@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
|
@@ -11,8 +11,8 @@ import { t as _plugin_vue_export_helper_default } from "../../../chunks/_plugin-
|
|
|
11
11
|
import { t as GrButton_default } from "../../GrButton/chunks/GrButton-CS4TqMtG.js";
|
|
12
12
|
import { useDragGesture } from "../../../composables/useDragGesture.js";
|
|
13
13
|
import { useToast } from "../../../composables/useToast.js";
|
|
14
|
-
import { a as SWIPE_THRESHOLD_RATIO, i as SWIPE_DIRECTION, o as
|
|
15
|
-
import { Fragment, Teleport, TransitionGroup, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, mergeProps, nextTick, normalizeClass, normalizeStyle, openBlock, ref, renderList, renderSlot, resolveDynamicComponent, toDisplayString, unref, useSlots, watchEffect, withCtx, withDirectives } from "vue";
|
|
14
|
+
import { a as SWIPE_THRESHOLD_RATIO, c as swipeOpacity, i as SWIPE_DIRECTION, o as collapsedTransform, r as PLACEMENT_CLASS, s as stackDepth } from "../../../chunks/config-B7qZqiUB.js";
|
|
15
|
+
import { Fragment, Teleport, TransitionGroup, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, mergeProps, nextTick, normalizeClass, normalizeStyle, onBeforeUnmount, onMounted, onUpdated, openBlock, ref, renderList, renderSlot, resolveDynamicComponent, toDisplayString, unref, useSlots, watchEffect, withCtx, withDirectives } from "vue";
|
|
16
16
|
import '../styles.css';//#region src/components/GrToaster/GrToaster.vue?vue&type=script&setup=true&lang.ts
|
|
17
17
|
var _hoisted_1 = ["aria-label"];
|
|
18
18
|
var _hoisted_2 = [
|
|
@@ -21,14 +21,13 @@ var _hoisted_2 = [
|
|
|
21
21
|
"role",
|
|
22
22
|
"onKeydown"
|
|
23
23
|
];
|
|
24
|
-
var _hoisted_3 = { class: "
|
|
25
|
-
var _hoisted_4 = { class: "
|
|
26
|
-
var _hoisted_5 = {
|
|
27
|
-
var _hoisted_6 = {
|
|
24
|
+
var _hoisted_3 = { class: "min-w-0 flex-1" };
|
|
25
|
+
var _hoisted_4 = { class: "text-[length:var(--gr-text-sm)] leading-[var(--gr-leading-sm)] font-700" };
|
|
26
|
+
var _hoisted_5 = {
|
|
28
27
|
key: 0,
|
|
29
28
|
class: "mt-0.5 text-[length:var(--gr-text-sm)] leading-[var(--gr-leading-sm)] text-[var(--gr-muted-fg)]"
|
|
30
29
|
};
|
|
31
|
-
var
|
|
30
|
+
var _hoisted_6 = {
|
|
32
31
|
key: 1,
|
|
33
32
|
class: "mt-2 flex flex-wrap gap-2"
|
|
34
33
|
};
|
|
@@ -49,6 +48,10 @@ var GrToaster_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PU
|
|
|
49
48
|
swipeDismiss: {
|
|
50
49
|
type: Boolean,
|
|
51
50
|
default: true
|
|
51
|
+
},
|
|
52
|
+
collapse: {
|
|
53
|
+
type: [Number, Boolean],
|
|
54
|
+
default: 3
|
|
52
55
|
}
|
|
53
56
|
},
|
|
54
57
|
setup(__props, { expose: __expose }) {
|
|
@@ -144,6 +147,79 @@ var GrToaster_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PU
|
|
|
144
147
|
const hovered = ref(false);
|
|
145
148
|
const focusWithin = ref(false);
|
|
146
149
|
const containerEl = ref(null);
|
|
150
|
+
/**
|
|
151
|
+
* Развёрнуто — по тем же двум флагам, что держат `paused`: рука на стеке или
|
|
152
|
+
* фокус внутри. Отдельного сигнала не заводим — читать стопку и не остановить
|
|
153
|
+
* при этом таймеры было бы ловушкой.
|
|
154
|
+
*/
|
|
155
|
+
const expanded = computed(() => hovered.value || focusWithin.value);
|
|
156
|
+
const stacked = computed(() => props.collapse !== false && visibleToasts.value.length > Math.max(1, props.collapse));
|
|
157
|
+
const collapsed = computed(() => stacked.value && !expanded.value);
|
|
158
|
+
/**
|
|
159
|
+
* Высоты тостов: они разные (заголовок, заголовок с текстом, плюс кнопки), а
|
|
160
|
+
* развёрнутая раскладка складывает их накопительно.
|
|
161
|
+
*
|
|
162
|
+
* `offsetHeight`, а не `getBoundingClientRect().height`: свёрнутая карточка
|
|
163
|
+
* уменьшена `scale()`, и рект вернул бы её экранный размер — стопка мерила бы
|
|
164
|
+
* саму себя и с каждым замером сжималась.
|
|
165
|
+
*/
|
|
166
|
+
const toastHeights = ref({});
|
|
167
|
+
let heightObserver = null;
|
|
168
|
+
function measureToasts() {
|
|
169
|
+
const root = containerEl.value;
|
|
170
|
+
if (!root) return;
|
|
171
|
+
const next = {};
|
|
172
|
+
for (const node of root.querySelectorAll("[data-gr-toast]")) {
|
|
173
|
+
const id = node.dataset.toastId;
|
|
174
|
+
if (id && node.offsetHeight > 0) next[id] = node.offsetHeight;
|
|
175
|
+
heightObserver?.observe(node);
|
|
176
|
+
}
|
|
177
|
+
toastHeights.value = next;
|
|
178
|
+
}
|
|
179
|
+
onMounted(() => {
|
|
180
|
+
if (typeof ResizeObserver !== "undefined") heightObserver = new ResizeObserver(() => measureToasts());
|
|
181
|
+
measureToasts();
|
|
182
|
+
});
|
|
183
|
+
onUpdated(measureToasts);
|
|
184
|
+
onBeforeUnmount(() => {
|
|
185
|
+
heightObserver?.disconnect();
|
|
186
|
+
heightObserver = null;
|
|
187
|
+
});
|
|
188
|
+
/** Все ли видимые тосты измерены. Пока нет — раскладка остаётся потоком. */
|
|
189
|
+
const measured = computed(() => visibleToasts.value.every((toast) => toastHeights.value[toast.id] > 0));
|
|
190
|
+
/** Абсолютная раскладка включается только когда есть чем считать смещения. */
|
|
191
|
+
const positioned = computed(() => stacked.value && measured.value);
|
|
192
|
+
function expandedOffset(index) {
|
|
193
|
+
let offset = 0;
|
|
194
|
+
for (let i = 0; i < index; i++) offset += (toastHeights.value[visibleToasts.value[i].id] ?? 0) + 12;
|
|
195
|
+
return offset;
|
|
196
|
+
}
|
|
197
|
+
function depthOf(index) {
|
|
198
|
+
return stackDepth(index, visibleToasts.value.length, props.placement);
|
|
199
|
+
}
|
|
200
|
+
/** Высота передней карточки — по ней живёт вся свёрнутая стопка. */
|
|
201
|
+
const frontHeight = computed(() => {
|
|
202
|
+
const heights = visibleToasts.value.map((toast) => toastHeights.value[toast.id] ?? 0);
|
|
203
|
+
return props.placement.startsWith("top") ? heights[0] : heights[heights.length - 1];
|
|
204
|
+
});
|
|
205
|
+
const stackHeight = computed(() => {
|
|
206
|
+
if (!positioned.value) return void 0;
|
|
207
|
+
if (collapsed.value) return `${frontHeight.value}px`;
|
|
208
|
+
const heights = visibleToasts.value.map((toast) => toastHeights.value[toast.id] ?? 0);
|
|
209
|
+
return `${heights.reduce((sum, h) => sum + h, 0) + 12 * (heights.length - 1)}px`;
|
|
210
|
+
});
|
|
211
|
+
/** Карточка лежит за передней: в свёрнутой стопке от неё виден только край. */
|
|
212
|
+
function isBehind(index) {
|
|
213
|
+
return collapsed.value && positioned.value && depthOf(index) > 0;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Содержимое карточек за передней гасится: из-под неё видно 12 пикселей, и в
|
|
217
|
+
* эту полоску попадали обрывок строки и хвост полосы прогресса. Колода должна
|
|
218
|
+
* читаться краями карточек, а не мусором в щели.
|
|
219
|
+
*/
|
|
220
|
+
function toastContentStyle(index) {
|
|
221
|
+
return isBehind(index) ? { opacity: "0" } : void 0;
|
|
222
|
+
}
|
|
147
223
|
const swipingId = ref(null);
|
|
148
224
|
const swipeOffset = ref(0);
|
|
149
225
|
let swipeStartX = 0;
|
|
@@ -212,13 +288,31 @@ var GrToaster_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PU
|
|
|
212
288
|
},
|
|
213
289
|
onCancel: resetSwipe
|
|
214
290
|
});
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
291
|
+
/**
|
|
292
|
+
* Стиль тоста: смахивание и стопка пишут в один `transform`. Двух инлайновых
|
|
293
|
+
* трансформов не бывает — второй затирает первый, и жест отменял бы раскладку.
|
|
294
|
+
*/
|
|
295
|
+
function toastStyle(toast, index) {
|
|
296
|
+
const style = {};
|
|
297
|
+
const transforms = [];
|
|
298
|
+
if (swipingId.value === toast.id) {
|
|
299
|
+
transforms.push(`translateX(${swipeOffset.value}px)`);
|
|
300
|
+
style.opacity = String(swipeOpacity(swipeOffset.value, swipeThreshold));
|
|
301
|
+
if (!swipeReleased.value) style.transition = "none";
|
|
302
|
+
}
|
|
303
|
+
if (positioned.value) {
|
|
304
|
+
const depth = depthOf(index);
|
|
305
|
+
transforms.push(collapsed.value ? collapsedTransform(depth, props.placement) : `translateY(${expandedOffset(index)}px)`);
|
|
306
|
+
style.zIndex = String(visibleToasts.value.length - depth);
|
|
307
|
+
style.transformOrigin = props.placement.startsWith("top") ? "top center" : "bottom center";
|
|
308
|
+
if (collapsed.value && depth > 0 && frontHeight.value > 0) style.height = `${frontHeight.value}px`;
|
|
309
|
+
if (collapsed.value && depth > 2) {
|
|
310
|
+
style.opacity = "0";
|
|
311
|
+
style.pointerEvents = "none";
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
if (transforms.length > 0) style.transform = transforms.join(" ");
|
|
315
|
+
return Object.keys(style).length > 0 ? style : void 0;
|
|
222
316
|
}
|
|
223
317
|
/**
|
|
224
318
|
* Клавиатурный эквивалент смахивания. `Escape` намеренно не берём: тостер не
|
|
@@ -240,6 +334,30 @@ var GrToaster_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PU
|
|
|
240
334
|
return TONE_META[tone] ?? TONE_META.info;
|
|
241
335
|
}
|
|
242
336
|
const containerClass = computed(() => PLACEMENT_CLASS[props.placement]);
|
|
337
|
+
const listClass = computed(() => positioned.value ? "relative transition-[height] duration-[var(--gr-duration-base)] ease-[var(--gr-ease-out)]" : "grid gap-3");
|
|
338
|
+
const listStyle = computed(() => stackHeight.value ? { height: stackHeight.value } : void 0);
|
|
339
|
+
/**
|
|
340
|
+
* В стопке карточка вынута из потока, а её место задаёт трансформ — он и
|
|
341
|
+
* обязан ехать плавно. В обычной колонке переход не нужен: там позицию держит
|
|
342
|
+
* сама раскладка, а сдвиги отрабатывает `move-class` группы.
|
|
343
|
+
*/
|
|
344
|
+
const toastLayoutClass = computed(() => positioned.value ? "absolute inset-x-0 top-0 transition-[transform,opacity] duration-[var(--gr-duration-base)] ease-[var(--gr-ease-out)]" : "relative");
|
|
345
|
+
/**
|
|
346
|
+
* В стопке перемещение группы выключается. `TransitionGroup` двигает детей
|
|
347
|
+
* приёмом FLIP: сам пишет в инлайновый `transform` и по концу перехода
|
|
348
|
+
* **очищает** его — то есть стирает раскладку стопки. Класс без перехода
|
|
349
|
+
* трансформа отключает проверку `hasCSSTransform`, и до записи дело не доходит.
|
|
350
|
+
*/
|
|
351
|
+
const moveClass = computed(() => positioned.value ? "transition-none" : "transition-transform duration-[var(--gr-duration-base)] ease-[var(--gr-ease-out)]");
|
|
352
|
+
/**
|
|
353
|
+
* В стопке появление и уход красятся только прозрачностью: `translate-y-*` из
|
|
354
|
+
* классов группы спорил бы с инлайновым трансформом раскладки, а инлайновый
|
|
355
|
+
* сильнее — сдвиг всё равно не сыграл бы.
|
|
356
|
+
*/
|
|
357
|
+
const enterFromClass = computed(() => positioned.value ? "opacity-0" : "opacity-0 translate-y-2");
|
|
358
|
+
const enterToClass = computed(() => positioned.value ? "opacity-100" : "opacity-100 translate-y-0");
|
|
359
|
+
const leaveFromClass = computed(() => positioned.value ? "opacity-100" : "opacity-100 translate-y-0");
|
|
360
|
+
const leaveToClass = computed(() => positioned.value ? "opacity-0" : "opacity-0 translate-y-2");
|
|
243
361
|
const containerStyle = computed(() => {
|
|
244
362
|
if (props.width === void 0) return void 0;
|
|
245
363
|
return { "--gr-toaster-width": typeof props.width === "number" ? `${props.width}px` : props.width };
|
|
@@ -286,16 +404,17 @@ var GrToaster_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PU
|
|
|
286
404
|
onFocusout: _cache[4] || (_cache[4] = ($event) => focusWithin.value = false)
|
|
287
405
|
}), [createVNode(TransitionGroup, {
|
|
288
406
|
tag: "div",
|
|
289
|
-
class:
|
|
407
|
+
class: normalizeClass(listClass.value),
|
|
408
|
+
style: normalizeStyle(listStyle.value),
|
|
290
409
|
"enter-active-class": "transition duration-[var(--gr-duration-base)] ease-[var(--gr-ease-out)]",
|
|
291
|
-
"enter-from-class":
|
|
292
|
-
"enter-to-class":
|
|
410
|
+
"enter-from-class": enterFromClass.value,
|
|
411
|
+
"enter-to-class": enterToClass.value,
|
|
293
412
|
"leave-active-class": "transition duration-[var(--gr-duration-fast)] ease-[var(--gr-ease-in)] absolute",
|
|
294
|
-
"leave-from-class":
|
|
295
|
-
"leave-to-class":
|
|
296
|
-
"move-class":
|
|
413
|
+
"leave-from-class": leaveFromClass.value,
|
|
414
|
+
"leave-to-class": leaveToClass.value,
|
|
415
|
+
"move-class": moveClass.value
|
|
297
416
|
}, {
|
|
298
|
-
default: withCtx(() => [(openBlock(true), createElementBlock(Fragment, null, renderList(visibleToasts.value, (toast) => {
|
|
417
|
+
default: withCtx(() => [(openBlock(true), createElementBlock(Fragment, null, renderList(visibleToasts.value, (toast, index) => {
|
|
299
418
|
return openBlock(), createElementBlock("div", {
|
|
300
419
|
key: toast.id,
|
|
301
420
|
"data-gr-toast": "",
|
|
@@ -304,11 +423,14 @@ var GrToaster_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PU
|
|
|
304
423
|
role: metaFor(toast.tone).role,
|
|
305
424
|
"aria-atomic": "true",
|
|
306
425
|
tabindex: "-1",
|
|
307
|
-
class: normalizeClass(["
|
|
308
|
-
style: normalizeStyle(
|
|
426
|
+
class: normalizeClass(["overflow-hidden rounded-[var(--gr-radius-lg)] border border-[var(--gr-brd)] bg-[var(--gr-card)] px-4 py-3 shadow-[var(--gr-shadow-2)] focus-visible:outline-none focus-visible:shadow-[var(--gr-shadow-2),0_0_0_2px_var(--gr-ring)]", [__props.swipeDismiss ? "[touch-action:pan-y]" : "", toastLayoutClass.value]]),
|
|
427
|
+
style: normalizeStyle(toastStyle(toast, index)),
|
|
309
428
|
onPointerdown: _cache[0] || (_cache[0] = (...args) => unref(swipe).start && unref(swipe).start(...args)),
|
|
310
429
|
onKeydown: ($event) => onToastKeydown($event, toast)
|
|
311
|
-
}, [createElementVNode("div",
|
|
430
|
+
}, [createElementVNode("div", {
|
|
431
|
+
class: "flex items-start gap-3 transition-opacity duration-[var(--gr-duration-base)] ease-[var(--gr-ease-out)]",
|
|
432
|
+
style: normalizeStyle(toastContentStyle(index))
|
|
433
|
+
}, [
|
|
312
434
|
createVNode(unref(GrIcon_default), {
|
|
313
435
|
size: "md",
|
|
314
436
|
class: "mt-0.5",
|
|
@@ -317,10 +439,10 @@ var GrToaster_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PU
|
|
|
317
439
|
default: withCtx(() => [(openBlock(), createBlock(resolveDynamicComponent(metaFor(toast.tone).icon)))]),
|
|
318
440
|
_: 2
|
|
319
441
|
}, 1032, ["style"]),
|
|
320
|
-
createElementVNode("div",
|
|
321
|
-
createElementVNode("div",
|
|
322
|
-
toast.message ? (openBlock(), createElementBlock("div",
|
|
323
|
-
hasActions(toast) ? (openBlock(), createElementBlock("div",
|
|
442
|
+
createElementVNode("div", _hoisted_3, [
|
|
443
|
+
createElementVNode("div", _hoisted_4, toDisplayString(toast.title), 1),
|
|
444
|
+
toast.message ? (openBlock(), createElementBlock("div", _hoisted_5, toDisplayString(toast.message), 1)) : createCommentVNode("", true),
|
|
445
|
+
hasActions(toast) ? (openBlock(), createElementBlock("div", _hoisted_6, [renderSlot(_ctx.$slots, "actions", {
|
|
324
446
|
toast,
|
|
325
447
|
dismiss: () => unref(dismiss)(toast.id)
|
|
326
448
|
}, () => [(openBlock(true), createElementBlock(Fragment, null, renderList(toastActions(toast), (action, index) => {
|
|
@@ -353,7 +475,7 @@ var GrToaster_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PU
|
|
|
353
475
|
})]),
|
|
354
476
|
_: 1
|
|
355
477
|
}, 8, ["aria-label", "onClick"])
|
|
356
|
-
]), toast.timeoutMs > 0 ? (openBlock(), createElementBlock("div", {
|
|
478
|
+
], 4), toast.timeoutMs > 0 ? (openBlock(), createElementBlock("div", {
|
|
357
479
|
key: 0,
|
|
358
480
|
"data-gr-toast-progress": "",
|
|
359
481
|
"aria-hidden": "true",
|
|
@@ -361,14 +483,23 @@ var GrToaster_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PU
|
|
|
361
483
|
style: normalizeStyle({
|
|
362
484
|
backgroundColor: metaFor(toast.tone).color,
|
|
363
485
|
animationDuration: `${toast.timeoutMs}ms`,
|
|
364
|
-
animationPlayState: paused.value ? "paused" : "running"
|
|
486
|
+
animationPlayState: paused.value ? "paused" : "running",
|
|
487
|
+
...toastContentStyle(index)
|
|
365
488
|
})
|
|
366
489
|
}, null, 4)) : createCommentVNode("", true)], 46, _hoisted_2);
|
|
367
490
|
}), 128))]),
|
|
368
491
|
_: 3
|
|
369
|
-
}
|
|
492
|
+
}, 8, [
|
|
493
|
+
"class",
|
|
494
|
+
"style",
|
|
495
|
+
"enter-from-class",
|
|
496
|
+
"enter-to-class",
|
|
497
|
+
"leave-from-class",
|
|
498
|
+
"leave-to-class",
|
|
499
|
+
"move-class"
|
|
500
|
+
])], 16, _hoisted_1)), [[unref(vHotkey), hotkeyBinding.value]])], 8, ["to", "disabled"]);
|
|
370
501
|
};
|
|
371
502
|
}
|
|
372
|
-
}), [["__scopeId", "data-v-
|
|
503
|
+
}), [["__scopeId", "data-v-185f56c0"]]);
|
|
373
504
|
//#endregion
|
|
374
505
|
export { GrToaster_default as t };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GrToaster-OzT1VKcp.js","names":[],"sources":["../../../../src/components/GrToaster/GrToaster.vue","../../../../src/components/GrToaster/GrToaster.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * GrToaster — GR-примитив области уведомлений (toast).\n *\n * Модель состояния берётся из `useToast`, поэтому в приложении предполагается\n * **один активный `GrToaster`** на корень (или app-scoped через плагин).\n *\n * A11y:\n * - контейнер — `role=\"region\"` с `aria-label` (i18n-проп `regionLabel`);\n * - объявляет каждый тост сам собой: `role=\"status\"`, а критичные\n * (`warning`/`danger`) — ассертивный `role=\"alert\"`. Обёртки-live-region над\n * ними нет намеренно: вложение регионов с разной ассертивностью\n * спецификацией не определено, браузеры и SR расходятся вплоть до потери\n * объявления;\n * - стек достижим с клавиатуры по `focusHotkey` (по умолчанию `F6`) — тосты\n * телепортированы в конец `body`, и без хоткея кнопка «Отменить» лежала бы\n * за пределами разумного числа нажатий `Tab`.\n *\n * UX:\n * - `maxVisible` ограничивает стек; лишние ждут в очереди (их таймеры на паузе);\n * - автозакрытие **останавливается под курсором/фокусом** (WCAG 2.2.1) и\n * визуализируется прогресс-баром до закрытия;\n * - `placement` настраивает угол экрана; слой — `--gr-z-toast`.\n */\nimport { computed, nextTick, onBeforeUnmount, onMounted, onUpdated, ref, useSlots, watchEffect } from 'vue'\n\nimport { usePortalTarget } from '../../composables/usePortalTarget'\nimport type { Component } from 'vue'\n\nimport { useDragGesture } from '../../composables/useDragGesture'\nimport { useToast } from '../../composables/useToast'\nimport { vHotkey } from '../../directives'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport type { GrToastTone, Toast, ToastAction } from '../../composables/useToast'\nimport GrButton from '../GrButton'\nimport GrIcon from '../GrIcon'\nimport {\n collapsedTransform,\n PLACEMENT_CLASS,\n STACK_GAP_PX,\n STACK_PEEK_DEPTH,\n stackDepth,\n SWIPE_DIRECTION,\n SWIPE_FLY_OUT_PX,\n SWIPE_RESISTANCE,\n SWIPE_THRESHOLD_MIN_PX,\n SWIPE_THRESHOLD_RATIO,\n swipeOpacity,\n type GrToasterPlacement,\n} from './grToasterStyles'\n\nimport IconCheck from '~icons/lucide/check-circle'\nimport IconWarning from '~icons/lucide/alert-triangle'\nimport IconError from '~icons/lucide/x-circle'\nimport IconInfo from '~icons/lucide/info'\nimport IconClose from '~icons/lucide/x'\n\nexport type { GrToasterPlacement }\n\ninterface ToneMeta {\n icon: Component\n color: string\n role: 'status' | 'alert'\n}\n\n// Единый маппинг по tone'у: иконка, цвет, a11y-роль. На уровне модуля —\n// чтобы не пересоздавать объект на каждый рендер.\nconst TONE_META: Record<GrToastTone, ToneMeta> = {\n primary: { icon: IconInfo, color: 'var(--gr-primary)', role: 'status' },\n neutral: { icon: IconInfo, color: 'var(--gr-muted-fg)', role: 'status' },\n info: { icon: IconInfo, color: 'var(--gr-info)', role: 'status' },\n success: { icon: IconCheck, color: 'var(--gr-success)', role: 'status' },\n warning: { icon: IconWarning, color: 'var(--gr-warning)', role: 'alert' },\n danger: { icon: IconError, color: 'var(--gr-danger)', role: 'alert' },\n slate: { icon: IconInfo, color: 'var(--gr-slate)', role: 'status' },\n azure: { icon: IconInfo, color: 'var(--gr-azure)', role: 'status' },\n}\n\nexport interface GrToasterProps {\n /** Угол экрана для стека уведомлений. */\n placement?: GrToasterPlacement\n /** Максимум одновременно видимых тостов; остальные ждут в очереди. По умолчанию `4`. */\n maxVisible?: number\n /** A11y-лейбл кнопки закрытия (i18n). */\n dismissLabel?: string\n /** A11y-лейбл контейнера-региона (i18n). */\n regionLabel?: string\n /**\n * Ширина стека. Число — пиксели, строка — любая CSS-длина. Уезжает в\n * `--gr-toaster-width`, поэтому то же самое можно задать и темой.\n */\n width?: string | number\n /**\n * Клавиша перевода фокуса в стек уведомлений; `false` отключает хоткей.\n * `F6` — рекомендация APG для перехода между «регионами» страницы.\n */\n focusHotkey?: string | false\n /**\n * Смахивание тоста к своему краю экрана. Клавиатурный эквивалент — `Delete`\n * и `Backspace` на сфокусированном тосте — остаётся и при выключенном жесте.\n */\n swipeDismiss?: boolean\n /**\n * Со скольких видимых тостов стек схлопывается в стопку: колонка занимает\n * место одного тоста, а остальные выглядывают из-под передней. Разворачивается\n * по наведению и по фокусу. `false` — не схлопывать никогда.\n *\n * Порог, а не переключатель: пока тостов мало, колонка читается лучше стопки,\n * и менять её незачем.\n */\n collapse?: number | false\n}\n\nimport { useGrThemeAttrs } from '../GrConfigProvider/context'\n\nconst props = withDefaults(defineProps<GrToasterProps>(), {\n placement: 'top-right',\n maxVisible: 4,\n dismissLabel: undefined,\n regionLabel: undefined,\n width: undefined,\n focusHotkey: 'F6',\n swipeDismiss: true,\n collapse: 3,\n})\n\n/**\n * Слот `actions` полностью заменяет дефолтные action-кнопки тоста. Получает сам\n * `toast` и `dismiss` — функцию, закрывающую именно этот тост.\n */\ndefineSlots<{\n actions?: (props: { toast: Toast, dismiss: () => void }) => unknown\n}>()\n\nconst { t } = useGranularityTranslations()\nconst slots = useSlots()\nconst resolvedDismissLabel = computed(() => props.dismissLabel ?? t('gr.toaster.dismiss', 'Dismiss'))\nconst resolvedRegionLabel = computed(() => props.regionLabel ?? t('gr.toaster.region', 'Notifications'))\n\nconst { list, dismiss, pause, resume } = useToast()\n\n// Единый список кнопок тоста: `action` (шорткат) + массив `actions`.\nfunction toastActions(toast: Toast): ToastAction[] {\n return [...(toast.action ? [toast.action] : []), ...(toast.actions ?? [])]\n}\n\n// Показываем блок действий, если есть кнопки или задан слот `actions`.\nfunction hasActions(toast: Toast): boolean {\n return Boolean(slots.actions) || toastActions(toast).length > 0\n}\n\n// Клик по action-кнопке тоста: вызываем обработчик и (по умолчанию) закрываем тост.\nfunction onAction(toast: Toast, action: ToastAction): void {\n action.onClick()\n if (action.dismissOnClick !== false)\n dismiss(toast.id)\n}\n\n// SSR-guard: на сервере `document.body` недоступен — отключаем `teleport`.\n// Телепорт включается только ПОСЛЕ монтирования: иначе первый клиентский\n// рендер не совпадает с серверным и ломается гидрация (см. композабл).\nconst { target: portalTarget, enabled: teleportEnabled } = usePortalTarget()\n\n// Тема поддерева на телепортированную панель: в DOM она уезжает в `body`, то\n// есть вне обёртки провайдера, и `data-theme` с неё не наследуется. В дереве\n// компонентов панель остаётся внутри — `inject` доходит, и тему она ставит себе\n// сама.\nconst themeAttrs = useGrThemeAttrs()\n\n// Видимые тосты (не больше `maxVisible`); остальные ждут в очереди. Список\n// хранится новейшими вперёд, поэтому «видимые дожинают, новые ждут» — это\n// хвост: старейшие N. Взяв голову, стек показывал бы новейшие, и каждый пуш\n// вытеснял бы с экрана тост, который пользователь ещё читает.\nconst visibleToasts = computed(() => list.value.slice(-Math.max(1, props.maxVisible)))\nconst visibleIds = computed(() => new Set(visibleToasts.value.map(toast => toast.id)))\n\n// Пауза под курсором/фокусом (WCAG 2.2.1). Флага два и они независимы: один\n// `paused` терялся на «фокус внутри + мышь прошла насквозь» — `mouseleave`\n// возобновлял отсчёт под клавиатурным фокусом.\nconst hovered = ref(false)\nconst focusWithin = ref(false)\n\n// Контейнер стека: по нему ищутся тосты — и для фокуса, и для жеста.\nconst containerEl = ref<HTMLElement | null>(null)\n\n// ————— Стопка.\n\n/**\n * Развёрнуто — по тем же двум флагам, что держат `paused`: рука на стеке или\n * фокус внутри. Отдельного сигнала не заводим — читать стопку и не остановить\n * при этом таймеры было бы ловушкой.\n */\nconst expanded = computed(() => hovered.value || focusWithin.value)\nconst stacked = computed(() => props.collapse !== false && visibleToasts.value.length > Math.max(1, props.collapse))\nconst collapsed = computed(() => stacked.value && !expanded.value)\n\n/**\n * Высоты тостов: они разные (заголовок, заголовок с текстом, плюс кнопки), а\n * развёрнутая раскладка складывает их накопительно.\n *\n * `offsetHeight`, а не `getBoundingClientRect().height`: свёрнутая карточка\n * уменьшена `scale()`, и рект вернул бы её экранный размер — стопка мерила бы\n * саму себя и с каждым замером сжималась.\n */\nconst toastHeights = ref<Record<string, number>>({})\n\nlet heightObserver: ResizeObserver | null = null\n\nfunction measureToasts(): void {\n const root = containerEl.value\n if (!root)\n return\n\n const next: Record<string, number> = {}\n for (const node of root.querySelectorAll<HTMLElement>('[data-gr-toast]')) {\n const id = node.dataset.toastId\n // В jsdom высота нулевая: раскладка обязана это пережить, поэтому нули не\n // запоминаются, а потребитель значения падает на запасной путь.\n if (id && node.offsetHeight > 0)\n next[id] = node.offsetHeight\n\n heightObserver?.observe(node)\n }\n\n toastHeights.value = next\n}\n\nonMounted(() => {\n if (typeof ResizeObserver !== 'undefined')\n heightObserver = new ResizeObserver(() => measureToasts())\n\n measureToasts()\n})\n\n// Замер до отрисовки кадра: содержимое тоста меняется на месте (`update`,\n// `toast.promise`), и без этого стопка кадр стояла бы по старым высотам.\nonUpdated(measureToasts)\n\nonBeforeUnmount(() => {\n heightObserver?.disconnect()\n heightObserver = null\n})\n\n/** Все ли видимые тосты измерены. Пока нет — раскладка остаётся потоком. */\nconst measured = computed(() => visibleToasts.value.every(toast => toastHeights.value[toast.id] > 0))\n\n/** Абсолютная раскладка включается только когда есть чем считать смещения. */\nconst positioned = computed(() => stacked.value && measured.value)\n\nfunction expandedOffset(index: number): number {\n let offset = 0\n for (let i = 0; i < index; i++)\n offset += (toastHeights.value[visibleToasts.value[i].id] ?? 0) + STACK_GAP_PX\n\n return offset\n}\n\nfunction depthOf(index: number): number {\n return stackDepth(index, visibleToasts.value.length, props.placement)\n}\n\n/** Высота передней карточки — по ней живёт вся свёрнутая стопка. */\nconst frontHeight = computed(() => {\n const heights = visibleToasts.value.map(toast => toastHeights.value[toast.id] ?? 0)\n return props.placement.startsWith('top') ? heights[0] : heights[heights.length - 1]\n})\n\nconst stackHeight = computed(() => {\n if (!positioned.value)\n return undefined\n\n if (collapsed.value)\n return `${frontHeight.value}px`\n\n const heights = visibleToasts.value.map(toast => toastHeights.value[toast.id] ?? 0)\n return `${heights.reduce((sum, h) => sum + h, 0) + STACK_GAP_PX * (heights.length - 1)}px`\n})\n\n/** Карточка лежит за передней: в свёрнутой стопке от неё виден только край. */\nfunction isBehind(index: number): boolean {\n return collapsed.value && positioned.value && depthOf(index) > 0\n}\n\n/**\n * Содержимое карточек за передней гасится: из-под неё видно 12 пикселей, и в\n * эту полоску попадали обрывок строки и хвост полосы прогресса. Колода должна\n * читаться краями карточек, а не мусором в щели.\n */\nfunction toastContentStyle(index: number): Record<string, string> | undefined {\n return isBehind(index) ? { opacity: '0' } : undefined\n}\n\n// ————— Смахивание.\n\nconst swipingId = ref<string | null>(null)\nconst swipeOffset = ref(0)\nlet swipeStartX = 0\nlet swipeThreshold = SWIPE_THRESHOLD_MIN_PX\n\n// Тост, который тянут, тоже держит таймеры: иначе уведомление сгорало бы прямо\n// под пальцем, посреди жеста.\nconst paused = computed(() => hovered.value || focusWithin.value || swipingId.value !== null)\n\nfunction toastElement(id: string): HTMLElement | null {\n return containerEl.value?.querySelector<HTMLElement>(`[data-gr-toast][data-toast-id=\"${id}\"]`) ?? null\n}\n\n/** Жест отпущен и тост закрывается: переход снова разрешён (см. `releaseSwiped`). */\nconst swipeReleased = ref(false)\n\nfunction resetSwipe(): void {\n swipingId.value = null\n swipeOffset.value = 0\n swipeReleased.value = false\n}\n\n/**\n * Отпущенный тост уезжает за свой край и только потом закрывается.\n *\n * Два кадра здесь обязательны, и оба по одной причине: уходящий элемент Vue\n * больше не перерисовывает — он уезжает с тем стилем, что был на последнем\n * рендере. Значит и разрешение перехода, и конечную точку нужно успеть отдать\n * до закрытия: первый кадр снимает инлайновый `transition: none` (во время\n * жеста он нужен, иначе переходы группы борются с пальцем), второй задаёт точку\n * отлёта — с этого момента анимация уже идёт, и `leave` подхватывает её на ходу.\n *\n * Закрыв тост сразу, получили бы не отлёт, а мгновенное исчезновение: элемент\n * ушёл бы в `leave` с запрещённым переходом.\n */\nasync function releaseSwiped(id: string): Promise<void> {\n swipeReleased.value = true\n await nextTick()\n\n swipeOffset.value = SWIPE_DIRECTION[props.placement] * SWIPE_FLY_OUT_PX\n await nextTick()\n\n dismiss(id)\n resetSwipe()\n}\n\n/**\n * Движение к своему краю идёт один к одному, в обратную сторону — с\n * сопротивлением: тост едет за пальцем, но закрыть его «наоборот» нельзя.\n */\nfunction resistOffset(delta: number): number {\n const toEdge = SWIPE_DIRECTION[props.placement]\n\n return Math.sign(delta) === toEdge ? delta : delta / SWIPE_RESISTANCE\n}\n\nconst swipe = useDragGesture({\n disabled: () => !props.swipeDismiss,\n onStart: (event) => {\n const target = event.target as HTMLElement | null\n // Нажатие на кнопке — это нажатие на кнопке: закрытие и действия тоста не\n // должны превращаться в протяжку.\n if (target?.closest('button, a[href]'))\n return false\n\n const host = target?.closest<HTMLElement>('[data-gr-toast]')\n const id = host?.dataset.toastId\n if (!host || !id)\n return false\n\n swipingId.value = id\n swipeOffset.value = 0\n swipeStartX = event.clientX\n swipeThreshold = Math.max(SWIPE_THRESHOLD_MIN_PX, host.getBoundingClientRect().width * SWIPE_THRESHOLD_RATIO)\n },\n onMove: (event) => {\n // Против выделения текста тоста во время протяжки.\n event.preventDefault()\n swipeOffset.value = resistOffset(event.clientX - swipeStartX)\n },\n onEnd: () => {\n const id = swipingId.value\n const passed = id !== null\n && Math.sign(swipeOffset.value) === SWIPE_DIRECTION[props.placement]\n && Math.abs(swipeOffset.value) >= swipeThreshold\n\n if (passed)\n void releaseSwiped(id)\n else resetSwipe()\n },\n // Обрыв возвращает тост на место, а не дожимает смахивание: указатель забрал\n // браузер, а не пользователь довёл жест.\n onCancel: resetSwipe,\n})\n\n/**\n * Стиль тоста: смахивание и стопка пишут в один `transform`. Двух инлайновых\n * трансформов не бывает — второй затирает первый, и жест отменял бы раскладку.\n */\nfunction toastStyle(toast: Toast, index: number): Record<string, string> | undefined {\n const style: Record<string, string> = {}\n const transforms: string[] = []\n\n if (swipingId.value === toast.id) {\n // Смахивание идёт первым: трансформы применяются справа налево, и после\n // `scale()` жест ехал бы в масштабе карточки, а не в пикселях экрана.\n transforms.push(`translateX(${swipeOffset.value}px)`)\n style.opacity = String(swipeOpacity(swipeOffset.value, swipeThreshold))\n\n // Переходы группы во время жеста борются с пальцем: тост едет с задержкой\n // и «догоняет» курсор после отпускания. После отпускания запрет снимается —\n // уходящему тосту переход нужен, иначе он не уедет вовсе.\n if (!swipeReleased.value)\n style.transition = 'none'\n }\n\n if (positioned.value) {\n const depth = depthOf(index)\n\n transforms.push(collapsed.value\n ? collapsedTransform(depth, props.placement)\n : `translateY(${expandedOffset(index)}px)`)\n\n style.zIndex = String(visibleToasts.value.length - depth)\n\n /*\n * Уменьшение идёт от того края, которым стопка прижата к углу. По центру\n * (умолчание) карточка теряет высоту с обеих сторон, и соседи разной высоты\n * выглядывают на разное расстояние — колода получается рваной.\n */\n style.transformOrigin = props.placement.startsWith('top') ? 'top center' : 'bottom center'\n\n /*\n * Высота карточек за передней приравнивается к её собственной: иначе более\n * высокий тост выглядывал бы дальше соседа, и шаг колоды плясал бы вместе с\n * длиной сообщения.\n */\n if (collapsed.value && depth > 0 && frontHeight.value > 0)\n style.height = `${frontHeight.value}px`\n\n if (collapsed.value && depth > STACK_PEEK_DEPTH) {\n style.opacity = '0'\n // Почти невидимый край иначе ловил бы клики мимо передней карточки.\n style.pointerEvents = 'none'\n }\n }\n\n if (transforms.length > 0)\n style.transform = transforms.join(' ')\n\n return Object.keys(style).length > 0 ? style : undefined\n}\n\n/**\n * Клавиатурный эквивалент смахивания. `Escape` намеренно не берём: тостер не\n * модальный слой, и перехват закрывал бы уведомление вместо диалога под ним.\n */\nfunction onToastKeydown(event: KeyboardEvent, toast: Toast): void {\n if (event.key !== 'Delete' && event.key !== 'Backspace')\n return\n\n event.preventDefault()\n\n const index = visibleToasts.value.findIndex(item => item.id === toast.id)\n const next = visibleToasts.value[index + 1] ?? visibleToasts.value[index - 1]\n\n dismiss(toast.id)\n\n // Фокус не должен упасть на `body`: дальше по стеку есть что читать.\n if (next)\n void nextTick(() => toastElement(next.id)?.focus())\n}\n\n// Единый источник правды по таймерам: тост тикает, только если он видим И стек не на\n// паузе. Очередь и hover — на паузе. Реагирует на изменения списка/hover.\n//\n// `timeoutMs` читается ради зависимости, а не ради значения: `toast.promise` и\n// `update` перезапускают таймер уже существующего тоста, не трогая ни список, ни\n// паузу. Без этой зависимости эффект не просыпался бы, и заново заведённый\n// таймер тикал бы под курсором или у тоста, который ещё ждёт в очереди, — тот\n// сгорал бы, ни разу не показавшись.\nwatchEffect(() => {\n for (const toast of list.value) {\n const shouldTick = toast.timeoutMs > 0 && visibleIds.value.has(toast.id) && !paused.value\n\n if (shouldTick)\n resume(toast.id)\n else\n pause(toast.id)\n }\n})\n\nfunction metaFor(tone: GrToastTone): ToneMeta {\n return TONE_META[tone] ?? TONE_META.info\n}\n\nconst containerClass = computed(() => PLACEMENT_CLASS[props.placement])\n\nconst listClass = computed(() => (positioned.value\n ? 'relative transition-[height] duration-[var(--gr-duration-base)] ease-[var(--gr-ease-out)]'\n : 'grid gap-3'))\n\nconst listStyle = computed(() => (stackHeight.value ? { height: stackHeight.value } : undefined))\n\n/**\n * В стопке карточка вынута из потока, а её место задаёт трансформ — он и\n * обязан ехать плавно. В обычной колонке переход не нужен: там позицию держит\n * сама раскладка, а сдвиги отрабатывает `move-class` группы.\n */\nconst toastLayoutClass = computed(() => (positioned.value\n ? 'absolute inset-x-0 top-0 transition-[transform,opacity] duration-[var(--gr-duration-base)] ease-[var(--gr-ease-out)]'\n : 'relative'))\n\n/**\n * В стопке перемещение группы выключается. `TransitionGroup` двигает детей\n * приёмом FLIP: сам пишет в инлайновый `transform` и по концу перехода\n * **очищает** его — то есть стирает раскладку стопки. Класс без перехода\n * трансформа отключает проверку `hasCSSTransform`, и до записи дело не доходит.\n */\nconst moveClass = computed(() => (positioned.value\n ? 'transition-none'\n : 'transition-transform duration-[var(--gr-duration-base)] ease-[var(--gr-ease-out)]'))\n\n/**\n * В стопке появление и уход красятся только прозрачностью: `translate-y-*` из\n * классов группы спорил бы с инлайновым трансформом раскладки, а инлайновый\n * сильнее — сдвиг всё равно не сыграл бы.\n */\nconst enterFromClass = computed(() => (positioned.value ? 'opacity-0' : 'opacity-0 translate-y-2'))\nconst enterToClass = computed(() => (positioned.value ? 'opacity-100' : 'opacity-100 translate-y-0'))\nconst leaveFromClass = computed(() => (positioned.value ? 'opacity-100' : 'opacity-100 translate-y-0'))\nconst leaveToClass = computed(() => (positioned.value ? 'opacity-0' : 'opacity-0 translate-y-2'))\n\nconst containerStyle = computed(() => {\n if (props.width === undefined)\n return undefined\n\n return { '--gr-toaster-width': typeof props.width === 'number' ? `${props.width}px` : props.width }\n})\n\n/**\n * Переводит фокус на верхний тост. Тост фокусируем только программно\n * (`tabindex=\"-1\"`): собственной остановкой `Tab` стек быть не должен, иначе\n * всплывающее уведомление перехватывало бы обход страницы.\n */\nfunction focus(): boolean {\n const target = containerEl.value?.querySelector<HTMLElement>('[data-gr-toast]')\n if (!target)\n return false\n\n target.focus()\n return true\n}\n\nconst hotkeyBinding = computed(() => ({\n enabled: props.focusHotkey !== false && visibleToasts.value.length > 0,\n handlers: { [props.focusHotkey || 'F6']: { handler: onFocusHotkey, allowInEditable: true } },\n}))\n\nfunction onFocusHotkey(event: KeyboardEvent): void {\n if (focus())\n event.preventDefault()\n}\n\ndefineExpose({ focus })\n</script>\n\n<template>\n <teleport :to=\"portalTarget\" :disabled=\"!teleportEnabled\">\n <div\n ref=\"containerEl\"\n v-hotkey=\"hotkeyBinding\"\n v-bind=\"themeAttrs\"\n data-gr-toaster\n data-gr-overlay-root\n role=\"region\"\n :aria-label=\"resolvedRegionLabel\"\n class=\"fixed z-[var(--gr-z-toast)] w-[var(--gr-toaster-width,360px)] max-w-[calc(100vw-2rem)]\"\n :class=\"containerClass\"\n :style=\"containerStyle\"\n @mouseenter=\"hovered = true\"\n @mouseleave=\"hovered = false\"\n @focusin=\"focusWithin = true\"\n @focusout=\"focusWithin = false\"\n >\n <TransitionGroup\n tag=\"div\"\n :class=\"listClass\"\n :style=\"listStyle\"\n enter-active-class=\"transition duration-[var(--gr-duration-base)] ease-[var(--gr-ease-out)]\"\n :enter-from-class=\"enterFromClass\"\n :enter-to-class=\"enterToClass\"\n leave-active-class=\"transition duration-[var(--gr-duration-fast)] ease-[var(--gr-ease-in)] absolute\"\n :leave-from-class=\"leaveFromClass\"\n :leave-to-class=\"leaveToClass\"\n :move-class=\"moveClass\"\n >\n <div\n v-for=\"(toast, index) in visibleToasts\"\n :key=\"toast.id\"\n data-gr-toast\n :data-tone=\"toast.tone\"\n :data-toast-id=\"toast.id\"\n :role=\"metaFor(toast.tone).role\"\n aria-atomic=\"true\"\n tabindex=\"-1\"\n class=\"overflow-hidden rounded-[var(--gr-radius-lg)] border border-[var(--gr-brd)] bg-[var(--gr-card)] px-4 py-3 shadow-[var(--gr-shadow-2)] focus-visible:outline-none focus-visible:shadow-[var(--gr-shadow-2),0_0_0_2px_var(--gr-ring)]\"\n :class=\"[swipeDismiss ? '[touch-action:pan-y]' : '', toastLayoutClass]\"\n :style=\"toastStyle(toast, index)\"\n @pointerdown=\"swipe.start\"\n @keydown=\"onToastKeydown($event, toast)\"\n >\n <div\n class=\"flex items-start gap-3 transition-opacity duration-[var(--gr-duration-base)] ease-[var(--gr-ease-out)]\"\n :style=\"toastContentStyle(index)\"\n >\n <GrIcon size=\"md\" class=\"mt-0.5\" :style=\"{ color: metaFor(toast.tone).color }\">\n <component :is=\"metaFor(toast.tone).icon\" />\n </GrIcon>\n <div class=\"min-w-0 flex-1\">\n <div class=\"text-[length:var(--gr-text-sm)] leading-[var(--gr-leading-sm)] font-700\">\n {{ toast.title }}\n </div>\n <div v-if=\"toast.message\" class=\"mt-0.5 text-[length:var(--gr-text-sm)] leading-[var(--gr-leading-sm)] text-[var(--gr-muted-fg)]\">\n {{ toast.message }}\n </div>\n\n <!-- Action-кнопки тоста: например «Отменить»/«Повторить». Можно\n задать массивом (`actions`) или переопределить слотом. -->\n <div v-if=\"hasActions(toast)\" class=\"mt-2 flex flex-wrap gap-2\">\n <slot name=\"actions\" :toast=\"toast\" :dismiss=\"() => dismiss(toast.id)\">\n <GrButton\n v-for=\"(action, index) in toastActions(toast)\"\n :key=\"index\"\n :variant=\"action.variant ?? 'outline'\"\n :size=\"action.size ?? 'sm'\"\n data-gr-toast-action\n @click=\"onAction(toast, action)\"\n >\n {{ action.label }}\n </GrButton>\n </slot>\n </div>\n </div>\n <GrButton\n variant=\"ghost\"\n size=\"sm\"\n square\n :aria-label=\"resolvedDismissLabel\"\n @click=\"dismiss(toast.id)\"\n >\n <GrIcon size=\"sm\">\n <IconClose />\n </GrIcon>\n </GrButton>\n </div>\n\n <!-- Прогресс до автозакрытия; замирает вместе с таймером на паузе. -->\n <div\n v-if=\"toast.timeoutMs > 0\"\n data-gr-toast-progress\n aria-hidden=\"true\"\n class=\"gr-toast-progress absolute bottom-0 left-0 h-[2px] w-full origin-left\"\n :style=\"{\n backgroundColor: metaFor(toast.tone).color,\n animationDuration: `${toast.timeoutMs}ms`,\n animationPlayState: paused ? 'paused' : 'running',\n ...toastContentStyle(index),\n }\"\n />\n </div>\n </TransitionGroup>\n </div>\n </teleport>\n</template>\n\n<style scoped>\n.gr-toast-progress {\n animation-name: gr-toast-progress;\n animation-timing-function: linear;\n animation-fill-mode: forwards;\n}\n\n@keyframes gr-toast-progress {\n from {\n transform: scaleX(1);\n }\n to {\n transform: scaleX(0);\n }\n}\n\n/*\n * Единственная анимация пакета, которую глобальный кламп чинит неверно.\n *\n * У полосы `animation-fill-mode: forwards`, поэтому сжатая до `0.01ms` она не\n * возвращается в исходное состояние, а фиксируется на `scaleX(0)`: таймер\n * выглядит истёкшим, пока тост ещё висит на экране. Полоса — единственный\n * носитель этого смысла, и статичной её оставить нельзя, поэтому под reduce она\n * убирается совсем. Автозакрытие ведёт JS-таймер, оно не страдает, а сам элемент\n * и так `aria-hidden`.\n */\n@media (prefers-reduced-motion: reduce) {\n .gr-toast-progress {\n display: none;\n }\n}\n</style>\n","<script setup lang=\"ts\">\n/**\n * GrToaster — GR-примитив области уведомлений (toast).\n *\n * Модель состояния берётся из `useToast`, поэтому в приложении предполагается\n * **один активный `GrToaster`** на корень (или app-scoped через плагин).\n *\n * A11y:\n * - контейнер — `role=\"region\"` с `aria-label` (i18n-проп `regionLabel`);\n * - объявляет каждый тост сам собой: `role=\"status\"`, а критичные\n * (`warning`/`danger`) — ассертивный `role=\"alert\"`. Обёртки-live-region над\n * ними нет намеренно: вложение регионов с разной ассертивностью\n * спецификацией не определено, браузеры и SR расходятся вплоть до потери\n * объявления;\n * - стек достижим с клавиатуры по `focusHotkey` (по умолчанию `F6`) — тосты\n * телепортированы в конец `body`, и без хоткея кнопка «Отменить» лежала бы\n * за пределами разумного числа нажатий `Tab`.\n *\n * UX:\n * - `maxVisible` ограничивает стек; лишние ждут в очереди (их таймеры на паузе);\n * - автозакрытие **останавливается под курсором/фокусом** (WCAG 2.2.1) и\n * визуализируется прогресс-баром до закрытия;\n * - `placement` настраивает угол экрана; слой — `--gr-z-toast`.\n */\nimport { computed, nextTick, onBeforeUnmount, onMounted, onUpdated, ref, useSlots, watchEffect } from 'vue'\n\nimport { usePortalTarget } from '../../composables/usePortalTarget'\nimport type { Component } from 'vue'\n\nimport { useDragGesture } from '../../composables/useDragGesture'\nimport { useToast } from '../../composables/useToast'\nimport { vHotkey } from '../../directives'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport type { GrToastTone, Toast, ToastAction } from '../../composables/useToast'\nimport GrButton from '../GrButton'\nimport GrIcon from '../GrIcon'\nimport {\n collapsedTransform,\n PLACEMENT_CLASS,\n STACK_GAP_PX,\n STACK_PEEK_DEPTH,\n stackDepth,\n SWIPE_DIRECTION,\n SWIPE_FLY_OUT_PX,\n SWIPE_RESISTANCE,\n SWIPE_THRESHOLD_MIN_PX,\n SWIPE_THRESHOLD_RATIO,\n swipeOpacity,\n type GrToasterPlacement,\n} from './grToasterStyles'\n\nimport IconCheck from '~icons/lucide/check-circle'\nimport IconWarning from '~icons/lucide/alert-triangle'\nimport IconError from '~icons/lucide/x-circle'\nimport IconInfo from '~icons/lucide/info'\nimport IconClose from '~icons/lucide/x'\n\nexport type { GrToasterPlacement }\n\ninterface ToneMeta {\n icon: Component\n color: string\n role: 'status' | 'alert'\n}\n\n// Единый маппинг по tone'у: иконка, цвет, a11y-роль. На уровне модуля —\n// чтобы не пересоздавать объект на каждый рендер.\nconst TONE_META: Record<GrToastTone, ToneMeta> = {\n primary: { icon: IconInfo, color: 'var(--gr-primary)', role: 'status' },\n neutral: { icon: IconInfo, color: 'var(--gr-muted-fg)', role: 'status' },\n info: { icon: IconInfo, color: 'var(--gr-info)', role: 'status' },\n success: { icon: IconCheck, color: 'var(--gr-success)', role: 'status' },\n warning: { icon: IconWarning, color: 'var(--gr-warning)', role: 'alert' },\n danger: { icon: IconError, color: 'var(--gr-danger)', role: 'alert' },\n slate: { icon: IconInfo, color: 'var(--gr-slate)', role: 'status' },\n azure: { icon: IconInfo, color: 'var(--gr-azure)', role: 'status' },\n}\n\nexport interface GrToasterProps {\n /** Угол экрана для стека уведомлений. */\n placement?: GrToasterPlacement\n /** Максимум одновременно видимых тостов; остальные ждут в очереди. По умолчанию `4`. */\n maxVisible?: number\n /** A11y-лейбл кнопки закрытия (i18n). */\n dismissLabel?: string\n /** A11y-лейбл контейнера-региона (i18n). */\n regionLabel?: string\n /**\n * Ширина стека. Число — пиксели, строка — любая CSS-длина. Уезжает в\n * `--gr-toaster-width`, поэтому то же самое можно задать и темой.\n */\n width?: string | number\n /**\n * Клавиша перевода фокуса в стек уведомлений; `false` отключает хоткей.\n * `F6` — рекомендация APG для перехода между «регионами» страницы.\n */\n focusHotkey?: string | false\n /**\n * Смахивание тоста к своему краю экрана. Клавиатурный эквивалент — `Delete`\n * и `Backspace` на сфокусированном тосте — остаётся и при выключенном жесте.\n */\n swipeDismiss?: boolean\n /**\n * Со скольких видимых тостов стек схлопывается в стопку: колонка занимает\n * место одного тоста, а остальные выглядывают из-под передней. Разворачивается\n * по наведению и по фокусу. `false` — не схлопывать никогда.\n *\n * Порог, а не переключатель: пока тостов мало, колонка читается лучше стопки,\n * и менять её незачем.\n */\n collapse?: number | false\n}\n\nimport { useGrThemeAttrs } from '../GrConfigProvider/context'\n\nconst props = withDefaults(defineProps<GrToasterProps>(), {\n placement: 'top-right',\n maxVisible: 4,\n dismissLabel: undefined,\n regionLabel: undefined,\n width: undefined,\n focusHotkey: 'F6',\n swipeDismiss: true,\n collapse: 3,\n})\n\n/**\n * Слот `actions` полностью заменяет дефолтные action-кнопки тоста. Получает сам\n * `toast` и `dismiss` — функцию, закрывающую именно этот тост.\n */\ndefineSlots<{\n actions?: (props: { toast: Toast, dismiss: () => void }) => unknown\n}>()\n\nconst { t } = useGranularityTranslations()\nconst slots = useSlots()\nconst resolvedDismissLabel = computed(() => props.dismissLabel ?? t('gr.toaster.dismiss', 'Dismiss'))\nconst resolvedRegionLabel = computed(() => props.regionLabel ?? t('gr.toaster.region', 'Notifications'))\n\nconst { list, dismiss, pause, resume } = useToast()\n\n// Единый список кнопок тоста: `action` (шорткат) + массив `actions`.\nfunction toastActions(toast: Toast): ToastAction[] {\n return [...(toast.action ? [toast.action] : []), ...(toast.actions ?? [])]\n}\n\n// Показываем блок действий, если есть кнопки или задан слот `actions`.\nfunction hasActions(toast: Toast): boolean {\n return Boolean(slots.actions) || toastActions(toast).length > 0\n}\n\n// Клик по action-кнопке тоста: вызываем обработчик и (по умолчанию) закрываем тост.\nfunction onAction(toast: Toast, action: ToastAction): void {\n action.onClick()\n if (action.dismissOnClick !== false)\n dismiss(toast.id)\n}\n\n// SSR-guard: на сервере `document.body` недоступен — отключаем `teleport`.\n// Телепорт включается только ПОСЛЕ монтирования: иначе первый клиентский\n// рендер не совпадает с серверным и ломается гидрация (см. композабл).\nconst { target: portalTarget, enabled: teleportEnabled } = usePortalTarget()\n\n// Тема поддерева на телепортированную панель: в DOM она уезжает в `body`, то\n// есть вне обёртки провайдера, и `data-theme` с неё не наследуется. В дереве\n// компонентов панель остаётся внутри — `inject` доходит, и тему она ставит себе\n// сама.\nconst themeAttrs = useGrThemeAttrs()\n\n// Видимые тосты (не больше `maxVisible`); остальные ждут в очереди. Список\n// хранится новейшими вперёд, поэтому «видимые дожинают, новые ждут» — это\n// хвост: старейшие N. Взяв голову, стек показывал бы новейшие, и каждый пуш\n// вытеснял бы с экрана тост, который пользователь ещё читает.\nconst visibleToasts = computed(() => list.value.slice(-Math.max(1, props.maxVisible)))\nconst visibleIds = computed(() => new Set(visibleToasts.value.map(toast => toast.id)))\n\n// Пауза под курсором/фокусом (WCAG 2.2.1). Флага два и они независимы: один\n// `paused` терялся на «фокус внутри + мышь прошла насквозь» — `mouseleave`\n// возобновлял отсчёт под клавиатурным фокусом.\nconst hovered = ref(false)\nconst focusWithin = ref(false)\n\n// Контейнер стека: по нему ищутся тосты — и для фокуса, и для жеста.\nconst containerEl = ref<HTMLElement | null>(null)\n\n// ————— Стопка.\n\n/**\n * Развёрнуто — по тем же двум флагам, что держат `paused`: рука на стеке или\n * фокус внутри. Отдельного сигнала не заводим — читать стопку и не остановить\n * при этом таймеры было бы ловушкой.\n */\nconst expanded = computed(() => hovered.value || focusWithin.value)\nconst stacked = computed(() => props.collapse !== false && visibleToasts.value.length > Math.max(1, props.collapse))\nconst collapsed = computed(() => stacked.value && !expanded.value)\n\n/**\n * Высоты тостов: они разные (заголовок, заголовок с текстом, плюс кнопки), а\n * развёрнутая раскладка складывает их накопительно.\n *\n * `offsetHeight`, а не `getBoundingClientRect().height`: свёрнутая карточка\n * уменьшена `scale()`, и рект вернул бы её экранный размер — стопка мерила бы\n * саму себя и с каждым замером сжималась.\n */\nconst toastHeights = ref<Record<string, number>>({})\n\nlet heightObserver: ResizeObserver | null = null\n\nfunction measureToasts(): void {\n const root = containerEl.value\n if (!root)\n return\n\n const next: Record<string, number> = {}\n for (const node of root.querySelectorAll<HTMLElement>('[data-gr-toast]')) {\n const id = node.dataset.toastId\n // В jsdom высота нулевая: раскладка обязана это пережить, поэтому нули не\n // запоминаются, а потребитель значения падает на запасной путь.\n if (id && node.offsetHeight > 0)\n next[id] = node.offsetHeight\n\n heightObserver?.observe(node)\n }\n\n toastHeights.value = next\n}\n\nonMounted(() => {\n if (typeof ResizeObserver !== 'undefined')\n heightObserver = new ResizeObserver(() => measureToasts())\n\n measureToasts()\n})\n\n// Замер до отрисовки кадра: содержимое тоста меняется на месте (`update`,\n// `toast.promise`), и без этого стопка кадр стояла бы по старым высотам.\nonUpdated(measureToasts)\n\nonBeforeUnmount(() => {\n heightObserver?.disconnect()\n heightObserver = null\n})\n\n/** Все ли видимые тосты измерены. Пока нет — раскладка остаётся потоком. */\nconst measured = computed(() => visibleToasts.value.every(toast => toastHeights.value[toast.id] > 0))\n\n/** Абсолютная раскладка включается только когда есть чем считать смещения. */\nconst positioned = computed(() => stacked.value && measured.value)\n\nfunction expandedOffset(index: number): number {\n let offset = 0\n for (let i = 0; i < index; i++)\n offset += (toastHeights.value[visibleToasts.value[i].id] ?? 0) + STACK_GAP_PX\n\n return offset\n}\n\nfunction depthOf(index: number): number {\n return stackDepth(index, visibleToasts.value.length, props.placement)\n}\n\n/** Высота передней карточки — по ней живёт вся свёрнутая стопка. */\nconst frontHeight = computed(() => {\n const heights = visibleToasts.value.map(toast => toastHeights.value[toast.id] ?? 0)\n return props.placement.startsWith('top') ? heights[0] : heights[heights.length - 1]\n})\n\nconst stackHeight = computed(() => {\n if (!positioned.value)\n return undefined\n\n if (collapsed.value)\n return `${frontHeight.value}px`\n\n const heights = visibleToasts.value.map(toast => toastHeights.value[toast.id] ?? 0)\n return `${heights.reduce((sum, h) => sum + h, 0) + STACK_GAP_PX * (heights.length - 1)}px`\n})\n\n/** Карточка лежит за передней: в свёрнутой стопке от неё виден только край. */\nfunction isBehind(index: number): boolean {\n return collapsed.value && positioned.value && depthOf(index) > 0\n}\n\n/**\n * Содержимое карточек за передней гасится: из-под неё видно 12 пикселей, и в\n * эту полоску попадали обрывок строки и хвост полосы прогресса. Колода должна\n * читаться краями карточек, а не мусором в щели.\n */\nfunction toastContentStyle(index: number): Record<string, string> | undefined {\n return isBehind(index) ? { opacity: '0' } : undefined\n}\n\n// ————— Смахивание.\n\nconst swipingId = ref<string | null>(null)\nconst swipeOffset = ref(0)\nlet swipeStartX = 0\nlet swipeThreshold = SWIPE_THRESHOLD_MIN_PX\n\n// Тост, который тянут, тоже держит таймеры: иначе уведомление сгорало бы прямо\n// под пальцем, посреди жеста.\nconst paused = computed(() => hovered.value || focusWithin.value || swipingId.value !== null)\n\nfunction toastElement(id: string): HTMLElement | null {\n return containerEl.value?.querySelector<HTMLElement>(`[data-gr-toast][data-toast-id=\"${id}\"]`) ?? null\n}\n\n/** Жест отпущен и тост закрывается: переход снова разрешён (см. `releaseSwiped`). */\nconst swipeReleased = ref(false)\n\nfunction resetSwipe(): void {\n swipingId.value = null\n swipeOffset.value = 0\n swipeReleased.value = false\n}\n\n/**\n * Отпущенный тост уезжает за свой край и только потом закрывается.\n *\n * Два кадра здесь обязательны, и оба по одной причине: уходящий элемент Vue\n * больше не перерисовывает — он уезжает с тем стилем, что был на последнем\n * рендере. Значит и разрешение перехода, и конечную точку нужно успеть отдать\n * до закрытия: первый кадр снимает инлайновый `transition: none` (во время\n * жеста он нужен, иначе переходы группы борются с пальцем), второй задаёт точку\n * отлёта — с этого момента анимация уже идёт, и `leave` подхватывает её на ходу.\n *\n * Закрыв тост сразу, получили бы не отлёт, а мгновенное исчезновение: элемент\n * ушёл бы в `leave` с запрещённым переходом.\n */\nasync function releaseSwiped(id: string): Promise<void> {\n swipeReleased.value = true\n await nextTick()\n\n swipeOffset.value = SWIPE_DIRECTION[props.placement] * SWIPE_FLY_OUT_PX\n await nextTick()\n\n dismiss(id)\n resetSwipe()\n}\n\n/**\n * Движение к своему краю идёт один к одному, в обратную сторону — с\n * сопротивлением: тост едет за пальцем, но закрыть его «наоборот» нельзя.\n */\nfunction resistOffset(delta: number): number {\n const toEdge = SWIPE_DIRECTION[props.placement]\n\n return Math.sign(delta) === toEdge ? delta : delta / SWIPE_RESISTANCE\n}\n\nconst swipe = useDragGesture({\n disabled: () => !props.swipeDismiss,\n onStart: (event) => {\n const target = event.target as HTMLElement | null\n // Нажатие на кнопке — это нажатие на кнопке: закрытие и действия тоста не\n // должны превращаться в протяжку.\n if (target?.closest('button, a[href]'))\n return false\n\n const host = target?.closest<HTMLElement>('[data-gr-toast]')\n const id = host?.dataset.toastId\n if (!host || !id)\n return false\n\n swipingId.value = id\n swipeOffset.value = 0\n swipeStartX = event.clientX\n swipeThreshold = Math.max(SWIPE_THRESHOLD_MIN_PX, host.getBoundingClientRect().width * SWIPE_THRESHOLD_RATIO)\n },\n onMove: (event) => {\n // Против выделения текста тоста во время протяжки.\n event.preventDefault()\n swipeOffset.value = resistOffset(event.clientX - swipeStartX)\n },\n onEnd: () => {\n const id = swipingId.value\n const passed = id !== null\n && Math.sign(swipeOffset.value) === SWIPE_DIRECTION[props.placement]\n && Math.abs(swipeOffset.value) >= swipeThreshold\n\n if (passed)\n void releaseSwiped(id)\n else resetSwipe()\n },\n // Обрыв возвращает тост на место, а не дожимает смахивание: указатель забрал\n // браузер, а не пользователь довёл жест.\n onCancel: resetSwipe,\n})\n\n/**\n * Стиль тоста: смахивание и стопка пишут в один `transform`. Двух инлайновых\n * трансформов не бывает — второй затирает первый, и жест отменял бы раскладку.\n */\nfunction toastStyle(toast: Toast, index: number): Record<string, string> | undefined {\n const style: Record<string, string> = {}\n const transforms: string[] = []\n\n if (swipingId.value === toast.id) {\n // Смахивание идёт первым: трансформы применяются справа налево, и после\n // `scale()` жест ехал бы в масштабе карточки, а не в пикселях экрана.\n transforms.push(`translateX(${swipeOffset.value}px)`)\n style.opacity = String(swipeOpacity(swipeOffset.value, swipeThreshold))\n\n // Переходы группы во время жеста борются с пальцем: тост едет с задержкой\n // и «догоняет» курсор после отпускания. После отпускания запрет снимается —\n // уходящему тосту переход нужен, иначе он не уедет вовсе.\n if (!swipeReleased.value)\n style.transition = 'none'\n }\n\n if (positioned.value) {\n const depth = depthOf(index)\n\n transforms.push(collapsed.value\n ? collapsedTransform(depth, props.placement)\n : `translateY(${expandedOffset(index)}px)`)\n\n style.zIndex = String(visibleToasts.value.length - depth)\n\n /*\n * Уменьшение идёт от того края, которым стопка прижата к углу. По центру\n * (умолчание) карточка теряет высоту с обеих сторон, и соседи разной высоты\n * выглядывают на разное расстояние — колода получается рваной.\n */\n style.transformOrigin = props.placement.startsWith('top') ? 'top center' : 'bottom center'\n\n /*\n * Высота карточек за передней приравнивается к её собственной: иначе более\n * высокий тост выглядывал бы дальше соседа, и шаг колоды плясал бы вместе с\n * длиной сообщения.\n */\n if (collapsed.value && depth > 0 && frontHeight.value > 0)\n style.height = `${frontHeight.value}px`\n\n if (collapsed.value && depth > STACK_PEEK_DEPTH) {\n style.opacity = '0'\n // Почти невидимый край иначе ловил бы клики мимо передней карточки.\n style.pointerEvents = 'none'\n }\n }\n\n if (transforms.length > 0)\n style.transform = transforms.join(' ')\n\n return Object.keys(style).length > 0 ? style : undefined\n}\n\n/**\n * Клавиатурный эквивалент смахивания. `Escape` намеренно не берём: тостер не\n * модальный слой, и перехват закрывал бы уведомление вместо диалога под ним.\n */\nfunction onToastKeydown(event: KeyboardEvent, toast: Toast): void {\n if (event.key !== 'Delete' && event.key !== 'Backspace')\n return\n\n event.preventDefault()\n\n const index = visibleToasts.value.findIndex(item => item.id === toast.id)\n const next = visibleToasts.value[index + 1] ?? visibleToasts.value[index - 1]\n\n dismiss(toast.id)\n\n // Фокус не должен упасть на `body`: дальше по стеку есть что читать.\n if (next)\n void nextTick(() => toastElement(next.id)?.focus())\n}\n\n// Единый источник правды по таймерам: тост тикает, только если он видим И стек не на\n// паузе. Очередь и hover — на паузе. Реагирует на изменения списка/hover.\n//\n// `timeoutMs` читается ради зависимости, а не ради значения: `toast.promise` и\n// `update` перезапускают таймер уже существующего тоста, не трогая ни список, ни\n// паузу. Без этой зависимости эффект не просыпался бы, и заново заведённый\n// таймер тикал бы под курсором или у тоста, который ещё ждёт в очереди, — тот\n// сгорал бы, ни разу не показавшись.\nwatchEffect(() => {\n for (const toast of list.value) {\n const shouldTick = toast.timeoutMs > 0 && visibleIds.value.has(toast.id) && !paused.value\n\n if (shouldTick)\n resume(toast.id)\n else\n pause(toast.id)\n }\n})\n\nfunction metaFor(tone: GrToastTone): ToneMeta {\n return TONE_META[tone] ?? TONE_META.info\n}\n\nconst containerClass = computed(() => PLACEMENT_CLASS[props.placement])\n\nconst listClass = computed(() => (positioned.value\n ? 'relative transition-[height] duration-[var(--gr-duration-base)] ease-[var(--gr-ease-out)]'\n : 'grid gap-3'))\n\nconst listStyle = computed(() => (stackHeight.value ? { height: stackHeight.value } : undefined))\n\n/**\n * В стопке карточка вынута из потока, а её место задаёт трансформ — он и\n * обязан ехать плавно. В обычной колонке переход не нужен: там позицию держит\n * сама раскладка, а сдвиги отрабатывает `move-class` группы.\n */\nconst toastLayoutClass = computed(() => (positioned.value\n ? 'absolute inset-x-0 top-0 transition-[transform,opacity] duration-[var(--gr-duration-base)] ease-[var(--gr-ease-out)]'\n : 'relative'))\n\n/**\n * В стопке перемещение группы выключается. `TransitionGroup` двигает детей\n * приёмом FLIP: сам пишет в инлайновый `transform` и по концу перехода\n * **очищает** его — то есть стирает раскладку стопки. Класс без перехода\n * трансформа отключает проверку `hasCSSTransform`, и до записи дело не доходит.\n */\nconst moveClass = computed(() => (positioned.value\n ? 'transition-none'\n : 'transition-transform duration-[var(--gr-duration-base)] ease-[var(--gr-ease-out)]'))\n\n/**\n * В стопке появление и уход красятся только прозрачностью: `translate-y-*` из\n * классов группы спорил бы с инлайновым трансформом раскладки, а инлайновый\n * сильнее — сдвиг всё равно не сыграл бы.\n */\nconst enterFromClass = computed(() => (positioned.value ? 'opacity-0' : 'opacity-0 translate-y-2'))\nconst enterToClass = computed(() => (positioned.value ? 'opacity-100' : 'opacity-100 translate-y-0'))\nconst leaveFromClass = computed(() => (positioned.value ? 'opacity-100' : 'opacity-100 translate-y-0'))\nconst leaveToClass = computed(() => (positioned.value ? 'opacity-0' : 'opacity-0 translate-y-2'))\n\nconst containerStyle = computed(() => {\n if (props.width === undefined)\n return undefined\n\n return { '--gr-toaster-width': typeof props.width === 'number' ? `${props.width}px` : props.width }\n})\n\n/**\n * Переводит фокус на верхний тост. Тост фокусируем только программно\n * (`tabindex=\"-1\"`): собственной остановкой `Tab` стек быть не должен, иначе\n * всплывающее уведомление перехватывало бы обход страницы.\n */\nfunction focus(): boolean {\n const target = containerEl.value?.querySelector<HTMLElement>('[data-gr-toast]')\n if (!target)\n return false\n\n target.focus()\n return true\n}\n\nconst hotkeyBinding = computed(() => ({\n enabled: props.focusHotkey !== false && visibleToasts.value.length > 0,\n handlers: { [props.focusHotkey || 'F6']: { handler: onFocusHotkey, allowInEditable: true } },\n}))\n\nfunction onFocusHotkey(event: KeyboardEvent): void {\n if (focus())\n event.preventDefault()\n}\n\ndefineExpose({ focus })\n</script>\n\n<template>\n <teleport :to=\"portalTarget\" :disabled=\"!teleportEnabled\">\n <div\n ref=\"containerEl\"\n v-hotkey=\"hotkeyBinding\"\n v-bind=\"themeAttrs\"\n data-gr-toaster\n data-gr-overlay-root\n role=\"region\"\n :aria-label=\"resolvedRegionLabel\"\n class=\"fixed z-[var(--gr-z-toast)] w-[var(--gr-toaster-width,360px)] max-w-[calc(100vw-2rem)]\"\n :class=\"containerClass\"\n :style=\"containerStyle\"\n @mouseenter=\"hovered = true\"\n @mouseleave=\"hovered = false\"\n @focusin=\"focusWithin = true\"\n @focusout=\"focusWithin = false\"\n >\n <TransitionGroup\n tag=\"div\"\n :class=\"listClass\"\n :style=\"listStyle\"\n enter-active-class=\"transition duration-[var(--gr-duration-base)] ease-[var(--gr-ease-out)]\"\n :enter-from-class=\"enterFromClass\"\n :enter-to-class=\"enterToClass\"\n leave-active-class=\"transition duration-[var(--gr-duration-fast)] ease-[var(--gr-ease-in)] absolute\"\n :leave-from-class=\"leaveFromClass\"\n :leave-to-class=\"leaveToClass\"\n :move-class=\"moveClass\"\n >\n <div\n v-for=\"(toast, index) in visibleToasts\"\n :key=\"toast.id\"\n data-gr-toast\n :data-tone=\"toast.tone\"\n :data-toast-id=\"toast.id\"\n :role=\"metaFor(toast.tone).role\"\n aria-atomic=\"true\"\n tabindex=\"-1\"\n class=\"overflow-hidden rounded-[var(--gr-radius-lg)] border border-[var(--gr-brd)] bg-[var(--gr-card)] px-4 py-3 shadow-[var(--gr-shadow-2)] focus-visible:outline-none focus-visible:shadow-[var(--gr-shadow-2),0_0_0_2px_var(--gr-ring)]\"\n :class=\"[swipeDismiss ? '[touch-action:pan-y]' : '', toastLayoutClass]\"\n :style=\"toastStyle(toast, index)\"\n @pointerdown=\"swipe.start\"\n @keydown=\"onToastKeydown($event, toast)\"\n >\n <div\n class=\"flex items-start gap-3 transition-opacity duration-[var(--gr-duration-base)] ease-[var(--gr-ease-out)]\"\n :style=\"toastContentStyle(index)\"\n >\n <GrIcon size=\"md\" class=\"mt-0.5\" :style=\"{ color: metaFor(toast.tone).color }\">\n <component :is=\"metaFor(toast.tone).icon\" />\n </GrIcon>\n <div class=\"min-w-0 flex-1\">\n <div class=\"text-[length:var(--gr-text-sm)] leading-[var(--gr-leading-sm)] font-700\">\n {{ toast.title }}\n </div>\n <div v-if=\"toast.message\" class=\"mt-0.5 text-[length:var(--gr-text-sm)] leading-[var(--gr-leading-sm)] text-[var(--gr-muted-fg)]\">\n {{ toast.message }}\n </div>\n\n <!-- Action-кнопки тоста: например «Отменить»/«Повторить». Можно\n задать массивом (`actions`) или переопределить слотом. -->\n <div v-if=\"hasActions(toast)\" class=\"mt-2 flex flex-wrap gap-2\">\n <slot name=\"actions\" :toast=\"toast\" :dismiss=\"() => dismiss(toast.id)\">\n <GrButton\n v-for=\"(action, index) in toastActions(toast)\"\n :key=\"index\"\n :variant=\"action.variant ?? 'outline'\"\n :size=\"action.size ?? 'sm'\"\n data-gr-toast-action\n @click=\"onAction(toast, action)\"\n >\n {{ action.label }}\n </GrButton>\n </slot>\n </div>\n </div>\n <GrButton\n variant=\"ghost\"\n size=\"sm\"\n square\n :aria-label=\"resolvedDismissLabel\"\n @click=\"dismiss(toast.id)\"\n >\n <GrIcon size=\"sm\">\n <IconClose />\n </GrIcon>\n </GrButton>\n </div>\n\n <!-- Прогресс до автозакрытия; замирает вместе с таймером на паузе. -->\n <div\n v-if=\"toast.timeoutMs > 0\"\n data-gr-toast-progress\n aria-hidden=\"true\"\n class=\"gr-toast-progress absolute bottom-0 left-0 h-[2px] w-full origin-left\"\n :style=\"{\n backgroundColor: metaFor(toast.tone).color,\n animationDuration: `${toast.timeoutMs}ms`,\n animationPlayState: paused ? 'paused' : 'running',\n ...toastContentStyle(index),\n }\"\n />\n </div>\n </TransitionGroup>\n </div>\n </teleport>\n</template>\n\n<style scoped>\n.gr-toast-progress {\n animation-name: gr-toast-progress;\n animation-timing-function: linear;\n animation-fill-mode: forwards;\n}\n\n@keyframes gr-toast-progress {\n from {\n transform: scaleX(1);\n }\n to {\n transform: scaleX(0);\n }\n}\n\n/*\n * Единственная анимация пакета, которую глобальный кламп чинит неверно.\n *\n * У полосы `animation-fill-mode: forwards`, поэтому сжатая до `0.01ms` она не\n * возвращается в исходное состояние, а фиксируется на `scaleX(0)`: таймер\n * выглядит истёкшим, пока тост ещё висит на экране. Полоса — единственный\n * носитель этого смысла, и статичной её оставить нельзя, поэтому под reduce она\n * убирается совсем. Автозакрытие ведёт JS-таймер, оно не страдает, а сам элемент\n * и так `aria-hidden`.\n */\n@media (prefers-reduced-motion: reduce) {\n .gr-toast-progress {\n display: none;\n }\n}\n</style>\n"],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { n as grToasterSafelist, t as grToasterConfig } from "../../chunks/config-
|
|
2
|
-
import { t as GrToaster_default } from "./chunks/GrToaster-
|
|
1
|
+
import { n as grToasterSafelist, t as grToasterConfig } from "../../chunks/config-B7qZqiUB.js";
|
|
2
|
+
import { t as GrToaster_default } from "./chunks/GrToaster-OzT1VKcp.js";
|
|
3
3
|
export { GrToaster_default as GrToaster, GrToaster_default as default, grToasterConfig, grToasterSafelist };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.gr-toast-progress[data-v-
|
|
1
|
+
.gr-toast-progress[data-v-185f56c0]{animation-name:gr-toast-progress-185f56c0;animation-timing-function:linear;animation-fill-mode:forwards}@keyframes gr-toast-progress-185f56c0{0%{transform:scaleX(1)}to{transform:scaleX(0)}}@media (prefers-reduced-motion:reduce){.gr-toast-progress[data-v-185f56c0]{display:none}}
|
|
@@ -5,14 +5,10 @@ import { vClickOutside } from "../../../directives/clickOutside.js";
|
|
|
5
5
|
import { t as GrIcon_default } from "../../GrIcon/chunks/GrIcon-DTZIgmje.js";
|
|
6
6
|
import { useFloating } from "../../../composables/useFloating.js";
|
|
7
7
|
import { useDismissible } from "../../../composables/useDismissible.js";
|
|
8
|
-
import {
|
|
9
|
-
import { Teleport, Transition, computed, createBlock, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, mergeProps, normalizeStyle, onMounted, onUnmounted, onUpdated, openBlock, ref, renderSlot, toDisplayString, unref, useId, useSlots, vShow, watchEffect, withCtx, withDirectives } from "vue";
|
|
8
|
+
import { n as panelWidths, r as triggerIconSizes, t as panelSizes } from "../../../chunks/grTooltipStyles-CtbGEEGV.js";
|
|
9
|
+
import { Teleport, Transition, computed, createBlock, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, mergeProps, normalizeClass, normalizeStyle, onMounted, onUnmounted, onUpdated, openBlock, ref, renderSlot, toDisplayString, unref, useId, useSlots, vShow, watchEffect, withCtx, withDirectives } from "vue";
|
|
10
10
|
//#region src/components/GrTooltip/GrTooltip.vue?vue&type=script&setup=true&lang.ts
|
|
11
|
-
var _hoisted_1 =
|
|
12
|
-
"data-gr-tooltip": "",
|
|
13
|
-
class: "relative inline-flex"
|
|
14
|
-
};
|
|
15
|
-
var _hoisted_2 = ["tabindex", "aria-describedby"];
|
|
11
|
+
var _hoisted_1 = ["tabindex", "aria-describedby"];
|
|
16
12
|
var FOCUSABLE_SELECTOR = "a[href],button,input,select,textarea,[tabindex]:not([tabindex=\"-1\"])";
|
|
17
13
|
//#endregion
|
|
18
14
|
//#region src/components/GrTooltip/GrTooltip.vue
|
|
@@ -33,6 +29,14 @@ var GrTooltip_default = /* @__PURE__ */ defineComponent({
|
|
|
33
29
|
open: {
|
|
34
30
|
type: Boolean,
|
|
35
31
|
default: void 0
|
|
32
|
+
},
|
|
33
|
+
block: {
|
|
34
|
+
type: Boolean,
|
|
35
|
+
default: false
|
|
36
|
+
},
|
|
37
|
+
describeTrigger: {
|
|
38
|
+
type: Boolean,
|
|
39
|
+
default: true
|
|
36
40
|
}
|
|
37
41
|
},
|
|
38
42
|
emits: ["update:open"],
|
|
@@ -130,21 +134,30 @@ var GrTooltip_default = /* @__PURE__ */ defineComponent({
|
|
|
130
134
|
onUpdated(syncSlotFocusable);
|
|
131
135
|
watchEffect((onCleanup) => {
|
|
132
136
|
const el = slotFocusableEl.value;
|
|
133
|
-
if (!el) return;
|
|
137
|
+
if (!el || !props.describeTrigger) return;
|
|
134
138
|
el.setAttribute("aria-describedby", tooltipId);
|
|
135
139
|
onCleanup(() => el.removeAttribute("aria-describedby"));
|
|
136
140
|
});
|
|
137
141
|
const wrapperTabindex = computed(() => slotFocusableEl.value ? void 0 : 0);
|
|
138
|
-
const wrapperDescribedBy = computed(() => slotFocusableEl.value ? void 0 : tooltipId);
|
|
142
|
+
const wrapperDescribedBy = computed(() => slotFocusableEl.value || !props.describeTrigger ? void 0 : tooltipId);
|
|
143
|
+
/**
|
|
144
|
+
* Обе обёртки, а не только внешняя: внутренний триггер тоже `inline-flex`, и
|
|
145
|
+
* снаружи до него не дотянуться — оставь его как есть, и содержимое всё равно
|
|
146
|
+
* схлопнется по себе.
|
|
147
|
+
*/
|
|
148
|
+
const layoutClass = computed(() => props.block ? "flex w-full" : "inline-flex");
|
|
139
149
|
return (_ctx, _cache) => {
|
|
140
|
-
return withDirectives((openBlock(), createElementBlock("span",
|
|
150
|
+
return withDirectives((openBlock(), createElementBlock("span", {
|
|
151
|
+
"data-gr-tooltip": "",
|
|
152
|
+
class: normalizeClass(["relative", layoutClass.value])
|
|
153
|
+
}, [createElementVNode("span", {
|
|
141
154
|
ref_key: "triggerEl",
|
|
142
155
|
ref: triggerEl,
|
|
143
156
|
"data-gr-tooltip-trigger": "",
|
|
144
157
|
"data-testid": "gr-tooltip-trigger",
|
|
145
158
|
tabindex: wrapperTabindex.value,
|
|
146
159
|
"aria-describedby": wrapperDescribedBy.value,
|
|
147
|
-
class: "
|
|
160
|
+
class: normalizeClass(["items-center justify-center focus:outline-none", layoutClass.value]),
|
|
148
161
|
style: normalizeStyle(triggerStyle.value),
|
|
149
162
|
onMouseenter: show,
|
|
150
163
|
onMouseleave: hide,
|
|
@@ -154,7 +167,7 @@ var GrTooltip_default = /* @__PURE__ */ defineComponent({
|
|
|
154
167
|
}, [renderSlot(_ctx.$slots, "default", {}, () => [createVNode(unref(GrIcon_default), { size: triggerIconSize.value }, {
|
|
155
168
|
default: withCtx(() => [createVNode(unref(info_default))]),
|
|
156
169
|
_: 1
|
|
157
|
-
}, 8, ["size"])])],
|
|
170
|
+
}, 8, ["size"])])], 46, _hoisted_1), (openBlock(), createBlock(Teleport, {
|
|
158
171
|
to: unref(portalTarget),
|
|
159
172
|
disabled: !unref(teleportEnabled)
|
|
160
173
|
}, [createVNode(Transition, {
|
|
@@ -177,7 +190,7 @@ var GrTooltip_default = /* @__PURE__ */ defineComponent({
|
|
|
177
190
|
style: unref(floatingStyle)
|
|
178
191
|
}), [renderSlot(_ctx.$slots, "content", {}, () => [createTextVNode(toDisplayString(__props.text), 1)])], 16), [[vShow, open.value]])]),
|
|
179
192
|
_: 3
|
|
180
|
-
})], 8, ["to", "disabled"]))])), [[unref(vClickOutside), dismissOnOutside.value]]);
|
|
193
|
+
})], 8, ["to", "disabled"]))], 2)), [[unref(vClickOutside), dismissOnOutside.value]]);
|
|
181
194
|
};
|
|
182
195
|
}
|
|
183
196
|
});
|