@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.
- package/README.md +49 -0
- package/dist/assets/LoaderMark-DxBV2iDJ.css +43 -0
- package/dist/assets/LpActivityLine-B3EwNQEB.css +33 -0
- package/dist/assets/{LpCommandPalette-DxyjhYn_.css → LpCommandPalette-u-zOxKWa.css} +21 -31
- package/dist/assets/LpDock-Cbh0wQUv.css +17 -0
- package/dist/assets/{LpDropzone-Qb8k7cg4.css → LpDropzone-Bb1vBTeU.css} +12 -17
- package/dist/assets/{LpImageEditor-CElPDzpF.css → LpImageEditor-XM5bAziW.css} +6 -6
- package/dist/assets/LpLogViewer-BDNW6P52.css +38 -0
- package/dist/assets/{LpPalettePreview-CJmAKgYW.css → LpPalettePreview-B9VKDrvA.css} +2 -7
- package/dist/assets/LpRepeater-C1Cw27hj.css +21 -0
- package/dist/assets/{LpRollingText-BGnE6q9j.css → LpRollingText-dyOXedGO.css} +7 -0
- package/dist/assets/LpShinyText-D69cBYDR.css +61 -0
- package/dist/assets/LpStatus-430OGTZY.css +17 -0
- package/dist/assets/LpStepMark-Drvx33Vg.css +10 -0
- package/dist/assets/{LpTable-BPERfJIk.css → LpTable-DHxEQ_-3.css} +19 -19
- package/dist/assets/LpTabs-BJ-nrJuI.css +18 -0
- package/dist/assets/LpTextReveal-DjI1MsDS.css +35 -0
- package/dist/assets/LpTypewriter-CXAm9Nca.css +27 -0
- package/dist/chunks/AttentionDot-DCBf4aWg.js +25 -0
- package/dist/chunks/{ContextMenuItems-B7XFHksm.js → ContextMenuItems-6kxEivBI.js} +11 -5
- package/dist/chunks/{DropzoneLinkField-CjkrpDqO.js → DropzoneLinkField-Bw8Flkhk.js} +2 -2
- package/dist/chunks/FieldWrapper-BiennROB.js +43 -0
- package/dist/chunks/{LayoutCanvas-DF9CovaK.js → LayoutCanvas-BsJIzhdd.js} +1 -1
- package/dist/chunks/{LayoutNode-D9bIFzk0.js → LayoutNode-DJVhkSGk.js} +6 -8
- package/dist/chunks/LegendSwatch-BhRjrtzv.js +18 -0
- package/dist/chunks/LoaderMark-C1dubiKn.js +85 -0
- package/dist/chunks/{LpActionBar-MPKMu3pz.js → LpActionBar-CzOFar5t.js} +14 -20
- package/dist/chunks/LpActivityLine-CJvzrNpj.js +95 -0
- package/dist/chunks/{LpAddressInput-DG0BTqdH.js → LpAddressInput-Chv_Xf8q.js} +7 -7
- package/dist/chunks/LpAlert-C5igj802.js +119 -0
- package/dist/chunks/{LpAppShell-DPh1756q.js → LpAppShell-BiWByLmt.js} +15 -16
- package/dist/chunks/{LpAutocomplete-Dgn6hw3p.js → LpAutocomplete-D92niDHE.js} +15 -32
- package/dist/chunks/{LpAvatar-Bs0Fb1lC.js → LpAvatar-CLPl-qOF.js} +18 -6
- package/dist/chunks/LpBadge-BBq1Er9T.js +126 -0
- package/dist/chunks/LpBreadcrumbs-JKEi_yFF.js +144 -0
- package/dist/chunks/{LpButton-DNR-YAq5.js → LpButton-CVxBfGjd.js} +12 -4
- package/dist/chunks/{LpCalendar-BLya39Fh.js → LpCalendar-pVL91-Pl.js} +1 -1
- package/dist/chunks/{LpCard-Bf71NXZq.js → LpCard-CqKLnEhl.js} +18 -8
- package/dist/chunks/{LpCheckbox-Da5oZPHo.js → LpCheckbox-DHc2bHDe.js} +9 -6
- package/dist/chunks/{LpCodeBlock-lLbmslfs.js → LpCodeBlock-BGsQhxw8.js} +24 -32
- package/dist/chunks/LpCodeDisplay-CbJMs-IK.js +189 -0
- package/dist/chunks/LpCollapse-CWS9M_lm.js +115 -0
- package/dist/chunks/{LpColorPicker-DtEfBAcK.js → LpColorPicker-B7HSIFmn.js} +11 -6
- package/dist/chunks/{LpConfirmDialog-D7s4jakB.js → LpConfirmDialog-CfGCux8m.js} +3 -3
- package/dist/chunks/{LpConfirmHost-DrYI5y1K.js → LpConfirmHost-exB7JmcO.js} +1 -1
- package/dist/chunks/{LpContextMenu-CRnjoqSt.js → LpContextMenu-Cj96ENDC.js} +16 -7
- package/dist/chunks/LpCopyButton-DzHjnFs0.js +133 -0
- package/dist/chunks/LpCountdown-BQnmB4gq.js +231 -0
- package/dist/chunks/LpDataList-CHNYQw7h.js +121 -0
- package/dist/chunks/LpDatePicker-ac1_6o5P.js +169 -0
- package/dist/chunks/LpDateRangePicker-B15gYrZJ.js +127 -0
- package/dist/chunks/{LpDisclosure-6AplYBub.js → LpDisclosure-DOarzlAG.js} +22 -11
- package/dist/chunks/{LpDrawer-Q4SOxM4s.js → LpDrawer-DGNKRsGq.js} +9 -4
- package/dist/chunks/{LpDropdownMenu-DWTt0ooM.js → LpDropdownMenu-R4aYVtVV.js} +14 -6
- package/dist/chunks/LpEditable-Ws3DNQHn.js +238 -0
- package/dist/chunks/{LpEmptyState-om1UnFjV.js → LpEmptyState-KTKipws2.js} +1 -1
- package/dist/chunks/{LpFieldNotice-CHuDeLjc.js → LpFieldNotice-CurbNuXI.js} +1 -1
- package/dist/chunks/{LpFileTree-CW24YsVX.js → LpFileTree-DDNg34tJ.js} +5 -3
- package/dist/chunks/{LpFileTreeNode-BXhTHaKW.js → LpFileTreeNode-DmPuYNZ_.js} +42 -55
- package/dist/chunks/{LpFormField-DPb47HEm.js → LpFormField-BWwgm1E4.js} +23 -9
- package/dist/chunks/LpFrame-BVQCQLDI.js +155 -0
- package/dist/chunks/LpGauge-C14Z9503.js +204 -0
- package/dist/chunks/LpGlowBorder-B8V-QzIl.js +40 -0
- package/dist/chunks/{LpHintExample-C1eKYdeL.js → LpHintExample-9Py0wc-L.js} +11 -34
- package/dist/chunks/{LpHintLayer-7UOdWQG3.js → LpHintLayer-HvwUA5Ec.js} +27 -14
- package/dist/chunks/{LpHints-BUtBp9-w.js → LpHints-DxbPKOzQ.js} +3 -3
- package/dist/chunks/LpHoverCard-spGxyw7T.js +130 -0
- package/dist/chunks/{LpIcon-6tSrZ3Zy.js → LpIcon-HJP5xMz4.js} +1 -1
- package/dist/chunks/LpIdenticon-BzdC_qz9.js +63 -0
- package/dist/chunks/{LpInfraNode-Ds_8SZgN.js → LpInfraNode-D64hywJI.js} +39 -25
- package/dist/chunks/{LpInput-CUyr6PIE.js → LpInput-CDuwODJG.js} +44 -18
- package/dist/chunks/{LpLightbox-B9J8rzsj.js → LpLightbox-XJ0LpTcZ.js} +69 -69
- package/dist/chunks/LpLoader-DjJEX8hL.js +92 -0
- package/dist/chunks/{LpLogViewer-4QFc-sVN.js → LpLogViewer-DKK4ySZl.js} +225 -129
- package/dist/chunks/LpMagnetic-CtXKLa2Y.js +62 -0
- package/dist/chunks/{LpMapPicker-BTbkFeSG.js → LpMapPicker-BtIl7NOM.js} +34 -31
- package/dist/chunks/LpMasonry--k0571qG.js +185 -0
- package/dist/chunks/{LpMediaGallery-CuPcscx3.js → LpMediaGallery-rmI1DjKN.js} +3 -3
- package/dist/chunks/{LpModal-hk1noDcr.js → LpModal-eBMt2Fqn.js} +8 -3
- package/dist/chunks/{LpModalNav-DQd2keZm.js → LpModalNav-DiyFCHiZ.js} +4 -4
- package/dist/chunks/{LpNotificationBell-X84PJIxD.js → LpNotificationBell-D-WhE5m2.js} +32 -48
- package/dist/chunks/LpNumberField-B9k-h2HE.js +140 -0
- package/dist/chunks/{LpNumberFlow-z4WPZcZu.js → LpNumberFlow-Cfyh033Q.js} +8 -28
- package/dist/chunks/{LpOtpInput-PbeNJ5In.js → LpOtpInput-CeBPsM7D.js} +2 -1
- package/dist/chunks/{LpPagination-Bx-VG4Ag.js → LpPagination-VNCX6pFC.js} +37 -6
- package/dist/chunks/{LpPalettePreview-CFav_7co.js → LpPalettePreview-BNB8T_MY.js} +1 -1
- package/dist/chunks/{LpPasswordInput-CbnXitAS.js → LpPasswordInput-GL2KOFK8.js} +26 -22
- package/dist/chunks/{LpPhoneInput-DP69HONS.js → LpPhoneInput-C60tx1tC.js} +12 -7
- package/dist/chunks/{LpPie-yLF9-aDR.js → LpPie-BgXZ3xmm.js} +159 -48
- package/dist/chunks/LpPipeline-B31h41Mu.js +329 -0
- package/dist/chunks/{LpPopover-DVnkHaOu.js → LpPopover-DmZ3wUtP.js} +13 -7
- package/dist/chunks/{LpProgress-CA86wxXu.js → LpProgress-CE-m5OpD.js} +23 -63
- package/dist/chunks/LpQuota-DaL8TgNe.js +162 -0
- package/dist/chunks/{LpRadioGroup-8S5hf8lE.js → LpRadioGroup-CGBr5nIp.js} +1 -1
- package/dist/chunks/{LpRangeCalendar-ByQi-WUz.js → LpRangeCalendar-c5qj7YcC.js} +1 -1
- package/dist/chunks/{LpRangeSlider-C1yF9-nP.js → LpRangeSlider-Dv6lNvHY.js} +6 -2
- package/dist/chunks/LpRelativeTime-yin9uQP7.js +73 -0
- package/dist/chunks/LpRepeater-D0S7jjwr.js +180 -0
- package/dist/chunks/LpRevealOnScroll-DcQjexLy.js +76 -0
- package/dist/chunks/{LpRollingText-DB7upf-5.js → LpRollingText-DiL717LK.js} +4 -3
- package/dist/chunks/LpScramble-TDO5Kdou.js +85 -0
- package/dist/chunks/LpSecretField-CfWyHv9m.js +316 -0
- package/dist/chunks/{LpSection-BmRXe6ZP.js → LpSection-BW4xJ-Li.js} +1 -1
- package/dist/chunks/{LpSegmented-CW3bFHM4.js → LpSegmented-BO99Sr4m.js} +11 -14
- package/dist/chunks/{LpSelect-BCyDYoih.js → LpSelect-C_8cJtj6.js} +91 -111
- package/dist/chunks/LpShaderBackdrop-Bote0iuy.js +332 -0
- package/dist/chunks/LpShinyText-DX2ajtWq.js +48 -0
- package/dist/chunks/{LpSidebar-DfIiS-lB.js → LpSidebar-CZRXtvem.js} +5 -3
- package/dist/chunks/{LpSidebarNav-C5FDNI0t.js → LpSidebarNav-DBg1U1oW.js} +3 -3
- package/dist/chunks/{LpSlider-Cuzmrd7p.js → LpSlider-DuoRpOrH.js} +6 -2
- package/dist/chunks/{LpSparkline-DXT4KrSi.js → LpSparkline-CExIRDb3.js} +32 -27
- package/dist/chunks/LpSpotlight-4F3NeUMY.js +41 -0
- package/dist/chunks/{LpStat-iBMF5QNk.js → LpStat-DFKlPJgy.js} +38 -35
- package/dist/chunks/LpStatus-BsGLrpor.js +86 -0
- package/dist/chunks/LpStepMark-TrzOioa9.js +101 -0
- package/dist/chunks/LpStepper-BbnS5jUr.js +76 -0
- package/dist/chunks/{LpSwap-D82jiecV.js → LpSwap-DzE6M3Mg.js} +1 -1
- package/dist/chunks/LpSwitch-DrzKrZZV.js +112 -0
- package/dist/chunks/{LpTableFilter-CuIbgdW0.js → LpTableFilter-DyvHGbOk.js} +3 -2
- package/dist/chunks/{LpTableOfContents-C_4VBktT.js → LpTableOfContents-rYvo8z5T.js} +34 -21
- package/dist/chunks/{LpTagsInput-DiXrpYeE.js → LpTagsInput-DZg80W-B.js} +68 -71
- package/dist/chunks/LpTextReveal-CtAnOUkp.js +140 -0
- package/dist/chunks/{LpTextarea-xoQd5Lnp.js → LpTextarea-DiWjeVoJ.js} +12 -11
- package/dist/chunks/{LpThemeProvider-CQ2jC9TA.js → LpThemeProvider-DcbfOxsU.js} +1 -1
- package/dist/chunks/LpThemeStudio-DxVZMtzN.js +416 -0
- package/dist/chunks/LpThemeStudioSection-BwhqYDLf.js +20 -0
- package/dist/chunks/LpThemeSwitcher-CadVBTBn.js +278 -0
- package/dist/chunks/{LpTimeField-MFgAsNc5.js → LpTimeField-BFQVf_PW.js} +13 -5
- package/dist/chunks/{LpToaster-C4zE9zB7.js → LpToaster-Wv9ksj4q.js} +49 -82
- package/dist/chunks/{LpTooltip-suFCM34F.js → LpTooltip-Cz8SQwRt.js} +8 -3
- package/dist/chunks/{LpTopologyCanvas-6ozNrQKh.js → LpTopologyCanvas-C17A1XCb.js} +1 -1
- package/dist/chunks/{LpTour-BUp3Jt2e.js → LpTour-CY2bFXge.js} +24 -18
- package/dist/chunks/LpTruncate-D_5Pfv5B.js +112 -0
- package/dist/chunks/LpTypewriter-BCL_a6wE.js +159 -0
- package/dist/chunks/{LpUptimeBar-B6kHw4Cj.js → LpUptimeBar-Tew1Ykx4.js} +10 -9
- package/dist/chunks/{LpVideoBackdrop-qWRYBOTQ.js → LpVideoBackdrop-DS1wGv-X.js} +7 -8
- package/dist/chunks/{MenuTitle-obgek0B7.js → MenuTitle-BjQZX8tQ.js} +1 -1
- package/dist/chunks/OptionContent-CmYUUeWj.js +40 -0
- package/dist/chunks/PickerField-DoHv0WMH.js +125 -0
- package/dist/chunks/RevealToggle-C-KzaQGJ.js +65 -0
- package/dist/chunks/StepConnector-37OgEOXA.js +41 -0
- package/dist/chunks/TourCard-BJ8i7dk0.js +123 -0
- package/dist/chunks/backdrop-Dkf2vM81.js +59 -0
- package/dist/chunks/{icons-DVhZ_plB.js → icons-4IywzkHk.js} +1 -1
- package/dist/chunks/{useTheme-2qHG8NEU.js → useTheme-BOV_-AiY.js} +9 -65
- package/dist/component-names.d.ts +1 -1
- package/dist/components/AttentionDot.vue.d.ts +9 -0
- package/dist/components/AttentionDot.vue.js +4 -0
- package/dist/components/ContextMenuItems.vue.js +1 -1
- package/dist/components/DropzoneLinkField.vue.js +1 -1
- package/dist/components/FieldWrapper.vue.d.ts +25 -0
- package/dist/components/FieldWrapper.vue.js +4 -0
- package/dist/components/LayoutCanvas.vue.js +1 -1
- package/dist/components/LayoutNode.vue.d.ts +4 -4
- package/dist/components/LayoutNode.vue.js +1 -1
- package/dist/components/LegendSwatch.vue.d.ts +6 -0
- package/dist/components/LegendSwatch.vue.js +4 -0
- package/dist/components/LoaderMark.vue.d.ts +12 -0
- package/dist/components/LoaderMark.vue.js +4 -0
- package/dist/components/LpActionBar.vue.js +1 -1
- package/dist/components/LpActivityLine.vue.d.ts +58 -0
- package/dist/components/LpActivityLine.vue.js +4 -0
- package/dist/components/LpAddressInput.vue.js +1 -1
- package/dist/components/LpAlert.vue.d.ts +2 -2
- package/dist/components/LpAlert.vue.js +1 -1
- package/dist/components/LpAppShell.vue.d.ts +8 -7
- package/dist/components/LpAppShell.vue.js +1 -1
- package/dist/components/LpAutocomplete.vue.js +1 -1
- package/dist/components/LpAvatar.vue.d.ts +16 -0
- package/dist/components/LpAvatar.vue.js +1 -1
- package/dist/components/LpBadge.vue.d.ts +19 -5
- package/dist/components/LpBadge.vue.js +1 -1
- package/dist/components/LpBreadcrumbs.vue.js +1 -1
- package/dist/components/LpButton.vue.d.ts +2 -2
- package/dist/components/LpButton.vue.js +1 -1
- package/dist/components/LpCalendar.vue.js +1 -1
- package/dist/components/LpCard.vue.d.ts +24 -0
- package/dist/components/LpCard.vue.js +1 -1
- package/dist/components/LpChart.vue.js +131 -160
- package/dist/components/LpCheckbox.vue.d.ts +2 -2
- package/dist/components/LpCheckbox.vue.js +1 -1
- package/dist/components/LpCodeBlock.vue.js +1 -1
- package/dist/components/LpCodeDisplay.vue.d.ts +89 -0
- package/dist/components/LpCodeDisplay.vue.js +4 -0
- package/dist/components/LpCollapse.vue.d.ts +58 -0
- package/dist/components/LpCollapse.vue.js +4 -0
- package/dist/components/LpColorPicker.vue.d.ts +2 -2
- package/dist/components/LpColorPicker.vue.js +1 -1
- package/dist/components/LpCommandPalette.vue.js +34 -23
- package/dist/components/LpConfirmDialog.vue.js +1 -1
- package/dist/components/LpConfirmHost.vue.js +1 -1
- package/dist/components/LpContextMenu.vue.js +1 -1
- package/dist/components/LpCopyButton.vue.d.ts +82 -0
- package/dist/components/LpCopyButton.vue.js +4 -0
- package/dist/components/LpCountdown.vue.d.ts +100 -0
- package/dist/components/LpCountdown.vue.js +4 -0
- package/dist/components/LpDataList.vue.d.ts +66 -0
- package/dist/components/LpDataList.vue.js +4 -0
- package/dist/components/LpDatePicker.vue.d.ts +3 -1
- package/dist/components/LpDatePicker.vue.js +1 -1
- package/dist/components/LpDateRangePicker.vue.d.ts +3 -1
- package/dist/components/LpDateRangePicker.vue.js +1 -1
- package/dist/components/LpDisclosure.vue.js +1 -1
- package/dist/components/LpDock.vue.d.ts +74 -0
- package/dist/components/LpDock.vue.js +204 -0
- package/dist/components/LpDrawer.vue.js +1 -1
- package/dist/components/LpDropdownMenu.vue.js +1 -1
- package/dist/components/LpDropzone.vue.d.ts +8 -1
- package/dist/components/LpDropzone.vue.js +36 -15
- package/dist/components/LpEditable.vue.d.ts +85 -0
- package/dist/components/LpEditable.vue.js +4 -0
- package/dist/components/LpEmptyState.vue.js +1 -1
- package/dist/components/LpFieldNotice.vue.js +1 -1
- package/dist/components/LpFileTree.vue.js +1 -1
- package/dist/components/LpFileTreeNode.vue.js +1 -1
- package/dist/components/LpFormField.vue.js +1 -1
- package/dist/components/LpFrame.vue.d.ts +22 -0
- package/dist/components/LpFrame.vue.js +4 -0
- package/dist/components/LpGauge.vue.d.ts +116 -0
- package/dist/components/LpGauge.vue.js +4 -0
- package/dist/components/LpGlowBorder.vue.d.ts +47 -0
- package/dist/components/LpGlowBorder.vue.js +4 -0
- package/dist/components/LpHintExample.vue.d.ts +2 -2
- package/dist/components/LpHintExample.vue.js +1 -1
- package/dist/components/LpHintLayer.vue.js +1 -1
- package/dist/components/LpHints.vue.js +1 -1
- package/dist/components/LpHoverCard.vue.d.ts +60 -0
- package/dist/components/LpHoverCard.vue.js +4 -0
- package/dist/components/LpIcon.vue.js +1 -1
- package/dist/components/LpIdenticon.vue.d.ts +37 -0
- package/dist/components/LpIdenticon.vue.js +4 -0
- package/dist/components/LpImageEditor.vue.js +13 -19
- package/dist/components/LpInfraNode.vue.js +1 -1
- package/dist/components/LpInput.vue.d.ts +10 -0
- package/dist/components/LpInput.vue.js +1 -1
- package/dist/components/LpLightbox.vue.js +1 -1
- package/dist/components/LpLoader.vue.d.ts +106 -0
- package/dist/components/LpLoader.vue.js +4 -0
- package/dist/components/LpLogViewer.vue.js +1 -1
- package/dist/components/LpMagnetic.vue.d.ts +28 -0
- package/dist/components/LpMagnetic.vue.js +4 -0
- package/dist/components/LpMapPicker.vue.js +1 -1
- package/dist/components/LpMasonry.vue.d.ts +42 -0
- package/dist/components/LpMasonry.vue.js +4 -0
- package/dist/components/LpMediaGallery.vue.js +1 -1
- package/dist/components/LpModal.vue.js +1 -1
- package/dist/components/LpModalNav.vue.js +1 -1
- package/dist/components/LpNotificationBell.vue.d.ts +15 -6
- package/dist/components/LpNotificationBell.vue.js +1 -1
- package/dist/components/LpNumberField.vue.d.ts +57 -0
- package/dist/components/LpNumberField.vue.js +1 -1
- package/dist/components/LpNumberFlow.vue.js +1 -1
- package/dist/components/LpOtpInput.vue.d.ts +12 -4
- package/dist/components/LpOtpInput.vue.js +1 -1
- package/dist/components/LpPagination.vue.js +1 -1
- package/dist/components/LpPaletteFacts.vue.js +2 -2
- package/dist/components/LpPaletteHeader.vue.js +2 -2
- package/dist/components/LpPalettePreview.vue.js +1 -1
- package/dist/components/LpPaletteStats.vue.js +2 -2
- package/dist/components/LpPasswordInput.vue.d.ts +19 -2
- package/dist/components/LpPasswordInput.vue.js +1 -1
- package/dist/components/LpPhoneInput.vue.js +1 -1
- package/dist/components/LpPie.vue.d.ts +3 -1
- package/dist/components/LpPie.vue.js +1 -1
- package/dist/components/LpPipeline.vue.d.ts +91 -0
- package/dist/components/LpPipeline.vue.js +4 -0
- package/dist/components/LpPopover.vue.d.ts +2 -2
- package/dist/components/LpPopover.vue.js +1 -1
- package/dist/components/LpProgress.vue.d.ts +11 -4
- package/dist/components/LpProgress.vue.js +1 -1
- package/dist/components/LpQuota.vue.d.ts +68 -0
- package/dist/components/LpQuota.vue.js +4 -0
- package/dist/components/LpRadioGroup.vue.js +1 -1
- package/dist/components/LpRangeCalendar.vue.js +1 -1
- package/dist/components/LpRangeSlider.vue.js +1 -1
- package/dist/components/LpRelativeTime.vue.d.ts +41 -0
- package/dist/components/LpRelativeTime.vue.js +4 -0
- package/dist/components/LpRepeater.vue.d.ts +48 -0
- package/dist/components/LpRepeater.vue.js +4 -0
- package/dist/components/LpRevealOnScroll.vue.d.ts +67 -0
- package/dist/components/LpRevealOnScroll.vue.js +4 -0
- package/dist/components/LpRollingText.vue.d.ts +3 -1
- package/dist/components/LpRollingText.vue.js +1 -1
- package/dist/components/LpScramble.vue.d.ts +55 -0
- package/dist/components/LpScramble.vue.js +4 -0
- package/dist/components/LpScrollArea.vue.d.ts +1 -1
- package/dist/components/LpSecretField.vue.d.ts +108 -0
- package/dist/components/LpSecretField.vue.js +4 -0
- package/dist/components/LpSection.vue.js +1 -1
- package/dist/components/LpSegmented.vue.js +1 -1
- package/dist/components/LpSelect.vue.d.ts +2 -0
- package/dist/components/LpSelect.vue.js +1 -1
- package/dist/components/LpShaderBackdrop.vue.d.ts +39 -0
- package/dist/components/LpShaderBackdrop.vue.js +4 -0
- package/dist/components/LpShinyText.vue.d.ts +39 -0
- package/dist/components/LpShinyText.vue.js +4 -0
- package/dist/components/LpShortcutsDialog.vue.js +1 -1
- package/dist/components/LpSidebar.vue.js +1 -1
- package/dist/components/LpSidebarNav.vue.js +1 -1
- package/dist/components/LpSlider.vue.js +1 -1
- package/dist/components/LpSparkline.vue.d.ts +4 -3
- package/dist/components/LpSparkline.vue.js +1 -1
- package/dist/components/LpSpotlight.vue.d.ts +37 -0
- package/dist/components/LpSpotlight.vue.js +4 -0
- package/dist/components/LpStat.vue.js +1 -1
- package/dist/components/LpStatus.vue.d.ts +65 -0
- package/dist/components/LpStatus.vue.js +4 -0
- package/dist/components/LpStepMark.vue.d.ts +31 -0
- package/dist/components/LpStepMark.vue.js +4 -0
- package/dist/components/LpStepper.vue.js +1 -1
- package/dist/components/LpSwap.vue.js +1 -1
- package/dist/components/LpSwitch.vue.d.ts +2 -2
- package/dist/components/LpSwitch.vue.js +1 -1
- package/dist/components/LpTable.vue.js +104 -120
- package/dist/components/LpTableFilter.vue.js +1 -1
- package/dist/components/LpTableOfContents.vue.d.ts +6 -1
- package/dist/components/LpTableOfContents.vue.js +1 -1
- package/dist/components/LpTabs.vue.d.ts +5 -5
- package/dist/components/LpTabs.vue.js +25 -33
- package/dist/components/LpTagsInput.vue.js +1 -1
- package/dist/components/LpTextReveal.vue.d.ts +58 -0
- package/dist/components/LpTextReveal.vue.js +4 -0
- package/dist/components/LpTextarea.vue.js +1 -1
- package/dist/components/LpThemeProvider.vue.js +1 -1
- package/dist/components/LpThemeStudio.vue.d.ts +54 -0
- package/dist/components/LpThemeStudio.vue.js +4 -0
- package/dist/components/LpThemeStudioSection.vue.d.ts +16 -0
- package/dist/components/LpThemeStudioSection.vue.js +4 -0
- package/dist/components/LpThemeSwitcher.vue.d.ts +32 -1
- package/dist/components/LpThemeSwitcher.vue.js +1 -1
- package/dist/components/LpTimeField.vue.d.ts +2 -0
- package/dist/components/LpTimeField.vue.js +1 -1
- package/dist/components/LpToaster.vue.js +1 -1
- package/dist/components/LpTooltip.vue.d.ts +2 -2
- package/dist/components/LpTooltip.vue.js +1 -1
- package/dist/components/LpTopologyCanvas.vue.js +1 -1
- package/dist/components/LpTour.vue.js +1 -1
- package/dist/components/LpTruncate.vue.d.ts +34 -0
- package/dist/components/LpTruncate.vue.js +4 -0
- package/dist/components/LpTypewriter.vue.d.ts +61 -0
- package/dist/components/LpTypewriter.vue.js +4 -0
- package/dist/components/LpUptimeBar.vue.js +1 -1
- package/dist/components/LpVideoBackdrop.vue.js +1 -1
- package/dist/components/MenuTitle.vue.js +1 -1
- package/dist/components/OptionContent.vue.d.ts +7 -0
- package/dist/components/OptionContent.vue.js +4 -0
- package/dist/components/PickerField.vue.d.ts +45 -0
- package/dist/components/PickerField.vue.js +4 -0
- package/dist/components/RevealToggle.vue.d.ts +21 -0
- package/dist/components/RevealToggle.vue.js +4 -0
- package/dist/components/StepConnector.vue.d.ts +19 -0
- package/dist/components/StepConnector.vue.js +4 -0
- package/dist/components/TourCard.vue.js +1 -1
- package/dist/components/badge.d.ts +1 -0
- package/dist/components/badge.js +4 -0
- package/dist/components/chart.d.ts +5 -1
- package/dist/components/chart.js +2 -21
- package/dist/components/dateRange.d.ts +11 -0
- package/dist/components/dateRange.js +12 -0
- package/dist/components/dock.d.ts +19 -0
- package/dist/components/dock.js +16 -0
- package/dist/components/dropdown.d.ts +10 -1
- package/dist/components/dropdown.js +7 -2
- package/dist/components/fieldText.d.ts +38 -0
- package/dist/components/fieldText.js +53 -0
- package/dist/components/fileTree.d.ts +7 -3
- package/dist/components/fileTree.js +12 -18
- package/dist/components/format.d.ts +41 -0
- package/dist/components/format.js +67 -0
- package/dist/components/identicon.d.ts +38 -0
- package/dist/components/identicon.js +85 -0
- package/dist/components/masonry.d.ts +32 -0
- package/dist/components/masonry.js +40 -0
- package/dist/components/menuWhen.js +1 -1
- package/dist/components/meter.d.ts +64 -0
- package/dist/components/meter.js +53 -0
- package/dist/components/otp.d.ts +1 -1
- package/dist/components/otp.js +7 -2
- package/dist/components/pipeline.d.ts +55 -0
- package/dist/components/pipeline.js +51 -0
- package/dist/components/quota.d.ts +57 -0
- package/dist/components/quota.js +40 -0
- package/dist/components/relativeTime.d.ts +24 -0
- package/dist/components/relativeTime.js +56 -0
- package/dist/components/reveal.d.ts +18 -0
- package/dist/components/reveal.js +32 -0
- package/dist/components/scramble.d.ts +68 -0
- package/dist/components/scramble.js +58 -0
- package/dist/components/shaderBackdrop.d.ts +20 -0
- package/dist/components/shaderBackdrop.js +156 -0
- package/dist/components/slider.d.ts +5 -0
- package/dist/components/slider.js +24 -0
- package/dist/components/slotText.d.ts +2 -0
- package/dist/components/slotText.js +9 -0
- package/dist/components/status.d.ts +14 -0
- package/dist/components/status.js +22 -0
- package/dist/components/tableFacets.d.ts +8 -0
- package/dist/components/tableFacets.js +19 -0
- package/dist/components/textSplit.d.ts +17 -0
- package/dist/components/textSplit.js +24 -0
- package/dist/components/timeSpan.d.ts +78 -0
- package/dist/components/timeSpan.js +85 -0
- package/dist/components/tone.d.ts +43 -0
- package/dist/components/tone.js +82 -0
- package/dist/components/tour.js +3 -2
- package/dist/components/typewriter.d.ts +36 -0
- package/dist/components/typewriter.js +53 -0
- package/dist/components/videoBackdrop.js +5 -6
- package/dist/composables/easing.d.ts +22 -1
- package/dist/composables/easing.js +42 -1
- package/dist/composables/pseudoLocale.d.ts +15 -0
- package/dist/composables/pseudoLocale.js +96 -0
- package/dist/composables/scroll.js +5 -3
- package/dist/composables/useClipboard.d.ts +4 -1
- package/dist/composables/useClipboard.js +12 -2
- package/dist/composables/useField.d.ts +13 -0
- package/dist/composables/useField.js +26 -1
- package/dist/composables/useForm.js +32 -9
- package/dist/composables/useInView.d.ts +11 -0
- package/dist/composables/useInView.js +39 -0
- package/dist/composables/useLoadingGate.d.ts +8 -0
- package/dist/composables/useLoadingGate.js +38 -0
- package/dist/composables/useLpConfig.d.ts +10 -0
- package/dist/composables/useLpConfig.js +11 -1
- package/dist/composables/useMediaQuery.js +3 -1
- package/dist/composables/useNow.d.ts +16 -0
- package/dist/composables/useNow.js +39 -0
- package/dist/composables/usePersisted.js +14 -7
- package/dist/composables/usePillTransition.d.ts +5 -2
- package/dist/composables/usePillTransition.js +4 -3
- package/dist/composables/usePointerFrame.d.ts +18 -0
- package/dist/composables/usePointerFrame.js +31 -0
- package/dist/composables/useReducedMotion.d.ts +2 -0
- package/dist/composables/useReducedMotion.js +7 -0
- package/dist/composables/useRepeater.d.ts +17 -0
- package/dist/composables/useRepeater.js +31 -0
- package/dist/composables/useResizeObserver.d.ts +8 -0
- package/dist/composables/useResizeObserver.js +33 -0
- package/dist/composables/useRevealedValue.d.ts +31 -0
- package/dist/composables/useRevealedValue.js +26 -0
- package/dist/composables/useScramble.d.ts +42 -0
- package/dist/composables/useScramble.js +76 -0
- package/dist/composables/useShift.js +2 -10
- package/dist/composables/useSpotlight.d.ts +18 -0
- package/dist/composables/useSpotlight.js +53 -0
- package/dist/composables/useTilt.js +26 -18
- package/dist/composables/useTween.d.ts +43 -0
- package/dist/composables/useTween.js +69 -0
- package/dist/composables/useView.d.ts +18 -0
- package/dist/composables/useView.js +64 -0
- package/dist/icons-all.js +1 -1
- package/dist/index.d.ts +98 -1
- package/dist/index.js +263 -105
- package/dist/theme/define.d.ts +12 -0
- package/dist/theme/studio.d.ts +90 -0
- package/package.json +8 -2
- package/src/component-names.ts +33 -0
- package/src/components/AttentionDot.vue +27 -0
- package/src/components/ContextMenuItems.vue +5 -2
- package/src/components/FieldWrapper.vue +38 -0
- package/src/components/LayoutNode.vue +5 -9
- package/src/components/LegendSwatch.vue +15 -0
- package/src/components/LoaderMark.vue +90 -0
- package/src/components/LpActionBar.vue +12 -20
- package/src/components/LpActivityLine.vue +186 -0
- package/src/components/LpAlert.vue +54 -24
- package/src/components/LpAppShell.vue +7 -11
- package/src/components/LpAutocomplete.vue +16 -14
- package/src/components/LpAvatar.vue +17 -2
- package/src/components/LpBadge.vue +77 -13
- package/src/components/LpBreadcrumbs.vue +101 -35
- package/src/components/LpButton.vue +15 -3
- package/src/components/LpCard.vue +30 -7
- package/src/components/LpChart.vue +162 -171
- package/src/components/LpCheckbox.vue +10 -4
- package/src/components/LpCodeBlock.vue +11 -19
- package/src/components/LpCodeDisplay.vue +228 -0
- package/src/components/LpCollapse.vue +162 -0
- package/src/components/LpColorPicker.vue +10 -1
- package/src/components/LpCommandPalette.vue +38 -24
- package/src/components/LpContextMenu.vue +13 -3
- package/src/components/LpCopyButton.vue +185 -0
- package/src/components/LpCountdown.vue +308 -0
- package/src/components/LpDataList.vue +154 -0
- package/src/components/LpDatePicker.vue +55 -104
- package/src/components/LpDateRangePicker.vue +51 -95
- package/src/components/LpDisclosure.vue +58 -36
- package/src/components/LpDock.vue +274 -0
- package/src/components/LpDrawer.vue +10 -1
- package/src/components/LpDropdownMenu.vue +11 -2
- package/src/components/LpDropzone.vue +34 -13
- package/src/components/LpEditable.vue +295 -0
- package/src/components/LpFileTree.vue +5 -1
- package/src/components/LpFileTreeNode.vue +25 -50
- package/src/components/LpFormField.vue +22 -3
- package/src/components/LpFrame.vue +200 -0
- package/src/components/LpGauge.vue +287 -0
- package/src/components/LpGlowBorder.vue +60 -0
- package/src/components/LpHintExample.vue +9 -32
- package/src/components/LpHintLayer.vue +13 -3
- package/src/components/LpHoverCard.vue +175 -0
- package/src/components/LpIdenticon.vue +69 -0
- package/src/components/LpImageEditor.vue +15 -18
- package/src/components/LpInfraNode.vue +27 -16
- package/src/components/LpInput.vue +30 -16
- package/src/components/LpLightbox.vue +44 -23
- package/src/components/LpLoader.vue +145 -0
- package/src/components/LpLogViewer.vue +311 -82
- package/src/components/LpMagnetic.vue +97 -0
- package/src/components/LpMapPicker.vue +26 -28
- package/src/components/LpMasonry.vue +247 -0
- package/src/components/LpModal.vue +10 -1
- package/src/components/LpNotificationBell.vue +33 -49
- package/src/components/LpNumberField.vue +79 -14
- package/src/components/LpNumberFlow.vue +10 -35
- package/src/components/LpOtpInput.vue +7 -2
- package/src/components/LpPagination.vue +38 -4
- package/src/components/LpPalettePreview.vue +2 -7
- package/src/components/LpPasswordInput.vue +25 -18
- package/src/components/LpPhoneInput.vue +12 -3
- package/src/components/LpPie.vue +197 -36
- package/src/components/LpPipeline.vue +366 -0
- package/src/components/LpPopover.vue +14 -1
- package/src/components/LpProgress.vue +22 -84
- package/src/components/LpQuota.vue +197 -0
- package/src/components/LpRangeSlider.vue +5 -1
- package/src/components/LpRelativeTime.vue +90 -0
- package/src/components/LpRepeater.vue +131 -0
- package/src/components/LpRevealOnScroll.vue +125 -0
- package/src/components/LpRollingText.vue +12 -1
- package/src/components/LpScramble.vue +107 -0
- package/src/components/LpSecretField.vue +320 -0
- package/src/components/LpSegmented.vue +3 -10
- package/src/components/LpSelect.vue +74 -65
- package/src/components/LpShaderBackdrop.vue +434 -0
- package/src/components/LpShinyText.vue +139 -0
- package/src/components/LpSidebar.vue +2 -0
- package/src/components/LpSlider.vue +5 -1
- package/src/components/LpSparkline.vue +55 -37
- package/src/components/LpSpotlight.vue +51 -0
- package/src/components/LpStat.vue +6 -2
- package/src/components/LpStatus.vue +127 -0
- package/src/components/LpStepMark.vue +138 -0
- package/src/components/LpStepper.vue +37 -43
- package/src/components/LpSwap.vue +2 -2
- package/src/components/LpSwitch.vue +15 -22
- package/src/components/LpTable.vue +47 -63
- package/src/components/LpTableFilter.vue +1 -0
- package/src/components/LpTableOfContents.vue +53 -29
- package/src/components/LpTabs.vue +10 -21
- package/src/components/LpTagsInput.vue +53 -37
- package/src/components/LpTextReveal.vue +236 -0
- package/src/components/LpTextarea.vue +11 -11
- package/src/components/LpThemeStudio.vue +216 -0
- package/src/components/LpThemeStudioSection.vue +16 -0
- package/src/components/LpThemeSwitcher.vue +156 -47
- package/src/components/LpTimeField.vue +9 -1
- package/src/components/LpToaster.vue +63 -83
- package/src/components/LpTooltip.vue +10 -1
- package/src/components/LpTour.vue +24 -13
- package/src/components/LpTruncate.vue +135 -0
- package/src/components/LpTypewriter.vue +236 -0
- package/src/components/LpUptimeBar.vue +6 -5
- package/src/components/LpVideoBackdrop.vue +15 -13
- package/src/components/OptionContent.vue +17 -0
- package/src/components/PickerField.vue +59 -0
- package/src/components/RevealToggle.vue +51 -0
- package/src/components/StepConnector.vue +54 -0
- package/src/components/TourCard.vue +29 -16
- package/src/components/badge.ts +8 -0
- package/src/components/chart.ts +8 -23
- package/src/components/dateRange.ts +25 -0
- package/src/components/dock.ts +31 -0
- package/src/components/dropdown.ts +15 -3
- package/src/components/fieldText.ts +95 -0
- package/src/components/fileTree.ts +19 -21
- package/src/components/format.ts +136 -0
- package/src/components/identicon.ts +160 -0
- package/src/components/masonry.ts +73 -0
- package/src/components/meter.ts +122 -0
- package/src/components/otp.ts +14 -3
- package/src/components/pipeline.ts +101 -0
- package/src/components/quota.ts +111 -0
- package/src/components/relativeTime.ts +118 -0
- package/src/components/reveal.ts +56 -0
- package/src/components/scramble.ts +138 -0
- package/src/components/shaderBackdrop.ts +208 -0
- package/src/components/slider.ts +30 -0
- package/src/components/slotText.ts +13 -0
- package/src/components/status.ts +46 -0
- package/src/components/tableFacets.ts +25 -0
- package/src/components/textSplit.ts +55 -0
- package/src/components/timeSpan.ts +183 -0
- package/src/components/tone.ts +144 -0
- package/src/components/tour.ts +3 -2
- package/src/components/typewriter.ts +104 -0
- package/src/components/videoBackdrop.ts +7 -6
- package/src/composables/easing.ts +66 -1
- package/src/composables/pseudoLocale.ts +105 -0
- package/src/composables/scroll.ts +6 -3
- package/src/composables/useClipboard.ts +25 -3
- package/src/composables/useField.ts +38 -1
- package/src/composables/useForm.ts +41 -11
- package/src/composables/useInView.ts +61 -0
- package/src/composables/useLoadingGate.ts +63 -0
- package/src/composables/useLpConfig.ts +20 -1
- package/src/composables/useMediaQuery.ts +6 -2
- package/src/composables/useNow.ts +84 -0
- package/src/composables/usePersisted.ts +19 -8
- package/src/composables/usePillTransition.ts +21 -13
- package/src/composables/usePointerFrame.ts +72 -0
- package/src/composables/useReducedMotion.ts +22 -0
- package/src/composables/useRepeater.ts +44 -0
- package/src/composables/useResizeObserver.ts +59 -0
- package/src/composables/useRevealedValue.ts +84 -0
- package/src/composables/useScramble.ts +152 -0
- package/src/composables/useShift.ts +10 -16
- package/src/composables/useSpotlight.ts +82 -0
- package/src/composables/useTilt.ts +40 -23
- package/src/composables/useTween.ts +149 -0
- package/src/composables/useView.ts +96 -0
- package/src/index.css +1 -0
- package/src/index.ts +143 -1
- package/src/kit-icons.ts +1 -1
- package/src/theme/define.ts +65 -0
- package/src/theme/studio.ts +202 -0
- package/src/tokens/effects.css +151 -0
- package/src/tokens/tokens.css +131 -39
- package/src/tokens/utilities.css +81 -0
- package/dist/assets/LpTabs-Bk7v4bZz.css +0 -18
- package/dist/chunks/LpAlert-BdvxvcWE.js +0 -85
- package/dist/chunks/LpBadge-Fe0D1bYx.js +0 -62
- package/dist/chunks/LpBreadcrumbs-rzOKkLiI.js +0 -98
- package/dist/chunks/LpDatePicker-BMfM454Y.js +0 -243
- package/dist/chunks/LpDateRangePicker-CNb9X3eL.js +0 -195
- package/dist/chunks/LpNumberField-DO1ufKvE.js +0 -107
- package/dist/chunks/LpStepper-C2slwObu.js +0 -90
- package/dist/chunks/LpSwitch-CZy9_IoA.js +0 -132
- package/dist/chunks/LpThemeSwitcher-CDoziW0z.js +0 -166
- 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(
|
|
916
|
-
|
|
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
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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, useView, viewDocument } from "../composables/useView"
|
|
17
18
|
|
|
18
19
|
export interface ContextMenuItemDef {
|
|
19
20
|
label: string
|
|
@@ -80,12 +81,13 @@ const PANEL = `${POPOVER_PANEL} z-(--z-popover) min-w-48 p-1 outline-none`
|
|
|
80
81
|
// selection if the menu action left the text as it was.
|
|
81
82
|
type TextField = HTMLInputElement | HTMLTextAreaElement
|
|
82
83
|
const SELECTABLE = new Set(["text", "search", "url", "tel", "password"])
|
|
84
|
+
const view = useView()
|
|
83
85
|
let field: { el: TextField; value: string; start: number; end: number } | null = null
|
|
84
86
|
|
|
85
87
|
function rememberField() {
|
|
86
|
-
const el =
|
|
88
|
+
const el = viewDocument(view.value).activeElement
|
|
87
89
|
const text =
|
|
88
|
-
el
|
|
90
|
+
el?.tagName === "TEXTAREA" || (el?.tagName === "INPUT" && SELECTABLE.has((el as HTMLInputElement).type))
|
|
89
91
|
field = text
|
|
90
92
|
? { el: el as TextField, value: (el as TextField).value, start: (el as TextField).selectionStart ?? 0, end: (el as TextField).selectionEnd ?? 0 }
|
|
91
93
|
: null
|
|
@@ -138,6 +140,12 @@ function returnFocus(event: Event) {
|
|
|
138
140
|
saved.el.focus()
|
|
139
141
|
if (saved.el.value === saved.value) saved.el.setSelectionRange(saved.start, saved.end)
|
|
140
142
|
}
|
|
143
|
+
|
|
144
|
+
// Overlays open in the window this component renders in (an LpFrame's, inside one).
|
|
145
|
+
const portalTo = usePortalTarget()
|
|
146
|
+
// What happens in another document (the page around a frame, or a frame in
|
|
147
|
+
// the page) is not "outside" for this layer.
|
|
148
|
+
const guardOutside = useOutsideGuard()
|
|
141
149
|
</script>
|
|
142
150
|
|
|
143
151
|
<template>
|
|
@@ -156,8 +164,10 @@ function returnFocus(event: Event) {
|
|
|
156
164
|
>
|
|
157
165
|
<slot />
|
|
158
166
|
</ContextMenuTrigger>
|
|
159
|
-
<ContextMenuPortal v-if="items.length">
|
|
167
|
+
<ContextMenuPortal :to="portalTo" v-if="items.length">
|
|
160
168
|
<ContextMenuContent
|
|
169
|
+
@interact-outside="guardOutside"
|
|
170
|
+
@escape-key-down="guardOutside"
|
|
161
171
|
:collision-padding="8"
|
|
162
172
|
:class="PANEL"
|
|
163
173
|
:aria-label="title"
|