@leavepulse/ui 0.77.3 → 0.78.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 (597) hide show
  1. package/README.md +68 -0
  2. package/dist/assets/{LpCommandPalette-DOIZHw-g.css → LpCommandPalette-DDJKICKh.css} +19 -19
  3. package/dist/assets/{LpDock-Cbh0wQUv.css → LpDock-Dw82tWVD.css} +3 -3
  4. package/dist/assets/{LpDropzone-B_qRq1-R.css → LpDropzone-DNbh_NFJ.css} +10 -10
  5. package/dist/assets/{LpImageEditor-XM5bAziW.css → LpImageEditor-Bgu20XLs.css} +6 -6
  6. package/dist/assets/{LpTable-Bv-EcQs7.css → LpTable-CCk0ZHo7.css} +19 -19
  7. package/dist/assets/LpTabs-Bh7a-Bdl.css +18 -0
  8. package/dist/chunks/AppShellContextNav-C6Ho2mof.js +49 -0
  9. package/dist/chunks/ChartRangeSelector-HO0sMMz6.js +129 -0
  10. package/dist/chunks/{ContextMenuItems-BXumicbh.js → ContextMenuItems-DmaKSJVv.js} +1 -1
  11. package/dist/chunks/{DropzoneLinkField-C-9BCGJn.js → DropzoneLinkField-DXIr0eFz.js} +2 -2
  12. package/dist/chunks/{FieldWrapper-CORPzo9s.js → FieldWrapper-DnuMTrqW.js} +1 -1
  13. package/dist/chunks/IconCloseButton-COZEsa9u.js +29 -0
  14. package/dist/chunks/{LayoutCanvas-CNOAUk7D.js → LayoutCanvas-CZKOltfA.js} +1 -1
  15. package/dist/chunks/{LayoutNode-DF5BMN0J.js → LayoutNode-D2f7v683.js} +45 -45
  16. package/dist/chunks/{LpActionBar-BP1ld7-S.js → LpActionBar-BGMk5KoG.js} +3 -3
  17. package/dist/chunks/{LpActivityLine-CJvzrNpj.js → LpActivityLine-Ea-t5Vza.js} +4 -2
  18. package/dist/chunks/{LpAddressInput-E8KtwU7-.js → LpAddressInput-ZqoZ-N2Y.js} +12 -11
  19. package/dist/chunks/{LpAlert-n5XPAZfv.js → LpAlert-CjvTZIKF.js} +3 -3
  20. package/dist/chunks/LpAppShell-BNAVTQsY.js +582 -0
  21. package/dist/chunks/{LpAutocomplete-C-SpPfBG.js → LpAutocomplete-DkY6CSyD.js} +24 -42
  22. package/dist/chunks/{LpAvatar-Cg6Az3wz.js → LpAvatar-cQVsNk6F.js} +2 -2
  23. package/dist/chunks/{LpBadge-wUYLN4U9.js → LpBadge-D5QQdDQ_.js} +2 -2
  24. package/dist/chunks/{LpBottomNav-CbNQQPuL.js → LpBottomNav-zxLGGbjm.js} +9 -2
  25. package/dist/chunks/{LpBreadcrumbs-DPdbth-c.js → LpBreadcrumbs-CIIBsygI.js} +4 -3
  26. package/dist/chunks/{LpButton-CFb44IjC.js → LpButton-DSHioIfD.js} +5 -4
  27. package/dist/chunks/{LpCalendar-CuoWks-0.js → LpCalendar-D4-LVjfF.js} +1 -1
  28. package/dist/chunks/{LpCard-r13WRqox.js → LpCard-BPtYXwnT.js} +1 -1
  29. package/dist/chunks/{LpCheckbox-Cs4SHaHX.js → LpCheckbox-D6RuDW4X.js} +38 -16
  30. package/dist/chunks/{LpCodeBlock-DRC8VbXW.js → LpCodeBlock-DuzmnIHl.js} +19 -41
  31. package/dist/chunks/{LpCodeDisplay-CE9TxCA4.js → LpCodeDisplay-CO8fngxa.js} +5 -5
  32. package/dist/chunks/{LpCollapse-CWS9M_lm.js → LpCollapse-DrAw5DBZ.js} +5 -4
  33. package/dist/chunks/{LpColorPicker-1y1QJHZR.js → LpColorPicker-BxAHEnR5.js} +11 -12
  34. package/dist/chunks/{LpCommandScope-CtUhJe8T.js → LpCommandScope-DRUvHiX7.js} +1 -1
  35. package/dist/chunks/{LpConfirmDialog-DlD45Bi_.js → LpConfirmDialog-6oCIJTDa.js} +3 -3
  36. package/dist/chunks/{LpConfirmHost-BIWjBLmI.js → LpConfirmHost-DgHvfT6s.js} +1 -1
  37. package/dist/chunks/{LpContextMenu-rx2tCjwk.js → LpContextMenu--eMGIql6.js} +13 -15
  38. package/dist/chunks/{LpContextSwitcher-Dwh6dyID.js → LpContextSwitcher-1C1tExdl.js} +2 -2
  39. package/dist/chunks/{LpCopyButton-xF7wFVoU.js → LpCopyButton-7EOSIuwa.js} +3 -3
  40. package/dist/chunks/{LpCountdown-DgeY3cLG.js → LpCountdown-DVl7vXI1.js} +4 -3
  41. package/dist/chunks/{LpDataList-Jxyl9H5w.js → LpDataList-DgBeM01y.js} +13 -4
  42. package/dist/chunks/{LpDatePicker-CA0QTfBC.js → LpDatePicker-DwSDY0mt.js} +12 -18
  43. package/dist/chunks/{LpDateRangePicker-u3J51xXk.js → LpDateRangePicker-CNQXdTVv.js} +10 -16
  44. package/dist/chunks/{LpDisclosure-Cpa7Hc5T.js → LpDisclosure-DG7JCo-d.js} +2 -2
  45. package/dist/chunks/{LpDrawer-CrG8t_KP.js → LpDrawer-Bt9UUqt_.js} +61 -61
  46. package/dist/chunks/{LpDropdownMenu-Dl7Z4ZhS.js → LpDropdownMenu-CLzxIOgM.js} +9 -17
  47. package/dist/chunks/{LpEditable-Cy6GLbFx.js → LpEditable-DVT0Rh8F.js} +9 -6
  48. package/dist/chunks/{LpEmptyState-EQHiRYhG.js → LpEmptyState-DurPF001.js} +1 -1
  49. package/dist/chunks/{LpFieldNotice-CzQ2_5rQ.js → LpFieldNotice-DJ10cYIo.js} +1 -1
  50. package/dist/chunks/LpFileTree-BSx1kBoV.js +735 -0
  51. package/dist/chunks/{LpFileTreeNode-cT6BIWvz.js → LpFileTreeNode-4dVmFHb3.js} +116 -34
  52. package/dist/chunks/{LpFormField-Ch69Jd-X.js → LpFormField-BKYn9dyP.js} +3 -3
  53. package/dist/chunks/{LpFrame-BVQCQLDI.js → LpFrame-Bv5Fphte.js} +25 -11
  54. package/dist/chunks/{LpHintExample-9Py0wc-L.js → LpHintExample-YzCXiSUp.js} +1 -1
  55. package/dist/chunks/{LpHintLayer-CgObdUsM.js → LpHintLayer-BeKRsRon.js} +2 -2
  56. package/dist/chunks/{LpHints-Bz-BlaSl.js → LpHints-qf3xYsza.js} +3 -3
  57. package/dist/chunks/{LpHoverCard-spGxyw7T.js → LpHoverCard-DanH3Nz1.js} +23 -5
  58. package/dist/chunks/{LpIcon--5WSb3jJ.js → LpIcon-C6JpQ5td.js} +6 -3
  59. package/dist/chunks/{LpIdenticon-BzdC_qz9.js → LpIdenticon-Dbbr4fvt.js} +2 -1
  60. package/dist/chunks/{LpInfraNode-46XOCkfq.js → LpInfraNode-BAU40Km2.js} +2 -2
  61. package/dist/chunks/{LpInput-Tw-yxT4I.js → LpInput-DL6HEJdi.js} +16 -28
  62. package/dist/chunks/LpInspector-CuoMAhiw.js +209 -0
  63. package/dist/chunks/{LpLightbox-B95yu22B.js → LpLightbox-xvpQ64MM.js} +57 -32
  64. package/dist/chunks/{LpLoader-DVwkOmt9.js → LpLoader-Bf1yZwaU.js} +1 -1
  65. package/dist/chunks/LpLogInspector-6cNnXqp4.js +119 -0
  66. package/dist/chunks/{LpLogViewer-ngqkns4m.js → LpLogViewer-Dvb1E9_G.js} +234 -53
  67. package/dist/chunks/{LpMapPicker-DRGgh89B.js → LpMapPicker-D5_YLLBC.js} +4 -3
  68. package/dist/chunks/{LpMasonry--k0571qG.js → LpMasonry-DPYekFxs.js} +8 -5
  69. package/dist/chunks/{LpMediaGallery-Bkram-MO.js → LpMediaGallery-Df-tiWeq.js} +3 -3
  70. package/dist/chunks/{LpModal-CoGhLTyH.js → LpModal-DrtQ_1A2.js} +11 -13
  71. package/dist/chunks/{LpModalNav-BGvs2y5Q.js → LpModalNav-DkmGCnZE.js} +11 -37
  72. package/dist/chunks/{LpNotificationBell-B0034Lk-.js → LpNotificationBell-D_wklO1m.js} +9 -9
  73. package/dist/chunks/{LpNumberField-e0IBkWU1.js → LpNumberField-CNHsmSDZ.js} +7 -16
  74. package/dist/chunks/{LpOtpInput-CeBPsM7D.js → LpOtpInput-BRpLBbOD.js} +2 -2
  75. package/dist/chunks/{LpPagination-BIIiYHXR.js → LpPagination-snQ020xQ.js} +6 -4
  76. package/dist/chunks/{LpPaletteTheme-DiLYKQiZ.js → LpPaletteTheme-dVtxHx-F.js} +4 -4
  77. package/dist/chunks/{LpPasswordInput-BkHKQDhM.js → LpPasswordInput-B-zD6tUS.js} +2 -2
  78. package/dist/chunks/{LpPhoneInput-CETEp5W7.js → LpPhoneInput-BSL7NX4z.js} +15 -26
  79. package/dist/chunks/{LpPie-DrZepi0p.js → LpPie-9t_guO49.js} +22 -21
  80. package/dist/chunks/{LpPipeline-B3aOVOkV.js → LpPipeline-rjXvEDRJ.js} +16 -7
  81. package/dist/chunks/{LpPopover-DmZ3wUtP.js → LpPopover-BQSuxtai.js} +10 -1
  82. package/dist/chunks/{LpProgress-Yr6ONG5t.js → LpProgress-D_MSjowb.js} +2 -1
  83. package/dist/chunks/{LpQuota-Dk2MyI2Z.js → LpQuota-CgWPgdVt.js} +1 -1
  84. package/dist/chunks/{LpRadioGroup-ggaPL92T.js → LpRadioGroup-BrazjLY_.js} +4 -4
  85. package/dist/chunks/{LpRangeCalendar-CYYUYqJ7.js → LpRangeCalendar-BrqlGZzE.js} +1 -1
  86. package/dist/chunks/{LpRangeSlider-CM-0ZITZ.js → LpRangeSlider-fz61tzc-.js} +5 -9
  87. package/dist/chunks/{LpRelativeTime-DwgCb5-8.js → LpRelativeTime-BovUk8MP.js} +1 -1
  88. package/dist/chunks/{LpRepeater-D7ZmnIYd.js → LpRepeater-BkJHSPI1.js} +3 -3
  89. package/dist/chunks/{LpRevealOnScroll-DcQjexLy.js → LpRevealOnScroll-CPwyiQAr.js} +1 -1
  90. package/dist/chunks/{LpScramble-Bn9OoOtC.js → LpScramble-DsE77iVp.js} +1 -1
  91. package/dist/chunks/{LpScrollArea-MyEnVB_5.js → LpScrollArea-ay4Xo_hg.js} +22 -10
  92. package/dist/chunks/{LpSecretField-BbmqM9ye.js → LpSecretField-DBvU6iAw.js} +10 -9
  93. package/dist/chunks/{LpSection-DFK_uoJE.js → LpSection-BfteipxU.js} +1 -1
  94. package/dist/chunks/{LpSegmented-CeACsMMA.js → LpSegmented-DbEJhbv-.js} +8 -10
  95. package/dist/chunks/{LpSelect-Cxq4yBGd.js → LpSelect-Y-iuSymW.js} +47 -30
  96. package/dist/chunks/{LpShaderBackdrop-Bote0iuy.js → LpShaderBackdrop-wQygYb5h.js} +13 -10
  97. package/dist/chunks/{LpShift-CCq7dofl.js → LpShift-DAgS_d2x.js} +18 -15
  98. package/dist/chunks/{LpSidebar-DzE1783C.js → LpSidebar-kSkpPh3-.js} +74 -87
  99. package/dist/chunks/{LpSidebarNav-DE3PhXVP.js → LpSidebarNav-C2mvqrY2.js} +8 -6
  100. package/dist/chunks/{LpSidebarRow-BRYhNDSo.js → LpSidebarRow-eRP4Q31q.js} +6 -5
  101. package/dist/chunks/{LpSlider-DxYoCJJO.js → LpSlider-A4ixovgS.js} +5 -9
  102. package/dist/chunks/{LpSpotlight-4F3NeUMY.js → LpSpotlight-DwxkhFgR.js} +2 -1
  103. package/dist/chunks/{LpStat-f2LfDCJ4.js → LpStat-pMNZgFcq.js} +2 -2
  104. package/dist/chunks/{LpStatus-DglxttQ7.js → LpStatus-DGJFwk5F.js} +2 -2
  105. package/dist/chunks/{LpStepMark-DpzKVyh8.js → LpStepMark-Dw2MRTrt.js} +2 -2
  106. package/dist/chunks/{LpStepper-DpsocBNJ.js → LpStepper-DNnh7lCu.js} +1 -1
  107. package/dist/chunks/{LpSwap-C96c0LWh.js → LpSwap-M7nFeW3C.js} +1 -1
  108. package/dist/chunks/{LpSwitch-BnXd1llc.js → LpSwitch-DnC2-0aV.js} +3 -3
  109. package/dist/chunks/{LpTabFace-DPCwKkH2.js → LpTabFace-DQoV8mQG.js} +2 -2
  110. package/dist/chunks/{LpTableFilter-CiVBpaq0.js → LpTableFilter-DgARTsA1.js} +4 -4
  111. package/dist/chunks/{LpTableOfContents-BN5zvpnx.js → LpTableOfContents-CKkWEK6R.js} +14 -9
  112. package/dist/chunks/{LpTagsInput-C-mDG648.js → LpTagsInput-Dt0mteSj.js} +19 -27
  113. package/dist/chunks/{LpTextarea-TE-yZv2U.js → LpTextarea-Co0b9PVx.js} +8 -16
  114. package/dist/chunks/LpThemeProvider-XK6ZeWAE.js +81 -0
  115. package/dist/chunks/{LpThemeStudio-BpORDvH6.js → LpThemeStudio-DzYfE-5k.js} +12 -195
  116. package/dist/chunks/{LpThemeSwitcher-BnEn_mvf.js → LpThemeSwitcher-CFLkdbBL.js} +8 -6
  117. package/dist/chunks/{LpTimeField-BawSVsmt.js → LpTimeField-DeOcKWJq.js} +6 -9
  118. package/dist/chunks/{LpToaster-IwTXjbbU.js → LpToaster-QFj0P-5m.js} +10 -8
  119. package/dist/chunks/{LpTooltip-BcBvIx4z.js → LpTooltip-BJf3lZMq.js} +51 -19
  120. package/dist/chunks/LpTopologyCanvas-BOHHHZ_6.js +673 -0
  121. package/dist/chunks/{LpTour-BZq-mUMv.js → LpTour-ClKYhx4h.js} +7 -5
  122. package/dist/chunks/{LpTruncate-CflAIwiJ.js → LpTruncate-C6u3gjc6.js} +6 -5
  123. package/dist/chunks/{LpTypewriter-BCL_a6wE.js → LpTypewriter-CZIzpdbe.js} +2 -1
  124. package/dist/chunks/{LpUptimeBar-DqNvvMBK.js → LpUptimeBar-BnYmR2rj.js} +3 -3
  125. package/dist/chunks/{LpVideoBackdrop-DS1wGv-X.js → LpVideoBackdrop-Ct4St4ZL.js} +10 -13
  126. package/dist/chunks/LpWindow-B8YSRVTH.js +297 -0
  127. package/dist/chunks/LpWorkspaceSwitcher-D0e9upAy.js +139 -0
  128. package/dist/chunks/{MenuTitle-BmCNNTKH.js → MenuTitle-Bh5dAdV1.js} +1 -1
  129. package/dist/chunks/{OptionContent-22UT8zLn.js → OptionContent-CGb8QlHA.js} +1 -1
  130. package/dist/chunks/{PickerField-Bfh8id3d.js → PickerField-BM1dyafh.js} +4 -4
  131. package/dist/chunks/{RevealToggle-BEit1n6Z.js → RevealToggle-CCPDE8Mv.js} +3 -3
  132. package/dist/chunks/SliderRail-DhPREa_R.js +18 -0
  133. package/dist/chunks/{TourCard-DNclH3u_.js → TourCard-DAzTYfav.js} +4 -4
  134. package/dist/chunks/{icons-DMITlfw5.js → icons-CYfcpSDS.js} +26 -10
  135. package/dist/component-names.d.ts +1 -1
  136. package/dist/components/AppShellContextNav.vue.d.ts +13 -0
  137. package/dist/components/AppShellContextNav.vue.js +4 -0
  138. package/dist/components/ChartRangeSelector.vue.d.ts +21 -0
  139. package/dist/components/ChartRangeSelector.vue.js +4 -0
  140. package/dist/components/ContextMenuItems.vue.js +1 -1
  141. package/dist/components/DropzoneLinkField.vue.d.ts +2 -2
  142. package/dist/components/DropzoneLinkField.vue.js +1 -1
  143. package/dist/components/FieldWrapper.vue.js +1 -1
  144. package/dist/components/IconCloseButton.vue.d.ts +7 -0
  145. package/dist/components/IconCloseButton.vue.js +4 -0
  146. package/dist/components/LayoutCanvas.vue.js +1 -1
  147. package/dist/components/LayoutNode.vue.js +1 -1
  148. package/dist/components/LpActionBar.vue.js +1 -1
  149. package/dist/components/LpActivityLine.vue.js +1 -1
  150. package/dist/components/LpAddressInput.vue.js +1 -1
  151. package/dist/components/LpAlert.vue.js +1 -1
  152. package/dist/components/LpAppShell.vue.d.ts +110 -2
  153. package/dist/components/LpAppShell.vue.js +1 -1
  154. package/dist/components/LpAutocomplete.vue.js +1 -1
  155. package/dist/components/LpAvatar.vue.js +1 -1
  156. package/dist/components/LpBadge.vue.js +1 -1
  157. package/dist/components/LpBottomNav.vue.d.ts +5 -0
  158. package/dist/components/LpBottomNav.vue.js +1 -1
  159. package/dist/components/LpBreadcrumbs.vue.js +1 -1
  160. package/dist/components/LpButton.vue.d.ts +14 -2
  161. package/dist/components/LpButton.vue.js +1 -1
  162. package/dist/components/LpCalendar.vue.js +1 -1
  163. package/dist/components/LpCard.vue.js +1 -1
  164. package/dist/components/LpChart.vue.d.ts +74 -2
  165. package/dist/components/LpChart.vue.js +326 -85
  166. package/dist/components/LpCheckbox.vue.d.ts +6 -2
  167. package/dist/components/LpCheckbox.vue.js +1 -1
  168. package/dist/components/LpCodeBlock.vue.js +1 -1
  169. package/dist/components/LpCodeDisplay.vue.js +1 -1
  170. package/dist/components/LpCollapse.vue.js +1 -1
  171. package/dist/components/LpColorPicker.vue.js +1 -1
  172. package/dist/components/LpCommandPalette.vue.d.ts +8 -0
  173. package/dist/components/LpCommandPalette.vue.js +107 -56
  174. package/dist/components/LpCommandScope.vue.js +1 -1
  175. package/dist/components/LpConfirmDialog.vue.js +1 -1
  176. package/dist/components/LpConfirmHost.vue.js +1 -1
  177. package/dist/components/LpContextMenu.vue.js +1 -1
  178. package/dist/components/LpContextSwitcher.vue.js +1 -1
  179. package/dist/components/LpCopyButton.vue.js +1 -1
  180. package/dist/components/LpCountdown.vue.js +1 -1
  181. package/dist/components/LpDataList.vue.d.ts +1 -1
  182. package/dist/components/LpDataList.vue.js +1 -1
  183. package/dist/components/LpDatePicker.vue.d.ts +3 -15
  184. package/dist/components/LpDatePicker.vue.js +1 -1
  185. package/dist/components/LpDateRangePicker.vue.d.ts +3 -13
  186. package/dist/components/LpDateRangePicker.vue.js +1 -1
  187. package/dist/components/LpDisclosure.vue.js +1 -1
  188. package/dist/components/LpDock.vue.js +21 -18
  189. package/dist/components/LpDrawer.vue.d.ts +1 -1
  190. package/dist/components/LpDrawer.vue.js +1 -1
  191. package/dist/components/LpDropdownMenu.vue.js +1 -1
  192. package/dist/components/LpDropzone.vue.js +14 -11
  193. package/dist/components/LpEditable.vue.js +1 -1
  194. package/dist/components/LpEmptyState.vue.js +1 -1
  195. package/dist/components/LpFieldNotice.vue.js +1 -1
  196. package/dist/components/LpFileTree.vue.d.ts +96 -6
  197. package/dist/components/LpFileTree.vue.js +1 -1
  198. package/dist/components/LpFileTreeNode.vue.d.ts +48 -0
  199. package/dist/components/LpFileTreeNode.vue.js +1 -1
  200. package/dist/components/LpFormField.vue.js +1 -1
  201. package/dist/components/LpFrame.vue.js +1 -1
  202. package/dist/components/LpGauge.vue.d.ts +1 -1
  203. package/dist/components/LpHintExample.vue.js +1 -1
  204. package/dist/components/LpHintLayer.vue.js +1 -1
  205. package/dist/components/LpHints.vue.js +1 -1
  206. package/dist/components/LpHoverCard.vue.js +1 -1
  207. package/dist/components/LpIcon.vue.d.ts +2 -0
  208. package/dist/components/LpIcon.vue.js +1 -1
  209. package/dist/components/LpIdenticon.vue.js +1 -1
  210. package/dist/components/LpImageEditor.vue.js +7 -6
  211. package/dist/components/LpInfraNode.vue.js +1 -1
  212. package/dist/components/LpInput.vue.d.ts +1 -1
  213. package/dist/components/LpInput.vue.js +1 -1
  214. package/dist/components/LpInspector.vue.d.ts +87 -0
  215. package/dist/components/LpInspector.vue.js +4 -0
  216. package/dist/components/LpLightbox.vue.d.ts +8 -0
  217. package/dist/components/LpLightbox.vue.js +1 -1
  218. package/dist/components/LpLoader.vue.d.ts +1 -1
  219. package/dist/components/LpLoader.vue.js +1 -1
  220. package/dist/components/LpLogInspector.vue.d.ts +18 -0
  221. package/dist/components/LpLogInspector.vue.js +4 -0
  222. package/dist/components/LpLogViewer.vue.d.ts +93 -0
  223. package/dist/components/LpLogViewer.vue.js +1 -1
  224. package/dist/components/LpMapPicker.vue.js +1 -1
  225. package/dist/components/LpMasonry.vue.js +1 -1
  226. package/dist/components/LpMediaGallery.vue.js +1 -1
  227. package/dist/components/LpModal.vue.d.ts +4 -2
  228. package/dist/components/LpModal.vue.js +1 -1
  229. package/dist/components/LpModalNav.vue.d.ts +5 -5
  230. package/dist/components/LpModalNav.vue.js +1 -1
  231. package/dist/components/LpNotificationBell.vue.d.ts +2 -2
  232. package/dist/components/LpNotificationBell.vue.js +1 -1
  233. package/dist/components/LpNumberField.vue.js +1 -1
  234. package/dist/components/LpOtpInput.vue.js +1 -1
  235. package/dist/components/LpPagination.vue.js +1 -1
  236. package/dist/components/LpPaletteFacts.vue.js +1 -1
  237. package/dist/components/LpPaletteHeader.vue.js +2 -2
  238. package/dist/components/LpPaletteTheme.vue.js +1 -1
  239. package/dist/components/LpPasswordInput.vue.js +1 -1
  240. package/dist/components/LpPhoneInput.vue.js +1 -1
  241. package/dist/components/LpPie.vue.d.ts +2 -2
  242. package/dist/components/LpPie.vue.js +1 -1
  243. package/dist/components/LpPipeline.vue.d.ts +4 -0
  244. package/dist/components/LpPipeline.vue.js +1 -1
  245. package/dist/components/LpPopover.vue.d.ts +7 -3
  246. package/dist/components/LpPopover.vue.js +1 -1
  247. package/dist/components/LpProgress.vue.d.ts +1 -1
  248. package/dist/components/LpProgress.vue.js +1 -1
  249. package/dist/components/LpQuota.vue.js +1 -1
  250. package/dist/components/LpRadioGroup.vue.js +1 -1
  251. package/dist/components/LpRangeCalendar.vue.js +1 -1
  252. package/dist/components/LpRangeSlider.vue.js +1 -1
  253. package/dist/components/LpRelativeTime.vue.js +1 -1
  254. package/dist/components/LpRepeater.vue.js +1 -1
  255. package/dist/components/LpRevealOnScroll.vue.js +1 -1
  256. package/dist/components/LpScramble.vue.js +1 -1
  257. package/dist/components/LpScrollArea.vue.js +1 -1
  258. package/dist/components/LpSecretField.vue.js +1 -1
  259. package/dist/components/LpSection.vue.js +1 -1
  260. package/dist/components/LpSegmented.vue.js +1 -1
  261. package/dist/components/LpSelect.vue.js +1 -1
  262. package/dist/components/LpShaderBackdrop.vue.js +1 -1
  263. package/dist/components/LpShift.vue.js +1 -1
  264. package/dist/components/LpShortcutsDialog.vue.js +1 -1
  265. package/dist/components/LpSidebar.vue.d.ts +1 -1
  266. package/dist/components/LpSidebar.vue.js +1 -1
  267. package/dist/components/LpSidebarNav.vue.js +1 -1
  268. package/dist/components/LpSidebarRow.vue.js +1 -1
  269. package/dist/components/LpSlider.vue.js +1 -1
  270. package/dist/components/LpSparkline.vue.d.ts +1 -1
  271. package/dist/components/LpSpotlight.vue.js +1 -1
  272. package/dist/components/LpStat.vue.js +1 -1
  273. package/dist/components/LpStatus.vue.js +1 -1
  274. package/dist/components/LpStepMark.vue.js +1 -1
  275. package/dist/components/LpStepper.vue.js +1 -1
  276. package/dist/components/LpSwap.vue.js +1 -1
  277. package/dist/components/LpSwitch.vue.js +1 -1
  278. package/dist/components/LpTabFace.vue.js +1 -1
  279. package/dist/components/LpTable.vue.d.ts +132 -0
  280. package/dist/components/LpTable.vue.js +547 -135
  281. package/dist/components/LpTableFilter.vue.js +1 -1
  282. package/dist/components/LpTableOfContents.vue.js +1 -1
  283. package/dist/components/LpTabs.vue.js +6 -5
  284. package/dist/components/LpTagsInput.vue.js +1 -1
  285. package/dist/components/LpTextarea.vue.js +1 -1
  286. package/dist/components/LpThemeProvider.vue.d.ts +2 -0
  287. package/dist/components/LpThemeProvider.vue.js +1 -1
  288. package/dist/components/LpThemeStudio.vue.js +1 -1
  289. package/dist/components/LpThemeSwitcher.vue.js +1 -1
  290. package/dist/components/LpTimeField.vue.js +1 -1
  291. package/dist/components/LpToaster.vue.js +1 -1
  292. package/dist/components/LpTooltip.vue.js +1 -1
  293. package/dist/components/LpTopologyCanvas.vue.d.ts +131 -5
  294. package/dist/components/LpTopologyCanvas.vue.js +1 -1
  295. package/dist/components/LpTour.vue.js +1 -1
  296. package/dist/components/LpTruncate.vue.js +1 -1
  297. package/dist/components/LpTypewriter.vue.js +1 -1
  298. package/dist/components/LpUptimeBar.vue.js +1 -1
  299. package/dist/components/LpVideoBackdrop.vue.js +1 -1
  300. package/dist/components/LpWindow.vue.d.ts +99 -0
  301. package/dist/components/LpWindow.vue.js +4 -0
  302. package/dist/components/LpWorkspaceSwitcher.vue.d.ts +18 -0
  303. package/dist/components/LpWorkspaceSwitcher.vue.js +4 -0
  304. package/dist/components/MenuTitle.vue.js +1 -1
  305. package/dist/components/OptionContent.vue.js +1 -1
  306. package/dist/components/PickerField.vue.d.ts +2 -2
  307. package/dist/components/PickerField.vue.js +1 -1
  308. package/dist/components/RevealToggle.vue.js +1 -1
  309. package/dist/components/SliderRail.vue.d.ts +3 -0
  310. package/dist/components/SliderRail.vue.js +4 -0
  311. package/dist/components/TourCard.vue.js +1 -1
  312. package/dist/components/address.js +2 -1
  313. package/dist/components/appShell.d.ts +36 -0
  314. package/dist/components/appShell.js +30 -0
  315. package/dist/components/calendar.d.ts +12 -3
  316. package/dist/components/calendar.js +2 -5
  317. package/dist/components/chart.d.ts +21 -0
  318. package/dist/components/chart.js +4 -3
  319. package/dist/components/chartWindow.d.ts +57 -0
  320. package/dist/components/chartWindow.js +136 -0
  321. package/dist/components/color.js +1 -1
  322. package/dist/components/commandPalette.d.ts +16 -2
  323. package/dist/components/commandPalette.js +39 -4
  324. package/dist/components/controlSize.d.ts +5 -0
  325. package/dist/components/controlSize.js +8 -0
  326. package/dist/components/dropdown.d.ts +5 -0
  327. package/dist/components/dropdown.js +2 -0
  328. package/dist/components/exportData.d.ts +6 -1
  329. package/dist/components/exportData.js +25 -18
  330. package/dist/components/fileTree.d.ts +67 -0
  331. package/dist/components/fileTree.js +141 -1
  332. package/dist/components/identicon.js +3 -2
  333. package/dist/components/logTools.d.ts +93 -0
  334. package/dist/components/logTools.js +210 -0
  335. package/dist/components/menuWhen.js +1 -1
  336. package/dist/components/meter.js +2 -1
  337. package/dist/components/pipeline.d.ts +2 -0
  338. package/dist/components/pipeline.js +5 -0
  339. package/dist/components/relativeTime.js +2 -1
  340. package/dist/components/reveal.js +2 -1
  341. package/dist/components/select.d.ts +5 -0
  342. package/dist/components/select.js +10 -0
  343. package/dist/components/sidebar.d.ts +1 -0
  344. package/dist/components/tableFeatures.d.ts +58 -0
  345. package/dist/components/tableFeatures.js +87 -0
  346. package/dist/components/topologyGraph.d.ts +164 -0
  347. package/dist/components/topologyGraph.js +416 -0
  348. package/dist/components/tour.js +5 -3
  349. package/dist/components/videoBackdrop.js +7 -6
  350. package/dist/composables/clamp.d.ts +2 -0
  351. package/dist/composables/clamp.js +4 -0
  352. package/dist/composables/devWarn.d.ts +3 -0
  353. package/dist/composables/devWarn.js +14 -0
  354. package/dist/composables/easing.d.ts +13 -4
  355. package/dist/composables/easing.js +16 -10
  356. package/dist/composables/overlayHistory.js +14 -1
  357. package/dist/composables/pointerDrag.d.ts +15 -0
  358. package/dist/composables/pointerDrag.js +40 -0
  359. package/dist/composables/propCheck.d.ts +10 -0
  360. package/dist/composables/propCheck.js +78 -0
  361. package/dist/composables/realm.d.ts +6 -0
  362. package/dist/composables/realm.js +23 -0
  363. package/dist/composables/scroll.js +4 -2
  364. package/dist/composables/scrollMemory.d.ts +12 -1
  365. package/dist/composables/scrollMemory.js +36 -12
  366. package/dist/composables/spatialNav.js +2 -1
  367. package/dist/composables/textEntry.d.ts +17 -0
  368. package/dist/composables/textEntry.js +19 -0
  369. package/dist/composables/useAsyncTask.d.ts +6 -0
  370. package/dist/composables/useChartSync.d.ts +5 -0
  371. package/dist/composables/useChartSync.js +33 -0
  372. package/dist/composables/useCloseGuard.d.ts +3 -1
  373. package/dist/composables/useCloseGuard.js +6 -3
  374. package/dist/composables/useCommands.d.ts +50 -0
  375. package/dist/composables/useCommands.js +66 -0
  376. package/dist/composables/useField.d.ts +37 -0
  377. package/dist/composables/useField.js +27 -2
  378. package/dist/composables/useFitScale.js +4 -1
  379. package/dist/composables/useFormDraft.d.ts +13 -2
  380. package/dist/composables/useFormDraft.js +17 -9
  381. package/dist/composables/useHintSystem.js +2 -2
  382. package/dist/composables/useHotkeys.js +11 -32
  383. package/dist/composables/useInView.js +2 -1
  384. package/dist/composables/useInputFilter.js +7 -5
  385. package/dist/composables/useInputMask.js +5 -3
  386. package/dist/composables/useLinkedView.d.ts +97 -0
  387. package/dist/composables/useLinkedView.js +139 -0
  388. package/dist/composables/useOptimisticToggle.d.ts +3 -1
  389. package/dist/composables/useOptimisticToggle.js +2 -1
  390. package/dist/composables/useOverlayHistory.d.ts +7 -0
  391. package/dist/composables/useOverlayHistory.js +16 -2
  392. package/dist/composables/usePaintSelect.js +18 -14
  393. package/dist/composables/usePaletteCommands.d.ts +7 -0
  394. package/dist/composables/usePaletteCommands.js +12 -1
  395. package/dist/composables/usePersisted.d.ts +10 -0
  396. package/dist/composables/usePersisted.js +1 -1
  397. package/dist/composables/usePillTransition.d.ts +2 -2
  398. package/dist/composables/usePillTransition.js +5 -5
  399. package/dist/composables/useResizeObserver.js +2 -1
  400. package/dist/composables/useReveal.js +2 -1
  401. package/dist/composables/useRovingFocus.d.ts +2 -2
  402. package/dist/composables/useRovingFocus.js +9 -11
  403. package/dist/composables/useScramble.js +7 -1
  404. package/dist/composables/useShift.js +8 -6
  405. package/dist/composables/useTilt.js +2 -1
  406. package/dist/composables/useTween.js +9 -5
  407. package/dist/composables/useView.d.ts +1 -0
  408. package/dist/composables/useView.js +14 -2
  409. package/dist/composables/useZoomPan.js +2 -4
  410. package/dist/composables/windowing.d.ts +40 -0
  411. package/dist/composables/windowing.js +118 -0
  412. package/dist/icons-all.js +1 -1
  413. package/dist/icons.d.ts +4 -0
  414. package/dist/index.d.ts +30 -5
  415. package/dist/index.js +310 -264
  416. package/dist/layout/tree.js +19 -15
  417. package/dist/layout/useLayout.d.ts +2 -0
  418. package/dist/layout/useLayout.js +5 -1
  419. package/dist/layout/useWorkspaces.d.ts +52 -0
  420. package/dist/layout/useWorkspaces.js +140 -0
  421. package/dist/{chunks/backdrop-Dkf2vM81.js → theme/backdrop.js} +5 -5
  422. package/dist/theme/config.js +25 -0
  423. package/dist/theme/define.js +61 -0
  424. package/dist/{chunks/palette-Co8tSASo.js → theme/palette.js} +2 -2
  425. package/dist/theme/presets.js +239 -0
  426. package/dist/theme/studio.js +134 -0
  427. package/dist/theme/tokens.js +63 -0
  428. package/dist/theme/useTheme.d.ts +3 -2
  429. package/dist/theme/useTheme.js +325 -0
  430. package/package.json +8 -1
  431. package/src/component-names.ts +5 -1
  432. package/src/components/AppShellContextNav.vue +44 -0
  433. package/src/components/ChartRangeSelector.vue +120 -0
  434. package/src/components/IconCloseButton.vue +21 -0
  435. package/src/components/LayoutCanvas.vue +3 -0
  436. package/src/components/LayoutNode.vue +37 -38
  437. package/src/components/LpActivityLine.vue +4 -2
  438. package/src/components/LpAddressInput.vue +3 -3
  439. package/src/components/LpAppShell.vue +362 -24
  440. package/src/components/LpAutocomplete.vue +13 -30
  441. package/src/components/LpBottomNav.vue +9 -1
  442. package/src/components/LpBreadcrumbs.vue +2 -1
  443. package/src/components/LpButton.vue +11 -4
  444. package/src/components/LpChart.vue +336 -37
  445. package/src/components/LpCheckbox.vue +43 -9
  446. package/src/components/LpCodeBlock.vue +17 -23
  447. package/src/components/LpCollapse.vue +5 -4
  448. package/src/components/LpColorPicker.vue +8 -9
  449. package/src/components/LpCommandPalette.vue +133 -50
  450. package/src/components/LpContextMenu.vue +15 -13
  451. package/src/components/LpCountdown.vue +2 -1
  452. package/src/components/LpDataList.vue +13 -1
  453. package/src/components/LpDatePicker.vue +5 -17
  454. package/src/components/LpDateRangePicker.vue +5 -16
  455. package/src/components/LpDock.vue +25 -16
  456. package/src/components/LpDrawer.vue +70 -61
  457. package/src/components/LpDropdownMenu.vue +6 -10
  458. package/src/components/LpDropzone.vue +12 -7
  459. package/src/components/LpEditable.vue +6 -2
  460. package/src/components/LpFileTree.vue +507 -66
  461. package/src/components/LpFileTreeNode.vue +106 -5
  462. package/src/components/LpFormField.vue +1 -1
  463. package/src/components/LpFrame.vue +33 -13
  464. package/src/components/LpHoverCard.vue +30 -5
  465. package/src/components/LpIcon.vue +6 -2
  466. package/src/components/LpIdenticon.vue +2 -1
  467. package/src/components/LpImageEditor.vue +5 -2
  468. package/src/components/LpInput.vue +15 -23
  469. package/src/components/LpInspector.vue +197 -0
  470. package/src/components/LpLightbox.vue +74 -29
  471. package/src/components/LpLogInspector.vue +85 -0
  472. package/src/components/LpLogViewer.vue +239 -29
  473. package/src/components/LpMapPicker.vue +2 -1
  474. package/src/components/LpMasonry.vue +8 -5
  475. package/src/components/LpModal.vue +12 -12
  476. package/src/components/LpModalNav.vue +2 -21
  477. package/src/components/LpNumberField.vue +6 -15
  478. package/src/components/LpOtpInput.vue +2 -2
  479. package/src/components/LpPagination.vue +5 -3
  480. package/src/components/LpPhoneInput.vue +8 -19
  481. package/src/components/LpPie.vue +25 -23
  482. package/src/components/LpPipeline.vue +14 -1
  483. package/src/components/LpPopover.vue +23 -2
  484. package/src/components/LpProgress.vue +2 -1
  485. package/src/components/LpRadioGroup.vue +2 -2
  486. package/src/components/LpRangeSlider.vue +5 -6
  487. package/src/components/LpRevealOnScroll.vue +1 -1
  488. package/src/components/LpScrollArea.vue +28 -11
  489. package/src/components/LpSecretField.vue +2 -1
  490. package/src/components/LpSegmented.vue +6 -8
  491. package/src/components/LpSelect.vue +54 -24
  492. package/src/components/LpShaderBackdrop.vue +12 -9
  493. package/src/components/LpShift.vue +18 -15
  494. package/src/components/LpSidebar.vue +77 -74
  495. package/src/components/LpSidebarNav.vue +3 -2
  496. package/src/components/LpSidebarRow.vue +2 -1
  497. package/src/components/LpSlider.vue +5 -6
  498. package/src/components/LpSpotlight.vue +2 -1
  499. package/src/components/LpSwitch.vue +5 -3
  500. package/src/components/LpTable.vue +609 -93
  501. package/src/components/LpTableFilter.vue +1 -1
  502. package/src/components/LpTableOfContents.vue +16 -9
  503. package/src/components/LpTabs.vue +2 -1
  504. package/src/components/LpTagsInput.vue +12 -19
  505. package/src/components/LpTextarea.vue +5 -11
  506. package/src/components/LpThemeProvider.vue +29 -13
  507. package/src/components/LpTimeField.vue +4 -7
  508. package/src/components/LpToaster.vue +7 -6
  509. package/src/components/LpTooltip.vue +62 -18
  510. package/src/components/LpTopologyCanvas.vue +567 -42
  511. package/src/components/LpTour.vue +7 -5
  512. package/src/components/LpTruncate.vue +4 -3
  513. package/src/components/LpTypewriter.vue +2 -1
  514. package/src/components/LpVideoBackdrop.vue +11 -13
  515. package/src/components/LpWindow.vue +373 -0
  516. package/src/components/LpWorkspaceSwitcher.vue +116 -0
  517. package/src/components/PickerField.vue +2 -2
  518. package/src/components/SliderRail.vue +10 -0
  519. package/src/components/address.ts +3 -1
  520. package/src/components/appShell.ts +74 -0
  521. package/src/components/calendar.ts +12 -5
  522. package/src/components/chart.ts +27 -3
  523. package/src/components/chartWindow.ts +198 -0
  524. package/src/components/color.ts +2 -1
  525. package/src/components/commandPalette.ts +66 -5
  526. package/src/components/controlSize.ts +6 -0
  527. package/src/components/dropdown.ts +3 -0
  528. package/src/components/exportData.ts +33 -18
  529. package/src/components/fileTree.ts +215 -0
  530. package/src/components/identicon.ts +4 -2
  531. package/src/components/logTools.ts +298 -0
  532. package/src/components/meter.ts +2 -1
  533. package/src/components/pipeline.ts +6 -0
  534. package/src/components/relativeTime.ts +2 -1
  535. package/src/components/reveal.ts +3 -1
  536. package/src/components/select.ts +14 -0
  537. package/src/components/sidebar.ts +1 -0
  538. package/src/components/tableFeatures.ts +149 -0
  539. package/src/components/topologyGraph.ts +655 -0
  540. package/src/components/tour.ts +5 -3
  541. package/src/components/videoBackdrop.ts +7 -6
  542. package/src/composables/clamp.ts +2 -0
  543. package/src/composables/devWarn.ts +19 -0
  544. package/src/composables/easing.ts +37 -12
  545. package/src/composables/overlayHistory.ts +24 -0
  546. package/src/composables/pointerDrag.ts +54 -0
  547. package/src/composables/propCheck.ts +90 -0
  548. package/src/composables/realm.ts +25 -0
  549. package/src/composables/scroll.ts +4 -2
  550. package/src/composables/scrollMemory.ts +56 -14
  551. package/src/composables/spatialNav.ts +2 -1
  552. package/src/composables/textEntry.ts +33 -0
  553. package/src/composables/useAsyncTask.ts +6 -0
  554. package/src/composables/useChartSync.ts +52 -0
  555. package/src/composables/useCloseGuard.ts +22 -10
  556. package/src/composables/useCommands.ts +123 -0
  557. package/src/composables/useField.ts +41 -2
  558. package/src/composables/useFitScale.ts +4 -1
  559. package/src/composables/useFormDraft.ts +38 -14
  560. package/src/composables/useHintSystem.ts +2 -2
  561. package/src/composables/useHotkeys.ts +19 -48
  562. package/src/composables/useInView.ts +2 -1
  563. package/src/composables/useInputFilter.ts +8 -5
  564. package/src/composables/useInputMask.ts +8 -3
  565. package/src/composables/useLinkedView.ts +222 -0
  566. package/src/composables/useOptimisticToggle.ts +7 -1
  567. package/src/composables/useOverlayHistory.ts +20 -0
  568. package/src/composables/usePaintSelect.ts +20 -14
  569. package/src/composables/usePaletteCommands.ts +13 -0
  570. package/src/composables/usePersisted.ts +10 -0
  571. package/src/composables/usePillTransition.ts +9 -6
  572. package/src/composables/useResizeObserver.ts +2 -1
  573. package/src/composables/useReveal.ts +2 -1
  574. package/src/composables/useRovingFocus.ts +11 -14
  575. package/src/composables/useScramble.ts +12 -1
  576. package/src/composables/useShift.ts +8 -6
  577. package/src/composables/useTilt.ts +2 -1
  578. package/src/composables/useTween.ts +10 -5
  579. package/src/composables/useView.ts +17 -3
  580. package/src/composables/useZoomPan.ts +2 -5
  581. package/src/composables/windowing.ts +190 -0
  582. package/src/icons.ts +27 -6
  583. package/src/index.ts +41 -4
  584. package/src/kit-icons.ts +1 -1
  585. package/src/layout/tree.ts +31 -16
  586. package/src/layout/useLayout.ts +6 -0
  587. package/src/layout/useWorkspaces.ts +234 -0
  588. package/src/nuxt.ts +9 -1
  589. package/src/runtime/propCheck.plugin.ts +10 -0
  590. package/src/theme/studio.ts +7 -5
  591. package/src/theme/useTheme.ts +89 -15
  592. package/src/tokens/tokens.css +8 -1
  593. package/dist/assets/LpTabs-CJ0rYQbx.css +0 -18
  594. package/dist/chunks/LpAppShell-Dgejipzz.js +0 -319
  595. package/dist/chunks/LpFileTree-CooHinsC.js +0 -425
  596. package/dist/chunks/LpThemeProvider-8MG6yqU9.js +0 -640
  597. package/dist/chunks/LpTopologyCanvas-B1gIbS0n.js +0 -298
