@leavepulse/ui 0.77.2 → 0.78.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 +68 -0
- package/dist/assets/{LpCommandPalette-DOIZHw-g.css → LpCommandPalette-DDJKICKh.css} +19 -19
- package/dist/assets/{LpDock-Cbh0wQUv.css → LpDock-Dw82tWVD.css} +3 -3
- package/dist/assets/{LpDropzone-B_qRq1-R.css → LpDropzone-DNbh_NFJ.css} +10 -10
- package/dist/assets/{LpImageEditor-XM5bAziW.css → LpImageEditor-Bgu20XLs.css} +6 -6
- package/dist/assets/{LpTable-Bv-EcQs7.css → LpTable-CCk0ZHo7.css} +19 -19
- package/dist/assets/LpTabs-Bh7a-Bdl.css +18 -0
- package/dist/chunks/AppShellContextNav-C6Ho2mof.js +49 -0
- package/dist/chunks/ChartRangeSelector-HO0sMMz6.js +129 -0
- package/dist/chunks/{ContextMenuItems-BXumicbh.js → ContextMenuItems-DmaKSJVv.js} +1 -1
- package/dist/chunks/{DropzoneLinkField-C-9BCGJn.js → DropzoneLinkField-DXIr0eFz.js} +2 -2
- package/dist/chunks/{FieldWrapper-CORPzo9s.js → FieldWrapper-DnuMTrqW.js} +1 -1
- package/dist/chunks/IconCloseButton-COZEsa9u.js +29 -0
- package/dist/chunks/{LayoutCanvas-CNOAUk7D.js → LayoutCanvas-CZKOltfA.js} +1 -1
- package/dist/chunks/{LayoutNode-DF5BMN0J.js → LayoutNode-D2f7v683.js} +45 -45
- package/dist/chunks/{LpActionBar-BP1ld7-S.js → LpActionBar-BGMk5KoG.js} +3 -3
- package/dist/chunks/{LpActivityLine-CJvzrNpj.js → LpActivityLine-Ea-t5Vza.js} +4 -2
- package/dist/chunks/{LpAddressInput-sYMvYzcY.js → LpAddressInput-ZqoZ-N2Y.js} +12 -11
- package/dist/chunks/{LpAlert-n5XPAZfv.js → LpAlert-CjvTZIKF.js} +3 -3
- package/dist/chunks/LpAppShell-BNAVTQsY.js +582 -0
- package/dist/chunks/{LpAutocomplete-DOu7FN5P.js → LpAutocomplete-DkY6CSyD.js} +26 -42
- package/dist/chunks/{LpAvatar-Cg6Az3wz.js → LpAvatar-cQVsNk6F.js} +2 -2
- package/dist/chunks/{LpBadge-wUYLN4U9.js → LpBadge-D5QQdDQ_.js} +2 -2
- package/dist/chunks/{LpBottomNav-CbNQQPuL.js → LpBottomNav-zxLGGbjm.js} +9 -2
- package/dist/chunks/{LpBreadcrumbs-DPdbth-c.js → LpBreadcrumbs-CIIBsygI.js} +4 -3
- package/dist/chunks/{LpButton-CFb44IjC.js → LpButton-DSHioIfD.js} +5 -4
- package/dist/chunks/{LpCalendar-CuoWks-0.js → LpCalendar-D4-LVjfF.js} +1 -1
- package/dist/chunks/{LpCard-r13WRqox.js → LpCard-BPtYXwnT.js} +1 -1
- package/dist/chunks/{LpCheckbox-Cs4SHaHX.js → LpCheckbox-D6RuDW4X.js} +38 -16
- package/dist/chunks/{LpCodeBlock-DRC8VbXW.js → LpCodeBlock-DuzmnIHl.js} +19 -41
- package/dist/chunks/{LpCodeDisplay-CE9TxCA4.js → LpCodeDisplay-CO8fngxa.js} +5 -5
- package/dist/chunks/{LpCollapse-CWS9M_lm.js → LpCollapse-DrAw5DBZ.js} +5 -4
- package/dist/chunks/{LpColorPicker-1y1QJHZR.js → LpColorPicker-BxAHEnR5.js} +11 -12
- package/dist/chunks/{LpCommandScope-CtUhJe8T.js → LpCommandScope-DRUvHiX7.js} +1 -1
- package/dist/chunks/{LpConfirmDialog-DlD45Bi_.js → LpConfirmDialog-6oCIJTDa.js} +3 -3
- package/dist/chunks/{LpConfirmHost-BIWjBLmI.js → LpConfirmHost-DgHvfT6s.js} +1 -1
- package/dist/chunks/{LpContextMenu-rx2tCjwk.js → LpContextMenu--eMGIql6.js} +13 -15
- package/dist/chunks/{LpContextSwitcher-Dwh6dyID.js → LpContextSwitcher-1C1tExdl.js} +2 -2
- package/dist/chunks/{LpCopyButton-xF7wFVoU.js → LpCopyButton-7EOSIuwa.js} +3 -3
- package/dist/chunks/{LpCountdown-DgeY3cLG.js → LpCountdown-DVl7vXI1.js} +4 -3
- package/dist/chunks/{LpDataList-Jxyl9H5w.js → LpDataList-DgBeM01y.js} +13 -4
- package/dist/chunks/{LpDatePicker-CA0QTfBC.js → LpDatePicker-DwSDY0mt.js} +12 -18
- package/dist/chunks/{LpDateRangePicker-u3J51xXk.js → LpDateRangePicker-CNQXdTVv.js} +10 -16
- package/dist/chunks/{LpDisclosure-Cpa7Hc5T.js → LpDisclosure-DG7JCo-d.js} +2 -2
- package/dist/chunks/{LpDrawer-CrG8t_KP.js → LpDrawer-Bt9UUqt_.js} +61 -61
- package/dist/chunks/{LpDropdownMenu-Dl7Z4ZhS.js → LpDropdownMenu-CLzxIOgM.js} +9 -17
- package/dist/chunks/{LpEditable-Cy6GLbFx.js → LpEditable-DVT0Rh8F.js} +9 -6
- package/dist/chunks/{LpEmptyState-EQHiRYhG.js → LpEmptyState-DurPF001.js} +1 -1
- package/dist/chunks/{LpFieldNotice-CzQ2_5rQ.js → LpFieldNotice-DJ10cYIo.js} +1 -1
- package/dist/chunks/LpFileTree-BSx1kBoV.js +735 -0
- package/dist/chunks/{LpFileTreeNode-cT6BIWvz.js → LpFileTreeNode-4dVmFHb3.js} +116 -34
- package/dist/chunks/{LpFormField-Ch69Jd-X.js → LpFormField-BKYn9dyP.js} +3 -3
- package/dist/chunks/{LpFrame-BVQCQLDI.js → LpFrame-Bv5Fphte.js} +25 -11
- package/dist/chunks/{LpHintExample-9Py0wc-L.js → LpHintExample-YzCXiSUp.js} +1 -1
- package/dist/chunks/{LpHintLayer-CgObdUsM.js → LpHintLayer-BeKRsRon.js} +2 -2
- package/dist/chunks/{LpHints-Bz-BlaSl.js → LpHints-qf3xYsza.js} +3 -3
- package/dist/chunks/{LpHoverCard-spGxyw7T.js → LpHoverCard-DanH3Nz1.js} +23 -5
- package/dist/chunks/{LpIcon--5WSb3jJ.js → LpIcon-C6JpQ5td.js} +6 -3
- package/dist/chunks/{LpIdenticon-BzdC_qz9.js → LpIdenticon-Dbbr4fvt.js} +2 -1
- package/dist/chunks/{LpInfraNode-46XOCkfq.js → LpInfraNode-BAU40Km2.js} +2 -2
- package/dist/chunks/{LpInput-Tw-yxT4I.js → LpInput-DL6HEJdi.js} +16 -28
- package/dist/chunks/LpInspector-CuoMAhiw.js +209 -0
- package/dist/chunks/{LpLightbox-B95yu22B.js → LpLightbox-xvpQ64MM.js} +57 -32
- package/dist/chunks/{LpLoader-DVwkOmt9.js → LpLoader-Bf1yZwaU.js} +1 -1
- package/dist/chunks/LpLogInspector-6cNnXqp4.js +119 -0
- package/dist/chunks/{LpLogViewer-ngqkns4m.js → LpLogViewer-Dvb1E9_G.js} +234 -53
- package/dist/chunks/{LpMapPicker-DRGgh89B.js → LpMapPicker-D5_YLLBC.js} +4 -3
- package/dist/chunks/{LpMasonry--k0571qG.js → LpMasonry-DPYekFxs.js} +8 -5
- package/dist/chunks/{LpMediaGallery-Bkram-MO.js → LpMediaGallery-Df-tiWeq.js} +3 -3
- package/dist/chunks/{LpModal-CoGhLTyH.js → LpModal-DrtQ_1A2.js} +11 -13
- package/dist/chunks/{LpModalNav-BGvs2y5Q.js → LpModalNav-DkmGCnZE.js} +11 -37
- package/dist/chunks/{LpNotificationBell-B0034Lk-.js → LpNotificationBell-D_wklO1m.js} +9 -9
- package/dist/chunks/{LpNumberField-e0IBkWU1.js → LpNumberField-CNHsmSDZ.js} +7 -16
- package/dist/chunks/{LpOtpInput-CeBPsM7D.js → LpOtpInput-BRpLBbOD.js} +2 -2
- package/dist/chunks/{LpPagination-BIIiYHXR.js → LpPagination-snQ020xQ.js} +6 -4
- package/dist/chunks/{LpPaletteTheme-DiLYKQiZ.js → LpPaletteTheme-dVtxHx-F.js} +4 -4
- package/dist/chunks/{LpPasswordInput-BkHKQDhM.js → LpPasswordInput-B-zD6tUS.js} +2 -2
- package/dist/chunks/{LpPhoneInput-CETEp5W7.js → LpPhoneInput-BSL7NX4z.js} +15 -26
- package/dist/chunks/{LpPie-DrZepi0p.js → LpPie-9t_guO49.js} +22 -21
- package/dist/chunks/{LpPipeline-B3aOVOkV.js → LpPipeline-rjXvEDRJ.js} +16 -7
- package/dist/chunks/{LpPopover-DmZ3wUtP.js → LpPopover-BQSuxtai.js} +10 -1
- package/dist/chunks/{LpProgress-Yr6ONG5t.js → LpProgress-D_MSjowb.js} +2 -1
- package/dist/chunks/{LpQuota-Dk2MyI2Z.js → LpQuota-CgWPgdVt.js} +1 -1
- package/dist/chunks/{LpRadioGroup-ggaPL92T.js → LpRadioGroup-BrazjLY_.js} +4 -4
- package/dist/chunks/{LpRangeCalendar-CYYUYqJ7.js → LpRangeCalendar-BrqlGZzE.js} +1 -1
- package/dist/chunks/{LpRangeSlider-CM-0ZITZ.js → LpRangeSlider-fz61tzc-.js} +5 -9
- package/dist/chunks/{LpRelativeTime-DwgCb5-8.js → LpRelativeTime-BovUk8MP.js} +1 -1
- package/dist/chunks/{LpRepeater-D7ZmnIYd.js → LpRepeater-BkJHSPI1.js} +3 -3
- package/dist/chunks/{LpRevealOnScroll-DcQjexLy.js → LpRevealOnScroll-CPwyiQAr.js} +1 -1
- package/dist/chunks/{LpScramble-Bn9OoOtC.js → LpScramble-DsE77iVp.js} +1 -1
- package/dist/chunks/{LpScrollArea-MyEnVB_5.js → LpScrollArea-ay4Xo_hg.js} +22 -10
- package/dist/chunks/{LpSecretField-BbmqM9ye.js → LpSecretField-DBvU6iAw.js} +10 -9
- package/dist/chunks/{LpSection-DFK_uoJE.js → LpSection-BfteipxU.js} +1 -1
- package/dist/chunks/{LpSegmented-CeACsMMA.js → LpSegmented-DbEJhbv-.js} +8 -10
- package/dist/chunks/{LpSelect-Cxq4yBGd.js → LpSelect-Y-iuSymW.js} +47 -30
- package/dist/chunks/{LpShaderBackdrop-Bote0iuy.js → LpShaderBackdrop-wQygYb5h.js} +13 -10
- package/dist/chunks/{LpShift-CCq7dofl.js → LpShift-DAgS_d2x.js} +18 -15
- package/dist/chunks/{LpSidebar-DzE1783C.js → LpSidebar-kSkpPh3-.js} +74 -87
- package/dist/chunks/{LpSidebarNav-DE3PhXVP.js → LpSidebarNav-C2mvqrY2.js} +8 -6
- package/dist/chunks/{LpSidebarRow-BRYhNDSo.js → LpSidebarRow-eRP4Q31q.js} +6 -5
- package/dist/chunks/{LpSlider-DxYoCJJO.js → LpSlider-A4ixovgS.js} +5 -9
- package/dist/chunks/{LpSpotlight-4F3NeUMY.js → LpSpotlight-DwxkhFgR.js} +2 -1
- package/dist/chunks/{LpStat-f2LfDCJ4.js → LpStat-pMNZgFcq.js} +2 -2
- package/dist/chunks/{LpStatus-DglxttQ7.js → LpStatus-DGJFwk5F.js} +2 -2
- package/dist/chunks/{LpStepMark-DpzKVyh8.js → LpStepMark-Dw2MRTrt.js} +2 -2
- package/dist/chunks/{LpStepper-DpsocBNJ.js → LpStepper-DNnh7lCu.js} +1 -1
- package/dist/chunks/{LpSwap-C96c0LWh.js → LpSwap-M7nFeW3C.js} +1 -1
- package/dist/chunks/{LpSwitch-BnXd1llc.js → LpSwitch-DnC2-0aV.js} +3 -3
- package/dist/chunks/{LpTabFace-DPCwKkH2.js → LpTabFace-DQoV8mQG.js} +2 -2
- package/dist/chunks/{LpTableFilter-CiVBpaq0.js → LpTableFilter-DgARTsA1.js} +4 -4
- package/dist/chunks/{LpTableOfContents-BN5zvpnx.js → LpTableOfContents-CKkWEK6R.js} +14 -9
- package/dist/chunks/{LpTagsInput-C-mDG648.js → LpTagsInput-Dt0mteSj.js} +19 -27
- package/dist/chunks/{LpTextarea-TE-yZv2U.js → LpTextarea-Co0b9PVx.js} +8 -16
- package/dist/chunks/LpThemeProvider-XK6ZeWAE.js +81 -0
- package/dist/chunks/{LpThemeStudio-BpORDvH6.js → LpThemeStudio-DzYfE-5k.js} +12 -195
- package/dist/chunks/{LpThemeSwitcher-BnEn_mvf.js → LpThemeSwitcher-CFLkdbBL.js} +8 -6
- package/dist/chunks/{LpTimeField-BawSVsmt.js → LpTimeField-DeOcKWJq.js} +6 -9
- package/dist/chunks/{LpToaster-IwTXjbbU.js → LpToaster-QFj0P-5m.js} +10 -8
- package/dist/chunks/{LpTooltip-BcBvIx4z.js → LpTooltip-BJf3lZMq.js} +51 -19
- package/dist/chunks/LpTopologyCanvas-BOHHHZ_6.js +673 -0
- package/dist/chunks/{LpTour-BZq-mUMv.js → LpTour-ClKYhx4h.js} +7 -5
- package/dist/chunks/{LpTruncate-CflAIwiJ.js → LpTruncate-C6u3gjc6.js} +6 -5
- package/dist/chunks/{LpTypewriter-BCL_a6wE.js → LpTypewriter-CZIzpdbe.js} +2 -1
- package/dist/chunks/{LpUptimeBar-DqNvvMBK.js → LpUptimeBar-BnYmR2rj.js} +3 -3
- package/dist/chunks/{LpVideoBackdrop-DS1wGv-X.js → LpVideoBackdrop-Ct4St4ZL.js} +10 -13
- package/dist/chunks/LpWindow-B8YSRVTH.js +297 -0
- package/dist/chunks/LpWorkspaceSwitcher-D0e9upAy.js +139 -0
- package/dist/chunks/{MenuTitle-BmCNNTKH.js → MenuTitle-Bh5dAdV1.js} +1 -1
- package/dist/chunks/{OptionContent-22UT8zLn.js → OptionContent-CGb8QlHA.js} +1 -1
- package/dist/chunks/{PickerField-Bfh8id3d.js → PickerField-BM1dyafh.js} +4 -4
- package/dist/chunks/{RevealToggle-BEit1n6Z.js → RevealToggle-CCPDE8Mv.js} +3 -3
- package/dist/chunks/SliderRail-DhPREa_R.js +18 -0
- package/dist/chunks/{TourCard-DNclH3u_.js → TourCard-DAzTYfav.js} +4 -4
- package/dist/chunks/{icons-DMITlfw5.js → icons-CYfcpSDS.js} +26 -10
- package/dist/component-names.d.ts +1 -1
- package/dist/components/AppShellContextNav.vue.d.ts +13 -0
- package/dist/components/AppShellContextNav.vue.js +4 -0
- package/dist/components/ChartRangeSelector.vue.d.ts +21 -0
- package/dist/components/ChartRangeSelector.vue.js +4 -0
- package/dist/components/ContextMenuItems.vue.js +1 -1
- package/dist/components/DropzoneLinkField.vue.d.ts +2 -2
- package/dist/components/DropzoneLinkField.vue.js +1 -1
- package/dist/components/FieldWrapper.vue.js +1 -1
- package/dist/components/IconCloseButton.vue.d.ts +7 -0
- package/dist/components/IconCloseButton.vue.js +4 -0
- package/dist/components/LayoutCanvas.vue.js +1 -1
- package/dist/components/LayoutNode.vue.js +1 -1
- package/dist/components/LpActionBar.vue.js +1 -1
- package/dist/components/LpActivityLine.vue.js +1 -1
- package/dist/components/LpAddressInput.vue.js +1 -1
- package/dist/components/LpAlert.vue.js +1 -1
- package/dist/components/LpAppShell.vue.d.ts +110 -2
- package/dist/components/LpAppShell.vue.js +1 -1
- package/dist/components/LpAutocomplete.vue.js +1 -1
- package/dist/components/LpAvatar.vue.js +1 -1
- package/dist/components/LpBadge.vue.js +1 -1
- package/dist/components/LpBottomNav.vue.d.ts +5 -0
- package/dist/components/LpBottomNav.vue.js +1 -1
- package/dist/components/LpBreadcrumbs.vue.js +1 -1
- package/dist/components/LpButton.vue.d.ts +14 -2
- package/dist/components/LpButton.vue.js +1 -1
- package/dist/components/LpCalendar.vue.js +1 -1
- package/dist/components/LpCard.vue.js +1 -1
- package/dist/components/LpChart.vue.d.ts +74 -2
- package/dist/components/LpChart.vue.js +326 -85
- package/dist/components/LpCheckbox.vue.d.ts +6 -2
- package/dist/components/LpCheckbox.vue.js +1 -1
- package/dist/components/LpCodeBlock.vue.js +1 -1
- package/dist/components/LpCodeDisplay.vue.js +1 -1
- package/dist/components/LpCollapse.vue.js +1 -1
- package/dist/components/LpColorPicker.vue.js +1 -1
- package/dist/components/LpCommandPalette.vue.d.ts +8 -0
- package/dist/components/LpCommandPalette.vue.js +107 -56
- package/dist/components/LpCommandScope.vue.js +1 -1
- 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/LpContextSwitcher.vue.js +1 -1
- package/dist/components/LpCopyButton.vue.js +1 -1
- package/dist/components/LpCountdown.vue.js +1 -1
- package/dist/components/LpDataList.vue.d.ts +1 -1
- package/dist/components/LpDataList.vue.js +1 -1
- package/dist/components/LpDatePicker.vue.d.ts +3 -15
- package/dist/components/LpDatePicker.vue.js +1 -1
- package/dist/components/LpDateRangePicker.vue.d.ts +3 -13
- package/dist/components/LpDateRangePicker.vue.js +1 -1
- package/dist/components/LpDisclosure.vue.js +1 -1
- package/dist/components/LpDock.vue.js +21 -18
- package/dist/components/LpDrawer.vue.d.ts +1 -1
- package/dist/components/LpDrawer.vue.js +1 -1
- package/dist/components/LpDropdownMenu.vue.js +1 -1
- package/dist/components/LpDropzone.vue.js +14 -11
- package/dist/components/LpEditable.vue.js +1 -1
- package/dist/components/LpEmptyState.vue.js +1 -1
- package/dist/components/LpFieldNotice.vue.js +1 -1
- package/dist/components/LpFileTree.vue.d.ts +96 -6
- package/dist/components/LpFileTree.vue.js +1 -1
- package/dist/components/LpFileTreeNode.vue.d.ts +48 -0
- package/dist/components/LpFileTreeNode.vue.js +1 -1
- package/dist/components/LpFormField.vue.js +1 -1
- package/dist/components/LpFrame.vue.js +1 -1
- package/dist/components/LpGauge.vue.d.ts +1 -1
- 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.js +1 -1
- package/dist/components/LpIcon.vue.d.ts +2 -0
- package/dist/components/LpIcon.vue.js +1 -1
- package/dist/components/LpIdenticon.vue.js +1 -1
- package/dist/components/LpImageEditor.vue.js +7 -6
- package/dist/components/LpInfraNode.vue.js +1 -1
- package/dist/components/LpInput.vue.d.ts +1 -1
- package/dist/components/LpInput.vue.js +1 -1
- package/dist/components/LpInspector.vue.d.ts +87 -0
- package/dist/components/LpInspector.vue.js +4 -0
- package/dist/components/LpLightbox.vue.d.ts +8 -0
- package/dist/components/LpLightbox.vue.js +1 -1
- package/dist/components/LpLoader.vue.d.ts +1 -1
- package/dist/components/LpLoader.vue.js +1 -1
- package/dist/components/LpLogInspector.vue.d.ts +18 -0
- package/dist/components/LpLogInspector.vue.js +4 -0
- package/dist/components/LpLogViewer.vue.d.ts +93 -0
- package/dist/components/LpLogViewer.vue.js +1 -1
- package/dist/components/LpMapPicker.vue.js +1 -1
- package/dist/components/LpMasonry.vue.js +1 -1
- package/dist/components/LpMediaGallery.vue.js +1 -1
- package/dist/components/LpModal.vue.d.ts +4 -2
- package/dist/components/LpModal.vue.js +1 -1
- package/dist/components/LpModalNav.vue.d.ts +5 -5
- package/dist/components/LpModalNav.vue.js +1 -1
- package/dist/components/LpNotificationBell.vue.d.ts +2 -2
- package/dist/components/LpNotificationBell.vue.js +1 -1
- package/dist/components/LpNumberField.vue.js +1 -1
- 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/LpPaletteTheme.vue.js +1 -1
- package/dist/components/LpPasswordInput.vue.js +1 -1
- package/dist/components/LpPhoneInput.vue.js +1 -1
- package/dist/components/LpPie.vue.d.ts +2 -2
- package/dist/components/LpPie.vue.js +1 -1
- package/dist/components/LpPipeline.vue.d.ts +4 -0
- package/dist/components/LpPipeline.vue.js +1 -1
- package/dist/components/LpPopover.vue.d.ts +7 -3
- package/dist/components/LpPopover.vue.js +1 -1
- package/dist/components/LpProgress.vue.d.ts +1 -1
- package/dist/components/LpProgress.vue.js +1 -1
- package/dist/components/LpQuota.vue.js +1 -1
- 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.js +1 -1
- package/dist/components/LpRepeater.vue.js +1 -1
- package/dist/components/LpRevealOnScroll.vue.js +1 -1
- package/dist/components/LpScramble.vue.js +1 -1
- package/dist/components/LpScrollArea.vue.js +1 -1
- package/dist/components/LpSecretField.vue.js +1 -1
- package/dist/components/LpSection.vue.js +1 -1
- package/dist/components/LpSegmented.vue.js +1 -1
- package/dist/components/LpSelect.vue.js +1 -1
- package/dist/components/LpShaderBackdrop.vue.js +1 -1
- package/dist/components/LpShift.vue.js +1 -1
- package/dist/components/LpShortcutsDialog.vue.js +1 -1
- package/dist/components/LpSidebar.vue.d.ts +1 -1
- package/dist/components/LpSidebar.vue.js +1 -1
- package/dist/components/LpSidebarNav.vue.js +1 -1
- package/dist/components/LpSidebarRow.vue.js +1 -1
- package/dist/components/LpSlider.vue.js +1 -1
- package/dist/components/LpSparkline.vue.d.ts +1 -1
- package/dist/components/LpSpotlight.vue.js +1 -1
- package/dist/components/LpStat.vue.js +1 -1
- package/dist/components/LpStatus.vue.js +1 -1
- package/dist/components/LpStepMark.vue.js +1 -1
- package/dist/components/LpStepper.vue.js +1 -1
- package/dist/components/LpSwap.vue.js +1 -1
- package/dist/components/LpSwitch.vue.js +1 -1
- package/dist/components/LpTabFace.vue.js +1 -1
- package/dist/components/LpTable.vue.d.ts +132 -0
- package/dist/components/LpTable.vue.js +547 -135
- package/dist/components/LpTableFilter.vue.js +1 -1
- package/dist/components/LpTableOfContents.vue.js +1 -1
- package/dist/components/LpTabs.vue.js +6 -5
- package/dist/components/LpTagsInput.vue.js +1 -1
- package/dist/components/LpTextarea.vue.js +1 -1
- package/dist/components/LpThemeProvider.vue.d.ts +2 -0
- package/dist/components/LpThemeProvider.vue.js +1 -1
- package/dist/components/LpThemeStudio.vue.js +1 -1
- package/dist/components/LpThemeSwitcher.vue.js +1 -1
- package/dist/components/LpTimeField.vue.js +1 -1
- package/dist/components/LpToaster.vue.js +1 -1
- package/dist/components/LpTooltip.vue.js +1 -1
- package/dist/components/LpTopologyCanvas.vue.d.ts +131 -5
- package/dist/components/LpTopologyCanvas.vue.js +1 -1
- package/dist/components/LpTour.vue.js +1 -1
- package/dist/components/LpTruncate.vue.js +1 -1
- package/dist/components/LpTypewriter.vue.js +1 -1
- package/dist/components/LpUptimeBar.vue.js +1 -1
- package/dist/components/LpVideoBackdrop.vue.js +1 -1
- package/dist/components/LpWindow.vue.d.ts +99 -0
- package/dist/components/LpWindow.vue.js +4 -0
- package/dist/components/LpWorkspaceSwitcher.vue.d.ts +18 -0
- package/dist/components/LpWorkspaceSwitcher.vue.js +4 -0
- package/dist/components/MenuTitle.vue.js +1 -1
- package/dist/components/OptionContent.vue.js +1 -1
- package/dist/components/PickerField.vue.d.ts +2 -2
- package/dist/components/PickerField.vue.js +1 -1
- package/dist/components/RevealToggle.vue.js +1 -1
- package/dist/components/SliderRail.vue.d.ts +3 -0
- package/dist/components/SliderRail.vue.js +4 -0
- package/dist/components/TourCard.vue.js +1 -1
- package/dist/components/address.js +2 -1
- package/dist/components/appShell.d.ts +36 -0
- package/dist/components/appShell.js +30 -0
- package/dist/components/calendar.d.ts +12 -3
- package/dist/components/calendar.js +2 -5
- package/dist/components/chart.d.ts +21 -0
- package/dist/components/chart.js +4 -3
- package/dist/components/chartWindow.d.ts +57 -0
- package/dist/components/chartWindow.js +136 -0
- package/dist/components/color.js +1 -1
- package/dist/components/commandPalette.d.ts +16 -2
- package/dist/components/commandPalette.js +39 -4
- package/dist/components/controlSize.d.ts +5 -0
- package/dist/components/controlSize.js +8 -0
- package/dist/components/dropdown.d.ts +5 -0
- package/dist/components/dropdown.js +2 -0
- package/dist/components/exportData.d.ts +6 -1
- package/dist/components/exportData.js +25 -18
- package/dist/components/fileTree.d.ts +67 -0
- package/dist/components/fileTree.js +141 -1
- package/dist/components/identicon.js +3 -2
- package/dist/components/logTools.d.ts +93 -0
- package/dist/components/logTools.js +210 -0
- package/dist/components/menuWhen.js +1 -1
- package/dist/components/meter.js +2 -1
- package/dist/components/pipeline.d.ts +2 -0
- package/dist/components/pipeline.js +5 -0
- package/dist/components/relativeTime.js +2 -1
- package/dist/components/reveal.js +2 -1
- package/dist/components/select.d.ts +5 -0
- package/dist/components/select.js +10 -0
- package/dist/components/sidebar.d.ts +1 -0
- package/dist/components/tableFeatures.d.ts +58 -0
- package/dist/components/tableFeatures.js +87 -0
- package/dist/components/topologyGraph.d.ts +164 -0
- package/dist/components/topologyGraph.js +416 -0
- package/dist/components/tour.js +5 -3
- package/dist/components/videoBackdrop.js +7 -6
- package/dist/composables/clamp.d.ts +2 -0
- package/dist/composables/clamp.js +4 -0
- package/dist/composables/devWarn.d.ts +3 -0
- package/dist/composables/devWarn.js +14 -0
- package/dist/composables/easing.d.ts +13 -4
- package/dist/composables/easing.js +16 -10
- package/dist/composables/overlayHistory.js +14 -1
- package/dist/composables/pointerDrag.d.ts +15 -0
- package/dist/composables/pointerDrag.js +40 -0
- package/dist/composables/propCheck.d.ts +10 -0
- package/dist/composables/propCheck.js +78 -0
- package/dist/composables/realm.d.ts +6 -0
- package/dist/composables/realm.js +23 -0
- package/dist/composables/scroll.js +4 -2
- package/dist/composables/scrollMemory.d.ts +12 -1
- package/dist/composables/scrollMemory.js +36 -12
- package/dist/composables/spatialNav.js +2 -1
- package/dist/composables/textEntry.d.ts +17 -0
- package/dist/composables/textEntry.js +19 -0
- package/dist/composables/useAsyncTask.d.ts +6 -0
- package/dist/composables/useChartSync.d.ts +5 -0
- package/dist/composables/useChartSync.js +33 -0
- package/dist/composables/useCloseGuard.d.ts +3 -1
- package/dist/composables/useCloseGuard.js +6 -3
- package/dist/composables/useCommands.d.ts +50 -0
- package/dist/composables/useCommands.js +66 -0
- package/dist/composables/useField.d.ts +37 -0
- package/dist/composables/useField.js +27 -2
- package/dist/composables/useFitScale.js +4 -1
- package/dist/composables/useFormDraft.d.ts +13 -2
- package/dist/composables/useFormDraft.js +17 -9
- package/dist/composables/useHintSystem.js +2 -2
- package/dist/composables/useHotkeys.js +11 -32
- package/dist/composables/useInView.js +2 -1
- package/dist/composables/useInputFilter.js +7 -5
- package/dist/composables/useInputMask.js +5 -3
- package/dist/composables/useLinkedView.d.ts +97 -0
- package/dist/composables/useLinkedView.js +139 -0
- package/dist/composables/useOptimisticToggle.d.ts +3 -1
- package/dist/composables/useOptimisticToggle.js +2 -1
- package/dist/composables/useOverlayHistory.d.ts +7 -0
- package/dist/composables/useOverlayHistory.js +16 -2
- package/dist/composables/usePaintSelect.js +18 -14
- package/dist/composables/usePaletteCommands.d.ts +7 -0
- package/dist/composables/usePaletteCommands.js +12 -1
- package/dist/composables/usePersisted.d.ts +10 -0
- package/dist/composables/usePersisted.js +1 -1
- package/dist/composables/usePillTransition.d.ts +2 -2
- package/dist/composables/usePillTransition.js +5 -5
- package/dist/composables/useResizeObserver.js +2 -1
- package/dist/composables/useReveal.js +2 -1
- package/dist/composables/useRovingFocus.d.ts +2 -2
- package/dist/composables/useRovingFocus.js +9 -11
- package/dist/composables/useScramble.js +7 -1
- package/dist/composables/useShift.js +8 -6
- package/dist/composables/useTilt.js +2 -1
- package/dist/composables/useTween.js +9 -5
- package/dist/composables/useView.d.ts +1 -0
- package/dist/composables/useView.js +14 -2
- package/dist/composables/useZoomPan.js +2 -4
- package/dist/composables/windowing.d.ts +40 -0
- package/dist/composables/windowing.js +118 -0
- package/dist/icons-all.js +1 -1
- package/dist/icons.d.ts +4 -0
- package/dist/index.d.ts +30 -5
- package/dist/index.js +310 -264
- package/dist/layout/tree.js +19 -15
- package/dist/layout/useLayout.d.ts +2 -0
- package/dist/layout/useLayout.js +5 -1
- package/dist/layout/useWorkspaces.d.ts +52 -0
- package/dist/layout/useWorkspaces.js +140 -0
- package/dist/{chunks/backdrop-Dkf2vM81.js → theme/backdrop.js} +5 -5
- package/dist/theme/config.js +25 -0
- package/dist/theme/define.js +61 -0
- package/dist/{chunks/palette-Co8tSASo.js → theme/palette.js} +2 -2
- package/dist/theme/presets.js +239 -0
- package/dist/theme/studio.js +134 -0
- package/dist/theme/tokens.js +63 -0
- package/dist/theme/useTheme.d.ts +3 -2
- package/dist/theme/useTheme.js +325 -0
- package/package.json +8 -1
- package/src/component-names.ts +5 -1
- package/src/components/AppShellContextNav.vue +44 -0
- package/src/components/ChartRangeSelector.vue +120 -0
- package/src/components/IconCloseButton.vue +21 -0
- package/src/components/LayoutCanvas.vue +3 -0
- package/src/components/LayoutNode.vue +37 -38
- package/src/components/LpActivityLine.vue +4 -2
- package/src/components/LpAddressInput.vue +3 -3
- package/src/components/LpAppShell.vue +362 -24
- package/src/components/LpAutocomplete.vue +18 -30
- package/src/components/LpBottomNav.vue +9 -1
- package/src/components/LpBreadcrumbs.vue +2 -1
- package/src/components/LpButton.vue +11 -4
- package/src/components/LpChart.vue +336 -37
- package/src/components/LpCheckbox.vue +43 -9
- package/src/components/LpCodeBlock.vue +17 -23
- package/src/components/LpCollapse.vue +5 -4
- package/src/components/LpColorPicker.vue +8 -9
- package/src/components/LpCommandPalette.vue +133 -50
- package/src/components/LpContextMenu.vue +15 -13
- package/src/components/LpCountdown.vue +2 -1
- package/src/components/LpDataList.vue +13 -1
- package/src/components/LpDatePicker.vue +5 -17
- package/src/components/LpDateRangePicker.vue +5 -16
- package/src/components/LpDock.vue +25 -16
- package/src/components/LpDrawer.vue +70 -61
- package/src/components/LpDropdownMenu.vue +6 -10
- package/src/components/LpDropzone.vue +12 -7
- package/src/components/LpEditable.vue +6 -2
- package/src/components/LpFileTree.vue +507 -66
- package/src/components/LpFileTreeNode.vue +106 -5
- package/src/components/LpFormField.vue +1 -1
- package/src/components/LpFrame.vue +33 -13
- package/src/components/LpHoverCard.vue +30 -5
- package/src/components/LpIcon.vue +6 -2
- package/src/components/LpIdenticon.vue +2 -1
- package/src/components/LpImageEditor.vue +5 -2
- package/src/components/LpInput.vue +15 -23
- package/src/components/LpInspector.vue +197 -0
- package/src/components/LpLightbox.vue +74 -29
- package/src/components/LpLogInspector.vue +85 -0
- package/src/components/LpLogViewer.vue +239 -29
- package/src/components/LpMapPicker.vue +2 -1
- package/src/components/LpMasonry.vue +8 -5
- package/src/components/LpModal.vue +12 -12
- package/src/components/LpModalNav.vue +2 -21
- package/src/components/LpNumberField.vue +6 -15
- package/src/components/LpOtpInput.vue +2 -2
- package/src/components/LpPagination.vue +5 -3
- package/src/components/LpPhoneInput.vue +8 -19
- package/src/components/LpPie.vue +25 -23
- package/src/components/LpPipeline.vue +14 -1
- package/src/components/LpPopover.vue +23 -2
- package/src/components/LpProgress.vue +2 -1
- package/src/components/LpRadioGroup.vue +2 -2
- package/src/components/LpRangeSlider.vue +5 -6
- package/src/components/LpRevealOnScroll.vue +1 -1
- package/src/components/LpScrollArea.vue +28 -11
- package/src/components/LpSecretField.vue +2 -1
- package/src/components/LpSegmented.vue +6 -8
- package/src/components/LpSelect.vue +54 -24
- package/src/components/LpShaderBackdrop.vue +12 -9
- package/src/components/LpShift.vue +18 -15
- package/src/components/LpSidebar.vue +77 -74
- package/src/components/LpSidebarNav.vue +3 -2
- package/src/components/LpSidebarRow.vue +2 -1
- package/src/components/LpSlider.vue +5 -6
- package/src/components/LpSpotlight.vue +2 -1
- package/src/components/LpSwitch.vue +5 -3
- package/src/components/LpTable.vue +609 -93
- package/src/components/LpTableFilter.vue +1 -1
- package/src/components/LpTableOfContents.vue +16 -9
- package/src/components/LpTabs.vue +2 -1
- package/src/components/LpTagsInput.vue +12 -19
- package/src/components/LpTextarea.vue +5 -11
- package/src/components/LpThemeProvider.vue +29 -13
- package/src/components/LpTimeField.vue +4 -7
- package/src/components/LpToaster.vue +7 -6
- package/src/components/LpTooltip.vue +62 -18
- package/src/components/LpTopologyCanvas.vue +567 -42
- package/src/components/LpTour.vue +7 -5
- package/src/components/LpTruncate.vue +4 -3
- package/src/components/LpTypewriter.vue +2 -1
- package/src/components/LpVideoBackdrop.vue +11 -13
- package/src/components/LpWindow.vue +373 -0
- package/src/components/LpWorkspaceSwitcher.vue +116 -0
- package/src/components/PickerField.vue +2 -2
- package/src/components/SliderRail.vue +10 -0
- package/src/components/address.ts +3 -1
- package/src/components/appShell.ts +74 -0
- package/src/components/calendar.ts +12 -5
- package/src/components/chart.ts +27 -3
- package/src/components/chartWindow.ts +198 -0
- package/src/components/color.ts +2 -1
- package/src/components/commandPalette.ts +66 -5
- package/src/components/controlSize.ts +6 -0
- package/src/components/dropdown.ts +3 -0
- package/src/components/exportData.ts +33 -18
- package/src/components/fileTree.ts +215 -0
- package/src/components/identicon.ts +4 -2
- package/src/components/logTools.ts +298 -0
- package/src/components/meter.ts +2 -1
- package/src/components/pipeline.ts +6 -0
- package/src/components/relativeTime.ts +2 -1
- package/src/components/reveal.ts +3 -1
- package/src/components/select.ts +14 -0
- package/src/components/sidebar.ts +1 -0
- package/src/components/tableFeatures.ts +149 -0
- package/src/components/topologyGraph.ts +655 -0
- package/src/components/tour.ts +5 -3
- package/src/components/videoBackdrop.ts +7 -6
- package/src/composables/clamp.ts +2 -0
- package/src/composables/devWarn.ts +19 -0
- package/src/composables/easing.ts +37 -12
- package/src/composables/overlayHistory.ts +24 -0
- package/src/composables/pointerDrag.ts +54 -0
- package/src/composables/propCheck.ts +90 -0
- package/src/composables/realm.ts +25 -0
- package/src/composables/scroll.ts +4 -2
- package/src/composables/scrollMemory.ts +56 -14
- package/src/composables/spatialNav.ts +2 -1
- package/src/composables/textEntry.ts +33 -0
- package/src/composables/useAsyncTask.ts +6 -0
- package/src/composables/useChartSync.ts +52 -0
- package/src/composables/useCloseGuard.ts +22 -10
- package/src/composables/useCommands.ts +123 -0
- package/src/composables/useField.ts +41 -2
- package/src/composables/useFitScale.ts +4 -1
- package/src/composables/useFormDraft.ts +38 -14
- package/src/composables/useHintSystem.ts +2 -2
- package/src/composables/useHotkeys.ts +19 -48
- package/src/composables/useInView.ts +2 -1
- package/src/composables/useInputFilter.ts +8 -5
- package/src/composables/useInputMask.ts +8 -3
- package/src/composables/useLinkedView.ts +222 -0
- package/src/composables/useOptimisticToggle.ts +7 -1
- package/src/composables/useOverlayHistory.ts +20 -0
- package/src/composables/usePaintSelect.ts +20 -14
- package/src/composables/usePaletteCommands.ts +13 -0
- package/src/composables/usePersisted.ts +10 -0
- package/src/composables/usePillTransition.ts +9 -6
- package/src/composables/useResizeObserver.ts +2 -1
- package/src/composables/useReveal.ts +2 -1
- package/src/composables/useRovingFocus.ts +11 -14
- package/src/composables/useScramble.ts +12 -1
- package/src/composables/useShift.ts +8 -6
- package/src/composables/useTilt.ts +2 -1
- package/src/composables/useTween.ts +10 -5
- package/src/composables/useView.ts +17 -3
- package/src/composables/useZoomPan.ts +2 -5
- package/src/composables/windowing.ts +190 -0
- package/src/icons.ts +27 -6
- package/src/index.ts +41 -4
- package/src/kit-icons.ts +1 -1
- package/src/layout/tree.ts +31 -16
- package/src/layout/useLayout.ts +6 -0
- package/src/layout/useWorkspaces.ts +234 -0
- package/src/nuxt.ts +9 -1
- package/src/runtime/propCheck.plugin.ts +10 -0
- package/src/theme/studio.ts +7 -5
- package/src/theme/useTheme.ts +89 -15
- package/src/tokens/tokens.css +8 -1
- package/dist/assets/LpTabs-CJ0rYQbx.css +0 -18
- package/dist/chunks/LpAppShell-Dgejipzz.js +0 -319
- package/dist/chunks/LpFileTree-CooHinsC.js +0 -425
- package/dist/chunks/LpThemeProvider-8MG6yqU9.js +0 -640
- package/dist/chunks/LpTopologyCanvas-B1gIbS0n.js +0 -298
|
@@ -16,6 +16,8 @@ export type SelectLabels = {
|
|
|
16
16
|
</script>
|
|
17
17
|
|
|
18
18
|
<script setup lang="ts" generic="V extends SelectValue = string">
|
|
19
|
+
import IconCloseButton from "./IconCloseButton.vue"
|
|
20
|
+
import { CONTROL_SIZE } from "./controlSize"
|
|
19
21
|
import { usePaletteControl, type PaletteControlOptions } from "../composables/usePaletteCommands"
|
|
20
22
|
/*
|
|
21
23
|
* One select to rule them all — built on reka-ui Combobox.
|
|
@@ -37,7 +39,7 @@ import {
|
|
|
37
39
|
ComboboxViewport,
|
|
38
40
|
} from "reka-ui"
|
|
39
41
|
import { computed, nextTick, reactive, ref, useAttrs, useId, watch } from "vue"
|
|
40
|
-
import { useFieldBlur, useFieldControl } from "../composables/useField"
|
|
42
|
+
import { useFieldBlur, useFieldControl, mergeDescribedBy } from "../composables/useField"
|
|
41
43
|
import { useLabels } from "../composables/useLpConfig"
|
|
42
44
|
import { useMergedAttrs } from "../composables/useMergedClass"
|
|
43
45
|
import { OPTION_ITEM, optionStagger, POPOVER_PANEL } from "./dropdown"
|
|
@@ -45,8 +47,8 @@ import LpIcon from "./LpIcon.vue"
|
|
|
45
47
|
import OptionContent from "./OptionContent.vue"
|
|
46
48
|
import LpRollingText from "./LpRollingText.vue"
|
|
47
49
|
import type { LpOptionBase, OptionSelection } from "./options"
|
|
48
|
-
import { fitChips, toggledValues } from "./select"
|
|
49
|
-
import { useOutsideGuard, usePortalTarget } from "../composables/useView"
|
|
50
|
+
import { evictOldest, fitChips, toggledValues } from "./select"
|
|
51
|
+
import { nodeWindow, useOutsideGuard, usePortalTarget } from "../composables/useView"
|
|
50
52
|
import { useResizeObserver } from "../composables/useResizeObserver"
|
|
51
53
|
|
|
52
54
|
export type SelectValue = string | number
|
|
@@ -105,11 +107,7 @@ const props = withDefaults(
|
|
|
105
107
|
)
|
|
106
108
|
|
|
107
109
|
/* The text steps with the height, as in every other kit field: a small select beside a small input read a size larger. */
|
|
108
|
-
const SIZE_HEIGHT =
|
|
109
|
-
sm: "h-(--size-control-sm) text-xs",
|
|
110
|
-
md: "h-(--size-control-md) text-sm",
|
|
111
|
-
lg: "h-(--size-control-lg) text-sm",
|
|
112
|
-
} as const
|
|
110
|
+
const SIZE_HEIGHT = CONTROL_SIZE
|
|
113
111
|
const anchorHeight = computed(() => SIZE_HEIGHT[props.size])
|
|
114
112
|
|
|
115
113
|
const field = useFieldControl(() => ({
|
|
@@ -189,7 +187,38 @@ async function openFromKeyboard(event: KeyboardEvent) {
|
|
|
189
187
|
const items = panel?.querySelectorAll<HTMLElement>('[role="option"]:not([data-disabled])')
|
|
190
188
|
const selected = panel?.querySelector<HTMLElement>('[role="option"][aria-selected="true"]:not([data-disabled])')
|
|
191
189
|
const target = search ?? selected ?? (event.key === "ArrowUp" ? items?.[items.length - 1] : items?.[0])
|
|
192
|
-
|
|
190
|
+
// Something else may have kept the list shut: nothing to move into then.
|
|
191
|
+
if (isOpen.value) target?.focus()
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/*
|
|
195
|
+
* reka reads the arrow keys from the search box. A list without one takes focus
|
|
196
|
+
* on an option, where its own handling put focus straight back on the option
|
|
197
|
+
* the list opened on, so that was all a keyboard could ever pick. Taken here,
|
|
198
|
+
* ahead of it.
|
|
199
|
+
*/
|
|
200
|
+
const LIST_KEYS = ["ArrowDown", "ArrowUp", "Home", "End", "Enter"]
|
|
201
|
+
|
|
202
|
+
function moveInList(event: KeyboardEvent) {
|
|
203
|
+
if (props.searchable || serverSide.value || !LIST_KEYS.includes(event.key)) return
|
|
204
|
+
const list = event.currentTarget as HTMLElement
|
|
205
|
+
const items = Array.from(list.querySelectorAll<HTMLElement>('[role="option"]:not([data-disabled])'))
|
|
206
|
+
if (!items.length) return
|
|
207
|
+
event.preventDefault()
|
|
208
|
+
event.stopPropagation()
|
|
209
|
+
const at = items.indexOf(list.ownerDocument.activeElement as HTMLElement)
|
|
210
|
+
if (event.key === "Enter") {
|
|
211
|
+
items[at]?.click()
|
|
212
|
+
return
|
|
213
|
+
}
|
|
214
|
+
const last = items.length - 1
|
|
215
|
+
const next = {
|
|
216
|
+
ArrowDown: at === last ? 0 : at + 1,
|
|
217
|
+
ArrowUp: at <= 0 ? last : at - 1,
|
|
218
|
+
Home: 0,
|
|
219
|
+
End: last,
|
|
220
|
+
}[event.key]
|
|
221
|
+
items[next ?? 0]?.focus()
|
|
193
222
|
}
|
|
194
223
|
|
|
195
224
|
// Leaving the field, not moving between its parts: the trigger and the list
|
|
@@ -219,7 +248,9 @@ function onListFocusOut(event: FocusEvent) {
|
|
|
219
248
|
* The trigger's name. reka hard-codes aria-label="Show popup" on it, which hid
|
|
220
249
|
* the field's label and the chosen value; aria-labelledby outranks aria-label,
|
|
221
250
|
* so inside a labelled field the name is the label plus the value. On its own,
|
|
222
|
-
* the consumer's aria-label, else the value or placeholder
|
|
251
|
+
* the consumer's aria-label plus the value, else the value or placeholder: the
|
|
252
|
+
* name has to hold the text the button shows, or a voice user who says what
|
|
253
|
+
* they see ("click Alpha") cannot reach it (WCAG 2.5.3).
|
|
223
254
|
*/
|
|
224
255
|
const attrs = useAttrs()
|
|
225
256
|
const valueId = `lp-select-${useId()}-value`
|
|
@@ -227,7 +258,7 @@ const valueText = computed(() => (chips.value.length ? chipNames.value : display
|
|
|
227
258
|
const triggerName = computed(() =>
|
|
228
259
|
field.value.labelId
|
|
229
260
|
? { "aria-labelledby": `${field.value.labelId} ${valueId}`, "aria-label": undefined }
|
|
230
|
-
: { "aria-label":
|
|
261
|
+
: { "aria-label": [attrs["aria-label"] as string | undefined, valueText.value].filter(Boolean).join(", ") },
|
|
231
262
|
)
|
|
232
263
|
|
|
233
264
|
// reka's Combobox forbids an empty-string item value (it reserves "" for
|
|
@@ -281,6 +312,7 @@ const filtered = computed(() => {
|
|
|
281
312
|
type Shown = { label: string; hint?: string; image?: string; icon?: string }
|
|
282
313
|
|
|
283
314
|
const remembered = reactive(new Map<SelectValue, Shown>())
|
|
315
|
+
const REMEMBERED_LIMIT = 500
|
|
284
316
|
|
|
285
317
|
function fromOption(o: SelectOption<V>): Shown {
|
|
286
318
|
return { label: o.label, hint: o.description, image: o.image, icon: o.icon }
|
|
@@ -291,6 +323,7 @@ function remember(values: readonly SelectValue[]) {
|
|
|
291
323
|
const o = props.options.find((x) => x.value === v)
|
|
292
324
|
if (o) remembered.set(v, fromOption(o))
|
|
293
325
|
}
|
|
326
|
+
evictOldest(remembered, new Set(values), REMEMBERED_LIMIT)
|
|
294
327
|
}
|
|
295
328
|
|
|
296
329
|
const modelList = computed<V[]>(() => {
|
|
@@ -355,7 +388,7 @@ function measure() {
|
|
|
355
388
|
if (!row || !probe) return
|
|
356
389
|
const kids = Array.from(probe.children) as HTMLElement[]
|
|
357
390
|
const more = kids.pop()
|
|
358
|
-
const gap = Number.parseFloat(getComputedStyle(probe).columnGap) || 0
|
|
391
|
+
const gap = Number.parseFloat(nodeWindow(probe).getComputedStyle(probe).columnGap) || 0
|
|
359
392
|
fit.value = fitChips(
|
|
360
393
|
kids.map((k) => k.offsetWidth),
|
|
361
394
|
row.clientWidth,
|
|
@@ -365,6 +398,9 @@ function measure() {
|
|
|
365
398
|
}
|
|
366
399
|
|
|
367
400
|
useResizeObserver(chipRow, () => measure())
|
|
401
|
+
// The chips can change width while the row keeps its own: a web font arriving,
|
|
402
|
+
// a theme. The probe is as wide as they are, so it notices.
|
|
403
|
+
useResizeObserver(probeRow, () => measure())
|
|
368
404
|
watch(chips, () => void nextTick(measure), { flush: "post", deep: true })
|
|
369
405
|
|
|
370
406
|
const shownChips = computed(() => chips.value.slice(0, fit.value))
|
|
@@ -451,7 +487,7 @@ usePaletteControl({ disabled: () => field.value.disabled, invalid: () => field.v
|
|
|
451
487
|
@keydown="openFromKeyboard"
|
|
452
488
|
v-bind="triggerName"
|
|
453
489
|
:aria-invalid="field.invalid || undefined"
|
|
454
|
-
:aria-describedby="field.describedBy"
|
|
490
|
+
:aria-describedby="mergeDescribedBy(rootAttrs['aria-describedby'], field.describedBy)"
|
|
455
491
|
class="flex min-w-0 flex-1 items-center gap-2 outline-none"
|
|
456
492
|
>
|
|
457
493
|
<!-- Several picks read as chips (picture + name) that collapse into
|
|
@@ -527,20 +563,13 @@ usePaletteControl({ disabled: () => field.value.disabled, invalid: () => field.v
|
|
|
527
563
|
</LpRollingText>
|
|
528
564
|
</template>
|
|
529
565
|
</ComboboxTrigger>
|
|
530
|
-
<
|
|
566
|
+
<IconCloseButton
|
|
531
567
|
v-if="clearable && hasValue && !field.disabled"
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
:aria-label="labels.clear"
|
|
568
|
+
inline
|
|
569
|
+
:label="labels.clear"
|
|
535
570
|
@pointerdown.prevent
|
|
536
571
|
@click="clear"
|
|
537
|
-
|
|
538
|
-
<LpIcon
|
|
539
|
-
name="lucide:x"
|
|
540
|
-
:size="16"
|
|
541
|
-
class="transition-transform duration-200 ease-[var(--ease-emphasized)] group-hover:rotate-90 group-active:scale-90 motion-reduce:group-hover:rotate-0"
|
|
542
|
-
/>
|
|
543
|
-
</button>
|
|
572
|
+
/>
|
|
544
573
|
<!-- A second way in for the pointer only: the main trigger already owns
|
|
545
574
|
focus and the accessible name, so this one stays out of the tab order
|
|
546
575
|
and the accessibility tree. -->
|
|
@@ -565,6 +594,7 @@ usePaletteControl({ disabled: () => field.value.disabled, invalid: () => field.v
|
|
|
565
594
|
<ComboboxContent
|
|
566
595
|
:data-lp-field-part="partId"
|
|
567
596
|
@focusout="onListFocusOut"
|
|
597
|
+
@keydown.capture="moveInList"
|
|
568
598
|
@interact-outside="guardOutside"
|
|
569
599
|
@escape-key-down="guardOutside"
|
|
570
600
|
position="popper"
|
|
@@ -35,6 +35,8 @@ export default { inheritAttrs: false }
|
|
|
35
35
|
* - Unmounting releases the GL context, so a page that mounts and unmounts
|
|
36
36
|
* backdrops does not run into the browser's limit on live contexts.
|
|
37
37
|
*/
|
|
38
|
+
import { clamp } from "../composables/clamp"
|
|
39
|
+
import { nodeWindow } from "../composables/useView"
|
|
38
40
|
import { computed, onBeforeUnmount, onMounted, ref, watch } from "vue"
|
|
39
41
|
import { parseColor } from "./color"
|
|
40
42
|
import { approach, frameDue, FRAGMENT_HEADER, PRESETS, tooSlow, VERTEX_SHADER, type ShaderPreset, type Vec3 } from "./shaderBackdrop"
|
|
@@ -95,7 +97,7 @@ const weakEngine = typeof navigator !== "undefined" && isBrokenBackdropEngine()
|
|
|
95
97
|
const fallbackStyle = computed(() => ({ background: PRESETS[props.preset].fallback, opacity: Math.min(1, clamp01(props.intensity) * 1.15) }))
|
|
96
98
|
|
|
97
99
|
function clamp01(n: number) {
|
|
98
|
-
return
|
|
100
|
+
return clamp(n, 0, 1)
|
|
99
101
|
}
|
|
100
102
|
|
|
101
103
|
// ── Theme colours ───────────────────────────────────────────────────────────
|
|
@@ -115,10 +117,10 @@ let paint: CanvasRenderingContext2D | null = null
|
|
|
115
117
|
function tokenColor(name: string): Vec3 {
|
|
116
118
|
if (!probe || !root.value) return [0, 0, 0]
|
|
117
119
|
probe.style.color = `var(--color-${name})`
|
|
118
|
-
const css = getComputedStyle(probe).color
|
|
120
|
+
const css = nodeWindow(probe).getComputedStyle(probe).color
|
|
119
121
|
const rgb = parseColor(css)
|
|
120
122
|
if (rgb) return [rgb.r / 255, rgb.g / 255, rgb.b / 255]
|
|
121
|
-
paint ??=
|
|
123
|
+
paint ??= probe.ownerDocument.createElement("canvas").getContext("2d", { willReadFrequently: true })
|
|
122
124
|
if (!paint) return [0, 0, 0]
|
|
123
125
|
paint.clearRect(0, 0, 1, 1)
|
|
124
126
|
paint.fillStyle = "#000"
|
|
@@ -204,7 +206,7 @@ let pixelRatio = 1
|
|
|
204
206
|
function sizeCanvas() {
|
|
205
207
|
const el = canvas.value
|
|
206
208
|
if (!el) return
|
|
207
|
-
const dpr = Math.min(weakEngine ? 1 : 2,
|
|
209
|
+
const dpr = Math.min(weakEngine ? 1 : 2, nodeWindow(el).devicePixelRatio || 1)
|
|
208
210
|
pixelRatio = dpr * PRESETS[props.preset].scale
|
|
209
211
|
const w = Math.max(1, Math.round(el.clientWidth * pixelRatio))
|
|
210
212
|
const h = Math.max(1, Math.round(el.clientHeight * pixelRatio))
|
|
@@ -351,16 +353,17 @@ useResizeObserver(root, () => {
|
|
|
351
353
|
})
|
|
352
354
|
|
|
353
355
|
onMounted(() => {
|
|
354
|
-
|
|
356
|
+
const page = root.value?.ownerDocument ?? document
|
|
357
|
+
probe = page.createElement("span")
|
|
355
358
|
probe.style.display = "none"
|
|
356
359
|
root.value?.appendChild(probe)
|
|
357
360
|
|
|
358
361
|
// Themes are applied as variables and attributes on <html>; a scheme switch can also come from the OS.
|
|
359
|
-
themeObserver = new MutationObserver(() => {
|
|
362
|
+
themeObserver = new (nodeWindow(page).MutationObserver)(() => {
|
|
360
363
|
if (gl) refreshPalette()
|
|
361
364
|
})
|
|
362
|
-
themeObserver.observe(
|
|
363
|
-
schemeQuery =
|
|
365
|
+
themeObserver.observe(page.documentElement, { attributes: true, attributeFilter: ["style", "class", "data-theme", "data-theme-mode"] })
|
|
366
|
+
schemeQuery = nodeWindow(page).matchMedia?.("(prefers-color-scheme: dark)")
|
|
364
367
|
schemeQuery?.addEventListener("change", refreshPalette)
|
|
365
368
|
|
|
366
369
|
if (wantGl.value) start()
|
|
@@ -391,7 +394,7 @@ watch(
|
|
|
391
394
|
}
|
|
392
395
|
drawFrame()
|
|
393
396
|
shown.value = true
|
|
394
|
-
}, durationToken("duration-medium"))
|
|
397
|
+
}, durationToken("duration-medium", undefined, root.value ?? undefined))
|
|
395
398
|
},
|
|
396
399
|
)
|
|
397
400
|
watch(
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
* The mechanism — measure the natural size, pin it in pixels, tween — lives in
|
|
26
26
|
* `useShift`, and LpModal drives its panel with the same composable.
|
|
27
27
|
*/
|
|
28
|
+
import { isElement, isHTMLElement, nodeWindow } from "../composables/useView"
|
|
28
29
|
import { computed, onBeforeUnmount, watch } from "vue"
|
|
29
30
|
import { prefersReducedMotion } from "../composables/easing"
|
|
30
31
|
import { useShift, type ShiftAxis } from "../composables/useShift"
|
|
@@ -99,6 +100,7 @@ const transitionClass = computed(() => TRANSITION_CLASS[props.axis])
|
|
|
99
100
|
const PRESENCE_MS = 200
|
|
100
101
|
const MOVE_MS = 160
|
|
101
102
|
const EASE = "cubic-bezier(0.2, 0, 0, 1)"
|
|
103
|
+
const SVG_NS = "http://www.w3.org/2000/svg"
|
|
102
104
|
const GHOST = "data-lp-shift-ghost"
|
|
103
105
|
|
|
104
106
|
interface Seen {
|
|
@@ -120,7 +122,7 @@ function rememberSoon(box: HTMLElement, wait = PRESENCE_MS + 80) {
|
|
|
120
122
|
}
|
|
121
123
|
|
|
122
124
|
function elementsOf(box: HTMLElement): Element[] {
|
|
123
|
-
return [...box.querySelectorAll("*")].filter((node) => !node.closest(`[${GHOST}]`) && !(node
|
|
125
|
+
return [...box.querySelectorAll("*")].filter((node) => !node.closest(`[${GHOST}]`) && !(node.namespaceURI === SVG_NS && node.localName !== "svg"))
|
|
124
126
|
}
|
|
125
127
|
|
|
126
128
|
function remember(box: HTMLElement) {
|
|
@@ -142,7 +144,7 @@ function remember(box: HTMLElement) {
|
|
|
142
144
|
// override that animation's transform, and the marker would pop instead of
|
|
143
145
|
// sliding.
|
|
144
146
|
function inFlow(node: Element): boolean {
|
|
145
|
-
const position = getComputedStyle(node).position
|
|
147
|
+
const position = nodeWindow(node).getComputedStyle(node).position
|
|
146
148
|
return position !== "absolute" && position !== "fixed"
|
|
147
149
|
}
|
|
148
150
|
|
|
@@ -150,7 +152,7 @@ function inFlow(node: Element): boolean {
|
|
|
150
152
|
// actions, a list re-keyed after a reload) is not a change anyone sees, so the
|
|
151
153
|
// pair is left alone rather than flashing out and in.
|
|
152
154
|
function signature(node: Node): string | undefined {
|
|
153
|
-
return node
|
|
155
|
+
return isElement(node) ? node.outerHTML : undefined
|
|
154
156
|
}
|
|
155
157
|
|
|
156
158
|
function unchanged(records: MutationRecord[]): Set<Node> {
|
|
@@ -172,7 +174,7 @@ const offset = () => (props.anchor === "end" ? -6 : 6)
|
|
|
172
174
|
|
|
173
175
|
function ghost(box: HTMLElement, node: Element) {
|
|
174
176
|
const at = seen.get(node)
|
|
175
|
-
if (!at || !at.flow || !(node
|
|
177
|
+
if (!at || !at.flow || !isHTMLElement(node) || node.hasAttribute(GHOST) || at.width === 0) return
|
|
176
178
|
const copy = node.cloneNode(true) as HTMLElement
|
|
177
179
|
copy.setAttribute(GHOST, "")
|
|
178
180
|
copy.setAttribute("aria-hidden", "true")
|
|
@@ -207,7 +209,7 @@ function ghost(box: HTMLElement, node: Element) {
|
|
|
207
209
|
}
|
|
208
210
|
|
|
209
211
|
function arrive(node: Element) {
|
|
210
|
-
if (!(node
|
|
212
|
+
if (!isHTMLElement(node) || node.hasAttribute(GHOST) || !inFlow(node)) return
|
|
211
213
|
node.animate(
|
|
212
214
|
[
|
|
213
215
|
{ opacity: 0, transform: `translateX(${offset()}px) scale(0.96)`, filter: "blur(2px)" },
|
|
@@ -219,7 +221,7 @@ function arrive(node: Element) {
|
|
|
219
221
|
|
|
220
222
|
function glide(node: Element) {
|
|
221
223
|
const was = seen.get(node)
|
|
222
|
-
if (!was || !(node
|
|
224
|
+
if (!was || !isHTMLElement(node)) return
|
|
223
225
|
const now = node.getBoundingClientRect()
|
|
224
226
|
const dx = was.x - now.left
|
|
225
227
|
const dy = was.y - now.top
|
|
@@ -236,25 +238,26 @@ watch(
|
|
|
236
238
|
presenceSize = undefined
|
|
237
239
|
if (!box || !on) return
|
|
238
240
|
remember(box)
|
|
239
|
-
|
|
241
|
+
const win = nodeWindow(box)
|
|
242
|
+
presenceObserver = new win.MutationObserver((records) => {
|
|
240
243
|
const real = records.filter(
|
|
241
244
|
(r) =>
|
|
242
|
-
![...r.addedNodes, ...r.removedNodes].every((n) => n
|
|
245
|
+
![...r.addedNodes, ...r.removedNodes].every((n) => isElement(n) && n.hasAttribute(GHOST)),
|
|
243
246
|
)
|
|
244
|
-
if (real.length && !prefersReducedMotion()) {
|
|
247
|
+
if (real.length && !prefersReducedMotion(win)) {
|
|
245
248
|
const added = new Set<Node>()
|
|
246
249
|
const same = unchanged(real)
|
|
247
250
|
for (const record of real) {
|
|
248
|
-
record.removedNodes.forEach((node) => node
|
|
251
|
+
record.removedNodes.forEach((node) => isElement(node) && !same.has(node) && ghost(box, node))
|
|
249
252
|
record.addedNodes.forEach((node) => {
|
|
250
253
|
added.add(node)
|
|
251
|
-
if (node
|
|
254
|
+
if (isElement(node) && !same.has(node)) arrive(node)
|
|
252
255
|
})
|
|
253
256
|
}
|
|
254
257
|
// Measured in the next frame, which still comes before the paint: by
|
|
255
258
|
// then the box has taken the classes the change gave it (held to its
|
|
256
259
|
// edge), and the place an element lands is the one it will keep.
|
|
257
|
-
const parents = real.map((r) => r.target).filter((t): t is Element => t
|
|
260
|
+
const parents = real.map((r) => r.target).filter((t): t is Element => isElement(t) && !t.hasAttribute(GHOST))
|
|
258
261
|
requestAnimationFrame(() => {
|
|
259
262
|
for (const parent of parents) for (const child of parent.children) if (!added.has(child)) glide(child)
|
|
260
263
|
})
|
|
@@ -262,9 +265,9 @@ watch(
|
|
|
262
265
|
rememberSoon(box)
|
|
263
266
|
})
|
|
264
267
|
presenceObserver.observe(box, { childList: true, subtree: true })
|
|
265
|
-
presenceSize = new ResizeObserver(() => rememberSoon(box, 60))
|
|
268
|
+
presenceSize = new win.ResizeObserver(() => rememberSoon(box, 60))
|
|
266
269
|
presenceSize.observe(box)
|
|
267
|
-
void
|
|
270
|
+
void box.ownerDocument.fonts?.ready.then(() => rememberSoon(box, 0))
|
|
268
271
|
},
|
|
269
272
|
{ flush: "post" },
|
|
270
273
|
)
|
|
@@ -274,7 +277,7 @@ watch(
|
|
|
274
277
|
// resize, every child glides from where it was last seen.
|
|
275
278
|
watch(resizing, (now) => {
|
|
276
279
|
const box = el.value
|
|
277
|
-
if (!now || !box || !presenceObserver || prefersReducedMotion()) return
|
|
280
|
+
if (!now || !box || !presenceObserver || prefersReducedMotion(nodeWindow(box))) return
|
|
278
281
|
requestAnimationFrame(() => {
|
|
279
282
|
for (const child of box.children) if (!child.hasAttribute(GHOST)) glide(child)
|
|
280
283
|
})
|
|
@@ -13,8 +13,10 @@
|
|
|
13
13
|
* auto-closes the drawer. With `responsive` off the component renders exactly
|
|
14
14
|
* the static <nav> it always has — existing call sites are unaffected.
|
|
15
15
|
*/
|
|
16
|
-
import {
|
|
16
|
+
import { clamp } from "../composables/clamp"
|
|
17
|
+
import { computed, nextTick, onBeforeUnmount, ref, useId } from "vue"
|
|
17
18
|
import { parseCombo, useHotkeys } from "../composables/useHotkeys"
|
|
19
|
+
import { startPointerDrag } from "../composables/pointerDrag"
|
|
18
20
|
import { usePersisted } from "../composables/usePersisted"
|
|
19
21
|
import { useLabels } from "../composables/useLpConfig"
|
|
20
22
|
import LpDrawer from "./LpDrawer.vue"
|
|
@@ -123,7 +125,7 @@ const props = withDefaults(
|
|
|
123
125
|
persist?: string
|
|
124
126
|
/**
|
|
125
127
|
* Fold collapsible groups automatically once the nav has more than this
|
|
126
|
-
* many rows, counting headings and
|
|
128
|
+
* many rows, counting headings, items and the pages under them alike.
|
|
127
129
|
*
|
|
128
130
|
* The reason is the reader, not the pixels: a short nav is taken in at a
|
|
129
131
|
* glance, a long one has to be searched, and searching a list you did not
|
|
@@ -310,9 +312,12 @@ const ownCollapsed = usePersisted<string[] | null>(
|
|
|
310
312
|
{ validate: (value): value is string[] | null => value === null || (Array.isArray(value) && value.every((k) => typeof k === "string")) },
|
|
311
313
|
)
|
|
312
314
|
|
|
313
|
-
/** Headings
|
|
314
|
-
const navLength = computed(
|
|
315
|
-
|
|
315
|
+
/** Headings, items and their pages: what the eye actually has to walk past. */
|
|
316
|
+
const navLength = computed(() =>
|
|
317
|
+
groups.value.reduce(
|
|
318
|
+
(n, g) => n + (g.title ? 1 : 0) + g.items.reduce((rows, i) => rows + 1 + (i.children?.length ?? 0), 0),
|
|
319
|
+
0,
|
|
320
|
+
),
|
|
316
321
|
)
|
|
317
322
|
|
|
318
323
|
/*
|
|
@@ -340,7 +345,9 @@ function toggleSection(key: string, collapsed: boolean) {
|
|
|
340
345
|
const next = collapsed
|
|
341
346
|
? [...new Set([...collapsedKeys.value, key])]
|
|
342
347
|
: collapsedKeys.value.filter((k) => k !== key)
|
|
343
|
-
|
|
348
|
+
// A bound value is the app's: storing it too would surface a stale choice
|
|
349
|
+
// the day the binding goes. The same goes for compact and pins below.
|
|
350
|
+
if (props.collapsed === undefined) ownCollapsed.value = next
|
|
344
351
|
emit("update:collapsed", next)
|
|
345
352
|
}
|
|
346
353
|
|
|
@@ -351,7 +358,7 @@ function toggleSection(key: string, collapsed: boolean) {
|
|
|
351
358
|
const ownCompact = usePersisted<boolean>(() => props.persist && `lp-sidebar:${props.persist}:compact`, false)
|
|
352
359
|
const isCompact = computed(() => props.compact ?? ownCompact.value)
|
|
353
360
|
function setCompact(value: boolean) {
|
|
354
|
-
ownCompact.value = value
|
|
361
|
+
if (props.compact === undefined) ownCompact.value = value
|
|
355
362
|
emit("update:compact", value)
|
|
356
363
|
}
|
|
357
364
|
|
|
@@ -370,12 +377,20 @@ const env = computed(() => {
|
|
|
370
377
|
|
|
371
378
|
const DEFAULT_WIDTH = 240
|
|
372
379
|
const COMPACT_WIDTH = 64
|
|
373
|
-
const ownWidth = usePersisted<number>(() => props.resizable && props.persist && `lp-sidebar:${props.persist}:width`, DEFAULT_WIDTH
|
|
380
|
+
const ownWidth = usePersisted<number>(() => props.resizable && props.persist && `lp-sidebar:${props.persist}:width`, DEFAULT_WIDTH, {
|
|
381
|
+
validate: (value): value is number => typeof value === "number" && Number.isFinite(value),
|
|
382
|
+
})
|
|
374
383
|
const dragging = ref(false)
|
|
375
384
|
|
|
385
|
+
/*
|
|
386
|
+
* The bounds apply to what is drawn, not to what is kept: a width remembered
|
|
387
|
+
* under other bounds fits today's, and comes back if they widen again.
|
|
388
|
+
*/
|
|
389
|
+
const boundedWidth = (width: number) => clamp(width, props.minWidth, props.maxWidth)
|
|
390
|
+
|
|
376
391
|
const railWidth = computed(() => {
|
|
377
392
|
if (isCompact.value) return `${COMPACT_WIDTH}px`
|
|
378
|
-
if (props.resizable) return `${ownWidth.value}px`
|
|
393
|
+
if (props.resizable) return `${boundedWidth(ownWidth.value)}px`
|
|
379
394
|
return props.width
|
|
380
395
|
})
|
|
381
396
|
|
|
@@ -385,34 +400,32 @@ const railWidth = computed(() => {
|
|
|
385
400
|
* useful, and the icon rail is the honest form of "narrow".
|
|
386
401
|
*/
|
|
387
402
|
const FOLD_AT = 132
|
|
403
|
+
let stopResize: (() => void) | null = null
|
|
404
|
+
onBeforeUnmount(() => stopResize?.())
|
|
405
|
+
|
|
388
406
|
function startResize(event: PointerEvent) {
|
|
389
407
|
if (event.button !== 0) return
|
|
390
|
-
const handle = event.currentTarget as HTMLElement
|
|
391
|
-
handle.setPointerCapture(event.pointerId)
|
|
392
408
|
const from = event.clientX
|
|
393
|
-
const start = isCompact.value ? COMPACT_WIDTH : ownWidth.value
|
|
409
|
+
const start = isCompact.value ? COMPACT_WIDTH : boundedWidth(ownWidth.value)
|
|
394
410
|
dragging.value = true
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
}
|
|
413
|
-
handle.addEventListener("pointermove", move)
|
|
414
|
-
handle.addEventListener("pointerup", stop)
|
|
415
|
-
handle.addEventListener("pointercancel", stop)
|
|
411
|
+
stopResize = startPointerDrag(event, {
|
|
412
|
+
move(e) {
|
|
413
|
+
const wanted = start + (e.clientX - from)
|
|
414
|
+
if (wanted < FOLD_AT) {
|
|
415
|
+
// Folded by dragging: the width it unfolds to is the one it had, not
|
|
416
|
+
// the narrowest the drag passed through on its way down.
|
|
417
|
+
if (!isCompact.value) setCompact(true)
|
|
418
|
+
if (start !== COMPACT_WIDTH) ownWidth.value = start
|
|
419
|
+
return
|
|
420
|
+
}
|
|
421
|
+
if (isCompact.value) setCompact(false)
|
|
422
|
+
ownWidth.value = Math.round(boundedWidth(wanted))
|
|
423
|
+
},
|
|
424
|
+
end() {
|
|
425
|
+
dragging.value = false
|
|
426
|
+
stopResize = null
|
|
427
|
+
},
|
|
428
|
+
})
|
|
416
429
|
}
|
|
417
430
|
const railEl = ref<HTMLElement | null>(null)
|
|
418
431
|
async function searchFromCompact() {
|
|
@@ -451,7 +464,7 @@ const pinnedItems = computed<SidebarItem[]>(() =>
|
|
|
451
464
|
)
|
|
452
465
|
function togglePin(id: string) {
|
|
453
466
|
const next = pinnedIds.value.includes(id) ? pinnedIds.value.filter((k) => k !== id) : [...pinnedIds.value, id]
|
|
454
|
-
ownPinned.value = next
|
|
467
|
+
if (props.pinned === undefined) ownPinned.value = next
|
|
455
468
|
emit("update:pinned", next)
|
|
456
469
|
}
|
|
457
470
|
|
|
@@ -495,6 +508,32 @@ const chromeClass = computed(() =>
|
|
|
495
508
|
// Vue can't auto-inherit a consumer-passed `class`. Take attrs over manually and
|
|
496
509
|
// land them on the desktop rail (where a layout class like `shrink-0` belongs).
|
|
497
510
|
defineOptions({ inheritAttrs: false })
|
|
511
|
+
|
|
512
|
+
// The rail and the drawer draw the same list and the same search over it.
|
|
513
|
+
const navBinds = computed(() => ({
|
|
514
|
+
groups: groups.value,
|
|
515
|
+
pinnable: props.pinnable,
|
|
516
|
+
pinned: pinnedItems.value,
|
|
517
|
+
previewDelay: props.previewDelay,
|
|
518
|
+
labels: text.value,
|
|
519
|
+
itemActive,
|
|
520
|
+
loading: props.loading,
|
|
521
|
+
skeletonRows: props.skeletonRows,
|
|
522
|
+
skeletonHeader: props.skeletonHeader,
|
|
523
|
+
collapsedKeys: collapsedKeys.value,
|
|
524
|
+
hoverFollow: props.hoverFollow,
|
|
525
|
+
onActivate: activate,
|
|
526
|
+
onToggleSection: toggleSection,
|
|
527
|
+
onTogglePin: togglePin,
|
|
528
|
+
}))
|
|
529
|
+
const searchField = computed(() => ({
|
|
530
|
+
size: "sm" as const,
|
|
531
|
+
icon: "lucide:search",
|
|
532
|
+
clearable: true,
|
|
533
|
+
class: "mb-2 shrink-0",
|
|
534
|
+
placeholder: placeholder.value,
|
|
535
|
+
"aria-label": placeholder.value,
|
|
536
|
+
}))
|
|
498
537
|
</script>
|
|
499
538
|
|
|
500
539
|
<template>
|
|
@@ -558,30 +597,12 @@ defineOptions({ inheritAttrs: false })
|
|
|
558
597
|
<LpInput
|
|
559
598
|
v-if="searchable && !isCompact"
|
|
560
599
|
v-model="query"
|
|
561
|
-
|
|
562
|
-
icon="lucide:search"
|
|
563
|
-
clearable
|
|
564
|
-
class="mb-2 shrink-0"
|
|
565
|
-
:placeholder="placeholder"
|
|
566
|
-
:aria-label="placeholder"
|
|
600
|
+
v-bind="searchField"
|
|
567
601
|
/>
|
|
568
602
|
<LpSidebarNav
|
|
569
|
-
|
|
603
|
+
v-bind="navBinds"
|
|
570
604
|
:pill-id="railPillId"
|
|
571
605
|
:compact="isCompact"
|
|
572
|
-
:pinnable="pinnable"
|
|
573
|
-
:pinned="pinnedItems"
|
|
574
|
-
:preview-delay="previewDelay"
|
|
575
|
-
:labels="text"
|
|
576
|
-
:item-active="itemActive"
|
|
577
|
-
:loading="loading"
|
|
578
|
-
:skeleton-rows="skeletonRows"
|
|
579
|
-
:skeleton-header="skeletonHeader"
|
|
580
|
-
:collapsed-keys="collapsedKeys"
|
|
581
|
-
:hover-follow="hoverFollow"
|
|
582
|
-
@activate="activate"
|
|
583
|
-
@toggle-section="toggleSection"
|
|
584
|
-
@toggle-pin="togglePin"
|
|
585
606
|
>
|
|
586
607
|
<template v-if="$slots.item" #item="slotProps">
|
|
587
608
|
<slot name="item" v-bind="slotProps" />
|
|
@@ -660,29 +681,11 @@ defineOptions({ inheritAttrs: false })
|
|
|
660
681
|
<LpInput
|
|
661
682
|
v-if="searchable"
|
|
662
683
|
v-model="query"
|
|
663
|
-
|
|
664
|
-
icon="lucide:search"
|
|
665
|
-
clearable
|
|
666
|
-
class="mb-2 shrink-0"
|
|
667
|
-
:placeholder="placeholder"
|
|
668
|
-
:aria-label="placeholder"
|
|
684
|
+
v-bind="searchField"
|
|
669
685
|
/>
|
|
670
686
|
<LpSidebarNav
|
|
671
|
-
|
|
687
|
+
v-bind="navBinds"
|
|
672
688
|
:pill-id="drawerPillId"
|
|
673
|
-
:pinnable="pinnable"
|
|
674
|
-
:pinned="pinnedItems"
|
|
675
|
-
:preview-delay="previewDelay"
|
|
676
|
-
:labels="text"
|
|
677
|
-
:item-active="itemActive"
|
|
678
|
-
:loading="loading"
|
|
679
|
-
:skeleton-rows="skeletonRows"
|
|
680
|
-
:skeleton-header="skeletonHeader"
|
|
681
|
-
:collapsed-keys="collapsedKeys"
|
|
682
|
-
:hover-follow="hoverFollow"
|
|
683
|
-
@activate="activate"
|
|
684
|
-
@toggle-section="toggleSection"
|
|
685
|
-
@toggle-pin="togglePin"
|
|
686
689
|
>
|
|
687
690
|
<template v-if="$slots.item" #item="slotProps">
|
|
688
691
|
<slot name="item" v-bind="slotProps" />
|
|
@@ -149,7 +149,8 @@ let typedAt = 0
|
|
|
149
149
|
function onKey(event: KeyboardEvent) {
|
|
150
150
|
const box = event.currentTarget as HTMLElement
|
|
151
151
|
const list = [...box.querySelectorAll<HTMLElement>("[data-lp-nav-row]")].filter((r) => r.offsetParent !== null)
|
|
152
|
-
|
|
152
|
+
// The rows' own document: inside an LpFrame the page's only knows the iframe.
|
|
153
|
+
const at = list.indexOf(box.ownerDocument.activeElement as HTMLElement)
|
|
153
154
|
if (at < 0) return
|
|
154
155
|
const row = list[at]!
|
|
155
156
|
const go = (i: number) => {
|
|
@@ -270,7 +271,7 @@ const { class: rootClass, attrs: rest } = useMergedAttrs(
|
|
|
270
271
|
@activate="activate"
|
|
271
272
|
/>
|
|
272
273
|
</div>
|
|
273
|
-
<template v-for="(section, si) in groups" :key="si">
|
|
274
|
+
<template v-for="(section, si) in groups" :key="sectionKey(section) || si">
|
|
274
275
|
<!-- Compact, a group that folds is one icon: its pages open in the card
|
|
275
276
|
beside it, as a page's own pages do. A hundred initials in a column
|
|
276
277
|
would be no nav at all. -->
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* sidebar it is the row's name (and the pages under it), since the row shows
|
|
10
10
|
* only an icon; with a `preview` it is a glance at the page before going there.
|
|
11
11
|
*/
|
|
12
|
+
import { clamp } from "../composables/clamp"
|
|
12
13
|
import { Motion } from "motion-v"
|
|
13
14
|
import { computed, onBeforeUnmount, ref, watch } from "vue"
|
|
14
15
|
import { useLocale } from "../composables/useLocale"
|
|
@@ -164,7 +165,7 @@ const delay = computed(() => (props.compact && !props.item.preview ? 250 : props
|
|
|
164
165
|
<span
|
|
165
166
|
v-if="typeof item.busy === 'number'"
|
|
166
167
|
class="block h-full rounded-pill bg-brand transition-[width] duration-(--duration-medium) ease-[var(--ease-emphasized)]"
|
|
167
|
-
:style="{ width: `${Math.round(
|
|
168
|
+
:style="{ width: `${Math.round(clamp(item.busy, 0, 1) * 100)}%` }"
|
|
168
169
|
/>
|
|
169
170
|
<span v-else class="lp-sweep absolute inset-y-0 left-0 w-2/5 rounded-pill bg-brand" />
|
|
170
171
|
</span>
|