@leavepulse/ui 0.77.3 → 0.78.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 (597) 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-DXIr0eFz.js} +2 -2
  12. package/dist/chunks/{FieldWrapper-CORPzo9s.js → FieldWrapper-DnuMTrqW.js} +1 -1
  13. package/dist/chunks/IconCloseButton-COZEsa9u.js +29 -0
  14. package/dist/chunks/{LayoutCanvas-CNOAUk7D.js → LayoutCanvas-CZKOltfA.js} +1 -1
  15. package/dist/chunks/{LayoutNode-DF5BMN0J.js → LayoutNode-D2f7v683.js} +45 -45
  16. package/dist/chunks/{LpActionBar-BP1ld7-S.js → LpActionBar-BGMk5KoG.js} +3 -3
  17. package/dist/chunks/{LpActivityLine-CJvzrNpj.js → LpActivityLine-Ea-t5Vza.js} +4 -2
  18. package/dist/chunks/{LpAddressInput-E8KtwU7-.js → LpAddressInput-ZqoZ-N2Y.js} +12 -11
  19. package/dist/chunks/{LpAlert-n5XPAZfv.js → LpAlert-CjvTZIKF.js} +3 -3
  20. package/dist/chunks/LpAppShell-BNAVTQsY.js +582 -0
  21. package/dist/chunks/{LpAutocomplete-C-SpPfBG.js → LpAutocomplete-DkY6CSyD.js} +24 -42
  22. package/dist/chunks/{LpAvatar-Cg6Az3wz.js → LpAvatar-cQVsNk6F.js} +2 -2
  23. package/dist/chunks/{LpBadge-wUYLN4U9.js → LpBadge-D5QQdDQ_.js} +2 -2
  24. package/dist/chunks/{LpBottomNav-CbNQQPuL.js → LpBottomNav-zxLGGbjm.js} +9 -2
  25. package/dist/chunks/{LpBreadcrumbs-DPdbth-c.js → LpBreadcrumbs-CIIBsygI.js} +4 -3
  26. package/dist/chunks/{LpButton-CFb44IjC.js → LpButton-DSHioIfD.js} +5 -4
  27. package/dist/chunks/{LpCalendar-CuoWks-0.js → LpCalendar-D4-LVjfF.js} +1 -1
  28. package/dist/chunks/{LpCard-r13WRqox.js → LpCard-BPtYXwnT.js} +1 -1
  29. package/dist/chunks/{LpCheckbox-Cs4SHaHX.js → LpCheckbox-D6RuDW4X.js} +38 -16
  30. package/dist/chunks/{LpCodeBlock-DRC8VbXW.js → LpCodeBlock-DuzmnIHl.js} +19 -41
  31. package/dist/chunks/{LpCodeDisplay-CE9TxCA4.js → LpCodeDisplay-CO8fngxa.js} +5 -5
  32. package/dist/chunks/{LpCollapse-CWS9M_lm.js → LpCollapse-DrAw5DBZ.js} +5 -4
  33. package/dist/chunks/{LpColorPicker-1y1QJHZR.js → LpColorPicker-BxAHEnR5.js} +11 -12
  34. package/dist/chunks/{LpCommandScope-CtUhJe8T.js → LpCommandScope-DRUvHiX7.js} +1 -1
  35. package/dist/chunks/{LpConfirmDialog-DlD45Bi_.js → LpConfirmDialog-6oCIJTDa.js} +3 -3
  36. package/dist/chunks/{LpConfirmHost-BIWjBLmI.js → LpConfirmHost-DgHvfT6s.js} +1 -1
  37. package/dist/chunks/{LpContextMenu-rx2tCjwk.js → LpContextMenu--eMGIql6.js} +13 -15
  38. package/dist/chunks/{LpContextSwitcher-Dwh6dyID.js → LpContextSwitcher-1C1tExdl.js} +2 -2
  39. package/dist/chunks/{LpCopyButton-xF7wFVoU.js → LpCopyButton-7EOSIuwa.js} +3 -3
  40. package/dist/chunks/{LpCountdown-DgeY3cLG.js → LpCountdown-DVl7vXI1.js} +4 -3
  41. package/dist/chunks/{LpDataList-Jxyl9H5w.js → LpDataList-DgBeM01y.js} +13 -4
  42. package/dist/chunks/{LpDatePicker-CA0QTfBC.js → LpDatePicker-DwSDY0mt.js} +12 -18
  43. package/dist/chunks/{LpDateRangePicker-u3J51xXk.js → LpDateRangePicker-CNQXdTVv.js} +10 -16
  44. package/dist/chunks/{LpDisclosure-Cpa7Hc5T.js → LpDisclosure-DG7JCo-d.js} +2 -2
  45. package/dist/chunks/{LpDrawer-CrG8t_KP.js → LpDrawer-Bt9UUqt_.js} +61 -61
  46. package/dist/chunks/{LpDropdownMenu-Dl7Z4ZhS.js → LpDropdownMenu-CLzxIOgM.js} +9 -17
  47. package/dist/chunks/{LpEditable-Cy6GLbFx.js → LpEditable-DVT0Rh8F.js} +9 -6
  48. package/dist/chunks/{LpEmptyState-EQHiRYhG.js → LpEmptyState-DurPF001.js} +1 -1
  49. package/dist/chunks/{LpFieldNotice-CzQ2_5rQ.js → LpFieldNotice-DJ10cYIo.js} +1 -1
  50. package/dist/chunks/LpFileTree-BSx1kBoV.js +735 -0
  51. package/dist/chunks/{LpFileTreeNode-cT6BIWvz.js → LpFileTreeNode-4dVmFHb3.js} +116 -34
  52. package/dist/chunks/{LpFormField-Ch69Jd-X.js → LpFormField-BKYn9dyP.js} +3 -3
  53. package/dist/chunks/{LpFrame-BVQCQLDI.js → LpFrame-Bv5Fphte.js} +25 -11
  54. package/dist/chunks/{LpHintExample-9Py0wc-L.js → LpHintExample-YzCXiSUp.js} +1 -1
  55. package/dist/chunks/{LpHintLayer-CgObdUsM.js → LpHintLayer-BeKRsRon.js} +2 -2
  56. package/dist/chunks/{LpHints-Bz-BlaSl.js → LpHints-qf3xYsza.js} +3 -3
  57. package/dist/chunks/{LpHoverCard-spGxyw7T.js → LpHoverCard-DanH3Nz1.js} +23 -5
  58. package/dist/chunks/{LpIcon--5WSb3jJ.js → LpIcon-C6JpQ5td.js} +6 -3
  59. package/dist/chunks/{LpIdenticon-BzdC_qz9.js → LpIdenticon-Dbbr4fvt.js} +2 -1
  60. package/dist/chunks/{LpInfraNode-46XOCkfq.js → LpInfraNode-BAU40Km2.js} +2 -2
  61. package/dist/chunks/{LpInput-Tw-yxT4I.js → LpInput-DL6HEJdi.js} +16 -28
  62. package/dist/chunks/LpInspector-CuoMAhiw.js +209 -0
  63. package/dist/chunks/{LpLightbox-B95yu22B.js → LpLightbox-xvpQ64MM.js} +57 -32
  64. package/dist/chunks/{LpLoader-DVwkOmt9.js → LpLoader-Bf1yZwaU.js} +1 -1
  65. package/dist/chunks/LpLogInspector-6cNnXqp4.js +119 -0
  66. package/dist/chunks/{LpLogViewer-ngqkns4m.js → LpLogViewer-Dvb1E9_G.js} +234 -53
  67. package/dist/chunks/{LpMapPicker-DRGgh89B.js → LpMapPicker-D5_YLLBC.js} +4 -3
  68. package/dist/chunks/{LpMasonry--k0571qG.js → LpMasonry-DPYekFxs.js} +8 -5
  69. package/dist/chunks/{LpMediaGallery-Bkram-MO.js → LpMediaGallery-Df-tiWeq.js} +3 -3
  70. package/dist/chunks/{LpModal-CoGhLTyH.js → LpModal-DrtQ_1A2.js} +11 -13
  71. package/dist/chunks/{LpModalNav-BGvs2y5Q.js → LpModalNav-DkmGCnZE.js} +11 -37
  72. package/dist/chunks/{LpNotificationBell-B0034Lk-.js → LpNotificationBell-D_wklO1m.js} +9 -9
  73. package/dist/chunks/{LpNumberField-e0IBkWU1.js → LpNumberField-CNHsmSDZ.js} +7 -16
  74. package/dist/chunks/{LpOtpInput-CeBPsM7D.js → LpOtpInput-BRpLBbOD.js} +2 -2
  75. package/dist/chunks/{LpPagination-BIIiYHXR.js → LpPagination-snQ020xQ.js} +6 -4
  76. package/dist/chunks/{LpPaletteTheme-DiLYKQiZ.js → LpPaletteTheme-dVtxHx-F.js} +4 -4
  77. package/dist/chunks/{LpPasswordInput-BkHKQDhM.js → LpPasswordInput-B-zD6tUS.js} +2 -2
  78. package/dist/chunks/{LpPhoneInput-CETEp5W7.js → LpPhoneInput-BSL7NX4z.js} +15 -26
  79. package/dist/chunks/{LpPie-DrZepi0p.js → LpPie-9t_guO49.js} +22 -21
  80. package/dist/chunks/{LpPipeline-B3aOVOkV.js → LpPipeline-rjXvEDRJ.js} +16 -7
  81. package/dist/chunks/{LpPopover-DmZ3wUtP.js → LpPopover-BQSuxtai.js} +10 -1
  82. package/dist/chunks/{LpProgress-Yr6ONG5t.js → LpProgress-D_MSjowb.js} +2 -1
  83. package/dist/chunks/{LpQuota-Dk2MyI2Z.js → LpQuota-CgWPgdVt.js} +1 -1
  84. package/dist/chunks/{LpRadioGroup-ggaPL92T.js → LpRadioGroup-BrazjLY_.js} +4 -4
  85. package/dist/chunks/{LpRangeCalendar-CYYUYqJ7.js → LpRangeCalendar-BrqlGZzE.js} +1 -1
  86. package/dist/chunks/{LpRangeSlider-CM-0ZITZ.js → LpRangeSlider-fz61tzc-.js} +5 -9
  87. package/dist/chunks/{LpRelativeTime-DwgCb5-8.js → LpRelativeTime-BovUk8MP.js} +1 -1
  88. package/dist/chunks/{LpRepeater-D7ZmnIYd.js → LpRepeater-BkJHSPI1.js} +3 -3
  89. package/dist/chunks/{LpRevealOnScroll-DcQjexLy.js → LpRevealOnScroll-CPwyiQAr.js} +1 -1
  90. package/dist/chunks/{LpScramble-Bn9OoOtC.js → LpScramble-DsE77iVp.js} +1 -1
  91. package/dist/chunks/{LpScrollArea-MyEnVB_5.js → LpScrollArea-ay4Xo_hg.js} +22 -10
  92. package/dist/chunks/{LpSecretField-BbmqM9ye.js → LpSecretField-DBvU6iAw.js} +10 -9
  93. package/dist/chunks/{LpSection-DFK_uoJE.js → LpSection-BfteipxU.js} +1 -1
  94. package/dist/chunks/{LpSegmented-CeACsMMA.js → LpSegmented-DbEJhbv-.js} +8 -10
  95. package/dist/chunks/{LpSelect-Cxq4yBGd.js → LpSelect-Y-iuSymW.js} +47 -30
  96. package/dist/chunks/{LpShaderBackdrop-Bote0iuy.js → LpShaderBackdrop-wQygYb5h.js} +13 -10
  97. package/dist/chunks/{LpShift-CCq7dofl.js → LpShift-DAgS_d2x.js} +18 -15
  98. package/dist/chunks/{LpSidebar-DzE1783C.js → LpSidebar-kSkpPh3-.js} +74 -87
  99. package/dist/chunks/{LpSidebarNav-DE3PhXVP.js → LpSidebarNav-C2mvqrY2.js} +8 -6
  100. package/dist/chunks/{LpSidebarRow-BRYhNDSo.js → LpSidebarRow-eRP4Q31q.js} +6 -5
  101. package/dist/chunks/{LpSlider-DxYoCJJO.js → LpSlider-A4ixovgS.js} +5 -9
  102. package/dist/chunks/{LpSpotlight-4F3NeUMY.js → LpSpotlight-DwxkhFgR.js} +2 -1
  103. package/dist/chunks/{LpStat-f2LfDCJ4.js → LpStat-pMNZgFcq.js} +2 -2
  104. package/dist/chunks/{LpStatus-DglxttQ7.js → LpStatus-DGJFwk5F.js} +2 -2
  105. package/dist/chunks/{LpStepMark-DpzKVyh8.js → LpStepMark-Dw2MRTrt.js} +2 -2
  106. package/dist/chunks/{LpStepper-DpsocBNJ.js → LpStepper-DNnh7lCu.js} +1 -1
  107. package/dist/chunks/{LpSwap-C96c0LWh.js → LpSwap-M7nFeW3C.js} +1 -1
  108. package/dist/chunks/{LpSwitch-BnXd1llc.js → LpSwitch-DnC2-0aV.js} +3 -3
  109. package/dist/chunks/{LpTabFace-DPCwKkH2.js → LpTabFace-DQoV8mQG.js} +2 -2
  110. package/dist/chunks/{LpTableFilter-CiVBpaq0.js → LpTableFilter-DgARTsA1.js} +4 -4
  111. package/dist/chunks/{LpTableOfContents-BN5zvpnx.js → LpTableOfContents-CKkWEK6R.js} +14 -9
  112. package/dist/chunks/{LpTagsInput-C-mDG648.js → LpTagsInput-Dt0mteSj.js} +19 -27
  113. package/dist/chunks/{LpTextarea-TE-yZv2U.js → LpTextarea-Co0b9PVx.js} +8 -16
  114. package/dist/chunks/LpThemeProvider-XK6ZeWAE.js +81 -0
  115. package/dist/chunks/{LpThemeStudio-BpORDvH6.js → LpThemeStudio-DzYfE-5k.js} +12 -195
  116. package/dist/chunks/{LpThemeSwitcher-BnEn_mvf.js → LpThemeSwitcher-CFLkdbBL.js} +8 -6
  117. package/dist/chunks/{LpTimeField-BawSVsmt.js → LpTimeField-DeOcKWJq.js} +6 -9
  118. package/dist/chunks/{LpToaster-IwTXjbbU.js → LpToaster-QFj0P-5m.js} +10 -8
  119. package/dist/chunks/{LpTooltip-BcBvIx4z.js → LpTooltip-BJf3lZMq.js} +51 -19
  120. package/dist/chunks/LpTopologyCanvas-BOHHHZ_6.js +673 -0
  121. package/dist/chunks/{LpTour-BZq-mUMv.js → LpTour-ClKYhx4h.js} +7 -5
  122. package/dist/chunks/{LpTruncate-CflAIwiJ.js → LpTruncate-C6u3gjc6.js} +6 -5
  123. package/dist/chunks/{LpTypewriter-BCL_a6wE.js → LpTypewriter-CZIzpdbe.js} +2 -1
  124. package/dist/chunks/{LpUptimeBar-DqNvvMBK.js → LpUptimeBar-BnYmR2rj.js} +3 -3
  125. package/dist/chunks/{LpVideoBackdrop-DS1wGv-X.js → LpVideoBackdrop-Ct4St4ZL.js} +10 -13
  126. package/dist/chunks/LpWindow-B8YSRVTH.js +297 -0
  127. package/dist/chunks/LpWorkspaceSwitcher-D0e9upAy.js +139 -0
  128. package/dist/chunks/{MenuTitle-BmCNNTKH.js → MenuTitle-Bh5dAdV1.js} +1 -1
  129. package/dist/chunks/{OptionContent-22UT8zLn.js → OptionContent-CGb8QlHA.js} +1 -1
  130. package/dist/chunks/{PickerField-Bfh8id3d.js → PickerField-BM1dyafh.js} +4 -4
  131. package/dist/chunks/{RevealToggle-BEit1n6Z.js → RevealToggle-CCPDE8Mv.js} +3 -3
  132. package/dist/chunks/SliderRail-DhPREa_R.js +18 -0
  133. package/dist/chunks/{TourCard-DNclH3u_.js → TourCard-DAzTYfav.js} +4 -4
  134. package/dist/chunks/{icons-DMITlfw5.js → icons-CYfcpSDS.js} +26 -10
  135. package/dist/component-names.d.ts +1 -1
  136. package/dist/components/AppShellContextNav.vue.d.ts +13 -0
  137. package/dist/components/AppShellContextNav.vue.js +4 -0
  138. package/dist/components/ChartRangeSelector.vue.d.ts +21 -0
  139. package/dist/components/ChartRangeSelector.vue.js +4 -0
  140. package/dist/components/ContextMenuItems.vue.js +1 -1
  141. package/dist/components/DropzoneLinkField.vue.d.ts +2 -2
  142. package/dist/components/DropzoneLinkField.vue.js +1 -1
  143. package/dist/components/FieldWrapper.vue.js +1 -1
  144. package/dist/components/IconCloseButton.vue.d.ts +7 -0
  145. package/dist/components/IconCloseButton.vue.js +4 -0
  146. package/dist/components/LayoutCanvas.vue.js +1 -1
  147. package/dist/components/LayoutNode.vue.js +1 -1
  148. package/dist/components/LpActionBar.vue.js +1 -1
  149. package/dist/components/LpActivityLine.vue.js +1 -1
  150. package/dist/components/LpAddressInput.vue.js +1 -1
  151. package/dist/components/LpAlert.vue.js +1 -1
  152. package/dist/components/LpAppShell.vue.d.ts +110 -2
  153. package/dist/components/LpAppShell.vue.js +1 -1
  154. package/dist/components/LpAutocomplete.vue.js +1 -1
  155. package/dist/components/LpAvatar.vue.js +1 -1
  156. package/dist/components/LpBadge.vue.js +1 -1
  157. package/dist/components/LpBottomNav.vue.d.ts +5 -0
  158. package/dist/components/LpBottomNav.vue.js +1 -1
  159. package/dist/components/LpBreadcrumbs.vue.js +1 -1
  160. package/dist/components/LpButton.vue.d.ts +14 -2
  161. package/dist/components/LpButton.vue.js +1 -1
  162. package/dist/components/LpCalendar.vue.js +1 -1
  163. package/dist/components/LpCard.vue.js +1 -1
  164. package/dist/components/LpChart.vue.d.ts +74 -2
  165. package/dist/components/LpChart.vue.js +326 -85
  166. package/dist/components/LpCheckbox.vue.d.ts +6 -2
  167. package/dist/components/LpCheckbox.vue.js +1 -1
  168. package/dist/components/LpCodeBlock.vue.js +1 -1
  169. package/dist/components/LpCodeDisplay.vue.js +1 -1
  170. package/dist/components/LpCollapse.vue.js +1 -1
  171. package/dist/components/LpColorPicker.vue.js +1 -1
  172. package/dist/components/LpCommandPalette.vue.d.ts +8 -0
  173. package/dist/components/LpCommandPalette.vue.js +107 -56
  174. package/dist/components/LpCommandScope.vue.js +1 -1
  175. package/dist/components/LpConfirmDialog.vue.js +1 -1
  176. package/dist/components/LpConfirmHost.vue.js +1 -1
  177. package/dist/components/LpContextMenu.vue.js +1 -1
  178. package/dist/components/LpContextSwitcher.vue.js +1 -1
  179. package/dist/components/LpCopyButton.vue.js +1 -1
  180. package/dist/components/LpCountdown.vue.js +1 -1
  181. package/dist/components/LpDataList.vue.d.ts +1 -1
  182. package/dist/components/LpDataList.vue.js +1 -1
  183. package/dist/components/LpDatePicker.vue.d.ts +3 -15
  184. package/dist/components/LpDatePicker.vue.js +1 -1
  185. package/dist/components/LpDateRangePicker.vue.d.ts +3 -13
  186. package/dist/components/LpDateRangePicker.vue.js +1 -1
  187. package/dist/components/LpDisclosure.vue.js +1 -1
  188. package/dist/components/LpDock.vue.js +21 -18
  189. package/dist/components/LpDrawer.vue.d.ts +1 -1
  190. package/dist/components/LpDrawer.vue.js +1 -1
  191. package/dist/components/LpDropdownMenu.vue.js +1 -1
  192. package/dist/components/LpDropzone.vue.js +14 -11
  193. package/dist/components/LpEditable.vue.js +1 -1
  194. package/dist/components/LpEmptyState.vue.js +1 -1
  195. package/dist/components/LpFieldNotice.vue.js +1 -1
  196. package/dist/components/LpFileTree.vue.d.ts +96 -6
  197. package/dist/components/LpFileTree.vue.js +1 -1
  198. package/dist/components/LpFileTreeNode.vue.d.ts +48 -0
  199. package/dist/components/LpFileTreeNode.vue.js +1 -1
  200. package/dist/components/LpFormField.vue.js +1 -1
  201. package/dist/components/LpFrame.vue.js +1 -1
  202. package/dist/components/LpGauge.vue.d.ts +1 -1
  203. package/dist/components/LpHintExample.vue.js +1 -1
  204. package/dist/components/LpHintLayer.vue.js +1 -1
  205. package/dist/components/LpHints.vue.js +1 -1
  206. package/dist/components/LpHoverCard.vue.js +1 -1
  207. package/dist/components/LpIcon.vue.d.ts +2 -0
  208. package/dist/components/LpIcon.vue.js +1 -1
  209. package/dist/components/LpIdenticon.vue.js +1 -1
  210. package/dist/components/LpImageEditor.vue.js +7 -6
  211. package/dist/components/LpInfraNode.vue.js +1 -1
  212. package/dist/components/LpInput.vue.d.ts +1 -1
  213. package/dist/components/LpInput.vue.js +1 -1
  214. package/dist/components/LpInspector.vue.d.ts +87 -0
  215. package/dist/components/LpInspector.vue.js +4 -0
  216. package/dist/components/LpLightbox.vue.d.ts +8 -0
  217. package/dist/components/LpLightbox.vue.js +1 -1
  218. package/dist/components/LpLoader.vue.d.ts +1 -1
  219. package/dist/components/LpLoader.vue.js +1 -1
  220. package/dist/components/LpLogInspector.vue.d.ts +18 -0
  221. package/dist/components/LpLogInspector.vue.js +4 -0
  222. package/dist/components/LpLogViewer.vue.d.ts +93 -0
  223. package/dist/components/LpLogViewer.vue.js +1 -1
  224. package/dist/components/LpMapPicker.vue.js +1 -1
  225. package/dist/components/LpMasonry.vue.js +1 -1
  226. package/dist/components/LpMediaGallery.vue.js +1 -1
  227. package/dist/components/LpModal.vue.d.ts +4 -2
  228. package/dist/components/LpModal.vue.js +1 -1
  229. package/dist/components/LpModalNav.vue.d.ts +5 -5
  230. package/dist/components/LpModalNav.vue.js +1 -1
  231. package/dist/components/LpNotificationBell.vue.d.ts +2 -2
  232. package/dist/components/LpNotificationBell.vue.js +1 -1
  233. package/dist/components/LpNumberField.vue.js +1 -1
  234. package/dist/components/LpOtpInput.vue.js +1 -1
  235. package/dist/components/LpPagination.vue.js +1 -1
  236. package/dist/components/LpPaletteFacts.vue.js +1 -1
  237. package/dist/components/LpPaletteHeader.vue.js +2 -2
  238. package/dist/components/LpPaletteTheme.vue.js +1 -1
  239. package/dist/components/LpPasswordInput.vue.js +1 -1
  240. package/dist/components/LpPhoneInput.vue.js +1 -1
  241. package/dist/components/LpPie.vue.d.ts +2 -2
  242. package/dist/components/LpPie.vue.js +1 -1
  243. package/dist/components/LpPipeline.vue.d.ts +4 -0
  244. package/dist/components/LpPipeline.vue.js +1 -1
  245. package/dist/components/LpPopover.vue.d.ts +7 -3
  246. package/dist/components/LpPopover.vue.js +1 -1
  247. package/dist/components/LpProgress.vue.d.ts +1 -1
  248. package/dist/components/LpProgress.vue.js +1 -1
  249. package/dist/components/LpQuota.vue.js +1 -1
  250. package/dist/components/LpRadioGroup.vue.js +1 -1
  251. package/dist/components/LpRangeCalendar.vue.js +1 -1
  252. package/dist/components/LpRangeSlider.vue.js +1 -1
  253. package/dist/components/LpRelativeTime.vue.js +1 -1
  254. package/dist/components/LpRepeater.vue.js +1 -1
  255. package/dist/components/LpRevealOnScroll.vue.js +1 -1
  256. package/dist/components/LpScramble.vue.js +1 -1
  257. package/dist/components/LpScrollArea.vue.js +1 -1
  258. package/dist/components/LpSecretField.vue.js +1 -1
  259. package/dist/components/LpSection.vue.js +1 -1
  260. package/dist/components/LpSegmented.vue.js +1 -1
  261. package/dist/components/LpSelect.vue.js +1 -1
  262. package/dist/components/LpShaderBackdrop.vue.js +1 -1
  263. package/dist/components/LpShift.vue.js +1 -1
  264. package/dist/components/LpShortcutsDialog.vue.js +1 -1
  265. package/dist/components/LpSidebar.vue.d.ts +1 -1
  266. package/dist/components/LpSidebar.vue.js +1 -1
  267. package/dist/components/LpSidebarNav.vue.js +1 -1
  268. package/dist/components/LpSidebarRow.vue.js +1 -1
  269. package/dist/components/LpSlider.vue.js +1 -1
  270. package/dist/components/LpSparkline.vue.d.ts +1 -1
  271. package/dist/components/LpSpotlight.vue.js +1 -1
  272. package/dist/components/LpStat.vue.js +1 -1
  273. package/dist/components/LpStatus.vue.js +1 -1
  274. package/dist/components/LpStepMark.vue.js +1 -1
  275. package/dist/components/LpStepper.vue.js +1 -1
  276. package/dist/components/LpSwap.vue.js +1 -1
  277. package/dist/components/LpSwitch.vue.js +1 -1
  278. package/dist/components/LpTabFace.vue.js +1 -1
  279. package/dist/components/LpTable.vue.d.ts +132 -0
  280. package/dist/components/LpTable.vue.js +547 -135
  281. package/dist/components/LpTableFilter.vue.js +1 -1
  282. package/dist/components/LpTableOfContents.vue.js +1 -1
  283. package/dist/components/LpTabs.vue.js +6 -5
  284. package/dist/components/LpTagsInput.vue.js +1 -1
  285. package/dist/components/LpTextarea.vue.js +1 -1
  286. package/dist/components/LpThemeProvider.vue.d.ts +2 -0
  287. package/dist/components/LpThemeProvider.vue.js +1 -1
  288. package/dist/components/LpThemeStudio.vue.js +1 -1
  289. package/dist/components/LpThemeSwitcher.vue.js +1 -1
  290. package/dist/components/LpTimeField.vue.js +1 -1
  291. package/dist/components/LpToaster.vue.js +1 -1
  292. package/dist/components/LpTooltip.vue.js +1 -1
  293. package/dist/components/LpTopologyCanvas.vue.d.ts +131 -5
  294. package/dist/components/LpTopologyCanvas.vue.js +1 -1
  295. package/dist/components/LpTour.vue.js +1 -1
  296. package/dist/components/LpTruncate.vue.js +1 -1
  297. package/dist/components/LpTypewriter.vue.js +1 -1
  298. package/dist/components/LpUptimeBar.vue.js +1 -1
  299. package/dist/components/LpVideoBackdrop.vue.js +1 -1
  300. package/dist/components/LpWindow.vue.d.ts +99 -0
  301. package/dist/components/LpWindow.vue.js +4 -0
  302. package/dist/components/LpWorkspaceSwitcher.vue.d.ts +18 -0
  303. package/dist/components/LpWorkspaceSwitcher.vue.js +4 -0
  304. package/dist/components/MenuTitle.vue.js +1 -1
  305. package/dist/components/OptionContent.vue.js +1 -1
  306. package/dist/components/PickerField.vue.d.ts +2 -2
  307. package/dist/components/PickerField.vue.js +1 -1
  308. package/dist/components/RevealToggle.vue.js +1 -1
  309. package/dist/components/SliderRail.vue.d.ts +3 -0
  310. package/dist/components/SliderRail.vue.js +4 -0
  311. package/dist/components/TourCard.vue.js +1 -1
  312. package/dist/components/address.js +2 -1
  313. package/dist/components/appShell.d.ts +36 -0
  314. package/dist/components/appShell.js +30 -0
  315. package/dist/components/calendar.d.ts +12 -3
  316. package/dist/components/calendar.js +2 -5
  317. package/dist/components/chart.d.ts +21 -0
  318. package/dist/components/chart.js +4 -3
  319. package/dist/components/chartWindow.d.ts +57 -0
  320. package/dist/components/chartWindow.js +136 -0
  321. package/dist/components/color.js +1 -1
  322. package/dist/components/commandPalette.d.ts +16 -2
  323. package/dist/components/commandPalette.js +39 -4
  324. package/dist/components/controlSize.d.ts +5 -0
  325. package/dist/components/controlSize.js +8 -0
  326. package/dist/components/dropdown.d.ts +5 -0
  327. package/dist/components/dropdown.js +2 -0
  328. package/dist/components/exportData.d.ts +6 -1
  329. package/dist/components/exportData.js +25 -18
  330. package/dist/components/fileTree.d.ts +67 -0
  331. package/dist/components/fileTree.js +141 -1
  332. package/dist/components/identicon.js +3 -2
  333. package/dist/components/logTools.d.ts +93 -0
  334. package/dist/components/logTools.js +210 -0
  335. package/dist/components/menuWhen.js +1 -1
  336. package/dist/components/meter.js +2 -1
  337. package/dist/components/pipeline.d.ts +2 -0
  338. package/dist/components/pipeline.js +5 -0
  339. package/dist/components/relativeTime.js +2 -1
  340. package/dist/components/reveal.js +2 -1
  341. package/dist/components/select.d.ts +5 -0
  342. package/dist/components/select.js +10 -0
  343. package/dist/components/sidebar.d.ts +1 -0
  344. package/dist/components/tableFeatures.d.ts +58 -0
  345. package/dist/components/tableFeatures.js +87 -0
  346. package/dist/components/topologyGraph.d.ts +164 -0
  347. package/dist/components/topologyGraph.js +416 -0
  348. package/dist/components/tour.js +5 -3
  349. package/dist/components/videoBackdrop.js +7 -6
  350. package/dist/composables/clamp.d.ts +2 -0
  351. package/dist/composables/clamp.js +4 -0
  352. package/dist/composables/devWarn.d.ts +3 -0
  353. package/dist/composables/devWarn.js +14 -0
  354. package/dist/composables/easing.d.ts +13 -4
  355. package/dist/composables/easing.js +16 -10
  356. package/dist/composables/overlayHistory.js +14 -1
  357. package/dist/composables/pointerDrag.d.ts +15 -0
  358. package/dist/composables/pointerDrag.js +40 -0
  359. package/dist/composables/propCheck.d.ts +10 -0
  360. package/dist/composables/propCheck.js +78 -0
  361. package/dist/composables/realm.d.ts +6 -0
  362. package/dist/composables/realm.js +23 -0
  363. package/dist/composables/scroll.js +4 -2
  364. package/dist/composables/scrollMemory.d.ts +12 -1
  365. package/dist/composables/scrollMemory.js +36 -12
  366. package/dist/composables/spatialNav.js +2 -1
  367. package/dist/composables/textEntry.d.ts +17 -0
  368. package/dist/composables/textEntry.js +19 -0
  369. package/dist/composables/useAsyncTask.d.ts +6 -0
  370. package/dist/composables/useChartSync.d.ts +5 -0
  371. package/dist/composables/useChartSync.js +33 -0
  372. package/dist/composables/useCloseGuard.d.ts +3 -1
  373. package/dist/composables/useCloseGuard.js +6 -3
  374. package/dist/composables/useCommands.d.ts +50 -0
  375. package/dist/composables/useCommands.js +66 -0
  376. package/dist/composables/useField.d.ts +37 -0
  377. package/dist/composables/useField.js +27 -2
  378. package/dist/composables/useFitScale.js +4 -1
  379. package/dist/composables/useFormDraft.d.ts +13 -2
  380. package/dist/composables/useFormDraft.js +17 -9
  381. package/dist/composables/useHintSystem.js +2 -2
  382. package/dist/composables/useHotkeys.js +11 -32
  383. package/dist/composables/useInView.js +2 -1
  384. package/dist/composables/useInputFilter.js +7 -5
  385. package/dist/composables/useInputMask.js +5 -3
  386. package/dist/composables/useLinkedView.d.ts +97 -0
  387. package/dist/composables/useLinkedView.js +139 -0
  388. package/dist/composables/useOptimisticToggle.d.ts +3 -1
  389. package/dist/composables/useOptimisticToggle.js +2 -1
  390. package/dist/composables/useOverlayHistory.d.ts +7 -0
  391. package/dist/composables/useOverlayHistory.js +16 -2
  392. package/dist/composables/usePaintSelect.js +18 -14
  393. package/dist/composables/usePaletteCommands.d.ts +7 -0
  394. package/dist/composables/usePaletteCommands.js +12 -1
  395. package/dist/composables/usePersisted.d.ts +10 -0
  396. package/dist/composables/usePersisted.js +1 -1
  397. package/dist/composables/usePillTransition.d.ts +2 -2
  398. package/dist/composables/usePillTransition.js +5 -5
  399. package/dist/composables/useResizeObserver.js +2 -1
  400. package/dist/composables/useReveal.js +2 -1
  401. package/dist/composables/useRovingFocus.d.ts +2 -2
  402. package/dist/composables/useRovingFocus.js +9 -11
  403. package/dist/composables/useScramble.js +7 -1
  404. package/dist/composables/useShift.js +8 -6
  405. package/dist/composables/useTilt.js +2 -1
  406. package/dist/composables/useTween.js +9 -5
  407. package/dist/composables/useView.d.ts +1 -0
  408. package/dist/composables/useView.js +14 -2
  409. package/dist/composables/useZoomPan.js +2 -4
  410. package/dist/composables/windowing.d.ts +40 -0
  411. package/dist/composables/windowing.js +118 -0
  412. package/dist/icons-all.js +1 -1
  413. package/dist/icons.d.ts +4 -0
  414. package/dist/index.d.ts +30 -5
  415. package/dist/index.js +310 -264
  416. package/dist/layout/tree.js +19 -15
  417. package/dist/layout/useLayout.d.ts +2 -0
  418. package/dist/layout/useLayout.js +5 -1
  419. package/dist/layout/useWorkspaces.d.ts +52 -0
  420. package/dist/layout/useWorkspaces.js +140 -0
  421. package/dist/{chunks/backdrop-Dkf2vM81.js → theme/backdrop.js} +5 -5
  422. package/dist/theme/config.js +25 -0
  423. package/dist/theme/define.js +61 -0
  424. package/dist/{chunks/palette-Co8tSASo.js → theme/palette.js} +2 -2
  425. package/dist/theme/presets.js +239 -0
  426. package/dist/theme/studio.js +134 -0
  427. package/dist/theme/tokens.js +63 -0
  428. package/dist/theme/useTheme.d.ts +3 -2
  429. package/dist/theme/useTheme.js +325 -0
  430. package/package.json +8 -1
  431. package/src/component-names.ts +5 -1
  432. package/src/components/AppShellContextNav.vue +44 -0
  433. package/src/components/ChartRangeSelector.vue +120 -0
  434. package/src/components/IconCloseButton.vue +21 -0
  435. package/src/components/LayoutCanvas.vue +3 -0
  436. package/src/components/LayoutNode.vue +37 -38
  437. package/src/components/LpActivityLine.vue +4 -2
  438. package/src/components/LpAddressInput.vue +3 -3
  439. package/src/components/LpAppShell.vue +362 -24
  440. package/src/components/LpAutocomplete.vue +13 -30
  441. package/src/components/LpBottomNav.vue +9 -1
  442. package/src/components/LpBreadcrumbs.vue +2 -1
  443. package/src/components/LpButton.vue +11 -4
  444. package/src/components/LpChart.vue +336 -37
  445. package/src/components/LpCheckbox.vue +43 -9
  446. package/src/components/LpCodeBlock.vue +17 -23
  447. package/src/components/LpCollapse.vue +5 -4
  448. package/src/components/LpColorPicker.vue +8 -9
  449. package/src/components/LpCommandPalette.vue +133 -50
  450. package/src/components/LpContextMenu.vue +15 -13
  451. package/src/components/LpCountdown.vue +2 -1
  452. package/src/components/LpDataList.vue +13 -1
  453. package/src/components/LpDatePicker.vue +5 -17
  454. package/src/components/LpDateRangePicker.vue +5 -16
  455. package/src/components/LpDock.vue +25 -16
  456. package/src/components/LpDrawer.vue +70 -61
  457. package/src/components/LpDropdownMenu.vue +6 -10
  458. package/src/components/LpDropzone.vue +12 -7
  459. package/src/components/LpEditable.vue +6 -2
  460. package/src/components/LpFileTree.vue +507 -66
  461. package/src/components/LpFileTreeNode.vue +106 -5
  462. package/src/components/LpFormField.vue +1 -1
  463. package/src/components/LpFrame.vue +33 -13
  464. package/src/components/LpHoverCard.vue +30 -5
  465. package/src/components/LpIcon.vue +6 -2
  466. package/src/components/LpIdenticon.vue +2 -1
  467. package/src/components/LpImageEditor.vue +5 -2
  468. package/src/components/LpInput.vue +15 -23
  469. package/src/components/LpInspector.vue +197 -0
  470. package/src/components/LpLightbox.vue +74 -29
  471. package/src/components/LpLogInspector.vue +85 -0
  472. package/src/components/LpLogViewer.vue +239 -29
  473. package/src/components/LpMapPicker.vue +2 -1
  474. package/src/components/LpMasonry.vue +8 -5
  475. package/src/components/LpModal.vue +12 -12
  476. package/src/components/LpModalNav.vue +2 -21
  477. package/src/components/LpNumberField.vue +6 -15
  478. package/src/components/LpOtpInput.vue +2 -2
  479. package/src/components/LpPagination.vue +5 -3
  480. package/src/components/LpPhoneInput.vue +8 -19
  481. package/src/components/LpPie.vue +25 -23
  482. package/src/components/LpPipeline.vue +14 -1
  483. package/src/components/LpPopover.vue +23 -2
  484. package/src/components/LpProgress.vue +2 -1
  485. package/src/components/LpRadioGroup.vue +2 -2
  486. package/src/components/LpRangeSlider.vue +5 -6
  487. package/src/components/LpRevealOnScroll.vue +1 -1
  488. package/src/components/LpScrollArea.vue +28 -11
  489. package/src/components/LpSecretField.vue +2 -1
  490. package/src/components/LpSegmented.vue +6 -8
  491. package/src/components/LpSelect.vue +54 -24
  492. package/src/components/LpShaderBackdrop.vue +12 -9
  493. package/src/components/LpShift.vue +18 -15
  494. package/src/components/LpSidebar.vue +77 -74
  495. package/src/components/LpSidebarNav.vue +3 -2
  496. package/src/components/LpSidebarRow.vue +2 -1
  497. package/src/components/LpSlider.vue +5 -6
  498. package/src/components/LpSpotlight.vue +2 -1
  499. package/src/components/LpSwitch.vue +5 -3
  500. package/src/components/LpTable.vue +609 -93
  501. package/src/components/LpTableFilter.vue +1 -1
  502. package/src/components/LpTableOfContents.vue +16 -9
  503. package/src/components/LpTabs.vue +2 -1
  504. package/src/components/LpTagsInput.vue +12 -19
  505. package/src/components/LpTextarea.vue +5 -11
  506. package/src/components/LpThemeProvider.vue +29 -13
  507. package/src/components/LpTimeField.vue +4 -7
  508. package/src/components/LpToaster.vue +7 -6
  509. package/src/components/LpTooltip.vue +62 -18
  510. package/src/components/LpTopologyCanvas.vue +567 -42
  511. package/src/components/LpTour.vue +7 -5
  512. package/src/components/LpTruncate.vue +4 -3
  513. package/src/components/LpTypewriter.vue +2 -1
  514. package/src/components/LpVideoBackdrop.vue +11 -13
  515. package/src/components/LpWindow.vue +373 -0
  516. package/src/components/LpWorkspaceSwitcher.vue +116 -0
  517. package/src/components/PickerField.vue +2 -2
  518. package/src/components/SliderRail.vue +10 -0
  519. package/src/components/address.ts +3 -1
  520. package/src/components/appShell.ts +74 -0
  521. package/src/components/calendar.ts +12 -5
  522. package/src/components/chart.ts +27 -3
  523. package/src/components/chartWindow.ts +198 -0
  524. package/src/components/color.ts +2 -1
  525. package/src/components/commandPalette.ts +66 -5
  526. package/src/components/controlSize.ts +6 -0
  527. package/src/components/dropdown.ts +3 -0
  528. package/src/components/exportData.ts +33 -18
  529. package/src/components/fileTree.ts +215 -0
  530. package/src/components/identicon.ts +4 -2
  531. package/src/components/logTools.ts +298 -0
  532. package/src/components/meter.ts +2 -1
  533. package/src/components/pipeline.ts +6 -0
  534. package/src/components/relativeTime.ts +2 -1
  535. package/src/components/reveal.ts +3 -1
  536. package/src/components/select.ts +14 -0
  537. package/src/components/sidebar.ts +1 -0
  538. package/src/components/tableFeatures.ts +149 -0
  539. package/src/components/topologyGraph.ts +655 -0
  540. package/src/components/tour.ts +5 -3
  541. package/src/components/videoBackdrop.ts +7 -6
  542. package/src/composables/clamp.ts +2 -0
  543. package/src/composables/devWarn.ts +19 -0
  544. package/src/composables/easing.ts +37 -12
  545. package/src/composables/overlayHistory.ts +24 -0
  546. package/src/composables/pointerDrag.ts +54 -0
  547. package/src/composables/propCheck.ts +90 -0
  548. package/src/composables/realm.ts +25 -0
  549. package/src/composables/scroll.ts +4 -2
  550. package/src/composables/scrollMemory.ts +56 -14
  551. package/src/composables/spatialNav.ts +2 -1
  552. package/src/composables/textEntry.ts +33 -0
  553. package/src/composables/useAsyncTask.ts +6 -0
  554. package/src/composables/useChartSync.ts +52 -0
  555. package/src/composables/useCloseGuard.ts +22 -10
  556. package/src/composables/useCommands.ts +123 -0
  557. package/src/composables/useField.ts +41 -2
  558. package/src/composables/useFitScale.ts +4 -1
  559. package/src/composables/useFormDraft.ts +38 -14
  560. package/src/composables/useHintSystem.ts +2 -2
  561. package/src/composables/useHotkeys.ts +19 -48
  562. package/src/composables/useInView.ts +2 -1
  563. package/src/composables/useInputFilter.ts +8 -5
  564. package/src/composables/useInputMask.ts +8 -3
  565. package/src/composables/useLinkedView.ts +222 -0
  566. package/src/composables/useOptimisticToggle.ts +7 -1
  567. package/src/composables/useOverlayHistory.ts +20 -0
  568. package/src/composables/usePaintSelect.ts +20 -14
  569. package/src/composables/usePaletteCommands.ts +13 -0
  570. package/src/composables/usePersisted.ts +10 -0
  571. package/src/composables/usePillTransition.ts +9 -6
  572. package/src/composables/useResizeObserver.ts +2 -1
  573. package/src/composables/useReveal.ts +2 -1
  574. package/src/composables/useRovingFocus.ts +11 -14
  575. package/src/composables/useScramble.ts +12 -1
  576. package/src/composables/useShift.ts +8 -6
  577. package/src/composables/useTilt.ts +2 -1
  578. package/src/composables/useTween.ts +10 -5
  579. package/src/composables/useView.ts +17 -3
  580. package/src/composables/useZoomPan.ts +2 -5
  581. package/src/composables/windowing.ts +190 -0
  582. package/src/icons.ts +27 -6
  583. package/src/index.ts +41 -4
  584. package/src/kit-icons.ts +1 -1
  585. package/src/layout/tree.ts +31 -16
  586. package/src/layout/useLayout.ts +6 -0
  587. package/src/layout/useWorkspaces.ts +234 -0
  588. package/src/nuxt.ts +9 -1
  589. package/src/runtime/propCheck.plugin.ts +10 -0
  590. package/src/theme/studio.ts +7 -5
  591. package/src/theme/useTheme.ts +89 -15
  592. package/src/tokens/tokens.css +8 -1
  593. package/dist/assets/LpTabs-CJ0rYQbx.css +0 -18
  594. package/dist/chunks/LpAppShell-Dgejipzz.js +0 -319
  595. package/dist/chunks/LpFileTree-CooHinsC.js +0 -425
  596. package/dist/chunks/LpThemeProvider-8MG6yqU9.js +0 -640
  597. package/dist/chunks/LpTopologyCanvas-B1gIbS0n.js +0 -298
