UNPKG

reka-ui

Version:

Vue port for Radix UI Primitives.

1 lines 8.76 kB
{"version":3,"file":"SelectItem.cjs","sources":["../../src/Select/SelectItem.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { Ref } from 'vue'\nimport type { PrimitiveProps } from '@/Primitive'\nimport { createContext, getActiveElement, handleAndDispatchCustomEvent, useForwardExpose, useId } from '@/shared'\nimport type { AcceptableValue } from '@/shared/types'\nimport { useCollection } from '@/Collection'\n\ninterface SelectItemContext<T = AcceptableValue> {\n value: T\n textId: string\n disabled: Ref<boolean>\n isSelected: Ref<boolean>\n onItemTextChange: (node: HTMLElement | undefined) => void\n}\n\nexport const [injectSelectItemContext, provideSelectItemContext]\n = createContext<SelectItemContext>('SelectItem')\n\nexport type SelectEvent<T> = CustomEvent<{ originalEvent: PointerEvent | KeyboardEvent, value?: T }>\n\nexport type SelectItemEmits<T = AcceptableValue> = {\n /** Event handler called when the selecting item. <br> It can be prevented by calling `event.preventDefault`. */\n select: [event: SelectEvent<T>]\n}\n\nexport interface SelectItemProps<T = AcceptableValue> extends PrimitiveProps {\n /** The value given as data when submitted with a `name`. */\n value: T\n /** When `true`, prevents the user from interacting with the item. */\n disabled?: boolean\n /**\n * Optional text used for typeahead purposes.\n *\n * By default the typeahead behavior will use the `.textContent` of the `SelectItemText` part.\n *\n * Use this when the content is complex, or you have non-textual content inside.\n */\n textValue?: string\n}\n</script>\n\n<script setup lang=\"ts\" generic=\"T extends AcceptableValue = AcceptableValue\">\nimport {\n computed,\n nextTick,\n onMounted,\n ref,\n toRefs,\n} from 'vue'\nimport { injectSelectRootContext } from './SelectRoot.vue'\nimport { injectSelectContentContext } from './SelectContentImpl.vue'\nimport { SELECTION_KEYS, valueComparator } from './utils'\nimport { Primitive } from '@/Primitive'\n\nconst props = defineProps<SelectItemProps>()\nconst emits = defineEmits<SelectItemEmits<T>>()\nconst { disabled } = toRefs(props)\n\nconst rootContext = injectSelectRootContext()\nconst contentContext = injectSelectContentContext()\nconst { forwardRef, currentElement } = useForwardExpose()\nconst { CollectionItem } = useCollection()\n\nconst isSelected = computed(() => valueComparator(rootContext.modelValue?.value, props.value, rootContext.by))\nconst isFocused = ref(false)\nconst textValue = ref(props.textValue ?? '')\nconst textId = useId(undefined, 'reka-select-item-text')\n\nconst SELECT_SELECT = 'select.select'\n\nasync function handleSelectCustomEvent(ev: PointerEvent | KeyboardEvent) {\n if (ev.defaultPrevented)\n return\n\n const eventDetail = { originalEvent: ev, value: props.value as T }\n handleAndDispatchCustomEvent(SELECT_SELECT, handleSelect, eventDetail)\n}\n\nasync function handleSelect(ev: SelectEvent<T>) {\n await nextTick()\n emits('select', ev)\n if (ev.defaultPrevented)\n return\n\n if (!disabled.value) {\n rootContext.onValueChange(props.value)\n if (!rootContext.multiple.value)\n rootContext.onOpenChange(false)\n }\n}\n\nasync function handlePointerMove(event: PointerEvent) {\n await nextTick()\n if (event.defaultPrevented)\n return\n if (disabled.value) {\n contentContext.onItemLeave?.()\n }\n else {\n // even though safari doesn't support this option, it's acceptable\n // as it only means it might scroll a few pixels when using the pointer.\n (event.currentTarget as HTMLElement).focus({ preventScroll: true })\n }\n}\n\nasync function handlePointerLeave(event: PointerEvent) {\n await nextTick()\n if (event.defaultPrevented)\n return\n if (event.currentTarget === getActiveElement())\n contentContext.onItemLeave?.()\n}\n\nasync function handleKeyDown(event: KeyboardEvent) {\n await nextTick()\n if (event.defaultPrevented)\n return\n const isTypingAhead = contentContext.searchRef?.value !== ''\n if (isTypingAhead && event.key === ' ')\n return\n if (SELECTION_KEYS.includes(event.key))\n handleSelectCustomEvent(event)\n // prevent page scroll if using the space key to select an item\n if (event.key === ' ')\n event.preventDefault()\n}\n\nif (props.value === '') {\n throw new Error(\n 'A <SelectItem /> must have a value prop that is not an empty string. This is because the Select value can be set to an empty string to clear the selection and show the placeholder.',\n )\n}\n\nonMounted(() => {\n if (!currentElement.value)\n return\n contentContext.itemRefCallback(\n currentElement.value,\n props.value,\n props.disabled,\n )\n})\n\nprovideSelectItemContext({\n value: props.value,\n disabled,\n textId,\n isSelected,\n onItemTextChange: (node) => {\n textValue.value = ((textValue.value || node?.textContent) ?? '').trim()\n },\n})\n</script>\n\n<template>\n <CollectionItem :value=\"{ textValue }\">\n <Primitive\n :ref=\"forwardRef\"\n role=\"option\"\n :aria-labelledby=\"textId\"\n :data-highlighted=\"isFocused ? '' : undefined\"\n :aria-selected=\"isSelected\"\n :data-state=\"isSelected ? 'checked' : 'unchecked'\"\n :aria-disabled=\"disabled || undefined\"\n :data-disabled=\"disabled ? '' : undefined\"\n :tabindex=\"disabled ? undefined : -1\"\n :as=\"as\"\n :as-child=\"asChild\"\n @focus=\"isFocused = true\"\n @blur=\"isFocused = false\"\n @pointerup=\"handleSelectCustomEvent\"\n @pointerdown=\"(event) => {\n (event.currentTarget as HTMLElement).focus({ preventScroll: true })\n }\"\n @touchend.prevent.stop\n @pointermove=\"handlePointerMove\"\n @pointerleave=\"handlePointerLeave\"\n @keydown=\"handleKeyDown\"\n >\n <slot />\n </Primitive>\n </CollectionItem>\n</template>\n"],"names":["createContext","toRefs","injectSelectRootContext","injectSelectContentContext","useForwardExpose","useCollection","computed","valueComparator","ref","useId","handleAndDispatchCustomEvent","nextTick","getActiveElement","SELECTION_KEYS","onMounted"],"mappings":"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"}