@sparklingopinions/sparkling-ui 0.9.1 → 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"Select.js","names":["_sfc_main","Select_vue_vue_type_script_setup_true_lang_default","Select_default"],"sources":["../../../src/components/Select/Select.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"T extends SelectValue\">\nimport { computed, nextTick, ref, shallowRef, useAttrs } from 'vue'\n\nimport {\n ListboxContent,\n ListboxFilter,\n ListboxItem,\n ListboxRoot,\n ListboxVirtualizer,\n PopoverAnchor,\n PopoverContent,\n PopoverPortal,\n PopoverRoot\n} from 'reka-ui'\n\nimport type { Hue } from '../../utils/hues'\nimport { useFieldControl } from '../FormField/context'\nimport Icon from '../Icon/Icon.vue'\nimport Spinner from '../Spinner/Spinner.vue'\nimport Tag from '../Tag/Tag.vue'\nimport CheckIcon from '../internal/CheckIcon.vue'\nimport type { SelectOption, SelectValue } from './types'\n\nexport interface SelectProps<T extends SelectValue> {\n options: SelectOption<T>[]\n /** The options for chosen values that aren't in `options`, such as a saved choice while `options` holds search\n * results. Options picked from the list are remembered without it. */\n selectedOptions?: SelectOption<T>[]\n multiple?: boolean\n /** Lets a single choice be removed, as a tag in the filter row or with Backspace there. */\n clearable?: boolean\n /** A filter row at the top of the list; on by default for `multiple`, `canCreate` or more than 8 options. */\n searchable?: boolean\n /** Narrows `options` to what's typed: by label, or by your function. `false` when `options` are already the results\n * for the query, such as from a server search through `query-change`. */\n filter?: boolean | ((option: SelectOption<T>, query: string) => boolean)\n /** Offers to create what was typed, through `createOption`. */\n canCreate?: boolean\n /** Makes the created option; by default its value is its label. */\n createOption?: (draft: { label: string; color?: Hue }) => SelectOption<T> | Promise<SelectOption<T>>\n /** Creates with a hue, shown as a tag. */\n createColored?: boolean\n loading?: boolean\n /** 36px for forms, 28px for table feet and toolbars. */\n size?: 'md' | 'sm'\n disabled?: boolean\n invalid?: boolean\n placeholder?: string\n searchPlaceholder?: string\n emptyLabel?: string\n createLabel?: string\n removeLabel?: string\n /** Where the list opens; it flips when there's no room. */\n side?: 'bottom' | 'top'\n align?: 'start' | 'end'\n /** The list's width, when it should differ from the trigger's, e.g. `20rem`. */\n panelWidth?: string\n}\n\n// Attributes (aria-label, class for its width) go to the trigger, the one element in the page's flow.\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<SelectProps<T>>(), {\n selectedOptions: () => [],\n searchable: undefined,\n filter: true,\n createOption: undefined,\n createColored: true,\n size: 'md',\n placeholder: 'Select an option',\n searchPlaceholder: 'Type to filter',\n emptyLabel: 'No results found',\n createLabel: 'Create',\n removeLabel: 'Remove',\n side: 'bottom',\n align: 'start',\n panelWidth: undefined\n})\n\nconst emit = defineEmits<{ 'query-change': [query: string]; 'create-error': [error: unknown] }>()\n\n// An aria-label would hide the trigger's visible value from its name; it's said before the value instead.\nconst attrs = useAttrs()\nconst label = computed(() => attrs['aria-label'] as string | undefined)\nconst triggerAttrs = computed(() => Object.fromEntries(Object.entries(attrs).filter(([key]) => key !== 'aria-label')))\n\nconst model = defineModel<T | T[] | null>({ default: null })\n\nconst open = ref(false)\nconst query = ref('')\nconst keyboard = ref(false)\n\nconst values = computed<T[]>(() =>\n Array.isArray(model.value) ? model.value : model.value === null || model.value === undefined ? [] : [model.value]\n)\n// Options picked from earlier results, which `options` may no longer hold.\nconst picked = shallowRef<SelectOption<T>[]>([])\nconst selected = computed(() =>\n values.value\n .map((value) =>\n [props.options, props.selectedOptions, picked.value]\n .map((list) => list.find((option) => option.value === value))\n .find((option) => !!option)\n )\n .filter((option) => !!option)\n)\nconst search = computed(\n () =>\n props.searchable ??\n (props.multiple || props.canCreate || props.clearable || props.filter === false || props.options.length > 8)\n)\nconst removable = computed(() => props.multiple || props.clearable)\nconst matches = (option: SelectOption<T>, text: string) =>\n typeof props.filter === 'function'\n ? props.filter(option, text)\n : option.label.toLowerCase().includes(text.toLowerCase())\nconst listed = computed(() => {\n const text = query.value.trim()\n return props.options\n .filter((option) => !(props.multiple && search.value && values.value.includes(option.value)))\n .filter((option) => !text || props.filter === false || matches(option, text))\n})\nconst showCreate = computed(() => {\n const text = query.value.trim().toLowerCase()\n return props.canCreate && !!text && !props.options.some((option) => option.label.toLowerCase() === text)\n})\n// More than this and the list renders only the rows in view.\nconst virtual = computed(() => listed.value.length > 20)\n\nconst createHues: Hue[] = ['gray', 'purple', 'red', 'green', 'orange', 'pink', 'blue', 'slate']\nconst newHue = computed(() => createHues[query.value.length % createHues.length])\nconst CREATE = { create: true } as const\n\nconst { attrs: fieldAttrs, invalid: isInvalid } = useFieldControl(\n () => undefined,\n () => props.invalid\n)\n\nfunction setQuery(text: string) {\n query.value = text\n emit('query-change', text)\n}\n\nfunction show(viaKeyboard: boolean) {\n if (props.disabled) return\n keyboard.value = viaKeyboard\n open.value = true\n}\n\nfunction close() {\n open.value = false\n if (query.value) setQuery('')\n}\n\nfunction toggle(event?: Event) {\n if (open.value) close()\n // A click from the keyboard (Enter, Space) has no pointer position.\n else show(!!event && (event as MouseEvent).detail === 0)\n}\n\nfunction choose(option: SelectOption<T>) {\n picked.value = [option, ...picked.value.filter((known) => known.value !== option.value)]\n if (props.multiple) {\n model.value = values.value.includes(option.value)\n ? values.value.filter((value) => value !== option.value)\n : [...values.value, option.value]\n setQuery('')\n } else {\n model.value = option.value\n close()\n }\n}\n\nconst creating = ref(false)\n\n// A failed createOption keeps what was typed, so it can be tried again.\nasync function create() {\n if (creating.value) return\n const label = query.value.trim()\n const draft = props.createColored ? { label, color: newHue.value } : { label }\n creating.value = true\n try {\n const option = props.createOption\n ? await props.createOption(draft)\n : ({ value: label as T, label, color: draft.color } as SelectOption<T>)\n choose(option)\n } catch (error) {\n emit('create-error', error)\n } finally {\n creating.value = false\n }\n}\n\nfunction onSelect(event: CustomEvent, row: SelectOption<T> | typeof CREATE) {\n // What's chosen lives in the model; the listbox keeps no selection of its own.\n event.preventDefault()\n if ('create' in row) create()\n else if (!row.disabled) choose(row)\n}\n\nfunction remove(value: T) {\n model.value = props.multiple ? values.value.filter((chosen) => chosen !== value) : null\n}\n\nfunction onKeydown(event: KeyboardEvent) {\n if (['ArrowUp', 'ArrowDown', 'Home', 'End'].includes(event.key)) keyboard.value = true\n if (event.key === 'Backspace' && removable.value && !query.value && values.value.length)\n remove(values.value[values.value.length - 1]!)\n}\n\nfunction onTriggerKeydown(event: KeyboardEvent) {\n if (!open.value && ['ArrowDown', 'ArrowUp'].includes(event.key)) {\n event.preventDefault()\n show(true)\n }\n}\n\n// The filter takes focus when there is one, or else the list, so the arrow keys work at once.\nfunction onOpenAutoFocus(event: Event) {\n event.preventDefault()\n nextTick(() =>\n (event.target as HTMLElement | null)?.querySelector<HTMLElement>('[data-select-filter], [role=\"listbox\"]')?.focus()\n )\n}\n\n// Back to the trigger, which Reka can't find: it's our anchor, not its trigger.\nconst anchor = ref<{ $el: HTMLElement }>()\n\n// Nor does Reka know a press on it isn't outside: closing there would let the click reopen the list.\nfunction onPointerDownOutside(event: CustomEvent<{ originalEvent: PointerEvent }>) {\n const target = event.detail.originalEvent.target\n if (target instanceof Node && anchor.value?.$el?.contains(target)) event.preventDefault()\n}\nfunction returnFocus(event: Event) {\n event.preventDefault()\n anchor.value?.$el?.focus()\n}\n\n// Reka highlights the first option as the list mounts; only the chosen one, or the keyboard, should be.\nconst listbox = ref()\nfunction onHighlight(payload: { value: unknown } | undefined) {\n if (keyboard.value || !payload) return\n if (values.value.includes(payload.value as T)) return\n nextTick(() => listbox.value && !keyboard.value && (listbox.value.highlightedElement = null))\n}\n\nconst triggerSizes = { md: 'min-h-9 pr-2.5 pl-3 text-sm', sm: 'h-7 pr-1.5 pl-2 text-13' }\nconst optionClass =\n 'flex min-h-8 cursor-pointer items-center justify-between gap-3 rounded-lg py-1.5 pr-2 pl-2.5 text-13 whitespace-nowrap text-sui-ink outline-hidden select-none data-disabled:cursor-default data-disabled:opacity-50 data-highlighted:bg-sui-sunken data-[state=checked]:font-medium data-[state=checked]:text-sui-accent group-data-keyboard/list:data-highlighted:sui-ring-inset'\n</script>\n\n<!-- One select for every choice: a short fixed list, a searchable one, several values as tags (`multiple`), or creating\n what was typed (`canCreate`). For a server search, set `:filter=\"false\"` and replace `options` on `query-change`. The `trigger` slot draws your own trigger and gets `open`, `toggle` and `selected`. -->\n<template>\n <PopoverRoot :open=\"open\" @update:open=\"(value) => (value ? show(false) : close())\">\n <PopoverAnchor ref=\"anchor\" as-child>\n <slot name=\"trigger\" :open=\"open\" :selected=\"selected\" :toggle=\"toggle\">\n <button\n v-bind=\"{ ...fieldAttrs, ...triggerAttrs }\"\n :aria-expanded=\"open\"\n aria-haspopup=\"listbox\"\n :aria-invalid=\"isInvalid ? 'true' : undefined\"\n class=\"group inline-flex items-center justify-between gap-1.5 rounded-(--sui-radius-button) border bg-sui-surface text-left text-sui-ink transition-[border-color,box-shadow] duration-150 focus-visible:border-sui-accent focus-visible:sui-ring-field disabled:pointer-events-none disabled:opacity-60\"\n :class=\"[\n triggerSizes[size],\n isInvalid ? 'border-sui-danger-mid' : 'border-sui-line-strong hover:border-sui-ink-muted'\n ]\"\n :disabled=\"disabled\"\n type=\"button\"\n @click=\"toggle\"\n @keydown=\"onTriggerKeydown\"\n >\n <span v-if=\"label\" class=\"sr-only\">{{ label }}: </span>\n <span v-if=\"!selected.length\" class=\"text-sui-ink-faint\">{{ placeholder }}</span>\n <span v-else-if=\"multiple\" class=\"flex flex-wrap gap-1 py-1.25\">\n <Tag\n v-for=\"option in selected\"\n :key=\"option.value\"\n :color=\"option.color ?? undefined\"\n :icon=\"option.icon\"\n :icon-color=\"option.iconColor\"\n :name=\"option.label\"\n />\n </span>\n <Tag\n v-else-if=\"selected[0]!.color\"\n :color=\"selected[0]!.color\"\n :icon=\"selected[0]!.icon\"\n :icon-color=\"selected[0]!.iconColor\"\n :name=\"selected[0]!.label\"\n />\n <span v-else-if=\"selected[0]!.icon\" class=\"inline-flex min-w-0 items-center gap-1.5\">\n <Icon class=\"shrink-0\" :color=\"selected[0]!.iconColor ?? 'ink-subtle'\" :name=\"selected[0]!.icon\" />\n <span class=\"truncate whitespace-nowrap\">{{ selected[0]!.label }}</span>\n </span>\n <span v-else class=\"min-w-0 truncate whitespace-nowrap\">{{ selected[0]!.label }}</span>\n <svg\n aria-hidden=\"true\"\n class=\"size-4 shrink-0 fill-none stroke-sui-ink-muted transition-transform duration-150 group-aria-expanded:rotate-180\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"1.5\"\n viewBox=\"0 0 16 16\"\n >\n <path d=\"M4.5 6.5 8 10l3.5-3.5\" />\n </svg>\n </button>\n </slot>\n </PopoverAnchor>\n <PopoverPortal>\n <PopoverContent\n :align=\"align\"\n :aria-label=\"label ?? placeholder\"\n class=\"z-[1100] overflow-hidden rounded-xl border border-sui-line-subtle bg-sui-surface text-sui-ink shadow-lg data-[state=open]:animate-sui-menu-in\"\n :class=\"\n search ? 'min-w-[max(var(--reka-popover-trigger-width),15rem)]' : 'min-w-(--reka-popover-trigger-width)'\n \"\n :side=\"side\"\n :side-offset=\"4\"\n :style=\"panelWidth ? { width: panelWidth } : undefined\"\n @close-auto-focus=\"returnFocus\"\n @open-auto-focus=\"onOpenAutoFocus\"\n @pointer-down-outside=\"onPointerDownOutside\"\n >\n <ListboxRoot\n ref=\"listbox\"\n :highlight-on-hover=\"true\"\n :model-value=\"multiple ? values : (values[0] ?? undefined)\"\n :multiple=\"multiple\"\n @highlight=\"onHighlight\"\n @keydown=\"onKeydown\"\n @pointermove=\"keyboard = false\"\n >\n <div\n v-if=\"search\"\n class=\"flex min-h-11 flex-wrap items-center gap-1 border-b border-sui-line-subtle px-3 py-2.5\"\n >\n <template v-if=\"removable\">\n <Tag\n v-for=\"option in selected\"\n :key=\"option.value\"\n :color=\"option.color ?? undefined\"\n :icon=\"option.icon\"\n :icon-color=\"option.iconColor\"\n :name=\"option.label\"\n removable\n :remove-label=\"removeLabel\"\n @remove=\"remove(option.value)\"\n />\n </template>\n <!-- focus: classes too: an app's forms plugin rings focused text fields, and outranks plain utilities. -->\n <ListboxFilter\n :aria-label=\"label ?? placeholder\"\n class=\"h-5 min-w-16 flex-1 rounded-none border-none bg-transparent p-0 text-13 text-sui-ink shadow-none outline-hidden placeholder:text-sui-ink-faint focus:border-none focus:shadow-none focus:ring-0 focus:outline-hidden\"\n data-select-filter\n :model-value=\"query\"\n :placeholder=\"removable && selected.length ? '' : searchPlaceholder\"\n @update:model-value=\"setQuery\"\n />\n </div>\n <div v-if=\"loading\" class=\"flex justify-center py-6\"><Spinner size=\"sm\" /></div>\n <ListboxContent\n v-else-if=\"listed.length || showCreate\"\n :aria-label=\"label ?? placeholder\"\n class=\"group/list max-h-60 overflow-auto p-1 outline-hidden\"\n :data-keyboard=\"keyboard || undefined\"\n >\n <ListboxVirtualizer\n v-if=\"virtual\"\n v-slot=\"{ option }\"\n :estimate-size=\"32\"\n :options=\"listed\"\n :text-content=\"(option) => option.label\"\n >\n <ListboxItem\n :class=\"optionClass\"\n :disabled=\"option.disabled\"\n :value=\"option.value\"\n @select=\"onSelect($event, option as SelectOption<T>)\"\n >\n <span class=\"inline-flex min-w-0 items-center gap-1.5 truncate\">\n <slot name=\"option\" :option=\"option as SelectOption<T>\">\n <Tag\n v-if=\"option.color\"\n :color=\"option.color\"\n :icon=\"option.icon\"\n :icon-color=\"option.iconColor\"\n :name=\"option.label\"\n />\n <template v-else>\n <Icon\n v-if=\"option.icon\"\n class=\"shrink-0\"\n :color=\"option.iconColor ?? 'ink-subtle'\"\n :name=\"option.icon\"\n />{{ option.label }}\n </template>\n </slot>\n </span>\n <CheckIcon v-if=\"values.includes(option.value)\" />\n </ListboxItem>\n </ListboxVirtualizer>\n <template v-else>\n <ListboxItem\n v-for=\"option in listed\"\n :key=\"option.value\"\n :class=\"optionClass\"\n :disabled=\"option.disabled\"\n :value=\"option.value\"\n @select=\"onSelect($event, option)\"\n >\n <span class=\"inline-flex min-w-0 items-center gap-1.5 truncate\">\n <slot name=\"option\" :option=\"option\">\n <Tag\n v-if=\"option.color\"\n :color=\"option.color\"\n :icon=\"option.icon\"\n :icon-color=\"option.iconColor\"\n :name=\"option.label\"\n />\n <template v-else>\n <Icon\n v-if=\"option.icon\"\n class=\"shrink-0\"\n :color=\"option.iconColor ?? 'ink-subtle'\"\n :name=\"option.icon\"\n />{{ option.label }}\n </template>\n </slot>\n </span>\n <CheckIcon v-if=\"values.includes(option.value)\" />\n </ListboxItem>\n </template>\n <ListboxItem v-if=\"showCreate\" :class=\"optionClass\" :value=\"CREATE\" @select=\"onSelect($event, CREATE)\">\n <span class=\"inline-flex min-w-0 items-center gap-1.5\">\n {{ createLabel }}\n <Tag v-if=\"createColored\" :color=\"newHue\" :name=\"query.trim()\" />\n <strong v-else class=\"font-medium\">“{{ query.trim() }}”</strong>\n </span>\n </ListboxItem>\n </ListboxContent>\n <div v-else class=\"px-3.5 py-3 text-13 text-sui-ink-muted\">{{ emptyLabel }}</div>\n </ListboxRoot>\n </PopoverContent>\n </PopoverPortal>\n </PopoverRoot>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"Select.js","names":["_sfc_main","Select_vue_vue_type_script_setup_true_lang_default","Select_default"],"sources":["../../../src/components/Select/Select.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"T extends SelectValue\">\nimport { computed, nextTick, ref, shallowRef, useAttrs } from 'vue'\n\nimport {\n ListboxContent,\n ListboxFilter,\n ListboxItem,\n ListboxRoot,\n ListboxVirtualizer,\n PopoverAnchor,\n PopoverContent,\n PopoverPortal,\n PopoverRoot\n} from 'reka-ui'\n\nimport type { Hue } from '../../utils/hues'\nimport { useFieldControl } from '../FormField/context'\nimport Icon from '../Icon/Icon.vue'\nimport Spinner from '../Spinner/Spinner.vue'\nimport Tag from '../Tag/Tag.vue'\nimport CheckIcon from '../internal/CheckIcon.vue'\nimport type { SelectOption, SelectValue } from './types'\n\nexport interface SelectProps<T extends SelectValue> {\n options: SelectOption<T>[]\n /** The options for chosen values that aren't in `options`, such as a saved choice while `options` holds search\n * results. Options picked from the list are remembered without it. */\n selectedOptions?: SelectOption<T>[]\n multiple?: boolean\n /** Lets a single choice be removed, as a tag in the filter row or with Backspace there. */\n clearable?: boolean\n /** A filter row at the top of the list; on by default for `multiple`, `canCreate` or more than 8 options. */\n searchable?: boolean\n /** Narrows `options` to what's typed: by label, or by your function. `false` when `options` are already the results\n * for the query, such as from a server search through `query-change`. */\n filter?: boolean | ((option: SelectOption<T>, query: string) => boolean)\n /** Offers to create what was typed, through `createOption`. */\n canCreate?: boolean\n /** Makes the created option; by default its value is its label. */\n createOption?: (draft: { label: string; color?: Hue }) => SelectOption<T> | Promise<SelectOption<T>>\n /** Creates with a hue, shown as a tag. */\n createColored?: boolean\n loading?: boolean\n /** 36px for forms, 28px for table feet and toolbars. */\n size?: 'md' | 'sm'\n disabled?: boolean\n invalid?: boolean\n placeholder?: string\n searchPlaceholder?: string\n emptyLabel?: string\n createLabel?: string\n removeLabel?: string\n /** Where the list opens; it flips when there's no room. */\n side?: 'bottom' | 'top'\n align?: 'start' | 'end'\n /** The list's width, when it should differ from the trigger's, e.g. `20rem`. */\n panelWidth?: string\n}\n\n// Attributes (aria-label, class for its width) go to the trigger, the one element in the page's flow.\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<SelectProps<T>>(), {\n selectedOptions: () => [],\n searchable: undefined,\n filter: true,\n createOption: undefined,\n createColored: true,\n size: 'md',\n placeholder: 'Select an option',\n searchPlaceholder: 'Type to filter',\n emptyLabel: 'No results found',\n createLabel: 'Create',\n removeLabel: 'Remove',\n side: 'bottom',\n align: 'start',\n panelWidth: undefined\n})\n\nconst emit = defineEmits<{ 'query-change': [query: string]; 'create-error': [error: unknown] }>()\n\n// An aria-label would hide the trigger's visible value from its name; it's said before the value instead.\nconst attrs = useAttrs()\nconst label = computed(() => attrs['aria-label'] as string | undefined)\nconst triggerAttrs = computed(() => Object.fromEntries(Object.entries(attrs).filter(([key]) => key !== 'aria-label')))\n\nconst model = defineModel<T | T[] | null>({ default: null })\n\nconst open = ref(false)\nconst query = ref('')\nconst keyboard = ref(false)\nconst pointer = ref(false)\n\nconst values = computed<T[]>(() =>\n Array.isArray(model.value) ? model.value : model.value === null || model.value === undefined ? [] : [model.value]\n)\n// Options picked from earlier results, which `options` may no longer hold.\nconst picked = shallowRef<SelectOption<T>[]>([])\nconst selected = computed(() =>\n values.value\n .map((value) =>\n [props.options, props.selectedOptions, picked.value]\n .map((list) => list.find((option) => option.value === value))\n .find((option) => !!option)\n )\n .filter((option) => !!option)\n)\nconst search = computed(\n () =>\n props.searchable ??\n (props.multiple || props.canCreate || props.clearable || props.filter === false || props.options.length > 8)\n)\nconst removable = computed(() => props.multiple || props.clearable)\nconst matches = (option: SelectOption<T>, text: string) =>\n typeof props.filter === 'function'\n ? props.filter(option, text)\n : option.label.toLowerCase().includes(text.toLowerCase())\nconst listed = computed(() => {\n const text = query.value.trim()\n return props.options\n .filter((option) => !(props.multiple && search.value && values.value.includes(option.value)))\n .filter((option) => !text || props.filter === false || matches(option, text))\n})\nconst showCreate = computed(() => {\n const text = query.value.trim().toLowerCase()\n return props.canCreate && !!text && !props.options.some((option) => option.label.toLowerCase() === text)\n})\n// More than this and the list renders only the rows in view.\nconst virtual = computed(() => listed.value.length > 20)\n\nconst createHues: Hue[] = ['gray', 'purple', 'red', 'green', 'orange', 'pink', 'blue', 'slate']\nconst newHue = computed(() => createHues[query.value.length % createHues.length])\nconst CREATE = { create: true } as const\n\nconst { attrs: fieldAttrs, invalid: isInvalid } = useFieldControl(\n () => undefined,\n () => props.invalid\n)\n\nfunction setQuery(text: string) {\n query.value = text\n emit('query-change', text)\n}\n\nfunction show(viaKeyboard: boolean) {\n if (props.disabled) return\n keyboard.value = viaKeyboard\n pointer.value = false\n open.value = true\n}\n\nfunction close() {\n open.value = false\n if (query.value) setQuery('')\n}\n\nfunction toggle(event?: Event) {\n if (open.value) close()\n // A click from the keyboard (Enter, Space) has no pointer position.\n else show(!!event && (event as MouseEvent).detail === 0)\n}\n\nfunction choose(option: SelectOption<T>) {\n picked.value = [option, ...picked.value.filter((known) => known.value !== option.value)]\n if (props.multiple) {\n model.value = values.value.includes(option.value)\n ? values.value.filter((value) => value !== option.value)\n : [...values.value, option.value]\n setQuery('')\n } else {\n model.value = option.value\n close()\n }\n}\n\nconst creating = ref(false)\n\n// A failed createOption keeps what was typed, so it can be tried again.\nasync function create() {\n if (creating.value) return\n const label = query.value.trim()\n const draft = props.createColored ? { label, color: newHue.value } : { label }\n creating.value = true\n try {\n const option = props.createOption\n ? await props.createOption(draft)\n : ({ value: label as T, label, color: draft.color } as SelectOption<T>)\n choose(option)\n } catch (error) {\n emit('create-error', error)\n } finally {\n creating.value = false\n }\n}\n\nfunction onSelect(event: CustomEvent, row: SelectOption<T> | typeof CREATE) {\n // What's chosen lives in the model; the listbox keeps no selection of its own.\n event.preventDefault()\n if ('create' in row) create()\n else if (!row.disabled) choose(row)\n}\n\nfunction remove(value: T) {\n model.value = props.multiple ? values.value.filter((chosen) => chosen !== value) : null\n}\n\nfunction onKeydown(event: KeyboardEvent) {\n if (['ArrowUp', 'ArrowDown', 'Home', 'End'].includes(event.key)) keyboard.value = true\n if (event.key === 'Backspace' && removable.value && !query.value && values.value.length)\n remove(values.value[values.value.length - 1]!)\n}\n\nfunction onTriggerKeydown(event: KeyboardEvent) {\n if (!open.value && ['ArrowDown', 'ArrowUp'].includes(event.key)) {\n event.preventDefault()\n show(true)\n }\n}\n\n// The filter takes focus when there is one, or else the list, so the arrow keys work at once.\nfunction onOpenAutoFocus(event: Event) {\n event.preventDefault()\n nextTick(() =>\n (event.target as HTMLElement | null)?.querySelector<HTMLElement>('[data-select-filter], [role=\"listbox\"]')?.focus()\n )\n}\n\n// Back to the trigger, which Reka can't find: it's our anchor, not its trigger.\nconst anchor = ref<{ $el: HTMLElement }>()\n\n// Nor does Reka know a press on it isn't outside: closing there would let the click reopen the list.\nfunction onPointerDownOutside(event: CustomEvent<{ originalEvent: PointerEvent }>) {\n const target = event.detail.originalEvent.target\n if (target instanceof Node && anchor.value?.$el?.contains(target)) event.preventDefault()\n}\nfunction returnFocus(event: Event) {\n event.preventDefault()\n anchor.value?.$el?.focus()\n}\n\n// Reka highlights the first option as the list mounts; only the chosen one, the keyboard or the pointer should.\nconst listbox = ref()\nfunction onHighlight(payload: { value: unknown } | undefined) {\n if (keyboard.value || pointer.value || !payload) return\n if (values.value.includes(payload.value as T)) return\n nextTick(() => listbox.value && !keyboard.value && !pointer.value && (listbox.value.highlightedElement = null))\n}\n\nconst triggerSizes = { md: 'min-h-9 pr-2.5 pl-3 text-sm', sm: 'h-7 pr-1.5 pl-2 text-13' }\nconst optionClass =\n 'flex min-h-8 cursor-pointer items-center justify-between gap-3 rounded-lg py-1.5 pr-2 pl-2.5 text-13 whitespace-nowrap text-sui-ink outline-hidden select-none data-disabled:cursor-default data-disabled:opacity-50 data-highlighted:bg-sui-sunken data-[state=checked]:font-medium data-[state=checked]:text-sui-accent group-data-keyboard/list:data-highlighted:sui-ring-inset'\n</script>\n\n<!-- One select for every choice: a short fixed list, a searchable one, several values as tags (`multiple`), or creating\n what was typed (`canCreate`). For a server search, set `:filter=\"false\"` and replace `options` on `query-change`. The `trigger` slot draws your own trigger and gets `open`, `toggle` and `selected`. -->\n<template>\n <PopoverRoot :open=\"open\" @update:open=\"(value) => (value ? show(false) : close())\">\n <PopoverAnchor ref=\"anchor\" as-child>\n <slot name=\"trigger\" :open=\"open\" :selected=\"selected\" :toggle=\"toggle\">\n <button\n v-bind=\"{ ...fieldAttrs, ...triggerAttrs }\"\n :aria-expanded=\"open\"\n aria-haspopup=\"listbox\"\n :aria-invalid=\"isInvalid ? 'true' : undefined\"\n class=\"group inline-flex items-center justify-between gap-1.5 rounded-(--sui-radius-button) border bg-sui-surface text-left text-sui-ink transition-[border-color,box-shadow] duration-150 focus-visible:border-sui-accent focus-visible:sui-ring-field disabled:pointer-events-none disabled:opacity-60\"\n :class=\"[\n triggerSizes[size],\n isInvalid ? 'border-sui-danger-mid' : 'border-sui-line-strong hover:border-sui-ink-muted'\n ]\"\n :disabled=\"disabled\"\n type=\"button\"\n @click=\"toggle\"\n @keydown=\"onTriggerKeydown\"\n >\n <span v-if=\"label\" class=\"sr-only\">{{ label }}: </span>\n <span v-if=\"!selected.length\" class=\"text-sui-ink-faint\">{{ placeholder }}</span>\n <span v-else-if=\"multiple\" class=\"flex flex-wrap gap-1 py-1.25\">\n <Tag\n v-for=\"option in selected\"\n :key=\"option.value\"\n :color=\"option.color ?? undefined\"\n :icon=\"option.icon\"\n :icon-color=\"option.iconColor\"\n :name=\"option.label\"\n />\n </span>\n <Tag\n v-else-if=\"selected[0]!.color\"\n :color=\"selected[0]!.color\"\n :icon=\"selected[0]!.icon\"\n :icon-color=\"selected[0]!.iconColor\"\n :name=\"selected[0]!.label\"\n />\n <span v-else-if=\"selected[0]!.icon\" class=\"inline-flex min-w-0 items-center gap-1.5\">\n <Icon class=\"shrink-0\" :color=\"selected[0]!.iconColor ?? 'ink-subtle'\" :name=\"selected[0]!.icon\" />\n <span class=\"truncate whitespace-nowrap\">{{ selected[0]!.label }}</span>\n </span>\n <span v-else class=\"min-w-0 truncate whitespace-nowrap\">{{ selected[0]!.label }}</span>\n <svg\n aria-hidden=\"true\"\n class=\"size-4 shrink-0 fill-none stroke-sui-ink-muted transition-transform duration-150 group-aria-expanded:rotate-180\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"1.5\"\n viewBox=\"0 0 16 16\"\n >\n <path d=\"M4.5 6.5 8 10l3.5-3.5\" />\n </svg>\n </button>\n </slot>\n </PopoverAnchor>\n <PopoverPortal>\n <PopoverContent\n :align=\"align\"\n :aria-label=\"label ?? placeholder\"\n class=\"z-[1100] overflow-hidden rounded-xl border border-sui-line-subtle bg-sui-surface text-sui-ink shadow-lg data-[state=open]:animate-sui-menu-in\"\n :class=\"\n search ? 'min-w-[max(var(--reka-popover-trigger-width),15rem)]' : 'min-w-(--reka-popover-trigger-width)'\n \"\n :side=\"side\"\n :side-offset=\"4\"\n :style=\"panelWidth ? { width: panelWidth } : undefined\"\n @close-auto-focus=\"returnFocus\"\n @open-auto-focus=\"onOpenAutoFocus\"\n @pointer-down-outside=\"onPointerDownOutside\"\n >\n <ListboxRoot\n ref=\"listbox\"\n :highlight-on-hover=\"true\"\n :model-value=\"multiple ? values : (values[0] ?? undefined)\"\n :multiple=\"multiple\"\n @highlight=\"onHighlight\"\n @keydown=\"onKeydown\"\n @pointermove.capture=\"((keyboard = false), (pointer = true))\"\n >\n <div\n v-if=\"search\"\n class=\"flex min-h-11 flex-wrap items-center gap-1 border-b border-sui-line-subtle px-3 py-2.5\"\n >\n <template v-if=\"removable\">\n <Tag\n v-for=\"option in selected\"\n :key=\"option.value\"\n :color=\"option.color ?? undefined\"\n :icon=\"option.icon\"\n :icon-color=\"option.iconColor\"\n :name=\"option.label\"\n removable\n :remove-label=\"removeLabel\"\n @remove=\"remove(option.value)\"\n />\n </template>\n <!-- focus: classes too: an app's forms plugin rings focused text fields, and outranks plain utilities. -->\n <ListboxFilter\n :aria-label=\"label ?? placeholder\"\n class=\"h-5 min-w-16 flex-1 rounded-none border-none bg-transparent p-0 text-13 text-sui-ink shadow-none outline-hidden placeholder:text-sui-ink-faint focus:border-none focus:shadow-none focus:ring-0 focus:outline-hidden\"\n data-select-filter\n :model-value=\"query\"\n :placeholder=\"removable && selected.length ? '' : searchPlaceholder\"\n @update:model-value=\"setQuery\"\n />\n </div>\n <div v-if=\"loading\" class=\"flex justify-center py-6\"><Spinner size=\"sm\" /></div>\n <ListboxContent\n v-else-if=\"listed.length || showCreate\"\n :aria-label=\"label ?? placeholder\"\n class=\"group/list max-h-60 overflow-auto p-1 outline-hidden\"\n :data-keyboard=\"keyboard || undefined\"\n >\n <ListboxVirtualizer\n v-if=\"virtual\"\n v-slot=\"{ option }\"\n :estimate-size=\"32\"\n :options=\"listed\"\n :text-content=\"(option) => option.label\"\n >\n <ListboxItem\n :class=\"optionClass\"\n :disabled=\"option.disabled\"\n :value=\"option.value\"\n @select=\"onSelect($event, option as SelectOption<T>)\"\n >\n <span class=\"inline-flex min-w-0 items-center gap-1.5 truncate\">\n <slot name=\"option\" :option=\"option as SelectOption<T>\">\n <Tag\n v-if=\"option.color\"\n :color=\"option.color\"\n :icon=\"option.icon\"\n :icon-color=\"option.iconColor\"\n :name=\"option.label\"\n />\n <template v-else>\n <Icon\n v-if=\"option.icon\"\n class=\"shrink-0\"\n :color=\"option.iconColor ?? 'ink-subtle'\"\n :name=\"option.icon\"\n />{{ option.label }}\n </template>\n </slot>\n </span>\n <CheckIcon v-if=\"values.includes(option.value)\" />\n </ListboxItem>\n </ListboxVirtualizer>\n <template v-else>\n <ListboxItem\n v-for=\"option in listed\"\n :key=\"option.value\"\n :class=\"optionClass\"\n :disabled=\"option.disabled\"\n :value=\"option.value\"\n @select=\"onSelect($event, option)\"\n >\n <span class=\"inline-flex min-w-0 items-center gap-1.5 truncate\">\n <slot name=\"option\" :option=\"option\">\n <Tag\n v-if=\"option.color\"\n :color=\"option.color\"\n :icon=\"option.icon\"\n :icon-color=\"option.iconColor\"\n :name=\"option.label\"\n />\n <template v-else>\n <Icon\n v-if=\"option.icon\"\n class=\"shrink-0\"\n :color=\"option.iconColor ?? 'ink-subtle'\"\n :name=\"option.icon\"\n />{{ option.label }}\n </template>\n </slot>\n </span>\n <CheckIcon v-if=\"values.includes(option.value)\" />\n </ListboxItem>\n </template>\n <ListboxItem v-if=\"showCreate\" :class=\"optionClass\" :value=\"CREATE\" @select=\"onSelect($event, CREATE)\">\n <span class=\"inline-flex min-w-0 items-center gap-1.5\">\n {{ createLabel }}\n <Tag v-if=\"createColored\" :color=\"newHue\" :name=\"query.trim()\" />\n <strong v-else class=\"font-medium\">“{{ query.trim() }}”</strong>\n </span>\n </ListboxItem>\n </ListboxContent>\n <div v-else class=\"px-3.5 py-3 text-13 text-sui-ink-muted\">{{ emptyLabel }}</div>\n </ListboxRoot>\n </PopoverContent>\n </PopoverPortal>\n </PopoverRoot>\n</template>\n"],"mappings":""}
@@ -80,17 +80,17 @@ var pe = [
80
80
  }),
