@leavepulse/ui 0.43.4 → 0.44.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 (337) hide show
  1. package/README.md +75 -7
  2. package/dist/assets/{LpCommandPalette-B-0Est4Z.css → LpCommandPalette-DCP5g2ik.css} +21 -21
  3. package/dist/assets/{LpDropzone-BBoWvi-J.css → LpDropzone-i4BdMi1H.css} +12 -12
  4. package/dist/assets/{LpImageEditor-Ct7Y3aNu.css → LpImageEditor-CbMA82g8.css} +6 -6
  5. package/dist/assets/{LpShortcutsDialog-C6YoQ8_M.css → LpShortcutsDialog-ChUyU7oV.css} +7 -7
  6. package/dist/assets/{LpSkeleton-D7xU8IPV.css → LpSkeleton-H3Z5dEIk.css} +4 -1
  7. package/dist/assets/{LpTable-BgPLJOXa.css → LpTable-DDQNdf86.css} +9 -9
  8. package/dist/chunks/ContextMenuItems-CrfeNPWT.js +123 -0
  9. package/dist/chunks/{LayoutCanvas-Dd20boUG.js → LayoutCanvas-D-jPOAvg.js} +26 -9
  10. package/dist/chunks/{LayoutNode-DGpZA9LX.js → LayoutNode-D8Xy9N-o.js} +20 -8
  11. package/dist/chunks/{LpActionBar-BlvtGB2P.js → LpActionBar-BbwCF6l5.js} +24 -10
  12. package/dist/chunks/{LpAddressInput-B-Zvxsn7.js → LpAddressInput-BrOqkZqg.js} +53 -48
  13. package/dist/chunks/{LpAlert-BAYHDSS1.js → LpAlert-DkOIjsbq.js} +15 -8
  14. package/dist/chunks/{LpAppShell-BGQVIY-3.js → LpAppShell-BUKPcHco.js} +51 -24
  15. package/dist/chunks/{LpAutocomplete-DExlIZe_.js → LpAutocomplete-DxV3Y9h4.js} +50 -23
  16. package/dist/chunks/{LpAvatar-B3-xAOH3.js → LpAvatar-ClBbEYZN.js} +17 -8
  17. package/dist/chunks/LpBreadcrumbs-B8IJgFIc.js +95 -0
  18. package/dist/chunks/{LpButton-5VXXCjwF.js → LpButton-kqJBHIIb.js} +44 -14
  19. package/dist/chunks/{LpCard-BhI1N_vL.js → LpCard-CpRByR0q.js} +1 -1
  20. package/dist/chunks/{LpCheckbox-CVccKYaH.js → LpCheckbox-DpqchzH4.js} +7 -3
  21. package/dist/chunks/{LpCodeBlock-Bo0B4TFR.js → LpCodeBlock-DeHJPq7p.js} +48 -16
  22. package/dist/chunks/{LpColorPicker-BlXea7LM.js → LpColorPicker-Bhf1qxhB.js} +32 -9
  23. package/dist/chunks/{LpConfirmDialog-Q-bxff8z.js → LpConfirmDialog-CIUOSnWo.js} +58 -16
  24. package/dist/chunks/LpConfirmHost-CDm0Wtpv.js +49 -0
  25. package/dist/chunks/LpContextMenu-DQw5dGfG.js +68 -0
  26. package/dist/chunks/LpDatePicker-Drirx1AK.js +191 -0
  27. package/dist/chunks/{LpDrawer-BZ6k3hvo.js → LpDrawer-bScx-KMO.js} +63 -26
  28. package/dist/chunks/{LpFileTree-_5vFBgaK.js → LpFileTree-CSI_5SK2.js} +23 -8
  29. package/dist/chunks/{LpFileTreeNode-BdcIYKIE.js → LpFileTreeNode-B4MiSQX2.js} +2 -2
  30. package/dist/chunks/LpFormField-CIk5qosh.js +87 -0
  31. package/dist/chunks/{LpInput-9EXWUM9B.js → LpInput-C0e8y8_d.js} +26 -11
  32. package/dist/chunks/{LpLightbox-2sYVMY-S.js → LpLightbox-Mr0W_6HK.js} +147 -60
  33. package/dist/chunks/{LpLink-DCND-zyu.js → LpLink-Krkjhe_y.js} +15 -6
  34. package/dist/chunks/{LpLogViewer-CaRy5MeS.js → LpLogViewer-YBOaFnc_.js} +68 -34
  35. package/dist/chunks/{LpMapPicker-ul4oYno6.js → LpMapPicker-NUzS9e37.js} +38 -13
  36. package/dist/chunks/{LpMediaGallery-FF-NquIo.js → LpMediaGallery-DfJmMW0I.js} +6 -3
  37. package/dist/chunks/{LpModal-Bt0pQCI_.js → LpModal-DPwGKBPv.js} +49 -26
  38. package/dist/chunks/{LpModalNav-YaifHrXC.js → LpModalNav-DPg5H9f3.js} +9 -6
  39. package/dist/chunks/{LpNotificationBell-DyGGsMAM.js → LpNotificationBell-t5yn-siX.js} +58 -24
  40. package/dist/chunks/{LpNumberField-CWuX08iX.js → LpNumberField-DWnQKktS.js} +20 -7
  41. package/dist/chunks/{LpNumberFlow-amWYaeuA.js → LpNumberFlow-z4WPZcZu.js} +22 -12
  42. package/dist/chunks/{LpOtpInput-y2v-pmiN.js → LpOtpInput-CziPF3Oq.js} +37 -8
  43. package/dist/chunks/{LpPagination-5FxjmmB5.js → LpPagination-DFngX7Xo.js} +30 -19
  44. package/dist/chunks/{LpPasswordInput--sjYCkLS.js → LpPasswordInput-CWVDuBJ5.js} +10 -7
  45. package/dist/chunks/{LpPhoneInput-BDSKVl_z.js → LpPhoneInput-CD-ZTeSd.js} +57 -33
  46. package/dist/chunks/{LpPie-D6OnzwlJ.js → LpPie-BLco31Nx.js} +78 -21
  47. package/dist/chunks/{LpPopover-8268UmlC.js → LpPopover-p_e_shN3.js} +4 -2
  48. package/dist/chunks/{LpProgress-Btq5W4Ut.js → LpProgress-CBU1iI69.js} +5 -4
  49. package/dist/chunks/{LpRadioGroup-xPIuVDO_.js → LpRadioGroup-DmEW0l78.js} +9 -2
  50. package/dist/chunks/{LpSegmented-fV0Sk92p.js → LpSegmented-Dejd7cIx.js} +7 -3
  51. package/dist/chunks/{LpSelect-ANIVtrpM.js → LpSelect-DrRD9I7L.js} +40 -18
  52. package/dist/chunks/{LpSidebar-ClBUwoEz.js → LpSidebar-BgwUNWpJ.js} +30 -22
  53. package/dist/chunks/{LpSidebarNav-llOcs_Fn.js → LpSidebarNav-Bqxz8aWT.js} +14 -9
  54. package/dist/chunks/{LpSkeleton-CTI-vBgW.js → LpSkeleton-BB6XIV-w.js} +1 -1
  55. package/dist/chunks/{LpSlider-BwNIBkAK.js → LpSlider-Cuzmrd7p.js} +7 -2
  56. package/dist/chunks/{LpSparkline-C6xQ2dwv.js → LpSparkline-CB80N8SJ.js} +11 -4
  57. package/dist/chunks/{LpStat-CQaW8R--.js → LpStat-dXtyrdX9.js} +1 -1
  58. package/dist/chunks/{LpSwitch-Blizvqyt.js → LpSwitch-B1aLKulj.js} +40 -26
  59. package/dist/chunks/{LpTableOfContents-CjvxPMpU.js → LpTableOfContents-BUcAfGPQ.js} +36 -41
  60. package/dist/chunks/{LpTabs-Cefe_lys.js → LpTabs-_qMVaZJ6.js} +19 -5
  61. package/dist/chunks/LpTextarea-yP8hGedR.js +77 -0
  62. package/dist/chunks/LpThemeProvider-Wjm7Tuit.js +35 -0
  63. package/dist/chunks/LpThemeSwitcher-CKLc10KZ.js +169 -0
  64. package/dist/chunks/{LpTilt-DuyKbpkA.js → LpTilt-B7KHX1zH.js} +2 -2
  65. package/dist/chunks/{LpTimeField-K6nAGboX.js → LpTimeField-C5HRgS5H.js} +13 -7
  66. package/dist/chunks/{LpToaster-gDB1EaU3.js → LpToaster--oT6lfhL.js} +57 -28
  67. package/dist/chunks/{LpTooltip-hCLPAqMG.js → LpTooltip-CBdzeKNf.js} +13 -6
  68. package/dist/chunks/LpTooltipProvider-CftjV7Xc.js +25 -0
  69. package/dist/chunks/{LpTopologyCanvas-Cm1L39uL.js → LpTopologyCanvas-DocsLal3.js} +6 -1
  70. package/dist/chunks/{LpUptimeBar-DvAMno0S.js → LpUptimeBar-DLtxOMRy.js} +43 -14
  71. package/dist/chunks/{LpThemeSwitcher-Cue-myST.js → useTheme-C8JHUlPM.js} +173 -215
  72. package/dist/component-names.d.ts +1 -1
  73. package/dist/components/ContextMenuItems.vue.d.ts +8 -0
  74. package/dist/components/ContextMenuItems.vue.js +4 -0
  75. package/dist/components/LayoutCanvas.vue.js +1 -1
  76. package/dist/components/LayoutNode.vue.d.ts +4 -0
  77. package/dist/components/LayoutNode.vue.js +1 -1
  78. package/dist/components/LpActionBar.vue.d.ts +3 -0
  79. package/dist/components/LpActionBar.vue.js +1 -1
  80. package/dist/components/LpAddressInput.vue.d.ts +1 -1
  81. package/dist/components/LpAddressInput.vue.js +1 -1
  82. package/dist/components/LpAlert.vue.d.ts +9 -0
  83. package/dist/components/LpAlert.vue.js +1 -1
  84. package/dist/components/LpAppShell.vue.d.ts +10 -0
  85. package/dist/components/LpAppShell.vue.js +1 -1
  86. package/dist/components/LpAutocomplete.vue.d.ts +31 -6
  87. package/dist/components/LpAutocomplete.vue.js +1 -1
  88. package/dist/components/LpAvatar.vue.d.ts +3 -3
  89. package/dist/components/LpAvatar.vue.js +1 -1
  90. package/dist/components/LpBadge.vue.d.ts +2 -2
  91. package/dist/components/LpBreadcrumbs.vue.d.ts +13 -9
  92. package/dist/components/LpBreadcrumbs.vue.js +1 -1
  93. package/dist/components/LpButton.vue.d.ts +35 -98
  94. package/dist/components/LpButton.vue.js +1 -1
  95. package/dist/components/LpCard.vue.js +1 -1
  96. package/dist/components/LpChart.vue.d.ts +31 -2
  97. package/dist/components/LpChart.vue.js +317 -95
  98. package/dist/components/LpCheckbox.vue.js +1 -1
  99. package/dist/components/LpCodeBlock.vue.d.ts +2 -0
  100. package/dist/components/LpCodeBlock.vue.js +1 -1
  101. package/dist/components/LpColorPicker.vue.js +1 -1
  102. package/dist/components/LpCommandPalette.vue.d.ts +8 -3
  103. package/dist/components/LpCommandPalette.vue.js +86 -72
  104. package/dist/components/LpConfirmDialog.vue.d.ts +15 -3
  105. package/dist/components/LpConfirmDialog.vue.js +1 -1
  106. package/dist/components/LpConfirmHost.vue.d.ts +9 -0
  107. package/dist/components/LpConfirmHost.vue.js +4 -0
  108. package/dist/components/LpContextMenu.vue.d.ts +3 -5
  109. package/dist/components/LpContextMenu.vue.js +1 -1
  110. package/dist/components/LpDatePicker.vue.d.ts +24 -6
  111. package/dist/components/LpDatePicker.vue.js +1 -1
  112. package/dist/components/LpDrawer.vue.d.ts +10 -0
  113. package/dist/components/LpDrawer.vue.js +1 -1
  114. package/dist/components/LpDropzone.vue.js +22 -6
  115. package/dist/components/LpFileTree.vue.d.ts +11 -2
  116. package/dist/components/LpFileTree.vue.js +1 -1
  117. package/dist/components/LpFileTreeNode.vue.js +1 -1
  118. package/dist/components/LpFormField.vue.d.ts +9 -0
  119. package/dist/components/LpFormField.vue.js +1 -1
  120. package/dist/components/LpImageEditor.vue.js +92 -57
  121. package/dist/components/LpInput.vue.d.ts +3 -3
  122. package/dist/components/LpInput.vue.js +1 -1
  123. package/dist/components/LpLightbox.vue.d.ts +17 -0
  124. package/dist/components/LpLightbox.vue.js +1 -1
  125. package/dist/components/LpLink.vue.d.ts +11 -11
  126. package/dist/components/LpLink.vue.js +1 -1
  127. package/dist/components/LpLogViewer.vue.d.ts +20 -2
  128. package/dist/components/LpLogViewer.vue.js +1 -1
  129. package/dist/components/LpMapPicker.vue.d.ts +4 -4
  130. package/dist/components/LpMapPicker.vue.js +1 -1
  131. package/dist/components/LpMediaGallery.vue.js +1 -1
  132. package/dist/components/LpModal.vue.d.ts +16 -6
  133. package/dist/components/LpModal.vue.js +1 -1
  134. package/dist/components/LpModalNav.vue.d.ts +0 -1
  135. package/dist/components/LpModalNav.vue.js +1 -1
  136. package/dist/components/LpNotificationBell.vue.d.ts +11 -2
  137. package/dist/components/LpNotificationBell.vue.js +1 -1
  138. package/dist/components/LpNumberField.vue.d.ts +2 -0
  139. package/dist/components/LpNumberField.vue.js +1 -1
  140. package/dist/components/LpNumberFlow.vue.js +1 -1
  141. package/dist/components/LpOtpInput.vue.js +1 -1
  142. package/dist/components/LpPagination.vue.d.ts +2 -0
  143. package/dist/components/LpPagination.vue.js +1 -1
  144. package/dist/components/LpPasswordInput.vue.js +1 -1
  145. package/dist/components/LpPhoneInput.vue.js +1 -1
  146. package/dist/components/LpPie.vue.d.ts +21 -2
  147. package/dist/components/LpPie.vue.js +1 -1
  148. package/dist/components/LpPopover.vue.d.ts +2 -0
  149. package/dist/components/LpPopover.vue.js +1 -1
  150. package/dist/components/LpProgress.vue.js +1 -1
  151. package/dist/components/LpRadioGroup.vue.js +1 -1
  152. package/dist/components/LpSection.vue.d.ts +1 -1
  153. package/dist/components/LpSegmented.vue.d.ts +5 -0
  154. package/dist/components/LpSegmented.vue.js +1 -1
  155. package/dist/components/LpSelect.vue.d.ts +1 -0
  156. package/dist/components/LpSelect.vue.js +1 -1
  157. package/dist/components/LpShortcutsDialog.vue.d.ts +1 -1
  158. package/dist/components/LpShortcutsDialog.vue.js +11 -8
  159. package/dist/components/LpSidebar.vue.d.ts +6 -2
  160. package/dist/components/LpSidebar.vue.js +1 -1
  161. package/dist/components/LpSidebarNav.vue.js +1 -1
  162. package/dist/components/LpSkeleton.vue.js +1 -1
  163. package/dist/components/LpSlider.vue.js +1 -1
  164. package/dist/components/LpSparkline.vue.d.ts +1 -0
  165. package/dist/components/LpSparkline.vue.js +1 -1
  166. package/dist/components/LpStat.vue.js +1 -1
  167. package/dist/components/LpSwitch.vue.js +1 -1
  168. package/dist/components/LpTable.vue.d.ts +23 -1
  169. package/dist/components/LpTable.vue.js +74 -36
  170. package/dist/components/LpTableOfContents.vue.d.ts +4 -2
  171. package/dist/components/LpTableOfContents.vue.js +1 -1
  172. package/dist/components/LpTabs.vue.d.ts +2 -0
  173. package/dist/components/LpTabs.vue.js +1 -1
  174. package/dist/components/LpTextarea.vue.d.ts +19 -6
  175. package/dist/components/LpTextarea.vue.js +1 -1
  176. package/dist/components/LpThemeProvider.vue.d.ts +22 -0
  177. package/dist/components/LpThemeProvider.vue.js +4 -0
  178. package/dist/components/LpThemeSwitcher.vue.d.ts +13 -0
  179. package/dist/components/LpThemeSwitcher.vue.js +1 -1
  180. package/dist/components/LpTilt.vue.js +1 -1
  181. package/dist/components/LpTimeField.vue.js +1 -1
  182. package/dist/components/LpToaster.vue.d.ts +6 -1
  183. package/dist/components/LpToaster.vue.js +1 -1
  184. package/dist/components/LpTooltip.vue.d.ts +1 -2
  185. package/dist/components/LpTooltip.vue.js +1 -1
  186. package/dist/components/LpTooltipProvider.vue.d.ts +22 -0
  187. package/dist/components/LpTooltipProvider.vue.js +4 -0
  188. package/dist/components/LpTopologyCanvas.vue.js +1 -1
  189. package/dist/components/LpUptimeBar.vue.d.ts +4 -0
  190. package/dist/components/LpUptimeBar.vue.js +1 -1
  191. package/dist/components/chart.d.ts +32 -1
  192. package/dist/components/chart.js +39 -4
  193. package/dist/components/codeHighlight.d.ts +6 -0
  194. package/dist/components/codeHighlight.js +92 -20
  195. package/dist/components/color.d.ts +1 -1
  196. package/dist/components/color.js +20 -9
  197. package/dist/components/confirm.d.ts +25 -0
  198. package/dist/components/confirm.js +26 -0
  199. package/dist/components/countries.d.ts +6 -0
  200. package/dist/components/countries.js +7 -0
  201. package/dist/components/fileTree.js +16 -7
  202. package/dist/components/imageCrop.d.ts +42 -0
  203. package/dist/components/imageCrop.js +47 -0
  204. package/dist/components/link.d.ts +12 -0
  205. package/dist/components/link.js +19 -0
  206. package/dist/components/modalDepth.d.ts +18 -2
  207. package/dist/components/modalDepth.js +17 -5
  208. package/dist/components/otp.d.ts +5 -0
  209. package/dist/components/otp.js +10 -0
  210. package/dist/components/sidebar.d.ts +7 -1
  211. package/dist/components/tableSort.d.ts +8 -0
  212. package/dist/components/tableSort.js +31 -0
  213. package/dist/composables/useField.d.ts +34 -0
  214. package/dist/composables/useField.js +45 -0
  215. package/dist/composables/useFormDraft.d.ts +10 -3
  216. package/dist/composables/useFormDraft.js +9 -14
  217. package/dist/composables/useHotkeys.d.ts +17 -1
  218. package/dist/composables/useHotkeys.js +55 -18
  219. package/dist/composables/useInputFilter.d.ts +17 -0
  220. package/dist/composables/useInputFilter.js +47 -10
  221. package/dist/composables/useLpConfig.d.ts +24 -0
  222. package/dist/composables/useLpConfig.js +44 -0
  223. package/dist/composables/useRovingFocus.js +7 -0
  224. package/dist/composables/useTilt.d.ts +2 -2
  225. package/dist/composables/useTilt.js +5 -6
  226. package/dist/composables/useToast.d.ts +20 -0
  227. package/dist/composables/useToast.js +28 -4
  228. package/dist/composables/useZoomPan.d.ts +3 -3
  229. package/dist/composables/useZoomPan.js +4 -4
  230. package/dist/index.d.ts +32 -2
  231. package/dist/index.js +184 -137
  232. package/dist/layout/tree.d.ts +2 -0
  233. package/dist/layout/tree.js +16 -1
  234. package/dist/layout/useLayout.d.ts +15 -0
  235. package/dist/layout/useLayout.js +41 -14
  236. package/dist/theme/useTheme.d.ts +32 -9
  237. package/package.json +8 -7
  238. package/src/component-names.ts +5 -7
  239. package/src/components/ContextMenuItems.vue +88 -0
  240. package/src/components/LayoutCanvas.vue +26 -6
  241. package/src/components/LayoutNode.vue +19 -2
  242. package/src/components/LpActionBar.vue +30 -7
  243. package/src/components/LpAddressInput.vue +57 -41
  244. package/src/components/LpAlert.vue +16 -3
  245. package/src/components/LpAppShell.vue +45 -12
  246. package/src/components/LpAutocomplete.vue +46 -10
  247. package/src/components/LpAvatar.vue +19 -5
  248. package/src/components/LpBreadcrumbs.vue +65 -41
  249. package/src/components/LpButton.vue +59 -13
  250. package/src/components/LpChart.vue +272 -28
  251. package/src/components/LpCheckbox.vue +7 -3
  252. package/src/components/LpCodeBlock.vue +50 -14
  253. package/src/components/LpColorPicker.vue +39 -9
  254. package/src/components/LpCommandPalette.vue +34 -13
  255. package/src/components/LpConfirmDialog.vue +68 -17
  256. package/src/components/LpConfirmHost.vue +59 -0
  257. package/src/components/LpContextMenu.vue +14 -115
  258. package/src/components/LpDatePicker.vue +99 -68
  259. package/src/components/LpDrawer.vue +56 -19
  260. package/src/components/LpDropzone.vue +21 -4
  261. package/src/components/LpFileTree.vue +33 -7
  262. package/src/components/LpFormField.vue +30 -7
  263. package/src/components/LpImageEditor.vue +96 -57
  264. package/src/components/LpInput.vue +18 -7
  265. package/src/components/LpLightbox.vue +140 -29
  266. package/src/components/LpLink.vue +24 -13
  267. package/src/components/LpLogViewer.vue +86 -17
  268. package/src/components/LpMapPicker.vue +36 -13
  269. package/src/components/LpMediaGallery.vue +8 -2
  270. package/src/components/LpModal.vue +53 -27
  271. package/src/components/LpModalNav.vue +5 -2
  272. package/src/components/LpNotificationBell.vue +63 -17
  273. package/src/components/LpNumberField.vue +21 -6
  274. package/src/components/LpNumberFlow.vue +26 -10
  275. package/src/components/LpOtpInput.vue +43 -8
  276. package/src/components/LpPagination.vue +23 -7
  277. package/src/components/LpPasswordInput.vue +4 -1
  278. package/src/components/LpPhoneInput.vue +53 -27
  279. package/src/components/LpPie.vue +94 -15
  280. package/src/components/LpPopover.vue +3 -0
  281. package/src/components/LpProgress.vue +5 -3
  282. package/src/components/LpRadioGroup.vue +9 -2
  283. package/src/components/LpSegmented.vue +12 -2
  284. package/src/components/LpSelect.vue +0 -0
  285. package/src/components/LpShortcutsDialog.vue +8 -3
  286. package/src/components/LpSidebar.vue +14 -9
  287. package/src/components/LpSidebarNav.vue +17 -5
  288. package/src/components/LpSkeleton.vue +4 -1
  289. package/src/components/LpSlider.vue +7 -1
  290. package/src/components/LpSparkline.vue +11 -3
  291. package/src/components/LpSwitch.vue +30 -7
  292. package/src/components/LpTable.vue +91 -32
  293. package/src/components/LpTableOfContents.vue +50 -32
  294. package/src/components/LpTabs.vue +23 -6
  295. package/src/components/LpTextarea.vue +44 -6
  296. package/src/components/LpThemeProvider.vue +41 -0
  297. package/src/components/LpThemeSwitcher.vue +64 -17
  298. package/src/components/LpTilt.vue +2 -2
  299. package/src/components/LpTimeField.vue +14 -3
  300. package/src/components/LpToaster.vue +66 -26
  301. package/src/components/LpTooltip.vue +22 -5
  302. package/src/components/LpTooltipProvider.vue +24 -0
  303. package/src/components/LpTopologyCanvas.vue +12 -1
  304. package/src/components/LpUptimeBar.vue +46 -8
  305. package/src/components/chart.ts +77 -5
  306. package/src/components/codeHighlight.ts +111 -15
  307. package/src/components/color.ts +30 -9
  308. package/src/components/confirm.ts +58 -0
  309. package/src/components/countries.ts +12 -0
  310. package/src/components/fileTree.ts +19 -7
  311. package/src/components/imageCrop.ts +107 -0
  312. package/src/components/link.ts +34 -0
  313. package/src/components/modalDepth.ts +48 -6
  314. package/src/components/otp.ts +16 -0
  315. package/src/components/sidebar.ts +7 -1
  316. package/src/components/tableSort.ts +37 -0
  317. package/src/composables/useField.ts +79 -0
  318. package/src/composables/useFormDraft.ts +25 -20
  319. package/src/composables/useHotkeys.ts +89 -18
  320. package/src/composables/useInputFilter.ts +77 -14
  321. package/src/composables/useLpConfig.ts +87 -0
  322. package/src/composables/useRovingFocus.ts +11 -0
  323. package/src/composables/useTilt.ts +5 -6
  324. package/src/composables/useToast.ts +56 -4
  325. package/src/composables/useZoomPan.ts +6 -6
  326. package/src/index.ts +37 -2
  327. package/src/layout/tree.ts +30 -0
  328. package/src/layout/useLayout.ts +68 -18
  329. package/src/nuxt.ts +59 -17
  330. package/src/runtime/config.plugin.ts +14 -0
  331. package/src/runtime/theme.plugin.ts +42 -22
  332. package/src/theme/useTheme.ts +206 -100
  333. package/dist/chunks/LpBreadcrumbs-p4jHe_V-.js +0 -62
  334. package/dist/chunks/LpContextMenu-CwW1QXe_.js +0 -217
  335. package/dist/chunks/LpDatePicker-CwOToxGq.js +0 -164
  336. package/dist/chunks/LpFormField-CazBc2-a.js +0 -62
  337. package/dist/chunks/LpTextarea-t7F6gv8E.js +0 -47
