@leavepulse/ui 0.68.0 → 0.70.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 (640) hide show
  1. package/README.md +37 -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/LpShinyText-D69cBYDR.css +61 -0
  11. package/dist/assets/LpStatus-430OGTZY.css +17 -0
  12. package/dist/assets/LpStepMark-Drvx33Vg.css +10 -0
  13. package/dist/assets/{LpTable-BPERfJIk.css → LpTable-DHxEQ_-3.css} +19 -19
  14. package/dist/assets/LpTabs-BJ-nrJuI.css +18 -0
  15. package/dist/assets/LpTextReveal-DjI1MsDS.css +35 -0
  16. package/dist/assets/LpTypewriter-CXAm9Nca.css +27 -0
  17. package/dist/chunks/AttentionDot-DCBf4aWg.js +25 -0
  18. package/dist/chunks/{ContextMenuItems-B7XFHksm.js → ContextMenuItems-B5uE8Znw.js} +1 -1
  19. package/dist/chunks/{DropzoneLinkField-CjkrpDqO.js → DropzoneLinkField-Bw8Flkhk.js} +2 -2
  20. package/dist/chunks/FieldWrapper-BiennROB.js +43 -0
  21. package/dist/chunks/{LayoutCanvas-DF9CovaK.js → LayoutCanvas-BsJIzhdd.js} +1 -1
  22. package/dist/chunks/{LayoutNode-D9bIFzk0.js → LayoutNode-DJVhkSGk.js} +6 -8
  23. package/dist/chunks/LegendSwatch-BhRjrtzv.js +18 -0
  24. package/dist/chunks/LoaderMark-C1dubiKn.js +85 -0
  25. package/dist/chunks/{LpActionBar-MPKMu3pz.js → LpActionBar-CzOFar5t.js} +14 -20
  26. package/dist/chunks/LpActivityLine-CJvzrNpj.js +95 -0
  27. package/dist/chunks/{LpAddressInput-DG0BTqdH.js → LpAddressInput-CNnLTDZg.js} +7 -7
  28. package/dist/chunks/LpAlert-C5igj802.js +119 -0
  29. package/dist/chunks/{LpAppShell-DPh1756q.js → LpAppShell-CEUAB8kK.js} +15 -16
  30. package/dist/chunks/{LpAutocomplete-Dgn6hw3p.js → LpAutocomplete-D92niDHE.js} +15 -32
  31. package/dist/chunks/{LpAvatar-Bs0Fb1lC.js → LpAvatar-CLPl-qOF.js} +18 -6
  32. package/dist/chunks/LpBadge-HOEPBYmi.js +126 -0
  33. package/dist/chunks/LpBreadcrumbs-DYoPc3P4.js +144 -0
  34. package/dist/chunks/{LpButton-DNR-YAq5.js → LpButton-CVxBfGjd.js} +12 -4
  35. package/dist/chunks/{LpCalendar-BLya39Fh.js → LpCalendar-pVL91-Pl.js} +1 -1
  36. package/dist/chunks/{LpCard-Bf71NXZq.js → LpCard-CqKLnEhl.js} +18 -8
  37. package/dist/chunks/{LpCheckbox-Da5oZPHo.js → LpCheckbox-DHc2bHDe.js} +9 -6
  38. package/dist/chunks/{LpCodeBlock-lLbmslfs.js → LpCodeBlock-BGsQhxw8.js} +24 -32
  39. package/dist/chunks/LpCodeDisplay-CIKKT2iW.js +189 -0
  40. package/dist/chunks/LpCollapse-CWS9M_lm.js +115 -0
  41. package/dist/chunks/{LpColorPicker-DtEfBAcK.js → LpColorPicker-DFugXNUi.js} +10 -5
  42. package/dist/chunks/{LpConfirmDialog-D7s4jakB.js → LpConfirmDialog-CfGCux8m.js} +3 -3
  43. package/dist/chunks/{LpConfirmHost-DrYI5y1K.js → LpConfirmHost-exB7JmcO.js} +1 -1
  44. package/dist/chunks/{LpContextMenu-CRnjoqSt.js → LpContextMenu-COwOwRgI.js} +13 -5
  45. package/dist/chunks/LpCopyButton-DzHjnFs0.js +133 -0
  46. package/dist/chunks/LpCountdown-Dtq1ihlJ.js +231 -0
  47. package/dist/chunks/LpDataList-B-5nHfNw.js +120 -0
  48. package/dist/chunks/LpDatePicker-BUe1VUC0.js +168 -0
  49. package/dist/chunks/LpDateRangePicker-C_k65vGR.js +126 -0
  50. package/dist/chunks/{LpDisclosure-6AplYBub.js → LpDisclosure-DOarzlAG.js} +22 -11
  51. package/dist/chunks/{LpDrawer-Q4SOxM4s.js → LpDrawer-DGNKRsGq.js} +9 -4
  52. package/dist/chunks/{LpDropdownMenu-DWTt0ooM.js → LpDropdownMenu-CRgrhdAH.js} +10 -5
  53. package/dist/chunks/LpEditable-DTqLt2lT.js +236 -0
  54. package/dist/chunks/{LpEmptyState-om1UnFjV.js → LpEmptyState-KTKipws2.js} +1 -1
  55. package/dist/chunks/{LpFieldNotice-CHuDeLjc.js → LpFieldNotice-CurbNuXI.js} +1 -1
  56. package/dist/chunks/{LpFileTree-CW24YsVX.js → LpFileTree-DMISXVHC.js} +5 -3
  57. package/dist/chunks/{LpFileTreeNode-BXhTHaKW.js → LpFileTreeNode-CPXB_Yy3.js} +42 -55
  58. package/dist/chunks/{LpFormField-DPb47HEm.js → LpFormField-BWwgm1E4.js} +23 -9
  59. package/dist/chunks/LpFrame-BVQCQLDI.js +155 -0
  60. package/dist/chunks/LpGauge-Bk8TwJj0.js +204 -0
  61. package/dist/chunks/LpGlowBorder-B8V-QzIl.js +40 -0
  62. package/dist/chunks/{LpHintExample-C1eKYdeL.js → LpHintExample-9Py0wc-L.js} +11 -34
  63. package/dist/chunks/{LpHintLayer-7UOdWQG3.js → LpHintLayer-p4hqzdyA.js} +27 -14
  64. package/dist/chunks/{LpHints-BUtBp9-w.js → LpHints-CCrhRfy9.js} +3 -3
  65. package/dist/chunks/LpHoverCard-spGxyw7T.js +130 -0
  66. package/dist/chunks/{LpIcon-6tSrZ3Zy.js → LpIcon-HJP5xMz4.js} +1 -1
  67. package/dist/chunks/LpIdenticon-BzdC_qz9.js +63 -0
  68. package/dist/chunks/{LpInfraNode-Ds_8SZgN.js → LpInfraNode-CUC3t4na.js} +39 -25
  69. package/dist/chunks/{LpInput-CUyr6PIE.js → LpInput-CDuwODJG.js} +44 -18
  70. package/dist/chunks/{LpLightbox-B9J8rzsj.js → LpLightbox-XJ0LpTcZ.js} +69 -69
  71. package/dist/chunks/LpLoader-DjJEX8hL.js +92 -0
  72. package/dist/chunks/{LpLogViewer-4QFc-sVN.js → LpLogViewer-elZHbj85.js} +225 -129
  73. package/dist/chunks/LpMagnetic-CtXKLa2Y.js +62 -0
  74. package/dist/chunks/{LpMapPicker-BTbkFeSG.js → LpMapPicker-BtIl7NOM.js} +34 -31
  75. package/dist/chunks/LpMasonry--k0571qG.js +185 -0
  76. package/dist/chunks/{LpMediaGallery-CuPcscx3.js → LpMediaGallery-D5swlmZ_.js} +3 -3
  77. package/dist/chunks/{LpModal-hk1noDcr.js → LpModal-eBMt2Fqn.js} +8 -3
  78. package/dist/chunks/{LpModalNav-DQd2keZm.js → LpModalNav-D4Z0wVHR.js} +4 -4
  79. package/dist/chunks/{LpNotificationBell-X84PJIxD.js → LpNotificationBell-DPZmP5dM.js} +32 -48
  80. package/dist/chunks/LpNumberField-B9k-h2HE.js +140 -0
  81. package/dist/chunks/{LpNumberFlow-z4WPZcZu.js → LpNumberFlow-Cfyh033Q.js} +8 -28
  82. package/dist/chunks/{LpOtpInput-PbeNJ5In.js → LpOtpInput-CeBPsM7D.js} +2 -1
  83. package/dist/chunks/{LpPagination-Bx-VG4Ag.js → LpPagination-VNCX6pFC.js} +37 -6
  84. package/dist/chunks/{LpPalettePreview-CFav_7co.js → LpPalettePreview-BNB8T_MY.js} +1 -1
  85. package/dist/chunks/{LpPasswordInput-CbnXitAS.js → LpPasswordInput-DTV18FIh.js} +20 -20
  86. package/dist/chunks/{LpPhoneInput-DP69HONS.js → LpPhoneInput-C60tx1tC.js} +12 -7
  87. package/dist/chunks/{LpPie-yLF9-aDR.js → LpPie-CFuV7pZv.js} +158 -47
  88. package/dist/chunks/LpPipeline-D81yh_NX.js +329 -0
  89. package/dist/chunks/{LpPopover-DVnkHaOu.js → LpPopover-BEIcqb9p.js} +8 -3
  90. package/dist/chunks/{LpProgress-CA86wxXu.js → LpProgress-CE-m5OpD.js} +23 -63
  91. package/dist/chunks/LpQuota-2Sw_gqcJ.js +162 -0
  92. package/dist/chunks/{LpRadioGroup-8S5hf8lE.js → LpRadioGroup-CGBr5nIp.js} +1 -1
  93. package/dist/chunks/{LpRangeCalendar-ByQi-WUz.js → LpRangeCalendar-c5qj7YcC.js} +1 -1
  94. package/dist/chunks/{LpRangeSlider-C1yF9-nP.js → LpRangeSlider-Dv6lNvHY.js} +6 -2
  95. package/dist/chunks/LpRelativeTime-CKzVqAo9.js +73 -0
  96. package/dist/chunks/LpRepeater-D0VjmD6y.js +140 -0
  97. package/dist/chunks/LpRevealOnScroll-DcQjexLy.js +76 -0
  98. package/dist/chunks/LpScramble-TDO5Kdou.js +85 -0
  99. package/dist/chunks/LpSecretField-DMfdJ1cQ.js +307 -0
  100. package/dist/chunks/{LpSection-BmRXe6ZP.js → LpSection-BW4xJ-Li.js} +1 -1
  101. package/dist/chunks/{LpSegmented-CW3bFHM4.js → LpSegmented-BO99Sr4m.js} +11 -14
  102. package/dist/chunks/{LpSelect-BCyDYoih.js → LpSelect-B4f_yRi5.js} +93 -108
  103. package/dist/chunks/LpShaderBackdrop-Bote0iuy.js +332 -0
  104. package/dist/chunks/LpShinyText-DX2ajtWq.js +48 -0
  105. package/dist/chunks/{LpSidebar-DfIiS-lB.js → LpSidebar-D-M0Y_7U.js} +5 -3
  106. package/dist/chunks/{LpSidebarNav-C5FDNI0t.js → LpSidebarNav-DF-TYxOV.js} +3 -3
  107. package/dist/chunks/{LpSlider-Cuzmrd7p.js → LpSlider-DuoRpOrH.js} +6 -2
  108. package/dist/chunks/{LpSparkline-DXT4KrSi.js → LpSparkline-CExIRDb3.js} +32 -27
  109. package/dist/chunks/LpSpotlight-4F3NeUMY.js +41 -0
  110. package/dist/chunks/{LpStat-iBMF5QNk.js → LpStat-B2ix1Q7t.js} +38 -35
  111. package/dist/chunks/LpStatus-C7kx5PKE.js +86 -0
  112. package/dist/chunks/LpStepMark-DK-5BKAt.js +101 -0
  113. package/dist/chunks/LpStepper-DRFfdJaq.js +76 -0
  114. package/dist/chunks/{LpSwap-D82jiecV.js → LpSwap-DzE6M3Mg.js} +1 -1
  115. package/dist/chunks/LpSwitch-DrzKrZZV.js +112 -0
  116. package/dist/chunks/{LpTableFilter-CuIbgdW0.js → LpTableFilter-DyvHGbOk.js} +3 -2
  117. package/dist/chunks/{LpTableOfContents-C_4VBktT.js → LpTableOfContents-rYvo8z5T.js} +34 -21
  118. package/dist/chunks/{LpTagsInput-DiXrpYeE.js → LpTagsInput-DgpBFRV2.js} +68 -71
  119. package/dist/chunks/LpTextReveal-CtAnOUkp.js +140 -0
  120. package/dist/chunks/{LpTextarea-xoQd5Lnp.js → LpTextarea-DiWjeVoJ.js} +12 -11
  121. package/dist/chunks/{LpThemeProvider-CQ2jC9TA.js → LpThemeProvider-DcbfOxsU.js} +1 -1
  122. package/dist/chunks/LpThemeStudio-DguwHdGt.js +416 -0
  123. package/dist/chunks/LpThemeStudioSection-BwhqYDLf.js +20 -0
  124. package/dist/chunks/LpThemeSwitcher-D5uz0MhK.js +278 -0
  125. package/dist/chunks/{LpTimeField-MFgAsNc5.js → LpTimeField-BFQVf_PW.js} +13 -5
  126. package/dist/chunks/{LpToaster-C4zE9zB7.js → LpToaster-Wv9ksj4q.js} +49 -82
  127. package/dist/chunks/{LpTooltip-suFCM34F.js → LpTooltip-Cz8SQwRt.js} +8 -3
  128. package/dist/chunks/{LpTopologyCanvas-6ozNrQKh.js → LpTopologyCanvas-ZhKthfgz.js} +1 -1
  129. package/dist/chunks/{LpTour-BUp3Jt2e.js → LpTour-NfRJNEIP.js} +24 -18
  130. package/dist/chunks/LpTruncate-D_5Pfv5B.js +112 -0
  131. package/dist/chunks/LpTypewriter-BCL_a6wE.js +159 -0
  132. package/dist/chunks/{LpUptimeBar-B6kHw4Cj.js → LpUptimeBar-DWegV2p6.js} +9 -8
  133. package/dist/chunks/{LpVideoBackdrop-qWRYBOTQ.js → LpVideoBackdrop-DS1wGv-X.js} +7 -8
  134. package/dist/chunks/{MenuTitle-obgek0B7.js → MenuTitle-BjQZX8tQ.js} +1 -1
  135. package/dist/chunks/OptionContent-CmYUUeWj.js +40 -0
  136. package/dist/chunks/PickerField-CHRS1h7K.js +116 -0
  137. package/dist/chunks/RevealToggle-C-KzaQGJ.js +65 -0
  138. package/dist/chunks/StepConnector-37OgEOXA.js +41 -0
  139. package/dist/chunks/TourCard-BXuVHsfn.js +123 -0
  140. package/dist/chunks/backdrop-Dkf2vM81.js +59 -0
  141. package/dist/chunks/{icons-DVhZ_plB.js → icons-4IywzkHk.js} +1 -1
  142. package/dist/chunks/{useTheme-2qHG8NEU.js → useTheme-BOV_-AiY.js} +9 -65
  143. package/dist/component-names.d.ts +1 -1
  144. package/dist/components/AttentionDot.vue.d.ts +9 -0
  145. package/dist/components/AttentionDot.vue.js +4 -0
  146. package/dist/components/ContextMenuItems.vue.js +1 -1
  147. package/dist/components/DropzoneLinkField.vue.js +1 -1
  148. package/dist/components/FieldWrapper.vue.d.ts +25 -0
  149. package/dist/components/FieldWrapper.vue.js +4 -0
  150. package/dist/components/LayoutCanvas.vue.js +1 -1
  151. package/dist/components/LayoutNode.vue.d.ts +4 -4
  152. package/dist/components/LayoutNode.vue.js +1 -1
  153. package/dist/components/LegendSwatch.vue.d.ts +6 -0
  154. package/dist/components/LegendSwatch.vue.js +4 -0
  155. package/dist/components/LoaderMark.vue.d.ts +12 -0
  156. package/dist/components/LoaderMark.vue.js +4 -0
  157. package/dist/components/LpActionBar.vue.js +1 -1
  158. package/dist/components/LpActivityLine.vue.d.ts +58 -0
  159. package/dist/components/LpActivityLine.vue.js +4 -0
  160. package/dist/components/LpAddressInput.vue.js +1 -1
  161. package/dist/components/LpAlert.vue.d.ts +2 -2
  162. package/dist/components/LpAlert.vue.js +1 -1
  163. package/dist/components/LpAppShell.vue.d.ts +8 -7
  164. package/dist/components/LpAppShell.vue.js +1 -1
  165. package/dist/components/LpAutocomplete.vue.js +1 -1
  166. package/dist/components/LpAvatar.vue.d.ts +16 -0
  167. package/dist/components/LpAvatar.vue.js +1 -1
  168. package/dist/components/LpBadge.vue.d.ts +19 -5
  169. package/dist/components/LpBadge.vue.js +1 -1
  170. package/dist/components/LpBreadcrumbs.vue.js +1 -1
  171. package/dist/components/LpButton.vue.d.ts +2 -2
  172. package/dist/components/LpButton.vue.js +1 -1
  173. package/dist/components/LpCalendar.vue.js +1 -1
  174. package/dist/components/LpCard.vue.d.ts +24 -0
  175. package/dist/components/LpCard.vue.js +1 -1
  176. package/dist/components/LpChart.vue.d.ts +10 -0
  177. package/dist/components/LpChart.vue.js +122 -142
  178. package/dist/components/LpCheckbox.vue.d.ts +2 -2
  179. package/dist/components/LpCheckbox.vue.js +1 -1
  180. package/dist/components/LpCodeBlock.vue.js +1 -1
  181. package/dist/components/LpCodeDisplay.vue.d.ts +89 -0
  182. package/dist/components/LpCodeDisplay.vue.js +4 -0
  183. package/dist/components/LpCollapse.vue.d.ts +58 -0
  184. package/dist/components/LpCollapse.vue.js +4 -0
  185. package/dist/components/LpColorPicker.vue.d.ts +2 -2
  186. package/dist/components/LpColorPicker.vue.js +1 -1
  187. package/dist/components/LpCommandPalette.vue.js +34 -23
  188. package/dist/components/LpConfirmDialog.vue.js +1 -1
  189. package/dist/components/LpConfirmHost.vue.js +1 -1
  190. package/dist/components/LpContextMenu.vue.js +1 -1
  191. package/dist/components/LpCopyButton.vue.d.ts +82 -0
  192. package/dist/components/LpCopyButton.vue.js +4 -0
  193. package/dist/components/LpCountdown.vue.d.ts +100 -0
  194. package/dist/components/LpCountdown.vue.js +4 -0
  195. package/dist/components/LpDataList.vue.d.ts +66 -0
  196. package/dist/components/LpDataList.vue.js +4 -0
  197. package/dist/components/LpDatePicker.vue.d.ts +1 -1
  198. package/dist/components/LpDatePicker.vue.js +1 -1
  199. package/dist/components/LpDateRangePicker.vue.d.ts +1 -1
  200. package/dist/components/LpDateRangePicker.vue.js +1 -1
  201. package/dist/components/LpDisclosure.vue.js +1 -1
  202. package/dist/components/LpDock.vue.d.ts +74 -0
  203. package/dist/components/LpDock.vue.js +204 -0
  204. package/dist/components/LpDrawer.vue.js +1 -1
  205. package/dist/components/LpDropdownMenu.vue.js +1 -1
  206. package/dist/components/LpDropzone.vue.d.ts +8 -1
  207. package/dist/components/LpDropzone.vue.js +36 -15
  208. package/dist/components/LpEditable.vue.d.ts +85 -0
  209. package/dist/components/LpEditable.vue.js +4 -0
  210. package/dist/components/LpEmptyState.vue.js +1 -1
  211. package/dist/components/LpFieldNotice.vue.js +1 -1
  212. package/dist/components/LpFileTree.vue.js +1 -1
  213. package/dist/components/LpFileTreeNode.vue.js +1 -1
  214. package/dist/components/LpFormField.vue.js +1 -1
  215. package/dist/components/LpFrame.vue.d.ts +22 -0
  216. package/dist/components/LpFrame.vue.js +4 -0
  217. package/dist/components/LpGauge.vue.d.ts +116 -0
  218. package/dist/components/LpGauge.vue.js +4 -0
  219. package/dist/components/LpGlowBorder.vue.d.ts +47 -0
  220. package/dist/components/LpGlowBorder.vue.js +4 -0
  221. package/dist/components/LpHintExample.vue.d.ts +2 -2
  222. package/dist/components/LpHintExample.vue.js +1 -1
  223. package/dist/components/LpHintLayer.vue.js +1 -1
  224. package/dist/components/LpHints.vue.js +1 -1
  225. package/dist/components/LpHoverCard.vue.d.ts +60 -0
  226. package/dist/components/LpHoverCard.vue.js +4 -0
  227. package/dist/components/LpIcon.vue.js +1 -1
  228. package/dist/components/LpIdenticon.vue.d.ts +37 -0
  229. package/dist/components/LpIdenticon.vue.js +4 -0
  230. package/dist/components/LpImageEditor.vue.js +13 -19
  231. package/dist/components/LpInfraNode.vue.js +1 -1
  232. package/dist/components/LpInput.vue.d.ts +10 -0
  233. package/dist/components/LpInput.vue.js +1 -1
  234. package/dist/components/LpLightbox.vue.js +1 -1
  235. package/dist/components/LpLoader.vue.d.ts +106 -0
  236. package/dist/components/LpLoader.vue.js +4 -0
  237. package/dist/components/LpLogViewer.vue.js +1 -1
  238. package/dist/components/LpMagnetic.vue.d.ts +28 -0
  239. package/dist/components/LpMagnetic.vue.js +4 -0
  240. package/dist/components/LpMapPicker.vue.js +1 -1
  241. package/dist/components/LpMasonry.vue.d.ts +42 -0
  242. package/dist/components/LpMasonry.vue.js +4 -0
  243. package/dist/components/LpMediaGallery.vue.js +1 -1
  244. package/dist/components/LpModal.vue.js +1 -1
  245. package/dist/components/LpModalNav.vue.js +1 -1
  246. package/dist/components/LpNotificationBell.vue.d.ts +15 -6
  247. package/dist/components/LpNotificationBell.vue.js +1 -1
  248. package/dist/components/LpNumberField.vue.d.ts +57 -0
  249. package/dist/components/LpNumberField.vue.js +1 -1
  250. package/dist/components/LpNumberFlow.vue.js +1 -1
  251. package/dist/components/LpOtpInput.vue.d.ts +12 -4
  252. package/dist/components/LpOtpInput.vue.js +1 -1
  253. package/dist/components/LpPagination.vue.js +1 -1
  254. package/dist/components/LpPaletteFacts.vue.js +1 -1
  255. package/dist/components/LpPaletteHeader.vue.js +2 -2
  256. package/dist/components/LpPalettePreview.vue.js +1 -1
  257. package/dist/components/LpPaletteStats.vue.js +1 -1
  258. package/dist/components/LpPasswordInput.vue.d.ts +12 -1
  259. package/dist/components/LpPasswordInput.vue.js +1 -1
  260. package/dist/components/LpPhoneInput.vue.js +1 -1
  261. package/dist/components/LpPie.vue.d.ts +3 -1
  262. package/dist/components/LpPie.vue.js +1 -1
  263. package/dist/components/LpPipeline.vue.d.ts +91 -0
  264. package/dist/components/LpPipeline.vue.js +4 -0
  265. package/dist/components/LpPopover.vue.d.ts +2 -2
  266. package/dist/components/LpPopover.vue.js +1 -1
  267. package/dist/components/LpProgress.vue.d.ts +11 -4
  268. package/dist/components/LpProgress.vue.js +1 -1
  269. package/dist/components/LpQuota.vue.d.ts +68 -0
  270. package/dist/components/LpQuota.vue.js +4 -0
  271. package/dist/components/LpRadioGroup.vue.js +1 -1
  272. package/dist/components/LpRangeCalendar.vue.js +1 -1
  273. package/dist/components/LpRangeSlider.vue.js +1 -1
  274. package/dist/components/LpRelativeTime.vue.d.ts +41 -0
  275. package/dist/components/LpRelativeTime.vue.js +4 -0
  276. package/dist/components/LpRepeater.vue.d.ts +48 -0
  277. package/dist/components/LpRepeater.vue.js +4 -0
  278. package/dist/components/LpRevealOnScroll.vue.d.ts +67 -0
  279. package/dist/components/LpRevealOnScroll.vue.js +4 -0
  280. package/dist/components/LpRollingText.vue.d.ts +1 -1
  281. package/dist/components/LpScramble.vue.d.ts +55 -0
  282. package/dist/components/LpScramble.vue.js +4 -0
  283. package/dist/components/LpScrollArea.vue.d.ts +1 -1
  284. package/dist/components/LpSecretField.vue.d.ts +108 -0
  285. package/dist/components/LpSecretField.vue.js +4 -0
  286. package/dist/components/LpSection.vue.js +1 -1
  287. package/dist/components/LpSegmented.vue.js +1 -1
  288. package/dist/components/LpSelect.vue.d.ts +2 -0
  289. package/dist/components/LpSelect.vue.js +1 -1
  290. package/dist/components/LpShaderBackdrop.vue.d.ts +39 -0
  291. package/dist/components/LpShaderBackdrop.vue.js +4 -0
  292. package/dist/components/LpShinyText.vue.d.ts +39 -0
  293. package/dist/components/LpShinyText.vue.js +4 -0
  294. package/dist/components/LpShortcutsDialog.vue.js +1 -1
  295. package/dist/components/LpSidebar.vue.js +1 -1
  296. package/dist/components/LpSidebarNav.vue.js +1 -1
  297. package/dist/components/LpSlider.vue.js +1 -1
  298. package/dist/components/LpSparkline.vue.d.ts +4 -3
  299. package/dist/components/LpSparkline.vue.js +1 -1
  300. package/dist/components/LpSpotlight.vue.d.ts +37 -0
  301. package/dist/components/LpSpotlight.vue.js +4 -0
  302. package/dist/components/LpStat.vue.js +1 -1
  303. package/dist/components/LpStatus.vue.d.ts +65 -0
  304. package/dist/components/LpStatus.vue.js +4 -0
  305. package/dist/components/LpStepMark.vue.d.ts +31 -0
  306. package/dist/components/LpStepMark.vue.js +4 -0
  307. package/dist/components/LpStepper.vue.js +1 -1
  308. package/dist/components/LpSwap.vue.js +1 -1
  309. package/dist/components/LpSwitch.vue.d.ts +2 -2
  310. package/dist/components/LpSwitch.vue.js +1 -1
  311. package/dist/components/LpTable.vue.js +104 -120
  312. package/dist/components/LpTableFilter.vue.js +1 -1
  313. package/dist/components/LpTableOfContents.vue.d.ts +6 -1
  314. package/dist/components/LpTableOfContents.vue.js +1 -1
  315. package/dist/components/LpTabs.vue.d.ts +5 -5
  316. package/dist/components/LpTabs.vue.js +25 -33
  317. package/dist/components/LpTagsInput.vue.js +1 -1
  318. package/dist/components/LpTextReveal.vue.d.ts +58 -0
  319. package/dist/components/LpTextReveal.vue.js +4 -0
  320. package/dist/components/LpTextarea.vue.js +1 -1
  321. package/dist/components/LpThemeProvider.vue.js +1 -1
  322. package/dist/components/LpThemeStudio.vue.d.ts +54 -0
  323. package/dist/components/LpThemeStudio.vue.js +4 -0
  324. package/dist/components/LpThemeStudioSection.vue.d.ts +16 -0
  325. package/dist/components/LpThemeStudioSection.vue.js +4 -0
  326. package/dist/components/LpThemeSwitcher.vue.d.ts +32 -1
  327. package/dist/components/LpThemeSwitcher.vue.js +1 -1
  328. package/dist/components/LpTimeField.vue.d.ts +2 -0
  329. package/dist/components/LpTimeField.vue.js +1 -1
  330. package/dist/components/LpToaster.vue.js +1 -1
  331. package/dist/components/LpTooltip.vue.d.ts +2 -2
  332. package/dist/components/LpTooltip.vue.js +1 -1
  333. package/dist/components/LpTopologyCanvas.vue.js +1 -1
  334. package/dist/components/LpTour.vue.js +1 -1
  335. package/dist/components/LpTruncate.vue.d.ts +34 -0
  336. package/dist/components/LpTruncate.vue.js +4 -0
  337. package/dist/components/LpTypewriter.vue.d.ts +61 -0
  338. package/dist/components/LpTypewriter.vue.js +4 -0
  339. package/dist/components/LpUptimeBar.vue.js +1 -1
  340. package/dist/components/LpVideoBackdrop.vue.js +1 -1
  341. package/dist/components/MenuTitle.vue.js +1 -1
  342. package/dist/components/OptionContent.vue.d.ts +7 -0
  343. package/dist/components/OptionContent.vue.js +4 -0
  344. package/dist/components/PickerField.vue.d.ts +43 -0
  345. package/dist/components/PickerField.vue.js +4 -0
  346. package/dist/components/RevealToggle.vue.d.ts +21 -0
  347. package/dist/components/RevealToggle.vue.js +4 -0
  348. package/dist/components/StepConnector.vue.d.ts +19 -0
  349. package/dist/components/StepConnector.vue.js +4 -0
  350. package/dist/components/TourCard.vue.js +1 -1
  351. package/dist/components/badge.d.ts +1 -0
  352. package/dist/components/badge.js +4 -0
  353. package/dist/components/chart.d.ts +5 -1
  354. package/dist/components/chart.js +2 -21
  355. package/dist/components/dateRange.d.ts +11 -0
  356. package/dist/components/dateRange.js +12 -0
  357. package/dist/components/dock.d.ts +19 -0
  358. package/dist/components/dock.js +16 -0
  359. package/dist/components/dropdown.d.ts +10 -1
  360. package/dist/components/dropdown.js +7 -2
  361. package/dist/components/fieldText.d.ts +38 -0
  362. package/dist/components/fieldText.js +53 -0
  363. package/dist/components/fileTree.d.ts +7 -3
  364. package/dist/components/fileTree.js +12 -18
  365. package/dist/components/format.d.ts +41 -0
  366. package/dist/components/format.js +67 -0
  367. package/dist/components/identicon.d.ts +38 -0
  368. package/dist/components/identicon.js +85 -0
  369. package/dist/components/masonry.d.ts +32 -0
  370. package/dist/components/masonry.js +40 -0
  371. package/dist/components/menuWhen.js +1 -1
  372. package/dist/components/meter.d.ts +64 -0
  373. package/dist/components/meter.js +53 -0
  374. package/dist/components/otp.d.ts +1 -1
  375. package/dist/components/otp.js +7 -2
  376. package/dist/components/pipeline.d.ts +55 -0
  377. package/dist/components/pipeline.js +51 -0
  378. package/dist/components/quota.d.ts +57 -0
  379. package/dist/components/quota.js +40 -0
  380. package/dist/components/relativeTime.d.ts +24 -0
  381. package/dist/components/relativeTime.js +56 -0
  382. package/dist/components/reveal.d.ts +18 -0
  383. package/dist/components/reveal.js +32 -0
  384. package/dist/components/scramble.d.ts +68 -0
  385. package/dist/components/scramble.js +58 -0
  386. package/dist/components/shaderBackdrop.d.ts +20 -0
  387. package/dist/components/shaderBackdrop.js +156 -0
  388. package/dist/components/slider.d.ts +5 -0
  389. package/dist/components/slider.js +24 -0
  390. package/dist/components/slotText.d.ts +2 -0
  391. package/dist/components/slotText.js +9 -0
  392. package/dist/components/status.d.ts +14 -0
  393. package/dist/components/status.js +22 -0
  394. package/dist/components/tableFacets.d.ts +8 -0
  395. package/dist/components/tableFacets.js +19 -0
  396. package/dist/components/textSplit.d.ts +17 -0
  397. package/dist/components/textSplit.js +24 -0
  398. package/dist/components/timeSpan.d.ts +78 -0
  399. package/dist/components/timeSpan.js +85 -0
  400. package/dist/components/tone.d.ts +43 -0
  401. package/dist/components/tone.js +82 -0
  402. package/dist/components/tour.js +3 -2
  403. package/dist/components/typewriter.d.ts +36 -0
  404. package/dist/components/typewriter.js +53 -0
  405. package/dist/components/videoBackdrop.js +5 -6
  406. package/dist/composables/easing.d.ts +22 -1
  407. package/dist/composables/easing.js +42 -1
  408. package/dist/composables/pseudoLocale.d.ts +15 -0
  409. package/dist/composables/pseudoLocale.js +96 -0
  410. package/dist/composables/scroll.js +5 -3
  411. package/dist/composables/useClipboard.d.ts +4 -1
  412. package/dist/composables/useClipboard.js +12 -2
  413. package/dist/composables/useField.d.ts +8 -0
  414. package/dist/composables/useField.js +5 -0
  415. package/dist/composables/useForm.js +19 -5
  416. package/dist/composables/useHintSystem.d.ts +4 -0
  417. package/dist/composables/useHintSystem.js +33 -1
  418. package/dist/composables/useHints.js +9 -3
  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 +61 -0
  451. package/dist/icons-all.js +1 -1
  452. package/dist/index.d.ts +98 -1
  453. package/dist/index.js +262 -104
  454. package/dist/theme/define.d.ts +12 -0
  455. package/dist/theme/studio.d.ts +90 -0
  456. package/package.json +5 -2
  457. package/src/component-names.ts +33 -0
  458. package/src/components/AttentionDot.vue +27 -0
  459. package/src/components/FieldWrapper.vue +38 -0
  460. package/src/components/LayoutNode.vue +5 -9
  461. package/src/components/LegendSwatch.vue +15 -0
  462. package/src/components/LoaderMark.vue +90 -0
  463. package/src/components/LpActionBar.vue +12 -20
  464. package/src/components/LpActivityLine.vue +186 -0
  465. package/src/components/LpAlert.vue +54 -24
  466. package/src/components/LpAppShell.vue +7 -11
  467. package/src/components/LpAutocomplete.vue +16 -14
  468. package/src/components/LpAvatar.vue +17 -2
  469. package/src/components/LpBadge.vue +77 -13
  470. package/src/components/LpBreadcrumbs.vue +101 -35
  471. package/src/components/LpButton.vue +15 -3
  472. package/src/components/LpCard.vue +30 -7
  473. package/src/components/LpChart.vue +152 -156
  474. package/src/components/LpCheckbox.vue +10 -4
  475. package/src/components/LpCodeBlock.vue +11 -19
  476. package/src/components/LpCodeDisplay.vue +228 -0
  477. package/src/components/LpCollapse.vue +162 -0
  478. package/src/components/LpColorPicker.vue +10 -1
  479. package/src/components/LpCommandPalette.vue +38 -24
  480. package/src/components/LpContextMenu.vue +10 -1
  481. package/src/components/LpCopyButton.vue +185 -0
  482. package/src/components/LpCountdown.vue +308 -0
  483. package/src/components/LpDataList.vue +154 -0
  484. package/src/components/LpDatePicker.vue +53 -104
  485. package/src/components/LpDateRangePicker.vue +49 -95
  486. package/src/components/LpDisclosure.vue +58 -36
  487. package/src/components/LpDock.vue +274 -0
  488. package/src/components/LpDrawer.vue +10 -1
  489. package/src/components/LpDropdownMenu.vue +10 -1
  490. package/src/components/LpDropzone.vue +34 -13
  491. package/src/components/LpEditable.vue +293 -0
  492. package/src/components/LpFileTree.vue +5 -1
  493. package/src/components/LpFileTreeNode.vue +25 -50
  494. package/src/components/LpFormField.vue +22 -3
  495. package/src/components/LpFrame.vue +200 -0
  496. package/src/components/LpGauge.vue +287 -0
  497. package/src/components/LpGlowBorder.vue +60 -0
  498. package/src/components/LpHintExample.vue +14 -38
  499. package/src/components/LpHintLayer.vue +13 -3
  500. package/src/components/LpHoverCard.vue +175 -0
  501. package/src/components/LpIdenticon.vue +69 -0
  502. package/src/components/LpImageEditor.vue +15 -18
  503. package/src/components/LpInfraNode.vue +27 -16
  504. package/src/components/LpInput.vue +30 -16
  505. package/src/components/LpLightbox.vue +44 -23
  506. package/src/components/LpLoader.vue +145 -0
  507. package/src/components/LpLogViewer.vue +311 -82
  508. package/src/components/LpMagnetic.vue +97 -0
  509. package/src/components/LpMapPicker.vue +26 -28
  510. package/src/components/LpMasonry.vue +247 -0
  511. package/src/components/LpModal.vue +10 -1
  512. package/src/components/LpNotificationBell.vue +33 -49
  513. package/src/components/LpNumberField.vue +79 -14
  514. package/src/components/LpNumberFlow.vue +10 -35
  515. package/src/components/LpOtpInput.vue +7 -2
  516. package/src/components/LpPagination.vue +38 -4
  517. package/src/components/LpPalettePreview.vue +2 -7
  518. package/src/components/LpPasswordInput.vue +16 -14
  519. package/src/components/LpPhoneInput.vue +12 -3
  520. package/src/components/LpPie.vue +197 -36
  521. package/src/components/LpPipeline.vue +366 -0
  522. package/src/components/LpPopover.vue +10 -1
  523. package/src/components/LpProgress.vue +22 -84
  524. package/src/components/LpQuota.vue +197 -0
  525. package/src/components/LpRangeSlider.vue +5 -1
  526. package/src/components/LpRelativeTime.vue +90 -0
  527. package/src/components/LpRepeater.vue +80 -0
  528. package/src/components/LpRevealOnScroll.vue +125 -0
  529. package/src/components/LpScramble.vue +107 -0
  530. package/src/components/LpSecretField.vue +313 -0
  531. package/src/components/LpSegmented.vue +3 -10
  532. package/src/components/LpSelect.vue +78 -64
  533. package/src/components/LpShaderBackdrop.vue +434 -0
  534. package/src/components/LpShinyText.vue +139 -0
  535. package/src/components/LpSidebar.vue +2 -0
  536. package/src/components/LpSlider.vue +5 -1
  537. package/src/components/LpSparkline.vue +55 -37
  538. package/src/components/LpSpotlight.vue +51 -0
  539. package/src/components/LpStat.vue +6 -2
  540. package/src/components/LpStatus.vue +127 -0
  541. package/src/components/LpStepMark.vue +138 -0
  542. package/src/components/LpStepper.vue +37 -43
  543. package/src/components/LpSwap.vue +2 -2
  544. package/src/components/LpSwitch.vue +15 -22
  545. package/src/components/LpTable.vue +47 -63
  546. package/src/components/LpTableFilter.vue +1 -0
  547. package/src/components/LpTableOfContents.vue +53 -29
  548. package/src/components/LpTabs.vue +10 -21
  549. package/src/components/LpTagsInput.vue +53 -37
  550. package/src/components/LpTextReveal.vue +236 -0
  551. package/src/components/LpTextarea.vue +11 -11
  552. package/src/components/LpThemeStudio.vue +216 -0
  553. package/src/components/LpThemeStudioSection.vue +16 -0
  554. package/src/components/LpThemeSwitcher.vue +156 -47
  555. package/src/components/LpTimeField.vue +9 -1
  556. package/src/components/LpToaster.vue +63 -83
  557. package/src/components/LpTooltip.vue +10 -1
  558. package/src/components/LpTour.vue +24 -13
  559. package/src/components/LpTruncate.vue +135 -0
  560. package/src/components/LpTypewriter.vue +236 -0
  561. package/src/components/LpUptimeBar.vue +6 -5
  562. package/src/components/LpVideoBackdrop.vue +15 -13
  563. package/src/components/OptionContent.vue +17 -0
  564. package/src/components/PickerField.vue +58 -0
  565. package/src/components/RevealToggle.vue +51 -0
  566. package/src/components/StepConnector.vue +54 -0
  567. package/src/components/TourCard.vue +29 -16
  568. package/src/components/badge.ts +8 -0
  569. package/src/components/chart.ts +8 -23
  570. package/src/components/dateRange.ts +25 -0
  571. package/src/components/dock.ts +31 -0
  572. package/src/components/dropdown.ts +15 -3
  573. package/src/components/fieldText.ts +95 -0
  574. package/src/components/fileTree.ts +19 -21
  575. package/src/components/format.ts +136 -0
  576. package/src/components/identicon.ts +160 -0
  577. package/src/components/masonry.ts +73 -0
  578. package/src/components/meter.ts +122 -0
  579. package/src/components/otp.ts +14 -3
  580. package/src/components/pipeline.ts +101 -0
  581. package/src/components/quota.ts +111 -0
  582. package/src/components/relativeTime.ts +118 -0
  583. package/src/components/reveal.ts +56 -0
  584. package/src/components/scramble.ts +138 -0
  585. package/src/components/shaderBackdrop.ts +208 -0
  586. package/src/components/slider.ts +30 -0
  587. package/src/components/slotText.ts +13 -0
  588. package/src/components/status.ts +46 -0
  589. package/src/components/tableFacets.ts +25 -0
  590. package/src/components/textSplit.ts +55 -0
  591. package/src/components/timeSpan.ts +183 -0
  592. package/src/components/tone.ts +144 -0
  593. package/src/components/tour.ts +3 -2
  594. package/src/components/typewriter.ts +104 -0
  595. package/src/components/videoBackdrop.ts +7 -6
  596. package/src/composables/easing.ts +66 -1
  597. package/src/composables/pseudoLocale.ts +105 -0
  598. package/src/composables/scroll.ts +6 -3
  599. package/src/composables/useClipboard.ts +25 -3
  600. package/src/composables/useField.ts +12 -0
  601. package/src/composables/useForm.ts +27 -6
  602. package/src/composables/useHintSystem.ts +40 -0
  603. package/src/composables/useHints.ts +14 -3
  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 +93 -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,228 @@
