Search (검색)
Va.Search — 검색 입력 필드
Va.Input과 거의 동일한 텍스트 입력이지만, HTML 표준 <input type="search"> 를 사용해 브라우저가 자동으로 검색 아이콘 · 지우기(×) 버튼 을 그려주는 컴포넌트입니다. 코드 자체는 초미니 클래스 — 사실상 "type을 'search'로 고정한 Input"입니다.
- 클래스: Va.Search — va_component.js:1216
- short name: search
- 상속: Va.PureField (Input과 형제)
- DOM 태그: <input type="search"> (하드코딩)
- isContainer: true
- 베이스 CSS: va-input (Input과 동일 클래스 공유)

1. 기본 사용
{
tagName: 'search',
placeholder: '검색어를 입력하세요',
onChange: 'onSearch'
}
브라우저가 렌더링 시 자동으로:
- 좌측(또는 우측)에 돋보기 아이콘
- 입력 시 우측에 × 버튼 (내용 지우기)
를 제공합니다. Chrome/Safari/Firefox 모두 지원.
2. Va.Input과의 차이
Search 소스는 딱 30줄입니다. Va.Input과 사실상 99% 같은데, 딱 두 지점만 다릅니다.
항목Va.InputVa.Search
| type 기본값 | 'text' (변경 가능) | 'search' (하드코딩) |
| numberComma 지원 | ✓ | ✕ (properties 배열에서 빠짐) |
| CSS 클래스 | va-input | va-input (동일) |
| 상속 | PureField | PureField (동일) |
| 이벤트/메서드 | 전부 동일 | 전부 동일 |
한 줄 요약: "<input type="search">가 필요하고, 숫자 콤마는 안 쓸 때"의 명시적 선택지.
Va.Input으로 type: 'search'를 직접 지정해도 결과는 거의 같습니다 — Search를 쓰는 실질적 이득은 의도 명확성 정도입니다.
3. <input type="search">의 브라우저 표준 동작
이 컴포넌트를 쓰는 진짜 이유는 브라우저가 type="search"에 주는 특수 처리입니다:
- 자동 지우기 버튼(×) — 값이 있으면 우측에 X 표시 (Chrome/Safari/Edge). Firefox는 우클릭 메뉴에서 활성화.
- Enter 키 자동 form 제출 (form 안에 있을 때)
- 모바일 소프트키보드 — 확인 버튼이 "Search" / "검색" 으로 표시됨
- 접근성 — 스크린리더가 "검색 입력창"으로 인식
- 자동 히스토리 — 브라우저에 따라 최근 검색어 자동완성 힌트 표시
이 표준 동작들이 Search 컴포넌트를 쓰는 실질적 가치입니다.
4. 속성
Search 전용
없음. properties, events, elements, innerComponents 모두 PureField의 것을 spread만 하고 아무것도 추가하지 않습니다 (va_component.js:1220-1223).
PureField 상속 (Input과 동일)
속성설명
| value | 검색어 값 |
| placeholder | 플레이스홀더 |
| name | 폼 name |
| readonly / disabled | 상태 |
| required | 필수 표시 |
| autocomplete | HTML autocomplete 속성 |
| textAlign | 정렬 |
| size | 크기 |
| appearance | 시각 스타일 |
| masking | 마스킹 패턴 (거의 안 씀) |
| maxLength / byteMaxLength | 글자 수 제한 |
| stopPropagation / preventParentFieldEvent | 이벤트 제어 |
⚠️ 주의: type 속성을 옵션으로 넘겨도 무시됩니다 — 생성자에서 this.type = 'search'로 강제 세팅되기 때문에 setOption() 이후에도 그대로. type: 'text'로 만들고 싶으면 그냥 Va.Input을 쓰세요.
⚠️ Va.Input의 numberComma는 여기서 지원 안 됨 — properties 배열에 추가되지 않아서 setOption()이 인식 못 함.
5. 이벤트 (PureField 상속)
Input과 완전히 동일합니다.
이벤트시그니처
| change | (component, element, evt) |
| focus / blur | (component, element, evt) — blur는 200ms debounce |
| click | (component, element, evt) |
| keydown / keyup / keypress | (component, element, keyCode, evt) |
| contextmenu / mousedown | (component, element, evt) |
자주 쓰는 패턴: Enter로 검색 실행
{
tagName: 'search',
placeholder: '이름으로 검색',
onKeydown: 'onSearchKey'
}
onSearchKey(component, element, keyCode, evt) {
if (keyCode === 13) { // Enter
const keyword = component.getValue();
this.doSearch(keyword);
}
}
자주 쓰는 패턴: 실시간 필터링 (debounce)
onSearchKey(component, element, keyCode, evt) {
clearTimeout(this._searchTimer);
this._searchTimer = setTimeout(() => {
this.filterList(component.getValue());
}, 300);
}
Search 자체엔 debounce 기능이 없어서 이런 식으로 손으로 걸어야 합니다.
브라우저 × 버튼으로 지웠을 때
브라우저의 지우기 버튼을 눌러 값이 비워지면 표준 change 이벤트가 발생합니다 — 그때 component.getValue()는 빈 문자열. 특별한 커스텀 이벤트는 없습니다.
6. 메서드 (PureField 상속)
Input과 완전히 동일:
메서드설명
| getValue() / setValue(value) | 값 조회/설정 |
| setDisabled(bool) / disable() / enable() / getDisabled() | 비활성화 |
| setReadOnly(bool) / setReadonly(bool) / getReadOnly() | 읽기 전용 |
| focus() / blur() | 포커스 제어 |
7. 내부 구조
Input과 완전히 동일한 구조 (부모 클래스가 같으니까):
<div elname="element" class="va-input [size] [focused] ..." tag-name="input" field="true">
<div elname="fieldWrapper" class="field-wrapper">
<input elname="field" type="search" style="border:0px" ...>
<div elname="focusLine" class="focus-line"></div>
</div>
</div>
차이는 innermost <input> 태그의 type 속성 하나뿐입니다.
8. Va.Search vs Va.SearchField vs Va.SearchPanel
세 컴포넌트가 이름이 비슷해서 혼동됩니다.
컴포넌트역할
| Va.Search | 순수 검색 입력 (라벨 없음, 이 문서 대상) |
| Va.SearchField | Search + 라벨 + 검증 (Field 계열 래퍼) |
| Va.SearchPanel | 검색 조건 여러 개를 담는 패널 컨테이너 (완전히 다른 컴포넌트) |
혼용 주의: 라벨 붙은 폼 안이면 SearchField, 검색 화면 상단의 조건 영역 전체면 SearchPanel, 헤더/툴바 안 심플한 검색창이면 Search.
9. 언제 쓰나
Search가 맞을 때
- 헤더·툴바·사이드바의 검색창
- 리스트/테이블 상단의 필터 입력창
- 브라우저의 지우기 버튼(×)이 있으면 좋을 때
- 모바일에서 검색 키보드가 뜨면 좋을 때
다른 걸 쓸 때
- 라벨 필요 → Va.SearchField
- 검색 조건 여러 개 필요 → Va.SearchPanel
- 자동완성 드롭다운 필요 → Va.Combobox / Va.Filterbox
- 숫자 콤마 등 특수 포맷 → Va.Input (type:'text' + numberComma)
- 검색이 아닌 일반 텍스트 입력 → Va.Input
10. 알아두면 좋을 주의사항
- numberComma 미지원 — 필요하면 Va.Input 사용.
- type 변경 불가 — 옵션으로 넘겨도 'search'로 강제됨.
- × 버튼 스타일은 브라우저 종속 — 크롬/사파리/엣지는 자동 표시, 파이어폭스는 CSS 커스텀 필요. 브라우저마다 위치/크기가 미묘하게 다름.
- × 버튼 클릭 = 값 지우기 — 별도 이벤트 없이 change만 발생. "지우기 버튼이 눌렸다"를 감지하려면 값이 빈 문자열인 change를 감지.
- debounce 내장 없음 — 실시간 필터링에 쓰려면 keyup에서 setTimeout으로 직접 구현.
- 폼 안이면 Enter 자동 제출 — <input type="search">의 표준 동작. 폼 안에 있으면 사용자가 Enter 누를 때 submit이 발생하므로 원치 않으면 onKeydown에서 preventDefault 필요.
- 모바일 키보드 확인 버튼 — 자동으로 "검색"/"Search"로 표시되어 UX 자연스러움.
- 접근성 — role="searchbox"가 자동으로 붙음 (브라우저 표준). 스크린리더 사용자에게 검색 입력이라고 명확히 전달됨.