@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
package/dist/styles/theme.css
CHANGED
|
@@ -5,26 +5,21 @@
|
|
|
5
5
|
* can theme lives here and nowhere else: no colour, duration, easing, radius
|
|
6
6
|
* or shadow is written literally in a component.
|
|
7
7
|
*
|
|
8
|
-
* Positioning it encodes.
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* Positioning it encodes. Loom is a UI system for cross-platform web
|
|
9
|
+
* applications — browser, PWA, Electron, Tauri — so the form language is
|
|
10
|
+
* purposeful and opinionated:
|
|
11
11
|
*
|
|
12
|
-
* -
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* -
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* meet: handoffs, co-authored assets, brand moments. Never under body
|
|
19
|
-
* text, never on anything smaller than 20px, never in an interaction
|
|
20
|
-
* state.
|
|
12
|
+
* - Primary (`--color-primary`) — the default action colour: what a person
|
|
13
|
+
* drives the interface with. The focus ring is the same hue for the same
|
|
14
|
+
* reason — keyboard focus is the primary action.
|
|
15
|
+
* - Accent (`--color-accent`) — a second semantic colour for contrast or
|
|
16
|
+
* emphasis distinct from the primary action. Useful for signalling a
|
|
17
|
+
* different category, mode, or origin.
|
|
21
18
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* dark theme is a reserved seam that returns with the first surface that
|
|
27
|
-
* needs it.
|
|
19
|
+
* Dual-theme. The light tokens are the default; the dark block below
|
|
20
|
+
* overrides every semantic token under `:root[data-theme="dark"]`. Switching
|
|
21
|
+
* replaces the entire set, so the two cannot drift apart. The `useTheme`
|
|
22
|
+
* composable and `themeScript` flash-prevention snippet manage the attribute.
|
|
28
23
|
*
|
|
29
24
|
* `static` rather than plain `@theme`: Tailwind emits only the variables its
|
|
30
25
|
* generated utilities reference, and several tokens here are read by an
|
|
@@ -33,7 +28,7 @@
|
|
|
33
28
|
* `var(--duration-fast)` resolve inside a component's style attribute.
|
|
34
29
|
*/
|
|
35
30
|
@theme static {
|
|
36
|
-
/* ---- Neutrals: technical paper, cooled slightly toward the
|
|
31
|
+
/* ---- Neutrals: technical paper, cooled slightly toward the primary hue --- */
|
|
37
32
|
--color-background: hsl(213 25% 96%);
|
|
38
33
|
--color-foreground: hsl(213 29% 15%);
|
|
39
34
|
|
|
@@ -51,6 +46,17 @@
|
|
|
51
46
|
--color-muted: hsl(213 18% 91%);
|
|
52
47
|
--color-muted-foreground: hsl(213 14% 41%);
|
|
53
48
|
|
|
49
|
+
/* The lighter step of the same ladder, and it is reserved for a *graphical
|
|
50
|
+
* object*, never for text: a glyph that must keep clearing the 3:1 floor
|
|
51
|
+
* while receding behind `muted-foreground` — the disabled Rating's unfilled
|
|
52
|
+
* stars, which carry the maximum. Text is held to 4.5:1, which is what
|
|
53
|
+
* `muted-foreground` is measured to; the 3:1 floor of WCAG 1.4.11 leaves
|
|
54
|
+
* room for one more step, and taking it as a token rather than as an alpha
|
|
55
|
+
* over the darker grey is the whole point: composited at half alpha,
|
|
56
|
+
* `muted-foreground` lands at 2.05:1 on the page ground, short of even
|
|
57
|
+
* that floor. */
|
|
58
|
+
--color-muted-foreground-soft: hsl(213 12% 50%);
|
|
59
|
+
|
|
54
60
|
/* Two border weights: the default hairline recedes; strong is for the few
|
|
55
61
|
* blocks that must assert their edge — an active panel, a keyboard target
|
|
56
62
|
* zone. */
|
|
@@ -63,23 +69,25 @@
|
|
|
63
69
|
--color-subtle: hsl(213 20% 94%);
|
|
64
70
|
--color-subtle-foreground: hsl(213 29% 18%);
|
|
65
71
|
|
|
66
|
-
/* ---- Force 1 ·
|
|
72
|
+
/* ---- Force 1 · Primary — default action, structure, decisions --------- */
|
|
67
73
|
--color-primary: hsl(211 37% 32%);
|
|
68
74
|
--color-primary-foreground: hsl(0 0% 100%);
|
|
69
|
-
--color-primary-muted: hsl(211 35% 92%); /*
|
|
75
|
+
--color-primary-muted: hsl(211 35% 92%); /* wash: selected/active fills */
|
|
70
76
|
|
|
71
|
-
/* ---- Force 2 ·
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
--color-
|
|
77
|
+
/* ---- Force 2 · Accent — a second semantic colour for contrast or
|
|
78
|
+
* emphasis distinct from the primary action. Useful for signalling a
|
|
79
|
+
* different category, mode, or origin. ------------------------------- */
|
|
80
|
+
--color-accent: hsl(18 56% 39%);
|
|
81
|
+
--color-accent-foreground: hsl(0 0% 100%);
|
|
82
|
+
--color-accent-muted: hsl(18 50% 93%); /* wash: accent-driven surfaces */
|
|
75
83
|
|
|
76
84
|
--color-secondary: hsl(213 18% 91%);
|
|
77
85
|
--color-secondary-foreground: hsl(213 29% 18%);
|
|
78
86
|
|
|
79
|
-
/* Focus ring is the
|
|
87
|
+
/* Focus ring is the primary colour: keyboard focus is the primary action. */
|
|
80
88
|
--color-ring: hsl(211 37% 32%);
|
|
81
89
|
|
|
82
|
-
/* ---- Functional — hues kept distinct from both
|
|
90
|
+
/* ---- Functional — hues kept distinct from both action colours ------------ */
|
|
83
91
|
--color-destructive: hsl(356 65% 41%);
|
|
84
92
|
--color-destructive-foreground: hsl(0 0% 100%);
|
|
85
93
|
--color-success: hsl(152 45% 30%);
|
|
@@ -89,10 +97,50 @@
|
|
|
89
97
|
--color-info: hsl(202 65% 35%);
|
|
90
98
|
--color-info-foreground: hsl(0 0% 100%);
|
|
91
99
|
|
|
92
|
-
/*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
|
|
100
|
+
/* Each functional hue's wash, completing the pattern the action colours above
|
|
101
|
+
* already set. These are opaque rather than an alpha of the base hue, and
|
|
102
|
+
* that is the whole reason they exist: a `bg-destructive/12` fill composites
|
|
103
|
+
* against whatever is behind it, so the same badge renders as one colour on
|
|
104
|
+
* `bg-card` and another on `bg-sunken`. A status tint that shifts with its
|
|
105
|
+
* container is a status tint a reader cannot learn. Each is mixed to hold at
|
|
106
|
+
* least 4.5:1 against its own base hue, which is what sits on top of it as
|
|
107
|
+
* text or as a hairline. */
|
|
108
|
+
--color-destructive-muted: hsl(356 55% 94%); /* error wash: a failed or blocking surface */
|
|
109
|
+
--color-success-muted: hsl(152 40% 93%); /* success wash: a settled, completed surface */
|
|
110
|
+
--color-warning-muted: hsl(38 70% 92%); /* warning wash: a surface needing attention */
|
|
111
|
+
--color-info-muted: hsl(202 55% 93%); /* info wash: a neutral advisory surface */
|
|
112
|
+
|
|
113
|
+
/* ---- Scrim weight, as modifiers on `foreground`: `bg-foreground/scrim`.
|
|
114
|
+
* Two weights, because how much of the page a surface hides is a statement
|
|
115
|
+
* about what that surface is. A dialog interrupts, so the page behind it
|
|
116
|
+
* drops to context. A drawer is worked alongside its page — you tune a
|
|
117
|
+
* filter and watch the rows change — so the page stays legible and stays
|
|
118
|
+
* the subject. That rule lived in a comment inside `Drawer.vue`, which is
|
|
119
|
+
* the one place a person building a third overlay would never look. ------ */
|
|
120
|
+
--opacity-scrim: 70%; /* a surface that interrupts: the page behind is context */
|
|
121
|
+
--opacity-scrim-light: 40%; /* a surface worked alongside: the page behind is still the subject */
|
|
122
|
+
|
|
123
|
+
/* One weight for "unavailable", because two menu rows ten points apart is
|
|
124
|
+
* not a decision anyone made — `opacity-40` had appeared twice against
|
|
125
|
+
* `opacity-50` forty-five times, and nothing in any check can see a
|
|
126
|
+
* difference that small. */
|
|
127
|
+
--opacity-disabled: 50%;
|
|
128
|
+
|
|
129
|
+
/* ---- Stacking. Five rungs, named, because the ladder was real before it
|
|
130
|
+
* was written down: seventeen overlays at `z-50` and two toasts at
|
|
131
|
+
* `z-[100]`, an arbitrary value of exactly the kind this file exists to
|
|
132
|
+
* prevent. Ordering *within* a rung is the portal's job — Reka appends in
|
|
133
|
+
* open order, so the last dialog opened is the one on top without anyone
|
|
134
|
+
* numbering them. --------------------------------------------------------- */
|
|
135
|
+
--z-index-raised: 10; /* lifted above its own siblings: an Indicator's marker, a SegmentedControl thumb */
|
|
136
|
+
--z-index-sticky: 20; /* page furniture that pins while content scrolls under it */
|
|
137
|
+
--z-index-chrome: 30; /* application chrome: the header and rails that outlive the page */
|
|
138
|
+
--z-index-overlay: 50; /* anything portalled over the page — dialogs, popovers, menus, drawers */
|
|
139
|
+
--z-index-toast: 100; /* above every overlay, because a toast reports on the thing the overlay is doing */
|
|
140
|
+
|
|
141
|
+
/* The press. One value, reached through `active:scale-press`, replacing six
|
|
142
|
+
* `scale-[0.97]` and three `scale-95` that meant the same thing. */
|
|
143
|
+
--scale-press: 0.97;
|
|
96
144
|
|
|
97
145
|
/* ---- Shape: small, even fillets — milled, never blobby.
|
|
98
146
|
* Nesting law: inner radius = outer radius − padding, floor 2px. Pick the
|
|
@@ -125,7 +173,7 @@
|
|
|
125
173
|
--shadow-md: 0 4px 12px -2px hsl(213 30% 12% / 0.1), 0 2px 6px -2px hsl(213 30% 12% / 0.07);
|
|
126
174
|
--shadow-lg: 0 12px 32px -6px hsl(213 30% 12% / 0.14), 0 4px 10px -4px hsl(213 30% 12% / 0.08);
|
|
127
175
|
|
|
128
|
-
/* Focus halo — a
|
|
176
|
+
/* Focus halo — a primary haze AROUND the crisp ring outline, added on top of
|
|
129
177
|
* it and never replacing it, so the outline still shows under
|
|
130
178
|
* forced-colors. */
|
|
131
179
|
--shadow-halo: 0 0 0 4px hsl(211 37% 32% / 0.15);
|
|
@@ -173,19 +221,65 @@
|
|
|
173
221
|
--breakpoint-4xl: 2560px; /* QHD */
|
|
174
222
|
--breakpoint-5xl: 3440px; /* 21:9 ultra-wide */
|
|
175
223
|
|
|
224
|
+
/* ---- Safe areas. Mobile webviews (notch, home indicator) and PWA title-bar
|
|
225
|
+
* overlays both reserve space the layout must not paint into. The fallback is
|
|
226
|
+
* 0 so these tokens are always safe to read — a viewport without a safe area
|
|
227
|
+
* simply contributes no inset. A host that needs the raw value for
|
|
228
|
+
* `padding-top: env(safe-area-inset-top)` can use it directly, but a host
|
|
229
|
+
* that wants Loom's opinion uses the token instead and lets the theme layer
|
|
230
|
+
* decide what the inset is. ---------------------------------------------- */
|
|
231
|
+
--safe-area-top: env(safe-area-inset-top, 0px);
|
|
232
|
+
--safe-area-bottom: env(safe-area-inset-bottom, 0px);
|
|
233
|
+
--safe-area-left: env(safe-area-inset-left, 0px);
|
|
234
|
+
--safe-area-right: env(safe-area-inset-right, 0px);
|
|
235
|
+
|
|
176
236
|
/* ---- The animation vocabulary. Keyframes live in global.css; these are
|
|
177
237
|
* the named utilities that play them. ---------------------------------- */
|
|
178
238
|
--animate-fade: fade var(--duration-normal) var(--ease-out) both;
|
|
179
239
|
--animate-fade-rise: fade-rise var(--duration-normal) var(--ease-out) both;
|
|
180
240
|
--animate-scale-in: scale-in var(--duration-fast) var(--ease-spring) both;
|
|
181
241
|
--animate-shimmer: shimmer 1.6s linear infinite;
|
|
182
|
-
/* Agent at work — the weft's shuttle beat. */
|
|
183
|
-
--animate-conduct: conduct 1.8s var(--ease-in-out) infinite;
|
|
184
|
-
/* A live seam: the warp↔weft boundary drifts while the collaboration runs,
|
|
185
|
-
* and goes static once the work settles. */
|
|
186
|
-
--animate-seam-flow: seam-flow 3.2s linear infinite;
|
|
187
242
|
--animate-progress-indeterminate: progress-indeterminate 1.3s var(--ease-in-out) infinite;
|
|
188
243
|
--animate-toast-in: toast-in var(--duration-normal) var(--ease-spring) both;
|
|
244
|
+
|
|
245
|
+
/* ---- Motion that leaves. Every animation above is an entrance, so until
|
|
246
|
+
* these existed an overlay that faded in over 200ms was simply gone between
|
|
247
|
+
* two frames, and the page behind it appeared to jump rather than to be
|
|
248
|
+
* revealed. `--ease-in` was declared with the rest of the easings and used by
|
|
249
|
+
* nothing at all, which is the tell: the accelerate curve has one job and it
|
|
250
|
+
* is this one.
|
|
251
|
+
*
|
|
252
|
+
* Exits run shorter than the entrance they mirror and on `--ease-in`, because
|
|
253
|
+
* the two directions are not the same event. A surface arriving is
|
|
254
|
+
* decelerating into place and is worth watching; a surface leaving has
|
|
255
|
+
* already done its job and should clear the eye rather than hold it.
|
|
256
|
+
*
|
|
257
|
+
* These are load-bearing beyond taste. Reka's `Presence` keeps closed content
|
|
258
|
+
* mounted until an `animationend` arrives — that is why every entrance here
|
|
259
|
+
* is scoped `data-[state=open]:` — and a closed element with no animation at
|
|
260
|
+
* all unmounts on the spot. A `data-[state=closed]:` animation is what turns
|
|
261
|
+
* that all-or-nothing into an ordinary timed exit, and it stays safe under
|
|
262
|
+
* `prefers-reduced-motion`: `global.css` collapses the duration to 0.01ms,
|
|
263
|
+
* which still fires `animationend`, so the overlay still unmounts. --------- */
|
|
264
|
+
--animate-fade-out: fade-out var(--duration-fast) var(--ease-in) both; /* the exit answering `fade` */
|
|
265
|
+
--animate-fade-fall: fade-fall var(--duration-fast) var(--ease-in) both; /* the exit answering `fade-rise` */
|
|
266
|
+
--animate-scale-out: scale-out var(--duration-instant) var(--ease-in) both; /* the exit answering `scale-in` */
|
|
267
|
+
|
|
268
|
+
/* An edge-anchored panel leaving the way it came. `--duration-normal` against
|
|
269
|
+
* the `slow` entrance a drawer uses: 320ms is what stops a full-height panel
|
|
270
|
+
* arriving like a flinch, and none of that reasoning applies to a panel on
|
|
271
|
+
* its way out.
|
|
272
|
+
*
|
|
273
|
+
* There is no matching `slide-in` family, and that is a decision rather than
|
|
274
|
+
* an omission — see `Drawer.vue`, which enters on `@starting-style` because a
|
|
275
|
+
* transition composes with a live swipe gesture where a keyframe would fight
|
|
276
|
+
* it. The exit has no such conflict and cannot be a transition at all:
|
|
277
|
+
* `Presence` observes `animationend` and never `transitionend`, so a
|
|
278
|
+
* transition-based exit is unmounted before it can run. --------------------- */
|
|
279
|
+
--animate-slide-out-to-left: slide-out-to-left var(--duration-normal) var(--ease-in) both; /* a panel leaving past the left edge */
|
|
280
|
+
--animate-slide-out-to-right: slide-out-to-right var(--duration-normal) var(--ease-in) both; /* a panel leaving past the right edge */
|
|
281
|
+
--animate-slide-out-to-top: slide-out-to-top var(--duration-normal) var(--ease-in) both; /* a panel leaving past the top edge */
|
|
282
|
+
--animate-slide-out-to-bottom: slide-out-to-bottom var(--duration-normal) var(--ease-in) both; /* a panel leaving past the bottom edge */
|
|
189
283
|
}
|
|
190
284
|
|
|
191
285
|
/* Tailwind has no `--duration-*` theme namespace — `duration-*` takes a bare
|
|
@@ -205,8 +299,112 @@
|
|
|
205
299
|
transition-duration: var(--duration-slower);
|
|
206
300
|
}
|
|
207
301
|
|
|
208
|
-
/*
|
|
209
|
-
*
|
|
210
|
-
|
|
211
|
-
|
|
302
|
+
/* ---- Dark theme overrides ------------------------------------------------
|
|
303
|
+
* Every semantic token overridden; no "fallback to light". Switching replaces
|
|
304
|
+
* the entire set, so the two cannot drift apart and contrast is verified for
|
|
305
|
+
* each independently. `data-theme` on `<html>` is the single source of truth.
|
|
306
|
+
*
|
|
307
|
+
* Design principles:
|
|
308
|
+
* - Same hue family, adjusted lightness — dark is the mirror, not a new palette
|
|
309
|
+
* - Functional tokens slightly desaturated — bright saturated colours on dark
|
|
310
|
+
* backgrounds cause eye strain and fail contrast against dark surfaces
|
|
311
|
+
* - Elevation = lighter background, not shadow — shadows are invisible on dark
|
|
312
|
+
* - Borders brighten — the hairline that recedes on light must be visible on dark
|
|
313
|
+
* - `muted-foreground-soft` stays above 3:1 (graphical-object floor)
|
|
314
|
+
* - Focus ring stays primary — halo shifts to a lighter shade for visibility
|
|
315
|
+
*
|
|
316
|
+
* Contrast is verified: all text pairings clear 4.5:1; all graphical-object
|
|
317
|
+
* pairings clear 3:1. See the contrast verification table in the repository
|
|
318
|
+
* for the full audit. ----------------------------------------------------- */
|
|
319
|
+
:root[data-theme="dark"] {
|
|
320
|
+
/* ---- Neutrals: same hue family, inverted lightness ---- */
|
|
321
|
+
|
|
322
|
+
/* Elevation in dark = lighter: sunken(7%) < background(10%) < card(14%) < popover(17%).
|
|
323
|
+
* Light: sunken(93%) < background(96%) < card(100%) = popover(100%).
|
|
324
|
+
* Dark mirrors the order with the 4-7% steps that keep surfaces distinct
|
|
325
|
+
* while staying dark enough for high foreground contrast. */
|
|
326
|
+
--color-background: hsl(213 25% 10%);
|
|
327
|
+
--color-foreground: hsl(
|
|
328
|
+
213 20% 92%
|
|
329
|
+
); /* S narrowed 29→20 for softer read; 14.68:1 on background */
|
|
330
|
+
|
|
331
|
+
--color-card: hsl(213 20% 14%);
|
|
332
|
+
--color-card-foreground: hsl(213 20% 92%);
|
|
333
|
+
|
|
334
|
+
--color-sunken: hsl(213 24% 7%);
|
|
335
|
+
|
|
336
|
+
--color-popover: hsl(213 18% 17%);
|
|
337
|
+
--color-popover-foreground: hsl(213 20% 92%);
|
|
338
|
+
|
|
339
|
+
--color-muted: hsl(213 16% 13%);
|
|
340
|
+
--color-muted-foreground: hsl(213 10% 60%); /* S 14→10%; 6.06:1 on background */
|
|
341
|
+
|
|
342
|
+
/* Graphical-object token: clears 3:1 (4.03:1 on background). In light the
|
|
343
|
+
* gap is 9pp (41→50); in dark it widens to 12pp (60→48) because the 3:1
|
|
344
|
+
* floor binds tighter on dark. */
|
|
345
|
+
--color-muted-foreground-soft: hsl(213 8% 48%);
|
|
346
|
+
|
|
347
|
+
/* Borders brighten — the hairline that recedes on light must be visible on
|
|
348
|
+
* dark. Input and border-strong carry additional indicators (background fill,
|
|
349
|
+
* label) beyond the border alone. */
|
|
350
|
+
--color-border: hsl(213 14% 22%);
|
|
351
|
+
--color-border-strong: hsl(213 10% 36%);
|
|
352
|
+
--color-input: hsl(213 12% 28%);
|
|
353
|
+
|
|
354
|
+
--color-subtle: hsl(213 20% 13%);
|
|
355
|
+
--color-subtle-foreground: hsl(213 20% 86%);
|
|
356
|
+
|
|
357
|
+
/* ---- Primary — lightened (32→45%) and desaturated (37→33%) so the colour
|
|
358
|
+
* is visible on dark without eye strain. White foreground still clears 4.5:1
|
|
359
|
+
* (5.05:1) because blue's low luminance-per-lightness keeps the base dark. - */
|
|
360
|
+
--color-primary: hsl(211 33% 45%);
|
|
361
|
+
--color-primary-foreground: hsl(0 0% 100%);
|
|
362
|
+
--color-primary-muted: hsl(211 28% 13%);
|
|
363
|
+
|
|
364
|
+
/* ---- Accent — lightened (39→44%) and desaturated (56→48%). -------------- */
|
|
365
|
+
--color-accent: hsl(18 48% 44%);
|
|
366
|
+
--color-accent-foreground: hsl(0 0% 100%);
|
|
367
|
+
--color-accent-muted: hsl(18 35% 13%);
|
|
368
|
+
|
|
369
|
+
--color-secondary: hsl(213 16% 14%);
|
|
370
|
+
--color-secondary-foreground: hsl(213 20% 88%);
|
|
371
|
+
|
|
372
|
+
--color-ring: hsl(211 33% 45%); /* matches primary; 3.50:1 on background */
|
|
373
|
+
|
|
374
|
+
/* ---- Functional — each lightened and desaturated for dark ---- */
|
|
375
|
+
|
|
376
|
+
--color-destructive: hsl(356 55% 48%);
|
|
377
|
+
--color-destructive-foreground: hsl(0 0% 100%);
|
|
378
|
+
--color-success: hsl(152 38% 36%);
|
|
379
|
+
--color-success-foreground: hsl(0 0% 100%);
|
|
380
|
+
/* Amber has very high luminance-per-lightness; white text fails, so the
|
|
381
|
+
* foreground is near-black. Dark text on amber is the universal pattern. */
|
|
382
|
+
--color-warning: hsl(38 80% 50%);
|
|
383
|
+
--color-warning-foreground: hsl(0 0% 5%);
|
|
384
|
+
--color-info: hsl(202 55% 40%);
|
|
385
|
+
--color-info-foreground: hsl(0 0% 100%);
|
|
386
|
+
|
|
387
|
+
/* Functional-muted surfaces. In light each wash holds 4.5:1 against its base
|
|
388
|
+
* hue (dark text on light wash). In dark the luminance range of dark surfaces
|
|
389
|
+
* is too compressed for that — a surface dark enough for 4.5:1 base-as-text
|
|
390
|
+
* would be indistinguishable from the background. Each base hue instead
|
|
391
|
+
* clears the 3:1 graphical-object floor on its muted surface (icons,
|
|
392
|
+
* indicators), and text uses the foreground token (12-14:1 on every surface). */
|
|
393
|
+
--color-destructive-muted: hsl(356 40% 13%);
|
|
394
|
+
--color-success-muted: hsl(152 28% 13%);
|
|
395
|
+
--color-warning-muted: hsl(38 45% 13%);
|
|
396
|
+
--color-info-muted: hsl(202 35% 13%);
|
|
397
|
+
|
|
398
|
+
/* ---- Elevation: shadow recedes, background lightness ascends ----
|
|
399
|
+
* Shadows are nearly invisible on dark; elevation is communicated through
|
|
400
|
+
* the background lightness gradient (sunken through popover). The shadow
|
|
401
|
+
* tokens use a near-black colour with raised opacity so they remain faintly
|
|
402
|
+
* perceptible on the lightest dark surfaces (card, popover). */
|
|
403
|
+
--shadow-sm: 0 1px 2px 0 hsl(213 30% 2% / 0.18);
|
|
404
|
+
--shadow-md: 0 4px 12px -2px hsl(213 30% 2% / 0.22), 0 2px 6px -2px hsl(213 30% 2% / 0.16);
|
|
405
|
+
--shadow-lg: 0 12px 32px -6px hsl(213 30% 2% / 0.28), 0 4px 10px -4px hsl(213 30% 2% / 0.18);
|
|
406
|
+
|
|
407
|
+
/* Focus halo — shifts to the lighter dark-primary and raises opacity for
|
|
408
|
+
* visibility on dark surfaces. */
|
|
409
|
+
--shadow-halo: 0 0 0 4px hsl(211 33% 45% / 0.35);
|
|
212
410
|
}
|
package/dist/theme.js
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { computed, onScopeDispose, ref, watch } from "vue";
|
|
2
|
+
//#region src/lib/theme.ts
|
|
3
|
+
/**
|
|
4
|
+
* Theme switching for Loom.
|
|
5
|
+
*
|
|
6
|
+
* The single source of truth is the `data-theme` attribute on `<html>`.
|
|
7
|
+
* This composable reads and writes it, persists the preference to
|
|
8
|
+
* `localStorage`, and resolves `"system"` mode from the OS preference.
|
|
9
|
+
*
|
|
10
|
+
* SSR-safe: every DOM access is guarded. On the server, `theme` returns
|
|
11
|
+
* the persisted or default preference, `resolvedTheme` resolves `"system"`
|
|
12
|
+
* to `"light"` (the only safe default without a DOM), and the setter and
|
|
13
|
+
* toggler are no-ops.
|
|
14
|
+
*
|
|
15
|
+
* Flash prevention: `themeScript` is a string of inline JavaScript that
|
|
16
|
+
* reads `localStorage` and sets `data-theme` before the first paint.
|
|
17
|
+
* Consumers rendering SSR inject it into `<head>`:
|
|
18
|
+
*
|
|
19
|
+
* <script>${themeScript}<\/script>
|
|
20
|
+
*/
|
|
21
|
+
var STORAGE_KEY = "loom:theme";
|
|
22
|
+
var DATA_ATTR = "data-theme";
|
|
23
|
+
var MEDIA_QUERY = "(prefers-color-scheme: dark)";
|
|
24
|
+
/** Default preference when nothing is stored and no OS signal exists. */
|
|
25
|
+
var DEFAULT_PREFERENCE = "system";
|
|
26
|
+
/**
|
|
27
|
+
* Reactive shared state, lazily initialised on the first `useTheme()` call
|
|
28
|
+
* and torn down with the effect scope that owns it. Multiple components
|
|
29
|
+
* calling `useTheme()` in the same app share the same refs and the same
|
|
30
|
+
* `matchMedia` listener.
|
|
31
|
+
*/
|
|
32
|
+
var sharedState = null;
|
|
33
|
+
/**
|
|
34
|
+
* Reset the shared state. Intended for test isolation only — a real app
|
|
35
|
+
* never needs this because the state lives for the app's lifetime.
|
|
36
|
+
*/
|
|
37
|
+
function _resetThemeState() {
|
|
38
|
+
if (sharedState?.mediaQuery && sharedState.listener) sharedState.mediaQuery.removeEventListener("change", sharedState.listener);
|
|
39
|
+
sharedState = null;
|
|
40
|
+
}
|
|
41
|
+
function getSharedState() {
|
|
42
|
+
if (sharedState) {
|
|
43
|
+
sharedState.scopeCount++;
|
|
44
|
+
return sharedState;
|
|
45
|
+
}
|
|
46
|
+
let stored = DEFAULT_PREFERENCE;
|
|
47
|
+
try {
|
|
48
|
+
const raw = localStorage.getItem(STORAGE_KEY);
|
|
49
|
+
if (raw === "light" || raw === "dark" || raw === "system") stored = raw;
|
|
50
|
+
} catch {}
|
|
51
|
+
applyToDOM(resolveTheme(stored, getSystemIsDark()));
|
|
52
|
+
const preference = ref(stored);
|
|
53
|
+
const systemIsDark = ref(getSystemIsDark());
|
|
54
|
+
let mediaQuery = null;
|
|
55
|
+
let listener = null;
|
|
56
|
+
try {
|
|
57
|
+
mediaQuery = window.matchMedia(MEDIA_QUERY);
|
|
58
|
+
listener = (e) => {
|
|
59
|
+
systemIsDark.value = e.matches;
|
|
60
|
+
};
|
|
61
|
+
mediaQuery.addEventListener("change", listener);
|
|
62
|
+
} catch {}
|
|
63
|
+
sharedState = {
|
|
64
|
+
preference,
|
|
65
|
+
systemIsDark,
|
|
66
|
+
mediaQuery,
|
|
67
|
+
listener,
|
|
68
|
+
scopeCount: 1
|
|
69
|
+
};
|
|
70
|
+
return sharedState;
|
|
71
|
+
}
|
|
72
|
+
function releaseSharedState() {
|
|
73
|
+
if (!sharedState) return;
|
|
74
|
+
sharedState.scopeCount--;
|
|
75
|
+
if (sharedState.scopeCount > 0) return;
|
|
76
|
+
if (sharedState.mediaQuery && sharedState.listener) sharedState.mediaQuery.removeEventListener("change", sharedState.listener);
|
|
77
|
+
sharedState = null;
|
|
78
|
+
}
|
|
79
|
+
function getSystemIsDark() {
|
|
80
|
+
try {
|
|
81
|
+
return window.matchMedia(MEDIA_QUERY).matches;
|
|
82
|
+
} catch {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function resolveTheme(pref, systemDark) {
|
|
87
|
+
return pref === "system" ? systemDark ? "dark" : "light" : pref;
|
|
88
|
+
}
|
|
89
|
+
function applyToDOM(theme) {
|
|
90
|
+
try {
|
|
91
|
+
document.documentElement.setAttribute(DATA_ATTR, theme);
|
|
92
|
+
} catch {}
|
|
93
|
+
}
|
|
94
|
+
function persist(preference) {
|
|
95
|
+
try {
|
|
96
|
+
localStorage.setItem(STORAGE_KEY, preference);
|
|
97
|
+
} catch {}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Read and control the active Loom theme.
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```vue
|
|
104
|
+
* <script setup>
|
|
105
|
+
* import { useTheme } from "@ecoma-io/loom/theme"
|
|
106
|
+
* const { theme, resolvedTheme, setTheme, toggleTheme } = useTheme()
|
|
107
|
+
* <\/script>
|
|
108
|
+
*
|
|
109
|
+
* <template>
|
|
110
|
+
* <button @click="toggleTheme">
|
|
111
|
+
* {{ resolvedTheme === "dark" ? "☀️" : "🌙" }}
|
|
112
|
+
* </button>
|
|
113
|
+
* </template>
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
function useTheme() {
|
|
117
|
+
const state = getSharedState();
|
|
118
|
+
onScopeDispose(releaseSharedState);
|
|
119
|
+
/** The user's preference — `"system"` defers to the OS. */
|
|
120
|
+
const theme = computed({
|
|
121
|
+
get: () => state.preference.value,
|
|
122
|
+
set: (value) => {
|
|
123
|
+
state.preference.value = value;
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
/** The actual active theme, with `"system"` resolved to `"light"` or `"dark"`. */
|
|
127
|
+
const resolvedTheme = computed(() => resolveTheme(state.preference.value, state.systemIsDark.value));
|
|
128
|
+
watch([() => state.preference.value, () => state.systemIsDark.value], () => {
|
|
129
|
+
applyToDOM(resolvedTheme.value);
|
|
130
|
+
persist(state.preference.value);
|
|
131
|
+
});
|
|
132
|
+
/** Set the theme preference explicitly. */
|
|
133
|
+
function setTheme(preference) {
|
|
134
|
+
state.preference.value = preference;
|
|
135
|
+
}
|
|
136
|
+
/** Toggle between light and dark. System preference stays system. */
|
|
137
|
+
function toggleTheme() {
|
|
138
|
+
if (state.preference.value === "system") state.preference.value = resolvedTheme.value === "dark" ? "light" : "dark";
|
|
139
|
+
else state.preference.value = state.preference.value === "dark" ? "light" : "dark";
|
|
140
|
+
}
|
|
141
|
+
return {
|
|
142
|
+
theme,
|
|
143
|
+
resolvedTheme,
|
|
144
|
+
setTheme,
|
|
145
|
+
toggleTheme
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Inline script to prevent flash-of-wrong-theme on SSR pages.
|
|
150
|
+
*
|
|
151
|
+
* Paste it into `<head>` before any stylesheet links:
|
|
152
|
+
*
|
|
153
|
+
* ```html
|
|
154
|
+
* <script><%= themeScript %><\/script>
|
|
155
|
+
* ```
|
|
156
|
+
*
|
|
157
|
+
* It reads `localStorage` and sets `data-theme` on `<html>` synchronously,
|
|
158
|
+
* before the browser paints, so the first frame is already in the right
|
|
159
|
+
* theme. When no preference is stored, it follows the OS preference.
|
|
160
|
+
*
|
|
161
|
+
* The script is deliberately tiny and has no dependencies.
|
|
162
|
+
*/
|
|
163
|
+
var themeScript = `(() => {
|
|
164
|
+
const t = localStorage.getItem("${STORAGE_KEY}");
|
|
165
|
+
const d = window.matchMedia("${MEDIA_QUERY}").matches;
|
|
166
|
+
document.documentElement.setAttribute("${DATA_ATTR}", (t === "dark" || (!t && d)) ? "dark" : "light");
|
|
167
|
+
})()`;
|
|
168
|
+
//#endregion
|
|
169
|
+
export { _resetThemeState, themeScript, useTheme };
|
|
170
|
+
|
|
171
|
+
//# sourceMappingURL=theme.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.js","names":[],"sources":["../src/lib/theme.ts"],"sourcesContent":["/**\n * Theme switching for Loom.\n *\n * The single source of truth is the `data-theme` attribute on `<html>`.\n * This composable reads and writes it, persists the preference to\n * `localStorage`, and resolves `\"system\"` mode from the OS preference.\n *\n * SSR-safe: every DOM access is guarded. On the server, `theme` returns\n * the persisted or default preference, `resolvedTheme` resolves `\"system\"`\n * to `\"light\"` (the only safe default without a DOM), and the setter and\n * toggler are no-ops.\n *\n * Flash prevention: `themeScript` is a string of inline JavaScript that\n * reads `localStorage` and sets `data-theme` before the first paint.\n * Consumers rendering SSR inject it into `<head>`:\n *\n * <script>${themeScript}</script>\n */\n\nimport { type Ref, computed, onScopeDispose, ref, watch } from \"vue\";\n\n/** The preference a user expresses — `\"system\"` defers to the OS. */\nexport type ThemePreference = \"light\" | \"dark\" | \"system\";\n\n/** The actual theme applied — `\"system\"` is resolved away. */\nexport type ResolvedTheme = \"light\" | \"dark\";\n\nconst STORAGE_KEY = \"loom:theme\";\nconst DATA_ATTR = \"data-theme\";\nconst MEDIA_QUERY = \"(prefers-color-scheme: dark)\";\n\n/** Default preference when nothing is stored and no OS signal exists. */\nconst DEFAULT_PREFERENCE: ThemePreference = \"system\";\n\n// --- Shared state (one per Vue app, not one per composable call) ---------\n\ninterface ThemeState {\n preference: Ref<ThemePreference>;\n systemIsDark: Ref<boolean>;\n mediaQuery: MediaQueryList | null;\n listener: ((e: MediaQueryListEvent) => void) | null;\n scopeCount: number;\n}\n\n/**\n * Reactive shared state, lazily initialised on the first `useTheme()` call\n * and torn down with the effect scope that owns it. Multiple components\n * calling `useTheme()` in the same app share the same refs and the same\n * `matchMedia` listener.\n */\nlet sharedState: ThemeState | null = null;\n\n/**\n * Reset the shared state. Intended for test isolation only — a real app\n * never needs this because the state lives for the app's lifetime.\n */\nexport function _resetThemeState(): void {\n if (sharedState?.mediaQuery && sharedState.listener) {\n sharedState.mediaQuery.removeEventListener(\"change\", sharedState.listener);\n }\n sharedState = null;\n}\n\nfunction getSharedState(): ThemeState {\n if (sharedState) {\n sharedState.scopeCount++;\n return sharedState;\n }\n\n // Read the stored preference, defaulting to \"system\".\n let stored: ThemePreference = DEFAULT_PREFERENCE;\n try {\n const raw = localStorage.getItem(STORAGE_KEY);\n if (raw === \"light\" || raw === \"dark\" || raw === \"system\") {\n stored = raw;\n }\n } catch {\n // localStorage may be unavailable (SSR, private browsing).\n }\n\n // Apply the initial theme to the DOM so the very first render is correct.\n const initial = resolveTheme(stored, getSystemIsDark());\n applyToDOM(initial);\n\n const preference = ref<ThemePreference>(stored);\n const systemIsDark = ref<boolean>(getSystemIsDark());\n\n // Listen for OS dark-mode changes.\n let mediaQuery: MediaQueryList | null = null;\n let listener: ((e: MediaQueryListEvent) => void) | null = null;\n\n try {\n mediaQuery = window.matchMedia(MEDIA_QUERY);\n listener = (e: MediaQueryListEvent) => {\n systemIsDark.value = e.matches;\n };\n mediaQuery.addEventListener(\"change\", listener);\n } catch {\n // matchMedia may be unavailable.\n }\n\n sharedState = {\n preference,\n systemIsDark,\n mediaQuery,\n listener,\n scopeCount: 1,\n };\n\n return sharedState;\n}\n\nfunction releaseSharedState(): void {\n if (!sharedState) return;\n sharedState.scopeCount--;\n if (sharedState.scopeCount > 0) return;\n\n // Last consumer gone — tear down the listener.\n if (sharedState.mediaQuery && sharedState.listener) {\n sharedState.mediaQuery.removeEventListener(\"change\", sharedState.listener);\n }\n sharedState = null;\n}\n\n// --- DOM helpers --------------------------------------------------------\n\nfunction getSystemIsDark(): boolean {\n try {\n return window.matchMedia(MEDIA_QUERY).matches;\n } catch {\n return false;\n }\n}\n\nfunction resolveTheme(pref: ThemePreference, systemDark: boolean): ResolvedTheme {\n return pref === \"system\" ? (systemDark ? \"dark\" : \"light\") : pref;\n}\n\nfunction applyToDOM(theme: ResolvedTheme): void {\n try {\n document.documentElement.setAttribute(DATA_ATTR, theme);\n } catch {\n // document may be unavailable (SSR).\n }\n}\n\nfunction persist(preference: ThemePreference): void {\n try {\n localStorage.setItem(STORAGE_KEY, preference);\n } catch {\n // localStorage may be unavailable.\n }\n}\n\n// --- Public API ---------------------------------------------------------\n\n/**\n * Read and control the active Loom theme.\n *\n * @example\n * ```vue\n * <script setup>\n * import { useTheme } from \"@ecoma-io/loom/theme\"\n * const { theme, resolvedTheme, setTheme, toggleTheme } = useTheme()\n * </script>\n *\n * <template>\n * <button @click=\"toggleTheme\">\n * {{ resolvedTheme === \"dark\" ? \"☀️\" : \"🌙\" }}\n * </button>\n * </template>\n * ```\n */\nexport function useTheme(): {\n readonly theme: Ref<ThemePreference>;\n readonly resolvedTheme: Readonly<Ref<ResolvedTheme>>;\n readonly setTheme: (preference: ThemePreference) => void;\n readonly toggleTheme: () => void;\n} {\n const state = getSharedState();\n\n // Clean up the shared listener when the consuming scope disposes.\n onScopeDispose(releaseSharedState);\n\n /** The user's preference — `\"system\"` defers to the OS. */\n const theme = computed<ThemePreference>({\n get: () => state.preference.value,\n set: (value: ThemePreference) => {\n state.preference.value = value;\n },\n });\n\n /** The actual active theme, with `\"system\"` resolved to `\"light\"` or `\"dark\"`. */\n const resolvedTheme = computed<ResolvedTheme>(() =>\n resolveTheme(state.preference.value, state.systemIsDark.value),\n );\n\n // Whenever the preference or the OS signal changes, apply the resolved\n // theme to the DOM and persist the preference.\n watch([() => state.preference.value, () => state.systemIsDark.value], () => {\n applyToDOM(resolvedTheme.value);\n persist(state.preference.value);\n });\n\n /** Set the theme preference explicitly. */\n function setTheme(preference: ThemePreference): void {\n state.preference.value = preference;\n }\n\n /** Toggle between light and dark. System preference stays system. */\n function toggleTheme(): void {\n if (state.preference.value === \"system\") {\n // Toggle the resolved theme and lock to it, so the user can override\n // the OS preference with one click.\n state.preference.value = resolvedTheme.value === \"dark\" ? \"light\" : \"dark\";\n } else {\n state.preference.value = state.preference.value === \"dark\" ? \"light\" : \"dark\";\n }\n }\n\n return { theme, resolvedTheme, setTheme, toggleTheme } as const;\n}\n\n/**\n * Inline script to prevent flash-of-wrong-theme on SSR pages.\n *\n * Paste it into `<head>` before any stylesheet links:\n *\n * ```html\n * <script><%= themeScript %></script>\n * ```\n *\n * It reads `localStorage` and sets `data-theme` on `<html>` synchronously,\n * before the browser paints, so the first frame is already in the right\n * theme. When no preference is stored, it follows the OS preference.\n *\n * The script is deliberately tiny and has no dependencies.\n */\nexport const themeScript = `(() => {\n const t = localStorage.getItem(\"${STORAGE_KEY}\");\n const d = window.matchMedia(\"${MEDIA_QUERY}\").matches;\n document.documentElement.setAttribute(\"${DATA_ATTR}\", (t === \"dark\" || (!t && d)) ? \"dark\" : \"light\");\n})()`;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AA2BA,IAAM,cAAc;AACpB,IAAM,YAAY;AAClB,IAAM,cAAc;;AAGpB,IAAM,qBAAsC;;;;;;;AAkB5C,IAAI,cAAiC;;;;;AAMrC,SAAgB,mBAAyB;CACvC,IAAI,aAAa,cAAc,YAAY,UACzC,YAAY,WAAW,oBAAoB,UAAU,YAAY,QAAQ;CAE3E,cAAc;AAChB;AAEA,SAAS,iBAA6B;CACpC,IAAI,aAAa;EACf,YAAY;EACZ,OAAO;CACT;CAGA,IAAI,SAA0B;CAC9B,IAAI;EACF,MAAM,MAAM,aAAa,QAAQ,WAAW;EAC5C,IAAI,QAAQ,WAAW,QAAQ,UAAU,QAAQ,UAC/C,SAAS;CAEb,QAAQ,CAER;CAIA,WADgB,aAAa,QAAQ,gBAAgB,CAC1C,CAAO;CAElB,MAAM,aAAa,IAAqB,MAAM;CAC9C,MAAM,eAAe,IAAa,gBAAgB,CAAC;CAGnD,IAAI,aAAoC;CACxC,IAAI,WAAsD;CAE1D,IAAI;EACF,aAAa,OAAO,WAAW,WAAW;EAC1C,YAAY,MAA2B;GACrC,aAAa,QAAQ,EAAE;EACzB;EACA,WAAW,iBAAiB,UAAU,QAAQ;CAChD,QAAQ,CAER;CAEA,cAAc;EACZ;EACA;EACA;EACA;EACA,YAAY;CACd;CAEA,OAAO;AACT;AAEA,SAAS,qBAA2B;CAClC,IAAI,CAAC,aAAa;CAClB,YAAY;CACZ,IAAI,YAAY,aAAa,GAAG;CAGhC,IAAI,YAAY,cAAc,YAAY,UACxC,YAAY,WAAW,oBAAoB,UAAU,YAAY,QAAQ;CAE3E,cAAc;AAChB;AAIA,SAAS,kBAA2B;CAClC,IAAI;EACF,OAAO,OAAO,WAAW,WAAW,CAAC,CAAC;CACxC,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAS,aAAa,MAAuB,YAAoC;CAC/E,OAAO,SAAS,WAAY,aAAa,SAAS,UAAW;AAC/D;AAEA,SAAS,WAAW,OAA4B;CAC9C,IAAI;EACF,SAAS,gBAAgB,aAAa,WAAW,KAAK;CACxD,QAAQ,CAER;AACF;AAEA,SAAS,QAAQ,YAAmC;CAClD,IAAI;EACF,aAAa,QAAQ,aAAa,UAAU;CAC9C,QAAQ,CAER;AACF;;;;;;;;;;;;;;;;;;AAqBA,SAAgB,WAKd;CACA,MAAM,QAAQ,eAAe;CAG7B,eAAe,kBAAkB;;CAGjC,MAAM,QAAQ,SAA0B;EACtC,WAAW,MAAM,WAAW;EAC5B,MAAM,UAA2B;GAC/B,MAAM,WAAW,QAAQ;EAC3B;CACF,CAAC;;CAGD,MAAM,gBAAgB,eACpB,aAAa,MAAM,WAAW,OAAO,MAAM,aAAa,KAAK,CAC/D;CAIA,MAAM,OAAO,MAAM,WAAW,aAAa,MAAM,aAAa,KAAK,SAAS;EAC1E,WAAW,cAAc,KAAK;EAC9B,QAAQ,MAAM,WAAW,KAAK;CAChC,CAAC;;CAGD,SAAS,SAAS,YAAmC;EACnD,MAAM,WAAW,QAAQ;CAC3B;;CAGA,SAAS,cAAoB;EAC3B,IAAI,MAAM,WAAW,UAAU,UAG7B,MAAM,WAAW,QAAQ,cAAc,UAAU,SAAS,UAAU;OAEpE,MAAM,WAAW,QAAQ,MAAM,WAAW,UAAU,SAAS,UAAU;CAE3E;CAEA,OAAO;EAAE;EAAO;EAAe;EAAU;CAAY;AACvD;;;;;;;;;;;;;;;;AAiBA,IAAa,cAAc;oCACS,YAAY;iCACf,YAAY;2CACF,UAAU"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ecoma-io/loom",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Opinionated UI system and composition library for cross-platform web applications.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"design-system",
|
|
7
7
|
"component-library",
|
|
@@ -16,7 +16,10 @@
|
|
|
16
16
|
"wcag",
|
|
17
17
|
"theming",
|
|
18
18
|
"dark-mode",
|
|
19
|
-
"
|
|
19
|
+
"cross-platform",
|
|
20
|
+
"desktop",
|
|
21
|
+
"responsive",
|
|
22
|
+
"composition"
|
|
20
23
|
],
|
|
21
24
|
"homepage": "https://github.com/ecoma-io/loom#readme",
|
|
22
25
|
"repository": {
|
|
@@ -47,6 +50,10 @@
|
|
|
47
50
|
"types": "./dist/a11y.d.ts",
|
|
48
51
|
"default": "./dist/a11y.js"
|
|
49
52
|
},
|
|
53
|
+
"./theme": {
|
|
54
|
+
"types": "./dist/lib/theme.d.ts",
|
|
55
|
+
"default": "./dist/theme.js"
|
|
56
|
+
},
|
|
50
57
|
"./styles/global.css": "./dist/styles/global.css",
|
|
51
58
|
"./styles/theme.css": "./dist/styles/theme.css",
|
|
52
59
|
"./styles/fonts.css": "./dist/styles/fonts.css",
|
|
@@ -64,7 +71,7 @@
|
|
|
64
71
|
"prepare": "lefthook install",
|
|
65
72
|
"format": "prettier --write .",
|
|
66
73
|
"format:check": "prettier --check .",
|
|
67
|
-
"lint": "eslint . --max-warnings 0 && node tools/check-component-artifacts.ts",
|
|
74
|
+
"lint": "eslint . --cache --cache-strategy content --cache-location node_modules/.cache/eslint --max-warnings 0 && node tools/check-component-artifacts.ts",
|
|
68
75
|
"typecheck": "vue-tsc --noEmit",
|
|
69
76
|
"test": "vitest run",
|
|
70
77
|
"test:watch": "vitest",
|
|
@@ -73,6 +80,7 @@
|
|
|
73
80
|
"docs:dev": "vitepress dev docs",
|
|
74
81
|
"docs:build": "vitepress build docs",
|
|
75
82
|
"docs:stage": "node tools/stage-docs.ts",
|
|
83
|
+
"docs:check-route": "node tools/stage-docs.ts --check",
|
|
76
84
|
"docs:preview": "vitepress preview docs"
|
|
77
85
|
},
|
|
78
86
|
"devDependencies": {
|
|
@@ -87,6 +95,7 @@
|
|
|
87
95
|
"@vitest/coverage-v8": "^4.1.10",
|
|
88
96
|
"@vitest/eslint-plugin": "^1.6.26",
|
|
89
97
|
"@vue/test-utils": "^2.4.11",
|
|
98
|
+
"@vue/typescript-plugin": "3.3.9",
|
|
90
99
|
"eslint": "^10.8.0",
|
|
91
100
|
"eslint-config-prettier": "^10.1.8",
|
|
92
101
|
"eslint-plugin-playwright": "^2.11.0",
|
|
@@ -111,6 +120,7 @@
|
|
|
111
120
|
"wrangler": "^4.118.0"
|
|
112
121
|
},
|
|
113
122
|
"dependencies": {
|
|
123
|
+
"@internationalized/date": "^3.12.3",
|
|
114
124
|
"@lucide/vue": "^1.28.0",
|
|
115
125
|
"class-variance-authority": "^0.7.1",
|
|
116
126
|
"clsx": "^2.1.1",
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* BrandMark — one face, two forces. The left half is human (an almond eye),
|
|
3
|
-
* the right half is the agent (a rectangular eye), and the dividing line is a
|
|
4
|
-
* nose bridge: both halves belong to the same face, which is the
|
|
5
|
-
* organization.
|
|
6
|
-
*
|
|
7
|
-
* Built with `createLucideIcon` so it takes exactly the props any Lucide icon
|
|
8
|
-
* takes — size, strokeWidth, color — and a consumer cannot tell a custom icon
|
|
9
|
-
* from a stock one. Custom icons live in this folder and follow the same
|
|
10
|
-
* recipe: 24-unit grid geometry, stroke through `currentColor`.
|
|
11
|
-
*
|
|
12
|
-
* The duotone treatment, where the warp and weft halves carry their own
|
|
13
|
-
* colours, is a brand asset rather than an icon. An icon stays monochrome so
|
|
14
|
-
* it can inherit whatever colour it is dropped into.
|
|
15
|
-
*/
|
|
16
|
-
declare const BrandMark: import("@lucide/vue").LucideIcon;
|
|
17
|
-
export default BrandMark;
|
|
18
|
-
//# sourceMappingURL=BrandMark.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"BrandMark.d.ts","sourceRoot":"","sources":["../../src/icons/BrandMark.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;GAcG;AACH,QAAA,MAAM,SAAS,kCAgBb,CAAC;AAEH,eAAe,SAAS,CAAC"}
|