Combobox
문자열로 항목을 걸러 내고 결과를 이동해 하나를 확정합니다.
용법
앞부분 검색
현재 검색어로 시작하는 항목만 찾습니다.
현재 검색어로 시작하는 항목만 찾습니다.
<!-- Combobox / Prefix -->
<script setup lang="ts">
import { ComboboxRoot, ComboboxInput, ComboboxContent, ComboboxItem, ComboboxEmpty } from '@sectile/vue/combobox'
const environments = [
{ id: 'production', label: 'Production', detail: 'customer.app' },
{ id: 'staging', label: 'Staging', detail: 'staging.customer.app' },
{ id: 'development', label: 'Development', detail: 'Local workspace' },
]
const environmentIDs = environments.map(({ id }) => id)
const environmentLabel = (id: string) => environments.find(item => item.id === id)?.label ?? id
</script>
<template>
<ComboboxRoot :items="environmentIDs" :text-value="environmentLabel" default-input-value="pro">
<ComboboxInput placeholder="Search environments" />
<ComboboxContent>
<ComboboxItem v-for="item in environments" :key="item.id" :value="item.id">
<strong>{{ item.label }}</strong>
<small>{{ item.detail }}</small>
</ComboboxItem>
<ComboboxEmpty>No matching environment</ComboboxEmpty>
</ComboboxContent>
</ComboboxRoot>
</template>포함 검색
검색어가 중간에 들어간 항목까지 모두 찾습니다.
검색어가 중간에 들어간 항목까지 모두 찾습니다.
<!-- Combobox / Contains -->
<script setup lang="ts">
import { ComboboxRoot, ComboboxInput, ComboboxContent, ComboboxItem, ComboboxEmpty } from '@sectile/vue/combobox'
const environments = [
{ id: 'production', label: 'Production', detail: 'customer.app' },
{ id: 'staging', label: 'Staging', detail: 'staging.customer.app' },
{ id: 'development', label: 'Development', detail: 'Local workspace' },
]
const environmentIDs = environments.map(({ id }) => id)
const environmentLabel = (id: string) => environments.find(item => item.id === id)?.label ?? id
</script>
<template>
<ComboboxRoot :items="environmentIDs" :text-value="environmentLabel" default-input-value="pro">
<ComboboxInput placeholder="Search environments" />
<ComboboxContent>
<ComboboxItem v-for="item in environments" :key="item.id" :value="item.id">
<strong>{{ item.label }}</strong>
<small>{{ item.detail }}</small>
</ComboboxItem>
<ComboboxEmpty>No matching environment</ComboboxEmpty>
</ComboboxContent>
</ComboboxRoot>
</template>외부 상태 관리
현재 값은 부모가 관리하고, 허용된 변경을 컴포넌트에 다시 전달합니다.
현재 값은 부모가 관리하고, 허용된 변경을 컴포넌트에 다시 전달합니다.
<!-- Combobox / Controlled -->
<script setup lang="ts">
import { ComboboxRoot, ComboboxInput, ComboboxContent, ComboboxItem, ComboboxEmpty } from '@sectile/vue/combobox'
const environments = [
{ id: 'production', label: 'Production', detail: 'customer.app' },
{ id: 'staging', label: 'Staging', detail: 'staging.customer.app' },
{ id: 'development', label: 'Development', detail: 'Local workspace' },
]
const environmentIDs = environments.map(({ id }) => id)
const environmentLabel = (id: string) => environments.find(item => item.id === id)?.label ?? id
</script>
<template>
<ComboboxRoot :items="environmentIDs" :text-value="environmentLabel" default-input-value="pro">
<ComboboxInput placeholder="Search environments" />
<ComboboxContent>
<ComboboxItem v-for="item in environments" :key="item.id" :value="item.id">
<strong>{{ item.label }}</strong>
<small>{{ item.detail }}</small>
</ComboboxItem>
<ComboboxEmpty>No matching environment</ComboboxEmpty>
</ComboboxContent>
</ComboboxRoot>
</template>예시
한글 조합 입력
한글 조합이 끝날 때까지 조합 중인 문자열과 확정된 검색어를 나눠 관리합니다.
한글 조합이 끝날 때까지 조합 중인 문자열과 확정된 검색어를 나눠 관리합니다.
<!-- Combobox / Ime -->
<script setup lang="ts">
import { ComboboxRoot, ComboboxInput, ComboboxContent, ComboboxItem, ComboboxEmpty } from '@sectile/vue/combobox'
const environments = [
{ id: 'production', label: 'Production', detail: 'customer.app' },
{ id: 'staging', label: 'Staging', detail: 'staging.customer.app' },
{ id: 'development', label: 'Development', detail: 'Local workspace' },
]
const environmentIDs = environments.map(({ id }) => id)
const environmentLabel = (id: string) => environments.find(item => item.id === id)?.label ?? id
</script>
<template>
<ComboboxRoot :items="environmentIDs" :text-value="environmentLabel" default-input-value="pro">
<ComboboxInput placeholder="Search environments" />
<ComboboxContent>
<ComboboxItem v-for="item in environments" :key="item.id" :value="item.id">
<strong>{{ item.label }}</strong>
<small>{{ item.detail }}</small>
</ComboboxItem>
<ComboboxEmpty>No matching environment</ComboboxEmpty>
</ComboboxContent>
</ComboboxRoot>
</template>Floating 위치
이 컴포넌트는 공통 위치 엔진을 사용합니다. 실시간 위치 예시에서 side, align, 간격, 충돌 경계, strategy, tracking을 바꾸며 계산 결과를 확인할 수 있습니다.
API
Vue 패키지: @sectile/vue/combobox
ComboboxRootComboboxInputComboboxContentComboboxItemComboboxEmpty
Props
ComboboxRootProps
align기준 요소를 중심으로 팝업 내용을 정렬할 위치입니다.
as이 파트가 렌더링할 요소 또는 컴포넌트입니다.
asChild하나뿐인 자식 요소에 파트 속성을 직접 합칠지 여부입니다.
avoidCollisions팝업이 화면 안에 남도록 위치를 뒤집거나 이동할지 여부입니다.
collisionBoundary팝업을 화면 안에 유지할 때 사용할 경계입니다.
collisionPadding팝업과 충돌 경계 사이에 둘 간격입니다.
defaultInputValue편집 입력에 처음 표시할 내부 관리 문자열입니다.
defaultOpen컴포넌트가 관리하는 초기 열림 상태입니다.
defaultValue컴포넌트가 값을 관리할 때 사용할 초깃값입니다.
disabled사용자 조작을 막을지 여부입니다.
hideWhenDetached기준 요소가 레이아웃에서 벗어나면 팝업을 숨길지 여부입니다.
inputValue편집 입력에 표시할 외부 제어 문자열입니다.
items컴포넌트가 관리할 순서 있는 항목 값입니다.
label보조 기술이 읽는 컨트롤 이름입니다.
modelValue부모가 상태를 관리할 때 사용할 현재 값입니다.
open연결된 팝업이나 펼침 영역이 열려 있는지 여부입니다.
policies검증, 이동, 선택 동작을 조정하는 정책입니다.
position실행 요소를 기준으로 팝업 위치를 계산할지 여부입니다.
readonly값 확인만 허용하는 읽기 전용 상태 여부입니다.
side기준 요소를 중심으로 팝업을 우선 배치할 방향입니다.
sideOffset팝업과 기준 요소 사이 거리입니다.
strategy기준 요소에 연결된 콘텐츠의 CSS 위치 전략입니다.
tracking기준 요소에 연결된 콘텐츠가 열린 동안 위치를 갱신할 방식입니다.
ComboboxItemProps
as이 파트가 렌더링할 요소 또는 컴포넌트입니다.
asChild하나뿐인 자식 요소에 파트 속성을 직접 합칠지 여부입니다.
disabled사용자 조작을 막을지 여부입니다.
value이 계약이 노출하는 현재 값입니다.
ComboboxPartProps
as이 파트가 렌더링할 요소 또는 컴포넌트입니다.
asChild하나뿐인 자식 요소에 파트 속성을 직접 합칠지 여부입니다.
슬롯
ComboboxRootSlotProps
disabled사용자 조작을 막을지 여부입니다.
highlightedValue조작 대상으로 강조된 현재 값입니다.
inputValue현재 편집 입력 문자열입니다.
open연결된 팝업이나 펼침 영역이 열려 있는지 여부입니다.
readonly값 확인만 허용하는 읽기 전용 상태 여부입니다.
value이 계약이 노출하는 현재 값입니다.
ComboboxItemSlotProps
disabled사용자 조작을 막을지 여부입니다.
highlighted조작 대상으로 강조된 항목인지 여부입니다.
selected현재 선택된 항목인지 여부입니다.
value이 계약이 노출하는 현재 값입니다.
이벤트
ComboboxRoot
accept현재 입력이 허용된 값으로 확정될 때 발생합니다.
highlight강조된 항목이 바뀔 때 발생합니다.
update:inputValue편집 입력 문자열이 바뀔 때 발생합니다.
update:modelValue컴포넌트가 외부 제어 값의 변경을 요청할 때 발생합니다.
update:open컴포넌트가 새 열림 상태를 요청할 때 발생합니다.
기타 타입
ComboboxValueChangeHandler
type ComboboxValueChangeHandler = (value: string | null) => voidComboboxInputValueChangeHandler
type ComboboxInputValueChangeHandler = (value: string) => voidComboboxOpenChangeHandler
type ComboboxOpenChangeHandler = (value: boolean) => voidComboboxHighlightHandler
type ComboboxHighlightHandler = (value: string | null) => voidComboboxAcceptHandler
type ComboboxAcceptHandler = (value: string) => void파트
공통 범위: [data-scope="combobox"]. 컴포넌트 내부로 스타일을 제한할 때 파트 선택자와 함께 사용합니다.
| 파트 | 선택자 | 역할 | 추가 속성 |
|---|---|---|---|
root | [data-part="root"] | 컴포넌트 경계와 내부 파트를 묶습니다. | — |
input | [data-part="input"] | 편집 값이나 초안을 입력받습니다. | — |
content | [data-part="content"] | 현재 상태에 맞는 컴포넌트 콘텐츠를 담습니다. | — |
item | [data-part="item"] | 선택하거나 실행할 수 있는 항목 하나입니다. | — |
empty | [data-part="empty"] | 검색 결과가 빈 상태일 때 안내를 표시합니다. | — |
키보드 동작
| 키 | 동작 |
|---|---|
| Arrow Down / Arrow Up | 팝업을 열고 현재 선택 항목을 이동합니다. |
| Enter | 현재 선택 항목을 확정합니다. |
| Escape | 확정된 값을 유지한 채 팝업을 닫습니다. |
| Text input | IME 조합 입력을 유지하며 항목을 검색합니다. |
접근성
입력란은 자동 완성·열림·팝업 연결·현재 항목을 노출하고 각 항목은 선택 상태를 노출합니다.
관련 WAI-ARIA 패턴에서 호스트 접근성 규칙을 확인할 수 있습니다.
