Text
라벨, 마스크, 통화 서식, 검색 등을 내장한 올인원 단일 라인 텍스트 입력 컴포넌트
개요
Cals Text은 Foundation Input을 래핑하여 CALS 제품의 텍스트 입력 UI를 선언적으로 구현하는 컴포넌트입니다. 폼 라벨, 입력 마스크, 천 단위 구분, 통화 서식 등 CALS에서 자주 쓰이는 입력 처리를 prop으로 제공합니다.
주요 특징
- ✅ controlled / uncontrolled: value/onChange 또는 defaultValue로 값 관리
- ✅ 입력 마스크: mask 패턴(9/A/S/*)으로 입력 형식 제한, autoUnmask로 순수 값 전달
- ✅ 천 단위 구분: thousandSeparator로 표시 포맷, 값은 순수 숫자 유지
- ✅ 통화 서식: currency prop으로 통화 기호·소수 자릿수 적용
- ✅ 코드 표시명 변환: codeMap으로 코드 값을 표시명으로 변환
- ✅ FormItem 내장: label/required/description/error prop으로 폼 라벨 자동 래핑
- ✅ 라벨 도움말: labelTooltip으로 라벨 옆 도움말 아이콘 표시
- ✅ 검색 실행: isSearch + onSearch로 Enter 검색 지원
- ✅ 가시성/포커스 제어: visible prop, ref.focus()/blur()/element
- ✅ 디자인 토큰: 조건부 토큰 오버라이드 (prop이 있을 때만 적용)
기본 사용
placeholder로 입력 전 안내 문구를 표시합니다.
Preview
기본값 설정
defaultValue로 초기 기본값을 지정합니다.
Preview
크기
size prop으로 입력란 크기를 지정합니다. xs / sm / md / lg / xl을 지원합니다.
Preview
비활성화 / 읽기 전용
disabled는 조작할 수 없고, readOnly는 값을 바꿀 수 없습니다. readOnly는 disabled로 바뀌지 않고 읽기 전용 모양으로 표시되며 Tab 포커스를 받습니다.
Preview
라벨 / 필수 입력
label로 라벨을 표시하고, required로 필수 표시 기호(*)를 추가합니다.
Preview
라벨 위치
orientation=“horizontal”이면 라벨이 입력란 왼쪽에 배치됩니다.
Preview
라벨 도움말
labelTooltip 지정 시 라벨 옆 아이콘에 마우스를 올리면 도움말이 표시됩니다.
Preview
글자 수 제한
maxLength로 최대 글자 수를 제한합니다. 초과 입력은 차단됩니다.
Preview
검색 실행
isSearch=true에서 Enter 키 입력 시 onSearch가 호출됩니다.
Preview
입력 마스크
mask 패턴으로 입력 형식을 제한합니다. 9는 숫자, A는 영문, S는 영숫자, *는 영숫자+한글이며 그 외 문자는 리터럴로 자동 삽입됩니다. autoUnmask=true이면 onChange로 마스크가 제거된 순수 값이 전달됩니다.
| 토큰 | 허용 문자 | 정규식 |
|---|---|---|
9 | 숫자 | [0-9] |
A | 영문 | [A-Za-z] |
S | 영숫자 | [A-Za-z0-9] |
* | 영숫자+한글 | [A-Za-z0-9가-힣] |
Preview
천 단위 구분
thousandSeparator로 숫자에 천 단위 구분 기호(,)를 표시합니다. 저장되는 값은 구분 기호가 제거된 순수 숫자입니다.
Preview
통화 서식
currency prop으로 통화 기호와 소수 자릿수를 지정합니다. blur 시 서식이 적용됩니다.
Preview
코드 표시명 변환
codeMap에 매핑된 코드 값은 표시명으로 변환되어 보입니다. 매핑이 없으면 원래 값이 표시됩니다.
Preview
스타일 설정
backgroundColor, color, borderColor 등으로 디자인 토큰을 오버라이드합니다.
Preview
API Reference
Props
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | number | - | 입력 값 (controlled) |
defaultValue | string | number | - | 초기 기본값 (uncontrolled) |
placeholder | string | - | 입력 전 안내 문구 |
showPlaceholder | boolean | true | 안내 문구 표시 여부 |
size | "xs" | "sm" | "md" | "lg" | "xl" | "md" | 입력란 크기 |
visible | boolean | true | 표시 여부 (false → 렌더링 안 함) |
disabled | boolean | false | 비활성화 |
readOnly | boolean | - | 읽기 전용 (disabled로 바꾸지 않음, Tab 포커스 받음). 주지 않으면 감싸는 Form·ToolbarForm의 readOnly를 따른다 |
required | boolean | - | 필수 입력. FormItem *와 aria-required만 켠다 (HTML required는 붙이지 않음) |
maxLength | number | - | 최대 글자 수 |
minLength | number | - | 최소 글자 수 |
isSearch | boolean | false | 검색 폼 여부 (Enter 시 onSearch 발생, 한글 조합을 끝내는 Enter 제외) |
mask | string | - | 입력 마스크 패턴 (9: 숫자, A: 영문, S: 영숫자, *: 영숫자+한글) |
autoUnmask | boolean | false | onChange로 마스크 제거된 순수 값 전달 여부 |
thousandSeparator | boolean | - | 천 단위 구분 기호 표시 (정수부만, 값은 순수 숫자). currency 모드는 주지 않으면 켜고 false면 끈다 |
currency | { symbol?: string; decimal?: number } | - | 통화 서식 모드 |
codeMap | Record<string, string> | - | 공통 코드 → 표시명 매핑 |
onBlurConvert | (value: string) => string | - | blur 시 값 변환 함수 |
byteLimit | number | - | 바이트 기준 입력 길이 제한 |
prefix | string | - | 입력 필드 앞 접두 텍스트 |
mentionTrigger | string | - | 멘션 트리거 문자 (예: ”@“) |
mentionItems | Array<{ label: string; value: string }> | - | 멘션 항목 목록 |
labelTooltip | string | - | 라벨 도움말 (아이콘 hover 시 표시) |
title | string | - | HTML title 속성 (native tooltip) |
backgroundColor | string | - | 배경색 토큰 오버라이드 |
color | string | - | 텍스트 색상 토큰 오버라이드 |
borderColor | string | - | 테두리 색상 토큰 오버라이드 |
borderWidth | string | - | 테두리 두께 |
fontSize | string | - | 폰트 크기 |
fontWeight | string | number | - | 폰트 굵기 |
fontFamily | string | - | 폰트 패밀리 |
fontStyle | string | - | 폰트 스타일 (italic 등) |
textAlign | string | - | 텍스트 정렬 |
className | string | - | FormItem 루트 className |
inputClassName | string | - | 입력란(input) className |
style | React.CSSProperties | - | 인라인 스타일 |
label | ReactNode | - | 라벨. ""이면 정렬용 빈 자리만 두고 입력란에 잇지 않는다 (이름은 aria-label로 준다, labelTooltip 무시) |
labelWidth | number | - | 라벨 너비 (px) |
labelAlign | "start" | "center" | "end" | - | 라벨 가로 정렬 |
labelVerticalAlign | "start" | "center" | "end" | - | 라벨 세로 정렬 |
requiredPosition | "left" | "right" | - | 필수 표시(*) 위치 |
orientation | "horizontal" | "vertical" | - | FormItem 라벨 방향 |
description | string | - | FormItem 설명 |
error | string | - | 오류 문구. 주면 오류 상태(aria-invalid)도 켠다 |
aria-invalid | boolean | - | 오류 상태. true면 문구 없이 상태만 켜고, false면 error가 있어도 상태와 문구를 끈다 |
Events
| Event | Type | Description |
|---|---|---|
onChange | (value: string) => void | 값 변경 시 호출 (마스크/구분기호 제거됨) |
onSearch | () => void | isSearch=true에서 Enter 입력 시 호출 |
onClick | () => void | 컨트롤 클릭 시 호출 |
onMentionSelect | (item: { label: string; value: string }) => void | 멘션 항목 선택 시 호출 |
Ref
| 메서드/속성 | Type | Description |
|---|---|---|
focus() | () => void | 입력란에 포커스 |
blur() | () => void | 포커스 해제 |
element | HTMLInputElement | null | input DOM 요소 |
접근성
권장 사항
- ✅ label 또는 aria-label로 입력란의 목적을 명확히 제공하세요.
- ✅ 필수 입력은 required로 설정하여 스크린 리더에 전달하세요.
- ❌ placeholder만으로 라벨을 대체하지 마세요. 값 입력 시 사라집니다.
관련 컴포넌트
- Foundation Input: 기본 입력 컴포넌트
- FormItem: 폼 라벨 래퍼
- Cals Select: 드롭다운 선택 컴포넌트