1
+ <script lang="ts">
2
+ export default { inheritAttrs: false }
3
+
4
+ export interface CodeDisplayLabels extends Record<string, string> {
5
+ show: string
6
+ hide: string
7
+ hidden: string
8
+ expiresIn: string
9
+ expired: string
10
+ saved: string
11
+ }
12
+ </script>
13
+
14
+ <script setup lang="ts">
15
+ /*
16
+ * A short code a person reads off the screen, types somewhere else or writes
17
+ * down: a one-time sign-in code, a pairing code for a device, a recovery key,
18
+ * a licence key. Not a field (that is LpOtpInput) and not source code (that is
19
+ * LpCodeBlock): it is shown to be transcribed.
20
+ *
21
+ * <LpCodeDisplay code="482913" :expires-at="expires" />
22
+ * <LpCodeDisplay code="K7QF-29XM-PL4D-8WNA" masked ack v-model:saved="saved" />
23
+ *
24
+ * What makes a code easy to transcribe: big monospace characters, every one
25
+ * the same width, broken into groups of 3–4 the eye can hold (`groupCode`).
26
+ * The separators are drawn, not text — selecting or copying the code gives
27
+ * the characters alone, which is what the place it is pasted into expects.
28
+ *
29
+ * A new code (regenerated, refreshed) turns over character by character
30
+ * rather than being swapped, so it is plain that it changed; revealing a
31
+ * masked code turns the dots over the same way.
32
+ *
33
+ * `expiresAt` adds a countdown with a draining bar (LpCountdown); at zero the code dims and
34
+ * can no longer be copied, and `expired` fires so the app can fetch a new one.
35
+ * `ack` adds "I've saved this", for codes shown once (recovery keys) where the
36
+ * app should not let the person continue before they have kept it.
37
+ */
38
+ import { computed, ref, watch } from "vue"
39
+ import { useLabels } from "../composables/useLpConfig"
40
+ import { useMergedAttrs } from "../composables/useMergedClass"
41
+ import { useNow } from "../composables/useNow"
42
+ import LpCheckbox from "./LpCheckbox.vue"
43
+ import LpCopyButton from "./LpCopyButton.vue"
44
+ import LpCountdown from "./LpCountdown.vue"
45
+ import LpIcon from "./LpIcon.vue"
46
+ import LpRollingText from "./LpRollingText.vue"
47
+ import RevealToggle from "./RevealToggle.vue"
48
+ import { groupCode } from "./fieldText"
49
+ import { ceilToSecond, formatTime, msToNextSecond, toEpoch } from "./timeSpan"
50
+
51
+ const props = withDefaults(
52
+ defineProps<{
53
+ code: string
54
+ /** One size for every group, or exact sizes in order. Unset picks 3s or 4s by length. */
55
+ groups?: number | number[]
56
+ /** Drawn between groups: `""` (a gap, the default), `"-"`, `"·"`, `" "`. */
57
+ separator?: string
58
+ /** Copy with separators (`grouped`) or the characters alone (`raw`, default). */
59
+ copyAs?: "raw" | "grouped"
60
+ /** Hidden until revealed (v-model:revealed). Copy still works while hidden. */
61
+ masked?: boolean
62
+ copyable?: boolean
63
+ /** When the code stops working; shows a countdown. */
64
+ expiresAt?: Date | number | string
65
+ /**
66
+ * When it was issued, for the countdown bar's full length. Unset, the bar
67
+ * starts full at the moment it first appears.
68
+ */
69
+ issuedAt?: Date | number | string
70
+ /** Add the "I've saved this" confirmation (v-model:saved). */
71
+ ack?: boolean
72
+ size?: "sm" | "md" | "lg"
73
+ labels?: Partial<CodeDisplayLabels>
74
+ }>(),
75
+ { separator: "", copyAs: "raw", copyable: true, size: "md" },
76
+ )
77
+
78
+ const emit = defineEmits<{
79
+ (e: "expired"): void
80
+ (e: "copied", text: string): void
81
+ }>()
82
+
83
+ const revealed = defineModel<boolean>("revealed", { default: false })
84
+ const saved = defineModel<boolean>("saved", { default: false })
85
+
86
+ const text = useLabels<CodeDisplayLabels>(
87
+ "codeDisplay",
88
+ {
89
+ show: "Show code",
90
+ hide: "Hide code",
91
+ hidden: "Code hidden",
92
+ expiresIn: "Expires in",
93
+ expired: "Expired",
94
+ saved: "I've saved this code",
95
+ },
96
+ () => props.labels,
97
+ )
98
+
99
+ const parts = computed(() => groupCode(props.code, props.groups))
100
+ const hidden = computed(() => props.masked && !revealed.value)
101
+ const copyText = computed(() =>
102
+ props.copyAs === "grouped" ? parts.value.join(props.separator || " ") : parts.value.join(""),
103
+ )
104
+ // Spelled out with spaces so a screen reader reads characters, not a "word".
105
+ const spoken = computed(() => parts.value.map((g) => Array.from(g).join(" ")).join(", "))
106
+
107
+ // ── countdown ────────────────────────────────────────────────
108
+ // The default expiry row IS LpCountdown. The clock here only feeds the slot's
109
+ // props and the `expired` event, which must work when the slot is replaced
110
+ // too; useNow wakes on the second boundary and sleeps in a hidden tab.
111
+ const end = computed(() => {
112
+ const at = toEpoch(props.expiresAt)
113
+ return Number.isNaN(at) ? undefined : at
114
+ })
115
+ // Without `issuedAt` the bar starts full the moment the code first appears.
116
+ const start = ref(Date.now())
117
+ watch(
118
+ [end, () => props.issuedAt],
119
+ () => {
120
+ const issued = toEpoch(props.issuedAt)
121
+ start.value = Number.isNaN(issued) ? Date.now() : issued
122
+ },
123
+ { immediate: true },
124
+ )
125
+ const now = useNow(() => end.value !== undefined && end.value > Date.now(), {
126
+ nextIn: (at) => msToNextSecond((end.value ?? at) - at),
127
+ restartOn: end,
128
+ })
129
+
130
+ const remaining = computed(() => (end.value === undefined ? undefined : Math.max(0, end.value - now.value)))
131
+ const expired = computed(() => remaining.value === 0)
132
+ const fraction = computed(() => {
133
+ if (end.value === undefined) return 1
134
+ const total = end.value - start.value
135
+ return total > 0 ? Math.min(1, (remaining.value ?? 0) / total) : 0
136
+ })
137
+ // The last fifth of the wait is urgent, as the bar has always turned there.
138
+ const urgentAt = computed(() => (end.value === undefined ? undefined : Math.max(0, end.value - start.value) * 0.2 / 1000))
139
+ watch(expired, (out) => out && emit("expired"))
140
+
141
+ const SIZE = {
142
+ sm: { text: "text-lg", gap: "gap-2", icon: 14 },
143
+ md: { text: "text-2xl", gap: "gap-3", icon: 16 },
144
+ lg: { text: "text-4xl", gap: "gap-4", icon: 18 },
145
+ } as const
146
+
147
+ const { class: rootClass, attrs: rest } = useMergedAttrs(() => "inline-flex max-w-full flex-col gap-3")
148
+ </script>
149
+
150
+ <template>
151
+ <div :class="rootClass" v-bind="rest">
152
+ <div class="flex flex-wrap items-center gap-x-2 gap-y-1">
153
+ <div
154
+ class="flex flex-wrap items-center font-mono font-semibold tracking-normal text-ink tabular-nums transition-opacity duration-(--duration-medium)"
155
+ :class="[SIZE[size].text, SIZE[size].gap, expired ? 'opacity-35' : '']"
156
+ >
157
+ <span class="sr-only">{{ hidden ? text.hidden : spoken }}</span>
158
+ <template v-for="(group, g) in parts" :key="g">
159
+ <span
160
+ v-if="g > 0 && separator"
161
+ aria-hidden="true"
162
+ class="-mx-1 select-none text-muted/70"
163
+ >{{ separator }}</span>
164
+ <span aria-hidden="true" class="inline-flex">
165
+ <!-- One cell per character, each exactly 1ch, so dots and
166
+ characters take the same room and nothing shifts on reveal. -->
167
+ <LpRollingText
168
+ v-for="(char, c) in Array.from(group)"
169
+ :key="c"
170
+ :value="hidden ? '•' : char"
171
+ mode="flip"
172
+ :duration="260 + (g * 4 + c) * 28"
173
+ class="w-[1ch]"
174
+ />
175
+ </span>
176
+ </template>
177
+ </div>
178
+
179
+ <div class="flex items-center gap-0.5">
180
+ <RevealToggle
181
+ v-if="masked"
182
+ v-model="revealed"
183
+ :icon-size="SIZE[size].icon"
184
+ :show-label="text.show"
185
+ :hide-label="text.hide"
186
+ />
187
+ <LpCopyButton
188
+ v-if="copyable"
189
+ :value="copyText"
190
+ size="sm"
191
+ class="text-muted hover:text-ink"
192
+ :disabled="expired"
193
+ @copied="(t: string) => emit('copied', t)"
194
+ />
195
+ </div>
196
+ </div>
197
+
198
+ <slot
199
+ v-if="remaining !== undefined"
200
+ name="expiry"
201
+ :remaining="remaining"
202
+ :formatted="formatTime(ceilToSecond(remaining), 'clock')"
203
+ :expired="expired"
204
+ :fraction="fraction"
205
+ >
206
+ <!-- LpCountdown lays its digits and its bar out itself; `contents` lets
207
+ them join this row instead, so the label sits beside the digits and
208
+ the bar wraps onto a line of its own under all three. -->
209
+ <div class="flex max-w-64 flex-wrap items-center gap-1.5 text-xs" :class="expired ? 'text-danger' : 'text-muted'">
210
+ <LpIcon :name="expired ? 'lucide:timer-off' : 'lucide:timer'" :size="12" />
211
+ <LpRollingText :value="expired ? text.expired : text.expiresIn" align="start" />
212
+ <LpCountdown
213
+ :to="end"
214
+ :from="start"
215
+ progress="bar"
216
+ :urgent-at="urgentAt"
217
+ :labels="{ done: text.expired }"
218
+ class="contents text-ink"
219
+ >
220
+ <!-- Nothing in place of 0:00: the label already says it is over. -->
221
+ <template #done />
222
+ </LpCountdown>
223
+ </div>
224
+ </slot>
225
+
226
+ <LpCheckbox v-if="ack" v-model="saved" :label="text.saved" />
227
+ </div>
228
+ </template>
@@ -0,0 +1,162 @@
1
+ <script lang="ts">
2
+ // Attributes go onto the collapsing box, not onto the Transition around it.
3
+ export default { inheritAttrs: false }
4
+ </script>
5
+
6
+ <script setup lang="ts">
7
+ /*
8
+ * Shows and hides content by folding it open and shut: the box grows from
9
+ * nothing to the content's own height (or width), and back. Anything under it
10
+ * glides instead of jumping.
11
+ *
12
+ * <LpButton @click="advanced = !advanced">Advanced</LpButton>
13
+ * <LpCollapse v-model:open="advanced">
14
+ * <AdvancedOptions />
15
+ * </LpCollapse>
16
+ *
17
+ * It is the bare motion with no trigger or chrome, for where the thing that
18
+ * opens it is somewhere else: a switch that reveals dependent fields, a
19
+ * "show details" link, a row that expands in a table, a toolbar section that
20
+ * slides out sideways (`axis="width"`). LpDisclosure is the ready-made header
21
+ * plus body; LpShift eases a box whose content CHANGES; this one eases
22
+ * content that comes and goes.
23
+ *
24
+ * Toggling mid-way reverses from where the box is, rather than snapping to an
25
+ * end first. Padding and margins belong on the content inside, not on the
26
+ * collapse itself: the box is measured and clipped, and its own padding would
27
+ * still show when it is folded to zero.
28
+ */
29
+ import { ref, watch } from "vue"
30
+ import { durationToken, easingToken, prefersReducedMotion } from "../composables/easing"
31
+
32
+ const props = withDefaults(
33
+ defineProps<{
34
+ /** Which dimension folds: `height` for a section, `width` for a side panel or a toolbar group, `both` for a corner pop-out. */
35
+ axis?: "height" | "width" | "both"
36
+ /** Fade the content along with the fold, so it does not show sliced while the box is small. */
37
+ fade?: boolean
38
+ /**
39
+ * Keep the content in the DOM while closed (hidden), so its state survives:
40
+ * a half-filled form, a scroll position, a playing preview. Off, it is
41
+ * unmounted once folded away, like `v-if`.
42
+ */
43
+ keepMounted?: boolean
44
+ /** With `keepMounted`, do not mount the content until it is first opened: an expensive body costs nothing until asked for. */
45
+ lazy?: boolean
46
+ /** Length of the fold in ms. Defaults to the kit's `--duration-medium`. */
47
+ duration?: number
48
+ }>(),
49
+ { axis: "height", fade: true, keepMounted: false, lazy: false },
50
+ )
51
+
52
+ const emit = defineEmits<{
53
+ /** The fold has finished opening. */
54
+ (e: "opened"): void
55
+ /** The fold has finished closing (and the content is unmounted, unless kept). */
56
+ (e: "closed"): void
57
+ }>()
58
+
59
+ const open = defineModel<boolean>("open", { default: false })
60
+
61
+ /*
62
+ * Mounted is separate from open: a closing box has to stay in the DOM until
63
+ * its fold has played, and a kept one stays after that. Rendering it with
64
+ * v-show under that v-if means a reopen during the close lands on the SAME
65
+ * element, so the fold reverses from where it is instead of starting a new
66
+ * box from zero beside the old one.
67
+ */
68
+ let unmounting = false
69
+ const present = ref(open.value || (props.keepMounted && !props.lazy))
70
+ watch(open, (value) => {
71
+ if (!value) return
72
+ unmounting = false
73
+ present.value = true
74
+ })
75
+
76
+ const running = new WeakMap<Element, Animation>()
77
+
78
+ type Size = { height: number; width: number; opacity: number }
79
+
80
+ function current(el: HTMLElement): Size {
81
+ const rect = el.getBoundingClientRect()
82
+ return { height: rect.height, width: rect.width, opacity: Number(getComputedStyle(el).opacity) }
83
+ }
84
+
85
+ function natural(el: HTMLElement): Size {
86
+ return { height: el.scrollHeight, width: el.scrollWidth, opacity: 1 }
87
+ }
88
+
89
+ const ZERO: Size = { height: 0, width: 0, opacity: 0 }
90
+
91
+ function frame(size: Size): Keyframe {
92
+ const out: Keyframe = {}
93
+ if (props.axis !== "width") out.height = `${size.height}px`
94
+ if (props.axis !== "height") out.width = `${size.width}px`
95
+ if (props.fade) out.opacity = size.opacity
96
+ return out
97
+ }
98
+
99
+ function fold(el: Element, opening: boolean, done: () => void) {
100
+ const box = el as HTMLElement
101
+ const previous = running.get(box)
102
+ if (prefersReducedMotion() || typeof box.animate !== "function") {
103
+ previous?.cancel()
104
+ done()
105
+ return
106
+ }
107
+ // Mid-fold, start from where the box is now; at rest, from the closed or open end.
108
+ const from = previous ? current(box) : opening ? ZERO : natural(box)
109
+ previous?.cancel()
110
+ const to = opening ? natural(box) : ZERO
111
+ box.style.overflow = "hidden"
112
+ const animation = box.animate([frame(from), frame(to)], {
113
+ duration: props.duration ?? durationToken("duration-medium"),
114
+ easing: easingToken("ease-emphasized"),
115
+ // Closing holds the folded frame until Vue hides the element, so it never flashes back open.
116
+ fill: opening ? "none" : "forwards",
117
+ })
118
+ running.set(box, animation)
119
+ animation.onfinish = () => {
120
+ if (running.get(box) !== animation) return
121
+ running.delete(box)
122
+ box.style.overflow = ""
123
+ done()
124
+ if (!opening) animation.cancel()
125
+ }
126
+ animation.oncancel = () => {
127
+ if (running.get(box) === animation) running.delete(box)
128
+ }
129
+ }
130
+
131
+ function onEnter(el: Element, done: () => void) {
132
+ fold(el, true, done)
133
+ }
134
+ /*
135
+ * Unmounting after the fold is a second leave for the Transition, of an
136
+ * element already hidden: it passes straight through, and is not reported as
137
+ * a second close.
138
+ */
139
+ function onLeave(el: Element, done: () => void) {
140
+ if (unmounting) done()
141
+ else fold(el, false, done)
142
+ }
143
+ function onAfterLeave() {
144
+ if (unmounting) {
145
+ unmounting = false
146
+ return
147
+ }
148
+ if (!props.keepMounted && !open.value) {
149
+ unmounting = true
150
+ present.value = false
151
+ }
152
+ emit("closed")
153
+ }
154
+ </script>
155
+
156
+ <template>
157
+ <Transition :css="false" @enter="onEnter" @leave="onLeave" @after-enter="emit('opened')" @after-leave="onAfterLeave">
158
+ <div v-if="present" v-show="open" v-bind="$attrs">
159
+ <slot />
160
+ </div>
161
+ </Transition>
162
+ </template>
@@ -57,6 +57,7 @@ import { POPOVER_PANEL } from "./dropdown"
57
57
  import LpContextMenu, { type ContextMenuItemDef } from "./LpContextMenu.vue"
