@leavepulse/ui 0.78.0 → 0.78.2

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 (243) hide show
  1. package/dist/chunks/{DropzoneLinkField-DXIr0eFz.js → DropzoneLinkField-CyE7TJ5f.js} +1 -1
  2. package/dist/chunks/FieldLeading-mr81aEAP.js +27 -0
  3. package/dist/chunks/LpAddressInput-ft8fQOGx.js +401 -0
  4. package/dist/chunks/{LpAppShell-BNAVTQsY.js → LpAppShell-DkvU6IBB.js} +23 -4
  5. package/dist/chunks/LpAutocomplete-CrZbd0uv.js +310 -0
  6. package/dist/chunks/LpCheckbox-CCWCwD0y.js +129 -0
  7. package/dist/chunks/{LpCodeBlock-DuzmnIHl.js → LpCodeBlock-DBqy4RLd.js} +1 -1
  8. package/dist/chunks/{LpCodeDisplay-CO8fngxa.js → LpCodeDisplay-D59uPwRb.js} +3 -3
  9. package/dist/chunks/LpColorPicker-BONURBFN.js +574 -0
  10. package/dist/chunks/{LpConfirmDialog-6oCIJTDa.js → LpConfirmDialog-CnrmzkuN.js} +1 -1
  11. package/dist/chunks/{LpConfirmHost-DgHvfT6s.js → LpConfirmHost-CwbObVGH.js} +1 -1
  12. package/dist/chunks/{LpContextMenu--eMGIql6.js → LpContextMenu-Bx_IhQDS.js} +5 -5
  13. package/dist/chunks/{LpCopyButton-7EOSIuwa.js → LpCopyButton-sAMvWeLP.js} +1 -1
  14. package/dist/chunks/{LpDataList-DgBeM01y.js → LpDataList-CaVfsozH.js} +2 -2
  15. package/dist/chunks/LpDatePicker-C2AOtxgF.js +171 -0
  16. package/dist/chunks/{LpDateRangePicker-CNQXdTVv.js → LpDateRangePicker-CiXdIAyh.js} +43 -35
  17. package/dist/chunks/{LpDrawer-Bt9UUqt_.js → LpDrawer-DXNQFpAA.js} +1 -1
  18. package/dist/chunks/{LpFileTree-BSx1kBoV.js → LpFileTree-CpNurwZp.js} +3 -3
  19. package/dist/chunks/{LpFileTreeNode-4dVmFHb3.js → LpFileTreeNode-DdF8Cq-s.js} +2 -2
  20. package/dist/chunks/{LpHoverCard-DanH3Nz1.js → LpHoverCard-CHE9jAJG.js} +6 -6
  21. package/dist/chunks/{LpInfraNode-BAU40Km2.js → LpInfraNode-Bb5nbuFY.js} +17 -0
  22. package/dist/chunks/{LpInput-DL6HEJdi.js → LpInput-CbI7z5fQ.js} +21 -25
  23. package/dist/chunks/{LpInspector-CuoMAhiw.js → LpInspector-DO3fTCQ1.js} +2 -2
  24. package/dist/chunks/{LpLaneNode-HtnQf2FF.js → LpLaneNode-Bqcdm8Rf.js} +19 -1
  25. package/dist/chunks/{LpLightbox-xvpQ64MM.js → LpLightbox-CtDTQV01.js} +1 -1
  26. package/dist/chunks/{LpLogInspector-6cNnXqp4.js → LpLogInspector-CcSJSGan.js} +1 -1
  27. package/dist/chunks/{LpLogViewer-Dvb1E9_G.js → LpLogViewer-CWu49Dko.js} +4 -4
  28. package/dist/chunks/{LpMediaGallery-Df-tiWeq.js → LpMediaGallery-BYEwySoF.js} +2 -2
  29. package/dist/chunks/{LpModal-DrtQ_1A2.js → LpModal-DDvrSAnf.js} +1 -1
  30. package/dist/chunks/{LpModalNav-DkmGCnZE.js → LpModalNav-DI3BW5ff.js} +2 -2
  31. package/dist/chunks/{LpNotificationBell-D_wklO1m.js → LpNotificationBell-DUbVyK6R.js} +3 -3
  32. package/dist/chunks/LpNumberField-C8LfUz_R.js +154 -0
  33. package/dist/chunks/LpOtpInput-B1X9l9no.js +140 -0
  34. package/dist/chunks/LpPageScrollbar-D2O0xhJw.js +164 -0
  35. package/dist/chunks/{LpPaletteTheme-dVtxHx-F.js → LpPaletteTheme-B-xuZiKK.js} +2 -2
  36. package/dist/chunks/{LpPasswordInput-B-zD6tUS.js → LpPasswordInput-Duc_3wPv.js} +2 -2
  37. package/dist/chunks/{LpPhoneInput-BSL7NX4z.js → LpPhoneInput-CctcRK9K.js} +124 -118
  38. package/dist/chunks/{LpPie-9t_guO49.js → LpPie-oVNHjsKD.js} +2 -2
  39. package/dist/chunks/{LpPipeline-rjXvEDRJ.js → LpPipeline-BSXT6oUJ.js} +1 -1
  40. package/dist/chunks/LpRadioGroup-DTM0nd9G.js +103 -0
  41. package/dist/chunks/LpRangeSlider-DJsEZXad.js +97 -0
  42. package/dist/chunks/{LpRelativeTime-BovUk8MP.js → LpRelativeTime-0zI-44ve.js} +1 -1
  43. package/dist/chunks/LpRepeater-Czib3rmv.js +193 -0
  44. package/dist/chunks/{LpScrollArea-ay4Xo_hg.js → LpScrollArea-CqvwfZs2.js} +9 -12
  45. package/dist/chunks/{LpSecretField-DBvU6iAw.js → LpSecretField-BtlCk3IH.js} +4 -4
  46. package/dist/chunks/LpSegmented-sskrJKJJ.js +128 -0
  47. package/dist/chunks/LpSelect-JFZehOkd.js +515 -0
  48. package/dist/chunks/{LpServiceNode-D8uJ8sGk.js → LpServiceNode-Cln2ntdw.js} +17 -0
  49. package/dist/chunks/{LpSidebar-kSkpPh3-.js → LpSidebar-CvRvVBTt.js} +4 -4
  50. package/dist/chunks/{LpSidebarNav-C2mvqrY2.js → LpSidebarNav-CE0jQS8i.js} +2 -2
  51. package/dist/chunks/{LpSidebarRow-eRP4Q31q.js → LpSidebarRow-DOTg1txp.js} +2 -2
  52. package/dist/chunks/LpSlider-C4ilCtZX.js +76 -0
  53. package/dist/chunks/{LpStat-pMNZgFcq.js → LpStat-DPjc6_fX.js} +17 -4
  54. package/dist/chunks/LpSwitch-DyAYTchz.js +122 -0
  55. package/dist/chunks/{LpTableFilter-DgARTsA1.js → LpTableFilter-CJg5eIcV.js} +2 -2
  56. package/dist/chunks/{LpTagsInput-Dt0mteSj.js → LpTagsInput-CkNxpNYa.js} +4 -3
  57. package/dist/chunks/{LpTextarea-Co0b9PVx.js → LpTextarea-CFK_5QB8.js} +3 -2
  58. package/dist/chunks/{LpThemeStudio-DzYfE-5k.js → LpThemeStudio-R-wohbCY.js} +3 -3
  59. package/dist/chunks/{LpThemeSwitcher-CFLkdbBL.js → LpThemeSwitcher-Bzy15MCP.js} +2 -2
  60. package/dist/chunks/LpTimeField-B5n0m8m0.js +115 -0
  61. package/dist/chunks/{LpToaster-QFj0P-5m.js → LpToaster-Ct_ZOhCh.js} +1 -1
  62. package/dist/chunks/{LpTooltip-BJf3lZMq.js → LpTooltip-Bz_rrq5S.js} +5 -5
  63. package/dist/chunks/{LpTopologyCanvas-BOHHHZ_6.js → LpTopologyCanvas-BNgw9RyZ.js} +14 -9
  64. package/dist/chunks/{LpTruncate-C6u3gjc6.js → LpTruncate-ellq9RYM.js} +2 -2
  65. package/dist/chunks/{LpUptimeBar-BnYmR2rj.js → LpUptimeBar-BoxcCDVY.js} +1 -1
  66. package/dist/chunks/{LpWorkspaceSwitcher-D0e9upAy.js → LpWorkspaceSwitcher-ugv-fyig.js} +2 -2
  67. package/dist/chunks/{RevealToggle-CCPDE8Mv.js → RevealToggle-D_iyrB8d.js} +1 -1
  68. package/dist/component-names.d.ts +1 -1
  69. package/dist/components/DropzoneLinkField.vue.js +1 -1
  70. package/dist/components/FieldLeading.vue.d.ts +16 -0
  71. package/dist/components/FieldLeading.vue.js +4 -0
  72. package/dist/components/LpAddressInput.vue.d.ts +4 -0
  73. package/dist/components/LpAddressInput.vue.js +1 -1
  74. package/dist/components/LpAlert.vue.d.ts +3 -3
  75. package/dist/components/LpAppShell.vue.d.ts +16 -1
  76. package/dist/components/LpAppShell.vue.js +1 -1
  77. package/dist/components/LpAutocomplete.vue.d.ts +4 -0
  78. package/dist/components/LpAutocomplete.vue.js +1 -1
  79. package/dist/components/LpBadge.vue.d.ts +2 -2
  80. package/dist/components/LpChart.vue.d.ts +1 -1
  81. package/dist/components/LpChart.vue.js +1 -1
  82. package/dist/components/LpCheckbox.vue.d.ts +4 -0
  83. package/dist/components/LpCheckbox.vue.js +1 -1
  84. package/dist/components/LpCodeBlock.vue.js +1 -1
  85. package/dist/components/LpCodeDisplay.vue.js +1 -1
  86. package/dist/components/LpCollapse.vue.d.ts +1 -1
  87. package/dist/components/LpColorPicker.vue.d.ts +5 -3
  88. package/dist/components/LpColorPicker.vue.js +1 -1
  89. package/dist/components/LpCommandPalette.vue.js +1 -1
  90. package/dist/components/LpConfirmDialog.vue.js +1 -1
  91. package/dist/components/LpConfirmHost.vue.js +1 -1
  92. package/dist/components/LpContextMenu.vue.js +1 -1
  93. package/dist/components/LpCopyButton.vue.js +1 -1
  94. package/dist/components/LpDataList.vue.js +1 -1
  95. package/dist/components/LpDatePicker.vue.js +1 -1
  96. package/dist/components/LpDateRangePicker.vue.js +1 -1
  97. package/dist/components/LpDock.vue.js +1 -1
  98. package/dist/components/LpDrawer.vue.js +1 -1
  99. package/dist/components/LpDropzone.vue.js +1 -1
  100. package/dist/components/LpFileTree.vue.js +1 -1
  101. package/dist/components/LpFileTreeNode.vue.js +1 -1
  102. package/dist/components/LpHoverCard.vue.js +1 -1
  103. package/dist/components/LpImageEditor.vue.d.ts +1 -1
  104. package/dist/components/LpInfraNode.vue.d.ts +11 -2
  105. package/dist/components/LpInfraNode.vue.js +1 -1
  106. package/dist/components/LpInput.vue.js +1 -1
  107. package/dist/components/LpInspector.vue.js +1 -1
  108. package/dist/components/LpLaneNode.vue.d.ts +2 -3
  109. package/dist/components/LpLaneNode.vue.js +1 -1
  110. package/dist/components/LpLightbox.vue.js +1 -1
  111. package/dist/components/LpLogInspector.vue.js +1 -1
  112. package/dist/components/LpLogViewer.vue.js +1 -1
  113. package/dist/components/LpMediaGallery.vue.js +1 -1
  114. package/dist/components/LpModal.vue.js +1 -1
  115. package/dist/components/LpModalNav.vue.js +1 -1
  116. package/dist/components/LpNotificationBell.vue.js +1 -1
  117. package/dist/components/LpNumberField.vue.d.ts +17 -2
  118. package/dist/components/LpNumberField.vue.js +1 -1
  119. package/dist/components/LpOtpInput.vue.d.ts +4 -0
  120. package/dist/components/LpOtpInput.vue.js +1 -1
  121. package/dist/components/LpPageScrollbar.vue.d.ts +10 -0
  122. package/dist/components/LpPageScrollbar.vue.js +4 -0
  123. package/dist/components/LpPaletteTheme.vue.js +1 -1
  124. package/dist/components/LpPasswordInput.vue.js +1 -1
  125. package/dist/components/LpPhoneInput.vue.d.ts +4 -0
  126. package/dist/components/LpPhoneInput.vue.js +1 -1
  127. package/dist/components/LpPie.vue.js +1 -1
  128. package/dist/components/LpPipeline.vue.js +1 -1
  129. package/dist/components/LpRadioGroup.vue.d.ts +4 -0
  130. package/dist/components/LpRadioGroup.vue.js +1 -1
  131. package/dist/components/LpRangeSlider.vue.d.ts +4 -0
  132. package/dist/components/LpRangeSlider.vue.js +1 -1
  133. package/dist/components/LpRelativeTime.vue.js +1 -1
  134. package/dist/components/LpRepeater.vue.d.ts +2 -0
  135. package/dist/components/LpRepeater.vue.js +1 -1
  136. package/dist/components/LpScrollArea.vue.d.ts +1 -1
  137. package/dist/components/LpScrollArea.vue.js +1 -1
  138. package/dist/components/LpSecretField.vue.js +1 -1
  139. package/dist/components/LpSegmented.vue.d.ts +4 -0
  140. package/dist/components/LpSegmented.vue.js +1 -1
  141. package/dist/components/LpSelect.vue.d.ts +2 -0
  142. package/dist/components/LpSelect.vue.js +1 -1
  143. package/dist/components/LpServiceNode.vue.d.ts +8 -2
  144. package/dist/components/LpServiceNode.vue.js +1 -1
  145. package/dist/components/LpShinyText.vue.d.ts +1 -1
  146. package/dist/components/LpShortcutsDialog.vue.js +1 -1
  147. package/dist/components/LpSidebar.vue.d.ts +1 -1
  148. package/dist/components/LpSidebar.vue.js +1 -1
  149. package/dist/components/LpSidebarNav.vue.js +1 -1
  150. package/dist/components/LpSidebarRow.vue.js +1 -1
  151. package/dist/components/LpSlider.vue.d.ts +4 -0
  152. package/dist/components/LpSlider.vue.js +1 -1
  153. package/dist/components/LpStat.vue.d.ts +16 -0
  154. package/dist/components/LpStat.vue.js +1 -1
  155. package/dist/components/LpSwitch.vue.d.ts +4 -0
  156. package/dist/components/LpSwitch.vue.js +1 -1
  157. package/dist/components/LpTable.vue.js +5 -5
  158. package/dist/components/LpTableFilter.vue.js +1 -1
  159. package/dist/components/LpTabs.vue.d.ts +1 -1
  160. package/dist/components/LpTabs.vue.js +1 -1
  161. package/dist/components/LpTagsInput.vue.js +1 -1
  162. package/dist/components/LpTextarea.vue.js +1 -1
  163. package/dist/components/LpThemeStudio.vue.js +1 -1
  164. package/dist/components/LpThemeSwitcher.vue.js +1 -1
  165. package/dist/components/LpTimeField.vue.d.ts +4 -0
  166. package/dist/components/LpTimeField.vue.js +1 -1
  167. package/dist/components/LpToaster.vue.js +1 -1
  168. package/dist/components/LpTooltip.vue.js +1 -1
  169. package/dist/components/LpTopologyCanvas.vue.d.ts +2 -2
  170. package/dist/components/LpTopologyCanvas.vue.js +1 -1
  171. package/dist/components/LpTruncate.vue.js +1 -1
  172. package/dist/components/LpUptimeBar.vue.js +1 -1
  173. package/dist/components/LpWorkspaceSwitcher.vue.js +1 -1
  174. package/dist/components/RevealToggle.vue.js +1 -1
  175. package/dist/components/calendar.d.ts +2 -0
  176. package/dist/components/menuWhen.js +1 -1
  177. package/dist/components/scrollbar.d.ts +34 -0
  178. package/dist/components/scrollbar.js +47 -0
  179. package/dist/composables/propCheck.d.ts +1 -1
  180. package/dist/composables/propCheck.js +15 -4
  181. package/dist/composables/useField.d.ts +50 -0
  182. package/dist/composables/useField.js +31 -2
  183. package/dist/composables/useMergedClass.d.ts +6 -2
  184. package/dist/composables/useMergedClass.js +6 -6
  185. package/dist/composables/usePaletteCommands.js +4 -2
  186. package/dist/index.d.ts +1 -0
  187. package/dist/index.js +170 -168
  188. package/package.json +1 -1
  189. package/src/component-names.ts +1 -0
  190. package/src/components/FieldLeading.vue +17 -0
  191. package/src/components/LpAddressInput.vue +8 -4
  192. package/src/components/LpAppShell.vue +23 -0
  193. package/src/components/LpAutocomplete.vue +11 -5
  194. package/src/components/LpCheckbox.vue +8 -6
  195. package/src/components/LpColorPicker.vue +7 -4
  196. package/src/components/LpContextMenu.vue +7 -0
  197. package/src/components/LpDatePicker.vue +8 -4
  198. package/src/components/LpDateRangePicker.vue +8 -4
  199. package/src/components/LpHoverCard.vue +7 -0
  200. package/src/components/LpInfraNode.vue +4 -3
  201. package/src/components/LpInput.vue +7 -7
  202. package/src/components/LpLaneNode.vue +5 -1
  203. package/src/components/LpNumberField.vue +18 -7
  204. package/src/components/LpOtpInput.vue +8 -6
  205. package/src/components/LpPageScrollbar.vue +195 -0
  206. package/src/components/LpPhoneInput.vue +11 -6
  207. package/src/components/LpRadioGroup.vue +9 -5
  208. package/src/components/LpRangeSlider.vue +8 -4
  209. package/src/components/LpRepeater.vue +16 -4
  210. package/src/components/LpScrollArea.vue +27 -23
  211. package/src/components/LpSegmented.vue +8 -4
  212. package/src/components/LpSelect.vue +8 -7
  213. package/src/components/LpServiceNode.vue +4 -2
  214. package/src/components/LpSlider.vue +8 -4
  215. package/src/components/LpStat.vue +25 -5
  216. package/src/components/LpSwitch.vue +8 -5
  217. package/src/components/LpTagsInput.vue +4 -3
  218. package/src/components/LpTextarea.vue +3 -2
  219. package/src/components/LpTimeField.vue +8 -6
  220. package/src/components/LpTooltip.vue +7 -0
  221. package/src/components/LpTopologyCanvas.vue +3 -1
  222. package/src/components/calendar.ts +2 -0
  223. package/src/components/scrollbar.ts +71 -0
  224. package/src/composables/propCheck.ts +20 -5
  225. package/src/composables/useField.ts +52 -0
  226. package/src/composables/useMergedClass.ts +11 -5
  227. package/src/composables/usePaletteCommands.ts +5 -2
  228. package/src/index.ts +1 -0
  229. package/dist/chunks/LpAddressInput-ZqoZ-N2Y.js +0 -393
  230. package/dist/chunks/LpAutocomplete-DkY6CSyD.js +0 -302
  231. package/dist/chunks/LpCheckbox-D6RuDW4X.js +0 -124
  232. package/dist/chunks/LpColorPicker-BxAHEnR5.js +0 -567
  233. package/dist/chunks/LpDatePicker-DwSDY0mt.js +0 -163
  234. package/dist/chunks/LpNumberField-CNHsmSDZ.js +0 -134
  235. package/dist/chunks/LpOtpInput-BRpLBbOD.js +0 -132
  236. package/dist/chunks/LpRadioGroup-BrazjLY_.js +0 -95
  237. package/dist/chunks/LpRangeSlider-fz61tzc-.js +0 -89
  238. package/dist/chunks/LpRepeater-BkJHSPI1.js +0 -180
  239. package/dist/chunks/LpSegmented-DbEJhbv-.js +0 -123
  240. package/dist/chunks/LpSelect-Y-iuSymW.js +0 -512
  241. package/dist/chunks/LpSlider-A4ixovgS.js +0 -68
  242. package/dist/chunks/LpSwitch-DnC2-0aV.js +0 -115
  243. package/dist/chunks/LpTimeField-DeOcKWJq.js +0 -110
