@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
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="ui-room-countdown">
|
|
3
|
+
<div
|
|
4
|
+
class="ui-room-countdown__dial"
|
|
5
|
+
:style="{ '--ui-room-countdown-size': sizeValue }"
|
|
6
|
+
role="timer"
|
|
7
|
+
aria-live="assertive"
|
|
8
|
+
:aria-label="isFinished ? label : `${remaining}`"
|
|
9
|
+
>
|
|
10
|
+
<div
|
|
11
|
+
class="ui-room-countdown__glass"
|
|
12
|
+
:class="{ 'ui-room-countdown__glass--out': live }"
|
|
13
|
+
aria-hidden="true"
|
|
14
|
+
/>
|
|
15
|
+
|
|
16
|
+
<svg
|
|
17
|
+
class="ui-room-countdown__ring"
|
|
18
|
+
:class="{ 'ui-room-countdown__ring--out': live }"
|
|
19
|
+
viewBox="0 0 100 100"
|
|
20
|
+
aria-hidden="true"
|
|
21
|
+
>
|
|
22
|
+
<circle
|
|
23
|
+
class="ui-room-countdown__track"
|
|
24
|
+
cx="50"
|
|
25
|
+
cy="50"
|
|
26
|
+
r="46"
|
|
27
|
+
/>
|
|
28
|
+
<circle
|
|
29
|
+
v-if="!isFinished"
|
|
30
|
+
class="ui-room-countdown__progress"
|
|
31
|
+
cx="50"
|
|
32
|
+
cy="50"
|
|
33
|
+
r="46"
|
|
34
|
+
path-length="1"
|
|
35
|
+
:style="{ animationDuration: `${seconds}s` }"
|
|
36
|
+
/>
|
|
37
|
+
<g
|
|
38
|
+
v-if="!isFinished"
|
|
39
|
+
class="ui-room-countdown__head"
|
|
40
|
+
:style="{ animationDuration: `${seconds}s` }"
|
|
41
|
+
>
|
|
42
|
+
<circle
|
|
43
|
+
cx="50"
|
|
44
|
+
cy="4"
|
|
45
|
+
r="2"
|
|
46
|
+
/>
|
|
47
|
+
</g>
|
|
48
|
+
<circle
|
|
49
|
+
v-if="isStarting"
|
|
50
|
+
class="ui-room-countdown__spinner"
|
|
51
|
+
cx="50"
|
|
52
|
+
cy="50"
|
|
53
|
+
r="46"
|
|
54
|
+
path-length="1"
|
|
55
|
+
/>
|
|
56
|
+
</svg>
|
|
57
|
+
|
|
58
|
+
<Transition
|
|
59
|
+
name="ui-room-countdown-digit"
|
|
60
|
+
mode="out-in"
|
|
61
|
+
>
|
|
62
|
+
<span
|
|
63
|
+
v-if="!isFinished"
|
|
64
|
+
:key="remaining"
|
|
65
|
+
class="ui-room-countdown__digit"
|
|
66
|
+
>
|
|
67
|
+
{{ remaining }}
|
|
68
|
+
</span>
|
|
69
|
+
</Transition>
|
|
70
|
+
|
|
71
|
+
<span
|
|
72
|
+
v-if="isFinished"
|
|
73
|
+
class="ui-room-countdown__label"
|
|
74
|
+
>
|
|
75
|
+
<span
|
|
76
|
+
v-if="live"
|
|
77
|
+
class="ui-room-countdown__rec"
|
|
78
|
+
aria-hidden="true"
|
|
79
|
+
/>
|
|
80
|
+
{{ label }}
|
|
81
|
+
</span>
|
|
82
|
+
</div>
|
|
83
|
+
|
|
84
|
+
<div
|
|
85
|
+
v-if="$slots.action"
|
|
86
|
+
class="ui-room-countdown__action"
|
|
87
|
+
>
|
|
88
|
+
<slot name="action" />
|
|
89
|
+
</div>
|
|
90
|
+
</div>
|
|
91
|
+
</template>
|
|
92
|
+
|
|
93
|
+
<script setup lang="ts">
|
|
94
|
+
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
|
95
|
+
|
|
96
|
+
const props = withDefaults(defineProps<{
|
|
97
|
+
seconds?: number
|
|
98
|
+
label?: string
|
|
99
|
+
size?: 'sm' | 'md' | 'lg'
|
|
100
|
+
finished?: boolean
|
|
101
|
+
live?: boolean
|
|
102
|
+
}>(), {
|
|
103
|
+
seconds: 5,
|
|
104
|
+
label: 'You are live',
|
|
105
|
+
size: 'md',
|
|
106
|
+
finished: false,
|
|
107
|
+
live: false,
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
const emit = defineEmits<{
|
|
111
|
+
tick: [remaining: number]
|
|
112
|
+
finished: []
|
|
113
|
+
}>()
|
|
114
|
+
|
|
115
|
+
const remaining = ref(props.seconds)
|
|
116
|
+
let timer: ReturnType<typeof setInterval> | undefined
|
|
117
|
+
|
|
118
|
+
const isFinished = computed(() => props.finished || remaining.value <= 0)
|
|
119
|
+
|
|
120
|
+
const isStarting = computed(() => isFinished.value && !props.live)
|
|
121
|
+
|
|
122
|
+
const sizeValue = computed(() => ({
|
|
123
|
+
sm: '96px',
|
|
124
|
+
md: '200px',
|
|
125
|
+
lg: '288px',
|
|
126
|
+
}[props.size]))
|
|
127
|
+
|
|
128
|
+
function stop () {
|
|
129
|
+
clearInterval(timer)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
watch(isFinished, (value) => {
|
|
133
|
+
if (!value) return
|
|
134
|
+
|
|
135
|
+
stop()
|
|
136
|
+
emit('finished')
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
onMounted(() => {
|
|
140
|
+
if (isFinished.value) return
|
|
141
|
+
|
|
142
|
+
timer = setInterval(() => {
|
|
143
|
+
remaining.value -= 1
|
|
144
|
+
emit('tick', remaining.value)
|
|
145
|
+
|
|
146
|
+
if (remaining.value <= 0) stop()
|
|
147
|
+
}, 1000)
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
onBeforeUnmount(stop)
|
|
151
|
+
</script>
|
|
152
|
+
|
|
153
|
+
<style scoped>
|
|
154
|
+
@reference '@livestorm/ui-tokens/output/supernova/index.css';
|
|
155
|
+
|
|
156
|
+
.ui-room-countdown {
|
|
157
|
+
@apply flex flex-col items-center gap-6 text-text-neutral-base;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.ui-room-countdown__dial {
|
|
161
|
+
@apply relative grid place-items-center;
|
|
162
|
+
width: var(--ui-room-countdown-size);
|
|
163
|
+
height: var(--ui-room-countdown-size);
|
|
164
|
+
font-size: var(--ui-room-countdown-size);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.ui-room-countdown__glass {
|
|
168
|
+
@apply absolute inset-[7%] rounded-full bg-surface-neutral-alpha-100;
|
|
169
|
+
backdrop-filter: blur(var(--blur-blur-lg));
|
|
170
|
+
transition: all 0.8s cubic-bezier(0.16, 1, 0.3, 1);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.ui-room-countdown__glass::after {
|
|
174
|
+
@apply absolute inset-0 rounded-full content-[''];
|
|
175
|
+
background: radial-gradient(circle, var(--color-surface-neutral-alpha-200) 0%, transparent 70%);
|
|
176
|
+
animation: ui-room-countdown-breath 1.4s ease-in-out infinite;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
.ui-room-countdown__glass--out {
|
|
180
|
+
@apply opacity-0;
|
|
181
|
+
transform: scale(1.2);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.ui-room-countdown__ring {
|
|
185
|
+
@apply absolute inset-0 h-full w-full -rotate-90 overflow-visible;
|
|
186
|
+
fill: none;
|
|
187
|
+
stroke: currentColor;
|
|
188
|
+
stroke-width: 1;
|
|
189
|
+
stroke-linecap: round;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.ui-room-countdown__track {
|
|
193
|
+
@apply opacity-20;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.ui-room-countdown__ring--out {
|
|
197
|
+
@apply opacity-0;
|
|
198
|
+
transform: rotate(-90deg) scale(1.3);
|
|
199
|
+
transition: all 0.8s cubic-bezier(0.16, 1, 0.3, 1);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
.ui-room-countdown__progress {
|
|
203
|
+
stroke-dasharray: 1;
|
|
204
|
+
animation: ui-room-countdown-drain linear forwards;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
.ui-room-countdown__spinner {
|
|
208
|
+
stroke-dasharray: 0.18 0.82;
|
|
209
|
+
transform-origin: 50px 50px;
|
|
210
|
+
animation: ui-room-countdown-spin 1.4s linear infinite;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.ui-room-countdown__head {
|
|
214
|
+
fill: currentColor;
|
|
215
|
+
stroke: none;
|
|
216
|
+
transform-origin: 50px 50px;
|
|
217
|
+
animation: ui-room-countdown-orbit linear forwards;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
.ui-room-countdown__action {
|
|
221
|
+
@apply flex items-center justify-center;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
.ui-room-countdown__digit {
|
|
225
|
+
@apply absolute inset-0 grid place-items-center leading-none;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
.ui-room-countdown__label {
|
|
229
|
+
@apply absolute inset-0 flex items-center justify-center leading-none;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.ui-room-countdown__digit {
|
|
233
|
+
font-size: 0.44em;
|
|
234
|
+
font-weight: 600;
|
|
235
|
+
font-variant-numeric: tabular-nums;
|
|
236
|
+
letter-spacing: -0.03em;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
.ui-room-countdown__label {
|
|
240
|
+
font-size: 0.095em;
|
|
241
|
+
font-weight: 500;
|
|
242
|
+
letter-spacing: -0.01em;
|
|
243
|
+
white-space: nowrap;
|
|
244
|
+
gap: 0.5em;
|
|
245
|
+
animation: ui-room-countdown-zoom 0.6s cubic-bezier(0.16, 1, 0.3, 1) 0.25s backwards;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
.ui-room-countdown__rec {
|
|
249
|
+
@apply relative h-[0.5em] w-[0.5em] shrink-0 rounded-full bg-actions-danger-idle;
|
|
250
|
+
transform-origin: right center;
|
|
251
|
+
animation: ui-room-countdown-rec-in 0.45s cubic-bezier(0.16, 1, 0.3, 1) 0.4s backwards;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
.ui-room-countdown__rec::after {
|
|
255
|
+
@apply absolute inset-0 rounded-full bg-actions-danger-idle content-[''];
|
|
256
|
+
animation: ui-room-countdown-rec-ping 1.8s cubic-bezier(0.16, 1, 0.3, 1) 0.6s infinite;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.ui-room-countdown-digit-enter-active {
|
|
260
|
+
animation: ui-room-countdown-digit-in 0.65s cubic-bezier(0.16, 1, 0.3, 1);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
.ui-room-countdown-digit-leave-active {
|
|
264
|
+
transition: all 0.22s cubic-bezier(0.7, 0, 0.84, 0);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
.ui-room-countdown-digit-leave-to {
|
|
268
|
+
opacity: 0;
|
|
269
|
+
filter: blur(0.03em);
|
|
270
|
+
transform: scale(0.6);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
@keyframes ui-room-countdown-drain {
|
|
274
|
+
to {
|
|
275
|
+
stroke-dashoffset: 1;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
@keyframes ui-room-countdown-digit-in {
|
|
280
|
+
0% {
|
|
281
|
+
opacity: 0;
|
|
282
|
+
filter: blur(0.03em);
|
|
283
|
+
transform: scale(1.3);
|
|
284
|
+
}
|
|
285
|
+
45% {
|
|
286
|
+
opacity: 1;
|
|
287
|
+
filter: blur(0);
|
|
288
|
+
}
|
|
289
|
+
70% {
|
|
290
|
+
transform: scale(0.98);
|
|
291
|
+
}
|
|
292
|
+
100% {
|
|
293
|
+
opacity: 1;
|
|
294
|
+
filter: blur(0);
|
|
295
|
+
transform: scale(1);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
@keyframes ui-room-countdown-breath {
|
|
300
|
+
0%,
|
|
301
|
+
100% {
|
|
302
|
+
opacity: 0.4;
|
|
303
|
+
transform: scale(0.9);
|
|
304
|
+
}
|
|
305
|
+
50% {
|
|
306
|
+
opacity: 0.9;
|
|
307
|
+
transform: scale(1.05);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
@keyframes ui-room-countdown-spin {
|
|
312
|
+
to {
|
|
313
|
+
transform: rotate(360deg);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
@keyframes ui-room-countdown-orbit {
|
|
318
|
+
to {
|
|
319
|
+
transform: rotate(360deg);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
@keyframes ui-room-countdown-zoom {
|
|
324
|
+
from {
|
|
325
|
+
opacity: 0;
|
|
326
|
+
filter: blur(0.02em);
|
|
327
|
+
transform: scale(0.88);
|
|
328
|
+
}
|
|
329
|
+
to {
|
|
330
|
+
opacity: 1;
|
|
331
|
+
filter: blur(0);
|
|
332
|
+
transform: scale(1);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
@keyframes ui-room-countdown-rec-in {
|
|
337
|
+
from {
|
|
338
|
+
opacity: 0;
|
|
339
|
+
transform: scale(0.5);
|
|
340
|
+
margin-right: -1em;
|
|
341
|
+
}
|
|
342
|
+
to {
|
|
343
|
+
opacity: 1;
|
|
344
|
+
transform: scale(1);
|
|
345
|
+
margin-right: 0;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
@keyframes ui-room-countdown-rec-ping {
|
|
350
|
+
from {
|
|
351
|
+
opacity: 0.45;
|
|
352
|
+
transform: scale(1);
|
|
353
|
+
}
|
|
354
|
+
to {
|
|
355
|
+
opacity: 0;
|
|
356
|
+
transform: scale(2.2);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
@media (prefers-reduced-motion: reduce) {
|
|
361
|
+
.ui-room-countdown__progress,
|
|
362
|
+
.ui-room-countdown__spinner,
|
|
363
|
+
.ui-room-countdown__label,
|
|
364
|
+
.ui-room-countdown__glass,
|
|
365
|
+
.ui-room-countdown__glass::after,
|
|
366
|
+
.ui-room-countdown__rec,
|
|
367
|
+
.ui-room-countdown__rec::after,
|
|
368
|
+
.ui-room-countdown__head,
|
|
369
|
+
.ui-room-countdown__ring--out,
|
|
370
|
+
.ui-room-countdown-digit-enter-active,
|
|
371
|
+
.ui-room-countdown-digit-leave-active {
|
|
372
|
+
animation: none;
|
|
373
|
+
transition: none;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
</style>
|
|
@@ -6,8 +6,11 @@ import UiButton from '../UiButton/UiButton.vue'
|
|
|
6
6
|
|
|
7
7
|
const props = withDefaults(defineProps<{
|
|
8
8
|
openMenuLabel?: string
|
|
9
|
+
/** The shell canvas (gradient and overlays). Off when the host paints its own surface. */
|
|
10
|
+
showBackground?: boolean
|
|
9
11
|
}>(), {
|
|
10
12
|
openMenuLabel: 'Menu',
|
|
13
|
+
showBackground: true,
|
|
11
14
|
})
|
|
12
15
|
|
|
13
16
|
const slots = useSlots() as {
|
|
@@ -29,7 +32,10 @@ const fallbackLabel = computed(() => menuLabel.value ?? props.openMenuLabel)
|
|
|
29
32
|
class="ui-shell h-dvh flex flex-col relative"
|
|
30
33
|
data-sizes-primitives="Mode-1"
|
|
31
34
|
>
|
|
32
|
-
<div
|
|
35
|
+
<div
|
|
36
|
+
v-if="showBackground"
|
|
37
|
+
class="ui-shell-backgrounds absolute inset-0 grid grid-cols-1 grid-rows-1 z-0"
|
|
38
|
+
>
|
|
33
39
|
<div class="ui-shell-background col-span-full row-span-full bg-gradient-to-tl from-surface-primary-100 to-surface-primary-300" />
|
|
34
40
|
<div class="ui-shell-background col-span-full row-span-full bg-surface-neutral-invert-alpha-600" />
|
|
35
41
|
<div class="ui-shell-background col-span-full row-span-full bg-surface-primary-alpha-100" />
|
|
@@ -44,7 +50,7 @@ const fallbackLabel = computed(() => menuLabel.value ?? props.openMenuLabel)
|
|
|
44
50
|
<div class="flex-1 flex w-full relative min-h-0">
|
|
45
51
|
<div
|
|
46
52
|
v-if="slots.sidemenu"
|
|
47
|
-
class="dashboard-sidebar md:flex shrink-0 text-text-neutral-base flex z-40"
|
|
53
|
+
class="dashboard-sidebar md:flex shrink-0 text-text-neutral-base flex z-40 [anchor-name:--ui-shell-side-menu]"
|
|
48
54
|
>
|
|
49
55
|
<slot
|
|
50
56
|
name="sidemenu"
|
|
@@ -52,7 +58,7 @@ const fallbackLabel = computed(() => menuLabel.value ?? props.openMenuLabel)
|
|
|
52
58
|
/>
|
|
53
59
|
</div>
|
|
54
60
|
|
|
55
|
-
<div class="dashboard-content flex-1 flex flex-col z-10 min-h-0">
|
|
61
|
+
<div class="dashboard-content flex-1 flex flex-col z-10 min-w-0 min-h-0">
|
|
56
62
|
<!--
|
|
57
63
|
Fallback mobile menu trigger. The hamburger normally lives in
|
|
58
64
|
UiPageHeader, but a page can render without a header — leaving no way
|
|
@@ -69,7 +75,7 @@ const fallbackLabel = computed(() => menuLabel.value ?? props.openMenuLabel)
|
|
|
69
75
|
<UiButton
|
|
70
76
|
color="neutral"
|
|
71
77
|
variant="tertiary"
|
|
72
|
-
icon="i-
|
|
78
|
+
icon="i-ph-list"
|
|
73
79
|
:aria-label="fallbackLabel"
|
|
74
80
|
@click="toggle"
|
|
75
81
|
/>
|
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import
|
|
3
|
-
import type { Slot } from 'vue'
|
|
2
|
+
import type { ComponentPublicInstance, Slot } from 'vue'
|
|
4
3
|
import type { SideMenuCollapsedItem, SideMenuItemProps, SideMenuMoreItem } from './types'
|
|
5
4
|
import UiSideMenuItem from './UiSideMenuItem.vue'
|
|
5
|
+
import UiLogo from '../UiLogo/UiLogo.vue'
|
|
6
6
|
import UiButton from '../UiButton/UiButton.vue'
|
|
7
7
|
import UiPopover from '../UiPopover/UiPopover.vue'
|
|
8
8
|
import UiPopoverTrigger from '../UiPopover/UiPopoverTrigger.vue'
|
|
9
9
|
import UiPopoverContent from '../UiPopover/UiPopoverContent.vue'
|
|
10
|
+
import UiTooltipProvider from '../UiTooltip/UiTooltipProvider.vue'
|
|
11
|
+
import UiTooltip from '../UiTooltip/UiTooltip.vue'
|
|
12
|
+
import UiTooltipTrigger from '../UiTooltip/UiTooltipTrigger.vue'
|
|
13
|
+
import UiTooltipContent from '../UiTooltip/UiTooltipContent.vue'
|
|
10
14
|
import { useMobileMenu } from '../../composables/useMobileMenu'
|
|
15
|
+
import { usePullGesture } from '../../composables/usePullGesture'
|
|
11
16
|
import { useTranslate } from '../../utils/i18n'
|
|
12
|
-
import { focusFirstMenuItem } from '../../utils'
|
|
13
|
-
import { computed, onBeforeUnmount, onMounted, provide, ref } from 'vue'
|
|
17
|
+
import { focusFirstMenuItem } from '../../utils/a11y'
|
|
18
|
+
import { computed, onBeforeUnmount, onMounted, provide, ref, watch } from 'vue'
|
|
14
19
|
import { SIDE_MENU_LAYOUT_KEY } from './injection'
|
|
15
20
|
const { close, isOpen } = useMobileMenu()
|
|
16
21
|
const translate = useTranslate()
|
|
@@ -81,6 +86,8 @@ const slots = defineSlots<{
|
|
|
81
86
|
* `close` callback to dismiss the popover (e.g. when a nested popover opens).
|
|
82
87
|
*/
|
|
83
88
|
collapsedMenuExtra?(props: { close: () => void }): Slot
|
|
89
|
+
/** Tooltip shown under the logo while it is pulled, with the stage reached so far. */
|
|
90
|
+
logoPullHint?(props: { stage: number }): Slot
|
|
84
91
|
}>()
|
|
85
92
|
|
|
86
93
|
const props = withDefaults(defineProps<{
|
|
@@ -105,6 +112,16 @@ const props = withDefaults(defineProps<{
|
|
|
105
112
|
*/
|
|
106
113
|
moreBadge?: number | boolean
|
|
107
114
|
showLivestormLogo?: boolean
|
|
115
|
+
/**
|
|
116
|
+
* Pointer travel (px, ascending) at which pulling the logo, in any
|
|
117
|
+
* direction, reaches each stage; `logoPull` emits the stage reached on
|
|
118
|
+
* release. Empty disables the gesture.
|
|
119
|
+
*/
|
|
120
|
+
logoPullStages?: number[]
|
|
121
|
+
/** Travel (px) after which the pulled logo starts resisting; defaults to the last stage. */
|
|
122
|
+
logoPullResistFrom?: number
|
|
123
|
+
/** Visible travel the resisting logo tends toward; defaults to five times the last stage. */
|
|
124
|
+
logoPullMaxOffset?: number
|
|
108
125
|
// Accessibility labels
|
|
109
126
|
logoAlt?: string
|
|
110
127
|
closeMenuLabel?: string
|
|
@@ -116,6 +133,9 @@ const props = withDefaults(defineProps<{
|
|
|
116
133
|
organizationId?: string
|
|
117
134
|
}>(), {
|
|
118
135
|
showLivestormLogo: true,
|
|
136
|
+
logoPullStages: () => [],
|
|
137
|
+
logoPullResistFrom: undefined,
|
|
138
|
+
logoPullMaxOffset: undefined,
|
|
119
139
|
logoAlt: 'Livestorm',
|
|
120
140
|
closeMenuLabel: 'Close navigation menu',
|
|
121
141
|
mainNavigationLabel: 'Main navigation',
|
|
@@ -162,7 +182,53 @@ const hasCollapsedMenu = computed(
|
|
|
162
182
|
() => (!!props.collapsedMenuItems && props.collapsedMenuItems.length > 0) || !!slots.collapsedMenuExtra,
|
|
163
183
|
)
|
|
164
184
|
|
|
185
|
+
const emit = defineEmits<{
|
|
186
|
+
logoPull: [stage: number]
|
|
187
|
+
}>()
|
|
188
|
+
|
|
189
|
+
const pull = usePullGesture({
|
|
190
|
+
stages: () => props.logoPullStages,
|
|
191
|
+
resistFrom: () => props.logoPullResistFrom,
|
|
192
|
+
maxOffset: () => props.logoPullMaxOffset,
|
|
193
|
+
onRelease: stage => emit('logoPull', stage),
|
|
194
|
+
})
|
|
195
|
+
|
|
196
|
+
// A lean toward the pull and a size step per stage make the gesture legible;
|
|
197
|
+
// grabbing shrinks the logo a touch, as if lifted out of its socket.
|
|
198
|
+
const LOGO_PULL_DEG_PER_PX = 0.15
|
|
199
|
+
const LOGO_PULL_MAX_DEG = 30
|
|
200
|
+
const LOGO_PULL_GRAB_SHRINK_PCT = 4
|
|
201
|
+
const LOGO_PULL_STAGE_GROWTH_PCT = 6
|
|
202
|
+
|
|
203
|
+
const logoPullStyle = computed(() => {
|
|
204
|
+
if (!pull.enabled.value) return undefined
|
|
205
|
+
const { x, y } = pull.offset.value
|
|
206
|
+
const shrink = pull.isPulling.value ? LOGO_PULL_GRAB_SHRINK_PCT : 0
|
|
207
|
+
const lean = Math.max(-LOGO_PULL_MAX_DEG, Math.min(LOGO_PULL_MAX_DEG, x * LOGO_PULL_DEG_PER_PX))
|
|
208
|
+
return {
|
|
209
|
+
translate: `${x}px ${y}px`,
|
|
210
|
+
rotate: `${lean}deg`,
|
|
211
|
+
scale: String((100 - shrink + pull.stage.value * LOGO_PULL_STAGE_GROWTH_PCT) / 100),
|
|
212
|
+
}
|
|
213
|
+
})
|
|
214
|
+
|
|
215
|
+
// Each new stage ticks: a quick overshoot of the logo and a haptic where
|
|
216
|
+
// supported. Reduced motion keeps the haptic only.
|
|
217
|
+
const logo = ref<ComponentPublicInstance | null>(null)
|
|
218
|
+
watch(pull.stage, (stage, previous) => {
|
|
219
|
+
if (stage <= previous) return
|
|
220
|
+
if ('vibrate' in navigator) navigator.vibrate(10)
|
|
221
|
+
if (window.matchMedia?.('(prefers-reduced-motion: reduce)').matches) return
|
|
222
|
+
const el = logo.value?.$el as HTMLElement | undefined
|
|
223
|
+
el?.animate?.(
|
|
224
|
+
[{ transform: 'scale(1)' }, { transform: 'scale(1.18)', offset: 0.4 }, { transform: 'scale(1)' }],
|
|
225
|
+
{ duration: 220, easing: 'ease-out' },
|
|
226
|
+
)
|
|
227
|
+
})
|
|
228
|
+
|
|
165
229
|
function handleLogoClick (event: MouseEvent) {
|
|
230
|
+
// The browser still fires a click after a pull; keep it off the click count.
|
|
231
|
+
if (pull.consumeDrag()) return
|
|
166
232
|
if (event.detail === 4) {
|
|
167
233
|
if (navigator.clipboard && props.organizationId) {
|
|
168
234
|
navigator.clipboard.writeText(props.organizationId)
|
|
@@ -182,24 +248,66 @@ function handleLogoClick (event: MouseEvent) {
|
|
|
182
248
|
<!-- Skip link for accessibility -->
|
|
183
249
|
<router-link
|
|
184
250
|
to="/"
|
|
185
|
-
class="sr-only focus:not-sr-only focus:absolute focus:top-4 focus:left-4 focus:z-50 focus:bg-
|
|
251
|
+
class="sr-only focus:not-sr-only focus:absolute focus:top-4 focus:left-4 focus:z-50 focus:bg-actions-primary-idle focus:text-text-neutral-invert-base focus:px-4 focus:py-2 focus:rounded-row bg-surface-overlay-alpha"
|
|
186
252
|
>
|
|
187
253
|
{{ skipToMainContentLabel }}
|
|
188
254
|
</router-link>
|
|
189
255
|
<!-- Top -->
|
|
190
256
|
<div class="flex flex-col md:items-center gap-8">
|
|
191
257
|
<div class="flex items-center justify-between">
|
|
192
|
-
<
|
|
258
|
+
<div
|
|
193
259
|
v-if="showLivestormLogo"
|
|
194
|
-
|
|
195
|
-
:
|
|
196
|
-
class="w-10 h-10 ml-4 md:ml-0"
|
|
197
|
-
role="img"
|
|
198
|
-
@click="handleLogoClick"
|
|
260
|
+
class="relative ml-4 md:ml-0"
|
|
261
|
+
:class="{ 'z-10': pull.enabled.value }"
|
|
199
262
|
>
|
|
263
|
+
<div
|
|
264
|
+
v-if="pull.enabled.value"
|
|
265
|
+
class="logo-pull-socket absolute top-0 left-0 w-10 h-10 rounded-[35%] pointer-events-none"
|
|
266
|
+
:class="{ 'logo-pull-socket-visible': pull.isPulling.value }"
|
|
267
|
+
/>
|
|
268
|
+
<!-- Controlled tooltip: shown only while pulling, never on hover. -->
|
|
269
|
+
<UiTooltipProvider>
|
|
270
|
+
<UiTooltip :open="!!slots.logoPullHint && pull.isPulling.value">
|
|
271
|
+
<UiTooltipTrigger as-child>
|
|
272
|
+
<div
|
|
273
|
+
:class="{
|
|
274
|
+
'logo-pull touch-none select-none cursor-grab': pull.enabled.value,
|
|
275
|
+
'logo-pull-active cursor-grabbing': pull.isPulling.value,
|
|
276
|
+
}"
|
|
277
|
+
:style="logoPullStyle"
|
|
278
|
+
@pointerdown="pull.onPointerDown"
|
|
279
|
+
@pointermove="pull.onPointerMove"
|
|
280
|
+
@pointerup="pull.onPointerUp"
|
|
281
|
+
@pointercancel="pull.onPointerCancel"
|
|
282
|
+
@click="handleLogoClick"
|
|
283
|
+
>
|
|
284
|
+
<UiLogo
|
|
285
|
+
ref="logo"
|
|
286
|
+
:height="2.5"
|
|
287
|
+
:width="2.5"
|
|
288
|
+
:themed="false"
|
|
289
|
+
:animated="false"
|
|
290
|
+
inverted="auto"
|
|
291
|
+
:label="logoAlt"
|
|
292
|
+
/>
|
|
293
|
+
</div>
|
|
294
|
+
</UiTooltipTrigger>
|
|
295
|
+
<UiTooltipContent
|
|
296
|
+
side="bottom"
|
|
297
|
+
:side-offset="8"
|
|
298
|
+
update-position-strategy="always"
|
|
299
|
+
>
|
|
300
|
+
<slot
|
|
301
|
+
name="logoPullHint"
|
|
302
|
+
:stage="pull.stage.value"
|
|
303
|
+
/>
|
|
304
|
+
</UiTooltipContent>
|
|
305
|
+
</UiTooltip>
|
|
306
|
+
</UiTooltipProvider>
|
|
307
|
+
</div>
|
|
200
308
|
<div class="md:hidden">
|
|
201
309
|
<UiButton
|
|
202
|
-
icon="i-
|
|
310
|
+
icon="i-ph-x"
|
|
203
311
|
variant="tertiary"
|
|
204
312
|
color="neutral"
|
|
205
313
|
size="lg"
|
|
@@ -289,7 +397,7 @@ function handleLogoClick (event: MouseEvent) {
|
|
|
289
397
|
<UiPopoverTrigger class="w-full cursor-pointer">
|
|
290
398
|
<UiSideMenuItem
|
|
291
399
|
:label="translate('room_bottom-bar_controls-label_more')"
|
|
292
|
-
icon="i-
|
|
400
|
+
icon="i-ph-dots-three"
|
|
293
401
|
:is-active="false"
|
|
294
402
|
:inside-interactive="true"
|
|
295
403
|
:badge="moreBadge"
|
|
@@ -308,14 +416,14 @@ function handleLogoClick (event: MouseEvent) {
|
|
|
308
416
|
:align="isMobile ? 'center' : 'end'"
|
|
309
417
|
:side-offset="8"
|
|
310
418
|
:collision-padding="16"
|
|
311
|
-
class="border-none bg-surface-neutral-300
|
|
419
|
+
class="border-none bg-surface-neutral-300 shadow-shadows-drop-shadow-2xl overflow-hidden data-[state=closed]:hidden"
|
|
312
420
|
:class="isMobile
|
|
313
421
|
? 'w-(--reka-popover-trigger-width)'
|
|
314
422
|
: 'w-[calc(var(--reka-popover-trigger-width)+2rem)]'"
|
|
315
423
|
data-colors-semantic="light"
|
|
316
424
|
@open-auto-focus="handleOpenAutoFocus"
|
|
317
425
|
>
|
|
318
|
-
<ul class="flex flex-col md:items-center gap-2
|
|
426
|
+
<ul class="flex flex-col md:items-center gap-2 px-1 py-2">
|
|
319
427
|
<li
|
|
320
428
|
v-for="item in collapsedMenuItems"
|
|
321
429
|
:key="`collapsed-menu-item-${item.label}`"
|
|
@@ -420,7 +528,7 @@ function handleLogoClick (event: MouseEvent) {
|
|
|
420
528
|
<UiPopoverTrigger class="cursor-pointer">
|
|
421
529
|
<UiSideMenuItem
|
|
422
530
|
:label="translate('room_bottom-bar_controls-label_more')"
|
|
423
|
-
icon="i-
|
|
531
|
+
icon="i-ph-dots-three-vertical"
|
|
424
532
|
:is-active="false"
|
|
425
533
|
:inside-interactive="true"
|
|
426
534
|
/>
|
|
@@ -429,11 +537,11 @@ function handleLogoClick (event: MouseEvent) {
|
|
|
429
537
|
side="right"
|
|
430
538
|
align="end"
|
|
431
539
|
:side-offset="8"
|
|
432
|
-
class="border-none bg-surface-neutral-300
|
|
540
|
+
class="border-none bg-surface-neutral-300 shadow-shadows-drop-shadow-2xl overflow-hidden"
|
|
433
541
|
data-colors-semantic="light"
|
|
434
542
|
@open-auto-focus="handleOpenAutoFocus"
|
|
435
543
|
>
|
|
436
|
-
<div class="flex flex-col md:items-center gap-2
|
|
544
|
+
<div class="flex flex-col md:items-center gap-2 px-1 py-2">
|
|
437
545
|
<li
|
|
438
546
|
v-for="item in bottomMenuItems"
|
|
439
547
|
:key="`popover-menu-item-${item.label}`"
|
|
@@ -486,6 +594,38 @@ function handleLogoClick (event: MouseEvent) {
|
|
|
486
594
|
</template>
|
|
487
595
|
|
|
488
596
|
<style scoped>
|
|
597
|
+
/* Logo pull: free while dragging, springs back on release. */
|
|
598
|
+
.logo-pull {
|
|
599
|
+
transition:
|
|
600
|
+
translate 400ms cubic-bezier(0.34, 1.56, 0.64, 1),
|
|
601
|
+
rotate 400ms cubic-bezier(0.34, 1.56, 0.64, 1),
|
|
602
|
+
scale 150ms ease-out;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
.logo-pull-active {
|
|
606
|
+
transition: scale 150ms ease-out;
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
/* Recess left where the logo rests; lingers until the logo has landed. */
|
|
610
|
+
.logo-pull-socket {
|
|
611
|
+
background: rgb(0 0 0 / 0.12);
|
|
612
|
+
box-shadow: inset 0 1px 3px rgb(0 0 0 / 0.25);
|
|
613
|
+
opacity: 0;
|
|
614
|
+
transition: opacity 200ms ease 250ms;
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
.logo-pull-socket-visible {
|
|
618
|
+
opacity: 1;
|
|
619
|
+
transition-delay: 0ms;
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
@media (prefers-reduced-motion: reduce) {
|
|
623
|
+
.logo-pull,
|
|
624
|
+
.logo-pull-socket {
|
|
625
|
+
transition: none;
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
|
|
489
629
|
/* Hide the more menu by default */
|
|
490
630
|
.show-on-short-height-desktop-only {
|
|
491
631
|
display: none;
|