@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.
Files changed (302) hide show
  1. package/README.md +9 -6
  2. package/components-vite.js +2 -2
  3. package/dist/UiButton-uyW8EHRJ.mjs +602 -0
  4. package/dist/UiTimelineItem-EiOEi1yF.mjs +7293 -0
  5. package/dist/UiTooltip-DZcPD6_N.mjs +158 -0
  6. package/dist/a11y-CaZxRWzo.mjs +6 -0
  7. package/dist/breakpoints.mjs +4 -9
  8. package/dist/bus.mjs +5 -5
  9. package/dist/components.mjs +236 -222
  10. package/dist/i18n-B8QOMuFD.mjs +46 -0
  11. package/dist/index.mjs +4 -87
  12. package/dist/integrations.mjs +3 -14
  13. package/dist/layouts.mjs +228 -236
  14. package/dist/responsive.mjs +31 -36
  15. package/dist/slot.mjs +11 -17
  16. package/dist/toastDSV2-D3xDZPe5.mjs +105 -0
  17. package/dist/types/index.d.ts +23 -1
  18. package/dist/types/src/components/Toast/ToastMessage.vue.d.ts +17 -7
  19. package/dist/types/src/components/Toast/toastDSV2.d.ts +89 -64
  20. package/dist/types/src/components/UiActionBar/UiActionBar.vue.d.ts +3 -1
  21. package/dist/types/src/components/UiActionBar/UiActionBarItem.vue.d.ts +18 -3
  22. package/dist/types/src/components/UiActionBar/types.d.ts +5 -1
  23. package/dist/types/src/components/UiAvatar/UiAvatar.vue.d.ts +4 -2
  24. package/dist/types/src/components/UiAvatarList/UiAvatarList.vue.d.ts +3 -2
  25. package/dist/types/src/components/UiBanner/UiBanner.vue.d.ts +13 -1
  26. package/dist/types/src/components/UiButton/UiButton.vue.d.ts +102 -38
  27. package/dist/types/src/components/UiButtonGroup/UiButtonGroup.vue.d.ts +8 -2
  28. package/dist/types/src/components/UiButtonGroup/UiButtonGroupItem.vue.d.ts +3 -0
  29. package/dist/types/src/components/UiButtonGroup/types.d.ts +5 -1
  30. package/dist/types/src/components/UiChoice/UiChoice.vue.d.ts +71 -0
  31. package/dist/types/src/components/UiChoice/index.d.ts +2 -0
  32. package/dist/types/src/components/UiChoice/types.d.ts +7 -0
  33. package/dist/types/src/components/UiColorField/UiColorField.vue.d.ts +1 -1
  34. package/dist/types/src/components/UiColorPicker/UiColorPicker.vue.d.ts +2 -2
  35. package/dist/types/src/components/UiCombobox/UiCombobox.types.d.ts +47 -0
  36. package/dist/types/src/components/UiCombobox/UiCombobox.vue.d.ts +40 -0
  37. package/dist/types/src/components/UiCombobox/index.d.ts +2 -0
  38. package/dist/types/src/components/UiDataTable/UiDataTable.types.d.ts +46 -0
  39. package/dist/types/src/components/UiDataTable/UiDataTable.vue.d.ts +136 -0
  40. package/dist/types/src/components/UiDataTable/index.d.ts +5 -0
  41. package/dist/types/src/components/UiDrawer/UiDrawer.vue.d.ts +28 -0
  42. package/dist/types/src/components/UiDrawer/UiDrawerContent.vue.d.ts +18 -0
  43. package/dist/types/src/components/UiDrawer/UiDrawerTrigger.vue.d.ts +14 -0
  44. package/dist/types/src/components/UiDropdown/DropdownItemCheckbox.vue.d.ts +3 -0
  45. package/dist/types/src/components/UiDropdown/UiDropdownContent.vue.d.ts +10 -0
  46. package/dist/types/src/components/UiDropdown/UiDropdownGroup.vue.d.ts +17 -0
  47. package/dist/types/src/components/UiDropdown/UiDropdownItem.vue.d.ts +9 -4
  48. package/dist/types/src/components/UiDropdown/UiDropdownTrigger.vue.d.ts +21 -5
  49. package/dist/types/src/components/UiDropdown/index.d.ts +1 -0
  50. package/dist/types/src/components/UiEmojiPickerList/UiEmojiPickerList.vue.d.ts +22 -0
  51. package/dist/types/src/components/UiEmptyState/UiEmptyState.vue.d.ts +8 -3
  52. package/dist/types/src/components/UiFieldWrapper/UiFieldWrapper.vue.d.ts +2 -2
  53. package/dist/types/src/components/UiInputCheckbox/CheckboxGlyph.vue.d.ts +17 -0
  54. package/dist/types/src/components/UiInputCheckbox/UiInputCheckbox.vue.d.ts +35 -4
  55. package/dist/types/src/components/UiInputEmoji/UiInputEmoji.vue.d.ts +45 -0
  56. package/dist/types/src/components/UiInputRadio/RadioGlyph.vue.d.ts +19 -0
  57. package/dist/types/src/components/UiInputRadio/UiInputRadio.vue.d.ts +80 -0
  58. package/dist/types/src/components/UiInputRadio/UiInputRadioGroup.vue.d.ts +86 -0
  59. package/dist/types/src/components/UiInputRadio/types.d.ts +19 -0
  60. package/dist/types/src/components/UiInputSelect/UiInputSelect.vue.d.ts +5 -5
  61. package/dist/types/src/components/UiInputTextarea/UiInputTextarea.vue.d.ts +5 -5
  62. package/dist/types/src/components/UiListItem/UiListItem.vue.d.ts +18 -4
  63. package/dist/types/src/components/UiLoader/UiLoader.vue.d.ts +6 -5
  64. package/dist/types/src/components/UiLoader/UiSpinnerIcon.vue.d.ts +3 -0
  65. package/dist/types/src/components/UiLogo/UiLogo.vue.d.ts +9 -3
  66. package/dist/types/src/components/UiMenu/UiMenuContent.vue.d.ts +15 -2
  67. package/dist/types/src/components/UiMenu/UiMenuItem.vue.d.ts +9 -3
  68. package/dist/types/src/components/UiNestedOptions/UiNestedOptions.vue.d.ts +13 -0
  69. package/dist/types/src/components/UiPage/UiPage.vue.d.ts +106 -8
  70. package/dist/types/src/components/UiPagination/UiPagination.vue.d.ts +36 -0
  71. package/dist/types/src/components/UiPagination/index.d.ts +2 -0
  72. package/dist/types/src/components/UiPagination/types.d.ts +4 -0
  73. package/dist/types/src/components/UiPane/UiPane.vue.d.ts +22 -0
  74. package/dist/types/src/components/UiPane/UiPaneContent.vue.d.ts +75 -0
  75. package/dist/types/src/components/UiPane/UiPaneTrigger.vue.d.ts +14 -0
  76. package/dist/types/src/components/UiPane/index.d.ts +5 -0
  77. package/dist/types/src/components/UiProgress/UiProgress.vue.d.ts +1 -1
  78. package/dist/types/src/components/UiRating/UiRating.vue.d.ts +62 -0
  79. package/dist/types/src/components/UiRating/types.d.ts +1 -0
  80. package/dist/types/src/components/UiRoomButton/UiRoomButton.vue.d.ts +5 -3
  81. package/dist/types/src/components/UiRoomCountdown/UiRoomCountdown.vue.d.ts +32 -0
  82. package/dist/types/src/components/UiShell/UiShell.vue.d.ts +3 -0
  83. package/dist/types/src/components/UiSideMenu/UiSideMenu.vue.d.ts +22 -1
  84. package/dist/types/src/components/UiSideMenu/UiSideMenuItemContent.vue.d.ts +2 -2
  85. package/dist/types/src/components/UiSwitch/UiSwitch.vue.d.ts +114 -0
  86. package/dist/types/src/components/UiSwitch/types.d.ts +3 -0
  87. package/dist/types/src/components/UiTable/UiTable.vue.d.ts +13 -4
  88. package/dist/types/src/components/UiTable/UiTableActionsCell.vue.d.ts +49 -0
  89. package/dist/types/src/components/UiTable/UiTableActionsHeaderCell.vue.d.ts +3 -0
  90. package/dist/types/src/components/UiTable/UiTableBody.vue.d.ts +11 -1
  91. package/dist/types/src/components/UiTable/UiTableCell.vue.d.ts +16 -1
  92. package/dist/types/src/components/UiTable/UiTableHeaderCell.vue.d.ts +31 -2
  93. package/dist/types/src/components/UiTable/UiTableRow.vue.d.ts +32 -2
  94. package/dist/types/src/components/UiTable/context.d.ts +3 -0
  95. package/dist/types/src/components/UiTable/index.d.ts +4 -0
  96. package/dist/types/src/components/UiTabs/UiTabs.vue.d.ts +8 -2
  97. package/dist/types/src/components/UiTag/UiTag.types.d.ts +25 -0
  98. package/dist/types/src/components/UiTag/UiTag.vue.d.ts +5 -26
  99. package/dist/types/src/components/UiTag/index.d.ts +2 -1
  100. package/dist/types/src/components/UiTextField/UiTextField.vue.d.ts +10 -5
  101. package/dist/types/src/components/UiTooltip/UiTooltipProvider.vue.d.ts +1 -0
  102. package/dist/types/src/components/UiTooltip/UiTooltipTrigger.vue.d.ts +2 -2
  103. package/dist/types/src/composables/storedThemingApplies.d.ts +17 -0
  104. package/dist/types/src/composables/useButtonStyles.d.ts +1 -0
  105. package/dist/types/src/composables/useChoiceboxSurface.d.ts +11 -0
  106. package/dist/types/src/composables/useContentMode.d.ts +23 -0
  107. package/dist/types/src/composables/useControlModes.d.ts +7 -0
  108. package/dist/types/src/composables/useControlShape.d.ts +24 -0
  109. package/dist/types/src/composables/useFieldFocusEvents.d.ts +12 -0
  110. package/dist/types/src/composables/useIconSize.d.ts +13 -0
  111. package/dist/types/src/composables/usePullGesture.d.ts +42 -0
  112. package/dist/types/src/composables/useThemeAndModes.d.ts +4 -0
  113. package/dist/types/src/constants/sizes.d.ts +1 -1
  114. package/dist/types/src/theming/colorScale.d.ts +165 -0
  115. package/dist/types/src/theming/legacyColorScale.d.ts +27 -0
  116. package/dist/types/src/theming/presetColors.d.ts +11 -0
  117. package/dist/types/src/theming/primitiveTokens.d.ts +2 -0
  118. package/dist/types/src/utils/effectiveOpacity.d.ts +2 -0
  119. package/dist/types/src/utils/numbers.d.ts +1 -2
  120. package/dist/types/src/utils/tokenColor.d.ts +2 -0
  121. package/dist/ui-vue.css +2 -1
  122. package/dist/utils.mjs +165 -194
  123. package/index.d.ts +22 -0
  124. package/index.js +44 -0
  125. package/package.json +28 -20
  126. package/src/components/Toast/LayoutToasts.vue +19 -11
  127. package/src/components/Toast/ToastMessage.vue +130 -73
  128. package/src/components/Toast/toastDSV2.ts +238 -67
  129. package/src/components/UiActionBar/UiActionBar.vue +15 -5
  130. package/src/components/UiActionBar/UiActionBarItem.vue +65 -38
  131. package/src/components/UiActionBar/types.ts +16 -1
  132. package/src/components/UiAvatar/UiAvatar.vue +9 -3
  133. package/src/components/UiAvatarList/UiAvatarList.vue +51 -20
  134. package/src/components/UiBadge/UiBadge.vue +1 -1
  135. package/src/components/UiBanner/UiBanner.vue +77 -27
  136. package/src/components/UiBreadcrumb/UiBreadcrumb.vue +1 -1
  137. package/src/components/UiButton/UiButton.vue +96 -29
  138. package/src/components/UiButtonGroup/UiButtonGroup.vue +22 -16
  139. package/src/components/UiButtonGroup/UiButtonGroupItem.vue +44 -14
  140. package/src/components/UiButtonGroup/types.ts +20 -1
  141. package/src/components/UiCard/UiCard.vue +20 -23
  142. package/src/components/UiCarousel/UiCarousel.vue +2 -2
  143. package/src/components/UiChoice/UiChoice.vue +187 -0
  144. package/src/components/UiChoice/index.ts +2 -0
  145. package/src/components/UiChoice/types.ts +11 -0
  146. package/src/components/UiColorField/UiColorField.vue +2 -2
  147. package/src/components/UiColorPicker/UiColorPicker.vue +16 -13
  148. package/src/components/UiCombobox/UiCombobox.types.ts +52 -0
  149. package/src/components/UiCombobox/UiCombobox.vue +296 -0
  150. package/src/components/UiCombobox/index.ts +2 -0
  151. package/src/components/UiDataTable/UiDataTable.types.ts +47 -0
  152. package/src/components/UiDataTable/UiDataTable.vue +422 -0
  153. package/src/components/UiDataTable/index.ts +12 -0
  154. package/src/components/UiDialog/UiDialogClose.vue +1 -1
  155. package/src/components/UiDialog/UiDialogContent.vue +22 -7
  156. package/src/components/UiDrawer/UiDrawer.vue +16 -0
  157. package/src/components/UiDrawer/UiDrawerContent.vue +42 -0
  158. package/src/components/UiDrawer/UiDrawerTrigger.vue +17 -0
  159. package/src/components/UiDropdown/DropdownItemCheckbox.vue +10 -0
  160. package/src/components/UiDropdown/UiDropdownContent.vue +32 -21
  161. package/src/components/UiDropdown/UiDropdownGroup.vue +23 -0
  162. package/src/components/UiDropdown/UiDropdownItem.vue +45 -18
  163. package/src/components/UiDropdown/UiDropdownSeparator.vue +1 -1
  164. package/src/components/UiDropdown/UiDropdownTrigger.vue +139 -45
  165. package/src/components/UiDropdown/index.ts +1 -0
  166. package/src/components/UiEmojiPickerList/UiEmojiPickerList.vue +122 -0
  167. package/src/components/UiEmptyState/UiEmptyState.vue +16 -4
  168. package/src/components/UiFieldWrapper/UiFieldWrapper.vue +10 -4
  169. package/src/components/UiHorizontalSeparator/UiHorizontalSeparator.vue +2 -2
  170. package/src/components/UiInputCheckbox/CheckboxGlyph.vue +78 -0
  171. package/src/components/UiInputCheckbox/UiInputCheckbox.vue +213 -177
  172. package/src/components/UiInputEmoji/UiInputEmoji.vue +96 -0
  173. package/src/components/UiInputRadio/RadioGlyph.vue +45 -0
  174. package/src/components/UiInputRadio/UiInputRadio.vue +382 -0
  175. package/src/components/UiInputRadio/UiInputRadioGroup.vue +166 -0
  176. package/src/components/UiInputRadio/types.ts +24 -0
  177. package/src/components/UiInputSelect/UiInputSelect.vue +9 -7
  178. package/src/components/UiInputTextarea/UiInputTextarea.vue +20 -35
  179. package/src/components/UiLabel/UiLabel.vue +1 -1
  180. package/src/components/UiListItem/UiListItem.vue +55 -9
  181. package/src/components/UiLoader/UiLoader.vue +11 -29
  182. package/src/components/UiLoader/UiSpinnerIcon.vue +21 -0
  183. package/src/components/UiLogo/UiLogo.vue +41 -7
  184. package/src/components/UiMenu/UiMenuContent.vue +24 -3
  185. package/src/components/UiMenu/UiMenuGroup.vue +1 -1
  186. package/src/components/UiMenu/UiMenuItem.vue +14 -3
  187. package/src/components/UiMenu/UiMenuSubContent.vue +1 -1
  188. package/src/components/UiMenu/UiMenuSubTrigger.vue +2 -2
  189. package/src/components/UiNestedOptions/UiNestedOptions.vue +6 -0
  190. package/src/components/UiPage/UiPage.vue +273 -47
  191. package/src/components/UiPageHeader/UiPageHeader.vue +29 -9
  192. package/src/components/UiPagination/UiPagination.vue +99 -0
  193. package/src/components/UiPagination/index.ts +2 -0
  194. package/src/components/UiPagination/types.ts +28 -0
  195. package/src/components/UiPane/UiPane.vue +20 -0
  196. package/src/components/UiPane/UiPaneContent.vue +232 -0
  197. package/src/components/UiPane/UiPaneTrigger.vue +14 -0
  198. package/src/components/UiPane/index.ts +12 -0
  199. package/src/components/UiPopover/UiPopoverContent.vue +21 -1
  200. package/src/components/UiProgress/UiProgress.vue +2 -2
  201. package/src/components/UiRating/UiRating.vue +258 -0
  202. package/src/components/UiRating/types.ts +1 -0
  203. package/src/components/UiRoomButton/UiRoomButton.vue +14 -45
  204. package/src/components/UiRoomCountdown/UiRoomCountdown.vue +376 -0
  205. package/src/components/UiShell/UiShell.vue +10 -4
  206. package/src/components/UiSideMenu/UiSideMenu.vue +158 -18
  207. package/src/components/UiSideMenu/UiSideMenuItemContent.vue +22 -18
  208. package/src/components/UiStepper/UiStepper.vue +3 -16
  209. package/src/components/UiStepper/UiStepperDescription.vue +1 -13
  210. package/src/components/UiStepper/UiStepperIndicator.vue +17 -57
  211. package/src/components/UiStepper/UiStepperItem.vue +1 -8
  212. package/src/components/UiStepper/UiStepperSeparator.vue +5 -16
  213. package/src/components/UiStepper/UiStepperTitle.vue +1 -10
  214. package/src/components/UiSwitch/UiSwitch.vue +375 -0
  215. package/src/components/UiSwitch/types.ts +5 -0
  216. package/src/components/UiTable/UiTable.vue +98 -8
  217. package/src/components/UiTable/UiTableActionsCell.vue +135 -0
  218. package/src/components/UiTable/UiTableActionsHeaderCell.vue +19 -0
  219. package/src/components/UiTable/UiTableBody.vue +16 -1
  220. package/src/components/UiTable/UiTableCell.vue +33 -16
  221. package/src/components/UiTable/UiTableHeader.vue +6 -5
  222. package/src/components/UiTable/UiTableHeaderCell.vue +61 -9
  223. package/src/components/UiTable/UiTableRow.vue +46 -10
  224. package/src/components/UiTable/context.ts +5 -0
  225. package/src/components/UiTable/index.ts +4 -0
  226. package/src/components/UiTabs/UiTabs.vue +61 -63
  227. package/src/components/UiTag/UiTag.types.ts +28 -0
  228. package/src/components/UiTag/UiTag.vue +24 -42
  229. package/src/components/UiTag/index.ts +2 -0
  230. package/src/components/UiTextField/UiTextField.vue +27 -47
  231. package/src/components/UiTimeline/README.md +6 -6
  232. package/src/components/UiTimeline/UiTimelineItem.vue +3 -3
  233. package/src/components/UiTooltip/UiTooltipContent.vue +1 -1
  234. package/src/components/UiTooltip/UiTooltipProvider.vue +3 -0
  235. package/src/components/UiTooltip/UiTooltipTrigger.vue +16 -1
  236. package/src/composables/storedThemingApplies.ts +19 -0
  237. package/src/composables/useButtonStyles.ts +9 -13
  238. package/src/composables/useChoiceboxSurface.ts +36 -0
  239. package/src/composables/useContentMode.ts +66 -0
  240. package/src/composables/useControlModes.ts +11 -0
  241. package/src/composables/useControlShape.ts +34 -0
  242. package/src/composables/useFieldFocusEvents.ts +30 -0
  243. package/src/composables/useIconSize.ts +43 -0
  244. package/src/composables/usePullGesture.ts +142 -0
  245. package/src/composables/useThemeAndModes.ts +28 -1
  246. package/src/constants/sizes.ts +1 -1
  247. package/src/css/body.css +16 -1
  248. package/src/css/fonts.css +39 -5
  249. package/src/global.d.ts +44 -0
  250. package/src/theming/colorScale.ts +173 -0
  251. package/src/theming/legacyColorScale.ts +58 -0
  252. package/src/theming/presetColors.ts +33 -0
  253. package/src/theming/primitiveTokens.ts +71 -0
  254. package/src/utils/effectiveOpacity.ts +8 -0
  255. package/src/utils/i18n.ts +6 -0
  256. package/src/utils/numbers.ts +1 -1
  257. package/src/utils/responsive.d.ts +14 -0
  258. package/src/utils/tokenColor.ts +9 -0
  259. package/dist/UiTimelineItem.vue_vue_type_style_index_0_lang-DJFdCn2R.mjs +0 -5456
  260. package/dist/a11y-BhF_nl7L.mjs +0 -159
  261. package/dist/i18n-Cktw9hIu.mjs +0 -49
  262. package/dist/toastDSV2-wMh-UMzW.mjs +0 -74
  263. package/dist/types/src/components/UiAvatar/index.d.ts +0 -1
  264. package/dist/types/src/components/UiAvatarList/index.d.ts +0 -1
  265. package/dist/types/src/components/UiBadge/index.d.ts +0 -1
  266. package/dist/types/src/components/UiBanner/index.d.ts +0 -2
  267. package/dist/types/src/components/UiButtonGroup/index.d.ts +0 -3
  268. package/dist/types/src/components/UiCarousel/index.d.ts +0 -2
  269. package/dist/types/src/components/UiColorField/index.d.ts +0 -2
  270. package/dist/types/src/components/UiDialog/MarketplaceHeaderExample.vue.d.ts +0 -28
  271. package/dist/types/src/components/UiDialog/index.d.ts +0 -7
  272. package/dist/types/src/components/UiFieldWrapper/index.d.ts +0 -1
  273. package/dist/types/src/components/UiInputCheckbox/index.d.ts +0 -2
  274. package/dist/types/src/components/UiInputSelect/index.d.ts +0 -2
  275. package/dist/types/src/components/UiInputTextarea/index.d.ts +0 -2
  276. package/dist/types/src/components/UiMenu/index.d.ts +0 -10
  277. package/dist/types/src/components/UiProgress/index.d.ts +0 -2
  278. package/dist/types/src/components/UiTabs/index.d.ts +0 -2
  279. package/dist/types/src/components/UiTimeline/index.d.ts +0 -2
  280. package/dist/types/src/components/UiTooltip/index.d.ts +0 -4
  281. package/dist/types/src/mixins/DynamicAction.d.ts +0 -30
  282. package/dist/useThemeAndModes-BzYwSOEv.mjs +0 -108
  283. package/src/components/UiAvatar/index.js +0 -1
  284. package/src/components/UiAvatarList/index.js +0 -1
  285. package/src/components/UiBadge/index.ts +0 -2
  286. package/src/components/UiBanner/index.ts +0 -2
  287. package/src/components/UiButtonGroup/index.ts +0 -3
  288. package/src/components/UiCarousel/index.ts +0 -2
  289. package/src/components/UiColorField/index.ts +0 -2
  290. package/src/components/UiDialog/MarketplaceHeaderExample.vue +0 -217
  291. package/src/components/UiDialog/index.ts +0 -18
  292. package/src/components/UiFieldWrapper/index.ts +0 -1
  293. package/src/components/UiInputCheckbox/index.ts +0 -2
  294. package/src/components/UiInputSelect/index.ts +0 -2
  295. package/src/components/UiInputTextarea/index.ts +0 -2
  296. package/src/components/UiMenu/index.ts +0 -10
  297. package/src/components/UiProgress/index.ts +0 -2
  298. package/src/components/UiTabs/index.ts +0 -5
  299. package/src/components/UiTag/index.js +0 -1
  300. package/src/components/UiTimeline/index.ts +0 -2
  301. package/src/components/UiTooltip/index.js +0 -4
  302. 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 class="ui-shell-backgrounds absolute inset-0 grid grid-cols-1 grid-rows-1 z-0">
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-ls-menu"
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 LivestormLogo from '@livestorm/ui-tokens/output/vectors/logos/livestorm-white.svg'
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-blue-600 focus:text-white focus:px-4 focus:py-2 focus:rounded bg-surface-overlay-alpha"
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
- <img
258
+ <div
193
259
  v-if="showLivestormLogo"
194
- :src="LivestormLogo"
195
- :alt="logoAlt"
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-ls-x-stream"
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-ls-more-horizontal"
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 rounded-2xl shadow-shadows-drop-shadow-2xl overflow-hidden data-[state=closed]:hidden"
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 p-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-ls-more-vertical"
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 rounded-2xl shadow-shadows-drop-shadow-2xl overflow-hidden"
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 p-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;