@leavepulse/ui 0.68.0 → 0.70.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 (640) hide show
  1. package/README.md +37 -0
  2. package/dist/assets/LoaderMark-DxBV2iDJ.css +43 -0
  3. package/dist/assets/LpActivityLine-B3EwNQEB.css +33 -0
  4. package/dist/assets/{LpCommandPalette-DxyjhYn_.css → LpCommandPalette-u-zOxKWa.css} +21 -31
  5. package/dist/assets/LpDock-Cbh0wQUv.css +17 -0
  6. package/dist/assets/{LpDropzone-Qb8k7cg4.css → LpDropzone-Bb1vBTeU.css} +12 -17
  7. package/dist/assets/{LpImageEditor-CElPDzpF.css → LpImageEditor-XM5bAziW.css} +6 -6
  8. package/dist/assets/LpLogViewer-BDNW6P52.css +38 -0
  9. package/dist/assets/{LpPalettePreview-CJmAKgYW.css → LpPalettePreview-B9VKDrvA.css} +2 -7
  10. package/dist/assets/LpShinyText-D69cBYDR.css +61 -0
  11. package/dist/assets/LpStatus-430OGTZY.css +17 -0
  12. package/dist/assets/LpStepMark-Drvx33Vg.css +10 -0
  13. package/dist/assets/{LpTable-BPERfJIk.css → LpTable-DHxEQ_-3.css} +19 -19
  14. package/dist/assets/LpTabs-BJ-nrJuI.css +18 -0
  15. package/dist/assets/LpTextReveal-DjI1MsDS.css +35 -0
  16. package/dist/assets/LpTypewriter-CXAm9Nca.css +27 -0
  17. package/dist/chunks/AttentionDot-DCBf4aWg.js +25 -0
  18. package/dist/chunks/{ContextMenuItems-B7XFHksm.js → ContextMenuItems-B5uE8Znw.js} +1 -1
  19. package/dist/chunks/{DropzoneLinkField-CjkrpDqO.js → DropzoneLinkField-Bw8Flkhk.js} +2 -2
  20. package/dist/chunks/FieldWrapper-BiennROB.js +43 -0
  21. package/dist/chunks/{LayoutCanvas-DF9CovaK.js → LayoutCanvas-BsJIzhdd.js} +1 -1
  22. package/dist/chunks/{LayoutNode-D9bIFzk0.js → LayoutNode-DJVhkSGk.js} +6 -8
  23. package/dist/chunks/LegendSwatch-BhRjrtzv.js +18 -0
  24. package/dist/chunks/LoaderMark-C1dubiKn.js +85 -0
  25. package/dist/chunks/{LpActionBar-MPKMu3pz.js → LpActionBar-CzOFar5t.js} +14 -20
  26. package/dist/chunks/LpActivityLine-CJvzrNpj.js +95 -0
  27. package/dist/chunks/{LpAddressInput-DG0BTqdH.js → LpAddressInput-CNnLTDZg.js} +7 -7
  28. package/dist/chunks/LpAlert-C5igj802.js +119 -0
  29. package/dist/chunks/{LpAppShell-DPh1756q.js → LpAppShell-CEUAB8kK.js} +15 -16
  30. package/dist/chunks/{LpAutocomplete-Dgn6hw3p.js → LpAutocomplete-D92niDHE.js} +15 -32
  31. package/dist/chunks/{LpAvatar-Bs0Fb1lC.js → LpAvatar-CLPl-qOF.js} +18 -6
  32. package/dist/chunks/LpBadge-HOEPBYmi.js +126 -0
  33. package/dist/chunks/LpBreadcrumbs-DYoPc3P4.js +144 -0
  34. package/dist/chunks/{LpButton-DNR-YAq5.js → LpButton-CVxBfGjd.js} +12 -4
  35. package/dist/chunks/{LpCalendar-BLya39Fh.js → LpCalendar-pVL91-Pl.js} +1 -1
  36. package/dist/chunks/{LpCard-Bf71NXZq.js → LpCard-CqKLnEhl.js} +18 -8
  37. package/dist/chunks/{LpCheckbox-Da5oZPHo.js → LpCheckbox-DHc2bHDe.js} +9 -6
  38. package/dist/chunks/{LpCodeBlock-lLbmslfs.js → LpCodeBlock-BGsQhxw8.js} +24 -32
  39. package/dist/chunks/LpCodeDisplay-CIKKT2iW.js +189 -0
  40. package/dist/chunks/LpCollapse-CWS9M_lm.js +115 -0
  41. package/dist/chunks/{LpColorPicker-DtEfBAcK.js → LpColorPicker-DFugXNUi.js} +10 -5
  42. package/dist/chunks/{LpConfirmDialog-D7s4jakB.js → LpConfirmDialog-CfGCux8m.js} +3 -3
  43. package/dist/chunks/{LpConfirmHost-DrYI5y1K.js → LpConfirmHost-exB7JmcO.js} +1 -1
  44. package/dist/chunks/{LpContextMenu-CRnjoqSt.js → LpContextMenu-COwOwRgI.js} +13 -5
  45. package/dist/chunks/LpCopyButton-DzHjnFs0.js +133 -0
  46. package/dist/chunks/LpCountdown-Dtq1ihlJ.js +231 -0
  47. package/dist/chunks/LpDataList-B-5nHfNw.js +120 -0
  48. package/dist/chunks/LpDatePicker-BUe1VUC0.js +168 -0
  49. package/dist/chunks/LpDateRangePicker-C_k65vGR.js +126 -0
  50. package/dist/chunks/{LpDisclosure-6AplYBub.js → LpDisclosure-DOarzlAG.js} +22 -11
  51. package/dist/chunks/{LpDrawer-Q4SOxM4s.js → LpDrawer-DGNKRsGq.js} +9 -4
  52. package/dist/chunks/{LpDropdownMenu-DWTt0ooM.js → LpDropdownMenu-CRgrhdAH.js} +10 -5
  53. package/dist/chunks/LpEditable-DTqLt2lT.js +236 -0
  54. package/dist/chunks/{LpEmptyState-om1UnFjV.js → LpEmptyState-KTKipws2.js} +1 -1
  55. package/dist/chunks/{LpFieldNotice-CHuDeLjc.js → LpFieldNotice-CurbNuXI.js} +1 -1
  56. package/dist/chunks/{LpFileTree-CW24YsVX.js → LpFileTree-DMISXVHC.js} +5 -3
  57. package/dist/chunks/{LpFileTreeNode-BXhTHaKW.js → LpFileTreeNode-CPXB_Yy3.js} +42 -55
  58. package/dist/chunks/{LpFormField-DPb47HEm.js → LpFormField-BWwgm1E4.js} +23 -9
  59. package/dist/chunks/LpFrame-BVQCQLDI.js +155 -0
  60. package/dist/chunks/LpGauge-Bk8TwJj0.js +204 -0
  61. package/dist/chunks/LpGlowBorder-B8V-QzIl.js +40 -0
  62. package/dist/chunks/{LpHintExample-C1eKYdeL.js → LpHintExample-9Py0wc-L.js} +11 -34
  63. package/dist/chunks/{LpHintLayer-7UOdWQG3.js → LpHintLayer-p4hqzdyA.js} +27 -14
  64. package/dist/chunks/{LpHints-BUtBp9-w.js → LpHints-CCrhRfy9.js} +3 -3
  65. package/dist/chunks/LpHoverCard-spGxyw7T.js +130 -0
  66. package/dist/chunks/{LpIcon-6tSrZ3Zy.js → LpIcon-HJP5xMz4.js} +1 -1
  67. package/dist/chunks/LpIdenticon-BzdC_qz9.js +63 -0
  68. package/dist/chunks/{LpInfraNode-Ds_8SZgN.js → LpInfraNode-CUC3t4na.js} +39 -25
  69. package/dist/chunks/{LpInput-CUyr6PIE.js → LpInput-CDuwODJG.js} +44 -18
  70. package/dist/chunks/{LpLightbox-B9J8rzsj.js → LpLightbox-XJ0LpTcZ.js} +69 -69
  71. package/dist/chunks/LpLoader-DjJEX8hL.js +92 -0
  72. package/dist/chunks/{LpLogViewer-4QFc-sVN.js → LpLogViewer-elZHbj85.js} +225 -129
  73. package/dist/chunks/LpMagnetic-CtXKLa2Y.js +62 -0
  74. package/dist/chunks/{LpMapPicker-BTbkFeSG.js → LpMapPicker-BtIl7NOM.js} +34 -31
  75. package/dist/chunks/LpMasonry--k0571qG.js +185 -0
  76. package/dist/chunks/{LpMediaGallery-CuPcscx3.js → LpMediaGallery-D5swlmZ_.js} +3 -3
  77. package/dist/chunks/{LpModal-hk1noDcr.js → LpModal-eBMt2Fqn.js} +8 -3
  78. package/dist/chunks/{LpModalNav-DQd2keZm.js → LpModalNav-D4Z0wVHR.js} +4 -4
  79. package/dist/chunks/{LpNotificationBell-X84PJIxD.js → LpNotificationBell-DPZmP5dM.js} +32 -48
  80. package/dist/chunks/LpNumberField-B9k-h2HE.js +140 -0
  81. package/dist/chunks/{LpNumberFlow-z4WPZcZu.js → LpNumberFlow-Cfyh033Q.js} +8 -28
  82. package/dist/chunks/{LpOtpInput-PbeNJ5In.js → LpOtpInput-CeBPsM7D.js} +2 -1
  83. package/dist/chunks/{LpPagination-Bx-VG4Ag.js → LpPagination-VNCX6pFC.js} +37 -6
  84. package/dist/chunks/{LpPalettePreview-CFav_7co.js → LpPalettePreview-BNB8T_MY.js} +1 -1
  85. package/dist/chunks/{LpPasswordInput-CbnXitAS.js → LpPasswordInput-DTV18FIh.js} +20 -20
  86. package/dist/chunks/{LpPhoneInput-DP69HONS.js → LpPhoneInput-C60tx1tC.js} +12 -7
  87. package/dist/chunks/{LpPie-yLF9-aDR.js → LpPie-CFuV7pZv.js} +158 -47
  88. package/dist/chunks/LpPipeline-D81yh_NX.js +329 -0
  89. package/dist/chunks/{LpPopover-DVnkHaOu.js → LpPopover-BEIcqb9p.js} +8 -3
  90. package/dist/chunks/{LpProgress-CA86wxXu.js → LpProgress-CE-m5OpD.js} +23 -63
  91. package/dist/chunks/LpQuota-2Sw_gqcJ.js +162 -0
  92. package/dist/chunks/{LpRadioGroup-8S5hf8lE.js → LpRadioGroup-CGBr5nIp.js} +1 -1
  93. package/dist/chunks/{LpRangeCalendar-ByQi-WUz.js → LpRangeCalendar-c5qj7YcC.js} +1 -1
  94. package/dist/chunks/{LpRangeSlider-C1yF9-nP.js → LpRangeSlider-Dv6lNvHY.js} +6 -2
  95. package/dist/chunks/LpRelativeTime-CKzVqAo9.js +73 -0
  96. package/dist/chunks/LpRepeater-D0VjmD6y.js +140 -0
  97. package/dist/chunks/LpRevealOnScroll-DcQjexLy.js +76 -0
  98. package/dist/chunks/LpScramble-TDO5Kdou.js +85 -0
  99. package/dist/chunks/LpSecretField-DMfdJ1cQ.js +307 -0
  100. package/dist/chunks/{LpSection-BmRXe6ZP.js → LpSection-BW4xJ-Li.js} +1 -1
  101. package/dist/chunks/{LpSegmented-CW3bFHM4.js → LpSegmented-BO99Sr4m.js} +11 -14
  102. package/dist/chunks/{LpSelect-BCyDYoih.js → LpSelect-B4f_yRi5.js} +93 -108
  103. package/dist/chunks/LpShaderBackdrop-Bote0iuy.js +332 -0
  104. package/dist/chunks/LpShinyText-DX2ajtWq.js +48 -0
  105. package/dist/chunks/{LpSidebar-DfIiS-lB.js → LpSidebar-D-M0Y_7U.js} +5 -3
  106. package/dist/chunks/{LpSidebarNav-C5FDNI0t.js → LpSidebarNav-DF-TYxOV.js} +3 -3
  107. package/dist/chunks/{LpSlider-Cuzmrd7p.js → LpSlider-DuoRpOrH.js} +6 -2
  108. package/dist/chunks/{LpSparkline-DXT4KrSi.js → LpSparkline-CExIRDb3.js} +32 -27
  109. package/dist/chunks/LpSpotlight-4F3NeUMY.js +41 -0
  110. package/dist/chunks/{LpStat-iBMF5QNk.js → LpStat-B2ix1Q7t.js} +38 -35
  111. package/dist/chunks/LpStatus-C7kx5PKE.js +86 -0
  112. package/dist/chunks/LpStepMark-DK-5BKAt.js +101 -0
  113. package/dist/chunks/LpStepper-DRFfdJaq.js +76 -0
  114. package/dist/chunks/{LpSwap-D82jiecV.js → LpSwap-DzE6M3Mg.js} +1 -1
  115. package/dist/chunks/LpSwitch-DrzKrZZV.js +112 -0
  116. package/dist/chunks/{LpTableFilter-CuIbgdW0.js → LpTableFilter-DyvHGbOk.js} +3 -2
  117. package/dist/chunks/{LpTableOfContents-C_4VBktT.js → LpTableOfContents-rYvo8z5T.js} +34 -21
  118. package/dist/chunks/{LpTagsInput-DiXrpYeE.js → LpTagsInput-DgpBFRV2.js} +68 -71
  119. package/dist/chunks/LpTextReveal-CtAnOUkp.js +140 -0
  120. package/dist/chunks/{LpTextarea-xoQd5Lnp.js → LpTextarea-DiWjeVoJ.js} +12 -11
  121. package/dist/chunks/{LpThemeProvider-CQ2jC9TA.js → LpThemeProvider-DcbfOxsU.js} +1 -1
  122. package/dist/chunks/LpThemeStudio-DguwHdGt.js +416 -0
  123. package/dist/chunks/LpThemeStudioSection-BwhqYDLf.js +20 -0
  124. package/dist/chunks/LpThemeSwitcher-D5uz0MhK.js +278 -0
  125. package/dist/chunks/{LpTimeField-MFgAsNc5.js → LpTimeField-BFQVf_PW.js} +13 -5
  126. package/dist/chunks/{LpToaster-C4zE9zB7.js → LpToaster-Wv9ksj4q.js} +49 -82
  127. package/dist/chunks/{LpTooltip-suFCM34F.js → LpTooltip-Cz8SQwRt.js} +8 -3
  128. package/dist/chunks/{LpTopologyCanvas-6ozNrQKh.js → LpTopologyCanvas-ZhKthfgz.js} +1 -1
  129. package/dist/chunks/{LpTour-BUp3Jt2e.js → LpTour-NfRJNEIP.js} +24 -18
  130. package/dist/chunks/LpTruncate-D_5Pfv5B.js +112 -0
  131. package/dist/chunks/LpTypewriter-BCL_a6wE.js +159 -0
  132. package/dist/chunks/{LpUptimeBar-B6kHw4Cj.js → LpUptimeBar-DWegV2p6.js} +9 -8
  133. package/dist/chunks/{LpVideoBackdrop-qWRYBOTQ.js → LpVideoBackdrop-DS1wGv-X.js} +7 -8
  134. package/dist/chunks/{MenuTitle-obgek0B7.js → MenuTitle-BjQZX8tQ.js} +1 -1
  135. package/dist/chunks/OptionContent-CmYUUeWj.js +40 -0
  136. package/dist/chunks/PickerField-CHRS1h7K.js +116 -0
  137. package/dist/chunks/RevealToggle-C-KzaQGJ.js +65 -0
  138. package/dist/chunks/StepConnector-37OgEOXA.js +41 -0
  139. package/dist/chunks/TourCard-BXuVHsfn.js +123 -0
  140. package/dist/chunks/backdrop-Dkf2vM81.js +59 -0
  141. package/dist/chunks/{icons-DVhZ_plB.js → icons-4IywzkHk.js} +1 -1
  142. package/dist/chunks/{useTheme-2qHG8NEU.js → useTheme-BOV_-AiY.js} +9 -65
  143. package/dist/component-names.d.ts +1 -1
  144. package/dist/components/AttentionDot.vue.d.ts +9 -0
  145. package/dist/components/AttentionDot.vue.js +4 -0
  146. package/dist/components/ContextMenuItems.vue.js +1 -1
  147. package/dist/components/DropzoneLinkField.vue.js +1 -1
  148. package/dist/components/FieldWrapper.vue.d.ts +25 -0
  149. package/dist/components/FieldWrapper.vue.js +4 -0
  150. package/dist/components/LayoutCanvas.vue.js +1 -1
  151. package/dist/components/LayoutNode.vue.d.ts +4 -4
  152. package/dist/components/LayoutNode.vue.js +1 -1
  153. package/dist/components/LegendSwatch.vue.d.ts +6 -0
  154. package/dist/components/LegendSwatch.vue.js +4 -0
  155. package/dist/components/LoaderMark.vue.d.ts +12 -0
  156. package/dist/components/LoaderMark.vue.js +4 -0
  157. package/dist/components/LpActionBar.vue.js +1 -1
  158. package/dist/components/LpActivityLine.vue.d.ts +58 -0
  159. package/dist/components/LpActivityLine.vue.js +4 -0
  160. package/dist/components/LpAddressInput.vue.js +1 -1
  161. package/dist/components/LpAlert.vue.d.ts +2 -2
  162. package/dist/components/LpAlert.vue.js +1 -1
  163. package/dist/components/LpAppShell.vue.d.ts +8 -7
  164. package/dist/components/LpAppShell.vue.js +1 -1
  165. package/dist/components/LpAutocomplete.vue.js +1 -1
  166. package/dist/components/LpAvatar.vue.d.ts +16 -0
  167. package/dist/components/LpAvatar.vue.js +1 -1
  168. package/dist/components/LpBadge.vue.d.ts +19 -5
  169. package/dist/components/LpBadge.vue.js +1 -1
  170. package/dist/components/LpBreadcrumbs.vue.js +1 -1
  171. package/dist/components/LpButton.vue.d.ts +2 -2
  172. package/dist/components/LpButton.vue.js +1 -1
  173. package/dist/components/LpCalendar.vue.js +1 -1
  174. package/dist/components/LpCard.vue.d.ts +24 -0
  175. package/dist/components/LpCard.vue.js +1 -1
  176. package/dist/components/LpChart.vue.d.ts +10 -0
  177. package/dist/components/LpChart.vue.js +122 -142
  178. package/dist/components/LpCheckbox.vue.d.ts +2 -2
  179. package/dist/components/LpCheckbox.vue.js +1 -1
  180. package/dist/components/LpCodeBlock.vue.js +1 -1
  181. package/dist/components/LpCodeDisplay.vue.d.ts +89 -0
  182. package/dist/components/LpCodeDisplay.vue.js +4 -0
  183. package/dist/components/LpCollapse.vue.d.ts +58 -0
  184. package/dist/components/LpCollapse.vue.js +4 -0
  185. package/dist/components/LpColorPicker.vue.d.ts +2 -2
  186. package/dist/components/LpColorPicker.vue.js +1 -1
  187. package/dist/components/LpCommandPalette.vue.js +34 -23
  188. package/dist/components/LpConfirmDialog.vue.js +1 -1
  189. package/dist/components/LpConfirmHost.vue.js +1 -1
  190. package/dist/components/LpContextMenu.vue.js +1 -1
  191. package/dist/components/LpCopyButton.vue.d.ts +82 -0
  192. package/dist/components/LpCopyButton.vue.js +4 -0
  193. package/dist/components/LpCountdown.vue.d.ts +100 -0
  194. package/dist/components/LpCountdown.vue.js +4 -0
  195. package/dist/components/LpDataList.vue.d.ts +66 -0
  196. package/dist/components/LpDataList.vue.js +4 -0
  197. package/dist/components/LpDatePicker.vue.d.ts +1 -1
  198. package/dist/components/LpDatePicker.vue.js +1 -1
  199. package/dist/components/LpDateRangePicker.vue.d.ts +1 -1
  200. package/dist/components/LpDateRangePicker.vue.js +1 -1
  201. package/dist/components/LpDisclosure.vue.js +1 -1
  202. package/dist/components/LpDock.vue.d.ts +74 -0
  203. package/dist/components/LpDock.vue.js +204 -0
  204. package/dist/components/LpDrawer.vue.js +1 -1
  205. package/dist/components/LpDropdownMenu.vue.js +1 -1
  206. package/dist/components/LpDropzone.vue.d.ts +8 -1
  207. package/dist/components/LpDropzone.vue.js +36 -15
  208. package/dist/components/LpEditable.vue.d.ts +85 -0
  209. package/dist/components/LpEditable.vue.js +4 -0
  210. package/dist/components/LpEmptyState.vue.js +1 -1
  211. package/dist/components/LpFieldNotice.vue.js +1 -1
  212. package/dist/components/LpFileTree.vue.js +1 -1
  213. package/dist/components/LpFileTreeNode.vue.js +1 -1
  214. package/dist/components/LpFormField.vue.js +1 -1
  215. package/dist/components/LpFrame.vue.d.ts +22 -0
  216. package/dist/components/LpFrame.vue.js +4 -0
  217. package/dist/components/LpGauge.vue.d.ts +116 -0
  218. package/dist/components/LpGauge.vue.js +4 -0
  219. package/dist/components/LpGlowBorder.vue.d.ts +47 -0
  220. package/dist/components/LpGlowBorder.vue.js +4 -0
  221. package/dist/components/LpHintExample.vue.d.ts +2 -2
  222. package/dist/components/LpHintExample.vue.js +1 -1
  223. package/dist/components/LpHintLayer.vue.js +1 -1
  224. package/dist/components/LpHints.vue.js +1 -1
  225. package/dist/components/LpHoverCard.vue.d.ts +60 -0
  226. package/dist/components/LpHoverCard.vue.js +4 -0
  227. package/dist/components/LpIcon.vue.js +1 -1
  228. package/dist/components/LpIdenticon.vue.d.ts +37 -0
  229. package/dist/components/LpIdenticon.vue.js +4 -0
  230. package/dist/components/LpImageEditor.vue.js +13 -19
  231. package/dist/components/LpInfraNode.vue.js +1 -1
  232. package/dist/components/LpInput.vue.d.ts +10 -0
  233. package/dist/components/LpInput.vue.js +1 -1
  234. package/dist/components/LpLightbox.vue.js +1 -1
  235. package/dist/components/LpLoader.vue.d.ts +106 -0
  236. package/dist/components/LpLoader.vue.js +4 -0
  237. package/dist/components/LpLogViewer.vue.js +1 -1
  238. package/dist/components/LpMagnetic.vue.d.ts +28 -0
  239. package/dist/components/LpMagnetic.vue.js +4 -0
  240. package/dist/components/LpMapPicker.vue.js +1 -1
  241. package/dist/components/LpMasonry.vue.d.ts +42 -0
  242. package/dist/components/LpMasonry.vue.js +4 -0
  243. package/dist/components/LpMediaGallery.vue.js +1 -1
  244. package/dist/components/LpModal.vue.js +1 -1
  245. package/dist/components/LpModalNav.vue.js +1 -1
  246. package/dist/components/LpNotificationBell.vue.d.ts +15 -6
  247. package/dist/components/LpNotificationBell.vue.js +1 -1
  248. package/dist/components/LpNumberField.vue.d.ts +57 -0
  249. package/dist/components/LpNumberField.vue.js +1 -1
  250. package/dist/components/LpNumberFlow.vue.js +1 -1
  251. package/dist/components/LpOtpInput.vue.d.ts +12 -4
  252. package/dist/components/LpOtpInput.vue.js +1 -1
  253. package/dist/components/LpPagination.vue.js +1 -1
  254. package/dist/components/LpPaletteFacts.vue.js +1 -1
  255. package/dist/components/LpPaletteHeader.vue.js +2 -2
  256. package/dist/components/LpPalettePreview.vue.js +1 -1
  257. package/dist/components/LpPaletteStats.vue.js +1 -1
  258. package/dist/components/LpPasswordInput.vue.d.ts +12 -1
  259. package/dist/components/LpPasswordInput.vue.js +1 -1
  260. package/dist/components/LpPhoneInput.vue.js +1 -1
  261. package/dist/components/LpPie.vue.d.ts +3 -1
  262. package/dist/components/LpPie.vue.js +1 -1
  263. package/dist/components/LpPipeline.vue.d.ts +91 -0
  264. package/dist/components/LpPipeline.vue.js +4 -0
  265. package/dist/components/LpPopover.vue.d.ts +2 -2
  266. package/dist/components/LpPopover.vue.js +1 -1
  267. package/dist/components/LpProgress.vue.d.ts +11 -4
  268. package/dist/components/LpProgress.vue.js +1 -1
  269. package/dist/components/LpQuota.vue.d.ts +68 -0
  270. package/dist/components/LpQuota.vue.js +4 -0
  271. package/dist/components/LpRadioGroup.vue.js +1 -1
  272. package/dist/components/LpRangeCalendar.vue.js +1 -1
  273. package/dist/components/LpRangeSlider.vue.js +1 -1
  274. package/dist/components/LpRelativeTime.vue.d.ts +41 -0
  275. package/dist/components/LpRelativeTime.vue.js +4 -0
  276. package/dist/components/LpRepeater.vue.d.ts +48 -0
  277. package/dist/components/LpRepeater.vue.js +4 -0
  278. package/dist/components/LpRevealOnScroll.vue.d.ts +67 -0
  279. package/dist/components/LpRevealOnScroll.vue.js +4 -0
  280. package/dist/components/LpRollingText.vue.d.ts +1 -1
  281. package/dist/components/LpScramble.vue.d.ts +55 -0
  282. package/dist/components/LpScramble.vue.js +4 -0
  283. package/dist/components/LpScrollArea.vue.d.ts +1 -1
  284. package/dist/components/LpSecretField.vue.d.ts +108 -0
  285. package/dist/components/LpSecretField.vue.js +4 -0
  286. package/dist/components/LpSection.vue.js +1 -1
  287. package/dist/components/LpSegmented.vue.js +1 -1
  288. package/dist/components/LpSelect.vue.d.ts +2 -0
  289. package/dist/components/LpSelect.vue.js +1 -1
  290. package/dist/components/LpShaderBackdrop.vue.d.ts +39 -0
  291. package/dist/components/LpShaderBackdrop.vue.js +4 -0
  292. package/dist/components/LpShinyText.vue.d.ts +39 -0
  293. package/dist/components/LpShinyText.vue.js +4 -0
  294. package/dist/components/LpShortcutsDialog.vue.js +1 -1
  295. package/dist/components/LpSidebar.vue.js +1 -1
  296. package/dist/components/LpSidebarNav.vue.js +1 -1
  297. package/dist/components/LpSlider.vue.js +1 -1
  298. package/dist/components/LpSparkline.vue.d.ts +4 -3
  299. package/dist/components/LpSparkline.vue.js +1 -1
  300. package/dist/components/LpSpotlight.vue.d.ts +37 -0
  301. package/dist/components/LpSpotlight.vue.js +4 -0
  302. package/dist/components/LpStat.vue.js +1 -1
  303. package/dist/components/LpStatus.vue.d.ts +65 -0
  304. package/dist/components/LpStatus.vue.js +4 -0
  305. package/dist/components/LpStepMark.vue.d.ts +31 -0
  306. package/dist/components/LpStepMark.vue.js +4 -0
  307. package/dist/components/LpStepper.vue.js +1 -1
  308. package/dist/components/LpSwap.vue.js +1 -1
  309. package/dist/components/LpSwitch.vue.d.ts +2 -2
  310. package/dist/components/LpSwitch.vue.js +1 -1
  311. package/dist/components/LpTable.vue.js +104 -120
  312. package/dist/components/LpTableFilter.vue.js +1 -1
  313. package/dist/components/LpTableOfContents.vue.d.ts +6 -1
  314. package/dist/components/LpTableOfContents.vue.js +1 -1
  315. package/dist/components/LpTabs.vue.d.ts +5 -5
  316. package/dist/components/LpTabs.vue.js +25 -33
  317. package/dist/components/LpTagsInput.vue.js +1 -1
  318. package/dist/components/LpTextReveal.vue.d.ts +58 -0
  319. package/dist/components/LpTextReveal.vue.js +4 -0
  320. package/dist/components/LpTextarea.vue.js +1 -1
  321. package/dist/components/LpThemeProvider.vue.js +1 -1
  322. package/dist/components/LpThemeStudio.vue.d.ts +54 -0
  323. package/dist/components/LpThemeStudio.vue.js +4 -0
  324. package/dist/components/LpThemeStudioSection.vue.d.ts +16 -0
  325. package/dist/components/LpThemeStudioSection.vue.js +4 -0
  326. package/dist/components/LpThemeSwitcher.vue.d.ts +32 -1
  327. package/dist/components/LpThemeSwitcher.vue.js +1 -1
  328. package/dist/components/LpTimeField.vue.d.ts +2 -0
  329. package/dist/components/LpTimeField.vue.js +1 -1
  330. package/dist/components/LpToaster.vue.js +1 -1
  331. package/dist/components/LpTooltip.vue.d.ts +2 -2
  332. package/dist/components/LpTooltip.vue.js +1 -1
  333. package/dist/components/LpTopologyCanvas.vue.js +1 -1
  334. package/dist/components/LpTour.vue.js +1 -1
  335. package/dist/components/LpTruncate.vue.d.ts +34 -0
  336. package/dist/components/LpTruncate.vue.js +4 -0
  337. package/dist/components/LpTypewriter.vue.d.ts +61 -0
  338. package/dist/components/LpTypewriter.vue.js +4 -0
  339. package/dist/components/LpUptimeBar.vue.js +1 -1
  340. package/dist/components/LpVideoBackdrop.vue.js +1 -1
  341. package/dist/components/MenuTitle.vue.js +1 -1
  342. package/dist/components/OptionContent.vue.d.ts +7 -0
  343. package/dist/components/OptionContent.vue.js +4 -0
  344. package/dist/components/PickerField.vue.d.ts +43 -0
  345. package/dist/components/PickerField.vue.js +4 -0
  346. package/dist/components/RevealToggle.vue.d.ts +21 -0
  347. package/dist/components/RevealToggle.vue.js +4 -0
  348. package/dist/components/StepConnector.vue.d.ts +19 -0
  349. package/dist/components/StepConnector.vue.js +4 -0
  350. package/dist/components/TourCard.vue.js +1 -1
  351. package/dist/components/badge.d.ts +1 -0
  352. package/dist/components/badge.js +4 -0
  353. package/dist/components/chart.d.ts +5 -1
  354. package/dist/components/chart.js +2 -21
  355. package/dist/components/dateRange.d.ts +11 -0
  356. package/dist/components/dateRange.js +12 -0
  357. package/dist/components/dock.d.ts +19 -0
  358. package/dist/components/dock.js +16 -0
  359. package/dist/components/dropdown.d.ts +10 -1
  360. package/dist/components/dropdown.js +7 -2
  361. package/dist/components/fieldText.d.ts +38 -0
  362. package/dist/components/fieldText.js +53 -0
  363. package/dist/components/fileTree.d.ts +7 -3
  364. package/dist/components/fileTree.js +12 -18
  365. package/dist/components/format.d.ts +41 -0
  366. package/dist/components/format.js +67 -0
  367. package/dist/components/identicon.d.ts +38 -0
  368. package/dist/components/identicon.js +85 -0
  369. package/dist/components/masonry.d.ts +32 -0
  370. package/dist/components/masonry.js +40 -0
  371. package/dist/components/menuWhen.js +1 -1
  372. package/dist/components/meter.d.ts +64 -0
  373. package/dist/components/meter.js +53 -0
  374. package/dist/components/otp.d.ts +1 -1
  375. package/dist/components/otp.js +7 -2
  376. package/dist/components/pipeline.d.ts +55 -0
  377. package/dist/components/pipeline.js +51 -0
  378. package/dist/components/quota.d.ts +57 -0
  379. package/dist/components/quota.js +40 -0
  380. package/dist/components/relativeTime.d.ts +24 -0
  381. package/dist/components/relativeTime.js +56 -0
  382. package/dist/components/reveal.d.ts +18 -0
  383. package/dist/components/reveal.js +32 -0
  384. package/dist/components/scramble.d.ts +68 -0
  385. package/dist/components/scramble.js +58 -0
  386. package/dist/components/shaderBackdrop.d.ts +20 -0
  387. package/dist/components/shaderBackdrop.js +156 -0
  388. package/dist/components/slider.d.ts +5 -0
  389. package/dist/components/slider.js +24 -0
  390. package/dist/components/slotText.d.ts +2 -0
  391. package/dist/components/slotText.js +9 -0
  392. package/dist/components/status.d.ts +14 -0
  393. package/dist/components/status.js +22 -0
  394. package/dist/components/tableFacets.d.ts +8 -0
  395. package/dist/components/tableFacets.js +19 -0
  396. package/dist/components/textSplit.d.ts +17 -0
  397. package/dist/components/textSplit.js +24 -0
  398. package/dist/components/timeSpan.d.ts +78 -0
  399. package/dist/components/timeSpan.js +85 -0
  400. package/dist/components/tone.d.ts +43 -0
  401. package/dist/components/tone.js +82 -0
  402. package/dist/components/tour.js +3 -2
  403. package/dist/components/typewriter.d.ts +36 -0
  404. package/dist/components/typewriter.js +53 -0
  405. package/dist/components/videoBackdrop.js +5 -6
  406. package/dist/composables/easing.d.ts +22 -1
  407. package/dist/composables/easing.js +42 -1
  408. package/dist/composables/pseudoLocale.d.ts +15 -0
  409. package/dist/composables/pseudoLocale.js +96 -0
  410. package/dist/composables/scroll.js +5 -3
  411. package/dist/composables/useClipboard.d.ts +4 -1
  412. package/dist/composables/useClipboard.js +12 -2
  413. package/dist/composables/useField.d.ts +8 -0
  414. package/dist/composables/useField.js +5 -0
  415. package/dist/composables/useForm.js +19 -5
  416. package/dist/composables/useHintSystem.d.ts +4 -0
  417. package/dist/composables/useHintSystem.js +33 -1
  418. package/dist/composables/useHints.js +9 -3
  419. package/dist/composables/useInView.d.ts +11 -0
  420. package/dist/composables/useInView.js +39 -0
  421. package/dist/composables/useLoadingGate.d.ts +8 -0
  422. package/dist/composables/useLoadingGate.js +38 -0
  423. package/dist/composables/useLpConfig.d.ts +10 -0
  424. package/dist/composables/useLpConfig.js +11 -1
  425. package/dist/composables/useMediaQuery.js +3 -1
  426. package/dist/composables/useNow.d.ts +16 -0
  427. package/dist/composables/useNow.js +39 -0
  428. package/dist/composables/usePersisted.js +14 -7
  429. package/dist/composables/usePillTransition.d.ts +5 -2
  430. package/dist/composables/usePillTransition.js +4 -3
  431. package/dist/composables/usePointerFrame.d.ts +18 -0
  432. package/dist/composables/usePointerFrame.js +31 -0
  433. package/dist/composables/useReducedMotion.d.ts +2 -0
  434. package/dist/composables/useReducedMotion.js +7 -0
  435. package/dist/composables/useRepeater.d.ts +17 -0
  436. package/dist/composables/useRepeater.js +31 -0
  437. package/dist/composables/useResizeObserver.d.ts +8 -0
  438. package/dist/composables/useResizeObserver.js +33 -0
  439. package/dist/composables/useRevealedValue.d.ts +31 -0
  440. package/dist/composables/useRevealedValue.js +26 -0
  441. package/dist/composables/useScramble.d.ts +42 -0
  442. package/dist/composables/useScramble.js +76 -0
  443. package/dist/composables/useShift.js +2 -10
  444. package/dist/composables/useSpotlight.d.ts +18 -0
  445. package/dist/composables/useSpotlight.js +53 -0
  446. package/dist/composables/useTilt.js +26 -18
  447. package/dist/composables/useTween.d.ts +43 -0
  448. package/dist/composables/useTween.js +69 -0
  449. package/dist/composables/useView.d.ts +18 -0
  450. package/dist/composables/useView.js +61 -0
  451. package/dist/icons-all.js +1 -1
  452. package/dist/index.d.ts +98 -1
  453. package/dist/index.js +262 -104
  454. package/dist/theme/define.d.ts +12 -0
  455. package/dist/theme/studio.d.ts +90 -0
  456. package/package.json +5 -2
  457. package/src/component-names.ts +33 -0
  458. package/src/components/AttentionDot.vue +27 -0
  459. package/src/components/FieldWrapper.vue +38 -0
  460. package/src/components/LayoutNode.vue +5 -9
  461. package/src/components/LegendSwatch.vue +15 -0
  462. package/src/components/LoaderMark.vue +90 -0
  463. package/src/components/LpActionBar.vue +12 -20
  464. package/src/components/LpActivityLine.vue +186 -0
  465. package/src/components/LpAlert.vue +54 -24
  466. package/src/components/LpAppShell.vue +7 -11
  467. package/src/components/LpAutocomplete.vue +16 -14
  468. package/src/components/LpAvatar.vue +17 -2
  469. package/src/components/LpBadge.vue +77 -13
  470. package/src/components/LpBreadcrumbs.vue +101 -35
  471. package/src/components/LpButton.vue +15 -3
  472. package/src/components/LpCard.vue +30 -7
  473. package/src/components/LpChart.vue +152 -156
  474. package/src/components/LpCheckbox.vue +10 -4
  475. package/src/components/LpCodeBlock.vue +11 -19
  476. package/src/components/LpCodeDisplay.vue +228 -0
  477. package/src/components/LpCollapse.vue +162 -0
  478. package/src/components/LpColorPicker.vue +10 -1
  479. package/src/components/LpCommandPalette.vue +38 -24
  480. package/src/components/LpContextMenu.vue +10 -1
  481. package/src/components/LpCopyButton.vue +185 -0
  482. package/src/components/LpCountdown.vue +308 -0
  483. package/src/components/LpDataList.vue +154 -0
  484. package/src/components/LpDatePicker.vue +53 -104
  485. package/src/components/LpDateRangePicker.vue +49 -95
  486. package/src/components/LpDisclosure.vue +58 -36
  487. package/src/components/LpDock.vue +274 -0
  488. package/src/components/LpDrawer.vue +10 -1
  489. package/src/components/LpDropdownMenu.vue +10 -1
  490. package/src/components/LpDropzone.vue +34 -13
  491. package/src/components/LpEditable.vue +293 -0
  492. package/src/components/LpFileTree.vue +5 -1
  493. package/src/components/LpFileTreeNode.vue +25 -50
  494. package/src/components/LpFormField.vue +22 -3
  495. package/src/components/LpFrame.vue +200 -0
  496. package/src/components/LpGauge.vue +287 -0
  497. package/src/components/LpGlowBorder.vue +60 -0
  498. package/src/components/LpHintExample.vue +14 -38
  499. package/src/components/LpHintLayer.vue +13 -3
  500. package/src/components/LpHoverCard.vue +175 -0
  501. package/src/components/LpIdenticon.vue +69 -0
  502. package/src/components/LpImageEditor.vue +15 -18
  503. package/src/components/LpInfraNode.vue +27 -16
  504. package/src/components/LpInput.vue +30 -16
  505. package/src/components/LpLightbox.vue +44 -23
  506. package/src/components/LpLoader.vue +145 -0
  507. package/src/components/LpLogViewer.vue +311 -82
  508. package/src/components/LpMagnetic.vue +97 -0
  509. package/src/components/LpMapPicker.vue +26 -28
  510. package/src/components/LpMasonry.vue +247 -0
  511. package/src/components/LpModal.vue +10 -1
  512. package/src/components/LpNotificationBell.vue +33 -49
  513. package/src/components/LpNumberField.vue +79 -14
  514. package/src/components/LpNumberFlow.vue +10 -35
  515. package/src/components/LpOtpInput.vue +7 -2
  516. package/src/components/LpPagination.vue +38 -4
  517. package/src/components/LpPalettePreview.vue +2 -7
  518. package/src/components/LpPasswordInput.vue +16 -14
  519. package/src/components/LpPhoneInput.vue +12 -3
  520. package/src/components/LpPie.vue +197 -36
  521. package/src/components/LpPipeline.vue +366 -0
  522. package/src/components/LpPopover.vue +10 -1
  523. package/src/components/LpProgress.vue +22 -84
  524. package/src/components/LpQuota.vue +197 -0
  525. package/src/components/LpRangeSlider.vue +5 -1
  526. package/src/components/LpRelativeTime.vue +90 -0
  527. package/src/components/LpRepeater.vue +80 -0
  528. package/src/components/LpRevealOnScroll.vue +125 -0
  529. package/src/components/LpScramble.vue +107 -0
  530. package/src/components/LpSecretField.vue +313 -0
  531. package/src/components/LpSegmented.vue +3 -10
  532. package/src/components/LpSelect.vue +78 -64
  533. package/src/components/LpShaderBackdrop.vue +434 -0
  534. package/src/components/LpShinyText.vue +139 -0
  535. package/src/components/LpSidebar.vue +2 -0
  536. package/src/components/LpSlider.vue +5 -1
  537. package/src/components/LpSparkline.vue +55 -37
  538. package/src/components/LpSpotlight.vue +51 -0
  539. package/src/components/LpStat.vue +6 -2
  540. package/src/components/LpStatus.vue +127 -0
  541. package/src/components/LpStepMark.vue +138 -0
  542. package/src/components/LpStepper.vue +37 -43
  543. package/src/components/LpSwap.vue +2 -2
  544. package/src/components/LpSwitch.vue +15 -22
  545. package/src/components/LpTable.vue +47 -63
  546. package/src/components/LpTableFilter.vue +1 -0
  547. package/src/components/LpTableOfContents.vue +53 -29
  548. package/src/components/LpTabs.vue +10 -21
  549. package/src/components/LpTagsInput.vue +53 -37
  550. package/src/components/LpTextReveal.vue +236 -0
  551. package/src/components/LpTextarea.vue +11 -11
  552. package/src/components/LpThemeStudio.vue +216 -0
  553. package/src/components/LpThemeStudioSection.vue +16 -0
  554. package/src/components/LpThemeSwitcher.vue +156 -47
  555. package/src/components/LpTimeField.vue +9 -1
  556. package/src/components/LpToaster.vue +63 -83
  557. package/src/components/LpTooltip.vue +10 -1
  558. package/src/components/LpTour.vue +24 -13
  559. package/src/components/LpTruncate.vue +135 -0
  560. package/src/components/LpTypewriter.vue +236 -0
  561. package/src/components/LpUptimeBar.vue +6 -5
  562. package/src/components/LpVideoBackdrop.vue +15 -13
  563. package/src/components/OptionContent.vue +17 -0
  564. package/src/components/PickerField.vue +58 -0
  565. package/src/components/RevealToggle.vue +51 -0
  566. package/src/components/StepConnector.vue +54 -0
  567. package/src/components/TourCard.vue +29 -16
  568. package/src/components/badge.ts +8 -0
  569. package/src/components/chart.ts +8 -23
  570. package/src/components/dateRange.ts +25 -0
  571. package/src/components/dock.ts +31 -0
  572. package/src/components/dropdown.ts +15 -3
  573. package/src/components/fieldText.ts +95 -0
  574. package/src/components/fileTree.ts +19 -21
  575. package/src/components/format.ts +136 -0
  576. package/src/components/identicon.ts +160 -0
  577. package/src/components/masonry.ts +73 -0
  578. package/src/components/meter.ts +122 -0
  579. package/src/components/otp.ts +14 -3
  580. package/src/components/pipeline.ts +101 -0
  581. package/src/components/quota.ts +111 -0
  582. package/src/components/relativeTime.ts +118 -0
  583. package/src/components/reveal.ts +56 -0
  584. package/src/components/scramble.ts +138 -0
  585. package/src/components/shaderBackdrop.ts +208 -0
  586. package/src/components/slider.ts +30 -0
  587. package/src/components/slotText.ts +13 -0
  588. package/src/components/status.ts +46 -0
  589. package/src/components/tableFacets.ts +25 -0
  590. package/src/components/textSplit.ts +55 -0
  591. package/src/components/timeSpan.ts +183 -0
  592. package/src/components/tone.ts +144 -0
  593. package/src/components/tour.ts +3 -2
  594. package/src/components/typewriter.ts +104 -0
  595. package/src/components/videoBackdrop.ts +7 -6
  596. package/src/composables/easing.ts +66 -1
  597. package/src/composables/pseudoLocale.ts +105 -0
  598. package/src/composables/scroll.ts +6 -3
  599. package/src/composables/useClipboard.ts +25 -3
  600. package/src/composables/useField.ts +12 -0
  601. package/src/composables/useForm.ts +27 -6
  602. package/src/composables/useHintSystem.ts +40 -0
  603. package/src/composables/useHints.ts +14 -3
  604. package/src/composables/useInView.ts +61 -0
  605. package/src/composables/useLoadingGate.ts +63 -0
  606. package/src/composables/useLpConfig.ts +20 -1
  607. package/src/composables/useMediaQuery.ts +6 -2
  608. package/src/composables/useNow.ts +84 -0
  609. package/src/composables/usePersisted.ts +19 -8
  610. package/src/composables/usePillTransition.ts +21 -13
  611. package/src/composables/usePointerFrame.ts +72 -0
  612. package/src/composables/useReducedMotion.ts +22 -0
  613. package/src/composables/useRepeater.ts +44 -0
  614. package/src/composables/useResizeObserver.ts +59 -0
  615. package/src/composables/useRevealedValue.ts +84 -0
  616. package/src/composables/useScramble.ts +152 -0
  617. package/src/composables/useShift.ts +10 -16
  618. package/src/composables/useSpotlight.ts +82 -0
  619. package/src/composables/useTilt.ts +40 -23
  620. package/src/composables/useTween.ts +149 -0
  621. package/src/composables/useView.ts +93 -0
  622. package/src/index.css +1 -0
  623. package/src/index.ts +143 -1
  624. package/src/kit-icons.ts +1 -1
  625. package/src/theme/define.ts +65 -0
  626. package/src/theme/studio.ts +202 -0
  627. package/src/tokens/effects.css +151 -0
  628. package/src/tokens/tokens.css +131 -39
  629. package/src/tokens/utilities.css +81 -0
  630. package/dist/assets/LpTabs-Bk7v4bZz.css +0 -18
  631. package/dist/chunks/LpAlert-BdvxvcWE.js +0 -85
  632. package/dist/chunks/LpBadge-Fe0D1bYx.js +0 -62
  633. package/dist/chunks/LpBreadcrumbs-rzOKkLiI.js +0 -98
  634. package/dist/chunks/LpDatePicker-BMfM454Y.js +0 -243
  635. package/dist/chunks/LpDateRangePicker-CNb9X3eL.js +0 -195
  636. package/dist/chunks/LpNumberField-DO1ufKvE.js +0 -107
  637. package/dist/chunks/LpStepper-C2slwObu.js +0 -90
  638. package/dist/chunks/LpSwitch-CZy9_IoA.js +0 -132
  639. package/dist/chunks/LpThemeSwitcher-CDoziW0z.js +0 -166
  640. package/dist/chunks/TourCard-BKI7X9-r.js +0 -105
