@feugene/granularity 0.36.0 → 0.38.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-DBi0GVce.js.map +1 -1
- 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/devHook-CiqijpNM.js +44 -0
- package/dist/chunks/devHook-CiqijpNM.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-Bp_BCBnr.js → granular-provider-DP2gk0oa.js} +9 -8
- package/dist/chunks/{granular-provider-Bp_BCBnr.js.map → granular-provider-DP2gk0oa.js.map} +1 -1
- package/dist/chunks/{overlayStack-0CZS99Da.js → overlayStack-DH4Z7am1.js} +45 -25
- package/dist/chunks/overlayStack-DH4Z7am1.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-ACRkflzx.js} +3 -3
- package/dist/chunks/{useModalOverlay-BnAGZpcI.js.map → useModalOverlay-ACRkflzx.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-B-L4CWMt.js → GrColorPicker-BwzRLs-i.js} +4 -4
- package/dist/components/GrColorPicker/chunks/{GrColorPicker-B-L4CWMt.js.map → GrColorPicker-BwzRLs-i.js.map} +1 -1
- package/dist/components/GrColorPicker/index.js +1 -1
- package/dist/components/GrCommandPalette/chunks/{GrCommandPalette-8HkYmMVP.js → GrCommandPalette-CnzPuoIM.js} +7 -7
- package/dist/components/GrCommandPalette/chunks/{GrCommandPalette-8HkYmMVP.js.map → GrCommandPalette-CnzPuoIM.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-CZEO2JR4.js → GrConfirmDialog-e15nFI8M.js} +4 -4
- package/dist/components/GrConfirmDialog/chunks/{GrConfirmDialog-CZEO2JR4.js.map → GrConfirmDialog-e15nFI8M.js.map} +1 -1
- package/dist/components/GrConfirmDialog/index.js +1 -1
- package/dist/components/GrContextMenu/chunks/{GrContextMenu-DlFWm0eW.js → GrContextMenu-RpxMHQXH.js} +1 -1
- package/dist/components/GrContextMenu/chunks/{GrContextMenu-DlFWm0eW.js.map → GrContextMenu-RpxMHQXH.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-CKNbnxwO.js → GrDialog-DDz_OEhk.js} +3 -3
- package/dist/components/GrDialog/chunks/{GrDialog-CKNbnxwO.js.map → GrDialog-DDz_OEhk.js.map} +1 -1
- package/dist/components/GrDialog/index.js +1 -1
- package/dist/components/GrDialogService/chunks/{GrDialogService-Ut8iiBQh.js → GrDialogService-BmXiYmUp.js} +9 -8
- package/dist/components/GrDialogService/chunks/{GrDialogService-Ut8iiBQh.js.map → GrDialogService-BmXiYmUp.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-BRMHhvbd.js} +5 -5
- package/dist/components/GrDrawer/chunks/{GrDrawer-xfoy-MCj.js.map → GrDrawer-BRMHhvbd.js.map} +1 -1
- package/dist/components/GrDrawer/index.js +1 -1
- package/dist/components/GrDropdown/chunks/{GrDropdown-7r772-Cq.js → GrDropdown-cLZuZMEY.js} +6 -8
- package/dist/components/GrDropdown/chunks/{GrDropdown-7r772-Cq.js.map → GrDropdown-cLZuZMEY.js.map} +1 -1
- package/dist/components/GrDropdown/index.js +1 -1
- package/dist/components/GrDropdownMenu/chunks/{GrDropdownMenu-DNurbsWc.js → GrDropdownMenu-Dxkz_ry4.js} +1 -1
- package/dist/components/GrDropdownMenu/chunks/{GrDropdownMenu-DNurbsWc.js.map → GrDropdownMenu-Dxkz_ry4.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-C0ROpmOY.js → GrFileUpload-BwMR71zN.js} +4 -4
- package/dist/components/GrFileUpload/chunks/{GrFileUpload-C0ROpmOY.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-CcduIFsa.js} +2 -4
- package/dist/components/GrImageViewer/chunks/{GrImageViewer--BU8yrfx.js.map → GrImageViewer-CcduIFsa.js.map} +1 -1
- package/dist/components/GrImageViewer/index.js +1 -1
- package/dist/components/GrInput/chunks/{GrInput-CJ7eu3fR.js → GrInput-TFeBm3gQ.js} +1 -1
- package/dist/components/GrInput/chunks/{GrInput-CJ7eu3fR.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-BXG7DdTe.js → GrJsonViewer-CdtmUpZ3.js} +6 -6
- package/dist/components/GrJsonViewer/chunks/{GrJsonViewer-BXG7DdTe.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-DixnhJcu.js → GrModal-Cm0mtSXk.js} +4 -4
- package/dist/components/GrModal/chunks/{GrModal-DixnhJcu.js.map → GrModal-Cm0mtSXk.js.map} +1 -1
- package/dist/components/GrModal/index.js +1 -1
- 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-68iyAwQz.js → GrPagination-DhbNZHEF.js} +4 -4
- package/dist/components/GrPagination/chunks/{GrPagination-68iyAwQz.js.map → GrPagination-DhbNZHEF.js.map} +1 -1
- package/dist/components/GrPagination/index.js +1 -1
- package/dist/components/GrPopover/chunks/{GrPopover-DEFxDffj.js → GrPopover-CcWvr1ZA.js} +3 -3
- package/dist/components/GrPopover/chunks/{GrPopover-DEFxDffj.js.map → GrPopover-CcWvr1ZA.js.map} +1 -1
- package/dist/components/GrPopover/index.js +2 -2
- package/dist/components/GrProgressBar/chunks/{GrProgressBar-Cd7AaJtR.js → GrProgressBar-C3NRBqIP.js} +2 -2
- package/dist/components/GrProgressBar/chunks/{GrProgressBar-Cd7AaJtR.js.map → GrProgressBar-C3NRBqIP.js.map} +1 -1
- 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-Ckeombia.js → GrPromptDialog-8RxQsOQ_.js} +8 -8
- package/dist/components/GrPromptDialog/chunks/{GrPromptDialog-Ckeombia.js.map → GrPromptDialog-8RxQsOQ_.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-Bm3Jugx8.js → GrSelect-Do1iAyp1.js} +6 -6
- package/dist/components/GrSelect/chunks/{GrSelect-Bm3Jugx8.js.map → GrSelect-Do1iAyp1.js.map} +1 -1
- package/dist/components/GrSelect/index.js +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-DM6W6U9c.js → GrSlider-Db-jACXz.js} +6 -4
- package/dist/components/GrSlider/chunks/{GrSlider-DM6W6U9c.js.map → GrSlider-Db-jACXz.js.map} +1 -1
- 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-BoLkXw7F.js → GrStatistic-C1_nY4Gc.js} +2 -2
- package/dist/components/GrStatistic/chunks/{GrStatistic-BoLkXw7F.js.map → GrStatistic-C1_nY4Gc.js.map} +1 -1
- package/dist/components/GrStatistic/index.js +1 -1
- package/dist/components/GrSteps/chunks/{GrSteps-CpGHXLOc.js → GrSteps-DXj7m-WO.js} +2 -2
- package/dist/components/GrSteps/chunks/{GrSteps-CpGHXLOc.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-MGsyvkJV.js → GrTreeSelect-DurwZ7Cz.js} +4 -4
- package/dist/components/GrTreeSelect/chunks/{GrTreeSelect-MGsyvkJV.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 +35 -6
- package/dist/composables/useOverlayLayer.js.map +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 +26 -6
- 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 +86 -86
- 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/composables/internal/overlayStack.d.ts +11 -0
- package/dist/types/internal/devHook.d.ts +119 -0
- package/dist/vue/index.js +2 -2
- package/dist/vue/index.js.map +1 -1
- package/dist/web-types.json +1 -1
- package/package.json +16 -16
- 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/overlayStack-0CZS99Da.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
|
@@ -6,7 +6,7 @@ import { t as grBadgeWrapConfig } from "./config-DwABJHEo.js";
|
|
|
6
6
|
import { t as grBottomNavConfig } from "./config-DM0lsduD.js";
|
|
7
7
|
import { t as grBreadcrumbsConfig } from "./config-C0Eu8jpG.js";
|
|
8
8
|
import { t as grButtonConfig } from "./config-87fszqnD.js";
|
|
9
|
-
import { t as grButtonGroupConfig } from "./config-
|
|
9
|
+
import { t as grButtonGroupConfig } from "./config-DBmdgoVf.js";
|
|
10
10
|
import { t as grCardConfig } from "./config-DUbbGcfw.js";
|
|
11
11
|
import { t as grCheckboxConfig } from "./config-DZCUPHPU.js";
|
|
12
12
|
import { t as grCheckboxGroupConfig } from "./config-BuGlNPE9.js";
|
|
@@ -23,7 +23,7 @@ import { t as grContextMenuConfig } from "./config-CsCUuukB.js";
|
|
|
23
23
|
import { t as grDataTableConfig } from "./config-DeyT9dJl.js";
|
|
24
24
|
import { t as grValueConfig } from "./config-Z5LeUXys.js";
|
|
25
25
|
import { t as grDeltaConfig } from "./config-CjWOTgLL.js";
|
|
26
|
-
import { t as grDescriptionListConfig } from "./config-
|
|
26
|
+
import { t as grDescriptionListConfig } from "./config-CnYdE3HZ.js";
|
|
27
27
|
import { t as grDialogSafelist } from "./safelist-Y3zrlhOa.js";
|
|
28
28
|
import { t as grDialogServiceConfig } from "./config-CjXjhphs.js";
|
|
29
29
|
import { t as grDividerConfig } from "./config-D82r782v.js";
|
|
@@ -40,20 +40,20 @@ import { t as grFormSectionConfig } from "./config-BEO7brpO.js";
|
|
|
40
40
|
import { t as grImageViewerConfig } from "./config-BDSaD-5p.js";
|
|
41
41
|
import { t as grInputConfig } from "./config-CIkdsWUk.js";
|
|
42
42
|
import { t as grInputTagConfig } from "./config-BqT6PMzO.js";
|
|
43
|
-
import { t as grJsonViewerConfig } from "./config-
|
|
43
|
+
import { t as grJsonViewerConfig } from "./config-DpAYidyY.js";
|
|
44
44
|
import { t as grKbdConfig } from "./config-BRESvs9g.js";
|
|
45
|
-
import { t as grLinkConfig } from "./config-
|
|
45
|
+
import { t as grLinkConfig } from "./config-CQLNjc9X.js";
|
|
46
46
|
import { t as grListConfig } from "./config-D0W8mGFD.js";
|
|
47
47
|
import { t as grLoadingConfig } from "./config-Bjn30smH.js";
|
|
48
48
|
import { t as grModalConfig } from "./config-DBi0GVce.js";
|
|
49
49
|
import { t as grNavbarConfig } from "./config-2ZHRsdOc.js";
|
|
50
|
-
import { t as grNumberInputConfig } from "./config-MmPym-
|
|
50
|
+
import { t as grNumberInputConfig } from "./config-MmPym-Z7.js";
|
|
51
51
|
import { t as grPaginationConfig } from "./config-CjKpUcmy.js";
|
|
52
|
-
import { t as grPopoverConfig } from "./config-
|
|
52
|
+
import { t as grPopoverConfig } from "./config-DVCNvhIG.js";
|
|
53
53
|
import { t as grProgressBarConfig } from "./config-DWL81-aM.js";
|
|
54
54
|
import { t as grProgressCircleConfig } from "./config-CJzmDHfI.js";
|
|
55
55
|
import { t as grPromptDialogConfig } from "./config-C0Ea9ePP.js";
|
|
56
|
-
import { t as grRadioConfig } from "./config-
|
|
56
|
+
import { t as grRadioConfig } from "./config-BUNxHnEz.js";
|
|
57
57
|
import { t as grRadioGroupConfig } from "./config-QaIc_gRa.js";
|
|
58
58
|
import { t as grRatingConfig } from "./config-DRbojEzO.js";
|
|
59
59
|
import { t as grSegmentedConfig } from "./config-rLkc9Zn2.js";
|
|
@@ -200,11 +200,12 @@ var baseComponents = Object.values(granularityComponentConfigs);
|
|
|
200
200
|
*/
|
|
201
201
|
function createGranularityProvider(overrides = []) {
|
|
202
202
|
const overrideByName = new Map(overrides.map((component) => [component.name, component]));
|
|
203
|
+
const components = [...baseComponents.map((component) => overrideByName.get(component.name) ?? component), ...overrides.filter((component) => !baseComponents.some((base) => base.name === component.name))];
|
|
203
204
|
return defineGranularProvider({
|
|
204
205
|
id: GRANULARITY_PROVIDER_ID,
|
|
205
206
|
contractVersion: 1,
|
|
206
207
|
packageBaseUrl,
|
|
207
|
-
components
|
|
208
|
+
components,
|
|
208
209
|
theme
|
|
209
210
|
});
|
|
210
211
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"granular-provider-Bp_BCBnr.js","names":[],"sources":["../../src/components/GrDialog/config.ts","../../src/components/GrResponseErrorBanner/config.ts","../../src/granular-provider/shared.ts","../../src/granular-provider/index.ts"],"sourcesContent":["import { defineGranularComponent } from '@feugene/unocss-preset-granular/contract'\n\nimport { grDialogSafelist } from './safelist'\n\nexport const grDialogConfig = defineGranularComponent(import.meta.url, {\n name: 'GrDialog',\n dependencies: ['GrButton', 'GrModal'],\n safelist: grDialogSafelist,\n})\n","import { defineGranularComponent } from '@feugene/unocss-preset-granular/contract'\n\nexport const grResponseErrorBannerConfig = defineGranularComponent(import.meta.url, {\n name: 'GrResponseErrorBanner',\n dependencies: ['GrAlert', 'GrButton'],\n})\n","// `id`, `theme.*`, `packageBaseUrl` и реестр компонентов провайдера.\n//\n// Все `new URL('../styles/...', import.meta.url)` обязаны лежать именно здесь:\n// `shared.ts` в одной директории с `index.ts` / `node.ts`, поэтому\n// относительные пути совпадают. Для браузера безопасно — бандлеры\n// транслируют такие литералы в статические asset-URL.\n//\n// `apps/showcase/scripts/generate-component-api.mjs` читает список компонентов\n// из `Object.keys(granularityComponentConfigs)` через vite SSR.\nimport {\n defineGranularProvider,\n type GranularComponentDescriptor,\n type GranularProvider,\n resolvePackageBaseUrl,\n} from '@feugene/unocss-preset-granular/contract'\n// <granularity:components:imports> — блок генерируется `yarn generate:registry`\nimport { grAlertConfig } from '../components/GrAlert/config'\nimport { grAutocompleteConfig } from '../components/GrAutocomplete/config'\nimport { grAvatarConfig } from '../components/GrAvatar/config'\nimport { grBadgeConfig } from '../components/GrBadge/config'\nimport { grBadgeWrapConfig } from '../components/GrBadgeWrap/config'\nimport { grBottomNavConfig } from '../components/GrBottomNav/config'\nimport { grBreadcrumbsConfig } from '../components/GrBreadcrumbs/config'\nimport { grButtonConfig } from '../components/GrButton/config'\nimport { grButtonGroupConfig } from '../components/GrButtonGroup/config'\nimport { grCardConfig } from '../components/GrCard/config'\nimport { grCheckboxConfig } from '../components/GrCheckbox/config'\nimport { grCheckboxGroupConfig } from '../components/GrCheckboxGroup/config'\nimport { grChipConfig } from '../components/GrChip/config'\nimport { grChipGroupConfig } from '../components/GrChipGroup/config'\nimport { grCodeBlockConfig } from '../components/GrCodeBlock/config'\nimport { grCollapseConfig } from '../components/GrCollapse/config'\nimport { grColorPickerConfig } from '../components/GrColorPicker/config'\nimport { grCommandPaletteConfig } from '../components/GrCommandPalette/config'\nimport { grConfigProviderConfig } from '../components/GrConfigProvider/config'\nimport { grConfirmDialogConfig } from '../components/GrConfirmDialog/config'\nimport { grContextMenuConfig } from '../components/GrContextMenu/config'\nimport { grDataTableConfig } from '../components/GrDataTable/config'\nimport { grDeltaConfig } from '../components/GrDelta/config'\nimport { grDescriptionListConfig } from '../components/GrDescriptionList/config'\nimport { grDialogConfig } from '../components/GrDialog/config'\nimport { grDialogServiceConfig } from '../components/GrDialogService/config'\nimport { grDividerConfig } from '../components/GrDivider/config'\nimport { grDrawerConfig } from '../components/GrDrawer/config'\nimport { grDropdownConfig } from '../components/GrDropdown/config'\nimport { grDropdownMenuConfig } from '../components/GrDropdownMenu/config'\nimport { grEmptyStateConfig } from '../components/GrEmptyState/config'\nimport { grFilePreviewConfig } from '../components/GrFilePreview/config'\nimport { grFileUploadConfig } from '../components/GrFileUpload/config'\nimport { grFormConfig } from '../components/GrForm/config'\nimport { grFormFieldConfig } from '../components/GrFormField/config'\nimport { grFormFileConfig } from '../components/GrFormFile/config'\nimport { grFormSectionConfig } from '../components/GrFormSection/config'\nimport { grIconConfig } from '../components/GrIcon/config'\nimport { grImageViewerConfig } from '../components/GrImageViewer/config'\nimport { grInputConfig } from '../components/GrInput/config'\nimport { grInputTagConfig } from '../components/GrInputTag/config'\nimport { grJsonViewerConfig } from '../components/GrJsonViewer/config'\nimport { grKbdConfig } from '../components/GrKbd/config'\nimport { grLinkConfig } from '../components/GrLink/config'\nimport { grListConfig } from '../components/GrList/config'\nimport { grLoadingConfig } from '../components/GrLoading/config'\nimport { grModalConfig } from '../components/GrModal/config'\nimport { grNavbarConfig } from '../components/GrNavbar/config'\nimport { grNumberInputConfig } from '../components/GrNumberInput/config'\nimport { grPaginationConfig } from '../components/GrPagination/config'\nimport { grPopoverConfig } from '../components/GrPopover/config'\nimport { grProgressBarConfig } from '../components/GrProgressBar/config'\nimport { grProgressCircleConfig } from '../components/GrProgressCircle/config'\nimport { grPromptDialogConfig } from '../components/GrPromptDialog/config'\nimport { grRadioConfig } from '../components/GrRadio/config'\nimport { grRadioGroupConfig } from '../components/GrRadioGroup/config'\nimport { grRatingConfig } from '../components/GrRating/config'\nimport { grResponseErrorBannerConfig } from '../components/GrResponseErrorBanner/config'\nimport { grSegmentedConfig } from '../components/GrSegmented/config'\nimport { grSelectConfig } from '../components/GrSelect/config'\nimport { grSidebarConfig } from '../components/GrSidebar/config'\nimport { grSkeletonConfig } from '../components/GrSkeleton/config'\nimport { grSliderConfig } from '../components/GrSlider/config'\nimport { grSortableListConfig } from '../components/GrSortableList/config'\nimport { grSplitterConfig } from '../components/GrSplitter/config'\nimport { grStatisticConfig } from '../components/GrStatistic/config'\nimport { grStepsConfig } from '../components/GrSteps/config'\nimport { grSwitchConfig } from '../components/GrSwitch/config'\nimport { grTableConfig } from '../components/GrTable/config'\nimport { grTabPanelsConfig } from '../components/GrTabPanels/config'\nimport { grTabsConfig } from '../components/GrTabs/config'\nimport { grTextareaConfig } from '../components/GrTextarea/config'\nimport { grTimelineConfig } from '../components/GrTimeline/config'\nimport { grToasterConfig } from '../components/GrToaster/config'\nimport { grTooltipConfig } from '../components/GrTooltip/config'\nimport { grTreeConfig } from '../components/GrTree/config'\nimport { grTreeSelectConfig } from '../components/GrTreeSelect/config'\nimport { grValueConfig } from '../components/GrValue/config'\n// </granularity:components:imports>\n\n/** Идентификатор провайдера — совпадает с именем пакета. */\nexport const GRANULARITY_PROVIDER_ID = '@feugene/granularity'\n\n// Не заменять на `new URL('..', import.meta.url)`: Vite и rolldown распознают\n// этот литерал и подставляют `data:`-URL, после чего scan-директории пустеют.\nconst packageBaseUrl = resolvePackageBaseUrl(import.meta.url)\n\n/** Встроенные темы пакета. Единственный источник правды о списке тем. */\nexport const granularityThemeNames = ['light', 'dark'] as const\nexport type GranularityThemeName = (typeof granularityThemeNames)[number]\n\n/** Темы, активные по умолчанию, если окружение не переопределяет выбор. */\nexport const granularityDefaultThemes: readonly GranularityThemeName[] = ['light']\n\nconst theme = {\n baseCssUrl: new URL('../styles/base.css', import.meta.url).href,\n tokensCssUrl: new URL('../styles/tokens.css', import.meta.url).href,\n themes: {\n light: new URL('../styles/themes/light.css', import.meta.url).href,\n dark: new URL('../styles/themes/dark.css', import.meta.url).href,\n },\n defaultThemes: granularityDefaultThemes,\n} as const\n\n/**\n * Реестр публичных компонентов. Ключи совпадают с subpath-экспортом\n * `@feugene/granularity/components/<Name>`.\n */\nexport const granularityComponentConfigs = {\n // <granularity:components:registry> — блок генерируется `yarn generate:registry`\n GrAlert: grAlertConfig,\n GrAutocomplete: grAutocompleteConfig,\n GrAvatar: grAvatarConfig,\n GrBadge: grBadgeConfig,\n GrBadgeWrap: grBadgeWrapConfig,\n GrBottomNav: grBottomNavConfig,\n GrBreadcrumbs: grBreadcrumbsConfig,\n GrButton: grButtonConfig,\n GrButtonGroup: grButtonGroupConfig,\n GrCard: grCardConfig,\n GrCheckbox: grCheckboxConfig,\n GrCheckboxGroup: grCheckboxGroupConfig,\n GrChip: grChipConfig,\n GrChipGroup: grChipGroupConfig,\n GrCodeBlock: grCodeBlockConfig,\n GrCollapse: grCollapseConfig,\n GrColorPicker: grColorPickerConfig,\n GrCommandPalette: grCommandPaletteConfig,\n GrConfigProvider: grConfigProviderConfig,\n GrConfirmDialog: grConfirmDialogConfig,\n GrContextMenu: grContextMenuConfig,\n GrDataTable: grDataTableConfig,\n GrDelta: grDeltaConfig,\n GrDescriptionList: grDescriptionListConfig,\n GrDialog: grDialogConfig,\n GrDialogService: grDialogServiceConfig,\n GrDivider: grDividerConfig,\n GrDrawer: grDrawerConfig,\n GrDropdown: grDropdownConfig,\n GrDropdownMenu: grDropdownMenuConfig,\n GrEmptyState: grEmptyStateConfig,\n GrFilePreview: grFilePreviewConfig,\n GrFileUpload: grFileUploadConfig,\n GrForm: grFormConfig,\n GrFormField: grFormFieldConfig,\n GrFormFile: grFormFileConfig,\n GrFormSection: grFormSectionConfig,\n GrIcon: grIconConfig,\n GrImageViewer: grImageViewerConfig,\n GrInput: grInputConfig,\n GrInputTag: grInputTagConfig,\n GrJsonViewer: grJsonViewerConfig,\n GrKbd: grKbdConfig,\n GrLink: grLinkConfig,\n GrList: grListConfig,\n GrLoading: grLoadingConfig,\n GrModal: grModalConfig,\n GrNavbar: grNavbarConfig,\n GrNumberInput: grNumberInputConfig,\n GrPagination: grPaginationConfig,\n GrPopover: grPopoverConfig,\n GrProgressBar: grProgressBarConfig,\n GrProgressCircle: grProgressCircleConfig,\n GrPromptDialog: grPromptDialogConfig,\n GrRadio: grRadioConfig,\n GrRadioGroup: grRadioGroupConfig,\n GrRating: grRatingConfig,\n GrResponseErrorBanner: grResponseErrorBannerConfig,\n GrSegmented: grSegmentedConfig,\n GrSelect: grSelectConfig,\n GrSidebar: grSidebarConfig,\n GrSkeleton: grSkeletonConfig,\n GrSlider: grSliderConfig,\n GrSortableList: grSortableListConfig,\n GrSplitter: grSplitterConfig,\n GrStatistic: grStatisticConfig,\n GrSteps: grStepsConfig,\n GrSwitch: grSwitchConfig,\n GrTable: grTableConfig,\n GrTabPanels: grTabPanelsConfig,\n GrTabs: grTabsConfig,\n GrTextarea: grTextareaConfig,\n GrTimeline: grTimelineConfig,\n GrToaster: grToasterConfig,\n GrTooltip: grTooltipConfig,\n GrTree: grTreeConfig,\n GrTreeSelect: grTreeSelectConfig,\n GrValue: grValueConfig,\n // </granularity:components:registry>\n}\n\nexport type GranularityComponentName = keyof typeof granularityComponentConfigs\n\n/** Базовый набор компонентов в порядке реестра. */\nconst baseComponents: readonly GranularComponentDescriptor[] = Object.values(\n granularityComponentConfigs,\n)\n\n/**\n * Собирает granular-provider пакета.\n *\n * `overrides` — точка расширения для потребителя: дескриптор с именем из\n * базового реестра заменяет его, остальные дописываются в конец.\n */\nexport function createGranularityProvider(\n overrides: readonly GranularComponentDescriptor[] = [],\n): GranularProvider {\n const overrideByName = new Map(\n overrides.map(component => [component.name, component]),\n )\n const components: GranularComponentDescriptor[] = [\n ...baseComponents.map(component => overrideByName.get(component.name) ?? component),\n ...overrides.filter(component => !baseComponents.some(base => base.name === component.name)),\n ]\n\n return defineGranularProvider({\n id: GRANULARITY_PROVIDER_ID,\n contractVersion: 1,\n packageBaseUrl,\n components,\n theme,\n })\n}\n","import { createGranularityProvider } from './shared'\n\nexport * from './shared'\n\nexport const granularityProvider = createGranularityProvider()\n\nexport default granularityProvider\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,IAAa,iBAAiB,wBAAwB,OAAO,KAAK,KAAK;CACrE,MAAM;CACN,cAAc,CAAC,YAAY,SAAS;CACpC,UAAU;AACZ,CAAC;;;ACND,IAAa,8BAA8B,wBAAwB,OAAO,KAAK,KAAK;CAClF,MAAM;CACN,cAAc,CAAC,WAAW,UAAU;AACtC,CAAC;;;;AC4FD,IAAa,0BAA0B;AAIvC,IAAM,iBAAiB,sBAAsB,OAAO,KAAK,GAAG;;AAG5D,IAAa,wBAAwB,CAAC,SAAS,MAAM;;AAIrD,IAAa,2BAA4D,CAAC,OAAO;AAEjF,IAAM,QAAQ;CACZ,YAAY,IAAA,IAAA,q5KAAA,KAAA,OAAA,KAAA,GAAA,CAA8C,CAAC;CAC3D,cAAc,IAAA,IAAA,65YAAA,KAAA,OAAA,KAAA,GAAA,CAAgD,CAAC;CAC/D,QAAQ;EACN,OAAO,IAAA,IAAA,iyYAAA,KAAA,OAAA,KAAA,GAAA,CAAsD,CAAC;EAC9D,MAAM,IAAA,IAAA,y/SAAA,KAAA,OAAA,KAAA,GAAA,CAAqD,CAAC;CAC9D;CACA,eAAe;AACjB;;;;;AAMA,IAAa,8BAA8B;CAEzC,SAAS;CACT,gBAAgB;CAChB,UAAU;CACV,SAAS;CACT,aAAa;CACb,aAAa;CACb,eAAe;CACf,UAAU;CACV,eAAe;CACf,QAAQ;CACR,YAAY;CACZ,iBAAiB;CACjB,QAAQ;CACR,aAAa;CACb,aAAa;CACb,YAAY;CACZ,eAAe;CACf,kBAAkB;CAClB,kBAAkB;CAClB,iBAAiB;CACjB,eAAe;CACf,aAAa;CACb,SAAS;CACT,mBAAmB;CACnB,UAAU;CACV,iBAAiB;CACjB,WAAW;CACX,UAAU;CACV,YAAY;CACZ,gBAAgB;CAChB,cAAc;CACd,eAAe;CACf,cAAc;CACd,QAAQ;CACR,aAAa;CACb,YAAY;CACZ,eAAe;CACf,QAAQ;CACR,eAAe;CACf,SAAS;CACT,YAAY;CACZ,cAAc;CACd,OAAO;CACP,QAAQ;CACR,QAAQ;CACR,WAAW;CACX,SAAS;CACT,UAAU;CACV,eAAe;CACf,cAAc;CACd,WAAW;CACX,eAAe;CACf,kBAAkB;CAClB,gBAAgB;CAChB,SAAS;CACT,cAAc;CACd,UAAU;CACV,uBAAuB;CACvB,aAAa;CACb,UAAU;CACV,WAAW;CACX,YAAY;CACZ,UAAU;CACV,gBAAgB;CAChB,YAAY;CACZ,aAAa;CACb,SAAS;CACT,UAAU;CACV,SAAS;CACT,aAAa;CACb,QAAQ;CACR,YAAY;CACZ,YAAY;CACZ,WAAW;CACX,WAAW;CACX,QAAQ;CACR,cAAc;CACd,SAAS;AAEX;;AAKA,IAAM,iBAAyD,OAAO,OACpE,2BACF;;;;;;;AAQA,SAAgB,0BACd,YAAoD,CAAC,GACnC;CAClB,MAAM,iBAAiB,IAAI,IACzB,UAAU,KAAI,cAAa,CAAC,UAAU,MAAM,SAAS,CAAC,CACxD;CAMA,OAAO,uBAAuB;EAC5B,IAAI;EACJ,iBAAiB;EACjB;EACA,aARA,GAAG,eAAe,KAAI,cAAa,eAAe,IAAI,UAAU,IAAI,KAAK,SAAS,GAClF,GAAG,UAAU,QAAO,cAAa,CAAC,eAAe,MAAK,SAAQ,KAAK,SAAS,UAAU,IAAI,CAAC,CAO3F;EACA;CACF,CAAC;AACH;;;AC1OA,IAAa,sBAAsB,0BAA0B"}
|
|
1
|
+
{"version":3,"file":"granular-provider-DP2gk0oa.js","names":[],"sources":["../../src/components/GrDialog/config.ts","../../src/components/GrResponseErrorBanner/config.ts","../../src/granular-provider/shared.ts","../../src/granular-provider/index.ts"],"sourcesContent":["import { defineGranularComponent } from '@feugene/unocss-preset-granular/contract'\n\nimport { grDialogSafelist } from './safelist'\n\nexport const grDialogConfig = defineGranularComponent(import.meta.url, {\n name: 'GrDialog',\n dependencies: ['GrButton', 'GrModal'],\n safelist: grDialogSafelist,\n})\n","import { defineGranularComponent } from '@feugene/unocss-preset-granular/contract'\n\nexport const grResponseErrorBannerConfig = defineGranularComponent(import.meta.url, {\n name: 'GrResponseErrorBanner',\n dependencies: ['GrAlert', 'GrButton'],\n})\n","// `id`, `theme.*`, `packageBaseUrl` и реестр компонентов провайдера.\n//\n// Все `new URL('../styles/...', import.meta.url)` обязаны лежать именно здесь:\n// `shared.ts` в одной директории с `index.ts` / `node.ts`, поэтому\n// относительные пути совпадают. Для браузера безопасно — бандлеры\n// транслируют такие литералы в статические asset-URL.\n//\n// `apps/showcase/scripts/generate-component-api.mjs` читает список компонентов\n// из `Object.keys(granularityComponentConfigs)` через vite SSR.\nimport {\n defineGranularProvider,\n type GranularComponentDescriptor,\n type GranularProvider,\n resolvePackageBaseUrl,\n} from '@feugene/unocss-preset-granular/contract'\n// <granularity:components:imports> — блок генерируется `yarn generate:registry`\nimport { grAlertConfig } from '../components/GrAlert/config'\nimport { grAutocompleteConfig } from '../components/GrAutocomplete/config'\nimport { grAvatarConfig } from '../components/GrAvatar/config'\nimport { grBadgeConfig } from '../components/GrBadge/config'\nimport { grBadgeWrapConfig } from '../components/GrBadgeWrap/config'\nimport { grBottomNavConfig } from '../components/GrBottomNav/config'\nimport { grBreadcrumbsConfig } from '../components/GrBreadcrumbs/config'\nimport { grButtonConfig } from '../components/GrButton/config'\nimport { grButtonGroupConfig } from '../components/GrButtonGroup/config'\nimport { grCardConfig } from '../components/GrCard/config'\nimport { grCheckboxConfig } from '../components/GrCheckbox/config'\nimport { grCheckboxGroupConfig } from '../components/GrCheckboxGroup/config'\nimport { grChipConfig } from '../components/GrChip/config'\nimport { grChipGroupConfig } from '../components/GrChipGroup/config'\nimport { grCodeBlockConfig } from '../components/GrCodeBlock/config'\nimport { grCollapseConfig } from '../components/GrCollapse/config'\nimport { grColorPickerConfig } from '../components/GrColorPicker/config'\nimport { grCommandPaletteConfig } from '../components/GrCommandPalette/config'\nimport { grConfigProviderConfig } from '../components/GrConfigProvider/config'\nimport { grConfirmDialogConfig } from '../components/GrConfirmDialog/config'\nimport { grContextMenuConfig } from '../components/GrContextMenu/config'\nimport { grDataTableConfig } from '../components/GrDataTable/config'\nimport { grDeltaConfig } from '../components/GrDelta/config'\nimport { grDescriptionListConfig } from '../components/GrDescriptionList/config'\nimport { grDialogConfig } from '../components/GrDialog/config'\nimport { grDialogServiceConfig } from '../components/GrDialogService/config'\nimport { grDividerConfig } from '../components/GrDivider/config'\nimport { grDrawerConfig } from '../components/GrDrawer/config'\nimport { grDropdownConfig } from '../components/GrDropdown/config'\nimport { grDropdownMenuConfig } from '../components/GrDropdownMenu/config'\nimport { grEmptyStateConfig } from '../components/GrEmptyState/config'\nimport { grFilePreviewConfig } from '../components/GrFilePreview/config'\nimport { grFileUploadConfig } from '../components/GrFileUpload/config'\nimport { grFormConfig } from '../components/GrForm/config'\nimport { grFormFieldConfig } from '../components/GrFormField/config'\nimport { grFormFileConfig } from '../components/GrFormFile/config'\nimport { grFormSectionConfig } from '../components/GrFormSection/config'\nimport { grIconConfig } from '../components/GrIcon/config'\nimport { grImageViewerConfig } from '../components/GrImageViewer/config'\nimport { grInputConfig } from '../components/GrInput/config'\nimport { grInputTagConfig } from '../components/GrInputTag/config'\nimport { grJsonViewerConfig } from '../components/GrJsonViewer/config'\nimport { grKbdConfig } from '../components/GrKbd/config'\nimport { grLinkConfig } from '../components/GrLink/config'\nimport { grListConfig } from '../components/GrList/config'\nimport { grLoadingConfig } from '../components/GrLoading/config'\nimport { grModalConfig } from '../components/GrModal/config'\nimport { grNavbarConfig } from '../components/GrNavbar/config'\nimport { grNumberInputConfig } from '../components/GrNumberInput/config'\nimport { grPaginationConfig } from '../components/GrPagination/config'\nimport { grPopoverConfig } from '../components/GrPopover/config'\nimport { grProgressBarConfig } from '../components/GrProgressBar/config'\nimport { grProgressCircleConfig } from '../components/GrProgressCircle/config'\nimport { grPromptDialogConfig } from '../components/GrPromptDialog/config'\nimport { grRadioConfig } from '../components/GrRadio/config'\nimport { grRadioGroupConfig } from '../components/GrRadioGroup/config'\nimport { grRatingConfig } from '../components/GrRating/config'\nimport { grResponseErrorBannerConfig } from '../components/GrResponseErrorBanner/config'\nimport { grSegmentedConfig } from '../components/GrSegmented/config'\nimport { grSelectConfig } from '../components/GrSelect/config'\nimport { grSidebarConfig } from '../components/GrSidebar/config'\nimport { grSkeletonConfig } from '../components/GrSkeleton/config'\nimport { grSliderConfig } from '../components/GrSlider/config'\nimport { grSortableListConfig } from '../components/GrSortableList/config'\nimport { grSplitterConfig } from '../components/GrSplitter/config'\nimport { grStatisticConfig } from '../components/GrStatistic/config'\nimport { grStepsConfig } from '../components/GrSteps/config'\nimport { grSwitchConfig } from '../components/GrSwitch/config'\nimport { grTableConfig } from '../components/GrTable/config'\nimport { grTabPanelsConfig } from '../components/GrTabPanels/config'\nimport { grTabsConfig } from '../components/GrTabs/config'\nimport { grTextareaConfig } from '../components/GrTextarea/config'\nimport { grTimelineConfig } from '../components/GrTimeline/config'\nimport { grToasterConfig } from '../components/GrToaster/config'\nimport { grTooltipConfig } from '../components/GrTooltip/config'\nimport { grTreeConfig } from '../components/GrTree/config'\nimport { grTreeSelectConfig } from '../components/GrTreeSelect/config'\nimport { grValueConfig } from '../components/GrValue/config'\n// </granularity:components:imports>\n\n/** Идентификатор провайдера — совпадает с именем пакета. */\nexport const GRANULARITY_PROVIDER_ID = '@feugene/granularity'\n\n// Не заменять на `new URL('..', import.meta.url)`: Vite и rolldown распознают\n// этот литерал и подставляют `data:`-URL, после чего scan-директории пустеют.\nconst packageBaseUrl = resolvePackageBaseUrl(import.meta.url)\n\n/** Встроенные темы пакета. Единственный источник правды о списке тем. */\nexport const granularityThemeNames = ['light', 'dark'] as const\nexport type GranularityThemeName = (typeof granularityThemeNames)[number]\n\n/** Темы, активные по умолчанию, если окружение не переопределяет выбор. */\nexport const granularityDefaultThemes: readonly GranularityThemeName[] = ['light']\n\nconst theme = {\n baseCssUrl: new URL('../styles/base.css', import.meta.url).href,\n tokensCssUrl: new URL('../styles/tokens.css', import.meta.url).href,\n themes: {\n light: new URL('../styles/themes/light.css', import.meta.url).href,\n dark: new URL('../styles/themes/dark.css', import.meta.url).href,\n },\n defaultThemes: granularityDefaultThemes,\n} as const\n\n/**\n * Реестр публичных компонентов. Ключи совпадают с subpath-экспортом\n * `@feugene/granularity/components/<Name>`.\n */\nexport const granularityComponentConfigs = {\n // <granularity:components:registry> — блок генерируется `yarn generate:registry`\n GrAlert: grAlertConfig,\n GrAutocomplete: grAutocompleteConfig,\n GrAvatar: grAvatarConfig,\n GrBadge: grBadgeConfig,\n GrBadgeWrap: grBadgeWrapConfig,\n GrBottomNav: grBottomNavConfig,\n GrBreadcrumbs: grBreadcrumbsConfig,\n GrButton: grButtonConfig,\n GrButtonGroup: grButtonGroupConfig,\n GrCard: grCardConfig,\n GrCheckbox: grCheckboxConfig,\n GrCheckboxGroup: grCheckboxGroupConfig,\n GrChip: grChipConfig,\n GrChipGroup: grChipGroupConfig,\n GrCodeBlock: grCodeBlockConfig,\n GrCollapse: grCollapseConfig,\n GrColorPicker: grColorPickerConfig,\n GrCommandPalette: grCommandPaletteConfig,\n GrConfigProvider: grConfigProviderConfig,\n GrConfirmDialog: grConfirmDialogConfig,\n GrContextMenu: grContextMenuConfig,\n GrDataTable: grDataTableConfig,\n GrDelta: grDeltaConfig,\n GrDescriptionList: grDescriptionListConfig,\n GrDialog: grDialogConfig,\n GrDialogService: grDialogServiceConfig,\n GrDivider: grDividerConfig,\n GrDrawer: grDrawerConfig,\n GrDropdown: grDropdownConfig,\n GrDropdownMenu: grDropdownMenuConfig,\n GrEmptyState: grEmptyStateConfig,\n GrFilePreview: grFilePreviewConfig,\n GrFileUpload: grFileUploadConfig,\n GrForm: grFormConfig,\n GrFormField: grFormFieldConfig,\n GrFormFile: grFormFileConfig,\n GrFormSection: grFormSectionConfig,\n GrIcon: grIconConfig,\n GrImageViewer: grImageViewerConfig,\n GrInput: grInputConfig,\n GrInputTag: grInputTagConfig,\n GrJsonViewer: grJsonViewerConfig,\n GrKbd: grKbdConfig,\n GrLink: grLinkConfig,\n GrList: grListConfig,\n GrLoading: grLoadingConfig,\n GrModal: grModalConfig,\n GrNavbar: grNavbarConfig,\n GrNumberInput: grNumberInputConfig,\n GrPagination: grPaginationConfig,\n GrPopover: grPopoverConfig,\n GrProgressBar: grProgressBarConfig,\n GrProgressCircle: grProgressCircleConfig,\n GrPromptDialog: grPromptDialogConfig,\n GrRadio: grRadioConfig,\n GrRadioGroup: grRadioGroupConfig,\n GrRating: grRatingConfig,\n GrResponseErrorBanner: grResponseErrorBannerConfig,\n GrSegmented: grSegmentedConfig,\n GrSelect: grSelectConfig,\n GrSidebar: grSidebarConfig,\n GrSkeleton: grSkeletonConfig,\n GrSlider: grSliderConfig,\n GrSortableList: grSortableListConfig,\n GrSplitter: grSplitterConfig,\n GrStatistic: grStatisticConfig,\n GrSteps: grStepsConfig,\n GrSwitch: grSwitchConfig,\n GrTable: grTableConfig,\n GrTabPanels: grTabPanelsConfig,\n GrTabs: grTabsConfig,\n GrTextarea: grTextareaConfig,\n GrTimeline: grTimelineConfig,\n GrToaster: grToasterConfig,\n GrTooltip: grTooltipConfig,\n GrTree: grTreeConfig,\n GrTreeSelect: grTreeSelectConfig,\n GrValue: grValueConfig,\n // </granularity:components:registry>\n}\n\nexport type GranularityComponentName = keyof typeof granularityComponentConfigs\n\n/** Базовый набор компонентов в порядке реестра. */\nconst baseComponents: readonly GranularComponentDescriptor[] = Object.values(\n granularityComponentConfigs,\n)\n\n/**\n * Собирает granular-provider пакета.\n *\n * `overrides` — точка расширения для потребителя: дескриптор с именем из\n * базового реестра заменяет его, остальные дописываются в конец.\n */\nexport function createGranularityProvider(\n overrides: readonly GranularComponentDescriptor[] = [],\n): GranularProvider {\n const overrideByName = new Map(\n overrides.map(component => [component.name, component]),\n )\n const components: GranularComponentDescriptor[] = [\n ...baseComponents.map(component => overrideByName.get(component.name) ?? component),\n ...overrides.filter(component => !baseComponents.some(base => base.name === component.name)),\n ]\n\n return defineGranularProvider({\n id: GRANULARITY_PROVIDER_ID,\n contractVersion: 1,\n packageBaseUrl,\n components,\n theme,\n })\n}\n","import { createGranularityProvider } from './shared'\n\nexport * from './shared'\n\nexport const granularityProvider = createGranularityProvider()\n\nexport default granularityProvider\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,IAAa,iBAAiB,wBAAwB,YAAY,KAAK;CACrE,MAAM;CACN,cAAc,CAAC,YAAY,SAAS;CACpC,UAAU;AACZ,CAAC;;;ACND,IAAa,8BAA8B,wBAAwB,YAAY,KAAK;CAClF,MAAM;CACN,cAAc,CAAC,WAAW,UAAU;AACtC,CAAC;;;;AC4FD,IAAa,0BAA0B;AAIvC,IAAM,iBAAiB,sBAAsB,YAAY,GAAG;;AAG5D,IAAa,wBAAwB,CAAC,SAAS,MAAM;;AAIrD,IAAa,2BAA4D,CAAC,OAAO;AAEjF,IAAM,QAAQ;CACZ,YAAY,IAAA,IAAA,q5KAAA,KAAA,YAAA,GAAA,CAA8C,CAAC;CAC3D,cAAc,IAAA,IAAA,65YAAA,KAAA,YAAA,GAAA,CAAgD,CAAC;CAC/D,QAAQ;EACN,OAAO,IAAA,IAAA,iyYAAA,KAAA,YAAA,GAAA,CAAsD,CAAC;EAC9D,MAAM,IAAA,IAAA,y/SAAA,KAAA,YAAA,GAAA,CAAqD,CAAC;CAC9D;CACA,eAAe;AACjB;;;;;AAMA,IAAa,8BAA8B;CAEzC,SAAS;CACT,gBAAgB;CAChB,UAAU;CACV,SAAS;CACT,aAAa;CACb,aAAa;CACb,eAAe;CACf,UAAU;CACV,eAAe;CACf,QAAQ;CACR,YAAY;CACZ,iBAAiB;CACjB,QAAQ;CACR,aAAa;CACb,aAAa;CACb,YAAY;CACZ,eAAe;CACf,kBAAkB;CAClB,kBAAkB;CAClB,iBAAiB;CACjB,eAAe;CACf,aAAa;CACb,SAAS;CACT,mBAAmB;CACnB,UAAU;CACV,iBAAiB;CACjB,WAAW;CACX,UAAU;CACV,YAAY;CACZ,gBAAgB;CAChB,cAAc;CACd,eAAe;CACf,cAAc;CACd,QAAQ;CACR,aAAa;CACb,YAAY;CACZ,eAAe;CACf,QAAQ;CACR,eAAe;CACf,SAAS;CACT,YAAY;CACZ,cAAc;CACd,OAAO;CACP,QAAQ;CACR,QAAQ;CACR,WAAW;CACX,SAAS;CACT,UAAU;CACV,eAAe;CACf,cAAc;CACd,WAAW;CACX,eAAe;CACf,kBAAkB;CAClB,gBAAgB;CAChB,SAAS;CACT,cAAc;CACd,UAAU;CACV,uBAAuB;CACvB,aAAa;CACb,UAAU;CACV,WAAW;CACX,YAAY;CACZ,UAAU;CACV,gBAAgB;CAChB,YAAY;CACZ,aAAa;CACb,SAAS;CACT,UAAU;CACV,SAAS;CACT,aAAa;CACb,QAAQ;CACR,YAAY;CACZ,YAAY;CACZ,WAAW;CACX,WAAW;CACX,QAAQ;CACR,cAAc;CACd,SAAS;AAEX;;AAKA,IAAM,iBAAyD,OAAO,OACpE,2BACF;;;;;;;AAQA,SAAgB,0BACd,YAAoD,CAAC,GACnC;CAClB,MAAM,iBAAiB,IAAI,IACzB,UAAU,KAAI,cAAa,CAAC,UAAU,MAAM,SAAS,CAAC,CACxD;CACA,MAAM,aAA4C,CAChD,GAAG,eAAe,KAAI,cAAa,eAAe,IAAI,UAAU,IAAI,KAAK,SAAS,GAClF,GAAG,UAAU,QAAO,cAAa,CAAC,eAAe,MAAK,SAAQ,KAAK,SAAS,UAAU,IAAI,CAAC,CAC7F;CAEA,OAAO,uBAAuB;EAC5B,IAAI;EACJ,iBAAiB;EACjB;EACA;EACA;CACF,CAAC;AACH;;;AC1OA,IAAa,sBAAsB,0BAA0B"}
|
|
@@ -1,29 +1,6 @@
|
|
|
1
1
|
import { r as isComposingEvent } from "./keyboard-DE2yhz_b.js";
|
|
2
|
+
import { n as provideGrDevLayers, t as emitGrDevEvent } from "./devHook-CiqijpNM.js";
|
|
2
3
|
//#region src/composables/internal/overlayStack.ts
|
|
3
|
-
/**
|
|
4
|
-
* Единый стек слоёв оверлеев: модалки, drawer'ы, просмотрщик, панели селектов,
|
|
5
|
-
* дропдауны, подсказки — всё, что открывается поверх страницы.
|
|
6
|
-
*
|
|
7
|
-
* Список один, и порядок регистрации совпадает с порядком открытия, но из него
|
|
8
|
-
* выводятся **две разные вершины**:
|
|
9
|
-
*
|
|
10
|
-
* - **Esc** → последний слой любого рода. Дропдаун, открытый внутри модалки,
|
|
11
|
-
* обязан закрыться первым — пользователь видит верхним именно его.
|
|
12
|
-
* - **`inert`** → ставится на модальные слои ниже последнего **модального**.
|
|
13
|
-
* Немодальный слой сверху модалку не понижает: иначе окно ушло бы в `inert`
|
|
14
|
-
* вместе со своим же открытым дропдауном и перестало отвечать.
|
|
15
|
-
* - **высота** → `openModalCount()` поднимает floating-панель над окном, из
|
|
16
|
-
* которого её открыли: телепортированная панель лежит рядом с корнем окна,
|
|
17
|
-
* и статический `z-index` дропдауна оставлял её под ним.
|
|
18
|
-
*
|
|
19
|
-
* Вести эти две вершины в двух независимых реестрах нельзя: реестры описывают
|
|
20
|
-
* один и тот же порядок и расходятся молча — достаточно оверлея, который
|
|
21
|
-
* зарегистрировался в одном и забыл про другой.
|
|
22
|
-
*
|
|
23
|
-
* Ловушку фокуса стек не реализует сам, но питает её (`useFocusTrap`): он
|
|
24
|
-
* видит слои из **разных деревьев рендера** (диалоги `useDialogService`
|
|
25
|
-
* монтируются отдельным `render()` в `body`) и знает их корни.
|
|
26
|
-
*/
|
|
27
4
|
var stack = [];
|
|
28
5
|
var listening = false;
|
|
29
6
|
var nextId = 1;
|
|
@@ -41,6 +18,32 @@ function syncModalLayers() {
|
|
|
41
18
|
layer.setTopmost?.(layer === top);
|
|
42
19
|
layer.setDepth?.(index);
|
|
43
20
|
});
|
|
21
|
+
if (process.env.NODE_ENV !== "production") emitGrDevEvent({
|
|
22
|
+
type: "overlay:sync",
|
|
23
|
+
layers: snapshotLayers()
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Снимок стека для dev-канала.
|
|
28
|
+
*
|
|
29
|
+
* Считается здесь же, где `syncModalLayers` раздаёт то же самое слоям, и по тем
|
|
30
|
+
* же выражениям: разъедься они — наблюдатель показывал бы картину, которой в
|
|
31
|
+
* пакете нет, и отладка по ней уводила бы в сторону.
|
|
32
|
+
*/
|
|
33
|
+
function snapshotLayers() {
|
|
34
|
+
const modals = stack.filter((layer) => layer.modal);
|
|
35
|
+
const topModal = modals[modals.length - 1];
|
|
36
|
+
const top = stack[stack.length - 1];
|
|
37
|
+
return stack.map((layer) => ({
|
|
38
|
+
id: layer.id,
|
|
39
|
+
owner: layer.owner ?? null,
|
|
40
|
+
focus: layer.describeFocus?.() ?? null,
|
|
41
|
+
modal: layer.modal,
|
|
42
|
+
topmostForEscape: layer === top,
|
|
43
|
+
inert: layer.modal && layer !== topModal,
|
|
44
|
+
depth: layer.modal ? modals.indexOf(layer) : null,
|
|
45
|
+
closesOnEscape: layer.shouldClose()
|
|
46
|
+
}));
|
|
44
47
|
}
|
|
45
48
|
function handleKeydown(event) {
|
|
46
49
|
if (event.key !== "Escape") return;
|
|
@@ -50,7 +53,13 @@ function handleKeydown(event) {
|
|
|
50
53
|
event.preventDefault();
|
|
51
54
|
event.stopPropagation();
|
|
52
55
|
if (typeof event.stopImmediatePropagation === "function") event.stopImmediatePropagation();
|
|
53
|
-
|
|
56
|
+
const closes = top.shouldClose();
|
|
57
|
+
if (process.env.NODE_ENV !== "production") emitGrDevEvent({
|
|
58
|
+
type: "overlay:escape",
|
|
59
|
+
id: top.id,
|
|
60
|
+
closed: closes
|
|
61
|
+
});
|
|
62
|
+
if (closes) top.close();
|
|
54
63
|
}
|
|
55
64
|
function startListening() {
|
|
56
65
|
if (listening) return;
|
|
@@ -72,6 +81,12 @@ function pushOverlayLayer(layer) {
|
|
|
72
81
|
id
|
|
73
82
|
});
|
|
74
83
|
startListening();
|
|
84
|
+
if (process.env.NODE_ENV !== "production") emitGrDevEvent({
|
|
85
|
+
type: "overlay:push",
|
|
86
|
+
id,
|
|
87
|
+
modal: layer.modal,
|
|
88
|
+
owner: layer.owner ?? null
|
|
89
|
+
});
|
|
75
90
|
syncModalLayers();
|
|
76
91
|
return id;
|
|
77
92
|
}
|
|
@@ -80,6 +95,10 @@ function removeOverlayLayer(id) {
|
|
|
80
95
|
const index = stack.findIndex((item) => item.id === id);
|
|
81
96
|
if (index >= 0) stack.splice(index, 1);
|
|
82
97
|
if (stack.length === 0) stopListening();
|
|
98
|
+
if (process.env.NODE_ENV !== "production" && index >= 0) emitGrDevEvent({
|
|
99
|
+
type: "overlay:remove",
|
|
100
|
+
id
|
|
101
|
+
});
|
|
83
102
|
syncModalLayers();
|
|
84
103
|
}
|
|
85
104
|
/**
|
|
@@ -129,5 +148,6 @@ function floatingLayerZIndex(zIndexVar) {
|
|
|
129
148
|
function modalLayerZIndex(depth, zIndexVar = "--gr-z-modal") {
|
|
130
149
|
return depth > 0 ? `calc(var(${zIndexVar}) + ${depth})` : `var(${zIndexVar})`;
|
|
131
150
|
}
|
|
151
|
+
if (process.env.NODE_ENV !== "production") provideGrDevLayers(snapshotLayers);
|
|
132
152
|
//#endregion
|
|
133
153
|
export { removeOverlayLayer as a, pushOverlayLayer as i, layerRootsAbove as n, modalLayerZIndex as r, floatingLayerZIndex as t };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overlayStack-DH4Z7am1.js","names":[],"sources":["../../src/composables/internal/overlayStack.ts"],"sourcesContent":["/**\n * Единый стек слоёв оверлеев: модалки, drawer'ы, просмотрщик, панели селектов,\n * дропдауны, подсказки — всё, что открывается поверх страницы.\n *\n * Список один, и порядок регистрации совпадает с порядком открытия, но из него\n * выводятся **две разные вершины**:\n *\n * - **Esc** → последний слой любого рода. Дропдаун, открытый внутри модалки,\n * обязан закрыться первым — пользователь видит верхним именно его.\n * - **`inert`** → ставится на модальные слои ниже последнего **модального**.\n * Немодальный слой сверху модалку не понижает: иначе окно ушло бы в `inert`\n * вместе со своим же открытым дропдауном и перестало отвечать.\n * - **высота** → `openModalCount()` поднимает floating-панель над окном, из\n * которого её открыли: телепортированная панель лежит рядом с корнем окна,\n * и статический `z-index` дропдауна оставлял её под ним.\n *\n * Вести эти две вершины в двух независимых реестрах нельзя: реестры описывают\n * один и тот же порядок и расходятся молча — достаточно оверлея, который\n * зарегистрировался в одном и забыл про другой.\n *\n * Ловушку фокуса стек не реализует сам, но питает её (`useFocusTrap`): он\n * видит слои из **разных деревьев рендера** (диалоги `useDialogService`\n * монтируются отдельным `render()` в `body`) и знает их корни.\n */\n\nimport type { GrLayerFocus, GrOverlaySnapshot } from '../../internal/devHook'\nimport { emitGrDevEvent, provideGrDevLayers } from '../../internal/devHook'\nimport { isComposingEvent } from '../../internal/keyboard'\n\nexport interface OverlayLayer {\n /** Уникальный id зарегистрированного слоя. */\n id: number\n /**\n * Модальный слой: блокирует страницу и участвует в вычислении `inert`.\n * Немодальные (поповеры, меню, подсказки) — только в очереди Esc.\n */\n modal: boolean\n /** Закрывать ли слой по Esc (реактивный геттер: `closeOnEsc` и подобные). */\n shouldClose: () => boolean\n /** Закрыть слой. */\n close: () => void\n /** Уведомление «этот модальный слой сейчас верхний». Только для `modal`. */\n setTopmost?: (isTopmost: boolean) => void\n /**\n * Позиция слоя среди модальных, от нуля. Только для `modal`.\n *\n * От неё считается высота: у всех модальных слоёв один токен\n * (`--gr-z-modal`), и без этой прибавки порядок отрисовки решал бы порядок\n * узлов в портале, а он задаётся **созданием** телепорта, а не открытием\n * слоя. Диалог, объявленный в шаблоне статически, вставал бы под окном,\n * открытым позже, — и получал бы `inert` от стека, оставаясь видимым.\n */\n setDepth?: (depth: number) => void\n /**\n * Корень слоя. Ловушка фокуса нижнего слоя обязана считать его своим:\n * панель селекта, открытого внутри модалки, телепортирована в `body` и лежит\n * вне DOM-поддерева окна, но для пользователя это тот же слой.\n */\n root?: () => HTMLElement | null\n /**\n * Компонент, открывший слой. Только для наблюдателя: стеку он не нужен, но\n * без него слой в панели — безымянный номер.\n */\n owner?: string | null\n /**\n * Картина фокуса глазами самого слоя. Геттер, а не значение: она меняется от\n * каждого клика, а спрашивают её только в момент снимка.\n */\n describeFocus?: () => GrLayerFocus | null\n}\n\nconst stack: OverlayLayer[] = []\nlet listening = false\nlet nextId = 1\n\n/**\n * Пересчитывает состояние модальных слоёв: кто верхний и на какой высоте.\n *\n * Обе величины выводятся из одного порядка, поэтому и считаются в одном месте:\n * разъедься они — «верхний» для `inert` и «верхний» для отрисовки перестали бы\n * совпадать, а это ровно тот дефект, из-за которого высота и заведена.\n */\nfunction syncModalLayers(): void {\n const modals = stack.filter(layer => layer.modal)\n const top = modals[modals.length - 1]\n\n modals.forEach((layer, index) => {\n layer.setTopmost?.(layer === top)\n layer.setDepth?.(index)\n })\n\n if (__GR_DEV__)\n emitGrDevEvent({ type: 'overlay:sync', layers: snapshotLayers() })\n}\n\n/**\n * Снимок стека для dev-канала.\n *\n * Считается здесь же, где `syncModalLayers` раздаёт то же самое слоям, и по тем\n * же выражениям: разъедься они — наблюдатель показывал бы картину, которой в\n * пакете нет, и отладка по ней уводила бы в сторону.\n */\nfunction snapshotLayers(): GrOverlaySnapshot[] {\n const modals = stack.filter(layer => layer.modal)\n const topModal = modals[modals.length - 1]\n const top = stack[stack.length - 1]\n\n return stack.map(layer => ({\n id: layer.id,\n owner: layer.owner ?? null,\n focus: layer.describeFocus?.() ?? null,\n modal: layer.modal,\n topmostForEscape: layer === top,\n inert: layer.modal && layer !== topModal,\n depth: layer.modal ? modals.indexOf(layer) : null,\n closesOnEscape: layer.shouldClose(),\n }))\n}\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (event.key !== 'Escape')\n return\n // Esc во время IME-композиции отменяет её, а не закрывает слой.\n if (isComposingEvent(event))\n return\n if (stack.length === 0)\n return\n\n const top = stack[stack.length - 1]\n\n // Гасим всегда, даже если верхний слой не закрывается по Esc: иначе нажатие\n // «провалится» на слой ниже и закроет не то, что видит пользователь.\n event.preventDefault()\n event.stopPropagation()\n if (typeof event.stopImmediatePropagation === 'function')\n event.stopImmediatePropagation()\n\n const closes = top.shouldClose()\n\n if (__GR_DEV__)\n emitGrDevEvent({ type: 'overlay:escape', id: top.id, closed: closes })\n\n if (closes)\n top.close()\n}\n\nfunction startListening(): void {\n if (listening)\n return\n if (typeof window === 'undefined')\n return\n // Capture-фаза опережает любые локальные обработчики: Esc обязан достаться\n // верхнему слою, а не тому, кто первым подписался.\n window.addEventListener('keydown', handleKeydown, true)\n listening = true\n}\n\nfunction stopListening(): void {\n if (!listening)\n return\n if (typeof window === 'undefined')\n return\n window.removeEventListener('keydown', handleKeydown, true)\n listening = false\n}\n\n/** Регистрирует слой как верхний и возвращает его id. */\nexport function pushOverlayLayer(layer: Omit<OverlayLayer, 'id'>): number {\n const id = nextId++\n stack.push({ ...layer, id })\n startListening()\n\n if (__GR_DEV__)\n emitGrDevEvent({ type: 'overlay:push', id, modal: layer.modal, owner: layer.owner ?? null })\n\n syncModalLayers()\n return id\n}\n\n/** Снимает слой со стека (при закрытии или размонтировании). */\nexport function removeOverlayLayer(id: number): void {\n const index = stack.findIndex(item => item.id === id)\n if (index >= 0)\n stack.splice(index, 1)\n if (stack.length === 0)\n stopListening()\n\n if (__GR_DEV__ && index >= 0)\n emitGrDevEvent({ type: 'overlay:remove', id })\n\n syncModalLayers()\n}\n\n/**\n * Корни слоёв, открытых **поверх** данного.\n *\n * Ими ловушка фокуса дополняет свой контейнер: всё, что открыто изнутри слоя\n * (панель селекта, меню, подсказка), лежит в `body` отдельным поддеревом, и\n * без этого списка ловушка утаскивала бы из него фокус обратно в окно.\n */\nexport function layerRootsAbove(id: number): HTMLElement[] {\n const index = stack.findIndex(layer => layer.id === id)\n if (index < 0)\n return []\n\n return stack\n .slice(index + 1)\n .map(layer => layer.root?.() ?? null)\n .filter((root): root is HTMLElement => root !== null)\n}\n\n/** Корни всех зарегистрированных слоёв. */\nexport function allLayerRoots(): HTMLElement[] {\n return stack\n .map(layer => layer.root?.() ?? null)\n .filter((root): root is HTMLElement => root !== null)\n}\n\n/** Сколько слоёв открыто. Для тестов и диагностики. */\nexport function overlayStackSize(): number {\n return stack.length\n}\n\n/**\n * Сколько **модальных** слоёв открыто прямо сейчас.\n *\n * Читает `useFloating`, когда считает высоту панели: панель телепортирована в\n * общий портал и лежит рядом с корнем окна, а не внутри него, поэтому свой\n * стек-контекст её не спасает — высоту приходится брать из порядка слоёв.\n */\nexport function openModalCount(): number {\n return stack.reduce((count, layer) => count + (layer.modal ? 1 : 0), 0)\n}\n\n/**\n * Высота слоя, лежащего внутри открытого окна.\n *\n * Панель телепортирована в общий портал и становится **соседом** корня окна, а\n * не его потомком: собственный stacking-контекст окна её не накрывает, и\n * статический `--gr-z-dropdown` (1000) оставлял её под окном (1100). Слагаемое —\n * число модальных слоёв, поэтому панель встаёт над самым верхним из них, а\n * полноэкранная загрузка (1150) и тосты (1200) остаются сверху.\n *\n * Обратный случай — «поповер снаружи не должен перекрывать окно» — не страдает:\n * пока окно открыто, страница под ним в `inert`, и открыть там поповер нечем.\n */\nexport function floatingLayerZIndex(zIndexVar: string): string {\n const modals = openModalCount()\n\n return modals > 0 ? `calc(var(--gr-z-modal) + ${modals})` : `var(${zIndexVar})`\n}\n\n/**\n * Высота самого модального слоя: базовый токен плюс его позиция в стеке.\n *\n * Нулевая глубина оставляет чистый `var(...)` — у единственного окна на экране\n * в стилях не появляется лишней арифметики.\n */\nexport function modalLayerZIndex(depth: number, zIndexVar = '--gr-z-modal'): string {\n return depth > 0 ? `calc(var(${zIndexVar}) + ${depth})` : `var(${zIndexVar})`\n}\n\n// Читалка регистрируется на загрузке модуля: наблюдатель может подключиться\n// раньше первого открытого слоя, и тогда спросить ему было бы нечего.\nif (__GR_DEV__)\n provideGrDevLayers(snapshotLayers)\n\n/** Тестовая/служебная очистка стека. */\nexport function resetOverlayStack(): void {\n stack.splice(0, stack.length)\n stopListening()\n\n if (__GR_DEV__)\n emitGrDevEvent({ type: 'overlay:sync', layers: [] })\n}\n"],"mappings":"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"}
|
|
@@ -19,7 +19,7 @@ import { watchEffect } from "vue";
|
|
|
19
19
|
* навсегда.
|
|
20
20
|
*/
|
|
21
21
|
function warnRenamedProp(component, attrs, renames) {
|
|
22
|
-
if (!(
|
|
22
|
+
if (!(process.env.NODE_ENV !== "production")) return;
|
|
23
23
|
const reported = /* @__PURE__ */ new Set();
|
|
24
24
|
watchEffect(() => {
|
|
25
25
|
for (const [from, to] of Object.entries(renames)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renamedProp-
|
|
1
|
+
{"version":3,"file":"renamedProp-Dy96tT-F.js","names":[],"sources":["../../src/components/shared/renamedProp.ts"],"sourcesContent":["import { watchEffect } from 'vue'\n\n/**\n * Предупреждение о пропе, который переименовали.\n *\n * Незнакомый атрибут Vue не отвергает: он уходит в `$attrs` и садится на\n * корневой узел. Значит переименование пропа проходит у потребителя **молча** —\n * не падают ни типы (`vue-tsc` не проверяет лишние атрибуты: принимать их\n * вправе любой компонент), ни рантайм. Компонент просто рисуется дефолтом, и\n * найти это можно только сверкой шаблона со списком пропов.\n *\n * Так и случилось со сменой `variant` на `tone` у `GrBadge` и `GrChip`: у\n * стороннего пакета тихо разъехались десять мест в шести файлах. Причём\n * `variant` в кольце остаётся законным именем у `GrButton`, `GrCard`, `GrAlert`\n * и десятка других — то есть по аналогии не угадать.\n *\n * Предупреждение живёт только в разработке и ничего не чинит за потребителя:\n * подставлять снятое имя значило бы завести алиас, который после 1.0 останется\n * навсегда.\n */\nexport function warnRenamedProp(\n component: string,\n attrs: Record<string, unknown>,\n renames: Readonly<Record<string, string>>,\n): void {\n if (!__GR_DEV__)\n return\n\n const reported = new Set<string>()\n\n watchEffect(() => {\n for (const [from, to] of Object.entries(renames)) {\n if (attrs[from] === undefined || reported.has(from))\n continue\n\n reported.add(from)\n console.warn(\n `[granularity] ${component}: проп \\`${from}\\` переименован в \\`${to}\\`. `\n + `Сейчас \\`${from}\\` уходит в атрибуты корневого узла и на вид компонента не влияет.`,\n )\n }\n })\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAoBA,SAAgB,gBACd,WACA,OACA,SACM;CACN,IAAI,EAAA,QAAA,IAAA,aAAA,eACF;CAEF,MAAM,2BAAW,IAAI,IAAY;CAEjC,kBAAkB;EAChB,KAAK,MAAM,CAAC,MAAM,OAAO,OAAO,QAAQ,OAAO,GAAG;GAChD,IAAI,MAAM,UAAU,KAAA,KAAa,SAAS,IAAI,IAAI,GAChD;GAEF,SAAS,IAAI,IAAI;GACjB,QAAQ,KACN,iBAAiB,UAAU,WAAW,KAAK,sBAAsB,GAAG,eACtD,KAAK,mEACrB;EACF;CACF,CAAC;AACH"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { s as useGrThemeAttrs } from "./context-
|
|
2
|
-
import { t as usePortalTarget } from "./usePortalTarget-
|
|
1
|
+
import { s as useGrThemeAttrs } from "./context-CPMRfwVr.js";
|
|
2
|
+
import { t as usePortalTarget } from "./usePortalTarget-BhrRgdqW.js";
|
|
3
3
|
import { n as markInert, t as inertableOutside } from "./inert-DIHCCn_1.js";
|
|
4
|
-
import { r as modalLayerZIndex } from "./overlayStack-
|
|
4
|
+
import { r as modalLayerZIndex } from "./overlayStack-DH4Z7am1.js";
|
|
5
5
|
import { useOverlayLayer } from "../composables/useOverlayLayer.js";
|
|
6
6
|
import { t as useFocusTrap } from "./useFocusTrap-D9bIPNF6.js";
|
|
7
7
|
import { computed, onBeforeUnmount, onScopeDispose, ref, watch } from "vue";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useModalOverlay-BnAGZpcI.js","names":[],"sources":["../../src/composables/internal/useInertOthers.ts","../../src/composables/internal/useOverlayPresence.ts","../../src/composables/internal/useScrollLock.ts","../../src/composables/internal/useModalOverlay.ts"],"sourcesContent":["import type { Ref } from 'vue'\nimport { onScopeDispose, watch } from 'vue'\n\nimport { inertableOutside, markInert } from './inert'\n\n/**\n * Пока слой активен, всё вне его ветки помечено `inert`: от корня оверлея вверх\n * до `<body>`, на каждом уровне — соседи.\n *\n * Это вторая половина модальности: `z-index` перекрывает страницу глазами,\n * `inert` — клавиатурой и скринридером.\n */\nexport function useInertOthers(root: Ref<HTMLElement | null>, active: () => boolean): void {\n let release: (() => void) | undefined\n\n function apply(): void {\n release?.()\n release = markInert(inertableOutside(root.value))\n }\n\n function clear(): void {\n release?.()\n release = undefined\n }\n\n watch(\n () => Boolean(active()) && Boolean(root.value),\n (isActive) => {\n if (isActive)\n apply()\n else clear()\n },\n { immediate: true, flush: 'post' },\n )\n\n onScopeDispose(clear)\n}\n","import type { Ref } from 'vue'\nimport { ref, watch } from 'vue'\n\nexport interface OverlayPresence {\n /** Смонтировано ли поддерево слоя: держится до конца leave-анимации. */\n mounted: Ref<boolean>\n /** Показан ли слой: этим переключаются `<Transition>` внутри. */\n visible: Ref<boolean>\n /** Вызывается из `@after-leave` панели. */\n onPanelAfterLeave: () => void\n}\n\n/**\n * Присутствие оверлея в DOM отдельно от его видимости.\n *\n * Штатный `<Transition>` анимирует свой элемент, но не координирует соседей:\n * убери обёртку по `v-if` — и подложка с панелью исчезнут мгновенно, без\n * leave-анимации. Поэтому присутствие поддерева и видимость слоя — два разных\n * флага: первый снимается только по концу leave-анимации панели.\n *\n * Видимость включается **в том же такте**, что и монтирование: содержимое окна\n * обязано появляться в DOM сразу после открытия — на этом стоит и код\n * потребителя, и внутренние компоненты, которые ищут в панели свои элементы.\n * Enter-анимацию это не отменяет: `<Transition appear>` проигрывает её и на\n * первом рендере ребёнка.\n */\nexport function useOverlayPresence(open: Ref<boolean>): OverlayPresence {\n const mounted = ref(open.value)\n const visible = ref(open.value)\n\n watch(open, (isOpen) => {\n if (isOpen)\n mounted.value = true\n visible.value = isOpen\n })\n\n function onPanelAfterLeave(): void {\n // Пока панель уезжала, слой могли открыть заново — тогда размонтировать\n // нечего и незачем.\n if (!open.value)\n mounted.value = false\n }\n\n return { mounted, visible, onPanelAfterLeave }\n}\n","/**\n * useScrollLock — общий **reference-counted** lock скролла `<body>` для оверлеев\n * (GrModal, GrDrawer, GrImageViewer).\n *\n * Зачем счётчик: состояние `<body>` принадлежит не оверлею, а их совокупности.\n * Держи каждый свой `savedBodyOverflow`, и закрытие A при ещё открытой B вернуло\n * бы странице прокрутку под открытым окном — закрывают не всегда в порядке\n * открытия. Поэтому состояние сохраняется один раз (переход счётчика 0→1) и\n * восстанавливается только когда закрыт последний оверлей (1→0).\n *\n * Плюс компенсация ширины скроллбара: при `overflow: hidden` скроллбар исчезает и\n * контент дёргается вправо — добавляем `padding-right` на его ширину.\n *\n * Отдельная ветка — iOS Safari: там `overflow: hidden` фон не держит, страница\n * продолжает «резинить» под открытым окном. Лечится тем же, чем лечил\n * HeadlessUI (`handleIOSLocking`): гасим `touchmove` вне скроллящихся областей\n * оверлея и возвращаем позицию прокрутки после снятия лока.\n */\n\ninterface SavedBodyStyle {\n overflow: string\n paddingRight: string\n overscrollBehavior: string\n}\n\nlet lockCount = 0\nlet saved: SavedBodyStyle | null = null\nlet savedScrollY = 0\nlet releaseTouchGuard: (() => void) | null = null\n\n/**\n * iOS определяем по платформе, а не по ширине экрана: лечение специфично для\n * движка, а не для размера. `maxTouchPoints` отличает iPadOS, который со времён\n * 13-й версии представляется десктопным Mac.\n */\nfunction isIOS(): boolean {\n if (typeof navigator === 'undefined')\n return false\n return /iP(?:hone|ad|od)/.test(navigator.platform)\n || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)\n}\n\n/** Прокручиваемая область оверлея — единственное, чему `touchmove` разрешён. */\nfunction isScrollableOverlayArea(target: EventTarget | null): boolean {\n if (!(target instanceof Element))\n return false\n\n for (let node: Element | null = target; node; node = node.parentElement) {\n if (!(node instanceof HTMLElement))\n continue\n if (node.hasAttribute('data-gr-overlay-root'))\n return true\n }\n\n return false\n}\n\nfunction applyTouchGuard(): void {\n if (!isIOS())\n return\n\n const onTouchMove = (event: TouchEvent): void => {\n // Внутри оверлея скролл законен (длинное окно, лента изображений), а всё\n // остальное — это и есть фон, который лок обязан держать.\n if (isScrollableOverlayArea(event.target))\n return\n if (event.cancelable)\n event.preventDefault()\n }\n\n document.addEventListener('touchmove', onTouchMove, { passive: false })\n releaseTouchGuard = () => document.removeEventListener('touchmove', onTouchMove)\n}\n\nfunction getScrollbarWidth(): number {\n return window.innerWidth - document.documentElement.clientWidth\n}\n\nfunction applyLock(): void {\n const body = document.body\n saved = {\n overflow: body.style.overflow,\n paddingRight: body.style.paddingRight,\n overscrollBehavior: body.style.overscrollBehavior,\n }\n savedScrollY = window.scrollY\n\n // Ширину скроллбара считаем ДО `overflow: hidden` (после — `clientWidth` меняется).\n const scrollbarWidth = getScrollbarWidth()\n\n body.style.overflow = 'hidden'\n // Прокрутка, «доехавшая» до края внутри окна, не должна продолжаться фоном.\n body.style.overscrollBehavior = 'contain'\n if (scrollbarWidth > 0) {\n const currentPadding = Number.parseFloat(getComputedStyle(body).paddingRight) || 0\n body.style.paddingRight = `${currentPadding + scrollbarWidth}px`\n }\n\n applyTouchGuard()\n}\n\nfunction releaseLock(): void {\n releaseTouchGuard?.()\n releaseTouchGuard = null\n\n if (!saved)\n return\n document.body.style.overflow = saved.overflow\n document.body.style.paddingRight = saved.paddingRight\n document.body.style.overscrollBehavior = saved.overscrollBehavior\n saved = null\n\n // iOS сдвигает страницу, пока фон заблокирован; возвращаем её на место.\n if (isIOS() && window.scrollY !== savedScrollY)\n window.scrollTo(0, savedScrollY)\n}\n\n/**\n * Возвращает пару `lock`/`unlock`, идемпотентную **в пределах одного инстанса**\n * (повторный `lock()` без `unlock()` не увеличивает глобальный счётчик дважды).\n * Глобальный счётчик разделяется всеми оверлеями.\n */\nexport function useScrollLock() {\n const isClient = typeof window !== 'undefined'\n let held = false\n\n function lock(): void {\n if (!isClient || held)\n return\n held = true\n lockCount += 1\n if (lockCount === 1)\n applyLock()\n }\n\n function unlock(): void {\n if (!isClient || !held)\n return\n held = false\n lockCount = Math.max(0, lockCount - 1)\n if (lockCount === 0)\n releaseLock()\n }\n\n return { lock, unlock }\n}\n\n/** Тестовая/служебная очистка глобального состояния. */\nexport function resetScrollLock(): void {\n lockCount = 0\n if (typeof document !== 'undefined')\n releaseLock()\n saved = null\n}\n","import type { ComputedRef, Ref } from 'vue'\nimport { computed, onBeforeUnmount, ref, watch } from 'vue'\n\nimport { useGrThemeAttrs } from '../../components/GrConfigProvider/context'\nimport { modalLayerZIndex } from './overlayStack'\nimport { useFocusTrap } from '../useFocusTrap'\nimport { useOverlayLayer } from '../useOverlayLayer'\nimport { usePortalTarget } from '../usePortalTarget'\nimport { useInertOthers } from './useInertOthers'\nimport { useOverlayPresence } from './useOverlayPresence'\nimport { useScrollLock } from './useScrollLock'\n\n/**\n * Модальный слой целиком: одна сборка на весь пакет.\n *\n * Модальность собиралась вручную в трёх компонентах (`GrModal`, `GrDrawer`,\n * `GrImageViewer`) из шести примитивов, и сборка повторялась дословно. Дело не\n * в объёме: в этой проводке сидят инварианты, каждый из которых при пропуске\n * даёт тихий баг доступности, а не заметную поломку. Здесь они собраны в одном\n * месте — забыть часть модального слоя больше нельзя.\n *\n * Что именно неочевидно:\n *\n * - **`restoreFocus: false` у ловушки.** Возврат фокуса принадлежит стеку\n * слоёв: у него правило строже — вернуть, только если на момент закрытия\n * фокус ещё был внутри слоя. Две системы возврата подрались бы за фокус.\n * - **`containers: layer.rootsAbove`.** Панель селекта, открытого ВНУТРИ окна,\n * телепортирована в `body` и лежит вне поддерева панели. Без этого списка\n * ловушка считала бы её «снаружи» и отбирала фокус.\n * - **Ловушка и `inert` работают, только пока слой верхний.** Иначе нижнее\n * окно ворует фокус у открытого поверх него, а `inert` гасит собственную\n * панель вместе со страницей.\n * - **Клик по подложке считается только тот, что на ней и начался.** Иначе\n * выделение текста мышью или перетаскивание, отпущенное за пределами панели,\n * закрывает слой.\n *\n * Чего композабл НЕ делает: не рисует разметку. Корневой `div`, подложка и\n * панель у трёх компонентов различаются по существу (обёртки скролла у окна,\n * сквозные клики у немодальной панели, слои хрома у просмотрщика), а классами\n * общий модуль владеть не вправе — пресет гранулярности подмешивает safelist\n * только по директориям выбранных компонентов.\n */\nexport interface UseModalOverlayOptions {\n /**\n * Модальный ли слой: блокирует страницу, держит фокус, гасит нижние окна.\n * Геттером — там, где модальность включается пропом (`GrDrawer`).\n */\n modal?: boolean | (() => boolean)\n /** Закрывать ли по Esc. Геттер — проп компонента реактивен. */\n closeOnEscape?: () => boolean\n /** Закрывать ли по клику в подложку; читается обработчиками `backdrop`. */\n closeOnBackdrop?: () => boolean\n /** Панель слоя: контейнер ловушки фокуса и её запасной приёмник. */\n panel: Ref<HTMLElement | null>\n /**\n * Свой корень слоя. У якорного оверлея (`GrPopover`) корень и панель — один\n * элемент: в портал уезжает сама панель, отдельной обёртки нет. Не задан —\n * композабл заводит корень сам, как у центрированных окон.\n */\n root?: Ref<HTMLElement | null>\n /**\n * Имя CSS-переменной слоя. Escape-hatch мимо `--gr-z-modal` — им пользуется\n * просмотрщик. Глубина слоя прибавляется и к подменённой переменной.\n */\n zIndexVar?: () => string | undefined\n /**\n * Точечное переопределение точки монтирования (проп `teleportTo`). По\n * умолчанию — общий портал оверлеев.\n */\n teleportTo?: () => string | HTMLElement | undefined\n /**\n * Кому отдать фокус при открытии. Не задан — первому фокусируемому внутри\n * панели (правило `useFocusTrap`): просмотрщику нужна именно кнопка тулбара,\n * а окну — сама панель, и оно передаёт её явно.\n */\n initialFocus?: () => HTMLElement | null | undefined\n /**\n * Блокировать ли скролл страницы. По умолчанию — пока слой открыт и модален:\n * немодальная панель существует ровно ради работы со страницей под ней.\n */\n lockScroll?: () => boolean\n}\n\nexport interface ModalOverlay {\n /** Корень слоя: цель `ref` в шаблоне, хозяин `inert` и корень для стека слоёв. */\n rootEl: Ref<HTMLElement | null>\n /** Смонтировано ли поддерево: держится до конца leave-анимации панели. */\n isMounted: Ref<boolean>\n /** Показан ли слой: этим переключаются `<Transition>` внутри. */\n isVisible: Ref<boolean>\n /** Верхний ли это слой сейчас. */\n isTopmost: Ref<boolean>\n /** Значение атрибута `inert` для корня: слой перестал быть верхним. */\n inertAttr: ComputedRef<true | undefined>\n /**\n * Высота слоя: базовый токен плюс позиция в стеке.\n *\n * Один токен на все модальные слои означал бы, что порядок отрисовки решает\n * порядок узлов в портале, а он задан **созданием** телепорта, а не\n * открытием: статически объявленный диалог вставал бы под окном, открытым\n * позже, и оказывался невидимым — при том что стек считает верхним его.\n */\n layerZIndex: ComputedRef<string>\n portalTarget: ComputedRef<string | HTMLElement>\n teleportEnabled: ComputedRef<boolean>\n /** `data-theme` на телепортированный корень: в DOM он вне обёртки провайдера. */\n themeAttrs: ComputedRef<{ 'data-theme'?: string }>\n /** Для `@after-leave` панели. Компонент оборачивает, если ему нужен эмит `closed`. */\n onPanelAfterLeave: () => void\n /**\n * Обработчики подложки вместе с guard'ом «клик начался на ней». Имена — под\n * `v-on=\"backdrop\"`: объектный синтаксис ждёт имена событий, а не пропов.\n */\n backdrop: {\n mousedown: (event: MouseEvent) => void\n click: (event: MouseEvent) => void\n }\n}\n\nexport function useModalOverlay(\n open: Ref<boolean>,\n onDismiss: () => void,\n options: UseModalOverlayOptions,\n): ModalOverlay {\n const isModal = (): boolean =>\n typeof options.modal === 'function' ? options.modal() : options.modal ?? true\n\n const rootEl = options.root ?? ref<HTMLElement | null>(null)\n const isTopmost = ref(true)\n\n const inertAttr = computed(() => (open.value && isModal() && !isTopmost.value ? true : undefined))\n\n // Телепорт включается только ПОСЛЕ монтирования: иначе первый клиентский\n // рендер не совпадёт с серверным и сломается гидрация.\n const { target: portalTarget, enabled: teleportEnabled } = usePortalTarget(options.teleportTo)\n\n // Панель уезжает в `body`, то есть вне обёртки провайдера, и `data-theme` с\n // неё не наследуется. В дереве компонентов слой остаётся внутри — `inject`\n // доходит, и тему он ставит себе сам.\n const themeAttrs = useGrThemeAttrs()\n\n const { mounted: isMounted, visible: isVisible, onPanelAfterLeave } = useOverlayPresence(open)\n\n const layer = useOverlayLayer(open, onDismiss, {\n modal: isModal,\n closeOnEscape: options.closeOnEscape,\n onTopmostChange: (value) => { isTopmost.value = value },\n root: rootEl,\n })\n\n const layerZIndex = computed(() => modalLayerZIndex(\n layer.depth.value,\n options.zIndexVar?.() ?? '--gr-z-modal',\n ))\n\n useFocusTrap(options.panel, {\n active: () => open.value && isModal() && isTopmost.value,\n initialFocus: options.initialFocus,\n fallbackFocus: () => options.panel.value,\n containers: layer.rootsAbove,\n restoreFocus: false,\n })\n\n useInertOthers(rootEl, () => open.value && isModal() && isTopmost.value)\n\n // Общий reference-counted lock: несколько открытых оверлеев снимают блокировку\n // независимо от порядка закрытия, ширина скроллбара компенсируется.\n const { lock, unlock } = useScrollLock()\n\n watch(\n () => options.lockScroll?.() ?? (open.value && isModal()),\n (locked) => {\n if (locked)\n lock()\n else unlock()\n },\n { immediate: true },\n )\n\n onBeforeUnmount(unlock)\n\n let pointerDownOnBackdrop = false\n\n return {\n rootEl,\n isMounted,\n isVisible,\n isTopmost,\n inertAttr,\n layerZIndex,\n portalTarget,\n teleportEnabled,\n themeAttrs,\n onPanelAfterLeave,\n backdrop: {\n mousedown(event: MouseEvent): void {\n pointerDownOnBackdrop = event.target === event.currentTarget\n },\n click(event: MouseEvent): void {\n const startedHere = pointerDownOnBackdrop\n pointerDownOnBackdrop = false\n\n if (!startedHere || event.target !== event.currentTarget)\n return\n if (options.closeOnBackdrop?.() === false)\n return\n\n onDismiss()\n },\n },\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;AAYA,SAAgB,eAAe,MAA+B,QAA6B;CACzF,IAAI;CAEJ,SAAS,QAAc;EACrB,UAAU;EACV,UAAU,UAAU,iBAAiB,KAAK,KAAK,CAAC;CAClD;CAEA,SAAS,QAAc;EACrB,UAAU;EACV,UAAU,KAAA;CACZ;CAEA,YACQ,QAAQ,OAAO,CAAC,KAAK,QAAQ,KAAK,KAAK,IAC5C,aAAa;EACZ,IAAI,UACF,MAAM;OACH,MAAM;CACb,GACA;EAAE,WAAW;EAAM,OAAO;CAAO,CACnC;CAEA,eAAe,KAAK;AACtB;;;;;;;;;;;;;;;;;ACVA,SAAgB,mBAAmB,MAAqC;CACtE,MAAM,UAAU,IAAI,KAAK,KAAK;CAC9B,MAAM,UAAU,IAAI,KAAK,KAAK;CAE9B,MAAM,OAAO,WAAW;EACtB,IAAI,QACF,QAAQ,QAAQ;EAClB,QAAQ,QAAQ;CAClB,CAAC;CAED,SAAS,oBAA0B;EAGjC,IAAI,CAAC,KAAK,OACR,QAAQ,QAAQ;CACpB;CAEA,OAAO;EAAE;EAAS;EAAS;CAAkB;AAC/C;;;ACnBA,IAAI,YAAY;AAChB,IAAI,QAA+B;AACnC,IAAI,eAAe;AACnB,IAAI,oBAAyC;;;;;;AAO7C,SAAS,QAAiB;CACxB,IAAI,OAAO,cAAc,aACvB,OAAO;CACT,OAAO,mBAAmB,KAAK,UAAU,QAAQ,KAC3C,UAAU,aAAa,cAAc,UAAU,iBAAiB;AACxE;;AAGA,SAAS,wBAAwB,QAAqC;CACpE,IAAI,EAAE,kBAAkB,UACtB,OAAO;CAET,KAAK,IAAI,OAAuB,QAAQ,MAAM,OAAO,KAAK,eAAe;EACvE,IAAI,EAAE,gBAAgB,cACpB;EACF,IAAI,KAAK,aAAa,sBAAsB,GAC1C,OAAO;CACX;CAEA,OAAO;AACT;AAEA,SAAS,kBAAwB;CAC/B,IAAI,CAAC,MAAM,GACT;CAEF,MAAM,eAAe,UAA4B;EAG/C,IAAI,wBAAwB,MAAM,MAAM,GACtC;EACF,IAAI,MAAM,YACR,MAAM,eAAe;CACzB;CAEA,SAAS,iBAAiB,aAAa,aAAa,EAAE,SAAS,MAAM,CAAC;CACtE,0BAA0B,SAAS,oBAAoB,aAAa,WAAW;AACjF;AAEA,SAAS,oBAA4B;CACnC,OAAO,OAAO,aAAa,SAAS,gBAAgB;AACtD;AAEA,SAAS,YAAkB;CACzB,MAAM,OAAO,SAAS;CACtB,QAAQ;EACN,UAAU,KAAK,MAAM;EACrB,cAAc,KAAK,MAAM;EACzB,oBAAoB,KAAK,MAAM;CACjC;CACA,eAAe,OAAO;CAGtB,MAAM,iBAAiB,kBAAkB;CAEzC,KAAK,MAAM,WAAW;CAEtB,KAAK,MAAM,qBAAqB;CAChC,IAAI,iBAAiB,GAAG;EACtB,MAAM,iBAAiB,OAAO,WAAW,iBAAiB,IAAI,CAAC,CAAC,YAAY,KAAK;EACjF,KAAK,MAAM,eAAe,GAAG,iBAAiB,eAAe;CAC/D;CAEA,gBAAgB;AAClB;AAEA,SAAS,cAAoB;CAC3B,oBAAoB;CACpB,oBAAoB;CAEpB,IAAI,CAAC,OACH;CACF,SAAS,KAAK,MAAM,WAAW,MAAM;CACrC,SAAS,KAAK,MAAM,eAAe,MAAM;CACzC,SAAS,KAAK,MAAM,qBAAqB,MAAM;CAC/C,QAAQ;CAGR,IAAI,MAAM,KAAK,OAAO,YAAY,cAChC,OAAO,SAAS,GAAG,YAAY;AACnC;;;;;;AAOA,SAAgB,gBAAgB;CAC9B,MAAM,WAAW,OAAO,WAAW;CACnC,IAAI,OAAO;CAEX,SAAS,OAAa;EACpB,IAAI,CAAC,YAAY,MACf;EACF,OAAO;EACP,aAAa;EACb,IAAI,cAAc,GAChB,UAAU;CACd;CAEA,SAAS,SAAe;EACtB,IAAI,CAAC,YAAY,CAAC,MAChB;EACF,OAAO;EACP,YAAY,KAAK,IAAI,GAAG,YAAY,CAAC;EACrC,IAAI,cAAc,GAChB,YAAY;CAChB;CAEA,OAAO;EAAE;EAAM;CAAO;AACxB;;;AC1BA,SAAgB,gBACd,MACA,WACA,SACc;CACd,MAAM,gBACJ,OAAO,QAAQ,UAAU,aAAa,QAAQ,MAAM,IAAI,QAAQ,SAAS;CAE3E,MAAM,SAAS,QAAQ,QAAQ,IAAwB,IAAI;CAC3D,MAAM,YAAY,IAAI,IAAI;CAE1B,MAAM,YAAY,eAAgB,KAAK,SAAS,QAAQ,KAAK,CAAC,UAAU,QAAQ,OAAO,KAAA,CAAU;CAIjG,MAAM,EAAE,QAAQ,cAAc,SAAS,oBAAoB,gBAAgB,QAAQ,UAAU;CAK7F,MAAM,aAAa,gBAAgB;CAEnC,MAAM,EAAE,SAAS,WAAW,SAAS,WAAW,sBAAsB,mBAAmB,IAAI;CAE7F,MAAM,QAAQ,gBAAgB,MAAM,WAAW;EAC7C,OAAO;EACP,eAAe,QAAQ;EACvB,kBAAkB,UAAU;GAAE,UAAU,QAAQ;EAAM;EACtD,MAAM;CACR,CAAC;CAED,MAAM,cAAc,eAAe,iBACjC,MAAM,MAAM,OACZ,QAAQ,YAAY,KAAK,cAC3B,CAAC;CAED,aAAa,QAAQ,OAAO;EAC1B,cAAc,KAAK,SAAS,QAAQ,KAAK,UAAU;EACnD,cAAc,QAAQ;EACtB,qBAAqB,QAAQ,MAAM;EACnC,YAAY,MAAM;EAClB,cAAc;CAChB,CAAC;CAED,eAAe,cAAc,KAAK,SAAS,QAAQ,KAAK,UAAU,KAAK;CAIvE,MAAM,EAAE,MAAM,WAAW,cAAc;CAEvC,YACQ,QAAQ,aAAa,MAAM,KAAK,SAAS,QAAQ,KACtD,WAAW;EACV,IAAI,QACF,KAAK;OACF,OAAO;CACd,GACA,EAAE,WAAW,KAAK,CACpB;CAEA,gBAAgB,MAAM;CAEtB,IAAI,wBAAwB;CAE5B,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,UAAU;GACR,UAAU,OAAyB;IACjC,wBAAwB,MAAM,WAAW,MAAM;GACjD;GACA,MAAM,OAAyB;IAC7B,MAAM,cAAc;IACpB,wBAAwB;IAExB,IAAI,CAAC,eAAe,MAAM,WAAW,MAAM,eACzC;IACF,IAAI,QAAQ,kBAAkB,MAAM,OAClC;IAEF,UAAU;GACZ;EACF;CACF;AACF"}
|
|
1
|
+
{"version":3,"file":"useModalOverlay-ACRkflzx.js","names":[],"sources":["../../src/composables/internal/useInertOthers.ts","../../src/composables/internal/useOverlayPresence.ts","../../src/composables/internal/useScrollLock.ts","../../src/composables/internal/useModalOverlay.ts"],"sourcesContent":["import type { Ref } from 'vue'\nimport { onScopeDispose, watch } from 'vue'\n\nimport { inertableOutside, markInert } from './inert'\n\n/**\n * Пока слой активен, всё вне его ветки помечено `inert`: от корня оверлея вверх\n * до `<body>`, на каждом уровне — соседи.\n *\n * Это вторая половина модальности: `z-index` перекрывает страницу глазами,\n * `inert` — клавиатурой и скринридером.\n */\nexport function useInertOthers(root: Ref<HTMLElement | null>, active: () => boolean): void {\n let release: (() => void) | undefined\n\n function apply(): void {\n release?.()\n release = markInert(inertableOutside(root.value))\n }\n\n function clear(): void {\n release?.()\n release = undefined\n }\n\n watch(\n () => Boolean(active()) && Boolean(root.value),\n (isActive) => {\n if (isActive)\n apply()\n else clear()\n },\n { immediate: true, flush: 'post' },\n )\n\n onScopeDispose(clear)\n}\n","import type { Ref } from 'vue'\nimport { ref, watch } from 'vue'\n\nexport interface OverlayPresence {\n /** Смонтировано ли поддерево слоя: держится до конца leave-анимации. */\n mounted: Ref<boolean>\n /** Показан ли слой: этим переключаются `<Transition>` внутри. */\n visible: Ref<boolean>\n /** Вызывается из `@after-leave` панели. */\n onPanelAfterLeave: () => void\n}\n\n/**\n * Присутствие оверлея в DOM отдельно от его видимости.\n *\n * Штатный `<Transition>` анимирует свой элемент, но не координирует соседей:\n * убери обёртку по `v-if` — и подложка с панелью исчезнут мгновенно, без\n * leave-анимации. Поэтому присутствие поддерева и видимость слоя — два разных\n * флага: первый снимается только по концу leave-анимации панели.\n *\n * Видимость включается **в том же такте**, что и монтирование: содержимое окна\n * обязано появляться в DOM сразу после открытия — на этом стоит и код\n * потребителя, и внутренние компоненты, которые ищут в панели свои элементы.\n * Enter-анимацию это не отменяет: `<Transition appear>` проигрывает её и на\n * первом рендере ребёнка.\n */\nexport function useOverlayPresence(open: Ref<boolean>): OverlayPresence {\n const mounted = ref(open.value)\n const visible = ref(open.value)\n\n watch(open, (isOpen) => {\n if (isOpen)\n mounted.value = true\n visible.value = isOpen\n })\n\n function onPanelAfterLeave(): void {\n // Пока панель уезжала, слой могли открыть заново — тогда размонтировать\n // нечего и незачем.\n if (!open.value)\n mounted.value = false\n }\n\n return { mounted, visible, onPanelAfterLeave }\n}\n","/**\n * useScrollLock — общий **reference-counted** lock скролла `<body>` для оверлеев\n * (GrModal, GrDrawer, GrImageViewer).\n *\n * Зачем счётчик: состояние `<body>` принадлежит не оверлею, а их совокупности.\n * Держи каждый свой `savedBodyOverflow`, и закрытие A при ещё открытой B вернуло\n * бы странице прокрутку под открытым окном — закрывают не всегда в порядке\n * открытия. Поэтому состояние сохраняется один раз (переход счётчика 0→1) и\n * восстанавливается только когда закрыт последний оверлей (1→0).\n *\n * Плюс компенсация ширины скроллбара: при `overflow: hidden` скроллбар исчезает и\n * контент дёргается вправо — добавляем `padding-right` на его ширину.\n *\n * Отдельная ветка — iOS Safari: там `overflow: hidden` фон не держит, страница\n * продолжает «резинить» под открытым окном. Лечится тем же, чем лечил\n * HeadlessUI (`handleIOSLocking`): гасим `touchmove` вне скроллящихся областей\n * оверлея и возвращаем позицию прокрутки после снятия лока.\n */\n\ninterface SavedBodyStyle {\n overflow: string\n paddingRight: string\n overscrollBehavior: string\n}\n\nlet lockCount = 0\nlet saved: SavedBodyStyle | null = null\nlet savedScrollY = 0\nlet releaseTouchGuard: (() => void) | null = null\n\n/**\n * iOS определяем по платформе, а не по ширине экрана: лечение специфично для\n * движка, а не для размера. `maxTouchPoints` отличает iPadOS, который со времён\n * 13-й версии представляется десктопным Mac.\n */\nfunction isIOS(): boolean {\n if (typeof navigator === 'undefined')\n return false\n return /iP(?:hone|ad|od)/.test(navigator.platform)\n || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)\n}\n\n/** Прокручиваемая область оверлея — единственное, чему `touchmove` разрешён. */\nfunction isScrollableOverlayArea(target: EventTarget | null): boolean {\n if (!(target instanceof Element))\n return false\n\n for (let node: Element | null = target; node; node = node.parentElement) {\n if (!(node instanceof HTMLElement))\n continue\n if (node.hasAttribute('data-gr-overlay-root'))\n return true\n }\n\n return false\n}\n\nfunction applyTouchGuard(): void {\n if (!isIOS())\n return\n\n const onTouchMove = (event: TouchEvent): void => {\n // Внутри оверлея скролл законен (длинное окно, лента изображений), а всё\n // остальное — это и есть фон, который лок обязан держать.\n if (isScrollableOverlayArea(event.target))\n return\n if (event.cancelable)\n event.preventDefault()\n }\n\n document.addEventListener('touchmove', onTouchMove, { passive: false })\n releaseTouchGuard = () => document.removeEventListener('touchmove', onTouchMove)\n}\n\nfunction getScrollbarWidth(): number {\n return window.innerWidth - document.documentElement.clientWidth\n}\n\nfunction applyLock(): void {\n const body = document.body\n saved = {\n overflow: body.style.overflow,\n paddingRight: body.style.paddingRight,\n overscrollBehavior: body.style.overscrollBehavior,\n }\n savedScrollY = window.scrollY\n\n // Ширину скроллбара считаем ДО `overflow: hidden` (после — `clientWidth` меняется).\n const scrollbarWidth = getScrollbarWidth()\n\n body.style.overflow = 'hidden'\n // Прокрутка, «доехавшая» до края внутри окна, не должна продолжаться фоном.\n body.style.overscrollBehavior = 'contain'\n if (scrollbarWidth > 0) {\n const currentPadding = Number.parseFloat(getComputedStyle(body).paddingRight) || 0\n body.style.paddingRight = `${currentPadding + scrollbarWidth}px`\n }\n\n applyTouchGuard()\n}\n\nfunction releaseLock(): void {\n releaseTouchGuard?.()\n releaseTouchGuard = null\n\n if (!saved)\n return\n document.body.style.overflow = saved.overflow\n document.body.style.paddingRight = saved.paddingRight\n document.body.style.overscrollBehavior = saved.overscrollBehavior\n saved = null\n\n // iOS сдвигает страницу, пока фон заблокирован; возвращаем её на место.\n if (isIOS() && window.scrollY !== savedScrollY)\n window.scrollTo(0, savedScrollY)\n}\n\n/**\n * Возвращает пару `lock`/`unlock`, идемпотентную **в пределах одного инстанса**\n * (повторный `lock()` без `unlock()` не увеличивает глобальный счётчик дважды).\n * Глобальный счётчик разделяется всеми оверлеями.\n */\nexport function useScrollLock() {\n const isClient = typeof window !== 'undefined'\n let held = false\n\n function lock(): void {\n if (!isClient || held)\n return\n held = true\n lockCount += 1\n if (lockCount === 1)\n applyLock()\n }\n\n function unlock(): void {\n if (!isClient || !held)\n return\n held = false\n lockCount = Math.max(0, lockCount - 1)\n if (lockCount === 0)\n releaseLock()\n }\n\n return { lock, unlock }\n}\n\n/** Тестовая/служебная очистка глобального состояния. */\nexport function resetScrollLock(): void {\n lockCount = 0\n if (typeof document !== 'undefined')\n releaseLock()\n saved = null\n}\n","import type { ComputedRef, Ref } from 'vue'\nimport { computed, onBeforeUnmount, ref, watch } from 'vue'\n\nimport { useGrThemeAttrs } from '../../components/GrConfigProvider/context'\nimport { modalLayerZIndex } from './overlayStack'\nimport { useFocusTrap } from '../useFocusTrap'\nimport { useOverlayLayer } from '../useOverlayLayer'\nimport { usePortalTarget } from '../usePortalTarget'\nimport { useInertOthers } from './useInertOthers'\nimport { useOverlayPresence } from './useOverlayPresence'\nimport { useScrollLock } from './useScrollLock'\n\n/**\n * Модальный слой целиком: одна сборка на весь пакет.\n *\n * Модальность собиралась вручную в трёх компонентах (`GrModal`, `GrDrawer`,\n * `GrImageViewer`) из шести примитивов, и сборка повторялась дословно. Дело не\n * в объёме: в этой проводке сидят инварианты, каждый из которых при пропуске\n * даёт тихий баг доступности, а не заметную поломку. Здесь они собраны в одном\n * месте — забыть часть модального слоя больше нельзя.\n *\n * Что именно неочевидно:\n *\n * - **`restoreFocus: false` у ловушки.** Возврат фокуса принадлежит стеку\n * слоёв: у него правило строже — вернуть, только если на момент закрытия\n * фокус ещё был внутри слоя. Две системы возврата подрались бы за фокус.\n * - **`containers: layer.rootsAbove`.** Панель селекта, открытого ВНУТРИ окна,\n * телепортирована в `body` и лежит вне поддерева панели. Без этого списка\n * ловушка считала бы её «снаружи» и отбирала фокус.\n * - **Ловушка и `inert` работают, только пока слой верхний.** Иначе нижнее\n * окно ворует фокус у открытого поверх него, а `inert` гасит собственную\n * панель вместе со страницей.\n * - **Клик по подложке считается только тот, что на ней и начался.** Иначе\n * выделение текста мышью или перетаскивание, отпущенное за пределами панели,\n * закрывает слой.\n *\n * Чего композабл НЕ делает: не рисует разметку. Корневой `div`, подложка и\n * панель у трёх компонентов различаются по существу (обёртки скролла у окна,\n * сквозные клики у немодальной панели, слои хрома у просмотрщика), а классами\n * общий модуль владеть не вправе — пресет гранулярности подмешивает safelist\n * только по директориям выбранных компонентов.\n */\nexport interface UseModalOverlayOptions {\n /**\n * Модальный ли слой: блокирует страницу, держит фокус, гасит нижние окна.\n * Геттером — там, где модальность включается пропом (`GrDrawer`).\n */\n modal?: boolean | (() => boolean)\n /** Закрывать ли по Esc. Геттер — проп компонента реактивен. */\n closeOnEscape?: () => boolean\n /** Закрывать ли по клику в подложку; читается обработчиками `backdrop`. */\n closeOnBackdrop?: () => boolean\n /** Панель слоя: контейнер ловушки фокуса и её запасной приёмник. */\n panel: Ref<HTMLElement | null>\n /**\n * Свой корень слоя. У якорного оверлея (`GrPopover`) корень и панель — один\n * элемент: в портал уезжает сама панель, отдельной обёртки нет. Не задан —\n * композабл заводит корень сам, как у центрированных окон.\n */\n root?: Ref<HTMLElement | null>\n /**\n * Имя CSS-переменной слоя. Escape-hatch мимо `--gr-z-modal` — им пользуется\n * просмотрщик. Глубина слоя прибавляется и к подменённой переменной.\n */\n zIndexVar?: () => string | undefined\n /**\n * Точечное переопределение точки монтирования (проп `teleportTo`). По\n * умолчанию — общий портал оверлеев.\n */\n teleportTo?: () => string | HTMLElement | undefined\n /**\n * Кому отдать фокус при открытии. Не задан — первому фокусируемому внутри\n * панели (правило `useFocusTrap`): просмотрщику нужна именно кнопка тулбара,\n * а окну — сама панель, и оно передаёт её явно.\n */\n initialFocus?: () => HTMLElement | null | undefined\n /**\n * Блокировать ли скролл страницы. По умолчанию — пока слой открыт и модален:\n * немодальная панель существует ровно ради работы со страницей под ней.\n */\n lockScroll?: () => boolean\n}\n\nexport interface ModalOverlay {\n /** Корень слоя: цель `ref` в шаблоне, хозяин `inert` и корень для стека слоёв. */\n rootEl: Ref<HTMLElement | null>\n /** Смонтировано ли поддерево: держится до конца leave-анимации панели. */\n isMounted: Ref<boolean>\n /** Показан ли слой: этим переключаются `<Transition>` внутри. */\n isVisible: Ref<boolean>\n /** Верхний ли это слой сейчас. */\n isTopmost: Ref<boolean>\n /** Значение атрибута `inert` для корня: слой перестал быть верхним. */\n inertAttr: ComputedRef<true | undefined>\n /**\n * Высота слоя: базовый токен плюс позиция в стеке.\n *\n * Один токен на все модальные слои означал бы, что порядок отрисовки решает\n * порядок узлов в портале, а он задан **созданием** телепорта, а не\n * открытием: статически объявленный диалог вставал бы под окном, открытым\n * позже, и оказывался невидимым — при том что стек считает верхним его.\n */\n layerZIndex: ComputedRef<string>\n portalTarget: ComputedRef<string | HTMLElement>\n teleportEnabled: ComputedRef<boolean>\n /** `data-theme` на телепортированный корень: в DOM он вне обёртки провайдера. */\n themeAttrs: ComputedRef<{ 'data-theme'?: string }>\n /** Для `@after-leave` панели. Компонент оборачивает, если ему нужен эмит `closed`. */\n onPanelAfterLeave: () => void\n /**\n * Обработчики подложки вместе с guard'ом «клик начался на ней». Имена — под\n * `v-on=\"backdrop\"`: объектный синтаксис ждёт имена событий, а не пропов.\n */\n backdrop: {\n mousedown: (event: MouseEvent) => void\n click: (event: MouseEvent) => void\n }\n}\n\nexport function useModalOverlay(\n open: Ref<boolean>,\n onDismiss: () => void,\n options: UseModalOverlayOptions,\n): ModalOverlay {\n const isModal = (): boolean =>\n typeof options.modal === 'function' ? options.modal() : options.modal ?? true\n\n const rootEl = options.root ?? ref<HTMLElement | null>(null)\n const isTopmost = ref(true)\n\n const inertAttr = computed(() => (open.value && isModal() && !isTopmost.value ? true : undefined))\n\n // Телепорт включается только ПОСЛЕ монтирования: иначе первый клиентский\n // рендер не совпадёт с серверным и сломается гидрация.\n const { target: portalTarget, enabled: teleportEnabled } = usePortalTarget(options.teleportTo)\n\n // Панель уезжает в `body`, то есть вне обёртки провайдера, и `data-theme` с\n // неё не наследуется. В дереве компонентов слой остаётся внутри — `inject`\n // доходит, и тему он ставит себе сам.\n const themeAttrs = useGrThemeAttrs()\n\n const { mounted: isMounted, visible: isVisible, onPanelAfterLeave } = useOverlayPresence(open)\n\n const layer = useOverlayLayer(open, onDismiss, {\n modal: isModal,\n closeOnEscape: options.closeOnEscape,\n onTopmostChange: (value) => { isTopmost.value = value },\n root: rootEl,\n })\n\n const layerZIndex = computed(() => modalLayerZIndex(\n layer.depth.value,\n options.zIndexVar?.() ?? '--gr-z-modal',\n ))\n\n useFocusTrap(options.panel, {\n active: () => open.value && isModal() && isTopmost.value,\n initialFocus: options.initialFocus,\n fallbackFocus: () => options.panel.value,\n containers: layer.rootsAbove,\n restoreFocus: false,\n })\n\n useInertOthers(rootEl, () => open.value && isModal() && isTopmost.value)\n\n // Общий reference-counted lock: несколько открытых оверлеев снимают блокировку\n // независимо от порядка закрытия, ширина скроллбара компенсируется.\n const { lock, unlock } = useScrollLock()\n\n watch(\n () => options.lockScroll?.() ?? (open.value && isModal()),\n (locked) => {\n if (locked)\n lock()\n else unlock()\n },\n { immediate: true },\n )\n\n onBeforeUnmount(unlock)\n\n let pointerDownOnBackdrop = false\n\n return {\n rootEl,\n isMounted,\n isVisible,\n isTopmost,\n inertAttr,\n layerZIndex,\n portalTarget,\n teleportEnabled,\n themeAttrs,\n onPanelAfterLeave,\n backdrop: {\n mousedown(event: MouseEvent): void {\n pointerDownOnBackdrop = event.target === event.currentTarget\n },\n click(event: MouseEvent): void {\n const startedHere = pointerDownOnBackdrop\n pointerDownOnBackdrop = false\n\n if (!startedHere || event.target !== event.currentTarget)\n return\n if (options.closeOnBackdrop?.() === false)\n return\n\n onDismiss()\n },\n },\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { o as useGrConfig } from "./context-
|
|
1
|
+
import { o as useGrConfig } from "./context-CPMRfwVr.js";
|
|
2
2
|
import { t as ensurePortalRoot } from "./portalRoot-CVhCgdG6.js";
|
|
3
3
|
import { computed, onMounted, readonly, ref } from "vue";
|
|
4
4
|
//#region src/composables/internal/useTeleportEnabled.ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePortalTarget-
|
|
1
|
+
{"version":3,"file":"usePortalTarget-BhrRgdqW.js","names":[],"sources":["../../src/composables/internal/useTeleportEnabled.ts","../../src/composables/usePortalTarget.ts"],"sourcesContent":["import { onMounted, readonly, ref, type Ref } from 'vue'\n\n/**\n * Можно ли телепортировать содержимое прямо сейчас.\n *\n * Возвращает `false` на сервере И на первом клиентском рендере, `true` — сразу\n * после монтирования. Использовать так:\n *\n * ```vue\n * <teleport to=\"body\" :disabled=\"!teleportEnabled\">…</teleport>\n * ```\n *\n * ## Зачем, если есть `typeof window !== 'undefined'`\n *\n * Проверка окружения выглядит достаточной, но именно она и ломала гидрацию.\n * `isClient` вычисляется в `setup`, поэтому получалось так:\n *\n * - сервер: `window` нет → телепорт выключен → содержимое остаётся НА МЕСТЕ\n * (`:disabled` означает «рендерить на месте», а не «не рендерить»);\n * - клиент, первый рендер: `window` есть → телепорт включён → содержимое сразу\n * уезжает в `body`.\n *\n * Структуры не совпадают, Vue сообщает `Hydration node mismatch`. В лучшем\n * случае это лишний варнинг и осиротевшая копия панели в DOM; в худшем —\n * панель «прилипает» к контейнеру приложения и пишет в него свои стили\n * (`position: fixed` + `display: none` у закрытой панели), после чего страница\n * исчезает целиком.\n *\n * Флаг, поднимаемый в `onMounted`, снимает проблему по построению: **первый**\n * клиентский рендер повторяет серверный, а телепорт включается уже после\n * гидрации. Для компонентов без SSR это ничего не меняет: панели закрыты\n * (`v-show`/`v-if`), а `onMounted` срабатывает в том же тике.\n *\n * Стенд, на котором это воспроизводится и проверяется, — `apps/playground-ssr`.\n */\nexport function useTeleportEnabled(): Readonly<Ref<boolean>> {\n const enabled = ref(false)\n\n onMounted(() => {\n enabled.value = true\n })\n\n return readonly(enabled)\n}\n","import type { ComputedRef } from 'vue'\nimport { computed } from 'vue'\n\nimport { useGrConfig } from '../components/GrConfigProvider/context'\nimport { ensurePortalRoot } from './internal/portalRoot'\nimport { useTeleportEnabled } from './internal/useTeleportEnabled'\n\nexport interface PortalTarget {\n /** Куда телепортировать: элемент портала либо селектор из конфига. */\n target: ComputedRef<string | HTMLElement>\n /**\n * Можно ли телепортировать прямо сейчас. `false` на сервере и на первом\n * клиентском рендере — иначе разметка разъедется на гидрации.\n */\n enabled: ComputedRef<boolean>\n}\n\n/**\n * Куда монтируются оверлеи пакета.\n *\n * Приоритет: локальное переопределение компонента (`teleportTo`) →\n * `portalTarget` из `GrConfigProvider` → общий корень `#gr-portal`, который\n * создаётся при первом обращении.\n *\n * ```vue\n * const { target, enabled } = usePortalTarget(() => props.teleportTo)\n *\n * <teleport :to=\"target\" :disabled=\"!enabled\">…</teleport>\n * ```\n *\n * Композабл публичный: свой оверлей потребителя должен уезжать туда же, куда и\n * оверлеи библиотеки, — иначе он окажется вне ветки портала и будет помечен\n * `inert` вместе со страницей, как только откроется модалка.\n */\nexport function usePortalTarget(local?: () => string | HTMLElement | undefined): PortalTarget {\n const config = useGrConfig()\n const teleportEnabled = useTeleportEnabled()\n\n const target = computed<string | HTMLElement>(() => {\n const explicit = local?.() ?? config.portalTarget?.value\n if (explicit)\n return explicit\n\n // Корень создаётся лениво и только на клиенте; до монтирования телепорт\n // выключен, поэтому `body` здесь — недостижимый запасной вариант, а не\n // рабочая ветка.\n return ensurePortalRoot() ?? 'body'\n })\n\n return { target, enabled: computed(() => teleportEnabled.value) }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCA,SAAgB,qBAA6C;CAC3D,MAAM,UAAU,IAAI,KAAK;CAEzB,gBAAgB;EACd,QAAQ,QAAQ;CAClB,CAAC;CAED,OAAO,SAAS,OAAO;AACzB;;;;;;;;;;;;;;;;;;;;ACTA,SAAgB,gBAAgB,OAA8D;CAC5F,MAAM,SAAS,YAAY;CAC3B,MAAM,kBAAkB,mBAAmB;CAa3C,OAAO;EAAE,QAXM,eAAqC;GAClD,MAAM,WAAW,QAAQ,KAAK,OAAO,cAAc;GACnD,IAAI,UACF,OAAO;GAKT,OAAO,iBAAiB,KAAK;EAC/B,CAES;EAAQ,SAAS,eAAe,gBAAgB,KAAK;CAAE;AAClE"}
|
|
@@ -11,7 +11,7 @@ import { a as allowedExtensionsValidator, f as runFileValidators, i as allowedMi
|
|
|
11
11
|
*
|
|
12
12
|
* Модуль чистый (без Vue): его гоняют юнит-тесты без монтирования.
|
|
13
13
|
*/
|
|
14
|
-
var BYTES_IN_MB =
|
|
14
|
+
var BYTES_IN_MB = 1048576;
|
|
15
15
|
function mbToBytes(mb) {
|
|
16
16
|
return typeof mb === "number" && Number.isFinite(mb) ? mb * BYTES_IN_MB : void 0;
|
|
17
17
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation-5HhpanPP.js","names":[],"sources":["../../src/components/GrForm/fileRule.ts","../../src/components/GrForm/validation.ts"],"sourcesContent":["/**\n * Файловое правило `GrForm` — мост между декларативными `rules` и валидаторами\n * из `src/fileValidation`.\n *\n * Своих проверок здесь нет ни одной: правило собирает те же валидаторы, которые\n * `GrFormFile` и `v-dropzone` запускают на выборе и на drop. Поэтому ограничение,\n * переехавшее из пропов поля в правило формы, не меняет ни поведения, ни текста\n * ошибки — меняется только момент проверки и то, кто о ней сообщает.\n *\n * Модуль чистый (без Vue): его гоняют юнит-тесты без монтирования.\n */\n\nimport {\n acceptValidator,\n allowedExtensionsValidator,\n allowedMimeTypesValidator,\n maxCountValidator,\n maxFileSize,\n maxTotalSizeBytesValidator,\n runFileValidators,\n type FileValidationIssue,\n type FileValidator,\n} from '../../fileValidation'\n\nexport interface GrFormFileRule {\n /** W3C `accept`: `'image/*,.pdf'`. */\n accept?: string\n /** Белый список расширений (с точкой или без). */\n extensions?: string[]\n /** Белый список MIME-типов. */\n mimeTypes?: string[]\n /** Предел размера одного файла в мегабайтах. */\n maxSizeMb?: number\n /** Предел размера одного файла в байтах. Задан вместе с `maxSizeMb` — берётся меньший. */\n maxSizeBytes?: number\n /** Максимум файлов в наборе. */\n maxCount?: number\n /** Суммарный размер набора в мегабайтах. */\n maxTotalSizeMb?: number\n /** Свои валидаторы — тот же тип, что у `GrFormFile` и `v-dropzone`. Идут после встроенных. */\n validators?: FileValidator[]\n}\n\nconst BYTES_IN_MB = 1024 * 1024\n\nfunction mbToBytes(mb: number | undefined): number | undefined {\n return typeof mb === 'number' && Number.isFinite(mb) ? mb * BYTES_IN_MB : undefined\n}\n\nfunction isFile(value: unknown): value is File {\n return typeof File !== 'undefined' && value instanceof File\n}\n\n/**\n * Значение поля как набор файлов. Всё, что файлами не является, даёт пустой\n * набор: правило молчит, а пустоту разбирает `required` движка.\n */\nexport function fileRuleFiles(value: unknown): File[] {\n if (isFile(value))\n return [value]\n if (Array.isArray(value))\n return value.filter(isFile)\n return []\n}\n\n/** Порядок повторяет `GrFormFile`: встроенные проверки, затем валидаторы потребителя. */\nexport function fileRuleValidators(rule: GrFormFileRule): FileValidator[] {\n return [\n acceptValidator(rule.accept),\n ...(rule.extensions ? [allowedExtensionsValidator(rule.extensions)] : []),\n ...(rule.mimeTypes ? [allowedMimeTypesValidator(rule.mimeTypes)] : []),\n maxFileSize({ bytes: rule.maxSizeBytes, mb: rule.maxSizeMb }),\n maxCountValidator(rule.maxCount),\n maxTotalSizeBytesValidator(mbToBytes(rule.maxTotalSizeMb)),\n ...(rule.validators ?? []),\n ]\n}\n\n/**\n * Первая проблема набора или `undefined`. Первая, а не все: у поля формы одна\n * строка ошибки, и файлы тут не исключение — подробный разбор по каждому файлу\n * остаётся за `GrFormFile`.\n */\nexport async function runFileRule(\n value: unknown,\n rule: GrFormFileRule,\n): Promise<FileValidationIssue | undefined> {\n const files = fileRuleFiles(value)\n if (!files.length)\n return undefined\n\n const { issues } = await runFileValidators(files, fileRuleValidators(rule), {\n source: 'form',\n multiple: Array.isArray(value),\n accept: rule.accept,\n })\n\n return issues[0]\n}\n","/**\n * Движок валидации `GrForm` — чистый (без Vue/i18n), тестируется изолированно.\n *\n * Правило описывает набор проверок значения поля; `runFieldRules` прогоняет их по\n * порядку и возвращает первое сообщение об ошибке (или `undefined`, если валидно).\n * Сообщения резолвит потребитель (компонент) через `resolveMessage` — так i18n и\n * дефолтные тексты остаются в компоненте, а движок ничего о них не знает.\n */\n\nimport { resolveFileValidationMessage, type FileValidationIssue } from '../../fileValidation'\nimport { runFileRule, type GrFormFileRule } from './fileRule'\n\nexport type { GrFormFileRule } from './fileRule'\n\nexport type GrFormTrigger = 'blur' | 'change' | 'submit'\n\n/** Результат кастомного валидатора: `true`/void — ок; `false` — ошибка (дефолт-текст); строка — текст ошибки. */\nexport type GrFormValidatorResult = boolean | string | void\n\nexport interface GrFormRule {\n /** Значение обязательно (не пустое). */\n required?: boolean\n /** Готовый текст ошибки — перекрывает дефолтное сообщение любой проверки этого правила. */\n message?: string\n /** Минимум: длина для строки/массива, значение для числа. */\n min?: number\n /** Максимум: длина для строки/массива, значение для числа. */\n max?: number\n /** Точная длина/значение. */\n len?: number\n /** Регулярное выражение (проверяется по `String(value)`). */\n pattern?: RegExp\n /** Встроенный тип-валидатор. */\n type?: 'email' | 'url'\n /** Ограничения для значения `File | File[]`: тип, размер, количество. */\n file?: GrFormFileRule\n /** Кастомный (в т.ч. async) валидатор. Второй аргумент — весь `model`. */\n validator?: (value: unknown, model: Record<string, unknown>) => GrFormValidatorResult | Promise<GrFormValidatorResult>\n /** Когда правило срабатывает. По умолчанию — на любом триггере (blur/change/submit). */\n trigger?: GrFormTrigger | GrFormTrigger[]\n}\n\nexport type GrFormRules = Record<string, GrFormRule | GrFormRule[]>\n\n/** Вид сработавшей проверки — ключ для дефолтного i18n-сообщения. */\nexport type GrFormRuleFailure = 'required' | 'min' | 'max' | 'len' | 'pattern' | 'email' | 'url' | 'file' | 'invalid'\n\nexport type GrFormMessageResolver = (\n kind: GrFormRuleFailure,\n rule: GrFormRule,\n params: Record<string, unknown>,\n) => string\n\n/** Подпись `t()` из `useGranularityTranslations()`: ключ, фолбэк, параметры. */\nexport type GrFormMessageTranslate = (\n key: string,\n fallback: string,\n params?: Record<string, unknown>,\n) => string\n\nconst DEFAULT_MESSAGES: Record<GrFormRuleFailure, string> = {\n required: 'This field is required',\n min: 'Minimum is {min}',\n max: 'Maximum is {max}',\n len: 'Length must be {len}',\n pattern: 'Invalid format',\n email: 'Enter a valid email',\n url: 'Enter a valid URL',\n file: 'Invalid file',\n invalid: 'Invalid value',\n}\n\n/**\n * Дефолтный резолвер сообщений: `rule.message` сильнее всего, иначе ключ\n * `gr.form.<kind>` из локали, иначе английский фолбэк.\n *\n * Вынесен из `GrForm.vue` и экспортируется наружу не «на всякий случай»:\n * `runFieldRules` публичен, но без резолвера бесполезен — любой, кто хочет\n * прогнать те же правила вне формы, обязан был написать свой.\n */\nexport function createGrFormMessageResolver(t: GrFormMessageTranslate): GrFormMessageResolver {\n return (kind, rule, params) => {\n if (rule.message)\n return rule.message\n\n // Текст файловой ошибки приходит от самого валидатора и локализуется его же\n // ключом (`gr.fileValidation.*`): иначе одно и то же «файл не того типа»\n // звучало бы по-разному в поле и в форме. `gr.form.file` — фолбэк на случай\n // вида `file` без issue: сюда движок не приходит, но резолвер публичный.\n const issue = params.issue as FileValidationIssue | undefined\n if (kind === 'file' && issue)\n return resolveFileValidationMessage(issue, t)\n\n return t(`gr.form.${kind}`, DEFAULT_MESSAGES[kind], params)\n }\n}\n\nconst EMAIL_RE = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/\n\nfunction isUrl(value: string): boolean {\n return URL.canParse(value)\n}\n\n/** Пустое значение: `null`/`undefined`/пустая (или пробельная) строка/пустой массив. */\nexport function isEmpty(value: unknown): boolean {\n if (value == null)\n return true\n if (typeof value === 'string')\n return value.trim() === ''\n if (Array.isArray(value))\n return value.length === 0\n return false\n}\n\n/** Мера значения для min/max/len: число → само значение, строка/массив → длина. */\nfunction measure(value: unknown): number {\n if (typeof value === 'number')\n return value\n if (typeof value === 'string')\n return value.length\n if (Array.isArray(value))\n return value.length\n return Number(value)\n}\n\n/** Достаёт значение из объекта по dot-path (`address.city`). */\nexport function getByPath(obj: Record<string, unknown>, path: string): unknown {\n if (!path.includes('.'))\n return obj[path]\n return path.split('.').reduce<unknown>((acc, key) => {\n if (acc && typeof acc === 'object')\n return (acc as Record<string, unknown>)[key]\n return undefined\n }, obj)\n}\n\n/** Записывает значение в объект по dot-path (создаёт промежуточные объекты). */\nexport function setByPath(obj: Record<string, unknown>, path: string, value: unknown): void {\n const keys = path.split('.')\n const last = keys.pop() as string\n let target = obj\n for (const key of keys) {\n if (!target[key] || typeof target[key] !== 'object')\n target[key] = {}\n target = target[key] as Record<string, unknown>\n }\n target[last] = value\n}\n\n/** Нормализует правило(а) поля в массив. */\nexport function toRuleArray(rules: GrFormRule | GrFormRule[] | undefined): GrFormRule[] {\n if (!rules)\n return []\n return Array.isArray(rules) ? rules : [rules]\n}\n\nfunction ruleMatchesTrigger(rule: GrFormRule, trigger?: GrFormTrigger): boolean {\n if (!trigger)\n return true // полная валидация (validate()) — все правила\n if (!rule.trigger)\n return true // правило без триггера срабатывает на любом\n const triggers = Array.isArray(rule.trigger) ? rule.trigger : [rule.trigger]\n return triggers.includes(trigger)\n}\n\n/** Правила поля, применимые для данного триггера (undefined = все). */\nexport function rulesForTrigger(rules: GrFormRule[], trigger?: GrFormTrigger): GrFormRule[] {\n return rules.filter(rule => ruleMatchesTrigger(rule, trigger))\n}\n\n/** Есть ли среди правил `required` (для маркера обязательности в поле). */\nexport function rulesRequired(rules: GrFormRule[]): boolean {\n return rules.some(rule => rule.required === true)\n}\n\n/**\n * Прогоняет правила по порядку, возвращает первое сообщение об ошибке или `undefined`.\n * Пустое необязательное значение проходит все проверки (кроме `required`).\n */\nexport async function runFieldRules(\n value: unknown,\n rules: GrFormRule[],\n model: Record<string, unknown>,\n resolveMessage: GrFormMessageResolver,\n): Promise<string | undefined> {\n for (const rule of rules) {\n const empty = isEmpty(value)\n\n if (rule.required && empty)\n return resolveMessage('required', rule, {})\n // Необязательное пустое значение — остальные проверки этого правила пропускаем.\n if (empty)\n continue\n\n if (rule.type === 'email' && !EMAIL_RE.test(String(value)))\n return resolveMessage('email', rule, {})\n if (rule.type === 'url' && !isUrl(String(value)))\n return resolveMessage('url', rule, {})\n\n if (rule.len != null && measure(value) !== rule.len)\n return resolveMessage('len', rule, { len: rule.len })\n if (rule.min != null && measure(value) < rule.min)\n return resolveMessage('min', rule, { min: rule.min })\n if (rule.max != null && measure(value) > rule.max)\n return resolveMessage('max', rule, { max: rule.max })\n\n if (rule.pattern && !rule.pattern.test(String(value)))\n return resolveMessage('pattern', rule, {})\n\n if (rule.file) {\n const issue = await runFileRule(value, rule.file)\n if (issue)\n return resolveMessage('file', rule, { issue })\n }\n\n if (rule.validator) {\n const result = await rule.validator(value, model)\n if (result === false)\n return rule.message ?? resolveMessage('invalid', rule, {})\n if (typeof result === 'string')\n return result\n }\n }\n\n return undefined\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"validation-BDjqsuGB.js","names":[],"sources":["../../src/components/GrForm/fileRule.ts","../../src/components/GrForm/validation.ts"],"sourcesContent":["/**\n * Файловое правило `GrForm` — мост между декларативными `rules` и валидаторами\n * из `src/fileValidation`.\n *\n * Своих проверок здесь нет ни одной: правило собирает те же валидаторы, которые\n * `GrFormFile` и `v-dropzone` запускают на выборе и на drop. Поэтому ограничение,\n * переехавшее из пропов поля в правило формы, не меняет ни поведения, ни текста\n * ошибки — меняется только момент проверки и то, кто о ней сообщает.\n *\n * Модуль чистый (без Vue): его гоняют юнит-тесты без монтирования.\n */\n\nimport {\n acceptValidator,\n allowedExtensionsValidator,\n allowedMimeTypesValidator,\n maxCountValidator,\n maxFileSize,\n maxTotalSizeBytesValidator,\n runFileValidators,\n type FileValidationIssue,\n type FileValidator,\n} from '../../fileValidation'\n\nexport interface GrFormFileRule {\n /** W3C `accept`: `'image/*,.pdf'`. */\n accept?: string\n /** Белый список расширений (с точкой или без). */\n extensions?: string[]\n /** Белый список MIME-типов. */\n mimeTypes?: string[]\n /** Предел размера одного файла в мегабайтах. */\n maxSizeMb?: number\n /** Предел размера одного файла в байтах. Задан вместе с `maxSizeMb` — берётся меньший. */\n maxSizeBytes?: number\n /** Максимум файлов в наборе. */\n maxCount?: number\n /** Суммарный размер набора в мегабайтах. */\n maxTotalSizeMb?: number\n /** Свои валидаторы — тот же тип, что у `GrFormFile` и `v-dropzone`. Идут после встроенных. */\n validators?: FileValidator[]\n}\n\nconst BYTES_IN_MB = 1024 * 1024\n\nfunction mbToBytes(mb: number | undefined): number | undefined {\n return typeof mb === 'number' && Number.isFinite(mb) ? mb * BYTES_IN_MB : undefined\n}\n\nfunction isFile(value: unknown): value is File {\n return typeof File !== 'undefined' && value instanceof File\n}\n\n/**\n * Значение поля как набор файлов. Всё, что файлами не является, даёт пустой\n * набор: правило молчит, а пустоту разбирает `required` движка.\n */\nexport function fileRuleFiles(value: unknown): File[] {\n if (isFile(value))\n return [value]\n if (Array.isArray(value))\n return value.filter(isFile)\n return []\n}\n\n/** Порядок повторяет `GrFormFile`: встроенные проверки, затем валидаторы потребителя. */\nexport function fileRuleValidators(rule: GrFormFileRule): FileValidator[] {\n return [\n acceptValidator(rule.accept),\n ...(rule.extensions ? [allowedExtensionsValidator(rule.extensions)] : []),\n ...(rule.mimeTypes ? [allowedMimeTypesValidator(rule.mimeTypes)] : []),\n maxFileSize({ bytes: rule.maxSizeBytes, mb: rule.maxSizeMb }),\n maxCountValidator(rule.maxCount),\n maxTotalSizeBytesValidator(mbToBytes(rule.maxTotalSizeMb)),\n ...(rule.validators ?? []),\n ]\n}\n\n/**\n * Первая проблема набора или `undefined`. Первая, а не все: у поля формы одна\n * строка ошибки, и файлы тут не исключение — подробный разбор по каждому файлу\n * остаётся за `GrFormFile`.\n */\nexport async function runFileRule(\n value: unknown,\n rule: GrFormFileRule,\n): Promise<FileValidationIssue | undefined> {\n const files = fileRuleFiles(value)\n if (!files.length)\n return undefined\n\n const { issues } = await runFileValidators(files, fileRuleValidators(rule), {\n source: 'form',\n multiple: Array.isArray(value),\n accept: rule.accept,\n })\n\n return issues[0]\n}\n","/**\n * Движок валидации `GrForm` — чистый (без Vue/i18n), тестируется изолированно.\n *\n * Правило описывает набор проверок значения поля; `runFieldRules` прогоняет их по\n * порядку и возвращает первое сообщение об ошибке (или `undefined`, если валидно).\n * Сообщения резолвит потребитель (компонент) через `resolveMessage` — так i18n и\n * дефолтные тексты остаются в компоненте, а движок ничего о них не знает.\n */\n\nimport { resolveFileValidationMessage, type FileValidationIssue } from '../../fileValidation'\nimport { runFileRule, type GrFormFileRule } from './fileRule'\n\nexport type { GrFormFileRule } from './fileRule'\n\nexport type GrFormTrigger = 'blur' | 'change' | 'submit'\n\n/** Результат кастомного валидатора: `true`/void — ок; `false` — ошибка (дефолт-текст); строка — текст ошибки. */\nexport type GrFormValidatorResult = boolean | string | void\n\nexport interface GrFormRule {\n /** Значение обязательно (не пустое). */\n required?: boolean\n /** Готовый текст ошибки — перекрывает дефолтное сообщение любой проверки этого правила. */\n message?: string\n /** Минимум: длина для строки/массива, значение для числа. */\n min?: number\n /** Максимум: длина для строки/массива, значение для числа. */\n max?: number\n /** Точная длина/значение. */\n len?: number\n /** Регулярное выражение (проверяется по `String(value)`). */\n pattern?: RegExp\n /** Встроенный тип-валидатор. */\n type?: 'email' | 'url'\n /** Ограничения для значения `File | File[]`: тип, размер, количество. */\n file?: GrFormFileRule\n /** Кастомный (в т.ч. async) валидатор. Второй аргумент — весь `model`. */\n validator?: (value: unknown, model: Record<string, unknown>) => GrFormValidatorResult | Promise<GrFormValidatorResult>\n /** Когда правило срабатывает. По умолчанию — на любом триггере (blur/change/submit). */\n trigger?: GrFormTrigger | GrFormTrigger[]\n}\n\nexport type GrFormRules = Record<string, GrFormRule | GrFormRule[]>\n\n/** Вид сработавшей проверки — ключ для дефолтного i18n-сообщения. */\nexport type GrFormRuleFailure = 'required' | 'min' | 'max' | 'len' | 'pattern' | 'email' | 'url' | 'file' | 'invalid'\n\nexport type GrFormMessageResolver = (\n kind: GrFormRuleFailure,\n rule: GrFormRule,\n params: Record<string, unknown>,\n) => string\n\n/** Подпись `t()` из `useGranularityTranslations()`: ключ, фолбэк, параметры. */\nexport type GrFormMessageTranslate = (\n key: string,\n fallback: string,\n params?: Record<string, unknown>,\n) => string\n\nconst DEFAULT_MESSAGES: Record<GrFormRuleFailure, string> = {\n required: 'This field is required',\n min: 'Minimum is {min}',\n max: 'Maximum is {max}',\n len: 'Length must be {len}',\n pattern: 'Invalid format',\n email: 'Enter a valid email',\n url: 'Enter a valid URL',\n file: 'Invalid file',\n invalid: 'Invalid value',\n}\n\n/**\n * Дефолтный резолвер сообщений: `rule.message` сильнее всего, иначе ключ\n * `gr.form.<kind>` из локали, иначе английский фолбэк.\n *\n * Вынесен из `GrForm.vue` и экспортируется наружу не «на всякий случай»:\n * `runFieldRules` публичен, но без резолвера бесполезен — любой, кто хочет\n * прогнать те же правила вне формы, обязан был написать свой.\n */\nexport function createGrFormMessageResolver(t: GrFormMessageTranslate): GrFormMessageResolver {\n return (kind, rule, params) => {\n if (rule.message)\n return rule.message\n\n // Текст файловой ошибки приходит от самого валидатора и локализуется его же\n // ключом (`gr.fileValidation.*`): иначе одно и то же «файл не того типа»\n // звучало бы по-разному в поле и в форме. `gr.form.file` — фолбэк на случай\n // вида `file` без issue: сюда движок не приходит, но резолвер публичный.\n const issue = params.issue as FileValidationIssue | undefined\n if (kind === 'file' && issue)\n return resolveFileValidationMessage(issue, t)\n\n return t(`gr.form.${kind}`, DEFAULT_MESSAGES[kind], params)\n }\n}\n\nconst EMAIL_RE = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/\n\nfunction isUrl(value: string): boolean {\n return URL.canParse(value)\n}\n\n/** Пустое значение: `null`/`undefined`/пустая (или пробельная) строка/пустой массив. */\nexport function isEmpty(value: unknown): boolean {\n if (value == null)\n return true\n if (typeof value === 'string')\n return value.trim() === ''\n if (Array.isArray(value))\n return value.length === 0\n return false\n}\n\n/** Мера значения для min/max/len: число → само значение, строка/массив → длина. */\nfunction measure(value: unknown): number {\n if (typeof value === 'number')\n return value\n if (typeof value === 'string')\n return value.length\n if (Array.isArray(value))\n return value.length\n return Number(value)\n}\n\n/** Достаёт значение из объекта по dot-path (`address.city`). */\nexport function getByPath(obj: Record<string, unknown>, path: string): unknown {\n if (!path.includes('.'))\n return obj[path]\n return path.split('.').reduce<unknown>((acc, key) => {\n if (acc && typeof acc === 'object')\n return (acc as Record<string, unknown>)[key]\n return undefined\n }, obj)\n}\n\n/** Записывает значение в объект по dot-path (создаёт промежуточные объекты). */\nexport function setByPath(obj: Record<string, unknown>, path: string, value: unknown): void {\n const keys = path.split('.')\n const last = keys.pop() as string\n let target = obj\n for (const key of keys) {\n if (!target[key] || typeof target[key] !== 'object')\n target[key] = {}\n target = target[key] as Record<string, unknown>\n }\n target[last] = value\n}\n\n/** Нормализует правило(а) поля в массив. */\nexport function toRuleArray(rules: GrFormRule | GrFormRule[] | undefined): GrFormRule[] {\n if (!rules)\n return []\n return Array.isArray(rules) ? rules : [rules]\n}\n\nfunction ruleMatchesTrigger(rule: GrFormRule, trigger?: GrFormTrigger): boolean {\n if (!trigger)\n return true // полная валидация (validate()) — все правила\n if (!rule.trigger)\n return true // правило без триггера срабатывает на любом\n const triggers = Array.isArray(rule.trigger) ? rule.trigger : [rule.trigger]\n return triggers.includes(trigger)\n}\n\n/** Правила поля, применимые для данного триггера (undefined = все). */\nexport function rulesForTrigger(rules: GrFormRule[], trigger?: GrFormTrigger): GrFormRule[] {\n return rules.filter(rule => ruleMatchesTrigger(rule, trigger))\n}\n\n/** Есть ли среди правил `required` (для маркера обязательности в поле). */\nexport function rulesRequired(rules: GrFormRule[]): boolean {\n return rules.some(rule => rule.required === true)\n}\n\n/**\n * Прогоняет правила по порядку, возвращает первое сообщение об ошибке или `undefined`.\n * Пустое необязательное значение проходит все проверки (кроме `required`).\n */\nexport async function runFieldRules(\n value: unknown,\n rules: GrFormRule[],\n model: Record<string, unknown>,\n resolveMessage: GrFormMessageResolver,\n): Promise<string | undefined> {\n for (const rule of rules) {\n const empty = isEmpty(value)\n\n if (rule.required && empty)\n return resolveMessage('required', rule, {})\n // Необязательное пустое значение — остальные проверки этого правила пропускаем.\n if (empty)\n continue\n\n if (rule.type === 'email' && !EMAIL_RE.test(String(value)))\n return resolveMessage('email', rule, {})\n if (rule.type === 'url' && !isUrl(String(value)))\n return resolveMessage('url', rule, {})\n\n if (rule.len != null && measure(value) !== rule.len)\n return resolveMessage('len', rule, { len: rule.len })\n if (rule.min != null && measure(value) < rule.min)\n return resolveMessage('min', rule, { min: rule.min })\n if (rule.max != null && measure(value) > rule.max)\n return resolveMessage('max', rule, { max: rule.max })\n\n if (rule.pattern && !rule.pattern.test(String(value)))\n return resolveMessage('pattern', rule, {})\n\n if (rule.file) {\n const issue = await runFileRule(value, rule.file)\n if (issue)\n return resolveMessage('file', rule, { issue })\n }\n\n if (rule.validator) {\n const result = await rule.validator(value, model)\n if (result === false)\n return rule.message ?? resolveMessage('invalid', rule, {})\n if (typeof result === 'string')\n return result\n }\n }\n\n return undefined\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { n as check_circle_default, r as alert_triangle_default, t as x_circle_default } from "../../../chunks/x-circle-BCBURwyX.js";
|
|
2
2
|
import { t as info_default } from "../../../chunks/info-Be2OccTu.js";
|
|
3
3
|
import { t as x_default } from "../../../chunks/x-2KXnqxiD.js";
|
|
4
|
-
import { i as useGrComponentProp } from "../../../chunks/context-
|
|
4
|
+
import { i as useGrComponentProp } from "../../../chunks/context-CPMRfwVr.js";
|
|
5
5
|
import { n as useGranularityTranslations } from "../../../chunks/granularityI18n-BC5zsj_d.js";
|
|
6
6
|
import { computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, normalizeClass, normalizeStyle, openBlock, renderSlot, resolveDynamicComponent, toDisplayString, unref } from "vue";
|
|
7
7
|
//#region src/components/GrAlert/grAlertStyles.ts
|