@feugene/granularity 0.23.0 → 0.25.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/dist/chunks/config-BFJIxE8b.js +62 -0
- package/dist/chunks/config-BFJIxE8b.js.map +1 -0
- package/dist/chunks/{config-DBQQT-WP.js → config-BIa3ilQm.js} +18 -3
- package/dist/chunks/config-BIa3ilQm.js.map +1 -0
- package/dist/chunks/config-BfsBepkH.js.map +1 -0
- package/dist/chunks/config-BoNR7_PD.js.map +1 -0
- package/dist/chunks/config-BuGlNPE92.js.map +1 -0
- package/dist/chunks/{config-Be9k9bOf.js → config-C8tVRv8i.js} +16 -2
- package/dist/chunks/config-C8tVRv8i.js.map +1 -0
- package/dist/chunks/config-CPSxM7XE.js +8 -0
- package/dist/chunks/config-CPSxM7XE.js.map +1 -0
- package/dist/chunks/config-D7zgE_Gr.js +107 -0
- package/dist/chunks/config-D7zgE_Gr.js.map +1 -0
- package/dist/chunks/config-DAX8Deh1.js.map +1 -0
- package/dist/chunks/config-DGCMHPCR.js +19 -0
- package/dist/chunks/config-DGCMHPCR.js.map +1 -0
- package/dist/chunks/config-DGWFal5h.js +128 -0
- package/dist/chunks/config-DGWFal5h.js.map +1 -0
- package/dist/chunks/config-DKISz9gR.js +39 -0
- package/dist/chunks/config-DKISz9gR.js.map +1 -0
- package/dist/chunks/{config-Bm_Sovla.js → config-DYgfMrIF.js} +14 -2
- package/dist/chunks/config-DYgfMrIF.js.map +1 -0
- package/dist/chunks/{config-BSyiFlbi.js → config-DtgYuGUn2.js} +2 -1
- package/dist/chunks/config-DtgYuGUn2.js.map +1 -0
- package/dist/chunks/config-Iu684VNI.js +21 -0
- package/dist/chunks/config-Iu684VNI.js.map +1 -0
- package/dist/chunks/config-T3qdQBgU.js.map +1 -0
- package/dist/chunks/{config-DCwQBMmJ.js → config-rkcKArZQ.js} +27 -8
- package/dist/chunks/config-rkcKArZQ.js.map +1 -0
- package/dist/chunks/config-zjeAJ4ho2.js.map +1 -0
- package/dist/chunks/context-BfIQv7m12.js.map +1 -0
- package/dist/chunks/context-CTbuwcYs.js.map +1 -1
- package/dist/chunks/{en-DCCFP4qu.js → en-NpP9e7lC.js} +16 -2
- package/dist/chunks/en-NpP9e7lC.js.map +1 -0
- package/dist/chunks/{es-CT34HBVM.js → es-DaeA2Ql-.js} +16 -2
- package/dist/chunks/es-DaeA2Ql-.js.map +1 -0
- package/dist/chunks/{es-DdJsxlUr.js → es-Do2CNrC2.js} +3 -3
- package/dist/chunks/{es-DdJsxlUr.js.map → es-Do2CNrC2.js.map} +1 -1
- package/dist/chunks/{generated-CiCrGDQO.js → generated-CJe6hdiE.js} +138 -6
- package/dist/chunks/{generated-CiCrGDQO.js.map → generated-CJe6hdiE.js.map} +1 -1
- package/dist/chunks/{grBadgeStyles-C2wLlkjF.js → grBadgeStyles-C1S56Alo.js} +6 -1
- package/dist/chunks/{grBadgeStyles-C2wLlkjF.js.map → grBadgeStyles-C1S56Alo.js.map} +1 -1
- package/dist/chunks/grChipGroupContext-DZXkACap.js +4 -0
- package/dist/chunks/grChipGroupContext-DZXkACap.js.map +1 -0
- package/dist/chunks/{config-C5mO5DYZ.js → grDropdownMenuStyles-D1LOkdVj.js} +1 -38
- package/dist/chunks/grDropdownMenuStyles-D1LOkdVj.js.map +1 -0
- package/dist/chunks/{grPopoverStyles-Rz_Z5nLW.js → grPopoverStyles-Cke_BZsM.js} +16 -3
- package/dist/chunks/grPopoverStyles-Cke_BZsM.js.map +1 -0
- package/dist/chunks/{granular-provider-CQKhl5C_.js → granular-provider-BaHkLjFX.js} +26 -16
- package/dist/chunks/granular-provider-BaHkLjFX.js.map +1 -0
- package/dist/chunks/{ru-CLiAMwrx.js → ru-Bg9-DPmg.js} +16 -2
- package/dist/chunks/ru-Bg9-DPmg.js.map +1 -0
- package/dist/chunks/{config-qVg3Zz_A.js → safelist-DOfCQR5O.js} +2 -19
- package/dist/chunks/safelist-DOfCQR5O.js.map +1 -0
- package/dist/chunks/useMenuItemsFocus-OyOnIAlr.js +117 -0
- package/dist/chunks/useMenuItemsFocus-OyOnIAlr.js.map +1 -0
- package/dist/components/GrAutocomplete/chunks/{GrAutocomplete-DsevPtiS.js → GrAutocomplete-D9c9BNFg.js} +1 -1
- package/dist/components/GrAutocomplete/chunks/{GrAutocomplete-DsevPtiS.js.map → GrAutocomplete-D9c9BNFg.js.map} +1 -1
- package/dist/components/GrAutocomplete/index.js +1 -1
- package/dist/components/GrBadge/chunks/{GrBadge-u2ZdS7CN.js → GrBadge-_9rCHuE1.js} +1 -1
- package/dist/components/GrBadge/chunks/{GrBadge-u2ZdS7CN.js.map → GrBadge-_9rCHuE1.js.map} +1 -1
- package/dist/components/GrBadge/index.js +3 -2
- package/dist/components/GrButton/chunks/{GrButton-Bw2AH4uX.js → GrButton-DCz-Wn-V.js} +1 -1
- package/dist/components/GrButton/chunks/{GrButton-Bw2AH4uX.js.map → GrButton-DCz-Wn-V.js.map} +1 -1
- package/dist/components/GrButton/index.js +1 -1
- package/dist/components/GrButtonGroup/chunks/{GrButtonGroup-CKyiAV8K.js → GrButtonGroup-BQo5VQ_c.js} +1 -1
- package/dist/components/GrButtonGroup/chunks/{GrButtonGroup-CKyiAV8K.js.map → GrButtonGroup-BQo5VQ_c.js.map} +1 -1
- package/dist/components/GrButtonGroup/index.js +2 -2
- package/dist/components/GrCard/chunks/{GrCard-Bc7nRfbe.js → GrCard-aQIjk6I9.js} +9 -3
- package/dist/components/GrCard/chunks/GrCard-aQIjk6I9.js.map +1 -0
- package/dist/components/GrCard/index.js +2 -2
- package/dist/components/GrCheckboxGroup/index.js +1 -1
- package/dist/components/GrChip/chunks/GrChip-BnL2FedO.js +222 -0
- package/dist/components/GrChip/chunks/GrChip-BnL2FedO.js.map +1 -0
- package/dist/components/GrChip/index.js +3 -0
- package/dist/components/GrChipGroup/chunks/GrChipGroup-DefmSdY9.js +209 -0
- package/dist/components/GrChipGroup/chunks/GrChipGroup-DefmSdY9.js.map +1 -0
- package/dist/components/GrChipGroup/index.js +3 -0
- package/dist/components/GrCodeBlock/chunks/{GrCodeBlock-BmXCLgLS.js → GrCodeBlock-CyptiEo4.js} +1 -1
- package/dist/components/GrCodeBlock/chunks/{GrCodeBlock-BmXCLgLS.js.map → GrCodeBlock-CyptiEo4.js.map} +1 -1
- package/dist/components/GrCodeBlock/index.js +1 -1
- package/dist/components/GrCollapse/chunks/{GrCollapse-C1rCfbc0.js → GrCollapse-DUROgAgc.js} +1 -1
- package/dist/components/GrCollapse/chunks/{GrCollapse-C1rCfbc0.js.map → GrCollapse-DUROgAgc.js.map} +1 -1
- package/dist/components/GrCollapse/index.js +1 -1
- package/dist/components/GrColorPicker/chunks/{GrColorPicker-qQdoEPHF.js → GrColorPicker-CDaJRVIM.js} +1 -1
- package/dist/components/GrColorPicker/chunks/{GrColorPicker-qQdoEPHF.js.map → GrColorPicker-CDaJRVIM.js.map} +1 -1
- package/dist/components/GrColorPicker/index.js +1 -1
- package/dist/components/GrCommandPalette/chunks/{GrCommandPalette-BFcMf4Pn.js → GrCommandPalette-BPsVN_XU.js} +3 -3
- package/dist/components/GrCommandPalette/chunks/GrCommandPalette-BPsVN_XU.js.map +1 -0
- package/dist/components/GrCommandPalette/index.js +1 -1
- package/dist/components/GrCommandPalette/styles.css +1 -1
- package/dist/components/GrConfigProvider/chunks/{GrConfigProvider-UP-EaoAf.js → GrConfigProvider-BF7R3hgg.js} +1 -1
- package/dist/components/GrConfigProvider/chunks/GrConfigProvider-BF7R3hgg.js.map +1 -0
- package/dist/components/GrConfigProvider/index.js +1 -1
- package/dist/components/GrConfirmDialog/chunks/{GrConfirmDialog-rRtMScJX.js → GrConfirmDialog-CwXNLyzk.js} +3 -3
- package/dist/components/GrConfirmDialog/chunks/{GrConfirmDialog-rRtMScJX.js.map → GrConfirmDialog-CwXNLyzk.js.map} +1 -1
- package/dist/components/GrConfirmDialog/index.js +1 -1
- package/dist/components/GrContextMenu/chunks/GrContextMenu-BbAJholy.js +331 -0
- package/dist/components/GrContextMenu/chunks/GrContextMenu-BbAJholy.js.map +1 -0
- package/dist/components/GrContextMenu/index.js +3 -0
- package/dist/components/GrDataTable/chunks/{GrDataTable-B5MmZFUg.js → GrDataTable-NRbrXpdx.js} +2 -2
- package/dist/components/GrDataTable/chunks/GrDataTable-NRbrXpdx.js.map +1 -0
- package/dist/components/GrDataTable/index.js +1 -1
- package/dist/components/GrDelta/chunks/{GrDelta-DFvxNpmN.js → GrDelta-NE5HhXoo.js} +0 -0
- package/dist/components/GrDelta/chunks/GrDelta-NE5HhXoo.js.map +1 -0
- package/dist/components/GrDelta/index.js +2 -2
- package/dist/components/GrDescriptionList/chunks/{GrDescriptionList-2zFXzX83.js → GrDescriptionList-1mICfrqX.js} +8 -4
- package/dist/components/GrDescriptionList/chunks/GrDescriptionList-1mICfrqX.js.map +1 -0
- package/dist/components/GrDescriptionList/index.js +2 -2
- package/dist/components/GrDialog/chunks/{GrDialog-D0U5iRqV.js → GrDialog-5Y5K87ss.js} +2 -2
- package/dist/components/GrDialog/chunks/{GrDialog-D0U5iRqV.js.map → GrDialog-5Y5K87ss.js.map} +1 -1
- package/dist/components/GrDialog/index.js +1 -1
- package/dist/components/GrDialogService/chunks/{GrDialogService-CrwA4aJq.js → GrDialogService-CHhzGRWy.js} +6 -6
- package/dist/components/GrDialogService/chunks/GrDialogService-CHhzGRWy.js.map +1 -0
- package/dist/components/GrDialogService/index.js +1 -1
- package/dist/components/GrDrawer/chunks/{GrDrawer-C3zAg2tG.js → GrDrawer-CXy3-SVd.js} +2 -2
- package/dist/components/GrDrawer/chunks/GrDrawer-CXy3-SVd.js.map +1 -0
- package/dist/components/GrDrawer/index.js +1 -1
- package/dist/components/GrDropdown/chunks/{GrDropdown-BSfFOcDx.js → GrDropdown-BfTmdPyh.js} +10 -79
- package/dist/components/GrDropdown/chunks/GrDropdown-BfTmdPyh.js.map +1 -0
- package/dist/components/GrDropdown/index.js +1 -1
- package/dist/components/GrDropdownMenu/chunks/GrDropdownMenu-l5HEqzjr.js +130 -0
- package/dist/components/GrDropdownMenu/chunks/GrDropdownMenu-l5HEqzjr.js.map +1 -0
- package/dist/components/GrDropdownMenu/chunks/{GrDropdownMenu-DyS6dWDp.js → GrDropdownMenuList-BGA_xNVo.js} +57 -159
- package/dist/components/GrDropdownMenu/chunks/GrDropdownMenuList-BGA_xNVo.js.map +1 -0
- package/dist/components/GrDropdownMenu/index.js +3 -2
- package/dist/components/GrFileUpload/chunks/{GrFileUpload-D3-vC-ap.js → GrFileUpload-wNXzHb5N.js} +1 -1
- package/dist/components/GrFileUpload/chunks/GrFileUpload-wNXzHb5N.js.map +1 -0
- package/dist/components/GrFileUpload/index.js +1 -1
- package/dist/components/GrFormField/chunks/{GrFormField-kqfVY30N.js → GrFormField-DSylU7IU.js} +1 -1
- package/dist/components/GrFormField/chunks/GrFormField-DSylU7IU.js.map +1 -0
- package/dist/components/GrFormField/index.js +1 -1
- package/dist/components/GrFormFile/chunks/{GrFormFile-D722xHn8.js → GrFormFile-DhVkB2gm.js} +1 -1
- package/dist/components/GrFormFile/chunks/{GrFormFile-D722xHn8.js.map → GrFormFile-DhVkB2gm.js.map} +1 -1
- package/dist/components/GrFormFile/index.js +1 -1
- package/dist/components/GrInputTag/chunks/{GrInputTag-C7QVPijj.js → GrInputTag-UI8kIB_F.js} +2 -2
- package/dist/components/GrInputTag/chunks/{GrInputTag-C7QVPijj.js.map → GrInputTag-UI8kIB_F.js.map} +1 -1
- package/dist/components/GrInputTag/index.js +1 -1
- package/dist/components/GrJsonViewer/chunks/{GrJsonViewer-DFUppRNb.js → GrJsonViewer-jk3ylOTc.js} +2 -2
- package/dist/components/GrJsonViewer/chunks/GrJsonViewer-jk3ylOTc.js.map +1 -0
- package/dist/components/GrJsonViewer/index.js +1 -1
- package/dist/components/GrList/chunks/{GrList-BRYhpqIe.js → GrList-B5bclmHV.js} +30 -3
- package/dist/components/GrList/chunks/GrList-B5bclmHV.js.map +1 -0
- package/dist/components/GrList/index.js +1 -1
- package/dist/components/GrList/styles.css +1 -1
- package/dist/components/GrLoading/chunks/{GrLoading-C3DZSSuh.js → GrLoading-DeBFTvFX.js} +1 -1
- package/dist/components/GrLoading/chunks/GrLoading-DeBFTvFX.js.map +1 -0
- package/dist/components/GrLoading/index.js +1 -1
- package/dist/components/GrModal/chunks/{GrModal-CPz7SWD_.js → GrModal-CCoWZuIl.js} +2 -2
- package/dist/components/GrModal/chunks/GrModal-CCoWZuIl.js.map +1 -0
- package/dist/components/GrModal/index.js +1 -1
- package/dist/components/GrNavbar/chunks/{GrNavbar-DWaaoV7n.js → GrNavbar-DPj30sHX.js} +1 -1
- package/dist/components/GrNavbar/chunks/{GrNavbar-DWaaoV7n.js.map → GrNavbar-DPj30sHX.js.map} +1 -1
- package/dist/components/GrNavbar/index.js +1 -1
- package/dist/components/GrNumberInput/chunks/{GrNumberInput-BotnzW77.js → GrNumberInput-V2mZvDDC.js} +1 -1
- package/dist/components/GrNumberInput/chunks/{GrNumberInput-BotnzW77.js.map → GrNumberInput-V2mZvDDC.js.map} +1 -1
- package/dist/components/GrNumberInput/index.js +2 -2
- package/dist/components/GrPagination/chunks/{GrPagination-GtGtSMJG.js → GrPagination-DG7kp6VL.js} +2 -2
- package/dist/components/GrPagination/chunks/{GrPagination-GtGtSMJG.js.map → GrPagination-DG7kp6VL.js.map} +1 -1
- package/dist/components/GrPagination/index.js +1 -1
- package/dist/components/GrPopover/chunks/{GrPopover-b70bIlQ9.js → GrPopover-DDChM1jD.js} +28 -10
- package/dist/components/GrPopover/chunks/GrPopover-DDChM1jD.js.map +1 -0
- package/dist/components/GrPopover/index.js +2 -2
- package/dist/components/GrPromptDialog/chunks/{GrPromptDialog-CEI8bf-t.js → GrPromptDialog-DjF-5oD9.js} +4 -4
- package/dist/components/GrPromptDialog/chunks/{GrPromptDialog-CEI8bf-t.js.map → GrPromptDialog-DjF-5oD9.js.map} +1 -1
- package/dist/components/GrPromptDialog/index.js +1 -1
- package/dist/components/GrRadioGroup/chunks/{GrRadioGroup-BVmjKXcv.js → GrRadioGroup-7w4bXIg_.js} +1 -1
- package/dist/components/GrRadioGroup/chunks/{GrRadioGroup-BVmjKXcv.js.map → GrRadioGroup-7w4bXIg_.js.map} +1 -1
- package/dist/components/GrRadioGroup/index.js +1 -1
- package/dist/components/GrResponseErrorBanner/chunks/{GrResponseErrorBanner-CZONq8uT.js → GrResponseErrorBanner-BhP-xw2P.js} +1 -1
- package/dist/components/GrResponseErrorBanner/chunks/{GrResponseErrorBanner-CZONq8uT.js.map → GrResponseErrorBanner-BhP-xw2P.js.map} +1 -1
- package/dist/components/GrResponseErrorBanner/chunks/{GrResponseErrorBanner-CgfAwlg3.js → GrResponseErrorBanner-DA4q90Zt.js} +1 -1
- package/dist/components/GrResponseErrorBanner/chunks/{GrResponseErrorBanner-CgfAwlg3.js.map → GrResponseErrorBanner-DA4q90Zt.js.map} +1 -1
- package/dist/components/GrResponseErrorBanner/index.js +2 -2
- package/dist/components/GrSegmented/chunks/{GrSegmented-D1mjxF_O.js → GrSegmented-DKpo3cnC.js} +30 -5
- package/dist/components/GrSegmented/chunks/GrSegmented-DKpo3cnC.js.map +1 -0
- package/dist/components/GrSegmented/index.js +1 -1
- package/dist/components/GrSelect/chunks/{GrSelect-CaGuyvtb.js → GrSelect-BA1wfX3c.js} +19 -3
- package/dist/components/GrSelect/chunks/GrSelect-BA1wfX3c.js.map +1 -0
- package/dist/components/GrSelect/index.js +1 -1
- package/dist/components/GrSelect/styles.css +1 -1
- package/dist/components/GrSidebar/chunks/{GrSidebar-D7WxRtIu.js → GrSidebar-DY-LgIbS.js} +2 -2
- package/dist/components/GrSidebar/chunks/{GrSidebar-D7WxRtIu.js.map → GrSidebar-DY-LgIbS.js.map} +1 -1
- package/dist/components/GrSidebar/index.js +2 -2
- package/dist/components/GrSlider/index.js +1 -1
- package/dist/components/GrSortableList/chunks/{GrSortableList-DPjxilmN.js → GrSortableList-BMXyxmRc.js} +3 -3
- package/dist/components/GrSortableList/chunks/{GrSortableList-DPjxilmN.js.map → GrSortableList-BMXyxmRc.js.map} +1 -1
- package/dist/components/GrSortableList/index.js +2 -2
- package/dist/components/GrStatistic/chunks/{GrStatistic-C7wQECeS.js → GrStatistic-BJQv5aOS.js} +41 -26
- package/dist/components/GrStatistic/chunks/GrStatistic-BJQv5aOS.js.map +1 -0
- package/dist/components/GrStatistic/index.js +2 -2
- package/dist/components/GrSteps/chunks/GrSteps-Cce4rfr3.js +282 -0
- package/dist/components/GrSteps/chunks/GrSteps-Cce4rfr3.js.map +1 -0
- package/dist/components/GrSteps/index.js +3 -0
- package/dist/components/GrSwitch/chunks/{GrSwitch-x_vQQ6ao.js → GrSwitch-CHiIj9GT.js} +1 -1
- package/dist/components/GrSwitch/chunks/{GrSwitch-x_vQQ6ao.js.map → GrSwitch-CHiIj9GT.js.map} +1 -1
- package/dist/components/GrSwitch/index.js +2 -2
- package/dist/components/GrTabPanels/chunks/{GrTabPanels-AJt1w1XC.js → GrTabPanels-BZQS8-JM.js} +12 -1
- package/dist/components/GrTabPanels/chunks/{GrTabPanels-AJt1w1XC.js.map → GrTabPanels-BZQS8-JM.js.map} +1 -1
- package/dist/components/GrTabPanels/index.js +1 -1
- package/dist/components/GrTimeline/chunks/{GrTimeline-Ch9sHzwL.js → GrTimeline-DIDdkTn7.js} +12 -1
- package/dist/components/GrTimeline/chunks/GrTimeline-DIDdkTn7.js.map +1 -0
- package/dist/components/GrTimeline/index.js +1 -1
- package/dist/components/GrToaster/chunks/{GrToaster-DJUzx3sR.js → GrToaster-CC49q3a4.js} +1 -1
- package/dist/components/GrToaster/chunks/{GrToaster-DJUzx3sR.js.map → GrToaster-CC49q3a4.js.map} +1 -1
- package/dist/components/GrToaster/index.js +1 -1
- package/dist/components/GrTree/chunks/{GrTree-BvOeQ3xJ.js.map → GrTree-J5q8aCya.js.map} +1 -1
- package/dist/components/GrTree/index.js +1 -1
- package/dist/components/GrTreeSelect/chunks/{GrTreeSelect-_LjTRR7X.js → GrTreeSelect-DEfxWAc3.js} +1 -1
- package/dist/components/GrTreeSelect/chunks/{GrTreeSelect-_LjTRR7X.js.map → GrTreeSelect-DEfxWAc3.js.map} +1 -1
- package/dist/components/GrTreeSelect/index.js +1 -1
- package/dist/components/GrValue/chunks/GrValue-CZsuZ4x-.js +38 -0
- package/dist/components/GrValue/chunks/GrValue-CZsuZ4x-.js.map +1 -0
- package/dist/components/GrValue/index.js +3 -0
- package/dist/composables/useFloating.js +47 -7
- package/dist/composables/useFloating.js.map +1 -1
- package/dist/composables/useTheme.js.map +1 -1
- package/dist/composables/useToast.js.map +1 -1
- package/dist/directives/loading.js +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 +74 -62
- package/dist/styles/themes/dark.css +11 -6
- package/dist/styles/themes/light.css +5 -0
- package/dist/theme.js +1 -1
- package/dist/tokens.js +1 -1
- package/dist/types/components/GrBadge/grBadgeStyles.d.ts +7 -0
- package/dist/types/components/GrCard/GrCard.vue.d.ts +1 -1
- package/dist/types/components/GrCard/grCardStyles.d.ts +11 -0
- package/dist/types/components/GrChip/GrChip.vue.d.ts +118 -0
- package/dist/types/components/GrChip/config.d.ts +1 -0
- package/dist/types/components/GrChip/defaults.d.ts +16 -0
- package/dist/types/components/GrChip/grChipGroupContext.d.ts +52 -0
- package/dist/types/components/GrChip/grChipStyles.d.ts +64 -0
- package/dist/types/components/GrChip/index.d.ts +11 -0
- package/dist/types/components/GrChip/safelist.d.ts +7 -0
- package/dist/types/components/GrChipGroup/GrChipGroup.vue.d.ts +128 -0
- package/dist/types/components/GrChipGroup/config.d.ts +1 -0
- package/dist/types/components/GrChipGroup/defaults.d.ts +13 -0
- package/dist/types/components/GrChipGroup/grChipGroupStyles.d.ts +7 -0
- package/dist/types/components/GrChipGroup/index.d.ts +9 -0
- package/dist/types/components/GrChipGroup/safelist.d.ts +1 -0
- package/dist/types/components/GrContextMenu/GrContextMenu.vue.d.ts +157 -0
- package/dist/types/components/GrContextMenu/config.d.ts +1 -0
- package/dist/types/components/GrContextMenu/contextMenuAnchor.d.ts +29 -0
- package/dist/types/components/GrContextMenu/index.d.ts +7 -0
- package/dist/types/components/GrDataTable/GrDataTable.vue.d.ts +1 -1
- package/dist/types/components/GrDelta/grDeltaStyles.d.ts +13 -1
- package/dist/types/components/GrDescriptionList/grDescriptionListStyles.d.ts +29 -1
- package/dist/types/components/GrDropdownMenu/GrDropdownMenu.vue.d.ts +3 -3
- package/dist/types/components/GrDropdownMenu/GrDropdownMenuEntries.vue.d.ts +22 -0
- package/dist/types/components/GrFilePreview/GrFilePreview.vue.d.ts +1 -1
- package/dist/types/components/GrList/GrListItem.vue.d.ts +1 -1
- package/dist/types/components/GrPopover/GrPopover.vue.d.ts +21 -2
- package/dist/types/components/GrPopover/grPopoverStyles.d.ts +11 -1
- package/dist/types/components/GrPopover/index.d.ts +1 -1
- package/dist/types/components/GrStatistic/GrStatistic.vue.d.ts +6 -6
- package/dist/types/components/GrStatistic/grStatisticStyles.d.ts +9 -0
- package/dist/types/components/GrSteps/GrSteps.vue.d.ts +118 -0
- package/dist/types/components/GrSteps/config.d.ts +1 -0
- package/dist/types/components/GrSteps/defaults.d.ts +18 -0
- package/dist/types/components/GrSteps/grStepsStyles.d.ts +63 -0
- package/dist/types/components/GrSteps/index.d.ts +11 -0
- package/dist/types/components/GrSteps/safelist.d.ts +1 -0
- package/dist/types/components/GrSteps/stepsModel.d.ts +57 -0
- package/dist/types/components/GrValue/GrValue.vue.d.ts +51 -0
- package/dist/types/components/GrValue/config.d.ts +1 -0
- package/dist/types/components/GrValue/grValueStyles.d.ts +34 -0
- package/dist/types/components/GrValue/index.d.ts +5 -0
- package/dist/types/components/GrValue/safelist.d.ts +1 -0
- package/dist/types/components/shared/truncationTitle.d.ts +16 -0
- package/dist/types/composables/internal/useMenuItemsFocus.d.ts +24 -0
- package/dist/types/composables/internal/useTypeahead.d.ts +30 -0
- package/dist/types/composables/useFloating.d.ts +33 -2
- package/dist/types/granular-provider/shared.d.ts +5 -0
- package/dist/types/i18n/messages/en.d.ts +26 -0
- package/dist/types/i18n/messages/es.d.ts +26 -0
- package/dist/types/i18n/messages/ru.d.ts +26 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/web-types.json +799 -195
- package/package.json +22 -2
- package/tokens/themes/dark.json +26 -6
- package/tokens/themes/light.json +20 -0
- package/dist/chunks/config-BSyiFlbi.js.map +0 -1
- package/dist/chunks/config-Be9k9bOf.js.map +0 -1
- package/dist/chunks/config-BfsBepkH2.js.map +0 -1
- package/dist/chunks/config-Bm_Sovla.js.map +0 -1
- package/dist/chunks/config-BoNR7_PD2.js.map +0 -1
- package/dist/chunks/config-BuGlNPE9.js.map +0 -1
- package/dist/chunks/config-C5mO5DYZ.js.map +0 -1
- package/dist/chunks/config-DAX8Deh12.js.map +0 -1
- package/dist/chunks/config-DBQQT-WP.js.map +0 -1
- package/dist/chunks/config-DCwQBMmJ.js.map +0 -1
- package/dist/chunks/config-T3qdQBgU2.js.map +0 -1
- package/dist/chunks/config-qVg3Zz_A.js.map +0 -1
- package/dist/chunks/config-zjeAJ4ho.js.map +0 -1
- package/dist/chunks/context-BfIQv7m1.js.map +0 -1
- package/dist/chunks/en-DCCFP4qu.js.map +0 -1
- package/dist/chunks/es-CT34HBVM.js.map +0 -1
- package/dist/chunks/grPopoverStyles-Rz_Z5nLW.js.map +0 -1
- package/dist/chunks/granular-provider-CQKhl5C_.js.map +0 -1
- package/dist/chunks/ru-CLiAMwrx.js.map +0 -1
- package/dist/components/GrCard/chunks/GrCard-Bc7nRfbe.js.map +0 -1
- package/dist/components/GrCommandPalette/chunks/GrCommandPalette-BFcMf4Pn.js.map +0 -1
- package/dist/components/GrConfigProvider/chunks/GrConfigProvider-UP-EaoAf.js.map +0 -1
- package/dist/components/GrDataTable/chunks/GrDataTable-B5MmZFUg.js.map +0 -1
- package/dist/components/GrDelta/chunks/GrDelta-DFvxNpmN.js.map +0 -1
- package/dist/components/GrDescriptionList/chunks/GrDescriptionList-2zFXzX83.js.map +0 -1
- package/dist/components/GrDialogService/chunks/GrDialogService-CrwA4aJq.js.map +0 -1
- package/dist/components/GrDrawer/chunks/GrDrawer-C3zAg2tG.js.map +0 -1
- package/dist/components/GrDropdown/chunks/GrDropdown-BSfFOcDx.js.map +0 -1
- package/dist/components/GrDropdownMenu/chunks/GrDropdownMenu-DyS6dWDp.js.map +0 -1
- package/dist/components/GrFileUpload/chunks/GrFileUpload-D3-vC-ap.js.map +0 -1
- package/dist/components/GrFormField/chunks/GrFormField-kqfVY30N.js.map +0 -1
- package/dist/components/GrJsonViewer/chunks/GrJsonViewer-DFUppRNb.js.map +0 -1
- package/dist/components/GrList/chunks/GrList-BRYhpqIe.js.map +0 -1
- package/dist/components/GrLoading/chunks/GrLoading-C3DZSSuh.js.map +0 -1
- package/dist/components/GrModal/chunks/GrModal-CPz7SWD_.js.map +0 -1
- package/dist/components/GrPopover/chunks/GrPopover-b70bIlQ9.js.map +0 -1
- package/dist/components/GrSegmented/chunks/GrSegmented-D1mjxF_O.js.map +0 -1
- package/dist/components/GrSelect/chunks/GrSelect-CaGuyvtb.js.map +0 -1
- package/dist/components/GrStatistic/chunks/GrStatistic-C7wQECeS.js.map +0 -1
- package/dist/components/GrTimeline/chunks/GrTimeline-Ch9sHzwL.js.map +0 -1
- package/dist/chunks/{config-BfsBepkH2.js → config-BfsBepkH.js} +0 -0
- package/dist/chunks/{config-BoNR7_PD2.js → config-BoNR7_PD.js} +0 -0
- package/dist/chunks/{config-BuGlNPE9.js → config-BuGlNPE92.js} +0 -0
- package/dist/chunks/{config-DAX8Deh12.js → config-DAX8Deh1.js} +0 -0
- package/dist/chunks/{config-T3qdQBgU2.js → config-T3qdQBgU.js} +0 -0
- package/dist/chunks/{config-zjeAJ4ho.js → config-zjeAJ4ho2.js} +0 -0
- package/dist/chunks/{context-BfIQv7m1.js → context-BfIQv7m12.js} +0 -0
- package/dist/components/GrTree/chunks/{GrTree-BvOeQ3xJ.js → GrTree-J5q8aCya.js} +1 -1
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { n as formatStatisticValue, t as GrStatistic_default } from "./chunks/GrStatistic-
|
|
2
|
-
import { n as grStatisticSafelist, t as grStatisticConfig } from "../../chunks/config-
|
|
1
|
+
import { n as formatStatisticValue, t as GrStatistic_default } from "./chunks/GrStatistic-BJQv5aOS.js";
|
|
2
|
+
import { n as grStatisticSafelist, t as grStatisticConfig } from "../../chunks/config-C8tVRv8i.js";
|
|
3
3
|
export { GrStatistic_default as GrStatistic, GrStatistic_default as default, formatStatisticValue, grStatisticConfig, grStatisticSafelist };
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
import { a as useGrComponentSize, i as useGrComponentProp } from "../../../chunks/context-CTbuwcYs.js";
|
|
2
|
+
import { n as useGranularityTranslations } from "../../../chunks/granularityI18n-BC5zsj_d.js";
|
|
3
|
+
import { t as check_default } from "../../../chunks/check-BZI24Qs4.js";
|
|
4
|
+
import { t as GrProgressBar_default } from "../../GrProgressBar/chunks/GrProgressBar-hszUOC8f.js";
|
|
5
|
+
import { _ as stepsSizeClassBySize, a as stepsCompactBarClass, b as stepsTriggerEnabledClass, c as stepsCompactRowClass, d as stepsConnectorPendingClass, f as stepsDescriptionClass, g as stepsRootClass, h as stepsListClass, i as grStepsMarkerClass, l as stepsConnectorClass, m as stepsItemConnectedClass, o as stepsCompactCounterClass, p as stepsItemClass, r as grStepsLabelClass, s as stepsCompactLabelClass, u as stepsConnectorDoneClass, v as stepsTriggerClass, y as stepsTriggerClassByOrientation } from "../../../chunks/config-DGWFal5h.js";
|
|
6
|
+
import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, normalizeClass, openBlock, renderList, renderSlot, resolveDynamicComponent, toDisplayString, unref, withCtx } from "vue";
|
|
7
|
+
//#region src/components/GrSteps/stepsModel.ts
|
|
8
|
+
function stepIndexOf(steps, value) {
|
|
9
|
+
return steps.findIndex((step) => step.value === value);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Статус шага: явный побеждает позиционный.
|
|
13
|
+
*
|
|
14
|
+
* Позиция даёт три состояния из четырёх, и только `error` приходит снаружи —
|
|
15
|
+
* вывести его неоткуда, ошибка живёт в форме, а не в порядке шагов.
|
|
16
|
+
*/
|
|
17
|
+
function stepStatusAt(steps, index, currentIndex) {
|
|
18
|
+
const explicit = steps[index]?.status;
|
|
19
|
+
if (explicit) return explicit;
|
|
20
|
+
if (index < currentIndex) return "complete";
|
|
21
|
+
if (index === currentIndex) return "current";
|
|
22
|
+
return "upcoming";
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Можно ли уйти на шаг по его индексу.
|
|
26
|
+
*
|
|
27
|
+
* `linear` ограничивает **только движение вперёд**, и не одним шагом, а первым
|
|
28
|
+
* непройденным: вернуться назад и снова прыгнуть на тот же шаг, до которого уже
|
|
29
|
+
* дошёл, — нормальный сценарий правки заполненного мастера. Запрещать его
|
|
30
|
+
* значило бы заставлять пользователя проходить всё заново ради одной опечатки.
|
|
31
|
+
*/
|
|
32
|
+
function canEnterStep(options) {
|
|
33
|
+
const { steps, index, currentIndex, linear } = options;
|
|
34
|
+
const step = steps[index];
|
|
35
|
+
if (!step || step.disabled) return false;
|
|
36
|
+
if (index === currentIndex) return false;
|
|
37
|
+
if (!linear || index < currentIndex) return true;
|
|
38
|
+
return index <= furthestReachableIndex(steps, currentIndex);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Дальний край доступного в линейном режиме: текущий шаг плюс идущие за ним
|
|
42
|
+
* подряд помеченные пройденными. Шаг с ошибкой краем не является — он и есть
|
|
43
|
+
* причина, по которой дальше идти нельзя.
|
|
44
|
+
*/
|
|
45
|
+
function furthestReachableIndex(steps, currentIndex) {
|
|
46
|
+
let furthest = currentIndex + 1;
|
|
47
|
+
for (let index = currentIndex + 1; index < steps.length; index += 1) {
|
|
48
|
+
if (steps[index]?.status !== "complete") break;
|
|
49
|
+
furthest = index + 1;
|
|
50
|
+
}
|
|
51
|
+
return Math.min(furthest, steps.length - 1);
|
|
52
|
+
}
|
|
53
|
+
/** Индекс следующего доступного шага, или `-1`, если дальше идти некуда. */
|
|
54
|
+
function nextEnterableIndex(steps, currentIndex) {
|
|
55
|
+
for (let index = currentIndex + 1; index < steps.length; index += 1) if (!steps[index]?.disabled) return index;
|
|
56
|
+
return -1;
|
|
57
|
+
}
|
|
58
|
+
/** Индекс предыдущего доступного шага, или `-1`. */
|
|
59
|
+
function previousEnterableIndex(steps, currentIndex) {
|
|
60
|
+
for (let index = currentIndex - 1; index >= 0; index -= 1) if (!steps[index]?.disabled) return index;
|
|
61
|
+
return -1;
|
|
62
|
+
}
|
|
63
|
+
//#endregion
|
|
64
|
+
//#region src/components/GrSteps/GrSteps.vue?vue&type=script&setup=true&lang.ts
|
|
65
|
+
var _hoisted_1 = ["data-orientation", "aria-label"];
|
|
66
|
+
var _hoisted_2 = {
|
|
67
|
+
key: 0,
|
|
68
|
+
"data-gr-steps-compact": ""
|
|
69
|
+
};
|
|
70
|
+
var _hoisted_3 = ["data-value", "data-status"];
|
|
71
|
+
var _hoisted_4 = { class: "block min-w-0" };
|
|
72
|
+
var _hoisted_5 = {
|
|
73
|
+
key: 0,
|
|
74
|
+
class: "sr-only"
|
|
75
|
+
};
|
|
76
|
+
var _hoisted_6 = {
|
|
77
|
+
"data-gr-steps-status": "",
|
|
78
|
+
role: "status",
|
|
79
|
+
class: "sr-only"
|
|
80
|
+
};
|
|
81
|
+
//#endregion
|
|
82
|
+
//#region src/components/GrSteps/GrSteps.vue
|
|
83
|
+
var GrSteps_default = /* @__PURE__ */ defineComponent({
|
|
84
|
+
__name: "GrSteps",
|
|
85
|
+
props: {
|
|
86
|
+
modelValue: {},
|
|
87
|
+
steps: {},
|
|
88
|
+
orientation: { default: void 0 },
|
|
89
|
+
size: { default: void 0 },
|
|
90
|
+
variant: { default: void 0 },
|
|
91
|
+
linear: {
|
|
92
|
+
type: Boolean,
|
|
93
|
+
default: void 0
|
|
94
|
+
},
|
|
95
|
+
clickable: {
|
|
96
|
+
type: Boolean,
|
|
97
|
+
default: void 0
|
|
98
|
+
},
|
|
99
|
+
ariaLabel: { default: void 0 },
|
|
100
|
+
beforeLeave: {
|
|
101
|
+
type: Function,
|
|
102
|
+
default: void 0
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
emits: ["update:modelValue", "change"],
|
|
106
|
+
setup(__props, { expose: __expose, emit: __emit }) {
|
|
107
|
+
const props = __props;
|
|
108
|
+
const emit = __emit;
|
|
109
|
+
const { t } = useGranularityTranslations();
|
|
110
|
+
const resolvedSize = useGrComponentSize(() => props.size, { component: "GrSteps" });
|
|
111
|
+
const resolvedOrientation = useGrComponentProp("GrSteps", "orientation", () => props.orientation, "horizontal");
|
|
112
|
+
const resolvedVariant = useGrComponentProp("GrSteps", "variant", () => props.variant, "steps");
|
|
113
|
+
const resolvedLinear = useGrComponentProp("GrSteps", "linear", () => props.linear, true);
|
|
114
|
+
const resolvedClickable = useGrComponentProp("GrSteps", "clickable", () => props.clickable, true);
|
|
115
|
+
const currentIndex = computed(() => stepIndexOf(props.steps, props.modelValue));
|
|
116
|
+
const currentStep = computed(() => props.steps[currentIndex.value]);
|
|
117
|
+
const resolvedAriaLabel = computed(() => props.ariaLabel ?? t("gr.steps.label", "Progress"));
|
|
118
|
+
function statusAt(index) {
|
|
119
|
+
return stepStatusAt(props.steps, index, currentIndex.value);
|
|
120
|
+
}
|
|
121
|
+
function isEnterable(index) {
|
|
122
|
+
if (!resolvedClickable.value) return false;
|
|
123
|
+
return canEnterStep({
|
|
124
|
+
steps: props.steps,
|
|
125
|
+
index,
|
|
126
|
+
currentIndex: currentIndex.value,
|
|
127
|
+
linear: resolvedLinear.value
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Пройденный шаг печатает галку вместо номера, шаг с ошибкой — восклицание.
|
|
132
|
+
* Оба декоративны: смысл несёт скрытая подпись состояния рядом с меткой.
|
|
133
|
+
*/
|
|
134
|
+
function markerText(index) {
|
|
135
|
+
return statusAt(index) === "error" ? "!" : String(index + 1);
|
|
136
|
+
}
|
|
137
|
+
function stateText(status) {
|
|
138
|
+
if (status === "complete") return t("gr.steps.completed", "completed");
|
|
139
|
+
if (status === "error") return t("gr.steps.error", "has errors");
|
|
140
|
+
return "";
|
|
141
|
+
}
|
|
142
|
+
const statusText = computed(() => t("gr.steps.status", "Step {step} of {count}", {
|
|
143
|
+
step: currentIndex.value + 1,
|
|
144
|
+
count: props.steps.length
|
|
145
|
+
}));
|
|
146
|
+
/** Полоса компактного вида: доля пройденного, а не номер шага. */
|
|
147
|
+
const progressValue = computed(() => {
|
|
148
|
+
if (props.steps.length <= 1) return 100;
|
|
149
|
+
return Math.round(currentIndex.value / (props.steps.length - 1) * 100);
|
|
150
|
+
});
|
|
151
|
+
function tagFor(index) {
|
|
152
|
+
return isEnterable(index) ? "button" : "span";
|
|
153
|
+
}
|
|
154
|
+
function triggerClass(index) {
|
|
155
|
+
const base = `${stepsTriggerClass} ${stepsTriggerClassByOrientation[resolvedOrientation.value]}`;
|
|
156
|
+
return isEnterable(index) ? `${base} ${stepsTriggerEnabledClass}` : base;
|
|
157
|
+
}
|
|
158
|
+
/** Место под соединитель нужно только тем пунктам, за которыми ещё есть шаг. */
|
|
159
|
+
function itemClass(index) {
|
|
160
|
+
const base = stepsItemClass[resolvedOrientation.value];
|
|
161
|
+
if (index >= props.steps.length - 1) return base;
|
|
162
|
+
return `${base} ${stepsItemConnectedClass[resolvedOrientation.value]}`.trim();
|
|
163
|
+
}
|
|
164
|
+
function connectorClass(index) {
|
|
165
|
+
const done = statusAt(index) === "complete";
|
|
166
|
+
return `${stepsConnectorClass[resolvedOrientation.value]} ${done ? stepsConnectorDoneClass : stepsConnectorPendingClass}`;
|
|
167
|
+
}
|
|
168
|
+
function iconOf(step) {
|
|
169
|
+
return step.icon;
|
|
170
|
+
}
|
|
171
|
+
async function goToIndex(index) {
|
|
172
|
+
const target = props.steps[index];
|
|
173
|
+
if (!target || target.value === props.modelValue) return false;
|
|
174
|
+
if (props.beforeLeave) {
|
|
175
|
+
if (!await props.beforeLeave(props.modelValue, target.value)) return false;
|
|
176
|
+
}
|
|
177
|
+
emit("update:modelValue", target.value);
|
|
178
|
+
emit("change", target.value);
|
|
179
|
+
return true;
|
|
180
|
+
}
|
|
181
|
+
async function onStepClick(index) {
|
|
182
|
+
if (!isEnterable(index)) return;
|
|
183
|
+
await goToIndex(index);
|
|
184
|
+
}
|
|
185
|
+
async function next() {
|
|
186
|
+
const index = nextEnterableIndex(props.steps, currentIndex.value);
|
|
187
|
+
return index === -1 ? false : goToIndex(index);
|
|
188
|
+
}
|
|
189
|
+
async function back() {
|
|
190
|
+
const index = previousEnterableIndex(props.steps, currentIndex.value);
|
|
191
|
+
return index === -1 ? false : goToIndex(index);
|
|
192
|
+
}
|
|
193
|
+
async function goTo(value) {
|
|
194
|
+
return goToIndex(stepIndexOf(props.steps, value));
|
|
195
|
+
}
|
|
196
|
+
__expose({
|
|
197
|
+
next,
|
|
198
|
+
back,
|
|
199
|
+
goTo,
|
|
200
|
+
isFirst: computed(() => previousEnterableIndex(props.steps, currentIndex.value) === -1),
|
|
201
|
+
isLast: computed(() => nextEnterableIndex(props.steps, currentIndex.value) === -1)
|
|
202
|
+
});
|
|
203
|
+
return (_ctx, _cache) => {
|
|
204
|
+
return openBlock(), createElementBlock("nav", {
|
|
205
|
+
"data-gr-steps": "",
|
|
206
|
+
"data-orientation": unref(resolvedOrientation),
|
|
207
|
+
class: normalizeClass([unref(stepsRootClass), unref(stepsSizeClassBySize)[unref(resolvedSize)]]),
|
|
208
|
+
"aria-label": resolvedAriaLabel.value
|
|
209
|
+
}, [unref(resolvedVariant) === "compact" ? (openBlock(), createElementBlock("div", _hoisted_2, [createElementVNode("div", { class: normalizeClass(unref(stepsCompactRowClass)) }, [createElementVNode("span", { class: normalizeClass(unref(stepsCompactLabelClass)) }, toDisplayString(currentStep.value?.label), 3), createElementVNode("span", { class: normalizeClass(unref(stepsCompactCounterClass)) }, toDisplayString(currentIndex.value + 1) + " / " + toDisplayString(__props.steps.length), 3)], 2), createVNode(GrProgressBar_default, {
|
|
210
|
+
value: progressValue.value,
|
|
211
|
+
size: unref(resolvedSize) === "lg" ? "md" : "sm",
|
|
212
|
+
class: normalizeClass(unref(stepsCompactBarClass)),
|
|
213
|
+
"aria-hidden": "true"
|
|
214
|
+
}, null, 8, [
|
|
215
|
+
"value",
|
|
216
|
+
"size",
|
|
217
|
+
"class"
|
|
218
|
+
])])) : (openBlock(), createElementBlock("ol", {
|
|
219
|
+
key: 1,
|
|
220
|
+
"data-gr-steps-list": "",
|
|
221
|
+
class: normalizeClass(unref(stepsListClass)[unref(resolvedOrientation)])
|
|
222
|
+
}, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.steps, (step, index) => {
|
|
223
|
+
return openBlock(), createElementBlock("li", {
|
|
224
|
+
key: step.value,
|
|
225
|
+
"data-gr-step": "",
|
|
226
|
+
"data-value": step.value,
|
|
227
|
+
"data-status": statusAt(index),
|
|
228
|
+
class: normalizeClass(itemClass(index))
|
|
229
|
+
}, [(openBlock(), createBlock(resolveDynamicComponent(tagFor(index)), {
|
|
230
|
+
"data-gr-step-trigger": "",
|
|
231
|
+
type: tagFor(index) === "button" ? "button" : void 0,
|
|
232
|
+
class: normalizeClass(triggerClass(index)),
|
|
233
|
+
"aria-current": statusAt(index) === "current" ? "step" : void 0,
|
|
234
|
+
"aria-disabled": step.disabled ? "true" : void 0,
|
|
235
|
+
onClick: ($event) => tagFor(index) === "button" ? onStepClick(index) : void 0
|
|
236
|
+
}, {
|
|
237
|
+
default: withCtx(() => [renderSlot(_ctx.$slots, "step", {
|
|
238
|
+
step,
|
|
239
|
+
index,
|
|
240
|
+
status: statusAt(index),
|
|
241
|
+
enterable: isEnterable(index)
|
|
242
|
+
}, () => [createElementVNode("span", {
|
|
243
|
+
"data-gr-step-marker": "",
|
|
244
|
+
class: normalizeClass(unref(grStepsMarkerClass)(statusAt(index))),
|
|
245
|
+
"aria-hidden": "true"
|
|
246
|
+
}, [step.icon ? (openBlock(), createBlock(resolveDynamicComponent(iconOf(step)), {
|
|
247
|
+
key: 0,
|
|
248
|
+
class: "h-[60%] w-[60%]"
|
|
249
|
+
})) : statusAt(index) === "complete" ? (openBlock(), createBlock(unref(check_default), {
|
|
250
|
+
key: 1,
|
|
251
|
+
class: "h-[60%] w-[60%]"
|
|
252
|
+
})) : (openBlock(), createElementBlock(Fragment, { key: 2 }, [createTextVNode(toDisplayString(markerText(index)), 1)], 64))], 2), createElementVNode("span", _hoisted_4, [
|
|
253
|
+
createElementVNode("span", {
|
|
254
|
+
"data-gr-step-label": "",
|
|
255
|
+
class: normalizeClass(unref(grStepsLabelClass)(statusAt(index)))
|
|
256
|
+
}, toDisplayString(step.label), 3),
|
|
257
|
+
stateText(statusAt(index)) ? (openBlock(), createElementBlock("span", _hoisted_5, " — " + toDisplayString(stateText(statusAt(index))), 1)) : createCommentVNode("", true),
|
|
258
|
+
step.description ? (openBlock(), createElementBlock("span", {
|
|
259
|
+
key: 1,
|
|
260
|
+
"data-gr-step-description": "",
|
|
261
|
+
class: normalizeClass(unref(stepsDescriptionClass))
|
|
262
|
+
}, toDisplayString(step.description), 3)) : createCommentVNode("", true)
|
|
263
|
+
])])]),
|
|
264
|
+
_: 2
|
|
265
|
+
}, 1032, [
|
|
266
|
+
"type",
|
|
267
|
+
"class",
|
|
268
|
+
"aria-current",
|
|
269
|
+
"aria-disabled",
|
|
270
|
+
"onClick"
|
|
271
|
+
])), index < __props.steps.length - 1 ? (openBlock(), createElementBlock("span", {
|
|
272
|
+
key: 0,
|
|
273
|
+
"data-gr-step-connector": "",
|
|
274
|
+
class: normalizeClass(connectorClass(index)),
|
|
275
|
+
"aria-hidden": "true"
|
|
276
|
+
}, null, 2)) : createCommentVNode("", true)], 10, _hoisted_3);
|
|
277
|
+
}), 128))], 2)), createElementVNode("div", _hoisted_6, toDisplayString(statusText.value), 1)], 10, _hoisted_1);
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
//#endregion
|
|
282
|
+
export { GrSteps_default as t };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GrSteps-Cce4rfr3.js","names":[],"sources":["../../../../src/components/GrSteps/stepsModel.ts","../../../../src/components/GrSteps/GrSteps.vue","../../../../src/components/GrSteps/GrSteps.vue"],"sourcesContent":["import type { Component } from 'vue'\n\n/**\n * Правила шагового мастера — чистая арифметика без Vue.\n *\n * Вынесено отдельным модулем и тестируется без монтирования: «можно ли уйти на\n * шаг N» и «какого он статуса» — вся содержательная логика компонента, и\n * проверять её через отрендеренный DOM было бы дороже и слабее (эталон —\n * `GrForm/validation.ts`).\n */\n\n/**\n * Состояние шага.\n *\n * `error` не выводится из позиции — его ставит приложение, когда шаг пройден,\n * но не прошёл проверку. Без него мастер не умеет сказать «на втором шаге\n * остались ошибки», ради чего гейт перехода и заводится.\n */\nexport type GrStepStatus = 'complete' | 'current' | 'upcoming' | 'error'\n\nexport type GrStep = {\n value: string\n label: string\n /** Вторая строка под подписью: что от пользователя ждут на этом шаге. */\n description?: string\n /**\n * Иконка вместо номера — декоративна. Vue-компонент либо класс иконки вашей\n * UnoCSS-сборки (`i-lucide-*` требует вашего `presetIcons`).\n */\n icon?: string | Component\n /** Явный статус. Не задан — выводится из позиции относительно текущего шага. */\n status?: GrStepStatus\n disabled?: boolean\n}\n\nexport function stepIndexOf(steps: readonly GrStep[], value: string): number {\n return steps.findIndex(step => step.value === value)\n}\n\n/**\n * Статус шага: явный побеждает позиционный.\n *\n * Позиция даёт три состояния из четырёх, и только `error` приходит снаружи —\n * вывести его неоткуда, ошибка живёт в форме, а не в порядке шагов.\n */\nexport function stepStatusAt(steps: readonly GrStep[], index: number, currentIndex: number): GrStepStatus {\n const explicit = steps[index]?.status\n if (explicit) return explicit\n\n if (index < currentIndex) return 'complete'\n if (index === currentIndex) return 'current'\n return 'upcoming'\n}\n\n/**\n * Можно ли уйти на шаг по его индексу.\n *\n * `linear` ограничивает **только движение вперёд**, и не одним шагом, а первым\n * непройденным: вернуться назад и снова прыгнуть на тот же шаг, до которого уже\n * дошёл, — нормальный сценарий правки заполненного мастера. Запрещать его\n * значило бы заставлять пользователя проходить всё заново ради одной опечатки.\n */\nexport function canEnterStep(options: {\n steps: readonly GrStep[]\n index: number\n currentIndex: number\n linear: boolean\n}): boolean {\n const { steps, index, currentIndex, linear } = options\n const step = steps[index]\n\n if (!step || step.disabled) return false\n if (index === currentIndex) return false\n if (!linear || index < currentIndex) return true\n\n return index <= furthestReachableIndex(steps, currentIndex)\n}\n\n/**\n * Дальний край доступного в линейном режиме: текущий шаг плюс идущие за ним\n * подряд помеченные пройденными. Шаг с ошибкой краем не является — он и есть\n * причина, по которой дальше идти нельзя.\n */\nfunction furthestReachableIndex(steps: readonly GrStep[], currentIndex: number): number {\n let furthest = currentIndex + 1\n\n for (let index = currentIndex + 1; index < steps.length; index += 1) {\n if (steps[index]?.status !== 'complete') break\n furthest = index + 1\n }\n\n return Math.min(furthest, steps.length - 1)\n}\n\n/** Индекс следующего доступного шага, или `-1`, если дальше идти некуда. */\nexport function nextEnterableIndex(steps: readonly GrStep[], currentIndex: number): number {\n for (let index = currentIndex + 1; index < steps.length; index += 1) {\n if (!steps[index]?.disabled) return index\n }\n\n return -1\n}\n\n/** Индекс предыдущего доступного шага, или `-1`. */\nexport function previousEnterableIndex(steps: readonly GrStep[], currentIndex: number): number {\n for (let index = currentIndex - 1; index >= 0; index -= 1) {\n if (!steps[index]?.disabled) return index\n }\n\n return -1\n}\n","<script setup lang=\"ts\">\nimport type { Component } from 'vue'\nimport { computed } from 'vue'\n\nimport IconCheck from '~icons/lucide/check'\n\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport { useGrComponentProp, useGrComponentSize } from '../GrConfigProvider/context'\nimport GrProgressBar from '../GrProgressBar/GrProgressBar.vue'\n\nimport type { GrStepsOrientation, GrStepsSize, GrStepsVariant } from './grStepsStyles'\nimport {\n grStepsLabelClass,\n grStepsMarkerClass,\n stepsCompactBarClass,\n stepsCompactCounterClass,\n stepsCompactLabelClass,\n stepsCompactRowClass,\n stepsConnectorClass,\n stepsConnectorDoneClass,\n stepsConnectorPendingClass,\n stepsDescriptionClass,\n stepsItemClass,\n stepsItemConnectedClass,\n stepsListClass,\n stepsRootClass,\n stepsSizeClassBySize,\n stepsTriggerClass,\n stepsTriggerClassByOrientation,\n stepsTriggerEnabledClass,\n} from './grStepsStyles'\nimport type { GrStep, GrStepStatus } from './stepsModel'\nimport {\n canEnterStep,\n nextEnterableIndex,\n previousEnterableIndex,\n stepIndexOf,\n stepStatusAt,\n} from './stepsModel'\n\n/**\n * Индикатор шагов многошагового мастера.\n *\n * По семантике это **навигация**, а не составной виджет выбора: `<nav>` со\n * списком, где пройденный шаг — кнопка со своей остановкой `Tab`, текущий —\n * `aria-current=\"step\"`, будущий — вне таб-порядка. Той же формы держатся\n * `GrBreadcrumbs` и `GrBottomNav`; `role=\"tab\"` здесь неприменим — tablist без\n * `tabpanel` это сломанный паттерн, а панель шага никакой роли не несёт.\n *\n * Контент шага компонент не рисует: его ставит потребитель обычным `v-if`.\n */\nexport interface GrStepsProps {\n modelValue: string\n steps: GrStep[]\n orientation?: GrStepsOrientation\n size?: GrStepsSize\n /** Компактный вид для узкой колонки: подпись текущего шага и полоса прогресса. */\n variant?: GrStepsVariant\n /**\n * Вперёд — не дальше первого непройденного. Назад свободно всегда: вернуться\n * и поправить заполненное — обычный сценарий, а не обход правила.\n */\n linear?: boolean\n /** Переход кликом по шагу. Выключен — лента становится только индикатором. */\n clickable?: boolean\n ariaLabel?: string\n /**\n * Гейт перехода. Вернул `false` — перехода нет.\n *\n * Сюда потребитель кладёт валидацию шага: `GrSteps` про `GrForm` ничего не\n * знает и знать не должен, а форма уже отдаёт `validate()`/`validateField()`.\n */\n beforeLeave?: (from: string, to: string) => boolean | Promise<boolean>\n}\n\nexport interface GrStepsEmits {\n (e: 'update:modelValue', value: string): void\n (e: 'change', value: string): void\n}\n\nconst props = withDefaults(defineProps<GrStepsProps>(), {\n // Дефолты живут в резолверах ниже: Vue подставил бы свой раньше, чем\n // компонент заглянет в `GrConfigProvider`.\n orientation: undefined,\n size: undefined,\n variant: undefined,\n linear: undefined,\n clickable: undefined,\n ariaLabel: undefined,\n beforeLeave: undefined,\n})\n\nconst emit = defineEmits<GrStepsEmits>()\n\ndefineSlots<{\n /**\n * Своя разметка пункта. Корневой тег, `aria-current` и клик остаются за\n * компонентом — иначе доступность шага пришлось бы собирать заново.\n */\n step?: (props: { step: GrStep, index: number, status: GrStepStatus, enterable: boolean }) => unknown\n}>()\n\nconst { t } = useGranularityTranslations()\n\nconst resolvedSize = useGrComponentSize<GrStepsSize>(() => props.size, { component: 'GrSteps' })\nconst resolvedOrientation = useGrComponentProp('GrSteps', 'orientation', () => props.orientation, 'horizontal')\nconst resolvedVariant = useGrComponentProp('GrSteps', 'variant', () => props.variant, 'steps')\nconst resolvedLinear = useGrComponentProp('GrSteps', 'linear', () => props.linear, true)\nconst resolvedClickable = useGrComponentProp('GrSteps', 'clickable', () => props.clickable, true)\n\nconst currentIndex = computed(() => stepIndexOf(props.steps, props.modelValue))\nconst currentStep = computed(() => props.steps[currentIndex.value])\n\nconst resolvedAriaLabel = computed(() => props.ariaLabel ?? t('gr.steps.label', 'Progress'))\n\nfunction statusAt(index: number): GrStepStatus {\n return stepStatusAt(props.steps, index, currentIndex.value)\n}\n\nfunction isEnterable(index: number): boolean {\n if (!resolvedClickable.value) return false\n return canEnterStep({\n steps: props.steps,\n index,\n currentIndex: currentIndex.value,\n linear: resolvedLinear.value,\n })\n}\n\n/**\n * Пройденный шаг печатает галку вместо номера, шаг с ошибкой — восклицание.\n * Оба декоративны: смысл несёт скрытая подпись состояния рядом с меткой.\n */\nfunction markerText(index: number): string {\n return statusAt(index) === 'error' ? '!' : String(index + 1)\n}\n\nfunction stateText(status: GrStepStatus): string {\n if (status === 'complete') return t('gr.steps.completed', 'completed')\n if (status === 'error') return t('gr.steps.error', 'has errors')\n return ''\n}\n\nconst statusText = computed(() => t('gr.steps.status', 'Step {step} of {count}', {\n step: currentIndex.value + 1,\n count: props.steps.length,\n}))\n\n/** Полоса компактного вида: доля пройденного, а не номер шага. */\nconst progressValue = computed(() => {\n if (props.steps.length <= 1) return 100\n return Math.round((currentIndex.value / (props.steps.length - 1)) * 100)\n})\n\nfunction tagFor(index: number): 'button' | 'span' {\n return isEnterable(index) ? 'button' : 'span'\n}\n\nfunction triggerClass(index: number): string {\n const base = `${stepsTriggerClass} ${stepsTriggerClassByOrientation[resolvedOrientation.value]}`\n return isEnterable(index) ? `${base} ${stepsTriggerEnabledClass}` : base\n}\n\n/** Место под соединитель нужно только тем пунктам, за которыми ещё есть шаг. */\nfunction itemClass(index: number): string {\n const base = stepsItemClass[resolvedOrientation.value]\n if (index >= props.steps.length - 1) return base\n return `${base} ${stepsItemConnectedClass[resolvedOrientation.value]}`.trim()\n}\n\nfunction connectorClass(index: number): string {\n const done = statusAt(index) === 'complete'\n return `${stepsConnectorClass[resolvedOrientation.value]} ${done ? stepsConnectorDoneClass : stepsConnectorPendingClass}`\n}\n\nfunction iconOf(step: GrStep): string | Component | undefined {\n return step.icon\n}\n\nasync function goToIndex(index: number): Promise<boolean> {\n const target = props.steps[index]\n if (!target || target.value === props.modelValue) return false\n\n if (props.beforeLeave) {\n const allowed = await props.beforeLeave(props.modelValue, target.value)\n if (!allowed) return false\n }\n\n emit('update:modelValue', target.value)\n emit('change', target.value)\n\n return true\n}\n\nasync function onStepClick(index: number): Promise<void> {\n if (!isEnterable(index)) return\n await goToIndex(index)\n}\n\nasync function next(): Promise<boolean> {\n const index = nextEnterableIndex(props.steps, currentIndex.value)\n return index === -1 ? false : goToIndex(index)\n}\n\nasync function back(): Promise<boolean> {\n const index = previousEnterableIndex(props.steps, currentIndex.value)\n return index === -1 ? false : goToIndex(index)\n}\n\nasync function goTo(value: string): Promise<boolean> {\n return goToIndex(stepIndexOf(props.steps, value))\n}\n\ndefineExpose({\n next,\n back,\n goTo,\n isFirst: computed(() => previousEnterableIndex(props.steps, currentIndex.value) === -1),\n isLast: computed(() => nextEnterableIndex(props.steps, currentIndex.value) === -1),\n})\n</script>\n\n<template>\n <nav\n data-gr-steps\n :data-orientation=\"resolvedOrientation\"\n :class=\"[stepsRootClass, stepsSizeClassBySize[resolvedSize]]\"\n :aria-label=\"resolvedAriaLabel\"\n >\n <div v-if=\"resolvedVariant === 'compact'\" data-gr-steps-compact>\n <div :class=\"stepsCompactRowClass\">\n <span :class=\"stepsCompactLabelClass\">{{ currentStep?.label }}</span>\n <span :class=\"stepsCompactCounterClass\">{{ currentIndex + 1 }} / {{ steps.length }}</span>\n </div>\n <!--\n Полоса декоративна: то же самое уже сказано текстом рядом и скрытым\n живым регионом ниже, а второй `progressbar` в дереве заставил бы\n диктора читать прогресс дважды.\n -->\n <GrProgressBar\n :value=\"progressValue\"\n :size=\"resolvedSize === 'lg' ? 'md' : 'sm'\"\n :class=\"stepsCompactBarClass\"\n aria-hidden=\"true\"\n />\n </div>\n\n <ol v-else data-gr-steps-list :class=\"stepsListClass[resolvedOrientation]\">\n <li\n v-for=\"(step, index) in steps\"\n :key=\"step.value\"\n data-gr-step\n :data-value=\"step.value\"\n :data-status=\"statusAt(index)\"\n :class=\"itemClass(index)\"\n >\n <component\n :is=\"tagFor(index)\"\n data-gr-step-trigger\n :type=\"tagFor(index) === 'button' ? 'button' : undefined\"\n :class=\"triggerClass(index)\"\n :aria-current=\"statusAt(index) === 'current' ? 'step' : undefined\"\n :aria-disabled=\"step.disabled ? 'true' : undefined\"\n @click=\"tagFor(index) === 'button' ? onStepClick(index) : undefined\"\n >\n <slot\n name=\"step\"\n :step=\"step\"\n :index=\"index\"\n :status=\"statusAt(index)\"\n :enterable=\"isEnterable(index)\"\n >\n <span data-gr-step-marker :class=\"grStepsMarkerClass(statusAt(index))\" aria-hidden=\"true\">\n <component :is=\"iconOf(step)\" v-if=\"step.icon\" class=\"h-[60%] w-[60%]\" />\n <IconCheck v-else-if=\"statusAt(index) === 'complete'\" class=\"h-[60%] w-[60%]\" />\n <template v-else>{{ markerText(index) }}</template>\n </span>\n\n <span class=\"block min-w-0\">\n <span data-gr-step-label :class=\"grStepsLabelClass(statusAt(index))\">{{ step.label }}</span>\n <!--\n Состояние шага словом: пройденный и шаг с ошибкой иначе звучат\n одинаково — цвет маркера диктору недоступен.\n -->\n <span v-if=\"stateText(statusAt(index))\" class=\"sr-only\"> — {{ stateText(statusAt(index)) }}</span>\n <span v-if=\"step.description\" data-gr-step-description :class=\"stepsDescriptionClass\">\n {{ step.description }}\n </span>\n </span>\n </slot>\n </component>\n\n <span\n v-if=\"index < steps.length - 1\"\n data-gr-step-connector\n :class=\"connectorClass(index)\"\n aria-hidden=\"true\"\n />\n </li>\n </ol>\n\n <!--\n «Шаг 2 из 5» — состояние виджета, а не событие, поэтому живёт своим\n регионом в разметке, а не уходит в общий объявитель (`docs/announcer.md`).\n Образец — компактный индикатор `GrPagination`.\n -->\n <div data-gr-steps-status role=\"status\" class=\"sr-only\">\n{{ statusText }}\n</div>\n </nav>\n</template>\n","<script setup lang=\"ts\">\nimport type { Component } from 'vue'\nimport { computed } from 'vue'\n\nimport IconCheck from '~icons/lucide/check'\n\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport { useGrComponentProp, useGrComponentSize } from '../GrConfigProvider/context'\nimport GrProgressBar from '../GrProgressBar/GrProgressBar.vue'\n\nimport type { GrStepsOrientation, GrStepsSize, GrStepsVariant } from './grStepsStyles'\nimport {\n grStepsLabelClass,\n grStepsMarkerClass,\n stepsCompactBarClass,\n stepsCompactCounterClass,\n stepsCompactLabelClass,\n stepsCompactRowClass,\n stepsConnectorClass,\n stepsConnectorDoneClass,\n stepsConnectorPendingClass,\n stepsDescriptionClass,\n stepsItemClass,\n stepsItemConnectedClass,\n stepsListClass,\n stepsRootClass,\n stepsSizeClassBySize,\n stepsTriggerClass,\n stepsTriggerClassByOrientation,\n stepsTriggerEnabledClass,\n} from './grStepsStyles'\nimport type { GrStep, GrStepStatus } from './stepsModel'\nimport {\n canEnterStep,\n nextEnterableIndex,\n previousEnterableIndex,\n stepIndexOf,\n stepStatusAt,\n} from './stepsModel'\n\n/**\n * Индикатор шагов многошагового мастера.\n *\n * По семантике это **навигация**, а не составной виджет выбора: `<nav>` со\n * списком, где пройденный шаг — кнопка со своей остановкой `Tab`, текущий —\n * `aria-current=\"step\"`, будущий — вне таб-порядка. Той же формы держатся\n * `GrBreadcrumbs` и `GrBottomNav`; `role=\"tab\"` здесь неприменим — tablist без\n * `tabpanel` это сломанный паттерн, а панель шага никакой роли не несёт.\n *\n * Контент шага компонент не рисует: его ставит потребитель обычным `v-if`.\n */\nexport interface GrStepsProps {\n modelValue: string\n steps: GrStep[]\n orientation?: GrStepsOrientation\n size?: GrStepsSize\n /** Компактный вид для узкой колонки: подпись текущего шага и полоса прогресса. */\n variant?: GrStepsVariant\n /**\n * Вперёд — не дальше первого непройденного. Назад свободно всегда: вернуться\n * и поправить заполненное — обычный сценарий, а не обход правила.\n */\n linear?: boolean\n /** Переход кликом по шагу. Выключен — лента становится только индикатором. */\n clickable?: boolean\n ariaLabel?: string\n /**\n * Гейт перехода. Вернул `false` — перехода нет.\n *\n * Сюда потребитель кладёт валидацию шага: `GrSteps` про `GrForm` ничего не\n * знает и знать не должен, а форма уже отдаёт `validate()`/`validateField()`.\n */\n beforeLeave?: (from: string, to: string) => boolean | Promise<boolean>\n}\n\nexport interface GrStepsEmits {\n (e: 'update:modelValue', value: string): void\n (e: 'change', value: string): void\n}\n\nconst props = withDefaults(defineProps<GrStepsProps>(), {\n // Дефолты живут в резолверах ниже: Vue подставил бы свой раньше, чем\n // компонент заглянет в `GrConfigProvider`.\n orientation: undefined,\n size: undefined,\n variant: undefined,\n linear: undefined,\n clickable: undefined,\n ariaLabel: undefined,\n beforeLeave: undefined,\n})\n\nconst emit = defineEmits<GrStepsEmits>()\n\ndefineSlots<{\n /**\n * Своя разметка пункта. Корневой тег, `aria-current` и клик остаются за\n * компонентом — иначе доступность шага пришлось бы собирать заново.\n */\n step?: (props: { step: GrStep, index: number, status: GrStepStatus, enterable: boolean }) => unknown\n}>()\n\nconst { t } = useGranularityTranslations()\n\nconst resolvedSize = useGrComponentSize<GrStepsSize>(() => props.size, { component: 'GrSteps' })\nconst resolvedOrientation = useGrComponentProp('GrSteps', 'orientation', () => props.orientation, 'horizontal')\nconst resolvedVariant = useGrComponentProp('GrSteps', 'variant', () => props.variant, 'steps')\nconst resolvedLinear = useGrComponentProp('GrSteps', 'linear', () => props.linear, true)\nconst resolvedClickable = useGrComponentProp('GrSteps', 'clickable', () => props.clickable, true)\n\nconst currentIndex = computed(() => stepIndexOf(props.steps, props.modelValue))\nconst currentStep = computed(() => props.steps[currentIndex.value])\n\nconst resolvedAriaLabel = computed(() => props.ariaLabel ?? t('gr.steps.label', 'Progress'))\n\nfunction statusAt(index: number): GrStepStatus {\n return stepStatusAt(props.steps, index, currentIndex.value)\n}\n\nfunction isEnterable(index: number): boolean {\n if (!resolvedClickable.value) return false\n return canEnterStep({\n steps: props.steps,\n index,\n currentIndex: currentIndex.value,\n linear: resolvedLinear.value,\n })\n}\n\n/**\n * Пройденный шаг печатает галку вместо номера, шаг с ошибкой — восклицание.\n * Оба декоративны: смысл несёт скрытая подпись состояния рядом с меткой.\n */\nfunction markerText(index: number): string {\n return statusAt(index) === 'error' ? '!' : String(index + 1)\n}\n\nfunction stateText(status: GrStepStatus): string {\n if (status === 'complete') return t('gr.steps.completed', 'completed')\n if (status === 'error') return t('gr.steps.error', 'has errors')\n return ''\n}\n\nconst statusText = computed(() => t('gr.steps.status', 'Step {step} of {count}', {\n step: currentIndex.value + 1,\n count: props.steps.length,\n}))\n\n/** Полоса компактного вида: доля пройденного, а не номер шага. */\nconst progressValue = computed(() => {\n if (props.steps.length <= 1) return 100\n return Math.round((currentIndex.value / (props.steps.length - 1)) * 100)\n})\n\nfunction tagFor(index: number): 'button' | 'span' {\n return isEnterable(index) ? 'button' : 'span'\n}\n\nfunction triggerClass(index: number): string {\n const base = `${stepsTriggerClass} ${stepsTriggerClassByOrientation[resolvedOrientation.value]}`\n return isEnterable(index) ? `${base} ${stepsTriggerEnabledClass}` : base\n}\n\n/** Место под соединитель нужно только тем пунктам, за которыми ещё есть шаг. */\nfunction itemClass(index: number): string {\n const base = stepsItemClass[resolvedOrientation.value]\n if (index >= props.steps.length - 1) return base\n return `${base} ${stepsItemConnectedClass[resolvedOrientation.value]}`.trim()\n}\n\nfunction connectorClass(index: number): string {\n const done = statusAt(index) === 'complete'\n return `${stepsConnectorClass[resolvedOrientation.value]} ${done ? stepsConnectorDoneClass : stepsConnectorPendingClass}`\n}\n\nfunction iconOf(step: GrStep): string | Component | undefined {\n return step.icon\n}\n\nasync function goToIndex(index: number): Promise<boolean> {\n const target = props.steps[index]\n if (!target || target.value === props.modelValue) return false\n\n if (props.beforeLeave) {\n const allowed = await props.beforeLeave(props.modelValue, target.value)\n if (!allowed) return false\n }\n\n emit('update:modelValue', target.value)\n emit('change', target.value)\n\n return true\n}\n\nasync function onStepClick(index: number): Promise<void> {\n if (!isEnterable(index)) return\n await goToIndex(index)\n}\n\nasync function next(): Promise<boolean> {\n const index = nextEnterableIndex(props.steps, currentIndex.value)\n return index === -1 ? false : goToIndex(index)\n}\n\nasync function back(): Promise<boolean> {\n const index = previousEnterableIndex(props.steps, currentIndex.value)\n return index === -1 ? false : goToIndex(index)\n}\n\nasync function goTo(value: string): Promise<boolean> {\n return goToIndex(stepIndexOf(props.steps, value))\n}\n\ndefineExpose({\n next,\n back,\n goTo,\n isFirst: computed(() => previousEnterableIndex(props.steps, currentIndex.value) === -1),\n isLast: computed(() => nextEnterableIndex(props.steps, currentIndex.value) === -1),\n})\n</script>\n\n<template>\n <nav\n data-gr-steps\n :data-orientation=\"resolvedOrientation\"\n :class=\"[stepsRootClass, stepsSizeClassBySize[resolvedSize]]\"\n :aria-label=\"resolvedAriaLabel\"\n >\n <div v-if=\"resolvedVariant === 'compact'\" data-gr-steps-compact>\n <div :class=\"stepsCompactRowClass\">\n <span :class=\"stepsCompactLabelClass\">{{ currentStep?.label }}</span>\n <span :class=\"stepsCompactCounterClass\">{{ currentIndex + 1 }} / {{ steps.length }}</span>\n </div>\n <!--\n Полоса декоративна: то же самое уже сказано текстом рядом и скрытым\n живым регионом ниже, а второй `progressbar` в дереве заставил бы\n диктора читать прогресс дважды.\n -->\n <GrProgressBar\n :value=\"progressValue\"\n :size=\"resolvedSize === 'lg' ? 'md' : 'sm'\"\n :class=\"stepsCompactBarClass\"\n aria-hidden=\"true\"\n />\n </div>\n\n <ol v-else data-gr-steps-list :class=\"stepsListClass[resolvedOrientation]\">\n <li\n v-for=\"(step, index) in steps\"\n :key=\"step.value\"\n data-gr-step\n :data-value=\"step.value\"\n :data-status=\"statusAt(index)\"\n :class=\"itemClass(index)\"\n >\n <component\n :is=\"tagFor(index)\"\n data-gr-step-trigger\n :type=\"tagFor(index) === 'button' ? 'button' : undefined\"\n :class=\"triggerClass(index)\"\n :aria-current=\"statusAt(index) === 'current' ? 'step' : undefined\"\n :aria-disabled=\"step.disabled ? 'true' : undefined\"\n @click=\"tagFor(index) === 'button' ? onStepClick(index) : undefined\"\n >\n <slot\n name=\"step\"\n :step=\"step\"\n :index=\"index\"\n :status=\"statusAt(index)\"\n :enterable=\"isEnterable(index)\"\n >\n <span data-gr-step-marker :class=\"grStepsMarkerClass(statusAt(index))\" aria-hidden=\"true\">\n <component :is=\"iconOf(step)\" v-if=\"step.icon\" class=\"h-[60%] w-[60%]\" />\n <IconCheck v-else-if=\"statusAt(index) === 'complete'\" class=\"h-[60%] w-[60%]\" />\n <template v-else>{{ markerText(index) }}</template>\n </span>\n\n <span class=\"block min-w-0\">\n <span data-gr-step-label :class=\"grStepsLabelClass(statusAt(index))\">{{ step.label }}</span>\n <!--\n Состояние шага словом: пройденный и шаг с ошибкой иначе звучат\n одинаково — цвет маркера диктору недоступен.\n -->\n <span v-if=\"stateText(statusAt(index))\" class=\"sr-only\"> — {{ stateText(statusAt(index)) }}</span>\n <span v-if=\"step.description\" data-gr-step-description :class=\"stepsDescriptionClass\">\n {{ step.description }}\n </span>\n </span>\n </slot>\n </component>\n\n <span\n v-if=\"index < steps.length - 1\"\n data-gr-step-connector\n :class=\"connectorClass(index)\"\n aria-hidden=\"true\"\n />\n </li>\n </ol>\n\n <!--\n «Шаг 2 из 5» — состояние виджета, а не событие, поэтому живёт своим\n регионом в разметке, а не уходит в общий объявитель (`docs/announcer.md`).\n Образец — компактный индикатор `GrPagination`.\n -->\n <div data-gr-steps-status role=\"status\" class=\"sr-only\">\n{{ statusText }}\n</div>\n </nav>\n</template>\n"],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@ import { n as useGranularityTranslations } from "../../../chunks/granularityI18n
|
|
|
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 grSwitchThumbClass, r as grSwitchLabelClass, s as grSwitchTrackClass } from "../../../chunks/config-
|
|
6
|
+
import { a as grSwitchSpinnerClass, i as grSwitchRootClass, o as grSwitchThumbClass, r as grSwitchLabelClass, s as grSwitchTrackClass } from "../../../chunks/config-BoNR7_PD.js";
|
|
7
7
|
import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, defineComponent, mergeProps, normalizeClass, normalizeStyle, openBlock, ref, renderSlot, toDisplayString, unref } from "vue";
|
|
8
8
|
//#region src/components/GrSwitch/GrSwitch.vue?vue&type=script&setup=true&lang.ts
|
|
9
9
|
var _hoisted_1 = [
|
package/dist/components/GrSwitch/chunks/{GrSwitch-x_vQQ6ao.js.map → GrSwitch-CHiIj9GT.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GrSwitch-x_vQQ6ao.js","names":["$attrs","$slots"],"sources":["../../../../src/components/GrSwitch/GrSwitch.vue","../../../../src/components/GrSwitch/GrSwitch.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport IconLoader from '~icons/lucide/loader-circle'\n\nimport { useGrComponentSize } from '../GrConfigProvider/context'\nimport { useGrFormFieldContext } from '../GrFormField/context'\nimport { useGrFormControl } from '../../composables/useGrFormControl'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\n\nimport {\n grSwitchLabelClass,\n grSwitchRootClass,\n grSwitchSpinnerClass,\n grSwitchThumbClass,\n grSwitchTrackClass,\n type GrSwitchLabelPosition,\n type GrSwitchSize,\n} from './grSwitchStyles'\n\nexport type { GrSwitchLabelPosition, GrSwitchSize } from './grSwitchStyles'\n\n/**\n * Пропсы публичного GR-примитива «Switch».\n */\nexport interface GrSwitchProps {\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\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 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 },\n)\n\n// Контекст `GrFormField`: id для `<label for>`, описание ошибкой, невалидность.\n// `<button>` — labelable-элемент, поэтому клик по подписи фокусирует переключатель.\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>()\ndefineSlots<{\n /** Подпись переключателя. */\n default?: () => any\n}>()\n\n\nconst rootClass = computed(() => grSwitchRootClass(props.labelPosition))\n\nconst trackClass = computed(() => grSwitchTrackClass(resolvedSize.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\nconst labelClass = computed(() => grSwitchLabelClass(resolvedSize.value, isDisabled.value))\n\nconst resolvedLoadingText = computed(() => props.loadingText ?? t('gr.switch.loading', 'Saving…'))\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 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 </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 } from 'vue'\nimport IconLoader from '~icons/lucide/loader-circle'\n\nimport { useGrComponentSize } from '../GrConfigProvider/context'\nimport { useGrFormFieldContext } from '../GrFormField/context'\nimport { useGrFormControl } from '../../composables/useGrFormControl'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\n\nimport {\n grSwitchLabelClass,\n grSwitchRootClass,\n grSwitchSpinnerClass,\n grSwitchThumbClass,\n grSwitchTrackClass,\n type GrSwitchLabelPosition,\n type GrSwitchSize,\n} from './grSwitchStyles'\n\nexport type { GrSwitchLabelPosition, GrSwitchSize } from './grSwitchStyles'\n\n/**\n * Пропсы публичного GR-примитива «Switch».\n */\nexport interface GrSwitchProps {\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\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 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 },\n)\n\n// Контекст `GrFormField`: id для `<label for>`, описание ошибкой, невалидность.\n// `<button>` — labelable-элемент, поэтому клик по подписи фокусирует переключатель.\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>()\ndefineSlots<{\n /** Подпись переключателя. */\n default?: () => any\n}>()\n\n\nconst rootClass = computed(() => grSwitchRootClass(props.labelPosition))\n\nconst trackClass = computed(() => grSwitchTrackClass(resolvedSize.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\nconst labelClass = computed(() => grSwitchLabelClass(resolvedSize.value, isDisabled.value))\n\nconst resolvedLoadingText = computed(() => props.loadingText ?? t('gr.switch.loading', 'Saving…'))\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 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 </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
|
+
{"version":3,"file":"GrSwitch-CHiIj9GT.js","names":["$attrs","$slots"],"sources":["../../../../src/components/GrSwitch/GrSwitch.vue","../../../../src/components/GrSwitch/GrSwitch.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport IconLoader from '~icons/lucide/loader-circle'\n\nimport { useGrComponentSize } from '../GrConfigProvider/context'\nimport { useGrFormFieldContext } from '../GrFormField/context'\nimport { useGrFormControl } from '../../composables/useGrFormControl'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\n\nimport {\n grSwitchLabelClass,\n grSwitchRootClass,\n grSwitchSpinnerClass,\n grSwitchThumbClass,\n grSwitchTrackClass,\n type GrSwitchLabelPosition,\n type GrSwitchSize,\n} from './grSwitchStyles'\n\nexport type { GrSwitchLabelPosition, GrSwitchSize } from './grSwitchStyles'\n\n/**\n * Пропсы публичного GR-примитива «Switch».\n */\nexport interface GrSwitchProps {\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\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 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 },\n)\n\n// Контекст `GrFormField`: id для `<label for>`, описание ошибкой, невалидность.\n// `<button>` — labelable-элемент, поэтому клик по подписи фокусирует переключатель.\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>()\ndefineSlots<{\n /** Подпись переключателя. */\n default?: () => any\n}>()\n\n\nconst rootClass = computed(() => grSwitchRootClass(props.labelPosition))\n\nconst trackClass = computed(() => grSwitchTrackClass(resolvedSize.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\nconst labelClass = computed(() => grSwitchLabelClass(resolvedSize.value, isDisabled.value))\n\nconst resolvedLoadingText = computed(() => props.loadingText ?? t('gr.switch.loading', 'Saving…'))\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 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 </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 } from 'vue'\nimport IconLoader from '~icons/lucide/loader-circle'\n\nimport { useGrComponentSize } from '../GrConfigProvider/context'\nimport { useGrFormFieldContext } from '../GrFormField/context'\nimport { useGrFormControl } from '../../composables/useGrFormControl'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\n\nimport {\n grSwitchLabelClass,\n grSwitchRootClass,\n grSwitchSpinnerClass,\n grSwitchThumbClass,\n grSwitchTrackClass,\n type GrSwitchLabelPosition,\n type GrSwitchSize,\n} from './grSwitchStyles'\n\nexport type { GrSwitchLabelPosition, GrSwitchSize } from './grSwitchStyles'\n\n/**\n * Пропсы публичного GR-примитива «Switch».\n */\nexport interface GrSwitchProps {\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\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 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 },\n)\n\n// Контекст `GrFormField`: id для `<label for>`, описание ошибкой, невалидность.\n// `<button>` — labelable-элемент, поэтому клик по подписи фокусирует переключатель.\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>()\ndefineSlots<{\n /** Подпись переключателя. */\n default?: () => any\n}>()\n\n\nconst rootClass = computed(() => grSwitchRootClass(props.labelPosition))\n\nconst trackClass = computed(() => grSwitchTrackClass(resolvedSize.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\nconst labelClass = computed(() => grSwitchLabelClass(resolvedSize.value, isDisabled.value))\n\nconst resolvedLoadingText = computed(() => props.loadingText ?? t('gr.switch.loading', 'Saving…'))\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 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 </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-BoNR7_PD.js";
|
|
2
|
+
import { t as GrSwitch_default } from "./chunks/GrSwitch-CHiIj9GT.js";
|
|
3
3
|
export { GrSwitch_default as GrSwitch, GrSwitch_default as default, grSwitchConfig, grSwitchSafelist };
|
package/dist/components/GrTabPanels/chunks/{GrTabPanels-AJt1w1XC.js → GrTabPanels-BZQS8-JM.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { computed, createCommentVNode, createElementBlock, defineComponent, inject, openBlock, provide, ref, renderSlot, useId, watch } from "vue";
|
|
1
|
+
import { computed, createCommentVNode, createElementBlock, defineComponent, inject, onMounted, openBlock, provide, ref, renderSlot, useId, watch } from "vue";
|
|
2
2
|
//#region src/components/GrTabPanels/context.ts
|
|
3
3
|
var GR_TAB_PANELS_KEY = Symbol("gr-tab-panels");
|
|
4
4
|
//#endregion
|
|
@@ -63,6 +63,17 @@ var GrTabPanel_default = /* @__PURE__ */ defineComponent({
|
|
|
63
63
|
if (!props.keepAlive) return false;
|
|
64
64
|
return props.lazy ? wasActive.value : true;
|
|
65
65
|
});
|
|
66
|
+
/**
|
|
67
|
+
* Панель ссылается на вкладку по id, а существует ли вкладка — знает только
|
|
68
|
+
* приложение: `GrTabs` с другим (или отсутствующим) `idBase` оставит
|
|
69
|
+
* `aria-labelledby` висеть в пустоту. Проверяем это в dev, как `GrFormField`
|
|
70
|
+
* проверяет забытый контрол.
|
|
71
|
+
*/
|
|
72
|
+
if (typeof process !== "undefined" && process.env.NODE_ENV !== "production") onMounted(() => {
|
|
73
|
+
if (!tabId.value || !isActive.value) return;
|
|
74
|
+
if (document.getElementById(tabId.value)) return;
|
|
75
|
+
console.warn(`[GrTabPanel] Вкладки с id "${tabId.value}" нет в документе: \`aria-labelledby\` ссылается в пустоту. Передайте один и тот же \`idBase\` в \`GrTabs\` и \`GrTabPanels\`.`);
|
|
76
|
+
});
|
|
66
77
|
return (_ctx, _cache) => {
|
|
67
78
|
return shouldRender.value ? (openBlock(), createElementBlock("div", {
|
|
68
79
|
key: 0,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GrTabPanels-
|
|
1
|
+
{"version":3,"file":"GrTabPanels-BZQS8-JM.js","names":[],"sources":["../../../../src/components/GrTabPanels/context.ts","../../../../src/components/GrTabPanels/GrTabPanels.vue","../../../../src/components/GrTabPanels/GrTabPanels.vue","../../../../src/components/GrTabPanels/GrTabPanel.vue","../../../../src/components/GrTabPanels/GrTabPanel.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\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})\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})\n</script>\n\n<template>\n <div data-gr-tab-panels>\n <slot />\n </div>\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\nconst wasActive = ref(isActive.value)\nwatch(isActive, (active) => {\n if (active) wasActive.value = true\n})\n\nconst shouldRender = computed(() => {\n if (isActive.value) return true\n if (!props.keepAlive) 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 (!tabId.value || !isActive.value) return\n if (document.getElementById(tabId.value)) return\n\n console.warn(\n `[GrTabPanel] Вкладки с id \"${tabId.value}\" нет в документе: `\n + '`aria-labelledby` ссылается в пустоту. Передайте один и тот же `idBase` в `GrTabs` и `GrTabPanels`.',\n )\n })\n}\n</script>\n\n<template>\n <div\n v-if=\"shouldRender\"\n :id=\"panelId\"\n role=\"tabpanel\"\n data-gr-tab-panel\n :aria-labelledby=\"tabId\"\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</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\nconst wasActive = ref(isActive.value)\nwatch(isActive, (active) => {\n if (active) wasActive.value = true\n})\n\nconst shouldRender = computed(() => {\n if (isActive.value) return true\n if (!props.keepAlive) 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 (!tabId.value || !isActive.value) return\n if (document.getElementById(tabId.value)) return\n\n console.warn(\n `[GrTabPanel] Вкладки с id \"${tabId.value}\" нет в документе: `\n + '`aria-labelledby` ссылается в пустоту. Передайте один и тот же `idBase` в `GrTabs` и `GrTabPanels`.',\n )\n })\n}\n</script>\n\n<template>\n <div\n v-if=\"shouldRender\"\n :id=\"panelId\"\n role=\"tabpanel\"\n data-gr-tab-panel\n :aria-labelledby=\"tabId\"\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</template>\n"],"mappings":";;AAUA,IAAa,oBAAsD,OAAO,eAAe;;;;;;;;;;;;;ECUzF,MAAM,QAAQ;EAOd,MAAM,kBAAkB,MAAM;EAI9B,MAAM,iBAAiB,eAAe,MAAM,UAAU,eAAe;EAErE,QAAQ,mBAAmB;GACzB,aAAa,eAAe,MAAM,UAAU;GAC5C,QAAQ;EACV,CAAC;;uBAIC,mBAEM,OAFN,cAEM,CADJ,WAAQ,KAAA,QAAA,SAAA,CAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;EErBZ,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;EAEzF,MAAM,YAAY,IAAI,SAAS,KAAK;EACpC,MAAM,WAAW,WAAW;GAC1B,IAAI,QAAQ,UAAU,QAAQ;EAChC,CAAC;EAED,MAAM,eAAe,eAAe;GAClC,IAAI,SAAS,OAAO,OAAO;GAC3B,IAAI,CAAC,MAAM,WAAW,OAAO;GAC7B,OAAO,MAAM,OAAO,UAAU,QAAQ;EACxC,CAAC;;;;;;;EAQD,IAAA,OAAA,YAAA,eAAA,QAAA,IAAA,aAAA,cACE,gBAAgB;GACd,IAAI,CAAC,MAAM,SAAS,CAAC,SAAS,OAAO;GACrC,IAAI,SAAS,eAAe,MAAM,KAAK,GAAG;GAE1C,QAAQ,KACN,8BAA8B,MAAM,MAAM,+HAE5C;EACF,CAAC;;UAMO,aAAA,SAAA,UAAA,GADR,mBAWM,OAAA;;IATH,IAAI,QAAA;IACL,MAAK;IACL,qBAAA;IACC,mBAAiB,MAAA;IACjB,QAAQ,QAAA,aAAS,CAAK,SAAA,QAAQ,OAAU,KAAA;IACxC,UAAU,SAAA,QAAQ,IAAO,KAAA;IAC1B,OAAM;OAEN,WAAQ,KAAA,QAAA,SAAA,CAAA,GAAA,GAAA,UAAA,KAAA,mBAAA,IAAA,IAAA"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { n as GrTabPanels_default, t as GrTabPanel_default } from "./chunks/GrTabPanels-
|
|
1
|
+
import { n as GrTabPanels_default, t as GrTabPanel_default } from "./chunks/GrTabPanels-BZQS8-JM.js";
|
|
2
2
|
import { t as grTabPanelsConfig } from "../../chunks/config-eXB87DOi.js";
|
|
3
3
|
export { GrTabPanel_default as GrTabPanel, GrTabPanels_default as GrTabPanels, GrTabPanels_default as default, grTabPanelsConfig };
|