@leavepulse/ui 0.69.0 → 0.70.1

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 (640) hide show
  1. package/README.md +49 -0
  2. package/dist/assets/LoaderMark-DxBV2iDJ.css +43 -0
  3. package/dist/assets/LpActivityLine-B3EwNQEB.css +33 -0
  4. package/dist/assets/{LpCommandPalette-DxyjhYn_.css → LpCommandPalette-u-zOxKWa.css} +21 -31
  5. package/dist/assets/LpDock-Cbh0wQUv.css +17 -0
  6. package/dist/assets/{LpDropzone-Qb8k7cg4.css → LpDropzone-Bb1vBTeU.css} +12 -17
  7. package/dist/assets/{LpImageEditor-CElPDzpF.css → LpImageEditor-XM5bAziW.css} +6 -6
  8. package/dist/assets/LpLogViewer-BDNW6P52.css +38 -0
  9. package/dist/assets/{LpPalettePreview-CJmAKgYW.css → LpPalettePreview-B9VKDrvA.css} +2 -7
  10. package/dist/assets/LpRepeater-C1Cw27hj.css +21 -0
  11. package/dist/assets/{LpRollingText-BGnE6q9j.css → LpRollingText-dyOXedGO.css} +7 -0
  12. package/dist/assets/LpShinyText-D69cBYDR.css +61 -0
  13. package/dist/assets/LpStatus-430OGTZY.css +17 -0
  14. package/dist/assets/LpStepMark-Drvx33Vg.css +10 -0
  15. package/dist/assets/{LpTable-BPERfJIk.css → LpTable-DHxEQ_-3.css} +19 -19
  16. package/dist/assets/LpTabs-BJ-nrJuI.css +18 -0
  17. package/dist/assets/LpTextReveal-DjI1MsDS.css +35 -0
  18. package/dist/assets/LpTypewriter-CXAm9Nca.css +27 -0
  19. package/dist/chunks/AttentionDot-DCBf4aWg.js +25 -0
  20. package/dist/chunks/{ContextMenuItems-B7XFHksm.js → ContextMenuItems-6kxEivBI.js} +11 -5
  21. package/dist/chunks/{DropzoneLinkField-CjkrpDqO.js → DropzoneLinkField-Bw8Flkhk.js} +2 -2
  22. package/dist/chunks/FieldWrapper-BiennROB.js +43 -0
  23. package/dist/chunks/{LayoutCanvas-DF9CovaK.js → LayoutCanvas-BsJIzhdd.js} +1 -1
  24. package/dist/chunks/{LayoutNode-D9bIFzk0.js → LayoutNode-DJVhkSGk.js} +6 -8
  25. package/dist/chunks/LegendSwatch-BhRjrtzv.js +18 -0
  26. package/dist/chunks/LoaderMark-C1dubiKn.js +85 -0
  27. package/dist/chunks/{LpActionBar-MPKMu3pz.js → LpActionBar-CzOFar5t.js} +14 -20
  28. package/dist/chunks/LpActivityLine-CJvzrNpj.js +95 -0
  29. package/dist/chunks/{LpAddressInput-DG0BTqdH.js → LpAddressInput-Chv_Xf8q.js} +7 -7
  30. package/dist/chunks/LpAlert-C5igj802.js +119 -0
  31. package/dist/chunks/{LpAppShell-DPh1756q.js → LpAppShell-BiWByLmt.js} +15 -16
  32. package/dist/chunks/{LpAutocomplete-Dgn6hw3p.js → LpAutocomplete-D92niDHE.js} +15 -32
  33. package/dist/chunks/{LpAvatar-Bs0Fb1lC.js → LpAvatar-CLPl-qOF.js} +18 -6
  34. package/dist/chunks/LpBadge-BBq1Er9T.js +126 -0
  35. package/dist/chunks/LpBreadcrumbs-JKEi_yFF.js +144 -0
  36. package/dist/chunks/{LpButton-DNR-YAq5.js → LpButton-CVxBfGjd.js} +12 -4
  37. package/dist/chunks/{LpCalendar-BLya39Fh.js → LpCalendar-pVL91-Pl.js} +1 -1
  38. package/dist/chunks/{LpCard-Bf71NXZq.js → LpCard-CqKLnEhl.js} +18 -8
  39. package/dist/chunks/{LpCheckbox-Da5oZPHo.js → LpCheckbox-DHc2bHDe.js} +9 -6
  40. package/dist/chunks/{LpCodeBlock-lLbmslfs.js → LpCodeBlock-BGsQhxw8.js} +24 -32
  41. package/dist/chunks/LpCodeDisplay-CbJMs-IK.js +189 -0
  42. package/dist/chunks/LpCollapse-CWS9M_lm.js +115 -0
  43. package/dist/chunks/{LpColorPicker-DtEfBAcK.js → LpColorPicker-B7HSIFmn.js} +11 -6
  44. package/dist/chunks/{LpConfirmDialog-D7s4jakB.js → LpConfirmDialog-CfGCux8m.js} +3 -3
  45. package/dist/chunks/{LpConfirmHost-DrYI5y1K.js → LpConfirmHost-exB7JmcO.js} +1 -1
  46. package/dist/chunks/{LpContextMenu-CRnjoqSt.js → LpContextMenu-Cj96ENDC.js} +16 -7
  47. package/dist/chunks/LpCopyButton-DzHjnFs0.js +133 -0
  48. package/dist/chunks/LpCountdown-BQnmB4gq.js +231 -0
  49. package/dist/chunks/LpDataList-CHNYQw7h.js +121 -0
  50. package/dist/chunks/LpDatePicker-ac1_6o5P.js +169 -0
  51. package/dist/chunks/LpDateRangePicker-B15gYrZJ.js +127 -0
  52. package/dist/chunks/{LpDisclosure-6AplYBub.js → LpDisclosure-DOarzlAG.js} +22 -11
  53. package/dist/chunks/{LpDrawer-Q4SOxM4s.js → LpDrawer-DGNKRsGq.js} +9 -4
  54. package/dist/chunks/{LpDropdownMenu-DWTt0ooM.js → LpDropdownMenu-R4aYVtVV.js} +14 -6
  55. package/dist/chunks/LpEditable-Ws3DNQHn.js +238 -0
  56. package/dist/chunks/{LpEmptyState-om1UnFjV.js → LpEmptyState-KTKipws2.js} +1 -1
  57. package/dist/chunks/{LpFieldNotice-CHuDeLjc.js → LpFieldNotice-CurbNuXI.js} +1 -1
  58. package/dist/chunks/{LpFileTree-CW24YsVX.js → LpFileTree-DDNg34tJ.js} +5 -3
  59. package/dist/chunks/{LpFileTreeNode-BXhTHaKW.js → LpFileTreeNode-DmPuYNZ_.js} +42 -55
  60. package/dist/chunks/{LpFormField-DPb47HEm.js → LpFormField-BWwgm1E4.js} +23 -9
  61. package/dist/chunks/LpFrame-BVQCQLDI.js +155 -0
  62. package/dist/chunks/LpGauge-C14Z9503.js +204 -0
  63. package/dist/chunks/LpGlowBorder-B8V-QzIl.js +40 -0
  64. package/dist/chunks/{LpHintExample-C1eKYdeL.js → LpHintExample-9Py0wc-L.js} +11 -34
  65. package/dist/chunks/{LpHintLayer-7UOdWQG3.js → LpHintLayer-HvwUA5Ec.js} +27 -14
  66. package/dist/chunks/{LpHints-BUtBp9-w.js → LpHints-DxbPKOzQ.js} +3 -3
  67. package/dist/chunks/LpHoverCard-spGxyw7T.js +130 -0
  68. package/dist/chunks/{LpIcon-6tSrZ3Zy.js → LpIcon-HJP5xMz4.js} +1 -1
  69. package/dist/chunks/LpIdenticon-BzdC_qz9.js +63 -0
  70. package/dist/chunks/{LpInfraNode-Ds_8SZgN.js → LpInfraNode-D64hywJI.js} +39 -25
  71. package/dist/chunks/{LpInput-CUyr6PIE.js → LpInput-CDuwODJG.js} +44 -18
  72. package/dist/chunks/{LpLightbox-B9J8rzsj.js → LpLightbox-XJ0LpTcZ.js} +69 -69
  73. package/dist/chunks/LpLoader-DjJEX8hL.js +92 -0
  74. package/dist/chunks/{LpLogViewer-4QFc-sVN.js → LpLogViewer-DKK4ySZl.js} +225 -129
  75. package/dist/chunks/LpMagnetic-CtXKLa2Y.js +62 -0
  76. package/dist/chunks/{LpMapPicker-BTbkFeSG.js → LpMapPicker-BtIl7NOM.js} +34 -31
  77. package/dist/chunks/LpMasonry--k0571qG.js +185 -0
  78. package/dist/chunks/{LpMediaGallery-CuPcscx3.js → LpMediaGallery-rmI1DjKN.js} +3 -3
  79. package/dist/chunks/{LpModal-hk1noDcr.js → LpModal-eBMt2Fqn.js} +8 -3
  80. package/dist/chunks/{LpModalNav-DQd2keZm.js → LpModalNav-DiyFCHiZ.js} +4 -4
  81. package/dist/chunks/{LpNotificationBell-X84PJIxD.js → LpNotificationBell-D-WhE5m2.js} +32 -48
  82. package/dist/chunks/LpNumberField-B9k-h2HE.js +140 -0
  83. package/dist/chunks/{LpNumberFlow-z4WPZcZu.js → LpNumberFlow-Cfyh033Q.js} +8 -28
  84. package/dist/chunks/{LpOtpInput-PbeNJ5In.js → LpOtpInput-CeBPsM7D.js} +2 -1
  85. package/dist/chunks/{LpPagination-Bx-VG4Ag.js → LpPagination-VNCX6pFC.js} +37 -6
  86. package/dist/chunks/{LpPalettePreview-CFav_7co.js → LpPalettePreview-BNB8T_MY.js} +1 -1
  87. package/dist/chunks/{LpPasswordInput-CbnXitAS.js → LpPasswordInput-GL2KOFK8.js} +26 -22
  88. package/dist/chunks/{LpPhoneInput-DP69HONS.js → LpPhoneInput-C60tx1tC.js} +12 -7
  89. package/dist/chunks/{LpPie-yLF9-aDR.js → LpPie-BgXZ3xmm.js} +159 -48
  90. package/dist/chunks/LpPipeline-B31h41Mu.js +329 -0
  91. package/dist/chunks/{LpPopover-DVnkHaOu.js → LpPopover-DmZ3wUtP.js} +13 -7
  92. package/dist/chunks/{LpProgress-CA86wxXu.js → LpProgress-CE-m5OpD.js} +23 -63
  93. package/dist/chunks/LpQuota-DaL8TgNe.js +162 -0
  94. package/dist/chunks/{LpRadioGroup-8S5hf8lE.js → LpRadioGroup-CGBr5nIp.js} +1 -1
  95. package/dist/chunks/{LpRangeCalendar-ByQi-WUz.js → LpRangeCalendar-c5qj7YcC.js} +1 -1
  96. package/dist/chunks/{LpRangeSlider-C1yF9-nP.js → LpRangeSlider-Dv6lNvHY.js} +6 -2
  97. package/dist/chunks/LpRelativeTime-yin9uQP7.js +73 -0
  98. package/dist/chunks/LpRepeater-D0S7jjwr.js +180 -0
  99. package/dist/chunks/LpRevealOnScroll-DcQjexLy.js +76 -0
  100. package/dist/chunks/{LpRollingText-DB7upf-5.js → LpRollingText-DiL717LK.js} +4 -3
  101. package/dist/chunks/LpScramble-TDO5Kdou.js +85 -0
  102. package/dist/chunks/LpSecretField-CfWyHv9m.js +316 -0
  103. package/dist/chunks/{LpSection-BmRXe6ZP.js → LpSection-BW4xJ-Li.js} +1 -1
  104. package/dist/chunks/{LpSegmented-CW3bFHM4.js → LpSegmented-BO99Sr4m.js} +11 -14
  105. package/dist/chunks/{LpSelect-BCyDYoih.js → LpSelect-C_8cJtj6.js} +91 -111
  106. package/dist/chunks/LpShaderBackdrop-Bote0iuy.js +332 -0
  107. package/dist/chunks/LpShinyText-DX2ajtWq.js +48 -0
  108. package/dist/chunks/{LpSidebar-DfIiS-lB.js → LpSidebar-CZRXtvem.js} +5 -3
  109. package/dist/chunks/{LpSidebarNav-C5FDNI0t.js → LpSidebarNav-DBg1U1oW.js} +3 -3
  110. package/dist/chunks/{LpSlider-Cuzmrd7p.js → LpSlider-DuoRpOrH.js} +6 -2
  111. package/dist/chunks/{LpSparkline-DXT4KrSi.js → LpSparkline-CExIRDb3.js} +32 -27
  112. package/dist/chunks/LpSpotlight-4F3NeUMY.js +41 -0
  113. package/dist/chunks/{LpStat-iBMF5QNk.js → LpStat-DFKlPJgy.js} +38 -35
  114. package/dist/chunks/LpStatus-BsGLrpor.js +86 -0
  115. package/dist/chunks/LpStepMark-TrzOioa9.js +101 -0
  116. package/dist/chunks/LpStepper-BbnS5jUr.js +76 -0
  117. package/dist/chunks/{LpSwap-D82jiecV.js → LpSwap-DzE6M3Mg.js} +1 -1
  118. package/dist/chunks/LpSwitch-DrzKrZZV.js +112 -0
  119. package/dist/chunks/{LpTableFilter-CuIbgdW0.js → LpTableFilter-DyvHGbOk.js} +3 -2
  120. package/dist/chunks/{LpTableOfContents-C_4VBktT.js → LpTableOfContents-rYvo8z5T.js} +34 -21
  121. package/dist/chunks/{LpTagsInput-DiXrpYeE.js → LpTagsInput-DZg80W-B.js} +68 -71
  122. package/dist/chunks/LpTextReveal-CtAnOUkp.js +140 -0
  123. package/dist/chunks/{LpTextarea-xoQd5Lnp.js → LpTextarea-DiWjeVoJ.js} +12 -11
  124. package/dist/chunks/{LpThemeProvider-CQ2jC9TA.js → LpThemeProvider-DcbfOxsU.js} +1 -1
  125. package/dist/chunks/LpThemeStudio-DxVZMtzN.js +416 -0
  126. package/dist/chunks/LpThemeStudioSection-BwhqYDLf.js +20 -0
  127. package/dist/chunks/LpThemeSwitcher-CadVBTBn.js +278 -0
  128. package/dist/chunks/{LpTimeField-MFgAsNc5.js → LpTimeField-BFQVf_PW.js} +13 -5
  129. package/dist/chunks/{LpToaster-C4zE9zB7.js → LpToaster-Wv9ksj4q.js} +49 -82
  130. package/dist/chunks/{LpTooltip-suFCM34F.js → LpTooltip-Cz8SQwRt.js} +8 -3
  131. package/dist/chunks/{LpTopologyCanvas-6ozNrQKh.js → LpTopologyCanvas-C17A1XCb.js} +1 -1
  132. package/dist/chunks/{LpTour-BUp3Jt2e.js → LpTour-CY2bFXge.js} +24 -18
  133. package/dist/chunks/LpTruncate-D_5Pfv5B.js +112 -0
  134. package/dist/chunks/LpTypewriter-BCL_a6wE.js +159 -0
  135. package/dist/chunks/{LpUptimeBar-B6kHw4Cj.js → LpUptimeBar-Tew1Ykx4.js} +10 -9
  136. package/dist/chunks/{LpVideoBackdrop-qWRYBOTQ.js → LpVideoBackdrop-DS1wGv-X.js} +7 -8
  137. package/dist/chunks/{MenuTitle-obgek0B7.js → MenuTitle-BjQZX8tQ.js} +1 -1
  138. package/dist/chunks/OptionContent-CmYUUeWj.js +40 -0
  139. package/dist/chunks/PickerField-DoHv0WMH.js +125 -0
  140. package/dist/chunks/RevealToggle-C-KzaQGJ.js +65 -0
  141. package/dist/chunks/StepConnector-37OgEOXA.js +41 -0
  142. package/dist/chunks/TourCard-BJ8i7dk0.js +123 -0
  143. package/dist/chunks/backdrop-Dkf2vM81.js +59 -0
  144. package/dist/chunks/{icons-DVhZ_plB.js → icons-4IywzkHk.js} +1 -1
  145. package/dist/chunks/{useTheme-2qHG8NEU.js → useTheme-BOV_-AiY.js} +9 -65
  146. package/dist/component-names.d.ts +1 -1
  147. package/dist/components/AttentionDot.vue.d.ts +9 -0
  148. package/dist/components/AttentionDot.vue.js +4 -0
  149. package/dist/components/ContextMenuItems.vue.js +1 -1
  150. package/dist/components/DropzoneLinkField.vue.js +1 -1
  151. package/dist/components/FieldWrapper.vue.d.ts +25 -0
  152. package/dist/components/FieldWrapper.vue.js +4 -0
  153. package/dist/components/LayoutCanvas.vue.js +1 -1
  154. package/dist/components/LayoutNode.vue.d.ts +4 -4
  155. package/dist/components/LayoutNode.vue.js +1 -1
  156. package/dist/components/LegendSwatch.vue.d.ts +6 -0
  157. package/dist/components/LegendSwatch.vue.js +4 -0
  158. package/dist/components/LoaderMark.vue.d.ts +12 -0
  159. package/dist/components/LoaderMark.vue.js +4 -0
  160. package/dist/components/LpActionBar.vue.js +1 -1
  161. package/dist/components/LpActivityLine.vue.d.ts +58 -0
  162. package/dist/components/LpActivityLine.vue.js +4 -0
  163. package/dist/components/LpAddressInput.vue.js +1 -1
  164. package/dist/components/LpAlert.vue.d.ts +2 -2
  165. package/dist/components/LpAlert.vue.js +1 -1
  166. package/dist/components/LpAppShell.vue.d.ts +8 -7
  167. package/dist/components/LpAppShell.vue.js +1 -1
  168. package/dist/components/LpAutocomplete.vue.js +1 -1
  169. package/dist/components/LpAvatar.vue.d.ts +16 -0
  170. package/dist/components/LpAvatar.vue.js +1 -1
  171. package/dist/components/LpBadge.vue.d.ts +19 -5
  172. package/dist/components/LpBadge.vue.js +1 -1
  173. package/dist/components/LpBreadcrumbs.vue.js +1 -1
  174. package/dist/components/LpButton.vue.d.ts +2 -2
  175. package/dist/components/LpButton.vue.js +1 -1
  176. package/dist/components/LpCalendar.vue.js +1 -1
  177. package/dist/components/LpCard.vue.d.ts +24 -0
  178. package/dist/components/LpCard.vue.js +1 -1
  179. package/dist/components/LpChart.vue.js +131 -160
  180. package/dist/components/LpCheckbox.vue.d.ts +2 -2
  181. package/dist/components/LpCheckbox.vue.js +1 -1
  182. package/dist/components/LpCodeBlock.vue.js +1 -1
  183. package/dist/components/LpCodeDisplay.vue.d.ts +89 -0
  184. package/dist/components/LpCodeDisplay.vue.js +4 -0
  185. package/dist/components/LpCollapse.vue.d.ts +58 -0
  186. package/dist/components/LpCollapse.vue.js +4 -0
  187. package/dist/components/LpColorPicker.vue.d.ts +2 -2
  188. package/dist/components/LpColorPicker.vue.js +1 -1
  189. package/dist/components/LpCommandPalette.vue.js +34 -23
  190. package/dist/components/LpConfirmDialog.vue.js +1 -1
  191. package/dist/components/LpConfirmHost.vue.js +1 -1
  192. package/dist/components/LpContextMenu.vue.js +1 -1
  193. package/dist/components/LpCopyButton.vue.d.ts +82 -0
  194. package/dist/components/LpCopyButton.vue.js +4 -0
  195. package/dist/components/LpCountdown.vue.d.ts +100 -0
  196. package/dist/components/LpCountdown.vue.js +4 -0
  197. package/dist/components/LpDataList.vue.d.ts +66 -0
  198. package/dist/components/LpDataList.vue.js +4 -0
  199. package/dist/components/LpDatePicker.vue.d.ts +3 -1
  200. package/dist/components/LpDatePicker.vue.js +1 -1
  201. package/dist/components/LpDateRangePicker.vue.d.ts +3 -1
  202. package/dist/components/LpDateRangePicker.vue.js +1 -1
  203. package/dist/components/LpDisclosure.vue.js +1 -1
  204. package/dist/components/LpDock.vue.d.ts +74 -0
  205. package/dist/components/LpDock.vue.js +204 -0
  206. package/dist/components/LpDrawer.vue.js +1 -1
  207. package/dist/components/LpDropdownMenu.vue.js +1 -1
  208. package/dist/components/LpDropzone.vue.d.ts +8 -1
  209. package/dist/components/LpDropzone.vue.js +36 -15
  210. package/dist/components/LpEditable.vue.d.ts +85 -0
  211. package/dist/components/LpEditable.vue.js +4 -0
  212. package/dist/components/LpEmptyState.vue.js +1 -1
  213. package/dist/components/LpFieldNotice.vue.js +1 -1
  214. package/dist/components/LpFileTree.vue.js +1 -1
  215. package/dist/components/LpFileTreeNode.vue.js +1 -1
  216. package/dist/components/LpFormField.vue.js +1 -1
  217. package/dist/components/LpFrame.vue.d.ts +22 -0
  218. package/dist/components/LpFrame.vue.js +4 -0
  219. package/dist/components/LpGauge.vue.d.ts +116 -0
  220. package/dist/components/LpGauge.vue.js +4 -0
  221. package/dist/components/LpGlowBorder.vue.d.ts +47 -0
  222. package/dist/components/LpGlowBorder.vue.js +4 -0
  223. package/dist/components/LpHintExample.vue.d.ts +2 -2
  224. package/dist/components/LpHintExample.vue.js +1 -1
  225. package/dist/components/LpHintLayer.vue.js +1 -1
  226. package/dist/components/LpHints.vue.js +1 -1
  227. package/dist/components/LpHoverCard.vue.d.ts +60 -0
  228. package/dist/components/LpHoverCard.vue.js +4 -0
  229. package/dist/components/LpIcon.vue.js +1 -1
  230. package/dist/components/LpIdenticon.vue.d.ts +37 -0
  231. package/dist/components/LpIdenticon.vue.js +4 -0
  232. package/dist/components/LpImageEditor.vue.js +13 -19
  233. package/dist/components/LpInfraNode.vue.js +1 -1
  234. package/dist/components/LpInput.vue.d.ts +10 -0
  235. package/dist/components/LpInput.vue.js +1 -1
  236. package/dist/components/LpLightbox.vue.js +1 -1
  237. package/dist/components/LpLoader.vue.d.ts +106 -0
  238. package/dist/components/LpLoader.vue.js +4 -0
  239. package/dist/components/LpLogViewer.vue.js +1 -1
  240. package/dist/components/LpMagnetic.vue.d.ts +28 -0
  241. package/dist/components/LpMagnetic.vue.js +4 -0
  242. package/dist/components/LpMapPicker.vue.js +1 -1
  243. package/dist/components/LpMasonry.vue.d.ts +42 -0
  244. package/dist/components/LpMasonry.vue.js +4 -0
  245. package/dist/components/LpMediaGallery.vue.js +1 -1
  246. package/dist/components/LpModal.vue.js +1 -1
  247. package/dist/components/LpModalNav.vue.js +1 -1
  248. package/dist/components/LpNotificationBell.vue.d.ts +15 -6
  249. package/dist/components/LpNotificationBell.vue.js +1 -1
  250. package/dist/components/LpNumberField.vue.d.ts +57 -0
  251. package/dist/components/LpNumberField.vue.js +1 -1
  252. package/dist/components/LpNumberFlow.vue.js +1 -1
  253. package/dist/components/LpOtpInput.vue.d.ts +12 -4
  254. package/dist/components/LpOtpInput.vue.js +1 -1
  255. package/dist/components/LpPagination.vue.js +1 -1
  256. package/dist/components/LpPaletteFacts.vue.js +2 -2
  257. package/dist/components/LpPaletteHeader.vue.js +2 -2
  258. package/dist/components/LpPalettePreview.vue.js +1 -1
  259. package/dist/components/LpPaletteStats.vue.js +2 -2
  260. package/dist/components/LpPasswordInput.vue.d.ts +19 -2
  261. package/dist/components/LpPasswordInput.vue.js +1 -1
  262. package/dist/components/LpPhoneInput.vue.js +1 -1
  263. package/dist/components/LpPie.vue.d.ts +3 -1
  264. package/dist/components/LpPie.vue.js +1 -1
  265. package/dist/components/LpPipeline.vue.d.ts +91 -0
  266. package/dist/components/LpPipeline.vue.js +4 -0
  267. package/dist/components/LpPopover.vue.d.ts +2 -2
  268. package/dist/components/LpPopover.vue.js +1 -1
  269. package/dist/components/LpProgress.vue.d.ts +11 -4
  270. package/dist/components/LpProgress.vue.js +1 -1
  271. package/dist/components/LpQuota.vue.d.ts +68 -0
  272. package/dist/components/LpQuota.vue.js +4 -0
  273. package/dist/components/LpRadioGroup.vue.js +1 -1
  274. package/dist/components/LpRangeCalendar.vue.js +1 -1
  275. package/dist/components/LpRangeSlider.vue.js +1 -1
  276. package/dist/components/LpRelativeTime.vue.d.ts +41 -0
  277. package/dist/components/LpRelativeTime.vue.js +4 -0
  278. package/dist/components/LpRepeater.vue.d.ts +48 -0
  279. package/dist/components/LpRepeater.vue.js +4 -0
  280. package/dist/components/LpRevealOnScroll.vue.d.ts +67 -0
  281. package/dist/components/LpRevealOnScroll.vue.js +4 -0
  282. package/dist/components/LpRollingText.vue.d.ts +3 -1
  283. package/dist/components/LpRollingText.vue.js +1 -1
  284. package/dist/components/LpScramble.vue.d.ts +55 -0
  285. package/dist/components/LpScramble.vue.js +4 -0
  286. package/dist/components/LpScrollArea.vue.d.ts +1 -1
  287. package/dist/components/LpSecretField.vue.d.ts +108 -0
  288. package/dist/components/LpSecretField.vue.js +4 -0
  289. package/dist/components/LpSection.vue.js +1 -1
  290. package/dist/components/LpSegmented.vue.js +1 -1
  291. package/dist/components/LpSelect.vue.d.ts +2 -0
  292. package/dist/components/LpSelect.vue.js +1 -1
  293. package/dist/components/LpShaderBackdrop.vue.d.ts +39 -0
  294. package/dist/components/LpShaderBackdrop.vue.js +4 -0
  295. package/dist/components/LpShinyText.vue.d.ts +39 -0
  296. package/dist/components/LpShinyText.vue.js +4 -0
  297. package/dist/components/LpShortcutsDialog.vue.js +1 -1
  298. package/dist/components/LpSidebar.vue.js +1 -1
  299. package/dist/components/LpSidebarNav.vue.js +1 -1
  300. package/dist/components/LpSlider.vue.js +1 -1
  301. package/dist/components/LpSparkline.vue.d.ts +4 -3
  302. package/dist/components/LpSparkline.vue.js +1 -1
  303. package/dist/components/LpSpotlight.vue.d.ts +37 -0
  304. package/dist/components/LpSpotlight.vue.js +4 -0
  305. package/dist/components/LpStat.vue.js +1 -1
  306. package/dist/components/LpStatus.vue.d.ts +65 -0
  307. package/dist/components/LpStatus.vue.js +4 -0
  308. package/dist/components/LpStepMark.vue.d.ts +31 -0
  309. package/dist/components/LpStepMark.vue.js +4 -0
  310. package/dist/components/LpStepper.vue.js +1 -1
  311. package/dist/components/LpSwap.vue.js +1 -1
  312. package/dist/components/LpSwitch.vue.d.ts +2 -2
  313. package/dist/components/LpSwitch.vue.js +1 -1
  314. package/dist/components/LpTable.vue.js +104 -120
  315. package/dist/components/LpTableFilter.vue.js +1 -1
  316. package/dist/components/LpTableOfContents.vue.d.ts +6 -1
  317. package/dist/components/LpTableOfContents.vue.js +1 -1
  318. package/dist/components/LpTabs.vue.d.ts +5 -5
  319. package/dist/components/LpTabs.vue.js +25 -33
  320. package/dist/components/LpTagsInput.vue.js +1 -1
  321. package/dist/components/LpTextReveal.vue.d.ts +58 -0
  322. package/dist/components/LpTextReveal.vue.js +4 -0
  323. package/dist/components/LpTextarea.vue.js +1 -1
  324. package/dist/components/LpThemeProvider.vue.js +1 -1
  325. package/dist/components/LpThemeStudio.vue.d.ts +54 -0
  326. package/dist/components/LpThemeStudio.vue.js +4 -0
  327. package/dist/components/LpThemeStudioSection.vue.d.ts +16 -0
  328. package/dist/components/LpThemeStudioSection.vue.js +4 -0
  329. package/dist/components/LpThemeSwitcher.vue.d.ts +32 -1
  330. package/dist/components/LpThemeSwitcher.vue.js +1 -1
  331. package/dist/components/LpTimeField.vue.d.ts +2 -0
  332. package/dist/components/LpTimeField.vue.js +1 -1
  333. package/dist/components/LpToaster.vue.js +1 -1
  334. package/dist/components/LpTooltip.vue.d.ts +2 -2
  335. package/dist/components/LpTooltip.vue.js +1 -1
  336. package/dist/components/LpTopologyCanvas.vue.js +1 -1
  337. package/dist/components/LpTour.vue.js +1 -1
  338. package/dist/components/LpTruncate.vue.d.ts +34 -0
  339. package/dist/components/LpTruncate.vue.js +4 -0
  340. package/dist/components/LpTypewriter.vue.d.ts +61 -0
  341. package/dist/components/LpTypewriter.vue.js +4 -0
  342. package/dist/components/LpUptimeBar.vue.js +1 -1
  343. package/dist/components/LpVideoBackdrop.vue.js +1 -1
  344. package/dist/components/MenuTitle.vue.js +1 -1
  345. package/dist/components/OptionContent.vue.d.ts +7 -0
  346. package/dist/components/OptionContent.vue.js +4 -0
  347. package/dist/components/PickerField.vue.d.ts +45 -0
  348. package/dist/components/PickerField.vue.js +4 -0
  349. package/dist/components/RevealToggle.vue.d.ts +21 -0
  350. package/dist/components/RevealToggle.vue.js +4 -0
  351. package/dist/components/StepConnector.vue.d.ts +19 -0
  352. package/dist/components/StepConnector.vue.js +4 -0
  353. package/dist/components/TourCard.vue.js +1 -1
  354. package/dist/components/badge.d.ts +1 -0
  355. package/dist/components/badge.js +4 -0
  356. package/dist/components/chart.d.ts +5 -1
  357. package/dist/components/chart.js +2 -21
  358. package/dist/components/dateRange.d.ts +11 -0
  359. package/dist/components/dateRange.js +12 -0
  360. package/dist/components/dock.d.ts +19 -0
  361. package/dist/components/dock.js +16 -0
  362. package/dist/components/dropdown.d.ts +10 -1
  363. package/dist/components/dropdown.js +7 -2
  364. package/dist/components/fieldText.d.ts +38 -0
  365. package/dist/components/fieldText.js +53 -0
  366. package/dist/components/fileTree.d.ts +7 -3
  367. package/dist/components/fileTree.js +12 -18
  368. package/dist/components/format.d.ts +41 -0
  369. package/dist/components/format.js +67 -0
  370. package/dist/components/identicon.d.ts +38 -0
  371. package/dist/components/identicon.js +85 -0
  372. package/dist/components/masonry.d.ts +32 -0
  373. package/dist/components/masonry.js +40 -0
  374. package/dist/components/menuWhen.js +1 -1
  375. package/dist/components/meter.d.ts +64 -0
  376. package/dist/components/meter.js +53 -0
  377. package/dist/components/otp.d.ts +1 -1
  378. package/dist/components/otp.js +7 -2
  379. package/dist/components/pipeline.d.ts +55 -0
  380. package/dist/components/pipeline.js +51 -0
  381. package/dist/components/quota.d.ts +57 -0
  382. package/dist/components/quota.js +40 -0
  383. package/dist/components/relativeTime.d.ts +24 -0
  384. package/dist/components/relativeTime.js +56 -0
  385. package/dist/components/reveal.d.ts +18 -0
  386. package/dist/components/reveal.js +32 -0
  387. package/dist/components/scramble.d.ts +68 -0
  388. package/dist/components/scramble.js +58 -0
  389. package/dist/components/shaderBackdrop.d.ts +20 -0
  390. package/dist/components/shaderBackdrop.js +156 -0
  391. package/dist/components/slider.d.ts +5 -0
  392. package/dist/components/slider.js +24 -0
  393. package/dist/components/slotText.d.ts +2 -0
  394. package/dist/components/slotText.js +9 -0
  395. package/dist/components/status.d.ts +14 -0
  396. package/dist/components/status.js +22 -0
  397. package/dist/components/tableFacets.d.ts +8 -0
  398. package/dist/components/tableFacets.js +19 -0
  399. package/dist/components/textSplit.d.ts +17 -0
  400. package/dist/components/textSplit.js +24 -0
  401. package/dist/components/timeSpan.d.ts +78 -0
  402. package/dist/components/timeSpan.js +85 -0
  403. package/dist/components/tone.d.ts +43 -0
  404. package/dist/components/tone.js +82 -0
  405. package/dist/components/tour.js +3 -2
  406. package/dist/components/typewriter.d.ts +36 -0
  407. package/dist/components/typewriter.js +53 -0
  408. package/dist/components/videoBackdrop.js +5 -6
  409. package/dist/composables/easing.d.ts +22 -1
  410. package/dist/composables/easing.js +42 -1
  411. package/dist/composables/pseudoLocale.d.ts +15 -0
  412. package/dist/composables/pseudoLocale.js +96 -0
  413. package/dist/composables/scroll.js +5 -3
  414. package/dist/composables/useClipboard.d.ts +4 -1
  415. package/dist/composables/useClipboard.js +12 -2
  416. package/dist/composables/useField.d.ts +13 -0
  417. package/dist/composables/useField.js +26 -1
  418. package/dist/composables/useForm.js +32 -9
  419. package/dist/composables/useInView.d.ts +11 -0
  420. package/dist/composables/useInView.js +39 -0
  421. package/dist/composables/useLoadingGate.d.ts +8 -0
  422. package/dist/composables/useLoadingGate.js +38 -0
  423. package/dist/composables/useLpConfig.d.ts +10 -0
  424. package/dist/composables/useLpConfig.js +11 -1
  425. package/dist/composables/useMediaQuery.js +3 -1
  426. package/dist/composables/useNow.d.ts +16 -0
  427. package/dist/composables/useNow.js +39 -0
  428. package/dist/composables/usePersisted.js +14 -7
  429. package/dist/composables/usePillTransition.d.ts +5 -2
  430. package/dist/composables/usePillTransition.js +4 -3
  431. package/dist/composables/usePointerFrame.d.ts +18 -0
  432. package/dist/composables/usePointerFrame.js +31 -0
  433. package/dist/composables/useReducedMotion.d.ts +2 -0
  434. package/dist/composables/useReducedMotion.js +7 -0
  435. package/dist/composables/useRepeater.d.ts +17 -0
  436. package/dist/composables/useRepeater.js +31 -0
  437. package/dist/composables/useResizeObserver.d.ts +8 -0
  438. package/dist/composables/useResizeObserver.js +33 -0
  439. package/dist/composables/useRevealedValue.d.ts +31 -0
  440. package/dist/composables/useRevealedValue.js +26 -0
  441. package/dist/composables/useScramble.d.ts +42 -0
  442. package/dist/composables/useScramble.js +76 -0
  443. package/dist/composables/useShift.js +2 -10
  444. package/dist/composables/useSpotlight.d.ts +18 -0
  445. package/dist/composables/useSpotlight.js +53 -0
  446. package/dist/composables/useTilt.js +26 -18
  447. package/dist/composables/useTween.d.ts +43 -0
  448. package/dist/composables/useTween.js +69 -0
  449. package/dist/composables/useView.d.ts +18 -0
  450. package/dist/composables/useView.js +64 -0
  451. package/dist/icons-all.js +1 -1
  452. package/dist/index.d.ts +98 -1
  453. package/dist/index.js +263 -105
  454. package/dist/theme/define.d.ts +12 -0
  455. package/dist/theme/studio.d.ts +90 -0
  456. package/package.json +8 -2
  457. package/src/component-names.ts +33 -0
  458. package/src/components/AttentionDot.vue +27 -0
  459. package/src/components/ContextMenuItems.vue +5 -2
  460. package/src/components/FieldWrapper.vue +38 -0
  461. package/src/components/LayoutNode.vue +5 -9
  462. package/src/components/LegendSwatch.vue +15 -0
  463. package/src/components/LoaderMark.vue +90 -0
  464. package/src/components/LpActionBar.vue +12 -20
  465. package/src/components/LpActivityLine.vue +186 -0
  466. package/src/components/LpAlert.vue +54 -24
  467. package/src/components/LpAppShell.vue +7 -11
  468. package/src/components/LpAutocomplete.vue +16 -14
  469. package/src/components/LpAvatar.vue +17 -2
  470. package/src/components/LpBadge.vue +77 -13
  471. package/src/components/LpBreadcrumbs.vue +101 -35
  472. package/src/components/LpButton.vue +15 -3
  473. package/src/components/LpCard.vue +30 -7
  474. package/src/components/LpChart.vue +162 -171
  475. package/src/components/LpCheckbox.vue +10 -4
  476. package/src/components/LpCodeBlock.vue +11 -19
  477. package/src/components/LpCodeDisplay.vue +228 -0
  478. package/src/components/LpCollapse.vue +162 -0
  479. package/src/components/LpColorPicker.vue +10 -1
  480. package/src/components/LpCommandPalette.vue +38 -24
  481. package/src/components/LpContextMenu.vue +13 -3
  482. package/src/components/LpCopyButton.vue +185 -0
  483. package/src/components/LpCountdown.vue +308 -0
  484. package/src/components/LpDataList.vue +154 -0
  485. package/src/components/LpDatePicker.vue +55 -104
  486. package/src/components/LpDateRangePicker.vue +51 -95
  487. package/src/components/LpDisclosure.vue +58 -36
  488. package/src/components/LpDock.vue +274 -0
  489. package/src/components/LpDrawer.vue +10 -1
  490. package/src/components/LpDropdownMenu.vue +11 -2
  491. package/src/components/LpDropzone.vue +34 -13
  492. package/src/components/LpEditable.vue +295 -0
  493. package/src/components/LpFileTree.vue +5 -1
  494. package/src/components/LpFileTreeNode.vue +25 -50
  495. package/src/components/LpFormField.vue +22 -3
  496. package/src/components/LpFrame.vue +200 -0
  497. package/src/components/LpGauge.vue +287 -0
  498. package/src/components/LpGlowBorder.vue +60 -0
  499. package/src/components/LpHintExample.vue +9 -32
  500. package/src/components/LpHintLayer.vue +13 -3
  501. package/src/components/LpHoverCard.vue +175 -0
  502. package/src/components/LpIdenticon.vue +69 -0
  503. package/src/components/LpImageEditor.vue +15 -18
  504. package/src/components/LpInfraNode.vue +27 -16
  505. package/src/components/LpInput.vue +30 -16
  506. package/src/components/LpLightbox.vue +44 -23
  507. package/src/components/LpLoader.vue +145 -0
  508. package/src/components/LpLogViewer.vue +311 -82
  509. package/src/components/LpMagnetic.vue +97 -0
  510. package/src/components/LpMapPicker.vue +26 -28
  511. package/src/components/LpMasonry.vue +247 -0
  512. package/src/components/LpModal.vue +10 -1
  513. package/src/components/LpNotificationBell.vue +33 -49
  514. package/src/components/LpNumberField.vue +79 -14
  515. package/src/components/LpNumberFlow.vue +10 -35
  516. package/src/components/LpOtpInput.vue +7 -2
  517. package/src/components/LpPagination.vue +38 -4
  518. package/src/components/LpPalettePreview.vue +2 -7
  519. package/src/components/LpPasswordInput.vue +25 -18
  520. package/src/components/LpPhoneInput.vue +12 -3
  521. package/src/components/LpPie.vue +197 -36
  522. package/src/components/LpPipeline.vue +366 -0
  523. package/src/components/LpPopover.vue +14 -1
  524. package/src/components/LpProgress.vue +22 -84
  525. package/src/components/LpQuota.vue +197 -0
  526. package/src/components/LpRangeSlider.vue +5 -1
  527. package/src/components/LpRelativeTime.vue +90 -0
  528. package/src/components/LpRepeater.vue +131 -0
  529. package/src/components/LpRevealOnScroll.vue +125 -0
  530. package/src/components/LpRollingText.vue +12 -1
  531. package/src/components/LpScramble.vue +107 -0
  532. package/src/components/LpSecretField.vue +320 -0
  533. package/src/components/LpSegmented.vue +3 -10
  534. package/src/components/LpSelect.vue +74 -65
  535. package/src/components/LpShaderBackdrop.vue +434 -0
  536. package/src/components/LpShinyText.vue +139 -0
  537. package/src/components/LpSidebar.vue +2 -0
  538. package/src/components/LpSlider.vue +5 -1
  539. package/src/components/LpSparkline.vue +55 -37
  540. package/src/components/LpSpotlight.vue +51 -0
  541. package/src/components/LpStat.vue +6 -2
  542. package/src/components/LpStatus.vue +127 -0
  543. package/src/components/LpStepMark.vue +138 -0
  544. package/src/components/LpStepper.vue +37 -43
  545. package/src/components/LpSwap.vue +2 -2
  546. package/src/components/LpSwitch.vue +15 -22
  547. package/src/components/LpTable.vue +47 -63
  548. package/src/components/LpTableFilter.vue +1 -0
  549. package/src/components/LpTableOfContents.vue +53 -29
  550. package/src/components/LpTabs.vue +10 -21
  551. package/src/components/LpTagsInput.vue +53 -37
  552. package/src/components/LpTextReveal.vue +236 -0
  553. package/src/components/LpTextarea.vue +11 -11
  554. package/src/components/LpThemeStudio.vue +216 -0
  555. package/src/components/LpThemeStudioSection.vue +16 -0
  556. package/src/components/LpThemeSwitcher.vue +156 -47
  557. package/src/components/LpTimeField.vue +9 -1
  558. package/src/components/LpToaster.vue +63 -83
  559. package/src/components/LpTooltip.vue +10 -1
  560. package/src/components/LpTour.vue +24 -13
  561. package/src/components/LpTruncate.vue +135 -0
  562. package/src/components/LpTypewriter.vue +236 -0
  563. package/src/components/LpUptimeBar.vue +6 -5
  564. package/src/components/LpVideoBackdrop.vue +15 -13
  565. package/src/components/OptionContent.vue +17 -0
  566. package/src/components/PickerField.vue +59 -0
  567. package/src/components/RevealToggle.vue +51 -0
  568. package/src/components/StepConnector.vue +54 -0
  569. package/src/components/TourCard.vue +29 -16
  570. package/src/components/badge.ts +8 -0
  571. package/src/components/chart.ts +8 -23
  572. package/src/components/dateRange.ts +25 -0
  573. package/src/components/dock.ts +31 -0
  574. package/src/components/dropdown.ts +15 -3
  575. package/src/components/fieldText.ts +95 -0
  576. package/src/components/fileTree.ts +19 -21
  577. package/src/components/format.ts +136 -0
  578. package/src/components/identicon.ts +160 -0
  579. package/src/components/masonry.ts +73 -0
  580. package/src/components/meter.ts +122 -0
  581. package/src/components/otp.ts +14 -3
  582. package/src/components/pipeline.ts +101 -0
  583. package/src/components/quota.ts +111 -0
  584. package/src/components/relativeTime.ts +118 -0
  585. package/src/components/reveal.ts +56 -0
  586. package/src/components/scramble.ts +138 -0
  587. package/src/components/shaderBackdrop.ts +208 -0
  588. package/src/components/slider.ts +30 -0
  589. package/src/components/slotText.ts +13 -0
  590. package/src/components/status.ts +46 -0
  591. package/src/components/tableFacets.ts +25 -0
  592. package/src/components/textSplit.ts +55 -0
  593. package/src/components/timeSpan.ts +183 -0
  594. package/src/components/tone.ts +144 -0
  595. package/src/components/tour.ts +3 -2
  596. package/src/components/typewriter.ts +104 -0
  597. package/src/components/videoBackdrop.ts +7 -6
  598. package/src/composables/easing.ts +66 -1
  599. package/src/composables/pseudoLocale.ts +105 -0
  600. package/src/composables/scroll.ts +6 -3
  601. package/src/composables/useClipboard.ts +25 -3
  602. package/src/composables/useField.ts +38 -1
  603. package/src/composables/useForm.ts +41 -11
  604. package/src/composables/useInView.ts +61 -0
  605. package/src/composables/useLoadingGate.ts +63 -0
  606. package/src/composables/useLpConfig.ts +20 -1
  607. package/src/composables/useMediaQuery.ts +6 -2
  608. package/src/composables/useNow.ts +84 -0
  609. package/src/composables/usePersisted.ts +19 -8
  610. package/src/composables/usePillTransition.ts +21 -13
  611. package/src/composables/usePointerFrame.ts +72 -0
  612. package/src/composables/useReducedMotion.ts +22 -0
  613. package/src/composables/useRepeater.ts +44 -0
  614. package/src/composables/useResizeObserver.ts +59 -0
  615. package/src/composables/useRevealedValue.ts +84 -0
  616. package/src/composables/useScramble.ts +152 -0
  617. package/src/composables/useShift.ts +10 -16
  618. package/src/composables/useSpotlight.ts +82 -0
  619. package/src/composables/useTilt.ts +40 -23
  620. package/src/composables/useTween.ts +149 -0
  621. package/src/composables/useView.ts +96 -0
  622. package/src/index.css +1 -0
  623. package/src/index.ts +143 -1
  624. package/src/kit-icons.ts +1 -1
  625. package/src/theme/define.ts +65 -0
  626. package/src/theme/studio.ts +202 -0
  627. package/src/tokens/effects.css +151 -0
  628. package/src/tokens/tokens.css +131 -39
  629. package/src/tokens/utilities.css +81 -0
  630. package/dist/assets/LpTabs-Bk7v4bZz.css +0 -18
  631. package/dist/chunks/LpAlert-BdvxvcWE.js +0 -85
  632. package/dist/chunks/LpBadge-Fe0D1bYx.js +0 -62
  633. package/dist/chunks/LpBreadcrumbs-rzOKkLiI.js +0 -98
  634. package/dist/chunks/LpDatePicker-BMfM454Y.js +0 -243
  635. package/dist/chunks/LpDateRangePicker-CNb9X3eL.js +0 -195
  636. package/dist/chunks/LpNumberField-DO1ufKvE.js +0 -107
  637. package/dist/chunks/LpStepper-C2slwObu.js +0 -90
  638. package/dist/chunks/LpSwitch-CZy9_IoA.js +0 -132
  639. package/dist/chunks/LpThemeSwitcher-CDoziW0z.js +0 -166
  640. package/dist/chunks/TourCard-BKI7X9-r.js +0 -105