package/README.md CHANGED
@@ -6,9 +6,15 @@ JSON token sets), and a composable block-layout canvas.
6
6
 
7
7
  ## Install
8
8
 
9
- The kit is consumed by the LeavePulse apps via a `file:`/git dependency. It needs
10
- the peer deps it declares (`vue`, `reka-ui`, `tailwindcss`, `tailwind-variants`,
11
- `tailwind-merge`, `motion-v`, `@iconify/vue`).
9
+ Published to the public npm registry:
10
+
11
+ ```bash
12
+ npm install @leavepulse/ui
13
+ ```
14
+
15
+ Peer dependencies to install alongside: `vue` 3.5+, `reka-ui` 2.9+, `tailwindcss` 4,
16
+ `tailwind-variants` 3, `motion-v` 2, `@iconify/vue` 5, `@iconify-json/lucide` and
17
+ `@internationalized/date`. `@nuxt/kit` is only needed for the Nuxt module.
12
18
 
13
19
  ## Usage
14
20
 
@@ -32,6 +38,65 @@ import { LpButton, LpModal } from "@leavepulse/ui"
32
38
  The kit does **not** ship a precompiled stylesheet — your Tailwind build emits the
33
39
  utilities its components use, scoped via the `@source` globs in the CSS entry.
34
40
 