58
58
  import LpIcon from "./LpIcon.vue"
59
59
  import LpRollingText from "./LpRollingText.vue"
60
+ import { useOutsideGuard, usePortalTarget } from "../composables/useView"
60
61
 
61
62
  /**
62
63
  * Every user-facing string the picker renders on its own — the menu items, the
@@ -614,6 +615,12 @@ const field = useFieldControl(() => ({
614
615
  }))
615
616
 
616
617
  defineExpose({ open })
618
+
619
+ // Overlays open in the window this component renders in (an LpFrame's, inside one).
620
+ const portalTo = usePortalTarget()
621
+ // What happens in another document (the page around a frame, or a frame in
622
+ // the page) is not "outside" for this layer.
623
+ const guardOutside = useOutsideGuard()
617
624
  </script>
618
625
 
619
626
  <template>
@@ -669,8 +676,10 @@ defineExpose({ open })
669
676
  </LpContextMenu>
670
677
  </PopoverAnchor>
671
678
 
672
- <PopoverPortal>
679
+ <PopoverPortal :to="portalTo">
673
680
  <PopoverContent
681
+ @interact-outside="guardOutside"
682
+ @escape-key-down="guardOutside"
674
683
  :collision-padding="8"
675
684
  :side="side"
676
685
  :align="align"
@@ -39,8 +39,10 @@ import {
39
39
  import { computed, nextTick, onBeforeUnmount, ref, shallowRef, useId, watch } from "vue"
40
40
  import LpAvatar from "./LpAvatar.vue"
41
41
  import LpIcon from "./LpIcon.vue"
42
+ import LpLoader from "./LpLoader.vue"
42
43
  import LpScrollArea from "./LpScrollArea.vue"
43
44
  import MenuShortcut from "./MenuShortcut.vue"
45
+ import { staggerDelay } from "./reveal"
44
46
  import { usePersisted } from "../composables/usePersisted"
45
47
  import { useAsyncTask } from "../composables/useAsyncTask"
46
48
  import { useGlass } from "../composables/useGlass"
@@ -72,6 +74,7 @@ import {
72
74
  type RecentEntry,
73
75
  type RecentItem,
74
76
  } from "./commandPalette"
77
+ import { useOutsideGuard, usePortalTarget } from "../composables/useView"
75
78
 
76
79
  /**
77
80
  * A picture in a row's icon slot: an avatar, a project logo, a world's
@@ -910,11 +913,17 @@ function paneHighlight(text: string): HighlightPart[] {
910
913
  const paneQuery = computed(() => parsePaletteQuery(query.value.trim()))
911
914
 
912
915
  // What the pane draws: the last row it showed, kept while the pane slides out
913
- // so it leaves with its content instead of emptying first.
916
+ // so it leaves with its content instead of emptying first. Immediate: the
917
+ // first row is already highlighted when the palette opens, and the pane
918
+ // opened beside it empty until the highlight moved.
914
919
  const paneBody = shallowRef<Command | undefined>()
915
- watch(paneCommand, (command) => {
916
- if (command) paneBody.value = command
917
- })
920
+ watch(
921
+ paneCommand,
922
+ (command) => {
923
+ if (command) paneBody.value = command
924
+ },
925
+ { immediate: true },
926
+ )
918
927
 
919
928
  /*
920
929
  * The text in paragraphs, so they can arrive one after another. A blank line
@@ -939,9 +948,8 @@ const paneDescription = computed(() => {
939
948
  return body.startsWith(description) ? undefined : description
940
949
  })
941
950
 
942
- /** Stagger between paragraphs, capped so a long section does not trickle in. */
943
- const STAGGER_MS = 45
944
- const STAGGER_MAX = 10
951
+ /** Stagger between paragraphs (after the description), capped so a long section does not trickle in. */
952
+ const paraDelay = (index: number) => `${staggerDelay(index + 1, 0, 45, 10)}ms`
945
953
 
