@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,58 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { useAttrs } from "vue"
|
|
3
|
+
import type { useFieldControl } from "../composables/useField"
|
|
4
|
+
import { mergeClass } from "../composables/useMergedClass"
|
|
5
|
+
import { PICKER_CLEAR, PICKER_PRESET, PICKER_PRESETS, PICKER_SIZE, PICKER_TRIGGER, pickerTone } from "./calendar"
|
|
6
|
+
import LpIcon from "./LpIcon.vue"
|
|
7
|
+
import LpPopover from "./LpPopover.vue"
|
|
8
|
+
import LpRollingText from "./LpRollingText.vue"
|
|
9
|
+
|
|
10
|
+
defineOptions({ inheritAttrs: false })
|
|
11
|
+
withDefaults(defineProps<{
|
|
12
|
+
field: ReturnType<typeof useFieldControl>["value"]
|
|
13
|
+
display: string
|
|
14
|
+
placeholder: string
|
|
15
|
+
icon: string
|
|
16
|
+
size?: "sm" | "md" | "lg"
|
|
17
|
+
clearable: boolean
|
|
18
|
+
clearLabel: string
|
|
19
|
+
presetsLabel: string
|
|
20
|
+
presets: { label: string; disabled: boolean; selected: boolean; select: () => void }[]
|
|
21
|
+
presetsClass: string
|
|
22
|
+
}>(), { size: "md" })
|
|
23
|
+
const open = defineModel<boolean>("open")
|
|
24
|
+
defineEmits<{ clear: [] }>()
|
|
25
|
+
const attrs = useAttrs()
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<template>
|
|
29
|
+
<div :class="mergeClass('relative w-full', attrs.class as string)" :style="attrs.style as never">
|
|
30
|
+
<LpPopover v-model:open="open" align="start" panel-class="flex w-auto max-w-[calc(100vw-1rem)] flex-col rounded-card p-0 sm:flex-row">
|
|
31
|
+
<template #trigger>
|
|
32
|
+
<button
|
|
33
|
+
v-bind="{ ...attrs, class: undefined, style: undefined }"
|
|
34
|
+
:id="field.id"
|
|
35
|
+
type="button"
|
|
36
|
+
:disabled="field.disabled"
|
|
37
|
+
:aria-invalid="field.invalid || undefined"
|
|
38
|
+
:aria-describedby="field.describedBy"
|
|
39
|
+
:class="[PICKER_TRIGGER, PICKER_SIZE[size], pickerTone(field.invalid)]"
|
|
40
|
+
>
|
|
41
|
+
<LpIcon :name="icon" :size="16" class="shrink-0 text-muted" />
|
|
42
|
+
<LpRollingText :value="display || placeholder" align="start" class="min-w-0 flex-1" :class="!display && 'text-muted'" />
|
|
43
|
+
<span v-if="clearable" class="w-[15px] shrink-0" aria-hidden="true" />
|
|
44
|
+
<LpIcon name="lucide:chevron-down" :size="15" class="shrink-0 text-muted transition-transform duration-[var(--duration-fast)] ease-[var(--ease-emphasized)] group-data-[state=open]:rotate-180 motion-reduce:transition-none" />
|
|
45
|
+
</button>
|
|
46
|
+
</template>
|
|
47
|
+
<div v-if="presets.length" role="group" :aria-label="presetsLabel" :class="[PICKER_PRESETS, presetsClass]">
|
|
48
|
+
<button v-for="(preset, i) in presets" :key="`${i}:${preset.label}`" type="button" :disabled="preset.disabled" :aria-pressed="preset.selected" :class="PICKER_PRESET" @click="preset.select">
|
|
49
|
+
{{ preset.label }}
|
|
50
|
+
</button>
|
|
51
|
+
</div>
|
|
52
|
+
<slot />
|
|
53
|
+
</LpPopover>
|
|
54
|
+
<button v-if="clearable" type="button" :aria-label="clearLabel" :class="PICKER_CLEAR" @click="$emit('clear')">
|
|
55
|
+
<LpIcon name="lucide:x" :size="15" />
|
|
56
|
+
</button>
|
|
57
|
+
</div>
|
|
58
|
+
</template>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/*
|
|
3
|
+
* The eye that shows and hides a value: LpPasswordInput's field, LpSecretField's
|
|
4
|
+
* display and LpCodeDisplay's code. One button so the three answer a click the
|
|
5
|
+
* same way: both eyes stay mounted and morph in place (lp-glyph-swap), the
|
|
6
|
+
* pressed state is announced, and the tooltip says what the next click does
|
|
7
|
+
* and doubles as the button's name. Internal; the fields expose it through
|
|
8
|
+
* their own `revealed`/`visible` models.
|
|
9
|
+
*/
|
|
10
|
+
import LpButton from "./LpButton.vue"
|
|
11
|
+
import LpIcon from "./LpIcon.vue"
|
|
12
|
+
import LpTooltip from "./LpTooltip.vue"
|
|
13
|
+
|
|
14
|
+
defineProps<{
|
|
15
|
+
/** Glyph size in px. The button's own size comes from the caller's class. */
|
|
16
|
+
iconSize: number
|
|
17
|
+
/** What the button says while the value is hidden, and while it is shown. */
|
|
18
|
+
showLabel: string
|
|
19
|
+
hideLabel: string
|
|
20
|
+
disabled?: boolean
|
|
21
|
+
/** Id of the element whose content this reveals. */
|
|
22
|
+
controls?: string
|
|
23
|
+
}>()
|
|
24
|
+
|
|
25
|
+
// The caller's class sizes the BUTTON (each field has its own), not the
|
|
26
|
+
// tooltip wrapper that is this component's root.
|
|
27
|
+
defineOptions({ inheritAttrs: false })
|
|
28
|
+
|
|
29
|
+
const revealed = defineModel<boolean>({ default: false })
|
|
30
|
+
</script>
|
|
31
|
+
|
|
32
|
+
<template>
|
|
33
|
+
<LpTooltip :content="revealed ? hideLabel : showLabel" label>
|
|
34
|
+
<LpButton
|
|
35
|
+
variant="ghost"
|
|
36
|
+
size="xs"
|
|
37
|
+
square
|
|
38
|
+
class="text-muted hover:text-ink"
|
|
39
|
+
v-bind="$attrs"
|
|
40
|
+
:disabled="disabled"
|
|
41
|
+
:aria-pressed="revealed"
|
|
42
|
+
:aria-controls="controls"
|
|
43
|
+
@click="revealed = !revealed"
|
|
44
|
+
>
|
|
45
|
+
<span class="grid place-items-center">
|
|
46
|
+
<LpIcon name="lucide:eye" :size="iconSize" class="lp-glyph-swap col-start-1 row-start-1" :data-on="!revealed || undefined" />
|
|
47
|
+
<LpIcon name="lucide:eye-off" :size="iconSize" class="lp-glyph-swap col-start-1 row-start-1" :data-on="revealed || undefined" />
|
|
48
|
+
</span>
|
|
49
|
+
</LpButton>
|
|
50
|
+
</LpTooltip>
|
|
51
|
+
</template>
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// The consumer's `class` is merged into the track's own rather than appended.
|
|
3
|
+
export default { inheritAttrs: false }
|
|
4
|
+
</script>
|
|
5
|
+
|
|
6
|
+
<script setup lang="ts">
|
|
7
|
+
/*
|
|
8
|
+
* The line between two steps, filled once the step it leaves is behind.
|
|
9
|
+
* Internal: LpStepper and LpPipeline both draw it, and it was two copies of
|
|
10
|
+
* the same track, fill and transition that had started to drift apart.
|
|
11
|
+
*
|
|
12
|
+
* The fill grows from the step it leaves towards the next one (scaled, so it
|
|
13
|
+
* eases on the compositor), which reads as moving forward. `flowing` runs a
|
|
14
|
+
* light along the empty line: the step is running and the work is on its way
|
|
15
|
+
* to the next. Thickness and margins are the caller's, through `class`.
|
|
16
|
+
*/
|
|
17
|
+
import { computed } from "vue"
|
|
18
|
+
import { useMergedAttrs } from "../composables/useMergedClass"
|
|
19
|
+
|
|
20
|
+
const props = withDefaults(
|
|
21
|
+
defineProps<{
|
|
22
|
+
filled: boolean
|
|
23
|
+
orientation?: "horizontal" | "vertical"
|
|
24
|
+
/** The fill's colour class: what the travelled part says (passed, skipped, done). */
|
|
25
|
+
fill?: string
|
|
26
|
+
flowing?: boolean
|
|
27
|
+
}>(),
|
|
28
|
+
{ orientation: "horizontal", fill: "bg-brand", flowing: false },
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
const across = computed(() => props.orientation === "horizontal")
|
|
32
|
+
|
|
33
|
+
const { class: trackClass, attrs: rest } = useMergedAttrs(() =>
|
|
34
|
+
`relative flex-1 overflow-hidden rounded-pill bg-line ${across.value ? "h-0.5" : "w-0.5"}`,
|
|
35
|
+
)
|
|
36
|
+
</script>
|
|
37
|
+
|
|
38
|
+
<template>
|
|
39
|
+
<span :class="trackClass" aria-hidden="true" v-bind="rest">
|
|
40
|
+
<span
|
|
41
|
+
class="absolute inset-0 transition-[scale,background-color] duration-(--duration-slow) ease-(--ease-emphasized) motion-reduce:transition-none"
|
|
42
|
+
:class="[
|
|
43
|
+
fill,
|
|
44
|
+
across ? 'origin-left rtl:origin-right' : 'origin-top',
|
|
45
|
+
filled ? (across ? 'scale-x-100' : 'scale-y-100') : across ? 'scale-x-0' : 'scale-y-0',
|
|
46
|
+
]"
|
|
47
|
+
/>
|
|
48
|
+
<span
|
|
49
|
+
v-if="flowing"
|
|
50
|
+
class="lp-sweep absolute from-transparent via-brand to-transparent [--sweep-to:200%]"
|
|
51
|
+
:class="across ? 'inset-y-0 left-0 w-1/2 bg-linear-to-r' : 'lp-sweep--y inset-x-0 top-0 h-1/2 bg-linear-to-b'"
|
|
52
|
+
/>
|
|
53
|
+
</span>
|
|
54
|
+
</template>
|
|
@@ -3,6 +3,9 @@ import type { TourStep } from "./LpTour.vue"
|
|
|
3
3
|
import LpButton from "./LpButton.vue"
|
|
4
4
|
import LpIcon from "./LpIcon.vue"
|
|
5
5
|
import LpKeys from "./LpKeys.vue"
|
|
6
|
+
import LpRollingText from "./LpRollingText.vue"
|
|
7
|
+
import LpShift from "./LpShift.vue"
|
|
8
|
+
import LpSwap from "./LpSwap.vue"
|
|
6
9
|
|
|
7
10
|
defineProps<{
|
|
8
11
|
step: TourStep | undefined
|
|
@@ -21,22 +24,32 @@ defineEmits<{
|
|
|
21
24
|
</script>
|
|
22
25
|
|
|
23
26
|
<template>
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
<div class="mt-4 flex items-center justify-between gap-2">
|
|
35
|
-
<span class="text-xs tabular-nums text-muted">{{ progress }}</span>
|
|
36
|
-
<div class="flex gap-2">
|
|
37
|
-
<LpButton v-if="index > 0" size="sm" variant="ghost" @click="$emit('back')">{{ labels.back }}</LpButton>
|
|
38
|
-
<LpButton v-if="step?.try && step.perform" size="sm" variant="outline" @click="$emit('perform')">{{ labels.perform }}</LpButton>
|
|
39
|
-
<LpButton size="sm" :variant="step?.try ? 'ghost' : undefined" @click="$emit('next')">{{ last ? labels.done : labels.next }}</LpButton>
|
|
27
|
+
<!-- A step is another piece of content in the same card: it swaps in and the
|
|
28
|
+
card eases to its height (LpSwap), the count and the main button roll,
|
|
29
|
+
and the button row eases when Back joins it, so moving on reads as the
|
|
30
|
+
card turning a page rather than being redrawn. -->
|
|
31
|
+
<LpSwap :swap-key="index">
|
|
32
|
+
<div class="flex items-start justify-between gap-3">
|
|
33
|
+
<p class="font-medium" aria-live="polite">{{ step?.title }}</p>
|
|
34
|
+
<button type="button" class="text-muted hover:text-ink" :aria-label="labels.close" @click="$emit('dismiss')">
|
|
35
|
+
<LpIcon name="lucide:x" class="size-4" />
|
|
36
|
+
</button>
|
|
40
37
|
</div>
|
|
38
|
+
<p v-if="step?.text" class="mt-1.5 text-muted">{{ step.text }}</p>
|
|
39
|
+
<LpKeys v-if="step?.keys" :combo="step.keys" size="sm" class="mt-2" />
|
|
40
|
+
<p v-if="step?.try" class="mt-2 text-xs text-brand">{{ labels.tryIt }}</p>
|
|
41
|
+
<p v-if="step?.example" class="mt-2 text-xs text-muted">{{ labels.example }}</p>
|
|
42
|
+
</LpSwap>
|
|
43
|
+
<div class="mt-4 flex items-center justify-between gap-2">
|
|
44
|
+
<LpRollingText class="text-xs tabular-nums text-muted" :value="progress" align="start" />
|
|
45
|
+
<LpShift axis="width">
|
|
46
|
+
<div class="flex gap-2">
|
|
47
|
+
<LpButton v-if="index > 0" size="sm" variant="ghost" @click="$emit('back')">{{ labels.back }}</LpButton>
|
|
48
|
+
<LpButton v-if="step?.try && step.perform" size="sm" variant="outline" @click="$emit('perform')">{{ labels.perform }}</LpButton>
|
|
49
|
+
<LpButton size="sm" :variant="step?.try ? 'ghost' : undefined" @click="$emit('next')">
|
|
50
|
+
<LpRollingText :value="last ? labels.done : labels.next" />
|
|
51
|
+
</LpButton>
|
|
52
|
+
</div>
|
|
53
|
+
</LpShift>
|
|
41
54
|
</div>
|
|
42
55
|
</template>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* The remove control on a chip (LpBadge `removable`): a small round ✕ that
|
|
3
|
+
* tints on hover. Exported for a chip whose remove control has to be another
|
|
4
|
+
* primitive's (reka's TagsInputItemDelete in LpTagsInput, which owns the
|
|
5
|
+
* keyboard handling), so it still looks like the badge's own.
|
|
6
|
+
*/
|
|
7
|
+
export const BADGE_REMOVE =
|
|
8
|
+
"grid size-4 shrink-0 place-items-center rounded-pill text-muted outline-none transition-colors duration-fast hover:bg-ink/10 hover:text-ink focus-visible:ring-2 focus-visible:ring-ring"
|
package/src/components/chart.ts
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
* pixel box, return paths and tick positions.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import { compactNumber } from "./format"
|
|
8
|
+
|
|
7
9
|
export interface ChartPoint {
|
|
8
10
|
/** Numeric value. `null` breaks the line — a real gap, not a zero. */
|
|
9
11
|
y: number | null
|
|
@@ -761,26 +763,9 @@ export const calloutLabels = (
|
|
|
761
763
|
return out
|
|
762
764
|
}
|
|
763
765
|
|
|
764
|
-
/**
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
[1e9, "B"],
|
|
771
|
-
[1e12, "T"],
|
|
772
|
-
]
|
|
773
|
-
const abs = Math.abs(v)
|
|
774
|
-
let i = units.length - 1
|
|
775
|
-
while (i >= 0 && abs < units[i][0]) i--
|
|
776
|
-
if (i < 0) {
|
|
777
|
-
const plain = Number(v.toFixed(2))
|
|
778
|
-
return Math.abs(plain) >= 1000 ? formatTick(Math.sign(v) * 1000) : String(plain)
|
|
779
|
-
}
|
|
780
|
-
const scaled = Number((v / units[i][0]).toFixed(1))
|
|
781
|
-
// 999 950 rounds to "1000k"; it reads as the next unit up.
|
|
782
|
-
if (Math.abs(scaled) >= 1000 && i < units.length - 1) {
|
|
783
|
-
return `${Number((v / units[i + 1][0]).toFixed(1))}${units[i + 1][1]}`
|
|
784
|
-
}
|
|
785
|
-
return `${scaled}${units[i][1]}`
|
|
786
|
-
}
|
|
766
|
+
/**
|
|
767
|
+
* Compact default tick formatting: 1.2k, 3.4M — never 1200.0000001 or 1000k.
|
|
768
|
+
* One argument on purpose: it is handed around as a formatter, and an index
|
|
769
|
+
* passed by `map` must not land in an options slot.
|
|
770
|
+
*/
|
|
771
|
+
export const formatTick = (v: number): string => compactNumber(v)
|
|
@@ -184,3 +184,28 @@ export function dayAllowed(iso: string, rules: DayRules = {}): boolean {
|
|
|
184
184
|
if (rules.isDisabled?.(value)) return false
|
|
185
185
|
return !rules.isDateUnavailable?.(value)
|
|
186
186
|
}
|
|
187
|
+
|
|
188
|
+
export interface RangeRules extends DayRules {
|
|
189
|
+
/** Longest range, in days, counting both ends. */
|
|
190
|
+
maximumDays?: number
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* A preset's range under the same rules as one picked on the calendar: trimmed
|
|
195
|
+
* to min/max, then refused if either end is a disabled day, it is longer than
|
|
196
|
+
* maximumDays, or a day inside it is unavailable. A preset that breaks them is
|
|
197
|
+
* shown disabled instead of writing a range the calendar would never allow.
|
|
198
|
+
*/
|
|
199
|
+
export function allowedRange(range: DateRange, rules: RangeRules = {}): DateRange | undefined {
|
|
200
|
+
const trimmed = clampRange(range, rules.min, rules.max)
|
|
201
|
+
if (!trimmed) return undefined
|
|
202
|
+
const end = (iso: string) => !rules.isDisabled?.(iso)
|
|
203
|
+
if (!end(trimmed.start)) return undefined
|
|
204
|
+
return (
|
|
205
|
+
reshapeRange(trimmed.start, trimmed.end, {
|
|
206
|
+
allowed: end,
|
|
207
|
+
unavailable: rules.isDateUnavailable,
|
|
208
|
+
maximumDays: rules.maximumDays,
|
|
209
|
+
}) ?? undefined
|
|
210
|
+
)
|
|
211
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Magnification curve for LpDock, apart from the component for testing.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Size of an item whose centre is `distance` px from the pointer.
|
|
7
|
+
*
|
|
8
|
+
* A raised cosine: full size right under the pointer, falling smoothly to the
|
|
9
|
+
* resting size at `radius` and flat beyond it. A linear falloff has a corner
|
|
10
|
+
* at the peak, which shows as the hovered icon "ticking" between sizes while
|
|
11
|
+
* the pointer crosses it.
|
|
12
|
+
*/
|
|
13
|
+
export function dockSize(base: number, max: number, distance: number, radius: number): number {
|
|
14
|
+
const d = Math.abs(distance)
|
|
15
|
+
if (radius <= 0 || d >= radius) return base
|
|
16
|
+
return base + (max - base) * ((Math.cos((Math.PI * d) / radius) + 1) / 2)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Offset of a magnetic element toward a pointer at (`dx`, `dy`) px from its
|
|
21
|
+
* centre (LpMagnetic). Zero beyond `reach`; inside it the pull is a fraction
|
|
22
|
+
* of the distance that fades out toward the edge of the field, so the element
|
|
23
|
+
* lets go gradually instead of snapping back at an invisible line.
|
|
24
|
+
*/
|
|
25
|
+
export function magneticOffset(dx: number, dy: number, reach: number, strength: number): { x: number; y: number } {
|
|
26
|
+
const distance = Math.hypot(dx, dy)
|
|
27
|
+
if (reach <= 0 || distance >= reach) return { x: 0, y: 0 }
|
|
28
|
+
const falloff = 1 - distance / reach
|
|
29
|
+
const pull = Math.max(0, strength) * falloff
|
|
30
|
+
return { x: dx * pull, y: dy * pull }
|
|
31
|
+
}
|
|
@@ -13,6 +13,9 @@
|
|
|
13
13
|
* the right way when the list flips above the trigger.
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
+
|
|
17
|
+
import { staggerDelay } from "./reveal"
|
|
18
|
+
|
|
16
19
|
/** Enter/exit animation for state-open panels (Select, Popover, Dropdown, …). */
|
|
17
20
|
export const POPOVER_ANIM =
|
|
18
21
|
"data-[state=open]:animate-[popover-in_140ms_var(--ease-emphasized)] " +
|
|
@@ -46,14 +49,23 @@ export const POPOVER_PANEL = PANEL_SURFACE + " " + POPOVER_ANIM
|
|
|
46
49
|
* A selectable option row: layout, highlight state, and the staggered cascade.
|
|
47
50
|
* Cascades downward by default and upward when the panel is flipped above the
|
|
48
51
|
* trigger (group-data-[side=top]). Pair with an inline animationDelay for the
|
|
49
|
-
* stagger. `flex` + gap are included; add justify/extra layout if needed.
|
|
52
|
+
* stagger (optionStagger). `flex` + gap are included; add justify/extra layout if needed.
|
|
50
53
|
*/
|
|
51
54
|
export const OPTION_ITEM =
|
|
52
55
|
"flex cursor-pointer items-center gap-2 rounded-inner px-2.5 py-1.5 text-sm text-ink outline-none " +
|
|
53
|
-
"animate-[
|
|
54
|
-
"group-data-[side=top]:animate-[option-in-up_180ms_var(--ease-emphasized)_both] " +
|
|
56
|
+
"animate-[rise-in_180ms_var(--ease-emphasized)_both] [--rise:-6px] group-data-[side=top]:[--rise:6px] " +
|
|
55
57
|
"data-[highlighted]:bg-brand-soft data-[highlighted]:text-brand"
|
|
56
58
|
|
|
59
|
+
/**
|
|
60
|
+
* The cascade's delay for the option at `index`, as an inline style for the
|
|
61
|
+
* row: 22 ms apart, and from the 12th on every option arrives together, so a
|
|
62
|
+
* long list still lands at once. Select, Autocomplete, PhoneInput and
|
|
63
|
+
* TagsInput each had this formula written out.
|
|
64
|
+
*/
|
|
65
|
+
export const optionStagger = (index: number): { animationDelay: string } => ({
|
|
66
|
+
animationDelay: `${staggerDelay(index, 0, 22, 12)}ms`,
|
|
67
|
+
})
|
|
68
|
+
|
|
57
69
|
/**
|
|
58
70
|
* Micro-animation for a close / clear "✕" icon: a quarter-turn on hover and a
|
|
59
71
|
* dip on press. Put on the <LpIcon>, with `group` on its button. Shared by
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Pure text helpers behind the "fields and text" components: grouping a code
|
|
3
|
+
* for reading aloud (LpCodeDisplay, LpOtpInput) and cutting a string out of its middle (LpTruncate). Kept apart from the
|
|
4
|
+
* components so the rules can be tested without a DOM.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { ceilToSecond, formatTime } from "./timeSpan"
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Splits a code into the groups a person reads it in.
|
|
11
|
+
*
|
|
12
|
+
* `groups` is either one size for every group ("4" → `ABCD EFGH IJ`) or the
|
|
13
|
+
* exact sizes in order (`[3, 3]` → `123 456`), the latter for formats whose
|
|
14
|
+
* groups differ (a licence key `5-5-5-5`, a card `4-6-5`). Characters past
|
|
15
|
+
* the listed sizes form one last group rather than being dropped: a code is
|
|
16
|
+
* never shown shorter than it is. Without `groups`, short codes read best in
|
|
17
|
+
* threes (6 → 3+3, 8 → 4+4) and longer ones in fours.
|
|
18
|
+
*/
|
|
19
|
+
export function groupCode(code: string, groups?: number | number[]): string[] {
|
|
20
|
+
const chars = Array.from(code)
|
|
21
|
+
if (!chars.length) return []
|
|
22
|
+
const sizes = Array.isArray(groups)
|
|
23
|
+
? groups.filter((n) => n > 0)
|
|
24
|
+
: [groups && groups > 0 ? groups : autoGroup(chars.length)]
|
|
25
|
+
const out: string[] = []
|
|
26
|
+
let at = 0
|
|
27
|
+
let i = 0
|
|
28
|
+
while (at < chars.length) {
|
|
29
|
+
const size = Array.isArray(groups) ? (sizes[i] ?? chars.length - at) : sizes[0]!
|
|
30
|
+
out.push(chars.slice(at, at + size).join(""))
|
|
31
|
+
at += size
|
|
32
|
+
i++
|
|
33
|
+
}
|
|
34
|
+
return out
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function autoGroup(length: number): number {
|
|
38
|
+
if (length <= 4) return length
|
|
39
|
+
if (length === 6 || length === 9) return 3
|
|
40
|
+
if (length % 4 === 0) return 4
|
|
41
|
+
if (length % 3 === 0) return 3
|
|
42
|
+
return 4
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Strips what people and copy-paste add to a code: spaces, dashes, dots. */
|
|
46
|
+
export function normalizeCode(code: string): string {
|
|
47
|
+
return code.replace(/[\s\-_.·]/g, "")
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* A remaining time the way a countdown shows it: `0:42`, `4:05`, `1:02:03`.
|
|
52
|
+
* Rounded UP to the second, so "0:00" only ever appears once time is out.
|
|
53
|
+
*
|
|
54
|
+
* @deprecated LpCountdown's own formatting, kept for apps that imported it:
|
|
55
|
+
* use `formatTime(ceilToSecond(ms), "clock")` from the time-span helpers.
|
|
56
|
+
*/
|
|
57
|
+
export function formatRemaining(ms: number): string {
|
|
58
|
+
return formatTime(ceilToSecond(ms), "clock")
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* The longest `start…end` cut of `text` that `fits`, keeping both ends.
|
|
63
|
+
*
|
|
64
|
+
* For identifiers whose meaning sits at both ends: a path's root and file
|
|
65
|
+
* name, a hash's first and last characters people compare, a server id's
|
|
66
|
+
* prefix and number. An ellipsis at the end would throw away exactly the part
|
|
67
|
+
* that tells two of them apart.
|
|
68
|
+
*
|
|
69
|
+
* `tail` pins how many characters the end keeps (an extension, the last
|
|
70
|
+
* digits); without it both ends shrink evenly. `fits` is the measurement —
|
|
71
|
+
* the component passes a canvas measure of its own font — so the search
|
|
72
|
+
* itself stays a pure binary search over how many characters survive.
|
|
73
|
+
*/
|
|
74
|
+
export function middleTruncate(
|
|
75
|
+
text: string,
|
|
76
|
+
fits: (candidate: string) => boolean,
|
|
77
|
+
options: { tail?: number; ellipsis?: string } = {},
|
|
78
|
+
): string {
|
|
79
|
+
const ellipsis = options.ellipsis ?? "…"
|
|
80
|
+
const chars = Array.from(text)
|
|
81
|
+
if (fits(text)) return text
|
|
82
|
+
const cut = (keep: number): string => {
|
|
83
|
+
const tail = options.tail !== undefined ? Math.min(options.tail, keep) : Math.floor(keep / 2)
|
|
84
|
+
const head = keep - tail
|
|
85
|
+
return chars.slice(0, head).join("") + ellipsis + (tail ? chars.slice(chars.length - tail).join("") : "")
|
|
86
|
+
}
|
|
87
|
+
let lo = 0
|
|
88
|
+
let hi = chars.length - 1
|
|
89
|
+
while (lo < hi) {
|
|
90
|
+
const mid = Math.ceil((lo + hi) / 2)
|
|
91
|
+
if (fits(cut(mid))) lo = mid
|
|
92
|
+
else hi = mid - 1
|
|
93
|
+
}
|
|
94
|
+
return cut(lo)
|
|
95
|
+
}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import type { ContextMenuItemDef } from "./LpContextMenu.vue"
|
|
8
|
+
import { formatBytes } from "./format"
|
|
8
9
|
|
|
9
10
|
export interface FileNode {
|
|
10
11
|
/** Stable identity — use the full path when you have one. */
|
|
@@ -119,33 +120,30 @@ export function sortNodes(nodes: FileNode[]): FileNode[] {
|
|
|
119
120
|
})
|
|
120
121
|
}
|
|
121
122
|
|
|
122
|
-
/**
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
// Compare the value as it will print, so 1 048 575 B is "1.0 MB", not "1024 KB".
|
|
130
|
-
while (Math.round(value) >= 1024 && i < units.length - 1) {
|
|
131
|
-
value /= 1024
|
|
132
|
-
i++
|
|
133
|
-
}
|
|
134
|
-
// One decimal below 10 (2.4 MB), none above (240 MB) — keeps the column tidy.
|
|
135
|
-
return `${value < 10 ? value.toFixed(1) : Math.round(value)} ${units[i]}`
|
|
123
|
+
/**
|
|
124
|
+
* Human-readable byte size for the size column (`formatBytes`, binary units,
|
|
125
|
+
* matching what file managers show). The decimal is kept even when it is zero
|
|
126
|
+
* ("1.0 MB") so the column holds one shape from row to row.
|
|
127
|
+
*/
|
|
128
|
+
export function formatSize(bytes: number, locale?: string): string {
|
|
129
|
+
return formatBytes(bytes, locale, { fixed: true })
|
|
136
130
|
}
|
|
137
131
|
|
|
132
|
+
const modifiedFormats = new Map<string, Intl.DateTimeFormat>()
|
|
133
|
+
|
|
138
134
|
/** Short local date-time for the modified column; passes strings through. */
|
|
139
|
-
export function formatModified(value: Date | number | string): string {
|
|
135
|
+
export function formatModified(value: Date | number | string, locale?: string): string {
|
|
140
136
|
if (typeof value === "string") return value
|
|
141
137
|
const date = value instanceof Date ? value : new Date(value)
|
|
142
138
|
if (Number.isNaN(date.getTime())) return "—"
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
minute: "2-digit"
|
|
148
|
-
|
|
139
|
+
// Built once per locale: the column formats a date on every row.
|
|
140
|
+
const key = locale ?? ""
|
|
141
|
+
let format = modifiedFormats.get(key)
|
|
142
|
+
if (!format) {
|
|
143
|
+
format = new Intl.DateTimeFormat(locale, { day: "2-digit", month: "short", hour: "2-digit", minute: "2-digit" })
|
|
144
|
+
modifiedFormats.set(key, format)
|
|
145
|
+
}
|
|
146
|
+
return format.format(date)
|
|
149
147
|
}
|
|
150
148
|
|
|
151
149
|
/**
|