Appearance
FilterSingleDropdown
기본 사용법
FilterSingleDropdown은 필터링 기능이 추가된 단일 선택 드롭다운 컴포넌트입니다. 사용자는 검색어를 입력하여 목록을 필터링할 수 있으며, 하나의 항목만 선택할 수 있습니다. 선택된 항목은 드롭다운 버튼에 표시됩니다.
vue
<script setup lang="ts">
import { ref, computed } from 'vue';
import {
FilterSingleDropdown,
ICON_TYPE,
} from '@jennifersoft/vue-components-v2';
const sampleItems = [
{ label: '딸기', value: 'strawberry' },
{ label: '딸기우유', value: 'strawberry_milk' },
{ label: '딸기케이크', value: 'strawberry_cake' },
{ label: '딸기아이스크림', value: 'strawberry_ice' },
{ label: '초코', value: 'choco' },
{ label: '초코우유', value: 'choco_milk' },
{ label: '초코케이크', value: 'choco_cake' },
{ label: '초코아이스크림', value: 'choco_ice', disabled: true },
{ label: '바나나', value: 'banana' },
{ label: '바나나우유', value: 'banana_milk' },
{ label: '바나나케이크', value: 'banana_cake' },
{ label: '바나나아이스크림', value: 'banana_ice' },
{ label: '사과주스', value: 'apple_juice' },
{ label: '사과파이', value: 'apple_pie' },
{ label: '사과잼', value: 'apple_jam' },
];
const selectedItemValue = ref(null);
const isOpen = ref(false);
const searchKeyword = ref('');
const filteredItems = computed(() => {
if (!searchKeyword.value) return sampleItems;
return sampleItems.filter((item) =>
item.label.toLowerCase().includes(searchKeyword.value.toLowerCase())
);
});
</script>
<template>
<filter-single-dropdown
v-model:selected-item-value="selectedItemValue"
v-model:open="isOpen"
v-model:search-keyword="searchKeyword"
:list="filteredItems"
title="과일 선택"
:text="{
whenFilterEmpty: '과일을 선택하세요',
noResult: '검색 결과가 없습니다',
noList: '목록이 없습니다',
}"
:leading-icon="ICON_TYPE.search"
/>
</template>
Props
이름 | 타입 | 기본값 | 설명 |
---|---|---|---|
list | Array<{ label: string, value: PropertyKey, disabled?: boolean }> | [] | 드롭다운 메뉴에 표시할 항목 목록 |
title | string | undefined | 드롭다운 라벨 (선택사항) |
text | { whenFilterEmpty: string, noResult: string, noList: string } | - | 텍스트 라벨 설정 객체 |
leadingIcon | IconTypes | undefined | 입력 필드 왼쪽에 표시할 아이콘 (선택사항) |
type | 'outlined' | 'contained' | 'outlined' | 입력 박스 스타일(외곽선/채움) |
visibleRows | number | 10 | 드롭다운 메뉴에 표시할 최대 행 수 |
v-model
이름 | 타입 | 기본값 | 설명 |
---|---|---|---|
open | boolean | false | 드롭다운 메뉴의 열림 상태 |
selectedItemValue | PropertyKey | null | null | 선택된 항목의 값 |
searchKeyword | string | '' | 현재 검색 키워드 |
이벤트
이름 | 파라미터 | 설명 |
---|---|---|
update:selectedItem | PropertyKey | 선택된 항목이 변경될 때 발생 |
update:searchKeyword | string | 검색 키워드가 변경될 때 발생 |
검색 및 필터링 기능
FilterSingleDropdown은 사용자가 검색어를 입력하면 목록을 실시간으로 필터링합니다. 필터링된 목록에서 사용자는 원하는 항목을 선택할 수 있습니다.
vue
<script setup lang="ts">
import { ref, computed } from 'vue';
import {
FilterSingleDropdown,
FloatLabel,
ICON_TYPE,
} from '@jennifersoft/vue-components-v2';
const selectedItemValue = ref('strawberry_banana_ice');
const isOpen = ref(false);
const searchKeyword = ref('');
// 샘플 아이템 목록
const sampleItems = [
{ label: '딸기', value: 'strawberry' },
{ label: '딸기우유', value: 'strawberry_milk' },
{ label: '초코', value: 'choco' },
{ label: '초코우유', value: 'choco_milk' },
/* ... 그 외 여러 항목들 */
];
const filteredItems = computed(() => {
if (!searchKeyword.value) return sampleItems;
return sampleItems.filter((item) =>
item.label.toLowerCase().includes(searchKeyword.value.toLowerCase())
);
});
</script>
<template>
<float-label fixed position="on">
<filter-single-dropdown
v-model:selected-item-value="selectedItemValue"
v-model:open="isOpen"
v-model:search-keyword="searchKeyword"
:list="filteredItems"
title="과일 필터"
:text="{
whenFilterEmpty: '과일 필터링하기',
noResult: '검색 결과가 없습니다',
noList: '목록이 없습니다',
}"
:leading-icon="ICON_TYPE.filter"
/>
<label>과일 필터</label>
</float-label>
</template>
빈 리스트 처리
FilterSingleDropdown은 리스트가 비어 있을 때 적절한 메시지를 표시합니다. 검색어가 있는 경우는 "검색 결과가 없습니다"라는 메시지가, 검색어가 없는 경우는 리스트가 비어 있다는 것을 알립니다.
vue
<script setup lang="ts">
import { ref } from 'vue';
import {
FilterSingleDropdown,
ICON_TYPE,
} from '@jennifersoft/vue-components-v2';
const emptySelectedItemValue = ref(null);
const isEmptyOpen = ref(false);
const emptySearchKeyword = ref('');
</script>
<template>
<filter-single-dropdown
v-model:selected-item-value="emptySelectedItemValue"
v-model:open="isEmptyOpen"
v-model:search-keyword="emptySearchKeyword"
:list="[]"
title="빈 리스트 예시"
:text="{
whenFilterEmpty: '항목이 없습니다',
noResult: '검색 결과가 없습니다',
noList: '리스트가 없습니다',
}"
:leading-icon="ICON_TYPE.list"
/>
</template>
크기(Size) 설정 예시
FilterSingleDropdown 컴포넌트는 'small', 'medium', 'large' 세 가지 크기 옵션을 지원합니다. 기본값은 'medium'입니다.
vue
<script setup lang="ts">
import { ref, computed } from 'vue';
import {
FilterSingleDropdown,
ICON_TYPE,
} from '@jennifersoft/vue-components-v2';
const selectedItemValue = ref(null);
const isOpen = ref(false);
const searchKeyword = ref('');
// 샘플 아이템 목록
const sampleItems = [
/* 아이템 목록 */
];
const filteredItems = computed(() => {
if (!searchKeyword.value) return sampleItems;
return sampleItems.filter((item) =>
item.label.toLowerCase().includes(searchKeyword.value.toLowerCase())
);
});
</script>
<template>
<filter-single-dropdown
v-model:selected-item-value="selectedItemValue"
v-model:open="isOpen"
v-model:search-keyword="searchKeyword"
:list="filteredItems"
title="과일 선택"
size="large"
:text="{
whenFilterEmpty: '과일을 선택하세요',
noResult: '검색 결과가 없습니다',
noList: '목록이 없습니다',
}"
:leading-icon="ICON_TYPE.search"
/>
</template>
타입(Type) 스타일
Outlined(기본)와 Contained(배경 채움) 두 가지 스타일을 지원합니다.
vue
<script setup lang="ts">
import { ref, computed } from 'vue';
import {
FilterSingleDropdown,
ICON_TYPE,
} from '@jennifersoft/vue-components-v2';
const sampleItems = [
{ label: '딸기', value: 'strawberry' },
{ label: '딸기우유', value: 'strawberry_milk' },
// ...
];
const selectedItemValueTypeOutlined = ref(null);
const selectedItemValueTypeContained = ref(null);
const isOpenTypeOutlined = ref(false);
const isOpenTypeContained = ref(false);
const searchKeywordTypeOutlined = ref('');
const searchKeywordTypeContained = ref('');
const filteredItemsTypeOutlined = computed(() => {
if (!searchKeywordTypeOutlined.value) return sampleItems;
return sampleItems.filter((item) =>
item.label
.toLowerCase()
.includes(searchKeywordTypeOutlined.value.toLowerCase())
);
});
const filteredItemsTypeContained = computed(() => {
if (!searchKeywordTypeContained.value) return sampleItems;
return sampleItems.filter((item) =>
item.label
.toLowerCase()
.includes(searchKeywordTypeContained.value.toLowerCase())
);
});
</script>
<template>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<filter-single-dropdown
v-model:open="isOpenTypeOutlined"
v-model:selected-item-value="selectedItemValueTypeOutlined"
v-model:search-keyword="searchKeywordTypeOutlined"
:list="filteredItemsTypeOutlined"
title="Outlined (기본)"
type="outlined"
:text="{
whenFilterEmpty: '과일을 선택하세요',
noResult: '검색 결과가 없습니다',
noList: '목록이 없습니다',
}"
:leading-icon="ICON_TYPE.search"
/>
<filter-single-dropdown
v-model:open="isOpenTypeContained"
v-model:selected-item-value="selectedItemValueTypeContained"
v-model:search-keyword="searchKeywordTypeContained"
:list="filteredItemsTypeContained"
title="Contained"
type="contained"
:text="{
whenFilterEmpty: '과일을 선택하세요',
noResult: '검색 결과가 없습니다',
noList: '목록이 없습니다',
}"
:leading-icon="ICON_TYPE.search"
/>
</div>
</template>
접근성
키 | 기능 |
---|---|
방향키 ↑ / ↓ | 메뉴 항목 포커스를 한 단계씩 이동 |
Alt + ↑ / Alt + ↓ | 메뉴 항목 포커스를 5개씩 이동 (macOS에서는 Option 키) |
Ctrl + ↑ / Ctrl + ↓ | 가장 처음 / 마지막 메뉴 항목으로 이동 (macOS에서는 Command 키) |
Home | 가장 처음 메뉴 항목으로 이동 |
End | 가장 마지막 메뉴 항목으로 이동 |
Enter | 현재 포커스된 메뉴 항목 선택 |
Escape | 드롭다운 메뉴 닫기 |