946
954
  /*
947
955
  * A preview is opened for the match, so the pane lands on it: the first
@@ -1216,17 +1224,25 @@ useHotkeys(() =>
1216
1224
  ]
1217
1225
  : [],
1218
1226
  )
1227
+
1228
+ // Overlays open in the window this component renders in (an LpFrame's, inside one).
1229
+ const portalTo = usePortalTarget()
1230
+ // What happens in another document (the page around a frame, or a frame in
1231
+ // the page) is not "outside" for this layer.
1232
+ const guardOutside = useOutsideGuard()
1219
1233
  </script>
1220
1234
 
1221
1235
  <template>
1222
1236
  <DialogRoot :open="open" @update:open="(v) => emit('update:open', v)">
1223
- <DialogPortal>
1237
+ <DialogPortal :to="portalTo">
1224
1238
  <DialogOverlay
1225
1239
  :class="{ 'lp-scrim--light': frosted, 'lp-scrim--nested': layer.nested, 'lp-scrim--covered': layer.covered }"
1226
1240
  class="lp-scrim fixed inset-0 data-[state=open]:animate-[fade-in_150ms_ease] data-[state=closed]:animate-[fade-out_130ms_ease]"
1227
1241
  :style="{ zIndex: layer.scrim }"
1228
1242
  />
1229
1243
  <DialogContent
1244
+ @interact-outside="guardOutside"
1245
+ @escape-key-down="guardOutside"
1230
1246
  ref="contentRef"
1231
1247
  class="lp-cmd-dialog fixed left-1/2 top-[12vh] flex max-h-[76vh] -translate-x-1/2 flex-col overflow-hidden rounded-card border border-line shadow-panel outline-none data-[state=open]:animate-[pop-in_160ms_var(--ease-emphasized)] data-[state=closed]:animate-[pop-out_130ms_ease]"
1232
1248
  :class="[frosted ? (layer.nested ? 'lp-glass-overlay lp-glass-overlay--nested' : 'lp-glass-overlay') : 'bg-surface-raised', previewPane && 'lp-cmd-split']"
@@ -1248,7 +1264,15 @@ useHotkeys(() =>
1248
1264
  :size="18"
1249
1265
  class="shrink-0 text-muted"
1250
1266
  />
1251
- <LpIcon v-else name="lucide:loader-circle" :size="18" class="shrink-0 animate-spin text-muted" />
1267
+ <!-- At once, since it takes the search icon's place. It is the only
1268
+ thing that tells a screen reader a search went out, so it speaks. -->
1269
+ <LpLoader
1270
+ v-else
1271
+ size="inline"
1272
+ :delay="0"
1273
+ :labels="{ loading: text.searching }"
1274
+ class="shrink-0 text-[18px] text-muted"
1275
+ />
1252
1276
 
1253
1277
  <button
1254
1278
  v-for="(step, i) in trail"
@@ -1446,7 +1470,7 @@ useHotkeys(() =>
1446
1470
  v-for="(para, i) in paragraphs"
1447
1471
  :key="i"
1448
1472
  class="lp-cmd-para mt-3 whitespace-pre-line text-sm leading-relaxed text-ink/90"
1449
- :style="{ animationDelay: `${Math.min(i + 1, STAGGER_MAX) * STAGGER_MS}ms` }"
1473
+ :style="{ animationDelay: paraDelay(i) }"
1450
1474
  >
1451
1475
  <template v-for="(p, pi) in highlight(para, paneBody.highlight)" :key="`p${pi}`">
1452
1476
  <mark v-if="p.hit" class="rounded-xs bg-brand/25 text-ink">{{ p.text }}</mark>
@@ -1548,13 +1572,8 @@ useHotkeys(() =>
1548
1572
  transform: translateX(40%);
1549
1573
  }
1550
1574
  .lp-cmd-para {
1551
- animation: lp-cmd-para-in 260ms ease-out both;
1552
- }
1553
- @keyframes lp-cmd-para-in {
1554
- from {
1555
- opacity: 0;
1556
- transform: translateY(4px);
1557
- }
1575
+ --rise: 4px;
1576
+ animation: rise-in 260ms ease-out both;
1558
1577
  }
1559
1578
  @media (prefers-reduced-motion: reduce) {
1560
1579
  .lp-cmd-split,
@@ -1573,13 +1592,8 @@ useHotkeys(() =>
1573
1592
  }
1574
1593
  /* Each result eases in; honours reduced motion. */
