@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 @@
|
|
|
1
|
+
{"version":3,"file":"OtpInput.js","names":[],"sources":["../../../src/primitives/OtpInput/OtpInput.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { LabelOf } from \"../../lib/labels\";\n\n/**\n * What a cell accepts, and what keyboard a phone raises for it. `numeric` is\n * digits only; `text` takes any character, for an alphanumeric backup code.\n */\nexport type OtpInputType = \"numeric\" | \"text\";\n\n/**\n * The one name this control publishes, and it replaces one Reka writes in\n * English of its own accord: `PinInputInput` labels every cell\n * `` `pin input ${index + 1} of ${length}` `` and exposes no prop for it.\n *\n * **One key, not \"Digit\" plus \"Character\" plus a joiner plus a position.** The\n * noun and the two numbers arrive together in one argument object, and the\n * variant — whether this row takes digits or any character — arrives with\n * them, because which word a language uses for a cell and where the position\n * sits relative to it are one decision rather than two. Four fragment keys\n * Loom then joined would be a sentence no translator could reorder.\n *\n * `index` is 1-based: it is a position a person is being read, not an offset\n * into an array, and handing over the 0-based one would make every override\n * write `index + 1` before it could say anything.\n */\nexport interface OtpInputLabels {\n /** One cell, named for what it takes and where it sits in the row. */\n readonly cell: LabelOf<{ index: number; length: number; type: OtpInputType }>;\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 */\nexport const OTP_INPUT_LABELS: OtpInputLabels = {\n cell: ({ index, length, type }) =>\n `${type === \"numeric\" ? \"Digit\" : \"Character\"} ${String(index)} of ${String(length)}`,\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, ref, watch } from \"vue\";\nimport { PinInputInput, PinInputRoot } from \"reka-ui\";\nimport { cn } from \"../../lib/cn\";\nimport { useSplitAttrs } from \"../../lib/attrs\";\nimport { useFieldControl } from \"../../lib/field-context\";\nimport { useLabels, type LabelOverrides } from \"../../lib/labels\";\nimport { optional } from \"../../lib/props\";\n\n/**\n * OtpInput — the row of single-character cells a one-time code or a short PIN\n * is typed into. Reach for it when the value really is a fixed-length code\n * that arrives out of band: the cells are what let `autocomplete=\"one-time-code\"`\n * offer the code the phone has just received, and `inputmode=\"numeric\"` is what\n * raises the digit keypad rather than the alphabet. Both are the reason this\n * exists at all rather than a TextField with a `maxlength` — and both are also\n * why anything a reader would want to read back, correct in the middle, or\n * paste in parts belongs in a TextField instead.\n *\n * Built on Reka UI's PinInput, which supplies the per-cell behaviour: typing\n * advances to the next cell, arrow keys move between them, Backspace on an\n * empty cell steps back and clears the one before it, and a pasted code is\n * distributed across the whole row rather than crammed into one cell.\n *\n * Two things are decided here that Reka leaves open.\n *\n * **The value is a scalar `string`.** Reka models it as an array of cells;\n * this exposes `\"1234\"`, exactly as Slider exposes a scalar where Reka models\n * an array — a code is what a host posts to an API and compares against, and\n * neither of those wants a six-element array. In numeric mode Reka's array is\n * even an array of *numbers*, which loses a leading zero the moment anyone\n * treats it as one value. The consequence is in `onUpdate`.\n *\n * **The row is one control, not `length` of them.** Reka names each cell and\n * leaves each one tabbable, which is how this control usually fails: six\n * inputs each announcing themselves in full, and six Tab presses to step over\n * a field a sighted user reads as one. The name of the thing being typed is\n * moved onto a labelled `role=\"group\"` so it is announced once on entering the\n * row, each cell is left with its position alone, and a roving tabindex makes\n * the row a single Tab stop.\n *\n * Inside a [Field](../Field/Field.vue) it wires itself through\n * `useFieldControl()`, and this control is the one where the resolved values\n * do not all land on the same node. The id of the row's hint or error line\n * describes the whole code and goes on the group; `required` and `invalid` are\n * states of the boxes being typed into and go on the cells, where the roles\n * that support them are — `role=\"group\"` supports neither. The row's id and\n * the name the code is submitted under both go to Reka's hidden input: `id` is\n * a declared prop of its root rather than a fallthrough attr, and that input is\n * the better target anyway, since `<label for>` associates only with a\n * labelable element and hands focus to the first cell from there.\n *\n * What a Field still cannot do here is *name* the row: its `<label>` reaches\n * the hidden input, which is `aria-hidden`, so no accessible name is computed\n * from it. Give the name with `ariaLabel` or `ariaLabelledby` as you would\n * outside a row.\n *\n * A row's `readonly` is deliberately ignored. There is nothing to read in an\n * uneditable code box that a line of text would not show better, and the cells\n * exist to be typed into. So the library's three resting appearances collapse\n * to two here: a cell goes straight from `background` to the disabled row's\n * drained fill, muted character and slackened rim, and the lifted `subtle` fill\n * that marks a value on show never appears on this control.\n */\nconst props = withDefaults(\n defineProps<{\n /** The code entered so far. Shorter than `length` while it is incomplete. */\n modelValue?: string;\n /** How many cells the code is typed into. */\n length?: number;\n /** What a cell accepts: digits only, or any character. */\n type?: OtpInputType;\n /** Renders every filled cell as a dot instead of its character, for a PIN typed in public. */\n mask?: boolean;\n /** Unavailable: dims the row and refuses every cell. Unset defers to a wrapping Field. */\n disabled?: boolean | undefined;\n /** Error state: paints the destructive border and ring, and sets `aria-invalid` on every cell. Unset defers to a wrapping Field's `error`. */\n invalid?: boolean | undefined;\n /** The accessible name of the whole row, when no visible element already labels it. */\n ariaLabel?: string;\n /** The id of the visible element that labels the row — a heading, or a field's own label. */\n ariaLabelledby?: string;\n /**\n * The name each cell gives itself, as any subset of `OtpInputLabels` — the\n * rest stay as the host's `provideLoomLabels` vocabulary left them, and\n * then as Loom's English.\n *\n * This is the per-instance correction, not the place to localise an\n * application: the case it exists for is a row whose cells are neither\n * digits nor characters in the reader's terms — the groups of a licence\n * key, say — where the noun has to say so however well the application is\n * translated.\n */\n labels?: LabelOverrides<OtpInputLabels>;\n }>(),\n {\n length: 6,\n type: \"numeric\",\n mask: false,\n // Not `false`, for either. `false` is a caller saying \"this row is fine /\n // enabled even though the field around it 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 — see TextField.vue, which carries\n // the full reasoning.\n disabled: undefined,\n invalid: undefined,\n },\n);\n\nconst emit = defineEmits<{\n /** The code so far, as one string. Fires on every cell that fills or clears. */\n \"update:modelValue\": [value: string];\n /** The finished code. Fires once, as the last empty cell takes its character. */\n complete: [value: string];\n}>();\n\n// `text`, not `labels`: the prop of that name is one of the three sources this\n// resolves, and a template reading the raw prop would be reading the overrides\n// rather than the answer.\nconst text = useLabels(\"otpInput\", OTP_INPUT_LABELS, () => props.labels);\n\n// Every fallthrough attribute lands on the group: an `aria-describedby`\n// pointing at an error line, a `data-testid`, an `id` — each describes the\n// control as a whole, and copying one onto `length` inputs would have a screen\n// reader repeat it on every cell. `class` is pulled out of that spread only so\n// it can go through `cn()`, which is what lets a caller's utility beat the\n// row's own instead of losing to whichever Tailwind emitted last.\ndefineOptions({ inheritAttrs: false });\nconst { attrs, rest: groupAttrs } = useSplitAttrs();\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. `name`,\n// `readonly` and `required` are absent from this object because there is no\n// prop to oppose the row with; the row's answer stands unopposed, which is\n// what is wanted.\nconst field = useFieldControl(() => ({\n id: attrs.id as string | undefined,\n describedBy: attrs[\"aria-describedby\"] as string | undefined,\n ariaLabelledby: props.ariaLabelledby,\n disabled: props.disabled,\n invalid: props.invalid,\n}));\n\n// Three of the resolved keys do not travel with the bag, because the bag lands\n// on the group and the group is the wrong node for all three.\n//\n// `name` would be a `name` on a `<div>`, which no form reads; Reka's own\n// hidden input carries the joined code, so the row's name is given to the root\n// as a prop instead.\n//\n// `aria-required` and `aria-invalid` are states of the boxes a reader types\n// into, and `role=\"group\"` supports neither — `aria-invalid` is a global so it\n// would at least be legal there, `aria-required` is not and would fail\n// `aria-allowed-attr`. Both are bound per cell below, off the same resolved\n// values, so the row's error reaches the element a screen reader is actually\n// sitting on.\n//\n// `id` stays in the bag and still does not land here: it is a declared prop of\n// Reka's root, so it is taken as a prop rather than falling through, and Reka\n// puts it on that same hidden input — which is the labelable node a\n// `<label for>` needs, and the one that hands focus to the first cell.\nconst groupFieldAttrs = computed(() => {\n // Removed from a copy rather than listed positively, so a key added to the\n // resolved bag later reaches this group without anyone remembering to come\n // back here.\n const group: Record<string, unknown> = { ...field.attrs };\n delete group.name;\n delete group[\"aria-required\"];\n delete group[\"aria-invalid\"];\n return group;\n});\n\n// The single source of truth for the code we know about: seeded from the prop,\n// then advanced on every update Reka reports. Feeding this back into Reka\n// rather than `props.modelValue` is what keeps the row usable for a host that\n// binds no `modelValue` at all — the same buffer Slider keeps, for the same\n// reason. An absent prop leaves it empty rather than sticking the row on one\n// value, so nothing here needs `optional()`.\nconst code = ref(props.modelValue ?? \"\");\nwatch(\n () => props.modelValue,\n (value) => {\n if (value !== undefined) code.value = value;\n },\n);\n\n// Longer than the row is the host's mistake to make, not ours to render: the\n// extra characters have no cell to live in.\nconst cells = computed(() => code.value.slice(0, props.length).split(\"\"));\n\n// Reka calls the digits-only mode \"number\". The prop says \"numeric\" because\n// nothing about the value is a number — a code with a leading zero is a\n// string, and this control never parses one.\nconst pinType = computed(() => (props.type === \"numeric\" ? \"number\" : \"text\"));\n\n// The row is one Tab stop. The stop is the first empty cell, which is also\n// where Reka's own `otp` handling redirects focus, or the last cell once the\n// code is full — so Tab lands where the next character goes.\nconst tabStopIndex = computed(() => Math.min(code.value.length, props.length - 1));\n\n// Typed wider than the declared emit on purpose: in numeric mode the array\n// really does come back holding numbers, and a cleared middle cell comes back\n// as a hole. Both are why a scalar is the exposed shape.\nfunction onUpdate(next: (string | number)[]) {\n // `join` is where the scalar is decided, and it closes gaps: Reka can hold a\n // cleared middle cell as a hole, a string cannot, so the cells after it\n // shift left. That is the only reading that keeps the model and the row\n // agreeing on one value — and it is what a single text input does when a\n // character in the middle is deleted.\n const value = next.join(\"\");\n // Reka reports the whole row on every write, including a write that changed\n // nothing a string can see — pasting the same code over itself is the\n // reachable one. Stopping here keeps one changed code to one emitted value,\n // and one filled code to one `complete`.\n if (value === code.value) return;\n code.value = value;\n emit(\"update:modelValue\", value);\n // Derived here rather than forwarded from Reka's own `complete`, which fires\n // from a deep watcher on its model — and that model is set twice for one\n // keystroke once the row is controlled, once by Reka and once by the value\n // coming back around. Forwarding it would announce one filled code twice.\n if (value.length === props.length) emit(\"complete\", value);\n}\n</script>\n\n<template>\n <PinInputRoot\n v-bind=\"{ ...groupAttrs, ...groupFieldAttrs, ...optional({ name: field.name }) }\"\n :model-value=\"cells\"\n :type=\"pinType\"\n :mask=\"mask\"\n :disabled=\"field.disabled\"\n otp\n role=\"group\"\n :aria-label=\"ariaLabelledby ? undefined : ariaLabel\"\n :aria-labelledby=\"ariaLabelledby || (!ariaLabel ? field.labelledBy : undefined)\"\n :data-invalid=\"field.invalid || undefined\"\n :class=\"cn('inline-flex items-center gap-2', attrs.class as string)\"\n @update:model-value=\"onUpdate\"\n >\n <!-- The `:aria-label` replaces the one Reka writes inside its own render\n function — \"pin input 3 of 6\", the field's whole purpose restated once\n per cell. It reaches the DOM node as a fallthrough attribute, which Vue\n merges last, so it is a replacement rather than a second name. Removing\n it does not fall back to nothing; it falls back to Reka's English. The\n group carries the purpose, and a cell carries only where it sits. -->\n <PinInputInput\n v-for=\"cell in length\"\n :key=\"cell\"\n :index=\"cell - 1\"\n :tabindex=\"cell - 1 === tabStopIndex ? 0 : -1\"\n :aria-label=\"text.cell({ index: cell, length, type })\"\n :aria-required=\"field.required || undefined\"\n :aria-invalid=\"field.invalid || undefined\"\n :data-filled=\"cell <= code.length || undefined\"\n :class=\"\n cn(\n // Square, on the control scale's tallest step: a code cell is a\n // touch target before it is a form row, and 44px is the size a thumb\n // is aimed at. `tabular` keeps the six glyphs on one width so the\n // row does not breathe as it fills.\n 'tabular h-11 w-11 rounded-md border border-input bg-background text-center text-base text-foreground',\n 'transition-[color,background-color,border-color,box-shadow] duration-fast ease-out',\n // Rim-lit at rest; the ring blooms on the cell being typed into.\n 'focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring',\n !field.invalid && 'focus-visible:shadow-halo',\n // A filled cell is legible as filled from its character — or its\n // mask dot — alone. The heavier border is a second, redundant cue,\n // and a weight rather than a hue, so it survives both a colour\n // deficiency and forced-colors.\n //\n // Withheld from an unavailable row, and only because the border is\n // also the third channel of the disabled state below: two rules\n // moving the same rim in opposite directions would leave a\n // half-filled disabled row with a heavier edge than an empty one,\n // which reads as the more available of the two. The cue is redundant\n // by construction, so the state wins it.\n !field.disabled && 'data-[filled]:border-border-strong',\n // Unavailable is a *colour* and a *weight*, never an opacity. A cell\n // holds one character — or one mask dot — and that is the entire\n // content of the control, so `opacity-50` here did not dim a code so\n // much as erase it: `--color-foreground` measures 14.09:1 on the\n // resting fill and 2.99:1 once composited at half alpha. The drained\n // fill carries the state instead, the character stays at a measured\n // 4.68:1, and the rim slackens from `input` to `border` so the state\n // is not told in hue alone.\n //\n // The fill and the text colour are `disabled:` variants rather than\n // plain classes, so each outranks the resting `bg-background\n // text-foreground` above on specificity rather than on where Tailwind\n // happened to emit it. The border cannot join them: a `disabled:`\n // variant would outrank the plain `border-destructive` below, and a\n // row that is both in error and unavailable has to keep saying so.\n 'disabled:cursor-not-allowed disabled:bg-muted disabled:text-muted-foreground',\n field.disabled && 'border-border',\n field.invalid && 'border-destructive focus-visible:outline-destructive',\n )\n \"\n />\n </PinInputRoot>\n</template>\n"],"mappings":""}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { type LabelOverrides } from "../../lib/labels";
|
|
2
|
+
import type { LabelOf } from "../../lib/labels";
|
|
3
|
+
/**
|
|
4
|
+
* What a cell accepts, and what keyboard a phone raises for it. `numeric` is
|
|
5
|
+
* digits only; `text` takes any character, for an alphanumeric backup code.
|
|
6
|
+
*/
|
|
7
|
+
export type OtpInputType = "numeric" | "text";
|
|
8
|
+
/**
|
|
9
|
+
* The one name this control publishes, and it replaces one Reka writes in
|
|
10
|
+
* English of its own accord: `PinInputInput` labels every cell
|
|
11
|
+
* `` `pin input ${index + 1} of ${length}` `` and exposes no prop for it.
|
|
12
|
+
*
|
|
13
|
+
* **One key, not "Digit" plus "Character" plus a joiner plus a position.** The
|
|
14
|
+
* noun and the two numbers arrive together in one argument object, and the
|
|
15
|
+
* variant — whether this row takes digits or any character — arrives with
|
|
16
|
+
* them, because which word a language uses for a cell and where the position
|
|
17
|
+
* sits relative to it are one decision rather than two. Four fragment keys
|
|
18
|
+
* Loom then joined would be a sentence no translator could reorder.
|
|
19
|
+
*
|
|
20
|
+
* `index` is 1-based: it is a position a person is being read, not an offset
|
|
21
|
+
* into an array, and handing over the 0-based one would make every override
|
|
22
|
+
* write `index + 1` before it could say anything.
|
|
23
|
+
*/
|
|
24
|
+
export interface OtpInputLabels {
|
|
25
|
+
/** One cell, named for what it takes and where it sits in the row. */
|
|
26
|
+
readonly cell: LabelOf<{
|
|
27
|
+
index: number;
|
|
28
|
+
length: number;
|
|
29
|
+
type: OtpInputType;
|
|
30
|
+
}>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Loom's English, co-located with the component so it tree-shakes with it, and
|
|
34
|
+
* exported so a host can build a partial vocabulary against the real thing.
|
|
35
|
+
*/
|
|
36
|
+
export declare const OTP_INPUT_LABELS: OtpInputLabels;
|
|
37
|
+
declare const _default: typeof __VLS_export;
|
|
38
|
+
export default _default;
|
|
39
|
+
declare const __VLS_export: import("vue").DefineComponent<{
|
|
40
|
+
/** The code entered so far. Shorter than `length` while it is incomplete. */
|
|
41
|
+
modelValue?: string;
|
|
42
|
+
/** How many cells the code is typed into. */
|
|
43
|
+
length?: number;
|
|
44
|
+
/** What a cell accepts: digits only, or any character. */
|
|
45
|
+
type?: OtpInputType;
|
|
46
|
+
/** Renders every filled cell as a dot instead of its character, for a PIN typed in public. */
|
|
47
|
+
mask?: boolean;
|
|
48
|
+
/** Unavailable: dims the row and refuses every cell. Unset defers to a wrapping Field. */
|
|
49
|
+
disabled?: boolean | undefined;
|
|
50
|
+
/** Error state: paints the destructive border and ring, and sets `aria-invalid` on every cell. Unset defers to a wrapping Field's `error`. */
|
|
51
|
+
invalid?: boolean | undefined;
|
|
52
|
+
/** The accessible name of the whole row, when no visible element already labels it. */
|
|
53
|
+
ariaLabel?: string;
|
|
54
|
+
/** The id of the visible element that labels the row — a heading, or a field's own label. */
|
|
55
|
+
ariaLabelledby?: string;
|
|
56
|
+
/**
|
|
57
|
+
* The name each cell gives itself, as any subset of `OtpInputLabels` — the
|
|
58
|
+
* rest stay as the host's `provideLoomLabels` vocabulary left them, and
|
|
59
|
+
* then as Loom's English.
|
|
60
|
+
*
|
|
61
|
+
* This is the per-instance correction, not the place to localise an
|
|
62
|
+
* application: the case it exists for is a row whose cells are neither
|
|
63
|
+
* digits nor characters in the reader's terms — the groups of a licence
|
|
64
|
+
* key, say — where the noun has to say so however well the application is
|
|
65
|
+
* translated.
|
|
66
|
+
*/
|
|
67
|
+
labels?: LabelOverrides<OtpInputLabels>;
|
|
68
|
+
}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
69
|
+
"update:modelValue": (value: string) => any;
|
|
70
|
+
complete: (value: string) => any;
|
|
71
|
+
}, string, import("vue").PublicProps, Readonly<{
|
|
72
|
+
/** The code entered so far. Shorter than `length` while it is incomplete. */
|
|
73
|
+
modelValue?: string;
|
|
74
|
+
/** How many cells the code is typed into. */
|
|
75
|
+
length?: number;
|
|
76
|
+
/** What a cell accepts: digits only, or any character. */
|
|
77
|
+
type?: OtpInputType;
|
|
78
|
+
/** Renders every filled cell as a dot instead of its character, for a PIN typed in public. */
|
|
79
|
+
mask?: boolean;
|
|
80
|
+
/** Unavailable: dims the row and refuses every cell. Unset defers to a wrapping Field. */
|
|
81
|
+
disabled?: boolean | undefined;
|
|
82
|
+
/** Error state: paints the destructive border and ring, and sets `aria-invalid` on every cell. Unset defers to a wrapping Field's `error`. */
|
|
83
|
+
invalid?: boolean | undefined;
|
|
84
|
+
/** The accessible name of the whole row, when no visible element already labels it. */
|
|
85
|
+
ariaLabel?: string;
|
|
86
|
+
/** The id of the visible element that labels the row — a heading, or a field's own label. */
|
|
87
|
+
ariaLabelledby?: string;
|
|
88
|
+
/**
|
|
89
|
+
* The name each cell gives itself, as any subset of `OtpInputLabels` — the
|
|
90
|
+
* rest stay as the host's `provideLoomLabels` vocabulary left them, and
|
|
91
|
+
* then as Loom's English.
|
|
92
|
+
*
|
|
93
|
+
* This is the per-instance correction, not the place to localise an
|
|
94
|
+
* application: the case it exists for is a row whose cells are neither
|
|
95
|
+
* digits nor characters in the reader's terms — the groups of a licence
|
|
96
|
+
* key, say — where the noun has to say so however well the application is
|
|
97
|
+
* translated.
|
|
98
|
+
*/
|
|
99
|
+
labels?: LabelOverrides<OtpInputLabels>;
|
|
100
|
+
}> & Readonly<{
|
|
101
|
+
"onUpdate:modelValue"?: (value: string) => any;
|
|
102
|
+
onComplete?: (value: string) => any;
|
|
103
|
+
}>, {
|
|
104
|
+
length: number;
|
|
105
|
+
disabled: boolean | undefined;
|
|
106
|
+
mask: boolean;
|
|
107
|
+
invalid: boolean | undefined;
|
|
108
|
+
type: OtpInputType;
|
|
109
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
110
|
+
//# sourceMappingURL=OtpInput.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OtpInput.vue.d.ts","sourceRoot":"","sources":["../../../src/primitives/OtpInput/OtpInput.vue"],"names":[],"mappings":"AA+VA,OAAO,EAAa,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAIlE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAEhD;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,MAAM,CAAC;AAE9C;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,cAAc;IAC7B,sEAAsE;IACtE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,YAAY,CAAA;KAAE,CAAC,CAAC;CAC/E;AAED;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,cAG9B,CAAC;wBACmB,OAAO,YAAY;AAAxC,wBAAyC;AACzC,QAAA,MAAM,YAAY;IAyDd,6EAA6E;iBAChE,MAAM;IACnB,6CAA6C;aACpC,MAAM;IACf,0DAA0D;WACnD,YAAY;IACnB,8FAA8F;WACvF,OAAO;IACd,0FAA0F;eAC/E,OAAO,GAAG,SAAS;IAC9B,8IAA8I;cACpI,OAAO,GAAG,SAAS;IAC7B,uFAAuF;gBAC3E,MAAM;IAClB,6FAA6F;qBAC5E,MAAM;IACvB;;;;;;;;;;OAUG;aACM,cAAc,CAAC,cAAc,CAAC;;;;;IA3BvC,6EAA6E;iBAChE,MAAM;IACnB,6CAA6C;aACpC,MAAM;IACf,0DAA0D;WACnD,YAAY;IACnB,8FAA8F;WACvF,OAAO;IACd,0FAA0F;eAC/E,OAAO,GAAG,SAAS;IAC9B,8IAA8I;cACpI,OAAO,GAAG,SAAS;IAC7B,uFAAuF;gBAC3E,MAAM;IAClB,6FAA6F;qBAC5E,MAAM;IACvB;;;;;;;;;;OAUG;aACM,cAAc,CAAC,cAAc,CAAC;;;;;YAxB9B,MAAM;cAMJ,OAAO,GAAG,SAAS;UAFvB,OAAO;aAIJ,OAAO,GAAG,SAAS;UANtB,YAAY;6EA8WnB,CAAC"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { cn } from "../../lib/cn.js";
|
|
2
|
+
import { optional } from "../../lib/props.js";
|
|
3
|
+
import { useLabels } from "../../lib/labels.js";
|
|
4
|
+
import { useSplitAttrs } from "../../lib/attrs.js";
|
|
5
|
+
import { useFieldControl } from "../../lib/field-context.js";
|
|
6
|
+
import { Fragment, computed, createBlock, createElementBlock, defineComponent, mergeProps, normalizeClass, openBlock, ref, renderList, unref, watch, withCtx } from "vue";
|
|
7
|
+
import { PinInputInput, PinInputRoot } from "reka-ui";
|
|
8
|
+
//#region src/primitives/OtpInput/OtpInput.vue?vue&type=script&setup=true&lang.ts
|
|
9
|
+
/**
|
|
10
|
+
* Loom's English, co-located with the component so it tree-shakes with it, and
|
|
11
|
+
* exported so a host can build a partial vocabulary against the real thing.
|
|
12
|
+
*/
|
|
13
|
+
var OTP_INPUT_LABELS = { cell: ({ index, length, type }) => `${type === "numeric" ? "Digit" : "Character"} ${String(index)} of ${String(length)}` };
|
|
14
|
+
var OtpInput_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
|
|
15
|
+
inheritAttrs: false,
|
|
16
|
+
__name: "OtpInput",
|
|
17
|
+
props: {
|
|
18
|
+
modelValue: {},
|
|
19
|
+
length: { default: 6 },
|
|
20
|
+
type: { default: "numeric" },
|
|
21
|
+
mask: {
|
|
22
|
+
type: Boolean,
|
|
23
|
+
default: false
|
|
24
|
+
},
|
|
25
|
+
disabled: {
|
|
26
|
+
type: Boolean,
|
|
27
|
+
default: void 0
|
|
28
|
+
},
|
|
29
|
+
invalid: {
|
|
30
|
+
type: Boolean,
|
|
31
|
+
default: void 0
|
|
32
|
+
},
|
|
33
|
+
ariaLabel: {},
|
|
34
|
+
ariaLabelledby: {},
|
|
35
|
+
labels: {}
|
|
36
|
+
},
|
|
37
|
+
emits: ["update:modelValue", "complete"],
|
|
38
|
+
setup(__props, { emit: __emit }) {
|
|
39
|
+
const props = __props;
|
|
40
|
+
const emit = __emit;
|
|
41
|
+
const text = useLabels("otpInput", OTP_INPUT_LABELS, () => props.labels);
|
|
42
|
+
const { attrs, rest: groupAttrs } = useSplitAttrs();
|
|
43
|
+
const field = useFieldControl(() => ({
|
|
44
|
+
id: attrs.id,
|
|
45
|
+
describedBy: attrs["aria-describedby"],
|
|
46
|
+
ariaLabelledby: props.ariaLabelledby,
|
|
47
|
+
disabled: props.disabled,
|
|
48
|
+
invalid: props.invalid
|
|
49
|
+
}));
|
|
50
|
+
const groupFieldAttrs = computed(() => {
|
|
51
|
+
const group = { ...field.attrs };
|
|
52
|
+
delete group.name;
|
|
53
|
+
delete group["aria-required"];
|
|
54
|
+
delete group["aria-invalid"];
|
|
55
|
+
return group;
|
|
56
|
+
});
|
|
57
|
+
const code = ref(props.modelValue ?? "");
|
|
58
|
+
watch(() => props.modelValue, (value) => {
|
|
59
|
+
if (value !== void 0) code.value = value;
|
|
60
|
+
});
|
|
61
|
+
const cells = computed(() => code.value.slice(0, props.length).split(""));
|
|
62
|
+
const pinType = computed(() => props.type === "numeric" ? "number" : "text");
|
|
63
|
+
const tabStopIndex = computed(() => Math.min(code.value.length, props.length - 1));
|
|
64
|
+
function onUpdate(next) {
|
|
65
|
+
const value = next.join("");
|
|
66
|
+
if (value === code.value) return;
|
|
67
|
+
code.value = value;
|
|
68
|
+
emit("update:modelValue", value);
|
|
69
|
+
if (value.length === props.length) emit("complete", value);
|
|
70
|
+
}
|
|
71
|
+
return (_ctx, _cache) => {
|
|
72
|
+
return openBlock(), createBlock(unref(PinInputRoot), mergeProps({
|
|
73
|
+
...unref(groupAttrs),
|
|
74
|
+
...groupFieldAttrs.value,
|
|
75
|
+
...unref(optional)({ name: unref(field).name })
|
|
76
|
+
}, {
|
|
77
|
+
"model-value": cells.value,
|
|
78
|
+
type: pinType.value,
|
|
79
|
+
mask: __props.mask,
|
|
80
|
+
disabled: unref(field).disabled,
|
|
81
|
+
otp: "",
|
|
82
|
+
role: "group",
|
|
83
|
+
"aria-label": __props.ariaLabelledby ? void 0 : __props.ariaLabel,
|
|
84
|
+
"aria-labelledby": __props.ariaLabelledby || (!__props.ariaLabel ? unref(field).labelledBy : void 0),
|
|
85
|
+
"data-invalid": unref(field).invalid || void 0,
|
|
86
|
+
class: unref(cn)("inline-flex items-center gap-2", unref(attrs).class),
|
|
87
|
+
"onUpdate:modelValue": onUpdate
|
|
88
|
+
}), {
|
|
89
|
+
default: withCtx(() => [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.length, (cell) => {
|
|
90
|
+
return openBlock(), createBlock(unref(PinInputInput), {
|
|
91
|
+
key: cell,
|
|
92
|
+
index: cell - 1,
|
|
93
|
+
tabindex: cell - 1 === tabStopIndex.value ? 0 : -1,
|
|
94
|
+
"aria-label": unref(text).cell({
|
|
95
|
+
index: cell,
|
|
96
|
+
length: __props.length,
|
|
97
|
+
type: __props.type
|
|
98
|
+
}),
|
|
99
|
+
"aria-required": unref(field).required || void 0,
|
|
100
|
+
"aria-invalid": unref(field).invalid || void 0,
|
|
101
|
+
"data-filled": cell <= code.value.length || void 0,
|
|
102
|
+
class: normalizeClass(unref(cn)("tabular h-11 w-11 rounded-md border border-input bg-background text-center text-base text-foreground", "transition-[color,background-color,border-color,box-shadow] duration-fast ease-out", "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring", !unref(field).invalid && "focus-visible:shadow-halo", !unref(field).disabled && "data-[filled]:border-border-strong", "disabled:cursor-not-allowed disabled:bg-muted disabled:text-muted-foreground", unref(field).disabled && "border-border", unref(field).invalid && "border-destructive focus-visible:outline-destructive"))
|
|
103
|
+
}, null, 8, [
|
|
104
|
+
"index",
|
|
105
|
+
"tabindex",
|
|
106
|
+
"aria-label",
|
|
107
|
+
"aria-required",
|
|
108
|
+
"aria-invalid",
|
|
109
|
+
"data-filled",
|
|
110
|
+
"class"
|
|
111
|
+
]);
|
|
112
|
+
}), 128))]),
|
|
113
|
+
_: 1
|
|
114
|
+
}, 16, [
|
|
115
|
+
"model-value",
|
|
116
|
+
"type",
|
|
117
|
+
"mask",
|
|
118
|
+
"disabled",
|
|
119
|
+
"aria-label",
|
|
120
|
+
"aria-labelledby",
|
|
121
|
+
"data-invalid",
|
|
122
|
+
"class"
|
|
123
|
+
]);
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
//#endregion
|
|
128
|
+
export { OTP_INPUT_LABELS, OtpInput_vue_vue_type_script_setup_true_lang_default as default };
|
|
129
|
+
|
|
130
|
+
//# sourceMappingURL=OtpInput.vue_vue_type_script_setup_true_lang.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OtpInput.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/primitives/OtpInput/OtpInput.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { LabelOf } from \"../../lib/labels\";\n\n/**\n * What a cell accepts, and what keyboard a phone raises for it. `numeric` is\n * digits only; `text` takes any character, for an alphanumeric backup code.\n */\nexport type OtpInputType = \"numeric\" | \"text\";\n\n/**\n * The one name this control publishes, and it replaces one Reka writes in\n * English of its own accord: `PinInputInput` labels every cell\n * `` `pin input ${index + 1} of ${length}` `` and exposes no prop for it.\n *\n * **One key, not \"Digit\" plus \"Character\" plus a joiner plus a position.** The\n * noun and the two numbers arrive together in one argument object, and the\n * variant — whether this row takes digits or any character — arrives with\n * them, because which word a language uses for a cell and where the position\n * sits relative to it are one decision rather than two. Four fragment keys\n * Loom then joined would be a sentence no translator could reorder.\n *\n * `index` is 1-based: it is a position a person is being read, not an offset\n * into an array, and handing over the 0-based one would make every override\n * write `index + 1` before it could say anything.\n */\nexport interface OtpInputLabels {\n /** One cell, named for what it takes and where it sits in the row. */\n readonly cell: LabelOf<{ index: number; length: number; type: OtpInputType }>;\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 */\nexport const OTP_INPUT_LABELS: OtpInputLabels = {\n cell: ({ index, length, type }) =>\n `${type === \"numeric\" ? \"Digit\" : \"Character\"} ${String(index)} of ${String(length)}`,\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, ref, watch } from \"vue\";\nimport { PinInputInput, PinInputRoot } from \"reka-ui\";\nimport { cn } from \"../../lib/cn\";\nimport { useSplitAttrs } from \"../../lib/attrs\";\nimport { useFieldControl } from \"../../lib/field-context\";\nimport { useLabels, type LabelOverrides } from \"../../lib/labels\";\nimport { optional } from \"../../lib/props\";\n\n/**\n * OtpInput — the row of single-character cells a one-time code or a short PIN\n * is typed into. Reach for it when the value really is a fixed-length code\n * that arrives out of band: the cells are what let `autocomplete=\"one-time-code\"`\n * offer the code the phone has just received, and `inputmode=\"numeric\"` is what\n * raises the digit keypad rather than the alphabet. Both are the reason this\n * exists at all rather than a TextField with a `maxlength` — and both are also\n * why anything a reader would want to read back, correct in the middle, or\n * paste in parts belongs in a TextField instead.\n *\n * Built on Reka UI's PinInput, which supplies the per-cell behaviour: typing\n * advances to the next cell, arrow keys move between them, Backspace on an\n * empty cell steps back and clears the one before it, and a pasted code is\n * distributed across the whole row rather than crammed into one cell.\n *\n * Two things are decided here that Reka leaves open.\n *\n * **The value is a scalar `string`.** Reka models it as an array of cells;\n * this exposes `\"1234\"`, exactly as Slider exposes a scalar where Reka models\n * an array — a code is what a host posts to an API and compares against, and\n * neither of those wants a six-element array. In numeric mode Reka's array is\n * even an array of *numbers*, which loses a leading zero the moment anyone\n * treats it as one value. The consequence is in `onUpdate`.\n *\n * **The row is one control, not `length` of them.** Reka names each cell and\n * leaves each one tabbable, which is how this control usually fails: six\n * inputs each announcing themselves in full, and six Tab presses to step over\n * a field a sighted user reads as one. The name of the thing being typed is\n * moved onto a labelled `role=\"group\"` so it is announced once on entering the\n * row, each cell is left with its position alone, and a roving tabindex makes\n * the row a single Tab stop.\n *\n * Inside a [Field](../Field/Field.vue) it wires itself through\n * `useFieldControl()`, and this control is the one where the resolved values\n * do not all land on the same node. The id of the row's hint or error line\n * describes the whole code and goes on the group; `required` and `invalid` are\n * states of the boxes being typed into and go on the cells, where the roles\n * that support them are — `role=\"group\"` supports neither. The row's id and\n * the name the code is submitted under both go to Reka's hidden input: `id` is\n * a declared prop of its root rather than a fallthrough attr, and that input is\n * the better target anyway, since `<label for>` associates only with a\n * labelable element and hands focus to the first cell from there.\n *\n * What a Field still cannot do here is *name* the row: its `<label>` reaches\n * the hidden input, which is `aria-hidden`, so no accessible name is computed\n * from it. Give the name with `ariaLabel` or `ariaLabelledby` as you would\n * outside a row.\n *\n * A row's `readonly` is deliberately ignored. There is nothing to read in an\n * uneditable code box that a line of text would not show better, and the cells\n * exist to be typed into. So the library's three resting appearances collapse\n * to two here: a cell goes straight from `background` to the disabled row's\n * drained fill, muted character and slackened rim, and the lifted `subtle` fill\n * that marks a value on show never appears on this control.\n */\nconst props = withDefaults(\n defineProps<{\n /** The code entered so far. Shorter than `length` while it is incomplete. */\n modelValue?: string;\n /** How many cells the code is typed into. */\n length?: number;\n /** What a cell accepts: digits only, or any character. */\n type?: OtpInputType;\n /** Renders every filled cell as a dot instead of its character, for a PIN typed in public. */\n mask?: boolean;\n /** Unavailable: dims the row and refuses every cell. Unset defers to a wrapping Field. */\n disabled?: boolean | undefined;\n /** Error state: paints the destructive border and ring, and sets `aria-invalid` on every cell. Unset defers to a wrapping Field's `error`. */\n invalid?: boolean | undefined;\n /** The accessible name of the whole row, when no visible element already labels it. */\n ariaLabel?: string;\n /** The id of the visible element that labels the row — a heading, or a field's own label. */\n ariaLabelledby?: string;\n /**\n * The name each cell gives itself, as any subset of `OtpInputLabels` — the\n * rest stay as the host's `provideLoomLabels` vocabulary left them, and\n * then as Loom's English.\n *\n * This is the per-instance correction, not the place to localise an\n * application: the case it exists for is a row whose cells are neither\n * digits nor characters in the reader's terms — the groups of a licence\n * key, say — where the noun has to say so however well the application is\n * translated.\n */\n labels?: LabelOverrides<OtpInputLabels>;\n }>(),\n {\n length: 6,\n type: \"numeric\",\n mask: false,\n // Not `false`, for either. `false` is a caller saying \"this row is fine /\n // enabled even though the field around it 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 — see TextField.vue, which carries\n // the full reasoning.\n disabled: undefined,\n invalid: undefined,\n },\n);\n\nconst emit = defineEmits<{\n /** The code so far, as one string. Fires on every cell that fills or clears. */\n \"update:modelValue\": [value: string];\n /** The finished code. Fires once, as the last empty cell takes its character. */\n complete: [value: string];\n}>();\n\n// `text`, not `labels`: the prop of that name is one of the three sources this\n// resolves, and a template reading the raw prop would be reading the overrides\n// rather than the answer.\nconst text = useLabels(\"otpInput\", OTP_INPUT_LABELS, () => props.labels);\n\n// Every fallthrough attribute lands on the group: an `aria-describedby`\n// pointing at an error line, a `data-testid`, an `id` — each describes the\n// control as a whole, and copying one onto `length` inputs would have a screen\n// reader repeat it on every cell. `class` is pulled out of that spread only so\n// it can go through `cn()`, which is what lets a caller's utility beat the\n// row's own instead of losing to whichever Tailwind emitted last.\ndefineOptions({ inheritAttrs: false });\nconst { attrs, rest: groupAttrs } = useSplitAttrs();\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. `name`,\n// `readonly` and `required` are absent from this object because there is no\n// prop to oppose the row with; the row's answer stands unopposed, which is\n// what is wanted.\nconst field = useFieldControl(() => ({\n id: attrs.id as string | undefined,\n describedBy: attrs[\"aria-describedby\"] as string | undefined,\n ariaLabelledby: props.ariaLabelledby,\n disabled: props.disabled,\n invalid: props.invalid,\n}));\n\n// Three of the resolved keys do not travel with the bag, because the bag lands\n// on the group and the group is the wrong node for all three.\n//\n// `name` would be a `name` on a `<div>`, which no form reads; Reka's own\n// hidden input carries the joined code, so the row's name is given to the root\n// as a prop instead.\n//\n// `aria-required` and `aria-invalid` are states of the boxes a reader types\n// into, and `role=\"group\"` supports neither — `aria-invalid` is a global so it\n// would at least be legal there, `aria-required` is not and would fail\n// `aria-allowed-attr`. Both are bound per cell below, off the same resolved\n// values, so the row's error reaches the element a screen reader is actually\n// sitting on.\n//\n// `id` stays in the bag and still does not land here: it is a declared prop of\n// Reka's root, so it is taken as a prop rather than falling through, and Reka\n// puts it on that same hidden input — which is the labelable node a\n// `<label for>` needs, and the one that hands focus to the first cell.\nconst groupFieldAttrs = computed(() => {\n // Removed from a copy rather than listed positively, so a key added to the\n // resolved bag later reaches this group without anyone remembering to come\n // back here.\n const group: Record<string, unknown> = { ...field.attrs };\n delete group.name;\n delete group[\"aria-required\"];\n delete group[\"aria-invalid\"];\n return group;\n});\n\n// The single source of truth for the code we know about: seeded from the prop,\n// then advanced on every update Reka reports. Feeding this back into Reka\n// rather than `props.modelValue` is what keeps the row usable for a host that\n// binds no `modelValue` at all — the same buffer Slider keeps, for the same\n// reason. An absent prop leaves it empty rather than sticking the row on one\n// value, so nothing here needs `optional()`.\nconst code = ref(props.modelValue ?? \"\");\nwatch(\n () => props.modelValue,\n (value) => {\n if (value !== undefined) code.value = value;\n },\n);\n\n// Longer than the row is the host's mistake to make, not ours to render: the\n// extra characters have no cell to live in.\nconst cells = computed(() => code.value.slice(0, props.length).split(\"\"));\n\n// Reka calls the digits-only mode \"number\". The prop says \"numeric\" because\n// nothing about the value is a number — a code with a leading zero is a\n// string, and this control never parses one.\nconst pinType = computed(() => (props.type === \"numeric\" ? \"number\" : \"text\"));\n\n// The row is one Tab stop. The stop is the first empty cell, which is also\n// where Reka's own `otp` handling redirects focus, or the last cell once the\n// code is full — so Tab lands where the next character goes.\nconst tabStopIndex = computed(() => Math.min(code.value.length, props.length - 1));\n\n// Typed wider than the declared emit on purpose: in numeric mode the array\n// really does come back holding numbers, and a cleared middle cell comes back\n// as a hole. Both are why a scalar is the exposed shape.\nfunction onUpdate(next: (string | number)[]) {\n // `join` is where the scalar is decided, and it closes gaps: Reka can hold a\n // cleared middle cell as a hole, a string cannot, so the cells after it\n // shift left. That is the only reading that keeps the model and the row\n // agreeing on one value — and it is what a single text input does when a\n // character in the middle is deleted.\n const value = next.join(\"\");\n // Reka reports the whole row on every write, including a write that changed\n // nothing a string can see — pasting the same code over itself is the\n // reachable one. Stopping here keeps one changed code to one emitted value,\n // and one filled code to one `complete`.\n if (value === code.value) return;\n code.value = value;\n emit(\"update:modelValue\", value);\n // Derived here rather than forwarded from Reka's own `complete`, which fires\n // from a deep watcher on its model — and that model is set twice for one\n // keystroke once the row is controlled, once by Reka and once by the value\n // coming back around. Forwarding it would announce one filled code twice.\n if (value.length === props.length) emit(\"complete\", value);\n}\n</script>\n\n<template>\n <PinInputRoot\n v-bind=\"{ ...groupAttrs, ...groupFieldAttrs, ...optional({ name: field.name }) }\"\n :model-value=\"cells\"\n :type=\"pinType\"\n :mask=\"mask\"\n :disabled=\"field.disabled\"\n otp\n role=\"group\"\n :aria-label=\"ariaLabelledby ? undefined : ariaLabel\"\n :aria-labelledby=\"ariaLabelledby || (!ariaLabel ? field.labelledBy : undefined)\"\n :data-invalid=\"field.invalid || undefined\"\n :class=\"cn('inline-flex items-center gap-2', attrs.class as string)\"\n @update:model-value=\"onUpdate\"\n >\n <!-- The `:aria-label` replaces the one Reka writes inside its own render\n function — \"pin input 3 of 6\", the field's whole purpose restated once\n per cell. It reaches the DOM node as a fallthrough attribute, which Vue\n merges last, so it is a replacement rather than a second name. Removing\n it does not fall back to nothing; it falls back to Reka's English. The\n group carries the purpose, and a cell carries only where it sits. -->\n <PinInputInput\n v-for=\"cell in length\"\n :key=\"cell\"\n :index=\"cell - 1\"\n :tabindex=\"cell - 1 === tabStopIndex ? 0 : -1\"\n :aria-label=\"text.cell({ index: cell, length, type })\"\n :aria-required=\"field.required || undefined\"\n :aria-invalid=\"field.invalid || undefined\"\n :data-filled=\"cell <= code.length || undefined\"\n :class=\"\n cn(\n // Square, on the control scale's tallest step: a code cell is a\n // touch target before it is a form row, and 44px is the size a thumb\n // is aimed at. `tabular` keeps the six glyphs on one width so the\n // row does not breathe as it fills.\n 'tabular h-11 w-11 rounded-md border border-input bg-background text-center text-base text-foreground',\n 'transition-[color,background-color,border-color,box-shadow] duration-fast ease-out',\n // Rim-lit at rest; the ring blooms on the cell being typed into.\n 'focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring',\n !field.invalid && 'focus-visible:shadow-halo',\n // A filled cell is legible as filled from its character — or its\n // mask dot — alone. The heavier border is a second, redundant cue,\n // and a weight rather than a hue, so it survives both a colour\n // deficiency and forced-colors.\n //\n // Withheld from an unavailable row, and only because the border is\n // also the third channel of the disabled state below: two rules\n // moving the same rim in opposite directions would leave a\n // half-filled disabled row with a heavier edge than an empty one,\n // which reads as the more available of the two. The cue is redundant\n // by construction, so the state wins it.\n !field.disabled && 'data-[filled]:border-border-strong',\n // Unavailable is a *colour* and a *weight*, never an opacity. A cell\n // holds one character — or one mask dot — and that is the entire\n // content of the control, so `opacity-50` here did not dim a code so\n // much as erase it: `--color-foreground` measures 14.09:1 on the\n // resting fill and 2.99:1 once composited at half alpha. The drained\n // fill carries the state instead, the character stays at a measured\n // 4.68:1, and the rim slackens from `input` to `border` so the state\n // is not told in hue alone.\n //\n // The fill and the text colour are `disabled:` variants rather than\n // plain classes, so each outranks the resting `bg-background\n // text-foreground` above on specificity rather than on where Tailwind\n // happened to emit it. The border cannot join them: a `disabled:`\n // variant would outrank the plain `border-destructive` below, and a\n // row that is both in error and unavailable has to keep saying so.\n 'disabled:cursor-not-allowed disabled:bg-muted disabled:text-muted-foreground',\n field.disabled && 'border-border',\n field.invalid && 'border-destructive focus-visible:outline-destructive',\n )\n \"\n />\n </PinInputRoot>\n</template>\n"],"mappings":";;;;;;;;;;;;AAkCA,IAAa,mBAAmC,EAC9C,OAAO,EAAE,OAAO,QAAQ,WACtB,GAAG,SAAS,YAAY,UAAU,YAAY,GAAG,OAAO,KAAK,EAAE,MAAM,OAAO,MAAM,IACtF;;;;;;;;;;;;;;;;;;;;;;;;;;EAmEA,MAAM,QAAQ;EA6Cd,MAAM,OAAO;EAUb,MAAM,OAAO,UAAU,YAAY,wBAAwB,MAAM,MAAM;EASvE,MAAM,EAAE,OAAO,MAAM,eAAe,cAAc;EASlD,MAAM,QAAQ,uBAAuB;GACnC,IAAI,MAAM;GACV,aAAa,MAAM;GACnB,gBAAgB,MAAM;GACtB,UAAU,MAAM;GAChB,SAAS,MAAM;EACjB,EAAE;EAoBF,MAAM,kBAAkB,eAAe;GAIrC,MAAM,QAAiC,EAAE,GAAG,MAAM,MAAM;GACxD,OAAO,MAAM;GACb,OAAO,MAAM;GACb,OAAO,MAAM;GACb,OAAO;EACT,CAAC;EAQD,MAAM,OAAO,IAAI,MAAM,cAAc,EAAE;EACvC,YACQ,MAAM,aACX,UAAU;GACT,IAAI,UAAU,KAAA,GAAW,KAAK,QAAQ;EACxC,CACF;EAIA,MAAM,QAAQ,eAAe,KAAK,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC;EAKxE,MAAM,UAAU,eAAgB,MAAM,SAAS,YAAY,WAAW,MAAO;EAK7E,MAAM,eAAe,eAAe,KAAK,IAAI,KAAK,MAAM,QAAQ,MAAM,SAAS,CAAC,CAAC;EAKjF,SAAS,SAAS,MAA2B;GAM3C,MAAM,QAAQ,KAAK,KAAK,EAAE;GAK1B,IAAI,UAAU,KAAK,OAAO;GAC1B,KAAK,QAAQ;GACb,KAAK,qBAAqB,KAAK;GAK/B,IAAI,MAAM,WAAW,MAAM,QAAQ,KAAK,YAAY,KAAK;EAC3D;;GAIE,OAAA,UAAA,GAAA,YAyEe,MAAA,YAAA,GAzEf,WAyEe;IAAA,GAxEA,MAAA,UAAA;IAAU,GAAK,gBAAA;IAAe,GAAK,MAAA,QAAA,CAAQ,CAAA,EAAA,MAAS,MAAA,KAAA,CAAK,CAAC,KAAI,CAAA;GAAA,GAAA;IAC1E,eAAa,MAAA;IACb,MAAM,QAAA;IACN,MAAM,QAAA;IACN,UAAU,MAAA,KAAA,CAAK,CAAC;IACjB,KAAA;IACA,MAAK;IACJ,cAAY,QAAA,iBAAiB,KAAA,IAAY,QAAA;IACzC,mBAAiB,QAAA,mBAAc,CAAM,QAAA,YAAY,MAAA,KAAA,CAAK,CAAC,aAAa,KAAA;IACpE,gBAAc,MAAA,KAAA,CAAK,CAAC,WAAW,KAAA;IAC/B,OAAO,MAAA,EAAA,CAAE,CAAA,kCAAmC,MAAA,KAAA,CAAK,CAAC,KAAK;IACvD,uBAAoB;;IASnB,SAAA,cAAsB,EADxB,UAAA,IAAA,GAAA,mBAoDE,UAAA,MAAA,WAnDe,QAAA,SAAR,SAAI;KADb,OAAA,UAAA,GAAA,YAoDE,MAAA,aAAA,GAAA;MAlDC,KAAK;MACL,OAAO,OAAI;MACX,UAAU,OAAI,MAAS,aAAA,QAAY,IAAA;MACnC,cAAY,MAAA,IAAA,CAAI,CAAC,KAAI;OAAA,OAAU;OAAI,QAAE,QAAA;OAAM,MAAE,QAAA;MAAI,CAAA;MACjD,iBAAe,MAAA,KAAA,CAAK,CAAC,YAAY,KAAA;MACjC,gBAAc,MAAA,KAAA,CAAK,CAAC,WAAW,KAAA;MAC/B,eAAa,QAAQ,KAAA,MAAK,UAAU,KAAA;MACpC,OAAK,eAAW,MAAA,EAAA,CAAE,CAAA,wGAAA,sFAAA,qFAAiqB,CAAA,MAAA,KAAA,CAAK,CAAC,WAAO,6BAAwvB,CAAA,MAAA,KAAA,CAAK,CAAC,YAAQ,sCAAA,gFAA2rC,MAAA,KAAA,CAAK,CAAC,YAAQ,iBAA+B,MAAA,KAAA,CAAK,CAAC,WAAO,sDAAA,CAAA"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import Pagination_vue_vue_type_script_setup_true_lang_default, { PAGINATION_LABELS, paginationVariants } from "./Pagination.vue_vue_type_script_setup_true_lang.js";
|
|
2
|
+
//#region src/primitives/Pagination/Pagination.vue
|
|
3
|
+
var Pagination_default = Pagination_vue_vue_type_script_setup_true_lang_default;
|
|
4
|
+
//#endregion
|
|
5
|
+
export { PAGINATION_LABELS, Pagination_default as default, paginationVariants };
|
|
6
|
+
|
|
7
|
+
//# sourceMappingURL=Pagination.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Pagination.js","names":[],"sources":["../../../src/primitives/Pagination/Pagination.vue"],"sourcesContent":["<script lang=\"ts\">\nimport { cva } from \"class-variance-authority\";\nimport type { LabelOf } from \"../../lib/labels\";\n\n/**\n * Everything this control publishes to assistive technology — including the six\n * names Reka would otherwise supply in English of its own accord.\n *\n * `first`, `previous`, `next`, `last` and `page` are not decoration. Reka's\n * `PaginationFirst` and its siblings write `aria-label=\"First Page\"` into their\n * own vnode props and expose no prop for it; `PaginationListItem` writes\n * `` `Page ${value}` ``. A binding on the Loom side arrives as a fallthrough\n * attribute, which Vue merges onto the root vnode *after* the render function\n * produced it, and `mergeProps` is last-write-wins for everything that is not\n * `class`, `style` or `on*`. So these replace Reka's rather than competing with\n * it — the same mechanism `DateRangePicker`'s cell triggers have relied on\n * since they landed, and `Pagination.test.ts` pins it by asserting the\n * *capitalisation* Loom uses and Reka does not.\n *\n * `page` and `position` take the numbers rather than a formatted string, so an\n * `ar-EG` host reaches `Intl.NumberFormat` for Eastern Arabic digits and a\n * language that orders \"of\" differently can order it differently. See\n * `LabelOf` in `src/lib/labels.ts`.\n */\nexport interface PaginationLabels {\n /**\n * The `<nav>` landmark's own name. A page commonly carries two of these —\n * above and below a table — and two `<nav>`s named the same thing are as\n * confusing to a screen reader as two named nothing, so give each one a name\n * that says which it is.\n */\n readonly nav: string;\n /** The button that jumps to page one. */\n readonly first: string;\n /** The button that steps back one page. */\n readonly previous: string;\n /** The button that steps on one page. */\n readonly next: string;\n /** The button that jumps to the last page. */\n readonly last: string;\n /** One numbered button in the `full` variant, named for the page it reaches. */\n readonly page: LabelOf<{ page: number }>;\n /** The position readout the `compact` and `simple` variants publish. */\n readonly position: LabelOf<{ page: number; pageCount: number }>;\n /** The ellipsis standing in for the pages the window had no room for. */\n readonly ellipsis: string;\n}\n\n/**\n * Loom's English, co-located with the component so it tree-shakes with it: a\n * consumer who never imports Pagination ships none of these bytes.\n *\n * Exported so a host can build a partial vocabulary against the real thing\n * rather than a transcription of it.\n */\nexport const PAGINATION_LABELS: PaginationLabels = {\n nav: \"Pagination\",\n first: \"First page\",\n previous: \"Previous page\",\n next: \"Next page\",\n last: \"Last page\",\n page: ({ page }) => `Page ${String(page)}`,\n position: ({ page, pageCount }) => `Page ${String(page)} of ${String(pageCount)}`,\n ellipsis: \"More pages\",\n};\n\n/**\n * How much of the paging apparatus is rendered. All three drive the same\n * model and carry the same semantics — they differ only in how much room the\n * navigation is worth on the surface it sits on.\n *\n * • `full` — the numbered row with ellipses, plus first/prev/next/last.\n * For a table where jumping to a known page is a real task.\n * • `compact` — prev, \"Page 3 of 12\", next. The position stays legible\n * without spending a whole row on it.\n * • `simple` — prev and next alone, for a feed nobody navigates by index.\n */\nexport type PaginationVariant = \"full\" | \"compact\" | \"simple\";\n\nexport const paginationVariants = cva(\"inline-flex items-center\", {\n // `satisfies` keeps the two halves honest: the union above is the name a\n // consumer imports and the documentation prints, the map below is the\n // classes. Adding a member to one and not the other stops compiling.\n variants: {\n variant: {\n // The numbered row is a run of same-size squares and reads as one strip\n // at gap-1; the compact form is a sentence between two controls and\n // needs the wider gap to stop reading as a third button.\n full: \"gap-1\",\n compact: \"gap-2\",\n simple: \"gap-1\",\n } satisfies Record<PaginationVariant, string>,\n },\n defaultVariants: { variant: \"full\" },\n});\n</script>\n\n<script setup lang=\"ts\">\nimport { nextTick } from \"vue\";\nimport {\n PaginationRoot,\n PaginationList,\n PaginationListItem,\n PaginationFirst,\n PaginationPrev,\n PaginationNext,\n PaginationLast,\n PaginationEllipsis,\n} from \"reka-ui\";\nimport { ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight } from \"@lucide/vue\";\nimport { buttonVariants } from \"../Button/Button.vue\";\nimport { cn } from \"../../lib/cn\";\nimport { optional } from \"../../lib/props\";\nimport { useSplitAttrs } from \"../../lib/attrs\";\nimport { useLabels, type LabelOverrides } from \"../../lib/labels\";\n\n/**\n * Pagination — moving through a paged result set, one page at a time or by\n * jumping to a numbered one.\n *\n * It renders **buttons, never links**. Loom cannot know whether a consumer's\n * pages are addressable URLs, and an `<a>` with no `href` is not a link at\n * all — it is a div that lies to a screen reader and drops out of the tab\n * order. A product whose pages are real, crawlable URLs wants its own\n * `<a href>` row instead of this component; nothing here can be made to\n * produce one.\n *\n * Reach for a different control when the list is not paged: an infinite feed\n * wants a \"load more\" button, and a long list a reader scans rather than\n * indexes wants a virtualised scroller.\n *\n * Built on Reka UI's Pagination, which owns the arithmetic — the page count,\n * the sliding window of numbers around the current page, and where the\n * ellipses fall. That window is fiddly enough at the boundaries that\n * recomputing it here would only be a second, subtly different answer.\n */\nconst props = withDefaults(\n defineProps<{\n /**\n * The current page, 1-based. Leave it unset to let the component keep its\n * own page and simply report changes.\n */\n page?: number;\n /** How many items exist in total, across every page. */\n total: number;\n /** How many items one page holds. With `total`, this is what fixes the page count. */\n itemsPerPage?: number;\n /** How much of the control renders: the numbered row, a position readout, or arrows alone. */\n variant?: PaginationVariant;\n /** How many numbers sit either side of the current page, in the `full` variant. */\n siblingCount?: number;\n /** Pins page 1 and the last page into the numbered row, with ellipses standing in for the gap. */\n showEdges?: boolean;\n /** Unavailable: every control dims and refuses to move the page. */\n disabled?: boolean;\n /**\n * Names for everything this control says out loud, as any subset of\n * `PaginationLabels` — 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: the case it exists for is the two paginations above and\n * below one table, which must not share `labels.nav`.\n */\n labels?: LabelOverrides<PaginationLabels>;\n }>(),\n {\n itemsPerPage: 10,\n variant: \"full\",\n siblingCount: 1,\n // Reka defaults this off, which drops the ellipses entirely and lets the\n // numbered row float free of both ends. The anchored form is what people\n // mean by a full pagination, so Loom turns it on.\n showEdges: true,\n disabled: false,\n },\n);\n\nconst emit = defineEmits<{\n /** The 1-based page the reader asked for. A controlled host decides whether to honour it. */\n \"update:page\": [page: number];\n}>();\n\n// `text`, not `labels`: the prop of that name is one of the three sources this\n// resolves, and a template reading the raw prop would be reading the overrides\n// rather than the answer.\nconst text = useLabels(\"pagination\", PAGINATION_LABELS, () => props.labels);\n\n// The root renders the `<nav>`, so every fallthrough attribute belongs on it —\n// there is no second node they could sensibly describe. `class` is pulled out\n// of that spread and merged through `cn()` instead: spreading it alongside the\n// nav's own `:class` only concatenates the two lists, so a caller's `gap-2`\n// would win or lose depending on which utility Tailwind happened to emit last.\ndefineOptions({ inheritAttrs: false });\nconst { attrs, rest: navAttrs } = useSplitAttrs();\n\n// The edge controls keep the dim, and they are the one place in this component\n// where it is still the right answer: their whole content is a chevron marked\n// `aria-hidden`, so there is no text for the alpha to take down with it and the\n// name a screen reader announces is an `aria-label` no paint can reach. WCAG\n// exempts an inactive control from 1.4.11 besides. Prev and First sit disabled\n// on page 1 for as long as a reader is on it, which is the other half of the\n// argument: a faded chevron is the conventional reading of \"no further this\n// way\", where a drained plate would draw the eye to the control that cannot be\n// used.\nconst edgeClass = cn(\n buttonVariants({ variant: \"ghost\", size: \"icon-sm\" }),\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n);\n\n// The page buttons borrow Button's own variants rather than restating its\n// press language, so the row cannot drift from every other pressable thing in\n// the library. `min-w-8` with tabular figures is what keeps the row from\n// reflowing as the numbers under it grow a digit.\nfunction pageClass(selected: boolean): string {\n return cn(\n buttonVariants({ variant: selected ? \"primary\" : \"ghost\", size: \"sm\" }),\n \"min-w-8 px-2 tabular\",\n // No `opacity` here, unlike the edges above, because this button's content\n // *is* text — the page number, the one thing a reader needs from a pager\n // that is briefly out of service. `disabled:opacity-50` composited the\n // ghost variant's `--color-muted-foreground` down to 2.05:1 and the current\n // page's white-on-primary label down to 2.48:1; halving the alpha more than\n // halves the contrast. Unavailability is painted in measured colours\n // instead.\n //\n // The two branches drain to different wells on purpose, which is Chip's\n // rule applied to a row of numbers: an unselected page falls to the neutral\n // well at 4.67:1, and the current page keeps the primary wash it already wears\n // at 6.84:1. Which page a reader is on is information, and a disabled pager\n // that forgets it has answered the question by refusing to answer it.\n selected\n ? \"disabled:cursor-not-allowed disabled:bg-primary-muted disabled:text-primary disabled:shadow-none\"\n : \"disabled:cursor-not-allowed disabled:bg-muted disabled:text-muted-foreground\",\n );\n}\n\n/** Which edge control stands in for which, when the one that was pressed goes away. */\nconst MIRROR: Record<string, string | undefined> = {\n first: \"last\",\n prev: \"next\",\n next: \"prev\",\n last: \"first\",\n};\n\n// Reka disables Prev/First at page 1 and Next/Last at the last page, and that\n// is the honest state: a control that looks unavailable and still fires is\n// worse than one that is not there at all. The cost is real, though — a\n// browser blurs a button the instant it becomes disabled, so a reader holding\n// Enter on Next arrives at the last page with focus dumped on `<body>` and\n// their place in the document gone.\n//\n// So the control that fired the change hands focus on: to the current page\n// button where the variant has one — which announces \"Page 12, current page\",\n// the very thing the reader was trying to find out — and to its mirror control\n// otherwise, which is the nearest thing still able to move the page.\n//\n// Only for a keyboard activation. `detail === 0` is what separates a click\n// synthesised by Enter or Space from a pointer click, and a pointer user has\n// no focus position to lose; moving focus for them would raise a ring nobody\n// asked for.\nlet pressed: HTMLButtonElement | null = null;\n\nfunction rememberKeyboardPress(event: MouseEvent): void {\n const target = event.target as HTMLElement | null;\n pressed = event.detail === 0 ? (target?.closest<HTMLButtonElement>(\"button\") ?? null) : null;\n}\n\nfunction handOffFocus(): void {\n const origin = pressed;\n pressed = null;\n if (!origin?.disabled) return;\n\n // Only rescue focus that was actually lost. A browser leaves `<body>`\n // focused after disabling the button; jsdom leaves the button itself. Any\n // other active element means the reader has already moved on, and stealing\n // focus back from them would be the worse bug.\n const active = document.activeElement;\n if (active !== origin && active !== document.body) return;\n\n const nav = origin.closest(\"nav\");\n if (!nav) return;\n\n const mirror = MIRROR[origin.getAttribute(\"data-edge\") ?? \"\"];\n const target =\n nav.querySelector<HTMLButtonElement>('[aria-current=\"page\"]:not([disabled])') ??\n (mirror\n ? nav.querySelector<HTMLButtonElement>(`[data-edge=\"${mirror}\"]:not([disabled])`)\n : null);\n target?.focus();\n}\n\nfunction onPageChange(value: number): void {\n emit(\"update:page\", value);\n // After the re-render rather than before it: the button that was pressed\n // only becomes disabled once the new page has been applied.\n void nextTick(handOffFocus);\n}\n</script>\n\n<template>\n <PaginationRoot\n v-slot=\"{ page: current, pageCount }\"\n v-bind=\"{ ...navAttrs, ...optional({ page }) }\"\n :total=\"total\"\n :items-per-page=\"itemsPerPage\"\n :sibling-count=\"siblingCount\"\n :show-edges=\"showEdges\"\n :disabled=\"disabled\"\n :aria-label=\"text.nav\"\n :class=\"cn(paginationVariants({ variant }), attrs.class as string)\"\n @click=\"rememberKeyboardPress\"\n @update:page=\"onPageChange\"\n >\n <!-- Every `:aria-label` from here down replaces one Reka writes in English\n inside its own render function. It reaches the DOM node as a\n fallthrough attribute, which Vue merges last, so it is a replacement\n rather than a second name. Removing one does not fall back to nothing;\n it falls back to Reka's English, which is the failure this whole seam\n exists to close and which no test of Loom's own strings would catch. -->\n <PaginationFirst\n v-if=\"variant === 'full'\"\n data-edge=\"first\"\n :aria-label=\"text.first\"\n :class=\"edgeClass\"\n >\n <ChevronsLeft class=\"h-4 w-4\" aria-hidden=\"true\" />\n </PaginationFirst>\n\n <PaginationPrev data-edge=\"prev\" :aria-label=\"text.previous\" :class=\"edgeClass\">\n <ChevronLeft class=\"h-4 w-4\" aria-hidden=\"true\" />\n </PaginationPrev>\n\n <PaginationList v-if=\"variant === 'full'\" v-slot=\"{ items }\" class=\"flex items-center gap-1\">\n <!-- Keyed by page number, never by index. The row is furniture: a page\n that stays inside the window across a change keeps its own DOM node,\n so nothing remounts, nothing re-animates, and the numbers do not\n shuffle under a reader who has just pressed Next. -->\n <template\n v-for=\"(item, index) in items\"\n :key=\"item.type === 'page' ? `page-${item.value}` : `ellipsis-${index}`\"\n >\n <PaginationListItem\n v-if=\"item.type === 'page'\"\n :value=\"item.value\"\n :aria-label=\"text.page({ page: item.value })\"\n :class=\"pageClass(item.value === current)\"\n />\n <!-- The ellipsis is not a control, so it renders as a span rather than\n Reka's default div-with-a-glyph inside a row of buttons: nothing to\n focus, nothing that looks pressable, and the glyph itself hidden\n from assistive technology because \"horizontal ellipsis\" is not what\n it means. The words are what it means. -->\n <PaginationEllipsis\n v-else\n as=\"span\"\n class=\"inline-flex h-8 min-w-8 select-none items-center justify-center text-sm text-muted-foreground\"\n >\n <span aria-hidden=\"true\">…</span>\n <span class=\"sr-only\">{{ text.ellipsis }}</span>\n </PaginationEllipsis>\n </template>\n </PaginationList>\n\n <!-- The position, for the two variants that have no numbered row to read it\n off. `role=\"status\"` because pressing Next in those variants otherwise\n changes nothing a screen reader would notice — focus stays put and no\n `aria-current` moves. The `full` variant deliberately has no live\n region: its number row already carries the state, and announcing it\n again on top of the focus hand-off below would say everything twice. -->\n <!-- One string rather than three nodes with the numbers between them: a\n language that puts the count before the word, or drops the preposition\n entirely, cannot reorder markup this component emits. `tabular` moves\n from the two number spans to the whole readout, which is the only real\n cost — the \"of\" between them is now tabular too, and the row of digits\n it was steadying is not rendered in either of these variants. -->\n <span\n v-if=\"variant !== 'full'\"\n role=\"status\"\n :class=\"variant === 'compact' ? 'px-1 text-sm tabular text-muted-foreground' : 'sr-only'\"\n >\n {{ text.position({ page: current, pageCount }) }}\n </span>\n\n <PaginationNext data-edge=\"next\" :aria-label=\"text.next\" :class=\"edgeClass\">\n <ChevronRight class=\"h-4 w-4\" aria-hidden=\"true\" />\n </PaginationNext>\n\n <PaginationLast\n v-if=\"variant === 'full'\"\n data-edge=\"last\"\n :aria-label=\"text.last\"\n :class=\"edgeClass\"\n >\n <ChevronsRight class=\"h-4 w-4\" aria-hidden=\"true\" />\n </PaginationLast>\n </PaginationRoot>\n</template>\n"],"mappings":""}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { type LabelOverrides } from "../../lib/labels";
|
|
2
|
+
import type { LabelOf } from "../../lib/labels";
|
|
3
|
+
/**
|
|
4
|
+
* Everything this control publishes to assistive technology — including the six
|
|
5
|
+
* names Reka would otherwise supply in English of its own accord.
|
|
6
|
+
*
|
|
7
|
+
* `first`, `previous`, `next`, `last` and `page` are not decoration. Reka's
|
|
8
|
+
* `PaginationFirst` and its siblings write `aria-label="First Page"` into their
|
|
9
|
+
* own vnode props and expose no prop for it; `PaginationListItem` writes
|
|
10
|
+
* `` `Page ${value}` ``. A binding on the Loom side arrives as a fallthrough
|
|
11
|
+
* attribute, which Vue merges onto the root vnode *after* the render function
|
|
12
|
+
* produced it, and `mergeProps` is last-write-wins for everything that is not
|
|
13
|
+
* `class`, `style` or `on*`. So these replace Reka's rather than competing with
|
|
14
|
+
* it — the same mechanism `DateRangePicker`'s cell triggers have relied on
|
|
15
|
+
* since they landed, and `Pagination.test.ts` pins it by asserting the
|
|
16
|
+
* *capitalisation* Loom uses and Reka does not.
|
|
17
|
+
*
|
|
18
|
+
* `page` and `position` take the numbers rather than a formatted string, so an
|
|
19
|
+
* `ar-EG` host reaches `Intl.NumberFormat` for Eastern Arabic digits and a
|
|
20
|
+
* language that orders "of" differently can order it differently. See
|
|
21
|
+
* `LabelOf` in `src/lib/labels.ts`.
|
|
22
|
+
*/
|
|
23
|
+
export interface PaginationLabels {
|
|
24
|
+
/**
|
|
25
|
+
* The `<nav>` landmark's own name. A page commonly carries two of these —
|
|
26
|
+
* above and below a table — and two `<nav>`s named the same thing are as
|
|
27
|
+
* confusing to a screen reader as two named nothing, so give each one a name
|
|
28
|
+
* that says which it is.
|
|
29
|
+
*/
|
|
30
|
+
readonly nav: string;
|
|
31
|
+
/** The button that jumps to page one. */
|
|
32
|
+
readonly first: string;
|
|
33
|
+
/** The button that steps back one page. */
|
|
34
|
+
readonly previous: string;
|
|
35
|
+
/** The button that steps on one page. */
|
|
36
|
+
readonly next: string;
|
|
37
|
+
/** The button that jumps to the last page. */
|
|
38
|
+
readonly last: string;
|
|
39
|
+
/** One numbered button in the `full` variant, named for the page it reaches. */
|
|
40
|
+
readonly page: LabelOf<{
|
|
41
|
+
page: number;
|
|
42
|
+
}>;
|
|
43
|
+
/** The position readout the `compact` and `simple` variants publish. */
|
|
44
|
+
readonly position: LabelOf<{
|
|
45
|
+
page: number;
|
|
46
|
+
pageCount: number;
|
|
47
|
+
}>;
|
|
48
|
+
/** The ellipsis standing in for the pages the window had no room for. */
|
|
49
|
+
readonly ellipsis: string;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Loom's English, co-located with the component so it tree-shakes with it: a
|
|
53
|
+
* consumer who never imports Pagination ships none of these bytes.
|
|
54
|
+
*
|
|
55
|
+
* Exported so a host can build a partial vocabulary against the real thing
|
|
56
|
+
* rather than a transcription of it.
|
|
57
|
+
*/
|
|
58
|
+
export declare const PAGINATION_LABELS: PaginationLabels;
|
|
59
|
+
/**
|
|
60
|
+
* How much of the paging apparatus is rendered. All three drive the same
|
|
61
|
+
* model and carry the same semantics — they differ only in how much room the
|
|
62
|
+
* navigation is worth on the surface it sits on.
|
|
63
|
+
*
|
|
64
|
+
* • `full` — the numbered row with ellipses, plus first/prev/next/last.
|
|
65
|
+
* For a table where jumping to a known page is a real task.
|
|
66
|
+
* • `compact` — prev, "Page 3 of 12", next. The position stays legible
|
|
67
|
+
* without spending a whole row on it.
|
|
68
|
+
* • `simple` — prev and next alone, for a feed nobody navigates by index.
|
|
69
|
+
*/
|
|
70
|
+
export type PaginationVariant = "full" | "compact" | "simple";
|
|
71
|
+
export declare const paginationVariants: (props?: ({
|
|
72
|
+
variant?: "full" | "compact" | "simple" | null | undefined;
|
|
73
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
74
|
+
declare const _default: typeof __VLS_export;
|
|
75
|
+
export default _default;
|
|
76
|
+
declare const __VLS_export: import("vue").DefineComponent<{
|
|
77
|
+
/**
|
|
78
|
+
* The current page, 1-based. Leave it unset to let the component keep its
|
|
79
|
+
* own page and simply report changes.
|
|
80
|
+
*/
|
|
81
|
+
page?: number;
|
|
82
|
+
/** How many items exist in total, across every page. */
|
|
83
|
+
total: number;
|
|
84
|
+
/** How many items one page holds. With `total`, this is what fixes the page count. */
|
|
85
|
+
itemsPerPage?: number;
|
|
86
|
+
/** How much of the control renders: the numbered row, a position readout, or arrows alone. */
|
|
87
|
+
variant?: PaginationVariant;
|
|
88
|
+
/** How many numbers sit either side of the current page, in the `full` variant. */
|
|
89
|
+
siblingCount?: number;
|
|
90
|
+
/** Pins page 1 and the last page into the numbered row, with ellipses standing in for the gap. */
|
|
91
|
+
showEdges?: boolean;
|
|
92
|
+
/** Unavailable: every control dims and refuses to move the page. */
|
|
93
|
+
disabled?: boolean;
|
|
94
|
+
/**
|
|
95
|
+
* Names for everything this control says out loud, as any subset of
|
|
96
|
+
* `PaginationLabels` — the rest stay as the host's `provideLoomLabels`
|
|
97
|
+
* vocabulary left them, and then as Loom's English.
|
|
98
|
+
*
|
|
99
|
+
* This is the per-instance correction, not the place to localise an
|
|
100
|
+
* application: the case it exists for is the two paginations above and
|
|
101
|
+
* below one table, which must not share `labels.nav`.
|
|
102
|
+
*/
|
|
103
|
+
labels?: LabelOverrides<PaginationLabels>;
|
|
104
|
+
}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
105
|
+
"update:page": (page: number) => any;
|
|
106
|
+
}, string, import("vue").PublicProps, Readonly<{
|
|
107
|
+
/**
|
|
108
|
+
* The current page, 1-based. Leave it unset to let the component keep its
|
|
109
|
+
* own page and simply report changes.
|
|
110
|
+
*/
|
|
111
|
+
page?: number;
|
|
112
|
+
/** How many items exist in total, across every page. */
|
|
113
|
+
total: number;
|
|
114
|
+
/** How many items one page holds. With `total`, this is what fixes the page count. */
|
|
115
|
+
itemsPerPage?: number;
|
|
116
|
+
/** How much of the control renders: the numbered row, a position readout, or arrows alone. */
|
|
117
|
+
variant?: PaginationVariant;
|
|
118
|
+
/** How many numbers sit either side of the current page, in the `full` variant. */
|
|
119
|
+
siblingCount?: number;
|
|
120
|
+
/** Pins page 1 and the last page into the numbered row, with ellipses standing in for the gap. */
|
|
121
|
+
showEdges?: boolean;
|
|
122
|
+
/** Unavailable: every control dims and refuses to move the page. */
|
|
123
|
+
disabled?: boolean;
|
|
124
|
+
/**
|
|
125
|
+
* Names for everything this control says out loud, as any subset of
|
|
126
|
+
* `PaginationLabels` — the rest stay as the host's `provideLoomLabels`
|
|
127
|
+
* vocabulary left them, and then as Loom's English.
|
|
128
|
+
*
|
|
129
|
+
* This is the per-instance correction, not the place to localise an
|
|
130
|
+
* application: the case it exists for is the two paginations above and
|
|
131
|
+
* below one table, which must not share `labels.nav`.
|
|
132
|
+
*/
|
|
133
|
+
labels?: LabelOverrides<PaginationLabels>;
|
|
134
|
+
}> & Readonly<{
|
|
135
|
+
"onUpdate:page"?: (page: number) => any;
|
|
136
|
+
}>, {
|
|
137
|
+
disabled: boolean;
|
|
138
|
+
variant: PaginationVariant;
|
|
139
|
+
itemsPerPage: number;
|
|
140
|
+
siblingCount: number;
|
|
141
|
+
showEdges: boolean;
|
|
142
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
143
|
+
//# sourceMappingURL=Pagination.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Pagination.vue.d.ts","sourceRoot":"","sources":["../../../src/primitives/Pagination/Pagination.vue"],"names":[],"mappings":"AAiaA,OAAO,EAAa,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAIlE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAEhD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;OAKG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,yCAAyC;IACzC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,2CAA2C;IAC3C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,yCAAyC;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,8CAA8C;IAC9C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,gFAAgF;IAChF,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACzC,wEAAwE;IACxE,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChE,yEAAyE;IACzE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,EAAE,gBAS/B,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE9D,eAAO,MAAM,kBAAkB;;8EAe7B,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC;AACzC,QAAA,MAAM,YAAY;IAsBd;;;OAGG;WACI,MAAM;IACb,wDAAwD;WACjD,MAAM;IACb,sFAAsF;mBACvE,MAAM;IACrB,8FAA8F;cACpF,iBAAiB;IAC3B,mFAAmF;mBACpE,MAAM;IACrB,kGAAkG;gBACtF,OAAO;IACnB,oEAAoE;eACzD,OAAO;IAClB;;;;;;;;OAQG;aACM,cAAc,CAAC,gBAAgB,CAAC;;;;IA1BzC;;;OAGG;WACI,MAAM;IACb,wDAAwD;WACjD,MAAM;IACb,sFAAsF;mBACvE,MAAM;IACrB,8FAA8F;cACpF,iBAAiB;IAC3B,mFAAmF;mBACpE,MAAM;IACrB,kGAAkG;gBACtF,OAAO;IACnB,oEAAoE;eACzD,OAAO;IAClB;;;;;;;;OAQG;aACM,cAAc,CAAC,gBAAgB,CAAC;;;;cAV9B,OAAO;aANR,iBAAiB;kBAFZ,MAAM;kBAIN,MAAM;eAET,OAAO;6EA2dnB,CAAC"}
|