diff --git a/docs/components/content/examples/SelectMenuExampleClearable.vue b/docs/components/content/examples/SelectMenuExampleClearable.vue new file mode 100644 index 00000000..ba019e27 --- /dev/null +++ b/docs/components/content/examples/SelectMenuExampleClearable.vue @@ -0,0 +1,102 @@ + + + diff --git a/docs/content/2.components/select-menu.md b/docs/content/2.components/select-menu.md index bb28993a..859bc109 100644 --- a/docs/content/2.components/select-menu.md +++ b/docs/content/2.components/select-menu.md @@ -156,7 +156,18 @@ Use the `searchableLazy` prop to control the immediacy of data requests. --- component: 'select-menu-example-search-async' componentProps: - class: 'w-full lg:w-48' + class: 'w-full lg:w-48' +--- +:: + +## Clearable +Use the `clearable` prop to enable the remove selected option. + +::component-example +--- +component: 'select-menu-example-clearable' +componentProps: + class: 'w-full lg:w-52' --- :: diff --git a/playground/app.vue b/playground/app.vue index 4df511af..5c8f5a2b 100644 --- a/playground/app.vue +++ b/playground/app.vue @@ -1,21 +1,23 @@ - - + + + + diff --git a/src/runtime/components/forms/SelectMenu.vue b/src/runtime/components/forms/SelectMenu.vue index b8410ea4..59299503 100644 --- a/src/runtime/components/forms/SelectMenu.vue +++ b/src/runtime/components/forms/SelectMenu.vue @@ -39,13 +39,22 @@ {{ label }} {{ placeholder || ' ' }} + + + + + - - @@ -152,6 +161,7 @@ import { useFormGroup } from '../../composables/useFormGroup' import { get, mergeConfig } from '../../utils' import { useInjectButtonGroup } from '../../composables/useButtonGroup' import type { SelectSize, SelectColor, SelectVariant, PopperOptions, Strategy, DeepPartial } from '../../types/index' +import type { Button } from '../../types/button' // @ts-expect-error import appConfig from '#build/app.config' import { select, selectMenu } from '#ui/ui.config' @@ -344,11 +354,8 @@ export default defineComponent({ clearableIcon: { type: String, default: () => config.default.clerableIcon - }, - closeOnClear: { - type: Boolean, - default: () => configMenu.default.closeOnClear } + }, emits: ['update:modelValue', 'update:query', 'open', 'close', 'change', 'clear'], setup(props, { emit, slots }) { @@ -463,10 +470,22 @@ export default defineComponent({ const canClearValue = computed(() => props.clearable && (Array.isArray(selected.value) ? selected.value.length > 0 : !!selected.value)) + const clearableWrapperClass = computed(() => { + return twJoin( + ui.value.icon.clearable.wrapper, + ui.value.icon.clearable.padding[size.value] + ) + }) + + const clearableButtonClass = computed(() => { + return twJoin( + ui.value.icon.base, + color.value && appConfig.ui.colors.includes(color.value) && ui.value.icon.color.replaceAll('{color}', color.value), + props.loading && ui.value.icon.loading + ) + }) + const trailingIconName = computed(() => { - if (canClearValue.value) { - return props.clearableIcon - } if (props.loading && !isLeading.value) { return props.loadingIcon } @@ -598,11 +617,8 @@ export default defineComponent({ query.value = event.target.value } - function onClear(e: Event) { + function onClear() { if (canClearValue.value) { - if (container.value && !props.closeOnClear) { - e.stopPropagation() - } emit('update:modelValue', props.multiple ? [] : null) emit('clear') emitFormChange() @@ -658,7 +674,10 @@ export default defineComponent({ query, onUpdate, onQueryChange, - trailingSlotProps + trailingSlotProps, + canClearValue, + clearableWrapperClass, + clearableButtonClass } } }) diff --git a/src/runtime/ui.config/forms/input.ts b/src/runtime/ui.config/forms/input.ts index ddf2c500..c61dc6be 100644 --- a/src/runtime/ui.config/forms/input.ts +++ b/src/runtime/ui.config/forms/input.ts @@ -98,6 +98,18 @@ export default { 'lg': 'px-3.5', 'xl': 'px-3.5' } + }, + clearable: { + wrapper: 'absolute inset-y-0 end-6 flex items-center', + pointer: 'pointer-events-auto', + padding: { + '2xs': 'px-2', + 'xs': 'px-2.5', + 'sm': 'px-2.5', + 'md': 'px-3', + 'lg': 'px-3.5', + 'xl': 'px-3.5' + } } }, default: { diff --git a/src/runtime/ui.config/forms/selectMenu.ts b/src/runtime/ui.config/forms/selectMenu.ts index 56e03fb7..96b56686 100644 --- a/src/runtime/ui.config/forms/selectMenu.ts +++ b/src/runtime/ui.config/forms/selectMenu.ts @@ -23,7 +23,6 @@ export default { default: { selectedIcon: 'i-heroicons-check-20-solid', clearSearchOnClose: false, - closeOnClear: true, showCreateOptionWhen: 'empty', searchablePlaceholder: { label: 'Search...'