@leavepulse/ui 0.77.3 → 0.78.1

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 (621) hide show
  1. package/README.md +68 -0
  2. package/dist/assets/{LpCommandPalette-DOIZHw-g.css → LpCommandPalette-DDJKICKh.css} +19 -19
  3. package/dist/assets/{LpDock-Cbh0wQUv.css → LpDock-Dw82tWVD.css} +3 -3
  4. package/dist/assets/{LpDropzone-B_qRq1-R.css → LpDropzone-DNbh_NFJ.css} +10 -10
  5. package/dist/assets/{LpImageEditor-XM5bAziW.css → LpImageEditor-Bgu20XLs.css} +6 -6
  6. package/dist/assets/{LpTable-Bv-EcQs7.css → LpTable-CCk0ZHo7.css} +19 -19
  7. package/dist/assets/LpTabs-Bh7a-Bdl.css +18 -0
  8. package/dist/chunks/AppShellContextNav-C6Ho2mof.js +49 -0
  9. package/dist/chunks/ChartRangeSelector-HO0sMMz6.js +129 -0
  10. package/dist/chunks/{ContextMenuItems-BXumicbh.js → ContextMenuItems-DmaKSJVv.js} +1 -1
  11. package/dist/chunks/{DropzoneLinkField-C-9BCGJn.js → DropzoneLinkField-CLLhd3WB.js} +2 -2
  12. package/dist/chunks/FieldLeading-mr81aEAP.js +27 -0
  13. package/dist/chunks/{FieldWrapper-CORPzo9s.js → FieldWrapper-DnuMTrqW.js} +1 -1
  14. package/dist/chunks/IconCloseButton-COZEsa9u.js +29 -0
  15. package/dist/chunks/{LayoutCanvas-CNOAUk7D.js → LayoutCanvas-CZKOltfA.js} +1 -1
  16. package/dist/chunks/{LayoutNode-DF5BMN0J.js → LayoutNode-D2f7v683.js} +45 -45
  17. package/dist/chunks/{LpActionBar-BP1ld7-S.js → LpActionBar-BGMk5KoG.js} +3 -3
  18. package/dist/chunks/{LpActivityLine-CJvzrNpj.js → LpActivityLine-Ea-t5Vza.js} +4 -2
  19. package/dist/chunks/{LpAddressInput-E8KtwU7-.js → LpAddressInput-BSS49jpm.js} +12 -11
  20. package/dist/chunks/{LpAlert-n5XPAZfv.js → LpAlert-CjvTZIKF.js} +3 -3
  21. package/dist/chunks/LpAppShell-BKbYCHkx.js +601 -0
  22. package/dist/chunks/{LpAutocomplete-C-SpPfBG.js → LpAutocomplete-DkY6CSyD.js} +24 -42
  23. package/dist/chunks/{LpAvatar-Cg6Az3wz.js → LpAvatar-cQVsNk6F.js} +2 -2
  24. package/dist/chunks/{LpBadge-wUYLN4U9.js → LpBadge-D5QQdDQ_.js} +2 -2
  25. package/dist/chunks/{LpBottomNav-CbNQQPuL.js → LpBottomNav-zxLGGbjm.js} +9 -2
  26. package/dist/chunks/{LpBreadcrumbs-DPdbth-c.js → LpBreadcrumbs-CIIBsygI.js} +4 -3
  27. package/dist/chunks/{LpButton-CFb44IjC.js → LpButton-DSHioIfD.js} +5 -4
  28. package/dist/chunks/{LpCalendar-CuoWks-0.js → LpCalendar-D4-LVjfF.js} +1 -1
  29. package/dist/chunks/{LpCard-r13WRqox.js → LpCard-BPtYXwnT.js} +1 -1
  30. package/dist/chunks/{LpCheckbox-Cs4SHaHX.js → LpCheckbox-D6RuDW4X.js} +38 -16
  31. package/dist/chunks/{LpCodeBlock-DRC8VbXW.js → LpCodeBlock-DBqy4RLd.js} +19 -41
  32. package/dist/chunks/{LpCodeDisplay-CE9TxCA4.js → LpCodeDisplay-D3BUAhV1.js} +5 -5
  33. package/dist/chunks/{LpCollapse-CWS9M_lm.js → LpCollapse-DrAw5DBZ.js} +5 -4
  34. package/dist/chunks/{LpColorPicker-1y1QJHZR.js → LpColorPicker-COHzV68R.js} +11 -12
  35. package/dist/chunks/{LpCommandScope-CtUhJe8T.js → LpCommandScope-DRUvHiX7.js} +1 -1
  36. package/dist/chunks/{LpConfirmDialog-DlD45Bi_.js → LpConfirmDialog-CnrmzkuN.js} +3 -3
  37. package/dist/chunks/{LpConfirmHost-BIWjBLmI.js → LpConfirmHost-CwbObVGH.js} +1 -1
  38. package/dist/chunks/{LpContextMenu-rx2tCjwk.js → LpContextMenu-Bx_IhQDS.js} +17 -19
  39. package/dist/chunks/{LpContextSwitcher-Dwh6dyID.js → LpContextSwitcher-1C1tExdl.js} +2 -2
  40. package/dist/chunks/{LpCopyButton-xF7wFVoU.js → LpCopyButton-sAMvWeLP.js} +3 -3
  41. package/dist/chunks/{LpCountdown-DgeY3cLG.js → LpCountdown-DVl7vXI1.js} +4 -3
  42. package/dist/chunks/{LpDataList-Jxyl9H5w.js → LpDataList-CaVfsozH.js} +13 -4
  43. package/dist/chunks/{LpDatePicker-CA0QTfBC.js → LpDatePicker-DwSDY0mt.js} +12 -18
  44. package/dist/chunks/{LpDateRangePicker-u3J51xXk.js → LpDateRangePicker-CNQXdTVv.js} +10 -16
  45. package/dist/chunks/{LpDisclosure-Cpa7Hc5T.js → LpDisclosure-DG7JCo-d.js} +2 -2
  46. package/dist/chunks/{LpDrawer-CrG8t_KP.js → LpDrawer-DXNQFpAA.js} +61 -61
  47. package/dist/chunks/{LpDropdownMenu-Dl7Z4ZhS.js → LpDropdownMenu-CLzxIOgM.js} +9 -17
  48. package/dist/chunks/{LpEditable-Cy6GLbFx.js → LpEditable-DVT0Rh8F.js} +9 -6
  49. package/dist/chunks/{LpEmptyState-EQHiRYhG.js → LpEmptyState-DurPF001.js} +1 -1
  50. package/dist/chunks/{LpFieldNotice-CzQ2_5rQ.js → LpFieldNotice-DJ10cYIo.js} +1 -1
  51. package/dist/chunks/LpFileTree-C-rJKzEQ.js +735 -0
  52. package/dist/chunks/{LpFileTreeNode-cT6BIWvz.js → LpFileTreeNode-BgYn4U1J.js} +116 -34
  53. package/dist/chunks/{LpFormField-Ch69Jd-X.js → LpFormField-BKYn9dyP.js} +3 -3
  54. package/dist/chunks/{LpFrame-BVQCQLDI.js → LpFrame-Bv5Fphte.js} +25 -11
  55. package/dist/chunks/{LpHintExample-9Py0wc-L.js → LpHintExample-YzCXiSUp.js} +1 -1
  56. package/dist/chunks/{LpHintLayer-CgObdUsM.js → LpHintLayer-BeKRsRon.js} +2 -2
  57. package/dist/chunks/{LpHints-Bz-BlaSl.js → LpHints-qf3xYsza.js} +3 -3
  58. package/dist/chunks/{LpHoverCard-spGxyw7T.js → LpHoverCard-CHE9jAJG.js} +29 -11
  59. package/dist/chunks/{LpIcon--5WSb3jJ.js → LpIcon-C6JpQ5td.js} +6 -3
  60. package/dist/chunks/{LpIdenticon-BzdC_qz9.js → LpIdenticon-Dbbr4fvt.js} +2 -1
  61. package/dist/chunks/{LpInfraNode-46XOCkfq.js → LpInfraNode-Bb5nbuFY.js} +19 -2
  62. package/dist/chunks/{LpInput-Tw-yxT4I.js → LpInput-D0O6dpuA.js} +32 -47
  63. package/dist/chunks/LpInspector-DO3fTCQ1.js +209 -0
  64. package/dist/chunks/{LpLaneNode-HtnQf2FF.js → LpLaneNode-Bqcdm8Rf.js} +19 -1
  65. package/dist/chunks/{LpLightbox-B95yu22B.js → LpLightbox-CtDTQV01.js} +57 -32
  66. package/dist/chunks/{LpLoader-DVwkOmt9.js → LpLoader-Bf1yZwaU.js} +1 -1
  67. package/dist/chunks/LpLogInspector-BdQlX6S-.js +119 -0
  68. package/dist/chunks/{LpLogViewer-ngqkns4m.js → LpLogViewer-umCZBapN.js} +234 -53
  69. package/dist/chunks/{LpMapPicker-DRGgh89B.js → LpMapPicker-D5_YLLBC.js} +4 -3
  70. package/dist/chunks/{LpMasonry--k0571qG.js → LpMasonry-DPYekFxs.js} +8 -5
  71. package/dist/chunks/{LpMediaGallery-Bkram-MO.js → LpMediaGallery-BYEwySoF.js} +3 -3
  72. package/dist/chunks/{LpModal-CoGhLTyH.js → LpModal-DDvrSAnf.js} +11 -13
  73. package/dist/chunks/{LpModalNav-BGvs2y5Q.js → LpModalNav-gOi1Giz1.js} +11 -37
  74. package/dist/chunks/{LpNotificationBell-B0034Lk-.js → LpNotificationBell-DUbVyK6R.js} +9 -9
  75. package/dist/chunks/{LpNumberField-e0IBkWU1.js → LpNumberField-Csg-1Zh_.js} +25 -20
  76. package/dist/chunks/{LpOtpInput-CeBPsM7D.js → LpOtpInput-BRpLBbOD.js} +2 -2
  77. package/dist/chunks/LpPageScrollbar-D2O0xhJw.js +164 -0
  78. package/dist/chunks/{LpPagination-BIIiYHXR.js → LpPagination-snQ020xQ.js} +6 -4
  79. package/dist/chunks/{LpPaletteTheme-DiLYKQiZ.js → LpPaletteTheme-BIXpZLGe.js} +4 -4
  80. package/dist/chunks/{LpPasswordInput-BkHKQDhM.js → LpPasswordInput-D4HPhqfV.js} +2 -2
  81. package/dist/chunks/{LpPhoneInput-CETEp5W7.js → LpPhoneInput-BSL7NX4z.js} +15 -26
  82. package/dist/chunks/{LpPie-DrZepi0p.js → LpPie-oVNHjsKD.js} +22 -21
  83. package/dist/chunks/{LpPipeline-B3aOVOkV.js → LpPipeline-BSXT6oUJ.js} +16 -7
  84. package/dist/chunks/{LpPopover-DmZ3wUtP.js → LpPopover-BQSuxtai.js} +10 -1
  85. package/dist/chunks/{LpProgress-Yr6ONG5t.js → LpProgress-D_MSjowb.js} +2 -1
  86. package/dist/chunks/{LpQuota-Dk2MyI2Z.js → LpQuota-CgWPgdVt.js} +1 -1
  87. package/dist/chunks/{LpRadioGroup-ggaPL92T.js → LpRadioGroup-BrazjLY_.js} +4 -4
  88. package/dist/chunks/{LpRangeCalendar-CYYUYqJ7.js → LpRangeCalendar-BrqlGZzE.js} +1 -1
  89. package/dist/chunks/{LpRangeSlider-CM-0ZITZ.js → LpRangeSlider-fz61tzc-.js} +5 -9
  90. package/dist/chunks/{LpRelativeTime-DwgCb5-8.js → LpRelativeTime-0zI-44ve.js} +1 -1
  91. package/dist/chunks/{LpRepeater-D7ZmnIYd.js → LpRepeater-BkJHSPI1.js} +3 -3
  92. package/dist/chunks/{LpRevealOnScroll-DcQjexLy.js → LpRevealOnScroll-CPwyiQAr.js} +1 -1
  93. package/dist/chunks/{LpScramble-Bn9OoOtC.js → LpScramble-DsE77iVp.js} +1 -1
  94. package/dist/chunks/{LpScrollArea-MyEnVB_5.js → LpScrollArea-CqvwfZs2.js} +31 -22
  95. package/dist/chunks/{LpSecretField-BbmqM9ye.js → LpSecretField-B2roc4Iz.js} +10 -9
  96. package/dist/chunks/{LpSection-DFK_uoJE.js → LpSection-BfteipxU.js} +1 -1
  97. package/dist/chunks/{LpSegmented-CeACsMMA.js → LpSegmented-DbEJhbv-.js} +8 -10
  98. package/dist/chunks/{LpSelect-Cxq4yBGd.js → LpSelect-Y-iuSymW.js} +47 -30
  99. package/dist/chunks/{LpServiceNode-D8uJ8sGk.js → LpServiceNode-Cln2ntdw.js} +17 -0
  100. package/dist/chunks/{LpShaderBackdrop-Bote0iuy.js → LpShaderBackdrop-wQygYb5h.js} +13 -10
  101. package/dist/chunks/{LpShift-CCq7dofl.js → LpShift-DAgS_d2x.js} +18 -15
  102. package/dist/chunks/{LpSidebar-DzE1783C.js → LpSidebar-DDNJzb69.js} +74 -87
  103. package/dist/chunks/{LpSidebarNav-DE3PhXVP.js → LpSidebarNav-CE0jQS8i.js} +8 -6
  104. package/dist/chunks/{LpSidebarRow-BRYhNDSo.js → LpSidebarRow-DOTg1txp.js} +6 -5
  105. package/dist/chunks/{LpSlider-DxYoCJJO.js → LpSlider-A4ixovgS.js} +5 -9
  106. package/dist/chunks/{LpSpotlight-4F3NeUMY.js → LpSpotlight-DwxkhFgR.js} +2 -1
  107. package/dist/chunks/{LpStat-f2LfDCJ4.js → LpStat-DPjc6_fX.js} +19 -6
  108. package/dist/chunks/{LpStatus-DglxttQ7.js → LpStatus-DGJFwk5F.js} +2 -2
  109. package/dist/chunks/{LpStepMark-DpzKVyh8.js → LpStepMark-Dw2MRTrt.js} +2 -2
  110. package/dist/chunks/{LpStepper-DpsocBNJ.js → LpStepper-DNnh7lCu.js} +1 -1
  111. package/dist/chunks/{LpSwap-C96c0LWh.js → LpSwap-M7nFeW3C.js} +1 -1
  112. package/dist/chunks/{LpSwitch-BnXd1llc.js → LpSwitch-DnC2-0aV.js} +3 -3
  113. package/dist/chunks/{LpTabFace-DPCwKkH2.js → LpTabFace-DQoV8mQG.js} +2 -2
  114. package/dist/chunks/{LpTableFilter-CiVBpaq0.js → LpTableFilter-B_XMOeAh.js} +4 -4
  115. package/dist/chunks/{LpTableOfContents-BN5zvpnx.js → LpTableOfContents-CKkWEK6R.js} +14 -9
  116. package/dist/chunks/{LpTagsInput-C-mDG648.js → LpTagsInput-Dt0mteSj.js} +19 -27
  117. package/dist/chunks/{LpTextarea-TE-yZv2U.js → LpTextarea-Co0b9PVx.js} +8 -16
  118. package/dist/chunks/LpThemeProvider-XK6ZeWAE.js +81 -0
  119. package/dist/chunks/{LpThemeStudio-BpORDvH6.js → LpThemeStudio-ChU0_Ga8.js} +12 -195
  120. package/dist/chunks/{LpThemeSwitcher-BnEn_mvf.js → LpThemeSwitcher-DmCZ21P_.js} +8 -6
  121. package/dist/chunks/{LpTimeField-BawSVsmt.js → LpTimeField-DeOcKWJq.js} +6 -9
  122. package/dist/chunks/{LpToaster-IwTXjbbU.js → LpToaster-Ct_ZOhCh.js} +10 -8
  123. package/dist/chunks/{LpTooltip-BcBvIx4z.js → LpTooltip-Bz_rrq5S.js} +56 -24
  124. package/dist/chunks/LpTopologyCanvas-jqz1KCq2.js +678 -0
  125. package/dist/chunks/{LpTour-BZq-mUMv.js → LpTour-ClKYhx4h.js} +7 -5
  126. package/dist/chunks/{LpTruncate-CflAIwiJ.js → LpTruncate-ellq9RYM.js} +6 -5
  127. package/dist/chunks/{LpTypewriter-BCL_a6wE.js → LpTypewriter-CZIzpdbe.js} +2 -1
  128. package/dist/chunks/{LpUptimeBar-DqNvvMBK.js → LpUptimeBar-BoxcCDVY.js} +3 -3
  129. package/dist/chunks/{LpVideoBackdrop-DS1wGv-X.js → LpVideoBackdrop-Ct4St4ZL.js} +10 -13
  130. package/dist/chunks/LpWindow-B8YSRVTH.js +297 -0
  131. package/dist/chunks/LpWorkspaceSwitcher-BeNHCLd5.js +139 -0
  132. package/dist/chunks/{MenuTitle-BmCNNTKH.js → MenuTitle-Bh5dAdV1.js} +1 -1
  133. package/dist/chunks/{OptionContent-22UT8zLn.js → OptionContent-CGb8QlHA.js} +1 -1
  134. package/dist/chunks/{PickerField-Bfh8id3d.js → PickerField-BM1dyafh.js} +4 -4
  135. package/dist/chunks/{RevealToggle-BEit1n6Z.js → RevealToggle-D_iyrB8d.js} +3 -3
  136. package/dist/chunks/SliderRail-DhPREa_R.js +18 -0
  137. package/dist/chunks/{TourCard-DNclH3u_.js → TourCard-DAzTYfav.js} +4 -4
  138. package/dist/chunks/{icons-DMITlfw5.js → icons-CYfcpSDS.js} +26 -10
  139. package/dist/component-names.d.ts +1 -1
  140. package/dist/components/AppShellContextNav.vue.d.ts +13 -0
  141. package/dist/components/AppShellContextNav.vue.js +4 -0
  142. package/dist/components/ChartRangeSelector.vue.d.ts +21 -0
  143. package/dist/components/ChartRangeSelector.vue.js +4 -0
  144. package/dist/components/ContextMenuItems.vue.js +1 -1
  145. package/dist/components/DropzoneLinkField.vue.d.ts +2 -2
  146. package/dist/components/DropzoneLinkField.vue.js +1 -1
  147. package/dist/components/FieldLeading.vue.d.ts +16 -0
  148. package/dist/components/FieldLeading.vue.js +4 -0
  149. package/dist/components/FieldWrapper.vue.js +1 -1
  150. package/dist/components/IconCloseButton.vue.d.ts +7 -0
  151. package/dist/components/IconCloseButton.vue.js +4 -0
  152. package/dist/components/LayoutCanvas.vue.js +1 -1
  153. package/dist/components/LayoutNode.vue.js +1 -1
  154. package/dist/components/LpActionBar.vue.js +1 -1
  155. package/dist/components/LpActivityLine.vue.js +1 -1
  156. package/dist/components/LpAddressInput.vue.js +1 -1
  157. package/dist/components/LpAlert.vue.js +1 -1
  158. package/dist/components/LpAppShell.vue.d.ts +125 -2
  159. package/dist/components/LpAppShell.vue.js +1 -1
  160. package/dist/components/LpAutocomplete.vue.js +1 -1
  161. package/dist/components/LpAvatar.vue.js +1 -1
  162. package/dist/components/LpBadge.vue.js +1 -1
  163. package/dist/components/LpBottomNav.vue.d.ts +5 -0
  164. package/dist/components/LpBottomNav.vue.js +1 -1
  165. package/dist/components/LpBreadcrumbs.vue.js +1 -1
  166. package/dist/components/LpButton.vue.d.ts +14 -2
  167. package/dist/components/LpButton.vue.js +1 -1
  168. package/dist/components/LpCalendar.vue.js +1 -1
  169. package/dist/components/LpCard.vue.js +1 -1
  170. package/dist/components/LpChart.vue.d.ts +74 -2
  171. package/dist/components/LpChart.vue.js +326 -85
  172. package/dist/components/LpCheckbox.vue.d.ts +6 -2
  173. package/dist/components/LpCheckbox.vue.js +1 -1
  174. package/dist/components/LpCodeBlock.vue.js +1 -1
  175. package/dist/components/LpCodeDisplay.vue.js +1 -1
  176. package/dist/components/LpCollapse.vue.js +1 -1
  177. package/dist/components/LpColorPicker.vue.js +1 -1
  178. package/dist/components/LpCommandPalette.vue.d.ts +8 -0
  179. package/dist/components/LpCommandPalette.vue.js +107 -56
  180. package/dist/components/LpCommandScope.vue.js +1 -1
  181. package/dist/components/LpConfirmDialog.vue.js +1 -1
  182. package/dist/components/LpConfirmHost.vue.js +1 -1
  183. package/dist/components/LpContextMenu.vue.js +1 -1
  184. package/dist/components/LpContextSwitcher.vue.js +1 -1
  185. package/dist/components/LpCopyButton.vue.js +1 -1
  186. package/dist/components/LpCountdown.vue.js +1 -1
  187. package/dist/components/LpDataList.vue.d.ts +1 -1
  188. package/dist/components/LpDataList.vue.js +1 -1
  189. package/dist/components/LpDatePicker.vue.d.ts +3 -15
  190. package/dist/components/LpDatePicker.vue.js +1 -1
  191. package/dist/components/LpDateRangePicker.vue.d.ts +3 -13
  192. package/dist/components/LpDateRangePicker.vue.js +1 -1
  193. package/dist/components/LpDisclosure.vue.js +1 -1
  194. package/dist/components/LpDock.vue.js +21 -18
  195. package/dist/components/LpDrawer.vue.d.ts +1 -1
  196. package/dist/components/LpDrawer.vue.js +1 -1
  197. package/dist/components/LpDropdownMenu.vue.js +1 -1
  198. package/dist/components/LpDropzone.vue.js +14 -11
  199. package/dist/components/LpEditable.vue.js +1 -1
  200. package/dist/components/LpEmptyState.vue.js +1 -1
  201. package/dist/components/LpFieldNotice.vue.js +1 -1
  202. package/dist/components/LpFileTree.vue.d.ts +96 -6
  203. package/dist/components/LpFileTree.vue.js +1 -1
  204. package/dist/components/LpFileTreeNode.vue.d.ts +48 -0
  205. package/dist/components/LpFileTreeNode.vue.js +1 -1
  206. package/dist/components/LpFormField.vue.js +1 -1
  207. package/dist/components/LpFrame.vue.js +1 -1
  208. package/dist/components/LpGauge.vue.d.ts +1 -1
  209. package/dist/components/LpHintExample.vue.js +1 -1
  210. package/dist/components/LpHintLayer.vue.js +1 -1
  211. package/dist/components/LpHints.vue.js +1 -1
  212. package/dist/components/LpHoverCard.vue.js +1 -1
  213. package/dist/components/LpIcon.vue.d.ts +2 -0
  214. package/dist/components/LpIcon.vue.js +1 -1
  215. package/dist/components/LpIdenticon.vue.js +1 -1
  216. package/dist/components/LpImageEditor.vue.js +7 -6
  217. package/dist/components/LpInfraNode.vue.d.ts +11 -2
  218. package/dist/components/LpInfraNode.vue.js +1 -1
  219. package/dist/components/LpInput.vue.d.ts +1 -1
  220. package/dist/components/LpInput.vue.js +1 -1
  221. package/dist/components/LpInspector.vue.d.ts +87 -0
  222. package/dist/components/LpInspector.vue.js +4 -0
  223. package/dist/components/LpLaneNode.vue.d.ts +2 -3
  224. package/dist/components/LpLaneNode.vue.js +1 -1
  225. package/dist/components/LpLightbox.vue.d.ts +8 -0
  226. package/dist/components/LpLightbox.vue.js +1 -1
  227. package/dist/components/LpLoader.vue.d.ts +1 -1
  228. package/dist/components/LpLoader.vue.js +1 -1
  229. package/dist/components/LpLogInspector.vue.d.ts +18 -0
  230. package/dist/components/LpLogInspector.vue.js +4 -0
  231. package/dist/components/LpLogViewer.vue.d.ts +93 -0
  232. package/dist/components/LpLogViewer.vue.js +1 -1
  233. package/dist/components/LpMapPicker.vue.js +1 -1
  234. package/dist/components/LpMasonry.vue.js +1 -1
  235. package/dist/components/LpMediaGallery.vue.js +1 -1
  236. package/dist/components/LpModal.vue.d.ts +4 -2
  237. package/dist/components/LpModal.vue.js +1 -1
  238. package/dist/components/LpModalNav.vue.d.ts +5 -5
  239. package/dist/components/LpModalNav.vue.js +1 -1
  240. package/dist/components/LpNotificationBell.vue.d.ts +2 -2
  241. package/dist/components/LpNotificationBell.vue.js +1 -1
  242. package/dist/components/LpNumberField.vue.d.ts +13 -2
  243. package/dist/components/LpNumberField.vue.js +1 -1
  244. package/dist/components/LpOtpInput.vue.js +1 -1
  245. package/dist/components/LpPageScrollbar.vue.d.ts +10 -0
  246. package/dist/components/LpPageScrollbar.vue.js +4 -0
  247. package/dist/components/LpPagination.vue.js +1 -1
  248. package/dist/components/LpPaletteFacts.vue.js +1 -1
  249. package/dist/components/LpPaletteHeader.vue.js +2 -2
  250. package/dist/components/LpPaletteTheme.vue.js +1 -1
  251. package/dist/components/LpPasswordInput.vue.js +1 -1
  252. package/dist/components/LpPhoneInput.vue.js +1 -1
  253. package/dist/components/LpPie.vue.d.ts +2 -2
  254. package/dist/components/LpPie.vue.js +1 -1
  255. package/dist/components/LpPipeline.vue.d.ts +4 -0
  256. package/dist/components/LpPipeline.vue.js +1 -1
  257. package/dist/components/LpPopover.vue.d.ts +7 -3
  258. package/dist/components/LpPopover.vue.js +1 -1
  259. package/dist/components/LpProgress.vue.d.ts +1 -1
  260. package/dist/components/LpProgress.vue.js +1 -1
  261. package/dist/components/LpQuota.vue.js +1 -1
  262. package/dist/components/LpRadioGroup.vue.js +1 -1
  263. package/dist/components/LpRangeCalendar.vue.js +1 -1
  264. package/dist/components/LpRangeSlider.vue.js +1 -1
  265. package/dist/components/LpRelativeTime.vue.js +1 -1
  266. package/dist/components/LpRepeater.vue.js +1 -1
  267. package/dist/components/LpRevealOnScroll.vue.js +1 -1
  268. package/dist/components/LpScramble.vue.js +1 -1
  269. package/dist/components/LpScrollArea.vue.js +1 -1
  270. package/dist/components/LpSecretField.vue.js +1 -1
  271. package/dist/components/LpSection.vue.js +1 -1
  272. package/dist/components/LpSegmented.vue.js +1 -1
  273. package/dist/components/LpSelect.vue.js +1 -1
  274. package/dist/components/LpServiceNode.vue.d.ts +8 -2
  275. package/dist/components/LpServiceNode.vue.js +1 -1
  276. package/dist/components/LpShaderBackdrop.vue.js +1 -1
  277. package/dist/components/LpShift.vue.js +1 -1
  278. package/dist/components/LpShortcutsDialog.vue.js +1 -1
  279. package/dist/components/LpSidebar.vue.d.ts +1 -1
  280. package/dist/components/LpSidebar.vue.js +1 -1
  281. package/dist/components/LpSidebarNav.vue.js +1 -1
  282. package/dist/components/LpSidebarRow.vue.js +1 -1
  283. package/dist/components/LpSlider.vue.js +1 -1
  284. package/dist/components/LpSparkline.vue.d.ts +1 -1
  285. package/dist/components/LpSpotlight.vue.js +1 -1
  286. package/dist/components/LpStat.vue.d.ts +16 -0
  287. package/dist/components/LpStat.vue.js +1 -1
  288. package/dist/components/LpStatus.vue.js +1 -1
  289. package/dist/components/LpStepMark.vue.js +1 -1
  290. package/dist/components/LpStepper.vue.js +1 -1
  291. package/dist/components/LpSwap.vue.js +1 -1
  292. package/dist/components/LpSwitch.vue.js +1 -1
  293. package/dist/components/LpTabFace.vue.js +1 -1
  294. package/dist/components/LpTable.vue.d.ts +132 -0
  295. package/dist/components/LpTable.vue.js +547 -135
  296. package/dist/components/LpTableFilter.vue.js +1 -1
  297. package/dist/components/LpTableOfContents.vue.js +1 -1
  298. package/dist/components/LpTabs.vue.js +6 -5
  299. package/dist/components/LpTagsInput.vue.js +1 -1
  300. package/dist/components/LpTextarea.vue.js +1 -1
  301. package/dist/components/LpThemeProvider.vue.d.ts +2 -0
  302. package/dist/components/LpThemeProvider.vue.js +1 -1
  303. package/dist/components/LpThemeStudio.vue.js +1 -1
  304. package/dist/components/LpThemeSwitcher.vue.js +1 -1
  305. package/dist/components/LpTimeField.vue.js +1 -1
  306. package/dist/components/LpToaster.vue.js +1 -1
  307. package/dist/components/LpTooltip.vue.js +1 -1
  308. package/dist/components/LpTopologyCanvas.vue.d.ts +131 -5
  309. package/dist/components/LpTopologyCanvas.vue.js +1 -1
  310. package/dist/components/LpTour.vue.js +1 -1
  311. package/dist/components/LpTruncate.vue.js +1 -1
  312. package/dist/components/LpTypewriter.vue.js +1 -1
  313. package/dist/components/LpUptimeBar.vue.js +1 -1
  314. package/dist/components/LpVideoBackdrop.vue.js +1 -1
  315. package/dist/components/LpWindow.vue.d.ts +99 -0
  316. package/dist/components/LpWindow.vue.js +4 -0
  317. package/dist/components/LpWorkspaceSwitcher.vue.d.ts +18 -0
  318. package/dist/components/LpWorkspaceSwitcher.vue.js +4 -0
  319. package/dist/components/MenuTitle.vue.js +1 -1
  320. package/dist/components/OptionContent.vue.js +1 -1
  321. package/dist/components/PickerField.vue.d.ts +2 -2
  322. package/dist/components/PickerField.vue.js +1 -1
  323. package/dist/components/RevealToggle.vue.js +1 -1
  324. package/dist/components/SliderRail.vue.d.ts +3 -0
  325. package/dist/components/SliderRail.vue.js +4 -0
  326. package/dist/components/TourCard.vue.js +1 -1
  327. package/dist/components/address.js +2 -1
  328. package/dist/components/appShell.d.ts +36 -0
  329. package/dist/components/appShell.js +30 -0
  330. package/dist/components/calendar.d.ts +12 -3
  331. package/dist/components/calendar.js +2 -5
  332. package/dist/components/chart.d.ts +21 -0
  333. package/dist/components/chart.js +4 -3
  334. package/dist/components/chartWindow.d.ts +57 -0
  335. package/dist/components/chartWindow.js +136 -0
  336. package/dist/components/color.js +1 -1
  337. package/dist/components/commandPalette.d.ts +16 -2
  338. package/dist/components/commandPalette.js +39 -4
  339. package/dist/components/controlSize.d.ts +5 -0
  340. package/dist/components/controlSize.js +8 -0
  341. package/dist/components/dropdown.d.ts +5 -0
  342. package/dist/components/dropdown.js +2 -0
  343. package/dist/components/exportData.d.ts +6 -1
  344. package/dist/components/exportData.js +25 -18
  345. package/dist/components/fileTree.d.ts +67 -0
  346. package/dist/components/fileTree.js +141 -1
  347. package/dist/components/identicon.js +3 -2
  348. package/dist/components/logTools.d.ts +93 -0
  349. package/dist/components/logTools.js +210 -0
  350. package/dist/components/menuWhen.js +1 -1
  351. package/dist/components/meter.js +2 -1
  352. package/dist/components/pipeline.d.ts +2 -0
  353. package/dist/components/pipeline.js +5 -0
  354. package/dist/components/relativeTime.js +2 -1
  355. package/dist/components/reveal.js +2 -1
  356. package/dist/components/scrollbar.d.ts +34 -0
  357. package/dist/components/scrollbar.js +47 -0
  358. package/dist/components/select.d.ts +5 -0
  359. package/dist/components/select.js +10 -0
  360. package/dist/components/sidebar.d.ts +1 -0
  361. package/dist/components/tableFeatures.d.ts +58 -0
  362. package/dist/components/tableFeatures.js +87 -0
  363. package/dist/components/topologyGraph.d.ts +164 -0
  364. package/dist/components/topologyGraph.js +416 -0
  365. package/dist/components/tour.js +5 -3
  366. package/dist/components/videoBackdrop.js +7 -6
  367. package/dist/composables/clamp.d.ts +2 -0
  368. package/dist/composables/clamp.js +4 -0
  369. package/dist/composables/devWarn.d.ts +3 -0
  370. package/dist/composables/devWarn.js +14 -0
  371. package/dist/composables/easing.d.ts +13 -4
  372. package/dist/composables/easing.js +16 -10
  373. package/dist/composables/overlayHistory.js +14 -1
  374. package/dist/composables/pointerDrag.d.ts +15 -0
  375. package/dist/composables/pointerDrag.js +40 -0
  376. package/dist/composables/propCheck.d.ts +10 -0
  377. package/dist/composables/propCheck.js +89 -0
  378. package/dist/composables/realm.d.ts +6 -0
  379. package/dist/composables/realm.js +23 -0
  380. package/dist/composables/scroll.js +4 -2
  381. package/dist/composables/scrollMemory.d.ts +12 -1
  382. package/dist/composables/scrollMemory.js +36 -12
  383. package/dist/composables/spatialNav.js +2 -1
  384. package/dist/composables/textEntry.d.ts +17 -0
  385. package/dist/composables/textEntry.js +19 -0
  386. package/dist/composables/useAsyncTask.d.ts +6 -0
  387. package/dist/composables/useChartSync.d.ts +5 -0
  388. package/dist/composables/useChartSync.js +33 -0
  389. package/dist/composables/useCloseGuard.d.ts +3 -1
  390. package/dist/composables/useCloseGuard.js +6 -3
  391. package/dist/composables/useCommands.d.ts +50 -0
  392. package/dist/composables/useCommands.js +66 -0
  393. package/dist/composables/useField.d.ts +37 -0
  394. package/dist/composables/useField.js +27 -2
  395. package/dist/composables/useFitScale.js +4 -1
  396. package/dist/composables/useFormDraft.d.ts +13 -2
  397. package/dist/composables/useFormDraft.js +17 -9
  398. package/dist/composables/useHintSystem.js +2 -2
  399. package/dist/composables/useHotkeys.js +11 -32
  400. package/dist/composables/useInView.js +2 -1
  401. package/dist/composables/useInputFilter.js +7 -5
  402. package/dist/composables/useInputMask.js +5 -3
  403. package/dist/composables/useLinkedView.d.ts +97 -0
  404. package/dist/composables/useLinkedView.js +139 -0
  405. package/dist/composables/useOptimisticToggle.d.ts +3 -1
  406. package/dist/composables/useOptimisticToggle.js +2 -1
  407. package/dist/composables/useOverlayHistory.d.ts +7 -0
  408. package/dist/composables/useOverlayHistory.js +16 -2
  409. package/dist/composables/usePaintSelect.js +18 -14
  410. package/dist/composables/usePaletteCommands.d.ts +7 -0
  411. package/dist/composables/usePaletteCommands.js +16 -3
  412. package/dist/composables/usePersisted.d.ts +10 -0
  413. package/dist/composables/usePersisted.js +1 -1
  414. package/dist/composables/usePillTransition.d.ts +2 -2
  415. package/dist/composables/usePillTransition.js +5 -5
  416. package/dist/composables/useResizeObserver.js +2 -1
  417. package/dist/composables/useReveal.js +2 -1
  418. package/dist/composables/useRovingFocus.d.ts +2 -2
  419. package/dist/composables/useRovingFocus.js +9 -11
  420. package/dist/composables/useScramble.js +7 -1
  421. package/dist/composables/useShift.js +8 -6
  422. package/dist/composables/useTilt.js +2 -1
  423. package/dist/composables/useTween.js +9 -5
  424. package/dist/composables/useView.d.ts +1 -0
  425. package/dist/composables/useView.js +14 -2
  426. package/dist/composables/useZoomPan.js +2 -4
  427. package/dist/composables/windowing.d.ts +40 -0
  428. package/dist/composables/windowing.js +118 -0
  429. package/dist/icons-all.js +1 -1
  430. package/dist/icons.d.ts +4 -0
  431. package/dist/index.d.ts +31 -5
  432. package/dist/index.js +312 -264
  433. package/dist/layout/tree.js +19 -15
  434. package/dist/layout/useLayout.d.ts +2 -0
  435. package/dist/layout/useLayout.js +5 -1
  436. package/dist/layout/useWorkspaces.d.ts +52 -0
  437. package/dist/layout/useWorkspaces.js +140 -0
  438. package/dist/{chunks/backdrop-Dkf2vM81.js → theme/backdrop.js} +5 -5
  439. package/dist/theme/config.js +25 -0
  440. package/dist/theme/define.js +61 -0
  441. package/dist/{chunks/palette-Co8tSASo.js → theme/palette.js} +2 -2
  442. package/dist/theme/presets.js +239 -0
  443. package/dist/theme/studio.js +134 -0
  444. package/dist/theme/tokens.js +63 -0
  445. package/dist/theme/useTheme.d.ts +3 -2
  446. package/dist/theme/useTheme.js +325 -0
  447. package/package.json +8 -1
  448. package/src/component-names.ts +6 -1
  449. package/src/components/AppShellContextNav.vue +44 -0
  450. package/src/components/ChartRangeSelector.vue +120 -0
  451. package/src/components/FieldLeading.vue +17 -0
  452. package/src/components/IconCloseButton.vue +21 -0
  453. package/src/components/LayoutCanvas.vue +3 -0
  454. package/src/components/LayoutNode.vue +37 -38
  455. package/src/components/LpActivityLine.vue +4 -2
  456. package/src/components/LpAddressInput.vue +3 -3
  457. package/src/components/LpAppShell.vue +385 -24
  458. package/src/components/LpAutocomplete.vue +13 -30
  459. package/src/components/LpBottomNav.vue +9 -1
  460. package/src/components/LpBreadcrumbs.vue +2 -1
  461. package/src/components/LpButton.vue +11 -4
  462. package/src/components/LpChart.vue +336 -37
  463. package/src/components/LpCheckbox.vue +43 -9
  464. package/src/components/LpCodeBlock.vue +17 -23
  465. package/src/components/LpCollapse.vue +5 -4
  466. package/src/components/LpColorPicker.vue +8 -9
  467. package/src/components/LpCommandPalette.vue +133 -50
  468. package/src/components/LpContextMenu.vue +22 -13
  469. package/src/components/LpCountdown.vue +2 -1
  470. package/src/components/LpDataList.vue +13 -1
  471. package/src/components/LpDatePicker.vue +5 -17
  472. package/src/components/LpDateRangePicker.vue +5 -16
  473. package/src/components/LpDock.vue +25 -16
  474. package/src/components/LpDrawer.vue +70 -61
  475. package/src/components/LpDropdownMenu.vue +6 -10
  476. package/src/components/LpDropzone.vue +12 -7
  477. package/src/components/LpEditable.vue +6 -2
  478. package/src/components/LpFileTree.vue +507 -66
  479. package/src/components/LpFileTreeNode.vue +106 -5
  480. package/src/components/LpFormField.vue +1 -1
  481. package/src/components/LpFrame.vue +33 -13
  482. package/src/components/LpHoverCard.vue +37 -5
  483. package/src/components/LpIcon.vue +6 -2
  484. package/src/components/LpIdenticon.vue +2 -1
  485. package/src/components/LpImageEditor.vue +5 -2
  486. package/src/components/LpInfraNode.vue +4 -3
  487. package/src/components/LpInput.vue +19 -26
  488. package/src/components/LpInspector.vue +197 -0
  489. package/src/components/LpLaneNode.vue +5 -1
  490. package/src/components/LpLightbox.vue +74 -29
  491. package/src/components/LpLogInspector.vue +85 -0
  492. package/src/components/LpLogViewer.vue +239 -29
  493. package/src/components/LpMapPicker.vue +2 -1
  494. package/src/components/LpMasonry.vue +8 -5
  495. package/src/components/LpModal.vue +12 -12
  496. package/src/components/LpModalNav.vue +2 -21
  497. package/src/components/LpNumberField.vue +13 -16
  498. package/src/components/LpOtpInput.vue +2 -2
  499. package/src/components/LpPageScrollbar.vue +195 -0
  500. package/src/components/LpPagination.vue +5 -3
  501. package/src/components/LpPhoneInput.vue +8 -19
  502. package/src/components/LpPie.vue +25 -23
  503. package/src/components/LpPipeline.vue +14 -1
  504. package/src/components/LpPopover.vue +23 -2
  505. package/src/components/LpProgress.vue +2 -1
  506. package/src/components/LpRadioGroup.vue +2 -2
  507. package/src/components/LpRangeSlider.vue +5 -6
  508. package/src/components/LpRevealOnScroll.vue +1 -1
  509. package/src/components/LpScrollArea.vue +55 -34
  510. package/src/components/LpSecretField.vue +2 -1
  511. package/src/components/LpSegmented.vue +6 -8
  512. package/src/components/LpSelect.vue +54 -24
  513. package/src/components/LpServiceNode.vue +4 -2
  514. package/src/components/LpShaderBackdrop.vue +12 -9
  515. package/src/components/LpShift.vue +18 -15
  516. package/src/components/LpSidebar.vue +77 -74
  517. package/src/components/LpSidebarNav.vue +3 -2
  518. package/src/components/LpSidebarRow.vue +2 -1
  519. package/src/components/LpSlider.vue +5 -6
  520. package/src/components/LpSpotlight.vue +2 -1
  521. package/src/components/LpStat.vue +25 -5
  522. package/src/components/LpSwitch.vue +5 -3
  523. package/src/components/LpTable.vue +609 -93
  524. package/src/components/LpTableFilter.vue +1 -1
  525. package/src/components/LpTableOfContents.vue +16 -9
  526. package/src/components/LpTabs.vue +2 -1
  527. package/src/components/LpTagsInput.vue +12 -19
  528. package/src/components/LpTextarea.vue +5 -11
  529. package/src/components/LpThemeProvider.vue +29 -13
  530. package/src/components/LpTimeField.vue +4 -7
  531. package/src/components/LpToaster.vue +7 -6
  532. package/src/components/LpTooltip.vue +69 -18
  533. package/src/components/LpTopologyCanvas.vue +569 -42
  534. package/src/components/LpTour.vue +7 -5
  535. package/src/components/LpTruncate.vue +4 -3
  536. package/src/components/LpTypewriter.vue +2 -1
  537. package/src/components/LpVideoBackdrop.vue +11 -13
  538. package/src/components/LpWindow.vue +373 -0
  539. package/src/components/LpWorkspaceSwitcher.vue +116 -0
  540. package/src/components/PickerField.vue +2 -2
  541. package/src/components/SliderRail.vue +10 -0
  542. package/src/components/address.ts +3 -1
  543. package/src/components/appShell.ts +74 -0
  544. package/src/components/calendar.ts +12 -5
  545. package/src/components/chart.ts +27 -3
  546. package/src/components/chartWindow.ts +198 -0
  547. package/src/components/color.ts +2 -1
  548. package/src/components/commandPalette.ts +66 -5
  549. package/src/components/controlSize.ts +6 -0
  550. package/src/components/dropdown.ts +3 -0
  551. package/src/components/exportData.ts +33 -18
  552. package/src/components/fileTree.ts +215 -0
  553. package/src/components/identicon.ts +4 -2
  554. package/src/components/logTools.ts +298 -0
  555. package/src/components/meter.ts +2 -1
  556. package/src/components/pipeline.ts +6 -0
  557. package/src/components/relativeTime.ts +2 -1
  558. package/src/components/reveal.ts +3 -1
  559. package/src/components/scrollbar.ts +71 -0
  560. package/src/components/select.ts +14 -0
  561. package/src/components/sidebar.ts +1 -0
  562. package/src/components/tableFeatures.ts +149 -0
  563. package/src/components/topologyGraph.ts +655 -0
  564. package/src/components/tour.ts +5 -3
  565. package/src/components/videoBackdrop.ts +7 -6
  566. package/src/composables/clamp.ts +2 -0
  567. package/src/composables/devWarn.ts +19 -0
  568. package/src/composables/easing.ts +37 -12
  569. package/src/composables/overlayHistory.ts +24 -0
  570. package/src/composables/pointerDrag.ts +54 -0
  571. package/src/composables/propCheck.ts +105 -0
  572. package/src/composables/realm.ts +25 -0
  573. package/src/composables/scroll.ts +4 -2
  574. package/src/composables/scrollMemory.ts +56 -14
  575. package/src/composables/spatialNav.ts +2 -1
  576. package/src/composables/textEntry.ts +33 -0
  577. package/src/composables/useAsyncTask.ts +6 -0
  578. package/src/composables/useChartSync.ts +52 -0
  579. package/src/composables/useCloseGuard.ts +22 -10
  580. package/src/composables/useCommands.ts +123 -0
  581. package/src/composables/useField.ts +41 -2
  582. package/src/composables/useFitScale.ts +4 -1
  583. package/src/composables/useFormDraft.ts +38 -14
  584. package/src/composables/useHintSystem.ts +2 -2
  585. package/src/composables/useHotkeys.ts +19 -48
  586. package/src/composables/useInView.ts +2 -1
  587. package/src/composables/useInputFilter.ts +8 -5
  588. package/src/composables/useInputMask.ts +8 -3
  589. package/src/composables/useLinkedView.ts +222 -0
  590. package/src/composables/useOptimisticToggle.ts +7 -1
  591. package/src/composables/useOverlayHistory.ts +20 -0
  592. package/src/composables/usePaintSelect.ts +20 -14
  593. package/src/composables/usePaletteCommands.ts +18 -2
  594. package/src/composables/usePersisted.ts +10 -0
  595. package/src/composables/usePillTransition.ts +9 -6
  596. package/src/composables/useResizeObserver.ts +2 -1
  597. package/src/composables/useReveal.ts +2 -1
  598. package/src/composables/useRovingFocus.ts +11 -14
  599. package/src/composables/useScramble.ts +12 -1
  600. package/src/composables/useShift.ts +8 -6
  601. package/src/composables/useTilt.ts +2 -1
  602. package/src/composables/useTween.ts +10 -5
  603. package/src/composables/useView.ts +17 -3
  604. package/src/composables/useZoomPan.ts +2 -5
  605. package/src/composables/windowing.ts +190 -0
  606. package/src/icons.ts +27 -6
  607. package/src/index.ts +42 -4
  608. package/src/kit-icons.ts +1 -1
  609. package/src/layout/tree.ts +31 -16
  610. package/src/layout/useLayout.ts +6 -0
  611. package/src/layout/useWorkspaces.ts +234 -0
  612. package/src/nuxt.ts +9 -1
  613. package/src/runtime/propCheck.plugin.ts +10 -0
  614. package/src/theme/studio.ts +7 -5
  615. package/src/theme/useTheme.ts +89 -15
  616. package/src/tokens/tokens.css +8 -1
  617. package/dist/assets/LpTabs-CJ0rYQbx.css +0 -18
  618. package/dist/chunks/LpAppShell-Dgejipzz.js +0 -319
  619. package/dist/chunks/LpFileTree-CooHinsC.js +0 -425
  620. package/dist/chunks/LpThemeProvider-8MG6yqU9.js +0 -640
  621. package/dist/chunks/LpTopologyCanvas-B1gIbS0n.js +0 -298