41
+ Apps using the topology canvas (`LpTopologyCanvas`) also import its stylesheet:
42
+
43
+ ```css
44
+ @import "@leavepulse/ui/canvas.css";
45
+ ```
46
+
47
+ ### Theme before mount (plain Vue)
48
+
49
+ Themes are JSON token sets applied at runtime. Paint the saved one before the
50
+ app mounts, so the first frame already has the right colours:
51
+
52
+ ```ts
53
+ import { bootstrapTheme, leavepulse, useTheme } from "@leavepulse/ui"
54
+
55
+ bootstrapTheme(leavepulse)
56
+ createApp(App).mount("#app")
57
+
58
+ // later, from a switcher or settings page
59
+ useTheme().setTheme(nord)
60
+ useTheme().setSystem({ light, dark: leavepulse }) // follow the OS colour scheme
61
+ ```
62
+
63
+ `LpThemeProvider` applies a theme to one subtree only (a dark sidebar in a light
64
+ app, a live preview).
65
+
66
+ ### App-wide configuration
67
+
68
+ `provideLpConfig` (or `app.use(lpConfig({...}))`) sets the link component that
69
+ internal links render (`LpLink`, `LpButton` with `to`/`href`, `LpBreadcrumbs`,
70
+ `LpSidebar` items) and overrides the English text the kit renders, per scope:
71
+
72
+ ```ts
73
+ import { RouterLink } from "vue-router"
74
+ import { lpConfig } from "@leavepulse/ui"
75
+
76
+ app.use(lpConfig({
77
+ linkComponent: RouterLink,
78
+ labels: { sidebar: { search: "Suche" }, appShell: { openMenu: "Menü öffnen" } },
79
+ }))
80
+ ```
81
+
82
+ A component's own `labels` prop wins over the configuration.
83
+
84
+ ### Nuxt
85
+
86
+ ```ts
87
+ export default defineNuxtConfig({
88
+ modules: ["@leavepulse/ui/nuxt"],
89
+ leavepulseUi: {
90
+ defaultTheme: "Nord", // fallback when nothing is saved
91
+ themes: "~/themes", // optional: module whose default export is your TokenSet[]
92
+ },
93
+ })
94
+ ```
95
+
96
+ The module registers every exported component, paints the saved theme during
97
+ SSR (from the `lp-theme` cookie, no flash), and provides `NuxtLink` as the link
98
+ component. `theme: false`, `link: false` and `exclude: ["Name"]` opt out.
99
+
35
100
  ### Native scrollbar skin (opt-in)
