@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
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { a as useGrComponentSize } from "../../../chunks/context-CPMRfwVr.js";
|
|
1
|
+
import { a as useGrComponentSize, i as useGrComponentProp } from "../../../chunks/context-CPMRfwVr.js";
|
|
2
2
|
import { n as useGranularityTranslations } from "../../../chunks/granularityI18n-BC5zsj_d.js";
|
|
3
3
|
import { t as loader_circle_default } from "../../../chunks/loader-circle-CfVLz7lb.js";
|
|
4
4
|
import { n as useGrFormFieldContext } from "../../../chunks/context-DdNIxa1w.js";
|
|
5
5
|
import { useGrFormControl } from "../../../composables/useGrFormControl.js";
|
|
6
|
-
import { a as grSwitchSpinnerClass, i as grSwitchRootClass, o as
|
|
7
|
-
import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, defineComponent, mergeProps, normalizeClass, normalizeStyle, openBlock, ref, renderSlot, toDisplayString, unref } from "vue";
|
|
6
|
+
import { a as grSwitchSpinnerClass, c as grSwitchThumbIconClass, d as stateTextGhostClass, f as stateTextRoom, i as grSwitchRootClass, l as grSwitchTrackClass, o as grSwitchStateTextClass, p as stateTextStackClass, r as grSwitchLabelClass, s as grSwitchThumbClass, u as isGrSwitchStateTextSize } from "../../../chunks/config-MUkhktTP.js";
|
|
7
|
+
import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, defineComponent, mergeProps, normalizeClass, normalizeStyle, openBlock, ref, renderSlot, toDisplayString, unref, useSlots, watchEffect } from "vue";
|
|
8
8
|
//#region src/components/GrSwitch/GrSwitch.vue?vue&type=script&setup=true&lang.ts
|
|
9
9
|
var _hoisted_1 = [
|
|
10
10
|
"name",
|
|
@@ -65,7 +65,17 @@ var GrSwitch_default = /* @__PURE__ */ defineComponent({
|
|
|
65
65
|
value: { default: "on" },
|
|
66
66
|
form: { default: void 0 },
|
|
67
67
|
activeBackgroundColor: { default: void 0 },
|
|
68
|
-
inactiveBackgroundColor: { default: void 0 }
|
|
68
|
+
inactiveBackgroundColor: { default: void 0 },
|
|
69
|
+
showStateText: {
|
|
70
|
+
type: Boolean,
|
|
71
|
+
default: void 0
|
|
72
|
+
},
|
|
73
|
+
checkedText: { default: void 0 },
|
|
74
|
+
uncheckedText: { default: void 0 },
|
|
75
|
+
autoWidth: {
|
|
76
|
+
type: Boolean,
|
|
77
|
+
default: void 0
|
|
78
|
+
}
|
|
69
79
|
},
|
|
70
80
|
emits: [
|
|
71
81
|
"update:modelValue",
|
|
@@ -76,6 +86,7 @@ var GrSwitch_default = /* @__PURE__ */ defineComponent({
|
|
|
76
86
|
setup(__props, { expose: __expose, emit: __emit }) {
|
|
77
87
|
const getCustomColor = (value) => value?.trim() || void 0;
|
|
78
88
|
const props = __props;
|
|
89
|
+
const slots = useSlots();
|
|
79
90
|
const field = useGrFormFieldContext();
|
|
80
91
|
const fieldId = computed(() => field?.id.value);
|
|
81
92
|
const describedBy = computed(() => field?.describedById.value);
|
|
@@ -102,8 +113,15 @@ var GrSwitch_default = /* @__PURE__ */ defineComponent({
|
|
|
102
113
|
]
|
|
103
114
|
});
|
|
104
115
|
const emit = __emit;
|
|
116
|
+
const resolvedShowStateText = useGrComponentProp("GrSwitch", "showStateText", () => props.showStateText, false);
|
|
117
|
+
const resolvedAutoWidth = useGrComponentProp("GrSwitch", "autoWidth", () => props.autoWidth, false);
|
|
118
|
+
const stateTextSize = computed(() => {
|
|
119
|
+
if (!resolvedShowStateText.value) return void 0;
|
|
120
|
+
return isGrSwitchStateTextSize(resolvedSize.value) ? resolvedSize.value : void 0;
|
|
121
|
+
});
|
|
122
|
+
const hasStateText = computed(() => stateTextSize.value !== void 0);
|
|
105
123
|
const rootClass = computed(() => grSwitchRootClass(props.labelPosition));
|
|
106
|
-
const trackClass = computed(() => grSwitchTrackClass(resolvedSize.value));
|
|
124
|
+
const trackClass = computed(() => grSwitchTrackClass(resolvedSize.value, hasStateText.value && resolvedAutoWidth.value));
|
|
107
125
|
const trackStyle = computed(() => {
|
|
108
126
|
const isChecked = props.modelValue;
|
|
109
127
|
const defaultBackgroundColor = isChecked ? "var(--gr-primary)" : "var(--gr-muted)";
|
|
@@ -120,8 +138,29 @@ var GrSwitch_default = /* @__PURE__ */ defineComponent({
|
|
|
120
138
|
checked: props.modelValue
|
|
121
139
|
}));
|
|
122
140
|
const spinnerClass = computed(() => grSwitchSpinnerClass(resolvedSize.value));
|
|
141
|
+
const thumbIconSlot = computed(() => props.modelValue ? slots["checked-icon"] : slots["unchecked-icon"]);
|
|
142
|
+
const thumbIconClass = computed(() => grSwitchThumbIconClass(resolvedSize.value));
|
|
123
143
|
const labelClass = computed(() => grSwitchLabelClass(resolvedSize.value, isDisabled.value));
|
|
124
144
|
const resolvedLoadingText = computed(() => props.loadingText ?? t("gr.switch.loading", "Saving…"));
|
|
145
|
+
const stateTextClass = computed(() => stateTextSize.value ? grSwitchStateTextClass({
|
|
146
|
+
size: stateTextSize.value,
|
|
147
|
+
checked: props.modelValue,
|
|
148
|
+
disabled: isDisabled.value,
|
|
149
|
+
autoWidth: resolvedAutoWidth.value
|
|
150
|
+
}) : "");
|
|
151
|
+
const checkedStateText = computed(() => props.checkedText ?? t("gr.switch.on", "ON"));
|
|
152
|
+
const uncheckedStateText = computed(() => props.uncheckedText ?? t("gr.switch.off", "OFF"));
|
|
153
|
+
const resolvedStateText = computed(() => props.modelValue ? checkedStateText.value : uncheckedStateText.value);
|
|
154
|
+
const ghostStateText = computed(() => props.modelValue ? uncheckedStateText.value : checkedStateText.value);
|
|
155
|
+
if (process.env.NODE_ENV !== "production") {
|
|
156
|
+
watchEffect(() => {
|
|
157
|
+
if (resolvedAutoWidth.value && !resolvedShowStateText.value) console.warn("[granularity] GrSwitch: `autoWidth` без `showStateText` ничего не делает — дорожке не подо что растягиваться.");
|
|
158
|
+
});
|
|
159
|
+
watchEffect(() => {
|
|
160
|
+
if (!resolvedShowStateText.value || isGrSwitchStateTextSize(resolvedSize.value)) return;
|
|
161
|
+
console.warn(`[granularity] GrSwitch: подпись состояния не нарисована на ступени \`${resolvedSize.value}\`: рядом с бегунком ${stateTextRoom[resolvedSize.value]}px, а минимально читаемой подписи нужен ${stateTextRoom.md}px. Подписи живут на \`md\` и \`lg\`.`);
|
|
162
|
+
});
|
|
163
|
+
}
|
|
125
164
|
const submitsValue = computed(() => props.modelValue && !isDisabled.value && Boolean(props.name));
|
|
126
165
|
function toggle() {
|
|
127
166
|
if (isDisabled.value || isReadonly.value || props.loading) return;
|
|
@@ -162,7 +201,17 @@ var GrSwitch_default = /* @__PURE__ */ defineComponent({
|
|
|
162
201
|
"data-gr-switch-track": "",
|
|
163
202
|
class: normalizeClass(trackClass.value),
|
|
164
203
|
style: normalizeStyle(trackStyle.value)
|
|
165
|
-
}, [
|
|
204
|
+
}, [stateTextSize.value ? (openBlock(), createElementBlock("span", {
|
|
205
|
+
key: 0,
|
|
206
|
+
"data-testid": "gr-switch-state-text",
|
|
207
|
+
"data-gr-switch-state-text": "",
|
|
208
|
+
class: normalizeClass(stateTextClass.value),
|
|
209
|
+
"aria-hidden": "true"
|
|
210
|
+
}, [createElementVNode("span", { class: normalizeClass(unref(stateTextStackClass)) }, toDisplayString(resolvedStateText.value), 3), unref(resolvedAutoWidth) ? (openBlock(), createElementBlock("span", {
|
|
211
|
+
key: 0,
|
|
212
|
+
"data-gr-switch-state-text-ghost": "",
|
|
213
|
+
class: normalizeClass(unref(stateTextGhostClass))
|
|
214
|
+
}, toDisplayString(ghostStateText.value), 3)) : createCommentVNode("", true)], 2)) : createCommentVNode("", true), createElementVNode("span", {
|
|
166
215
|
"data-testid": "gr-switch-thumb",
|
|
167
216
|
"data-gr-switch-thumb": "",
|
|
168
217
|
class: normalizeClass(thumbClass.value),
|
|
@@ -171,7 +220,12 @@ var GrSwitch_default = /* @__PURE__ */ defineComponent({
|
|
|
171
220
|
key: 0,
|
|
172
221
|
"data-gr-switch-spinner": "",
|
|
173
222
|
class: normalizeClass(spinnerClass.value)
|
|
174
|
-
}, null, 8, ["class"])) :
|
|
223
|
+
}, null, 8, ["class"])) : thumbIconSlot.value ? (openBlock(), createElementBlock("span", {
|
|
224
|
+
key: 1,
|
|
225
|
+
"data-testid": "gr-switch-thumb-icon",
|
|
226
|
+
"data-gr-switch-thumb-icon": "",
|
|
227
|
+
class: normalizeClass(thumbIconClass.value)
|
|
228
|
+
}, [__props.modelValue ? renderSlot(_ctx.$slots, "checked-icon", {}, void 0, void 0, 0) : renderSlot(_ctx.$slots, "unchecked-icon", {}, void 0, void 0, 1)], 2)) : createCommentVNode("", true)], 2)], 6),
|
|
175
229
|
_ctx.$slots.default ? (openBlock(), createElementBlock("span", {
|
|
176
230
|
key: 0,
|
|
177
231
|
"data-gr-switch-label": "",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GrSwitch-D7X42uIA.js","names":["$attrs","$slots"],"sources":["../../../../src/components/GrSwitch/GrSwitch.vue","../../../../src/components/GrSwitch/GrSwitch.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, watchEffect } from 'vue'\nimport IconLoader from '~icons/lucide/loader-circle'\n\nimport { useGrComponentSize } from '../GrConfigProvider/context'\nimport { useGrFormFieldContext } from '../GrFormField/context'\nimport { useGrComponentProp } from '../../composables/useGrComponentConfig'\nimport { useGrFormControl } from '../../composables/useGrFormControl'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\n\nimport {\n grSwitchLabelClass,\n grSwitchRootClass,\n grSwitchSpinnerClass,\n grSwitchStateTextClass,\n grSwitchThumbClass,\n grSwitchThumbIconClass,\n grSwitchTrackClass,\n isGrSwitchStateTextSize,\n stateTextGhostClass,\n stateTextRoom,\n stateTextStackClass,\n type GrSwitchLabelPosition,\n type GrSwitchSize,\n type GrSwitchStateTextSize,\n} from './grSwitchStyles'\n\nexport type {\n GrSwitchLabelPosition,\n GrSwitchSize,\n GrSwitchStateTextSize,\n} from './grSwitchStyles'\n\n/**\n * Пропсы публичного GR-примитива «Switch».\n */\nexport interface GrSwitchProps {\n /**\n * Значение переключателя. Необязательное: без `v-model` контрол рисуется\n * выключенным — так же, как `GrCheckbox`. Обязательный проп заставлял бы\n * заводить `ref` даже там, где переключатель presentational.\n */\n modelValue?: boolean\n disabled?: boolean\n /** Только для чтения: состояние видно, но не переключается. */\n readonly?: boolean\n /** Визуальное и ARIA-состояние ошибки. */\n invalid?: boolean\n /** Обязательное поле (`aria-required`). */\n required?: boolean\n ariaLabel?: string\n size?: GrSwitchSize\n /** Сторона подписи относительно дорожки. */\n labelPosition?: GrSwitchLabelPosition\n /** Идёт сохранение: бегунок показывает спиннер, переключение заблокировано. */\n loading?: boolean\n /** i18n: что именно грузится. `aria-busy` сам по себе часть AT не объявляет. */\n loadingText?: string\n /** Имя поля для нативной отправки формы. Без него скрытое поле не рендерится. */\n name?: string\n /** Значение, уходящее в форму во включённом состоянии. */\n value?: string\n /** `id` формы, если переключатель лежит вне неё. */\n form?: string\n /** Кастомный цвет фона в активном состоянии. Если не задан — `var(--gr-primary)`. */\n activeBackgroundColor?: string\n /** Кастомный цвет фона в неактивном состоянии. Если не задан — `var(--gr-muted)`. */\n inactiveBackgroundColor?: string\n /**\n * Подпись состояния внутри дорожки — на свободной от бегунка стороне.\n * Помещается только на `md` и `lg`; на мелких ступенях не рисуется.\n */\n showStateText?: boolean\n /** Текст включённого состояния. Без него — `gr.switch.on` из локали. */\n checkedText?: string\n /** Текст выключенного состояния. Без него — `gr.switch.off` из локали. */\n uncheckedText?: string\n /**\n * Дорожка растягивается под подпись, а ступень размера становится нижней\n * границей ширины. Без `showStateText` смысла не имеет: тянуться не под что.\n */\n autoWidth?: boolean\n}\n\nexport interface GrSwitchEmits {\n (e: 'update:modelValue', value: boolean): void\n (e: 'change', value: boolean): void\n (e: 'focus', event: FocusEvent): void\n (e: 'blur', event: FocusEvent): void\n}\n\nconst getCustomColor = (value?: string) => value?.trim() || undefined\n\n// Скрытое поле — сосед кнопки, а не её потомок: интерактивный контент внутри\n// `<button>` невалиден. Из-за этого корень компонента — фрагмент, и атрибуты\n// потребителя надо донести до кнопки руками.\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(\n defineProps<GrSwitchProps>(),\n {\n modelValue: false,\n disabled: false,\n readonly: false,\n invalid: false,\n required: false,\n ariaLabel: undefined,\n size: undefined,\n labelPosition: 'end',\n loading: false,\n loadingText: undefined,\n name: undefined,\n value: 'on',\n form: undefined,\n activeBackgroundColor: undefined,\n inactiveBackgroundColor: undefined,\n // `undefined`, а не `false`: Vue приводит отсутствующий boolean к `false`,\n // и дефолт из `GrConfigProvider` до компонента бы не доехал.\n showStateText: undefined,\n checkedText: undefined,\n uncheckedText: undefined,\n autoWidth: undefined,\n },\n)\n\n// Контекст `GrFormField`: id для `<label for>`, описание ошибкой, невалидность.\n// `<button>` — labelable-элемент, поэтому клик по подписи фокусирует переключатель.\nconst slots = defineSlots<{\n /** Подпись переключателя. */\n 'default'?: () => any\n /**\n * Знак на бегунке во включённом состоянии — галочка, замок, что угодно.\n *\n * Размер задаёт обёртка по ступени `size`, поэтому содержимое слота тянется\n * до неё: `class=\"h-full w-full\"`, как у `GrBadge` и `GrChip`.\n *\n * Знак декоративен — бегунок целиком `aria-hidden`, а состояние диктор берёт\n * из `aria-checked`. Смысла, которого нет больше нигде, сюда класть нельзя.\n */\n 'checked-icon'?: () => any\n /** То же для выключенного состояния. Слоты независимы. */\n 'unchecked-icon'?: () => any\n}>()\n\nconst field = useGrFormFieldContext()\nconst fieldId = computed(() => field?.id.value)\nconst describedBy = computed(() => field?.describedById.value)\nconst {\n disabled: isDisabled,\n invalid: isInvalid,\n required: isRequired,\n readonly: isReadonly,\n} = useGrFormControl(() => props)\n\nconst { t } = useGranularityTranslations()\n\nconst rootEl = ref<HTMLButtonElement | null>(null)\n\nfunction focus(): void {\n rootEl.value?.focus()\n}\n\nfunction blur(): void {\n rootEl.value?.blur()\n}\n\ndefineExpose({ focus, blur })\n\n// Эффективный размер: локальный проп → `GrConfigProvider` → дефолт компонента.\nconst resolvedSize = useGrComponentSize(() => props.size, {\n component: 'GrSwitch',\n supported: ['xs', 'sm', 'md', 'lg'],\n})\n\nconst emit = defineEmits<GrSwitchEmits>()\n\nconst resolvedShowStateText = useGrComponentProp(\n 'GrSwitch',\n 'showStateText',\n () => props.showStateText,\n false,\n)\n\nconst resolvedAutoWidth = useGrComponentProp(\n 'GrSwitch',\n 'autoWidth',\n () => props.autoWidth,\n false,\n)\n\n// Ступень, на которой подпись помещается в дорожку, — иначе её нет вовсе.\nconst stateTextSize = computed<GrSwitchStateTextSize | undefined>(() => {\n if (!resolvedShowStateText.value)\n return undefined\n\n return isGrSwitchStateTextSize(resolvedSize.value) ? resolvedSize.value : undefined\n})\n\nconst hasStateText = computed(() => stateTextSize.value !== undefined)\n\nconst rootClass = computed(() => grSwitchRootClass(props.labelPosition))\n\nconst trackClass = computed(() => grSwitchTrackClass(resolvedSize.value, hasStateText.value && resolvedAutoWidth.value))\n\nconst trackStyle = computed(() => {\n const isChecked = props.modelValue\n const defaultBackgroundColor = isChecked ? 'var(--gr-primary)' : 'var(--gr-muted)'\n const customBackgroundColor = getCustomColor(\n isChecked ? props.activeBackgroundColor : props.inactiveBackgroundColor,\n )\n // Недоступность гасится токеном и перебивает кастомный цвет: иначе выключенный\n // переключатель остался бы таким же ярким, как рабочий.\n const backgroundColor = isDisabled.value\n ? 'var(--gr-disabled-bg)'\n : customBackgroundColor ?? defaultBackgroundColor\n\n return {\n '--gr-switch-track-bg': backgroundColor,\n '--gr-switch-track-brd': isDisabled.value\n ? 'var(--gr-disabled-brd)'\n : customBackgroundColor\n ? backgroundColor\n : isChecked\n ? 'var(--gr-primary)'\n : 'var(--gr-brd)',\n 'backgroundColor': 'var(--gr-switch-track-bg)',\n }\n})\n\nconst thumbClass = computed(() => grSwitchThumbClass({ size: resolvedSize.value, checked: props.modelValue }))\n\nconst spinnerClass = computed(() => grSwitchSpinnerClass(resolvedSize.value))\n\n// Спиннер и иконка занимают центр бегунка: пока идёт запрос, важнее «состояние\n// меняется», чем «каким оно стало».\nconst thumbIconSlot = computed(() => (props.modelValue ? slots['checked-icon'] : slots['unchecked-icon']))\n\nconst thumbIconClass = computed(() => grSwitchThumbIconClass(resolvedSize.value))\n\nconst labelClass = computed(() => grSwitchLabelClass(resolvedSize.value, isDisabled.value))\n\nconst resolvedLoadingText = computed(() => props.loadingText ?? t('gr.switch.loading', 'Saving…'))\n\nconst stateTextClass = computed(() => (stateTextSize.value\n ? grSwitchStateTextClass({\n size: stateTextSize.value,\n checked: props.modelValue,\n disabled: isDisabled.value,\n autoWidth: resolvedAutoWidth.value,\n })\n : ''))\n\nconst checkedStateText = computed(() => props.checkedText ?? t('gr.switch.on', 'ON'))\nconst uncheckedStateText = computed(() => props.uncheckedText ?? t('gr.switch.off', 'OFF'))\n\nconst resolvedStateText = computed(() => (\n props.modelValue ? checkedStateText.value : uncheckedStateText.value\n))\n\n// Невидимый дубль держит ширину: без него дорожка меняла бы размер на каждом\n// щелчке, потому что «вкл» и «выкл» почти никогда не равны по ширине.\nconst ghostStateText = computed(() => (\n props.modelValue ? uncheckedStateText.value : checkedStateText.value\n))\n\nif (__GR_DEV__) {\n watchEffect(() => {\n if (resolvedAutoWidth.value && !resolvedShowStateText.value) {\n console.warn(\n '[granularity] GrSwitch: `autoWidth` без `showStateText` ничего не делает — '\n + 'дорожке не подо что растягиваться.',\n )\n }\n })\n\n watchEffect(() => {\n if (!resolvedShowStateText.value || isGrSwitchStateTextSize(resolvedSize.value))\n return\n\n console.warn(\n `[granularity] GrSwitch: подпись состояния не нарисована на ступени \\`${resolvedSize.value}\\`: `\n + `рядом с бегунком ${stateTextRoom[resolvedSize.value]}px, а минимально читаемой подписи нужен `\n + `${stateTextRoom.md}px. Подписи живут на \\`md\\` и \\`lg\\`.`,\n )\n })\n}\n\n// Выключенный переключатель не отправляется вовсе — так устроен чекбокс в HTML,\n// и сервер отличает «выкл» по отсутствию ключа.\nconst submitsValue = computed(\n () => props.modelValue && !isDisabled.value && Boolean(props.name),\n)\n\nfunction toggle(): void {\n if (isDisabled.value || isReadonly.value || props.loading) {\n return\n }\n\n const next = !props.modelValue\n emit('update:modelValue', next)\n emit('change', next)\n}\n</script>\n\n<template>\n <input\n v-if=\"submitsValue\"\n type=\"hidden\"\n :name=\"name\"\n :value=\"value\"\n :form=\"form\"\n >\n\n <button\n :id=\"fieldId\"\n ref=\"rootEl\"\n v-bind=\"$attrs\"\n type=\"button\"\n role=\"switch\"\n data-gr-switch\n :aria-checked=\"modelValue ? 'true' : 'false'\"\n :aria-label=\"ariaLabel\"\n :aria-describedby=\"describedBy\"\n :aria-invalid=\"isInvalid ? 'true' : undefined\"\n :aria-required=\"isRequired ? 'true' : undefined\"\n :aria-readonly=\"isReadonly ? 'true' : undefined\"\n :aria-busy=\"loading ? 'true' : undefined\"\n :disabled=\"isDisabled\"\n :class=\"rootClass\"\n @click=\"toggle\"\n @focus=\"emit('focus', $event)\"\n @blur=\"emit('blur', $event)\"\n >\n <span\n data-testid=\"gr-switch-track\"\n data-gr-switch-track\n :class=\"trackClass\"\n :style=\"trackStyle\"\n >\n <span\n v-if=\"stateTextSize\"\n data-testid=\"gr-switch-state-text\"\n data-gr-switch-state-text\n :class=\"stateTextClass\"\n aria-hidden=\"true\"\n >\n <span :class=\"stateTextStackClass\">{{ resolvedStateText }}</span>\n <span\n v-if=\"resolvedAutoWidth\"\n data-gr-switch-state-text-ghost\n :class=\"stateTextGhostClass\"\n >{{ ghostStateText }}</span>\n </span>\n <span\n data-testid=\"gr-switch-thumb\"\n data-gr-switch-thumb\n :class=\"thumbClass\"\n aria-hidden=\"true\"\n >\n <IconLoader v-if=\"loading\" data-gr-switch-spinner :class=\"spinnerClass\" />\n <span\n v-else-if=\"thumbIconSlot\"\n data-testid=\"gr-switch-thumb-icon\"\n data-gr-switch-thumb-icon\n :class=\"thumbIconClass\"\n >\n <slot v-if=\"modelValue\" name=\"checked-icon\" />\n <slot v-else name=\"unchecked-icon\" />\n </span>\n </span>\n </span>\n <span\n v-if=\"$slots.default\"\n data-gr-switch-label\n :class=\"labelClass\"\n >\n <slot />\n </span>\n <span v-if=\"loading\" data-gr-switch-loading-text class=\"sr-only\">{{ resolvedLoadingText }}</span>\n </button>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, ref, watchEffect } from 'vue'\nimport IconLoader from '~icons/lucide/loader-circle'\n\nimport { useGrComponentSize } from '../GrConfigProvider/context'\nimport { useGrFormFieldContext } from '../GrFormField/context'\nimport { useGrComponentProp } from '../../composables/useGrComponentConfig'\nimport { useGrFormControl } from '../../composables/useGrFormControl'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\n\nimport {\n grSwitchLabelClass,\n grSwitchRootClass,\n grSwitchSpinnerClass,\n grSwitchStateTextClass,\n grSwitchThumbClass,\n grSwitchThumbIconClass,\n grSwitchTrackClass,\n isGrSwitchStateTextSize,\n stateTextGhostClass,\n stateTextRoom,\n stateTextStackClass,\n type GrSwitchLabelPosition,\n type GrSwitchSize,\n type GrSwitchStateTextSize,\n} from './grSwitchStyles'\n\nexport type {\n GrSwitchLabelPosition,\n GrSwitchSize,\n GrSwitchStateTextSize,\n} from './grSwitchStyles'\n\n/**\n * Пропсы публичного GR-примитива «Switch».\n */\nexport interface GrSwitchProps {\n /**\n * Значение переключателя. Необязательное: без `v-model` контрол рисуется\n * выключенным — так же, как `GrCheckbox`. Обязательный проп заставлял бы\n * заводить `ref` даже там, где переключатель presentational.\n */\n modelValue?: boolean\n disabled?: boolean\n /** Только для чтения: состояние видно, но не переключается. */\n readonly?: boolean\n /** Визуальное и ARIA-состояние ошибки. */\n invalid?: boolean\n /** Обязательное поле (`aria-required`). */\n required?: boolean\n ariaLabel?: string\n size?: GrSwitchSize\n /** Сторона подписи относительно дорожки. */\n labelPosition?: GrSwitchLabelPosition\n /** Идёт сохранение: бегунок показывает спиннер, переключение заблокировано. */\n loading?: boolean\n /** i18n: что именно грузится. `aria-busy` сам по себе часть AT не объявляет. */\n loadingText?: string\n /** Имя поля для нативной отправки формы. Без него скрытое поле не рендерится. */\n name?: string\n /** Значение, уходящее в форму во включённом состоянии. */\n value?: string\n /** `id` формы, если переключатель лежит вне неё. */\n form?: string\n /** Кастомный цвет фона в активном состоянии. Если не задан — `var(--gr-primary)`. */\n activeBackgroundColor?: string\n /** Кастомный цвет фона в неактивном состоянии. Если не задан — `var(--gr-muted)`. */\n inactiveBackgroundColor?: string\n /**\n * Подпись состояния внутри дорожки — на свободной от бегунка стороне.\n * Помещается только на `md` и `lg`; на мелких ступенях не рисуется.\n */\n showStateText?: boolean\n /** Текст включённого состояния. Без него — `gr.switch.on` из локали. */\n checkedText?: string\n /** Текст выключенного состояния. Без него — `gr.switch.off` из локали. */\n uncheckedText?: string\n /**\n * Дорожка растягивается под подпись, а ступень размера становится нижней\n * границей ширины. Без `showStateText` смысла не имеет: тянуться не под что.\n */\n autoWidth?: boolean\n}\n\nexport interface GrSwitchEmits {\n (e: 'update:modelValue', value: boolean): void\n (e: 'change', value: boolean): void\n (e: 'focus', event: FocusEvent): void\n (e: 'blur', event: FocusEvent): void\n}\n\nconst getCustomColor = (value?: string) => value?.trim() || undefined\n\n// Скрытое поле — сосед кнопки, а не её потомок: интерактивный контент внутри\n// `<button>` невалиден. Из-за этого корень компонента — фрагмент, и атрибуты\n// потребителя надо донести до кнопки руками.\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(\n defineProps<GrSwitchProps>(),\n {\n modelValue: false,\n disabled: false,\n readonly: false,\n invalid: false,\n required: false,\n ariaLabel: undefined,\n size: undefined,\n labelPosition: 'end',\n loading: false,\n loadingText: undefined,\n name: undefined,\n value: 'on',\n form: undefined,\n activeBackgroundColor: undefined,\n inactiveBackgroundColor: undefined,\n // `undefined`, а не `false`: Vue приводит отсутствующий boolean к `false`,\n // и дефолт из `GrConfigProvider` до компонента бы не доехал.\n showStateText: undefined,\n checkedText: undefined,\n uncheckedText: undefined,\n autoWidth: undefined,\n },\n)\n\n// Контекст `GrFormField`: id для `<label for>`, описание ошибкой, невалидность.\n// `<button>` — labelable-элемент, поэтому клик по подписи фокусирует переключатель.\nconst slots = defineSlots<{\n /** Подпись переключателя. */\n 'default'?: () => any\n /**\n * Знак на бегунке во включённом состоянии — галочка, замок, что угодно.\n *\n * Размер задаёт обёртка по ступени `size`, поэтому содержимое слота тянется\n * до неё: `class=\"h-full w-full\"`, как у `GrBadge` и `GrChip`.\n *\n * Знак декоративен — бегунок целиком `aria-hidden`, а состояние диктор берёт\n * из `aria-checked`. Смысла, которого нет больше нигде, сюда класть нельзя.\n */\n 'checked-icon'?: () => any\n /** То же для выключенного состояния. Слоты независимы. */\n 'unchecked-icon'?: () => any\n}>()\n\nconst field = useGrFormFieldContext()\nconst fieldId = computed(() => field?.id.value)\nconst describedBy = computed(() => field?.describedById.value)\nconst {\n disabled: isDisabled,\n invalid: isInvalid,\n required: isRequired,\n readonly: isReadonly,\n} = useGrFormControl(() => props)\n\nconst { t } = useGranularityTranslations()\n\nconst rootEl = ref<HTMLButtonElement | null>(null)\n\nfunction focus(): void {\n rootEl.value?.focus()\n}\n\nfunction blur(): void {\n rootEl.value?.blur()\n}\n\ndefineExpose({ focus, blur })\n\n// Эффективный размер: локальный проп → `GrConfigProvider` → дефолт компонента.\nconst resolvedSize = useGrComponentSize(() => props.size, {\n component: 'GrSwitch',\n supported: ['xs', 'sm', 'md', 'lg'],\n})\n\nconst emit = defineEmits<GrSwitchEmits>()\n\nconst resolvedShowStateText = useGrComponentProp(\n 'GrSwitch',\n 'showStateText',\n () => props.showStateText,\n false,\n)\n\nconst resolvedAutoWidth = useGrComponentProp(\n 'GrSwitch',\n 'autoWidth',\n () => props.autoWidth,\n false,\n)\n\n// Ступень, на которой подпись помещается в дорожку, — иначе её нет вовсе.\nconst stateTextSize = computed<GrSwitchStateTextSize | undefined>(() => {\n if (!resolvedShowStateText.value)\n return undefined\n\n return isGrSwitchStateTextSize(resolvedSize.value) ? resolvedSize.value : undefined\n})\n\nconst hasStateText = computed(() => stateTextSize.value !== undefined)\n\nconst rootClass = computed(() => grSwitchRootClass(props.labelPosition))\n\nconst trackClass = computed(() => grSwitchTrackClass(resolvedSize.value, hasStateText.value && resolvedAutoWidth.value))\n\nconst trackStyle = computed(() => {\n const isChecked = props.modelValue\n const defaultBackgroundColor = isChecked ? 'var(--gr-primary)' : 'var(--gr-muted)'\n const customBackgroundColor = getCustomColor(\n isChecked ? props.activeBackgroundColor : props.inactiveBackgroundColor,\n )\n // Недоступность гасится токеном и перебивает кастомный цвет: иначе выключенный\n // переключатель остался бы таким же ярким, как рабочий.\n const backgroundColor = isDisabled.value\n ? 'var(--gr-disabled-bg)'\n : customBackgroundColor ?? defaultBackgroundColor\n\n return {\n '--gr-switch-track-bg': backgroundColor,\n '--gr-switch-track-brd': isDisabled.value\n ? 'var(--gr-disabled-brd)'\n : customBackgroundColor\n ? backgroundColor\n : isChecked\n ? 'var(--gr-primary)'\n : 'var(--gr-brd)',\n 'backgroundColor': 'var(--gr-switch-track-bg)',\n }\n})\n\nconst thumbClass = computed(() => grSwitchThumbClass({ size: resolvedSize.value, checked: props.modelValue }))\n\nconst spinnerClass = computed(() => grSwitchSpinnerClass(resolvedSize.value))\n\n// Спиннер и иконка занимают центр бегунка: пока идёт запрос, важнее «состояние\n// меняется», чем «каким оно стало».\nconst thumbIconSlot = computed(() => (props.modelValue ? slots['checked-icon'] : slots['unchecked-icon']))\n\nconst thumbIconClass = computed(() => grSwitchThumbIconClass(resolvedSize.value))\n\nconst labelClass = computed(() => grSwitchLabelClass(resolvedSize.value, isDisabled.value))\n\nconst resolvedLoadingText = computed(() => props.loadingText ?? t('gr.switch.loading', 'Saving…'))\n\nconst stateTextClass = computed(() => (stateTextSize.value\n ? grSwitchStateTextClass({\n size: stateTextSize.value,\n checked: props.modelValue,\n disabled: isDisabled.value,\n autoWidth: resolvedAutoWidth.value,\n })\n : ''))\n\nconst checkedStateText = computed(() => props.checkedText ?? t('gr.switch.on', 'ON'))\nconst uncheckedStateText = computed(() => props.uncheckedText ?? t('gr.switch.off', 'OFF'))\n\nconst resolvedStateText = computed(() => (\n props.modelValue ? checkedStateText.value : uncheckedStateText.value\n))\n\n// Невидимый дубль держит ширину: без него дорожка меняла бы размер на каждом\n// щелчке, потому что «вкл» и «выкл» почти никогда не равны по ширине.\nconst ghostStateText = computed(() => (\n props.modelValue ? uncheckedStateText.value : checkedStateText.value\n))\n\nif (__GR_DEV__) {\n watchEffect(() => {\n if (resolvedAutoWidth.value && !resolvedShowStateText.value) {\n console.warn(\n '[granularity] GrSwitch: `autoWidth` без `showStateText` ничего не делает — '\n + 'дорожке не подо что растягиваться.',\n )\n }\n })\n\n watchEffect(() => {\n if (!resolvedShowStateText.value || isGrSwitchStateTextSize(resolvedSize.value))\n return\n\n console.warn(\n `[granularity] GrSwitch: подпись состояния не нарисована на ступени \\`${resolvedSize.value}\\`: `\n + `рядом с бегунком ${stateTextRoom[resolvedSize.value]}px, а минимально читаемой подписи нужен `\n + `${stateTextRoom.md}px. Подписи живут на \\`md\\` и \\`lg\\`.`,\n )\n })\n}\n\n// Выключенный переключатель не отправляется вовсе — так устроен чекбокс в HTML,\n// и сервер отличает «выкл» по отсутствию ключа.\nconst submitsValue = computed(\n () => props.modelValue && !isDisabled.value && Boolean(props.name),\n)\n\nfunction toggle(): void {\n if (isDisabled.value || isReadonly.value || props.loading) {\n return\n }\n\n const next = !props.modelValue\n emit('update:modelValue', next)\n emit('change', next)\n}\n</script>\n\n<template>\n <input\n v-if=\"submitsValue\"\n type=\"hidden\"\n :name=\"name\"\n :value=\"value\"\n :form=\"form\"\n >\n\n <button\n :id=\"fieldId\"\n ref=\"rootEl\"\n v-bind=\"$attrs\"\n type=\"button\"\n role=\"switch\"\n data-gr-switch\n :aria-checked=\"modelValue ? 'true' : 'false'\"\n :aria-label=\"ariaLabel\"\n :aria-describedby=\"describedBy\"\n :aria-invalid=\"isInvalid ? 'true' : undefined\"\n :aria-required=\"isRequired ? 'true' : undefined\"\n :aria-readonly=\"isReadonly ? 'true' : undefined\"\n :aria-busy=\"loading ? 'true' : undefined\"\n :disabled=\"isDisabled\"\n :class=\"rootClass\"\n @click=\"toggle\"\n @focus=\"emit('focus', $event)\"\n @blur=\"emit('blur', $event)\"\n >\n <span\n data-testid=\"gr-switch-track\"\n data-gr-switch-track\n :class=\"trackClass\"\n :style=\"trackStyle\"\n >\n <span\n v-if=\"stateTextSize\"\n data-testid=\"gr-switch-state-text\"\n data-gr-switch-state-text\n :class=\"stateTextClass\"\n aria-hidden=\"true\"\n >\n <span :class=\"stateTextStackClass\">{{ resolvedStateText }}</span>\n <span\n v-if=\"resolvedAutoWidth\"\n data-gr-switch-state-text-ghost\n :class=\"stateTextGhostClass\"\n >{{ ghostStateText }}</span>\n </span>\n <span\n data-testid=\"gr-switch-thumb\"\n data-gr-switch-thumb\n :class=\"thumbClass\"\n aria-hidden=\"true\"\n >\n <IconLoader v-if=\"loading\" data-gr-switch-spinner :class=\"spinnerClass\" />\n <span\n v-else-if=\"thumbIconSlot\"\n data-testid=\"gr-switch-thumb-icon\"\n data-gr-switch-thumb-icon\n :class=\"thumbIconClass\"\n >\n <slot v-if=\"modelValue\" name=\"checked-icon\" />\n <slot v-else name=\"unchecked-icon\" />\n </span>\n </span>\n </span>\n <span\n v-if=\"$slots.default\"\n data-gr-switch-label\n :class=\"labelClass\"\n >\n <slot />\n </span>\n <span v-if=\"loading\" data-gr-switch-loading-text class=\"sr-only\">{{ resolvedLoadingText }}</span>\n </button>\n</template>\n"],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { n as grSwitchSafelist, t as grSwitchConfig } from "../../chunks/config-
|
|
2
|
-
import { t as GrSwitch_default } from "./chunks/GrSwitch-
|
|
1
|
+
import { n as grSwitchSafelist, t as grSwitchConfig } from "../../chunks/config-MUkhktTP.js";
|
|
2
|
+
import { t as GrSwitch_default } from "./chunks/GrSwitch-D7X42uIA.js";
|
|
3
3
|
export { GrSwitch_default as GrSwitch, GrSwitch_default as default, grSwitchConfig, grSwitchSafelist };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { computed, createElementBlock, defineComponent, openBlock, provide, renderSlot, useId } from "vue";
|
|
2
|
+
//#region src/components/GrTabPanels/context.ts
|
|
3
|
+
var GR_TAB_PANELS_KEY = Symbol("gr-tab-panels");
|
|
4
|
+
//#endregion
|
|
5
|
+
//#region src/components/GrTabPanels/GrTabPanels.vue?vue&type=script&setup=true&lang.ts
|
|
6
|
+
var _hoisted_1 = { "data-gr-tab-panels": "" };
|
|
7
|
+
//#endregion
|
|
8
|
+
//#region src/components/GrTabPanels/GrTabPanels.vue
|
|
9
|
+
var GrTabPanels_default = /* @__PURE__ */ defineComponent({
|
|
10
|
+
__name: "GrTabPanels",
|
|
11
|
+
props: {
|
|
12
|
+
modelValue: {},
|
|
13
|
+
idBase: { default: void 0 }
|
|
14
|
+
},
|
|
15
|
+
setup(__props) {
|
|
16
|
+
const props = __props;
|
|
17
|
+
const generatedIdBase = useId();
|
|
18
|
+
const resolvedIdBase = computed(() => props.idBase ?? generatedIdBase);
|
|
19
|
+
provide(GR_TAB_PANELS_KEY, {
|
|
20
|
+
activeValue: computed(() => props.modelValue),
|
|
21
|
+
idBase: resolvedIdBase,
|
|
22
|
+
tabsLinked: computed(() => props.idBase != null)
|
|
23
|
+
});
|
|
24
|
+
return (_ctx, _cache) => {
|
|
25
|
+
return openBlock(), createElementBlock("div", _hoisted_1, [renderSlot(_ctx.$slots, "default")]);
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
//#endregion
|
|
30
|
+
export { GR_TAB_PANELS_KEY as n, GrTabPanels_default as t };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GrTabPanels-BDt5oVdd.js","names":[],"sources":["../../../../src/components/GrTabPanels/context.ts","../../../../src/components/GrTabPanels/GrTabPanels.vue","../../../../src/components/GrTabPanels/GrTabPanels.vue"],"sourcesContent":["import type { ComputedRef, InjectionKey } from 'vue'\n\n/** Контекст, который `GrTabPanels` предоставляет своим `GrTabPanel`. */\nexport interface GrTabPanelsContext {\n /** Значение активной вкладки (совпадает с `modelValue` у `GrTabs`). */\n activeValue: ComputedRef<string>\n /** Общая база id для связки `tab`↔`tabpanel` (см. проп `idBase` у `GrTabs`). */\n idBase: ComputedRef<string>\n /**\n * Задал ли `idBase` потребитель. Без него вкладок с подходящими id не\n * существует: `GrTabs` проставляет их **только** при явном `idBase`, — и\n * ссылаться на них панели нечем.\n */\n tabsLinked: ComputedRef<boolean>\n}\n\nexport const GR_TAB_PANELS_KEY: InjectionKey<GrTabPanelsContext> = Symbol('gr-tab-panels')\n","<script setup lang=\"ts\">\nimport { computed, provide, useId } from 'vue'\n\nimport { GR_TAB_PANELS_KEY } from './context'\n\nexport interface GrTabPanelsProps {\n modelValue: string\n idBase?: string\n}\n\n/**\n * GrTabPanels — контейнер `tabpanel`-ов, companion к `GrTabs`.\n *\n * Показывает панель, чьё `value` совпадает с `modelValue`, и связывает её с\n * соответствующей вкладкой по ARIA (`role=\"tabpanel\"`, `aria-labelledby`).\n *\n * Для полной связки `tab`↔`tabpanel` передайте **одинаковый `idBase`** и в\n * `GrTabs`, и в `GrTabPanels` — тогда id вкладок и панелей совпадут\n * (`aria-controls` ↔ `aria-labelledby`).\n */\nconst props = withDefaults(\n defineProps<GrTabPanelsProps>(),\n {\n idBase: undefined,\n },\n)\n\nconst generatedIdBase = useId()\n// `computed`, а не значение: `idBase` — реактивный проп, и вычисленный один раз\n// при setup он оставил бы панели со старыми id, пока `GrTabs` уехал бы на новые.\n// Связка `aria-controls` ↔ `aria-labelledby` разъезжается молча.\nconst resolvedIdBase = computed(() => props.idBase ?? generatedIdBase)\n\nprovide(GR_TAB_PANELS_KEY, {\n activeValue: computed(() => props.modelValue),\n idBase: resolvedIdBase,\n tabsLinked: computed(() => props.idBase != null),\n})\n\ndefineSlots<{\n /** Панели (`GrTabPanel`). */\n default?: () => any\n}>()\n</script>\n\n<template>\n <div data-gr-tab-panels>\n <slot />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, provide, useId } from 'vue'\n\nimport { GR_TAB_PANELS_KEY } from './context'\n\nexport interface GrTabPanelsProps {\n modelValue: string\n idBase?: string\n}\n\n/**\n * GrTabPanels — контейнер `tabpanel`-ов, companion к `GrTabs`.\n *\n * Показывает панель, чьё `value` совпадает с `modelValue`, и связывает её с\n * соответствующей вкладкой по ARIA (`role=\"tabpanel\"`, `aria-labelledby`).\n *\n * Для полной связки `tab`↔`tabpanel` передайте **одинаковый `idBase`** и в\n * `GrTabs`, и в `GrTabPanels` — тогда id вкладок и панелей совпадут\n * (`aria-controls` ↔ `aria-labelledby`).\n */\nconst props = withDefaults(\n defineProps<GrTabPanelsProps>(),\n {\n idBase: undefined,\n },\n)\n\nconst generatedIdBase = useId()\n// `computed`, а не значение: `idBase` — реактивный проп, и вычисленный один раз\n// при setup он оставил бы панели со старыми id, пока `GrTabs` уехал бы на новые.\n// Связка `aria-controls` ↔ `aria-labelledby` разъезжается молча.\nconst resolvedIdBase = computed(() => props.idBase ?? generatedIdBase)\n\nprovide(GR_TAB_PANELS_KEY, {\n activeValue: computed(() => props.modelValue),\n idBase: resolvedIdBase,\n tabsLinked: computed(() => props.idBase != null),\n})\n\ndefineSlots<{\n /** Панели (`GrTabPanel`). */\n default?: () => any\n}>()\n</script>\n\n<template>\n <div data-gr-tab-panels>\n <slot />\n </div>\n</template>\n"],"mappings":";;AAgBA,IAAa,oBAAsD,OAAO,eAAe;;;;;;;;;;;;;ECIzF,MAAM,QAAQ;EAOd,MAAM,kBAAkB,MAAM;EAI9B,MAAM,iBAAiB,eAAe,MAAM,UAAU,eAAe;EAErE,QAAQ,mBAAmB;GACzB,aAAa,eAAe,MAAM,UAAU;GAC5C,QAAQ;GACR,YAAY,eAAe,MAAM,UAAU,IAAI;EACjD,CAAC;;GASC,OAAA,UAAA,GAAA,mBAEM,OAFN,YAEM,CADJ,WAAQ,KAAA,QAAA,SAAA,CAAA,CAAA"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { n as GR_TAB_PANELS_KEY } from "./GrTabPanels-BDt5oVdd.js";
|
|
2
|
+
import { Transition, computed, createBlock, createCommentVNode, createElementBlock, defineComponent, inject, onMounted, openBlock, ref, renderSlot, watch, withCtx } from "vue";
|
|
3
|
+
//#region src/components/GrTabPanels/GrTabPanel.vue?vue&type=script&setup=true&lang.ts
|
|
4
|
+
var _hoisted_1 = [
|
|
5
|
+
"id",
|
|
6
|
+
"aria-labelledby",
|
|
7
|
+
"hidden",
|
|
8
|
+
"tabindex"
|
|
9
|
+
];
|
|
10
|
+
//#endregion
|
|
11
|
+
//#region src/components/GrTabPanels/GrTabPanel.vue
|
|
12
|
+
var GrTabPanel_default = /* @__PURE__ */ defineComponent({
|
|
13
|
+
__name: "GrTabPanel",
|
|
14
|
+
props: {
|
|
15
|
+
value: {},
|
|
16
|
+
keepAlive: {
|
|
17
|
+
type: Boolean,
|
|
18
|
+
default: false
|
|
19
|
+
},
|
|
20
|
+
lazy: {
|
|
21
|
+
type: Boolean,
|
|
22
|
+
default: false
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
setup(__props) {
|
|
26
|
+
const props = __props;
|
|
27
|
+
const ctx = inject(GR_TAB_PANELS_KEY, null);
|
|
28
|
+
const isActive = computed(() => ctx ? ctx.activeValue.value === props.value : true);
|
|
29
|
+
const panelId = computed(() => ctx ? `${ctx.idBase.value}-panel-${props.value}` : void 0);
|
|
30
|
+
const tabId = computed(() => ctx ? `${ctx.idBase.value}-tab-${props.value}` : void 0);
|
|
31
|
+
/**
|
|
32
|
+
* Без общего `idBase` вкладки с таким id не существует, и `aria-labelledby`
|
|
33
|
+
* указывал бы в пустоту. Панель без имени — потеря, а ссылка в никуда — ложь:
|
|
34
|
+
* диктор объявляет её пустой строкой вместо «нет подписи», и починить это
|
|
35
|
+
* потребитель уже не может.
|
|
36
|
+
*/
|
|
37
|
+
const labelledBy = computed(() => ctx?.tabsLinked.value ? tabId.value : void 0);
|
|
38
|
+
const wasActive = ref(isActive.value);
|
|
39
|
+
watch(isActive, (active) => {
|
|
40
|
+
if (active) wasActive.value = true;
|
|
41
|
+
});
|
|
42
|
+
const shouldRender = computed(() => {
|
|
43
|
+
if (isActive.value) return true;
|
|
44
|
+
if (!props.keepAlive) return false;
|
|
45
|
+
return props.lazy ? wasActive.value : true;
|
|
46
|
+
});
|
|
47
|
+
/**
|
|
48
|
+
* Панель ссылается на вкладку по id, а существует ли вкладка — знает только
|
|
49
|
+
* приложение: `GrTabs` с другим (или отсутствующим) `idBase` оставит
|
|
50
|
+
* `aria-labelledby` висеть в пустоту. Проверяем это в dev, как `GrFormField`
|
|
51
|
+
* проверяет забытый контрол.
|
|
52
|
+
*/
|
|
53
|
+
if (process.env.NODE_ENV !== "production") onMounted(() => {
|
|
54
|
+
if (!ctx || !isActive.value) return;
|
|
55
|
+
if (!ctx.tabsLinked.value) {
|
|
56
|
+
console.warn("[GrTabPanel] Панель не связана с вкладкой: у неё нет доступного имени. Передайте один и тот же `idBase` в `GrTabs` и `GrTabPanels`.");
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
if (tabId.value && !document.getElementById(tabId.value)) console.warn(`[GrTabPanel] Вкладки с id "${tabId.value}" нет в документе: \`aria-labelledby\` ссылается в пустоту. Передайте один и тот же \`idBase\` в \`GrTabs\` и \`GrTabPanels\`.`);
|
|
60
|
+
});
|
|
61
|
+
return (_ctx, _cache) => {
|
|
62
|
+
return openBlock(), createBlock(Transition, {
|
|
63
|
+
"enter-active-class": "transition ease-[var(--gr-ease-out)] duration-[var(--gr-duration-fast)]",
|
|
64
|
+
"enter-from-class": "transform opacity-0 translate-y-1",
|
|
65
|
+
"enter-to-class": "transform opacity-100 translate-y-0"
|
|
66
|
+
}, {
|
|
67
|
+
default: withCtx(() => [shouldRender.value ? (openBlock(), createElementBlock("div", {
|
|
68
|
+
key: 0,
|
|
69
|
+
id: panelId.value,
|
|
70
|
+
role: "tabpanel",
|
|
71
|
+
"data-gr-tab-panel": "",
|
|
72
|
+
"aria-labelledby": labelledBy.value,
|
|
73
|
+
hidden: __props.keepAlive && !isActive.value ? true : void 0,
|
|
74
|
+
tabindex: isActive.value ? 0 : void 0,
|
|
75
|
+
class: "rounded-[var(--gr-radius-md)] focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--gr-ring)]"
|
|
76
|
+
}, [renderSlot(_ctx.$slots, "default")], 8, _hoisted_1)) : createCommentVNode("", true)]),
|
|
77
|
+
_: 3
|
|
78
|
+
});
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
//#endregion
|
|
83
|
+
export { GrTabPanel_default as t };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GrTabPanels-BJvAflnA.js","names":[],"sources":["../../../../src/components/GrTabPanels/GrTabPanel.vue","../../../../src/components/GrTabPanels/GrTabPanel.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, inject, onMounted, ref, watch } from 'vue'\n\nimport { GR_TAB_PANELS_KEY } from './context'\n\nexport interface GrTabPanelProps {\n value: string\n keepAlive?: boolean\n /**\n * Не монтировать содержимое, пока панель не показали впервые. Имеет смысл\n * вместе с `keepAlive`: без него неактивная панель и так не в DOM.\n */\n lazy?: boolean\n}\n\n/**\n * GrTabPanel — одна панель внутри `GrTabPanels`. Показывается, когда её `value`\n * равно активной вкладке. `keepAlive` оставляет неактивные панели в DOM\n * (скрытыми через `hidden`) — полезно, чтобы не терять состояние форм.\n */\nconst props = withDefaults(\n defineProps<GrTabPanelProps>(),\n {\n keepAlive: false,\n lazy: false,\n },\n)\n\nconst ctx = inject(GR_TAB_PANELS_KEY, null)\n\nconst isActive = computed(() => (ctx ? ctx.activeValue.value === props.value : true))\n// id совпадают с id вкладок `GrTabs` при одинаковом `idBase` → корректная ARIA-связка.\nconst panelId = computed(() => (ctx ? `${ctx.idBase.value}-panel-${props.value}` : undefined))\nconst tabId = computed(() => (ctx ? `${ctx.idBase.value}-tab-${props.value}` : undefined))\n\n/**\n * Без общего `idBase` вкладки с таким id не существует, и `aria-labelledby`\n * указывал бы в пустоту. Панель без имени — потеря, а ссылка в никуда — ложь:\n * диктор объявляет её пустой строкой вместо «нет подписи», и починить это\n * потребитель уже не может.\n */\nconst labelledBy = computed(() => (ctx?.tabsLinked.value ? tabId.value : undefined))\n\nconst wasActive = ref(isActive.value)\nwatch(isActive, (active) => {\n if (active)\n wasActive.value = true\n})\n\nconst shouldRender = computed(() => {\n if (isActive.value)\n return true\n if (!props.keepAlive)\n return false\n return props.lazy ? wasActive.value : true\n})\n\n/**\n * Панель ссылается на вкладку по id, а существует ли вкладка — знает только\n * приложение: `GrTabs` с другим (или отсутствующим) `idBase` оставит\n * `aria-labelledby` висеть в пустоту. Проверяем это в dev, как `GrFormField`\n * проверяет забытый контрол.\n */\nif (__GR_DEV__) {\n onMounted(() => {\n if (!ctx || !isActive.value)\n return\n\n if (!ctx.tabsLinked.value) {\n console.warn(\n '[GrTabPanel] Панель не связана с вкладкой: у неё нет доступного имени. '\n + 'Передайте один и тот же `idBase` в `GrTabs` и `GrTabPanels`.',\n )\n return\n }\n\n if (tabId.value && !document.getElementById(tabId.value)) {\n console.warn(\n `[GrTabPanel] Вкладки с id \"${tabId.value}\" нет в документе: `\n + '`aria-labelledby` ссылается в пустоту. Передайте один и тот же `idBase` в `GrTabs` и `GrTabPanels`.',\n )\n }\n })\n}\n\n/*\n * Появление панели — `<Transition>` в шаблоне, и у него есть только фаза входа.\n * Уходящая панель обязана исчезать мгновенно: две панели одновременно\n * растянули бы контейнер на высоту обеих, и смена вкладки дёргала бы страницу.\n * При `keepAlive` перехода не будет вовсе — панель из DOM не уходит, а `hidden`\n * это `display: none`, который не анимируется в принципе.\n */\n\ndefineSlots<{\n /** Содержимое панели. */\n default?: () => any\n}>()\n</script>\n\n<template>\n <Transition\n enter-active-class=\"transition ease-[var(--gr-ease-out)] duration-[var(--gr-duration-fast)]\"\n enter-from-class=\"transform opacity-0 translate-y-1\"\n enter-to-class=\"transform opacity-100 translate-y-0\"\n >\n <div\n v-if=\"shouldRender\"\n :id=\"panelId\"\n role=\"tabpanel\"\n data-gr-tab-panel\n :aria-labelledby=\"labelledBy\"\n :hidden=\"keepAlive && !isActive ? true : undefined\"\n :tabindex=\"isActive ? 0 : undefined\"\n class=\"rounded-[var(--gr-radius-md)] focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--gr-ring)]\"\n >\n <slot />\n </div>\n </Transition>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, inject, onMounted, ref, watch } from 'vue'\n\nimport { GR_TAB_PANELS_KEY } from './context'\n\nexport interface GrTabPanelProps {\n value: string\n keepAlive?: boolean\n /**\n * Не монтировать содержимое, пока панель не показали впервые. Имеет смысл\n * вместе с `keepAlive`: без него неактивная панель и так не в DOM.\n */\n lazy?: boolean\n}\n\n/**\n * GrTabPanel — одна панель внутри `GrTabPanels`. Показывается, когда её `value`\n * равно активной вкладке. `keepAlive` оставляет неактивные панели в DOM\n * (скрытыми через `hidden`) — полезно, чтобы не терять состояние форм.\n */\nconst props = withDefaults(\n defineProps<GrTabPanelProps>(),\n {\n keepAlive: false,\n lazy: false,\n },\n)\n\nconst ctx = inject(GR_TAB_PANELS_KEY, null)\n\nconst isActive = computed(() => (ctx ? ctx.activeValue.value === props.value : true))\n// id совпадают с id вкладок `GrTabs` при одинаковом `idBase` → корректная ARIA-связка.\nconst panelId = computed(() => (ctx ? `${ctx.idBase.value}-panel-${props.value}` : undefined))\nconst tabId = computed(() => (ctx ? `${ctx.idBase.value}-tab-${props.value}` : undefined))\n\n/**\n * Без общего `idBase` вкладки с таким id не существует, и `aria-labelledby`\n * указывал бы в пустоту. Панель без имени — потеря, а ссылка в никуда — ложь:\n * диктор объявляет её пустой строкой вместо «нет подписи», и починить это\n * потребитель уже не может.\n */\nconst labelledBy = computed(() => (ctx?.tabsLinked.value ? tabId.value : undefined))\n\nconst wasActive = ref(isActive.value)\nwatch(isActive, (active) => {\n if (active)\n wasActive.value = true\n})\n\nconst shouldRender = computed(() => {\n if (isActive.value)\n return true\n if (!props.keepAlive)\n return false\n return props.lazy ? wasActive.value : true\n})\n\n/**\n * Панель ссылается на вкладку по id, а существует ли вкладка — знает только\n * приложение: `GrTabs` с другим (или отсутствующим) `idBase` оставит\n * `aria-labelledby` висеть в пустоту. Проверяем это в dev, как `GrFormField`\n * проверяет забытый контрол.\n */\nif (__GR_DEV__) {\n onMounted(() => {\n if (!ctx || !isActive.value)\n return\n\n if (!ctx.tabsLinked.value) {\n console.warn(\n '[GrTabPanel] Панель не связана с вкладкой: у неё нет доступного имени. '\n + 'Передайте один и тот же `idBase` в `GrTabs` и `GrTabPanels`.',\n )\n return\n }\n\n if (tabId.value && !document.getElementById(tabId.value)) {\n console.warn(\n `[GrTabPanel] Вкладки с id \"${tabId.value}\" нет в документе: `\n + '`aria-labelledby` ссылается в пустоту. Передайте один и тот же `idBase` в `GrTabs` и `GrTabPanels`.',\n )\n }\n })\n}\n\n/*\n * Появление панели — `<Transition>` в шаблоне, и у него есть только фаза входа.\n * Уходящая панель обязана исчезать мгновенно: две панели одновременно\n * растянули бы контейнер на высоту обеих, и смена вкладки дёргала бы страницу.\n * При `keepAlive` перехода не будет вовсе — панель из DOM не уходит, а `hidden`\n * это `display: none`, который не анимируется в принципе.\n */\n\ndefineSlots<{\n /** Содержимое панели. */\n default?: () => any\n}>()\n</script>\n\n<template>\n <Transition\n enter-active-class=\"transition ease-[var(--gr-ease-out)] duration-[var(--gr-duration-fast)]\"\n enter-from-class=\"transform opacity-0 translate-y-1\"\n enter-to-class=\"transform opacity-100 translate-y-0\"\n >\n <div\n v-if=\"shouldRender\"\n :id=\"panelId\"\n role=\"tabpanel\"\n data-gr-tab-panel\n :aria-labelledby=\"labelledBy\"\n :hidden=\"keepAlive && !isActive ? true : undefined\"\n :tabindex=\"isActive ? 0 : undefined\"\n class=\"rounded-[var(--gr-radius-md)] focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--gr-ring)]\"\n >\n <slot />\n </div>\n </Transition>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;EAoBA,MAAM,QAAQ;EAQd,MAAM,MAAM,OAAO,mBAAmB,IAAI;EAE1C,MAAM,WAAW,eAAgB,MAAM,IAAI,YAAY,UAAU,MAAM,QAAQ,IAAK;EAEpF,MAAM,UAAU,eAAgB,MAAM,GAAG,IAAI,OAAO,MAAM,SAAS,MAAM,UAAU,KAAA,CAAU;EAC7F,MAAM,QAAQ,eAAgB,MAAM,GAAG,IAAI,OAAO,MAAM,OAAO,MAAM,UAAU,KAAA,CAAU;;;;;;;EAQzF,MAAM,aAAa,eAAgB,KAAK,WAAW,QAAQ,MAAM,QAAQ,KAAA,CAAU;EAEnF,MAAM,YAAY,IAAI,SAAS,KAAK;EACpC,MAAM,WAAW,WAAW;GAC1B,IAAI,QACF,UAAU,QAAQ;EACtB,CAAC;EAED,MAAM,eAAe,eAAe;GAClC,IAAI,SAAS,OACX,OAAO;GACT,IAAI,CAAC,MAAM,WACT,OAAO;GACT,OAAO,MAAM,OAAO,UAAU,QAAQ;EACxC,CAAC;;;;;;;EAQD,IAAA,QAAA,IAAA,aAAA,cACE,gBAAgB;GACd,IAAI,CAAC,OAAO,CAAC,SAAS,OACpB;GAEF,IAAI,CAAC,IAAI,WAAW,OAAO;IACzB,QAAQ,KACN,qIAEF;IACA;GACF;GAEA,IAAI,MAAM,SAAS,CAAC,SAAS,eAAe,MAAM,KAAK,GACrD,QAAQ,KACN,8BAA8B,MAAM,MAAM,+HAE5C;EAEJ,CAAC;;GAkBD,OAAA,UAAA,GAAA,YAiBa,YAAA;IAhBX,sBAAmB;IACnB,oBAAiB;IACjB,kBAAe;;IAEf,SAAA,cAWM,CAVE,aAAA,SADR,UAAA,GAAA,mBAWM,OAAA;;KATH,IAAI,QAAA;KACL,MAAK;KACL,qBAAA;KACC,mBAAiB,WAAA;KACjB,QAAQ,QAAA,aAAS,CAAK,SAAA,QAAQ,OAAU,KAAA;KACxC,UAAU,SAAA,QAAQ,IAAO,KAAA;KAC1B,OAAM;IAEN,GAAA,CAAA,WAAQ,KAAA,QAAA,SAAA,CAAA,GAAA,GAAA,UAAA,KAAA,mBAAA,IAAA,IAAA,CAAA,CAAA"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { t as GrTabPanels_default } from "./chunks/GrTabPanels-BDt5oVdd.js";
|
|
2
|
+
import { t as GrTabPanel_default } from "./chunks/GrTabPanels-BJvAflnA.js";
|
|
2
3
|
import { t as grTabPanelsConfig } from "../../chunks/config-eXB87DOi.js";
|
|
3
4
|
export { GrTabPanel_default as GrTabPanel, GrTabPanels_default as GrTabPanels, GrTabPanels_default as default, grTabPanelsConfig };
|
|
@@ -2,7 +2,7 @@ import { a as useGrComponentSize } from "../../../chunks/context-CPMRfwVr.js";
|
|
|
2
2
|
import { n as useGranularityTranslations } from "../../../chunks/granularityI18n-BC5zsj_d.js";
|
|
3
3
|
import { t as GrSkeleton_default } from "../../GrSkeleton/chunks/GrSkeleton-CgfXxPQ2.js";
|
|
4
4
|
import { n as hasMeaningfulSlotContent } from "../../../chunks/slotNodes-DxNXpC7v.js";
|
|
5
|
-
import { a as
|
|
5
|
+
import { a as stickyColumnStripedClass, i as stickyColumnHoverableClass, n as hoverableClass, o as stripedClass, r as loadingRowCellClass, s as tableSizes, t as emptyCellClass } from "../../../chunks/grTableStyles-CPSxDTOW.js";
|
|
6
6
|
import { Fragment, computed, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, normalizeClass, normalizeStyle, openBlock, ref, renderList, renderSlot, toDisplayString, unref, useSlots } from "vue";
|
|
7
7
|
//#region src/components/GrTable/GrTable.vue?vue&type=script&setup=true&lang.ts
|
|
8
8
|
var _hoisted_1 = [
|
|
@@ -11,6 +11,7 @@ var _hoisted_1 = [
|
|
|
11
11
|
"aria-busy"
|
|
12
12
|
];
|
|
13
13
|
var _hoisted_2 = [
|
|
14
|
+
"role",
|
|
14
15
|
"aria-label",
|
|
15
16
|
"aria-labelledby",
|
|
16
17
|
"aria-rowcount"
|
|
@@ -19,14 +20,14 @@ var _hoisted_3 = {
|
|
|
19
20
|
key: 0,
|
|
20
21
|
class: "sr-only"
|
|
21
22
|
};
|
|
22
|
-
var _hoisted_4 =
|
|
23
|
-
var _hoisted_5 =
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
var
|
|
28
|
-
var
|
|
29
|
-
key:
|
|
23
|
+
var _hoisted_4 = { key: 1 };
|
|
24
|
+
var _hoisted_5 = ["colspan"];
|
|
25
|
+
var _hoisted_6 = { key: 2 };
|
|
26
|
+
var _hoisted_7 = { "data-gr-table-empty": "" };
|
|
27
|
+
var _hoisted_8 = ["colspan"];
|
|
28
|
+
var _hoisted_9 = { key: 4 };
|
|
29
|
+
var _hoisted_10 = {
|
|
30
|
+
key: 5,
|
|
30
31
|
class: "text-[var(--gr-fg)]"
|
|
31
32
|
};
|
|
32
33
|
//#endregion
|
|
@@ -58,10 +59,19 @@ var GrTable_default = /* @__PURE__ */ defineComponent({
|
|
|
58
59
|
type: Boolean,
|
|
59
60
|
default: false
|
|
60
61
|
},
|
|
62
|
+
rowGroups: {
|
|
63
|
+
type: Boolean,
|
|
64
|
+
default: false
|
|
65
|
+
},
|
|
66
|
+
role: { default: "table" },
|
|
61
67
|
stickyHeader: {
|
|
62
68
|
type: Boolean,
|
|
63
69
|
default: false
|
|
64
70
|
},
|
|
71
|
+
stickyColumn: {
|
|
72
|
+
type: Boolean,
|
|
73
|
+
default: false
|
|
74
|
+
},
|
|
65
75
|
rowCount: { default: void 0 },
|
|
66
76
|
fixedLayout: {
|
|
67
77
|
type: Boolean,
|
|
@@ -85,11 +95,31 @@ var GrTable_default = /* @__PURE__ */ defineComponent({
|
|
|
85
95
|
const showRows = computed(() => !props.loading && !isEmpty.value);
|
|
86
96
|
const loadingRowCount = computed(() => Math.max(1, Math.trunc(props.loadingRows)));
|
|
87
97
|
const serviceColSpan = computed(() => Math.max(1, Math.trunc(props.columnCount)));
|
|
88
|
-
|
|
98
|
+
/**
|
|
99
|
+
* Цвет текста, полосатость и подсветка висят на таблице, а не на теле: групп у
|
|
100
|
+
* тела может быть много (`rowGroups`), и рисует их потребитель — правило,
|
|
101
|
+
* привязанное к одной группе, до остальных не дотянулось бы, а цвет и вовсе
|
|
102
|
+
* не достался бы ни одной.
|
|
103
|
+
*/
|
|
104
|
+
const bodyClass = computed(() => [
|
|
89
105
|
"text-[var(--gr-fg)]",
|
|
90
106
|
props.striped && showRows.value ? stripedClass : "",
|
|
91
107
|
props.hoverable && showRows.value ? hoverableClass : ""
|
|
92
108
|
].filter(Boolean).join(" "));
|
|
109
|
+
const stickyColumnClass = computed(() => {
|
|
110
|
+
if (!props.stickyColumn) return "";
|
|
111
|
+
return [
|
|
112
|
+
"[&_tr>*:first-child]:sticky",
|
|
113
|
+
"[&_tr>*:first-child]:left-0",
|
|
114
|
+
"[&_tr>*:first-child]:z-[2]",
|
|
115
|
+
"[&_tr>*:first-child]:shadow-[var(--gr-table-sticky-column-shadow,4px_0_6px_-4px_rgba(0,0,0,0.25))]",
|
|
116
|
+
"[&>tbody>tr>*:first-child]:bg-[var(--gr-card)]",
|
|
117
|
+
"[&>tfoot>tr>*:first-child]:bg-[var(--gr-card)]",
|
|
118
|
+
"[&>thead>tr>*:first-child]:bg-[var(--gr-muted)]",
|
|
119
|
+
props.striped && showRows.value ? stickyColumnStripedClass : "",
|
|
120
|
+
props.hoverable && showRows.value ? stickyColumnHoverableClass : ""
|
|
121
|
+
].filter(Boolean).join(" ");
|
|
122
|
+
});
|
|
93
123
|
const scrollStyle = computed(() => {
|
|
94
124
|
const anchor = props.rowCount === void 0 ? void 0 : { overflowAnchor: "none" };
|
|
95
125
|
if (props.maxHeight === void 0) return anchor;
|
|
@@ -151,7 +181,13 @@ var GrTable_default = /* @__PURE__ */ defineComponent({
|
|
|
151
181
|
style: normalizeStyle(scrollStyle.value)
|
|
152
182
|
}, [createElementVNode("table", {
|
|
153
183
|
"data-gr-table": "",
|
|
154
|
-
|
|
184
|
+
role: __props.role === "grid" ? "grid" : void 0,
|
|
185
|
+
class: normalizeClass(["min-w-full", [
|
|
186
|
+
tableTextClass.value,
|
|
187
|
+
bodyClass.value,
|
|
188
|
+
stickyColumnClass.value,
|
|
189
|
+
__props.fixedLayout ? "[table-layout:fixed]" : ""
|
|
190
|
+
]]),
|
|
155
191
|
style: normalizeStyle(tableStyle.value),
|
|
156
192
|
"aria-label": __props.ariaLabelledby ? void 0 : __props.ariaLabel,
|
|
157
193
|
"aria-labelledby": __props.ariaLabelledby,
|
|
@@ -159,19 +195,19 @@ var GrTable_default = /* @__PURE__ */ defineComponent({
|
|
|
159
195
|
}, [
|
|
160
196
|
hasCaption.value ? (openBlock(), createElementBlock("caption", _hoisted_3, [renderSlot(_ctx.$slots, "caption", {}, () => [createTextVNode(toDisplayString(__props.caption), 1)])])) : createCommentVNode("", true),
|
|
161
197
|
createElementVNode("thead", { class: normalizeClass(theadClass.value) }, [renderSlot(_ctx.$slots, "header")], 2),
|
|
162
|
-
|
|
198
|
+
__props.loading ? (openBlock(), createElementBlock("tbody", _hoisted_4, [renderSlot(_ctx.$slots, "loading", {}, () => [(openBlock(true), createElementBlock(Fragment, null, renderList(loadingRowCount.value, (row) => {
|
|
163
199
|
return openBlock(), createElementBlock("tr", {
|
|
164
200
|
key: row,
|
|
165
201
|
"data-gr-table-loading-row": ""
|
|
166
202
|
}, [createElementVNode("td", {
|
|
167
203
|
colspan: serviceColSpan.value,
|
|
168
204
|
class: normalizeClass(unref(loadingRowCellClass))
|
|
169
|
-
}, [createVNode(GrSkeleton_default)], 10,
|
|
170
|
-
}), 128))]
|
|
205
|
+
}, [createVNode(GrSkeleton_default)], 10, _hoisted_5)]);
|
|
206
|
+
}), 128))])])) : isEmpty.value ? (openBlock(), createElementBlock("tbody", _hoisted_6, [createElementVNode("tr", _hoisted_7, [createElementVNode("td", {
|
|
171
207
|
colspan: serviceColSpan.value,
|
|
172
208
|
class: normalizeClass(unref(emptyCellClass))
|
|
173
|
-
}, [renderSlot(_ctx.$slots, "empty", {}, () => [createTextVNode(toDisplayString(resolvedEmptyText.value), 1)])], 10,
|
|
174
|
-
unref(slots).footer ? (openBlock(), createElementBlock("tfoot",
|
|
209
|
+
}, [renderSlot(_ctx.$slots, "empty", {}, () => [createTextVNode(toDisplayString(resolvedEmptyText.value), 1)])], 10, _hoisted_8)])])) : __props.rowGroups ? renderSlot(_ctx.$slots, "default", {}, void 0, void 0, 3) : (openBlock(), createElementBlock("tbody", _hoisted_9, [renderSlot(_ctx.$slots, "default")])),
|
|
210
|
+
unref(slots).footer ? (openBlock(), createElementBlock("tfoot", _hoisted_10, [renderSlot(_ctx.$slots, "footer")])) : createCommentVNode("", true)
|
|
175
211
|
], 14, _hoisted_2)], 12, _hoisted_1);
|
|
176
212
|
};
|
|
177
213
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GrTable-BQitSDep.js","names":[],"sources":["../../../../src/components/GrTable/GrTable.vue","../../../../src/components/GrTable/GrTable.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, useSlots } from 'vue'\n\nimport { useGrComponentSize } from '../GrConfigProvider/context'\nimport GrSkeleton from '../GrSkeleton/GrSkeleton.vue'\nimport { hasMeaningfulSlotContent } from '../shared/slotNodes'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport {\n emptyCellClass,\n hoverableClass,\n loadingRowCellClass,\n stickyColumnHoverableClass,\n stickyColumnStripedClass,\n stripedClass,\n tableSizes,\n type GrTableSize,\n} from './grTableStyles'\n\nexport interface GrTableProps {\n /**\n * Размер таблицы — базовый кегль текста. Паддинги ячеек оставлены за\n * консьюмером (GrTable — «тонкий» контейнер).\n */\n size?: GrTableSize\n /**\n * Текст caption для screen reader'ов. Рендерится как `<caption class=\"sr-only\">`,\n * если не передан слот `#caption`.\n */\n caption?: string\n /** Прямой ARIA-label для `<table>`. Игнорируется, если задан `ariaLabelledby`. */\n ariaLabel?: string\n /** ID элемента-заголовка, связанного с `<table>` через `aria-labelledby`. */\n ariaLabelledby?: string\n /**\n * ARIA-label для скролл-контейнера. Включает `role=\"region\"`; сам скролл\n * достижим с клавиатуры всегда, независимо от метки.\n */\n regionLabel?: string\n /** Идёт загрузка: вместо строк — скелетоны, контейнер помечен `aria-busy`. */\n loading?: boolean\n /** Сколько строк-заглушек показать при `loading`. */\n loadingRows?: number\n /** Сколько колонок занимает служебная строка (пустое состояние и скелетоны). */\n columnCount?: number\n /** Текст пустого состояния. Слот `#empty` сильнее. */\n emptyText?: string\n /** Таблица пуста. По умолчанию определяется по содержимому слота. */\n empty?: boolean\n /** Чередование строк. */\n striped?: boolean\n /** Подсветка строки под курсором. */\n hoverable?: boolean\n /**\n * Тело собрано группами строк, и рисует их потребитель: слот по умолчанию\n * встаёт прямо в таблицу, без обёртки в `<tbody>`.\n *\n * Нужно там, где пара строк обязана мериться и жить вместе — второй ярус\n * `GrDataTable` рядом со своей строкой. Обернуть две `<tr>` в таблице больше\n * не во что: группа строк — единственный контейнер, который для них\n * существует.\n */\n rowGroups?: boolean\n /**\n * Роль таблицы. `grid` — интерактивная сетка с клавиатурой по ячейкам\n * (паттерн WAI-ARIA `grid`): она объявляет диктору, что по таблице ходят\n * стрелками, а не читают её как статичную.\n *\n * Роль ставит тот, кто клавиатуру и реализует, — сама по себе она обещание,\n * которое таблица не выполняет.\n */\n role?: 'table' | 'grid'\n /**\n * Прилипающий заголовок: `<thead>` остаётся видимым при вертикальном скролле.\n * Осмысленно вместе с `maxHeight` (иначе таблица не скроллится вертикально).\n */\n stickyHeader?: boolean\n /**\n * Прилипающая первая колонка: остаётся видимой при горизонтальном скролле.\n *\n * Только первая, и это не упрощение: `left` со второй колонки равен сумме\n * ширин предыдущих, а ячейки принадлежат потребителю — мерить их «тонкому»\n * контейнеру нечем. Многоколоночное закрепление есть у `GrDataTable`: он\n * знает свои колонки и меряет смещения сам.\n */\n stickyColumn?: boolean\n /**\n * Полное число строк набора, включая строки заголовка (`aria-rowcount`).\n *\n * Нужен, когда в DOM не весь набор — например, при виртуализации: диктор\n * считает строки по разметке и объявил бы «5 из 20» на таблице в десять\n * тысяч. Строки при этом обязаны нести `aria-rowindex`.\n */\n rowCount?: number\n /**\n * Фиксированная раскладка (`table-layout: fixed`): ширины колонок берутся из\n * первой строки, а не из содержимого всех.\n *\n * Обязателен, если в DOM не весь набор: иначе ширины считаются по\n * отрисованному окну и прыгают на каждой прокрутке.\n *\n * Класс — arbitrary-значение, а не `table-fixed`: такого правила в\n * `presetMini` нет, и класс молча не превратился бы в CSS.\n */\n fixedLayout?: boolean\n /**\n * Минимальная ширина самой таблицы (число — пиксели).\n *\n * Нужна при `fixedLayout`: с фиксированной раскладкой и шириной `auto`\n * браузер вписывает таблицу в контейнер и делит место между колонками\n * пропорционально — то есть заданные ширины молча ужимаются, а\n * горизонтальной прокрутки, на которой держатся закреплённые колонки, не\n * возникает вовсе.\n */\n tableMinWidth?: string | number\n /**\n * Максимальная высота скролл-контейнера (включает вертикальный скролл).\n * Число трактуется как пиксели. Нужен для работы `stickyHeader`.\n */\n maxHeight?: string | number\n}\n\n/**\n * `GrTable` — «тонкий» GR-контейнер для табличных данных.\n *\n * Рендерит `<table>` внутри скролл-обёртки и даёт слоты `#caption`, `#header`,\n * default (tbody) и `#footer`. Стили ячеек (`<th>`/`<td>` паддинги, выравнивание)\n * оставлены на консьюмере.\n *\n * ВАЖНО: `min-w-full` сам по себе не даст горизонтального скролла. Для него\n * консьюмеру нужны `white-space: nowrap` на ячейках или явные ширины колонок.\n */\nconst props = withDefaults(defineProps<GrTableProps>(), {\n size: undefined,\n caption: undefined,\n ariaLabel: undefined,\n ariaLabelledby: undefined,\n regionLabel: undefined,\n loading: false,\n loadingRows: 3,\n columnCount: 1,\n emptyText: undefined,\n empty: undefined,\n striped: false,\n hoverable: false,\n rowGroups: false,\n role: 'table',\n stickyHeader: false,\n stickyColumn: false,\n maxHeight: undefined,\n rowCount: undefined,\n fixedLayout: false,\n tableMinWidth: undefined,\n})\n\nconst slots = useSlots()\n\nconst resolvedSize = useGrComponentSize(() => props.size, { component: 'GrTable' })\nconst tableTextClass = computed(() => tableSizes[resolvedSize.value])\nconst hasCaption = computed(() => Boolean(slots.caption) || Boolean(props.caption))\n\nconst { t } = useGranularityTranslations()\nconst resolvedEmptyText = computed(() => props.emptyText ?? t('gr.table.empty', 'Nothing here yet'))\n\n// Пустоту видно по слоту: `v-for` по пустому массиву оставляет фрагмент без\n// узлов, `v-if` — комментарий, и ни то ни другое строкой не является.\nconst isEmpty = computed(() => {\n if (props.empty !== undefined)\n return props.empty\n\n return !hasMeaningfulSlotContent(slots.default?.() ?? [])\n})\n\nconst showRows = computed(() => !props.loading && !isEmpty.value)\nconst loadingRowCount = computed(() => Math.max(1, Math.trunc(props.loadingRows)))\nconst serviceColSpan = computed(() => Math.max(1, Math.trunc(props.columnCount)))\n\n/**\n * Цвет текста, полосатость и подсветка висят на таблице, а не на теле: групп у\n * тела может быть много (`rowGroups`), и рисует их потребитель — правило,\n * привязанное к одной группе, до остальных не дотянулось бы, а цвет и вовсе\n * не достался бы ни одной.\n */\nconst bodyClass = computed(() => [\n 'text-[var(--gr-fg)]',\n props.striped && showRows.value ? stripedClass : '',\n props.hoverable && showRows.value ? hoverableClass : '',\n].filter(Boolean).join(' '))\n\n/*\n * Прилипающая первая колонка.\n *\n * Липкая ячейка обязана быть непрозрачной, иначе уезжающее просвечивает\n * насквозь. Наследовать фон строки нельзя, хотя это и просится: оттенки полосы\n * и подсветки полупрозрачны, и сквозь такую ячейку числа видно. Поэтому фон у\n * неё свой, а полоса и подсветка собираются заново поверх карточки —\n * `stickyColumn*Class` в `grTableStyles.ts`.\n *\n * Правила позиционирования — литералами здесь, а не в хелпере: литерал `.vue`\n * уезжает в чанк самого компонента, то есть всегда в области скана UnoCSS.\n * Тем же путём живёт `stickyHeader`. В хелпер вынесено только то, чему нужны\n * общие оттенки, — и оно объявлено в safelist.\n */\nconst stickyColumnClass = computed(() => {\n if (!props.stickyColumn)\n return ''\n\n return [\n '[&_tr>*:first-child]:sticky',\n '[&_tr>*:first-child]:left-0',\n '[&_tr>*:first-child]:z-[2]',\n '[&_tr>*:first-child]:shadow-[var(--gr-table-sticky-column-shadow,4px_0_6px_-4px_rgba(0,0,0,0.25))]',\n '[&>tbody>tr>*:first-child]:bg-[var(--gr-card)]',\n '[&>tfoot>tr>*:first-child]:bg-[var(--gr-card)]',\n // Шапке фон уже задан на `<thead>`, но он скроллится вместе с ней:\n // липкой ячейке нужен свой.\n '[&>thead>tr>*:first-child]:bg-[var(--gr-muted)]',\n props.striped && showRows.value ? stickyColumnStripedClass : '',\n props.hoverable && showRows.value ? stickyColumnHoverableClass : '',\n ].filter(Boolean).join(' ')\n})\n\nconst scrollStyle = computed(() => {\n // Неполный набор в DOM (`rowCount`) означает виртуализацию, а с ней обязан\n // быть выключен браузерный scroll anchoring: он подправляет `scrollTop`,\n // когда меняется высота содержимого выше видимого узла, — а окно меняет её\n // на каждом кадре прокрутки, и список уезжает.\n const anchor = props.rowCount === undefined ? undefined : { overflowAnchor: 'none' as const }\n\n if (props.maxHeight === undefined)\n return anchor\n\n const value = typeof props.maxHeight === 'number' ? `${props.maxHeight}px` : props.maxHeight\n return { ...anchor, maxHeight: value, overflowY: 'auto' as const }\n})\n\n// Прилипающий заголовок: `<thead>` на `position: sticky`; фон обязателен, иначе\n// сквозь него будут просвечивать строки при скролле.\nconst theadClass = computed(() => [\n 'bg-[var(--gr-muted)] text-[var(--gr-muted-fg)]',\n props.stickyHeader ? 'sticky top-0 z-[1]' : '',\n].filter(Boolean).join(' '))\n\nconst tableStyle = computed(() => {\n if (props.tableMinWidth === undefined)\n return undefined\n\n const value = typeof props.tableMinWidth === 'number' ? `${props.tableMinWidth}px` : props.tableMinWidth\n\n return { minWidth: value }\n})\n\nconst scrollEl = ref<HTMLElement | null>(null)\n\nfunction scrollTo(options: ScrollToOptions): void {\n scrollEl.value?.scrollTo(options)\n}\n\n// Только верхний уровень собственного tbody: вложенная таблица в ячейке не\n// должна сдвигать индексацию строк.\nfunction contentRows(): HTMLElement[] {\n if (!showRows.value)\n return []\n const el = scrollEl.value\n if (!el)\n return []\n return Array.from(el.querySelectorAll<HTMLElement>(':scope > table > tbody > tr'))\n}\n\nfunction scrollToRow(index: number, options?: ScrollIntoViewOptions): boolean {\n const row = contentRows()[index]\n if (!row)\n return false\n row.scrollIntoView(options ?? { block: 'nearest' })\n return true\n}\n\ndefineExpose({\n /** Прокрутить скролл-контейнер таблицы — тот же контракт, что у `GrDataTable`. */\n scrollTo,\n /** Прокрутить к строке содержимого по её индексу в разметке. `false` — строки нет в DOM. */\n scrollToRow,\n})\n\ndefineSlots<{\n /** Строки таблицы, когда разметка пишется руками вместо `data`. */\n default?: () => any\n /** Подпись таблицы — `<caption>`, читается диктором первой. */\n caption?: () => any\n /** Шапка вместо построенной по `columns`. */\n header?: () => any\n /** Содержимое, пока едут данные, — вместо строк-заглушек. */\n loading?: () => any\n /** Пустое состояние вместо текста по умолчанию. */\n empty?: () => any\n /** Итоговая строка под таблицей. */\n footer?: () => any\n}>()\n\n/**\n * `relative` на скроллере — не для потомков с координатами, а чтобы он стал\n * containing block. Без него абсолютные потомки (`sr-only`-подсказка у кнопки\n * сортировки — единственный такой в самой таблице, но разметка ячеек чужая)\n * считают позицию от документа и выпадают из прокрутки наружу: на узком экране\n * широкая таблица начинает тащить вбок всю страницу, а не только себя.\n *\n * Живёт здесь, а не над `<div>`: комментарий в корне `<template>` делает\n * компонент фрагментом, и `$el` у потребителя становится Comment-нодой —\n * `GrDataTable` падает на `root.matches` ещё до первого рендера.\n */\n</script>\n\n<template>\n <div\n ref=\"scrollEl\"\n data-gr-table-scroll\n :role=\"regionLabel ? 'region' : undefined\"\n :aria-label=\"regionLabel\"\n :aria-busy=\"loading ? 'true' : undefined\"\n tabindex=\"0\"\n class=\"relative overflow-x-auto rounded-[var(--gr-radius-lg)] border border-[var(--gr-brd)] bg-[var(--gr-card)] focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--gr-ring)]\"\n :style=\"scrollStyle\"\n >\n <table\n data-gr-table\n :role=\"role === 'grid' ? 'grid' : undefined\"\n class=\"min-w-full\" :class=\"[tableTextClass, bodyClass, stickyColumnClass, fixedLayout ? '[table-layout:fixed]' : '']\"\n :style=\"tableStyle\"\n :aria-label=\"ariaLabelledby ? undefined : ariaLabel\"\n :aria-labelledby=\"ariaLabelledby\"\n :aria-rowcount=\"rowCount\"\n >\n <caption v-if=\"hasCaption\" class=\"sr-only\">\n <slot name=\"caption\">\n{{ caption }}\n</slot>\n </caption>\n <thead :class=\"theadClass\">\n <slot name=\"header\" />\n </thead>\n <tbody v-if=\"loading\">\n <slot name=\"loading\">\n <tr v-for=\"row in loadingRowCount\" :key=\"row\" data-gr-table-loading-row>\n <td :colspan=\"serviceColSpan\" :class=\"loadingRowCellClass\">\n <GrSkeleton />\n </td>\n </tr>\n </slot>\n </tbody>\n\n <tbody v-else-if=\"isEmpty\">\n <tr data-gr-table-empty>\n <td :colspan=\"serviceColSpan\" :class=\"emptyCellClass\">\n <slot name=\"empty\">\n {{ resolvedEmptyText }}\n </slot>\n </td>\n </tr>\n </tbody>\n\n <!-- Группы рисует потребитель: своя обёртка разделила бы пару строк. -->\n <slot v-else-if=\"rowGroups\" />\n\n <tbody v-else>\n <slot />\n </tbody>\n <tfoot v-if=\"slots.footer\" class=\"text-[var(--gr-fg)]\">\n <slot name=\"footer\" />\n </tfoot>\n </table>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, ref, useSlots } from 'vue'\n\nimport { useGrComponentSize } from '../GrConfigProvider/context'\nimport GrSkeleton from '../GrSkeleton/GrSkeleton.vue'\nimport { hasMeaningfulSlotContent } from '../shared/slotNodes'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport {\n emptyCellClass,\n hoverableClass,\n loadingRowCellClass,\n stickyColumnHoverableClass,\n stickyColumnStripedClass,\n stripedClass,\n tableSizes,\n type GrTableSize,\n} from './grTableStyles'\n\nexport interface GrTableProps {\n /**\n * Размер таблицы — базовый кегль текста. Паддинги ячеек оставлены за\n * консьюмером (GrTable — «тонкий» контейнер).\n */\n size?: GrTableSize\n /**\n * Текст caption для screen reader'ов. Рендерится как `<caption class=\"sr-only\">`,\n * если не передан слот `#caption`.\n */\n caption?: string\n /** Прямой ARIA-label для `<table>`. Игнорируется, если задан `ariaLabelledby`. */\n ariaLabel?: string\n /** ID элемента-заголовка, связанного с `<table>` через `aria-labelledby`. */\n ariaLabelledby?: string\n /**\n * ARIA-label для скролл-контейнера. Включает `role=\"region\"`; сам скролл\n * достижим с клавиатуры всегда, независимо от метки.\n */\n regionLabel?: string\n /** Идёт загрузка: вместо строк — скелетоны, контейнер помечен `aria-busy`. */\n loading?: boolean\n /** Сколько строк-заглушек показать при `loading`. */\n loadingRows?: number\n /** Сколько колонок занимает служебная строка (пустое состояние и скелетоны). */\n columnCount?: number\n /** Текст пустого состояния. Слот `#empty` сильнее. */\n emptyText?: string\n /** Таблица пуста. По умолчанию определяется по содержимому слота. */\n empty?: boolean\n /** Чередование строк. */\n striped?: boolean\n /** Подсветка строки под курсором. */\n hoverable?: boolean\n /**\n * Тело собрано группами строк, и рисует их потребитель: слот по умолчанию\n * встаёт прямо в таблицу, без обёртки в `<tbody>`.\n *\n * Нужно там, где пара строк обязана мериться и жить вместе — второй ярус\n * `GrDataTable` рядом со своей строкой. Обернуть две `<tr>` в таблице больше\n * не во что: группа строк — единственный контейнер, который для них\n * существует.\n */\n rowGroups?: boolean\n /**\n * Роль таблицы. `grid` — интерактивная сетка с клавиатурой по ячейкам\n * (паттерн WAI-ARIA `grid`): она объявляет диктору, что по таблице ходят\n * стрелками, а не читают её как статичную.\n *\n * Роль ставит тот, кто клавиатуру и реализует, — сама по себе она обещание,\n * которое таблица не выполняет.\n */\n role?: 'table' | 'grid'\n /**\n * Прилипающий заголовок: `<thead>` остаётся видимым при вертикальном скролле.\n * Осмысленно вместе с `maxHeight` (иначе таблица не скроллится вертикально).\n */\n stickyHeader?: boolean\n /**\n * Прилипающая первая колонка: остаётся видимой при горизонтальном скролле.\n *\n * Только первая, и это не упрощение: `left` со второй колонки равен сумме\n * ширин предыдущих, а ячейки принадлежат потребителю — мерить их «тонкому»\n * контейнеру нечем. Многоколоночное закрепление есть у `GrDataTable`: он\n * знает свои колонки и меряет смещения сам.\n */\n stickyColumn?: boolean\n /**\n * Полное число строк набора, включая строки заголовка (`aria-rowcount`).\n *\n * Нужен, когда в DOM не весь набор — например, при виртуализации: диктор\n * считает строки по разметке и объявил бы «5 из 20» на таблице в десять\n * тысяч. Строки при этом обязаны нести `aria-rowindex`.\n */\n rowCount?: number\n /**\n * Фиксированная раскладка (`table-layout: fixed`): ширины колонок берутся из\n * первой строки, а не из содержимого всех.\n *\n * Обязателен, если в DOM не весь набор: иначе ширины считаются по\n * отрисованному окну и прыгают на каждой прокрутке.\n *\n * Класс — arbitrary-значение, а не `table-fixed`: такого правила в\n * `presetMini` нет, и класс молча не превратился бы в CSS.\n */\n fixedLayout?: boolean\n /**\n * Минимальная ширина самой таблицы (число — пиксели).\n *\n * Нужна при `fixedLayout`: с фиксированной раскладкой и шириной `auto`\n * браузер вписывает таблицу в контейнер и делит место между колонками\n * пропорционально — то есть заданные ширины молча ужимаются, а\n * горизонтальной прокрутки, на которой держатся закреплённые колонки, не\n * возникает вовсе.\n */\n tableMinWidth?: string | number\n /**\n * Максимальная высота скролл-контейнера (включает вертикальный скролл).\n * Число трактуется как пиксели. Нужен для работы `stickyHeader`.\n */\n maxHeight?: string | number\n}\n\n/**\n * `GrTable` — «тонкий» GR-контейнер для табличных данных.\n *\n * Рендерит `<table>` внутри скролл-обёртки и даёт слоты `#caption`, `#header`,\n * default (tbody) и `#footer`. Стили ячеек (`<th>`/`<td>` паддинги, выравнивание)\n * оставлены на консьюмере.\n *\n * ВАЖНО: `min-w-full` сам по себе не даст горизонтального скролла. Для него\n * консьюмеру нужны `white-space: nowrap` на ячейках или явные ширины колонок.\n */\nconst props = withDefaults(defineProps<GrTableProps>(), {\n size: undefined,\n caption: undefined,\n ariaLabel: undefined,\n ariaLabelledby: undefined,\n regionLabel: undefined,\n loading: false,\n loadingRows: 3,\n columnCount: 1,\n emptyText: undefined,\n empty: undefined,\n striped: false,\n hoverable: false,\n rowGroups: false,\n role: 'table',\n stickyHeader: false,\n stickyColumn: false,\n maxHeight: undefined,\n rowCount: undefined,\n fixedLayout: false,\n tableMinWidth: undefined,\n})\n\nconst slots = useSlots()\n\nconst resolvedSize = useGrComponentSize(() => props.size, { component: 'GrTable' })\nconst tableTextClass = computed(() => tableSizes[resolvedSize.value])\nconst hasCaption = computed(() => Boolean(slots.caption) || Boolean(props.caption))\n\nconst { t } = useGranularityTranslations()\nconst resolvedEmptyText = computed(() => props.emptyText ?? t('gr.table.empty', 'Nothing here yet'))\n\n// Пустоту видно по слоту: `v-for` по пустому массиву оставляет фрагмент без\n// узлов, `v-if` — комментарий, и ни то ни другое строкой не является.\nconst isEmpty = computed(() => {\n if (props.empty !== undefined)\n return props.empty\n\n return !hasMeaningfulSlotContent(slots.default?.() ?? [])\n})\n\nconst showRows = computed(() => !props.loading && !isEmpty.value)\nconst loadingRowCount = computed(() => Math.max(1, Math.trunc(props.loadingRows)))\nconst serviceColSpan = computed(() => Math.max(1, Math.trunc(props.columnCount)))\n\n/**\n * Цвет текста, полосатость и подсветка висят на таблице, а не на теле: групп у\n * тела может быть много (`rowGroups`), и рисует их потребитель — правило,\n * привязанное к одной группе, до остальных не дотянулось бы, а цвет и вовсе\n * не достался бы ни одной.\n */\nconst bodyClass = computed(() => [\n 'text-[var(--gr-fg)]',\n props.striped && showRows.value ? stripedClass : '',\n props.hoverable && showRows.value ? hoverableClass : '',\n].filter(Boolean).join(' '))\n\n/*\n * Прилипающая первая колонка.\n *\n * Липкая ячейка обязана быть непрозрачной, иначе уезжающее просвечивает\n * насквозь. Наследовать фон строки нельзя, хотя это и просится: оттенки полосы\n * и подсветки полупрозрачны, и сквозь такую ячейку числа видно. Поэтому фон у\n * неё свой, а полоса и подсветка собираются заново поверх карточки —\n * `stickyColumn*Class` в `grTableStyles.ts`.\n *\n * Правила позиционирования — литералами здесь, а не в хелпере: литерал `.vue`\n * уезжает в чанк самого компонента, то есть всегда в области скана UnoCSS.\n * Тем же путём живёт `stickyHeader`. В хелпер вынесено только то, чему нужны\n * общие оттенки, — и оно объявлено в safelist.\n */\nconst stickyColumnClass = computed(() => {\n if (!props.stickyColumn)\n return ''\n\n return [\n '[&_tr>*:first-child]:sticky',\n '[&_tr>*:first-child]:left-0',\n '[&_tr>*:first-child]:z-[2]',\n '[&_tr>*:first-child]:shadow-[var(--gr-table-sticky-column-shadow,4px_0_6px_-4px_rgba(0,0,0,0.25))]',\n '[&>tbody>tr>*:first-child]:bg-[var(--gr-card)]',\n '[&>tfoot>tr>*:first-child]:bg-[var(--gr-card)]',\n // Шапке фон уже задан на `<thead>`, но он скроллится вместе с ней:\n // липкой ячейке нужен свой.\n '[&>thead>tr>*:first-child]:bg-[var(--gr-muted)]',\n props.striped && showRows.value ? stickyColumnStripedClass : '',\n props.hoverable && showRows.value ? stickyColumnHoverableClass : '',\n ].filter(Boolean).join(' ')\n})\n\nconst scrollStyle = computed(() => {\n // Неполный набор в DOM (`rowCount`) означает виртуализацию, а с ней обязан\n // быть выключен браузерный scroll anchoring: он подправляет `scrollTop`,\n // когда меняется высота содержимого выше видимого узла, — а окно меняет её\n // на каждом кадре прокрутки, и список уезжает.\n const anchor = props.rowCount === undefined ? undefined : { overflowAnchor: 'none' as const }\n\n if (props.maxHeight === undefined)\n return anchor\n\n const value = typeof props.maxHeight === 'number' ? `${props.maxHeight}px` : props.maxHeight\n return { ...anchor, maxHeight: value, overflowY: 'auto' as const }\n})\n\n// Прилипающий заголовок: `<thead>` на `position: sticky`; фон обязателен, иначе\n// сквозь него будут просвечивать строки при скролле.\nconst theadClass = computed(() => [\n 'bg-[var(--gr-muted)] text-[var(--gr-muted-fg)]',\n props.stickyHeader ? 'sticky top-0 z-[1]' : '',\n].filter(Boolean).join(' '))\n\nconst tableStyle = computed(() => {\n if (props.tableMinWidth === undefined)\n return undefined\n\n const value = typeof props.tableMinWidth === 'number' ? `${props.tableMinWidth}px` : props.tableMinWidth\n\n return { minWidth: value }\n})\n\nconst scrollEl = ref<HTMLElement | null>(null)\n\nfunction scrollTo(options: ScrollToOptions): void {\n scrollEl.value?.scrollTo(options)\n}\n\n// Только верхний уровень собственного tbody: вложенная таблица в ячейке не\n// должна сдвигать индексацию строк.\nfunction contentRows(): HTMLElement[] {\n if (!showRows.value)\n return []\n const el = scrollEl.value\n if (!el)\n return []\n return Array.from(el.querySelectorAll<HTMLElement>(':scope > table > tbody > tr'))\n}\n\nfunction scrollToRow(index: number, options?: ScrollIntoViewOptions): boolean {\n const row = contentRows()[index]\n if (!row)\n return false\n row.scrollIntoView(options ?? { block: 'nearest' })\n return true\n}\n\ndefineExpose({\n /** Прокрутить скролл-контейнер таблицы — тот же контракт, что у `GrDataTable`. */\n scrollTo,\n /** Прокрутить к строке содержимого по её индексу в разметке. `false` — строки нет в DOM. */\n scrollToRow,\n})\n\ndefineSlots<{\n /** Строки таблицы, когда разметка пишется руками вместо `data`. */\n default?: () => any\n /** Подпись таблицы — `<caption>`, читается диктором первой. */\n caption?: () => any\n /** Шапка вместо построенной по `columns`. */\n header?: () => any\n /** Содержимое, пока едут данные, — вместо строк-заглушек. */\n loading?: () => any\n /** Пустое состояние вместо текста по умолчанию. */\n empty?: () => any\n /** Итоговая строка под таблицей. */\n footer?: () => any\n}>()\n\n/**\n * `relative` на скроллере — не для потомков с координатами, а чтобы он стал\n * containing block. Без него абсолютные потомки (`sr-only`-подсказка у кнопки\n * сортировки — единственный такой в самой таблице, но разметка ячеек чужая)\n * считают позицию от документа и выпадают из прокрутки наружу: на узком экране\n * широкая таблица начинает тащить вбок всю страницу, а не только себя.\n *\n * Живёт здесь, а не над `<div>`: комментарий в корне `<template>` делает\n * компонент фрагментом, и `$el` у потребителя становится Comment-нодой —\n * `GrDataTable` падает на `root.matches` ещё до первого рендера.\n */\n</script>\n\n<template>\n <div\n ref=\"scrollEl\"\n data-gr-table-scroll\n :role=\"regionLabel ? 'region' : undefined\"\n :aria-label=\"regionLabel\"\n :aria-busy=\"loading ? 'true' : undefined\"\n tabindex=\"0\"\n class=\"relative overflow-x-auto rounded-[var(--gr-radius-lg)] border border-[var(--gr-brd)] bg-[var(--gr-card)] focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--gr-ring)]\"\n :style=\"scrollStyle\"\n >\n <table\n data-gr-table\n :role=\"role === 'grid' ? 'grid' : undefined\"\n class=\"min-w-full\" :class=\"[tableTextClass, bodyClass, stickyColumnClass, fixedLayout ? '[table-layout:fixed]' : '']\"\n :style=\"tableStyle\"\n :aria-label=\"ariaLabelledby ? undefined : ariaLabel\"\n :aria-labelledby=\"ariaLabelledby\"\n :aria-rowcount=\"rowCount\"\n >\n <caption v-if=\"hasCaption\" class=\"sr-only\">\n <slot name=\"caption\">\n{{ caption }}\n</slot>\n </caption>\n <thead :class=\"theadClass\">\n <slot name=\"header\" />\n </thead>\n <tbody v-if=\"loading\">\n <slot name=\"loading\">\n <tr v-for=\"row in loadingRowCount\" :key=\"row\" data-gr-table-loading-row>\n <td :colspan=\"serviceColSpan\" :class=\"loadingRowCellClass\">\n <GrSkeleton />\n </td>\n </tr>\n </slot>\n </tbody>\n\n <tbody v-else-if=\"isEmpty\">\n <tr data-gr-table-empty>\n <td :colspan=\"serviceColSpan\" :class=\"emptyCellClass\">\n <slot name=\"empty\">\n {{ resolvedEmptyText }}\n </slot>\n </td>\n </tr>\n </tbody>\n\n <!-- Группы рисует потребитель: своя обёртка разделила бы пару строк. -->\n <slot v-else-if=\"rowGroups\" />\n\n <tbody v-else>\n <slot />\n </tbody>\n <tfoot v-if=\"slots.footer\" class=\"text-[var(--gr-fg)]\">\n <slot name=\"footer\" />\n </tfoot>\n </table>\n </div>\n</template>\n"],"mappings":"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"}
|