FormLabel
폼 입력 필드용 라벨 (필수 표시 옵션 포함)
목차
폼 입력에 붙는 설명 라벨입니다. isRequired 가 true 면 라벨 뒤에 필수 표시(*)를 붙입니다(커스텀 표시는
requiredIndicator, 기본은 error 색 별표). Flutter / Web 1:1 동일 API 입니다.
Live Preview#
코드 보기
class FormLabelDefaultExample extends StatelessComponent {
const FormLabelDefaultExample({super.key});
@override
Component build(BuildContext context) {
return FormLabel(label: Text('이메일'), isRequired: true);
}
}
class FormLabelDefaultExample extends StatelessWidget {
const FormLabelDefaultExample({super.key});
@override
Widget build(BuildContext context) {
return FormLabel(label: const Text('이메일'), isRequired: true);
}
}
사용법#
FormLabel(label: const Text('이메일'), isRequired: true)
빠른 오버라이드 (Chain)#
이미 만든 FormLabel 인스턴스에 스타일을 빠르게 덧붙이고 싶다면 withStyle 체인을 쓸 수 있습니다. 생성자의 style 슬롯 인자와 동일하게 동작하지만, 이미 구성된 위젯 위에서 바로 이어 쓸 수 있습니다.
class FormLabelChainExample extends StatelessWidget {
const FormLabelChainExample({super.key});
@override
Widget build(BuildContext context) {
return FormLabel(
label: const Text('이메일'),
isRequired: true,
).withStyle(
const CoreFormLabelStyle(
labelStyle: CoreTextStyle.token(
CoreTextStyles.titleMedium,
color: CoreColor.token(CoreColors.primary),
),
requiredColor: CoreColor.token(CoreColors.tertiary),
requiredIndicatorGapStyle: CoreGapStyle(size: CoreSpace.space12),
),
);
}
}
class FormLabelChainExample extends StatelessComponent {
const FormLabelChainExample({super.key});
@override
Component build(BuildContext context) {
return FormLabel(
label: Text('이메일'),
isRequired: true,
).withStyle(
const CoreFormLabelStyle(
labelStyle: CoreTextStyle.token(
CoreTextStyles.titleMedium,
color: CoreColor.token(CoreColors.primary),
),
requiredColor: CoreColor.token(CoreColors.tertiary),
requiredIndicatorGapStyle: CoreGapStyle(size: CoreSpace.space12),
),
);
}
}
Props / Parameters#
W 는 Flutter의 Widget, Web의 Jaspr Component 입니다. 공통 호출에서는 label을 명시합니다. Web에서 label을 생략할 수 있는 것은 기존 soft-requiredness 호환 예외입니다.
| 파라미터 | 타입 | 기본값 | 설명 |
|---|---|---|---|
label | W? | 명시 | 라벨 콘텐츠 |
isRequired |
bool |
false |
필수 표시(*) 노출 여부 |
requiredIndicator |
W? |
null |
커스텀 필수 표시 (기본: error 색 별표) |
size |
CoreComponentSize |
md |
라벨 크기 단계 —
xs
·
sm
·
md
는
label-medium
(13 / 500),
lg
·
xl
·
xl2
는
label-large
(14 / 500)
|
enabled |
bool |
true |
라벨 활성/비활성 타이포그래피 — 활성은
onSurfaceVariant
(라벨은 컨트롤의 이름이고 값이 더 크게 읽힙니다), 비활성은
disabledColor
(기본
disabledContent
)입니다.
TextField
·
TextArea
는 자기
labelDisabledColor
(
onSurfaceSubtle
)를 넘겨 한 단계 위에 둡니다
|
formLabelStyle |
CoreFormLabelStyle? |
null |
chrome / 타이포 단일 진입점 |
스타일 시스템 (Style System)#
CoreFormLabelStyle 필드#
| 필드 | 타입 | 설명 |
|---|---|---|
labelStyle |
CoreTextStyle? |
Nested [CoreTextStyle] slot for the label typography — role + colour.
null
→ the size-keyed default in [defaultsBySize]. A caller that overrides only the colour keeps the default role, and vice versa, because the resolver merges this override on top of that size default.
|
requiredColor |
CoreColor? |
Override colour applied to the required indicator while enabled. |
requiredIndicatorGapStyle |
CoreGapStyle? |
Nested [CoreGapStyle] slot for the gap between the label and the required indicator — forwarded straight to
Gap(gapStyle: …)
.
Gap
runs its own resolve step, so this slot is merged on top of the design-system default in pre-scaling units (the receiving widget owns scaling).
|
disabledColor |
CoreColor? |
Override colour applied to the label and the required indicator while
CoreFormLabelContract.enabled
is
false
.
null
→ the design-system [defaultDisabledColor].
|
동작 스펙 (Behavior)#
-
label과 선택적 필수 표시를 가로로 놓습니다.
isRequired: true이면 requiredIndicator를 쓰고, 없으면 기본 별표를 표시합니다. 기본 별표는 장식으로 리더에서 제외합니다. -
required는 검증 규칙이 아니라 표시입니다.
enabled: false도 라벨 스타일만 바꾸며 연결된 입력을 비활성화하지 않습니다. 자체 콜백·포커스·입력값이 없습니다. - 검증·description·error까지 필요한 필드 래퍼이면 FormField, 단순 정적 라벨이면 Label 입니다.
사용 가이드라인 (Usage Guidelines)#
✅ Do#
입력 컴포넌트에 접근 가능한 이름을 직접 지정
FormLabel(label: const Text('이메일'), isRequired: true)
TextField(
placeholder: const Text('you@company.com'),
// 접근 가능한 이름은 이 TextField 쪽에서 직접 책임져야 함
)
FormLabel이 그리는 <label>은 for를 emit하지 않고 Flutter에는 대응하는 Semantics 연결조차 없어, 라벨이 어떤 컨트롤과도 연결되지 않습니다. 접근 가능한 이름은 입력 컴포넌트 쪽에서 직접 지정해야 합니다.
❌ Don't#
isRequired 하나로 "필수" 여부가 낭독된다고 가정하지 않기
// ❌ isRequired 는 시각적 별표만 만들 뿐 보조기술에 아무것도 알리지 않음
FormLabel(label: const Text('이메일'), isRequired: true)
isRequired는 시각적 별표만 만들 뿐 aria-required도, "필수"라는 텍스트도 보조기술에 노출하지 않습니다. 필수 여부를 낭독시키려면 입력 컴포넌트(예: FormField의 aria-required) 쪽에 별도로 표기해야 합니다.
접근성 (Accessibility)#
역할#
-
Web: 네이티브
<label>요소로 렌더됩니다. 다만for속성을 emit 하지 않습니다 — 컴포넌트가 붙이는 속성은 호출자가 넘긴 것뿐입니다. -
Flutter:
Semantics/CoUISemantics가 전혀 없습니다.DefaultTextStyle.merge→Row로 텍스트만 그립니다.
기본 필수 표시(*)는 양 플랫폼 모두 낭독에서 제외됩니다 — Web 은 <span aria-hidden="true">, Flutter 는
ExcludeSemantics 입니다.
키보드#
처리하는 키가 없습니다. Web 의 <label> 도 클릭을 입력으로 전달하지 못합니다 — for 를 emit 하지 않고,
FormField 안에서도 입력을 감싸지 않고 형제로 배치되기 때문입니다.
포커스 관리#
포커스 관련 동작이 없습니다 — FocusNode / tabindex / 포커스 링 / 트랩 / 복원 모두 없습니다.
스크린 리더#
라벨 텍스트가 읽힙니다. Web 의 <label> 은 존재하지만 어떤 컨트롤과도 연결되어 있지 않아, 컨트롤의 접근 가능한 이름이 아니라 그냥 일반 텍스트로
낭독됩니다.
알려진 제약#
-
for/id연결도, 입력 감싸기도 없어<label>의 시맨틱이 실질적으로 장식입니다. 이 라벨은 입력의 이름이 되지 못하며, Flutter 에는 라벨 연결 수단 자체가 없습니다. 입력의 접근 가능한 이름은 입력 컴포넌트 쪽에서 직접 지정하세요. -
isRequired는 시각적 별표만 만듭니다.aria-required도, "필수"라는 텍스트도 보조기술에 노출되지 않으므로 필수 여부는 입력 자체에 따로 표기해야 합니다. -
커스텀
requiredIndicator는 숨김 처리를 우회합니다. 기본 별표와 달리aria-hidden(Web) /ExcludeSemantics(Flutter) 가 붙지 않아 그대로 낭독됩니다. 장식용 마커라면 호출자가 직접 숨겨야 합니다.
크로스 플랫폼 차이점 (Platform Differences)#
| 항목 | Flutter | Web |
|---|---|---|
| 렌더링 | Row·DefaultTextStyle | <label> 래퍼 |
| 입력 연결 | 호출부의 필드 의미로 구성 | 필요 시 caller attributes의 for로 연결 |
| 기본 별표 숨김 | ExcludeSemantics | aria-hidden span |
| 생성자 관대함 | nullable label 인자를 필수로 받음 | label 생략 가능 |