@auronui/vue 1.0.1 → 1.0.3

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.
Files changed (29) hide show
  1. package/LICENSE +21 -0
  2. package/dist/cjs/index.cjs +760 -194
  3. package/dist/cjs/index.cjs.map +1 -1
  4. package/dist/components/autocomplete/Autocomplete.context.js.map +1 -1
  5. package/dist/components/autocomplete/Autocomplete.js.map +1 -1
  6. package/dist/components/autocomplete/Autocomplete.vue_vue_type_script_setup_true_lang.js +7 -0
  7. package/dist/components/autocomplete/Autocomplete.vue_vue_type_script_setup_true_lang.js.map +1 -1
  8. package/dist/components/autocomplete/AutocompleteContent.js.map +1 -1
  9. package/dist/components/autocomplete/AutocompleteContent.vue_vue_type_script_setup_true_lang.js +10 -4
  10. package/dist/components/autocomplete/AutocompleteContent.vue_vue_type_script_setup_true_lang.js.map +1 -1
  11. package/dist/components/autocomplete/AutocompleteInput.js.map +1 -1
  12. package/dist/components/autocomplete/AutocompleteInput.vue_vue_type_script_setup_true_lang.js +2 -1
  13. package/dist/components/autocomplete/AutocompleteInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  14. package/dist/components/autocomplete/AutocompleteItem.js.map +1 -1
  15. package/dist/components/autocomplete/AutocompleteItem.vue_vue_type_script_setup_true_lang.js +5 -1
  16. package/dist/components/autocomplete/AutocompleteItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  17. package/dist/components/date-picker/DatePicker.js.map +1 -1
  18. package/dist/components/date-picker/DatePicker.vue_vue_type_script_setup_true_lang.js +6 -1
  19. package/dist/components/date-picker/DatePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  20. package/dist/components/date-time-picker/DateTimePicker.js +7 -0
  21. package/dist/components/date-time-picker/DateTimePicker.js.map +1 -0
  22. package/dist/components/date-time-picker/DateTimePicker.vue_vue_type_script_setup_true_lang.js +398 -0
  23. package/dist/components/date-time-picker/DateTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -0
  24. package/dist/components/date-time-picker/DateTimePickerTimeScroller.js +7 -0
  25. package/dist/components/date-time-picker/DateTimePickerTimeScroller.js.map +1 -0
  26. package/dist/components/date-time-picker/DateTimePickerTimeScroller.vue_vue_type_script_setup_true_lang.js +157 -0
  27. package/dist/components/date-time-picker/DateTimePickerTimeScroller.vue_vue_type_script_setup_true_lang.js.map +1 -0
  28. package/dist/index.js +2 -1
  29. package/package.json +15 -15
@@ -1 +1 @@
1
- {"version":3,"file":"Autocomplete.context.js","names":[],"sources":["../../../src/components/autocomplete/Autocomplete.context.ts"],"sourcesContent":["import { createContext } from '../../utils/context'\nimport type { ComputedRef, Ref } from 'vue'\nimport type { autocompleteVariants } from '@auronui/styles'\n\nexport interface AutocompleteContext {\n isDisabled: Ref<boolean>\n isInvalid: Ref<boolean>\n isReadonly: Ref<boolean>\n isRequired: Ref<boolean>\n isLoading: Ref<boolean>\n isFilled: Ref<boolean>\n fullWidth: Ref<boolean>\n hasLabel: Ref<boolean>\n labelPlacement: Ref<'inside' | 'outside' | 'outside-left'>\n inputId: Ref<string>\n label: Ref<string | undefined>\n ariaDescribedBy: Ref<string | undefined>\n slots: ComputedRef<ReturnType<typeof autocompleteVariants>>\n}\n\nexport const {\n useProvide: useAutocompleteProvide,\n useInject: useAutocompleteInject,\n key: autocompleteContextKey,\n} = createContext<AutocompleteContext>('Autocomplete')\n"],"mappings":";;AAoBA,IAAa,EACX,YAAY,wBACZ,WAAW,uBACX,KAAK,2BACH,cAAmC,eAAe"}
1
+ {"version":3,"file":"Autocomplete.context.js","names":[],"sources":["../../../src/components/autocomplete/Autocomplete.context.ts"],"sourcesContent":["import { createContext } from '../../utils/context'\nimport type { ComputedRef, Ref } from 'vue'\nimport type { autocompleteVariants } from '@auronui/styles'\n\nexport interface AutocompleteContext {\n isDisabled: Ref<boolean>\n isInvalid: Ref<boolean>\n isReadonly: Ref<boolean>\n isRequired: Ref<boolean>\n isLoading: Ref<boolean>\n isFilled: Ref<boolean>\n fullWidth: Ref<boolean>\n hasLabel: Ref<boolean>\n labelPlacement: Ref<'inside' | 'outside' | 'outside-left'>\n inputId: Ref<string>\n label: Ref<string | undefined>\n ariaDescribedBy: Ref<string | undefined>\n truncateItems: Ref<boolean>\n hasItems: Ref<boolean>\n slots: ComputedRef<ReturnType<typeof autocompleteVariants>>\n}\n\nexport const {\n useProvide: useAutocompleteProvide,\n useInject: useAutocompleteInject,\n key: autocompleteContextKey,\n} = createContext<AutocompleteContext>('Autocomplete')\n"],"mappings":";;AAsBA,IAAa,EACX,YAAY,wBACZ,WAAW,uBACX,KAAK,2BACH,cAAmC,eAAe"}
@@ -1 +1 @@
1
- {"version":3,"file":"Autocomplete.js","names":[],"sources":["../../../src/components/autocomplete/Autocomplete.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, onMounted, ref, toRef, useAttrs, useId, watch } from 'vue'\nimport { AutocompleteRoot } from 'reka-ui'\nimport { autocompleteVariants, type AutocompleteVariants } from '@auronui/styles'\nimport { composeClassName } from '../../utils/composeClassName'\nimport { useAutocompleteProvide } from './Autocomplete.context'\n\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<Props>(), {\n variant: 'flat',\n size: 'md',\n color: 'default',\n labelPlacement: 'inside',\n fullWidth: false,\n isInvalid: false,\n isDisabled: false,\n isReadonly: false,\n isRequired: false,\n modelValue: undefined,\n defaultValue: undefined,\n open: undefined,\n defaultOpen: undefined,\n items: () => [],\n loadItems: undefined,\n debounceMs: 200,\n filterOnOpen: false,\n})\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string]\n 'update:open': [value: boolean]\n}>()\n\nexport interface AutocompleteItem {\n value: string\n label?: string\n textValue?: string\n isDisabled?: boolean\n}\n\ntype Props = {\n /** Visual style of the field. @default 'flat' */\n variant?: AutocompleteVariants['variant']\n /** Field height. @default 'md' */\n size?: AutocompleteVariants['size']\n /** Accent color applied to focus ring + floating label. @default 'default' */\n color?: AutocompleteVariants['color']\n /**\n * Where the `label` is rendered relative to the field.\n * - `inside`: floats above the trigger (shrinks when focused/filled)\n * - `outside`: sits above the field, static\n * - `outside-left`: sits to the left, horizontal layout\n * @default 'inside'\n */\n labelPlacement?: AutocompleteVariants['labelPlacement']\n /** Stretches root wrapper to 100% width. @default false */\n fullWidth?: boolean\n /** Marks the field as invalid. Triggers danger styling and enables `errorMessage`. @default false */\n isInvalid?: boolean\n /** Disables the field. @default false */\n isDisabled?: boolean\n /** Makes the field read-only. @default false */\n isReadonly?: boolean\n /** Adds a required asterisk next to the label. @default false */\n isRequired?: boolean\n /** Placeholder shown when empty. */\n placeholder?: string\n /** Form field name, for native form submission. */\n name?: string\n /** Field label. When omitted, the floating-label behavior is skipped. */\n label?: string\n /** Helper text displayed below the field. Suppressed when `isInvalid && errorMessage` is shown. */\n description?: string\n /** Error text displayed below the field. Only rendered when `isInvalid` is also true. */\n errorMessage?: string\n /** Extra classes merged onto the root wrapper via `composeClassName`. */\n class?: string\n\n /* ─── Autocomplete-specific ─────────────────────────────────────── */\n /** Two-way bound selected value. */\n modelValue?: string\n /** Initial selected value (uncontrolled). */\n defaultValue?: string\n /** Controls open state of the dropdown. */\n open?: boolean\n /** Initial open state of the dropdown (uncontrolled). */\n defaultOpen?: boolean\n /** Static items list — used when no loadItems is provided. */\n items?: AutocompleteItem[]\n /** Async data source: called on every query change. */\n loadItems?: (query: string) => Promise<AutocompleteItem[]>\n /** Debounce delay for loadItems calls (ms). 0 = no debounce. */\n debounceMs?: number\n /** Apply filter immediately on open (default: false — show all items until user types). */\n filterOnOpen?: boolean\n}\n\nconst attrs = useAttrs()\nconst generatedId = useId()\nconst inputId = computed(() => (attrs.id as string | undefined) ?? generatedId)\n\nconst hasLabel = computed(() => !!props.label)\n\n// Internal async state\nconst isLoading = ref(false)\nconst internalItems = ref<AutocompleteItem[]>([...props.items])\n\n// Open-state tracking so we can skip client-side filtering until the user types\nconst isOpen = ref(props.defaultOpen ?? false)\nconst termAtOpen = ref('')\nconst isUserTyping = ref(false)\nconst effectiveIgnoreFilter = computed(() => {\n if (props.loadItems) return true\n if (!props.filterOnOpen && isOpen.value && !isUserTyping.value) return true\n return false\n})\n\n// Internal display text — bound to AutocompleteRoot's model-value.\n// Holds the LABEL (what the user reads), not the value. Bridged below.\nfunction labelFor(value: string | undefined): string {\n if (value == null || value === '') return ''\n const match = internalItems.value.find((i) => i.value === value)\n return match?.label ?? match?.textValue ?? value\n}\nfunction valueFor(displayed: string): string {\n if (!displayed) return ''\n const match = internalItems.value.find(\n (i) => (i.label ?? i.textValue ?? i.value) === displayed,\n )\n return match?.value ?? displayed\n}\n\nconst searchTerm = ref(labelFor(props.modelValue))\n\nconst isFilled = computed(() => !!searchTerm.value)\n\n// Helper IDs / aria wiring\nconst descriptionId = computed(() => `${inputId.value}-description`)\nconst errorMessageId = computed(() => `${inputId.value}-error`)\nconst showError = computed(() => props.isInvalid && !!props.errorMessage)\nconst showDescription = computed(() => !!props.description && !showError.value)\nconst hasHelper = computed(() => showError.value || showDescription.value)\nconst ariaDescribedBy = computed(() => {\n if (showError.value) return errorMessageId.value\n if (showDescription.value) return descriptionId.value\n return undefined\n})\n\n// Parent → internal: when the v-model value changes, reflect its label\nwatch(() => props.modelValue, (val) => {\n const next = labelFor(val)\n if (searchTerm.value !== next) searchTerm.value = next\n})\n\n// Internal → parent: when the displayed label changes, emit the real value.\n// Also detect user typing (for open-time filtering suppression).\nwatch(searchTerm, (displayed) => {\n const next = valueFor(displayed)\n if (next !== (props.modelValue ?? '')) emit('update:modelValue', next)\n if (isOpen.value && displayed !== termAtOpen.value) {\n isUserTyping.value = true\n }\n})\n\nfunction handleOpenChange(val: boolean) {\n isOpen.value = val\n if (val) {\n termAtOpen.value = searchTerm.value\n isUserTyping.value = false\n } else {\n isUserTyping.value = false\n }\n emit('update:open', val)\n}\n\n// Debounce timer\nlet debounceTimer: ReturnType<typeof setTimeout> | undefined\n\nasync function runLoadItems(query: string) {\n if (!props.loadItems) return\n isLoading.value = true\n try {\n internalItems.value = await props.loadItems(query)\n } finally {\n isLoading.value = false\n }\n}\n\nfunction scheduleLoad(query: string) {\n if (!props.loadItems) return\n clearTimeout(debounceTimer)\n if (props.debounceMs === 0) {\n // Run immediately (for tests and zero-debounce configs)\n void runLoadItems(query)\n } else {\n debounceTimer = setTimeout(() => void runLoadItems(query), props.debounceMs)\n }\n}\n\n// Initial load on mount\nonMounted(() => {\n if (props.loadItems) {\n void runLoadItems(searchTerm.value)\n }\n})\n\n// Watch searchTerm changes and invoke loadItems (debounced)\nwatch(searchTerm, (q) => {\n if (props.loadItems) {\n scheduleLoad(q)\n }\n})\n\n// Sync static items when they change\nwatch(() => props.items, (newItems) => {\n if (!props.loadItems) {\n internalItems.value = [...newItems]\n }\n})\n\n// When items arrive (async) or change, re-resolve the display label\nwatch(internalItems, () => {\n const next = labelFor(props.modelValue)\n if (next && searchTerm.value !== next && valueFor(searchTerm.value) === (props.modelValue ?? '')) {\n searchTerm.value = next\n }\n})\n\nconst slotFns = computed(() =>\n autocompleteVariants({\n variant: props.variant,\n size: props.size,\n color: props.color,\n fullWidth: props.fullWidth,\n isInvalid: props.isInvalid,\n isDisabled: props.isDisabled,\n isReadonly: props.isReadonly,\n hasLabel: hasLabel.value,\n labelPlacement: props.labelPlacement,\n }),\n)\n\nconst showOutsideLabel = computed(\n () => hasLabel.value && props.labelPlacement !== 'inside',\n)\n\nuseAutocompleteProvide({\n isDisabled: toRef(props, 'isDisabled'),\n isInvalid: toRef(props, 'isInvalid'),\n isReadonly: toRef(props, 'isReadonly'),\n isRequired: toRef(props, 'isRequired'),\n isLoading,\n isFilled,\n fullWidth: toRef(props, 'fullWidth'),\n hasLabel,\n labelPlacement: toRef(props, 'labelPlacement'),\n inputId,\n label: toRef(props, 'label'),\n ariaDescribedBy,\n slots: slotFns,\n})\n</script>\n\n<template>\n <div\n :class=\"composeClassName(slotFns.base(), props.class)\"\n :data-invalid=\"isInvalid || undefined\"\n :data-disabled=\"isDisabled || undefined\"\n :data-readonly=\"isReadonly || undefined\"\n :data-required=\"isRequired || undefined\"\n :data-has-label=\"hasLabel || undefined\"\n :data-has-helper=\"hasHelper || undefined\"\n >\n <label\n v-if=\"showOutsideLabel\"\n :for=\"inputId\"\n :class=\"slotFns.label()\"\n >{{ label }}<span\n v-if=\"isRequired\"\n aria-hidden=\"true\"\n > *</span></label>\n\n <div :class=\"slotFns.mainWrapper()\">\n <!-- AutocompleteRoot is Reka UI's distinct autocomplete primitive.\n ignoreFilter=true ensures server-returned items are never filtered\n client-side (the server handles filtering). -->\n <AutocompleteRoot\n v-model:model-value=\"searchTerm\"\n :open=\"props.open\"\n :default-open=\"props.defaultOpen\"\n :disabled=\"props.isDisabled\"\n :required=\"props.isRequired\"\n :ignore-filter=\"effectiveIgnoreFilter\"\n :open-on-focus=\"true\"\n @update:open=\"handleOpenChange\"\n >\n <slot\n :is-loading=\"isLoading\"\n :items=\"internalItems\"\n />\n </AutocompleteRoot>\n\n <div\n v-if=\"hasHelper\"\n :class=\"slotFns.helperWrapper()\"\n >\n <div\n v-if=\"showError\"\n :id=\"errorMessageId\"\n :class=\"slotFns.errorMessage()\"\n >\n {{ errorMessage }}\n </div>\n <div\n v-else-if=\"showDescription\"\n :id=\"descriptionId\"\n :class=\"slotFns.description()\"\n >\n {{ description }}\n </div>\n </div>\n </div>\n </div>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"Autocomplete.js","names":[],"sources":["../../../src/components/autocomplete/Autocomplete.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, onMounted, ref, toRef, useAttrs, useId, watch } from 'vue'\nimport { AutocompleteRoot } from 'reka-ui'\nimport { autocompleteVariants, type AutocompleteVariants } from '@auronui/styles'\nimport { composeClassName } from '../../utils/composeClassName'\nimport { useAutocompleteProvide } from './Autocomplete.context'\n\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<Props>(), {\n variant: 'flat',\n size: 'md',\n color: 'default',\n labelPlacement: 'inside',\n fullWidth: false,\n isInvalid: false,\n isDisabled: false,\n isReadonly: false,\n isRequired: false,\n modelValue: undefined,\n defaultValue: undefined,\n open: undefined,\n defaultOpen: undefined,\n items: () => [],\n loadItems: undefined,\n debounceMs: 200,\n filterOnOpen: false,\n truncateItems: true,\n})\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string]\n 'update:open': [value: boolean]\n}>()\n\nexport interface AutocompleteItem {\n value: string\n label?: string\n textValue?: string\n isDisabled?: boolean\n}\n\ntype Props = {\n /** Visual style of the field. @default 'flat' */\n variant?: AutocompleteVariants['variant']\n /** Field height. @default 'md' */\n size?: AutocompleteVariants['size']\n /** Accent color applied to focus ring + floating label. @default 'default' */\n color?: AutocompleteVariants['color']\n /**\n * Where the `label` is rendered relative to the field.\n * - `inside`: floats above the trigger (shrinks when focused/filled)\n * - `outside`: sits above the field, static\n * - `outside-left`: sits to the left, horizontal layout\n * @default 'inside'\n */\n labelPlacement?: AutocompleteVariants['labelPlacement']\n /** Stretches root wrapper to 100% width. @default false */\n fullWidth?: boolean\n /** Marks the field as invalid. Triggers danger styling and enables `errorMessage`. @default false */\n isInvalid?: boolean\n /** Disables the field. @default false */\n isDisabled?: boolean\n /** Makes the field read-only. @default false */\n isReadonly?: boolean\n /** Adds a required asterisk next to the label. @default false */\n isRequired?: boolean\n /** Placeholder shown when empty. */\n placeholder?: string\n /** Form field name, for native form submission. */\n name?: string\n /** Field label. When omitted, the floating-label behavior is skipped. */\n label?: string\n /** Helper text displayed below the field. Suppressed when `isInvalid && errorMessage` is shown. */\n description?: string\n /** Error text displayed below the field. Only rendered when `isInvalid` is also true. */\n errorMessage?: string\n /** Extra classes merged onto the root wrapper via `composeClassName`. */\n class?: string\n\n /* ─── Autocomplete-specific ─────────────────────────────────────── */\n /** Two-way bound selected value. */\n modelValue?: string\n /** Initial selected value (uncontrolled). */\n defaultValue?: string\n /** Controls open state of the dropdown. */\n open?: boolean\n /** Initial open state of the dropdown (uncontrolled). */\n defaultOpen?: boolean\n /** Static items list — used when no loadItems is provided. */\n items?: AutocompleteItem[]\n /** Async data source: called on every query change. */\n loadItems?: (query: string) => Promise<AutocompleteItem[]>\n /** Debounce delay for loadItems calls (ms). 0 = no debounce. */\n debounceMs?: number\n /** Apply filter immediately on open (default: false — show all items until user types). */\n filterOnOpen?: boolean\n /**\n * Truncate item text with an ellipsis when it overflows the dropdown width.\n * Set to `false` to show full text — the dropdown will widen to fit.\n * @default true\n */\n truncateItems?: boolean\n}\n\nconst attrs = useAttrs()\nconst generatedId = useId()\nconst inputId = computed(() => (attrs.id as string | undefined) ?? generatedId)\n\nconst hasLabel = computed(() => !!props.label)\n\n// Internal async state\nconst isLoading = ref(false)\nconst internalItems = ref<AutocompleteItem[]>([...props.items])\n\n// Open-state tracking so we can skip client-side filtering until the user types\nconst isOpen = ref(props.defaultOpen ?? false)\nconst termAtOpen = ref('')\nconst isUserTyping = ref(false)\nconst effectiveIgnoreFilter = computed(() => {\n if (props.loadItems) return true\n if (!props.filterOnOpen && isOpen.value && !isUserTyping.value) return true\n return false\n})\n\n// Internal display text — bound to AutocompleteRoot's model-value.\n// Holds the LABEL (what the user reads), not the value. Bridged below.\nfunction labelFor(value: string | undefined): string {\n if (value == null || value === '') return ''\n const match = internalItems.value.find((i) => i.value === value)\n return match?.label ?? match?.textValue ?? value\n}\nfunction valueFor(displayed: string): string {\n if (!displayed) return ''\n const match = internalItems.value.find(\n (i) => (i.label ?? i.textValue ?? i.value) === displayed,\n )\n return match?.value ?? displayed\n}\n\nconst searchTerm = ref(labelFor(props.modelValue))\n\nconst isFilled = computed(() => !!searchTerm.value)\nconst hasItems = computed(() => internalItems.value.length > 0)\n\n// Helper IDs / aria wiring\nconst descriptionId = computed(() => `${inputId.value}-description`)\nconst errorMessageId = computed(() => `${inputId.value}-error`)\nconst showError = computed(() => props.isInvalid && !!props.errorMessage)\nconst showDescription = computed(() => !!props.description && !showError.value)\nconst hasHelper = computed(() => showError.value || showDescription.value)\nconst ariaDescribedBy = computed(() => {\n if (showError.value) return errorMessageId.value\n if (showDescription.value) return descriptionId.value\n return undefined\n})\n\n// Parent → internal: when the v-model value changes, reflect its label\nwatch(() => props.modelValue, (val) => {\n const next = labelFor(val)\n if (searchTerm.value !== next) searchTerm.value = next\n})\n\n// Internal → parent: when the displayed label changes, emit the real value.\n// Also detect user typing (for open-time filtering suppression).\nwatch(searchTerm, (displayed) => {\n const next = valueFor(displayed)\n if (next !== (props.modelValue ?? '')) emit('update:modelValue', next)\n if (isOpen.value && displayed !== termAtOpen.value) {\n isUserTyping.value = true\n }\n})\n\nfunction handleOpenChange(val: boolean) {\n isOpen.value = val\n if (val) {\n termAtOpen.value = searchTerm.value\n isUserTyping.value = false\n } else {\n isUserTyping.value = false\n }\n emit('update:open', val)\n}\n\n// Debounce timer\nlet debounceTimer: ReturnType<typeof setTimeout> | undefined\n\nasync function runLoadItems(query: string) {\n if (!props.loadItems) return\n isLoading.value = true\n try {\n internalItems.value = await props.loadItems(query)\n } finally {\n isLoading.value = false\n }\n}\n\nfunction scheduleLoad(query: string) {\n if (!props.loadItems) return\n clearTimeout(debounceTimer)\n if (props.debounceMs === 0) {\n // Run immediately (for tests and zero-debounce configs)\n void runLoadItems(query)\n } else {\n debounceTimer = setTimeout(() => void runLoadItems(query), props.debounceMs)\n }\n}\n\n// Initial load on mount\nonMounted(() => {\n if (props.loadItems) {\n void runLoadItems(searchTerm.value)\n }\n})\n\n// Watch searchTerm changes and invoke loadItems (debounced)\nwatch(searchTerm, (q) => {\n if (props.loadItems) {\n scheduleLoad(q)\n }\n})\n\n// Sync static items when they change\nwatch(() => props.items, (newItems) => {\n if (!props.loadItems) {\n internalItems.value = [...newItems]\n }\n})\n\n// When items arrive (async) or change, re-resolve the display label\nwatch(internalItems, () => {\n const next = labelFor(props.modelValue)\n if (next && searchTerm.value !== next && valueFor(searchTerm.value) === (props.modelValue ?? '')) {\n searchTerm.value = next\n }\n})\n\nconst slotFns = computed(() =>\n autocompleteVariants({\n variant: props.variant,\n size: props.size,\n color: props.color,\n fullWidth: props.fullWidth,\n isInvalid: props.isInvalid,\n isDisabled: props.isDisabled,\n isReadonly: props.isReadonly,\n hasLabel: hasLabel.value,\n labelPlacement: props.labelPlacement,\n }),\n)\n\nconst showOutsideLabel = computed(\n () => hasLabel.value && props.labelPlacement !== 'inside',\n)\n\nuseAutocompleteProvide({\n isDisabled: toRef(props, 'isDisabled'),\n isInvalid: toRef(props, 'isInvalid'),\n isReadonly: toRef(props, 'isReadonly'),\n isRequired: toRef(props, 'isRequired'),\n isLoading,\n isFilled,\n fullWidth: toRef(props, 'fullWidth'),\n hasLabel,\n labelPlacement: toRef(props, 'labelPlacement'),\n inputId,\n label: toRef(props, 'label'),\n ariaDescribedBy,\n truncateItems: toRef(props, 'truncateItems'),\n hasItems,\n slots: slotFns,\n})\n</script>\n\n<template>\n <div\n :class=\"composeClassName(slotFns.base(), props.class)\"\n :data-invalid=\"isInvalid || undefined\"\n :data-disabled=\"isDisabled || undefined\"\n :data-readonly=\"isReadonly || undefined\"\n :data-required=\"isRequired || undefined\"\n :data-has-label=\"hasLabel || undefined\"\n :data-has-helper=\"hasHelper || undefined\"\n >\n <label\n v-if=\"showOutsideLabel\"\n :for=\"inputId\"\n :class=\"slotFns.label()\"\n >{{ label }}<span\n v-if=\"isRequired\"\n aria-hidden=\"true\"\n > *</span></label>\n\n <div :class=\"slotFns.mainWrapper()\">\n <!-- AutocompleteRoot is Reka UI's distinct autocomplete primitive.\n ignoreFilter=true ensures server-returned items are never filtered\n client-side (the server handles filtering). -->\n <AutocompleteRoot\n v-model:model-value=\"searchTerm\"\n :open=\"props.open\"\n :default-open=\"props.defaultOpen\"\n :disabled=\"props.isDisabled\"\n :required=\"props.isRequired\"\n :ignore-filter=\"effectiveIgnoreFilter\"\n :open-on-focus=\"true\"\n @update:open=\"handleOpenChange\"\n >\n <slot\n :is-loading=\"isLoading\"\n :items=\"internalItems\"\n />\n </AutocompleteRoot>\n\n <div\n v-if=\"hasHelper\"\n :class=\"slotFns.helperWrapper()\"\n >\n <div\n v-if=\"showError\"\n :id=\"errorMessageId\"\n :class=\"slotFns.errorMessage()\"\n >\n {{ errorMessage }}\n </div>\n <div\n v-else-if=\"showDescription\"\n :id=\"descriptionId\"\n :class=\"slotFns.description()\"\n >\n {{ description }}\n </div>\n </div>\n </div>\n </div>\n</template>\n"],"mappings":""}
@@ -72,6 +72,10 @@ var Autocomplete_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ d
72
72
  filterOnOpen: {
73
73
  type: Boolean,
74
74
  default: false
75
+ },
76
+ truncateItems: {
77
+ type: Boolean,
78
+ default: true
75
79
  }
