@leavepulse/ui 0.69.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.js +107 -138
- 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/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 +143 -154
- 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 +9 -32
- package/src/components/LpHintLayer.vue +13 -3
- package/src/components/LpHoverCard.vue +175 -0
- package/src/components/LpIdenticon.vue +69 -0
- package/src/components/LpImageEditor.vue +15 -18
- package/src/components/LpInfraNode.vue +27 -16
- package/src/components/LpInput.vue +30 -16
- package/src/components/LpLightbox.vue +44 -23
- package/src/components/LpLoader.vue +145 -0
- package/src/components/LpLogViewer.vue +311 -82
- package/src/components/LpMagnetic.vue +97 -0
- package/src/components/LpMapPicker.vue +26 -28
- package/src/components/LpMasonry.vue +247 -0
- package/src/components/LpModal.vue +10 -1
- package/src/components/LpNotificationBell.vue +33 -49
- package/src/components/LpNumberField.vue +79 -14
- package/src/components/LpNumberFlow.vue +10 -35
- package/src/components/LpOtpInput.vue +7 -2
- package/src/components/LpPagination.vue +38 -4
- package/src/components/LpPalettePreview.vue +2 -7
- package/src/components/LpPasswordInput.vue +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/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,186 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// The consumer's `class` is merged into the root's own rather than appended to
|
|
3
|
+
// it, so opt out of the automatic pass-through that would add it unmerged.
|
|
4
|
+
export default { inheritAttrs: false }
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<script setup lang="ts">
|
|
8
|
+
/*
|
|
9
|
+
* A hairline along the edge of a card, table or page that says "something is
|
|
10
|
+
* happening here": a sweep while the length of the work is unknown, a fill once
|
|
11
|
+
* it is, a quick run to the end and a fade when it is done.
|
|
12
|
+
*
|
|
13
|
+
* Not LpProgress. LpProgress is a reading the user looks AT: it has a track,
|
|
14
|
+
* a caption, a value that persists. This is ambient: it has no track, lies over
|
|
15
|
+
* the edge of something else without taking space, is absent while idle, waits
|
|
16
|
+
* a beat before appearing so a fast load never flashes it, and on completion
|
|
17
|
+
* finishes its run before fading, so "done" is seen rather than the line just
|
|
18
|
+
* vanishing mid-way.
|
|
19
|
+
*/
|
|
20
|
+
import { computed, onBeforeUnmount, ref, watch } from "vue"
|
|
21
|
+
import { durationToken, prefersReducedMotion } from "../composables/easing"
|
|
22
|
+
import { useLoadingGate } from "../composables/useLoadingGate"
|
|
23
|
+
import { useLabels } from "../composables/useLpConfig"
|
|
24
|
+
import { useMergedAttrs } from "../composables/useMergedClass"
|
|
25
|
+
import { meterFraction, TONE_COLOR, type MeterTone } from "./meter"
|
|
26
|
+
|
|
27
|
+
const props = withDefaults(
|
|
28
|
+
defineProps<{
|
|
29
|
+
/** Work is in flight. Going false finishes the line and fades it out. */
|
|
30
|
+
active?: boolean
|
|
31
|
+
/** Known progress. Unset or null: the length of the work is unknown, and the line sweeps. */
|
|
32
|
+
value?: number | null
|
|
33
|
+
max?: number
|
|
34
|
+
tone?: MeterTone
|
|
35
|
+
/**
|
|
36
|
+
* Where it lies. `top` and `bottom` are absolute, over the edge of the
|
|
37
|
+
* nearest positioned ancestor (give the card `relative`), so showing it
|
|
38
|
+
* moves nothing; `inline` takes its own line in the flow.
|
|
39
|
+
*/
|
|
40
|
+
placement?: "top" | "bottom" | "inline"
|
|
41
|
+
/** Thickness in px. */
|
|
42
|
+
height?: number
|
|
43
|
+
/**
|
|
44
|
+
* Ms to wait before showing. Work that finishes within it never shows the
|
|
45
|
+
* line at all: a flash of activity for a 90 ms request is noise.
|
|
46
|
+
*/
|
|
47
|
+
delay?: number
|
|
48
|
+
labels?: Partial<{ busy: string }>
|
|
49
|
+
}>(),
|
|
50
|
+
{ active: true, value: null, max: 100, tone: "brand", placement: "top", height: 2, delay: 150 },
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
const text = useLabels("activityLine", { busy: "Loading" }, () => props.labels)
|
|
54
|
+
|
|
55
|
+
/*
|
|
56
|
+
* Whether it is up at all is the same question LpLoader answers, so it is
|
|
57
|
+
* answered the same way (useLoadingGate): wait `delay` before appearing, and
|
|
58
|
+
* once up stay long enough to be read as a state rather than a blink.
|
|
59
|
+
*
|
|
60
|
+
* On top of that the line has an exit of its own:
|
|
61
|
+
* idle → running → (gate closes) → finishing → idle. `finishing` is the run to
|
|
62
|
+
* the end and the fade after it; then the element is gone.
|
|
63
|
+
*/
|
|
64
|
+
const gated = useLoadingGate(() => props.active, {
|
|
65
|
+
delay: () => (prefersReducedMotion() ? 0 : props.delay),
|
|
66
|
+
minVisible: 300,
|
|
67
|
+
})
|
|
68
|
+
const phase = ref<"idle" | "running" | "finishing">("idle")
|
|
69
|
+
let doneTimer: ReturnType<typeof setTimeout> | undefined
|
|
70
|
+
|
|
71
|
+
watch(
|
|
72
|
+
gated,
|
|
73
|
+
(on) => {
|
|
74
|
+
clearTimeout(doneTimer)
|
|
75
|
+
if (on) {
|
|
76
|
+
phase.value = "running"
|
|
77
|
+
return
|
|
78
|
+
}
|
|
79
|
+
if (phase.value === "idle") return
|
|
80
|
+
phase.value = "finishing"
|
|
81
|
+
// The run to the end (slow), then the fade (medium), then gone.
|
|
82
|
+
const hold = prefersReducedMotion() ? 0 : durationToken("duration-medium") * 3
|
|
83
|
+
doneTimer = setTimeout(() => (phase.value = "idle"), hold)
|
|
84
|
+
},
|
|
85
|
+
{ immediate: true },
|
|
86
|
+
)
|
|
87
|
+
onBeforeUnmount(() => clearTimeout(doneTimer))
|
|
88
|
+
|
|
89
|
+
const determinate = computed(() => props.value != null)
|
|
90
|
+
const fraction = computed(() =>
|
|
91
|
+
phase.value === "finishing" ? 1 : determinate.value ? meterFraction(props.value as number, 0, props.max) : 0,
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
const { class: rootClass, attrs: rest } = useMergedAttrs(() =>
|
|
95
|
+
[
|
|
96
|
+
"pointer-events-none overflow-hidden",
|
|
97
|
+
props.placement === "inline" ? "relative block w-full" : "z-[2]",
|
|
98
|
+
"transition-opacity duration-(--duration-medium) ease-(--ease-emphasized) motion-reduce:transition-none",
|
|
99
|
+
].join(" "),
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
/*
|
|
103
|
+
* Edge placement goes inline, not through `absolute top-0` classes: a card's
|
|
104
|
+
* skin (`.lp-skin-panel > *`) makes every direct child `position: relative`
|
|
105
|
+
* with a more specific selector than a utility class, which collapsed the line
|
|
106
|
+
* to zero width exactly where it is meant to be used, as a card's first child.
|
|
107
|
+
*/
|
|
108
|
+
const edge = computed(() =>
|
|
109
|
+
props.placement === "inline"
|
|
110
|
+
? {}
|
|
111
|
+
: { position: "absolute" as const, left: 0, right: 0, [props.placement]: 0 },
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
// The fade starts once the run to the end is over, not with it.
|
|
115
|
+
const opacity = computed(() => (phase.value === "running" ? 1 : 0))
|
|
116
|
+
const fadeDelay = computed(() => (phase.value === "finishing" ? "var(--duration-slow)" : "0ms"))
|
|
117
|
+
</script>
|
|
118
|
+
|
|
119
|
+
<template>
|
|
120
|
+
<span
|
|
121
|
+
v-if="phase !== 'idle' || placement === 'inline'"
|
|
122
|
+
role="progressbar"
|
|
123
|
+
:aria-label="text.busy"
|
|
124
|
+
:aria-hidden="phase === 'idle' ? 'true' : undefined"
|
|
125
|
+
:aria-busy="phase === 'running' ? 'true' : undefined"
|
|
126
|
+
:aria-valuenow="determinate && phase !== 'idle' ? (value as number) : undefined"
|
|
127
|
+
:aria-valuemin="determinate ? 0 : undefined"
|
|
128
|
+
:aria-valuemax="determinate ? max : undefined"
|
|
129
|
+
:class="rootClass"
|
|
130
|
+
:style="{ ...edge, height: `${height}px`, opacity, transitionDelay: fadeDelay, '--lp-al-color': TONE_COLOR[tone] }"
|
|
131
|
+
v-bind="rest"
|
|
132
|
+
>
|
|
133
|
+
<!-- The sweep: a short bright segment crossing the edge. Faded rather than
|
|
134
|
+
cut when the work turns determinate or ends. -->
|
|
135
|
+
<span
|
|
136
|
+
class="lp-sweep lp-activity-sweep absolute inset-y-0 left-0 w-2/5 rounded-pill transition-opacity duration-(--duration-medium)"
|
|
137
|
+
:class="determinate || phase === 'finishing' ? 'opacity-0' : 'opacity-100'"
|
|
138
|
+
/>
|
|
139
|
+
<!-- The fill, scaled rather than sized, so it eases on the compositor. A
|
|
140
|
+
shimmer runs along it while it is still filling. -->
|
|
141
|
+
<span
|
|
142
|
+
class="absolute inset-0 origin-left rounded-pill transition-transform duration-(--duration-slow) ease-(--ease-emphasized) motion-reduce:transition-none"
|
|
143
|
+
:style="{ transform: `scaleX(${fraction})`, backgroundColor: 'var(--lp-al-color)' }"
|
|
144
|
+
>
|
|
145
|
+
<span v-if="determinate && phase === 'running'" class="lp-activity-shimmer absolute inset-0" />
|
|
146
|
+
</span>
|
|
147
|
+
</span>
|
|
148
|
+
</template>
|
|
149
|
+
|
|
150
|
+
<style>
|
|
151
|
+
/*
|
|
152
|
+
* Unscoped and namespaced, like the other kit animations: the keyframes are
|
|
153
|
+
* shared by every line on the page. The sweep's travel is the kit's own
|
|
154
|
+
* (.lp-sweep in tokens.css); this paints it, soft at both ends.
|
|
155
|
+
*/
|
|
156
|
+
.lp-activity-sweep {
|
|
157
|
+
background: linear-gradient(90deg, transparent, var(--lp-al-color) 35%, var(--lp-al-color) 65%, transparent);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.lp-activity-shimmer {
|
|
161
|
+
background: linear-gradient(90deg, transparent, color-mix(in oklab, var(--color-surface) 45%, transparent), transparent);
|
|
162
|
+
background-size: 40% 100%;
|
|
163
|
+
background-repeat: no-repeat;
|
|
164
|
+
animation: lp-activity-shimmer 1.6s linear infinite;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
@keyframes lp-activity-shimmer {
|
|
168
|
+
0% {
|
|
169
|
+
background-position: -40% 0;
|
|
170
|
+
}
|
|
171
|
+
100% {
|
|
172
|
+
background-position: 140% 0;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
@media (prefers-reduced-motion: reduce) {
|
|
177
|
+
/* The sweep lies still across the line (tokens.css); a solid tint rather than its soft ends. */
|
|
178
|
+
.lp-activity-sweep {
|
|
179
|
+
background: var(--lp-al-color);
|
|
180
|
+
}
|
|
181
|
+
.lp-activity-shimmer {
|
|
182
|
+
animation: none;
|
|
183
|
+
display: none;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
</style>
|
|
@@ -7,18 +7,29 @@ export default { inheritAttrs: false }
|
|
|
7
7
|
|
|
8
8
|
<script setup lang="ts">
|
|
9
9
|
import { tv, type VariantProps } from "tailwind-variants"
|
|
10
|
-
import { computed, ref, watch } from "vue"
|
|
10
|
+
import { computed, ref, useSlots, watch } from "vue"
|
|
11
11
|
import { useMergedAttrs } from "../composables/useMergedClass"
|
|
12
12
|
import LpIcon from "./LpIcon.vue"
|
|
13
|
+
import LpLoader from "./LpLoader.vue"
|
|
14
|
+
import LpSwap from "./LpSwap.vue"
|
|
15
|
+
import { slotText } from "./slotText"
|
|
16
|
+
import { TONES, toneLook } from "./tone"
|
|
13
17
|
|
|
14
18
|
const alert = tv({
|
|
15
|
-
|
|
19
|
+
/*
|
|
20
|
+
* An alert changes while it is read (saving → saved → failed), so the change
|
|
21
|
+
* shows as one: the tint eases between variants, the icon turns over, and
|
|
22
|
+
* the message is swapped by LpSwap, its box easing to the new height.
|
|
23
|
+
*/
|
|
24
|
+
base: "flex gap-3 rounded-card border p-4 text-sm transition-[background-color,border-color,color] duration-(--duration-medium) ease-(--ease-emphasized) motion-reduce:transition-none",
|
|
16
25
|
variants: {
|
|
26
|
+
// The tint is the tone's quiet panel (tone.ts); an info alert is a plain
|
|
27
|
+
// neutral panel whose meaning is carried by its brand-coloured icon alone.
|
|
17
28
|
variant: {
|
|
18
|
-
info:
|
|
19
|
-
success:
|
|
20
|
-
warning:
|
|
21
|
-
danger:
|
|
29
|
+
info: `${TONES.neutral.panel} text-ink`,
|
|
30
|
+
success: `${TONES.success.panel} text-ink`,
|
|
31
|
+
warning: `${TONES.warning.panel} text-ink`,
|
|
32
|
+
danger: `${TONES.danger.panel} text-ink`,
|
|
22
33
|
},
|
|
23
34
|
},
|
|
24
35
|
defaultVariants: { variant: "info" },
|
|
@@ -33,13 +44,6 @@ const ICONS: Record<NonNullable<AlertVariants["variant"]>, string> = {
|
|
|
33
44
|
danger: "lucide:octagon-alert",
|
|
34
45
|
}
|
|
35
46
|
|
|
36
|
-
const ICON_TONE: Record<NonNullable<AlertVariants["variant"]>, string> = {
|
|
37
|
-
info: "text-brand",
|
|
38
|
-
success: "text-action",
|
|
39
|
-
warning: "text-accent",
|
|
40
|
-
danger: "text-danger",
|
|
41
|
-
}
|
|
42
|
-
|
|
43
47
|
const props = withDefaults(
|
|
44
48
|
defineProps<{
|
|
45
49
|
variant?: AlertVariants["variant"]
|
|
@@ -54,7 +58,7 @@ const props = withDefaults(
|
|
|
54
58
|
*/
|
|
55
59
|
live?: "assertive" | "polite" | false
|
|
56
60
|
/**
|
|
57
|
-
* Work is under way: the icon becomes
|
|
61
|
+
* Work is under way: the icon becomes LpLoader's spinner (unless `icon` is
|
|
58
62
|
* given, which then spins instead) and the alert is announced politely.
|
|
59
63
|
* A loader drawn as a still icon read as a frozen page.
|
|
60
64
|
*/
|
|
@@ -78,23 +82,49 @@ const role = computed(() => {
|
|
|
78
82
|
|
|
79
83
|
// `p-3` or a different border must beat the variant's own, not race it.
|
|
80
84
|
const { class: rootClass, attrs: rest } = useMergedAttrs(() => alert({ variant: props.variant }))
|
|
81
|
-
const
|
|
82
|
-
const
|
|
85
|
+
const spinning = computed(() => props.busy && !props.icon)
|
|
86
|
+
const resolvedIcon = computed(() => props.icon ?? ICONS[props.variant ?? "info"])
|
|
87
|
+
const iconTone = computed(() => toneLook(props.variant ?? "info").text)
|
|
88
|
+
|
|
89
|
+
// What counts as another message: the variant, the title and the slot's words
|
|
90
|
+
// when it is plain text. Rich content keeps its key and only eases its height.
|
|
91
|
+
const slots = useSlots()
|
|
92
|
+
const messageKey = () => [props.variant, props.title ?? "", slotText(slots.default) ?? ""].join("\u0000")
|
|
83
93
|
</script>
|
|
84
94
|
|
|
85
95
|
<template>
|
|
86
96
|
<div :class="rootClass" :role="role" :aria-busy="busy || undefined" v-bind="rest">
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
97
|
+
<!-- The busy loader shows at once, since it replaces the icon, and stays
|
|
98
|
+
silent: the alert's own role and aria-busy already announce the work. -->
|
|
99
|
+
<span class="relative mt-0.5 grid size-[18px] shrink-0 place-items-center" aria-hidden="true">
|
|
100
|
+
<Transition
|
|
101
|
+
enter-from-class="scale-50 opacity-0"
|
|
102
|
+
leave-to-class="scale-50 opacity-0"
|
|
103
|
+
enter-active-class="transition-[scale,opacity] duration-(--duration-medium) ease-(--ease-emphasized) motion-reduce:transition-none"
|
|
104
|
+
leave-active-class="absolute transition-[scale,opacity] duration-(--duration-fast) ease-out motion-reduce:transition-none"
|
|
105
|
+
>
|
|
106
|
+
<LpLoader
|
|
107
|
+
v-if="spinning"
|
|
108
|
+
key="busy"
|
|
109
|
+
size="inline"
|
|
110
|
+
:delay="0"
|
|
111
|
+
class="text-[18px] transition-colors duration-(--duration-medium)"
|
|
112
|
+
:class="iconTone"
|
|
113
|
+
/>
|
|
114
|
+
<LpIcon
|
|
115
|
+
v-else
|
|
116
|
+
:key="resolvedIcon"
|
|
117
|
+
:name="resolvedIcon"
|
|
118
|
+
:size="18"
|
|
119
|
+
:class="[iconTone, 'transition-colors duration-(--duration-medium)', busy ? 'animate-spin motion-reduce:animate-none' : '']"
|
|
120
|
+
/>
|
|
121
|
+
</Transition>
|
|
122
|
+
</span>
|
|
123
|
+
<LpSwap :swap-key="messageKey()" class="min-w-0 flex-1">
|
|
94
124
|
<p v-if="title" class="font-semibold text-ink">{{ title }}</p>
|
|
95
125
|
<div :class="['text-muted-strong', title ? 'mt-0.5' : '']">
|
|
96
126
|
<slot />
|
|
97
127
|
</div>
|
|
98
|
-
</
|
|
128
|
+
</LpSwap>
|
|
99
129
|
</div>
|
|
100
130
|
</template>
|
|
@@ -66,8 +66,6 @@ const props = withDefaults(
|
|
|
66
66
|
isActive?: (item: SidebarItem) => boolean
|
|
67
67
|
/** Override the header title. Falls back to the active item's label. */
|
|
68
68
|
title?: string
|
|
69
|
-
/** Mobile drawer open state (v-model:open). */
|
|
70
|
-
open?: boolean
|
|
71
69
|
/** Tailwind breakpoint below which the rail becomes a drawer. */
|
|
72
70
|
mobileBreakpoint?: "sm" | "md" | "lg" | "xl"
|
|
73
71
|
/** Show the brand/header divider in the rail. */
|
|
@@ -94,7 +92,6 @@ const props = withDefaults(
|
|
|
94
92
|
|
|
95
93
|
const emit = defineEmits<{
|
|
96
94
|
(e: "update:modelValue", id: string): void
|
|
97
|
-
(e: "update:open", value: boolean): void
|
|
98
95
|
(e: "update:collapsed", keys: string[]): void
|
|
99
96
|
(e: "select", item: SidebarItem): void
|
|
100
97
|
}>()
|
|
@@ -139,10 +136,9 @@ const pageTitle = computed(() => {
|
|
|
139
136
|
|
|
140
137
|
// Mobile drawer: also close it on every path change, so href/select navigation
|
|
141
138
|
// from a nav item dismisses it.
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
})
|
|
139
|
+
// Its own state when the app does not bind it: the shell's burger must open
|
|
140
|
+
// the drawer either way. v-model:open still controls it from outside.
|
|
141
|
+
const drawerOpen = defineModel<boolean>("open", { default: false })
|
|
146
142
|
const text = useLabels(
|
|
147
143
|
"appShell",
|
|
148
144
|
{ openMenu: "Open menu", skipToContent: "Skip to content" },
|
|
@@ -165,7 +161,7 @@ function skipToMain() {
|
|
|
165
161
|
watch(
|
|
166
162
|
() => props.path,
|
|
167
163
|
() => {
|
|
168
|
-
if (drawerOpen.value)
|
|
164
|
+
if (drawerOpen.value) drawerOpen.value = false
|
|
169
165
|
scrollArea.value?.viewportEl?.scrollTo({ top: 0, left: 0, behavior: "instant" })
|
|
170
166
|
},
|
|
171
167
|
)
|
|
@@ -186,7 +182,7 @@ const burgerHidden: Record<NonNullable<typeof props.mobileBreakpoint>, string> =
|
|
|
186
182
|
const burgerClass = computed(() => burgerHidden[props.mobileBreakpoint])
|
|
187
183
|
|
|
188
184
|
// Expose the burger trigger so a host can omit its own header entirely.
|
|
189
|
-
const _openDrawer = () =>
|
|
185
|
+
const _openDrawer = () => (drawerOpen.value = true)
|
|
190
186
|
defineExpose({ openDrawer: _openDrawer })
|
|
191
187
|
|
|
192
188
|
// The shell claims the full viewport height, which is wrong when it is embedded in a page that already has a header of its own.
|
|
@@ -221,7 +217,7 @@ const { class: rootClass, attrs: rest } = useMergedAttrs(
|
|
|
221
217
|
:auto-collapse-after="autoCollapseAfter"
|
|
222
218
|
class="shrink-0"
|
|
223
219
|
@update:model-value="onModel"
|
|
224
|
-
@update:open="(v) =>
|
|
220
|
+
@update:open="(v) => (drawerOpen = v)"
|
|
225
221
|
@update:collapsed="(v) => emit('update:collapsed', v)"
|
|
226
222
|
@select="onSelect"
|
|
227
223
|
>
|
|
@@ -256,7 +252,7 @@ const { class: rootClass, attrs: rest } = useMergedAttrs(
|
|
|
256
252
|
size="sm"
|
|
257
253
|
square
|
|
258
254
|
:aria-label="text.openMenu"
|
|
259
|
-
@click="
|
|
255
|
+
@click="drawerOpen = true"
|
|
260
256
|
>
|
|
261
257
|
<LpIcon name="lucide:menu" :size="18" />
|
|
262
258
|
</LpButton>
|
|
@@ -36,9 +36,11 @@ import { computed, nextTick, ref, useAttrs, useId, watch } from "vue"
|
|
|
36
36
|
import { useFieldControl } from "../composables/useField"
|
|
37
37
|
import { useInputFilter } from "../composables/useInputFilter"
|
|
38
38
|
import { useLabels } from "../composables/useLpConfig"
|
|
39
|
-
import { CLOSE_ICON, OPTION_ITEM, POPOVER_PANEL } from "./dropdown"
|
|
39
|
+
import { CLOSE_ICON, OPTION_ITEM, optionStagger, POPOVER_PANEL } from "./dropdown"
|
|
40
40
|
import LpIcon from "./LpIcon.vue"
|
|
41
|
+
import OptionContent from "./OptionContent.vue"
|
|
41
42
|
import type { LpOptionBase, OptionSelection } from "./options"
|
|
43
|
+
import { useOutsideGuard, usePortalTarget } from "../composables/useView"
|
|
42
44
|
|
|
43
45
|
export type AutocompleteOption = LpOptionBase<string>
|
|
44
46
|
|
|
@@ -256,11 +258,18 @@ function choose(opt: AutocompleteOption) {
|
|
|
256
258
|
}
|
|
257
259
|
|
|
258
260
|
function clear() {
|
|
261
|
+
if (field.value.disabled) return
|
|
259
262
|
typing.value = false
|
|
260
263
|
draft.value = null
|
|
261
264
|
emit("update:modelValue", "")
|
|
262
265
|
open.value = false
|
|
263
266
|
}
|
|
267
|
+
|
|
268
|
+
// Overlays open in the window this component renders in (an LpFrame's, inside one).
|
|
269
|
+
const portalTo = usePortalTarget()
|
|
270
|
+
// What happens in another document (the page around a frame, or a frame in
|
|
271
|
+
// the page) is not "outside" for this layer.
|
|
272
|
+
const guardOutside = useOutsideGuard()
|
|
264
273
|
</script>
|
|
265
274
|
|
|
266
275
|
<template>
|
|
@@ -360,7 +369,7 @@ function clear() {
|
|
|
360
369
|
</Transition>
|
|
361
370
|
</div>
|
|
362
371
|
<button
|
|
363
|
-
v-if="clearable && hasValue"
|
|
372
|
+
v-if="clearable && hasValue && !field.disabled"
|
|
364
373
|
type="button"
|
|
365
374
|
class="group flex shrink-0 items-center text-muted outline-none transition-colors duration-[var(--duration-fast)] hover:text-ink"
|
|
366
375
|
:aria-label="labels.clear"
|
|
@@ -375,8 +384,10 @@ function clear() {
|
|
|
375
384
|
</button>
|
|
376
385
|
</ComboboxAnchor>
|
|
377
386
|
|
|
378
|
-
<ComboboxPortal>
|
|
387
|
+
<ComboboxPortal :to="portalTo">
|
|
379
388
|
<ComboboxContent
|
|
389
|
+
@interact-outside="guardOutside"
|
|
390
|
+
@escape-key-down="guardOutside"
|
|
380
391
|
:collision-padding="8"
|
|
381
392
|
position="popper"
|
|
382
393
|
:side-offset="6"
|
|
@@ -396,20 +407,11 @@ function clear() {
|
|
|
396
407
|
:key="opt.value"
|
|
397
408
|
:value="opt.value"
|
|
398
409
|
:disabled="opt.disabled"
|
|
399
|
-
:style="
|
|
410
|
+
:style="optionStagger(i)"
|
|
400
411
|
:class="[OPTION_ITEM, 'justify-between data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50']"
|
|
401
412
|
@select.prevent="choose(opt)"
|
|
402
413
|
>
|
|
403
|
-
<
|
|
404
|
-
<img v-if="opt.image" :src="opt.image" alt="" class="size-6 shrink-0 rounded-full object-cover" />
|
|
405
|
-
<LpIcon v-else-if="opt.icon" :name="opt.icon" :size="16" class="shrink-0 text-muted" />
|
|
406
|
-
<span class="flex min-w-0 flex-col">
|
|
407
|
-
<span class="truncate">{{ opt.label ?? opt.value }}</span>
|
|
408
|
-
<span v-if="opt.description" class="truncate text-xs text-muted">
|
|
409
|
-
{{ opt.description }}
|
|
410
|
-
</span>
|
|
411
|
-
</span>
|
|
412
|
-
</span>
|
|
414
|
+
<OptionContent :option="opt" />
|
|
413
415
|
</ComboboxItem>
|
|
414
416
|
</ComboboxViewport>
|
|
415
417
|
</ComboboxContent>
|
|
@@ -11,6 +11,7 @@ import { computed, onMounted, ref } from "vue"
|
|
|
11
11
|
import type { ContextMenuItemDef } from "./LpContextMenu.vue"
|
|
12
12
|
import { MenuWhen } from "./menuWhen"
|
|
13
13
|
import LpIcon from "./LpIcon.vue"
|
|
14
|
+
import LpIdenticon from "./LpIdenticon.vue"
|
|
14
15
|
import { useMergedAttrs } from "../composables/useMergedClass"
|
|
15
16
|
|
|
16
17
|
const avatar = tv({
|
|
@@ -48,6 +49,14 @@ const props = withDefaults(
|
|
|
48
49
|
* letters read as noise. `fallback` text still wins when both are given.
|
|
49
50
|
*/
|
|
50
51
|
icon?: string
|
|
52
|
+
/**
|
|
53
|
+
* Draw an identicon while there is no picture, instead of initials: a
|
|
54
|
+
* pattern and colour derived from a string, so accounts that never set an
|
|
55
|
+
* avatar still look different from each other. `true` derives it from
|
|
56
|
+
* `alt`; a string is the seed itself (an id outlives a rename). `fallback`
|
|
57
|
+
* text and `icon` still win when given.
|
|
58
|
+
*/
|
|
59
|
+
identicon?: boolean | string
|
|
51
60
|
size?: AvatarVariants["size"]
|
|
52
61
|
/** Explicit pixel size, wins over `size` — for avatars keyed to a layout. */
|
|
53
62
|
pixelSize?: number
|
|
@@ -111,6 +120,11 @@ const { class: rootClass, attrs: rest } = useMergedAttrs(() =>
|
|
|
111
120
|
// <ClientOnly>.
|
|
112
121
|
const mounted = ref(false)
|
|
113
122
|
|
|
123
|
+
const identiconSeed = computed(() => {
|
|
124
|
+
if (!props.identicon || props.fallback || props.icon) return ""
|
|
125
|
+
return props.identicon === true ? (props.alt ?? "").trim() : props.identicon
|
|
126
|
+
})
|
|
127
|
+
|
|
114
128
|
const menuHeading = computed(() => props.menuTitle ?? props.alt)
|
|
115
129
|
onMounted(() => {
|
|
116
130
|
mounted.value = true
|
|
@@ -129,8 +143,9 @@ onMounted(() => {
|
|
|
129
143
|
>
|
|
130
144
|
<AvatarRoot :class="rootClass" :style="sizeStyle" v-bind="rest">
|
|
131
145
|
<AvatarImage v-if="src && mounted" :src="src" :alt="alt" class="size-full object-cover animate-[fade-in_var(--duration-medium)_ease] motion-reduce:animate-none" />
|
|
132
|
-
<AvatarFallback>
|
|
133
|
-
<
|
|
146
|
+
<AvatarFallback :class="identiconSeed ? 'size-full' : undefined">
|
|
147
|
+
<LpIdenticon v-if="identiconSeed" :seed="identiconSeed" :padding="shape === 'circle' ? 0.24 : 0.14" />
|
|
148
|
+
<LpIcon v-else-if="icon && !fallback" :name="icon" :size="iconSize" />
|
|
134
149
|
<template v-else>{{ initials }}</template>
|
|
135
150
|
</AvatarFallback>
|
|
136
151
|
</AvatarRoot>
|
|
@@ -6,7 +6,15 @@ export default { inheritAttrs: false }
|
|
|
6
6
|
|
|
7
7
|
<script setup lang="ts">
|
|
8
8
|
import { tv, type VariantProps } from "tailwind-variants"
|
|
9
|
+
import { useSlots } from "vue"
|
|
10
|
+
import { useLabels } from "../composables/useLpConfig"
|
|
9
11
|
import { useMergedClass } from "../composables/useMergedClass"
|
|
12
|
+
import { BADGE_REMOVE } from "./badge"
|
|
13
|
+
import LpIcon from "./LpIcon.vue"
|
|
14
|
+
import LpRollingText from "./LpRollingText.vue"
|
|
15
|
+
import LpShift from "./LpShift.vue"
|
|
16
|
+
import { slotText } from "./slotText"
|
|
17
|
+
import { TONES } from "./tone"
|
|
10
18
|
|
|
11
19
|
const badge = tv({
|
|
12
20
|
/*
|
|
@@ -17,7 +25,14 @@ const badge = tv({
|
|
|
17
25
|
* the moment it gained a status. The badge now occupies the height it says it
|
|
18
26
|
* does and leaves the line it sits on alone.
|
|
19
27
|
*/
|
|
20
|
-
|
|
28
|
+
/*
|
|
29
|
+
* A status changes while it is watched, so the change shows as one: the
|
|
30
|
+
* colours ease between tones, the width eases (LpShift) and plain text rolls
|
|
31
|
+
* to the new word (LpRollingText). The outline tone draws its edge as an
|
|
32
|
+
* inset ring rather than a border, so switching to it neither adds a pixel
|
|
33
|
+
* nor snaps: the ring is there in every tone, transparent.
|
|
34
|
+
*/
|
|
35
|
+
base: "inline-flex shrink-0 items-center rounded-pill align-middle font-medium leading-[1.2] ring-1 ring-transparent ring-inset transition-[color,background-color,box-shadow] duration-(--duration-medium) ease-(--ease-emphasized) motion-reduce:transition-none",
|
|
21
36
|
variants: {
|
|
22
37
|
size: {
|
|
23
38
|
// Fits inside a text-sm line without growing it — for a badge beside a
|
|
@@ -26,16 +41,30 @@ const badge = tv({
|
|
|
26
41
|
md: "px-2.5 py-0.5 text-xs",
|
|
27
42
|
lg: "px-3 py-1 text-sm",
|
|
28
43
|
},
|
|
44
|
+
/*
|
|
45
|
+
* The kit's tones (tone.ts) under every name they go by, so a badge and a
|
|
46
|
+
* tinted row in one tone are one colour. `warning` is partial trouble,
|
|
47
|
+
* which every status surface eventually needs: without it a half-failed
|
|
48
|
+
* thing has to render as either fine or broken.
|
|
49
|
+
*/
|
|
29
50
|
tone: {
|
|
30
|
-
neutral:
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
51
|
+
neutral: TONES.neutral.chip,
|
|
52
|
+
muted: TONES.neutral.chip,
|
|
53
|
+
brand: TONES.brand.chip,
|
|
54
|
+
info: TONES.brand.chip,
|
|
55
|
+
action: TONES.success.chip,
|
|
56
|
+
success: TONES.success.chip,
|
|
57
|
+
ok: TONES.success.chip,
|
|
58
|
+
warning: TONES.warning.chip,
|
|
59
|
+
accent: TONES.warning.chip,
|
|
60
|
+
danger: TONES.danger.chip,
|
|
61
|
+
error: TONES.danger.chip,
|
|
62
|
+
outline: "text-ink ring-line",
|
|
63
|
+
},
|
|
64
|
+
// A chip that can be taken away (a tag, a filter in force): the ✕ sits
|
|
65
|
+
// tight to the trailing edge, so that side keeps only a hair of padding.
|
|
66
|
+
removable: {
|
|
67
|
+
true: "gap-1 pr-1",
|
|
39
68
|
},
|
|
40
69
|
},
|
|
41
70
|
defaultVariants: { tone: "neutral", size: "md" },
|
|
@@ -48,14 +77,49 @@ const props = defineProps<{
|
|
|
48
77
|
/** `sm` is the one that does not disturb a text-sm line it sits on. */
|
|
49
78
|
size?: BadgeVariants["size"]
|
|
50
79
|
dot?: boolean
|
|
80
|
+
/** A ✕ after the content that emits `remove`: a tag, a filter chip. */
|
|
81
|
+
removable?: boolean
|
|
82
|
+
/** Accessible name of the ✕, e.g. "Remove tag alpha". */
|
|
83
|
+
removeLabel?: string
|
|
84
|
+
}>()
|
|
85
|
+
|
|
86
|
+
const emit = defineEmits<{
|
|
87
|
+
/** The ✕ was pressed. */
|
|
88
|
+
(e: "remove"): void
|
|
51
89
|
}>()
|
|
52
90
|
|
|
53
|
-
|
|
91
|
+
defineSlots<{
|
|
92
|
+
default?: () => unknown
|
|
93
|
+
/** Replaces the ✕ (with `removable`), for a chip whose remove control is another primitive's. */
|
|
94
|
+
remove?: () => unknown
|
|
95
|
+
}>()
|
|
96
|
+
|
|
97
|
+
const text = useLabels("badge", { remove: "Remove" })
|
|
98
|
+
|
|
99
|
+
const classes = useMergedClass(() => badge({ tone: props.tone, size: props.size, removable: props.removable }))
|
|
100
|
+
|
|
101
|
+
// Plain words roll to the new ones; richer content only eases its width.
|
|
102
|
+
const slots = useSlots()
|
|
103
|
+
const plainText = () => slotText(slots.default)
|
|
54
104
|
</script>
|
|
55
105
|
|
|
56
106
|
<template>
|
|
57
107
|
<span v-bind="$attrs" :class="classes">
|
|
58
|
-
|
|
59
|
-
|
|
108
|
+
<!-- min-w-0 / max-w-full: a chip given a max width truncates its words
|
|
109
|
+
instead of spilling them past its edge. -->
|
|
110
|
+
<LpShift axis="width" class="min-w-0">
|
|
111
|
+
<span class="inline-flex max-w-full items-center gap-1.5 whitespace-nowrap">
|
|
112
|
+
<span v-if="dot" class="size-1.5 shrink-0 rounded-full bg-current" />
|
|
113
|
+
<LpRollingText v-if="plainText() !== null" :value="plainText()!" align="start" />
|
|
114
|
+
<slot v-else />
|
|
115
|
+
</span>
|
|
116
|
+
</LpShift>
|
|
117
|
+
<template v-if="removable">
|
|
118
|
+
<slot name="remove">
|
|
119
|
+
<button type="button" :class="BADGE_REMOVE" :aria-label="removeLabel ?? text.remove" @click="emit('remove')">
|
|
120
|
+
<LpIcon name="lucide:x" :size="12" />
|
|
121
|
+
</button>
|
|
122
|
+
</slot>
|
|
123
|
+
</template>
|
|
60
124
|
</span>
|
|
61
125
|
</template>
|