@@ -21,7 +21,7 @@ export default { inheritAttrs: false }
21
21
  */
22
22
  import { PinInputInput, PinInputRoot } from "reka-ui"
23
23
  import { computed, ref, watch } from "vue"
24
- import { useFieldControl } from "../composables/useField"
24
+ import { useFieldControl, mergeDescribedBy } from "../composables/useField"
25
25
  import { useMergedAttrs } from "../composables/useMergedClass"
26
26
  import { groupBreaks, joinCells, splitCode, upperCells, type OtpCells } from "./otp"
27
27
 
@@ -166,7 +166,7 @@ const { class: rootClass, attrs: rest } = useMergedAttrs(
166
166
  :index="i - 1"
167
167
  :id="i === 1 ? field.id : undefined"
168
168
  :aria-invalid="field.invalid || undefined"
169
- :aria-describedby="field.describedBy"
169
+ :aria-describedby="mergeDescribedBy(rest['aria-describedby'], field.describedBy)"
170
170
  :autocapitalize="upper ? 'characters' : 'none'"
171
171
  autocorrect="off"
172
172
  :spellcheck="false"
@@ -6,6 +6,7 @@ export default { inheritAttrs: false }
6
6
  </script>
7
7
 
8
8
  <script setup lang="ts">
9
+ import { nodeWindow } from "../composables/realm"
9
10
  /*
10
11
  * Page navigator. Pairs with LpTable but stands alone.
11
12
  *
@@ -17,6 +18,7 @@ export default { inheritAttrs: false }
17
18
  * and just swaps its number — which lets the brand pill glide between slots via
18
19
  * motion-v's shared layoutId with zero list-animation conflicts.
19
20
  */
21
+ import { clamp } from "../composables/clamp"
20
22
  import { Motion } from "motion-v"
21
23
  import { computed, ref, useId } from "vue"
22
24
  import { usePillTransition } from "../composables/usePillTransition"
@@ -66,7 +68,7 @@ const count = computed(() => {
66
68
  })
67
69
 
68
70
  const current = computed(() =>
69
- Number.isFinite(props.page) ? Math.min(Math.max(1, Math.floor(props.page)), count.value) : 1,
71
+ Number.isFinite(props.page) ? clamp(Math.floor(props.page), 1, count.value) : 1,
70
72
  )
71
73
 
72
74
  // A fixed run of page slots. Each slot is either a real page or a gap ("…").
@@ -85,7 +87,7 @@ const gap = ref(6)
85
87
  function measure() {
86
88
  const nav = root.value
87
89
  if (!nav || !nav.children.length) return
88
- gap.value = parseFloat(getComputedStyle(nav).columnGap) || 0
90
+ gap.value = parseFloat(nodeWindow(nav).getComputedStyle(nav).columnGap) || 0
89
91
  const items = nav.children.length
90
92
  const used = [...nav.children].reduce((sum, el) => sum + (el as HTMLElement).offsetWidth, 0)
91
93
  slotWidth.value = used / items
@@ -144,7 +146,7 @@ const slots = computed<Slot[]>(() => {
144
146
 
145
147
  function go(p: number) {
146
148
  if (props.disabled) return
147
- const next = Math.min(Math.max(1, p), count.value)
149
+ const next = clamp(p, 1, count.value)
148
150
  if (next === current.value) return
149
151
  emit("update:page", next)
150
152
  emit("change", next)
@@ -36,6 +36,7 @@ export type PhoneInputLabels = {
36
36
  * is what a form should store. Until the library arrives the field takes digits
37
37
  * as before, unformatted.
38
38
  */
39
+ import { CONTROL_SIZE } from "./controlSize"
39
40
  import {
40
41
  ComboboxAnchor,
41
42
  ComboboxContent,
@@ -47,13 +48,13 @@ import {
47
48
  ComboboxTrigger,
48
49
  ComboboxViewport,
49
50
  } from "reka-ui"
50
- import { computed, onMounted, ref, shallowRef, useAttrs } from "vue"
51
- import { useField, useFieldControl } from "../composables/useField"
51
+ import { computed, onMounted, ref, shallowRef } from "vue"
52
+ import { useField, useAttrsField, mergeDescribedBy } from "../composables/useField"
52
53
  import { useFieldNotice, type FieldNoticeOptions } from "../composables/useFieldNotice"
53
54
  import { useInputFilter } from "../composables/useInputFilter"
54
55
  import { useLabels } from "../composables/useLpConfig"
55
56
  import { type Country, filterCountries, flagEmoji, loadCountries, matchCountryByValue } from "./countries"
56
- import { OPTION_ITEM, optionStagger, POPOVER_PANEL } from "./dropdown"
57
+ import { OPTION_ITEM, optionStagger, COMBOBOX_PANEL, POPOVER_PANEL } from "./dropdown"
57
58
  import LpFieldNotice from "./LpFieldNotice.vue"
58
59
  import LpIcon from "./LpIcon.vue"
59
60
  import {
@@ -315,23 +316,13 @@ function onBlur() {
315
316
  say(reason.replace("{country}", name), { tone: "danger", duration: 0 })
316
317
  }
317
318
 
318
- const sizeClass = {
319
- sm: "h-(--size-control-sm) text-xs",
320
- md: "h-(--size-control-md) text-sm",
321
- lg: "h-(--size-control-lg) text-sm",
322
- }
319
+ const sizeClass = CONTROL_SIZE
323
320
 
324
321
  // The control is full-width with its own frame — the two things a consumer
325
322
  // placing it in a narrow column has to change, so `class="w-48"` must win.
326
323
  // style lays out the frame; every other attr (name, autocomplete, @blur…)
327
324
  // belongs to the number <input>.
328
- const attrs = useAttrs()
329
- const field = useFieldControl(() => ({
330
- wrapped: false,
331
- id: typeof attrs.id === "string" ? attrs.id : undefined,
332
- invalid: props.invalid || flagged.value,
333
- disabled: props.disabled,
334
- }))
325
+ const { attrs, field } = useAttrsField(() => ({ invalid: props.invalid || flagged.value, disabled: props.disabled }))
335
326
  const text = useLabels<PhoneInputLabels>("phoneInput", {
336
327
  selectCountry: "Select country",
337
328
  placeholder: "Phone number",
@@ -406,10 +397,8 @@ const guardOutside = useOutsideGuard()
406
397
  <ComboboxContent
407
398
  @interact-outside="guardOutside"
408
399
  @escape-key-down="guardOutside"
409
- :collision-padding="8"
410
- position="popper"
400
+ v-bind="COMBOBOX_PANEL"
411
401
  align="start"
412
- :side-offset="6"
413
402
  :class="[POPOVER_PANEL, 'z-(--z-popover) max-h-72 w-72 overflow-hidden']"
414
403
  >
415
404
  <div class="border-b border-line p-2">
@@ -460,7 +449,7 @@ const guardOutside = useOutsideGuard()
460
449
  :disabled="field.disabled"
461
450
  :required="field.required || undefined"
462
451
  :aria-invalid="field.invalid || undefined"
463
- :aria-describedby="[field.describedBy, notice.message.value ? noticeId : ''].filter(Boolean).join(' ') || undefined"
452
+ :aria-describedby="mergeDescribedBy(rest['aria-describedby'], field.describedBy, notice.message.value ? noticeId : undefined)"
464
453
  class="lp-autofill min-w-0 flex-1 self-stretch bg-transparent px-3 outline-none placeholder:text-muted"
465
454
  @beforeinput="onBeforeEdit"
466
455
  @paste="onPaste"
@@ -20,7 +20,10 @@ export default { inheritAttrs: false }
20
20
  * A donut's hole is the natural place for the headline the chart is about — the
21
21
  * total, or whatever the caller puts in the `center` slot.
22
22
  */
23
+ import { clamp } from "../composables/clamp"
24
+ import { isElement, useView, viewWindow } from "../composables/useView"
23
25
  import { computed, onBeforeUnmount, ref, watch } from "vue"
26
+ import { useHotkeys } from "../composables/useHotkeys"
24
27
  import { easeTravel, prefersReducedMotion } from "../composables/easing"
25
28
  import { useReveal } from "../composables/useReveal"
26
29
  import { lerp, mixColor, useTween } from "../composables/useTween"
@@ -272,7 +275,7 @@ const skeletonRing = computed(() => {
272
275
  return { inset: `${inset}px`, borderWidth: `${Math.max(1, band)}px` }
273
276
  })
274
277
  const inner = computed(() =>
275
- props.type === "donut" ? outer.value * Math.min(0.95, Math.max(0, props.innerRatio)) : 0,
278
+ props.type === "donut" ? outer.value * clamp(props.innerRatio, 0, 0.95) : 0,
276
279
  )
277
280
 
278
281
  /*
@@ -682,7 +685,7 @@ const leaveChart = (e: PointerEvent) => {
682
685
  // it, so look both up and down from wherever the pointer was reported to go.
683
686
  const to = e.relatedTarget
684
687
  if (
685
- to instanceof Element &&
688
+ isElement(to) &&
686
689
  (to.closest("[data-lp-follow]") || to.querySelector("[data-lp-follow]"))
687
690
  )
688
691
  return
@@ -691,22 +694,28 @@ const leaveChart = (e: PointerEvent) => {
691
694
  endDrag()
692
695
  }
693
696
 
697
+ const view = useView()
698
+
699
+ // Where the pointer is held: inside an LpFrame its release stays in the frame's window.
700
+ let dragWindow: Window | null = null
701
+
694
702
  const endDrag = () => {
695
703
  dragging.value = false
696
- window.removeEventListener("pointerup", endDrag)
697
- window.removeEventListener("pointercancel", endDrag)
704
+ dragWindow?.removeEventListener("pointerup", endDrag)
705
+ dragWindow?.removeEventListener("pointercancel", endDrag)
706
+ dragWindow = null
698
707
  }
699
708
 
700
709
  const beginDrag = () => {
701
710
  dragging.value = true
702
- window.addEventListener("pointerup", endDrag)
703
- window.addEventListener("pointercancel", endDrag)
711
+ dragWindow = viewWindow(view.value)
712
+ dragWindow.addEventListener("pointerup", endDrag)
713
+ dragWindow.addEventListener("pointercancel", endDrag)
704
714
  }
705
715
 
706
716
  onBeforeUnmount(() => {
707
717
  endDrag()
708
718
  clearTimeout(leaveTimer)
709
- window.removeEventListener("keydown", onKeydown)
710
719
  })
711
720
 
712
721
  const clearSelection = () => {
@@ -717,23 +726,16 @@ const clearSelection = () => {
717
726
  }
718
727
 
719
728
  /*
720
- * Escape drops the selection, the way it dismisses any transient state. Bound
721
- * to the window rather than the chart because a selection made with the mouse
722
- * leaves focus nowhere in particular — requiring the user to focus the chart
723
- * first would make the key useless exactly when they reach for it. Only armed
724
- * while something is selected, so the chart never swallows an Escape meant for
725
- * a dialog or a menu above it.
729
+ * Escape drops the selection, the way it dismisses any transient state. Global
730
+ * rather than on the chart because a selection made with the mouse leaves focus
731
+ * nowhere in particular — requiring the user to focus the chart first would
732
+ * make the key useless exactly when they reach for it. Only armed while
733
+ * something is selected, so the chart never swallows an Escape meant for a
734
+ * dialog or a menu above it.
726
735
  */
727
- const onKeydown = (e: KeyboardEvent) => {
728
- if (e.key === "Escape") clearSelection()
729
- }
730
-
731
- watch(
732
- () => selected.value.size > 0,
733
- (hasSelection) => {
734
- if (hasSelection) window.addEventListener("keydown", onKeydown)
735
- else window.removeEventListener("keydown", onKeydown)
736
- },
736
+ useHotkeys(
737
+ () => [{ key: "escape", allowInInput: true, handler: clearSelection }],
738
+ { enabled: () => selected.value.size > 0 },
737
739
  )
738
740
 
739
741
  const menuPoint = ref<{ index: number; label: string; value: number; isOther: boolean } | null>(
@@ -27,6 +27,8 @@ export default { inheritAttrs: false }
27
27
  */
28
28
  import { computed, nextTick, ref, useId, useSlots, watch } from "vue"
29
29
  import { prefersReducedMotion } from "../composables/easing"
30
+ import { isElement } from "../composables/useView"
31
+ import { devWarn } from "../composables/devWarn"
30
32
  import { useLabels } from "../composables/useLpConfig"
31
33
  import { useMergedAttrs } from "../composables/useMergedClass"
32
34
  import { useNow } from "../composables/useNow"
@@ -42,6 +44,7 @@ import {
42
44
  connectorFilled,
43
45
  currentStepIndex,
44
46
  stepElapsed,
47
+ duplicateStepKeys,
45
48
  stepKey,
46
49
  type PipelineStep,
47
50
  type StepStatus,
@@ -73,6 +76,8 @@ const props = withDefaults(
73
76
  /**
74
77
  * Keep the current step (see `currentStepIndex`) scrolled into view as the
75
78
  * run advances: a long job list, or a horizontal strip wider than its box.
79
+ * It moves only when the current step changes, so a status update inside a
80
+ * step leaves the reader's scroll alone.
76
81
  */
77
82
  follow?: boolean
78
83
  /**
@@ -164,11 +169,17 @@ const announcement = ref("")
164
169
  let seen = new Map<string, StepStatus>()
165
170
  /* Steps the pipeline opened itself — the only ones it may close again. */
166
171
  const autoOpened = new Set<string>()
172
+ const warnedKeys = new Set<string>()
167
173
 
168
174
  watch(
169
175
  () => props.steps.map((s, i) => [stepKey(s, i), s.status] as const),
170
176
  (pairs, old) => {
171
177
  const next = new Map(pairs)
178
+ const repeated = duplicateStepKeys(props.steps).filter((key) => !warnedKeys.has(key))
179
+ if (repeated.length) {
180
+ repeated.forEach((key) => warnedKeys.add(key))
181
+ devWarn(`LpPipeline: step keys must be unique, repeated: ${repeated.join(", ")}`)
182
+ }
172
183
  if (old) {
173
184
  const opened: string[] = []
174
185
  const closed: string[] = []
@@ -191,6 +202,8 @@ watch(
191
202
  }
192
203
  }
193
204
  seen = next
205
+ // A step that left the run will never pass to be folded again.
206
+ for (const key of autoOpened) if (!next.has(key)) autoOpened.delete(key)
194
207
  },
195
208
  { immediate: true },
196
209
  )
@@ -198,7 +211,7 @@ watch(
198
211
  /* ── Following the current step. */
199
212
  const uid = useId()
200
213
  const items: Array<Element | null> = []
201
- const bindItem = (i: number) => (el: unknown) => { items[i] = el instanceof Element ? el : null }
214
+ const bindItem = (i: number) => (el: unknown) => { items[i] = isElement(el) ? el : null }
202
215
  const current = computed(() => currentStepIndex(props.steps))
203
216
 
204
217
  watch(current, async (i) => {
@@ -5,7 +5,7 @@ import {
5
5
  PopoverRoot,
6
6
  PopoverTrigger,
7
7
  } from "reka-ui"
8
- import { computed } from "vue"
8
+ import { computed, useAttrs } from "vue"
9
9
  import { mergeClass } from "../composables/useMergedClass"
10
10
  import { POPOVER_PANEL } from "./dropdown"
11
11
  import { useOutsideGuard, usePortalTarget } from "../composables/useView"
@@ -20,7 +20,11 @@ const props = withDefaults(
20
20
  sideOffset?: number
21
21
  /** Extra classes for the floating panel (width, padding, overflow). */
22
22
  panelClass?: string
23
- /** Accessible name of the panel, which reka exposes as a dialog. */
23
+ /**
24
+ * Accessible name of the panel, which reka exposes as a dialog. Without
25
+ * one the trigger names it. A heading inside the panel names it better:
26
+ * pass `aria-labelledby` with its id.
27
+ */
24
28
  ariaLabel?: string
25
29
  }>(),
26
30
  { side: "bottom", align: "center", sideOffset: 6 },
@@ -36,6 +40,22 @@ const panel = computed(() =>
36
40
  mergeClass(POPOVER_PANEL, "z-(--z-popover) w-64 rounded-card p-3 text-sm text-ink outline-none", props.panelClass),
37
41
  )
38
42
 
43
+ /*
44
+ * reka writes the trigger's id into `aria-labelledby` after the attributes it
45
+ * was given, and that outranks `aria-label`: a name passed here never reached
46
+ * a reader. It renders that value once per open, so the panel can be put right
47
+ * as it opens without being overwritten.
48
+ */
49
+ const attrs = useAttrs()
50
+ function namePanel(event: Event) {
51
+ // The event comes from the positioning wrapper around the panel.
52
+ const panel = (event.currentTarget as HTMLElement).querySelector('[role="dialog"]')
53
+ if (!panel) return
54
+ const labelledBy = attrs["aria-labelledby"]
55
+ if (typeof labelledBy === "string") panel.setAttribute("aria-labelledby", labelledBy)
56
+ else if (props.ariaLabel) panel.removeAttribute("aria-labelledby")
57
+ }
58
+
39
59
  // Overlays open in the window this component renders in (an LpFrame's, inside one).
40
60
  const portalTo = usePortalTarget()
41
61
  // What happens in another document (the page around a frame, or a frame in
@@ -51,6 +71,7 @@ const guardOutside = useOutsideGuard()
51
71
  <PopoverPortal :to="portalTo">
52
72
  <PopoverContent
53
73
  v-bind="$attrs"
74
+ @open-auto-focus="namePanel"
54
75
  @interact-outside="guardOutside"
55
76
  @escape-key-down="guardOutside"
56
77
  :collision-padding="8"
@@ -16,6 +16,7 @@ export default { inheritAttrs: false }
16
16
  * reka ProgressRoot underneath (so assistive tech reads a progressbar with a
17
17
  * value either way).
18
18
  */
19
+ import { clamp } from "../composables/clamp"
19
20
  import { ProgressIndicator, ProgressRoot } from "reka-ui"
20
21
  import { computed } from "vue"
21
22
  import { useMergedAttrs } from "../composables/useMergedClass"
@@ -130,7 +131,7 @@ const bindReveal = (instance: unknown) => {
130
131
  // A zero or missing max (no quota known yet) reads as empty, not as NaN%.
131
132
  const pct = computed(() => {
132
133
  const ratio = props.max > 0 ? (shown.value / props.max) * 100 : 0
133
- return Number.isFinite(ratio) ? Math.max(0, Math.min(100, ratio)) : 0
134
+ return Number.isFinite(ratio) ? clamp(ratio, 0, 100) : 0
134
135
  })
135
136
 
136
137
  /*
@@ -9,7 +9,7 @@ export default { inheritAttrs: false }
9
9
  import { usePaletteControl, type PaletteControlOptions } from "../composables/usePaletteCommands"
10
10
  import { RadioGroupIndicator, RadioGroupItem, RadioGroupRoot } from "reka-ui"
11
11
  import { useId } from "vue"
12
- import { useFieldControl } from "../composables/useField"
12
+ import { useFieldControl, mergeDescribedBy } from "../composables/useField"
13
13
  import { useMergedAttrs } from "../composables/useMergedClass"
14
14
  import LpIcon from "./LpIcon.vue"
15
15
  import type { LpOptionBase } from "./options"
@@ -42,10 +42,10 @@ usePaletteControl({ disabled: () => field.value.disabled })
42
42
  :disabled="field.disabled"
43
43
  :required="field.required"
44
44
  :aria-labelledby="field.labelId"
45
- :aria-describedby="field.describedBy"
46
45
  :aria-invalid="field.invalid || undefined"
47
46
  :class="rootClass"
48
47
  v-bind="rest"
48
+ :aria-describedby="mergeDescribedBy(rest['aria-describedby'], field.describedBy)"
49
49
  @update:model-value="(v) => $emit('update:modelValue', v as string)"
50
50
  >
51
51
  <slot>
@@ -6,6 +6,7 @@ export default { inheritAttrs: false }
6
6
  </script>
7
7
 
8
8
  <script setup lang="ts">
9
+ import SliderRail from "./SliderRail.vue"
9
10
  import { usePaletteControl, type PaletteControlOptions } from "../composables/usePaletteCommands"
10
11
  /*
11
12
  * Two thumbs on one track: a range rather than a value. A price "from – to",
@@ -14,8 +15,8 @@ import { usePaletteControl, type PaletteControlOptions } from "../composables/us
14
15
  * Each thumb can carry a label above it (`format`), shown while it is hovered,
15
16
  * focused or dragged, so the numbers are readable without a second readout.
16
17
  */
17
- import { SliderRange, SliderRoot, SliderThumb, SliderTrack } from "reka-ui"
18
- import { useFieldControl } from "../composables/useField"
18
+ import { SliderRoot, SliderThumb } from "reka-ui"
19
+ import { useFieldControl, mergeDescribedBy } from "../composables/useField"
19
20
  import { useMergedAttrs } from "../composables/useMergedClass"
20
21
  import { SLIDER_GLIDE, useSliderDrag } from "./slider"
21
22
 
@@ -87,16 +88,14 @@ usePaletteControl({ disabled: () => field.value.disabled })
87
88
  @update:model-value="onUpdate"
88
89
  @value-commit="onCommit"
89
90
  >
90
- <SliderTrack class="relative h-1.5 grow overflow-hidden rounded-pill bg-surface-soft">
91
- <SliderRange class="absolute h-full rounded-pill bg-brand" />
92
- </SliderTrack>
91
+ <SliderRail />
93
92
  <SliderThumb
94
93
  v-for="index in [0, 1] as const"
95
94
  :key="index"
96
95
  :id="index === 0 ? field.id : undefined"
97
96
  :aria-label="ariaLabels?.[index]"
98
97
  :aria-labelledby="ariaLabels ? undefined : field.labelId"
99
- :aria-describedby="field.describedBy"
98
+ :aria-describedby="mergeDescribedBy(rest['aria-describedby'], field.describedBy)"
100
99
  :class="thumbClass"
101
100
  >
102
101
  <span v-if="format" :class="labelClass">{{ format(props.modelValue[index]) }}</span>
@@ -85,7 +85,7 @@ function play(node: HTMLElement) {
85
85
  if (props.immediate || prefersReducedMotion() || typeof node.animate !== "function") return
86
86
  const from = revealFrom(props.preset, props.direction, props.distance)
87
87
  const frames = [from, revealTo(from)]
88
- const easing = easingToken("ease-emphasized")
88
+ const easing = easingToken("ease-emphasized", undefined, node)
89
89
  // `backwards` holds each target in its hidden state through its delay, so a
90
90
  // staggered child does not flash in before its turn.
91
91
  const targets = props.stagger > 0 ? Array.from(node.children) : [node]
@@ -14,6 +14,7 @@ import {
14
14
  ScrollAreaViewport,
15
15
  } from "reka-ui"
16
16
  import { prefersReducedMotion } from "../composables/easing"
17
+ import { nodeWindow } from "../composables/useView"
17
18
 
18
19
  // `fade` softens whichever of the top/bottom edges currently has content beyond
19
20
  // it, so a clipped list reads as continuing rather than as cut off. On by
@@ -122,7 +123,9 @@ function measureEdges(el: HTMLElement) {
122
123
  * it has to come off the element.
123
124
  *
124
125
  * Kept in sync with content size rather than set once: a list that fills in
125
- * later becomes scrollable without anything else changing.
126
+ * later becomes scrollable without anything else changing. The viewport's
127
+ * tabindex is therefore this component's alone; `tabindex` on LpScrollArea
128
+ * lands on its root and does not reach it.
126
129
  */
127
130
  function syncViewportFocusable(el: HTMLElement) {
128
131
  const scrollable = el.scrollHeight > el.clientHeight || el.scrollWidth > el.clientWidth
@@ -161,8 +164,10 @@ watch(
161
164
  }
162
165
  remeasure()
163
166
 
164
- if (typeof ResizeObserver !== "undefined") {
165
- edgeResize = new ResizeObserver(remeasure)
167
+ // The element's own window: the observers belong to the realm they watch.
168
+ const win = nodeWindow(el)
169
+ if (win.ResizeObserver) {
170
+ edgeResize = new win.ResizeObserver(remeasure)
166
171
  edgeResize.observe(el)
167
172
  // Watching the children too, since a grid that reflows into more rows
168
173
  // grows the content box without the viewport's own size moving.
@@ -171,8 +176,8 @@ watch(
171
176
  // Rows arriving after the first paint are the common case — a list waiting
172
177
  // on a query renders empty, and observing only the boxes that existed then
173
178
  // left the fade off until something else happened to trigger a measure.
174
- if (typeof MutationObserver !== "undefined") {
175
- edgeMutation = new MutationObserver(() => {
179
+ if (win.MutationObserver) {
180
+ edgeMutation = new win.MutationObserver(() => {
176
181
  if (edgeResize) {
177
182
  edgeResize.disconnect()
178
183
  edgeResize.observe(el)
@@ -186,7 +191,10 @@ watch(
186
191
  { immediate: true, flush: "post" },
187
192
  )
188
193
 
189
- onBeforeUnmount(stopEdgeWatch)
194
+ onBeforeUnmount(() => {
195
+ stopEdgeWatch()
196
+ stopThumbDrag?.()
197
+ })
190
198
 
191
199
  /*
192
200
  * A press on the bar beside the thumb. reka treats any press on the track as
@@ -211,17 +219,26 @@ function onTrackPointerDown(event: PointerEvent, axis: "x" | "y") {
211
219
  el.scrollBy(axis === "y" ? { top: step, behavior } : { left: step, behavior })
212
220
  }
213
221
 
214
- function onThumbPointerDown() {
222
+ let stopThumbDrag: (() => void) | null = null
223
+
224
+ function onThumbPointerDown(event: PointerEvent) {
215
225
  dragging.value = true
226
+ stopThumbDrag?.()
227
+ // The thumb's own window: inside an LpFrame the page's never hears the release.
228
+ const win = nodeWindow(event.currentTarget as Node)
216
229
  const stop = () => {
217
230
  dragging.value = false
218
- window.removeEventListener("pointerup", stop)
219
- window.removeEventListener("pointercancel", stop)
231
+ win.removeEventListener("pointerup", stop)
232
+ win.removeEventListener("pointercancel", stop)
233
+ win.removeEventListener("lostpointercapture", stop)
234
+ stopThumbDrag = null
220
235
  }
236
+ stopThumbDrag = stop
221
237
  // Bound on the window: the pointer is captured by the thumb, and the release
222
238
  // routinely happens far outside the scroll area.
223
- window.addEventListener("pointerup", stop)
224
- window.addEventListener("pointercancel", stop)
239
+ win.addEventListener("pointerup", stop)
240
+ win.addEventListener("pointercancel", stop)
241
+ win.addEventListener("lostpointercapture", stop)
225
242
  }
226
243
  </script>
227
244
 
@@ -12,6 +12,7 @@ export interface SecretFieldLabels extends Record<string, string> {
12
12
  </script>
13
13
 
14
14
  <script setup lang="ts">
15
+ import { isElement } from "../composables/useView"
15
16
  import { suppressPaletteDiscovery } from "../composables/usePaletteCommands"
16
17
  /*
17
18
  * A value someone must be able to read and copy but should not have on screen
@@ -159,7 +160,7 @@ const field = ref<{ $el?: Element } | null>(null)
159
160
  watch(revealed, () => {
160
161
  if (!props.input || prefersReducedMotion()) return
161
162
  const el = field.value?.$el
162
- const input = el instanceof Element ? el.querySelector("input") : null
163
+ const input = isElement(el) ? el.querySelector("input") : null
163
164
  input?.animate([{ filter: "blur(4px)", opacity: 0.35 }, { filter: "blur(0)", opacity: 1 }], {
164
165
  duration: 260,
165
166
  easing: "cubic-bezier(0.2, 0, 0, 1)",
@@ -6,6 +6,8 @@ export default { inheritAttrs: false }
6
6
  </script>
7
7
 
8
8
  <script setup lang="ts">
9
+ import { CONTROL_SIZE } from "./controlSize"
10
+ import { isHTMLElement } from "../composables/useView"
9
11
  import { usePaletteControl, type PaletteControlOptions } from "../composables/usePaletteCommands"
10
12
  /*
11
13
  * Segmented control — a compact bar of mutually-exclusive options with a sliding
@@ -17,7 +19,7 @@ import { usePaletteControl, type PaletteControlOptions } from "../composables/us
17
19
  import { Motion } from "motion-v"
18
20
  import { ToggleGroupItem, ToggleGroupRoot } from "reka-ui"
19
21
  import { ref, useId } from "vue"
20
- import { useFieldControl } from "../composables/useField"
22
+ import { useFieldControl, mergeDescribedBy } from "../composables/useField"
21
23
  import { useMergedAttrs } from "../composables/useMergedClass"
22
24
  import { usePillTransition } from "../composables/usePillTransition"
23
25
  import AttentionDot from "./AttentionDot.vue"
@@ -66,11 +68,7 @@ function onChange(v: unknown) {
66
68
  if (typeof v === "string" && v) emit("update:modelValue", v)
67
69
  }
68
70
 
69
- const sizeCls = {
70
- sm: "h-(--size-control-sm) text-xs",
71
- md: "h-(--size-control-md) text-sm",
72
- lg: "h-(--size-control-lg) text-sm",
73
- }
71
+ const sizeCls = CONTROL_SIZE
74
72
 
75
73
  // The bar sizes itself from `size` and `block`, which is right until a consumer
76
74
  // needs it flush against something — `class="p-0"` and `class="rounded-none"`
@@ -109,7 +107,7 @@ function pillUnder(value: string): boolean {
109
107
  */
110
108
  function releaseFocusAfterPointer(event: PointerEvent) {
111
109
  const target = event.currentTarget
112
- if (target instanceof HTMLElement) target.blur()
110
+ if (isHTMLElement(target)) target.blur()
113
111
  }
114
112
 
115
113
  usePaletteControl({ disabled: () => field.value.disabled })
@@ -121,10 +119,10 @@ usePaletteControl({ disabled: () => field.value.disabled })
121
119
  type="single"
122
120
  :disabled="field.disabled"
123
121
  :aria-labelledby="field.labelId"
124
- :aria-describedby="field.describedBy"
125
122
  :rovingFocus="true"
126
123
  :class="rootClass"
127
124
  v-bind="rest"
125
+ :aria-describedby="mergeDescribedBy(rest['aria-describedby'], field.describedBy)"
128
126
  @update:model-value="onChange"
129
127
  @pointerleave="hovered = null"
130
128
  >