76
80
  },
77
81
  emits: ["update:modelValue", "update:open"],
@@ -103,6 +107,7 @@ var Autocomplete_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ d
103
107
  }
104
108
  const searchTerm = ref(labelFor(props.modelValue));
105
109
  const isFilled = computed(() => !!searchTerm.value);
110
+ const hasItems = computed(() => internalItems.value.length > 0);
106
111
  const descriptionId = computed(() => `${inputId.value}-description`);
107
112
  const errorMessageId = computed(() => `${inputId.value}-error`);
108
113
  const showError = computed(() => props.isInvalid && !!props.errorMessage);
@@ -183,6 +188,8 @@ var Autocomplete_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ d
183
188
  inputId,
184
189
  label: toRef(props, "label"),
185
190
  ariaDescribedBy,
191
+ truncateItems: toRef(props, "truncateItems"),
192
+ hasItems,
186
193
  slots: slotFns
187
194
  });
188
195
  return (_ctx, _cache) => {
@@ -1 +1 @@
1
- {"version":3,"file":"Autocomplete.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/autocomplete/Autocomplete.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, onMounted, ref, toRef, useAttrs, useId, watch } from 'vue'\nimport { AutocompleteRoot } from 'reka-ui'\nimport { autocompleteVariants, type AutocompleteVariants } from '@auronui/styles'\nimport { composeClassName } from '../../utils/composeClassName'\nimport { useAutocompleteProvide } from './Autocomplete.context'\n\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<Props>(), {\n variant: 'flat',\n size: 'md',\n color: 'default',\n labelPlacement: 'inside',\n fullWidth: false,\n isInvalid: false,\n isDisabled: false,\n isReadonly: false,\n isRequired: false,\n modelValue: undefined,\n defaultValue: undefined,\n open: undefined,\n defaultOpen: undefined,\n items: () => [],\n loadItems: undefined,\n debounceMs: 200,\n filterOnOpen: false,\n})\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string]\n 'update:open': [value: boolean]\n}>()\n\nexport interface AutocompleteItem {\n value: string\n label?: string\n textValue?: string\n isDisabled?: boolean\n}\n\ntype Props = {\n /** Visual style of the field. @default 'flat' */\n variant?: AutocompleteVariants['variant']\n /** Field height. @default 'md' */\n size?: AutocompleteVariants['size']\n /** Accent color applied to focus ring + floating label. @default 'default' */\n color?: AutocompleteVariants['color']\n /**\n * Where the `label` is rendered relative to the field.\n * - `inside`: floats above the trigger (shrinks when focused/filled)\n * - `outside`: sits above the field, static\n * - `outside-left`: sits to the left, horizontal layout\n * @default 'inside'\n */\n labelPlacement?: AutocompleteVariants['labelPlacement']\n /** Stretches root wrapper to 100% width. @default false */\n fullWidth?: boolean\n /** Marks the field as invalid. Triggers danger styling and enables `errorMessage`. @default false */\n isInvalid?: boolean\n /** Disables the field. @default false */\n isDisabled?: boolean\n /** Makes the field read-only. @default false */\n isReadonly?: boolean\n /** Adds a required asterisk next to the label. @default false */\n isRequired?: boolean\n /** Placeholder shown when empty. */\n placeholder?: string\n /** Form field name, for native form submission. */\n name?: string\n /** Field label. When omitted, the floating-label behavior is skipped. */\n label?: string\n /** Helper text displayed below the field. Suppressed when `isInvalid && errorMessage` is shown. */\n description?: string\n /** Error text displayed below the field. Only rendered when `isInvalid` is also true. */\n errorMessage?: string\n /** Extra classes merged onto the root wrapper via `composeClassName`. */\n class?: string\n\n /* ─── Autocomplete-specific ─────────────────────────────────────── */\n /** Two-way bound selected value. */\n modelValue?: string\n /** Initial selected value (uncontrolled). */\n defaultValue?: string\n /** Controls open state of the dropdown. */\n open?: boolean\n /** Initial open state of the dropdown (uncontrolled). */\n defaultOpen?: boolean\n /** Static items list — used when no loadItems is provided. */\n items?: AutocompleteItem[]\n /** Async data source: called on every query change. */\n loadItems?: (query: string) => Promise<AutocompleteItem[]>\n /** Debounce delay for loadItems calls (ms). 0 = no debounce. */\n debounceMs?: number\n /** Apply filter immediately on open (default: false — show all items until user types). */\n filterOnOpen?: boolean\n}\n\nconst attrs = useAttrs()\nconst generatedId = useId()\nconst inputId = computed(() => (attrs.id as string | undefined) ?? generatedId)\n\nconst hasLabel = computed(() => !!props.label)\n\n// Internal async state\nconst isLoading = ref(false)\nconst internalItems = ref<AutocompleteItem[]>([...props.items])\n\n// Open-state tracking so we can skip client-side filtering until the user types\nconst isOpen = ref(props.defaultOpen ?? false)\nconst termAtOpen = ref('')\nconst isUserTyping = ref(false)\nconst effectiveIgnoreFilter = computed(() => {\n if (props.loadItems) return true\n if (!props.filterOnOpen && isOpen.value && !isUserTyping.value) return true\n return false\n})\n\n// Internal display text — bound to AutocompleteRoot's model-value.\n// Holds the LABEL (what the user reads), not the value. Bridged below.\nfunction labelFor(value: string | undefined): string {\n if (value == null || value === '') return ''\n const match = internalItems.value.find((i) => i.value === value)\n return match?.label ?? match?.textValue ?? value\n}\nfunction valueFor(displayed: string): string {\n if (!displayed) return ''\n const match = internalItems.value.find(\n (i) => (i.label ?? i.textValue ?? i.value) === displayed,\n )\n return match?.value ?? displayed\n}\n\nconst searchTerm = ref(labelFor(props.modelValue))\n\nconst isFilled = computed(() => !!searchTerm.value)\n\n// Helper IDs / aria wiring\nconst descriptionId = computed(() => `${inputId.value}-description`)\nconst errorMessageId = computed(() => `${inputId.value}-error`)\nconst showError = computed(() => props.isInvalid && !!props.errorMessage)\nconst showDescription = computed(() => !!props.description && !showError.value)\nconst hasHelper = computed(() => showError.value || showDescription.value)\nconst ariaDescribedBy = computed(() => {\n if (showError.value) return errorMessageId.value\n if (showDescription.value) return descriptionId.value\n return undefined\n})\n\n// Parent → internal: when the v-model value changes, reflect its label\nwatch(() => props.modelValue, (val) => {\n const next = labelFor(val)\n if (searchTerm.value !== next) searchTerm.value = next\n})\n\n// Internal → parent: when the displayed label changes, emit the real value.\n// Also detect user typing (for open-time filtering suppression).\nwatch(searchTerm, (displayed) => {\n const next = valueFor(displayed)\n if (next !== (props.modelValue ?? '')) emit('update:modelValue', next)\n if (isOpen.value && displayed !== termAtOpen.value) {\n isUserTyping.value = true\n }\n})\n\nfunction handleOpenChange(val: boolean) {\n isOpen.value = val\n if (val) {\n termAtOpen.value = searchTerm.value\n isUserTyping.value = false\n } else {\n isUserTyping.value = false\n }\n emit('update:open', val)\n}\n\n// Debounce timer\nlet debounceTimer: ReturnType<typeof setTimeout> | undefined\n\nasync function runLoadItems(query: string) {\n if (!props.loadItems) return\n isLoading.value = true\n try {\n internalItems.value = await props.loadItems(query)\n } finally {\n isLoading.value = false\n }\n}\n\nfunction scheduleLoad(query: string) {\n if (!props.loadItems) return\n clearTimeout(debounceTimer)\n if (props.debounceMs === 0) {\n // Run immediately (for tests and zero-debounce configs)\n void runLoadItems(query)\n } else {\n debounceTimer = setTimeout(() => void runLoadItems(query), props.debounceMs)\n }\n}\n\n// Initial load on mount\nonMounted(() => {\n if (props.loadItems) {\n void runLoadItems(searchTerm.value)\n }\n})\n\n// Watch searchTerm changes and invoke loadItems (debounced)\nwatch(searchTerm, (q) => {\n if (props.loadItems) {\n scheduleLoad(q)\n }\n})\n\n// Sync static items when they change\nwatch(() => props.items, (newItems) => {\n if (!props.loadItems) {\n internalItems.value = [...newItems]\n }\n})\n\n// When items arrive (async) or change, re-resolve the display label\nwatch(internalItems, () => {\n const next = labelFor(props.modelValue)\n if (next && searchTerm.value !== next && valueFor(searchTerm.value) === (props.modelValue ?? '')) {\n searchTerm.value = next\n }\n})\n\nconst slotFns = computed(() =>\n autocompleteVariants({\n variant: props.variant,\n size: props.size,\n color: props.color,\n fullWidth: props.fullWidth,\n isInvalid: props.isInvalid,\n isDisabled: props.isDisabled,\n isReadonly: props.isReadonly,\n hasLabel: hasLabel.value,\n labelPlacement: props.labelPlacement,\n }),\n)\n\nconst showOutsideLabel = computed(\n () => hasLabel.value && props.labelPlacement !== 'inside',\n)\n\nuseAutocompleteProvide({\n isDisabled: toRef(props, 'isDisabled'),\n isInvalid: toRef(props, 'isInvalid'),\n isReadonly: toRef(props, 'isReadonly'),\n isRequired: toRef(props, 'isRequired'),\n isLoading,\n isFilled,\n fullWidth: toRef(props, 'fullWidth'),\n hasLabel,\n labelPlacement: toRef(props, 'labelPlacement'),\n inputId,\n label: toRef(props, 'label'),\n ariaDescribedBy,\n slots: slotFns,\n})\n</script>\n\n<template>\n <div\n :class=\"composeClassName(slotFns.base(), props.class)\"\n :data-invalid=\"isInvalid || undefined\"\n :data-disabled=\"isDisabled || undefined\"\n :data-readonly=\"isReadonly || undefined\"\n :data-required=\"isRequired || undefined\"\n :data-has-label=\"hasLabel || undefined\"\n :data-has-helper=\"hasHelper || undefined\"\n >\n <label\n v-if=\"showOutsideLabel\"\n :for=\"inputId\"\n :class=\"slotFns.label()\"\n >{{ label }}<span\n v-if=\"isRequired\"\n aria-hidden=\"true\"\n > *</span></label>\n\n <div :class=\"slotFns.mainWrapper()\">\n <!-- AutocompleteRoot is Reka UI's distinct autocomplete primitive.\n ignoreFilter=true ensures server-returned items are never filtered\n client-side (the server handles filtering). -->\n <AutocompleteRoot\n v-model:model-value=\"searchTerm\"\n :open=\"props.open\"\n :default-open=\"props.defaultOpen\"\n :disabled=\"props.isDisabled\"\n :required=\"props.isRequired\"\n :ignore-filter=\"effectiveIgnoreFilter\"\n :open-on-focus=\"true\"\n @update:open=\"handleOpenChange\"\n >\n <slot\n :is-loading=\"isLoading\"\n :items=\"internalItems\"\n />\n </AutocompleteRoot>\n\n <div\n v-if=\"hasHelper\"\n :class=\"slotFns.helperWrapper()\"\n >\n <div\n v-if=\"showError\"\n :id=\"errorMessageId\"\n :class=\"slotFns.errorMessage()\"\n >\n {{ errorMessage }}\n </div>\n <div\n v-else-if=\"showDescription\"\n :id=\"descriptionId\"\n :class=\"slotFns.description()\"\n >\n {{ description }}\n </div>\n </div>\n </div>\n </div>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"Autocomplete.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/autocomplete/Autocomplete.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, onMounted, ref, toRef, useAttrs, useId, watch } from 'vue'\nimport { AutocompleteRoot } from 'reka-ui'\nimport { autocompleteVariants, type AutocompleteVariants } from '@auronui/styles'\nimport { composeClassName } from '../../utils/composeClassName'\nimport { useAutocompleteProvide } from './Autocomplete.context'\n\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<Props>(), {\n variant: 'flat',\n size: 'md',\n color: 'default',\n labelPlacement: 'inside',\n fullWidth: false,\n isInvalid: false,\n isDisabled: false,\n isReadonly: false,\n isRequired: false,\n modelValue: undefined,\n defaultValue: undefined,\n open: undefined,\n defaultOpen: undefined,\n items: () => [],\n loadItems: undefined,\n debounceMs: 200,\n filterOnOpen: false,\n truncateItems: true,\n})\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string]\n 'update:open': [value: boolean]\n}>()\n\nexport interface AutocompleteItem {\n value: string\n label?: string\n textValue?: string\n isDisabled?: boolean\n}\n\ntype Props = {\n /** Visual style of the field. @default 'flat' */\n variant?: AutocompleteVariants['variant']\n /** Field height. @default 'md' */\n size?: AutocompleteVariants['size']\n /** Accent color applied to focus ring + floating label. @default 'default' */\n color?: AutocompleteVariants['color']\n /**\n * Where the `label` is rendered relative to the field.\n * - `inside`: floats above the trigger (shrinks when focused/filled)\n * - `outside`: sits above the field, static\n * - `outside-left`: sits to the left, horizontal layout\n * @default 'inside'\n */\n labelPlacement?: AutocompleteVariants['labelPlacement']\n /** Stretches root wrapper to 100% width. @default false */\n fullWidth?: boolean\n /** Marks the field as invalid. Triggers danger styling and enables `errorMessage`. @default false */\n isInvalid?: boolean\n /** Disables the field. @default false */\n isDisabled?: boolean\n /** Makes the field read-only. @default false */\n isReadonly?: boolean\n /** Adds a required asterisk next to the label. @default false */\n isRequired?: boolean\n /** Placeholder shown when empty. */\n placeholder?: string\n /** Form field name, for native form submission. */\n name?: string\n /** Field label. When omitted, the floating-label behavior is skipped. */\n label?: string\n /** Helper text displayed below the field. Suppressed when `isInvalid && errorMessage` is shown. */\n description?: string\n /** Error text displayed below the field. Only rendered when `isInvalid` is also true. */\n errorMessage?: string\n /** Extra classes merged onto the root wrapper via `composeClassName`. */\n class?: string\n\n /* ─── Autocomplete-specific ─────────────────────────────────────── */\n /** Two-way bound selected value. */\n modelValue?: string\n /** Initial selected value (uncontrolled). */\n defaultValue?: string\n /** Controls open state of the dropdown. */\n open?: boolean\n /** Initial open state of the dropdown (uncontrolled). */\n defaultOpen?: boolean\n /** Static items list — used when no loadItems is provided. */\n items?: AutocompleteItem[]\n /** Async data source: called on every query change. */\n loadItems?: (query: string) => Promise<AutocompleteItem[]>\n /** Debounce delay for loadItems calls (ms). 0 = no debounce. */\n debounceMs?: number\n /** Apply filter immediately on open (default: false — show all items until user types). */\n filterOnOpen?: boolean\n /**\n * Truncate item text with an ellipsis when it overflows the dropdown width.\n * Set to `false` to show full text — the dropdown will widen to fit.\n * @default true\n */\n truncateItems?: boolean\n}\n\nconst attrs = useAttrs()\nconst generatedId = useId()\nconst inputId = computed(() => (attrs.id as string | undefined) ?? generatedId)\n\nconst hasLabel = computed(() => !!props.label)\n\n// Internal async state\nconst isLoading = ref(false)\nconst internalItems = ref<AutocompleteItem[]>([...props.items])\n\n// Open-state tracking so we can skip client-side filtering until the user types\nconst isOpen = ref(props.defaultOpen ?? false)\nconst termAtOpen = ref('')\nconst isUserTyping = ref(false)\nconst effectiveIgnoreFilter = computed(() => {\n if (props.loadItems) return true\n if (!props.filterOnOpen && isOpen.value && !isUserTyping.value) return true\n return false\n})\n\n// Internal display text — bound to AutocompleteRoot's model-value.\n// Holds the LABEL (what the user reads), not the value. Bridged below.\nfunction labelFor(value: string | undefined): string {\n if (value == null || value === '') return ''\n const match = internalItems.value.find((i) => i.value === value)\n return match?.label ?? match?.textValue ?? value\n}\nfunction valueFor(displayed: string): string {\n if (!displayed) return ''\n const match = internalItems.value.find(\n (i) => (i.label ?? i.textValue ?? i.value) === displayed,\n )\n return match?.value ?? displayed\n}\n\nconst searchTerm = ref(labelFor(props.modelValue))\n\nconst isFilled = computed(() => !!searchTerm.value)\nconst hasItems = computed(() => internalItems.value.length > 0)\n\n// Helper IDs / aria wiring\nconst descriptionId = computed(() => `${inputId.value}-description`)\nconst errorMessageId = computed(() => `${inputId.value}-error`)\nconst showError = computed(() => props.isInvalid && !!props.errorMessage)\nconst showDescription = computed(() => !!props.description && !showError.value)\nconst hasHelper = computed(() => showError.value || showDescription.value)\nconst ariaDescribedBy = computed(() => {\n if (showError.value) return errorMessageId.value\n if (showDescription.value) return descriptionId.value\n return undefined\n})\n\n// Parent → internal: when the v-model value changes, reflect its label\nwatch(() => props.modelValue, (val) => {\n const next = labelFor(val)\n if (searchTerm.value !== next) searchTerm.value = next\n})\n\n// Internal → parent: when the displayed label changes, emit the real value.\n// Also detect user typing (for open-time filtering suppression).\nwatch(searchTerm, (displayed) => {\n const next = valueFor(displayed)\n if (next !== (props.modelValue ?? '')) emit('update:modelValue', next)\n if (isOpen.value && displayed !== termAtOpen.value) {\n isUserTyping.value = true\n }\n})\n\nfunction handleOpenChange(val: boolean) {\n isOpen.value = val\n if (val) {\n termAtOpen.value = searchTerm.value\n isUserTyping.value = false\n } else {\n isUserTyping.value = false\n }\n emit('update:open', val)\n}\n\n// Debounce timer\nlet debounceTimer: ReturnType<typeof setTimeout> | undefined\n\nasync function runLoadItems(query: string) {\n if (!props.loadItems) return\n isLoading.value = true\n try {\n internalItems.value = await props.loadItems(query)\n } finally {\n isLoading.value = false\n }\n}\n\nfunction scheduleLoad(query: string) {\n if (!props.loadItems) return\n clearTimeout(debounceTimer)\n if (props.debounceMs === 0) {\n // Run immediately (for tests and zero-debounce configs)\n void runLoadItems(query)\n } else {\n debounceTimer = setTimeout(() => void runLoadItems(query), props.debounceMs)\n }\n}\n\n// Initial load on mount\nonMounted(() => {\n if (props.loadItems) {\n void runLoadItems(searchTerm.value)\n }\n})\n\n// Watch searchTerm changes and invoke loadItems (debounced)\nwatch(searchTerm, (q) => {\n if (props.loadItems) {\n scheduleLoad(q)\n }\n})\n\n// Sync static items when they change\nwatch(() => props.items, (newItems) => {\n if (!props.loadItems) {\n internalItems.value = [...newItems]\n }\n})\n\n// When items arrive (async) or change, re-resolve the display label\nwatch(internalItems, () => {\n const next = labelFor(props.modelValue)\n if (next && searchTerm.value !== next && valueFor(searchTerm.value) === (props.modelValue ?? '')) {\n searchTerm.value = next\n }\n})\n\nconst slotFns = computed(() =>\n autocompleteVariants({\n variant: props.variant,\n size: props.size,\n color: props.color,\n fullWidth: props.fullWidth,\n isInvalid: props.isInvalid,\n isDisabled: props.isDisabled,\n isReadonly: props.isReadonly,\n hasLabel: hasLabel.value,\n labelPlacement: props.labelPlacement,\n }),\n)\n\nconst showOutsideLabel = computed(\n () => hasLabel.value && props.labelPlacement !== 'inside',\n)\n\nuseAutocompleteProvide({\n isDisabled: toRef(props, 'isDisabled'),\n isInvalid: toRef(props, 'isInvalid'),\n isReadonly: toRef(props, 'isReadonly'),\n isRequired: toRef(props, 'isRequired'),\n isLoading,\n isFilled,\n fullWidth: toRef(props, 'fullWidth'),\n hasLabel,\n labelPlacement: toRef(props, 'labelPlacement'),\n inputId,\n label: toRef(props, 'label'),\n ariaDescribedBy,\n truncateItems: toRef(props, 'truncateItems'),\n hasItems,\n slots: slotFns,\n})\n</script>\n\n<template>\n <div\n :class=\"composeClassName(slotFns.base(), props.class)\"\n :data-invalid=\"isInvalid || undefined\"\n :data-disabled=\"isDisabled || undefined\"\n :data-readonly=\"isReadonly || undefined\"\n :data-required=\"isRequired || undefined\"\n :data-has-label=\"hasLabel || undefined\"\n :data-has-helper=\"hasHelper || undefined\"\n >\n <label\n v-if=\"showOutsideLabel\"\n :for=\"inputId\"\n :class=\"slotFns.label()\"\n >{{ label }}<span\n v-if=\"isRequired\"\n aria-hidden=\"true\"\n > *</span></label>\n\n <div :class=\"slotFns.mainWrapper()\">\n <!-- AutocompleteRoot is Reka UI's distinct autocomplete primitive.\n ignoreFilter=true ensures server-returned items are never filtered\n client-side (the server handles filtering). -->\n <AutocompleteRoot\n v-model:model-value=\"searchTerm\"\n :open=\"props.open\"\n :default-open=\"props.defaultOpen\"\n :disabled=\"props.isDisabled\"\n :required=\"props.isRequired\"\n :ignore-filter=\"effectiveIgnoreFilter\"\n :open-on-focus=\"true\"\n @update:open=\"handleOpenChange\"\n >\n <slot\n :is-loading=\"isLoading\"\n :items=\"internalItems\"\n />\n </AutocompleteRoot>\n\n <div\n v-if=\"hasHelper\"\n :class=\"slotFns.helperWrapper()\"\n >\n <div\n v-if=\"showError\"\n :id=\"errorMessageId\"\n :class=\"slotFns.errorMessage()\"\n >\n {{ errorMessage }}\n </div>\n <div\n v-else-if=\"showDescription\"\n :id=\"descriptionId\"\n :class=\"slotFns.description()\"\n >\n {{ description }}\n </div>\n </div>\n </div>\n </div>\n</template>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"AutocompleteContent.js","names":[],"sources":["../../../src/components/autocomplete/AutocompleteContent.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { AutocompletePortal, AutocompleteContent, AutocompleteViewport, AutocompleteEmpty, injectComboboxRootContext } from 'reka-ui'\nimport { motion, AnimatePresence } from 'motion-v'\nimport { useAutocompleteInject } from './Autocomplete.context'\n\nconst props = withDefaults(defineProps<{\n sideOffset?: number\n class?: string\n}>(), {\n sideOffset: 8,\n class: undefined,\n})\n\nconst ctx = useAutocompleteInject()\n// AutocompleteRoot internally provides the ComboboxRoot context\nconst rootContext = injectComboboxRootContext()\n</script>\n\n<template>\n <AutocompletePortal>\n <AnimatePresence>\n <AutocompleteContent\n v-if=\"rootContext.open.value\"\n position=\"popper\"\n :side-offset=\"props.sideOffset\"\n as-child\n data-slot=\"popover\"\n >\n <motion.div\n :class=\"['autocomplete__popover', 'relative']\"\n :data-loading=\"ctx.isLoading.value ? '' : undefined\"\n :aria-busy=\"ctx.isLoading.value || undefined\"\n :initial=\"{ opacity: 0, scale: 0.95 }\"\n :animate=\"{ opacity: 1, scale: 1 }\"\n :exit=\"{ opacity: 0, scale: 0.95 }\"\n :transition=\"{ duration: 0.15 }\"\n >\n <div\n :class=\"[\n 'transition-opacity duration-150',\n ctx.isLoading.value\n ? 'pointer-events-none opacity-50 grayscale cursor-not-allowed select-none'\n : '',\n ]\"\n :inert=\"ctx.isLoading.value || undefined\"\n :aria-disabled=\"ctx.isLoading.value || undefined\"\n :data-disabled=\"ctx.isLoading.value ? '' : undefined\"\n data-slot=\"list-wrapper\"\n >\n <AutocompleteViewport\n data-slot=\"list-box\"\n >\n <slot />\n <!-- Empty state when no items match -->\n <AutocompleteEmpty\n class=\"py-3 text-center text-sm text-default-400\"\n data-slot=\"empty-content\"\n >\n <slot name=\"empty\">\n No results found\n </slot>\n </AutocompleteEmpty>\n </AutocompleteViewport>\n </div>\n </motion.div>\n </AutocompleteContent>\n </AnimatePresence>\n </AutocompletePortal>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"AutocompleteContent.js","names":[],"sources":["../../../src/components/autocomplete/AutocompleteContent.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { AutocompletePortal, AutocompleteContent, AutocompleteViewport, AutocompleteEmpty, injectComboboxRootContext } from 'reka-ui'\nimport { motion, AnimatePresence } from 'motion-v'\nimport { useAutocompleteInject } from './Autocomplete.context'\n\nconst props = withDefaults(defineProps<{\n sideOffset?: number\n class?: string\n}>(), {\n sideOffset: 8,\n class: undefined,\n})\n\nconst ctx = useAutocompleteInject()\n// AutocompleteRoot internally provides the ComboboxRoot context\nconst rootContext = injectComboboxRootContext()\n</script>\n\n<template>\n <AutocompletePortal>\n <AnimatePresence>\n <AutocompleteContent\n v-if=\"rootContext.open.value && (ctx.hasItems.value || (ctx.isFilled.value && !ctx.isLoading.value))\"\n position=\"popper\"\n :side-offset=\"props.sideOffset\"\n as-child\n data-slot=\"popover\"\n >\n <motion.div\n :class=\"['autocomplete__popover', 'relative']\"\n :data-loading=\"ctx.isLoading.value ? '' : undefined\"\n :data-truncate-items=\"ctx.truncateItems.value ? undefined : 'false'\"\n :aria-busy=\"ctx.isLoading.value || undefined\"\n :initial=\"{ opacity: 0, scale: 0.95 }\"\n :animate=\"{ opacity: 1, scale: 1 }\"\n :exit=\"{ opacity: 0, scale: 0.95 }\"\n :transition=\"{ duration: 0.15 }\"\n >\n <div\n :class=\"[\n 'transition-opacity duration-150',\n ctx.isLoading.value\n ? 'pointer-events-none opacity-50 grayscale cursor-not-allowed select-none'\n : '',\n ]\"\n :inert=\"ctx.isLoading.value || undefined\"\n :aria-disabled=\"ctx.isLoading.value || undefined\"\n :data-disabled=\"ctx.isLoading.value ? '' : undefined\"\n data-slot=\"list-wrapper\"\n >\n <AutocompleteViewport\n data-slot=\"list-box\"\n >\n <slot />\n <!-- Empty state: only show when the user has typed a query -->\n <AutocompleteEmpty\n v-if=\"ctx.isFilled.value && !ctx.isLoading.value\"\n class=\"py-3 text-center text-sm text-default-400\"\n data-slot=\"empty-content\"\n >\n <slot name=\"empty\">\n No results found\n </slot>\n </AutocompleteEmpty>\n </AutocompleteViewport>\n </div>\n </motion.div>\n </AutocompleteContent>\n </AnimatePresence>\n </AutocompletePortal>\n</template>\n"],"mappings":""}
@@ -22,7 +22,7 @@ var AutocompleteContent_vue_vue_type_script_setup_true_lang_default = /* @__PURE
22
22
  return (_ctx, _cache) => {
23
23
  return openBlock(), createBlock(unref(AutocompletePortal), null, {
24
24
  default: withCtx(() => [createVNode(unref(AnimatePresence_default), null, {
25
- default: withCtx(() => [unref(rootContext).open.value ? (openBlock(), createBlock(unref(AutocompleteContent), {
25
+ default: withCtx(() => [unref(rootContext).open.value && (unref(ctx).hasItems.value || unref(ctx).isFilled.value && !unref(ctx).isLoading.value) ? (openBlock(), createBlock(unref(AutocompleteContent), {
26
26
  key: 0,
27
27
  position: "popper",
28
28
  "side-offset": props.sideOffset,
@@ -32,6 +32,7 @@ var AutocompleteContent_vue_vue_type_script_setup_true_lang_default = /* @__PURE
32
32
  default: withCtx(() => [createVNode(unref(motion).div, {
33
33
  class: normalizeClass(["autocomplete__popover", "relative"]),
34
34
  "data-loading": unref(ctx).isLoading.value ? "" : void 0,
35
+ "data-truncate-items": unref(ctx).truncateItems.value ? void 0 : "false",
35
36
  "aria-busy": unref(ctx).isLoading.value || void 0,
36
37
  initial: {
37
38
  opacity: 0,
@@ -54,17 +55,22 @@ var AutocompleteContent_vue_vue_type_script_setup_true_lang_default = /* @__PURE
54
55
  "data-disabled": unref(ctx).isLoading.value ? "" : void 0,
55
56
  "data-slot": "list-wrapper"
56
57
  }, [createVNode(unref(AutocompleteViewport), { "data-slot": "list-box" }, {
57
- default: withCtx(() => [renderSlot(_ctx.$slots, "default"), createVNode(unref(AutocompleteEmpty), {
58
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default"), unref(ctx).isFilled.value && !unref(ctx).isLoading.value ? (openBlock(), createBlock(unref(AutocompleteEmpty), {
59
+ key: 0,
58
60
  class: "py-3 text-center text-sm text-default-400",
59
61
  "data-slot": "empty-content"
60
62
  }, {
61
63
  default: withCtx(() => [renderSlot(_ctx.$slots, "empty", {}, () => [_cache[0] || (_cache[0] = createTextVNode(" No results found ", -1))])]),
62
64
  _: 3
63
- })]),
65
+ })) : createCommentVNode("", true)]),
64
66
  _: 3
65
67
  })], 10, _hoisted_1)]),
66
68
  _: 3
67
- }, 8, ["data-loading", "aria-busy"])]),
69
+ }, 8, [
70
+ "data-loading",
71
+ "data-truncate-items",
72
+ "aria-busy"
73
+ ])]),
68
74
  _: 3
69
75
  }, 8, ["side-offset"])) : createCommentVNode("", true)]),
70
76
  _: 3
@@ -1 +1 @@
1
- {"version":3,"file":"AutocompleteContent.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/autocomplete/AutocompleteContent.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { AutocompletePortal, AutocompleteContent, AutocompleteViewport, AutocompleteEmpty, injectComboboxRootContext } from 'reka-ui'\nimport { motion, AnimatePresence } from 'motion-v'\nimport { useAutocompleteInject } from './Autocomplete.context'\n\nconst props = withDefaults(defineProps<{\n sideOffset?: number\n class?: string\n}>(), {\n sideOffset: 8,\n class: undefined,\n})\n\nconst ctx = useAutocompleteInject()\n// AutocompleteRoot internally provides the ComboboxRoot context\nconst rootContext = injectComboboxRootContext()\n</script>\n\n<template>\n <AutocompletePortal>\n <AnimatePresence>\n <AutocompleteContent\n v-if=\"rootContext.open.value\"\n position=\"popper\"\n :side-offset=\"props.sideOffset\"\n as-child\n data-slot=\"popover\"\n >\n <motion.div\n :class=\"['autocomplete__popover', 'relative']\"\n :data-loading=\"ctx.isLoading.value ? '' : undefined\"\n :aria-busy=\"ctx.isLoading.value || undefined\"\n :initial=\"{ opacity: 0, scale: 0.95 }\"\n :animate=\"{ opacity: 1, scale: 1 }\"\n :exit=\"{ opacity: 0, scale: 0.95 }\"\n :transition=\"{ duration: 0.15 }\"\n >\n <div\n :class=\"[\n 'transition-opacity duration-150',\n ctx.isLoading.value\n ? 'pointer-events-none opacity-50 grayscale cursor-not-allowed select-none'\n : '',\n ]\"\n :inert=\"ctx.isLoading.value || undefined\"\n :aria-disabled=\"ctx.isLoading.value || undefined\"\n :data-disabled=\"ctx.isLoading.value ? '' : undefined\"\n data-slot=\"list-wrapper\"\n >\n <AutocompleteViewport\n data-slot=\"list-box\"\n >\n <slot />\n <!-- Empty state when no items match -->\n <AutocompleteEmpty\n class=\"py-3 text-center text-sm text-default-400\"\n data-slot=\"empty-content\"\n >\n <slot name=\"empty\">\n No results found\n </slot>\n </AutocompleteEmpty>\n </AutocompleteViewport>\n </div>\n </motion.div>\n </AutocompleteContent>\n </AnimatePresence>\n </AutocompletePortal>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;EAKA,MAAM,QAAQ;EAQd,MAAM,MAAM,uBAAsB;EAElC,MAAM,cAAc,2BAA0B;;uBAI5C,YAgDqB,MAAA,mBAAA,EAAA,MAAA;2BADD,CA9ClB,YA8CkB,MAAA,wBAAA,EAAA,MAAA;4BADM,CA3Cd,MAAA,YAAW,CAAC,KAAK,SAAA,WAAA,EADzB,YA4CsB,MAAA,oBAAA,EAAA;;MA1CpB,UAAS;MACR,eAAa,MAAM;MACpB,YAAA;MACA,aAAU;;6BAsCG,CApCb,YAoCa,MAAA,OAAA,CAAA,KAAA;OAnCV,OAAK,eAAE,CAAA,yBAAA,WAAqC,CAAA;OAC5C,gBAAc,MAAA,IAAG,CAAC,UAAU,QAAK,KAAQ,KAAA;OACzC,aAAW,MAAA,IAAG,CAAC,UAAU,SAAS,KAAA;OAClC,SAAS;QAAA,SAAA;QAAA,OAAA;QAA2B;OACpC,SAAS;QAAA,SAAA;QAAA,OAAA;QAAwB;OACjC,MAAM;QAAA,SAAA;QAAA,OAAA;QAA2B;OACjC,YAAY,EAAA,UAAA,KAAkB;;8BA4BzB,CA1BN,mBA0BM,OAAA;QAzBH,OAAK,eAAA,CAAA,mCAAmE,MAAA,IAAG,CAAC,UAAU,QAAA,4EAAA,GAAA,CAAA;QAMtF,OAAO,MAAA,IAAG,CAAC,UAAU,SAAS,KAAA;QAC9B,iBAAe,MAAA,IAAG,CAAC,UAAU,SAAS,KAAA;QACtC,iBAAe,MAAA,IAAG,CAAC,UAAU,QAAK,KAAQ,KAAA;QAC3C,aAAU;WAEV,YAauB,MAAA,qBAAA,EAAA,EAZrB,aAAU,YAAU,EAAA;+BAEZ,CAAR,WAAQ,KAAA,QAAA,UAAA,EAER,YAOoB,MAAA,kBAAA,EAAA;SANlB,OAAM;SACN,aAAU;;gCAIH,CAFP,WAEO,KAAA,QAAA,SAAA,EAAA,QAAA,CAAA,OAAA,OAAA,OAAA,KAAA,gBAFY,sBAEnB,GAAA,EAAA,CAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"AutocompleteContent.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/autocomplete/AutocompleteContent.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { AutocompletePortal, AutocompleteContent, AutocompleteViewport, AutocompleteEmpty, injectComboboxRootContext } from 'reka-ui'\nimport { motion, AnimatePresence } from 'motion-v'\nimport { useAutocompleteInject } from './Autocomplete.context'\n\nconst props = withDefaults(defineProps<{\n sideOffset?: number\n class?: string\n}>(), {\n sideOffset: 8,\n class: undefined,\n})\n\nconst ctx = useAutocompleteInject()\n// AutocompleteRoot internally provides the ComboboxRoot context\nconst rootContext = injectComboboxRootContext()\n</script>\n\n<template>\n <AutocompletePortal>\n <AnimatePresence>\n <AutocompleteContent\n v-if=\"rootContext.open.value && (ctx.hasItems.value || (ctx.isFilled.value && !ctx.isLoading.value))\"\n position=\"popper\"\n :side-offset=\"props.sideOffset\"\n as-child\n data-slot=\"popover\"\n >\n <motion.div\n :class=\"['autocomplete__popover', 'relative']\"\n :data-loading=\"ctx.isLoading.value ? '' : undefined\"\n :data-truncate-items=\"ctx.truncateItems.value ? undefined : 'false'\"\n :aria-busy=\"ctx.isLoading.value || undefined\"\n :initial=\"{ opacity: 0, scale: 0.95 }\"\n :animate=\"{ opacity: 1, scale: 1 }\"\n :exit=\"{ opacity: 0, scale: 0.95 }\"\n :transition=\"{ duration: 0.15 }\"\n >\n <div\n :class=\"[\n 'transition-opacity duration-150',\n ctx.isLoading.value\n ? 'pointer-events-none opacity-50 grayscale cursor-not-allowed select-none'\n : '',\n ]\"\n :inert=\"ctx.isLoading.value || undefined\"\n :aria-disabled=\"ctx.isLoading.value || undefined\"\n :data-disabled=\"ctx.isLoading.value ? '' : undefined\"\n data-slot=\"list-wrapper\"\n >\n <AutocompleteViewport\n data-slot=\"list-box\"\n >\n <slot />\n <!-- Empty state: only show when the user has typed a query -->\n <AutocompleteEmpty\n v-if=\"ctx.isFilled.value && !ctx.isLoading.value\"\n class=\"py-3 text-center text-sm text-default-400\"\n data-slot=\"empty-content\"\n >\n <slot name=\"empty\">\n No results found\n </slot>\n </AutocompleteEmpty>\n </AutocompleteViewport>\n </div>\n </motion.div>\n </AutocompleteContent>\n </AnimatePresence>\n </AutocompletePortal>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;EAKA,MAAM,QAAQ;EAQd,MAAM,MAAM,uBAAsB;EAElC,MAAM,cAAc,2BAA0B;;uBAI5C,YAkDqB,MAAA,mBAAA,EAAA,MAAA;2BADD,CAhDlB,YAgDkB,MAAA,wBAAA,EAAA,MAAA;4BADM,CA7Cd,MAAA,YAAW,CAAC,KAAK,UAAU,MAAA,IAAG,CAAC,SAAS,SAAU,MAAA,IAAG,CAAC,SAAS,SAAK,CAAK,MAAA,IAAG,CAAC,UAAU,UAAA,WAAA,EAD/F,YA8CsB,MAAA,oBAAA,EAAA;;MA5CpB,UAAS;MACR,eAAa,MAAM;MACpB,YAAA;MACA,aAAU;;6BAwCG,CAtCb,YAsCa,MAAA,OAAA,CAAA,KAAA;OArCV,OAAK,eAAE,CAAA,yBAAA,WAAqC,CAAA;OAC5C,gBAAc,MAAA,IAAG,CAAC,UAAU,QAAK,KAAQ,KAAA;OACzC,uBAAqB,MAAA,IAAG,CAAC,cAAc,QAAQ,KAAA,IAAS;OACxD,aAAW,MAAA,IAAG,CAAC,UAAU,SAAS,KAAA;OAClC,SAAS;QAAA,SAAA;QAAA,OAAA;QAA2B;OACpC,SAAS;QAAA,SAAA;QAAA,OAAA;QAAwB;OACjC,MAAM;QAAA,SAAA;QAAA,OAAA;QAA2B;OACjC,YAAY,EAAA,UAAA,KAAkB;;8BA6BzB,CA3BN,mBA2BM,OAAA;QA1BH,OAAK,eAAA,CAAA,mCAAmE,MAAA,IAAG,CAAC,UAAU,QAAA,4EAAA,GAAA,CAAA;QAMtF,OAAO,MAAA,IAAG,CAAC,UAAU,SAAS,KAAA;QAC9B,iBAAe,MAAA,IAAG,CAAC,UAAU,SAAS,KAAA;QACtC,iBAAe,MAAA,IAAG,CAAC,UAAU,QAAK,KAAQ,KAAA;QAC3C,aAAU;WAEV,YAcuB,MAAA,qBAAA,EAAA,EAbrB,aAAU,YAAU,EAAA;+BAEZ,CAAR,WAAQ,KAAA,QAAA,UAAA,EAGA,MAAA,IAAG,CAAC,SAAS,SAAK,CAAK,MAAA,IAAG,CAAC,UAAU,SAAA,WAAA,EAD7C,YAQoB,MAAA,kBAAA,EAAA;;SANlB,OAAM;SACN,aAAU;;gCAIH,CAFP,WAEO,KAAA,QAAA,SAAA,EAAA,QAAA,CAAA,OAAA,OAAA,OAAA,KAAA,gBAFY,sBAEnB,GAAA,EAAA,CAAA,CAAA,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"AutocompleteInput.js","names":[],"sources":["../../../src/components/autocomplete/AutocompleteInput.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, useTemplateRef } from 'vue'\nimport { useFocusWithin } from '@vueuse/core'\nimport { AutocompleteInput, AutocompleteTrigger, AutocompleteCancel, AutocompleteAnchor } from 'reka-ui'\nimport { useAutocompleteInject } from './Autocomplete.context'\nimport Spinner from '../spinner/Spinner.vue';\n\nconst props = withDefaults(defineProps<{\n placeholder?: string\n class?: string\n}>(), {\n placeholder: undefined,\n class: undefined,\n})\n\nconst ctx = useAutocompleteInject()\n\n// Track focused state via useFocusWithin (NOT manual @focus/@blur listeners) — the\n// inner Reka <AutocompleteInput> wraps the native <input>; useFocusWithin observes\n// the actual DOM subtree of the anchor, so isFocused flips reliably regardless of\n// how Reka forwards refs/attrs.\nconst anchorRef = useTemplateRef<HTMLElement>('anchor')\nconst { focused: isFocused } = useFocusWithin(anchorRef)\n\n// Render the inside-label only when (a) a label is set and (b) labelPlacement is 'inside'\nconst showInsideLabel = computed(\n () => ctx.hasLabel.value && ctx.labelPlacement.value === 'inside',\n)\n</script>\n\n<template>\n <AutocompleteAnchor\n ref=\"anchor\"\n :class=\"ctx.slots.value.trigger()\"\n :data-filled=\"ctx.hasLabel.value ? (ctx.isFilled.value || undefined) : undefined\"\n :data-focused=\"isFocused || undefined\"\n :data-invalid=\"ctx.isInvalid.value || undefined\"\n :data-disabled=\"ctx.isDisabled.value || undefined\"\n :data-readonly=\"ctx.isReadonly.value || undefined\"\n data-slot=\"trigger\"\n >\n <label\n v-if=\"showInsideLabel\"\n :for=\"ctx.inputId.value\"\n :class=\"ctx.slots.value.label()\"\n >{{ ctx.label.value }}<span\n v-if=\"ctx.isRequired.value\"\n aria-hidden=\"true\"\n > *</span></label>\n <span\n v-if=\"$slots.startContent\"\n :class=\"ctx.slots.value.startContent()\"\n data-slot=\"start-content\"\n >\n <slot name=\"startContent\" />\n </span>\n <AutocompleteInput\n :id=\"ctx.inputId.value\"\n :placeholder=\"props.placeholder\"\n :disabled=\"ctx.isDisabled.value\"\n :readonly=\"ctx.isReadonly.value\"\n :required=\"ctx.isRequired.value\"\n :aria-invalid=\"ctx.isInvalid.value || undefined\"\n :aria-describedby=\"ctx.ariaDescribedBy.value\"\n :class=\"ctx.slots.value.input()\"\n data-slot=\"input\"\n autocomplete=\"off\"\n />\n <!-- Clear button: resets the search term -->\n <AutocompleteCancel\n :class=\"ctx.slots.value.clearButton()\"\n data-slot=\"clear-button\"\n aria-label=\"Clear\"\n >\n <slot name=\"clearIcon\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n data-slot=\"autocomplete-clear-button-icon\"\n aria-hidden=\"true\"\n >\n <line\n x1=\"18\"\n y1=\"6\"\n x2=\"6\"\n y2=\"18\"\n />\n <line\n x1=\"6\"\n y1=\"6\"\n x2=\"18\"\n y2=\"18\"\n />\n </svg>\n </slot>\n </AutocompleteCancel>\n <!-- Inline loading spinner: replaces the dropdown indicator while loadItems is pending -->\n <span\n v-if=\"ctx.isLoading.value\"\n :class=\"ctx.slots.value.indicator()\"\n data-slot=\"autocomplete-loading-indicator\"\n role=\"status\"\n aria-live=\"polite\"\n aria-label=\"Loading suggestions\"\n >\n <Spinner size=\"sm\" />\n </span>\n <!-- Dropdown trigger indicator (hidden while loading) -->\n <AutocompleteTrigger\n v-else\n :class=\"ctx.slots.value.indicator()\"\n data-slot=\"autocomplete-default-indicator\"\n aria-label=\"Toggle suggestions\"\n >\n <slot name=\"triggerIcon\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"6 9 12 15 18 9\" />\n </svg>\n </slot>\n </AutocompleteTrigger>\n </AutocompleteAnchor>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"AutocompleteInput.js","names":[],"sources":["../../../src/components/autocomplete/AutocompleteInput.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, useTemplateRef } from 'vue'\nimport { useFocusWithin } from '@vueuse/core'\nimport { AutocompleteInput, AutocompleteTrigger, AutocompleteCancel, AutocompleteAnchor } from 'reka-ui'\nimport { useAutocompleteInject } from './Autocomplete.context'\nimport Spinner from '../spinner/Spinner.vue';\n\nconst props = withDefaults(defineProps<{\n placeholder?: string\n class?: string\n}>(), {\n placeholder: undefined,\n class: undefined,\n})\n\nconst ctx = useAutocompleteInject()\n\n// Track focused state via useFocusWithin (NOT manual @focus/@blur listeners) — the\n// inner Reka <AutocompleteInput> wraps the native <input>; useFocusWithin observes\n// the actual DOM subtree of the anchor, so isFocused flips reliably regardless of\n// how Reka forwards refs/attrs.\nconst anchorRef = useTemplateRef<HTMLElement>('anchor')\nconst { focused: isFocused } = useFocusWithin(anchorRef)\n\n// Render the inside-label only when (a) a label is set and (b) labelPlacement is 'inside'\nconst showInsideLabel = computed(\n () => ctx.hasLabel.value && ctx.labelPlacement.value === 'inside',\n)\n</script>\n\n<template>\n <AutocompleteAnchor\n ref=\"anchor\"\n :class=\"ctx.slots.value.trigger()\"\n :data-filled=\"ctx.hasLabel.value ? (ctx.isFilled.value || undefined) : undefined\"\n :data-focused=\"isFocused || undefined\"\n :data-invalid=\"ctx.isInvalid.value || undefined\"\n :data-disabled=\"ctx.isDisabled.value || undefined\"\n :data-readonly=\"ctx.isReadonly.value || undefined\"\n data-slot=\"trigger\"\n >\n <label\n v-if=\"showInsideLabel\"\n :for=\"ctx.inputId.value\"\n :class=\"ctx.slots.value.label()\"\n >{{ ctx.label.value }}<span\n v-if=\"ctx.isRequired.value\"\n aria-hidden=\"true\"\n > *</span></label>\n <span\n v-if=\"$slots.startContent\"\n :class=\"ctx.slots.value.startContent()\"\n data-slot=\"start-content\"\n >\n <slot name=\"startContent\" />\n </span>\n <AutocompleteInput\n :id=\"ctx.inputId.value\"\n :placeholder=\"props.placeholder\"\n :disabled=\"ctx.isDisabled.value\"\n :readonly=\"ctx.isReadonly.value\"\n :required=\"ctx.isRequired.value\"\n :aria-invalid=\"ctx.isInvalid.value || undefined\"\n :aria-describedby=\"ctx.ariaDescribedBy.value\"\n :class=\"ctx.slots.value.input()\"\n data-slot=\"input\"\n autocomplete=\"off\"\n />\n <!-- Clear button: only shown when filled and not in a readonly/disabled state.\n Reka's AutocompleteCancel does not set data-empty itself, so we drive it here. -->\n <AutocompleteCancel\n :class=\"ctx.slots.value.clearButton()\"\n :data-empty=\"(!ctx.isFilled.value || ctx.isReadonly.value || ctx.isDisabled.value) ? 'true' : undefined\"\n data-slot=\"clear-button\"\n aria-label=\"Clear\"\n >\n <slot name=\"clearIcon\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n data-slot=\"autocomplete-clear-button-icon\"\n aria-hidden=\"true\"\n >\n <line\n x1=\"18\"\n y1=\"6\"\n x2=\"6\"\n y2=\"18\"\n />\n <line\n x1=\"6\"\n y1=\"6\"\n x2=\"18\"\n y2=\"18\"\n />\n </svg>\n </slot>\n </AutocompleteCancel>\n <!-- Inline loading spinner: replaces the dropdown indicator while loadItems is pending -->\n <span\n v-if=\"ctx.isLoading.value\"\n :class=\"ctx.slots.value.indicator()\"\n data-slot=\"autocomplete-loading-indicator\"\n role=\"status\"\n aria-live=\"polite\"\n aria-label=\"Loading suggestions\"\n >\n <Spinner size=\"sm\" />\n </span>\n <!-- Dropdown trigger indicator (hidden while loading) -->\n <AutocompleteTrigger\n v-else\n :class=\"ctx.slots.value.indicator()\"\n data-slot=\"autocomplete-default-indicator\"\n aria-label=\"Toggle suggestions\"\n >\n <slot name=\"triggerIcon\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"6 9 12 15 18 9\" />\n </svg>\n </slot>\n </AutocompleteTrigger>\n </AutocompleteAnchor>\n</template>\n"],"mappings":""}
@@ -65,6 +65,7 @@ var AutocompleteInput_vue_vue_type_script_setup_true_lang_default = /* @__PURE__
65
65
  ]),
66
66
  createVNode(unref(AutocompleteCancel), {
67
67
  class: normalizeClass(unref(ctx).slots.value.clearButton()),
68
+ "data-empty": !unref(ctx).isFilled.value || unref(ctx).isReadonly.value || unref(ctx).isDisabled.value ? "true" : void 0,
68
69
  "data-slot": "clear-button",
69
70
  "aria-label": "Clear"
70
71
  }, {
@@ -92,7 +93,7 @@ var AutocompleteInput_vue_vue_type_script_setup_true_lang_default = /* @__PURE__
92
93
  y2: "18"
93
94
  })], -1))])]),
94
95
  _: 3
95
- }, 8, ["class"]),
96
+ }, 8, ["class", "data-empty"]),
96
97
  unref(ctx).isLoading.value ? (openBlock(), createElementBlock("span", {
97
98
  key: 2,
98
99
  class: normalizeClass(unref(ctx).slots.value.indicator()),
@@ -1 +1 @@
1
- {"version":3,"file":"AutocompleteInput.vue_vue_type_script_setup_true_lang.js","names":["$slots"],"sources":["../../../src/components/autocomplete/AutocompleteInput.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, useTemplateRef } from 'vue'\nimport { useFocusWithin } from '@vueuse/core'\nimport { AutocompleteInput, AutocompleteTrigger, AutocompleteCancel, AutocompleteAnchor } from 'reka-ui'\nimport { useAutocompleteInject } from './Autocomplete.context'\nimport Spinner from '../spinner/Spinner.vue';\n\nconst props = withDefaults(defineProps<{\n placeholder?: string\n class?: string\n}>(), {\n placeholder: undefined,\n class: undefined,\n})\n\nconst ctx = useAutocompleteInject()\n\n// Track focused state via useFocusWithin (NOT manual @focus/@blur listeners) — the\n// inner Reka <AutocompleteInput> wraps the native <input>; useFocusWithin observes\n// the actual DOM subtree of the anchor, so isFocused flips reliably regardless of\n// how Reka forwards refs/attrs.\nconst anchorRef = useTemplateRef<HTMLElement>('anchor')\nconst { focused: isFocused } = useFocusWithin(anchorRef)\n\n// Render the inside-label only when (a) a label is set and (b) labelPlacement is 'inside'\nconst showInsideLabel = computed(\n () => ctx.hasLabel.value && ctx.labelPlacement.value === 'inside',\n)\n</script>\n\n<template>\n <AutocompleteAnchor\n ref=\"anchor\"\n :class=\"ctx.slots.value.trigger()\"\n :data-filled=\"ctx.hasLabel.value ? (ctx.isFilled.value || undefined) : undefined\"\n :data-focused=\"isFocused || undefined\"\n :data-invalid=\"ctx.isInvalid.value || undefined\"\n :data-disabled=\"ctx.isDisabled.value || undefined\"\n :data-readonly=\"ctx.isReadonly.value || undefined\"\n data-slot=\"trigger\"\n >\n <label\n v-if=\"showInsideLabel\"\n :for=\"ctx.inputId.value\"\n :class=\"ctx.slots.value.label()\"\n >{{ ctx.label.value }}<span\n v-if=\"ctx.isRequired.value\"\n aria-hidden=\"true\"\n > *</span></label>\n <span\n v-if=\"$slots.startContent\"\n :class=\"ctx.slots.value.startContent()\"\n data-slot=\"start-content\"\n >\n <slot name=\"startContent\" />\n </span>\n <AutocompleteInput\n :id=\"ctx.inputId.value\"\n :placeholder=\"props.placeholder\"\n :disabled=\"ctx.isDisabled.value\"\n :readonly=\"ctx.isReadonly.value\"\n :required=\"ctx.isRequired.value\"\n :aria-invalid=\"ctx.isInvalid.value || undefined\"\n :aria-describedby=\"ctx.ariaDescribedBy.value\"\n :class=\"ctx.slots.value.input()\"\n data-slot=\"input\"\n autocomplete=\"off\"\n />\n <!-- Clear button: resets the search term -->\n <AutocompleteCancel\n :class=\"ctx.slots.value.clearButton()\"\n data-slot=\"clear-button\"\n aria-label=\"Clear\"\n >\n <slot name=\"clearIcon\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n data-slot=\"autocomplete-clear-button-icon\"\n aria-hidden=\"true\"\n >\n <line\n x1=\"18\"\n y1=\"6\"\n x2=\"6\"\n y2=\"18\"\n />\n <line\n x1=\"6\"\n y1=\"6\"\n x2=\"18\"\n y2=\"18\"\n />\n </svg>\n </slot>\n </AutocompleteCancel>\n <!-- Inline loading spinner: replaces the dropdown indicator while loadItems is pending -->\n <span\n v-if=\"ctx.isLoading.value\"\n :class=\"ctx.slots.value.indicator()\"\n data-slot=\"autocomplete-loading-indicator\"\n role=\"status\"\n aria-live=\"polite\"\n aria-label=\"Loading suggestions\"\n >\n <Spinner size=\"sm\" />\n </span>\n <!-- Dropdown trigger indicator (hidden while loading) -->\n <AutocompleteTrigger\n v-else\n :class=\"ctx.slots.value.indicator()\"\n data-slot=\"autocomplete-default-indicator\"\n aria-label=\"Toggle suggestions\"\n >\n <slot name=\"triggerIcon\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"6 9 12 15 18 9\" />\n </svg>\n </slot>\n </AutocompleteTrigger>\n </AutocompleteAnchor>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"AutocompleteInput.vue_vue_type_script_setup_true_lang.js","names":["$slots"],"sources":["../../../src/components/autocomplete/AutocompleteInput.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, useTemplateRef } from 'vue'\nimport { useFocusWithin } from '@vueuse/core'\nimport { AutocompleteInput, AutocompleteTrigger, AutocompleteCancel, AutocompleteAnchor } from 'reka-ui'\nimport { useAutocompleteInject } from './Autocomplete.context'\nimport Spinner from '../spinner/Spinner.vue';\n\nconst props = withDefaults(defineProps<{\n placeholder?: string\n class?: string\n}>(), {\n placeholder: undefined,\n class: undefined,\n})\n\nconst ctx = useAutocompleteInject()\n\n// Track focused state via useFocusWithin (NOT manual @focus/@blur listeners) — the\n// inner Reka <AutocompleteInput> wraps the native <input>; useFocusWithin observes\n// the actual DOM subtree of the anchor, so isFocused flips reliably regardless of\n// how Reka forwards refs/attrs.\nconst anchorRef = useTemplateRef<HTMLElement>('anchor')\nconst { focused: isFocused } = useFocusWithin(anchorRef)\n\n// Render the inside-label only when (a) a label is set and (b) labelPlacement is 'inside'\nconst showInsideLabel = computed(\n () => ctx.hasLabel.value && ctx.labelPlacement.value === 'inside',\n)\n</script>\n\n<template>\n <AutocompleteAnchor\n ref=\"anchor\"\n :class=\"ctx.slots.value.trigger()\"\n :data-filled=\"ctx.hasLabel.value ? (ctx.isFilled.value || undefined) : undefined\"\n :data-focused=\"isFocused || undefined\"\n :data-invalid=\"ctx.isInvalid.value || undefined\"\n :data-disabled=\"ctx.isDisabled.value || undefined\"\n :data-readonly=\"ctx.isReadonly.value || undefined\"\n data-slot=\"trigger\"\n >\n <label\n v-if=\"showInsideLabel\"\n :for=\"ctx.inputId.value\"\n :class=\"ctx.slots.value.label()\"\n >{{ ctx.label.value }}<span\n v-if=\"ctx.isRequired.value\"\n aria-hidden=\"true\"\n > *</span></label>\n <span\n v-if=\"$slots.startContent\"\n :class=\"ctx.slots.value.startContent()\"\n data-slot=\"start-content\"\n >\n <slot name=\"startContent\" />\n </span>\n <AutocompleteInput\n :id=\"ctx.inputId.value\"\n :placeholder=\"props.placeholder\"\n :disabled=\"ctx.isDisabled.value\"\n :readonly=\"ctx.isReadonly.value\"\n :required=\"ctx.isRequired.value\"\n :aria-invalid=\"ctx.isInvalid.value || undefined\"\n :aria-describedby=\"ctx.ariaDescribedBy.value\"\n :class=\"ctx.slots.value.input()\"\n data-slot=\"input\"\n autocomplete=\"off\"\n />\n <!-- Clear button: only shown when filled and not in a readonly/disabled state.\n Reka's AutocompleteCancel does not set data-empty itself, so we drive it here. -->\n <AutocompleteCancel\n :class=\"ctx.slots.value.clearButton()\"\n :data-empty=\"(!ctx.isFilled.value || ctx.isReadonly.value || ctx.isDisabled.value) ? 'true' : undefined\"\n data-slot=\"clear-button\"\n aria-label=\"Clear\"\n >\n <slot name=\"clearIcon\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n data-slot=\"autocomplete-clear-button-icon\"\n aria-hidden=\"true\"\n >\n <line\n x1=\"18\"\n y1=\"6\"\n x2=\"6\"\n y2=\"18\"\n />\n <line\n x1=\"6\"\n y1=\"6\"\n x2=\"18\"\n y2=\"18\"\n />\n </svg>\n </slot>\n </AutocompleteCancel>\n <!-- Inline loading spinner: replaces the dropdown indicator while loadItems is pending -->\n <span\n v-if=\"ctx.isLoading.value\"\n :class=\"ctx.slots.value.indicator()\"\n data-slot=\"autocomplete-loading-indicator\"\n role=\"status\"\n aria-live=\"polite\"\n aria-label=\"Loading suggestions\"\n >\n <Spinner size=\"sm\" />\n </span>\n <!-- Dropdown trigger indicator (hidden while loading) -->\n <AutocompleteTrigger\n v-else\n :class=\"ctx.slots.value.indicator()\"\n data-slot=\"autocomplete-default-indicator\"\n aria-label=\"Toggle suggestions\"\n >\n <slot name=\"triggerIcon\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"6 9 12 15 18 9\" />\n </svg>\n </slot>\n </AutocompleteTrigger>\n </AutocompleteAnchor>\n</template>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"AutocompleteItem.js","names":[],"sources":["../../../src/components/autocomplete/AutocompleteItem.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { AutocompleteItem, ComboboxItemIndicator } from 'reka-ui'\n\nconst props = withDefaults(defineProps<{\n value: string\n textValue?: string\n isDisabled?: boolean\n class?: string\n}>(), {\n textValue: undefined,\n isDisabled: false,\n class: undefined,\n})\n</script>\n\n<template>\n <AutocompleteItem\n :value=\"props.textValue ?? props.value\"\n :text-value=\"props.textValue ?? props.value\"\n :disabled=\"props.isDisabled\"\n :data-item-value=\"props.value\"\n class=\"list-box-item list-box-item--default\"\n data-slot=\"list-box-item\"\n >\n <slot name=\"startContent\" />\n <slot />\n <ComboboxItemIndicator\n class=\"list-box-item__indicator\"\n data-slot=\"list-box-item-indicator\"\n >\n <slot name=\"selectedIcon\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n data-slot=\"list-box-item-indicator--checkmark\"\n aria-hidden=\"true\"\n >\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n </slot>\n </ComboboxItemIndicator>\n <slot name=\"endContent\" />\n </AutocompleteItem>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"AutocompleteItem.js","names":[],"sources":["../../../src/components/autocomplete/AutocompleteItem.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { AutocompleteItem, ComboboxItemIndicator } from 'reka-ui'\n\nconst props = withDefaults(defineProps<{\n value: string\n textValue?: string\n isDisabled?: boolean\n class?: string\n}>(), {\n textValue: undefined,\n isDisabled: false,\n class: undefined,\n})\n</script>\n\n<template>\n <AutocompleteItem\n :value=\"props.textValue ?? props.value\"\n :text-value=\"props.textValue ?? props.value\"\n :disabled=\"props.isDisabled\"\n :data-item-value=\"props.value\"\n class=\"list-box-item list-box-item--default\"\n data-slot=\"list-box-item\"\n >\n <slot name=\"startContent\" />\n <span class=\"autocomplete-item__text\" data-slot=\"item-text\"><slot /></span>\n <ComboboxItemIndicator\n class=\"list-box-item__indicator\"\n data-slot=\"list-box-item-indicator\"\n >\n <slot name=\"selectedIcon\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n data-slot=\"list-box-item-indicator--checkmark\"\n aria-hidden=\"true\"\n >\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n </slot>\n </ComboboxItemIndicator>\n <slot name=\"endContent\" />\n </AutocompleteItem>\n</template>\n"],"mappings":""}
@@ -1,6 +1,10 @@
1
1
  import { createBlock, createElementVNode, createVNode, defineComponent, openBlock, renderSlot, unref, withCtx } from "vue";
2
2
  import { AutocompleteItem, ComboboxItemIndicator } from "reka-ui";
3
3
  //#region src/components/autocomplete/AutocompleteItem.vue?vue&type=script&setup=true&lang.ts
4
+ var _hoisted_1 = {
5
+ class: "autocomplete-item__text",
6
+ "data-slot": "item-text"
7
+ };
4
8
  var AutocompleteItem_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
5
9
  __name: "AutocompleteItem",
6
10
  props: {
@@ -25,7 +29,7 @@ var AutocompleteItem_vue_vue_type_script_setup_true_lang_default = /* @__PURE__
25
29
  }, {
26
30
  default: withCtx(() => [
27
31
  renderSlot(_ctx.$slots, "startContent"),
28
- renderSlot(_ctx.$slots, "default"),
32
+ createElementVNode("span", _hoisted_1, [renderSlot(_ctx.$slots, "default")]),
29
33
  createVNode(unref(ComboboxItemIndicator), {
30
34
  class: "list-box-item__indicator",
31
35
  "data-slot": "list-box-item-indicator"
@@ -1 +1 @@
1
- {"version":3,"file":"AutocompleteItem.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/autocomplete/AutocompleteItem.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { AutocompleteItem, ComboboxItemIndicator } from 'reka-ui'\n\nconst props = withDefaults(defineProps<{\n value: string\n textValue?: string\n isDisabled?: boolean\n class?: string\n}>(), {\n textValue: undefined,\n isDisabled: false,\n class: undefined,\n})\n</script>\n\n<template>\n <AutocompleteItem\n :value=\"props.textValue ?? props.value\"\n :text-value=\"props.textValue ?? props.value\"\n :disabled=\"props.isDisabled\"\n :data-item-value=\"props.value\"\n class=\"list-box-item list-box-item--default\"\n data-slot=\"list-box-item\"\n >\n <slot name=\"startContent\" />\n <slot />\n <ComboboxItemIndicator\n class=\"list-box-item__indicator\"\n data-slot=\"list-box-item-indicator\"\n >\n <slot name=\"selectedIcon\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n data-slot=\"list-box-item-indicator--checkmark\"\n aria-hidden=\"true\"\n >\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n </slot>\n </ComboboxItemIndicator>\n <slot name=\"endContent\" />\n </AutocompleteItem>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;EAGA,MAAM,QAAQ;;uBAaZ,YAiCmB,MAAA,iBAAA,EAAA;IAhChB,OAAO,MAAM,aAAa,MAAM;IAChC,cAAY,MAAM,aAAa,MAAM;IACrC,UAAU,MAAM;IAChB,mBAAiB,MAAM;IACxB,OAAM;IACN,aAAU;;2BAEkB;KAA5B,WAA4B,KAAA,QAAA,eAAA;KAC5B,WAAQ,KAAA,QAAA,UAAA;KACR,YAqBwB,MAAA,sBAAA,EAAA;MApBtB,OAAM;MACN,aAAU;;6BAkBH,CAhBP,WAgBO,KAAA,QAAA,gBAAA,EAAA,QAAA,CAAA,OAAA,OAAA,OAAA,KAfL,mBAcM,OAAA;OAbJ,OAAM;OACN,OAAM;OACN,QAAO;OACP,SAAQ;OACR,MAAK;OACL,QAAO;OACP,gBAAa;OACb,kBAAe;OACf,mBAAgB;OAChB,aAAU;OACV,eAAY;UAEZ,mBAAoC,YAAA,EAA1B,QAAO,kBAAgB,CAAA,CAAA,EAAA,GAAA,EAAA,CAAA,CAAA,CAAA;;;KAIvC,WAA0B,KAAA,QAAA,aAAA"}
1
+ {"version":3,"file":"AutocompleteItem.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/autocomplete/AutocompleteItem.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { AutocompleteItem, ComboboxItemIndicator } from 'reka-ui'\n\nconst props = withDefaults(defineProps<{\n value: string\n textValue?: string\n isDisabled?: boolean\n class?: string\n}>(), {\n textValue: undefined,\n isDisabled: false,\n class: undefined,\n})\n</script>\n\n<template>\n <AutocompleteItem\n :value=\"props.textValue ?? props.value\"\n :text-value=\"props.textValue ?? props.value\"\n :disabled=\"props.isDisabled\"\n :data-item-value=\"props.value\"\n class=\"list-box-item list-box-item--default\"\n data-slot=\"list-box-item\"\n >\n <slot name=\"startContent\" />\n <span class=\"autocomplete-item__text\" data-slot=\"item-text\"><slot /></span>\n <ComboboxItemIndicator\n class=\"list-box-item__indicator\"\n data-slot=\"list-box-item-indicator\"\n >\n <slot name=\"selectedIcon\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n data-slot=\"list-box-item-indicator--checkmark\"\n aria-hidden=\"true\"\n >\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n </slot>\n </ComboboxItemIndicator>\n <slot name=\"endContent\" />\n </AutocompleteItem>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;EAGA,MAAM,QAAQ;;uBAaZ,YAiCmB,MAAA,iBAAA,EAAA;IAhChB,OAAO,MAAM,aAAa,MAAM;IAChC,cAAY,MAAM,aAAa,MAAM;IACrC,UAAU,MAAM;IAChB,mBAAiB,MAAM;IACxB,OAAM;IACN,aAAU;;2BAEkB;KAA5B,WAA4B,KAAA,QAAA,eAAA;KAC5B,mBAA2E,QAA3E,YAA2E,CAAf,WAAQ,KAAA,QAAA,UAAA,CAAA,CAAA;KACpE,YAqBwB,MAAA,sBAAA,EAAA;MApBtB,OAAM;MACN,aAAU;;6BAkBH,CAhBP,WAgBO,KAAA,QAAA,gBAAA,EAAA,QAAA,CAAA,OAAA,OAAA,OAAA,KAfL,mBAcM,OAAA;OAbJ,OAAM;OACN,OAAM;OACN,QAAO;OACP,SAAQ;OACR,MAAK;OACL,QAAO;OACP,gBAAa;OACb,kBAAe;OACf,mBAAgB;OAChB,aAAU;OACV,eAAY;UAEZ,mBAAoC,YAAA,EAA1B,QAAO,kBAAgB,CAAA,CAAA,EAAA,GAAA,EAAA,CAAA,CAAA,CAAA;;;KAIvC,WAA0B,KAAA,QAAA,aAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"DatePicker.js","names":[],"sources":["../../../src/components/date-picker/DatePicker.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport {\n DatePickerRoot,\n DatePickerTrigger,\n DatePickerContent,\n} from 'reka-ui'\nimport type { DateValue } from '@internationalized/date'\nimport { datePickerVariants, type DateInputVariants } from '@auronui/styles'\nimport { composeClassName } from '../../utils/composeClassName'\nimport Calendar from '../calendar/Calendar.vue'\nimport DateInput from '../date-input/DateInput.vue'\n\nconst props = withDefaults(defineProps<{\n /* Field appearance — forwarded to DateInput */\n variant?: DateInputVariants['variant']\n size?: DateInputVariants['size']\n color?: DateInputVariants['color']\n labelPlacement?: DateInputVariants['labelPlacement']\n fullWidth?: boolean\n\n defaultValue?: DateValue\n defaultOpen?: boolean\n placeholderValue?: DateValue\n minValue?: DateValue\n maxValue?: DateValue\n isDateUnavailable?: (date: DateValue) => boolean\n isDateDisabled?: (date: DateValue) => boolean\n locale?: string\n granularity?: 'day' | 'hour' | 'minute' | 'second'\n hourCycle?: 12 | 24\n label?: string\n description?: string\n errorMessage?: string\n isInvalid?: boolean\n isDisabled?: boolean\n isReadOnly?: boolean\n isRequired?: boolean\n name?: string\n hideTimeZone?: boolean\n visibleMonths?: number\n pageBehavior?: 'visible' | 'single'\n closeOnSelect?: boolean\n modal?: boolean\n class?: string\n}>(), {\n variant: 'flat',\n size: 'md',\n color: 'default',\n labelPlacement: 'inside',\n fullWidth: false,\n isInvalid: false,\n isDisabled: false,\n isReadOnly: false,\n isRequired: false,\n hideTimeZone: false,\n closeOnSelect: true,\n modal: false,\n visibleMonths: 1,\n defaultOpen: false,\n})\n\nconst modelValue = defineModel<DateValue | null | undefined>('modelValue')\nconst openModel = defineModel<boolean>('open')\n\nconst slotFns = computed(() => datePickerVariants())\n\n// Sync Calendar's `DateValue` v-model with DatePicker's `DateValue | null` model,\n// and close the popover on selection when closeOnSelect is enabled.\nconst calendarValue = computed<DateValue | undefined>({\n get: () => modelValue.value ?? undefined,\n set: (val) => {\n modelValue.value = val ?? null\n if (props.closeOnSelect && val != null) {\n openModel.value = false\n }\n },\n})\n</script>\n\n<template>\n <DatePickerRoot\n v-model=\"modelValue\"\n v-model:open=\"openModel\"\n :default-value=\"defaultValue\"\n :default-open=\"defaultOpen\"\n :placeholder-value=\"placeholderValue\"\n :min-value=\"minValue\"\n :max-value=\"maxValue\"\n :is-date-unavailable=\"isDateUnavailable\"\n :is-date-disabled=\"isDateDisabled\"\n :locale=\"locale\"\n :granularity=\"granularity\"\n :hour-cycle=\"hourCycle\"\n :disabled=\"isDisabled\"\n :readonly=\"isReadOnly\"\n :name=\"name\"\n :number-of-months=\"visibleMonths\"\n :class=\"composeClassName(slotFns.base(), props.class)\"\n data-slot=\"date-picker\"\n >\n <!-- DateInput hosts label/helper/field; trigger sits in its endContent slot -->\n <DateInput\n v-model=\"modelValue\"\n :variant=\"variant\"\n :size=\"size\"\n :color=\"color\"\n :label-placement=\"labelPlacement\"\n :full-width=\"fullWidth\"\n :default-value=\"defaultValue\"\n :placeholder-value=\"placeholderValue\"\n :min-value=\"minValue\"\n :max-value=\"maxValue\"\n :granularity=\"granularity\"\n :hour-cycle=\"hourCycle\"\n :locale=\"locale\"\n :label=\"label\"\n :description=\"description\"\n :error-message=\"errorMessage\"\n :is-invalid=\"isInvalid\"\n :is-disabled=\"isDisabled\"\n :is-read-only=\"isReadOnly\"\n :is-required=\"isRequired\"\n :name=\"name\"\n :hide-time-zone=\"hideTimeZone\"\n >\n <template #endContent>\n <DatePickerTrigger\n :class=\"slotFns.trigger()\"\n aria-label=\"Open date picker\"\n @mousedown.prevent\n >\n <slot name=\"selectorIcon\">\n <svg\n :class=\"slotFns.triggerIndicator()\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <rect\n x=\"3\"\n y=\"4\"\n width=\"18\"\n height=\"18\"\n rx=\"2\"\n ry=\"2\"\n />\n <line\n x1=\"16\"\n y1=\"2\"\n x2=\"16\"\n y2=\"6\"\n />\n <line\n x1=\"8\"\n y1=\"2\"\n x2=\"8\"\n y2=\"6\"\n />\n <line\n x1=\"3\"\n y1=\"10\"\n x2=\"21\"\n y2=\"10\"\n />\n </svg>\n </slot>\n </DatePickerTrigger>\n </template>\n </DateInput>\n\n <!-- Popover (portaled + positioned by Reka) -->\n <DatePickerContent\n :class=\"slotFns.popover()\"\n data-slot=\"popover\"\n :side-offset=\"8\"\n >\n <slot name=\"calendarTopContent\" />\n\n <Calendar\n v-model=\"calendarValue\"\n :default-value=\"defaultValue\"\n :default-placeholder=\"placeholderValue ?? defaultValue\"\n :min-value=\"minValue\"\n :max-value=\"maxValue\"\n :is-date-disabled=\"isDateDisabled\"\n :is-date-unavailable=\"isDateUnavailable\"\n :locale=\"locale\"\n :number-of-months=\"visibleMonths\"\n :readonly=\"isReadOnly\"\n :disabled=\"isDisabled\"\n />\n\n <slot name=\"calendarBottomContent\" />\n </DatePickerContent>\n </DatePickerRoot>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"DatePicker.js","names":[],"sources":["../../../src/components/date-picker/DatePicker.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport {\n DatePickerRoot,\n DatePickerTrigger,\n DatePickerContent,\n} from 'reka-ui'\nimport type { DateValue } from '@internationalized/date'\nimport type { CalendarDateTime, ZonedDateTime } from '@internationalized/date'\nimport { datePickerVariants, type DateInputVariants } from '@auronui/styles'\nimport { composeClassName } from '../../utils/composeClassName'\nimport Calendar from '../calendar/Calendar.vue'\nimport DateInput from '../date-input/DateInput.vue'\n\nconst props = withDefaults(defineProps<{\n /* Field appearance — forwarded to DateInput */\n variant?: DateInputVariants['variant']\n size?: DateInputVariants['size']\n color?: DateInputVariants['color']\n labelPlacement?: DateInputVariants['labelPlacement']\n fullWidth?: boolean\n\n defaultValue?: DateValue\n defaultOpen?: boolean\n placeholderValue?: DateValue\n minValue?: DateValue\n maxValue?: DateValue\n isDateUnavailable?: (date: DateValue) => boolean\n isDateDisabled?: (date: DateValue) => boolean\n locale?: string\n granularity?: 'day' | 'hour' | 'minute' | 'second'\n hourCycle?: 12 | 24\n label?: string\n description?: string\n errorMessage?: string\n isInvalid?: boolean\n isDisabled?: boolean\n isReadOnly?: boolean\n isRequired?: boolean\n name?: string\n hideTimeZone?: boolean\n visibleMonths?: number\n pageBehavior?: 'visible' | 'single'\n closeOnSelect?: boolean\n modal?: boolean\n class?: string\n}>(), {\n variant: 'flat',\n size: 'md',\n color: 'default',\n labelPlacement: 'inside',\n fullWidth: false,\n isInvalid: false,\n isDisabled: false,\n isReadOnly: false,\n isRequired: false,\n hideTimeZone: false,\n closeOnSelect: true,\n modal: false,\n visibleMonths: 1,\n defaultOpen: false,\n})\n\nconst modelValue = defineModel<DateValue | null | undefined>('modelValue')\nconst openModel = defineModel<boolean>('open')\n\nconst slotFns = computed(() => datePickerVariants())\n\n// Sync Calendar's `DateValue` v-model with DatePicker's `DateValue | null` model,\n// and close the popover on selection when closeOnSelect is enabled.\n// When the current value carries a time component (CalendarDateTime / ZonedDateTime),\n// preserve it so clicking a date in the calendar doesn't wipe out the time the user\n// typed into the field segments.\nconst calendarValue = computed<DateValue | undefined>({\n get: () => modelValue.value ?? undefined,\n set: (val) => {\n if (val != null && modelValue.value != null && 'hour' in modelValue.value) {\n const existing = modelValue.value as CalendarDateTime | ZonedDateTime\n modelValue.value = existing.set({ year: val.year, month: val.month, day: val.day })\n } else {\n modelValue.value = val ?? null\n }\n if (props.closeOnSelect && val != null) {\n openModel.value = false\n }\n },\n})\n</script>\n\n<template>\n <DatePickerRoot\n v-model=\"modelValue\"\n v-model:open=\"openModel\"\n :default-value=\"defaultValue\"\n :default-open=\"defaultOpen\"\n :placeholder-value=\"placeholderValue\"\n :min-value=\"minValue\"\n :max-value=\"maxValue\"\n :is-date-unavailable=\"isDateUnavailable\"\n :is-date-disabled=\"isDateDisabled\"\n :locale=\"locale\"\n :granularity=\"granularity\"\n :hour-cycle=\"hourCycle\"\n :disabled=\"isDisabled\"\n :readonly=\"isReadOnly\"\n :name=\"name\"\n :number-of-months=\"visibleMonths\"\n :class=\"composeClassName(slotFns.base(), props.class)\"\n data-slot=\"date-picker\"\n >\n <!-- DateInput hosts label/helper/field; trigger sits in its endContent slot -->\n <DateInput\n v-model=\"modelValue\"\n :variant=\"variant\"\n :size=\"size\"\n :color=\"color\"\n :label-placement=\"labelPlacement\"\n :full-width=\"fullWidth\"\n :default-value=\"defaultValue\"\n :placeholder-value=\"placeholderValue\"\n :min-value=\"minValue\"\n :max-value=\"maxValue\"\n :granularity=\"granularity\"\n :hour-cycle=\"hourCycle\"\n :locale=\"locale\"\n :label=\"label\"\n :description=\"description\"\n :error-message=\"errorMessage\"\n :is-invalid=\"isInvalid\"\n :is-disabled=\"isDisabled\"\n :is-read-only=\"isReadOnly\"\n :is-required=\"isRequired\"\n :name=\"name\"\n :hide-time-zone=\"hideTimeZone\"\n >\n <template #endContent>\n <DatePickerTrigger\n :class=\"slotFns.trigger()\"\n aria-label=\"Open date picker\"\n @mousedown.prevent\n >\n <slot name=\"selectorIcon\">\n <svg\n :class=\"slotFns.triggerIndicator()\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <rect\n x=\"3\"\n y=\"4\"\n width=\"18\"\n height=\"18\"\n rx=\"2\"\n ry=\"2\"\n />\n <line\n x1=\"16\"\n y1=\"2\"\n x2=\"16\"\n y2=\"6\"\n />\n <line\n x1=\"8\"\n y1=\"2\"\n x2=\"8\"\n y2=\"6\"\n />\n <line\n x1=\"3\"\n y1=\"10\"\n x2=\"21\"\n y2=\"10\"\n />\n </svg>\n </slot>\n </DatePickerTrigger>\n </template>\n </DateInput>\n\n <!-- Popover (portaled + positioned by Reka) -->\n <DatePickerContent\n :class=\"slotFns.popover()\"\n data-slot=\"popover\"\n :side-offset=\"8\"\n >\n <slot name=\"calendarTopContent\" />\n\n <Calendar\n v-model=\"calendarValue\"\n :default-value=\"defaultValue\"\n :default-placeholder=\"placeholderValue ?? defaultValue\"\n :min-value=\"minValue\"\n :max-value=\"maxValue\"\n :is-date-disabled=\"isDateDisabled\"\n :is-date-unavailable=\"isDateUnavailable\"\n :locale=\"locale\"\n :number-of-months=\"visibleMonths\"\n :readonly=\"isReadOnly\"\n :disabled=\"isDisabled\"\n />\n\n <slot name=\"calendarBottomContent\" />\n </DatePickerContent>\n </DatePickerRoot>\n</template>\n"],"mappings":""}
@@ -79,7 +79,12 @@ var DatePicker_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ def
79
79
  const calendarValue = computed({
80
80
  get: () => modelValue.value ?? void 0,
81
81
  set: (val) => {
82
- modelValue.value = val ?? null;
82
+ if (val != null && modelValue.value != null && "hour" in modelValue.value) modelValue.value = modelValue.value.set({
83
+ year: val.year,
84
+ month: val.month,
85
+ day: val.day
86
+ });
87
+ else modelValue.value = val ?? null;
83
88
  if (props.closeOnSelect && val != null) openModel.value = false;
84
89
  }
85
90
  });
