@feugene/granularity 0.48.0 → 0.50.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 +3 -3
- package/dist/chunks/chevron-up-BhW6hi8L.js +23 -0
- package/dist/chunks/chevron-up-BhW6hi8L.js.map +1 -0
- package/dist/chunks/{config-E1cTyRVV.js → config-8n1VR0ju.js} +1 -1
- package/dist/chunks/{config-E1cTyRVV.js.map → config-8n1VR0ju.js.map} +1 -1
- package/dist/chunks/{config-2vrOFn2f.js → config-AKpLyIGD.js} +2 -2
- package/dist/chunks/{config-2vrOFn2f.js.map → config-AKpLyIGD.js.map} +1 -1
- package/dist/chunks/{config-DIDz_E5m.js → config-B34mkd53.js} +66 -1
- package/dist/chunks/config-B34mkd53.js.map +1 -0
- package/dist/chunks/{config-B5SBUa6u.js → config-B7qZqiUB.js} +28 -1
- package/dist/chunks/config-B7qZqiUB.js.map +1 -0
- package/dist/chunks/config-BBrPUEye.js +8 -0
- package/dist/chunks/config-BBrPUEye.js.map +1 -0
- package/dist/chunks/config-BBtBQE3s.js +108 -0
- package/dist/chunks/config-BBtBQE3s.js.map +1 -0
- package/dist/chunks/{config-CT4lP6S4.js → config-BOCzHqWh.js} +2 -2
- package/dist/chunks/{config-CT4lP6S4.js.map → config-BOCzHqWh.js.map} +1 -1
- package/dist/chunks/{config-iemgzS4x.js → config-BP1ktzwh.js} +2 -24
- package/dist/chunks/config-BP1ktzwh.js.map +1 -0
- package/dist/chunks/config-BTxmdRzT.js +28 -0
- package/dist/chunks/config-BTxmdRzT.js.map +1 -0
- package/dist/chunks/{config-CjWOTgLL.js → config-Bk52xd5l.js} +12 -5
- package/dist/chunks/config-Bk52xd5l.js.map +1 -0
- package/dist/chunks/{config-D3HOuHDe.js → config-C3SqBqSQ.js} +3 -1
- package/dist/chunks/config-C3SqBqSQ.js.map +1 -0
- package/dist/chunks/{config-2ZHRsdOc.js → config-C3uqd-sW.js} +1 -1
- package/dist/chunks/config-C3uqd-sW.js.map +1 -0
- package/dist/chunks/{config-BXRmsn3t.js → config-CPhcZzHi.js} +72 -10
- package/dist/chunks/config-CPhcZzHi.js.map +1 -0
- package/dist/chunks/config-CWtfxkM9.js.map +1 -1
- package/dist/chunks/{config--t2dxj0t.js → config-CmLTCmY9.js} +2 -2
- package/dist/chunks/{config--t2dxj0t.js.map → config-CmLTCmY9.js.map} +1 -1
- package/dist/chunks/{config-BAse0laT.js → config-CvtqB4ki.js} +8 -3
- package/dist/chunks/config-CvtqB4ki.js.map +1 -0
- package/dist/chunks/{config-BcXX7S7B.js → config-D-JgqV0J.js} +5 -1
- package/dist/chunks/{config-BcXX7S7B.js.map → config-D-JgqV0J.js.map} +1 -1
- package/dist/chunks/{config-BHLMTJaR.js → config-D1oVht-E.js} +8 -3
- package/dist/chunks/config-D1oVht-E.js.map +1 -0
- package/dist/chunks/{config-BscVxZR3.js → config-DF1ezU6y.js} +1 -1
- package/dist/chunks/{config-BscVxZR3.js.map → config-DF1ezU6y.js.map} +1 -1
- package/dist/chunks/{config-B42iJ48O.js → config-DG41PD9i.js} +13 -1
- package/dist/chunks/config-DG41PD9i.js.map +1 -0
- package/dist/chunks/{config-Bs1HwUcx.js → config-DPJ3jtiB.js} +12 -2
- package/dist/chunks/config-DPJ3jtiB.js.map +1 -0
- package/dist/chunks/{config-tNqtapcT.js → config-DpqjlCfB.js} +2 -2
- package/dist/chunks/{config-tNqtapcT.js.map → config-DpqjlCfB.js.map} +1 -1
- package/dist/chunks/{config-DNDgp9bB.js → config-DpzFoSIh.js} +64 -2
- package/dist/chunks/config-DpzFoSIh.js.map +1 -0
- package/dist/chunks/config-MUkhktTP.js +267 -0
- package/dist/chunks/config-MUkhktTP.js.map +1 -0
- package/dist/chunks/config-SPugeaHT.js +37 -0
- package/dist/chunks/config-SPugeaHT.js.map +1 -0
- package/dist/chunks/{en-Bxyn5lW7.js → en-mIFywnV2.js} +27 -7
- package/dist/chunks/en-mIFywnV2.js.map +1 -0
- package/dist/chunks/{es-Dtl-a7ui.js → es-CvthYwtB.js} +27 -7
- package/dist/chunks/es-CvthYwtB.js.map +1 -0
- package/dist/chunks/{es-Bj_vc18Z.js → es-DlGd6Mrj.js} +3 -3
- package/dist/chunks/{es-Bj_vc18Z.js.map → es-DlGd6Mrj.js.map} +1 -1
- package/dist/chunks/{generated-hELWB0gZ.js → generated-Cx4C7GRN.js} +126 -0
- package/dist/chunks/{generated-hELWB0gZ.js.map → generated-Cx4C7GRN.js.map} +1 -1
- package/dist/chunks/{grBadgeStyles-DV0DrAew.js → grBadgeStyles-D51AXbj5.js} +57 -1
- package/dist/chunks/grBadgeStyles-D51AXbj5.js.map +1 -0
- package/dist/chunks/{grChipStyles-DcDyxAL0.js → grChipStyles-CA9Wj1_E.js} +1 -1
- package/dist/chunks/{grChipStyles-DcDyxAL0.js.map → grChipStyles-CA9Wj1_E.js.map} +1 -1
- package/dist/chunks/{grPopoverStyles-CYAeO3Ov.js → grPopoverStyles-CncEkiPu.js} +1 -1
- package/dist/chunks/{grPopoverStyles-CYAeO3Ov.js.map → grPopoverStyles-CncEkiPu.js.map} +1 -1
- package/dist/chunks/{grSelectStyles-D9EQ-pgK.js → grSelectStyles-Cam-IG9s.js} +3 -2
- package/dist/chunks/grSelectStyles-Cam-IG9s.js.map +1 -0
- package/dist/chunks/{grSliderStyles-kaz6VXZ3.js → grSliderStyles-CqzV0hll.js} +1 -1
- package/dist/chunks/grSliderStyles-CqzV0hll.js.map +1 -0
- package/dist/chunks/{config-CbEbLyDE.js → grSortableListStyles-CxieDmpe.js} +1 -27
- package/dist/chunks/grSortableListStyles-CxieDmpe.js.map +1 -0
- package/dist/chunks/grTableStyles-CPSxDTOW.js +66 -0
- package/dist/chunks/grTableStyles-CPSxDTOW.js.map +1 -0
- package/dist/chunks/{config-CMNfZO7S.js → grTabsStyles-DIz2VdIm.js} +1 -36
- package/dist/chunks/grTabsStyles-DIz2VdIm.js.map +1 -0
- package/dist/chunks/grTooltipStyles-CtbGEEGV.js +24 -0
- package/dist/chunks/grTooltipStyles-CtbGEEGV.js.map +1 -0
- package/dist/chunks/{granular-provider-BOQp7N5o.js → granular-provider-cv5vaM1a.js} +26 -22
- package/dist/chunks/granular-provider-cv5vaM1a.js.map +1 -0
- package/dist/chunks/hotkeySequence-BTHIM_5A.js +46 -0
- package/dist/chunks/hotkeySequence-BTHIM_5A.js.map +1 -0
- package/dist/chunks/{keyboard-DE2yhz_b.js → keyboard-BiFSgWLt.js} +70 -1
- package/dist/chunks/keyboard-BiFSgWLt.js.map +1 -0
- package/dist/chunks/optionPanel-DvY7Tv_4.js +182 -0
- package/dist/chunks/optionPanel-DvY7Tv_4.js.map +1 -0
- package/dist/chunks/overlayListPanel-D91jBCHU.js +21 -0
- package/dist/chunks/overlayListPanel-D91jBCHU.js.map +1 -0
- package/dist/chunks/{overlayStack-DH4Z7am1.js → overlayStack-DCkCgXZP.js} +1 -1
- package/dist/chunks/{overlayStack-DH4Z7am1.js.map → overlayStack-DCkCgXZP.js.map} +1 -1
- package/dist/chunks/{overlayPanelSurface-BKeMhRx4.js → overlayTransition-C0FDMx7Q.js} +24 -24
- package/dist/chunks/overlayTransition-C0FDMx7Q.js.map +1 -0
- package/dist/chunks/{ru-hrB4I1u_.js → ru-CQKDR-kD.js} +27 -7
- package/dist/chunks/ru-CQKDR-kD.js.map +1 -0
- package/dist/chunks/{safelist-x8USecK8.js → safelist-CSfynUC1.js} +5 -1
- package/dist/chunks/safelist-CSfynUC1.js.map +1 -0
- package/dist/chunks/{useMenuItemsFocus-B7Bl_aFA.js → useMenuItemsFocus-C031blYS.js} +1 -1
- package/dist/chunks/{useMenuItemsFocus-B7Bl_aFA.js.map → useMenuItemsFocus-C031blYS.js.map} +1 -1
- package/dist/chunks/{useModalOverlay-ACRkflzx.js → useModalOverlay-CKCQkGdB.js} +1 -1
- package/dist/chunks/{useModalOverlay-ACRkflzx.js.map → useModalOverlay-CKCQkGdB.js.map} +1 -1
- package/dist/components/GrAutocomplete/chunks/{GrAutocomplete-C-uovdv8.js → GrAutocomplete-Cyr1-ENw.js} +183 -125
- package/dist/components/GrAutocomplete/chunks/GrAutocomplete-Cyr1-ENw.js.map +1 -0
- package/dist/components/GrAutocomplete/index.js +2 -2
- package/dist/components/GrAutocomplete/styles.css +1 -1
- package/dist/components/GrBadge/chunks/GrBadge-C42KLyUD.js +71 -0
- package/dist/components/GrBadge/chunks/GrBadge-C42KLyUD.js.map +1 -0
- package/dist/components/GrBadge/index.js +3 -3
- package/dist/components/GrBadge/styles.css +1 -1
- package/dist/components/GrCarousel/chunks/{GrCarousel-ByuughtI.js → GrCarousel-CBj-PEPB.js} +186 -37
- package/dist/components/GrCarousel/chunks/GrCarousel-CBj-PEPB.js.map +1 -0
- package/dist/components/GrCarousel/index.js +2 -2
- package/dist/components/GrCarousel/styles.css +1 -1
- package/dist/components/GrCheckbox/chunks/{GrCheckbox-Dp201frb.js → GrCheckbox-B4NJc7Ur.js} +2 -1
- package/dist/components/GrCheckbox/chunks/GrCheckbox-B4NJc7Ur.js.map +1 -0
- package/dist/components/GrCheckbox/index.js +1 -1
- package/dist/components/GrCheckboxGroup/chunks/{GrCheckboxGroup-IpqG5qwm.js → GrCheckboxGroup-qZHpNFCX.js} +1 -1
- package/dist/components/GrCheckboxGroup/chunks/{GrCheckboxGroup-IpqG5qwm.js.map → GrCheckboxGroup-qZHpNFCX.js.map} +1 -1
- package/dist/components/GrCheckboxGroup/index.js +1 -1
- package/dist/components/GrChip/chunks/{GrChip-CKqyzYcv.js → GrChip-DoyS1Dr4.js} +1 -1
- package/dist/components/GrChip/chunks/{GrChip-CKqyzYcv.js.map → GrChip-DoyS1Dr4.js.map} +1 -1
- package/dist/components/GrChip/index.js +2 -2
- package/dist/components/GrColorPicker/chunks/{GrColorPicker-BRM_4lyI.js → GrColorPicker-vGSgpUV9.js} +353 -38
- package/dist/components/GrColorPicker/chunks/GrColorPicker-vGSgpUV9.js.map +1 -0
- package/dist/components/GrColorPicker/index.js +2 -2
- package/dist/components/GrColorPicker/styles.css +1 -1
- package/dist/components/GrCommandPalette/chunks/{GrCommandPalette-BJHmkDQv.js → GrCommandPalette-CAHgj0Aa.js} +23 -7
- package/dist/components/GrCommandPalette/chunks/GrCommandPalette-CAHgj0Aa.js.map +1 -0
- package/dist/components/GrCommandPalette/index.js +1 -1
- package/dist/components/GrCommandPalette/styles.css +1 -1
- package/dist/components/GrConfirmDialog/chunks/{GrConfirmDialog-BzUQwbec.js → GrConfirmDialog-dg021BMd.js} +1 -1
- package/dist/components/GrConfirmDialog/chunks/{GrConfirmDialog-BzUQwbec.js.map → GrConfirmDialog-dg021BMd.js.map} +1 -1
- package/dist/components/GrConfirmDialog/index.js +1 -1
- package/dist/components/GrContextMenu/chunks/{GrContextMenu-RpxMHQXH.js → GrContextMenu-bQ1Vvy2c.js} +3 -3
- package/dist/components/GrContextMenu/chunks/{GrContextMenu-RpxMHQXH.js.map → GrContextMenu-bQ1Vvy2c.js.map} +1 -1
- package/dist/components/GrContextMenu/index.js +1 -1
- package/dist/components/GrDataTable/chunks/{GrDataTable-DQxYYgQk.js → GrDataTable-Bb2jWnRG.js} +576 -136
- package/dist/components/GrDataTable/chunks/GrDataTable-Bb2jWnRG.js.map +1 -0
- package/dist/components/GrDataTable/index.js +2 -2
- package/dist/components/GrDelta/chunks/{GrDelta-CgTvfoIN.js → GrDelta-BSv1KdMy.js} +0 -0
- package/dist/components/GrDelta/chunks/{GrDelta-CgTvfoIN.js.map → GrDelta-BSv1KdMy.js.map} +1 -1
- package/dist/components/GrDelta/index.js +2 -2
- package/dist/components/GrDialog/chunks/{GrDialog-DDz_OEhk.js → GrDialog-C9Zu72jB.js} +1 -1
- package/dist/components/GrDialog/chunks/{GrDialog-DDz_OEhk.js.map → GrDialog-C9Zu72jB.js.map} +1 -1
- package/dist/components/GrDialog/index.js +1 -1
- package/dist/components/GrDialogService/chunks/{GrDialogService-Dtq0ZCN5.js → GrDialogService-DLBifO61.js} +2 -2
- package/dist/components/GrDialogService/chunks/{GrDialogService-Dtq0ZCN5.js.map → GrDialogService-DLBifO61.js.map} +1 -1
- package/dist/components/GrDialogService/index.js +1 -1
- package/dist/components/GrDrawer/chunks/{GrDrawer-CNpSMuN-.js → GrDrawer-DOcRTE8G.js} +1 -1
- package/dist/components/GrDrawer/chunks/{GrDrawer-CNpSMuN-.js.map → GrDrawer-DOcRTE8G.js.map} +1 -1
- package/dist/components/GrDrawer/index.js +1 -1
- package/dist/components/GrDropdown/chunks/{GrDropdown-cLZuZMEY.js → GrDropdown-kxwmgfSe.js} +2 -2
- package/dist/components/GrDropdown/chunks/{GrDropdown-cLZuZMEY.js.map → GrDropdown-kxwmgfSe.js.map} +1 -1
- package/dist/components/GrDropdown/index.js +2 -2
- package/dist/components/GrDropdownMenu/chunks/{GrDropdownMenu-Dxkz_ry4.js → GrDropdownMenu--VoK3VY0.js} +3 -34
- package/dist/components/GrDropdownMenu/chunks/GrDropdownMenu--VoK3VY0.js.map +1 -0
- package/dist/components/GrDropdownMenu/chunks/GrDropdownMenu-CkM3BFPL.js +34 -0
- package/dist/components/GrDropdownMenu/chunks/GrDropdownMenu-CkM3BFPL.js.map +1 -0
- package/dist/components/GrDropdownMenu/index.js +2 -1
- package/dist/components/GrEmptyState/chunks/{GrEmptyState-BbvwE-E0.js → GrEmptyState-Bz6-_ED4.js} +42 -6
- package/dist/components/GrEmptyState/chunks/GrEmptyState-Bz6-_ED4.js.map +1 -0
- package/dist/components/GrEmptyState/index.js +1 -1
- package/dist/components/GrFileUpload/chunks/{GrFileUpload-BwMR71zN.js → GrFileUpload-Bgdfnkd8.js} +5 -2
- package/dist/components/GrFileUpload/chunks/GrFileUpload-Bgdfnkd8.js.map +1 -0
- package/dist/components/GrFileUpload/index.js +1 -1
- package/dist/components/GrFormFile/chunks/{GrFormFile-Dlxx-9zi.js → GrFormFile-Ctq1isz-.js} +78 -11
- package/dist/components/GrFormFile/chunks/GrFormFile-Ctq1isz-.js.map +1 -0
- package/dist/components/GrFormFile/index.js +2 -2
- package/dist/components/GrFormFile/styles.css +1 -1
- package/dist/components/GrImageViewer/chunks/{GrImageViewer-DK-iVHHC.js → GrImageViewer-Bnql_dNP.js} +1 -1
- package/dist/components/GrImageViewer/chunks/{GrImageViewer-DK-iVHHC.js.map → GrImageViewer-Bnql_dNP.js.map} +1 -1
- package/dist/components/GrImageViewer/index.js +1 -1
- package/dist/components/GrInput/chunks/{GrInput-DV4gMWPR.js → GrInput-CoaFLpaU.js} +43 -22
- package/dist/components/GrInput/chunks/GrInput-CoaFLpaU.js.map +1 -0
- package/dist/components/GrInput/index.js +1 -1
- package/dist/components/GrInputTag/chunks/{GrInputTag-CO0YU-ok.js → GrInputTag-BzzNRBe3.js} +247 -20
- package/dist/components/GrInputTag/chunks/GrInputTag-BzzNRBe3.js.map +1 -0
- package/dist/components/GrInputTag/index.js +2 -2
- package/dist/components/GrJsonViewer/chunks/{GrJsonViewer-D7CyWzhT.js → GrJsonViewer-B6ZJ3GFH.js} +2 -2
- package/dist/components/GrJsonViewer/chunks/{GrJsonViewer-D7CyWzhT.js.map → GrJsonViewer-B6ZJ3GFH.js.map} +1 -1
- package/dist/components/GrJsonViewer/index.js +1 -1
- package/dist/components/GrKbd/chunks/{GrKbd-BNMeoaLV.js → GrKbd-D2rHDkQv.js} +42 -37
- package/dist/components/GrKbd/chunks/GrKbd-D2rHDkQv.js.map +1 -0
- package/dist/components/GrKbd/index.js +1 -1
- package/dist/components/GrModal/chunks/{GrModal-Cm0mtSXk.js → GrModal-SHb1U2qx.js} +1 -1
- package/dist/components/GrModal/chunks/{GrModal-Cm0mtSXk.js.map → GrModal-SHb1U2qx.js.map} +1 -1
- package/dist/components/GrModal/index.js +1 -1
- package/dist/components/GrNavbar/chunks/{GrNavbar-BRGuksiy.js → GrNavbar-IEIHC5Vt.js} +10 -4
- package/dist/components/GrNavbar/chunks/GrNavbar-IEIHC5Vt.js.map +1 -0
- package/dist/components/GrNavbar/index.js +2 -2
- package/dist/components/GrNumberInput/chunks/{GrNumberInput-BI6-vkcs.js → GrNumberInput-CmnUDaKi.js} +2 -22
- package/dist/components/GrNumberInput/chunks/{GrNumberInput-BI6-vkcs.js.map → GrNumberInput-CmnUDaKi.js.map} +1 -1
- package/dist/components/GrNumberInput/index.js +1 -1
- package/dist/components/GrOtpInput/chunks/GrOtpInput-B_Q-RDLw.js +419 -0
- package/dist/components/GrOtpInput/chunks/GrOtpInput-B_Q-RDLw.js.map +1 -0
- package/dist/components/GrOtpInput/index.js +3 -0
- package/dist/components/GrOtpInput/styles.css +1 -0
- package/dist/components/GrPagination/chunks/{GrPagination-BbaF5eXk.js → GrPagination-AMbn5D8I.js} +1 -1
- package/dist/components/GrPagination/chunks/{GrPagination-BbaF5eXk.js.map → GrPagination-AMbn5D8I.js.map} +1 -1
- package/dist/components/GrPagination/index.js +1 -1
- package/dist/components/GrPopover/chunks/{GrPopover-CcWvr1ZA.js → GrPopover-DjVxt8bf.js} +3 -3
- package/dist/components/GrPopover/chunks/{GrPopover-CcWvr1ZA.js.map → GrPopover-DjVxt8bf.js.map} +1 -1
- package/dist/components/GrPopover/index.js +2 -2
- package/dist/components/GrPromptDialog/chunks/{GrPromptDialog-BEL-QgwE.js → GrPromptDialog-BhbIZP1f.js} +3 -3
- package/dist/components/GrPromptDialog/chunks/{GrPromptDialog-BEL-QgwE.js.map → GrPromptDialog-BhbIZP1f.js.map} +1 -1
- package/dist/components/GrPromptDialog/index.js +1 -1
- package/dist/components/GrSelect/chunks/{GrSelect-0iI4wdR_.js → GrSelect-B-ykrHpL.js} +26 -182
- package/dist/components/GrSelect/chunks/GrSelect-B-ykrHpL.js.map +1 -0
- package/dist/components/GrSelect/index.js +2 -2
- package/dist/components/GrSelect/styles.css +1 -1
- package/dist/components/GrSidebar/chunks/GrSidebar-jVvoLGDO.js +543 -0
- package/dist/components/GrSidebar/chunks/GrSidebar-jVvoLGDO.js.map +1 -0
- package/dist/components/GrSidebar/index.js +2 -2
- package/dist/components/GrSlider/chunks/{GrSlider-CO8N9SF6.js → GrSlider-DF2Cq0rV.js} +29 -4
- package/dist/components/GrSlider/chunks/GrSlider-DF2Cq0rV.js.map +1 -0
- package/dist/components/GrSlider/index.js +2 -2
- package/dist/components/GrSortableList/chunks/{GrSortableList-NKriuGm_.js → GrSortableList-ChH9nQBv.js} +1 -1
- package/dist/components/GrSortableList/chunks/{GrSortableList-NKriuGm_.js.map → GrSortableList-ChH9nQBv.js.map} +1 -1
- package/dist/components/GrSortableList/index.js +2 -2
- package/dist/components/GrSwitch/chunks/{GrSwitch-CriHWT2A.js → GrSwitch-D7X42uIA.js} +61 -7
- package/dist/components/GrSwitch/chunks/GrSwitch-D7X42uIA.js.map +1 -0
- package/dist/components/GrSwitch/index.js +2 -2
- package/dist/components/GrTabPanels/chunks/GrTabPanels-BDt5oVdd.js +30 -0
- package/dist/components/GrTabPanels/chunks/GrTabPanels-BDt5oVdd.js.map +1 -0
- package/dist/components/GrTabPanels/chunks/GrTabPanels-BJvAflnA.js +83 -0
- package/dist/components/GrTabPanels/chunks/GrTabPanels-BJvAflnA.js.map +1 -0
- package/dist/components/GrTabPanels/index.js +2 -1
- package/dist/components/GrTable/chunks/{GrTable-CKJ-HrsN.js → GrTable-BQitSDep.js} +52 -16
- package/dist/components/GrTable/chunks/GrTable-BQitSDep.js.map +1 -0
- package/dist/components/GrTable/index.js +2 -2
- package/dist/components/GrTabs/chunks/{GrTabs-s9RzC1WX.js → GrTabs-DVC6nfWB.js} +1 -1
- package/dist/components/GrTabs/chunks/{GrTabs-s9RzC1WX.js.map → GrTabs-DVC6nfWB.js.map} +1 -1
- package/dist/components/GrTabs/index.js +2 -2
- package/dist/components/GrTabsWithPanels/chunks/GrTabsWithPanels-BYtuzouj.js +98 -0
- package/dist/components/GrTabsWithPanels/chunks/GrTabsWithPanels-BYtuzouj.js.map +1 -0
- package/dist/components/GrTabsWithPanels/index.js +3 -0
- package/dist/components/GrTextarea/chunks/{GrTextarea-Bfgc0DD2.js → GrTextarea-BFwyqcHB.js} +22 -5
- package/dist/components/GrTextarea/chunks/GrTextarea-BFwyqcHB.js.map +1 -0
- package/dist/components/GrTextarea/index.js +1 -1
- package/dist/components/GrToaster/chunks/{GrToaster-CZixNk0l.js → GrToaster-OzT1VKcp.js} +163 -32
- package/dist/components/GrToaster/chunks/GrToaster-OzT1VKcp.js.map +1 -0
- package/dist/components/GrToaster/index.js +2 -2
- package/dist/components/GrToaster/styles.css +1 -1
- package/dist/components/GrTooltip/chunks/{GrTooltip-DkMMM0uq.js → GrTooltip-BDcFycvW.js} +26 -13
- package/dist/components/GrTooltip/chunks/GrTooltip-BDcFycvW.js.map +1 -0
- package/dist/components/GrTooltip/index.js +2 -2
- package/dist/components/GrTransfer/chunks/{GrTransfer-DdfBUf35.js → GrTransfer-CV7BL5UK.js} +114 -12
- package/dist/components/GrTransfer/chunks/GrTransfer-CV7BL5UK.js.map +1 -0
- package/dist/components/GrTransfer/index.js +1 -1
- package/dist/components/GrTransfer/styles.css +1 -1
- package/dist/components/GrTree/chunks/{GrTree-6yZrncJE.js → GrTree-DpgaP8hk.js} +39 -1
- package/dist/components/GrTree/chunks/GrTree-DpgaP8hk.js.map +1 -0
- package/dist/components/GrTree/index.js +1 -1
- package/dist/components/GrTree/styles.css +1 -1
- package/dist/components/GrTreeSections/chunks/{GrTreeSections-DcmDcLwj.js → GrTreeSections-BeOj__44.js} +1 -1
- package/dist/components/GrTreeSections/chunks/{GrTreeSections-DcmDcLwj.js.map → GrTreeSections-BeOj__44.js.map} +1 -1
- package/dist/components/GrTreeSections/index.js +1 -1
- package/dist/components/GrTreeSelect/chunks/{GrTreeSelect-B6KoDYiZ.js → GrTreeSelect-BHq-T8wH.js} +113 -14
- package/dist/components/GrTreeSelect/chunks/GrTreeSelect-BHq-T8wH.js.map +1 -0
- package/dist/components/GrTreeSelect/index.js +2 -2
- package/dist/composables/useFloating.js +1 -1
- package/dist/composables/useHotkeys.js +89 -0
- package/dist/composables/useHotkeys.js.map +1 -0
- package/dist/composables/useOverlayLayer.js +1 -1
- package/dist/directives/hotkey.js +19 -46
- package/dist/directives/hotkey.js.map +1 -1
- package/dist/granular-provider-node.js +1 -1
- package/dist/granular-provider.js +1 -1
- package/dist/i18n/all.js +1 -1
- package/dist/i18n/index.js +1 -1
- package/dist/index.js +80 -71
- package/dist/theme.js +1 -1
- package/dist/tokens.js +1 -1
- package/dist/types/components/GrAutocomplete/GrAutocomplete.vue.d.ts +4 -4
- package/dist/types/components/GrAutocomplete/composables/useAutocompleteNavigation.d.ts +12 -3
- package/dist/types/components/GrAutocomplete/composables/useAutocompletePanel.d.ts +12 -2
- package/dist/types/components/GrAutocomplete/composables/useAutocompleteValues.d.ts +7 -4
- package/dist/types/components/GrAutocomplete/composables/useRemoteOptions.d.ts +4 -4
- package/dist/types/components/GrAutocomplete/grAutocompleteStyles.d.ts +15 -1
- package/dist/types/components/GrAutocomplete/index.d.ts +1 -1
- package/dist/types/components/GrBadge/GrBadge.vue.d.ts +15 -1
- package/dist/types/components/GrBadge/grBadgeStyles.d.ts +57 -0
- package/dist/types/components/GrBadge/index.d.ts +1 -1
- package/dist/types/components/GrCarousel/GrCarousel.vue.d.ts +29 -1
- package/dist/types/components/GrCarousel/composables/useCarouselSwipe.d.ts +5 -0
- package/dist/types/components/GrCarousel/grCarouselContext.d.ts +21 -0
- package/dist/types/components/GrCarousel/grCarouselStyles.d.ts +39 -9
- package/dist/types/components/GrCheckbox/GrCheckbox.vue.d.ts +13 -0
- package/dist/types/components/GrColorPicker/GrColorPicker.vue.d.ts +18 -2
- package/dist/types/components/GrColorPicker/color.d.ts +13 -1
- package/dist/types/components/GrColorPicker/colorArea.d.ts +59 -0
- package/dist/types/components/GrColorPicker/defaults.d.ts +3 -1
- package/dist/types/components/GrColorPicker/eyeDropper.d.ts +21 -0
- package/dist/types/components/GrColorPicker/grColorPickerStyles.d.ts +42 -0
- package/dist/types/components/GrCommandPalette/GrCommandPalette.vue.d.ts +10 -1
- package/dist/types/components/GrDataTable/GrDataTable.vue.d.ts +41 -1
- package/dist/types/components/GrDataTable/composables/useDataTableGridNavigation.d.ts +53 -0
- package/dist/types/components/GrDataTable/grDataTableStyles.d.ts +8 -0
- package/dist/types/components/GrDataTable/index.d.ts +1 -1
- package/dist/types/components/GrDelta/grDeltaStyles.d.ts +10 -3
- package/dist/types/components/GrEmptyState/GrEmptyState.vue.d.ts +11 -2
- package/dist/types/components/GrEmptyState/grEmptyStateStyles.d.ts +10 -0
- package/dist/types/components/GrEmptyState/index.d.ts +1 -1
- package/dist/types/components/GrFileUpload/GrFileUpload.vue.d.ts +2 -1
- package/dist/types/components/GrFormFile/GrFormFile.vue.d.ts +10 -0
- package/dist/types/components/GrInput/GrInput.vue.d.ts +15 -0
- package/dist/types/components/GrInputTag/GrInputTag.vue.d.ts +16 -0
- package/dist/types/components/GrInputTag/grInputTagStyles.d.ts +11 -0
- package/dist/types/components/GrKbd/GrKbd.vue.d.ts +14 -0
- package/dist/types/components/GrNavbar/GrNavbar.vue.d.ts +18 -0
- package/dist/types/components/GrNavbar/grNavbarStyles.d.ts +10 -1
- package/dist/types/components/GrNavbar/index.d.ts +1 -0
- package/dist/types/components/GrOtpInput/GrOtpInput.vue.d.ts +164 -0
- package/dist/types/components/GrOtpInput/config.d.ts +1 -0
- package/dist/types/components/GrOtpInput/defaults.d.ts +15 -0
- package/dist/types/components/GrOtpInput/grOtpInputStyles.d.ts +62 -0
- package/dist/types/components/GrOtpInput/index.d.ts +9 -0
- package/dist/types/components/GrOtpInput/otpValue.d.ts +71 -0
- package/dist/types/components/GrOtpInput/safelist.d.ts +7 -0
- package/dist/types/components/GrSelect/composables/useSelectPanelItems.d.ts +8 -34
- package/dist/types/components/GrSelect/composables/useSelectVirtualization.d.ts +7 -0
- package/dist/types/components/GrSelect/grSelectStyles.d.ts +1 -1
- package/dist/types/components/GrSidebar/GrSidebar.vue.d.ts +20 -0
- package/dist/types/components/GrSidebar/GrSidebarItem.vue.d.ts +39 -5
- package/dist/types/components/GrSidebar/grSidebarStyles.d.ts +32 -0
- package/dist/types/components/GrSidebar/index.d.ts +1 -1
- package/dist/types/components/GrSidebar/sidebarContext.d.ts +23 -1
- package/dist/types/components/GrSlider/GrSlider.vue.d.ts +39 -1
- package/dist/types/components/GrSlider/grSliderStyles.d.ts +1 -1
- package/dist/types/components/GrSwitch/GrSwitch.vue.d.ts +42 -4
- package/dist/types/components/GrSwitch/defaults.d.ts +2 -0
- package/dist/types/components/GrSwitch/grSwitchStyles.d.ts +129 -25
- package/dist/types/components/GrSwitch/index.d.ts +1 -1
- package/dist/types/components/GrSwitch/safelist.d.ts +4 -3
- package/dist/types/components/GrTabPanels/context.d.ts +6 -0
- package/dist/types/components/GrTable/GrTable.vue.d.ts +37 -0
- package/dist/types/components/GrTable/grTableStyles.d.ts +16 -7
- package/dist/types/components/GrTabsWithPanels/GrTabsWithPanels.vue.d.ts +77 -0
- package/dist/types/components/GrTabsWithPanels/config.d.ts +1 -0
- package/dist/types/components/GrTabsWithPanels/index.d.ts +4 -0
- package/dist/types/components/GrTextarea/GrTextarea.vue.d.ts +19 -1
- package/dist/types/components/GrToaster/GrToaster.vue.d.ts +12 -0
- package/dist/types/components/GrToaster/grToasterStyles.d.ts +26 -0
- package/dist/types/components/GrTooltip/GrTooltip.vue.d.ts +22 -0
- package/dist/types/components/GrTransfer/GrTransfer.vue.d.ts +23 -0
- package/dist/types/components/GrTreeSelect/grTreeSelectStyles.d.ts +1 -1
- package/dist/types/components/GrTreeSelect/grTreeSelectTypes.d.ts +20 -0
- package/dist/types/components/shared/hotkey.d.ts +8 -9
- package/dist/types/components/shared/optionPanel.d.ts +100 -0
- package/dist/types/components/shared/overlayListPanel.d.ts +18 -0
- package/dist/types/composables/useHotkeys.d.ts +43 -0
- package/dist/types/granular-provider/shared.d.ts +2 -0
- package/dist/types/i18n/messages/en.d.ts +32 -0
- package/dist/types/i18n/messages/es.d.ts +32 -0
- package/dist/types/i18n/messages/ru.d.ts +32 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/internal/hotkeySequence.d.ts +22 -0
- package/dist/types/internal/keyboard.d.ts +45 -0
- package/dist/web-types.json +784 -101
- package/package.json +13 -1
- package/dist/chunks/config-2ZHRsdOc.js.map +0 -1
- package/dist/chunks/config-B42iJ48O.js.map +0 -1
- package/dist/chunks/config-B5SBUa6u.js.map +0 -1
- package/dist/chunks/config-BAse0laT.js.map +0 -1
- package/dist/chunks/config-BHLMTJaR.js.map +0 -1
- package/dist/chunks/config-BXRmsn3t.js.map +0 -1
- package/dist/chunks/config-Bs1HwUcx.js.map +0 -1
- package/dist/chunks/config-CMNfZO7S.js.map +0 -1
- package/dist/chunks/config-CbEbLyDE.js.map +0 -1
- package/dist/chunks/config-CjWOTgLL.js.map +0 -1
- package/dist/chunks/config-D3HOuHDe.js.map +0 -1
- package/dist/chunks/config-DIDz_E5m.js.map +0 -1
- package/dist/chunks/config-DNDgp9bB.js.map +0 -1
- package/dist/chunks/config-Yy67uWHY.js +0 -140
- package/dist/chunks/config-Yy67uWHY.js.map +0 -1
- package/dist/chunks/config-iemgzS4x.js.map +0 -1
- package/dist/chunks/en-Bxyn5lW7.js.map +0 -1
- package/dist/chunks/es-Dtl-a7ui.js.map +0 -1
- package/dist/chunks/grBadgeStyles-DV0DrAew.js.map +0 -1
- package/dist/chunks/grSelectStyles-D9EQ-pgK.js.map +0 -1
- package/dist/chunks/grSliderStyles-kaz6VXZ3.js.map +0 -1
- package/dist/chunks/grTableStyles-DkQPMfx9.js +0 -39
- package/dist/chunks/grTableStyles-DkQPMfx9.js.map +0 -1
- package/dist/chunks/granular-provider-BOQp7N5o.js.map +0 -1
- package/dist/chunks/keyboard-DE2yhz_b.js.map +0 -1
- package/dist/chunks/overlayPanelSurface-BKeMhRx4.js.map +0 -1
- package/dist/chunks/ru-hrB4I1u_.js.map +0 -1
- package/dist/chunks/safelist-x8USecK8.js.map +0 -1
- package/dist/components/GrAutocomplete/chunks/GrAutocomplete-C-uovdv8.js.map +0 -1
- package/dist/components/GrBadge/chunks/GrBadge-DBeQXEir.js +0 -47
- package/dist/components/GrBadge/chunks/GrBadge-DBeQXEir.js.map +0 -1
- package/dist/components/GrCarousel/chunks/GrCarousel-ByuughtI.js.map +0 -1
- package/dist/components/GrCheckbox/chunks/GrCheckbox-Dp201frb.js.map +0 -1
- package/dist/components/GrColorPicker/chunks/GrColorPicker-BRM_4lyI.js.map +0 -1
- package/dist/components/GrCommandPalette/chunks/GrCommandPalette-BJHmkDQv.js.map +0 -1
- package/dist/components/GrDataTable/chunks/GrDataTable-DQxYYgQk.js.map +0 -1
- package/dist/components/GrDropdownMenu/chunks/GrDropdownMenu-Dxkz_ry4.js.map +0 -1
- package/dist/components/GrEmptyState/chunks/GrEmptyState-BbvwE-E0.js.map +0 -1
- package/dist/components/GrFileUpload/chunks/GrFileUpload-BwMR71zN.js.map +0 -1
- package/dist/components/GrFormFile/chunks/GrFormFile-Dlxx-9zi.js.map +0 -1
- package/dist/components/GrInput/chunks/GrInput-DV4gMWPR.js.map +0 -1
- package/dist/components/GrInputTag/chunks/GrInputTag-CO0YU-ok.js.map +0 -1
- package/dist/components/GrKbd/chunks/GrKbd-BNMeoaLV.js.map +0 -1
- package/dist/components/GrNavbar/chunks/GrNavbar-BRGuksiy.js.map +0 -1
- package/dist/components/GrSelect/chunks/GrSelect-0iI4wdR_.js.map +0 -1
- package/dist/components/GrSidebar/chunks/GrSidebar-DoKLlHSw.js +0 -264
- package/dist/components/GrSidebar/chunks/GrSidebar-DoKLlHSw.js.map +0 -1
- package/dist/components/GrSlider/chunks/GrSlider-CO8N9SF6.js.map +0 -1
- package/dist/components/GrSwitch/chunks/GrSwitch-CriHWT2A.js.map +0 -1
- package/dist/components/GrTabPanels/chunks/GrTabPanels-5zsbqS1v.js +0 -92
- package/dist/components/GrTabPanels/chunks/GrTabPanels-5zsbqS1v.js.map +0 -1
- package/dist/components/GrTable/chunks/GrTable-CKJ-HrsN.js.map +0 -1
- package/dist/components/GrTextarea/chunks/GrTextarea-Bfgc0DD2.js.map +0 -1
- package/dist/components/GrToaster/chunks/GrToaster-CZixNk0l.js.map +0 -1
- package/dist/components/GrTooltip/chunks/GrTooltip-DkMMM0uq.js.map +0 -1
- package/dist/components/GrTransfer/chunks/GrTransfer-DdfBUf35.js.map +0 -1
- package/dist/components/GrTree/chunks/GrTree-6yZrncJE.js.map +0 -1
- package/dist/components/GrTreeSelect/chunks/GrTreeSelect-B6KoDYiZ.js.map +0 -1
- package/dist/types/components/GrAutocomplete/composables/useAutocompleteVirtual.d.ts +0 -33
package/dist/components/GrTreeSelect/chunks/{GrTreeSelect-B6KoDYiZ.js → GrTreeSelect-BHq-T8wH.js}
RENAMED
|
@@ -7,18 +7,20 @@ import { vClickOutside } from "../../../directives/clickOutside.js";
|
|
|
7
7
|
import { t as loader_circle_default } from "../../../chunks/loader-circle-CfVLz7lb.js";
|
|
8
8
|
import { useFloating } from "../../../composables/useFloating.js";
|
|
9
9
|
import { useOverlayLayer } from "../../../composables/useOverlayLayer.js";
|
|
10
|
+
import { t as panelPopTransition } from "../../../chunks/overlayTransition-C0FDMx7Q.js";
|
|
10
11
|
import { n as useGrFormFieldContext } from "../../../chunks/context-DdNIxa1w.js";
|
|
11
12
|
import { useGrFormControl } from "../../../composables/useGrFormControl.js";
|
|
12
13
|
import { t as useFocusWithin } from "../../../chunks/useFocusWithin-BwHE0rzm.js";
|
|
13
14
|
import { t as useControlledOpen } from "../../../chunks/useControlledOpen-DV3SqLTP.js";
|
|
14
15
|
import { t as useControlAddons } from "../../../chunks/useControlAddons-asUr10Pf.js";
|
|
15
|
-
import {
|
|
16
|
+
import { d as chipSizeForBadgeScale } from "../../../chunks/grChipStyles-CA9Wj1_E.js";
|
|
17
|
+
import { t as GrChip_default } from "../../GrChip/chunks/GrChip-DoyS1Dr4.js";
|
|
16
18
|
import { t as check_default } from "../../../chunks/check-BZI24Qs4.js";
|
|
17
19
|
import { t as chevron_down_default } from "../../../chunks/chevron-down-CQS2OG_s.js";
|
|
18
20
|
import { a as controlStateTextKey, i as controlStateIconColors, n as controlStateFallbackText, r as controlStateIconClass, t as controlSignalState } from "../../../chunks/controlState-DoImKciE.js";
|
|
19
|
-
import { t as GrInput_default } from "../../GrInput/chunks/GrInput-
|
|
20
|
-
import { t as GrTree_default } from "../../GrTree/chunks/GrTree-
|
|
21
|
-
import { a as grTreeSelectStateClass, i as grTreeSelectPanelClass, o as paddingX, r as grTreeSelectClass, s as trailingZoneWidth } from "../../../chunks/config-
|
|
21
|
+
import { t as GrInput_default } from "../../GrInput/chunks/GrInput-CoaFLpaU.js";
|
|
22
|
+
import { t as GrTree_default } from "../../GrTree/chunks/GrTree-DpgaP8hk.js";
|
|
23
|
+
import { a as grTreeSelectStateClass, i as grTreeSelectPanelClass, o as paddingX, r as grTreeSelectClass, s as trailingZoneWidth } from "../../../chunks/config-CvtqB4ki.js";
|
|
22
24
|
import { Fragment, Teleport, Transition, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, mergeProps, nextTick, normalizeClass, normalizeStyle, openBlock, ref, renderList, renderSlot, resolveDynamicComponent, toDisplayString, unref, useId, useSlots, vShow, watch, withCtx, withDirectives, withModifiers } from "vue";
|
|
23
25
|
//#region src/components/GrTreeSelect/GrTreeSelect.vue?vue&type=script&setup=true&lang.ts
|
|
24
26
|
var _hoisted_1 = ["name", "value"];
|
|
@@ -43,18 +45,19 @@ var _hoisted_6 = {
|
|
|
43
45
|
"data-gr-tree-select-chevron": "",
|
|
44
46
|
class: "absolute top-1/2 -translate-y-1/2 right-3 text-[var(--gr-muted-fg)] pointer-events-none"
|
|
45
47
|
};
|
|
46
|
-
var _hoisted_7 = {
|
|
48
|
+
var _hoisted_7 = { class: "truncate" };
|
|
49
|
+
var _hoisted_8 = {
|
|
47
50
|
key: 0,
|
|
48
51
|
class: "p-2 border-b border-[var(--gr-brd)]"
|
|
49
52
|
};
|
|
50
|
-
var
|
|
51
|
-
var
|
|
53
|
+
var _hoisted_9 = { class: "flex items-center gap-2 min-w-0" };
|
|
54
|
+
var _hoisted_10 = {
|
|
52
55
|
key: 0,
|
|
53
56
|
"data-gr-tree-select-check": "",
|
|
54
57
|
class: "inline-block h-4 w-4 shrink-0",
|
|
55
58
|
"aria-hidden": "true"
|
|
56
59
|
};
|
|
57
|
-
var
|
|
60
|
+
var _hoisted_11 = { class: "truncate" };
|
|
58
61
|
//#endregion
|
|
59
62
|
//#region src/components/GrTreeSelect/GrTreeSelect.vue
|
|
60
63
|
var GrTreeSelect_default = /* @__PURE__ */ defineComponent({
|
|
@@ -104,6 +107,18 @@ var GrTreeSelect_default = /* @__PURE__ */ defineComponent({
|
|
|
104
107
|
type: Boolean,
|
|
105
108
|
default: false
|
|
106
109
|
},
|
|
110
|
+
tags: {
|
|
111
|
+
type: Boolean,
|
|
112
|
+
default: false
|
|
113
|
+
},
|
|
114
|
+
maxTagCount: { default: void 0 },
|
|
115
|
+
tagTone: { default: "neutral" },
|
|
116
|
+
tagDark: {
|
|
117
|
+
type: Boolean,
|
|
118
|
+
default: false
|
|
119
|
+
},
|
|
120
|
+
tagSize: { default: "sm" },
|
|
121
|
+
tagRadius: { default: "round" },
|
|
107
122
|
clearable: {
|
|
108
123
|
type: Boolean,
|
|
109
124
|
default: false
|
|
@@ -273,6 +288,31 @@ var GrTreeSelect_default = /* @__PURE__ */ defineComponent({
|
|
|
273
288
|
const labels = selectedLabels.value;
|
|
274
289
|
return labels.length ? [labels[0]] : void 0;
|
|
275
290
|
});
|
|
291
|
+
/**
|
|
292
|
+
* Чипы живут РЯДОМ с триггером, а не внутри него: `role="combobox"` объявляет
|
|
293
|
+
* потомков презентационными, и крестик внутри был бы недостижим с клавиатуры
|
|
294
|
+
* (axe: `nested-interactive`). Тот же приём — у `GrSelect`.
|
|
295
|
+
*/
|
|
296
|
+
const showTags = computed(() => props.multiple && props.tags);
|
|
297
|
+
/** Полоса чипов рисуется только когда есть что рисовать: пустая съела бы плейсхолдер. */
|
|
298
|
+
const hasTags = computed(() => showTags.value && selectedKeys.value.length > 0);
|
|
299
|
+
const visibleTagKeys = computed(() => {
|
|
300
|
+
const limit = props.maxTagCount;
|
|
301
|
+
if (limit === void 0 || limit < 0) return selectedKeys.value;
|
|
302
|
+
return selectedKeys.value.slice(0, limit);
|
|
303
|
+
});
|
|
304
|
+
const hiddenTagCount = computed(() => selectedKeys.value.length - visibleTagKeys.value.length);
|
|
305
|
+
/**
|
|
306
|
+
* Проп `tagSize` объявлен по шкале бейджа и остаётся публичным контрактом:
|
|
307
|
+
* ступени чипа сдвинуты, и перевод держит кегль тем же.
|
|
308
|
+
*/
|
|
309
|
+
const chipSize = computed(() => chipSizeForBadgeScale(props.tagSize));
|
|
310
|
+
function tagLabel(key) {
|
|
311
|
+
return labelByKey.value.get(key) ?? String(key);
|
|
312
|
+
}
|
|
313
|
+
function tagRemoveLabel(key) {
|
|
314
|
+
return t("gr.treeSelect.removeTag", "Remove {label}", { label: tagLabel(key) });
|
|
315
|
+
}
|
|
276
316
|
const displayValue = computed(() => {
|
|
277
317
|
const labels = selectedLabels.value;
|
|
278
318
|
if (labels.length === 0) return "";
|
|
@@ -431,6 +471,20 @@ var GrTreeSelect_default = /* @__PURE__ */ defineComponent({
|
|
|
431
471
|
if (isDisabled.value || isReadonly.value) return;
|
|
432
472
|
emitModel([...keys]);
|
|
433
473
|
}
|
|
474
|
+
/**
|
|
475
|
+
* Снятие чипа в режиме чекбоксов идёт через дерево, а не через фильтрацию
|
|
476
|
+
* ключей: каскад по родителям и детям считает `GrTree`, и убрав ключ мимо него,
|
|
477
|
+
* мы получили бы отмеченного родителя без детей. Дерево смонтировано и при
|
|
478
|
+
* закрытой панели (она под `v-show`), так что звать его можно всегда.
|
|
479
|
+
*/
|
|
480
|
+
function removeTag(key) {
|
|
481
|
+
if (isDisabled.value || isReadonly.value) return;
|
|
482
|
+
if (checkboxMode.value) {
|
|
483
|
+
treeRef.value?.setChecked(key, false);
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
emitModel(selectedKeys.value.filter((k) => k !== key));
|
|
487
|
+
}
|
|
434
488
|
function onNodeClick(data, node) {
|
|
435
489
|
emit("nodeClick", data, node);
|
|
436
490
|
if (isDisabled.value) return;
|
|
@@ -498,7 +552,7 @@ var GrTreeSelect_default = /* @__PURE__ */ defineComponent({
|
|
|
498
552
|
"aria-required": unref(isRequired) ? "true" : void 0,
|
|
499
553
|
"aria-describedby": describedBy.value,
|
|
500
554
|
"aria-label": __props.ariaLabel,
|
|
501
|
-
class: normalizeClass(["w-full rounded-[var(--gr-radius-control)] border placeholder:text-[var(--gr-muted-fg)] transition-colors duration-[var(--gr-duration-fast)] focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--gr-ring)]", [className.value, _ctx.$slots.value ? "text-transparent placeholder:text-transparent" : ""]]),
|
|
555
|
+
class: normalizeClass(["w-full rounded-[var(--gr-radius-control)] border placeholder:text-[var(--gr-muted-fg)] transition-colors duration-[var(--gr-duration-fast)] focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--gr-ring)]", [className.value, _ctx.$slots.value || hasTags.value ? "text-transparent placeholder:text-transparent" : ""]]),
|
|
502
556
|
style: normalizeStyle(unref(triggerStyle)),
|
|
503
557
|
onPointerdown: onTriggerPointerDown,
|
|
504
558
|
onClick: toggleDropdown,
|
|
@@ -541,8 +595,53 @@ var GrTreeSelect_default = /* @__PURE__ */ defineComponent({
|
|
|
541
595
|
style: normalizeStyle(unref(suffixStyle)),
|
|
542
596
|
"aria-hidden": "true"
|
|
543
597
|
}, [renderSlot(_ctx.$slots, "suffix")], 6)) : createCommentVNode("", true),
|
|
544
|
-
|
|
598
|
+
hasTags.value ? (openBlock(), createElementBlock("div", {
|
|
545
599
|
key: 6,
|
|
600
|
+
"data-gr-tree-select-tags": "",
|
|
601
|
+
class: "absolute inset-y-0 left-3 right-9 flex flex-wrap items-center gap-1 py-1.5 pointer-events-none",
|
|
602
|
+
style: normalizeStyle(valueOverlayStyle.value)
|
|
603
|
+
}, [(openBlock(true), createElementBlock(Fragment, null, renderList(visibleTagKeys.value, (key) => {
|
|
604
|
+
return openBlock(), createBlock(GrChip_default, {
|
|
605
|
+
key: `tag-${String(key)}`,
|
|
606
|
+
"data-gr-tree-select-tag": "",
|
|
607
|
+
class: "pointer-events-auto",
|
|
608
|
+
tone: __props.tagTone,
|
|
609
|
+
dark: __props.tagDark,
|
|
610
|
+
size: chipSize.value,
|
|
611
|
+
radius: __props.tagRadius,
|
|
612
|
+
closable: !unref(isDisabled) && !unref(isReadonly),
|
|
613
|
+
"remove-label": tagRemoveLabel(key),
|
|
614
|
+
onRemove: ($event) => removeTag(key)
|
|
615
|
+
}, {
|
|
616
|
+
default: withCtx(() => [createElementVNode("span", _hoisted_7, toDisplayString(tagLabel(key)), 1)]),
|
|
617
|
+
_: 2
|
|
618
|
+
}, 1032, [
|
|
619
|
+
"tone",
|
|
620
|
+
"dark",
|
|
621
|
+
"size",
|
|
622
|
+
"radius",
|
|
623
|
+
"closable",
|
|
624
|
+
"remove-label",
|
|
625
|
+
"onRemove"
|
|
626
|
+
]);
|
|
627
|
+
}), 128)), hiddenTagCount.value > 0 ? (openBlock(), createBlock(GrChip_default, {
|
|
628
|
+
key: 0,
|
|
629
|
+
"data-gr-tree-select-tag-rest": "",
|
|
630
|
+
tone: __props.tagTone,
|
|
631
|
+
dark: __props.tagDark,
|
|
632
|
+
size: chipSize.value,
|
|
633
|
+
radius: __props.tagRadius
|
|
634
|
+
}, {
|
|
635
|
+
default: withCtx(() => [createTextVNode(" +" + toDisplayString(hiddenTagCount.value), 1)]),
|
|
636
|
+
_: 1
|
|
637
|
+
}, 8, [
|
|
638
|
+
"tone",
|
|
639
|
+
"dark",
|
|
640
|
+
"size",
|
|
641
|
+
"radius"
|
|
642
|
+
])) : createCommentVNode("", true)], 4)) : createCommentVNode("", true),
|
|
643
|
+
_ctx.$slots.value ? (openBlock(), createElementBlock("div", {
|
|
644
|
+
key: 7,
|
|
546
645
|
class: "absolute inset-y-0 left-3 right-9 flex items-center pointer-events-none",
|
|
547
646
|
style: normalizeStyle(valueOverlayStyle.value)
|
|
548
647
|
}, [renderSlot(_ctx.$slots, "value", {
|
|
@@ -572,7 +671,7 @@ var GrTreeSelect_default = /* @__PURE__ */ defineComponent({
|
|
|
572
671
|
"data-gr-overlay-root": "",
|
|
573
672
|
style: unref(floatingStyle),
|
|
574
673
|
onKeydown: onPanelKeydown
|
|
575
|
-
}), [createElementVNode("div", { class: normalizeClass(panelClasses.value) }, [__props.filterable ? (openBlock(), createElementBlock("div",
|
|
674
|
+
}), [createElementVNode("div", { class: normalizeClass(panelClasses.value) }, [__props.filterable ? (openBlock(), createElementBlock("div", _hoisted_8, [createVNode(GrInput_default, {
|
|
576
675
|
ref_key: "filterInputRef",
|
|
577
676
|
ref: filterInputRef,
|
|
578
677
|
modelValue: filterValue.value,
|
|
@@ -589,7 +688,7 @@ var GrTreeSelect_default = /* @__PURE__ */ defineComponent({
|
|
|
589
688
|
"inputmode",
|
|
590
689
|
"placeholder"
|
|
591
690
|
])])) : createCommentVNode("", true), createElementVNode("div", {
|
|
592
|
-
class: normalizeClass(["p-1", __props.virtual ? "" : "overflow-auto"]),
|
|
691
|
+
class: normalizeClass(["p-1 min-h-0", __props.virtual ? "" : "overflow-auto"]),
|
|
593
692
|
style: normalizeStyle(__props.virtual ? void 0 : { maxHeight: `${__props.dropdownMaxHeight}px` })
|
|
594
693
|
}, [__props.loading ? (openBlock(), createElementBlock("div", {
|
|
595
694
|
key: 0,
|
|
@@ -626,10 +725,10 @@ var GrTreeSelect_default = /* @__PURE__ */ defineComponent({
|
|
|
626
725
|
node,
|
|
627
726
|
data,
|
|
628
727
|
selected: selectedKeySet.value.has(node.key)
|
|
629
|
-
}, () => [createElementVNode("div",
|
|
728
|
+
}, () => [createElementVNode("div", _hoisted_9, [!checkboxMode.value ? (openBlock(), createElementBlock("span", _hoisted_10, [selectedKeySet.value.has(node.key) ? (openBlock(), createBlock(unref(check_default), {
|
|
630
729
|
key: 0,
|
|
631
730
|
class: "block h-4 w-4 text-[var(--gr-primary-text)]"
|
|
632
|
-
})) : createCommentVNode("", true)])) : createCommentVNode("", true), createElementVNode("span",
|
|
731
|
+
})) : createCommentVNode("", true)])) : createCommentVNode("", true), createElementVNode("span", _hoisted_11, toDisplayString(node.label), 1)])])]),
|
|
633
732
|
_: 3
|
|
634
733
|
}, 8, [
|
|
635
734
|
"size",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GrTreeSelect-BHq-T8wH.js","names":["$slots"],"sources":["../../../../src/components/GrTreeSelect/GrTreeSelect.vue","../../../../src/components/GrTreeSelect/GrTreeSelect.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"T extends Record<string, any> = any\">\nimport { computed, nextTick, ref, useId, useSlots, watch } from 'vue'\n\nimport { usePortalTarget } from '../../composables/usePortalTarget'\n\nimport { vClickOutside } from '../../directives'\nimport { useFloating } from '../../composables/useFloating'\nimport { useOverlayLayer } from '../../composables/useOverlayLayer'\nimport { useControlAddons } from '../../composables/internal/useControlAddons'\nimport { useControlledOpen } from '../../composables/internal/useControlledOpen'\nimport { useGrComponentSize, useGrThemeAttrs } from '../GrConfigProvider/context'\nimport { useGrFormControl } from '../../composables/useGrFormControl'\nimport { useFocusWithin } from '../../composables/internal/useFocusWithin'\nimport { useGrFormFieldContext } from '../GrFormField/context'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport {\n controlSignalState,\n controlStateFallbackText,\n controlStateIconClass,\n controlStateIconColors,\n controlStateTextKey,\n} from '../shared/controlState'\nimport GrChip from '../GrChip/GrChip.vue'\nimport { chipSizeForBadgeScale } from '../GrChip/grChipStyles'\nimport GrInput from '../GrInput/GrInput.vue'\nimport GrTree, {\n type GrTreeInstance,\n type GrTreeKey,\n type GrTreeNode,\n} from '../GrTree'\nimport type { GrInputSize } from '../GrInput/GrInput.vue'\nimport { panelPopTransition } from '../shared/overlayTransition'\nimport type { GrTreeSelectModelValue, GrTreeSelectProps } from './grTreeSelectTypes'\nimport { grTreeSelectClass, grTreeSelectPanelClass, grTreeSelectStateClass, paddingX, trailingZoneWidth } from './grTreeSelectStyles'\n\nimport IconCheck from '~icons/lucide/check'\nimport IconChevronDown from '~icons/lucide/chevron-down'\nimport IconCheckCircle from '~icons/lucide/check-circle'\nimport IconAlertTriangle from '~icons/lucide/alert-triangle'\nimport IconLoaderCircle from '~icons/lucide/loader-circle'\nimport IconX from '~icons/lucide/x'\n\nexport interface GrTreeSelectEmits<T extends Record<string, any> = any> {\n (e: 'update:modelValue', value: GrTreeSelectModelValue): void\n (e: 'change', value: GrTreeSelectModelValue): void\n /** Панель открылась/закрылась (`v-model:open`). */\n (e: 'update:open', value: boolean): void\n (e: 'clear'): void\n (e: 'nodeClick', data: T, node: GrTreeNode<T>): void\n (e: 'focus', event: FocusEvent): void\n (e: 'blur', event: FocusEvent): void\n}\n\nconst props = withDefaults(\n defineProps<GrTreeSelectProps<T>>(),\n {\n props: () => ({\n children: 'children',\n label: 'label',\n }),\n nodeKey: 'id' as any,\n defaultExpandedKeys: () => [],\n disabled: false,\n placeholder: undefined,\n size: undefined,\n loading: false,\n invalid: false,\n readonly: false,\n required: false,\n ariaLabel: undefined,\n state: 'default',\n multiple: false,\n tags: false,\n maxTagCount: undefined,\n tagTone: 'neutral',\n tagDark: false,\n tagSize: 'sm',\n tagRadius: 'round',\n showCheckbox: false,\n checkStrictly: false,\n clearable: false,\n open: undefined,\n name: undefined,\n valueDisplay: 'label',\n filterable: false,\n filterPlaceholder: undefined,\n filterInputmode: undefined,\n filterNodeMethod: undefined,\n closeOnSelect: undefined,\n dropdownMaxHeight: 320,\n virtual: false,\n prefixMinWidth: undefined,\n prefixMaxWidth: undefined,\n suffixMinWidth: undefined,\n suffixMaxWidth: undefined,\n prefixFixed: false,\n suffixFixed: false,\n },\n)\n\nconst { t } = useGranularityTranslations()\n\nconst emit = defineEmits<GrTreeSelectEmits<T>>()\n\ndefineSlots<{\n /** Рендер значения внутри триггера (вместо дефолтного текста). */\n value?: (props: { value: GrTreeSelectModelValue, labels: string[], displayValue: string, pathLabels?: string[] }) => any\n /** Рендер строки дерева. */\n node?: (props: { node: GrTreeNode<T>, data: T, selected: boolean }) => any\n /** Содержимое пустого состояния (когда нет данных). */\n empty?: () => any\n /** Содержимое панели, пока данные едут. */\n loading?: () => any\n /** Аддон слева от значения: иконка, код валюты, метка. */\n prefix?: () => any\n /** Аддон справа от значения, перед крестиком и шевроном. */\n suffix?: () => any\n}>()\n\nconst rootEl = ref<HTMLElement | null>(null)\nconst triggerEl = ref<HTMLInputElement | null>(null)\nconst treeId = `gr-tree-select-tree-${useId()}`\n\n// Контекст `GrFormField` + общий контракт форм-контрола.\nconst field = useGrFormFieldContext()\nconst fieldId = computed(() => field?.id.value)\nconst stateTextId = useId()\nconst {\n disabled: isDisabled,\n invalid: isInvalid,\n required: isRequired,\n readonly: isReadonly,\n} = useGrFormControl(() => props)\n\n/**\n * Небуквенный признак состояния: иконка для глаз, скрытая подпись для\n * скринридера. Разбор — `shared/controlState`. Встаёт левее крестика и\n * шеврона: правый край триггера занят одним из них всегда.\n */\nconst signalState = computed(() => controlSignalState(props.state, isInvalid.value))\nconst stateIcon = computed(() => (signalState.value === 'success' ? IconCheckCircle : IconAlertTriangle))\nconst stateIconClass = computed(() => (signalState.value\n ? `${controlStateIconClass} ${controlStateIconColors[signalState.value]}`\n : ''))\nconst stateText = computed(() => (signalState.value\n ? t(controlStateTextKey[signalState.value], controlStateFallbackText[signalState.value])\n : ''))\n\nconst describedBy = computed(() =>\n [field?.describedById.value, signalState.value ? stateTextId : undefined]\n .filter(Boolean)\n .join(' ') || undefined,\n)\n\nfunction focus(): void {\n triggerEl.value?.focus()\n}\n\nfunction blur(): void {\n triggerEl.value?.blur()\n}\n\ndefineExpose({ focus, blur })\nconst filterInputRef = ref<InstanceType<typeof GrInput> | null>(null)\nconst treeRef = ref<GrTreeInstance | null>(null)\nconst panelEl = ref<HTMLElement | null>(null)\n\n// Панель телепортирована в `body`, то есть лежит вне корня, но для пользователя\n// она часть контрола: без неё уход фокуса в панель читался бы как `blur`.\nconst { onFocusIn, onFocusOut } = useFocusWithin(rootEl, {\n enter: event => emit('focus', event),\n leave: event => emit('blur', event),\n containers: () => [panelEl.value],\n})\n\nconst clickOutsideExclude = [() => panelEl.value]\n\nlet hadPointerDownOnTrigger = false\n\n// Имя `open` сохранено: читатели работают с computed-Ref.\nconst { open, setOpen: setOpenState } = useControlledOpen(\n () => props.open,\n next => emit('update:open', next),\n)\nconst filterValue = ref('')\n\nconst { floatingStyle } = useFloating(rootEl, panelEl, open, {\n placement: 'bottom-start',\n matchWidth: true,\n zIndexVar: '--gr-z-dropdown',\n})\n\nconst closeOnSelectResolved = computed(() => {\n return props.closeOnSelect ?? !props.multiple\n})\n\nfunction getChildrenKey() {\n return props.props.children ?? 'children'\n}\n\nfunction getLabelKey() {\n return props.props.label ?? 'label'\n}\n\nfunction nodeLabel(data: T): string {\n const key = getLabelKey() as keyof T\n const v = data[key]\n return v == null ? '' : String(v)\n}\n\nfunction nodeChildren(data: T): T[] {\n const key = getChildrenKey() as keyof T\n const v = data[key]\n return Array.isArray(v) ? (v as any) : []\n}\n\nfunction nodeKeyOf(data: T, index: number, parentKey: GrTreeKey | undefined): GrTreeKey {\n const keyName = props.nodeKey as keyof T\n const v = data[keyName]\n if (v != null)\n return v as GrTreeKey\n\n return parentKey == null ? index : `${String(parentKey)}:${index}`\n}\n\nconst labelByKey = computed(() => {\n const map = new Map<GrTreeKey, string>()\n\n const walk = (items: T[], parentKey: GrTreeKey | undefined) => {\n for (let i = 0; i < items.length; i++) {\n const item = items[i]\n const key = nodeKeyOf(item, i, parentKey)\n map.set(key, nodeLabel(item))\n walk(nodeChildren(item), key)\n }\n }\n\n walk(props.data ?? [], undefined)\n return map\n})\n\nconst pathLabelsByKey = computed(() => {\n const map = new Map<GrTreeKey, string[]>()\n\n const walk = (items: T[], parentKey: GrTreeKey | undefined, parentPath: string[]) => {\n for (let i = 0; i < items.length; i++) {\n const item = items[i]\n const key = nodeKeyOf(item, i, parentKey)\n const label = nodeLabel(item)\n const path = [...parentPath, label]\n map.set(key, path)\n walk(nodeChildren(item), key, path)\n }\n }\n\n walk(props.data ?? [], undefined, [])\n return map\n})\n\nconst selectedKeys = computed<GrTreeKey[]>(() => {\n if (props.multiple) {\n return Array.isArray(props.modelValue) ? props.modelValue : []\n }\n\n const v = props.modelValue\n if (v == null || Array.isArray(v))\n return []\n return [v]\n})\n\nconst selectedKeySet = computed(() => new Set(selectedKeys.value))\n\nconst selectedLabels = computed(() => {\n const map = labelByKey.value\n return selectedKeys.value.map(k => map.get(k) ?? String(k))\n})\n\nconst selectedPathLabels = computed<string[] | undefined>(() => {\n if (props.multiple)\n return undefined\n\n const key = selectedKeys.value[0]\n if (key == null)\n return undefined\n\n const path = pathLabelsByKey.value.get(key)\n if (path?.length)\n return path\n\n const labels = selectedLabels.value\n return labels.length ? [labels[0]] : undefined\n})\n\n/**\n * Чипы живут РЯДОМ с триггером, а не внутри него: `role=\"combobox\"` объявляет\n * потомков презентационными, и крестик внутри был бы недостижим с клавиатуры\n * (axe: `nested-interactive`). Тот же приём — у `GrSelect`.\n */\nconst showTags = computed(() => props.multiple && props.tags)\n\n/** Полоса чипов рисуется только когда есть что рисовать: пустая съела бы плейсхолдер. */\nconst hasTags = computed(() => showTags.value && selectedKeys.value.length > 0)\n\nconst visibleTagKeys = computed(() => {\n const limit = props.maxTagCount\n if (limit === undefined || limit < 0)\n return selectedKeys.value\n\n return selectedKeys.value.slice(0, limit)\n})\n\nconst hiddenTagCount = computed(() => selectedKeys.value.length - visibleTagKeys.value.length)\n\n/**\n * Проп `tagSize` объявлен по шкале бейджа и остаётся публичным контрактом:\n * ступени чипа сдвинуты, и перевод держит кегль тем же.\n */\nconst chipSize = computed(() => chipSizeForBadgeScale(props.tagSize))\n\nfunction tagLabel(key: GrTreeKey): string {\n return labelByKey.value.get(key) ?? String(key)\n}\n\nfunction tagRemoveLabel(key: GrTreeKey): string {\n return t('gr.treeSelect.removeTag', 'Remove {label}', { label: tagLabel(key) })\n}\n\nconst displayValue = computed(() => {\n const labels = selectedLabels.value\n if (labels.length === 0)\n return ''\n\n if (!props.multiple) {\n if (props.valueDisplay === 'path') {\n const path = selectedPathLabels.value\n if (path?.length)\n return path.join(' / ')\n }\n return labels[0]\n }\n\n if (labels.length === 1)\n return labels[0]\n return `${labels[0]} +${labels.length - 1}`\n})\n\nconst hasSelection = computed(() => selectedKeys.value.length > 0)\n\n/** Дерево рендерится только когда есть что показать — ссылаться иначе не на что. */\nconst hasTree = computed(() => !props.loading && (props.data?.length ?? 0) > 0)\n\nconst resolvedFilterPlaceholder = computed(() => {\n return props.filterPlaceholder ?? t('gr.treeSelect.filterPlaceholder', 'Search…')\n})\n\nconst resolvedSize = useGrComponentSize(() => props.size, { component: 'GrTreeSelect' })\n\nconst className = computed(() => {\n return grTreeSelectClass({\n size: resolvedSize.value,\n state: props.state,\n invalid: isInvalid.value,\n disabled: isDisabled.value,\n })\n})\n\nconst panelClasses = computed(() => {\n return grTreeSelectPanelClass\n})\n\nconst ADDON_MIN_WIDTH_BY_SIZE: Record<GrInputSize, string> = {\n xs: '2rem',\n sm: '2.25rem',\n md: '2.5rem',\n lg: '3rem',\n}\n\nconst slots = useSlots()\n\nconst {\n hasPrefix,\n hasSuffix,\n prefixEl,\n suffixEl,\n prefixStyle,\n suffixStyle,\n fieldPadding: triggerStyle,\n} = useControlAddons(() => props, {\n defaultMinWidth: () => ADDON_MIN_WIDTH_BY_SIZE[resolvedSize.value],\n paddingX: () => paddingX[resolvedSize.value],\n // Место под крестик и шеврон уже отдано классом `pr-9`, но инлайн-паддинг\n // перекрывает класс целиком — с суффиксом эту зону приходится вернуть числом.\n trailingReserve: () => (slots.suffix ? trailingZoneWidth : '0px'),\n})\n\n// Слот `value` рисуется поверх поля и обязан жить в тех же границах, что и\n// текст под ним. Без аддонов границы задаёт класс — стиль остаётся пустым.\nconst valueOverlayStyle = computed(() => ({\n left: hasPrefix.value ? triggerStyle.value.paddingLeft : undefined,\n right: hasSuffix.value ? triggerStyle.value.paddingRight : undefined,\n}))\n\nfunction setOpen(next: boolean) {\n if (isDisabled.value || isReadonly.value)\n return\n\n setOpenState(next)\n}\n\nfunction onClickOutside(): void {\n setOpen(false)\n}\n\nfunction openDropdown(): void {\n setOpen(true)\n}\n\n/**\n * Стек слоёв возвращает фокус на триггер сразу после закрытия, а у триггера\n * открытие висит на `focus`. Без флага `Escape` из дерева закрывал бы панель и\n * тем же движением открывал её заново.\n */\nlet suppressFocusOpen = false\n\nfunction closeDropdown(): void {\n suppressFocusOpen = true\n setOpen(false)\n setTimeout(() => {\n suppressFocusOpen = false\n }, 0)\n}\n\nfunction toggleDropdown(): void {\n setOpen(!open.value)\n}\n\n// Клик по триггеру сам переключает панель через `@click`; флаг гасит открытие\n// по приходящему следом `focus`, иначе один клик открыл бы и тут же закрыл.\nfunction onTriggerPointerDown(): void {\n hadPointerDownOnTrigger = true\n setTimeout(() => {\n hadPointerDownOnTrigger = false\n }, 0)\n}\n\nfunction onTriggerFocus(): void {\n if (hadPointerDownOnTrigger || suppressFocusOpen)\n return\n openDropdown()\n}\n\n// Возврат фокуса на триггер — из контракта слоя, а не руками через `nextTick`.\nuseOverlayLayer(open, closeDropdown, { root: panelEl })\n\nwatch(\n open,\n async (isOpen) => {\n if (!isOpen) {\n if (filterValue.value.trim().length > 0)\n filterValue.value = ''\n return\n }\n\n // Подсветка дерева идёт за значением: панель могли открыть после того, как\n // значение сменили снаружи.\n if (!props.multiple) {\n const v = props.modelValue\n if (v != null && !Array.isArray(v))\n treeRef.value?.setCurrentKey(v)\n }\n\n if (props.filterable) {\n await nextTick()\n filterInputRef.value?.focus()\n }\n },\n { immediate: true },\n)\n\nwatch(\n () => props.modelValue,\n (v) => {\n if (props.multiple)\n return\n if (v == null || Array.isArray(v)) {\n treeRef.value?.setCurrentKey(undefined)\n return\n }\n treeRef.value?.setCurrentKey(v)\n },\n)\n\nwatch(\n filterValue,\n (v) => {\n treeRef.value?.filter(v)\n },\n)\n\nfunction emitModel(next: GrTreeSelectModelValue) {\n emit('update:modelValue', next)\n emit('change', next)\n}\n\nfunction clear(): void {\n if (isDisabled.value || isReadonly.value)\n return\n\n const next: GrTreeSelectModelValue = props.multiple ? [] : null\n emitModel(next)\n emit('clear')\n if (!props.multiple)\n treeRef.value?.setCurrentKey(undefined)\n}\n\n/**\n * Отдаёт клавиатуру дереву. Панель под `v-show`, поэтому дерево уже в DOM, но\n * скрытый элемент сфокусировать нельзя — сначала открытие, потом кадр, потом\n * фокус. Дальше работают клавиши `GrTree`, а `Escape` возвращает фокус на\n * триггер силами общего стека слоёв.\n */\nasync function focusTree(): Promise<boolean> {\n if (!open.value)\n return false\n\n await nextTick()\n return treeRef.value?.focus() ?? false\n}\n\nfunction onTriggerKeydown(e: KeyboardEvent): void {\n if (isDisabled.value)\n return\n\n if (e.key === 'Escape') {\n e.preventDefault()\n closeDropdown()\n return\n }\n\n if (e.key === 'ArrowDown' || e.key === 'ArrowUp' || e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n openDropdown()\n\n // При `filterable` фокус уходит в поле поиска (см. watch на `open`), и\n // дальше в дерево ведёт стрелка уже оттуда.\n if (!props.filterable)\n void focusTree()\n }\n}\n\n/** Стрелка из поля поиска — единственный путь из фильтра в дерево. */\nfunction onFilterKeydown(e: KeyboardEvent): void {\n if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp')\n return\n\n e.preventDefault()\n void focusTree()\n}\n\n/** `Tab` уводит из панели — оставлять её открытой за спиной незачем. */\nfunction onPanelKeydown(e: KeyboardEvent): void {\n if (e.key === 'Tab')\n closeDropdown()\n}\n\n// Чекбоксы осмысленны только в множественном выборе: одиночный уже подсвечен\n// текущим узлом.\nconst checkboxMode = computed(() => props.multiple && props.showCheckbox)\n\n// В режиме чекбоксов каскад по родителям и детям считает `GrTree`, а не копия\n// его логики здесь: значение приходит обратно одним `update:checkedKeys`.\nfunction onCheckedKeys(keys: GrTreeKey[]): void {\n if (isDisabled.value || isReadonly.value)\n return\n\n emitModel([...keys])\n}\n\n/**\n * Снятие чипа в режиме чекбоксов идёт через дерево, а не через фильтрацию\n * ключей: каскад по родителям и детям считает `GrTree`, и убрав ключ мимо него,\n * мы получили бы отмеченного родителя без детей. Дерево смонтировано и при\n * закрытой панели (она под `v-show`), так что звать его можно всегда.\n */\nfunction removeTag(key: GrTreeKey): void {\n if (isDisabled.value || isReadonly.value)\n return\n\n if (checkboxMode.value) {\n treeRef.value?.setChecked(key, false)\n return\n }\n\n emitModel(selectedKeys.value.filter(k => k !== key))\n}\n\nfunction onNodeClick(data: T, node: GrTreeNode<T>): void {\n emit('nodeClick', data, node)\n\n if (isDisabled.value)\n return\n\n if (checkboxMode.value) {\n // Клик по строке — тот же переключатель отметки, что и сам чекбокс;\n // значение придёт через `update:checkedKeys`, поэтому здесь не эмитим.\n treeRef.value?.setChecked(node.key, !selectedKeySet.value.has(node.key))\n return\n }\n\n if (props.multiple) {\n const next = new Set(selectedKeySet.value)\n if (next.has(node.key))\n next.delete(node.key)\n else\n next.add(node.key)\n emitModel([...next])\n\n if (closeOnSelectResolved.value) {\n closeDropdown()\n }\n return\n }\n\n emitModel(node.key)\n if (closeOnSelectResolved.value) {\n closeDropdown()\n }\n}\n\n// Телепорт включается только ПОСЛЕ монтирования: иначе первый клиентский\n// рендер не совпадает с серверным и ломается гидрация (см. композабл).\nconst { target: portalTarget, enabled: teleportEnabled } = usePortalTarget()\n\n// Тема поддерева на телепортированную панель: в DOM она уезжает в `body`, то\n// есть вне обёртки провайдера, и `data-theme` с неё не наследуется. В дереве\n// компонентов панель остаётся внутри — `inject` доходит, и тему она ставит себе\n// сама.\nconst themeAttrs = useGrThemeAttrs()\n</script>\n\n<template>\n <div\n ref=\"rootEl\"\n v-click-outside=\"{ handler: onClickOutside, enabled: open, exclude: clickOutsideExclude }\"\n data-gr-tree-select\n class=\"relative\"\n @focusin=\"onFocusIn\"\n @focusout=\"onFocusOut\"\n >\n <!-- Нативная форма: hidden на каждый выбранный ключ. -->\n <template v-if=\"name\">\n <input\n v-for=\"key in selectedKeys\"\n :key=\"`hidden-${String(key)}`\"\n type=\"hidden\"\n :name=\"name\"\n :value=\"String(key)\"\n >\n </template>\n <div class=\"relative\">\n <div\n v-if=\"hasPrefix\"\n ref=\"prefixEl\"\n data-gr-tree-select-prefix\n class=\"absolute inset-y-px left-px flex items-center justify-center rounded-l-[var(--gr-radius-control)] border-r border-[var(--gr-brd)] px-2 text-[var(--gr-muted-fg)] pointer-events-none select-none truncate\"\n :style=\"prefixStyle\"\n aria-hidden=\"true\"\n >\n <slot name=\"prefix\" />\n </div>\n\n <input\n :id=\"fieldId\"\n ref=\"triggerEl\"\n data-testid=\"gr-tree-select-trigger\"\n data-gr-tree-select-trigger\n type=\"text\"\n :value=\"displayValue\"\n :placeholder=\"placeholder\"\n :disabled=\"isDisabled\"\n readonly\n role=\"combobox\"\n aria-readonly=\"true\"\n aria-haspopup=\"tree\"\n :aria-expanded=\"open ? 'true' : 'false'\"\n :aria-controls=\"open && hasTree ? treeId : undefined\"\n :aria-invalid=\"isInvalid ? 'true' : undefined\"\n :aria-required=\"isRequired ? 'true' : undefined\"\n :aria-describedby=\"describedBy\"\n :aria-label=\"ariaLabel\"\n class=\"w-full rounded-[var(--gr-radius-control)] border placeholder:text-[var(--gr-muted-fg)] transition-colors duration-[var(--gr-duration-fast)] focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--gr-ring)]\"\n :class=\"[className, $slots.value || hasTags ? 'text-transparent placeholder:text-transparent' : '']\"\n :style=\"triggerStyle\"\n @pointerdown=\"onTriggerPointerDown\"\n @click=\"toggleDropdown\"\n @focus=\"onTriggerFocus\"\n @keydown=\"onTriggerKeydown\"\n >\n\n <span\n v-if=\"signalState\"\n data-gr-tree-select-state\n class=\"absolute top-1/2 -translate-y-1/2 right-9\"\n :class=\"stateIconClass\"\n aria-hidden=\"true\"\n >\n <component :is=\"stateIcon\" class=\"h-4 w-4\" />\n </span>\n\n <span v-if=\"signalState\" :id=\"stateTextId\" data-gr-tree-select-state-text class=\"sr-only\">{{ stateText }}</span>\n\n <button\n v-if=\"clearable && hasSelection && !disabled && !isReadonly\"\n data-testid=\"gr-tree-select-clear\"\n data-gr-tree-select-clear\n type=\"button\"\n class=\"absolute top-1/2 -translate-y-1/2 right-3 h-6 w-6 inline-flex items-center justify-center rounded-[var(--gr-radius-control)] text-[var(--gr-muted-fg)] hover:text-[var(--gr-fg)] hover:bg-[color-mix(in_srgb,var(--gr-muted)_25%,transparent)]\"\n :aria-label=\"t('gr.common.clear', 'Clear')\"\n @click.stop=\"clear\"\n >\n <IconX class=\"inline-block h-4 w-4\" aria-hidden=\"true\" />\n </button>\n\n <span\n v-else\n data-testid=\"gr-tree-select-chevron\"\n data-gr-tree-select-chevron\n class=\"absolute top-1/2 -translate-y-1/2 right-3 text-[var(--gr-muted-fg)] pointer-events-none\"\n >\n <IconChevronDown\n class=\"inline-block h-4 w-4 transition-transform duration-[var(--gr-duration-fast)]\"\n :class=\"open ? 'rotate-180' : ''\"\n aria-hidden=\"true\"\n />\n </span>\n\n <div\n v-if=\"hasSuffix\"\n ref=\"suffixEl\"\n data-gr-tree-select-suffix\n class=\"absolute inset-y-px right-9 flex items-center justify-center border-l border-[var(--gr-brd)] px-2 text-[var(--gr-muted-fg)] pointer-events-none select-none truncate\"\n :class=\"suffixFixed ? '[direction:rtl]' : ''\"\n :style=\"suffixStyle\"\n aria-hidden=\"true\"\n >\n <slot name=\"suffix\" />\n </div>\n\n <!--\n Полоса не ловит указатель целиком, а каждый чип — ловит: клик мимо чипа\n обязан открыть панель, как и клик по любому другому месту триггера.\n -->\n <div\n v-if=\"hasTags\"\n data-gr-tree-select-tags\n class=\"absolute inset-y-0 left-3 right-9 flex flex-wrap items-center gap-1 py-1.5 pointer-events-none\"\n :style=\"valueOverlayStyle\"\n >\n <GrChip\n v-for=\"key in visibleTagKeys\"\n :key=\"`tag-${String(key)}`\"\n data-gr-tree-select-tag\n class=\"pointer-events-auto\"\n :tone=\"tagTone\"\n :dark=\"tagDark\"\n :size=\"chipSize\"\n :radius=\"tagRadius\"\n :closable=\"!isDisabled && !isReadonly\"\n :remove-label=\"tagRemoveLabel(key)\"\n @remove=\"removeTag(key)\"\n >\n <span class=\"truncate\">{{ tagLabel(key) }}</span>\n </GrChip>\n\n <GrChip\n v-if=\"hiddenTagCount > 0\"\n data-gr-tree-select-tag-rest\n :tone=\"tagTone\"\n :dark=\"tagDark\"\n :size=\"chipSize\"\n :radius=\"tagRadius\"\n >\n +{{ hiddenTagCount }}\n </GrChip>\n </div>\n\n <div\n v-if=\"$slots.value\"\n class=\"absolute inset-y-0 left-3 right-9 flex items-center pointer-events-none\"\n :style=\"valueOverlayStyle\"\n >\n <slot\n name=\"value\"\n :value=\"modelValue\"\n :labels=\"selectedLabels\"\n :display-value=\"displayValue\"\n :path-labels=\"selectedPathLabels\"\n />\n </div>\n </div>\n\n <teleport :to=\"portalTarget\" :disabled=\"!teleportEnabled\">\n <transition\n :enter-active-class=\"panelPopTransition.enter\"\n :enter-from-class=\"panelPopTransition.enterFrom\"\n :enter-to-class=\"panelPopTransition.enterTo\"\n :leave-active-class=\"panelPopTransition.leave\"\n :leave-from-class=\"panelPopTransition.leaveFrom\"\n :leave-to-class=\"panelPopTransition.leaveTo\"\n >\n <div\n v-show=\"open\"\n ref=\"panelEl\"\n data-testid=\"gr-tree-select-panel\"\n v-bind=\"themeAttrs\"\n data-gr-tree-select-panel\n data-gr-overlay-root\n :style=\"floatingStyle\"\n @keydown=\"onPanelKeydown\"\n >\n <div :class=\"panelClasses\">\n <div v-if=\"filterable\" class=\"p-2 border-b border-[var(--gr-brd)]\">\n <GrInput\n ref=\"filterInputRef\"\n v-model=\"filterValue\"\n data-testid=\"gr-tree-select-filter\"\n data-gr-tree-select-filter\n type=\"search\"\n :inputmode=\"filterInputmode\"\n :placeholder=\"resolvedFilterPlaceholder\"\n size=\"sm\"\n @keydown=\"onFilterKeydown\"\n />\n </div>\n\n <!--\n Скроллер один. При виртуализации его берёт на себя дерево: своя\n высота нужна ему, чтобы посчитать окно, а вложенный скроллер поверх\n дал бы вторую полосу прокрутки на том же списке.\n -->\n <div\n class=\"p-1 min-h-0\"\n :class=\"virtual ? '' : 'overflow-auto'\"\n :style=\"virtual ? undefined : { maxHeight: `${dropdownMaxHeight}px` }\"\n >\n <div\n v-if=\"loading\"\n data-gr-tree-select-loading\n role=\"status\"\n :class=\"grTreeSelectStateClass\"\n >\n <slot name=\"loading\">\n <IconLoaderCircle class=\"block h-4 w-4 animate-spin\" aria-hidden=\"true\" />\n <span>{{ t('gr.treeSelect.loading', 'Loading…') }}</span>\n </slot>\n </div>\n\n <div v-else-if=\"(data?.length ?? 0) === 0\" :class=\"grTreeSelectStateClass\">\n <slot name=\"empty\">\n {{ t('gr.treeSelect.empty', 'No data') }}\n </slot>\n </div>\n\n <GrTree\n v-else\n :id=\"treeId\"\n ref=\"treeRef\"\n :size=\"resolvedSize\"\n :data=\"data\"\n :props=\"props.props\"\n :node-key=\"nodeKey as any\"\n :default-expanded-keys=\"defaultExpandedKeys\"\n :filter-node-method=\"filterNodeMethod\"\n :highlight-current=\"!multiple\"\n :virtual=\"virtual\"\n :max-height=\"dropdownMaxHeight\"\n :show-checkbox=\"checkboxMode\"\n :check-strictly=\"checkStrictly\"\n :checked-keys=\"selectedKeys\"\n @node-click=\"onNodeClick\"\n @update:checked-keys=\"onCheckedKeys\"\n >\n <template #default=\"{ node, data }\">\n <slot\n name=\"node\"\n :node=\"node\"\n :data=\"data\"\n :selected=\"selectedKeySet.has(node.key)\"\n >\n <div class=\"flex items-center gap-2 min-w-0\">\n <!-- Чекбокс дерева уже показывает отметку: вторая галочка\n рядом читалась бы как ошибка. -->\n <span\n v-if=\"!checkboxMode\"\n data-gr-tree-select-check\n class=\"inline-block h-4 w-4 shrink-0\"\n aria-hidden=\"true\"\n >\n <IconCheck v-if=\"selectedKeySet.has(node.key)\" class=\"block h-4 w-4 text-[var(--gr-primary-text)]\" />\n </span>\n <span class=\"truncate\">{{ node.label }}</span>\n </div>\n </slot>\n </template>\n </GrTree>\n </div>\n </div>\n </div>\n </transition>\n </teleport>\n </div>\n</template>\n","<script setup lang=\"ts\" generic=\"T extends Record<string, any> = any\">\nimport { computed, nextTick, ref, useId, useSlots, watch } from 'vue'\n\nimport { usePortalTarget } from '../../composables/usePortalTarget'\n\nimport { vClickOutside } from '../../directives'\nimport { useFloating } from '../../composables/useFloating'\nimport { useOverlayLayer } from '../../composables/useOverlayLayer'\nimport { useControlAddons } from '../../composables/internal/useControlAddons'\nimport { useControlledOpen } from '../../composables/internal/useControlledOpen'\nimport { useGrComponentSize, useGrThemeAttrs } from '../GrConfigProvider/context'\nimport { useGrFormControl } from '../../composables/useGrFormControl'\nimport { useFocusWithin } from '../../composables/internal/useFocusWithin'\nimport { useGrFormFieldContext } from '../GrFormField/context'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport {\n controlSignalState,\n controlStateFallbackText,\n controlStateIconClass,\n controlStateIconColors,\n controlStateTextKey,\n} from '../shared/controlState'\nimport GrChip from '../GrChip/GrChip.vue'\nimport { chipSizeForBadgeScale } from '../GrChip/grChipStyles'\nimport GrInput from '../GrInput/GrInput.vue'\nimport GrTree, {\n type GrTreeInstance,\n type GrTreeKey,\n type GrTreeNode,\n} from '../GrTree'\nimport type { GrInputSize } from '../GrInput/GrInput.vue'\nimport { panelPopTransition } from '../shared/overlayTransition'\nimport type { GrTreeSelectModelValue, GrTreeSelectProps } from './grTreeSelectTypes'\nimport { grTreeSelectClass, grTreeSelectPanelClass, grTreeSelectStateClass, paddingX, trailingZoneWidth } from './grTreeSelectStyles'\n\nimport IconCheck from '~icons/lucide/check'\nimport IconChevronDown from '~icons/lucide/chevron-down'\nimport IconCheckCircle from '~icons/lucide/check-circle'\nimport IconAlertTriangle from '~icons/lucide/alert-triangle'\nimport IconLoaderCircle from '~icons/lucide/loader-circle'\nimport IconX from '~icons/lucide/x'\n\nexport interface GrTreeSelectEmits<T extends Record<string, any> = any> {\n (e: 'update:modelValue', value: GrTreeSelectModelValue): void\n (e: 'change', value: GrTreeSelectModelValue): void\n /** Панель открылась/закрылась (`v-model:open`). */\n (e: 'update:open', value: boolean): void\n (e: 'clear'): void\n (e: 'nodeClick', data: T, node: GrTreeNode<T>): void\n (e: 'focus', event: FocusEvent): void\n (e: 'blur', event: FocusEvent): void\n}\n\nconst props = withDefaults(\n defineProps<GrTreeSelectProps<T>>(),\n {\n props: () => ({\n children: 'children',\n label: 'label',\n }),\n nodeKey: 'id' as any,\n defaultExpandedKeys: () => [],\n disabled: false,\n placeholder: undefined,\n size: undefined,\n loading: false,\n invalid: false,\n readonly: false,\n required: false,\n ariaLabel: undefined,\n state: 'default',\n multiple: false,\n tags: false,\n maxTagCount: undefined,\n tagTone: 'neutral',\n tagDark: false,\n tagSize: 'sm',\n tagRadius: 'round',\n showCheckbox: false,\n checkStrictly: false,\n clearable: false,\n open: undefined,\n name: undefined,\n valueDisplay: 'label',\n filterable: false,\n filterPlaceholder: undefined,\n filterInputmode: undefined,\n filterNodeMethod: undefined,\n closeOnSelect: undefined,\n dropdownMaxHeight: 320,\n virtual: false,\n prefixMinWidth: undefined,\n prefixMaxWidth: undefined,\n suffixMinWidth: undefined,\n suffixMaxWidth: undefined,\n prefixFixed: false,\n suffixFixed: false,\n },\n)\n\nconst { t } = useGranularityTranslations()\n\nconst emit = defineEmits<GrTreeSelectEmits<T>>()\n\ndefineSlots<{\n /** Рендер значения внутри триггера (вместо дефолтного текста). */\n value?: (props: { value: GrTreeSelectModelValue, labels: string[], displayValue: string, pathLabels?: string[] }) => any\n /** Рендер строки дерева. */\n node?: (props: { node: GrTreeNode<T>, data: T, selected: boolean }) => any\n /** Содержимое пустого состояния (когда нет данных). */\n empty?: () => any\n /** Содержимое панели, пока данные едут. */\n loading?: () => any\n /** Аддон слева от значения: иконка, код валюты, метка. */\n prefix?: () => any\n /** Аддон справа от значения, перед крестиком и шевроном. */\n suffix?: () => any\n}>()\n\nconst rootEl = ref<HTMLElement | null>(null)\nconst triggerEl = ref<HTMLInputElement | null>(null)\nconst treeId = `gr-tree-select-tree-${useId()}`\n\n// Контекст `GrFormField` + общий контракт форм-контрола.\nconst field = useGrFormFieldContext()\nconst fieldId = computed(() => field?.id.value)\nconst stateTextId = useId()\nconst {\n disabled: isDisabled,\n invalid: isInvalid,\n required: isRequired,\n readonly: isReadonly,\n} = useGrFormControl(() => props)\n\n/**\n * Небуквенный признак состояния: иконка для глаз, скрытая подпись для\n * скринридера. Разбор — `shared/controlState`. Встаёт левее крестика и\n * шеврона: правый край триггера занят одним из них всегда.\n */\nconst signalState = computed(() => controlSignalState(props.state, isInvalid.value))\nconst stateIcon = computed(() => (signalState.value === 'success' ? IconCheckCircle : IconAlertTriangle))\nconst stateIconClass = computed(() => (signalState.value\n ? `${controlStateIconClass} ${controlStateIconColors[signalState.value]}`\n : ''))\nconst stateText = computed(() => (signalState.value\n ? t(controlStateTextKey[signalState.value], controlStateFallbackText[signalState.value])\n : ''))\n\nconst describedBy = computed(() =>\n [field?.describedById.value, signalState.value ? stateTextId : undefined]\n .filter(Boolean)\n .join(' ') || undefined,\n)\n\nfunction focus(): void {\n triggerEl.value?.focus()\n}\n\nfunction blur(): void {\n triggerEl.value?.blur()\n}\n\ndefineExpose({ focus, blur })\nconst filterInputRef = ref<InstanceType<typeof GrInput> | null>(null)\nconst treeRef = ref<GrTreeInstance | null>(null)\nconst panelEl = ref<HTMLElement | null>(null)\n\n// Панель телепортирована в `body`, то есть лежит вне корня, но для пользователя\n// она часть контрола: без неё уход фокуса в панель читался бы как `blur`.\nconst { onFocusIn, onFocusOut } = useFocusWithin(rootEl, {\n enter: event => emit('focus', event),\n leave: event => emit('blur', event),\n containers: () => [panelEl.value],\n})\n\nconst clickOutsideExclude = [() => panelEl.value]\n\nlet hadPointerDownOnTrigger = false\n\n// Имя `open` сохранено: читатели работают с computed-Ref.\nconst { open, setOpen: setOpenState } = useControlledOpen(\n () => props.open,\n next => emit('update:open', next),\n)\nconst filterValue = ref('')\n\nconst { floatingStyle } = useFloating(rootEl, panelEl, open, {\n placement: 'bottom-start',\n matchWidth: true,\n zIndexVar: '--gr-z-dropdown',\n})\n\nconst closeOnSelectResolved = computed(() => {\n return props.closeOnSelect ?? !props.multiple\n})\n\nfunction getChildrenKey() {\n return props.props.children ?? 'children'\n}\n\nfunction getLabelKey() {\n return props.props.label ?? 'label'\n}\n\nfunction nodeLabel(data: T): string {\n const key = getLabelKey() as keyof T\n const v = data[key]\n return v == null ? '' : String(v)\n}\n\nfunction nodeChildren(data: T): T[] {\n const key = getChildrenKey() as keyof T\n const v = data[key]\n return Array.isArray(v) ? (v as any) : []\n}\n\nfunction nodeKeyOf(data: T, index: number, parentKey: GrTreeKey | undefined): GrTreeKey {\n const keyName = props.nodeKey as keyof T\n const v = data[keyName]\n if (v != null)\n return v as GrTreeKey\n\n return parentKey == null ? index : `${String(parentKey)}:${index}`\n}\n\nconst labelByKey = computed(() => {\n const map = new Map<GrTreeKey, string>()\n\n const walk = (items: T[], parentKey: GrTreeKey | undefined) => {\n for (let i = 0; i < items.length; i++) {\n const item = items[i]\n const key = nodeKeyOf(item, i, parentKey)\n map.set(key, nodeLabel(item))\n walk(nodeChildren(item), key)\n }\n }\n\n walk(props.data ?? [], undefined)\n return map\n})\n\nconst pathLabelsByKey = computed(() => {\n const map = new Map<GrTreeKey, string[]>()\n\n const walk = (items: T[], parentKey: GrTreeKey | undefined, parentPath: string[]) => {\n for (let i = 0; i < items.length; i++) {\n const item = items[i]\n const key = nodeKeyOf(item, i, parentKey)\n const label = nodeLabel(item)\n const path = [...parentPath, label]\n map.set(key, path)\n walk(nodeChildren(item), key, path)\n }\n }\n\n walk(props.data ?? [], undefined, [])\n return map\n})\n\nconst selectedKeys = computed<GrTreeKey[]>(() => {\n if (props.multiple) {\n return Array.isArray(props.modelValue) ? props.modelValue : []\n }\n\n const v = props.modelValue\n if (v == null || Array.isArray(v))\n return []\n return [v]\n})\n\nconst selectedKeySet = computed(() => new Set(selectedKeys.value))\n\nconst selectedLabels = computed(() => {\n const map = labelByKey.value\n return selectedKeys.value.map(k => map.get(k) ?? String(k))\n})\n\nconst selectedPathLabels = computed<string[] | undefined>(() => {\n if (props.multiple)\n return undefined\n\n const key = selectedKeys.value[0]\n if (key == null)\n return undefined\n\n const path = pathLabelsByKey.value.get(key)\n if (path?.length)\n return path\n\n const labels = selectedLabels.value\n return labels.length ? [labels[0]] : undefined\n})\n\n/**\n * Чипы живут РЯДОМ с триггером, а не внутри него: `role=\"combobox\"` объявляет\n * потомков презентационными, и крестик внутри был бы недостижим с клавиатуры\n * (axe: `nested-interactive`). Тот же приём — у `GrSelect`.\n */\nconst showTags = computed(() => props.multiple && props.tags)\n\n/** Полоса чипов рисуется только когда есть что рисовать: пустая съела бы плейсхолдер. */\nconst hasTags = computed(() => showTags.value && selectedKeys.value.length > 0)\n\nconst visibleTagKeys = computed(() => {\n const limit = props.maxTagCount\n if (limit === undefined || limit < 0)\n return selectedKeys.value\n\n return selectedKeys.value.slice(0, limit)\n})\n\nconst hiddenTagCount = computed(() => selectedKeys.value.length - visibleTagKeys.value.length)\n\n/**\n * Проп `tagSize` объявлен по шкале бейджа и остаётся публичным контрактом:\n * ступени чипа сдвинуты, и перевод держит кегль тем же.\n */\nconst chipSize = computed(() => chipSizeForBadgeScale(props.tagSize))\n\nfunction tagLabel(key: GrTreeKey): string {\n return labelByKey.value.get(key) ?? String(key)\n}\n\nfunction tagRemoveLabel(key: GrTreeKey): string {\n return t('gr.treeSelect.removeTag', 'Remove {label}', { label: tagLabel(key) })\n}\n\nconst displayValue = computed(() => {\n const labels = selectedLabels.value\n if (labels.length === 0)\n return ''\n\n if (!props.multiple) {\n if (props.valueDisplay === 'path') {\n const path = selectedPathLabels.value\n if (path?.length)\n return path.join(' / ')\n }\n return labels[0]\n }\n\n if (labels.length === 1)\n return labels[0]\n return `${labels[0]} +${labels.length - 1}`\n})\n\nconst hasSelection = computed(() => selectedKeys.value.length > 0)\n\n/** Дерево рендерится только когда есть что показать — ссылаться иначе не на что. */\nconst hasTree = computed(() => !props.loading && (props.data?.length ?? 0) > 0)\n\nconst resolvedFilterPlaceholder = computed(() => {\n return props.filterPlaceholder ?? t('gr.treeSelect.filterPlaceholder', 'Search…')\n})\n\nconst resolvedSize = useGrComponentSize(() => props.size, { component: 'GrTreeSelect' })\n\nconst className = computed(() => {\n return grTreeSelectClass({\n size: resolvedSize.value,\n state: props.state,\n invalid: isInvalid.value,\n disabled: isDisabled.value,\n })\n})\n\nconst panelClasses = computed(() => {\n return grTreeSelectPanelClass\n})\n\nconst ADDON_MIN_WIDTH_BY_SIZE: Record<GrInputSize, string> = {\n xs: '2rem',\n sm: '2.25rem',\n md: '2.5rem',\n lg: '3rem',\n}\n\nconst slots = useSlots()\n\nconst {\n hasPrefix,\n hasSuffix,\n prefixEl,\n suffixEl,\n prefixStyle,\n suffixStyle,\n fieldPadding: triggerStyle,\n} = useControlAddons(() => props, {\n defaultMinWidth: () => ADDON_MIN_WIDTH_BY_SIZE[resolvedSize.value],\n paddingX: () => paddingX[resolvedSize.value],\n // Место под крестик и шеврон уже отдано классом `pr-9`, но инлайн-паддинг\n // перекрывает класс целиком — с суффиксом эту зону приходится вернуть числом.\n trailingReserve: () => (slots.suffix ? trailingZoneWidth : '0px'),\n})\n\n// Слот `value` рисуется поверх поля и обязан жить в тех же границах, что и\n// текст под ним. Без аддонов границы задаёт класс — стиль остаётся пустым.\nconst valueOverlayStyle = computed(() => ({\n left: hasPrefix.value ? triggerStyle.value.paddingLeft : undefined,\n right: hasSuffix.value ? triggerStyle.value.paddingRight : undefined,\n}))\n\nfunction setOpen(next: boolean) {\n if (isDisabled.value || isReadonly.value)\n return\n\n setOpenState(next)\n}\n\nfunction onClickOutside(): void {\n setOpen(false)\n}\n\nfunction openDropdown(): void {\n setOpen(true)\n}\n\n/**\n * Стек слоёв возвращает фокус на триггер сразу после закрытия, а у триггера\n * открытие висит на `focus`. Без флага `Escape` из дерева закрывал бы панель и\n * тем же движением открывал её заново.\n */\nlet suppressFocusOpen = false\n\nfunction closeDropdown(): void {\n suppressFocusOpen = true\n setOpen(false)\n setTimeout(() => {\n suppressFocusOpen = false\n }, 0)\n}\n\nfunction toggleDropdown(): void {\n setOpen(!open.value)\n}\n\n// Клик по триггеру сам переключает панель через `@click`; флаг гасит открытие\n// по приходящему следом `focus`, иначе один клик открыл бы и тут же закрыл.\nfunction onTriggerPointerDown(): void {\n hadPointerDownOnTrigger = true\n setTimeout(() => {\n hadPointerDownOnTrigger = false\n }, 0)\n}\n\nfunction onTriggerFocus(): void {\n if (hadPointerDownOnTrigger || suppressFocusOpen)\n return\n openDropdown()\n}\n\n// Возврат фокуса на триггер — из контракта слоя, а не руками через `nextTick`.\nuseOverlayLayer(open, closeDropdown, { root: panelEl })\n\nwatch(\n open,\n async (isOpen) => {\n if (!isOpen) {\n if (filterValue.value.trim().length > 0)\n filterValue.value = ''\n return\n }\n\n // Подсветка дерева идёт за значением: панель могли открыть после того, как\n // значение сменили снаружи.\n if (!props.multiple) {\n const v = props.modelValue\n if (v != null && !Array.isArray(v))\n treeRef.value?.setCurrentKey(v)\n }\n\n if (props.filterable) {\n await nextTick()\n filterInputRef.value?.focus()\n }\n },\n { immediate: true },\n)\n\nwatch(\n () => props.modelValue,\n (v) => {\n if (props.multiple)\n return\n if (v == null || Array.isArray(v)) {\n treeRef.value?.setCurrentKey(undefined)\n return\n }\n treeRef.value?.setCurrentKey(v)\n },\n)\n\nwatch(\n filterValue,\n (v) => {\n treeRef.value?.filter(v)\n },\n)\n\nfunction emitModel(next: GrTreeSelectModelValue) {\n emit('update:modelValue', next)\n emit('change', next)\n}\n\nfunction clear(): void {\n if (isDisabled.value || isReadonly.value)\n return\n\n const next: GrTreeSelectModelValue = props.multiple ? [] : null\n emitModel(next)\n emit('clear')\n if (!props.multiple)\n treeRef.value?.setCurrentKey(undefined)\n}\n\n/**\n * Отдаёт клавиатуру дереву. Панель под `v-show`, поэтому дерево уже в DOM, но\n * скрытый элемент сфокусировать нельзя — сначала открытие, потом кадр, потом\n * фокус. Дальше работают клавиши `GrTree`, а `Escape` возвращает фокус на\n * триггер силами общего стека слоёв.\n */\nasync function focusTree(): Promise<boolean> {\n if (!open.value)\n return false\n\n await nextTick()\n return treeRef.value?.focus() ?? false\n}\n\nfunction onTriggerKeydown(e: KeyboardEvent): void {\n if (isDisabled.value)\n return\n\n if (e.key === 'Escape') {\n e.preventDefault()\n closeDropdown()\n return\n }\n\n if (e.key === 'ArrowDown' || e.key === 'ArrowUp' || e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n openDropdown()\n\n // При `filterable` фокус уходит в поле поиска (см. watch на `open`), и\n // дальше в дерево ведёт стрелка уже оттуда.\n if (!props.filterable)\n void focusTree()\n }\n}\n\n/** Стрелка из поля поиска — единственный путь из фильтра в дерево. */\nfunction onFilterKeydown(e: KeyboardEvent): void {\n if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp')\n return\n\n e.preventDefault()\n void focusTree()\n}\n\n/** `Tab` уводит из панели — оставлять её открытой за спиной незачем. */\nfunction onPanelKeydown(e: KeyboardEvent): void {\n if (e.key === 'Tab')\n closeDropdown()\n}\n\n// Чекбоксы осмысленны только в множественном выборе: одиночный уже подсвечен\n// текущим узлом.\nconst checkboxMode = computed(() => props.multiple && props.showCheckbox)\n\n// В режиме чекбоксов каскад по родителям и детям считает `GrTree`, а не копия\n// его логики здесь: значение приходит обратно одним `update:checkedKeys`.\nfunction onCheckedKeys(keys: GrTreeKey[]): void {\n if (isDisabled.value || isReadonly.value)\n return\n\n emitModel([...keys])\n}\n\n/**\n * Снятие чипа в режиме чекбоксов идёт через дерево, а не через фильтрацию\n * ключей: каскад по родителям и детям считает `GrTree`, и убрав ключ мимо него,\n * мы получили бы отмеченного родителя без детей. Дерево смонтировано и при\n * закрытой панели (она под `v-show`), так что звать его можно всегда.\n */\nfunction removeTag(key: GrTreeKey): void {\n if (isDisabled.value || isReadonly.value)\n return\n\n if (checkboxMode.value) {\n treeRef.value?.setChecked(key, false)\n return\n }\n\n emitModel(selectedKeys.value.filter(k => k !== key))\n}\n\nfunction onNodeClick(data: T, node: GrTreeNode<T>): void {\n emit('nodeClick', data, node)\n\n if (isDisabled.value)\n return\n\n if (checkboxMode.value) {\n // Клик по строке — тот же переключатель отметки, что и сам чекбокс;\n // значение придёт через `update:checkedKeys`, поэтому здесь не эмитим.\n treeRef.value?.setChecked(node.key, !selectedKeySet.value.has(node.key))\n return\n }\n\n if (props.multiple) {\n const next = new Set(selectedKeySet.value)\n if (next.has(node.key))\n next.delete(node.key)\n else\n next.add(node.key)\n emitModel([...next])\n\n if (closeOnSelectResolved.value) {\n closeDropdown()\n }\n return\n }\n\n emitModel(node.key)\n if (closeOnSelectResolved.value) {\n closeDropdown()\n }\n}\n\n// Телепорт включается только ПОСЛЕ монтирования: иначе первый клиентский\n// рендер не совпадает с серверным и ломается гидрация (см. композабл).\nconst { target: portalTarget, enabled: teleportEnabled } = usePortalTarget()\n\n// Тема поддерева на телепортированную панель: в DOM она уезжает в `body`, то\n// есть вне обёртки провайдера, и `data-theme` с неё не наследуется. В дереве\n// компонентов панель остаётся внутри — `inject` доходит, и тему она ставит себе\n// сама.\nconst themeAttrs = useGrThemeAttrs()\n</script>\n\n<template>\n <div\n ref=\"rootEl\"\n v-click-outside=\"{ handler: onClickOutside, enabled: open, exclude: clickOutsideExclude }\"\n data-gr-tree-select\n class=\"relative\"\n @focusin=\"onFocusIn\"\n @focusout=\"onFocusOut\"\n >\n <!-- Нативная форма: hidden на каждый выбранный ключ. -->\n <template v-if=\"name\">\n <input\n v-for=\"key in selectedKeys\"\n :key=\"`hidden-${String(key)}`\"\n type=\"hidden\"\n :name=\"name\"\n :value=\"String(key)\"\n >\n </template>\n <div class=\"relative\">\n <div\n v-if=\"hasPrefix\"\n ref=\"prefixEl\"\n data-gr-tree-select-prefix\n class=\"absolute inset-y-px left-px flex items-center justify-center rounded-l-[var(--gr-radius-control)] border-r border-[var(--gr-brd)] px-2 text-[var(--gr-muted-fg)] pointer-events-none select-none truncate\"\n :style=\"prefixStyle\"\n aria-hidden=\"true\"\n >\n <slot name=\"prefix\" />\n </div>\n\n <input\n :id=\"fieldId\"\n ref=\"triggerEl\"\n data-testid=\"gr-tree-select-trigger\"\n data-gr-tree-select-trigger\n type=\"text\"\n :value=\"displayValue\"\n :placeholder=\"placeholder\"\n :disabled=\"isDisabled\"\n readonly\n role=\"combobox\"\n aria-readonly=\"true\"\n aria-haspopup=\"tree\"\n :aria-expanded=\"open ? 'true' : 'false'\"\n :aria-controls=\"open && hasTree ? treeId : undefined\"\n :aria-invalid=\"isInvalid ? 'true' : undefined\"\n :aria-required=\"isRequired ? 'true' : undefined\"\n :aria-describedby=\"describedBy\"\n :aria-label=\"ariaLabel\"\n class=\"w-full rounded-[var(--gr-radius-control)] border placeholder:text-[var(--gr-muted-fg)] transition-colors duration-[var(--gr-duration-fast)] focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--gr-ring)]\"\n :class=\"[className, $slots.value || hasTags ? 'text-transparent placeholder:text-transparent' : '']\"\n :style=\"triggerStyle\"\n @pointerdown=\"onTriggerPointerDown\"\n @click=\"toggleDropdown\"\n @focus=\"onTriggerFocus\"\n @keydown=\"onTriggerKeydown\"\n >\n\n <span\n v-if=\"signalState\"\n data-gr-tree-select-state\n class=\"absolute top-1/2 -translate-y-1/2 right-9\"\n :class=\"stateIconClass\"\n aria-hidden=\"true\"\n >\n <component :is=\"stateIcon\" class=\"h-4 w-4\" />\n </span>\n\n <span v-if=\"signalState\" :id=\"stateTextId\" data-gr-tree-select-state-text class=\"sr-only\">{{ stateText }}</span>\n\n <button\n v-if=\"clearable && hasSelection && !disabled && !isReadonly\"\n data-testid=\"gr-tree-select-clear\"\n data-gr-tree-select-clear\n type=\"button\"\n class=\"absolute top-1/2 -translate-y-1/2 right-3 h-6 w-6 inline-flex items-center justify-center rounded-[var(--gr-radius-control)] text-[var(--gr-muted-fg)] hover:text-[var(--gr-fg)] hover:bg-[color-mix(in_srgb,var(--gr-muted)_25%,transparent)]\"\n :aria-label=\"t('gr.common.clear', 'Clear')\"\n @click.stop=\"clear\"\n >\n <IconX class=\"inline-block h-4 w-4\" aria-hidden=\"true\" />\n </button>\n\n <span\n v-else\n data-testid=\"gr-tree-select-chevron\"\n data-gr-tree-select-chevron\n class=\"absolute top-1/2 -translate-y-1/2 right-3 text-[var(--gr-muted-fg)] pointer-events-none\"\n >\n <IconChevronDown\n class=\"inline-block h-4 w-4 transition-transform duration-[var(--gr-duration-fast)]\"\n :class=\"open ? 'rotate-180' : ''\"\n aria-hidden=\"true\"\n />\n </span>\n\n <div\n v-if=\"hasSuffix\"\n ref=\"suffixEl\"\n data-gr-tree-select-suffix\n class=\"absolute inset-y-px right-9 flex items-center justify-center border-l border-[var(--gr-brd)] px-2 text-[var(--gr-muted-fg)] pointer-events-none select-none truncate\"\n :class=\"suffixFixed ? '[direction:rtl]' : ''\"\n :style=\"suffixStyle\"\n aria-hidden=\"true\"\n >\n <slot name=\"suffix\" />\n </div>\n\n <!--\n Полоса не ловит указатель целиком, а каждый чип — ловит: клик мимо чипа\n обязан открыть панель, как и клик по любому другому месту триггера.\n -->\n <div\n v-if=\"hasTags\"\n data-gr-tree-select-tags\n class=\"absolute inset-y-0 left-3 right-9 flex flex-wrap items-center gap-1 py-1.5 pointer-events-none\"\n :style=\"valueOverlayStyle\"\n >\n <GrChip\n v-for=\"key in visibleTagKeys\"\n :key=\"`tag-${String(key)}`\"\n data-gr-tree-select-tag\n class=\"pointer-events-auto\"\n :tone=\"tagTone\"\n :dark=\"tagDark\"\n :size=\"chipSize\"\n :radius=\"tagRadius\"\n :closable=\"!isDisabled && !isReadonly\"\n :remove-label=\"tagRemoveLabel(key)\"\n @remove=\"removeTag(key)\"\n >\n <span class=\"truncate\">{{ tagLabel(key) }}</span>\n </GrChip>\n\n <GrChip\n v-if=\"hiddenTagCount > 0\"\n data-gr-tree-select-tag-rest\n :tone=\"tagTone\"\n :dark=\"tagDark\"\n :size=\"chipSize\"\n :radius=\"tagRadius\"\n >\n +{{ hiddenTagCount }}\n </GrChip>\n </div>\n\n <div\n v-if=\"$slots.value\"\n class=\"absolute inset-y-0 left-3 right-9 flex items-center pointer-events-none\"\n :style=\"valueOverlayStyle\"\n >\n <slot\n name=\"value\"\n :value=\"modelValue\"\n :labels=\"selectedLabels\"\n :display-value=\"displayValue\"\n :path-labels=\"selectedPathLabels\"\n />\n </div>\n </div>\n\n <teleport :to=\"portalTarget\" :disabled=\"!teleportEnabled\">\n <transition\n :enter-active-class=\"panelPopTransition.enter\"\n :enter-from-class=\"panelPopTransition.enterFrom\"\n :enter-to-class=\"panelPopTransition.enterTo\"\n :leave-active-class=\"panelPopTransition.leave\"\n :leave-from-class=\"panelPopTransition.leaveFrom\"\n :leave-to-class=\"panelPopTransition.leaveTo\"\n >\n <div\n v-show=\"open\"\n ref=\"panelEl\"\n data-testid=\"gr-tree-select-panel\"\n v-bind=\"themeAttrs\"\n data-gr-tree-select-panel\n data-gr-overlay-root\n :style=\"floatingStyle\"\n @keydown=\"onPanelKeydown\"\n >\n <div :class=\"panelClasses\">\n <div v-if=\"filterable\" class=\"p-2 border-b border-[var(--gr-brd)]\">\n <GrInput\n ref=\"filterInputRef\"\n v-model=\"filterValue\"\n data-testid=\"gr-tree-select-filter\"\n data-gr-tree-select-filter\n type=\"search\"\n :inputmode=\"filterInputmode\"\n :placeholder=\"resolvedFilterPlaceholder\"\n size=\"sm\"\n @keydown=\"onFilterKeydown\"\n />\n </div>\n\n <!--\n Скроллер один. При виртуализации его берёт на себя дерево: своя\n высота нужна ему, чтобы посчитать окно, а вложенный скроллер поверх\n дал бы вторую полосу прокрутки на том же списке.\n -->\n <div\n class=\"p-1 min-h-0\"\n :class=\"virtual ? '' : 'overflow-auto'\"\n :style=\"virtual ? undefined : { maxHeight: `${dropdownMaxHeight}px` }\"\n >\n <div\n v-if=\"loading\"\n data-gr-tree-select-loading\n role=\"status\"\n :class=\"grTreeSelectStateClass\"\n >\n <slot name=\"loading\">\n <IconLoaderCircle class=\"block h-4 w-4 animate-spin\" aria-hidden=\"true\" />\n <span>{{ t('gr.treeSelect.loading', 'Loading…') }}</span>\n </slot>\n </div>\n\n <div v-else-if=\"(data?.length ?? 0) === 0\" :class=\"grTreeSelectStateClass\">\n <slot name=\"empty\">\n {{ t('gr.treeSelect.empty', 'No data') }}\n </slot>\n </div>\n\n <GrTree\n v-else\n :id=\"treeId\"\n ref=\"treeRef\"\n :size=\"resolvedSize\"\n :data=\"data\"\n :props=\"props.props\"\n :node-key=\"nodeKey as any\"\n :default-expanded-keys=\"defaultExpandedKeys\"\n :filter-node-method=\"filterNodeMethod\"\n :highlight-current=\"!multiple\"\n :virtual=\"virtual\"\n :max-height=\"dropdownMaxHeight\"\n :show-checkbox=\"checkboxMode\"\n :check-strictly=\"checkStrictly\"\n :checked-keys=\"selectedKeys\"\n @node-click=\"onNodeClick\"\n @update:checked-keys=\"onCheckedKeys\"\n >\n <template #default=\"{ node, data }\">\n <slot\n name=\"node\"\n :node=\"node\"\n :data=\"data\"\n :selected=\"selectedKeySet.has(node.key)\"\n >\n <div class=\"flex items-center gap-2 min-w-0\">\n <!-- Чекбокс дерева уже показывает отметку: вторая галочка\n рядом читалась бы как ошибка. -->\n <span\n v-if=\"!checkboxMode\"\n data-gr-tree-select-check\n class=\"inline-block h-4 w-4 shrink-0\"\n aria-hidden=\"true\"\n >\n <IconCheck v-if=\"selectedKeySet.has(node.key)\" class=\"block h-4 w-4 text-[var(--gr-primary-text)]\" />\n </span>\n <span class=\"truncate\">{{ node.label }}</span>\n </div>\n </slot>\n </template>\n </GrTree>\n </div>\n </div>\n </div>\n </transition>\n </teleport>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqDA,MAAM,QAAQ;EA+Cd,MAAM,EAAE,MAAM,2BAA2B;EAEzC,MAAM,OAAO;EAiBb,MAAM,SAAS,IAAwB,IAAI;EAC3C,MAAM,YAAY,IAA6B,IAAI;EACnD,MAAM,SAAS,uBAAuB,MAAM;EAG5C,MAAM,QAAQ,sBAAsB;EACpC,MAAM,UAAU,eAAe,OAAO,GAAG,KAAK;EAC9C,MAAM,cAAc,MAAM;EAC1B,MAAM,EACJ,UAAU,YACV,SAAS,WACT,UAAU,YACV,UAAU,eACR,uBAAuB,KAAK;;;;;;EAOhC,MAAM,cAAc,eAAe,mBAAmB,MAAM,OAAO,UAAU,KAAK,CAAC;EACnF,MAAM,YAAY,eAAgB,YAAY,UAAU,YAAY,uBAAkB,sBAAkB;EACxG,MAAM,iBAAiB,eAAgB,YAAY,QAC/C,GAAG,sBAAsB,GAAG,uBAAuB,YAAY,WAC/D,EAAG;EACP,MAAM,YAAY,eAAgB,YAAY,QAC1C,EAAE,oBAAoB,YAAY,QAAQ,yBAAyB,YAAY,MAAM,IACrF,EAAG;EAEP,MAAM,cAAc,eAClB,CAAC,OAAO,cAAc,OAAO,YAAY,QAAQ,cAAc,KAAA,CAAS,CAAA,CACrE,OAAO,OAAO,CAAA,CACd,KAAK,GAAG,KAAK,KAAA,CAClB;EAEA,SAAS,QAAc;GACrB,UAAU,OAAO,MAAM;EACzB;EAEA,SAAS,OAAa;GACpB,UAAU,OAAO,KAAK;EACxB;EAEA,SAAa;GAAE;GAAO;EAAK,CAAC;EAC5B,MAAM,iBAAiB,IAAyC,IAAI;EACpE,MAAM,UAAU,IAA2B,IAAI;EAC/C,MAAM,UAAU,IAAwB,IAAI;EAI5C,MAAM,EAAE,WAAW,eAAe,eAAe,QAAQ;GACvD,QAAO,UAAS,KAAK,SAAS,KAAK;GACnC,QAAO,UAAS,KAAK,QAAQ,KAAK;GAClC,kBAAkB,CAAC,QAAQ,KAAK;EAClC,CAAC;EAED,MAAM,sBAAsB,OAAO,QAAQ,KAAK;EAEhD,IAAI,0BAA0B;EAG9B,MAAM,EAAE,MAAM,SAAS,iBAAiB,wBAChC,MAAM,OACZ,SAAQ,KAAK,eAAe,IAAI,CAClC;EACA,MAAM,cAAc,IAAI,EAAE;EAE1B,MAAM,EAAE,kBAAkB,YAAY,QAAQ,SAAS,MAAM;GAC3D,WAAW;GACX,YAAY;GACZ,WAAW;EACb,CAAC;EAED,MAAM,wBAAwB,eAAe;GAC3C,OAAO,MAAM,iBAAiB,CAAC,MAAM;EACvC,CAAC;EAED,SAAS,iBAAiB;GACxB,OAAO,MAAM,MAAM,YAAY;EACjC;EAEA,SAAS,cAAc;GACrB,OAAO,MAAM,MAAM,SAAS;EAC9B;EAEA,SAAS,UAAU,MAAiB;GAElC,MAAM,IAAI,KADE,YACG;GACf,OAAO,KAAK,OAAO,KAAK,OAAO,CAAC;EAClC;EAEA,SAAS,aAAa,MAAc;GAElC,MAAM,IAAI,KADE,eACG;GACf,OAAO,MAAM,QAAQ,CAAC,IAAK,IAAY,CAAC;EAC1C;EAEA,SAAS,UAAU,MAAS,OAAe,WAA6C;GAEtF,MAAM,IAAI,KADM,MAAM;GAEtB,IAAI,KAAK,MACP,OAAO;GAET,OAAO,aAAa,OAAO,QAAQ,GAAG,OAAO,SAAS,EAAE,GAAG;EAC7D;EAEA,MAAM,aAAa,eAAe;GAChC,MAAM,sBAAM,IAAI,IAAuB;GAEvC,MAAM,QAAQ,OAAY,cAAqC;IAC7D,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;KACrC,MAAM,OAAO,MAAM;KACnB,MAAM,MAAM,UAAU,MAAM,GAAG,SAAS;KACxC,IAAI,IAAI,KAAK,UAAU,IAAI,CAAC;KAC5B,KAAK,aAAa,IAAI,GAAG,GAAG;IAC9B;GACF;GAEA,KAAK,MAAM,QAAQ,CAAC,GAAG,KAAA,CAAS;GAChC,OAAO;EACT,CAAC;EAED,MAAM,kBAAkB,eAAe;GACrC,MAAM,sBAAM,IAAI,IAAyB;GAEzC,MAAM,QAAQ,OAAY,WAAkC,eAAyB;IACnF,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;KACrC,MAAM,OAAO,MAAM;KACnB,MAAM,MAAM,UAAU,MAAM,GAAG,SAAS;KACxC,MAAM,QAAQ,UAAU,IAAI;KAC5B,MAAM,OAAO,CAAC,GAAG,YAAY,KAAK;KAClC,IAAI,IAAI,KAAK,IAAI;KACjB,KAAK,aAAa,IAAI,GAAG,KAAK,IAAI;IACpC;GACF;GAEA,KAAK,MAAM,QAAQ,CAAC,GAAG,KAAA,GAAW,CAAC,CAAC;GACpC,OAAO;EACT,CAAC;EAED,MAAM,eAAe,eAA4B;GAC/C,IAAI,MAAM,UACR,OAAO,MAAM,QAAQ,MAAM,UAAU,IAAI,MAAM,aAAa,CAAC;GAG/D,MAAM,IAAI,MAAM;GAChB,IAAI,KAAK,QAAQ,MAAM,QAAQ,CAAC,GAC9B,OAAO,CAAC;GACV,OAAO,CAAC,CAAC;EACX,CAAC;EAED,MAAM,iBAAiB,eAAe,IAAI,IAAI,aAAa,KAAK,CAAC;EAEjE,MAAM,iBAAiB,eAAe;GACpC,MAAM,MAAM,WAAW;GACvB,OAAO,aAAa,MAAM,KAAI,MAAK,IAAI,IAAI,CAAC,KAAK,OAAO,CAAC,CAAC;EAC5D,CAAC;EAED,MAAM,qBAAqB,eAAqC;GAC9D,IAAI,MAAM,UACR,OAAO,KAAA;GAET,MAAM,MAAM,aAAa,MAAM;GAC/B,IAAI,OAAO,MACT,OAAO,KAAA;GAET,MAAM,OAAO,gBAAgB,MAAM,IAAI,GAAG;GAC1C,IAAI,MAAM,QACR,OAAO;GAET,MAAM,SAAS,eAAe;GAC9B,OAAO,OAAO,SAAS,CAAC,OAAO,EAAE,IAAI,KAAA;EACvC,CAAC;;;;;;EAOD,MAAM,WAAW,eAAe,MAAM,YAAY,MAAM,IAAI;;EAG5D,MAAM,UAAU,eAAe,SAAS,SAAS,aAAa,MAAM,SAAS,CAAC;EAE9E,MAAM,iBAAiB,eAAe;GACpC,MAAM,QAAQ,MAAM;GACpB,IAAI,UAAU,KAAA,KAAa,QAAQ,GACjC,OAAO,aAAa;GAEtB,OAAO,aAAa,MAAM,MAAM,GAAG,KAAK;EAC1C,CAAC;EAED,MAAM,iBAAiB,eAAe,aAAa,MAAM,SAAS,eAAe,MAAM,MAAM;;;;;EAM7F,MAAM,WAAW,eAAe,sBAAsB,MAAM,OAAO,CAAC;EAEpE,SAAS,SAAS,KAAwB;GACxC,OAAO,WAAW,MAAM,IAAI,GAAG,KAAK,OAAO,GAAG;EAChD;EAEA,SAAS,eAAe,KAAwB;GAC9C,OAAO,EAAE,2BAA2B,kBAAkB,EAAE,OAAO,SAAS,GAAG,EAAE,CAAC;EAChF;EAEA,MAAM,eAAe,eAAe;GAClC,MAAM,SAAS,eAAe;GAC9B,IAAI,OAAO,WAAW,GACpB,OAAO;GAET,IAAI,CAAC,MAAM,UAAU;IACnB,IAAI,MAAM,iBAAiB,QAAQ;KACjC,MAAM,OAAO,mBAAmB;KAChC,IAAI,MAAM,QACR,OAAO,KAAK,KAAK,KAAK;IAC1B;IACA,OAAO,OAAO;GAChB;GAEA,IAAI,OAAO,WAAW,GACpB,OAAO,OAAO;GAChB,OAAO,GAAG,OAAO,GAAG,IAAI,OAAO,SAAS;EAC1C,CAAC;EAED,MAAM,eAAe,eAAe,aAAa,MAAM,SAAS,CAAC;;EAGjE,MAAM,UAAU,eAAe,CAAC,MAAM,YAAY,MAAM,MAAM,UAAU,KAAK,CAAC;EAE9E,MAAM,4BAA4B,eAAe;GAC/C,OAAO,MAAM,qBAAqB,EAAE,mCAAmC,SAAS;EAClF,CAAC;EAED,MAAM,eAAe,yBAAyB,MAAM,MAAM,EAAE,WAAW,eAAe,CAAC;EAEvF,MAAM,YAAY,eAAe;GAC/B,OAAO,kBAAkB;IACvB,MAAM,aAAa;IACnB,OAAO,MAAM;IACb,SAAS,UAAU;IACnB,UAAU,WAAW;GACvB,CAAC;EACH,CAAC;EAED,MAAM,eAAe,eAAe;GAClC,OAAO;EACT,CAAC;EAED,MAAM,0BAAuD;GAC3D,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;EACN;EAEA,MAAM,QAAQ,SAAS;EAEvB,MAAM,EACJ,WACA,WACA,UACA,UACA,aACA,aACA,cAAc,iBACZ,uBAAuB,OAAO;GAChC,uBAAuB,wBAAwB,aAAa;GAC5D,gBAAgB,SAAS,aAAa;GAGtC,uBAAwB,MAAM,SAAS,oBAAoB;EAC7D,CAAC;EAID,MAAM,oBAAoB,gBAAgB;GACxC,MAAM,UAAU,QAAQ,aAAa,MAAM,cAAc,KAAA;GACzD,OAAO,UAAU,QAAQ,aAAa,MAAM,eAAe,KAAA;EAC7D,EAAE;EAEF,SAAS,QAAQ,MAAe;GAC9B,IAAI,WAAW,SAAS,WAAW,OACjC;GAEF,aAAa,IAAI;EACnB;EAEA,SAAS,iBAAuB;GAC9B,QAAQ,KAAK;EACf;EAEA,SAAS,eAAqB;GAC5B,QAAQ,IAAI;EACd;;;;;;EAOA,IAAI,oBAAoB;EAExB,SAAS,gBAAsB;GAC7B,oBAAoB;GACpB,QAAQ,KAAK;GACb,iBAAiB;IACf,oBAAoB;GACtB,GAAG,CAAC;EACN;EAEA,SAAS,iBAAuB;GAC9B,QAAQ,CAAC,KAAK,KAAK;EACrB;EAIA,SAAS,uBAA6B;GACpC,0BAA0B;GAC1B,iBAAiB;IACf,0BAA0B;GAC5B,GAAG,CAAC;EACN;EAEA,SAAS,iBAAuB;GAC9B,IAAI,2BAA2B,mBAC7B;GACF,aAAa;EACf;EAGA,gBAAgB,MAAM,eAAe,EAAE,MAAM,QAAQ,CAAC;EAEtD,MACE,MACA,OAAO,WAAW;GAChB,IAAI,CAAC,QAAQ;IACX,IAAI,YAAY,MAAM,KAAK,CAAC,CAAC,SAAS,GACpC,YAAY,QAAQ;IACtB;GACF;GAIA,IAAI,CAAC,MAAM,UAAU;IACnB,MAAM,IAAI,MAAM;IAChB,IAAI,KAAK,QAAQ,CAAC,MAAM,QAAQ,CAAC,GAC/B,QAAQ,OAAO,cAAc,CAAC;GAClC;GAEA,IAAI,MAAM,YAAY;IACpB,MAAM,SAAS;IACf,eAAe,OAAO,MAAM;GAC9B;EACF,GACA,EAAE,WAAW,KAAK,CACpB;EAEA,YACQ,MAAM,aACX,MAAM;GACL,IAAI,MAAM,UACR;GACF,IAAI,KAAK,QAAQ,MAAM,QAAQ,CAAC,GAAG;IACjC,QAAQ,OAAO,cAAc,KAAA,CAAS;IACtC;GACF;GACA,QAAQ,OAAO,cAAc,CAAC;EAChC,CACF;EAEA,MACE,cACC,MAAM;GACL,QAAQ,OAAO,OAAO,CAAC;EACzB,CACF;EAEA,SAAS,UAAU,MAA8B;GAC/C,KAAK,qBAAqB,IAAI;GAC9B,KAAK,UAAU,IAAI;EACrB;EAEA,SAAS,QAAc;GACrB,IAAI,WAAW,SAAS,WAAW,OACjC;GAGF,UADqC,MAAM,WAAW,CAAC,IAAI,IAC7C;GACd,KAAK,OAAO;GACZ,IAAI,CAAC,MAAM,UACT,QAAQ,OAAO,cAAc,KAAA,CAAS;EAC1C;;;;;;;EAQA,eAAe,YAA8B;GAC3C,IAAI,CAAC,KAAK,OACR,OAAO;GAET,MAAM,SAAS;GACf,OAAO,QAAQ,OAAO,MAAM,KAAK;EACnC;EAEA,SAAS,iBAAiB,GAAwB;GAChD,IAAI,WAAW,OACb;GAEF,IAAI,EAAE,QAAQ,UAAU;IACtB,EAAE,eAAe;IACjB,cAAc;IACd;GACF;GAEA,IAAI,EAAE,QAAQ,eAAe,EAAE,QAAQ,aAAa,EAAE,QAAQ,WAAW,EAAE,QAAQ,KAAK;IACtF,EAAE,eAAe;IACjB,aAAa;IAIb,IAAI,CAAC,MAAM,YACT,UAAe;GACnB;EACF;;EAGA,SAAS,gBAAgB,GAAwB;GAC/C,IAAI,EAAE,QAAQ,eAAe,EAAE,QAAQ,WACrC;GAEF,EAAE,eAAe;GACjB,UAAe;EACjB;;EAGA,SAAS,eAAe,GAAwB;GAC9C,IAAI,EAAE,QAAQ,OACZ,cAAc;EAClB;EAIA,MAAM,eAAe,eAAe,MAAM,YAAY,MAAM,YAAY;EAIxE,SAAS,cAAc,MAAyB;GAC9C,IAAI,WAAW,SAAS,WAAW,OACjC;GAEF,UAAU,CAAC,GAAG,IAAI,CAAC;EACrB;;;;;;;EAQA,SAAS,UAAU,KAAsB;GACvC,IAAI,WAAW,SAAS,WAAW,OACjC;GAEF,IAAI,aAAa,OAAO;IACtB,QAAQ,OAAO,WAAW,KAAK,KAAK;IACpC;GACF;GAEA,UAAU,aAAa,MAAM,QAAO,MAAK,MAAM,GAAG,CAAC;EACrD;EAEA,SAAS,YAAY,MAAS,MAA2B;GACvD,KAAK,aAAa,MAAM,IAAI;GAE5B,IAAI,WAAW,OACb;GAEF,IAAI,aAAa,OAAO;IAGtB,QAAQ,OAAO,WAAW,KAAK,KAAK,CAAC,eAAe,MAAM,IAAI,KAAK,GAAG,CAAC;IACvE;GACF;GAEA,IAAI,MAAM,UAAU;IAClB,MAAM,OAAO,IAAI,IAAI,eAAe,KAAK;IACzC,IAAI,KAAK,IAAI,KAAK,GAAG,GACnB,KAAK,OAAO,KAAK,GAAG;SAEpB,KAAK,IAAI,KAAK,GAAG;IACnB,UAAU,CAAC,GAAG,IAAI,CAAC;IAEnB,IAAI,sBAAsB,OACxB,cAAc;IAEhB;GACF;GAEA,UAAU,KAAK,GAAG;GAClB,IAAI,sBAAsB,OACxB,cAAc;EAElB;EAIA,MAAM,EAAE,QAAQ,cAAc,SAAS,oBAAoB,gBAAgB;EAM3E,MAAM,aAAa,gBAAgB;;GAIjC,OAAA,gBAAA,UAAA,GAAA,mBA6QM,OAAA;IA5QA,SAAA;IAAJ,KAAI;IAEJ,uBAAA;IACA,OAAM;IACJ,WAAO,OAAA,OAAA,OAAA,MAAE,GAAA,SAAA,MAAA,SAAA,KAAA,MAAA,SAAA,CAAA,CAAA,GAAA,IAAA;IACV,YAAQ,OAAA,OAAA,OAAA,MAAE,GAAA,SAAA,MAAA,UAAA,KAAA,MAAA,UAAA,CAAA,CAAA,GAAA,IAAA;;IAGK,QAAA,QACd,UAAA,IAAA,GAAA,mBAMC,UAAA,EAAA,KAAA,EAAA,GAAA,WALe,aAAA,QAAP,QAAG;KADZ,OAAA,UAAA,GAAA,mBAMC,SAAA;MAJE,KAAG,UAAY,OAAO,GAAG;MAC1B,MAAK;MACJ,MAAM,QAAA;MACN,OAAO,OAAO,GAAG;;;IAGtB,mBA4IM,OA5IN,YA4IM;KA1II,MAAA,SAAA,KADR,UAAA,GAAA,mBASM,OAAA;;MAPA,SAAA;MAAJ,KAAI;MACJ,8BAAA;MACA,OAAM;MACL,OAAK,eAAE,MAAA,WAAA,CAAW;MACnB,eAAY;KAEZ,GAAA,CAAA,WAAsB,KAAA,QAAA,QAAA,CAAA,GAAA,CAAA,KAAA,mBAAA,IAAA,IAAA;KAGxB,mBA0BC,SAAA;MAzBE,IAAI,QAAA;MACD,SAAA;MAAJ,KAAI;MACJ,eAAY;MACZ,+BAAA;MACA,MAAK;MACJ,OAAO,aAAA;MACP,aAAa,QAAA;MACb,UAAU,MAAA,UAAA;MACX,UAAA;MACA,MAAK;MACL,iBAAc;MACd,iBAAc;MACb,iBAAe,MAAA,IAAA,IAAI,SAAA;MACnB,iBAAe,MAAA,IAAA,KAAQ,QAAA,QAAU,SAAS,KAAA;MAC1C,gBAAc,MAAA,SAAA,IAAS,SAAY,KAAA;MACnC,iBAAe,MAAA,UAAA,IAAU,SAAY,KAAA;MACrC,oBAAkB,YAAA;MAClB,cAAY,QAAA;MACb,OAAK,eAAA,CAAC,2NAAyN,CACtN,UAAA,OAAWA,KAAAA,OAAO,SAAS,QAAA,QAAO,kDAAA,EAAA,CAAA,CAAA;MAC1C,OAAK,eAAE,MAAA,YAAA,CAAY;MACnB,eAAa;MACb,SAAO;MACP,SAAO;MACP,WAAS;;KAIJ,YAAA,SADR,UAAA,GAAA,mBAQO,QAAA;;MANL,6BAAA;MACA,OAAK,eAAA,CAAC,6CACE,eAAA,KAAc,CAAA;MACtB,eAAY;KAEZ,GAAA,EAAA,UAAA,GAAA,YAA6C,wBAA7B,UAAA,KAAS,GAAA,EAAE,OAAM,UAAS,CAAA,EAAA,GAAA,CAAA,KAAA,mBAAA,IAAA,IAAA;KAGhC,YAAA,SAAZ,UAAA,GAAA,mBAAgH,QAAA;;MAAtF,IAAI,MAAA,WAAA;MAAa,kCAAA;MAA+B,OAAM;KAAa,GAAA,gBAAA,UAAA,KAAS,GAAA,GAAA,UAAA,KAAA,mBAAA,IAAA,IAAA;KAG9F,QAAA,aAAa,aAAA,SAAY,CAAK,QAAA,YAAQ,CAAK,MAAA,UAAA,KADnD,UAAA,GAAA,mBAUS,UAAA;;MARP,eAAY;MACZ,6BAAA;MACA,MAAK;MACL,OAAM;MACL,cAAY,MAAA,CAAA,CAAC,CAAA,mBAAA,OAAA;MACb,SAAK,cAAO,OAAK,CAAA,MAAA,CAAA;KAElB,GAAA,CAAA,YAAyD,MAAA,SAAA,GAAA;MAAlD,OAAM;MAAuB,eAAY;KAGlD,CAAA,CAAA,GAAA,GAAA,UAAA,MAAA,UAAA,GAAA,mBAWO,QAXP,YAWO,CALL,YAIE,MAAA,oBAAA,GAAA;MAHA,OAAK,eAAA,CAAC,gFACE,MAAA,IAAA,IAAI,eAAA,EAAA,CAAA;MACZ,eAAY;;KAKR,MAAA,SAAA,KADR,UAAA,GAAA,mBAUM,OAAA;;MARA,SAAA;MAAJ,KAAI;MACJ,8BAAA;MACA,OAAK,eAAA,CAAC,wKACE,QAAA,cAAW,oBAAA,EAAA,CAAA;MAClB,OAAK,eAAE,MAAA,WAAA,CAAW;MACnB,eAAY;KAEZ,GAAA,CAAA,WAAsB,KAAA,QAAA,QAAA,CAAA,GAAA,CAAA,KAAA,mBAAA,IAAA,IAAA;KAQhB,QAAA,SADR,UAAA,GAAA,mBAgCM,OAAA;;MA9BJ,4BAAA;MACA,OAAM;MACL,OAAK,eAAE,kBAAA,KAAiB;KAEzB,GAAA,EAAA,UAAA,IAAA,GAAA,mBAcS,UAAA,MAAA,WAbO,eAAA,QAAP,QAAG;MADZ,OAAA,UAAA,GAAA,YAcS,gBAAA;OAZN,KAAG,OAAS,OAAO,GAAG;OACvB,2BAAA;OACA,OAAM;OACL,MAAM,QAAA;OACN,MAAM,QAAA;OACN,MAAM,SAAA;OACN,QAAQ,QAAA;OACR,UAAQ,CAAG,MAAA,UAAA,KAAU,CAAK,MAAA,UAAA;OAC1B,gBAAc,eAAe,GAAG;OAChC,WAAM,WAAE,UAAU,GAAG;;OAEtB,SAAA,cAAiD,CAAjD,mBAAiD,QAAjD,YAAiD,gBAAvB,SAAS,GAAG,CAAA,GAAA,CAAA,CAAA,CAAA;;;;;;;;;;;KAIhC,CAAA,GAAA,GAAA,IAAA,eAAA,QAAc,KADtB,UAAA,GAAA,YASS,gBAAA;;MAPP,gCAAA;MACC,MAAM,QAAA;MACN,MAAM,QAAA;MACN,MAAM,SAAA;MACN,QAAQ,QAAA;;MACV,SAAA,cACE,CADF,gBAAA,OACE,gBAAG,eAAA,KAAc,GAAA,CAAA,CAAA,CAAA;;;;;;;;KAKdA,KAAAA,OAAO,SADf,UAAA,GAAA,mBAYM,OAAA;;MAVJ,OAAM;MACL,OAAK,eAAE,kBAAA,KAAiB;KAEzB,GAAA,CAAA,WAME,KAAA,QAAA,SAAA;MAJC,OAAO,QAAA;MACP,QAAQ,eAAA;MACR,cAAe,aAAA;MACf,YAAa,mBAAA;;;KAKpB,UAAA,GAAA,YA4GW,UAAA;KA5GA,IAAI,MAAA,YAAA;KAAe,UAAQ,CAAG,MAAA,eAAA;IACvC,GAAA,CAAA,YA0Ga,YAAA;KAzGV,sBAAoB,MAAA,kBAAA,CAAkB,CAAC;KACvC,oBAAkB,MAAA,kBAAA,CAAkB,CAAC;KACrC,kBAAgB,MAAA,kBAAA,CAAkB,CAAC;KACnC,sBAAoB,MAAA,kBAAA,CAAkB,CAAC;KACvC,oBAAkB,MAAA,kBAAA,CAAkB,CAAC;KACrC,kBAAgB,MAAA,kBAAA,CAAkB,CAAC;;KAEpC,SAAA,cAiGM,CAjGN,eAAA,mBAiGM,OAjGN,WAiGM;MA/FA,SAAA;MAAJ,KAAI;MACJ,eAAY;KACJ,GAAA,MAAA,UAAA,GAAU;MAClB,6BAAA;MACA,wBAAA;MACC,OAAO,MAAA,aAAA;MACP,WAAS;KAEV,CAAA,GAAA,CAAA,mBAsFI,OAAA,EAtFE,OAAK,eAAE,aAAA,KAAY,EAAA,GAAA,CACd,QAAA,cAAX,UAAA,GAAA,mBAYM,OAZN,YAYM,CAXJ,YAUE,iBAAA;MATI,SAAA;MAAJ,KAAI;MACK,YAAA,YAAA;MAAA,uBAAA,OAAA,OAAA,OAAA,MAAA,WAAA,YAAW,QAAA;MACpB,eAAY;MACZ,8BAAA;MACA,MAAK;MACJ,WAAW,QAAA;MACX,aAAa,0BAAA;MACd,MAAK;MACJ,WAAS;;;;;KASd,CAAA,CAAA,CAAA,KAAA,mBAAA,IAAA,IAAA,GAAA,mBAiEM,OAAA;MAhEJ,OAAK,eAAA,CAAC,eACE,QAAA,UAAO,KAAA,eAAA,CAAA;MACd,OAAK,eAAE,QAAA,UAAU,KAAA,IAAS,EAAA,WAAA,GAAmB,QAAA,kBAAiB,IAAA,CAAA;KAGvD,GAAA,CAAA,QAAA,WADR,UAAA,GAAA,mBAUM,OAAA;;MARJ,+BAAA;MACA,MAAK;MACJ,OAAK,eAAE,MAAA,sBAAA,CAAsB;KAE9B,GAAA,CAAA,WAGO,KAAA,QAAA,WAAA,CAAA,SAAA,CAFL,YAA0E,MAAA,qBAAA,GAAA;MAAxD,OAAM;MAA6B,eAAY;KACjE,CAAA,GAAA,mBAAyD,QAAA,MAAA,gBAAhD,MAAA,CAAA,CAAC,CAAA,yBAAA,UAAA,CAAA,GAAA,CAAA,CAAA,CAAA,CAAA,GAAA,CAAA,MAIG,QAAA,MAAM,UAAM,OAAA,KAA7B,UAAA,GAAA,mBAIM,OAAA;;MAJsC,OAAK,eAAE,MAAA,sBAAA,CAAsB;KACvE,GAAA,CAAA,WAEO,KAAA,QAAA,SAAA,CAAA,SAAA,CADF,gBAAA,gBAAA,MAAA,CAAA,CAAC,CAAA,uBAAA,SAAA,CAAA,GAAA,CAAA,CAAA,CAAA,CAAA,GAAA,CAAA,MAIR,UAAA,GAAA,YAyCS,MAAA,cAAA,GAAA;;MAvCN,IAAI;MACD,SAAA;MAAJ,KAAI;MACH,MAAM,MAAA,YAAA;MACN,MAAM,QAAA;MACN,OAAO,MAAM;MACb,YAAU,QAAA;MACV,yBAAuB,QAAA;MACvB,sBAAoB,QAAA;MACpB,qBAAiB,CAAG,QAAA;MACpB,SAAS,QAAA;MACT,cAAY,QAAA;MACZ,iBAAe,aAAA;MACf,kBAAgB,QAAA;MAChB,gBAAc,aAAA;MACF;MACZ,wBAAqB;;MAEX,SAAO,SAoBT,EApBa,MAAM,WAAI,CAC9B,WAmBO,KAAA,QAAA,QAAA;OAjBE;OACA;OACN,UAAU,eAAA,MAAe,IAAI,KAAK,GAAG;MAJxC,SAmBO,CAbL,mBAYM,OAZN,YAYM,CARK,CAAA,aAAA,SADT,UAAA,GAAA,mBAOO,QAPP,aAOO,CADY,eAAA,MAAe,IAAI,KAAK,GAAG,KAA5C,UAAA,GAAA,YAAqG,MAAA,aAAA,GAAA;;OAAtD,OAAM;MAEvD,CAAA,KAAA,mBAAA,IAAA,IAAA,CAAA,CAAA,KAAA,mBAAA,IAAA,IAAA,GAAA,mBAA8C,QAA9C,aAA8C,gBAApB,KAAK,KAAK,GAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;;;;;;;;;;;;;;;KAzFtC,CAAA,EAAA,GAAA,CAAA,CAAA,GAAA,CAAA,CAAA,GAAA,EAAA,GAAA,CAAA,CAAA,OAAA,MAAA,IAAA,CAAI,CAAA,CAAA,CAAA,CAAA;;;;;;;;;;GAxKU,GAAA,EAAA,IAAA,CAAA,CAAA,MAAA,aAAA,GAAA;IAAA,SAAA;IAAc,SAAW,MAAA,IAAA;IAAI,SAAW;GAAmB,CAAA,CAAA,CAAA"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { n as grTreeSelectSafelist, t as grTreeSelectConfig } from "../../chunks/config-
|
|
2
|
-
import { t as GrTreeSelect_default } from "./chunks/GrTreeSelect-
|
|
1
|
+
import { n as grTreeSelectSafelist, t as grTreeSelectConfig } from "../../chunks/config-CvtqB4ki.js";
|
|
2
|
+
import { t as GrTreeSelect_default } from "./chunks/GrTreeSelect-BHq-T8wH.js";
|
|
3
3
|
export { GrTreeSelect_default as GrTreeSelect, GrTreeSelect_default as default, grTreeSelectConfig, grTreeSelectSafelist };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as floatingLayerZIndex } from "../chunks/overlayStack-
|
|
1
|
+
import { t as floatingLayerZIndex } from "../chunks/overlayStack-DCkCgXZP.js";
|
|
2
2
|
import { nextTick, onBeforeUnmount, ref, watch } from "vue";
|
|
3
3
|
import { autoUpdate, computePosition, flip, offset, shift, size } from "@floating-ui/dom";
|
|
4
4
|
//#region src/composables/useFloating.ts
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { computed, hasInjectionContext, inject, reactive } from "vue";
|
|
2
|
+
//#region src/composables/useHotkeys.ts
|
|
3
|
+
function createHotkeysState(hotkeys = {}) {
|
|
4
|
+
return reactive({ hotkeys: { ...hotkeys } });
|
|
5
|
+
}
|
|
6
|
+
/** Ключ provide/inject для app-scoped реестра (устанавливает плагин ниже). */
|
|
7
|
+
var GRANULARITY_HOTKEYS_STATE = Symbol.for("@feugene/granularity/hotkeys-state");
|
|
8
|
+
/**
|
|
9
|
+
* Vue-плагин: даёт каждому приложению собственный реестр через `app.provide`.
|
|
10
|
+
* Обязателен там же, где и у тостов: несколько приложений на странице делили бы
|
|
11
|
+
* один реестр, а на сервере модульное состояние текло бы между запросами.
|
|
12
|
+
*
|
|
13
|
+
* ```ts
|
|
14
|
+
* app.use(granularityHotkeysPlugin, {
|
|
15
|
+
* hotkeys: {
|
|
16
|
+
* 'search.open': { keys: 'mod+k', label: 'Открыть поиск' },
|
|
17
|
+
* 'issues.goto': { keys: 'g i', label: 'Перейти к задачам' },
|
|
18
|
+
* },
|
|
19
|
+
* })
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
var appScopedHotkeysProvided = false;
|
|
23
|
+
var contextFallbackWarned = false;
|
|
24
|
+
var granularityHotkeysPlugin = { install(app, options = {}) {
|
|
25
|
+
appScopedHotkeysProvided = true;
|
|
26
|
+
app.provide(GRANULARITY_HOTKEYS_STATE, createHotkeysState(options.hotkeys));
|
|
27
|
+
} };
|
|
28
|
+
var moduleHotkeysState = null;
|
|
29
|
+
/** Сброс модульного реестра и dev-предупреждения. Внутреннее API — нужно тестам. */
|
|
30
|
+
function resetHotkeysRegistry() {
|
|
31
|
+
moduleHotkeysState = null;
|
|
32
|
+
contextFallbackWarned = false;
|
|
33
|
+
}
|
|
34
|
+
function resolveHotkeysState() {
|
|
35
|
+
if (hasInjectionContext()) {
|
|
36
|
+
const provided = inject(GRANULARITY_HOTKEYS_STATE, null);
|
|
37
|
+
if (provided) return provided;
|
|
38
|
+
}
|
|
39
|
+
if (appScopedHotkeysProvided && !contextFallbackWarned && process.env.NODE_ENV !== "production") {
|
|
40
|
+
contextFallbackWarned = true;
|
|
41
|
+
console.warn("[granularity] useHotkeys() вызван вне setup/inject-контекста: app-scoped реестр granularityHotkeysPlugin недоступен, использован модульный. Оберните вызов: app.runWithContext(() => useHotkeys()).");
|
|
42
|
+
}
|
|
43
|
+
if (!moduleHotkeysState) moduleHotkeysState = createHotkeysState();
|
|
44
|
+
return moduleHotkeysState;
|
|
45
|
+
}
|
|
46
|
+
var warnedIds = /* @__PURE__ */ new Set();
|
|
47
|
+
function useHotkeys() {
|
|
48
|
+
const state = resolveHotkeysState();
|
|
49
|
+
/**
|
|
50
|
+
* Неизвестный id — предупреждение, а не тишина. Молча вернув `undefined`, мы
|
|
51
|
+
* получили бы исчезнувшую подсказку и непривязанный хоткей: оба симптома
|
|
52
|
+
* выглядят как «забыли сделать», и искать причину пришлось бы в чужом коде.
|
|
53
|
+
*/
|
|
54
|
+
function get(id) {
|
|
55
|
+
const definition = state.hotkeys[id];
|
|
56
|
+
if (!definition && process.env.NODE_ENV !== "production" && !warnedIds.has(id)) {
|
|
57
|
+
warnedIds.add(id);
|
|
58
|
+
console.warn(`[granularity] useHotkeys: сочетания с id "${id}" в реестре нет.`);
|
|
59
|
+
}
|
|
60
|
+
return definition;
|
|
61
|
+
}
|
|
62
|
+
function register(id, definition) {
|
|
63
|
+
state.hotkeys[id] = definition;
|
|
64
|
+
warnedIds.delete(id);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Разворачивает `{ id: обработчик }` в карту для `v-hotkey`. Директива про
|
|
68
|
+
* реестр так и не узнаёт — сочетание приезжает к ней строкой, как и раньше, —
|
|
69
|
+
* а источник у привязки и подсказки остаётся один.
|
|
70
|
+
*/
|
|
71
|
+
function byHotkeyId(map) {
|
|
72
|
+
const result = {};
|
|
73
|
+
for (const [id, handler] of Object.entries(map)) {
|
|
74
|
+
const keys = get(id)?.keys;
|
|
75
|
+
if (keys) result[keys] = handler;
|
|
76
|
+
}
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
hotkeys: computed(() => state.hotkeys),
|
|
81
|
+
get,
|
|
82
|
+
register,
|
|
83
|
+
byHotkeyId,
|
|
84
|
+
keysOf: (id) => get(id)?.keys,
|
|
85
|
+
labelOf: (id) => get(id)?.label
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
//#endregion
|
|
89
|
+
export { GRANULARITY_HOTKEYS_STATE, granularityHotkeysPlugin, resetHotkeysRegistry, useHotkeys };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useHotkeys.js","names":[],"sources":["../../src/composables/useHotkeys.ts"],"sourcesContent":["import type { App, InjectionKey } from 'vue'\nimport { computed, hasInjectionContext, inject, reactive } from 'vue'\n\n/**\n * Реестр горячих клавиш приложения: один источник «id → сочетание + подпись».\n *\n * Без него сочетание пишется дважды — в привязке (`v-hotkey`) и в подсказке\n * (`GrKbd`), — и расходится молча: подсказка обещает одно, а срабатывает другое,\n * и заметить это можно только руками.\n *\n * Реестр объявляет **умолчания приложения**. Пользовательские переопределения —\n * состояние приложения, и жить им здесь незачем: кит про них ничего не знает.\n */\n\nexport interface GrHotkeyDefinition {\n /**\n * Сочетание в общем синтаксисе пакета: `'mod+k'` — аккорд, `'g i'` —\n * «G, затем I». Разбор — `parseHotkeySequence`.\n */\n keys: string\n /** Человекочитаемое имя действия: для подсказок и списка сочетаний. */\n label?: string\n}\n\nexport type GrHotkeyRegistry = Record<string, GrHotkeyDefinition>\n\ninterface HotkeysState {\n hotkeys: GrHotkeyRegistry\n}\n\nexport interface GranularityHotkeysPluginOptions {\n hotkeys?: GrHotkeyRegistry\n}\n\nfunction createHotkeysState(hotkeys: GrHotkeyRegistry = {}): HotkeysState {\n return reactive<HotkeysState>({ hotkeys: { ...hotkeys } })\n}\n\n/** Ключ provide/inject для app-scoped реестра (устанавливает плагин ниже). */\nexport const GRANULARITY_HOTKEYS_STATE: InjectionKey<HotkeysState>\n = Symbol.for('@feugene/granularity/hotkeys-state')\n\n/**\n * Vue-плагин: даёт каждому приложению собственный реестр через `app.provide`.\n * Обязателен там же, где и у тостов: несколько приложений на странице делили бы\n * один реестр, а на сервере модульное состояние текло бы между запросами.\n *\n * ```ts\n * app.use(granularityHotkeysPlugin, {\n * hotkeys: {\n * 'search.open': { keys: 'mod+k', label: 'Открыть поиск' },\n * 'issues.goto': { keys: 'g i', label: 'Перейти к задачам' },\n * },\n * })\n * ```\n */\nlet appScopedHotkeysProvided = false\nlet contextFallbackWarned = false\n\nexport const granularityHotkeysPlugin = {\n install(app: App, options: GranularityHotkeysPluginOptions = {}) {\n appScopedHotkeysProvided = true\n app.provide(GRANULARITY_HOTKEYS_STATE, createHotkeysState(options.hotkeys))\n },\n}\n\nlet moduleHotkeysState: HotkeysState | null = null\n\n/** Сброс модульного реестра и dev-предупреждения. Внутреннее API — нужно тестам. */\nexport function resetHotkeysRegistry(): void {\n moduleHotkeysState = null\n contextFallbackWarned = false\n}\n\nfunction resolveHotkeysState(): HotkeysState {\n if (hasInjectionContext()) {\n const provided = inject(GRANULARITY_HOTKEYS_STATE, null)\n if (provided)\n return provided\n }\n\n if (appScopedHotkeysProvided && !contextFallbackWarned && __GR_DEV__) {\n contextFallbackWarned = true\n console.warn(\n '[granularity] useHotkeys() вызван вне setup/inject-контекста: app-scoped реестр '\n + 'granularityHotkeysPlugin недоступен, использован модульный. Оберните вызов: '\n + 'app.runWithContext(() => useHotkeys()).',\n )\n }\n\n if (!moduleHotkeysState)\n moduleHotkeysState = createHotkeysState()\n\n return moduleHotkeysState\n}\n\nconst warnedIds = new Set<string>()\n\nexport function useHotkeys() {\n const state = resolveHotkeysState()\n\n /**\n * Неизвестный id — предупреждение, а не тишина. Молча вернув `undefined`, мы\n * получили бы исчезнувшую подсказку и непривязанный хоткей: оба симптома\n * выглядят как «забыли сделать», и искать причину пришлось бы в чужом коде.\n */\n function get(id: string): GrHotkeyDefinition | undefined {\n const definition = state.hotkeys[id]\n\n if (!definition && __GR_DEV__ && !warnedIds.has(id)) {\n warnedIds.add(id)\n console.warn(`[granularity] useHotkeys: сочетания с id \"${id}\" в реестре нет.`)\n }\n\n return definition\n }\n\n function register(id: string, definition: GrHotkeyDefinition): void {\n state.hotkeys[id] = definition\n warnedIds.delete(id)\n }\n\n /**\n * Разворачивает `{ id: обработчик }` в карту для `v-hotkey`. Директива про\n * реестр так и не узнаёт — сочетание приезжает к ней строкой, как и раньше, —\n * а источник у привязки и подсказки остаётся один.\n */\n function byHotkeyId(map: Record<string, unknown>): Record<string, any> {\n const result: Record<string, any> = {}\n\n for (const [id, handler] of Object.entries(map)) {\n const keys = get(id)?.keys\n if (keys)\n result[keys] = handler\n }\n\n return result\n }\n\n return {\n hotkeys: computed(() => state.hotkeys),\n get,\n register,\n byHotkeyId,\n keysOf: (id: string) => get(id)?.keys,\n labelOf: (id: string) => get(id)?.label,\n }\n}\n"],"mappings":";;AAkCA,SAAS,mBAAmB,UAA4B,CAAC,GAAiB;CACxE,OAAO,SAAuB,EAAE,SAAS,EAAE,GAAG,QAAQ,EAAE,CAAC;AAC3D;;AAGA,IAAa,4BACT,OAAO,IAAI,oCAAoC;;;;;;;;;;;;;;;AAgBnD,IAAI,2BAA2B;AAC/B,IAAI,wBAAwB;AAE5B,IAAa,2BAA2B,EACtC,QAAQ,KAAU,UAA2C,CAAC,GAAG;CAC/D,2BAA2B;CAC3B,IAAI,QAAQ,2BAA2B,mBAAmB,QAAQ,OAAO,CAAC;AAC5E,EACF;AAEA,IAAI,qBAA0C;;AAG9C,SAAgB,uBAA6B;CAC3C,qBAAqB;CACrB,wBAAwB;AAC1B;AAEA,SAAS,sBAAoC;CAC3C,IAAI,oBAAoB,GAAG;EACzB,MAAM,WAAW,OAAO,2BAA2B,IAAI;EACvD,IAAI,UACF,OAAO;CACX;CAEA,IAAI,4BAA4B,CAAC,yBAAA,QAAA,IAAA,aAAA,cAAqC;EACpE,wBAAwB;EACxB,QAAQ,KACN,qMAGF;CACF;CAEA,IAAI,CAAC,oBACH,qBAAqB,mBAAmB;CAE1C,OAAO;AACT;AAEA,IAAM,4BAAY,IAAI,IAAY;AAElC,SAAgB,aAAa;CAC3B,MAAM,QAAQ,oBAAoB;;;;;;CAOlC,SAAS,IAAI,IAA4C;EACvD,MAAM,aAAa,MAAM,QAAQ;EAEjC,IAAI,CAAC,cAAA,QAAA,IAAA,aAAA,gBAA4B,CAAC,UAAU,IAAI,EAAE,GAAG;GACnD,UAAU,IAAI,EAAE;GAChB,QAAQ,KAAK,6CAA6C,GAAG,iBAAiB;EAChF;EAEA,OAAO;CACT;CAEA,SAAS,SAAS,IAAY,YAAsC;EAClE,MAAM,QAAQ,MAAM;EACpB,UAAU,OAAO,EAAE;CACrB;;;;;;CAOA,SAAS,WAAW,KAAmD;EACrE,MAAM,SAA8B,CAAC;EAErC,KAAK,MAAM,CAAC,IAAI,YAAY,OAAO,QAAQ,GAAG,GAAG;GAC/C,MAAM,OAAO,IAAI,EAAE,CAAC,EAAE;GACtB,IAAI,MACF,OAAO,QAAQ;EACnB;EAEA,OAAO;CACT;CAEA,OAAO;EACL,SAAS,eAAe,MAAM,OAAO;EACrC;EACA;EACA;EACA,SAAS,OAAe,IAAI,EAAE,CAAC,EAAE;EACjC,UAAU,OAAe,IAAI,EAAE,CAAC,EAAE;CACpC;AACF"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as removeOverlayLayer, i as pushOverlayLayer, n as layerRootsAbove } from "../chunks/overlayStack-
|
|
1
|
+
import { a as removeOverlayLayer, i as pushOverlayLayer, n as layerRootsAbove } from "../chunks/overlayStack-DCkCgXZP.js";
|
|
2
2
|
import { getCurrentInstance, nextTick, onUnmounted, ref, watch } from "vue";
|
|
3
3
|
//#region src/composables/useOverlayLayer.ts
|
|
4
4
|
/**
|