36
101
 
37
102
  `LpScrollArea` skins the scroll it owns. For everything it can't — the page
@@ -51,11 +116,14 @@ Hide a specific scrollbar with the `lp-scrollbar-none` class.
51
116
  ## Develop
52
117
 
53
118
  ```bash
54
- bun install # also builds dist via the prepare hook
119
+ bun install
55
120
  bun run dev # live preview/playground on http://127.0.0.1:4500
56
- bun run build # type-check + build the library to dist/
121
+ bun test # unit tests
122
+ bun run build # type-check + build the library and declarations to dist/
123
+ npm run check:pack # the tarball has its declarations and every export target
57
124
  bun run dev:dist # rebuild dist on change (for a linked consumer)
58
125
  ```
59
126
 
60
- `dist/` is generated, not committed — the `prepare` hook rebuilds it on install so
61
- any consumer gets a fresh build.
127
+ `dist/` is generated, not committed. Releases: `npm run release` (or
128
+ `release:minor`) bumps the version and pushes the tag; CI tests, builds and
129
+ publishes it.
@@ -5,81 +5,81 @@
5
5
  * pane from its right edge as it grows. Animating the columns themselves made
6
6
  * every line of the list and the pane re-wrap on every frame.
7
7
  */
8
- .lp-cmd-dialog[data-v-89a89377] {
8
+ .lp-cmd-dialog[data-v-7fa6825e] {
9
9
  --lp-cmd-list: min(92vw, 40rem);
10
10
  --lp-cmd-pane: max(0px, min(26rem, 96vw - var(--lp-cmd-list)));
11
11
  width: var(--lp-cmd-list);
12
12
  }
13
- .lp-cmd-split[data-v-89a89377] {
13
+ .lp-cmd-split[data-v-7fa6825e] {
14
14
  transition:
15
15
  width 300ms var(--ease-emphasized, ease),
16
16
  min-height 300ms var(--ease-emphasized, ease);
17
17
  }
18
18
  @media (min-width: 768px) {
19
- .lp-cmd-split .lp-cmd-list[data-v-89a89377] {
19
+ .lp-cmd-split .lp-cmd-list[data-v-7fa6825e] {
20
20
  flex: 0 0 auto;
21
21
  /* the dialog's 1px border on each side */
22
22
  width: calc(var(--lp-cmd-list) - 2px);
23
23
  }
24
- .lp-cmd-dialog[data-pane="open"][data-v-89a89377] {
24
+ .lp-cmd-dialog[data-pane="open"][data-v-7fa6825e] {
25
25
  width: calc(var(--lp-cmd-list) + var(--lp-cmd-pane));
26
26
  min-height: min(76vh, 36rem);
27
27
  }
28
28
  }
29
- .lp-cmd-pane[data-v-89a89377] {
29
+ .lp-cmd-pane[data-v-7fa6825e] {
30
30
  width: var(--lp-cmd-pane);
31
31
  }
32
32
  /*
33
33
  * The pane rides in from the right edge while the dialog opens up to it, and
34
34
  * leaves the same way, for as long as the dialog takes to close over it.
35
35
  */
36
- .lp-cmd-pane-enter-active[data-v-89a89377],
37
- .lp-cmd-pane-leave-active[data-v-89a89377] {
36
+ .lp-cmd-pane-enter-active[data-v-7fa6825e],
37
+ .lp-cmd-pane-leave-active[data-v-7fa6825e] {
38
38
  transition:
39
39
  transform 300ms var(--ease-emphasized, ease),
40
40
  opacity 300ms ease;
41
41
  }
42
- .lp-cmd-pane-enter-from[data-v-89a89377],
43
- .lp-cmd-pane-leave-to[data-v-89a89377] {
42
+ .lp-cmd-pane-enter-from[data-v-7fa6825e],
43
+ .lp-cmd-pane-leave-to[data-v-7fa6825e] {
44
44
  opacity: 0;
45
45
  transform: translateX(40%);
46
46
  }
47
- .lp-cmd-para[data-v-89a89377] {
48
- animation: lp-cmd-para-in-89a89377 260ms ease-out both;
47
+ .lp-cmd-para[data-v-7fa6825e] {
48
+ animation: lp-cmd-para-in-7fa6825e 260ms ease-out both;
49
49
  }
50
- @keyframes lp-cmd-para-in-89a89377 {
50
+ @keyframes lp-cmd-para-in-7fa6825e {
51
51
  from {
52
52
  opacity: 0;
53
53
  transform: translateY(4px);
54
54
  }
55
55
  }
56
56
  @media (prefers-reduced-motion: reduce) {
57
- .lp-cmd-split[data-v-89a89377],
58
- .lp-cmd-pane-enter-active[data-v-89a89377],
59
- .lp-cmd-pane-leave-active[data-v-89a89377] {
57
+ .lp-cmd-split[data-v-7fa6825e],
58
+ .lp-cmd-pane-enter-active[data-v-7fa6825e],
59
+ .lp-cmd-pane-leave-active[data-v-7fa6825e] {
60
60
  transition: none;
61
61
  }
62
- .lp-cmd-para[data-v-89a89377] {
62
+ .lp-cmd-para[data-v-7fa6825e] {
63
63
  animation: none;
64
64
  }
65
65
  }
66
- .lp-cmd-excerpt[data-v-89a89377] {
66
+ .lp-cmd-excerpt[data-v-7fa6825e] {
67
67
  display: -webkit-box;
68
68
  -webkit-box-orient: vertical;
69
69
  overflow: hidden;
70
70
  }
71
71
  /* Each result eases in; honours reduced motion. */
72
- .lp-cmd-item[data-v-89a89377] {
73
- animation: lp-cmd-in-89a89377 140ms ease-out both;
72
+ .lp-cmd-item[data-v-7fa6825e] {
73
+ animation: lp-cmd-in-7fa6825e 140ms ease-out both;
74
74
  }
75
- @keyframes lp-cmd-in-89a89377 {
75
+ @keyframes lp-cmd-in-7fa6825e {
76
76
  from {
77
77
  opacity: 0;
78
78
  transform: translateY(3px);
79
79
  }
80
80
  }
81
81
  @media (prefers-reduced-motion: reduce) {
82
- .lp-cmd-item[data-v-89a89377] {
82
+ .lp-cmd-item[data-v-7fa6825e] {
83
83
  animation: none;
84
84
  }
85
85
  }
@@ -1,9 +1,9 @@
1
1
 
2
- .lp-dropzone__frame rect[data-v-5e560a6d] {
2
+ .lp-dropzone__frame rect[data-v-6f6d375e] {
3
3
  stroke: var(--color-line);
4
4
  transition: stroke var(--duration-fast) linear;
5
5
  }
6
- .lp-dropzone:hover .lp-dropzone__frame rect[data-v-5e560a6d] {
6
+ .lp-dropzone:hover .lp-dropzone__frame rect[data-v-6f6d375e] {
7
7
  stroke: var(--color-line-strong);
8
8
  }
9
9
 
@@ -12,33 +12,33 @@
12
12
  with every other thing on it; under a drag it is the answer to "can I let go
13
13
  here". One dash period per cycle, so the travel is continuous rather than
14
14
  jumping back at the seam. */
15
- .lp-dropzone--over .lp-dropzone__frame rect[data-v-5e560a6d] {
15
+ .lp-dropzone--over .lp-dropzone__frame rect[data-v-6f6d375e] {
16
16
  stroke: var(--color-brand);
17
- animation: lp-dropzone-ants-5e560a6d 500ms linear infinite;
17
+ animation: lp-dropzone-ants-6f6d375e 500ms linear infinite;
18
18
  }
19
- @keyframes lp-dropzone-ants-5e560a6d {
19
+ @keyframes lp-dropzone-ants-6f6d375e {
20
20
  to {
21
21
  stroke-dashoffset: -11;
22
22
  }
23
23
  }
24
24
 
25
25
  /* The dashes fade in and the block settles up a few pixels. */
26
- .lp-dropzone[data-v-5e560a6d] {
27
- animation: lp-dropzone-in-5e560a6d var(--duration-slow) var(--ease-settle) both;
26
+ .lp-dropzone[data-v-6f6d375e] {
27
+ animation: lp-dropzone-in-6f6d375e var(--duration-slow) var(--ease-settle) both;
28
28
  }
29
- .lp-dropzone--waiting[data-v-5e560a6d] {
29
+ .lp-dropzone--waiting[data-v-6f6d375e] {
30
30
  opacity: 0;
31
31
  animation: none;
32
32
  }
33
- @keyframes lp-dropzone-in-5e560a6d {
33
+ @keyframes lp-dropzone-in-6f6d375e {
34
34
  from {
35
35
  opacity: 0;
36
36
  transform: translateY(6px);
37
37
  }
38
38
  }
39
39
  @media (prefers-reduced-motion: reduce) {
40
- .lp-dropzone[data-v-5e560a6d],
41
- .lp-dropzone--waiting[data-v-5e560a6d] {
40
+ .lp-dropzone[data-v-6f6d375e],
41
+ .lp-dropzone--waiting[data-v-6f6d375e] {
42
42
  opacity: 1;
43
43
  transform: none;
44
44
  animation: none;
@@ -46,7 +46,7 @@ from {
46
46
 
47
47
  /* The ants stop, the colour stays: the brand stroke is what says "drop
48
48
  here", and it says it standing still. */
49
- .lp-dropzone--over .lp-dropzone__frame rect[data-v-5e560a6d] {
49
+ .lp-dropzone--over .lp-dropzone__frame rect[data-v-6f6d375e] {
50
50
  animation: none;
51
51
  }
52
52
  }
@@ -2,22 +2,22 @@
2
2
  /* The picture settles into the frame instead of appearing in it. Scale rather
3
3
  than a slide: the frame is the fixed thing here and the image lives inside
4
4
  it, so anything that moved would read as a crop that had shifted. */
5
- .lp-editor__image[data-v-a19a8cf6] {
6
- animation: lp-editor-in-a19a8cf6 var(--duration-slow) var(--ease-settle) both;
5
+ .lp-editor__image[data-v-b510205a] {
6
+ animation: lp-editor-in-b510205a var(--duration-slow) var(--ease-settle) both;
7
7
  }
8
- .lp-editor__image--waiting[data-v-a19a8cf6] {
8
+ .lp-editor__image--waiting[data-v-b510205a] {
9
9
  opacity: 0;
10
10
  animation: none;
11
11
  }
12
- @keyframes lp-editor-in-a19a8cf6 {
12
+ @keyframes lp-editor-in-b510205a {
13
13
  from {
14
14
  opacity: 0;
15
15
  scale: 1.04;
16
16
  }
17
17
  }
18
18
  @media (prefers-reduced-motion: reduce) {
19
- .lp-editor__image[data-v-a19a8cf6],
20
- .lp-editor__image--waiting[data-v-a19a8cf6] {
19
+ .lp-editor__image[data-v-b510205a],
20
+ .lp-editor__image--waiting[data-v-b510205a] {
21
21
  opacity: 1;
22
22
  scale: 1;
23
23
  animation: none;
@@ -1,12 +1,12 @@
1
1
 
2
2
  /* Two columns where there is room: the list is long enough that one column
3
3
  pushes the last group off a laptop screen. */
4
- .shortcut-groups[data-v-8af3bafc] {
4
+ .shortcut-groups[data-v-b7784bfc] {
5
5
  display: grid;
6
6
  gap: 18px;
7
7
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
8
8
  }
9
- .shortcut-group h3[data-v-8af3bafc] {
9
+ .shortcut-group h3[data-v-b7784bfc] {
10
10
  margin: 0 0 6px;
11
11
  color: var(--color-muted);
12
12
  font-size: 0.7rem;
@@ -14,31 +14,31 @@
14
14
  letter-spacing: 0.06em;
15
15
  text-transform: uppercase;
16
16
  }
17
- .shortcut-group dl[data-v-8af3bafc] {
17
+ .shortcut-group dl[data-v-b7784bfc] {
18
18
  display: flex;
19
19
  flex-direction: column;
20
20
  gap: 1px;
21
21
  margin: 0;
22
22
  }
23
- .shortcut-row[data-v-8af3bafc] {
23
+ .shortcut-row[data-v-b7784bfc] {
24
24
  display: flex;
25
25
  align-items: center;
26
26
  justify-content: space-between;
27
27
  gap: 12px;
28
28
  padding: 5px 0;
29
29
  }
30
- .shortcut-row dt[data-v-8af3bafc] {
30
+ .shortcut-row dt[data-v-b7784bfc] {
31
31
  color: var(--color-ink);
32
32
  font-size: 0.82rem;
33
33
  min-width: 0;
34
34
  }
35
- .shortcut-row dd[data-v-8af3bafc] {
35
+ .shortcut-row dd[data-v-b7784bfc] {
36
36
  display: flex;
37
37
  flex-shrink: 0;
38
38
  gap: 3px;
39
39
  margin: 0;
40
40
  }
41
- kbd[data-v-8af3bafc] {
41
+ kbd[data-v-b7784bfc] {
42
42
  display: inline-flex;
43
43
  min-width: 20px;
44
44
  align-items: center;
@@ -22,7 +22,10 @@
22
22
  }
23
23
  }
24
24
  @media (prefers-reduced-motion: reduce) {
25
- .lp-skeleton-item {
25
+ /* Repeats the descendant form: it outranks a bare class, and grouped items
26
+ kept pulsing under reduced motion. */
27
+ .lp-skeleton-item,
28
+ .lp-skeleton .lp-skeleton-item {
26
29
  animation: none;
27
30
  opacity: 0.75;
28
31
  }
@@ -11,17 +11,17 @@
11
11
  * fade before closing the gap and the whole list lurches at the end instead of
12
12
  * gliding.
13
13
  */
14
- .lp-row-enter-active[data-v-e0bb036b],
15
- .lp-row-leave-active[data-v-e0bb036b] {
14
+ .lp-row-enter-active[data-v-ebce6d15],
15
+ .lp-row-leave-active[data-v-ebce6d15] {
16
16
  transition:
17
17
  opacity var(--duration-fast) var(--ease-emphasized),
18
18
  transform var(--duration-fast) var(--ease-emphasized);
19
19
  }
20
- .lp-row-move[data-v-e0bb036b] {
20
+ .lp-row-move[data-v-ebce6d15] {
21
21
  transition: transform var(--duration-medium) var(--ease-emphasized);
22
22
  }
23
- .lp-row-enter-from[data-v-e0bb036b],
24
- .lp-row-leave-to[data-v-e0bb036b] {
23
+ .lp-row-enter-from[data-v-ebce6d15],
24
+ .lp-row-leave-to[data-v-ebce6d15] {
25
25
  opacity: 0;
26
26
  transform: translateX(-0.5rem);
27
27
  }
@@ -35,7 +35,7 @@
35
35
  * drops out of the table layout entirely. Nothing sits below this row to be
36
36
  * dragged around, so simply not animating its exit costs nothing.
37
37
  */
38
- .lp-row-empty.lp-row-leave-active[data-v-e0bb036b] {
38
+ .lp-row-empty.lp-row-leave-active[data-v-ebce6d15] {
39
39
  display: none;
40
40
  }
41
41
 
@@ -50,9 +50,9 @@
50
50
  /* A filter that redraws the list is information, not decoration: with motion
51
51
  turned down the rows change without animating rather than not changing. */
52
52
  @media (prefers-reduced-motion: reduce) {
53
- .lp-row-enter-active[data-v-e0bb036b],
54
- .lp-row-leave-active[data-v-e0bb036b],
55
- .lp-row-move[data-v-e0bb036b] {
53
+ .lp-row-enter-active[data-v-ebce6d15],
54
+ .lp-row-leave-active[data-v-ebce6d15],
55
+ .lp-row-move[data-v-ebce6d15] {
56
56
  transition: none;
57
57
  }
58
58
  }
@@ -0,0 +1,123 @@
1
+ import { defineComponent, resolveComponent, openBlock, createElementBlock, Fragment, renderList, createBlock, unref, createCommentVNode, withCtx, createVNode, normalizeClass, createElementVNode, createTextVNode, toDisplayString, withModifiers } from "vue";
2
+ import { ContextMenuSeparator, ContextMenuSub, ContextMenuSubTrigger, ContextMenuPortal, ContextMenuSubContent, ContextMenuCheckboxItem, ContextMenuItem } from "reka-ui";
3
+ import { _ as _sfc_main$1 } from "./LpIcon-CCnX5_2j.js";
4
+ const _hoisted_1 = { class: "flex items-center gap-2" };
5
+ const _hoisted_2 = { class: "flex items-center gap-2" };
6
+ const _hoisted_3 = {
7
+ key: 0,
8
+ class: "text-xs text-muted"
9
+ };
10
+ const _hoisted_4 = { class: "flex items-center gap-2" };
11
+ const _hoisted_5 = {
12
+ key: 0,
13
+ class: "text-xs text-muted"
14
+ };
15
+ const ITEM = "group/item flex cursor-pointer select-none items-center gap-2 rounded-md px-2.5 py-1.5 text-sm outline-none transition-[background-color,color] duration-[var(--duration-fast)] data-[disabled]:pointer-events-none data-[disabled]:opacity-45 data-[highlighted]:bg-brand-soft";
16
+ const ICON = "transition-transform duration-[var(--duration-fast)] ease-[var(--ease-emphasized)] group-data-[highlighted]/item:translate-x-0.5";
17
+ const _sfc_main = /* @__PURE__ */ defineComponent({
18
+ ...{ name: "ContextMenuItems" },
19
+ __name: "ContextMenuItems",
20
+ props: {
21
+ items: {},
22
+ panel: {}
23
+ },
24
+ setup(__props) {
25
+ return (_ctx, _cache) => {
26
+ const _component_ContextMenuItems = resolveComponent("ContextMenuItems", true);
27
+ return openBlock(true), createElementBlock(Fragment, null, renderList(__props.items, (item, i) => {
28
+ return openBlock(), createElementBlock(Fragment, { key: i }, [
29
+ item.separatorBefore ? (openBlock(), createBlock(unref(ContextMenuSeparator), {
30
+ key: 0,
31
+ class: "my-1 h-px bg-line"
32
+ })) : createCommentVNode("", true),
33
+ item.children?.length ? (openBlock(), createBlock(unref(ContextMenuSub), { key: 1 }, {
34
+ default: withCtx(() => [
35
+ createVNode(unref(ContextMenuSubTrigger), {
36
+ class: normalizeClass([ITEM, "justify-between text-ink data-[highlighted]:text-brand data-[state=open]:bg-brand-soft data-[state=open]:text-brand"]),
37
+ disabled: item.disabled
38
+ }, {
39
+ default: withCtx(() => [
40
+ createElementVNode("span", _hoisted_1, [
41
+ item.icon ? (openBlock(), createBlock(_sfc_main$1, {
42
+ key: 0,
43
+ name: item.icon,
44
+ size: 15,
45
+ class: normalizeClass(ICON)
46
+ }, null, 8, ["name"])) : createCommentVNode("", true),
47
+ createTextVNode(" " + toDisplayString(item.label), 1)
48
+ ]),
49
+ createVNode(_sfc_main$1, {
50
+ name: "lucide:chevron-right",
51
+ size: 14,
52
+ class: "text-muted"
53
+ })
54
+ ]),
55
+ _: 2
56
+ }, 1032, ["class", "disabled"]),
57
+ createVNode(unref(ContextMenuPortal), null, {
58
+ default: withCtx(() => [
59
+ createVNode(unref(ContextMenuSubContent), {
60
+ class: normalizeClass(__props.panel),
61
+ "side-offset": 2,
62
+ "align-offset": -4
63
+ }, {
64
+ default: withCtx(() => [
65
+ createVNode(_component_ContextMenuItems, {
66
+ items: item.children,
67
+ panel: __props.panel
68
+ }, null, 8, ["items", "panel"])
69
+ ]),
70
+ _: 2
71
+ }, 1032, ["class"])
72
+ ]),
73
+ _: 2
74
+ }, 1024)
75
+ ]),
76
+ _: 2
77
+ }, 1024)) : item.checked !== void 0 ? (openBlock(), createBlock(unref(ContextMenuCheckboxItem), {
78
+ key: 2,
79
+ "model-value": item.checked,
80
+ class: normalizeClass([ITEM, "justify-between text-ink data-[highlighted]:text-brand"]),
81
+ disabled: item.disabled,
82
+ onSelect: withModifiers(($event) => item.onSelect?.(), ["prevent"])
83
+ }, {
84
+ default: withCtx(() => [
85
+ createElementVNode("span", _hoisted_2, [
86
+ createVNode(_sfc_main$1, {
87
+ name: item.checked ? "lucide:check" : "lucide:minus",
88
+ size: 15,
89
+ class: normalizeClass([ICON, item.checked ? "" : "opacity-25"])
90
+ }, null, 8, ["name", "class"]),
91
+ createTextVNode(" " + toDisplayString(item.label), 1)
92
+ ]),
93
+ item.shortcut ? (openBlock(), createElementBlock("kbd", _hoisted_3, toDisplayString(item.shortcut), 1)) : createCommentVNode("", true)
94
+ ]),
95
+ _: 2
96
+ }, 1032, ["model-value", "class", "disabled", "onSelect"])) : (openBlock(), createBlock(unref(ContextMenuItem), {
97
+ key: 3,
98
+ class: normalizeClass([ITEM, "justify-between", item.danger ? "text-danger data-[highlighted]:bg-danger-soft data-[highlighted]:text-danger" : "text-ink data-[highlighted]:text-brand"]),
99
+ disabled: item.disabled,
100
+ onSelect: ($event) => item.onSelect?.()
101
+ }, {
102
+ default: withCtx(() => [
103
+ createElementVNode("span", _hoisted_4, [
104
+ item.icon ? (openBlock(), createBlock(_sfc_main$1, {
105
+ key: 0,
106
+ name: item.icon,
107
+ size: 15,
108
+ class: normalizeClass(ICON)
109
+ }, null, 8, ["name"])) : createCommentVNode("", true),
110
+ createTextVNode(" " + toDisplayString(item.label), 1)
111
+ ]),
112
+ item.shortcut ? (openBlock(), createElementBlock("kbd", _hoisted_5, toDisplayString(item.shortcut), 1)) : createCommentVNode("", true)
113
+ ]),
114
+ _: 2
115
+ }, 1032, ["class", "disabled", "onSelect"]))
116
+ ], 64);
117
+ }), 128);
118
+ };
119
+ }
120
+ });
121
+ export {
122
+ _sfc_main as _
123
+ };
@@ -1,6 +1,7 @@
1
- import { defineComponent, ref, openBlock, createElementBlock, createVNode, unref, withCtx, renderSlot, normalizeProps, guardReactiveProps } from "vue";
2
- import { _ as _sfc_main$1 } from "./LayoutNode-DGpZA9LX.js";
3
- import { reorderTab, removeBlock, setActiveTab, moveLeaf, resizeAt } from "../layout/tree.js";
1
+ import { defineComponent, ref, computed, openBlock, createElementBlock, createVNode, withCtx, renderSlot, normalizeProps, guardReactiveProps } from "vue";
2
+ import { _ as _sfc_main$1 } from "./LayoutNode-D8Xy9N-o.js";
3
+ import { resizeAt, setActiveTab, reorderTab, removeBlock, moveLeaf } from "../layout/tree.js";
4
+ import { layoutController } from "../layout/useLayout.js";
4
5
  const _hoisted_1 = { class: "flex min-h-0 min-w-0 flex-1" };
5
6
  const _sfc_main = /* @__PURE__ */ defineComponent({
6
7
  __name: "LayoutCanvas",
@@ -13,12 +14,26 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
13
14
  setup(__props) {
14
15
  const props = __props;
15
16
  const dragId = ref(null);
17
+ const edits = computed(() => {
18
+ const tree = props.modelValue;
19
+ return layoutController(tree) ?? {
20
+ move: (movingId, targetId, side) => moveLeaf(tree, movingId, targetId, side),
21
+ removeBlock: (leafId, index) => removeBlock(tree, leafId, index),
22
+ reorderTab: (leafId, from, to) => reorderTab(tree, leafId, from, to),
23
+ setActive: (leafId, index) => setActiveTab(tree, leafId, index),
24
+ resize: (parent, index, delta) => resizeAt(parent, index, delta),
25
+ beginResize: () => {
26
+ },
27
+ endResize: () => {
28
+ }
29
+ };
30
+ });
16
31
  function onDrop(targetId, side) {
17
- if (dragId.value) moveLeaf(props.modelValue, dragId.value, targetId, side);
32
+ if (dragId.value) edits.value.move(dragId.value, targetId, side);
18
33
  dragId.value = null;
19
34
  }
20
35
  function onResize(parent, index, delta) {
21
- resizeAt(parent, index, delta);
36
+ edits.value.resize(parent, index, delta);
22
37
  }
23
38
  return (_ctx, _cache) => {
24
39
  return openBlock(), createElementBlock("div", _hoisted_1, [
@@ -31,10 +46,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
31
46
  onDragstart: _cache[0] || (_cache[0] = (id) => dragId.value = id),
32
47
  onDragend: _cache[1] || (_cache[1] = ($event) => dragId.value = null),
33
48
  onDrop,
34
- onSetActive: _cache[2] || (_cache[2] = (leafId, i) => unref(setActiveTab)(__props.modelValue, leafId, i)),
35
- onRemoveBlock: _cache[3] || (_cache[3] = (leafId, i) => unref(removeBlock)(__props.modelValue, leafId, i)),
36
- onReorderTab: _cache[4] || (_cache[4] = (leafId, from, to) => unref(reorderTab)(__props.modelValue, leafId, from, to)),
37
- onResize
49
+ onSetActive: _cache[2] || (_cache[2] = (leafId, i) => edits.value.setActive(leafId, i)),
50
+ onRemoveBlock: _cache[3] || (_cache[3] = (leafId, i) => edits.value.removeBlock(leafId, i)),
51
+ onReorderTab: _cache[4] || (_cache[4] = (leafId, from, to) => edits.value.reorderTab(leafId, from, to)),
52
+ onResize,
53
+ onResizeStart: _cache[5] || (_cache[5] = ($event) => edits.value.beginResize()),
54
+ onResizeEnd: _cache[6] || (_cache[6] = ($event) => edits.value.endResize())
38
55
  }, {
39
56
  block: withCtx((slotProps) => [
40
57
  renderSlot(_ctx.$slots, "block", normalizeProps(guardReactiveProps(slotProps)))
@@ -1,4 +1,4 @@
1
- import { defineComponent, ref, computed, resolveComponent, openBlock, createElementBlock, normalizeClass, Fragment, renderList, createVNode, normalizeStyle, withCtx, renderSlot, mergeProps, createElementVNode, createCommentVNode, createBlock, unref, withModifiers, toDisplayString } from "vue";
1
+ import { defineComponent, ref, computed, onBeforeUnmount, resolveComponent, openBlock, createElementBlock, normalizeClass, Fragment, renderList, createVNode, normalizeStyle, withCtx, renderSlot, mergeProps, createElementVNode, createCommentVNode, createBlock, unref, withModifiers, toDisplayString } from "vue";
2
2
  import { Motion } from "motion-v";
3
3
  import { blockTitle } from "../layout/registry.js";
4
4
  import { _ as _sfc_main$1 } from "./LpIcon-CCnX5_2j.js";
@@ -20,7 +20,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
20
20
  edit: { type: Boolean },
21
21
  registry: {}
22
22
  },
23
- emits: ["dragstart", "dragend", "drop", "set-active", "remove-block", "reorder-tab", "resize"],
23
+ emits: ["dragstart", "dragend", "drop", "set-active", "remove-block", "reorder-tab", "resize", "resize-start", "resize-end"],
24
24
  setup(__props, { emit: __emit }) {
25
25
  const props = __props;
26
26
  const emit = __emit;
@@ -80,10 +80,15 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
80
80
  else if (py > 1 - edge) hoverSide.value = "bottom";
81
81
  else hoverSide.value = "center";
82
82
  }
83
+ let stopSplitter = null;
84
+ onBeforeUnmount(() => stopSplitter?.());
83
85
  function startSplitter(ev, parent, index) {
84
86
  ev.preventDefault();
85
- const host = ev.currentTarget.parentElement;
87
+ const handle = ev.currentTarget;
88
+ const host = handle.parentElement;
86
89
  if (!host) return;
90
+ handle.setPointerCapture?.(ev.pointerId);
91
+ emit("resize-start");
87
92
  const rect = host.getBoundingClientRect();
88
93
  const horizontal = parent.dir === "row";
89
94
  const span = horizontal ? rect.width : rect.height;
@@ -96,9 +101,14 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
96
101
  const up = () => {
97
102
  window.removeEventListener("pointermove", move);
98
103
  window.removeEventListener("pointerup", up);
104
+ window.removeEventListener("pointercancel", up);
105
+ stopSplitter = null;
106
+ emit("resize-end");
99
107
  };
108
+ stopSplitter = up;
100
109
  window.addEventListener("pointermove", move);
101
110
  window.addEventListener("pointerup", up);
111
+ window.addEventListener("pointercancel", up);
102
112
  }
103
113
  return (_ctx, _cache) => {
104
114
  const _component_LayoutNode = resolveComponent("LayoutNode", true);
@@ -122,7 +132,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
122
132
  onSetActive: _cache[3] || (_cache[3] = (l, idx) => emit("set-active", l, idx)),
123
133
  onRemoveBlock: _cache[4] || (_cache[4] = (l, idx) => emit("remove-block", l, idx)),
124
134
  onReorderTab: _cache[5] || (_cache[5] = (l, from, to) => emit("reorder-tab", l, from, to)),
125
- onResize: _cache[6] || (_cache[6] = (p, idx, d) => emit("resize", p, idx, d))
135
+ onResize: _cache[6] || (_cache[6] = (p, idx, d) => emit("resize", p, idx, d)),
136
+ onResizeStart: _cache[7] || (_cache[7] = ($event) => emit("resize-start")),
137
+ onResizeEnd: _cache[8] || (_cache[8] = ($event) => emit("resize-end"))
126
138
  }, {
127
139
  block: withCtx((slotProps) => [
128
140
  renderSlot(_ctx.$slots, "block", mergeProps({ ref_for: true }, slotProps))
@@ -151,8 +163,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
151
163
  key: 0,
152
164
  class: "flex shrink-0 items-center gap-1 overflow-x-auto border-b border-line px-1 py-1",
153
165
  draggable: __props.edit,
154
- onDragstart: _cache[7] || (_cache[7] = ($event) => emit("dragstart", __props.node.id)),
155
- onDragend: _cache[8] || (_cache[8] = ($event) => (hoverSide.value = null, emit("dragend")))
166
+ onDragstart: _cache[9] || (_cache[9] = ($event) => emit("dragstart", __props.node.id)),
167
+ onDragend: _cache[10] || (_cache[10] = ($event) => (hoverSide.value = null, emit("dragend")))
156
168
  }, [
157
169
  (openBlock(true), createElementBlock(Fragment, null, renderList(leaf.value.blocks, (block, i) => {
158
170
  return openBlock(), createElementBlock("button", {
@@ -202,8 +214,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
202
214
  key: 1,
203
215
  class: "absolute inset-0 z-[5]",
204
216
  onDragover: onDragOver,
205
- onDragleave: _cache[9] || (_cache[9] = ($event) => hoverSide.value = null),
206
- onDrop: _cache[10] || (_cache[10] = () => {
217
+ onDragleave: _cache[11] || (_cache[11] = ($event) => hoverSide.value = null),
218
+ onDrop: _cache[12] || (_cache[12] = () => {
207
219
  const s = hoverSide.value;
208
220
  hoverSide.value = null;
209
221
  if (s) emit("drop", __props.node.id, s);