Components / Inputs
Text Field
텍스트 입력 필드입니다. 라벨, 도움말, 에러 메시지, 글자 수 카운터, 접두/접미 요소를 지원합니다.
사용법
TextField는 라벨 + 입력 영역 + 도움말/에러의 3단 구조입니다.
작품의 공식 명칭을 입력하세요
<TextField
label="작품 제목"
placeholder="작품명을 입력하세요"
helperText="작품의 공식 명칭을 입력하세요"
value={title}
onChange={setTitle}
/>
<div class="ch-field"> <label class="ch-label">Label</label> <input class="ch-input" placeholder="Enter value"> </div> <!-- Error state --> <input class="ch-input ch-input--error" value="Invalid">
상태: default / focus / error / disabled
입력 필드의 4가지 상태를 시각적으로 구분합니다.
Default
Focus
Error
필수 입력 항목입니다
Disabled
<TextField state="default" />
<TextField state="focus" /> {/* border: chaart-red */}
<TextField state="error" errorText="필수 입력 항목입니다" />
<TextField disabled />
라벨과 도움말
라벨은 필드 위, 도움말은 필드 아래에 표시됩니다. 필수 표시(*)를 지원합니다.
실명 또는 호를 입력하세요
<TextField label="작가명" required helperText="실명 또는 호를 입력하세요" />
글자 수 카운터
최대 글자 수를 제한하고, 현재/최대 글자 수를 표시합니다.
<TextField
multiline
maxLength={200}
showCount
/>
접근성
| 속성 | 값 | 설명 |
|---|---|---|
aria-label | "{label}" | 라벨이 없을 때 입력 필드의 용도를 설명합니다. |
aria-required | "true" | 필수 입력 필드에 적용됩니다. |
aria-invalid | "true" | 에러 상태에서 적용됩니다. |
aria-describedby | "{helperId}" | 도움말/에러 텍스트를 참조합니다. |
사용 방법 예시
인터페이스
TextFieldProps
| 속성 | 필수 | 기본값 | 타입 | 설명 |
|---|---|---|---|---|
label | — | — | string | 입력 필드 라벨입니다. |
placeholder | — | — | string | 플레이스홀더 텍스트입니다. |
value | — | — | string | 입력 값입니다. |
onChange | — | — | (value: string) => void | 값 변경 핸들러입니다. |
required | — | false | boolean | 필수 입력 여부입니다. |
errorText | — | — | string | 에러 메시지입니다. |
helperText | — | — | string | 도움말 텍스트입니다. |
maxLength | — | — | number | 최대 글자 수입니다. |
showCount | — | false | boolean | 글자 수 카운터 표시 여부입니다. |
multiline | — | false | boolean | 여러 줄 입력 여부입니다. |
disabled | — | false | boolean | 비활성 상태입니다. |
Components / Inputs
Checkbox
다중 선택을 위한 체크박스 컴포넌트입니다. 단독/그룹 사용, 전체 선택, 비활성 상태를 지원합니다.
사용법
Checkbox는 라벨과 함께 사용되며, 클릭 시 checked/unchecked 상태를 토글합니다.
<Checkbox checked={true} onChange={toggle}>회화</Checkbox>
<Checkbox checked={false}>조각</Checkbox>
<Checkbox checked={true}>사진</Checkbox>
<label style="display:flex;align-items:center;gap:var(--space-2);cursor:pointer;font-size:var(--text-sm)"> <input type="checkbox" style="width:18px;height:18px;accent-color:var(--red-brand)"> Option Label </label>
상태: unchecked / checked / indeterminate
3가지 시각 상태를 지원합니다. indeterminate는 전체 선택에서 일부만 선택된 경우 표시됩니다.
Unchecked
Checked
Indeterminate
Disabled
<Checkbox checked={false} /> {/* Unchecked */}
<Checkbox checked={true} /> {/* Checked */}
<Checkbox indeterminate /> {/* 부분 선택 */}
<Checkbox disabled /> {/* 비활성 */}
그룹 사용
CheckboxGroup으로 여러 체크박스를 묶고, 전체 선택을 제어합니다.
<CheckboxGroup value={['painting','photo']} onChange={set}>
<Checkbox value="painting">회화</Checkbox>
<Checkbox value="sculpture">조각</Checkbox>
<Checkbox value="photo">사진</Checkbox>
</CheckboxGroup>
접근성
| 속성 | 값 | 설명 |
|---|---|---|
role | "checkbox" | 체크박스 역할입니다. |
aria-checked | "true" | "false" | "mixed" | 체크 상태입니다. mixed는 indeterminate입니다. |
aria-label | "{label}" | 라벨 텍스트를 스크린 리더에 전달합니다. |
aria-disabled | "true" | 비활성 상태에서 적용됩니다. |
사용 방법 예시
매체 선택
인터페이스
CheckboxProps
| 속성 | 필수 | 기본값 | 타입 | 설명 |
|---|---|---|---|---|
checked | — | false | boolean | 체크 상태입니다. |
indeterminate | — | false | boolean | 부분 선택 상태입니다. |
onChange | — | — | (checked: boolean) => void | 상태 변경 핸들러입니다. |
disabled | — | false | boolean | 비활성 상태입니다. |
value | — | — | string | 그룹에서 식별할 값입니다. |
children | — | — | string | 라벨 텍스트입니다. |
크기 (Size)
4단계 사이즈 스케일을 지원합니다. 기본값은 md입니다.
Components / Inputs
Numeric Spinner
숫자를 증감하는 입력 컴포넌트입니다. +/- 버튼과 숫자 표시로 구성되며, 작품 수량 설정, 에디션 번호 선택, 가격 조정 등에 활용됩니다.
사용법
기본 넘버릭 스피너는 1단위로 증감하며, 최소/최대 제한 없이 동작합니다.
<NumericSpinner value={3} onChange={setValue} />
<div style="display:inline-flex;align-items:center;border:1px solid var(--alpha-12);height:var(--size-md-height)"> <button style="width:40px;height:100%;border:none;background:none;cursor:pointer;font-size:var(--text-lg)">−</button> <input style="width:48px;text-align:center;border:none;border-left:1px solid var(--alpha-12);border-right:1px solid var(--alpha-12);font-family:var(--mono);font-size:var(--text-sm)" value="1"> <button style="width:40px;height:100%;border:none;background:none;cursor:pointer;font-size:var(--text-lg)">+</button> </div>
최소/최대 제한
min, max props로 입력 범위를 제한합니다. 제한에 도달하면 해당 방향 버튼이 비활성됩니다.
<NumericSpinner value={1} min={1} max={50} onChange={setValue} />
Step 및 비활성 상태
step으로 증감 단위를 설정하고, disabled로 전체를 비활성화할 수 있습니다.
<NumericSpinner value={100} step={100} onChange={setValue} />
<NumericSpinner value={5} disabled />
접근성
| 속성 | 값 | 설명 |
|---|---|---|
role | spinbutton | 숫자 스피너 역할을 명시합니다 |
aria-valuenow | number | 현재 숫자 값을 전달합니다 |
aria-valuemin | number | 최솟값을 전달합니다 |
aria-valuemax | number | 최댓값을 전달합니다 |
aria-label | string | 스피너의 용도를 설명합니다 |
사용 방법 예시
인터페이스
NumericSpinnerProps
| 속성 | 필수 | 기본값 | 타입 | 설명 |
|---|---|---|---|---|
value | ✓ | — | number | 현재 숫자 값 |
onChange | ✓ | — | (value: number) => void | 값 변경 콜백 |
min | -Infinity | number | 최솟값 제한 | |
max | Infinity | number | 최댓값 제한 | |
step | 1 | number | 증감 단위 | |
disabled | false | boolean | 비활성 상태 여부 | |
aria-label | — | string | 스크린 리더용 접근성 텍스트 | |
formatValue | — | (v: number) => string | 표시 값 포맷 함수 (예: 통화) |
Components / Inputs
Rating
별점으로 평가를 입력하거나 표시하는 컴포넌트입니다. 사용자가 직접 평가를 입력하거나, 기존 평점을 읽기 전용으로 표시할 수 있습니다. 반별(half-star) 표시를 지원합니다.
사용법
기본 Rating은 value 속성으로 별점을 표시합니다. 클릭하여 평가를 입력하거나, 읽기 전용 모드로 평점만 표시할 수 있습니다.
<Rating value={3} onChange={handleChange} />
<Rating value={4.5} readOnly />
<div style="display:flex;gap:2px"> <span style="color:var(--red-brand);font-size:16px">★</span> <span style="color:var(--red-brand);font-size:16px">★</span> <span style="color:var(--red-brand);font-size:16px">★</span> <span style="color:var(--alpha-16);font-size:16px">★</span> <span style="color:var(--alpha-16);font-size:16px">★</span> </div>
읽기 전용과 크기
크기는 sm, md, lg를 지원합니다. 읽기 전용 모드에서는 클릭이 비활성화되며, 반별(half) 표시가 가능합니다.
<Rating value={4} size="sm" readOnly />
<Rating value={4} size="md" readOnly />
<Rating value={4} size="lg" readOnly />
접근성
| 속성 | 값 | 설명 |
|---|---|---|
role | radiogroup | 평가 입력 그룹임을 명시합니다 (입력 모드) |
role | img | 읽기 전용 시 이미지 역할을 명시합니다 |
aria-label | string | 별점 설명을 제공합니다 (예: "5점 만점에 4점") |
aria-valuenow | {value} | 현재 선택된 별점 값을 전달합니다 |
aria-valuemax | {max} | 최대 별점 값을 전달합니다 |
사용 방법 예시
전시 리뷰에서 평점을 입력하는 예시입니다.
인터페이스
RatingProps
| 속성 | 필수 | 기본값 | 타입 | 설명 |
|---|---|---|---|---|
value | ✓ | — | number | 현재 별점 값 |
max | 5 | number | 최대 별 개수 | |
size | 'md' | 'sm' | 'md' | 'lg' | 별 아이콘의 크기 | |
readOnly | false | boolean | 읽기 전용 모드 여부 | |
onChange | — | (value: number) => void | 별점 변경 시 호출되는 콜백 |
Components / Inputs
Search Field
검색 입력 필드 컴포넌트입니다. 돋보기 아이콘, 입력 필드, 지우기 버튼이 통합되어 있으며, 디바운스(debounce) 기능을 내장하여 효율적인 검색 경험을 제공합니다.
사용법
기본 Search Field는 돋보기 아이콘과 placeholder를 표시합니다. 텍스트를 입력하면 지우기(X) 버튼이 나타납니다.
<SearchField placeholder="작품, 작가 검색..." />
<SearchField
value="김환기"
onSearch={handleSearch}
onClear={handleClear}
/>
<div style="position:relative"> <input class="ch-input" placeholder="검색..." style="padding-left:36px"> <svg style="position:absolute;left:12px;top:50%;transform:translateY(-50%);opacity:0.4" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg> </div>
크기와 변형
3가지 크기(sm, md, lg)를 지원합니다. 디바운스 시간을 설정하여 타이핑 중 불필요한 검색 요청을 방지할 수 있습니다.
<SearchField size="sm" placeholder="검색..." />
<SearchField size="md" placeholder="검색..." />
<SearchField size="lg" placeholder="검색..." />
<SearchField debounceMs={300} onSearch={handleSearch} />
접근성
| 속성 | 값 | 설명 |
|---|---|---|
role | searchbox | 검색 입력 필드임을 명시합니다 |
aria-label | string | 검색 필드에 대한 설명을 제공합니다 |
aria-haspopup | listbox | 자동완성 드롭다운이 있을 경우 명시합니다 |
aria-expanded | boolean | 자동완성 목록 표시 여부를 전달합니다 |
지우기 버튼 | aria-label="검색어 삭제" | 지우기 버튼의 접근성 레이블을 제공합니다 |
사용 방법 예시
작가 및 작품을 검색하는 예시입니다.
인터페이스
SearchFieldProps
| 속성 | 필수 | 기본값 | 타입 | 설명 |
|---|---|---|---|---|
value | '' | string | 검색 입력값 | |
placeholder | '검색...' | string | 플레이스홀더 텍스트 | |
size | 'md' | 'sm' | 'md' | 'lg' | 검색 필드의 크기 | |
onSearch | — | (value: string) => void | 검색 실행 시 호출되는 콜백 | |
onClear | — | () => void | 지우기 버튼 클릭 시 호출되는 콜백 | |
autoFocus | false | boolean | 마운트 시 자동 포커스 여부 | |
debounceMs | 0 | number | 디바운스 지연 시간 (ms) |
크기 (Size)
4단계 사이즈 스케일을 지원합니다. 기본값은 md입니다.
Components / Inputs
Slider
값 범위를 슬라이드로 선택하는 컴포넌트입니다. 사용자가 드래그하여 원하는 값을 직관적으로 선택할 수 있습니다.
사용법
<Slider
value={60}
min={0}
max={100}
step={1}
onChange={(v) => setValue(v)}
/>
<input type="range" style="width:100%;accent-color:var(--red-brand);height:4px">
범위와 스텝
접근성
| 속성 | 값 | 설명 |
|---|---|---|
role | slider | 슬라이더 역할을 스크린 리더에 전달합니다 |
aria-valuenow | 현재 값 | 현재 선택된 값을 전달합니다 |
aria-valuemin | 최솟값 | 슬라이더의 최솟값을 전달합니다 |
aria-valuemax | 최댓값 | 슬라이더의 최댓값을 전달합니다 |
tabindex | 0 | 키보드 탐색으로 포커스 가능합니다 |
| 키보드 | ← → 화살표 | 좌/우 화살표로 값 조절이 가능합니다 |
사용 방법 예시
인터페이스
SliderProps
| 속성 | 필수 | 기본값 | 타입 | 설명 |
|---|---|---|---|---|
value | ✓ | — | number | 슬라이더의 현재 값 |
min | 0 | number | 선택 가능한 최솟값 | |
max | 100 | number | 선택 가능한 최댓값 | |
step | 1 | number | 값 변경 단위 | |
onChange | — | (value: number) => void | 값 변경 시 호출되는 콜백 | |
showValue | false | boolean | 현재 값 표시 여부 | |
disabled | false | boolean | 비활성화 상태 |
크기 (Size)
4단계 사이즈 스케일을 지원합니다. 기본값은 md입니다.
상태 (States)
Slider의 인터랙션 상태입니다.
Components / Inputs
Stepper
+ / - 버튼으로 수량을 조절하는 컴포넌트입니다. 정확한 숫자 입력이 필요할 때 직관적인 증감 인터페이스를 제공합니다.
사용법
<Stepper
value={3}
min={1}
max={10}
step={1}
onChange={(v) => setCount(v)}
/>
<div style="display:flex;align-items:center;gap:var(--space-2)"> <div style="width:24px;height:24px;background:var(--red-brand);color:var(--white);display:flex;align-items:center;justify-content:center;border-radius:50%;font-size:var(--text-xs);font-weight:700">1</div> <div style="height:1px;width:24px;background:var(--alpha-12)"></div> <div style="width:24px;height:24px;border:1px solid var(--alpha-12);color:var(--text-muted);display:flex;align-items:center;justify-content:center;border-radius:50%;font-size:var(--text-xs)">2</div> </div>
크기와 변형
접근성
| 속성 | 값 | 설명 |
|---|---|---|
role | spinbutton | 증감 버튼 역할을 스크린 리더에 전달합니다 |
aria-valuenow | 현재 값 | 현재 수량 값을 전달합니다 |
aria-valuemin | 최솟값 | 감소 가능한 최솟값을 전달합니다 |
aria-valuemax | 최댓값 | 증가 가능한 최댓값을 전달합니다 |
aria-label | 설명 텍스트 | 스테퍼의 용도를 설명합니다 |
| 키보드 | ↑ ↓ 화살표 | 위/아래 화살표로 값 증감이 가능합니다 |
사용 방법 예시
인터페이스
StepperProps
| 속성 | 필수 | 기본값 | 타입 | 설명 |
|---|---|---|---|---|
value | ✓ | — | number | 현재 수량 값 |
min | 0 | number | 최소 수량 | |
max | 99 | number | 최대 수량 | |
step | 1 | number | 증감 단위 | |
size | "md" | "sm" | "md" | "lg" | 스테퍼 크기 | |
onChange | — | (value: number) => void | 값 변경 시 호출되는 콜백 | |
disabled | false | boolean | 비활성화 상태 |
Components / Inputs
Switch
토글 스위치 (on/off) 컴포넌트입니다. 설정이나 기능의 활성/비활성 상태를 즉시 전환할 수 있습니다.
사용법
<Switch
checked={isEnabled}
onChange={(v) => setIsEnabled(v)}
label="알림 활성화"
/>
<label style="display:flex;align-items:center;gap:var(--space-3);cursor:pointer;font-size:var(--text-sm)">
<div style="width:40px;height:22px;background:var(--alpha-12);border-radius:11px;position:relative;transition:background var(--dur-fast)">
<div style="width:18px;height:18px;background:var(--white);border-radius:50%;position:absolute;top:2px;left:2px;box-shadow:var(--shadow-sm);transition:transform var(--dur-fast)"></div>
</div>
Toggle Label
</label>
크기와 라벨
접근성
| 속성 | 값 | 설명 |
|---|---|---|
role | switch | 토글 스위치 역할을 스크린 리더에 전달합니다 |
aria-checked | true | false | 현재 켜짐/꺼짐 상태를 전달합니다 |
aria-label | 설명 텍스트 | 스위치의 용도를 설명합니다 |
tabindex | 0 | 키보드 탐색으로 포커스 가능합니다 |
| 키보드 | Space / Enter | 스페이스바 또는 엔터로 토글합니다 |
사용 방법 예시
인터페이스
SwitchProps
| 속성 | 필수 | 기본값 | 타입 | 설명 |
|---|---|---|---|---|
checked | ✓ | — | boolean | 스위치의 켜짐/꺼짐 상태 |
size | "md" | "sm" | "md" | "lg" | 스위치 크기 | |
label | — | string | 스위치 라벨 텍스트 | |
onChange | — | (checked: boolean) => void | 상태 변경 시 호출되는 콜백 | |
disabled | false | boolean | 비활성화 상태 |
크기 (Size)
4단계 사이즈 스케일을 지원합니다. 기본값은 md입니다.