@leavepulse/ui 0.44.0 → 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 (265) hide show
  1. package/README.md +49 -3
  2. package/dist/assets/{LpCommandPalette-DCP5g2ik.css → LpCommandPalette-nGNnzXqQ.css} +21 -21
  3. package/dist/assets/{LpRollingText-CR1mb0Vt.css → LpRollingText-BGnE6q9j.css} +3 -0
  4. package/dist/assets/{LpShortcutsDialog-ChUyU7oV.css → LpShortcutsDialog-CqYX3yy6.css} +28 -7
  5. package/dist/assets/{LpTable-DDQNdf86.css → LpTable-CPwWxTJS.css} +49 -9
  6. package/dist/chunks/{ContextMenuItems-CrfeNPWT.js → ContextMenuItems-BtKU7074.js} +2 -1
  7. package/dist/chunks/{LayoutCanvas-D-jPOAvg.js → LayoutCanvas-BkaGXTjx.js} +1 -1
  8. package/dist/chunks/{LayoutNode-D8Xy9N-o.js → LayoutNode-B3_9E1Xa.js} +9 -5
  9. package/dist/chunks/{LpActionBar-BbwCF6l5.js → LpActionBar-CnfFVIwC.js} +3 -3
  10. package/dist/chunks/{LpAddressInput-BrOqkZqg.js → LpAddressInput-BwX8uo4_.js} +7 -7
  11. package/dist/chunks/{LpAlert-DkOIjsbq.js → LpAlert-B6ilrM7T.js} +1 -1
  12. package/dist/chunks/{LpAppShell-BUKPcHco.js → LpAppShell-C53_RaGF.js} +4 -4
  13. package/dist/chunks/{LpAutocomplete-DxV3Y9h4.js → LpAutocomplete-C8IgSMsi.js} +2 -1
  14. package/dist/chunks/{LpAvatar-ClBbEYZN.js → LpAvatar-C1XStdOo.js} +3 -3
  15. package/dist/chunks/{LpBreadcrumbs-B8IJgFIc.js → LpBreadcrumbs-CQJd73Gm.js} +1 -1
  16. package/dist/chunks/{LpButton-kqJBHIIb.js → LpButton-CKSwC6Mu.js} +1 -1
  17. package/dist/chunks/{LpCalendar-B7Ko5RdR.js → LpCalendar-DrA2McTU.js} +1 -1
  18. package/dist/chunks/{LpCard-CpRByR0q.js → LpCard-C2IvucmX.js} +1 -1
  19. package/dist/chunks/{LpCheckbox-DpqchzH4.js → LpCheckbox-Bkj13CbW.js} +1 -1
  20. package/dist/chunks/{LpCodeBlock-DeHJPq7p.js → LpCodeBlock-ca7ANFyW.js} +1 -1
  21. package/dist/chunks/{LpColorPicker-Bhf1qxhB.js → LpColorPicker-zz4VGkG4.js} +46 -20
  22. package/dist/chunks/{LpConfirmDialog-CIUOSnWo.js → LpConfirmDialog-DCw5jR1t.js} +3 -3
  23. package/dist/chunks/{LpConfirmHost-CDm0Wtpv.js → LpConfirmHost-CbywMpMP.js} +1 -1
  24. package/dist/chunks/{LpContextMenu-DQw5dGfG.js → LpContextMenu-BqkAYa9X.js} +2 -1
  25. package/dist/chunks/{LpDatePicker-Drirx1AK.js → LpDatePicker-DuusgT69.js} +13 -9
  26. package/dist/chunks/LpDateRangePicker-DHeuznfC.js +208 -0
  27. package/dist/chunks/{LpDisclosure-ChQYmjlR.js → LpDisclosure-Cc23-JOT.js} +1 -1
  28. package/dist/chunks/{LpDrawer-bScx-KMO.js → LpDrawer-Dt4aB4Fr.js} +2 -2
  29. package/dist/chunks/{LpDropdownMenu-DJpoqRCb.js → LpDropdownMenu-DdJGQzPn.js} +2 -1
  30. package/dist/chunks/{LpEmptyState-Dsdqz1Wj.js → LpEmptyState-BJbZXC8D.js} +1 -1
  31. package/dist/chunks/LpFieldNotice-wtieLUTj.js +64 -0
  32. package/dist/chunks/{LpFileTree-CSI_5SK2.js → LpFileTree-CNurOvkV.js} +3 -3
  33. package/dist/chunks/{LpFileTreeNode-B4MiSQX2.js → LpFileTreeNode-D_qRRdsH.js} +3 -3
  34. package/dist/chunks/{LpFormField-CIk5qosh.js → LpFormField-CtVYj6tO.js} +29 -15
  35. package/dist/chunks/{LpIcon-CCnX5_2j.js → LpIcon-DYtaid0K.js} +20 -6
  36. package/dist/chunks/{LpInput-C0e8y8_d.js → LpInput-D-YGQbEv.js} +39 -16
  37. package/dist/chunks/{LpLightbox-Mr0W_6HK.js → LpLightbox-DSDahF23.js} +1 -1
  38. package/dist/chunks/{LpLogViewer-YBOaFnc_.js → LpLogViewer-KypbgOyo.js} +252 -58
  39. package/dist/chunks/{LpMapPicker-NUzS9e37.js → LpMapPicker-Cc84LaM3.js} +1 -1
  40. package/dist/chunks/{LpMediaGallery-DfJmMW0I.js → LpMediaGallery-YKr-cQPN.js} +2 -2
  41. package/dist/chunks/{LpModal-DPwGKBPv.js → LpModal-DMMDQHAu.js} +3 -3
  42. package/dist/chunks/{LpModalNav-DPg5H9f3.js → LpModalNav-BVPDyIup.js} +4 -4
  43. package/dist/chunks/{LpNotificationBell-t5yn-siX.js → LpNotificationBell-CCwyJP5C.js} +26 -14
  44. package/dist/chunks/{LpNumberField-DWnQKktS.js → LpNumberField-B77O-z28.js} +1 -1
  45. package/dist/chunks/{LpPagination-DFngX7Xo.js → LpPagination-BcDlo3r_.js} +1 -1
  46. package/dist/chunks/{LpPasswordInput-CWVDuBJ5.js → LpPasswordInput-eKzQhbQP.js} +2 -2
  47. package/dist/chunks/{LpPhoneInput-CD-ZTeSd.js → LpPhoneInput-BCbrrhgE.js} +126 -23
  48. package/dist/chunks/{LpPie-BLco31Nx.js → LpPie-BEJ2SfI6.js} +9 -10
  49. package/dist/chunks/{LpPopover-p_e_shN3.js → LpPopover-DCKeqiVn.js} +1 -0
  50. package/dist/chunks/LpRangeCalendar-DZuaRV0W.js +331 -0
  51. package/dist/chunks/{LpRollingText-CM5gkSeF.js → LpRollingText-DB7upf-5.js} +1 -1
  52. package/dist/chunks/{LpScrollArea-D8xyKXcF.js → LpScrollArea-Bry1fdOM.js} +14 -2
  53. package/dist/chunks/{LpSection-aM6J_u51.js → LpSection-tKEH0jYf.js} +1 -1
  54. package/dist/chunks/{LpSegmented-Dejd7cIx.js → LpSegmented-C09EEam2.js} +1 -1
  55. package/dist/chunks/{LpSelect-DrRD9I7L.js → LpSelect-DNIL6MB9.js} +20 -23
  56. package/dist/chunks/{LpSidebar-BgwUNWpJ.js → LpSidebar-CQNB0-yU.js} +3 -3
  57. package/dist/chunks/{LpSidebarNav-Bqxz8aWT.js → LpSidebarNav-kx-LdqNU.js} +3 -3
  58. package/dist/chunks/{LpStat-dXtyrdX9.js → LpStat-B-7udBRP.js} +1 -1
  59. package/dist/chunks/{LpStepper-Bk-XaQYU.js → LpStepper-C7XiVKZj.js} +34 -19
  60. package/dist/chunks/{LpSwitch-B1aLKulj.js → LpSwitch-OrcOJX9m.js} +1 -1
  61. package/dist/chunks/LpTableFilter-BV8PpLM9.js +158 -0
  62. package/dist/chunks/{LpTabs-_qMVaZJ6.js → LpTabs-29iW1XOx.js} +1 -1
  63. package/dist/chunks/LpTagsInput-D1SuqbhB.js +300 -0
  64. package/dist/chunks/{LpTextarea-yP8hGedR.js → LpTextarea-uuScWo6-.js} +1 -1
  65. package/dist/chunks/{LpThemeProvider-Wjm7Tuit.js → LpThemeProvider-Be4r2TQX.js} +1 -1
  66. package/dist/chunks/{LpThemeSwitcher-CKLc10KZ.js → LpThemeSwitcher-B4aVPbNC.js} +19 -22
  67. package/dist/chunks/{LpTimeField-C5HRgS5H.js → LpTimeField-Cqe7fXnh.js} +1 -1
  68. package/dist/chunks/{LpToaster--oT6lfhL.js → LpToaster-DpJvoCOh.js} +37 -3
  69. package/dist/chunks/{LpTooltip-CBdzeKNf.js → LpTooltip-CXVKcOXT.js} +3 -2
  70. package/dist/chunks/{LpTopologyCanvas-DocsLal3.js → LpTopologyCanvas-6ozNrQKh.js} +2 -1
  71. package/dist/chunks/{LpUptimeBar-DLtxOMRy.js → LpUptimeBar-ugcv25xj.js} +2 -2
  72. package/dist/chunks/icons-CkA0njzm.js +43 -0
  73. package/dist/chunks/{useTheme-C8JHUlPM.js → useTheme-DJm1JSsY.js} +47 -50
  74. package/dist/component-names.d.ts +1 -1
  75. package/dist/components/ContextMenuItems.vue.js +1 -1
  76. package/dist/components/LayoutCanvas.vue.js +1 -1
  77. package/dist/components/LayoutNode.vue.js +1 -1
  78. package/dist/components/LpActionBar.vue.js +1 -1
  79. package/dist/components/LpAddressInput.vue.js +1 -1
  80. package/dist/components/LpAlert.vue.js +1 -1
  81. package/dist/components/LpAppShell.vue.js +1 -1
  82. package/dist/components/LpAutocomplete.vue.js +1 -1
  83. package/dist/components/LpAvatar.vue.js +1 -1
  84. package/dist/components/LpBreadcrumbs.vue.js +1 -1
  85. package/dist/components/LpButton.vue.d.ts +2 -2
  86. package/dist/components/LpButton.vue.js +1 -1
  87. package/dist/components/LpCalendar.vue.js +1 -1
  88. package/dist/components/LpCard.vue.js +1 -1
  89. package/dist/components/LpChart.vue.d.ts +16 -1
  90. package/dist/components/LpChart.vue.js +63 -5
  91. package/dist/components/LpCheckbox.vue.js +1 -1
  92. package/dist/components/LpCodeBlock.vue.js +1 -1
  93. package/dist/components/LpColorPicker.vue.d.ts +2 -2
  94. package/dist/components/LpColorPicker.vue.js +1 -1
  95. package/dist/components/LpCommandPalette.vue.d.ts +6 -0
  96. package/dist/components/LpCommandPalette.vue.js +61 -10
  97. package/dist/components/LpConfirmDialog.vue.js +1 -1
  98. package/dist/components/LpConfirmHost.vue.js +1 -1
  99. package/dist/components/LpContextMenu.vue.js +1 -1
  100. package/dist/components/LpDatePicker.vue.js +1 -1
  101. package/dist/components/LpDateRangePicker.vue.d.ts +60 -0
  102. package/dist/components/LpDateRangePicker.vue.js +4 -0
  103. package/dist/components/LpDisclosure.vue.js +1 -1
  104. package/dist/components/LpDrawer.vue.js +1 -1
  105. package/dist/components/LpDropdownMenu.vue.js +1 -1
  106. package/dist/components/LpDropzone.vue.js +1 -1
  107. package/dist/components/LpEmptyState.vue.js +1 -1
  108. package/dist/components/LpFieldNotice.vue.d.ts +8 -0
  109. package/dist/components/LpFieldNotice.vue.js +4 -0
  110. package/dist/components/LpFileTree.vue.js +1 -1
  111. package/dist/components/LpFileTreeNode.vue.js +1 -1
  112. package/dist/components/LpFormField.vue.d.ts +4 -1
  113. package/dist/components/LpFormField.vue.js +1 -1
  114. package/dist/components/LpIcon.vue.d.ts +0 -1
  115. package/dist/components/LpIcon.vue.js +1 -1
  116. package/dist/components/LpImageEditor.vue.js +2 -2
  117. package/dist/components/LpInput.vue.d.ts +19 -0
  118. package/dist/components/LpInput.vue.js +1 -1
  119. package/dist/components/LpLightbox.vue.js +1 -1
  120. package/dist/components/LpLogViewer.vue.d.ts +52 -1
  121. package/dist/components/LpLogViewer.vue.js +1 -1
  122. package/dist/components/LpMapPicker.vue.js +1 -1
  123. package/dist/components/LpMediaGallery.vue.js +1 -1
  124. package/dist/components/LpModal.vue.js +1 -1
  125. package/dist/components/LpModalNav.vue.js +1 -1
  126. package/dist/components/LpNotificationBell.vue.js +1 -1
  127. package/dist/components/LpNumberField.vue.js +1 -1
  128. package/dist/components/LpPagination.vue.js +1 -1
  129. package/dist/components/LpPasswordInput.vue.js +1 -1
  130. package/dist/components/LpPhoneInput.vue.d.ts +13 -0
  131. package/dist/components/LpPhoneInput.vue.js +1 -1
  132. package/dist/components/LpPie.vue.js +1 -1
  133. package/dist/components/LpPopover.vue.js +1 -1
  134. package/dist/components/LpProgress.vue.d.ts +1 -1
  135. package/dist/components/LpRangeCalendar.vue.d.ts +51 -0
  136. package/dist/components/LpRangeCalendar.vue.js +4 -0
  137. package/dist/components/LpRollingText.vue.d.ts +1 -1
  138. package/dist/components/LpRollingText.vue.js +1 -1
  139. package/dist/components/LpScrollArea.vue.d.ts +2 -2
  140. package/dist/components/LpScrollArea.vue.js +1 -1
  141. package/dist/components/LpSection.vue.js +1 -1
  142. package/dist/components/LpSegmented.vue.js +1 -1
  143. package/dist/components/LpSelect.vue.js +1 -1
  144. package/dist/components/LpShortcutsDialog.vue.d.ts +6 -0
  145. package/dist/components/LpShortcutsDialog.vue.js +56 -14
  146. package/dist/components/LpSidebar.vue.js +1 -1
  147. package/dist/components/LpSidebarNav.vue.js +1 -1
  148. package/dist/components/LpStat.vue.js +1 -1
  149. package/dist/components/LpStepper.vue.js +1 -1
  150. package/dist/components/LpSwitch.vue.js +1 -1
  151. package/dist/components/LpTable.vue.d.ts +84 -2
  152. package/dist/components/LpTable.vue.js +481 -107
  153. package/dist/components/LpTableFilter.vue.d.ts +31 -0
  154. package/dist/components/LpTableFilter.vue.js +4 -0
  155. package/dist/components/LpTabs.vue.js +1 -1
  156. package/dist/components/LpTagsInput.vue.d.ts +77 -0
  157. package/dist/components/LpTagsInput.vue.js +4 -0
  158. package/dist/components/LpTextarea.vue.js +1 -1
  159. package/dist/components/LpThemeProvider.vue.js +1 -1
  160. package/dist/components/LpThemeSwitcher.vue.d.ts +2 -2
  161. package/dist/components/LpThemeSwitcher.vue.js +1 -1
  162. package/dist/components/LpTimeField.vue.js +1 -1
  163. package/dist/components/LpToaster.vue.js +1 -1
  164. package/dist/components/LpTooltip.vue.js +1 -1
  165. package/dist/components/LpTopologyCanvas.vue.js +1 -1
  166. package/dist/components/LpUptimeBar.vue.js +1 -1
  167. package/dist/components/chart.js +3 -2
  168. package/dist/components/commandSearch.js +3 -0
  169. package/dist/components/dateRange.d.ts +43 -0
  170. package/dist/components/dateRange.js +76 -0
  171. package/dist/components/exportData.d.ts +58 -0
  172. package/dist/components/exportData.js +165 -0
  173. package/dist/components/logSearch.d.ts +18 -0
  174. package/dist/components/logSearch.js +36 -0
  175. package/dist/components/phone.d.ts +41 -0
  176. package/dist/components/phone.js +80 -0
  177. package/dist/components/tableFilter.d.ts +36 -0
  178. package/dist/components/tableFilter.js +84 -0
  179. package/dist/components/tags.d.ts +20 -0
  180. package/dist/components/tags.js +37 -0
  181. package/dist/composables/useField.d.ts +4 -0
  182. package/dist/composables/useFieldNotice.d.ts +17 -0
  183. package/dist/composables/useFieldNotice.js +28 -0
  184. package/dist/composables/useForm.d.ts +53 -0
  185. package/dist/composables/useForm.js +207 -0
  186. package/dist/composables/useHotkeys.d.ts +65 -5
  187. package/dist/composables/useHotkeys.js +170 -9
  188. package/dist/composables/useInputMask.d.ts +59 -0
  189. package/dist/composables/useInputMask.js +170 -0
  190. package/dist/composables/usePaintSelect.d.ts +22 -0
  191. package/dist/composables/usePaintSelect.js +169 -0
  192. package/dist/composables/useShift.js +7 -2
  193. package/dist/icons-all.d.ts +1 -0
  194. package/dist/icons-all.js +3 -0
  195. package/dist/icons.d.ts +14 -1
  196. package/dist/index.d.ts +29 -3
  197. package/dist/index.js +195 -138
  198. package/dist/kit-icons.d.ts +2 -0
  199. package/dist/theme/backdrop.d.ts +12 -0
  200. package/dist/theme/presets.d.ts +0 -2
  201. package/package.json +13 -4
  202. package/src/component-names.ts +4 -0
  203. package/src/components/ContextMenuItems.vue +1 -1
  204. package/src/components/LayoutNode.vue +11 -2
  205. package/src/components/LpActionBar.vue +1 -1
  206. package/src/components/LpAutocomplete.vue +1 -0
  207. package/src/components/LpAvatar.vue +2 -2
  208. package/src/components/LpButton.vue +1 -1
  209. package/src/components/LpChart.vue +80 -1
  210. package/src/components/LpColorPicker.vue +34 -1
  211. package/src/components/LpCommandPalette.vue +81 -7
  212. package/src/components/LpContextMenu.vue +1 -1
  213. package/src/components/LpDatePicker.vue +8 -3
  214. package/src/components/LpDateRangePicker.vue +224 -0
  215. package/src/components/LpDropdownMenu.vue +1 -0
  216. package/src/components/LpFieldNotice.vue +65 -0
  217. package/src/components/LpFormField.vue +33 -4
  218. package/src/components/LpIcon.vue +22 -4
  219. package/src/components/LpInput.vue +46 -6
  220. package/src/components/LpLogViewer.vue +225 -22
  221. package/src/components/LpModal.vue +1 -1
  222. package/src/components/LpNotificationBell.vue +15 -7
  223. package/src/components/LpPhoneInput.vue +179 -20
  224. package/src/components/LpPie.vue +8 -5
  225. package/src/components/LpPopover.vue +1 -0
  226. package/src/components/LpRangeCalendar.vue +365 -0
  227. package/src/components/LpRollingText.vue +3 -0
  228. package/src/components/LpScrollArea.vue +22 -2
  229. package/src/components/LpSelect.vue +0 -0
  230. package/src/components/LpShortcutsDialog.vue +77 -8
  231. package/src/components/LpStepper.vue +23 -10
  232. package/src/components/LpSwitch.vue +1 -1
  233. package/src/components/LpTable.vue +584 -65
  234. package/src/components/LpTableFilter.vue +175 -0
  235. package/src/components/LpTagsInput.vue +364 -0
  236. package/src/components/LpThemeSwitcher.vue +19 -23
  237. package/src/components/LpToaster.vue +49 -1
  238. package/src/components/LpTooltip.vue +9 -2
  239. package/src/components/LpTopologyCanvas.vue +7 -1
  240. package/src/components/chart.ts +5 -3
  241. package/src/components/commandSearch.ts +6 -0
  242. package/src/components/dateRange.ts +134 -0
  243. package/src/components/exportData.ts +228 -0
  244. package/src/components/logSearch.ts +46 -0
  245. package/src/components/phone.ts +140 -0
  246. package/src/components/tableFilter.ts +122 -0
  247. package/src/components/tags.ts +62 -0
  248. package/src/composables/useField.ts +4 -0
  249. package/src/composables/useFieldNotice.ts +59 -0
  250. package/src/composables/useForm.ts +314 -0
  251. package/src/composables/useHotkeys.ts +269 -13
  252. package/src/composables/useInputMask.ts +254 -0
  253. package/src/composables/usePaintSelect.ts +243 -0
  254. package/src/composables/useShift.ts +13 -2
  255. package/src/iconSubset.d.mts +10 -0
  256. package/src/iconSubset.mjs +51 -0
  257. package/src/icons-all.ts +10 -0
  258. package/src/icons.ts +59 -8
  259. package/src/index.ts +37 -3
  260. package/src/kit-icons.ts +5 -0
  261. package/src/nuxt.ts +30 -2
  262. package/src/runtime/theme.plugin.ts +2 -2
  263. package/src/theme/backdrop.ts +69 -0
  264. package/src/theme/presets.ts +6 -64
  265. package/src/tokens/tokens.css +46 -0
