@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,40 @@
|
|
|
1
|
+
function masonryColumnCount(width, options) {
|
|
2
|
+
const { columns, minColumnWidth, maxColumns, gap } = options;
|
|
3
|
+
if (typeof columns === "number") return Math.max(1, Math.floor(columns));
|
|
4
|
+
if (columns) {
|
|
5
|
+
let picked = 1;
|
|
6
|
+
let best = -Infinity;
|
|
7
|
+
for (const [min, count] of Object.entries(columns)) {
|
|
8
|
+
const at = Number(min);
|
|
9
|
+
if (width >= at && at > best) {
|
|
10
|
+
best = at;
|
|
11
|
+
picked = count;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return Math.max(1, Math.floor(picked));
|
|
15
|
+
}
|
|
16
|
+
const fit = Math.floor((width + gap) / (Math.max(1, minColumnWidth) + gap));
|
|
17
|
+
return Math.max(1, Math.min(fit, maxColumns ?? Infinity));
|
|
18
|
+
}
|
|
19
|
+
function placeMasonry(heights, count, width, gap) {
|
|
20
|
+
const columns = Math.max(1, count);
|
|
21
|
+
const columnWidth = Math.max(0, (width - gap * (columns - 1)) / columns);
|
|
22
|
+
const bottoms = new Array(columns).fill(0);
|
|
23
|
+
const x = [];
|
|
24
|
+
const y = [];
|
|
25
|
+
const column = [];
|
|
26
|
+
for (const height of heights) {
|
|
27
|
+
let shortest = 0;
|
|
28
|
+
for (let c = 1; c < columns; c += 1) if (bottoms[c] < bottoms[shortest] - 0.5) shortest = c;
|
|
29
|
+
x.push(shortest * (columnWidth + gap));
|
|
30
|
+
y.push(bottoms[shortest]);
|
|
31
|
+
column.push(shortest);
|
|
32
|
+
bottoms[shortest] = bottoms[shortest] + Math.max(0, height) + gap;
|
|
33
|
+
}
|
|
34
|
+
const tallest = Math.max(0, ...bottoms);
|
|
35
|
+
return { x, y, column, columnWidth, height: heights.length ? tallest - gap : 0 };
|
|
36
|
+
}
|
|
37
|
+
export {
|
|
38
|
+
masonryColumnCount,
|
|
39
|
+
placeMasonry
|
|
40
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The semantic tones a meter speaks in. They name what the reading MEANS, not
|
|
3
|
+
* which colour it is: a theme decides the colour, and `ok` stays the "fine"
|
|
4
|
+
* colour whatever that happens to be.
|
|
5
|
+
*/
|
|
6
|
+
export type MeterTone = "ok" | "warning" | "danger" | "brand" | "neutral";
|
|
7
|
+
/** One step of a scale: from `at` (in the meter's own units) upward, `tone`. */
|
|
8
|
+
export interface MeterThreshold {
|
|
9
|
+
at: number;
|
|
10
|
+
tone: MeterTone;
|
|
11
|
+
}
|
|
12
|
+
/** The solid colour of a tone, as a CSS value a style or an SVG stroke takes. */
|
|
13
|
+
export declare const TONE_COLOR: Record<MeterTone, string>;
|
|
14
|
+
/** The tinted background of a tone, for pills and highlighted rows. */
|
|
15
|
+
export declare const TONE_SOFT: Record<MeterTone, string>;
|
|
16
|
+
/**
|
|
17
|
+
* Where `value` sits between `min` and `max`, as 0–1. An empty or inverted
|
|
18
|
+
* range (no limit known yet) reads as empty rather than as NaN or Infinity,
|
|
19
|
+
* which would otherwise reach an SVG attribute and draw nothing at all.
|
|
20
|
+
*/
|
|
21
|
+
export declare function meterFraction(value: number, min: number, max: number): number;
|
|
22
|
+
/**
|
|
23
|
+
* The capacity scale every finite resource is read against: comfortable well
|
|
24
|
+
* past half, uncomfortable in the last fifth, urgent in the last tenth. The
|
|
25
|
+
* same breakpoints LpProgress's `auto` tone uses, so the two never disagree
|
|
26
|
+
* about one disk.
|
|
27
|
+
*/
|
|
28
|
+
export declare function capacityThresholds(min: number, max: number, warnAt?: number, dangerAt?: number): MeterThreshold[];
|
|
29
|
+
/**
|
|
30
|
+
* The tone a reading earns on a scale. Thresholds are steps, not bands: each
|
|
31
|
+
* one holds from its `at` until the next, and below the first the reading is
|
|
32
|
+
* `base`. Sorted here, so a caller can list them in whatever order reads best.
|
|
33
|
+
*
|
|
34
|
+
* Steps go either way, which is what lets one shape describe both "higher is
|
|
35
|
+
* worse" (load: ok → warning → danger) and "higher is better" (a score:
|
|
36
|
+
* danger from 0, warning from 50, ok from 80).
|
|
37
|
+
*/
|
|
38
|
+
export declare function toneAt(value: number, thresholds: readonly MeterThreshold[], base?: MeterTone): MeterTone;
|
|
39
|
+
/**
|
|
40
|
+
* The track a bar meter fills, shared so LpProgress's bar and LpQuota's read as
|
|
41
|
+
* one family. Each adds its own clipping: a progress bar clips its fill, a
|
|
42
|
+
* quota lets its limit mark stand out past the track.
|
|
43
|
+
*/
|
|
44
|
+
export declare const METER_TRACK = "h-1.5 w-full rounded-pill bg-surface-soft";
|
|
45
|
+
/** The row above a bar: what is measured at the start, the reading at the end. Each sets its own size and gap. */
|
|
46
|
+
export declare const METER_HEADER = "flex items-baseline justify-between";
|
|
47
|
+
/**
|
|
48
|
+
* A point on a circle, with the angle in degrees clockwise from twelve
|
|
49
|
+
* o'clock — the way a dial is read, so -90 is nine o'clock and 90 is three.
|
|
50
|
+
*/
|
|
51
|
+
export declare function polar(cx: number, cy: number, r: number, deg: number): {
|
|
52
|
+
x: number;
|
|
53
|
+
y: number;
|
|
54
|
+
};
|
|
55
|
+
/** An SVG path along a circle from one angle to another, clockwise. */
|
|
56
|
+
export declare function arcPath(cx: number, cy: number, r: number, from: number, to: number): string;
|
|
57
|
+
/**
|
|
58
|
+
* The sweep of each gauge shape, as [start, end] angles. A semicircle reads
|
|
59
|
+
* left to right across the top; the full dial opens at the bottom, a 270°
|
|
60
|
+
* sweep, because a closed circle has no visible start or end and that is
|
|
61
|
+
* LpProgress's ring, a different thing (progress toward done, not a reading
|
|
62
|
+
* within a range).
|
|
63
|
+
*/
|
|
64
|
+
export declare const GAUGE_SWEEP: Record<"semi" | "full", readonly [number, number]>;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { TONES, TONE_ALIASES } from "./tone.js";
|
|
2
|
+
const METER_TONES = ["ok", "warning", "danger", "brand", "neutral"];
|
|
3
|
+
const byMeterTone = (pick) => Object.fromEntries(METER_TONES.map((t) => [t, pick(TONES[TONE_ALIASES[t]])]));
|
|
4
|
+
const TONE_COLOR = byMeterTone((look) => look.color);
|
|
5
|
+
const TONE_SOFT = byMeterTone((look) => look.soft);
|
|
6
|
+
function meterFraction(value, min, max) {
|
|
7
|
+
const span = max - min;
|
|
8
|
+
if (!(span > 0) || !Number.isFinite(value)) return 0;
|
|
9
|
+
return Math.max(0, Math.min(1, (value - min) / span));
|
|
10
|
+
}
|
|
11
|
+
function capacityThresholds(min, max, warnAt = 0.8, dangerAt = 0.9) {
|
|
12
|
+
const span = max - min;
|
|
13
|
+
return [
|
|
14
|
+
{ at: min + span * warnAt, tone: "warning" },
|
|
15
|
+
{ at: min + span * dangerAt, tone: "danger" }
|
|
16
|
+
];
|
|
17
|
+
}
|
|
18
|
+
function toneAt(value, thresholds, base = "ok") {
|
|
19
|
+
let tone = base;
|
|
20
|
+
for (const step of [...thresholds].sort((a, b) => a.at - b.at)) {
|
|
21
|
+
if (value >= step.at) tone = step.tone;
|
|
22
|
+
}
|
|
23
|
+
return tone;
|
|
24
|
+
}
|
|
25
|
+
const METER_TRACK = "h-1.5 w-full rounded-pill bg-surface-soft";
|
|
26
|
+
const METER_HEADER = "flex items-baseline justify-between";
|
|
27
|
+
function polar(cx, cy, r, deg) {
|
|
28
|
+
const rad = deg * Math.PI / 180;
|
|
29
|
+
return { x: cx + r * Math.sin(rad), y: cy - r * Math.cos(rad) };
|
|
30
|
+
}
|
|
31
|
+
function arcPath(cx, cy, r, from, to) {
|
|
32
|
+
const a = polar(cx, cy, r, from);
|
|
33
|
+
const b = polar(cx, cy, r, to);
|
|
34
|
+
const large = to - from > 180 ? 1 : 0;
|
|
35
|
+
const f = (n) => Number(n.toFixed(3));
|
|
36
|
+
return `M ${f(a.x)} ${f(a.y)} A ${f(r)} ${f(r)} 0 ${large} 1 ${f(b.x)} ${f(b.y)}`;
|
|
37
|
+
}
|
|
38
|
+
const GAUGE_SWEEP = {
|
|
39
|
+
semi: [-90, 90],
|
|
40
|
+
full: [-135, 135]
|
|
41
|
+
};
|
|
42
|
+
export {
|
|
43
|
+
GAUGE_SWEEP,
|
|
44
|
+
METER_HEADER,
|
|
45
|
+
METER_TRACK,
|
|
46
|
+
TONE_COLOR,
|
|
47
|
+
TONE_SOFT,
|
|
48
|
+
arcPath,
|
|
49
|
+
capacityThresholds,
|
|
50
|
+
meterFraction,
|
|
51
|
+
polar,
|
|
52
|
+
toneAt
|
|
53
|
+
};
|
package/dist/components/otp.d.ts
CHANGED
|
@@ -4,4 +4,4 @@ export declare function joinCells(cells: OtpCells): string;
|
|
|
4
4
|
/** Cells for a code given from outside, one character each. */
|
|
5
5
|
export declare function splitCode(code: string | undefined, length: number): string[];
|
|
6
6
|
export declare function upperCells<T extends OtpCells>(cells: T): T;
|
|
7
|
-
export declare function groupBreaks(length: number, group: number | undefined): Set<number>;
|
|
7
|
+
export declare function groupBreaks(length: number, group: number | number[] | undefined): Set<number>;
|
package/dist/components/otp.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { groupCode } from "./fieldText.js";
|
|
1
2
|
function joinCells(cells) {
|
|
2
3
|
return Array.from(cells, (c) => c === void 0 ? "" : String(c)).join("");
|
|
3
4
|
}
|
|
@@ -14,8 +15,12 @@ function upperCells(cells) {
|
|
|
14
15
|
}
|
|
15
16
|
function groupBreaks(length, group) {
|
|
16
17
|
const breaks = /* @__PURE__ */ new Set();
|
|
17
|
-
if (
|
|
18
|
-
|
|
18
|
+
if (Array.isArray(group) ? !group.some((n) => n > 0) : !group || group < 1) return breaks;
|
|
19
|
+
let at = 0;
|
|
20
|
+
for (const block of groupCode("x".repeat(Math.max(0, length)), group)) {
|
|
21
|
+
at += block.length;
|
|
22
|
+
if (at < length) breaks.add(at - 1);
|
|
23
|
+
}
|
|
19
24
|
return breaks;
|
|
20
25
|
}
|
|
21
26
|
export {
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export type StepStatus = "pending" | "running" | "success" | "failed" | "skipped" | "cancelled";
|
|
2
|
+
export interface PipelineStep {
|
|
3
|
+
label: string;
|
|
4
|
+
/** Stable id: what `expanded` and the `step` slot address. Defaults to the index. */
|
|
5
|
+
key?: string;
|
|
6
|
+
status: StepStatus;
|
|
7
|
+
/** A line under the label: the command, the host, the reason it was skipped. */
|
|
8
|
+
description?: string;
|
|
9
|
+
/** Replaces the glyph while the step is pending (a step that is "deploy" more than "3"). */
|
|
10
|
+
icon?: string;
|
|
11
|
+
/**
|
|
12
|
+
* Time the step took, in ms. When it is not known yet, `startedAt` (and
|
|
13
|
+
* `finishedAt`) let the pipeline work it out — and keep a running step's
|
|
14
|
+
* clock ticking without the app re-sending it every second.
|
|
15
|
+
*/
|
|
16
|
+
duration?: number;
|
|
17
|
+
startedAt?: Date | string | number;
|
|
18
|
+
finishedAt?: Date | string | number;
|
|
19
|
+
/** Jobs inside this one, shown when the step is expanded (vertical layout). */
|
|
20
|
+
steps?: PipelineStep[];
|
|
21
|
+
}
|
|
22
|
+
/** Done, one way or another: nothing more will happen to the step. */
|
|
23
|
+
export declare function isSettled(status: StepStatus): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Whether the line leaving a step is drawn as travelled. A step that passed
|
|
26
|
+
* or was skipped hands over to the next; one that failed or was cancelled is
|
|
27
|
+
* where the run stopped, so the line after it stays empty — the break in the
|
|
28
|
+
* line is the place to look.
|
|
29
|
+
*/
|
|
30
|
+
export declare function connectorFilled(status: StepStatus): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* The step a viewer is following: the running one, else the first that has
|
|
33
|
+
* not run yet after something has, else the last failure. -1 when the run has
|
|
34
|
+
* not started or is cleanly over.
|
|
35
|
+
*/
|
|
36
|
+
export declare function currentStepIndex(steps: readonly Pick<PipelineStep, "status">[]): number;
|
|
37
|
+
/**
|
|
38
|
+
* What the run amounts to. A failure anywhere outranks everything (one red
|
|
39
|
+
* job fails the build), then work in progress, then a cancellation; a run of
|
|
40
|
+
* passes and skips is a pass. Nothing started is pending.
|
|
41
|
+
*/
|
|
42
|
+
export declare function overallStatus(steps: readonly Pick<PipelineStep, "status">[]): StepStatus;
|
|
43
|
+
/**
|
|
44
|
+
* Ms a step has taken, as of `now`. An explicit `duration` wins; otherwise
|
|
45
|
+
* from `startedAt` to `finishedAt`, or to `now` while it is still running.
|
|
46
|
+
* null when there is nothing to say (pending, or no times given).
|
|
47
|
+
*/
|
|
48
|
+
export declare function stepElapsed(step: PipelineStep, now: number): number | null;
|
|
49
|
+
/** "2/5": finished children out of all, for a step whose inside is folded away. */
|
|
50
|
+
export declare function childProgress(step: PipelineStep): {
|
|
51
|
+
done: number;
|
|
52
|
+
total: number;
|
|
53
|
+
} | null;
|
|
54
|
+
/** The key a step is addressed by. */
|
|
55
|
+
export declare function stepKey(step: Pick<PipelineStep, "key">, index: number): string;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { toEpoch } from "./timeSpan.js";
|
|
2
|
+
function isSettled(status) {
|
|
3
|
+
return status !== "pending" && status !== "running";
|
|
4
|
+
}
|
|
5
|
+
function connectorFilled(status) {
|
|
6
|
+
return status === "success" || status === "skipped";
|
|
7
|
+
}
|
|
8
|
+
function currentStepIndex(steps) {
|
|
9
|
+
const running = steps.findIndex((s) => s.status === "running");
|
|
10
|
+
if (running !== -1) return running;
|
|
11
|
+
const failed = steps.findIndex((s) => s.status === "failed");
|
|
12
|
+
if (failed !== -1) return failed;
|
|
13
|
+
const started = steps.some((s) => isSettled(s.status));
|
|
14
|
+
if (!started) return -1;
|
|
15
|
+
return steps.findIndex((s) => s.status === "pending");
|
|
16
|
+
}
|
|
17
|
+
function overallStatus(steps) {
|
|
18
|
+
if (steps.length === 0) return "pending";
|
|
19
|
+
const has = (s) => steps.some((step) => step.status === s);
|
|
20
|
+
if (has("failed")) return "failed";
|
|
21
|
+
if (has("running")) return "running";
|
|
22
|
+
if (has("cancelled")) return "cancelled";
|
|
23
|
+
if (steps.every((s) => s.status === "skipped")) return "skipped";
|
|
24
|
+
if (steps.every((s) => s.status === "success" || s.status === "skipped")) return "success";
|
|
25
|
+
if (steps.some((s) => isSettled(s.status))) return "running";
|
|
26
|
+
return "pending";
|
|
27
|
+
}
|
|
28
|
+
function stepElapsed(step, now) {
|
|
29
|
+
if (typeof step.duration === "number" && Number.isFinite(step.duration)) return Math.max(0, step.duration);
|
|
30
|
+
const start = toEpoch(step.startedAt);
|
|
31
|
+
if (Number.isNaN(start)) return null;
|
|
32
|
+
const end = toEpoch(step.finishedAt);
|
|
33
|
+
if (!Number.isNaN(end)) return Math.max(0, end - start);
|
|
34
|
+
return step.status === "running" ? Math.max(0, now - start) : null;
|
|
35
|
+
}
|
|
36
|
+
function childProgress(step) {
|
|
37
|
+
if (!step.steps?.length) return null;
|
|
38
|
+
return { done: step.steps.filter((s) => isSettled(s.status)).length, total: step.steps.length };
|
|
39
|
+
}
|
|
40
|
+
function stepKey(step, index) {
|
|
41
|
+
return step.key ?? String(index);
|
|
42
|
+
}
|
|
43
|
+
export {
|
|
44
|
+
childProgress,
|
|
45
|
+
connectorFilled,
|
|
46
|
+
currentStepIndex,
|
|
47
|
+
isSettled,
|
|
48
|
+
overallStatus,
|
|
49
|
+
stepElapsed,
|
|
50
|
+
stepKey
|
|
51
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { type MeterTone } from "./meter";
|
|
2
|
+
/** One part of what is used, for a stacked bar ("Images 12 GB, Backups 30 GB"). */
|
|
3
|
+
export interface QuotaPart {
|
|
4
|
+
label: string;
|
|
5
|
+
value: number;
|
|
6
|
+
/** Any CSS colour. Unset parts take the chart palette in order, like LpChart's series (minus danger). */
|
|
7
|
+
color?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* How amounts are written. `"bytes"` scales to the largest whole unit (1 536 →
|
|
11
|
+
* 1.5 KB) in binary steps, the way storage limits are sold and shown; any
|
|
12
|
+
* other string is a plain suffix ("seats", "req/min"); a function says it its
|
|
13
|
+
* own way.
|
|
14
|
+
*/
|
|
15
|
+
export type QuotaUnit = "bytes" | string | ((value: number) => string);
|
|
16
|
+
export interface QuotaState {
|
|
17
|
+
/** Share of the limit used, 0–1 and beyond: 1.25 is a quarter over. */
|
|
18
|
+
ratio: number;
|
|
19
|
+
/** What is left; zero once over. */
|
|
20
|
+
remaining: number;
|
|
21
|
+
/** By how much the limit is exceeded; zero within it. */
|
|
22
|
+
over: number;
|
|
23
|
+
/** False when there is no limit to measure against (unset, zero, Infinity). */
|
|
24
|
+
limited: boolean;
|
|
25
|
+
tone: MeterTone;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Where a quota stands. Thresholds are shares of the limit, read on the same
|
|
29
|
+
* capacity scale (and with the same defaults) as LpProgress's `auto` tone and
|
|
30
|
+
* LpGauge, so a quota and a gauge of one disk turn red together; anything past
|
|
31
|
+
* the limit is danger whatever they say, because "over" is the one state a
|
|
32
|
+
* quota must never paint as merely amber.
|
|
33
|
+
*/
|
|
34
|
+
export declare function quotaState(used: number, limit: number | null | undefined, warnAt?: number, dangerAt?: number): QuotaState;
|
|
35
|
+
/**
|
|
36
|
+
* An amount in its unit, locale-aware. Bytes go through `formatBytes`, whose
|
|
37
|
+
* unit names come from Intl, so a Russian app reads "1,5 ГБ" without a
|
|
38
|
+
* translation table of its own.
|
|
39
|
+
*/
|
|
40
|
+
export declare function formatAmount(value: number, unit?: QuotaUnit, locale?: string): string;
|
|
41
|
+
export interface QuotaSegment extends QuotaPart {
|
|
42
|
+
color: string;
|
|
43
|
+
/** Share of the bar's width, 0–1. */
|
|
44
|
+
share: number;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The parts laid out along the bar. Within the limit the bar's width IS the
|
|
48
|
+
* limit, so a part's share is its value over the limit and the rest of the
|
|
49
|
+
* track is what remains. Over it, the bar stretches to hold everything used and
|
|
50
|
+
* the limit becomes a mark partway along (`limitAt`), so the overflow reads as
|
|
51
|
+
* the part of the bar beyond the line rather than as a bar that simply stopped
|
|
52
|
+
* at full.
|
|
53
|
+
*/
|
|
54
|
+
export declare function quotaSegments(parts: readonly QuotaPart[], limit: number | null | undefined): {
|
|
55
|
+
segments: QuotaSegment[];
|
|
56
|
+
limitAt: number | null;
|
|
57
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { CHART_PALETTE } from "./chart.js";
|
|
2
|
+
import { formatBytes } from "./format.js";
|
|
3
|
+
import { toneAt, capacityThresholds } from "./meter.js";
|
|
4
|
+
function quotaState(used, limit, warnAt = 0.8, dangerAt = 0.9) {
|
|
5
|
+
const safeUsed = Number.isFinite(used) ? Math.max(0, used) : 0;
|
|
6
|
+
const limited = limit != null && Number.isFinite(limit) && limit > 0;
|
|
7
|
+
if (!limited) return { ratio: 0, remaining: Infinity, over: 0, limited, tone: "ok" };
|
|
8
|
+
const ratio = safeUsed / limit;
|
|
9
|
+
const tone = ratio > 1 ? "danger" : toneAt(ratio, capacityThresholds(0, 1, warnAt, dangerAt));
|
|
10
|
+
return {
|
|
11
|
+
ratio,
|
|
12
|
+
remaining: Math.max(0, limit - safeUsed),
|
|
13
|
+
over: Math.max(0, safeUsed - limit),
|
|
14
|
+
limited,
|
|
15
|
+
tone
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function formatAmount(value, unit, locale) {
|
|
19
|
+
if (typeof unit === "function") return unit(value);
|
|
20
|
+
if (unit === "bytes") return formatBytes(Math.max(0, value), locale);
|
|
21
|
+
const number = new Intl.NumberFormat(locale, { maximumFractionDigits: value < 10 ? 1 : 0 }).format(value);
|
|
22
|
+
return unit ? `${number} ${unit}` : number;
|
|
23
|
+
}
|
|
24
|
+
const PART_PALETTE = CHART_PALETTE.filter((c) => !c.includes("danger"));
|
|
25
|
+
function quotaSegments(parts, limit) {
|
|
26
|
+
const total = parts.reduce((sum, p) => sum + Math.max(0, p.value), 0);
|
|
27
|
+
const limited = limit != null && Number.isFinite(limit) && limit > 0;
|
|
28
|
+
const scale = limited ? Math.max(limit, total) : total;
|
|
29
|
+
const segments = parts.map((p, i) => ({
|
|
30
|
+
...p,
|
|
31
|
+
color: p.color ?? PART_PALETTE[i % PART_PALETTE.length],
|
|
32
|
+
share: scale > 0 ? Math.max(0, p.value) / scale : 0
|
|
33
|
+
}));
|
|
34
|
+
return { segments, limitAt: limited && total > limit ? limit / total : null };
|
|
35
|
+
}
|
|
36
|
+
export {
|
|
37
|
+
formatAmount,
|
|
38
|
+
quotaSegments,
|
|
39
|
+
quotaState
|
|
40
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export type RelativeUnit = "second" | "minute" | "hour" | "day" | "week" | "month" | "year";
|
|
2
|
+
export interface RelativeTimeOptions {
|
|
3
|
+
locale?: string;
|
|
4
|
+
/** Intl's width: `long` "3 minutes ago", `short` "3 min. ago", `narrow` "3m ago". */
|
|
5
|
+
style?: Intl.RelativeTimeFormatStyle;
|
|
6
|
+
/**
|
|
7
|
+
* Under this many ms either side of now, say "now" instead of counting
|
|
8
|
+
* seconds. Counting seconds is churn nobody reads; a countdown that needs
|
|
9
|
+
* them wants a timer, not this.
|
|
10
|
+
*/
|
|
11
|
+
nowWithin?: number;
|
|
12
|
+
}
|
|
13
|
+
export interface RelativeTime {
|
|
14
|
+
text: string;
|
|
15
|
+
unit: RelativeUnit;
|
|
16
|
+
/** Signed: negative is the past. */
|
|
17
|
+
value: number;
|
|
18
|
+
/**
|
|
19
|
+
* Milliseconds until `text` would read differently. A ticker sleeps this
|
|
20
|
+
* long instead of waking every second for a date three weeks away.
|
|
21
|
+
*/
|
|
22
|
+
refreshIn: number;
|
|
23
|
+
}
|
|
24
|
+
export declare function formatRelativeTime(date: Date | string | number, now?: number, options?: RelativeTimeOptions): RelativeTime;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { toEpoch } from "./timeSpan.js";
|
|
2
|
+
const SECOND = 1e3;
|
|
3
|
+
const MINUTE = 60 * SECOND;
|
|
4
|
+
const HOUR = 60 * MINUTE;
|
|
5
|
+
const DAY = 24 * HOUR;
|
|
6
|
+
const WEEK = 7 * DAY;
|
|
7
|
+
const MONTH = 30.4375 * DAY;
|
|
8
|
+
const YEAR = 365.25 * DAY;
|
|
9
|
+
const SCALE = [
|
|
10
|
+
{ unit: "second", ms: SECOND, until: 45 * SECOND },
|
|
11
|
+
{ unit: "minute", ms: MINUTE, until: 45 * MINUTE },
|
|
12
|
+
{ unit: "hour", ms: HOUR, until: 22 * HOUR },
|
|
13
|
+
{ unit: "day", ms: DAY, until: 6.5 * DAY },
|
|
14
|
+
{ unit: "week", ms: WEEK, until: 26 * DAY },
|
|
15
|
+
{ unit: "month", ms: MONTH, until: 320 * DAY },
|
|
16
|
+
{ unit: "year", ms: YEAR, until: Infinity }
|
|
17
|
+
];
|
|
18
|
+
const formatters = /* @__PURE__ */ new Map();
|
|
19
|
+
function formatterFor(locale, style) {
|
|
20
|
+
const key = `${locale ?? ""}|${style}`;
|
|
21
|
+
let f = formatters.get(key);
|
|
22
|
+
if (!f) {
|
|
23
|
+
f = new Intl.RelativeTimeFormat(locale, { numeric: "auto", style });
|
|
24
|
+
formatters.set(key, f);
|
|
25
|
+
}
|
|
26
|
+
return f;
|
|
27
|
+
}
|
|
28
|
+
const MAX_REFRESH = HOUR;
|
|
29
|
+
const MIN_REFRESH = SECOND;
|
|
30
|
+
function formatRelativeTime(date, now = Date.now(), options = {}) {
|
|
31
|
+
const { locale, style = "long", nowWithin = 45 * SECOND } = options;
|
|
32
|
+
const at = toEpoch(date);
|
|
33
|
+
const fmt = formatterFor(locale, style);
|
|
34
|
+
if (!Number.isFinite(at)) return { text: "", unit: "second", value: 0, refreshIn: MAX_REFRESH };
|
|
35
|
+
const diff = at - now;
|
|
36
|
+
const abs = Math.abs(diff);
|
|
37
|
+
if (abs < nowWithin) {
|
|
38
|
+
const refreshIn2 = diff >= 0 ? diff + nowWithin : nowWithin - abs;
|
|
39
|
+
return { text: fmt.format(0, "second"), unit: "second", value: 0, refreshIn: clampRefresh(refreshIn2) };
|
|
40
|
+
}
|
|
41
|
+
const index = SCALE.findIndex((s) => abs < s.until);
|
|
42
|
+
const step = SCALE[index];
|
|
43
|
+
const count = Math.max(1, Math.round(abs / step.ms));
|
|
44
|
+
const value = diff < 0 ? -count : count;
|
|
45
|
+
const units = abs / step.ms;
|
|
46
|
+
const boundary = diff < 0 ? (Math.floor(units + 0.5) + 0.5) * step.ms : (Math.ceil(units - 0.5) - 0.5) * step.ms;
|
|
47
|
+
const unitChange = diff < 0 ? step.until - abs : index > 0 ? abs - SCALE[index - 1].until : Infinity;
|
|
48
|
+
const refreshIn = Math.min(diff < 0 ? boundary - abs : abs - boundary, unitChange);
|
|
49
|
+
return { text: fmt.format(value, step.unit), unit: step.unit, value, refreshIn: clampRefresh(refreshIn) };
|
|
50
|
+
}
|
|
51
|
+
function clampRefresh(ms) {
|
|
52
|
+
return Math.min(MAX_REFRESH, Math.max(MIN_REFRESH, Math.ceil(ms)));
|
|
53
|
+
}
|
|
54
|
+
export {
|
|
55
|
+
formatRelativeTime
|
|
56
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type RevealPreset = "fade" | "rise" | "blur" | "scale";
|
|
2
|
+
export type RevealDirection = "up" | "down" | "left" | "right";
|
|
3
|
+
/**
|
|
4
|
+
* The hidden state an entrance starts from; the end state is always "as laid
|
|
5
|
+
* out", so the keyframes only describe where the content comes FROM.
|
|
6
|
+
*
|
|
7
|
+
* `direction` is the way the content travels: `up` starts below and rises.
|
|
8
|
+
* Every preset fades — motion without a fade reads as a layout jump.
|
|
9
|
+
*/
|
|
10
|
+
export declare function revealFrom(preset: RevealPreset, direction: RevealDirection, distance: number): Keyframe;
|
|
11
|
+
/** The resting state matching `revealFrom`'s properties. */
|
|
12
|
+
export declare function revealTo(from: Keyframe): Keyframe;
|
|
13
|
+
/**
|
|
14
|
+
* Delay of the `index`-th child. The steps stop growing after `cap` children:
|
|
15
|
+
* a list of eighty would otherwise take seconds to finish arriving, and the
|
|
16
|
+
* last rows would still be invisible when the user starts reading them.
|
|
17
|
+
*/
|
|
18
|
+
export declare function staggerDelay(index: number, delay: number, stagger: number, cap?: number): number;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
function revealFrom(preset, direction, distance) {
|
|
2
|
+
const offset = (d) => ({
|
|
3
|
+
up: `translate3d(0, ${d}px, 0)`,
|
|
4
|
+
down: `translate3d(0, ${-d}px, 0)`,
|
|
5
|
+
left: `translate3d(${d}px, 0, 0)`,
|
|
6
|
+
right: `translate3d(${-d}px, 0, 0)`
|
|
7
|
+
})[direction];
|
|
8
|
+
switch (preset) {
|
|
9
|
+
case "fade":
|
|
10
|
+
return { opacity: 0 };
|
|
11
|
+
case "rise":
|
|
12
|
+
return { opacity: 0, transform: offset(distance) };
|
|
13
|
+
case "blur":
|
|
14
|
+
return { opacity: 0, filter: "blur(8px)", transform: offset(distance / 2) };
|
|
15
|
+
case "scale":
|
|
16
|
+
return { opacity: 0, transform: "scale(0.94)" };
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function revealTo(from) {
|
|
20
|
+
const to = { opacity: 1 };
|
|
21
|
+
if ("transform" in from) to.transform = "none";
|
|
22
|
+
if ("filter" in from) to.filter = "blur(0px)";
|
|
23
|
+
return to;
|
|
24
|
+
}
|
|
25
|
+
function staggerDelay(index, delay, stagger, cap = 10) {
|
|
26
|
+
return delay + Math.min(Math.max(0, index), cap) * Math.max(0, stagger);
|
|
27
|
+
}
|
|
28
|
+
export {
|
|
29
|
+
revealFrom,
|
|
30
|
+
revealTo,
|
|
31
|
+
staggerDelay
|
|
32
|
+
};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/** Random number in [0, 1). Injected so frames are reproducible under test. */
|
|
2
|
+
export type Random = () => number;
|
|
3
|
+
/** Glyphs a position cycles through before it settles. Upper case and digits read as "code". */
|
|
4
|
+
export declare const SCRAMBLE_GLYPHS = "ABCDEFGHJKLMNPQRSTUVWXYZ0123456789#%&*+=?@$";
|
|
5
|
+
export interface ScrambleOptions {
|
|
6
|
+
/** Total travel time in ms, from the first glyph to the last position settling. */
|
|
7
|
+
duration: number;
|
|
8
|
+
/**
|
|
9
|
+
* `sequential` settles left to right, which reads as decoding; `together`
|
|
10
|
+
* holds every position until near the end and lands them in a short burst,
|
|
11
|
+
* which reads as a lock opening.
|
|
12
|
+
*/
|
|
13
|
+
order?: "sequential" | "together";
|
|
14
|
+
/** Glyph pool. */
|
|
15
|
+
glyphs?: string;
|
|
16
|
+
/**
|
|
17
|
+
* Characters that never scramble: a space or a dash in a key keeps the
|
|
18
|
+
* grouping visible while the rest churns, so the reader sees the shape of
|
|
19
|
+
* what is coming.
|
|
20
|
+
*/
|
|
21
|
+
keep?: (char: string) => boolean;
|
|
22
|
+
}
|
|
23
|
+
export interface ScrambleCell {
|
|
24
|
+
/** The character settled into, or "" for a position the new value no longer has. */
|
|
25
|
+
final: string;
|
|
26
|
+
/** The character shown before the run started (sizes a position the value is losing). */
|
|
27
|
+
initial: string;
|
|
28
|
+
/** Ms from the start of the run when this position shows `final`. */
|
|
29
|
+
settleAt: number;
|
|
30
|
+
/** Never churns (see `keep`). */
|
|
31
|
+
fixed: boolean;
|
|
32
|
+
}
|
|
33
|
+
export interface ScrambleFrameCell {
|
|
34
|
+
/** What to draw now. */
|
|
35
|
+
char: string;
|
|
36
|
+
/** The character that gives the position its width: the final one, or the old one while it is leaving. */
|
|
37
|
+
sizer: string;
|
|
38
|
+
settled: boolean;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Splits into user-perceived characters, so an emoji or an accented letter is
|
|
42
|
+
* one position rather than two halves that scramble separately.
|
|
43
|
+
*/
|
|
44
|
+
export declare function graphemes(text: string): string[];
|
|
45
|
+
/**
|
|
46
|
+
* When each position stops churning (all of them start at once).
|
|
47
|
+
*
|
|
48
|
+
* `sequential`: positions start together and settle on a ramp across the last
|
|
49
|
+
* 70% of the run, so the left of the value is readable while the right still
|
|
50
|
+
* moves. `together`: every position settles within the last 15%, with a
|
|
51
|
+
* little random spread so they do not land as one flat click.
|
|
52
|
+
*/
|
|
53
|
+
export declare function planScramble(from: string, to: string, options: ScrambleOptions, random?: Random): ScrambleCell[];
|
|
54
|
+
/** A glyph from the pool. */
|
|
55
|
+
export declare function randomGlyph(random: Random, glyphs?: string): string;
|
|
56
|
+
/**
|
|
57
|
+
* The text at `elapsed` ms into the run. A churning position draws a fresh
|
|
58
|
+
* random glyph each call; the caller decides how often to call (the glyph
|
|
59
|
+
* re-roll rate), not this.
|
|
60
|
+
*/
|
|
61
|
+
export declare function scrambleFrame(cells: ScrambleCell[], elapsed: number, random?: Random, glyphs?: string): ScrambleFrameCell[];
|
|
62
|
+
/** The cells of a value at rest, for the first paint and for reduced motion. */
|
|
63
|
+
export declare function settledCells(text: string): ScrambleFrameCell[];
|
|
64
|
+
/**
|
|
65
|
+
* A small seeded generator (mulberry32), for tests and for a scramble that
|
|
66
|
+
* should look the same every time it plays (a demo, a screenshot).
|
|
67
|
+
*/
|
|
68
|
+
export declare function seededRandom(seed: number): Random;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
const SCRAMBLE_GLYPHS = "ABCDEFGHJKLMNPQRSTUVWXYZ0123456789#%&*+=?@$";
|
|
2
|
+
const defaultKeep = (char) => /\s/.test(char);
|
|
3
|
+
function graphemes(text) {
|
|
4
|
+
const Segmenter = Intl.Segmenter;
|
|
5
|
+
if (Segmenter) return Array.from(new Segmenter(void 0, { granularity: "grapheme" }).segment(text), (s) => s.segment);
|
|
6
|
+
return Array.from(text);
|
|
7
|
+
}
|
|
8
|
+
function planScramble(from, to, options, random = Math.random) {
|
|
9
|
+
const keep = options.keep ?? defaultKeep;
|
|
10
|
+
const a = graphemes(from);
|
|
11
|
+
const b = graphemes(to);
|
|
12
|
+
const length = Math.max(a.length, b.length);
|
|
13
|
+
const duration = Math.max(0, options.duration);
|
|
14
|
+
const cells = [];
|
|
15
|
+
for (let i = 0; i < length; i++) {
|
|
16
|
+
const final = b[i] ?? "";
|
|
17
|
+
const initial = a[i] ?? "";
|
|
18
|
+
let settleAt;
|
|
19
|
+
if (options.order === "together") settleAt = duration * (0.85 + 0.15 * random());
|
|
20
|
+
else settleAt = length === 1 ? duration : duration * (0.3 + 0.7 * i / (length - 1));
|
|
21
|
+
const fixed = final !== "" && keep(final) && (initial === final || initial === "");
|
|
22
|
+
cells.push({ final, initial, settleAt: fixed ? 0 : settleAt, fixed });
|
|
23
|
+
}
|
|
24
|
+
return cells;
|
|
25
|
+
}
|
|
26
|
+
function randomGlyph(random, glyphs = SCRAMBLE_GLYPHS) {
|
|
27
|
+
const pool = graphemes(glyphs);
|
|
28
|
+
return pool[Math.min(pool.length - 1, Math.floor(random() * pool.length))] ?? "";
|
|
29
|
+
}
|
|
30
|
+
function scrambleFrame(cells, elapsed, random = Math.random, glyphs = SCRAMBLE_GLYPHS) {
|
|
31
|
+
return cells.map((cell) => {
|
|
32
|
+
const sizer = cell.final || cell.initial;
|
|
33
|
+
if (cell.fixed || elapsed >= cell.settleAt) return { char: cell.final, sizer: cell.final, settled: true };
|
|
34
|
+
return { char: randomGlyph(random, glyphs), sizer, settled: false };
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
function settledCells(text) {
|
|
38
|
+
return graphemes(text).map((char) => ({ char, sizer: char, settled: true }));
|
|
39
|
+
}
|
|
40
|
+
function seededRandom(seed) {
|
|
41
|
+
let state = seed >>> 0;
|
|
42
|
+
return () => {
|
|
43
|
+
state = state + 1831565813 >>> 0;
|
|
44
|
+
let t = state;
|
|
45
|
+
t = Math.imul(t ^ t >>> 15, t | 1);
|
|
46
|
+
t ^= t + Math.imul(t ^ t >>> 7, t | 61);
|
|
47
|
+
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
export {
|
|
51
|
+
SCRAMBLE_GLYPHS,
|
|
52
|
+
graphemes,
|
|
53
|
+
planScramble,
|
|
54
|
+
randomGlyph,
|
|
55
|
+
scrambleFrame,
|
|
56
|
+
seededRandom,
|
|
57
|
+
settledCells
|
|
58
|
+
};
|