@ecoma-io/loom 0.1.0 → 0.2.0
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/README.md +54 -57
- package/dist/blocks/AppHeader/AppHeader.js.map +1 -1
- package/dist/blocks/AppHeader/AppHeader.vue.d.ts +5 -6
- package/dist/blocks/AppHeader/AppHeader.vue.d.ts.map +1 -1
- package/dist/blocks/AppHeader/AppHeader.vue_vue_type_script_setup_true_lang.js +6 -7
- package/dist/blocks/AppHeader/AppHeader.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/blocks/DashboardGrid/DashboardGrid.vue.d.ts +1 -1
- package/dist/blocks/DashboardGrid/DashboardGrid.vue.d.ts.map +1 -1
- package/dist/blocks/DesktopAppShell/DesktopAppShell.js +7 -0
- package/dist/blocks/DesktopAppShell/DesktopAppShell.js.map +1 -0
- package/dist/blocks/DesktopAppShell/DesktopAppShell.vue.d.ts +102 -0
- package/dist/blocks/DesktopAppShell/DesktopAppShell.vue.d.ts.map +1 -0
- package/dist/blocks/DesktopAppShell/DesktopAppShell.vue_vue_type_script_setup_true_lang.js +74 -0
- package/dist/blocks/DesktopAppShell/DesktopAppShell.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/blocks/ErrorState/ErrorState.js +7 -0
- package/dist/blocks/ErrorState/ErrorState.js.map +1 -0
- package/dist/blocks/ErrorState/ErrorState.vue.d.ts +44 -0
- package/dist/blocks/ErrorState/ErrorState.vue.d.ts.map +1 -0
- package/dist/blocks/ErrorState/ErrorState.vue_vue_type_script_setup_true_lang.js +60 -0
- package/dist/blocks/ErrorState/ErrorState.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/blocks/FormActions/FormActions.js +7 -0
- package/dist/blocks/FormActions/FormActions.js.map +1 -0
- package/dist/blocks/FormActions/FormActions.vue.d.ts +51 -0
- package/dist/blocks/FormActions/FormActions.vue.d.ts.map +1 -0
- package/dist/blocks/FormActions/FormActions.vue_vue_type_script_setup_true_lang.js +21 -0
- package/dist/blocks/FormActions/FormActions.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/blocks/FormSection/FormSection.js +7 -0
- package/dist/blocks/FormSection/FormSection.js.map +1 -0
- package/dist/blocks/FormSection/FormSection.vue.d.ts +85 -0
- package/dist/blocks/FormSection/FormSection.vue.d.ts.map +1 -0
- package/dist/blocks/FormSection/FormSection.vue_vue_type_script_setup_true_lang.js +62 -0
- package/dist/blocks/FormSection/FormSection.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/blocks/LoadingState/LoadingState.js +7 -0
- package/dist/blocks/LoadingState/LoadingState.js.map +1 -0
- package/dist/blocks/LoadingState/LoadingState.vue.d.ts +22 -0
- package/dist/blocks/LoadingState/LoadingState.vue.d.ts.map +1 -0
- package/dist/blocks/LoadingState/LoadingState.vue_vue_type_script_setup_true_lang.js +57 -0
- package/dist/blocks/LoadingState/LoadingState.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/blocks/MetricCard/MetricCard.js +7 -0
- package/dist/blocks/MetricCard/MetricCard.js.map +1 -0
- package/dist/blocks/MetricCard/MetricCard.vue.d.ts +59 -0
- package/dist/blocks/MetricCard/MetricCard.vue.d.ts.map +1 -0
- package/dist/blocks/MetricCard/MetricCard.vue_vue_type_script_setup_true_lang.js +63 -0
- package/dist/blocks/MetricCard/MetricCard.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/blocks/SidebarNav/SidebarNav.js.map +1 -1
- package/dist/blocks/SidebarNav/SidebarNav.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/blocks/TitleBar/TitleBar.js.map +1 -1
- package/dist/blocks/TitleBar/TitleBar.vue.d.ts +37 -3
- package/dist/blocks/TitleBar/TitleBar.vue.d.ts.map +1 -1
- package/dist/blocks/TitleBar/TitleBar.vue_vue_type_script_setup_true_lang.js +14 -14
- package/dist/blocks/TitleBar/TitleBar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/blocks/ToastStack/ToastStack.js.map +1 -1
- package/dist/blocks/ToastStack/ToastStack.vue.d.ts +20 -0
- package/dist/blocks/ToastStack/ToastStack.vue.d.ts.map +1 -1
- package/dist/blocks/ToastStack/ToastStack.vue_vue_type_script_setup_true_lang.js +16 -5
- package/dist/blocks/ToastStack/ToastStack.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/composition/Center/Center.js +7 -0
- package/dist/composition/Center/Center.js.map +1 -0
- package/dist/composition/Center/Center.vue.d.ts +40 -0
- package/dist/composition/Center/Center.vue.d.ts.map +1 -0
- package/dist/composition/Center/Center.vue_vue_type_script_setup_true_lang.js +29 -0
- package/dist/composition/Center/Center.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/composition/Frame/Frame.js +7 -0
- package/dist/composition/Frame/Frame.js.map +1 -0
- package/dist/composition/Frame/Frame.vue.d.ts +35 -0
- package/dist/composition/Frame/Frame.vue.d.ts.map +1 -0
- package/dist/composition/Frame/Frame.vue_vue_type_script_setup_true_lang.js +29 -0
- package/dist/composition/Frame/Frame.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/composition/Grid/Grid.js +7 -0
- package/dist/composition/Grid/Grid.js.map +1 -0
- package/dist/composition/Grid/Grid.vue.d.ts +41 -0
- package/dist/composition/Grid/Grid.vue.d.ts.map +1 -0
- package/dist/composition/Grid/Grid.vue_vue_type_script_setup_true_lang.js +27 -0
- package/dist/composition/Grid/Grid.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/composition/Inline/Inline.js +7 -0
- package/dist/composition/Inline/Inline.js.map +1 -0
- package/dist/composition/Inline/Inline.vue.d.ts +46 -0
- package/dist/composition/Inline/Inline.vue.d.ts.map +1 -0
- package/dist/composition/Inline/Inline.vue_vue_type_script_setup_true_lang.js +35 -0
- package/dist/composition/Inline/Inline.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/composition/ScrollReel/ScrollReel.js +7 -0
- package/dist/composition/ScrollReel/ScrollReel.js.map +1 -0
- package/dist/composition/ScrollReel/ScrollReel.vue.d.ts +42 -0
- package/dist/composition/ScrollReel/ScrollReel.vue.d.ts.map +1 -0
- package/dist/composition/ScrollReel/ScrollReel.vue_vue_type_script_setup_true_lang.js +79 -0
- package/dist/composition/ScrollReel/ScrollReel.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/composition/Sidebar/Sidebar.js +7 -0
- package/dist/composition/Sidebar/Sidebar.js.map +1 -0
- package/dist/composition/Sidebar/Sidebar.vue.d.ts +52 -0
- package/dist/composition/Sidebar/Sidebar.vue.d.ts.map +1 -0
- package/dist/composition/Sidebar/Sidebar.vue_vue_type_script_setup_true_lang.js +36 -0
- package/dist/composition/Sidebar/Sidebar.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/composition/Split/Split.js +7 -0
- package/dist/composition/Split/Split.js.map +1 -0
- package/dist/composition/Split/Split.vue.d.ts +58 -0
- package/dist/composition/Split/Split.vue.d.ts.map +1 -0
- package/dist/composition/Split/Split.vue_vue_type_script_setup_true_lang.js +40 -0
- package/dist/composition/Split/Split.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/composition/Stack/Stack.js +7 -0
- package/dist/composition/Stack/Stack.js.map +1 -0
- package/dist/composition/Stack/Stack.vue.d.ts +43 -0
- package/dist/composition/Stack/Stack.vue.d.ts.map +1 -0
- package/dist/composition/Stack/Stack.vue_vue_type_script_setup_true_lang.js +30 -0
- package/dist/composition/Stack/Stack.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/index.d.ts +119 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +83 -5
- package/dist/layouts/AppShell/AppShell.js +7 -0
- package/dist/layouts/AppShell/AppShell.js.map +1 -0
- package/dist/layouts/AppShell/AppShell.vue.d.ts +51 -0
- package/dist/layouts/AppShell/AppShell.vue.d.ts.map +1 -0
- package/dist/layouts/AppShell/AppShell.vue_vue_type_script_setup_true_lang.js +47 -0
- package/dist/layouts/AppShell/AppShell.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/layouts/Centered/Centered.js +7 -0
- package/dist/layouts/Centered/Centered.js.map +1 -0
- package/dist/layouts/Centered/Centered.vue.d.ts +48 -0
- package/dist/layouts/Centered/Centered.vue.d.ts.map +1 -0
- package/dist/layouts/Centered/Centered.vue_vue_type_script_setup_true_lang.js +35 -0
- package/dist/layouts/Centered/Centered.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/layouts/Dashboard/Dashboard.js +7 -0
- package/dist/layouts/Dashboard/Dashboard.js.map +1 -0
- package/dist/layouts/Dashboard/Dashboard.vue.d.ts +60 -0
- package/dist/layouts/Dashboard/Dashboard.vue.d.ts.map +1 -0
- package/dist/layouts/Dashboard/Dashboard.vue_vue_type_script_setup_true_lang.js +64 -0
- package/dist/layouts/Dashboard/Dashboard.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/layouts/FormLayout/FormLayout.js +7 -0
- package/dist/layouts/FormLayout/FormLayout.js.map +1 -0
- package/dist/layouts/FormLayout/FormLayout.vue.d.ts +46 -0
- package/dist/layouts/FormLayout/FormLayout.vue.d.ts.map +1 -0
- package/dist/layouts/FormLayout/FormLayout.vue_vue_type_script_setup_true_lang.js +28 -0
- package/dist/layouts/FormLayout/FormLayout.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/layouts/MasterDetail/MasterDetail.js +7 -0
- package/dist/layouts/MasterDetail/MasterDetail.js.map +1 -0
- package/dist/layouts/MasterDetail/MasterDetail.vue.d.ts +49 -0
- package/dist/layouts/MasterDetail/MasterDetail.vue.d.ts.map +1 -0
- package/dist/layouts/MasterDetail/MasterDetail.vue_vue_type_script_setup_true_lang.js +42 -0
- package/dist/layouts/MasterDetail/MasterDetail.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/layouts/Reading/Reading.js +7 -0
- package/dist/layouts/Reading/Reading.js.map +1 -0
- package/dist/layouts/Reading/Reading.vue.d.ts +24 -0
- package/dist/layouts/Reading/Reading.vue.d.ts.map +1 -0
- package/dist/layouts/Reading/Reading.vue_vue_type_script_setup_true_lang.js +29 -0
- package/dist/layouts/Reading/Reading.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/layouts/Settings/Settings.js +7 -0
- package/dist/layouts/Settings/Settings.js.map +1 -0
- package/dist/layouts/Settings/Settings.vue.d.ts +39 -0
- package/dist/layouts/Settings/Settings.vue.d.ts.map +1 -0
- package/dist/layouts/Settings/Settings.vue_vue_type_script_setup_true_lang.js +35 -0
- package/dist/layouts/Settings/Settings.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/layouts/SplitLayout/SplitLayout.js +7 -0
- package/dist/layouts/SplitLayout/SplitLayout.js.map +1 -0
- package/dist/layouts/SplitLayout/SplitLayout.vue.d.ts +63 -0
- package/dist/layouts/SplitLayout/SplitLayout.vue.d.ts.map +1 -0
- package/dist/layouts/SplitLayout/SplitLayout.vue_vue_type_script_setup_true_lang.js +46 -0
- package/dist/layouts/SplitLayout/SplitLayout.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/lib/ancestor-disabled.d.ts +35 -0
- package/dist/lib/ancestor-disabled.d.ts.map +1 -0
- package/dist/lib/ancestor-disabled.js +86 -0
- package/dist/lib/ancestor-disabled.js.map +1 -0
- package/dist/lib/cn.d.ts.map +1 -1
- package/dist/lib/cn.js +46 -1
- package/dist/lib/cn.js.map +1 -1
- package/dist/lib/count-labels.d.ts +78 -0
- package/dist/lib/count-labels.d.ts.map +1 -0
- package/dist/lib/count-labels.js +29 -0
- package/dist/lib/count-labels.js.map +1 -0
- package/dist/lib/date-labels.d.ts +278 -0
- package/dist/lib/date-labels.d.ts.map +1 -0
- package/dist/lib/date-labels.js +157 -0
- package/dist/lib/date-labels.js.map +1 -0
- package/dist/lib/field-context.d.ts +178 -0
- package/dist/lib/field-context.d.ts.map +1 -0
- package/dist/lib/field-context.js +106 -0
- package/dist/lib/field-context.js.map +1 -0
- package/dist/lib/label-registry.d.ts +75 -0
- package/dist/lib/label-registry.d.ts.map +1 -0
- package/dist/lib/labels.d.ts +116 -0
- package/dist/lib/labels.d.ts.map +1 -0
- package/dist/lib/labels.js +84 -0
- package/dist/lib/labels.js.map +1 -0
- package/dist/lib/theme.d.ts +68 -0
- package/dist/lib/theme.d.ts.map +1 -0
- package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/CalendarDate.js +236 -0
- package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/CalendarDate.js.map +1 -0
- package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/calendars/GregorianCalendar.js +117 -0
- package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/calendars/GregorianCalendar.js.map +1 -0
- package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/conversion.js +142 -0
- package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/conversion.js.map +1 -0
- package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/manipulation.js +280 -0
- package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/manipulation.js.map +1 -0
- package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/queries.js +40 -0
- package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/queries.js.map +1 -0
- package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/string.js +69 -0
- package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/string.js.map +1 -0
- package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/utils.js +8 -0
- package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/utils.js.map +1 -0
- package/dist/primitives/Accordion/Accordion.js +7 -0
- package/dist/primitives/Accordion/Accordion.js.map +1 -0
- package/dist/primitives/Accordion/Accordion.vue.d.ts +68 -0
- package/dist/primitives/Accordion/Accordion.vue.d.ts.map +1 -0
- package/dist/primitives/Accordion/Accordion.vue_vue_type_script_setup_true_lang.js +67 -0
- package/dist/primitives/Accordion/Accordion.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/AlertDialog/AlertDialog.js +7 -0
- package/dist/primitives/AlertDialog/AlertDialog.js.map +1 -0
- package/dist/primitives/AlertDialog/AlertDialog.vue.d.ts +94 -0
- package/dist/primitives/AlertDialog/AlertDialog.vue.d.ts.map +1 -0
- package/dist/primitives/AlertDialog/AlertDialog.vue_vue_type_script_setup_true_lang.js +99 -0
- package/dist/primitives/AlertDialog/AlertDialog.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/Avatar/Avatar.js +2 -2
- package/dist/primitives/Avatar/Avatar.js.map +1 -1
- package/dist/primitives/Avatar/Avatar.vue.d.ts +30 -3
- package/dist/primitives/Avatar/Avatar.vue.d.ts.map +1 -1
- package/dist/primitives/Avatar/Avatar.vue_vue_type_script_setup_true_lang.js +95 -14
- package/dist/primitives/Avatar/Avatar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/primitives/AvatarGroup/AvatarGroup.js +7 -0
- package/dist/primitives/AvatarGroup/AvatarGroup.js.map +1 -0
- package/dist/primitives/AvatarGroup/AvatarGroup.vue.d.ts +104 -0
- package/dist/primitives/AvatarGroup/AvatarGroup.vue.d.ts.map +1 -0
- package/dist/primitives/AvatarGroup/AvatarGroup.vue_vue_type_script_setup_true_lang.js +139 -0
- package/dist/primitives/AvatarGroup/AvatarGroup.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/Badge/Badge.js.map +1 -1
- package/dist/primitives/Badge/Badge.vue.d.ts +6 -6
- package/dist/primitives/Badge/Badge.vue.d.ts.map +1 -1
- package/dist/primitives/Badge/Badge.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/primitives/Badge/Badge.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/primitives/Breadcrumb/Breadcrumb.js +7 -0
- package/dist/primitives/Breadcrumb/Breadcrumb.js.map +1 -0
- package/dist/primitives/Breadcrumb/Breadcrumb.vue.d.ts +25 -0
- package/dist/primitives/Breadcrumb/Breadcrumb.vue.d.ts.map +1 -0
- package/dist/primitives/Breadcrumb/Breadcrumb.vue_vue_type_script_setup_true_lang.js +48 -0
- package/dist/primitives/Breadcrumb/Breadcrumb.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/Button/Button.js +2 -2
- package/dist/primitives/Button/Button.js.map +1 -1
- package/dist/primitives/Button/Button.vue.d.ts +31 -8
- package/dist/primitives/Button/Button.vue.d.ts.map +1 -1
- package/dist/primitives/Button/Button.vue_vue_type_script_setup_true_lang.js +32 -16
- package/dist/primitives/Button/Button.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/primitives/Checkbox/Checkbox.js.map +1 -1
- package/dist/primitives/Checkbox/Checkbox.vue.d.ts +18 -3
- package/dist/primitives/Checkbox/Checkbox.vue.d.ts.map +1 -1
- package/dist/primitives/Checkbox/Checkbox.vue_vue_type_script_setup_true_lang.js +46 -7
- package/dist/primitives/Checkbox/Checkbox.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/primitives/Chip/Chip.js +7 -0
- package/dist/primitives/Chip/Chip.js.map +1 -0
- package/dist/primitives/Chip/Chip.vue.d.ts +79 -0
- package/dist/primitives/Chip/Chip.vue.d.ts.map +1 -0
- package/dist/primitives/Chip/Chip.vue_vue_type_script_setup_true_lang.js +139 -0
- package/dist/primitives/Chip/Chip.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/ColorPicker/ColorPicker.js +7 -0
- package/dist/primitives/ColorPicker/ColorPicker.js.map +1 -0
- package/dist/primitives/ColorPicker/ColorPicker.vue.d.ts +125 -0
- package/dist/primitives/ColorPicker/ColorPicker.vue.d.ts.map +1 -0
- package/dist/primitives/ColorPicker/ColorPicker.vue_vue_type_script_setup_true_lang.js +301 -0
- package/dist/primitives/ColorPicker/ColorPicker.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/Combobox/Combobox.js +7 -0
- package/dist/primitives/Combobox/Combobox.js.map +1 -0
- package/dist/primitives/Combobox/Combobox.vue.d.ts +205 -0
- package/dist/primitives/Combobox/Combobox.vue.d.ts.map +1 -0
- package/dist/primitives/Combobox/Combobox.vue_vue_type_script_setup_true_lang.js +345 -0
- package/dist/primitives/Combobox/Combobox.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/ContextMenu/ContextMenu.js +7 -0
- package/dist/primitives/ContextMenu/ContextMenu.js.map +1 -0
- package/dist/primitives/ContextMenu/ContextMenu.vue.d.ts +55 -0
- package/dist/primitives/ContextMenu/ContextMenu.vue.d.ts.map +1 -0
- package/dist/primitives/ContextMenu/ContextMenu.vue_vue_type_script_setup_true_lang.js +82 -0
- package/dist/primitives/ContextMenu/ContextMenu.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/DatePicker/DatePicker.js +7 -0
- package/dist/primitives/DatePicker/DatePicker.js.map +1 -0
- package/dist/primitives/DatePicker/DatePicker.vue.d.ts +102 -0
- package/dist/primitives/DatePicker/DatePicker.vue.d.ts.map +1 -0
- package/dist/primitives/DatePicker/DatePicker.vue_vue_type_script_setup_true_lang.js +292 -0
- package/dist/primitives/DatePicker/DatePicker.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/DateRangePicker/DateRangePicker.js +7 -0
- package/dist/primitives/DateRangePicker/DateRangePicker.js.map +1 -0
- package/dist/primitives/DateRangePicker/DateRangePicker.vue.d.ts +173 -0
- package/dist/primitives/DateRangePicker/DateRangePicker.vue.d.ts.map +1 -0
- package/dist/primitives/DateRangePicker/DateRangePicker.vue_vue_type_script_setup_true_lang.js +412 -0
- package/dist/primitives/DateRangePicker/DateRangePicker.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/DateTimePicker/DateTimePicker.js +7 -0
- package/dist/primitives/DateTimePicker/DateTimePicker.js.map +1 -0
- package/dist/primitives/DateTimePicker/DateTimePicker.vue.d.ts +113 -0
- package/dist/primitives/DateTimePicker/DateTimePicker.vue.d.ts.map +1 -0
- package/dist/primitives/DateTimePicker/DateTimePicker.vue_vue_type_script_setup_true_lang.js +358 -0
- package/dist/primitives/DateTimePicker/DateTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/DateTimeRangePicker/DateTimeRangePicker.js +7 -0
- package/dist/primitives/DateTimeRangePicker/DateTimeRangePicker.js.map +1 -0
- package/dist/primitives/DateTimeRangePicker/DateTimeRangePicker.vue.d.ts +181 -0
- package/dist/primitives/DateTimeRangePicker/DateTimeRangePicker.vue.d.ts.map +1 -0
- package/dist/primitives/DateTimeRangePicker/DateTimeRangePicker.vue_vue_type_script_setup_true_lang.js +562 -0
- package/dist/primitives/DateTimeRangePicker/DateTimeRangePicker.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/Dialog/Dialog.js +2 -2
- package/dist/primitives/Dialog/Dialog.js.map +1 -1
- package/dist/primitives/Dialog/Dialog.vue.d.ts +39 -0
- package/dist/primitives/Dialog/Dialog.vue.d.ts.map +1 -1
- package/dist/primitives/Dialog/Dialog.vue_vue_type_script_setup_true_lang.js +14 -5
- package/dist/primitives/Dialog/Dialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/primitives/Drawer/Drawer.js +7 -0
- package/dist/primitives/Drawer/Drawer.js.map +1 -0
- package/dist/primitives/Drawer/Drawer.vue.d.ts +110 -0
- package/dist/primitives/Drawer/Drawer.vue.d.ts.map +1 -0
- package/dist/primitives/Drawer/Drawer.vue_vue_type_script_setup_true_lang.js +223 -0
- package/dist/primitives/Drawer/Drawer.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/DropdownMenu/DropdownMenu.js.map +1 -1
- package/dist/primitives/DropdownMenu/DropdownMenu.vue.d.ts.map +1 -1
- package/dist/primitives/DropdownMenu/DropdownMenu.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/primitives/DropdownMenu/DropdownMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/primitives/Editable/Editable.js +7 -0
- package/dist/primitives/Editable/Editable.js.map +1 -0
- package/dist/primitives/Editable/Editable.vue.d.ts +200 -0
- package/dist/primitives/Editable/Editable.vue.d.ts.map +1 -0
- package/dist/primitives/Editable/Editable.vue_vue_type_script_setup_true_lang.js +275 -0
- package/dist/primitives/Editable/Editable.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/Field/Field.js.map +1 -1
- package/dist/primitives/Field/Field.vue.d.ts +32 -17
- package/dist/primitives/Field/Field.vue.d.ts.map +1 -1
- package/dist/primitives/Field/Field.vue_vue_type_script_setup_true_lang.js +51 -18
- package/dist/primitives/Field/Field.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/primitives/Fieldset/Fieldset.js +7 -0
- package/dist/primitives/Fieldset/Fieldset.js.map +1 -0
- package/dist/primitives/Fieldset/Fieldset.vue.d.ts +91 -0
- package/dist/primitives/Fieldset/Fieldset.vue.d.ts.map +1 -0
- package/dist/primitives/Fieldset/Fieldset.vue_vue_type_script_setup_true_lang.js +138 -0
- package/dist/primitives/Fieldset/Fieldset.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/FileUpload/FileUpload.js +7 -0
- package/dist/primitives/FileUpload/FileUpload.js.map +1 -0
- package/dist/primitives/FileUpload/FileUpload.vue.d.ts +132 -0
- package/dist/primitives/FileUpload/FileUpload.vue.d.ts.map +1 -0
- package/dist/primitives/FileUpload/FileUpload.vue_vue_type_script_setup_true_lang.js +359 -0
- package/dist/primitives/FileUpload/FileUpload.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/HoverCard/HoverCard.js +7 -0
- package/dist/primitives/HoverCard/HoverCard.js.map +1 -0
- package/dist/primitives/HoverCard/HoverCard.vue.d.ts +68 -0
- package/dist/primitives/HoverCard/HoverCard.vue.d.ts.map +1 -0
- package/dist/primitives/HoverCard/HoverCard.vue_vue_type_script_setup_true_lang.js +62 -0
- package/dist/primitives/HoverCard/HoverCard.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/IconButton/IconButton.js +7 -0
- package/dist/primitives/IconButton/IconButton.js.map +1 -0
- package/dist/primitives/IconButton/IconButton.vue.d.ts +45 -0
- package/dist/primitives/IconButton/IconButton.vue.d.ts.map +1 -0
- package/dist/primitives/IconButton/IconButton.vue_vue_type_script_setup_true_lang.js +58 -0
- package/dist/primitives/IconButton/IconButton.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/Indicator/Indicator.js +7 -0
- package/dist/primitives/Indicator/Indicator.js.map +1 -0
- package/dist/primitives/Indicator/Indicator.vue.d.ts +144 -0
- package/dist/primitives/Indicator/Indicator.vue.d.ts.map +1 -0
- package/dist/primitives/Indicator/Indicator.vue_vue_type_script_setup_true_lang.js +198 -0
- package/dist/primitives/Indicator/Indicator.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/Link/Link.js +7 -0
- package/dist/primitives/Link/Link.js.map +1 -0
- package/dist/primitives/Link/Link.vue.d.ts +46 -0
- package/dist/primitives/Link/Link.vue.d.ts.map +1 -0
- package/dist/primitives/Link/Link.vue_vue_type_script_setup_true_lang.js +85 -0
- package/dist/primitives/Link/Link.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/Menubar/Menubar.js.map +1 -1
- package/dist/primitives/Menubar/Menubar.vue.d.ts.map +1 -1
- package/dist/primitives/Menubar/Menubar.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/primitives/Menubar/Menubar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/primitives/NumberField/NumberField.js +2 -2
- package/dist/primitives/NumberField/NumberField.js.map +1 -1
- package/dist/primitives/NumberField/NumberField.vue.d.ts +86 -25
- package/dist/primitives/NumberField/NumberField.vue.d.ts.map +1 -1
- package/dist/primitives/NumberField/NumberField.vue_vue_type_script_setup_true_lang.js +83 -39
- package/dist/primitives/NumberField/NumberField.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/primitives/OtpInput/OtpInput.js +7 -0
- package/dist/primitives/OtpInput/OtpInput.js.map +1 -0
- package/dist/primitives/OtpInput/OtpInput.vue.d.ts +110 -0
- package/dist/primitives/OtpInput/OtpInput.vue.d.ts.map +1 -0
- package/dist/primitives/OtpInput/OtpInput.vue_vue_type_script_setup_true_lang.js +130 -0
- package/dist/primitives/OtpInput/OtpInput.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/Pagination/Pagination.js +7 -0
- package/dist/primitives/Pagination/Pagination.js.map +1 -0
- package/dist/primitives/Pagination/Pagination.vue.d.ts +143 -0
- package/dist/primitives/Pagination/Pagination.vue.d.ts.map +1 -0
- package/dist/primitives/Pagination/Pagination.vue_vue_type_script_setup_true_lang.js +231 -0
- package/dist/primitives/Pagination/Pagination.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/Progress/Progress.js +2 -2
- package/dist/primitives/Progress/Progress.js.map +1 -1
- package/dist/primitives/Progress/Progress.vue.d.ts +81 -15
- package/dist/primitives/Progress/Progress.vue.d.ts.map +1 -1
- package/dist/primitives/Progress/Progress.vue_vue_type_script_setup_true_lang.js +88 -22
- package/dist/primitives/Progress/Progress.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/primitives/RadialProgress/RadialProgress.js +7 -0
- package/dist/primitives/RadialProgress/RadialProgress.js.map +1 -0
- package/dist/primitives/RadialProgress/RadialProgress.vue.d.ts +96 -0
- package/dist/primitives/RadialProgress/RadialProgress.vue.d.ts.map +1 -0
- package/dist/primitives/RadialProgress/RadialProgress.vue_vue_type_script_setup_true_lang.js +189 -0
- package/dist/primitives/RadialProgress/RadialProgress.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/RadioGroup/RadioGroup.js.map +1 -1
- package/dist/primitives/RadioGroup/RadioGroup.vue.d.ts +7 -7
- package/dist/primitives/RadioGroup/RadioGroup.vue.d.ts.map +1 -1
- package/dist/primitives/RadioGroup/RadioGroup.vue_vue_type_script_setup_true_lang.js +26 -9
- package/dist/primitives/RadioGroup/RadioGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/primitives/Rating/Rating.js +7 -0
- package/dist/primitives/Rating/Rating.js.map +1 -0
- package/dist/primitives/Rating/Rating.vue.d.ts +113 -0
- package/dist/primitives/Rating/Rating.vue.d.ts.map +1 -0
- package/dist/primitives/Rating/Rating.vue_vue_type_script_setup_true_lang.js +282 -0
- package/dist/primitives/Rating/Rating.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/ScrollArea/ScrollArea.js +7 -0
- package/dist/primitives/ScrollArea/ScrollArea.js.map +1 -0
- package/dist/primitives/ScrollArea/ScrollArea.vue.d.ts +25 -0
- package/dist/primitives/ScrollArea/ScrollArea.vue.d.ts.map +1 -0
- package/dist/primitives/ScrollArea/ScrollArea.vue_vue_type_script_setup_true_lang.js +45 -0
- package/dist/primitives/ScrollArea/ScrollArea.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/SegmentedControl/SegmentedControl.js.map +1 -1
- package/dist/primitives/SegmentedControl/SegmentedControl.vue.d.ts +5 -5
- package/dist/primitives/SegmentedControl/SegmentedControl.vue.d.ts.map +1 -1
- package/dist/primitives/SegmentedControl/SegmentedControl.vue_vue_type_script_setup_true_lang.js +51 -8
- package/dist/primitives/SegmentedControl/SegmentedControl.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/primitives/Select/Select.js.map +1 -1
- package/dist/primitives/Select/Select.vue.d.ts +10 -10
- package/dist/primitives/Select/Select.vue.d.ts.map +1 -1
- package/dist/primitives/Select/Select.vue_vue_type_script_setup_true_lang.js +105 -52
- package/dist/primitives/Select/Select.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/primitives/Skeleton/Skeleton.vue.d.ts +1 -1
- package/dist/primitives/Slider/Slider.js.map +1 -1
- package/dist/primitives/Slider/Slider.vue.d.ts +24 -4
- package/dist/primitives/Slider/Slider.vue.d.ts.map +1 -1
- package/dist/primitives/Slider/Slider.vue_vue_type_script_setup_true_lang.js +79 -9
- package/dist/primitives/Slider/Slider.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/primitives/SpeedDial/SpeedDial.js +7 -0
- package/dist/primitives/SpeedDial/SpeedDial.js.map +1 -0
- package/dist/primitives/SpeedDial/SpeedDial.vue.d.ts +58 -0
- package/dist/primitives/SpeedDial/SpeedDial.vue.d.ts.map +1 -0
- package/dist/primitives/SpeedDial/SpeedDial.vue_vue_type_script_setup_true_lang.js +175 -0
- package/dist/primitives/SpeedDial/SpeedDial.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/Stepper/Stepper.js +7 -0
- package/dist/primitives/Stepper/Stepper.js.map +1 -0
- package/dist/primitives/Stepper/Stepper.vue.d.ts +119 -0
- package/dist/primitives/Stepper/Stepper.vue.d.ts.map +1 -0
- package/dist/primitives/Stepper/Stepper.vue_vue_type_script_setup_true_lang.js +202 -0
- package/dist/primitives/Stepper/Stepper.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/Switch/Switch.js.map +1 -1
- package/dist/primitives/Switch/Switch.vue.d.ts +13 -3
- package/dist/primitives/Switch/Switch.vue.d.ts.map +1 -1
- package/dist/primitives/Switch/Switch.vue_vue_type_script_setup_true_lang.js +34 -5
- package/dist/primitives/Switch/Switch.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/primitives/Tabs/Tabs.js.map +1 -1
- package/dist/primitives/Tabs/Tabs.vue.d.ts.map +1 -1
- package/dist/primitives/Tabs/Tabs.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/primitives/Tabs/Tabs.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/primitives/TagsInput/TagsInput.js +7 -0
- package/dist/primitives/TagsInput/TagsInput.js.map +1 -0
- package/dist/primitives/TagsInput/TagsInput.vue.d.ts +156 -0
- package/dist/primitives/TagsInput/TagsInput.vue.d.ts.map +1 -0
- package/dist/primitives/TagsInput/TagsInput.vue_vue_type_script_setup_true_lang.js +387 -0
- package/dist/primitives/TagsInput/TagsInput.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/TextField/TextField.js +2 -2
- package/dist/primitives/TextField/TextField.js.map +1 -1
- package/dist/primitives/TextField/TextField.vue.d.ts +119 -10
- package/dist/primitives/TextField/TextField.vue.d.ts.map +1 -1
- package/dist/primitives/TextField/TextField.vue_vue_type_script_setup_true_lang.js +270 -21
- package/dist/primitives/TextField/TextField.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/primitives/Textarea/Textarea.js +2 -2
- package/dist/primitives/Textarea/Textarea.js.map +1 -1
- package/dist/primitives/Textarea/Textarea.vue.d.ts +114 -14
- package/dist/primitives/Textarea/Textarea.vue.d.ts.map +1 -1
- package/dist/primitives/Textarea/Textarea.vue_vue_type_script_setup_true_lang.js +216 -20
- package/dist/primitives/Textarea/Textarea.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/primitives/TimePicker/TimePicker.js +7 -0
- package/dist/primitives/TimePicker/TimePicker.js.map +1 -0
- package/dist/primitives/TimePicker/TimePicker.vue.d.ts +111 -0
- package/dist/primitives/TimePicker/TimePicker.vue.d.ts.map +1 -0
- package/dist/primitives/TimePicker/TimePicker.vue_vue_type_script_setup_true_lang.js +185 -0
- package/dist/primitives/TimePicker/TimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/Toast/Toast.js +2 -1
- package/dist/primitives/Toast/Toast.js.map +1 -1
- package/dist/primitives/Toast/Toast.vue.d.ts +29 -3
- package/dist/primitives/Toast/Toast.vue.d.ts.map +1 -1
- package/dist/primitives/Toast/Toast.vue_vue_type_script_setup_true_lang.js +17 -7
- package/dist/primitives/Toast/Toast.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/primitives/Toast/ToastItem.js +2 -2
- package/dist/primitives/Toast/ToastItem.js.map +1 -1
- package/dist/primitives/Toast/ToastItem.vue.d.ts +69 -12
- package/dist/primitives/Toast/ToastItem.vue.d.ts.map +1 -1
- package/dist/primitives/Toast/ToastItem.vue_vue_type_script_setup_true_lang.js +23 -23
- package/dist/primitives/Toast/ToastItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/primitives/Tooltip/Tooltip.vue.d.ts +1 -1
- package/dist/primitives/Tooltip/Tooltip.vue.d.ts.map +1 -1
- package/dist/primitives/WindowControls/WindowControls.js +2 -2
- package/dist/primitives/WindowControls/WindowControls.js.map +1 -1
- package/dist/primitives/WindowControls/WindowControls.vue.d.ts +66 -10
- package/dist/primitives/WindowControls/WindowControls.vue.d.ts.map +1 -1
- package/dist/primitives/WindowControls/WindowControls.vue_vue_type_script_setup_true_lang.js +23 -13
- package/dist/primitives/WindowControls/WindowControls.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/styles/global.css +116 -17
- package/dist/styles/theme.contrast.test.ts +460 -0
- package/dist/styles/theme.css +239 -41
- package/dist/theme.js +171 -0
- package/dist/theme.js.map +1 -0
- package/package.json +14 -4
- package/dist/icons/BrandMark.d.ts +0 -18
- package/dist/icons/BrandMark.d.ts.map +0 -1
- package/dist/icons/BrandMark.js +0 -47
- package/dist/icons/BrandMark.js.map +0 -1
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
import { cn } from "../../lib/cn.js";
|
|
2
|
+
import { optional } from "../../lib/props.js";
|
|
3
|
+
import { useLabels } from "../../lib/labels.js";
|
|
4
|
+
import { getLocalTimeZone as $ad063034c8620db8$export$aa8b41735afcabd2, isToday as $ad063034c8620db8$export$629b0a497aa65267 } from "../../node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/queries.js";
|
|
5
|
+
import { toCalendarDate as $d07e34cce18680fd$export$93522d1a439f3617 } from "../../node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/conversion.js";
|
|
6
|
+
import { parseDate as $58246871e4652552$export$6b862160d295c8e } from "../../node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/string.js";
|
|
7
|
+
import { CALENDAR_PANEL_LABELS, DATE_SEGMENT_LABELS, emptySegmentValueText, isDateSegmentPart } from "../../lib/date-labels.js";
|
|
8
|
+
import { useSplitAttrs } from "../../lib/attrs.js";
|
|
9
|
+
import { useFieldControl } from "../../lib/field-context.js";
|
|
10
|
+
import { useAncestorDisabled } from "../../lib/ancestor-disabled.js";
|
|
11
|
+
import { CalendarDays, ChevronLeft, ChevronRight } from "@lucide/vue";
|
|
12
|
+
import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, mergeProps, normalizeClass, openBlock, ref, renderList, toDisplayString, unref, useId, useTemplateRef, withCtx } from "vue";
|
|
13
|
+
import { DatePickerAnchor, DatePickerCalendar, DatePickerCell, DatePickerCellTrigger, DatePickerContent, DatePickerField, DatePickerGrid, DatePickerGridBody, DatePickerGridHead, DatePickerGridRow, DatePickerHeadCell, DatePickerHeader, DatePickerHeading, DatePickerInput, DatePickerNext, DatePickerPrev, DatePickerRoot, DatePickerTrigger } from "reka-ui";
|
|
14
|
+
//#region src/primitives/DatePicker/DatePicker.vue?vue&type=script&setup=true&lang.ts
|
|
15
|
+
var _hoisted_1 = {
|
|
16
|
+
key: 0,
|
|
17
|
+
"aria-hidden": "true",
|
|
18
|
+
class: "absolute bottom-1 h-1 w-1 rounded-full bg-primary group-data-[selected]:bg-primary-foreground"
|
|
19
|
+
};
|
|
20
|
+
var DatePicker_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
|
|
21
|
+
inheritAttrs: false,
|
|
22
|
+
__name: "DatePicker",
|
|
23
|
+
props: {
|
|
24
|
+
modelValue: {},
|
|
25
|
+
min: {},
|
|
26
|
+
max: {},
|
|
27
|
+
locale: { default: "en" },
|
|
28
|
+
disabled: {
|
|
29
|
+
type: Boolean,
|
|
30
|
+
default: void 0
|
|
31
|
+
},
|
|
32
|
+
readonly: {
|
|
33
|
+
type: Boolean,
|
|
34
|
+
default: void 0
|
|
35
|
+
},
|
|
36
|
+
invalid: {
|
|
37
|
+
type: Boolean,
|
|
38
|
+
default: void 0
|
|
39
|
+
},
|
|
40
|
+
required: {
|
|
41
|
+
type: Boolean,
|
|
42
|
+
default: void 0
|
|
43
|
+
},
|
|
44
|
+
name: {},
|
|
45
|
+
labels: {}
|
|
46
|
+
},
|
|
47
|
+
emits: ["update:modelValue"],
|
|
48
|
+
setup(__props, { emit: __emit }) {
|
|
49
|
+
const props = __props;
|
|
50
|
+
const emit = __emit;
|
|
51
|
+
const segmentText = useLabels("dateSegments", DATE_SEGMENT_LABELS, () => props.labels);
|
|
52
|
+
const panelText = useLabels("calendarPanel", CALENDAR_PANEL_LABELS, () => props.labels);
|
|
53
|
+
function segmentLabel(part) {
|
|
54
|
+
return isDateSegmentPart(part) ? segmentText.value[part] : void 0;
|
|
55
|
+
}
|
|
56
|
+
function segmentValueText(part, value, monthValue) {
|
|
57
|
+
const empty = emptySegmentValueText(part, value, segmentText.value.empty);
|
|
58
|
+
if (empty["aria-valuetext"]) return empty;
|
|
59
|
+
if (part === "month" && monthValue !== void 0) return { "aria-valuetext": segmentText.value.filledMonth({
|
|
60
|
+
value: monthValue,
|
|
61
|
+
locale: props.locale
|
|
62
|
+
}) };
|
|
63
|
+
return {};
|
|
64
|
+
}
|
|
65
|
+
const { attrs, rest: fieldAttrs } = useSplitAttrs();
|
|
66
|
+
/**
|
|
67
|
+
* The date segments are `<div role="spinbutton" tabindex="0">`, and
|
|
68
|
+
* `<fieldset disabled>` reaches only `<input>`, `<button>`, `<select>` and
|
|
69
|
+
* `<textarea>` — so the calendar trigger inside a disabled group went inert
|
|
70
|
+
* while the segments beside it still typed a date on an arrow key. Measured in
|
|
71
|
+
* jsdom: an empty `mm` segment became `8`.
|
|
72
|
+
*
|
|
73
|
+
* Read off the DOM rather than taken from the Field context, which publishes no
|
|
74
|
+
* `disabled` on purpose — see `../../lib/ancestor-disabled.ts`.
|
|
75
|
+
*/
|
|
76
|
+
const anchor = useTemplateRef("anchor");
|
|
77
|
+
const groupDisabled = useAncestorDisabled(() => anchor.value?.$el);
|
|
78
|
+
const field = useFieldControl(() => ({
|
|
79
|
+
id: attrs.id,
|
|
80
|
+
describedBy: attrs["aria-describedby"],
|
|
81
|
+
ariaLabelledby: attrs["aria-labelledby"],
|
|
82
|
+
name: props.name,
|
|
83
|
+
disabled: groupDisabled.value ? true : props.disabled,
|
|
84
|
+
readonly: props.readonly,
|
|
85
|
+
invalid: props.invalid,
|
|
86
|
+
required: props.required
|
|
87
|
+
}));
|
|
88
|
+
const groupLabelledBy = computed(() => attrs["aria-label"] || attrs["aria-labelledby"] ? void 0 : field.labelledBy);
|
|
89
|
+
function fromIso(value) {
|
|
90
|
+
if (!value) return void 0;
|
|
91
|
+
try {
|
|
92
|
+
return $58246871e4652552$export$6b862160d295c8e(value);
|
|
93
|
+
} catch {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
function toIso(date) {
|
|
98
|
+
return $d07e34cce18680fd$export$93522d1a439f3617(date).toString();
|
|
99
|
+
}
|
|
100
|
+
const rootValue = computed(() => optional({
|
|
101
|
+
modelValue: fromIso(props.modelValue),
|
|
102
|
+
minValue: fromIso(props.min),
|
|
103
|
+
maxValue: fromIso(props.max)
|
|
104
|
+
}));
|
|
105
|
+
const open = ref(false);
|
|
106
|
+
function onDateChange(date) {
|
|
107
|
+
open.value = false;
|
|
108
|
+
emit("update:modelValue", date ? toIso(date) : void 0);
|
|
109
|
+
}
|
|
110
|
+
function isDateToday(date) {
|
|
111
|
+
return $ad063034c8620db8$export$629b0a497aa65267(date, $ad063034c8620db8$export$aa8b41735afcabd2());
|
|
112
|
+
}
|
|
113
|
+
const focusedPart = ref();
|
|
114
|
+
function segmentTabIndex(part, segments) {
|
|
115
|
+
if (field.disabled || part === "literal") return void 0;
|
|
116
|
+
const editable = segments.filter((segment) => segment.part !== "literal");
|
|
117
|
+
return part === (focusedPart.value !== void 0 && editable.some((segment) => segment.part === focusedPart.value) ? focusedPart.value : editable[0]?.part) ? 0 : -1;
|
|
118
|
+
}
|
|
119
|
+
const headingId = useId();
|
|
120
|
+
const panel = ref(null);
|
|
121
|
+
function onOpenAutoFocus(event) {
|
|
122
|
+
const day = panel.value?.querySelector("[data-reka-calendar-cell-trigger][tabindex=\"0\"]");
|
|
123
|
+
if (!day) return;
|
|
124
|
+
event.preventDefault();
|
|
125
|
+
day.focus();
|
|
126
|
+
}
|
|
127
|
+
return (_ctx, _cache) => {
|
|
128
|
+
return openBlock(), createBlock(unref(DatePickerRoot), mergeProps({
|
|
129
|
+
open: open.value,
|
|
130
|
+
"onUpdate:open": _cache[0] || (_cache[0] = ($event) => open.value = $event)
|
|
131
|
+
}, rootValue.value, {
|
|
132
|
+
locale: __props.locale,
|
|
133
|
+
disabled: unref(field).disabled,
|
|
134
|
+
readonly: unref(field).readonly,
|
|
135
|
+
granularity: "day",
|
|
136
|
+
"prevent-deselect": "",
|
|
137
|
+
"onUpdate:modelValue": onDateChange
|
|
138
|
+
}), {
|
|
139
|
+
default: withCtx(() => [createVNode(unref(DatePickerAnchor), {
|
|
140
|
+
ref_key: "anchor",
|
|
141
|
+
ref: anchor,
|
|
142
|
+
"data-invalid": unref(field).invalid || void 0,
|
|
143
|
+
"data-readonly": unref(field).readonly || void 0,
|
|
144
|
+
class: normalizeClass(unref(cn)("block w-full", unref(attrs).class))
|
|
145
|
+
}, {
|
|
146
|
+
default: withCtx(() => [createVNode(unref(DatePickerField), mergeProps({
|
|
147
|
+
...unref(fieldAttrs),
|
|
148
|
+
...unref(field).attrs
|
|
149
|
+
}, {
|
|
150
|
+
"aria-labelledby": groupLabelledBy.value,
|
|
151
|
+
class: unref(cn)("flex h-9 w-full items-center rounded-md border border-input bg-background px-3 text-sm text-foreground", "transition-[color,background-color,border-color,box-shadow] duration-fast ease-out", "focus-within:outline-2 focus-within:outline-offset-2 focus-within:outline-ring", !unref(field).invalid && "focus-within:shadow-halo", unref(field).readonly && "bg-subtle", unref(field).disabled && "cursor-not-allowed border-border bg-muted text-muted-foreground", unref(field).invalid && "border-destructive focus-within:outline-destructive")
|
|
152
|
+
}), {
|
|
153
|
+
default: withCtx(({ segments }) => [(openBlock(true), createElementBlock(Fragment, null, renderList(segments, (item, index) => {
|
|
154
|
+
return openBlock(), createBlock(unref(DatePickerInput), mergeProps({
|
|
155
|
+
key: index,
|
|
156
|
+
part: item.part,
|
|
157
|
+
tabindex: segmentTabIndex(item.part, segments),
|
|
158
|
+
"aria-label": segmentLabel(item.part)
|
|
159
|
+
}, { ref_for: true }, segmentValueText(item.part, item.value, fromIso(props.modelValue)?.month), {
|
|
160
|
+
class: unref(cn)("tabular rounded-sm px-0.5 outline-none", "transition-colors duration-instant ease-out", "focus:bg-primary-muted focus:text-primary", "data-[placeholder]:text-muted-foreground", item.part === "literal" && "text-muted-foreground"),
|
|
161
|
+
onFocusin: ($event) => focusedPart.value = item.part
|
|
162
|
+
}), {
|
|
163
|
+
default: withCtx(() => [createTextVNode(toDisplayString(item.value), 1)]),
|
|
164
|
+
_: 2
|
|
165
|
+
}, 1040, [
|
|
166
|
+
"part",
|
|
167
|
+
"tabindex",
|
|
168
|
+
"aria-label",
|
|
169
|
+
"class",
|
|
170
|
+
"onFocusin"
|
|
171
|
+
]);
|
|
172
|
+
}), 128)), !unref(field).readonly ? (openBlock(), createBlock(unref(DatePickerTrigger), {
|
|
173
|
+
key: 0,
|
|
174
|
+
"aria-label": unref(panelText).openCalendar,
|
|
175
|
+
class: "ml-auto inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-sm text-muted-foreground transition-colors duration-fast ease-out hover:bg-subtle hover:text-foreground focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring disabled:cursor-not-allowed"
|
|
176
|
+
}, {
|
|
177
|
+
default: withCtx(() => [createVNode(unref(CalendarDays), { class: "h-4 w-4" })]),
|
|
178
|
+
_: 1
|
|
179
|
+
}, 8, ["aria-label"])) : createCommentVNode("", true)]),
|
|
180
|
+
_: 1
|
|
181
|
+
}, 16, ["aria-labelledby", "class"])]),
|
|
182
|
+
_: 1
|
|
183
|
+
}, 8, [
|
|
184
|
+
"data-invalid",
|
|
185
|
+
"data-readonly",
|
|
186
|
+
"class"
|
|
187
|
+
]), createVNode(unref(DatePickerContent), {
|
|
188
|
+
align: "start",
|
|
189
|
+
"side-offset": 6,
|
|
190
|
+
class: normalizeClass(unref(cn)("z-50 rounded-md border border-border bg-popover p-3 text-popover-foreground shadow-md outline-none", "data-[state=open]:animate-fade-rise")),
|
|
191
|
+
onOpenAutoFocus
|
|
192
|
+
}, {
|
|
193
|
+
default: withCtx(() => [createElementVNode("div", {
|
|
194
|
+
ref_key: "panel",
|
|
195
|
+
ref: panel,
|
|
196
|
+
class: "flex flex-col gap-3"
|
|
197
|
+
}, [createVNode(unref(DatePickerCalendar), { "calendar-label": unref(panelText).calendar }, {
|
|
198
|
+
default: withCtx(({ grid, weekDays }) => [createVNode(unref(DatePickerHeader), { class: "flex items-center justify-between gap-2" }, {
|
|
199
|
+
default: withCtx(() => [
|
|
200
|
+
createVNode(unref(DatePickerPrev), {
|
|
201
|
+
"aria-label": unref(panelText).previousMonth,
|
|
202
|
+
class: "inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-sm text-muted-foreground transition-colors duration-fast ease-out hover:bg-subtle hover:text-foreground focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring data-[disabled]:pointer-events-none data-[disabled]:opacity-50"
|
|
203
|
+
}, {
|
|
204
|
+
default: withCtx(() => [createVNode(unref(ChevronLeft), { class: "h-4 w-4" })]),
|
|
205
|
+
_: 1
|
|
206
|
+
}, 8, ["aria-label"]),
|
|
207
|
+
createVNode(unref(DatePickerHeading), {
|
|
208
|
+
id: unref(headingId),
|
|
209
|
+
"aria-live": "polite",
|
|
210
|
+
class: "text-sm font-medium text-foreground"
|
|
211
|
+
}, null, 8, ["id"]),
|
|
212
|
+
createVNode(unref(DatePickerNext), {
|
|
213
|
+
"aria-label": unref(panelText).nextMonth,
|
|
214
|
+
class: "inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-sm text-muted-foreground transition-colors duration-fast ease-out hover:bg-subtle hover:text-foreground focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring data-[disabled]:pointer-events-none data-[disabled]:opacity-50"
|
|
215
|
+
}, {
|
|
216
|
+
default: withCtx(() => [createVNode(unref(ChevronRight), { class: "h-4 w-4" })]),
|
|
217
|
+
_: 1
|
|
218
|
+
}, 8, ["aria-label"])
|
|
219
|
+
]),
|
|
220
|
+
_: 1
|
|
221
|
+
}), (openBlock(true), createElementBlock(Fragment, null, renderList(grid, (month) => {
|
|
222
|
+
return openBlock(), createBlock(unref(DatePickerGrid), {
|
|
223
|
+
key: month.value.toString(),
|
|
224
|
+
role: "grid",
|
|
225
|
+
"aria-labelledby": unref(headingId),
|
|
226
|
+
class: "border-collapse select-none"
|
|
227
|
+
}, {
|
|
228
|
+
default: withCtx(() => [createVNode(unref(DatePickerGridHead), null, {
|
|
229
|
+
default: withCtx(() => [createVNode(unref(DatePickerGridRow), null, {
|
|
230
|
+
default: withCtx(() => [(openBlock(true), createElementBlock(Fragment, null, renderList(weekDays, (day, index) => {
|
|
231
|
+
return openBlock(), createBlock(unref(DatePickerHeadCell), {
|
|
232
|
+
key: index,
|
|
233
|
+
class: "w-9 text-xs font-normal text-muted-foreground"
|
|
234
|
+
}, {
|
|
235
|
+
default: withCtx(() => [createTextVNode(toDisplayString(day), 1)]),
|
|
236
|
+
_: 2
|
|
237
|
+
}, 1024);
|
|
238
|
+
}), 128))]),
|
|
239
|
+
_: 2
|
|
240
|
+
}, 1024)]),
|
|
241
|
+
_: 2
|
|
242
|
+
}, 1024), createVNode(unref(DatePickerGridBody), null, {
|
|
243
|
+
default: withCtx(() => [(openBlock(true), createElementBlock(Fragment, null, renderList(month.rows, (week, weekIndex) => {
|
|
244
|
+
return openBlock(), createBlock(unref(DatePickerGridRow), { key: weekIndex }, {
|
|
245
|
+
default: withCtx(() => [(openBlock(true), createElementBlock(Fragment, null, renderList(week, (day) => {
|
|
246
|
+
return openBlock(), createBlock(unref(DatePickerCell), {
|
|
247
|
+
key: day.toString(),
|
|
248
|
+
date: day,
|
|
249
|
+
class: "p-0 text-center"
|
|
250
|
+
}, {
|
|
251
|
+
default: withCtx(() => [createVNode(unref(DatePickerCellTrigger), {
|
|
252
|
+
day,
|
|
253
|
+
month: month.value,
|
|
254
|
+
"aria-current": isDateToday(day) ? "date" : void 0,
|
|
255
|
+
class: "group relative inline-flex h-9 w-9 items-center justify-center rounded-sm text-sm text-foreground transition-colors duration-fast ease-out hover:bg-subtle focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:shadow-halo data-[outside-view]:text-muted-foreground data-[selected]:bg-primary data-[selected]:text-primary-foreground data-[disabled]:pointer-events-none data-[disabled]:line-through [&[data-disabled]:not([data-selected])]:text-muted-foreground"
|
|
256
|
+
}, {
|
|
257
|
+
default: withCtx(({ dayValue, today }) => [createTextVNode(toDisplayString(dayValue) + " ", 1), today ? (openBlock(), createElementBlock("span", _hoisted_1)) : createCommentVNode("", true)]),
|
|
258
|
+
_: 1
|
|
259
|
+
}, 8, [
|
|
260
|
+
"day",
|
|
261
|
+
"month",
|
|
262
|
+
"aria-current"
|
|
263
|
+
])]),
|
|
264
|
+
_: 2
|
|
265
|
+
}, 1032, ["date"]);
|
|
266
|
+
}), 128))]),
|
|
267
|
+
_: 2
|
|
268
|
+
}, 1024);
|
|
269
|
+
}), 128))]),
|
|
270
|
+
_: 2
|
|
271
|
+
}, 1024)]),
|
|
272
|
+
_: 2
|
|
273
|
+
}, 1032, ["aria-labelledby"]);
|
|
274
|
+
}), 128))]),
|
|
275
|
+
_: 1
|
|
276
|
+
}, 8, ["calendar-label"])], 512)]),
|
|
277
|
+
_: 1
|
|
278
|
+
}, 8, ["class"])]),
|
|
279
|
+
_: 1
|
|
280
|
+
}, 16, [
|
|
281
|
+
"open",
|
|
282
|
+
"locale",
|
|
283
|
+
"disabled",
|
|
284
|
+
"readonly"
|
|
285
|
+
]);
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
//#endregion
|
|
290
|
+
export { DatePicker_vue_vue_type_script_setup_true_lang_default as default };
|
|
291
|
+
|
|
292
|
+
//# sourceMappingURL=DatePicker.vue_vue_type_script_setup_true_lang.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DatePicker.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/primitives/DatePicker/DatePicker.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { CalendarPanelLabels, DateSegmentLabels } from \"../../lib/date-labels\";\n\n/**\n * Everything this control publishes to assistive technology, which is two\n * shared slices and nothing of its own: the names of the field's segments and\n * the calendar popover's chrome. Both are declared in `src/lib/date-labels.ts`,\n * because `DateTimePicker`, `DateRangePicker` and `DateTimeRangePicker` say the\n * same words for the same reason — they are all one Reka implementation\n * underneath — and four copies of `Previous month` is a translator writing the\n * same word four times.\n *\n * An intersection rather than a third interface, so this name is the type a\n * consumer annotates their own bag with and the two halves stay one definition\n * each. Annotate with `LabelOverrides<DatePickerLabels>` and never with this\n * directly: this one is total, and a key added in a later release would stop a\n * consumer's build.\n */\nexport type DatePickerLabels = DateSegmentLabels & CalendarPanelLabels;\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, ref, useId, useTemplateRef } from \"vue\";\nimport {\n DatePickerRoot,\n DatePickerAnchor,\n DatePickerField,\n DatePickerInput,\n DatePickerTrigger,\n DatePickerContent,\n DatePickerCalendar,\n DatePickerHeader,\n DatePickerPrev,\n DatePickerHeading,\n DatePickerNext,\n DatePickerGrid,\n DatePickerGridHead,\n DatePickerGridRow,\n DatePickerHeadCell,\n DatePickerGridBody,\n DatePickerCell,\n DatePickerCellTrigger,\n} from \"reka-ui\";\nimport { CalendarDays, ChevronLeft, ChevronRight } from \"@lucide/vue\";\nimport {\n getLocalTimeZone,\n isToday,\n parseDate,\n toCalendarDate,\n type DateValue,\n} from \"@internationalized/date\";\nimport { cn } from \"../../lib/cn\";\nimport { useSplitAttrs } from \"../../lib/attrs\";\nimport { useAncestorDisabled } from \"../../lib/ancestor-disabled\";\nimport { useFieldControl } from \"../../lib/field-context\";\nimport { optional } from \"../../lib/props\";\nimport { useLabels, type LabelOverrides } from \"../../lib/labels\";\nimport {\n CALENDAR_PANEL_LABELS,\n DATE_SEGMENT_LABELS,\n emptySegmentValueText,\n isDateSegmentPart,\n} from \"../../lib/date-labels\";\n\n/**\n * DatePicker — one calendar date, entered either by typing it into a segmented\n * field or by picking it out of a calendar popover. Reach for it wherever a\n * date is a value rather than a search: a due date, a start date, a date of\n * birth.\n *\n * The segmented field is the reason this is not an `<input type=\"date\">`.\n * Arrow keys change the segment under the cursor, typing digits fills it and\n * advances, and the segment order and the month names follow `locale` rather\n * than the browser's own — which is what lets a Vietnamese reader and an\n * American reader see the same date written the way each of them writes it.\n * The calendar is the second path to the same value, not the only one.\n *\n * **The model value is a plain ISO date string, `\"YYYY-MM-DD\"`, never a\n * `DateValue`.** Reka and `@internationalized/date` model a date as a calendar\n * object, and that object is the right shape *inside* a date control — it\n * knows about calendars other than the Gregorian one, about month lengths, and\n * about what \"next month\" means on the 31st. It is the wrong shape at the\n * boundary: a host binding a due date has a string from its API and wants a\n * string back for it, and nobody should have to learn a date library to bind a\n * date. So the string is parsed on the way in and re-serialised on the way\n * out, the same instinct as Slider exposing a scalar where Reka models an\n * array. `min`, `max` and the emitted value all speak that one format.\n *\n * A value that does not parse — a half-typed string, an empty one, a\n * datetime — is read as *no date chosen* rather than thrown on. A component\n * library cannot decide that a host's bad data is fatal, and a date field that\n * crashes the page while someone types into the host's own text input beside\n * it is the worst possible reading of \"strict\".\n *\n * For a span rather than a single day, compose two of these — a range control\n * shares almost none of this one's model. For a month or a year alone, neither\n * this nor a Select is right; that is a control this library does not have yet.\n *\n * Inside a [Field](../Field/Field.vue) it wires itself: the row's id, the id of\n * its hint or error line, and `required` / `invalid` / `disabled` / `readonly` /\n * `name` all arrive through `useFieldControl()`, so `<Field label=\"Due date\"\n * error=\"…\"><DatePicker /></Field>` needs no attributes at the call site. Every\n * prop below still wins over the row when it is set, in both directions — which\n * is why the four booleans default to `undefined` rather than `false`.\n *\n * `readonly` and `disabled` are different states, not two dials on one, so the\n * field has three resting appearances rather than two. A read-only date is a\n * value on show: the field stays a Tab stop, its segments stay readable and\n * copyable at full strength, and it takes a lifted fill. A disabled one is\n * unavailable: no Tab stop, nothing submitted, and drained a step further in\n * fill, text colour and border weight together.\n */\nconst props = withDefaults(\n defineProps<{\n /**\n * The chosen date as ISO `YYYY-MM-DD`. Unset, empty or unparseable means no\n * date is chosen. The explicit `| undefined` is what lets `v-model` bind a\n * ref that clears — the emitted value drops to `undefined` when the field\n * is emptied, and a plain optional prop refuses to take it back.\n */\n modelValue?: string | undefined;\n /** The earliest choosable date, same ISO format. Days before it are announced disabled and skipped by the keyboard. */\n min?: string;\n /** The latest choosable date, same ISO format. Days after it are announced disabled and skipped by the keyboard. */\n max?: string;\n /** BCP 47 tag driving the order of the field's segments, the month and weekday names, and which day a week starts on. */\n locale?: string;\n /** Unavailable: dims the control, refuses the calendar, and takes the field out of the tab order. Unset defers to a wrapping Field. */\n disabled?: boolean | undefined;\n /** Shows the date without allowing an edit: the field stays a Tab stop and stays submitted, and the calendar button is dropped because nothing in the calendar could be chosen. Unset defers to a wrapping Field. */\n readonly?: boolean | undefined;\n /** Error state: paints the destructive border and ring, and sets `aria-invalid`. Unset defers to a wrapping Field's `error`. */\n invalid?: boolean | undefined;\n /** Marks the field mandatory to assistive tech (`aria-required` on the segment group). Unset defers to a wrapping Field. */\n required?: boolean | undefined;\n /** The field name for a native form post or `FormData`, carried on the hidden input Reka submits the date through. Unset defers to a wrapping Field. */\n name?: string;\n /**\n * Names for everything this control says out loud, as any subset of\n * `DatePickerLabels` — the rest stay as the host's `provideLoomLabels`\n * vocabulary left them, and then as Loom's English.\n *\n * This is the per-instance correction, not the place to localise an\n * application: six of the nine names replace English literals Reka UI\n * writes of its own accord, and a language is set once with\n * `provideLoomLabels`.\n */\n labels?: LabelOverrides<DatePickerLabels>;\n }>(),\n {\n locale: \"en\",\n // Not `false`, for any of the four — TextField.vue carries the full\n // reasoning. `false` is a caller deciding this one control is fine,\n // enabled or editable even though its row is not; absent is a caller\n // saying nothing, and only `undefined` survives to mean that past Vue's\n // absent-Boolean-casts-to-false rule.\n disabled: undefined,\n readonly: undefined,\n invalid: undefined,\n required: undefined,\n },\n);\n\nconst emit = defineEmits<{\n /** The chosen date as ISO `YYYY-MM-DD`, or `undefined` once the field has been cleared. */\n \"update:modelValue\": [value: string | undefined];\n}>();\n\n// Two slots, one prop. `text` is the name everywhere else in the library, and\n// there is no single `text` here because there is no single slot: the segment\n// names and the popover's chrome are separate vocabularies with separate\n// registry entries, and naming them apart is what keeps a reader of the\n// template able to see which one a binding came from. The one `labels` prop\n// feeds both — a getter returning the intersection satisfies either half, and\n// the keys the other half does not know are ignored by `useLabels`' own return\n// type.\nconst segmentText = useLabels(\"dateSegments\", DATE_SEGMENT_LABELS, () => props.labels);\nconst panelText = useLabels(\"calendarPanel\", CALENDAR_PANEL_LABELS, () => props.labels);\n\n// Read through the ref on every call rather than resolved into a lookup table\n// once: a table built in `setup` freezes the first language and every later\n// switch silently does nothing. `undefined` for the parts this slice does not\n// name — the `literal` separators, which Reka renders `aria-hidden` and which\n// must stay unnamed.\nfunction segmentLabel(part: string): string | undefined {\n return isDateSegmentPart(part) ? segmentText.value[part] : undefined;\n}\n\n// The companion to `segmentLabel`, and the reason it returns an object rather\n// than a string is in `emptySegmentValueText`: Reka's `aria-valuetext` is a\n// hard-coded \"Empty\" only while the segment holds nothing, so this replaces\n// that case and leaves the filled one — a number, and the locale's own month\n// name — exactly as Reka wrote it.\n//\n// The month is the exception. Reka writes `\"5 - May\"`, with the month name from\n// `Intl.DateTimeFormat` but the separator and order hard-coded. `filledMonth`\n// lets a host compose the string their language needs (Japanese `\"5月\"`,\n// Vietnamese `\"tháng 5\"`). The numeric month arrives from the parsed model value\n// rather than from the segment's displayed text, because `item.value` is the\n// locale-formatted display and may not contain a parseable number.\nfunction segmentValueText(\n part: string,\n value: string,\n monthValue?: number,\n): { \"aria-valuetext\"?: string } {\n const empty = emptySegmentValueText(part, value, segmentText.value.empty);\n if (empty[\"aria-valuetext\"]) return empty;\n if (part === \"month\" && monthValue !== undefined) {\n return {\n \"aria-valuetext\": segmentText.value.filledMonth({ value: monthValue, locale: props.locale }),\n };\n }\n return {};\n}\n\n// `class` sizes the whole control, so it lands on the anchor — the element the\n// caller's `max-w-xs` has to reach, and the one the popover measures itself\n// against. Every other fallthrough attribute goes one level in, onto the\n// `role=\"group\"` field: `aria-label`, `aria-labelledby` and `aria-describedby`\n// name and describe the thing being entered, and a group is what a screen\n// reader announces that name on entering. Putting them on the anchor instead\n// would name a layout div nothing ever lands in.\ndefineOptions({ inheritAttrs: false });\nconst { attrs, rest: fieldAttrs } = useSplitAttrs();\n\n/**\n * The date segments are `<div role=\"spinbutton\" tabindex=\"0\">`, and\n * `<fieldset disabled>` reaches only `<input>`, `<button>`, `<select>` and\n * `<textarea>` — so the calendar trigger inside a disabled group went inert\n * while the segments beside it still typed a date on an arrow key. Measured in\n * jsdom: an empty `mm` segment became `8`.\n *\n * Read off the DOM rather than taken from the Field context, which publishes no\n * `disabled` on purpose — see `../../lib/ancestor-disabled.ts`.\n */\nconst anchor = useTemplateRef<{ $el?: Element }>(\"anchor\");\nconst groupDisabled = useAncestorDisabled(() => anchor.value?.$el);\n\n// `id` and `aria-describedby` reach this control as fallthrough attrs rather\n// than props, so they are read off `attrs` and handed in as this caller's own\n// values — a caller who sets either still beats the row, and the row's\n// description is merged into theirs rather than replacing it.\n//\n// `field.attrs` spreads onto `DatePickerField` **after** `fieldAttrs`, which is\n// the node those two were already landing on, and the position is the contract:\n// the bag has resolved the caller's own values already and drops every key that\n// resolved to nothing, so it can only add. Where each key ends up is Reka's\n// decision and worth knowing: `DateFieldRoot` declares `id` and `name` as props\n// and puts both on the visually-hidden `<input>` it submits the date through —\n// which is the element a `<label for>` can actually name, a `role=\"group\"` div\n// being unlabelable — while `aria-describedby`, `aria-required` and\n// `aria-invalid` are undeclared, fall through to `$attrs`, and land on the group\n// itself, where a screen reader announces them once on entering the field.\n//\n// The `:aria-invalid` binding that used to sit on the field is gone with it: an\n// individual attribute written after a `v-bind` wins, so keeping one would\n// overwrite the resolved value with the raw prop.\nconst field = useFieldControl(() => ({\n id: attrs.id as string | undefined,\n describedBy: attrs[\"aria-describedby\"] as string | undefined,\n ariaLabelledby: attrs[\"aria-labelledby\"] as string | undefined,\n name: props.name,\n // The fieldset beats the prop in both directions, exactly as it does for the\n // trigger button inside this very control.\n disabled: groupDisabled.value ? true : props.disabled,\n readonly: props.readonly,\n invalid: props.invalid,\n required: props.required,\n}));\n\n// `aria-labelledby` for the group, resolved against the row. A caller who passes\n// `aria-labelledby` as a fallthrough attr wins (it reaches this control's own\n// `ariaLabelledby` through `useFieldControl`). A caller who passes `aria-label`\n// wins too — `aria-labelledby` overrides `aria-label` in ARIA, so the row's\n// label must not appear when the caller named the control themselves. Otherwise,\n// the row's label (published by Field as `labelledBy`) is the accessible name.\nconst groupLabelledBy = computed(() =>\n attrs[\"aria-label\"] || attrs[\"aria-labelledby\"] ? undefined : field.labelledBy,\n);\n\nfunction fromIso(value: string | undefined): DateValue | undefined {\n if (!value) return undefined;\n try {\n return parseDate(value);\n } catch {\n return undefined;\n }\n}\n\n// `toString()` already normalises to the Gregorian ISO form whatever calendar\n// the value carries — a locale such as `th-TH` makes Reka's own placeholder a\n// Buddhist date whose year reads 2569, and it still prints `2026-08-11`. What\n// `toCalendarDate` adds is dropping a time component before it can turn the\n// string into `2026-08-11T00:00:00`. `granularity=\"day\"` below is what makes\n// that unreachable today; this is what keeps it unreachable if it ever moves.\nfunction toIso(date: DateValue): string {\n return toCalendarDate(date).toString();\n}\n\n// `optional()` rather than three separate bindings: an absent bound forwarded\n// as an explicit `undefined` is still a key Reka sees, and an absent\n// `modelValue` forwarded that way is what turns an uncontrolled field into a\n// permanently empty one. Dropping the key says what is true.\nconst rootValue = computed(() =>\n optional({\n modelValue: fromIso(props.modelValue),\n minValue: fromIso(props.min),\n maxValue: fromIso(props.max),\n }),\n);\n\n// The panel's open state is owned here rather than left to Reka's\n// `closeOnSelect`, which closes by watching its *own* model value — and that\n// value only moves for a host that echoes the emitted date straight back down.\n// A host that validates before accepting one, or that binds nothing at all,\n// would pick a day and watch the calendar stay open over the field it just\n// filled. Closing on the choice itself does not depend on anyone answering.\nconst open = ref(false);\n\nfunction onDateChange(date: DateValue | undefined) {\n open.value = false;\n emit(\"update:modelValue\", date ? toIso(date) : undefined);\n}\n\n// Today is a state, and it may not be carried by the marker dot alone — a\n// reader who cannot see the dot gets `aria-current=\"date\"`, which is the one\n// attribute screen readers already announce for \"this is the current one\".\n// Reka publishes today only as a `data-` attribute and a slot prop, neither of\n// which can reach an attribute binding on the cell itself.\nfunction isDateToday(date: DateValue): boolean {\n return isToday(date, getLocalTimeZone());\n}\n\n// The field is one Tab stop, not three. Reka leaves every segment tabbable,\n// which turns a single date into three stops a keyboard user has to walk\n// through — and the control everyone already knows, the browser's own date\n// input, is one stop with the arrow keys moving inside it. So a roving\n// tabindex names exactly one segment as the stop, and Reka's own\n// ArrowLeft/ArrowRight handling (and its auto-advance after a filled segment)\n// moves between them by calling `focus()` directly, which ignores tabindex\n// entirely and so keeps working untouched.\nconst focusedPart = ref<string>();\n\nfunction segmentTabIndex(part: string, segments: readonly { part: string }[]): number | undefined {\n // A disabled field has no stop at all; returning `undefined` removes the\n // attribute, which is exactly what Reka does for the same case. A read-only\n // one keeps every stop it had — the value is on show and a reader still\n // arrows across it to read it, which is the whole difference between the two\n // states.\n if (field.disabled || part === \"literal\") return undefined;\n const editable = segments.filter((segment) => segment.part !== \"literal\");\n // The remembered segment is dropped when a locale change takes it away —\n // a field with no tab stop is unreachable, and `en` has no era segment that\n // `ja-JP-u-ca-japanese` does.\n const active =\n focusedPart.value !== undefined &&\n editable.some((segment) => segment.part === focusedPart.value)\n ? focusedPart.value\n : editable[0]?.part;\n return part === active ? 0 : -1;\n}\n\n// The month/year heading names the grid, so the two are wired together rather\n// than the grid being an unnamed table of numbers.\nconst headingId = useId();\n\nconst panel = ref<HTMLElement | null>(null);\n\n// Reka's focus scope would land on the first tabbable thing in the panel,\n// which is the previous-month button — so a keyboard user opening the calendar\n// arrives one Tab away from the grid and two from the day they came for.\n// Focus goes to the day the calendar is already sitting on instead: the\n// selected date, or today when nothing is selected, which is the cell Reka has\n// given the grid's own roving tabindex to.\nfunction onOpenAutoFocus(event: Event) {\n const day = panel.value?.querySelector<HTMLElement>(\n '[data-reka-calendar-cell-trigger][tabindex=\"0\"]',\n );\n if (!day) return;\n event.preventDefault();\n day.focus();\n}\n</script>\n\n<template>\n <DatePickerRoot\n v-model:open=\"open\"\n v-bind=\"rootValue\"\n :locale=\"locale\"\n :disabled=\"field.disabled\"\n :readonly=\"field.readonly\"\n granularity=\"day\"\n prevent-deselect\n @update:model-value=\"onDateChange\"\n >\n <!-- The invalid marker lives out here, on the control as a whole, because\n the field group below already carries a `data-invalid` of Reka's own\n with a different meaning: that the *typed* date falls outside `min` and\n `max`. Two markers spelled the same on one element is how a style rule\n starts answering a question nobody asked it. -->\n <DatePickerAnchor\n ref=\"anchor\"\n :data-invalid=\"field.invalid || undefined\"\n :data-readonly=\"field.readonly || undefined\"\n :class=\"cn('block w-full', attrs.class as string)\"\n >\n <DatePickerField\n v-slot=\"{ segments }\"\n v-bind=\"{ ...fieldAttrs, ...field.attrs }\"\n :aria-labelledby=\"groupLabelledBy\"\n :class=\"\n cn(\n // The text input's own height scale, so a date sitting in a form\n // row beside a text field lines up rather than nearly lining up.\n // No gap: the separator between two segments is itself a segment,\n // so spacing them apart writes the date as `3 / 14 / 2026`.\n 'flex h-9 w-full items-center rounded-md border border-input bg-background px-3 text-sm text-foreground',\n 'transition-[color,background-color,border-color,box-shadow] duration-fast ease-out',\n // The box carries the ring, exactly as TextField's wrapper does,\n // and the focused segment below carries a fill instead of a second\n // outline — a ring drawn inside a ring reads as a rendering fault.\n 'focus-within:outline-2 focus-within:outline-offset-2 focus-within:outline-ring',\n !field.invalid && 'focus-within:shadow-halo',\n // Three resting appearances, and every one of them belongs to this\n // group rather than to the segments inside it. A fill painted per\n // segment leaves the literal separators between them on\n // `background`, and the control comes out striped.\n //\n // Read-only keeps its focus ring and its full-strength text: a\n // read-only date is a value on show, not an unavailable control,\n // and the two must not look alike. The fill lifts off `background`\n // to `subtle`, which holds the segments at 13.46:1, and the rim\n // stays `input` because nothing about the field's reach has moved —\n // it is still a Tab stop and still submitted. Reka's own\n // `data-readonly` on this group carries the same state to assistive\n // tech, so nothing here rests on colour.\n field.readonly && 'bg-subtle',\n // Unavailable is a *colour* and a *weight*, never an opacity.\n // `opacity-50` here faded the segments along with the box, and the\n // segments are the whole content of the control: `--color-foreground`\n // measures 14.09:1 on the resting fill and 2.99:1 once composited at\n // half alpha, with the literal separators and any placeholder\n // segment down at 2.02:1. The fill drains one step past read-only,\n // the text follows it to a measured 4.68:1, and the rim slackens\n // from `input` to `border` — so the two unavailable-looking states\n // part on three channels rather than on hue alone, which is what a\n // reader who cannot separate two greys has to have.\n //\n // The colour is set here rather than on each segment because no\n // segment declares one of its own in the resting state, so each\n // inherits this; `focus:text-primary` below is unreachable on a\n // control that cannot take focus.\n field.disabled && 'cursor-not-allowed border-border bg-muted text-muted-foreground',\n // Last of the rules that name a border colour, and the order is\n // load-bearing: `cn()` resolves a border colour by whichever class\n // it saw last, so a field that is both in error and unavailable\n // would otherwise lose its destructive rim to the disabled one.\n field.invalid && 'border-destructive focus-within:outline-destructive',\n )\n \"\n >\n <!-- Every `:aria-label` from here down replaces one Reka writes in\n English inside its own render function. Each reaches the DOM node\n as a fallthrough attribute, which Vue merges last, so it is a\n replacement rather than a second name. Removing one does not fall\n back to nothing; it falls back to Reka's English, which is the\n failure the label seam exists to close and which no test of Loom's\n own strings would catch. -->\n <DatePickerInput\n v-for=\"(item, index) in segments\"\n :key=\"index\"\n :part=\"item.part\"\n :tabindex=\"segmentTabIndex(item.part, segments)\"\n :aria-label=\"segmentLabel(item.part)\"\n v-bind=\"segmentValueText(item.part, item.value, fromIso(props.modelValue)?.month)\"\n :class=\"\n cn(\n 'tabular rounded-sm px-0.5 outline-none',\n 'transition-colors duration-instant ease-out',\n 'focus:bg-primary-muted focus:text-primary',\n 'data-[placeholder]:text-muted-foreground',\n item.part === 'literal' && 'text-muted-foreground',\n )\n \"\n @focusin=\"focusedPart = item.part\"\n >\n {{ item.value }}\n </DatePickerInput>\n\n <!-- Dropped entirely while read-only rather than disabled beside a\n field that is plainly still alive. Reka's `readonly` reaches the\n calendar too and makes every cell's click a no-op, so the button\n would open a panel in which nothing can be chosen — a dead end that\n looks like a working control, which is worse than not offering it.\n The segments are still there to read the date off. -->\n <DatePickerTrigger\n v-if=\"!field.readonly\"\n :aria-label=\"panelText.openCalendar\"\n class=\"ml-auto inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-sm text-muted-foreground transition-colors duration-fast ease-out hover:bg-subtle hover:text-foreground focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring disabled:cursor-not-allowed\"\n >\n <CalendarDays class=\"h-4 w-4\" />\n </DatePickerTrigger>\n </DatePickerField>\n </DatePickerAnchor>\n\n <DatePickerContent\n align=\"start\"\n :side-offset=\"6\"\n :class=\"\n cn(\n 'z-50 rounded-md border border-border bg-popover p-3 text-popover-foreground shadow-md outline-none',\n // Scoped to the open state, never unconditional. Reka's Presence\n // keeps the closed content mounted until an animationend arrives,\n // and a mount-only animation never fires a second one — so an\n // unconditional class strands an invisible panel over the page,\n // eating clicks. Scoped, the closed element computes\n // `animation-name: none` and Presence unmounts it immediately.\n 'data-[state=open]:animate-fade-rise',\n )\n \"\n @open-auto-focus=\"onOpenAutoFocus\"\n >\n <!-- The whole panel rises as one piece. The 42 cells deliberately carry\n no stagger of their own: `listStaggerDelay` is the vocabulary for a\n list of rows arriving in reading order, and a grid rippling in cell\n by cell reads as a rendering glitch rather than as an entrance. -->\n <div ref=\"panel\" class=\"flex flex-col gap-3\">\n <!-- `calendarLabel` is a real Reka prop rather than a literal to\n override, and it defaults to `\"Event Date\"` — a name for somebody\n else's application. It is published twice: as the calendar\n container's `aria-label`, and inside a visually-hidden live region\n Reka renders itself, which a fallthrough attribute could not have\n reached. -->\n <DatePickerCalendar v-slot=\"{ grid, weekDays }\" :calendar-label=\"panelText.calendar\">\n <DatePickerHeader class=\"flex items-center justify-between gap-2\">\n <!-- The two pagers keep `data-[disabled]:opacity-50` where the\n field and the cells gave it up, and the difference is what is\n inside them: a chevron and nothing else. Fading a glyph costs a\n reader nothing, and the buttons carry their name in\n `aria-label` rather than in dimmed text. -->\n <DatePickerPrev\n :aria-label=\"panelText.previousMonth\"\n class=\"inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-sm text-muted-foreground transition-colors duration-fast ease-out hover:bg-subtle hover:text-foreground focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring data-[disabled]:pointer-events-none data-[disabled]:opacity-50\"\n >\n <ChevronLeft class=\"h-4 w-4\" />\n </DatePickerPrev>\n\n <!-- Paging the calendar changes nothing a reader is looking at\n except this line, and nothing moves focus — so without the\n live region the month silently becomes a different month. -->\n <DatePickerHeading\n :id=\"headingId\"\n aria-live=\"polite\"\n class=\"text-sm font-medium text-foreground\"\n />\n\n <DatePickerNext\n :aria-label=\"panelText.nextMonth\"\n class=\"inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-sm text-muted-foreground transition-colors duration-fast ease-out hover:bg-subtle hover:text-foreground focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring data-[disabled]:pointer-events-none data-[disabled]:opacity-50\"\n >\n <ChevronRight class=\"h-4 w-4\" />\n </DatePickerNext>\n </DatePickerHeader>\n\n <DatePickerGrid\n v-for=\"month in grid\"\n :key=\"month.value.toString()\"\n role=\"grid\"\n :aria-labelledby=\"headingId\"\n class=\"border-collapse select-none\"\n >\n <!-- Reka renders `role=\"application\"` here, which hands every key\n straight to the page and takes the table's own semantics away\n with it. A calendar is a grid: `role=\"grid\"` is what makes the\n cells rows and columns to a screen reader rather than 42\n unrelated buttons, and the arrow-key handling Reka installs on\n the cells is what a grid promises anyway.\n\n The rows and cells below are laid out by the table itself\n rather than by flex, and that is load-bearing: `display: flex`\n on a `tr` drops its implicit `row` mapping in Chromium and\n WebKit, which leaves `role=\"gridcell\"` inside a grid with no\n row between them — a broken grid that looks identical. -->\n <DatePickerGridHead>\n <DatePickerGridRow>\n <DatePickerHeadCell\n v-for=\"(day, index) in weekDays\"\n :key=\"index\"\n class=\"w-9 text-xs font-normal text-muted-foreground\"\n >\n {{ day }}\n </DatePickerHeadCell>\n </DatePickerGridRow>\n </DatePickerGridHead>\n\n <DatePickerGridBody>\n <DatePickerGridRow v-for=\"(week, weekIndex) in month.rows\" :key=\"weekIndex\">\n <DatePickerCell\n v-for=\"day in week\"\n :key=\"day.toString()\"\n :date=\"day\"\n class=\"p-0 text-center\"\n >\n <!-- A day out of `min`/`max` range is drawn in colour rather\n than faded: the number is the cell's whole content, and\n `opacity-50` took `--color-foreground` from 14.09:1 on\n the popover to 3.13:1. Muted is 5.76:1 and the rule is\n written as `:not([data-selected])` so it can never order\n against the selected fill's own text colour — the same\n trick the range pickers use on their four competing\n fills. The strike is the second, hueless cue, and it is\n what keeps an unavailable day apart from an adjacent\n month's, which is muted too and still selectable. -->\n <DatePickerCellTrigger\n v-slot=\"{ dayValue, today }\"\n :day=\"day\"\n :month=\"month.value\"\n :aria-current=\"isDateToday(day) ? 'date' : undefined\"\n class=\"group relative inline-flex h-9 w-9 items-center justify-center rounded-sm text-sm text-foreground transition-colors duration-fast ease-out hover:bg-subtle focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:shadow-halo data-[outside-view]:text-muted-foreground data-[selected]:bg-primary data-[selected]:text-primary-foreground data-[disabled]:pointer-events-none data-[disabled]:line-through [&[data-disabled]:not([data-selected])]:text-muted-foreground\"\n >\n {{ dayValue }}\n <!-- Today's second cue. The dot is decoration to a screen\n reader — `aria-current` on the cell is what it reads —\n but it is the whole cue for a reader who is looking at\n the grid, and it is a shape rather than a hue so it\n survives a colour deficiency and forced-colors both. -->\n <span\n v-if=\"today\"\n aria-hidden=\"true\"\n class=\"absolute bottom-1 h-1 w-1 rounded-full bg-primary group-data-[selected]:bg-primary-foreground\"\n />\n </DatePickerCellTrigger>\n </DatePickerCell>\n </DatePickerGridRow>\n </DatePickerGridBody>\n </DatePickerGrid>\n </DatePickerCalendar>\n </div>\n </DatePickerContent>\n </DatePickerRoot>\n</template>\n"],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import DateRangePicker_vue_vue_type_script_setup_true_lang_default, { DATE_RANGE_LABELS } from "./DateRangePicker.vue_vue_type_script_setup_true_lang.js";
|
|
2
|
+
//#region src/primitives/DateRangePicker/DateRangePicker.vue
|
|
3
|
+
var DateRangePicker_default = DateRangePicker_vue_vue_type_script_setup_true_lang_default;
|
|
4
|
+
//#endregion
|
|
5
|
+
export { DATE_RANGE_LABELS, DateRangePicker_default as default };
|
|
6
|
+
|
|
7
|
+
//# sourceMappingURL=DateRangePicker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DateRangePicker.js","names":[],"sources":["../../../src/primitives/DateRangePicker/DateRangePicker.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { LabelOf } from \"../../lib/labels\";\nimport type {\n CalendarPanelLabels,\n DateSegmentLabels,\n RangeCellLabels,\n} from \"../../lib/date-labels\";\n\n/**\n * A span of days as the outside world holds it: two plain ISO `YYYY-MM-DD`\n * strings, both optional.\n *\n * An object rather than a `[start, end]` tuple, and both halves optional\n * rather than one string with a separator in it, because **a half-made range\n * has to be representable**. Between the first click and the second there is a\n * range with a start and no end, and that state lives on screen for as long as\n * it takes a reader to decide — a tuple has to fill the second slot with\n * something, and a single string has to invent a spelling for \"not yet\". Both\n * end up lying about a state the control is genuinely in. `{ start }` says it.\n *\n * It reads at a call site, too: `range.start` needs no comment, `range[0]`\n * needs one.\n */\nexport interface DateRange {\n /** The first day of the span, ISO `YYYY-MM-DD`. Absent while nothing has been chosen. */\n start?: string | undefined;\n /** The last day of the span, ISO `YYYY-MM-DD`, and part of it. Absent while only the start has been chosen. */\n end?: string | undefined;\n}\n\n/**\n * The strings this control says that no other member of the family says: the\n * two half-group names and the status line above the grids.\n *\n * They are **not** shared with `DateTimeRangePicker`, which says both in\n * different words and from different facts — `Start date` against `Start date\n * and time`, a count of whole days against a signed duration. A key shared\n * between them would have to be a sentence that is never true of both. Its\n * calendar cells' names *are* shared, in `rangeCell`, because those differ in\n * neither.\n *\n * The segment names and the calendar chrome, which every one of the five\n * shares, come from `src/lib/date-labels.ts` too.\n */\nexport interface DateRangeLabels {\n /** The group holding the first half of the field. Reka names a segment `day` or `year` alone, which is two identical sets of three names with nothing to tell the ends apart. */\n readonly startDate: string;\n /** The group holding the second half of the field. */\n readonly endDate: string;\n /**\n * The `role=\"status\"` line above the grids — what has been chosen, what is\n * wanted next, and how long the finished span is.\n *\n * One message rather than four phrases and a joiner. Which end is chosen,\n * whether a count follows the dates or precedes them, and how \"7 days\" is\n * written are all properties of a language, and a control that emitted them\n * as separate nodes would have decided all three in English.\n *\n * `days` counts **both ends**, which is how a reader counts a booking: the\n * 14th to the 20th is seven days. It arrives as a number so the plural\n * category is the host's to select — Loom ships no plural engine — and\n * `locale` arrives with it only because Loom's own English default has to\n * format the two dates somehow. A host replacing this formats with whatever\n * their application already uses and ignores it.\n */\n readonly status: LabelOf<{\n locale: string;\n start: DateValue | undefined;\n end: DateValue | undefined;\n days: number | undefined;\n }>;\n}\n\n/** A day, month and year in the control's locale — the status line's own shape, without the weekday a cell's name carries. */\nfunction formatDay(locale: string, date: DateValue): string {\n return new Intl.DateTimeFormat(locale, {\n day: \"numeric\",\n month: \"long\",\n year: \"numeric\",\n }).format(date.toDate(getLocalTimeZone()));\n}\n\n/**\n * Loom's English, co-located with the component so it tree-shakes with it, and\n * exported so a host can build a partial vocabulary against the real thing.\n *\n * The `day`/`days` choice below is English's plural rule sitting in English's\n * own bag, which is the only place a plural rule belongs. It is not extracted,\n * shared or applied to anything a host supplies: `status` hands over the number\n * and receives a finished sentence, so a language with one form or with six\n * selects its own.\n */\nexport const DATE_RANGE_LABELS: DateRangeLabels = {\n startDate: \"Start date\",\n endDate: \"End date\",\n status: ({ locale, start, end, days }) => {\n const anchor = start ?? end;\n if (!anchor) return \"No dates chosen. Choose the first day of the range.\";\n if (!start || !end || days === undefined) {\n return `${formatDay(locale, anchor)} chosen. Choose the last day of the range.`;\n }\n return `${formatDay(locale, start)} to ${formatDay(locale, end)}, ${String(days)} ${days === 1 ? \"day\" : \"days\"}.`;\n },\n};\n\n/**\n * Everything this control can be asked to say: the three shared slices, plus\n * its own. Annotate a bag with\n * `LabelOverrides<DateRangePickerLabels>` and never with this, which is total.\n */\nexport type DateRangePickerLabels = DateSegmentLabels &\n CalendarPanelLabels &\n RangeCellLabels &\n DateRangeLabels;\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, ref, useId, useTemplateRef } from \"vue\";\nimport {\n DateRangePickerRoot,\n DateRangePickerAnchor,\n DateRangePickerField,\n DateRangePickerInput,\n DateRangePickerTrigger,\n DateRangePickerContent,\n DateRangePickerCalendar,\n DateRangePickerHeader,\n DateRangePickerPrev,\n DateRangePickerHeading,\n DateRangePickerNext,\n DateRangePickerGrid,\n DateRangePickerGridHead,\n DateRangePickerGridRow,\n DateRangePickerHeadCell,\n DateRangePickerGridBody,\n DateRangePickerCell,\n DateRangePickerCellTrigger,\n} from \"reka-ui\";\nimport { CalendarRange, ChevronLeft, ChevronRight } from \"@lucide/vue\";\nimport {\n getLocalTimeZone,\n isSameDay,\n isToday,\n parseDate,\n toCalendarDate,\n type DateValue,\n} from \"@internationalized/date\";\nimport { cn } from \"../../lib/cn\";\nimport { useSplitAttrs } from \"../../lib/attrs\";\nimport { useAncestorDisabled } from \"../../lib/ancestor-disabled\";\nimport { useFieldControl } from \"../../lib/field-context\";\nimport { optional } from \"../../lib/props\";\nimport { useLabels, type LabelOverrides } from \"../../lib/labels\";\nimport {\n CALENDAR_PANEL_LABELS,\n DATE_SEGMENT_LABELS,\n RANGE_CELL_LABELS,\n emptySegmentValueText,\n isDateSegmentPart,\n type RangeCellPart,\n} from \"../../lib/date-labels\";\n\n/** The range as Reka models it, which is the same shape carrying calendar objects. */\ntype CalendarRangeValue = { start: DateValue | undefined; end: DateValue | undefined };\n\n/** Which end of the range a segment belongs to, as Reka's field parts name it. */\ntype SegmentType = \"start\" | \"end\";\n\n/**\n * DateRangePicker — a span of days with a first and a last, entered either by\n * typing both ends into one segmented field or by picking them out of a\n * two-month calendar. Reach for it wherever the value is the window rather\n * than the day: a report period, a booking, a filter over a table.\n *\n * It is DatePicker with two ends. Everything that control decides, this one\n * inherits and does not restate: the segmented field rather than a native\n * input, the roving tabindex that makes the whole field one Tab stop, the\n * popover owning its own open state rather than trusting a host to echo a\n * value back, the calendar laid out by a real table because `display: flex` on\n * a `tr` drops its row semantics, and the panel animating as one piece with no\n * per-cell stagger. Read `DatePicker.vue` for the reasoning behind each; the\n * comments below cover only what having two ends changes.\n *\n * **The model value is a pair of plain ISO date strings** — see `DateRange`\n * above for why it is an object with two optional halves rather than a tuple.\n * As in DatePicker, `min`, `max` and both emitted halves speak that one\n * format, and a value that does not parse is read as *not chosen* rather than\n * thrown on.\n *\n * Choosing the end before the start is not an error and is not refused: the\n * two are sorted on the way out, so a reader who clicks the 20th and then the\n * 14th gets `{ start: \"…-14\", end: \"…-20\" }`. Refusing it would mean a control\n * that rejects the second half of every backwards gesture with nothing on\n * screen explaining what it wanted instead.\n *\n * For a single day reach for DatePicker; for a day and a time together,\n * DateTimePicker. Two DatePickers side by side are two values and two\n * validations, and nothing between them knows that the second must not fall\n * before the first — which is the whole reason this control exists.\n *\n * Inside a [Field](../Field/Field.vue) it wires itself through\n * `useFieldControl()` — the row's id, the id of its hint or error line, and\n * `required` / `invalid` / `disabled` / `readonly` / `name` — so `<Field\n * label=\"Report period\" error=\"…\"><DateRangePicker /></Field>` needs no\n * attributes at the call site. Every prop below still wins over the row when it\n * is set, in both directions, which is why the four booleans default to\n * `undefined` rather than `false`. The row describes the field as a whole and\n * not either half: a description repeated onto both ends would be read out\n * twice for one span.\n */\nconst props = withDefaults(\n defineProps<{\n /**\n * The chosen span, as `{ start, end }` ISO `YYYY-MM-DD` strings. Either\n * half may be absent: `{}` is nothing chosen, `{ start }` is a range\n * half made. The explicit `| undefined` is what lets `v-model` bind a ref\n * that clears.\n */\n modelValue?: DateRange | undefined;\n /** The earliest choosable day, ISO `YYYY-MM-DD`. Days before it are announced disabled and skipped by the keyboard. */\n min?: string;\n /** The latest choosable day, ISO `YYYY-MM-DD`. Days after it are announced disabled and skipped by the keyboard. */\n max?: string;\n /** BCP 47 tag driving the order of the field's segments, the month and weekday names, and which day a week starts on. */\n locale?: string;\n /** How many months the calendar shows at once. Two is the default because a range is usually read across a month boundary; one is for a host that knows it is rendering into a narrow shell. */\n months?: 1 | 2;\n /** Unavailable: dims the control, refuses the calendar, and takes the field out of the tab order. Unset defers to a wrapping Field. */\n disabled?: boolean | undefined;\n /** Shows the span without allowing an edit: the field stays a Tab stop and stays submitted, and the calendar button is dropped because nothing in the calendar could be chosen. Unset defers to a wrapping Field. */\n readonly?: boolean | undefined;\n /** Error state: paints the destructive border and ring, and sets `aria-invalid`. Unset defers to a wrapping Field's `error`. */\n invalid?: boolean | undefined;\n /** Marks the field mandatory to assistive tech (`aria-required` on the group holding both halves). Unset defers to a wrapping Field. */\n required?: boolean | undefined;\n /** The field name for a native form post or `FormData`. Reka submits the whole span through one hidden input, as `start - end`. Unset defers to a wrapping Field. */\n name?: string;\n /**\n * Names for everything this control says out loud, as any subset of\n * `DateRangePickerLabels` — the rest stay as the host's `provideLoomLabels`\n * vocabulary left them, and then as Loom's English.\n *\n * This is the per-instance correction, not the place to localise an\n * application: six of the thirteen names replace English literals Reka UI\n * writes of its own accord, and a language is set once with\n * `provideLoomLabels`.\n */\n labels?: LabelOverrides<DateRangePickerLabels>;\n }>(),\n {\n locale: \"en\",\n months: 2,\n // Not `false`, for any of the four — TextField.vue carries the full\n // reasoning: `false` is a caller's decision that must beat the row, absent\n // is a caller saying nothing, and only `undefined` survives to mean that\n // past Vue's absent-Boolean-casts-to-false rule.\n disabled: undefined,\n readonly: undefined,\n invalid: undefined,\n required: undefined,\n },\n);\n\nconst emit = defineEmits<{\n /** The chosen span as ISO `YYYY-MM-DD` strings. A half-made range arrives as `{ start }`; a cleared one as `{}`. */\n \"update:modelValue\": [value: DateRange];\n}>();\n\nconst SEGMENT_TYPES: readonly SegmentType[] = [\"start\", \"end\"];\n\n// Four slots, one prop. There is no single `text` for the whole control\n// because there is no single slot: the segment names and the popover's chrome\n// are shared vocabularies with their own registry entries, and only the third\n// is this control's own. Naming them apart is what keeps a reader of the\n// template able to see which one a binding came from.\nconst dateText = useLabels(\"dateSegments\", DATE_SEGMENT_LABELS, () => props.labels);\nconst panelText = useLabels(\"calendarPanel\", CALENDAR_PANEL_LABELS, () => props.labels);\nconst cellText = useLabels(\"rangeCell\", RANGE_CELL_LABELS, () => props.labels);\nconst text = useLabels(\"dateRange\", DATE_RANGE_LABELS, () => props.labels);\n\n// Read through the ref on every call rather than resolved into a lookup table\n// once: a table built in `setup` freezes the first language and every later\n// switch silently does nothing. `undefined` for the `literal` separators, which\n// Reka renders `aria-hidden` and which must stay unnamed.\nfunction segmentLabel(part: string): string | undefined {\n return isDateSegmentPart(part) ? dateText.value[part] : undefined;\n}\n\n// The companion to `segmentLabel`, and the reason it returns an object rather\n// than a string is in `emptySegmentValueText`: Reka's `aria-valuetext` is a\n// hard-coded \"Empty\" only while the segment holds nothing, so this replaces\n// that case and leaves the filled one — a number, and the locale's own month\n// name — exactly as Reka wrote it.\n//\n// The month is the exception. See DatePicker's `segmentValueText` for the full\n// account; the same reasoning and the same `filledMonth` label apply here,\n// with the month taken from whichever half is rendering the segment.\nfunction segmentValueText(\n part: string,\n value: string,\n monthValue?: number,\n): { \"aria-valuetext\"?: string } {\n const empty = emptySegmentValueText(part, value, dateText.value.empty);\n if (empty[\"aria-valuetext\"]) return empty;\n if (part === \"month\" && monthValue !== undefined)\n return {\n \"aria-valuetext\": dateText.value.filledMonth({ value: monthValue, locale: props.locale }),\n };\n return {};\n}\n\n// Routed exactly as DatePicker routes it, and for the same reasons: `class`\n// sizes the whole control so it lands on the anchor, and everything else names\n// or describes the value, so it lands on the `role=\"group\"` field.\ndefineOptions({ inheritAttrs: false });\nconst { attrs, rest: fieldAttrs } = useSplitAttrs();\n\n/**\n * The segments are `<div role=\"spinbutton\" tabindex=\"0\">`, and\n * `<fieldset disabled>` reaches only `<input>`, `<button>`, `<select>` and\n * `<textarea>` — so the trigger button inside a disabled group went inert while\n * the segments beside it still typed. Measured on this branch: an empty `mm`\n * segment became `8` on an arrow key. Exactly the defect DatePicker carries,\n * and fixed exactly the way DatePicker fixes it.\n *\n * Read off the DOM rather than taken from the Field context, which publishes no\n * `disabled` on purpose — see `../../lib/ancestor-disabled.ts`.\n */\nconst anchor = useTemplateRef<{ $el?: Element }>(\"anchor\");\nconst groupDisabled = useAncestorDisabled(() => anchor.value?.$el);\n\n// `id` and `aria-describedby` reach this control as fallthrough attrs rather\n// than props, so they are handed in as this caller's own values: a caller who\n// sets either still beats the row, and the row's description is merged into\n// theirs. `field.attrs` then spreads onto `DateRangePickerField` **after**\n// `fieldAttrs`, which is the node both were already landing on — DatePicker.vue\n// carries the full account of that position and of where Reka then puts each\n// key. It is the outer field group and not either half's own group, which is\n// the point: a description repeated onto the start and the end is read out\n// twice for one span. The `:aria-invalid` binding that used to sit there went\n// with it — an individual attribute after a `v-bind` wins, so keeping one would\n// overwrite the resolved value.\nconst field = useFieldControl(() => ({\n id: attrs.id as string | undefined,\n describedBy: attrs[\"aria-describedby\"] as string | undefined,\n ariaLabelledby: attrs[\"aria-labelledby\"] as string | undefined,\n name: props.name,\n // The fieldset beats the prop in both directions, exactly as it does for the\n // trigger button inside this very control.\n disabled: groupDisabled.value ? true : props.disabled,\n readonly: props.readonly,\n invalid: props.invalid,\n required: props.required,\n}));\n\n// `aria-labelledby` for the group, resolved against the row — DatePicker's\n// reasoning, and the same three-way guard.\nconst groupLabelledBy = computed(() =>\n attrs[\"aria-label\"] || attrs[\"aria-labelledby\"] ? undefined : field.labelledBy,\n);\n\nfunction fromIso(value: string | undefined): DateValue | undefined {\n if (!value) return undefined;\n try {\n return parseDate(value);\n } catch {\n return undefined;\n }\n}\n\nfunction toIso(date: DateValue): string {\n return toCalendarDate(date).toString();\n}\n\nconst rootValue = computed(() =>\n optional({\n // Half of a range is still a range, so the two ends are converted\n // independently and an unparseable one only empties its own half. The\n // whole key is dropped when nothing at all is bound, which is what keeps\n // an unbound control uncontrolled — see `optional()`.\n modelValue: props.modelValue\n ? { start: fromIso(props.modelValue.start), end: fromIso(props.modelValue.end) }\n : undefined,\n minValue: fromIso(props.min),\n maxValue: fromIso(props.max),\n }),\n);\n\n// Owned here rather than left to Reka's `closeOnSelect`, for the reason\n// DatePicker gives. What differs is *when*: a range is not chosen until both\n// ends are, so the panel stays open over a half-made selection. Closing on the\n// first click would hide the calendar exactly when the reader still needs it.\nconst open = ref(false);\n\nfunction onRangeChange(range: CalendarRangeValue) {\n if (range.start && range.end) open.value = false;\n emit(\n \"update:modelValue\",\n optional({\n start: range.start ? toIso(range.start) : undefined,\n end: range.end ? toIso(range.end) : undefined,\n }),\n );\n}\n\nfunction isDateToday(date: DateValue): boolean {\n return isToday(date, getLocalTimeZone());\n}\n\n// One Tab stop for the whole field, not six. The roving stop is DatePicker's,\n// widened: Reka collects the start's segments and the end's into a single\n// ordered set and walks it with ArrowLeft/ArrowRight, so the two halves are\n// one continuous run and a stop per half would be an arbitrary place to make\n// a keyboard user press Tab. The remembered segment is therefore keyed by\n// half *and* part — `year` alone names two different segments here.\nconst focusedSegment = ref<string>();\n\nfunction segmentKey(type: SegmentType, part: string): string {\n return `${type}:${part}`;\n}\n\nfunction segmentTabIndex(\n type: SegmentType,\n part: string,\n segments: Record<SegmentType, readonly { part: string }[]>,\n): number | undefined {\n // Read-only keeps every stop it had, unlike disabled: the span is on show and\n // a reader still arrows across the segments to read it.\n if (field.disabled || part === \"literal\") return undefined;\n const editable = SEGMENT_TYPES.flatMap((each) =>\n segments[each]\n .filter((segment) => segment.part !== \"literal\")\n .map((segment) => segmentKey(each, segment.part)),\n );\n // Dropped when a locale change takes the remembered segment away, exactly as\n // in DatePicker: a field with no tab stop is unreachable.\n const active =\n focusedSegment.value !== undefined && editable.includes(focusedSegment.value)\n ? focusedSegment.value\n : editable[0];\n return segmentKey(type, part) === active ? 0 : -1;\n}\n\nconst headingId = useId();\n\n// Each grid's own name is formatted here rather than read off Reka because it\n// is needed in the parent scope of the cells, where Reka's slot props are not\n// in scope — and it is a date rather than a label, so `Intl` and `locale` are\n// the whole answer. A Thai reader gets a Buddhist year in it, as in the field.\nconst monthFormat = computed(\n () => new Intl.DateTimeFormat(props.locale, { month: \"long\", year: \"numeric\" }),\n);\n\nfunction format(formatter: Intl.DateTimeFormat, date: DateValue): string {\n return formatter.format(date.toDate(getLocalTimeZone()));\n}\n\nconst MS_PER_DAY = 86_400_000;\n\n/** Days in the span counting both ends, which is how a reader counts a booking. */\nfunction spanLength(start: DateValue, end: DateValue): number {\n const from = toCalendarDate(start).toDate(\"UTC\").getTime();\n const to = toCalendarDate(end).toDate(\"UTC\").getTime();\n return Math.round((to - from) / MS_PER_DAY) + 1;\n}\n\n// **This is the accessibility decision this control turns on.** The band of\n// highlight drawn between the anchor and the pointer is what makes a range\n// calendar legible, and it is worth nothing to a reader who is not looking at\n// it: the preview is a hover state, and a hover state has no reader.\n//\n// Reka gets a keyboard reader half of it for free — it moves the preview on\n// `focusin` as well as on `mouseenter`, so arrowing across the grid drags the\n// band along. That covers the reader who can see the grid and is not using a\n// pointer. It does nothing for the one who cannot.\n//\n// So the same information is published as text, in a `role=\"status\"` line\n// above the grids: which end has been chosen, what is wanted next, and once\n// both are in, the span and how long it is. It changes exactly when the\n// selection changes, which is what makes it announceable — a summary that\n// moved with every arrow key would be read over the cell the reader had just\n// landed on. The per-cell half of the story is `dayLabel` below.\nfunction rangeStatus(range: CalendarRangeValue): string {\n // The whole sentence is one label taking raw values — the two ends and a\n // count — rather than phrases this control joins. The `day`/`days` choice\n // that used to live here was English's plural rule written into a component\n // that renders in every language; it now lives in `DATE_RANGE_LABELS`, where\n // it applies to English and to nothing else.\n return text.value.status({\n locale: props.locale,\n start: range.start,\n end: range.end,\n days: range.start && range.end ? spanLength(range.start, range.end) : undefined,\n });\n}\n\n/**\n * A cell's part in the range, or nothing when it has none.\n *\n * The first, the last and every day between are three different states, and\n * the fills that carry them are three shades of one colour — which is a\n * distinction that survives neither a colour deficiency nor forced-colors\n * mode. Reka's own `aria-pressed` separates \"in the range\" from \"outside it\"\n * and stops there, so the three read identically to a screen reader. Naming\n * the part in the cell's accessible name is what tells them apart, and it is\n * also what makes the boundary case — a one-day range, where the first day is\n * also the last — say so rather than being announced twice as two things.\n */\nfunction rangePart(day: DateValue, range: CalendarRangeValue): RangeCellPart | undefined {\n const isStart = range.start !== undefined && isSameDay(day, range.start);\n const isEnd = range.end !== undefined && isSameDay(day, range.end);\n if (isStart && isEnd) return \"both\";\n if (isStart) return \"start\";\n if (isEnd) return \"end\";\n if (range.start && range.end && day.compare(range.start) > 0 && day.compare(range.end) < 0) {\n return \"within\";\n }\n return undefined;\n}\n\n// Reka labels every cell with its full date already; this replaces that label\n// rather than adding to it, because a cell's part in the range has to arrive\n// *with* the date and there is no second slot on an element for a name. The\n// date and the part are handed over raw: which side of the date the qualifier\n// belongs on is a property of the language, not of this control.\nfunction dayLabel(day: DateValue, range: CalendarRangeValue): string {\n return cellText.value.cell({ locale: props.locale, date: day, part: rangePart(day, range) });\n}\n\nconst panel = ref<HTMLElement | null>(null);\n\nfunction onOpenAutoFocus(event: Event) {\n const day = panel.value?.querySelector<HTMLElement>(\n '[data-reka-calendar-cell-trigger][tabindex=\"0\"]',\n );\n if (!day) return;\n event.preventDefault();\n day.focus();\n}\n</script>\n\n<template>\n <DateRangePickerRoot\n v-slot=\"{ modelValue: range }\"\n v-model:open=\"open\"\n v-bind=\"rootValue\"\n :locale=\"locale\"\n :disabled=\"field.disabled\"\n :readonly=\"field.readonly\"\n :number-of-months=\"months\"\n granularity=\"day\"\n prevent-deselect\n @update:model-value=\"onRangeChange\"\n >\n <!-- The invalid marker is on the control as a whole, not on the field:\n Reka spells its own `data-invalid` on the field group already, and\n there it means that the *typed* range is out of bounds or runs\n backwards. Same reasoning as DatePicker. -->\n <DateRangePickerAnchor\n ref=\"anchor\"\n :data-invalid=\"field.invalid || undefined\"\n :data-readonly=\"field.readonly || undefined\"\n :class=\"cn('block w-full', attrs.class as string)\"\n >\n <DateRangePickerField\n v-slot=\"{ segments }\"\n v-bind=\"{ ...fieldAttrs, ...field.attrs }\"\n :aria-labelledby=\"groupLabelledBy\"\n :class=\"\n cn(\n 'flex h-9 w-full items-center rounded-md border border-input bg-background px-3 text-sm text-foreground',\n 'transition-[color,background-color,border-color,box-shadow] duration-fast ease-out',\n 'focus-within:outline-2 focus-within:outline-offset-2 focus-within:outline-ring',\n !field.invalid && 'focus-within:shadow-halo',\n // Three resting appearances, all three painted on this group rather\n // than on the segments: a per-segment fill leaves the slashes and\n // the dash between the two halves on `background`, and the span\n // comes out striped.\n //\n // Read-only lifts to `subtle` and keeps its focus ring and its\n // full-strength text — a read-only span is a value on show, not an\n // unavailable control — with the rim left at `input`, because the\n // field is still a Tab stop and still submitted. Reka's own\n // `data-readonly` on this group says the same thing to assistive\n // tech, so nothing here rests on colour.\n field.readonly && 'bg-subtle',\n // Drained rather than faded, for the reason DatePicker writes out:\n // `opacity-50` took the six segments and the dash between them down\n // with the box, from 14.09:1 to 2.99:1 and the dash to 2.02:1. The\n // fill drains one step past read-only, the muted text over it is\n // 4.68:1, and the rim slackens from `input` to `border` — three\n // channels, so the two states do not part on hue alone. The dash\n // declares its own colour and the segments declare none, so this one\n // line covers both by inheritance.\n field.disabled && 'cursor-not-allowed border-border bg-muted text-muted-foreground',\n // Last of the rules that name a border colour: `cn()` resolves one\n // by whichever class it saw last, so a field both in error and\n // unavailable would otherwise lose its destructive rim.\n field.invalid && 'border-destructive focus-within:outline-destructive',\n )\n \"\n >\n <!-- Each half is its own named group. Reka labels a segment by its\n part alone — \"month\", \"day\", \"year\" — which is six segments and\n two identical sets of three names, and no way for a screen reader\n to tell which end of the range it is sitting in. The group is\n where that name belongs: it is announced once on entering the\n half, rather than folded into every segment.\n\n Every `:aria-label` from here down replaces one Reka writes in\n English inside its own render function, reaching the DOM node as a\n fallthrough attribute that Vue merges last. Removing one falls back\n not to nothing but to Reka's English. -->\n <template v-for=\"(type, typeIndex) in SEGMENT_TYPES\" :key=\"type\">\n <span v-if=\"typeIndex > 0\" aria-hidden=\"true\" class=\"px-1.5 text-muted-foreground\"\n >–</span\n >\n\n <div\n role=\"group\"\n :aria-label=\"type === 'start' ? text.startDate : text.endDate\"\n class=\"flex items-center\"\n >\n <DateRangePickerInput\n v-for=\"(item, index) in segments[type]\"\n :key=\"index\"\n :part=\"item.part\"\n :type=\"type\"\n :tabindex=\"segmentTabIndex(type, item.part, segments)\"\n :aria-label=\"segmentLabel(item.part)\"\n v-bind=\"\n segmentValueText(\n item.part,\n item.value,\n (type === 'start' ? range.start : range.end)?.month,\n )\n \"\n :class=\"\n cn(\n 'tabular rounded-sm px-0.5 outline-none',\n 'transition-colors duration-instant ease-out',\n 'focus:bg-primary-muted focus:text-primary',\n 'data-[placeholder]:text-muted-foreground',\n item.part === 'literal' && 'text-muted-foreground',\n )\n \"\n @focusin=\"focusedSegment = segmentKey(type, item.part)\"\n >\n {{ item.value }}\n </DateRangePickerInput>\n </div>\n </template>\n\n <!-- Dropped entirely while read-only, as in DatePicker: Reka's\n `readonly` reaches the calendar and makes every cell's click a\n no-op, so the button would open a panel in which no range can be\n chosen. The segments are still there to read the span off. -->\n <DateRangePickerTrigger\n v-if=\"!field.readonly\"\n :aria-label=\"panelText.openCalendar\"\n class=\"ml-auto inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-sm text-muted-foreground transition-colors duration-fast ease-out hover:bg-subtle hover:text-foreground focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring disabled:cursor-not-allowed\"\n >\n <CalendarRange class=\"h-4 w-4\" />\n </DateRangePickerTrigger>\n </DateRangePickerField>\n </DateRangePickerAnchor>\n\n <DateRangePickerContent\n align=\"start\"\n :side-offset=\"6\"\n :class=\"\n cn(\n 'z-50 rounded-md border border-border bg-popover p-3 text-popover-foreground shadow-md outline-none',\n // Scoped to the open state, never unconditional — DatePicker carries\n // the full account of why.\n 'data-[state=open]:animate-fade-rise',\n )\n \"\n @open-auto-focus=\"onOpenAutoFocus\"\n >\n <div ref=\"panel\" class=\"flex flex-col gap-3\">\n <!-- `calendarLabel` is a real Reka prop rather than a literal to\n override, and it defaults to `\"Event Date\"`. It is published twice:\n as the calendar container's `aria-label`, and inside a\n visually-hidden live region Reka renders itself, which a\n fallthrough attribute could not have reached. -->\n <DateRangePickerCalendar v-slot=\"{ grid, weekDays }\" :calendar-label=\"panelText.calendar\">\n <DateRangePickerHeader class=\"flex items-center justify-between gap-2\">\n <!-- The pagers keep their opacity where the field and the cells gave\n it up: a chevron is a glyph, and fading one costs a reader\n nothing. Their names live in `aria-label`, not in dimmed text. -->\n <DateRangePickerPrev\n :aria-label=\"panelText.previousMonth\"\n class=\"inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-sm text-muted-foreground transition-colors duration-fast ease-out hover:bg-subtle hover:text-foreground focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring data-[disabled]:pointer-events-none data-[disabled]:opacity-50\"\n >\n <ChevronLeft class=\"h-4 w-4\" />\n </DateRangePickerPrev>\n\n <DateRangePickerHeading\n :id=\"headingId\"\n aria-live=\"polite\"\n class=\"text-sm font-medium text-foreground\"\n />\n\n <DateRangePickerNext\n :aria-label=\"panelText.nextMonth\"\n class=\"inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-sm text-muted-foreground transition-colors duration-fast ease-out hover:bg-subtle hover:text-foreground focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring data-[disabled]:pointer-events-none data-[disabled]:opacity-50\"\n >\n <ChevronRight class=\"h-4 w-4\" />\n </DateRangePickerNext>\n </DateRangePickerHeader>\n\n <p role=\"status\" class=\"text-xs text-muted-foreground\">{{ rangeStatus(range) }}</p>\n\n <!-- Two months stacked below `sm`, side by side above it — and both\n of them in the document at every width. Hiding the second one\n instead would be a keyboard trap of the quiet kind: Reka walks\n the arrow keys by looking up the next day's `[data-value]` in\n the panel and calling `focus()` on it, and `display: none`\n leaves the element findable and unfocusable, so the reader\n presses ArrowRight at the end of the first month and nothing at\n all happens. A tall panel is a worse layout; a silent dead end\n is a worse control. -->\n <div class=\"flex flex-col gap-3 sm:flex-row sm:gap-5\">\n <DateRangePickerGrid\n v-for=\"month in grid\"\n :key=\"month.value.toString()\"\n role=\"grid\"\n :aria-label=\"format(monthFormat, month.value)\"\n class=\"border-collapse select-none\"\n >\n <!-- `role=\"grid\"` over Reka's `role=\"application\"`, and the rows\n laid out by the table rather than by flex: DatePicker\n carries the reasoning for both. The name is each grid's own\n month rather than the shared heading, because two grids\n sharing one name leaves a reader entering the second with\n no idea which month they are in. -->\n <DateRangePickerGridHead>\n <DateRangePickerGridRow>\n <DateRangePickerHeadCell\n v-for=\"(day, index) in weekDays\"\n :key=\"index\"\n class=\"w-9 text-xs font-normal text-muted-foreground\"\n >\n {{ day }}\n </DateRangePickerHeadCell>\n </DateRangePickerGridRow>\n </DateRangePickerGridHead>\n\n <DateRangePickerGridBody>\n <DateRangePickerGridRow v-for=\"(week, weekIndex) in month.rows\" :key=\"weekIndex\">\n <DateRangePickerCell\n v-for=\"day in week\"\n :key=\"day.toString()\"\n :date=\"day\"\n class=\"p-0 text-center\"\n >\n <DateRangePickerCellTrigger\n v-slot=\"{ dayValue, today }\"\n :day=\"day\"\n :month=\"month.value\"\n :aria-label=\"dayLabel(day, range)\"\n :aria-current=\"isDateToday(day) ? 'date' : undefined\"\n :class=\"\n cn(\n 'group relative inline-flex h-9 w-9 items-center justify-center rounded-sm text-sm text-foreground',\n 'transition-colors duration-fast ease-out hover:bg-subtle',\n // The outline sits outside the cell and the halo\n // outside that, so neither is painted over by the\n // fill of the day beside it — which is what keeps\n // the focused day findable in the middle of a\n // filled band.\n 'focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:shadow-halo',\n 'data-[outside-view]:text-muted-foreground',\n // Out of range is drawn in colour and struck through\n // rather than faded: the number is the cell's whole\n // content, and half alpha took `--color-foreground`\n // from 14.09:1 on the popover to 3.13:1. Muted is\n // 5.76:1, and the `:not([data-selected])` is there for\n // exactly the reason the fills below are — it keeps\n // this colour from having to order against the\n // selection's own. The strike is the hueless second\n // cue, and it is what separates an unavailable day\n // from an adjacent month's: muted too, still pickable.\n 'data-[disabled]:pointer-events-none data-[disabled]:line-through',\n '[&[data-disabled]:not([data-selected])]:text-muted-foreground',\n // Four fills compete on one cell — the two ends, the\n // days between, and the uncommitted preview — and\n // between two variants of the same property the\n // winner is whichever Tailwind emits last, which is\n // not something a class list can state. Writing the\n // three weaker ones as `:not()` of the stronger\n // makes them mutually exclusive, so no cell ever has\n // two backgrounds to order and the result does not\n // depend on generated stylesheet order.\n 'data-[selection-start]:bg-primary data-[selection-start]:text-primary-foreground',\n 'data-[selection-end]:bg-primary data-[selection-end]:text-primary-foreground',\n '[&[data-selected]:not([data-selection-start]):not([data-selection-end])]:bg-primary-muted',\n '[&[data-selected]:not([data-selection-start]):not([data-selection-end])]:text-primary',\n // The preview is deliberately the neutral hover\n // surface rather than a wash of the action colour:\n // it is a proposal, and it must not read as a range\n // that has already been made.\n '[&[data-highlighted]:not([data-selected])]:bg-subtle',\n // Square in the middle so the band reads as one\n // stretch of days rather than a row of pills.\n '[&[data-selected]:not([data-selection-start]):not([data-selection-end])]:rounded-none',\n '[&[data-highlighted]:not([data-highlighted-start]):not([data-highlighted-end])]:rounded-none',\n )\n \"\n >\n {{ dayValue }}\n <span\n v-if=\"today\"\n aria-hidden=\"true\"\n class=\"absolute bottom-1 h-1 w-1 rounded-full bg-primary group-data-[selection-start]:bg-primary-foreground group-data-[selection-end]:bg-primary-foreground\"\n />\n </DateRangePickerCellTrigger>\n </DateRangePickerCell>\n </DateRangePickerGridRow>\n </DateRangePickerGridBody>\n </DateRangePickerGrid>\n </div>\n </DateRangePickerCalendar>\n </div>\n </DateRangePickerContent>\n </DateRangePickerRoot>\n</template>\n"],"mappings":""}
|