81
81
  emits: /*@__PURE__*/ m(["query-change", "create-error"], ["update:modelValue"]),
82
82
  setup(p, { emit: m }) {
83
- let E = p, D = m, O = re(), k = o(() => O["aria-label"]), De = o(() => Object.fromEntries(Object.entries(O).filter(([e]) => e !== "aria-label"))), A = ie(p, "modelValue"), j = v(!1), M = v(""), N = v(!1), P = o(() => Array.isArray(A.value) ? A.value : A.value === null || A.value === void 0 ? [] : [A.value]), F = ne([]), I = o(() => P.value.map((e) => [
83
+ let E = p, D = m, O = re(), k = o(() => O["aria-label"]), De = o(() => Object.fromEntries(Object.entries(O).filter(([e]) => e !== "aria-label"))), A = ie(p, "modelValue"), j = v(!1), M = v(""), N = v(!1), P = v(!1), F = o(() => Array.isArray(A.value) ? A.value : A.value === null || A.value === void 0 ? [] : [A.value]), I = ne([]), L = o(() => F.value.map((e) => [
84
84
  E.options,
85
85
  E.selectedOptions,
86
- F.value
87
- ].map((t) => t.find((t) => t.value === e)).find((e) => !!e)).filter((e) => !!e)), L = o(() => E.searchable ?? (E.multiple || E.canCreate || E.clearable || E.filter === !1 || E.options.length > 8)), R = o(() => E.multiple || E.clearable), Oe = (e, t) => typeof E.filter == "function" ? E.filter(e, t) : e.label.toLowerCase().includes(t.toLowerCase()), z = o(() => {
86
+ I.value
87
+ ].map((t) => t.find((t) => t.value === e)).find((e) => !!e)).filter((e) => !!e)), R = o(() => E.searchable ?? (E.multiple || E.canCreate || E.clearable || E.filter === !1 || E.options.length > 8)), z = o(() => E.multiple || E.clearable), Oe = (e, t) => typeof E.filter == "function" ? E.filter(e, t) : e.label.toLowerCase().includes(t.toLowerCase()), B = o(() => {
88
88
  let e = M.value.trim();
89
- return E.options.filter((e) => !(E.multiple && L.value && P.value.includes(e.value))).filter((t) => !e || E.filter === !1 || Oe(t, e));
90
- }), B = o(() => {
89
+ return E.options.filter((e) => !(E.multiple && R.value && F.value.includes(e.value))).filter((t) => !e || E.filter === !1 || Oe(t, e));
90
+ }), V = o(() => {
91
91
  let e = M.value.trim().toLowerCase();
92
92
  return E.canCreate && !!e && !E.options.some((t) => t.label.toLowerCase() === e);
93
- }), ke = o(() => z.value.length > 20), V = [
93
+ }), ke = o(() => B.value.length > 20), H = [
94
94
  "gray",
95
95
  "purple",
96
96
  "red",
@@ -99,30 +99,30 @@ var pe = [
99
99
  "pink",
100
100
  "blue",
101
101
  "slate"
102
- ], H = o(() => V[M.value.length % V.length]), U = { create: !0 }, { attrs: Ae, invalid: W } = t(() => void 0, () => E.invalid);
103
- function G(e) {
102
+ ], U = o(() => H[M.value.length % H.length]), W = { create: !0 }, { attrs: Ae, invalid: G } = t(() => void 0, () => E.invalid);
103
+ function K(e) {
104
104
  M.value = e, D("query-change", e);
105
105
  }
106
- function K(e) {
107
- E.disabled || (N.value = e, j.value = !0);
106
+ function q(e) {
107
+ E.disabled || (N.value = e, P.value = !1, j.value = !0);
108
108
  }
109
- function q() {
110
- j.value = !1, M.value && G("");
109
+ function J() {
110
+ j.value = !1, M.value && K("");
111
111
  }
112
- function J(e) {
113
- j.value ? q() : K(!!e && e.detail === 0);
112
+ function Y(e) {
113
+ j.value ? J() : q(!!e && e.detail === 0);
114
114
  }
115
115
  function je(e) {
116
- F.value = [e, ...F.value.filter((t) => t.value !== e.value)], E.multiple ? (A.value = P.value.includes(e.value) ? P.value.filter((t) => t !== e.value) : [...P.value, e.value], G("")) : (A.value = e.value, q());
116
+ I.value = [e, ...I.value.filter((t) => t.value !== e.value)], E.multiple ? (A.value = F.value.includes(e.value) ? F.value.filter((t) => t !== e.value) : [...F.value, e.value], K("")) : (A.value = e.value, J());
117
117
  }
118
- let Y = v(!1);
118
+ let X = v(!1);
119
119
  async function Me() {
120
- if (Y.value) return;
120
+ if (X.value) return;
121
121
  let e = M.value.trim(), t = E.createColored ? {
122
122
  label: e,
123
- color: H.value
123
+ color: U.value
124
124
  } : { label: e };
125
- Y.value = !0;
125
+ X.value = !0;
126
126
  try {
127
127
  je(E.createOption ? await E.createOption(t) : {
128
128
  value: e,
@@ -132,48 +132,48 @@ var pe = [
132
132
  } catch (e) {
133
133
  D("create-error", e);
134
134
  } finally {
135
- Y.value = !1;
135
+ X.value = !1;
136
136
  }
137
137
  }
138
- function X(e, t) {
138
+ function Z(e, t) {
139
139
  e.preventDefault(), "create" in t ? Me() : t.disabled || je(t);
140
140
  }
141
- function Z(e) {
142
- A.value = E.multiple ? P.value.filter((t) => t !== e) : null;
143
- }
144
141
  function Ne(e) {
142
+ A.value = E.multiple ? F.value.filter((t) => t !== e) : null;
143
+ }
144
+ function Pe(e) {
145
145
  [
146
146
  "ArrowUp",
147
147
  "ArrowDown",
148
148
  "Home",
149
149
  "End"
150
- ].includes(e.key) && (N.value = !0), e.key === "Backspace" && R.value && !M.value && P.value.length && Z(P.value[P.value.length - 1]);
151
- }
152
- function Pe(e) {
153
- !j.value && ["ArrowDown", "ArrowUp"].includes(e.key) && (e.preventDefault(), K(!0));
150
+ ].includes(e.key) && (N.value = !0), e.key === "Backspace" && z.value && !M.value && F.value.length && Ne(F.value[F.value.length - 1]);
154
151
  }
155
152
  function Fe(e) {
153
+ !j.value && ["ArrowDown", "ArrowUp"].includes(e.key) && (e.preventDefault(), q(!0));
154
+ }
155
+ function Ie(e) {
156
156
  e.preventDefault(), h(() => e.target?.querySelector("[data-select-filter], [role=\"listbox\"]")?.focus());
157
157
  }
158
158
  let Q = v();
159
- function Ie(e) {
159
+ function Le(e) {
160
160
  let t = e.detail.originalEvent.target;
161
161
  t instanceof Node && Q.value?.$el?.contains(t) && e.preventDefault();
162
162
  }
163
- function Le(e) {
163
+ function Re(e) {
164
164
  e.preventDefault(), Q.value?.$el?.focus();
165
165
  }
166
166
  let $ = v();
167
- function Re(e) {
168
- !N.value && e && (P.value.includes(e.value) || h(() => $.value && !N.value && ($.value.highlightedElement = null)));
167
+ function ze(e) {
168
+ N.value || P.value || !e || F.value.includes(e.value) || h(() => $.value && !N.value && !P.value && ($.value.highlightedElement = null));
169
169
  }
170
- let ze = {
170
+ let Be = {
171
171
  md: "min-h-9 pr-2.5 pl-3 text-sm",
172
172
  sm: "h-7 pr-1.5 pl-2 text-13"
173
173
  };
174
174
  return (t, o) => (_(), s(S(fe), {
175
175
  open: j.value,
176
- "onUpdate:open": o[2] ||= (e) => e ? K(!1) : q()
176
+ "onUpdate:open": o[2] ||= (e) => e ? q(!1) : J()
177
177
  }, {
178
178
  default: C(() => [f(S(le), {
179
179
  ref_key: "anchor",
@@ -182,23 +182,23 @@ var pe = [
182
182
  }, {
183
183
  default: C(() => [b(t.$slots, "trigger", {
184
184
  open: j.value,
185
- selected: I.value,
186
- toggle: J
185
+ selected: L.value,
186
+ toggle: Y
187
187
  }, () => [u("button", ee({
188
188
  ...S(Ae),
189
189
  ...De.value
190
190
  }, {
191
191
  "aria-expanded": j.value,
192
192
  "aria-haspopup": "listbox",
193
- "aria-invalid": S(W) ? "true" : void 0,
194
- class: ["group inline-flex items-center justify-between gap-1.5 rounded-(--sui-radius-button) border bg-sui-surface text-left text-sui-ink transition-[border-color,box-shadow] duration-150 focus-visible:border-sui-accent focus-visible:sui-ring-field disabled:pointer-events-none disabled:opacity-60", [ze[p.size], S(W) ? "border-sui-danger-mid" : "border-sui-line-strong hover:border-sui-ink-muted"]],
193
+ "aria-invalid": S(G) ? "true" : void 0,
194
+ class: ["group inline-flex items-center justify-between gap-1.5 rounded-(--sui-radius-button) border bg-sui-surface text-left text-sui-ink transition-[border-color,box-shadow] duration-150 focus-visible:border-sui-accent focus-visible:sui-ring-field disabled:pointer-events-none disabled:opacity-60", [Be[p.size], S(G) ? "border-sui-danger-mid" : "border-sui-line-strong hover:border-sui-ink-muted"]],
195
195
  disabled: p.disabled,
196
196
  type: "button",
197
- onClick: J,
198
- onKeydown: Pe
197
+ onClick: Y,
198
+ onKeydown: Fe
199
199
  }), [
200
200
  k.value ? (_(), l("span", me, x(k.value) + ": ", 1)) : c("", !0),
201
- I.value.length ? p.multiple ? (_(), l("span", ge, [(_(!0), l(a, null, y(I.value, (e) => (_(), s(i, {
201
+ L.value.length ? p.multiple ? (_(), l("span", ge, [(_(!0), l(a, null, y(L.value, (e) => (_(), s(i, {
202
202
  key: e.value,
203
203
  color: e.color ?? void 0,
204
204
  icon: e.icon,
@@ -209,22 +209,22 @@ var pe = [
209
209
  "icon",
210
210
  "icon-color",
211
211
  "name"
212
- ]))), 128))])) : I.value[0].color ? (_(), s(i, {
212
+ ]))), 128))])) : L.value[0].color ? (_(), s(i, {
213
213
  key: 3,
214
- color: I.value[0].color,
215
- icon: I.value[0].icon,
216
- "icon-color": I.value[0].iconColor,
217
- name: I.value[0].label
214
+ color: L.value[0].color,
215
+ icon: L.value[0].icon,
216
+ "icon-color": L.value[0].iconColor,
217
+ name: L.value[0].label
218
218
  }, null, 8, [
219
219
  "color",
220
220
  "icon",
221
221
  "icon-color",
222
222
  "name"
223
- ])) : I.value[0].icon ? (_(), l("span", _e, [f(e, {
223
+ ])) : L.value[0].icon ? (_(), l("span", _e, [f(e, {
224
224
  class: "shrink-0",
225
- color: I.value[0].iconColor ?? "ink-subtle",
226
- name: I.value[0].icon
227
- }, null, 8, ["color", "name"]), u("span", ve, x(I.value[0].label), 1)])) : (_(), l("span", ye, x(I.value[0].label), 1)) : (_(), l("span", he, x(p.placeholder), 1)),
225
+ color: L.value[0].iconColor ?? "ink-subtle",
226
+ name: L.value[0].icon
227
+ }, null, 8, ["color", "name"]), u("span", ve, x(L.value[0].label), 1)])) : (_(), l("span", ye, x(L.value[0].label), 1)) : (_(), l("span", he, x(p.placeholder), 1)),
228
228
  o[3] ||= u("svg", {
229
229
  "aria-hidden": "true",
230
230
  class: "size-4 shrink-0 fill-none stroke-sui-ink-muted transition-transform duration-150 group-aria-expanded:rotate-180",
@@ -239,25 +239,25 @@ var pe = [
239
239
  default: C(() => [f(S(ue), {
240
240
  align: p.align,
241
241
  "aria-label": k.value ?? p.placeholder,
242
- class: g(["z-[1100] overflow-hidden rounded-xl border border-sui-line-subtle bg-sui-surface text-sui-ink shadow-lg data-[state=open]:animate-sui-menu-in", L.value ? "min-w-[max(var(--reka-popover-trigger-width),15rem)]" : "min-w-(--reka-popover-trigger-width)"]),
242
+ class: g(["z-[1100] overflow-hidden rounded-xl border border-sui-line-subtle bg-sui-surface text-sui-ink shadow-lg data-[state=open]:animate-sui-menu-in", R.value ? "min-w-[max(var(--reka-popover-trigger-width),15rem)]" : "min-w-(--reka-popover-trigger-width)"]),
243
243
  side: p.side,
244
244
  "side-offset": 4,
245
245
  style: te(p.panelWidth ? { width: p.panelWidth } : void 0),
246
- onCloseAutoFocus: Le,
247
- onOpenAutoFocus: Fe,
248
- onPointerDownOutside: Ie
246
+ onCloseAutoFocus: Re,
247
+ onOpenAutoFocus: Ie,
248
+ onPointerDownOutside: Le
249
249
  }, {
250
250
  default: C(() => [f(S(se), {
251
251
  ref_key: "listbox",
252
252
  ref: $,
253
253
  "highlight-on-hover": !0,
254
- "model-value": p.multiple ? P.value : P.value[0] ?? void 0,
254
+ "model-value": p.multiple ? F.value : F.value[0] ?? void 0,
255
255
  multiple: p.multiple,
256
- onHighlight: Re,
257
- onKeydown: Ne,
258
- onPointermove: o[1] ||= (e) => N.value = !1
256
+ onHighlight: ze,
257
+ onKeydown: Pe,
258
+ onPointermoveCapture: o[1] ||= (e) => (N.value = !1, P.value = !0)
259
259
  }, {
260
- default: C(() => [L.value ? (_(), l("div", be, [R.value ? (_(!0), l(a, { key: 0 }, y(I.value, (e) => (_(), s(i, {
260
+ default: C(() => [R.value ? (_(), l("div", be, [z.value ? (_(!0), l(a, { key: 0 }, y(L.value, (e) => (_(), s(i, {
261
261
  key: e.value,
262
262
  color: e.color ?? void 0,
263
263
  icon: e.icon,
@@ -265,7 +265,7 @@ var pe = [
265
265
  name: e.label,
266
266
  removable: "",
267
267
  "remove-label": p.removeLabel,
268
- onRemove: (t) => Z(e.value)
268
+ onRemove: (t) => Ne(e.value)
269
269
  }, null, 8, [
270
270
  "color",
271
271
  "icon",
@@ -278,13 +278,13 @@ var pe = [
278
278
  class: "h-5 min-w-16 flex-1 rounded-none border-none bg-transparent p-0 text-13 text-sui-ink shadow-none outline-hidden placeholder:text-sui-ink-faint focus:border-none focus:shadow-none focus:ring-0 focus:outline-hidden",
279
279
  "data-select-filter": "",
280
280
  "model-value": M.value,
281
- placeholder: R.value && I.value.length ? "" : p.searchPlaceholder,
282
- "onUpdate:modelValue": G
281
+ placeholder: z.value && L.value.length ? "" : p.searchPlaceholder,
282
+ "onUpdate:modelValue": K
283
283
  }, null, 8, [
284
284
  "aria-label",
285
285
  "model-value",
286
286
  "placeholder"
287
- ])])) : c("", !0), p.loading ? (_(), l("div", xe, [f(r, { size: "sm" })])) : z.value.length || B.value ? (_(), s(S(ae), {
287
+ ])])) : c("", !0), p.loading ? (_(), l("div", xe, [f(r, { size: "sm" })])) : B.value.length || V.value ? (_(), s(S(ae), {
288
288
  key: 2,
289
289
  "aria-label": k.value ?? p.placeholder,
290
290
  class: "group/list max-h-60 overflow-auto p-1 outline-hidden",
@@ -293,14 +293,14 @@ var pe = [
293
293
  default: C(() => [ke.value ? (_(), s(S(ce), {
294
294
  key: 0,
295
295
  "estimate-size": 32,
296
- options: z.value,
296
+ options: B.value,
297
297
  "text-content": (e) => e.label
298
298
  }, {
299
299
  default: C(({ option: r }) => [f(S(w), {
300
300
  class: g(T),
301
301
  disabled: r.disabled,
302
302
  value: r.value,
303
- onSelect: (e) => X(e, r)
303
+ onSelect: (e) => Z(e, r)
304
304
  }, {
305
305
  default: C(() => [u("span", Se, [b(t.$slots, "option", { option: r }, () => [r.color ? (_(), s(i, {
306
306
  key: 0,
@@ -318,7 +318,7 @@ var pe = [
318
318
  class: "shrink-0",
319
319
  color: r.iconColor ?? "ink-subtle",
320
320
  name: r.icon
321
- }, null, 8, ["color", "name"])) : c("", !0), d(x(r.label), 1)], 64))])]), P.value.includes(r.value) ? (_(), s(n, { key: 0 })) : c("", !0)]),
321
+ }, null, 8, ["color", "name"])) : c("", !0), d(x(r.label), 1)], 64))])]), F.value.includes(r.value) ? (_(), s(n, { key: 0 })) : c("", !0)]),
322
322
  _: 2
323
323
  }, 1032, [
324
324
  "disabled",
@@ -326,12 +326,12 @@ var pe = [
326
326
  "onSelect"
327
327
  ])]),
328
328
  _: 3
329
- }, 8, ["options", "text-content"])) : (_(!0), l(a, { key: 1 }, y(z.value, (r) => (_(), s(S(w), {
329
+ }, 8, ["options", "text-content"])) : (_(!0), l(a, { key: 1 }, y(B.value, (r) => (_(), s(S(w), {
330
330
  key: r.value,
331
331
  class: g(T),
332
332
  disabled: r.disabled,
333
333
  value: r.value,
334
- onSelect: (e) => X(e, r)
334
+ onSelect: (e) => Z(e, r)
335
335
  }, {
336
336
  default: C(() => [u("span", Ce, [b(t.$slots, "option", { option: r }, () => [r.color ? (_(), s(i, {
337
337
  key: 0,
@@ -349,21 +349,21 @@ var pe = [
349
349
  class: "shrink-0",
350
350
  color: r.iconColor ?? "ink-subtle",
351
351
  name: r.icon
352
- }, null, 8, ["color", "name"])) : c("", !0), d(x(r.label), 1)], 64))])]), P.value.includes(r.value) ? (_(), s(n, { key: 0 })) : c("", !0)]),
352
+ }, null, 8, ["color", "name"])) : c("", !0), d(x(r.label), 1)], 64))])]), F.value.includes(r.value) ? (_(), s(n, { key: 0 })) : c("", !0)]),
353
353
  _: 2
354
354
  }, 1032, [
355
355
  "disabled",
356
356
  "value",
357
357
  "onSelect"
358
- ]))), 128)), B.value ? (_(), s(S(w), {
358
+ ]))), 128)), V.value ? (_(), s(S(w), {
359
359
  key: 2,
360
360
  class: g(T),
361
- value: U,
362
- onSelect: o[0] ||= (e) => X(e, U)
361
+ value: W,
362
+ onSelect: o[0] ||= (e) => Z(e, W)
363
363
  }, {
364
364
  default: C(() => [u("span", we, [d(x(p.createLabel) + " ", 1), p.createColored ? (_(), s(i, {
365
365
  key: 0,
366
- color: H.value,
366
+ color: U.value,
367
367
  name: M.value.trim()
368
368
  }, null, 8, ["color", "name"])) : (_(), l("strong", Te, "“" + x(M.value.trim()) + "”", 1))])]),
369
369
  _: 1
@@ -1 +1 @@
1
- {"version":3,"file":"Select.vue_vue_type_script_setup_true_lang.js","names":["_useModel","_openBlock","_createBlock","_unref","_withCtx","_createVNode","_renderSlot","_createElementVNode","_mergeProps","_createElementBlock","_toDisplayString","_createCommentVNode","_Fragment","_renderList","Tag","Icon","_normalizeClass","_normalizeStyle","Spinner","_createTextVNode","CheckIcon","Icon_default","CheckIcon_default","Spinner_default","Tag_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","_hoisted_14","optionClass","Select_vue_vue_type_script_setup_true_lang_default","\"modelValue\"","\"modelModifiers\"","__emit","props","__props","emit","attrs","useAttrs","label","computed","triggerAttrs","key","model","useModel","open","ref","query","keyboard","values","picked","shallowRef","selected","list","option","value","search","removable","matches","text","listed","showCreate","virtual","createHues","newHue","CREATE","fieldAttrs","isInvalid","useFieldControl","setQuery","show","viaKeyboard","close","toggle","event","choose","known","creating","create","draft","error","onSelect","row","remove","chosen","onKeydown","onTriggerKeydown","onOpenAutoFocus","nextTick","anchor","onPointerDownOutside","target","returnFocus","listbox","onHighlight","payload","triggerSizes","openBlock","createBlock","unref","PopoverRoot","_cache","withCtx","createVNode","PopoverAnchor","renderSlot","_ctx","createElementVNode","mergeProps","createElementBlock","toDisplayString","createCommentVNode","Fragment","renderList","PopoverPortal","PopoverContent","normalizeClass","normalizeStyle","ListboxRoot","ListboxFilter","ListboxContent","ListboxVirtualizer","ListboxItem","$event","createTextVNode"],"sources":["../../../src/components/Select/Select.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"T extends SelectValue\">\nimport { computed, nextTick, ref, shallowRef, useAttrs } from 'vue'\n\nimport {\n ListboxContent,\n ListboxFilter,\n ListboxItem,\n ListboxRoot,\n ListboxVirtualizer,\n PopoverAnchor,\n PopoverContent,\n PopoverPortal,\n PopoverRoot\n} from 'reka-ui'\n\nimport type { Hue } from '../../utils/hues'\nimport { useFieldControl } from '../FormField/context'\nimport Icon from '../Icon/Icon.vue'\nimport Spinner from '../Spinner/Spinner.vue'\nimport Tag from '../Tag/Tag.vue'\nimport CheckIcon from '../internal/CheckIcon.vue'\nimport type { SelectOption, SelectValue } from './types'\n\nexport interface SelectProps<T extends SelectValue> {\n options: SelectOption<T>[]\n /** The options for chosen values that aren't in `options`, such as a saved choice while `options` holds search\n * results. Options picked from the list are remembered without it. */\n selectedOptions?: SelectOption<T>[]\n multiple?: boolean\n /** Lets a single choice be removed, as a tag in the filter row or with Backspace there. */\n clearable?: boolean\n /** A filter row at the top of the list; on by default for `multiple`, `canCreate` or more than 8 options. */\n searchable?: boolean\n /** Narrows `options` to what's typed: by label, or by your function. `false` when `options` are already the results\n * for the query, such as from a server search through `query-change`. */\n filter?: boolean | ((option: SelectOption<T>, query: string) => boolean)\n /** Offers to create what was typed, through `createOption`. */\n canCreate?: boolean\n /** Makes the created option; by default its value is its label. */\n createOption?: (draft: { label: string; color?: Hue }) => SelectOption<T> | Promise<SelectOption<T>>\n /** Creates with a hue, shown as a tag. */\n createColored?: boolean\n loading?: boolean\n /** 36px for forms, 28px for table feet and toolbars. */\n size?: 'md' | 'sm'\n disabled?: boolean\n invalid?: boolean\n placeholder?: string\n searchPlaceholder?: string\n emptyLabel?: string\n createLabel?: string\n removeLabel?: string\n /** Where the list opens; it flips when there's no room. */\n side?: 'bottom' | 'top'\n align?: 'start' | 'end'\n /** The list's width, when it should differ from the trigger's, e.g. `20rem`. */\n panelWidth?: string\n}\n\n// Attributes (aria-label, class for its width) go to the trigger, the one element in the page's flow.\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<SelectProps<T>>(), {\n selectedOptions: () => [],\n searchable: undefined,\n filter: true,\n createOption: undefined,\n createColored: true,\n size: 'md',\n placeholder: 'Select an option',\n searchPlaceholder: 'Type to filter',\n emptyLabel: 'No results found',\n createLabel: 'Create',\n removeLabel: 'Remove',\n side: 'bottom',\n align: 'start',\n panelWidth: undefined\n})\n\nconst emit = defineEmits<{ 'query-change': [query: string]; 'create-error': [error: unknown] }>()\n\n// An aria-label would hide the trigger's visible value from its name; it's said before the value instead.\nconst attrs = useAttrs()\nconst label = computed(() => attrs['aria-label'] as string | undefined)\nconst triggerAttrs = computed(() => Object.fromEntries(Object.entries(attrs).filter(([key]) => key !== 'aria-label')))\n\nconst model = defineModel<T | T[] | null>({ default: null })\n\nconst open = ref(false)\nconst query = ref('')\nconst keyboard = ref(false)\n\nconst values = computed<T[]>(() =>\n Array.isArray(model.value) ? model.value : model.value === null || model.value === undefined ? [] : [model.value]\n)\n// Options picked from earlier results, which `options` may no longer hold.\nconst picked = shallowRef<SelectOption<T>[]>([])\nconst selected = computed(() =>\n values.value\n .map((value) =>\n [props.options, props.selectedOptions, picked.value]\n .map((list) => list.find((option) => option.value === value))\n .find((option) => !!option)\n )\n .filter((option) => !!option)\n)\nconst search = computed(\n () =>\n props.searchable ??\n (props.multiple || props.canCreate || props.clearable || props.filter === false || props.options.length > 8)\n)\nconst removable = computed(() => props.multiple || props.clearable)\nconst matches = (option: SelectOption<T>, text: string) =>\n typeof props.filter === 'function'\n ? props.filter(option, text)\n : option.label.toLowerCase().includes(text.toLowerCase())\nconst listed = computed(() => {\n const text = query.value.trim()\n return props.options\n .filter((option) => !(props.multiple && search.value && values.value.includes(option.value)))\n .filter((option) => !text || props.filter === false || matches(option, text))\n})\nconst showCreate = computed(() => {\n const text = query.value.trim().toLowerCase()\n return props.canCreate && !!text && !props.options.some((option) => option.label.toLowerCase() === text)\n})\n// More than this and the list renders only the rows in view.\nconst virtual = computed(() => listed.value.length > 20)\n\nconst createHues: Hue[] = ['gray', 'purple', 'red', 'green', 'orange', 'pink', 'blue', 'slate']\nconst newHue = computed(() => createHues[query.value.length % createHues.length])\nconst CREATE = { create: true } as const\n\nconst { attrs: fieldAttrs, invalid: isInvalid } = useFieldControl(\n () => undefined,\n () => props.invalid\n)\n\nfunction setQuery(text: string) {\n query.value = text\n emit('query-change', text)\n}\n\nfunction show(viaKeyboard: boolean) {\n if (props.disabled) return\n keyboard.value = viaKeyboard\n open.value = true\n}\n\nfunction close() {\n open.value = false\n if (query.value) setQuery('')\n}\n\nfunction toggle(event?: Event) {\n if (open.value) close()\n // A click from the keyboard (Enter, Space) has no pointer position.\n else show(!!event && (event as MouseEvent).detail === 0)\n}\n\nfunction choose(option: SelectOption<T>) {\n picked.value = [option, ...picked.value.filter((known) => known.value !== option.value)]\n if (props.multiple) {\n model.value = values.value.includes(option.value)\n ? values.value.filter((value) => value !== option.value)\n : [...values.value, option.value]\n setQuery('')\n } else {\n model.value = option.value\n close()\n }\n}\n\nconst creating = ref(false)\n\n// A failed createOption keeps what was typed, so it can be tried again.\nasync function create() {\n if (creating.value) return\n const label = query.value.trim()\n const draft = props.createColored ? { label, color: newHue.value } : { label }\n creating.value = true\n try {\n const option = props.createOption\n ? await props.createOption(draft)\n : ({ value: label as T, label, color: draft.color } as SelectOption<T>)\n choose(option)\n } catch (error) {\n emit('create-error', error)\n } finally {\n creating.value = false\n }\n}\n\nfunction onSelect(event: CustomEvent, row: SelectOption<T> | typeof CREATE) {\n // What's chosen lives in the model; the listbox keeps no selection of its own.\n event.preventDefault()\n if ('create' in row) create()\n else if (!row.disabled) choose(row)\n}\n\nfunction remove(value: T) {\n model.value = props.multiple ? values.value.filter((chosen) => chosen !== value) : null\n}\n\nfunction onKeydown(event: KeyboardEvent) {\n if (['ArrowUp', 'ArrowDown', 'Home', 'End'].includes(event.key)) keyboard.value = true\n if (event.key === 'Backspace' && removable.value && !query.value && values.value.length)\n remove(values.value[values.value.length - 1]!)\n}\n\nfunction onTriggerKeydown(event: KeyboardEvent) {\n if (!open.value && ['ArrowDown', 'ArrowUp'].includes(event.key)) {\n event.preventDefault()\n show(true)\n }\n}\n\n// The filter takes focus when there is one, or else the list, so the arrow keys work at once.\nfunction onOpenAutoFocus(event: Event) {\n event.preventDefault()\n nextTick(() =>\n (event.target as HTMLElement | null)?.querySelector<HTMLElement>('[data-select-filter], [role=\"listbox\"]')?.focus()\n )\n}\n\n// Back to the trigger, which Reka can't find: it's our anchor, not its trigger.\nconst anchor = ref<{ $el: HTMLElement }>()\n\n// Nor does Reka know a press on it isn't outside: closing there would let the click reopen the list.\nfunction onPointerDownOutside(event: CustomEvent<{ originalEvent: PointerEvent }>) {\n const target = event.detail.originalEvent.target\n if (target instanceof Node && anchor.value?.$el?.contains(target)) event.preventDefault()\n}\nfunction returnFocus(event: Event) {\n event.preventDefault()\n anchor.value?.$el?.focus()\n}\n\n// Reka highlights the first option as the list mounts; only the chosen one, or the keyboard, should be.\nconst listbox = ref()\nfunction onHighlight(payload: { value: unknown } | undefined) {\n if (keyboard.value || !payload) return\n if (values.value.includes(payload.value as T)) return\n nextTick(() => listbox.value && !keyboard.value && (listbox.value.highlightedElement = null))\n}\n\nconst triggerSizes = { md: 'min-h-9 pr-2.5 pl-3 text-sm', sm: 'h-7 pr-1.5 pl-2 text-13' }\nconst optionClass =\n 'flex min-h-8 cursor-pointer items-center justify-between gap-3 rounded-lg py-1.5 pr-2 pl-2.5 text-13 whitespace-nowrap text-sui-ink outline-hidden select-none data-disabled:cursor-default data-disabled:opacity-50 data-highlighted:bg-sui-sunken data-[state=checked]:font-medium data-[state=checked]:text-sui-accent group-data-keyboard/list:data-highlighted:sui-ring-inset'\n</script>\n\n<!-- One select for every choice: a short fixed list, a searchable one, several values as tags (`multiple`), or creating\n what was typed (`canCreate`). For a server search, set `:filter=\"false\"` and replace `options` on `query-change`. The `trigger` slot draws your own trigger and gets `open`, `toggle` and `selected`. -->\n<template>\n <PopoverRoot :open=\"open\" @update:open=\"(value) => (value ? show(false) : close())\">\n <PopoverAnchor ref=\"anchor\" as-child>\n <slot name=\"trigger\" :open=\"open\" :selected=\"selected\" :toggle=\"toggle\">\n <button\n v-bind=\"{ ...fieldAttrs, ...triggerAttrs }\"\n :aria-expanded=\"open\"\n aria-haspopup=\"listbox\"\n :aria-invalid=\"isInvalid ? 'true' : undefined\"\n class=\"group inline-flex items-center justify-between gap-1.5 rounded-(--sui-radius-button) border bg-sui-surface text-left text-sui-ink transition-[border-color,box-shadow] duration-150 focus-visible:border-sui-accent focus-visible:sui-ring-field disabled:pointer-events-none disabled:opacity-60\"\n :class=\"[\n triggerSizes[size],\n isInvalid ? 'border-sui-danger-mid' : 'border-sui-line-strong hover:border-sui-ink-muted'\n ]\"\n :disabled=\"disabled\"\n type=\"button\"\n @click=\"toggle\"\n @keydown=\"onTriggerKeydown\"\n >\n <span v-if=\"label\" class=\"sr-only\">{{ label }}: </span>\n <span v-if=\"!selected.length\" class=\"text-sui-ink-faint\">{{ placeholder }}</span>\n <span v-else-if=\"multiple\" class=\"flex flex-wrap gap-1 py-1.25\">\n <Tag\n v-for=\"option in selected\"\n :key=\"option.value\"\n :color=\"option.color ?? undefined\"\n :icon=\"option.icon\"\n :icon-color=\"option.iconColor\"\n :name=\"option.label\"\n />\n </span>\n <Tag\n v-else-if=\"selected[0]!.color\"\n :color=\"selected[0]!.color\"\n :icon=\"selected[0]!.icon\"\n :icon-color=\"selected[0]!.iconColor\"\n :name=\"selected[0]!.label\"\n />\n <span v-else-if=\"selected[0]!.icon\" class=\"inline-flex min-w-0 items-center gap-1.5\">\n <Icon class=\"shrink-0\" :color=\"selected[0]!.iconColor ?? 'ink-subtle'\" :name=\"selected[0]!.icon\" />\n <span class=\"truncate whitespace-nowrap\">{{ selected[0]!.label }}</span>\n </span>\n <span v-else class=\"min-w-0 truncate whitespace-nowrap\">{{ selected[0]!.label }}</span>\n <svg\n aria-hidden=\"true\"\n class=\"size-4 shrink-0 fill-none stroke-sui-ink-muted transition-transform duration-150 group-aria-expanded:rotate-180\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"1.5\"\n viewBox=\"0 0 16 16\"\n >\n <path d=\"M4.5 6.5 8 10l3.5-3.5\" />\n </svg>\n </button>\n </slot>\n </PopoverAnchor>\n <PopoverPortal>\n <PopoverContent\n :align=\"align\"\n :aria-label=\"label ?? placeholder\"\n class=\"z-[1100] overflow-hidden rounded-xl border border-sui-line-subtle bg-sui-surface text-sui-ink shadow-lg data-[state=open]:animate-sui-menu-in\"\n :class=\"\n search ? 'min-w-[max(var(--reka-popover-trigger-width),15rem)]' : 'min-w-(--reka-popover-trigger-width)'\n \"\n :side=\"side\"\n :side-offset=\"4\"\n :style=\"panelWidth ? { width: panelWidth } : undefined\"\n @close-auto-focus=\"returnFocus\"\n @open-auto-focus=\"onOpenAutoFocus\"\n @pointer-down-outside=\"onPointerDownOutside\"\n >\n <ListboxRoot\n ref=\"listbox\"\n :highlight-on-hover=\"true\"\n :model-value=\"multiple ? values : (values[0] ?? undefined)\"\n :multiple=\"multiple\"\n @highlight=\"onHighlight\"\n @keydown=\"onKeydown\"\n @pointermove=\"keyboard = false\"\n >\n <div\n v-if=\"search\"\n class=\"flex min-h-11 flex-wrap items-center gap-1 border-b border-sui-line-subtle px-3 py-2.5\"\n >\n <template v-if=\"removable\">\n <Tag\n v-for=\"option in selected\"\n :key=\"option.value\"\n :color=\"option.color ?? undefined\"\n :icon=\"option.icon\"\n :icon-color=\"option.iconColor\"\n :name=\"option.label\"\n removable\n :remove-label=\"removeLabel\"\n @remove=\"remove(option.value)\"\n />\n </template>\n <!-- focus: classes too: an app's forms plugin rings focused text fields, and outranks plain utilities. -->\n <ListboxFilter\n :aria-label=\"label ?? placeholder\"\n class=\"h-5 min-w-16 flex-1 rounded-none border-none bg-transparent p-0 text-13 text-sui-ink shadow-none outline-hidden placeholder:text-sui-ink-faint focus:border-none focus:shadow-none focus:ring-0 focus:outline-hidden\"\n data-select-filter\n :model-value=\"query\"\n :placeholder=\"removable && selected.length ? '' : searchPlaceholder\"\n @update:model-value=\"setQuery\"\n />\n </div>\n <div v-if=\"loading\" class=\"flex justify-center py-6\"><Spinner size=\"sm\" /></div>\n <ListboxContent\n v-else-if=\"listed.length || showCreate\"\n :aria-label=\"label ?? placeholder\"\n class=\"group/list max-h-60 overflow-auto p-1 outline-hidden\"\n :data-keyboard=\"keyboard || undefined\"\n >\n <ListboxVirtualizer\n v-if=\"virtual\"\n v-slot=\"{ option }\"\n :estimate-size=\"32\"\n :options=\"listed\"\n :text-content=\"(option) => option.label\"\n >\n <ListboxItem\n :class=\"optionClass\"\n :disabled=\"option.disabled\"\n :value=\"option.value\"\n @select=\"onSelect($event, option as SelectOption<T>)\"\n >\n <span class=\"inline-flex min-w-0 items-center gap-1.5 truncate\">\n <slot name=\"option\" :option=\"option as SelectOption<T>\">\n <Tag\n v-if=\"option.color\"\n :color=\"option.color\"\n :icon=\"option.icon\"\n :icon-color=\"option.iconColor\"\n :name=\"option.label\"\n />\n <template v-else>\n <Icon\n v-if=\"option.icon\"\n class=\"shrink-0\"\n :color=\"option.iconColor ?? 'ink-subtle'\"\n :name=\"option.icon\"\n />{{ option.label }}\n </template>\n </slot>\n </span>\n <CheckIcon v-if=\"values.includes(option.value)\" />\n </ListboxItem>\n </ListboxVirtualizer>\n <template v-else>\n <ListboxItem\n v-for=\"option in listed\"\n :key=\"option.value\"\n :class=\"optionClass\"\n :disabled=\"option.disabled\"\n :value=\"option.value\"\n @select=\"onSelect($event, option)\"\n >\n <span class=\"inline-flex min-w-0 items-center gap-1.5 truncate\">\n <slot name=\"option\" :option=\"option\">\n <Tag\n v-if=\"option.color\"\n :color=\"option.color\"\n :icon=\"option.icon\"\n :icon-color=\"option.iconColor\"\n :name=\"option.label\"\n />\n <template v-else>\n <Icon\n v-if=\"option.icon\"\n class=\"shrink-0\"\n :color=\"option.iconColor ?? 'ink-subtle'\"\n :name=\"option.icon\"\n />{{ option.label }}\n </template>\n </slot>\n </span>\n <CheckIcon v-if=\"values.includes(option.value)\" />\n </ListboxItem>\n </template>\n <ListboxItem v-if=\"showCreate\" :class=\"optionClass\" :value=\"CREATE\" @select=\"onSelect($event, CREATE)\">\n <span class=\"inline-flex min-w-0 items-center gap-1.5\">\n {{ createLabel }}\n <Tag v-if=\"createColored\" :color=\"newHue\" :name=\"query.trim()\" />\n <strong v-else class=\"font-medium\">“{{ query.trim() }}”</strong>\n </span>\n </ListboxItem>\n </ListboxContent>\n <div v-else class=\"px-3.5 py-3 text-13 text-sui-ink-muted\">{{ emptyLabel }}</div>\n </ListboxRoot>\n </PopoverContent>\n </PopoverPortal>\n </PopoverRoot>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"Select.vue_vue_type_script_setup_true_lang.js","names":["_useModel","_openBlock","_createBlock","_unref","_withCtx","_createVNode","_renderSlot","_createElementVNode","_mergeProps","_createElementBlock","_toDisplayString","_createCommentVNode","_Fragment","_renderList","Tag","Icon","_normalizeClass","_normalizeStyle","Spinner","_createTextVNode","CheckIcon","Icon_default","CheckIcon_default","Spinner_default","Tag_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","_hoisted_14","optionClass","Select_vue_vue_type_script_setup_true_lang_default","\"modelValue\"","\"modelModifiers\"","__emit","props","__props","emit","attrs","useAttrs","label","computed","triggerAttrs","key","model","useModel","open","ref","query","keyboard","pointer","values","picked","shallowRef","selected","list","option","value","search","removable","matches","text","listed","showCreate","virtual","createHues","newHue","CREATE","fieldAttrs","isInvalid","useFieldControl","setQuery","show","viaKeyboard","close","toggle","event","choose","known","creating","create","draft","error","onSelect","row","remove","chosen","onKeydown","onTriggerKeydown","onOpenAutoFocus","nextTick","anchor","onPointerDownOutside","target","returnFocus","listbox","onHighlight","payload","triggerSizes","openBlock","createBlock","unref","PopoverRoot","_cache","withCtx","createVNode","PopoverAnchor","renderSlot","_ctx","createElementVNode","mergeProps","createElementBlock","toDisplayString","createCommentVNode","Fragment","renderList","PopoverPortal","PopoverContent","normalizeClass","normalizeStyle","ListboxRoot","ListboxFilter","ListboxContent","ListboxVirtualizer","ListboxItem","$event","createTextVNode"],"sources":["../../../src/components/Select/Select.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"T extends SelectValue\">\nimport { computed, nextTick, ref, shallowRef, useAttrs } from 'vue'\n\nimport {\n ListboxContent,\n ListboxFilter,\n ListboxItem,\n ListboxRoot,\n ListboxVirtualizer,\n PopoverAnchor,\n PopoverContent,\n PopoverPortal,\n PopoverRoot\n} from 'reka-ui'\n\nimport type { Hue } from '../../utils/hues'\nimport { useFieldControl } from '../FormField/context'\nimport Icon from '../Icon/Icon.vue'\nimport Spinner from '../Spinner/Spinner.vue'\nimport Tag from '../Tag/Tag.vue'\nimport CheckIcon from '../internal/CheckIcon.vue'\nimport type { SelectOption, SelectValue } from './types'\n\nexport interface SelectProps<T extends SelectValue> {\n options: SelectOption<T>[]\n /** The options for chosen values that aren't in `options`, such as a saved choice while `options` holds search\n * results. Options picked from the list are remembered without it. */\n selectedOptions?: SelectOption<T>[]\n multiple?: boolean\n /** Lets a single choice be removed, as a tag in the filter row or with Backspace there. */\n clearable?: boolean\n /** A filter row at the top of the list; on by default for `multiple`, `canCreate` or more than 8 options. */\n searchable?: boolean\n /** Narrows `options` to what's typed: by label, or by your function. `false` when `options` are already the results\n * for the query, such as from a server search through `query-change`. */\n filter?: boolean | ((option: SelectOption<T>, query: string) => boolean)\n /** Offers to create what was typed, through `createOption`. */\n canCreate?: boolean\n /** Makes the created option; by default its value is its label. */\n createOption?: (draft: { label: string; color?: Hue }) => SelectOption<T> | Promise<SelectOption<T>>\n /** Creates with a hue, shown as a tag. */\n createColored?: boolean\n loading?: boolean\n /** 36px for forms, 28px for table feet and toolbars. */\n size?: 'md' | 'sm'\n disabled?: boolean\n invalid?: boolean\n placeholder?: string\n searchPlaceholder?: string\n emptyLabel?: string\n createLabel?: string\n removeLabel?: string\n /** Where the list opens; it flips when there's no room. */\n side?: 'bottom' | 'top'\n align?: 'start' | 'end'\n /** The list's width, when it should differ from the trigger's, e.g. `20rem`. */\n panelWidth?: string\n}\n\n// Attributes (aria-label, class for its width) go to the trigger, the one element in the page's flow.\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<SelectProps<T>>(), {\n selectedOptions: () => [],\n searchable: undefined,\n filter: true,\n createOption: undefined,\n createColored: true,\n size: 'md',\n placeholder: 'Select an option',\n searchPlaceholder: 'Type to filter',\n emptyLabel: 'No results found',\n createLabel: 'Create',\n removeLabel: 'Remove',\n side: 'bottom',\n align: 'start',\n panelWidth: undefined\n})\n\nconst emit = defineEmits<{ 'query-change': [query: string]; 'create-error': [error: unknown] }>()\n\n// An aria-label would hide the trigger's visible value from its name; it's said before the value instead.\nconst attrs = useAttrs()\nconst label = computed(() => attrs['aria-label'] as string | undefined)\nconst triggerAttrs = computed(() => Object.fromEntries(Object.entries(attrs).filter(([key]) => key !== 'aria-label')))\n\nconst model = defineModel<T | T[] | null>({ default: null })\n\nconst open = ref(false)\nconst query = ref('')\nconst keyboard = ref(false)\nconst pointer = ref(false)\n\nconst values = computed<T[]>(() =>\n Array.isArray(model.value) ? model.value : model.value === null || model.value === undefined ? [] : [model.value]\n)\n// Options picked from earlier results, which `options` may no longer hold.\nconst picked = shallowRef<SelectOption<T>[]>([])\nconst selected = computed(() =>\n values.value\n .map((value) =>\n [props.options, props.selectedOptions, picked.value]\n .map((list) => list.find((option) => option.value === value))\n .find((option) => !!option)\n )\n .filter((option) => !!option)\n)\nconst search = computed(\n () =>\n props.searchable ??\n (props.multiple || props.canCreate || props.clearable || props.filter === false || props.options.length > 8)\n)\nconst removable = computed(() => props.multiple || props.clearable)\nconst matches = (option: SelectOption<T>, text: string) =>\n typeof props.filter === 'function'\n ? props.filter(option, text)\n : option.label.toLowerCase().includes(text.toLowerCase())\nconst listed = computed(() => {\n const text = query.value.trim()\n return props.options\n .filter((option) => !(props.multiple && search.value && values.value.includes(option.value)))\n .filter((option) => !text || props.filter === false || matches(option, text))\n})\nconst showCreate = computed(() => {\n const text = query.value.trim().toLowerCase()\n return props.canCreate && !!text && !props.options.some((option) => option.label.toLowerCase() === text)\n})\n// More than this and the list renders only the rows in view.\nconst virtual = computed(() => listed.value.length > 20)\n\nconst createHues: Hue[] = ['gray', 'purple', 'red', 'green', 'orange', 'pink', 'blue', 'slate']\nconst newHue = computed(() => createHues[query.value.length % createHues.length])\nconst CREATE = { create: true } as const\n\nconst { attrs: fieldAttrs, invalid: isInvalid } = useFieldControl(\n () => undefined,\n () => props.invalid\n)\n\nfunction setQuery(text: string) {\n query.value = text\n emit('query-change', text)\n}\n\nfunction show(viaKeyboard: boolean) {\n if (props.disabled) return\n keyboard.value = viaKeyboard\n pointer.value = false\n open.value = true\n}\n\nfunction close() {\n open.value = false\n if (query.value) setQuery('')\n}\n\nfunction toggle(event?: Event) {\n if (open.value) close()\n // A click from the keyboard (Enter, Space) has no pointer position.\n else show(!!event && (event as MouseEvent).detail === 0)\n}\n\nfunction choose(option: SelectOption<T>) {\n picked.value = [option, ...picked.value.filter((known) => known.value !== option.value)]\n if (props.multiple) {\n model.value = values.value.includes(option.value)\n ? values.value.filter((value) => value !== option.value)\n : [...values.value, option.value]\n setQuery('')\n } else {\n model.value = option.value\n close()\n }\n}\n\nconst creating = ref(false)\n\n// A failed createOption keeps what was typed, so it can be tried again.\nasync function create() {\n if (creating.value) return\n const label = query.value.trim()\n const draft = props.createColored ? { label, color: newHue.value } : { label }\n creating.value = true\n try {\n const option = props.createOption\n ? await props.createOption(draft)\n : ({ value: label as T, label, color: draft.color } as SelectOption<T>)\n choose(option)\n } catch (error) {\n emit('create-error', error)\n } finally {\n creating.value = false\n }\n}\n\nfunction onSelect(event: CustomEvent, row: SelectOption<T> | typeof CREATE) {\n // What's chosen lives in the model; the listbox keeps no selection of its own.\n event.preventDefault()\n if ('create' in row) create()\n else if (!row.disabled) choose(row)\n}\n\nfunction remove(value: T) {\n model.value = props.multiple ? values.value.filter((chosen) => chosen !== value) : null\n}\n\nfunction onKeydown(event: KeyboardEvent) {\n if (['ArrowUp', 'ArrowDown', 'Home', 'End'].includes(event.key)) keyboard.value = true\n if (event.key === 'Backspace' && removable.value && !query.value && values.value.length)\n remove(values.value[values.value.length - 1]!)\n}\n\nfunction onTriggerKeydown(event: KeyboardEvent) {\n if (!open.value && ['ArrowDown', 'ArrowUp'].includes(event.key)) {\n event.preventDefault()\n show(true)\n }\n}\n\n// The filter takes focus when there is one, or else the list, so the arrow keys work at once.\nfunction onOpenAutoFocus(event: Event) {\n event.preventDefault()\n nextTick(() =>\n (event.target as HTMLElement | null)?.querySelector<HTMLElement>('[data-select-filter], [role=\"listbox\"]')?.focus()\n )\n}\n\n// Back to the trigger, which Reka can't find: it's our anchor, not its trigger.\nconst anchor = ref<{ $el: HTMLElement }>()\n\n// Nor does Reka know a press on it isn't outside: closing there would let the click reopen the list.\nfunction onPointerDownOutside(event: CustomEvent<{ originalEvent: PointerEvent }>) {\n const target = event.detail.originalEvent.target\n if (target instanceof Node && anchor.value?.$el?.contains(target)) event.preventDefault()\n}\nfunction returnFocus(event: Event) {\n event.preventDefault()\n anchor.value?.$el?.focus()\n}\n\n// Reka highlights the first option as the list mounts; only the chosen one, the keyboard or the pointer should.\nconst listbox = ref()\nfunction onHighlight(payload: { value: unknown } | undefined) {\n if (keyboard.value || pointer.value || !payload) return\n if (values.value.includes(payload.value as T)) return\n nextTick(() => listbox.value && !keyboard.value && !pointer.value && (listbox.value.highlightedElement = null))\n}\n\nconst triggerSizes = { md: 'min-h-9 pr-2.5 pl-3 text-sm', sm: 'h-7 pr-1.5 pl-2 text-13' }\nconst optionClass =\n 'flex min-h-8 cursor-pointer items-center justify-between gap-3 rounded-lg py-1.5 pr-2 pl-2.5 text-13 whitespace-nowrap text-sui-ink outline-hidden select-none data-disabled:cursor-default data-disabled:opacity-50 data-highlighted:bg-sui-sunken data-[state=checked]:font-medium data-[state=checked]:text-sui-accent group-data-keyboard/list:data-highlighted:sui-ring-inset'\n</script>\n\n<!-- One select for every choice: a short fixed list, a searchable one, several values as tags (`multiple`), or creating\n what was typed (`canCreate`). For a server search, set `:filter=\"false\"` and replace `options` on `query-change`. The `trigger` slot draws your own trigger and gets `open`, `toggle` and `selected`. -->\n<template>\n <PopoverRoot :open=\"open\" @update:open=\"(value) => (value ? show(false) : close())\">\n <PopoverAnchor ref=\"anchor\" as-child>\n <slot name=\"trigger\" :open=\"open\" :selected=\"selected\" :toggle=\"toggle\">\n <button\n v-bind=\"{ ...fieldAttrs, ...triggerAttrs }\"\n :aria-expanded=\"open\"\n aria-haspopup=\"listbox\"\n :aria-invalid=\"isInvalid ? 'true' : undefined\"\n class=\"group inline-flex items-center justify-between gap-1.5 rounded-(--sui-radius-button) border bg-sui-surface text-left text-sui-ink transition-[border-color,box-shadow] duration-150 focus-visible:border-sui-accent focus-visible:sui-ring-field disabled:pointer-events-none disabled:opacity-60\"\n :class=\"[\n triggerSizes[size],\n isInvalid ? 'border-sui-danger-mid' : 'border-sui-line-strong hover:border-sui-ink-muted'\n ]\"\n :disabled=\"disabled\"\n type=\"button\"\n @click=\"toggle\"\n @keydown=\"onTriggerKeydown\"\n >\n <span v-if=\"label\" class=\"sr-only\">{{ label }}: </span>\n <span v-if=\"!selected.length\" class=\"text-sui-ink-faint\">{{ placeholder }}</span>\n <span v-else-if=\"multiple\" class=\"flex flex-wrap gap-1 py-1.25\">\n <Tag\n v-for=\"option in selected\"\n :key=\"option.value\"\n :color=\"option.color ?? undefined\"\n :icon=\"option.icon\"\n :icon-color=\"option.iconColor\"\n :name=\"option.label\"\n />\n </span>\n <Tag\n v-else-if=\"selected[0]!.color\"\n :color=\"selected[0]!.color\"\n :icon=\"selected[0]!.icon\"\n :icon-color=\"selected[0]!.iconColor\"\n :name=\"selected[0]!.label\"\n />\n <span v-else-if=\"selected[0]!.icon\" class=\"inline-flex min-w-0 items-center gap-1.5\">\n <Icon class=\"shrink-0\" :color=\"selected[0]!.iconColor ?? 'ink-subtle'\" :name=\"selected[0]!.icon\" />\n <span class=\"truncate whitespace-nowrap\">{{ selected[0]!.label }}</span>\n </span>\n <span v-else class=\"min-w-0 truncate whitespace-nowrap\">{{ selected[0]!.label }}</span>\n <svg\n aria-hidden=\"true\"\n class=\"size-4 shrink-0 fill-none stroke-sui-ink-muted transition-transform duration-150 group-aria-expanded:rotate-180\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"1.5\"\n viewBox=\"0 0 16 16\"\n >\n <path d=\"M4.5 6.5 8 10l3.5-3.5\" />\n </svg>\n </button>\n </slot>\n </PopoverAnchor>\n <PopoverPortal>\n <PopoverContent\n :align=\"align\"\n :aria-label=\"label ?? placeholder\"\n class=\"z-[1100] overflow-hidden rounded-xl border border-sui-line-subtle bg-sui-surface text-sui-ink shadow-lg data-[state=open]:animate-sui-menu-in\"\n :class=\"\n search ? 'min-w-[max(var(--reka-popover-trigger-width),15rem)]' : 'min-w-(--reka-popover-trigger-width)'\n \"\n :side=\"side\"\n :side-offset=\"4\"\n :style=\"panelWidth ? { width: panelWidth } : undefined\"\n @close-auto-focus=\"returnFocus\"\n @open-auto-focus=\"onOpenAutoFocus\"\n @pointer-down-outside=\"onPointerDownOutside\"\n >\n <ListboxRoot\n ref=\"listbox\"\n :highlight-on-hover=\"true\"\n :model-value=\"multiple ? values : (values[0] ?? undefined)\"\n :multiple=\"multiple\"\n @highlight=\"onHighlight\"\n @keydown=\"onKeydown\"\n @pointermove.capture=\"((keyboard = false), (pointer = true))\"\n >\n <div\n v-if=\"search\"\n class=\"flex min-h-11 flex-wrap items-center gap-1 border-b border-sui-line-subtle px-3 py-2.5\"\n >\n <template v-if=\"removable\">\n <Tag\n v-for=\"option in selected\"\n :key=\"option.value\"\n :color=\"option.color ?? undefined\"\n :icon=\"option.icon\"\n :icon-color=\"option.iconColor\"\n :name=\"option.label\"\n removable\n :remove-label=\"removeLabel\"\n @remove=\"remove(option.value)\"\n />\n </template>\n <!-- focus: classes too: an app's forms plugin rings focused text fields, and outranks plain utilities. -->\n <ListboxFilter\n :aria-label=\"label ?? placeholder\"\n class=\"h-5 min-w-16 flex-1 rounded-none border-none bg-transparent p-0 text-13 text-sui-ink shadow-none outline-hidden placeholder:text-sui-ink-faint focus:border-none focus:shadow-none focus:ring-0 focus:outline-hidden\"\n data-select-filter\n :model-value=\"query\"\n :placeholder=\"removable && selected.length ? '' : searchPlaceholder\"\n @update:model-value=\"setQuery\"\n />\n </div>\n <div v-if=\"loading\" class=\"flex justify-center py-6\"><Spinner size=\"sm\" /></div>\n <ListboxContent\n v-else-if=\"listed.length || showCreate\"\n :aria-label=\"label ?? placeholder\"\n class=\"group/list max-h-60 overflow-auto p-1 outline-hidden\"\n :data-keyboard=\"keyboard || undefined\"\n >\n <ListboxVirtualizer\n v-if=\"virtual\"\n v-slot=\"{ option }\"\n :estimate-size=\"32\"\n :options=\"listed\"\n :text-content=\"(option) => option.label\"\n >\n <ListboxItem\n :class=\"optionClass\"\n :disabled=\"option.disabled\"\n :value=\"option.value\"\n @select=\"onSelect($event, option as SelectOption<T>)\"\n >\n <span class=\"inline-flex min-w-0 items-center gap-1.5 truncate\">\n <slot name=\"option\" :option=\"option as SelectOption<T>\">\n <Tag\n v-if=\"option.color\"\n :color=\"option.color\"\n :icon=\"option.icon\"\n :icon-color=\"option.iconColor\"\n :name=\"option.label\"\n />\n <template v-else>\n <Icon\n v-if=\"option.icon\"\n class=\"shrink-0\"\n :color=\"option.iconColor ?? 'ink-subtle'\"\n :name=\"option.icon\"\n />{{ option.label }}\n </template>\n </slot>\n </span>\n <CheckIcon v-if=\"values.includes(option.value)\" />\n </ListboxItem>\n </ListboxVirtualizer>\n <template v-else>\n <ListboxItem\n v-for=\"option in listed\"\n :key=\"option.value\"\n :class=\"optionClass\"\n :disabled=\"option.disabled\"\n :value=\"option.value\"\n @select=\"onSelect($event, option)\"\n >\n <span class=\"inline-flex min-w-0 items-center gap-1.5 truncate\">\n <slot name=\"option\" :option=\"option\">\n <Tag\n v-if=\"option.color\"\n :color=\"option.color\"\n :icon=\"option.icon\"\n :icon-color=\"option.iconColor\"\n :name=\"option.label\"\n />\n <template v-else>\n <Icon\n v-if=\"option.icon\"\n class=\"shrink-0\"\n :color=\"option.iconColor ?? 'ink-subtle'\"\n :name=\"option.icon\"\n />{{ option.label }}\n </template>\n </slot>\n </span>\n <CheckIcon v-if=\"values.includes(option.value)\" />\n </ListboxItem>\n </template>\n <ListboxItem v-if=\"showCreate\" :class=\"optionClass\" :value=\"CREATE\" @select=\"onSelect($event, CREATE)\">\n <span class=\"inline-flex min-w-0 items-center gap-1.5\">\n {{ createLabel }}\n <Tag v-if=\"createColored\" :color=\"newHue\" :name=\"query.trim()\" />\n <strong v-else class=\"font-medium\">“{{ query.trim() }}”</strong>\n </span>\n </ListboxItem>\n </ListboxContent>\n <div v-else class=\"px-3.5 py-3 text-13 text-sui-ink-muted\">{{ emptyLabel }}</div>\n </ListboxRoot>\n </PopoverContent>\n </PopoverPortal>\n </PopoverRoot>\n</template>\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sparklingopinions/sparkling-ui",
3
- "version": "0.9.1",
3
+ "version": "0.9.2",
4
4
  "description": "A product-agnostic Vue 3 component library, themed by semantic tokens",
5
5
  "type": "module",
6
6
  "license": "MIT",