@@ -25,6 +25,7 @@
25
25
  * The mechanism — measure the natural size, pin it in pixels, tween — lives in
26
26
  * `useShift`, and LpModal drives its panel with the same composable.
27
27
  */
28
+ import { isElement, isHTMLElement, nodeWindow } from "../composables/useView"
28
29
  import { computed, onBeforeUnmount, watch } from "vue"
29
30
  import { prefersReducedMotion } from "../composables/easing"
30
31
  import { useShift, type ShiftAxis } from "../composables/useShift"
@@ -99,6 +100,7 @@ const transitionClass = computed(() => TRANSITION_CLASS[props.axis])
99
100
  const PRESENCE_MS = 200
100
101
  const MOVE_MS = 160
101
102
  const EASE = "cubic-bezier(0.2, 0, 0, 1)"
103
+ const SVG_NS = "http://www.w3.org/2000/svg"
102
104
  const GHOST = "data-lp-shift-ghost"
103
105
 
104
106
  interface Seen {
@@ -120,7 +122,7 @@ function rememberSoon(box: HTMLElement, wait = PRESENCE_MS + 80) {
120
122
  }
121
123
 
122
124
  function elementsOf(box: HTMLElement): Element[] {
123
- return [...box.querySelectorAll("*")].filter((node) => !node.closest(`[${GHOST}]`) && !(node instanceof SVGElement && !(node instanceof SVGSVGElement)))
125
+ return [...box.querySelectorAll("*")].filter((node) => !node.closest(`[${GHOST}]`) && !(node.namespaceURI === SVG_NS && node.localName !== "svg"))
124
126
  }
125
127
 
126
128
  function remember(box: HTMLElement) {
@@ -142,7 +144,7 @@ function remember(box: HTMLElement) {
142
144
  // override that animation's transform, and the marker would pop instead of
143
145
  // sliding.
144
146
  function inFlow(node: Element): boolean {
145
- const position = getComputedStyle(node).position
147
+ const position = nodeWindow(node).getComputedStyle(node).position
146
148
  return position !== "absolute" && position !== "fixed"
147
149
  }
148
150
 
@@ -150,7 +152,7 @@ function inFlow(node: Element): boolean {
150
152
  // actions, a list re-keyed after a reload) is not a change anyone sees, so the
151
153
  // pair is left alone rather than flashing out and in.
152
154
  function signature(node: Node): string | undefined {
153
- return node instanceof Element ? node.outerHTML : undefined
155
+ return isElement(node) ? node.outerHTML : undefined
154
156
  }
155
157
 
156
158
  function unchanged(records: MutationRecord[]): Set<Node> {
@@ -172,7 +174,7 @@ const offset = () => (props.anchor === "end" ? -6 : 6)
172
174
 
173
175
  function ghost(box: HTMLElement, node: Element) {
174
176
  const at = seen.get(node)
175
- if (!at || !at.flow || !(node instanceof HTMLElement) || node.hasAttribute(GHOST) || at.width === 0) return
177
+ if (!at || !at.flow || !isHTMLElement(node) || node.hasAttribute(GHOST) || at.width === 0) return
176
178
  const copy = node.cloneNode(true) as HTMLElement
177
179
  copy.setAttribute(GHOST, "")
178
180
  copy.setAttribute("aria-hidden", "true")
@@ -207,7 +209,7 @@ function ghost(box: HTMLElement, node: Element) {
207
209
  }
208
210
 
209
211
  function arrive(node: Element) {
210
- if (!(node instanceof HTMLElement) || node.hasAttribute(GHOST) || !inFlow(node)) return
212
+ if (!isHTMLElement(node) || node.hasAttribute(GHOST) || !inFlow(node)) return
211
213
  node.animate(
212
214
  [
213
215
  { opacity: 0, transform: `translateX(${offset()}px) scale(0.96)`, filter: "blur(2px)" },
@@ -219,7 +221,7 @@ function arrive(node: Element) {
219
221
 
220
222
  function glide(node: Element) {
221
223
  const was = seen.get(node)
222
- if (!was || !(node instanceof HTMLElement)) return
224
+ if (!was || !isHTMLElement(node)) return
223
225
  const now = node.getBoundingClientRect()
224
226
  const dx = was.x - now.left
225
227
  const dy = was.y - now.top
@@ -236,25 +238,26 @@ watch(
236
238
  presenceSize = undefined
237
239
  if (!box || !on) return
238
240
  remember(box)
239
- presenceObserver = new MutationObserver((records) => {
241
+ const win = nodeWindow(box)
242
+ presenceObserver = new win.MutationObserver((records) => {
240
243
  const real = records.filter(
241
244
  (r) =>
242
- ![...r.addedNodes, ...r.removedNodes].every((n) => n instanceof Element && n.hasAttribute(GHOST)),
245
+ ![...r.addedNodes, ...r.removedNodes].every((n) => isElement(n) && n.hasAttribute(GHOST)),
243
246
  )
244
- if (real.length && !prefersReducedMotion()) {
247
+ if (real.length && !prefersReducedMotion(win)) {
245
248
  const added = new Set<Node>()
246
249
  const same = unchanged(real)
247
250
  for (const record of real) {
248
- record.removedNodes.forEach((node) => node instanceof Element && !same.has(node) && ghost(box, node))
251
+ record.removedNodes.forEach((node) => isElement(node) && !same.has(node) && ghost(box, node))
249
252
  record.addedNodes.forEach((node) => {
250
253
  added.add(node)
251
- if (node instanceof Element && !same.has(node)) arrive(node)
254
+ if (isElement(node) && !same.has(node)) arrive(node)
252
255
  })
253
256
  }
254
257
  // Measured in the next frame, which still comes before the paint: by
255
258
  // then the box has taken the classes the change gave it (held to its
256
259
  // edge), and the place an element lands is the one it will keep.
257
- const parents = real.map((r) => r.target).filter((t): t is Element => t instanceof Element && !t.hasAttribute(GHOST))
260
+ const parents = real.map((r) => r.target).filter((t): t is Element => isElement(t) && !t.hasAttribute(GHOST))
258
261
  requestAnimationFrame(() => {
259
262
  for (const parent of parents) for (const child of parent.children) if (!added.has(child)) glide(child)
260
263
  })
@@ -262,9 +265,9 @@ watch(
262
265
  rememberSoon(box)
263
266
  })
264
267
  presenceObserver.observe(box, { childList: true, subtree: true })
265
- presenceSize = new ResizeObserver(() => rememberSoon(box, 60))
268
+ presenceSize = new win.ResizeObserver(() => rememberSoon(box, 60))
266
269
  presenceSize.observe(box)
267
- void document.fonts?.ready.then(() => rememberSoon(box, 0))
270
+ void box.ownerDocument.fonts?.ready.then(() => rememberSoon(box, 0))
268
271
  },
269
272
  { flush: "post" },
270
273
  )
@@ -274,7 +277,7 @@ watch(
274
277
  // resize, every child glides from where it was last seen.
275
278
  watch(resizing, (now) => {
276
279
  const box = el.value
277
- if (!now || !box || !presenceObserver || prefersReducedMotion()) return
280
+ if (!now || !box || !presenceObserver || prefersReducedMotion(nodeWindow(box))) return
278
281
  requestAnimationFrame(() => {
279
282
  for (const child of box.children) if (!child.hasAttribute(GHOST)) glide(child)
280
283
  })
@@ -13,8 +13,10 @@
13
13
  * auto-closes the drawer. With `responsive` off the component renders exactly
14
14
  * the static <nav> it always has — existing call sites are unaffected.
15
15
  */
16
- import { computed, nextTick, ref, useId } from "vue"
16
+ import { clamp } from "../composables/clamp"
17
+ import { computed, nextTick, onBeforeUnmount, ref, useId } from "vue"
17
18
  import { parseCombo, useHotkeys } from "../composables/useHotkeys"
19
+ import { startPointerDrag } from "../composables/pointerDrag"
18
20
  import { usePersisted } from "../composables/usePersisted"
19
21
  import { useLabels } from "../composables/useLpConfig"
20
22
  import LpDrawer from "./LpDrawer.vue"
@@ -123,7 +125,7 @@ const props = withDefaults(
123
125
  persist?: string
124
126
  /**
125
127
  * Fold collapsible groups automatically once the nav has more than this
126
- * many rows, counting headings and items alike.
128
+ * many rows, counting headings, items and the pages under them alike.
127
129
  *
128
130
  * The reason is the reader, not the pixels: a short nav is taken in at a
129
131
  * glance, a long one has to be searched, and searching a list you did not
@@ -310,9 +312,12 @@ const ownCollapsed = usePersisted<string[] | null>(
310
312
  { validate: (value): value is string[] | null => value === null || (Array.isArray(value) && value.every((k) => typeof k === "string")) },
311
313
  )
312
314
 
313
- /** Headings + items: what the eye actually has to walk past. */
314
- const navLength = computed(
315
- () => groups.value.reduce((n, g) => n + g.items.length + (g.title ? 1 : 0), 0),
315
+ /** Headings, items and their pages: what the eye actually has to walk past. */
316
+ const navLength = computed(() =>
317
+ groups.value.reduce(
318
+ (n, g) => n + (g.title ? 1 : 0) + g.items.reduce((rows, i) => rows + 1 + (i.children?.length ?? 0), 0),
319
+ 0,
320
+ ),
316
321
  )
317
322
 
318
323
  /*
@@ -340,7 +345,9 @@ function toggleSection(key: string, collapsed: boolean) {
340
345
  const next = collapsed
341
346
  ? [...new Set([...collapsedKeys.value, key])]
342
347
  : collapsedKeys.value.filter((k) => k !== key)
343
- ownCollapsed.value = next
348
+ // A bound value is the app's: storing it too would surface a stale choice
349
+ // the day the binding goes. The same goes for compact and pins below.
350
+ if (props.collapsed === undefined) ownCollapsed.value = next
344
351
  emit("update:collapsed", next)
345
352
  }
346
353
 
@@ -351,7 +358,7 @@ function toggleSection(key: string, collapsed: boolean) {
351
358
  const ownCompact = usePersisted<boolean>(() => props.persist && `lp-sidebar:${props.persist}:compact`, false)
352
359
  const isCompact = computed(() => props.compact ?? ownCompact.value)
353
360
  function setCompact(value: boolean) {
354
- ownCompact.value = value
361
+ if (props.compact === undefined) ownCompact.value = value
355
362
  emit("update:compact", value)
356
363
  }
357
364
 
@@ -370,12 +377,20 @@ const env = computed(() => {
370
377
 
371
378
  const DEFAULT_WIDTH = 240
372
379
  const COMPACT_WIDTH = 64
373
- const ownWidth = usePersisted<number>(() => props.resizable && props.persist && `lp-sidebar:${props.persist}:width`, DEFAULT_WIDTH)
380
+ const ownWidth = usePersisted<number>(() => props.resizable && props.persist && `lp-sidebar:${props.persist}:width`, DEFAULT_WIDTH, {
381
+ validate: (value): value is number => typeof value === "number" && Number.isFinite(value),
382
+ })
374
383
  const dragging = ref(false)
375
384
 
385
+ /*
386
+ * The bounds apply to what is drawn, not to what is kept: a width remembered
387
+ * under other bounds fits today's, and comes back if they widen again.
388
+ */
389
+ const boundedWidth = (width: number) => clamp(width, props.minWidth, props.maxWidth)
390
+
376
391
  const railWidth = computed(() => {
377
392
  if (isCompact.value) return `${COMPACT_WIDTH}px`
378
- if (props.resizable) return `${ownWidth.value}px`
393
+ if (props.resizable) return `${boundedWidth(ownWidth.value)}px`
379
394
  return props.width
380
395
  })
381
396
 
@@ -385,34 +400,32 @@ const railWidth = computed(() => {
385
400
  * useful, and the icon rail is the honest form of "narrow".
386
401
  */
387
402
  const FOLD_AT = 132
403
+ let stopResize: (() => void) | null = null
404
+ onBeforeUnmount(() => stopResize?.())
405
+
388
406
  function startResize(event: PointerEvent) {
389
407
  if (event.button !== 0) return
390
- const handle = event.currentTarget as HTMLElement
391
- handle.setPointerCapture(event.pointerId)
392
408
  const from = event.clientX
393
- const start = isCompact.value ? COMPACT_WIDTH : ownWidth.value
409
+ const start = isCompact.value ? COMPACT_WIDTH : boundedWidth(ownWidth.value)
394
410
  dragging.value = true
395
- const move = (e: PointerEvent) => {
396
- const wanted = start + (e.clientX - from)
397
- if (wanted < FOLD_AT) {
398
- // Folded by dragging: the width it unfolds to is the one it had, not
399
- // the narrowest the drag passed through on its way down.
400
- if (!isCompact.value) setCompact(true)
401
- if (start !== COMPACT_WIDTH) ownWidth.value = start
402
- return
403
- }
404
- if (isCompact.value) setCompact(false)
405
- ownWidth.value = Math.round(Math.min(props.maxWidth, Math.max(props.minWidth, wanted)))
406
- }
407
- const stop = () => {
408
- dragging.value = false
409
- handle.removeEventListener("pointermove", move)
410
- handle.removeEventListener("pointerup", stop)
411
- handle.removeEventListener("pointercancel", stop)
412
- }
413
- handle.addEventListener("pointermove", move)
414
- handle.addEventListener("pointerup", stop)
415
- handle.addEventListener("pointercancel", stop)
411
+ stopResize = startPointerDrag(event, {
412
+ move(e) {
413
+ const wanted = start + (e.clientX - from)
414
+ if (wanted < FOLD_AT) {
415
+ // Folded by dragging: the width it unfolds to is the one it had, not
416
+ // the narrowest the drag passed through on its way down.
417
+ if (!isCompact.value) setCompact(true)
418
+ if (start !== COMPACT_WIDTH) ownWidth.value = start
419
+ return
420
+ }
421
+ if (isCompact.value) setCompact(false)
422
+ ownWidth.value = Math.round(boundedWidth(wanted))
423
+ },
424
+ end() {
425
+ dragging.value = false
426
+ stopResize = null
427
+ },
428
+ })
416
429
  }
417
430
  const railEl = ref<HTMLElement | null>(null)
418
431
  async function searchFromCompact() {
@@ -451,7 +464,7 @@ const pinnedItems = computed<SidebarItem[]>(() =>
451
464
  )
452
465
  function togglePin(id: string) {
453
466
  const next = pinnedIds.value.includes(id) ? pinnedIds.value.filter((k) => k !== id) : [...pinnedIds.value, id]
454
- ownPinned.value = next
467
+ if (props.pinned === undefined) ownPinned.value = next
455
468
  emit("update:pinned", next)
456
469
  }
457
470
 
@@ -495,6 +508,32 @@ const chromeClass = computed(() =>
495
508
  // Vue can't auto-inherit a consumer-passed `class`. Take attrs over manually and
496
509
  // land them on the desktop rail (where a layout class like `shrink-0` belongs).
497
510
  defineOptions({ inheritAttrs: false })
511
+
512
+ // The rail and the drawer draw the same list and the same search over it.
513
+ const navBinds = computed(() => ({
514
+ groups: groups.value,
515
+ pinnable: props.pinnable,
516
+ pinned: pinnedItems.value,
517
+ previewDelay: props.previewDelay,
518
+ labels: text.value,
519
+ itemActive,
520
+ loading: props.loading,
521
+ skeletonRows: props.skeletonRows,
522
+ skeletonHeader: props.skeletonHeader,
523
+ collapsedKeys: collapsedKeys.value,
524
+ hoverFollow: props.hoverFollow,
525
+ onActivate: activate,
526
+ onToggleSection: toggleSection,
527
+ onTogglePin: togglePin,
528
+ }))
529
+ const searchField = computed(() => ({
530
+ size: "sm" as const,
531
+ icon: "lucide:search",
532
+ clearable: true,
533
+ class: "mb-2 shrink-0",
534
+ placeholder: placeholder.value,
535
+ "aria-label": placeholder.value,
536
+ }))
498
537
  </script>
499
538
 
500
539
  <template>
@@ -558,30 +597,12 @@ defineOptions({ inheritAttrs: false })
558
597
  <LpInput
559
598
  v-if="searchable && !isCompact"
560
599
  v-model="query"
561
- size="sm"
562
- icon="lucide:search"
563
- clearable
564
- class="mb-2 shrink-0"
565
- :placeholder="placeholder"
566
- :aria-label="placeholder"
600
+ v-bind="searchField"
567
601
  />
568
602
  <LpSidebarNav
569
- :groups="groups"
603
+ v-bind="navBinds"
570
604
  :pill-id="railPillId"
571
605
  :compact="isCompact"
572
- :pinnable="pinnable"
573
- :pinned="pinnedItems"
574
- :preview-delay="previewDelay"
575
- :labels="text"
576
- :item-active="itemActive"
577
- :loading="loading"
578
- :skeleton-rows="skeletonRows"
579
- :skeleton-header="skeletonHeader"
580
- :collapsed-keys="collapsedKeys"
581
- :hover-follow="hoverFollow"
582
- @activate="activate"
583
- @toggle-section="toggleSection"
584
- @toggle-pin="togglePin"
585
606
  >
586
607
  <template v-if="$slots.item" #item="slotProps">
587
608
  <slot name="item" v-bind="slotProps" />
@@ -660,29 +681,11 @@ defineOptions({ inheritAttrs: false })
660
681
  <LpInput
661
682
  v-if="searchable"
662
683
  v-model="query"
663
- size="sm"
664
- icon="lucide:search"
665
- clearable
666
- class="mb-2 shrink-0"
667
- :placeholder="placeholder"
668
- :aria-label="placeholder"
684
+ v-bind="searchField"
669
685
  />
670
686
  <LpSidebarNav
671
- :groups="groups"
687
+ v-bind="navBinds"
672
688
  :pill-id="drawerPillId"
673
- :pinnable="pinnable"
674
- :pinned="pinnedItems"
675
- :preview-delay="previewDelay"
676
- :labels="text"
677
- :item-active="itemActive"
678
- :loading="loading"
679
- :skeleton-rows="skeletonRows"
680
- :skeleton-header="skeletonHeader"
681
- :collapsed-keys="collapsedKeys"
682
- :hover-follow="hoverFollow"
683
- @activate="activate"
684
- @toggle-section="toggleSection"
685
- @toggle-pin="togglePin"
686
689
  >
687
690
  <template v-if="$slots.item" #item="slotProps">
688
691
  <slot name="item" v-bind="slotProps" />
@@ -149,7 +149,8 @@ let typedAt = 0
149
149
  function onKey(event: KeyboardEvent) {
150
150
  const box = event.currentTarget as HTMLElement
151
151
  const list = [...box.querySelectorAll<HTMLElement>("[data-lp-nav-row]")].filter((r) => r.offsetParent !== null)
152
- const at = list.indexOf(document.activeElement as HTMLElement)
152
+ // The rows' own document: inside an LpFrame the page's only knows the iframe.
153
+ const at = list.indexOf(box.ownerDocument.activeElement as HTMLElement)
153
154
  if (at < 0) return
154
155
  const row = list[at]!
155
156
  const go = (i: number) => {
@@ -270,7 +271,7 @@ const { class: rootClass, attrs: rest } = useMergedAttrs(
270
271
  @activate="activate"
271
272
  />
272
273
  </div>
273
- <template v-for="(section, si) in groups" :key="si">
274
+ <template v-for="(section, si) in groups" :key="sectionKey(section) || si">
274
275
  <!-- Compact, a group that folds is one icon: its pages open in the card
275
276
  beside it, as a page's own pages do. A hundred initials in a column
276
277
  would be no nav at all. -->
@@ -9,6 +9,7 @@
9
9
  * sidebar it is the row's name (and the pages under it), since the row shows
10
10
  * only an icon; with a `preview` it is a glance at the page before going there.
11
11
  */
12
+ import { clamp } from "../composables/clamp"
12
13
  import { Motion } from "motion-v"
13
14
  import { computed, onBeforeUnmount, ref, watch } from "vue"
14
15
  import { useLocale } from "../composables/useLocale"
@@ -164,7 +165,7 @@ const delay = computed(() => (props.compact && !props.item.preview ? 250 : props
164
165
  <span
165
166
  v-if="typeof item.busy === 'number'"
166
167
  class="block h-full rounded-pill bg-brand transition-[width] duration-(--duration-medium) ease-[var(--ease-emphasized)]"
167
- :style="{ width: `${Math.round(Math.min(1, Math.max(0, item.busy)) * 100)}%` }"
168
+ :style="{ width: `${Math.round(clamp(item.busy, 0, 1) * 100)}%` }"
168
169
  />
169
170
  <span v-else class="lp-sweep absolute inset-y-0 left-0 w-2/5 rounded-pill bg-brand" />
170
171
  </span>
@@ -6,11 +6,12 @@ export default { inheritAttrs: false }
6
6
  </script>
7
7
 
8
8
  <script setup lang="ts">
9
+ import SliderRail from "./SliderRail.vue"
9
10
  import { usePaletteControl, type PaletteControlOptions } from "../composables/usePaletteCommands"
10
11
  // Single-value slider (reka Slider). reka models value as an array; we expose
11
12
  // a plain number for the common single-thumb case. Themed via tokens.
12
- import { SliderRange, SliderRoot, SliderThumb, SliderTrack } from "reka-ui"
13
- import { useFieldControl } from "../composables/useField"
13
+ import { SliderRoot, SliderThumb } from "reka-ui"
14
+ import { useFieldControl, mergeDescribedBy } from "../composables/useField"
14
15
  import { useMergedAttrs } from "../composables/useMergedClass"
15
16
  import { SLIDER_GLIDE, useSliderDrag } from "./slider"
16
17
 
@@ -68,14 +69,12 @@ usePaletteControl({ disabled: () => field.value.disabled })
68
69
  @update:model-value="onUpdate"
69
70
  @value-commit="onCommit"
70
71
  >
71
- <SliderTrack class="relative h-1.5 grow overflow-hidden rounded-pill bg-surface-soft">
72
- <SliderRange class="absolute h-full rounded-pill bg-brand" />
73
- </SliderTrack>
72
+ <SliderRail />
74
73
  <SliderThumb
75
74
  :id="field.id"
76
75
  :aria-label="ariaLabel"
77
76
  :aria-labelledby="ariaLabel ? undefined : field.labelId"
78
- :aria-describedby="field.describedBy"
77
+ :aria-describedby="mergeDescribedBy(rest['aria-describedby'], field.describedBy)"
79
78
  class="block size-4 rounded-pill border-2 border-brand bg-surface shadow outline-none transition-transform duration-[var(--duration-fast)] ease-[var(--ease-emphasized)] hover:scale-110 active:scale-95 focus-visible:ring-2 focus-visible:ring-ring motion-reduce:hover:scale-100 motion-reduce:active:scale-100"
80
79
  />
81
80
  </SliderRoot>
@@ -14,6 +14,7 @@ export default { inheritAttrs: false }
14
14
  * that is not a card. Mouse only; reduced motion draws nothing. The glow is
15
15
  * painted by `.lp-spotlight` in tokens/effects.css.
16
16
  */
17
+ import { clamp } from "../composables/clamp"
17
18
  import { computed } from "vue"
18
19
  import { useMergedAttrs } from "../composables/useMergedClass"
19
20
  import { useSpotlight } from "../composables/useSpotlight"
@@ -39,7 +40,7 @@ const { class: classes, attrs: rest } = useMergedAttrs(() => "lp-spotlight round
39
40
 
40
41
  const style = computed(() => ({
41
42
  "--lp-spot-size": `${props.size}px`,
42
- "--lp-spot-strength": `${Math.min(100, Math.max(0, props.strength))}%`,
43
+ "--lp-spot-strength": `${clamp(props.strength, 0, 100)}%`,
43
44
  ...(props.color ? { "--lp-spot-color": props.color } : {}),
44
45
  }))
45
46
  </script>
@@ -15,7 +15,7 @@ import LpSkeleton from "./LpSkeleton.vue"
15
15
  import LpStatus from "./LpStatus.vue"
16
16
  import { useFitScale } from "../composables/useFitScale"
17
17
  import { useMergedAttrs } from "../composables/useMergedClass"
18
- import { TONES } from "./tone"
18
+ import { TONES, toneOf, type ToneName } from "./tone"
19
19
 
20
20
  const props = withDefaults(
21
21
  defineProps<{
@@ -59,10 +59,26 @@ const props = withDefaults(
59
59
  * (it names the tile, it is not data); an empty one pulses too.
60
60
  */
61
61
  loading?: boolean
62
+ /**
63
+ * Colour of the figure, from the kit's tones (`danger` for offenders,
64
+ * `success`, `warning`…). Unset, it is ink. The delta keeps its own colour.
65
+ */
66
+ tone?: ToneName
67
+ /** Size of the figure: `lg` (the tile's own, text-3xl), `md` or `sm` for a dense row. */
68
+ size?: "sm" | "md" | "lg"
62
69
  }>(),
63
- { trend: "auto", decimals: 0, animateOnMount: true },
70
+ { trend: "auto", decimals: 0, animateOnMount: true, size: "lg" },
64
71
  )
65
72
 
73
+ /* The figure's type, and the variable its fit to the tile scales from. */
74
+ const FIGURE_SIZE = {
75
+ sm: { class: "text-lg", font: "var(--text-lg, 1.125rem)", line: "var(--text-lg--line-height, 1.55)" },
76
+ md: { class: "text-2xl", font: "var(--text-2xl, 1.5rem)", line: "var(--text-2xl--line-height, 1.33)" },
77
+ lg: { class: "text-3xl", font: "var(--text-3xl, 1.875rem)", line: "var(--text-3xl--line-height, 1.2)" },
78
+ } as const
79
+ const figureSize = computed(() => FIGURE_SIZE[props.size])
80
+ const figureColor = computed(() => (props.tone ? TONES[toneOf(props.tone)].text : "text-ink"))
81
+
66
82
  // Resolve the trend direction: explicit wins; "auto" reads a numeric delta.
67
83
  const dir = computed<"up" | "down" | "flat">(() => {
68
84
  if (props.trend !== "auto") return props.trend
@@ -136,7 +152,11 @@ const FIT_MIN = 0.6
136
152
  const row = ref<HTMLElement | null>(null)
137
153
  const figure = ref<HTMLElement | null>(null)
138
154
  const fit = useFitScale(row, figure, FIT_MIN)
139
- const figureStyle = computed(() => (fit.scale.value < 1 ? { fontSize: `calc(var(--text-3xl, 1.875rem) * ${fit.scale.value})`, lineHeight: "calc(var(--text-3xl, 1.875rem) * var(--text-3xl--line-height, 1.2))" } : undefined))
155
+ const figureStyle = computed(() => {
156
+ if (fit.scale.value >= 1) return undefined
157
+ const { font, line } = figureSize.value
158
+ return { fontSize: `calc(${font} * ${fit.scale.value})`, lineHeight: `calc(${font} * ${line})` }
159
+ })
140
160
  const figureTitle = computed(() => (fit.clipped.value && !props.loading ? `${props.prefix ?? ""}${props.value}${props.valueSuffix ?? ""}` : undefined))
141
161
 
142
162
  // A stat tile spaces its label and value on a fixed gap; a dense KPI row needs that tighter.
@@ -168,8 +188,8 @@ const { class: rootClass, attrs: rest } = useMergedAttrs(
168
188
  is the real one: the tile cannot change height when the figure lands. -->
169
189
  <span
170
190
  ref="figure"
171
- class="max-w-full whitespace-nowrap font-mono text-3xl font-medium tracking-tight text-ink"
172
- :class="fit.clipped.value ? 'inline-block overflow-hidden text-ellipsis align-bottom' : ''"
191
+ class="max-w-full whitespace-nowrap font-mono font-medium tracking-tight"
192
+ :class="[figureSize.class, figureColor, fit.clipped.value ? 'inline-block overflow-hidden text-ellipsis align-bottom' : '']"
173
193
  :style="figureStyle"
174
194
  :title="figureTitle"
175
195
  >
@@ -9,7 +9,7 @@ export default { inheritAttrs: false }
9
9
  import { usePaletteControl, type PaletteControlOptions } from "../composables/usePaletteCommands"
10
10
  import { computed, useId, useSlots } from "vue"
11
11
  import { SwitchRoot, SwitchThumb } from "reka-ui"
12
- import { useFieldControl } from "../composables/useField"
12
+ import { mergeDescribedBy, useFieldControl } from "../composables/useField"
13
13
  import { useOptimisticToggle } from "../composables/useOptimisticToggle"
14
14
  import LpLoader from "./LpLoader.vue"
15
15
  import { useMergedAttrs } from "../composables/useMergedClass"
@@ -49,6 +49,8 @@ const emit = defineEmits<{
49
49
 
50
50
  const { pending, set } = useOptimisticToggle(() => props.action, emit)
51
51
 
52
+ // A given default slot counts as the name whether or not it renders anything:
53
+ // a slot that may come out empty leaves the switch unnamed, so pass `aria-label`.
52
54
  const slots = useSlots()
53
55
  const labelled = computed(() => Boolean(props.label || props.description || slots.default))
54
56
 
@@ -75,8 +77,8 @@ const field = useFieldControl(() => ({
75
77
  disabled: props.disabled,
76
78
  }))
77
79
  const descriptionId = `${useId()}-description`
78
- const describedBy = computed(
79
- () => [props.description && labelled.value ? descriptionId : "", field.value.describedBy ?? ""].filter(Boolean).join(" ") || undefined,
80
+ const describedBy = computed(() =>
81
+ mergeDescribedBy(rest.value["aria-describedby"], props.description && labelled.value ? descriptionId : undefined, field.value.describedBy),
80
82
  )
81
83
 
82
84
  function onUpdate(value: boolean) {