@leavepulse/ui 0.43.3 → 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 (340) hide show
  1. package/README.md +75 -7
  2. package/dist/assets/{LpCommandPalette-DH7sPcKP.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 -10
  103. package/dist/components/LpCommandPalette.vue.js +88 -78
  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/commandSearch.d.ts +0 -1
  198. package/dist/components/commandSearch.js +1 -17
  199. package/dist/components/confirm.d.ts +25 -0
  200. package/dist/components/confirm.js +26 -0
  201. package/dist/components/countries.d.ts +6 -0
  202. package/dist/components/countries.js +7 -0
  203. package/dist/components/fileTree.js +16 -7
  204. package/dist/components/imageCrop.d.ts +42 -0
  205. package/dist/components/imageCrop.js +47 -0
  206. package/dist/components/link.d.ts +12 -0
  207. package/dist/components/link.js +19 -0
  208. package/dist/components/modalDepth.d.ts +18 -2
  209. package/dist/components/modalDepth.js +17 -5
  210. package/dist/components/otp.d.ts +5 -0
  211. package/dist/components/otp.js +10 -0
  212. package/dist/components/sidebar.d.ts +7 -1
  213. package/dist/components/tableSort.d.ts +8 -0
  214. package/dist/components/tableSort.js +31 -0
  215. package/dist/composables/useField.d.ts +34 -0
  216. package/dist/composables/useField.js +45 -0
  217. package/dist/composables/useFormDraft.d.ts +10 -3
  218. package/dist/composables/useFormDraft.js +9 -14
  219. package/dist/composables/useHotkeys.d.ts +17 -1
  220. package/dist/composables/useHotkeys.js +55 -18
  221. package/dist/composables/useInputFilter.d.ts +17 -0
  222. package/dist/composables/useInputFilter.js +47 -10
  223. package/dist/composables/useLpConfig.d.ts +24 -0
  224. package/dist/composables/useLpConfig.js +44 -0
  225. package/dist/composables/useRovingFocus.js +7 -0
  226. package/dist/composables/useTilt.d.ts +2 -2
  227. package/dist/composables/useTilt.js +5 -6
  228. package/dist/composables/useToast.d.ts +20 -0
  229. package/dist/composables/useToast.js +28 -4
  230. package/dist/composables/useZoomPan.d.ts +3 -3
  231. package/dist/composables/useZoomPan.js +4 -4
  232. package/dist/index.d.ts +33 -3
  233. package/dist/index.js +185 -139
  234. package/dist/layout/tree.d.ts +2 -0
  235. package/dist/layout/tree.js +16 -1
  236. package/dist/layout/useLayout.d.ts +15 -0
  237. package/dist/layout/useLayout.js +41 -14
  238. package/dist/theme/useTheme.d.ts +32 -9
  239. package/package.json +8 -7
  240. package/src/component-names.ts +5 -7
  241. package/src/components/ContextMenuItems.vue +88 -0
  242. package/src/components/LayoutCanvas.vue +26 -6
  243. package/src/components/LayoutNode.vue +19 -2
  244. package/src/components/LpActionBar.vue +30 -7
  245. package/src/components/LpAddressInput.vue +57 -41
  246. package/src/components/LpAlert.vue +16 -3
  247. package/src/components/LpAppShell.vue +45 -12
  248. package/src/components/LpAutocomplete.vue +46 -10
  249. package/src/components/LpAvatar.vue +19 -5
  250. package/src/components/LpBreadcrumbs.vue +65 -41
  251. package/src/components/LpButton.vue +59 -13
  252. package/src/components/LpChart.vue +272 -28
  253. package/src/components/LpCheckbox.vue +7 -3
  254. package/src/components/LpCodeBlock.vue +50 -14
  255. package/src/components/LpColorPicker.vue +39 -9
  256. package/src/components/LpCommandPalette.vue +36 -25
  257. package/src/components/LpConfirmDialog.vue +68 -17
  258. package/src/components/LpConfirmHost.vue +59 -0
  259. package/src/components/LpContextMenu.vue +14 -115
  260. package/src/components/LpDatePicker.vue +99 -68
  261. package/src/components/LpDrawer.vue +56 -19
  262. package/src/components/LpDropzone.vue +21 -4
  263. package/src/components/LpFileTree.vue +33 -7
  264. package/src/components/LpFormField.vue +30 -7
  265. package/src/components/LpImageEditor.vue +96 -57
  266. package/src/components/LpInput.vue +18 -7
  267. package/src/components/LpLightbox.vue +140 -29
  268. package/src/components/LpLink.vue +24 -13
  269. package/src/components/LpLogViewer.vue +86 -17
  270. package/src/components/LpMapPicker.vue +36 -13
  271. package/src/components/LpMediaGallery.vue +8 -2
  272. package/src/components/LpModal.vue +53 -27
  273. package/src/components/LpModalNav.vue +5 -2
  274. package/src/components/LpNotificationBell.vue +63 -17
  275. package/src/components/LpNumberField.vue +21 -6
  276. package/src/components/LpNumberFlow.vue +26 -10
  277. package/src/components/LpOtpInput.vue +43 -8
  278. package/src/components/LpPagination.vue +23 -7
  279. package/src/components/LpPasswordInput.vue +4 -1
  280. package/src/components/LpPhoneInput.vue +53 -27
  281. package/src/components/LpPie.vue +94 -15
  282. package/src/components/LpPopover.vue +3 -0
  283. package/src/components/LpProgress.vue +5 -3
  284. package/src/components/LpRadioGroup.vue +9 -2
  285. package/src/components/LpSegmented.vue +12 -2
  286. package/src/components/LpSelect.vue +0 -0
  287. package/src/components/LpShortcutsDialog.vue +8 -3
  288. package/src/components/LpSidebar.vue +14 -9
  289. package/src/components/LpSidebarNav.vue +17 -5
  290. package/src/components/LpSkeleton.vue +4 -1
  291. package/src/components/LpSlider.vue +7 -1
  292. package/src/components/LpSparkline.vue +11 -3
  293. package/src/components/LpSwitch.vue +30 -7
  294. package/src/components/LpTable.vue +91 -32
  295. package/src/components/LpTableOfContents.vue +50 -32
  296. package/src/components/LpTabs.vue +23 -6
  297. package/src/components/LpTextarea.vue +44 -6
  298. package/src/components/LpThemeProvider.vue +41 -0
  299. package/src/components/LpThemeSwitcher.vue +64 -17
  300. package/src/components/LpTilt.vue +2 -2
  301. package/src/components/LpTimeField.vue +14 -3
  302. package/src/components/LpToaster.vue +66 -26
  303. package/src/components/LpTooltip.vue +22 -5
  304. package/src/components/LpTooltipProvider.vue +24 -0
  305. package/src/components/LpTopologyCanvas.vue +12 -1
  306. package/src/components/LpUptimeBar.vue +46 -8
  307. package/src/components/chart.ts +77 -5
  308. package/src/components/codeHighlight.ts +111 -15
  309. package/src/components/color.ts +30 -9
  310. package/src/components/commandSearch.ts +0 -17
  311. package/src/components/confirm.ts +58 -0
  312. package/src/components/countries.ts +12 -0
  313. package/src/components/fileTree.ts +19 -7
  314. package/src/components/imageCrop.ts +107 -0
  315. package/src/components/link.ts +34 -0
  316. package/src/components/modalDepth.ts +48 -6
  317. package/src/components/otp.ts +16 -0
  318. package/src/components/sidebar.ts +7 -1
  319. package/src/components/tableSort.ts +37 -0
  320. package/src/composables/useField.ts +79 -0
  321. package/src/composables/useFormDraft.ts +25 -20
  322. package/src/composables/useHotkeys.ts +89 -18
  323. package/src/composables/useInputFilter.ts +77 -14
  324. package/src/composables/useLpConfig.ts +87 -0
  325. package/src/composables/useRovingFocus.ts +11 -0
  326. package/src/composables/useTilt.ts +5 -6
  327. package/src/composables/useToast.ts +56 -4
  328. package/src/composables/useZoomPan.ts +6 -6
  329. package/src/index.ts +38 -3
  330. package/src/layout/tree.ts +30 -0
  331. package/src/layout/useLayout.ts +68 -18
  332. package/src/nuxt.ts +59 -17
  333. package/src/runtime/config.plugin.ts +14 -0
  334. package/src/runtime/theme.plugin.ts +42 -22
  335. package/src/theme/useTheme.ts +206 -100
  336. package/dist/chunks/LpBreadcrumbs-p4jHe_V-.js +0 -62
  337. package/dist/chunks/LpContextMenu-CwW1QXe_.js +0 -217
  338. package/dist/chunks/LpDatePicker-CwOToxGq.js +0 -164
  339. package/dist/chunks/LpFormField-CazBc2-a.js +0 -62
  340. package/dist/chunks/LpTextarea-t7F6gv8E.js +0 -47
@@ -2,10 +2,11 @@ import { defineComponent, ref, shallowRef, computed, onMounted, onBeforeUnmount,
2
2
  import { prefersReducedMotion } from "../composables/easing.js";
3
3
  import { useClipboard } from "../composables/useClipboard.js";
4
4
  import { useHotkeys } from "../composables/useHotkeys.js";
5
- import { _ as _sfc_main$3 } from "./LpContextMenu-CwW1QXe_.js";
5
+ import { _ as _sfc_main$3 } from "./LpContextMenu-DQw5dGfG.js";
6
6
  import { _ as _sfc_main$2 } from "./LpIcon-CCnX5_2j.js";
7
7
  import { _ as _sfc_main$1 } from "./LpScrollArea-D8xyKXcF.js";
8
8
  import { useMergedAttrs } from "../composables/useMergedClass.js";
9
+ import { useLabels } from "../composables/useLpConfig.js";
9
10
  const _hoisted_1 = {
10
11
  key: 0,
11
12
  class: "pointer-events-none absolute top-2 left-1/2 z-10 -translate-x-1/2 rounded-pill bg-brand px-2.5 py-1 text-[11px] font-medium text-ink-inverse"
@@ -23,25 +24,26 @@ const _hoisted_5 = {
23
24
  key: 0,
24
25
  class: "flex items-center justify-center gap-2 py-2 text-muted"
25
26
  };
26
- const _hoisted_6 = ["data-log-row"];
27
- const _hoisted_7 = {
27
+ const _hoisted_6 = { class: "text-[11px]" };
28
+ const _hoisted_7 = ["data-log-row"];
29
+ const _hoisted_8 = {
28
30
  key: 0,
29
31
  class: "mr-3 w-10 shrink-0 select-none text-right tabular-nums text-muted/70"
30
32
  };
31
- const _hoisted_8 = {
33
+ const _hoisted_9 = {
32
34
  key: 1,
33
35
  class: "mr-3 shrink-0 tabular-nums text-muted"
34
36
  };
35
- const _hoisted_9 = {
37
+ const _hoisted_10 = {
36
38
  key: 3,
37
39
  class: "mr-2 shrink-0 text-muted-strong"
38
40
  };
39
- const _hoisted_10 = {
41
+ const _hoisted_11 = {
40
42
  key: 0,
41
43
  class: "rounded-xs bg-accent/30 text-ink"
42
44
  };
43
- const _hoisted_11 = ["title"];
44
- const _hoisted_12 = {
45
+ const _hoisted_12 = ["title"];
46
+ const _hoisted_13 = {
45
47
  key: 0,
46
48
  class: "absolute inset-x-0 bottom-3 flex justify-center"
47
49
  };
@@ -60,18 +62,37 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
60
62
  compact: { type: Boolean },
61
63
  tail: { type: Boolean, default: true },
62
64
  height: { default: "20rem" },
63
- emptyLabel: { default: "No logs yet" },
64
- frozenLabel: { default: "Held — release Ctrl to resume" },
65
+ emptyLabel: {},
66
+ frozenLabel: {},
65
67
  loadingOlder: { type: Boolean },
66
68
  loadOlder: { type: Boolean },
67
69
  rowMenu: { type: Boolean, default: true },
68
70
  extraRowItems: {},
69
- parse: { type: Boolean, default: false }
71
+ parse: { type: Boolean, default: false },
72
+ labels: {}
70
73
  },
71
74
  emits: ["filter", "reach-top"],
72
75
  setup(__props, { emit: __emit }) {
73
76
  const props = __props;
74
77
  const emit = __emit;
78
+ const text = useLabels(
79
+ "logViewer",
80
+ {
81
+ empty: "No logs yet",
82
+ frozen: "Held — release Ctrl to resume",
83
+ noMatch: "No lines match",
84
+ loadingOlder: "loading older…",
85
+ copyMessage: "Copy message",
86
+ copyLine: "Copy line",
87
+ copyTimestamp: "Copy timestamp",
88
+ copied: "Copied to clipboard",
89
+ filterSource: "Filter by [{source}]",
90
+ filterLevel: "Filter by {level}",
91
+ identical: "{n} identical lines",
92
+ jump: "Jump to latest"
93
+ },
94
+ () => props.labels
95
+ );
75
96
  const levelMeta = {
76
97
  trace: { rail: "bg-line-strong", text: "text-muted", chip: "text-muted", sel: "selection:bg-muted/40" },
77
98
  debug: { rail: "bg-line-strong", text: "text-muted-strong", chip: "text-muted-strong", sel: "selection:bg-muted-strong/40" },
@@ -189,6 +210,18 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
189
210
  }
190
211
  return folded;
191
212
  });
213
+ const lineIds = /* @__PURE__ */ new WeakMap();
214
+ let nextLineId = 0;
215
+ function lineKey(n) {
216
+ const line = sourceLines.value[n];
217
+ if (!line) return -1 - n;
218
+ let id = lineIds.get(line);
219
+ if (id === void 0) {
220
+ id = nextLineId++;
221
+ lineIds.set(line, id);
222
+ }
223
+ return id;
224
+ }
192
225
  const filteredEmpty = computed(
193
226
  () => props.lines.length > 0 && visibleLines.value.length === 0
194
227
  );
@@ -202,7 +235,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
202
235
  return time;
203
236
  }
204
237
  const { copy: writeClipboard } = useClipboard();
205
- const copy = (text) => writeClipboard(text, { toast: "Copied to clipboard" });
238
+ const copy = (value) => writeClipboard(value, { toast: text.value.copied });
206
239
  function lineText(line) {
207
240
  return [fmtTime(line.time), line.level?.toUpperCase(), line.source && `[${line.source}]`, line.message].filter(Boolean).join(" ");
208
241
  }
@@ -223,15 +256,15 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
223
256
  function menuFor(line, index) {
224
257
  if (!props.rowMenu) return [];
225
258
  const items = [
226
- { label: "Copy message", icon: "lucide:copy", onSelect: () => copy(line.message) },
227
- { label: "Copy line", icon: "lucide:clipboard-list", onSelect: () => copy(lineText(line)) }
259
+ { label: text.value.copyMessage, icon: "lucide:copy", onSelect: () => copy(line.message) },
260
+ { label: text.value.copyLine, icon: "lucide:clipboard-list", onSelect: () => copy(lineText(line)) }
228
261
  ];
229
262
  if (line.time != null) {
230
- items.push({ label: "Copy timestamp", icon: "lucide:clock", onSelect: () => copy(fmtTime(line.time)) });
263
+ items.push({ label: text.value.copyTimestamp, icon: "lucide:clock", onSelect: () => copy(fmtTime(line.time)) });
231
264
  }
232
265
  if (line.source) {
233
266
  items.push({
234
- label: `Filter by [${line.source}]`,
267
+ label: text.value.filterSource.replace("{source}", line.source),
235
268
  icon: "lucide:filter",
236
269
  separatorBefore: true,
237
270
  onSelect: () => emit("filter", { source: line.source })
@@ -239,7 +272,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
239
272
  }
240
273
  if (line.level) {
241
274
  items.push({
242
- label: `Filter by ${line.level}`,
275
+ label: text.value.filterLevel.replace("{level}", line.level),
243
276
  icon: "lucide:filter",
244
277
  separatorBefore: !line.source,
245
278
  onSelect: () => emit("filter", { level: line.level })
@@ -344,15 +377,16 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
344
377
  rideToBottom(true, true);
345
378
  pinned.value = true;
346
379
  }
380
+ const linesSignal = () => [props.lines, props.lines.length, props.lines[props.lines.length - 1]];
347
381
  watch(
348
- () => props.lines.length,
382
+ linesSignal,
349
383
  () => {
350
384
  if (!pinned.value) captureScrollAnchor();
351
385
  },
352
386
  { flush: "pre" }
353
387
  );
354
388
  watch(
355
- () => props.lines.length,
389
+ linesSignal,
356
390
  async () => {
357
391
  await nextTick();
358
392
  if (props.tail && pinned.value) {
@@ -412,7 +446,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
412
446
  "leave-to-class": "-translate-y-1 opacity-0"
413
447
  }, {
414
448
  default: withCtx(() => [
415
- frozen.value ? (openBlock(), createElementBlock("div", _hoisted_1, toDisplayString(__props.frozenLabel), 1)) : createCommentVNode("", true)
449
+ frozen.value ? (openBlock(), createElementBlock("div", _hoisted_1, toDisplayString(__props.frozenLabel ?? unref(text).frozen), 1)) : createCommentVNode("", true)
416
450
  ]),
417
451
  _: 1
418
452
  }),
@@ -426,7 +460,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
426
460
  }, {
427
461
  default: withCtx(() => [
428
462
  __props.lines.length === 0 || filteredEmpty.value ? (openBlock(), createElementBlock("div", _hoisted_2, [
429
- createElementVNode("span", _hoisted_3, toDisplayString(filteredEmpty.value ? "No lines match" : __props.emptyLabel), 1),
463
+ createElementVNode("span", _hoisted_3, toDisplayString(filteredEmpty.value ? unref(text).noMatch : __props.emptyLabel ?? unref(text).empty), 1),
430
464
  filteredEmpty.value ? (openBlock(), createElementBlock("span", _hoisted_4, "“" + toDisplayString(__props.highlight) + "”", 1)) : createCommentVNode("", true)
431
465
  ])) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
432
466
  __props.loadingOlder ? (openBlock(), createElementBlock("div", _hoisted_5, [
@@ -435,7 +469,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
435
469
  size: 14,
436
470
  class: "animate-spin"
437
471
  }),
438
- _cache[2] || (_cache[2] = createElementVNode("span", { class: "text-[11px]" }, "loading older…", -1))
472
+ createElementVNode("span", _hoisted_6, toDisplayString(unref(text).loadingOlder), 1)
439
473
  ])) : createCommentVNode("", true),
440
474
  createVNode(_sfc_main$3, {
441
475
  items: menuItems.value,
@@ -455,7 +489,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
455
489
  }, null, 4)) : createCommentVNode("", true),
456
490
  (openBlock(true), createElementBlock(Fragment, null, renderList(renderedLines.value, ({ line, n, count }) => {
457
491
  return openBlock(), createElementBlock("li", {
458
- key: n,
492
+ key: lineKey(n),
459
493
  "data-log-row": n,
460
494
  class: normalizeClass(["group relative flex items-start gap-0 px-0 leading-5 transition-colors hover:bg-surface-soft/60", metaFor(line.level).sel])
461
495
  }, [
@@ -463,23 +497,23 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
463
497
  class: normalizeClass(["absolute inset-y-0 left-0 w-0.5", metaFor(line.level).rail]),
464
498
  "aria-hidden": "true"
465
499
  }, null, 2),
466
- _cache[3] || (_cache[3] = createElementVNode("span", {
500
+ _cache[2] || (_cache[2] = createElementVNode("span", {
467
501
  class: "mr-2 w-0.5 shrink-0",
468
502
  "aria-hidden": "true"
469
503
  }, null, -1)),
470
- __props.lineNumbers ? (openBlock(), createElementBlock("span", _hoisted_7, toDisplayString(n + 1), 1)) : createCommentVNode("", true),
471
- __props.showTime ? (openBlock(), createElementBlock("span", _hoisted_8, toDisplayString(fmtTime(line.time)), 1)) : createCommentVNode("", true),
504
+ __props.lineNumbers ? (openBlock(), createElementBlock("span", _hoisted_8, toDisplayString(n + 1), 1)) : createCommentVNode("", true),
505
+ __props.showTime ? (openBlock(), createElementBlock("span", _hoisted_9, toDisplayString(fmtTime(line.time)), 1)) : createCommentVNode("", true),
472
506
  __props.showLevel ? (openBlock(), createElementBlock("span", {
473
507
  key: 2,
474
508
  class: normalizeClass(["mr-3 w-12 shrink-0 text-[10px] font-semibold uppercase tracking-[0.06em]", metaFor(line.level).chip])
475
509
  }, toDisplayString(line.level ?? "info"), 3)) : createCommentVNode("", true),
476
- line.source ? (openBlock(), createElementBlock("span", _hoisted_9, "[" + toDisplayString(line.source) + "]", 1)) : createCommentVNode("", true),
510
+ line.source ? (openBlock(), createElementBlock("span", _hoisted_10, "[" + toDisplayString(line.source) + "]", 1)) : createCommentVNode("", true),
477
511
  createElementVNode("span", {
478
512
  class: normalizeClass(["min-w-0 pr-3", [metaFor(line.level).text, __props.wrap ? "whitespace-pre-wrap break-words" : "whitespace-pre"]])
479
513
  }, [
480
- (openBlock(true), createElementBlock(Fragment, null, renderList(splitHighlight(line.message), (part, p) => {
514
+ (openBlock(true), createElementBlock(Fragment, null, renderList(splitHighlight(virtualise.value ? line.message.replace(/\r?\n/g, " ↵ ") : line.message), (part, p) => {
481
515
  return openBlock(), createElementBlock(Fragment, { key: p }, [
482
- part.hit ? (openBlock(), createElementBlock("mark", _hoisted_10, toDisplayString(part.text), 1)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
516
+ part.hit ? (openBlock(), createElementBlock("mark", _hoisted_11, toDisplayString(part.text), 1)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
483
517
  createTextVNode(toDisplayString(part.text), 1)
484
518
  ], 64))
485
519
  ], 64);
@@ -492,13 +526,13 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
492
526
  count > 1 ? (openBlock(), createElementBlock("span", {
493
527
  key: count,
494
528
  class: "ml-2 select-none rounded-pill bg-surface-soft px-1.5 align-[1px] text-[10px] font-semibold tabular-nums text-muted-strong",
495
- title: `${count} identical lines`
496
- }, "×" + toDisplayString(count), 9, _hoisted_11)) : createCommentVNode("", true)
529
+ title: unref(text).identical.replace("{n}", String(count))
530
+ }, "×" + toDisplayString(count), 9, _hoisted_12)) : createCommentVNode("", true)
497
531
  ]),
498
532
  _: 2
499
533
  }, 1024)
500
534
  ], 2)
501
- ], 10, _hoisted_6);
535
+ ], 10, _hoisted_7);
502
536
  }), 128)),
503
537
  virtualise.value && padBottom.value > 0 ? (openBlock(), createElementBlock("li", {
504
538
  key: "pad-bottom",
@@ -522,7 +556,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
522
556
  "leave-to-class": "translate-y-3 scale-90 opacity-0"
523
557
  }, {
524
558
  default: withCtx(() => [
525
- showJump.value ? (openBlock(), createElementBlock("div", _hoisted_12, [
559
+ showJump.value ? (openBlock(), createElementBlock("div", _hoisted_13, [
526
560
  createElementVNode("button", {
527
561
  type: "button",
528
562
  class: "group flex items-center gap-1.5 rounded-pill border border-line bg-surface-overlay px-3 py-1 text-xs font-medium text-ink shadow-[var(--shadow-panel)] backdrop-blur outline-none transition-colors hover:bg-surface-soft focus-visible:ring-2 focus-visible:ring-ring",
@@ -533,7 +567,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
533
567
  size: 14,
534
568
  class: "transition-transform duration-200 ease-[var(--ease-emphasized)] group-hover:translate-y-0.5"
535
569
  }),
536
- _cache[4] || (_cache[4] = createTextVNode(" Jump to latest ", -1))
570
+ createTextVNode(" " + toDisplayString(unref(text).jump), 1)
537
571
  ])
538
572
  ])) : createCommentVNode("", true)
539
573
  ]),
@@ -3,6 +3,7 @@ import { prefersReducedMotion } from "../composables/easing.js";
3
3
  import { OSM_TILES, project, tileUrl, unproject } from "../components/address.js";
4
4
  import { _ as _sfc_main$1 } from "./LpIcon-CCnX5_2j.js";
5
5
  import { useMergedAttrs } from "../composables/useMergedClass.js";
6
+ import { useLabels } from "../composables/useLpConfig.js";
6
7
  const _hoisted_1 = ["tabindex", "aria-label"];
7
8
  const _hoisted_2 = ["src", "onLoad"];
8
9
  const _hoisted_3 = { class: "absolute right-2 top-2 flex flex-col gap-1.5" };
@@ -26,15 +27,30 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
26
27
  disabled: { type: Boolean },
27
28
  height: { default: "20rem" },
28
29
  locatable: { type: Boolean, default: true },
29
- zoomInLabel: { default: "Zoom in" },
30
- zoomOutLabel: { default: "Zoom out" },
31
- locateLabel: { default: "Use my location" },
32
- recentreLabel: { default: "Back to the pin" }
30
+ zoomInLabel: {},
31
+ zoomOutLabel: {},
32
+ locateLabel: {},
33
+ recentreLabel: {},
34
+ mapLabel: {}
33
35
  },
34
36
  emits: ["update:modelValue"],
35
37
  setup(__props, { expose: __expose, emit: __emit }) {
36
38
  const props = __props;
37
39
  const emit = __emit;
40
+ const labelSet = useLabels("mapPicker", {
41
+ zoomIn: "Zoom in",
42
+ zoomOut: "Zoom out",
43
+ locate: "Use my location",
44
+ recentre: "Back to the pin",
45
+ map: "Map — arrows pan, +/− zoom, Enter drops the pin in the centre"
46
+ });
47
+ const text = computed(() => ({
48
+ zoomIn: props.zoomInLabel ?? labelSet.value.zoomIn,
49
+ zoomOut: props.zoomOutLabel ?? labelSet.value.zoomOut,
50
+ locate: props.locateLabel ?? labelSet.value.locate,
51
+ recentre: props.recentreLabel ?? labelSet.value.recentre,
52
+ map: props.mapLabel ?? labelSet.value.map
53
+ }));
38
54
  const PAN_STEP = 80;
39
55
  const ZOOM_MS = 220;
40
56
  const seenTiles = /* @__PURE__ */ new Set();
@@ -304,6 +320,15 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
304
320
  e.preventDefault();
305
321
  recentre();
306
322
  break;
323
+ // Without this a keyboard could pan and zoom but never actually pick.
324
+ case "Enter":
325
+ case " ": {
326
+ const el = viewport.value;
327
+ if (!el) return;
328
+ e.preventDefault();
329
+ emit("update:modelValue", toLatLon({ x: el.clientWidth / 2, y: el.clientHeight / 2 }));
330
+ break;
331
+ }
307
332
  }
308
333
  }
309
334
  const canRecentre = computed(() => {
@@ -395,7 +420,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
395
420
  class: normalizeClass(["absolute inset-0 touch-none select-none outline-none focus-visible:ring-2 focus-visible:ring-ring", __props.disabled ? "cursor-not-allowed opacity-55" : panning.value ? "cursor-grabbing" : "cursor-grab"]),
396
421
  tabindex: __props.disabled ? -1 : 0,
397
422
  role: "application",
398
- "aria-label": __props.recentreLabel,
423
+ "aria-label": text.value.map,
399
424
  onPointerdown: onPointerDown,
400
425
  onPointermove: onPointerMove,
401
426
  onPointerup: onPointerUp,
@@ -445,8 +470,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
445
470
  class: normalizeClass(CONTROL),
446
471
  type: "button",
447
472
  disabled: __props.disabled || level.value >= maxZoom.value,
448
- title: __props.zoomInLabel,
449
- "aria-label": __props.zoomInLabel,
473
+ title: text.value.zoomIn,
474
+ "aria-label": text.value.zoomIn,
450
475
  onClick: _cache[0] || (_cache[0] = ($event) => zoomBy(1))
451
476
  }, [
452
477
  createVNode(_sfc_main$1, {
@@ -458,8 +483,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
458
483
  class: normalizeClass(CONTROL),
459
484
  type: "button",
460
485
  disabled: __props.disabled || level.value <= minZoom.value,
461
- title: __props.zoomOutLabel,
462
- "aria-label": __props.zoomOutLabel,
486
+ title: text.value.zoomOut,
487
+ "aria-label": text.value.zoomOut,
463
488
  onClick: _cache[1] || (_cache[1] = ($event) => zoomBy(-1))
464
489
  }, [
465
490
  createVNode(_sfc_main$1, {
@@ -471,8 +496,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
471
496
  key: 0,
472
497
  class: normalizeClass(CONTROL),
473
498
  type: "button",
474
- title: __props.recentreLabel,
475
- "aria-label": __props.recentreLabel,
499
+ title: text.value.recentre,
500
+ "aria-label": text.value.recentre,
476
501
  onClick: recentre
477
502
  }, [
478
503
  createVNode(_sfc_main$1, {
@@ -485,8 +510,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
485
510
  class: normalizeClass(CONTROL),
486
511
  type: "button",
487
512
  disabled: __props.disabled || locating.value,
488
- title: __props.locateLabel,
489
- "aria-label": __props.locateLabel,
513
+ title: text.value.locate,
514
+ "aria-label": text.value.locate,
490
515
  onClick: locate
491
516
  }, [
492
517
  createVNode(_sfc_main$1, {
@@ -1,7 +1,7 @@
1
- import { defineComponent, ref, computed, openBlock, createElementBlock, renderSlot, mergeProps, unref, Fragment, renderList, normalizeClass, createElementVNode, toDisplayString, createVNode, createCommentVNode, createBlock } from "vue";
1
+ import { defineComponent, ref, watch, computed, openBlock, createElementBlock, renderSlot, mergeProps, unref, Fragment, renderList, normalizeClass, createElementVNode, toDisplayString, createVNode, createCommentVNode, createBlock } from "vue";
2
2
  import { useMergedAttrs } from "../composables/useMergedClass.js";
3
3
  import { _ as _sfc_main$1 } from "./LpIcon-CCnX5_2j.js";
4
- import { _ as _sfc_main$2 } from "./LpLightbox-2sYVMY-S.js";
4
+ import { _ as _sfc_main$2 } from "./LpLightbox-Mr0W_6HK.js";
5
5
  const _hoisted_1 = { key: 0 };
6
6
  const _hoisted_2 = ["aria-label"];
7
7
  const _hoisted_3 = ["aria-label", "onClick"];
@@ -38,6 +38,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
38
38
  const emit = __emit;
39
39
  const open = ref(false);
40
40
  const index = ref(0);
41
+ watch(open, (value, was) => {
42
+ if (!value && was) emit("update:open", false);
43
+ });
41
44
  const visible = computed(
42
45
  () => props.max && props.items.length > props.max ? props.items.slice(0, props.max) : props.items
43
46
  );
@@ -118,8 +121,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
118
121
  const at = openIndexOf(i);
119
122
  if (at === -1) return;
120
123
  index.value = at;
124
+ if (!open.value) emit("update:open", true);
121
125
  open.value = true;
122
- emit("update:open", true);
123
126
  }
124
127
  function openOverflow() {
125
128
  activate(visible.value.length);
@@ -1,6 +1,7 @@
1
- import { defineComponent, computed, useSlots, watch, onBeforeUnmount, ref, openBlock, createBlock, unref, withCtx, createVNode, normalizeStyle, normalizeClass, createElementVNode, mergeProps, createElementBlock, renderSlot, createCommentVNode, createTextVNode, toDisplayString } from "vue";
1
+ import { defineComponent, ref, computed, useSlots, watch, onBeforeUnmount, openBlock, createBlock, unref, withCtx, createVNode, normalizeStyle, normalizeClass, createElementVNode, mergeProps, createElementBlock, renderSlot, createCommentVNode, createTextVNode, toDisplayString } from "vue";
2
2
  import { DialogRoot, DialogPortal, DialogOverlay, DialogContent, DialogTitle, DialogDescription, DialogClose } from "reka-ui";
3
3
  import { useGlass } from "../composables/useGlass.js";
4
+ import { useLabels } from "../composables/useLpConfig.js";
4
5
  import { useShift } from "../composables/useShift.js";
5
6
  import { useModalLayer } from "../components/modalDepth.js";
6
7
  import { CLOSE_ICON } from "../components/dropdown.js";
@@ -12,12 +13,12 @@ const _hoisted_1 = {
12
13
  class: "flex min-h-0 flex-col"
13
14
  };
14
15
  const _hoisted_2 = {
15
- key: 0,
16
+ key: 1,
16
17
  class: "flex shrink-0 items-start justify-between gap-4 p-5 pb-3"
17
18
  };
18
19
  const _hoisted_3 = { class: "flex flex-col gap-1" };
19
20
  const _hoisted_4 = {
20
- key: 3,
21
+ key: 4,
21
22
  class: "flex shrink-0 justify-end gap-2 p-5 pt-4"
22
23
  };
23
24
  const _hoisted_5 = {
@@ -35,12 +36,17 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
35
36
  width: {},
36
37
  fillBody: { type: Boolean },
37
38
  autoFocus: { default: "auto" },
38
- glass: { type: Boolean, default: void 0 }
39
+ glass: { type: Boolean, default: void 0 },
40
+ ariaLabel: {},
41
+ role: {},
42
+ labels: {}
39
43
  },
40
44
  emits: ["update:open"],
41
45
  setup(__props) {
42
- const { claim, release, layer } = useModalLayer();
46
+ const panelRef = ref(null);
47
+ const { claim, release, layer } = useModalLayer({ element: () => panelRef.value?.parentElement });
43
48
  const props = __props;
49
+ const text = useLabels("modal", { close: "Close" }, () => props.labels);
44
50
  const frosted = useGlass(() => props.glass);
45
51
  const onInteractOutside = (event) => {
46
52
  const target = event.target;
@@ -48,9 +54,10 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
48
54
  event.preventDefault();
49
55
  }
50
56
  };
51
- const describedByAttrs = computed(
52
- () => props.description ? {} : { "aria-describedby": void 0 }
53
- );
57
+ const describedByAttrs = computed(() => ({
58
+ ...props.description ? {} : { "aria-describedby": void 0 },
59
+ ...props.role ? { role: props.role } : {}
60
+ }));
54
61
  const widthClass = computed(() => {
55
62
  if (props.width) return "";
56
63
  return {
@@ -74,9 +81,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
74
81
  slots.footer ? "" : "pb-5"
75
82
  ].filter(Boolean).join(" ")
76
83
  );
77
- const panelRef = ref(null);
78
84
  const AUTO_FOCUS_ORDER = [
79
- "input:not([type=hidden]):not([disabled]):not([readonly])",
85
+ "input:not([type=hidden]):not([disabled]):not([readonly]):not([tabindex='-1'])",
80
86
  "textarea:not([disabled]):not([readonly])",
81
87
  "select:not([disabled])",
82
88
  "[data-lp-autofocus]",
@@ -84,25 +90,33 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
84
90
  "[href]",
85
91
  "[tabindex]:not([tabindex='-1'])"
86
92
  ];
93
+ function focusable(el) {
94
+ if (el.hasAttribute("disabled") || el.getAttribute("tabindex") === "-1") return false;
95
+ if (el.closest("[aria-hidden='true'], [data-hidden], [inert]")) return false;
96
+ if (typeof el.checkVisibility === "function") return el.checkVisibility({ visibilityProperty: true });
97
+ return el.getClientRects().length > 0;
98
+ }
87
99
  function onOpenAutoFocus(event) {
88
100
  if (props.autoFocus === "none") return;
89
101
  const panel = panelRef.value;
90
102
  if (!panel) return;
91
103
  const selectors = props.autoFocus === "auto" ? AUTO_FOCUS_ORDER : [props.autoFocus];
92
104
  for (const selector of selectors) {
93
- const target = panel.querySelector(selector);
94
- if (!target || target.hasAttribute("disabled")) continue;
95
- event.preventDefault();
96
- if (!target.closest("[data-lp-ring-owner]")) {
97
- target.setAttribute("data-lp-focus-ring", "");
98
- target.addEventListener(
99
- "blur",
100
- () => target.removeAttribute("data-lp-focus-ring"),
101
- { once: true }
102
- );
105
+ for (const target of panel.querySelectorAll(selector)) {
106
+ if (!focusable(target)) continue;
107
+ target.focus();
108
+ if (document.activeElement !== target) continue;
109
+ event.preventDefault();
110
+ if (!target.closest("[data-lp-ring-owner]")) {
111
+ target.setAttribute("data-lp-focus-ring", "");
112
+ target.addEventListener(
113
+ "blur",
114
+ () => target.removeAttribute("data-lp-focus-ring"),
115
+ { once: true }
116
+ );
117
+ }
118
+ return;
103
119
  }
104
- target.focus();
105
- return;
106
120
  }
107
121
  }
108
122
  const {
@@ -151,6 +165,15 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
151
165
  class: normalizeClass(["flex max-h-[min(90vh,calc(100dvh-2rem))] min-h-0 flex-col overflow-hidden rounded-card border border-line shadow-panel", [unref(frosted) ? unref(layer).nested ? "lp-glass-overlay--nested" : "lp-glass-overlay" : "bg-surface-raised", widthClass.value, unref(tweening) ? "transition-[height] duration-fast ease-[var(--ease-emphasized)] motion-reduce:transition-none" : ""]]),
152
166
  style: normalizeStyle({ ...__props.width ? { width: __props.width } : {}, ...hasAside.value ? { alignSelf: "stretch" } : {} })
153
167
  }, [
168
+ !(__props.title || _ctx.$slots.title) && __props.ariaLabel ? (openBlock(), createBlock(unref(DialogTitle), {
169
+ key: 0,
170
+ class: "sr-only"
171
+ }, {
172
+ default: withCtx(() => [
173
+ createTextVNode(toDisplayString(__props.ariaLabel), 1)
174
+ ]),
175
+ _: 1
176
+ })) : createCommentVNode("", true),
154
177
  __props.title || _ctx.$slots.title ? (openBlock(), createElementBlock("header", _hoisted_2, [
155
178
  createElementVNode("div", _hoisted_3, [
156
179
  createVNode(unref(DialogTitle), { class: "text-base font-semibold text-ink" }, {
@@ -174,7 +197,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
174
197
  createVNode(unref(DialogClose), {
175
198
  "data-lp-dialog-close": "",
176
199
  class: "group flex shrink-0 items-center rounded-md p-1 text-muted outline-none transition-colors duration-[var(--duration-fast)] hover:text-ink focus-visible:ring-2 focus-visible:ring-ring",
177
- "aria-label": "Close"
200
+ "aria-label": unref(text).close
178
201
  }, {
179
202
  default: withCtx(() => [
180
203
  createVNode(_sfc_main$1, {
@@ -184,15 +207,15 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
184
207
  }, null, 8, ["class"])
185
208
  ]),
186
209
  _: 1
187
- })
210
+ }, 8, ["aria-label"])
188
211
  ])) : createCommentVNode("", true),
189
212
  __props.fillBody ? (openBlock(), createElementBlock("div", {
190
- key: 1,
213
+ key: 2,
191
214
  class: normalizeClass(["flex min-h-0 flex-1 flex-col overflow-hidden text-sm text-ink/90", bodyPad.value])
192
215
  }, [
193
216
  renderSlot(_ctx.$slots, "default")
194
217
  ], 2)) : (openBlock(), createBlock(_sfc_main$2, {
195
- key: 2,
218
+ key: 3,
196
219
  class: normalizeClass(["min-h-0 flex-1 text-sm text-ink/90", unref(resizing) ? "[&_[data-scrollbarimpl]]:invisible" : ""]),
197
220
  "content-class": bodyPad.value
198
221
  }, {
@@ -1,8 +1,9 @@
1
- import { defineComponent, ref, computed, openBlock, createBlock, createSlots, withCtx, renderSlot, createElementVNode, normalizeClass, createVNode, createCommentVNode, createTextVNode, toDisplayString } from "vue";
2
- import { _ as _sfc_main$2 } from "./LpButton-5VXXCjwF.js";
1
+ import { defineComponent, computed, ref, openBlock, createBlock, createSlots, withCtx, renderSlot, createElementVNode, normalizeClass, createVNode, createCommentVNode, createTextVNode, toDisplayString } from "vue";
2
+ import { useLabels } from "../composables/useLpConfig.js";
3
+ import { _ as _sfc_main$2 } from "./LpButton-kqJBHIIb.js";
3
4
  import { _ as _sfc_main$3 } from "./LpIcon-CCnX5_2j.js";
4
- import { _ as _sfc_main$1 } from "./LpModal-Bt0pQCI_.js";
5
- import { _ as _sfc_main$4 } from "./LpSidebar-ClBUwoEz.js";
5
+ import { _ as _sfc_main$1 } from "./LpModal-DPwGKBPv.js";
6
+ import { _ as _sfc_main$4 } from "./LpSidebar-BgwUNWpJ.js";
6
7
  const _hoisted_1 = { class: "flex items-center gap-2" };
7
8
  const _sfc_main = /* @__PURE__ */ defineComponent({
8
9
  __name: "LpModalNav",
@@ -20,7 +21,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
20
21
  searchPlaceholder: {},
21
22
  loading: { type: Boolean },
22
23
  mobileBreakpoint: { default: "lg" },
23
- navLabel: { default: "Sections" },
24
+ navLabel: {},
24
25
  navSide: { default: "start" },
25
26
  fillBody: { type: Boolean },
26
27
  glass: { type: Boolean, default: void 0 }
@@ -29,6 +30,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
29
30
  setup(__props, { emit: __emit }) {
30
31
  const props = __props;
31
32
  const emit = __emit;
33
+ const text = useLabels("modalNav", { nav: "Sections" });
34
+ const navName = computed(() => props.navLabel ?? text.value.nav);
32
35
  const navOpen = ref(false);
33
36
  const active = computed({
34
37
  get: () => props.modelValue ?? "",
@@ -76,7 +79,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
76
79
  variant: "ghost",
77
80
  size: "sm",
78
81
  square: "",
79
- "aria-label": __props.navLabel,
82
+ "aria-label": navName.value,
80
83
  class: normalizeClass(triggerClass.value),
81
84
  onClick: _cache[4] || (_cache[4] = ($event) => navOpen.value = true)
82
85
  }, {