@@ -0,0 +1,200 @@
1
+ <script lang="ts">
2
+ // The consumer's `class` is merged into the iframe's own (below) rather than
3
+ // appended to it, so opt out of the automatic pass-through that would add it
4
+ // a second time, unmerged.
5
+ export default { inheritAttrs: false }
6
+ </script>
7
+
8
+ <script setup lang="ts">
9
+ /*
10
+ * A window of its own inside the page, as LpThemeProvider is a theme of its
11
+ * own: what is rendered in it behaves as if it were the whole screen. It is
12
+ * an iframe the slot is teleported into, so the content stays part of the
13
+ * same app (its state, theme, config and labels are the page's) while:
14
+ *
15
+ * - its width is the viewport: CSS breakpoints (`sm:`, `max-sm:`) and the
16
+ * kit's own media queries answer for the frame, so a frame narrowed to a
17
+ * phone gets the phone layout, a tour's bottom sheet included;
18
+ * - the kit's overlays (modals, popovers, menus, the tour, toasts) open
19
+ * inside it, not over the page;
20
+ * - a click outside the frame is not "outside" for what is open in it: a
21
+ * notification feed stays open while the page around it is used, and
22
+ * Escape pressed on the page does not close it.
23
+ *
24
+ * The page's stylesheets and the root element's theme are mirrored into the
25
+ * frame and kept in step (hot reloads and theme switches included). A modal
26
+ * in the frame would lock the page's scroll and pointer (reka locks the
27
+ * global body); the frame lifts such a lock while the page itself has no
28
+ * layer open. Its height follows the content unless `height` fixes it, which
29
+ * a screen-sized demo wants: a frame as tall as its content gives a modal
30
+ * nothing to centre in.
31
+ */
32
+ import { computed, onBeforeUnmount, onMounted, ref, shallowRef } from "vue"
33
+ import { useMergedAttrs } from "../composables/useMergedClass"
34
+ import { forwardViewEvents, provideView, type LpView } from "../composables/useView"
35
+
36
+ const props = withDefaults(
37
+ defineProps<{
38
+ /** Fixed height (px or any CSS length). Without it the frame grows with its content. */
39
+ height?: number | string
40
+ /** Read by assistive technology for the frame as a whole. */
41
+ title?: string
42
+ }>(),
43
+ { title: "Preview" },
44
+ )
45
+
46
+ const frame = ref<HTMLIFrameElement | null>(null)
47
+ const view = shallowRef<LpView | null>(null)
48
+ provideView(computed(() => view.value))
49
+
50
+ const contentHeight = ref(0)
51
+ const fixed = computed(() =>
52
+ props.height === undefined ? undefined : typeof props.height === "number" ? `${props.height}px` : props.height,
53
+ )
54
+
55
+ // Height eases, so a frame switched to a device screen or grown by an
56
+ // opening popover does not jump.
57
+ const { class: frameClass, attrs: rest } = useMergedAttrs(
58
+ "block w-full border-0 bg-transparent transition-[height] duration-(--duration-medium) ease-(--ease-emphasized) motion-reduce:transition-none",
59
+ )
60
+
61
+ const cleanups: (() => void)[] = []
62
+
63
+ function mirrorHead(doc: Document) {
64
+ const copies = new Map<Node, Node>()
65
+ const copy = (node: Node) => {
66
+ if (!(node instanceof HTMLStyleElement || (node instanceof HTMLLinkElement && node.rel === "stylesheet"))) return
67
+ const clone = doc.importNode(node, true)
68
+ copies.set(node, clone)
69
+ doc.head.appendChild(clone)
70
+ }
71
+ for (const node of document.head.childNodes) copy(node)
72
+ const observer = new MutationObserver((records) => {
73
+ for (const record of records) {
74
+ if (record.type === "childList") {
75
+ for (const node of record.addedNodes) copy(node)
76
+ for (const node of record.removedNodes) {
77
+ copies.get(node)?.parentNode?.removeChild(copies.get(node)!)
78
+ copies.delete(node)
79
+ }
80
+ continue
81
+ }
82
+ // A style rewritten in place (a hot reload) is copied again.
83
+ const style = record.target instanceof HTMLStyleElement ? record.target : record.target.parentNode
84
+ if (style instanceof HTMLStyleElement && copies.has(style)) copies.get(style)!.textContent = style.textContent
85
+ }
86
+ })
87
+ observer.observe(document.head, { childList: true, subtree: true, characterData: true })
88
+ cleanups.push(() => observer.disconnect())
89
+ }
90
+
91
+ // The theme lives on the page's root element (its class, data attributes and
92
+ // token variables); the frame's root carries the same, so it themes as one.
93
+ function mirrorRoot(doc: Document) {
94
+ const sync = () => {
95
+ const from = document.documentElement
96
+ const to = doc.documentElement
97
+ for (const name of to.getAttributeNames()) if (!from.hasAttribute(name)) to.removeAttribute(name)
98
+ for (const name of from.getAttributeNames()) to.setAttribute(name, from.getAttribute(name) ?? "")
99
+ }
100
+ sync()
101
+ const observer = new MutationObserver(sync)
102
+ observer.observe(document.documentElement, { attributes: true })
103
+ cleanups.push(() => observer.disconnect())
104
+ }
105
+
106
+ // reka's modal locks `document.body` of the page whatever document the layer
107
+ // is in. The lock is the page's only when the page has a layer of its own.
108
+ function liftForeignLocks(doc: Document) {
109
+ const lift = () => {
110
+ if (!doc.querySelector("[data-dismissable-layer]")) return
111
+ if (document.querySelector("[data-dismissable-layer]")) return
112
+ const style = document.body.style
113
+ if (style.pointerEvents === "none") style.pointerEvents = ""
114
+ if (style.overflow === "hidden") {
115
+ style.overflow = ""
116
+ style.paddingRight = ""
117
+ style.marginRight = ""
118
+ }
119
+ }
120
+ const observer = new MutationObserver(lift)
121
+ observer.observe(document.body, { attributes: true, attributeFilter: ["style"] })
122
+ cleanups.push(() => observer.disconnect())
123
+ }
124
+
125
+ function setup() {
126
+ const win = frame.value?.contentWindow
127
+ const doc = frame.value?.contentDocument
128
+ if (!win || !doc) return
129
+ // Relative URLs in the copied styles (fonts, images) resolve against the page.
130
+ const base = doc.createElement("base")
131
+ base.href = document.baseURI
132
+ doc.head.appendChild(base)
133
+ doc.body.style.margin = "0"
134
+ doc.body.style.background = "transparent"
135
+ mirrorHead(doc)
136
+ mirrorRoot(doc)
137
+ liftForeignLocks(doc)
138
+ cleanups.push(forwardViewEvents(doc, document))
139
+ const content = doc.createElement("div")
140
+ doc.body.appendChild(content)
141
+ // Grown to fit the content and whatever is open over it: a popover hanging
142
+ // below the last line would otherwise be cut off at the frame's edge.
143
+ let pending = 0
144
+ const measure = () => {
145
+ pending = 0
146
+ let bottom = content.offsetHeight
147
+ for (const child of doc.body.children) {
148
+ if (child === content) continue
149
+ for (const layer of child.querySelectorAll("[data-dismissable-layer], [role=dialog], [role=menu], [role=listbox]")) {
150
+ bottom = Math.max(bottom, Math.ceil(layer.getBoundingClientRect().bottom + 8))
151
+ }
152
+ }
153
+ contentHeight.value = bottom
154
+ }
155
+ const schedule = () => {
156
+ if (!pending) pending = win.requestAnimationFrame(measure)
157
+ }
158
+ const Observer = (win as Window & typeof globalThis).ResizeObserver
159
+ const resize = new Observer(schedule)
160
+ resize.observe(content)
161
+ const layers = new (win as Window & typeof globalThis).MutationObserver(schedule)
162
+ layers.observe(doc.body, { childList: true, subtree: true })
163
+ cleanups.push(() => {
164
+ resize.disconnect()
165
+ layers.disconnect()
166
+ if (pending) win.cancelAnimationFrame(pending)
167
+ })
168
+ view.value = { window: win, document: doc, portal: doc.body }
169
+ root.value = content
170
+ }
171
+
172
+ const root = shallowRef<HTMLElement | null>(null)
173
+
174
+ onMounted(() => {
175
+ const el = frame.value
176
+ if (!el) return
177
+ // about:blank is ready synchronously in Chromium and WebKit, but Firefox
178
+ // swaps the document on load: wait for it there.
179
+ if (el.contentDocument?.readyState === "complete") setup()
180
+ else el.addEventListener("load", setup, { once: true })
181
+ })
182
+
183
+ onBeforeUnmount(() => {
184
+ for (const clean of cleanups) clean()
185
+ cleanups.length = 0
186
+ })
187
+ </script>
188
+
189
+ <template>
190
+ <iframe
191
+ ref="frame"
192
+ :title="title"
193
+ :class="frameClass"
194
+ :style="{ height: fixed ?? `${contentHeight}px` }"
195
+ v-bind="rest"
196
+ />
197
+ <Teleport v-if="root" :to="root">
198
+ <slot />
199
+ </Teleport>
200
+ </template>
@@ -0,0 +1,287 @@
1
+ <script lang="ts">
2
+ // The consumer's `class` is merged into the root's own rather than appended to
3
+ // it, so opt out of the automatic pass-through that would add it unmerged.
4
+ export default { inheritAttrs: false }
5
+ </script>
6
+
7
+ <script setup lang="ts">
8
+ /*
9
+ * One reading within a range, drawn as a dial: CPU load, disk use, a score.
10
+ *
11
+ * Not a variant of LpProgress's ring, though both draw an arc. The ring is
12
+ * progress toward done: it starts at zero, closes into a circle at 100 and has
13
+ * no idea what the number means. A gauge is a reading on a scale: it has a
14
+ * floor that need not be zero, steps along the way where the reading changes
15
+ * meaning (the threshold notches), and a sweep with a visible start and end so
16
+ * the eye can tell low from high without reading the figure. Folding that into
17
+ * the ring would grow it a second set of props that only apply in one variant.
18
+ * The arithmetic both need (fraction of a range, tone at a reading) lives in
19
+ * meter.ts and is shared rather than copied.
20
+ */
21
+ import { computed } from "vue"
22
+ import { useLabels } from "../composables/useLpConfig"
23
+ import { useLocale } from "../composables/useLocale"
24
+ import { useMergedAttrs } from "../composables/useMergedClass"
25
+ import { useRevealedValue } from "../composables/useRevealedValue"
26
+ import LpNumberFlow from "./LpNumberFlow.vue"
27
+ import LpRollingText from "./LpRollingText.vue"
28
+ import {
29
+ arcPath,
30
+ capacityThresholds,
31
+ GAUGE_SWEEP,
32
+ meterFraction,
33
+ polar,
34
+ toneAt,
35
+ type MeterThreshold,
36
+ type MeterTone,
37
+ } from "./meter"
38
+ import { toneLook } from "./tone"
39
+
40
+ export type GaugeLabels = {
41
+ /** Appended to the spoken value when the reading is in a warning step. */
42
+ warning: string
43
+ /** Appended to the spoken value when the reading is in a danger step. */
44
+ danger: string
45
+ }
46
+
47
+ const props = withDefaults(
48
+ defineProps<{
49
+ value: number
50
+ min?: number
51
+ max?: number
52
+ /**
53
+ * Steps of the scale, in the gauge's own units: from each `at` upward the
54
+ * arc takes that tone. Unset, the capacity scale applies (warning from 80%
55
+ * of the range, danger from 90%), which is what a resource gauge wants. A
56
+ * score where higher is better lists its own steps:
57
+ * `[{ at: 0, tone: 'danger' }, { at: 50, tone: 'warning' }, { at: 80, tone: 'ok' }]`.
58
+ */
59
+ thresholds?: MeterThreshold[]
60
+ /**
61
+ * A fixed tone instead of the scale. For a gauge whose reading is neither
62
+ * good nor bad (a temperature, a position), where colouring it by
63
+ * thresholds would invent a judgement.
64
+ */
65
+ tone?: MeterTone
66
+ /** What is measured, printed under the figure ("CPU", "Disk"). Also the accessible name. */
67
+ label?: string
68
+ /** Printed after the figure, smaller ("%", "°C", "ms"). */
69
+ unit?: string
70
+ /** Decimal places of the figure. */
71
+ decimals?: number
72
+ /**
73
+ * Says the figure differently ("1.2k", "3/8"). Overrides `decimals`; the
74
+ * figure still rolls, since the formatted string is what LpNumberFlow animates.
75
+ */
76
+ format?: (value: number) => string
77
+ /** `semi` (default) sweeps across the top; `full` is a 270° dial open at the bottom. */
78
+ variant?: "semi" | "full"
79
+ /** Width in px. The height follows from the shape. */
80
+ size?: number
81
+ /** Arc thickness in px. Defaults to a share of `size`. */
82
+ thickness?: number
83
+ /** Print `min` and `max` under the ends of the arc. On by default for `semi`, where they sit naturally. */
84
+ showRange?: boolean
85
+ /** Notch the track where each threshold starts, so the reader sees how far the next step is. */
86
+ showThresholds?: boolean
87
+ /**
88
+ * Sweep up from the floor when first seen, instead of appearing already
89
+ * at the reading. Later changes always ease from where the needle is.
90
+ */
91
+ animateOnMount?: boolean
92
+ /** Sweep length in ms, shared by the arc and the figure. */
93
+ duration?: number
94
+ locale?: string
95
+ labels?: Partial<GaugeLabels>
96
+ }>(),
97
+ {
98
+ min: 0,
99
+ max: 100,
100
+ decimals: 0,
101
+ variant: "semi",
102
+ size: 160,
103
+ showRange: undefined,
104
+ showThresholds: true,
105
+ animateOnMount: true,
106
+ // Same as LpProgress: a gauge filling is content, and at the kit's
107
+ // `slow` step the sweep is over before it is noticed.
108
+ duration: 900,
109
+ },
110
+ )
111
+
112
+ const text = useLabels<GaugeLabels>("gauge", { warning: "warning", danger: "critical" }, () => props.labels)
113
+ const locale = useLocale(() => props.locale)
114
+
115
+ /*
116
+ * One animated number drives both the arc and the figure, as in LpProgress:
117
+ * two animations of the same length still drift apart through the middle,
118
+ * because they ease on different curves.
119
+ */
120
+ const { el: revealAnchor, shown } = useRevealedValue(() => props.value, {
121
+ from: () => props.min,
122
+ animateOnMount: () => props.animateOnMount,
123
+ duration: () => props.duration,
124
+ })
125
+
126
+ const steps = computed(() => props.thresholds ?? capacityThresholds(props.min, props.max))
127
+
128
+ /*
129
+ * The tone follows the TARGET, not the sweeping value, so the arc does not
130
+ * flash through amber on its way down from red: it travels in the colour its
131
+ * reading warrants.
132
+ */
133
+ const paintedTone = computed<MeterTone>(() => props.tone ?? toneAt(props.value, steps.value))
134
+
135
+ const thick = computed(() => props.thickness ?? Math.max(4, Math.round(props.size * 0.075)))
136
+ const sweep = computed(() => GAUGE_SWEEP[props.variant])
137
+ // Threshold notches sit just outside the arc, so the arc gives up their room.
138
+ const NOTCH = 5
139
+ const radius = computed(() => (props.size - thick.value) / 2 - (props.showThresholds ? NOTCH : 0))
140
+ const cx = computed(() => props.size / 2)
141
+ const cy = computed(() => props.size / 2)
142
+ // A semicircle needs only its top half plus the round caps hanging below the
143
+ // ends; the full dial needs the square.
144
+ const height = computed(() =>
145
+ props.variant === "semi" ? Math.ceil(cy.value + thick.value / 2) : props.size,
146
+ )
147
+
148
+ const track = computed(() => arcPath(cx.value, cy.value, radius.value, sweep.value[0], sweep.value[1]))
149
+ const fraction = computed(() => meterFraction(shown.value, props.min, props.max))
150
+
151
+ /*
152
+ * The value arc is the track path dashed to length, with `pathLength` so the
153
+ * dash is a plain share of 1000 whatever the radius. At zero a round-capped
154
+ * zero-length dash still draws a dot, so the arc hides instead.
155
+ */
156
+ const dash = computed(() => `${(fraction.value * 1000).toFixed(2)} 1000`)
157
+
158
+ const notches = computed(() => {
159
+ if (!props.showThresholds) return []
160
+ const [from, to] = sweep.value
161
+ const inner = radius.value + thick.value / 2 + 1.5
162
+ const outer = inner + NOTCH - 1
163
+ return steps.value
164
+ .filter((s) => s.at > props.min && s.at < props.max)
165
+ .map((s) => {
166
+ const deg = from + (to - from) * meterFraction(s.at, props.min, props.max)
167
+ const a = polar(cx.value, cy.value, inner, deg)
168
+ const b = polar(cx.value, cy.value, outer, deg)
169
+ return { key: `${s.at}-${s.tone}`, a, b, color: toneLook(s.tone).color }
170
+ })
171
+ })
172
+
173
+ const rangeShown = computed(() => props.showRange ?? props.variant === "semi")
174
+
175
+ const formatter = computed(() => {
176
+ if (props.format) return props.format
177
+ const nf = new Intl.NumberFormat(locale.value, {
178
+ minimumFractionDigits: props.decimals,
179
+ maximumFractionDigits: props.decimals,
180
+ })
181
+ return (v: number) => nf.format(v)
182
+ })
183
+
184
+ const valueText = computed(() => {
185
+ const reading = `${formatter.value(props.value)}${props.unit ? ` ${props.unit}` : ""}`
186
+ const tone = paintedTone.value
187
+ return tone === "warning" || tone === "danger" ? `${reading}, ${text.value[tone]}` : reading
188
+ })
189
+
190
+ const { class: rootClass, attrs: rest } = useMergedAttrs(
191
+ "relative inline-flex shrink-0 flex-col items-center",
192
+ )
193
+ const figureSize = computed(() => `${Math.max(14, Math.round(props.size * 0.19))}px`)
194
+ </script>
195
+
196
+ <template>
197
+ <div
198
+ :ref="(el) => (revealAnchor = el as Element | null)"
199
+ role="meter"
200
+ :aria-valuenow="value"
201
+ :aria-valuemin="min"
202
+ :aria-valuemax="max"
203
+ :aria-valuetext="valueText"
204
+ :aria-label="label"
205
+ :class="rootClass"
206
+ :style="{ width: `${size}px` }"
207
+ v-bind="rest"
208
+ >
209
+ <div class="relative">
210
+ <svg
211
+ :width="size"
212
+ :height="height"
213
+ :viewBox="`0 0 ${size} ${height}`"
214
+ class="overflow-visible"
215
+ aria-hidden="true"
216
+ >
217
+ <path
218
+ :d="track"
219
+ fill="none"
220
+ stroke="var(--color-surface-soft)"
221
+ :stroke-width="thick"
222
+ stroke-linecap="round"
223
+ />
224
+ <path
225
+ :d="track"
226
+ fill="none"
227
+ pathLength="1000"
228
+ :stroke="toneLook(paintedTone).color"
229
+ :stroke-width="thick"
230
+ stroke-linecap="round"
231
+ :stroke-dasharray="dash"
232
+ :opacity="fraction > 0.0005 ? 1 : 0"
233
+ class="transition-[stroke] duration-(--duration-slow) ease-(--ease-emphasized) motion-reduce:transition-none"
234
+ />
235
+ <line
236
+ v-for="n in notches"
237
+ :key="n.key"
238
+ :x1="n.a.x"
239
+ :y1="n.a.y"
240
+ :x2="n.b.x"
241
+ :y2="n.b.y"
242
+ :stroke="n.color"
243
+ stroke-width="2"
244
+ stroke-linecap="round"
245
+ />
246
+ </svg>
247
+
248
+ <!-- The figure sits in the bowl of the arc: on its baseline for the
249
+ semicircle, in the middle for the dial. -->
250
+ <div
251
+ class="pointer-events-none absolute inset-x-0 flex flex-col items-center leading-none"
252
+ :class="variant === 'semi' ? 'bottom-0' : 'top-1/2 -translate-y-1/2'"
253
+ >
254
+ <span class="flex items-baseline gap-0.5 font-mono font-semibold text-ink" :style="{ fontSize: figureSize }">
255
+ <LpNumberFlow
256
+ :value="shown"
257
+ :decimals="decimals"
258
+ :format="format"
259
+ :locale="locale"
260
+ :duration="0"
261
+ :animate-on-mount="false"
262
+ :style="{ '--lp-nf-spin': '90ms' }"
263
+ />
264
+ <span v-if="unit" class="text-[0.55em] font-medium text-muted">{{ unit }}</span>
265
+ </span>
266
+ <span v-if="label && variant === 'full'" class="mt-1 text-xs text-muted">
267
+ <LpRollingText :value="label" />
268
+ </span>
269
+ </div>
270
+ </div>
271
+
272
+ <!-- Under a semicircle the label shares the baseline row with the range
273
+ ends rather than stacking under the figure inside the bowl: a small
274
+ gauge has no room for both there, and the figure ran into the arc. -->
275
+ <div
276
+ v-if="rangeShown || (label && variant === 'semi')"
277
+ class="mt-1 grid w-full grid-cols-[1fr_auto_1fr] items-baseline gap-2 text-[11px] text-muted"
278
+ :style="{ paddingInline: `${Math.max(0, cx - radius - thick / 2)}px` }"
279
+ >
280
+ <span class="font-mono tabular-nums" aria-hidden="true">{{ rangeShown ? formatter(min) : "" }}</span>
281
+ <span class="truncate text-xs">
282
+ <LpRollingText v-if="label && variant === 'semi'" :value="label" />
283
+ </span>
284
+ <span class="text-right font-mono tabular-nums" aria-hidden="true">{{ rangeShown ? formatter(max) : "" }}</span>
285
+ </div>
286
+ </div>
287
+ </template>
@@ -0,0 +1,60 @@
1
+ <script lang="ts">
2
+ export default { inheritAttrs: false }
3
+ </script>
4
+
5
+ <script setup lang="ts">
6
+ /*
7
+ * LpGlowBorder — a gradient that runs round the edge of whatever it wraps.
8
+ *
9
+ * <LpGlowBorder><LpCard>Recommended build</LpCard></LpGlowBorder>
10
+ *
11
+ * For the ONE item in a list that should be noticed first: a new release, the
12
+ * recommended option. Several glowing borders on one screen cancel each other
13
+ * out, so this is a highlight, not a style.
14
+ *
15
+ * Pure CSS (`.lp-glow-border` in tokens/effects.css): a conic gradient whose
16
+ * angle is an animated registered property. Without @property support (older
17
+ * WebKitGTK) the ring stays still as a static gradient border, and reduced
18
+ * motion stops it the same way. The ring takes no layout space: it sits just
19
+ * outside the wrapped element's edge, following `rounded-card` by default —
20
+ * pass a radius class matching the child if it is not a card.
21
+ */
22
+ import { computed } from "vue"
23
+ import { useMergedAttrs } from "../composables/useMergedClass"
24
+
25
+ const props = withDefaults(
26
+ defineProps<{
27
+ /** Leading colour of the gradient. Defaults to the brand colour. */
28
+ from?: string
29
+ /** Trailing colour of the gradient. Defaults to the action colour. */
30
+ to?: string
31
+ /** Ring thickness in px. */
32
+ width?: number
33
+ /** Seconds per revolution. Slower reads as calm, faster as urgent. */
34
+ speed?: number
35
+ /**
36
+ * Light the ring. Off keeps the wrapper (so the layout does not change when
37
+ * an item stops being "new") and removes only the ring.
38
+ */
39
+ active?: boolean
40
+ /** Element to render as. */
41
+ as?: string
42
+ }>(),
43
+ { width: 1.5, speed: 4, active: true, as: "div" },
44
+ )
45
+
46
+ const { class: classes, attrs: rest } = useMergedAttrs(() => "lp-glow-border rounded-card")
47
+
48
+ const style = computed(() => ({
49
+ "--lp-glow-width": `${props.width}px`,
50
+ "--lp-glow-speed": `${props.speed}s`,
51
+ ...(props.from ? { "--lp-glow-from": props.from } : {}),
52
+ ...(props.to ? { "--lp-glow-to": props.to } : {}),
53
+ }))
54
+ </script>
55
+
56
+ <template>
57
+ <component :is="as" :class="classes" :style="style" :data-lp-glow-off="active ? undefined : ''" v-bind="rest">
58
+ <slot />
59
+ </component>
60
+ </template>
@@ -31,9 +31,9 @@
31
31
  * card still says it is an example.
