@livestorm/ui-vue 2.0.5 → 4.0.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 +9 -6
- package/components-vite.js +2 -2
- package/dist/UiButton-uyW8EHRJ.mjs +602 -0
- package/dist/UiTimelineItem-EiOEi1yF.mjs +7293 -0
- package/dist/UiTooltip-DZcPD6_N.mjs +158 -0
- package/dist/a11y-CaZxRWzo.mjs +6 -0
- package/dist/breakpoints.mjs +4 -9
- package/dist/bus.mjs +5 -5
- package/dist/components.mjs +236 -222
- package/dist/i18n-B8QOMuFD.mjs +46 -0
- package/dist/index.mjs +4 -87
- package/dist/integrations.mjs +3 -14
- package/dist/layouts.mjs +228 -236
- package/dist/responsive.mjs +31 -36
- package/dist/slot.mjs +11 -17
- package/dist/toastDSV2-D3xDZPe5.mjs +105 -0
- package/dist/types/index.d.ts +23 -1
- package/dist/types/src/components/Toast/ToastMessage.vue.d.ts +17 -7
- package/dist/types/src/components/Toast/toastDSV2.d.ts +89 -64
- package/dist/types/src/components/UiActionBar/UiActionBar.vue.d.ts +3 -1
- package/dist/types/src/components/UiActionBar/UiActionBarItem.vue.d.ts +18 -3
- package/dist/types/src/components/UiActionBar/types.d.ts +5 -1
- package/dist/types/src/components/UiAvatar/UiAvatar.vue.d.ts +4 -2
- package/dist/types/src/components/UiAvatarList/UiAvatarList.vue.d.ts +3 -2
- package/dist/types/src/components/UiBanner/UiBanner.vue.d.ts +13 -1
- package/dist/types/src/components/UiButton/UiButton.vue.d.ts +102 -38
- package/dist/types/src/components/UiButtonGroup/UiButtonGroup.vue.d.ts +8 -2
- package/dist/types/src/components/UiButtonGroup/UiButtonGroupItem.vue.d.ts +3 -0
- package/dist/types/src/components/UiButtonGroup/types.d.ts +5 -1
- package/dist/types/src/components/UiChoice/UiChoice.vue.d.ts +71 -0
- package/dist/types/src/components/UiChoice/index.d.ts +2 -0
- package/dist/types/src/components/UiChoice/types.d.ts +7 -0
- package/dist/types/src/components/UiColorField/UiColorField.vue.d.ts +1 -1
- package/dist/types/src/components/UiColorPicker/UiColorPicker.vue.d.ts +2 -2
- package/dist/types/src/components/UiCombobox/UiCombobox.types.d.ts +47 -0
- package/dist/types/src/components/UiCombobox/UiCombobox.vue.d.ts +40 -0
- package/dist/types/src/components/UiCombobox/index.d.ts +2 -0
- package/dist/types/src/components/UiDataTable/UiDataTable.types.d.ts +46 -0
- package/dist/types/src/components/UiDataTable/UiDataTable.vue.d.ts +136 -0
- package/dist/types/src/components/UiDataTable/index.d.ts +5 -0
- package/dist/types/src/components/UiDrawer/UiDrawer.vue.d.ts +28 -0
- package/dist/types/src/components/UiDrawer/UiDrawerContent.vue.d.ts +18 -0
- package/dist/types/src/components/UiDrawer/UiDrawerTrigger.vue.d.ts +14 -0
- package/dist/types/src/components/UiDropdown/DropdownItemCheckbox.vue.d.ts +3 -0
- package/dist/types/src/components/UiDropdown/UiDropdownContent.vue.d.ts +10 -0
- package/dist/types/src/components/UiDropdown/UiDropdownGroup.vue.d.ts +17 -0
- package/dist/types/src/components/UiDropdown/UiDropdownItem.vue.d.ts +9 -4
- package/dist/types/src/components/UiDropdown/UiDropdownTrigger.vue.d.ts +21 -5
- package/dist/types/src/components/UiDropdown/index.d.ts +1 -0
- package/dist/types/src/components/UiEmojiPickerList/UiEmojiPickerList.vue.d.ts +22 -0
- package/dist/types/src/components/UiEmptyState/UiEmptyState.vue.d.ts +8 -3
- package/dist/types/src/components/UiFieldWrapper/UiFieldWrapper.vue.d.ts +2 -2
- package/dist/types/src/components/UiInputCheckbox/CheckboxGlyph.vue.d.ts +17 -0
- package/dist/types/src/components/UiInputCheckbox/UiInputCheckbox.vue.d.ts +35 -4
- package/dist/types/src/components/UiInputEmoji/UiInputEmoji.vue.d.ts +45 -0
- package/dist/types/src/components/UiInputRadio/RadioGlyph.vue.d.ts +19 -0
- package/dist/types/src/components/UiInputRadio/UiInputRadio.vue.d.ts +80 -0
- package/dist/types/src/components/UiInputRadio/UiInputRadioGroup.vue.d.ts +86 -0
- package/dist/types/src/components/UiInputRadio/types.d.ts +19 -0
- package/dist/types/src/components/UiInputSelect/UiInputSelect.vue.d.ts +5 -5
- package/dist/types/src/components/UiInputTextarea/UiInputTextarea.vue.d.ts +5 -5
- package/dist/types/src/components/UiListItem/UiListItem.vue.d.ts +18 -4
- package/dist/types/src/components/UiLoader/UiLoader.vue.d.ts +6 -5
- package/dist/types/src/components/UiLoader/UiSpinnerIcon.vue.d.ts +3 -0
- package/dist/types/src/components/UiLogo/UiLogo.vue.d.ts +9 -3
- package/dist/types/src/components/UiMenu/UiMenuContent.vue.d.ts +15 -2
- package/dist/types/src/components/UiMenu/UiMenuItem.vue.d.ts +9 -3
- package/dist/types/src/components/UiNestedOptions/UiNestedOptions.vue.d.ts +13 -0
- package/dist/types/src/components/UiPage/UiPage.vue.d.ts +106 -8
- package/dist/types/src/components/UiPagination/UiPagination.vue.d.ts +36 -0
- package/dist/types/src/components/UiPagination/index.d.ts +2 -0
- package/dist/types/src/components/UiPagination/types.d.ts +4 -0
- package/dist/types/src/components/UiPane/UiPane.vue.d.ts +22 -0
- package/dist/types/src/components/UiPane/UiPaneContent.vue.d.ts +75 -0
- package/dist/types/src/components/UiPane/UiPaneTrigger.vue.d.ts +14 -0
- package/dist/types/src/components/UiPane/index.d.ts +5 -0
- package/dist/types/src/components/UiProgress/UiProgress.vue.d.ts +1 -1
- package/dist/types/src/components/UiRating/UiRating.vue.d.ts +62 -0
- package/dist/types/src/components/UiRating/types.d.ts +1 -0
- package/dist/types/src/components/UiRoomButton/UiRoomButton.vue.d.ts +5 -3
- package/dist/types/src/components/UiRoomCountdown/UiRoomCountdown.vue.d.ts +32 -0
- package/dist/types/src/components/UiShell/UiShell.vue.d.ts +3 -0
- package/dist/types/src/components/UiSideMenu/UiSideMenu.vue.d.ts +22 -1
- package/dist/types/src/components/UiSideMenu/UiSideMenuItemContent.vue.d.ts +2 -2
- package/dist/types/src/components/UiSwitch/UiSwitch.vue.d.ts +114 -0
- package/dist/types/src/components/UiSwitch/types.d.ts +3 -0
- package/dist/types/src/components/UiTable/UiTable.vue.d.ts +13 -4
- package/dist/types/src/components/UiTable/UiTableActionsCell.vue.d.ts +49 -0
- package/dist/types/src/components/UiTable/UiTableActionsHeaderCell.vue.d.ts +3 -0
- package/dist/types/src/components/UiTable/UiTableBody.vue.d.ts +11 -1
- package/dist/types/src/components/UiTable/UiTableCell.vue.d.ts +16 -1
- package/dist/types/src/components/UiTable/UiTableHeaderCell.vue.d.ts +31 -2
- package/dist/types/src/components/UiTable/UiTableRow.vue.d.ts +32 -2
- package/dist/types/src/components/UiTable/context.d.ts +3 -0
- package/dist/types/src/components/UiTable/index.d.ts +4 -0
- package/dist/types/src/components/UiTabs/UiTabs.vue.d.ts +8 -2
- package/dist/types/src/components/UiTag/UiTag.types.d.ts +25 -0
- package/dist/types/src/components/UiTag/UiTag.vue.d.ts +5 -26
- package/dist/types/src/components/UiTag/index.d.ts +2 -1
- package/dist/types/src/components/UiTextField/UiTextField.vue.d.ts +10 -5
- package/dist/types/src/components/UiTooltip/UiTooltipProvider.vue.d.ts +1 -0
- package/dist/types/src/components/UiTooltip/UiTooltipTrigger.vue.d.ts +2 -2
- package/dist/types/src/composables/storedThemingApplies.d.ts +17 -0
- package/dist/types/src/composables/useButtonStyles.d.ts +1 -0
- package/dist/types/src/composables/useChoiceboxSurface.d.ts +11 -0
- package/dist/types/src/composables/useContentMode.d.ts +23 -0
- package/dist/types/src/composables/useControlModes.d.ts +7 -0
- package/dist/types/src/composables/useControlShape.d.ts +24 -0
- package/dist/types/src/composables/useFieldFocusEvents.d.ts +12 -0
- package/dist/types/src/composables/useIconSize.d.ts +13 -0
- package/dist/types/src/composables/usePullGesture.d.ts +42 -0
- package/dist/types/src/composables/useThemeAndModes.d.ts +4 -0
- package/dist/types/src/constants/sizes.d.ts +1 -1
- package/dist/types/src/theming/colorScale.d.ts +165 -0
- package/dist/types/src/theming/legacyColorScale.d.ts +27 -0
- package/dist/types/src/theming/presetColors.d.ts +11 -0
- package/dist/types/src/theming/primitiveTokens.d.ts +2 -0
- package/dist/types/src/utils/effectiveOpacity.d.ts +2 -0
- package/dist/types/src/utils/numbers.d.ts +1 -2
- package/dist/types/src/utils/tokenColor.d.ts +2 -0
- package/dist/ui-vue.css +2 -1
- package/dist/utils.mjs +165 -194
- package/index.d.ts +22 -0
- package/index.js +44 -0
- package/package.json +28 -20
- package/src/components/Toast/LayoutToasts.vue +19 -11
- package/src/components/Toast/ToastMessage.vue +130 -73
- package/src/components/Toast/toastDSV2.ts +238 -67
- package/src/components/UiActionBar/UiActionBar.vue +15 -5
- package/src/components/UiActionBar/UiActionBarItem.vue +65 -38
- package/src/components/UiActionBar/types.ts +16 -1
- package/src/components/UiAvatar/UiAvatar.vue +9 -3
- package/src/components/UiAvatarList/UiAvatarList.vue +51 -20
- package/src/components/UiBadge/UiBadge.vue +1 -1
- package/src/components/UiBanner/UiBanner.vue +77 -27
- package/src/components/UiBreadcrumb/UiBreadcrumb.vue +1 -1
- package/src/components/UiButton/UiButton.vue +96 -29
- package/src/components/UiButtonGroup/UiButtonGroup.vue +22 -16
- package/src/components/UiButtonGroup/UiButtonGroupItem.vue +44 -14
- package/src/components/UiButtonGroup/types.ts +20 -1
- package/src/components/UiCard/UiCard.vue +20 -23
- package/src/components/UiCarousel/UiCarousel.vue +2 -2
- package/src/components/UiChoice/UiChoice.vue +187 -0
- package/src/components/UiChoice/index.ts +2 -0
- package/src/components/UiChoice/types.ts +11 -0
- package/src/components/UiColorField/UiColorField.vue +2 -2
- package/src/components/UiColorPicker/UiColorPicker.vue +16 -13
- package/src/components/UiCombobox/UiCombobox.types.ts +52 -0
- package/src/components/UiCombobox/UiCombobox.vue +296 -0
- package/src/components/UiCombobox/index.ts +2 -0
- package/src/components/UiDataTable/UiDataTable.types.ts +47 -0
- package/src/components/UiDataTable/UiDataTable.vue +422 -0
- package/src/components/UiDataTable/index.ts +12 -0
- package/src/components/UiDialog/UiDialogClose.vue +1 -1
- package/src/components/UiDialog/UiDialogContent.vue +22 -7
- package/src/components/UiDrawer/UiDrawer.vue +16 -0
- package/src/components/UiDrawer/UiDrawerContent.vue +42 -0
- package/src/components/UiDrawer/UiDrawerTrigger.vue +17 -0
- package/src/components/UiDropdown/DropdownItemCheckbox.vue +10 -0
- package/src/components/UiDropdown/UiDropdownContent.vue +32 -21
- package/src/components/UiDropdown/UiDropdownGroup.vue +23 -0
- package/src/components/UiDropdown/UiDropdownItem.vue +45 -18
- package/src/components/UiDropdown/UiDropdownSeparator.vue +1 -1
- package/src/components/UiDropdown/UiDropdownTrigger.vue +139 -45
- package/src/components/UiDropdown/index.ts +1 -0
- package/src/components/UiEmojiPickerList/UiEmojiPickerList.vue +122 -0
- package/src/components/UiEmptyState/UiEmptyState.vue +16 -4
- package/src/components/UiFieldWrapper/UiFieldWrapper.vue +10 -4
- package/src/components/UiHorizontalSeparator/UiHorizontalSeparator.vue +2 -2
- package/src/components/UiInputCheckbox/CheckboxGlyph.vue +78 -0
- package/src/components/UiInputCheckbox/UiInputCheckbox.vue +213 -177
- package/src/components/UiInputEmoji/UiInputEmoji.vue +96 -0
- package/src/components/UiInputRadio/RadioGlyph.vue +45 -0
- package/src/components/UiInputRadio/UiInputRadio.vue +382 -0
- package/src/components/UiInputRadio/UiInputRadioGroup.vue +166 -0
- package/src/components/UiInputRadio/types.ts +24 -0
- package/src/components/UiInputSelect/UiInputSelect.vue +9 -7
- package/src/components/UiInputTextarea/UiInputTextarea.vue +20 -35
- package/src/components/UiLabel/UiLabel.vue +1 -1
- package/src/components/UiListItem/UiListItem.vue +55 -9
- package/src/components/UiLoader/UiLoader.vue +11 -29
- package/src/components/UiLoader/UiSpinnerIcon.vue +21 -0
- package/src/components/UiLogo/UiLogo.vue +41 -7
- package/src/components/UiMenu/UiMenuContent.vue +24 -3
- package/src/components/UiMenu/UiMenuGroup.vue +1 -1
- package/src/components/UiMenu/UiMenuItem.vue +14 -3
- package/src/components/UiMenu/UiMenuSubContent.vue +1 -1
- package/src/components/UiMenu/UiMenuSubTrigger.vue +2 -2
- package/src/components/UiNestedOptions/UiNestedOptions.vue +6 -0
- package/src/components/UiPage/UiPage.vue +273 -47
- package/src/components/UiPageHeader/UiPageHeader.vue +29 -9
- package/src/components/UiPagination/UiPagination.vue +99 -0
- package/src/components/UiPagination/index.ts +2 -0
- package/src/components/UiPagination/types.ts +28 -0
- package/src/components/UiPane/UiPane.vue +20 -0
- package/src/components/UiPane/UiPaneContent.vue +232 -0
- package/src/components/UiPane/UiPaneTrigger.vue +14 -0
- package/src/components/UiPane/index.ts +12 -0
- package/src/components/UiPopover/UiPopoverContent.vue +21 -1
- package/src/components/UiProgress/UiProgress.vue +2 -2
- package/src/components/UiRating/UiRating.vue +258 -0
- package/src/components/UiRating/types.ts +1 -0
- package/src/components/UiRoomButton/UiRoomButton.vue +14 -45
- package/src/components/UiRoomCountdown/UiRoomCountdown.vue +376 -0
- package/src/components/UiShell/UiShell.vue +10 -4
- package/src/components/UiSideMenu/UiSideMenu.vue +158 -18
- package/src/components/UiSideMenu/UiSideMenuItemContent.vue +22 -18
- package/src/components/UiStepper/UiStepper.vue +3 -16
- package/src/components/UiStepper/UiStepperDescription.vue +1 -13
- package/src/components/UiStepper/UiStepperIndicator.vue +17 -57
- package/src/components/UiStepper/UiStepperItem.vue +1 -8
- package/src/components/UiStepper/UiStepperSeparator.vue +5 -16
- package/src/components/UiStepper/UiStepperTitle.vue +1 -10
- package/src/components/UiSwitch/UiSwitch.vue +375 -0
- package/src/components/UiSwitch/types.ts +5 -0
- package/src/components/UiTable/UiTable.vue +98 -8
- package/src/components/UiTable/UiTableActionsCell.vue +135 -0
- package/src/components/UiTable/UiTableActionsHeaderCell.vue +19 -0
- package/src/components/UiTable/UiTableBody.vue +16 -1
- package/src/components/UiTable/UiTableCell.vue +33 -16
- package/src/components/UiTable/UiTableHeader.vue +6 -5
- package/src/components/UiTable/UiTableHeaderCell.vue +61 -9
- package/src/components/UiTable/UiTableRow.vue +46 -10
- package/src/components/UiTable/context.ts +5 -0
- package/src/components/UiTable/index.ts +4 -0
- package/src/components/UiTabs/UiTabs.vue +61 -63
- package/src/components/UiTag/UiTag.types.ts +28 -0
- package/src/components/UiTag/UiTag.vue +24 -42
- package/src/components/UiTag/index.ts +2 -0
- package/src/components/UiTextField/UiTextField.vue +27 -47
- package/src/components/UiTimeline/README.md +6 -6
- package/src/components/UiTimeline/UiTimelineItem.vue +3 -3
- package/src/components/UiTooltip/UiTooltipContent.vue +1 -1
- package/src/components/UiTooltip/UiTooltipProvider.vue +3 -0
- package/src/components/UiTooltip/UiTooltipTrigger.vue +16 -1
- package/src/composables/storedThemingApplies.ts +19 -0
- package/src/composables/useButtonStyles.ts +9 -13
- package/src/composables/useChoiceboxSurface.ts +36 -0
- package/src/composables/useContentMode.ts +66 -0
- package/src/composables/useControlModes.ts +11 -0
- package/src/composables/useControlShape.ts +34 -0
- package/src/composables/useFieldFocusEvents.ts +30 -0
- package/src/composables/useIconSize.ts +43 -0
- package/src/composables/usePullGesture.ts +142 -0
- package/src/composables/useThemeAndModes.ts +28 -1
- package/src/constants/sizes.ts +1 -1
- package/src/css/body.css +16 -1
- package/src/css/fonts.css +39 -5
- package/src/global.d.ts +44 -0
- package/src/theming/colorScale.ts +173 -0
- package/src/theming/legacyColorScale.ts +58 -0
- package/src/theming/presetColors.ts +33 -0
- package/src/theming/primitiveTokens.ts +71 -0
- package/src/utils/effectiveOpacity.ts +8 -0
- package/src/utils/i18n.ts +6 -0
- package/src/utils/numbers.ts +1 -1
- package/src/utils/responsive.d.ts +14 -0
- package/src/utils/tokenColor.ts +9 -0
- package/dist/UiTimelineItem.vue_vue_type_style_index_0_lang-DJFdCn2R.mjs +0 -5456
- package/dist/a11y-BhF_nl7L.mjs +0 -159
- package/dist/i18n-Cktw9hIu.mjs +0 -49
- package/dist/toastDSV2-wMh-UMzW.mjs +0 -74
- package/dist/types/src/components/UiAvatar/index.d.ts +0 -1
- package/dist/types/src/components/UiAvatarList/index.d.ts +0 -1
- package/dist/types/src/components/UiBadge/index.d.ts +0 -1
- package/dist/types/src/components/UiBanner/index.d.ts +0 -2
- package/dist/types/src/components/UiButtonGroup/index.d.ts +0 -3
- package/dist/types/src/components/UiCarousel/index.d.ts +0 -2
- package/dist/types/src/components/UiColorField/index.d.ts +0 -2
- package/dist/types/src/components/UiDialog/MarketplaceHeaderExample.vue.d.ts +0 -28
- package/dist/types/src/components/UiDialog/index.d.ts +0 -7
- package/dist/types/src/components/UiFieldWrapper/index.d.ts +0 -1
- package/dist/types/src/components/UiInputCheckbox/index.d.ts +0 -2
- package/dist/types/src/components/UiInputSelect/index.d.ts +0 -2
- package/dist/types/src/components/UiInputTextarea/index.d.ts +0 -2
- package/dist/types/src/components/UiMenu/index.d.ts +0 -10
- package/dist/types/src/components/UiProgress/index.d.ts +0 -2
- package/dist/types/src/components/UiTabs/index.d.ts +0 -2
- package/dist/types/src/components/UiTimeline/index.d.ts +0 -2
- package/dist/types/src/components/UiTooltip/index.d.ts +0 -4
- package/dist/types/src/mixins/DynamicAction.d.ts +0 -30
- package/dist/useThemeAndModes-BzYwSOEv.mjs +0 -108
- package/src/components/UiAvatar/index.js +0 -1
- package/src/components/UiAvatarList/index.js +0 -1
- package/src/components/UiBadge/index.ts +0 -2
- package/src/components/UiBanner/index.ts +0 -2
- package/src/components/UiButtonGroup/index.ts +0 -3
- package/src/components/UiCarousel/index.ts +0 -2
- package/src/components/UiColorField/index.ts +0 -2
- package/src/components/UiDialog/MarketplaceHeaderExample.vue +0 -217
- package/src/components/UiDialog/index.ts +0 -18
- package/src/components/UiFieldWrapper/index.ts +0 -1
- package/src/components/UiInputCheckbox/index.ts +0 -2
- package/src/components/UiInputSelect/index.ts +0 -2
- package/src/components/UiInputTextarea/index.ts +0 -2
- package/src/components/UiMenu/index.ts +0 -10
- package/src/components/UiProgress/index.ts +0 -2
- package/src/components/UiTabs/index.ts +0 -5
- package/src/components/UiTag/index.js +0 -1
- package/src/components/UiTimeline/index.ts +0 -2
- package/src/components/UiTooltip/index.js +0 -4
- package/src/mixins/DynamicAction.js +0 -61
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { computed, type MaybeRefOrGetter, toValue } from 'vue'
|
|
2
2
|
|
|
3
3
|
// Single source of truth for the action-button visual language (background,
|
|
4
|
-
// text,
|
|
4
|
+
// text, hover/active overlays) keyed by `variant` × `color`. Both
|
|
5
5
|
// `UiButton` and `UiDropdownTrigger` consume this so a trigger styled as a
|
|
6
6
|
// tertiary button stays pixel-identical to a real `UiButton` without copying
|
|
7
7
|
// token names around.
|
|
@@ -81,16 +81,6 @@ const TEXT_MAP: Record<ButtonVariant, Record<ButtonColor, string>> = {
|
|
|
81
81
|
},
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
// Border — only `secondary` draws one.
|
|
85
|
-
const BORDER_MAP: Record<ButtonColor, string[]> = {
|
|
86
|
-
'primary': ['border', 'border-borders-primary-strong'],
|
|
87
|
-
'neutral': ['border', 'border-borders-neutral-strong'],
|
|
88
|
-
'neutral-invert': ['border', 'border-borders-neutral-invert-strong'],
|
|
89
|
-
'success': ['border', 'border-borders-success-strong'],
|
|
90
|
-
'warning': ['border', 'border-borders-warning-strong'],
|
|
91
|
-
'error': ['border', 'border-borders-danger-strong'],
|
|
92
|
-
}
|
|
93
|
-
|
|
94
84
|
// Hover overlay tints keyed by `variant-color`, in both the `group-hover:`
|
|
95
85
|
// flavor (layered button overlay element) and the `before:` flavor
|
|
96
86
|
// (single-element trigger pseudo). Kept as literals for Tailwind extraction.
|
|
@@ -205,9 +195,14 @@ export function useButtonStyles(options: UseButtonStylesOptions) {
|
|
|
205
195
|
/** Text color class for the current variant × color. */
|
|
206
196
|
const textClass = computed(() => TEXT_MAP[variant.value][color.value])
|
|
207
197
|
|
|
208
|
-
/**
|
|
198
|
+
/** Soft border of the secondary fill layer; transparent except in the accessible look. */
|
|
209
199
|
const borderClasses = computed(() =>
|
|
210
|
-
variant.value === 'secondary' ?
|
|
200
|
+
variant.value === 'secondary' ? ['border', 'border-control-soft-border'] : [],
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
/** Tertiary labels are underlined in the accessible look. */
|
|
204
|
+
const decorationClass = computed(() =>
|
|
205
|
+
variant.value === 'tertiary' ? '[text-decoration-line:var(--control-link-decoration)] underline-offset-3' : '',
|
|
211
206
|
)
|
|
212
207
|
|
|
213
208
|
/**
|
|
@@ -236,6 +231,7 @@ export function useButtonStyles(options: UseButtonStylesOptions) {
|
|
|
236
231
|
bgClass,
|
|
237
232
|
textClass,
|
|
238
233
|
borderClasses,
|
|
234
|
+
decorationClass,
|
|
239
235
|
overlayClasses,
|
|
240
236
|
beforeHoverOverlayClass,
|
|
241
237
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { computed, type ComputedRef, type MaybeRefOrGetter, toValue } from 'vue'
|
|
2
|
+
import type { ChoiceControl } from '../components/UiChoice/types'
|
|
3
|
+
|
|
4
|
+
interface ChoiceboxState {
|
|
5
|
+
control: ChoiceControl
|
|
6
|
+
selected: boolean
|
|
7
|
+
disabled: boolean
|
|
8
|
+
error?: boolean
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// Only the row's own control rings the surface: a control in the content slot keeps its own focus
|
|
12
|
+
const FOCUS_RING: Record<ChoiceControl, string> = {
|
|
13
|
+
radio: 'has-[[role=radio]:focus-visible]:focus-ring',
|
|
14
|
+
switch: 'has-[[role=switch]:focus-visible]:focus-ring',
|
|
15
|
+
checkbox: 'has-[[type=checkbox]:focus-visible]:focus-ring',
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** Border, fill, radius and focus ring of a UiChoice choicebox */
|
|
19
|
+
export function useChoiceboxSurface (state: MaybeRefOrGetter<ChoiceboxState>): ComputedRef<string[]> {
|
|
20
|
+
return computed(() => {
|
|
21
|
+
const { control, selected, disabled, error } = toValue(state)
|
|
22
|
+
const classes = ['rounded-row border', FOCUS_RING[control]]
|
|
23
|
+
|
|
24
|
+
if (error) {
|
|
25
|
+
classes.push('bg-actions-danger-idle-alpha-light', selected ? 'border-actions-danger-idle' : 'border-control-error-border')
|
|
26
|
+
} else if (disabled) {
|
|
27
|
+
classes.push('bg-control-choice-bg-disabled border-control-choice-border-disabled')
|
|
28
|
+
} else if (selected) {
|
|
29
|
+
classes.push('bg-control-choice-selected-bg border-control-choice-selected-border hover:bg-control-choice-selected-bg-hover')
|
|
30
|
+
} else {
|
|
31
|
+
classes.push('bg-control-choice-bg border-control-choice-border hover:bg-control-choice-bg-hover hover:border-control-choice-border-hover')
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return classes
|
|
35
|
+
})
|
|
36
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { computed, onMounted, onUnmounted, ref, type Ref } from 'vue'
|
|
2
|
+
import useThemeAndModes from './useThemeAndModes'
|
|
3
|
+
import { storedThemingApplies } from './storedThemingApplies'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Registers an element as a page "content" surface so the stored content mode
|
|
7
|
+
* (driven by the ThemePicker) applies its `data-colors-semantic` — the same
|
|
8
|
+
* behaviour `UiPage` gives its page content, without pulling in the full page
|
|
9
|
+
* layout (and its `<main>`).
|
|
10
|
+
*
|
|
11
|
+
* Content ships light. The stored content mode applies where the picker
|
|
12
|
+
* exists (see storedThemingApplies); everyone else gets the shipped default
|
|
13
|
+
* regardless of what localStorage may hold.
|
|
14
|
+
*
|
|
15
|
+
* The predicate is read in onMounted, not at setup: setup also runs during
|
|
16
|
+
* SSR (no localStorage), and server + client-hydration markup must be
|
|
17
|
+
* identical — stored modes take over right after mount instead.
|
|
18
|
+
*
|
|
19
|
+
* @param element Template ref of the content element to watch.
|
|
20
|
+
* @param selector Unique key for the watch registry — one per logical surface
|
|
21
|
+
* (e.g. `[data-name="ui-page-content"]`).
|
|
22
|
+
* @returns `contentMode`, to bind to the element's `data-colors-semantic`.
|
|
23
|
+
*/
|
|
24
|
+
export function useContentMode (
|
|
25
|
+
element: Ref<HTMLElement | undefined>,
|
|
26
|
+
selector: string,
|
|
27
|
+
) {
|
|
28
|
+
const { addElementToWatch, removeElementToWatch, currentContentMode } = useThemeAndModes()
|
|
29
|
+
const storedApplies = ref(false)
|
|
30
|
+
|
|
31
|
+
// Captured at registration: Vue has already nulled the template ref by the
|
|
32
|
+
// time onUnmounted runs, and unregistering needs the element it registered.
|
|
33
|
+
let registered: HTMLElement | undefined
|
|
34
|
+
|
|
35
|
+
// Always resolve to a concrete mode, never undefined. useThemeAndModes also
|
|
36
|
+
// sets this attribute imperatively; if the binding resolved to undefined,
|
|
37
|
+
// Vue would strip the attribute on the re-render that follows the onMounted
|
|
38
|
+
// flag flip, and the content would silently inherit the *shell* mode from
|
|
39
|
+
// <body> — reading as "content mode resets to dark on every navigation".
|
|
40
|
+
const contentMode = computed(() => (
|
|
41
|
+
storedApplies.value ? currentContentMode.value : 'light'
|
|
42
|
+
))
|
|
43
|
+
|
|
44
|
+
onMounted(() => {
|
|
45
|
+
storedApplies.value = storedThemingApplies()
|
|
46
|
+
|
|
47
|
+
if (!element.value) { return }
|
|
48
|
+
|
|
49
|
+
registered = element.value
|
|
50
|
+
addElementToWatch('content', {
|
|
51
|
+
selector,
|
|
52
|
+
element: registered,
|
|
53
|
+
...(storedApplies.value ? {} : { modeOverride: 'light' }),
|
|
54
|
+
})
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
// The registry outlives this component, so a surface that unmounts without
|
|
58
|
+
// this stays referenced and keeps being written to.
|
|
59
|
+
onUnmounted(() => {
|
|
60
|
+
if (registered) {
|
|
61
|
+
removeElementToWatch('content', { selector, element: registered })
|
|
62
|
+
}
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
return { contentMode }
|
|
66
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Applies the accessibility look on the app root: `data-accessibility="on"`.
|
|
3
|
+
* The control tokens read this attribute.
|
|
4
|
+
*/
|
|
5
|
+
export function applyControlModes (
|
|
6
|
+
{ accessibility }: { accessibility: boolean },
|
|
7
|
+
root: HTMLElement = document.body,
|
|
8
|
+
) {
|
|
9
|
+
if (accessibility) root.setAttribute('data-accessibility', 'on')
|
|
10
|
+
else root.removeAttribute('data-accessibility')
|
|
11
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { computed, type ComputedRef, type MaybeRefOrGetter, toValue } from 'vue'
|
|
2
|
+
|
|
3
|
+
// NOTE: every class must be a complete literal string: Tailwind's static
|
|
4
|
+
// extractor can't see interpolated class names.
|
|
5
|
+
|
|
6
|
+
export type FieldSize = 'sm' | 'md' | 'lg' | 'xl'
|
|
7
|
+
type ButtonSize = 'xs' | 'sm' | 'md' | 'lg'
|
|
8
|
+
|
|
9
|
+
interface FieldShape { height: string, radius: string, chevron: string }
|
|
10
|
+
|
|
11
|
+
const FIELD_SHAPES: Record<FieldSize, FieldShape> = {
|
|
12
|
+
sm: { height: 'h-field-sm', radius: 'rounded-field-sm', chevron: 'size-3.5' },
|
|
13
|
+
md: { height: 'h-field-md', radius: 'rounded-field-md', chevron: 'size-4' },
|
|
14
|
+
lg: { height: 'h-field-lg', radius: 'rounded-field-lg', chevron: 'size-5' },
|
|
15
|
+
xl: { height: 'h-field-xl', radius: 'rounded-field-xl', chevron: 'size-6' },
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const BUTTON_SHAPES: Record<ButtonSize, { height: string, square: string, radius: string }> = {
|
|
19
|
+
xs: { height: 'h-button-xs', square: 'size-button-xs', radius: 'rounded-button-xs' },
|
|
20
|
+
sm: { height: 'h-button-sm', square: 'size-button-sm', radius: 'rounded-button-sm' },
|
|
21
|
+
md: { height: 'h-button-md', square: 'size-button-md', radius: 'rounded-button-md' },
|
|
22
|
+
lg: { height: 'h-button-lg', square: 'size-button-lg', radius: 'rounded-button-lg' },
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
interface ControlShapes {
|
|
26
|
+
field: { size: FieldSize, shape: FieldShape }
|
|
27
|
+
button: { size: ButtonSize, shape: { height: string, square: string, radius: string } }
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function useControlShape<K extends keyof ControlShapes> (kind: K, size: MaybeRefOrGetter<ControlShapes[K]['size']>): ComputedRef<ControlShapes[K]['shape']> {
|
|
31
|
+
return computed(() => (kind === 'field'
|
|
32
|
+
? FIELD_SHAPES[toValue(size) as FieldSize]
|
|
33
|
+
: BUTTON_SHAPES[toValue(size) as ButtonSize]) as ControlShapes[K]['shape'])
|
|
34
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { ref } from 'vue'
|
|
2
|
+
|
|
3
|
+
export function useFieldFocusEvents(emit: {
|
|
4
|
+
(event: 'focus', payload: FocusEvent): void
|
|
5
|
+
(event: 'blur', payload: FocusEvent): void
|
|
6
|
+
(event: 'keydown', payload: KeyboardEvent): void
|
|
7
|
+
(event: 'keyup', payload: KeyboardEvent): void
|
|
8
|
+
}) {
|
|
9
|
+
const isFocused = ref(false)
|
|
10
|
+
|
|
11
|
+
function handleFocus(event: FocusEvent) {
|
|
12
|
+
isFocused.value = true
|
|
13
|
+
emit('focus', event)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function handleBlur(event: FocusEvent) {
|
|
17
|
+
isFocused.value = false
|
|
18
|
+
emit('blur', event)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function handleKeydown(event: KeyboardEvent) {
|
|
22
|
+
emit('keydown', event)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function handleKeyup(event: KeyboardEvent) {
|
|
26
|
+
emit('keyup', event)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return { isFocused, handleFocus, handleBlur, handleKeydown, handleKeyup }
|
|
30
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { computed, type MaybeRefOrGetter, toValue } from 'vue'
|
|
2
|
+
|
|
3
|
+
// Single source of truth for the icon diameter a control renders at, keyed by
|
|
4
|
+
// the control's size name.
|
|
5
|
+
//
|
|
6
|
+
// Every control that puts an icon inside itself consumes this — buttons, button
|
|
7
|
+
// groups, action bar items, dropdown triggers, text fields, stepper indicators,
|
|
8
|
+
// loaders — so a design change to the ladder is one edit here instead of one
|
|
9
|
+
// per component. Components covering only part of the ladder (an action bar
|
|
10
|
+
// stops at md, a text field starts at sm) index the rungs they expose.
|
|
11
|
+
//
|
|
12
|
+
// NOTE: every class must be a complete literal string — Tailwind's static
|
|
13
|
+
// extractor can't see interpolated class names (`size-${n}`).
|
|
14
|
+
|
|
15
|
+
export const ICON_SIZES = {
|
|
16
|
+
xs: 'size-3',
|
|
17
|
+
sm: 'size-4',
|
|
18
|
+
md: 'size-5',
|
|
19
|
+
lg: 'size-6',
|
|
20
|
+
xl: 'size-7',
|
|
21
|
+
} as const
|
|
22
|
+
|
|
23
|
+
export type IconSizeName = keyof typeof ICON_SIZES
|
|
24
|
+
|
|
25
|
+
/** Reactive icon size class for a control's `size`. */
|
|
26
|
+
export function useIconSize(size: MaybeRefOrGetter<IconSizeName>) {
|
|
27
|
+
return computed(() => ICON_SIZES[toValue(size)])
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// A button's trailing icon (external link, chevron) sits one step below its
|
|
31
|
+
// leading icon so it reads as an affordance, not as content.
|
|
32
|
+
const TRAILING_ICON_SIZES = {
|
|
33
|
+
xs: 'size-2.5',
|
|
34
|
+
sm: 'size-3.5',
|
|
35
|
+
md: 'size-4',
|
|
36
|
+
lg: 'size-5',
|
|
37
|
+
xl: 'size-6',
|
|
38
|
+
} as const
|
|
39
|
+
|
|
40
|
+
/** Reactive trailing icon size class for a control's `size`. */
|
|
41
|
+
export function useTrailingIconSize(size: MaybeRefOrGetter<IconSizeName>) {
|
|
42
|
+
return computed(() => TRAILING_ICON_SIZES[toValue(size)])
|
|
43
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { computed, ref, toValue, type MaybeRefOrGetter } from 'vue'
|
|
2
|
+
|
|
3
|
+
interface UsePullGestureOptions {
|
|
4
|
+
/**
|
|
5
|
+
* Pointer travel (px, ascending) at which each stage is reached. An empty
|
|
6
|
+
* list disables the gesture.
|
|
7
|
+
*/
|
|
8
|
+
stages: MaybeRefOrGetter<number[]>
|
|
9
|
+
/**
|
|
10
|
+
* Travel (px) up to which the element tracks the pointer 1:1; resistance
|
|
11
|
+
* builds beyond it. Defaults to the last stage.
|
|
12
|
+
*/
|
|
13
|
+
resistFrom?: MaybeRefOrGetter<number | undefined>
|
|
14
|
+
/**
|
|
15
|
+
* Visible travel the pulled element tends toward once resisting. Defaults to
|
|
16
|
+
* five times the last stage.
|
|
17
|
+
*/
|
|
18
|
+
maxOffset?: MaybeRefOrGetter<number | undefined>
|
|
19
|
+
/** Called on release when at least one stage was reached. */
|
|
20
|
+
onRelease?: (stage: number) => void
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface Point {
|
|
24
|
+
x: number
|
|
25
|
+
y: number
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const REST: Point = { x: 0, y: 0 }
|
|
29
|
+
|
|
30
|
+
// Travel (px) under which a press still counts as a click, not a drag.
|
|
31
|
+
const DRAG_SLOP = 4
|
|
32
|
+
|
|
33
|
+
// Detent at each stage: the element holds still for this much travel past
|
|
34
|
+
// the threshold, then catches up at double speed over the same distance.
|
|
35
|
+
const DETENT = 8
|
|
36
|
+
|
|
37
|
+
function detentLag (distance: number, stages: number[]) {
|
|
38
|
+
return stages.reduce(
|
|
39
|
+
(lag, threshold) => lag + Math.max(0, DETENT - Math.abs(distance - threshold - DETENT)),
|
|
40
|
+
0,
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Free travel up to `free`, then an iOS-style rubber band lets the visible
|
|
45
|
+
// travel approach `max` asymptotically.
|
|
46
|
+
function resist (distance: number, free: number, max: number) {
|
|
47
|
+
if (distance <= free) return distance
|
|
48
|
+
const tail = max - free
|
|
49
|
+
if (tail <= 0) return free
|
|
50
|
+
const beyond = distance - free
|
|
51
|
+
return free + (tail * beyond) / (beyond + tail)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Pull gesture in any direction with staged thresholds: the element follows
|
|
56
|
+
* the pointer through the stages and resists beyond the last one. Bind the
|
|
57
|
+
* returned pointer handlers to the pulled element and apply `offset` as its
|
|
58
|
+
* translation; on release the state snaps back to rest.
|
|
59
|
+
*/
|
|
60
|
+
export function usePullGesture (options: UsePullGestureOptions) {
|
|
61
|
+
const isPulling = ref(false)
|
|
62
|
+
const delta = ref<Point>(REST)
|
|
63
|
+
let pointerId: number | null = null
|
|
64
|
+
let start: Point = REST
|
|
65
|
+
let didDrag = false
|
|
66
|
+
|
|
67
|
+
const stages = computed(() => toValue(options.stages))
|
|
68
|
+
const enabled = computed(() => stages.value.length > 0)
|
|
69
|
+
const lastStage = computed(() => stages.value[stages.value.length - 1] ?? 0)
|
|
70
|
+
const resistFrom = computed(() => toValue(options.resistFrom) ?? lastStage.value)
|
|
71
|
+
const maxOffset = computed(() => toValue(options.maxOffset) ?? lastStage.value * 5)
|
|
72
|
+
const distance = computed(() => Math.hypot(delta.value.x, delta.value.y))
|
|
73
|
+
const stage = computed(() => stages.value.filter(threshold => distance.value >= threshold).length)
|
|
74
|
+
const offset = computed<Point>(() => {
|
|
75
|
+
if (distance.value === 0) return REST
|
|
76
|
+
const eased = distance.value - detentLag(distance.value, stages.value)
|
|
77
|
+
const ratio = resist(eased, resistFrom.value, maxOffset.value) / distance.value
|
|
78
|
+
return { x: delta.value.x * ratio, y: delta.value.y * ratio }
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
function reset () {
|
|
82
|
+
isPulling.value = false
|
|
83
|
+
delta.value = REST
|
|
84
|
+
pointerId = null
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function onPointerDown (event: PointerEvent) {
|
|
88
|
+
if (!enabled.value || !event.isPrimary || event.button !== 0) return
|
|
89
|
+
pointerId = event.pointerId
|
|
90
|
+
start = { x: event.clientX, y: event.clientY }
|
|
91
|
+
didDrag = false
|
|
92
|
+
isPulling.value = true
|
|
93
|
+
// Keep receiving move/up events once the pointer leaves the element.
|
|
94
|
+
;(event.currentTarget as Element | null)?.setPointerCapture?.(event.pointerId)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function track (event: PointerEvent) {
|
|
98
|
+
delta.value = { x: event.clientX - start.x, y: event.clientY - start.y }
|
|
99
|
+
if (distance.value > DRAG_SLOP) didDrag = true
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function onPointerMove (event: PointerEvent) {
|
|
103
|
+
if (!isPulling.value || event.pointerId !== pointerId) return
|
|
104
|
+
track(event)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function onPointerUp (event: PointerEvent) {
|
|
108
|
+
if (!isPulling.value || event.pointerId !== pointerId) return
|
|
109
|
+
// A fast drag can end past the last delivered move: judge the release position.
|
|
110
|
+
track(event)
|
|
111
|
+
const reached = stage.value
|
|
112
|
+
reset()
|
|
113
|
+
if (reached > 0) options.onRelease?.(reached)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function onPointerCancel (event: PointerEvent) {
|
|
117
|
+
if (event.pointerId !== pointerId) return
|
|
118
|
+
reset()
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Whether the press that just ended was a drag. Lets a click handler ignore
|
|
123
|
+
* the click the browser fires after a drag; the next press starts clean.
|
|
124
|
+
*/
|
|
125
|
+
function consumeDrag () {
|
|
126
|
+
const wasDrag = didDrag
|
|
127
|
+
didDrag = false
|
|
128
|
+
return wasDrag
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return {
|
|
132
|
+
enabled,
|
|
133
|
+
isPulling,
|
|
134
|
+
stage,
|
|
135
|
+
offset,
|
|
136
|
+
onPointerDown,
|
|
137
|
+
onPointerMove,
|
|
138
|
+
onPointerUp,
|
|
139
|
+
onPointerCancel,
|
|
140
|
+
consumeDrag,
|
|
141
|
+
}
|
|
142
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useStorage } from '@vueuse/core'
|
|
2
|
+
import { storedThemingApplies } from './storedThemingApplies'
|
|
2
3
|
import { computed, getCurrentInstance, ref, watch } from 'vue'
|
|
3
4
|
import {
|
|
4
5
|
THEME_LIST,
|
|
@@ -124,10 +125,35 @@ export default function useThemeAndModes (
|
|
|
124
125
|
list.value.set(selector, { element, modeOverride })
|
|
125
126
|
}
|
|
126
127
|
|
|
128
|
+
/**
|
|
129
|
+
* Drops an element from the watch list. The registries outlive every
|
|
130
|
+
* component that registers with them, so an element that unmounts without
|
|
131
|
+
* this stays referenced — and keeps being written to — for the life of the
|
|
132
|
+
* page.
|
|
133
|
+
*
|
|
134
|
+
* The element is part of the descriptor because a selector is a surface, not
|
|
135
|
+
* an instance: where two instances of one surface overlap (a route leaving
|
|
136
|
+
* while its replacement mounts), the leaving one must not drop the entry the
|
|
137
|
+
* incoming one just registered.
|
|
138
|
+
* @param listType Which registry the element was added to.
|
|
139
|
+
* @param descriptor The selector it was registered under, and the element itself.
|
|
140
|
+
* @returns void
|
|
141
|
+
*/
|
|
142
|
+
function removeElementToWatch (
|
|
143
|
+
listType: 'mode' | 'content',
|
|
144
|
+
{ selector, element }: { selector: string, element: HTMLElement }
|
|
145
|
+
) {
|
|
146
|
+
const list = listType === 'mode' ? modeTemplateRefsToWatch : contentTemplateRefsToWatch
|
|
147
|
+
if (list.value.get(selector)?.element === element) {
|
|
148
|
+
list.value.delete(selector)
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
127
152
|
return {
|
|
128
153
|
initOnAppMounted,
|
|
129
154
|
registerWatchers,
|
|
130
155
|
addElementToWatch,
|
|
156
|
+
removeElementToWatch,
|
|
131
157
|
updateContentMode,
|
|
132
158
|
|
|
133
159
|
updateTheme,
|
|
@@ -214,7 +240,8 @@ const DYNAMIC_TOKENS_STORAGE_KEY = 'customThemeTokens'
|
|
|
214
240
|
*/
|
|
215
241
|
function applyStoredDynamicTokens () {
|
|
216
242
|
try {
|
|
217
|
-
|
|
243
|
+
// Seed tokens are picker output — same consumption rule as stored modes.
|
|
244
|
+
if (!storedThemingApplies()) return
|
|
218
245
|
|
|
219
246
|
const stored = localStorage.getItem(DYNAMIC_TOKENS_STORAGE_KEY)
|
|
220
247
|
if (!stored) return
|
package/src/constants/sizes.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const SIZES = ['sm', 'md', 'lg'] as const
|
|
1
|
+
export const SIZES = ['xs', 'sm', 'md', 'lg'] as const
|
|
2
2
|
export type Size = typeof SIZES[number]
|
package/src/css/body.css
CHANGED
|
@@ -14,6 +14,21 @@
|
|
|
14
14
|
line-height: 1.5;
|
|
15
15
|
font-weight: 400;
|
|
16
16
|
color: var(--color-grey-700);
|
|
17
|
+
font-feature-settings: 'cv01', 'cv05', 'cv09', 'cv11', 'ss03';
|
|
18
|
+
font-optical-sizing: auto;
|
|
19
|
+
font-kerning: normal;
|
|
20
|
+
font-synthesis: none;
|
|
21
|
+
text-rendering: optimizeLegibility;
|
|
22
|
+
-webkit-font-smoothing: antialiased;
|
|
23
|
+
-moz-osx-font-smoothing: grayscale;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
h1, h2, h3, h4, h5, h6 {
|
|
27
|
+
text-wrap: balance;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
p {
|
|
31
|
+
text-wrap: pretty;
|
|
17
32
|
}
|
|
18
33
|
}
|
|
19
34
|
|
|
@@ -34,5 +49,5 @@
|
|
|
34
49
|
https://css-tricks.com/almanac/selectors/f/focus-visible/#aa-how-do-browsers-determine-when-something-is-focus-visible
|
|
35
50
|
*/
|
|
36
51
|
*:focus-visible:not(input, .base-input, textarea, .v-popper__popper, .focus-indicator-none, [contenteditable]) {
|
|
37
|
-
@apply
|
|
52
|
+
@apply focus-ring;
|
|
38
53
|
}
|
package/src/css/fonts.css
CHANGED
|
@@ -1,10 +1,44 @@
|
|
|
1
1
|
/*
|
|
2
|
-
Inter
|
|
3
|
-
purpose: a
|
|
4
|
-
|
|
2
|
+
Inter Variable, served from the inter-ui package (OFL-1.1) - kept OUT of
|
|
3
|
+
the base stylesheet (./style) on purpose: loading a font must stay the
|
|
4
|
+
consumer's choice. Apps that want the quick path import this file once:
|
|
5
5
|
|
|
6
6
|
import '@livestorm/ui-vue/fonts'
|
|
7
7
|
|
|
8
|
-
The
|
|
8
|
+
The Latin subsets come last so the browser tries them first; it downloads a
|
|
9
|
+
full file only for text they do not cover. Their unicode-range is the
|
|
10
|
+
subset's own character map.
|
|
9
11
|
*/
|
|
10
|
-
@
|
|
12
|
+
@font-face {
|
|
13
|
+
font-family: 'Inter';
|
|
14
|
+
font-style: normal;
|
|
15
|
+
font-weight: 100 900;
|
|
16
|
+
font-display: swap;
|
|
17
|
+
src: url('inter-ui/variable/InterVariable.woff2') format('woff2');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
@font-face {
|
|
21
|
+
font-family: 'Inter';
|
|
22
|
+
font-style: italic;
|
|
23
|
+
font-weight: 100 900;
|
|
24
|
+
font-display: swap;
|
|
25
|
+
src: url('inter-ui/variable/InterVariable-Italic.woff2') format('woff2');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@font-face {
|
|
29
|
+
font-family: 'Inter';
|
|
30
|
+
font-style: normal;
|
|
31
|
+
font-weight: 100 900;
|
|
32
|
+
font-display: swap;
|
|
33
|
+
src: url('inter-ui/variable-latin/InterVariable-subset.woff2') format('woff2');
|
|
34
|
+
unicode-range: U+0000, U+0020-007E, U+00A0-00AC, U+00AE-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-200B, U+2010-2027, U+202F-2055, U+2057, U+205F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+FEFF;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@font-face {
|
|
38
|
+
font-family: 'Inter';
|
|
39
|
+
font-style: italic;
|
|
40
|
+
font-weight: 100 900;
|
|
41
|
+
font-display: swap;
|
|
42
|
+
src: url('inter-ui/variable-latin/InterVariable-Italic-subset.woff2') format('woff2');
|
|
43
|
+
unicode-range: U+0000, U+0020-007E, U+00A0-00AC, U+00AE-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-200B, U+2010-2027, U+202F-2055, U+2057, U+205F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+FEFF;
|
|
44
|
+
}
|