@auronui/vue 1.4.1 → 1.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.cjs +719 -460
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/components/_shared/TimeScroller.js.map +1 -1
- package/dist/components/_shared/TimeScroller.vue_vue_type_script_setup_true_lang.js +11 -7
- package/dist/components/_shared/TimeScroller.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/accordion/Accordion.js.map +1 -1
- package/dist/components/accordion/Accordion.vue_vue_type_script_setup_true_lang.js +17 -6
- package/dist/components/accordion/Accordion.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/autocomplete/Autocomplete.js.map +1 -1
- package/dist/components/autocomplete/Autocomplete.vue_vue_type_script_setup_true_lang.js +23 -3
- package/dist/components/autocomplete/Autocomplete.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/autocomplete/AutocompleteCreateItem.js.map +1 -1
- package/dist/components/autocomplete/AutocompleteCreateItem.vue_vue_type_script_setup_true_lang.js +11 -7
- package/dist/components/autocomplete/AutocompleteCreateItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/autocomplete/AutocompleteInput.js.map +1 -1
- package/dist/components/autocomplete/AutocompleteInput.vue_vue_type_script_setup_true_lang.js +23 -11
- package/dist/components/autocomplete/AutocompleteInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/autocomplete/AutocompleteItem.js.map +1 -1
- package/dist/components/autocomplete/AutocompleteItem.vue_vue_type_script_setup_true_lang.js +25 -17
- package/dist/components/autocomplete/AutocompleteItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/autocomplete/AutocompleteOverflowChips.js.map +1 -1
- package/dist/components/autocomplete/AutocompleteOverflowChips.vue_vue_type_script_setup_true_lang.js +11 -4
- package/dist/components/autocomplete/AutocompleteOverflowChips.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/avatar/Avatar.js.map +1 -1
- package/dist/components/avatar/Avatar.vue_vue_type_script_setup_true_lang.js +11 -13
- package/dist/components/avatar/Avatar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/avatar/AvatarGroup.js.map +1 -1
- package/dist/components/avatar/AvatarGroup.vue_vue_type_script_setup_true_lang.js +12 -8
- package/dist/components/avatar/AvatarGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/breadcrumbs/Breadcrumbs.js.map +1 -1
- package/dist/components/breadcrumbs/Breadcrumbs.vue_vue_type_script_setup_true_lang.js +11 -2
- package/dist/components/breadcrumbs/Breadcrumbs.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/button/ButtonGroup.js.map +1 -1
- package/dist/components/button/ButtonGroup.vue_vue_type_script_setup_true_lang.js +4 -2
- package/dist/components/button/ButtonGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/calendar/Calendar.js.map +1 -1
- package/dist/components/calendar/Calendar.vue_vue_type_script_setup_true_lang.js +3 -1
- package/dist/components/calendar/Calendar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/checkbox/CheckboxGroup.js.map +1 -1
- package/dist/components/checkbox/CheckboxGroup.vue_vue_type_script_setup_true_lang.js +32 -19
- package/dist/components/checkbox/CheckboxGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/collapsible/CollapsibleGroup.js.map +1 -1
- package/dist/components/collapsible/CollapsibleGroup.vue_vue_type_script_setup_true_lang.js +9 -3
- package/dist/components/collapsible/CollapsibleGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/color-field/ColorField.js.map +1 -1
- package/dist/components/color-field/ColorField.vue_vue_type_script_setup_true_lang.js +17 -17
- package/dist/components/color-field/ColorField.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/color-input-group/ColorInputGroup.js.map +1 -1
- package/dist/components/color-input-group/ColorInputGroup.vue_vue_type_script_setup_true_lang.js +16 -18
- package/dist/components/color-input-group/ColorInputGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/combo-box/ComboBox.js.map +1 -1
- package/dist/components/combo-box/ComboBox.vue_vue_type_script_setup_true_lang.js +10 -2
- package/dist/components/combo-box/ComboBox.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/combo-box/ComboBoxInput.js.map +1 -1
- package/dist/components/combo-box/ComboBoxInput.vue_vue_type_script_setup_true_lang.js +9 -4
- package/dist/components/combo-box/ComboBoxInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/combo-box/ComboBoxItem.js.map +1 -1
- package/dist/components/combo-box/ComboBoxItem.vue_vue_type_script_setup_true_lang.js +15 -6
- package/dist/components/combo-box/ComboBoxItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/date-picker/DatePicker.js.map +1 -1
- package/dist/components/date-picker/DatePicker.vue_vue_type_script_setup_true_lang.js +8 -4
- package/dist/components/date-picker/DatePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/date-time-picker/DateTimePicker.js.map +1 -1
- package/dist/components/date-time-picker/DateTimePicker.vue_vue_type_script_setup_true_lang.js +10 -4
- package/dist/components/date-time-picker/DateTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/list-box/ListBox.js.map +1 -1
- package/dist/components/list-box/ListBox.vue_vue_type_script_setup_true_lang.js +14 -4
- package/dist/components/list-box/ListBox.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/modal/ModalContent.js.map +1 -1
- package/dist/components/modal/ModalContent.vue_vue_type_script_setup_true_lang.js +2 -3
- package/dist/components/modal/ModalContent.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/radio/RadioGroup.js.map +1 -1
- package/dist/components/radio/RadioGroup.vue_vue_type_script_setup_true_lang.js +32 -19
- package/dist/components/radio/RadioGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/scroll-area/ScrollArea.js.map +1 -1
- package/dist/components/scroll-area/ScrollArea.vue_vue_type_script_setup_true_lang.js +30 -13
- package/dist/components/scroll-area/ScrollArea.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/select/Select.js.map +1 -1
- package/dist/components/select/Select.vue_vue_type_script_setup_true_lang.js +21 -5
- package/dist/components/select/Select.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/select/SelectItem.js.map +1 -1
- package/dist/components/select/SelectItem.vue_vue_type_script_setup_true_lang.js +11 -6
- package/dist/components/select/SelectItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/select/SelectOverflowChips.js.map +1 -1
- package/dist/components/select/SelectOverflowChips.vue_vue_type_script_setup_true_lang.js +8 -5
- package/dist/components/select/SelectOverflowChips.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/select/SelectTrigger.js.map +1 -1
- package/dist/components/select/SelectTrigger.vue_vue_type_script_setup_true_lang.js +7 -5
- package/dist/components/select/SelectTrigger.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/select/SelectValue.js.map +1 -1
- package/dist/components/select/SelectValue.vue_vue_type_script_setup_true_lang.js +11 -4
- package/dist/components/select/SelectValue.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/separator/Separator.js.map +1 -1
- package/dist/components/separator/Separator.vue_vue_type_script_setup_true_lang.js +9 -8
- package/dist/components/separator/Separator.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/stepper/Stepper.js.map +1 -1
- package/dist/components/stepper/Stepper.vue_vue_type_script_setup_true_lang.js +20 -10
- package/dist/components/stepper/Stepper.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/switch/SwitchGroup.js.map +1 -1
- package/dist/components/switch/SwitchGroup.vue_vue_type_script_setup_true_lang.js +29 -15
- package/dist/components/switch/SwitchGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/table/Table.js.map +1 -1
- package/dist/components/table/Table.vue_vue_type_script_setup_true_lang.js +29 -9
- package/dist/components/table/Table.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tabs/TabList.js.map +1 -1
- package/dist/components/tabs/TabList.vue_vue_type_script_setup_true_lang.js +18 -15
- package/dist/components/tabs/TabList.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tabs/Tabs.js.map +1 -1
- package/dist/components/tabs/Tabs.vue_vue_type_script_setup_true_lang.js +30 -7
- package/dist/components/tabs/Tabs.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/time-picker/TimePicker.js.map +1 -1
- package/dist/components/time-picker/TimePicker.vue_vue_type_script_setup_true_lang.js +6 -2
- package/dist/components/time-picker/TimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/toast/ToastViewport.js.map +1 -1
- package/dist/components/toast/ToastViewport.vue_vue_type_script_setup_true_lang.js +19 -6
- package/dist/components/toast/ToastViewport.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/index.d.ts +363 -0
- package/dist/packages/styles/dist/components/modal/modal.styles.js +2 -1
- package/dist/packages/styles/dist/components/modal/modal.styles.js.map +1 -1
- package/package.json +4 -4
|
@@ -1 +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, 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 { dateTimePickerVariants } from '@auronui/styles'\nimport { composeClassName , type ClassValue} from '../../utils/composeClassName'\nimport Calendar from '../calendar/Calendar.vue'\nimport DateInput from '../date-input/DateInput.vue'\nimport TimeScroller from '../_shared/TimeScroller.vue'\nimport Button from '../button/Button.vue'\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?: ClassValue\n /** Override classes for individual slots */\n classNames?: Partial<{\n base: ClassValue\n trigger: ClassValue\n triggerIndicator: ClassValue\n popover: ClassValue\n panel: ClassValue\n divider: ClassValue\n }>\n granularity?: 'minute' | 'second'\n hourCycle?: 12 | 24\n hideTimeZone?: boolean\n defaultOpen?: boolean\n closeOnSelect?: boolean\n /** Label for the footer button that closes the picker. */\n doneLabel?: string\n locale?: string\n defaultValue?: CalendarDateTime\n /** Initial placeholder date for the calendar. */\n defaultPlaceholder?: DateValue\n /** Controlled placeholder date. */\n placeholder?: DateValue\n minValue?: CalendarDateTime\n maxValue?: CalendarDateTime\n isDateUnavailable?: (date: DateValue) => boolean\n isDateDisabled?: (date: DateValue) => boolean\n /** Steps for segment keyboard navigation. */\n step?: Partial<Record<'hour' | 'minute' | 'second' | 'millisecond', number>>\n /** Text direction. */\n dir?: 'ltr' | 'rtl'\n /** HTML id attribute forwarded to the root element. */\n id?: string\n /** Whether the calendar popover is modal (traps focus). */\n modal?: boolean\n /** Marks the field as required. */\n required?: boolean\n /** Use paged navigation in the calendar. */\n pagedNavigation?: boolean\n /** Day the week starts on. */\n weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6\n /** Format for weekday header cells. */\n weekdayFormat?: 'narrow' | 'short' | 'long'\n /** Always show 6 weeks per month. */\n fixedWeeks?: boolean\n /** Number of months shown in the calendar. */\n numberOfMonths?: number\n /** Prevent deselecting a selected date. */\n preventDeselect?: boolean\n /** Render trigger as a different element. */\n triggerAs?: string\n /** Render trigger child as root element. */\n triggerAsChild?: boolean\n /** Portal target for the content. */\n portal?: string | HTMLElement\n /** Force the content to stay mounted. */\n forceMount?: boolean\n /** Side of the anchor the content appears on. */\n side?: 'top' | 'right' | 'bottom' | 'left'\n /** Distance in px from the anchor. */\n sideOffset?: number\n /** Allow flipping to opposite side. */\n sideFlip?: boolean\n /** Alignment of the content relative to the anchor. */\n align?: 'start' | 'center' | 'end'\n /** Offset along the align axis. */\n alignOffset?: number\n /** Allow flipping alignment. */\n alignFlip?: boolean\n /** Avoid collisions with the viewport. */\n avoidCollisions?: boolean\n /** Elements to use as collision boundaries. */\n collisionBoundary?: Element | null | Array<Element | null>\n /** Padding for collision detection. */\n collisionPadding?: number | Partial<Record<'top' | 'right' | 'bottom' | 'left', number>>\n /** Padding between arrow and content edge. */\n arrowPadding?: number\n /** Hide the arrow when it is shifted. */\n hideShiftedArrow?: boolean\n /** Sticky behavior when overflowing. */\n sticky?: 'partial' | 'always'\n /** Hide content when anchor is detached. */\n hideWhenDetached?: boolean\n /** CSS position strategy. */\n positionStrategy?: 'fixed' | 'absolute'\n /** When to recalculate position. */\n updatePositionStrategy?: 'always' | 'optimized'\n /** Disable position update on layout shift. */\n disableUpdateOnLayoutShift?: boolean\n /** Prioritize keeping content in viewport. */\n prioritizePosition?: boolean\n /** Virtual reference element for positioning. */\n reference?: object | null\n /** Render content as a different element. */\n contentAs?: string\n /** Render content child as root element. */\n contentAsChild?: boolean\n /** Disable pointer events outside the content. */\n disableOutsidePointerEvents?: 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 doneLabel: 'Done',\n avoidCollisions: true,\n collisionPadding: 8,\n prioritizePosition: true,\n})\n\nconst emit = defineEmits<{\n 'update:placeholder': [value: DateValue | undefined]\n 'escape-key-down': [event: KeyboardEvent]\n 'pointer-down-outside': [event: Event]\n 'focus-outside': [event: Event]\n 'interact-outside': [event: Event]\n 'open-auto-focus': [event: Event]\n 'close-auto-focus': [event: Event]\n}>()\n\nconst modelValue = defineModel<CalendarDateTime | null | undefined>('modelValue')\nconst openModel = defineModel<boolean>('open', { default: undefined })\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// ─── 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 },\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 :default-placeholder=\"defaultPlaceholder\"\n :placeholder=\"placeholder\"\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 :step=\"step\"\n :disabled=\"isDisabled\"\n :readonly=\"isReadOnly\"\n :name=\"name\"\n :dir=\"dir\"\n :id=\"id\"\n :required=\"required\"\n :modal=\"modal\"\n :paged-navigation=\"pagedNavigation\"\n :week-starts-on=\"weekStartsOn\"\n :weekday-format=\"weekdayFormat\"\n :fixed-weeks=\"fixedWeeks\"\n :number-of-months=\"numberOfMonths\"\n :prevent-deselect=\"preventDeselect\"\n :class=\"composeClassName(slotFns.base(), props.class, props.classNames?.base)\"\n data-slot=\"date-time-picker\"\n >\n <DateInput\n :model-value=\"internalValue\"\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 @update:model-value=\"onInputChange\"\n >\n <template #endContent>\n <DatePickerTrigger\n :class=\"composeClassName(slotFns.trigger(), props.classNames?.trigger)\"\n :as=\"triggerAs\"\n :as-child=\"triggerAsChild\"\n aria-label=\"Open date time picker\"\n @mousedown.prevent\n >\n <slot name=\"selectorIcon\">\n <svg\n :class=\"composeClassName(slotFns.triggerIndicator(), props.classNames?.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 <DatePickerContent\n :class=\"composeClassName(slotFns.popover(), props.classNames?.popover)\"\n data-slot=\"popover\"\n :side-offset=\"sideOffset ?? 8\"\n :portal=\"portal != null ? { to: portal } : undefined\"\n :force-mount=\"forceMount\"\n :side=\"side\"\n :side-flip=\"sideFlip\"\n :align=\"align\"\n :align-offset=\"alignOffset\"\n :align-flip=\"alignFlip\"\n :avoid-collisions=\"avoidCollisions\"\n :collision-boundary=\"collisionBoundary\"\n :collision-padding=\"collisionPadding\"\n :arrow-padding=\"arrowPadding\"\n :hide-shifted-arrow=\"hideShiftedArrow\"\n :sticky=\"sticky\"\n :hide-when-detached=\"hideWhenDetached\"\n :position-strategy=\"positionStrategy\"\n :update-position-strategy=\"updatePositionStrategy\"\n :disable-update-on-layout-shift=\"disableUpdateOnLayoutShift\"\n :prioritize-position=\"prioritizePosition\"\n :reference=\"(reference as any)\"\n :as=\"contentAs\"\n :as-child=\"contentAsChild\"\n :disable-outside-pointer-events=\"disableOutsidePointerEvents\"\n @escape-key-down=\"emit('escape-key-down', $event)\"\n @pointer-down-outside=\"emit('pointer-down-outside', $event)\"\n @focus-outside=\"emit('focus-outside', $event)\"\n @interact-outside=\"emit('interact-outside', $event)\"\n @open-auto-focus=\"emit('open-auto-focus', $event)\"\n @close-auto-focus=\"emit('close-auto-focus', $event)\"\n >\n <div\n :class=\"composeClassName(slotFns.panel(), props.classNames?.panel)\"\n data-slot=\"panel\"\n >\n <!-- Wrapper keeps Calendar's multiple view roots (date grid, month\n picker, year picker) as ONE flex child. Without it, the panel's\n flex layout spreads those sibling roots into separate columns and\n the inactive (empty) root shows as a blank box. -->\n <div\n :class=\"slotFns.calendarPane()\"\n data-slot=\"calendar-pane\"\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 </div>\n\n <div\n :class=\"composeClassName(slotFns.divider(), props.classNames?.divider)\"\n data-slot=\"divider\"\n aria-hidden=\"true\"\n />\n\n <!-- Time column: wheels on top, Done button pinned to the bottom so it\n lines up with the calendar's bottom edge. Selection is already live,\n so Done just closes the popover for users who miss click-outside. -->\n <div\n :class=\"slotFns.timePane()\"\n data-slot=\"time-pane\"\n >\n <TimeScroller\n :model-value=\"internalValue\"\n :granularity=\"granularity\"\n :hour-cycle=\"hourCycle\"\n @update:model-value=\"(val) => onTimeUpdate(val as CalendarDateTime)\"\n />\n\n <div\n :class=\"slotFns.timeDone()\"\n data-slot=\"time-done\"\n >\n <slot name=\"footer\" :close=\"() => { openModel = false }\">\n <Button\n size=\"sm\"\n color=\"primary\"\n data-slot=\"done-button\"\n @click=\"openModel = false\"\n >\n {{ doneLabel }}\n </Button>\n </slot>\n </div>\n </div>\n </div>\n </DatePickerContent>\n </DatePickerRoot>\n</template>\n"],"mappings":""}
|
|
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, 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 { dateTimePickerVariants } from '@auronui/styles'\nimport { composeClassName , type ClassValue} from '../../utils/composeClassName'\nimport Calendar from '../calendar/Calendar.vue'\nimport DateInput from '../date-input/DateInput.vue'\nimport TimeScroller from '../_shared/TimeScroller.vue'\nimport Button from '../button/Button.vue'\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?: ClassValue\n /** Override classes for individual slots */\n classNames?: Partial<{\n base: ClassValue\n trigger: ClassValue\n triggerIndicator: ClassValue\n popover: ClassValue\n panel: ClassValue\n divider: ClassValue\n calendar: Partial<{\n base: ClassValue\n header: ClassValue\n navButton: ClassValue\n navButtonIcon: ClassValue\n heading: ClassValue\n headingButton: ClassValue\n grid: ClassValue\n gridHeader: ClassValue\n gridRow: ClassValue\n headerCell: ClassValue\n gridBody: ClassValue\n cell: ClassValue\n cellButton: ClassValue\n monthGrid: ClassValue\n monthGridBody: ClassValue\n monthGridRow: ClassValue\n monthCell: ClassValue\n yearView: Partial<{\n header: ClassValue\n navButton: ClassValue\n navButtonIcon: ClassValue\n heading: ClassValue\n yearGrid: ClassValue\n yearGridBody: ClassValue\n yearGridRow: ClassValue\n yearCell: ClassValue\n }>\n }>\n dateInput: Partial<{\n label: ClassValue\n mainWrapper: ClassValue\n inputWrapper: ClassValue\n startContent: ClassValue\n segmentList: ClassValue\n segment: ClassValue\n endContent: ClassValue\n helperWrapper: ClassValue\n errorMessage: ClassValue\n description: ClassValue\n }>\n timeScroller: Partial<{\n scrollerWrap: ClassValue\n scrollerColumn: ClassValue\n scrollerItem: ClassValue\n }>\n }>\n granularity?: 'minute' | 'second'\n hourCycle?: 12 | 24\n hideTimeZone?: boolean\n defaultOpen?: boolean\n closeOnSelect?: boolean\n /** Label for the footer button that closes the picker. */\n doneLabel?: string\n locale?: string\n defaultValue?: CalendarDateTime\n /** Initial placeholder date for the calendar. */\n defaultPlaceholder?: DateValue\n /** Controlled placeholder date. */\n placeholder?: DateValue\n minValue?: CalendarDateTime\n maxValue?: CalendarDateTime\n isDateUnavailable?: (date: DateValue) => boolean\n isDateDisabled?: (date: DateValue) => boolean\n /** Steps for segment keyboard navigation. */\n step?: Partial<Record<'hour' | 'minute' | 'second' | 'millisecond', number>>\n /** Text direction. */\n dir?: 'ltr' | 'rtl'\n /** HTML id attribute forwarded to the root element. */\n id?: string\n /** Whether the calendar popover is modal (traps focus). */\n modal?: boolean\n /** Marks the field as required. */\n required?: boolean\n /** Use paged navigation in the calendar. */\n pagedNavigation?: boolean\n /** Day the week starts on. */\n weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6\n /** Format for weekday header cells. */\n weekdayFormat?: 'narrow' | 'short' | 'long'\n /** Always show 6 weeks per month. */\n fixedWeeks?: boolean\n /** Number of months shown in the calendar. */\n numberOfMonths?: number\n /** Prevent deselecting a selected date. */\n preventDeselect?: boolean\n /** Render trigger as a different element. */\n triggerAs?: string\n /** Render trigger child as root element. */\n triggerAsChild?: boolean\n /** Portal target for the content. */\n portal?: string | HTMLElement\n /** Force the content to stay mounted. */\n forceMount?: boolean\n /** Side of the anchor the content appears on. */\n side?: 'top' | 'right' | 'bottom' | 'left'\n /** Distance in px from the anchor. */\n sideOffset?: number\n /** Allow flipping to opposite side. */\n sideFlip?: boolean\n /** Alignment of the content relative to the anchor. */\n align?: 'start' | 'center' | 'end'\n /** Offset along the align axis. */\n alignOffset?: number\n /** Allow flipping alignment. */\n alignFlip?: boolean\n /** Avoid collisions with the viewport. */\n avoidCollisions?: boolean\n /** Elements to use as collision boundaries. */\n collisionBoundary?: Element | null | Array<Element | null>\n /** Padding for collision detection. */\n collisionPadding?: number | Partial<Record<'top' | 'right' | 'bottom' | 'left', number>>\n /** Padding between arrow and content edge. */\n arrowPadding?: number\n /** Hide the arrow when it is shifted. */\n hideShiftedArrow?: boolean\n /** Sticky behavior when overflowing. */\n sticky?: 'partial' | 'always'\n /** Hide content when anchor is detached. */\n hideWhenDetached?: boolean\n /** CSS position strategy. */\n positionStrategy?: 'fixed' | 'absolute'\n /** When to recalculate position. */\n updatePositionStrategy?: 'always' | 'optimized'\n /** Disable position update on layout shift. */\n disableUpdateOnLayoutShift?: boolean\n /** Prioritize keeping content in viewport. */\n prioritizePosition?: boolean\n /** Virtual reference element for positioning. */\n reference?: object | null\n /** Render content as a different element. */\n contentAs?: string\n /** Render content child as root element. */\n contentAsChild?: boolean\n /** Disable pointer events outside the content. */\n disableOutsidePointerEvents?: 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 doneLabel: 'Done',\n avoidCollisions: true,\n collisionPadding: 8,\n prioritizePosition: true,\n})\n\nconst emit = defineEmits<{\n 'update:placeholder': [value: DateValue | undefined]\n 'escape-key-down': [event: KeyboardEvent]\n 'pointer-down-outside': [event: Event]\n 'focus-outside': [event: Event]\n 'interact-outside': [event: Event]\n 'open-auto-focus': [event: Event]\n 'close-auto-focus': [event: Event]\n}>()\n\nconst modelValue = defineModel<CalendarDateTime | null | undefined>('modelValue')\nconst openModel = defineModel<boolean>('open', { default: undefined })\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// ─── 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 },\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 :default-placeholder=\"defaultPlaceholder\"\n :placeholder=\"placeholder\"\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 :step=\"step\"\n :disabled=\"isDisabled\"\n :readonly=\"isReadOnly\"\n :name=\"name\"\n :dir=\"dir\"\n :id=\"id\"\n :required=\"required\"\n :modal=\"modal\"\n :paged-navigation=\"pagedNavigation\"\n :week-starts-on=\"weekStartsOn\"\n :weekday-format=\"weekdayFormat\"\n :fixed-weeks=\"fixedWeeks\"\n :number-of-months=\"numberOfMonths\"\n :prevent-deselect=\"preventDeselect\"\n :class=\"composeClassName(slotFns.base(), props.class, props.classNames?.base)\"\n data-slot=\"date-time-picker\"\n >\n <DateInput\n :model-value=\"internalValue\"\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 :class-names=\"props.classNames?.dateInput\"\n @update:model-value=\"onInputChange\"\n >\n <template #endContent>\n <DatePickerTrigger\n :class=\"composeClassName(slotFns.trigger(), props.classNames?.trigger)\"\n :as=\"triggerAs\"\n :as-child=\"triggerAsChild\"\n aria-label=\"Open date time picker\"\n @mousedown.prevent\n >\n <slot name=\"selectorIcon\">\n <svg\n :class=\"composeClassName(slotFns.triggerIndicator(), props.classNames?.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 <DatePickerContent\n :class=\"composeClassName(slotFns.popover(), props.classNames?.popover)\"\n data-slot=\"popover\"\n :side-offset=\"sideOffset ?? 8\"\n :portal=\"portal != null ? { to: portal } : undefined\"\n :force-mount=\"forceMount\"\n :side=\"side\"\n :side-flip=\"sideFlip\"\n :align=\"align\"\n :align-offset=\"alignOffset\"\n :align-flip=\"alignFlip\"\n :avoid-collisions=\"avoidCollisions\"\n :collision-boundary=\"collisionBoundary\"\n :collision-padding=\"collisionPadding\"\n :arrow-padding=\"arrowPadding\"\n :hide-shifted-arrow=\"hideShiftedArrow\"\n :sticky=\"sticky\"\n :hide-when-detached=\"hideWhenDetached\"\n :position-strategy=\"positionStrategy\"\n :update-position-strategy=\"updatePositionStrategy\"\n :disable-update-on-layout-shift=\"disableUpdateOnLayoutShift\"\n :prioritize-position=\"prioritizePosition\"\n :reference=\"(reference as any)\"\n :as=\"contentAs\"\n :as-child=\"contentAsChild\"\n :disable-outside-pointer-events=\"disableOutsidePointerEvents\"\n @escape-key-down=\"emit('escape-key-down', $event)\"\n @pointer-down-outside=\"emit('pointer-down-outside', $event)\"\n @focus-outside=\"emit('focus-outside', $event)\"\n @interact-outside=\"emit('interact-outside', $event)\"\n @open-auto-focus=\"emit('open-auto-focus', $event)\"\n @close-auto-focus=\"emit('close-auto-focus', $event)\"\n >\n <div\n :class=\"composeClassName(slotFns.panel(), props.classNames?.panel)\"\n data-slot=\"panel\"\n >\n <!-- Wrapper keeps Calendar's multiple view roots (date grid, month\n picker, year picker) as ONE flex child. Without it, the panel's\n flex layout spreads those sibling roots into separate columns and\n the inactive (empty) root shows as a blank box. -->\n <div\n :class=\"slotFns.calendarPane()\"\n data-slot=\"calendar-pane\"\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 :class-names=\"props.classNames?.calendar\"\n />\n </div>\n\n <div\n :class=\"composeClassName(slotFns.divider(), props.classNames?.divider)\"\n data-slot=\"divider\"\n aria-hidden=\"true\"\n />\n\n <!-- Time column: wheels on top, Done button pinned to the bottom so it\n lines up with the calendar's bottom edge. Selection is already live,\n so Done just closes the popover for users who miss click-outside. -->\n <div\n :class=\"slotFns.timePane()\"\n data-slot=\"time-pane\"\n >\n <TimeScroller\n :model-value=\"internalValue\"\n :granularity=\"granularity\"\n :hour-cycle=\"hourCycle\"\n :class-names=\"props.classNames?.timeScroller\"\n @update:model-value=\"(val) => onTimeUpdate(val as CalendarDateTime)\"\n />\n\n <div\n :class=\"slotFns.timeDone()\"\n data-slot=\"time-done\"\n >\n <slot name=\"footer\" :close=\"() => { openModel = false }\">\n <Button\n size=\"sm\"\n color=\"primary\"\n data-slot=\"done-button\"\n @click=\"openModel = false\"\n >\n {{ doneLabel }}\n </Button>\n </slot>\n </div>\n </div>\n </div>\n </DatePickerContent>\n </DatePickerRoot>\n</template>\n"],"mappings":""}
|
package/dist/components/date-time-picker/DateTimePicker.vue_vue_type_script_setup_true_lang.js
CHANGED
|
@@ -223,6 +223,7 @@ var DateTimePicker_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
|
|
|
223
223
|
"is-required": __props.isRequired,
|
|
224
224
|
name: __props.name,
|
|
225
225
|
"hide-time-zone": __props.hideTimeZone,
|
|
226
|
+
"class-names": props.classNames?.dateInput,
|
|
226
227
|
"onUpdate:modelValue": onInputChange
|
|
227
228
|
}, {
|
|
228
229
|
endContent: withCtx(() => [createVNode(unref(DatePickerTrigger), {
|
|
@@ -299,7 +300,8 @@ var DateTimePicker_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
|
|
|
299
300
|
"is-read-only",
|
|
300
301
|
"is-required",
|
|
301
302
|
"name",
|
|
302
|
-
"hide-time-zone"
|
|
303
|
+
"hide-time-zone",
|
|
304
|
+
"class-names"
|
|
303
305
|
]), createVNode(unref(DatePickerContent), {
|
|
304
306
|
class: normalizeClass(unref(composeClassName)(slotFns.value.popover(), props.classNames?.popover)),
|
|
305
307
|
"data-slot": "popover",
|
|
@@ -350,7 +352,8 @@ var DateTimePicker_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
|
|
|
350
352
|
"is-date-unavailable": __props.isDateUnavailable,
|
|
351
353
|
locale: __props.locale,
|
|
352
354
|
readonly: __props.isReadOnly,
|
|
353
|
-
disabled: __props.isDisabled
|
|
355
|
+
disabled: __props.isDisabled,
|
|
356
|
+
"class-names": props.classNames?.calendar
|
|
354
357
|
}, null, 8, [
|
|
355
358
|
"modelValue",
|
|
356
359
|
"default-value",
|
|
@@ -360,7 +363,8 @@ var DateTimePicker_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
|
|
|
360
363
|
"is-date-unavailable",
|
|
361
364
|
"locale",
|
|
362
365
|
"readonly",
|
|
363
|
-
"disabled"
|
|
366
|
+
"disabled",
|
|
367
|
+
"class-names"
|
|
364
368
|
])], 2),
|
|
365
369
|
createElementVNode("div", {
|
|
366
370
|
class: normalizeClass(unref(composeClassName)(slotFns.value.divider(), props.classNames?.divider)),
|
|
@@ -374,11 +378,13 @@ var DateTimePicker_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
|
|
|
374
378
|
"model-value": internalValue.value,
|
|
375
379
|
granularity: __props.granularity,
|
|
376
380
|
"hour-cycle": __props.hourCycle,
|
|
381
|
+
"class-names": props.classNames?.timeScroller,
|
|
377
382
|
"onUpdate:modelValue": _cache[2] || (_cache[2] = (val) => onTimeUpdate(val))
|
|
378
383
|
}, null, 8, [
|
|
379
384
|
"model-value",
|
|
380
385
|
"granularity",
|
|
381
|
-
"hour-cycle"
|
|
386
|
+
"hour-cycle",
|
|
387
|
+
"class-names"
|
|
382
388
|
]), createElementVNode("div", {
|
|
383
389
|
class: normalizeClass(slotFns.value.timeDone()),
|
|
384
390
|
"data-slot": "time-done"
|
package/dist/components/date-time-picker/DateTimePicker.vue_vue_type_script_setup_true_lang.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DateTimePicker.vue_vue_type_script_setup_true_lang.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, 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 { dateTimePickerVariants } from '@auronui/styles'\nimport { composeClassName , type ClassValue} from '../../utils/composeClassName'\nimport Calendar from '../calendar/Calendar.vue'\nimport DateInput from '../date-input/DateInput.vue'\nimport TimeScroller from '../_shared/TimeScroller.vue'\nimport Button from '../button/Button.vue'\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?: ClassValue\n /** Override classes for individual slots */\n classNames?: Partial<{\n base: ClassValue\n trigger: ClassValue\n triggerIndicator: ClassValue\n popover: ClassValue\n panel: ClassValue\n divider: ClassValue\n }>\n granularity?: 'minute' | 'second'\n hourCycle?: 12 | 24\n hideTimeZone?: boolean\n defaultOpen?: boolean\n closeOnSelect?: boolean\n /** Label for the footer button that closes the picker. */\n doneLabel?: string\n locale?: string\n defaultValue?: CalendarDateTime\n /** Initial placeholder date for the calendar. */\n defaultPlaceholder?: DateValue\n /** Controlled placeholder date. */\n placeholder?: DateValue\n minValue?: CalendarDateTime\n maxValue?: CalendarDateTime\n isDateUnavailable?: (date: DateValue) => boolean\n isDateDisabled?: (date: DateValue) => boolean\n /** Steps for segment keyboard navigation. */\n step?: Partial<Record<'hour' | 'minute' | 'second' | 'millisecond', number>>\n /** Text direction. */\n dir?: 'ltr' | 'rtl'\n /** HTML id attribute forwarded to the root element. */\n id?: string\n /** Whether the calendar popover is modal (traps focus). */\n modal?: boolean\n /** Marks the field as required. */\n required?: boolean\n /** Use paged navigation in the calendar. */\n pagedNavigation?: boolean\n /** Day the week starts on. */\n weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6\n /** Format for weekday header cells. */\n weekdayFormat?: 'narrow' | 'short' | 'long'\n /** Always show 6 weeks per month. */\n fixedWeeks?: boolean\n /** Number of months shown in the calendar. */\n numberOfMonths?: number\n /** Prevent deselecting a selected date. */\n preventDeselect?: boolean\n /** Render trigger as a different element. */\n triggerAs?: string\n /** Render trigger child as root element. */\n triggerAsChild?: boolean\n /** Portal target for the content. */\n portal?: string | HTMLElement\n /** Force the content to stay mounted. */\n forceMount?: boolean\n /** Side of the anchor the content appears on. */\n side?: 'top' | 'right' | 'bottom' | 'left'\n /** Distance in px from the anchor. */\n sideOffset?: number\n /** Allow flipping to opposite side. */\n sideFlip?: boolean\n /** Alignment of the content relative to the anchor. */\n align?: 'start' | 'center' | 'end'\n /** Offset along the align axis. */\n alignOffset?: number\n /** Allow flipping alignment. */\n alignFlip?: boolean\n /** Avoid collisions with the viewport. */\n avoidCollisions?: boolean\n /** Elements to use as collision boundaries. */\n collisionBoundary?: Element | null | Array<Element | null>\n /** Padding for collision detection. */\n collisionPadding?: number | Partial<Record<'top' | 'right' | 'bottom' | 'left', number>>\n /** Padding between arrow and content edge. */\n arrowPadding?: number\n /** Hide the arrow when it is shifted. */\n hideShiftedArrow?: boolean\n /** Sticky behavior when overflowing. */\n sticky?: 'partial' | 'always'\n /** Hide content when anchor is detached. */\n hideWhenDetached?: boolean\n /** CSS position strategy. */\n positionStrategy?: 'fixed' | 'absolute'\n /** When to recalculate position. */\n updatePositionStrategy?: 'always' | 'optimized'\n /** Disable position update on layout shift. */\n disableUpdateOnLayoutShift?: boolean\n /** Prioritize keeping content in viewport. */\n prioritizePosition?: boolean\n /** Virtual reference element for positioning. */\n reference?: object | null\n /** Render content as a different element. */\n contentAs?: string\n /** Render content child as root element. */\n contentAsChild?: boolean\n /** Disable pointer events outside the content. */\n disableOutsidePointerEvents?: 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 doneLabel: 'Done',\n avoidCollisions: true,\n collisionPadding: 8,\n prioritizePosition: true,\n})\n\nconst emit = defineEmits<{\n 'update:placeholder': [value: DateValue | undefined]\n 'escape-key-down': [event: KeyboardEvent]\n 'pointer-down-outside': [event: Event]\n 'focus-outside': [event: Event]\n 'interact-outside': [event: Event]\n 'open-auto-focus': [event: Event]\n 'close-auto-focus': [event: Event]\n}>()\n\nconst modelValue = defineModel<CalendarDateTime | null | undefined>('modelValue')\nconst openModel = defineModel<boolean>('open', { default: undefined })\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// ─── 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 },\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 :default-placeholder=\"defaultPlaceholder\"\n :placeholder=\"placeholder\"\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 :step=\"step\"\n :disabled=\"isDisabled\"\n :readonly=\"isReadOnly\"\n :name=\"name\"\n :dir=\"dir\"\n :id=\"id\"\n :required=\"required\"\n :modal=\"modal\"\n :paged-navigation=\"pagedNavigation\"\n :week-starts-on=\"weekStartsOn\"\n :weekday-format=\"weekdayFormat\"\n :fixed-weeks=\"fixedWeeks\"\n :number-of-months=\"numberOfMonths\"\n :prevent-deselect=\"preventDeselect\"\n :class=\"composeClassName(slotFns.base(), props.class, props.classNames?.base)\"\n data-slot=\"date-time-picker\"\n >\n <DateInput\n :model-value=\"internalValue\"\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 @update:model-value=\"onInputChange\"\n >\n <template #endContent>\n <DatePickerTrigger\n :class=\"composeClassName(slotFns.trigger(), props.classNames?.trigger)\"\n :as=\"triggerAs\"\n :as-child=\"triggerAsChild\"\n aria-label=\"Open date time picker\"\n @mousedown.prevent\n >\n <slot name=\"selectorIcon\">\n <svg\n :class=\"composeClassName(slotFns.triggerIndicator(), props.classNames?.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 <DatePickerContent\n :class=\"composeClassName(slotFns.popover(), props.classNames?.popover)\"\n data-slot=\"popover\"\n :side-offset=\"sideOffset ?? 8\"\n :portal=\"portal != null ? { to: portal } : undefined\"\n :force-mount=\"forceMount\"\n :side=\"side\"\n :side-flip=\"sideFlip\"\n :align=\"align\"\n :align-offset=\"alignOffset\"\n :align-flip=\"alignFlip\"\n :avoid-collisions=\"avoidCollisions\"\n :collision-boundary=\"collisionBoundary\"\n :collision-padding=\"collisionPadding\"\n :arrow-padding=\"arrowPadding\"\n :hide-shifted-arrow=\"hideShiftedArrow\"\n :sticky=\"sticky\"\n :hide-when-detached=\"hideWhenDetached\"\n :position-strategy=\"positionStrategy\"\n :update-position-strategy=\"updatePositionStrategy\"\n :disable-update-on-layout-shift=\"disableUpdateOnLayoutShift\"\n :prioritize-position=\"prioritizePosition\"\n :reference=\"(reference as any)\"\n :as=\"contentAs\"\n :as-child=\"contentAsChild\"\n :disable-outside-pointer-events=\"disableOutsidePointerEvents\"\n @escape-key-down=\"emit('escape-key-down', $event)\"\n @pointer-down-outside=\"emit('pointer-down-outside', $event)\"\n @focus-outside=\"emit('focus-outside', $event)\"\n @interact-outside=\"emit('interact-outside', $event)\"\n @open-auto-focus=\"emit('open-auto-focus', $event)\"\n @close-auto-focus=\"emit('close-auto-focus', $event)\"\n >\n <div\n :class=\"composeClassName(slotFns.panel(), props.classNames?.panel)\"\n data-slot=\"panel\"\n >\n <!-- Wrapper keeps Calendar's multiple view roots (date grid, month\n picker, year picker) as ONE flex child. Without it, the panel's\n flex layout spreads those sibling roots into separate columns and\n the inactive (empty) root shows as a blank box. -->\n <div\n :class=\"slotFns.calendarPane()\"\n data-slot=\"calendar-pane\"\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 </div>\n\n <div\n :class=\"composeClassName(slotFns.divider(), props.classNames?.divider)\"\n data-slot=\"divider\"\n aria-hidden=\"true\"\n />\n\n <!-- Time column: wheels on top, Done button pinned to the bottom so it\n lines up with the calendar's bottom edge. Selection is already live,\n so Done just closes the popover for users who miss click-outside. -->\n <div\n :class=\"slotFns.timePane()\"\n data-slot=\"time-pane\"\n >\n <TimeScroller\n :model-value=\"internalValue\"\n :granularity=\"granularity\"\n :hour-cycle=\"hourCycle\"\n @update:model-value=\"(val) => onTimeUpdate(val as CalendarDateTime)\"\n />\n\n <div\n :class=\"slotFns.timeDone()\"\n data-slot=\"time-done\"\n >\n <slot name=\"footer\" :close=\"() => { openModel = false }\">\n <Button\n size=\"sm\"\n color=\"primary\"\n data-slot=\"done-button\"\n @click=\"openModel = false\"\n >\n {{ doneLabel }}\n </Button>\n </slot>\n </div>\n </div>\n </div>\n </DatePickerContent>\n </DatePickerRoot>\n</template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DateTimePicker.vue_vue_type_script_setup_true_lang.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, 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 { dateTimePickerVariants } from '@auronui/styles'\nimport { composeClassName , type ClassValue} from '../../utils/composeClassName'\nimport Calendar from '../calendar/Calendar.vue'\nimport DateInput from '../date-input/DateInput.vue'\nimport TimeScroller from '../_shared/TimeScroller.vue'\nimport Button from '../button/Button.vue'\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?: ClassValue\n /** Override classes for individual slots */\n classNames?: Partial<{\n base: ClassValue\n trigger: ClassValue\n triggerIndicator: ClassValue\n popover: ClassValue\n panel: ClassValue\n divider: ClassValue\n calendar: Partial<{\n base: ClassValue\n header: ClassValue\n navButton: ClassValue\n navButtonIcon: ClassValue\n heading: ClassValue\n headingButton: ClassValue\n grid: ClassValue\n gridHeader: ClassValue\n gridRow: ClassValue\n headerCell: ClassValue\n gridBody: ClassValue\n cell: ClassValue\n cellButton: ClassValue\n monthGrid: ClassValue\n monthGridBody: ClassValue\n monthGridRow: ClassValue\n monthCell: ClassValue\n yearView: Partial<{\n header: ClassValue\n navButton: ClassValue\n navButtonIcon: ClassValue\n heading: ClassValue\n yearGrid: ClassValue\n yearGridBody: ClassValue\n yearGridRow: ClassValue\n yearCell: ClassValue\n }>\n }>\n dateInput: Partial<{\n label: ClassValue\n mainWrapper: ClassValue\n inputWrapper: ClassValue\n startContent: ClassValue\n segmentList: ClassValue\n segment: ClassValue\n endContent: ClassValue\n helperWrapper: ClassValue\n errorMessage: ClassValue\n description: ClassValue\n }>\n timeScroller: Partial<{\n scrollerWrap: ClassValue\n scrollerColumn: ClassValue\n scrollerItem: ClassValue\n }>\n }>\n granularity?: 'minute' | 'second'\n hourCycle?: 12 | 24\n hideTimeZone?: boolean\n defaultOpen?: boolean\n closeOnSelect?: boolean\n /** Label for the footer button that closes the picker. */\n doneLabel?: string\n locale?: string\n defaultValue?: CalendarDateTime\n /** Initial placeholder date for the calendar. */\n defaultPlaceholder?: DateValue\n /** Controlled placeholder date. */\n placeholder?: DateValue\n minValue?: CalendarDateTime\n maxValue?: CalendarDateTime\n isDateUnavailable?: (date: DateValue) => boolean\n isDateDisabled?: (date: DateValue) => boolean\n /** Steps for segment keyboard navigation. */\n step?: Partial<Record<'hour' | 'minute' | 'second' | 'millisecond', number>>\n /** Text direction. */\n dir?: 'ltr' | 'rtl'\n /** HTML id attribute forwarded to the root element. */\n id?: string\n /** Whether the calendar popover is modal (traps focus). */\n modal?: boolean\n /** Marks the field as required. */\n required?: boolean\n /** Use paged navigation in the calendar. */\n pagedNavigation?: boolean\n /** Day the week starts on. */\n weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6\n /** Format for weekday header cells. */\n weekdayFormat?: 'narrow' | 'short' | 'long'\n /** Always show 6 weeks per month. */\n fixedWeeks?: boolean\n /** Number of months shown in the calendar. */\n numberOfMonths?: number\n /** Prevent deselecting a selected date. */\n preventDeselect?: boolean\n /** Render trigger as a different element. */\n triggerAs?: string\n /** Render trigger child as root element. */\n triggerAsChild?: boolean\n /** Portal target for the content. */\n portal?: string | HTMLElement\n /** Force the content to stay mounted. */\n forceMount?: boolean\n /** Side of the anchor the content appears on. */\n side?: 'top' | 'right' | 'bottom' | 'left'\n /** Distance in px from the anchor. */\n sideOffset?: number\n /** Allow flipping to opposite side. */\n sideFlip?: boolean\n /** Alignment of the content relative to the anchor. */\n align?: 'start' | 'center' | 'end'\n /** Offset along the align axis. */\n alignOffset?: number\n /** Allow flipping alignment. */\n alignFlip?: boolean\n /** Avoid collisions with the viewport. */\n avoidCollisions?: boolean\n /** Elements to use as collision boundaries. */\n collisionBoundary?: Element | null | Array<Element | null>\n /** Padding for collision detection. */\n collisionPadding?: number | Partial<Record<'top' | 'right' | 'bottom' | 'left', number>>\n /** Padding between arrow and content edge. */\n arrowPadding?: number\n /** Hide the arrow when it is shifted. */\n hideShiftedArrow?: boolean\n /** Sticky behavior when overflowing. */\n sticky?: 'partial' | 'always'\n /** Hide content when anchor is detached. */\n hideWhenDetached?: boolean\n /** CSS position strategy. */\n positionStrategy?: 'fixed' | 'absolute'\n /** When to recalculate position. */\n updatePositionStrategy?: 'always' | 'optimized'\n /** Disable position update on layout shift. */\n disableUpdateOnLayoutShift?: boolean\n /** Prioritize keeping content in viewport. */\n prioritizePosition?: boolean\n /** Virtual reference element for positioning. */\n reference?: object | null\n /** Render content as a different element. */\n contentAs?: string\n /** Render content child as root element. */\n contentAsChild?: boolean\n /** Disable pointer events outside the content. */\n disableOutsidePointerEvents?: 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 doneLabel: 'Done',\n avoidCollisions: true,\n collisionPadding: 8,\n prioritizePosition: true,\n})\n\nconst emit = defineEmits<{\n 'update:placeholder': [value: DateValue | undefined]\n 'escape-key-down': [event: KeyboardEvent]\n 'pointer-down-outside': [event: Event]\n 'focus-outside': [event: Event]\n 'interact-outside': [event: Event]\n 'open-auto-focus': [event: Event]\n 'close-auto-focus': [event: Event]\n}>()\n\nconst modelValue = defineModel<CalendarDateTime | null | undefined>('modelValue')\nconst openModel = defineModel<boolean>('open', { default: undefined })\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// ─── 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 },\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 :default-placeholder=\"defaultPlaceholder\"\n :placeholder=\"placeholder\"\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 :step=\"step\"\n :disabled=\"isDisabled\"\n :readonly=\"isReadOnly\"\n :name=\"name\"\n :dir=\"dir\"\n :id=\"id\"\n :required=\"required\"\n :modal=\"modal\"\n :paged-navigation=\"pagedNavigation\"\n :week-starts-on=\"weekStartsOn\"\n :weekday-format=\"weekdayFormat\"\n :fixed-weeks=\"fixedWeeks\"\n :number-of-months=\"numberOfMonths\"\n :prevent-deselect=\"preventDeselect\"\n :class=\"composeClassName(slotFns.base(), props.class, props.classNames?.base)\"\n data-slot=\"date-time-picker\"\n >\n <DateInput\n :model-value=\"internalValue\"\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 :class-names=\"props.classNames?.dateInput\"\n @update:model-value=\"onInputChange\"\n >\n <template #endContent>\n <DatePickerTrigger\n :class=\"composeClassName(slotFns.trigger(), props.classNames?.trigger)\"\n :as=\"triggerAs\"\n :as-child=\"triggerAsChild\"\n aria-label=\"Open date time picker\"\n @mousedown.prevent\n >\n <slot name=\"selectorIcon\">\n <svg\n :class=\"composeClassName(slotFns.triggerIndicator(), props.classNames?.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 <DatePickerContent\n :class=\"composeClassName(slotFns.popover(), props.classNames?.popover)\"\n data-slot=\"popover\"\n :side-offset=\"sideOffset ?? 8\"\n :portal=\"portal != null ? { to: portal } : undefined\"\n :force-mount=\"forceMount\"\n :side=\"side\"\n :side-flip=\"sideFlip\"\n :align=\"align\"\n :align-offset=\"alignOffset\"\n :align-flip=\"alignFlip\"\n :avoid-collisions=\"avoidCollisions\"\n :collision-boundary=\"collisionBoundary\"\n :collision-padding=\"collisionPadding\"\n :arrow-padding=\"arrowPadding\"\n :hide-shifted-arrow=\"hideShiftedArrow\"\n :sticky=\"sticky\"\n :hide-when-detached=\"hideWhenDetached\"\n :position-strategy=\"positionStrategy\"\n :update-position-strategy=\"updatePositionStrategy\"\n :disable-update-on-layout-shift=\"disableUpdateOnLayoutShift\"\n :prioritize-position=\"prioritizePosition\"\n :reference=\"(reference as any)\"\n :as=\"contentAs\"\n :as-child=\"contentAsChild\"\n :disable-outside-pointer-events=\"disableOutsidePointerEvents\"\n @escape-key-down=\"emit('escape-key-down', $event)\"\n @pointer-down-outside=\"emit('pointer-down-outside', $event)\"\n @focus-outside=\"emit('focus-outside', $event)\"\n @interact-outside=\"emit('interact-outside', $event)\"\n @open-auto-focus=\"emit('open-auto-focus', $event)\"\n @close-auto-focus=\"emit('close-auto-focus', $event)\"\n >\n <div\n :class=\"composeClassName(slotFns.panel(), props.classNames?.panel)\"\n data-slot=\"panel\"\n >\n <!-- Wrapper keeps Calendar's multiple view roots (date grid, month\n picker, year picker) as ONE flex child. Without it, the panel's\n flex layout spreads those sibling roots into separate columns and\n the inactive (empty) root shows as a blank box. -->\n <div\n :class=\"slotFns.calendarPane()\"\n data-slot=\"calendar-pane\"\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 :class-names=\"props.classNames?.calendar\"\n />\n </div>\n\n <div\n :class=\"composeClassName(slotFns.divider(), props.classNames?.divider)\"\n data-slot=\"divider\"\n aria-hidden=\"true\"\n />\n\n <!-- Time column: wheels on top, Done button pinned to the bottom so it\n lines up with the calendar's bottom edge. Selection is already live,\n so Done just closes the popover for users who miss click-outside. -->\n <div\n :class=\"slotFns.timePane()\"\n data-slot=\"time-pane\"\n >\n <TimeScroller\n :model-value=\"internalValue\"\n :granularity=\"granularity\"\n :hour-cycle=\"hourCycle\"\n :class-names=\"props.classNames?.timeScroller\"\n @update:model-value=\"(val) => onTimeUpdate(val as CalendarDateTime)\"\n />\n\n <div\n :class=\"slotFns.timeDone()\"\n data-slot=\"time-done\"\n >\n <slot name=\"footer\" :close=\"() => { openModel = false }\">\n <Button\n size=\"sm\"\n color=\"primary\"\n data-slot=\"done-button\"\n @click=\"openModel = false\"\n >\n {{ doneLabel }}\n </Button>\n </slot>\n </div>\n </div>\n </div>\n </DatePickerContent>\n </DatePickerRoot>\n</template>\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ListBox.js","names":[],"sources":["../../../src/components/list-box/ListBox.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, toRef, useAttrs, useTemplateRef } from 'vue'\nimport { useInfiniteScroll } from '@vueuse/core'\nimport { ListboxRoot, ListboxContent, ListboxVirtualizer } from 'reka-ui'\nimport { listboxVariants, type ListBoxVariants } from '@auronui/styles'\nimport { composeClassName , type ClassValue} from '../../utils/composeClassName'\nimport { useListBoxProvide } from './ListBox.context'\nimport ListBoxItem from './ListBoxItem.vue'\nimport Button from '../button/Button.vue'\nimport { useDeprecatedBooleanProp } from '../../composables/useDeprecatedBooleanProp'\n\ntype ListBoxShorthandItem = { value: string; label?: string; disabled?: boolean; textValue?: string }\n\n// Disable Vue attribute fallthrough — we manually forward ARIA attrs to ListboxContent\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<{\n modelValue?: string | string[]\n defaultValue?: string | string[]\n selectionMode?: 'single' | 'multiple'\n variant?: ListBoxVariants['variant']\n isDisabled?: boolean\n class?: ClassValue\n /**\n * Per-slot class overrides. Each key maps to a named slot in the anatomy;\n * the value is merged with the generated variant classes via `composeClassName`.\n */\n classNames?: Partial<{\n base: ClassValue\n }>\n /** Shorthand API: render list items from an array instead of the compound slot API */\n items?: ListBoxShorthandItem[]\n /** Allow selecting multiple values (alias for selectionMode=\"multiple\"). */\n multiple?: boolean\n /** Orientation of the listbox for keyboard navigation. */\n orientation?: 'horizontal' | 'vertical'\n /** Reading direction for the component. */\n dir?: 'ltr' | 'rtl'\n /** Selection behavior when multiple is true. */\n selectionBehavior?: 'toggle' | 'replace'\n /** Highlight item on hover. */\n highlightOnHover?: boolean\n /** Key used to compare items for equality. */\n by?: string\n /** Render as a different element or component. */\n as?: string\n /** Merge props onto child element instead of rendering a wrapper. */\n asChild?: boolean\n /** Form field name for native form submission. */\n name?: string\n isRequired?: boolean\n /**\n * Mark the field as required.\n * @deprecated Use isRequired instead.\n */\n required?: boolean\n /** Render the ListboxContent as a different element. */\n contentAs?: string\n /** Merge content props onto child element. */\n contentAsChild?: boolean\n /** Hide the selected checkmark on all items (forwarded via context). */\n hideSelectedIcon?: boolean\n /** Enable windowed rendering (opt-in). Renders from `items`. */\n virtualized?: boolean\n /** Estimated row height in px (or per-index fn) for the virtualizer. */\n estimateSize?: number | ((index: number) => number)\n /** Rows rendered outside the visible area. */\n overscan?: number\n /** Scroll-viewport height for the content when scrolling is active. */\n maxHeight?: string | number\n /** Whether more pages remain to load (gates load-more). */\n hasMore?: boolean\n /** A page is currently loading (gates load-more; drives #loading slot). */\n isLoading?: boolean\n /** Distance in px from the bottom that triggers load-more. */\n loadMoreDistance?: number\n /** How the next page is requested: auto on scroll, or a manual button. */\n loadMode?: 'scroll' | 'button'\n /** Label for the manual load-more button (loadMode=\"button\"). */\n loadMoreLabel?: string\n}>(), {\n modelValue: undefined,\n defaultValue: undefined,\n selectionMode: 'single',\n variant: 'default',\n isDisabled: false,\n class: undefined,\n multiple: undefined,\n orientation: undefined,\n dir: undefined,\n selectionBehavior: undefined,\n highlightOnHover: undefined,\n by: undefined,\n as: undefined,\n asChild: false,\n name: undefined,\n isRequired: undefined,\n required: undefined,\n contentAs: undefined,\n contentAsChild: false,\n hideSelectedIcon: false,\n virtualized: false,\n estimateSize: 36,\n overscan: 12,\n maxHeight: '16rem',\n hasMore: false,\n isLoading: false,\n loadMoreDistance: 120,\n loadMode: 'scroll',\n loadMoreLabel: 'Load more',\n})\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string | string[] | undefined]\n 'highlight': [context: unknown]\n 'entry-focus': [event: Event]\n 'leave': [event: Event]\n 'load-more': []\n}>()\n\nconst attrs = useAttrs()\n\nconst isRequired = useDeprecatedBooleanProp(\n 'ListBox', 'isRequired', () => props.isRequired, 'required', () => props.required,\n)\n\n// Provide context for ListBoxItem and ListBoxSection children\nuseListBoxProvide({\n variant: toRef(props, 'variant'),\n itemVariant: toRef(props, 'variant'),\n isDisabled: toRef(props, 'isDisabled'),\n hideSelectedIcon: toRef(props, 'hideSelectedIcon'),\n})\n\nconst slotFns = computed(() =>\n listboxVariants({ variant: props.variant })\n)\n\n// Bounded scroll viewport only when the content actually needs to scroll, so\n// default (non-virtualized) ListBoxes are visually unchanged.\n// useTemplateRef on a Reka component resolves to its instance; useInfiniteScroll's\n// internal unrefElement reads `.$el` to get the scroll DOM node.\nconst contentRef = useTemplateRef<HTMLElement>('content')\n\n// Re-arm latch. useInfiniteScroll keeps re-invoking onLoadMore while the scroll\n// element stays at the bottom and canLoadMore is true. Emitting `load-more` does\n// not itself flip hasMore/isLoading, so without this guard it fires in a tight\n// loop (unbounded emits → hang). We record the item count at the moment we ask\n// for a page and refuse to ask again until the dataset actually grows — i.e.\n// until the consumer has appended the next page.\nconst lastRequestedCount = ref(-1)\nuseInfiniteScroll(\n contentRef,\n () => {\n lastRequestedCount.value = props.items?.length ?? 0\n emit('load-more')\n },\n {\n // Read once at setup: useScroll consumes `offset.bottom` as a raw number\n // (no toValue), so a getter/ref here would break arrival math. Hot-swapping\n // loadMoreDistance after mount is not supported (not a real use case).\n distance: props.loadMoreDistance,\n canLoadMore: () =>\n props.loadMode === 'scroll'\n && props.hasMore\n && !props.isLoading\n && (props.items?.length ?? 0) !== lastRequestedCount.value,\n },\n)\n\n// Manual load-more (loadMode=\"button\"). User-driven, so no re-arm latch needed —\n// the hasMore/isLoading gate is enough (and the button is disabled while loading).\nfunction requestLoadMore() {\n if (props.hasMore && !props.isLoading) emit('load-more')\n}\n\nconst needsScroll = computed(() => props.virtualized)\nconst contentStyle = computed(() =>\n needsScroll.value\n ? { maxHeight: typeof props.maxHeight === 'number' ? `${props.maxHeight}px` : props.maxHeight, overflowY: 'auto' as const }\n : undefined,\n)\n\n// Stable array references for Reka. Building a fresh array inline on every render\n// would retrigger Reka's `watch(modelValue)`, which re-highlights and\n// scrollIntoView's the selected/first item — making the list jump to the top on\n// any unrelated re-render (e.g. when isLoading toggles during load-more). A\n// computed is cached, so the reference only changes when the value really does.\nconst rekaModelValue = computed(() =>\n props.modelValue == null ? undefined : ([] as string[]).concat(props.modelValue),\n)\nconst rekaDefaultValue = computed(() =>\n props.defaultValue == null ? undefined : ([] as string[]).concat(props.defaultValue),\n)\n</script>\n\n<template>\n <!-- ListboxRoot is an invisible wrapper that manages state; ListboxContent carries role=\"listbox\" -->\n <!-- We forward attrs (aria-label, aria-labelledby, etc.) to ListboxContent, not the root -->\n <ListboxRoot\n :model-value=\"rekaModelValue\"\n :default-value=\"rekaDefaultValue\"\n :multiple=\"props.multiple ?? props.selectionMode === 'multiple'\"\n :selection-behavior=\"props.selectionBehavior ?? (props.selectionMode === 'multiple' ? 'toggle' : 'replace')\"\n :disabled=\"props.isDisabled\"\n :orientation=\"props.orientation\"\n :dir=\"props.dir\"\n :highlight-on-hover=\"props.highlightOnHover\"\n :by=\"props.by\"\n :as=\"props.as\"\n :as-child=\"props.asChild\"\n :name=\"props.name\"\n :required=\"isRequired\"\n @update:model-value=\"emit('update:modelValue', props.selectionMode === 'single' ? (Array.isArray($event) ? ($event as string[])[0] : $event as string) : $event as string[])\"\n @highlight=\"emit('highlight', $event)\"\n @entry-focus=\"emit('entry-focus', $event)\"\n @leave=\"emit('leave', $event)\"\n >\n <ListboxContent\n ref=\"content\"\n v-bind=\"attrs\"\n :as=\"props.contentAs\"\n :as-child=\"props.contentAsChild\"\n :style=\"contentStyle\"\n :class=\"composeClassName(slotFns, props.class, props.classNames?.base)\"\n >\n <ListboxVirtualizer\n v-if=\"props.virtualized && props.items\"\n :options=\"props.items\"\n :estimate-size=\"props.estimateSize\"\n :overscan=\"props.overscan\"\n :text-content=\"(o) => (o.label ?? o.value)\"\n >\n <template #default=\"{ option, virtualItem }\">\n <slot name=\"item\" :item=\"option\" :index=\"virtualItem.index\">\n <ListBoxItem\n :value=\"option.value\"\n :is-disabled=\"option.disabled\"\n :text-value=\"option.textValue\"\n >{{ option.label ?? option.value }}</ListBoxItem>\n </slot>\n </template>\n </ListboxVirtualizer>\n\n <template v-else-if=\"props.items\">\n <ListBoxItem\n v-for=\"item in props.items\"\n :key=\"item.value\"\n :value=\"item.value\"\n :is-disabled=\"item.disabled\"\n :text-value=\"item.textValue\"\n >{{ item.label ?? item.value }}</ListBoxItem>\n </template>\n\n <slot v-else />\n </ListboxContent>\n\n <!-- Bottom area, rendered outside role=\"listbox\" so it does not violate\n aria-required-children. Scroll mode shows a loading row; button mode\n shows a manual \"Load more\" button (which conveys its own loading state). -->\n <div\n v-if=\"props.loadMode === 'scroll' && props.isLoading\"\n data-slot=\"list-box-loading\"\n role=\"status\"\n aria-live=\"polite\"\n >\n <slot name=\"loading\">Loading…</slot>\n </div>\n\n <div\n v-if=\"props.loadMode === 'button' && props.hasMore\"\n class=\"flex justify-center p-2\"\n data-slot=\"list-box-load-more\"\n >\n <slot\n name=\"loadMore\"\n :load-more=\"requestLoadMore\"\n :is-loading=\"props.isLoading\"\n :has-more=\"props.hasMore\"\n >\n <Button\n size=\"sm\"\n :is-loading=\"props.isLoading\"\n :disabled=\"props.isLoading\"\n data-slot=\"load-more-button\"\n @click=\"requestLoadMore\"\n >\n {{ props.loadMoreLabel }}\n </Button>\n </slot>\n </div>\n </ListboxRoot>\n</template>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"ListBox.js","names":[],"sources":["../../../src/components/list-box/ListBox.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, toRef, useAttrs, useTemplateRef } from 'vue'\nimport { useInfiniteScroll } from '@vueuse/core'\nimport { ListboxRoot, ListboxContent, ListboxVirtualizer } from 'reka-ui'\nimport { listboxVariants, type ListBoxVariants } from '@auronui/styles'\nimport { composeClassName , type ClassValue} from '../../utils/composeClassName'\nimport { useListBoxProvide } from './ListBox.context'\nimport ListBoxItem from './ListBoxItem.vue'\nimport Button from '../button/Button.vue'\nimport { useDeprecatedBooleanProp } from '../../composables/useDeprecatedBooleanProp'\n\ntype ListBoxShorthandItem = { value: string; label?: string; disabled?: boolean; textValue?: string }\n\n// Disable Vue attribute fallthrough — we manually forward ARIA attrs to ListboxContent\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<{\n modelValue?: string | string[]\n defaultValue?: string | string[]\n selectionMode?: 'single' | 'multiple'\n variant?: ListBoxVariants['variant']\n isDisabled?: boolean\n class?: ClassValue\n /**\n * Per-slot class overrides. Each key maps to a named slot in the anatomy;\n * the value is merged with the generated variant classes via `composeClassName`.\n */\n classNames?: Partial<{\n base: ClassValue\n item: ClassValue\n indicator: ClassValue\n }>\n /** Shorthand API: render list items from an array instead of the compound slot API */\n items?: ListBoxShorthandItem[]\n /** Allow selecting multiple values (alias for selectionMode=\"multiple\"). */\n multiple?: boolean\n /** Orientation of the listbox for keyboard navigation. */\n orientation?: 'horizontal' | 'vertical'\n /** Reading direction for the component. */\n dir?: 'ltr' | 'rtl'\n /** Selection behavior when multiple is true. */\n selectionBehavior?: 'toggle' | 'replace'\n /** Highlight item on hover. */\n highlightOnHover?: boolean\n /** Key used to compare items for equality. */\n by?: string\n /** Render as a different element or component. */\n as?: string\n /** Merge props onto child element instead of rendering a wrapper. */\n asChild?: boolean\n /** Form field name for native form submission. */\n name?: string\n isRequired?: boolean\n /**\n * Mark the field as required.\n * @deprecated Use isRequired instead.\n */\n required?: boolean\n /** Render the ListboxContent as a different element. */\n contentAs?: string\n /** Merge content props onto child element. */\n contentAsChild?: boolean\n /** Hide the selected checkmark on all items (forwarded via context). */\n hideSelectedIcon?: boolean\n /** Enable windowed rendering (opt-in). Renders from `items`. */\n virtualized?: boolean\n /** Estimated row height in px (or per-index fn) for the virtualizer. */\n estimateSize?: number | ((index: number) => number)\n /** Rows rendered outside the visible area. */\n overscan?: number\n /** Scroll-viewport height for the content when scrolling is active. */\n maxHeight?: string | number\n /** Whether more pages remain to load (gates load-more). */\n hasMore?: boolean\n /** A page is currently loading (gates load-more; drives #loading slot). */\n isLoading?: boolean\n /** Distance in px from the bottom that triggers load-more. */\n loadMoreDistance?: number\n /** How the next page is requested: auto on scroll, or a manual button. */\n loadMode?: 'scroll' | 'button'\n /** Label for the manual load-more button (loadMode=\"button\"). */\n loadMoreLabel?: string\n}>(), {\n modelValue: undefined,\n defaultValue: undefined,\n selectionMode: 'single',\n variant: 'default',\n isDisabled: false,\n class: undefined,\n multiple: undefined,\n orientation: undefined,\n dir: undefined,\n selectionBehavior: undefined,\n highlightOnHover: undefined,\n by: undefined,\n as: undefined,\n asChild: false,\n name: undefined,\n isRequired: undefined,\n required: undefined,\n contentAs: undefined,\n contentAsChild: false,\n hideSelectedIcon: false,\n virtualized: false,\n estimateSize: 36,\n overscan: 12,\n maxHeight: '16rem',\n hasMore: false,\n isLoading: false,\n loadMoreDistance: 120,\n loadMode: 'scroll',\n loadMoreLabel: 'Load more',\n})\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string | string[] | undefined]\n 'highlight': [context: unknown]\n 'entry-focus': [event: Event]\n 'leave': [event: Event]\n 'load-more': []\n}>()\n\nconst attrs = useAttrs()\n\nconst isRequired = useDeprecatedBooleanProp(\n 'ListBox', 'isRequired', () => props.isRequired, 'required', () => props.required,\n)\n\n// Provide context for ListBoxItem and ListBoxSection children\nuseListBoxProvide({\n variant: toRef(props, 'variant'),\n itemVariant: toRef(props, 'variant'),\n isDisabled: toRef(props, 'isDisabled'),\n hideSelectedIcon: toRef(props, 'hideSelectedIcon'),\n})\n\nconst slotFns = computed(() =>\n listboxVariants({ variant: props.variant })\n)\n\n// Bounded scroll viewport only when the content actually needs to scroll, so\n// default (non-virtualized) ListBoxes are visually unchanged.\n// useTemplateRef on a Reka component resolves to its instance; useInfiniteScroll's\n// internal unrefElement reads `.$el` to get the scroll DOM node.\nconst contentRef = useTemplateRef<HTMLElement>('content')\n\n// Re-arm latch. useInfiniteScroll keeps re-invoking onLoadMore while the scroll\n// element stays at the bottom and canLoadMore is true. Emitting `load-more` does\n// not itself flip hasMore/isLoading, so without this guard it fires in a tight\n// loop (unbounded emits → hang). We record the item count at the moment we ask\n// for a page and refuse to ask again until the dataset actually grows — i.e.\n// until the consumer has appended the next page.\nconst lastRequestedCount = ref(-1)\nuseInfiniteScroll(\n contentRef,\n () => {\n lastRequestedCount.value = props.items?.length ?? 0\n emit('load-more')\n },\n {\n // Read once at setup: useScroll consumes `offset.bottom` as a raw number\n // (no toValue), so a getter/ref here would break arrival math. Hot-swapping\n // loadMoreDistance after mount is not supported (not a real use case).\n distance: props.loadMoreDistance,\n canLoadMore: () =>\n props.loadMode === 'scroll'\n && props.hasMore\n && !props.isLoading\n && (props.items?.length ?? 0) !== lastRequestedCount.value,\n },\n)\n\n// Manual load-more (loadMode=\"button\"). User-driven, so no re-arm latch needed —\n// the hasMore/isLoading gate is enough (and the button is disabled while loading).\nfunction requestLoadMore() {\n if (props.hasMore && !props.isLoading) emit('load-more')\n}\n\nconst needsScroll = computed(() => props.virtualized)\nconst contentStyle = computed(() =>\n needsScroll.value\n ? { maxHeight: typeof props.maxHeight === 'number' ? `${props.maxHeight}px` : props.maxHeight, overflowY: 'auto' as const }\n : undefined,\n)\n\n// Stable array references for Reka. Building a fresh array inline on every render\n// would retrigger Reka's `watch(modelValue)`, which re-highlights and\n// scrollIntoView's the selected/first item — making the list jump to the top on\n// any unrelated re-render (e.g. when isLoading toggles during load-more). A\n// computed is cached, so the reference only changes when the value really does.\nconst rekaModelValue = computed(() =>\n props.modelValue == null ? undefined : ([] as string[]).concat(props.modelValue),\n)\nconst rekaDefaultValue = computed(() =>\n props.defaultValue == null ? undefined : ([] as string[]).concat(props.defaultValue),\n)\n</script>\n\n<template>\n <!-- ListboxRoot is an invisible wrapper that manages state; ListboxContent carries role=\"listbox\" -->\n <!-- We forward attrs (aria-label, aria-labelledby, etc.) to ListboxContent, not the root -->\n <ListboxRoot\n :model-value=\"rekaModelValue\"\n :default-value=\"rekaDefaultValue\"\n :multiple=\"props.multiple ?? props.selectionMode === 'multiple'\"\n :selection-behavior=\"props.selectionBehavior ?? (props.selectionMode === 'multiple' ? 'toggle' : 'replace')\"\n :disabled=\"props.isDisabled\"\n :orientation=\"props.orientation\"\n :dir=\"props.dir\"\n :highlight-on-hover=\"props.highlightOnHover\"\n :by=\"props.by\"\n :as=\"props.as\"\n :as-child=\"props.asChild\"\n :name=\"props.name\"\n :required=\"isRequired\"\n @update:model-value=\"emit('update:modelValue', props.selectionMode === 'single' ? (Array.isArray($event) ? ($event as string[])[0] : $event as string) : $event as string[])\"\n @highlight=\"emit('highlight', $event)\"\n @entry-focus=\"emit('entry-focus', $event)\"\n @leave=\"emit('leave', $event)\"\n >\n <ListboxContent\n ref=\"content\"\n v-bind=\"attrs\"\n :as=\"props.contentAs\"\n :as-child=\"props.contentAsChild\"\n :style=\"contentStyle\"\n :class=\"composeClassName(slotFns, props.class, props.classNames?.base)\"\n >\n <ListboxVirtualizer\n v-if=\"props.virtualized && props.items\"\n :options=\"props.items\"\n :estimate-size=\"props.estimateSize\"\n :overscan=\"props.overscan\"\n :text-content=\"(o) => (o.label ?? o.value)\"\n >\n <template #default=\"{ option, virtualItem }\">\n <slot name=\"item\" :item=\"option\" :index=\"virtualItem.index\">\n <ListBoxItem\n :value=\"option.value\"\n :is-disabled=\"option.disabled\"\n :text-value=\"option.textValue\"\n :class-names=\"{ item: props.classNames?.item, indicator: props.classNames?.indicator }\"\n >{{ option.label ?? option.value }}</ListBoxItem>\n </slot>\n </template>\n </ListboxVirtualizer>\n\n <template v-else-if=\"props.items\">\n <ListBoxItem\n v-for=\"item in props.items\"\n :key=\"item.value\"\n :value=\"item.value\"\n :is-disabled=\"item.disabled\"\n :text-value=\"item.textValue\"\n :class-names=\"{ item: props.classNames?.item, indicator: props.classNames?.indicator }\"\n >{{ item.label ?? item.value }}</ListBoxItem>\n </template>\n\n <slot v-else />\n </ListboxContent>\n\n <!-- Bottom area, rendered outside role=\"listbox\" so it does not violate\n aria-required-children. Scroll mode shows a loading row; button mode\n shows a manual \"Load more\" button (which conveys its own loading state). -->\n <div\n v-if=\"props.loadMode === 'scroll' && props.isLoading\"\n data-slot=\"list-box-loading\"\n role=\"status\"\n aria-live=\"polite\"\n >\n <slot name=\"loading\">Loading…</slot>\n </div>\n\n <div\n v-if=\"props.loadMode === 'button' && props.hasMore\"\n class=\"flex justify-center p-2\"\n data-slot=\"list-box-load-more\"\n >\n <slot\n name=\"loadMore\"\n :load-more=\"requestLoadMore\"\n :is-loading=\"props.isLoading\"\n :has-more=\"props.hasMore\"\n >\n <Button\n size=\"sm\"\n :is-loading=\"props.isLoading\"\n :disabled=\"props.isLoading\"\n data-slot=\"load-more-button\"\n @click=\"requestLoadMore\"\n >\n {{ props.loadMoreLabel }}\n </Button>\n </slot>\n </div>\n </ListboxRoot>\n</template>\n"],"mappings":""}
|
|
@@ -178,14 +178,19 @@ var ListBox_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ define
|
|
|
178
178
|
}, () => [createVNode(ListBoxItem_default, {
|
|
179
179
|
value: option.value,
|
|
180
180
|
"is-disabled": option.disabled,
|
|
181
|
-
"text-value": option.textValue
|
|
181
|
+
"text-value": option.textValue,
|
|
182
|
+
"class-names": {
|
|
183
|
+
item: props.classNames?.item,
|
|
184
|
+
indicator: props.classNames?.indicator
|
|
185
|
+
}
|
|
182
186
|
}, {
|
|
183
187
|
default: withCtx(() => [createTextVNode(toDisplayString(option.label ?? option.value), 1)]),
|
|
184
188
|
_: 2
|
|
185
189
|
}, 1032, [
|
|
186
190
|
"value",
|
|
187
191
|
"is-disabled",
|
|
188
|
-
"text-value"
|
|
192
|
+
"text-value",
|
|
193
|
+
"class-names"
|
|
189
194
|
])])]),
|
|
190
195
|
_: 3
|
|
191
196
|
}, 8, [
|
|
@@ -198,14 +203,19 @@ var ListBox_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ define
|
|
|
198
203
|
key: item.value,
|
|
199
204
|
value: item.value,
|
|
200
205
|
"is-disabled": item.disabled,
|
|
201
|
-
"text-value": item.textValue
|
|
206
|
+
"text-value": item.textValue,
|
|
207
|
+
"class-names": {
|
|
208
|
+
item: props.classNames?.item,
|
|
209
|
+
indicator: props.classNames?.indicator
|
|
210
|
+
}
|
|
202
211
|
}, {
|
|
203
212
|
default: withCtx(() => [createTextVNode(toDisplayString(item.label ?? item.value), 1)]),
|
|
204
213
|
_: 2
|
|
205
214
|
}, 1032, [
|
|
206
215
|
"value",
|
|
207
216
|
"is-disabled",
|
|
208
|
-
"text-value"
|
|
217
|
+
"text-value",
|
|
218
|
+
"class-names"
|
|
209
219
|
]);
|
|
210
220
|
}), 128)) : renderSlot(_ctx.$slots, "default", { key: 2 })]),
|
|
211
221
|
_: 3
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ListBox.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/list-box/ListBox.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, toRef, useAttrs, useTemplateRef } from 'vue'\nimport { useInfiniteScroll } from '@vueuse/core'\nimport { ListboxRoot, ListboxContent, ListboxVirtualizer } from 'reka-ui'\nimport { listboxVariants, type ListBoxVariants } from '@auronui/styles'\nimport { composeClassName , type ClassValue} from '../../utils/composeClassName'\nimport { useListBoxProvide } from './ListBox.context'\nimport ListBoxItem from './ListBoxItem.vue'\nimport Button from '../button/Button.vue'\nimport { useDeprecatedBooleanProp } from '../../composables/useDeprecatedBooleanProp'\n\ntype ListBoxShorthandItem = { value: string; label?: string; disabled?: boolean; textValue?: string }\n\n// Disable Vue attribute fallthrough — we manually forward ARIA attrs to ListboxContent\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<{\n modelValue?: string | string[]\n defaultValue?: string | string[]\n selectionMode?: 'single' | 'multiple'\n variant?: ListBoxVariants['variant']\n isDisabled?: boolean\n class?: ClassValue\n /**\n * Per-slot class overrides. Each key maps to a named slot in the anatomy;\n * the value is merged with the generated variant classes via `composeClassName`.\n */\n classNames?: Partial<{\n base: ClassValue\n }>\n /** Shorthand API: render list items from an array instead of the compound slot API */\n items?: ListBoxShorthandItem[]\n /** Allow selecting multiple values (alias for selectionMode=\"multiple\"). */\n multiple?: boolean\n /** Orientation of the listbox for keyboard navigation. */\n orientation?: 'horizontal' | 'vertical'\n /** Reading direction for the component. */\n dir?: 'ltr' | 'rtl'\n /** Selection behavior when multiple is true. */\n selectionBehavior?: 'toggle' | 'replace'\n /** Highlight item on hover. */\n highlightOnHover?: boolean\n /** Key used to compare items for equality. */\n by?: string\n /** Render as a different element or component. */\n as?: string\n /** Merge props onto child element instead of rendering a wrapper. */\n asChild?: boolean\n /** Form field name for native form submission. */\n name?: string\n isRequired?: boolean\n /**\n * Mark the field as required.\n * @deprecated Use isRequired instead.\n */\n required?: boolean\n /** Render the ListboxContent as a different element. */\n contentAs?: string\n /** Merge content props onto child element. */\n contentAsChild?: boolean\n /** Hide the selected checkmark on all items (forwarded via context). */\n hideSelectedIcon?: boolean\n /** Enable windowed rendering (opt-in). Renders from `items`. */\n virtualized?: boolean\n /** Estimated row height in px (or per-index fn) for the virtualizer. */\n estimateSize?: number | ((index: number) => number)\n /** Rows rendered outside the visible area. */\n overscan?: number\n /** Scroll-viewport height for the content when scrolling is active. */\n maxHeight?: string | number\n /** Whether more pages remain to load (gates load-more). */\n hasMore?: boolean\n /** A page is currently loading (gates load-more; drives #loading slot). */\n isLoading?: boolean\n /** Distance in px from the bottom that triggers load-more. */\n loadMoreDistance?: number\n /** How the next page is requested: auto on scroll, or a manual button. */\n loadMode?: 'scroll' | 'button'\n /** Label for the manual load-more button (loadMode=\"button\"). */\n loadMoreLabel?: string\n}>(), {\n modelValue: undefined,\n defaultValue: undefined,\n selectionMode: 'single',\n variant: 'default',\n isDisabled: false,\n class: undefined,\n multiple: undefined,\n orientation: undefined,\n dir: undefined,\n selectionBehavior: undefined,\n highlightOnHover: undefined,\n by: undefined,\n as: undefined,\n asChild: false,\n name: undefined,\n isRequired: undefined,\n required: undefined,\n contentAs: undefined,\n contentAsChild: false,\n hideSelectedIcon: false,\n virtualized: false,\n estimateSize: 36,\n overscan: 12,\n maxHeight: '16rem',\n hasMore: false,\n isLoading: false,\n loadMoreDistance: 120,\n loadMode: 'scroll',\n loadMoreLabel: 'Load more',\n})\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string | string[] | undefined]\n 'highlight': [context: unknown]\n 'entry-focus': [event: Event]\n 'leave': [event: Event]\n 'load-more': []\n}>()\n\nconst attrs = useAttrs()\n\nconst isRequired = useDeprecatedBooleanProp(\n 'ListBox', 'isRequired', () => props.isRequired, 'required', () => props.required,\n)\n\n// Provide context for ListBoxItem and ListBoxSection children\nuseListBoxProvide({\n variant: toRef(props, 'variant'),\n itemVariant: toRef(props, 'variant'),\n isDisabled: toRef(props, 'isDisabled'),\n hideSelectedIcon: toRef(props, 'hideSelectedIcon'),\n})\n\nconst slotFns = computed(() =>\n listboxVariants({ variant: props.variant })\n)\n\n// Bounded scroll viewport only when the content actually needs to scroll, so\n// default (non-virtualized) ListBoxes are visually unchanged.\n// useTemplateRef on a Reka component resolves to its instance; useInfiniteScroll's\n// internal unrefElement reads `.$el` to get the scroll DOM node.\nconst contentRef = useTemplateRef<HTMLElement>('content')\n\n// Re-arm latch. useInfiniteScroll keeps re-invoking onLoadMore while the scroll\n// element stays at the bottom and canLoadMore is true. Emitting `load-more` does\n// not itself flip hasMore/isLoading, so without this guard it fires in a tight\n// loop (unbounded emits → hang). We record the item count at the moment we ask\n// for a page and refuse to ask again until the dataset actually grows — i.e.\n// until the consumer has appended the next page.\nconst lastRequestedCount = ref(-1)\nuseInfiniteScroll(\n contentRef,\n () => {\n lastRequestedCount.value = props.items?.length ?? 0\n emit('load-more')\n },\n {\n // Read once at setup: useScroll consumes `offset.bottom` as a raw number\n // (no toValue), so a getter/ref here would break arrival math. Hot-swapping\n // loadMoreDistance after mount is not supported (not a real use case).\n distance: props.loadMoreDistance,\n canLoadMore: () =>\n props.loadMode === 'scroll'\n && props.hasMore\n && !props.isLoading\n && (props.items?.length ?? 0) !== lastRequestedCount.value,\n },\n)\n\n// Manual load-more (loadMode=\"button\"). User-driven, so no re-arm latch needed —\n// the hasMore/isLoading gate is enough (and the button is disabled while loading).\nfunction requestLoadMore() {\n if (props.hasMore && !props.isLoading) emit('load-more')\n}\n\nconst needsScroll = computed(() => props.virtualized)\nconst contentStyle = computed(() =>\n needsScroll.value\n ? { maxHeight: typeof props.maxHeight === 'number' ? `${props.maxHeight}px` : props.maxHeight, overflowY: 'auto' as const }\n : undefined,\n)\n\n// Stable array references for Reka. Building a fresh array inline on every render\n// would retrigger Reka's `watch(modelValue)`, which re-highlights and\n// scrollIntoView's the selected/first item — making the list jump to the top on\n// any unrelated re-render (e.g. when isLoading toggles during load-more). A\n// computed is cached, so the reference only changes when the value really does.\nconst rekaModelValue = computed(() =>\n props.modelValue == null ? undefined : ([] as string[]).concat(props.modelValue),\n)\nconst rekaDefaultValue = computed(() =>\n props.defaultValue == null ? undefined : ([] as string[]).concat(props.defaultValue),\n)\n</script>\n\n<template>\n <!-- ListboxRoot is an invisible wrapper that manages state; ListboxContent carries role=\"listbox\" -->\n <!-- We forward attrs (aria-label, aria-labelledby, etc.) to ListboxContent, not the root -->\n <ListboxRoot\n :model-value=\"rekaModelValue\"\n :default-value=\"rekaDefaultValue\"\n :multiple=\"props.multiple ?? props.selectionMode === 'multiple'\"\n :selection-behavior=\"props.selectionBehavior ?? (props.selectionMode === 'multiple' ? 'toggle' : 'replace')\"\n :disabled=\"props.isDisabled\"\n :orientation=\"props.orientation\"\n :dir=\"props.dir\"\n :highlight-on-hover=\"props.highlightOnHover\"\n :by=\"props.by\"\n :as=\"props.as\"\n :as-child=\"props.asChild\"\n :name=\"props.name\"\n :required=\"isRequired\"\n @update:model-value=\"emit('update:modelValue', props.selectionMode === 'single' ? (Array.isArray($event) ? ($event as string[])[0] : $event as string) : $event as string[])\"\n @highlight=\"emit('highlight', $event)\"\n @entry-focus=\"emit('entry-focus', $event)\"\n @leave=\"emit('leave', $event)\"\n >\n <ListboxContent\n ref=\"content\"\n v-bind=\"attrs\"\n :as=\"props.contentAs\"\n :as-child=\"props.contentAsChild\"\n :style=\"contentStyle\"\n :class=\"composeClassName(slotFns, props.class, props.classNames?.base)\"\n >\n <ListboxVirtualizer\n v-if=\"props.virtualized && props.items\"\n :options=\"props.items\"\n :estimate-size=\"props.estimateSize\"\n :overscan=\"props.overscan\"\n :text-content=\"(o) => (o.label ?? o.value)\"\n >\n <template #default=\"{ option, virtualItem }\">\n <slot name=\"item\" :item=\"option\" :index=\"virtualItem.index\">\n <ListBoxItem\n :value=\"option.value\"\n :is-disabled=\"option.disabled\"\n :text-value=\"option.textValue\"\n >{{ option.label ?? option.value }}</ListBoxItem>\n </slot>\n </template>\n </ListboxVirtualizer>\n\n <template v-else-if=\"props.items\">\n <ListBoxItem\n v-for=\"item in props.items\"\n :key=\"item.value\"\n :value=\"item.value\"\n :is-disabled=\"item.disabled\"\n :text-value=\"item.textValue\"\n >{{ item.label ?? item.value }}</ListBoxItem>\n </template>\n\n <slot v-else />\n </ListboxContent>\n\n <!-- Bottom area, rendered outside role=\"listbox\" so it does not violate\n aria-required-children. Scroll mode shows a loading row; button mode\n shows a manual \"Load more\" button (which conveys its own loading state). -->\n <div\n v-if=\"props.loadMode === 'scroll' && props.isLoading\"\n data-slot=\"list-box-loading\"\n role=\"status\"\n aria-live=\"polite\"\n >\n <slot name=\"loading\">Loading…</slot>\n </div>\n\n <div\n v-if=\"props.loadMode === 'button' && props.hasMore\"\n class=\"flex justify-center p-2\"\n data-slot=\"list-box-load-more\"\n >\n <slot\n name=\"loadMore\"\n :load-more=\"requestLoadMore\"\n :is-loading=\"props.isLoading\"\n :has-more=\"props.hasMore\"\n >\n <Button\n size=\"sm\"\n :is-loading=\"props.isLoading\"\n :disabled=\"props.isLoading\"\n data-slot=\"load-more-button\"\n @click=\"requestLoadMore\"\n >\n {{ props.loadMoreLabel }}\n </Button>\n </slot>\n </div>\n </ListboxRoot>\n</template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ListBox.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/list-box/ListBox.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, toRef, useAttrs, useTemplateRef } from 'vue'\nimport { useInfiniteScroll } from '@vueuse/core'\nimport { ListboxRoot, ListboxContent, ListboxVirtualizer } from 'reka-ui'\nimport { listboxVariants, type ListBoxVariants } from '@auronui/styles'\nimport { composeClassName , type ClassValue} from '../../utils/composeClassName'\nimport { useListBoxProvide } from './ListBox.context'\nimport ListBoxItem from './ListBoxItem.vue'\nimport Button from '../button/Button.vue'\nimport { useDeprecatedBooleanProp } from '../../composables/useDeprecatedBooleanProp'\n\ntype ListBoxShorthandItem = { value: string; label?: string; disabled?: boolean; textValue?: string }\n\n// Disable Vue attribute fallthrough — we manually forward ARIA attrs to ListboxContent\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<{\n modelValue?: string | string[]\n defaultValue?: string | string[]\n selectionMode?: 'single' | 'multiple'\n variant?: ListBoxVariants['variant']\n isDisabled?: boolean\n class?: ClassValue\n /**\n * Per-slot class overrides. Each key maps to a named slot in the anatomy;\n * the value is merged with the generated variant classes via `composeClassName`.\n */\n classNames?: Partial<{\n base: ClassValue\n item: ClassValue\n indicator: ClassValue\n }>\n /** Shorthand API: render list items from an array instead of the compound slot API */\n items?: ListBoxShorthandItem[]\n /** Allow selecting multiple values (alias for selectionMode=\"multiple\"). */\n multiple?: boolean\n /** Orientation of the listbox for keyboard navigation. */\n orientation?: 'horizontal' | 'vertical'\n /** Reading direction for the component. */\n dir?: 'ltr' | 'rtl'\n /** Selection behavior when multiple is true. */\n selectionBehavior?: 'toggle' | 'replace'\n /** Highlight item on hover. */\n highlightOnHover?: boolean\n /** Key used to compare items for equality. */\n by?: string\n /** Render as a different element or component. */\n as?: string\n /** Merge props onto child element instead of rendering a wrapper. */\n asChild?: boolean\n /** Form field name for native form submission. */\n name?: string\n isRequired?: boolean\n /**\n * Mark the field as required.\n * @deprecated Use isRequired instead.\n */\n required?: boolean\n /** Render the ListboxContent as a different element. */\n contentAs?: string\n /** Merge content props onto child element. */\n contentAsChild?: boolean\n /** Hide the selected checkmark on all items (forwarded via context). */\n hideSelectedIcon?: boolean\n /** Enable windowed rendering (opt-in). Renders from `items`. */\n virtualized?: boolean\n /** Estimated row height in px (or per-index fn) for the virtualizer. */\n estimateSize?: number | ((index: number) => number)\n /** Rows rendered outside the visible area. */\n overscan?: number\n /** Scroll-viewport height for the content when scrolling is active. */\n maxHeight?: string | number\n /** Whether more pages remain to load (gates load-more). */\n hasMore?: boolean\n /** A page is currently loading (gates load-more; drives #loading slot). */\n isLoading?: boolean\n /** Distance in px from the bottom that triggers load-more. */\n loadMoreDistance?: number\n /** How the next page is requested: auto on scroll, or a manual button. */\n loadMode?: 'scroll' | 'button'\n /** Label for the manual load-more button (loadMode=\"button\"). */\n loadMoreLabel?: string\n}>(), {\n modelValue: undefined,\n defaultValue: undefined,\n selectionMode: 'single',\n variant: 'default',\n isDisabled: false,\n class: undefined,\n multiple: undefined,\n orientation: undefined,\n dir: undefined,\n selectionBehavior: undefined,\n highlightOnHover: undefined,\n by: undefined,\n as: undefined,\n asChild: false,\n name: undefined,\n isRequired: undefined,\n required: undefined,\n contentAs: undefined,\n contentAsChild: false,\n hideSelectedIcon: false,\n virtualized: false,\n estimateSize: 36,\n overscan: 12,\n maxHeight: '16rem',\n hasMore: false,\n isLoading: false,\n loadMoreDistance: 120,\n loadMode: 'scroll',\n loadMoreLabel: 'Load more',\n})\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string | string[] | undefined]\n 'highlight': [context: unknown]\n 'entry-focus': [event: Event]\n 'leave': [event: Event]\n 'load-more': []\n}>()\n\nconst attrs = useAttrs()\n\nconst isRequired = useDeprecatedBooleanProp(\n 'ListBox', 'isRequired', () => props.isRequired, 'required', () => props.required,\n)\n\n// Provide context for ListBoxItem and ListBoxSection children\nuseListBoxProvide({\n variant: toRef(props, 'variant'),\n itemVariant: toRef(props, 'variant'),\n isDisabled: toRef(props, 'isDisabled'),\n hideSelectedIcon: toRef(props, 'hideSelectedIcon'),\n})\n\nconst slotFns = computed(() =>\n listboxVariants({ variant: props.variant })\n)\n\n// Bounded scroll viewport only when the content actually needs to scroll, so\n// default (non-virtualized) ListBoxes are visually unchanged.\n// useTemplateRef on a Reka component resolves to its instance; useInfiniteScroll's\n// internal unrefElement reads `.$el` to get the scroll DOM node.\nconst contentRef = useTemplateRef<HTMLElement>('content')\n\n// Re-arm latch. useInfiniteScroll keeps re-invoking onLoadMore while the scroll\n// element stays at the bottom and canLoadMore is true. Emitting `load-more` does\n// not itself flip hasMore/isLoading, so without this guard it fires in a tight\n// loop (unbounded emits → hang). We record the item count at the moment we ask\n// for a page and refuse to ask again until the dataset actually grows — i.e.\n// until the consumer has appended the next page.\nconst lastRequestedCount = ref(-1)\nuseInfiniteScroll(\n contentRef,\n () => {\n lastRequestedCount.value = props.items?.length ?? 0\n emit('load-more')\n },\n {\n // Read once at setup: useScroll consumes `offset.bottom` as a raw number\n // (no toValue), so a getter/ref here would break arrival math. Hot-swapping\n // loadMoreDistance after mount is not supported (not a real use case).\n distance: props.loadMoreDistance,\n canLoadMore: () =>\n props.loadMode === 'scroll'\n && props.hasMore\n && !props.isLoading\n && (props.items?.length ?? 0) !== lastRequestedCount.value,\n },\n)\n\n// Manual load-more (loadMode=\"button\"). User-driven, so no re-arm latch needed —\n// the hasMore/isLoading gate is enough (and the button is disabled while loading).\nfunction requestLoadMore() {\n if (props.hasMore && !props.isLoading) emit('load-more')\n}\n\nconst needsScroll = computed(() => props.virtualized)\nconst contentStyle = computed(() =>\n needsScroll.value\n ? { maxHeight: typeof props.maxHeight === 'number' ? `${props.maxHeight}px` : props.maxHeight, overflowY: 'auto' as const }\n : undefined,\n)\n\n// Stable array references for Reka. Building a fresh array inline on every render\n// would retrigger Reka's `watch(modelValue)`, which re-highlights and\n// scrollIntoView's the selected/first item — making the list jump to the top on\n// any unrelated re-render (e.g. when isLoading toggles during load-more). A\n// computed is cached, so the reference only changes when the value really does.\nconst rekaModelValue = computed(() =>\n props.modelValue == null ? undefined : ([] as string[]).concat(props.modelValue),\n)\nconst rekaDefaultValue = computed(() =>\n props.defaultValue == null ? undefined : ([] as string[]).concat(props.defaultValue),\n)\n</script>\n\n<template>\n <!-- ListboxRoot is an invisible wrapper that manages state; ListboxContent carries role=\"listbox\" -->\n <!-- We forward attrs (aria-label, aria-labelledby, etc.) to ListboxContent, not the root -->\n <ListboxRoot\n :model-value=\"rekaModelValue\"\n :default-value=\"rekaDefaultValue\"\n :multiple=\"props.multiple ?? props.selectionMode === 'multiple'\"\n :selection-behavior=\"props.selectionBehavior ?? (props.selectionMode === 'multiple' ? 'toggle' : 'replace')\"\n :disabled=\"props.isDisabled\"\n :orientation=\"props.orientation\"\n :dir=\"props.dir\"\n :highlight-on-hover=\"props.highlightOnHover\"\n :by=\"props.by\"\n :as=\"props.as\"\n :as-child=\"props.asChild\"\n :name=\"props.name\"\n :required=\"isRequired\"\n @update:model-value=\"emit('update:modelValue', props.selectionMode === 'single' ? (Array.isArray($event) ? ($event as string[])[0] : $event as string) : $event as string[])\"\n @highlight=\"emit('highlight', $event)\"\n @entry-focus=\"emit('entry-focus', $event)\"\n @leave=\"emit('leave', $event)\"\n >\n <ListboxContent\n ref=\"content\"\n v-bind=\"attrs\"\n :as=\"props.contentAs\"\n :as-child=\"props.contentAsChild\"\n :style=\"contentStyle\"\n :class=\"composeClassName(slotFns, props.class, props.classNames?.base)\"\n >\n <ListboxVirtualizer\n v-if=\"props.virtualized && props.items\"\n :options=\"props.items\"\n :estimate-size=\"props.estimateSize\"\n :overscan=\"props.overscan\"\n :text-content=\"(o) => (o.label ?? o.value)\"\n >\n <template #default=\"{ option, virtualItem }\">\n <slot name=\"item\" :item=\"option\" :index=\"virtualItem.index\">\n <ListBoxItem\n :value=\"option.value\"\n :is-disabled=\"option.disabled\"\n :text-value=\"option.textValue\"\n :class-names=\"{ item: props.classNames?.item, indicator: props.classNames?.indicator }\"\n >{{ option.label ?? option.value }}</ListBoxItem>\n </slot>\n </template>\n </ListboxVirtualizer>\n\n <template v-else-if=\"props.items\">\n <ListBoxItem\n v-for=\"item in props.items\"\n :key=\"item.value\"\n :value=\"item.value\"\n :is-disabled=\"item.disabled\"\n :text-value=\"item.textValue\"\n :class-names=\"{ item: props.classNames?.item, indicator: props.classNames?.indicator }\"\n >{{ item.label ?? item.value }}</ListBoxItem>\n </template>\n\n <slot v-else />\n </ListboxContent>\n\n <!-- Bottom area, rendered outside role=\"listbox\" so it does not violate\n aria-required-children. Scroll mode shows a loading row; button mode\n shows a manual \"Load more\" button (which conveys its own loading state). -->\n <div\n v-if=\"props.loadMode === 'scroll' && props.isLoading\"\n data-slot=\"list-box-loading\"\n role=\"status\"\n aria-live=\"polite\"\n >\n <slot name=\"loading\">Loading…</slot>\n </div>\n\n <div\n v-if=\"props.loadMode === 'button' && props.hasMore\"\n class=\"flex justify-center p-2\"\n data-slot=\"list-box-load-more\"\n >\n <slot\n name=\"loadMore\"\n :load-more=\"requestLoadMore\"\n :is-loading=\"props.isLoading\"\n :has-more=\"props.hasMore\"\n >\n <Button\n size=\"sm\"\n :is-loading=\"props.isLoading\"\n :disabled=\"props.isLoading\"\n data-slot=\"load-more-button\"\n @click=\"requestLoadMore\"\n >\n {{ props.loadMoreLabel }}\n </Button>\n </slot>\n </div>\n </ListboxRoot>\n</template>\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ModalContent.js","names":[],"sources":["../../../src/components/modal/ModalContent.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { DialogPortal, DialogContent, injectDialogRootContext } from 'reka-ui'\nimport { motion, AnimatePresence } from 'motion-v'\nimport { modalVariants } from '@auronui/styles/components/modal'\nimport { composeClassName } from '../../utils/composeClassName'\nimport { useModalInject } from './Modal.vue'\nimport ModalOverlay from './ModalOverlay.vue'\n\nconst props = withDefaults(defineProps<{\n as?: string\n asChild?: boolean\n forceMount?: boolean\n disableOutsidePointerEvents?: boolean\n to?: string | HTMLElement\n disabled?: boolean\n defer?: boolean\n class?: string\n}>(), {\n asChild: false,\n forceMount: false,\n disableOutsidePointerEvents: false,\n disabled: false,\n defer: false,\n})\n\nconst emit = defineEmits<{\n 'escape-key-down': [event: KeyboardEvent]\n 'pointer-down-outside': [event: Event]\n 'interact-outside': [event: Event]\n 'open-auto-focus': [event: Event]\n 'close-auto-focus': [event: Event]\n 'focus-outside': [event: Event]\n}>()\n\n// Inject context from Modal root\nconst ctx = useModalInject({ size: 'md', scroll: 'inside', variant: 'opaque', placement: 'auto' })\n\n// Inject Reka's dialog root context to read open state for AnimatePresence\nconst dialogRootContext = injectDialogRootContext()\n\nconst styles = modalVariants()\n</script>\n\n<template>\n <DialogPortal :to=\"props.to\" :disabled=\"props.disabled\" :defer=\"props.defer\" :force-mount=\"props.forceMount\">\n <div class=\"
|
|
1
|
+
{"version":3,"file":"ModalContent.js","names":[],"sources":["../../../src/components/modal/ModalContent.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { DialogPortal, DialogContent, injectDialogRootContext } from 'reka-ui'\nimport { motion, AnimatePresence } from 'motion-v'\nimport { modalVariants } from '@auronui/styles/components/modal'\nimport { composeClassName } from '../../utils/composeClassName'\nimport { useModalInject } from './Modal.vue'\nimport ModalOverlay from './ModalOverlay.vue'\n\nconst props = withDefaults(defineProps<{\n as?: string\n asChild?: boolean\n forceMount?: boolean\n disableOutsidePointerEvents?: boolean\n to?: string | HTMLElement\n disabled?: boolean\n defer?: boolean\n class?: string\n}>(), {\n asChild: false,\n forceMount: false,\n disableOutsidePointerEvents: false,\n disabled: false,\n defer: false,\n})\n\nconst emit = defineEmits<{\n 'escape-key-down': [event: KeyboardEvent]\n 'pointer-down-outside': [event: Event]\n 'interact-outside': [event: Event]\n 'open-auto-focus': [event: Event]\n 'close-auto-focus': [event: Event]\n 'focus-outside': [event: Event]\n}>()\n\n// Inject context from Modal root\nconst ctx = useModalInject({ size: 'md', scroll: 'inside', variant: 'opaque', placement: 'auto' })\n\n// Inject Reka's dialog root context to read open state for AnimatePresence\nconst dialogRootContext = injectDialogRootContext()\n\nconst styles = modalVariants()\n</script>\n\n<template>\n <DialogPortal :to=\"props.to\" :disabled=\"props.disabled\" :defer=\"props.defer\" :force-mount=\"props.forceMount\">\n <div :class=\"styles.portal()\">\n <ModalOverlay />\n <DialogContent\n :as=\"props.as\"\n :as-child=\"props.asChild\"\n :force-mount=\"props.forceMount\"\n :disable-outside-pointer-events=\"props.disableOutsidePointerEvents\"\n :class=\"composeClassName(styles.container({ scroll: ctx.scroll }), props.class)\"\n :data-placement=\"ctx.placement\"\n :aria-hidden=\"!dialogRootContext.open.value || undefined\"\n @escape-key-down=\"emit('escape-key-down', $event)\"\n @pointer-down-outside=\"emit('pointer-down-outside', $event)\"\n @interact-outside=\"emit('interact-outside', $event)\"\n @open-auto-focus=\"emit('open-auto-focus', $event)\"\n @close-auto-focus=\"emit('close-auto-focus', $event)\"\n @focus-outside=\"emit('focus-outside', $event)\"\n >\n <AnimatePresence>\n <motion.div\n v-if=\"dialogRootContext.open.value\"\n :class=\"composeClassName(styles.dialog({ size: ctx.size, scroll: ctx.scroll }), 'modal-content-inner')\"\n :data-placement=\"ctx.placement\"\n :initial=\"{ opacity: 0, scale: 0.95, y: -10 }\"\n :animate=\"{ opacity: 1, scale: 1, y: 0 }\"\n :exit=\"{ opacity: 0, scale: 0.95, y: -10 }\"\n :transition=\"{ duration: 0.2, ease: 'easeOut' }\"\n >\n <slot />\n </motion.div>\n </AnimatePresence>\n </DialogContent>\n </div>\n </DialogPortal>\n</template>\n"],"mappings":""}
|
|
@@ -7,7 +7,6 @@ import ModalOverlay_default from "./ModalOverlay.js";
|
|
|
7
7
|
import { createBlock, createCommentVNode, createElementVNode, createVNode, defineComponent, normalizeClass, openBlock, renderSlot, unref, withCtx } from "vue";
|
|
8
8
|
import { DialogContent, DialogPortal, injectDialogRootContext } from "reka-ui";
|
|
9
9
|
//#region src/components/modal/ModalContent.vue?vue&type=script&setup=true&lang.ts
|
|
10
|
-
var _hoisted_1 = { class: "modal__portal" };
|
|
11
10
|
var ModalContent_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
|
|
12
11
|
__name: "ModalContent",
|
|
13
12
|
props: {
|
|
@@ -61,7 +60,7 @@ var ModalContent_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ d
|
|
|
61
60
|
defer: props.defer,
|
|
62
61
|
"force-mount": props.forceMount
|
|
63
62
|
}, {
|
|
64
|
-
default: withCtx(() => [createElementVNode("div",
|
|
63
|
+
default: withCtx(() => [createElementVNode("div", { class: normalizeClass(unref(styles).portal()) }, [createVNode(ModalOverlay_default), createVNode(unref(DialogContent), {
|
|
65
64
|
as: props.as,
|
|
66
65
|
"as-child": props.asChild,
|
|
67
66
|
"force-mount": props.forceMount,
|
|
@@ -118,7 +117,7 @@ var ModalContent_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ d
|
|
|
118
117
|
"class",
|
|
119
118
|
"data-placement",
|
|
120
119
|
"aria-hidden"
|
|
121
|
-
])])]),
|
|
120
|
+
])], 2)]),
|
|
122
121
|
_: 3
|
|
123
122
|
}, 8, [
|
|
124
123
|
"to",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ModalContent.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/modal/ModalContent.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { DialogPortal, DialogContent, injectDialogRootContext } from 'reka-ui'\nimport { motion, AnimatePresence } from 'motion-v'\nimport { modalVariants } from '@auronui/styles/components/modal'\nimport { composeClassName } from '../../utils/composeClassName'\nimport { useModalInject } from './Modal.vue'\nimport ModalOverlay from './ModalOverlay.vue'\n\nconst props = withDefaults(defineProps<{\n as?: string\n asChild?: boolean\n forceMount?: boolean\n disableOutsidePointerEvents?: boolean\n to?: string | HTMLElement\n disabled?: boolean\n defer?: boolean\n class?: string\n}>(), {\n asChild: false,\n forceMount: false,\n disableOutsidePointerEvents: false,\n disabled: false,\n defer: false,\n})\n\nconst emit = defineEmits<{\n 'escape-key-down': [event: KeyboardEvent]\n 'pointer-down-outside': [event: Event]\n 'interact-outside': [event: Event]\n 'open-auto-focus': [event: Event]\n 'close-auto-focus': [event: Event]\n 'focus-outside': [event: Event]\n}>()\n\n// Inject context from Modal root\nconst ctx = useModalInject({ size: 'md', scroll: 'inside', variant: 'opaque', placement: 'auto' })\n\n// Inject Reka's dialog root context to read open state for AnimatePresence\nconst dialogRootContext = injectDialogRootContext()\n\nconst styles = modalVariants()\n</script>\n\n<template>\n <DialogPortal :to=\"props.to\" :disabled=\"props.disabled\" :defer=\"props.defer\" :force-mount=\"props.forceMount\">\n <div class=\"
|
|
1
|
+
{"version":3,"file":"ModalContent.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/modal/ModalContent.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { DialogPortal, DialogContent, injectDialogRootContext } from 'reka-ui'\nimport { motion, AnimatePresence } from 'motion-v'\nimport { modalVariants } from '@auronui/styles/components/modal'\nimport { composeClassName } from '../../utils/composeClassName'\nimport { useModalInject } from './Modal.vue'\nimport ModalOverlay from './ModalOverlay.vue'\n\nconst props = withDefaults(defineProps<{\n as?: string\n asChild?: boolean\n forceMount?: boolean\n disableOutsidePointerEvents?: boolean\n to?: string | HTMLElement\n disabled?: boolean\n defer?: boolean\n class?: string\n}>(), {\n asChild: false,\n forceMount: false,\n disableOutsidePointerEvents: false,\n disabled: false,\n defer: false,\n})\n\nconst emit = defineEmits<{\n 'escape-key-down': [event: KeyboardEvent]\n 'pointer-down-outside': [event: Event]\n 'interact-outside': [event: Event]\n 'open-auto-focus': [event: Event]\n 'close-auto-focus': [event: Event]\n 'focus-outside': [event: Event]\n}>()\n\n// Inject context from Modal root\nconst ctx = useModalInject({ size: 'md', scroll: 'inside', variant: 'opaque', placement: 'auto' })\n\n// Inject Reka's dialog root context to read open state for AnimatePresence\nconst dialogRootContext = injectDialogRootContext()\n\nconst styles = modalVariants()\n</script>\n\n<template>\n <DialogPortal :to=\"props.to\" :disabled=\"props.disabled\" :defer=\"props.defer\" :force-mount=\"props.forceMount\">\n <div :class=\"styles.portal()\">\n <ModalOverlay />\n <DialogContent\n :as=\"props.as\"\n :as-child=\"props.asChild\"\n :force-mount=\"props.forceMount\"\n :disable-outside-pointer-events=\"props.disableOutsidePointerEvents\"\n :class=\"composeClassName(styles.container({ scroll: ctx.scroll }), props.class)\"\n :data-placement=\"ctx.placement\"\n :aria-hidden=\"!dialogRootContext.open.value || undefined\"\n @escape-key-down=\"emit('escape-key-down', $event)\"\n @pointer-down-outside=\"emit('pointer-down-outside', $event)\"\n @interact-outside=\"emit('interact-outside', $event)\"\n @open-auto-focus=\"emit('open-auto-focus', $event)\"\n @close-auto-focus=\"emit('close-auto-focus', $event)\"\n @focus-outside=\"emit('focus-outside', $event)\"\n >\n <AnimatePresence>\n <motion.div\n v-if=\"dialogRootContext.open.value\"\n :class=\"composeClassName(styles.dialog({ size: ctx.size, scroll: ctx.scroll }), 'modal-content-inner')\"\n :data-placement=\"ctx.placement\"\n :initial=\"{ opacity: 0, scale: 0.95, y: -10 }\"\n :animate=\"{ opacity: 1, scale: 1, y: 0 }\"\n :exit=\"{ opacity: 0, scale: 0.95, y: -10 }\"\n :transition=\"{ duration: 0.2, ease: 'easeOut' }\"\n >\n <slot />\n </motion.div>\n </AnimatePresence>\n </DialogContent>\n </div>\n </DialogPortal>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAQA,MAAM,QAAQ;EAiBd,MAAM,OAAO;EAUb,MAAM,MAAM,eAAe;GAAE,MAAM;GAAM,QAAQ;GAAU,SAAS;GAAU,WAAW;GAAQ,CAAA;EAGjG,MAAM,oBAAoB,yBAAwB;EAElD,MAAM,SAAS,eAAc;;uBAI3B,YAiCe,MAAA,aAAA,EAAA;IAjCA,IAAI,MAAM;IAAK,UAAU,MAAM;IAAW,OAAO,MAAM;IAAQ,eAAa,MAAM;;2BAgCzF,CA/BN,mBA+BM,OAAA,EA/BA,OAAK,eAAE,MAAA,OAAM,CAAC,QAAM,CAAA,EAAA,EAAA,CAC1B,YAAgB,qBAAA,EAChB,YA4BgB,MAAA,cAAA,EAAA;KA3Bb,IAAI,MAAM;KACV,YAAU,MAAM;KAChB,eAAa,MAAM;KACnB,kCAAgC,MAAM;KACtC,OAAK,eAAE,MAAA,iBAAgB,CAAC,MAAA,OAAM,CAAC,UAAS,EAAA,QAAW,MAAA,IAAG,CAAC,QAAM,CAAA,EAAK,MAAM,MAAK,CAAA;KAC7E,kBAAgB,MAAA,IAAG,CAAC;KACpB,eAAW,CAAG,MAAA,kBAAiB,CAAC,KAAK,SAAS,KAAA;KAC9C,iBAAe,OAAA,OAAA,OAAA,MAAA,WAAE,KAAI,mBAAoB,OAAM;KAC/C,sBAAoB,OAAA,OAAA,OAAA,MAAA,WAAE,KAAI,wBAAyB,OAAM;KACzD,mBAAgB,OAAA,OAAA,OAAA,MAAA,WAAE,KAAI,oBAAqB,OAAM;KACjD,iBAAe,OAAA,OAAA,OAAA,MAAA,WAAE,KAAI,mBAAoB,OAAM;KAC/C,kBAAgB,OAAA,OAAA,OAAA,MAAA,WAAE,KAAI,oBAAqB,OAAM;KACjD,gBAAa,OAAA,OAAA,OAAA,MAAA,WAAE,KAAI,iBAAkB,OAAM;;4BAc1B,CAZlB,YAYkB,MAAA,wBAAA,EAAA,MAAA;6BADH,CATL,MAAA,kBAAiB,CAAC,KAAK,SAAA,WAAA,EAD/B,YAUa,MAAA,OAAA,CAAA,KAAA;;OARV,OAAK,eAAE,MAAA,iBAAgB,CAAC,MAAA,OAAM,CAAC,OAAM;QAAA,MAAS,MAAA,IAAG,CAAC;QAAI,QAAU,MAAA,IAAG,CAAC;QAAM,CAAA,EAAA,sBAAA,CAAA;OAC1E,kBAAgB,MAAA,IAAG,CAAC;OACpB,SAAS;QAAA,SAAA;QAAA,OAAA;QAAA,GAAA;QAAmC;OAC5C,SAAS;QAAA,SAAA;QAAA,OAAA;QAAA,GAAA;QAA8B;OACvC,MAAM;QAAA,SAAA;QAAA,OAAA;QAAA,GAAA;QAAmC;OACzC,YAAY;QAAA,UAAA;QAAA,MAAA;QAAkC;;8BAEvC,CAAR,WAAQ,KAAA,QAAA,UAAA,CAAA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RadioGroup.js","names":[],"sources":["../../../src/components/radio/RadioGroup.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, toRef } from 'vue'\nimport { RadioGroupRoot } from 'reka-ui'\nimport { radioGroupVariants, type RadioGroupVariants } from '@auronui/styles'\nimport { composeClassName } from '../../utils/composeClassName'\nimport { useRadioGroupProvide } from './radio-group.context'\nimport Radio from './Radio.vue'\nimport { useDeprecatedBooleanProp } from '../../composables/useDeprecatedBooleanProp'\n\ntype RadioShorthandItem = {
|
|
1
|
+
{"version":3,"file":"RadioGroup.js","names":[],"sources":["../../../src/components/radio/RadioGroup.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, toRef } from 'vue'\nimport { RadioGroupRoot } from 'reka-ui'\nimport { radioGroupVariants, type RadioGroupVariants } from '@auronui/styles'\nimport { composeClassName , type ClassValue} from '../../utils/composeClassName'\nimport { useRadioGroupProvide } from './radio-group.context'\nimport Radio from './Radio.vue'\nimport { useDeprecatedBooleanProp } from '../../composables/useDeprecatedBooleanProp'\n\ntype RadioShorthandItem = {\n value: string\n label?: string\n disabled?: boolean\n class?: ClassValue\n classNames?: Partial<{\n base: ClassValue\n control: ClassValue\n indicator: ClassValue\n content: ClassValue\n }>\n}\n\nconst props = withDefaults(defineProps<{\n variant?: RadioGroupVariants['variant']\n isDisabled?: boolean\n /** @deprecated Use isDisabled instead. */\n disabled?: boolean\n isInvalid?: boolean\n modelValue?: string\n defaultValue?: string\n name?: string\n orientation?: 'horizontal' | 'vertical'\n label?: string\n description?: string\n errorMessage?: string\n /** Text direction forwarded to RadioGroupRoot. */\n dir?: 'ltr' | 'rtl'\n /** Whether keyboard navigation loops from last to first item. */\n loop?: boolean\n /** Whether RadioGroupRoot renders as a child element. */\n asChild?: boolean\n /** Element or component to render RadioGroupRoot as. */\n as?: string\n isRequired?: boolean\n /**\n * Whether the radio group is required.\n * @deprecated Use isRequired instead.\n */\n required?: boolean\n class?: string\n /** Shorthand API: render radio options from an array instead of the compound slot API */\n items?: RadioShorthandItem[]\n /** Per-slot class overrides */\n classNames?: Partial<{\n label: ClassValue\n wrapper: ClassValue\n description: ClassValue\n errorMessage: ClassValue\n /** Applied to every shorthand-rendered Radio, before any per-item override */\n radio: Partial<{\n base: ClassValue\n control: ClassValue\n indicator: ClassValue\n content: ClassValue\n }>\n }>\n}>(), {\n variant: 'primary',\n isDisabled: undefined,\n disabled: undefined,\n isInvalid: false,\n modelValue: undefined,\n defaultValue: undefined,\n name: undefined,\n orientation: 'vertical',\n label: undefined,\n description: undefined,\n errorMessage: undefined,\n dir: undefined,\n loop: true,\n asChild: false,\n as: undefined,\n isRequired: undefined,\n required: undefined,\n})\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string]\n}>()\n\nconst isDisabled = useDeprecatedBooleanProp(\n 'RadioGroup', 'isDisabled', () => props.isDisabled, 'disabled', () => props.disabled,\n)\n\nconst isRequired = useDeprecatedBooleanProp(\n 'RadioGroup', 'isRequired', () => props.isRequired, 'required', () => props.required,\n)\n\n// Provide context to child Radio components\nuseRadioGroupProvide({\n variant: toRef(props, 'variant'),\n disabled: isDisabled,\n isInvalid: toRef(props, 'isInvalid'),\n})\n\nconst labelId = `radio-group-label-${Math.random().toString(36).slice(2, 8)}`\n\nconst slotFns = computed(() =>\n radioGroupVariants({ variant: props.variant })\n)\n\n// Group-wide radio classNames apply first; per-item classNames win on conflict.\nfunction itemClassNames(item: RadioShorthandItem) {\n return {\n base: composeClassName(props.classNames?.radio?.base, item.classNames?.base),\n control: composeClassName(props.classNames?.radio?.control, item.classNames?.control),\n indicator: composeClassName(props.classNames?.radio?.indicator, item.classNames?.indicator),\n content: composeClassName(props.classNames?.radio?.content, item.classNames?.content),\n }\n}\n</script>\n\n<template>\n <RadioGroupRoot\n :model-value=\"props.modelValue\"\n :default-value=\"props.defaultValue\"\n :disabled=\"isDisabled\"\n :aria-invalid=\"props.isInvalid || undefined\"\n :name=\"props.name\"\n :orientation=\"props.orientation\"\n :dir=\"props.dir\"\n :loop=\"props.loop\"\n :as-child=\"props.asChild\"\n :as=\"props.as\"\n :required=\"isRequired\"\n :aria-labelledby=\"props.label ? labelId : undefined\"\n :class=\"composeClassName(slotFns.base(), props.class)\"\n @update:model-value=\"$event != null && emit('update:modelValue', String($event))\"\n >\n <span\n v-if=\"props.label\"\n :id=\"labelId\"\n :class=\"composeClassName(slotFns.label(), props.classNames?.label)\"\n >{{ props.label }}</span>\n <div :class=\"composeClassName(slotFns.wrapper(), props.classNames?.wrapper)\">\n <template v-if=\"props.items\">\n <Radio\n v-for=\"item in props.items\"\n :key=\"item.value\"\n :value=\"item.value\"\n :is-disabled=\"item.disabled\"\n :class=\"item.class\"\n :class-names=\"itemClassNames(item)\"\n >{{ item.label ?? item.value }}</Radio>\n </template>\n <slot v-else />\n </div>\n <span\n v-if=\"props.isInvalid && props.errorMessage\"\n :class=\"composeClassName(slotFns.errorMessage(), props.classNames?.errorMessage)\"\n >{{ props.errorMessage }}</span>\n <span\n v-else-if=\"props.description\"\n :class=\"composeClassName(slotFns.description(), props.classNames?.description)\"\n >{{ props.description }}</span>\n </RadioGroupRoot>\n</template>\n"],"mappings":""}
|