← Examples

Bonbon TextField 데모

bonbon/textfield는 Radix Slot 기반 compound 컴포넌트와 TextFieldSingleLine·TextFieldMultiLine 래퍼를 제공합니다. SingleLine은 grapheme 기준 characterLimit을 사용합니다.

import

import {
  TextField,
  TextFieldSingleLine,
  TextFieldMultiLine,
} from "@/shared/components/bonbon/textfield";

SingleLine — 기본

라벨·입력·도움말을 한 컴포넌트로 묶습니다.

도움말

SingleLine — characterLimit + onValueChange

DOM maxLength 대신 grapheme 기준 characterLimit을 사용합니다.

const [value, setValue] = useState("");

<TextFieldSingleLine
  id="title"
  label="제목"
  inputProps={{
    value,
    onValueChange: setValue,
    placeholder: "플레이스 홀더",
    characterLimit: 50,
    showCount: true,
    clearable: true,
  }}
/>
10/50

현재 값: 자유롭게 그린 그림

SingleLine — 이모지 grapheme 카운트

👨‍👩‍👧‍👦는 화면에서 1글자지만 JS String.length는 더 큽니다.

1/50

보이는 글자 수: 1 / JS length: 11

SingleLine — 라벨 없음 / error / success / disabled

error는 TextField.Root에 전달되며, showCount일 때 TextField.CharacterCount가 context를 읽어 카운트 색도 함께 바뀝니다.

8/50

에러 도움말

성공 도움말

6/50

비활성 도움말

MultiLine — 기본

textareaProps.maxLength는 native maxLength를 사용합니다.

0/200

도움말

MultiLine — 제어 + 커스텀 높이

0/300

현재 값: «빈 문자열»

Compound — TextField.Root

SingleLine·MultiLine 내부 카운트도 동일한 TextField.CharacterCount를 사용합니다.

0/100

compound API로 레이아웃을 직접 구성한 예시입니다.

CharacterCount — error / disabled (context)

TextField.Root의 error·disabled를 CharacterCount가 context로 반영합니다.

<TextField.Root id="title" error>
  ...
  <TextField.CharacterCount current={12} max={50} />
</TextField.Root>
9/50

카운트가 semantic-error 색입니다.

9/50

Zod 검증 시 주의

UI와 동일한 기준으로 검증하려면 isTextInputWithinMaxLength를 사용하세요.

import { isTextInputWithinMaxLength } from "@/shared/lib/textInputPolicy";

const schema = z.object({
  title: z
    .string()
    .trim()
    .min(1)
    .refine((value) => isTextInputWithinMaxLength(value, 50)),
});
아트봉봉스쿨

아트봉봉스쿨은더 큰 화면에서 쓸 수 있어요