@@ -1 +1 @@
1
- {"version":3,"file":"DatePicker.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/date-picker/DatePicker.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport {\n DatePickerRoot,\n DatePickerTrigger,\n DatePickerContent,\n} from 'reka-ui'\nimport type { DateValue } from '@internationalized/date'\nimport { datePickerVariants, type DateInputVariants } from '@auronui/styles'\nimport { composeClassName } from '../../utils/composeClassName'\nimport Calendar from '../calendar/Calendar.vue'\nimport DateInput from '../date-input/DateInput.vue'\n\nconst props = withDefaults(defineProps<{\n /* Field appearance — forwarded to DateInput */\n variant?: DateInputVariants['variant']\n size?: DateInputVariants['size']\n color?: DateInputVariants['color']\n labelPlacement?: DateInputVariants['labelPlacement']\n fullWidth?: boolean\n\n defaultValue?: DateValue\n defaultOpen?: boolean\n placeholderValue?: DateValue\n minValue?: DateValue\n maxValue?: DateValue\n isDateUnavailable?: (date: DateValue) => boolean\n isDateDisabled?: (date: DateValue) => boolean\n locale?: string\n granularity?: 'day' | 'hour' | 'minute' | 'second'\n hourCycle?: 12 | 24\n label?: string\n description?: string\n errorMessage?: string\n isInvalid?: boolean\n isDisabled?: boolean\n isReadOnly?: boolean\n isRequired?: boolean\n name?: string\n hideTimeZone?: boolean\n visibleMonths?: number\n pageBehavior?: 'visible' | 'single'\n closeOnSelect?: boolean\n modal?: boolean\n class?: string\n}>(), {\n variant: 'flat',\n size: 'md',\n color: 'default',\n labelPlacement: 'inside',\n fullWidth: false,\n isInvalid: false,\n isDisabled: false,\n isReadOnly: false,\n isRequired: false,\n hideTimeZone: false,\n closeOnSelect: true,\n modal: false,\n visibleMonths: 1,\n defaultOpen: false,\n})\n\nconst modelValue = defineModel<DateValue | null | undefined>('modelValue')\nconst openModel = defineModel<boolean>('open')\n\nconst slotFns = computed(() => datePickerVariants())\n\n// Sync Calendar's `DateValue` v-model with DatePicker's `DateValue | null` model,\n// and close the popover on selection when closeOnSelect is enabled.\nconst calendarValue = computed<DateValue | undefined>({\n get: () => modelValue.value ?? undefined,\n set: (val) => {\n modelValue.value = val ?? null\n if (props.closeOnSelect && val != null) {\n openModel.value = false\n }\n },\n})\n</script>\n\n<template>\n <DatePickerRoot\n v-model=\"modelValue\"\n v-model:open=\"openModel\"\n :default-value=\"defaultValue\"\n :default-open=\"defaultOpen\"\n :placeholder-value=\"placeholderValue\"\n :min-value=\"minValue\"\n :max-value=\"maxValue\"\n :is-date-unavailable=\"isDateUnavailable\"\n :is-date-disabled=\"isDateDisabled\"\n :locale=\"locale\"\n :granularity=\"granularity\"\n :hour-cycle=\"hourCycle\"\n :disabled=\"isDisabled\"\n :readonly=\"isReadOnly\"\n :name=\"name\"\n :number-of-months=\"visibleMonths\"\n :class=\"composeClassName(slotFns.base(), props.class)\"\n data-slot=\"date-picker\"\n >\n <!-- DateInput hosts label/helper/field; trigger sits in its endContent slot -->\n <DateInput\n v-model=\"modelValue\"\n :variant=\"variant\"\n :size=\"size\"\n :color=\"color\"\n :label-placement=\"labelPlacement\"\n :full-width=\"fullWidth\"\n :default-value=\"defaultValue\"\n :placeholder-value=\"placeholderValue\"\n :min-value=\"minValue\"\n :max-value=\"maxValue\"\n :granularity=\"granularity\"\n :hour-cycle=\"hourCycle\"\n :locale=\"locale\"\n :label=\"label\"\n :description=\"description\"\n :error-message=\"errorMessage\"\n :is-invalid=\"isInvalid\"\n :is-disabled=\"isDisabled\"\n :is-read-only=\"isReadOnly\"\n :is-required=\"isRequired\"\n :name=\"name\"\n :hide-time-zone=\"hideTimeZone\"\n >\n <template #endContent>\n <DatePickerTrigger\n :class=\"slotFns.trigger()\"\n aria-label=\"Open date picker\"\n @mousedown.prevent\n >\n <slot name=\"selectorIcon\">\n <svg\n :class=\"slotFns.triggerIndicator()\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <rect\n x=\"3\"\n y=\"4\"\n width=\"18\"\n height=\"18\"\n rx=\"2\"\n ry=\"2\"\n />\n <line\n x1=\"16\"\n y1=\"2\"\n x2=\"16\"\n y2=\"6\"\n />\n <line\n x1=\"8\"\n y1=\"2\"\n x2=\"8\"\n y2=\"6\"\n />\n <line\n x1=\"3\"\n y1=\"10\"\n x2=\"21\"\n y2=\"10\"\n />\n </svg>\n </slot>\n </DatePickerTrigger>\n </template>\n </DateInput>\n\n <!-- Popover (portaled + positioned by Reka) -->\n <DatePickerContent\n :class=\"slotFns.popover()\"\n data-slot=\"popover\"\n :side-offset=\"8\"\n >\n <slot name=\"calendarTopContent\" />\n\n <Calendar\n v-model=\"calendarValue\"\n :default-value=\"defaultValue\"\n :default-placeholder=\"placeholderValue ?? defaultValue\"\n :min-value=\"minValue\"\n :max-value=\"maxValue\"\n :is-date-disabled=\"isDateDisabled\"\n :is-date-unavailable=\"isDateUnavailable\"\n :locale=\"locale\"\n :number-of-months=\"visibleMonths\"\n :readonly=\"isReadOnly\"\n :disabled=\"isDisabled\"\n />\n\n <slot name=\"calendarBottomContent\" />\n </DatePickerContent>\n </DatePickerRoot>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"DatePicker.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/date-picker/DatePicker.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport {\n DatePickerRoot,\n DatePickerTrigger,\n DatePickerContent,\n} from 'reka-ui'\nimport type { DateValue } from '@internationalized/date'\nimport type { CalendarDateTime, ZonedDateTime } from '@internationalized/date'\nimport { datePickerVariants, type DateInputVariants } from '@auronui/styles'\nimport { composeClassName } from '../../utils/composeClassName'\nimport Calendar from '../calendar/Calendar.vue'\nimport DateInput from '../date-input/DateInput.vue'\n\nconst props = withDefaults(defineProps<{\n /* Field appearance — forwarded to DateInput */\n variant?: DateInputVariants['variant']\n size?: DateInputVariants['size']\n color?: DateInputVariants['color']\n labelPlacement?: DateInputVariants['labelPlacement']\n fullWidth?: boolean\n\n defaultValue?: DateValue\n defaultOpen?: boolean\n placeholderValue?: DateValue\n minValue?: DateValue\n maxValue?: DateValue\n isDateUnavailable?: (date: DateValue) => boolean\n isDateDisabled?: (date: DateValue) => boolean\n locale?: string\n granularity?: 'day' | 'hour' | 'minute' | 'second'\n hourCycle?: 12 | 24\n label?: string\n description?: string\n errorMessage?: string\n isInvalid?: boolean\n isDisabled?: boolean\n isReadOnly?: boolean\n isRequired?: boolean\n name?: string\n hideTimeZone?: boolean\n visibleMonths?: number\n pageBehavior?: 'visible' | 'single'\n closeOnSelect?: boolean\n modal?: boolean\n class?: string\n}>(), {\n variant: 'flat',\n size: 'md',\n color: 'default',\n labelPlacement: 'inside',\n fullWidth: false,\n isInvalid: false,\n isDisabled: false,\n isReadOnly: false,\n isRequired: false,\n hideTimeZone: false,\n closeOnSelect: true,\n modal: false,\n visibleMonths: 1,\n defaultOpen: false,\n})\n\nconst modelValue = defineModel<DateValue | null | undefined>('modelValue')\nconst openModel = defineModel<boolean>('open')\n\nconst slotFns = computed(() => datePickerVariants())\n\n// Sync Calendar's `DateValue` v-model with DatePicker's `DateValue | null` model,\n// and close the popover on selection when closeOnSelect is enabled.\n// When the current value carries a time component (CalendarDateTime / ZonedDateTime),\n// preserve it so clicking a date in the calendar doesn't wipe out the time the user\n// typed into the field segments.\nconst calendarValue = computed<DateValue | undefined>({\n get: () => modelValue.value ?? undefined,\n set: (val) => {\n if (val != null && modelValue.value != null && 'hour' in modelValue.value) {\n const existing = modelValue.value as CalendarDateTime | ZonedDateTime\n modelValue.value = existing.set({ year: val.year, month: val.month, day: val.day })\n } else {\n modelValue.value = val ?? null\n }\n if (props.closeOnSelect && val != null) {\n openModel.value = false\n }\n },\n})\n</script>\n\n<template>\n <DatePickerRoot\n v-model=\"modelValue\"\n v-model:open=\"openModel\"\n :default-value=\"defaultValue\"\n :default-open=\"defaultOpen\"\n :placeholder-value=\"placeholderValue\"\n :min-value=\"minValue\"\n :max-value=\"maxValue\"\n :is-date-unavailable=\"isDateUnavailable\"\n :is-date-disabled=\"isDateDisabled\"\n :locale=\"locale\"\n :granularity=\"granularity\"\n :hour-cycle=\"hourCycle\"\n :disabled=\"isDisabled\"\n :readonly=\"isReadOnly\"\n :name=\"name\"\n :number-of-months=\"visibleMonths\"\n :class=\"composeClassName(slotFns.base(), props.class)\"\n data-slot=\"date-picker\"\n >\n <!-- DateInput hosts label/helper/field; trigger sits in its endContent slot -->\n <DateInput\n v-model=\"modelValue\"\n :variant=\"variant\"\n :size=\"size\"\n :color=\"color\"\n :label-placement=\"labelPlacement\"\n :full-width=\"fullWidth\"\n :default-value=\"defaultValue\"\n :placeholder-value=\"placeholderValue\"\n :min-value=\"minValue\"\n :max-value=\"maxValue\"\n :granularity=\"granularity\"\n :hour-cycle=\"hourCycle\"\n :locale=\"locale\"\n :label=\"label\"\n :description=\"description\"\n :error-message=\"errorMessage\"\n :is-invalid=\"isInvalid\"\n :is-disabled=\"isDisabled\"\n :is-read-only=\"isReadOnly\"\n :is-required=\"isRequired\"\n :name=\"name\"\n :hide-time-zone=\"hideTimeZone\"\n >\n <template #endContent>\n <DatePickerTrigger\n :class=\"slotFns.trigger()\"\n aria-label=\"Open date picker\"\n @mousedown.prevent\n >\n <slot name=\"selectorIcon\">\n <svg\n :class=\"slotFns.triggerIndicator()\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <rect\n x=\"3\"\n y=\"4\"\n width=\"18\"\n height=\"18\"\n rx=\"2\"\n ry=\"2\"\n />\n <line\n x1=\"16\"\n y1=\"2\"\n x2=\"16\"\n y2=\"6\"\n />\n <line\n x1=\"8\"\n y1=\"2\"\n x2=\"8\"\n y2=\"6\"\n />\n <line\n x1=\"3\"\n y1=\"10\"\n x2=\"21\"\n y2=\"10\"\n />\n </svg>\n </slot>\n </DatePickerTrigger>\n </template>\n </DateInput>\n\n <!-- Popover (portaled + positioned by Reka) -->\n <DatePickerContent\n :class=\"slotFns.popover()\"\n data-slot=\"popover\"\n :side-offset=\"8\"\n >\n <slot name=\"calendarTopContent\" />\n\n <Calendar\n v-model=\"calendarValue\"\n :default-value=\"defaultValue\"\n :default-placeholder=\"placeholderValue ?? defaultValue\"\n :min-value=\"minValue\"\n :max-value=\"maxValue\"\n :is-date-disabled=\"isDateDisabled\"\n :is-date-unavailable=\"isDateUnavailable\"\n :locale=\"locale\"\n :number-of-months=\"visibleMonths\"\n :readonly=\"isReadOnly\"\n :disabled=\"isDisabled\"\n />\n\n <slot name=\"calendarBottomContent\" />\n </DatePickerContent>\n </DatePickerRoot>\n</template>\n"],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import DateTimePicker_vue_vue_type_script_setup_true_lang_default from "./DateTimePicker.vue_vue_type_script_setup_true_lang.js";
2
+ //#region src/components/date-time-picker/DateTimePicker.vue
3
+ var DateTimePicker_default = DateTimePicker_vue_vue_type_script_setup_true_lang_default;
4
+ //#endregion
5
+ export { DateTimePicker_default as default };
6
+
7
+ //# sourceMappingURL=DateTimePicker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DateTimePicker.js","names":[],"sources":["../../../src/components/date-time-picker/DateTimePicker.vue"],"sourcesContent":["<!-- packages/vue/src/components/date-time-picker/DateTimePicker.vue -->\n<script setup lang=\"ts\">\nimport { computed, ref, shallowRef, watch } from 'vue'\nimport {\n DatePickerRoot,\n DatePickerTrigger,\n DatePickerContent,\n} from 'reka-ui'\nimport {\n type DateValue,\n CalendarDateTime,\n toCalendarDate,\n today,\n getLocalTimeZone,\n} from '@internationalized/date'\nimport { AnimatePresence, motion } from 'motion-v'\nimport { dateTimePickerVariants } from '@auronui/styles'\nimport { composeClassName } from '../../utils/composeClassName'\nimport Calendar from '../calendar/Calendar.vue'\nimport DateInput from '../date-input/DateInput.vue'\nimport DateTimePickerTimeScroller from './DateTimePickerTimeScroller.vue'\n\ntype Step = 'date' | 'time'\n\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<{\n variant?: 'flat' | 'bordered' | 'faded' | 'underlined'\n size?: 'sm' | 'md' | 'lg'\n color?: 'default' | 'primary' | 'secondary' | 'success' | 'warning' | 'danger'\n labelPlacement?: 'inside' | 'outside' | 'outside-left'\n fullWidth?: boolean\n label?: string\n description?: string\n errorMessage?: string\n isInvalid?: boolean\n isDisabled?: boolean\n isReadOnly?: boolean\n isRequired?: boolean\n name?: string\n class?: string\n granularity?: 'minute' | 'second'\n hourCycle?: 12 | 24\n hideTimeZone?: boolean\n defaultOpen?: boolean\n closeOnSelect?: boolean\n locale?: string\n defaultValue?: CalendarDateTime\n minValue?: CalendarDateTime\n maxValue?: CalendarDateTime\n isDateUnavailable?: (date: DateValue) => boolean\n isDateDisabled?: (date: DateValue) => boolean\n}>(), {\n size: 'md',\n color: 'default',\n labelPlacement: 'inside',\n fullWidth: false,\n isInvalid: false,\n isDisabled: false,\n isReadOnly: false,\n isRequired: false,\n hideTimeZone: false,\n granularity: 'minute',\n defaultOpen: false,\n closeOnSelect: true,\n})\n\nconst modelValue = defineModel<CalendarDateTime | null | undefined>('modelValue')\nconst openModel = defineModel<boolean>('open', { default: undefined })\n\nconst STEP_TITLES: Record<Step, string> = {\n date: 'Pick a date',\n time: 'Pick a time',\n}\nconst STEP_ORDER: Step[] = ['date', 'time']\n\n// Seed controlled open state from defaultOpen so portal renders in uncontrolled mode too\nif (props.defaultOpen && openModel.value === undefined) {\n openModel.value = true\n}\n\n// Seed controlled value from defaultValue so DateFieldRoot is always in controlled\n// mode from the start. Without this, an uncontrolled→controlled transition\n// happens mid-lifecycle and Reka's DateFieldRoot won't re-render segments.\nif (modelValue.value == null && props.defaultValue != null) {\n modelValue.value = props.defaultValue\n}\n\n// Internal working value — always a CalendarDateTime, never null/undefined.\nconst _today = today(getLocalTimeZone())\nconst internalValue = shallowRef<CalendarDateTime>(\n modelValue.value ?? props.defaultValue ?? new CalendarDateTime(_today.year, _today.month, _today.day, 0, 0),\n)\n\n// Sync inbound: parent resets the value → update internalValue.\n// Guard on CalendarDateTime: ignore CalendarDate emits (no time info).\nwatch(modelValue, (v) => {\n if (v instanceof CalendarDateTime) internalValue.value = v\n})\n\n// Route segment edits from DateInput back to both internalValue and modelValue.\n// DateInput is bound to internalValue (not modelValue) so this is the only place\n// that propagates user-typed changes outward.\nfunction onInputChange(v: DateValue | null | undefined) {\n if (!(v instanceof CalendarDateTime)) return\n internalValue.value = v\n modelValue.value = v\n}\n\n// ─── Step state ──────────────────────────────────────────────────────────\n\nconst activeStep = ref<Step>('date')\nconst direction = ref<1 | -1>(1)\n\nwatch(openModel, (open) => {\n if (open) activeStep.value = 'date'\n})\n\nfunction goTo(step: Step) {\n const from = STEP_ORDER.indexOf(activeStep.value)\n const to = STEP_ORDER.indexOf(step)\n direction.value = to > from ? 1 : -1\n activeStep.value = step\n}\n\nfunction goBack() {\n const idx = STEP_ORDER.indexOf(activeStep.value)\n if (idx > 0) goTo(STEP_ORDER[idx - 1])\n}\n\nfunction goForward() {\n const idx = STEP_ORDER.indexOf(activeStep.value)\n if (idx < STEP_ORDER.length - 1) {\n goTo(STEP_ORDER[idx + 1])\n } else if (props.closeOnSelect) {\n openModel.value = false\n }\n}\n\n// ─── Panel animation variants ────────────────────────────────────────────\n\nconst panelInitial = computed(() => ({ x: direction.value > 0 ? '100%' : '-100%', opacity: 0 }))\nconst panelAnimate = { x: '0%', opacity: 1 }\nconst panelExit = computed(() => ({ x: direction.value > 0 ? '-100%' : '100%', opacity: 0 }))\n\n// ─── Calendar value sync ─────────────────────────────────────────────────\n\nconst calendarValue = computed<DateValue | undefined>({\n // Pass CalendarDate to CalendarRoot — Reka always emits CalendarDate from\n // onDateChange. The setter reconstructs the full CalendarDateTime.\n get: () => toCalendarDate(internalValue.value),\n set: (val) => {\n if (!val) return\n internalValue.value = internalValue.value.set({\n year: val.year,\n month: val.month,\n day: val.day,\n })\n modelValue.value = internalValue.value\n goTo('time')\n },\n})\n\n// ─── Time update ─────────────────────────────────────────────────────────\n\nfunction onTimeUpdate(val: CalendarDateTime) {\n internalValue.value = val\n modelValue.value = val\n}\n\n// ─── Styles ──────────────────────────────────────────────────────────────\n\nconst slotFns = computed(() =>\n dateTimePickerVariants({\n isInvalid: props.isInvalid,\n isDisabled: props.isDisabled,\n fullWidth: props.fullWidth,\n }),\n)\n</script>\n\n<template>\n <DatePickerRoot\n v-model=\"modelValue\"\n v-model:open=\"openModel\"\n :default-value=\"defaultValue\"\n :default-open=\"defaultOpen\"\n :min-value=\"minValue\"\n :max-value=\"maxValue\"\n :is-date-unavailable=\"isDateUnavailable\"\n :is-date-disabled=\"isDateDisabled\"\n :locale=\"locale\"\n :granularity=\"granularity\"\n :hour-cycle=\"hourCycle\"\n :disabled=\"isDisabled\"\n :readonly=\"isReadOnly\"\n :name=\"name\"\n :class=\"composeClassName(slotFns.base(), props.class)\"\n data-slot=\"date-time-picker\"\n >\n <DateInput\n :model-value=\"internalValue\"\n @update:model-value=\"onInputChange\"\n :variant=\"variant\"\n :size=\"size\"\n :color=\"color\"\n :label-placement=\"labelPlacement\"\n :full-width=\"fullWidth\"\n :default-value=\"defaultValue\"\n :granularity=\"granularity\"\n :hour-cycle=\"hourCycle\"\n :locale=\"locale\"\n :label=\"label\"\n :description=\"description\"\n :error-message=\"errorMessage\"\n :is-invalid=\"isInvalid\"\n :is-disabled=\"isDisabled\"\n :is-read-only=\"isReadOnly\"\n :is-required=\"isRequired\"\n :name=\"name\"\n :hide-time-zone=\"hideTimeZone\"\n >\n <template #endContent>\n <DatePickerTrigger\n :class=\"slotFns.trigger()\"\n aria-label=\"Open date time picker\"\n @mousedown.prevent\n >\n <slot name=\"selectorIcon\">\n <svg\n :class=\"slotFns.triggerIndicator()\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <rect x=\"3\" y=\"4\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\" />\n <line x1=\"16\" y1=\"2\" x2=\"16\" y2=\"6\" />\n <line x1=\"8\" y1=\"2\" x2=\"8\" y2=\"6\" />\n <line x1=\"3\" y1=\"10\" x2=\"21\" y2=\"10\" />\n </svg>\n </slot>\n </DatePickerTrigger>\n </template>\n </DateInput>\n\n <DatePickerContent\n :class=\"slotFns.popover()\"\n data-slot=\"popover\"\n :side-offset=\"8\"\n >\n <!-- Step header -->\n <div :class=\"slotFns.stepHeader()\" data-slot=\"step-header\">\n <button\n type=\"button\"\n :class=\"slotFns.navButton()\"\n :data-hidden=\"activeStep === 'date' ? 'true' : undefined\"\n aria-label=\"Previous step\"\n data-slot=\"back-button\"\n @click=\"goBack\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n <polyline points=\"15 18 9 12 15 6\" />\n </svg>\n </button>\n\n <span :class=\"slotFns.stepTitle()\">{{ STEP_TITLES[activeStep] }}</span>\n\n <button\n type=\"button\"\n :class=\"slotFns.navButton()\"\n :aria-label=\"activeStep === 'time' ? 'Done' : 'Next step'\"\n data-slot=\"forward-button\"\n @click=\"goForward\"\n >\n <span v-if=\"activeStep === 'time'\" :class=\"slotFns.doneLabel()\">Done</span>\n <svg v-else width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n <polyline points=\"9 18 15 12 9 6\" />\n </svg>\n </button>\n </div>\n\n <!-- Sliding panels -->\n <div :class=\"slotFns.panelWrap()\" style=\"overflow: hidden;\">\n <AnimatePresence mode=\"popLayout\">\n <motion.div\n v-if=\"activeStep === 'date'\"\n key=\"date\"\n :initial=\"panelInitial\"\n :animate=\"panelAnimate\"\n :exit=\"panelExit\"\n :transition=\"{ duration: 0.15 }\"\n class=\"px-3 pb-3\"\n data-slot=\"calendar-panel\"\n >\n <Calendar\n v-model=\"calendarValue\"\n :default-value=\"defaultValue\"\n :min-value=\"minValue\"\n :max-value=\"maxValue\"\n :is-date-disabled=\"isDateDisabled\"\n :is-date-unavailable=\"isDateUnavailable\"\n :locale=\"locale\"\n :readonly=\"isReadOnly\"\n :disabled=\"isDisabled\"\n />\n </motion.div>\n\n <motion.div\n v-else-if=\"activeStep === 'time'\"\n key=\"time\"\n :initial=\"panelInitial\"\n :animate=\"panelAnimate\"\n :exit=\"panelExit\"\n :transition=\"{ duration: 0.15 }\"\n >\n <DateTimePickerTimeScroller\n :model-value=\"internalValue\"\n :granularity=\"granularity\"\n :hour-cycle=\"hourCycle\"\n @update:model-value=\"onTimeUpdate\"\n />\n </motion.div>\n\n </AnimatePresence>\n </div>\n </DatePickerContent>\n </DatePickerRoot>\n</template>\n"],"mappings":""}