@feugene/granularity 0.9.3 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/{config-d386uO3O.js.map → config-58Mj2rGH.js.map} +1 -1
- package/dist/chunks/{config-D4s_QWVP.js.map → config-8f8624RN.js.map} +1 -1
- package/dist/chunks/{config-B_nSBc7W.js.map → config-A-iei0Ux.js.map} +1 -1
- package/dist/chunks/{config-CFf7xaG1.js → config-B0uUCaJW.js} +1 -1
- package/dist/chunks/{config-CFf7xaG1.js.map → config-B0uUCaJW.js.map} +1 -1
- package/dist/chunks/{config-Dcb7xK-C.js.map → config-B3dn-gdC.js.map} +1 -1
- package/dist/chunks/{config-D6Oe3blW2.js.map → config-BLa1TEGm2.js.map} +1 -1
- package/dist/chunks/{config-Dzd6BzIN2.js.map → config-BeBsN0c12.js.map} +1 -1
- package/dist/chunks/{config-BU0olrvr.js.map → config-Bh4NWWsQ.js.map} +1 -1
- package/dist/chunks/{config-BeQuykDk2.js.map → config-BuoIngj32.js.map} +1 -1
- package/dist/chunks/{config-BbKroFtR.js.map → config-C5-ujXCI.js.map} +1 -1
- package/dist/chunks/{config-BY81UKv0.js → config-C8MM2Dg0.js} +1 -1
- package/dist/chunks/{config-BY81UKv0.js.map → config-C8MM2Dg0.js.map} +1 -1
- package/dist/chunks/{config-DF_RlCIO.js.map → config-CPSdAjUi.js.map} +1 -1
- package/dist/chunks/{config-iuMz79Mg.js.map → config-CWTfyPNI.js.map} +1 -1
- package/dist/chunks/{config-Br_qI3Za.js → config-C_egzT_K.js} +2 -2
- package/dist/chunks/config-C_egzT_K.js.map +1 -0
- package/dist/chunks/{config-Ci9nXGUV.js.map → config-C_q_4FrU.js.map} +1 -1
- package/dist/chunks/{config-O1_FTqD3.js.map → config-CzgNEHKi.js.map} +1 -1
- package/dist/chunks/{config-Bcf-8XlK2.js.map → config-DDUPnue12.js.map} +1 -1
- package/dist/chunks/{config-DmjwIqx1.js.map → config-DDwBSoc_.js.map} +1 -1
- package/dist/chunks/{config-C5OwJM3-.js → config-DRpkoSvq.js} +1 -1
- package/dist/chunks/{config-C5OwJM3-.js.map → config-DRpkoSvq.js.map} +1 -1
- package/dist/chunks/{config-DaHI5bD_2.js.map → config-DZrlovR42.js.map} +1 -1
- package/dist/chunks/{config-72sW9Bag2.js.map → config-D_Pafsjq2.js.map} +1 -1
- package/dist/chunks/{config-B1kFmhpM.js.map → config-DhQc1TRY.js.map} +1 -1
- package/dist/chunks/{config-CetsgpaZ2.js.map → config-DkeLkzxj2.js.map} +1 -1
- package/dist/chunks/{config-BOdu-O_B.js.map → config-Dl5aZ5VR.js.map} +1 -1
- package/dist/chunks/{config-CvGdaXvH.js.map → config-Doa_gU40.js.map} +1 -1
- package/dist/chunks/{config-CdJpnjDj.js.map → config-DvDNney3.js.map} +1 -1
- package/dist/chunks/{config-CpMYmvVT.js.map → config-NkbzVFZo.js.map} +1 -1
- package/dist/chunks/{config-_3De4HFf.js.map → config-RjfJFv1Y.js.map} +1 -1
- package/dist/chunks/{config-DoBk_CzG.js.map → config-VJuoznpH.js.map} +1 -1
- package/dist/chunks/{config-BnWSHTEU.js.map → config-XspHtPsU.js.map} +1 -1
- package/dist/chunks/{config-B2YTEe_h.js.map → config-hSlCXHoG.js.map} +1 -1
- package/dist/chunks/{config-DSBlHQVa.js.map → config-lMDE_8A5.js.map} +1 -1
- package/dist/chunks/{config-Cp_XHsze.js.map → config-nrOj9p6I.js.map} +1 -1
- package/dist/chunks/{en-foQA8imU.js → en-B_fSdoTi.js} +9 -2
- package/dist/chunks/en-B_fSdoTi.js.map +1 -0
- package/dist/chunks/{es-Bx3Kuy6z.js → es-CISK11Nv.js} +3 -3
- package/dist/chunks/{es-Bx3Kuy6z.js.map → es-CISK11Nv.js.map} +1 -1
- package/dist/chunks/{es-DZFSojYL.js → es-DKP6fLir.js} +9 -2
- package/dist/chunks/es-DKP6fLir.js.map +1 -0
- package/dist/chunks/{grDropdownStyles-B41mVR1H.js → grDropdownStyles-Bqx9hOzU.js} +10 -7
- package/dist/chunks/grDropdownStyles-Bqx9hOzU.js.map +1 -0
- package/dist/chunks/{grModalStyles-DS1Vl6EW.js → grModalStyles-FgaKqx50.js} +1 -1
- package/dist/chunks/grModalStyles-FgaKqx50.js.map +1 -0
- package/dist/chunks/grSelectStyles-AjWWl007.js.map +1 -0
- package/dist/chunks/{grStyle-CUaTmpyW.js.map → grStyle-D-gPHdyW.js.map} +1 -1
- package/dist/chunks/{granularityI18n-LcJ88Vce.js → granularityI18n-D_7jowK2.js} +17 -2
- package/dist/chunks/granularityI18n-D_7jowK2.js.map +1 -0
- package/dist/chunks/{ru-LhkPpPIl.js → ru-S6VlnurJ.js} +9 -2
- package/dist/chunks/ru-S6VlnurJ.js.map +1 -0
- package/dist/chunks/{shared-BiqXd5MW.js → shared-DpjTvFno.js} +34 -34
- package/dist/chunks/{shared-BiqXd5MW.js.map → shared-DpjTvFno.js.map} +1 -1
- package/dist/chunks/useFloating-CLtbU7eD.js +1234 -0
- package/dist/chunks/useFloating-CLtbU7eD.js.map +1 -0
- package/dist/components/GrConfirmDialog/chunks/{GrConfirmDialog-Br6WJkLE.js → GrConfirmDialog-Bi2KLumL.js} +2 -2
- package/dist/components/GrConfirmDialog/chunks/{GrConfirmDialog-Br6WJkLE.js.map → GrConfirmDialog-Bi2KLumL.js.map} +1 -1
- package/dist/components/GrConfirmDialog/index.js +1 -1
- package/dist/components/GrDialog/chunks/{GrDialog-C7XLxp8e.js → GrDialog-CxK4Lj4F.js} +1 -1
- package/dist/components/GrDialog/chunks/{GrDialog-C7XLxp8e.js.map → GrDialog-CxK4Lj4F.js.map} +1 -1
- package/dist/components/GrDialog/index.js +1 -1
- package/dist/components/GrDropdown/chunks/{GrDropdown-DOvHKnih.js → GrDropdown-BGKeEfZ1.js} +13 -59
- package/dist/components/GrDropdown/chunks/GrDropdown-BGKeEfZ1.js.map +1 -0
- package/dist/components/GrDropdown/index.js +2 -2
- package/dist/components/GrDropdownMenu/chunks/{GrDropdownMenu-CLPwbiyG.js → GrDropdownMenu-CJom_-c2.js} +1 -1
- package/dist/components/GrDropdownMenu/chunks/{GrDropdownMenu-CLPwbiyG.js.map → GrDropdownMenu-CJom_-c2.js.map} +1 -1
- package/dist/components/GrDropdownMenu/index.js +2 -2
- package/dist/components/GrEmptyState/chunks/{GrEmptyState-Dj2V5GaX.js.map → GrEmptyState-yOuZW7-t.js.map} +1 -1
- package/dist/components/GrEmptyState/index.js +2 -2
- package/dist/components/GrFileUpload/chunks/{GrFileUpload-BEKNB1RM.js → GrFileUpload-CBKK3dgC.js} +1 -1
- package/dist/components/GrFileUpload/chunks/{GrFileUpload-BEKNB1RM.js.map → GrFileUpload-CBKK3dgC.js.map} +1 -1
- package/dist/components/GrFileUpload/index.js +2 -2
- package/dist/components/GrFormField/index.js +1 -1
- package/dist/components/GrFormFile/chunks/{GrFormFile-CIleXnfr.js.map → GrFormFile-CkR6cYqf.js.map} +1 -1
- package/dist/components/GrFormFile/index.js +2 -2
- package/dist/components/GrFormSection/chunks/{GrFormSection-DpGhY7MX.js.map → GrFormSection-dbyzqxYk.js.map} +1 -1
- package/dist/components/GrFormSection/index.js +2 -2
- package/dist/components/GrImageViewer/chunks/{GrImageViewer-CsvXQHM9.js.map → GrImageViewer-BG40DsHa.js.map} +1 -1
- package/dist/components/GrImageViewer/index.js +2 -2
- package/dist/components/GrInput/index.js +1 -1
- package/dist/components/GrInputTag/chunks/{GrInputTag-Dcj3F6rQ.js → GrInputTag-g-KdUI_Z.js} +1 -1
- package/dist/components/GrInputTag/chunks/{GrInputTag-Dcj3F6rQ.js.map → GrInputTag-g-KdUI_Z.js.map} +1 -1
- package/dist/components/GrInputTag/index.js +2 -2
- package/dist/components/GrLink/chunks/{GrLink-BMwn2iJ9.js → GrLink-KSTmk9Yq.js} +1 -1
- package/dist/components/GrLink/chunks/{GrLink-BMwn2iJ9.js.map → GrLink-KSTmk9Yq.js.map} +1 -1
- package/dist/components/GrLink/index.js +2 -2
- package/dist/components/GrList/chunks/{GrList-D8nM1FuV.js.map → GrList-CUW2sRm_.js.map} +1 -1
- package/dist/components/GrList/index.js +2 -2
- package/dist/components/GrLoading/index.js +1 -1
- package/dist/components/GrModal/chunks/{GrModal-lh0lOmoi.js → GrModal-CSOL3fHQ.js} +1 -1
- package/dist/components/GrModal/chunks/{GrModal-lh0lOmoi.js.map → GrModal-CSOL3fHQ.js.map} +1 -1
- package/dist/components/GrModal/index.js +3 -3
- package/dist/components/GrNavbar/chunks/{GrNavbar-BH7XiF9q.js → GrNavbar-CHxwtFIR.js} +1 -1
- package/dist/components/GrNavbar/chunks/{GrNavbar-BH7XiF9q.js.map → GrNavbar-CHxwtFIR.js.map} +1 -1
- package/dist/components/GrNavbar/index.js +2 -2
- package/dist/components/GrNumberInput/chunks/{GrNumberInput-YIWhV85S.js → GrNumberInput-ClPBwkxx.js} +1 -1
- package/dist/components/GrNumberInput/chunks/{GrNumberInput-YIWhV85S.js.map → GrNumberInput-ClPBwkxx.js.map} +1 -1
- package/dist/components/GrNumberInput/index.js +2 -2
- package/dist/components/GrPagination/chunks/{GrPagination-cD6rFO9W.js → GrPagination-D2GS0ShQ.js} +4 -4
- package/dist/components/GrPagination/chunks/GrPagination-D2GS0ShQ.js.map +1 -0
- package/dist/components/GrPagination/index.js +2 -2
- package/dist/components/GrProgressBar/chunks/{GrProgressBar-C2HdYjp4.js → GrProgressBar-BBSFpVEq.js} +1 -1
- package/dist/components/GrProgressBar/chunks/{GrProgressBar-C2HdYjp4.js.map → GrProgressBar-BBSFpVEq.js.map} +1 -1
- package/dist/components/GrProgressBar/index.js +2 -2
- package/dist/components/GrPromptDialog/chunks/{GrPromptDialog-BV4EW3XO.js → GrPromptDialog-D_TFqKsF.js} +2 -2
- package/dist/components/GrPromptDialog/chunks/{GrPromptDialog-BV4EW3XO.js.map → GrPromptDialog-D_TFqKsF.js.map} +1 -1
- package/dist/components/GrPromptDialog/index.js +2 -2
- package/dist/components/GrRadio/chunks/{GrRadio-IFU9Hiu2.js → GrRadio-CSbTnrom.js} +1 -1
- package/dist/components/GrRadio/chunks/{GrRadio-IFU9Hiu2.js.map → GrRadio-CSbTnrom.js.map} +1 -1
- package/dist/components/GrRadio/index.js +2 -2
- package/dist/components/GrRadioGroup/chunks/{GrRadioGroup-C8IcJuuF.js → GrRadioGroup-DsrnTygR.js} +1 -1
- package/dist/components/GrRadioGroup/chunks/{GrRadioGroup-C8IcJuuF.js.map → GrRadioGroup-DsrnTygR.js.map} +1 -1
- package/dist/components/GrRadioGroup/index.js +2 -2
- package/dist/components/GrResponseErrorBanner/chunks/{GrResponseErrorBanner-BMvXREcv.js → GrResponseErrorBanner-K1uZ1mYD.js} +1 -1
- package/dist/components/GrResponseErrorBanner/chunks/{GrResponseErrorBanner-BMvXREcv.js.map → GrResponseErrorBanner-K1uZ1mYD.js.map} +1 -1
- package/dist/components/GrResponseErrorBanner/chunks/{GrResponseErrorBanner-CzdTh4gd.js → GrResponseErrorBanner-bM8FC_Bw.js} +1 -1
- package/dist/components/GrResponseErrorBanner/chunks/{GrResponseErrorBanner-CzdTh4gd.js.map → GrResponseErrorBanner-bM8FC_Bw.js.map} +1 -1
- package/dist/components/GrResponseErrorBanner/index.js +2 -2
- package/dist/components/GrSegmented/chunks/{GrSegmented-BRmwBsEG.js → GrSegmented-DpZGs4VX.js} +1 -1
- package/dist/components/GrSegmented/chunks/{GrSegmented-BRmwBsEG.js.map → GrSegmented-DpZGs4VX.js.map} +1 -1
- package/dist/components/GrSegmented/index.js +2 -2
- package/dist/components/GrSelect/chunks/{GrSelect-W9lbAjRZ.js → GrSelect-DSz7jvUb.js} +132 -106
- package/dist/components/GrSelect/chunks/GrSelect-DSz7jvUb.js.map +1 -0
- package/dist/components/GrSelect/index.js +2 -2
- package/dist/components/GrSidebar/chunks/{GrSidebar-BpBtAGBs.js.map → GrSidebar-BW8LRMZ-.js.map} +1 -1
- package/dist/components/GrSidebar/index.js +2 -2
- package/dist/components/GrSkeleton/chunks/{GrSkeleton-URyMkBqI.js.map → GrSkeleton-B05K0QKh.js.map} +1 -1
- package/dist/components/GrSkeleton/index.js +2 -2
- package/dist/components/GrSwitch/chunks/{GrSwitch-29h0QhMO.js → GrSwitch-CSRtcN5-.js} +1 -1
- package/dist/components/GrSwitch/chunks/{GrSwitch-29h0QhMO.js.map → GrSwitch-CSRtcN5-.js.map} +1 -1
- package/dist/components/GrSwitch/index.js +2 -2
- package/dist/components/GrTable/index.js +1 -1
- package/dist/components/GrTabs/chunks/{GrTabs-D3ntDdtg.js.map → GrTabs-BfeVNMFJ.js.map} +1 -1
- package/dist/components/GrTabs/index.js +2 -2
- package/dist/components/GrTextarea/chunks/{GrTextarea-Cv6r2GuC.js → GrTextarea-CBBzpF2S.js} +1 -1
- package/dist/components/GrTextarea/chunks/{GrTextarea-Cv6r2GuC.js.map → GrTextarea-CBBzpF2S.js.map} +1 -1
- package/dist/components/GrTextarea/index.js +2 -2
- package/dist/components/GrToaster/chunks/{GrToaster-DluJmR5D.js → GrToaster-C6_iHk2J.js} +4 -3
- package/dist/components/GrToaster/chunks/GrToaster-C6_iHk2J.js.map +1 -0
- package/dist/components/GrToaster/index.js +2 -2
- package/dist/components/GrTooltip/chunks/GrTooltip-BC-40SA5.js +109 -0
- package/dist/components/GrTooltip/chunks/GrTooltip-BC-40SA5.js.map +1 -0
- package/dist/components/GrTooltip/index.js +2 -2
- package/dist/components/GrTree/chunks/{GrTree-B2SMU5Py.js.map → GrTree-uZr5SyQI.js.map} +1 -1
- package/dist/components/GrTree/index.js +2 -2
- package/dist/components/GrTreeSelect/chunks/{GrTreeSelect-C1abr5uH.js → GrTreeSelect-CytivcCa.js} +9 -37
- package/dist/components/GrTreeSelect/chunks/GrTreeSelect-CytivcCa.js.map +1 -0
- package/dist/components/GrTreeSelect/index.js +2 -2
- package/dist/granular-provider-node.js +2 -2
- 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 +67 -67
- package/dist/types/src/components/GrDropdown/grDropdownStyles.d.ts +3 -2
- package/dist/types/src/components/GrDropdownMenu/GrDropdownMenu.vue.d.ts +2 -2
- package/dist/types/src/components/GrDropdownMenu/GrDropdownMenuGroup.vue.d.ts +1 -1
- package/dist/types/src/components/GrDropdownMenu/GrDropdownMenuList.vue.d.ts +2 -2
- package/dist/types/src/components/GrFileUpload/GrFileUpload.vue.d.ts +1 -1
- package/dist/types/src/components/GrLink/GrLink.vue.d.ts +1 -1
- package/dist/types/src/components/GrModal/grModalStyles.d.ts +1 -1
- package/dist/types/src/components/GrSegmented/GrSegmented.vue.d.ts +1 -1
- package/dist/types/src/components/GrSelect/GrSelect.vue.d.ts +11 -10
- package/dist/types/src/components/GrSelect/grSelectStyles.d.ts +7 -0
- package/dist/types/src/components/GrSelect/index.d.ts +1 -1
- package/dist/types/src/composables/internal/useFloating.d.ts +53 -0
- package/dist/types/src/i18n/messages/en.d.ts +12 -0
- package/dist/types/src/i18n/messages/es.d.ts +12 -0
- package/dist/types/src/i18n/messages/ru.d.ts +12 -0
- package/package.json +9 -1
- package/dist/chunks/config-Br_qI3Za.js.map +0 -1
- package/dist/chunks/en-foQA8imU.js.map +0 -1
- package/dist/chunks/es-DZFSojYL.js.map +0 -1
- package/dist/chunks/grDropdownStyles-B41mVR1H.js.map +0 -1
- package/dist/chunks/grModalStyles-DS1Vl6EW.js.map +0 -1
- package/dist/chunks/grSelectStyles-pUt19VGy.js.map +0 -1
- package/dist/chunks/granularityI18n-LcJ88Vce.js.map +0 -1
- package/dist/chunks/ru-LhkPpPIl.js.map +0 -1
- package/dist/components/GrDropdown/chunks/GrDropdown-DOvHKnih.js.map +0 -1
- package/dist/components/GrPagination/chunks/GrPagination-cD6rFO9W.js.map +0 -1
- package/dist/components/GrSelect/chunks/GrSelect-W9lbAjRZ.js.map +0 -1
- package/dist/components/GrToaster/chunks/GrToaster-DluJmR5D.js.map +0 -1
- package/dist/components/GrTooltip/chunks/GrTooltip-B7I1AVIC.js +0 -55
- package/dist/components/GrTooltip/chunks/GrTooltip-B7I1AVIC.js.map +0 -1
- package/dist/components/GrTreeSelect/chunks/GrTreeSelect-C1abr5uH.js.map +0 -1
- /package/dist/chunks/{config-d386uO3O.js → config-58Mj2rGH.js} +0 -0
- /package/dist/chunks/{config-D4s_QWVP.js → config-8f8624RN.js} +0 -0
- /package/dist/chunks/{config-B_nSBc7W.js → config-A-iei0Ux.js} +0 -0
- /package/dist/chunks/{config-Dcb7xK-C.js → config-B3dn-gdC.js} +0 -0
- /package/dist/chunks/{config-D6Oe3blW2.js → config-BLa1TEGm2.js} +0 -0
- /package/dist/chunks/{config-Dzd6BzIN2.js → config-BeBsN0c12.js} +0 -0
- /package/dist/chunks/{config-BU0olrvr.js → config-Bh4NWWsQ.js} +0 -0
- /package/dist/chunks/{config-BeQuykDk2.js → config-BuoIngj32.js} +0 -0
- /package/dist/chunks/{config-BbKroFtR.js → config-C5-ujXCI.js} +0 -0
- /package/dist/chunks/{config-DF_RlCIO.js → config-CPSdAjUi.js} +0 -0
- /package/dist/chunks/{config-iuMz79Mg.js → config-CWTfyPNI.js} +0 -0
- /package/dist/chunks/{config-Ci9nXGUV.js → config-C_q_4FrU.js} +0 -0
- /package/dist/chunks/{config-O1_FTqD3.js → config-CzgNEHKi.js} +0 -0
- /package/dist/chunks/{config-Bcf-8XlK2.js → config-DDUPnue12.js} +0 -0
- /package/dist/chunks/{config-DmjwIqx1.js → config-DDwBSoc_.js} +0 -0
- /package/dist/chunks/{config-DaHI5bD_2.js → config-DZrlovR42.js} +0 -0
- /package/dist/chunks/{config-72sW9Bag2.js → config-D_Pafsjq2.js} +0 -0
- /package/dist/chunks/{config-B1kFmhpM.js → config-DhQc1TRY.js} +0 -0
- /package/dist/chunks/{config-CetsgpaZ2.js → config-DkeLkzxj2.js} +0 -0
- /package/dist/chunks/{config-BOdu-O_B.js → config-Dl5aZ5VR.js} +0 -0
- /package/dist/chunks/{config-CvGdaXvH.js → config-Doa_gU40.js} +0 -0
- /package/dist/chunks/{config-CdJpnjDj.js → config-DvDNney3.js} +0 -0
- /package/dist/chunks/{config-CpMYmvVT.js → config-NkbzVFZo.js} +0 -0
- /package/dist/chunks/{config-_3De4HFf.js → config-RjfJFv1Y.js} +0 -0
- /package/dist/chunks/{config-DoBk_CzG.js → config-VJuoznpH.js} +0 -0
- /package/dist/chunks/{config-BnWSHTEU.js → config-XspHtPsU.js} +0 -0
- /package/dist/chunks/{config-B2YTEe_h.js → config-hSlCXHoG.js} +0 -0
- /package/dist/chunks/{config-DSBlHQVa.js → config-lMDE_8A5.js} +0 -0
- /package/dist/chunks/{config-Cp_XHsze.js → config-nrOj9p6I.js} +0 -0
- /package/dist/chunks/{grSelectStyles-pUt19VGy.js → grSelectStyles-AjWWl007.js} +0 -0
- /package/dist/chunks/{grStyle-CUaTmpyW.js → grStyle-D-gPHdyW.js} +0 -0
- /package/dist/components/GrEmptyState/chunks/{GrEmptyState-Dj2V5GaX.js → GrEmptyState-yOuZW7-t.js} +0 -0
- /package/dist/components/GrFormFile/chunks/{GrFormFile-CIleXnfr.js → GrFormFile-CkR6cYqf.js} +0 -0
- /package/dist/components/GrFormSection/chunks/{GrFormSection-DpGhY7MX.js → GrFormSection-dbyzqxYk.js} +0 -0
- /package/dist/components/GrImageViewer/chunks/{GrImageViewer-CsvXQHM9.js → GrImageViewer-BG40DsHa.js} +0 -0
- /package/dist/components/GrList/chunks/{GrList-D8nM1FuV.js → GrList-CUW2sRm_.js} +0 -0
- /package/dist/components/GrSidebar/chunks/{GrSidebar-BpBtAGBs.js → GrSidebar-BW8LRMZ-.js} +0 -0
- /package/dist/components/GrSkeleton/chunks/{GrSkeleton-URyMkBqI.js → GrSkeleton-B05K0QKh.js} +0 -0
- /package/dist/components/GrTabs/chunks/{GrTabs-D3ntDdtg.js → GrTabs-BfeVNMFJ.js} +0 -0
- /package/dist/components/GrTree/chunks/{GrTree-B2SMU5Py.js → GrTree-uZr5SyQI.js} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"grModalStyles-DS1Vl6EW.js","names":[],"sources":["../../src/components/GrModal/grModalStyles.ts"],"sourcesContent":["export type GrModalSize = 'sm' | 'md' | 'lg' | 'xl' | 'full'\n\n// Корневые утилитарные классы, используемые шаблоном `GrModal.vue`.\n// Они же являются единственным источником истины для safelist.\nexport const root = 'fixed inset-0 z-50'\nexport const shell = 'fixed inset-0 overflow-y-auto p-4 sm:p-6'\nexport const layout = 'min-h-full flex items-center justify-center'\nexport const overlay = 'fixed inset-0 z-0 bg-black/40'\n\n// Классы для `<TransitionChild :enter=\"...\" :enter-from=\"...\" ...>`.\n// Разбиты по фазам транзишна, чтобы не склеивать их в «мешок токенов».\nexport const overlayTransition = {\n enter: 'duration-200 ease-out',\n enterFrom: 'opacity-0',\n enterTo: 'opacity-100',\n leave: 'duration-150 ease-in',\n leaveFrom: 'opacity-100',\n leaveTo: 'opacity-0',\n} as const\n\nexport const panelTransition = {\n enter: 'duration-200 ease-out',\n enterFrom: 'opacity-0 translate-y-2 sm:translate-y-0 sm:scale-95',\n enterTo: 'opacity-100 translate-y-0 sm:scale-100',\n leave: 'duration-150 ease-in',\n leaveFrom: 'opacity-100 translate-y-0 sm:scale-100',\n leaveTo: 'opacity-0 translate-y-2 sm:translate-y-0 sm:scale-95',\n} as const\n\nexport const panelBase\n = 'w-full overflow-hidden relative z-10 border border-[var(--brd)] bg-[var(--card)] text-[var(--card-fg)] shadow-[var(--ds-shadow-2)] outline-none'\n\nexport const panelWidthBySize: Record<GrModalSize, string> = {\n sm: 'max-w-[420px]',\n md: 'max-w-[560px]',\n lg: 'max-w-[720px]',\n xl: 'max-w-[920px]',\n full: 'max-w-none',\n}\n\nexport const panelRadiusBySize: Record<GrModalSize, string> = {\n sm: 'rounded-[var(--ds-radius-xl)]',\n md: 'rounded-[var(--ds-radius-xl)]',\n lg: 'rounded-[var(--ds-radius-xl)]',\n xl: 'rounded-[var(--ds-radius-xl)]',\n full: 'rounded-none sm:rounded-[var(--ds-radius-xl)]',\n}\n\n// Для большинства размеров высота не задаётся — `Partial` + фильтрация пустых\n// значений в `getGrModalPanelClass` избавляют от двойных пробелов.\nexport const panelHeightBySize: Partial<Record<GrModalSize, string>> = {\n full: 'h-[100svh] sm:h-auto',\n}\n\nexport function getGrModalPanelClass(size: GrModalSize): string {\n return [\n panelBase,\n panelWidthBySize[size],\n panelHeightBySize[size],\n panelRadiusBySize[size],\n ]\n .filter(Boolean)\n .join(' ')\n}\n"],"mappings":";AAIA,IAAa,OAAO;AACpB,IAAa,QAAQ;AACrB,IAAa,SAAS;AACtB,IAAa,UAAU;AAIvB,IAAa,oBAAoB;CAC/B,OAAO;CACP,WAAW;CACX,SAAS;CACT,OAAO;CACP,WAAW;CACX,SAAS;CACV;AAED,IAAa,kBAAkB;CAC7B,OAAO;CACP,WAAW;CACX,SAAS;CACT,OAAO;CACP,WAAW;CACX,SAAS;CACV;AAED,IAAa,YACT;AAEJ,IAAa,mBAAgD;CAC3D,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,MAAM;CACP;AAED,IAAa,oBAAiD;CAC5D,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,MAAM;CACP;AAID,IAAa,oBAA0D,EACrE,MAAM,wBACP;AAED,SAAgB,qBAAqB,MAA2B;AAC9D,QAAO;EACL;EACA,iBAAiB;EACjB,kBAAkB;EAClB,kBAAkB;EACnB,CACE,OAAO,QAAQ,CACf,KAAK,IAAI"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"grSelectStyles-pUt19VGy.js","names":[],"sources":["../../src/components/GrSelect/grSelectStyles.ts"],"sourcesContent":["export type GrSelectView = 'default' | 'link'\nexport type GrSelectSize = 'xs' | 'sm' | 'md' | 'lg'\nexport type GrSelectVariant = 'primary' | 'default' | 'muted' | 'danger'\nexport type GrSelectUnderline = 'auto' | 'always' | 'none'\nexport type GrSelectOptionsView = 'native' | 'panel'\nexport type GrSelectOption = { value: string, label: string }\nexport type GrSelectModelValue = string | string[]\n\nexport const defaultBaseClass = 'w-full rounded-md border border-[var(--brd)] bg-[var(--bg)] text-[var(--fg)] transition-colors duration-150 focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)]'\nexport const linkBaseClass = 'cursor-pointer inline-block w-auto align-baseline appearance-none bg-transparent border border-transparent px-0 py-0 rounded-[6px] transition-colors duration-150 focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)]'\n\n\nexport const selectSizeClassBySize: Record<GrSelectSize, string> = {\n xs: 'h-7 px-2.5 text-[12px]',\n sm: 'h-8 px-3 text-[13px]',\n md: 'h-10 px-3 text-[14px]',\n lg: 'h-11 px-4 text-[16px]',\n}\n\nexport const selectLinkSizeClassBySize: Record<GrSelectSize, string> = {\n xs: 'text-[12px]',\n sm: 'text-[13px]',\n md: 'text-[14px]',\n lg: 'text-[16px]',\n}\n\nexport const selectLinkVariantClassByVariant: Record<GrSelectVariant, string> = {\n primary: 'text-[var(--primary)] hover:text-[var(--primary-hover)] active:text-[var(--primary-active)]',\n default: 'text-[var(--fg)] hover:text-[var(--primary)] active:text-[var(--primary-active)]',\n muted: 'text-[var(--muted-fg)] hover:text-[var(--fg)] active:text-[var(--fg)]',\n danger: 'text-[var(--ds-danger)] hover:text-[var(--ds-danger-hover)] active:text-[var(--ds-danger-active)]',\n}\n\n/**\n * Variant-классы для видимой метки в `view=\"link\"` + `optionsView=\"native\"`.\n * Hover-цвет приходит через `peer-hover:` от прозрачного `<select>`-overlay,\n * т.к. видимая метка имеет `pointer-events-none` и не получает hover напрямую.\n */\nexport const selectLinkNativeLabelVariantClassByVariant: Record<GrSelectVariant, string> = {\n primary: 'text-[var(--primary)] peer-hover:text-[var(--primary-hover)] peer-active:text-[var(--primary-active)]',\n default: 'text-[var(--fg)] peer-hover:text-[var(--primary)] peer-active:text-[var(--primary-active)]',\n muted: 'text-[var(--muted-fg)] peer-hover:text-[var(--fg)] peer-active:text-[var(--fg)]',\n danger: 'text-[var(--ds-danger)] peer-hover:text-[var(--ds-danger-hover)] peer-active:text-[var(--ds-danger-active)]',\n}\n\nfunction selectLinkUnderlineClass(options: { underline: GrSelectUnderline, disabled: boolean }): string {\n if (options.disabled) return 'no-underline'\n if (options.underline === 'always') return 'underline underline-offset-4'\n if (options.underline === 'none') return 'no-underline'\n return 'no-underline hover:underline hover:underline-offset-4'\n}\n\n/**\n * Underline-классы для видимой метки в `view=\"link\"` + `optionsView=\"native\"`.\n * Видимая метка имеет `pointer-events-none`, а hover получает прозрачный\n * `<select>`-overlay (peer), поэтому для `underline=\"auto\"` используем\n * `peer-hover:underline` вместо `hover:underline`.\n */\nfunction selectLinkNativeLabelUnderlineClass(options: { underline: GrSelectUnderline, disabled: boolean }): string {\n if (options.disabled) return 'no-underline'\n if (options.underline === 'always') return 'underline underline-offset-4'\n if (options.underline === 'none') return 'no-underline'\n return 'no-underline peer-hover:underline peer-hover:underline-offset-4'\n}\n\n/**\n * Классы прозрачного `<select>`-overlay для `view=\"link\"` + `optionsView=\"native\"`.\n * Нативный селект растягивается на всю обёртку, но визуально невидим — ширину обёртки\n * задаёт видимый `<span>` с выбранной меткой, благодаря чему компонент в закрытом\n * состоянии занимает столько места, сколько нужно текущей опции (а не самой длинной).\n */\nexport const grSelectLinkNativeOverlayClass = 'peer absolute inset-0 w-full h-full m-0 p-0 border-0 bg-transparent text-transparent appearance-none opacity-0 cursor-pointer disabled:cursor-not-allowed focus:outline-none'\n\n/**\n * Классы видимой метки для `view=\"link\"` + `optionsView=\"native\"` (поверх прозрачного `<select>`).\n * Получает все link-стили (size/variant/underline), а также focus-ring через `peer-focus-visible`.\n */\nexport function grSelectLinkNativeLabelClass(options: {\n size: GrSelectSize\n variant: GrSelectVariant\n underline: GrSelectUnderline\n disabled: boolean\n}): string {\n return [\n 'pointer-events-none inline-block whitespace-nowrap align-baseline rounded-[6px] transition-colors duration-150',\n selectLinkSizeClassBySize[options.size],\n selectLinkNativeLabelUnderlineClass({ underline: options.underline, disabled: options.disabled }),\n selectLinkNativeLabelVariantClassByVariant[options.variant],\n options.disabled ? 'opacity-60 text-[var(--muted-fg)] no-underline' : '',\n 'peer-focus-visible:outline-none peer-focus-visible:ring-2 peer-focus-visible:ring-[var(--ring)]',\n ]\n .filter(Boolean)\n .join(' ')\n}\n\nexport function grSelectClass(options: {\n view: GrSelectView\n size: GrSelectSize\n disabled: boolean\n variant: GrSelectVariant\n underline: GrSelectUnderline\n}): string {\n if (options.view === 'link') {\n return [\n selectLinkSizeClassBySize[options.size],\n selectLinkUnderlineClass({ underline: options.underline, disabled: options.disabled }),\n selectLinkVariantClassByVariant[options.variant],\n 'disabled:opacity-60 disabled:cursor-not-allowed disabled:text-[var(--muted-fg)] disabled:no-underline',\n ].join(' ')\n }\n\n return [\n selectSizeClassBySize[options.size],\n 'disabled:opacity-50 disabled:cursor-not-allowed',\n ].join(' ')\n}\n\nexport function grSelectNativeClass(options: {\n view: GrSelectView\n size: GrSelectSize\n disabled: boolean\n variant: GrSelectVariant\n underline: GrSelectUnderline\n showNativeChevron: boolean\n}): string {\n return [\n grSelectClass(options),\n options.showNativeChevron ? 'appearance-none pr-9' : '',\n ]\n .filter(Boolean)\n .join(' ')\n}\n\nexport function grSelectTriggerClass(options: {\n view: GrSelectView\n optionsView: GrSelectOptionsView\n size: GrSelectSize\n disabled: boolean\n variant: GrSelectVariant\n underline: GrSelectUnderline\n}): string {\n if (options.optionsView !== 'panel') {\n return grSelectClass(options)\n }\n\n if (options.view === 'link') {\n return [\n grSelectClass(options),\n 'inline-flex items-center gap-1 text-left',\n ].join(' ')\n }\n\n return [\n grSelectClass(options),\n 'flex items-center justify-between text-left',\n ].join(' ')\n}\n\nexport const grSelectPanelClasses = 'rounded-[var(--ds-radius-xl)] border border-[var(--brd)] bg-[var(--card)] text-[var(--card-fg)] shadow-[var(--ds-shadow-2)] overflow-hidden'\n"],"mappings":";AAQA,IAAa,mBAAmB;AAChC,IAAa,gBAAgB;AAG7B,IAAa,wBAAsD;CACjE,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACL;AAED,IAAa,4BAA0D;CACrE,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACL;AAED,IAAa,kCAAmE;CAC9E,SAAS;CACT,SAAS;CACT,OAAO;CACP,QAAQ;CACT;;;;;;AAOD,IAAa,6CAA8E;CACzF,SAAS;CACT,SAAS;CACT,OAAO;CACP,QAAQ;CACT;AAED,SAAS,yBAAyB,SAAsE;AACtG,KAAI,QAAQ,SAAU,QAAO;AAC7B,KAAI,QAAQ,cAAc,SAAU,QAAO;AAC3C,KAAI,QAAQ,cAAc,OAAQ,QAAO;AACzC,QAAO;;;;;;;;AAST,SAAS,oCAAoC,SAAsE;AACjH,KAAI,QAAQ,SAAU,QAAO;AAC7B,KAAI,QAAQ,cAAc,SAAU,QAAO;AAC3C,KAAI,QAAQ,cAAc,OAAQ,QAAO;AACzC,QAAO;;;;;;;;AAST,IAAa,iCAAiC;;;;;AAM9C,SAAgB,6BAA6B,SAKlC;AACT,QAAO;EACL;EACA,0BAA0B,QAAQ;EAClC,oCAAoC;GAAE,WAAW,QAAQ;GAAW,UAAU,QAAQ;GAAU,CAAC;EACjG,2CAA2C,QAAQ;EACnD,QAAQ,WAAW,mDAAmD;EACtE;EACD,CACE,OAAO,QAAQ,CACf,KAAK,IAAI;;AAGd,SAAgB,cAAc,SAMnB;AACT,KAAI,QAAQ,SAAS,OACnB,QAAO;EACL,0BAA0B,QAAQ;EAClC,yBAAyB;GAAE,WAAW,QAAQ;GAAW,UAAU,QAAQ;GAAU,CAAC;EACtF,gCAAgC,QAAQ;EACxC;EACD,CAAC,KAAK,IAAI;AAGb,QAAO,CACL,sBAAsB,QAAQ,OAC9B,kDACD,CAAC,KAAK,IAAI;;AAGb,SAAgB,oBAAoB,SAOzB;AACT,QAAO,CACL,cAAc,QAAQ,EACtB,QAAQ,oBAAoB,yBAAyB,GACtD,CACE,OAAO,QAAQ,CACf,KAAK,IAAI;;AAGd,SAAgB,qBAAqB,SAO1B;AACT,KAAI,QAAQ,gBAAgB,QAC1B,QAAO,cAAc,QAAQ;AAG/B,KAAI,QAAQ,SAAS,OACnB,QAAO,CACL,cAAc,QAAQ,EACtB,2CACD,CAAC,KAAK,IAAI;AAGb,QAAO,CACL,cAAc,QAAQ,EACtB,8CACD,CAAC,KAAK,IAAI;;AAGb,IAAa,uBAAuB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"granularityI18n-LcJ88Vce.js","names":[],"sources":["../../src/internal/granularityI18n.ts"],"sourcesContent":["import { getCurrentInstance, inject, type AppContext } from 'vue'\n\nimport { GRANULARITY_I18N_KEY, type GranularityI18nAdapter } from '../i18n/adapter'\n\nexport type GranularityI18nLike = GranularityI18nAdapter\n\n/**\n * Ключ provide/inject из `@feugene/fint-i18n` (`Symbol.for(\"FintI18n\")`).\n *\n * Дублируем константу здесь, чтобы не делать `@feugene/fint-i18n` обязательной\n * runtime-зависимостью пакета: достаточно, чтобы приложение само установило\n * fint-i18n через `installI18n(app, i18n)` — символ глобальный (Symbol.for),\n * поэтому ключи будут совпадать без прямого импорта.\n */\nconst FINT_I18N_KEY: symbol = Symbol.for('FintI18n')\n\nfunction isGranularityI18nLike(value: unknown): value is GranularityI18nLike {\n return typeof (value as GranularityI18nLike | null)?.t === 'function'\n}\n\nexport function resolveGranularityI18n(context?: AppContext | GranularityI18nLike | null): GranularityI18nLike | null {\n if (isGranularityI18nLike(context)) {\n return context\n }\n\n const provides = context?.provides\n\n if (provides) {\n const fromGranularity = provides[GRANULARITY_I18N_KEY as symbol] as GranularityI18nLike | null | undefined\n if (isGranularityI18nLike(fromGranularity)) {\n return fromGranularity\n }\n\n const fromFint = provides[FINT_I18N_KEY] as GranularityI18nLike | null | undefined\n if (isGranularityI18nLike(fromFint)) {\n return fromFint\n }\n\n return null\n }\n\n if (!getCurrentInstance()) {\n return null\n }\n\n const fromGranularity = inject<GranularityI18nLike | null>(GRANULARITY_I18N_KEY, null)\n if (isGranularityI18nLike(fromGranularity)) {\n return fromGranularity\n }\n\n const fromFint = inject<GranularityI18nLike | null>(FINT_I18N_KEY, null)\n if (isGranularityI18nLike(fromFint)) {\n return fromFint\n }\n\n return null\n}\n\nexport function useGranularityTranslations(context?: AppContext | GranularityI18nLike | null) {\n const i18n = resolveGranularityI18n(context)\n\n const t = (key: string, fallback: string, params?: Record<string, any>): string => {\n if (!i18n) {\n return fallback\n }\n\n const result = i18n.t(key, params)\n return result === key ? fallback : result\n }\n\n return {\n i18n,\n t,\n }\n}"],"mappings":";;;;;;;;;;;AAcA,IAAM,gBAAwB,OAAO,IAAI,WAAW;AAEpD,SAAS,sBAAsB,OAA8C;AAC3E,QAAO,OAAQ,OAAsC,MAAM;;AAG7D,SAAgB,uBAAuB,SAA+E;AACpH,KAAI,sBAAsB,QAAQ,CAChC,QAAO;CAGT,MAAM,WAAW,SAAS;AAE1B,KAAI,UAAU;EACZ,MAAM,kBAAkB,SAAS;AACjC,MAAI,sBAAsB,gBAAgB,CACxC,QAAO;EAGT,MAAM,WAAW,SAAS;AAC1B,MAAI,sBAAsB,SAAS,CACjC,QAAO;AAGT,SAAO;;AAGT,KAAI,CAAC,oBAAoB,CACvB,QAAO;CAGT,MAAM,kBAAkB,OAAmC,sBAAsB,KAAK;AACtF,KAAI,sBAAsB,gBAAgB,CACxC,QAAO;CAGT,MAAM,WAAW,OAAmC,eAAe,KAAK;AACxE,KAAI,sBAAsB,SAAS,CACjC,QAAO;AAGT,QAAO;;AAGT,SAAgB,2BAA2B,SAAmD;CAC5F,MAAM,OAAO,uBAAuB,QAAQ;CAE5C,MAAM,KAAK,KAAa,UAAkB,WAAyC;AACjF,MAAI,CAAC,KACH,QAAO;EAGT,MAAM,SAAS,KAAK,EAAE,KAAK,OAAO;AAClC,SAAO,WAAW,MAAM,WAAW;;AAGrC,QAAO;EACL;EACA;EACD"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ru-LhkPpPIl.js","names":[],"sources":["../../src/i18n/locales/ru.json"],"sourcesContent":["{\n \"common\": {\n \"confirm\": \"Подтвердить\",\n \"cancel\": \"Отмена\",\n \"add\": \"Добавить\",\n \"clear\": \"Очистить\",\n \"close\": \"Закрыть\"\n },\n \"loading\": {\n \"defaultText\": \"Загрузка...\"\n },\n \"treeSelect\": {\n \"filterPlaceholder\": \"Поиск…\",\n \"empty\": \"Нет данных\"\n },\n \"dialog\": {\n \"confirm\": {\n \"title\": \"Подтверждение\"\n },\n \"prompt\": {\n \"title\": \"Введите значение\",\n \"label\": \"Значение\",\n \"required\": \"Введите значение.\"\n }\n },\n \"pagination\": {\n \"pageSize\": \"Размер страницы\",\n \"prev\": \"Назад\",\n \"next\": \"Вперёд\"\n },\n \"navbar\": {\n \"openMenu\": \"Открыть меню\"\n },\n \"responseError\": {\n \"networkTitle\": \"Нет связи с сервером\",\n \"networkMessage\": \"Проверьте подключение к интернету и попробуйте ещё раз.\",\n \"abortedTitle\": \"Запрос отменён\",\n \"abortedMessage\": \"Запрос был отменён.\",\n \"validationTitle\": \"Проверьте данные\",\n \"validationMessage\": \"Сервер вернул ошибку валидации. Исправьте поля и попробуйте снова.\",\n \"clientTitle\": \"Ошибка запроса\",\n \"clientMessage\": \"Сервер отклонил запрос.\",\n \"serverTitle\": \"Ошибка сервера\",\n \"serverMessage\": \"Произошла ошибка на сервере. Попробуйте ещё раз.\",\n \"unknownTitle\": \"Что-то пошло не так\",\n \"unknownMessage\": \"Не удалось выполнить операцию. Попробуйте ещё раз.\",\n \"retryLabel\": \"Повторить\",\n \"dismissLabel\": \"Скрыть\"\n },\n \"colors\": {\n \"neutral\": \"Нейтральный\",\n \"success\": \"Успех\",\n \"warning\": \"Предупреждение\",\n \"danger\": \"Опасность\",\n \"info\": \"Инфо\",\n \"primary\": \"Primary\",\n \"slate\": \"Сланцевый\",\n \"azure\": \"Лазурный\"\n }\n}\n"],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"GrDropdown-DOvHKnih.js","names":[],"sources":["../../../../src/components/GrDropdown/GrDropdown.vue","../../../../src/components/GrDropdown/GrDropdown.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, onUnmounted, ref, watch } from 'vue'\n\nimport { vClickOutside } from '../../directives'\nimport {\n grDropdownAlignmentClass,\n grDropdownContentClass,\n grDropdownWidthClass,\n type GrDropdownAlign,\n type GrDropdownWidth,\n} from './grDropdownStyles'\n\nexport interface GrDropdownProps {\n /** Выравнивание панели относительно триггера. */\n align?: GrDropdownAlign\n /** Ширина панели (tailwind-токены `w-*` или `auto`). */\n width?: GrDropdownWidth\n /** Закрывать панель по клику внутри content. */\n closeOnContentClick?: boolean\n /** Дополнительные классы контейнера content. */\n contentClass?: string\n /** Куда телепортировать панель (`body` по умолчанию). */\n teleportTo?: string | HTMLElement\n}\n\nconst props = withDefaults(defineProps<GrDropdownProps>(), {\n align: 'right',\n width: '48',\n closeOnContentClick: true,\n contentClass: '',\n teleportTo: 'body',\n})\n\nconst open = ref(false)\nconst rootEl = ref<HTMLElement | null>(null)\nconst panelEl = ref<HTMLElement | null>(null)\nconst clickOutsideExclude = [() => panelEl.value]\nconst panelStyle = ref<Record<string, string>>({\n left: '0px',\n top: '0px',\n zIndex: '2147483647',\n})\nlet syncFrame = 0\n\nfunction cancelPanelPositionSync(): void {\n if (typeof window === 'undefined') return\n if (!syncFrame) return\n\n window.cancelAnimationFrame(syncFrame)\n syncFrame = 0\n}\n\nfunction syncPanelPosition(): void {\n if (typeof window === 'undefined') return\n\n const root = rootEl.value\n if (!root) return\n\n const rootRect = root.getBoundingClientRect()\n const left = (() => {\n if (props.align === 'right') return rootRect.right\n if (props.align === 'center') return rootRect.left + (rootRect.width / 2)\n return rootRect.left\n })()\n\n panelStyle.value = {\n left: `${left}px`,\n top: `${rootRect.bottom + 8}px`,\n zIndex: '2147483647',\n }\n}\n\nfunction schedulePanelPositionSync(): void {\n if (typeof window === 'undefined') return\n if (syncFrame) return\n\n syncFrame = window.requestAnimationFrame(() => {\n syncFrame = 0\n\n if (open.value) {\n syncPanelPosition()\n }\n })\n}\n\nfunction bindPanelPositionListeners(): void {\n if (typeof window === 'undefined') return\n window.addEventListener('resize', schedulePanelPositionSync)\n window.addEventListener('scroll', schedulePanelPositionSync, true)\n}\n\nfunction unbindPanelPositionListeners(): void {\n if (typeof window === 'undefined') return\n window.removeEventListener('resize', schedulePanelPositionSync)\n window.removeEventListener('scroll', schedulePanelPositionSync, true)\n}\n\nfunction toggle(): void {\n open.value = !open.value\n}\n\nfunction close(): void {\n open.value = false\n}\n\nfunction closeOnEscape(e: KeyboardEvent): void {\n if (e.key === 'Escape') close()\n}\n\nwatch(\n open,\n (isOpen) => {\n if (typeof document === 'undefined') return\n\n document.removeEventListener('keydown', closeOnEscape)\n unbindPanelPositionListeners()\n cancelPanelPositionSync()\n if (isOpen) document.addEventListener('keydown', closeOnEscape)\n\n if (!isOpen) return\n\n bindPanelPositionListeners()\n syncPanelPosition()\n },\n { immediate: true },\n)\n\nwatch(\n () => props.align,\n () => {\n if (open.value) {\n schedulePanelPositionSync()\n }\n },\n)\n\nonUnmounted(() => {\n if (typeof document === 'undefined') return\n document.removeEventListener('keydown', closeOnEscape)\n unbindPanelPositionListeners()\n cancelPanelPositionSync()\n})\n\nconst widthClass = computed(() => grDropdownWidthClass(props.width))\n\nconst contentClasses = computed(() => grDropdownContentClass(props.contentClass))\n\nconst panelClasses = computed(() => {\n return ['fixed z-50', widthClass.value, grDropdownAlignmentClass(props.align)].filter(Boolean)\n})\n\nfunction onContentClick(): void {\n if (props.closeOnContentClick) {\n close()\n }\n}\n</script>\n\n<template>\n <div data-ds-dropdown>\n <div\n ref=\"rootEl\"\n v-click-outside=\"{ handler: close, enabled: open, exclude: clickOutsideExclude }\"\n data-ds-dropdown-trigger\n class=\"inline-block max-w-full\"\n @click=\"toggle\"\n >\n <slot name=\"trigger\" :open=\"open\" :toggle=\"toggle\" :close=\"close\" />\n </div>\n\n <teleport :to=\"teleportTo\">\n <transition\n enter-active-class=\"transition ease-out duration-150\"\n enter-from-class=\"transform opacity-0 scale-95\"\n enter-to-class=\"transform opacity-100 scale-100\"\n leave-active-class=\"transition ease-in duration-100\"\n leave-from-class=\"transform opacity-100 scale-100\"\n leave-to-class=\"transform opacity-0 scale-95\"\n >\n <div\n v-show=\"open\"\n ref=\"panelEl\"\n data-ds-dropdown-panel\n :class=\"panelClasses\"\n :style=\"panelStyle\"\n @click=\"onContentClick\"\n >\n <div data-ds-dropdown-content :class=\"contentClasses\">\n <slot name=\"content\" :close=\"close\" />\n </div>\n </div>\n </transition>\n </teleport>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, onUnmounted, ref, watch } from 'vue'\n\nimport { vClickOutside } from '../../directives'\nimport {\n grDropdownAlignmentClass,\n grDropdownContentClass,\n grDropdownWidthClass,\n type GrDropdownAlign,\n type GrDropdownWidth,\n} from './grDropdownStyles'\n\nexport interface GrDropdownProps {\n /** Выравнивание панели относительно триггера. */\n align?: GrDropdownAlign\n /** Ширина панели (tailwind-токены `w-*` или `auto`). */\n width?: GrDropdownWidth\n /** Закрывать панель по клику внутри content. */\n closeOnContentClick?: boolean\n /** Дополнительные классы контейнера content. */\n contentClass?: string\n /** Куда телепортировать панель (`body` по умолчанию). */\n teleportTo?: string | HTMLElement\n}\n\nconst props = withDefaults(defineProps<GrDropdownProps>(), {\n align: 'right',\n width: '48',\n closeOnContentClick: true,\n contentClass: '',\n teleportTo: 'body',\n})\n\nconst open = ref(false)\nconst rootEl = ref<HTMLElement | null>(null)\nconst panelEl = ref<HTMLElement | null>(null)\nconst clickOutsideExclude = [() => panelEl.value]\nconst panelStyle = ref<Record<string, string>>({\n left: '0px',\n top: '0px',\n zIndex: '2147483647',\n})\nlet syncFrame = 0\n\nfunction cancelPanelPositionSync(): void {\n if (typeof window === 'undefined') return\n if (!syncFrame) return\n\n window.cancelAnimationFrame(syncFrame)\n syncFrame = 0\n}\n\nfunction syncPanelPosition(): void {\n if (typeof window === 'undefined') return\n\n const root = rootEl.value\n if (!root) return\n\n const rootRect = root.getBoundingClientRect()\n const left = (() => {\n if (props.align === 'right') return rootRect.right\n if (props.align === 'center') return rootRect.left + (rootRect.width / 2)\n return rootRect.left\n })()\n\n panelStyle.value = {\n left: `${left}px`,\n top: `${rootRect.bottom + 8}px`,\n zIndex: '2147483647',\n }\n}\n\nfunction schedulePanelPositionSync(): void {\n if (typeof window === 'undefined') return\n if (syncFrame) return\n\n syncFrame = window.requestAnimationFrame(() => {\n syncFrame = 0\n\n if (open.value) {\n syncPanelPosition()\n }\n })\n}\n\nfunction bindPanelPositionListeners(): void {\n if (typeof window === 'undefined') return\n window.addEventListener('resize', schedulePanelPositionSync)\n window.addEventListener('scroll', schedulePanelPositionSync, true)\n}\n\nfunction unbindPanelPositionListeners(): void {\n if (typeof window === 'undefined') return\n window.removeEventListener('resize', schedulePanelPositionSync)\n window.removeEventListener('scroll', schedulePanelPositionSync, true)\n}\n\nfunction toggle(): void {\n open.value = !open.value\n}\n\nfunction close(): void {\n open.value = false\n}\n\nfunction closeOnEscape(e: KeyboardEvent): void {\n if (e.key === 'Escape') close()\n}\n\nwatch(\n open,\n (isOpen) => {\n if (typeof document === 'undefined') return\n\n document.removeEventListener('keydown', closeOnEscape)\n unbindPanelPositionListeners()\n cancelPanelPositionSync()\n if (isOpen) document.addEventListener('keydown', closeOnEscape)\n\n if (!isOpen) return\n\n bindPanelPositionListeners()\n syncPanelPosition()\n },\n { immediate: true },\n)\n\nwatch(\n () => props.align,\n () => {\n if (open.value) {\n schedulePanelPositionSync()\n }\n },\n)\n\nonUnmounted(() => {\n if (typeof document === 'undefined') return\n document.removeEventListener('keydown', closeOnEscape)\n unbindPanelPositionListeners()\n cancelPanelPositionSync()\n})\n\nconst widthClass = computed(() => grDropdownWidthClass(props.width))\n\nconst contentClasses = computed(() => grDropdownContentClass(props.contentClass))\n\nconst panelClasses = computed(() => {\n return ['fixed z-50', widthClass.value, grDropdownAlignmentClass(props.align)].filter(Boolean)\n})\n\nfunction onContentClick(): void {\n if (props.closeOnContentClick) {\n close()\n }\n}\n</script>\n\n<template>\n <div data-ds-dropdown>\n <div\n ref=\"rootEl\"\n v-click-outside=\"{ handler: close, enabled: open, exclude: clickOutsideExclude }\"\n data-ds-dropdown-trigger\n class=\"inline-block max-w-full\"\n @click=\"toggle\"\n >\n <slot name=\"trigger\" :open=\"open\" :toggle=\"toggle\" :close=\"close\" />\n </div>\n\n <teleport :to=\"teleportTo\">\n <transition\n enter-active-class=\"transition ease-out duration-150\"\n enter-from-class=\"transform opacity-0 scale-95\"\n enter-to-class=\"transform opacity-100 scale-100\"\n leave-active-class=\"transition ease-in duration-100\"\n leave-from-class=\"transform opacity-100 scale-100\"\n leave-to-class=\"transform opacity-0 scale-95\"\n >\n <div\n v-show=\"open\"\n ref=\"panelEl\"\n data-ds-dropdown-panel\n :class=\"panelClasses\"\n :style=\"panelStyle\"\n @click=\"onContentClick\"\n >\n <div data-ds-dropdown-content :class=\"contentClasses\">\n <slot name=\"content\" :close=\"close\" />\n </div>\n </div>\n </transition>\n </teleport>\n </div>\n</template>\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"GrPagination-cD6rFO9W.js","names":[],"sources":["../../../../src/components/GrPagination/GrPagination.vue","../../../../src/components/GrPagination/GrPagination.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport GrButton from '../GrButton/GrButton.vue'\nimport GrSelect from '../GrSelect/GrSelect.vue'\n\n/**\n * Пропы пагинации.\n *\n * `total` интерпретируется как общее количество элементов; число страниц\n * вычисляется из `total` и `pageSize`. Окно отображаемых номеров — 5.\n */\nexport interface GrPaginationProps {\n page: number\n pageSize: number\n total: number\n pageSizes?: number[]\n}\n\nconst { t } = useGranularityTranslations()\n\nconst props = withDefaults(defineProps<GrPaginationProps>(), {\n pageSizes: () => [10, 20, 50],\n})\n\nconst emit = defineEmits<{\n (e: 'update:page', value: number): void\n (e: 'update:pageSize', value: number): void\n}>()\n\nconst pageCount = computed(() => Math.max(1, Math.ceil(props.total / props.pageSize)))\n\nconst pageSizeModel = computed({\n get: () => String(props.pageSize),\n set: (value: string) => emit('update:pageSize', Number(value)),\n})\n\nconst pageSizeOptions = computed(() =>\n props.pageSizes.map(pageSize => ({\n value: String(pageSize),\n label: String(pageSize),\n })),\n)\n\nconst pages = computed(() => {\n const max = pageCount.value\n const current = props.page\n const windowSize = 5\n const half = Math.floor(windowSize / 2)\n\n let start = Math.max(1, current - half)\n const end = Math.min(max, start + windowSize - 1)\n start = Math.max(1, end - windowSize + 1)\n\n const list: number[] = []\n for (let page = start; page <= end; page += 1)\n list.push(page)\n\n return list\n})\n\nfunction goTo(page: number): void {\n emit('update:page', page)\n}\n\nfunction prev(): void {\n goTo(Math.max(1, props.page - 1))\n}\n\nfunction next(): void {\n goTo(Math.min(pageCount.value, props.page + 1))\n}\n</script>\n\n<template>\n <div\n class=\"flex flex-wrap items-center justify-end gap-3\"\n data-ds-pagination\n role=\"navigation\"\n :aria-label=\"t('gr.pagination.pageSize', 'Pagination')\"\n >\n <div class=\"min-w-[100px]\">\n <GrSelect\n v-model=\"pageSizeModel\"\n :options=\"pageSizeOptions\"\n :aria-label=\"t('gr.pagination.pageSize', 'Page size')\"\n />\n </div>\n\n <GrButton variant=\"ghost\" size=\"sm\" :disabled=\"page <= 1\" @click=\"prev\">\n {{ t('gr.pagination.prev', 'Prev') }}\n </GrButton>\n\n <div class=\"flex items-center gap-1\">\n <button\n v-for=\"pageNumber in pages\"\n :key=\"pageNumber\"\n type=\"button\"\n data-ds-pagination-page\n :aria-current=\"pageNumber === page ? 'page' : undefined\"\n :aria-label=\"`Page ${pageNumber}`\"\n class=\"h-8 min-w-8 px-2 rounded-md text-sm font-600 transition-colors duration-150 focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)]\"\n :class=\"pageNumber === page ? 'bg-[var(--primary)] text-[var(--primary-fg)]' : 'text-[var(--muted-fg)] hover:bg-[var(--muted)] hover:text-[var(--fg)]'\"\n @click=\"goTo(pageNumber)\"\n >\n {{ pageNumber }}\n </button>\n </div>\n\n <GrButton variant=\"ghost\" size=\"sm\" :disabled=\"page >= pageCount\" @click=\"next\">\n {{ t('gr.pagination.next', 'Next') }}\n </GrButton>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport GrButton from '../GrButton/GrButton.vue'\nimport GrSelect from '../GrSelect/GrSelect.vue'\n\n/**\n * Пропы пагинации.\n *\n * `total` интерпретируется как общее количество элементов; число страниц\n * вычисляется из `total` и `pageSize`. Окно отображаемых номеров — 5.\n */\nexport interface GrPaginationProps {\n page: number\n pageSize: number\n total: number\n pageSizes?: number[]\n}\n\nconst { t } = useGranularityTranslations()\n\nconst props = withDefaults(defineProps<GrPaginationProps>(), {\n pageSizes: () => [10, 20, 50],\n})\n\nconst emit = defineEmits<{\n (e: 'update:page', value: number): void\n (e: 'update:pageSize', value: number): void\n}>()\n\nconst pageCount = computed(() => Math.max(1, Math.ceil(props.total / props.pageSize)))\n\nconst pageSizeModel = computed({\n get: () => String(props.pageSize),\n set: (value: string) => emit('update:pageSize', Number(value)),\n})\n\nconst pageSizeOptions = computed(() =>\n props.pageSizes.map(pageSize => ({\n value: String(pageSize),\n label: String(pageSize),\n })),\n)\n\nconst pages = computed(() => {\n const max = pageCount.value\n const current = props.page\n const windowSize = 5\n const half = Math.floor(windowSize / 2)\n\n let start = Math.max(1, current - half)\n const end = Math.min(max, start + windowSize - 1)\n start = Math.max(1, end - windowSize + 1)\n\n const list: number[] = []\n for (let page = start; page <= end; page += 1)\n list.push(page)\n\n return list\n})\n\nfunction goTo(page: number): void {\n emit('update:page', page)\n}\n\nfunction prev(): void {\n goTo(Math.max(1, props.page - 1))\n}\n\nfunction next(): void {\n goTo(Math.min(pageCount.value, props.page + 1))\n}\n</script>\n\n<template>\n <div\n class=\"flex flex-wrap items-center justify-end gap-3\"\n data-ds-pagination\n role=\"navigation\"\n :aria-label=\"t('gr.pagination.pageSize', 'Pagination')\"\n >\n <div class=\"min-w-[100px]\">\n <GrSelect\n v-model=\"pageSizeModel\"\n :options=\"pageSizeOptions\"\n :aria-label=\"t('gr.pagination.pageSize', 'Page size')\"\n />\n </div>\n\n <GrButton variant=\"ghost\" size=\"sm\" :disabled=\"page <= 1\" @click=\"prev\">\n {{ t('gr.pagination.prev', 'Prev') }}\n </GrButton>\n\n <div class=\"flex items-center gap-1\">\n <button\n v-for=\"pageNumber in pages\"\n :key=\"pageNumber\"\n type=\"button\"\n data-ds-pagination-page\n :aria-current=\"pageNumber === page ? 'page' : undefined\"\n :aria-label=\"`Page ${pageNumber}`\"\n class=\"h-8 min-w-8 px-2 rounded-md text-sm font-600 transition-colors duration-150 focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)]\"\n :class=\"pageNumber === page ? 'bg-[var(--primary)] text-[var(--primary-fg)]' : 'text-[var(--muted-fg)] hover:bg-[var(--muted)] hover:text-[var(--fg)]'\"\n @click=\"goTo(pageNumber)\"\n >\n {{ pageNumber }}\n </button>\n </div>\n\n <GrButton variant=\"ghost\" size=\"sm\" :disabled=\"page >= pageCount\" @click=\"next\">\n {{ t('gr.pagination.next', 'Next') }}\n </GrButton>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoBA,MAAM,EAAE,MAAM,4BAA2B;EAEzC,MAAM,QAAQ;EAId,MAAM,OAAO;EAKb,MAAM,YAAY,eAAe,KAAK,IAAI,GAAG,KAAK,KAAK,MAAM,QAAQ,MAAM,SAAS,CAAC,CAAA;EAErF,MAAM,gBAAgB,SAAS;GAC7B,WAAW,OAAO,MAAM,SAAS;GACjC,MAAM,UAAkB,KAAK,mBAAmB,OAAO,MAAM,CAAC;GAC/D,CAAA;EAED,MAAM,kBAAkB,eACtB,MAAM,UAAU,KAAI,cAAa;GAC/B,OAAO,OAAO,SAAS;GACvB,OAAO,OAAO,SAAS;GACxB,EAAE,CACL;EAEA,MAAM,QAAQ,eAAe;GAC3B,MAAM,MAAM,UAAU;GACtB,MAAM,UAAU,MAAM;GACtB,MAAM,aAAa;GACnB,MAAM,OAAO,KAAK,MAAM,aAAa,EAAC;GAEtC,IAAI,QAAQ,KAAK,IAAI,GAAG,UAAU,KAAI;GACtC,MAAM,MAAM,KAAK,IAAI,KAAK,QAAQ,aAAa,EAAC;AAChD,WAAQ,KAAK,IAAI,GAAG,MAAM,aAAa,EAAC;GAExC,MAAM,OAAiB,EAAC;AACxB,QAAK,IAAI,OAAO,OAAO,QAAQ,KAAK,QAAQ,EAC1C,MAAK,KAAK,KAAI;AAEhB,UAAO;IACR;EAED,SAAS,KAAK,MAAoB;AAChC,QAAK,eAAe,KAAI;;EAG1B,SAAS,OAAa;AACpB,QAAK,KAAK,IAAI,GAAG,MAAM,OAAO,EAAE,CAAA;;EAGlC,SAAS,OAAa;AACpB,QAAK,KAAK,IAAI,UAAU,OAAO,MAAM,OAAO,EAAE,CAAA;;;uBAK9C,mBAqCM,OAAA;IApCJ,OAAM;IACN,sBAAA;IACA,MAAK;IACJ,cAAY,MAAA,EAAC,CAAA,0BAAA,aAAA;;IAEd,mBAMM,OANN,YAMM,CALJ,YAIE,kBAAA;iBAHS,cAAA;gFAAa,QAAA;KACrB,SAAS,gBAAA;KACT,cAAY,MAAA,EAAC,CAAA,0BAAA,YAAA;;;;;;IAIlB,YAEW,kBAAA;KAFD,SAAQ;KAAQ,MAAK;KAAM,UAAU,QAAA,QAAI;KAAQ,SAAO;;4BAC3B,CAAA,gBAAA,gBAAlC,MAAA,EAAC,CAAA,sBAAA,OAAA,CAAA,EAAA,EAAA,CAAA,CAAA;;;IAGN,mBAcM,OAdN,YAcM,EAAA,UAAA,KAAA,EAbJ,mBAYS,UAAA,MAAA,WAXc,MAAA,QAAd,eAAU;yBADnB,mBAYS,UAAA;MAVN,KAAK;MACN,MAAK;MACL,2BAAA;MACC,gBAAc,eAAe,QAAA,OAAI,SAAY,KAAA;MAC7C,cAAU,QAAU;MACrB,OAAK,eAAA,CAAC,wJACE,eAAe,QAAA,OAAI,iDAAA,wEAAA,CAAA;MAC1B,UAAK,WAAE,KAAK,WAAU;wBAEpB,WAAU,EAAA,IAAA,WAAA;;IAIjB,YAEW,kBAAA;KAFD,SAAQ;KAAQ,MAAK;KAAM,UAAU,QAAA,QAAQ,UAAA;KAAY,SAAO;;4BACnC,CAAA,gBAAA,gBAAlC,MAAA,EAAC,CAAA,sBAAA,OAAA,CAAA,EAAA,EAAA,CAAA,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"GrSelect-W9lbAjRZ.js","names":[],"sources":["../../../../src/components/GrSelect/GrSelect.vue","../../../../src/components/GrSelect/GrSelect.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, nextTick, onUnmounted, ref, watch } from 'vue'\n\nimport GrInput from '../GrInput/GrInput.vue'\nimport { vClickOutside } from '../../directives'\n\nimport {\n defaultBaseClass,\n grSelectLinkNativeLabelClass,\n grSelectLinkNativeOverlayClass,\n grSelectNativeClass,\n grSelectPanelClasses,\n grSelectTriggerClass,\n linkBaseClass,\n type GrSelectModelValue,\n type GrSelectOption,\n type GrSelectOptionsView,\n type GrSelectSize,\n type GrSelectUnderline,\n type GrSelectVariant,\n type GrSelectView,\n} from './grSelectStyles'\n\nexport type {\n GrSelectModelValue,\n GrSelectOption,\n GrSelectOptionsView,\n GrSelectSize,\n GrSelectUnderline,\n GrSelectVariant,\n GrSelectView,\n} from './grSelectStyles'\n\n/**\n * Пропсы публичного DS-примитива «Select».\n */\nexport interface GrSelectProps {\n modelValue: GrSelectModelValue\n options?: GrSelectOption[]\n disabled?: boolean\n ariaLabel?: string\n view?: GrSelectView\n size?: GrSelectSize\n /** Placeholder (показывается, когда значение не выбрано). */\n placeholder?: string\n /** Multiple selection. */\n multiple?: boolean\n /** Как отображать список опций: нативный `<select>` или кастомная панель. */\n optionsView?: GrSelectOptionsView\n /** Разрешает ввод/выбор значения, которого нет в `options`. */\n allowCustomValue?: boolean\n /** Placeholder для инпута кастомного значения (только в `optionsView=\"panel\"`). */\n customValuePlaceholder?: string\n /** Максимальная высота панели (только в `optionsView=\"panel\"`). */\n dropdownMaxHeight?: number\n /** Закрывать панель после выбора (только в `optionsView=\"panel\"`). */\n closeOnSelect?: boolean\n /** Разрешает очистку выбранного значения. */\n clearable?: boolean\n /** i18n-label для кнопки очистки (`aria-label`). */\n clearLabel?: string\n /**\n * Цвет/вариант ссылки для `view=\"link\"` (аналогично `GrLink`).\n * В `view=\"default\"` не используется.\n */\n variant?: GrSelectVariant\n /**\n * Подчёркивание для `view=\"link\"` (аналогично `GrLink`).\n * В `view=\"default\"` не используется.\n */\n underline?: GrSelectUnderline\n}\n\nconst props = withDefaults(\n defineProps<GrSelectProps>(),\n {\n options: undefined,\n disabled: false,\n ariaLabel: undefined,\n view: 'default',\n size: 'md',\n\n placeholder: undefined,\n multiple: false,\n\n optionsView: 'native',\n allowCustomValue: false,\n customValuePlaceholder: 'Add value…',\n dropdownMaxHeight: 280,\n closeOnSelect: true,\n clearable: false,\n clearLabel: 'Clear',\n variant: 'primary',\n underline: 'auto',\n },\n)\n\nconst baseClassName = computed(() => props.view === 'link' ? linkBaseClass : defaultBaseClass)\n\nconst rootClass = computed(() => props.view === 'link' ? 'relative inline-block align-baseline' : 'relative w-full')\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: GrSelectModelValue): void\n}>()\n\nconst optionsResolved = computed(() => props.options ?? [])\n\nfunction modelToArray(value: GrSelectModelValue): string[] {\n if (Array.isArray(value)) return value\n if (!value) return []\n return [value]\n}\n\nconst modelSingle = computed(() => {\n return Array.isArray(props.modelValue) ? (props.modelValue[0] ?? '') : props.modelValue\n})\n\nconst modelMultiple = computed(() => modelToArray(props.modelValue))\n\nconst selectedValues = computed(() => {\n return props.multiple ? modelMultiple.value : (modelSingle.value ? [modelSingle.value] : [])\n})\n\nconst hasSelection = computed(() => selectedValues.value.length > 0)\n\nconst selectedOptions = computed<GrSelectOption[]>(() => {\n const byValue = new Map(optionsResolved.value.map(o => [o.value, o]))\n return selectedValues.value.map((v) => byValue.get(v) ?? { value: v, label: v })\n})\n\nconst hasModelInOptions = computed(() => {\n if (props.multiple) return false\n return optionsResolved.value.some((o) => o.value === modelSingle.value)\n})\n\nconst displayLabel = computed(() => {\n if (props.multiple) {\n if (!selectedValues.value.length) return ''\n return selectedValues.value\n .map((v) => optionsResolved.value.find((o) => o.value === v)?.label ?? v)\n .join(', ')\n }\n\n return optionsResolved.value.find((o) => o.value === modelSingle.value)?.label ?? modelSingle.value\n})\n\nconst displayText = computed(() => {\n if (hasSelection.value) return displayLabel.value\n return props.placeholder ?? ''\n})\n\nconst nativeCustomOptionVisible = computed(() => {\n if (!props.allowCustomValue) return false\n if (props.optionsView !== 'native') return false\n if (props.multiple) return false\n if (!props.options) return false\n if (modelSingle.value === '') return false\n return !hasModelInOptions.value\n})\n\nconst customValue = ref('')\nconst open = ref(false)\nconst rootEl = ref<HTMLElement | null>(null)\nconst panelEl = ref<HTMLElement | null>(null)\nconst customInputRef = ref<InstanceType<typeof GrInput> | null>(null)\nconst clickOutsideExclude = [() => panelEl.value]\nconst panelStyle = ref<Record<string, string>>({\n left: '0px',\n top: '0px',\n width: '0px',\n zIndex: '2147483647',\n})\n\nfunction syncPanelPosition(): void {\n if (typeof window === 'undefined') return\n\n const root = rootEl.value\n if (!root) return\n\n const rect = root.getBoundingClientRect()\n\n // Для `view='link'` ширина триггера = ширине выбранной опции (`inline-block w-auto`),\n // и без отдельной обработки панель тоже становилась шириной выбранной опции, из-за чего\n // её размер «прыгал» при выборе разных опций. Решение — отдать вычисление ширины браузеру:\n // `width: max-content` (по самому длинному ребёнку — `w-full`-кнопкам с `whitespace-nowrap`),\n // `min-width` равной ширине триггера (чтобы панель не была уже самого триггера).\n // Это чисто CSS-подход — без JS-замеров и ResizeObserver, максимально перформантный.\n if (props.view === 'link') {\n panelStyle.value = {\n left: `${rect.left}px`,\n top: `${rect.bottom + 8}px`,\n width: 'max-content',\n minWidth: `${rect.width}px`,\n zIndex: '2147483647',\n }\n return\n }\n\n panelStyle.value = {\n left: `${rect.left}px`,\n top: `${rect.bottom + 8}px`,\n width: `${rect.width}px`,\n zIndex: '2147483647',\n }\n}\n\nfunction bindPanelPositionListeners(): void {\n if (typeof window === 'undefined') return\n window.addEventListener('resize', syncPanelPosition)\n window.addEventListener('scroll', syncPanelPosition, true)\n}\n\nfunction unbindPanelPositionListeners(): void {\n if (typeof window === 'undefined') return\n window.removeEventListener('resize', syncPanelPosition)\n window.removeEventListener('scroll', syncPanelPosition, true)\n}\n\nfunction closeDropdown(): void {\n open.value = false\n}\n\nfunction toggleDropdown(): void {\n if (props.disabled) return\n open.value = !open.value\n}\n\nfunction closeOnEscape(e: KeyboardEvent): void {\n if (e.key === 'Escape') closeDropdown()\n}\n\nwatch(\n open,\n async (isOpen) => {\n if (typeof document === 'undefined') return\n\n document.removeEventListener('keydown', closeOnEscape)\n unbindPanelPositionListeners()\n\n if (isOpen) document.addEventListener('keydown', closeOnEscape)\n\n if (!isOpen) {\n customValue.value = ''\n return\n }\n\n bindPanelPositionListeners()\n await nextTick()\n syncPanelPosition()\n\n if (props.allowCustomValue) {\n customInputRef.value?.focus()\n }\n },\n { immediate: true },\n)\n\nonUnmounted(() => {\n if (typeof document === 'undefined') return\n document.removeEventListener('keydown', closeOnEscape)\n unbindPanelPositionListeners()\n})\n\nconst panelClasses = computed(() => {\n return grSelectPanelClasses\n})\n\nconst visibleOptions = computed(() => {\n const base = optionsResolved.value\n\n const withCustom = (() => {\n if (!props.allowCustomValue) return base\n if (props.multiple) return base\n if (modelSingle.value === '') return base\n if (hasModelInOptions.value) return base\n return [{ value: modelSingle.value, label: modelSingle.value }, ...base]\n })()\n\n if (!props.allowCustomValue) return withCustom\n\n const q = customValue.value.trim().toLowerCase()\n if (!q) return withCustom\n\n return withCustom.filter((o) => {\n return o.label.toLowerCase().includes(q) || o.value.toLowerCase().includes(q)\n })\n})\n\nconst canAddCustom = computed(() => {\n if (!props.allowCustomValue) return false\n if (props.optionsView !== 'panel') return false\n const v = customValue.value.trim()\n if (!v) return false\n\n if (props.multiple) {\n if (selectedValues.value.includes(v)) return false\n return !optionsResolved.value.some((o) => o.value === v)\n }\n\n if (v === modelSingle.value) return false\n return !optionsResolved.value.some((o) => o.value === v)\n})\n\nfunction emitValue(value: GrSelectModelValue): void {\n emit('update:modelValue', value)\n}\n\nfunction isSelected(value: string): boolean {\n return selectedValues.value.includes(value)\n}\n\nfunction selectValue(value: string): void {\n emitValue(value)\n if (props.closeOnSelect) {\n closeDropdown()\n }\n}\n\nfunction toggleValue(value: string): void {\n if (!props.multiple) {\n selectValue(value)\n return\n }\n\n const next = selectedValues.value.slice()\n const idx = next.indexOf(value)\n if (idx >= 0) {\n next.splice(idx, 1)\n }\n else {\n next.push(value)\n }\n\n emitValue(next)\n if (props.closeOnSelect) {\n closeDropdown()\n }\n}\n\nfunction addCustom(): void {\n const v = customValue.value.trim()\n if (!v) return\n toggleValue(v)\n}\n\nconst showNativeChevron = computed(() => {\n return props.optionsView === 'native' && props.view !== 'link' && !props.multiple\n})\n\nconst nativeClearOptionVisible = computed(() => {\n if (!props.clearable) return false\n if (props.optionsView !== 'native') return false\n if (props.multiple) return false\n if (!props.options) return true\n return !props.options.some(o => o.value === '')\n})\n\nconst panelClearVisible = computed(() => {\n if (!props.clearable) return false\n if (props.optionsView !== 'panel') return false\n if (props.view === 'link') return false\n return hasSelection.value\n})\n\nconst nativeClassName = computed(() => {\n return grSelectNativeClass({\n view: props.view,\n size: props.size,\n disabled: props.disabled,\n variant: props.variant,\n underline: props.underline,\n showNativeChevron: showNativeChevron.value,\n })\n})\n\n/**\n * `view=\"link\"` в native-режиме: ширина обёртки должна определяться выбранной опцией,\n * а не самой длинной (как делает браузер по умолчанию). Поэтому рендерим прозрачный\n * `<select>`-overlay поверх видимого `<span>` с меткой — overlay принимает клики/клавиатуру,\n * span задаёт ширину компонента в закрытом состоянии.\n */\nconst isLinkNative = computed(() => props.view === 'link' && props.optionsView === 'native')\n\nconst linkNativeLabelClassName = computed(() => grSelectLinkNativeLabelClass({\n size: props.size,\n variant: props.variant,\n underline: props.underline,\n disabled: props.disabled,\n}))\n\nconst linkNativeDisplayText = computed(() => {\n return displayText.value || props.placeholder || '\\u00A0'\n})\n\nconst triggerClassName = computed(() => {\n return grSelectTriggerClass({\n view: props.view,\n optionsView: props.optionsView,\n size: props.size,\n disabled: props.disabled,\n variant: props.variant,\n underline: props.underline,\n })\n})\n\nfunction onChange(e: Event): void {\n const el = e.target as HTMLSelectElement\n\n if (props.multiple) {\n const values = Array.from(el.selectedOptions, o => o.value)\n emit('update:modelValue', values)\n return\n }\n\n emit('update:modelValue', el.value)\n}\n\nfunction clearSelection(): void {\n if (props.disabled) return\n emitValue(props.multiple ? [] : '')\n}\n</script>\n\n<template>\n <div\n v-if=\"optionsView === 'native'\"\n data-ds-select\n :class=\"rootClass\"\n >\n <select\n data-ds-select-native\n :value=\"multiple ? modelMultiple : modelSingle\"\n :multiple=\"multiple\"\n :disabled=\"disabled\"\n :aria-label=\"ariaLabel\"\n :class=\"isLinkNative ? grSelectLinkNativeOverlayClass : [baseClassName, nativeClassName]\"\n @change=\"onChange\"\n >\n <option v-if=\"nativeClearOptionVisible\" value=\"\" />\n\n <slot>\n <option v-if=\"nativeCustomOptionVisible\" :value=\"modelSingle\">\n {{ modelSingle }}\n </option>\n <option v-for=\"opt in options\" :key=\"opt.value\" :value=\"opt.value\">\n {{ opt.label }}\n </option>\n </slot>\n </select>\n\n <span\n v-if=\"isLinkNative\"\n data-ds-select-link-label\n aria-hidden=\"true\"\n :class=\"linkNativeLabelClassName\"\n >{{ linkNativeDisplayText }}</span>\n\n <span\n v-if=\"showNativeChevron\"\n data-testid=\"ds-select-chevron\"\n class=\"absolute top-1/2 -translate-y-1/2 right-3 text-[var(--muted-fg)] pointer-events-none\"\n >\n <span class=\"i-lucide-chevron-down inline-block h-4 w-4\" aria-hidden=\"true\" />\n </span>\n </div>\n\n <div\n v-else\n ref=\"rootEl\"\n v-click-outside=\"{ handler: closeDropdown, enabled: open, exclude: clickOutsideExclude }\"\n data-ds-select\n :class=\"rootClass\"\n >\n <button\n data-testid=\"ds-select-trigger\"\n data-ds-select-trigger\n type=\"button\"\n :disabled=\"disabled\"\n :aria-label=\"ariaLabel\"\n role=\"combobox\"\n aria-readonly=\"true\"\n :aria-expanded=\"open ? 'true' : 'false'\"\n :class=\"[baseClassName, triggerClassName]\"\n @click=\"toggleDropdown\"\n >\n <span class=\"min-w-0 flex-1\">\n <slot\n name=\"value\"\n :selected-options=\"selectedOptions\"\n :selected-values=\"selectedValues\"\n :display-label=\"displayLabel\"\n :placeholder=\"placeholder\"\n :has-selection=\"hasSelection\"\n >\n <span\n class=\"block truncate\"\n :class=\"!hasSelection ? 'text-[var(--muted-fg)]' : ''\"\n >\n {{ displayText }}\n </span>\n </slot>\n </span>\n\n <span\n v-if=\"panelClearVisible\"\n class=\"shrink-0 h-4 w-4\"\n aria-hidden=\"true\"\n />\n\n <span\n v-else\n data-testid=\"ds-select-chevron\"\n class=\"shrink-0 text-[var(--muted-fg)] pointer-events-none\"\n >\n <span class=\"i-lucide-chevron-down inline-block h-4 w-4\" aria-hidden=\"true\" />\n </span>\n </button>\n\n <button\n v-if=\"panelClearVisible\"\n data-testid=\"ds-select-clear\"\n data-ds-select-clear\n type=\"button\"\n class=\"absolute top-1/2 -translate-y-1/2 right-3 h-6 w-6 inline-flex items-center justify-center rounded-md text-[var(--muted-fg)] hover:text-[var(--fg)] hover:bg-[color-mix(in_srgb,var(--muted)_25%,transparent)] disabled:opacity-50\"\n :disabled=\"disabled\"\n :aria-label=\"clearLabel\"\n @click.stop=\"clearSelection\"\n >\n <span class=\"i-lucide-x inline-block h-4 w-4\" aria-hidden=\"true\" />\n </button>\n\n <teleport to=\"body\">\n <transition\n enter-active-class=\"transition ease-out duration-150\"\n enter-from-class=\"transform opacity-0 scale-95\"\n enter-to-class=\"transform opacity-100 scale-100\"\n leave-active-class=\"transition ease-in duration-100\"\n leave-from-class=\"transform opacity-100 scale-100\"\n leave-to-class=\"transform opacity-0 scale-95\"\n >\n <div\n v-show=\"open\"\n ref=\"panelEl\"\n data-testid=\"ds-select-panel\"\n data-ds-select-panel\n class=\"fixed w-full\"\n :style=\"panelStyle\"\n >\n <div :class=\"panelClasses\">\n <div v-if=\"allowCustomValue\" class=\"p-2 border-b border-[var(--brd)]\">\n <GrInput\n ref=\"customInputRef\"\n v-model=\"customValue\"\n data-testid=\"ds-select-custom-input\"\n type=\"text\"\n :placeholder=\"customValuePlaceholder\"\n size=\"sm\"\n @keydown.enter.prevent=\"addCustom\"\n />\n </div>\n\n <div\n data-ds-select-listbox\n class=\"p-1 overflow-auto\"\n :style=\"{ maxHeight: `${dropdownMaxHeight}px` }\"\n role=\"listbox\"\n :aria-multiselectable=\"multiple ? 'true' : undefined\"\n >\n <button\n v-if=\"canAddCustom\"\n data-testid=\"ds-select-add-option\"\n data-ds-select-add-option\n type=\"button\"\n class=\"rounded-[10px] px-3 py-2 text-left text-[13px] hover:bg-[color-mix(in_srgb,var(--muted)_30%,transparent)]\" :class=\"[\n view === 'link' ? 'block min-w-full w-max whitespace-nowrap' : 'w-full',\n ]\"\n @click=\"addCustom\"\n >\n Add “{{ customValue.trim() }}”\n </button>\n\n <button\n v-for=\"opt in visibleOptions\"\n :key=\"opt.value\"\n data-ds-select-option\n type=\"button\"\n role=\"option\"\n :aria-selected=\"isSelected(opt.value) ? 'true' : 'false'\"\n class=\"rounded-[10px] px-3 py-2 text-left text-[13px] hover:bg-[color-mix(in_srgb,var(--muted)_30%,transparent)]\" :class=\"[\n view === 'link' ? 'block min-w-full w-max whitespace-nowrap' : 'w-full',\n ]\"\n @click=\"toggleValue(opt.value)\"\n >\n <slot name=\"option\" :option=\"opt\" :selected=\"isSelected(opt.value)\">\n <span class=\"flex items-center gap-2 min-w-0\">\n <span\n class=\"inline-block h-4 w-4 shrink-0\"\n :class=\"isSelected(opt.value) ? 'i-lucide-check text-[var(--primary)]' : ''\"\n aria-hidden=\"true\"\n />\n <span class=\"truncate\">{{ opt.label }}</span>\n </span>\n </slot>\n </button>\n </div>\n </div>\n </div>\n </transition>\n </teleport>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, nextTick, onUnmounted, ref, watch } from 'vue'\n\nimport GrInput from '../GrInput/GrInput.vue'\nimport { vClickOutside } from '../../directives'\n\nimport {\n defaultBaseClass,\n grSelectLinkNativeLabelClass,\n grSelectLinkNativeOverlayClass,\n grSelectNativeClass,\n grSelectPanelClasses,\n grSelectTriggerClass,\n linkBaseClass,\n type GrSelectModelValue,\n type GrSelectOption,\n type GrSelectOptionsView,\n type GrSelectSize,\n type GrSelectUnderline,\n type GrSelectVariant,\n type GrSelectView,\n} from './grSelectStyles'\n\nexport type {\n GrSelectModelValue,\n GrSelectOption,\n GrSelectOptionsView,\n GrSelectSize,\n GrSelectUnderline,\n GrSelectVariant,\n GrSelectView,\n} from './grSelectStyles'\n\n/**\n * Пропсы публичного DS-примитива «Select».\n */\nexport interface GrSelectProps {\n modelValue: GrSelectModelValue\n options?: GrSelectOption[]\n disabled?: boolean\n ariaLabel?: string\n view?: GrSelectView\n size?: GrSelectSize\n /** Placeholder (показывается, когда значение не выбрано). */\n placeholder?: string\n /** Multiple selection. */\n multiple?: boolean\n /** Как отображать список опций: нативный `<select>` или кастомная панель. */\n optionsView?: GrSelectOptionsView\n /** Разрешает ввод/выбор значения, которого нет в `options`. */\n allowCustomValue?: boolean\n /** Placeholder для инпута кастомного значения (только в `optionsView=\"panel\"`). */\n customValuePlaceholder?: string\n /** Максимальная высота панели (только в `optionsView=\"panel\"`). */\n dropdownMaxHeight?: number\n /** Закрывать панель после выбора (только в `optionsView=\"panel\"`). */\n closeOnSelect?: boolean\n /** Разрешает очистку выбранного значения. */\n clearable?: boolean\n /** i18n-label для кнопки очистки (`aria-label`). */\n clearLabel?: string\n /**\n * Цвет/вариант ссылки для `view=\"link\"` (аналогично `GrLink`).\n * В `view=\"default\"` не используется.\n */\n variant?: GrSelectVariant\n /**\n * Подчёркивание для `view=\"link\"` (аналогично `GrLink`).\n * В `view=\"default\"` не используется.\n */\n underline?: GrSelectUnderline\n}\n\nconst props = withDefaults(\n defineProps<GrSelectProps>(),\n {\n options: undefined,\n disabled: false,\n ariaLabel: undefined,\n view: 'default',\n size: 'md',\n\n placeholder: undefined,\n multiple: false,\n\n optionsView: 'native',\n allowCustomValue: false,\n customValuePlaceholder: 'Add value…',\n dropdownMaxHeight: 280,\n closeOnSelect: true,\n clearable: false,\n clearLabel: 'Clear',\n variant: 'primary',\n underline: 'auto',\n },\n)\n\nconst baseClassName = computed(() => props.view === 'link' ? linkBaseClass : defaultBaseClass)\n\nconst rootClass = computed(() => props.view === 'link' ? 'relative inline-block align-baseline' : 'relative w-full')\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: GrSelectModelValue): void\n}>()\n\nconst optionsResolved = computed(() => props.options ?? [])\n\nfunction modelToArray(value: GrSelectModelValue): string[] {\n if (Array.isArray(value)) return value\n if (!value) return []\n return [value]\n}\n\nconst modelSingle = computed(() => {\n return Array.isArray(props.modelValue) ? (props.modelValue[0] ?? '') : props.modelValue\n})\n\nconst modelMultiple = computed(() => modelToArray(props.modelValue))\n\nconst selectedValues = computed(() => {\n return props.multiple ? modelMultiple.value : (modelSingle.value ? [modelSingle.value] : [])\n})\n\nconst hasSelection = computed(() => selectedValues.value.length > 0)\n\nconst selectedOptions = computed<GrSelectOption[]>(() => {\n const byValue = new Map(optionsResolved.value.map(o => [o.value, o]))\n return selectedValues.value.map((v) => byValue.get(v) ?? { value: v, label: v })\n})\n\nconst hasModelInOptions = computed(() => {\n if (props.multiple) return false\n return optionsResolved.value.some((o) => o.value === modelSingle.value)\n})\n\nconst displayLabel = computed(() => {\n if (props.multiple) {\n if (!selectedValues.value.length) return ''\n return selectedValues.value\n .map((v) => optionsResolved.value.find((o) => o.value === v)?.label ?? v)\n .join(', ')\n }\n\n return optionsResolved.value.find((o) => o.value === modelSingle.value)?.label ?? modelSingle.value\n})\n\nconst displayText = computed(() => {\n if (hasSelection.value) return displayLabel.value\n return props.placeholder ?? ''\n})\n\nconst nativeCustomOptionVisible = computed(() => {\n if (!props.allowCustomValue) return false\n if (props.optionsView !== 'native') return false\n if (props.multiple) return false\n if (!props.options) return false\n if (modelSingle.value === '') return false\n return !hasModelInOptions.value\n})\n\nconst customValue = ref('')\nconst open = ref(false)\nconst rootEl = ref<HTMLElement | null>(null)\nconst panelEl = ref<HTMLElement | null>(null)\nconst customInputRef = ref<InstanceType<typeof GrInput> | null>(null)\nconst clickOutsideExclude = [() => panelEl.value]\nconst panelStyle = ref<Record<string, string>>({\n left: '0px',\n top: '0px',\n width: '0px',\n zIndex: '2147483647',\n})\n\nfunction syncPanelPosition(): void {\n if (typeof window === 'undefined') return\n\n const root = rootEl.value\n if (!root) return\n\n const rect = root.getBoundingClientRect()\n\n // Для `view='link'` ширина триггера = ширине выбранной опции (`inline-block w-auto`),\n // и без отдельной обработки панель тоже становилась шириной выбранной опции, из-за чего\n // её размер «прыгал» при выборе разных опций. Решение — отдать вычисление ширины браузеру:\n // `width: max-content` (по самому длинному ребёнку — `w-full`-кнопкам с `whitespace-nowrap`),\n // `min-width` равной ширине триггера (чтобы панель не была уже самого триггера).\n // Это чисто CSS-подход — без JS-замеров и ResizeObserver, максимально перформантный.\n if (props.view === 'link') {\n panelStyle.value = {\n left: `${rect.left}px`,\n top: `${rect.bottom + 8}px`,\n width: 'max-content',\n minWidth: `${rect.width}px`,\n zIndex: '2147483647',\n }\n return\n }\n\n panelStyle.value = {\n left: `${rect.left}px`,\n top: `${rect.bottom + 8}px`,\n width: `${rect.width}px`,\n zIndex: '2147483647',\n }\n}\n\nfunction bindPanelPositionListeners(): void {\n if (typeof window === 'undefined') return\n window.addEventListener('resize', syncPanelPosition)\n window.addEventListener('scroll', syncPanelPosition, true)\n}\n\nfunction unbindPanelPositionListeners(): void {\n if (typeof window === 'undefined') return\n window.removeEventListener('resize', syncPanelPosition)\n window.removeEventListener('scroll', syncPanelPosition, true)\n}\n\nfunction closeDropdown(): void {\n open.value = false\n}\n\nfunction toggleDropdown(): void {\n if (props.disabled) return\n open.value = !open.value\n}\n\nfunction closeOnEscape(e: KeyboardEvent): void {\n if (e.key === 'Escape') closeDropdown()\n}\n\nwatch(\n open,\n async (isOpen) => {\n if (typeof document === 'undefined') return\n\n document.removeEventListener('keydown', closeOnEscape)\n unbindPanelPositionListeners()\n\n if (isOpen) document.addEventListener('keydown', closeOnEscape)\n\n if (!isOpen) {\n customValue.value = ''\n return\n }\n\n bindPanelPositionListeners()\n await nextTick()\n syncPanelPosition()\n\n if (props.allowCustomValue) {\n customInputRef.value?.focus()\n }\n },\n { immediate: true },\n)\n\nonUnmounted(() => {\n if (typeof document === 'undefined') return\n document.removeEventListener('keydown', closeOnEscape)\n unbindPanelPositionListeners()\n})\n\nconst panelClasses = computed(() => {\n return grSelectPanelClasses\n})\n\nconst visibleOptions = computed(() => {\n const base = optionsResolved.value\n\n const withCustom = (() => {\n if (!props.allowCustomValue) return base\n if (props.multiple) return base\n if (modelSingle.value === '') return base\n if (hasModelInOptions.value) return base\n return [{ value: modelSingle.value, label: modelSingle.value }, ...base]\n })()\n\n if (!props.allowCustomValue) return withCustom\n\n const q = customValue.value.trim().toLowerCase()\n if (!q) return withCustom\n\n return withCustom.filter((o) => {\n return o.label.toLowerCase().includes(q) || o.value.toLowerCase().includes(q)\n })\n})\n\nconst canAddCustom = computed(() => {\n if (!props.allowCustomValue) return false\n if (props.optionsView !== 'panel') return false\n const v = customValue.value.trim()\n if (!v) return false\n\n if (props.multiple) {\n if (selectedValues.value.includes(v)) return false\n return !optionsResolved.value.some((o) => o.value === v)\n }\n\n if (v === modelSingle.value) return false\n return !optionsResolved.value.some((o) => o.value === v)\n})\n\nfunction emitValue(value: GrSelectModelValue): void {\n emit('update:modelValue', value)\n}\n\nfunction isSelected(value: string): boolean {\n return selectedValues.value.includes(value)\n}\n\nfunction selectValue(value: string): void {\n emitValue(value)\n if (props.closeOnSelect) {\n closeDropdown()\n }\n}\n\nfunction toggleValue(value: string): void {\n if (!props.multiple) {\n selectValue(value)\n return\n }\n\n const next = selectedValues.value.slice()\n const idx = next.indexOf(value)\n if (idx >= 0) {\n next.splice(idx, 1)\n }\n else {\n next.push(value)\n }\n\n emitValue(next)\n if (props.closeOnSelect) {\n closeDropdown()\n }\n}\n\nfunction addCustom(): void {\n const v = customValue.value.trim()\n if (!v) return\n toggleValue(v)\n}\n\nconst showNativeChevron = computed(() => {\n return props.optionsView === 'native' && props.view !== 'link' && !props.multiple\n})\n\nconst nativeClearOptionVisible = computed(() => {\n if (!props.clearable) return false\n if (props.optionsView !== 'native') return false\n if (props.multiple) return false\n if (!props.options) return true\n return !props.options.some(o => o.value === '')\n})\n\nconst panelClearVisible = computed(() => {\n if (!props.clearable) return false\n if (props.optionsView !== 'panel') return false\n if (props.view === 'link') return false\n return hasSelection.value\n})\n\nconst nativeClassName = computed(() => {\n return grSelectNativeClass({\n view: props.view,\n size: props.size,\n disabled: props.disabled,\n variant: props.variant,\n underline: props.underline,\n showNativeChevron: showNativeChevron.value,\n })\n})\n\n/**\n * `view=\"link\"` в native-режиме: ширина обёртки должна определяться выбранной опцией,\n * а не самой длинной (как делает браузер по умолчанию). Поэтому рендерим прозрачный\n * `<select>`-overlay поверх видимого `<span>` с меткой — overlay принимает клики/клавиатуру,\n * span задаёт ширину компонента в закрытом состоянии.\n */\nconst isLinkNative = computed(() => props.view === 'link' && props.optionsView === 'native')\n\nconst linkNativeLabelClassName = computed(() => grSelectLinkNativeLabelClass({\n size: props.size,\n variant: props.variant,\n underline: props.underline,\n disabled: props.disabled,\n}))\n\nconst linkNativeDisplayText = computed(() => {\n return displayText.value || props.placeholder || '\\u00A0'\n})\n\nconst triggerClassName = computed(() => {\n return grSelectTriggerClass({\n view: props.view,\n optionsView: props.optionsView,\n size: props.size,\n disabled: props.disabled,\n variant: props.variant,\n underline: props.underline,\n })\n})\n\nfunction onChange(e: Event): void {\n const el = e.target as HTMLSelectElement\n\n if (props.multiple) {\n const values = Array.from(el.selectedOptions, o => o.value)\n emit('update:modelValue', values)\n return\n }\n\n emit('update:modelValue', el.value)\n}\n\nfunction clearSelection(): void {\n if (props.disabled) return\n emitValue(props.multiple ? [] : '')\n}\n</script>\n\n<template>\n <div\n v-if=\"optionsView === 'native'\"\n data-ds-select\n :class=\"rootClass\"\n >\n <select\n data-ds-select-native\n :value=\"multiple ? modelMultiple : modelSingle\"\n :multiple=\"multiple\"\n :disabled=\"disabled\"\n :aria-label=\"ariaLabel\"\n :class=\"isLinkNative ? grSelectLinkNativeOverlayClass : [baseClassName, nativeClassName]\"\n @change=\"onChange\"\n >\n <option v-if=\"nativeClearOptionVisible\" value=\"\" />\n\n <slot>\n <option v-if=\"nativeCustomOptionVisible\" :value=\"modelSingle\">\n {{ modelSingle }}\n </option>\n <option v-for=\"opt in options\" :key=\"opt.value\" :value=\"opt.value\">\n {{ opt.label }}\n </option>\n </slot>\n </select>\n\n <span\n v-if=\"isLinkNative\"\n data-ds-select-link-label\n aria-hidden=\"true\"\n :class=\"linkNativeLabelClassName\"\n >{{ linkNativeDisplayText }}</span>\n\n <span\n v-if=\"showNativeChevron\"\n data-testid=\"ds-select-chevron\"\n class=\"absolute top-1/2 -translate-y-1/2 right-3 text-[var(--muted-fg)] pointer-events-none\"\n >\n <span class=\"i-lucide-chevron-down inline-block h-4 w-4\" aria-hidden=\"true\" />\n </span>\n </div>\n\n <div\n v-else\n ref=\"rootEl\"\n v-click-outside=\"{ handler: closeDropdown, enabled: open, exclude: clickOutsideExclude }\"\n data-ds-select\n :class=\"rootClass\"\n >\n <button\n data-testid=\"ds-select-trigger\"\n data-ds-select-trigger\n type=\"button\"\n :disabled=\"disabled\"\n :aria-label=\"ariaLabel\"\n role=\"combobox\"\n aria-readonly=\"true\"\n :aria-expanded=\"open ? 'true' : 'false'\"\n :class=\"[baseClassName, triggerClassName]\"\n @click=\"toggleDropdown\"\n >\n <span class=\"min-w-0 flex-1\">\n <slot\n name=\"value\"\n :selected-options=\"selectedOptions\"\n :selected-values=\"selectedValues\"\n :display-label=\"displayLabel\"\n :placeholder=\"placeholder\"\n :has-selection=\"hasSelection\"\n >\n <span\n class=\"block truncate\"\n :class=\"!hasSelection ? 'text-[var(--muted-fg)]' : ''\"\n >\n {{ displayText }}\n </span>\n </slot>\n </span>\n\n <span\n v-if=\"panelClearVisible\"\n class=\"shrink-0 h-4 w-4\"\n aria-hidden=\"true\"\n />\n\n <span\n v-else\n data-testid=\"ds-select-chevron\"\n class=\"shrink-0 text-[var(--muted-fg)] pointer-events-none\"\n >\n <span class=\"i-lucide-chevron-down inline-block h-4 w-4\" aria-hidden=\"true\" />\n </span>\n </button>\n\n <button\n v-if=\"panelClearVisible\"\n data-testid=\"ds-select-clear\"\n data-ds-select-clear\n type=\"button\"\n class=\"absolute top-1/2 -translate-y-1/2 right-3 h-6 w-6 inline-flex items-center justify-center rounded-md text-[var(--muted-fg)] hover:text-[var(--fg)] hover:bg-[color-mix(in_srgb,var(--muted)_25%,transparent)] disabled:opacity-50\"\n :disabled=\"disabled\"\n :aria-label=\"clearLabel\"\n @click.stop=\"clearSelection\"\n >\n <span class=\"i-lucide-x inline-block h-4 w-4\" aria-hidden=\"true\" />\n </button>\n\n <teleport to=\"body\">\n <transition\n enter-active-class=\"transition ease-out duration-150\"\n enter-from-class=\"transform opacity-0 scale-95\"\n enter-to-class=\"transform opacity-100 scale-100\"\n leave-active-class=\"transition ease-in duration-100\"\n leave-from-class=\"transform opacity-100 scale-100\"\n leave-to-class=\"transform opacity-0 scale-95\"\n >\n <div\n v-show=\"open\"\n ref=\"panelEl\"\n data-testid=\"ds-select-panel\"\n data-ds-select-panel\n class=\"fixed w-full\"\n :style=\"panelStyle\"\n >\n <div :class=\"panelClasses\">\n <div v-if=\"allowCustomValue\" class=\"p-2 border-b border-[var(--brd)]\">\n <GrInput\n ref=\"customInputRef\"\n v-model=\"customValue\"\n data-testid=\"ds-select-custom-input\"\n type=\"text\"\n :placeholder=\"customValuePlaceholder\"\n size=\"sm\"\n @keydown.enter.prevent=\"addCustom\"\n />\n </div>\n\n <div\n data-ds-select-listbox\n class=\"p-1 overflow-auto\"\n :style=\"{ maxHeight: `${dropdownMaxHeight}px` }\"\n role=\"listbox\"\n :aria-multiselectable=\"multiple ? 'true' : undefined\"\n >\n <button\n v-if=\"canAddCustom\"\n data-testid=\"ds-select-add-option\"\n data-ds-select-add-option\n type=\"button\"\n class=\"rounded-[10px] px-3 py-2 text-left text-[13px] hover:bg-[color-mix(in_srgb,var(--muted)_30%,transparent)]\" :class=\"[\n view === 'link' ? 'block min-w-full w-max whitespace-nowrap' : 'w-full',\n ]\"\n @click=\"addCustom\"\n >\n Add “{{ customValue.trim() }}”\n </button>\n\n <button\n v-for=\"opt in visibleOptions\"\n :key=\"opt.value\"\n data-ds-select-option\n type=\"button\"\n role=\"option\"\n :aria-selected=\"isSelected(opt.value) ? 'true' : 'false'\"\n class=\"rounded-[10px] px-3 py-2 text-left text-[13px] hover:bg-[color-mix(in_srgb,var(--muted)_30%,transparent)]\" :class=\"[\n view === 'link' ? 'block min-w-full w-max whitespace-nowrap' : 'w-full',\n ]\"\n @click=\"toggleValue(opt.value)\"\n >\n <slot name=\"option\" :option=\"opt\" :selected=\"isSelected(opt.value)\">\n <span class=\"flex items-center gap-2 min-w-0\">\n <span\n class=\"inline-block h-4 w-4 shrink-0\"\n :class=\"isSelected(opt.value) ? 'i-lucide-check text-[var(--primary)]' : ''\"\n aria-hidden=\"true\"\n />\n <span class=\"truncate\">{{ opt.label }}</span>\n </span>\n </slot>\n </button>\n </div>\n </div>\n </div>\n </transition>\n </teleport>\n </div>\n</template>\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"GrToaster-DluJmR5D.js","names":[],"sources":["../../../../src/components/GrToaster/GrToaster.vue","../../../../src/components/GrToaster/GrToaster.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * GrToaster — DS-примитив области уведомлений (toast).\n *\n * Модель состояния берётся из `useToast` (модульный синглтон), поэтому\n * в приложении предполагается **один активный `GrToaster`** на корень.\n *\n * A11y:\n * - контейнер — `role=\"region\"` с `aria-label` (i18n-проп `regionLabel`);\n * - каждый toast — `role=\"status\"` + `aria-live=\"polite\"` для `info`/`success`\n * и `role=\"alert\"` + `aria-live=\"assertive\"` для `warning`/`danger`\n * (критичные сообщения должны прерывать скринридер).\n *\n * UX:\n * - появление/исчезновение анимируется `TransitionGroup`;\n * - `placement` настраивает угол экрана;\n * - `z-[60]` — выше, чем `GrModal` (`z-50`), чтобы уведомления не перекрывались диалогом.\n */\nimport {computed} from 'vue'\nimport type {Component} from 'vue'\n\nimport {useToast} from '../../composables/useToast'\nimport type {GrToastTone} from '../../composables/useToast'\nimport GrButton from '../GrButton'\nimport GrIcon from '../GrIcon'\nimport {PLACEMENT_CLASS, type GrToasterPlacement} from './grToasterStyles'\n\nimport IconCheck from '~icons/lucide/check-circle'\nimport IconWarning from '~icons/lucide/alert-triangle'\nimport IconError from '~icons/lucide/x-circle'\nimport IconInfo from '~icons/lucide/info'\nimport IconClose from '~icons/lucide/x'\n\nexport type {GrToasterPlacement}\n\ninterface ToneMeta {\n icon: Component\n color: string\n role: 'status' | 'alert'\n live: 'polite' | 'assertive'\n}\n\n// Единый маппинг по tone'у: иконка, цвет, a11y-роль и «напор» live-региона.\n// На уровне модуля — чтобы не пересоздавать объект на каждый рендер.\nconst TONE_META: Record<GrToastTone, ToneMeta> = {\n primary: {icon: IconInfo, color: 'var(--primary)', role: 'status', live: 'polite'},\n neutral: {icon: IconInfo, color: 'var(--muted-fg)', role: 'status', live: 'polite'},\n info: {icon: IconInfo, color: 'var(--ds-info)', role: 'status', live: 'polite'},\n success: {icon: IconCheck, color: 'var(--ds-success)', role: 'status', live: 'polite'},\n warning: {icon: IconWarning, color: 'var(--ds-warning)', role: 'alert', live: 'assertive'},\n danger: {icon: IconError, color: 'var(--ds-danger)', role: 'alert', live: 'assertive'},\n slate: {icon: IconInfo, color: 'var(--ds-slate)', role: 'status', live: 'polite'},\n azure: {icon: IconInfo, color: 'var(--ds-azure)', role: 'status', live: 'polite'},\n}\n\n\nexport interface GrToasterProps {\n /** Угол экрана для стека уведомлений. */\n placement?: GrToasterPlacement\n /** A11y-лейбл кнопки закрытия (i18n). */\n dismissLabel?: string\n /** A11y-лейбл контейнера-региона (i18n). */\n regionLabel?: string\n}\n\nconst props = withDefaults(defineProps<GrToasterProps>(), {\n placement: 'top-right',\n dismissLabel: 'Dismiss',\n regionLabel: 'Notifications',\n})\n\nconst {list, dismiss} = useToast()\n\n// SSR-guard: на сервере `document.body` недоступен — отключаем `teleport`.\nconst isClient = typeof window !== 'undefined'\n\nfunction metaFor(tone: GrToastTone): ToneMeta {\n return TONE_META[tone] ?? TONE_META.info\n}\n\nconst containerClass = computed(() => PLACEMENT_CLASS[props.placement])\n</script>\n\n<template>\n <teleport to=\"body\" :disabled=\"!isClient\">\n <div\n data-ds-toaster\n role=\"region\"\n :aria-label=\"regionLabel\"\n class=\"fixed z-[60] grid w-[360px] max-w-[calc(100vw-2rem)] gap-3\"\n :class=\"containerClass\"\n >\n <TransitionGroup\n tag=\"div\"\n class=\"grid gap-3\"\n enter-active-class=\"transition duration-200 ease-out\"\n enter-from-class=\"opacity-0 translate-y-2\"\n enter-to-class=\"opacity-100 translate-y-0\"\n leave-active-class=\"transition duration-150 ease-in absolute\"\n leave-from-class=\"opacity-100 translate-y-0\"\n leave-to-class=\"opacity-0 translate-y-2\"\n move-class=\"transition-transform duration-200 ease-out\"\n >\n <div\n v-for=\"toast in list\"\n :key=\"toast.id\"\n data-ds-toast\n :data-tone=\"toast.tone\"\n :role=\"metaFor(toast.tone).role\"\n :aria-live=\"metaFor(toast.tone).live\"\n aria-atomic=\"true\"\n class=\"rounded-[var(--ds-radius-lg)] border border-[var(--brd)] bg-[var(--card)] px-4 py-3 shadow-[var(--ds-shadow-2)]\"\n >\n <div class=\"flex items-start gap-3\">\n <GrIcon size=\"md\" class=\"mt-0.5\" :style=\"{ color: metaFor(toast.tone).color }\" aria-hidden=\"true\">\n <component :is=\"metaFor(toast.tone).icon\" />\n </GrIcon>\n <div class=\"min-w-0 flex-1\">\n <div class=\"text-[13px] font-700\">\n {{ toast.title }}\n </div>\n <div v-if=\"toast.message\" class=\"mt-0.5 text-[13px] text-[var(--muted-fg)]\">\n {{ toast.message }}\n </div>\n </div>\n <GrButton\n variant=\"ghost\"\n size=\"sm\"\n square\n :aria-label=\"dismissLabel\"\n @click=\"dismiss(toast.id)\"\n >\n <GrIcon size=\"sm\" aria-hidden=\"true\">\n <IconClose />\n </GrIcon>\n </GrButton>\n </div>\n </div>\n </TransitionGroup>\n </div>\n </teleport>\n</template>\n","<script setup lang=\"ts\">\n/**\n * GrToaster — DS-примитив области уведомлений (toast).\n *\n * Модель состояния берётся из `useToast` (модульный синглтон), поэтому\n * в приложении предполагается **один активный `GrToaster`** на корень.\n *\n * A11y:\n * - контейнер — `role=\"region\"` с `aria-label` (i18n-проп `regionLabel`);\n * - каждый toast — `role=\"status\"` + `aria-live=\"polite\"` для `info`/`success`\n * и `role=\"alert\"` + `aria-live=\"assertive\"` для `warning`/`danger`\n * (критичные сообщения должны прерывать скринридер).\n *\n * UX:\n * - появление/исчезновение анимируется `TransitionGroup`;\n * - `placement` настраивает угол экрана;\n * - `z-[60]` — выше, чем `GrModal` (`z-50`), чтобы уведомления не перекрывались диалогом.\n */\nimport {computed} from 'vue'\nimport type {Component} from 'vue'\n\nimport {useToast} from '../../composables/useToast'\nimport type {GrToastTone} from '../../composables/useToast'\nimport GrButton from '../GrButton'\nimport GrIcon from '../GrIcon'\nimport {PLACEMENT_CLASS, type GrToasterPlacement} from './grToasterStyles'\n\nimport IconCheck from '~icons/lucide/check-circle'\nimport IconWarning from '~icons/lucide/alert-triangle'\nimport IconError from '~icons/lucide/x-circle'\nimport IconInfo from '~icons/lucide/info'\nimport IconClose from '~icons/lucide/x'\n\nexport type {GrToasterPlacement}\n\ninterface ToneMeta {\n icon: Component\n color: string\n role: 'status' | 'alert'\n live: 'polite' | 'assertive'\n}\n\n// Единый маппинг по tone'у: иконка, цвет, a11y-роль и «напор» live-региона.\n// На уровне модуля — чтобы не пересоздавать объект на каждый рендер.\nconst TONE_META: Record<GrToastTone, ToneMeta> = {\n primary: {icon: IconInfo, color: 'var(--primary)', role: 'status', live: 'polite'},\n neutral: {icon: IconInfo, color: 'var(--muted-fg)', role: 'status', live: 'polite'},\n info: {icon: IconInfo, color: 'var(--ds-info)', role: 'status', live: 'polite'},\n success: {icon: IconCheck, color: 'var(--ds-success)', role: 'status', live: 'polite'},\n warning: {icon: IconWarning, color: 'var(--ds-warning)', role: 'alert', live: 'assertive'},\n danger: {icon: IconError, color: 'var(--ds-danger)', role: 'alert', live: 'assertive'},\n slate: {icon: IconInfo, color: 'var(--ds-slate)', role: 'status', live: 'polite'},\n azure: {icon: IconInfo, color: 'var(--ds-azure)', role: 'status', live: 'polite'},\n}\n\n\nexport interface GrToasterProps {\n /** Угол экрана для стека уведомлений. */\n placement?: GrToasterPlacement\n /** A11y-лейбл кнопки закрытия (i18n). */\n dismissLabel?: string\n /** A11y-лейбл контейнера-региона (i18n). */\n regionLabel?: string\n}\n\nconst props = withDefaults(defineProps<GrToasterProps>(), {\n placement: 'top-right',\n dismissLabel: 'Dismiss',\n regionLabel: 'Notifications',\n})\n\nconst {list, dismiss} = useToast()\n\n// SSR-guard: на сервере `document.body` недоступен — отключаем `teleport`.\nconst isClient = typeof window !== 'undefined'\n\nfunction metaFor(tone: GrToastTone): ToneMeta {\n return TONE_META[tone] ?? TONE_META.info\n}\n\nconst containerClass = computed(() => PLACEMENT_CLASS[props.placement])\n</script>\n\n<template>\n <teleport to=\"body\" :disabled=\"!isClient\">\n <div\n data-ds-toaster\n role=\"region\"\n :aria-label=\"regionLabel\"\n class=\"fixed z-[60] grid w-[360px] max-w-[calc(100vw-2rem)] gap-3\"\n :class=\"containerClass\"\n >\n <TransitionGroup\n tag=\"div\"\n class=\"grid gap-3\"\n enter-active-class=\"transition duration-200 ease-out\"\n enter-from-class=\"opacity-0 translate-y-2\"\n enter-to-class=\"opacity-100 translate-y-0\"\n leave-active-class=\"transition duration-150 ease-in absolute\"\n leave-from-class=\"opacity-100 translate-y-0\"\n leave-to-class=\"opacity-0 translate-y-2\"\n move-class=\"transition-transform duration-200 ease-out\"\n >\n <div\n v-for=\"toast in list\"\n :key=\"toast.id\"\n data-ds-toast\n :data-tone=\"toast.tone\"\n :role=\"metaFor(toast.tone).role\"\n :aria-live=\"metaFor(toast.tone).live\"\n aria-atomic=\"true\"\n class=\"rounded-[var(--ds-radius-lg)] border border-[var(--brd)] bg-[var(--card)] px-4 py-3 shadow-[var(--ds-shadow-2)]\"\n >\n <div class=\"flex items-start gap-3\">\n <GrIcon size=\"md\" class=\"mt-0.5\" :style=\"{ color: metaFor(toast.tone).color }\" aria-hidden=\"true\">\n <component :is=\"metaFor(toast.tone).icon\" />\n </GrIcon>\n <div class=\"min-w-0 flex-1\">\n <div class=\"text-[13px] font-700\">\n {{ toast.title }}\n </div>\n <div v-if=\"toast.message\" class=\"mt-0.5 text-[13px] text-[var(--muted-fg)]\">\n {{ toast.message }}\n </div>\n </div>\n <GrButton\n variant=\"ghost\"\n size=\"sm\"\n square\n :aria-label=\"dismissLabel\"\n @click=\"dismiss(toast.id)\"\n >\n <GrIcon size=\"sm\" aria-hidden=\"true\">\n <IconClose />\n </GrIcon>\n </GrButton>\n </div>\n </div>\n </TransitionGroup>\n </div>\n </teleport>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4CA,MAAM,YAA2C;GAC/C,SAAS;IAAC,MAAM;IAAU,OAAO;IAAkB,MAAM;IAAU,MAAM;IAAS;GAClF,SAAS;IAAC,MAAM;IAAU,OAAO;IAAmB,MAAM;IAAU,MAAM;IAAS;GACnF,MAAM;IAAC,MAAM;IAAU,OAAO;IAAkB,MAAM;IAAU,MAAM;IAAS;GAC/E,SAAS;IAAC,MAAM;IAAW,OAAO;IAAqB,MAAM;IAAU,MAAM;IAAS;GACtF,SAAS;IAAC,MAAM;IAAa,OAAO;IAAqB,MAAM;IAAS,MAAM;IAAY;GAC1F,QAAQ;IAAC,MAAM;IAAW,OAAO;IAAoB,MAAM;IAAS,MAAM;IAAY;GACtF,OAAO;IAAC,MAAM;IAAU,OAAO;IAAmB,MAAM;IAAU,MAAM;IAAS;GACjF,OAAO;IAAC,MAAM;IAAU,OAAO;IAAmB,MAAM;IAAU,MAAM;IAAS;GACnF;EAYA,MAAM,QAAQ;EAMd,MAAM,EAAC,MAAM,YAAW,UAAS;EAGjC,MAAM,WAAW,OAAO,WAAW;EAEnC,SAAS,QAAQ,MAA6B;AAC5C,UAAO,UAAU,SAAS,UAAU;;EAGtC,MAAM,iBAAiB,eAAe,gBAAgB,MAAM,WAAU;;uBAIpE,YAwDW,UAAA;IAxDD,IAAG;IAAQ,UAAQ,CAAG;OAC9B,mBAsDM,OAAA;IArDF,mBAAA;IACA,MAAK;IACJ,cAAY,QAAA;IACb,OAAK,eAAA,CAAC,8DACE,eAAA,MAAc,CAAA;OAExB,YA8CkB,iBAAA;IA7Cd,KAAI;IACJ,OAAM;IACN,sBAAmB;IACnB,oBAAiB;IACjB,kBAAe;IACf,sBAAmB;IACnB,oBAAiB;IACjB,kBAAe;IACf,cAAW;;2BAGY,EAAA,UAAA,KAAA,EADzB,mBAkCM,UAAA,MAAA,WAjCc,MAAA,KAAI,GAAb,UAAK;yBADhB,mBAkCM,OAAA;MAhCD,KAAK,MAAM;MACZ,iBAAA;MACC,aAAW,MAAM;MACjB,MAAM,QAAQ,MAAM,KAAI,CAAE;MAC1B,aAAW,QAAQ,MAAM,KAAI,CAAE;MAChC,eAAY;MACZ,OAAM;SAER,mBAuBM,OAvBN,YAuBM;MAtBJ,YAES,MAAA,eAAA,EAAA;OAFD,MAAK;OAAK,OAAM;OAAU,OAAK,eAAA,EAAA,OAAW,QAAQ,MAAM,KAAI,CAAE,OAAK,CAAA;OAAI,eAAY;;8BAC7C,EAAA,WAAA,EAA5C,YAA4C,wBAA5B,QAAQ,MAAM,KAAI,CAAE,KAAI,CAAA,EAAA,CAAA;;;MAE1C,mBAOM,OAPN,YAOM,CANJ,mBAEM,OAFN,YAEM,gBADD,MAAM,MAAK,EAAA,EAAA,EAEL,MAAM,WAAA,WAAA,EAAjB,mBAEM,OAFN,YAEM,gBADD,MAAM,QAAO,EAAA,EAAA,IAAA,mBAAA,IAAA,KAAA,CAAA,CAAA;MAGpB,YAUW,MAAA,iBAAA,EAAA;OATP,SAAQ;OACR,MAAK;OACL,QAAA;OACC,cAAY,QAAA;OACZ,UAAK,WAAE,MAAA,QAAO,CAAC,MAAM,GAAE;;8BAIjB,CAFT,YAES,MAAA,eAAA,EAAA;QAFD,MAAK;QAAK,eAAY;;+BACf,CAAb,YAAa,MAAA,UAAA,CAAA,CAAA,CAAA"}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { t as info_default } from "../../../chunks/info-C0bHmdZq.js";
|
|
2
|
-
import { t as GrIcon_default } from "../../GrIcon/chunks/GrIcon-BV7RBU_0.js";
|
|
3
|
-
import { computed, createElementBlock, createElementVNode, createVNode, defineComponent, normalizeStyle, openBlock, renderSlot, toDisplayString, unref, useId, withCtx } from "vue";
|
|
4
|
-
//#region src/components/GrTooltip/GrTooltip.vue?vue&type=script&setup=true&lang.ts
|
|
5
|
-
var _hoisted_1 = {
|
|
6
|
-
"data-ds-tooltip": "",
|
|
7
|
-
class: "group relative inline-flex"
|
|
8
|
-
};
|
|
9
|
-
//#endregion
|
|
10
|
-
//#region src/components/GrTooltip/GrTooltip.vue
|
|
11
|
-
var GrTooltip_default = /* @__PURE__ */ defineComponent({
|
|
12
|
-
__name: "GrTooltip",
|
|
13
|
-
props: {
|
|
14
|
-
text: {},
|
|
15
|
-
iconColor: { default: "var(--muted-fg)" }
|
|
16
|
-
},
|
|
17
|
-
setup(__props) {
|
|
18
|
-
/**
|
|
19
|
-
* GrTooltip — DS-примитив инлайн-подсказки на hover/focus.
|
|
20
|
-
*
|
|
21
|
-
* По умолчанию триггер — иконка info; можно заменить через слот.
|
|
22
|
-
* A11y: `<span role="tooltip">` связывается с триггером через
|
|
23
|
-
* уникальный `aria-describedby`, чтобы скринридер озвучил подсказку
|
|
24
|
-
* при фокусе.
|
|
25
|
-
*
|
|
26
|
-
* Ограничения: без автопозиционирования/flip — подсказка всегда
|
|
27
|
-
* сверху по центру триггера.
|
|
28
|
-
*/
|
|
29
|
-
const props = __props;
|
|
30
|
-
const tooltipId = `ds-tooltip-${useId()}`;
|
|
31
|
-
const triggerStyle = computed(() => ({ color: props.iconColor }));
|
|
32
|
-
return (_ctx, _cache) => {
|
|
33
|
-
return openBlock(), createElementBlock("span", _hoisted_1, [createElementVNode("span", {
|
|
34
|
-
"data-ds-tooltip-trigger": "",
|
|
35
|
-
"data-testid": "ds-tooltip-trigger",
|
|
36
|
-
tabindex: "0",
|
|
37
|
-
"aria-describedby": tooltipId,
|
|
38
|
-
class: "inline-flex items-center justify-center focus:outline-none",
|
|
39
|
-
style: normalizeStyle(triggerStyle.value)
|
|
40
|
-
}, [renderSlot(_ctx.$slots, "default", {}, () => [createVNode(unref(GrIcon_default), {
|
|
41
|
-
size: "sm",
|
|
42
|
-
"aria-hidden": "true"
|
|
43
|
-
}, {
|
|
44
|
-
default: withCtx(() => [createVNode(unref(info_default))]),
|
|
45
|
-
_: 1
|
|
46
|
-
})])], 4), createElementVNode("span", {
|
|
47
|
-
id: tooltipId,
|
|
48
|
-
role: "tooltip",
|
|
49
|
-
class: "pointer-events-none absolute bottom-[calc(100%+8px)] left-1/2 z-10 -translate-x-1/2 whitespace-nowrap rounded-md border border-[var(--brd)] bg-[var(--popover)] px-2 py-1 text-[12px] text-[var(--popover-fg)] opacity-0 shadow-[var(--ds-shadow-1)] transition-opacity duration-150 group-hover:opacity-100 group-focus-within:opacity-100"
|
|
50
|
-
}, toDisplayString(__props.text), 1)]);
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
//#endregion
|
|
55
|
-
export { GrTooltip_default as t };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"GrTooltip-B7I1AVIC.js","names":[],"sources":["../../../../src/components/GrTooltip/GrTooltip.vue","../../../../src/components/GrTooltip/GrTooltip.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * GrTooltip — DS-примитив инлайн-подсказки на hover/focus.\n *\n * По умолчанию триггер — иконка info; можно заменить через слот.\n * A11y: `<span role=\"tooltip\">` связывается с триггером через\n * уникальный `aria-describedby`, чтобы скринридер озвучил подсказку\n * при фокусе.\n *\n * Ограничения: без автопозиционирования/flip — подсказка всегда\n * сверху по центру триггера.\n */\nimport { computed, useId } from 'vue'\n\nimport GrIcon from '../GrIcon'\n\nimport IconInfo from '~icons/lucide/info'\n\nexport interface GrTooltipProps {\n text: string\n /** Цвет триггер-иконки (CSS color). По умолчанию — `var(--muted-fg)`. */\n iconColor?: string\n}\n\nconst props = withDefaults(defineProps<GrTooltipProps>(), {\n iconColor: 'var(--muted-fg)',\n})\n\nconst tooltipId = `ds-tooltip-${useId()}`\n\nconst triggerStyle = computed(() => ({ color: props.iconColor }))\n</script>\n\n<template>\n <span data-ds-tooltip class=\"group relative inline-flex\">\n <span\n data-ds-tooltip-trigger\n data-testid=\"ds-tooltip-trigger\"\n tabindex=\"0\"\n :aria-describedby=\"tooltipId\"\n class=\"inline-flex items-center justify-center focus:outline-none\"\n :style=\"triggerStyle\"\n >\n <slot>\n <GrIcon size=\"sm\" aria-hidden=\"true\">\n <IconInfo />\n </GrIcon>\n </slot>\n </span>\n <span\n :id=\"tooltipId\"\n role=\"tooltip\"\n class=\"pointer-events-none absolute bottom-[calc(100%+8px)] left-1/2 z-10 -translate-x-1/2 whitespace-nowrap rounded-md border border-[var(--brd)] bg-[var(--popover)] px-2 py-1 text-[12px] text-[var(--popover-fg)] opacity-0 shadow-[var(--ds-shadow-1)] transition-opacity duration-150 group-hover:opacity-100 group-focus-within:opacity-100\"\n >\n {{ text }}\n </span>\n </span>\n</template>\n","<script setup lang=\"ts\">\n/**\n * GrTooltip — DS-примитив инлайн-подсказки на hover/focus.\n *\n * По умолчанию триггер — иконка info; можно заменить через слот.\n * A11y: `<span role=\"tooltip\">` связывается с триггером через\n * уникальный `aria-describedby`, чтобы скринридер озвучил подсказку\n * при фокусе.\n *\n * Ограничения: без автопозиционирования/flip — подсказка всегда\n * сверху по центру триггера.\n */\nimport { computed, useId } from 'vue'\n\nimport GrIcon from '../GrIcon'\n\nimport IconInfo from '~icons/lucide/info'\n\nexport interface GrTooltipProps {\n text: string\n /** Цвет триггер-иконки (CSS color). По умолчанию — `var(--muted-fg)`. */\n iconColor?: string\n}\n\nconst props = withDefaults(defineProps<GrTooltipProps>(), {\n iconColor: 'var(--muted-fg)',\n})\n\nconst tooltipId = `ds-tooltip-${useId()}`\n\nconst triggerStyle = computed(() => ({ color: props.iconColor }))\n</script>\n\n<template>\n <span data-ds-tooltip class=\"group relative inline-flex\">\n <span\n data-ds-tooltip-trigger\n data-testid=\"ds-tooltip-trigger\"\n tabindex=\"0\"\n :aria-describedby=\"tooltipId\"\n class=\"inline-flex items-center justify-center focus:outline-none\"\n :style=\"triggerStyle\"\n >\n <slot>\n <GrIcon size=\"sm\" aria-hidden=\"true\">\n <IconInfo />\n </GrIcon>\n </slot>\n </span>\n <span\n :id=\"tooltipId\"\n role=\"tooltip\"\n class=\"pointer-events-none absolute bottom-[calc(100%+8px)] left-1/2 z-10 -translate-x-1/2 whitespace-nowrap rounded-md border border-[var(--brd)] bg-[var(--popover)] px-2 py-1 text-[12px] text-[var(--popover-fg)] opacity-0 shadow-[var(--ds-shadow-1)] transition-opacity duration-150 group-hover:opacity-100 group-focus-within:opacity-100\"\n >\n {{ text }}\n </span>\n </span>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwBA,MAAM,QAAQ;EAId,MAAM,YAAY,cAAc,OAAO;EAEvC,MAAM,eAAe,gBAAgB,EAAE,OAAO,MAAM,WAAW,EAAC;;uBAI9D,mBAsBO,QAtBP,YAsBO,CArBL,mBAaO,QAAA;IAZL,2BAAA;IACA,eAAY;IACZ,UAAS;IACR,oBAAkB;IACnB,OAAM;IACL,OAAK,eAAE,aAAA,MAAY;OAEpB,WAIO,KAAA,QAAA,WAAA,EAAA,QAAA,CAHL,YAES,MAAA,eAAA,EAAA;IAFD,MAAK;IAAK,eAAY;;2BAChB,CAAZ,YAAY,MAAA,aAAA,CAAA,CAAA,CAAA;;cAIlB,mBAMO,QAAA;IALJ,IAAI;IACL,MAAK;IACL,OAAM;sBAEH,QAAA,KAAI,EAAA,EAAA,CAAA,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"GrTreeSelect-C1abr5uH.js","names":["$slots"],"sources":["../../../../src/components/GrTreeSelect/GrTreeSelect.vue","../../../../src/components/GrTreeSelect/GrTreeSelect.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"T extends Record<string, any> = any\">\nimport { computed, nextTick, onUnmounted, ref, watch } from 'vue'\n\nimport { vClickOutside } from '../../directives'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport GrInput from '../GrInput/GrInput.vue'\nimport GrTree, {\n type GrTreeInstance,\n type GrTreeKey,\n type GrTreeNode,\n} from '../GrTree'\nimport type { GrTreeSelectModelValue, GrTreeSelectProps } from './grTreeSelectTypes'\nimport { grTreeSelectClass, grTreeSelectPanelClass } from './grTreeSelectStyles'\n\nconst props = withDefaults(\n defineProps<GrTreeSelectProps<T>>(),\n {\n props: () => ({\n children: 'children',\n label: 'label',\n }),\n nodeKey: 'id' as any,\n defaultExpandedKeys: () => [],\n disabled: false,\n placeholder: undefined,\n size: 'md',\n invalid: false,\n state: 'default',\n multiple: false,\n clearable: false,\n valueDisplay: 'label',\n filterable: false,\n filterPlaceholder: undefined,\n filterInputmode: undefined,\n filterNodeMethod: undefined,\n closeOnSelect: undefined,\n dropdownMaxHeight: 320,\n },\n)\n\nconst { t } = useGranularityTranslations()\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: GrTreeSelectModelValue): void\n (e: 'change', value: GrTreeSelectModelValue): void\n (e: 'visibleChange', visible: boolean): void\n (e: 'clear'): void\n (e: 'nodeClick', data: T, node: GrTreeNode<T>): void\n}>()\n\ndefineSlots<{\n /** Рендер значения внутри триггера (вместо дефолтного текста). */\n value?: (props: { value: GrTreeSelectModelValue; labels: string[]; displayValue: string; pathLabels?: string[] }) => any\n /** Рендер строки дерева. */\n node?: (props: { node: GrTreeNode<T>; data: T; selected: boolean }) => any\n /** Содержимое пустого состояния (когда нет данных). */\n empty?: () => any\n}>()\n\nconst rootEl = ref<HTMLElement | null>(null)\nconst triggerEl = ref<HTMLInputElement | null>(null)\nconst filterInputRef = ref<InstanceType<typeof GrInput> | null>(null)\nconst treeRef = ref<GrTreeInstance | null>(null)\nconst panelEl = ref<HTMLElement | null>(null)\n\nconst clickOutsideExclude = [() => panelEl.value]\n\nlet hadPointerDownOnTrigger = false\n\nconst open = ref(false)\nconst filterValue = ref('')\n\nconst panelStyle = ref<Record<string, string>>({\n left: '0px',\n top: '0px',\n width: '0px',\n zIndex: '2147483647',\n})\n\nfunction syncPanelPosition(): void {\n if (typeof window === 'undefined')\n return\n\n const root = rootEl.value\n if (!root)\n return\n\n const rect = root.getBoundingClientRect()\n\n panelStyle.value = {\n left: `${rect.left}px`,\n top: `${rect.bottom + 8}px`,\n width: `${rect.width}px`,\n zIndex: '2147483647',\n }\n}\n\nfunction bindPanelPositionListeners(): void {\n if (typeof window === 'undefined')\n return\n window.addEventListener('resize', syncPanelPosition)\n window.addEventListener('scroll', syncPanelPosition, true)\n}\n\nfunction unbindPanelPositionListeners(): void {\n if (typeof window === 'undefined')\n return\n window.removeEventListener('resize', syncPanelPosition)\n window.removeEventListener('scroll', syncPanelPosition, true)\n}\n\nconst closeOnSelectResolved = computed(() => {\n return props.closeOnSelect ?? !props.multiple\n})\n\nfunction getChildrenKey() {\n return props.props.children ?? 'children'\n}\n\nfunction getLabelKey() {\n return props.props.label ?? 'label'\n}\n\nfunction nodeLabel(data: T): string {\n const key = getLabelKey() as keyof T\n const v = data[key]\n return v == null ? '' : String(v)\n}\n\nfunction nodeChildren(data: T): T[] {\n const key = getChildrenKey() as keyof T\n const v = data[key]\n return Array.isArray(v) ? (v as any) : []\n}\n\nfunction nodeKeyOf(data: T, index: number, parentKey: GrTreeKey | undefined): GrTreeKey {\n const keyName = props.nodeKey as keyof T\n const v = data[keyName]\n if (v != null)\n return v as GrTreeKey\n\n return parentKey == null ? index : `${String(parentKey)}:${index}`\n}\n\nconst labelByKey = computed(() => {\n const map = new Map<GrTreeKey, string>()\n\n const walk = (items: T[], parentKey: GrTreeKey | undefined) => {\n for (let i = 0; i < items.length; i++) {\n const item = items[i]\n const key = nodeKeyOf(item, i, parentKey)\n map.set(key, nodeLabel(item))\n walk(nodeChildren(item), key)\n }\n }\n\n walk(props.data ?? [], undefined)\n return map\n})\n\nconst pathLabelsByKey = computed(() => {\n const map = new Map<GrTreeKey, string[]>()\n\n const walk = (items: T[], parentKey: GrTreeKey | undefined, parentPath: string[]) => {\n for (let i = 0; i < items.length; i++) {\n const item = items[i]\n const key = nodeKeyOf(item, i, parentKey)\n const label = nodeLabel(item)\n const path = [...parentPath, label]\n map.set(key, path)\n walk(nodeChildren(item), key, path)\n }\n }\n\n walk(props.data ?? [], undefined, [])\n return map\n})\n\nconst selectedKeys = computed<GrTreeKey[]>(() => {\n if (props.multiple) {\n return Array.isArray(props.modelValue) ? props.modelValue : []\n }\n\n const v = props.modelValue\n if (v == null || Array.isArray(v))\n return []\n return [v]\n})\n\nconst selectedKeySet = computed(() => new Set(selectedKeys.value))\n\nconst selectedLabels = computed(() => {\n const map = labelByKey.value\n return selectedKeys.value.map((k) => map.get(k) ?? String(k))\n})\n\nconst selectedPathLabels = computed<string[] | undefined>(() => {\n if (props.multiple)\n return undefined\n\n const key = selectedKeys.value[0]\n if (key == null)\n return undefined\n\n const path = pathLabelsByKey.value.get(key)\n if (path?.length)\n return path\n\n const labels = selectedLabels.value\n return labels.length ? [labels[0]] : undefined\n})\n\nconst displayValue = computed(() => {\n const labels = selectedLabels.value\n if (labels.length === 0)\n return ''\n\n if (!props.multiple) {\n if (props.valueDisplay === 'path') {\n const path = selectedPathLabels.value\n if (path?.length)\n return path.join(' / ')\n }\n return labels[0]\n }\n\n if (labels.length === 1)\n return labels[0]\n return `${labels[0]} +${labels.length - 1}`\n})\n\nconst hasSelection = computed(() => selectedKeys.value.length > 0)\n\nconst resolvedFilterPlaceholder = computed(() => {\n return props.filterPlaceholder ?? t('gr.treeSelect.filterPlaceholder', 'Search…')\n})\n\nconst className = computed(() => {\n return grTreeSelectClass({\n size: props.size,\n state: props.state,\n invalid: props.invalid,\n })\n})\n\nconst panelClasses = computed(() => {\n return grTreeSelectPanelClass\n})\n\nfunction setOpen(next: boolean) {\n if (props.disabled)\n return\n\n if (open.value === next)\n return\n\n open.value = next\n emit('visibleChange', next)\n}\n\nfunction onClickOutside(): void {\n setOpen(false)\n}\n\nfunction openDropdown(): void {\n setOpen(true)\n}\n\nfunction closeDropdown(): void {\n setOpen(false)\n}\n\nfunction toggleDropdown(): void {\n setOpen(!open.value)\n}\n\nfunction onTriggerPointerDown(): void {\n hadPointerDownOnTrigger = true\n if (typeof window !== 'undefined') {\n window.setTimeout(() => {\n hadPointerDownOnTrigger = false\n }, 0)\n }\n else {\n // SSR / no window: reset sync\n hadPointerDownOnTrigger = false\n }\n}\n\nfunction onTriggerFocus(): void {\n if (hadPointerDownOnTrigger)\n return\n openDropdown()\n}\n\nfunction closeOnEscape(e: KeyboardEvent): void {\n if (e.key === 'Escape') {\n closeDropdown()\n nextTick(() => triggerEl.value?.focus())\n }\n}\n\nwatch(\n open,\n async (isOpen) => {\n if (typeof document === 'undefined')\n return\n\n document.removeEventListener('keydown', closeOnEscape)\n unbindPanelPositionListeners()\n\n if (isOpen)\n document.addEventListener('keydown', closeOnEscape)\n\n if (!isOpen)\n return\n\n bindPanelPositionListeners()\n await nextTick()\n syncPanelPosition()\n\n // sync tree highlight\n if (!props.multiple) {\n const v = props.modelValue\n if (v != null && !Array.isArray(v))\n treeRef.value?.setCurrentKey(v)\n }\n\n // focus filter input\n if (props.filterable) {\n await nextTick()\n filterInputRef.value?.focus()\n }\n },\n { immediate: true },\n)\n\nonUnmounted(() => {\n if (typeof document === 'undefined')\n return\n document.removeEventListener('keydown', closeOnEscape)\n unbindPanelPositionListeners()\n})\n\nwatch(\n () => props.modelValue,\n (v) => {\n if (props.multiple)\n return\n if (v == null || Array.isArray(v)) {\n treeRef.value?.setCurrentKey(undefined)\n return\n }\n treeRef.value?.setCurrentKey(v)\n },\n)\n\nwatch(\n filterValue,\n (v) => {\n treeRef.value?.filter(v)\n },\n)\n\nwatch(\n open,\n (isOpen) => {\n if (isOpen)\n return\n if (filterValue.value.trim().length > 0)\n filterValue.value = ''\n },\n)\n\nfunction emitModel(next: GrTreeSelectModelValue) {\n emit('update:modelValue', next)\n emit('change', next)\n}\n\nfunction clear(): void {\n if (props.disabled)\n return\n\n const next: GrTreeSelectModelValue = props.multiple ? [] : null\n emitModel(next)\n emit('clear')\n if (!props.multiple)\n treeRef.value?.setCurrentKey(undefined)\n}\n\nfunction onTriggerKeydown(e: KeyboardEvent): void {\n if (props.disabled)\n return\n\n if (e.key === 'ArrowDown' || e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n openDropdown()\n }\n if (e.key === 'Escape') {\n e.preventDefault()\n closeDropdown()\n }\n}\n\nfunction onNodeClick(data: T, node: GrTreeNode<T>): void {\n emit('nodeClick', data, node)\n\n if (props.disabled)\n return\n\n if (props.multiple) {\n const next = new Set(selectedKeySet.value)\n if (next.has(node.key))\n next.delete(node.key)\n else\n next.add(node.key)\n emitModel([...next])\n\n if (closeOnSelectResolved.value) {\n closeDropdown()\n }\n return\n }\n\n emitModel(node.key)\n if (closeOnSelectResolved.value) {\n closeDropdown()\n }\n}\n</script>\n\n<template>\n <div\n ref=\"rootEl\"\n v-click-outside=\"{ handler: onClickOutside, enabled: open, exclude: clickOutsideExclude }\"\n data-ds-tree-select\n class=\"relative\"\n >\n <div class=\"relative\">\n <input\n ref=\"triggerEl\"\n data-testid=\"ds-tree-select-trigger\"\n data-ds-tree-select-trigger\n type=\"text\"\n :value=\"displayValue\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n readonly\n role=\"combobox\"\n aria-readonly=\"true\"\n :aria-expanded=\"open ? 'true' : 'false'\"\n :aria-invalid=\"invalid ? 'true' : undefined\"\n class=\"w-full rounded-md border bg-[var(--bg)] text-[var(--fg)] placeholder:text-[var(--muted-fg)] transition-colors duration-150 focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)] disabled:opacity-50 disabled:cursor-not-allowed\"\n :class=\"[className, $slots.value ? 'text-transparent placeholder:text-transparent' : '']\"\n @pointerdown=\"onTriggerPointerDown\"\n @click=\"toggleDropdown\"\n @focus=\"onTriggerFocus\"\n @keydown=\"onTriggerKeydown\"\n >\n\n <button\n v-if=\"clearable && hasSelection\"\n data-testid=\"ds-tree-select-clear\"\n data-ds-tree-select-clear\n type=\"button\"\n class=\"absolute top-1/2 -translate-y-1/2 right-3 h-6 w-6 inline-flex items-center justify-center rounded-md text-[var(--muted-fg)] hover:text-[var(--fg)] hover:bg-[color-mix(in_srgb,var(--muted)_25%,transparent)] disabled:opacity-50\"\n :disabled=\"disabled\"\n :aria-label=\"t('gr.common.clear', 'Clear')\"\n @click.stop=\"clear\"\n >\n <span class=\"i-lucide-x inline-block h-4 w-4\" />\n </button>\n\n <span\n v-else\n data-testid=\"ds-tree-select-chevron\"\n data-ds-tree-select-chevron\n class=\"absolute top-1/2 -translate-y-1/2 right-3 text-[var(--muted-fg)] pointer-events-none\"\n >\n <span\n class=\"i-lucide-chevron-down inline-block h-4 w-4 transition-transform duration-150\"\n :class=\"open ? 'rotate-180' : ''\"\n />\n </span>\n\n <div\n v-if=\"$slots.value\"\n class=\"absolute inset-y-0 left-3 right-9 flex items-center pointer-events-none\"\n >\n <slot\n name=\"value\"\n :value=\"modelValue\"\n :labels=\"selectedLabels\"\n :display-value=\"displayValue\"\n :path-labels=\"selectedPathLabels\"\n />\n </div>\n </div>\n\n <teleport to=\"body\">\n <transition\n enter-active-class=\"transition ease-out duration-150\"\n enter-from-class=\"transform opacity-0 scale-95\"\n enter-to-class=\"transform opacity-100 scale-100\"\n leave-active-class=\"transition ease-in duration-100\"\n leave-from-class=\"transform opacity-100 scale-100\"\n leave-to-class=\"transform opacity-0 scale-95\"\n >\n <div\n v-show=\"open\"\n ref=\"panelEl\"\n data-testid=\"ds-tree-select-panel\"\n data-ds-tree-select-panel\n class=\"fixed w-full\"\n :style=\"panelStyle\"\n >\n <div :class=\"panelClasses\">\n <div v-if=\"filterable\" class=\"p-2 border-b border-[var(--brd)]\">\n <GrInput\n ref=\"filterInputRef\"\n v-model=\"filterValue\"\n data-testid=\"ds-tree-select-filter\"\n data-ds-tree-select-filter\n type=\"search\"\n :inputmode=\"filterInputmode\"\n :placeholder=\"resolvedFilterPlaceholder\"\n size=\"sm\"\n />\n </div>\n\n <div\n class=\"p-1 overflow-auto\"\n :style=\"{ maxHeight: `${dropdownMaxHeight}px` }\"\n >\n <div v-if=\"(data?.length ?? 0) === 0\" class=\"px-3 py-2 text-[13px] text-[var(--muted-fg)]\">\n <slot name=\"empty\">\n {{ t('gr.treeSelect.empty', 'No data') }}\n </slot>\n </div>\n\n <GrTree\n v-else\n ref=\"treeRef\"\n :data=\"data\"\n :props=\"props.props\"\n :node-key=\"nodeKey as any\"\n :default-expanded-keys=\"defaultExpandedKeys\"\n :filter-node-method=\"filterNodeMethod\"\n :highlight-current=\"!multiple\"\n @node-click=\"onNodeClick\"\n >\n <template #default=\"{ node, data }\">\n <slot\n name=\"node\"\n :node=\"node\"\n :data=\"data\"\n :selected=\"selectedKeySet.has(node.key)\"\n >\n <div class=\"flex items-center gap-2 min-w-0\">\n <span\n class=\"inline-block h-4 w-4 shrink-0\"\n :class=\"selectedKeySet.has(node.key) ? 'i-lucide-check text-[var(--primary)]' : ''\"\n aria-hidden=\"true\"\n />\n <span class=\"truncate\">{{ node.label }}</span>\n </div>\n </slot>\n </template>\n </GrTree>\n </div>\n </div>\n </div>\n </transition>\n </teleport>\n </div>\n</template>\n","<script setup lang=\"ts\" generic=\"T extends Record<string, any> = any\">\nimport { computed, nextTick, onUnmounted, ref, watch } from 'vue'\n\nimport { vClickOutside } from '../../directives'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport GrInput from '../GrInput/GrInput.vue'\nimport GrTree, {\n type GrTreeInstance,\n type GrTreeKey,\n type GrTreeNode,\n} from '../GrTree'\nimport type { GrTreeSelectModelValue, GrTreeSelectProps } from './grTreeSelectTypes'\nimport { grTreeSelectClass, grTreeSelectPanelClass } from './grTreeSelectStyles'\n\nconst props = withDefaults(\n defineProps<GrTreeSelectProps<T>>(),\n {\n props: () => ({\n children: 'children',\n label: 'label',\n }),\n nodeKey: 'id' as any,\n defaultExpandedKeys: () => [],\n disabled: false,\n placeholder: undefined,\n size: 'md',\n invalid: false,\n state: 'default',\n multiple: false,\n clearable: false,\n valueDisplay: 'label',\n filterable: false,\n filterPlaceholder: undefined,\n filterInputmode: undefined,\n filterNodeMethod: undefined,\n closeOnSelect: undefined,\n dropdownMaxHeight: 320,\n },\n)\n\nconst { t } = useGranularityTranslations()\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: GrTreeSelectModelValue): void\n (e: 'change', value: GrTreeSelectModelValue): void\n (e: 'visibleChange', visible: boolean): void\n (e: 'clear'): void\n (e: 'nodeClick', data: T, node: GrTreeNode<T>): void\n}>()\n\ndefineSlots<{\n /** Рендер значения внутри триггера (вместо дефолтного текста). */\n value?: (props: { value: GrTreeSelectModelValue; labels: string[]; displayValue: string; pathLabels?: string[] }) => any\n /** Рендер строки дерева. */\n node?: (props: { node: GrTreeNode<T>; data: T; selected: boolean }) => any\n /** Содержимое пустого состояния (когда нет данных). */\n empty?: () => any\n}>()\n\nconst rootEl = ref<HTMLElement | null>(null)\nconst triggerEl = ref<HTMLInputElement | null>(null)\nconst filterInputRef = ref<InstanceType<typeof GrInput> | null>(null)\nconst treeRef = ref<GrTreeInstance | null>(null)\nconst panelEl = ref<HTMLElement | null>(null)\n\nconst clickOutsideExclude = [() => panelEl.value]\n\nlet hadPointerDownOnTrigger = false\n\nconst open = ref(false)\nconst filterValue = ref('')\n\nconst panelStyle = ref<Record<string, string>>({\n left: '0px',\n top: '0px',\n width: '0px',\n zIndex: '2147483647',\n})\n\nfunction syncPanelPosition(): void {\n if (typeof window === 'undefined')\n return\n\n const root = rootEl.value\n if (!root)\n return\n\n const rect = root.getBoundingClientRect()\n\n panelStyle.value = {\n left: `${rect.left}px`,\n top: `${rect.bottom + 8}px`,\n width: `${rect.width}px`,\n zIndex: '2147483647',\n }\n}\n\nfunction bindPanelPositionListeners(): void {\n if (typeof window === 'undefined')\n return\n window.addEventListener('resize', syncPanelPosition)\n window.addEventListener('scroll', syncPanelPosition, true)\n}\n\nfunction unbindPanelPositionListeners(): void {\n if (typeof window === 'undefined')\n return\n window.removeEventListener('resize', syncPanelPosition)\n window.removeEventListener('scroll', syncPanelPosition, true)\n}\n\nconst closeOnSelectResolved = computed(() => {\n return props.closeOnSelect ?? !props.multiple\n})\n\nfunction getChildrenKey() {\n return props.props.children ?? 'children'\n}\n\nfunction getLabelKey() {\n return props.props.label ?? 'label'\n}\n\nfunction nodeLabel(data: T): string {\n const key = getLabelKey() as keyof T\n const v = data[key]\n return v == null ? '' : String(v)\n}\n\nfunction nodeChildren(data: T): T[] {\n const key = getChildrenKey() as keyof T\n const v = data[key]\n return Array.isArray(v) ? (v as any) : []\n}\n\nfunction nodeKeyOf(data: T, index: number, parentKey: GrTreeKey | undefined): GrTreeKey {\n const keyName = props.nodeKey as keyof T\n const v = data[keyName]\n if (v != null)\n return v as GrTreeKey\n\n return parentKey == null ? index : `${String(parentKey)}:${index}`\n}\n\nconst labelByKey = computed(() => {\n const map = new Map<GrTreeKey, string>()\n\n const walk = (items: T[], parentKey: GrTreeKey | undefined) => {\n for (let i = 0; i < items.length; i++) {\n const item = items[i]\n const key = nodeKeyOf(item, i, parentKey)\n map.set(key, nodeLabel(item))\n walk(nodeChildren(item), key)\n }\n }\n\n walk(props.data ?? [], undefined)\n return map\n})\n\nconst pathLabelsByKey = computed(() => {\n const map = new Map<GrTreeKey, string[]>()\n\n const walk = (items: T[], parentKey: GrTreeKey | undefined, parentPath: string[]) => {\n for (let i = 0; i < items.length; i++) {\n const item = items[i]\n const key = nodeKeyOf(item, i, parentKey)\n const label = nodeLabel(item)\n const path = [...parentPath, label]\n map.set(key, path)\n walk(nodeChildren(item), key, path)\n }\n }\n\n walk(props.data ?? [], undefined, [])\n return map\n})\n\nconst selectedKeys = computed<GrTreeKey[]>(() => {\n if (props.multiple) {\n return Array.isArray(props.modelValue) ? props.modelValue : []\n }\n\n const v = props.modelValue\n if (v == null || Array.isArray(v))\n return []\n return [v]\n})\n\nconst selectedKeySet = computed(() => new Set(selectedKeys.value))\n\nconst selectedLabels = computed(() => {\n const map = labelByKey.value\n return selectedKeys.value.map((k) => map.get(k) ?? String(k))\n})\n\nconst selectedPathLabels = computed<string[] | undefined>(() => {\n if (props.multiple)\n return undefined\n\n const key = selectedKeys.value[0]\n if (key == null)\n return undefined\n\n const path = pathLabelsByKey.value.get(key)\n if (path?.length)\n return path\n\n const labels = selectedLabels.value\n return labels.length ? [labels[0]] : undefined\n})\n\nconst displayValue = computed(() => {\n const labels = selectedLabels.value\n if (labels.length === 0)\n return ''\n\n if (!props.multiple) {\n if (props.valueDisplay === 'path') {\n const path = selectedPathLabels.value\n if (path?.length)\n return path.join(' / ')\n }\n return labels[0]\n }\n\n if (labels.length === 1)\n return labels[0]\n return `${labels[0]} +${labels.length - 1}`\n})\n\nconst hasSelection = computed(() => selectedKeys.value.length > 0)\n\nconst resolvedFilterPlaceholder = computed(() => {\n return props.filterPlaceholder ?? t('gr.treeSelect.filterPlaceholder', 'Search…')\n})\n\nconst className = computed(() => {\n return grTreeSelectClass({\n size: props.size,\n state: props.state,\n invalid: props.invalid,\n })\n})\n\nconst panelClasses = computed(() => {\n return grTreeSelectPanelClass\n})\n\nfunction setOpen(next: boolean) {\n if (props.disabled)\n return\n\n if (open.value === next)\n return\n\n open.value = next\n emit('visibleChange', next)\n}\n\nfunction onClickOutside(): void {\n setOpen(false)\n}\n\nfunction openDropdown(): void {\n setOpen(true)\n}\n\nfunction closeDropdown(): void {\n setOpen(false)\n}\n\nfunction toggleDropdown(): void {\n setOpen(!open.value)\n}\n\nfunction onTriggerPointerDown(): void {\n hadPointerDownOnTrigger = true\n if (typeof window !== 'undefined') {\n window.setTimeout(() => {\n hadPointerDownOnTrigger = false\n }, 0)\n }\n else {\n // SSR / no window: reset sync\n hadPointerDownOnTrigger = false\n }\n}\n\nfunction onTriggerFocus(): void {\n if (hadPointerDownOnTrigger)\n return\n openDropdown()\n}\n\nfunction closeOnEscape(e: KeyboardEvent): void {\n if (e.key === 'Escape') {\n closeDropdown()\n nextTick(() => triggerEl.value?.focus())\n }\n}\n\nwatch(\n open,\n async (isOpen) => {\n if (typeof document === 'undefined')\n return\n\n document.removeEventListener('keydown', closeOnEscape)\n unbindPanelPositionListeners()\n\n if (isOpen)\n document.addEventListener('keydown', closeOnEscape)\n\n if (!isOpen)\n return\n\n bindPanelPositionListeners()\n await nextTick()\n syncPanelPosition()\n\n // sync tree highlight\n if (!props.multiple) {\n const v = props.modelValue\n if (v != null && !Array.isArray(v))\n treeRef.value?.setCurrentKey(v)\n }\n\n // focus filter input\n if (props.filterable) {\n await nextTick()\n filterInputRef.value?.focus()\n }\n },\n { immediate: true },\n)\n\nonUnmounted(() => {\n if (typeof document === 'undefined')\n return\n document.removeEventListener('keydown', closeOnEscape)\n unbindPanelPositionListeners()\n})\n\nwatch(\n () => props.modelValue,\n (v) => {\n if (props.multiple)\n return\n if (v == null || Array.isArray(v)) {\n treeRef.value?.setCurrentKey(undefined)\n return\n }\n treeRef.value?.setCurrentKey(v)\n },\n)\n\nwatch(\n filterValue,\n (v) => {\n treeRef.value?.filter(v)\n },\n)\n\nwatch(\n open,\n (isOpen) => {\n if (isOpen)\n return\n if (filterValue.value.trim().length > 0)\n filterValue.value = ''\n },\n)\n\nfunction emitModel(next: GrTreeSelectModelValue) {\n emit('update:modelValue', next)\n emit('change', next)\n}\n\nfunction clear(): void {\n if (props.disabled)\n return\n\n const next: GrTreeSelectModelValue = props.multiple ? [] : null\n emitModel(next)\n emit('clear')\n if (!props.multiple)\n treeRef.value?.setCurrentKey(undefined)\n}\n\nfunction onTriggerKeydown(e: KeyboardEvent): void {\n if (props.disabled)\n return\n\n if (e.key === 'ArrowDown' || e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n openDropdown()\n }\n if (e.key === 'Escape') {\n e.preventDefault()\n closeDropdown()\n }\n}\n\nfunction onNodeClick(data: T, node: GrTreeNode<T>): void {\n emit('nodeClick', data, node)\n\n if (props.disabled)\n return\n\n if (props.multiple) {\n const next = new Set(selectedKeySet.value)\n if (next.has(node.key))\n next.delete(node.key)\n else\n next.add(node.key)\n emitModel([...next])\n\n if (closeOnSelectResolved.value) {\n closeDropdown()\n }\n return\n }\n\n emitModel(node.key)\n if (closeOnSelectResolved.value) {\n closeDropdown()\n }\n}\n</script>\n\n<template>\n <div\n ref=\"rootEl\"\n v-click-outside=\"{ handler: onClickOutside, enabled: open, exclude: clickOutsideExclude }\"\n data-ds-tree-select\n class=\"relative\"\n >\n <div class=\"relative\">\n <input\n ref=\"triggerEl\"\n data-testid=\"ds-tree-select-trigger\"\n data-ds-tree-select-trigger\n type=\"text\"\n :value=\"displayValue\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n readonly\n role=\"combobox\"\n aria-readonly=\"true\"\n :aria-expanded=\"open ? 'true' : 'false'\"\n :aria-invalid=\"invalid ? 'true' : undefined\"\n class=\"w-full rounded-md border bg-[var(--bg)] text-[var(--fg)] placeholder:text-[var(--muted-fg)] transition-colors duration-150 focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)] disabled:opacity-50 disabled:cursor-not-allowed\"\n :class=\"[className, $slots.value ? 'text-transparent placeholder:text-transparent' : '']\"\n @pointerdown=\"onTriggerPointerDown\"\n @click=\"toggleDropdown\"\n @focus=\"onTriggerFocus\"\n @keydown=\"onTriggerKeydown\"\n >\n\n <button\n v-if=\"clearable && hasSelection\"\n data-testid=\"ds-tree-select-clear\"\n data-ds-tree-select-clear\n type=\"button\"\n class=\"absolute top-1/2 -translate-y-1/2 right-3 h-6 w-6 inline-flex items-center justify-center rounded-md text-[var(--muted-fg)] hover:text-[var(--fg)] hover:bg-[color-mix(in_srgb,var(--muted)_25%,transparent)] disabled:opacity-50\"\n :disabled=\"disabled\"\n :aria-label=\"t('gr.common.clear', 'Clear')\"\n @click.stop=\"clear\"\n >\n <span class=\"i-lucide-x inline-block h-4 w-4\" />\n </button>\n\n <span\n v-else\n data-testid=\"ds-tree-select-chevron\"\n data-ds-tree-select-chevron\n class=\"absolute top-1/2 -translate-y-1/2 right-3 text-[var(--muted-fg)] pointer-events-none\"\n >\n <span\n class=\"i-lucide-chevron-down inline-block h-4 w-4 transition-transform duration-150\"\n :class=\"open ? 'rotate-180' : ''\"\n />\n </span>\n\n <div\n v-if=\"$slots.value\"\n class=\"absolute inset-y-0 left-3 right-9 flex items-center pointer-events-none\"\n >\n <slot\n name=\"value\"\n :value=\"modelValue\"\n :labels=\"selectedLabels\"\n :display-value=\"displayValue\"\n :path-labels=\"selectedPathLabels\"\n />\n </div>\n </div>\n\n <teleport to=\"body\">\n <transition\n enter-active-class=\"transition ease-out duration-150\"\n enter-from-class=\"transform opacity-0 scale-95\"\n enter-to-class=\"transform opacity-100 scale-100\"\n leave-active-class=\"transition ease-in duration-100\"\n leave-from-class=\"transform opacity-100 scale-100\"\n leave-to-class=\"transform opacity-0 scale-95\"\n >\n <div\n v-show=\"open\"\n ref=\"panelEl\"\n data-testid=\"ds-tree-select-panel\"\n data-ds-tree-select-panel\n class=\"fixed w-full\"\n :style=\"panelStyle\"\n >\n <div :class=\"panelClasses\">\n <div v-if=\"filterable\" class=\"p-2 border-b border-[var(--brd)]\">\n <GrInput\n ref=\"filterInputRef\"\n v-model=\"filterValue\"\n data-testid=\"ds-tree-select-filter\"\n data-ds-tree-select-filter\n type=\"search\"\n :inputmode=\"filterInputmode\"\n :placeholder=\"resolvedFilterPlaceholder\"\n size=\"sm\"\n />\n </div>\n\n <div\n class=\"p-1 overflow-auto\"\n :style=\"{ maxHeight: `${dropdownMaxHeight}px` }\"\n >\n <div v-if=\"(data?.length ?? 0) === 0\" class=\"px-3 py-2 text-[13px] text-[var(--muted-fg)]\">\n <slot name=\"empty\">\n {{ t('gr.treeSelect.empty', 'No data') }}\n </slot>\n </div>\n\n <GrTree\n v-else\n ref=\"treeRef\"\n :data=\"data\"\n :props=\"props.props\"\n :node-key=\"nodeKey as any\"\n :default-expanded-keys=\"defaultExpandedKeys\"\n :filter-node-method=\"filterNodeMethod\"\n :highlight-current=\"!multiple\"\n @node-click=\"onNodeClick\"\n >\n <template #default=\"{ node, data }\">\n <slot\n name=\"node\"\n :node=\"node\"\n :data=\"data\"\n :selected=\"selectedKeySet.has(node.key)\"\n >\n <div class=\"flex items-center gap-2 min-w-0\">\n <span\n class=\"inline-block h-4 w-4 shrink-0\"\n :class=\"selectedKeySet.has(node.key) ? 'i-lucide-check text-[var(--primary)]' : ''\"\n aria-hidden=\"true\"\n />\n <span class=\"truncate\">{{ node.label }}</span>\n </div>\n </slot>\n </template>\n </GrTree>\n </div>\n </div>\n </div>\n </transition>\n </teleport>\n </div>\n</template>\n"],"mappings":"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"}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/dist/components/GrEmptyState/chunks/{GrEmptyState-Dj2V5GaX.js → GrEmptyState-yOuZW7-t.js}
RENAMED
|
File without changes
|
/package/dist/components/GrFormFile/chunks/{GrFormFile-CIleXnfr.js → GrFormFile-CkR6cYqf.js}
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/dist/components/GrSkeleton/chunks/{GrSkeleton-URyMkBqI.js → GrSkeleton-B05K0QKh.js}
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|