// FoxInput — 시안: 통합관리자페이지 디자인시스템(KE9UILWhB8qTBe14uXUn4F) // Figma input (컴포넌트 세트 135:621) // // 마크업 계약 (React 밖 소비자용): //
// //
// // // …svg… //
//

…

//
// // 상태는 두 갈래다. // - 기본(자동): 브라우저가 판단한다. 포커스는 `:focus-within`, 비활성·읽기전용은 네이티브 // 속성, 오류는 `aria-invalid="true"`. 값이 들어찬 모습(시안의 completed)은 따로 규칙이 // 필요 없다 — 시안에서 default와 completed의 차이가 글자색뿐인데 그건 플레이스홀더와 // 입력값의 네이티브 차이다. // - 고정: 루트에 `data-state`를 주면 그 모양으로 못박힌다. 자동 규칙은 전부 꺼진다. // 카탈로그·스냅샷처럼 상태를 눈으로 비교해야 할 때 쓴다. // // 라벨·헬퍼·상자·알맹이와 두 갈래 상태는 `form-field` 믹스인이 갖는다 — 입력 계열 여섯 // 컴포넌트가 같은 값을 쓴다. 이 파일에는 FoxInput만의 것(크기 축, 아이콘, 지우기 버튼)이 // 남는다. // // 아이콘 크기 24/20/16은 시안이 변수를 걸지 않았지만 상자의 나머지 치수가 전부 `form/*` // 반응형 토큰이라 아이콘도 `form-icon-*`(PC 24/20/16 · 모바일 20/16/12)에 맞춘다. // // 토큰이 아닌 값(FoxButton과 동일한 근거로 승인된 항목): // - cursor / flex / appearance 관련: 구조·상호작용 규칙. @use "abstracts" as fox; @use "form-field" as field; .fox-input { @include field.root; // 크기(높이·좌우 여백·모서리)는 아래 크기 수식어가 정한다. &__box { @include field.box; } // 글자 크기도 크기 수식어가 정한다. &__field { @include field.field; } &__icon, &__clear { display: inline-flex; flex-shrink: 0; align-items: center; justify-content: center; color: fox.color(icon-neutral-default); } &__icon > *, &__clear > * { inline-size: 100%; block-size: 100%; } &__clear { margin: 0; padding: 0; border: none; background: none; cursor: pointer; } &__message { @include field.message; } &__message-icon { @include field.message-icon; } // ── 크기 ────────────────────────────────────────────────────────────────── &--lg &__box { block-size: fox.form(height-lg); padding-inline: fox.form(padding-lg); border-radius: fox.form(radius-lg); } &--lg &__field { font-size: fox.font-size(label-lg); } &--lg &__icon, &--lg &__clear { inline-size: fox.form(icon-lg); block-size: fox.form(icon-lg); } &--md &__box { block-size: fox.form(height-md); padding-inline: fox.form(padding-md); border-radius: fox.form(radius-md); } &--md &__field { font-size: fox.font-size(label-md); } &--md &__icon, &--md &__clear { inline-size: fox.form(icon-md); block-size: fox.form(icon-md); } &--sm &__box { block-size: fox.form(height-sm); padding-inline: fox.form(padding-sm); border-radius: fox.form(radius-sm); } &--sm &__field { font-size: fox.font-size(label-sm); } &--sm &__icon, &--sm &__clear { inline-size: fox.form(icon-sm); block-size: fox.form(icon-sm); } // 지우기 버튼은 포커스 중에만 보인다(시안에서 focused 변형에만 있다). &__clear { display: none; } &__box:focus-within &__clear { display: inline-flex; } } @include field.auto-states("fox-input"); @include field.fixed-states("fox-input") { .fox-input[data-state="focused"] .fox-input__clear { display: inline-flex; } }