@@ -1,567 +0,0 @@
1
- import { defineComponent, ref, watch, computed, useAttrs, openBlock, createBlock, unref, withCtx, createVNode, normalizeClass, createElementBlock, normalizeStyle, createElementVNode, createCommentVNode, toDisplayString, withDirectives, vShow, withKeys, Fragment, renderList, renderSlot, nextTick } from "vue";
2
- import { CONTROL_SIZE } from "../components/controlSize.js";
3
- import { clamp } from "../composables/clamp.js";
4
- import { PopoverRoot, PopoverAnchor, PopoverTrigger, PopoverPortal, PopoverContent } from "reka-ui";
5
- import { useKitStorage } from "../composables/usePersisted.js";
6
- import { prefersReducedMotion } from "../composables/easing.js";
7
- import { useFieldControl, mergeDescribedBy } from "../composables/useField.js";
8
- import { DEFAULT_SWATCHES, formatColor, opaqueCss, parseColor, rgbToHsv, isLight, clampHsv } from "../components/color.js";
9
- import { useClipboard } from "../composables/useClipboard.js";
10
- import { useLabels } from "../composables/useLpConfig.js";
11
- import { POPOVER_PANEL } from "../components/dropdown.js";
12
- import { _ as _sfc_main$1 } from "./LpContextMenu--eMGIql6.js";
13
- import { _ as _sfc_main$2 } from "./LpIcon-C6JpQ5td.js";
14
- import { _ as _sfc_main$3 } from "./LpRollingText-B54Pje7P.js";
15
- import { usePortalTarget, useOutsideGuard } from "../composables/useView.js";
16
- const _hoisted_1 = ["id", "disabled", "aria-label", "title"];
17
- const _hoisted_2 = ["id", "disabled", "aria-label", "aria-invalid", "aria-describedby"];
18
- const _hoisted_3 = { class: "min-w-0 flex-1 truncate font-mono text-xs text-muted-strong" };
19
- const _hoisted_4 = { class: "flex flex-col gap-3" };
20
- const _hoisted_5 = ["tabindex", "aria-label", "aria-valuenow", "aria-valuetext"];
21
- const _hoisted_6 = ["aria-label", "aria-valuenow", "tabindex"];
22
- const _hoisted_7 = ["aria-label", "aria-valuenow", "tabindex"];
23
- const _hoisted_8 = {
24
- key: 1,
25
- "data-lp-ring-owner": "",
26
- class: "flex h-(--size-control-sm) items-center gap-2 overflow-hidden rounded-control border border-line bg-surface-soft px-2 transition-colors duration-[var(--duration-fast)] focus-within:border-brand focus-within:ring-2 focus-within:ring-ring"
27
- };
28
- const _hoisted_9 = { class: "relative flex min-w-0 flex-1 items-center" };
29
- const _hoisted_10 = ["value", "disabled", "aria-label"];
30
- const _hoisted_11 = {
31
- key: 0,
32
- class: "text-[11px] font-medium uppercase tracking-wide text-muted"
33
- };
34
- const _hoisted_12 = ["disabled", "aria-label", "aria-pressed", "onClick"];
35
- const ANY_COLOUR = "conic-gradient(from 90deg, #ff5c5c, #ffd23f, #39e58c, #2dd4bf, #00bcff, #7c5cff, #ff5ca8, #ff5c5c)";
36
- const CHECKERBOARD = "repeating-conic-gradient(var(--color-line-strong) 0% 25%, transparent 0% 50%) 0 0 / 12px 12px";
37
- const ROLL_MS = 320;
38
- const _sfc_main = /* @__PURE__ */ defineComponent({
39
- __name: "LpColorPicker",
40
- props: {
41
- modelValue: { default: "#3b82f6" },
42
- format: { default: "hex" },
43
- alpha: { type: Boolean, default: false },
44
- swatches: { default: () => DEFAULT_SWATCHES },
45
- hideInput: { type: Boolean },
46
- disabled: { type: Boolean },
47
- invalid: { type: Boolean },
48
- size: { default: "md" },
49
- label: {},
50
- variant: { default: "field" },
51
- selected: { type: Boolean, default: true },
52
- ariaLabel: {},
53
- side: { default: "bottom" },
54
- align: { default: "start" },
55
- menu: {},
56
- menuItems: {},
57
- recent: { type: Boolean, default: false },
58
- recentKey: { default: "lp.color.recent" },
59
- recentLimit: { default: 8 },
60
- labels: {},
61
- copyToast: { type: [String, Boolean] }
62
- },
63
- emits: ["update:modelValue", "change"],
64
- setup(__props, { expose: __expose, emit: __emit }) {
65
- const props = __props;
66
- const emit = __emit;
67
- function fill(tpl, vars) {
68
- return tpl.replace(/\{(\w+)\}/g, (_, k) => String(vars[k] ?? ""));
69
- }
70
- const l = useLabels(
71
- "colorPicker",
72
- {
73
- saturation: "Saturation and brightness",
74
- hue: "Hue",
75
- opacity: "Opacity",
76
- value: "Colour value",
77
- recent: "Recent",
78
- copyHex: "Copy hex",
79
- copyRgb: "Copy rgb",
80
- copyHsl: "Copy hsl",
81
- paste: "Paste colour",
82
- formatAs: "Show as",
83
- format_hex: "HEX",
84
- format_rgb: "RGB",
85
- format_hsl: "HSL",
86
- saturationValueText: "saturation {s}%, brightness {v}%",
87
- copyToast: "Copied {value}"
88
- },
89
- () => props.labels
90
- );
91
- const { copy } = useClipboard();
92
- const open = ref(false);
93
- const hsv = ref({ h: 217, s: 0.76, v: 0.96, a: 1 });
94
- function adopt(value) {
95
- const rgb = parseColor(value ?? "");
96
- if (!rgb) return;
97
- const next = rgbToHsv(rgb);
98
- if (next.s === 0) next.h = hsv.value.h;
99
- if (next.v === 0) next.s = hsv.value.s;
100
- hsv.value = next;
101
- }
102
- adopt(props.modelValue);
103
- watch(
104
- () => props.modelValue,
105
- (v) => {
106
- if (v !== current.value) adopt(v);
107
- }
108
- );
109
- const activeFormat = ref(props.format);
110
- watch(() => props.format, (f) => activeFormat.value = f);
111
- const current = computed(
112
- () => formatColor(props.alpha ? hsv.value : { ...hsv.value, a: 1 }, activeFormat.value)
113
- );
114
- function set(patch, commit = false) {
115
- if (props.disabled) return;
116
- hsv.value = clampHsv({ ...hsv.value, ...patch });
117
- emit("update:modelValue", current.value);
118
- if (commit) emit("change", current.value);
119
- }
120
- function trackPointer(e, onMove) {
121
- if (props.disabled) return;
122
- if (e.button !== 0) return;
123
- e.preventDefault();
124
- const el = e.currentTarget;
125
- const rect = el.getBoundingClientRect();
126
- const at = (ev) => {
127
- const x = rect.width === 0 ? 0 : (ev.clientX - rect.left) / rect.width;
128
- const y = rect.height === 0 ? 0 : (ev.clientY - rect.top) / rect.height;
129
- onMove(clamp(x, 0, 1), clamp(y, 0, 1));
130
- };
131
- el.setPointerCapture(e.pointerId);
132
- at(e);
133
- const move = (ev) => at(ev);
134
- const up = () => {
135
- el.removeEventListener("pointermove", move);
136
- el.removeEventListener("pointerup", up);
137
- el.removeEventListener("pointercancel", up);
138
- emit("change", current.value);
139
- };
140
- el.addEventListener("pointermove", move);
141
- el.addEventListener("pointerup", up);
142
- el.addEventListener("pointercancel", up);
143
- }
144
- const onFieldPointer = (e) => trackPointer(e, (x, y) => set({ s: x, v: 1 - y }));
145
- const onHuePointer = (e) => trackPointer(e, (x) => set({ h: Math.min(x * 360, 359.9) }));
146
- const onAlphaPointer = (e) => trackPointer(e, (x) => set({ a: x }));
147
- function step(e, axis) {
148
- const big = e.shiftKey;
149
- const k = e.key;
150
- const arrows = ["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown", "Home", "End"];
151
- if (!arrows.includes(k)) return;
152
- e.preventDefault();
153
- const dx = (k === "ArrowRight" ? 1 : k === "ArrowLeft" ? -1 : 0) * (big ? 10 : 1);
154
- const dy = (k === "ArrowUp" ? 1 : k === "ArrowDown" ? -1 : 0) * (big ? 10 : 1);
155
- if (axis === "h") {
156
- if (k === "Home") return set({ h: 0 }, true);
157
- if (k === "End") return set({ h: 359 }, true);
158
- return set({ h: hsv.value.h + (dx || dy) }, true);
159
- }
160
- if (axis === "a") {
161
- if (k === "Home") return set({ a: 0 }, true);
162
- if (k === "End") return set({ a: 1 }, true);
163
- return set({ a: hsv.value.a + (dx || dy) / 100 }, true);
164
- }
165
- if (k === "Home") return set({ s: 0 }, true);
166
- if (k === "End") return set({ s: 1 }, true);
167
- set({ s: hsv.value.s + dx / 100, v: hsv.value.v + dy / 100 }, true);
168
- }
169
- const typed = ref(null);
170
- let typedChange = false;
171
- const inputValue = computed(() => typed.value ?? current.value);
172
- function onInput(e) {
173
- const value = e.target.value;
174
- typed.value = value;
175
- const rgb = parseColor(value);
176
- if (!rgb) return;
177
- const next = rgbToHsv(rgb);
178
- if (next.s === 0) next.h = hsv.value.h;
179
- if (next.v === 0) next.s = hsv.value.s;
180
- set(props.alpha ? next : { ...next, a: 1 });
181
- typedChange = true;
182
- }
183
- function commitTyped() {
184
- if (!typedChange) return;
185
- typedChange = false;
186
- emit("change", current.value);
187
- }
188
- function onInputBlur() {
189
- typed.value = null;
190
- commitTyped();
191
- }
192
- function pickSwatch(value) {
193
- const rgb = parseColor(value);
194
- if (!rgb) return;
195
- typed.value = null;
196
- set(rgbToHsv(rgb), true);
197
- }
198
- function isActiveSwatch(value) {
199
- const rgb = parseColor(value);
200
- return !!rgb && formatColor(rgbToHsv(rgb), "hex") === formatColor({ ...hsv.value, a: 1 }, "hex");
201
- }
202
- function tickClass(value) {
203
- const rgb = parseColor(value);
204
- return rgb && isLight(rgbToHsv(rgb)) ? "text-black" : "text-white";
205
- }
206
- const SWATCH_SIZE = { sm: "size-6", md: "size-7", lg: "size-8" };
207
- const triggerSize = CONTROL_SIZE;
208
- const previewCss = computed(() => formatColor(props.alpha ? hsv.value : { ...hsv.value, a: 1 }, "rgb"));
209
- const hueCss = computed(() => `hsl(${Math.round(hsv.value.h)}, 100%, 50%)`);
210
- const alphaRampStart = computed(() => formatColor({ ...hsv.value, a: 0 }, "rgb"));
211
- const fieldCss = computed(() => opaqueCss({ ...hsv.value, s: 1, v: 1 }));
212
- const fieldStyle = computed(() => ({
213
- background: [
214
- "linear-gradient(to top, rgba(0, 0, 0, 1), rgba(0, 0, 0, 0))",
215
- "linear-gradient(to right, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0))",
216
- fieldCss.value
217
- ].join(", ")
218
- }));
219
- const store = useKitStorage();
220
- function readRecent() {
221
- try {
222
- const raw = JSON.parse(store.get(props.recentKey) ?? "[]");
223
- return Array.isArray(raw) ? raw.filter((v) => typeof v === "string" && !!parseColor(v)).slice(0, props.recentLimit) : [];
224
- } catch {
225
- return [];
226
- }
227
- }
228
- const recentColors = ref(props.recent ? readRecent() : []);
229
- function remember(value) {
230
- if (!props.recent) return;
231
- const key = formatColor({ ...hsv.value, a: 1 }, "hex");
232
- const without = recentColors.value.filter(
233
- (c) => formatColor(rgbToHsv(parseColor(c) ?? { r: 0, g: 0, b: 0, a: 1 }), "hex") !== key
234
- );
235
- recentColors.value = [value, ...without].slice(0, props.recentLimit);
236
- store.set(props.recentKey, JSON.stringify(recentColors.value));
237
- }
238
- let openedOn = "";
239
- watch(open, (isOpen, was) => {
240
- if (isOpen) openedOn = current.value;
241
- else if (was && current.value !== openedOn) remember(current.value);
242
- });
243
- const swatchRows = computed(
244
- () => [
245
- {
246
- key: "recent",
247
- heading: l.value.recent,
248
- colors: props.recent ? recentColors.value : [],
249
- cols: "grid-cols-8",
250
- size: "size-6"
251
- },
252
- {
253
- key: "presets",
254
- heading: "",
255
- colors: [...props.swatches],
256
- cols: "grid-cols-6",
257
- size: "size-7"
258
- }
259
- ].filter((r) => r.colors.length)
260
- );
261
- function onPanelOpen(e) {
262
- e.preventDefault();
263
- e.currentTarget?.focus?.({ preventScroll: true });
264
- }
265
- function copyAs(fmt) {
266
- const text = formatColor(props.alpha ? hsv.value : { ...hsv.value, a: 1 }, fmt);
267
- const toast = props.copyToast ?? l.value.copyToast;
268
- void copy(text, { toast: toast === false ? false : fill(toast, { value: text }) });
269
- }
270
- async function pasteColor() {
271
- try {
272
- const text = await navigator.clipboard.readText();
273
- const rgb = parseColor(text);
274
- if (!rgb) return;
275
- typed.value = null;
276
- const next = rgbToHsv(rgb);
277
- set(props.alpha ? next : { ...next, a: 1 }, true);
278
- } catch {
279
- }
280
- }
281
- const rollText = ref(current.value);
282
- const rolling = ref(false);
283
- let rollTimer;
284
- function setFormat(f) {
285
- if (activeFormat.value === f) return;
286
- rollText.value = inputValue.value;
287
- activeFormat.value = f;
288
- if (!prefersReducedMotion()) {
289
- rolling.value = true;
290
- void nextTick(() => rollText.value = current.value);
291
- if (rollTimer) clearTimeout(rollTimer);
292
- rollTimer = setTimeout(() => rolling.value = false, ROLL_MS + 40);
293
- }
294
- typed.value = null;
295
- emit("update:modelValue", current.value);
296
- emit("change", current.value);
297
- }
298
- const menuItems = computed(() => {
299
- const own = props.menuItems ?? [];
300
- if (props.menu === "none") return own;
301
- const builtin = [
302
- { label: l.value.copyHex, icon: "lucide:copy", onSelect: () => copyAs("hex") },
303
- { label: l.value.copyRgb, icon: "lucide:copy", onSelect: () => copyAs("rgb") },
304
- { label: l.value.copyHsl, icon: "lucide:copy", onSelect: () => copyAs("hsl") },
305
- { label: l.value.paste, icon: "lucide:clipboard", onSelect: pasteColor },
306
- {
307
- // Ticks rather than a plain list: this is a setting with a current value,
308
- // and the menu should say which one is on without being opened twice.
309
- label: l.value.formatAs,
310
- icon: "lucide:code",
311
- separatorBefore: true,
312
- children: ["hex", "rgb", "hsl"].map((f) => ({
313
- label: l.value[`format_${f}`],
314
- checked: activeFormat.value === f,
315
- onSelect: () => setFormat(f)
316
- }))
317
- }
318
- ];
319
- return own.length ? [...builtin, { ...own[0], separatorBefore: true }, ...own.slice(1)] : builtin;
320
- });
321
- const attrs = useAttrs();
322
- const field = useFieldControl(() => ({
323
- wrapped: false,
324
- invalid: props.invalid,
325
- disabled: props.disabled
326
- }));
327
- __expose({ open });
328
- const portalTo = usePortalTarget();
329
- const guardOutside = useOutsideGuard();
330
- return (_ctx, _cache) => {
331
- return openBlock(), createBlock(unref(PopoverRoot), {
332
- open: open.value,
333
- "onUpdate:open": _cache[3] || (_cache[3] = ($event) => open.value = $event)
334
- }, {
335
- default: withCtx(() => [
336
- createVNode(unref(PopoverAnchor), {
337
- class: normalizeClass(__props.variant === "swatch" ? "inline-block" : "block w-full")
338
- }, {
339
- default: withCtx(() => [
340
- createVNode(_sfc_main$1, { items: menuItems.value }, {
341
- default: withCtx(() => [
342
- createVNode(unref(PopoverTrigger), { "as-child": "" }, {
343
- default: withCtx(() => [
344
- __props.variant === "swatch" ? (openBlock(), createElementBlock("button", {
345
- key: 0,
346
- type: "button",
347
- id: unref(field).id,
348
- disabled: unref(field).disabled,
349
- "aria-label": __props.ariaLabel ?? current.value,
350
- title: current.value,
351
- class: normalizeClass(["relative shrink-0 overflow-hidden rounded-full outline-none ring-2 ring-offset-2 ring-offset-surface-raised transition-[box-shadow,scale] duration-(--duration-fast) hover:scale-110 focus-visible:ring-ring data-[state=open]:ring-brand disabled:cursor-not-allowed disabled:opacity-55", [SWATCH_SIZE[__props.size], __props.selected ? "ring-ink" : "ring-line"]]),
352
- style: normalizeStyle({ background: CHECKERBOARD })
353
- }, [
354
- createElementVNode("span", {
355
- class: "block size-full",
356
- style: normalizeStyle({ background: __props.selected ? previewCss.value : ANY_COLOUR })
357
- }, null, 4),
358
- !__props.selected ? (openBlock(), createBlock(_sfc_main$2, {
359
- key: 0,
360
- name: "lucide:pipette",
361
- size: 12,
362
- class: "absolute inset-0 m-auto text-white drop-shadow"
363
- })) : createCommentVNode("", true)
364
- ], 14, _hoisted_1)) : (openBlock(), createElementBlock("button", {
365
- key: 1,
366
- type: "button",
367
- id: unref(field).id,
368
- disabled: unref(field).disabled,
369
- "aria-label": __props.ariaLabel,
370
- "aria-invalid": unref(field).invalid || void 0,
371
- "aria-describedby": unref(mergeDescribedBy)(unref(attrs)["aria-describedby"], unref(field).describedBy),
372
- class: normalizeClass(["group inline-flex w-full items-center gap-2 rounded-control border bg-surface-soft px-2 text-left text-ink outline-none transition-colors duration-[var(--duration-fast)] focus-visible:ring-2 focus-visible:ring-ring data-[state=open]:border-brand disabled:cursor-not-allowed disabled:opacity-55", [
373
- unref(triggerSize)[__props.size],
374
- unref(field).invalid ? "border-danger focus-visible:ring-danger-soft" : "border-line focus-visible:border-brand"
375
- ]])
376
- }, [
377
- createElementVNode("span", {
378
- class: "relative size-5 shrink-0 overflow-hidden rounded-inner",
379
- style: normalizeStyle({ background: CHECKERBOARD })
380
- }, [
381
- createElementVNode("span", {
382
- class: "block size-full",
383
- style: normalizeStyle({ backgroundColor: previewCss.value })
384
- }, null, 4),
385
- _cache[4] || (_cache[4] = createElementVNode("span", { class: "pointer-events-none absolute inset-0 rounded-inner ring-1 ring-inset ring-line" }, null, -1))
386
- ], 4),
387
- createElementVNode("span", _hoisted_3, toDisplayString(__props.label ?? current.value), 1),
388
- createVNode(_sfc_main$2, {
389
- name: "lucide:chevron-down",
390
- size: 15,
391
- class: "shrink-0 text-muted transition-transform duration-[var(--duration-fast)] ease-[var(--ease-emphasized)] group-data-[state=open]:rotate-180"
392
- })
393
- ], 10, _hoisted_2))
394
- ]),
395
- _: 1
396
- })
397
- ]),
398
- _: 1
399
- }, 8, ["items"])
400
- ]),
401
- _: 1
402
- }, 8, ["class"]),
403
- createVNode(unref(PopoverPortal), { to: unref(portalTo) }, {
404
- default: withCtx(() => [
405
- createVNode(unref(PopoverContent), {
406
- onInteractOutside: unref(guardOutside),
407
- onEscapeKeyDown: unref(guardOutside),
408
- "collision-padding": 8,
409
- side: __props.side,
410
- align: __props.align,
411
- "side-offset": 6,
412
- class: normalizeClass([unref(POPOVER_PANEL), "z-(--z-popover) w-64 select-none rounded-card p-3 outline-none"]),
413
- onOpenAutoFocus: onPanelOpen
414
- }, {
415
- default: withCtx(() => [
416
- createVNode(_sfc_main$1, { items: menuItems.value }, {
417
- default: withCtx(() => [
418
- createElementVNode("div", _hoisted_4, [
419
- createElementVNode("div", {
420
- role: "slider",
421
- tabindex: __props.disabled ? -1 : 0,
422
- "aria-label": unref(l).saturation,
423
- "aria-valuemin": 0,
424
- "aria-valuemax": 100,
425
- "aria-valuenow": Math.round(hsv.value.s * 100),
426
- "aria-valuetext": fill(unref(l).saturationValueText, { s: Math.round(hsv.value.s * 100), v: Math.round(hsv.value.v * 100) }),
427
- class: "relative h-36 w-full cursor-crosshair touch-none overflow-hidden rounded-control outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring",
428
- style: normalizeStyle(fieldStyle.value),
429
- onPointerdown: onFieldPointer,
430
- onKeydown: _cache[0] || (_cache[0] = ($event) => step($event, "sv"))
431
- }, [
432
- createElementVNode("span", {
433
- class: "pointer-events-none absolute size-3.5 -translate-x-1/2 -translate-y-1/2 rounded-pill border-2 border-white shadow ring-1 ring-black/30",
434
- style: normalizeStyle({
435
- left: `${hsv.value.s * 100}%`,
436
- top: `${(1 - hsv.value.v) * 100}%`,
437
- backgroundColor: previewCss.value
438
- })
439
- }, null, 4)
440
- ], 44, _hoisted_5),
441
- createElementVNode("div", {
442
- role: "slider",
443
- "aria-label": unref(l).hue,
444
- "aria-valuemin": 0,
445
- "aria-valuemax": 360,
446
- "aria-valuenow": Math.round(hsv.value.h),
447
- tabindex: __props.disabled ? -1 : 0,
448
- class: "relative h-3 w-full cursor-pointer touch-none rounded-pill outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring",
449
- style: { "background": "linear-gradient(to right, #f00, #ff0, #0f0, #0ff, #00f, #f0f, #f00)" },
450
- onPointerdown: onHuePointer,
451
- onKeydown: _cache[1] || (_cache[1] = ($event) => step($event, "h"))
452
- }, [
453
- createElementVNode("span", {
454
- class: "pointer-events-none absolute top-1/2 size-4 -translate-x-1/2 -translate-y-1/2 rounded-pill border-2 border-white shadow ring-1 ring-black/30",
455
- style: normalizeStyle({ left: `${hsv.value.h / 360 * 100}%`, backgroundColor: hueCss.value })
456
- }, null, 4)
457
- ], 40, _hoisted_6),
458
- __props.alpha ? (openBlock(), createElementBlock("div", {
459
- key: 0,
460
- role: "slider",
461
- "aria-label": unref(l).opacity,
462
- "aria-valuemin": 0,
463
- "aria-valuemax": 100,
464
- "aria-valuenow": Math.round(hsv.value.a * 100),
465
- tabindex: __props.disabled ? -1 : 0,
466
- class: "relative h-3 w-full cursor-pointer touch-none rounded-pill outline-none ring-1 ring-inset ring-line focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring",
467
- style: normalizeStyle({ background: CHECKERBOARD }),
468
- onPointerdown: onAlphaPointer,
469
- onKeydown: _cache[2] || (_cache[2] = ($event) => step($event, "a"))
470
- }, [
471
- createElementVNode("div", {
472
- class: "absolute inset-0 overflow-hidden rounded-pill",
473
- style: normalizeStyle({ backgroundImage: `linear-gradient(to right, ${alphaRampStart.value}, ${unref(opaqueCss)(hsv.value)})` })
474
- }, null, 4),
475
- createElementVNode("span", {
476
- class: "pointer-events-none absolute top-1/2 size-4 -translate-x-1/2 -translate-y-1/2 rounded-pill border-2 border-white shadow ring-1 ring-black/30",
477
- style: normalizeStyle({ left: `${hsv.value.a * 100}%`, backgroundColor: previewCss.value })
478
- }, null, 4)
479
- ], 44, _hoisted_7)) : createCommentVNode("", true),
480
- !__props.hideInput ? (openBlock(), createElementBlock("div", _hoisted_8, [
481
- createElementVNode("span", {
482
- class: "size-4 shrink-0 rounded-[5px] border border-line",
483
- style: normalizeStyle({ backgroundColor: previewCss.value })
484
- }, null, 4),
485
- createElementVNode("span", _hoisted_9, [
486
- withDirectives(createVNode(_sfc_main$3, {
487
- value: rollText.value,
488
- duration: ROLL_MS,
489
- align: "start",
490
- "aria-hidden": "true",
491
- class: "pointer-events-none absolute inset-0 font-mono text-xs text-ink"
492
- }, null, 8, ["value"]), [
493
- [vShow, rolling.value]
494
- ]),
495
- createElementVNode("input", {
496
- value: inputValue.value,
497
- disabled: __props.disabled,
498
- spellcheck: "false",
499
- autocapitalize: "off",
500
- autocomplete: "off",
501
- "aria-label": unref(l).value,
502
- class: normalizeClass(["min-w-0 flex-1 select-text bg-transparent font-mono text-xs text-ink outline-none placeholder:text-muted", rolling.value ? "text-transparent" : ""]),
503
- onInput,
504
- onKeydown: withKeys(commitTyped, ["enter"]),
505
- onBlur: onInputBlur
506
- }, null, 42, _hoisted_10)
507
- ])
508
- ])) : createCommentVNode("", true),
509
- (openBlock(true), createElementBlock(Fragment, null, renderList(swatchRows.value, (row) => {
510
- return openBlock(), createElementBlock("div", {
511
- key: row.key,
512
- class: "flex flex-col gap-1.5"
513
- }, [
514
- row.heading ? (openBlock(), createElementBlock("span", _hoisted_11, toDisplayString(row.heading), 1)) : createCommentVNode("", true),
515
- createElementVNode("div", {
516
- class: normalizeClass(["grid gap-1.5", row.cols])
517
- }, [
518
- (openBlock(true), createElementBlock(Fragment, null, renderList(row.colors, (c) => {
519
- return openBlock(), createElementBlock("button", {
520
- key: c,
521
- type: "button",
522
- disabled: __props.disabled,
523
- "aria-label": c,
524
- "aria-pressed": isActiveSwatch(c),
525
- class: normalizeClass(["relative flex items-center justify-center overflow-hidden rounded-inner outline-none transition-transform duration-[var(--duration-fast)] ease-[var(--ease-emphasized)] hover:scale-110 active:scale-95 focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed motion-reduce:hover:scale-100 motion-reduce:active:scale-95", row.size]),
526
- style: normalizeStyle({ background: CHECKERBOARD }),
527
- onClick: ($event) => pickSwatch(c)
528
- }, [
529
- createElementVNode("span", {
530
- class: "absolute inset-0",
531
- style: normalizeStyle({ backgroundColor: c })
532
- }, null, 4),
533
- _cache[5] || (_cache[5] = createElementVNode("span", { class: "pointer-events-none absolute inset-0 rounded-inner ring-1 ring-inset ring-line" }, null, -1)),
534
- isActiveSwatch(c) ? (openBlock(), createBlock(_sfc_main$2, {
535
- key: 0,
536
- name: "lucide:check",
537
- size: 13,
538
- class: normalizeClass(["relative", tickClass(c)])
539
- }, null, 8, ["class"])) : createCommentVNode("", true)
540
- ], 14, _hoisted_12);
541
- }), 128))
542
- ], 2)
543
- ]);
544
- }), 128)),
545
- renderSlot(_ctx.$slots, "default", {
546
- color: current.value,
547
- hsv: hsv.value
548
- })
549
- ])
550
- ]),
551
- _: 3
552
- }, 8, ["items"])
553
- ]),
554
- _: 3
555
- }, 8, ["onInteractOutside", "onEscapeKeyDown", "side", "align", "class"])
556
- ]),
557
- _: 3
558
- }, 8, ["to"])
559
- ]),
560
- _: 3
561
- }, 8, ["open"]);
562
- };
563
- }
564
- });
565
- export {
566
- _sfc_main as _
567
- };