@leavepulse/ui 0.43.4 → 0.45.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 (437) hide show
  1. package/README.md +121 -7
  2. package/dist/assets/{LpCommandPalette-B-0Est4Z.css → LpCommandPalette-nGNnzXqQ.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/{LpRollingText-CR1mb0Vt.css → LpRollingText-BGnE6q9j.css} +3 -0
  6. package/dist/assets/{LpShortcutsDialog-C6YoQ8_M.css → LpShortcutsDialog-CqYX3yy6.css} +28 -7
  7. package/dist/assets/{LpSkeleton-D7xU8IPV.css → LpSkeleton-H3Z5dEIk.css} +4 -1
  8. package/dist/assets/{LpTable-BgPLJOXa.css → LpTable-CPwWxTJS.css} +49 -9
  9. package/dist/chunks/ContextMenuItems-BtKU7074.js +124 -0
  10. package/dist/chunks/{LayoutCanvas-Dd20boUG.js → LayoutCanvas-BkaGXTjx.js} +26 -9
  11. package/dist/chunks/{LayoutNode-DGpZA9LX.js → LayoutNode-B3_9E1Xa.js} +28 -12
  12. package/dist/chunks/{LpActionBar-BlvtGB2P.js → LpActionBar-CnfFVIwC.js} +26 -12
  13. package/dist/chunks/{LpAddressInput-B-Zvxsn7.js → LpAddressInput-BwX8uo4_.js} +54 -49
  14. package/dist/chunks/{LpAlert-BAYHDSS1.js → LpAlert-B6ilrM7T.js} +16 -9
  15. package/dist/chunks/{LpAppShell-BGQVIY-3.js → LpAppShell-C53_RaGF.js} +53 -26
  16. package/dist/chunks/{LpAutocomplete-DExlIZe_.js → LpAutocomplete-C8IgSMsi.js} +52 -24
  17. package/dist/chunks/{LpAvatar-B3-xAOH3.js → LpAvatar-C1XStdOo.js} +19 -10
  18. package/dist/chunks/LpBreadcrumbs-CQJd73Gm.js +95 -0
  19. package/dist/chunks/{LpButton-5VXXCjwF.js → LpButton-CKSwC6Mu.js} +45 -15
  20. package/dist/chunks/{LpCalendar-B7Ko5RdR.js → LpCalendar-DrA2McTU.js} +1 -1
  21. package/dist/chunks/{LpCard-BhI1N_vL.js → LpCard-C2IvucmX.js} +1 -1
  22. package/dist/chunks/{LpCheckbox-CVccKYaH.js → LpCheckbox-Bkj13CbW.js} +8 -4
  23. package/dist/chunks/{LpCodeBlock-Bo0B4TFR.js → LpCodeBlock-ca7ANFyW.js} +49 -17
  24. package/dist/chunks/{LpColorPicker-BlXea7LM.js → LpColorPicker-zz4VGkG4.js} +75 -26
  25. package/dist/chunks/{LpConfirmDialog-Q-bxff8z.js → LpConfirmDialog-DCw5jR1t.js} +59 -17
  26. package/dist/chunks/LpConfirmHost-CbywMpMP.js +49 -0
  27. package/dist/chunks/LpContextMenu-BqkAYa9X.js +69 -0
  28. package/dist/chunks/LpDatePicker-DuusgT69.js +195 -0
  29. package/dist/chunks/LpDateRangePicker-DHeuznfC.js +208 -0
  30. package/dist/chunks/{LpDisclosure-ChQYmjlR.js → LpDisclosure-Cc23-JOT.js} +1 -1
  31. package/dist/chunks/{LpDrawer-BZ6k3hvo.js → LpDrawer-Dt4aB4Fr.js} +65 -28
  32. package/dist/chunks/{LpDropdownMenu-DJpoqRCb.js → LpDropdownMenu-DdJGQzPn.js} +2 -1
  33. package/dist/chunks/{LpEmptyState-Dsdqz1Wj.js → LpEmptyState-BJbZXC8D.js} +1 -1
  34. package/dist/chunks/LpFieldNotice-wtieLUTj.js +64 -0
  35. package/dist/chunks/{LpFileTree-_5vFBgaK.js → LpFileTree-CNurOvkV.js} +25 -10
  36. package/dist/chunks/{LpFileTreeNode-BdcIYKIE.js → LpFileTreeNode-D_qRRdsH.js} +3 -3
  37. package/dist/chunks/LpFormField-CtVYj6tO.js +101 -0
  38. package/dist/chunks/{LpIcon-CCnX5_2j.js → LpIcon-DYtaid0K.js} +20 -6
  39. package/dist/chunks/{LpInput-9EXWUM9B.js → LpInput-D-YGQbEv.js} +58 -20
  40. package/dist/chunks/{LpLightbox-2sYVMY-S.js → LpLightbox-DSDahF23.js} +148 -61
  41. package/dist/chunks/{LpLink-DCND-zyu.js → LpLink-Krkjhe_y.js} +15 -6
  42. package/dist/chunks/{LpLogViewer-CaRy5MeS.js → LpLogViewer-KypbgOyo.js} +300 -72
  43. package/dist/chunks/{LpMapPicker-ul4oYno6.js → LpMapPicker-Cc84LaM3.js} +39 -14
  44. package/dist/chunks/{LpMediaGallery-FF-NquIo.js → LpMediaGallery-YKr-cQPN.js} +7 -4
  45. package/dist/chunks/{LpModal-Bt0pQCI_.js → LpModal-DMMDQHAu.js} +52 -29
  46. package/dist/chunks/{LpModalNav-YaifHrXC.js → LpModalNav-BVPDyIup.js} +10 -7
  47. package/dist/chunks/{LpNotificationBell-DyGGsMAM.js → LpNotificationBell-CCwyJP5C.js} +79 -33
  48. package/dist/chunks/{LpNumberField-CWuX08iX.js → LpNumberField-B77O-z28.js} +21 -8
  49. package/dist/chunks/{LpNumberFlow-amWYaeuA.js → LpNumberFlow-z4WPZcZu.js} +22 -12
  50. package/dist/chunks/{LpOtpInput-y2v-pmiN.js → LpOtpInput-CziPF3Oq.js} +37 -8
  51. package/dist/chunks/{LpPagination-5FxjmmB5.js → LpPagination-BcDlo3r_.js} +31 -20
  52. package/dist/chunks/{LpPasswordInput--sjYCkLS.js → LpPasswordInput-eKzQhbQP.js} +11 -8
  53. package/dist/chunks/LpPhoneInput-BCbrrhgE.js +336 -0
  54. package/dist/chunks/{LpPie-D6OnzwlJ.js → LpPie-BEJ2SfI6.js} +84 -28
  55. package/dist/chunks/{LpPopover-8268UmlC.js → LpPopover-DCKeqiVn.js} +5 -2
  56. package/dist/chunks/{LpProgress-Btq5W4Ut.js → LpProgress-CBU1iI69.js} +5 -4
  57. package/dist/chunks/{LpRadioGroup-xPIuVDO_.js → LpRadioGroup-DmEW0l78.js} +9 -2
  58. package/dist/chunks/LpRangeCalendar-DZuaRV0W.js +331 -0
  59. package/dist/chunks/{LpRollingText-CM5gkSeF.js → LpRollingText-DB7upf-5.js} +1 -1
  60. package/dist/chunks/{LpScrollArea-D8xyKXcF.js → LpScrollArea-Bry1fdOM.js} +14 -2
  61. package/dist/chunks/{LpSection-aM6J_u51.js → LpSection-tKEH0jYf.js} +1 -1
  62. package/dist/chunks/{LpSegmented-fV0Sk92p.js → LpSegmented-C09EEam2.js} +8 -4
  63. package/dist/chunks/{LpSelect-ANIVtrpM.js → LpSelect-DNIL6MB9.js} +50 -31
  64. package/dist/chunks/{LpSidebar-ClBUwoEz.js → LpSidebar-CQNB0-yU.js} +30 -22
  65. package/dist/chunks/{LpSidebarNav-llOcs_Fn.js → LpSidebarNav-kx-LdqNU.js} +16 -11
  66. package/dist/chunks/{LpSkeleton-CTI-vBgW.js → LpSkeleton-BB6XIV-w.js} +1 -1
  67. package/dist/chunks/{LpSlider-BwNIBkAK.js → LpSlider-Cuzmrd7p.js} +7 -2
  68. package/dist/chunks/{LpSparkline-C6xQ2dwv.js → LpSparkline-CB80N8SJ.js} +11 -4
  69. package/dist/chunks/{LpStat-CQaW8R--.js → LpStat-B-7udBRP.js} +2 -2
  70. package/dist/chunks/{LpStepper-Bk-XaQYU.js → LpStepper-C7XiVKZj.js} +34 -19
  71. package/dist/chunks/{LpSwitch-Blizvqyt.js → LpSwitch-OrcOJX9m.js} +41 -27
  72. package/dist/chunks/LpTableFilter-BV8PpLM9.js +158 -0
  73. package/dist/chunks/{LpTableOfContents-CjvxPMpU.js → LpTableOfContents-BUcAfGPQ.js} +36 -41
  74. package/dist/chunks/{LpTabs-Cefe_lys.js → LpTabs-29iW1XOx.js} +20 -6
  75. package/dist/chunks/LpTagsInput-D1SuqbhB.js +300 -0
  76. package/dist/chunks/LpTextarea-uuScWo6-.js +77 -0
  77. package/dist/chunks/LpThemeProvider-Be4r2TQX.js +35 -0
  78. package/dist/chunks/LpThemeSwitcher-B4aVPbNC.js +166 -0
  79. package/dist/chunks/{LpTilt-DuyKbpkA.js → LpTilt-B7KHX1zH.js} +2 -2
  80. package/dist/chunks/{LpTimeField-K6nAGboX.js → LpTimeField-Cqe7fXnh.js} +14 -8
  81. package/dist/chunks/{LpToaster-gDB1EaU3.js → LpToaster-DpJvoCOh.js} +94 -31
  82. package/dist/chunks/{LpTooltip-hCLPAqMG.js → LpTooltip-CXVKcOXT.js} +14 -6
  83. package/dist/chunks/LpTooltipProvider-CftjV7Xc.js +25 -0
  84. package/dist/chunks/{LpTopologyCanvas-Cm1L39uL.js → LpTopologyCanvas-6ozNrQKh.js} +8 -2
  85. package/dist/chunks/{LpUptimeBar-DvAMno0S.js → LpUptimeBar-ugcv25xj.js} +44 -15
  86. package/dist/chunks/icons-CkA0njzm.js +43 -0
  87. package/dist/chunks/{LpThemeSwitcher-Cue-myST.js → useTheme-DJm1JSsY.js} +215 -260
  88. package/dist/component-names.d.ts +1 -1
  89. package/dist/components/ContextMenuItems.vue.d.ts +8 -0
  90. package/dist/components/ContextMenuItems.vue.js +4 -0
  91. package/dist/components/LayoutCanvas.vue.js +1 -1
  92. package/dist/components/LayoutNode.vue.d.ts +4 -0
  93. package/dist/components/LayoutNode.vue.js +1 -1
  94. package/dist/components/LpActionBar.vue.d.ts +3 -0
  95. package/dist/components/LpActionBar.vue.js +1 -1
  96. package/dist/components/LpAddressInput.vue.d.ts +1 -1
  97. package/dist/components/LpAddressInput.vue.js +1 -1
  98. package/dist/components/LpAlert.vue.d.ts +9 -0
  99. package/dist/components/LpAlert.vue.js +1 -1
  100. package/dist/components/LpAppShell.vue.d.ts +10 -0
  101. package/dist/components/LpAppShell.vue.js +1 -1
  102. package/dist/components/LpAutocomplete.vue.d.ts +31 -6
  103. package/dist/components/LpAutocomplete.vue.js +1 -1
  104. package/dist/components/LpAvatar.vue.d.ts +3 -3
  105. package/dist/components/LpAvatar.vue.js +1 -1
  106. package/dist/components/LpBadge.vue.d.ts +2 -2
  107. package/dist/components/LpBreadcrumbs.vue.d.ts +13 -9
  108. package/dist/components/LpBreadcrumbs.vue.js +1 -1
  109. package/dist/components/LpButton.vue.d.ts +35 -98
  110. package/dist/components/LpButton.vue.js +1 -1
  111. package/dist/components/LpCalendar.vue.js +1 -1
  112. package/dist/components/LpCard.vue.js +1 -1
  113. package/dist/components/LpChart.vue.d.ts +47 -3
  114. package/dist/components/LpChart.vue.js +377 -97
  115. package/dist/components/LpCheckbox.vue.js +1 -1
  116. package/dist/components/LpCodeBlock.vue.d.ts +2 -0
  117. package/dist/components/LpCodeBlock.vue.js +1 -1
  118. package/dist/components/LpColorPicker.vue.d.ts +2 -2
  119. package/dist/components/LpColorPicker.vue.js +1 -1
  120. package/dist/components/LpCommandPalette.vue.d.ts +14 -3
  121. package/dist/components/LpCommandPalette.vue.js +142 -77
  122. package/dist/components/LpConfirmDialog.vue.d.ts +15 -3
  123. package/dist/components/LpConfirmDialog.vue.js +1 -1
  124. package/dist/components/LpConfirmHost.vue.d.ts +9 -0
  125. package/dist/components/LpConfirmHost.vue.js +4 -0
  126. package/dist/components/LpContextMenu.vue.d.ts +3 -5
  127. package/dist/components/LpContextMenu.vue.js +1 -1
  128. package/dist/components/LpDatePicker.vue.d.ts +24 -6
  129. package/dist/components/LpDatePicker.vue.js +1 -1
  130. package/dist/components/LpDateRangePicker.vue.d.ts +60 -0
  131. package/dist/components/LpDateRangePicker.vue.js +4 -0
  132. package/dist/components/LpDisclosure.vue.js +1 -1
  133. package/dist/components/LpDrawer.vue.d.ts +10 -0
  134. package/dist/components/LpDrawer.vue.js +1 -1
  135. package/dist/components/LpDropdownMenu.vue.js +1 -1
  136. package/dist/components/LpDropzone.vue.js +23 -7
  137. package/dist/components/LpEmptyState.vue.js +1 -1
  138. package/dist/components/LpFieldNotice.vue.d.ts +8 -0
  139. package/dist/components/LpFieldNotice.vue.js +4 -0
  140. package/dist/components/LpFileTree.vue.d.ts +11 -2
  141. package/dist/components/LpFileTree.vue.js +1 -1
  142. package/dist/components/LpFileTreeNode.vue.js +1 -1
  143. package/dist/components/LpFormField.vue.d.ts +13 -1
  144. package/dist/components/LpFormField.vue.js +1 -1
  145. package/dist/components/LpIcon.vue.d.ts +0 -1
  146. package/dist/components/LpIcon.vue.js +1 -1
  147. package/dist/components/LpImageEditor.vue.js +93 -58
  148. package/dist/components/LpInput.vue.d.ts +22 -3
  149. package/dist/components/LpInput.vue.js +1 -1
  150. package/dist/components/LpLightbox.vue.d.ts +17 -0
  151. package/dist/components/LpLightbox.vue.js +1 -1
  152. package/dist/components/LpLink.vue.d.ts +11 -11
  153. package/dist/components/LpLink.vue.js +1 -1
  154. package/dist/components/LpLogViewer.vue.d.ts +72 -3
  155. package/dist/components/LpLogViewer.vue.js +1 -1
  156. package/dist/components/LpMapPicker.vue.d.ts +4 -4
  157. package/dist/components/LpMapPicker.vue.js +1 -1
  158. package/dist/components/LpMediaGallery.vue.js +1 -1
  159. package/dist/components/LpModal.vue.d.ts +16 -6
  160. package/dist/components/LpModal.vue.js +1 -1
  161. package/dist/components/LpModalNav.vue.d.ts +0 -1
  162. package/dist/components/LpModalNav.vue.js +1 -1
  163. package/dist/components/LpNotificationBell.vue.d.ts +11 -2
  164. package/dist/components/LpNotificationBell.vue.js +1 -1
  165. package/dist/components/LpNumberField.vue.d.ts +2 -0
  166. package/dist/components/LpNumberField.vue.js +1 -1
  167. package/dist/components/LpNumberFlow.vue.js +1 -1
  168. package/dist/components/LpOtpInput.vue.js +1 -1
  169. package/dist/components/LpPagination.vue.d.ts +2 -0
  170. package/dist/components/LpPagination.vue.js +1 -1
  171. package/dist/components/LpPasswordInput.vue.js +1 -1
  172. package/dist/components/LpPhoneInput.vue.d.ts +13 -0
  173. package/dist/components/LpPhoneInput.vue.js +1 -1
  174. package/dist/components/LpPie.vue.d.ts +21 -2
  175. package/dist/components/LpPie.vue.js +1 -1
  176. package/dist/components/LpPopover.vue.d.ts +2 -0
  177. package/dist/components/LpPopover.vue.js +1 -1
  178. package/dist/components/LpProgress.vue.d.ts +1 -1
  179. package/dist/components/LpProgress.vue.js +1 -1
  180. package/dist/components/LpRadioGroup.vue.js +1 -1
  181. package/dist/components/LpRangeCalendar.vue.d.ts +51 -0
  182. package/dist/components/LpRangeCalendar.vue.js +4 -0
  183. package/dist/components/LpRollingText.vue.d.ts +1 -1
  184. package/dist/components/LpRollingText.vue.js +1 -1
  185. package/dist/components/LpScrollArea.vue.d.ts +2 -2
  186. package/dist/components/LpScrollArea.vue.js +1 -1
  187. package/dist/components/LpSection.vue.d.ts +1 -1
  188. package/dist/components/LpSection.vue.js +1 -1
  189. package/dist/components/LpSegmented.vue.d.ts +5 -0
  190. package/dist/components/LpSegmented.vue.js +1 -1
  191. package/dist/components/LpSelect.vue.d.ts +1 -0
  192. package/dist/components/LpSelect.vue.js +1 -1
  193. package/dist/components/LpShortcutsDialog.vue.d.ts +7 -1
  194. package/dist/components/LpShortcutsDialog.vue.js +60 -15
  195. package/dist/components/LpSidebar.vue.d.ts +6 -2
  196. package/dist/components/LpSidebar.vue.js +1 -1
  197. package/dist/components/LpSidebarNav.vue.js +1 -1
  198. package/dist/components/LpSkeleton.vue.js +1 -1
  199. package/dist/components/LpSlider.vue.js +1 -1
  200. package/dist/components/LpSparkline.vue.d.ts +1 -0
  201. package/dist/components/LpSparkline.vue.js +1 -1
  202. package/dist/components/LpStat.vue.js +1 -1
  203. package/dist/components/LpStepper.vue.js +1 -1
  204. package/dist/components/LpSwitch.vue.js +1 -1
  205. package/dist/components/LpTable.vue.d.ts +107 -3
  206. package/dist/components/LpTable.vue.js +540 -128
  207. package/dist/components/LpTableFilter.vue.d.ts +31 -0
  208. package/dist/components/LpTableFilter.vue.js +4 -0
  209. package/dist/components/LpTableOfContents.vue.d.ts +4 -2
  210. package/dist/components/LpTableOfContents.vue.js +1 -1
  211. package/dist/components/LpTabs.vue.d.ts +2 -0
  212. package/dist/components/LpTabs.vue.js +1 -1
  213. package/dist/components/LpTagsInput.vue.d.ts +77 -0
  214. package/dist/components/LpTagsInput.vue.js +4 -0
  215. package/dist/components/LpTextarea.vue.d.ts +19 -6
  216. package/dist/components/LpTextarea.vue.js +1 -1
  217. package/dist/components/LpThemeProvider.vue.d.ts +22 -0
  218. package/dist/components/LpThemeProvider.vue.js +4 -0
  219. package/dist/components/LpThemeSwitcher.vue.d.ts +15 -2
  220. package/dist/components/LpThemeSwitcher.vue.js +1 -1
  221. package/dist/components/LpTilt.vue.js +1 -1
  222. package/dist/components/LpTimeField.vue.js +1 -1
  223. package/dist/components/LpToaster.vue.d.ts +6 -1
  224. package/dist/components/LpToaster.vue.js +1 -1
  225. package/dist/components/LpTooltip.vue.d.ts +1 -2
  226. package/dist/components/LpTooltip.vue.js +1 -1
  227. package/dist/components/LpTooltipProvider.vue.d.ts +22 -0
  228. package/dist/components/LpTooltipProvider.vue.js +4 -0
  229. package/dist/components/LpTopologyCanvas.vue.js +1 -1
  230. package/dist/components/LpUptimeBar.vue.d.ts +4 -0
  231. package/dist/components/LpUptimeBar.vue.js +1 -1
  232. package/dist/components/chart.d.ts +32 -1
  233. package/dist/components/chart.js +42 -6
  234. package/dist/components/codeHighlight.d.ts +6 -0
  235. package/dist/components/codeHighlight.js +92 -20
  236. package/dist/components/color.d.ts +1 -1
  237. package/dist/components/color.js +20 -9
  238. package/dist/components/commandSearch.js +3 -0
  239. package/dist/components/confirm.d.ts +25 -0
  240. package/dist/components/confirm.js +26 -0
  241. package/dist/components/countries.d.ts +6 -0
  242. package/dist/components/countries.js +7 -0
  243. package/dist/components/dateRange.d.ts +43 -0
  244. package/dist/components/dateRange.js +76 -0
  245. package/dist/components/exportData.d.ts +58 -0
  246. package/dist/components/exportData.js +165 -0
  247. package/dist/components/fileTree.js +16 -7
  248. package/dist/components/imageCrop.d.ts +42 -0
  249. package/dist/components/imageCrop.js +47 -0
  250. package/dist/components/link.d.ts +12 -0
  251. package/dist/components/link.js +19 -0
  252. package/dist/components/logSearch.d.ts +18 -0
  253. package/dist/components/logSearch.js +36 -0
  254. package/dist/components/modalDepth.d.ts +18 -2
  255. package/dist/components/modalDepth.js +17 -5
  256. package/dist/components/otp.d.ts +5 -0
  257. package/dist/components/otp.js +10 -0
  258. package/dist/components/phone.d.ts +41 -0
  259. package/dist/components/phone.js +80 -0
  260. package/dist/components/sidebar.d.ts +7 -1
  261. package/dist/components/tableFilter.d.ts +36 -0
  262. package/dist/components/tableFilter.js +84 -0
  263. package/dist/components/tableSort.d.ts +8 -0
  264. package/dist/components/tableSort.js +31 -0
  265. package/dist/components/tags.d.ts +20 -0
  266. package/dist/components/tags.js +37 -0
  267. package/dist/composables/useField.d.ts +38 -0
  268. package/dist/composables/useField.js +45 -0
  269. package/dist/composables/useFieldNotice.d.ts +17 -0
  270. package/dist/composables/useFieldNotice.js +28 -0
  271. package/dist/composables/useForm.d.ts +53 -0
  272. package/dist/composables/useForm.js +207 -0
  273. package/dist/composables/useFormDraft.d.ts +10 -3
  274. package/dist/composables/useFormDraft.js +9 -14
  275. package/dist/composables/useHotkeys.d.ts +81 -5
  276. package/dist/composables/useHotkeys.js +223 -25
  277. package/dist/composables/useInputFilter.d.ts +17 -0
  278. package/dist/composables/useInputFilter.js +47 -10
  279. package/dist/composables/useInputMask.d.ts +59 -0
  280. package/dist/composables/useInputMask.js +170 -0
  281. package/dist/composables/useLpConfig.d.ts +24 -0
  282. package/dist/composables/useLpConfig.js +44 -0
  283. package/dist/composables/usePaintSelect.d.ts +22 -0
  284. package/dist/composables/usePaintSelect.js +169 -0
  285. package/dist/composables/useRovingFocus.js +7 -0
  286. package/dist/composables/useShift.js +7 -2
  287. package/dist/composables/useTilt.d.ts +2 -2
  288. package/dist/composables/useTilt.js +5 -6
  289. package/dist/composables/useToast.d.ts +20 -0
  290. package/dist/composables/useToast.js +28 -4
  291. package/dist/composables/useZoomPan.d.ts +3 -3
  292. package/dist/composables/useZoomPan.js +4 -4
  293. package/dist/icons-all.d.ts +1 -0
  294. package/dist/icons-all.js +3 -0
  295. package/dist/icons.d.ts +14 -1
  296. package/dist/index.d.ts +60 -4
  297. package/dist/index.js +245 -141
  298. package/dist/kit-icons.d.ts +2 -0
  299. package/dist/layout/tree.d.ts +2 -0
  300. package/dist/layout/tree.js +16 -1
  301. package/dist/layout/useLayout.d.ts +15 -0
  302. package/dist/layout/useLayout.js +41 -14
  303. package/dist/theme/backdrop.d.ts +12 -0
  304. package/dist/theme/presets.d.ts +0 -2
  305. package/dist/theme/useTheme.d.ts +32 -9
  306. package/package.json +18 -8
  307. package/src/component-names.ts +9 -7
  308. package/src/components/ContextMenuItems.vue +88 -0
  309. package/src/components/LayoutCanvas.vue +26 -6
  310. package/src/components/LayoutNode.vue +30 -4
  311. package/src/components/LpActionBar.vue +31 -8
  312. package/src/components/LpAddressInput.vue +57 -41
  313. package/src/components/LpAlert.vue +16 -3
  314. package/src/components/LpAppShell.vue +45 -12
  315. package/src/components/LpAutocomplete.vue +47 -10
  316. package/src/components/LpAvatar.vue +20 -6
  317. package/src/components/LpBreadcrumbs.vue +65 -41
  318. package/src/components/LpButton.vue +60 -14
  319. package/src/components/LpChart.vue +351 -28
  320. package/src/components/LpCheckbox.vue +7 -3
  321. package/src/components/LpCodeBlock.vue +50 -14
  322. package/src/components/LpColorPicker.vue +73 -10
  323. package/src/components/LpCommandPalette.vue +115 -20
  324. package/src/components/LpConfirmDialog.vue +68 -17
  325. package/src/components/LpConfirmHost.vue +59 -0
  326. package/src/components/LpContextMenu.vue +15 -116
  327. package/src/components/LpDatePicker.vue +104 -68
  328. package/src/components/LpDateRangePicker.vue +224 -0
  329. package/src/components/LpDrawer.vue +56 -19
  330. package/src/components/LpDropdownMenu.vue +1 -0
  331. package/src/components/LpDropzone.vue +21 -4
  332. package/src/components/LpFieldNotice.vue +65 -0
  333. package/src/components/LpFileTree.vue +33 -7
  334. package/src/components/LpFormField.vue +59 -7
  335. package/src/components/LpIcon.vue +22 -4
  336. package/src/components/LpImageEditor.vue +96 -57
  337. package/src/components/LpInput.vue +62 -11
  338. package/src/components/LpLightbox.vue +140 -29
  339. package/src/components/LpLink.vue +24 -13
  340. package/src/components/LpLogViewer.vue +311 -39
  341. package/src/components/LpMapPicker.vue +36 -13
  342. package/src/components/LpMediaGallery.vue +8 -2
  343. package/src/components/LpModal.vue +54 -28
  344. package/src/components/LpModalNav.vue +5 -2
  345. package/src/components/LpNotificationBell.vue +77 -23
  346. package/src/components/LpNumberField.vue +21 -6
  347. package/src/components/LpNumberFlow.vue +26 -10
  348. package/src/components/LpOtpInput.vue +43 -8
  349. package/src/components/LpPagination.vue +23 -7
  350. package/src/components/LpPasswordInput.vue +4 -1
  351. package/src/components/LpPhoneInput.vue +224 -39
  352. package/src/components/LpPie.vue +102 -20
  353. package/src/components/LpPopover.vue +4 -0
  354. package/src/components/LpProgress.vue +5 -3
  355. package/src/components/LpRadioGroup.vue +9 -2
  356. package/src/components/LpRangeCalendar.vue +365 -0
  357. package/src/components/LpRollingText.vue +3 -0
  358. package/src/components/LpScrollArea.vue +22 -2
  359. package/src/components/LpSegmented.vue +12 -2
  360. package/src/components/LpSelect.vue +0 -0
  361. package/src/components/LpShortcutsDialog.vue +83 -9
  362. package/src/components/LpSidebar.vue +14 -9
  363. package/src/components/LpSidebarNav.vue +17 -5
  364. package/src/components/LpSkeleton.vue +4 -1
  365. package/src/components/LpSlider.vue +7 -1
  366. package/src/components/LpSparkline.vue +11 -3
  367. package/src/components/LpStepper.vue +23 -10
  368. package/src/components/LpSwitch.vue +31 -8
  369. package/src/components/LpTable.vue +668 -90
  370. package/src/components/LpTableFilter.vue +175 -0
  371. package/src/components/LpTableOfContents.vue +50 -32
  372. package/src/components/LpTabs.vue +23 -6
  373. package/src/components/LpTagsInput.vue +364 -0
  374. package/src/components/LpTextarea.vue +44 -6
  375. package/src/components/LpThemeProvider.vue +41 -0
  376. package/src/components/LpThemeSwitcher.vue +76 -33
  377. package/src/components/LpTilt.vue +2 -2
  378. package/src/components/LpTimeField.vue +14 -3
  379. package/src/components/LpToaster.vue +115 -27
  380. package/src/components/LpTooltip.vue +29 -5
  381. package/src/components/LpTooltipProvider.vue +24 -0
  382. package/src/components/LpTopologyCanvas.vue +19 -2
  383. package/src/components/LpUptimeBar.vue +46 -8
  384. package/src/components/chart.ts +82 -8
  385. package/src/components/codeHighlight.ts +111 -15
  386. package/src/components/color.ts +30 -9
  387. package/src/components/commandSearch.ts +6 -0
  388. package/src/components/confirm.ts +58 -0
  389. package/src/components/countries.ts +12 -0
  390. package/src/components/dateRange.ts +134 -0
  391. package/src/components/exportData.ts +228 -0
  392. package/src/components/fileTree.ts +19 -7
  393. package/src/components/imageCrop.ts +107 -0
  394. package/src/components/link.ts +34 -0
  395. package/src/components/logSearch.ts +46 -0
  396. package/src/components/modalDepth.ts +48 -6
  397. package/src/components/otp.ts +16 -0
  398. package/src/components/phone.ts +140 -0
  399. package/src/components/sidebar.ts +7 -1
  400. package/src/components/tableFilter.ts +122 -0
  401. package/src/components/tableSort.ts +37 -0
  402. package/src/components/tags.ts +62 -0
  403. package/src/composables/useField.ts +83 -0
  404. package/src/composables/useFieldNotice.ts +59 -0
  405. package/src/composables/useForm.ts +314 -0
  406. package/src/composables/useFormDraft.ts +25 -20
  407. package/src/composables/useHotkeys.ts +355 -28
  408. package/src/composables/useInputFilter.ts +77 -14
  409. package/src/composables/useInputMask.ts +254 -0
  410. package/src/composables/useLpConfig.ts +87 -0
  411. package/src/composables/usePaintSelect.ts +243 -0
  412. package/src/composables/useRovingFocus.ts +11 -0
  413. package/src/composables/useShift.ts +13 -2
  414. package/src/composables/useTilt.ts +5 -6
  415. package/src/composables/useToast.ts +56 -4
  416. package/src/composables/useZoomPan.ts +6 -6
  417. package/src/iconSubset.d.mts +10 -0
  418. package/src/iconSubset.mjs +51 -0
  419. package/src/icons-all.ts +10 -0
  420. package/src/icons.ts +59 -8
  421. package/src/index.ts +73 -4
  422. package/src/kit-icons.ts +5 -0
  423. package/src/layout/tree.ts +30 -0
  424. package/src/layout/useLayout.ts +68 -18
  425. package/src/nuxt.ts +87 -17
  426. package/src/runtime/config.plugin.ts +14 -0
  427. package/src/runtime/theme.plugin.ts +43 -23
  428. package/src/theme/backdrop.ts +69 -0
  429. package/src/theme/presets.ts +6 -64
  430. package/src/theme/useTheme.ts +206 -100
  431. package/src/tokens/tokens.css +46 -0
  432. package/dist/chunks/LpBreadcrumbs-p4jHe_V-.js +0 -62
  433. package/dist/chunks/LpContextMenu-CwW1QXe_.js +0 -217
  434. package/dist/chunks/LpDatePicker-CwOToxGq.js +0 -164
  435. package/dist/chunks/LpFormField-CazBc2-a.js +0 -62
  436. package/dist/chunks/LpPhoneInput-BDSKVl_z.js +0 -209
  437. package/dist/chunks/LpTextarea-t7F6gv8E.js +0 -47
@@ -1,25 +1,61 @@
1
- import { defineComponent, useAttrs, computed, ref, shallowRef, watch, onBeforeUnmount, openBlock, createElementBlock, normalizeClass, createVNode, mergeProps, withCtx, createElementVNode, createCommentVNode, Fragment, renderList, normalizeStyle, createBlock, createTextVNode, toDisplayString, TransitionGroup, unref, withModifiers, renderSlot, nextTick } from "vue";
2
- import { _ as _sfc_main$3 } from "../chunks/LpCheckbox-CVccKYaH.js";
3
- import { _ as _sfc_main$2 } from "../chunks/LpContextMenu-CwW1QXe_.js";
4
- import { _ as _sfc_main$4 } from "../chunks/LpIcon-CCnX5_2j.js";
5
- import { _ as _sfc_main$5 } from "../chunks/LpPagination-5FxjmmB5.js";
6
- import { _ as _sfc_main$1 } from "../chunks/LpScrollArea-D8xyKXcF.js";
1
+ import { defineComponent, computed, useAttrs, ref, shallowRef, watch, onMounted, onBeforeUnmount, openBlock, createElementBlock, normalizeClass, createVNode, withCtx, createTextVNode, toDisplayString, createCommentVNode, Fragment, renderList, createElementVNode, Transition, renderSlot, mergeProps, normalizeStyle, createBlock, TransitionGroup, unref, withModifiers, nextTick } from "vue";
2
+ import { _ as _sfc_main$7 } from "../chunks/LpCheckbox-Bkj13CbW.js";
3
+ import { _ as _sfc_main$6 } from "../chunks/LpContextMenu-BqkAYa9X.js";
4
+ import { _ as _sfc_main$2 } from "../chunks/LpIcon-DYtaid0K.js";
5
+ import { _ as _sfc_main$a } from "../chunks/LpPagination-BcDlo3r_.js";
6
+ import { _ as _sfc_main$8 } from "../chunks/LpPopover-DCKeqiVn.js";
7
+ import { _ as _sfc_main$5 } from "../chunks/LpScrollArea-Bry1fdOM.js";
8
+ import { _ as _sfc_main$4 } from "../chunks/LpRollingText-DB7upf-5.js";
9
+ import { _ as _sfc_main$3 } from "../chunks/LpShift-DXNsauQZ.js";
10
+ import { _ as _sfc_main$9 } from "../chunks/LpTableFilter-BV8PpLM9.js";
7
11
  import { useAsyncTask } from "../composables/useAsyncTask.js";
12
+ import { useHotkeys } from "../composables/useHotkeys.js";
13
+ import { usePaintSelect } from "../composables/usePaintSelect.js";
8
14
  import { useRovingFocus } from "../composables/useRovingFocus.js";
15
+ import { useLabels } from "../composables/useLpConfig.js";
16
+ import { compareValues } from "./tableSort.js";
17
+ import { _ as _sfc_main$1 } from "../chunks/LpButton-CKSwC6Mu.js";
18
+ import { toCsv, downloadFile, fileStem } from "./exportData.js";
19
+ import { summarizeShown, parseTableState, serializeTableState, countValues } from "./tableFilter.js";
9
20
  import { _ as _export_sfc } from "../chunks/_plugin-vue_export-helper-1tPrXgE0.js";
10
- import '../assets/LpTable-BgPLJOXa.css';const _hoisted_1 = { class: "border-b border-line bg-surface-soft" };
21
+ import '../assets/LpTable-CPwWxTJS.css';const _hoisted_1 = {
22
+ key: 0,
23
+ class: "flex justify-end"
24
+ };
11
25
  const _hoisted_2 = {
12
26
  key: 0,
13
- class: "w-px px-4 py-3"
27
+ class: "flex min-h-8 items-center gap-x-3 pb-3 text-xs"
28
+ };
29
+ const _hoisted_3 = {
30
+ key: 0,
31
+ class: "flex min-w-0 flex-1 flex-wrap items-center gap-1.5"
32
+ };
33
+ const _hoisted_4 = { class: "truncate" };
34
+ const _hoisted_5 = { class: "text-muted" };
35
+ const _hoisted_6 = ["aria-label", "onClick"];
36
+ const _hoisted_7 = { class: "flex items-center gap-2 whitespace-nowrap text-muted" };
37
+ const _hoisted_8 = {
38
+ key: 0,
39
+ class: "flex items-center gap-2"
14
40
  };
15
- const _hoisted_3 = ["aria-sort"];
16
- const _hoisted_4 = ["onClick"];
17
- const _hoisted_5 = {
41
+ const _hoisted_9 = {
42
+ key: 0,
43
+ class: "flex items-center gap-2"
44
+ };
45
+ const _hoisted_10 = { class: "hidden sm:inline" };
46
+ const _hoisted_11 = { class: "w-full border-collapse text-sm" };
47
+ const _hoisted_12 = { class: "border-b border-line bg-surface-soft" };
48
+ const _hoisted_13 = ["inert"];
49
+ const _hoisted_14 = ["aria-sort"];
50
+ const _hoisted_15 = ["onClick"];
51
+ const _hoisted_16 = ["aria-label", "data-lp-filter"];
52
+ const _hoisted_17 = {
18
53
  key: "lp-table-empty",
19
54
  class: "lp-row-empty"
20
55
  };
21
- const _hoisted_6 = ["colspan"];
22
- const _hoisted_7 = ["onContextmenu", "onClick"];
56
+ const _hoisted_18 = ["colspan"];
57
+ const _hoisted_19 = ["onContextmenu", "data-paint-key", "onClick", "onPointerdown"];
58
+ const _hoisted_20 = ["onPointerdown"];
23
59
  const __default__ = { inheritAttrs: false };
24
60
  const _sfc_main = /* @__PURE__ */ defineComponent({
25
61
  ...__default__,
@@ -30,26 +66,84 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
30
66
  load: {},
31
67
  pageSize: { default: 25 },
32
68
  debounce: { default: 150 },
33
- loadingLabel: { default: "Loading…" },
34
- errorLabel: { default: "Could not load" },
69
+ loadingLabel: {},
70
+ errorLabel: {},
35
71
  rowKey: {},
36
- emptyLabel: { default: "Nothing here yet" },
72
+ emptyLabel: {},
37
73
  emptyIcon: { default: "lucide:inbox" },
38
- selectable: { type: Boolean, default: false },
74
+ selectable: { type: [Boolean, String], default: false },
39
75
  selected: { default: () => [] },
40
- sort: { default: null },
76
+ sort: { default: void 0 },
41
77
  stickyHeader: { type: Boolean },
42
78
  rowMenu: {},
43
- sortAscLabel: { default: "Sort ascending" },
44
- sortDescLabel: { default: "Sort descending" },
45
- sortClearLabel: { default: "Clear sorting" },
46
- filterLabel: { default: "Show only" },
47
- showAllLabel: { default: "Show all" },
48
- columnsLabel: { default: "Columns" }
79
+ sortAscLabel: {},
80
+ sortDescLabel: {},
81
+ sortClearLabel: {},
82
+ filterLabel: {},
83
+ showAllLabel: {},
84
+ columnsLabel: {},
85
+ exportable: { type: Boolean },
86
+ exportFilename: {},
87
+ labels: {},
88
+ density: { default: "comfortable" },
89
+ summary: { type: Boolean, default: false },
90
+ persist: {},
91
+ allMatching: { type: Boolean, default: false }
49
92
  },
50
- emits: ["update:selected", "update:sort", "rowClick"],
93
+ emits: ["update:selected", "update:sort", "update:allMatching", "rowClick"],
51
94
  setup(__props, { expose: __expose, emit: __emit }) {
52
95
  const props = __props;
96
+ const labelSet = useLabels(
97
+ "table",
98
+ {
99
+ loading: "Loading…",
100
+ error: "Could not load",
101
+ empty: "Nothing here yet",
102
+ sortAsc: "Sort ascending",
103
+ sortDesc: "Sort descending",
104
+ sortClear: "Clear sorting",
105
+ filter: "Show only",
106
+ showAll: "Show all",
107
+ columns: "Columns",
108
+ exportCsv: "Export CSV",
109
+ selectAll: "Select every row",
110
+ shortcutsGroup: "Table",
111
+ filterColumn: "Filter {column}",
112
+ filterSearch: "Search values",
113
+ filterAll: "All",
114
+ filterNone: "None",
115
+ filterInvert: "Invert",
116
+ filterOnly: "Only",
117
+ filterOnlyShown: "Only these {count}",
118
+ filterAddShown: "Add these {count}",
119
+ filterNoValues: "No values match",
120
+ filterNothingShown: "none",
121
+ clearFilter: "Clear the {column} filter",
122
+ clearFilters: "Clear all",
123
+ noMatches: "No rows match the filters",
124
+ resetFilters: "Reset filters",
125
+ rowCount: "{shown} of {total}",
126
+ rowsTotal: "{total} rows",
127
+ selectedCount: "{count} selected",
128
+ clearSelection: "Clear selection",
129
+ pageSelected: "All {count} on this page are selected.",
130
+ selectAllMatching: "Select all {total}",
131
+ allMatchingSelected: "All {total} are selected."
132
+ },
133
+ () => props.labels
134
+ );
135
+ const text = computed(() => ({
136
+ ...labelSet.value,
137
+ loading: props.loadingLabel ?? labelSet.value.loading,
138
+ error: props.errorLabel ?? labelSet.value.error,
139
+ empty: props.emptyLabel ?? labelSet.value.empty,
140
+ sortAsc: props.sortAscLabel ?? labelSet.value.sortAsc,
141
+ sortDesc: props.sortDescLabel ?? labelSet.value.sortDesc,
142
+ sortClear: props.sortClearLabel ?? labelSet.value.sortClear,
143
+ filter: props.filterLabel ?? labelSet.value.filter,
144
+ showAll: props.showAllLabel ?? labelSet.value.showAll,
145
+ columns: props.columnsLabel ?? labelSet.value.columns
146
+ }));
53
147
  const attrs = useAttrs();
54
148
  const rootClass = computed(() => attrs.class);
55
149
  const scrollAttrs = computed(() => {
@@ -60,7 +154,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
60
154
  function keyFor(row, index) {
61
155
  if (typeof props.rowKey === "function") return props.rowKey(row);
62
156
  if (props.rowKey) return row[props.rowKey];
63
- return index;
157
+ return sourceIndex.value.get(row) ?? index;
64
158
  }
65
159
  function alignClass(align) {
66
160
  if (align === "right") return "text-right";
@@ -72,6 +166,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
72
166
  menuRow.value = row;
73
167
  }
74
168
  const contextMenu = computed(() => {
169
+ if (paint.painting.value) return [];
75
170
  const table = tableMenu();
76
171
  const row = menuRow.value ? props.rowMenu?.(menuRow.value) ?? [] : [];
77
172
  if (!row.length) return table;
@@ -79,7 +174,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
79
174
  return [...row, { ...table[0], separatorBefore: true }, ...table.slice(1)];
80
175
  });
81
176
  const ownSort = ref(null);
82
- const activeSort = computed(() => props.sort ?? ownSort.value);
177
+ const activeSort = computed(() => props.sort !== void 0 ? props.sort : ownSort.value);
83
178
  const loaded = shallowRef([]);
84
179
  const total = ref(0);
85
180
  const facets = ref({});
@@ -88,11 +183,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
88
183
  const task = useAsyncTask();
89
184
  const loading = task.pending;
90
185
  const sourceRows = computed(() => props.load ? loaded.value : props.rows);
91
- const tableEl = ref(null);
186
+ const sourceIndex = computed(() => new Map(sourceRows.value.map((row, i) => [row, i])));
187
+ const frameEl = ref(null);
92
188
  const floor = ref(0);
93
189
  async function holdHeight() {
94
190
  await nextTick();
95
- const height = tableEl.value?.offsetHeight ?? 0;
191
+ const height = frameEl.value?.querySelector("table")?.offsetHeight ?? 0;
96
192
  if (height > floor.value) floor.value = height;
97
193
  }
98
194
  const hiddenValues = ref({});
@@ -119,20 +215,46 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
119
215
  }
120
216
  return seen;
121
217
  }
122
- function isValueHidden(key, value) {
123
- return hiddenValues.value[key]?.has(value) ?? false;
218
+ function showAllValues(key) {
219
+ withMotion(() => hiddenValues.value = { ...hiddenValues.value, [key]: /* @__PURE__ */ new Set() });
124
220
  }
125
- function toggleValue(key, value) {
126
- withMotion(() => applyToggle(key, value));
221
+ function setHidden(key, next) {
222
+ withMotion(() => hiddenValues.value = { ...hiddenValues.value, [key]: next });
127
223
  }
128
- function applyToggle(key, value) {
129
- const next = new Set(hiddenValues.value[key] ?? []);
130
- if (next.has(value)) next.delete(value);
131
- else next.add(value);
132
- hiddenValues.value = { ...hiddenValues.value, [key]: next };
224
+ function labelOf(col, value) {
225
+ return col.valueLabel?.(value) ?? String(value ?? "—");
133
226
  }
134
- function showAllValues(key) {
135
- withMotion(() => hiddenValues.value = { ...hiddenValues.value, [key]: /* @__PURE__ */ new Set() });
227
+ function filterOptions(col) {
228
+ let counts;
229
+ if (!props.load) {
230
+ const others = Object.entries(hiddenValues.value).filter(([key, set]) => key !== col.key && set.size);
231
+ const rows = others.length ? props.rows.filter((row) => others.every(([key, hidden]) => !hidden.has(row[key]))) : props.rows;
232
+ counts = countValues(rows, col.key);
233
+ }
234
+ return valuesOf(col).map((value) => ({ value, label: labelOf(col, value), count: counts?.get(value) ?? (counts ? 0 : void 0) }));
235
+ }
236
+ const activeFilters = computed(
237
+ () => props.columns.filter((col) => col.filterable && hiddenValues.value[col.key]?.size).map((col) => {
238
+ const hidden = hiddenValues.value[col.key];
239
+ const shown = valuesOf(col).filter((v) => !hidden.has(v)).map((v) => labelOf(col, v));
240
+ return { col, text: shown.length ? summarizeShown(shown) : text.value.filterNothingShown };
241
+ })
242
+ );
243
+ function clearAllFilters() {
244
+ withMotion(() => hiddenValues.value = {});
245
+ }
246
+ function filterLabels() {
247
+ const t = text.value;
248
+ return {
249
+ search: t.filterSearch,
250
+ all: t.filterAll,
251
+ none: t.filterNone,
252
+ invert: t.filterInvert,
253
+ only: t.filterOnly,
254
+ onlyShown: t.filterOnlyShown,
255
+ addShown: t.filterAddShown,
256
+ noValues: t.filterNoValues
257
+ };
136
258
  }
137
259
  function toggleColumn(key) {
138
260
  const next = new Set(hiddenColumns.value);
@@ -148,21 +270,17 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
148
270
  (row) => active.every(([key, hidden]) => !hidden.has(row[key]))
149
271
  );
150
272
  });
151
- const displayRows = computed(() => {
273
+ function sortRows(rows) {
152
274
  const s = activeSort.value;
153
- if (!s || props.load) return filteredRows.value;
275
+ if (!s || props.load) return rows;
154
276
  const col = props.columns.find((c) => c.key === s.key);
155
- if (!col?.sortable) return filteredRows.value;
277
+ if (!col?.sortable) return rows;
156
278
  const factor = s.dir === "asc" ? 1 : -1;
157
- return [...filteredRows.value].sort((a, b) => compare(a[s.key], b[s.key]) * factor);
158
- });
159
- function compare(a, b) {
160
- if (a == null && b == null) return 0;
161
- if (a == null) return -1;
162
- if (b == null) return 1;
163
- if (typeof a === "number" && typeof b === "number") return a - b;
164
- return String(a).localeCompare(String(b), void 0, { numeric: true });
279
+ const own = col.compare;
280
+ const value = col.sortValue ?? ((row) => row[s.key]);
281
+ return [...rows].sort((a, b) => (own ? own(a, b) : compareValues(value(a), value(b))) * factor);
165
282
  }
283
+ const displayRows = computed(() => sortRows(filteredRows.value));
166
284
  function toggleSort(col) {
167
285
  if (!col.sortable) return;
168
286
  const s = activeSort.value;
@@ -180,6 +298,15 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
180
298
  if (s?.key !== col.key) return "lucide:chevrons-up-down";
181
299
  return s.dir === "asc" ? "lucide:arrow-up" : "lucide:arrow-down";
182
300
  }
301
+ function openFilter(key) {
302
+ const open = () => frameEl.value?.querySelector(`[data-lp-filter="${CSS.escape(key)}"]`)?.click();
303
+ const started = performance.now();
304
+ const wait = () => {
305
+ if (!document.querySelector("[data-reka-menu-content]") || performance.now() - started > 600) setTimeout(open, 30);
306
+ else requestAnimationFrame(wait);
307
+ };
308
+ requestAnimationFrame(wait);
309
+ }
183
310
  function headerMenu(col) {
184
311
  const s = activeSort.value;
185
312
  const set = (next) => () => withMotion(() => {
@@ -190,19 +317,19 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
190
317
  if (col.sortable) {
191
318
  items.push(
192
319
  {
193
- label: props.sortAscLabel,
320
+ label: text.value.sortAsc,
194
321
  icon: "lucide:arrow-up",
195
322
  disabled: s?.key === col.key && s.dir === "asc",
196
323
  onSelect: set({ key: col.key, dir: "asc" })
197
324
  },
198
325
  {
199
- label: props.sortDescLabel,
326
+ label: text.value.sortDesc,
200
327
  icon: "lucide:arrow-down",
201
328
  disabled: s?.key === col.key && s.dir === "desc",
202
329
  onSelect: set({ key: col.key, dir: "desc" })
203
330
  },
204
331
  {
205
- label: props.sortClearLabel,
332
+ label: text.value.sortClear,
206
333
  icon: "lucide:x",
207
334
  disabled: !s,
208
335
  onSelect: set(null)
@@ -211,34 +338,31 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
211
338
  }
212
339
  if (col.filterable) {
213
340
  const hidden = hiddenValues.value[col.key];
214
- items.push({
215
- label: props.filterLabel,
216
- icon: "lucide:filter",
217
- separatorBefore: items.length > 0,
218
- children: [
219
- ...valuesOf(col).map((value) => ({
220
- label: col.valueLabel?.(value) ?? String(value ?? "—"),
221
- checked: !isValueHidden(col.key, value),
222
- onSelect: () => toggleValue(col.key, value)
223
- })),
224
- {
225
- label: props.showAllLabel,
226
- icon: "lucide:list",
227
- separatorBefore: true,
228
- disabled: !hidden?.size,
229
- onSelect: () => showAllValues(col.key)
230
- }
231
- ]
232
- });
341
+ items.push(
342
+ {
343
+ label: text.value.filterColumn.replace("{column}", col.label),
344
+ icon: "lucide:filter",
345
+ separatorBefore: items.length > 0,
346
+ onSelect: () => openFilter(col.key)
347
+ },
348
+ {
349
+ label: text.value.showAll,
350
+ icon: "lucide:list",
351
+ disabled: !hidden?.size,
352
+ onSelect: () => showAllValues(col.key)
353
+ }
354
+ );
233
355
  }
234
356
  return items;
235
357
  }
236
358
  function tableMenu() {
237
359
  const offered = props.columns.filter((c) => !c.alwaysVisible && c.label);
238
- if (!offered.length) return [];
360
+ const exportItem = props.exportable ? [{ label: text.value.exportCsv, icon: "lucide:download", onSelect: () => exportCsv() }] : [];
361
+ if (!offered.length) return exportItem;
239
362
  return [
363
+ ...exportItem,
240
364
  {
241
- label: props.columnsLabel,
365
+ label: text.value.columns,
242
366
  icon: "lucide:columns-3",
243
367
  children: offered.map((col) => ({
244
368
  label: col.label,
@@ -261,6 +385,11 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
261
385
  task.run((signal) => load(query, signal), {
262
386
  delay,
263
387
  apply: (result) => {
388
+ const last = Math.max(1, Math.ceil(result.total / props.pageSize));
389
+ if (page.value > last) {
390
+ page.value = last;
391
+ return;
392
+ }
264
393
  loaded.value = result.rows;
265
394
  total.value = result.total;
266
395
  facets.value = result.facets ?? {};
@@ -278,10 +407,64 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
278
407
  else fetchPage(props.debounce);
279
408
  });
280
409
  watch(page, () => fetchPage());
410
+ const storageKey = computed(() => props.persist ? `lp-table:${props.persist}` : "");
411
+ const restored = ref(false);
412
+ onMounted(() => {
413
+ if (storageKey.value) {
414
+ let raw = null;
415
+ try {
416
+ raw = localStorage.getItem(storageKey.value);
417
+ } catch {
418
+ }
419
+ const state = parseTableState(raw, props.columns.map((c) => c.key));
420
+ if (state) {
421
+ if (state.sort !== void 0) {
422
+ ownSort.value = state.sort;
423
+ emit("update:sort", state.sort);
424
+ }
425
+ if (state.hidden) {
426
+ hiddenValues.value = Object.fromEntries(Object.entries(state.hidden).map(([k, v]) => [k, new Set(v)]));
427
+ }
428
+ if (state.columns) hiddenColumns.value = new Set(state.columns);
429
+ }
430
+ }
431
+ restored.value = true;
432
+ });
433
+ watch([activeSort, hiddenValues, hiddenColumns], () => {
434
+ if (!storageKey.value || !restored.value) return;
435
+ const state = serializeTableState({
436
+ sort: activeSort.value,
437
+ hidden: Object.fromEntries(Object.entries(hiddenValues.value).map(([k, v]) => [k, [...v]])),
438
+ columns: [...hiddenColumns.value]
439
+ });
440
+ try {
441
+ localStorage.setItem(storageKey.value, state);
442
+ } catch {
443
+ }
444
+ });
281
445
  watch(() => props.load, () => fetchPage(), { immediate: true });
282
- __expose({ reload: () => fetchPage() });
446
+ function exportCsv(options = {}) {
447
+ const scope = options.scope ?? "filtered";
448
+ let rows;
449
+ if (scope === "all") rows = sortRows(sourceRows.value);
450
+ else if (scope === "selected") {
451
+ const keys = new Set(props.selected);
452
+ rows = sortRows(sourceRows.value).filter((row, i) => keys.has(keyFor(row, i)));
453
+ } else rows = displayRows.value;
454
+ const columns = visibleColumns.value.filter((col) => col.label).map((col) => ({
455
+ key: col.key,
456
+ label: col.label,
457
+ value: col.exportValue ?? ((row) => row[col.key])
458
+ }));
459
+ const csv = toCsv(rows, columns, options);
460
+ if (options.download !== false) {
461
+ downloadFile(`${fileStem(options.filename ?? props.exportFilename, "table")}.csv`, csv, "text/csv;charset=utf-8");
462
+ }
463
+ return csv;
464
+ }
465
+ __expose({ reload: () => fetchPage(), exportCsv });
283
466
  const selectedSet = computed(() => new Set(props.selected));
284
- const allKeys = computed(() => sourceRows.value.map((r, i) => keyFor(r, i)));
467
+ const allKeys = computed(() => filteredRows.value.map((r, i) => keyFor(r, i)));
285
468
  const allChecked = computed(
286
469
  () => allKeys.value.length > 0 && allKeys.value.every((k) => selectedSet.value.has(k))
287
470
  );
@@ -289,7 +472,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
289
472
  () => !allChecked.value && allKeys.value.some((k) => selectedSet.value.has(k))
290
473
  );
291
474
  function toggleAll(checked) {
292
- emit("update:selected", checked ? [...allKeys.value] : []);
475
+ const next = new Set(selectedSet.value);
476
+ for (const key of allKeys.value) {
477
+ if (checked) next.add(key);
478
+ else next.delete(key);
479
+ }
480
+ emit("update:selected", [...next]);
293
481
  }
294
482
  function toggleRow(key, checked) {
295
483
  const next = new Set(selectedSet.value);
@@ -297,7 +485,73 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
297
485
  else next.delete(key);
298
486
  emit("update:selected", [...next]);
299
487
  }
300
- const colSpan = computed(() => props.columns.length + (props.selectable ? 1 : 0));
488
+ const keyByText = computed(
489
+ () => new Map(displayRows.value.map((row, index) => [String(keyFor(row, index)), keyFor(row, index)]))
490
+ );
491
+ const paint = usePaintSelect({
492
+ root: frameEl,
493
+ enabled: () => !!props.selectable,
494
+ selection: () => props.selected,
495
+ set: (keys) => emit("update:selected", keys),
496
+ resolve: (raw) => keyByText.value.get(raw),
497
+ selectAll: () => [.../* @__PURE__ */ new Set([...props.selected, ...allKeys.value])],
498
+ help: () => ({ group: text.value.shortcutsGroup, label: text.value.selectAll })
499
+ });
500
+ const holdMode = computed(() => props.selectable === "hold");
501
+ const ticksShown = computed(
502
+ () => props.selectable === true || props.selected.length > 0 || paint.painting.value
503
+ );
504
+ function clearSelection() {
505
+ emit("update:selected", []);
506
+ if (props.allMatching) emit("update:allMatching", false);
507
+ }
508
+ const OWN_CLICKS = "a,button,input,select,textarea,label,[role=button],[role=checkbox],[contenteditable=true]";
509
+ function onRowPointerDown(event, key) {
510
+ if (!holdMode.value) return;
511
+ if (event.target?.closest(OWN_CLICKS)) return;
512
+ paint.onPointerDown(event, key, { hold: 420 });
513
+ }
514
+ function onRowClick(row, key) {
515
+ if (holdMode.value && props.selected.length) toggleRow(key, !selectedSet.value.has(key));
516
+ else emit("rowClick", row);
517
+ }
518
+ useHotkeys(
519
+ () => props.selectable && props.selected.length ? [
520
+ {
521
+ key: "escape",
522
+ help: { group: text.value.shortcutsGroup, label: text.value.clearSelection },
523
+ handler: () => clearSelection()
524
+ }
525
+ ] : [],
526
+ { scope: frameEl }
527
+ );
528
+ const pageKeys = computed(() => displayRows.value.map((row, i) => keyFor(row, i)));
529
+ const pageAllSelected = computed(
530
+ () => pageKeys.value.length > 0 && pageKeys.value.every((k) => selectedSet.value.has(k))
531
+ );
532
+ watch(pageAllSelected, (all) => {
533
+ if (!all && props.allMatching) emit("update:allMatching", false);
534
+ });
535
+ const statusText = computed(() => {
536
+ if (!(props.selectable && props.selected.length)) return countText.value;
537
+ return props.allMatching ? text.value.allMatchingSelected.replace("{total}", String(total.value)) : text.value.selectedCount.replace("{count}", String(props.selected.length));
538
+ });
539
+ const countText = computed(() => {
540
+ const t = text.value;
541
+ if (props.load) return t.rowsTotal.replace("{total}", String(total.value));
542
+ if (displayRows.value.length !== props.rows.length) {
543
+ return t.rowCount.replace("{shown}", String(displayRows.value.length)).replace("{total}", String(props.rows.length));
544
+ }
545
+ return t.rowsTotal.replace("{total}", String(props.rows.length));
546
+ });
547
+ const showBar = computed(() => props.summary || !!props.selectable || activeFilters.value.length > 0);
548
+ const filteredOut = computed(() => {
549
+ if (loading.value || failed.value || displayRows.value.length) return false;
550
+ if (props.load) return Object.values(hiddenValues.value).some((set) => set.size);
551
+ return props.rows.length > 0;
552
+ });
553
+ const cellY = computed(() => props.density === "compact" ? "py-1.5" : "py-3");
554
+ const colSpan = computed(() => visibleColumns.value.length + (props.selectable ? 1 : 0));
301
555
  const rovingItems = computed(
302
556
  () => displayRows.value.map((row, index) => ({
303
557
  id: String(keyFor(row, index)),
@@ -357,46 +611,161 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
357
611
  );
358
612
  return (_ctx, _cache) => {
359
613
  return openBlock(), createElementBlock("div", {
614
+ ref_key: "frameEl",
615
+ ref: frameEl,
360
616
  class: normalizeClass(["flex flex-col gap-3", rootClass.value])
361
617
  }, [
362
- createVNode(_sfc_main$1, mergeProps(scrollAttrs.value, {
618
+ __props.exportable ? (openBlock(), createElementBlock("div", _hoisted_1, [
619
+ createVNode(_sfc_main$1, {
620
+ variant: "ghost",
621
+ size: "sm",
622
+ onClick: _cache[0] || (_cache[0] = ($event) => exportCsv())
623
+ }, {
624
+ default: withCtx(() => [
625
+ createVNode(_sfc_main$2, {
626
+ name: "lucide:download",
627
+ size: 14
628
+ }),
629
+ createTextVNode(" " + toDisplayString(text.value.exportCsv), 1)
630
+ ]),
631
+ _: 1
632
+ })
633
+ ])) : createCommentVNode("", true),
634
+ createVNode(_sfc_main$3, { class: "-mb-3" }, {
635
+ default: withCtx(() => [
636
+ showBar.value ? (openBlock(), createElementBlock("div", _hoisted_2, [
637
+ activeFilters.value.length ? (openBlock(), createElementBlock("div", _hoisted_3, [
638
+ (openBlock(true), createElementBlock(Fragment, null, renderList(activeFilters.value, (f) => {
639
+ return openBlock(), createElementBlock("span", {
640
+ key: f.col.key,
641
+ class: "inline-flex max-w-72 animate-[chip-in_var(--duration-fast)_var(--ease-emphasized)] items-center gap-1 rounded-pill bg-brand-soft py-0.5 pr-1 pl-2.5 text-ink motion-reduce:animate-none"
642
+ }, [
643
+ createElementVNode("span", _hoisted_4, [
644
+ createElementVNode("span", _hoisted_5, toDisplayString(f.col.label) + ":", 1),
645
+ createTextVNode(" " + toDisplayString(f.text), 1)
646
+ ]),
647
+ createElementVNode("button", {
648
+ type: "button",
649
+ class: "grid size-4 shrink-0 place-items-center rounded-pill text-muted outline-none transition-colors duration-fast hover:bg-ink/10 hover:text-ink focus-visible:ring-2 focus-visible:ring-ring",
650
+ "aria-label": text.value.clearFilter.replace("{column}", f.col.label),
651
+ onClick: ($event) => showAllValues(f.col.key)
652
+ }, [
653
+ createVNode(_sfc_main$2, {
654
+ name: "lucide:x",
655
+ size: 12
656
+ })
657
+ ], 8, _hoisted_6)
658
+ ]);
659
+ }), 128)),
660
+ activeFilters.value.length > 1 ? (openBlock(), createElementBlock("button", {
661
+ key: 0,
662
+ type: "button",
663
+ class: "rounded-control px-1.5 py-0.5 font-medium text-muted outline-none transition-colors duration-fast hover:text-ink focus-visible:ring-2 focus-visible:ring-ring",
664
+ onClick: clearAllFilters
665
+ }, toDisplayString(text.value.clearFilters), 1)) : createCommentVNode("", true)
666
+ ])) : createCommentVNode("", true),
667
+ createVNode(_sfc_main$3, {
668
+ axis: "width",
669
+ class: "ml-auto shrink-0"
670
+ }, {
671
+ default: withCtx(() => [
672
+ createElementVNode("div", _hoisted_7, [
673
+ createVNode(_sfc_main$4, {
674
+ value: statusText.value,
675
+ align: "end",
676
+ class: normalizeClass(["tabular-nums", __props.selectable && __props.selected.length ? "font-medium text-ink" : ""]),
677
+ "aria-live": "polite"
678
+ }, null, 8, ["value", "class"]),
679
+ createVNode(Transition, {
680
+ "enter-active-class": "transition-opacity duration-fast motion-reduce:transition-none",
681
+ "leave-active-class": "transition-opacity duration-fast motion-reduce:transition-none",
682
+ "enter-from-class": "opacity-0",
683
+ "leave-to-class": "opacity-0"
684
+ }, {
685
+ default: withCtx(() => [
686
+ __props.selectable && __props.selected.length ? (openBlock(), createElementBlock("span", _hoisted_8, [
687
+ createVNode(Transition, {
688
+ "enter-active-class": "transition-opacity duration-fast motion-reduce:transition-none",
689
+ "leave-active-class": "transition-opacity duration-fast motion-reduce:transition-none",
690
+ "enter-from-class": "opacity-0",
691
+ "leave-to-class": "opacity-0"
692
+ }, {
693
+ default: withCtx(() => [
694
+ __props.load && pageAllSelected.value && !__props.allMatching && total.value > pageKeys.value.length ? (openBlock(), createElementBlock("span", _hoisted_9, [
695
+ createElementVNode("span", _hoisted_10, toDisplayString(text.value.pageSelected.replace("{count}", String(pageKeys.value.length))), 1),
696
+ createElementVNode("button", {
697
+ type: "button",
698
+ class: "rounded-control px-1.5 py-0.5 font-medium text-brand outline-none transition-colors duration-fast hover:bg-brand-soft focus-visible:ring-2 focus-visible:ring-ring",
699
+ onClick: _cache[1] || (_cache[1] = ($event) => emit("update:allMatching", true))
700
+ }, toDisplayString(text.value.selectAllMatching.replace("{total}", String(total.value))), 1)
701
+ ])) : createCommentVNode("", true)
702
+ ]),
703
+ _: 1
704
+ }),
705
+ createElementVNode("button", {
706
+ type: "button",
707
+ class: "rounded-control px-1.5 py-0.5 font-medium outline-none transition-colors duration-fast hover:text-ink focus-visible:ring-2 focus-visible:ring-ring",
708
+ onClick: clearSelection
709
+ }, toDisplayString(text.value.clearSelection), 1),
710
+ renderSlot(_ctx.$slots, "bulk", {
711
+ selected: __props.selected,
712
+ allMatching: __props.allMatching,
713
+ clear: clearSelection
714
+ }, void 0, true)
715
+ ])) : createCommentVNode("", true)
716
+ ]),
717
+ _: 3
718
+ })
719
+ ])
720
+ ]),
721
+ _: 3
722
+ })
723
+ ])) : createCommentVNode("", true)
724
+ ]),
725
+ _: 3
726
+ }),
727
+ createVNode(_sfc_main$5, mergeProps(scrollAttrs.value, {
363
728
  fade: false,
364
729
  class: "min-h-0 flex-1 rounded-card border border-line",
365
730
  style: __props.load && floor.value ? { minHeight: `${floor.value + 2}px` } : void 0,
366
731
  "bar-inset-top": barInsetTop.value
367
732
  }), {
368
733
  default: withCtx(() => [
369
- createVNode(_sfc_main$2, {
734
+ createVNode(_sfc_main$6, {
370
735
  items: contextMenu.value,
371
736
  always: ""
372
737
  }, {
373
738
  default: withCtx(() => [
374
- createElementVNode("table", {
375
- ref_key: "tableEl",
376
- ref: tableEl,
377
- class: "w-full border-collapse text-sm"
378
- }, [
739
+ createElementVNode("table", _hoisted_11, [
379
740
  createElementVNode("thead", {
380
741
  ref_key: "headEl",
381
742
  ref: headEl,
382
743
  class: normalizeClass(__props.stickyHeader ? "sticky top-0 z-10 bg-surface-soft" : "")
383
744
  }, [
384
- createElementVNode("tr", _hoisted_1, [
385
- __props.selectable ? (openBlock(), createElementBlock("th", _hoisted_2, [
386
- createVNode(_sfc_main$3, {
387
- "model-value": allChecked.value,
388
- indeterminate: someChecked.value,
389
- "onUpdate:modelValue": toggleAll
390
- }, null, 8, ["model-value", "indeterminate"])
391
- ])) : createCommentVNode("", true),
745
+ createElementVNode("tr", _hoisted_12, [
746
+ __props.selectable ? (openBlock(), createElementBlock("th", {
747
+ key: 0,
748
+ class: normalizeClass(["w-px p-0", cellY.value])
749
+ }, [
750
+ createElementVNode("div", {
751
+ class: normalizeClass(["lp-tick lp-tick-open", ticksShown.value ? "" : "lp-tick-hidden"]),
752
+ inert: !ticksShown.value
753
+ }, [
754
+ createVNode(_sfc_main$7, {
755
+ "model-value": allChecked.value,
756
+ indeterminate: someChecked.value,
757
+ "onUpdate:modelValue": toggleAll
758
+ }, null, 8, ["model-value", "indeterminate"])
759
+ ], 10, _hoisted_13)
760
+ ], 2)) : createCommentVNode("", true),
392
761
  (openBlock(true), createElementBlock(Fragment, null, renderList(visibleColumns.value, (col) => {
393
762
  return openBlock(), createElementBlock("th", {
394
763
  key: col.key,
395
764
  style: normalizeStyle(col.width ? { width: col.width } : void 0),
396
- class: normalizeClass(["px-4 py-3 text-[11px] font-semibold uppercase tracking-[0.08em] text-muted", alignClass(col.align)]),
765
+ class: normalizeClass(["px-4 text-[11px] font-semibold uppercase tracking-[0.08em] text-muted", [alignClass(col.align), cellY.value]]),
397
766
  "aria-sort": activeSort.value?.key === col.key ? activeSort.value.dir === "asc" ? "ascending" : "descending" : void 0
398
767
  }, [
399
- col.sortable || col.filterable ? (openBlock(), createBlock(_sfc_main$2, {
768
+ col.sortable || col.filterable ? (openBlock(), createBlock(_sfc_main$6, {
400
769
  key: 0,
401
770
  items: headerMenu(col)
402
771
  }, {
@@ -410,27 +779,51 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
410
779
  onClick: ($event) => toggleSort(col)
411
780
  }, [
412
781
  createTextVNode(toDisplayString(col.label) + " ", 1),
413
- !col.sortable ? (openBlock(), createBlock(_sfc_main$4, {
782
+ col.sortable ? (openBlock(), createBlock(_sfc_main$2, {
414
783
  key: 0,
415
- name: "lucide:filter",
416
- size: 12,
417
- class: normalizeClass(["shrink-0", hiddenValues.value[col.key]?.size ? "text-brand opacity-100" : "opacity-40 group-hover/sort:opacity-70"])
418
- }, null, 8, ["class"])) : (openBlock(), createBlock(_sfc_main$4, {
419
- key: 1,
420
784
  name: sortIcon(col),
421
785
  size: 13,
422
786
  class: normalizeClass([
423
787
  "shrink-0 transition-[transform,opacity] duration-[var(--duration-fast)] ease-[var(--ease-emphasized)]",
424
788
  activeSort.value?.key === col.key ? "opacity-100" : "opacity-40 group-hover/sort:opacity-70"
425
789
  ])
426
- }, null, 8, ["name", "class"]))
427
- ], 10, _hoisted_4)
790
+ }, null, 8, ["name", "class"])) : createCommentVNode("", true)
791
+ ], 10, _hoisted_15)
428
792
  ]),
429
793
  _: 2
430
794
  }, 1032, ["items"])) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
431
795
  createTextVNode(toDisplayString(col.label), 1)
432
- ], 64))
433
- ], 14, _hoisted_3);
796
+ ], 64)),
797
+ col.filterable ? (openBlock(), createBlock(_sfc_main$8, {
798
+ key: 2,
799
+ align: "start",
800
+ "panel-class": "w-72",
801
+ "aria-label": text.value.filterColumn.replace("{column}", col.label)
802
+ }, {
803
+ trigger: withCtx(() => [
804
+ createElementVNode("button", {
805
+ type: "button",
806
+ class: normalizeClass(["ml-0.5 inline-grid size-5 place-items-center rounded align-middle outline-none transition-colors duration-fast hover:bg-surface-raised hover:text-ink focus-visible:ring-2 focus-visible:ring-ring", hiddenValues.value[col.key]?.size ? "text-brand" : "opacity-60"]),
807
+ "aria-label": text.value.filterColumn.replace("{column}", col.label),
808
+ "data-lp-filter": col.key
809
+ }, [
810
+ createVNode(_sfc_main$2, {
811
+ name: hiddenValues.value[col.key]?.size ? "lucide:filter-x" : "lucide:filter",
812
+ size: 12
813
+ }, null, 8, ["name"])
814
+ ], 10, _hoisted_16)
815
+ ]),
816
+ default: withCtx(() => [
817
+ createVNode(_sfc_main$9, {
818
+ options: filterOptions(col),
819
+ hidden: hiddenValues.value[col.key] ?? /* @__PURE__ */ new Set(),
820
+ labels: filterLabels(),
821
+ "onUpdate:hidden": (next) => setHidden(col.key, next)
822
+ }, null, 8, ["options", "hidden", "labels", "onUpdate:hidden"])
823
+ ]),
824
+ _: 2
825
+ }, 1032, ["aria-label"])) : createCommentVNode("", true)
826
+ ], 14, _hoisted_14);
434
827
  }), 128))
435
828
  ])
436
829
  ], 2),
@@ -442,18 +835,30 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
442
835
  ref: (el) => unref(roving).setContainer(el?.$el ?? null)
443
836
  }, {
444
837
  default: withCtx(() => [
445
- displayRows.value.length === 0 ? (openBlock(), createElementBlock("tr", _hoisted_5, [
838
+ displayRows.value.length === 0 ? (openBlock(), createElementBlock("tr", _hoisted_17, [
446
839
  createElementVNode("td", {
447
840
  colspan: colSpan.value,
448
841
  class: "px-4 py-10 text-center text-muted"
449
842
  }, [
450
- createVNode(_sfc_main$4, {
451
- name: unref(loading) ? "lucide:loader-circle" : failed.value ? "lucide:circle-alert" : __props.emptyIcon,
843
+ createVNode(_sfc_main$2, {
844
+ name: unref(loading) ? "lucide:loader-circle" : failed.value ? "lucide:circle-alert" : filteredOut.value ? "lucide:filter-x" : __props.emptyIcon,
452
845
  size: 22,
453
846
  class: normalizeClass(["mx-auto mb-2 opacity-60", unref(loading) ? "animate-spin" : ""])
454
847
  }, null, 8, ["name", "class"]),
455
- createElementVNode("div", null, toDisplayString(unref(loading) ? __props.loadingLabel : failed.value ? __props.errorLabel : __props.emptyLabel), 1)
456
- ], 8, _hoisted_6)
848
+ createElementVNode("div", null, toDisplayString(unref(loading) ? text.value.loading : failed.value ? text.value.error : filteredOut.value ? text.value.noMatches : text.value.empty), 1),
849
+ filteredOut.value ? (openBlock(), createBlock(_sfc_main$1, {
850
+ key: 0,
851
+ variant: "outline",
852
+ size: "sm",
853
+ class: "mt-3",
854
+ onClick: clearAllFilters
855
+ }, {
856
+ default: withCtx(() => [
857
+ createTextVNode(toDisplayString(text.value.resetFilters), 1)
858
+ ]),
859
+ _: 1
860
+ })) : createCommentVNode("", true)
861
+ ], 8, _hoisted_18)
457
862
  ])) : createCommentVNode("", true),
458
863
  (openBlock(true), createElementBlock(Fragment, null, renderList(displayRows.value, (row, index) => {
459
864
  return openBlock(), createElementBlock("tr", mergeProps({
@@ -461,24 +866,31 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
461
866
  onContextmenu: ($event) => onRowContextMenu(row),
462
867
  class: ["group border-b border-line/60 outline-none transition-colors last:border-0 hover:bg-surface-soft/60 focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring data-[active]:bg-surface-soft/40", selectedSet.value.has(keyFor(row, index)) ? "bg-brand-soft/40" : ""]
463
868
  }, { ref_for: true }, unref(roving).itemProps(String(keyFor(row, index))), {
464
- onClick: ($event) => emit("rowClick", row),
869
+ "data-paint-key": __props.selectable ? String(keyFor(row, index)) : void 0,
870
+ onClick: ($event) => onRowClick(row, keyFor(row, index)),
871
+ onPointerdown: ($event) => onRowPointerDown($event, keyFor(row, index)),
465
872
  onKeydown: onRowKeydown
466
873
  }), [
467
874
  __props.selectable ? (openBlock(), createElementBlock("td", {
468
875
  key: 0,
469
- class: "w-px px-4 py-3",
470
- onClick: _cache[0] || (_cache[0] = withModifiers(() => {
471
- }, ["stop"]))
876
+ class: normalizeClass(["w-px cursor-pointer p-0 select-none", cellY.value]),
877
+ onClick: _cache[2] || (_cache[2] = withModifiers(() => {
878
+ }, ["stop"])),
879
+ onPointerdown: withModifiers(($event) => unref(paint).onPointerDown($event, keyFor(row, index)), ["stop"])
472
880
  }, [
473
- createVNode(_sfc_main$3, {
474
- "model-value": selectedSet.value.has(keyFor(row, index)),
475
- "onUpdate:modelValue": (v) => toggleRow(keyFor(row, index), v)
476
- }, null, 8, ["model-value", "onUpdate:modelValue"])
477
- ])) : createCommentVNode("", true),
478
- (openBlock(true), createElementBlock(Fragment, null, renderList(visibleColumns.value, (col) => {
881
+ createElementVNode("div", {
882
+ class: normalizeClass(["lp-tick lp-tick-open", ticksShown.value ? "" : "lp-tick-cue"])
883
+ }, [
884
+ createVNode(_sfc_main$7, {
885
+ "model-value": selectedSet.value.has(keyFor(row, index)),
886
+ "onUpdate:modelValue": (v) => toggleRow(keyFor(row, index), v)
887
+ }, null, 8, ["model-value", "onUpdate:modelValue"])
888
+ ], 2)
889
+ ], 42, _hoisted_20)) : createCommentVNode("", true),
890
+ (openBlock(true), createElementBlock(Fragment, null, renderList(visibleColumns.value, (col, ci) => {
479
891
  return openBlock(), createElementBlock("td", {
480
892
  key: col.key,
481
- class: normalizeClass(["px-4 py-3 text-ink", alignClass(col.align)])
893
+ class: normalizeClass(["px-4 text-ink", [alignClass(col.align), cellY.value, col.nowrap ? "whitespace-nowrap" : ""]])
482
894
  }, [
483
895
  renderSlot(_ctx.$slots, `cell-${col.key}`, {
484
896
  row,
@@ -488,22 +900,22 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
488
900
  ], true)
489
901
  ], 2);
490
902
  }), 128))
491
- ], 16, _hoisted_7);
903
+ ], 16, _hoisted_19);
492
904
  }), 128))
493
905
  ]),
494
906
  _: 3
495
907
  }, 8, ["css", "class"])
496
- ], 512)
908
+ ])
497
909
  ]),
498
910
  _: 3
499
911
  }, 8, ["items"])
500
912
  ]),
501
913
  _: 3
502
914
  }, 16, ["style", "bar-inset-top"]),
503
- __props.load && total.value > __props.pageSize ? (openBlock(), createBlock(_sfc_main$5, {
504
- key: 0,
915
+ __props.load && total.value > __props.pageSize ? (openBlock(), createBlock(_sfc_main$a, {
916
+ key: 1,
505
917
  page: page.value,
506
- "onUpdate:page": _cache[1] || (_cache[1] = ($event) => page.value = $event),
918
+ "onUpdate:page": _cache[3] || (_cache[3] = ($event) => page.value = $event),
507
919
  total: total.value,
508
920
  "page-size": __props.pageSize,
509
921
  disabled: unref(loading)
@@ -512,7 +924,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
512
924
  };
513
925
  }
514
926
  });
515
- const LpTable = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-e0bb036b"]]);
927
+ const LpTable = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-fff7ed10"]]);
516
928
  export {
517
929
  LpTable as default
518
930
  };