검색 입력
목록·표를 좁혀 들어가는 검색창이다. 좌측 아이콘으로 무엇을 하는 자리인지 알리고, 평소엔 중립 테두리로 조용히 있다가 마우스를 올리면 surface-muted 로 살짝 떠오른다. 입력 중에는 짙은 중립 테두리로 또렷해지고, 값이 생기면 우측에 지우기(X) 버튼이 나타나 한 번에 비울 수 있다. 폼·라우팅 로직은 호출자 몫이라 GET 폼(uncontrolled)과 state(controlled) 둘 다에 그대로 끼워 쓴다.
상태
기본 (비어 있음)
값 있음 (지우기)
비활성
hover 면 bg-surface-muted(드롭다운 트리거와 같은 결), focus 면 border-muted(컬러 없이 짙게). 값이 있을 때만 지우기 버튼이 보인다.
활용 방법
라이브 (controlled)
value/onChange 로 state 에 묶고, onClear 로 비움을 받는다. 직접 입력하고 X 를 눌러보자.
Preview
입력값: 제주 카페
tsx
const [q, setQ] = useState("");<SearchInputvalue={q}onChange={(e) => setQ(e.target.value)}onClear={() => setQ("")}placeholder="검색"/>
GET 폼 (uncontrolled)
name + defaultValue 만 주면 폼 제출(Enter)로 검색된다. 지우기 버튼은 입력을 비우고 포커스를 유지한다.
Preview
tsx
<form method="get"><SearchInput name="q" defaultValue={q ?? ""} placeholder="검색" /></form>
너비 조절
className 으로 너비를 준다(기본 w-48). 그 외 텍스트·테두리 크롬은 토큰 고정.
Preview
tsx
<SearchInput placeholder="검색" className="w-72" />
속성
| 이름 | 타입 | 기본값 | 설명 |
|---|---|---|---|
| onClear | () => void | - | 지우기 버튼 클릭 후 호출(입력은 이미 비워진 뒤): 검색 결과 초기화 등 |
| clearLabel | string | "검색 지우기" | 지우기 버튼의 title·aria-label |
| className | string | "w-48" | 래퍼 클래스: 주로 너비 |
| ...props | InputHTMLAttributes | - | 네이티브 input 속성 전부 전달(name·value·defaultValue·placeholder·disabled·onChange ...) |