@@ -7,8 +7,8 @@ export default { inheritAttrs: false }
7
7
 
8
8
  <script setup lang="ts">
9
9
  import { computed } from "vue"
10
- import LpIcon from "./LpIcon.vue"
11
- import LpRollingText from "./LpRollingText.vue"
10
+ import LpStepMark from "./LpStepMark.vue"
11
+ import StepConnector from "./StepConnector.vue"
12
12
  import { useMergedAttrs } from "../composables/useMergedClass"
13
13
 
14
14
  export interface Step {
@@ -50,7 +50,7 @@ function isCurrent(i: number): boolean {
50
50
 
51
51
  // The stepper spaces its steps evenly; a compact wizard header needs that spacing under the consumer's control.
52
52
  const { class: rootClass, attrs: rest } = useMergedAttrs(
53
- "flex items-center gap-2",
53
+ "@container flex w-full min-w-0 items-center gap-2",
54
54
  )
55
55
  </script>
56
56
 
@@ -61,54 +61,48 @@ const { class: rootClass, attrs: rest } = useMergedAttrs(
61
61
  <li
62
62
  v-for="(step, i) in steps"
63
63
  :key="step.key ?? i"
64
- class="flex flex-1 items-center gap-2 last:flex-none"
64
+ class="flex min-w-0 flex-1 items-center gap-2 last:flex-none"
65
65
  :aria-current="isCurrent(i) ? 'step' : undefined"
66
66
  >
67
- <div class="flex items-center gap-2">
68
- <span
69
- class="flex size-7 shrink-0 items-center justify-center rounded-pill border text-xs font-semibold transition-colors duration-[var(--duration-medium)]"
70
- :class="isCompleted(step, i)
71
- ? 'border-transparent bg-brand text-ink-inverse'
72
- : isCurrent(i)
73
- ? 'border-brand text-brand'
74
- : 'border-line text-muted'"
75
- >
76
- <!-- The number turns into the tick rather than swapping for it. -->
77
- <LpRollingText
78
- mode="flip"
79
- :duration="260"
80
- :value="isCompleted(step, i) ? 'done' : step.icon ? 'icon' : String(i + 1)"
81
- >
82
- <template #default="{ value }">
83
- <LpIcon v-if="value === 'done'" name="lucide:check" :size="14" />
84
- <LpIcon v-else-if="value === 'icon' && step.icon" :name="step.icon" :size="14" />
85
- <template v-else>{{ value }}</template>
86
- </template>
87
- </LpRollingText>
88
- </span>
67
+ <div class="flex min-w-0 items-center">
68
+ <!-- The kit's step mark, as a wizard draws it: the number turns into the
69
+ tick rather than swapping for it. -->
70
+ <LpStepMark
71
+ variant="step"
72
+ :status="isCompleted(step, i) ? 'success' : isCurrent(i) ? 'current' : 'pending'"
73
+ :number="i + 1"
74
+ :icon="step.icon"
75
+ class="size-7 text-xs"
76
+ />
77
+ <!-- Where only the current step has room for its name (a narrow
78
+ container), the others fold their label to nothing rather than
79
+ dropping it in one frame: the row slides instead of jumping when
80
+ the step changes. Folded, the words stay in the reading order. -->
89
81
  <span
90
- class="text-sm transition-colors duration-[var(--duration-medium)]"
91
- :class="isCompleted(step, i) || isCurrent(i) ? 'text-ink' : 'text-muted'"
82
+ class="grid min-w-0 grid-cols-[1fr] transition-[grid-template-columns,opacity] duration-(--duration-medium) ease-(--ease-emphasized) motion-reduce:transition-none"
83
+ :class="!isCurrent(i) && '@max-md:grid-cols-[0fr] @max-md:opacity-0'"
92
84
  >
93
- {{ step.label }}
94
- <!-- Status for screen readers; the colour/check are visual only. -->
95
- <span class="sr-only">{{
96
- isCompleted(step, i)
97
- ? "(completed)"
98
- : isCurrent(i)
99
- ? "(current step)"
100
- : ""
101
- }}</span>
85
+ <span class="min-w-0 overflow-hidden">
86
+ <span
87
+ class="block truncate pl-2 text-sm transition-colors duration-[var(--duration-medium)]"
88
+ :class="isCompleted(step, i) || isCurrent(i) ? 'text-ink' : 'text-muted'"
89
+ >
90
+ {{ step.label }}
91
+ <!-- Status for screen readers; the colour/check are visual only. -->
92
+ <span class="sr-only">{{
93
+ isCompleted(step, i)
94
+ ? "(completed)"
95
+ : isCurrent(i)
96
+ ? "(current step)"
97
+ : ""
98
+ }}</span>
99
+ </span>
100
+ </span>
102
101
  </span>
103
102
  </div>
104
103
  <!-- The connector fills from the step it leaves towards the next one,
105
104
  so finishing a step reads as moving forward. -->
106
- <span v-if="i < steps.length - 1" class="relative h-px flex-1 overflow-hidden bg-line">
107
- <span
108
- class="absolute inset-0 origin-left bg-brand transition-transform duration-[var(--duration-medium)] ease-[var(--ease-emphasized)] motion-reduce:transition-none rtl:origin-right"
109
- :class="isCompleted(step, i) ? 'scale-x-100' : 'scale-x-0'"
110
- />
111
- </span>
105
+ <StepConnector v-if="i < steps.length - 1" :filled="isCompleted(step, i)" class="h-px" />
112
106
  </li>
113
107
  </ol>
114
108
  </template>
@@ -11,7 +11,7 @@
11
11
  * </LpSwap>
12
12
  *
13
13
  * The outgoing content fades out quickly, the incoming one rises in the way
14
- * LpTabs panels do (`tab-in`), and the box eases between the two heights
14
+ * LpTabs panels do (`rise-in`), and the box eases between the two heights
15
15
  * through LpShift, so what sits under it glides instead of jolting.
16
16
  *
17
17
  * `swapKey` is what decides that the content is "another one". Change it per
@@ -33,7 +33,7 @@ defineProps<{
33
33
  <Transition
34
34
  mode="out-in"
35
35
  :css="!disabled"
36
- enter-active-class="animate-[tab-in_220ms_var(--ease-emphasized)] motion-reduce:animate-none"
36
+ enter-active-class="animate-[rise-in_220ms_var(--ease-emphasized)] [--rise:6px] motion-reduce:animate-none"
37
37
  leave-active-class="transition-opacity duration-[var(--duration-fast)] ease-out motion-reduce:transition-none"
38
38
  leave-to-class="opacity-0"
39
39
  >
@@ -10,7 +10,7 @@ import { computed, useId, useSlots } from "vue"
10
10
  import { SwitchRoot, SwitchThumb } from "reka-ui"
11
11
  import { useFieldControl } from "../composables/useField"
12
12
  import { useOptimisticToggle } from "../composables/useOptimisticToggle"
13
- import LpIcon from "./LpIcon.vue"
13
+ import LpLoader from "./LpLoader.vue"
14
14
  import { useMergedAttrs } from "../composables/useMergedClass"
15
15
 
16
16
  const props = withDefaults(
@@ -82,8 +82,8 @@ function onUpdate(value: boolean) {
82
82
  </script>
83
83
 
84
84
  <template>
85
- <label v-if="labelled" :class="[rootClass, field.disabled && 'cursor-not-allowed']">
86
- <span v-if="labelPosition === 'start'" class="flex min-w-0 flex-col">
85
+ <component :is="labelled ? 'label' : 'span'" :class="labelled ? [rootClass, field.disabled && 'cursor-not-allowed'] : 'contents'">
86
+ <span v-if="labelled && labelPosition === 'start'" class="flex min-w-0 flex-col">
87
87
  <slot>{{ label }}</slot>
88
88
  <span v-if="description" :id="descriptionId" class="text-xs text-muted">{{ description }}</span>
89
89
  </span>
@@ -92,33 +92,26 @@ function onUpdate(value: boolean) {
92
92
  :id="field.id"
93
93
  :model-value="modelValue"
94
94
  :disabled="field.disabled"
95
+ :required="field.required"
95
96
  :aria-describedby="describedBy"
96
97
  :aria-busy="pending || undefined"
97
- :class="TRACK"
98
+ :class="labelled ? TRACK : rootClass"
98
99
  @update:model-value="onUpdate"
99
100
  >
100
101
  <SwitchThumb :class="[THUMB, 'grid place-items-center']">
101
- <LpIcon v-if="pending" name="lucide:loader-circle" class="size-2.5 animate-spin text-ink-inverse group-data-[state=checked]/switch:text-ink motion-reduce:animate-none" />
102
+ <!-- Hidden from screen readers: the switch itself says aria-busy, and
103
+ a "Loading…" inside it would become part of its name. -->
104
+ <LpLoader
105
+ :active="pending"
106
+ size="inline"
107
+ aria-hidden="true"
108
+ class="text-[10px] text-ink-inverse group-data-[state=checked]/switch:text-ink"
109
+ />
102
110
  </SwitchThumb>
103
111
  </SwitchRoot>
104
- <span v-if="labelPosition === 'end'" class="flex min-w-0 flex-col">
112
+ <span v-if="labelled && labelPosition === 'end'" class="flex min-w-0 flex-col">
105
113
  <slot>{{ label }}</slot>
106
114
  <span v-if="description" :id="descriptionId" class="text-xs text-muted">{{ description }}</span>
107
115
  </span>
108
- </label>
109
- <SwitchRoot
110
- v-else
111
- v-bind="rest"
112
- :id="field.id"
113
- :model-value="modelValue"
114
- :disabled="field.disabled"
115
- :aria-describedby="describedBy"
116
- :aria-busy="pending || undefined"
117
- :class="rootClass"
118
- @update:model-value="onUpdate"
119
- >
120
- <SwitchThumb :class="[THUMB, 'grid place-items-center']">
121
- <LpIcon v-if="pending" name="lucide:loader-circle" class="size-2.5 animate-spin text-ink-inverse group-data-[state=checked]/switch:text-ink motion-reduce:animate-none" />
122
- </SwitchThumb>
123
- </SwitchRoot>
116
+ </component>
124
117
  </template>
@@ -9,6 +9,7 @@ import { computed, nextTick, onBeforeUnmount, onMounted, ref, shallowRef, useAtt
9
9
  import LpCheckbox from "./LpCheckbox.vue"
10
10
  import LpContextMenu, { type ContextMenuItemDef } from "./LpContextMenu.vue"
11
11
  import LpEmptyState from "./LpEmptyState.vue"
12
+ import LpBadge from "./LpBadge.vue"
12
13
  import LpIcon from "./LpIcon.vue"
13
14
  import LpSkeleton from "./LpSkeleton.vue"
14
15
  import LpPagination from "./LpPagination.vue"
@@ -19,14 +20,16 @@ import LpShift from "./LpShift.vue"
19
20
  import LpTableFilter, { type TableFilterOption } from "./LpTableFilter.vue"
20
21
  import { useKitStorage } from "../composables/usePersisted"
21
22
  import { useAsyncTask } from "../composables/useAsyncTask"
23
+ import { useTableFacets } from "./tableFacets"
22
24
  import { useHotkeys } from "../composables/useHotkeys"
23
25
  import { usePaintSelect } from "../composables/usePaintSelect"
24
26
  import { useRovingFocus } from "../composables/useRovingFocus"
25
27
  import { useLabels } from "../composables/useLpConfig"
28
+ import { useResizeObserver } from "../composables/useResizeObserver"
26
29
  import { compareValues } from "./tableSort"
27
30
  import LpButton from "./LpButton.vue"
28
31
  import { downloadFile, fileStem, toCsv, type CsvOptions } from "./exportData"
29
- import { countValues, parseTableState, serializeTableState, summarizeShown } from "./tableFilter"
32
+ import { parseTableState, serializeTableState, summarizeShown } from "./tableFilter"
30
33
  import { resolveRowMenu, type TableRowMenuResult } from "./tableRowMenu"
31
34
 
32
35
  export interface TableColumn<Row> {
@@ -492,18 +495,10 @@ const hiddenColumns = ref<Set<string>>(new Set())
492
495
  // while the table itself widens with whatever it overflows by.
493
496
  const tableEl = ref<HTMLElement | null>(null)
494
497
  const tableWidth = ref(Number.POSITIVE_INFINITY)
495
- let widthObserver: ResizeObserver | undefined
496
- watch(
497
- tableEl,
498
- (table) => {
499
- widthObserver?.disconnect()
500
- const el = table?.closest<HTMLElement>("[data-reka-scroll-area-viewport]") ?? table?.parentElement
501
- if (!el || typeof ResizeObserver === "undefined") return
502
- widthObserver = new ResizeObserver(() => (tableWidth.value = el.clientWidth))
503
- widthObserver.observe(el)
504
- tableWidth.value = el.clientWidth
505
- },
506
- { flush: "post" },
498
+ useResizeObserver(
499
+ () => tableEl.value?.closest<HTMLElement>("[data-reka-scroll-area-viewport]") ?? tableEl.value?.parentElement,
500
+ (_, el) => (tableWidth.value = el.clientWidth),
501
+ { immediate: true },
507
502
  )
508
503
 
509
504
  const visibleColumns = computed(() =>
@@ -512,15 +507,16 @@ const visibleColumns = computed(() =>
512
507
  ),
513
508
  )
514
509
 
515
- /** The distinct values a filterable column holds, in first-seen order. */
510
+ const facetColumns = computed(() => props.columns.filter((col) => col.filterable).map((col) => col.key))
511
+ const localFacets = useTableFacets({
512
+ rows: () => props.load ? [] : props.rows,
513
+ columns: () => facetColumns.value,
514
+ hidden: () => hiddenValues.value,
515
+ })
516
+
516
517
  function valuesOf(col: TableColumn<T>): unknown[] {
517
- if (props.load && facets.value[col.key]) return facets.value[col.key]
518
- const seen: unknown[] = []
519
- for (const row of sourceRows.value) {
520
- const v = row[col.key]
521
- if (!seen.includes(v)) seen.push(v)
522
- }
523
- return seen
518
+ if (props.load) return facets.value[col.key] ?? [...new Set(sourceRows.value.map((row) => row[col.key]))]
519
+ return localFacets.distinct(col.key)
524
520
  }
525
521
 
526
522
  function isValueHidden(key: string, value: unknown): boolean {
@@ -555,17 +551,16 @@ function labelOf(col: TableColumn<T>, value: unknown): string {
555
551
  * way a faceted search does: with "Status: open" set, the "Owner" filter
556
552
  * counts open rows, which is what the user is about to narrow further.
557
553
  */
558
- function filterOptions(col: TableColumn<T>): TableFilterOption[] {
559
- let counts: Map<unknown, number> | undefined
560
- if (!props.load) {
561
- const others = Object.entries(hiddenValues.value).filter(([key, set]) => key !== col.key && set.size)
562
- const rows = others.length
563
- ? props.rows.filter((row) => others.every(([key, hidden]) => !hidden.has(row[key])))
564
- : props.rows
565
- counts = countValues(rows, col.key)
566
- }
567
- return valuesOf(col).map((value) => ({ value, label: labelOf(col, value), count: counts?.get(value) ?? (counts ? 0 : undefined) }))
568
- }
554
+ const facetOptions = computed(() => new Map(props.columns.filter((col) => col.filterable).map((col) => {
555
+ return [col.key, computed(() => {
556
+ const counts = props.load ? undefined : localFacets.counts(col.key)
557
+ return valuesOf(col).map((value) => ({
558
+ value,
559
+ label: labelOf(col, value),
560
+ count: counts?.get(value) ?? (counts ? 0 : undefined),
561
+ }))
562
+ })]
563
+ })))
569
564
 
570
565
  /** Every column with something hidden, summarised for the chips above the table. */
571
566
  const activeFilters = computed(() =>
@@ -791,9 +786,10 @@ function fetchPage(delay = 0) {
791
786
  })
792
787
  }
793
788
 
794
- // A new sort or filter starts from the first page: page 4 of a different
795
- // question is a page of nothing in particular.
796
- watch([activeSort, hiddenValues], () => {
789
+ // A new sort, filter or page size starts from the first page: page 4 of a
790
+ // different question, or of a different cut of the rows, is a page of nothing
791
+ // in particular.
792
+ watch([activeSort, hiddenValues, () => props.pageSize], () => {
797
793
  if (!props.load) return
798
794
  if (page.value !== 1) page.value = 1
799
795
  else fetchPage(props.debounce)
@@ -1061,26 +1057,18 @@ function onRowKeydown(event: KeyboardEvent) {
1061
1057
  // starts below the header. Tracked live (density/content can change it).
1062
1058
  const headEl = ref<HTMLElement | null>(null)
1063
1059
  const headHeight = ref(0)
1064
- let ro: ResizeObserver | undefined
1060
+ useResizeObserver(
1061
+ () => (props.stickyHeader ? headEl.value : null),
1062
+ (_, el) => (headHeight.value = (el as HTMLElement).offsetHeight),
1063
+ { immediate: true },
1064
+ )
1065
1065
  watch(
1066
- [headEl, () => props.stickyHeader],
1067
- ([el, sticky]) => {
1068
- ro?.disconnect()
1069
- if (!el || !sticky || typeof ResizeObserver === "undefined") {
1070
- headHeight.value = 0
1071
- return
1072
- }
1073
- ro = new ResizeObserver(() => {
1074
- headHeight.value = el.offsetHeight
1075
- })
1076
- ro.observe(el)
1077
- headHeight.value = el.offsetHeight
1066
+ () => props.stickyHeader,
1067
+ (sticky) => {
1068
+ if (!sticky) headHeight.value = 0
1078
1069
  },
1079
- { immediate: true, flush: "post" },
1080
1070
  )
1081
1071
  onBeforeUnmount(() => {
1082
- ro?.disconnect()
1083
- widthObserver?.disconnect()
1084
1072
  if (motionTimer) clearTimeout(motionTimer)
1085
1073
  })
1086
1074
 
@@ -1108,21 +1096,17 @@ const barInsetTop = computed(() =>
1108
1096
  <LpShift class="-mb-3">
1109
1097
  <div v-if="showBar" class="flex min-h-8 items-center gap-x-3 pb-3 text-xs">
1110
1098
  <div v-if="activeFilters.length" class="flex min-w-0 flex-1 flex-wrap items-center gap-1.5">
1111
- <span
1099
+ <LpBadge
1112
1100
  v-for="f in activeFilters"
1113
1101
  :key="f.col.key"
1114
- class="inline-flex max-w-72 animate-[chip-in_var(--duration-fast)_var(--ease-emphasized)] items-center gap-1 rounded-pill bg-brand-soft py-0.5 pr-1 pl-2.5 text-ink motion-reduce:animate-none"
1102
+ tone="brand"
1103
+ removable
1104
+ :remove-label="text.clearFilter.replace('{column}', f.col.label)"
1105
+ class="max-w-72 animate-[chip-in_var(--duration-fast)_var(--ease-emphasized)] font-normal text-ink motion-reduce:animate-none"
1106
+ @remove="showAllValues(f.col.key)"
1115
1107
  >
1116
1108
  <span class="truncate"><span class="text-muted">{{ f.col.label }}:</span> {{ f.text }}</span>
1117
- <button
1118
- type="button"
1119
- class="grid size-4 shrink-0 place-items-center rounded-pill text-muted outline-none transition-colors duration-fast hover:bg-ink/10 hover:text-ink focus-visible:ring-2 focus-visible:ring-ring"
1120
- :aria-label="text.clearFilter.replace('{column}', f.col.label)"
1121
- @click="showAllValues(f.col.key)"
1122
- >
1123
- <LpIcon name="lucide:x" :size="12" />
1124
- </button>
1125
- </span>
1109
+ </LpBadge>
1126
1110
  <button
1127
1111
  v-if="activeFilters.length > 1"
1128
1112
  type="button"
@@ -1286,7 +1270,7 @@ const barInsetTop = computed(() =>
1286
1270
  </button>
1287
1271
  </template>
1288
1272
  <LpTableFilter
1289
- :options="filterOptions(col)"
1273
+ :options="facetOptions.get(col.key)?.value ?? []"
1290
1274
  :hidden="hiddenValues[col.key] ?? new Set()"
1291
1275
  :labels="filterLabels()"
1292
1276
  @update:hidden="(next) => setHidden(col.key, next)"
@@ -98,6 +98,7 @@ const action =
98
98
  v-model="query"
99
99
  size="sm"
100
100
  icon="lucide:search"
101
+ clearable
101
102
  :placeholder="labels.search"
102
103
  :aria-label="labels.search"
103
104
  />
@@ -2,11 +2,11 @@
2
2
  /*
3
3
  * On-this-page table of contents with scroll-spy. Data-driven: pass the heading
4
4
  * tree (id + text, optional nested children) and it renders a rail of anchor
5
- * links, tracking which section is in view via IntersectionObserver and sliding
5
+ * links, tracking which section is in view from heading positions and sliding
6
6
  * a brand indicator to it (motion-v shared layoutId — same feel as Tabs/Sidebar).
7
7
  *
8
8
  * The kit convention for a docs/article TOC so apps stop re-implementing the
9
- * observer + active-link math. Clicking a link smooth-scrolls to the heading and
9
+ * scroll-spy + active-link math. Clicking a link smooth-scrolls to the heading and
10
10
  * marks it active immediately (so the pill doesn't lag the scroll).
11
11
  */
12
12
  import { Motion } from "motion-v"
@@ -27,7 +27,12 @@ const props = withDefaults(
27
27
  links: TocLink[]
28
28
  /** Heading shown above the list (defaults to the `title` label). */
29
29
  title?: string
30
- /** px offset from the top used as the scroll-spy trigger line. */
30
+ /**
31
+ * The least distance, px from the top, of the scroll-spy trigger line. The
32
+ * line sits at a quarter of the view when that is lower: a heading a
33
+ * couple of lines down already starts what is being read, and a fixed line
34
+ * near the top kept the previous section lit under it.
35
+ */
31
36
  offset?: number
32
37
  labels?: Partial<{ title: string }>
33
38
  /**
@@ -70,7 +75,7 @@ function flatIds(links: TocLink[]): string[] {
70
75
  return links.flatMap((l) => [l.id, ...(l.children ? flatIds(l.children) : [])])
71
76
  }
72
77
 
73
- let observer: IntersectionObserver | null = null
78
+ let stopSpy: (() => void) | null = null
74
79
 
75
80
  // While a click-driven smooth scroll is in flight, freeze scroll-spy so the bar
76
81
  // doesn't skip through every heading the page passes on the way to the target.
@@ -78,34 +83,53 @@ let spySuppressed = false
78
83
  let rafId: number | null = null
79
84
  let safetyTimer: ReturnType<typeof setTimeout> | null = null
80
85
 
86
+ /*
87
+ * The current section is read from positions on every scroll, not from which
88
+ * headings cross a thin band: a band misses the moment no heading is in it,
89
+ * and scrolling back to the top then left the second section lit. The active
90
+ * heading is the last one whose top has passed the offset line; above the
91
+ * first, the first; at the very end of the scroll, the last, which a short
92
+ * final section could otherwise never reach. Works for the window and for a
93
+ * scroll area the headings live in.
94
+ */
81
95
  function setup() {
82
- observer?.disconnect()
96
+ stopSpy?.()
97
+ stopSpy = null
83
98
  const ids = flatIds(props.links)
84
99
  if (!ids.length) return
85
-
86
- // Track the topmost heading whose top has crossed the offset line. We keep a
87
- // set of "currently intersecting" and, on every change, pick the first id in
88
- // document order that's visible — falling back to the last one scrolled past.
89
- const visible = new Set<string>()
90
- observer = new IntersectionObserver(
91
- (entries) => {
92
- for (const e of entries) {
93
- if (e.isIntersecting) visible.add(e.target.id)
94
- else visible.delete(e.target.id)
95
- }
96
- if (spySuppressed) return // ignore intermediate sections during a click-scroll
97
- const firstVisible = ids.find((id) => visible.has(id))
98
- if (firstVisible) activeId.value = firstVisible
99
- },
100
- { rootMargin: `-${props.offset}px 0px -70% 0px`, threshold: 0 },
101
- )
102
-
103
- for (const id of ids) {
104
- const el = document.getElementById(id)
105
- if (el) observer.observe(el)
100
+ const first = document.getElementById(ids[0]!)
101
+ const scroller = first ? scrollParent(first) : null
102
+ let frame = 0
103
+
104
+ const measure = () => {
105
+ frame = 0
106
+ if (spySuppressed) return
107
+ const top = scroller ? scroller.getBoundingClientRect().top : 0
108
+ const headings = ids.map((id) => document.getElementById(id)).filter((el): el is HTMLElement => !!el)
109
+ if (!headings.length) return
110
+ let current = headings[0]!.id
111
+ const view = scroller ? scroller.clientHeight : window.innerHeight
112
+ const line = Math.max(props.offset, view / 4)
113
+ for (const el of headings) if (el.getBoundingClientRect().top - top <= line + 1) current = el.id
114
+ const scrolled = scroller ? scroller.scrollTop : window.scrollY
115
+ const end = scroller
116
+ ? scroller.scrollTop + scroller.clientHeight >= scroller.scrollHeight - 2
117
+ : window.scrollY + window.innerHeight >= document.documentElement.scrollHeight - 2
118
+ if (scrolled > 0 && end) current = headings[headings.length - 1]!.id
119
+ activeId.value = current
120
+ }
121
+ const onScroll = () => {
122
+ if (!frame) frame = requestAnimationFrame(measure)
123
+ }
124
+ const target: HTMLElement | Window = scroller ?? window
125
+ target.addEventListener("scroll", onScroll, { passive: true })
126
+ window.addEventListener("resize", onScroll)
127
+ measure()
128
+ stopSpy = () => {
129
+ target.removeEventListener("scroll", onScroll)
130
+ window.removeEventListener("resize", onScroll)
131
+ if (frame) cancelAnimationFrame(frame)
106
132
  }
107
- // Seed the initial active id (top-most heading) so the bar isn't empty.
108
- if (!activeId.value) activeId.value = ids[0] ?? ""
109
133
  }
110
134
 
111
135
  // Suppress scroll-spy until the smooth scroll settles. The unfreeze isn't on a
@@ -157,7 +181,7 @@ function onClick(id: string, ev: MouseEvent) {
157
181
  onMounted(setup)
158
182
  watch(() => props.links, setup, { deep: true })
159
183
  onBeforeUnmount(() => {
160
- observer?.disconnect()
184
+ stopSpy?.()
161
185
  unfreeze()
162
186
  })
163
187
  </script>
@@ -1,8 +1,10 @@
1
1
  <script setup lang="ts">
2
- import { Motion, useReducedMotion } from "motion-v"
2
+ import { Motion } from "motion-v"
3
3
  import { TabsContent, TabsList, TabsRoot, TabsTrigger } from "reka-ui"
4
4
  import { computed, nextTick, ref, useId, watch } from "vue"
5
5
  import { usePillTransition } from "../composables/usePillTransition"
6
+ import { prefersReducedMotion } from "../composables/easing"
7
+ import AttentionDot from "./AttentionDot.vue"
6
8
  import LpBadge from "./LpBadge.vue"
7
9
  import LpContextMenu, { type ContextMenuItemDef } from "./LpContextMenu.vue"
8
10
  import LpIcon from "./LpIcon.vue"
@@ -99,7 +101,7 @@ watch(current, () => {
99
101
  const end = start + active.offsetWidth
100
102
  if (start >= row.scrollLeft && end <= row.scrollLeft + row.clientWidth) return
101
103
  const left = start < row.scrollLeft ? start : end - row.clientWidth
102
- row.scrollTo({ left, behavior: reduceMotion.value ? "auto" : "smooth" })
104
+ row.scrollTo({ left, behavior: prefersReducedMotion() ? "auto" : "smooth" })
103
105
  })
104
106
  })
105
107
 
@@ -120,14 +122,9 @@ const hovered = ref<string | null>(null)
120
122
  const pillTransition = usePillTransition()
121
123
 
122
124
  // Panel height spring: when the active #panel differs in height, the wrapper
123
- // grows/shrinks smoothly instead of snapping. Same feel as the drag layout in
124
- // LayoutNode; collapses to instant under reduced motion.
125
- const reduceMotion = useReducedMotion()
126
- const panelLayoutTransition = computed(() =>
127
- reduceMotion.value
128
- ? { duration: 0 }
129
- : { type: "spring" as const, stiffness: 520, damping: 42, mass: 0.9 },
130
- )
125
+ // grows/shrinks smoothly instead of snapping. The kit's layout feel, as the
126
+ // drag layout in LayoutNode; collapses to instant under reduced motion.
127
+ const panelLayoutTransition = usePillTransition("layout")
131
128
 
132
129
  // A bottom bar marks only the active tab: on a phone a tap is the hover, and
133
130
  // a bar that chased the mouse across a desktop window would point at a tab
@@ -226,11 +223,7 @@ function releaseFocusAfterPointer(event: PointerEvent) {
226
223
  />
227
224
  <span v-if="item.icon" class="relative z-10 inline-flex">
228
225
  <LpIcon :name="item.icon" :size="bottom ? 22 : 14" />
229
- <span
230
- v-if="item.dot"
231
- aria-hidden="true"
232
- class="absolute -right-1 -top-0.5 size-2 rounded-full bg-accent"
233
- />
226
+ <AttentionDot v-if="item.dot" corner />
234
227
  <!-- On a bottom bar the count rides on the icon's corner, as phone
235
228
  navs draw it: the label under the icon has no room beside it. -->
236
229
  <Transition name="lp-tab-badge">
@@ -245,11 +238,7 @@ function releaseFocusAfterPointer(event: PointerEvent) {
245
238
  </Transition>
246
239
  </span>
247
240
  <span class="relative z-10" :class="bottom ? 'max-w-full truncate' : ''">{{ item.label }}</span>
248
- <span
249
- v-if="item.dot && !item.icon"
250
- aria-hidden="true"
251
- class="relative z-10 size-1.5 self-start rounded-full bg-accent"
252
- />
241
+ <AttentionDot v-if="item.dot && !item.icon" />
253
242
  <!-- The count rolls when it changes, and the chip scales in and out
254
243
  rather than popping. -->
255
244
  <Transition name="lp-tab-badge">
@@ -288,7 +277,7 @@ function releaseFocusAfterPointer(event: PointerEvent) {
288
277
  v-for="item in items"
289
278
  :key="item.value"
290
279
  :value="item.value"
291
- class="outline-none data-[state=active]:animate-[tab-in_200ms_var(--ease-emphasized)]"
280
+ class="outline-none [--rise:6px] data-[state=active]:animate-[rise-in_200ms_var(--ease-emphasized)]"
292
281
  >
293
282
  <slot name="panel" :value="item.value" />
294
283
  </TabsContent>