@@ -0,0 +1,74 @@
1
+ import type { SidebarItem } from "./sidebar"
2
+
3
+ /*
4
+ * What LpAppShell decides from numbers: which navigation a width gets, whether
5
+ * the header stays while a page scrolls, how tight the page sits. Kept out of
6
+ * the component so each rule is tested without a browser.
7
+ */
8
+
9
+ export type NavBreakpoint = "sm" | "md" | "lg" | "xl" | "2xl"
10
+
11
+ /** Tailwind's default widths, which the shell's own classes follow. */
12
+ export const NAV_BREAKPOINT_PX: Record<NavBreakpoint, number> = { sm: 640, md: 768, lg: 1024, xl: 1280, "2xl": 1536 }
13
+
14
+ /**
15
+ * The one navigation the shell shows at a width. `rail` the full side rail,
16
+ * `compact` its icons, `bottom` a phone's bottom bar, `drawer` a burger.
17
+ */
18
+ export type NavMode = "rail" | "compact" | "bottom" | "drawer"
19
+
20
+ export interface AdaptiveNav {
21
+ /** Below this width (and above `mobileBreakpoint`) the rail folds to icons. */
22
+ compactBelow?: NavBreakpoint
23
+ /**
24
+ * Where the rail is gone, a row of the current page's `children` under the
25
+ * header, so a sub-page stays one tap away. The `context-nav` slot redraws it.
26
+ */
27
+ contextNav?: boolean
28
+ }
29
+
30
+ /** Padding around the page: `auto` tightens it on small screens only. */
31
+ export type ShellDensity = "comfortable" | "compact" | "auto"
32
+
33
+ export const DENSITY_CLASS: Record<ShellDensity, string> = {
34
+ comfortable: "px-4 py-6 md:px-6",
35
+ compact: "px-2 py-3 md:px-3",
36
+ auto: "px-2 py-3 sm:px-4 sm:py-4 md:px-6 md:py-6",
37
+ }
38
+
39
+ export function resolveNavMode(
40
+ atLeast: (breakpoint: NavBreakpoint) => boolean,
41
+ options: { mobileBreakpoint: NavBreakpoint; bottomNav: boolean; compactBelow?: NavBreakpoint },
42
+ ): NavMode {
43
+ if (!atLeast(options.mobileBreakpoint)) return options.bottomNav ? "bottom" : "drawer"
44
+ return options.compactBelow && !atLeast(options.compactBelow) ? "compact" : "rail"
45
+ }
46
+
47
+ /** What the header height is, in px: where a page counts as being at its top. */
48
+ export const SHELL_HEADER_PX = 64
49
+ /* Below this a scroll is a tremble of the finger, not a direction. */
50
+ const SCROLL_SLOP_PX = 8
51
+
52
+ /**
53
+ * The header leaves on the way down and returns on the way up. Near the end of
54
+ * a page it stays as it is: the viewport changes height with the header, the
55
+ * browser clamps the scroll, and that clamp would read as scrolling back up.
56
+ */
57
+ export function headerCollapsedAfter(
58
+ collapsed: boolean,
59
+ from: number,
60
+ to: number,
61
+ maxTop: number,
62
+ slop = SCROLL_SLOP_PX,
63
+ ): boolean {
64
+ if (to <= SHELL_HEADER_PX) return false
65
+ if (to >= maxTop - SHELL_HEADER_PX) return collapsed
66
+ if (to - from > slop) return true
67
+ if (from - to > slop) return false
68
+ return collapsed
69
+ }
70
+
71
+ /** The sub-pages of the page in view: its own, or its siblings' when it is one of them. */
72
+ export function contextNavItems(items: SidebarItem[], isActive: (item: SidebarItem) => boolean): SidebarItem[] {
73
+ return items.find((item) => item.children?.length && (isActive(item) || item.children.some(isActive)))?.children ?? []
74
+ }
@@ -6,6 +6,7 @@
6
6
  * pair drifting apart again (one had translatable month buttons, the other
7
7
  * English ones).
