@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,197 @@
1
+ <script lang="ts">
2
+ import IconCloseButton from "./IconCloseButton.vue"
3
+ import { clamp } from "../composables/clamp"
4
+ import type { DataListItem } from "./LpDataList.vue"
5
+
6
+ export interface InspectorSection {
7
+ /** Stable identity, and the name of its slot: `#section-<key>`. */
8
+ key: string
9
+ title?: string
10
+ /** Facts about the subject. Replaced by the section's slot, which is where editing fields go. */
11
+ items?: DataListItem[]
12
+ /** Folds under its title. Sections without a title cannot fold. */
13
+ collapsible?: boolean
14
+ /** Starts folded, when `collapsible`. */
15
+ collapsed?: boolean
16
+ }
17
+
18
+ export default { inheritAttrs: false }
19
+ </script>
20
+
21
+ <script setup lang="ts" generic="T">
22
+ /*
23
+ * The panel beside a table, graph or canvas that shows the selected thing and
24
+ * lets it be edited: one place and one shape for "what is this, and change it".
25
+ *
26
+ * <LpInspector :subject="server" :title="server?.name" :sections="[
27
+ * { key: 'facts', title: 'Overview', items: facts },
28
+ * { key: 'edit', title: 'Settings' },
29
+ * ]" v-model:open="inspecting" resizable persist="servers">
30
+ * <template #section-edit="{ subject }"><LpInput v-model="subject.name" label="Name" /></template>
31
+ * </LpInspector>
32
+ *
33
+ * It sits in the layout, beside what it inspects, so selecting another row
34
+ * while it is open just works: nothing is covered and no focus is taken. On a
35
+ * phone, where there is no beside, put it in an LpDrawer with `closable` off.
36
+ *
37
+ * With nothing selected it stays and says so (`#empty`), so the page around it
38
+ * does not jump at every change of selection.
39
+ */
40
+ import { computed, onBeforeUnmount, useSlots, watch } from "vue"
41
+ import { startPointerDrag } from "../composables/pointerDrag"
42
+ import { useCloseGuard, type CloseGuard } from "../composables/useCloseGuard"
43
+ import { useLabels } from "../composables/useLpConfig"
44
+ import { useMergedAttrs } from "../composables/useMergedClass"
45
+ import { usePersisted } from "../composables/usePersisted"
46
+ import { CLOSE_ICON } from "./dropdown"
47
+ import LpDataList from "./LpDataList.vue"
48
+ import LpDisclosure from "./LpDisclosure.vue"
49
+ import LpIcon from "./LpIcon.vue"
50
+ import LpScrollArea from "./LpScrollArea.vue"
51
+
52
+ const KEY_STEP = 16
53
+
54
+ const props = withDefaults(
55
+ defineProps<{
56
+ /** The thing inspected, handed to the slots. Empty state when nothing else is given either. */
57
+ subject?: T | null
58
+ title?: string
59
+ subtitle?: string
60
+ sections?: InspectorSection[]
61
+ /** Which side of the content it sits on: the resize grip goes on the other. */
62
+ side?: "left" | "right"
63
+ /** Default width in px. */
64
+ width?: number
65
+ /** Drag the inner edge to resize, or use arrow keys on it. */
66
+ resizable?: boolean
67
+ minWidth?: number
68
+ maxWidth?: number
69
+ /** Remember the dragged width under this key, across visits. */
70
+ persist?: string
71
+ closable?: boolean
72
+ /** Unsaved edits: `true` asks before closing, a function asks the app. */
73
+ guard?: CloseGuard
74
+ labels?: Partial<{ close: string; empty: string; resize: string; region: string }>
75
+ }>(),
76
+ { side: "right", width: 320, minWidth: 240, maxWidth: 640, closable: true, subject: undefined },
77
+ )
78
+
79
+ const open = defineModel<boolean>("open", { default: true })
80
+ const slots = useSlots()
81
+ const text = useLabels(
82
+ "inspector",
83
+ { close: "Close", empty: "Nothing selected", resize: "Resize panel", region: "Details" },
84
+ () => props.labels,
85
+ )
86
+
87
+ const saved = usePersisted<number | null>(() => props.resizable && props.persist && `lp-inspector:${props.persist}`, null, {
88
+ validate: (value): value is number | null => value === null || (typeof value === "number" && value > 0),
89
+ })
90
+ // Applied within today's limits; the saved width outlives a change to them.
91
+ const shownWidth = computed(() => clamp(saved.value ?? props.width, props.minWidth, props.maxWidth))
92
+
93
+ const isEmpty = computed(() => props.subject == null && !props.sections?.length && !slots.default)
94
+
95
+ const { allowClose } = useCloseGuard(() => props.guard, () => open.value)
96
+ async function close() {
97
+ if (await allowClose()) open.value = false
98
+ }
99
+ defineExpose({ close })
100
+
101
+ const { class: rootClass, attrs: rest } = useMergedAttrs(() =>
102
+ [
103
+ "relative flex h-full min-h-0 shrink-0 flex-col bg-surface border-line",
104
+ props.side === "right" ? "border-l" : "border-r",
105
+ ].join(" "),
106
+ )
107
+
108
+ let stopDrag: (() => void) | null = null
109
+
110
+ function startResize(event: PointerEvent) {
111
+ if (event.button !== 0) return
112
+ const start = shownWidth.value
113
+ const startX = event.clientX
114
+ const sign = props.side === "right" ? -1 : 1
115
+ stopDrag = startPointerDrag(event, {
116
+ move: (ev) => {
117
+ saved.value = clamp(start + (ev.clientX - startX) * sign, props.minWidth, props.maxWidth)
118
+ },
119
+ end: () => (stopDrag = null),
120
+ })
121
+ }
122
+
123
+ function onGripKeydown(event: KeyboardEvent) {
124
+ const step = event.key === "ArrowLeft" ? -KEY_STEP : event.key === "ArrowRight" ? KEY_STEP : 0
125
+ if (!step) return
126
+ event.preventDefault()
127
+ const sign = props.side === "right" ? -1 : 1
128
+ saved.value = clamp(shownWidth.value + step * sign, props.minWidth, props.maxWidth)
129
+ }
130
+
131
+ watch(open, (isOpen) => {
132
+ if (!isOpen) stopDrag?.()
133
+ })
134
+ onBeforeUnmount(() => stopDrag?.())
135
+ </script>
136
+
137
+ <template>
138
+ <aside
139
+ v-if="open"
140
+ v-bind="rest"
141
+ :class="rootClass"
142
+ :style="{ width: `${shownWidth}px` }"
143
+ :aria-label="title ?? text.region"
144
+ >
145
+ <div
146
+ v-if="resizable"
147
+ role="separator"
148
+ tabindex="0"
149
+ aria-orientation="vertical"
150
+ :aria-label="text.resize"
151
+ :aria-valuenow="shownWidth"
152
+ :aria-valuemin="minWidth"
153
+ :aria-valuemax="maxWidth"
154
+ class="group/resize absolute inset-y-0 z-10 w-1.5 cursor-ew-resize touch-none outline-none"
155
+ :class="side === 'right' ? '-left-px' : '-right-px'"
156
+ @pointerdown="startResize"
157
+ @keydown="onGripKeydown"
158
+ >
159
+ <span class="absolute inset-y-0 left-0 w-px transition-colors group-hover/resize:bg-brand group-focus-visible/resize:bg-brand" />
160
+ </div>
161
+
162
+ <header v-if="title || subtitle || $slots.title || closable" class="flex shrink-0 items-start gap-2 px-4 pb-3 pt-4">
163
+ <div class="min-w-0 flex-1">
164
+ <h2 class="truncate text-sm font-semibold text-ink"><slot name="title">{{ title }}</slot></h2>
165
+ <p v-if="subtitle" class="truncate text-xs text-muted">{{ subtitle }}</p>
166
+ </div>
167
+ <slot name="actions" />
168
+ <IconCloseButton v-if="closable" :label="text.close" @click="close" />
169
+ </header>
170
+
171
+ <LpScrollArea class="min-h-0 flex-1" content-class="flex flex-col gap-4 px-4 pb-4">
172
+ <slot v-if="isEmpty" name="empty">
173
+ <p class="py-8 text-center text-sm text-muted">{{ text.empty }}</p>
174
+ </slot>
175
+ <template v-else>
176
+ <template v-for="section in sections" :key="section.key">
177
+ <LpDisclosure v-if="section.collapsible && section.title" :label="section.title" :default-open="!section.collapsed">
178
+ <slot :name="`section-${section.key}`" :subject="subject" :section="section">
179
+ <LpDataList :items="section.items ?? []" size="sm" />
180
+ </slot>
181
+ </LpDisclosure>
182
+ <section v-else class="flex flex-col gap-2">
183
+ <h3 v-if="section.title" class="text-xs font-semibold text-muted">{{ section.title }}</h3>
184
+ <slot :name="`section-${section.key}`" :subject="subject" :section="section">
185
+ <LpDataList :items="section.items ?? []" size="sm" />
186
+ </slot>
187
+ </section>
188
+ </template>
189
+ <slot :subject="subject" />
190
+ </template>
191
+ </LpScrollArea>
192
+
193
+ <footer v-if="$slots.footer" class="flex shrink-0 justify-end gap-2 px-4 pb-4 pt-3">
194
+ <slot name="footer" :subject="subject" :close="close" />
195
+ </footer>
196
+ </aside>
197
+ </template>
@@ -1,4 +1,5 @@
1
1
  <script setup lang="ts">
