@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.
- package/README.md +37 -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/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-B5uE8Znw.js} +1 -1
- 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-CNnLTDZg.js} +7 -7
- package/dist/chunks/LpAlert-C5igj802.js +119 -0
- package/dist/chunks/{LpAppShell-DPh1756q.js → LpAppShell-CEUAB8kK.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-HOEPBYmi.js +126 -0
- package/dist/chunks/LpBreadcrumbs-DYoPc3P4.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-CIKKT2iW.js +189 -0
- package/dist/chunks/LpCollapse-CWS9M_lm.js +115 -0
- package/dist/chunks/{LpColorPicker-DtEfBAcK.js → LpColorPicker-DFugXNUi.js} +10 -5
- 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-COwOwRgI.js} +13 -5
- package/dist/chunks/LpCopyButton-DzHjnFs0.js +133 -0
- package/dist/chunks/LpCountdown-Dtq1ihlJ.js +231 -0
- package/dist/chunks/LpDataList-B-5nHfNw.js +120 -0
- package/dist/chunks/LpDatePicker-BUe1VUC0.js +168 -0
- package/dist/chunks/LpDateRangePicker-C_k65vGR.js +126 -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-CRgrhdAH.js} +10 -5
- package/dist/chunks/LpEditable-DTqLt2lT.js +236 -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-DMISXVHC.js} +5 -3
- package/dist/chunks/{LpFileTreeNode-BXhTHaKW.js → LpFileTreeNode-CPXB_Yy3.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-Bk8TwJj0.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-p4hqzdyA.js} +27 -14
- package/dist/chunks/{LpHints-BUtBp9-w.js → LpHints-CCrhRfy9.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-CUC3t4na.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-elZHbj85.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-D5swlmZ_.js} +3 -3
- package/dist/chunks/{LpModal-hk1noDcr.js → LpModal-eBMt2Fqn.js} +8 -3
- package/dist/chunks/{LpModalNav-DQd2keZm.js → LpModalNav-D4Z0wVHR.js} +4 -4
- package/dist/chunks/{LpNotificationBell-X84PJIxD.js → LpNotificationBell-DPZmP5dM.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-DTV18FIh.js} +20 -20
- package/dist/chunks/{LpPhoneInput-DP69HONS.js → LpPhoneInput-C60tx1tC.js} +12 -7
- package/dist/chunks/{LpPie-yLF9-aDR.js → LpPie-CFuV7pZv.js} +158 -47
- package/dist/chunks/LpPipeline-D81yh_NX.js +329 -0
- package/dist/chunks/{LpPopover-DVnkHaOu.js → LpPopover-BEIcqb9p.js} +8 -3
- package/dist/chunks/{LpProgress-CA86wxXu.js → LpProgress-CE-m5OpD.js} +23 -63
- package/dist/chunks/LpQuota-2Sw_gqcJ.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-CKzVqAo9.js +73 -0
- package/dist/chunks/LpRepeater-D0VjmD6y.js +140 -0
- package/dist/chunks/LpRevealOnScroll-DcQjexLy.js +76 -0
- package/dist/chunks/LpScramble-TDO5Kdou.js +85 -0
- package/dist/chunks/LpSecretField-DMfdJ1cQ.js +307 -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-B4f_yRi5.js} +93 -108
- package/dist/chunks/LpShaderBackdrop-Bote0iuy.js +332 -0
- package/dist/chunks/LpShinyText-DX2ajtWq.js +48 -0
- package/dist/chunks/{LpSidebar-DfIiS-lB.js → LpSidebar-D-M0Y_7U.js} +5 -3
- package/dist/chunks/{LpSidebarNav-C5FDNI0t.js → LpSidebarNav-DF-TYxOV.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-B2ix1Q7t.js} +38 -35
- package/dist/chunks/LpStatus-C7kx5PKE.js +86 -0
- package/dist/chunks/LpStepMark-DK-5BKAt.js +101 -0
- package/dist/chunks/LpStepper-DRFfdJaq.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-DgpBFRV2.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-DguwHdGt.js +416 -0
- package/dist/chunks/LpThemeStudioSection-BwhqYDLf.js +20 -0
- package/dist/chunks/LpThemeSwitcher-D5uz0MhK.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-ZhKthfgz.js} +1 -1
- package/dist/chunks/{LpTour-BUp3Jt2e.js → LpTour-NfRJNEIP.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-DWegV2p6.js} +9 -8
- 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-CHRS1h7K.js +116 -0
- package/dist/chunks/RevealToggle-C-KzaQGJ.js +65 -0
- package/dist/chunks/StepConnector-37OgEOXA.js +41 -0
- package/dist/chunks/TourCard-BXuVHsfn.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.d.ts +10 -0
- package/dist/components/LpChart.vue.js +122 -142
- 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 +1 -1
- package/dist/components/LpDatePicker.vue.js +1 -1
- package/dist/components/LpDateRangePicker.vue.d.ts +1 -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 +1 -1
- package/dist/components/LpPaletteHeader.vue.js +2 -2
- package/dist/components/LpPalettePreview.vue.js +1 -1
- package/dist/components/LpPaletteStats.vue.js +1 -1
- package/dist/components/LpPasswordInput.vue.d.ts +12 -1
- 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 +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 +43 -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 +8 -0
- package/dist/composables/useField.js +5 -0
- package/dist/composables/useForm.js +19 -5
- package/dist/composables/useHintSystem.d.ts +4 -0
- package/dist/composables/useHintSystem.js +33 -1
- package/dist/composables/useHints.js +9 -3
- 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 +61 -0
- package/dist/icons-all.js +1 -1
- package/dist/index.d.ts +98 -1
- package/dist/index.js +262 -104
- package/dist/theme/define.d.ts +12 -0
- package/dist/theme/studio.d.ts +90 -0
- package/package.json +5 -2
- package/src/component-names.ts +33 -0
- package/src/components/AttentionDot.vue +27 -0
- 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 +152 -156
- 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 +10 -1
- 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 +53 -104
- package/src/components/LpDateRangePicker.vue +49 -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 +10 -1
- package/src/components/LpDropzone.vue +34 -13
- package/src/components/LpEditable.vue +293 -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 +14 -38
- 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 +16 -14
- 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 +10 -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 +80 -0
- package/src/components/LpRevealOnScroll.vue +125 -0
- package/src/components/LpScramble.vue +107 -0
- package/src/components/LpSecretField.vue +313 -0
- package/src/components/LpSegmented.vue +3 -10
- package/src/components/LpSelect.vue +78 -64
- 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 +58 -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 +12 -0
- package/src/composables/useForm.ts +27 -6
- package/src/composables/useHintSystem.ts +40 -0
- package/src/composables/useHints.ts +14 -3
- 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 +93 -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,175 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/*
|
|
3
|
+
* A preview card that opens when the pointer rests on something: a username
|
|
4
|
+
* that shows the profile, a server name that shows its status, a link that
|
|
5
|
+
* shows where it goes. Reading it costs a pause, not a click and a back.
|
|
6
|
+
*
|
|
7
|
+
* <LpHoverCard>
|
|
8
|
+
* <template #trigger><a href="/u/ada">@ada</a></template>
|
|
9
|
+
* <ProfilePreview id="ada" />
|
|
10
|
+
* </LpHoverCard>
|
|
11
|
+
*
|
|
12
|
+
* Different from the neighbours on purpose:
|
|
13
|
+
* - LpTooltip names or explains a control in a line of text; this holds a
|
|
14
|
+
* small layout (avatar, stats, actions) and waits longer before opening, so
|
|
15
|
+
* passing over a list of names does not flash a card at every row.
|
|
16
|
+
* - LpPopover opens on a click and is a place to DO something; a hover card is
|
|
17
|
+
* a glance, and everything in it must also be reachable without it (the
|
|
18
|
+
* trigger usually links to the full page).
|
|
19
|
+
*
|
|
20
|
+
* Behaviour, built on reka's HoverCard:
|
|
21
|
+
* - Opens after `openDelay` on hover, and at once on keyboard focus of the
|
|
22
|
+
* trigger, so it is not a mouse-only feature.
|
|
23
|
+
* - Stays open while the pointer travels to the card and over it, so a link
|
|
24
|
+
* or a button inside can be used; closes `closeDelay` after it leaves.
|
|
25
|
+
* - Touch has no hover. With `touch="hold"` a press-and-hold opens the card
|
|
26
|
+
* (and that press does not also follow the link); a tap elsewhere closes it.
|
|
27
|
+
* `touch="none"` leaves touch alone, for triggers where a hold means
|
|
28
|
+
* something else (a drag handle, a context menu).
|
|
29
|
+
*/
|
|
30
|
+
import {
|
|
31
|
+
HoverCardArrow,
|
|
32
|
+
HoverCardContent,
|
|
33
|
+
HoverCardPortal,
|
|
34
|
+
HoverCardRoot,
|
|
35
|
+
HoverCardTrigger,
|
|
36
|
+
} from "reka-ui"
|
|
37
|
+
import { computed, onBeforeUnmount, watch } from "vue"
|
|
38
|
+
import { mergeClass } from "../composables/useMergedClass"
|
|
39
|
+
import { useOutsideGuard, usePortalTarget } from "../composables/useView"
|
|
40
|
+
import { POPOVER_PANEL } from "./dropdown"
|
|
41
|
+
|
|
42
|
+
const props = withDefaults(
|
|
43
|
+
defineProps<{
|
|
44
|
+
side?: "top" | "right" | "bottom" | "left"
|
|
45
|
+
align?: "start" | "center" | "end"
|
|
46
|
+
sideOffset?: number
|
|
47
|
+
/**
|
|
48
|
+
* Milliseconds the pointer rests before the card opens. Longer than a
|
|
49
|
+
* tooltip's on purpose: a card is big, and one that opens while the
|
|
50
|
+
* pointer is only passing by covers what the reader was heading for.
|
|
51
|
+
*/
|
|
52
|
+
openDelay?: number
|
|
53
|
+
/** Milliseconds after the pointer leaves before it closes: room to cross the gap to the card. */
|
|
54
|
+
closeDelay?: number
|
|
55
|
+
/** A small pointer from the card to its trigger, for a trigger in a dense row where the card could belong to a neighbour. */
|
|
56
|
+
arrow?: boolean
|
|
57
|
+
/** Touch: `hold` opens on press-and-hold; `none` leaves touch to the trigger. */
|
|
58
|
+
touch?: "hold" | "none"
|
|
59
|
+
/** How long a touch must be held to open, in ms. */
|
|
60
|
+
holdDelay?: number
|
|
61
|
+
/** Turn the card off: the trigger stays and behaves as itself. */
|
|
62
|
+
disabled?: boolean
|
|
63
|
+
/** Extra classes for the card (width, padding). Merged, so `w-80 p-0` replaces the defaults. */
|
|
64
|
+
panelClass?: string
|
|
65
|
+
}>(),
|
|
66
|
+
{
|
|
67
|
+
side: "bottom",
|
|
68
|
+
align: "center",
|
|
69
|
+
sideOffset: 8,
|
|
70
|
+
openDelay: 500,
|
|
71
|
+
closeDelay: 200,
|
|
72
|
+
arrow: false,
|
|
73
|
+
touch: "hold",
|
|
74
|
+
holdDelay: 450,
|
|
75
|
+
disabled: false,
|
|
76
|
+
},
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
// Controllable (v-model:open). Always held here, also uncontrolled, because a
|
|
80
|
+
// touch hold opens the card from outside reka's own hover handling.
|
|
81
|
+
const open = defineModel<boolean>("open", { default: false })
|
|
82
|
+
|
|
83
|
+
const panel = computed(() =>
|
|
84
|
+
mergeClass(POPOVER_PANEL, "z-(--z-popover) w-72 rounded-card p-4 text-sm text-ink outline-none", props.panelClass),
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
const portalTo = usePortalTarget()
|
|
88
|
+
const guardOutside = useOutsideGuard()
|
|
89
|
+
|
|
90
|
+
/*
|
|
91
|
+
* Press-and-hold. A hold that drifts is a scroll, not a hold, so moving past
|
|
92
|
+
* a few pixels cancels it. Once it has opened the card, the click the finger
|
|
93
|
+
* produces on lifting is swallowed: the reader asked for the preview, not for
|
|
94
|
+
* the link under it.
|
|
95
|
+
*/
|
|
96
|
+
const SLOP = 8
|
|
97
|
+
let holdTimer = 0
|
|
98
|
+
let start = { x: 0, y: 0 }
|
|
99
|
+
let held = false
|
|
100
|
+
|
|
101
|
+
function cancelHold() {
|
|
102
|
+
window.clearTimeout(holdTimer)
|
|
103
|
+
holdTimer = 0
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function onPointerDown(event: PointerEvent) {
|
|
107
|
+
if (event.pointerType !== "touch" || props.touch !== "hold" || props.disabled) return
|
|
108
|
+
held = false
|
|
109
|
+
start = { x: event.clientX, y: event.clientY }
|
|
110
|
+
cancelHold()
|
|
111
|
+
holdTimer = window.setTimeout(() => {
|
|
112
|
+
holdTimer = 0
|
|
113
|
+
held = true
|
|
114
|
+
open.value = true
|
|
115
|
+
}, props.holdDelay)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function onPointerMove(event: PointerEvent) {
|
|
119
|
+
if (!holdTimer) return
|
|
120
|
+
if (Math.hypot(event.clientX - start.x, event.clientY - start.y) > SLOP) cancelHold()
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function onClickCapture(event: MouseEvent) {
|
|
124
|
+
if (!held) return
|
|
125
|
+
held = false
|
|
126
|
+
event.preventDefault()
|
|
127
|
+
event.stopPropagation()
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// A long press would otherwise also bring up the system's own menu for the link.
|
|
131
|
+
function onContextMenu(event: Event) {
|
|
132
|
+
if (holdTimer || held) event.preventDefault()
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
watch(
|
|
136
|
+
() => props.disabled,
|
|
137
|
+
(off) => {
|
|
138
|
+
if (off) open.value = false
|
|
139
|
+
},
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
onBeforeUnmount(cancelHold)
|
|
143
|
+
</script>
|
|
144
|
+
|
|
145
|
+
<template>
|
|
146
|
+
<slot v-if="disabled" name="trigger" />
|
|
147
|
+
<HoverCardRoot v-else v-model:open="open" :open-delay="openDelay" :close-delay="closeDelay">
|
|
148
|
+
<HoverCardTrigger
|
|
149
|
+
as-child
|
|
150
|
+
:class="touch === 'hold' ? '[-webkit-touch-callout:none]' : undefined"
|
|
151
|
+
@pointerdown="onPointerDown"
|
|
152
|
+
@pointermove="onPointerMove"
|
|
153
|
+
@pointerup="cancelHold"
|
|
154
|
+
@pointercancel="cancelHold"
|
|
155
|
+
@click.capture="onClickCapture"
|
|
156
|
+
@contextmenu="onContextMenu"
|
|
157
|
+
>
|
|
158
|
+
<slot name="trigger" />
|
|
159
|
+
</HoverCardTrigger>
|
|
160
|
+
<HoverCardPortal :to="portalTo">
|
|
161
|
+
<HoverCardContent
|
|
162
|
+
:side="side"
|
|
163
|
+
:align="align"
|
|
164
|
+
:side-offset="sideOffset"
|
|
165
|
+
:collision-padding="8"
|
|
166
|
+
:class="panel"
|
|
167
|
+
@pointer-down-outside="guardOutside"
|
|
168
|
+
@escape-key-down="guardOutside"
|
|
169
|
+
>
|
|
170
|
+
<slot :close="() => (open = false)" />
|
|
171
|
+
<HoverCardArrow v-if="arrow" :width="14" :height="7" class="fill-surface-raised" />
|
|
172
|
+
</HoverCardContent>
|
|
173
|
+
</HoverCardPortal>
|
|
174
|
+
</HoverCardRoot>
|
|
175
|
+
</template>
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// The consumer's `class` is merged into the root's own (below) rather than
|
|
3
|
+
// appended to it, so opt out of the automatic pass-through that would add it
|
|
4
|
+
// a second time, unmerged.
|
|
5
|
+
export default { inheritAttrs: false }
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<script setup lang="ts">
|
|
9
|
+
/*
|
|
10
|
+
* A face for something that has no picture: a mirrored pixel pattern and a
|
|
11
|
+
* colour, both derived from `seed` (an id, a username, a key's fingerprint).
|
|
12
|
+
* The same seed draws the same identicon everywhere, so people learn to
|
|
13
|
+
* recognise it the way they recognise an avatar.
|
|
14
|
+
*
|
|
15
|
+
* It fills the box it is put in (an LpAvatar sizes it through `identicon`);
|
|
16
|
+
* give it a size class of its own anywhere else. The pattern is generated by
|
|
17
|
+
* `identicon()` in identicon.ts, which a canvas, a favicon or a notification
|
|
18
|
+
* icon can call directly.
|
|
19
|
+
*/
|
|
20
|
+
import { computed } from "vue"
|
|
21
|
+
import { identicon, identiconRects } from "./identicon"
|
|
22
|
+
import { useMergedAttrs } from "../composables/useMergedClass"
|
|
23
|
+
|
|
24
|
+
const props = withDefaults(
|
|
25
|
+
defineProps<{
|
|
26
|
+
/** What the picture is derived from. Use something stable: an id outlives a renamed username. */
|
|
27
|
+
seed: string
|
|
28
|
+
/** Cells per side: 5 is the familiar look, 7 gives busier shapes for large sizes. */
|
|
29
|
+
grid?: number
|
|
30
|
+
/**
|
|
31
|
+
* `tint` lays a pale wash of the shape's own hue behind it, mixed into the
|
|
32
|
+
* theme's soft surface so it sits right on dark and light alike; `none`
|
|
33
|
+
* leaves the box behind it showing.
|
|
34
|
+
*/
|
|
35
|
+
background?: "tint" | "none"
|
|
36
|
+
/** Empty margin around the grid as a share of the side; more for a round crop. */
|
|
37
|
+
padding?: number
|
|
38
|
+
/** Accessible name. Unset, the picture is decorative: the name is usually written next to it. */
|
|
39
|
+
label?: string
|
|
40
|
+
}>(),
|
|
41
|
+
{ grid: 5, background: "tint", padding: 0.14 },
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
const icon = computed(() => identicon(props.seed, { grid: props.grid }))
|
|
45
|
+
const rects = computed(() => identiconRects(icon.value.cells))
|
|
46
|
+
const pad = computed(() => props.grid * Math.max(0, Math.min(0.4, props.padding)))
|
|
47
|
+
const view = computed(() => props.grid + pad.value * 2)
|
|
48
|
+
const wash = computed(() => `color-mix(in oklab, ${icon.value.color} 16%, var(--color-surface-soft))`)
|
|
49
|
+
|
|
50
|
+
const { class: rootClass, attrs: rest } = useMergedAttrs("block size-full")
|
|
51
|
+
</script>
|
|
52
|
+
|
|
53
|
+
<template>
|
|
54
|
+
<svg
|
|
55
|
+
:class="rootClass"
|
|
56
|
+
v-bind="rest"
|
|
57
|
+
:viewBox="`0 0 ${view} ${view}`"
|
|
58
|
+
shape-rendering="crispEdges"
|
|
59
|
+
:role="label ? 'img' : undefined"
|
|
60
|
+
:aria-label="label"
|
|
61
|
+
:aria-hidden="label ? undefined : 'true'"
|
|
62
|
+
>
|
|
63
|
+
<rect v-if="background === 'tint'" :width="view" :height="view" :style="{ fill: wash }" class="transition-[fill] duration-medium motion-reduce:transition-none" />
|
|
64
|
+
<!-- Keyed by seed: a new seed is a new face, faded in rather than snapped. -->
|
|
65
|
+
<g :key="seed" :fill="icon.color" class="animate-[fade-in_var(--duration-medium)_ease] motion-reduce:animate-none">
|
|
66
|
+
<rect v-for="(r, i) in rects" :key="i" :x="r.x + pad" :y="r.y + pad" :width="r.w" height="1" />
|
|
67
|
+
</g>
|
|
68
|
+
</svg>
|
|
69
|
+
</template>
|
|
@@ -48,6 +48,7 @@ import LpButton from "./LpButton.vue"
|
|
|
48
48
|
import LpContextMenu, { type ContextMenuItemDef } from "./LpContextMenu.vue"
|
|
49
49
|
import LpIcon from "./LpIcon.vue"
|
|
50
50
|
import { useMergedAttrs } from "../composables/useMergedClass"
|
|
51
|
+
import { useResizeObserver } from "../composables/useResizeObserver"
|
|
51
52
|
|
|
52
53
|
const props = withDefaults(
|
|
53
54
|
defineProps<{
|
|
@@ -144,23 +145,20 @@ const viewport = ref<HTMLElement | null>(null)
|
|
|
144
145
|
const zoom = useZoomPan({ min: 1, max: 6 })
|
|
145
146
|
|
|
146
147
|
const frameSize = ref<{ width: number; height: number } | null>(null)
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
frameObserver.observe(el)
|
|
162
|
-
}
|
|
163
|
-
})
|
|
148
|
+
|
|
149
|
+
watch(viewport, (el) => zoom.setViewport(el))
|
|
150
|
+
// Fractional, not clientWidth: a rounded-down frame left a hairline of
|
|
151
|
+
// background showing along the edges of a turned picture. The first, rounded
|
|
152
|
+
// reading only holds the frame until the observer's first report.
|
|
153
|
+
useResizeObserver(
|
|
154
|
+
viewport,
|
|
155
|
+
(entry, el) => {
|
|
156
|
+
frameSize.value = entry
|
|
157
|
+
? { width: entry.contentRect.width, height: entry.contentRect.height }
|
|
158
|
+
: { width: el.clientWidth, height: el.clientHeight }
|
|
159
|
+
},
|
|
160
|
+
{ immediate: true },
|
|
161
|
+
)
|
|
164
162
|
|
|
165
163
|
/** Which way up it ends, 0-270, whatever the accumulated angle. */
|
|
166
164
|
const upright = computed(() => ((rotation.value % 360) + 360) % 360)
|
|
@@ -296,7 +294,6 @@ function revoke() {
|
|
|
296
294
|
onBeforeUnmount(() => {
|
|
297
295
|
generation++
|
|
298
296
|
revoke()
|
|
299
|
-
frameObserver?.disconnect()
|
|
300
297
|
})
|
|
301
298
|
|
|
302
299
|
function rotate(by: number) {
|
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import { Handle, Position } from "@vue-flow/core"
|
|
12
12
|
import { computed } from "vue"
|
|
13
|
+
import LpBadge from "./LpBadge.vue"
|
|
14
|
+
import LpStatus from "./LpStatus.vue"
|
|
13
15
|
|
|
14
16
|
export interface InfraNodeData {
|
|
15
17
|
name: string
|
|
@@ -174,10 +176,12 @@ const accentLine = computed(
|
|
|
174
176
|
<div class="flex items-center gap-[7px]">
|
|
175
177
|
<span class="text-[13px] text-[var(--accent)]">{{ icon }}</span>
|
|
176
178
|
<span class="flex-1 truncate text-[13px] font-semibold text-ink">{{ data.name }}</span>
|
|
177
|
-
|
|
179
|
+
<!-- The kit's status light: a live host breathes, a lost one is a steady red. -->
|
|
180
|
+
<LpStatus
|
|
178
181
|
v-if="data.online !== undefined"
|
|
179
|
-
|
|
180
|
-
:
|
|
182
|
+
:state="data.online ? 'online' : 'down'"
|
|
183
|
+
:pulse="data.online"
|
|
184
|
+
hide-label
|
|
181
185
|
/>
|
|
182
186
|
</div>
|
|
183
187
|
<div class="mt-1.5 flex items-center justify-between">
|
|
@@ -190,32 +194,39 @@ const accentLine = computed(
|
|
|
190
194
|
v-if="data.firewallCount || data.serviceCount !== undefined || data.staleFor"
|
|
191
195
|
class="mt-1.5 flex items-center gap-1.5"
|
|
192
196
|
>
|
|
193
|
-
|
|
197
|
+
<!-- LpBadge's small chip, with the card's own 9px type: at the badge's
|
|
198
|
+
11px three of them (a firewall count, a service count, an age)
|
|
199
|
+
overflow a 168px card. -->
|
|
200
|
+
<LpBadge
|
|
194
201
|
v-if="data.firewallCount"
|
|
195
|
-
|
|
202
|
+
tone="danger"
|
|
203
|
+
size="sm"
|
|
204
|
+
class="text-[9px]"
|
|
196
205
|
:title="fill(text.firewallRules, { n: data.firewallCount! })"
|
|
197
206
|
>
|
|
198
|
-
|
|
199
|
-
</
|
|
200
|
-
<
|
|
207
|
+
⛨ {{ data.firewallCount }}
|
|
208
|
+
</LpBadge>
|
|
209
|
+
<LpBadge
|
|
201
210
|
v-if="data.serviceCount !== undefined"
|
|
202
|
-
|
|
203
|
-
|
|
211
|
+
size="sm"
|
|
212
|
+
class="text-[9px] text-muted"
|
|
204
213
|
:title="
|
|
205
214
|
data.staleFor
|
|
206
215
|
? fill(text.servicesStale, { n: data.serviceCount!, age: data.staleFor })
|
|
207
216
|
: fill(text.services, { n: data.serviceCount! })
|
|
208
217
|
"
|
|
209
218
|
>
|
|
210
|
-
<span
|
|
211
|
-
</
|
|
212
|
-
<
|
|
219
|
+
<span :class="data.staleFor ? 'line-through decoration-danger/70' : ''">◇ {{ data.serviceCount }}</span>
|
|
220
|
+
</LpBadge>
|
|
221
|
+
<LpBadge
|
|
213
222
|
v-if="data.staleFor"
|
|
214
|
-
|
|
223
|
+
tone="danger"
|
|
224
|
+
size="sm"
|
|
225
|
+
class="text-[9px]"
|
|
215
226
|
:title="fill(text.noContact, { age: data.staleFor })"
|
|
216
227
|
>
|
|
217
|
-
|
|
218
|
-
</
|
|
228
|
+
⚠ {{ data.staleFor }} {{ text.old }}
|
|
229
|
+
</LpBadge>
|
|
219
230
|
</div>
|
|
220
231
|
</div>
|
|
221
232
|
</div>
|
|
@@ -6,10 +6,11 @@ export default { inheritAttrs: false }
|
|
|
6
6
|
import { tv, type VariantProps } from "tailwind-variants"
|
|
7
7
|
import { computed, ref, useAttrs, useSlots } from "vue"
|
|
8
8
|
import { useFieldControl } from "../composables/useField"
|
|
9
|
+
import { useLabels } from "../composables/useLpConfig"
|
|
9
10
|
import { useInputFilter } from "../composables/useInputFilter"
|
|
10
11
|
import { DEFAULT_MASK_TOKENS, useInputMask, type MaskSpec, type MaskTokens } from "../composables/useInputMask"
|
|
11
12
|
import { mergeClass } from "../composables/useMergedClass"
|
|
12
|
-
import
|
|
13
|
+
import FieldWrapper from "./FieldWrapper.vue"
|
|
13
14
|
import LpIcon from "./LpIcon.vue"
|
|
14
15
|
|
|
15
16
|
// Single source of truth for the field shell — bare input and adorned input
|
|
@@ -57,6 +58,9 @@ const props = withDefaults(
|
|
|
57
58
|
hint?: string
|
|
58
59
|
error?: string
|
|
59
60
|
icon?: string
|
|
61
|
+
/** Show an accessible clear button, returning focus to the input. */
|
|
62
|
+
clearable?: boolean
|
|
63
|
+
labels?: Partial<{ clear: string }>
|
|
60
64
|
/**
|
|
61
65
|
* Marks the label with the required indicator. The attribute still reaches
|
|
62
66
|
* the underlying <input> for native validation; this only makes the field
|
|
@@ -130,7 +134,7 @@ const patternInvalid = computed(() => isInvalid(props.modelValue))
|
|
|
130
134
|
const slots = useSlots()
|
|
131
135
|
const attrs = useAttrs()
|
|
132
136
|
const hasLeading = computed(() => !!slots.leading || !!props.icon)
|
|
133
|
-
const hasTrailing = computed(() => !!slots.trailing)
|
|
137
|
+
const hasTrailing = computed(() => !!slots.trailing || showClear.value)
|
|
134
138
|
const hasField = computed(
|
|
135
139
|
() => !!props.label || !!props.hint || !!props.error,
|
|
136
140
|
)
|
|
@@ -142,6 +146,8 @@ const field = useFieldControl(() => ({
|
|
|
142
146
|
required: props.required,
|
|
143
147
|
disabled: props.disabled,
|
|
144
148
|
}))
|
|
149
|
+
const text = useLabels("input", { clear: "Clear" }, () => props.labels)
|
|
150
|
+
const showClear = computed(() => props.clearable && !!props.modelValue && !field.value.disabled && (attrs.readonly === undefined || attrs.readonly === false))
|
|
145
151
|
const isInvalidState = computed(() => field.value.invalid)
|
|
146
152
|
const shellClass = computed(() =>
|
|
147
153
|
shell({ size: props.size, invalid: isInvalidState.value }),
|
|
@@ -150,14 +156,18 @@ const shellClass = computed(() =>
|
|
|
150
156
|
// class/style belong to the wrapper (so `<LpInput class="...">` lays out the
|
|
151
157
|
// whole field); every other attr (autocomplete, name, @keyup, inputmode…) goes
|
|
152
158
|
// to the real <input>.
|
|
153
|
-
const rootClass = computed(() => attrs.class)
|
|
154
|
-
const rootStyle = computed(() => attrs.style)
|
|
155
159
|
const inputAttrs = computed(() => {
|
|
156
160
|
const { class: _c, style: _s, ...rest } = attrs
|
|
157
161
|
return rest
|
|
158
162
|
})
|
|
159
163
|
|
|
160
164
|
const inputEl = ref<HTMLInputElement | null>(null)
|
|
165
|
+
function clear() {
|
|
166
|
+
if (!showClear.value) return
|
|
167
|
+
emit("update:modelValue", "")
|
|
168
|
+
if (masking.active.value) emit("update:raw", "")
|
|
169
|
+
inputEl.value?.focus()
|
|
170
|
+
}
|
|
161
171
|
defineExpose({
|
|
162
172
|
focus: (options?: FocusOptions) => inputEl.value?.focus(options),
|
|
163
173
|
blur: () => inputEl.value?.blur(),
|
|
@@ -167,20 +177,20 @@ defineExpose({
|
|
|
167
177
|
</script>
|
|
168
178
|
|
|
169
179
|
<template>
|
|
170
|
-
<
|
|
171
|
-
:
|
|
172
|
-
:
|
|
173
|
-
:
|
|
174
|
-
:
|
|
175
|
-
:
|
|
176
|
-
:
|
|
177
|
-
:class="
|
|
178
|
-
:style="
|
|
180
|
+
<FieldWrapper
|
|
181
|
+
:wrapped="hasField"
|
|
182
|
+
:id="field.id"
|
|
183
|
+
:label="label"
|
|
184
|
+
:hint="hint"
|
|
185
|
+
:error="error"
|
|
186
|
+
:required="required"
|
|
187
|
+
:class="attrs.class"
|
|
188
|
+
:style="attrs.style"
|
|
179
189
|
>
|
|
180
190
|
<div
|
|
181
191
|
data-lp-ring-owner
|
|
182
|
-
:class="mergeClass(shellClass, hasLeading ? 'pl-2.5' : '', hasTrailing ? 'pr-1.5' : '', hasField ? '' : (
|
|
183
|
-
:style="hasField ? undefined :
|
|
192
|
+
:class="mergeClass(shellClass, hasLeading ? 'pl-2.5' : '', hasTrailing ? 'pr-1.5' : '', hasField ? '' : (attrs.class as string))"
|
|
193
|
+
:style="hasField ? undefined : attrs.style"
|
|
184
194
|
>
|
|
185
195
|
<span v-if="hasLeading" class="flex shrink-0 items-center text-muted">
|
|
186
196
|
<slot name="leading"><LpIcon v-if="icon" :name="icon" :size="16" /></slot>
|
|
@@ -198,6 +208,7 @@ defineExpose({
|
|
|
198
208
|
:aria-describedby="field.describedBy"
|
|
199
209
|
:class="[
|
|
200
210
|
'lp-autofill min-w-0 flex-1 self-stretch bg-transparent outline-none placeholder:text-muted',
|
|
211
|
+
clearable && '[&::-webkit-search-cancel-button]:hidden',
|
|
201
212
|
hasLeading ? 'pl-2' : padX[size ?? 'md'],
|
|
202
213
|
hasTrailing ? '' : padX[size ?? 'md'],
|
|
203
214
|
]"
|
|
@@ -207,6 +218,9 @@ defineExpose({
|
|
|
207
218
|
@input="onInputEvent"
|
|
208
219
|
/>
|
|
209
220
|
<slot name="trailing" />
|
|
221
|
+
<button v-if="showClear" type="button" :aria-label="text.clear" class="shrink-0 rounded-inner p-1 text-muted outline-none transition-colors hover:text-ink focus-visible:ring-2 focus-visible:ring-ring" @pointerdown.prevent @click="clear">
|
|
222
|
+
<LpIcon name="lucide:x" :size="size === 'sm' ? 12 : 16" />
|
|
223
|
+
</button>
|
|
210
224
|
</div>
|
|
211
|
-
</
|
|
225
|
+
</FieldWrapper>
|
|
212
226
|
</template>
|
|
@@ -25,8 +25,11 @@ import { computed, nextTick, onBeforeUnmount, ref, watch } from "vue"
|
|
|
25
25
|
import { useLabels } from "../composables/useLpConfig"
|
|
26
26
|
import { useZoomPan } from "../composables/useZoomPan"
|
|
27
27
|
import { fileNameOf, type LightboxItem } from "./lightbox"
|
|
28
|
+
import LpCopyButton from "./LpCopyButton.vue"
|
|
28
29
|
import LpIcon from "./LpIcon.vue"
|
|
30
|
+
import LpLoader from "./LpLoader.vue"
|
|
29
31
|
import { useModalLayer } from "./modalDepth"
|
|
32
|
+
import { useOutsideGuard, usePortalTarget } from "../composables/useView"
|
|
30
33
|
|
|
31
34
|
export type LightboxLabels = {
|
|
32
35
|
viewer: string
|
|
@@ -380,20 +383,22 @@ async function download() {
|
|
|
380
383
|
}
|
|
381
384
|
}
|
|
382
385
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
386
|
+
/*
|
|
387
|
+
* The copy button (LpCopyButton) asks for the image when clicked: fetched then,
|
|
388
|
+
* not for every image paged past, and reported against the item that was on
|
|
389
|
+
* screen at the click even if the viewer pages on while it loads.
|
|
390
|
+
*/
|
|
391
|
+
let copyTarget: LightboxItem | undefined
|
|
392
|
+
async function imageToCopy(): Promise<Blob> {
|
|
393
|
+
const target = (copyTarget = item.value)
|
|
394
|
+
if (!target) throw new Error("No image")
|
|
395
|
+
const response = await fetch(target.src)
|
|
396
|
+
const blob = await response.blob()
|
|
397
|
+
// Clipboard only takes PNG; re-encode anything else through a canvas.
|
|
398
|
+
return blob.type === "image/png" ? blob : reencodeToPng(await createImageBitmap(blob))
|
|
399
|
+
}
|
|
400
|
+
function copyDone(ok: boolean) {
|
|
401
|
+
if (copyTarget) emit("copy", copyTarget, ok)
|
|
397
402
|
}
|
|
398
403
|
|
|
399
404
|
async function reencodeToPng(bitmap: ImageBitmap): Promise<Blob> {
|
|
@@ -430,11 +435,17 @@ const BTN =
|
|
|
430
435
|
*/
|
|
431
436
|
const ARROW =
|
|
432
437
|
"absolute top-1/2 z-10 flex size-11 -translate-y-1/2 items-center justify-center rounded-pill bg-black/45 text-white/75 ring-1 ring-white/0 outline-none backdrop-blur-sm transition-[background-color,scale,color,box-shadow] duration-[var(--duration-fast)] ease-[var(--ease-emphasized)] hover:bg-white/20 hover:text-white hover:ring-white/30 hover:scale-110 active:scale-95 focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-0 motion-reduce:transition-none motion-reduce:hover:scale-100 motion-reduce:active:scale-100"
|
|
438
|
+
|
|
439
|
+
// Overlays open in the window this component renders in (an LpFrame's, inside one).
|
|
440
|
+
const portalTo = usePortalTarget()
|
|
441
|
+
// What happens in another document (the page around a frame, or a frame in
|
|
442
|
+
// the page) is not "outside" for this layer.
|
|
443
|
+
const guardOutside = useOutsideGuard()
|
|
433
444
|
</script>
|
|
434
445
|
|
|
435
446
|
<template>
|
|
436
447
|
<DialogRoot :open="open" @update:open="(v) => emit('update:open', v)">
|
|
437
|
-
<DialogPortal>
|
|
448
|
+
<DialogPortal :to="portalTo">
|
|
438
449
|
<!-- Not `lp-scrim--nested` even over another layer: a lightbox wants its
|
|
439
450
|
full dark backdrop around the picture, not the lighter nested tint.
|
|
440
451
|
The blur is handed up the stack like every scrim's. -->
|
|
@@ -444,6 +455,8 @@ const ARROW =
|
|
|
444
455
|
:style="{ zIndex: layer.scrim }"
|
|
445
456
|
/>
|
|
446
457
|
<DialogContent
|
|
458
|
+
@interact-outside="guardOutside"
|
|
459
|
+
@escape-key-down="guardOutside"
|
|
447
460
|
ref="contentRef"
|
|
448
461
|
class="fixed inset-0 flex flex-col outline-none data-[state=open]:animate-[lightbox-in_var(--duration-medium)_var(--ease-emphasized)] data-[state=closed]:animate-[lightbox-out_140ms_cubic-bezier(0.4,0,1,1)] motion-reduce:animate-none"
|
|
449
462
|
:style="{ zIndex: layer.panel }"
|
|
@@ -483,9 +496,15 @@ const ARROW =
|
|
|
483
496
|
>
|
|
484
497
|
<LpIcon name="lucide:rotate-cw" :size="18" />
|
|
485
498
|
</button>
|
|
486
|
-
<
|
|
487
|
-
|
|
488
|
-
|
|
499
|
+
<LpCopyButton
|
|
500
|
+
v-if="copyable"
|
|
501
|
+
:value="imageToCopy"
|
|
502
|
+
:icon-size="18"
|
|
503
|
+
:class="BTN"
|
|
504
|
+
:labels="{ copy: text.copy }"
|
|
505
|
+
@copied="copyDone(true)"
|
|
506
|
+
@error="copyDone(false)"
|
|
507
|
+
/>
|
|
489
508
|
<button
|
|
490
509
|
v-if="downloadable"
|
|
491
510
|
:class="BTN"
|
|
@@ -561,11 +580,13 @@ const ARROW =
|
|
|
561
580
|
@error="((failed = true), (loading = false))"
|
|
562
581
|
/>
|
|
563
582
|
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
583
|
+
<!-- Mounted throughout and driven by `active`, so a cached image that
|
|
584
|
+
loads at once shows no spinner and a slow one keeps it long
|
|
585
|
+
enough not to blink. -->
|
|
586
|
+
<LpLoader
|
|
587
|
+
:active="loading && !failed && !covered(current)"
|
|
588
|
+
size="inline"
|
|
589
|
+
class="absolute text-[28px] text-white/50"
|
|
569
590
|
/>
|
|
570
591
|
|
|
571
592
|
<button
|