@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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Textarea.js","names":[],"sources":["../../../src/primitives/Textarea/Textarea.vue"],"sourcesContent":["<script lang=\"ts\">\nexport type TextareaResize = \"none\" | \"vertical\";\n</script>\n\n<script setup lang=\"ts\">\nimport { cn } from \"../../lib/cn\";\nimport { useSplitAttrs } from \"../../lib/attrs\";\n\n/**\n * Textarea — multi-line text entry. A native `<textarea>`, single node (no\n * wrapper — unlike TextField there are no `#leading`/`#trailing` adornments to\n * frame), so `class` and the rest of the fallthrough attrs both target the\n * same element; still routed through `useSplitAttrs()` for the same reason as\n * every other primitive — a caller's `class` needs a Tailwind-aware `cn()`\n * merge, not a raw `v-bind` clobbering it. The accessible name is a\n * first-class prop pair (`aria-label`/`aria-labelledby`, camelized by Vue)\n * bound onto the textarea explicitly, the same contract as TextField.\n */\nwithDefaults(\n defineProps<{\n /** The current value. Pair with `@update:modelValue` for `v-model`. */\n modelValue?: string;\n /** Text shown in the empty field. */\n placeholder?: string;\n /** Disables the field and blocks pointer and keyboard input. */\n disabled?: boolean;\n /** Error state: paints the destructive border/ring and sets aria-invalid. */\n invalid?: boolean;\n /** Initial height in text rows. */\n rows?: number;\n /** Whether a person can drag-resize the field; `none` locks it to `rows`. */\n resize?: TextareaResize;\n /** The accessible name, when no visible element already labels the field. */\n ariaLabel?: string;\n /** The id of the visible element that labels the field (e.g. a Field wrapper's label). */\n ariaLabelledby?: string;\n }>(),\n {\n disabled: false,\n invalid: false,\n rows: 3,\n resize: \"vertical\",\n },\n);\n\ndefineEmits<{ \"update:modelValue\": [value: string] }>();\n\ndefineOptions({ inheritAttrs: false });\nconst { attrs, rest: textareaAttrs } = useSplitAttrs();\n</script>\n\n<template>\n <textarea\n v-bind=\"textareaAttrs\"\n :aria-label=\"ariaLabel\"\n :aria-labelledby=\"ariaLabelledby\"\n :value=\"modelValue\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :rows=\"rows\"\n :aria-invalid=\"invalid || undefined\"\n :class=\"\n cn(\n 'rounded-md border border-input bg-background text-foreground px-3 py-2 text-sm',\n 'transition-[color,background-color,border-color,box-shadow] duration-fast ease-out',\n // Rim-lit at rest, the weave blooms on focus (Signature law).\n 'focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring',\n !invalid && 'focus-visible:shadow-halo',\n 'placeholder:text-muted-foreground',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n invalid && 'border-destructive focus-visible:outline-destructive',\n resize === 'none' ? 'resize-none' : 'resize-y',\n attrs.class as string,\n )\n \"\n @input=\"$emit('update:modelValue', ($event.target as HTMLTextAreaElement).value)\"\n />\n</template>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"Textarea.js","names":[],"sources":["../../../src/primitives/Textarea/Textarea.vue"],"sourcesContent":["<script lang=\"ts\">\nimport {\n COUNT_LABELS,\n warningWindow,\n type CountBand,\n type CountLabels,\n} from \"../../lib/count-labels\";\n\nexport type TextareaResize = \"none\" | \"vertical\";\n\n/**\n * Everything this control says out loud, and every word of it is Loom's own —\n * a bare `<textarea>` renders no English of anybody else's, so a dropped key\n * here falls back to nothing rather than to a stray untranslated string.\n *\n * These are TextField's five counter keys, by name and by argument shape, and\n * deliberately so: a host that has already worded a character counter should be\n * able to copy that bag across unchanged. They come from\n * `src/lib/count-labels.ts` rather than being declared a second time. They are\n * a slot of their own rather than a share of `textField`'s because that slot\n * also carries `reveal`, and handing a textarea's translator a password-toggle\n * key to fill in is asking a question the control cannot answer.\n */\nexport type TextareaLabels = CountLabels;\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 * rather than a transcription of it.\n */\nexport const TEXTAREA_LABELS: TextareaLabels = COUNT_LABELS;\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, ref, useId, watch } from \"vue\";\nimport { cn } from \"../../lib/cn\";\nimport { useSplitAttrs } from \"../../lib/attrs\";\nimport { useFieldControl } from \"../../lib/field-context\";\nimport { useLabels, type LabelOverrides } from \"../../lib/labels\";\n\n/**\n * Textarea — multi-line text entry, around a native `<textarea>`. The\n * accessible name is a first-class prop pair (`aria-label`/`aria-labelledby`,\n * camelized by Vue) bound onto the textarea explicitly, the same contract as\n * TextField.\n *\n * The border, focus ring and invalid state live on the wrapper so optional\n * `#leading`/`#trailing` adornments sit *inside* the field and share its focus\n * bloom, instead of every caller re-inventing an icon-inside-input layout.\n * The slot names and positions match TextField's, and the vertical alignment\n * differs — `items-start` for multi-line, where the text begins, versus\n * `items-center` for single-line — because a five-row box with a centered icon\n * mid-field reads as a mistake rather than a choice.\n *\n * Wrapping a rendered structure means the fallthrough `class` must land on the\n * wrapper (so a caller's `w-64`/`flex-1` sizes the whole field) while the rest\n * of the attrs (`id`, `name`, `data-testid`, `aria-describedby`) belong on the\n * real `<textarea>` — the split-attrs convention shared with TextField.\n *\n * That same wrapper is why the character counter is a prop here rather than a\n * `CountedField` beside this one. A counter rendered *below* the field would\n * have to move the fallthrough `class` off the box a caller sizes with it, and\n * a textarea has no free column to hang one in — the value fills the box and\n * scrolls, and the bottom-right corner belongs to the native resize grabber.\n * The counter sits below the border, where `resize` moves the box's bottom\n * edge and the counter travels with it rather than floating over the text.\n *\n * Inside a [Field](../Field/Field.vue) it wires itself through\n * `useFieldControl()` — the row's id, the id of its hint or error line, and\n * `required` / `invalid` / `disabled` / `readonly` / `name` — so\n * `<Field label=\"Bio\" hint=\"…\"><Textarea /></Field>` needs no attributes at the\n * call site. Every prop below still wins over the row when it is set, in both\n * directions, which is why the four booleans default to `undefined` rather\n * than `false`.\n *\n * `readonly` and `disabled` are different states, and they are told apart on\n * three channels rather than one. A read-only field is a value on show: the\n * subtle fill, the text at full strength, the input hairline, still a Tab stop\n * and still submitted. A disabled one is unavailable: the deeper neutral fill,\n * the muted text, and the hairline receding to the plain border — a difference\n * in shape as well as in colour, which is what survives a reader who cannot\n * resolve the two fills apart.\n */\nconst props = withDefaults(\n defineProps<{\n /** The current value. Pair with `@update:modelValue` for `v-model`. */\n modelValue?: string;\n /** Text shown in the empty field. */\n placeholder?: string;\n /** Disables the field and blocks pointer and keyboard input. Unset defers to a wrapping Field. */\n disabled?: boolean | undefined;\n /** Shows the value without allowing an edit, while staying focusable and still submitted. Unset defers to a wrapping Field. */\n readonly?: boolean | undefined;\n /** Error state: paints the destructive border/ring and sets aria-invalid. Unset defers to a wrapping Field's `error`. */\n invalid?: boolean | undefined;\n /** Marks the field mandatory to assistive tech (`aria-required`). Unset defers to a wrapping Field. */\n required?: boolean | undefined;\n /** The field name for a native form post or `FormData`. Unset defers to a wrapping Field. */\n name?: string;\n /** Initial height in text rows. */\n rows?: number;\n /** Whether a person can drag-resize the field; `none` locks it to `rows`. The counter sits below the box either way, so a drag never moves it onto the value. */\n resize?: TextareaResize;\n /** The accessible name, when no visible element already labels the field. */\n ariaLabel?: string;\n /** The id of the visible element that labels the field (e.g. a Field wrapper's label). */\n ariaLabelledby?: string;\n /**\n * The character limit the counter reports against, and the point past\n * which it reads as over-limit.\n *\n * Advisory, exactly as `required` is: it does **not** set the native\n * `maxlength`, which silently truncates a paste and tells the reader\n * nothing. Pass `maxlength` yourself as a plain attribute where you want\n * the browser to enforce it too.\n */\n maxLength?: number;\n /**\n * Forces the counter on or off. Left unset it follows `maxLength` — a\n * limit the reader is never shown is one they can only discover by\n * exceeding it — so set it `true` for a running total with no limit, and\n * `false` to hold a limit the field reports nowhere.\n */\n showCount?: boolean | undefined;\n /**\n * Names for everything this control says out loud, as any subset of\n * `TextareaLabels` — 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 a field counting something other\n * than characters, where \"80 words left\" is the true sentence.\n */\n labels?: LabelOverrides<TextareaLabels>;\n }>(),\n {\n // Not `false`, for any of the four — see TextField.vue, which carries the\n // full reasoning. `false` is a caller's decision that must beat the row;\n // absent is a caller saying nothing, and only `undefined` survives to mean\n // that past Vue's absent-Boolean-casts-to-false rule.\n disabled: undefined,\n readonly: undefined,\n invalid: undefined,\n required: undefined,\n rows: 3,\n resize: \"vertical\",\n // `undefined` for the same Boolean-cast reason, and here it is the whole\n // feature: `showCount ?? (maxLength !== undefined)` would be a dead branch\n // if an absent prop arrived as `false`.\n showCount: undefined,\n },\n);\n\nconst emit = defineEmits<{ \"update:modelValue\": [value: string] }>();\n\ndefineOptions({ inheritAttrs: false });\nconst { attrs, rest: textareaAttrs } = useSplitAttrs();\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(\"textarea\", TEXTAREA_LABELS, () => props.labels);\n\nconst countId = useId();\n\n/**\n * What is actually in the box, which is not always `modelValue` — TextField's\n * reasoning, and the same defect waiting on this side of it.\n *\n * Used without `v-model` this component is uncontrolled, so `modelValue` stays\n * `undefined` while the reader types and the counter still has to count. And\n * binding `:value=\"currentValue\"` rather than `:value=\"modelValue\"` is\n * load-bearing rather than cosmetic: Vue's `value` patch coerces\n * `null`/`undefined` to `\"\"`, so any re-render of an uncontrolled field wipes\n * it — a defect nothing had met only because nothing in this component\n * re-rendered on a keystroke until the counter did.\n */\nconst typed = ref(props.modelValue ?? \"\");\nconst currentValue = computed(() => props.modelValue ?? typed.value);\n\nfunction onInput(event: Event): void {\n const value = (event.target as HTMLTextAreaElement).value;\n typed.value = value;\n emit(\"update:modelValue\", value);\n}\n\n/**\n * Length in UTF-16 code units, which is what the platform's own `maxlength`\n * counts. `[...value].length` would count code points and disagree with the\n * browser on any astral character, so a caller who pairs this with a native\n * `maxlength` would watch the counter and the enforcement drift apart.\n */\nconst count = computed(() => currentValue.value.length);\nconst showsCount = computed(() => props.showCount ?? props.maxLength !== undefined);\n\nconst band = computed<CountBand>(() => {\n const max = props.maxLength;\n if (max === undefined) return \"under\";\n const remaining = max - count.value;\n if (remaining < 0) return \"over\";\n return remaining <= warningWindow(max) ? \"near\" : \"under\";\n});\n\nconst countText = computed(() => {\n const max = props.maxLength;\n if (max === undefined) return text.value.count({ count: count.value });\n const over = count.value - max;\n return over > 0\n ? text.value.countOverMax({ count: count.value, max, over })\n : text.value.countOfMax({ count: count.value, max });\n});\n\n/**\n * What the live region says, and it changes **only when the band changes** —\n * TextField's decision, taken once for the pair rather than re-litigated here.\n *\n * A region holding the counter itself would speak on every keystroke, burying\n * the field's own echo of the character just typed under a number nobody asked\n * for. What a reader needs is the two facts they cannot see coming — the limit\n * is close, and the limit is passed — so this fires once at each crossing and\n * goes quiet again on the way back down. The numbers are therefore true at the\n * moment they are spoken and not after; the visible counter carries the live\n * figure, and it is wired into `aria-describedby`, so the exact count is one\n * re-read away whenever the reader wants it rather than pushed at them.\n */\nconst announcement = ref(\"\");\nwatch(band, (now) => {\n const max = props.maxLength;\n if (max === undefined || now === \"under\") {\n announcement.value = \"\";\n return;\n }\n announcement.value =\n now === \"over\"\n ? text.value.limitExceeded({ over: count.value - max, max })\n : text.value.approachingLimit({ remaining: max - count.value, max });\n});\n\n// `id` and `aria-describedby` arrive as fallthrough attrs rather than props, so\n// they are handed in as this caller's own values: a caller who sets either\n// still beats the row, and the row's description is merged into theirs. The\n// counter joins that list rather than replacing anything — it reads after the\n// caller's own description and before the row's message, which is the same\n// most-specific-first order `useFieldControl` applies one layer out.\n//\n// `field.attrs` then spreads **after** `textareaAttrs`, and that position is\n// the contract — see TextField.vue, which carries the full reasoning. The\n// `:aria-invalid` binding that used to sit below went with it: an individual\n// attribute written after a `v-bind` wins, so keeping one would overwrite the\n// resolved value with the raw prop.\nconst field = useFieldControl(() => ({\n id: attrs.id as string | undefined,\n describedBy: [attrs[\"aria-describedby\"] as string | undefined, showsCount.value ? countId : \"\"]\n .filter((id): id is string => typeof id === \"string\" && id.length > 0)\n .join(\" \"),\n name: props.name,\n disabled: props.disabled,\n readonly: props.readonly,\n invalid: props.invalid,\n required: props.required,\n}));\n</script>\n\n<template>\n <!-- Layout, and nothing else: no fallthrough attribute lands here and nothing\n is painted on it. `inline-flex` is what makes it shrink-wrap the field\n frame — a block wrapper would be as wide as the column, and the counter\n would right-align to that column rather than to the field's own edge. -->\n <div class=\"inline-flex max-w-full flex-col align-top\">\n <!-- The field frame: border, focus, state. Like TextField, the border lives\n here so optional #leading/#trailing adornments sit inside the field and\n share its focus bloom, instead of every caller re-inventing an\n icon-inside-input layout. -->\n <div\n :data-disabled=\"field.disabled || undefined\"\n :data-readonly=\"field.readonly || undefined\"\n :data-invalid=\"field.invalid || undefined\"\n :class=\"\n cn(\n 'group flex items-start gap-2 rounded-md border border-input bg-background text-foreground px-3 py-2 text-sm',\n 'transition-[color,background-color,border-color,box-shadow] duration-fast ease-out',\n // Rim-lit at rest, the weave blooms on focus (Signature law): the field\n // catches light instead of casting a shadow, and focus draws it tight.\n 'focus-within:outline-2 focus-within:outline-offset-2 focus-within:outline-ring',\n !field.invalid && 'focus-within:shadow-halo',\n // The three resting appearances, and each is three changes rather than\n // one. Read-only and disabled used to share `bg-muted` and part only on\n // the text colour, which is a distinction carried by hue alone — the\n // one thing a reader with a colour deficiency, or a low-quality\n // display, or forced-colors, does not get. The fill separates them and\n // the border weight separates them again, so the progression\n // available → on show → unavailable is legible on three channels.\n //\n // Read-only is a value **on show**: the fill lifts off `background` to\n // `subtle` so the row reads as settled rather than editable, and the\n // text stays full strength — 13.46:1 over that fill — because being\n // read is the entire purpose of the state. The border does not move,\n // because nothing about the control's reach has: it is still a Tab stop\n // and still submitted. The native `readonly` attribute below carries\n // the same fact to assistive tech, so nothing here rests on colour.\n field.readonly && 'bg-subtle',\n // Disabled is **unavailable**: the fill drains one step further to\n // `muted`, the text follows it down to `muted-foreground` (4.68:1 over\n // it, still AA), and the rim slackens from `input` to the lighter\n // `border`.\n //\n // Drained rather than faded, and `opacity` is never the mechanism. The\n // element a dim would sit on is the box, and the box is wrapped around\n // the one thing a reader still needs: measured on the built site,\n // `opacity-50` put a disabled field's value at 3.08:1 and its\n // placeholder — already the muted colour before the fade — at 2.07:1.\n // The text colour is declared here rather than on the `<textarea>` because\n // the textarea sets no resting colour of its own and inherits this one,\n // which also carries it to the adornments in the same box.\n field.disabled && 'cursor-not-allowed border-border bg-muted text-muted-foreground',\n // The same appearance, reached from the other direction: a\n // `<fieldset disabled>` above this field disables the `<textarea>` inside\n // it natively and never touches `field.disabled`, so the rule above\n // cannot fire and the field rendered byte-identical to an editable one.\n //\n // `in-[fieldset:disabled]:` is a *read* of the attribute that did the\n // disabling, so the fill and the native inertness cannot disagree — the\n // fieldset element is still the only place the fact is written. It is\n // preferred to `has-[:disabled]:` (a wrapper reading its own contents)\n // because that proxy is wrong wherever a control holds a part that\n // disables itself.\n 'in-[fieldset:disabled]:cursor-not-allowed in-[fieldset:disabled]:bg-muted in-[fieldset:disabled]:text-muted-foreground',\n // Gated where the two rules below are ordered, and for the same reason.\n // Tailwind emits the ancestor half of `in-*` inside `:where()`, so this\n // carries no more specificity than `border-destructive` and would win\n // on emission order alone — an unavailable field that is also in error\n // would quietly lose its destructive rim.\n !field.invalid && 'in-[fieldset:disabled]:border-border',\n // Last of the three rules that name a border colour, and the order is\n // load-bearing: `cn()` resolves a border colour by whichever class it\n // saw last, so a field that is both in error and unavailable would lose\n // its destructive rim to the disabled one if this sat above it.\n field.invalid && 'border-destructive focus-within:outline-destructive',\n attrs.class as string,\n )\n \"\n >\n <span\n v-if=\"$slots.leading\"\n class=\"inline-flex shrink-0 text-muted-foreground transition-colors duration-fast ease-out group-focus-within:text-foreground\"\n >\n <slot name=\"leading\" />\n </span>\n <textarea\n v-bind=\"{ ...textareaAttrs, ...field.attrs }\"\n :aria-label=\"ariaLabel\"\n :aria-labelledby=\"ariaLabelledby\"\n :value=\"currentValue\"\n :placeholder=\"placeholder\"\n :disabled=\"field.disabled\"\n :readonly=\"field.readonly\"\n :rows=\"rows\"\n :class=\"\n cn(\n 'min-w-0 flex-1 bg-transparent outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed',\n resize === 'none' ? 'resize-none' : 'resize-y',\n )\n \"\n @input=\"onInput\"\n />\n <span\n v-if=\"$slots.trailing\"\n class=\"inline-flex shrink-0 items-center gap-1 text-muted-foreground transition-colors duration-fast ease-out group-focus-within:text-foreground\"\n >\n <slot name=\"trailing\" />\n </span>\n </div>\n <!-- Below the box, never inside it. A textarea's value fills its box and\n scrolls, so there is no free column to hang a readout in, and the\n bottom-right corner belongs to the native resize grabber — an inset\n counter would sit on top of the one affordance that says the field can\n be dragged. Here it travels with the bottom edge instead, so `resize`\n moves it rather than moving the box out from under it.\n\n `tabular` because the number changes under itself on every keystroke,\n and proportional digits would shuffle the whole readout sideways as\n they do. -->\n <span\n v-if=\"showsCount\"\n :id=\"countId\"\n :data-over-limit=\"band === 'over' || undefined\"\n :class=\"\n cn(\n 'tabular mt-1 select-none self-end text-small',\n band === 'under' && 'text-muted-foreground',\n // Colour, and never only colour: `countOverMax` says the limit is\n // passed in words as well, and `approachingLimit` announces the near\n // band once. The digits themselves are the third reading — 21/20 is\n // over the limit whatever it is painted.\n band === 'near' && 'text-warning',\n band === 'over' && 'text-destructive',\n )\n \"\n >\n {{ countText }}\n </span>\n <!-- In the DOM from the first render, empty. A live region mounted at the\n same moment as its text is a region assistive tech was not yet\n watching, so the first warning — the one that matters most — is the one\n it announces least reliably. -->\n <span v-if=\"showsCount && maxLength !== undefined\" role=\"status\" class=\"sr-only\">\n {{ announcement }}\n </span>\n </div>\n</template>\n"],"mappings":""}
|
|
@@ -1,23 +1,78 @@
|
|
|
1
|
+
import { type LabelOverrides } from "../../lib/labels";
|
|
2
|
+
import { type CountLabels } from "../../lib/count-labels";
|
|
1
3
|
export type TextareaResize = "none" | "vertical";
|
|
4
|
+
/**
|
|
5
|
+
* Everything this control says out loud, and every word of it is Loom's own —
|
|
6
|
+
* a bare `<textarea>` renders no English of anybody else's, so a dropped key
|
|
7
|
+
* here falls back to nothing rather than to a stray untranslated string.
|
|
8
|
+
*
|
|
9
|
+
* These are TextField's five counter keys, by name and by argument shape, and
|
|
10
|
+
* deliberately so: a host that has already worded a character counter should be
|
|
11
|
+
* able to copy that bag across unchanged. They come from
|
|
12
|
+
* `src/lib/count-labels.ts` rather than being declared a second time. They are
|
|
13
|
+
* a slot of their own rather than a share of `textField`'s because that slot
|
|
14
|
+
* also carries `reveal`, and handing a textarea's translator a password-toggle
|
|
15
|
+
* key to fill in is asking a question the control cannot answer.
|
|
16
|
+
*/
|
|
17
|
+
export type TextareaLabels = CountLabels;
|
|
18
|
+
/**
|
|
19
|
+
* Loom's English, co-located with the component so it tree-shakes with it, and
|
|
20
|
+
* exported so a host can build a partial vocabulary against the real thing
|
|
21
|
+
* rather than a transcription of it.
|
|
22
|
+
*/
|
|
23
|
+
export declare const TEXTAREA_LABELS: TextareaLabels;
|
|
2
24
|
declare const _default: typeof __VLS_export;
|
|
3
25
|
export default _default;
|
|
4
|
-
declare const __VLS_export: import("vue").DefineComponent<{
|
|
26
|
+
declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
|
|
5
27
|
/** The current value. Pair with `@update:modelValue` for `v-model`. */
|
|
6
28
|
modelValue?: string;
|
|
7
29
|
/** Text shown in the empty field. */
|
|
8
30
|
placeholder?: string;
|
|
9
|
-
/** Disables the field and blocks pointer and keyboard input. */
|
|
10
|
-
disabled?: boolean;
|
|
11
|
-
/**
|
|
12
|
-
|
|
31
|
+
/** Disables the field and blocks pointer and keyboard input. Unset defers to a wrapping Field. */
|
|
32
|
+
disabled?: boolean | undefined;
|
|
33
|
+
/** Shows the value without allowing an edit, while staying focusable and still submitted. Unset defers to a wrapping Field. */
|
|
34
|
+
readonly?: boolean | undefined;
|
|
35
|
+
/** Error state: paints the destructive border/ring and sets aria-invalid. Unset defers to a wrapping Field's `error`. */
|
|
36
|
+
invalid?: boolean | undefined;
|
|
37
|
+
/** Marks the field mandatory to assistive tech (`aria-required`). Unset defers to a wrapping Field. */
|
|
38
|
+
required?: boolean | undefined;
|
|
39
|
+
/** The field name for a native form post or `FormData`. Unset defers to a wrapping Field. */
|
|
40
|
+
name?: string;
|
|
13
41
|
/** Initial height in text rows. */
|
|
14
42
|
rows?: number;
|
|
15
|
-
/** Whether a person can drag-resize the field; `none` locks it to `rows`. */
|
|
43
|
+
/** Whether a person can drag-resize the field; `none` locks it to `rows`. The counter sits below the box either way, so a drag never moves it onto the value. */
|
|
16
44
|
resize?: TextareaResize;
|
|
17
45
|
/** The accessible name, when no visible element already labels the field. */
|
|
18
46
|
ariaLabel?: string;
|
|
19
47
|
/** The id of the visible element that labels the field (e.g. a Field wrapper's label). */
|
|
20
48
|
ariaLabelledby?: string;
|
|
49
|
+
/**
|
|
50
|
+
* The character limit the counter reports against, and the point past
|
|
51
|
+
* which it reads as over-limit.
|
|
52
|
+
*
|
|
53
|
+
* Advisory, exactly as `required` is: it does **not** set the native
|
|
54
|
+
* `maxlength`, which silently truncates a paste and tells the reader
|
|
55
|
+
* nothing. Pass `maxlength` yourself as a plain attribute where you want
|
|
56
|
+
* the browser to enforce it too.
|
|
57
|
+
*/
|
|
58
|
+
maxLength?: number;
|
|
59
|
+
/**
|
|
60
|
+
* Forces the counter on or off. Left unset it follows `maxLength` — a
|
|
61
|
+
* limit the reader is never shown is one they can only discover by
|
|
62
|
+
* exceeding it — so set it `true` for a running total with no limit, and
|
|
63
|
+
* `false` to hold a limit the field reports nowhere.
|
|
64
|
+
*/
|
|
65
|
+
showCount?: boolean | undefined;
|
|
66
|
+
/**
|
|
67
|
+
* Names for everything this control says out loud, as any subset of
|
|
68
|
+
* `TextareaLabels` — the rest stay as the host's `provideLoomLabels`
|
|
69
|
+
* vocabulary left them, and then as Loom's English.
|
|
70
|
+
*
|
|
71
|
+
* This is the per-instance correction, not the place to localise an
|
|
72
|
+
* application: the case it exists for is a field counting something other
|
|
73
|
+
* than characters, where "80 words left" is the true sentence.
|
|
74
|
+
*/
|
|
75
|
+
labels?: LabelOverrides<TextareaLabels>;
|
|
21
76
|
}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
22
77
|
"update:modelValue": (value: string) => any;
|
|
23
78
|
}, string, import("vue").PublicProps, Readonly<{
|
|
@@ -25,24 +80,69 @@ declare const __VLS_export: import("vue").DefineComponent<{
|
|
|
25
80
|
modelValue?: string;
|
|
26
81
|
/** Text shown in the empty field. */
|
|
27
82
|
placeholder?: string;
|
|
28
|
-
/** Disables the field and blocks pointer and keyboard input. */
|
|
29
|
-
disabled?: boolean;
|
|
30
|
-
/**
|
|
31
|
-
|
|
83
|
+
/** Disables the field and blocks pointer and keyboard input. Unset defers to a wrapping Field. */
|
|
84
|
+
disabled?: boolean | undefined;
|
|
85
|
+
/** Shows the value without allowing an edit, while staying focusable and still submitted. Unset defers to a wrapping Field. */
|
|
86
|
+
readonly?: boolean | undefined;
|
|
87
|
+
/** Error state: paints the destructive border/ring and sets aria-invalid. Unset defers to a wrapping Field's `error`. */
|
|
88
|
+
invalid?: boolean | undefined;
|
|
89
|
+
/** Marks the field mandatory to assistive tech (`aria-required`). Unset defers to a wrapping Field. */
|
|
90
|
+
required?: boolean | undefined;
|
|
91
|
+
/** The field name for a native form post or `FormData`. Unset defers to a wrapping Field. */
|
|
92
|
+
name?: string;
|
|
32
93
|
/** Initial height in text rows. */
|
|
33
94
|
rows?: number;
|
|
34
|
-
/** Whether a person can drag-resize the field; `none` locks it to `rows`. */
|
|
95
|
+
/** Whether a person can drag-resize the field; `none` locks it to `rows`. The counter sits below the box either way, so a drag never moves it onto the value. */
|
|
35
96
|
resize?: TextareaResize;
|
|
36
97
|
/** The accessible name, when no visible element already labels the field. */
|
|
37
98
|
ariaLabel?: string;
|
|
38
99
|
/** The id of the visible element that labels the field (e.g. a Field wrapper's label). */
|
|
39
100
|
ariaLabelledby?: string;
|
|
101
|
+
/**
|
|
102
|
+
* The character limit the counter reports against, and the point past
|
|
103
|
+
* which it reads as over-limit.
|
|
104
|
+
*
|
|
105
|
+
* Advisory, exactly as `required` is: it does **not** set the native
|
|
106
|
+
* `maxlength`, which silently truncates a paste and tells the reader
|
|
107
|
+
* nothing. Pass `maxlength` yourself as a plain attribute where you want
|
|
108
|
+
* the browser to enforce it too.
|
|
109
|
+
*/
|
|
110
|
+
maxLength?: number;
|
|
111
|
+
/**
|
|
112
|
+
* Forces the counter on or off. Left unset it follows `maxLength` — a
|
|
113
|
+
* limit the reader is never shown is one they can only discover by
|
|
114
|
+
* exceeding it — so set it `true` for a running total with no limit, and
|
|
115
|
+
* `false` to hold a limit the field reports nowhere.
|
|
116
|
+
*/
|
|
117
|
+
showCount?: boolean | undefined;
|
|
118
|
+
/**
|
|
119
|
+
* Names for everything this control says out loud, as any subset of
|
|
120
|
+
* `TextareaLabels` — the rest stay as the host's `provideLoomLabels`
|
|
121
|
+
* vocabulary left them, and then as Loom's English.
|
|
122
|
+
*
|
|
123
|
+
* This is the per-instance correction, not the place to localise an
|
|
124
|
+
* application: the case it exists for is a field counting something other
|
|
125
|
+
* than characters, where "80 words left" is the true sentence.
|
|
126
|
+
*/
|
|
127
|
+
labels?: LabelOverrides<TextareaLabels>;
|
|
40
128
|
}> & Readonly<{
|
|
41
129
|
"onUpdate:modelValue"?: (value: string) => any;
|
|
42
130
|
}>, {
|
|
43
|
-
disabled: boolean;
|
|
44
|
-
invalid: boolean;
|
|
45
131
|
resize: TextareaResize;
|
|
132
|
+
disabled: boolean | undefined;
|
|
133
|
+
invalid: boolean | undefined;
|
|
134
|
+
readonly: boolean | undefined;
|
|
135
|
+
required: boolean | undefined;
|
|
46
136
|
rows: number;
|
|
47
|
-
|
|
137
|
+
showCount: boolean | undefined;
|
|
138
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, {
|
|
139
|
+
leading?: (props: {}) => any;
|
|
140
|
+
} & {
|
|
141
|
+
trailing?: (props: {}) => any;
|
|
142
|
+
}>;
|
|
143
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
144
|
+
new (): {
|
|
145
|
+
$slots: S;
|
|
146
|
+
};
|
|
147
|
+
};
|
|
48
148
|
//# sourceMappingURL=Textarea.vue.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Textarea.vue.d.ts","sourceRoot":"","sources":["../../../src/primitives/Textarea/Textarea.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Textarea.vue.d.ts","sourceRoot":"","sources":["../../../src/primitives/Textarea/Textarea.vue"],"names":[],"mappings":"AAiaA,OAAO,EAAa,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGlE,OAAO,EAIL,KAAK,WAAW,EACjB,MAAM,wBAAwB,CAAC;AAEhC,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,UAAU,CAAC;AAEjD;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,cAAc,GAAG,WAAW,CAAC;AAEzC;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,cAA6B,CAAC;wBACvC,OAAO,YAAY;AAAxC,wBAAyC;AACzC,QAAA,MAAM,YAAY;IA6Cd,uEAAuE;iBAC1D,MAAM;IACnB,qCAAqC;kBACvB,MAAM;IACpB,kGAAkG;eACvF,OAAO,GAAG,SAAS;IAC9B,+HAA+H;eACpH,OAAO,GAAG,SAAS;IAC9B,yHAAyH;cAC/G,OAAO,GAAG,SAAS;IAC7B,uGAAuG;eAC5F,OAAO,GAAG,SAAS;IAC9B,6FAA6F;WACtF,MAAM;IACb,mCAAmC;WAC5B,MAAM;IACb,iKAAiK;aACxJ,cAAc;IACvB,6EAA6E;gBACjE,MAAM;IAClB,0FAA0F;qBACzE,MAAM;IACvB;;;;;;;;OAQG;gBACS,MAAM;IAClB;;;;;OAKG;gBACS,OAAO,GAAG,SAAS;IAC/B;;;;;;;;OAQG;aACM,cAAc,CAAC,cAAc,CAAC;;;;IAhDvC,uEAAuE;iBAC1D,MAAM;IACnB,qCAAqC;kBACvB,MAAM;IACpB,kGAAkG;eACvF,OAAO,GAAG,SAAS;IAC9B,+HAA+H;eACpH,OAAO,GAAG,SAAS;IAC9B,yHAAyH;cAC/G,OAAO,GAAG,SAAS;IAC7B,uGAAuG;eAC5F,OAAO,GAAG,SAAS;IAC9B,6FAA6F;WACtF,MAAM;IACb,mCAAmC;WAC5B,MAAM;IACb,iKAAiK;aACxJ,cAAc;IACvB,6EAA6E;gBACjE,MAAM;IAClB,0FAA0F;qBACzE,MAAM;IACvB;;;;;;;;OAQG;gBACS,MAAM;IAClB;;;;;OAKG;gBACS,OAAO,GAAG,SAAS;IAC/B;;;;;;;;OAQG;aACM,cAAc,CAAC,cAAc,CAAC;;;;YA/B9B,cAAc;cAZZ,OAAO,GAAG,SAAS;aAIpB,OAAO,GAAG,SAAS;cAFlB,OAAO,GAAG,SAAS;cAInB,OAAO,GAAG,SAAS;UAIvB,MAAM;eAuBD,OAAO,GAAG,SAAS;;cAoVrB,CAAC,KAAK,IAAgB,KAAK,GAAG;;eAC7B,CAAC,KAAK,IAAgB,KAAK,GAAG;EAWzC,CAAC;AAWL,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
|
|
@@ -1,16 +1,88 @@
|
|
|
1
1
|
import { cn } from "../../lib/cn.js";
|
|
2
|
+
import { useLabels } from "../../lib/labels.js";
|
|
2
3
|
import { useSplitAttrs } from "../../lib/attrs.js";
|
|
3
|
-
import {
|
|
4
|
+
import { useFieldControl } from "../../lib/field-context.js";
|
|
5
|
+
import { COUNT_LABELS, warningWindow } from "../../lib/count-labels.js";
|
|
6
|
+
import { computed, createCommentVNode, createElementBlock, createElementVNode, defineComponent, mergeProps, normalizeClass, openBlock, ref, renderSlot, toDisplayString, unref, useId, watch } from "vue";
|
|
4
7
|
//#region src/primitives/Textarea/Textarea.vue?vue&type=script&setup=true&lang.ts
|
|
5
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Textarea — multi-line text entry, around a native `<textarea>`. The
|
|
10
|
+
* accessible name is a first-class prop pair (`aria-label`/`aria-labelledby`,
|
|
11
|
+
* camelized by Vue) bound onto the textarea explicitly, the same contract as
|
|
12
|
+
* TextField.
|
|
13
|
+
*
|
|
14
|
+
* The border, focus ring and invalid state live on the wrapper so optional
|
|
15
|
+
* `#leading`/`#trailing` adornments sit *inside* the field and share its focus
|
|
16
|
+
* bloom, instead of every caller re-inventing an icon-inside-input layout.
|
|
17
|
+
* The slot names and positions match TextField's, and the vertical alignment
|
|
18
|
+
* differs — `items-start` for multi-line, where the text begins, versus
|
|
19
|
+
* `items-center` for single-line — because a five-row box with a centered icon
|
|
20
|
+
* mid-field reads as a mistake rather than a choice.
|
|
21
|
+
*
|
|
22
|
+
* Wrapping a rendered structure means the fallthrough `class` must land on the
|
|
23
|
+
* wrapper (so a caller's `w-64`/`flex-1` sizes the whole field) while the rest
|
|
24
|
+
* of the attrs (`id`, `name`, `data-testid`, `aria-describedby`) belong on the
|
|
25
|
+
* real `<textarea>` — the split-attrs convention shared with TextField.
|
|
26
|
+
*
|
|
27
|
+
* That same wrapper is why the character counter is a prop here rather than a
|
|
28
|
+
* `CountedField` beside this one. A counter rendered *below* the field would
|
|
29
|
+
* have to move the fallthrough `class` off the box a caller sizes with it, and
|
|
30
|
+
* a textarea has no free column to hang one in — the value fills the box and
|
|
31
|
+
* scrolls, and the bottom-right corner belongs to the native resize grabber.
|
|
32
|
+
* The counter sits below the border, where `resize` moves the box's bottom
|
|
33
|
+
* edge and the counter travels with it rather than floating over the text.
|
|
34
|
+
*
|
|
35
|
+
* Inside a [Field](../Field/Field.vue) it wires itself through
|
|
36
|
+
* `useFieldControl()` — the row's id, the id of its hint or error line, and
|
|
37
|
+
* `required` / `invalid` / `disabled` / `readonly` / `name` — so
|
|
38
|
+
* `<Field label="Bio" hint="…"><Textarea /></Field>` needs no attributes at the
|
|
39
|
+
* call site. Every prop below still wins over the row when it is set, in both
|
|
40
|
+
* directions, which is why the four booleans default to `undefined` rather
|
|
41
|
+
* than `false`.
|
|
42
|
+
*
|
|
43
|
+
* `readonly` and `disabled` are different states, and they are told apart on
|
|
44
|
+
* three channels rather than one. A read-only field is a value on show: the
|
|
45
|
+
* subtle fill, the text at full strength, the input hairline, still a Tab stop
|
|
46
|
+
* and still submitted. A disabled one is unavailable: the deeper neutral fill,
|
|
47
|
+
* the muted text, and the hairline receding to the plain border — a difference
|
|
48
|
+
* in shape as well as in colour, which is what survives a reader who cannot
|
|
49
|
+
* resolve the two fills apart.
|
|
50
|
+
*/
|
|
51
|
+
var _hoisted_1 = { class: "inline-flex max-w-full flex-col align-top" };
|
|
52
|
+
var _hoisted_2 = [
|
|
53
|
+
"data-disabled",
|
|
54
|
+
"data-readonly",
|
|
55
|
+
"data-invalid"
|
|
56
|
+
];
|
|
57
|
+
var _hoisted_3 = {
|
|
58
|
+
key: 0,
|
|
59
|
+
class: "inline-flex shrink-0 text-muted-foreground transition-colors duration-fast ease-out group-focus-within:text-foreground"
|
|
60
|
+
};
|
|
61
|
+
var _hoisted_4 = [
|
|
6
62
|
"aria-label",
|
|
7
63
|
"aria-labelledby",
|
|
8
64
|
"value",
|
|
9
65
|
"placeholder",
|
|
10
66
|
"disabled",
|
|
11
|
-
"
|
|
12
|
-
"
|
|
67
|
+
"readonly",
|
|
68
|
+
"rows"
|
|
13
69
|
];
|
|
70
|
+
var _hoisted_5 = {
|
|
71
|
+
key: 1,
|
|
72
|
+
class: "inline-flex shrink-0 items-center gap-1 text-muted-foreground transition-colors duration-fast ease-out group-focus-within:text-foreground"
|
|
73
|
+
};
|
|
74
|
+
var _hoisted_6 = ["id", "data-over-limit"];
|
|
75
|
+
var _hoisted_7 = {
|
|
76
|
+
key: 1,
|
|
77
|
+
role: "status",
|
|
78
|
+
class: "sr-only"
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Loom's English, co-located with the component so it tree-shakes with it, and
|
|
82
|
+
* exported so a host can build a partial vocabulary against the real thing
|
|
83
|
+
* rather than a transcription of it.
|
|
84
|
+
*/
|
|
85
|
+
var TEXTAREA_LABELS = COUNT_LABELS;
|
|
14
86
|
var Textarea_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
|
|
15
87
|
inheritAttrs: false,
|
|
16
88
|
__name: "Textarea",
|
|
@@ -19,36 +91,160 @@ var Textarea_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineC
|
|
|
19
91
|
placeholder: {},
|
|
20
92
|
disabled: {
|
|
21
93
|
type: Boolean,
|
|
22
|
-
default:
|
|
94
|
+
default: void 0
|
|
95
|
+
},
|
|
96
|
+
readonly: {
|
|
97
|
+
type: Boolean,
|
|
98
|
+
default: void 0
|
|
23
99
|
},
|
|
24
100
|
invalid: {
|
|
25
101
|
type: Boolean,
|
|
26
|
-
default:
|
|
102
|
+
default: void 0
|
|
27
103
|
},
|
|
104
|
+
required: {
|
|
105
|
+
type: Boolean,
|
|
106
|
+
default: void 0
|
|
107
|
+
},
|
|
108
|
+
name: {},
|
|
28
109
|
rows: { default: 3 },
|
|
29
110
|
resize: { default: "vertical" },
|
|
30
111
|
ariaLabel: {},
|
|
31
|
-
ariaLabelledby: {}
|
|
112
|
+
ariaLabelledby: {},
|
|
113
|
+
maxLength: {},
|
|
114
|
+
showCount: {
|
|
115
|
+
type: Boolean,
|
|
116
|
+
default: void 0
|
|
117
|
+
},
|
|
118
|
+
labels: {}
|
|
32
119
|
},
|
|
33
120
|
emits: ["update:modelValue"],
|
|
34
|
-
setup(__props) {
|
|
121
|
+
setup(__props, { emit: __emit }) {
|
|
122
|
+
const props = __props;
|
|
123
|
+
const emit = __emit;
|
|
35
124
|
const { attrs, rest: textareaAttrs } = useSplitAttrs();
|
|
125
|
+
const text = useLabels("textarea", TEXTAREA_LABELS, () => props.labels);
|
|
126
|
+
const countId = useId();
|
|
127
|
+
/**
|
|
128
|
+
* What is actually in the box, which is not always `modelValue` — TextField's
|
|
129
|
+
* reasoning, and the same defect waiting on this side of it.
|
|
130
|
+
*
|
|
131
|
+
* Used without `v-model` this component is uncontrolled, so `modelValue` stays
|
|
132
|
+
* `undefined` while the reader types and the counter still has to count. And
|
|
133
|
+
* binding `:value="currentValue"` rather than `:value="modelValue"` is
|
|
134
|
+
* load-bearing rather than cosmetic: Vue's `value` patch coerces
|
|
135
|
+
* `null`/`undefined` to `""`, so any re-render of an uncontrolled field wipes
|
|
136
|
+
* it — a defect nothing had met only because nothing in this component
|
|
137
|
+
* re-rendered on a keystroke until the counter did.
|
|
138
|
+
*/
|
|
139
|
+
const typed = ref(props.modelValue ?? "");
|
|
140
|
+
const currentValue = computed(() => props.modelValue ?? typed.value);
|
|
141
|
+
function onInput(event) {
|
|
142
|
+
const value = event.target.value;
|
|
143
|
+
typed.value = value;
|
|
144
|
+
emit("update:modelValue", value);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Length in UTF-16 code units, which is what the platform's own `maxlength`
|
|
148
|
+
* counts. `[...value].length` would count code points and disagree with the
|
|
149
|
+
* browser on any astral character, so a caller who pairs this with a native
|
|
150
|
+
* `maxlength` would watch the counter and the enforcement drift apart.
|
|
151
|
+
*/
|
|
152
|
+
const count = computed(() => currentValue.value.length);
|
|
153
|
+
const showsCount = computed(() => props.showCount ?? props.maxLength !== void 0);
|
|
154
|
+
const band = computed(() => {
|
|
155
|
+
const max = props.maxLength;
|
|
156
|
+
if (max === void 0) return "under";
|
|
157
|
+
const remaining = max - count.value;
|
|
158
|
+
if (remaining < 0) return "over";
|
|
159
|
+
return remaining <= warningWindow(max) ? "near" : "under";
|
|
160
|
+
});
|
|
161
|
+
const countText = computed(() => {
|
|
162
|
+
const max = props.maxLength;
|
|
163
|
+
if (max === void 0) return text.value.count({ count: count.value });
|
|
164
|
+
const over = count.value - max;
|
|
165
|
+
return over > 0 ? text.value.countOverMax({
|
|
166
|
+
count: count.value,
|
|
167
|
+
max,
|
|
168
|
+
over
|
|
169
|
+
}) : text.value.countOfMax({
|
|
170
|
+
count: count.value,
|
|
171
|
+
max
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
/**
|
|
175
|
+
* What the live region says, and it changes **only when the band changes** —
|
|
176
|
+
* TextField's decision, taken once for the pair rather than re-litigated here.
|
|
177
|
+
*
|
|
178
|
+
* A region holding the counter itself would speak on every keystroke, burying
|
|
179
|
+
* the field's own echo of the character just typed under a number nobody asked
|
|
180
|
+
* for. What a reader needs is the two facts they cannot see coming — the limit
|
|
181
|
+
* is close, and the limit is passed — so this fires once at each crossing and
|
|
182
|
+
* goes quiet again on the way back down. The numbers are therefore true at the
|
|
183
|
+
* moment they are spoken and not after; the visible counter carries the live
|
|
184
|
+
* figure, and it is wired into `aria-describedby`, so the exact count is one
|
|
185
|
+
* re-read away whenever the reader wants it rather than pushed at them.
|
|
186
|
+
*/
|
|
187
|
+
const announcement = ref("");
|
|
188
|
+
watch(band, (now) => {
|
|
189
|
+
const max = props.maxLength;
|
|
190
|
+
if (max === void 0 || now === "under") {
|
|
191
|
+
announcement.value = "";
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
announcement.value = now === "over" ? text.value.limitExceeded({
|
|
195
|
+
over: count.value - max,
|
|
196
|
+
max
|
|
197
|
+
}) : text.value.approachingLimit({
|
|
198
|
+
remaining: max - count.value,
|
|
199
|
+
max
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
const field = useFieldControl(() => ({
|
|
203
|
+
id: attrs.id,
|
|
204
|
+
describedBy: [attrs["aria-describedby"], showsCount.value ? countId : ""].filter((id) => typeof id === "string" && id.length > 0).join(" "),
|
|
205
|
+
name: props.name,
|
|
206
|
+
disabled: props.disabled,
|
|
207
|
+
readonly: props.readonly,
|
|
208
|
+
invalid: props.invalid,
|
|
209
|
+
required: props.required
|
|
210
|
+
}));
|
|
36
211
|
return (_ctx, _cache) => {
|
|
37
|
-
return openBlock(), createElementBlock("
|
|
38
|
-
"
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
212
|
+
return openBlock(), createElementBlock("div", _hoisted_1, [
|
|
213
|
+
createElementVNode("div", {
|
|
214
|
+
"data-disabled": unref(field).disabled || void 0,
|
|
215
|
+
"data-readonly": unref(field).readonly || void 0,
|
|
216
|
+
"data-invalid": unref(field).invalid || void 0,
|
|
217
|
+
class: normalizeClass(unref(cn)("group flex items-start gap-2 rounded-md border border-input bg-background text-foreground px-3 py-2 text-sm", "transition-[color,background-color,border-color,box-shadow] duration-fast ease-out", "focus-within:outline-2 focus-within:outline-offset-2 focus-within:outline-ring", !unref(field).invalid && "focus-within:shadow-halo", unref(field).readonly && "bg-subtle", unref(field).disabled && "cursor-not-allowed border-border bg-muted text-muted-foreground", "in-[fieldset:disabled]:cursor-not-allowed in-[fieldset:disabled]:bg-muted in-[fieldset:disabled]:text-muted-foreground", !unref(field).invalid && "in-[fieldset:disabled]:border-border", unref(field).invalid && "border-destructive focus-within:outline-destructive", unref(attrs).class))
|
|
218
|
+
}, [
|
|
219
|
+
_ctx.$slots.leading ? (openBlock(), createElementBlock("span", _hoisted_3, [renderSlot(_ctx.$slots, "leading")])) : createCommentVNode("", true),
|
|
220
|
+
createElementVNode("textarea", mergeProps({
|
|
221
|
+
...unref(textareaAttrs),
|
|
222
|
+
...unref(field).attrs
|
|
223
|
+
}, {
|
|
224
|
+
"aria-label": __props.ariaLabel,
|
|
225
|
+
"aria-labelledby": __props.ariaLabelledby,
|
|
226
|
+
value: currentValue.value,
|
|
227
|
+
placeholder: __props.placeholder,
|
|
228
|
+
disabled: unref(field).disabled,
|
|
229
|
+
readonly: unref(field).readonly,
|
|
230
|
+
rows: __props.rows,
|
|
231
|
+
class: unref(cn)("min-w-0 flex-1 bg-transparent outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed", __props.resize === "none" ? "resize-none" : "resize-y"),
|
|
232
|
+
onInput
|
|
233
|
+
}), null, 16, _hoisted_4),
|
|
234
|
+
_ctx.$slots.trailing ? (openBlock(), createElementBlock("span", _hoisted_5, [renderSlot(_ctx.$slots, "trailing")])) : createCommentVNode("", true)
|
|
235
|
+
], 10, _hoisted_2),
|
|
236
|
+
showsCount.value ? (openBlock(), createElementBlock("span", {
|
|
237
|
+
key: 0,
|
|
238
|
+
id: unref(countId),
|
|
239
|
+
"data-over-limit": band.value === "over" || void 0,
|
|
240
|
+
class: normalizeClass(unref(cn)("tabular mt-1 select-none self-end text-small", band.value === "under" && "text-muted-foreground", band.value === "near" && "text-warning", band.value === "over" && "text-destructive"))
|
|
241
|
+
}, toDisplayString(countText.value), 11, _hoisted_6)) : createCommentVNode("", true),
|
|
242
|
+
showsCount.value && __props.maxLength !== void 0 ? (openBlock(), createElementBlock("span", _hoisted_7, toDisplayString(announcement.value), 1)) : createCommentVNode("", true)
|
|
243
|
+
]);
|
|
48
244
|
};
|
|
49
245
|
}
|
|
50
246
|
});
|
|
51
247
|
//#endregion
|
|
52
|
-
export { Textarea_vue_vue_type_script_setup_true_lang_default as default };
|
|
248
|
+
export { TEXTAREA_LABELS, Textarea_vue_vue_type_script_setup_true_lang_default as default };
|
|
53
249
|
|
|
54
250
|
//# sourceMappingURL=Textarea.vue_vue_type_script_setup_true_lang.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Textarea.vue_vue_type_script_setup_true_lang.js","names":["$emit"],"sources":["../../../src/primitives/Textarea/Textarea.vue"],"sourcesContent":["<script lang=\"ts\">\nexport type TextareaResize = \"none\" | \"vertical\";\n</script>\n\n<script setup lang=\"ts\">\nimport { cn } from \"../../lib/cn\";\nimport { useSplitAttrs } from \"../../lib/attrs\";\n\n/**\n * Textarea — multi-line text entry. A native `<textarea>`, single node (no\n * wrapper — unlike TextField there are no `#leading`/`#trailing` adornments to\n * frame), so `class` and the rest of the fallthrough attrs both target the\n * same element; still routed through `useSplitAttrs()` for the same reason as\n * every other primitive — a caller's `class` needs a Tailwind-aware `cn()`\n * merge, not a raw `v-bind` clobbering it. The accessible name is a\n * first-class prop pair (`aria-label`/`aria-labelledby`, camelized by Vue)\n * bound onto the textarea explicitly, the same contract as TextField.\n */\nwithDefaults(\n defineProps<{\n /** The current value. Pair with `@update:modelValue` for `v-model`. */\n modelValue?: string;\n /** Text shown in the empty field. */\n placeholder?: string;\n /** Disables the field and blocks pointer and keyboard input. */\n disabled?: boolean;\n /** Error state: paints the destructive border/ring and sets aria-invalid. */\n invalid?: boolean;\n /** Initial height in text rows. */\n rows?: number;\n /** Whether a person can drag-resize the field; `none` locks it to `rows`. */\n resize?: TextareaResize;\n /** The accessible name, when no visible element already labels the field. */\n ariaLabel?: string;\n /** The id of the visible element that labels the field (e.g. a Field wrapper's label). */\n ariaLabelledby?: string;\n }>(),\n {\n disabled: false,\n invalid: false,\n rows: 3,\n resize: \"vertical\",\n },\n);\n\ndefineEmits<{ \"update:modelValue\": [value: string] }>();\n\ndefineOptions({ inheritAttrs: false });\nconst { attrs, rest: textareaAttrs } = useSplitAttrs();\n</script>\n\n<template>\n <textarea\n v-bind=\"textareaAttrs\"\n :aria-label=\"ariaLabel\"\n :aria-labelledby=\"ariaLabelledby\"\n :value=\"modelValue\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :rows=\"rows\"\n :aria-invalid=\"invalid || undefined\"\n :class=\"\n cn(\n 'rounded-md border border-input bg-background text-foreground px-3 py-2 text-sm',\n 'transition-[color,background-color,border-color,box-shadow] duration-fast ease-out',\n // Rim-lit at rest, the weave blooms on focus (Signature law).\n 'focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring',\n !invalid && 'focus-visible:shadow-halo',\n 'placeholder:text-muted-foreground',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n invalid && 'border-destructive focus-visible:outline-destructive',\n resize === 'none' ? 'resize-none' : 'resize-y',\n attrs.class as string,\n )\n \"\n @input=\"$emit('update:modelValue', ($event.target as HTMLTextAreaElement).value)\"\n />\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgDA,MAAM,EAAE,OAAO,MAAM,kBAAkB,cAAc;;GAInD,OAAA,UAAA,GAAA,mBAwBE,YAxBF,WACU,MAuBR,aAAA,GAvBqB;IACpB,cAAY,QAAA;IACZ,mBAAiB,QAAA;IACjB,OAAO,QAAA;IACP,aAAa,QAAA;IACb,UAAU,QAAA;IACV,MAAM,QAAA;IACN,gBAAc,QAAA,WAAW,KAAA;IACzB,OAAc,MAAA,EAAA,CAAE,CAAA,kFAAA,sFAAA,qFAAuW,CAAA,QAAA,WAAO,6BAAA,qCAAA,mDAAiJ,QAAA,WAAO,wDAAoE,QAAA,WAAM,SAAA,gBAAA,YAAkD,MAAA,KAAA,CAAK,CAAC,KAAA;IAcxpB,SAAK,OAAA,OAAA,OAAA,MAAA,WAAEA,KAAAA,MAAK,qBAAuB,OAAO,OAA+B,KAAK"}
|
|
1
|
+
{"version":3,"file":"Textarea.vue_vue_type_script_setup_true_lang.js","names":["$slots"],"sources":["../../../src/primitives/Textarea/Textarea.vue"],"sourcesContent":["<script lang=\"ts\">\nimport {\n COUNT_LABELS,\n warningWindow,\n type CountBand,\n type CountLabels,\n} from \"../../lib/count-labels\";\n\nexport type TextareaResize = \"none\" | \"vertical\";\n\n/**\n * Everything this control says out loud, and every word of it is Loom's own —\n * a bare `<textarea>` renders no English of anybody else's, so a dropped key\n * here falls back to nothing rather than to a stray untranslated string.\n *\n * These are TextField's five counter keys, by name and by argument shape, and\n * deliberately so: a host that has already worded a character counter should be\n * able to copy that bag across unchanged. They come from\n * `src/lib/count-labels.ts` rather than being declared a second time. They are\n * a slot of their own rather than a share of `textField`'s because that slot\n * also carries `reveal`, and handing a textarea's translator a password-toggle\n * key to fill in is asking a question the control cannot answer.\n */\nexport type TextareaLabels = CountLabels;\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 * rather than a transcription of it.\n */\nexport const TEXTAREA_LABELS: TextareaLabels = COUNT_LABELS;\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, ref, useId, watch } from \"vue\";\nimport { cn } from \"../../lib/cn\";\nimport { useSplitAttrs } from \"../../lib/attrs\";\nimport { useFieldControl } from \"../../lib/field-context\";\nimport { useLabels, type LabelOverrides } from \"../../lib/labels\";\n\n/**\n * Textarea — multi-line text entry, around a native `<textarea>`. The\n * accessible name is a first-class prop pair (`aria-label`/`aria-labelledby`,\n * camelized by Vue) bound onto the textarea explicitly, the same contract as\n * TextField.\n *\n * The border, focus ring and invalid state live on the wrapper so optional\n * `#leading`/`#trailing` adornments sit *inside* the field and share its focus\n * bloom, instead of every caller re-inventing an icon-inside-input layout.\n * The slot names and positions match TextField's, and the vertical alignment\n * differs — `items-start` for multi-line, where the text begins, versus\n * `items-center` for single-line — because a five-row box with a centered icon\n * mid-field reads as a mistake rather than a choice.\n *\n * Wrapping a rendered structure means the fallthrough `class` must land on the\n * wrapper (so a caller's `w-64`/`flex-1` sizes the whole field) while the rest\n * of the attrs (`id`, `name`, `data-testid`, `aria-describedby`) belong on the\n * real `<textarea>` — the split-attrs convention shared with TextField.\n *\n * That same wrapper is why the character counter is a prop here rather than a\n * `CountedField` beside this one. A counter rendered *below* the field would\n * have to move the fallthrough `class` off the box a caller sizes with it, and\n * a textarea has no free column to hang one in — the value fills the box and\n * scrolls, and the bottom-right corner belongs to the native resize grabber.\n * The counter sits below the border, where `resize` moves the box's bottom\n * edge and the counter travels with it rather than floating over the text.\n *\n * Inside a [Field](../Field/Field.vue) it wires itself through\n * `useFieldControl()` — the row's id, the id of its hint or error line, and\n * `required` / `invalid` / `disabled` / `readonly` / `name` — so\n * `<Field label=\"Bio\" hint=\"…\"><Textarea /></Field>` needs no attributes at the\n * call site. Every prop below still wins over the row when it is set, in both\n * directions, which is why the four booleans default to `undefined` rather\n * than `false`.\n *\n * `readonly` and `disabled` are different states, and they are told apart on\n * three channels rather than one. A read-only field is a value on show: the\n * subtle fill, the text at full strength, the input hairline, still a Tab stop\n * and still submitted. A disabled one is unavailable: the deeper neutral fill,\n * the muted text, and the hairline receding to the plain border — a difference\n * in shape as well as in colour, which is what survives a reader who cannot\n * resolve the two fills apart.\n */\nconst props = withDefaults(\n defineProps<{\n /** The current value. Pair with `@update:modelValue` for `v-model`. */\n modelValue?: string;\n /** Text shown in the empty field. */\n placeholder?: string;\n /** Disables the field and blocks pointer and keyboard input. Unset defers to a wrapping Field. */\n disabled?: boolean | undefined;\n /** Shows the value without allowing an edit, while staying focusable and still submitted. Unset defers to a wrapping Field. */\n readonly?: boolean | undefined;\n /** Error state: paints the destructive border/ring and sets aria-invalid. Unset defers to a wrapping Field's `error`. */\n invalid?: boolean | undefined;\n /** Marks the field mandatory to assistive tech (`aria-required`). Unset defers to a wrapping Field. */\n required?: boolean | undefined;\n /** The field name for a native form post or `FormData`. Unset defers to a wrapping Field. */\n name?: string;\n /** Initial height in text rows. */\n rows?: number;\n /** Whether a person can drag-resize the field; `none` locks it to `rows`. The counter sits below the box either way, so a drag never moves it onto the value. */\n resize?: TextareaResize;\n /** The accessible name, when no visible element already labels the field. */\n ariaLabel?: string;\n /** The id of the visible element that labels the field (e.g. a Field wrapper's label). */\n ariaLabelledby?: string;\n /**\n * The character limit the counter reports against, and the point past\n * which it reads as over-limit.\n *\n * Advisory, exactly as `required` is: it does **not** set the native\n * `maxlength`, which silently truncates a paste and tells the reader\n * nothing. Pass `maxlength` yourself as a plain attribute where you want\n * the browser to enforce it too.\n */\n maxLength?: number;\n /**\n * Forces the counter on or off. Left unset it follows `maxLength` — a\n * limit the reader is never shown is one they can only discover by\n * exceeding it — so set it `true` for a running total with no limit, and\n * `false` to hold a limit the field reports nowhere.\n */\n showCount?: boolean | undefined;\n /**\n * Names for everything this control says out loud, as any subset of\n * `TextareaLabels` — 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 a field counting something other\n * than characters, where \"80 words left\" is the true sentence.\n */\n labels?: LabelOverrides<TextareaLabels>;\n }>(),\n {\n // Not `false`, for any of the four — see TextField.vue, which carries the\n // full reasoning. `false` is a caller's decision that must beat the row;\n // absent is a caller saying nothing, and only `undefined` survives to mean\n // that past Vue's absent-Boolean-casts-to-false rule.\n disabled: undefined,\n readonly: undefined,\n invalid: undefined,\n required: undefined,\n rows: 3,\n resize: \"vertical\",\n // `undefined` for the same Boolean-cast reason, and here it is the whole\n // feature: `showCount ?? (maxLength !== undefined)` would be a dead branch\n // if an absent prop arrived as `false`.\n showCount: undefined,\n },\n);\n\nconst emit = defineEmits<{ \"update:modelValue\": [value: string] }>();\n\ndefineOptions({ inheritAttrs: false });\nconst { attrs, rest: textareaAttrs } = useSplitAttrs();\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(\"textarea\", TEXTAREA_LABELS, () => props.labels);\n\nconst countId = useId();\n\n/**\n * What is actually in the box, which is not always `modelValue` — TextField's\n * reasoning, and the same defect waiting on this side of it.\n *\n * Used without `v-model` this component is uncontrolled, so `modelValue` stays\n * `undefined` while the reader types and the counter still has to count. And\n * binding `:value=\"currentValue\"` rather than `:value=\"modelValue\"` is\n * load-bearing rather than cosmetic: Vue's `value` patch coerces\n * `null`/`undefined` to `\"\"`, so any re-render of an uncontrolled field wipes\n * it — a defect nothing had met only because nothing in this component\n * re-rendered on a keystroke until the counter did.\n */\nconst typed = ref(props.modelValue ?? \"\");\nconst currentValue = computed(() => props.modelValue ?? typed.value);\n\nfunction onInput(event: Event): void {\n const value = (event.target as HTMLTextAreaElement).value;\n typed.value = value;\n emit(\"update:modelValue\", value);\n}\n\n/**\n * Length in UTF-16 code units, which is what the platform's own `maxlength`\n * counts. `[...value].length` would count code points and disagree with the\n * browser on any astral character, so a caller who pairs this with a native\n * `maxlength` would watch the counter and the enforcement drift apart.\n */\nconst count = computed(() => currentValue.value.length);\nconst showsCount = computed(() => props.showCount ?? props.maxLength !== undefined);\n\nconst band = computed<CountBand>(() => {\n const max = props.maxLength;\n if (max === undefined) return \"under\";\n const remaining = max - count.value;\n if (remaining < 0) return \"over\";\n return remaining <= warningWindow(max) ? \"near\" : \"under\";\n});\n\nconst countText = computed(() => {\n const max = props.maxLength;\n if (max === undefined) return text.value.count({ count: count.value });\n const over = count.value - max;\n return over > 0\n ? text.value.countOverMax({ count: count.value, max, over })\n : text.value.countOfMax({ count: count.value, max });\n});\n\n/**\n * What the live region says, and it changes **only when the band changes** —\n * TextField's decision, taken once for the pair rather than re-litigated here.\n *\n * A region holding the counter itself would speak on every keystroke, burying\n * the field's own echo of the character just typed under a number nobody asked\n * for. What a reader needs is the two facts they cannot see coming — the limit\n * is close, and the limit is passed — so this fires once at each crossing and\n * goes quiet again on the way back down. The numbers are therefore true at the\n * moment they are spoken and not after; the visible counter carries the live\n * figure, and it is wired into `aria-describedby`, so the exact count is one\n * re-read away whenever the reader wants it rather than pushed at them.\n */\nconst announcement = ref(\"\");\nwatch(band, (now) => {\n const max = props.maxLength;\n if (max === undefined || now === \"under\") {\n announcement.value = \"\";\n return;\n }\n announcement.value =\n now === \"over\"\n ? text.value.limitExceeded({ over: count.value - max, max })\n : text.value.approachingLimit({ remaining: max - count.value, max });\n});\n\n// `id` and `aria-describedby` arrive as fallthrough attrs rather than props, so\n// they are handed in as this caller's own values: a caller who sets either\n// still beats the row, and the row's description is merged into theirs. The\n// counter joins that list rather than replacing anything — it reads after the\n// caller's own description and before the row's message, which is the same\n// most-specific-first order `useFieldControl` applies one layer out.\n//\n// `field.attrs` then spreads **after** `textareaAttrs`, and that position is\n// the contract — see TextField.vue, which carries the full reasoning. The\n// `:aria-invalid` binding that used to sit below went with it: an individual\n// attribute written after a `v-bind` wins, so keeping one would overwrite the\n// resolved value with the raw prop.\nconst field = useFieldControl(() => ({\n id: attrs.id as string | undefined,\n describedBy: [attrs[\"aria-describedby\"] as string | undefined, showsCount.value ? countId : \"\"]\n .filter((id): id is string => typeof id === \"string\" && id.length > 0)\n .join(\" \"),\n name: props.name,\n disabled: props.disabled,\n readonly: props.readonly,\n invalid: props.invalid,\n required: props.required,\n}));\n</script>\n\n<template>\n <!-- Layout, and nothing else: no fallthrough attribute lands here and nothing\n is painted on it. `inline-flex` is what makes it shrink-wrap the field\n frame — a block wrapper would be as wide as the column, and the counter\n would right-align to that column rather than to the field's own edge. -->\n <div class=\"inline-flex max-w-full flex-col align-top\">\n <!-- The field frame: border, focus, state. Like TextField, the border lives\n here so optional #leading/#trailing adornments sit inside the field and\n share its focus bloom, instead of every caller re-inventing an\n icon-inside-input layout. -->\n <div\n :data-disabled=\"field.disabled || undefined\"\n :data-readonly=\"field.readonly || undefined\"\n :data-invalid=\"field.invalid || undefined\"\n :class=\"\n cn(\n 'group flex items-start gap-2 rounded-md border border-input bg-background text-foreground px-3 py-2 text-sm',\n 'transition-[color,background-color,border-color,box-shadow] duration-fast ease-out',\n // Rim-lit at rest, the weave blooms on focus (Signature law): the field\n // catches light instead of casting a shadow, and focus draws it tight.\n 'focus-within:outline-2 focus-within:outline-offset-2 focus-within:outline-ring',\n !field.invalid && 'focus-within:shadow-halo',\n // The three resting appearances, and each is three changes rather than\n // one. Read-only and disabled used to share `bg-muted` and part only on\n // the text colour, which is a distinction carried by hue alone — the\n // one thing a reader with a colour deficiency, or a low-quality\n // display, or forced-colors, does not get. The fill separates them and\n // the border weight separates them again, so the progression\n // available → on show → unavailable is legible on three channels.\n //\n // Read-only is a value **on show**: the fill lifts off `background` to\n // `subtle` so the row reads as settled rather than editable, and the\n // text stays full strength — 13.46:1 over that fill — because being\n // read is the entire purpose of the state. The border does not move,\n // because nothing about the control's reach has: it is still a Tab stop\n // and still submitted. The native `readonly` attribute below carries\n // the same fact to assistive tech, so nothing here rests on colour.\n field.readonly && 'bg-subtle',\n // Disabled is **unavailable**: the fill drains one step further to\n // `muted`, the text follows it down to `muted-foreground` (4.68:1 over\n // it, still AA), and the rim slackens from `input` to the lighter\n // `border`.\n //\n // Drained rather than faded, and `opacity` is never the mechanism. The\n // element a dim would sit on is the box, and the box is wrapped around\n // the one thing a reader still needs: measured on the built site,\n // `opacity-50` put a disabled field's value at 3.08:1 and its\n // placeholder — already the muted colour before the fade — at 2.07:1.\n // The text colour is declared here rather than on the `<textarea>` because\n // the textarea sets no resting colour of its own and inherits this one,\n // which also carries it to the adornments in the same box.\n field.disabled && 'cursor-not-allowed border-border bg-muted text-muted-foreground',\n // The same appearance, reached from the other direction: a\n // `<fieldset disabled>` above this field disables the `<textarea>` inside\n // it natively and never touches `field.disabled`, so the rule above\n // cannot fire and the field rendered byte-identical to an editable one.\n //\n // `in-[fieldset:disabled]:` is a *read* of the attribute that did the\n // disabling, so the fill and the native inertness cannot disagree — the\n // fieldset element is still the only place the fact is written. It is\n // preferred to `has-[:disabled]:` (a wrapper reading its own contents)\n // because that proxy is wrong wherever a control holds a part that\n // disables itself.\n 'in-[fieldset:disabled]:cursor-not-allowed in-[fieldset:disabled]:bg-muted in-[fieldset:disabled]:text-muted-foreground',\n // Gated where the two rules below are ordered, and for the same reason.\n // Tailwind emits the ancestor half of `in-*` inside `:where()`, so this\n // carries no more specificity than `border-destructive` and would win\n // on emission order alone — an unavailable field that is also in error\n // would quietly lose its destructive rim.\n !field.invalid && 'in-[fieldset:disabled]:border-border',\n // Last of the three rules that name a border colour, and the order is\n // load-bearing: `cn()` resolves a border colour by whichever class it\n // saw last, so a field that is both in error and unavailable would lose\n // its destructive rim to the disabled one if this sat above it.\n field.invalid && 'border-destructive focus-within:outline-destructive',\n attrs.class as string,\n )\n \"\n >\n <span\n v-if=\"$slots.leading\"\n class=\"inline-flex shrink-0 text-muted-foreground transition-colors duration-fast ease-out group-focus-within:text-foreground\"\n >\n <slot name=\"leading\" />\n </span>\n <textarea\n v-bind=\"{ ...textareaAttrs, ...field.attrs }\"\n :aria-label=\"ariaLabel\"\n :aria-labelledby=\"ariaLabelledby\"\n :value=\"currentValue\"\n :placeholder=\"placeholder\"\n :disabled=\"field.disabled\"\n :readonly=\"field.readonly\"\n :rows=\"rows\"\n :class=\"\n cn(\n 'min-w-0 flex-1 bg-transparent outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed',\n resize === 'none' ? 'resize-none' : 'resize-y',\n )\n \"\n @input=\"onInput\"\n />\n <span\n v-if=\"$slots.trailing\"\n class=\"inline-flex shrink-0 items-center gap-1 text-muted-foreground transition-colors duration-fast ease-out group-focus-within:text-foreground\"\n >\n <slot name=\"trailing\" />\n </span>\n </div>\n <!-- Below the box, never inside it. A textarea's value fills its box and\n scrolls, so there is no free column to hang a readout in, and the\n bottom-right corner belongs to the native resize grabber — an inset\n counter would sit on top of the one affordance that says the field can\n be dragged. Here it travels with the bottom edge instead, so `resize`\n moves it rather than moving the box out from under it.\n\n `tabular` because the number changes under itself on every keystroke,\n and proportional digits would shuffle the whole readout sideways as\n they do. -->\n <span\n v-if=\"showsCount\"\n :id=\"countId\"\n :data-over-limit=\"band === 'over' || undefined\"\n :class=\"\n cn(\n 'tabular mt-1 select-none self-end text-small',\n band === 'under' && 'text-muted-foreground',\n // Colour, and never only colour: `countOverMax` says the limit is\n // passed in words as well, and `approachingLimit` announces the near\n // band once. The digits themselves are the third reading — 21/20 is\n // over the limit whatever it is painted.\n band === 'near' && 'text-warning',\n band === 'over' && 'text-destructive',\n )\n \"\n >\n {{ countText }}\n </span>\n <!-- In the DOM from the first render, empty. A live region mounted at the\n same moment as its text is a region assistive tech was not yet\n watching, so the first warning — the one that matters most — is the one\n it announces least reliably. -->\n <span v-if=\"showsCount && maxLength !== undefined\" role=\"status\" class=\"sr-only\">\n {{ announcement }}\n </span>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,IAAa,kBAAkC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqD/C,MAAM,QAAQ;EAsEd,MAAM,OAAO;EAGb,MAAM,EAAE,OAAO,MAAM,kBAAkB,cAAc;EAKrD,MAAM,OAAO,UAAU,YAAY,uBAAuB,MAAM,MAAM;EAEtE,MAAM,UAAU,MAAM;;;;;;;;;;;;;EActB,MAAM,QAAQ,IAAI,MAAM,cAAc,EAAE;EACxC,MAAM,eAAe,eAAe,MAAM,cAAc,MAAM,KAAK;EAEnE,SAAS,QAAQ,OAAoB;GACnC,MAAM,QAAS,MAAM,OAA+B;GACpD,MAAM,QAAQ;GACd,KAAK,qBAAqB,KAAK;EACjC;;;;;;;EAQA,MAAM,QAAQ,eAAe,aAAa,MAAM,MAAM;EACtD,MAAM,aAAa,eAAe,MAAM,aAAa,MAAM,cAAc,KAAA,CAAS;EAElF,MAAM,OAAO,eAA0B;GACrC,MAAM,MAAM,MAAM;GAClB,IAAI,QAAQ,KAAA,GAAW,OAAO;GAC9B,MAAM,YAAY,MAAM,MAAM;GAC9B,IAAI,YAAY,GAAG,OAAO;GAC1B,OAAO,aAAa,cAAc,GAAG,IAAI,SAAS;EACpD,CAAC;EAED,MAAM,YAAY,eAAe;GAC/B,MAAM,MAAM,MAAM;GAClB,IAAI,QAAQ,KAAA,GAAW,OAAO,KAAK,MAAM,MAAM,EAAE,OAAO,MAAM,MAAM,CAAC;GACrE,MAAM,OAAO,MAAM,QAAQ;GAC3B,OAAO,OAAO,IACV,KAAK,MAAM,aAAa;IAAE,OAAO,MAAM;IAAO;IAAK;GAAK,CAAC,IACzD,KAAK,MAAM,WAAW;IAAE,OAAO,MAAM;IAAO;GAAI,CAAC;EACvD,CAAC;;;;;;;;;;;;;;EAeD,MAAM,eAAe,IAAI,EAAE;EAC3B,MAAM,OAAO,QAAQ;GACnB,MAAM,MAAM,MAAM;GAClB,IAAI,QAAQ,KAAA,KAAa,QAAQ,SAAS;IACxC,aAAa,QAAQ;IACrB;GACF;GACA,aAAa,QACX,QAAQ,SACJ,KAAK,MAAM,cAAc;IAAE,MAAM,MAAM,QAAQ;IAAK;GAAI,CAAC,IACzD,KAAK,MAAM,iBAAiB;IAAE,WAAW,MAAM,MAAM;IAAO;GAAI,CAAC;EACzE,CAAC;EAcD,MAAM,QAAQ,uBAAuB;GACnC,IAAI,MAAM;GACV,aAAa,CAAC,MAAM,qBAA2C,WAAW,QAAQ,UAAU,EAAE,CAAA,CAC3F,QAAQ,OAAqB,OAAO,OAAO,YAAY,GAAG,SAAS,CAAC,CAAA,CACpE,KAAK,GAAG;GACX,MAAM,MAAM;GACZ,UAAU,MAAM;GAChB,UAAU,MAAM;GAChB,SAAS,MAAM;GACf,UAAU,MAAM;EAClB,EAAE;;GAQA,OAAA,UAAA,GAAA,mBA4IM,OA5IN,YA4IM;IAvIJ,mBAkGM,OAAA;KAjGH,iBAAe,MAAA,KAAA,CAAK,CAAC,YAAY,KAAA;KACjC,iBAAe,MAAA,KAAA,CAAK,CAAC,YAAY,KAAA;KACjC,gBAAc,MAAA,KAAA,CAAK,CAAC,WAAW,KAAA;KAC/B,OAAK,eAAW,MAAA,EAAA,CAAE,CAAA,+GAAA,sFAAA,kFAAue,CAAA,MAAA,KAAA,CAAK,CAAC,WAAO,4BAAipC,MAAA,KAAA,CAAK,CAAC,YAAQ,aAAs6B,MAAA,KAAA,CAAK,CAAC,YAAQ,mEAAA,0HAAi1C,CAAA,MAAA,KAAA,CAAK,CAAC,WAAO,wCAAsX,MAAA,KAAA,CAAK,CAAC,WAAO,uDAAqE,MAAA,KAAA,CAAK,CAAC,KAAA,CAAA;;KAkE93IA,KAAAA,OAAO,WADf,UAAA,GAAA,mBAKO,QALP,YAKO,CADL,WAAuB,KAAA,QAAA,SAAA,CAAA,CAAA,KAAA,mBAAA,IAAA,IAAA;KAEzB,mBAgBE,YAhBF,WAgBE;MAAA,GAfa,MAAA,aAAA;MAAa,GAAK,MAAA,KAAA,CAAK,CAAC;KAAK,GAAA;MACzC,cAAY,QAAA;MACZ,mBAAiB,QAAA;MACjB,OAAO,aAAA;MACP,aAAa,QAAA;MACb,UAAU,MAAA,KAAA,CAAK,CAAC;MAChB,UAAU,MAAA,KAAA,CAAK,CAAC;MAChB,MAAM,QAAA;MACN,OAAkB,MAAA,EAAA,CAAE,CAAA,4GAAsI,QAAA,WAAM,SAAA,gBAAA,UAAA;MAMzJ;;KAGFA,KAAAA,OAAO,YADf,UAAA,GAAA,mBAKO,QALP,YAKO,CADL,WAAwB,KAAA,QAAA,UAAA,CAAA,CAAA,KAAA,mBAAA,IAAA,IAAA;;IAcpB,WAAA,SADR,UAAA,GAAA,mBAkBO,QAAA;;KAhBJ,IAAI,MAAA,OAAA;KACJ,mBAAiB,KAAA,UAAI,UAAe,KAAA;KACpC,OAAK,eAAW,MAAA,EAAA,CAAE,CAAA,gDAAsE,KAAA,UAAI,WAAA,yBAAmV,KAAA,UAAI,UAAA,gBAAyC,KAAA,UAAI,UAAA,kBAAA,CAAA;IAa9d,GAAA,gBAAA,UAAA,KAAS,GAAA,IAAA,UAAA,KAAA,mBAAA,IAAA,IAAA;IAMF,WAAA,SAAc,QAAA,cAAc,KAAA,KAAxC,UAAA,GAAA,mBAEO,QAFP,YAEO,gBADF,aAAA,KAAY,GAAA,CAAA,KAAA,mBAAA,IAAA,IAAA"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import TimePicker_vue_vue_type_script_setup_true_lang_default from "./TimePicker.vue_vue_type_script_setup_true_lang.js";
|
|
2
|
+
//#region src/primitives/TimePicker/TimePicker.vue
|
|
3
|
+
var TimePicker_default = TimePicker_vue_vue_type_script_setup_true_lang_default;
|
|
4
|
+
//#endregion
|
|
5
|
+
export { TimePicker_default as default };
|
|
6
|
+
|
|
7
|
+
//# sourceMappingURL=TimePicker.js.map
|