2
+ import { useModelOverlayHistory, type OverlayHistoryMode } from "../composables/useOverlayHistory"
2
3
  /*
3
4
  * Full-screen image viewer — the Discord-style lightbox: click a thumbnail, the
4
5
  * image fills the screen, arrows step through the set, the wheel zooms toward
@@ -13,6 +14,7 @@
13
14
  * Controlled via v-model:open and v-model:index, so the caller owns which image
14
15
  * is showing and can drive it from a grid, a route or a keyboard shortcut.
15
16
  */
17
+ import { clamp } from "../composables/clamp"
16
18
  import {
17
19
  DialogContent,
18
20
  DialogDescription,
@@ -24,12 +26,14 @@ import {
24
26
  import { computed, nextTick, onBeforeUnmount, ref, watch } from "vue"
25
27
  import { useLabels } from "../composables/useLpConfig"
26
28
  import { useZoomPan } from "../composables/useZoomPan"
29
+ import { clickLink } from "./exportData"
27
30
  import { fileNameOf, type LightboxItem } from "./lightbox"
28
31
  import LpCopyButton from "./LpCopyButton.vue"
29
32
  import LpIcon from "./LpIcon.vue"
30
33
  import LpLoader from "./LpLoader.vue"
31
34
  import { useModalLayer } from "./modalDepth"
32
- import { useOutsideGuard, usePortalTarget } from "../composables/useView"
35
+ import { inTextField } from "../composables/textEntry"
36
+ import { nodeWindow, useOutsideGuard, usePortalTarget, useView, viewDocument } from "../composables/useView"
33
37
 
34
38
  export type LightboxLabels = {
35
39
  viewer: string
@@ -50,6 +54,12 @@ export type LightboxLabels = {
50
54
 
51
55
  const props = withDefaults(
52
56
  defineProps<{
57
+ /**
58
+ * Browser Back closes it, and opening it adds a history entry. Unset
59
+ * follows `provideOverlayHistory` (off without one); `"reopen"` also opens
60
+ * it again on Forward; `false` keeps it out of history.
61
+ */
62
+ history?: OverlayHistoryMode
53
63
  open?: boolean
54
64
  /** Images to page through. */
55
65
  items: LightboxItem[]
@@ -70,6 +80,7 @@ const props = withDefaults(
70
80
  labels?: Partial<LightboxLabels>
71
81
  }>(),
72
82
  {
83
+ history: undefined,
73
84
  open: false,
74
85
  index: 0,
75
86
  rotatable: true,
@@ -90,6 +101,13 @@ const emit = defineEmits<{
90
101
  (e: "copy", item: LightboxItem, ok: boolean): void
91
102
  }>()
92
103
 
104
+ useModelOverlayHistory({
105
+ mode: () => props.history,
106
+ open: () => !!props.open,
107
+ setOpen: (open) => emit("update:open", open),
108
+ allowClose: async () => true,
109
+ })
110
+
93
111
  const text = useLabels<LightboxLabels>(
94
112
  "lightbox",
95
113
  {
@@ -137,7 +155,7 @@ const isPanning = computed(() => zoom.panning.value)
137
155
  // moves it locally and reports the move.
138
156
  const shown = ref(props.index)
139
157
  watch(() => props.index, (i) => (shown.value = i))
140
- const current = computed(() => Math.min(Math.max(shown.value, 0), Math.max(props.items.length - 1, 0)))
158
+ const current = computed(() => clamp(shown.value, 0, Math.max(props.items.length - 1, 0)))
141
159
  const item = computed<LightboxItem | undefined>(() => props.items[current.value])
142
160
  const total = computed(() => props.items.length)
143
161
  const showStrip = computed(() => props.filmstrip ?? total.value > 1)
@@ -146,6 +164,7 @@ const rotation = ref(0)
146
164
  const loading = ref(false)
147
165
  const failed = ref(false)
148
166
  const viewport = ref<HTMLElement | null>(null)
167
+ const stageImage = ref<HTMLImageElement | null>(null)
149
168
  const stripEl = ref<HTMLElement | null>(null)
150
169
 
151
170
  watch(viewport, (el) => zoom.setViewport(el))
@@ -158,7 +177,7 @@ function go(next: number) {
158
177
  if (!total.value) return
159
178
  const wrapped = props.loop
160
179
  ? (next + total.value) % total.value
161
- : Math.min(Math.max(next, 0), total.value - 1)
180
+ : clamp(next, 0, total.value - 1)
162
181
  if (wrapped === current.value) return
163
182
  // Compare against the raw target, not the wrapped one: stepping past the last
164
183
  // image is still "forward" even though the index jumps back to 0.
@@ -225,7 +244,7 @@ function onStageWheel(e: WheelEvent) {
225
244
  // Reset the view whenever the image changes — carrying a 4x zoom onto the next
226
245
  // picture means landing on a random crop of it.
227
246
  watch(
228
- () => [current.value, props.open] as const,
247
+ () => [current.value, props.open, item.value?.src] as const,
229
248
  () => {
230
249
  zoom.reset()
231
250
  rotation.value = 0
@@ -235,6 +254,16 @@ watch(
235
254
  },
236
255
  )
237
256
 
257
+ /*
258
+ * An image paged past stays in flight after it leaves the DOM and still reports
259
+ * here: only the one on stage may settle the spinner or the failed state.
260
+ */
261
+ function imageSettled(event: Event, ok: boolean) {
262
+ if (event.currentTarget !== stageImage.value) return
263
+ loading.value = false
264
+ if (!ok) failed.value = true
265
+ }
266
+
238
267
  function scrollThumbIntoView() {
239
268
  const el = stripEl.value?.querySelector<HTMLElement>(`[data-index="${current.value}"]`)
240
269
  el?.scrollIntoView({ behavior: "smooth", block: "nearest", inline: "center" })
@@ -261,7 +290,13 @@ watch(
261
290
  },
262
291
  )
263
292
 
293
+ /* Controls in the `actions` slot keep their own keys: a caret, a typed "r". */
294
+ const OWNS_KEYS =
295
+ "input, textarea, select, [contenteditable]:not([contenteditable='false']), [role='textbox'], [role='searchbox'], [role='combobox']"
296
+
264
297
  function onKeydown(e: KeyboardEvent) {
298
+ if (e.defaultPrevented || e.ctrlKey || e.metaKey || e.altKey) return
299
+ if (inTextField(e.target, OWNS_KEYS)) return
265
300
  switch (e.key) {
266
301
  case "ArrowRight":
267
302
  e.preventDefault()
@@ -338,27 +373,27 @@ function onViewportClick(e: MouseEvent) {
338
373
  close()
339
374
  }
340
375
 
376
+ /*
377
+ * The window the viewer opened in. Inside an LpFrame its location is
378
+ * about:blank, which resolves nothing, so a relative source is read against the
379
+ * document's base URL rather than the location.
380
+ */
381
+ const view = useView()
382
+ const viewerDocument = () => viewDocument(view.value)
383
+ const viewerWindow = () => nodeWindow(viewerDocument())
384
+ const resolved = (src: string) => new URL(src, viewerDocument().baseURI)
385
+
341
386
  function sameOrigin(src: string): boolean {
342
387
  try {
343
- const url = new URL(src, window.location.href)
344
- return url.protocol === "blob:" || url.protocol === "data:" || url.origin === window.location.origin
388
+ const url = resolved(src)
389
+ return url.protocol === "blob:" || url.protocol === "data:" || url.origin === new URL(viewerDocument().baseURI).origin
345
390
  } catch {
346
391
  return false
347
392
  }
348
393
  }
349
394
 
350
395
  function save(href: string, name: string, newTab = false) {
351
- const a = document.createElement("a")
352
- a.href = href
353
- if (newTab) {
354
- a.target = "_blank"
355
- a.rel = "noopener"
356
- } else {
357
- a.download = name
358
- }
359
- document.body.appendChild(a)
360
- a.click()
361
- a.remove()
396
+ clickLink(viewerDocument(), newTab ? { href, target: "_blank", rel: "noopener" } : { href, download: name })
362
397
  }
363
398
 
364
399
  /*
@@ -373,11 +408,12 @@ async function download() {
373
408
  const name = fileNameOf(target)
374
409
  if (sameOrigin(target.src)) return save(target.src, name)
375
410
  try {
376
- const response = await fetch(target.src, { mode: "cors" })
411
+ const win = viewerWindow()
412
+ const response = await win.fetch(resolved(target.src).href, { mode: "cors" })
377
413
  if (!response.ok) throw new Error(String(response.status))
378
- const url = URL.createObjectURL(await response.blob())
414
+ const url = win.URL.createObjectURL(await response.blob())
379
415
  save(url, name)
380
- window.setTimeout(() => URL.revokeObjectURL(url), 0)
416
+ win.setTimeout(() => win.URL.revokeObjectURL(url), 0)
381
417
  } catch {
382
418
  save(target.src, name, true)
383
419
  }
@@ -392,20 +428,28 @@ let copyTarget: LightboxItem | undefined
392
428
  async function imageToCopy(): Promise<Blob> {
393
429
  const target = (copyTarget = item.value)
394
430
  if (!target) throw new Error("No image")
395
- const response = await fetch(target.src)
431
+ const win = viewerWindow()
432
+ const response = await win.fetch(resolved(target.src).href)
396
433
  const blob = await response.blob()
397
434
  // Clipboard only takes PNG; re-encode anything else through a canvas.
398
- return blob.type === "image/png" ? blob : reencodeToPng(await createImageBitmap(blob))
435
+ return blob.type === "image/png" ? blob : reencodeToPng(await win.createImageBitmap(blob))
399
436
  }
400
437
  function copyDone(ok: boolean) {
401
- if (copyTarget) emit("copy", copyTarget, ok)
438
+ const target = copyTarget
439
+ copyTarget = undefined
440
+ if (target) emit("copy", target, ok)
402
441
  }
403
442
 
404
443
  async function reencodeToPng(bitmap: ImageBitmap): Promise<Blob> {
405
- const canvas = document.createElement("canvas")
406
- canvas.width = bitmap.width
407
- canvas.height = bitmap.height
408
- canvas.getContext("2d")?.drawImage(bitmap, 0, 0)
444
+ const canvas = viewerDocument().createElement("canvas")
445
+ try {
446
+ canvas.width = bitmap.width
447
+ canvas.height = bitmap.height
448
+ canvas.getContext("2d")?.drawImage(bitmap, 0, 0)
449
+ } finally {
450
+ // Decoded pixels live outside the JS heap; a large image should not wait for GC.
451
+ bitmap.close()
452
+ }
409
453
  return new Promise((resolve, reject) =>
410
454
  canvas.toBlob((b) => (b ? resolve(b) : reject(new Error("encode failed"))), "image/png"),
411
455
  )
@@ -570,14 +614,15 @@ const guardOutside = useOutsideGuard()
570
614
  <img
571
615
  v-else-if="item"
572
616
  :key="`${current}:${item.src}`"
617
+ ref="stageImage"
573
618
  data-lightbox-image
574
619
  :src="item.src"
575
620
  :alt="item.title ?? ''"
576
621
  class="max-h-full max-w-full select-none object-contain transition-transform duration-[var(--duration-medium)] ease-[var(--ease-emphasized)] animate-[lightbox-frame-in_var(--duration-medium)_var(--ease-emphasized)] motion-reduce:animate-none motion-reduce:transition-none"
577
622
  :style="imageStyle"
578
623
  draggable="false"
579
- @load="loading = false"
580
- @error="((failed = true), (loading = false))"
624
+ @load="imageSettled($event, true)"
625
+ @error="imageSettled($event, false)"
581
626
  />
582
627
 
583
628
  <!-- Mounted throughout and driven by `active`, so a cached image that
@@ -0,0 +1,85 @@
1
+ <script setup lang="ts">
2
+ /*
3
+ * One log entry read closely: a structured payload as a tree, a stack trace with
4
+ * its frames set apart from the error above them. LpLogViewer shows it under
5
+ * the stream for the selected line (`inspector`); on its own it takes the
6
+ * message, or `value` for a payload the app already has parsed.
7
+ */
8
+ import { computed, ref, watch } from "vue"
9
+ import LpIcon from "./LpIcon.vue"
10
+ import LpInput from "./LpInput.vue"
11
+ import { useLabels } from "../composables/useLpConfig"
12
+ import { jsonRows, stackLines, structuredPayload } from "./logTools"
13
+
14
+ export interface LogInspectorLabels {
15
+ [key: string]: string
16
+ title: string
17
+ filterFields: string
18
+ noFields: string
19
+ expand: string
20
+ collapse: string
21
+ }
22
+
23
+ const props = defineProps<{
24
+ /** The entry's text. Its JSON, if it holds any, becomes the tree. */
25
+ message?: string
26
+ /** A parsed payload, instead of reading one from `message`. */
27
+ value?: object
28
+ labels?: Partial<LogInspectorLabels>
29
+ }>()
30
+
31
+ const text = useLabels<LogInspectorLabels>(
32
+ "logInspector",
33
+ { title: "Log entry", filterFields: "Filter fields", noFields: "No fields match", expand: "Expand {field}", collapse: "Collapse {field}" },
34
+ () => props.labels,
35
+ )
36
+
37
+ const filter = ref("")
38
+ const collapsed = ref(new Set<string>())
39
+ const payload = computed(() => props.value ?? (props.message ? structuredPayload(props.message) : null))
40
+ const rows = computed(() => (payload.value ? jsonRows(payload.value, collapsed.value, filter.value) : []))
41
+ const stack = computed(() => (props.message ? stackLines(props.message) : null))
42
+
43
+ // Another entry is another document: what was folded here means nothing there.
44
+ watch(payload, () => {
45
+ collapsed.value = new Set()
46
+ })
47
+
48
+ function toggle(path: string) {
49
+ const next = new Set(collapsed.value)
50
+ if (!next.delete(path)) next.add(path)
51
+ collapsed.value = next
52
+ }
53
+
54
+ const VALUE_TONE = { string: "text-success", number: "text-accent", boolean: "text-brand", null: "text-muted", object: "text-muted", array: "text-muted" }
55
+ /* Each level of the tree steps in by this much, in rem. */
56
+ const INDENT_REM = 1
57
+ </script>
58
+
59
+ <template>
60
+ <section :aria-label="text.title" class="font-mono text-xs leading-5">
61
+ <template v-if="payload">
62
+ <LpInput v-model="filter" type="search" size="sm" icon="lucide:filter" clearable class="mb-2 font-sans" :aria-label="text.filterFields" :placeholder="text.filterFields" />
63
+ <p v-if="!rows.length" class="py-1 font-sans text-muted">{{ text.noFields }}</p>
64
+ <ul v-else class="min-w-0">
65
+ <li v-for="row in rows" :key="row.path" class="flex items-start gap-1" :style="{ paddingLeft: `${row.depth * INDENT_REM}rem` }">
66
+ <button
67
+ v-if="row.expandable"
68
+ type="button"
69
+ class="mt-0.5 shrink-0 rounded-xs text-muted outline-none hover:text-ink focus-visible:ring-2 focus-visible:ring-ring"
70
+ :aria-expanded="!collapsed.has(row.path)"
71
+ :aria-label="(collapsed.has(row.path) ? text.expand : text.collapse).replace('{field}', row.label)"
72
+ @click="toggle(row.path)"
73
+ >
74
+ <LpIcon :name="collapsed.has(row.path) ? 'lucide:chevron-right' : 'lucide:chevron-down'" :size="12" />
75
+ </button>
76
+ <span v-else class="w-3 shrink-0" aria-hidden="true" />
77
+ <span class="shrink-0 text-muted-strong">{{ row.label }}:</span>
78
+ <span class="min-w-0 whitespace-pre-wrap break-words" :class="VALUE_TONE[row.kind]">{{ row.value }}</span>
79
+ </li>
80
+ </ul>
81
+ </template>
82
+ <pre v-else-if="stack" class="overflow-x-auto"><template v-for="(line, i) in stack" :key="i"><span :class="line.frame ? 'text-muted' : 'text-ink'">{{ line.text }}</span>{{ "\n" }}</template></pre>
83
+ <p v-else class="whitespace-pre-wrap break-words text-ink">{{ message }}</p>
84
+ </section>
85
+ </template>