VanillaFront 2026. 9. 10. 14:49

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. 알아두면 좋을 주의사항

  1. numberComma 미지원 — 필요하면 Va.Input 사용.
  2. type 변경 불가 — 옵션으로 넘겨도 'search'로 강제됨.
  3. × 버튼 스타일은 브라우저 종속 — 크롬/사파리/엣지는 자동 표시, 파이어폭스는 CSS 커스텀 필요. 브라우저마다 위치/크기가 미묘하게 다름.
  4. × 버튼 클릭 = 값 지우기 — 별도 이벤트 없이 change만 발생. "지우기 버튼이 눌렸다"를 감지하려면 값이 빈 문자열인 change를 감지.
  5. debounce 내장 없음 — 실시간 필터링에 쓰려면 keyup에서 setTimeout으로 직접 구현.
  6. 폼 안이면 Enter 자동 제출  <input type="search">의 표준 동작. 폼 안에 있으면 사용자가 Enter 누를 때 submit이 발생하므로 원치 않으면 onKeydown에서 preventDefault 필요.
  7. 모바일 키보드 확인 버튼 — 자동으로 "검색"/"Search"로 표시되어 UX 자연스러움.
  8. 접근성  role="searchbox"가 자동으로 붙음 (브라우저 표준). 스크린리더 사용자에게 검색 입력이라고 명확히 전달됨.