diff --git a/src/components/input/MultiSelect.vue b/src/components/input/MultiSelect.vue index 2dd01dcb5..d1d02a4f1 100644 --- a/src/components/input/MultiSelect.vue +++ b/src/components/input/MultiSelect.vue @@ -9,6 +9,41 @@ :max-selected-labels="0" :pt="pt" > + + - +
() +import SearchBox from '@/components/input/SearchBox.vue' -const selectedItems = defineModel<{ name: string; value: string }[]>({ +import TextButton from '../button/TextButton.vue' + +type Option = { name: string; value: string } + +interface Props { + /** Input label shown on the trigger button */ + label?: string + /** Static options for the multiselect (when not using async search) */ + options: Option[] + /** Show search box in the panel header */ + hasSearchBox?: boolean + /** Show selected count text in the panel header */ + showSelectedCount?: boolean + /** Show "Clear all" action in the panel header */ + hasClearButton?: boolean + /** Placeholder for the search input */ + searchPlaceholder?: string +} +const { + label, + options, + hasSearchBox = false, + showSelectedCount = false, + hasClearButton = false, + searchPlaceholder = 'Search...' +} = defineProps() + +const selectedItems = defineModel({ required: true }) - +const searchQuery = defineModel('searchQuery') const selectedCount = computed(() => selectedItems.value.length) -/** - * Pure unstyled mode using only the PrimeVue PT API. - * All PrimeVue built-in checkboxes/headers are hidden via PT (no :deep hacks). - * Visual output matches the previous version exactly. - */ const pt = computed(() => ({ root: ({ props }: MultiSelectPassThroughMethodOptions) => ({ class: [ @@ -97,19 +151,19 @@ const pt = computed(() => ({ dropdown: { class: 'flex shrink-0 cursor-pointer items-center justify-center px-3' }, - header: { class: 'hidden' }, - + header: () => ({ + class: + hasSearchBox || showSelectedCount || hasClearButton ? 'block' : 'hidden' + }), // Overlay & list visuals unchanged overlay: - 'mt-2 bg-white dark-theme:bg-zinc-800 text-neutral dark-theme:text-white rounded-lg border border-solid border-zinc-100', + 'mt-2 bg-white dark-theme:bg-zinc-800 text-neutral dark-theme:text-white rounded-lg border border-solid border-zinc-100 dark-theme:border-zinc-700', list: { class: 'flex flex-col gap-1 p-0 list-none border-none text-xs' }, - // Option row hover tone identical option: 'flex gap-1 items-center p-2 hover:bg-neutral-100/50 dark-theme:hover:bg-zinc-700/50', - // Hide built-in checkboxes entirely via PT (no :deep) pcHeaderCheckbox: { root: { class: 'hidden' }, diff --git a/src/components/input/SearchBox.vue b/src/components/input/SearchBox.vue index 08075b18b..462668a12 100644 --- a/src/components/input/SearchBox.vue +++ b/src/components/input/SearchBox.vue @@ -1,8 +1,6 @@