package/src/nuxt.ts CHANGED
@@ -18,9 +18,17 @@
18
18
  * link false to skip providing NuxtLink as the kit's link component
19
19
  * exclude component names not to auto-register (e.g. ["LayoutCanvas"]
20
20
  * when the app has its own component of that name)
21
+ * icons which lucide icons render in the server pass and ship in the
22
+ * main bundle: "scan" (default) finds "lucide:*" literals in the
23
+ * app's source, "all" registers the whole set, "kit" only the
24
+ * kit's own, or a list of names. Anything else still renders,
25
+ * from a lazily loaded chunk of the bundled collection.
21
26
  */
22
- import { addComponent, addPlugin, addTemplate, createResolver, defineNuxtModule } from "@nuxt/kit"
27
+ import { readFileSync } from "node:fs"
28
+ import { createRequire } from "node:module"
29
+ import { addComponent, addPlugin, addPluginTemplate, addTemplate, createResolver, defineNuxtModule } from "@nuxt/kit"
23
30
  import { COMPONENT_NAMES } from "./component-names"
31
+ import { namesInDirs, subset } from "./iconSubset.mjs"
24
32
 
25
33
  export interface LeavepulseUiOptions {
26
34
  /** Register the SSR theme plugin. Disable to wire theming yourself. */
@@ -33,17 +41,28 @@ export interface LeavepulseUiOptions {
33
41
  link?: boolean
34
42
  /** Component names to leave unregistered. */
35
43
  exclude?: string[]
44
+ /** Lucide icons registered up front (default "scan"). */
45
+ icons?: "scan" | "all" | "kit" | string[]
46
+ }
47
+
48
+ function iconsPlugin(mode: LeavepulseUiOptions["icons"], srcDir: string): string {
49
+ if (mode === "kit") return ""
50
+ if (mode === "all") return 'import "@leavepulse/ui/icons-all"\n'
51
+ const lucide = JSON.parse(readFileSync(createRequire(import.meta.url).resolve("@iconify-json/lucide/icons.json"), "utf8"))
52
+ const names = Array.isArray(mode) ? mode.map((n) => n.replace(/^lucide:/, "")) : namesInDirs([srcDir])
53
+ return `import { registerIconCollection } from "@leavepulse/ui"\nregisterIconCollection(${JSON.stringify(subset(lucide, names))})\n`
36
54
  }
37
55
 
38
56
  export default defineNuxtModule<LeavepulseUiOptions>({
39
57
  meta: { name: "@leavepulse/ui", configKey: "leavepulseUi" },
40
- defaults: { theme: true, link: true },
58
+ defaults: { theme: true, link: true, icons: "scan" },
41
59
  setup(
42
60
  options: LeavepulseUiOptions,
43
61
  nuxt: {
44
62
  options: {
45
63
  runtimeConfig: { public: Record<string, unknown> }
46
64
  alias: Record<string, string>
65
+ srcDir: string
47
66
  }
48
67
  hook: (
49
68
  name: "prepare:types",
@@ -64,6 +83,15 @@ export default defineNuxtModule<LeavepulseUiOptions>({
64
83
  })
65
84
  }
66
85
 
86
+ const icons = iconsPlugin(options.icons, nuxt.options.srcDir)
87
+ if (icons) {
88
+ addPluginTemplate({
89
+ filename: "leavepulse-ui-icons.mjs",
90
+ mode: "all",
91
+ getContents: () => `${icons}import { defineNuxtPlugin } from "#app"\nexport default defineNuxtPlugin(() => {})\n`,
92
+ })
93
+ }
94
+
67
95
  if (options.link !== false) {
68
96
  addPlugin({ src: resolver.resolve("./runtime/config.plugin"), mode: "all" })
69
97
  }
@@ -17,7 +17,7 @@
17
17
  // Through the barrel, not "../theme/…": this file is compiled by the consuming
18
18
  // app, where the barrel resolves to the same dist instance the components use.
19
19
  import {
20
- leavepulse,
20
+ dark,
21
21
  presets,
22
22
  THEME_COOKIE,
23
23
  themeFromCookie,
@@ -43,7 +43,7 @@ export default defineNuxtPlugin(() => {
43
43
  }
44
44
 
45
45
  const themes = [...(appThemes as TokenSet[]), ...(Object.values(presets) as TokenSet[])]
46
- const fallback = themes.find((theme) => theme.name === options.defaultTheme) ?? leavepulse
46
+ const fallback = themes.find((theme) => theme.name === options.defaultTheme) ?? dark
47
47
 
48
48
  // Raw value: themeFromCookie decodes safely itself, a throwing decode here
49
49
  // would turn a malformed cookie into a 500 on every request.
@@ -49,3 +49,72 @@ export function detectBackdropFilter(
49
49
  root.toggleAttribute(NO_BACKDROP_ATTR, !usable)
50
50
  return usable
51
51
  }
52
+
53
+ /*
54
+ * Glass without backdrop-filter. Where the engine cannot blur what lies under
55
+ * a panel (the flag above), it can still blur an ordinary element, so a panel
56
+ * can be frosted by painting a blurred copy of what is under it, as long as
57
+ * that is known. In an app that paints its own wallpaper (a launcher, a shell)
58
+ * it is: the consumer hands the wallpaper over as a CSS `background` value,
59
+ * and every `.lp-glass-overlay` draws it, blurred and aligned to the viewport,
60
+ * beneath its tint. Live content under the panel stays sharp; the wallpaper,
61
+ * which is most of what glass shows, reads as frosted.
62
+ *
63
+ * The copy is placed by the panel's position on screen, which overlays animate
64
+ * and drawers drag, so while any glass panel is mounted its offset is kept in
65
+ * CSS variables (`--lp-gx`, `--lp-gy`) once a frame. Nothing runs where the
66
+ * real blur works or no backdrop was given.
67
+ */
68
+ export const GLASS_BACKDROP_ATTR = "data-lp-glass-backdrop"
69
+
70
+ let tracking = 0
71
+ let observer: MutationObserver | undefined
72
+
73
+ function trackPanels() {
74
+ const panels = document.querySelectorAll<HTMLElement>(".lp-glass-overlay")
75
+ for (const panel of panels) {
76
+ const rect = panel.getBoundingClientRect()
77
+ const x = `${Math.round(rect.left)}px`
78
+ const y = `${Math.round(rect.top)}px`
79
+ if (panel.style.getPropertyValue("--lp-gx") !== x) panel.style.setProperty("--lp-gx", x)
80
+ if (panel.style.getPropertyValue("--lp-gy") !== y) panel.style.setProperty("--lp-gy", y)
81
+ }
82
+ tracking = panels.length ? requestAnimationFrame(trackPanels) : 0
83
+ }
84
+
85
+ function startTracking() {
86
+ if (!tracking && document.querySelector(".lp-glass-overlay")) tracking = requestAnimationFrame(trackPanels)
87
+ }
88
+
89
+ /**
90
+ * Give glass panels a wallpaper to frost where backdrop-filter does not work:
91
+ * `setGlassBackdrop("url(/bg.jpg) center / cover no-repeat, #0b0f14")`, the
92
+ * same value the app paints behind itself. `filter` replaces the default blur,
93
+ * e.g. `"none"` for a wallpaper that was blurred ahead of time, which is
94
+ * cheaper on an engine that blurs on the CPU. `null` turns it off.
95
+ */
96
+ export function setGlassBackdrop(
97
+ background: string | null,
98
+ options: { filter?: string; root?: HTMLElement } = {},
99
+ ): void {
100
+ if (typeof document === "undefined") return
101
+ const root = options.root ?? document.documentElement
102
+ if (!background) {
103
+ root.removeAttribute(GLASS_BACKDROP_ATTR)
104
+ root.style.removeProperty("--lp-glass-backdrop")
105
+ root.style.removeProperty("--lp-glass-backdrop-filter")
106
+ observer?.disconnect()
107
+ observer = undefined
108
+ return
109
+ }
110
+ root.setAttribute(GLASS_BACKDROP_ATTR, "")
111
+ root.style.setProperty("--lp-glass-backdrop", background)
112
+ if (options.filter) root.style.setProperty("--lp-glass-backdrop-filter", options.filter)
113
+ else root.style.removeProperty("--lp-glass-backdrop-filter")
114
+ if (!root.hasAttribute(NO_BACKDROP_ATTR) || typeof MutationObserver === "undefined") return
115
+ if (!observer) {
116
+ observer = new MutationObserver(startTracking)
117
+ observer.observe(document.body, { childList: true, subtree: true })
118
+ }
119
+ startTracking()
120
+ }
@@ -1,4 +1,4 @@
1
- import type { SurfaceTokens, TokenSet } from "./tokens"
1
+ import type { TokenSet } from "./tokens"
2
2
 
3
3
  /*
4
4
  * Built-in theme presets — plain TokenSet objects (JSON). These ARE the themes;
@@ -14,13 +14,12 @@ const interFont = {
14
14
  }
15
15
 
16
16
  /*
17
- * NOTE on naming: the exported CONST names are frozen for compatibility (apps
18
- * import `dark` / `leavepulse` directly), but the display `name` changed —
19
- * `leavepulse` is now the one called "Dark" (it is the product's dark theme),
20
- * and this near-black neutral became "Onyx" to free that label up.
17
+ * The kit's dark theme, a near-black neutral. It was displayed as "Onyx" while
18
+ * the LeavePulse site theme held the "Dark" label; with that theme gone the
19
+ * label is back here.
21
20
  */
22
21
  export const dark: TokenSet = {
23
- name: "Onyx",
22
+ name: "Dark",
24
23
  mode: "dark",
25
24
  colors: {
26
25
  surface: "#080b0d",
@@ -120,63 +119,6 @@ export const lime: TokenSet = {
120
119
  },
121
120
  }
122
121
 
123
- /*
124
- * Glass skin — frosted panels with backdrop blur, a faint top-down highlight
125
- * overlay, a layered drop shadow and an inset highlight line. Opt a theme into
126
- * it by setting its `surface` axis to this (the LeavePulse site uses it).
127
- */
128
- const glassSurface: SurfaceTokens = {
129
- borderWidth: "1px",
130
- panelBlur: "10px",
131
- panelSaturate: "120%",
132
- panelOverlay:
133
- "linear-gradient(180deg, rgba(255, 255, 255, 0.06), rgba(255, 255, 255, 0.01))",
134
- panelShadow: "0 20px 60px rgba(0, 0, 0, 0.35)",
135
- panelInset: "inset 0 1px 0 rgba(255, 255, 255, 0.08)",
136
- }
137
-
138
- /*
139
- * LeavePulse site theme — the colours the website shipped before the kit
140
- * migration (deep navy surfaces, cyan brand, teal accent), with the glass skin.
141
- * Distinct from `dark` (which is a near-black neutral) so the site keeps its
142
- * look when it switches its CSS-var dictionary over to the kit.
143
- */
144
- export const leavepulse: TokenSet = {
145
- name: "Dark",
146
- mode: "dark",
147
- colors: {
148
- surface: "#020618",
149
- surfaceRaised: "#0b1222",
150
- surfaceSoft: "rgba(11, 18, 34, 0.7)",
151
- ink: "#f3f6ff",
152
- inkInverse: "#0b1222",
153
- muted: "#94a3bf",
154
- mutedStrong: "#cad5e2",
155
- brand: "#00bcff",
156
- brandHover: "#19c3ff",
157
- brandSoft: "rgba(0, 188, 255, 0.2)",
158
- action: "#44c2ad",
159
- actionHover: "#56d3be",
160
- actionSoft: "rgba(68, 194, 173, 0.14)",
161
- accent: "#d36a2c",
162
- accentHover: "#da824e",
163
- accentSoft: "rgba(211, 106, 44, 0.14)",
164
- danger: "#f87171",
165
- dangerHover: "#fca5a5",
166
- dangerSoft: "rgba(248, 113, 113, 0.14)",
167
- line: "#1c2740",
168
- lineStrong: "rgba(255, 255, 255, 0.15)",
169
- ring: "rgba(0, 188, 255, 0.35)",
170
- },
171
- shape: { ...sharedShape, radiusControl: 12 },
172
- density: { ...sharedDensity },
173
- font: {
174
- sans: '"Inter", "IBM Plex Sans", "Segoe UI", sans-serif',
175
- mono: '"JetBrains Mono", "SF Mono", ui-monospace, monospace',
176
- },
177
- surface: glassSurface,
178
- }
179
-
180
122
  export const rose: TokenSet = {
181
123
  name: "Rose",
182
124
  mode: "dark",
@@ -305,5 +247,5 @@ export const nord: TokenSet = {
305
247
  font: { ...interFont },
306
248
  }
307
249
 
308
- export const presets = { dark, light, lime, leavepulse, rose, amber, violet, nord } as const
250
+ export const presets = { dark, light, lime, rose, amber, violet, nord } as const
309
251
  export type PresetName = keyof typeof presets
@@ -256,6 +256,19 @@
256
256
  transform: translateY(4px) scale(0.97);
257
257
  }
258
258
  }
259
+ /* A chip joining a row of chips (tags): grows out of its own centre. */
260
+ @keyframes chip-in {
261
+ from {
262
+ opacity: 0;
263
+ transform: scale(0.85);
264
+ }
265
+ }
266
+ @keyframes chip-out {
267
+ to {
268
+ opacity: 0;
269
+ transform: scale(0.85);
270
+ }
271
+ }
259
272
  /* Option cascade: items slide in top→down on open. */
260
273
  @keyframes option-in {
261
274
  from {
@@ -551,6 +564,39 @@
551
564
  backdrop-filter: none;
552
565
  }
553
566
 
567
+ /*
568
+ * The same glass where the blur does not composite but the app said what lies
569
+ * behind it (setGlassBackdrop): a blurred copy of that wallpaper, aligned to
570
+ * the viewport by the panel's offset, sits under a fill a little denser than
571
+ * the real glass, since only the wallpaper and not the page is softened.
572
+ */
573
+ :root[data-lp-no-backdrop][data-lp-glass-backdrop] .lp-glass-overlay {
574
+ background: none;
575
+ isolation: isolate;
576
+ overflow: clip;
577
+ }
578
+
579
+ :root[data-lp-no-backdrop][data-lp-glass-backdrop] .lp-glass-overlay::before {
580
+ content: "";
581
+ position: absolute;
582
+ z-index: -1;
583
+ left: calc(-1 * var(--lp-gx, 0px));
584
+ top: calc(-1 * var(--lp-gy, 0px));
585
+ width: 100vw;
586
+ height: 100vh;
587
+ /* The tint rides in the same layer: a negative z-index child paints over
588
+ its stacking context's own background, so a fill on the panel would sit
589
+ under the wallpaper and vanish. */
590
+ background:
591
+ linear-gradient(
592
+ color-mix(in srgb, var(--color-surface-raised) var(--glass-overlay-fallback-fill, 62%), transparent),
593
+ color-mix(in srgb, var(--color-surface-raised) var(--glass-overlay-fallback-fill, 62%), transparent)
594
+ ),
595
+ var(--lp-glass-backdrop);
596
+ filter: var(--lp-glass-backdrop-filter, blur(var(--glass-overlay-blur, 28px)) saturate(170%));
597
+ pointer-events: none;
598
+ }
599
+
554
600
  /* The overlay gradient rides above the base fill but under the content. */
555
601
  .lp-skin-panel::before {
556
602
  content: "";