@leavepulse/ui 0.69.0 → 0.70.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +49 -0
- package/dist/assets/LoaderMark-DxBV2iDJ.css +43 -0
- package/dist/assets/LpActivityLine-B3EwNQEB.css +33 -0
- package/dist/assets/{LpCommandPalette-DxyjhYn_.css → LpCommandPalette-u-zOxKWa.css} +21 -31
- package/dist/assets/LpDock-Cbh0wQUv.css +17 -0
- package/dist/assets/{LpDropzone-Qb8k7cg4.css → LpDropzone-Bb1vBTeU.css} +12 -17
- package/dist/assets/{LpImageEditor-CElPDzpF.css → LpImageEditor-XM5bAziW.css} +6 -6
- package/dist/assets/LpLogViewer-BDNW6P52.css +38 -0
- package/dist/assets/{LpPalettePreview-CJmAKgYW.css → LpPalettePreview-B9VKDrvA.css} +2 -7
- package/dist/assets/LpRepeater-C1Cw27hj.css +21 -0
- package/dist/assets/{LpRollingText-BGnE6q9j.css → LpRollingText-dyOXedGO.css} +7 -0
- package/dist/assets/LpShinyText-D69cBYDR.css +61 -0
- package/dist/assets/LpStatus-430OGTZY.css +17 -0
- package/dist/assets/LpStepMark-Drvx33Vg.css +10 -0
- package/dist/assets/{LpTable-BPERfJIk.css → LpTable-DHxEQ_-3.css} +19 -19
- package/dist/assets/LpTabs-BJ-nrJuI.css +18 -0
- package/dist/assets/LpTextReveal-DjI1MsDS.css +35 -0
- package/dist/assets/LpTypewriter-CXAm9Nca.css +27 -0
- package/dist/chunks/AttentionDot-DCBf4aWg.js +25 -0
- package/dist/chunks/{ContextMenuItems-B7XFHksm.js → ContextMenuItems-6kxEivBI.js} +11 -5
- package/dist/chunks/{DropzoneLinkField-CjkrpDqO.js → DropzoneLinkField-Bw8Flkhk.js} +2 -2
- package/dist/chunks/FieldWrapper-BiennROB.js +43 -0
- package/dist/chunks/{LayoutCanvas-DF9CovaK.js → LayoutCanvas-BsJIzhdd.js} +1 -1
- package/dist/chunks/{LayoutNode-D9bIFzk0.js → LayoutNode-DJVhkSGk.js} +6 -8
- package/dist/chunks/LegendSwatch-BhRjrtzv.js +18 -0
- package/dist/chunks/LoaderMark-C1dubiKn.js +85 -0
- package/dist/chunks/{LpActionBar-MPKMu3pz.js → LpActionBar-CzOFar5t.js} +14 -20
- package/dist/chunks/LpActivityLine-CJvzrNpj.js +95 -0
- package/dist/chunks/{LpAddressInput-DG0BTqdH.js → LpAddressInput-Chv_Xf8q.js} +7 -7
- package/dist/chunks/LpAlert-C5igj802.js +119 -0
- package/dist/chunks/{LpAppShell-DPh1756q.js → LpAppShell-BiWByLmt.js} +15 -16
- package/dist/chunks/{LpAutocomplete-Dgn6hw3p.js → LpAutocomplete-D92niDHE.js} +15 -32
- package/dist/chunks/{LpAvatar-Bs0Fb1lC.js → LpAvatar-CLPl-qOF.js} +18 -6
- package/dist/chunks/LpBadge-BBq1Er9T.js +126 -0
- package/dist/chunks/LpBreadcrumbs-JKEi_yFF.js +144 -0
- package/dist/chunks/{LpButton-DNR-YAq5.js → LpButton-CVxBfGjd.js} +12 -4
- package/dist/chunks/{LpCalendar-BLya39Fh.js → LpCalendar-pVL91-Pl.js} +1 -1
- package/dist/chunks/{LpCard-Bf71NXZq.js → LpCard-CqKLnEhl.js} +18 -8
- package/dist/chunks/{LpCheckbox-Da5oZPHo.js → LpCheckbox-DHc2bHDe.js} +9 -6
- package/dist/chunks/{LpCodeBlock-lLbmslfs.js → LpCodeBlock-BGsQhxw8.js} +24 -32
- package/dist/chunks/LpCodeDisplay-CbJMs-IK.js +189 -0
- package/dist/chunks/LpCollapse-CWS9M_lm.js +115 -0
- package/dist/chunks/{LpColorPicker-DtEfBAcK.js → LpColorPicker-B7HSIFmn.js} +11 -6
- package/dist/chunks/{LpConfirmDialog-D7s4jakB.js → LpConfirmDialog-CfGCux8m.js} +3 -3
- package/dist/chunks/{LpConfirmHost-DrYI5y1K.js → LpConfirmHost-exB7JmcO.js} +1 -1
- package/dist/chunks/{LpContextMenu-CRnjoqSt.js → LpContextMenu-Cj96ENDC.js} +16 -7
- package/dist/chunks/LpCopyButton-DzHjnFs0.js +133 -0
- package/dist/chunks/LpCountdown-BQnmB4gq.js +231 -0
- package/dist/chunks/LpDataList-CHNYQw7h.js +121 -0
- package/dist/chunks/LpDatePicker-ac1_6o5P.js +169 -0
- package/dist/chunks/LpDateRangePicker-B15gYrZJ.js +127 -0
- package/dist/chunks/{LpDisclosure-6AplYBub.js → LpDisclosure-DOarzlAG.js} +22 -11
- package/dist/chunks/{LpDrawer-Q4SOxM4s.js → LpDrawer-DGNKRsGq.js} +9 -4
- package/dist/chunks/{LpDropdownMenu-DWTt0ooM.js → LpDropdownMenu-R4aYVtVV.js} +14 -6
- package/dist/chunks/LpEditable-Ws3DNQHn.js +238 -0
- package/dist/chunks/{LpEmptyState-om1UnFjV.js → LpEmptyState-KTKipws2.js} +1 -1
- package/dist/chunks/{LpFieldNotice-CHuDeLjc.js → LpFieldNotice-CurbNuXI.js} +1 -1
- package/dist/chunks/{LpFileTree-CW24YsVX.js → LpFileTree-DDNg34tJ.js} +5 -3
- package/dist/chunks/{LpFileTreeNode-BXhTHaKW.js → LpFileTreeNode-DmPuYNZ_.js} +42 -55
- package/dist/chunks/{LpFormField-DPb47HEm.js → LpFormField-BWwgm1E4.js} +23 -9
- package/dist/chunks/LpFrame-BVQCQLDI.js +155 -0
- package/dist/chunks/LpGauge-C14Z9503.js +204 -0
- package/dist/chunks/LpGlowBorder-B8V-QzIl.js +40 -0
- package/dist/chunks/{LpHintExample-C1eKYdeL.js → LpHintExample-9Py0wc-L.js} +11 -34
- package/dist/chunks/{LpHintLayer-7UOdWQG3.js → LpHintLayer-HvwUA5Ec.js} +27 -14
- package/dist/chunks/{LpHints-BUtBp9-w.js → LpHints-DxbPKOzQ.js} +3 -3
- package/dist/chunks/LpHoverCard-spGxyw7T.js +130 -0
- package/dist/chunks/{LpIcon-6tSrZ3Zy.js → LpIcon-HJP5xMz4.js} +1 -1
- package/dist/chunks/LpIdenticon-BzdC_qz9.js +63 -0
- package/dist/chunks/{LpInfraNode-Ds_8SZgN.js → LpInfraNode-D64hywJI.js} +39 -25
- package/dist/chunks/{LpInput-CUyr6PIE.js → LpInput-CDuwODJG.js} +44 -18
- package/dist/chunks/{LpLightbox-B9J8rzsj.js → LpLightbox-XJ0LpTcZ.js} +69 -69
- package/dist/chunks/LpLoader-DjJEX8hL.js +92 -0
- package/dist/chunks/{LpLogViewer-4QFc-sVN.js → LpLogViewer-DKK4ySZl.js} +225 -129
- package/dist/chunks/LpMagnetic-CtXKLa2Y.js +62 -0
- package/dist/chunks/{LpMapPicker-BTbkFeSG.js → LpMapPicker-BtIl7NOM.js} +34 -31
- package/dist/chunks/LpMasonry--k0571qG.js +185 -0
- package/dist/chunks/{LpMediaGallery-CuPcscx3.js → LpMediaGallery-rmI1DjKN.js} +3 -3
- package/dist/chunks/{LpModal-hk1noDcr.js → LpModal-eBMt2Fqn.js} +8 -3
- package/dist/chunks/{LpModalNav-DQd2keZm.js → LpModalNav-DiyFCHiZ.js} +4 -4
- package/dist/chunks/{LpNotificationBell-X84PJIxD.js → LpNotificationBell-D-WhE5m2.js} +32 -48
- package/dist/chunks/LpNumberField-B9k-h2HE.js +140 -0
- package/dist/chunks/{LpNumberFlow-z4WPZcZu.js → LpNumberFlow-Cfyh033Q.js} +8 -28
- package/dist/chunks/{LpOtpInput-PbeNJ5In.js → LpOtpInput-CeBPsM7D.js} +2 -1
- package/dist/chunks/{LpPagination-Bx-VG4Ag.js → LpPagination-VNCX6pFC.js} +37 -6
- package/dist/chunks/{LpPalettePreview-CFav_7co.js → LpPalettePreview-BNB8T_MY.js} +1 -1
- package/dist/chunks/{LpPasswordInput-CbnXitAS.js → LpPasswordInput-GL2KOFK8.js} +26 -22
- package/dist/chunks/{LpPhoneInput-DP69HONS.js → LpPhoneInput-C60tx1tC.js} +12 -7
- package/dist/chunks/{LpPie-yLF9-aDR.js → LpPie-BgXZ3xmm.js} +159 -48
- package/dist/chunks/LpPipeline-B31h41Mu.js +329 -0
- package/dist/chunks/{LpPopover-DVnkHaOu.js → LpPopover-DmZ3wUtP.js} +13 -7
- package/dist/chunks/{LpProgress-CA86wxXu.js → LpProgress-CE-m5OpD.js} +23 -63
- package/dist/chunks/LpQuota-DaL8TgNe.js +162 -0
- package/dist/chunks/{LpRadioGroup-8S5hf8lE.js → LpRadioGroup-CGBr5nIp.js} +1 -1
- package/dist/chunks/{LpRangeCalendar-ByQi-WUz.js → LpRangeCalendar-c5qj7YcC.js} +1 -1
- package/dist/chunks/{LpRangeSlider-C1yF9-nP.js → LpRangeSlider-Dv6lNvHY.js} +6 -2
- package/dist/chunks/LpRelativeTime-yin9uQP7.js +73 -0
- package/dist/chunks/LpRepeater-D0S7jjwr.js +180 -0
- package/dist/chunks/LpRevealOnScroll-DcQjexLy.js +76 -0
- package/dist/chunks/{LpRollingText-DB7upf-5.js → LpRollingText-DiL717LK.js} +4 -3
- package/dist/chunks/LpScramble-TDO5Kdou.js +85 -0
- package/dist/chunks/LpSecretField-CfWyHv9m.js +316 -0
- package/dist/chunks/{LpSection-BmRXe6ZP.js → LpSection-BW4xJ-Li.js} +1 -1
- package/dist/chunks/{LpSegmented-CW3bFHM4.js → LpSegmented-BO99Sr4m.js} +11 -14
- package/dist/chunks/{LpSelect-BCyDYoih.js → LpSelect-C_8cJtj6.js} +91 -111
- package/dist/chunks/LpShaderBackdrop-Bote0iuy.js +332 -0
- package/dist/chunks/LpShinyText-DX2ajtWq.js +48 -0
- package/dist/chunks/{LpSidebar-DfIiS-lB.js → LpSidebar-CZRXtvem.js} +5 -3
- package/dist/chunks/{LpSidebarNav-C5FDNI0t.js → LpSidebarNav-DBg1U1oW.js} +3 -3
- package/dist/chunks/{LpSlider-Cuzmrd7p.js → LpSlider-DuoRpOrH.js} +6 -2
- package/dist/chunks/{LpSparkline-DXT4KrSi.js → LpSparkline-CExIRDb3.js} +32 -27
- package/dist/chunks/LpSpotlight-4F3NeUMY.js +41 -0
- package/dist/chunks/{LpStat-iBMF5QNk.js → LpStat-DFKlPJgy.js} +38 -35
- package/dist/chunks/LpStatus-BsGLrpor.js +86 -0
- package/dist/chunks/LpStepMark-TrzOioa9.js +101 -0
- package/dist/chunks/LpStepper-BbnS5jUr.js +76 -0
- package/dist/chunks/{LpSwap-D82jiecV.js → LpSwap-DzE6M3Mg.js} +1 -1
- package/dist/chunks/LpSwitch-DrzKrZZV.js +112 -0
- package/dist/chunks/{LpTableFilter-CuIbgdW0.js → LpTableFilter-DyvHGbOk.js} +3 -2
- package/dist/chunks/{LpTableOfContents-C_4VBktT.js → LpTableOfContents-rYvo8z5T.js} +34 -21
- package/dist/chunks/{LpTagsInput-DiXrpYeE.js → LpTagsInput-DZg80W-B.js} +68 -71
- package/dist/chunks/LpTextReveal-CtAnOUkp.js +140 -0
- package/dist/chunks/{LpTextarea-xoQd5Lnp.js → LpTextarea-DiWjeVoJ.js} +12 -11
- package/dist/chunks/{LpThemeProvider-CQ2jC9TA.js → LpThemeProvider-DcbfOxsU.js} +1 -1
- package/dist/chunks/LpThemeStudio-DxVZMtzN.js +416 -0
- package/dist/chunks/LpThemeStudioSection-BwhqYDLf.js +20 -0
- package/dist/chunks/LpThemeSwitcher-CadVBTBn.js +278 -0
- package/dist/chunks/{LpTimeField-MFgAsNc5.js → LpTimeField-BFQVf_PW.js} +13 -5
- package/dist/chunks/{LpToaster-C4zE9zB7.js → LpToaster-Wv9ksj4q.js} +49 -82
- package/dist/chunks/{LpTooltip-suFCM34F.js → LpTooltip-Cz8SQwRt.js} +8 -3
- package/dist/chunks/{LpTopologyCanvas-6ozNrQKh.js → LpTopologyCanvas-C17A1XCb.js} +1 -1
- package/dist/chunks/{LpTour-BUp3Jt2e.js → LpTour-CY2bFXge.js} +24 -18
- package/dist/chunks/LpTruncate-D_5Pfv5B.js +112 -0
- package/dist/chunks/LpTypewriter-BCL_a6wE.js +159 -0
- package/dist/chunks/{LpUptimeBar-B6kHw4Cj.js → LpUptimeBar-Tew1Ykx4.js} +10 -9
- package/dist/chunks/{LpVideoBackdrop-qWRYBOTQ.js → LpVideoBackdrop-DS1wGv-X.js} +7 -8
- package/dist/chunks/{MenuTitle-obgek0B7.js → MenuTitle-BjQZX8tQ.js} +1 -1
- package/dist/chunks/OptionContent-CmYUUeWj.js +40 -0
- package/dist/chunks/PickerField-DoHv0WMH.js +125 -0
- package/dist/chunks/RevealToggle-C-KzaQGJ.js +65 -0
- package/dist/chunks/StepConnector-37OgEOXA.js +41 -0
- package/dist/chunks/TourCard-BJ8i7dk0.js +123 -0
- package/dist/chunks/backdrop-Dkf2vM81.js +59 -0
- package/dist/chunks/{icons-DVhZ_plB.js → icons-4IywzkHk.js} +1 -1
- package/dist/chunks/{useTheme-2qHG8NEU.js → useTheme-BOV_-AiY.js} +9 -65
- package/dist/component-names.d.ts +1 -1
- package/dist/components/AttentionDot.vue.d.ts +9 -0
- package/dist/components/AttentionDot.vue.js +4 -0
- package/dist/components/ContextMenuItems.vue.js +1 -1
- package/dist/components/DropzoneLinkField.vue.js +1 -1
- package/dist/components/FieldWrapper.vue.d.ts +25 -0
- package/dist/components/FieldWrapper.vue.js +4 -0
- package/dist/components/LayoutCanvas.vue.js +1 -1
- package/dist/components/LayoutNode.vue.d.ts +4 -4
- package/dist/components/LayoutNode.vue.js +1 -1
- package/dist/components/LegendSwatch.vue.d.ts +6 -0
- package/dist/components/LegendSwatch.vue.js +4 -0
- package/dist/components/LoaderMark.vue.d.ts +12 -0
- package/dist/components/LoaderMark.vue.js +4 -0
- package/dist/components/LpActionBar.vue.js +1 -1
- package/dist/components/LpActivityLine.vue.d.ts +58 -0
- package/dist/components/LpActivityLine.vue.js +4 -0
- package/dist/components/LpAddressInput.vue.js +1 -1
- package/dist/components/LpAlert.vue.d.ts +2 -2
- package/dist/components/LpAlert.vue.js +1 -1
- package/dist/components/LpAppShell.vue.d.ts +8 -7
- package/dist/components/LpAppShell.vue.js +1 -1
- package/dist/components/LpAutocomplete.vue.js +1 -1
- package/dist/components/LpAvatar.vue.d.ts +16 -0
- package/dist/components/LpAvatar.vue.js +1 -1
- package/dist/components/LpBadge.vue.d.ts +19 -5
- package/dist/components/LpBadge.vue.js +1 -1
- package/dist/components/LpBreadcrumbs.vue.js +1 -1
- package/dist/components/LpButton.vue.d.ts +2 -2
- package/dist/components/LpButton.vue.js +1 -1
- package/dist/components/LpCalendar.vue.js +1 -1
- package/dist/components/LpCard.vue.d.ts +24 -0
- package/dist/components/LpCard.vue.js +1 -1
- package/dist/components/LpChart.vue.js +131 -160
- package/dist/components/LpCheckbox.vue.d.ts +2 -2
- package/dist/components/LpCheckbox.vue.js +1 -1
- package/dist/components/LpCodeBlock.vue.js +1 -1
- package/dist/components/LpCodeDisplay.vue.d.ts +89 -0
- package/dist/components/LpCodeDisplay.vue.js +4 -0
- package/dist/components/LpCollapse.vue.d.ts +58 -0
- package/dist/components/LpCollapse.vue.js +4 -0
- package/dist/components/LpColorPicker.vue.d.ts +2 -2
- package/dist/components/LpColorPicker.vue.js +1 -1
- package/dist/components/LpCommandPalette.vue.js +34 -23
- package/dist/components/LpConfirmDialog.vue.js +1 -1
- package/dist/components/LpConfirmHost.vue.js +1 -1
- package/dist/components/LpContextMenu.vue.js +1 -1
- package/dist/components/LpCopyButton.vue.d.ts +82 -0
- package/dist/components/LpCopyButton.vue.js +4 -0
- package/dist/components/LpCountdown.vue.d.ts +100 -0
- package/dist/components/LpCountdown.vue.js +4 -0
- package/dist/components/LpDataList.vue.d.ts +66 -0
- package/dist/components/LpDataList.vue.js +4 -0
- package/dist/components/LpDatePicker.vue.d.ts +3 -1
- package/dist/components/LpDatePicker.vue.js +1 -1
- package/dist/components/LpDateRangePicker.vue.d.ts +3 -1
- package/dist/components/LpDateRangePicker.vue.js +1 -1
- package/dist/components/LpDisclosure.vue.js +1 -1
- package/dist/components/LpDock.vue.d.ts +74 -0
- package/dist/components/LpDock.vue.js +204 -0
- package/dist/components/LpDrawer.vue.js +1 -1
- package/dist/components/LpDropdownMenu.vue.js +1 -1
- package/dist/components/LpDropzone.vue.d.ts +8 -1
- package/dist/components/LpDropzone.vue.js +36 -15
- package/dist/components/LpEditable.vue.d.ts +85 -0
- package/dist/components/LpEditable.vue.js +4 -0
- package/dist/components/LpEmptyState.vue.js +1 -1
- package/dist/components/LpFieldNotice.vue.js +1 -1
- package/dist/components/LpFileTree.vue.js +1 -1
- package/dist/components/LpFileTreeNode.vue.js +1 -1
- package/dist/components/LpFormField.vue.js +1 -1
- package/dist/components/LpFrame.vue.d.ts +22 -0
- package/dist/components/LpFrame.vue.js +4 -0
- package/dist/components/LpGauge.vue.d.ts +116 -0
- package/dist/components/LpGauge.vue.js +4 -0
- package/dist/components/LpGlowBorder.vue.d.ts +47 -0
- package/dist/components/LpGlowBorder.vue.js +4 -0
- package/dist/components/LpHintExample.vue.d.ts +2 -2
- package/dist/components/LpHintExample.vue.js +1 -1
- package/dist/components/LpHintLayer.vue.js +1 -1
- package/dist/components/LpHints.vue.js +1 -1
- package/dist/components/LpHoverCard.vue.d.ts +60 -0
- package/dist/components/LpHoverCard.vue.js +4 -0
- package/dist/components/LpIcon.vue.js +1 -1
- package/dist/components/LpIdenticon.vue.d.ts +37 -0
- package/dist/components/LpIdenticon.vue.js +4 -0
- package/dist/components/LpImageEditor.vue.js +13 -19
- package/dist/components/LpInfraNode.vue.js +1 -1
- package/dist/components/LpInput.vue.d.ts +10 -0
- package/dist/components/LpInput.vue.js +1 -1
- package/dist/components/LpLightbox.vue.js +1 -1
- package/dist/components/LpLoader.vue.d.ts +106 -0
- package/dist/components/LpLoader.vue.js +4 -0
- package/dist/components/LpLogViewer.vue.js +1 -1
- package/dist/components/LpMagnetic.vue.d.ts +28 -0
- package/dist/components/LpMagnetic.vue.js +4 -0
- package/dist/components/LpMapPicker.vue.js +1 -1
- package/dist/components/LpMasonry.vue.d.ts +42 -0
- package/dist/components/LpMasonry.vue.js +4 -0
- package/dist/components/LpMediaGallery.vue.js +1 -1
- package/dist/components/LpModal.vue.js +1 -1
- package/dist/components/LpModalNav.vue.js +1 -1
- package/dist/components/LpNotificationBell.vue.d.ts +15 -6
- package/dist/components/LpNotificationBell.vue.js +1 -1
- package/dist/components/LpNumberField.vue.d.ts +57 -0
- package/dist/components/LpNumberField.vue.js +1 -1
- package/dist/components/LpNumberFlow.vue.js +1 -1
- package/dist/components/LpOtpInput.vue.d.ts +12 -4
- package/dist/components/LpOtpInput.vue.js +1 -1
- package/dist/components/LpPagination.vue.js +1 -1
- package/dist/components/LpPaletteFacts.vue.js +2 -2
- package/dist/components/LpPaletteHeader.vue.js +2 -2
- package/dist/components/LpPalettePreview.vue.js +1 -1
- package/dist/components/LpPaletteStats.vue.js +2 -2
- package/dist/components/LpPasswordInput.vue.d.ts +19 -2
- package/dist/components/LpPasswordInput.vue.js +1 -1
- package/dist/components/LpPhoneInput.vue.js +1 -1
- package/dist/components/LpPie.vue.d.ts +3 -1
- package/dist/components/LpPie.vue.js +1 -1
- package/dist/components/LpPipeline.vue.d.ts +91 -0
- package/dist/components/LpPipeline.vue.js +4 -0
- package/dist/components/LpPopover.vue.d.ts +2 -2
- package/dist/components/LpPopover.vue.js +1 -1
- package/dist/components/LpProgress.vue.d.ts +11 -4
- package/dist/components/LpProgress.vue.js +1 -1
- package/dist/components/LpQuota.vue.d.ts +68 -0
- package/dist/components/LpQuota.vue.js +4 -0
- package/dist/components/LpRadioGroup.vue.js +1 -1
- package/dist/components/LpRangeCalendar.vue.js +1 -1
- package/dist/components/LpRangeSlider.vue.js +1 -1
- package/dist/components/LpRelativeTime.vue.d.ts +41 -0
- package/dist/components/LpRelativeTime.vue.js +4 -0
- package/dist/components/LpRepeater.vue.d.ts +48 -0
- package/dist/components/LpRepeater.vue.js +4 -0
- package/dist/components/LpRevealOnScroll.vue.d.ts +67 -0
- package/dist/components/LpRevealOnScroll.vue.js +4 -0
- package/dist/components/LpRollingText.vue.d.ts +3 -1
- package/dist/components/LpRollingText.vue.js +1 -1
- package/dist/components/LpScramble.vue.d.ts +55 -0
- package/dist/components/LpScramble.vue.js +4 -0
- package/dist/components/LpScrollArea.vue.d.ts +1 -1
- package/dist/components/LpSecretField.vue.d.ts +108 -0
- package/dist/components/LpSecretField.vue.js +4 -0
- package/dist/components/LpSection.vue.js +1 -1
- package/dist/components/LpSegmented.vue.js +1 -1
- package/dist/components/LpSelect.vue.d.ts +2 -0
- package/dist/components/LpSelect.vue.js +1 -1
- package/dist/components/LpShaderBackdrop.vue.d.ts +39 -0
- package/dist/components/LpShaderBackdrop.vue.js +4 -0
- package/dist/components/LpShinyText.vue.d.ts +39 -0
- package/dist/components/LpShinyText.vue.js +4 -0
- package/dist/components/LpShortcutsDialog.vue.js +1 -1
- package/dist/components/LpSidebar.vue.js +1 -1
- package/dist/components/LpSidebarNav.vue.js +1 -1
- package/dist/components/LpSlider.vue.js +1 -1
- package/dist/components/LpSparkline.vue.d.ts +4 -3
- package/dist/components/LpSparkline.vue.js +1 -1
- package/dist/components/LpSpotlight.vue.d.ts +37 -0
- package/dist/components/LpSpotlight.vue.js +4 -0
- package/dist/components/LpStat.vue.js +1 -1
- package/dist/components/LpStatus.vue.d.ts +65 -0
- package/dist/components/LpStatus.vue.js +4 -0
- package/dist/components/LpStepMark.vue.d.ts +31 -0
- package/dist/components/LpStepMark.vue.js +4 -0
- package/dist/components/LpStepper.vue.js +1 -1
- package/dist/components/LpSwap.vue.js +1 -1
- package/dist/components/LpSwitch.vue.d.ts +2 -2
- package/dist/components/LpSwitch.vue.js +1 -1
- package/dist/components/LpTable.vue.js +104 -120
- package/dist/components/LpTableFilter.vue.js +1 -1
- package/dist/components/LpTableOfContents.vue.d.ts +6 -1
- package/dist/components/LpTableOfContents.vue.js +1 -1
- package/dist/components/LpTabs.vue.d.ts +5 -5
- package/dist/components/LpTabs.vue.js +25 -33
- package/dist/components/LpTagsInput.vue.js +1 -1
- package/dist/components/LpTextReveal.vue.d.ts +58 -0
- package/dist/components/LpTextReveal.vue.js +4 -0
- package/dist/components/LpTextarea.vue.js +1 -1
- package/dist/components/LpThemeProvider.vue.js +1 -1
- package/dist/components/LpThemeStudio.vue.d.ts +54 -0
- package/dist/components/LpThemeStudio.vue.js +4 -0
- package/dist/components/LpThemeStudioSection.vue.d.ts +16 -0
- package/dist/components/LpThemeStudioSection.vue.js +4 -0
- package/dist/components/LpThemeSwitcher.vue.d.ts +32 -1
- package/dist/components/LpThemeSwitcher.vue.js +1 -1
- package/dist/components/LpTimeField.vue.d.ts +2 -0
- package/dist/components/LpTimeField.vue.js +1 -1
- package/dist/components/LpToaster.vue.js +1 -1
- package/dist/components/LpTooltip.vue.d.ts +2 -2
- package/dist/components/LpTooltip.vue.js +1 -1
- package/dist/components/LpTopologyCanvas.vue.js +1 -1
- package/dist/components/LpTour.vue.js +1 -1
- package/dist/components/LpTruncate.vue.d.ts +34 -0
- package/dist/components/LpTruncate.vue.js +4 -0
- package/dist/components/LpTypewriter.vue.d.ts +61 -0
- package/dist/components/LpTypewriter.vue.js +4 -0
- package/dist/components/LpUptimeBar.vue.js +1 -1
- package/dist/components/LpVideoBackdrop.vue.js +1 -1
- package/dist/components/MenuTitle.vue.js +1 -1
- package/dist/components/OptionContent.vue.d.ts +7 -0
- package/dist/components/OptionContent.vue.js +4 -0
- package/dist/components/PickerField.vue.d.ts +45 -0
- package/dist/components/PickerField.vue.js +4 -0
- package/dist/components/RevealToggle.vue.d.ts +21 -0
- package/dist/components/RevealToggle.vue.js +4 -0
- package/dist/components/StepConnector.vue.d.ts +19 -0
- package/dist/components/StepConnector.vue.js +4 -0
- package/dist/components/TourCard.vue.js +1 -1
- package/dist/components/badge.d.ts +1 -0
- package/dist/components/badge.js +4 -0
- package/dist/components/chart.d.ts +5 -1
- package/dist/components/chart.js +2 -21
- package/dist/components/dateRange.d.ts +11 -0
- package/dist/components/dateRange.js +12 -0
- package/dist/components/dock.d.ts +19 -0
- package/dist/components/dock.js +16 -0
- package/dist/components/dropdown.d.ts +10 -1
- package/dist/components/dropdown.js +7 -2
- package/dist/components/fieldText.d.ts +38 -0
- package/dist/components/fieldText.js +53 -0
- package/dist/components/fileTree.d.ts +7 -3
- package/dist/components/fileTree.js +12 -18
- package/dist/components/format.d.ts +41 -0
- package/dist/components/format.js +67 -0
- package/dist/components/identicon.d.ts +38 -0
- package/dist/components/identicon.js +85 -0
- package/dist/components/masonry.d.ts +32 -0
- package/dist/components/masonry.js +40 -0
- package/dist/components/menuWhen.js +1 -1
- package/dist/components/meter.d.ts +64 -0
- package/dist/components/meter.js +53 -0
- package/dist/components/otp.d.ts +1 -1
- package/dist/components/otp.js +7 -2
- package/dist/components/pipeline.d.ts +55 -0
- package/dist/components/pipeline.js +51 -0
- package/dist/components/quota.d.ts +57 -0
- package/dist/components/quota.js +40 -0
- package/dist/components/relativeTime.d.ts +24 -0
- package/dist/components/relativeTime.js +56 -0
- package/dist/components/reveal.d.ts +18 -0
- package/dist/components/reveal.js +32 -0
- package/dist/components/scramble.d.ts +68 -0
- package/dist/components/scramble.js +58 -0
- package/dist/components/shaderBackdrop.d.ts +20 -0
- package/dist/components/shaderBackdrop.js +156 -0
- package/dist/components/slider.d.ts +5 -0
- package/dist/components/slider.js +24 -0
- package/dist/components/slotText.d.ts +2 -0
- package/dist/components/slotText.js +9 -0
- package/dist/components/status.d.ts +14 -0
- package/dist/components/status.js +22 -0
- package/dist/components/tableFacets.d.ts +8 -0
- package/dist/components/tableFacets.js +19 -0
- package/dist/components/textSplit.d.ts +17 -0
- package/dist/components/textSplit.js +24 -0
- package/dist/components/timeSpan.d.ts +78 -0
- package/dist/components/timeSpan.js +85 -0
- package/dist/components/tone.d.ts +43 -0
- package/dist/components/tone.js +82 -0
- package/dist/components/tour.js +3 -2
- package/dist/components/typewriter.d.ts +36 -0
- package/dist/components/typewriter.js +53 -0
- package/dist/components/videoBackdrop.js +5 -6
- package/dist/composables/easing.d.ts +22 -1
- package/dist/composables/easing.js +42 -1
- package/dist/composables/pseudoLocale.d.ts +15 -0
- package/dist/composables/pseudoLocale.js +96 -0
- package/dist/composables/scroll.js +5 -3
- package/dist/composables/useClipboard.d.ts +4 -1
- package/dist/composables/useClipboard.js +12 -2
- package/dist/composables/useField.d.ts +13 -0
- package/dist/composables/useField.js +26 -1
- package/dist/composables/useForm.js +32 -9
- package/dist/composables/useInView.d.ts +11 -0
- package/dist/composables/useInView.js +39 -0
- package/dist/composables/useLoadingGate.d.ts +8 -0
- package/dist/composables/useLoadingGate.js +38 -0
- package/dist/composables/useLpConfig.d.ts +10 -0
- package/dist/composables/useLpConfig.js +11 -1
- package/dist/composables/useMediaQuery.js +3 -1
- package/dist/composables/useNow.d.ts +16 -0
- package/dist/composables/useNow.js +39 -0
- package/dist/composables/usePersisted.js +14 -7
- package/dist/composables/usePillTransition.d.ts +5 -2
- package/dist/composables/usePillTransition.js +4 -3
- package/dist/composables/usePointerFrame.d.ts +18 -0
- package/dist/composables/usePointerFrame.js +31 -0
- package/dist/composables/useReducedMotion.d.ts +2 -0
- package/dist/composables/useReducedMotion.js +7 -0
- package/dist/composables/useRepeater.d.ts +17 -0
- package/dist/composables/useRepeater.js +31 -0
- package/dist/composables/useResizeObserver.d.ts +8 -0
- package/dist/composables/useResizeObserver.js +33 -0
- package/dist/composables/useRevealedValue.d.ts +31 -0
- package/dist/composables/useRevealedValue.js +26 -0
- package/dist/composables/useScramble.d.ts +42 -0
- package/dist/composables/useScramble.js +76 -0
- package/dist/composables/useShift.js +2 -10
- package/dist/composables/useSpotlight.d.ts +18 -0
- package/dist/composables/useSpotlight.js +53 -0
- package/dist/composables/useTilt.js +26 -18
- package/dist/composables/useTween.d.ts +43 -0
- package/dist/composables/useTween.js +69 -0
- package/dist/composables/useView.d.ts +18 -0
- package/dist/composables/useView.js +64 -0
- package/dist/icons-all.js +1 -1
- package/dist/index.d.ts +98 -1
- package/dist/index.js +263 -105
- package/dist/theme/define.d.ts +12 -0
- package/dist/theme/studio.d.ts +90 -0
- package/package.json +8 -2
- package/src/component-names.ts +33 -0
- package/src/components/AttentionDot.vue +27 -0
- package/src/components/ContextMenuItems.vue +5 -2
- package/src/components/FieldWrapper.vue +38 -0
- package/src/components/LayoutNode.vue +5 -9
- package/src/components/LegendSwatch.vue +15 -0
- package/src/components/LoaderMark.vue +90 -0
- package/src/components/LpActionBar.vue +12 -20
- package/src/components/LpActivityLine.vue +186 -0
- package/src/components/LpAlert.vue +54 -24
- package/src/components/LpAppShell.vue +7 -11
- package/src/components/LpAutocomplete.vue +16 -14
- package/src/components/LpAvatar.vue +17 -2
- package/src/components/LpBadge.vue +77 -13
- package/src/components/LpBreadcrumbs.vue +101 -35
- package/src/components/LpButton.vue +15 -3
- package/src/components/LpCard.vue +30 -7
- package/src/components/LpChart.vue +162 -171
- package/src/components/LpCheckbox.vue +10 -4
- package/src/components/LpCodeBlock.vue +11 -19
- package/src/components/LpCodeDisplay.vue +228 -0
- package/src/components/LpCollapse.vue +162 -0
- package/src/components/LpColorPicker.vue +10 -1
- package/src/components/LpCommandPalette.vue +38 -24
- package/src/components/LpContextMenu.vue +13 -3
- package/src/components/LpCopyButton.vue +185 -0
- package/src/components/LpCountdown.vue +308 -0
- package/src/components/LpDataList.vue +154 -0
- package/src/components/LpDatePicker.vue +55 -104
- package/src/components/LpDateRangePicker.vue +51 -95
- package/src/components/LpDisclosure.vue +58 -36
- package/src/components/LpDock.vue +274 -0
- package/src/components/LpDrawer.vue +10 -1
- package/src/components/LpDropdownMenu.vue +11 -2
- package/src/components/LpDropzone.vue +34 -13
- package/src/components/LpEditable.vue +295 -0
- package/src/components/LpFileTree.vue +5 -1
- package/src/components/LpFileTreeNode.vue +25 -50
- package/src/components/LpFormField.vue +22 -3
- package/src/components/LpFrame.vue +200 -0
- package/src/components/LpGauge.vue +287 -0
- package/src/components/LpGlowBorder.vue +60 -0
- package/src/components/LpHintExample.vue +9 -32
- package/src/components/LpHintLayer.vue +13 -3
- package/src/components/LpHoverCard.vue +175 -0
- package/src/components/LpIdenticon.vue +69 -0
- package/src/components/LpImageEditor.vue +15 -18
- package/src/components/LpInfraNode.vue +27 -16
- package/src/components/LpInput.vue +30 -16
- package/src/components/LpLightbox.vue +44 -23
- package/src/components/LpLoader.vue +145 -0
- package/src/components/LpLogViewer.vue +311 -82
- package/src/components/LpMagnetic.vue +97 -0
- package/src/components/LpMapPicker.vue +26 -28
- package/src/components/LpMasonry.vue +247 -0
- package/src/components/LpModal.vue +10 -1
- package/src/components/LpNotificationBell.vue +33 -49
- package/src/components/LpNumberField.vue +79 -14
- package/src/components/LpNumberFlow.vue +10 -35
- package/src/components/LpOtpInput.vue +7 -2
- package/src/components/LpPagination.vue +38 -4
- package/src/components/LpPalettePreview.vue +2 -7
- package/src/components/LpPasswordInput.vue +25 -18
- package/src/components/LpPhoneInput.vue +12 -3
- package/src/components/LpPie.vue +197 -36
- package/src/components/LpPipeline.vue +366 -0
- package/src/components/LpPopover.vue +14 -1
- package/src/components/LpProgress.vue +22 -84
- package/src/components/LpQuota.vue +197 -0
- package/src/components/LpRangeSlider.vue +5 -1
- package/src/components/LpRelativeTime.vue +90 -0
- package/src/components/LpRepeater.vue +131 -0
- package/src/components/LpRevealOnScroll.vue +125 -0
- package/src/components/LpRollingText.vue +12 -1
- package/src/components/LpScramble.vue +107 -0
- package/src/components/LpSecretField.vue +320 -0
- package/src/components/LpSegmented.vue +3 -10
- package/src/components/LpSelect.vue +74 -65
- package/src/components/LpShaderBackdrop.vue +434 -0
- package/src/components/LpShinyText.vue +139 -0
- package/src/components/LpSidebar.vue +2 -0
- package/src/components/LpSlider.vue +5 -1
- package/src/components/LpSparkline.vue +55 -37
- package/src/components/LpSpotlight.vue +51 -0
- package/src/components/LpStat.vue +6 -2
- package/src/components/LpStatus.vue +127 -0
- package/src/components/LpStepMark.vue +138 -0
- package/src/components/LpStepper.vue +37 -43
- package/src/components/LpSwap.vue +2 -2
- package/src/components/LpSwitch.vue +15 -22
- package/src/components/LpTable.vue +47 -63
- package/src/components/LpTableFilter.vue +1 -0
- package/src/components/LpTableOfContents.vue +53 -29
- package/src/components/LpTabs.vue +10 -21
- package/src/components/LpTagsInput.vue +53 -37
- package/src/components/LpTextReveal.vue +236 -0
- package/src/components/LpTextarea.vue +11 -11
- package/src/components/LpThemeStudio.vue +216 -0
- package/src/components/LpThemeStudioSection.vue +16 -0
- package/src/components/LpThemeSwitcher.vue +156 -47
- package/src/components/LpTimeField.vue +9 -1
- package/src/components/LpToaster.vue +63 -83
- package/src/components/LpTooltip.vue +10 -1
- package/src/components/LpTour.vue +24 -13
- package/src/components/LpTruncate.vue +135 -0
- package/src/components/LpTypewriter.vue +236 -0
- package/src/components/LpUptimeBar.vue +6 -5
- package/src/components/LpVideoBackdrop.vue +15 -13
- package/src/components/OptionContent.vue +17 -0
- package/src/components/PickerField.vue +59 -0
- package/src/components/RevealToggle.vue +51 -0
- package/src/components/StepConnector.vue +54 -0
- package/src/components/TourCard.vue +29 -16
- package/src/components/badge.ts +8 -0
- package/src/components/chart.ts +8 -23
- package/src/components/dateRange.ts +25 -0
- package/src/components/dock.ts +31 -0
- package/src/components/dropdown.ts +15 -3
- package/src/components/fieldText.ts +95 -0
- package/src/components/fileTree.ts +19 -21
- package/src/components/format.ts +136 -0
- package/src/components/identicon.ts +160 -0
- package/src/components/masonry.ts +73 -0
- package/src/components/meter.ts +122 -0
- package/src/components/otp.ts +14 -3
- package/src/components/pipeline.ts +101 -0
- package/src/components/quota.ts +111 -0
- package/src/components/relativeTime.ts +118 -0
- package/src/components/reveal.ts +56 -0
- package/src/components/scramble.ts +138 -0
- package/src/components/shaderBackdrop.ts +208 -0
- package/src/components/slider.ts +30 -0
- package/src/components/slotText.ts +13 -0
- package/src/components/status.ts +46 -0
- package/src/components/tableFacets.ts +25 -0
- package/src/components/textSplit.ts +55 -0
- package/src/components/timeSpan.ts +183 -0
- package/src/components/tone.ts +144 -0
- package/src/components/tour.ts +3 -2
- package/src/components/typewriter.ts +104 -0
- package/src/components/videoBackdrop.ts +7 -6
- package/src/composables/easing.ts +66 -1
- package/src/composables/pseudoLocale.ts +105 -0
- package/src/composables/scroll.ts +6 -3
- package/src/composables/useClipboard.ts +25 -3
- package/src/composables/useField.ts +38 -1
- package/src/composables/useForm.ts +41 -11
- package/src/composables/useInView.ts +61 -0
- package/src/composables/useLoadingGate.ts +63 -0
- package/src/composables/useLpConfig.ts +20 -1
- package/src/composables/useMediaQuery.ts +6 -2
- package/src/composables/useNow.ts +84 -0
- package/src/composables/usePersisted.ts +19 -8
- package/src/composables/usePillTransition.ts +21 -13
- package/src/composables/usePointerFrame.ts +72 -0
- package/src/composables/useReducedMotion.ts +22 -0
- package/src/composables/useRepeater.ts +44 -0
- package/src/composables/useResizeObserver.ts +59 -0
- package/src/composables/useRevealedValue.ts +84 -0
- package/src/composables/useScramble.ts +152 -0
- package/src/composables/useShift.ts +10 -16
- package/src/composables/useSpotlight.ts +82 -0
- package/src/composables/useTilt.ts +40 -23
- package/src/composables/useTween.ts +149 -0
- package/src/composables/useView.ts +96 -0
- package/src/index.css +1 -0
- package/src/index.ts +143 -1
- package/src/kit-icons.ts +1 -1
- package/src/theme/define.ts +65 -0
- package/src/theme/studio.ts +202 -0
- package/src/tokens/effects.css +151 -0
- package/src/tokens/tokens.css +131 -39
- package/src/tokens/utilities.css +81 -0
- package/dist/assets/LpTabs-Bk7v4bZz.css +0 -18
- package/dist/chunks/LpAlert-BdvxvcWE.js +0 -85
- package/dist/chunks/LpBadge-Fe0D1bYx.js +0 -62
- package/dist/chunks/LpBreadcrumbs-rzOKkLiI.js +0 -98
- package/dist/chunks/LpDatePicker-BMfM454Y.js +0 -243
- package/dist/chunks/LpDateRangePicker-CNb9X3eL.js +0 -195
- package/dist/chunks/LpNumberField-DO1ufKvE.js +0 -107
- package/dist/chunks/LpStepper-C2slwObu.js +0 -90
- package/dist/chunks/LpSwitch-CZy9_IoA.js +0 -132
- package/dist/chunks/LpThemeSwitcher-CDoziW0z.js +0 -166
- package/dist/chunks/TourCard-BKI7X9-r.js +0 -105
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
export default { inheritAttrs: false }
|
|
3
|
+
|
|
4
|
+
export interface EditableLabels extends Record<string, string> {
|
|
5
|
+
edit: string
|
|
6
|
+
empty: string
|
|
7
|
+
saving: string
|
|
8
|
+
failed: string
|
|
9
|
+
}
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<script setup lang="ts">
|
|
13
|
+
/*
|
|
14
|
+
* Text that is edited where it stands: a server's name in its header, a
|
|
15
|
+
* channel's topic, a note on a row. Reading it is the common case, so it reads
|
|
16
|
+
* as plain text; a click, Enter or F2 turns that same text into a field.
|
|
17
|
+
*
|
|
18
|
+
* <LpEditable v-model="server.name" label="Server name" :save="rename" />
|
|
19
|
+
*
|
|
20
|
+
* Enter (Ctrl/⌘+Enter when `multiline`) or leaving the field commits; Escape
|
|
21
|
+
* puts the old text back. A commit that changes nothing just closes.
|
|
22
|
+
*
|
|
23
|
+
* Saving is optimistic: the new text shows at once, dimmed with a spinner,
|
|
24
|
+
* while `save` runs. If `save` throws, the field opens again holding what was
|
|
25
|
+
* typed and the error floats under it (LpFieldNotice), so nothing typed is
|
|
26
|
+
* lost and the person can fix it or press Escape. The model only changes once
|
|
27
|
+
* the save succeeded, so the app never holds a value its server refused.
|
|
28
|
+
*
|
|
29
|
+
* The field is the text's twin: same font, same padding, sized by an
|
|
30
|
+
* invisible copy of what is typed, so switching between reading and editing
|
|
31
|
+
* moves nothing around it. The pencil beside the text keeps its room while
|
|
32
|
+
* editing too (an empty spacer of its width), so the row stays where it was. What does change size (a longer name) eases
|
|
33
|
+
* through LpShift.
|
|
34
|
+
*/
|
|
35
|
+
import { computed, nextTick, ref, watch } from "vue"
|
|
36
|
+
import { useFieldNotice } from "../composables/useFieldNotice"
|
|
37
|
+
import { useLabels } from "../composables/useLpConfig"
|
|
38
|
+
import { useMergedAttrs } from "../composables/useMergedClass"
|
|
39
|
+
import LpFieldNotice from "./LpFieldNotice.vue"
|
|
40
|
+
import LpIcon from "./LpIcon.vue"
|
|
41
|
+
import LpLoader from "./LpLoader.vue"
|
|
42
|
+
import LpRollingText from "./LpRollingText.vue"
|
|
43
|
+
import LpShift from "./LpShift.vue"
|
|
44
|
+
|
|
45
|
+
const props = withDefaults(
|
|
46
|
+
defineProps<{
|
|
47
|
+
modelValue?: string
|
|
48
|
+
/** What the text is, for assistive tech ("Server name"). */
|
|
49
|
+
label?: string
|
|
50
|
+
/** Shown when the text is empty; clicking it starts editing. */
|
|
51
|
+
placeholder?: string
|
|
52
|
+
/** A textarea; Enter adds a line and Ctrl/⌘+Enter commits. */
|
|
53
|
+
multiline?: boolean
|
|
54
|
+
/**
|
|
55
|
+
* Persists the new text. May be async and may throw: a throw reopens the
|
|
56
|
+
* field with the typed text and shows the error's message.
|
|
57
|
+
*/
|
|
58
|
+
save?: (value: string) => unknown
|
|
59
|
+
/**
|
|
60
|
+
* Checks the text before saving. Return an error message to refuse it
|
|
61
|
+
* (the field stays open with the message under it), anything else to accept.
|
|
62
|
+
*/
|
|
63
|
+
validate?: (value: string) => string | true | void | null | undefined
|
|
64
|
+
/** Trim spaces around the text on commit. */
|
|
65
|
+
trim?: boolean
|
|
66
|
+
/** Refuse an empty commit (with the `required` message) instead of saving "". */
|
|
67
|
+
required?: boolean
|
|
68
|
+
maxlength?: number
|
|
69
|
+
disabled?: boolean
|
|
70
|
+
/** Shown as text, never editable — for a viewer without the right to change it. */
|
|
71
|
+
readonly?: boolean
|
|
72
|
+
size?: "sm" | "md" | "lg"
|
|
73
|
+
labels?: Partial<EditableLabels & { required: string }>
|
|
74
|
+
}>(),
|
|
75
|
+
{ modelValue: "", trim: true, size: "md" },
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
const emit = defineEmits<{
|
|
79
|
+
(e: "update:modelValue", value: string): void
|
|
80
|
+
/** Editing opened. */
|
|
81
|
+
(e: "edit"): void
|
|
82
|
+
/** Editing closed without a change. */
|
|
83
|
+
(e: "cancel"): void
|
|
84
|
+
/** The text was saved (after `save` resolved, when there is one). */
|
|
85
|
+
(e: "saved", value: string): void
|
|
86
|
+
(e: "error", error: unknown): void
|
|
87
|
+
}>()
|
|
88
|
+
|
|
89
|
+
const text = useLabels<EditableLabels & { required: string }>(
|
|
90
|
+
"editable",
|
|
91
|
+
{ edit: "Edit", empty: "Empty", saving: "Saving…", failed: "Couldn't save", required: "Can't be empty" },
|
|
92
|
+
() => props.labels,
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
const editing = ref(false)
|
|
96
|
+
const draft = ref("")
|
|
97
|
+
const pending = ref<string | null>(null)
|
|
98
|
+
const notice = useFieldNotice(4000)
|
|
99
|
+
|
|
100
|
+
// What reads on screen: the text being saved, else the model.
|
|
101
|
+
const shown = computed(() => pending.value ?? props.modelValue)
|
|
102
|
+
const interactive = computed(() => !props.disabled && !props.readonly)
|
|
103
|
+
|
|
104
|
+
const field = ref<HTMLInputElement | HTMLTextAreaElement | null>(null)
|
|
105
|
+
const idle = ref<HTMLElement | null>(null)
|
|
106
|
+
|
|
107
|
+
async function open(selectAll = true) {
|
|
108
|
+
if (!interactive.value || editing.value || pending.value !== null) return
|
|
109
|
+
draft.value = props.modelValue
|
|
110
|
+
editing.value = true
|
|
111
|
+
emit("edit")
|
|
112
|
+
await nextTick()
|
|
113
|
+
field.value?.focus({ preventScroll: true })
|
|
114
|
+
if (selectAll) field.value?.select()
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
async function close(refocus: boolean) {
|
|
118
|
+
editing.value = false
|
|
119
|
+
if (!refocus) return
|
|
120
|
+
await nextTick()
|
|
121
|
+
idle.value?.focus({ preventScroll: true })
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function cancel() {
|
|
125
|
+
notice.clear()
|
|
126
|
+
emit("cancel")
|
|
127
|
+
void close(true)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
let committing = false
|
|
131
|
+
async function commit(refocus: boolean) {
|
|
132
|
+
if (!editing.value || committing || !interactive.value) return
|
|
133
|
+
const value = props.trim ? draft.value.trim() : draft.value
|
|
134
|
+
if (value === props.modelValue) {
|
|
135
|
+
notice.clear()
|
|
136
|
+
emit("cancel")
|
|
137
|
+
return close(refocus)
|
|
138
|
+
}
|
|
139
|
+
const problem = props.required && !value ? text.value.required : props.validate?.(value)
|
|
140
|
+
if (typeof problem === "string" && problem) {
|
|
141
|
+
// The field stays open with the reason under it. Focus is not pulled
|
|
142
|
+
// back: after a blur the person has moved on to something else.
|
|
143
|
+
notice.show(problem, { tone: "danger" })
|
|
144
|
+
return
|
|
145
|
+
}
|
|
146
|
+
notice.clear()
|
|
147
|
+
committing = true
|
|
148
|
+
pending.value = value
|
|
149
|
+
await close(refocus)
|
|
150
|
+
try {
|
|
151
|
+
await props.save?.(value)
|
|
152
|
+
emit("update:modelValue", value)
|
|
153
|
+
emit("saved", value)
|
|
154
|
+
} catch (error) {
|
|
155
|
+
emit("error", error)
|
|
156
|
+
draft.value = value
|
|
157
|
+
editing.value = true
|
|
158
|
+
await nextTick()
|
|
159
|
+
// Back into the field only if focus is not already somewhere else.
|
|
160
|
+
const active = document.activeElement
|
|
161
|
+
if (!active || active === document.body || active === idle.value) field.value?.focus({ preventScroll: true })
|
|
162
|
+
notice.show(error instanceof Error && error.message ? error.message : text.value.failed, { tone: "danger" })
|
|
163
|
+
} finally {
|
|
164
|
+
pending.value = null
|
|
165
|
+
committing = false
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function onIdleKey(event: KeyboardEvent) {
|
|
170
|
+
if (event.key === "Enter" || event.key === "F2" || event.key === " ") {
|
|
171
|
+
event.preventDefault()
|
|
172
|
+
void open()
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function onFieldKey(event: KeyboardEvent) {
|
|
177
|
+
if (event.key === "Escape") {
|
|
178
|
+
event.preventDefault()
|
|
179
|
+
event.stopPropagation()
|
|
180
|
+
cancel()
|
|
181
|
+
} else if (event.key === "Enter" && !event.isComposing && (!props.multiline || event.ctrlKey || event.metaKey)) {
|
|
182
|
+
event.preventDefault()
|
|
183
|
+
void commit(true)
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// An outside change while editing (another tab renamed it) is not overwritten
|
|
188
|
+
// by an old draft unnoticed: the draft follows when the person had not typed.
|
|
189
|
+
let opened = ""
|
|
190
|
+
watch(editing, (on) => (opened = on ? props.modelValue : ""))
|
|
191
|
+
watch(
|
|
192
|
+
() => props.modelValue,
|
|
193
|
+
(next) => {
|
|
194
|
+
if (editing.value && draft.value === opened) draft.value = next
|
|
195
|
+
opened = next
|
|
196
|
+
},
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
const PAD = { sm: "px-1.5 py-0.5 text-xs", md: "px-2 py-1 text-sm", lg: "px-2.5 py-1.5 text-base" } as const
|
|
200
|
+
const spinnerSize = computed(() => (props.size === "sm" ? 11 : 13))
|
|
201
|
+
const singleLineRoll = computed(() => !props.multiline && shown.value.length <= 60 && !!shown.value)
|
|
202
|
+
|
|
203
|
+
const { class: rootClass, attrs: rest } = useMergedAttrs(() => "relative inline-block max-w-full align-baseline")
|
|
204
|
+
</script>
|
|
205
|
+
|
|
206
|
+
<template>
|
|
207
|
+
<span :class="rootClass">
|
|
208
|
+
<LpShift axis="both" class="max-w-full">
|
|
209
|
+
<!-- Reading: the text itself, a button to assistive tech. -->
|
|
210
|
+
<span
|
|
211
|
+
v-if="!editing"
|
|
212
|
+
ref="idle"
|
|
213
|
+
v-bind="rest"
|
|
214
|
+
:role="interactive ? 'button' : undefined"
|
|
215
|
+
:tabindex="interactive ? 0 : undefined"
|
|
216
|
+
:aria-disabled="disabled || undefined"
|
|
217
|
+
:aria-label="interactive ? `${text.edit} ${label ?? ''}: ${shown || placeholder || text.empty}`.replace(' :', ':') : undefined"
|
|
218
|
+
:aria-busy="pending !== null || undefined"
|
|
219
|
+
:title="pending !== null ? text.saving : undefined"
|
|
220
|
+
class="group/edit relative inline-flex max-w-full items-baseline gap-1.5 rounded-control border border-transparent outline-none transition-[background-color,border-color,opacity] duration-(--duration-fast)"
|
|
221
|
+
:class="[
|
|
222
|
+
PAD[size],
|
|
223
|
+
interactive ? 'cursor-text hover:border-line hover:bg-ink/[0.04] focus-visible:ring-2 focus-visible:ring-ring' : '',
|
|
224
|
+
disabled ? 'cursor-not-allowed opacity-55' : '',
|
|
225
|
+
pending !== null ? 'opacity-70' : '',
|
|
226
|
+
multiline ? 'whitespace-pre-wrap break-words' : 'whitespace-nowrap',
|
|
227
|
+
]"
|
|
228
|
+
@click="open()"
|
|
229
|
+
@keydown="onIdleKey"
|
|
230
|
+
>
|
|
231
|
+
<span v-if="!shown" class="text-muted italic">{{ placeholder ?? text.empty }}</span>
|
|
232
|
+
<LpRollingText v-else-if="singleLineRoll" :value="shown" align="start" class="min-w-0" />
|
|
233
|
+
<span v-else class="min-w-0" :class="multiline ? '' : 'truncate'">{{ shown }}</span>
|
|
234
|
+
<!-- At once, since it takes the pencil's place; silent, since the
|
|
235
|
+
text's aria-busy already says it. -->
|
|
236
|
+
<LpLoader
|
|
237
|
+
v-if="pending !== null"
|
|
238
|
+
size="inline"
|
|
239
|
+
:delay="0"
|
|
240
|
+
aria-hidden="true"
|
|
241
|
+
class="shrink-0 self-center text-muted"
|
|
242
|
+
:style="{ fontSize: `${spinnerSize}px` }"
|
|
243
|
+
/>
|
|
244
|
+
<LpIcon
|
|
245
|
+
v-else-if="interactive"
|
|
246
|
+
name="lucide:pencil"
|
|
247
|
+
:size="spinnerSize"
|
|
248
|
+
class="shrink-0 self-center text-muted opacity-0 transition-opacity duration-(--duration-fast) group-hover/edit:opacity-100 group-focus-visible/edit:opacity-100 [@media(hover:none)]:opacity-60"
|
|
249
|
+
/>
|
|
250
|
+
</span>
|
|
251
|
+
|
|
252
|
+
<!-- Editing: the field over an invisible twin of its text, which gives
|
|
253
|
+
the box its size in every browser (no field-sizing needed). The
|
|
254
|
+
field asks for one column (`size`/`cols`), or its default width of
|
|
255
|
+
~20 characters would be the box's minimum. -->
|
|
256
|
+
<span v-else class="inline-flex max-w-full items-baseline gap-1.5">
|
|
257
|
+
<span
|
|
258
|
+
class="relative inline-grid max-w-full min-w-0 rounded-control border bg-surface-soft focus-within:ring-2 focus-within:ring-ring"
|
|
259
|
+
:class="notice.tone.value === 'danger' && notice.message.value ? 'border-danger' : 'border-brand'"
|
|
260
|
+
>
|
|
261
|
+
<span
|
|
262
|
+
aria-hidden="true"
|
|
263
|
+
class="invisible col-start-1 row-start-1 min-w-[4ch]"
|
|
264
|
+
:class="[PAD[size], multiline ? 'whitespace-pre-wrap break-words' : 'whitespace-pre']"
|
|
265
|
+
>{{ (draft || placeholder || " ") + (multiline ? "\n" : "\u200a") }}</span>
|
|
266
|
+
<component
|
|
267
|
+
:is="multiline ? 'textarea' : 'input'"
|
|
268
|
+
ref="field"
|
|
269
|
+
:value="draft"
|
|
270
|
+
:size="multiline ? undefined : 1"
|
|
271
|
+
:cols="multiline ? 1 : undefined"
|
|
272
|
+
:aria-label="label"
|
|
273
|
+
:aria-invalid="(notice.tone.value === 'danger' && !!notice.message.value) || undefined"
|
|
274
|
+
:placeholder="placeholder"
|
|
275
|
+
:maxlength="maxlength"
|
|
276
|
+
:disabled="disabled"
|
|
277
|
+
:readonly="readonly"
|
|
278
|
+
:rows="multiline ? 1 : undefined"
|
|
279
|
+
class="col-start-1 row-start-1 w-full min-w-0 resize-none overflow-hidden bg-transparent text-ink outline-none placeholder:text-muted"
|
|
280
|
+
:class="PAD[size]"
|
|
281
|
+
@input="draft = ($event.target as HTMLInputElement).value"
|
|
282
|
+
@keydown="onFieldKey"
|
|
283
|
+
@blur="commit(false)"
|
|
284
|
+
/>
|
|
285
|
+
</span>
|
|
286
|
+
<span v-if="interactive" aria-hidden="true" class="shrink-0" :style="{ width: `${spinnerSize}px` }" />
|
|
287
|
+
</span>
|
|
288
|
+
</LpShift>
|
|
289
|
+
<!-- The note may be wider than a short text: it gets its own room under
|
|
290
|
+
the text rather than being clipped to the text's width. -->
|
|
291
|
+
<span class="pointer-events-none absolute top-full left-0 h-0 w-[min(22rem,80vw)]">
|
|
292
|
+
<LpFieldNotice :notice="notice" />
|
|
293
|
+
</span>
|
|
294
|
+
</span>
|
|
295
|
+
</template>
|
|
@@ -26,6 +26,7 @@ export default { inheritAttrs: false }
|
|
|
26
26
|
* single tab stop.
|
|
27
27
|
*/
|
|
28
28
|
import { computed, ref, watch } from "vue"
|
|
29
|
+
import { useLocale } from "../composables/useLocale"
|
|
29
30
|
import {
|
|
30
31
|
ancestorIds,
|
|
31
32
|
computeStats,
|
|
@@ -207,6 +208,9 @@ const byId = computed(() => index.value.byId)
|
|
|
207
208
|
// its temporal dead zone when the watcher first runs.
|
|
208
209
|
const stats = computed(() => computeStats(props.nodes, checkedIds.value))
|
|
209
210
|
|
|
211
|
+
// Read by `summary` below, so declared ahead of it for the same reason.
|
|
212
|
+
const locale = useLocale()
|
|
213
|
+
|
|
210
214
|
/**
|
|
211
215
|
* What the ticked set adds up to. Directories are counted but not sized — their
|
|
212
216
|
* bytes arrive through the files inside them, so summing both would double-count.
|
|
@@ -263,7 +267,7 @@ const summary = computed<FileTreeSummary>(() => {
|
|
|
263
267
|
files,
|
|
264
268
|
dirs,
|
|
265
269
|
bytes: sized ? bytes : undefined,
|
|
266
|
-
sizeLabel: sized ? formatSize(bytes) : "—",
|
|
270
|
+
sizeLabel: sized ? formatSize(bytes, locale.value) : "—",
|
|
267
271
|
}
|
|
268
272
|
})
|
|
269
273
|
|
|
@@ -17,7 +17,6 @@ export default { inheritAttrs: false }
|
|
|
17
17
|
* Tab enters the tree once, arrows move within it. The parent owns that state.
|
|
18
18
|
*/
|
|
19
19
|
import { computed } from "vue"
|
|
20
|
-
import { easingToken, prefersReducedMotion } from "../composables/easing"
|
|
21
20
|
import {
|
|
22
21
|
fileIcon,
|
|
23
22
|
formatModified,
|
|
@@ -26,9 +25,14 @@ import {
|
|
|
26
25
|
type FileNode,
|
|
27
26
|
type NodeStats,
|
|
28
27
|
} from "./fileTree"
|
|
28
|
+
import LpBadge from "./LpBadge.vue"
|
|
29
29
|
import LpCheckbox from "./LpCheckbox.vue"
|
|
30
|
+
import LpCollapse from "./LpCollapse.vue"
|
|
30
31
|
import LpContextMenu from "./LpContextMenu.vue"
|
|
31
32
|
import LpIcon from "./LpIcon.vue"
|
|
33
|
+
import LpLoader from "./LpLoader.vue"
|
|
34
|
+
import { staggerDelay } from "./reveal"
|
|
35
|
+
import { useLocale } from "../composables/useLocale"
|
|
32
36
|
import { useMergedAttrs } from "../composables/useMergedClass"
|
|
33
37
|
|
|
34
38
|
const props = defineProps<{
|
|
@@ -88,10 +92,14 @@ const checkState = computed(() =>
|
|
|
88
92
|
|
|
89
93
|
// A directory shows the rolled-up size of what's under it, so a backup picker
|
|
90
94
|
// can answer "how much is this folder" without expanding it.
|
|
95
|
+
// The app's locale (reka's ConfigProvider), so sizes and dates read the way
|
|
96
|
+
// the rest of its interface does.
|
|
97
|
+
const locale = useLocale()
|
|
98
|
+
|
|
91
99
|
const sizeLabel = computed(() => {
|
|
92
100
|
if (!props.showSize) return ""
|
|
93
101
|
const bytes = stat.value?.size
|
|
94
|
-
return bytes === undefined ? "" : formatSize(bytes)
|
|
102
|
+
return bytes === undefined ? "" : formatSize(bytes, locale.value)
|
|
95
103
|
})
|
|
96
104
|
|
|
97
105
|
/**
|
|
@@ -107,7 +115,7 @@ const countLabel = computed(() => {
|
|
|
107
115
|
|
|
108
116
|
const modifiedLabel = computed(() =>
|
|
109
117
|
props.showModified && props.node.modified !== undefined
|
|
110
|
-
? formatModified(props.node.modified)
|
|
118
|
+
? formatModified(props.node.modified, locale.value)
|
|
111
119
|
: "",
|
|
112
120
|
)
|
|
113
121
|
|
|
@@ -116,34 +124,7 @@ const modifiedLabel = computed(() =>
|
|
|
116
124
|
* spend a second unfolding — past the cap every remaining row comes in together.
|
|
117
125
|
*/
|
|
118
126
|
function rowDelay(index: number): string {
|
|
119
|
-
return `${
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// Expand/collapse the branch by animating from 0 to its measured height. The
|
|
123
|
-
// Web Animations API is used directly (rather than a CSS class) because the
|
|
124
|
-
// target height isn't known until the rows are in the DOM.
|
|
125
|
-
function onBranchEnter(el: Element, done: () => void) {
|
|
126
|
-
if (prefersReducedMotion()) return done()
|
|
127
|
-
const height = (el as HTMLElement).scrollHeight
|
|
128
|
-
el.animate(
|
|
129
|
-
[
|
|
130
|
-
{ height: "0px", opacity: 0 },
|
|
131
|
-
{ height: `${height}px`, opacity: 1 },
|
|
132
|
-
],
|
|
133
|
-
{ duration: 220, easing: easingToken("ease-emphasized") },
|
|
134
|
-
).onfinish = () => done()
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
function onBranchLeave(el: Element, done: () => void) {
|
|
138
|
-
if (prefersReducedMotion()) return done()
|
|
139
|
-
const height = (el as HTMLElement).scrollHeight
|
|
140
|
-
el.animate(
|
|
141
|
-
[
|
|
142
|
-
{ height: `${height}px`, opacity: 1 },
|
|
143
|
-
{ height: "0px", opacity: 0 },
|
|
144
|
-
],
|
|
145
|
-
{ duration: 180, easing: easingToken("ease-emphasized") },
|
|
146
|
-
).onfinish = () => done()
|
|
127
|
+
return `${staggerDelay(index, 0, 18, 10)}ms`
|
|
147
128
|
}
|
|
148
129
|
|
|
149
130
|
function onActivate() {
|
|
@@ -208,11 +189,14 @@ const { class: rootClass, attrs: rest } = useMergedAttrs(
|
|
|
208
189
|
:class="canExpand ? 'cursor-pointer rounded-sm hover:bg-line' : ''"
|
|
209
190
|
@click.stop="canExpand && !node.disabled ? emit('toggle', node) : undefined"
|
|
210
191
|
>
|
|
211
|
-
|
|
192
|
+
<!-- At once, since it takes the chevron's place; silent, since a
|
|
193
|
+
"Loading…" inside the row would become part of its name. -->
|
|
194
|
+
<LpLoader
|
|
212
195
|
v-if="isLoading"
|
|
213
|
-
|
|
214
|
-
:
|
|
215
|
-
|
|
196
|
+
size="inline"
|
|
197
|
+
:delay="0"
|
|
198
|
+
aria-hidden="true"
|
|
199
|
+
class="text-[13px] text-muted"
|
|
216
200
|
/>
|
|
217
201
|
<LpIcon
|
|
218
202
|
v-else-if="canExpand"
|
|
@@ -251,12 +235,7 @@ const { class: rootClass, attrs: rest } = useMergedAttrs(
|
|
|
251
235
|
|
|
252
236
|
<!-- Partial-selection counter: says outright how much of the folder is
|
|
253
237
|
ticked, which a half-state checkbox alone doesn't convey. -->
|
|
254
|
-
<
|
|
255
|
-
v-if="countLabel"
|
|
256
|
-
class="shrink-0 rounded-pill bg-brand-soft px-1.5 py-0.5 text-[11px] font-medium tabular-nums text-brand"
|
|
257
|
-
>
|
|
258
|
-
{{ countLabel }}
|
|
259
|
-
</span>
|
|
238
|
+
<LpBadge v-if="countLabel" tone="brand" size="sm" class="tabular-nums">{{ countLabel }}</LpBadge>
|
|
260
239
|
|
|
261
240
|
<!-- Metadata columns: tabular figures so sizes line up down the tree.
|
|
262
241
|
`meta` is free text, so it truncates rather than pushing the size
|
|
@@ -279,14 +258,10 @@ const { class: rootClass, attrs: rest } = useMergedAttrs(
|
|
|
279
258
|
</div>
|
|
280
259
|
</LpContextMenu>
|
|
281
260
|
|
|
282
|
-
<!--
|
|
283
|
-
|
|
284
|
-
<
|
|
285
|
-
|
|
286
|
-
@enter="onBranchEnter"
|
|
287
|
-
@leave="onBranchLeave"
|
|
288
|
-
>
|
|
289
|
-
<ul v-if="isOpen && hasChildren" role="group" class="flex min-w-0 flex-col overflow-hidden">
|
|
261
|
+
<!-- The branch folds open and shut (LpCollapse); a toggle mid-way reverses
|
|
262
|
+
from where it is. Rows inside stagger themselves in. -->
|
|
263
|
+
<LpCollapse :open="isOpen && hasChildren">
|
|
264
|
+
<ul role="group" class="flex min-w-0 flex-col overflow-hidden">
|
|
290
265
|
<LpFileTreeNode
|
|
291
266
|
v-for="(child, i) in children"
|
|
292
267
|
:key="child.id"
|
|
@@ -315,6 +290,6 @@ const { class: rootClass, attrs: rest } = useMergedAttrs(
|
|
|
315
290
|
</template>
|
|
316
291
|
</LpFileTreeNode>
|
|
317
292
|
</ul>
|
|
318
|
-
</
|
|
293
|
+
</LpCollapse>
|
|
319
294
|
</li>
|
|
320
295
|
</template>
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// appended to it, so opt out of the automatic pass-through that would add it
|
|
4
4
|
// a second time, unmerged.
|
|
5
5
|
export default { inheritAttrs: false }
|
|
6
|
+
|
|
6
7
|
</script>
|
|
7
8
|
|
|
8
9
|
<script setup lang="ts">
|
|
@@ -16,7 +17,7 @@ export default { inheritAttrs: false }
|
|
|
16
17
|
* eased box, so the thing being typed into never moves.
|
|
17
18
|
*/
|
|
18
19
|
import { Label } from "reka-ui"
|
|
19
|
-
import { computed, useId, useSlots } from "vue"
|
|
20
|
+
import { computed, ref, useId, useSlots } from "vue"
|
|
20
21
|
import LpFieldNotice from "./LpFieldNotice.vue"
|
|
21
22
|
import LpShift from "./LpShift.vue"
|
|
22
23
|
import { fieldMessageId, provideField } from "../composables/useField"
|
|
@@ -67,6 +68,24 @@ defineExpose({ notify: notice.show, clearNotice: notice.clear })
|
|
|
67
68
|
const { class: rootClass, attrs: rest } = useMergedAttrs(
|
|
68
69
|
"flex min-w-0 flex-col gap-1.5",
|
|
69
70
|
)
|
|
71
|
+
/*
|
|
72
|
+
* A label's `for` only focuses an element that can be labelled (an input, a
|
|
73
|
+
* button, a select). Composite controls put the field id on a group or have no
|
|
74
|
+
* single input (a time field's segments, a pin input's cells), so clicking the
|
|
75
|
+
* label did nothing there. Then the label focuses the first focusable thing in
|
|
76
|
+
* the control instead.
|
|
77
|
+
*/
|
|
78
|
+
const control = ref<HTMLElement | null>(null)
|
|
79
|
+
const LABELABLE = "input, button, select, textarea, meter, output, progress"
|
|
80
|
+
function focusControl() {
|
|
81
|
+
const target = document.getElementById(id.value)
|
|
82
|
+
if (target?.matches(LABELABLE)) return
|
|
83
|
+
const first = control.value?.querySelector<HTMLElement>(
|
|
84
|
+
'input:not([type="hidden"]):not([disabled]), button:not([disabled]), select, textarea, [tabindex]:not([tabindex="-1"]), [contenteditable="true"]',
|
|
85
|
+
)
|
|
86
|
+
first?.focus()
|
|
87
|
+
}
|
|
88
|
+
|
|
70
89
|
</script>
|
|
71
90
|
|
|
72
91
|
<template>
|
|
@@ -78,7 +97,7 @@ const { class: rootClass, attrs: rest } = useMergedAttrs(
|
|
|
78
97
|
<div
|
|
79
98
|
:class="rootClass"
|
|
80
99
|
v-bind="rest">
|
|
81
|
-
<Label v-if="label" :id="`${id}-label`" :for="id" class="text-sm font-medium text-ink">
|
|
100
|
+
<Label v-if="label" :id="`${id}-label`" :for="id" class="text-sm font-medium text-ink" @click="focusControl">
|
|
82
101
|
{{ label }}
|
|
83
102
|
<span v-if="required" class="text-danger">*</span>
|
|
84
103
|
</Label>
|
|
@@ -86,7 +105,7 @@ const { class: rootClass, attrs: rest } = useMergedAttrs(
|
|
|
86
105
|
<!-- The note from `notify` floats from here, over the message line below,
|
|
87
106
|
so raising one never moves the form; the line fades out under it
|
|
88
107
|
rather than showing through. -->
|
|
89
|
-
<div class="relative">
|
|
108
|
+
<div ref="control" class="relative">
|
|
90
109
|
<slot :id="id" :describedBy="hasMessage ? messageId : undefined" />
|
|
91
110
|
<LpFieldNotice :notice="notice" :id="noticeId" />
|
|
92
111
|
</div>
|