8
8
  */
9
+ import { CONTROL_SIZE } from "./controlSize"
9
10
 
10
11
  export interface CalendarLabels extends Record<string, string> {
11
12
  previous: string
@@ -24,11 +25,7 @@ export const CALENDAR_NAV =
24
25
  export const PICKER_TRIGGER =
25
26
  "group flex w-full items-center gap-2 rounded-control border bg-surface-soft px-3 text-left text-ink outline-none transition-colors duration-[var(--duration-fast)] focus-visible:ring-2 focus-visible:ring-ring data-[state=open]:border-brand disabled:cursor-not-allowed disabled:opacity-55"
26
27
 
27
- export const PICKER_SIZE = {
28
- sm: "h-(--size-control-sm) text-xs",
29
- md: "h-(--size-control-md) text-sm",
30
- lg: "h-(--size-control-lg) text-sm",
31
- } as const
28
+ export const PICKER_SIZE = CONTROL_SIZE
32
29
 
33
30
  export function pickerTone(invalid: boolean): string {
34
31
  return invalid ? "border-danger focus-visible:ring-danger-soft" : "border-line focus-visible:border-brand"
@@ -49,3 +46,13 @@ export const PICKER_PRESETS =
49
46
 
50
47
  export const PICKER_PRESET =
51
48
  "shrink-0 rounded-control px-2.5 py-1.5 text-left text-sm whitespace-nowrap text-muted outline-none transition-colors duration-[var(--duration-fast)] hover:bg-surface-soft hover:text-ink focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-40 aria-pressed:bg-brand-soft aria-pressed:text-ink"
49
+
50
+ /** The props the two pickers share. */
51
+ export interface PickerFieldProps {
52
+ clearable?: boolean
53
+ disabled?: boolean
54
+ invalid?: boolean
55
+ size?: "sm" | "md" | "lg"
56
+ /** Locale of the shown date and the calendar; defaults to reka's ConfigProvider, then the browser. */
57
+ locale?: string
58
+ }
@@ -4,6 +4,7 @@
4
4
  * pixel box, return paths and tick positions.
5
5
  */
6
6
 
7
+ import { clamp } from "../composables/clamp"
7
8
  import { compactNumber } from "./format"
8
9
 
9
10
  export interface ChartPoint {
@@ -65,6 +66,29 @@ export interface ChartMarker {
65
66
  color?: string
66
67
  }
67
68
 
69
+ /**
70
+ * A stretch of the x axis: a maintenance window, an incident, off hours. `from`
71
+ * and `to` are point indices or x labels. Drawn under the data.
72
+ */
73
+ export interface ChartBand {
74
+ from: number | string
75
+ to: number | string
76
+ label?: string
77
+ color?: string
78
+ }
79
+
80
+ /**
81
+ * A note pinned to one reading. `at` is a point index or an x label; `value`
82
+ * places it on the y axis and defaults to the first visible series there.
83
+ */
84
+ export interface ChartAnnotation {
85
+ at: number | string
86
+ value?: number
87
+ label: string
88
+ color?: string
89
+ axis?: ChartAxis
90
+ }
91
+
68
92
  /**
69
93
  * Which x labels to print with every `stride`-th one shown. The last point is
70
94
  * always labelled (it is usually "now"), and when it lands within half a
@@ -307,8 +331,8 @@ const smoothSegment = (pts: { x: number; y: number }[], tension: number): string
307
331
  let c2y = p2.y - ((p3.y - p1.y) / 6) * tension
308
332
  const lo = Math.min(p1.y, p2.y)
309
333
  const hi = Math.max(p1.y, p2.y)
310
- c1y = Math.min(hi, Math.max(lo, c1y))
311
- c2y = Math.min(hi, Math.max(lo, c2y))
334
+ c1y = clamp(c1y, lo, hi)
335
+ c2y = clamp(c2y, lo, hi)
312
336
  d += `C${c1x},${c1y} ${c2x},${c2y} ${p2.x},${p2.y}`
313
337
  }
314
338
  return d
@@ -344,7 +368,7 @@ export const areaPath = (
344
368
  s: Scale,
345
369
  smooth: number,
346
370
  ): string => {
347
- const base = yAt(Math.max(s.min, Math.min(s.max, 0)), s.min, s.max, s.box)
371
+ const base = yAt(clamp(0, s.min, s.max), s.min, s.max, s.box)
348
372
  return runs(values, s.count)
349
373
  .map((idx) => {
350
374
  const d = segmentPath(idx, values, s, smooth)
@@ -0,0 +1,198 @@
1
+ import { clamp } from "../composables/clamp"
2
+
3
+ /*
4
+ * The part of a long series a chart draws: which points are in the window, and
5
+ * how many of them survive the width of the plot. No DOM and no Vue, so the
6
+ * promises it makes (a peak is never lost) can be tested on the numbers.
7
+ */
8
+
9
+ /** A window into the data: indices of its first and last point, both included. */
10
+ export interface ChartRange {
11
+ start: number
12
+ end: number
13
+ }
14
+
15
+ /** How a series longer than the plot is thinned. */
16
+ export type ChartDownsample = "minmax" | "lttb"
17
+
18
+ /** What the chart draws: per series values, each slot traced back to its source. */
19
+ export interface ChartView {
20
+ values: (number | null)[][]
21
+ start: number
22
+ end: number
23
+ /** Source index of every slot; null while the slots are contiguous from `start`. */
24
+ indices: number[] | null
25
+ }
26
+
27
+ type Values = (number | null)[]
28
+
29
+ /* Below this a window has no line to read: two points are one segment. */
30
+ export const MIN_RANGE_POINTS = 2
31
+ /* Two slots a bucket: its lowest and its highest reading, in the order they came. */
32
+ const SLOTS_PER_BUCKET = 2
33
+ /* LTTB always keeps the first and last point, so anything less is not a choice. */
34
+ const LTTB_MIN_TARGET = 3
35
+ /* Share of the window one step of a keyboard or wheel zoom takes away. */
36
+ export const ZOOM_STEP = 0.8
37
+
38
+ /**
39
+ * A range fit to the data: in bounds, ordered, at least `MIN_RANGE_POINTS` wide.
40
+ * Null when there is nothing to narrow, so the whole series stays the plain case.
41
+ */
42
+ export function clampRange(range: ChartRange | null | undefined, count: number): ChartRange | null {
43
+ if (!range || count <= MIN_RANGE_POINTS || !Number.isFinite(range.start) || !Number.isFinite(range.end)) return null
44
+ const last = count - 1
45
+ let start = Math.max(0, Math.min(last, Math.round(Math.min(range.start, range.end))))
46
+ let end = Math.max(0, Math.min(last, Math.round(Math.max(range.start, range.end))))
47
+ if (end - start + 1 < MIN_RANGE_POINTS) {
48
+ end = Math.min(last, start + MIN_RANGE_POINTS - 1)
49
+ start = Math.max(0, end - MIN_RANGE_POINTS + 1)
50
+ }
51
+ return start === 0 && end === last ? null : { start, end }
52
+ }
53
+
54
+ /** The range after a zoom by `factor` (below 1 is in), keeping `anchor` (0–1 across it) in place. */
55
+ export function zoomRange(range: ChartRange | null, count: number, anchor: number, factor: number): ChartRange | null {
56
+ const from = range ?? { start: 0, end: count - 1 }
57
+ const span = from.end - from.start
58
+ const next = Math.max(MIN_RANGE_POINTS - 1, span * factor)
59
+ const at = from.start + span * clamp(anchor, 0, 1)
60
+ const start = at - (at - from.start) * (next / (span || 1))
61
+ return clampRange({ start, end: start + next }, count)
62
+ }
63
+
64
+ /** The range moved by `delta` points, keeping its width at the ends of the data. */
65
+ export function panRange(range: ChartRange, count: number, delta: number): ChartRange | null {
66
+ const span = range.end - range.start
67
+ const start = Math.max(0, Math.min(count - 1 - span, range.start + delta))
68
+ return clampRange({ start, end: start + span }, count)
69
+ }
70
+
71
+ /**
72
+ * Keeps each bucket's lowest and highest reading, per series. Slots stay shared
73
+ * across series, so a bucket is two x positions and each series fills them with
74
+ * its own extremes. A monitoring chart must not lose a one-point spike: thinning
75
+ * by average or by every n-th point does exactly that.
76
+ */
77
+ export function minMaxBuckets(series: Values[], slots: number): { values: Values[]; indices: number[] } {
78
+ const count = series.reduce((n, values) => Math.max(n, values.length), 0)
79
+ const buckets = Math.floor(slots / SLOTS_PER_BUCKET)
80
+ if (count === 0 || buckets < 1) return { values: series.map(() => []), indices: [] }
81
+ const indices: number[] = []
82
+ const values: Values[] = series.map(() => [])
83
+ for (let bucket = 0; bucket < buckets; bucket++) {
84
+ const from = Math.floor((bucket * count) / buckets)
85
+ const to = Math.floor(((bucket + 1) * count) / buckets)
86
+ if (to <= from) continue
87
+ indices.push(from, Math.max(from, to - 1))
88
+ series.forEach((data, s) => {
89
+ let low = -1
90
+ let high = -1
91
+ for (let i = from; i < to && i < data.length; i++) {
92
+ const v = data[i]
93
+ if (v == null) continue
94
+ if (low < 0 || v < (data[low] as number)) low = i
95
+ if (high < 0 || v > (data[high] as number)) high = i
96
+ }
97
+ if (low < 0) values[s].push(null, null)
98
+ else values[s].push(data[Math.min(low, high)], data[Math.max(low, high)])
99
+ })
100
+ }
101
+ return { values, indices }
102
+ }
103
+
104
+ /**
105
+ * Largest-Triangle-Three-Buckets: the indices of `target` points that keep a
106
+ * line's shape, one a bucket, always with its first and last. It reads better
107
+ * than min/max on a smooth curve and can drop a short spike, so it is the
108
+ * option rather than the default.
109
+ */
110
+ export function lttbIndices(values: Values, target: number): number[] {
111
+ const present = values.flatMap((v, i) => (v == null ? [] : [i]))
112
+ if (target >= present.length || target < LTTB_MIN_TARGET) return present
113
+ const y = (at: number) => values[present[at]] as number
114
+ const x = (at: number) => present[at]
115
+ const step = (present.length - 2) / (target - 2)
116
+ const kept = [0]
117
+ let previous = 0
118
+ for (let bucket = 0; bucket < target - 2; bucket++) {
119
+ const from = Math.floor(bucket * step) + 1
120
+ const to = Math.floor((bucket + 1) * step) + 1
121
+ const nextEnd = Math.min(present.length, Math.floor((bucket + 2) * step) + 1)
122
+ let meanX = 0
123
+ let meanY = 0
124
+ for (let i = to; i < nextEnd; i++) {
125
+ meanX += x(i)
126
+ meanY += y(i)
127
+ }
128
+ const size = Math.max(1, nextEnd - to)
129
+ meanX /= size
130
+ meanY /= size
131
+ let best = from
132
+ let largest = -1
133
+ for (let i = from; i < to; i++) {
134
+ const area = Math.abs((x(previous) - meanX) * (y(i) - y(previous)) - (x(previous) - x(i)) * (meanY - y(previous)))
135
+ if (area > largest) {
136
+ largest = area
137
+ best = i
138
+ }
139
+ }
140
+ kept.push(best)
141
+ previous = best
142
+ }
143
+ kept.push(present.length - 1)
144
+ return kept.map((at) => present[at])
145
+ }
146
+
147
+ const contiguous = (series: Values[], range: ChartRange): Values[] =>
148
+ series.map((values) => values.slice(range.start, range.end + 1))
149
+
150
+ /**
151
+ * The series as drawn. Without a range or a thinning it hands the input back, so
152
+ * a chart using neither does no work and draws what it always drew.
153
+ *
154
+ * LTTB picks by the first series that has data and the others follow those
155
+ * points, because slots are shared across series.
156
+ */
157
+ export function chartView(
158
+ series: Values[],
159
+ count: number,
160
+ range: ChartRange | null,
161
+ mode: ChartDownsample | false | undefined,
162
+ slots: number,
163
+ ): ChartView {
164
+ const start = range?.start ?? 0
165
+ const end = range?.end ?? Math.max(0, count - 1)
166
+ const windowed = range ? contiguous(series, range) : series
167
+ const shown = end - start + 1
168
+ if (!mode || slots <= 0 || shown <= slots) return { values: windowed, start, end, indices: null }
169
+ if (mode === "minmax") {
170
+ const { values, indices } = minMaxBuckets(windowed, slots)
171
+ return { values, start, end, indices: indices.map((i) => i + start) }
172
+ }
173
+ const lead = windowed.find((values) => values.some((v) => v != null)) ?? []
174
+ const picked = lttbIndices(lead, slots)
175
+ return {
176
+ values: windowed.map((values) => picked.map((i) => values[i] ?? null)),
177
+ start,
178
+ end,
179
+ indices: picked.map((i) => i + start),
180
+ }
181
+ }
182
+
183
+ /** The slot at or before a source index, or -1 when the window does not hold it. */
184
+ export function slotOf(view: ChartView, source: number): number {
185
+ if (source < view.start || source > view.end) return -1
186
+ if (!view.indices) return source - view.start
187
+ let low = 0
188
+ let high = view.indices.length - 1
189
+ while (low < high) {
190
+ const middle = Math.ceil((low + high) / 2)
191
+ if (view.indices[middle] <= source) low = middle
192
+ else high = middle - 1
193
+ }
194
+ return high < 0 ? -1 : low
195
+ }
196
+
197
+ /** The source index behind a slot. */
198
+ export const sourceOf = (view: ChartView, slot: number): number => (view.indices ? (view.indices[slot] ?? -1) : slot + view.start)
@@ -1,3 +1,5 @@
1
+ import { clamp } from "../composables/clamp"
2
+
1
3
  /*
2
4
  * Colour conversion for LpColorPicker — kept out of the component so the maths
3
5
  * is testable on its own and reusable by anything that has to meet a colour
@@ -33,7 +35,6 @@ export interface Rgb {
33
35
  /** The string shapes a caller can hand the picker, and ask back out of it. */
34
36
  export type ColorFormat = "hex" | "rgb" | "hsl"
35
37
 
36
- const clamp = (n: number, min: number, max: number) => Math.min(max, Math.max(min, n))
37
38
 
38
39
  /** Wraps rather than clamps: hue is a circle, and 370° is 10°, not 360°. */
39
40
  export function normalizeHue(h: number): number {
@@ -165,6 +165,52 @@ export interface RecentSource {
165
165
  children?: unknown
166
166
  }
167
167
 
168
+ /*
169
+ * Where a command's `href` may lead. Commands can come from a search or from
170
+ * stored history, so a `javascript:` link there would run in the app's origin.
171
+ * Mail and phone links are as harmless as a web one and common in a help menu.
172
+ * The base only lets a relative link parse: nothing here reads the window, so
173
+ * this holds on the server.
174
+ */
175
+ const SAFE_LINK_SCHEMES = new Set(["http:", "https:", "mailto:", "tel:"])
176
+ const RELATIVE_BASE = "http://relative.invalid/"
177
+
178
+ export function isSafeHref(href: string): boolean {
179
+ try {
180
+ return SAFE_LINK_SCHEMES.has(new URL(href, RELATIVE_BASE).protocol)
181
+ } catch {
182
+ return false
183
+ }
184
+ }
185
+
186
+ /** The link as it would be pasted elsewhere: absolute, or as given if it cannot be read. */
187
+ export function absoluteHref(href: string, base: string): string {
188
+ try {
189
+ return new URL(href, base).href
190
+ } catch {
191
+ return href
192
+ }
193
+ }
194
+
195
+ /** The row that unfolds a group; the NUL keeps it out of any id an app would write. */
196
+ export function moreRowId(group: string): string {
197
+ return `\u0000lp-cmd-more\u0000${group}`
198
+ }
199
+
200
+ const IMAGE_SHAPES: unknown[] = ["circle", "soft", "square"]
201
+ const isOptionalString = (value: unknown) => value === undefined || typeof value === "string"
202
+
203
+ function isStoredImage(value: unknown): boolean {
204
+ if (value === undefined || typeof value === "string") return true
205
+ if (!value || typeof value !== "object") return false
206
+ const { src, alt, fallback, icon, shape } = value as Record<string, unknown>
207
+ return (src === null || isOptionalString(src))
208
+ && isOptionalString(alt)
209
+ && isOptionalString(fallback)
210
+ && isOptionalString(icon)
211
+ && (shape === undefined || IMAGE_SHAPES.includes(shape))
212
+ }
213
+
168
214
  function isEntry(value: unknown): value is RecentEntry {
169
215
  if (!value || typeof value !== "object") return false
170
216
  const v = value as Record<string, unknown>
@@ -173,6 +219,10 @@ function isEntry(value: unknown): value is RecentEntry {
173
219
  && typeof v.label === "string"
174
220
  && Array.isArray(v.path)
175
221
  && v.path.every((step) => typeof step === "string")
222
+ && isOptionalString(v.description)
223
+ && isOptionalString(v.icon)
224
+ && isStoredImage(v.image)
225
+ && (v.href === undefined || (typeof v.href === "string" && isSafeHref(v.href)))
176
226
  )
177
227
  }
178
228
 
@@ -182,17 +232,28 @@ export function readRecent(stored: unknown): RecentItem[] {
182
232
  return stored.filter((v): v is RecentItem => typeof v === "string" || isEntry(v))
183
233
  }
184
234
 
185
- function recentKey(item: RecentItem): string {
186
- return typeof item === "string" ? item : [...item.path, item.id].join("\u0000")
235
+ /**
236
+ * What makes a command itself: the same id may live in two modes
237
+ * (`services/restart`, `deploy/restart`). A root command's key is its bare id,
238
+ * so a stored id and a stored entry at the root count as one.
239
+ */
240
+ export function commandKey(id: string, path: readonly string[] = []): string {
241
+ return [...path, id].join("\u0000")
242
+ }
243
+
244
+ export function recentKey(item: RecentItem): string {
245
+ return typeof item === "string" ? item : commandKey(item.id, item.path)
187
246
  }
188
247
 
189
248
  /**
190
249
  * The history item for a pick. A root pick stays a bare id, the format older
191
250
  * versions wrote and still read; anything deeper becomes an entry with only
192
- * the fields that survive JSON.
251
+ * the fields that survive JSON. So does a `fetched` pick at the root: its id
252
+ * stands for nothing among the root commands, and only an entry reaches
253
+ * `resolveRecent` with what is needed to find it again.
193
254
  */
194
- export function toRecentItem(command: RecentSource, path: readonly string[]): RecentItem {
195
- if (!path.length) return command.id
255
+ export function toRecentItem(command: RecentSource, path: readonly string[], fetched = false): RecentItem {
256
+ if (!path.length && !fetched) return command.id
196
257
  const entry: RecentEntry = { id: command.id, label: command.label, path: [...path] }
197
258
  if (command.description) entry.description = command.description
198
259
  if (command.icon) entry.icon = command.icon
@@ -0,0 +1,6 @@
1
+ /* Height and text of a control at each size, shared so a form lines up. */
2
+ export const CONTROL_SIZE = {
3
+ sm: "h-(--size-control-sm) text-xs",
4
+ md: "h-(--size-control-md) text-sm",
5
+ lg: "h-(--size-control-lg) text-sm",
6
+ }
@@ -71,6 +71,9 @@ export const optionStagger = (index: number): { animationDelay: string } => ({
71
71
  * dip on press. Put on the <LpIcon>, with `group` on its button. Shared by
72
72
  * Modal, Drawer, Toaster and the Autocomplete clear button.
73
73
  */
74
+ /* Where a combobox list sits under its field. */
75
+ export const COMBOBOX_PANEL = { collisionPadding: 8, position: "popper", sideOffset: 6 } as const
76
+
74
77
  export const CLOSE_ICON =
75
78
  "transition-transform duration-medium ease-[var(--ease-emphasized)] " +
76
79
  "group-hover:rotate-90 group-active:scale-90 motion-reduce:group-hover:rotate-0"
@@ -2,6 +2,7 @@
2
2
  * Data export shared by the table and the chart: CSV text, a file download,
3
3
  * and an SVG rasterised with its theme resolved.
4
4
  */
5
+ import { isElement, nodeWindow } from "../composables/useView"
5
6
 
6
7
  export interface CsvColumn<Row> {
7
8
  key: string
@@ -64,19 +65,30 @@ export function toCsv<Row>(rows: readonly Row[], columns: readonly CsvColumn<Row
64
65
  * Hand the viewer a file to save. Does nothing outside a browser, so a call
65
66
  * that runs during SSR is harmless.
66
67
  */
67
- export function downloadFile(name: string, data: Blob | string, type = "text/plain;charset=utf-8"): void {
68
- if (typeof document === "undefined" || typeof URL === "undefined") return
68
+ export function downloadFile(
69
+ name: string,
70
+ data: Blob | string,
71
+ type = "text/plain;charset=utf-8",
72
+ doc: Document | undefined = typeof document === "undefined" ? undefined : document,
73
+ ): void {
74
+ if (!doc || typeof URL === "undefined") return
69
75
  const blob = typeof data === "string" ? new Blob([data], { type }) : data
70
76
  const url = URL.createObjectURL(blob)
71
- const a = document.createElement("a")
72
- a.href = url
73
- a.download = name
74
- a.rel = "noopener"
77
+ clickLink(doc, { href: url, download: name, rel: "noopener" })
78
+ setTimeout(() => URL.revokeObjectURL(url), 0)
79
+ }
80
+
81
+ /**
82
+ * Follow a link the way a click on it would, from the document it should open
83
+ * in: an LpFrame's, inside one.
84
+ */
85
+ export function clickLink(doc: Document, attributes: Partial<Pick<HTMLAnchorElement, "href" | "download" | "target" | "rel">>): void {
86
+ const a = doc.createElement("a")
87
+ Object.assign(a, attributes)
75
88
  a.style.display = "none"
76
- document.body.append(a)
89
+ doc.body.append(a)
77
90
  a.click()
78
91
  a.remove()
79
- setTimeout(() => URL.revokeObjectURL(url), 0)
80
92
  }
81
93
 
82
94
  const PAINT_PROPS = [
@@ -111,13 +123,14 @@ const PAINT_PROPS = [
111
123
  * are frozen at their end state.
112
124
  */
113
125
  export function inlineSvg(svg: SVGSVGElement): SVGSVGElement {
126
+ const view = nodeWindow(svg)
114
127
  const clone = svg.cloneNode(true) as SVGSVGElement
115
128
  const source = [svg, ...svg.querySelectorAll("*")]
116
129
  const target = [clone, ...clone.querySelectorAll("*")]
117
130
  source.forEach((el, i) => {
118
131
  const copy = target[i]
119
- if (!(copy instanceof Element)) return
120
- const computed = getComputedStyle(el)
132
+ if (!isElement(copy)) return
133
+ const computed = view.getComputedStyle(el)
121
134
  const style = PAINT_PROPS.map((p) => `${p}:${computed.getPropertyValue(p)}`)
122
135
  .filter((d) => !d.endsWith(":"))
123
136
  .join(";")
@@ -126,7 +139,7 @@ export function inlineSvg(svg: SVGSVGElement): SVGSVGElement {
126
139
  })
127
140
  // Comment nodes (Vue leaves them in development builds) may hold "--", which
128
141
  // is invalid inside an XML comment and makes the whole image fail to load.
129
- const comments = document.createTreeWalker(clone, NodeFilter.SHOW_COMMENT)
142
+ const comments = view.document.createTreeWalker(clone, view.NodeFilter.SHOW_COMMENT)
130
143
  const dead: Node[] = []
131
144
  while (comments.nextNode()) dead.push(comments.currentNode)
132
145
  for (const node of dead) node.parentNode?.removeChild(node)
@@ -157,13 +170,14 @@ export interface RasterOptions {
157
170
 
158
171
  /** Rasterise an SVG element to a PNG blob with its theme resolved. */
159
172
  export async function svgToPng(svg: SVGSVGElement, options: RasterOptions = {}): Promise<Blob> {
173
+ const view = nodeWindow(svg)
160
174
  const copy = inlineSvg(svg)
161
175
  const width = Number(copy.getAttribute("width"))
162
176
  const height = Number(copy.getAttribute("height"))
163
177
  const markup = new XMLSerializer().serializeToString(copy)
164
178
  const url = URL.createObjectURL(new Blob([markup], { type: "image/svg+xml;charset=utf-8" }))
165
179
  try {
166
- const img = new Image()
180
+ const img = new view.Image()
167
181
  img.decoding = "async"
168
182
  const loaded = new Promise<void>((resolve, reject) => {
169
183
  img.onload = () => resolve()
@@ -172,11 +186,11 @@ export async function svgToPng(svg: SVGSVGElement, options: RasterOptions = {}):
172
186
  img.src = url
173
187
  await loaded
174
188
 
175
- const scale = options.scale ?? Math.max(2, globalThis.devicePixelRatio || 1)
189
+ const scale = options.scale ?? Math.max(2, view.devicePixelRatio || 1)
176
190
  const pad = options.padding ?? 0
177
- const measure = document.createElement("canvas").getContext("2d")
191
+ const measure = view.document.createElement("canvas").getContext("2d")
178
192
  const headerHeight = measure && options.header ? options.header(measure, width) : 0
179
- const canvas = document.createElement("canvas")
193
+ const canvas = view.document.createElement("canvas")
180
194
  canvas.width = Math.ceil((width + pad * 2) * scale)
181
195
  canvas.height = Math.ceil((height + headerHeight + pad * 2) * scale)
182
196
  const ctx = canvas.getContext("2d")
@@ -200,7 +214,7 @@ export async function svgToPng(svg: SVGSVGElement, options: RasterOptions = {}):
200
214
  /** The first non-transparent background at or above an element. */
201
215
  export function backgroundOf(el: Element | null): string | undefined {
202
216
  for (let node = el; node; node = node.parentElement) {
203
- const bg = getComputedStyle(node).backgroundColor
217
+ const bg = nodeWindow(node).getComputedStyle(node).backgroundColor
204
218
  if (bg && bg !== "transparent" && !/rgba\([^)]*,\s*0\)$/.test(bg)) return bg
205
219
  }
206
220
  return undefined
@@ -212,11 +226,12 @@ export function backgroundOf(el: Element | null): string | undefined {
212
226
  */
213
227
  export function resolveCssColor(value: string, within: Element): string {
214
228
  if (!value.includes("var(") && !value.toLowerCase().includes("currentcolor")) return value
215
- const probe = document.createElement("span")
229
+ const view = nodeWindow(within)
230
+ const probe = view.document.createElement("span")
216
231
  probe.style.color = value
217
232
  probe.style.display = "none"
218
233
  within.append(probe)
219
- const resolved = getComputedStyle(probe).color
234
+ const resolved = view.getComputedStyle(probe).color
220
235
  probe.remove()
221
236
  return resolved || value
222
237
  }