Label
컨트롤의 보이는 이름입니다. 복합 컴포넌트의 파트가 아니라 형제 요소입니다. htmlFor는 필수이며 컨트롤 id와 같아야 합니다. Field라면 Field.Root의 id입니다. Label 자체는 컨트롤이 아닙니다.
Server Components에서는 @tounsoo/todae/label에서 가져올 수 있습니다. 이 엔트리에는 'use client'와 훅이 없습니다. 기본 @tounsoo/todae 엔트리는 클라이언트 모듈입니다.
Field와 함께
Label에는 마진이 없습니다. 레이블과 셸 사이의 간격은 field.label.gap(0.4rem)입니다. 이 간격은 둘을 쌓는 래퍼에 두세요. 그 래퍼가 Description이나 ErrorMessage의 간격을 잡게 하지 마세요. 이 컴포넌트들은 margin-block-start를 스스로 가집니다.
.labelled-field {
display: flex;
flex-direction: column;
}
.labelled-field
> :not([data-todae-description], [data-todae-error])
+ :not([data-todae-description], [data-todae-error]) {
margin-block-start: var(--todae-field-label-gap);
}
const id = useId()
<div className="labelled-field">
<Label htmlFor={id}>Email</Label>
<Field.Root id={id}>
<Field.TextInput value={v} onChange={(event) => setV(event.target.value)} />
</Field.Root>
</div>
스택 하나에 .labelled-field 하나를 씁니다. 순서는 Label, 컨트롤, 그리고 형제 요소인 Description과 ErrorMessage입니다. 컨트롤과 메시지 사이 간격은 컴포넌트의 margin-block-start인 0.4rem입니다. ErrorMessage가 Description 뒤에 오면 그 시작 마진은 0.2rem입니다. 여러 스택을 래퍼 하나로 감싸지 마세요. 스택을 Stack으로 감싸지 마세요. stack.gap은 필드 사이의 밀도 간격이지, 레이블과 셸 사이의 간격이 아닙니다. .labelled-field 스택들을 Stack 안에 넣으세요.
상태
비활성과 유효하지 않음 상태는 Field.Root에 있습니다. Label은 다시 칠해지지 않습니다. 필수 표시는 레이블 텍스트에 직접 씁니다.
언제 쓰나요
언제: 형제 요소로 배치하는 컨트롤의 보이는 이름. htmlFor = 컨트롤 id(Field라면 Field.Root의 id). 필수 표시는 텍스트에 넣습니다.
쓰지 않을 때: Field.Root 안. Checkbox / Radio / Switch(자식이 레이블입니다). 그룹 캡션 → RadioGroup의 aria-label / aria-labelledby. 힌트 텍스트 → Description.
Props
| 이름 | 타입 | 필수 | 기본값 | 설명 |
|---|---|---|---|---|
| htmlFor | string | 예 | — | 레이블이 붙는 컨트롤의 id. Field에 캡션을 달 때는 Field.Root id와 일치해야 합니다. |
| children | React.ReactNode | 아니요 | — | 레이블 텍스트. 필요하면 필수 표시를 여기에 직접 작성합니다. |
| className | string | 아니요 | — | 네이티브 label에 붙는 선택적 클래스. |