32
32
  */
33
33
  import { computed, watch } from "vue"
34
- import { durationToken, easingToken, prefersReducedMotion } from "../composables/easing"
35
34
  import { hints } from "../composables/useHints"
36
35
  import HintSampleTag from "./HintSampleTag.vue"
36
+ import LpCollapse from "./LpCollapse.vue"
37
37
 
38
38
  const props = defineProps<{
39
39
  /** The hint id this stands in for, as in `v-hint`, or several for a sample with parts. */
@@ -59,26 +59,10 @@ watch(
59
59
 
60
60
  const visible = computed(() => absent.value.some((id) => hints.showingExample(id)))
61
61
 
62
- // The block grows from nothing and shrinks back, so what sits below it glides
63
- // instead of jumping. It exists only while shown: an always-present wrapper
64
- // would take a gap in the parent's flex column even when empty.
65
-
66
- function grow(el: Element, done: () => void, opening: boolean) {
67
- if (prefersReducedMotion()) return done()
68
- const box = el as HTMLElement
69
- const frames = [
70
- { height: "0px", opacity: 0 },
71
- { height: `${box.scrollHeight}px`, opacity: 1 },
72
- ]
73
- box.style.overflow = "hidden"
74
- box.animate(opening ? frames : frames.reverse(), {
75
- duration: durationToken("duration-medium"),
76
- easing: easingToken("ease-emphasized"),
77
- }).onfinish = () => {
78
- box.style.overflow = ""
79
- done()
80
- }
81
- }
62
+ // The block folds open from nothing and shut again (LpCollapse), so what sits
63
+ // below it glides instead of jumping. It exists only while shown (the collapse
64
+ // unmounts it once folded): an always-present wrapper would take a gap in the
65
+ // parent's flex column even when empty.
82
66
  </script>
83
67
 
84
68
  <template>
@@ -93,15 +77,8 @@ function grow(el: Element, done: () => void, opening: boolean) {
93
77
  <slot />
94
78
  </span>
95
79
  </Transition>
96
- <Transition
97
- v-else
98
- :css="false"
99
- @enter="(el, done) => grow(el, done, true)"
100
- @leave="(el, done) => grow(el, done, false)"
101
- >
102
- <div v-if="visible" :data-lp-hint-example="ids.join(' ')" inert aria-hidden="true" class="relative">
103
- <slot />
104
- <HintSampleTag :labels="labels" />
105
- </div>
106
- </Transition>
80
+ <LpCollapse v-else :open="visible" :data-lp-hint-example="ids.join(' ')" inert aria-hidden="true" class="relative">
81
+ <slot />
82
+ <HintSampleTag :labels="labels" />
83
+ </LpCollapse>
107
84
  </template>
@@ -20,7 +20,9 @@ import { computed, onBeforeUnmount, onMounted, ref, shallowRef, watch } from "vu
20
20
  import { hints } from "../composables/useHints"
21
21
  import { useLabels } from "../composables/useLpConfig"
22
22
  import { PANEL_SURFACE, POPOVER_ANIM } from "./dropdown"
23
+ import LpBadge from "./LpBadge.vue"
23
24
  import LpButton from "./LpButton.vue"
25
+ import { useOutsideGuard, usePortalTarget } from "../composables/useView"
24
26
 
25
27
  const props = withDefaults(
26
28
  defineProps<{
@@ -104,10 +106,16 @@ onBeforeUnmount(() => {
104
106
  })
105
107
 
106
108
  const note = computed(() => (openId.value ? props.notes[openId.value] : undefined))
109
+
110
+ // Overlays open in the window this component renders in (an LpFrame's, inside one).
111
+ const portalTo = usePortalTarget()
112
+ // What happens in another document (the page around a frame, or a frame in
113
+ // the page) is not "outside" for this layer.
114
+ const guardOutside = useOutsideGuard()
107
115
  </script>
108
116
 
109
117
  <template>
110
- <Teleport to="body">
118
+ <Teleport :to="portalTo">
111
119
  <button
112
120
  v-for="spot in spots"
113
121
  :key="spot.id"
@@ -126,15 +134,17 @@ const note = computed(() => (openId.value ? props.notes[openId.value] : undefine
126
134
  </button>
127
135
  <PopoverRoot :open="!!openId" @update:open="(value) => !value && (openId = null)">
128
136
  <PopoverAnchor v-if="anchor" :reference="anchor" />
129
- <PopoverPortal>
137
+ <PopoverPortal :to="portalTo">
130
138
  <PopoverContent
139
+ @interact-outside="guardOutside"
140
+ @escape-key-down="guardOutside"
131
141
  side="bottom"
132
142
  :side-offset="8"
133
143
  :collision-padding="8"
134
144
  :class="[PANEL_SURFACE, POPOVER_ANIM, 'z-(--z-popover) w-72 rounded-card p-3 text-sm text-ink outline-none']"
135
145
  >
136
146
  <p class="flex items-center gap-2 font-medium">
137
- <span class="rounded-full bg-brand/15 px-1.5 text-[11px] text-brand">{{ labels.badge }}</span>
147
+ <LpBadge tone="brand" size="sm">{{ labels.badge }}</LpBadge>
138
148
  {{ note?.title }}
139
149
  </p>
140
150
  <p v-if="note?.text" class="mt-1.5 text-muted">{{ note.text }}</p>