1575
1594
  .lp-cmd-item {
1576
- animation: lp-cmd-in 140ms ease-out both;
1577
- }
1578
- @keyframes lp-cmd-in {
1579
- from {
1580
- opacity: 0;
1581
- transform: translateY(3px);
1582
- }
1595
+ --rise: 3px;
1596
+ animation: rise-in 140ms ease-out both;
1583
1597
  }
1584
1598
  @media (prefers-reduced-motion: reduce) {
1585
1599
  .lp-cmd-item {
@@ -14,6 +14,7 @@ import { HINT_SIGNALS, noteContextTarget } from "../composables/useHintSystem"
14
14
  import ContextMenuItems from "./ContextMenuItems.vue"
15
15
  import MenuTitle from "./MenuTitle.vue"
16
16
  import { POPOVER_PANEL } from "./dropdown"
17
+ import { useOutsideGuard, usePortalTarget } from "../composables/useView"
17
18
 
18
19
  export interface ContextMenuItemDef {
19
20
  label: string
@@ -138,6 +139,12 @@ function returnFocus(event: Event) {
138
139
  saved.el.focus()
139
140
  if (saved.el.value === saved.value) saved.el.setSelectionRange(saved.start, saved.end)
140
141
  }
142
+
143
+ // Overlays open in the window this component renders in (an LpFrame's, inside one).
144
+ const portalTo = usePortalTarget()
145
+ // What happens in another document (the page around a frame, or a frame in
146
+ // the page) is not "outside" for this layer.
147
+ const guardOutside = useOutsideGuard()
141
148
  </script>
142
149
 
143
150
  <template>
@@ -156,8 +163,10 @@ function returnFocus(event: Event) {
156
163
  >
157
164
  <slot />
158
165
  </ContextMenuTrigger>
159
- <ContextMenuPortal v-if="items.length">
166
+ <ContextMenuPortal :to="portalTo" v-if="items.length">
160
167
  <ContextMenuContent
168
+ @interact-outside="guardOutside"
169
+ @escape-key-down="guardOutside"
161
170
  :collision-padding="8"
162
171
  :class="PANEL"
163
172
  :aria-label="title"