@feugene/granularity 0.35.0 → 0.37.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-2ZHRsdOc.js.map +1 -1
- package/dist/chunks/config-2vrOFn2f.js.map +1 -1
- package/dist/chunks/config-3bQeQvqd.js.map +1 -1
- package/dist/chunks/config-87fszqnD.js.map +1 -1
- package/dist/chunks/config-8Pcutu1j.js.map +1 -1
- package/dist/chunks/config-A-bBiotF.js.map +1 -1
- package/dist/chunks/config-B0uvcTPH.js.map +1 -1
- package/dist/chunks/config-B3J0alyY.js.map +1 -1
- package/dist/chunks/config-B5SBUa6u.js.map +1 -1
- package/dist/chunks/config-B7W9VlZ7.js.map +1 -1
- package/dist/chunks/config-BDSaD-5p.js.map +1 -1
- package/dist/chunks/config-BEO7brpO.js.map +1 -1
- package/dist/chunks/config-BNu8lFQB.js.map +1 -1
- package/dist/chunks/config-BRESvs9g.js.map +1 -1
- package/dist/chunks/config-BTmfQFwi.js.map +1 -1
- package/dist/chunks/{config-CuQmUkMw2.js → config-BUNxHnEz.js} +1 -1
- package/dist/chunks/config-BUNxHnEz.js.map +1 -0
- package/dist/chunks/config-BaWANzzB.js.map +1 -1
- package/dist/chunks/config-BcXX7S7B.js.map +1 -1
- package/dist/chunks/config-Bd7QfiGj.js.map +1 -1
- package/dist/chunks/config-BhfNgyWL.js.map +1 -1
- package/dist/chunks/config-Bjn30smH.js.map +1 -1
- package/dist/chunks/config-BlJa1Mj9.js.map +1 -1
- package/dist/chunks/config-BoUI0t-t.js.map +1 -1
- package/dist/chunks/config-BqT6PMzO.js.map +1 -1
- package/dist/chunks/config-BscVxZR3.js.map +1 -1
- package/dist/chunks/config-BuGlNPE9.js.map +1 -1
- package/dist/chunks/config-C0Ea9ePP.js.map +1 -1
- package/dist/chunks/config-C0Eu8jpG.js.map +1 -1
- package/dist/chunks/config-CDat1wXf.js.map +1 -1
- package/dist/chunks/config-CIkdsWUk.js.map +1 -1
- package/dist/chunks/config-CJzmDHfI.js.map +1 -1
- package/dist/chunks/config-CLjjjPZj.js.map +1 -1
- package/dist/chunks/config-CMNfZO7S.js.map +1 -1
- package/dist/chunks/config-CQLNjc9X.js.map +1 -0
- package/dist/chunks/config-CT4lP6S4.js.map +1 -1
- package/dist/chunks/config-CWtfxkM9.js.map +1 -1
- package/dist/chunks/config-CYthTVK2.js.map +1 -1
- package/dist/chunks/config-CZPDPJlg.js.map +1 -1
- package/dist/chunks/config-CbEbLyDE.js.map +1 -1
- package/dist/chunks/config-ChPg-BQv.js.map +1 -1
- package/dist/chunks/config-CjKpUcmy.js.map +1 -1
- package/dist/chunks/config-CjWOTgLL.js.map +1 -1
- package/dist/chunks/config-CjXjhphs.js.map +1 -1
- package/dist/chunks/config-CnYdE3HZ.js.map +1 -0
- package/dist/chunks/config-CsCUuukB.js.map +1 -1
- package/dist/chunks/config-CvbVM4ep.js.map +1 -1
- package/dist/chunks/config-D0NzGYaE.js.map +1 -1
- package/dist/chunks/config-D0W8mGFD.js.map +1 -1
- package/dist/chunks/config-D82r782v.js.map +1 -1
- package/dist/chunks/{config-mlheIMtV.js → config-DBi0GVce.js} +2 -2
- package/dist/chunks/config-DBi0GVce.js.map +1 -0
- package/dist/chunks/config-DBmdgoVf.js.map +1 -0
- package/dist/chunks/config-DCq4JySZ.js.map +1 -1
- package/dist/chunks/config-DGC00bTp.js.map +1 -1
- package/dist/chunks/config-DIDz_E5m.js.map +1 -1
- package/dist/chunks/config-DM0lsduD.js.map +1 -1
- package/dist/chunks/config-DNDgp9bB.js.map +1 -1
- package/dist/chunks/config-DOYz_SVK.js.map +1 -1
- package/dist/chunks/config-DRbojEzO.js.map +1 -1
- package/dist/chunks/config-DUNH02Fg.js.map +1 -1
- package/dist/chunks/config-DUbbGcfw.js.map +1 -1
- package/dist/chunks/config-DVCNvhIG.js.map +1 -0
- package/dist/chunks/config-DWL81-aM.js.map +1 -1
- package/dist/chunks/config-DZCUPHPU.js.map +1 -1
- package/dist/chunks/config-DeyT9dJl.js.map +1 -1
- package/dist/chunks/config-DolULhjJ.js.map +1 -1
- package/dist/chunks/config-DpAYidyY.js.map +1 -0
- package/dist/chunks/config-Droqn55j.js.map +1 -1
- package/dist/chunks/config-DwABJHEo.js.map +1 -1
- package/dist/chunks/config-E1cTyRVV.js.map +1 -1
- package/dist/chunks/config-MmPym-Z7.js.map +1 -0
- package/dist/chunks/config-QaIc_gRa.js.map +1 -1
- package/dist/chunks/config-Yy67uWHY.js.map +1 -1
- package/dist/chunks/config-Z5LeUXys.js.map +1 -1
- package/dist/chunks/config-_jbgsFpw.js.map +1 -1
- package/dist/chunks/config-eXB87DOi.js.map +1 -1
- package/dist/chunks/config-rLkc9Zn2.js.map +1 -1
- package/dist/chunks/{context-CTbuwcYs.js → context-CPMRfwVr.js} +1 -1
- package/dist/chunks/{context-CTbuwcYs.js.map → context-CPMRfwVr.js.map} +1 -1
- package/dist/chunks/{grModalStyles-EZfuEiw_.js → grModalStyles-BEkiFal_.js} +10 -1
- package/dist/chunks/grModalStyles-BEkiFal_.js.map +1 -0
- package/dist/chunks/{grRadioStyles-DGL2QLy6.js → grRadioStyles-BwRyCjQQ.js} +4 -2
- package/dist/chunks/{grRadioStyles-DGL2QLy6.js.map → grRadioStyles-BwRyCjQQ.js.map} +1 -1
- package/dist/chunks/{granular-provider-DCn6fgEs.js → granular-provider-DP2gk0oa.js} +10 -9
- package/dist/chunks/{granular-provider-DCn6fgEs.js.map → granular-provider-DP2gk0oa.js.map} +1 -1
- package/dist/chunks/{overlayStack-0CZS99Da.js → overlayStack-B_UFaFzk.js} +65 -24
- package/dist/chunks/overlayStack-B_UFaFzk.js.map +1 -0
- package/dist/chunks/{renamedProp-BwcN-SJg.js → renamedProp-Dy96tT-F.js} +1 -1
- package/dist/chunks/{renamedProp-BwcN-SJg.js.map → renamedProp-Dy96tT-F.js.map} +1 -1
- package/dist/chunks/{useModalOverlay-BnAGZpcI.js → useModalOverlay-BwX8WEcI.js} +3 -3
- package/dist/chunks/{useModalOverlay-BnAGZpcI.js.map → useModalOverlay-BwX8WEcI.js.map} +1 -1
- package/dist/chunks/{usePortalTarget-C0p-mhaM.js → usePortalTarget-BhrRgdqW.js} +1 -1
- package/dist/chunks/{usePortalTarget-C0p-mhaM.js.map → usePortalTarget-BhrRgdqW.js.map} +1 -1
- package/dist/chunks/{validation-5HhpanPP.js → validation-BDjqsuGB.js} +1 -1
- package/dist/chunks/{validation-5HhpanPP.js.map → validation-BDjqsuGB.js.map} +1 -1
- package/dist/components/GrAlert/chunks/{GrAlert-FAVf-ksH.js → GrAlert-D72y1IEh.js} +1 -1
- package/dist/components/GrAlert/chunks/{GrAlert-FAVf-ksH.js.map → GrAlert-D72y1IEh.js.map} +1 -1
- package/dist/components/GrAlert/index.js +1 -1
- package/dist/components/GrAutocomplete/chunks/{GrAutocomplete-BQsSE7sj.js → GrAutocomplete-BpmFmpKs.js} +4 -6
- package/dist/components/GrAutocomplete/chunks/{GrAutocomplete-BQsSE7sj.js.map → GrAutocomplete-BpmFmpKs.js.map} +1 -1
- package/dist/components/GrAutocomplete/index.js +1 -1
- package/dist/components/GrAvatar/chunks/{GrAvatar-CNmLmgcr.js → GrAvatar-dWEXiCJG.js} +1 -1
- package/dist/components/GrAvatar/chunks/{GrAvatar-CNmLmgcr.js.map → GrAvatar-dWEXiCJG.js.map} +1 -1
- package/dist/components/GrAvatar/index.js +1 -1
- package/dist/components/GrBadge/chunks/{GrBadge-DpUDXKbq.js → GrBadge-DBeQXEir.js} +2 -2
- package/dist/components/GrBadge/chunks/{GrBadge-DpUDXKbq.js.map → GrBadge-DBeQXEir.js.map} +1 -1
- package/dist/components/GrBadge/index.js +1 -1
- package/dist/components/GrBadgeWrap/chunks/{GrBadgeWrap-B-A3PRkE.js → GrBadgeWrap-wdfxaXiu.js} +3 -1
- package/dist/components/GrBadgeWrap/chunks/{GrBadgeWrap-B-A3PRkE.js.map → GrBadgeWrap-wdfxaXiu.js.map} +1 -1
- package/dist/components/GrBadgeWrap/index.js +1 -1
- package/dist/components/GrBottomNav/chunks/{GrBottomNav-wtFatLjB.js → GrBottomNav-nE08pVUJ.js} +1 -1
- package/dist/components/GrBottomNav/chunks/{GrBottomNav-wtFatLjB.js.map → GrBottomNav-nE08pVUJ.js.map} +1 -1
- package/dist/components/GrBottomNav/index.js +1 -1
- package/dist/components/GrBreadcrumbs/chunks/{GrBreadcrumbs-DRDNan_n.js → GrBreadcrumbs-DOpwY2EF.js} +3 -3
- package/dist/components/GrBreadcrumbs/chunks/{GrBreadcrumbs-DRDNan_n.js.map → GrBreadcrumbs-DOpwY2EF.js.map} +1 -1
- package/dist/components/GrBreadcrumbs/index.js +1 -1
- package/dist/components/GrButton/chunks/{GrButton-7GP0zObj.js → GrButton-CS4TqMtG.js} +1 -1
- package/dist/components/GrButton/chunks/{GrButton-7GP0zObj.js.map → GrButton-CS4TqMtG.js.map} +1 -1
- package/dist/components/GrButton/index.js +1 -1
- package/dist/components/GrButtonGroup/chunks/GrButtonGroup-CKyiAV8K.js.map +1 -1
- package/dist/components/GrButtonGroup/index.js +1 -1
- package/dist/components/GrCard/chunks/{GrCard-BttXz1pQ.js → GrCard-Ck5--lMF.js} +2 -2
- package/dist/components/GrCard/chunks/{GrCard-BttXz1pQ.js.map → GrCard-Ck5--lMF.js.map} +1 -1
- package/dist/components/GrCard/index.js +1 -1
- package/dist/components/GrCheckbox/chunks/{GrCheckbox-CEcHIsXM.js → GrCheckbox-Dp201frb.js} +1 -1
- package/dist/components/GrCheckbox/chunks/{GrCheckbox-CEcHIsXM.js.map → GrCheckbox-Dp201frb.js.map} +1 -1
- package/dist/components/GrCheckbox/index.js +1 -1
- package/dist/components/GrCheckboxGroup/chunks/{GrCheckboxGroup-BOwrVcFr.js → GrCheckboxGroup-IpqG5qwm.js} +2 -2
- package/dist/components/GrCheckboxGroup/chunks/{GrCheckboxGroup-BOwrVcFr.js.map → GrCheckboxGroup-IpqG5qwm.js.map} +1 -1
- package/dist/components/GrCheckboxGroup/index.js +1 -1
- package/dist/components/GrChip/chunks/{GrChip-BTivtwff.js → GrChip-CKqyzYcv.js} +10 -7
- package/dist/components/GrChip/chunks/{GrChip-BTivtwff.js.map → GrChip-CKqyzYcv.js.map} +1 -1
- package/dist/components/GrChip/index.js +1 -1
- package/dist/components/GrChipGroup/chunks/{GrChipGroup-C78Vcwos.js → GrChipGroup-dDGwnC04.js} +1 -1
- package/dist/components/GrChipGroup/chunks/{GrChipGroup-C78Vcwos.js.map → GrChipGroup-dDGwnC04.js.map} +1 -1
- package/dist/components/GrChipGroup/index.js +1 -1
- package/dist/components/GrCodeBlock/chunks/{GrCodeBlock-Dp0eEBTZ.js → GrCodeBlock-BUOwKwQE.js} +2 -2
- package/dist/components/GrCodeBlock/chunks/{GrCodeBlock-Dp0eEBTZ.js.map → GrCodeBlock-BUOwKwQE.js.map} +1 -1
- package/dist/components/GrCodeBlock/index.js +1 -1
- package/dist/components/GrCollapse/chunks/{GrCollapse-BlW6ybdL.js → GrCollapse-DWH3QAnU.js} +6 -5
- package/dist/components/GrCollapse/chunks/{GrCollapse-BlW6ybdL.js.map → GrCollapse-DWH3QAnU.js.map} +1 -1
- package/dist/components/GrCollapse/index.js +1 -1
- package/dist/components/GrColorPicker/chunks/{GrColorPicker-CIgdPXHn.js → GrColorPicker-BNtpj_P6.js} +4 -4
- package/dist/components/GrColorPicker/chunks/{GrColorPicker-CIgdPXHn.js.map → GrColorPicker-BNtpj_P6.js.map} +1 -1
- package/dist/components/GrColorPicker/index.js +1 -1
- package/dist/components/GrCommandPalette/chunks/{GrCommandPalette-BZHUKlux.js → GrCommandPalette-BVZEd4yy.js} +7 -7
- package/dist/components/GrCommandPalette/chunks/{GrCommandPalette-BZHUKlux.js.map → GrCommandPalette-BVZEd4yy.js.map} +1 -1
- package/dist/components/GrCommandPalette/index.js +1 -1
- package/dist/components/GrConfigProvider/chunks/{GrConfigProvider-BF7R3hgg.js → GrConfigProvider-t9x2UToH.js} +13 -12
- package/dist/components/GrConfigProvider/chunks/{GrConfigProvider-BF7R3hgg.js.map → GrConfigProvider-t9x2UToH.js.map} +1 -1
- package/dist/components/GrConfigProvider/index.js +2 -2
- package/dist/components/GrConfirmDialog/chunks/{GrConfirmDialog-jRDs_E6C.js → GrConfirmDialog-K5ht2cYq.js} +4 -4
- package/dist/components/GrConfirmDialog/chunks/{GrConfirmDialog-jRDs_E6C.js.map → GrConfirmDialog-K5ht2cYq.js.map} +1 -1
- package/dist/components/GrConfirmDialog/index.js +1 -1
- package/dist/components/GrContextMenu/chunks/{GrContextMenu-DlFWm0eW.js → GrContextMenu-Dd2tgMoL.js} +1 -1
- package/dist/components/GrContextMenu/chunks/{GrContextMenu-DlFWm0eW.js.map → GrContextMenu-Dd2tgMoL.js.map} +1 -1
- package/dist/components/GrContextMenu/index.js +1 -1
- package/dist/components/GrDataTable/chunks/{GrDataTable-4JAgOQ-7.js → GrDataTable-BYYG_XZA.js} +5 -5
- package/dist/components/GrDataTable/chunks/{GrDataTable-4JAgOQ-7.js.map → GrDataTable-BYYG_XZA.js.map} +1 -1
- package/dist/components/GrDataTable/index.js +1 -1
- package/dist/components/GrDelta/chunks/{GrDelta-BZwkgQW-.js → GrDelta-BpfqebEV.js} +0 -0
- package/dist/components/GrDelta/chunks/{GrDelta-BZwkgQW-.js.map → GrDelta-BpfqebEV.js.map} +1 -1
- package/dist/components/GrDelta/index.js +1 -1
- package/dist/components/GrDescriptionList/chunks/{GrDescriptionList-BMeCgFV3.js → GrDescriptionList-D8ANFpn_.js} +2 -2
- package/dist/components/GrDescriptionList/chunks/{GrDescriptionList-BMeCgFV3.js.map → GrDescriptionList-D8ANFpn_.js.map} +1 -1
- package/dist/components/GrDescriptionList/index.js +2 -2
- package/dist/components/GrDialog/chunks/{GrDialog-C01Hhk6G.js → GrDialog-CeJubnKJ.js} +3 -3
- package/dist/components/GrDialog/chunks/{GrDialog-C01Hhk6G.js.map → GrDialog-CeJubnKJ.js.map} +1 -1
- package/dist/components/GrDialog/index.js +1 -1
- package/dist/components/GrDialogService/chunks/{GrDialogService-CmsJNUmM.js → GrDialogService-BArvw1DV.js} +9 -8
- package/dist/components/GrDialogService/chunks/{GrDialogService-CmsJNUmM.js.map → GrDialogService-BArvw1DV.js.map} +1 -1
- package/dist/components/GrDialogService/index.js +1 -1
- package/dist/components/GrDivider/chunks/{GrDivider-BXavGcMX.js → GrDivider-DxA-zV25.js} +1 -1
- package/dist/components/GrDivider/chunks/{GrDivider-BXavGcMX.js.map → GrDivider-DxA-zV25.js.map} +1 -1
- package/dist/components/GrDivider/index.js +1 -1
- package/dist/components/GrDrawer/chunks/{GrDrawer-xfoy-MCj.js → GrDrawer-BBHNgeH0.js} +5 -5
- package/dist/components/GrDrawer/chunks/{GrDrawer-xfoy-MCj.js.map → GrDrawer-BBHNgeH0.js.map} +1 -1
- package/dist/components/GrDrawer/index.js +1 -1
- package/dist/components/GrDropdown/chunks/{GrDropdown-7r772-Cq.js → GrDropdown-CUlviqMi.js} +6 -8
- package/dist/components/GrDropdown/chunks/{GrDropdown-7r772-Cq.js.map → GrDropdown-CUlviqMi.js.map} +1 -1
- package/dist/components/GrDropdown/index.js +1 -1
- package/dist/components/GrDropdownMenu/chunks/{GrDropdownMenu-DNurbsWc.js → GrDropdownMenu-COOR1LCs.js} +1 -1
- package/dist/components/GrDropdownMenu/chunks/{GrDropdownMenu-DNurbsWc.js.map → GrDropdownMenu-COOR1LCs.js.map} +1 -1
- package/dist/components/GrDropdownMenu/chunks/GrDropdownMenuList-B33ZzwfB.js.map +1 -1
- package/dist/components/GrDropdownMenu/index.js +1 -1
- package/dist/components/GrEmptyState/chunks/{GrEmptyState-RqsWvgI9.js → GrEmptyState-BbvwE-E0.js} +2 -2
- package/dist/components/GrEmptyState/chunks/{GrEmptyState-RqsWvgI9.js.map → GrEmptyState-BbvwE-E0.js.map} +1 -1
- package/dist/components/GrEmptyState/index.js +1 -1
- package/dist/components/GrFilePreview/chunks/{GrFilePreview-C9Z7hMK8.js → GrFilePreview-PabkLgYX.js} +1 -1
- package/dist/components/GrFilePreview/chunks/{GrFilePreview-C9Z7hMK8.js.map → GrFilePreview-PabkLgYX.js.map} +1 -1
- package/dist/components/GrFilePreview/index.js +1 -1
- package/dist/components/GrFileUpload/chunks/{GrFileUpload-LL8RZvC0.js → GrFileUpload-BwMR71zN.js} +4 -4
- package/dist/components/GrFileUpload/chunks/{GrFileUpload-LL8RZvC0.js.map → GrFileUpload-BwMR71zN.js.map} +1 -1
- package/dist/components/GrFileUpload/index.js +1 -1
- package/dist/components/GrForm/chunks/{GrForm-CrnfCsgj.js → GrForm-xTtavR-K.js} +1 -1
- package/dist/components/GrForm/chunks/{GrForm-CrnfCsgj.js.map → GrForm-xTtavR-K.js.map} +1 -1
- package/dist/components/GrForm/index.js +2 -2
- package/dist/components/GrFormField/chunks/{GrFormField-DSylU7IU.js → GrFormField-DO61vxpS.js} +2 -2
- package/dist/components/GrFormField/chunks/{GrFormField-DSylU7IU.js.map → GrFormField-DO61vxpS.js.map} +1 -1
- package/dist/components/GrFormField/index.js +1 -1
- package/dist/components/GrFormFile/chunks/{GrFormFile-B1jGZyIj.js → GrFormFile-Dlxx-9zi.js} +3 -3
- package/dist/components/GrFormFile/chunks/{GrFormFile-B1jGZyIj.js.map → GrFormFile-Dlxx-9zi.js.map} +1 -1
- package/dist/components/GrFormFile/index.js +1 -1
- package/dist/components/GrFormSection/chunks/{GrFormSection-ejieOg9H.js → GrFormSection-DV1S6R_N.js} +1 -1
- package/dist/components/GrFormSection/chunks/{GrFormSection-ejieOg9H.js.map → GrFormSection-DV1S6R_N.js.map} +1 -1
- package/dist/components/GrFormSection/index.js +1 -1
- package/dist/components/GrIcon/chunks/{GrIcon-Dmf0c9ba.js → GrIcon-DTZIgmje.js} +1 -1
- package/dist/components/GrIcon/chunks/{GrIcon-Dmf0c9ba.js.map → GrIcon-DTZIgmje.js.map} +1 -1
- package/dist/components/GrIcon/index.js +1 -1
- package/dist/components/GrImageViewer/chunks/{GrImageViewer--BU8yrfx.js → GrImageViewer-BjYw-uTF.js} +2 -4
- package/dist/components/GrImageViewer/chunks/{GrImageViewer--BU8yrfx.js.map → GrImageViewer-BjYw-uTF.js.map} +1 -1
- package/dist/components/GrImageViewer/index.js +1 -1
- package/dist/components/GrInput/chunks/{GrInput-BLywRZUN.js → GrInput-TFeBm3gQ.js} +2 -1
- package/dist/components/GrInput/chunks/{GrInput-BLywRZUN.js.map → GrInput-TFeBm3gQ.js.map} +1 -1
- package/dist/components/GrInput/index.js +1 -1
- package/dist/components/GrInputTag/chunks/{GrInputTag-ByD9NugQ.js → GrInputTag-DhfUNOA5.js} +3 -3
- package/dist/components/GrInputTag/chunks/{GrInputTag-ByD9NugQ.js.map → GrInputTag-DhfUNOA5.js.map} +1 -1
- package/dist/components/GrInputTag/index.js +1 -1
- package/dist/components/GrJsonViewer/chunks/{GrJsonViewer-BCZ7lE2k.js → GrJsonViewer-CdtmUpZ3.js} +6 -6
- package/dist/components/GrJsonViewer/chunks/{GrJsonViewer-BCZ7lE2k.js.map → GrJsonViewer-CdtmUpZ3.js.map} +1 -1
- package/dist/components/GrJsonViewer/index.js +2 -2
- package/dist/components/GrKbd/chunks/{GrKbd-D2ga1H9i.js → GrKbd-D_a1mPLe.js} +1 -1
- package/dist/components/GrKbd/chunks/{GrKbd-D2ga1H9i.js.map → GrKbd-D_a1mPLe.js.map} +1 -1
- package/dist/components/GrKbd/index.js +1 -1
- package/dist/components/GrLink/chunks/{GrLink-DYXw3W9w.js → GrLink-DwWErumU.js} +2 -2
- package/dist/components/GrLink/chunks/{GrLink-DYXw3W9w.js.map → GrLink-DwWErumU.js.map} +1 -1
- package/dist/components/GrLink/index.js +2 -2
- package/dist/components/GrList/chunks/{GrList-B_CRJB4c.js → GrList-Unya-LXb.js} +3 -3
- package/dist/components/GrList/chunks/{GrList-B_CRJB4c.js.map → GrList-Unya-LXb.js.map} +1 -1
- package/dist/components/GrList/index.js +1 -1
- package/dist/components/GrLoading/chunks/{GrLoading-CMD3Ri9P.js → GrLoading-BDrlrup_.js} +1 -1
- package/dist/components/GrLoading/chunks/{GrLoading-CMD3Ri9P.js.map → GrLoading-BDrlrup_.js.map} +1 -1
- package/dist/components/GrLoading/index.js +1 -1
- package/dist/components/GrModal/chunks/{GrModal-_JrDhon-.js → GrModal-xIWaJozo.js} +7 -6
- package/dist/components/GrModal/chunks/GrModal-xIWaJozo.js.map +1 -0
- package/dist/components/GrModal/index.js +2 -2
- package/dist/components/GrNavbar/chunks/{GrNavbar-Dr8e5kW-.js → GrNavbar-BRGuksiy.js} +3 -3
- package/dist/components/GrNavbar/chunks/{GrNavbar-Dr8e5kW-.js.map → GrNavbar-BRGuksiy.js.map} +1 -1
- package/dist/components/GrNavbar/index.js +1 -1
- package/dist/components/GrNumberInput/chunks/{GrNumberInput-DQ59YICu.js → GrNumberInput-BqPydXpK.js} +7 -9
- package/dist/components/GrNumberInput/chunks/{GrNumberInput-DQ59YICu.js.map → GrNumberInput-BqPydXpK.js.map} +1 -1
- package/dist/components/GrNumberInput/index.js +2 -2
- package/dist/components/GrPagination/chunks/{GrPagination-gBoWVHk6.js → GrPagination-DhbNZHEF.js} +26 -11
- package/dist/components/GrPagination/chunks/GrPagination-DhbNZHEF.js.map +1 -0
- package/dist/components/GrPagination/index.js +1 -1
- package/dist/components/GrPopover/chunks/{GrPopover-DEFxDffj.js → GrPopover-BakLcWkX.js} +3 -3
- package/dist/components/GrPopover/chunks/{GrPopover-DEFxDffj.js.map → GrPopover-BakLcWkX.js.map} +1 -1
- package/dist/components/GrPopover/index.js +2 -2
- package/dist/components/GrProgressBar/chunks/{GrProgressBar-hszUOC8f.js → GrProgressBar-C3NRBqIP.js} +6 -3
- package/dist/components/GrProgressBar/chunks/GrProgressBar-C3NRBqIP.js.map +1 -0
- package/dist/components/GrProgressBar/index.js +1 -1
- package/dist/components/GrProgressCircle/chunks/{GrProgressCircle-D3yWXYDa.js → GrProgressCircle-CdvbINQc.js} +2 -2
- package/dist/components/GrProgressCircle/chunks/{GrProgressCircle-D3yWXYDa.js.map → GrProgressCircle-CdvbINQc.js.map} +1 -1
- package/dist/components/GrProgressCircle/index.js +1 -1
- package/dist/components/GrPromptDialog/chunks/{GrPromptDialog-CailXSqW.js → GrPromptDialog-C9Y1ifE_.js} +8 -8
- package/dist/components/GrPromptDialog/chunks/{GrPromptDialog-CailXSqW.js.map → GrPromptDialog-C9Y1ifE_.js.map} +1 -1
- package/dist/components/GrPromptDialog/index.js +1 -1
- package/dist/components/GrRadio/chunks/{GrRadio-Aq3v8XgG.js → GrRadio-B1776V9D.js} +2 -2
- package/dist/components/GrRadio/chunks/{GrRadio-Aq3v8XgG.js.map → GrRadio-B1776V9D.js.map} +1 -1
- package/dist/components/GrRadio/index.js +2 -2
- package/dist/components/GrRadioGroup/chunks/{GrRadioGroup-y9LVdTWh.js → GrRadioGroup-UgitrBFl.js} +2 -2
- package/dist/components/GrRadioGroup/chunks/{GrRadioGroup-y9LVdTWh.js.map → GrRadioGroup-UgitrBFl.js.map} +1 -1
- package/dist/components/GrRadioGroup/index.js +1 -1
- package/dist/components/GrRating/chunks/{GrRating-IEiTOdnF.js → GrRating-DTriyyqG.js} +1 -1
- package/dist/components/GrRating/chunks/{GrRating-IEiTOdnF.js.map → GrRating-DTriyyqG.js.map} +1 -1
- package/dist/components/GrRating/index.js +1 -1
- package/dist/components/GrResponseErrorBanner/chunks/{GrResponseErrorBanner-DMeOWlzj.js → GrResponseErrorBanner-NEEJZ8zi.js} +2 -2
- package/dist/components/GrResponseErrorBanner/chunks/{GrResponseErrorBanner-DMeOWlzj.js.map → GrResponseErrorBanner-NEEJZ8zi.js.map} +1 -1
- package/dist/components/GrResponseErrorBanner/chunks/{GrResponseErrorBanner-CBVRpgIG.js → GrResponseErrorBanner-ZvBvEQDZ.js} +1 -1
- package/dist/components/GrResponseErrorBanner/chunks/{GrResponseErrorBanner-CBVRpgIG.js.map → GrResponseErrorBanner-ZvBvEQDZ.js.map} +1 -1
- package/dist/components/GrResponseErrorBanner/index.js +2 -2
- package/dist/components/GrSegmented/chunks/{GrSegmented-CB-VR-yL.js → GrSegmented-NKTi9bMG.js} +1 -1
- package/dist/components/GrSegmented/chunks/{GrSegmented-CB-VR-yL.js.map → GrSegmented-NKTi9bMG.js.map} +1 -1
- package/dist/components/GrSegmented/index.js +1 -1
- package/dist/components/GrSelect/chunks/{GrSelect-CZqV1Eg4.js → GrSelect-Do1iAyp1.js} +8 -12
- package/dist/components/GrSelect/chunks/GrSelect-Do1iAyp1.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-alkwBUzL.js → GrSidebar-DoKLlHSw.js} +2 -2
- package/dist/components/GrSidebar/chunks/{GrSidebar-alkwBUzL.js.map → GrSidebar-DoKLlHSw.js.map} +1 -1
- package/dist/components/GrSidebar/index.js +1 -1
- package/dist/components/GrSkeleton/chunks/GrSkeleton-CgfXxPQ2.js.map +1 -1
- package/dist/components/GrSlider/chunks/{GrSlider-DTTrZTHK.js → GrSlider-Db-jACXz.js} +14 -6
- package/dist/components/GrSlider/chunks/GrSlider-Db-jACXz.js.map +1 -0
- package/dist/components/GrSlider/index.js +1 -1
- package/dist/components/GrSortableList/chunks/{GrSortableList-HyKX--rO.js → GrSortableList-CQCaWivn.js} +1 -1
- package/dist/components/GrSortableList/chunks/{GrSortableList-HyKX--rO.js.map → GrSortableList-CQCaWivn.js.map} +1 -1
- package/dist/components/GrSortableList/index.js +1 -1
- package/dist/components/GrSplitter/chunks/{GrSplitter-MltjaADn.js → GrSplitter-C-XQzq7q.js} +1 -1
- package/dist/components/GrSplitter/chunks/{GrSplitter-MltjaADn.js.map → GrSplitter-C-XQzq7q.js.map} +1 -1
- package/dist/components/GrSplitter/index.js +1 -1
- package/dist/components/GrStatistic/chunks/{GrStatistic-qHVasK37.js → GrStatistic-C1_nY4Gc.js} +8 -4
- package/dist/components/GrStatistic/chunks/GrStatistic-C1_nY4Gc.js.map +1 -0
- package/dist/components/GrStatistic/index.js +1 -1
- package/dist/components/GrSteps/chunks/{GrSteps-C2jxpZoN.js → GrSteps-DXj7m-WO.js} +2 -2
- package/dist/components/GrSteps/chunks/{GrSteps-C2jxpZoN.js.map → GrSteps-DXj7m-WO.js.map} +1 -1
- package/dist/components/GrSteps/index.js +1 -1
- package/dist/components/GrSwitch/chunks/{GrSwitch-7Oe5QfQZ.js → GrSwitch-CriHWT2A.js} +1 -1
- package/dist/components/GrSwitch/chunks/{GrSwitch-7Oe5QfQZ.js.map → GrSwitch-CriHWT2A.js.map} +1 -1
- package/dist/components/GrSwitch/index.js +1 -1
- package/dist/components/GrTabPanels/chunks/{GrTabPanels-BZQS8-JM.js → GrTabPanels-5zsbqS1v.js} +1 -1
- package/dist/components/GrTabPanels/chunks/{GrTabPanels-BZQS8-JM.js.map → GrTabPanels-5zsbqS1v.js.map} +1 -1
- package/dist/components/GrTabPanels/index.js +1 -1
- package/dist/components/GrTable/chunks/{GrTable-jhUTczjv.js → GrTable-iwzHvlMC.js} +1 -1
- package/dist/components/GrTable/chunks/{GrTable-jhUTczjv.js.map → GrTable-iwzHvlMC.js.map} +1 -1
- package/dist/components/GrTable/index.js +1 -1
- package/dist/components/GrTabs/chunks/{GrTabs-CT2nk_HV.js → GrTabs-DHfv67cp.js} +1 -1
- package/dist/components/GrTabs/chunks/{GrTabs-CT2nk_HV.js.map → GrTabs-DHfv67cp.js.map} +1 -1
- package/dist/components/GrTabs/index.js +1 -1
- package/dist/components/GrTextarea/chunks/{GrTextarea-DinXG12-.js → GrTextarea-BII3w61K.js} +1 -1
- package/dist/components/GrTextarea/chunks/{GrTextarea-DinXG12-.js.map → GrTextarea-BII3w61K.js.map} +1 -1
- package/dist/components/GrTextarea/index.js +1 -1
- package/dist/components/GrTimeline/chunks/{GrTimeline-BiHpArsg.js → GrTimeline-Bs60huw0.js} +2 -2
- package/dist/components/GrTimeline/chunks/{GrTimeline-BiHpArsg.js.map → GrTimeline-Bs60huw0.js.map} +1 -1
- package/dist/components/GrTimeline/index.js +1 -1
- package/dist/components/GrToaster/chunks/{GrToaster-COXIBKzq.js → GrToaster-D-sV-9of.js} +4 -4
- package/dist/components/GrToaster/chunks/{GrToaster-COXIBKzq.js.map → GrToaster-D-sV-9of.js.map} +1 -1
- package/dist/components/GrToaster/index.js +1 -1
- package/dist/components/GrTooltip/chunks/{GrTooltip-uYETdbCD.js → GrTooltip-BUiTbROv.js} +3 -3
- package/dist/components/GrTooltip/chunks/{GrTooltip-uYETdbCD.js.map → GrTooltip-BUiTbROv.js.map} +1 -1
- package/dist/components/GrTooltip/index.js +1 -1
- package/dist/components/GrTree/chunks/{GrTree-Ci6CZfKR.js → GrTree-CkELQwR8.js} +1 -2
- package/dist/components/GrTree/chunks/{GrTree-Ci6CZfKR.js.map → GrTree-CkELQwR8.js.map} +1 -1
- package/dist/components/GrTree/index.js +1 -1
- package/dist/components/GrTreeSelect/chunks/{GrTreeSelect-DOXcpWq2.js → GrTreeSelect-DurwZ7Cz.js} +4 -4
- package/dist/components/GrTreeSelect/chunks/{GrTreeSelect-DOXcpWq2.js.map → GrTreeSelect-DurwZ7Cz.js.map} +1 -1
- package/dist/components/GrTreeSelect/index.js +1 -1
- package/dist/components/GrValue/chunks/GrValue-ezkQM05Q.js.map +1 -1
- package/dist/composables/useFloating.js +1 -1
- package/dist/composables/useGrComponentConfig.js +1 -1
- package/dist/composables/useOverlayLayer.js +1 -1
- package/dist/composables/usePortalTarget.js +1 -1
- package/dist/composables/useTheme.js +1 -1
- package/dist/composables/useTheme.js.map +1 -1
- package/dist/composables/useToast.js +1 -1
- package/dist/composables/useToast.js.map +1 -1
- package/dist/composables/useVirtualList.js +3 -5
- package/dist/composables/useVirtualList.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/index.js +87 -87
- package/dist/testing.js +1 -1
- package/dist/testing.js.map +1 -1
- package/dist/types/components/GrDialog/GrDialog.vue.d.ts +1 -1
- package/dist/types/components/GrDrawer/GrDrawer.vue.d.ts +1 -1
- package/dist/types/components/GrModal/GrModal.vue.d.ts +1 -1
- package/dist/types/components/GrModal/grModalStyles.d.ts +9 -0
- package/dist/types/components/GrProgressBar/GrProgressBar.vue.d.ts +1 -1
- package/dist/types/internal/devHook.d.ts +53 -0
- package/dist/vue/index.js +2 -2
- package/dist/vue/index.js.map +1 -1
- package/dist/web-types.json +2 -2
- package/package.json +17 -17
- package/dist/chunks/config-CQLNjc9X2.js.map +0 -1
- package/dist/chunks/config-CnYdE3HZ2.js.map +0 -1
- package/dist/chunks/config-CuQmUkMw2.js.map +0 -1
- package/dist/chunks/config-DBmdgoVf2.js.map +0 -1
- package/dist/chunks/config-DVCNvhIG2.js.map +0 -1
- package/dist/chunks/config-DpAYidyY2.js.map +0 -1
- package/dist/chunks/config-MmPym-Z72.js.map +0 -1
- package/dist/chunks/config-mlheIMtV.js.map +0 -1
- package/dist/chunks/grModalStyles-EZfuEiw_.js.map +0 -1
- package/dist/chunks/overlayStack-0CZS99Da.js.map +0 -1
- package/dist/components/GrModal/chunks/GrModal-_JrDhon-.js.map +0 -1
- package/dist/components/GrPagination/chunks/GrPagination-gBoWVHk6.js.map +0 -1
- package/dist/components/GrProgressBar/chunks/GrProgressBar-hszUOC8f.js.map +0 -1
- package/dist/components/GrSelect/chunks/GrSelect-CZqV1Eg4.js.map +0 -1
- package/dist/components/GrSlider/chunks/GrSlider-DTTrZTHK.js.map +0 -1
- package/dist/components/GrStatistic/chunks/GrStatistic-qHVasK37.js.map +0 -1
- /package/dist/chunks/{config-CQLNjc9X2.js → config-CQLNjc9X.js} +0 -0
- /package/dist/chunks/{config-CnYdE3HZ2.js → config-CnYdE3HZ.js} +0 -0
- /package/dist/chunks/{config-DBmdgoVf2.js → config-DBmdgoVf.js} +0 -0
- /package/dist/chunks/{config-DVCNvhIG2.js → config-DVCNvhIG.js} +0 -0
- /package/dist/chunks/{config-DpAYidyY2.js → config-DpAYidyY.js} +0 -0
- /package/dist/chunks/{config-MmPym-Z72.js → config-MmPym-Z7.js} +0 -0
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { n as grAutocompleteSafelist, t as grAutocompleteConfig } from "../../chunks/config-CYthTVK2.js";
|
|
2
|
-
import { t as GrAutocomplete_default } from "./chunks/GrAutocomplete-
|
|
2
|
+
import { t as GrAutocomplete_default } from "./chunks/GrAutocomplete-BpmFmpKs.js";
|
|
3
3
|
export { GrAutocomplete_default as GrAutocomplete, GrAutocomplete_default as default, grAutocompleteConfig, grAutocompleteSafelist };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as useGrComponentSize, i as useGrComponentProp } from "../../../chunks/context-
|
|
1
|
+
import { a as useGrComponentSize, i as useGrComponentProp } from "../../../chunks/context-CPMRfwVr.js";
|
|
2
2
|
import { n as useGranularityTranslations } from "../../../chunks/granularityI18n-BC5zsj_d.js";
|
|
3
3
|
import { t as GrSkeleton_default } from "../../GrSkeleton/chunks/GrSkeleton-CgfXxPQ2.js";
|
|
4
4
|
import { a as groupBaseClass, c as initialsFrom, d as rootBaseClass, f as rootStatusClass, i as grAvatarClass, l as mediaClass, m as statusToneClass, o as groupItemClass, p as statusDotClass, r as avatarFontSizePx, s as groupOverflowClass, u as mediaClipClass } from "../../../chunks/config-B3J0alyY.js";
|
package/dist/components/GrAvatar/chunks/{GrAvatar-CNmLmgcr.js.map → GrAvatar-dWEXiCJG.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GrAvatar-CNmLmgcr.js","names":[],"sources":["../../../../src/components/GrAvatar/avatarContext.ts","../../../../src/components/GrAvatar/GrAvatar.vue","../../../../src/components/GrAvatar/GrAvatar.vue","../../../../src/components/GrAvatar/GrAvatarGroup.vue","../../../../src/components/GrAvatar/GrAvatarGroup.vue"],"sourcesContent":["import type { InjectionKey } from 'vue'\n\nimport type { GrAvatarShape } from './grAvatarStyles'\nimport type { GrSizeWithPx } from '../shared/sizes'\n\n/**\n * Контекст `GrAvatarGroup`: размер и форма задаются на группе, чтобы ряд\n * аватаров не расползался, когда потребитель забыл повторить пропы у каждого.\n */\nexport interface GrAvatarGroupContext {\n size?: GrSizeWithPx\n shape?: GrAvatarShape\n}\n\nexport const GR_AVATAR_GROUP_KEY: InjectionKey<GrAvatarGroupContext> = Symbol.for('@feugene/granularity/avatar-group')\n","<script setup lang=\"ts\">\nimport { computed, inject, ref, watch } from 'vue'\n\nimport GrSkeleton from '../GrSkeleton/GrSkeleton.vue'\nimport { useGrComponentProp, useGrComponentSize } from '../GrConfigProvider/context'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport type { GrSizeWithPx } from '../shared/sizes'\n\nimport { GR_AVATAR_GROUP_KEY } from './avatarContext'\nimport {\n avatarFontSizePx,\n grAvatarClass,\n initialsFrom,\n mediaClass,\n mediaClipClass,\n rootBaseClass,\n rootStatusClass,\n statusDotClass,\n statusToneClass,\n type GrAvatarShape,\n type GrAvatarStatus,\n} from './grAvatarStyles'\n\nexport type { GrAvatarShape, GrAvatarStatus } from './grAvatarStyles'\n\n/** Диаметр аватара для каждой ступени канонической шкалы. */\nconst GR_AVATAR_SIZE_PX = {\n xs: 24,\n sm: 32,\n md: 40,\n lg: 56,\n} as const\n\nexport interface GrAvatarProps {\n /**\n * Размер по канонической шкале (`xs|sm|md|lg`) — тогда работает\n * `GrConfigProvider`. Число — escape-hatch: аватар нужен произвольного\n * диаметра (24px в строке списка, 96px в профиле), и четыре ступени шкалы\n * этого не закрывают.\n */\n size?: GrSizeWithPx\n src?: string\n /** Резервная картинка: показывается, когда `src` не загрузился. */\n fallbackSrc?: string\n alt?: string\n /** Имя участника: даёт инициалы и доступное имя аватара. */\n name?: string\n shape?: GrAvatarShape\n /** Статус участника. Точка декоративна — рядом идёт скрытая подпись. */\n status?: GrAvatarStatus\n}\n\nconst props = withDefaults(defineProps<GrAvatarProps>(), {\n size: undefined,\n src: undefined,\n fallbackSrc: undefined,\n alt: undefined,\n name: undefined,\n // Дефолт живёт в резолвере: Vue подставил бы свой раньше, чем компонент\n // заглянет в `GrConfigProvider`.\n shape: undefined,\n status: undefined,\n})\n\nconst slots = defineSlots<{\n /** Содержимое вместо картинки и инициалов. */\n default?: () => unknown\n}>()\n\nconst { t } = useGranularityTranslations()\nconst group = inject(GR_AVATAR_GROUP_KEY, null)\n\n// Размер и форма группы сильнее провайдера, но слабее собственного пропа.\nconst localSize = computed(() => props.size ?? group?.size)\n\nconst resolvedScaleSize = useGrComponentSize(\n () => (typeof localSize.value === 'number' ? undefined : localSize.value),\n { component: 'GrAvatar' },\n)\n\nconst resolvedShape = useGrComponentProp(\n 'GrAvatar',\n 'shape',\n () => props.shape ?? group?.shape,\n 'circle',\n)\n\nconst sizePx = computed(() => (\n typeof localSize.value === 'number' ? localSize.value : GR_AVATAR_SIZE_PX[resolvedScaleSize.value]\n))\n\nconst style = computed(() => {\n const px = `${sizePx.value}px`\n // Кегль на корне, а не на span инициалов: так он достаётся и слотовому тексту.\n return { width: px, height: px, fontSize: `${avatarFontSizePx(sizePx.value)}px` }\n})\n\n/**\n * Состояние картинки. Без него битая ссылка оставляла `v-if=\"src\"` истинным:\n * браузер рисовал сломанное изображение, а запасной вариант не показывался\n * никогда.\n */\ntype ImageState = 'loading' | 'loaded' | 'error'\n\nconst primaryState = ref<ImageState>('loading')\nconst fallbackState = ref<ImageState>('loading')\n\n// Новая ссылка не должна наследовать ошибку прошлой.\nwatch(() => props.src, () => {\n primaryState.value = 'loading'\n})\nwatch(() => props.fallbackSrc, () => {\n fallbackState.value = 'loading'\n})\n\nconst activeSrc = computed(() => {\n if (props.src && primaryState.value !== 'error')\n return props.src\n if (props.fallbackSrc && fallbackState.value !== 'error')\n return props.fallbackSrc\n return undefined\n})\n\nconst isFallbackActive = computed(() => Boolean(activeSrc.value) && activeSrc.value !== props.src)\n\n// Скелет держит место, пока картинка едет: иначе ряд аватаров мигает пустотой.\nconst showSkeleton = computed(() => {\n if (!activeSrc.value)\n return false\n return (isFallbackActive.value ? fallbackState.value : primaryState.value) === 'loading'\n})\n\nconst initials = computed(() => (props.name ? initialsFrom(props.name) : ''))\n\n// Пусто — когда нет ни картинки, ни слота, ни имени.\nconst showInitials = computed(() => !activeSrc.value && !slots.default && Boolean(initials.value))\n\nconst statusLabel = computed(() => (props.status\n ? t(`gr.avatar.status.${props.status}`, props.status)\n : undefined))\n\n/**\n * Доступное имя: `alt` сильнее всего, иначе имя участника.\n *\n * Когда есть картинка, имя несёт её `alt` — так привычнее потребителю и не\n * возникает двойного объявления. Без картинки роль и имя берёт на себя корень:\n * иначе аватар с инициалами остался бы для диктора пустым.\n */\nconst accessibleName = computed(() => props.alt ?? props.name ?? '')\n\nconst rootIsImage = computed(() => !activeSrc.value && accessibleName.value !== '')\n\nconst rootClass = computed(() => [\n rootBaseClass,\n grAvatarClass(resolvedShape.value),\n props.status ? rootStatusClass : '',\n])\n\nfunction onError(kind: 'primary' | 'fallback'): void {\n if (kind === 'primary')\n primaryState.value = 'error'\n else fallbackState.value = 'error'\n}\n\nfunction onLoad(kind: 'primary' | 'fallback'): void {\n if (kind === 'primary')\n primaryState.value = 'loaded'\n else fallbackState.value = 'loaded'\n}\n</script>\n\n<template>\n <span\n data-gr-avatar\n :style=\"style\"\n :class=\"rootClass\"\n :role=\"rootIsImage ? 'img' : undefined\"\n :aria-label=\"rootIsImage ? accessibleName : undefined\"\n >\n <span :class=\"[mediaClass, status ? [mediaClipClass, grAvatarClass(resolvedShape)] : '']\">\n <GrSkeleton\n v-if=\"showSkeleton\"\n data-gr-avatar-skeleton\n width=\"100%\"\n height=\"100%\"\n :rounded=\"resolvedShape === 'circle' ? 'var(--gr-radius-full)' : 'var(--gr-avatar-square-radius, 10px)'\"\n />\n\n <img\n v-if=\"activeSrc\"\n :key=\"activeSrc\"\n data-gr-avatar-image\n :src=\"activeSrc\"\n :alt=\"accessibleName\"\n class=\"h-full w-full object-cover\"\n :class=\"showSkeleton ? 'invisible absolute' : ''\"\n @error=\"onError(isFallbackActive ? 'fallback' : 'primary')\"\n @load=\"onLoad(isFallbackActive ? 'fallback' : 'primary')\"\n >\n\n <span v-else-if=\"showInitials\" data-gr-avatar-initials>{{ initials }}</span>\n\n <slot v-else />\n </span>\n\n <template v-if=\"status\">\n <span\n data-gr-avatar-status\n :class=\"[statusDotClass, statusToneClass[status]]\"\n aria-hidden=\"true\"\n />\n <!-- Цвет точки смысл не передаёт: статус объявляется словом (WCAG 1.4.1). -->\n <span data-gr-avatar-status-label class=\"sr-only\">{{ statusLabel }}</span>\n </template>\n </span>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, inject, ref, watch } from 'vue'\n\nimport GrSkeleton from '../GrSkeleton/GrSkeleton.vue'\nimport { useGrComponentProp, useGrComponentSize } from '../GrConfigProvider/context'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport type { GrSizeWithPx } from '../shared/sizes'\n\nimport { GR_AVATAR_GROUP_KEY } from './avatarContext'\nimport {\n avatarFontSizePx,\n grAvatarClass,\n initialsFrom,\n mediaClass,\n mediaClipClass,\n rootBaseClass,\n rootStatusClass,\n statusDotClass,\n statusToneClass,\n type GrAvatarShape,\n type GrAvatarStatus,\n} from './grAvatarStyles'\n\nexport type { GrAvatarShape, GrAvatarStatus } from './grAvatarStyles'\n\n/** Диаметр аватара для каждой ступени канонической шкалы. */\nconst GR_AVATAR_SIZE_PX = {\n xs: 24,\n sm: 32,\n md: 40,\n lg: 56,\n} as const\n\nexport interface GrAvatarProps {\n /**\n * Размер по канонической шкале (`xs|sm|md|lg`) — тогда работает\n * `GrConfigProvider`. Число — escape-hatch: аватар нужен произвольного\n * диаметра (24px в строке списка, 96px в профиле), и четыре ступени шкалы\n * этого не закрывают.\n */\n size?: GrSizeWithPx\n src?: string\n /** Резервная картинка: показывается, когда `src` не загрузился. */\n fallbackSrc?: string\n alt?: string\n /** Имя участника: даёт инициалы и доступное имя аватара. */\n name?: string\n shape?: GrAvatarShape\n /** Статус участника. Точка декоративна — рядом идёт скрытая подпись. */\n status?: GrAvatarStatus\n}\n\nconst props = withDefaults(defineProps<GrAvatarProps>(), {\n size: undefined,\n src: undefined,\n fallbackSrc: undefined,\n alt: undefined,\n name: undefined,\n // Дефолт живёт в резолвере: Vue подставил бы свой раньше, чем компонент\n // заглянет в `GrConfigProvider`.\n shape: undefined,\n status: undefined,\n})\n\nconst slots = defineSlots<{\n /** Содержимое вместо картинки и инициалов. */\n default?: () => unknown\n}>()\n\nconst { t } = useGranularityTranslations()\nconst group = inject(GR_AVATAR_GROUP_KEY, null)\n\n// Размер и форма группы сильнее провайдера, но слабее собственного пропа.\nconst localSize = computed(() => props.size ?? group?.size)\n\nconst resolvedScaleSize = useGrComponentSize(\n () => (typeof localSize.value === 'number' ? undefined : localSize.value),\n { component: 'GrAvatar' },\n)\n\nconst resolvedShape = useGrComponentProp(\n 'GrAvatar',\n 'shape',\n () => props.shape ?? group?.shape,\n 'circle',\n)\n\nconst sizePx = computed(() => (\n typeof localSize.value === 'number' ? localSize.value : GR_AVATAR_SIZE_PX[resolvedScaleSize.value]\n))\n\nconst style = computed(() => {\n const px = `${sizePx.value}px`\n // Кегль на корне, а не на span инициалов: так он достаётся и слотовому тексту.\n return { width: px, height: px, fontSize: `${avatarFontSizePx(sizePx.value)}px` }\n})\n\n/**\n * Состояние картинки. Без него битая ссылка оставляла `v-if=\"src\"` истинным:\n * браузер рисовал сломанное изображение, а запасной вариант не показывался\n * никогда.\n */\ntype ImageState = 'loading' | 'loaded' | 'error'\n\nconst primaryState = ref<ImageState>('loading')\nconst fallbackState = ref<ImageState>('loading')\n\n// Новая ссылка не должна наследовать ошибку прошлой.\nwatch(() => props.src, () => {\n primaryState.value = 'loading'\n})\nwatch(() => props.fallbackSrc, () => {\n fallbackState.value = 'loading'\n})\n\nconst activeSrc = computed(() => {\n if (props.src && primaryState.value !== 'error')\n return props.src\n if (props.fallbackSrc && fallbackState.value !== 'error')\n return props.fallbackSrc\n return undefined\n})\n\nconst isFallbackActive = computed(() => Boolean(activeSrc.value) && activeSrc.value !== props.src)\n\n// Скелет держит место, пока картинка едет: иначе ряд аватаров мигает пустотой.\nconst showSkeleton = computed(() => {\n if (!activeSrc.value)\n return false\n return (isFallbackActive.value ? fallbackState.value : primaryState.value) === 'loading'\n})\n\nconst initials = computed(() => (props.name ? initialsFrom(props.name) : ''))\n\n// Пусто — когда нет ни картинки, ни слота, ни имени.\nconst showInitials = computed(() => !activeSrc.value && !slots.default && Boolean(initials.value))\n\nconst statusLabel = computed(() => (props.status\n ? t(`gr.avatar.status.${props.status}`, props.status)\n : undefined))\n\n/**\n * Доступное имя: `alt` сильнее всего, иначе имя участника.\n *\n * Когда есть картинка, имя несёт её `alt` — так привычнее потребителю и не\n * возникает двойного объявления. Без картинки роль и имя берёт на себя корень:\n * иначе аватар с инициалами остался бы для диктора пустым.\n */\nconst accessibleName = computed(() => props.alt ?? props.name ?? '')\n\nconst rootIsImage = computed(() => !activeSrc.value && accessibleName.value !== '')\n\nconst rootClass = computed(() => [\n rootBaseClass,\n grAvatarClass(resolvedShape.value),\n props.status ? rootStatusClass : '',\n])\n\nfunction onError(kind: 'primary' | 'fallback'): void {\n if (kind === 'primary')\n primaryState.value = 'error'\n else fallbackState.value = 'error'\n}\n\nfunction onLoad(kind: 'primary' | 'fallback'): void {\n if (kind === 'primary')\n primaryState.value = 'loaded'\n else fallbackState.value = 'loaded'\n}\n</script>\n\n<template>\n <span\n data-gr-avatar\n :style=\"style\"\n :class=\"rootClass\"\n :role=\"rootIsImage ? 'img' : undefined\"\n :aria-label=\"rootIsImage ? accessibleName : undefined\"\n >\n <span :class=\"[mediaClass, status ? [mediaClipClass, grAvatarClass(resolvedShape)] : '']\">\n <GrSkeleton\n v-if=\"showSkeleton\"\n data-gr-avatar-skeleton\n width=\"100%\"\n height=\"100%\"\n :rounded=\"resolvedShape === 'circle' ? 'var(--gr-radius-full)' : 'var(--gr-avatar-square-radius, 10px)'\"\n />\n\n <img\n v-if=\"activeSrc\"\n :key=\"activeSrc\"\n data-gr-avatar-image\n :src=\"activeSrc\"\n :alt=\"accessibleName\"\n class=\"h-full w-full object-cover\"\n :class=\"showSkeleton ? 'invisible absolute' : ''\"\n @error=\"onError(isFallbackActive ? 'fallback' : 'primary')\"\n @load=\"onLoad(isFallbackActive ? 'fallback' : 'primary')\"\n >\n\n <span v-else-if=\"showInitials\" data-gr-avatar-initials>{{ initials }}</span>\n\n <slot v-else />\n </span>\n\n <template v-if=\"status\">\n <span\n data-gr-avatar-status\n :class=\"[statusDotClass, statusToneClass[status]]\"\n aria-hidden=\"true\"\n />\n <!-- Цвет точки смысл не передаёт: статус объявляется словом (WCAG 1.4.1). -->\n <span data-gr-avatar-status-label class=\"sr-only\">{{ statusLabel }}</span>\n </template>\n </span>\n</template>\n","<script setup lang=\"ts\">\n/**\n * GrAvatarGroup — ряд аватаров со стекингом и счётчиком скрытых.\n *\n * Группа объявлена `role=\"group\"` с именем и числом участников: без этого\n * скринридер читает набор безымянных картинок и не понимает, что их больше,\n * чем видно.\n */\nimport { computed, provide, type VNode } from 'vue'\n\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport type { GrSizeWithPx } from '../shared/sizes'\n\nimport { GR_AVATAR_GROUP_KEY } from './avatarContext'\nimport {\n avatarFontSizePx,\n grAvatarClass,\n groupBaseClass,\n groupItemClass,\n groupOverflowClass,\n rootBaseClass,\n type GrAvatarShape,\n} from './grAvatarStyles'\n\nconst GR_AVATAR_GROUP_SIZE_PX = {\n xs: 24,\n sm: 32,\n md: 40,\n lg: 56,\n} as const\n\nexport interface GrAvatarGroupProps {\n /** Размер и форма ряда: дети берут их из контекста. */\n size?: GrSizeWithPx\n shape?: GrAvatarShape\n /** Сколько аватаров показывать; остальные сворачиваются в «+N». */\n max?: number\n /** Сколько участников всего, если в слоте лежит лишь часть. */\n total?: number\n /** Имя группы. Не задано — берётся из локали. */\n ariaLabel?: string\n}\n\nconst props = withDefaults(defineProps<GrAvatarGroupProps>(), {\n size: undefined,\n shape: undefined,\n max: undefined,\n total: undefined,\n ariaLabel: undefined,\n})\n\nconst slots = defineSlots<{\n /** Аватары ряда. */\n default?: () => VNode[]\n}>()\n\nconst { t } = useGranularityTranslations()\n\nprovide(GR_AVATAR_GROUP_KEY, {\n get size() {\n return props.size\n },\n get shape() {\n return props.shape\n },\n})\n\nconst children = computed(() => slots.default?.() ?? [])\n\n// `v-for` внутри слота приходит фрагментом — считаем его детей, иначе весь\n// список выглядел бы одним аватаром.\nconst items = computed<VNode[]>(() => children.value.flatMap((node) => {\n const nested = node.children\n return Array.isArray(nested) && typeof node.type === 'symbol' ? (nested as VNode[]) : [node]\n}))\n\nconst visible = computed(() => (props.max === undefined ? items.value : items.value.slice(0, Math.max(0, props.max))))\n\nconst hiddenCount = computed(() => {\n const total = props.total ?? items.value.length\n return Math.max(0, total - visible.value.length)\n})\n\nconst overflowSizePx = computed(() => (\n typeof props.size === 'number' ? props.size : GR_AVATAR_GROUP_SIZE_PX[props.size ?? 'md']\n))\n\nconst overflowStyle = computed(() => {\n const px = `${overflowSizePx.value}px`\n return { width: px, height: px, fontSize: `${avatarFontSizePx(overflowSizePx.value)}px` }\n})\n\nconst groupLabel = computed(() => props.ariaLabel ?? t('gr.avatar.group', 'People'))\n\nconst accessibleLabel = computed(() => (hiddenCount.value > 0\n ? `${groupLabel.value}, ${t('gr.avatar.groupOverflow', 'and {count} more', { count: hiddenCount.value, n: hiddenCount.value })}`\n : groupLabel.value))\n</script>\n\n<template>\n <div\n data-gr-avatar-group\n role=\"group\"\n :aria-label=\"accessibleLabel\"\n :class=\"groupBaseClass\"\n >\n <component\n :is=\"node\"\n v-for=\"(node, index) in visible\"\n :key=\"index\"\n :class=\"groupItemClass\"\n />\n\n <span\n v-if=\"hiddenCount > 0\"\n data-gr-avatar-group-overflow\n aria-hidden=\"true\"\n :class=\"[rootBaseClass, groupOverflowClass, groupItemClass, grAvatarClass(shape ?? 'circle')]\"\n :style=\"overflowStyle\"\n >+{{ hiddenCount }}</span>\n </div>\n</template>\n","<script setup lang=\"ts\">\n/**\n * GrAvatarGroup — ряд аватаров со стекингом и счётчиком скрытых.\n *\n * Группа объявлена `role=\"group\"` с именем и числом участников: без этого\n * скринридер читает набор безымянных картинок и не понимает, что их больше,\n * чем видно.\n */\nimport { computed, provide, type VNode } from 'vue'\n\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport type { GrSizeWithPx } from '../shared/sizes'\n\nimport { GR_AVATAR_GROUP_KEY } from './avatarContext'\nimport {\n avatarFontSizePx,\n grAvatarClass,\n groupBaseClass,\n groupItemClass,\n groupOverflowClass,\n rootBaseClass,\n type GrAvatarShape,\n} from './grAvatarStyles'\n\nconst GR_AVATAR_GROUP_SIZE_PX = {\n xs: 24,\n sm: 32,\n md: 40,\n lg: 56,\n} as const\n\nexport interface GrAvatarGroupProps {\n /** Размер и форма ряда: дети берут их из контекста. */\n size?: GrSizeWithPx\n shape?: GrAvatarShape\n /** Сколько аватаров показывать; остальные сворачиваются в «+N». */\n max?: number\n /** Сколько участников всего, если в слоте лежит лишь часть. */\n total?: number\n /** Имя группы. Не задано — берётся из локали. */\n ariaLabel?: string\n}\n\nconst props = withDefaults(defineProps<GrAvatarGroupProps>(), {\n size: undefined,\n shape: undefined,\n max: undefined,\n total: undefined,\n ariaLabel: undefined,\n})\n\nconst slots = defineSlots<{\n /** Аватары ряда. */\n default?: () => VNode[]\n}>()\n\nconst { t } = useGranularityTranslations()\n\nprovide(GR_AVATAR_GROUP_KEY, {\n get size() {\n return props.size\n },\n get shape() {\n return props.shape\n },\n})\n\nconst children = computed(() => slots.default?.() ?? [])\n\n// `v-for` внутри слота приходит фрагментом — считаем его детей, иначе весь\n// список выглядел бы одним аватаром.\nconst items = computed<VNode[]>(() => children.value.flatMap((node) => {\n const nested = node.children\n return Array.isArray(nested) && typeof node.type === 'symbol' ? (nested as VNode[]) : [node]\n}))\n\nconst visible = computed(() => (props.max === undefined ? items.value : items.value.slice(0, Math.max(0, props.max))))\n\nconst hiddenCount = computed(() => {\n const total = props.total ?? items.value.length\n return Math.max(0, total - visible.value.length)\n})\n\nconst overflowSizePx = computed(() => (\n typeof props.size === 'number' ? props.size : GR_AVATAR_GROUP_SIZE_PX[props.size ?? 'md']\n))\n\nconst overflowStyle = computed(() => {\n const px = `${overflowSizePx.value}px`\n return { width: px, height: px, fontSize: `${avatarFontSizePx(overflowSizePx.value)}px` }\n})\n\nconst groupLabel = computed(() => props.ariaLabel ?? t('gr.avatar.group', 'People'))\n\nconst accessibleLabel = computed(() => (hiddenCount.value > 0\n ? `${groupLabel.value}, ${t('gr.avatar.groupOverflow', 'and {count} more', { count: hiddenCount.value, n: hiddenCount.value })}`\n : groupLabel.value))\n</script>\n\n<template>\n <div\n data-gr-avatar-group\n role=\"group\"\n :aria-label=\"accessibleLabel\"\n :class=\"groupBaseClass\"\n >\n <component\n :is=\"node\"\n v-for=\"(node, index) in visible\"\n :key=\"index\"\n :class=\"groupItemClass\"\n />\n\n <span\n v-if=\"hiddenCount > 0\"\n data-gr-avatar-group-overflow\n aria-hidden=\"true\"\n :class=\"[rootBaseClass, groupOverflowClass, groupItemClass, grAvatarClass(shape ?? 'circle')]\"\n :style=\"overflowStyle\"\n >+{{ hiddenCount }}</span>\n </div>\n</template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"GrAvatar-dWEXiCJG.js","names":[],"sources":["../../../../src/components/GrAvatar/avatarContext.ts","../../../../src/components/GrAvatar/GrAvatar.vue","../../../../src/components/GrAvatar/GrAvatar.vue","../../../../src/components/GrAvatar/GrAvatarGroup.vue","../../../../src/components/GrAvatar/GrAvatarGroup.vue"],"sourcesContent":["import type { InjectionKey } from 'vue'\n\nimport type { GrAvatarShape } from './grAvatarStyles'\nimport type { GrSizeWithPx } from '../shared/sizes'\n\n/**\n * Контекст `GrAvatarGroup`: размер и форма задаются на группе, чтобы ряд\n * аватаров не расползался, когда потребитель забыл повторить пропы у каждого.\n */\nexport interface GrAvatarGroupContext {\n size?: GrSizeWithPx\n shape?: GrAvatarShape\n}\n\nexport const GR_AVATAR_GROUP_KEY: InjectionKey<GrAvatarGroupContext> = Symbol.for('@feugene/granularity/avatar-group')\n","<script setup lang=\"ts\">\nimport { computed, inject, ref, watch } from 'vue'\n\nimport GrSkeleton from '../GrSkeleton/GrSkeleton.vue'\nimport { useGrComponentProp, useGrComponentSize } from '../GrConfigProvider/context'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport type { GrSizeWithPx } from '../shared/sizes'\n\nimport { GR_AVATAR_GROUP_KEY } from './avatarContext'\nimport {\n avatarFontSizePx,\n grAvatarClass,\n initialsFrom,\n mediaClass,\n mediaClipClass,\n rootBaseClass,\n rootStatusClass,\n statusDotClass,\n statusToneClass,\n type GrAvatarShape,\n type GrAvatarStatus,\n} from './grAvatarStyles'\n\nexport type { GrAvatarShape, GrAvatarStatus } from './grAvatarStyles'\n\n/** Диаметр аватара для каждой ступени канонической шкалы. */\nconst GR_AVATAR_SIZE_PX = {\n xs: 24,\n sm: 32,\n md: 40,\n lg: 56,\n} as const\n\nexport interface GrAvatarProps {\n /**\n * Размер по канонической шкале (`xs|sm|md|lg`) — тогда работает\n * `GrConfigProvider`. Число — escape-hatch: аватар нужен произвольного\n * диаметра (24px в строке списка, 96px в профиле), и четыре ступени шкалы\n * этого не закрывают.\n */\n size?: GrSizeWithPx\n src?: string\n /** Резервная картинка: показывается, когда `src` не загрузился. */\n fallbackSrc?: string\n alt?: string\n /** Имя участника: даёт инициалы и доступное имя аватара. */\n name?: string\n shape?: GrAvatarShape\n /** Статус участника. Точка декоративна — рядом идёт скрытая подпись. */\n status?: GrAvatarStatus\n}\n\nconst props = withDefaults(defineProps<GrAvatarProps>(), {\n size: undefined,\n src: undefined,\n fallbackSrc: undefined,\n alt: undefined,\n name: undefined,\n // Дефолт живёт в резолвере: Vue подставил бы свой раньше, чем компонент\n // заглянет в `GrConfigProvider`.\n shape: undefined,\n status: undefined,\n})\n\nconst slots = defineSlots<{\n /** Содержимое вместо картинки и инициалов. */\n default?: () => unknown\n}>()\n\nconst { t } = useGranularityTranslations()\nconst group = inject(GR_AVATAR_GROUP_KEY, null)\n\n// Размер и форма группы сильнее провайдера, но слабее собственного пропа.\nconst localSize = computed(() => props.size ?? group?.size)\n\nconst resolvedScaleSize = useGrComponentSize(\n () => (typeof localSize.value === 'number' ? undefined : localSize.value),\n { component: 'GrAvatar' },\n)\n\nconst resolvedShape = useGrComponentProp(\n 'GrAvatar',\n 'shape',\n () => props.shape ?? group?.shape,\n 'circle',\n)\n\nconst sizePx = computed(() => (\n typeof localSize.value === 'number' ? localSize.value : GR_AVATAR_SIZE_PX[resolvedScaleSize.value]\n))\n\nconst style = computed(() => {\n const px = `${sizePx.value}px`\n // Кегль на корне, а не на span инициалов: так он достаётся и слотовому тексту.\n return { width: px, height: px, fontSize: `${avatarFontSizePx(sizePx.value)}px` }\n})\n\n/**\n * Состояние картинки. Без него битая ссылка оставляла `v-if=\"src\"` истинным:\n * браузер рисовал сломанное изображение, а запасной вариант не показывался\n * никогда.\n */\ntype ImageState = 'loading' | 'loaded' | 'error'\n\nconst primaryState = ref<ImageState>('loading')\nconst fallbackState = ref<ImageState>('loading')\n\n// Новая ссылка не должна наследовать ошибку прошлой.\nwatch(() => props.src, () => {\n primaryState.value = 'loading'\n})\nwatch(() => props.fallbackSrc, () => {\n fallbackState.value = 'loading'\n})\n\nconst activeSrc = computed(() => {\n if (props.src && primaryState.value !== 'error')\n return props.src\n if (props.fallbackSrc && fallbackState.value !== 'error')\n return props.fallbackSrc\n return undefined\n})\n\nconst isFallbackActive = computed(() => Boolean(activeSrc.value) && activeSrc.value !== props.src)\n\n// Скелет держит место, пока картинка едет: иначе ряд аватаров мигает пустотой.\nconst showSkeleton = computed(() => {\n if (!activeSrc.value)\n return false\n return (isFallbackActive.value ? fallbackState.value : primaryState.value) === 'loading'\n})\n\nconst initials = computed(() => (props.name ? initialsFrom(props.name) : ''))\n\n// Пусто — когда нет ни картинки, ни слота, ни имени.\nconst showInitials = computed(() => !activeSrc.value && !slots.default && Boolean(initials.value))\n\nconst statusLabel = computed(() => (props.status\n ? t(`gr.avatar.status.${props.status}`, props.status)\n : undefined))\n\n/**\n * Доступное имя: `alt` сильнее всего, иначе имя участника.\n *\n * Когда есть картинка, имя несёт её `alt` — так привычнее потребителю и не\n * возникает двойного объявления. Без картинки роль и имя берёт на себя корень:\n * иначе аватар с инициалами остался бы для диктора пустым.\n */\nconst accessibleName = computed(() => props.alt ?? props.name ?? '')\n\nconst rootIsImage = computed(() => !activeSrc.value && accessibleName.value !== '')\n\nconst rootClass = computed(() => [\n rootBaseClass,\n grAvatarClass(resolvedShape.value),\n props.status ? rootStatusClass : '',\n])\n\nfunction onError(kind: 'primary' | 'fallback'): void {\n if (kind === 'primary')\n primaryState.value = 'error'\n else fallbackState.value = 'error'\n}\n\nfunction onLoad(kind: 'primary' | 'fallback'): void {\n if (kind === 'primary')\n primaryState.value = 'loaded'\n else fallbackState.value = 'loaded'\n}\n</script>\n\n<template>\n <span\n data-gr-avatar\n :style=\"style\"\n :class=\"rootClass\"\n :role=\"rootIsImage ? 'img' : undefined\"\n :aria-label=\"rootIsImage ? accessibleName : undefined\"\n >\n <span :class=\"[mediaClass, status ? [mediaClipClass, grAvatarClass(resolvedShape)] : '']\">\n <GrSkeleton\n v-if=\"showSkeleton\"\n data-gr-avatar-skeleton\n width=\"100%\"\n height=\"100%\"\n :rounded=\"resolvedShape === 'circle' ? 'var(--gr-radius-full)' : 'var(--gr-avatar-square-radius, 10px)'\"\n />\n\n <img\n v-if=\"activeSrc\"\n :key=\"activeSrc\"\n data-gr-avatar-image\n :src=\"activeSrc\"\n :alt=\"accessibleName\"\n class=\"h-full w-full object-cover\"\n :class=\"showSkeleton ? 'invisible absolute' : ''\"\n @error=\"onError(isFallbackActive ? 'fallback' : 'primary')\"\n @load=\"onLoad(isFallbackActive ? 'fallback' : 'primary')\"\n >\n\n <span v-else-if=\"showInitials\" data-gr-avatar-initials>{{ initials }}</span>\n\n <slot v-else />\n </span>\n\n <template v-if=\"status\">\n <span\n data-gr-avatar-status\n :class=\"[statusDotClass, statusToneClass[status]]\"\n aria-hidden=\"true\"\n />\n <!-- Цвет точки смысл не передаёт: статус объявляется словом (WCAG 1.4.1). -->\n <span data-gr-avatar-status-label class=\"sr-only\">{{ statusLabel }}</span>\n </template>\n </span>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, inject, ref, watch } from 'vue'\n\nimport GrSkeleton from '../GrSkeleton/GrSkeleton.vue'\nimport { useGrComponentProp, useGrComponentSize } from '../GrConfigProvider/context'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport type { GrSizeWithPx } from '../shared/sizes'\n\nimport { GR_AVATAR_GROUP_KEY } from './avatarContext'\nimport {\n avatarFontSizePx,\n grAvatarClass,\n initialsFrom,\n mediaClass,\n mediaClipClass,\n rootBaseClass,\n rootStatusClass,\n statusDotClass,\n statusToneClass,\n type GrAvatarShape,\n type GrAvatarStatus,\n} from './grAvatarStyles'\n\nexport type { GrAvatarShape, GrAvatarStatus } from './grAvatarStyles'\n\n/** Диаметр аватара для каждой ступени канонической шкалы. */\nconst GR_AVATAR_SIZE_PX = {\n xs: 24,\n sm: 32,\n md: 40,\n lg: 56,\n} as const\n\nexport interface GrAvatarProps {\n /**\n * Размер по канонической шкале (`xs|sm|md|lg`) — тогда работает\n * `GrConfigProvider`. Число — escape-hatch: аватар нужен произвольного\n * диаметра (24px в строке списка, 96px в профиле), и четыре ступени шкалы\n * этого не закрывают.\n */\n size?: GrSizeWithPx\n src?: string\n /** Резервная картинка: показывается, когда `src` не загрузился. */\n fallbackSrc?: string\n alt?: string\n /** Имя участника: даёт инициалы и доступное имя аватара. */\n name?: string\n shape?: GrAvatarShape\n /** Статус участника. Точка декоративна — рядом идёт скрытая подпись. */\n status?: GrAvatarStatus\n}\n\nconst props = withDefaults(defineProps<GrAvatarProps>(), {\n size: undefined,\n src: undefined,\n fallbackSrc: undefined,\n alt: undefined,\n name: undefined,\n // Дефолт живёт в резолвере: Vue подставил бы свой раньше, чем компонент\n // заглянет в `GrConfigProvider`.\n shape: undefined,\n status: undefined,\n})\n\nconst slots = defineSlots<{\n /** Содержимое вместо картинки и инициалов. */\n default?: () => unknown\n}>()\n\nconst { t } = useGranularityTranslations()\nconst group = inject(GR_AVATAR_GROUP_KEY, null)\n\n// Размер и форма группы сильнее провайдера, но слабее собственного пропа.\nconst localSize = computed(() => props.size ?? group?.size)\n\nconst resolvedScaleSize = useGrComponentSize(\n () => (typeof localSize.value === 'number' ? undefined : localSize.value),\n { component: 'GrAvatar' },\n)\n\nconst resolvedShape = useGrComponentProp(\n 'GrAvatar',\n 'shape',\n () => props.shape ?? group?.shape,\n 'circle',\n)\n\nconst sizePx = computed(() => (\n typeof localSize.value === 'number' ? localSize.value : GR_AVATAR_SIZE_PX[resolvedScaleSize.value]\n))\n\nconst style = computed(() => {\n const px = `${sizePx.value}px`\n // Кегль на корне, а не на span инициалов: так он достаётся и слотовому тексту.\n return { width: px, height: px, fontSize: `${avatarFontSizePx(sizePx.value)}px` }\n})\n\n/**\n * Состояние картинки. Без него битая ссылка оставляла `v-if=\"src\"` истинным:\n * браузер рисовал сломанное изображение, а запасной вариант не показывался\n * никогда.\n */\ntype ImageState = 'loading' | 'loaded' | 'error'\n\nconst primaryState = ref<ImageState>('loading')\nconst fallbackState = ref<ImageState>('loading')\n\n// Новая ссылка не должна наследовать ошибку прошлой.\nwatch(() => props.src, () => {\n primaryState.value = 'loading'\n})\nwatch(() => props.fallbackSrc, () => {\n fallbackState.value = 'loading'\n})\n\nconst activeSrc = computed(() => {\n if (props.src && primaryState.value !== 'error')\n return props.src\n if (props.fallbackSrc && fallbackState.value !== 'error')\n return props.fallbackSrc\n return undefined\n})\n\nconst isFallbackActive = computed(() => Boolean(activeSrc.value) && activeSrc.value !== props.src)\n\n// Скелет держит место, пока картинка едет: иначе ряд аватаров мигает пустотой.\nconst showSkeleton = computed(() => {\n if (!activeSrc.value)\n return false\n return (isFallbackActive.value ? fallbackState.value : primaryState.value) === 'loading'\n})\n\nconst initials = computed(() => (props.name ? initialsFrom(props.name) : ''))\n\n// Пусто — когда нет ни картинки, ни слота, ни имени.\nconst showInitials = computed(() => !activeSrc.value && !slots.default && Boolean(initials.value))\n\nconst statusLabel = computed(() => (props.status\n ? t(`gr.avatar.status.${props.status}`, props.status)\n : undefined))\n\n/**\n * Доступное имя: `alt` сильнее всего, иначе имя участника.\n *\n * Когда есть картинка, имя несёт её `alt` — так привычнее потребителю и не\n * возникает двойного объявления. Без картинки роль и имя берёт на себя корень:\n * иначе аватар с инициалами остался бы для диктора пустым.\n */\nconst accessibleName = computed(() => props.alt ?? props.name ?? '')\n\nconst rootIsImage = computed(() => !activeSrc.value && accessibleName.value !== '')\n\nconst rootClass = computed(() => [\n rootBaseClass,\n grAvatarClass(resolvedShape.value),\n props.status ? rootStatusClass : '',\n])\n\nfunction onError(kind: 'primary' | 'fallback'): void {\n if (kind === 'primary')\n primaryState.value = 'error'\n else fallbackState.value = 'error'\n}\n\nfunction onLoad(kind: 'primary' | 'fallback'): void {\n if (kind === 'primary')\n primaryState.value = 'loaded'\n else fallbackState.value = 'loaded'\n}\n</script>\n\n<template>\n <span\n data-gr-avatar\n :style=\"style\"\n :class=\"rootClass\"\n :role=\"rootIsImage ? 'img' : undefined\"\n :aria-label=\"rootIsImage ? accessibleName : undefined\"\n >\n <span :class=\"[mediaClass, status ? [mediaClipClass, grAvatarClass(resolvedShape)] : '']\">\n <GrSkeleton\n v-if=\"showSkeleton\"\n data-gr-avatar-skeleton\n width=\"100%\"\n height=\"100%\"\n :rounded=\"resolvedShape === 'circle' ? 'var(--gr-radius-full)' : 'var(--gr-avatar-square-radius, 10px)'\"\n />\n\n <img\n v-if=\"activeSrc\"\n :key=\"activeSrc\"\n data-gr-avatar-image\n :src=\"activeSrc\"\n :alt=\"accessibleName\"\n class=\"h-full w-full object-cover\"\n :class=\"showSkeleton ? 'invisible absolute' : ''\"\n @error=\"onError(isFallbackActive ? 'fallback' : 'primary')\"\n @load=\"onLoad(isFallbackActive ? 'fallback' : 'primary')\"\n >\n\n <span v-else-if=\"showInitials\" data-gr-avatar-initials>{{ initials }}</span>\n\n <slot v-else />\n </span>\n\n <template v-if=\"status\">\n <span\n data-gr-avatar-status\n :class=\"[statusDotClass, statusToneClass[status]]\"\n aria-hidden=\"true\"\n />\n <!-- Цвет точки смысл не передаёт: статус объявляется словом (WCAG 1.4.1). -->\n <span data-gr-avatar-status-label class=\"sr-only\">{{ statusLabel }}</span>\n </template>\n </span>\n</template>\n","<script setup lang=\"ts\">\n/**\n * GrAvatarGroup — ряд аватаров со стекингом и счётчиком скрытых.\n *\n * Группа объявлена `role=\"group\"` с именем и числом участников: без этого\n * скринридер читает набор безымянных картинок и не понимает, что их больше,\n * чем видно.\n */\nimport { computed, provide, type VNode } from 'vue'\n\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport type { GrSizeWithPx } from '../shared/sizes'\n\nimport { GR_AVATAR_GROUP_KEY } from './avatarContext'\nimport {\n avatarFontSizePx,\n grAvatarClass,\n groupBaseClass,\n groupItemClass,\n groupOverflowClass,\n rootBaseClass,\n type GrAvatarShape,\n} from './grAvatarStyles'\n\nconst GR_AVATAR_GROUP_SIZE_PX = {\n xs: 24,\n sm: 32,\n md: 40,\n lg: 56,\n} as const\n\nexport interface GrAvatarGroupProps {\n /** Размер и форма ряда: дети берут их из контекста. */\n size?: GrSizeWithPx\n shape?: GrAvatarShape\n /** Сколько аватаров показывать; остальные сворачиваются в «+N». */\n max?: number\n /** Сколько участников всего, если в слоте лежит лишь часть. */\n total?: number\n /** Имя группы. Не задано — берётся из локали. */\n ariaLabel?: string\n}\n\nconst props = withDefaults(defineProps<GrAvatarGroupProps>(), {\n size: undefined,\n shape: undefined,\n max: undefined,\n total: undefined,\n ariaLabel: undefined,\n})\n\nconst slots = defineSlots<{\n /** Аватары ряда. */\n default?: () => VNode[]\n}>()\n\nconst { t } = useGranularityTranslations()\n\nprovide(GR_AVATAR_GROUP_KEY, {\n get size() {\n return props.size\n },\n get shape() {\n return props.shape\n },\n})\n\nconst children = computed(() => slots.default?.() ?? [])\n\n// `v-for` внутри слота приходит фрагментом — считаем его детей, иначе весь\n// список выглядел бы одним аватаром.\nconst items = computed<VNode[]>(() => children.value.flatMap((node) => {\n const nested = node.children\n return Array.isArray(nested) && typeof node.type === 'symbol' ? (nested as VNode[]) : [node]\n}))\n\nconst visible = computed(() => (props.max === undefined ? items.value : items.value.slice(0, Math.max(0, props.max))))\n\nconst hiddenCount = computed(() => {\n const total = props.total ?? items.value.length\n return Math.max(0, total - visible.value.length)\n})\n\nconst overflowSizePx = computed(() => (\n typeof props.size === 'number' ? props.size : GR_AVATAR_GROUP_SIZE_PX[props.size ?? 'md']\n))\n\nconst overflowStyle = computed(() => {\n const px = `${overflowSizePx.value}px`\n return { width: px, height: px, fontSize: `${avatarFontSizePx(overflowSizePx.value)}px` }\n})\n\nconst groupLabel = computed(() => props.ariaLabel ?? t('gr.avatar.group', 'People'))\n\nconst accessibleLabel = computed(() => (hiddenCount.value > 0\n ? `${groupLabel.value}, ${t('gr.avatar.groupOverflow', 'and {count} more', { count: hiddenCount.value, n: hiddenCount.value })}`\n : groupLabel.value))\n</script>\n\n<template>\n <div\n data-gr-avatar-group\n role=\"group\"\n :aria-label=\"accessibleLabel\"\n :class=\"groupBaseClass\"\n >\n <component\n :is=\"node\"\n v-for=\"(node, index) in visible\"\n :key=\"index\"\n :class=\"groupItemClass\"\n />\n\n <span\n v-if=\"hiddenCount > 0\"\n data-gr-avatar-group-overflow\n aria-hidden=\"true\"\n :class=\"[rootBaseClass, groupOverflowClass, groupItemClass, grAvatarClass(shape ?? 'circle')]\"\n :style=\"overflowStyle\"\n >+{{ hiddenCount }}</span>\n </div>\n</template>\n","<script setup lang=\"ts\">\n/**\n * GrAvatarGroup — ряд аватаров со стекингом и счётчиком скрытых.\n *\n * Группа объявлена `role=\"group\"` с именем и числом участников: без этого\n * скринридер читает набор безымянных картинок и не понимает, что их больше,\n * чем видно.\n */\nimport { computed, provide, type VNode } from 'vue'\n\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport type { GrSizeWithPx } from '../shared/sizes'\n\nimport { GR_AVATAR_GROUP_KEY } from './avatarContext'\nimport {\n avatarFontSizePx,\n grAvatarClass,\n groupBaseClass,\n groupItemClass,\n groupOverflowClass,\n rootBaseClass,\n type GrAvatarShape,\n} from './grAvatarStyles'\n\nconst GR_AVATAR_GROUP_SIZE_PX = {\n xs: 24,\n sm: 32,\n md: 40,\n lg: 56,\n} as const\n\nexport interface GrAvatarGroupProps {\n /** Размер и форма ряда: дети берут их из контекста. */\n size?: GrSizeWithPx\n shape?: GrAvatarShape\n /** Сколько аватаров показывать; остальные сворачиваются в «+N». */\n max?: number\n /** Сколько участников всего, если в слоте лежит лишь часть. */\n total?: number\n /** Имя группы. Не задано — берётся из локали. */\n ariaLabel?: string\n}\n\nconst props = withDefaults(defineProps<GrAvatarGroupProps>(), {\n size: undefined,\n shape: undefined,\n max: undefined,\n total: undefined,\n ariaLabel: undefined,\n})\n\nconst slots = defineSlots<{\n /** Аватары ряда. */\n default?: () => VNode[]\n}>()\n\nconst { t } = useGranularityTranslations()\n\nprovide(GR_AVATAR_GROUP_KEY, {\n get size() {\n return props.size\n },\n get shape() {\n return props.shape\n },\n})\n\nconst children = computed(() => slots.default?.() ?? [])\n\n// `v-for` внутри слота приходит фрагментом — считаем его детей, иначе весь\n// список выглядел бы одним аватаром.\nconst items = computed<VNode[]>(() => children.value.flatMap((node) => {\n const nested = node.children\n return Array.isArray(nested) && typeof node.type === 'symbol' ? (nested as VNode[]) : [node]\n}))\n\nconst visible = computed(() => (props.max === undefined ? items.value : items.value.slice(0, Math.max(0, props.max))))\n\nconst hiddenCount = computed(() => {\n const total = props.total ?? items.value.length\n return Math.max(0, total - visible.value.length)\n})\n\nconst overflowSizePx = computed(() => (\n typeof props.size === 'number' ? props.size : GR_AVATAR_GROUP_SIZE_PX[props.size ?? 'md']\n))\n\nconst overflowStyle = computed(() => {\n const px = `${overflowSizePx.value}px`\n return { width: px, height: px, fontSize: `${avatarFontSizePx(overflowSizePx.value)}px` }\n})\n\nconst groupLabel = computed(() => props.ariaLabel ?? t('gr.avatar.group', 'People'))\n\nconst accessibleLabel = computed(() => (hiddenCount.value > 0\n ? `${groupLabel.value}, ${t('gr.avatar.groupOverflow', 'and {count} more', { count: hiddenCount.value, n: hiddenCount.value })}`\n : groupLabel.value))\n</script>\n\n<template>\n <div\n data-gr-avatar-group\n role=\"group\"\n :aria-label=\"accessibleLabel\"\n :class=\"groupBaseClass\"\n >\n <component\n :is=\"node\"\n v-for=\"(node, index) in visible\"\n :key=\"index\"\n :class=\"groupItemClass\"\n />\n\n <span\n v-if=\"hiddenCount > 0\"\n data-gr-avatar-group-overflow\n aria-hidden=\"true\"\n :class=\"[rootBaseClass, groupOverflowClass, groupItemClass, grAvatarClass(shape ?? 'circle')]\"\n :style=\"overflowStyle\"\n >+{{ hiddenCount }}</span>\n </div>\n</template>\n"],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { n as GrAvatar_default, t as GrAvatarGroup_default } from "./chunks/GrAvatar-
|
|
1
|
+
import { n as GrAvatar_default, t as GrAvatarGroup_default } from "./chunks/GrAvatar-dWEXiCJG.js";
|
|
2
2
|
import { c as initialsFrom, n as grAvatarSafelist, t as grAvatarConfig } from "../../chunks/config-B3J0alyY.js";
|
|
3
3
|
export { GrAvatar_default as GrAvatar, GrAvatar_default as default, GrAvatarGroup_default as GrAvatarGroup, grAvatarConfig, grAvatarSafelist, initialsFrom };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { i as useGrComponentProp } from "../../../chunks/context-
|
|
2
|
-
import { t as warnRenamedProp } from "../../../chunks/renamedProp-
|
|
1
|
+
import { i as useGrComponentProp } from "../../../chunks/context-CPMRfwVr.js";
|
|
2
|
+
import { t as warnRenamedProp } from "../../../chunks/renamedProp-Dy96tT-F.js";
|
|
3
3
|
import { i as grBadgeClass, n as badgeIconSizeClassBySize, t as badgeIconClass } from "../../../chunks/grBadgeStyles-DV0DrAew.js";
|
|
4
4
|
import { t as _plugin_vue_export_helper_default } from "../../../chunks/_plugin-vue_export-helper-BOaGB7Aw.js";
|
|
5
5
|
import { computed, createCommentVNode, createElementBlock, createElementVNode, defineComponent, normalizeClass, openBlock, renderSlot, unref, useAttrs } from "vue";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GrBadge-
|
|
1
|
+
{"version":3,"file":"GrBadge-DBeQXEir.js","names":["$slots"],"sources":["../../../../src/components/GrBadge/GrBadge.vue","../../../../src/components/GrBadge/GrBadge.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue'\n\nimport { useGrComponentProp } from '../GrConfigProvider/context'\n\nexport type { GrBadgeRadius, GrBadgeSize, GrBadgeTone } from './grBadgeStyles'\n\nimport { warnRenamedProp } from '../shared/renamedProp'\n\nimport {\n badgeIconClass,\n badgeIconSizeClassBySize,\n grBadgeClass,\n type GrBadgeRadius,\n type GrBadgeSize,\n type GrBadgeTone,\n} from './grBadgeStyles'\n\nexport interface GrBadgeProps {\n tone?: GrBadgeTone\n dark?: boolean\n size?: GrBadgeSize\n radius?: GrBadgeRadius\n}\n\nconst props = withDefaults(\n defineProps<GrBadgeProps>(),\n {\n // `tone`/`size`/`radius` настраиваются через `GrConfigProvider`, поэтому\n // их дефолты живут в резолверах ниже, а не в `withDefaults`.\n tone: undefined,\n dark: false,\n size: undefined,\n radius: undefined,\n },\n)\n\n// Эффективные значения: локальный проп → `GrConfigProvider` → дефолт компонента.\nconst resolvedTone = useGrComponentProp('GrBadge', 'tone', () => props.tone, 'neutral')\nconst resolvedSize = useGrComponentProp('GrBadge', 'size', () => props.size, 'sm')\nconst resolvedRadius = useGrComponentProp('GrBadge', 'radius', () => props.radius, 'round')\n\n// `variant` переименован в `tone`: незнакомый атрибут Vue сажает на корневой\n// узел, поэтому старое имя не роняет ни типы, ни рантайм — компонент молча\n// рисуется дефолтным тоном.\nwarnRenamedProp('GrBadge', useAttrs(), { variant: 'tone' })\n\nconst className = computed(() => {\n return grBadgeClass({\n tone: resolvedTone.value,\n dark: props.dark,\n size: resolvedSize.value,\n radius: resolvedRadius.value,\n })\n})\n\nconst iconSizeClass = computed(() => badgeIconSizeClassBySize[resolvedSize.value])\n\ndefineSlots<{\n /** Содержимое метки. */\n default?: () => any\n /**\n * Иконка перед подписью: статус со спиннером, флаг, значок типа.\n *\n * Размер задаёт обёртка по ступени `size`, поэтому содержимое слота тянется\n * до неё — `class=\"h-full w-full\"`, как у `GrChip`. Вращение спиннера —\n * `animate-spin` на самой иконке.\n *\n * `GrProgressCircle` сюда не кладут: у кругового индикатора шкала виджетная,\n * нижняя ступень — `2rem`, и в строку бейджа он не помещается.\n */\n icon?: () => any\n}>()\n</script>\n\n<template>\n <span\n class=\"gr-badge inline-block border whitespace-nowrap leading-none\"\n :class=\"className\"\n >\n <span class=\"gr-badge__label\">\n <span\n v-if=\"$slots.icon\"\n data-gr-badge-icon\n :class=\"[badgeIconClass, iconSizeClass]\"\n >\n <slot name=\"icon\" />\n </span>\n <span class=\"gr-badge__text\">\n <slot />\n </span>\n </span>\n </span>\n</template>\n\n<style scoped>\n/*\n * Оптически центрируем текст по вертикали независимо от регистра,\n * не уменьшая высоту самого бейджа.\n *\n * Высоту держит обёртка `.gr-badge__label` (`min-height: 1lh` — высота\n * line-box при `leading-none`), а текст (`.gr-badge__text`) обрезается до\n * cap-height и центрируется внутри этой высоты через flex.\n *\n * Обрезка обязана жить на вложенном узле, а не на самом тексте: `text-box-trim`\n * уменьшает line-box, и повесь его прямо на текст — вместе с ним просядет\n * высота контента, а за ней и весь бейдж.\n *\n * `gap` задан в `em`, чтобы просвет перед иконкой шёл за кеглем ступени, а не\n * за корневым размером. Бейджа без иконки он не касается: у flex-контейнера с\n * единственным ребёнком просветов нет.\n */\n.gr-badge__label {\n display: flex;\n align-items: center;\n gap: 0.25em;\n min-height: 1lh;\n}\n\n.gr-badge__text {\n display: block;\n text-box-trim: trim-both;\n text-box-edge: cap alphabetic;\n /* Шорткат для браузеров с поддержкой нового синтаксиса. */\n text-box: trim-both cap alphabetic;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue'\n\nimport { useGrComponentProp } from '../GrConfigProvider/context'\n\nexport type { GrBadgeRadius, GrBadgeSize, GrBadgeTone } from './grBadgeStyles'\n\nimport { warnRenamedProp } from '../shared/renamedProp'\n\nimport {\n badgeIconClass,\n badgeIconSizeClassBySize,\n grBadgeClass,\n type GrBadgeRadius,\n type GrBadgeSize,\n type GrBadgeTone,\n} from './grBadgeStyles'\n\nexport interface GrBadgeProps {\n tone?: GrBadgeTone\n dark?: boolean\n size?: GrBadgeSize\n radius?: GrBadgeRadius\n}\n\nconst props = withDefaults(\n defineProps<GrBadgeProps>(),\n {\n // `tone`/`size`/`radius` настраиваются через `GrConfigProvider`, поэтому\n // их дефолты живут в резолверах ниже, а не в `withDefaults`.\n tone: undefined,\n dark: false,\n size: undefined,\n radius: undefined,\n },\n)\n\n// Эффективные значения: локальный проп → `GrConfigProvider` → дефолт компонента.\nconst resolvedTone = useGrComponentProp('GrBadge', 'tone', () => props.tone, 'neutral')\nconst resolvedSize = useGrComponentProp('GrBadge', 'size', () => props.size, 'sm')\nconst resolvedRadius = useGrComponentProp('GrBadge', 'radius', () => props.radius, 'round')\n\n// `variant` переименован в `tone`: незнакомый атрибут Vue сажает на корневой\n// узел, поэтому старое имя не роняет ни типы, ни рантайм — компонент молча\n// рисуется дефолтным тоном.\nwarnRenamedProp('GrBadge', useAttrs(), { variant: 'tone' })\n\nconst className = computed(() => {\n return grBadgeClass({\n tone: resolvedTone.value,\n dark: props.dark,\n size: resolvedSize.value,\n radius: resolvedRadius.value,\n })\n})\n\nconst iconSizeClass = computed(() => badgeIconSizeClassBySize[resolvedSize.value])\n\ndefineSlots<{\n /** Содержимое метки. */\n default?: () => any\n /**\n * Иконка перед подписью: статус со спиннером, флаг, значок типа.\n *\n * Размер задаёт обёртка по ступени `size`, поэтому содержимое слота тянется\n * до неё — `class=\"h-full w-full\"`, как у `GrChip`. Вращение спиннера —\n * `animate-spin` на самой иконке.\n *\n * `GrProgressCircle` сюда не кладут: у кругового индикатора шкала виджетная,\n * нижняя ступень — `2rem`, и в строку бейджа он не помещается.\n */\n icon?: () => any\n}>()\n</script>\n\n<template>\n <span\n class=\"gr-badge inline-block border whitespace-nowrap leading-none\"\n :class=\"className\"\n >\n <span class=\"gr-badge__label\">\n <span\n v-if=\"$slots.icon\"\n data-gr-badge-icon\n :class=\"[badgeIconClass, iconSizeClass]\"\n >\n <slot name=\"icon\" />\n </span>\n <span class=\"gr-badge__text\">\n <slot />\n </span>\n </span>\n </span>\n</template>\n\n<style scoped>\n/*\n * Оптически центрируем текст по вертикали независимо от регистра,\n * не уменьшая высоту самого бейджа.\n *\n * Высоту держит обёртка `.gr-badge__label` (`min-height: 1lh` — высота\n * line-box при `leading-none`), а текст (`.gr-badge__text`) обрезается до\n * cap-height и центрируется внутри этой высоты через flex.\n *\n * Обрезка обязана жить на вложенном узле, а не на самом тексте: `text-box-trim`\n * уменьшает line-box, и повесь его прямо на текст — вместе с ним просядет\n * высота контента, а за ней и весь бейдж.\n *\n * `gap` задан в `em`, чтобы просвет перед иконкой шёл за кеглем ступени, а не\n * за корневым размером. Бейджа без иконки он не касается: у flex-контейнера с\n * единственным ребёнком просветов нет.\n */\n.gr-badge__label {\n display: flex;\n align-items: center;\n gap: 0.25em;\n min-height: 1lh;\n}\n\n.gr-badge__text {\n display: block;\n text-box-trim: trim-both;\n text-box-edge: cap alphabetic;\n /* Шорткат для браузеров с поддержкой нового синтаксиса. */\n text-box: trim-both cap alphabetic;\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;EAyBA,MAAM,QAAQ;EAad,MAAM,eAAe,mBAAmB,WAAW,cAAc,MAAM,MAAM,SAAS;EACtF,MAAM,eAAe,mBAAmB,WAAW,cAAc,MAAM,MAAM,IAAI;EACjF,MAAM,iBAAiB,mBAAmB,WAAW,gBAAgB,MAAM,QAAQ,OAAO;EAK1F,gBAAgB,WAAW,SAAS,GAAG,EAAE,SAAS,OAAO,CAAC;EAE1D,MAAM,YAAY,eAAe;GAC/B,OAAO,aAAa;IAClB,MAAM,aAAa;IACnB,MAAM,MAAM;IACZ,MAAM,aAAa;IACnB,QAAQ,eAAe;GACzB,CAAC;EACH,CAAC;EAED,MAAM,gBAAgB,eAAe,yBAAyB,aAAa,MAAM;;GAoB/E,OAAA,UAAA,GAAA,mBAgBO,QAAA,EAfH,OAAK,eAAA,CAAC,+DACE,UAAA,KAAS,CAAA,EAAA,GAAA,CAEnB,mBAWO,QAXP,YAWO,CATGA,KAAAA,OAAO,QADf,UAAA,GAAA,mBAMO,QAAA;;IAJL,sBAAA;IACC,OAAK,eAAA,CAAG,MAAA,cAAA,GAAgB,cAAA,KAAa,CAAA;GAEtC,GAAA,CAAA,WAAoB,KAAA,QAAA,QAAA,CAAA,GAAA,KAAA,GAAA,IAAA,CAAA,GAAA,CAAA,KAAA,mBAAA,IAAA,IAAA,GAEtB,mBAEO,QAFP,YAEO,CADL,WAAQ,KAAA,QAAA,WAAA,CAAA,GAAA,KAAA,GAAA,IAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,CAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as GrBadge_default } from "./chunks/GrBadge-
|
|
1
|
+
import { t as GrBadge_default } from "./chunks/GrBadge-DBeQXEir.js";
|
|
2
2
|
import { t as grBadgeSafelist } from "../../chunks/safelist-x8USecK8.js";
|
|
3
3
|
import { t as grBadgeConfig } from "../../chunks/config-BscVxZR3.js";
|
|
4
4
|
export { GrBadge_default as GrBadge, GrBadge_default as default, grBadgeConfig, grBadgeSafelist };
|
package/dist/components/GrBadgeWrap/chunks/{GrBadgeWrap-B-A3PRkE.js → GrBadgeWrap-wdfxaXiu.js}
RENAMED
|
@@ -53,6 +53,8 @@ var GrBadgeWrap_default = /* @__PURE__ */ defineComponent({
|
|
|
53
53
|
n: props.value
|
|
54
54
|
}));
|
|
55
55
|
const pulsing = ref(false);
|
|
56
|
+
/** Значение на экране: скрытый счётчик — то же самое, что его отсутствие. */
|
|
57
|
+
const visibleValue = computed(() => showCount.value ? props.value : void 0);
|
|
56
58
|
/**
|
|
57
59
|
* Пока анимация играет, новое изменение её не перезапускает: счётчик меняется
|
|
58
60
|
* пачкой (пять писем за секунду), и «поп» на каждое превратился бы в мельтешение.
|
|
@@ -63,7 +65,7 @@ var GrBadgeWrap_default = /* @__PURE__ */ defineComponent({
|
|
|
63
65
|
* `prefers-reduced-motion` событие тоже приходит — глобальный кламп сжимает
|
|
64
66
|
* анимацию до `0.01ms`, а не выключает её (`docs/motion.md`).
|
|
65
67
|
*/
|
|
66
|
-
watch(
|
|
68
|
+
watch(visibleValue, (next, prev) => {
|
|
67
69
|
if (!props.animate || pulsing.value) return;
|
|
68
70
|
if (isBadgeWrapPulse(prev, next)) pulsing.value = true;
|
|
69
71
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GrBadgeWrap-B-A3PRkE.js","names":[],"sources":["../../../../src/components/GrBadgeWrap/GrBadgeWrap.vue","../../../../src/components/GrBadgeWrap/GrBadgeWrap.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue'\n\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\n\nimport {\n countBaseClass,\n dotBaseClass,\n dotPlacementClass,\n formatBadgeValue,\n isBadgeWrapPulse,\n placementClass,\n rootClass,\n toneClass,\n type GrBadgeWrapPlacement,\n type GrBadgeWrapTone,\n} from './grBadgeWrapStyles'\n\nexport type { GrBadgeWrapPlacement, GrBadgeWrapTone } from './grBadgeWrapStyles'\n\n/**\n * GrBadgeWrap — обёртка, вешающая на потомка счётчик или точку-индикатор.\n *\n * Число объявляется скринридеру: «3» без единицы измерения ничего не значит,\n * поэтому рядом с бейджем идёт визуально скрытая подпись.\n */\nexport interface GrBadgeWrapProps {\n value?: string | number\n /** Точка вместо числа: чистая декорация, если не задан `ariaLabel`. */\n dot?: boolean\n /** Порог: значения больше него рисуются как «{max}+». */\n max?: number\n /** Показывать ли нулевое значение. По умолчанию ноль скрыт. */\n showZero?: boolean\n tone?: GrBadgeWrapTone\n placement?: GrBadgeWrapPlacement\n /** Подпись счётчика для скринридера. Не задана — берётся из локали. */\n ariaLabel?: string\n /** Отмечать ли появление и рост **счётчика** анимацией. Точке анимировать нечего. */\n animate?: boolean\n}\n\nconst props = withDefaults(defineProps<GrBadgeWrapProps>(), {\n value: undefined,\n dot: false,\n max: undefined,\n showZero: false,\n tone: 'danger',\n placement: 'top-right',\n ariaLabel: undefined,\n animate: false,\n})\n\nconst { t } = useGranularityTranslations()\n\nconst showCount = computed(() => {\n if (props.dot || props.value === undefined)\n return false\n return props.value !== 0 || props.showZero\n})\n\n/** Видимый текст: «120» при `max=99` превращается в «99+». */\nconst displayValue = computed(() => formatBadgeValue(props.value ?? '', props.max))\n\n/**\n * Озвучивается настоящее значение, а не обрезанное: «99 плюс» пользователю\n * ничего не говорит, «120 непрочитанных» — говорит.\n */\nconst countLabel = computed(() => props.ariaLabel\n ?? t('gr.badgeWrap.count', '{count} new', { count: props.value, n: props.value }))\n\nconst pulsing = ref(false)\n\n/** Значение на экране: скрытый счётчик — то же самое, что его отсутствие. */\nconst visibleValue = computed(() => showCount.value ? props.value : undefined)\n\n/**\n * Пока анимация играет, новое изменение её не перезапускает: счётчик меняется\n * пачкой (пять писем за секунду), и «поп» на каждое превратился бы в мельтешение.\n * Серия за время анимации даёт ровно один «поп».\n *\n * Флаг отпускает `animationend`, а не таймер: длительность живёт в CSS-токене,\n * и число в скрипте было бы вторым источником правды. Под\n * `prefers-reduced-motion` событие тоже приходит — глобальный кламп сжимает\n * анимацию до `0.01ms`, а не выключает её (`docs/motion.md`).\n */\nwatch(visibleValue, (next, prev) => {\n if (!props.animate || pulsing.value)\n return\n if (isBadgeWrapPulse(prev, next))\n pulsing.value = true\n})\n\n// Ушедший с экрана счётчик `animationend` уже не пришлёт, и без сброса\n// следующее его появление осталось бы без анимации навсегда.\nwatch(showCount, (visible) => {\n if (!visible)\n pulsing.value = false\n})\n\ndefineSlots<{\n /** Элемент, к которому крепится метка. */\n default?: () => any\n}>()\n</script>\n\n<template>\n <span :class=\"rootClass\">\n <slot />\n\n <template v-if=\"dot\">\n <span\n data-gr-badge-wrap-dot\n :class=\"[dotBaseClass, dotPlacementClass[placement], toneClass[tone]]\"\n aria-hidden=\"true\"\n />\n <!-- Точка сама по себе смысла не несёт; подпись появляется только когда\n потребитель объяснил, о чём она. -->\n <span v-if=\"ariaLabel\" data-gr-badge-wrap-label class=\"sr-only\">{{ ariaLabel }}</span>\n </template>\n\n <template v-else-if=\"showCount\">\n <span\n data-gr-badge-wrap-count\n :data-gr-badge-wrap-pop=\"pulsing || undefined\"\n :class=\"[countBaseClass, placementClass[placement], toneClass[tone]]\"\n aria-hidden=\"true\"\n @animationend=\"pulsing = false\"\n >{{ displayValue }}</span>\n <span data-gr-badge-wrap-label class=\"sr-only\">{{ countLabel }}</span>\n </template>\n </span>\n</template>\n\n<style>\n@keyframes gr-badge-wrap-pop {\n 0% {\n transform: scale(0.4);\n }\n 60% {\n transform: scale(1.12);\n }\n 100% {\n transform: scale(1);\n }\n}\n\n/*\n * `animation-fill-mode` не задан намеренно: под `prefers-reduced-motion` анимация\n * доигрывает за `0.01ms` и возвращает элемент в исходный кадр — бейдж на месте\n * и в нужном размере. Именно поэтому компоненту хватает глобального клампа и не\n * нужен собственный reduce-блок (`docs/motion.md`).\n */\n[data-gr-badge-wrap-count][data-gr-badge-wrap-pop] {\n animation: gr-badge-wrap-pop var(--gr-duration-base) var(--gr-ease-out);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue'\n\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\n\nimport {\n countBaseClass,\n dotBaseClass,\n dotPlacementClass,\n formatBadgeValue,\n isBadgeWrapPulse,\n placementClass,\n rootClass,\n toneClass,\n type GrBadgeWrapPlacement,\n type GrBadgeWrapTone,\n} from './grBadgeWrapStyles'\n\nexport type { GrBadgeWrapPlacement, GrBadgeWrapTone } from './grBadgeWrapStyles'\n\n/**\n * GrBadgeWrap — обёртка, вешающая на потомка счётчик или точку-индикатор.\n *\n * Число объявляется скринридеру: «3» без единицы измерения ничего не значит,\n * поэтому рядом с бейджем идёт визуально скрытая подпись.\n */\nexport interface GrBadgeWrapProps {\n value?: string | number\n /** Точка вместо числа: чистая декорация, если не задан `ariaLabel`. */\n dot?: boolean\n /** Порог: значения больше него рисуются как «{max}+». */\n max?: number\n /** Показывать ли нулевое значение. По умолчанию ноль скрыт. */\n showZero?: boolean\n tone?: GrBadgeWrapTone\n placement?: GrBadgeWrapPlacement\n /** Подпись счётчика для скринридера. Не задана — берётся из локали. */\n ariaLabel?: string\n /** Отмечать ли появление и рост **счётчика** анимацией. Точке анимировать нечего. */\n animate?: boolean\n}\n\nconst props = withDefaults(defineProps<GrBadgeWrapProps>(), {\n value: undefined,\n dot: false,\n max: undefined,\n showZero: false,\n tone: 'danger',\n placement: 'top-right',\n ariaLabel: undefined,\n animate: false,\n})\n\nconst { t } = useGranularityTranslations()\n\nconst showCount = computed(() => {\n if (props.dot || props.value === undefined)\n return false\n return props.value !== 0 || props.showZero\n})\n\n/** Видимый текст: «120» при `max=99` превращается в «99+». */\nconst displayValue = computed(() => formatBadgeValue(props.value ?? '', props.max))\n\n/**\n * Озвучивается настоящее значение, а не обрезанное: «99 плюс» пользователю\n * ничего не говорит, «120 непрочитанных» — говорит.\n */\nconst countLabel = computed(() => props.ariaLabel\n ?? t('gr.badgeWrap.count', '{count} new', { count: props.value, n: props.value }))\n\nconst pulsing = ref(false)\n\n/** Значение на экране: скрытый счётчик — то же самое, что его отсутствие. */\nconst visibleValue = computed(() => showCount.value ? props.value : undefined)\n\n/**\n * Пока анимация играет, новое изменение её не перезапускает: счётчик меняется\n * пачкой (пять писем за секунду), и «поп» на каждое превратился бы в мельтешение.\n * Серия за время анимации даёт ровно один «поп».\n *\n * Флаг отпускает `animationend`, а не таймер: длительность живёт в CSS-токене,\n * и число в скрипте было бы вторым источником правды. Под\n * `prefers-reduced-motion` событие тоже приходит — глобальный кламп сжимает\n * анимацию до `0.01ms`, а не выключает её (`docs/motion.md`).\n */\nwatch(visibleValue, (next, prev) => {\n if (!props.animate || pulsing.value)\n return\n if (isBadgeWrapPulse(prev, next))\n pulsing.value = true\n})\n\n// Ушедший с экрана счётчик `animationend` уже не пришлёт, и без сброса\n// следующее его появление осталось бы без анимации навсегда.\nwatch(showCount, (visible) => {\n if (!visible)\n pulsing.value = false\n})\n\ndefineSlots<{\n /** Элемент, к которому крепится метка. */\n default?: () => any\n}>()\n</script>\n\n<template>\n <span :class=\"rootClass\">\n <slot />\n\n <template v-if=\"dot\">\n <span\n data-gr-badge-wrap-dot\n :class=\"[dotBaseClass, dotPlacementClass[placement], toneClass[tone]]\"\n aria-hidden=\"true\"\n />\n <!-- Точка сама по себе смысла не несёт; подпись появляется только когда\n потребитель объяснил, о чём она. -->\n <span v-if=\"ariaLabel\" data-gr-badge-wrap-label class=\"sr-only\">{{ ariaLabel }}</span>\n </template>\n\n <template v-else-if=\"showCount\">\n <span\n data-gr-badge-wrap-count\n :data-gr-badge-wrap-pop=\"pulsing || undefined\"\n :class=\"[countBaseClass, placementClass[placement], toneClass[tone]]\"\n aria-hidden=\"true\"\n @animationend=\"pulsing = false\"\n >{{ displayValue }}</span>\n <span data-gr-badge-wrap-label class=\"sr-only\">{{ countLabel }}</span>\n </template>\n </span>\n</template>\n\n<style>\n@keyframes gr-badge-wrap-pop {\n 0% {\n transform: scale(0.4);\n }\n 60% {\n transform: scale(1.12);\n }\n 100% {\n transform: scale(1);\n }\n}\n\n/*\n * `animation-fill-mode` не задан намеренно: под `prefers-reduced-motion` анимация\n * доигрывает за `0.01ms` и возвращает элемент в исходный кадр — бейдж на месте\n * и в нужном размере. Именно поэтому компоненту хватает глобального клампа и не\n * нужен собственный reduce-блок (`docs/motion.md`).\n */\n[data-gr-badge-wrap-count][data-gr-badge-wrap-pop] {\n animation: gr-badge-wrap-pop var(--gr-duration-base) var(--gr-ease-out);\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0CA,MAAM,QAAQ;EAWd,MAAM,EAAE,MAAM,2BAA2B;EAEzC,MAAM,YAAY,eAAe;GAC/B,IAAI,MAAM,OAAO,MAAM,UAAU,KAAA,GAC/B,OAAO;GACT,OAAO,MAAM,UAAU,KAAK,MAAM;EACpC,CAAC;;EAGD,MAAM,eAAe,eAAe,iBAAiB,MAAM,SAAS,IAAI,MAAM,GAAG,CAAC;;;;;EAMlF,MAAM,aAAa,eAAe,MAAM,aACnC,EAAE,sBAAsB,eAAe;GAAE,OAAO,MAAM;GAAO,GAAG,MAAM;EAAM,CAAC,CAAC;EAEnF,MAAM,UAAU,IAAI,KAAK;;;;;;;;;;;EAezB,MAZqB,eAAe,UAAU,QAAQ,MAAM,QAAQ,KAAA,CAY9D,IAAe,MAAM,SAAS;GAClC,IAAI,CAAC,MAAM,WAAW,QAAQ,OAC5B;GACF,IAAI,iBAAiB,MAAM,IAAI,GAC7B,QAAQ,QAAQ;EACpB,CAAC;EAID,MAAM,YAAY,YAAY;GAC5B,IAAI,CAAC,SACH,QAAQ,QAAQ;EACpB,CAAC;;uBASC,mBAwBO,QAAA,EAxBA,OAAK,eAAE,MAAA,SAAA,CAAS,EAAA,GAAA,CACrB,WAAQ,KAAA,QAAA,SAAA,GAEQ,QAAA,OAAA,UAAA,GAAhB,mBASW,UAAA,EAAA,KAAA,EAAA,GAAA,CART,mBAIE,QAAA;IAHA,0BAAA;IACC,OAAK,eAAA;KAAG,MAAA,YAAA;KAAc,MAAA,iBAAA,CAAiB,CAAC,QAAA;KAAY,MAAA,SAAA,CAAS,CAAC,QAAA;IAAI,CAAA;IACnE,eAAY;gBAIF,QAAA,aAAA,UAAA,GAAZ,mBAAsF,QAAtF,YAAsF,gBAAnB,QAAA,SAAS,GAAA,CAAA,KAAA,mBAAA,IAAA,IAAA,CAAA,GAAA,EAAA,KAGzD,UAAA,SAAA,UAAA,GAArB,mBASW,UAAA,EAAA,KAAA,EAAA,GAAA,CART,mBAM0B,QAAA;IALxB,4BAAA;IACC,0BAAwB,QAAA,SAAW,KAAA;IACnC,OAAK,eAAA;KAAG,MAAA,cAAA;KAAgB,MAAA,cAAA,CAAc,CAAC,QAAA;KAAY,MAAA,SAAA,CAAS,CAAC,QAAA;IAAI,CAAA;IAClE,eAAY;IACX,gBAAY,OAAA,OAAA,OAAA,MAAA,WAAE,QAAA,QAAO;sBACpB,aAAA,KAAY,GAAA,IAAA,UAAA,GAChB,mBAAsE,QAAtE,YAAsE,gBAApB,WAAA,KAAU,GAAA,CAAA,CAAA,GAAA,EAAA,KAAA,mBAAA,IAAA,IAAA,CAAA,GAAA,CAAA"}
|
|
1
|
+
{"version":3,"file":"GrBadgeWrap-wdfxaXiu.js","names":[],"sources":["../../../../src/components/GrBadgeWrap/GrBadgeWrap.vue","../../../../src/components/GrBadgeWrap/GrBadgeWrap.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue'\n\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\n\nimport {\n countBaseClass,\n dotBaseClass,\n dotPlacementClass,\n formatBadgeValue,\n isBadgeWrapPulse,\n placementClass,\n rootClass,\n toneClass,\n type GrBadgeWrapPlacement,\n type GrBadgeWrapTone,\n} from './grBadgeWrapStyles'\n\nexport type { GrBadgeWrapPlacement, GrBadgeWrapTone } from './grBadgeWrapStyles'\n\n/**\n * GrBadgeWrap — обёртка, вешающая на потомка счётчик или точку-индикатор.\n *\n * Число объявляется скринридеру: «3» без единицы измерения ничего не значит,\n * поэтому рядом с бейджем идёт визуально скрытая подпись.\n */\nexport interface GrBadgeWrapProps {\n value?: string | number\n /** Точка вместо числа: чистая декорация, если не задан `ariaLabel`. */\n dot?: boolean\n /** Порог: значения больше него рисуются как «{max}+». */\n max?: number\n /** Показывать ли нулевое значение. По умолчанию ноль скрыт. */\n showZero?: boolean\n tone?: GrBadgeWrapTone\n placement?: GrBadgeWrapPlacement\n /** Подпись счётчика для скринридера. Не задана — берётся из локали. */\n ariaLabel?: string\n /** Отмечать ли появление и рост **счётчика** анимацией. Точке анимировать нечего. */\n animate?: boolean\n}\n\nconst props = withDefaults(defineProps<GrBadgeWrapProps>(), {\n value: undefined,\n dot: false,\n max: undefined,\n showZero: false,\n tone: 'danger',\n placement: 'top-right',\n ariaLabel: undefined,\n animate: false,\n})\n\nconst { t } = useGranularityTranslations()\n\nconst showCount = computed(() => {\n if (props.dot || props.value === undefined)\n return false\n return props.value !== 0 || props.showZero\n})\n\n/** Видимый текст: «120» при `max=99` превращается в «99+». */\nconst displayValue = computed(() => formatBadgeValue(props.value ?? '', props.max))\n\n/**\n * Озвучивается настоящее значение, а не обрезанное: «99 плюс» пользователю\n * ничего не говорит, «120 непрочитанных» — говорит.\n */\nconst countLabel = computed(() => props.ariaLabel\n ?? t('gr.badgeWrap.count', '{count} new', { count: props.value, n: props.value }))\n\nconst pulsing = ref(false)\n\n/** Значение на экране: скрытый счётчик — то же самое, что его отсутствие. */\nconst visibleValue = computed(() => showCount.value ? props.value : undefined)\n\n/**\n * Пока анимация играет, новое изменение её не перезапускает: счётчик меняется\n * пачкой (пять писем за секунду), и «поп» на каждое превратился бы в мельтешение.\n * Серия за время анимации даёт ровно один «поп».\n *\n * Флаг отпускает `animationend`, а не таймер: длительность живёт в CSS-токене,\n * и число в скрипте было бы вторым источником правды. Под\n * `prefers-reduced-motion` событие тоже приходит — глобальный кламп сжимает\n * анимацию до `0.01ms`, а не выключает её (`docs/motion.md`).\n */\nwatch(visibleValue, (next, prev) => {\n if (!props.animate || pulsing.value)\n return\n if (isBadgeWrapPulse(prev, next))\n pulsing.value = true\n})\n\n// Ушедший с экрана счётчик `animationend` уже не пришлёт, и без сброса\n// следующее его появление осталось бы без анимации навсегда.\nwatch(showCount, (visible) => {\n if (!visible)\n pulsing.value = false\n})\n\ndefineSlots<{\n /** Элемент, к которому крепится метка. */\n default?: () => any\n}>()\n</script>\n\n<template>\n <span :class=\"rootClass\">\n <slot />\n\n <template v-if=\"dot\">\n <span\n data-gr-badge-wrap-dot\n :class=\"[dotBaseClass, dotPlacementClass[placement], toneClass[tone]]\"\n aria-hidden=\"true\"\n />\n <!-- Точка сама по себе смысла не несёт; подпись появляется только когда\n потребитель объяснил, о чём она. -->\n <span v-if=\"ariaLabel\" data-gr-badge-wrap-label class=\"sr-only\">{{ ariaLabel }}</span>\n </template>\n\n <template v-else-if=\"showCount\">\n <span\n data-gr-badge-wrap-count\n :data-gr-badge-wrap-pop=\"pulsing || undefined\"\n :class=\"[countBaseClass, placementClass[placement], toneClass[tone]]\"\n aria-hidden=\"true\"\n @animationend=\"pulsing = false\"\n >{{ displayValue }}</span>\n <span data-gr-badge-wrap-label class=\"sr-only\">{{ countLabel }}</span>\n </template>\n </span>\n</template>\n\n<style>\n@keyframes gr-badge-wrap-pop {\n 0% {\n transform: scale(0.4);\n }\n 60% {\n transform: scale(1.12);\n }\n 100% {\n transform: scale(1);\n }\n}\n\n/*\n * `animation-fill-mode` не задан намеренно: под `prefers-reduced-motion` анимация\n * доигрывает за `0.01ms` и возвращает элемент в исходный кадр — бейдж на месте\n * и в нужном размере. Именно поэтому компоненту хватает глобального клампа и не\n * нужен собственный reduce-блок (`docs/motion.md`).\n */\n[data-gr-badge-wrap-count][data-gr-badge-wrap-pop] {\n animation: gr-badge-wrap-pop var(--gr-duration-base) var(--gr-ease-out);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue'\n\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\n\nimport {\n countBaseClass,\n dotBaseClass,\n dotPlacementClass,\n formatBadgeValue,\n isBadgeWrapPulse,\n placementClass,\n rootClass,\n toneClass,\n type GrBadgeWrapPlacement,\n type GrBadgeWrapTone,\n} from './grBadgeWrapStyles'\n\nexport type { GrBadgeWrapPlacement, GrBadgeWrapTone } from './grBadgeWrapStyles'\n\n/**\n * GrBadgeWrap — обёртка, вешающая на потомка счётчик или точку-индикатор.\n *\n * Число объявляется скринридеру: «3» без единицы измерения ничего не значит,\n * поэтому рядом с бейджем идёт визуально скрытая подпись.\n */\nexport interface GrBadgeWrapProps {\n value?: string | number\n /** Точка вместо числа: чистая декорация, если не задан `ariaLabel`. */\n dot?: boolean\n /** Порог: значения больше него рисуются как «{max}+». */\n max?: number\n /** Показывать ли нулевое значение. По умолчанию ноль скрыт. */\n showZero?: boolean\n tone?: GrBadgeWrapTone\n placement?: GrBadgeWrapPlacement\n /** Подпись счётчика для скринридера. Не задана — берётся из локали. */\n ariaLabel?: string\n /** Отмечать ли появление и рост **счётчика** анимацией. Точке анимировать нечего. */\n animate?: boolean\n}\n\nconst props = withDefaults(defineProps<GrBadgeWrapProps>(), {\n value: undefined,\n dot: false,\n max: undefined,\n showZero: false,\n tone: 'danger',\n placement: 'top-right',\n ariaLabel: undefined,\n animate: false,\n})\n\nconst { t } = useGranularityTranslations()\n\nconst showCount = computed(() => {\n if (props.dot || props.value === undefined)\n return false\n return props.value !== 0 || props.showZero\n})\n\n/** Видимый текст: «120» при `max=99` превращается в «99+». */\nconst displayValue = computed(() => formatBadgeValue(props.value ?? '', props.max))\n\n/**\n * Озвучивается настоящее значение, а не обрезанное: «99 плюс» пользователю\n * ничего не говорит, «120 непрочитанных» — говорит.\n */\nconst countLabel = computed(() => props.ariaLabel\n ?? t('gr.badgeWrap.count', '{count} new', { count: props.value, n: props.value }))\n\nconst pulsing = ref(false)\n\n/** Значение на экране: скрытый счётчик — то же самое, что его отсутствие. */\nconst visibleValue = computed(() => showCount.value ? props.value : undefined)\n\n/**\n * Пока анимация играет, новое изменение её не перезапускает: счётчик меняется\n * пачкой (пять писем за секунду), и «поп» на каждое превратился бы в мельтешение.\n * Серия за время анимации даёт ровно один «поп».\n *\n * Флаг отпускает `animationend`, а не таймер: длительность живёт в CSS-токене,\n * и число в скрипте было бы вторым источником правды. Под\n * `prefers-reduced-motion` событие тоже приходит — глобальный кламп сжимает\n * анимацию до `0.01ms`, а не выключает её (`docs/motion.md`).\n */\nwatch(visibleValue, (next, prev) => {\n if (!props.animate || pulsing.value)\n return\n if (isBadgeWrapPulse(prev, next))\n pulsing.value = true\n})\n\n// Ушедший с экрана счётчик `animationend` уже не пришлёт, и без сброса\n// следующее его появление осталось бы без анимации навсегда.\nwatch(showCount, (visible) => {\n if (!visible)\n pulsing.value = false\n})\n\ndefineSlots<{\n /** Элемент, к которому крепится метка. */\n default?: () => any\n}>()\n</script>\n\n<template>\n <span :class=\"rootClass\">\n <slot />\n\n <template v-if=\"dot\">\n <span\n data-gr-badge-wrap-dot\n :class=\"[dotBaseClass, dotPlacementClass[placement], toneClass[tone]]\"\n aria-hidden=\"true\"\n />\n <!-- Точка сама по себе смысла не несёт; подпись появляется только когда\n потребитель объяснил, о чём она. -->\n <span v-if=\"ariaLabel\" data-gr-badge-wrap-label class=\"sr-only\">{{ ariaLabel }}</span>\n </template>\n\n <template v-else-if=\"showCount\">\n <span\n data-gr-badge-wrap-count\n :data-gr-badge-wrap-pop=\"pulsing || undefined\"\n :class=\"[countBaseClass, placementClass[placement], toneClass[tone]]\"\n aria-hidden=\"true\"\n @animationend=\"pulsing = false\"\n >{{ displayValue }}</span>\n <span data-gr-badge-wrap-label class=\"sr-only\">{{ countLabel }}</span>\n </template>\n </span>\n</template>\n\n<style>\n@keyframes gr-badge-wrap-pop {\n 0% {\n transform: scale(0.4);\n }\n 60% {\n transform: scale(1.12);\n }\n 100% {\n transform: scale(1);\n }\n}\n\n/*\n * `animation-fill-mode` не задан намеренно: под `prefers-reduced-motion` анимация\n * доигрывает за `0.01ms` и возвращает элемент в исходный кадр — бейдж на месте\n * и в нужном размере. Именно поэтому компоненту хватает глобального клампа и не\n * нужен собственный reduce-блок (`docs/motion.md`).\n */\n[data-gr-badge-wrap-count][data-gr-badge-wrap-pop] {\n animation: gr-badge-wrap-pop var(--gr-duration-base) var(--gr-ease-out);\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0CA,MAAM,QAAQ;EAWd,MAAM,EAAE,MAAM,2BAA2B;EAEzC,MAAM,YAAY,eAAe;GAC/B,IAAI,MAAM,OAAO,MAAM,UAAU,KAAA,GAC/B,OAAO;GACT,OAAO,MAAM,UAAU,KAAK,MAAM;EACpC,CAAC;;EAGD,MAAM,eAAe,eAAe,iBAAiB,MAAM,SAAS,IAAI,MAAM,GAAG,CAAC;;;;;EAMlF,MAAM,aAAa,eAAe,MAAM,aACnC,EAAE,sBAAsB,eAAe;GAAE,OAAO,MAAM;GAAO,GAAG,MAAM;EAAM,CAAC,CAAC;EAEnF,MAAM,UAAU,IAAI,KAAK;;EAGzB,MAAM,eAAe,eAAe,UAAU,QAAQ,MAAM,QAAQ,KAAA,CAAS;;;;;;;;;;;EAY7E,MAAM,eAAe,MAAM,SAAS;GAClC,IAAI,CAAC,MAAM,WAAW,QAAQ,OAC5B;GACF,IAAI,iBAAiB,MAAM,IAAI,GAC7B,QAAQ,QAAQ;EACpB,CAAC;EAID,MAAM,YAAY,YAAY;GAC5B,IAAI,CAAC,SACH,QAAQ,QAAQ;EACpB,CAAC;;GASC,OAAA,UAAA,GAAA,mBAwBO,QAAA,EAxBA,OAAK,eAAE,MAAA,SAAA,CAAS,EAAA,GAAA,CACrB,WAAQ,KAAA,QAAA,SAAA,GAEQ,QAAA,OAAhB,UAAA,GAAA,mBASW,UAAA,EAAA,KAAA,EAAA,GAAA,CART,mBAIE,QAAA;IAHA,0BAAA;IACC,OAAK,eAAA;KAAG,MAAA,YAAA;KAAc,MAAA,iBAAA,CAAiB,CAAC,QAAA;KAAY,MAAA,SAAA,CAAS,CAAC,QAAA;IAAI,CAAA;IACnE,eAAY;GAIF,GAAA,MAAA,CAAA,GAAA,QAAA,aAAZ,UAAA,GAAA,mBAAsF,QAAtF,YAAsF,gBAAnB,QAAA,SAAS,GAAA,CAAA,KAAA,mBAAA,IAAA,IAAA,CAAA,GAAA,EAAA,KAGzD,UAAA,SAArB,UAAA,GAAA,mBASW,UAAA,EAAA,KAAA,EAAA,GAAA,CART,mBAM0B,QAAA;IALxB,4BAAA;IACC,0BAAwB,QAAA,SAAW,KAAA;IACnC,OAAK,eAAA;KAAG,MAAA,cAAA;KAAgB,MAAA,cAAA,CAAc,CAAC,QAAA;KAAY,MAAA,SAAA,CAAS,CAAC,QAAA;IAAI,CAAA;IAClE,eAAY;IACX,gBAAY,OAAA,OAAA,OAAA,MAAA,WAAE,QAAA,QAAO;GACpB,GAAA,gBAAA,aAAA,KAAY,GAAA,IAAA,UAAA,GAChB,mBAAsE,QAAtE,YAAsE,gBAApB,WAAA,KAAU,GAAA,CAAA,CAAA,GAAA,EAAA,KAAA,mBAAA,IAAA,IAAA,CAAA,GAAA,CAAA"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { n as grBadgeWrapSafelist, o as formatBadgeValue, t as grBadgeWrapConfig } from "../../chunks/config-DwABJHEo.js";
|
|
2
|
-
import { t as GrBadgeWrap_default } from "./chunks/GrBadgeWrap-
|
|
2
|
+
import { t as GrBadgeWrap_default } from "./chunks/GrBadgeWrap-wdfxaXiu.js";
|
|
3
3
|
export { GrBadgeWrap_default as GrBadgeWrap, GrBadgeWrap_default as default, formatBadgeValue, grBadgeWrapConfig, grBadgeWrapSafelist };
|
package/dist/components/GrBottomNav/chunks/{GrBottomNav-wtFatLjB.js → GrBottomNav-nE08pVUJ.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as useGrComponentSize } from "../../../chunks/context-
|
|
1
|
+
import { a as useGrComponentSize } from "../../../chunks/context-CPMRfwVr.js";
|
|
2
2
|
import { n as useGranularityTranslations } from "../../../chunks/granularityI18n-BC5zsj_d.js";
|
|
3
3
|
import { a as grBottomNavListClass, c as itemLabelClass, i as grBottomNavItemClass, o as grBottomNavRootClass, r as grBottomNavIconClass, s as itemBadgeClass } from "../../../chunks/config-DM0lsduD.js";
|
|
4
4
|
import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, defineComponent, markRaw, normalizeClass, openBlock, renderList, renderSlot, resolveDynamicComponent, toDisplayString, unref, withCtx } from "vue";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GrBottomNav-wtFatLjB.js","names":[],"sources":["../../../../src/components/GrBottomNav/GrBottomNav.vue","../../../../src/components/GrBottomNav/GrBottomNav.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, markRaw, type Component } from 'vue'\n\nimport type { GrComponentSize } from '../shared/sizes'\n\nimport { useGrComponentSize } from '../GrConfigProvider/context'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\n\nimport {\n grBottomNavIconClass,\n grBottomNavItemClass,\n grBottomNavListClass,\n grBottomNavRootClass,\n itemBadgeClass,\n itemLabelClass,\n type GrBottomNavHideAbove,\n type GrBottomNavPosition,\n} from './grBottomNavStyles'\n\nimport './defaults'\n\nexport type { GrBottomNavHideAbove, GrBottomNavPosition } from './grBottomNavStyles'\n\n/** Пункт нижней навигации. Кроме подписи и значения всё опционально. */\nexport type GrBottomNavItem = {\n label: string\n value: string\n /** Иконка: класс UnoCSS-иконки (`'i-lucide-home'`) или Vue-компонент. Декоративна. */\n icon?: string | Component\n /** Счётчик поверх пункта. Число озвучивается словами, строка — как есть. */\n badge?: string | number\n /** Подпись счётчика для скринридера, сильнее локали. */\n badgeLabel?: string\n disabled?: boolean\n href?: string\n /** Цель роутерной ссылки: уезжает в компонент из `as`. */\n to?: unknown\n /** Доступное имя пункта, когда подписи недостаточно. */\n ariaLabel?: string\n}\n\n/**\n * GrBottomNav — нижняя навигация приложения: ряд разделов, прижатый к нижней\n * кромке экрана.\n *\n * Активный пункт объявлен `aria-current=\"page\"` и отличается не только цветом:\n * подложкой и весом подписи тоже.\n */\nexport interface GrBottomNavProps {\n modelValue: string\n items: GrBottomNavItem[]\n /** Компонент ссылки для пунктов с `to`: `RouterLink`, `NuxtLink`, `Link` Inertia. */\n as?: string | Component\n /** Брейкпоинт, начиная с которого панель скрывается. `none` — видна всегда. */\n hideAbove?: GrBottomNavHideAbove\n /** `static` вынимает панель из фиксированного слоя — для встраивания в макет. */\n position?: GrBottomNavPosition\n /** Имя лендмарка. Не задано — берётся из локали. */\n ariaLabel?: string\n /**\n * Ступень размера: высота полосы, глиф и кегль подписи. Тач-таргет пункта\n * остаётся 44×44 на любой ступени.\n */\n size?: GrComponentSize\n}\n\nexport interface GrBottomNavEmits {\n (e: 'update:modelValue', value: string): void\n}\n\nconst props = withDefaults(defineProps<GrBottomNavProps>(), {\n as: undefined,\n hideAbove: 'sm',\n position: 'fixed',\n ariaLabel: undefined,\n // `undefined`: «настоящий» дефолт живёт в `useGrComponentSize`, иначе\n // `GrConfigProvider` не отличит заданное значение от подставленного Vue.\n size: undefined,\n})\n\nconst emit = defineEmits<GrBottomNavEmits>()\n\ndefineSlots<{\n /**\n * Содержимое пункта вместо иконки, подписи и счётчика. Корень пункта —\n * тег, `aria-current`, `aria-disabled` и клик — остаётся за компонентом.\n */\n item?: (props: {\n item: GrBottomNavItem\n active: boolean\n disabled: boolean\n badgeLabel: string | undefined\n }) => any\n}>()\n\nconst { t } = useGranularityTranslations()\n\nconst resolvedAriaLabel = computed(() => props.ariaLabel ?? t('gr.bottomNav.label', 'Bottom navigation'))\n\nconst resolvedSize = useGrComponentSize(() => props.size, { component: 'GrBottomNav' })\n\nconst rootClass = computed(() => grBottomNavRootClass({\n position: props.position,\n hideAbove: props.hideAbove,\n}))\n\nconst linkComponent = computed(() => (props.as && typeof props.as !== 'string' ? markRaw(props.as) : props.as))\n\nfunction itemTag(item: GrBottomNavItem): string | Component {\n if (item.disabled)\n return 'span'\n if (item.to !== undefined && linkComponent.value)\n return linkComponent.value\n return item.href ? 'a' : 'button'\n}\n\n/**\n * Счётчик рисуется декоративно, а рядом идёт скрытая подпись: голое «3» без\n * единицы измерения диктору ничего не сообщает.\n */\nfunction badgeLabel(item: GrBottomNavItem): string | undefined {\n if (item.badge == null || item.badge === '')\n return undefined\n if (item.badgeLabel)\n return item.badgeLabel\n if (typeof item.badge === 'number') {\n return t('gr.bottomNav.badge', '{count} new', { count: item.badge, n: item.badge })\n }\n return String(item.badge)\n}\n\nfunction select(item: GrBottomNavItem): void {\n if (item.disabled)\n return\n emit('update:modelValue', item.value)\n}\n</script>\n\n<template>\n <nav :class=\"rootClass\" :aria-label=\"resolvedAriaLabel\">\n <div :class=\"grBottomNavListClass(resolvedSize)\">\n <component\n :is=\"itemTag(item)\"\n v-for=\"item in items\"\n :key=\"item.value\"\n data-gr-bottom-nav-item\n :type=\"itemTag(item) === 'button' ? 'button' : undefined\"\n :href=\"itemTag(item) === 'a' ? item.href : undefined\"\n :to=\"item.to !== undefined && linkComponent ? item.to : undefined\"\n :aria-current=\"item.value === modelValue ? 'page' : undefined\"\n :aria-disabled=\"item.disabled ? 'true' : undefined\"\n :aria-label=\"item.ariaLabel\"\n :class=\"grBottomNavItemClass({ active: item.value === modelValue, disabled: item.disabled ?? false, size: resolvedSize })\"\n @click=\"select(item)\"\n >\n <slot\n name=\"item\"\n :item=\"item\"\n :active=\"item.value === modelValue\"\n :disabled=\"item.disabled ?? false\"\n :badge-label=\"badgeLabel(item)\"\n >\n <component :is=\"item.icon\" v-if=\"item.icon && typeof item.icon !== 'string'\" :class=\"grBottomNavIconClass(resolvedSize)\" aria-hidden=\"true\" />\n <span v-else-if=\"item.icon\" :class=\"[item.icon, grBottomNavIconClass(resolvedSize)]\" aria-hidden=\"true\" />\n\n <span :class=\"itemLabelClass\">{{ item.label }}</span>\n\n <template v-if=\"item.badge != null && item.badge !== ''\">\n <span data-gr-bottom-nav-badge :class=\"itemBadgeClass\" aria-hidden=\"true\">{{ item.badge }}</span>\n <span data-gr-bottom-nav-badge-label class=\"sr-only\">{{ badgeLabel(item) }}</span>\n </template>\n </slot>\n </component>\n </div>\n </nav>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, markRaw, type Component } from 'vue'\n\nimport type { GrComponentSize } from '../shared/sizes'\n\nimport { useGrComponentSize } from '../GrConfigProvider/context'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\n\nimport {\n grBottomNavIconClass,\n grBottomNavItemClass,\n grBottomNavListClass,\n grBottomNavRootClass,\n itemBadgeClass,\n itemLabelClass,\n type GrBottomNavHideAbove,\n type GrBottomNavPosition,\n} from './grBottomNavStyles'\n\nimport './defaults'\n\nexport type { GrBottomNavHideAbove, GrBottomNavPosition } from './grBottomNavStyles'\n\n/** Пункт нижней навигации. Кроме подписи и значения всё опционально. */\nexport type GrBottomNavItem = {\n label: string\n value: string\n /** Иконка: класс UnoCSS-иконки (`'i-lucide-home'`) или Vue-компонент. Декоративна. */\n icon?: string | Component\n /** Счётчик поверх пункта. Число озвучивается словами, строка — как есть. */\n badge?: string | number\n /** Подпись счётчика для скринридера, сильнее локали. */\n badgeLabel?: string\n disabled?: boolean\n href?: string\n /** Цель роутерной ссылки: уезжает в компонент из `as`. */\n to?: unknown\n /** Доступное имя пункта, когда подписи недостаточно. */\n ariaLabel?: string\n}\n\n/**\n * GrBottomNav — нижняя навигация приложения: ряд разделов, прижатый к нижней\n * кромке экрана.\n *\n * Активный пункт объявлен `aria-current=\"page\"` и отличается не только цветом:\n * подложкой и весом подписи тоже.\n */\nexport interface GrBottomNavProps {\n modelValue: string\n items: GrBottomNavItem[]\n /** Компонент ссылки для пунктов с `to`: `RouterLink`, `NuxtLink`, `Link` Inertia. */\n as?: string | Component\n /** Брейкпоинт, начиная с которого панель скрывается. `none` — видна всегда. */\n hideAbove?: GrBottomNavHideAbove\n /** `static` вынимает панель из фиксированного слоя — для встраивания в макет. */\n position?: GrBottomNavPosition\n /** Имя лендмарка. Не задано — берётся из локали. */\n ariaLabel?: string\n /**\n * Ступень размера: высота полосы, глиф и кегль подписи. Тач-таргет пункта\n * остаётся 44×44 на любой ступени.\n */\n size?: GrComponentSize\n}\n\nexport interface GrBottomNavEmits {\n (e: 'update:modelValue', value: string): void\n}\n\nconst props = withDefaults(defineProps<GrBottomNavProps>(), {\n as: undefined,\n hideAbove: 'sm',\n position: 'fixed',\n ariaLabel: undefined,\n // `undefined`: «настоящий» дефолт живёт в `useGrComponentSize`, иначе\n // `GrConfigProvider` не отличит заданное значение от подставленного Vue.\n size: undefined,\n})\n\nconst emit = defineEmits<GrBottomNavEmits>()\n\ndefineSlots<{\n /**\n * Содержимое пункта вместо иконки, подписи и счётчика. Корень пункта —\n * тег, `aria-current`, `aria-disabled` и клик — остаётся за компонентом.\n */\n item?: (props: {\n item: GrBottomNavItem\n active: boolean\n disabled: boolean\n badgeLabel: string | undefined\n }) => any\n}>()\n\nconst { t } = useGranularityTranslations()\n\nconst resolvedAriaLabel = computed(() => props.ariaLabel ?? t('gr.bottomNav.label', 'Bottom navigation'))\n\nconst resolvedSize = useGrComponentSize(() => props.size, { component: 'GrBottomNav' })\n\nconst rootClass = computed(() => grBottomNavRootClass({\n position: props.position,\n hideAbove: props.hideAbove,\n}))\n\nconst linkComponent = computed(() => (props.as && typeof props.as !== 'string' ? markRaw(props.as) : props.as))\n\nfunction itemTag(item: GrBottomNavItem): string | Component {\n if (item.disabled)\n return 'span'\n if (item.to !== undefined && linkComponent.value)\n return linkComponent.value\n return item.href ? 'a' : 'button'\n}\n\n/**\n * Счётчик рисуется декоративно, а рядом идёт скрытая подпись: голое «3» без\n * единицы измерения диктору ничего не сообщает.\n */\nfunction badgeLabel(item: GrBottomNavItem): string | undefined {\n if (item.badge == null || item.badge === '')\n return undefined\n if (item.badgeLabel)\n return item.badgeLabel\n if (typeof item.badge === 'number') {\n return t('gr.bottomNav.badge', '{count} new', { count: item.badge, n: item.badge })\n }\n return String(item.badge)\n}\n\nfunction select(item: GrBottomNavItem): void {\n if (item.disabled)\n return\n emit('update:modelValue', item.value)\n}\n</script>\n\n<template>\n <nav :class=\"rootClass\" :aria-label=\"resolvedAriaLabel\">\n <div :class=\"grBottomNavListClass(resolvedSize)\">\n <component\n :is=\"itemTag(item)\"\n v-for=\"item in items\"\n :key=\"item.value\"\n data-gr-bottom-nav-item\n :type=\"itemTag(item) === 'button' ? 'button' : undefined\"\n :href=\"itemTag(item) === 'a' ? item.href : undefined\"\n :to=\"item.to !== undefined && linkComponent ? item.to : undefined\"\n :aria-current=\"item.value === modelValue ? 'page' : undefined\"\n :aria-disabled=\"item.disabled ? 'true' : undefined\"\n :aria-label=\"item.ariaLabel\"\n :class=\"grBottomNavItemClass({ active: item.value === modelValue, disabled: item.disabled ?? false, size: resolvedSize })\"\n @click=\"select(item)\"\n >\n <slot\n name=\"item\"\n :item=\"item\"\n :active=\"item.value === modelValue\"\n :disabled=\"item.disabled ?? false\"\n :badge-label=\"badgeLabel(item)\"\n >\n <component :is=\"item.icon\" v-if=\"item.icon && typeof item.icon !== 'string'\" :class=\"grBottomNavIconClass(resolvedSize)\" aria-hidden=\"true\" />\n <span v-else-if=\"item.icon\" :class=\"[item.icon, grBottomNavIconClass(resolvedSize)]\" aria-hidden=\"true\" />\n\n <span :class=\"itemLabelClass\">{{ item.label }}</span>\n\n <template v-if=\"item.badge != null && item.badge !== ''\">\n <span data-gr-bottom-nav-badge :class=\"itemBadgeClass\" aria-hidden=\"true\">{{ item.badge }}</span>\n <span data-gr-bottom-nav-badge-label class=\"sr-only\">{{ badgeLabel(item) }}</span>\n </template>\n </slot>\n </component>\n </div>\n </nav>\n</template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"GrBottomNav-nE08pVUJ.js","names":[],"sources":["../../../../src/components/GrBottomNav/GrBottomNav.vue","../../../../src/components/GrBottomNav/GrBottomNav.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, markRaw, type Component } from 'vue'\n\nimport type { GrComponentSize } from '../shared/sizes'\n\nimport { useGrComponentSize } from '../GrConfigProvider/context'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\n\nimport {\n grBottomNavIconClass,\n grBottomNavItemClass,\n grBottomNavListClass,\n grBottomNavRootClass,\n itemBadgeClass,\n itemLabelClass,\n type GrBottomNavHideAbove,\n type GrBottomNavPosition,\n} from './grBottomNavStyles'\n\nimport './defaults'\n\nexport type { GrBottomNavHideAbove, GrBottomNavPosition } from './grBottomNavStyles'\n\n/** Пункт нижней навигации. Кроме подписи и значения всё опционально. */\nexport type GrBottomNavItem = {\n label: string\n value: string\n /** Иконка: класс UnoCSS-иконки (`'i-lucide-home'`) или Vue-компонент. Декоративна. */\n icon?: string | Component\n /** Счётчик поверх пункта. Число озвучивается словами, строка — как есть. */\n badge?: string | number\n /** Подпись счётчика для скринридера, сильнее локали. */\n badgeLabel?: string\n disabled?: boolean\n href?: string\n /** Цель роутерной ссылки: уезжает в компонент из `as`. */\n to?: unknown\n /** Доступное имя пункта, когда подписи недостаточно. */\n ariaLabel?: string\n}\n\n/**\n * GrBottomNav — нижняя навигация приложения: ряд разделов, прижатый к нижней\n * кромке экрана.\n *\n * Активный пункт объявлен `aria-current=\"page\"` и отличается не только цветом:\n * подложкой и весом подписи тоже.\n */\nexport interface GrBottomNavProps {\n modelValue: string\n items: GrBottomNavItem[]\n /** Компонент ссылки для пунктов с `to`: `RouterLink`, `NuxtLink`, `Link` Inertia. */\n as?: string | Component\n /** Брейкпоинт, начиная с которого панель скрывается. `none` — видна всегда. */\n hideAbove?: GrBottomNavHideAbove\n /** `static` вынимает панель из фиксированного слоя — для встраивания в макет. */\n position?: GrBottomNavPosition\n /** Имя лендмарка. Не задано — берётся из локали. */\n ariaLabel?: string\n /**\n * Ступень размера: высота полосы, глиф и кегль подписи. Тач-таргет пункта\n * остаётся 44×44 на любой ступени.\n */\n size?: GrComponentSize\n}\n\nexport interface GrBottomNavEmits {\n (e: 'update:modelValue', value: string): void\n}\n\nconst props = withDefaults(defineProps<GrBottomNavProps>(), {\n as: undefined,\n hideAbove: 'sm',\n position: 'fixed',\n ariaLabel: undefined,\n // `undefined`: «настоящий» дефолт живёт в `useGrComponentSize`, иначе\n // `GrConfigProvider` не отличит заданное значение от подставленного Vue.\n size: undefined,\n})\n\nconst emit = defineEmits<GrBottomNavEmits>()\n\ndefineSlots<{\n /**\n * Содержимое пункта вместо иконки, подписи и счётчика. Корень пункта —\n * тег, `aria-current`, `aria-disabled` и клик — остаётся за компонентом.\n */\n item?: (props: {\n item: GrBottomNavItem\n active: boolean\n disabled: boolean\n badgeLabel: string | undefined\n }) => any\n}>()\n\nconst { t } = useGranularityTranslations()\n\nconst resolvedAriaLabel = computed(() => props.ariaLabel ?? t('gr.bottomNav.label', 'Bottom navigation'))\n\nconst resolvedSize = useGrComponentSize(() => props.size, { component: 'GrBottomNav' })\n\nconst rootClass = computed(() => grBottomNavRootClass({\n position: props.position,\n hideAbove: props.hideAbove,\n}))\n\nconst linkComponent = computed(() => (props.as && typeof props.as !== 'string' ? markRaw(props.as) : props.as))\n\nfunction itemTag(item: GrBottomNavItem): string | Component {\n if (item.disabled)\n return 'span'\n if (item.to !== undefined && linkComponent.value)\n return linkComponent.value\n return item.href ? 'a' : 'button'\n}\n\n/**\n * Счётчик рисуется декоративно, а рядом идёт скрытая подпись: голое «3» без\n * единицы измерения диктору ничего не сообщает.\n */\nfunction badgeLabel(item: GrBottomNavItem): string | undefined {\n if (item.badge == null || item.badge === '')\n return undefined\n if (item.badgeLabel)\n return item.badgeLabel\n if (typeof item.badge === 'number') {\n return t('gr.bottomNav.badge', '{count} new', { count: item.badge, n: item.badge })\n }\n return String(item.badge)\n}\n\nfunction select(item: GrBottomNavItem): void {\n if (item.disabled)\n return\n emit('update:modelValue', item.value)\n}\n</script>\n\n<template>\n <nav :class=\"rootClass\" :aria-label=\"resolvedAriaLabel\">\n <div :class=\"grBottomNavListClass(resolvedSize)\">\n <component\n :is=\"itemTag(item)\"\n v-for=\"item in items\"\n :key=\"item.value\"\n data-gr-bottom-nav-item\n :type=\"itemTag(item) === 'button' ? 'button' : undefined\"\n :href=\"itemTag(item) === 'a' ? item.href : undefined\"\n :to=\"item.to !== undefined && linkComponent ? item.to : undefined\"\n :aria-current=\"item.value === modelValue ? 'page' : undefined\"\n :aria-disabled=\"item.disabled ? 'true' : undefined\"\n :aria-label=\"item.ariaLabel\"\n :class=\"grBottomNavItemClass({ active: item.value === modelValue, disabled: item.disabled ?? false, size: resolvedSize })\"\n @click=\"select(item)\"\n >\n <slot\n name=\"item\"\n :item=\"item\"\n :active=\"item.value === modelValue\"\n :disabled=\"item.disabled ?? false\"\n :badge-label=\"badgeLabel(item)\"\n >\n <component :is=\"item.icon\" v-if=\"item.icon && typeof item.icon !== 'string'\" :class=\"grBottomNavIconClass(resolvedSize)\" aria-hidden=\"true\" />\n <span v-else-if=\"item.icon\" :class=\"[item.icon, grBottomNavIconClass(resolvedSize)]\" aria-hidden=\"true\" />\n\n <span :class=\"itemLabelClass\">{{ item.label }}</span>\n\n <template v-if=\"item.badge != null && item.badge !== ''\">\n <span data-gr-bottom-nav-badge :class=\"itemBadgeClass\" aria-hidden=\"true\">{{ item.badge }}</span>\n <span data-gr-bottom-nav-badge-label class=\"sr-only\">{{ badgeLabel(item) }}</span>\n </template>\n </slot>\n </component>\n </div>\n </nav>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, markRaw, type Component } from 'vue'\n\nimport type { GrComponentSize } from '../shared/sizes'\n\nimport { useGrComponentSize } from '../GrConfigProvider/context'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\n\nimport {\n grBottomNavIconClass,\n grBottomNavItemClass,\n grBottomNavListClass,\n grBottomNavRootClass,\n itemBadgeClass,\n itemLabelClass,\n type GrBottomNavHideAbove,\n type GrBottomNavPosition,\n} from './grBottomNavStyles'\n\nimport './defaults'\n\nexport type { GrBottomNavHideAbove, GrBottomNavPosition } from './grBottomNavStyles'\n\n/** Пункт нижней навигации. Кроме подписи и значения всё опционально. */\nexport type GrBottomNavItem = {\n label: string\n value: string\n /** Иконка: класс UnoCSS-иконки (`'i-lucide-home'`) или Vue-компонент. Декоративна. */\n icon?: string | Component\n /** Счётчик поверх пункта. Число озвучивается словами, строка — как есть. */\n badge?: string | number\n /** Подпись счётчика для скринридера, сильнее локали. */\n badgeLabel?: string\n disabled?: boolean\n href?: string\n /** Цель роутерной ссылки: уезжает в компонент из `as`. */\n to?: unknown\n /** Доступное имя пункта, когда подписи недостаточно. */\n ariaLabel?: string\n}\n\n/**\n * GrBottomNav — нижняя навигация приложения: ряд разделов, прижатый к нижней\n * кромке экрана.\n *\n * Активный пункт объявлен `aria-current=\"page\"` и отличается не только цветом:\n * подложкой и весом подписи тоже.\n */\nexport interface GrBottomNavProps {\n modelValue: string\n items: GrBottomNavItem[]\n /** Компонент ссылки для пунктов с `to`: `RouterLink`, `NuxtLink`, `Link` Inertia. */\n as?: string | Component\n /** Брейкпоинт, начиная с которого панель скрывается. `none` — видна всегда. */\n hideAbove?: GrBottomNavHideAbove\n /** `static` вынимает панель из фиксированного слоя — для встраивания в макет. */\n position?: GrBottomNavPosition\n /** Имя лендмарка. Не задано — берётся из локали. */\n ariaLabel?: string\n /**\n * Ступень размера: высота полосы, глиф и кегль подписи. Тач-таргет пункта\n * остаётся 44×44 на любой ступени.\n */\n size?: GrComponentSize\n}\n\nexport interface GrBottomNavEmits {\n (e: 'update:modelValue', value: string): void\n}\n\nconst props = withDefaults(defineProps<GrBottomNavProps>(), {\n as: undefined,\n hideAbove: 'sm',\n position: 'fixed',\n ariaLabel: undefined,\n // `undefined`: «настоящий» дефолт живёт в `useGrComponentSize`, иначе\n // `GrConfigProvider` не отличит заданное значение от подставленного Vue.\n size: undefined,\n})\n\nconst emit = defineEmits<GrBottomNavEmits>()\n\ndefineSlots<{\n /**\n * Содержимое пункта вместо иконки, подписи и счётчика. Корень пункта —\n * тег, `aria-current`, `aria-disabled` и клик — остаётся за компонентом.\n */\n item?: (props: {\n item: GrBottomNavItem\n active: boolean\n disabled: boolean\n badgeLabel: string | undefined\n }) => any\n}>()\n\nconst { t } = useGranularityTranslations()\n\nconst resolvedAriaLabel = computed(() => props.ariaLabel ?? t('gr.bottomNav.label', 'Bottom navigation'))\n\nconst resolvedSize = useGrComponentSize(() => props.size, { component: 'GrBottomNav' })\n\nconst rootClass = computed(() => grBottomNavRootClass({\n position: props.position,\n hideAbove: props.hideAbove,\n}))\n\nconst linkComponent = computed(() => (props.as && typeof props.as !== 'string' ? markRaw(props.as) : props.as))\n\nfunction itemTag(item: GrBottomNavItem): string | Component {\n if (item.disabled)\n return 'span'\n if (item.to !== undefined && linkComponent.value)\n return linkComponent.value\n return item.href ? 'a' : 'button'\n}\n\n/**\n * Счётчик рисуется декоративно, а рядом идёт скрытая подпись: голое «3» без\n * единицы измерения диктору ничего не сообщает.\n */\nfunction badgeLabel(item: GrBottomNavItem): string | undefined {\n if (item.badge == null || item.badge === '')\n return undefined\n if (item.badgeLabel)\n return item.badgeLabel\n if (typeof item.badge === 'number') {\n return t('gr.bottomNav.badge', '{count} new', { count: item.badge, n: item.badge })\n }\n return String(item.badge)\n}\n\nfunction select(item: GrBottomNavItem): void {\n if (item.disabled)\n return\n emit('update:modelValue', item.value)\n}\n</script>\n\n<template>\n <nav :class=\"rootClass\" :aria-label=\"resolvedAriaLabel\">\n <div :class=\"grBottomNavListClass(resolvedSize)\">\n <component\n :is=\"itemTag(item)\"\n v-for=\"item in items\"\n :key=\"item.value\"\n data-gr-bottom-nav-item\n :type=\"itemTag(item) === 'button' ? 'button' : undefined\"\n :href=\"itemTag(item) === 'a' ? item.href : undefined\"\n :to=\"item.to !== undefined && linkComponent ? item.to : undefined\"\n :aria-current=\"item.value === modelValue ? 'page' : undefined\"\n :aria-disabled=\"item.disabled ? 'true' : undefined\"\n :aria-label=\"item.ariaLabel\"\n :class=\"grBottomNavItemClass({ active: item.value === modelValue, disabled: item.disabled ?? false, size: resolvedSize })\"\n @click=\"select(item)\"\n >\n <slot\n name=\"item\"\n :item=\"item\"\n :active=\"item.value === modelValue\"\n :disabled=\"item.disabled ?? false\"\n :badge-label=\"badgeLabel(item)\"\n >\n <component :is=\"item.icon\" v-if=\"item.icon && typeof item.icon !== 'string'\" :class=\"grBottomNavIconClass(resolvedSize)\" aria-hidden=\"true\" />\n <span v-else-if=\"item.icon\" :class=\"[item.icon, grBottomNavIconClass(resolvedSize)]\" aria-hidden=\"true\" />\n\n <span :class=\"itemLabelClass\">{{ item.label }}</span>\n\n <template v-if=\"item.badge != null && item.badge !== ''\">\n <span data-gr-bottom-nav-badge :class=\"itemBadgeClass\" aria-hidden=\"true\">{{ item.badge }}</span>\n <span data-gr-bottom-nav-badge-label class=\"sr-only\">{{ badgeLabel(item) }}</span>\n </template>\n </slot>\n </component>\n </div>\n </nav>\n</template>\n"],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { n as grBottomNavSafelist, t as grBottomNavConfig } from "../../chunks/config-DM0lsduD.js";
|
|
2
|
-
import { t as GrBottomNav_default } from "./chunks/GrBottomNav-
|
|
2
|
+
import { t as GrBottomNav_default } from "./chunks/GrBottomNav-nE08pVUJ.js";
|
|
3
3
|
export { GrBottomNav_default as GrBottomNav, GrBottomNav_default as default, grBottomNavConfig, grBottomNavSafelist };
|
package/dist/components/GrBreadcrumbs/chunks/{GrBreadcrumbs-DRDNan_n.js → GrBreadcrumbs-DOpwY2EF.js}
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { a as useGrComponentSize, i as useGrComponentProp } from "../../../chunks/context-
|
|
1
|
+
import { a as useGrComponentSize, i as useGrComponentProp } from "../../../chunks/context-CPMRfwVr.js";
|
|
2
2
|
import { n as useGranularityTranslations } from "../../../chunks/granularityI18n-BC5zsj_d.js";
|
|
3
|
-
import { t as GrLink_default } from "../../GrLink/chunks/GrLink-
|
|
3
|
+
import { t as GrLink_default } from "../../GrLink/chunks/GrLink-DwWErumU.js";
|
|
4
4
|
import { n as iconTag, t as iconClass } from "../../../chunks/icon-Dag2tIMs.js";
|
|
5
5
|
import { a as breadcrumbsItemIconClass, c as breadcrumbsLabelHiddenClass, d as breadcrumbsListWrapClass, f as breadcrumbsRootClass, g as resolveBreadcrumbsLayout, h as resolveBreadcrumbsFit, i as breadcrumbsEllipsisClass, l as breadcrumbsListClass, m as breadcrumbsSizeClassBySize, o as breadcrumbsItemWrapClass, p as breadcrumbsSeparatorClass, r as breadcrumbsCurrentClass, s as breadcrumbsLabelClass, u as breadcrumbsListNowrapClass } from "../../../chunks/config-C0Eu8jpG.js";
|
|
6
6
|
import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, defineComponent, nextTick, normalizeClass, onBeforeUnmount, onMounted, openBlock, ref, renderList, renderSlot, resolveDynamicComponent, toDisplayString, unref, watch, withCtx } from "vue";
|
|
@@ -113,7 +113,7 @@ var GrBreadcrumbs_default = /* @__PURE__ */ defineComponent({
|
|
|
113
113
|
function labelClassFor(item) {
|
|
114
114
|
if (!item.iconOnly) return breadcrumbsLabelClass;
|
|
115
115
|
if (!item.icon) {
|
|
116
|
-
if (
|
|
116
|
+
if (process.env.NODE_ENV !== "production") console.warn(`[granularity] GrBreadcrumbs: у пункта «${item.label}» стоит \`iconOnly\` без \`icon\`. Подпись осталась видимой: прятать её, не показав иконку, значит стереть пункт.`);
|
|
117
117
|
return breadcrumbsLabelClass;
|
|
118
118
|
}
|
|
119
119
|
return breadcrumbsLabelHiddenClass;
|