SearchField
검색어 입력, 명시적인 clear 동작, 선택적인 fixed 배치를 native search input으로 제공합니다.
예제
SearchField 입력과 fixed 배치
controlled typing, clear 순서, filled·readonly·disabled 상태, 측정된 fixed spacer를 확인하세요.
사용해야 할 때
목록이나 페이지의 콘텐츠를 검색어 하나로 빠르게 좁히고, 현재 query를 한 번에 지우는 동작이 필요할 때 사용합니다. viewport 상단에 검색 맥락을 유지해야 하면 fixed와 기본 takeSpace=true를 함께 사용합니다.
사용하지 말아야 할 때
일반 데이터 입력, validation, help text, error message가 필요한 form field에는 TextField를 사용합니다. SearchField는 validation과 오류 표현을 의도적으로 포함하지 않습니다. 복수 필터, autocomplete 결과 popup, suggestion list는 이 컴포넌트의 책임이 아닙니다.
구조
visually hidden label과 native input type="search", 항상 표시되는 decorative Search icon, 값이 있는 enabled writable 상태에서만 표시되는 owned Close IconButton으로 구성됩니다. label과 clearLabel은 trim 뒤 non-empty여야 합니다.
크기와 변형
SearchField는 별도 size prop 없이 large control geometry를 사용합니다. 시각 계약은 Empty와 Filled이며 Default, Focus, Disabled, ReadOnly 상태를 갖습니다. clear target은 모든 viewport에서 최소 44 CSS px를 유지합니다.
상태와 동작
value !== undefined이면 controlled, 아니면 defaultValue ?? ''로 초기화하는 uncontrolled입니다. mount 뒤 mode 전환은 지원하지 않습니다. typing은 onValueChange(next)를 호출합니다. clear는 다음 값을 빈 문자열로 반영하고 onValueChange(''), onClear() 순서로 호출한 뒤 native input focus를 복원합니다. disabled와 readonly에는 clear action이 없습니다.
반응형 동작
root와 input은 min-inline-size: 0으로 320px viewport와 긴 query에서도 page overflow를 만들지 않습니다. fixed=true이면 bar는 viewport 상단에 남고 portal하지 않습니다. 기본 takeSpace=true는 ResizeObserver 측정값을 사용하며 JavaScript가 없으면 token 기반 CSS 높이로 content jump를 방지합니다. takeSpace는 fixed가 아닐 때 효과가 없습니다.
접근성
native search input과 associated hidden label을 사용하며 caller가 label과 clearLabel을 현지화합니다. Search icon은 decorative이고 Close button만 action으로 노출됩니다. WebKit native cancel decoration은 숨겨 중복 clear control을 만들지 않습니다. forced colors에서는 system surface, border, focus outline을 유지합니다.
React 예제
import { useState } from 'react';
import { SearchField } from '@hds/react';
import '@hds/react/styles.css';
export function ProductSearch() {
const [query, setQuery] = useState('');
return (
<SearchField
clearLabel="상품 검색어 지우기"
label="상품 검색"
name="query"
placeholder="상품명 또는 브랜드"
value={query}
onClear={() => console.info('cleared')}
onValueChange={setQuery}
/>
);
}
API
| Prop | Type | Default | 설명 |
|---|---|---|---|
label |
string |
required | hidden associated input label; trim 뒤 non-empty |
clearLabel |
string |
required | owned clear button label; trim 뒤 non-empty |
value |
string |
- | controlled value |
defaultValue |
string |
'' |
uncontrolled initial value |
onValueChange |
(value: string) => void |
- | typing과 clear value callback |
onClear |
() => void |
- | onValueChange('') 뒤 clear callback |
fixed |
boolean |
false |
viewport 상단 fixed 배치 |
takeSpace |
boolean |
true |
fixed bar의 measured spacer 유지 |
| native input props | Omit<InputHTMLAttributes<HTMLInputElement>, owned props> |
- | native form, reset, autocomplete, inputMode와 data attributes |
사용 토큰
- geometry:
size/control/medium,size/control/large,space/2,space/4,space/8,space/16,radius/full - type와 motion:
font/family/sans,font/size/body,font/line-height/body,motion/duration/fast,motion/easing/standard - color:
color/bg/surface,color/bg/subtle,color/text/primary,color/text/secondary,color/text/disabled,color/border/default,color/border/focus,color/focus/ring
Figma
live SearchField component set은 Value Empty/Filled × State Default/Focus/Disabled/ReadOnly = 8 variants와 Placeholder, Value TEXT properties를 가집니다. 모든 variant는 owned Icon/Search와 Icon/Close instance를 유지하고, Close는 Filled + Default/Focus에서만 보입니다. fixed와 takeSpace는 구현 동작으로 문서화하며 variant axis로 만들지 않습니다. TDS Mobile SearchField를 참고하되 이 저장소는 native form과 controlled/uncontrolled web 계약을 유지합니다.
지원 상태
| React | Svelte | React Native |
|---|---|---|
| preview | planned | planned |