@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
@@ -7,6 +7,7 @@
7
7
  import { computed, readonly, shallowRef, type ComputedRef, type DeepReadonly, type Ref } from "vue"
8
8
  import { easingToken, prefersReducedMotion } from "../composables/easing"
9
9
  import { detectBackdropFilter } from "./backdrop"
10
+ import { dark as darkPreset, light as lightPreset } from "./presets"
10
11
  import {
11
12
  COLOR_VARS,
12
13
  DEFAULT_SURFACE,
@@ -24,57 +25,134 @@ import {
24
25
 
25
26
  const CACHE_KEY = "leavepulse-ui-theme"
26
27
 
28
+ /** A light/dark pair followed by the operating system's colour scheme. */
29
+ export interface SystemThemes {
30
+ light: TokenSet
31
+ dark: TokenSet
32
+ }
33
+
34
+ type Cached = { theme: TokenSet; system?: undefined } | { system: SystemThemes; theme?: undefined }
35
+
27
36
  // ── self-managed theme state (singleton) ─────────────────────────────────
28
- // The kit owns the active theme — like an i18n locale — so every consumer
29
- // shares one source of truth instead of each wiring its own ref + bootstrap.
30
- // Module-level (created once per app), reactive, and lazily hydrated from the
31
- // cache on the client. SSR-safe: hydration only touches localStorage in a
32
- // browser; on the server `current` stays null until the client mounts.
37
+ // The kit owns the active theme, like an i18n locale, so every consumer shares
38
+ // one source of truth. Lazily hydrated from the cache on the client; on the
39
+ // server `current` stays null.
33
40
  const _current = shallowRef<TokenSet | null>(null)
41
+ const _system = shallowRef<SystemThemes | null>(null)
34
42
  let _hydrated = false
35
-
36
- // The fallback used when nothing is cached yet. Consumers can override it via
37
- // initTheme(fallback); defaults to whatever the first apply() sets.
38
43
  let _fallback: TokenSet | null = null
39
44
 
40
- function hydrateOnce(): void {
41
- if (_hydrated || typeof window === "undefined") return
42
- _hydrated = true
45
+ const DARK_QUERY = "(prefers-color-scheme: dark)"
46
+ let _media: MediaQueryList | null = null
47
+
48
+ /** Whether the OS asks for dark. True where it cannot be asked (server, old engines). */
49
+ export function prefersDarkScheme(): boolean {
50
+ if (typeof window === "undefined" || typeof window.matchMedia !== "function") return true
51
+ return window.matchMedia(DARK_QUERY).matches || !window.matchMedia("(prefers-color-scheme: light)").matches
52
+ }
53
+
54
+ function pick(system: SystemThemes, dark = prefersDarkScheme()): TokenSet {
55
+ return dark ? system.dark : system.light
56
+ }
57
+
58
+ function onSchemeChange(event: MediaQueryListEvent): void {
59
+ const system = _system.value
60
+ if (!system) return
61
+ const theme = pick(system, event.matches)
62
+ applyTheme(theme)
63
+ _current.value = theme
64
+ }
65
+
66
+ function followSystem(system: SystemThemes | null): void {
67
+ _system.value = system
68
+ if (typeof window === "undefined" || typeof window.matchMedia !== "function") return
69
+ if (system && !_media) {
70
+ _media = window.matchMedia(DARK_QUERY)
71
+ _media.addEventListener("change", onSchemeChange)
72
+ } else if (!system && _media) {
73
+ _media.removeEventListener("change", onSchemeChange)
74
+ _media = null
75
+ }
76
+ }
77
+
78
+ function readCache(): Cached | null {
43
79
  try {
44
80
  const cached = localStorage.getItem(CACHE_KEY)
45
- if (cached) {
46
- _current.value = parseTheme(cached)
47
- applyTheme(_current.value)
48
- return
81
+ if (!cached) return null
82
+ const raw = JSON.parse(cached) as { system?: { light?: unknown; dark?: unknown } }
83
+ if (raw && typeof raw === "object" && raw.system) {
84
+ return {
85
+ system: {
86
+ light: parseTheme(JSON.stringify(raw.system.light)),
87
+ dark: parseTheme(JSON.stringify(raw.system.dark)),
88
+ },
89
+ }
49
90
  }
91
+ return { theme: parseTheme(cached) }
50
92
  } catch {
51
- /* ignore — fall through to fallback */
93
+ return null
52
94
  }
53
- if (_fallback) {
95
+ }
96
+
97
+ function hydrateOnce(): void {
98
+ if (_hydrated || typeof window === "undefined") return
99
+ _hydrated = true
100
+ const cached = readCache()
101
+ if (cached?.system) {
102
+ followSystem(cached.system)
103
+ _current.value = pick(cached.system)
104
+ writeThemeCookie(systemCookieValue(cached.system))
105
+ } else if (cached?.theme) {
106
+ _current.value = cached.theme
107
+ writeThemeCookie(cached.theme.name)
108
+ } else if (_fallback) {
54
109
  _current.value = _fallback
55
- applyTheme(_fallback)
110
+ } else {
111
+ return
56
112
  }
113
+ applyTheme(_current.value)
57
114
  }
58
115
 
59
- export function applyTheme(theme: TokenSet, root: HTMLElement = document.documentElement): void {
116
+ /*
117
+ * Tokens defined in terms of other tokens. A custom property holding `var()` is
118
+ * resolved where it is declared, so the stylesheet's `:root` copies only ever
119
+ * see the root theme. Re-declaring them next to a theme makes a theme applied
120
+ * to a subtree (applyTheme(theme, el), themeToCssRule(theme, ".x")) carry them.
121
+ */
122
+ const DERIVED_VARS: readonly (readonly [string, string])[] = [
123
+ ["--color-surface-overlay", "color-mix(in srgb, var(--color-surface-raised) 94%, transparent)"],
124
+ ["--color-node-compute", "var(--color-action)"],
125
+ ["--color-node-transit", "var(--color-accent)"],
126
+ ["--color-node-edge", "var(--color-brand)"],
127
+ ["--color-node-unknown", "var(--color-line-strong)"],
128
+ ]
129
+
130
+ /** Every CSS variable a theme sets, in application order. */
131
+ export function themeEntries(input: TokenSet): [string, string][] {
132
+ const theme = normalizeTheme(input)
133
+ const out: [string, string][] = []
60
134
  for (const [key, cssVar] of Object.entries(COLOR_VARS)) {
61
- root.style.setProperty(cssVar, theme.colors[key as keyof ColorTokens])
135
+ out.push([cssVar, theme.colors[key as keyof ColorTokens]])
62
136
  }
63
137
  for (const [key, cssVar] of Object.entries(SHAPE_VARS)) {
64
- root.style.setProperty(cssVar, `${theme.shape[key as keyof ShapeTokens]}px`)
138
+ out.push([cssVar, `${theme.shape[key as keyof ShapeTokens]}px`])
65
139
  }
66
140
  for (const [key, cssVar] of Object.entries(DENSITY_VARS)) {
67
- root.style.setProperty(cssVar, `${theme.density[key as keyof DensityTokens]}px`)
141
+ out.push([cssVar, `${theme.density[key as keyof DensityTokens]}px`])
68
142
  }
69
143
  for (const [key, cssVar] of Object.entries(FONT_VARS)) {
70
- root.style.setProperty(cssVar, theme.font[key as keyof FontTokens])
144
+ out.push([cssVar, theme.font[key as keyof FontTokens]])
71
145
  }
72
- // Skin axis is optional; fall back to a flat default so themes saved before
73
- // it existed still paint correctly.
74
146
  const surface = theme.surface ?? DEFAULT_SURFACE
75
147
  for (const [key, cssVar] of Object.entries(SURFACE_VARS)) {
76
- root.style.setProperty(cssVar, surface[key as keyof SurfaceTokens])
148
+ out.push([cssVar, surface[key as keyof SurfaceTokens]])
77
149
  }
150
+ for (const [cssVar, value] of DERIVED_VARS) out.push([cssVar, value])
151
+ return out
152
+ }
153
+
154
+ export function applyTheme(theme: TokenSet, root: HTMLElement = document.documentElement): void {
155
+ for (const [cssVar, value] of themeEntries(theme)) root.style.setProperty(cssVar, value)
78
156
  root.dataset.themeMode = theme.mode
79
157
  root.style.colorScheme = theme.mode
80
158
  // Engine capability, not theme data — but this is the one path every consumer
@@ -157,24 +235,9 @@ export function serializeTheme(theme: TokenSet): string {
157
235
  * applyTheme — no duplicated values, the TokenSet stays the single source.
158
236
  */
159
237
  export function themeToCssVars(theme: TokenSet): string {
160
- const decls: string[] = []
161
- for (const [key, cssVar] of Object.entries(COLOR_VARS)) {
162
- decls.push(`${cssVar}: ${theme.colors[key as keyof ColorTokens]}`)
163
- }
164
- for (const [key, cssVar] of Object.entries(SHAPE_VARS)) {
165
- decls.push(`${cssVar}: ${theme.shape[key as keyof ShapeTokens]}px`)
166
- }
167
- for (const [key, cssVar] of Object.entries(DENSITY_VARS)) {
168
- decls.push(`${cssVar}: ${theme.density[key as keyof DensityTokens]}px`)
169
- }
170
- for (const [key, cssVar] of Object.entries(FONT_VARS)) {
171
- decls.push(`${cssVar}: ${theme.font[key as keyof FontTokens]}`)
172
- }
173
- const surface = theme.surface ?? DEFAULT_SURFACE
174
- for (const [key, cssVar] of Object.entries(SURFACE_VARS)) {
175
- decls.push(`${cssVar}: ${surface[key as keyof SurfaceTokens]}`)
176
- }
177
- return decls.join("; ")
238
+ return themeEntries(theme)
239
+ .map(([cssVar, value]) => `${cssVar}: ${value}`)
240
+ .join("; ")
178
241
  }
179
242
 
180
243
  /** Render a theme as a complete CSS rule (default selector `:root`). */
@@ -182,33 +245,43 @@ export function themeToCssRule(theme: TokenSet, selector = ":root"): string {
182
245
  return `${selector} { color-scheme: ${theme.mode}; ${themeToCssVars(theme)}; }`
183
246
  }
184
247
 
185
- const DEFAULT_FONT = {
186
- sans: '"Inter", "Segoe UI", system-ui, sans-serif',
187
- mono: '"JetBrains Mono", "SF Mono", ui-monospace, monospace',
248
+ /*
249
+ * Fill every axis a theme leaves out from the built-in preset of the same mode.
250
+ * Themes are stored by consumers and live longer than a kit version: a theme
251
+ * saved before a token existed would otherwise write `undefined` into that
252
+ * variable and blank out every utility that reads it.
253
+ */
254
+ export function normalizeTheme(raw: Partial<TokenSet> & { name?: string }): TokenSet {
255
+ const mode = raw.mode === "light" ? "light" : "dark"
256
+ const base = mode === "light" ? lightPreset : darkPreset
257
+ return {
258
+ name: typeof raw.name === "string" ? raw.name : base.name,
259
+ mode,
260
+ colors: { ...base.colors, ...raw.colors },
261
+ shape: { ...base.shape, ...raw.shape },
262
+ density: { ...base.density, ...raw.density },
263
+ font: { ...base.font, ...raw.font },
264
+ surface: raw.surface ? { ...DEFAULT_SURFACE, ...raw.surface } : undefined,
265
+ }
188
266
  }
189
267
 
190
- /** Parse + shallow-validate a theme JSON; throws on a malformed shape. */
268
+ /** Parse + validate a theme JSON; throws on a malformed shape. */
191
269
  export function parseTheme(json: string): TokenSet {
192
270
  const raw = JSON.parse(json) as Partial<TokenSet>
193
271
  if (!raw || typeof raw !== "object" || !raw.colors || !raw.shape || !raw.density) {
194
272
  throw new Error("Invalid theme: missing colors/shape/density")
195
273
  }
196
- // font is a newer axis — fill it in for configs saved before it existed.
197
- return { ...raw, font: raw.font ?? DEFAULT_FONT } as TokenSet
274
+ return normalizeTheme(raw)
198
275
  }
199
276
 
200
277
  // ── anti-flash bootstrap ─────────────────────────────────────
201
278
  // Call once before mount with your default theme; paints the cached theme (if
202
279
  // any) synchronously so the first frame already matches the saved look.
203
280
  export function bootstrapTheme(fallback: TokenSet): TokenSet {
204
- let theme = fallback
205
- try {
206
- const cached = localStorage.getItem(CACHE_KEY)
207
- if (cached) theme = parseTheme(cached)
208
- } catch {
209
- /* ignore, use fallback */
210
- }
211
- applyTheme(theme)
281
+ const cached = typeof window === "undefined" ? null : readCache()
282
+ const theme = cached?.system ? pick(cached.system) : (cached?.theme ?? fallback)
283
+ if (cached?.system) followSystem(cached.system)
284
+ if (typeof document !== "undefined") applyTheme(theme)
212
285
  return theme
213
286
  }
214
287
 
@@ -216,62 +289,97 @@ export function cacheTheme(theme: TokenSet): void {
216
289
  try {
217
290
  localStorage.setItem(CACHE_KEY, serializeTheme(theme))
218
291
  } catch {
219
- /* storage unavailable — non-fatal */
292
+ /* storage unavailable, non-fatal */
220
293
  }
221
294
  writeThemeCookie(theme.name)
222
295
  }
223
296
 
297
+ /** Persist "follow the OS" with the pair it switches between. */
298
+ export function cacheSystemThemes(system: SystemThemes): void {
299
+ try {
300
+ localStorage.setItem(CACHE_KEY, JSON.stringify({ system }))
301
+ } catch {
302
+ /* storage unavailable, non-fatal */
303
+ }
304
+ writeThemeCookie(systemCookieValue(system))
305
+ }
306
+
224
307
  /*
225
- * SSR handoff. localStorage is invisible to the server, so an SSR app would
226
- * render the default theme and only repaint after hydration — a visible flash on
227
- * every reload. The cookie rides along with the request, letting the server
228
- * inline the user's real theme in the first frame (see themeFromCookie).
229
- *
230
- * Only the NAME is stored: a full TokenSet is ~1KB of JSON that would be sent on
231
- * every request. The server resolves the name against the themes it knows, and
232
- * localStorage stays the client's source of truth for the full token values.
308
+ * SSR handoff. localStorage is invisible to the server, so the theme NAME rides
309
+ * along in a cookie and the server resolves it against the themes it knows
310
+ * (see themeFromCookie). "Follow the OS" is stored as `system:<light>|<dark>`.
233
311
  */
234
312
  export const THEME_COOKIE = "lp-theme"
313
+ const SYSTEM_PREFIX = "system:"
235
314
 
236
315
  const COOKIE_MAX_AGE = 60 * 60 * 24 * 365
237
316
 
238
- function writeThemeCookie(name: string): void {
317
+ function systemCookieValue(system: SystemThemes): string {
318
+ return `${SYSTEM_PREFIX}${system.light.name}|${system.dark.name}`
319
+ }
320
+
321
+ function writeThemeCookie(value: string): void {
239
322
  if (typeof document === "undefined") return
240
- // lax: the theme must survive a top-level navigation (which is what SSR
241
- // renders) without riding cross-site subrequests.
242
323
  document.cookie =
243
- `${THEME_COOKIE}=${encodeURIComponent(name)}` +
324
+ `${THEME_COOKIE}=${encodeURIComponent(value)}` +
244
325
  `; path=/; max-age=${COOKIE_MAX_AGE}; samesite=lax`
245
326
  }
246
327
 
328
+ function safeDecode(value: string): string {
329
+ try {
330
+ return decodeURIComponent(value)
331
+ } catch {
332
+ return value
333
+ }
334
+ }
335
+
247
336
  /**
248
337
  * Resolve a theme name (as read from the `lp-theme` cookie) against a set of
249
338
  * known themes. Returns `null` when the name is absent or unknown, so the caller
250
339
  * can fall back to its own default.
251
340
  *
252
- * Server-side counterpart to `cacheTheme`: pair it with `themeToCssRule` to
253
- * inline the right variables into `<head>` during SSR.
341
+ * Accepts both a raw and an already-decoded value: frameworks differ on whether
342
+ * their cookie helpers decode, and a name containing `%` must not throw.
343
+ * A "follow the OS" cookie resolves to its dark member unless `prefersDark` is
344
+ * false (pass it from the `Sec-CH-Prefers-Color-Scheme` request header).
254
345
  */
255
346
  export function themeFromCookie(
256
347
  cookieValue: string | null | undefined,
257
348
  themes: readonly TokenSet[],
349
+ options: { prefersDark?: boolean } = {},
258
350
  ): TokenSet | null {
259
351
  if (!cookieValue) return null
260
- const name = decodeURIComponent(cookieValue)
261
- return themes.find((theme) => theme.name === name) ?? null
352
+ const find = (name: string) => themes.find((theme) => theme.name === name) ?? null
353
+ for (const value of [cookieValue, safeDecode(cookieValue)]) {
354
+ if (value.startsWith(SYSTEM_PREFIX)) {
355
+ const [lightName = "", darkName = ""] = value.slice(SYSTEM_PREFIX.length).split("|")
356
+ const wanted = options.prefersDark === false ? lightName : darkName
357
+ const found = find(wanted)
358
+ if (found) return found
359
+ continue
360
+ }
361
+ const found = find(value)
362
+ if (found) return found
363
+ }
364
+ return null
262
365
  }
263
366
 
264
367
  export interface UseTheme {
265
368
  /** The active theme, kept in sync by the kit. Null until hydrated (SSR/first
266
- * paint) — reactive, so a switcher binds straight to it. */
369
+ * paint), reactive, so a switcher binds straight to it. */
267
370
  current: DeepReadonly<Ref<TokenSet | null>>
268
371
  /** The active theme's name (""="not yet hydrated"). */
269
372
  currentName: ComputedRef<string>
270
- /** Set + persist a theme (with the circular reveal if `origin`/transition).
271
- * This is the one call a switcher needs — it updates `current` too. */
373
+ /** True while the theme follows the OS colour scheme (see setSystem). */
374
+ system: ComputedRef<boolean>
375
+ /** Set + persist a theme (with the circular reveal). Stops following the OS. */
272
376
  setTheme: (theme: TokenSet, origin?: RevealOrigin) => void
273
- /** Seed the fallback (used when nothing is cached) and hydrate now. Call once
274
- * at app start (client) — optional; the first useTheme() hydrates anyway. */
377
+ /**
378
+ * Follow the OS colour scheme, switching between `themes.light` and
379
+ * `themes.dark` as it changes. Persisted like any other choice.
380
+ */
381
+ setSystem: (themes: SystemThemes, origin?: RevealOrigin) => void
382
+ /** Seed the fallback (used when nothing is cached) and hydrate now. */
275
383
  init: (fallback: TokenSet) => TokenSet
276
384
  apply: (theme: TokenSet) => void
277
385
  applyWithTransition: (theme: TokenSet, origin?: RevealOrigin) => void
@@ -281,14 +389,10 @@ export interface UseTheme {
281
389
  }
282
390
 
283
391
  export function useTheme(): UseTheme {
284
- // Lazily hydrate the singleton the first time anyone asks (client only).
285
392
  hydrateOnce()
286
393
 
287
- // The single "set a theme" path the kit owns: apply, cache, and update the
288
- // shared reactive state so every consumer + switcher reflects it.
289
- const setTheme = (theme: TokenSet, origin?: RevealOrigin) => {
290
- if (origin) applyThemeWithTransition(theme, origin)
291
- else applyThemeWithTransition(theme)
394
+ const commit = (theme: TokenSet) => {
395
+ followSystem(null)
292
396
  cacheTheme(theme)
293
397
  _current.value = theme
294
398
  }
@@ -296,29 +400,31 @@ export function useTheme(): UseTheme {
296
400
  return {
297
401
  current: readonly(_current),
298
402
  currentName: computed(() => _current.value?.name ?? ""),
299
- setTheme,
403
+ system: computed(() => _system.value !== null),
404
+ setTheme: (theme, origin) => {
405
+ applyThemeWithTransition(theme, origin)
406
+ commit(theme)
407
+ },
408
+ setSystem: (themes, origin) => {
409
+ const theme = pick(themes)
410
+ applyThemeWithTransition(theme, origin)
411
+ followSystem(themes)
412
+ cacheSystemThemes(themes)
413
+ _current.value = theme
414
+ },
300
415
  init: (fallback: TokenSet) => {
301
416
  _fallback = fallback
302
- if (!_hydrated) hydrateOnce()
303
- if (!_current.value) {
304
- _current.value = bootstrapTheme(fallback)
305
- }
417
+ hydrateOnce()
418
+ if (!_current.value) _current.value = bootstrapTheme(fallback)
306
419
  return _current.value
307
420
  },
308
421
  apply: (theme: TokenSet) => {
309
422
  applyTheme(theme)
310
- cacheTheme(theme)
311
- _current.value = theme
423
+ commit(theme)
312
424
  },
313
- /**
314
- * Apply + cache a theme with the circular reveal animation. Pass the click
315
- * point (e.g. from a toggle's `event`) as `origin` so the circle grows from
316
- * the button; omit it to reveal from the viewport centre.
317
- */
318
425
  applyWithTransition: (theme: TokenSet, origin?: RevealOrigin) => {
319
426
  applyThemeWithTransition(theme, origin)
320
- cacheTheme(theme)
321
- _current.value = theme
427
+ commit(theme)
322
428
  },
323
429
  serialize: serializeTheme,
324
430
  parse: parseTheme,
@@ -1,62 +0,0 @@
1
- import { defineComponent, openBlock, createElementBlock, mergeProps, unref, Fragment, renderList, createBlock, createCommentVNode, resolveDynamicComponent, withCtx, createTextVNode, toDisplayString, normalizeClass } from "vue";
2
- import { _ as _sfc_main$1 } from "./LpIcon-CCnX5_2j.js";
3
- import { useMergedAttrs } from "../composables/useMergedClass.js";
4
- const __default__ = { inheritAttrs: false };
5
- const _sfc_main = /* @__PURE__ */ defineComponent({
6
- ...__default__,
7
- __name: "LpBreadcrumbs",
8
- props: {
9
- items: {},
10
- as: { default: "a" }
11
- },
12
- emits: ["navigate"],
13
- setup(__props) {
14
- const { class: rootClass, attrs: rest } = useMergedAttrs(
15
- "flex items-center gap-1.5 text-sm"
16
- );
17
- return (_ctx, _cache) => {
18
- return openBlock(), createElementBlock("nav", mergeProps({ class: unref(rootClass) }, unref(rest), { "aria-label": "Breadcrumb" }), [
19
- (openBlock(true), createElementBlock(Fragment, null, renderList(__props.items, (item, i) => {
20
- return openBlock(), createElementBlock(Fragment, { key: i }, [
21
- i > 0 ? (openBlock(), createBlock(_sfc_main$1, {
22
- key: 0,
23
- name: "lucide:chevron-right",
24
- size: 14,
25
- class: "text-muted"
26
- })) : createCommentVNode("", true),
27
- (item.href || item.to) && i < __props.items.length - 1 ? (openBlock(), createBlock(resolveDynamicComponent(__props.as), {
28
- key: 1,
29
- href: __props.as === "a" ? item.href : void 0,
30
- to: __props.as === "a" ? void 0 : item.to,
31
- class: "inline-flex items-center gap-1.5 rounded-xs text-muted outline-none transition-colors duration-[var(--duration-fast)] hover:text-ink focus-visible:ring-2 focus-visible:ring-ring",
32
- onClick: ($event) => _ctx.$emit("navigate", item, i)
33
- }, {
34
- default: withCtx(() => [
35
- item.icon ? (openBlock(), createBlock(_sfc_main$1, {
36
- key: 0,
37
- name: item.icon,
38
- size: 14
39
- }, null, 8, ["name"])) : createCommentVNode("", true),
40
- createTextVNode(" " + toDisplayString(item.label), 1)
41
- ]),
42
- _: 2
43
- }, 1032, ["href", "to", "onClick"])) : (openBlock(), createElementBlock("span", {
44
- key: 2,
45
- class: normalizeClass(["inline-flex items-center gap-1.5", i === __props.items.length - 1 ? "text-ink" : "text-muted"])
46
- }, [
47
- item.icon ? (openBlock(), createBlock(_sfc_main$1, {
48
- key: 0,
49
- name: item.icon,
50
- size: 14
51
- }, null, 8, ["name"])) : createCommentVNode("", true),
52
- createTextVNode(" " + toDisplayString(item.label), 1)
53
- ], 2))
54
- ], 64);
55
- }), 128))
56
- ], 16);
57
- };
58
- }
59
- });
60
- export {
61
- _sfc_main as _
62
- };