@feugene/granularity 0.49.0 → 0.50.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/chunks/chevron-up-BhW6hi8L.js +23 -0
- package/dist/chunks/chevron-up-BhW6hi8L.js.map +1 -0
- package/dist/chunks/{config-E1cTyRVV.js → config-8n1VR0ju.js} +1 -1
- package/dist/chunks/{config-E1cTyRVV.js.map → config-8n1VR0ju.js.map} +1 -1
- package/dist/chunks/{config-DIDz_E5m.js → config-B34mkd53.js} +66 -1
- package/dist/chunks/config-B34mkd53.js.map +1 -0
- package/dist/chunks/{config-B5SBUa6u.js → config-B7qZqiUB.js} +28 -1
- package/dist/chunks/config-B7qZqiUB.js.map +1 -0
- package/dist/chunks/config-BBrPUEye.js +8 -0
- package/dist/chunks/config-BBrPUEye.js.map +1 -0
- package/dist/chunks/{config-CT4lP6S4.js → config-BOCzHqWh.js} +2 -2
- package/dist/chunks/{config-CT4lP6S4.js.map → config-BOCzHqWh.js.map} +1 -1
- package/dist/chunks/{config-iemgzS4x.js → config-BP1ktzwh.js} +2 -24
- package/dist/chunks/config-BP1ktzwh.js.map +1 -0
- package/dist/chunks/config-BTxmdRzT.js +28 -0
- package/dist/chunks/config-BTxmdRzT.js.map +1 -0
- package/dist/chunks/{config-CjWOTgLL.js → config-Bk52xd5l.js} +12 -5
- package/dist/chunks/config-Bk52xd5l.js.map +1 -0
- package/dist/chunks/{config-D3HOuHDe.js → config-C3SqBqSQ.js} +3 -1
- package/dist/chunks/config-C3SqBqSQ.js.map +1 -0
- package/dist/chunks/{config-2ZHRsdOc.js → config-C3uqd-sW.js} +1 -1
- package/dist/chunks/config-C3uqd-sW.js.map +1 -0
- package/dist/chunks/{config-BXRmsn3t.js → config-CPhcZzHi.js} +72 -10
- package/dist/chunks/config-CPhcZzHi.js.map +1 -0
- package/dist/chunks/config-CWtfxkM9.js.map +1 -1
- package/dist/chunks/{config--t2dxj0t.js → config-CmLTCmY9.js} +2 -2
- package/dist/chunks/{config--t2dxj0t.js.map → config-CmLTCmY9.js.map} +1 -1
- package/dist/chunks/{config-BAse0laT.js → config-CvtqB4ki.js} +8 -3
- package/dist/chunks/config-CvtqB4ki.js.map +1 -0
- package/dist/chunks/{config-BcXX7S7B.js → config-D-JgqV0J.js} +5 -1
- package/dist/chunks/{config-BcXX7S7B.js.map → config-D-JgqV0J.js.map} +1 -1
- package/dist/chunks/{config-BHLMTJaR.js → config-D1oVht-E.js} +8 -3
- package/dist/chunks/config-D1oVht-E.js.map +1 -0
- package/dist/chunks/{config-B42iJ48O.js → config-DG41PD9i.js} +13 -1
- package/dist/chunks/config-DG41PD9i.js.map +1 -0
- package/dist/chunks/{config-Bs1HwUcx.js → config-DPJ3jtiB.js} +12 -2
- package/dist/chunks/config-DPJ3jtiB.js.map +1 -0
- package/dist/chunks/{config-tNqtapcT.js → config-DpqjlCfB.js} +2 -2
- package/dist/chunks/{config-tNqtapcT.js.map → config-DpqjlCfB.js.map} +1 -1
- package/dist/chunks/{config-DNDgp9bB.js → config-DpzFoSIh.js} +64 -2
- package/dist/chunks/config-DpzFoSIh.js.map +1 -0
- package/dist/chunks/config-SPugeaHT.js +37 -0
- package/dist/chunks/config-SPugeaHT.js.map +1 -0
- package/dist/chunks/{en-CsQUoBS2.js → en-mIFywnV2.js} +22 -6
- package/dist/chunks/en-mIFywnV2.js.map +1 -0
- package/dist/chunks/{es-9nbkPvdA.js → es-CvthYwtB.js} +22 -6
- package/dist/chunks/es-CvthYwtB.js.map +1 -0
- package/dist/chunks/{es-DrUz5J6I.js → es-DlGd6Mrj.js} +3 -3
- package/dist/chunks/{es-DrUz5J6I.js.map → es-DlGd6Mrj.js.map} +1 -1
- package/dist/chunks/{generated-CxvC5O0V.js → generated-Cx4C7GRN.js} +84 -0
- package/dist/chunks/{generated-CxvC5O0V.js.map → generated-Cx4C7GRN.js.map} +1 -1
- package/dist/chunks/{grPopoverStyles-CYAeO3Ov.js → grPopoverStyles-CncEkiPu.js} +1 -1
- package/dist/chunks/{grPopoverStyles-CYAeO3Ov.js.map → grPopoverStyles-CncEkiPu.js.map} +1 -1
- package/dist/chunks/{grSelectStyles-D9EQ-pgK.js → grSelectStyles-Cam-IG9s.js} +3 -2
- package/dist/chunks/grSelectStyles-Cam-IG9s.js.map +1 -0
- package/dist/chunks/{grSliderStyles-kaz6VXZ3.js → grSliderStyles-CqzV0hll.js} +1 -1
- package/dist/chunks/grSliderStyles-CqzV0hll.js.map +1 -0
- package/dist/chunks/{config-CbEbLyDE.js → grSortableListStyles-CxieDmpe.js} +1 -27
- package/dist/chunks/grSortableListStyles-CxieDmpe.js.map +1 -0
- package/dist/chunks/grTableStyles-CPSxDTOW.js +66 -0
- package/dist/chunks/grTableStyles-CPSxDTOW.js.map +1 -0
- package/dist/chunks/{config-CMNfZO7S.js → grTabsStyles-DIz2VdIm.js} +1 -36
- package/dist/chunks/grTabsStyles-DIz2VdIm.js.map +1 -0
- package/dist/chunks/grTooltipStyles-CtbGEEGV.js +24 -0
- package/dist/chunks/grTooltipStyles-CtbGEEGV.js.map +1 -0
- package/dist/chunks/{granular-provider-B6xomapW.js → granular-provider-cv5vaM1a.js} +21 -19
- package/dist/chunks/granular-provider-cv5vaM1a.js.map +1 -0
- package/dist/chunks/hotkeySequence-BTHIM_5A.js +46 -0
- package/dist/chunks/hotkeySequence-BTHIM_5A.js.map +1 -0
- package/dist/chunks/{keyboard-DE2yhz_b.js → keyboard-BiFSgWLt.js} +70 -1
- package/dist/chunks/keyboard-BiFSgWLt.js.map +1 -0
- package/dist/chunks/optionPanel-DvY7Tv_4.js +182 -0
- package/dist/chunks/optionPanel-DvY7Tv_4.js.map +1 -0
- package/dist/chunks/overlayListPanel-D91jBCHU.js +21 -0
- package/dist/chunks/overlayListPanel-D91jBCHU.js.map +1 -0
- package/dist/chunks/{overlayStack-DH4Z7am1.js → overlayStack-DCkCgXZP.js} +1 -1
- package/dist/chunks/{overlayStack-DH4Z7am1.js.map → overlayStack-DCkCgXZP.js.map} +1 -1
- package/dist/chunks/{overlayPanelSurface-BKeMhRx4.js → overlayTransition-C0FDMx7Q.js} +24 -24
- package/dist/chunks/overlayTransition-C0FDMx7Q.js.map +1 -0
- package/dist/chunks/{ru-88i1WG0b.js → ru-CQKDR-kD.js} +22 -6
- package/dist/chunks/ru-CQKDR-kD.js.map +1 -0
- package/dist/chunks/{useMenuItemsFocus-B7Bl_aFA.js → useMenuItemsFocus-C031blYS.js} +1 -1
- package/dist/chunks/{useMenuItemsFocus-B7Bl_aFA.js.map → useMenuItemsFocus-C031blYS.js.map} +1 -1
- package/dist/chunks/{useModalOverlay-ACRkflzx.js → useModalOverlay-CKCQkGdB.js} +1 -1
- package/dist/chunks/{useModalOverlay-ACRkflzx.js.map → useModalOverlay-CKCQkGdB.js.map} +1 -1
- package/dist/components/GrAutocomplete/chunks/{GrAutocomplete-Chhw65pI.js → GrAutocomplete-Cyr1-ENw.js} +181 -123
- package/dist/components/GrAutocomplete/chunks/GrAutocomplete-Cyr1-ENw.js.map +1 -0
- package/dist/components/GrAutocomplete/index.js +2 -2
- package/dist/components/GrAutocomplete/styles.css +1 -1
- package/dist/components/GrCarousel/chunks/{GrCarousel-ByuughtI.js → GrCarousel-CBj-PEPB.js} +186 -37
- package/dist/components/GrCarousel/chunks/GrCarousel-CBj-PEPB.js.map +1 -0
- package/dist/components/GrCarousel/index.js +2 -2
- package/dist/components/GrCarousel/styles.css +1 -1
- package/dist/components/GrCheckbox/chunks/{GrCheckbox-Dp201frb.js → GrCheckbox-B4NJc7Ur.js} +2 -1
- package/dist/components/GrCheckbox/chunks/GrCheckbox-B4NJc7Ur.js.map +1 -0
- package/dist/components/GrCheckbox/index.js +1 -1
- package/dist/components/GrCheckboxGroup/chunks/{GrCheckboxGroup-IpqG5qwm.js → GrCheckboxGroup-qZHpNFCX.js} +1 -1
- package/dist/components/GrCheckboxGroup/chunks/{GrCheckboxGroup-IpqG5qwm.js.map → GrCheckboxGroup-qZHpNFCX.js.map} +1 -1
- package/dist/components/GrCheckboxGroup/index.js +1 -1
- package/dist/components/GrColorPicker/chunks/{GrColorPicker-BRM_4lyI.js → GrColorPicker-vGSgpUV9.js} +353 -38
- package/dist/components/GrColorPicker/chunks/GrColorPicker-vGSgpUV9.js.map +1 -0
- package/dist/components/GrColorPicker/index.js +2 -2
- package/dist/components/GrColorPicker/styles.css +1 -1
- package/dist/components/GrCommandPalette/chunks/{GrCommandPalette-BJHmkDQv.js → GrCommandPalette-CAHgj0Aa.js} +23 -7
- package/dist/components/GrCommandPalette/chunks/GrCommandPalette-CAHgj0Aa.js.map +1 -0
- package/dist/components/GrCommandPalette/index.js +1 -1
- package/dist/components/GrCommandPalette/styles.css +1 -1
- package/dist/components/GrConfirmDialog/chunks/{GrConfirmDialog-BzUQwbec.js → GrConfirmDialog-dg021BMd.js} +1 -1
- package/dist/components/GrConfirmDialog/chunks/{GrConfirmDialog-BzUQwbec.js.map → GrConfirmDialog-dg021BMd.js.map} +1 -1
- package/dist/components/GrConfirmDialog/index.js +1 -1
- package/dist/components/GrContextMenu/chunks/{GrContextMenu-RpxMHQXH.js → GrContextMenu-bQ1Vvy2c.js} +3 -3
- package/dist/components/GrContextMenu/chunks/{GrContextMenu-RpxMHQXH.js.map → GrContextMenu-bQ1Vvy2c.js.map} +1 -1
- package/dist/components/GrContextMenu/index.js +1 -1
- package/dist/components/GrDataTable/chunks/{GrDataTable-DQxYYgQk.js → GrDataTable-Bb2jWnRG.js} +576 -136
- package/dist/components/GrDataTable/chunks/GrDataTable-Bb2jWnRG.js.map +1 -0
- package/dist/components/GrDataTable/index.js +2 -2
- package/dist/components/GrDelta/chunks/{GrDelta-CgTvfoIN.js → GrDelta-BSv1KdMy.js} +0 -0
- package/dist/components/GrDelta/chunks/{GrDelta-CgTvfoIN.js.map → GrDelta-BSv1KdMy.js.map} +1 -1
- package/dist/components/GrDelta/index.js +2 -2
- package/dist/components/GrDialog/chunks/{GrDialog-DDz_OEhk.js → GrDialog-C9Zu72jB.js} +1 -1
- package/dist/components/GrDialog/chunks/{GrDialog-DDz_OEhk.js.map → GrDialog-C9Zu72jB.js.map} +1 -1
- package/dist/components/GrDialog/index.js +1 -1
- package/dist/components/GrDialogService/chunks/{GrDialogService-Dtq0ZCN5.js → GrDialogService-DLBifO61.js} +2 -2
- package/dist/components/GrDialogService/chunks/{GrDialogService-Dtq0ZCN5.js.map → GrDialogService-DLBifO61.js.map} +1 -1
- package/dist/components/GrDialogService/index.js +1 -1
- package/dist/components/GrDrawer/chunks/{GrDrawer-CNpSMuN-.js → GrDrawer-DOcRTE8G.js} +1 -1
- package/dist/components/GrDrawer/chunks/{GrDrawer-CNpSMuN-.js.map → GrDrawer-DOcRTE8G.js.map} +1 -1
- package/dist/components/GrDrawer/index.js +1 -1
- package/dist/components/GrDropdown/chunks/{GrDropdown-cLZuZMEY.js → GrDropdown-kxwmgfSe.js} +2 -2
- package/dist/components/GrDropdown/chunks/{GrDropdown-cLZuZMEY.js.map → GrDropdown-kxwmgfSe.js.map} +1 -1
- package/dist/components/GrDropdown/index.js +2 -2
- package/dist/components/GrDropdownMenu/chunks/{GrDropdownMenu-Dxkz_ry4.js → GrDropdownMenu--VoK3VY0.js} +3 -34
- package/dist/components/GrDropdownMenu/chunks/GrDropdownMenu--VoK3VY0.js.map +1 -0
- package/dist/components/GrDropdownMenu/chunks/GrDropdownMenu-CkM3BFPL.js +34 -0
- package/dist/components/GrDropdownMenu/chunks/GrDropdownMenu-CkM3BFPL.js.map +1 -0
- package/dist/components/GrDropdownMenu/index.js +2 -1
- package/dist/components/GrEmptyState/chunks/{GrEmptyState-BbvwE-E0.js → GrEmptyState-Bz6-_ED4.js} +42 -6
- package/dist/components/GrEmptyState/chunks/GrEmptyState-Bz6-_ED4.js.map +1 -0
- package/dist/components/GrEmptyState/index.js +1 -1
- package/dist/components/GrFileUpload/chunks/{GrFileUpload-BwMR71zN.js → GrFileUpload-Bgdfnkd8.js} +5 -2
- package/dist/components/GrFileUpload/chunks/GrFileUpload-Bgdfnkd8.js.map +1 -0
- package/dist/components/GrFileUpload/index.js +1 -1
- package/dist/components/GrFormFile/chunks/{GrFormFile-Dlxx-9zi.js → GrFormFile-Ctq1isz-.js} +78 -11
- package/dist/components/GrFormFile/chunks/GrFormFile-Ctq1isz-.js.map +1 -0
- package/dist/components/GrFormFile/index.js +2 -2
- package/dist/components/GrFormFile/styles.css +1 -1
- package/dist/components/GrImageViewer/chunks/{GrImageViewer-DK-iVHHC.js → GrImageViewer-Bnql_dNP.js} +1 -1
- package/dist/components/GrImageViewer/chunks/{GrImageViewer-DK-iVHHC.js.map → GrImageViewer-Bnql_dNP.js.map} +1 -1
- package/dist/components/GrImageViewer/index.js +1 -1
- package/dist/components/GrInput/chunks/{GrInput-DV4gMWPR.js → GrInput-CoaFLpaU.js} +43 -22
- package/dist/components/GrInput/chunks/GrInput-CoaFLpaU.js.map +1 -0
- package/dist/components/GrInput/index.js +1 -1
- package/dist/components/GrInputTag/chunks/{GrInputTag-qnRdAZnn.js → GrInputTag-BzzNRBe3.js} +245 -18
- package/dist/components/GrInputTag/chunks/GrInputTag-BzzNRBe3.js.map +1 -0
- package/dist/components/GrInputTag/index.js +2 -2
- package/dist/components/GrJsonViewer/chunks/{GrJsonViewer-D7CyWzhT.js → GrJsonViewer-B6ZJ3GFH.js} +2 -2
- package/dist/components/GrJsonViewer/chunks/{GrJsonViewer-D7CyWzhT.js.map → GrJsonViewer-B6ZJ3GFH.js.map} +1 -1
- package/dist/components/GrJsonViewer/index.js +1 -1
- package/dist/components/GrKbd/chunks/{GrKbd-BNMeoaLV.js → GrKbd-D2rHDkQv.js} +42 -37
- package/dist/components/GrKbd/chunks/GrKbd-D2rHDkQv.js.map +1 -0
- package/dist/components/GrKbd/index.js +1 -1
- package/dist/components/GrModal/chunks/{GrModal-Cm0mtSXk.js → GrModal-SHb1U2qx.js} +1 -1
- package/dist/components/GrModal/chunks/{GrModal-Cm0mtSXk.js.map → GrModal-SHb1U2qx.js.map} +1 -1
- package/dist/components/GrModal/index.js +1 -1
- package/dist/components/GrNavbar/chunks/{GrNavbar-BRGuksiy.js → GrNavbar-IEIHC5Vt.js} +10 -4
- package/dist/components/GrNavbar/chunks/GrNavbar-IEIHC5Vt.js.map +1 -0
- package/dist/components/GrNavbar/index.js +2 -2
- package/dist/components/GrNumberInput/chunks/{GrNumberInput-BI6-vkcs.js → GrNumberInput-CmnUDaKi.js} +2 -22
- package/dist/components/GrNumberInput/chunks/{GrNumberInput-BI6-vkcs.js.map → GrNumberInput-CmnUDaKi.js.map} +1 -1
- package/dist/components/GrNumberInput/index.js +1 -1
- package/dist/components/GrPagination/chunks/{GrPagination-CMrLPzvL.js → GrPagination-AMbn5D8I.js} +1 -1
- package/dist/components/GrPagination/chunks/{GrPagination-CMrLPzvL.js.map → GrPagination-AMbn5D8I.js.map} +1 -1
- package/dist/components/GrPagination/index.js +1 -1
- package/dist/components/GrPopover/chunks/{GrPopover-CcWvr1ZA.js → GrPopover-DjVxt8bf.js} +3 -3
- package/dist/components/GrPopover/chunks/{GrPopover-CcWvr1ZA.js.map → GrPopover-DjVxt8bf.js.map} +1 -1
- package/dist/components/GrPopover/index.js +2 -2
- package/dist/components/GrPromptDialog/chunks/{GrPromptDialog-BEL-QgwE.js → GrPromptDialog-BhbIZP1f.js} +3 -3
- package/dist/components/GrPromptDialog/chunks/{GrPromptDialog-BEL-QgwE.js.map → GrPromptDialog-BhbIZP1f.js.map} +1 -1
- package/dist/components/GrPromptDialog/index.js +1 -1
- package/dist/components/GrSelect/chunks/{GrSelect-DvSq-nV-.js → GrSelect-B-ykrHpL.js} +24 -180
- package/dist/components/GrSelect/chunks/GrSelect-B-ykrHpL.js.map +1 -0
- package/dist/components/GrSelect/index.js +2 -2
- package/dist/components/GrSelect/styles.css +1 -1
- package/dist/components/GrSidebar/chunks/GrSidebar-jVvoLGDO.js +543 -0
- package/dist/components/GrSidebar/chunks/GrSidebar-jVvoLGDO.js.map +1 -0
- package/dist/components/GrSidebar/index.js +2 -2
- package/dist/components/GrSlider/chunks/{GrSlider-CO8N9SF6.js → GrSlider-DF2Cq0rV.js} +29 -4
- package/dist/components/GrSlider/chunks/GrSlider-DF2Cq0rV.js.map +1 -0
- package/dist/components/GrSlider/index.js +2 -2
- package/dist/components/GrSortableList/chunks/{GrSortableList-NKriuGm_.js → GrSortableList-ChH9nQBv.js} +1 -1
- package/dist/components/GrSortableList/chunks/{GrSortableList-NKriuGm_.js.map → GrSortableList-ChH9nQBv.js.map} +1 -1
- package/dist/components/GrSortableList/index.js +2 -2
- package/dist/components/GrTabPanels/chunks/GrTabPanels-BDt5oVdd.js +30 -0
- package/dist/components/GrTabPanels/chunks/GrTabPanels-BDt5oVdd.js.map +1 -0
- package/dist/components/GrTabPanels/chunks/GrTabPanels-BJvAflnA.js +83 -0
- package/dist/components/GrTabPanels/chunks/GrTabPanels-BJvAflnA.js.map +1 -0
- package/dist/components/GrTabPanels/index.js +2 -1
- package/dist/components/GrTable/chunks/{GrTable-CKJ-HrsN.js → GrTable-BQitSDep.js} +52 -16
- package/dist/components/GrTable/chunks/GrTable-BQitSDep.js.map +1 -0
- package/dist/components/GrTable/index.js +2 -2
- package/dist/components/GrTabs/chunks/{GrTabs-s9RzC1WX.js → GrTabs-DVC6nfWB.js} +1 -1
- package/dist/components/GrTabs/chunks/{GrTabs-s9RzC1WX.js.map → GrTabs-DVC6nfWB.js.map} +1 -1
- package/dist/components/GrTabs/index.js +2 -2
- package/dist/components/GrTabsWithPanels/chunks/GrTabsWithPanels-BYtuzouj.js +98 -0
- package/dist/components/GrTabsWithPanels/chunks/GrTabsWithPanels-BYtuzouj.js.map +1 -0
- package/dist/components/GrTabsWithPanels/index.js +3 -0
- package/dist/components/GrTextarea/chunks/{GrTextarea-Bfgc0DD2.js → GrTextarea-BFwyqcHB.js} +22 -5
- package/dist/components/GrTextarea/chunks/GrTextarea-BFwyqcHB.js.map +1 -0
- package/dist/components/GrTextarea/index.js +1 -1
- package/dist/components/GrToaster/chunks/{GrToaster-CZixNk0l.js → GrToaster-OzT1VKcp.js} +163 -32
- package/dist/components/GrToaster/chunks/GrToaster-OzT1VKcp.js.map +1 -0
- package/dist/components/GrToaster/index.js +2 -2
- package/dist/components/GrToaster/styles.css +1 -1
- package/dist/components/GrTooltip/chunks/{GrTooltip-DkMMM0uq.js → GrTooltip-BDcFycvW.js} +26 -13
- package/dist/components/GrTooltip/chunks/GrTooltip-BDcFycvW.js.map +1 -0
- package/dist/components/GrTooltip/index.js +2 -2
- package/dist/components/GrTransfer/chunks/{GrTransfer-DdfBUf35.js → GrTransfer-CV7BL5UK.js} +114 -12
- package/dist/components/GrTransfer/chunks/GrTransfer-CV7BL5UK.js.map +1 -0
- package/dist/components/GrTransfer/index.js +1 -1
- package/dist/components/GrTransfer/styles.css +1 -1
- package/dist/components/GrTree/chunks/{GrTree-6yZrncJE.js → GrTree-DpgaP8hk.js} +39 -1
- package/dist/components/GrTree/chunks/GrTree-DpgaP8hk.js.map +1 -0
- package/dist/components/GrTree/index.js +1 -1
- package/dist/components/GrTree/styles.css +1 -1
- package/dist/components/GrTreeSections/chunks/{GrTreeSections-DcmDcLwj.js → GrTreeSections-BeOj__44.js} +1 -1
- package/dist/components/GrTreeSections/chunks/{GrTreeSections-DcmDcLwj.js.map → GrTreeSections-BeOj__44.js.map} +1 -1
- package/dist/components/GrTreeSections/index.js +1 -1
- package/dist/components/GrTreeSelect/chunks/{GrTreeSelect-B6KoDYiZ.js → GrTreeSelect-BHq-T8wH.js} +113 -14
- package/dist/components/GrTreeSelect/chunks/GrTreeSelect-BHq-T8wH.js.map +1 -0
- package/dist/components/GrTreeSelect/index.js +2 -2
- package/dist/composables/useFloating.js +1 -1
- package/dist/composables/useHotkeys.js +89 -0
- package/dist/composables/useHotkeys.js.map +1 -0
- package/dist/composables/useOverlayLayer.js +1 -1
- package/dist/directives/hotkey.js +19 -46
- package/dist/directives/hotkey.js.map +1 -1
- package/dist/granular-provider-node.js +1 -1
- package/dist/granular-provider.js +1 -1
- package/dist/i18n/all.js +1 -1
- package/dist/i18n/index.js +1 -1
- package/dist/index.js +71 -63
- package/dist/theme.js +1 -1
- package/dist/tokens.js +1 -1
- package/dist/types/components/GrAutocomplete/GrAutocomplete.vue.d.ts +4 -4
- package/dist/types/components/GrAutocomplete/composables/useAutocompleteNavigation.d.ts +12 -3
- package/dist/types/components/GrAutocomplete/composables/useAutocompletePanel.d.ts +12 -2
- package/dist/types/components/GrAutocomplete/composables/useAutocompleteValues.d.ts +7 -4
- package/dist/types/components/GrAutocomplete/composables/useRemoteOptions.d.ts +4 -4
- package/dist/types/components/GrAutocomplete/grAutocompleteStyles.d.ts +15 -1
- package/dist/types/components/GrAutocomplete/index.d.ts +1 -1
- package/dist/types/components/GrCarousel/GrCarousel.vue.d.ts +29 -1
- package/dist/types/components/GrCarousel/composables/useCarouselSwipe.d.ts +5 -0
- package/dist/types/components/GrCarousel/grCarouselContext.d.ts +21 -0
- package/dist/types/components/GrCarousel/grCarouselStyles.d.ts +39 -9
- package/dist/types/components/GrCheckbox/GrCheckbox.vue.d.ts +13 -0
- package/dist/types/components/GrColorPicker/GrColorPicker.vue.d.ts +18 -2
- package/dist/types/components/GrColorPicker/color.d.ts +13 -1
- package/dist/types/components/GrColorPicker/colorArea.d.ts +59 -0
- package/dist/types/components/GrColorPicker/defaults.d.ts +3 -1
- package/dist/types/components/GrColorPicker/eyeDropper.d.ts +21 -0
- package/dist/types/components/GrColorPicker/grColorPickerStyles.d.ts +42 -0
- package/dist/types/components/GrCommandPalette/GrCommandPalette.vue.d.ts +10 -1
- package/dist/types/components/GrDataTable/GrDataTable.vue.d.ts +41 -1
- package/dist/types/components/GrDataTable/composables/useDataTableGridNavigation.d.ts +53 -0
- package/dist/types/components/GrDataTable/grDataTableStyles.d.ts +8 -0
- package/dist/types/components/GrDataTable/index.d.ts +1 -1
- package/dist/types/components/GrDelta/grDeltaStyles.d.ts +10 -3
- package/dist/types/components/GrEmptyState/GrEmptyState.vue.d.ts +11 -2
- package/dist/types/components/GrEmptyState/grEmptyStateStyles.d.ts +10 -0
- package/dist/types/components/GrEmptyState/index.d.ts +1 -1
- package/dist/types/components/GrFileUpload/GrFileUpload.vue.d.ts +2 -1
- package/dist/types/components/GrFormFile/GrFormFile.vue.d.ts +10 -0
- package/dist/types/components/GrInput/GrInput.vue.d.ts +15 -0
- package/dist/types/components/GrInputTag/GrInputTag.vue.d.ts +16 -0
- package/dist/types/components/GrInputTag/grInputTagStyles.d.ts +11 -0
- package/dist/types/components/GrKbd/GrKbd.vue.d.ts +14 -0
- package/dist/types/components/GrNavbar/GrNavbar.vue.d.ts +18 -0
- package/dist/types/components/GrNavbar/grNavbarStyles.d.ts +10 -1
- package/dist/types/components/GrNavbar/index.d.ts +1 -0
- package/dist/types/components/GrSelect/composables/useSelectPanelItems.d.ts +8 -34
- package/dist/types/components/GrSelect/composables/useSelectVirtualization.d.ts +7 -0
- package/dist/types/components/GrSelect/grSelectStyles.d.ts +1 -1
- package/dist/types/components/GrSidebar/GrSidebar.vue.d.ts +20 -0
- package/dist/types/components/GrSidebar/GrSidebarItem.vue.d.ts +39 -5
- package/dist/types/components/GrSidebar/grSidebarStyles.d.ts +32 -0
- package/dist/types/components/GrSidebar/index.d.ts +1 -1
- package/dist/types/components/GrSidebar/sidebarContext.d.ts +23 -1
- package/dist/types/components/GrSlider/GrSlider.vue.d.ts +39 -1
- package/dist/types/components/GrSlider/grSliderStyles.d.ts +1 -1
- package/dist/types/components/GrTabPanels/context.d.ts +6 -0
- package/dist/types/components/GrTable/GrTable.vue.d.ts +37 -0
- package/dist/types/components/GrTable/grTableStyles.d.ts +16 -7
- package/dist/types/components/GrTabsWithPanels/GrTabsWithPanels.vue.d.ts +77 -0
- package/dist/types/components/GrTabsWithPanels/config.d.ts +1 -0
- package/dist/types/components/GrTabsWithPanels/index.d.ts +4 -0
- package/dist/types/components/GrTextarea/GrTextarea.vue.d.ts +19 -1
- package/dist/types/components/GrToaster/GrToaster.vue.d.ts +12 -0
- package/dist/types/components/GrToaster/grToasterStyles.d.ts +26 -0
- package/dist/types/components/GrTooltip/GrTooltip.vue.d.ts +22 -0
- package/dist/types/components/GrTransfer/GrTransfer.vue.d.ts +23 -0
- package/dist/types/components/GrTreeSelect/grTreeSelectStyles.d.ts +1 -1
- package/dist/types/components/GrTreeSelect/grTreeSelectTypes.d.ts +20 -0
- package/dist/types/components/shared/hotkey.d.ts +8 -9
- package/dist/types/components/shared/optionPanel.d.ts +100 -0
- package/dist/types/components/shared/overlayListPanel.d.ts +18 -0
- package/dist/types/composables/useHotkeys.d.ts +43 -0
- package/dist/types/granular-provider/shared.d.ts +1 -0
- package/dist/types/i18n/messages/en.d.ts +28 -0
- package/dist/types/i18n/messages/es.d.ts +28 -0
- package/dist/types/i18n/messages/ru.d.ts +28 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/internal/hotkeySequence.d.ts +22 -0
- package/dist/types/internal/keyboard.d.ts +45 -0
- package/dist/web-types.json +463 -26
- package/package.json +9 -1
- package/dist/chunks/config-2ZHRsdOc.js.map +0 -1
- package/dist/chunks/config-B42iJ48O.js.map +0 -1
- package/dist/chunks/config-B5SBUa6u.js.map +0 -1
- package/dist/chunks/config-BAse0laT.js.map +0 -1
- package/dist/chunks/config-BHLMTJaR.js.map +0 -1
- package/dist/chunks/config-BXRmsn3t.js.map +0 -1
- package/dist/chunks/config-Bs1HwUcx.js.map +0 -1
- package/dist/chunks/config-CMNfZO7S.js.map +0 -1
- package/dist/chunks/config-CbEbLyDE.js.map +0 -1
- package/dist/chunks/config-CjWOTgLL.js.map +0 -1
- package/dist/chunks/config-D3HOuHDe.js.map +0 -1
- package/dist/chunks/config-DIDz_E5m.js.map +0 -1
- package/dist/chunks/config-DNDgp9bB.js.map +0 -1
- package/dist/chunks/config-iemgzS4x.js.map +0 -1
- package/dist/chunks/en-CsQUoBS2.js.map +0 -1
- package/dist/chunks/es-9nbkPvdA.js.map +0 -1
- package/dist/chunks/grSelectStyles-D9EQ-pgK.js.map +0 -1
- package/dist/chunks/grSliderStyles-kaz6VXZ3.js.map +0 -1
- package/dist/chunks/grTableStyles-DkQPMfx9.js +0 -39
- package/dist/chunks/grTableStyles-DkQPMfx9.js.map +0 -1
- package/dist/chunks/granular-provider-B6xomapW.js.map +0 -1
- package/dist/chunks/keyboard-DE2yhz_b.js.map +0 -1
- package/dist/chunks/overlayPanelSurface-BKeMhRx4.js.map +0 -1
- package/dist/chunks/ru-88i1WG0b.js.map +0 -1
- package/dist/components/GrAutocomplete/chunks/GrAutocomplete-Chhw65pI.js.map +0 -1
- package/dist/components/GrCarousel/chunks/GrCarousel-ByuughtI.js.map +0 -1
- package/dist/components/GrCheckbox/chunks/GrCheckbox-Dp201frb.js.map +0 -1
- package/dist/components/GrColorPicker/chunks/GrColorPicker-BRM_4lyI.js.map +0 -1
- package/dist/components/GrCommandPalette/chunks/GrCommandPalette-BJHmkDQv.js.map +0 -1
- package/dist/components/GrDataTable/chunks/GrDataTable-DQxYYgQk.js.map +0 -1
- package/dist/components/GrDropdownMenu/chunks/GrDropdownMenu-Dxkz_ry4.js.map +0 -1
- package/dist/components/GrEmptyState/chunks/GrEmptyState-BbvwE-E0.js.map +0 -1
- package/dist/components/GrFileUpload/chunks/GrFileUpload-BwMR71zN.js.map +0 -1
- package/dist/components/GrFormFile/chunks/GrFormFile-Dlxx-9zi.js.map +0 -1
- package/dist/components/GrInput/chunks/GrInput-DV4gMWPR.js.map +0 -1
- package/dist/components/GrInputTag/chunks/GrInputTag-qnRdAZnn.js.map +0 -1
- package/dist/components/GrKbd/chunks/GrKbd-BNMeoaLV.js.map +0 -1
- package/dist/components/GrNavbar/chunks/GrNavbar-BRGuksiy.js.map +0 -1
- package/dist/components/GrSelect/chunks/GrSelect-DvSq-nV-.js.map +0 -1
- package/dist/components/GrSidebar/chunks/GrSidebar-DoKLlHSw.js +0 -264
- package/dist/components/GrSidebar/chunks/GrSidebar-DoKLlHSw.js.map +0 -1
- package/dist/components/GrSlider/chunks/GrSlider-CO8N9SF6.js.map +0 -1
- package/dist/components/GrTabPanels/chunks/GrTabPanels-5zsbqS1v.js +0 -92
- package/dist/components/GrTabPanels/chunks/GrTabPanels-5zsbqS1v.js.map +0 -1
- package/dist/components/GrTable/chunks/GrTable-CKJ-HrsN.js.map +0 -1
- package/dist/components/GrTextarea/chunks/GrTextarea-Bfgc0DD2.js.map +0 -1
- package/dist/components/GrToaster/chunks/GrToaster-CZixNk0l.js.map +0 -1
- package/dist/components/GrTooltip/chunks/GrTooltip-DkMMM0uq.js.map +0 -1
- package/dist/components/GrTransfer/chunks/GrTransfer-DdfBUf35.js.map +0 -1
- package/dist/components/GrTree/chunks/GrTree-6yZrncJE.js.map +0 -1
- package/dist/components/GrTreeSelect/chunks/GrTreeSelect-B6KoDYiZ.js.map +0 -1
- package/dist/types/components/GrAutocomplete/composables/useAutocompleteVirtual.d.ts +0 -33
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GrDelta-CgTvfoIN.js","names":[],"sources":["../../../../src/internal/granularityFormat.ts","../../../../src/components/GrDelta/GrDelta.vue","../../../../src/components/GrDelta/GrDelta.vue"],"sourcesContent":["/**\n * Форматирование чисел и дат по локали.\n *\n * Своё, а не из `@feugene/fint-i18n`: тот объявлен **опциональной** peer-зависимостью,\n * и пакет обязан работать без него. Под капотом всё равно `Intl`, то есть\n * результат совпадает с `useI18nFormat()` библиотеки — расхождения между\n * приложением с i18n и без него не возникает.\n *\n * Инстансы `Intl` кэшируются: их построение примерно на порядок дороже самого\n * форматирования. Кэш ограничен — иначе сгенерированные на лету опции растили\n * бы его без предела, — и вытесняет по давности чтения.\n */\n\nconst CACHE_LIMIT = 64\n\nconst numberFormats = new Map<string, Intl.NumberFormat>()\nconst dateFormats = new Map<string, Intl.DateTimeFormat>()\n\nfunction cacheKey(locale: string, options?: object): string {\n return options ? `${locale}\u0000${JSON.stringify(options)}` : locale\n}\n\nfunction take<T>(cache: Map<string, T>, key: string, create: () => T): T {\n const cached = cache.get(key)\n if (cached) {\n // Перечитанная запись уезжает в конец очереди. `Map` держит порядок\n // вставки, и это единственный способ отличить горячую запись от давней.\n cache.delete(key)\n cache.set(key, cached)\n\n return cached\n }\n\n const created = create()\n\n // Вытесняется самая давняя запись, а не весь кэш разом: у таблицы с десятком\n // колонок в нескольких локалях рабочий набор перерастает предел, и сброс\n // целиком пересоздавал бы на каждой вставке в том числе и горячие форматтеры.\n if (cache.size >= CACHE_LIMIT) {\n const oldest = cache.keys().next()\n if (!oldest.done)\n cache.delete(oldest.value)\n }\n\n cache.set(key, created)\n\n return created\n}\n\n/**\n * Локаль приходит из настроек приложения, а `Intl` бросает на некорректном\n * теге. Форматирование не имеет права уронить рендер, поэтому неизвестный тег\n * сводим к `en`.\n */\nexport function formatNumber(\n locale: string,\n value: number | bigint,\n options?: Intl.NumberFormatOptions,\n): string {\n try {\n return take(numberFormats, cacheKey(locale, options), () => new Intl.NumberFormat(locale, options)).format(value)\n }\n catch {\n return take(numberFormats, cacheKey('en', options), () => new Intl.NumberFormat('en', options)).format(value)\n }\n}\n\n/**\n * Те же правила, что у `formatNumber`, но по частям: вызывающему нужно знать,\n * где в записи стоит знак, чтобы вынести его отдельным узлом.\n *\n * Инстанс тот же, что у `formatNumber`: `Intl.NumberFormat` умеет оба метода, а\n * второй кэш под теми же ключами разъехался бы с первым на первом вытеснении.\n */\nexport function formatNumberToParts(\n locale: string,\n value: number | bigint,\n options?: Intl.NumberFormatOptions,\n): Intl.NumberFormatPart[] {\n try {\n return take(numberFormats, cacheKey(locale, options), () => new Intl.NumberFormat(locale, options)).formatToParts(value)\n }\n catch {\n return take(numberFormats, cacheKey('en', options), () => new Intl.NumberFormat('en', options)).formatToParts(value)\n }\n}\n\n/**\n * Ведущий знак и остаток записи.\n *\n * Нужно там, где знаку полагается свой узел разметки: валюта обязана стоять\n * после знака (`+$0,03`, а не `$+0,03`). Резать готовую строку по первому\n * символу нельзя — в RTL-локалях знаку предшествует невидимая метка\n * направления (`he-IL` — U+200E, `ar-EG` — U+061C), которой и разворачивается\n * минус относительно цифр. Метка уходит вместе со знаком: она управляет им.\n *\n * `sign` пуст, когда знака нет вовсе (ноль, положительное при `signDisplay:\n * 'auto'`, `NaN`) либо когда перед ним стоит содержательная часть. Во втором\n * случае запись не делится совсем: вернуть половину по догадке хуже, чем\n * вернуть целое.\n */\nexport function splitLeadingSign(\n parts: readonly Intl.NumberFormatPart[],\n): { sign: string, rest: string } {\n const join = (from: readonly Intl.NumberFormatPart[]): string => from.map(part => part.value).join('')\n const at = parts.findIndex(part => part.type === 'minusSign' || part.type === 'plusSign')\n\n if (at === -1 || parts.slice(0, at).some(part => part.type !== 'literal'))\n return { sign: '', rest: join(parts) }\n\n return { sign: join(parts.slice(0, at + 1)), rest: join(parts.slice(at + 1)) }\n}\n\nexport function formatDate(\n locale: string,\n value: Date | number | string,\n options?: Intl.DateTimeFormatOptions,\n): string {\n const date = value instanceof Date ? value : new Date(value)\n\n // Невалидную дату возвращаем как есть: пустая или «Invalid Date» в интерфейсе\n // хуже, чем исходное значение, но лучше, чем исключение на рендере.\n if (Number.isNaN(date.getTime()))\n return String(value)\n\n try {\n return take(dateFormats, cacheKey(locale, options), () => new Intl.DateTimeFormat(locale, options)).format(date)\n }\n catch {\n return take(dateFormats, cacheKey('en', options), () => new Intl.DateTimeFormat('en', options)).format(date)\n }\n}\n","<script setup lang=\"ts\">\nimport { computed, watchEffect } from 'vue'\n\nimport { formatNumberToParts, splitLeadingSign } from '../../internal/granularityFormat'\nimport GrValue from '../GrValue'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport { useGrComponentProp, useGrComponentSize } from '../GrConfigProvider/context'\n\nimport IconMinus from '~icons/lucide/minus'\nimport IconTrendingDown from '~icons/lucide/trending-down'\nimport IconTrendingUp from '~icons/lucide/trending-up'\n\nimport { deltaDirection, deltaTone, type GrDeltaPolarity, type GrDeltaTone } from './deltaTone'\nimport {\n deltaArrowClass,\n deltaEmptyClass,\n deltaRootClass,\n deltaSizeClass,\n deltaValueStyle,\n deltaToneClass,\n} from './grDeltaStyles'\n\nimport type { GrComponentSize } from '../shared/sizes'\n\nexport type { GrDeltaPolarity, GrDeltaTone } from './deltaTone'\n\n/**\n * Величина со знаком и тоном **внутри строки текста**: «Дельта: +$0.004».\n *\n * Компонент презентационный: дельту не считает и периоды не сравнивает —\n * «к чему сравнивать» знает приложение. Блочная плитка показателя — `GrStatistic`.\n */\nexport interface GrDeltaProps {\n /** Величина. `null` — её нет; это не ноль. */\n value: number | null\n /** Знаков после запятой. Не задано — как отдаст локаль. */\n precision?: number\n /** Приписка перед числом: валюта, единица. */\n prefix?: string\n /** Приписка после числа: `%`, `мс`. */\n suffix?: string\n /**\n * Что считать хорошим. Для выручки рост — успех, для себестоимости и времени\n * отклика — наоборот; без этого компонент врал бы в половине случаев.\n */\n polarity?: GrDeltaPolarity\n /** Ставить `+` у положительных. Минус подставляет `Intl` сам. */\n showSign?: boolean\n /** Стрелка направления. Декоративна: направление уже в знаке. */\n showArrow?: boolean\n /** Чем печатать отсутствующую величину. */\n emptyText?: string\n /** Локаль форматирования. Не задана — локаль i18n-адаптера. */\n locale?: string\n size?: GrComponentSize\n}\n\nconst props = withDefaults(defineProps<GrDeltaProps>(), {\n // Дефолты живут в резолверах ниже: Vue подставил бы свой раньше, чем\n // компонент заглянет в `GrConfigProvider`.\n precision: undefined,\n prefix: undefined,\n suffix: undefined,\n polarity: undefined,\n showSign: undefined,\n showArrow: undefined,\n emptyText: undefined,\n locale: undefined,\n size: undefined,\n})\n\nconst { locale, t } = useGranularityTranslations()\n\nconst resolvedSize = useGrComponentSize(() => props.size, { component: 'GrDelta' })\nconst resolvedLocale = computed(() => props.locale ?? locale.value ?? 'en')\nconst resolvedPolarity = useGrComponentProp('GrDelta', 'polarity', () => props.polarity, 'positive-good')\nconst resolvedShowSign = useGrComponentProp('GrDelta', 'showSign', () => props.showSign, true)\nconst resolvedShowArrow = useGrComponentProp('GrDelta', 'showArrow', () => props.showArrow, false)\nconst resolvedEmptyText = useGrComponentProp('GrDelta', 'emptyText', () => props.emptyText, '—')\n\nconst isEmpty = computed(() => props.value === null || props.value === undefined)\n\nconst tone = computed<GrDeltaTone>(() => (\n isEmpty.value ? 'neutral' : deltaTone(props.value as number, resolvedPolarity.value)\n))\n\nconst direction = computed(() => (isEmpty.value ? 'flat' : deltaDirection(props.value as number)))\n\nconst formatOptions = computed<Intl.NumberFormatOptions>(() => ({\n signDisplay: resolvedShowSign.value ? 'exceptZero' : 'auto',\n ...(props.precision === undefined\n ? {}\n : { minimumFractionDigits: props.precision, maximumFractionDigits: props.precision }),\n}))\n\n/**\n * Знак и число по отдельности.\n *\n * Знак — префикс форматирования, а не склейка строки. `'+' + value` уже ломало\n * `GrStatistic`: строка `'+10'` разбирается как число, и разряды теряются.\n * Поэтому знак не дописывают, а **вынимают** из готовых частей `Intl`.\n *\n * Делится величина только вместе с `prefix`: валюта обязана стоять после знака\n * (`+$0,0280`, а не `$+0,0280`). Без приписки делить нечего — знак остаётся\n * внутри величины, и разметка не меняется ни на байт.\n */\nconst valueNodes = computed<{ sign: string, value: string }>(() => {\n if (isEmpty.value)\n return { sign: '', value: resolvedEmptyText.value }\n\n const parts = formatNumberToParts(resolvedLocale.value, props.value as number, formatOptions.value)\n\n if (!props.prefix)\n return { sign: '', value: parts.map(part => part.value).join('') }\n\n const { sign, rest } = splitLeadingSign(parts)\n\n return { sign, value: rest }\n})\n\nconst sign = computed(() => valueNodes.value.sign)\nconst formatted = computed(() => valueNodes.value.value)\n\nconst arrowIcon = computed(() => {\n if (direction.value === 'up')\n return IconTrendingUp\n if (direction.value === 'down')\n return IconTrendingDown\n return IconMinus\n})\n\n/**\n * Направление словом — когда знака в записи нет.\n *\n * `showSign: false` убирает плюс у роста, и направление остаётся на тоне, то\n * есть на цвете: WCAG 1.4.1. Падение этим не задето — минус `Intl` печатает\n * всегда, а у нуля направления нет вовсе.\n */\nconst spokenDirection = computed(() => (\n !isEmpty.value && !resolvedShowSign.value && direction.value === 'up'\n ? t('gr.delta.increase', 'increase')\n : ''\n))\n\nif (__GR_DEV__) {\n watchEffect(() => {\n // `null` — заявленное «величины нет», `undefined` — забытый проп. На экране\n // они неотличимы, и промах выглядит как честный прочерк.\n if (props.value === undefined) {\n console.warn(\n '[granularity] GrDelta: обязательный проп `value` не передан — нарисован прочерк. '\n + 'Отсутствие величины объявляется явным `null`.',\n )\n }\n })\n}\n\nconst rootClass = computed(() => [\n deltaRootClass,\n deltaSizeClass[resolvedSize.value],\n isEmpty.value ? deltaEmptyClass : deltaToneClass[tone.value],\n].filter(Boolean).join(' '))\n</script>\n\n<template>\n <span data-gr-delta :data-tone=\"isEmpty ? undefined : tone\" :class=\"rootClass\" :style=\"deltaValueStyle\">\n <component\n :is=\"arrowIcon\"\n v-if=\"resolvedShowArrow && !isEmpty\"\n data-gr-delta-arrow\n :class=\"deltaArrowClass\"\n aria-hidden=\"true\"\n />\n\n <!-- Запись величины рисует `GrValue`: приписки оформляются там же, где у\n остальных величин пакета, и настраиваются теми же токенами. Знак идёт\n в `#lead` — он обязан встать перед валютой, а не после неё. -->\n <GrValue\n :value=\"formatted\"\n :prefix=\"isEmpty ? undefined : prefix\"\n :suffix=\"isEmpty ? undefined : suffix\"\n >\n <template v-if=\"sign\" #lead>\n <span data-gr-delta-sign>{{ sign }}</span>\n </template>\n\n </GrValue>\n\n <span v-if=\"spokenDirection\" data-gr-delta-direction class=\"sr-only\">{{ spokenDirection }}</span>\n </span>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, watchEffect } from 'vue'\n\nimport { formatNumberToParts, splitLeadingSign } from '../../internal/granularityFormat'\nimport GrValue from '../GrValue'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport { useGrComponentProp, useGrComponentSize } from '../GrConfigProvider/context'\n\nimport IconMinus from '~icons/lucide/minus'\nimport IconTrendingDown from '~icons/lucide/trending-down'\nimport IconTrendingUp from '~icons/lucide/trending-up'\n\nimport { deltaDirection, deltaTone, type GrDeltaPolarity, type GrDeltaTone } from './deltaTone'\nimport {\n deltaArrowClass,\n deltaEmptyClass,\n deltaRootClass,\n deltaSizeClass,\n deltaValueStyle,\n deltaToneClass,\n} from './grDeltaStyles'\n\nimport type { GrComponentSize } from '../shared/sizes'\n\nexport type { GrDeltaPolarity, GrDeltaTone } from './deltaTone'\n\n/**\n * Величина со знаком и тоном **внутри строки текста**: «Дельта: +$0.004».\n *\n * Компонент презентационный: дельту не считает и периоды не сравнивает —\n * «к чему сравнивать» знает приложение. Блочная плитка показателя — `GrStatistic`.\n */\nexport interface GrDeltaProps {\n /** Величина. `null` — её нет; это не ноль. */\n value: number | null\n /** Знаков после запятой. Не задано — как отдаст локаль. */\n precision?: number\n /** Приписка перед числом: валюта, единица. */\n prefix?: string\n /** Приписка после числа: `%`, `мс`. */\n suffix?: string\n /**\n * Что считать хорошим. Для выручки рост — успех, для себестоимости и времени\n * отклика — наоборот; без этого компонент врал бы в половине случаев.\n */\n polarity?: GrDeltaPolarity\n /** Ставить `+` у положительных. Минус подставляет `Intl` сам. */\n showSign?: boolean\n /** Стрелка направления. Декоративна: направление уже в знаке. */\n showArrow?: boolean\n /** Чем печатать отсутствующую величину. */\n emptyText?: string\n /** Локаль форматирования. Не задана — локаль i18n-адаптера. */\n locale?: string\n size?: GrComponentSize\n}\n\nconst props = withDefaults(defineProps<GrDeltaProps>(), {\n // Дефолты живут в резолверах ниже: Vue подставил бы свой раньше, чем\n // компонент заглянет в `GrConfigProvider`.\n precision: undefined,\n prefix: undefined,\n suffix: undefined,\n polarity: undefined,\n showSign: undefined,\n showArrow: undefined,\n emptyText: undefined,\n locale: undefined,\n size: undefined,\n})\n\nconst { locale, t } = useGranularityTranslations()\n\nconst resolvedSize = useGrComponentSize(() => props.size, { component: 'GrDelta' })\nconst resolvedLocale = computed(() => props.locale ?? locale.value ?? 'en')\nconst resolvedPolarity = useGrComponentProp('GrDelta', 'polarity', () => props.polarity, 'positive-good')\nconst resolvedShowSign = useGrComponentProp('GrDelta', 'showSign', () => props.showSign, true)\nconst resolvedShowArrow = useGrComponentProp('GrDelta', 'showArrow', () => props.showArrow, false)\nconst resolvedEmptyText = useGrComponentProp('GrDelta', 'emptyText', () => props.emptyText, '—')\n\nconst isEmpty = computed(() => props.value === null || props.value === undefined)\n\nconst tone = computed<GrDeltaTone>(() => (\n isEmpty.value ? 'neutral' : deltaTone(props.value as number, resolvedPolarity.value)\n))\n\nconst direction = computed(() => (isEmpty.value ? 'flat' : deltaDirection(props.value as number)))\n\nconst formatOptions = computed<Intl.NumberFormatOptions>(() => ({\n signDisplay: resolvedShowSign.value ? 'exceptZero' : 'auto',\n ...(props.precision === undefined\n ? {}\n : { minimumFractionDigits: props.precision, maximumFractionDigits: props.precision }),\n}))\n\n/**\n * Знак и число по отдельности.\n *\n * Знак — префикс форматирования, а не склейка строки. `'+' + value` уже ломало\n * `GrStatistic`: строка `'+10'` разбирается как число, и разряды теряются.\n * Поэтому знак не дописывают, а **вынимают** из готовых частей `Intl`.\n *\n * Делится величина только вместе с `prefix`: валюта обязана стоять после знака\n * (`+$0,0280`, а не `$+0,0280`). Без приписки делить нечего — знак остаётся\n * внутри величины, и разметка не меняется ни на байт.\n */\nconst valueNodes = computed<{ sign: string, value: string }>(() => {\n if (isEmpty.value)\n return { sign: '', value: resolvedEmptyText.value }\n\n const parts = formatNumberToParts(resolvedLocale.value, props.value as number, formatOptions.value)\n\n if (!props.prefix)\n return { sign: '', value: parts.map(part => part.value).join('') }\n\n const { sign, rest } = splitLeadingSign(parts)\n\n return { sign, value: rest }\n})\n\nconst sign = computed(() => valueNodes.value.sign)\nconst formatted = computed(() => valueNodes.value.value)\n\nconst arrowIcon = computed(() => {\n if (direction.value === 'up')\n return IconTrendingUp\n if (direction.value === 'down')\n return IconTrendingDown\n return IconMinus\n})\n\n/**\n * Направление словом — когда знака в записи нет.\n *\n * `showSign: false` убирает плюс у роста, и направление остаётся на тоне, то\n * есть на цвете: WCAG 1.4.1. Падение этим не задето — минус `Intl` печатает\n * всегда, а у нуля направления нет вовсе.\n */\nconst spokenDirection = computed(() => (\n !isEmpty.value && !resolvedShowSign.value && direction.value === 'up'\n ? t('gr.delta.increase', 'increase')\n : ''\n))\n\nif (__GR_DEV__) {\n watchEffect(() => {\n // `null` — заявленное «величины нет», `undefined` — забытый проп. На экране\n // они неотличимы, и промах выглядит как честный прочерк.\n if (props.value === undefined) {\n console.warn(\n '[granularity] GrDelta: обязательный проп `value` не передан — нарисован прочерк. '\n + 'Отсутствие величины объявляется явным `null`.',\n )\n }\n })\n}\n\nconst rootClass = computed(() => [\n deltaRootClass,\n deltaSizeClass[resolvedSize.value],\n isEmpty.value ? deltaEmptyClass : deltaToneClass[tone.value],\n].filter(Boolean).join(' '))\n</script>\n\n<template>\n <span data-gr-delta :data-tone=\"isEmpty ? undefined : tone\" :class=\"rootClass\" :style=\"deltaValueStyle\">\n <component\n :is=\"arrowIcon\"\n v-if=\"resolvedShowArrow && !isEmpty\"\n data-gr-delta-arrow\n :class=\"deltaArrowClass\"\n aria-hidden=\"true\"\n />\n\n <!-- Запись величины рисует `GrValue`: приписки оформляются там же, где у\n остальных величин пакета, и настраиваются теми же токенами. Знак идёт\n в `#lead` — он обязан встать перед валютой, а не после неё. -->\n <GrValue\n :value=\"formatted\"\n :prefix=\"isEmpty ? undefined : prefix\"\n :suffix=\"isEmpty ? undefined : suffix\"\n >\n <template v-if=\"sign\" #lead>\n <span data-gr-delta-sign>{{ sign }}</span>\n </template>\n\n </GrValue>\n\n <span v-if=\"spokenDirection\" data-gr-delta-direction class=\"sr-only\">{{ spokenDirection }}</span>\n </span>\n</template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"GrDelta-BSv1KdMy.js","names":[],"sources":["../../../../src/internal/granularityFormat.ts","../../../../src/components/GrDelta/GrDelta.vue","../../../../src/components/GrDelta/GrDelta.vue"],"sourcesContent":["/**\n * Форматирование чисел и дат по локали.\n *\n * Своё, а не из `@feugene/fint-i18n`: тот объявлен **опциональной** peer-зависимостью,\n * и пакет обязан работать без него. Под капотом всё равно `Intl`, то есть\n * результат совпадает с `useI18nFormat()` библиотеки — расхождения между\n * приложением с i18n и без него не возникает.\n *\n * Инстансы `Intl` кэшируются: их построение примерно на порядок дороже самого\n * форматирования. Кэш ограничен — иначе сгенерированные на лету опции растили\n * бы его без предела, — и вытесняет по давности чтения.\n */\n\nconst CACHE_LIMIT = 64\n\nconst numberFormats = new Map<string, Intl.NumberFormat>()\nconst dateFormats = new Map<string, Intl.DateTimeFormat>()\n\nfunction cacheKey(locale: string, options?: object): string {\n return options ? `${locale}\u0000${JSON.stringify(options)}` : locale\n}\n\nfunction take<T>(cache: Map<string, T>, key: string, create: () => T): T {\n const cached = cache.get(key)\n if (cached) {\n // Перечитанная запись уезжает в конец очереди. `Map` держит порядок\n // вставки, и это единственный способ отличить горячую запись от давней.\n cache.delete(key)\n cache.set(key, cached)\n\n return cached\n }\n\n const created = create()\n\n // Вытесняется самая давняя запись, а не весь кэш разом: у таблицы с десятком\n // колонок в нескольких локалях рабочий набор перерастает предел, и сброс\n // целиком пересоздавал бы на каждой вставке в том числе и горячие форматтеры.\n if (cache.size >= CACHE_LIMIT) {\n const oldest = cache.keys().next()\n if (!oldest.done)\n cache.delete(oldest.value)\n }\n\n cache.set(key, created)\n\n return created\n}\n\n/**\n * Локаль приходит из настроек приложения, а `Intl` бросает на некорректном\n * теге. Форматирование не имеет права уронить рендер, поэтому неизвестный тег\n * сводим к `en`.\n */\nexport function formatNumber(\n locale: string,\n value: number | bigint,\n options?: Intl.NumberFormatOptions,\n): string {\n try {\n return take(numberFormats, cacheKey(locale, options), () => new Intl.NumberFormat(locale, options)).format(value)\n }\n catch {\n return take(numberFormats, cacheKey('en', options), () => new Intl.NumberFormat('en', options)).format(value)\n }\n}\n\n/**\n * Те же правила, что у `formatNumber`, но по частям: вызывающему нужно знать,\n * где в записи стоит знак, чтобы вынести его отдельным узлом.\n *\n * Инстанс тот же, что у `formatNumber`: `Intl.NumberFormat` умеет оба метода, а\n * второй кэш под теми же ключами разъехался бы с первым на первом вытеснении.\n */\nexport function formatNumberToParts(\n locale: string,\n value: number | bigint,\n options?: Intl.NumberFormatOptions,\n): Intl.NumberFormatPart[] {\n try {\n return take(numberFormats, cacheKey(locale, options), () => new Intl.NumberFormat(locale, options)).formatToParts(value)\n }\n catch {\n return take(numberFormats, cacheKey('en', options), () => new Intl.NumberFormat('en', options)).formatToParts(value)\n }\n}\n\n/**\n * Ведущий знак и остаток записи.\n *\n * Нужно там, где знаку полагается свой узел разметки: валюта обязана стоять\n * после знака (`+$0,03`, а не `$+0,03`). Резать готовую строку по первому\n * символу нельзя — в RTL-локалях знаку предшествует невидимая метка\n * направления (`he-IL` — U+200E, `ar-EG` — U+061C), которой и разворачивается\n * минус относительно цифр. Метка уходит вместе со знаком: она управляет им.\n *\n * `sign` пуст, когда знака нет вовсе (ноль, положительное при `signDisplay:\n * 'auto'`, `NaN`) либо когда перед ним стоит содержательная часть. Во втором\n * случае запись не делится совсем: вернуть половину по догадке хуже, чем\n * вернуть целое.\n */\nexport function splitLeadingSign(\n parts: readonly Intl.NumberFormatPart[],\n): { sign: string, rest: string } {\n const join = (from: readonly Intl.NumberFormatPart[]): string => from.map(part => part.value).join('')\n const at = parts.findIndex(part => part.type === 'minusSign' || part.type === 'plusSign')\n\n if (at === -1 || parts.slice(0, at).some(part => part.type !== 'literal'))\n return { sign: '', rest: join(parts) }\n\n return { sign: join(parts.slice(0, at + 1)), rest: join(parts.slice(at + 1)) }\n}\n\nexport function formatDate(\n locale: string,\n value: Date | number | string,\n options?: Intl.DateTimeFormatOptions,\n): string {\n const date = value instanceof Date ? value : new Date(value)\n\n // Невалидную дату возвращаем как есть: пустая или «Invalid Date» в интерфейсе\n // хуже, чем исходное значение, но лучше, чем исключение на рендере.\n if (Number.isNaN(date.getTime()))\n return String(value)\n\n try {\n return take(dateFormats, cacheKey(locale, options), () => new Intl.DateTimeFormat(locale, options)).format(date)\n }\n catch {\n return take(dateFormats, cacheKey('en', options), () => new Intl.DateTimeFormat('en', options)).format(date)\n }\n}\n","<script setup lang=\"ts\">\nimport { computed, watchEffect } from 'vue'\n\nimport { formatNumberToParts, splitLeadingSign } from '../../internal/granularityFormat'\nimport GrValue from '../GrValue'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport { useGrComponentProp, useGrComponentSize } from '../GrConfigProvider/context'\n\nimport IconMinus from '~icons/lucide/minus'\nimport IconTrendingDown from '~icons/lucide/trending-down'\nimport IconTrendingUp from '~icons/lucide/trending-up'\n\nimport { deltaDirection, deltaTone, type GrDeltaPolarity, type GrDeltaTone } from './deltaTone'\nimport {\n deltaArrowClass,\n deltaEmptyClass,\n deltaRootClass,\n deltaSizeClass,\n deltaValueStyle,\n deltaToneClass,\n} from './grDeltaStyles'\n\nimport type { GrComponentSize } from '../shared/sizes'\n\nexport type { GrDeltaPolarity, GrDeltaTone } from './deltaTone'\n\n/**\n * Величина со знаком и тоном **внутри строки текста**: «Дельта: +$0.004».\n *\n * Компонент презентационный: дельту не считает и периоды не сравнивает —\n * «к чему сравнивать» знает приложение. Блочная плитка показателя — `GrStatistic`.\n */\nexport interface GrDeltaProps {\n /** Величина. `null` — её нет; это не ноль. */\n value: number | null\n /** Знаков после запятой. Не задано — как отдаст локаль. */\n precision?: number\n /** Приписка перед числом: валюта, единица. */\n prefix?: string\n /** Приписка после числа: `%`, `мс`. */\n suffix?: string\n /**\n * Что считать хорошим. Для выручки рост — успех, для себестоимости и времени\n * отклика — наоборот; без этого компонент врал бы в половине случаев.\n */\n polarity?: GrDeltaPolarity\n /** Ставить `+` у положительных. Минус подставляет `Intl` сам. */\n showSign?: boolean\n /** Стрелка направления. Декоративна: направление уже в знаке. */\n showArrow?: boolean\n /** Чем печатать отсутствующую величину. */\n emptyText?: string\n /** Локаль форматирования. Не задана — локаль i18n-адаптера. */\n locale?: string\n size?: GrComponentSize\n}\n\nconst props = withDefaults(defineProps<GrDeltaProps>(), {\n // Дефолты живут в резолверах ниже: Vue подставил бы свой раньше, чем\n // компонент заглянет в `GrConfigProvider`.\n precision: undefined,\n prefix: undefined,\n suffix: undefined,\n polarity: undefined,\n showSign: undefined,\n showArrow: undefined,\n emptyText: undefined,\n locale: undefined,\n size: undefined,\n})\n\nconst { locale, t } = useGranularityTranslations()\n\nconst resolvedSize = useGrComponentSize(() => props.size, { component: 'GrDelta' })\nconst resolvedLocale = computed(() => props.locale ?? locale.value ?? 'en')\nconst resolvedPolarity = useGrComponentProp('GrDelta', 'polarity', () => props.polarity, 'positive-good')\nconst resolvedShowSign = useGrComponentProp('GrDelta', 'showSign', () => props.showSign, true)\nconst resolvedShowArrow = useGrComponentProp('GrDelta', 'showArrow', () => props.showArrow, false)\nconst resolvedEmptyText = useGrComponentProp('GrDelta', 'emptyText', () => props.emptyText, '—')\n\nconst isEmpty = computed(() => props.value === null || props.value === undefined)\n\nconst tone = computed<GrDeltaTone>(() => (\n isEmpty.value ? 'neutral' : deltaTone(props.value as number, resolvedPolarity.value)\n))\n\nconst direction = computed(() => (isEmpty.value ? 'flat' : deltaDirection(props.value as number)))\n\nconst formatOptions = computed<Intl.NumberFormatOptions>(() => ({\n signDisplay: resolvedShowSign.value ? 'exceptZero' : 'auto',\n ...(props.precision === undefined\n ? {}\n : { minimumFractionDigits: props.precision, maximumFractionDigits: props.precision }),\n}))\n\n/**\n * Знак и число по отдельности.\n *\n * Знак — префикс форматирования, а не склейка строки. `'+' + value` уже ломало\n * `GrStatistic`: строка `'+10'` разбирается как число, и разряды теряются.\n * Поэтому знак не дописывают, а **вынимают** из готовых частей `Intl`.\n *\n * Делится величина только вместе с `prefix`: валюта обязана стоять после знака\n * (`+$0,0280`, а не `$+0,0280`). Без приписки делить нечего — знак остаётся\n * внутри величины, и разметка не меняется ни на байт.\n */\nconst valueNodes = computed<{ sign: string, value: string }>(() => {\n if (isEmpty.value)\n return { sign: '', value: resolvedEmptyText.value }\n\n const parts = formatNumberToParts(resolvedLocale.value, props.value as number, formatOptions.value)\n\n if (!props.prefix)\n return { sign: '', value: parts.map(part => part.value).join('') }\n\n const { sign, rest } = splitLeadingSign(parts)\n\n return { sign, value: rest }\n})\n\nconst sign = computed(() => valueNodes.value.sign)\nconst formatted = computed(() => valueNodes.value.value)\n\nconst arrowIcon = computed(() => {\n if (direction.value === 'up')\n return IconTrendingUp\n if (direction.value === 'down')\n return IconTrendingDown\n return IconMinus\n})\n\n/**\n * Направление словом — когда знака в записи нет.\n *\n * `showSign: false` убирает плюс у роста, и направление остаётся на тоне, то\n * есть на цвете: WCAG 1.4.1. Падение этим не задето — минус `Intl` печатает\n * всегда, а у нуля направления нет вовсе.\n */\nconst spokenDirection = computed(() => (\n !isEmpty.value && !resolvedShowSign.value && direction.value === 'up'\n ? t('gr.delta.increase', 'increase')\n : ''\n))\n\nif (__GR_DEV__) {\n watchEffect(() => {\n // `null` — заявленное «величины нет», `undefined` — забытый проп. На экране\n // они неотличимы, и промах выглядит как честный прочерк.\n if (props.value === undefined) {\n console.warn(\n '[granularity] GrDelta: обязательный проп `value` не передан — нарисован прочерк. '\n + 'Отсутствие величины объявляется явным `null`.',\n )\n }\n })\n}\n\nconst rootClass = computed(() => [\n deltaRootClass,\n deltaSizeClass[resolvedSize.value],\n isEmpty.value ? deltaEmptyClass : deltaToneClass[tone.value],\n].filter(Boolean).join(' '))\n</script>\n\n<template>\n <span data-gr-delta :data-tone=\"isEmpty ? undefined : tone\" :class=\"rootClass\" :style=\"deltaValueStyle\">\n <component\n :is=\"arrowIcon\"\n v-if=\"resolvedShowArrow && !isEmpty\"\n data-gr-delta-arrow\n :class=\"deltaArrowClass\"\n aria-hidden=\"true\"\n />\n\n <!-- Запись величины рисует `GrValue`: приписки оформляются там же, где у\n остальных величин пакета, и настраиваются теми же токенами. Знак идёт\n в `#lead` — он обязан встать перед валютой, а не после неё. -->\n <GrValue\n :value=\"formatted\"\n :prefix=\"isEmpty ? undefined : prefix\"\n :suffix=\"isEmpty ? undefined : suffix\"\n >\n <template v-if=\"sign\" #lead>\n <span data-gr-delta-sign>{{ sign }}</span>\n </template>\n\n </GrValue>\n\n <span v-if=\"spokenDirection\" data-gr-delta-direction class=\"sr-only\">{{ spokenDirection }}</span>\n </span>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, watchEffect } from 'vue'\n\nimport { formatNumberToParts, splitLeadingSign } from '../../internal/granularityFormat'\nimport GrValue from '../GrValue'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport { useGrComponentProp, useGrComponentSize } from '../GrConfigProvider/context'\n\nimport IconMinus from '~icons/lucide/minus'\nimport IconTrendingDown from '~icons/lucide/trending-down'\nimport IconTrendingUp from '~icons/lucide/trending-up'\n\nimport { deltaDirection, deltaTone, type GrDeltaPolarity, type GrDeltaTone } from './deltaTone'\nimport {\n deltaArrowClass,\n deltaEmptyClass,\n deltaRootClass,\n deltaSizeClass,\n deltaValueStyle,\n deltaToneClass,\n} from './grDeltaStyles'\n\nimport type { GrComponentSize } from '../shared/sizes'\n\nexport type { GrDeltaPolarity, GrDeltaTone } from './deltaTone'\n\n/**\n * Величина со знаком и тоном **внутри строки текста**: «Дельта: +$0.004».\n *\n * Компонент презентационный: дельту не считает и периоды не сравнивает —\n * «к чему сравнивать» знает приложение. Блочная плитка показателя — `GrStatistic`.\n */\nexport interface GrDeltaProps {\n /** Величина. `null` — её нет; это не ноль. */\n value: number | null\n /** Знаков после запятой. Не задано — как отдаст локаль. */\n precision?: number\n /** Приписка перед числом: валюта, единица. */\n prefix?: string\n /** Приписка после числа: `%`, `мс`. */\n suffix?: string\n /**\n * Что считать хорошим. Для выручки рост — успех, для себестоимости и времени\n * отклика — наоборот; без этого компонент врал бы в половине случаев.\n */\n polarity?: GrDeltaPolarity\n /** Ставить `+` у положительных. Минус подставляет `Intl` сам. */\n showSign?: boolean\n /** Стрелка направления. Декоративна: направление уже в знаке. */\n showArrow?: boolean\n /** Чем печатать отсутствующую величину. */\n emptyText?: string\n /** Локаль форматирования. Не задана — локаль i18n-адаптера. */\n locale?: string\n size?: GrComponentSize\n}\n\nconst props = withDefaults(defineProps<GrDeltaProps>(), {\n // Дефолты живут в резолверах ниже: Vue подставил бы свой раньше, чем\n // компонент заглянет в `GrConfigProvider`.\n precision: undefined,\n prefix: undefined,\n suffix: undefined,\n polarity: undefined,\n showSign: undefined,\n showArrow: undefined,\n emptyText: undefined,\n locale: undefined,\n size: undefined,\n})\n\nconst { locale, t } = useGranularityTranslations()\n\nconst resolvedSize = useGrComponentSize(() => props.size, { component: 'GrDelta' })\nconst resolvedLocale = computed(() => props.locale ?? locale.value ?? 'en')\nconst resolvedPolarity = useGrComponentProp('GrDelta', 'polarity', () => props.polarity, 'positive-good')\nconst resolvedShowSign = useGrComponentProp('GrDelta', 'showSign', () => props.showSign, true)\nconst resolvedShowArrow = useGrComponentProp('GrDelta', 'showArrow', () => props.showArrow, false)\nconst resolvedEmptyText = useGrComponentProp('GrDelta', 'emptyText', () => props.emptyText, '—')\n\nconst isEmpty = computed(() => props.value === null || props.value === undefined)\n\nconst tone = computed<GrDeltaTone>(() => (\n isEmpty.value ? 'neutral' : deltaTone(props.value as number, resolvedPolarity.value)\n))\n\nconst direction = computed(() => (isEmpty.value ? 'flat' : deltaDirection(props.value as number)))\n\nconst formatOptions = computed<Intl.NumberFormatOptions>(() => ({\n signDisplay: resolvedShowSign.value ? 'exceptZero' : 'auto',\n ...(props.precision === undefined\n ? {}\n : { minimumFractionDigits: props.precision, maximumFractionDigits: props.precision }),\n}))\n\n/**\n * Знак и число по отдельности.\n *\n * Знак — префикс форматирования, а не склейка строки. `'+' + value` уже ломало\n * `GrStatistic`: строка `'+10'` разбирается как число, и разряды теряются.\n * Поэтому знак не дописывают, а **вынимают** из готовых частей `Intl`.\n *\n * Делится величина только вместе с `prefix`: валюта обязана стоять после знака\n * (`+$0,0280`, а не `$+0,0280`). Без приписки делить нечего — знак остаётся\n * внутри величины, и разметка не меняется ни на байт.\n */\nconst valueNodes = computed<{ sign: string, value: string }>(() => {\n if (isEmpty.value)\n return { sign: '', value: resolvedEmptyText.value }\n\n const parts = formatNumberToParts(resolvedLocale.value, props.value as number, formatOptions.value)\n\n if (!props.prefix)\n return { sign: '', value: parts.map(part => part.value).join('') }\n\n const { sign, rest } = splitLeadingSign(parts)\n\n return { sign, value: rest }\n})\n\nconst sign = computed(() => valueNodes.value.sign)\nconst formatted = computed(() => valueNodes.value.value)\n\nconst arrowIcon = computed(() => {\n if (direction.value === 'up')\n return IconTrendingUp\n if (direction.value === 'down')\n return IconTrendingDown\n return IconMinus\n})\n\n/**\n * Направление словом — когда знака в записи нет.\n *\n * `showSign: false` убирает плюс у роста, и направление остаётся на тоне, то\n * есть на цвете: WCAG 1.4.1. Падение этим не задето — минус `Intl` печатает\n * всегда, а у нуля направления нет вовсе.\n */\nconst spokenDirection = computed(() => (\n !isEmpty.value && !resolvedShowSign.value && direction.value === 'up'\n ? t('gr.delta.increase', 'increase')\n : ''\n))\n\nif (__GR_DEV__) {\n watchEffect(() => {\n // `null` — заявленное «величины нет», `undefined` — забытый проп. На экране\n // они неотличимы, и промах выглядит как честный прочерк.\n if (props.value === undefined) {\n console.warn(\n '[granularity] GrDelta: обязательный проп `value` не передан — нарисован прочерк. '\n + 'Отсутствие величины объявляется явным `null`.',\n )\n }\n })\n}\n\nconst rootClass = computed(() => [\n deltaRootClass,\n deltaSizeClass[resolvedSize.value],\n isEmpty.value ? deltaEmptyClass : deltaToneClass[tone.value],\n].filter(Boolean).join(' '))\n</script>\n\n<template>\n <span data-gr-delta :data-tone=\"isEmpty ? undefined : tone\" :class=\"rootClass\" :style=\"deltaValueStyle\">\n <component\n :is=\"arrowIcon\"\n v-if=\"resolvedShowArrow && !isEmpty\"\n data-gr-delta-arrow\n :class=\"deltaArrowClass\"\n aria-hidden=\"true\"\n />\n\n <!-- Запись величины рисует `GrValue`: приписки оформляются там же, где у\n остальных величин пакета, и настраиваются теми же токенами. Знак идёт\n в `#lead` — он обязан встать перед валютой, а не после неё. -->\n <GrValue\n :value=\"formatted\"\n :prefix=\"isEmpty ? undefined : prefix\"\n :suffix=\"isEmpty ? undefined : suffix\"\n >\n <template v-if=\"sign\" #lead>\n <span data-gr-delta-sign>{{ sign }}</span>\n </template>\n\n </GrValue>\n\n <span v-if=\"spokenDirection\" data-gr-delta-direction class=\"sr-only\">{{ spokenDirection }}</span>\n </span>\n</template>\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as GrDelta_default } from "./chunks/GrDelta-
|
|
1
|
+
import { t as GrDelta_default } from "./chunks/GrDelta-BSv1KdMy.js";
|
|
2
2
|
import { n as deltaTone, t as deltaDirection } from "../../chunks/deltaTone-B5OoS1vo.js";
|
|
3
|
-
import { n as grDeltaSafelist, t as grDeltaConfig } from "../../chunks/config-
|
|
3
|
+
import { n as grDeltaSafelist, t as grDeltaConfig } from "../../chunks/config-Bk52xd5l.js";
|
|
4
4
|
export { GrDelta_default as GrDelta, GrDelta_default as default, deltaDirection, deltaTone, grDeltaConfig, grDeltaSafelist };
|
|
@@ -2,7 +2,7 @@ import { t as x_default } from "../../../chunks/x-2KXnqxiD.js";
|
|
|
2
2
|
import { i as useGrComponentProp } from "../../../chunks/context-CPMRfwVr.js";
|
|
3
3
|
import { n as useGranularityTranslations } from "../../../chunks/granularityI18n-BC5zsj_d.js";
|
|
4
4
|
import { t as GrButton_default } from "../../GrButton/chunks/GrButton-CS4TqMtG.js";
|
|
5
|
-
import { n as useGrModalTitle, t as GrModal_default } from "../../GrModal/chunks/GrModal-
|
|
5
|
+
import { n as useGrModalTitle, t as GrModal_default } from "../../GrModal/chunks/GrModal-SHb1U2qx.js";
|
|
6
6
|
import { a as resolveGrDialogTitle, i as resolveGrDialogSectionConfig, n as DEFAULT_GR_DIALOG_FOOTER_CONFIG, r as DEFAULT_GR_DIALOG_HEADER_CONFIG, t as DEFAULT_GR_DIALOG_BODY_CONFIG } from "../../../chunks/dialogShared-CxW62PQE.js";
|
|
7
7
|
import { computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createSlots, createVNode, defineComponent, guardReactiveProps, mergeProps, normalizeClass, normalizeProps, openBlock, renderSlot, toDisplayString, unref, useAttrs, useSlots, withCtx } from "vue";
|
|
8
8
|
//#endregion
|
package/dist/components/GrDialog/chunks/{GrDialog-DDz_OEhk.js.map → GrDialog-C9Zu72jB.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GrDialog-DDz_OEhk.js","names":["$emit","$emit"],"sources":["../../../../src/components/GrDialog/GrDialogFooter.vue","../../../../src/components/GrDialog/GrDialogFooter.vue","../../../../src/components/GrDialog/GrDialogCloseButton.vue","../../../../src/components/GrDialog/GrDialogCloseButton.vue","../../../../src/components/GrDialog/GrDialogHeader.vue","../../../../src/components/GrDialog/GrDialogHeader.vue","../../../../src/components/GrDialog/GrDialog.vue","../../../../src/components/GrDialog/GrDialog.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport {\n DEFAULT_GR_DIALOG_FOOTER_CONFIG,\n resolveGrDialogSectionConfig,\n type GrDialogSectionConfig,\n} from './dialogShared'\n\nexport interface GrDialogFooterProps {\n config?: GrDialogSectionConfig\n}\n\nconst props = withDefaults(defineProps<GrDialogFooterProps>(), {\n config: undefined,\n})\n\nconst resolvedConfig = computed(() => resolveGrDialogSectionConfig(props.config, DEFAULT_GR_DIALOG_FOOTER_CONFIG))\n\nconst rootClass = computed(() => [\n resolvedConfig.value.paddingX,\n resolvedConfig.value.paddingY,\n resolvedConfig.value.bordered ? 'border-t border-[var(--gr-brd)]' : '',\n])\n\ndefineSlots<{\n /** Действия диалога. */\n default?: () => any\n}>()\n</script>\n\n<template>\n <div data-gr-dialog-footer :class=\"rootClass\">\n <slot />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport {\n DEFAULT_GR_DIALOG_FOOTER_CONFIG,\n resolveGrDialogSectionConfig,\n type GrDialogSectionConfig,\n} from './dialogShared'\n\nexport interface GrDialogFooterProps {\n config?: GrDialogSectionConfig\n}\n\nconst props = withDefaults(defineProps<GrDialogFooterProps>(), {\n config: undefined,\n})\n\nconst resolvedConfig = computed(() => resolveGrDialogSectionConfig(props.config, DEFAULT_GR_DIALOG_FOOTER_CONFIG))\n\nconst rootClass = computed(() => [\n resolvedConfig.value.paddingX,\n resolvedConfig.value.paddingY,\n resolvedConfig.value.bordered ? 'border-t border-[var(--gr-brd)]' : '',\n])\n\ndefineSlots<{\n /** Действия диалога. */\n default?: () => any\n}>()\n</script>\n\n<template>\n <div data-gr-dialog-footer :class=\"rootClass\">\n <slot />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue'\n\nimport GrButton from '../GrButton/GrButton.vue'\nimport IconClose from '~icons/lucide/x'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\n\nexport interface GrDialogCloseButtonEmits {\n (e: 'click'): void\n}\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst { t } = useGranularityTranslations()\n\n// A11y-лейбл: берём из атрибутов (родитель прокидывает `:aria-label=\"closeLabel\"`)\n// или используем i18n-дефолт. Не хардкодим английское \"Close\" — GR должен быть i18n-friendly.\nconst attrs = useAttrs()\nconst ariaLabel = computed(() => (attrs['aria-label'] as string | undefined) ?? t('gr.common.close', 'Close'))\n\ndefineEmits<GrDialogCloseButtonEmits>()\n</script>\n\n<template>\n <GrButton\n v-bind=\"attrs\"\n data-gr-dialog-close\n variant=\"ghost\"\n size=\"sm\"\n square\n :aria-label=\"ariaLabel\"\n @click=\"$emit('click')\"\n >\n <IconClose class=\"h-4 w-4\" aria-hidden=\"true\" />\n </GrButton>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue'\n\nimport GrButton from '../GrButton/GrButton.vue'\nimport IconClose from '~icons/lucide/x'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\n\nexport interface GrDialogCloseButtonEmits {\n (e: 'click'): void\n}\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst { t } = useGranularityTranslations()\n\n// A11y-лейбл: берём из атрибутов (родитель прокидывает `:aria-label=\"closeLabel\"`)\n// или используем i18n-дефолт. Не хардкодим английское \"Close\" — GR должен быть i18n-friendly.\nconst attrs = useAttrs()\nconst ariaLabel = computed(() => (attrs['aria-label'] as string | undefined) ?? t('gr.common.close', 'Close'))\n\ndefineEmits<GrDialogCloseButtonEmits>()\n</script>\n\n<template>\n <GrButton\n v-bind=\"attrs\"\n data-gr-dialog-close\n variant=\"ghost\"\n size=\"sm\"\n square\n :aria-label=\"ariaLabel\"\n @click=\"$emit('click')\"\n >\n <IconClose class=\"h-4 w-4\" aria-hidden=\"true\" />\n </GrButton>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport GrDialogCloseButton from './GrDialogCloseButton.vue'\nimport { useGrModalTitle } from '../GrModal/context'\nimport {\n DEFAULT_GR_DIALOG_HEADER_CONFIG,\n type GrDialogSectionConfig,\n resolveGrDialogSectionConfig,\n resolveGrDialogTitle,\n} from './dialogShared'\n\nexport interface GrDialogHeaderProps {\n title?: string\n showCloseButton?: boolean\n config?: GrDialogSectionConfig\n /** A11y-лейбл кнопки закрытия (i18n). */\n closeLabel?: string\n}\n\nexport interface GrDialogHeaderEmits {\n (e: 'close'): void\n}\n\nconst props = withDefaults(defineProps<GrDialogHeaderProps>(), {\n title: undefined,\n showCloseButton: true,\n config: undefined,\n closeLabel: undefined,\n})\n\nconst slots = defineSlots<{\n default?: (props: { title?: string }) => any\n}>()\n\ndefineEmits<GrDialogHeaderEmits>()\n\nconst resolvedTitle = computed(() => resolveGrDialogTitle(props.title))\n\nconst resolvedConfig = computed(() =>\n resolveGrDialogSectionConfig(props.config, DEFAULT_GR_DIALOG_HEADER_CONFIG),\n)\n\nconst rootClass = computed(() => [\n resolvedConfig.value.paddingX,\n resolvedConfig.value.paddingY,\n resolvedConfig.value.bordered ? 'border-b border-[var(--gr-brd)]' : '',\n 'flex items-center justify-between gap-4',\n])\n\n// Видимый заголовок рендерим только когда нет пользовательского слота:\n// если слот `#header` задан, a11y-title отдаётся через `GrModal #title`\n// на уровне `GrDialog` (см. JSDoc у `GrDialog.vue`).\nconst showVisibleTitle = computed(() => !slots.default && !!resolvedTitle.value)\n\n// Имя окна: заголовок объявляет себя окну, и `GrModal` ставит на него\n// `aria-labelledby`. Вне `GrModal` регистрация — no-op, шапку можно\n// использовать и отдельно.\nconst { titleId } = useGrModalTitle(() => showVisibleTitle.value)\n</script>\n\n<template>\n <div data-gr-dialog-header :class=\"rootClass\">\n <template v-if=\"slots.default\">\n <div class=\"flex-1 min-w-0 flex items-center\">\n <slot :title=\"resolvedTitle\" />\n </div>\n </template>\n <div\n v-else-if=\"showVisibleTitle\"\n :id=\"titleId\"\n data-gr-dialog-title\n class=\"flex-1 min-w-0 text-[length:var(--gr-control-text-md)] leading-[var(--gr-control-leading-md)] font-700\"\n >\n {{ resolvedTitle }}\n </div>\n <div v-else class=\"flex-1 min-w-0\" />\n <GrDialogCloseButton\n v-if=\"showCloseButton\"\n :aria-label=\"closeLabel\"\n @click=\"$emit('close')\"\n />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport GrDialogCloseButton from './GrDialogCloseButton.vue'\nimport { useGrModalTitle } from '../GrModal/context'\nimport {\n DEFAULT_GR_DIALOG_HEADER_CONFIG,\n type GrDialogSectionConfig,\n resolveGrDialogSectionConfig,\n resolveGrDialogTitle,\n} from './dialogShared'\n\nexport interface GrDialogHeaderProps {\n title?: string\n showCloseButton?: boolean\n config?: GrDialogSectionConfig\n /** A11y-лейбл кнопки закрытия (i18n). */\n closeLabel?: string\n}\n\nexport interface GrDialogHeaderEmits {\n (e: 'close'): void\n}\n\nconst props = withDefaults(defineProps<GrDialogHeaderProps>(), {\n title: undefined,\n showCloseButton: true,\n config: undefined,\n closeLabel: undefined,\n})\n\nconst slots = defineSlots<{\n default?: (props: { title?: string }) => any\n}>()\n\ndefineEmits<GrDialogHeaderEmits>()\n\nconst resolvedTitle = computed(() => resolveGrDialogTitle(props.title))\n\nconst resolvedConfig = computed(() =>\n resolveGrDialogSectionConfig(props.config, DEFAULT_GR_DIALOG_HEADER_CONFIG),\n)\n\nconst rootClass = computed(() => [\n resolvedConfig.value.paddingX,\n resolvedConfig.value.paddingY,\n resolvedConfig.value.bordered ? 'border-b border-[var(--gr-brd)]' : '',\n 'flex items-center justify-between gap-4',\n])\n\n// Видимый заголовок рендерим только когда нет пользовательского слота:\n// если слот `#header` задан, a11y-title отдаётся через `GrModal #title`\n// на уровне `GrDialog` (см. JSDoc у `GrDialog.vue`).\nconst showVisibleTitle = computed(() => !slots.default && !!resolvedTitle.value)\n\n// Имя окна: заголовок объявляет себя окну, и `GrModal` ставит на него\n// `aria-labelledby`. Вне `GrModal` регистрация — no-op, шапку можно\n// использовать и отдельно.\nconst { titleId } = useGrModalTitle(() => showVisibleTitle.value)\n</script>\n\n<template>\n <div data-gr-dialog-header :class=\"rootClass\">\n <template v-if=\"slots.default\">\n <div class=\"flex-1 min-w-0 flex items-center\">\n <slot :title=\"resolvedTitle\" />\n </div>\n </template>\n <div\n v-else-if=\"showVisibleTitle\"\n :id=\"titleId\"\n data-gr-dialog-title\n class=\"flex-1 min-w-0 text-[length:var(--gr-control-text-md)] leading-[var(--gr-control-leading-md)] font-700\"\n >\n {{ resolvedTitle }}\n </div>\n <div v-else class=\"flex-1 min-w-0\" />\n <GrDialogCloseButton\n v-if=\"showCloseButton\"\n :aria-label=\"closeLabel\"\n @click=\"$emit('close')\"\n />\n </div>\n</template>\n","<script setup lang=\"ts\">\n/**\n * GrDialog — GR-примитив диалога поверх `GrModal`.\n *\n * Архитектурно:\n * - ширина/радиус/скролл-лок/Esc/бэкдроп — ответственность `GrModal`;\n * - заголовок/подвал/кнопка закрытия/паддинги секций — ответственность `GrDialog`.\n *\n * A11y: ровно один `DialogTitle` на открытое окно.\n * - Если хедер отображается без слота `#header` — видимый `DialogTitle` рендерит\n * `GrDialogHeader`.\n * - В остальных случаях (`!showHeader`, либо `showHeader` со слотом `#header`)\n * `GrDialog` отдаёт sr-only title в слот `#title` у `GrModal`, чтобы\n * `GrModal` корректно проставил `aria-labelledby` на корень окна.\n * - `aria-label` вниз уходит всегда: `GrModal` иначе не отличил бы «заголовок\n * рисует `GrDialogHeader`» от «имени нет вовсе» и подставил бы обобщённое.\n */\nimport { useGrComponentProp } from '../GrConfigProvider/context'\nimport { computed } from 'vue'\n\nimport GrModal from '../GrModal/GrModal.vue'\nimport type { GrModalScrollBehavior } from '../GrModal/grModalStyles'\nimport GrDialogFooter from './GrDialogFooter.vue'\nimport GrDialogHeader from './GrDialogHeader.vue'\nimport {\n DEFAULT_GR_DIALOG_BODY_CONFIG,\n type GrDialogSectionConfig,\n type GrDialogSize,\n resolveGrDialogSectionConfig,\n resolveGrDialogTitle,\n} from './dialogShared'\n\nexport interface GrDialogProps {\n modelValue: boolean\n title?: string\n closeOnBackdrop?: boolean\n closeOnEsc?: boolean\n showHeader?: boolean\n showCloseButton?: boolean\n size?: GrDialogSize\n headerConfig?: GrDialogSectionConfig\n footerConfig?: GrDialogSectionConfig\n bodyConfig?: GrDialogSectionConfig\n /** A11y-лейбл кнопки закрытия (i18n). */\n closeLabel?: string\n /**\n * Доступное имя окна, когда заголовка нет вовсе: `showHeader: false` без\n * `title` и без слота `#header` оставил бы окно безымянным.\n */\n ariaLabel?: string\n /**\n * Кто скроллится при длинном содержимом. При `inside` шапка и подвал\n * закреплены, а едет только тело.\n */\n scrollBehavior?: GrModalScrollBehavior\n /**\n * Элемент, получающий фокус при открытии. По умолчанию — панель окна.\n * Элемент **из самого диалога** сюда передавать нельзя: проп, возвращающий\n * наверх то, что рождено внутри поддерева, замыкает рендер в цикл. Фокус на\n * своём содержимом ставится из содержимого — так это сделано в\n * `GrPromptDialog`.\n */\n initialFocus?: HTMLElement | null\n}\n\nexport interface GrDialogEmits {\n (e: 'update:modelValue', value: boolean): void\n /** Окно открылось и анимация закончилась. */\n (e: 'opened'): void\n /** Окно закрылось и анимация закончилась — содержимое можно размонтировать. */\n (e: 'closed'): void\n}\n\nimport './defaults'\n\nconst props = withDefaults(defineProps<GrDialogProps>(), {\n title: undefined,\n closeOnBackdrop: true,\n closeOnEsc: true,\n showHeader: true,\n showCloseButton: true,\n // Дефолт `size` живёт в резолвере ниже, а не здесь: Vue подставил бы его\n // до того, как компонент заглянет в `GrConfigProvider`.\n size: undefined,\n headerConfig: undefined,\n footerConfig: undefined,\n bodyConfig: undefined,\n closeLabel: undefined,\n ariaLabel: undefined,\n scrollBehavior: 'outside',\n initialFocus: null,\n})\n\nconst emit = defineEmits<GrDialogEmits>()\n\nconst slots = defineSlots<{\n default?: () => any\n header?: (props: { title?: string }) => any\n footer?: () => any\n}>()\n\n// Эффективный размер: локальный проп → `GrConfigProvider` → дефолт компонента.\n// Резолвим здесь, а не полагаемся на `GrModal`: иначе дефолт диалога затенил бы\n// конфиг раньше, чем примитив успел бы в него заглянуть.\nconst resolvedSize = useGrComponentProp('GrDialog', 'size', () => props.size, 'md')\n\nconst resolvedTitle = computed(() => resolveGrDialogTitle(props.title))\n\nconst bodyClass = computed(() => {\n const cfg = resolveGrDialogSectionConfig(props.bodyConfig, DEFAULT_GR_DIALOG_BODY_CONFIG)\n return [cfg.paddingX, cfg.paddingY]\n})\n\n// Нужен ли sr-only title через `GrModal #title`:\n// - `!showHeader` — вообще нет заголовка в разметке;\n// - `showHeader && $slots.header` — кастомный хедер не обязан содержать DialogTitle.\n// В обоих случаях даём окну a11y-title, не дублируя его визуально.\nconst useModalSrOnlyTitle = computed(\n () => !!resolvedTitle.value && (!props.showHeader || !!slots.header),\n)\n\nfunction open(): void {\n emit('update:modelValue', true)\n}\n\nfunction close(): void {\n emit('update:modelValue', false)\n}\n\nfunction toggle(): void {\n emit('update:modelValue', !props.modelValue)\n}\n\ndefineExpose({ open, close, toggle })\n</script>\n\n<template>\n <GrModal\n :model-value=\"modelValue\"\n :size=\"resolvedSize\"\n :scroll-behavior=\"scrollBehavior\"\n :initial-focus=\"initialFocus\"\n :close-on-backdrop=\"closeOnBackdrop\"\n :close-on-esc=\"closeOnEsc\"\n :aria-label=\"ariaLabel ?? resolvedTitle\"\n @update:model-value=\"emit('update:modelValue', $event)\"\n @opened=\"emit('opened')\"\n @closed=\"emit('closed')\"\n >\n <template v-if=\"useModalSrOnlyTitle\" #title>\n <span class=\"sr-only\">{{ resolvedTitle }}</span>\n </template>\n\n <!-- Шапка и подвал уходят в layout-слоты `GrModal`: при `inside` они\n остаются вне скроллящегося тела. -->\n <template v-if=\"showHeader\" #header>\n <GrDialogHeader\n :title=\"resolvedTitle\"\n :show-close-button=\"showCloseButton\"\n :config=\"headerConfig\"\n :close-label=\"closeLabel\"\n @close=\"close\"\n >\n <template v-if=\"slots.header\" #default=\"slotProps\">\n <slot name=\"header\" v-bind=\"slotProps\" />\n </template>\n </GrDialogHeader>\n </template>\n\n <div :class=\"bodyClass\">\n <slot />\n </div>\n\n <template v-if=\"slots.footer\" #footer>\n <GrDialogFooter :config=\"footerConfig\">\n <slot name=\"footer\" />\n </GrDialogFooter>\n </template>\n </GrModal>\n</template>\n","<script setup lang=\"ts\">\n/**\n * GrDialog — GR-примитив диалога поверх `GrModal`.\n *\n * Архитектурно:\n * - ширина/радиус/скролл-лок/Esc/бэкдроп — ответственность `GrModal`;\n * - заголовок/подвал/кнопка закрытия/паддинги секций — ответственность `GrDialog`.\n *\n * A11y: ровно один `DialogTitle` на открытое окно.\n * - Если хедер отображается без слота `#header` — видимый `DialogTitle` рендерит\n * `GrDialogHeader`.\n * - В остальных случаях (`!showHeader`, либо `showHeader` со слотом `#header`)\n * `GrDialog` отдаёт sr-only title в слот `#title` у `GrModal`, чтобы\n * `GrModal` корректно проставил `aria-labelledby` на корень окна.\n * - `aria-label` вниз уходит всегда: `GrModal` иначе не отличил бы «заголовок\n * рисует `GrDialogHeader`» от «имени нет вовсе» и подставил бы обобщённое.\n */\nimport { useGrComponentProp } from '../GrConfigProvider/context'\nimport { computed } from 'vue'\n\nimport GrModal from '../GrModal/GrModal.vue'\nimport type { GrModalScrollBehavior } from '../GrModal/grModalStyles'\nimport GrDialogFooter from './GrDialogFooter.vue'\nimport GrDialogHeader from './GrDialogHeader.vue'\nimport {\n DEFAULT_GR_DIALOG_BODY_CONFIG,\n type GrDialogSectionConfig,\n type GrDialogSize,\n resolveGrDialogSectionConfig,\n resolveGrDialogTitle,\n} from './dialogShared'\n\nexport interface GrDialogProps {\n modelValue: boolean\n title?: string\n closeOnBackdrop?: boolean\n closeOnEsc?: boolean\n showHeader?: boolean\n showCloseButton?: boolean\n size?: GrDialogSize\n headerConfig?: GrDialogSectionConfig\n footerConfig?: GrDialogSectionConfig\n bodyConfig?: GrDialogSectionConfig\n /** A11y-лейбл кнопки закрытия (i18n). */\n closeLabel?: string\n /**\n * Доступное имя окна, когда заголовка нет вовсе: `showHeader: false` без\n * `title` и без слота `#header` оставил бы окно безымянным.\n */\n ariaLabel?: string\n /**\n * Кто скроллится при длинном содержимом. При `inside` шапка и подвал\n * закреплены, а едет только тело.\n */\n scrollBehavior?: GrModalScrollBehavior\n /**\n * Элемент, получающий фокус при открытии. По умолчанию — панель окна.\n * Элемент **из самого диалога** сюда передавать нельзя: проп, возвращающий\n * наверх то, что рождено внутри поддерева, замыкает рендер в цикл. Фокус на\n * своём содержимом ставится из содержимого — так это сделано в\n * `GrPromptDialog`.\n */\n initialFocus?: HTMLElement | null\n}\n\nexport interface GrDialogEmits {\n (e: 'update:modelValue', value: boolean): void\n /** Окно открылось и анимация закончилась. */\n (e: 'opened'): void\n /** Окно закрылось и анимация закончилась — содержимое можно размонтировать. */\n (e: 'closed'): void\n}\n\nimport './defaults'\n\nconst props = withDefaults(defineProps<GrDialogProps>(), {\n title: undefined,\n closeOnBackdrop: true,\n closeOnEsc: true,\n showHeader: true,\n showCloseButton: true,\n // Дефолт `size` живёт в резолвере ниже, а не здесь: Vue подставил бы его\n // до того, как компонент заглянет в `GrConfigProvider`.\n size: undefined,\n headerConfig: undefined,\n footerConfig: undefined,\n bodyConfig: undefined,\n closeLabel: undefined,\n ariaLabel: undefined,\n scrollBehavior: 'outside',\n initialFocus: null,\n})\n\nconst emit = defineEmits<GrDialogEmits>()\n\nconst slots = defineSlots<{\n default?: () => any\n header?: (props: { title?: string }) => any\n footer?: () => any\n}>()\n\n// Эффективный размер: локальный проп → `GrConfigProvider` → дефолт компонента.\n// Резолвим здесь, а не полагаемся на `GrModal`: иначе дефолт диалога затенил бы\n// конфиг раньше, чем примитив успел бы в него заглянуть.\nconst resolvedSize = useGrComponentProp('GrDialog', 'size', () => props.size, 'md')\n\nconst resolvedTitle = computed(() => resolveGrDialogTitle(props.title))\n\nconst bodyClass = computed(() => {\n const cfg = resolveGrDialogSectionConfig(props.bodyConfig, DEFAULT_GR_DIALOG_BODY_CONFIG)\n return [cfg.paddingX, cfg.paddingY]\n})\n\n// Нужен ли sr-only title через `GrModal #title`:\n// - `!showHeader` — вообще нет заголовка в разметке;\n// - `showHeader && $slots.header` — кастомный хедер не обязан содержать DialogTitle.\n// В обоих случаях даём окну a11y-title, не дублируя его визуально.\nconst useModalSrOnlyTitle = computed(\n () => !!resolvedTitle.value && (!props.showHeader || !!slots.header),\n)\n\nfunction open(): void {\n emit('update:modelValue', true)\n}\n\nfunction close(): void {\n emit('update:modelValue', false)\n}\n\nfunction toggle(): void {\n emit('update:modelValue', !props.modelValue)\n}\n\ndefineExpose({ open, close, toggle })\n</script>\n\n<template>\n <GrModal\n :model-value=\"modelValue\"\n :size=\"resolvedSize\"\n :scroll-behavior=\"scrollBehavior\"\n :initial-focus=\"initialFocus\"\n :close-on-backdrop=\"closeOnBackdrop\"\n :close-on-esc=\"closeOnEsc\"\n :aria-label=\"ariaLabel ?? resolvedTitle\"\n @update:model-value=\"emit('update:modelValue', $event)\"\n @opened=\"emit('opened')\"\n @closed=\"emit('closed')\"\n >\n <template v-if=\"useModalSrOnlyTitle\" #title>\n <span class=\"sr-only\">{{ resolvedTitle }}</span>\n </template>\n\n <!-- Шапка и подвал уходят в layout-слоты `GrModal`: при `inside` они\n остаются вне скроллящегося тела. -->\n <template v-if=\"showHeader\" #header>\n <GrDialogHeader\n :title=\"resolvedTitle\"\n :show-close-button=\"showCloseButton\"\n :config=\"headerConfig\"\n :close-label=\"closeLabel\"\n @close=\"close\"\n >\n <template v-if=\"slots.header\" #default=\"slotProps\">\n <slot name=\"header\" v-bind=\"slotProps\" />\n </template>\n </GrDialogHeader>\n </template>\n\n <div :class=\"bodyClass\">\n <slot />\n </div>\n\n <template v-if=\"slots.footer\" #footer>\n <GrDialogFooter :config=\"footerConfig\">\n <slot name=\"footer\" />\n </GrDialogFooter>\n </template>\n </GrModal>\n</template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"GrDialog-C9Zu72jB.js","names":["$emit","$emit"],"sources":["../../../../src/components/GrDialog/GrDialogFooter.vue","../../../../src/components/GrDialog/GrDialogFooter.vue","../../../../src/components/GrDialog/GrDialogCloseButton.vue","../../../../src/components/GrDialog/GrDialogCloseButton.vue","../../../../src/components/GrDialog/GrDialogHeader.vue","../../../../src/components/GrDialog/GrDialogHeader.vue","../../../../src/components/GrDialog/GrDialog.vue","../../../../src/components/GrDialog/GrDialog.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport {\n DEFAULT_GR_DIALOG_FOOTER_CONFIG,\n resolveGrDialogSectionConfig,\n type GrDialogSectionConfig,\n} from './dialogShared'\n\nexport interface GrDialogFooterProps {\n config?: GrDialogSectionConfig\n}\n\nconst props = withDefaults(defineProps<GrDialogFooterProps>(), {\n config: undefined,\n})\n\nconst resolvedConfig = computed(() => resolveGrDialogSectionConfig(props.config, DEFAULT_GR_DIALOG_FOOTER_CONFIG))\n\nconst rootClass = computed(() => [\n resolvedConfig.value.paddingX,\n resolvedConfig.value.paddingY,\n resolvedConfig.value.bordered ? 'border-t border-[var(--gr-brd)]' : '',\n])\n\ndefineSlots<{\n /** Действия диалога. */\n default?: () => any\n}>()\n</script>\n\n<template>\n <div data-gr-dialog-footer :class=\"rootClass\">\n <slot />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport {\n DEFAULT_GR_DIALOG_FOOTER_CONFIG,\n resolveGrDialogSectionConfig,\n type GrDialogSectionConfig,\n} from './dialogShared'\n\nexport interface GrDialogFooterProps {\n config?: GrDialogSectionConfig\n}\n\nconst props = withDefaults(defineProps<GrDialogFooterProps>(), {\n config: undefined,\n})\n\nconst resolvedConfig = computed(() => resolveGrDialogSectionConfig(props.config, DEFAULT_GR_DIALOG_FOOTER_CONFIG))\n\nconst rootClass = computed(() => [\n resolvedConfig.value.paddingX,\n resolvedConfig.value.paddingY,\n resolvedConfig.value.bordered ? 'border-t border-[var(--gr-brd)]' : '',\n])\n\ndefineSlots<{\n /** Действия диалога. */\n default?: () => any\n}>()\n</script>\n\n<template>\n <div data-gr-dialog-footer :class=\"rootClass\">\n <slot />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue'\n\nimport GrButton from '../GrButton/GrButton.vue'\nimport IconClose from '~icons/lucide/x'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\n\nexport interface GrDialogCloseButtonEmits {\n (e: 'click'): void\n}\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst { t } = useGranularityTranslations()\n\n// A11y-лейбл: берём из атрибутов (родитель прокидывает `:aria-label=\"closeLabel\"`)\n// или используем i18n-дефолт. Не хардкодим английское \"Close\" — GR должен быть i18n-friendly.\nconst attrs = useAttrs()\nconst ariaLabel = computed(() => (attrs['aria-label'] as string | undefined) ?? t('gr.common.close', 'Close'))\n\ndefineEmits<GrDialogCloseButtonEmits>()\n</script>\n\n<template>\n <GrButton\n v-bind=\"attrs\"\n data-gr-dialog-close\n variant=\"ghost\"\n size=\"sm\"\n square\n :aria-label=\"ariaLabel\"\n @click=\"$emit('click')\"\n >\n <IconClose class=\"h-4 w-4\" aria-hidden=\"true\" />\n </GrButton>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue'\n\nimport GrButton from '../GrButton/GrButton.vue'\nimport IconClose from '~icons/lucide/x'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\n\nexport interface GrDialogCloseButtonEmits {\n (e: 'click'): void\n}\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst { t } = useGranularityTranslations()\n\n// A11y-лейбл: берём из атрибутов (родитель прокидывает `:aria-label=\"closeLabel\"`)\n// или используем i18n-дефолт. Не хардкодим английское \"Close\" — GR должен быть i18n-friendly.\nconst attrs = useAttrs()\nconst ariaLabel = computed(() => (attrs['aria-label'] as string | undefined) ?? t('gr.common.close', 'Close'))\n\ndefineEmits<GrDialogCloseButtonEmits>()\n</script>\n\n<template>\n <GrButton\n v-bind=\"attrs\"\n data-gr-dialog-close\n variant=\"ghost\"\n size=\"sm\"\n square\n :aria-label=\"ariaLabel\"\n @click=\"$emit('click')\"\n >\n <IconClose class=\"h-4 w-4\" aria-hidden=\"true\" />\n </GrButton>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport GrDialogCloseButton from './GrDialogCloseButton.vue'\nimport { useGrModalTitle } from '../GrModal/context'\nimport {\n DEFAULT_GR_DIALOG_HEADER_CONFIG,\n type GrDialogSectionConfig,\n resolveGrDialogSectionConfig,\n resolveGrDialogTitle,\n} from './dialogShared'\n\nexport interface GrDialogHeaderProps {\n title?: string\n showCloseButton?: boolean\n config?: GrDialogSectionConfig\n /** A11y-лейбл кнопки закрытия (i18n). */\n closeLabel?: string\n}\n\nexport interface GrDialogHeaderEmits {\n (e: 'close'): void\n}\n\nconst props = withDefaults(defineProps<GrDialogHeaderProps>(), {\n title: undefined,\n showCloseButton: true,\n config: undefined,\n closeLabel: undefined,\n})\n\nconst slots = defineSlots<{\n default?: (props: { title?: string }) => any\n}>()\n\ndefineEmits<GrDialogHeaderEmits>()\n\nconst resolvedTitle = computed(() => resolveGrDialogTitle(props.title))\n\nconst resolvedConfig = computed(() =>\n resolveGrDialogSectionConfig(props.config, DEFAULT_GR_DIALOG_HEADER_CONFIG),\n)\n\nconst rootClass = computed(() => [\n resolvedConfig.value.paddingX,\n resolvedConfig.value.paddingY,\n resolvedConfig.value.bordered ? 'border-b border-[var(--gr-brd)]' : '',\n 'flex items-center justify-between gap-4',\n])\n\n// Видимый заголовок рендерим только когда нет пользовательского слота:\n// если слот `#header` задан, a11y-title отдаётся через `GrModal #title`\n// на уровне `GrDialog` (см. JSDoc у `GrDialog.vue`).\nconst showVisibleTitle = computed(() => !slots.default && !!resolvedTitle.value)\n\n// Имя окна: заголовок объявляет себя окну, и `GrModal` ставит на него\n// `aria-labelledby`. Вне `GrModal` регистрация — no-op, шапку можно\n// использовать и отдельно.\nconst { titleId } = useGrModalTitle(() => showVisibleTitle.value)\n</script>\n\n<template>\n <div data-gr-dialog-header :class=\"rootClass\">\n <template v-if=\"slots.default\">\n <div class=\"flex-1 min-w-0 flex items-center\">\n <slot :title=\"resolvedTitle\" />\n </div>\n </template>\n <div\n v-else-if=\"showVisibleTitle\"\n :id=\"titleId\"\n data-gr-dialog-title\n class=\"flex-1 min-w-0 text-[length:var(--gr-control-text-md)] leading-[var(--gr-control-leading-md)] font-700\"\n >\n {{ resolvedTitle }}\n </div>\n <div v-else class=\"flex-1 min-w-0\" />\n <GrDialogCloseButton\n v-if=\"showCloseButton\"\n :aria-label=\"closeLabel\"\n @click=\"$emit('close')\"\n />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport GrDialogCloseButton from './GrDialogCloseButton.vue'\nimport { useGrModalTitle } from '../GrModal/context'\nimport {\n DEFAULT_GR_DIALOG_HEADER_CONFIG,\n type GrDialogSectionConfig,\n resolveGrDialogSectionConfig,\n resolveGrDialogTitle,\n} from './dialogShared'\n\nexport interface GrDialogHeaderProps {\n title?: string\n showCloseButton?: boolean\n config?: GrDialogSectionConfig\n /** A11y-лейбл кнопки закрытия (i18n). */\n closeLabel?: string\n}\n\nexport interface GrDialogHeaderEmits {\n (e: 'close'): void\n}\n\nconst props = withDefaults(defineProps<GrDialogHeaderProps>(), {\n title: undefined,\n showCloseButton: true,\n config: undefined,\n closeLabel: undefined,\n})\n\nconst slots = defineSlots<{\n default?: (props: { title?: string }) => any\n}>()\n\ndefineEmits<GrDialogHeaderEmits>()\n\nconst resolvedTitle = computed(() => resolveGrDialogTitle(props.title))\n\nconst resolvedConfig = computed(() =>\n resolveGrDialogSectionConfig(props.config, DEFAULT_GR_DIALOG_HEADER_CONFIG),\n)\n\nconst rootClass = computed(() => [\n resolvedConfig.value.paddingX,\n resolvedConfig.value.paddingY,\n resolvedConfig.value.bordered ? 'border-b border-[var(--gr-brd)]' : '',\n 'flex items-center justify-between gap-4',\n])\n\n// Видимый заголовок рендерим только когда нет пользовательского слота:\n// если слот `#header` задан, a11y-title отдаётся через `GrModal #title`\n// на уровне `GrDialog` (см. JSDoc у `GrDialog.vue`).\nconst showVisibleTitle = computed(() => !slots.default && !!resolvedTitle.value)\n\n// Имя окна: заголовок объявляет себя окну, и `GrModal` ставит на него\n// `aria-labelledby`. Вне `GrModal` регистрация — no-op, шапку можно\n// использовать и отдельно.\nconst { titleId } = useGrModalTitle(() => showVisibleTitle.value)\n</script>\n\n<template>\n <div data-gr-dialog-header :class=\"rootClass\">\n <template v-if=\"slots.default\">\n <div class=\"flex-1 min-w-0 flex items-center\">\n <slot :title=\"resolvedTitle\" />\n </div>\n </template>\n <div\n v-else-if=\"showVisibleTitle\"\n :id=\"titleId\"\n data-gr-dialog-title\n class=\"flex-1 min-w-0 text-[length:var(--gr-control-text-md)] leading-[var(--gr-control-leading-md)] font-700\"\n >\n {{ resolvedTitle }}\n </div>\n <div v-else class=\"flex-1 min-w-0\" />\n <GrDialogCloseButton\n v-if=\"showCloseButton\"\n :aria-label=\"closeLabel\"\n @click=\"$emit('close')\"\n />\n </div>\n</template>\n","<script setup lang=\"ts\">\n/**\n * GrDialog — GR-примитив диалога поверх `GrModal`.\n *\n * Архитектурно:\n * - ширина/радиус/скролл-лок/Esc/бэкдроп — ответственность `GrModal`;\n * - заголовок/подвал/кнопка закрытия/паддинги секций — ответственность `GrDialog`.\n *\n * A11y: ровно один `DialogTitle` на открытое окно.\n * - Если хедер отображается без слота `#header` — видимый `DialogTitle` рендерит\n * `GrDialogHeader`.\n * - В остальных случаях (`!showHeader`, либо `showHeader` со слотом `#header`)\n * `GrDialog` отдаёт sr-only title в слот `#title` у `GrModal`, чтобы\n * `GrModal` корректно проставил `aria-labelledby` на корень окна.\n * - `aria-label` вниз уходит всегда: `GrModal` иначе не отличил бы «заголовок\n * рисует `GrDialogHeader`» от «имени нет вовсе» и подставил бы обобщённое.\n */\nimport { useGrComponentProp } from '../GrConfigProvider/context'\nimport { computed } from 'vue'\n\nimport GrModal from '../GrModal/GrModal.vue'\nimport type { GrModalScrollBehavior } from '../GrModal/grModalStyles'\nimport GrDialogFooter from './GrDialogFooter.vue'\nimport GrDialogHeader from './GrDialogHeader.vue'\nimport {\n DEFAULT_GR_DIALOG_BODY_CONFIG,\n type GrDialogSectionConfig,\n type GrDialogSize,\n resolveGrDialogSectionConfig,\n resolveGrDialogTitle,\n} from './dialogShared'\n\nexport interface GrDialogProps {\n modelValue: boolean\n title?: string\n closeOnBackdrop?: boolean\n closeOnEsc?: boolean\n showHeader?: boolean\n showCloseButton?: boolean\n size?: GrDialogSize\n headerConfig?: GrDialogSectionConfig\n footerConfig?: GrDialogSectionConfig\n bodyConfig?: GrDialogSectionConfig\n /** A11y-лейбл кнопки закрытия (i18n). */\n closeLabel?: string\n /**\n * Доступное имя окна, когда заголовка нет вовсе: `showHeader: false` без\n * `title` и без слота `#header` оставил бы окно безымянным.\n */\n ariaLabel?: string\n /**\n * Кто скроллится при длинном содержимом. При `inside` шапка и подвал\n * закреплены, а едет только тело.\n */\n scrollBehavior?: GrModalScrollBehavior\n /**\n * Элемент, получающий фокус при открытии. По умолчанию — панель окна.\n * Элемент **из самого диалога** сюда передавать нельзя: проп, возвращающий\n * наверх то, что рождено внутри поддерева, замыкает рендер в цикл. Фокус на\n * своём содержимом ставится из содержимого — так это сделано в\n * `GrPromptDialog`.\n */\n initialFocus?: HTMLElement | null\n}\n\nexport interface GrDialogEmits {\n (e: 'update:modelValue', value: boolean): void\n /** Окно открылось и анимация закончилась. */\n (e: 'opened'): void\n /** Окно закрылось и анимация закончилась — содержимое можно размонтировать. */\n (e: 'closed'): void\n}\n\nimport './defaults'\n\nconst props = withDefaults(defineProps<GrDialogProps>(), {\n title: undefined,\n closeOnBackdrop: true,\n closeOnEsc: true,\n showHeader: true,\n showCloseButton: true,\n // Дефолт `size` живёт в резолвере ниже, а не здесь: Vue подставил бы его\n // до того, как компонент заглянет в `GrConfigProvider`.\n size: undefined,\n headerConfig: undefined,\n footerConfig: undefined,\n bodyConfig: undefined,\n closeLabel: undefined,\n ariaLabel: undefined,\n scrollBehavior: 'outside',\n initialFocus: null,\n})\n\nconst emit = defineEmits<GrDialogEmits>()\n\nconst slots = defineSlots<{\n default?: () => any\n header?: (props: { title?: string }) => any\n footer?: () => any\n}>()\n\n// Эффективный размер: локальный проп → `GrConfigProvider` → дефолт компонента.\n// Резолвим здесь, а не полагаемся на `GrModal`: иначе дефолт диалога затенил бы\n// конфиг раньше, чем примитив успел бы в него заглянуть.\nconst resolvedSize = useGrComponentProp('GrDialog', 'size', () => props.size, 'md')\n\nconst resolvedTitle = computed(() => resolveGrDialogTitle(props.title))\n\nconst bodyClass = computed(() => {\n const cfg = resolveGrDialogSectionConfig(props.bodyConfig, DEFAULT_GR_DIALOG_BODY_CONFIG)\n return [cfg.paddingX, cfg.paddingY]\n})\n\n// Нужен ли sr-only title через `GrModal #title`:\n// - `!showHeader` — вообще нет заголовка в разметке;\n// - `showHeader && $slots.header` — кастомный хедер не обязан содержать DialogTitle.\n// В обоих случаях даём окну a11y-title, не дублируя его визуально.\nconst useModalSrOnlyTitle = computed(\n () => !!resolvedTitle.value && (!props.showHeader || !!slots.header),\n)\n\nfunction open(): void {\n emit('update:modelValue', true)\n}\n\nfunction close(): void {\n emit('update:modelValue', false)\n}\n\nfunction toggle(): void {\n emit('update:modelValue', !props.modelValue)\n}\n\ndefineExpose({ open, close, toggle })\n</script>\n\n<template>\n <GrModal\n :model-value=\"modelValue\"\n :size=\"resolvedSize\"\n :scroll-behavior=\"scrollBehavior\"\n :initial-focus=\"initialFocus\"\n :close-on-backdrop=\"closeOnBackdrop\"\n :close-on-esc=\"closeOnEsc\"\n :aria-label=\"ariaLabel ?? resolvedTitle\"\n @update:model-value=\"emit('update:modelValue', $event)\"\n @opened=\"emit('opened')\"\n @closed=\"emit('closed')\"\n >\n <template v-if=\"useModalSrOnlyTitle\" #title>\n <span class=\"sr-only\">{{ resolvedTitle }}</span>\n </template>\n\n <!-- Шапка и подвал уходят в layout-слоты `GrModal`: при `inside` они\n остаются вне скроллящегося тела. -->\n <template v-if=\"showHeader\" #header>\n <GrDialogHeader\n :title=\"resolvedTitle\"\n :show-close-button=\"showCloseButton\"\n :config=\"headerConfig\"\n :close-label=\"closeLabel\"\n @close=\"close\"\n >\n <template v-if=\"slots.header\" #default=\"slotProps\">\n <slot name=\"header\" v-bind=\"slotProps\" />\n </template>\n </GrDialogHeader>\n </template>\n\n <div :class=\"bodyClass\">\n <slot />\n </div>\n\n <template v-if=\"slots.footer\" #footer>\n <GrDialogFooter :config=\"footerConfig\">\n <slot name=\"footer\" />\n </GrDialogFooter>\n </template>\n </GrModal>\n</template>\n","<script setup lang=\"ts\">\n/**\n * GrDialog — GR-примитив диалога поверх `GrModal`.\n *\n * Архитектурно:\n * - ширина/радиус/скролл-лок/Esc/бэкдроп — ответственность `GrModal`;\n * - заголовок/подвал/кнопка закрытия/паддинги секций — ответственность `GrDialog`.\n *\n * A11y: ровно один `DialogTitle` на открытое окно.\n * - Если хедер отображается без слота `#header` — видимый `DialogTitle` рендерит\n * `GrDialogHeader`.\n * - В остальных случаях (`!showHeader`, либо `showHeader` со слотом `#header`)\n * `GrDialog` отдаёт sr-only title в слот `#title` у `GrModal`, чтобы\n * `GrModal` корректно проставил `aria-labelledby` на корень окна.\n * - `aria-label` вниз уходит всегда: `GrModal` иначе не отличил бы «заголовок\n * рисует `GrDialogHeader`» от «имени нет вовсе» и подставил бы обобщённое.\n */\nimport { useGrComponentProp } from '../GrConfigProvider/context'\nimport { computed } from 'vue'\n\nimport GrModal from '../GrModal/GrModal.vue'\nimport type { GrModalScrollBehavior } from '../GrModal/grModalStyles'\nimport GrDialogFooter from './GrDialogFooter.vue'\nimport GrDialogHeader from './GrDialogHeader.vue'\nimport {\n DEFAULT_GR_DIALOG_BODY_CONFIG,\n type GrDialogSectionConfig,\n type GrDialogSize,\n resolveGrDialogSectionConfig,\n resolveGrDialogTitle,\n} from './dialogShared'\n\nexport interface GrDialogProps {\n modelValue: boolean\n title?: string\n closeOnBackdrop?: boolean\n closeOnEsc?: boolean\n showHeader?: boolean\n showCloseButton?: boolean\n size?: GrDialogSize\n headerConfig?: GrDialogSectionConfig\n footerConfig?: GrDialogSectionConfig\n bodyConfig?: GrDialogSectionConfig\n /** A11y-лейбл кнопки закрытия (i18n). */\n closeLabel?: string\n /**\n * Доступное имя окна, когда заголовка нет вовсе: `showHeader: false` без\n * `title` и без слота `#header` оставил бы окно безымянным.\n */\n ariaLabel?: string\n /**\n * Кто скроллится при длинном содержимом. При `inside` шапка и подвал\n * закреплены, а едет только тело.\n */\n scrollBehavior?: GrModalScrollBehavior\n /**\n * Элемент, получающий фокус при открытии. По умолчанию — панель окна.\n * Элемент **из самого диалога** сюда передавать нельзя: проп, возвращающий\n * наверх то, что рождено внутри поддерева, замыкает рендер в цикл. Фокус на\n * своём содержимом ставится из содержимого — так это сделано в\n * `GrPromptDialog`.\n */\n initialFocus?: HTMLElement | null\n}\n\nexport interface GrDialogEmits {\n (e: 'update:modelValue', value: boolean): void\n /** Окно открылось и анимация закончилась. */\n (e: 'opened'): void\n /** Окно закрылось и анимация закончилась — содержимое можно размонтировать. */\n (e: 'closed'): void\n}\n\nimport './defaults'\n\nconst props = withDefaults(defineProps<GrDialogProps>(), {\n title: undefined,\n closeOnBackdrop: true,\n closeOnEsc: true,\n showHeader: true,\n showCloseButton: true,\n // Дефолт `size` живёт в резолвере ниже, а не здесь: Vue подставил бы его\n // до того, как компонент заглянет в `GrConfigProvider`.\n size: undefined,\n headerConfig: undefined,\n footerConfig: undefined,\n bodyConfig: undefined,\n closeLabel: undefined,\n ariaLabel: undefined,\n scrollBehavior: 'outside',\n initialFocus: null,\n})\n\nconst emit = defineEmits<GrDialogEmits>()\n\nconst slots = defineSlots<{\n default?: () => any\n header?: (props: { title?: string }) => any\n footer?: () => any\n}>()\n\n// Эффективный размер: локальный проп → `GrConfigProvider` → дефолт компонента.\n// Резолвим здесь, а не полагаемся на `GrModal`: иначе дефолт диалога затенил бы\n// конфиг раньше, чем примитив успел бы в него заглянуть.\nconst resolvedSize = useGrComponentProp('GrDialog', 'size', () => props.size, 'md')\n\nconst resolvedTitle = computed(() => resolveGrDialogTitle(props.title))\n\nconst bodyClass = computed(() => {\n const cfg = resolveGrDialogSectionConfig(props.bodyConfig, DEFAULT_GR_DIALOG_BODY_CONFIG)\n return [cfg.paddingX, cfg.paddingY]\n})\n\n// Нужен ли sr-only title через `GrModal #title`:\n// - `!showHeader` — вообще нет заголовка в разметке;\n// - `showHeader && $slots.header` — кастомный хедер не обязан содержать DialogTitle.\n// В обоих случаях даём окну a11y-title, не дублируя его визуально.\nconst useModalSrOnlyTitle = computed(\n () => !!resolvedTitle.value && (!props.showHeader || !!slots.header),\n)\n\nfunction open(): void {\n emit('update:modelValue', true)\n}\n\nfunction close(): void {\n emit('update:modelValue', false)\n}\n\nfunction toggle(): void {\n emit('update:modelValue', !props.modelValue)\n}\n\ndefineExpose({ open, close, toggle })\n</script>\n\n<template>\n <GrModal\n :model-value=\"modelValue\"\n :size=\"resolvedSize\"\n :scroll-behavior=\"scrollBehavior\"\n :initial-focus=\"initialFocus\"\n :close-on-backdrop=\"closeOnBackdrop\"\n :close-on-esc=\"closeOnEsc\"\n :aria-label=\"ariaLabel ?? resolvedTitle\"\n @update:model-value=\"emit('update:modelValue', $event)\"\n @opened=\"emit('opened')\"\n @closed=\"emit('closed')\"\n >\n <template v-if=\"useModalSrOnlyTitle\" #title>\n <span class=\"sr-only\">{{ resolvedTitle }}</span>\n </template>\n\n <!-- Шапка и подвал уходят в layout-слоты `GrModal`: при `inside` они\n остаются вне скроллящегося тела. -->\n <template v-if=\"showHeader\" #header>\n <GrDialogHeader\n :title=\"resolvedTitle\"\n :show-close-button=\"showCloseButton\"\n :config=\"headerConfig\"\n :close-label=\"closeLabel\"\n @close=\"close\"\n >\n <template v-if=\"slots.header\" #default=\"slotProps\">\n <slot name=\"header\" v-bind=\"slotProps\" />\n </template>\n </GrDialogHeader>\n </template>\n\n <div :class=\"bodyClass\">\n <slot />\n </div>\n\n <template v-if=\"slots.footer\" #footer>\n <GrDialogFooter :config=\"footerConfig\">\n <slot name=\"footer\" />\n </GrDialogFooter>\n </template>\n </GrModal>\n</template>\n"],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { i as GrDialogFooter_default, n as GrDialogHeader_default, r as GrDialogCloseButton_default, t as GrDialog_default } from "./chunks/GrDialog-
|
|
1
|
+
import { i as GrDialogFooter_default, n as GrDialogHeader_default, r as GrDialogCloseButton_default, t as GrDialog_default } from "./chunks/GrDialog-C9Zu72jB.js";
|
|
2
2
|
import { t as grDialogSafelist } from "../../chunks/safelist-Y3zrlhOa.js";
|
|
3
3
|
export { GrDialog_default as GrDialog, GrDialog_default as default, GrDialogCloseButton_default as GrDialogCloseButton, GrDialogFooter_default as GrDialogFooter, GrDialogHeader_default as GrDialogHeader, grDialogSafelist };
|
|
@@ -4,8 +4,8 @@ import { n as useGranularityTranslations, t as resolveGranularityI18n } from "..
|
|
|
4
4
|
import { t as ensurePortalRoot } from "../../../chunks/portalRoot-CVhCgdG6.js";
|
|
5
5
|
import { t as GrButton_default } from "../../GrButton/chunks/GrButton-CS4TqMtG.js";
|
|
6
6
|
import { n as coreResponseErrorParsers, o as responseErrorParserPresets, r as createResponseErrorClassifier } from "../../GrResponseErrorBanner/chunks/GrResponseErrorBanner-Bdd5c07x.js";
|
|
7
|
-
import { t as GrConfirmDialog_default } from "../../GrConfirmDialog/chunks/GrConfirmDialog-
|
|
8
|
-
import { t as GrPromptDialog_default } from "../../GrPromptDialog/chunks/GrPromptDialog-
|
|
7
|
+
import { t as GrConfirmDialog_default } from "../../GrConfirmDialog/chunks/GrConfirmDialog-dg021BMd.js";
|
|
8
|
+
import { t as GrPromptDialog_default } from "../../GrPromptDialog/chunks/GrPromptDialog-BhbIZP1f.js";
|
|
9
9
|
import { Fragment, computed, createBlock, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, getCurrentInstance, inject, markRaw, mergeProps, nextTick, onBeforeUnmount, onMounted, openBlock, provide, reactive, ref, render, renderList, shallowRef, toDisplayString, withCtx } from "vue";
|
|
10
10
|
//#region src/components/GrDialogService/store.ts
|
|
11
11
|
function createDialogServiceState() {
|