@feugene/granularity 0.9.4 → 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-pUt19VGy.js.map → grSelectStyles-AjWWl007.js.map} +1 -1
- 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-BNDEqM8_.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-CnHdbPlf.js → GrSelect-DSz7jvUb.js} +25 -51
- 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 +6 -6
- 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/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-BNDEqM8_.js.map +0 -1
- package/dist/components/GrSelect/chunks/GrSelect-CnHdbPlf.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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GrToaster-C6_iHk2J.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-[var(--gr-z-toast)]` — верхний слой шкалы токенов (см. `styles/tokens.css`),\n * выше `GrModal` (`--gr-z-modal`), чтобы уведомления не перекрывались диалогом.\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-[var(--gr-z-toast)] 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-[var(--gr-z-toast)]` — верхний слой шкалы токенов (см. `styles/tokens.css`),\n * выше `GrModal` (`--gr-z-modal`), чтобы уведомления не перекрывались диалогом.\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-[var(--gr-z-toast)] 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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6CA,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,6EACE,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,3 +1,3 @@
|
|
|
1
|
-
import { n as grToasterSafelist, t as grToasterConfig } from "../../chunks/config-
|
|
2
|
-
import { t as GrToaster_default } from "./chunks/GrToaster-
|
|
1
|
+
import { n as grToasterSafelist, t as grToasterConfig } from "../../chunks/config-DkeLkzxj2.js";
|
|
2
|
+
import { t as GrToaster_default } from "./chunks/GrToaster-C6_iHk2J.js";
|
|
3
3
|
export { GrToaster_default as GrToaster, GrToaster_default as default, grToasterConfig, grToasterSafelist };
|
|
@@ -0,0 +1,109 @@
|
|
|
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 { t as useFloating } from "../../../chunks/useFloating-CLtbU7eD.js";
|
|
4
|
+
import { Teleport, Transition, computed, createBlock, createElementBlock, createElementVNode, createVNode, defineComponent, normalizeStyle, onUnmounted, openBlock, ref, renderSlot, toDisplayString, unref, useId, vShow, watch, withCtx, withDirectives } from "vue";
|
|
5
|
+
//#region src/components/GrTooltip/GrTooltip.vue?vue&type=script&setup=true&lang.ts
|
|
6
|
+
var _hoisted_1 = {
|
|
7
|
+
"data-ds-tooltip": "",
|
|
8
|
+
class: "relative inline-flex"
|
|
9
|
+
};
|
|
10
|
+
//#endregion
|
|
11
|
+
//#region src/components/GrTooltip/GrTooltip.vue
|
|
12
|
+
var GrTooltip_default = /* @__PURE__ */ defineComponent({
|
|
13
|
+
__name: "GrTooltip",
|
|
14
|
+
props: {
|
|
15
|
+
text: {},
|
|
16
|
+
iconColor: { default: "var(--muted-fg)" }
|
|
17
|
+
},
|
|
18
|
+
setup(__props) {
|
|
19
|
+
/**
|
|
20
|
+
* GrTooltip — DS-примитив инлайн-подсказки на hover/focus.
|
|
21
|
+
*
|
|
22
|
+
* По умолчанию триггер — иконка info; можно заменить через слот.
|
|
23
|
+
* A11y:
|
|
24
|
+
* - `role="tooltip"` связывается с триггером через уникальный `aria-describedby`;
|
|
25
|
+
* - подсказка закрывается по `Escape` (WCAG 1.4.13 «Content on Hover or Focus» —
|
|
26
|
+
* dismissible без необходимости двигать курсор/фокус);
|
|
27
|
+
* - панель не интерактивна (`pointer-events-none`), поэтому «hoverable»-требование
|
|
28
|
+
* того же критерия неприменимо — навести курсор на саму подсказку невозможно.
|
|
29
|
+
*
|
|
30
|
+
* Позиционирование — через общий `useFloating` (см. `composables/internal`):
|
|
31
|
+
* по умолчанию сверху по центру, но `flip` переворачивает подсказку вниз, если
|
|
32
|
+
* места над триггером не хватает, а `shift` не даёт ей вылезти за края viewport.
|
|
33
|
+
*/
|
|
34
|
+
const props = __props;
|
|
35
|
+
const tooltipId = `ds-tooltip-${useId()}`;
|
|
36
|
+
const triggerStyle = computed(() => ({ color: props.iconColor }));
|
|
37
|
+
const isClient = typeof window !== "undefined";
|
|
38
|
+
const open = ref(false);
|
|
39
|
+
const triggerEl = ref(null);
|
|
40
|
+
const panelEl = ref(null);
|
|
41
|
+
const { floatingStyle } = useFloating(triggerEl, panelEl, open, {
|
|
42
|
+
placement: "top",
|
|
43
|
+
zIndexVar: "--gr-z-tooltip"
|
|
44
|
+
});
|
|
45
|
+
function show() {
|
|
46
|
+
open.value = true;
|
|
47
|
+
}
|
|
48
|
+
function hide() {
|
|
49
|
+
open.value = false;
|
|
50
|
+
}
|
|
51
|
+
function closeOnEscape(e) {
|
|
52
|
+
if (e.key === "Escape") hide();
|
|
53
|
+
}
|
|
54
|
+
watch(open, (isOpen) => {
|
|
55
|
+
if (typeof document === "undefined") return;
|
|
56
|
+
document.removeEventListener("keydown", closeOnEscape);
|
|
57
|
+
if (isOpen) document.addEventListener("keydown", closeOnEscape);
|
|
58
|
+
}, { immediate: true });
|
|
59
|
+
onUnmounted(() => {
|
|
60
|
+
if (typeof document === "undefined") return;
|
|
61
|
+
document.removeEventListener("keydown", closeOnEscape);
|
|
62
|
+
});
|
|
63
|
+
return (_ctx, _cache) => {
|
|
64
|
+
return openBlock(), createElementBlock("span", _hoisted_1, [createElementVNode("span", {
|
|
65
|
+
ref_key: "triggerEl",
|
|
66
|
+
ref: triggerEl,
|
|
67
|
+
"data-ds-tooltip-trigger": "",
|
|
68
|
+
"data-testid": "ds-tooltip-trigger",
|
|
69
|
+
tabindex: "0",
|
|
70
|
+
"aria-describedby": tooltipId,
|
|
71
|
+
class: "inline-flex items-center justify-center focus:outline-none",
|
|
72
|
+
style: normalizeStyle(triggerStyle.value),
|
|
73
|
+
onMouseenter: show,
|
|
74
|
+
onMouseleave: hide,
|
|
75
|
+
onFocus: show,
|
|
76
|
+
onBlur: hide
|
|
77
|
+
}, [renderSlot(_ctx.$slots, "default", {}, () => [createVNode(unref(GrIcon_default), {
|
|
78
|
+
size: "sm",
|
|
79
|
+
"aria-hidden": "true"
|
|
80
|
+
}, {
|
|
81
|
+
default: withCtx(() => [createVNode(unref(info_default))]),
|
|
82
|
+
_: 1
|
|
83
|
+
})])], 36), (openBlock(), createBlock(Teleport, {
|
|
84
|
+
to: "body",
|
|
85
|
+
disabled: !isClient
|
|
86
|
+
}, [createVNode(Transition, {
|
|
87
|
+
"enter-active-class": "transition-opacity duration-150",
|
|
88
|
+
"enter-from-class": "opacity-0",
|
|
89
|
+
"enter-to-class": "opacity-100",
|
|
90
|
+
"leave-active-class": "transition-opacity duration-100",
|
|
91
|
+
"leave-from-class": "opacity-100",
|
|
92
|
+
"leave-to-class": "opacity-0"
|
|
93
|
+
}, {
|
|
94
|
+
default: withCtx(() => [withDirectives(createElementVNode("span", {
|
|
95
|
+
id: tooltipId,
|
|
96
|
+
ref_key: "panelEl",
|
|
97
|
+
ref: panelEl,
|
|
98
|
+
role: "tooltip",
|
|
99
|
+
"data-ds-tooltip-panel": "",
|
|
100
|
+
class: "pointer-events-none max-w-[280px] rounded-md border border-[var(--brd)] bg-[var(--popover)] px-2 py-1 text-[12px] text-[var(--popover-fg)] shadow-[var(--ds-shadow-1)]",
|
|
101
|
+
style: normalizeStyle(unref(floatingStyle))
|
|
102
|
+
}, toDisplayString(__props.text), 5), [[vShow, open.value]])]),
|
|
103
|
+
_: 1
|
|
104
|
+
})], 8, ["disabled"]))]);
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
//#endregion
|
|
109
|
+
export { GrTooltip_default as t };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GrTooltip-BC-40SA5.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:\n * - `role=\"tooltip\"` связывается с триггером через уникальный `aria-describedby`;\n * - подсказка закрывается по `Escape` (WCAG 1.4.13 «Content on Hover or Focus» —\n * dismissible без необходимости двигать курсор/фокус);\n * - панель не интерактивна (`pointer-events-none`), поэтому «hoverable»-требование\n * того же критерия неприменимо — навести курсор на саму подсказку невозможно.\n *\n * Позиционирование — через общий `useFloating` (см. `composables/internal`):\n * по умолчанию сверху по центру, но `flip` переворачивает подсказку вниз, если\n * места над триггером не хватает, а `shift` не даёт ей вылезти за края viewport.\n */\nimport { computed, onUnmounted, ref, useId, watch } from 'vue'\n\nimport GrIcon from '../GrIcon'\nimport { useFloating } from '../../composables/internal/useFloating'\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\nconst isClient = typeof window !== 'undefined'\n\nconst open = ref(false)\nconst triggerEl = ref<HTMLElement | null>(null)\nconst panelEl = ref<HTMLElement | null>(null)\n\nconst { floatingStyle } = useFloating(triggerEl, panelEl, open, {\n placement: 'top',\n zIndexVar: '--gr-z-tooltip',\n})\n\nfunction show(): void {\n open.value = true\n}\n\nfunction hide(): void {\n open.value = false\n}\n\nfunction closeOnEscape(e: KeyboardEvent): void {\n if (e.key === 'Escape') hide()\n}\n\nwatch(\n open,\n (isOpen) => {\n if (typeof document === 'undefined') return\n\n document.removeEventListener('keydown', closeOnEscape)\n if (isOpen) document.addEventListener('keydown', closeOnEscape)\n },\n { immediate: true },\n)\n\nonUnmounted(() => {\n if (typeof document === 'undefined') return\n document.removeEventListener('keydown', closeOnEscape)\n})\n</script>\n\n<template>\n <span data-ds-tooltip class=\"relative inline-flex\">\n <span\n ref=\"triggerEl\"\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 @mouseenter=\"show\"\n @mouseleave=\"hide\"\n @focus=\"show\"\n @blur=\"hide\"\n >\n <slot>\n <GrIcon size=\"sm\" aria-hidden=\"true\">\n <IconInfo />\n </GrIcon>\n </slot>\n </span>\n\n <teleport to=\"body\" :disabled=\"!isClient\">\n <transition\n enter-active-class=\"transition-opacity duration-150\"\n enter-from-class=\"opacity-0\"\n enter-to-class=\"opacity-100\"\n leave-active-class=\"transition-opacity duration-100\"\n leave-from-class=\"opacity-100\"\n leave-to-class=\"opacity-0\"\n >\n <span\n v-show=\"open\"\n :id=\"tooltipId\"\n ref=\"panelEl\"\n role=\"tooltip\"\n data-ds-tooltip-panel\n class=\"pointer-events-none max-w-[280px] rounded-md border border-[var(--brd)] bg-[var(--popover)] px-2 py-1 text-[12px] text-[var(--popover-fg)] shadow-[var(--ds-shadow-1)]\"\n :style=\"floatingStyle\"\n >\n {{ text }}\n </span>\n </transition>\n </teleport>\n </span>\n</template>\n","<script setup lang=\"ts\">\n/**\n * GrTooltip — DS-примитив инлайн-подсказки на hover/focus.\n *\n * По умолчанию триггер — иконка info; можно заменить через слот.\n * A11y:\n * - `role=\"tooltip\"` связывается с триггером через уникальный `aria-describedby`;\n * - подсказка закрывается по `Escape` (WCAG 1.4.13 «Content on Hover or Focus» —\n * dismissible без необходимости двигать курсор/фокус);\n * - панель не интерактивна (`pointer-events-none`), поэтому «hoverable»-требование\n * того же критерия неприменимо — навести курсор на саму подсказку невозможно.\n *\n * Позиционирование — через общий `useFloating` (см. `composables/internal`):\n * по умолчанию сверху по центру, но `flip` переворачивает подсказку вниз, если\n * места над триггером не хватает, а `shift` не даёт ей вылезти за края viewport.\n */\nimport { computed, onUnmounted, ref, useId, watch } from 'vue'\n\nimport GrIcon from '../GrIcon'\nimport { useFloating } from '../../composables/internal/useFloating'\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\nconst isClient = typeof window !== 'undefined'\n\nconst open = ref(false)\nconst triggerEl = ref<HTMLElement | null>(null)\nconst panelEl = ref<HTMLElement | null>(null)\n\nconst { floatingStyle } = useFloating(triggerEl, panelEl, open, {\n placement: 'top',\n zIndexVar: '--gr-z-tooltip',\n})\n\nfunction show(): void {\n open.value = true\n}\n\nfunction hide(): void {\n open.value = false\n}\n\nfunction closeOnEscape(e: KeyboardEvent): void {\n if (e.key === 'Escape') hide()\n}\n\nwatch(\n open,\n (isOpen) => {\n if (typeof document === 'undefined') return\n\n document.removeEventListener('keydown', closeOnEscape)\n if (isOpen) document.addEventListener('keydown', closeOnEscape)\n },\n { immediate: true },\n)\n\nonUnmounted(() => {\n if (typeof document === 'undefined') return\n document.removeEventListener('keydown', closeOnEscape)\n})\n</script>\n\n<template>\n <span data-ds-tooltip class=\"relative inline-flex\">\n <span\n ref=\"triggerEl\"\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 @mouseenter=\"show\"\n @mouseleave=\"hide\"\n @focus=\"show\"\n @blur=\"hide\"\n >\n <slot>\n <GrIcon size=\"sm\" aria-hidden=\"true\">\n <IconInfo />\n </GrIcon>\n </slot>\n </span>\n\n <teleport to=\"body\" :disabled=\"!isClient\">\n <transition\n enter-active-class=\"transition-opacity duration-150\"\n enter-from-class=\"opacity-0\"\n enter-to-class=\"opacity-100\"\n leave-active-class=\"transition-opacity duration-100\"\n leave-from-class=\"opacity-100\"\n leave-to-class=\"opacity-0\"\n >\n <span\n v-show=\"open\"\n :id=\"tooltipId\"\n ref=\"panelEl\"\n role=\"tooltip\"\n data-ds-tooltip-panel\n class=\"pointer-events-none max-w-[280px] rounded-md border border-[var(--brd)] bg-[var(--popover)] px-2 py-1 text-[12px] text-[var(--popover-fg)] shadow-[var(--ds-shadow-1)]\"\n :style=\"floatingStyle\"\n >\n {{ text }}\n </span>\n </transition>\n </teleport>\n </span>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6BA,MAAM,QAAQ;EAId,MAAM,YAAY,cAAc,OAAO;EAEvC,MAAM,eAAe,gBAAgB,EAAE,OAAO,MAAM,WAAW,EAAC;EAEhE,MAAM,WAAW,OAAO,WAAW;EAEnC,MAAM,OAAO,IAAI,MAAK;EACtB,MAAM,YAAY,IAAwB,KAAI;EAC9C,MAAM,UAAU,IAAwB,KAAI;EAE5C,MAAM,EAAE,kBAAkB,YAAY,WAAW,SAAS,MAAM;GAC9D,WAAW;GACX,WAAW;GACZ,CAAA;EAED,SAAS,OAAa;AACpB,QAAK,QAAQ;;EAGf,SAAS,OAAa;AACpB,QAAK,QAAQ;;EAGf,SAAS,cAAc,GAAwB;AAC7C,OAAI,EAAE,QAAQ,SAAU,OAAK;;AAG/B,QACE,OACC,WAAW;AACV,OAAI,OAAO,aAAa,YAAa;AAErC,YAAS,oBAAoB,WAAW,cAAa;AACrD,OAAI,OAAQ,UAAS,iBAAiB,WAAW,cAAa;KAEhE,EAAE,WAAW,MAAM,CACrB;AAEA,oBAAkB;AAChB,OAAI,OAAO,aAAa,YAAa;AACrC,YAAS,oBAAoB,WAAW,cAAa;IACtD;;uBAIC,mBA2CO,QA3CP,YA2CO,CA1CL,mBAkBO,QAAA;aAjBD;IAAJ,KAAI;IACJ,2BAAA;IACA,eAAY;IACZ,UAAS;IACR,oBAAkB;IACnB,OAAM;IACL,OAAK,eAAE,aAAA,MAAY;IACnB,cAAY;IACZ,cAAY;IACZ,SAAO;IACP,QAAM;OAEP,WAIO,KAAA,QAAA,WAAA,EAAA,QAAA,CAHL,YAES,MAAA,eAAA,EAAA;IAFD,MAAK;IAAK,eAAY;;2BAChB,CAAZ,YAAY,MAAA,aAAA,CAAA,CAAA,CAAA;;6BAKlB,YAqBW,UAAA;IArBD,IAAG;IAAQ,UAAQ,CAAG;OAC9B,YAmBa,YAAA;IAlBX,sBAAmB;IACnB,oBAAiB;IACjB,kBAAe;IACf,sBAAmB;IACnB,oBAAiB;IACjB,kBAAe;;2BAYR,CAAA,eAVP,mBAUO,QAAA;KARJ,IAAI;cACD;KAAJ,KAAI;KACJ,MAAK;KACL,yBAAA;KACA,OAAM;KACL,OAAK,eAAE,MAAA,cAAa,CAAA;uBAElB,QAAA,KAAI,EAAA,EAAA,EAAA,CAAA,CAAA,OARC,KAAA,MAAI,CAAA,CAAA,CAAA,CAAA"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { t as GrTooltip_default } from "./chunks/GrTooltip-
|
|
2
|
-
import { t as grTooltipConfig } from "../../chunks/config-
|
|
1
|
+
import { t as GrTooltip_default } from "./chunks/GrTooltip-BC-40SA5.js";
|
|
2
|
+
import { t as grTooltipConfig } from "../../chunks/config-Dl5aZ5VR.js";
|
|
3
3
|
export { GrTooltip_default as GrTooltip, GrTooltip_default as default, grTooltipConfig };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GrTree-B2SMU5Py.js","names":[],"sources":["../../../../src/components/GrTree/grTreeDataAdapter.ts","../../../../src/components/GrTree/grTreeInteractionContext.ts","../../../../src/components/GrTree/grTreeStore.ts","../../../../src/components/GrTree/GrTree.vue","../../../../src/components/GrTree/GrTree.vue"],"sourcesContent":["import type { GrTreeKey } from './grTreeTypes'\nimport type {\n GrTreeDataProps,\n GrTreePropsMap,\n} from './grTreeProps'\n\nconst DEFAULT_CHILDREN_KEY = 'children'\nconst DEFAULT_LABEL_KEY = 'label'\n\nexport type GrTreeDataAdapterOptions<T extends object> = Pick<GrTreeDataProps<T>, 'props' | 'nodeKey'>\n\nexport type GrTreeDataAdapter<T extends object> = {\n hasNodeKey: () => boolean\n getChildrenKey: () => string\n getLabelKey: () => string\n getLabel: (data: T) => string\n getChildren: (data: T) => T[]\n ensureChildren: (data: T) => T[]\n getNodeKey: (data: T, index: number, parentKey: GrTreeKey | undefined) => GrTreeKey\n getExplicitNodeKey: (data: T) => GrTreeKey | undefined\n}\n\nfunction isTreeKey(value: unknown): value is GrTreeKey {\n return typeof value === 'string' || typeof value === 'number'\n}\n\nfunction resolveMapValue(map: GrTreePropsMap | undefined, key: keyof GrTreePropsMap, fallback: string) {\n return map?.[key] ?? fallback\n}\n\nexport function createGrTreeDataAdapter<T extends Record<string, any> = any>(\n options: GrTreeDataAdapterOptions<T>,\n): GrTreeDataAdapter<T> {\n function hasNodeKey() {\n return options.nodeKey != null\n }\n\n function getChildrenKey() {\n return resolveMapValue(options.props, 'children', DEFAULT_CHILDREN_KEY)\n }\n\n function getLabelKey() {\n return resolveMapValue(options.props, 'label', DEFAULT_LABEL_KEY)\n }\n\n function getLabel(data: T): string {\n const key = getLabelKey() as keyof T\n const value = data[key]\n return value == null ? '' : String(value)\n }\n\n function getChildren(data: T): T[] {\n const key = getChildrenKey() as keyof T\n const value = data[key]\n return Array.isArray(value) ? (value as T[]) : []\n }\n\n function ensureChildren(data: T): T[] {\n const key = getChildrenKey()\n const value = (data as Record<string, unknown>)[key]\n if (Array.isArray(value))\n return value as T[]\n\n const children: T[] = []\n ;(data as Record<string, unknown>)[key] = children\n return children\n }\n\n function getExplicitNodeKey(data: T): GrTreeKey | undefined {\n if (options.nodeKey == null)\n return undefined\n\n const keyName = options.nodeKey as keyof T\n const value = data[keyName] as unknown\n return isTreeKey(value) ? value : undefined\n }\n\n function getNodeKey(data: T, index: number, parentKey: GrTreeKey | undefined): GrTreeKey {\n const explicitKey = getExplicitNodeKey(data)\n if (explicitKey != null)\n return explicitKey\n\n return parentKey == null ? index : `${String(parentKey)}:${index}`\n }\n\n return {\n hasNodeKey,\n getChildrenKey,\n getLabelKey,\n getLabel,\n getChildren,\n ensureChildren,\n getNodeKey,\n getExplicitNodeKey,\n }\n}","import type { Ref, ShallowRef } from 'vue'\nimport { ref, shallowRef } from 'vue'\nimport type {\n GrTreeAllowDropType,\n GrTreeKey,\n GrTreeNode,\n GrTreeNodeDropType,\n} from './grTreeTypes'\n\nexport type GrTreeDropTarget = {\n key: GrTreeKey\n type: GrTreeNodeDropType\n allowed: boolean\n}\n\nexport type GrTreeInteractionOptions<T> = {\n draggable?: boolean\n allowDrop?: (draggingNode: GrTreeNode<T>, dropNode: GrTreeNode<T>, type: GrTreeAllowDropType) => boolean\n allowDrag?: (draggingNode: GrTreeNode<T>) => boolean\n}\n\nexport type GrTreeInteractionEmitters<T> = {\n emitNodeClick: (data: T, node: GrTreeNode<T>) => void\n emitNodeExpand: (data: T, node: GrTreeNode<T>) => void\n emitNodeCollapse: (data: T, node: GrTreeNode<T>) => void\n emitNodeDrop: (draggingNode: GrTreeNode<T>, dropNode: GrTreeNode<T>, dropType: GrTreeNodeDropType) => void\n}\n\nexport type GrTreeInteractionContext<T> = {\n hoveredKey: Ref<GrTreeKey | undefined>\n draggingNode: ShallowRef<GrTreeNode<T> | null>\n dropTarget: ShallowRef<GrTreeDropTarget | null>\n canDrag: (node: GrTreeNode<T>) => boolean\n canDrop: (drag: GrTreeNode<T>, target: GrTreeNode<T>, type: GrTreeAllowDropType) => boolean\n resetDragState: () => void\n emitNodeClick: (data: T, node: GrTreeNode<T>) => void\n emitNodeExpand: (data: T, node: GrTreeNode<T>) => void\n emitNodeCollapse: (data: T, node: GrTreeNode<T>) => void\n emitNodeDrop: (draggingNode: GrTreeNode<T>, dropNode: GrTreeNode<T>, dropType: GrTreeNodeDropType) => void\n}\n\nexport function createGrTreeInteractionContext<T>(\n options: GrTreeInteractionOptions<T>,\n emitters: GrTreeInteractionEmitters<T>,\n): GrTreeInteractionContext<T> {\n const hoveredKey = ref<GrTreeKey | undefined>(undefined)\n const draggingNode = shallowRef<GrTreeNode<T> | null>(null)\n const dropTarget = shallowRef<GrTreeDropTarget | null>(null)\n\n function canDrag(node: GrTreeNode<T>): boolean {\n if (!options.draggable)\n return false\n\n if (options.allowDrag)\n return options.allowDrag(node)\n\n return true\n }\n\n function canDrop(drag: GrTreeNode<T>, target: GrTreeNode<T>, type: GrTreeAllowDropType): boolean {\n if (!options.allowDrop)\n return true\n\n return options.allowDrop(drag, target, type)\n }\n\n function resetDragState() {\n draggingNode.value = null\n dropTarget.value = null\n }\n\n return {\n hoveredKey,\n draggingNode,\n dropTarget,\n canDrag,\n canDrop,\n resetDragState,\n ...emitters,\n }\n}","import type { ComputedRef, MaybeRefOrGetter, Ref, ShallowRef } from 'vue'\nimport { computed, ref, shallowRef, toValue, watch } from 'vue'\nimport type {\n GrTreeKey,\n GrTreeNode,\n GrTreeNodeDropType,\n GrTreeNodeTarget,\n} from './grTreeTypes'\nimport type { GrTreeDataAdapter } from './grTreeDataAdapter'\nimport type { GrTreeDataProps, GrTreeFilterNodeMethod } from './grTreeProps'\n\ntype TreeModel<T extends object> = {\n roots: GrTreeNode<T>[]\n byKey: Map<GrTreeKey, GrTreeNode<T>>\n byData: WeakMap<T, GrTreeNode<T>>\n}\n\ntype FilterInfo = {\n isActive: boolean\n subtreeHasMatch: Map<GrTreeKey, boolean>\n matchedKeys: Set<GrTreeKey>\n autoExpandKeys: Set<GrTreeKey>\n}\n\nexport type GrTreeStoreOptions<T extends object> = {\n data: MaybeRefOrGetter<GrTreeDataProps<T>['data']>\n defaultExpandedKeys?: MaybeRefOrGetter<GrTreeDataProps<T>['defaultExpandedKeys']>\n filterNodeMethod?: MaybeRefOrGetter<GrTreeFilterNodeMethod<T> | undefined>\n adapter: GrTreeDataAdapter<T>\n}\n\nexport type GrTreeStore<T extends object> = {\n filterValue: Ref<string>\n expandedKeys: ShallowRef<Set<GrTreeKey>>\n currentKey: Ref<GrTreeKey | undefined>\n treeModel: ComputedRef<TreeModel<T>>\n filterInfo: ComputedRef<FilterInfo>\n filter: (value: string) => void\n isExpandedKey: (key: GrTreeKey) => boolean\n setExpandedKey: (key: GrTreeKey, expanded: boolean) => void\n toggleExpand: (node: GrTreeNode<T>) => void\n setCurrentKey: (key?: GrTreeKey) => void\n getCurrentKey: () => GrTreeKey | undefined\n getCurrentNode: () => GrTreeNode<T> | undefined\n setCurrentNode: (node?: GrTreeNodeTarget<T>) => boolean\n getNode: (key: GrTreeKey) => GrTreeNode<T> | undefined\n canMoveNode: (node: GrTreeNodeTarget<T>, referenceNode: GrTreeNodeTarget<T>, dropType: GrTreeNodeDropType) => boolean\n moveNode: (node: GrTreeNodeTarget<T>, referenceNode: GrTreeNodeTarget<T>, dropType: GrTreeNodeDropType) => GrTreeNode<T> | undefined\n appendNode: (data: T, parent: GrTreeNodeTarget<T>) => GrTreeNode<T> | undefined\n removeNode: (node: GrTreeNodeTarget<T>) => boolean\n insertNodeBefore: (data: T, referenceNode: GrTreeNodeTarget<T>) => GrTreeNode<T> | undefined\n insertNodeAfter: (data: T, referenceNode: GrTreeNodeTarget<T>) => GrTreeNode<T> | undefined\n}\n\nexport function createGrTreeStore<T extends Record<string, any> = any>(\n options: GrTreeStoreOptions<T>,\n): GrTreeStore<T> {\n const filterValue = ref('')\n const expandedKeys = shallowRef<Set<GrTreeKey>>(new Set())\n const currentKey = ref<GrTreeKey | undefined>(undefined)\n const getData = () => toValue(options.data) ?? []\n const getFilterNodeMethod = () => toValue(options.filterNodeMethod)\n\n watch(\n () => toValue(options.defaultExpandedKeys),\n (keys) => {\n expandedKeys.value = new Set(keys ?? [])\n },\n { immediate: true },\n )\n\n const treeModel = computed<TreeModel<T>>(() => {\n const byKey = new Map<GrTreeKey, GrTreeNode<T>>()\n const byData = new WeakMap<T, GrTreeNode<T>>()\n\n const build = (items: T[], parent: GrTreeNode<T> | undefined, level: number): GrTreeNode<T>[] => {\n return items.map((item, index) => {\n const node: GrTreeNode<T> = {\n key: options.adapter.getNodeKey(item, index, parent?.key),\n label: options.adapter.getLabel(item),\n data: item,\n level,\n parent,\n childNodes: [],\n }\n\n byKey.set(node.key, node)\n byData.set(item, node)\n node.childNodes = build(options.adapter.getChildren(item), node, level + 1)\n\n return node\n })\n }\n\n return {\n roots: build(getData(), undefined, 1),\n byKey,\n byData,\n }\n })\n\n const filterInfo = computed<FilterInfo>(() => {\n const value = filterValue.value\n const isActive = value.trim().length > 0\n const valueLower = value.toLowerCase()\n const subtreeHasMatch = new Map<GrTreeKey, boolean>()\n const matchedKeys = new Set<GrTreeKey>()\n const autoExpandKeys = new Set<GrTreeKey>()\n\n if (!isActive) {\n return {\n isActive,\n subtreeHasMatch,\n matchedKeys,\n autoExpandKeys,\n }\n }\n\n const match = (node: GrTreeNode<T>): boolean => {\n const filterNodeMethod = getFilterNodeMethod()\n if (filterNodeMethod)\n return filterNodeMethod(value, node.data, node)\n\n return node.label.toLowerCase().includes(valueLower)\n }\n\n const walk = (nodes: GrTreeNode<T>[]): boolean => {\n let any = false\n\n for (const node of nodes) {\n const self = match(node)\n const childAny = walk(node.childNodes)\n const has = self || childAny\n\n subtreeHasMatch.set(node.key, has)\n\n if (self)\n matchedKeys.add(node.key)\n\n if (childAny)\n autoExpandKeys.add(node.key)\n\n any ||= has\n }\n\n return any\n }\n\n walk(treeModel.value.roots)\n\n return {\n isActive,\n subtreeHasMatch,\n matchedKeys,\n autoExpandKeys,\n }\n })\n\n function getNode(key: GrTreeKey) {\n return treeModel.value.byKey.get(key)\n }\n\n function findNodeByData(data: T): GrTreeNode<T> | undefined {\n return treeModel.value.byData.get(data)\n }\n\n function isTreeNode(target: GrTreeNodeTarget<T>): target is GrTreeNode<T> {\n return typeof target === 'object'\n && target !== null\n && 'key' in target\n && 'data' in target\n && 'childNodes' in target\n }\n\n function resolveNodeTarget(target?: GrTreeNodeTarget<T>): GrTreeNode<T> | undefined {\n if (target == null)\n return undefined\n\n if (typeof target === 'string' || typeof target === 'number')\n return getNode(target)\n\n if (isTreeNode(target))\n return getNode(target.key) ?? target\n\n const key = options.adapter.getExplicitNodeKey(target)\n if (key != null)\n return getNode(key)\n\n return findNodeByData(target)\n }\n\n function getNodeContainer(node: GrTreeNode<T>) {\n const items = node.parent ? options.adapter.ensureChildren(node.parent.data) : getData()\n\n let index = items.findIndex(item => item === node.data)\n if (index >= 0)\n return { items, index }\n\n const key = options.adapter.getExplicitNodeKey(node.data)\n if (key == null)\n return undefined\n\n index = items.findIndex(item => options.adapter.getExplicitNodeKey(item) === key)\n if (index < 0)\n return undefined\n\n return { items, index }\n }\n\n function isDescendantNode(ancestor: GrTreeNode<T>, node: GrTreeNode<T>) {\n let current = node.parent\n\n while (current) {\n if (current.key === ancestor.key)\n return true\n\n current = current.parent\n }\n\n return false\n }\n\n function canMoveNode(node: GrTreeNodeTarget<T>, referenceNode: GrTreeNodeTarget<T>, dropType: GrTreeNodeDropType) {\n const sourceNode = resolveNodeTarget(node)\n const targetNode = resolveNodeTarget(referenceNode)\n\n if (!sourceNode || !targetNode)\n return false\n\n if (sourceNode.key === targetNode.key)\n return false\n\n if (isDescendantNode(sourceNode, targetNode))\n return false\n\n const sourceContainer = getNodeContainer(sourceNode)\n if (!sourceContainer)\n return false\n\n if (dropType === 'inner')\n return true\n\n return Boolean(getNodeContainer(targetNode))\n }\n\n function sanitizeTreeState() {\n const byKey = treeModel.value.byKey\n\n if (currentKey.value != null && !byKey.has(currentKey.value))\n currentKey.value = undefined\n\n const nextExpandedKeys = new Set(Array.from(expandedKeys.value).filter(key => byKey.has(key)))\n if (nextExpandedKeys.size !== expandedKeys.value.size)\n expandedKeys.value = nextExpandedKeys\n }\n\n function isExpandedKey(key: GrTreeKey): boolean {\n return expandedKeys.value.has(key)\n }\n\n function setExpandedKey(key: GrTreeKey, expanded: boolean) {\n const next = new Set(expandedKeys.value)\n\n if (expanded)\n next.add(key)\n else\n next.delete(key)\n\n expandedKeys.value = next\n }\n\n function toggleExpand(node: GrTreeNode<T>) {\n setExpandedKey(node.key, !isExpandedKey(node.key))\n }\n\n function setCurrentKey(key?: GrTreeKey) {\n currentKey.value = key\n }\n\n function getCurrentKey() {\n return currentKey.value\n }\n\n function getCurrentNode() {\n const key = currentKey.value\n return key == null ? undefined : getNode(key)\n }\n\n function setCurrentNode(node?: GrTreeNodeTarget<T>) {\n if (node == null) {\n currentKey.value = undefined\n return true\n }\n\n const targetNode = resolveNodeTarget(node)\n if (!targetNode)\n return false\n\n currentKey.value = targetNode.key\n return true\n }\n\n function resolveInsertedNode(data: T) {\n const key = options.adapter.getExplicitNodeKey(data)\n if (key != null)\n return getNode(key)\n\n return findNodeByData(data)\n }\n\n function moveNode(node: GrTreeNodeTarget<T>, referenceNode: GrTreeNodeTarget<T>, dropType: GrTreeNodeDropType) {\n const sourceNode = resolveNodeTarget(node)\n const targetNode = resolveNodeTarget(referenceNode)\n\n if (!sourceNode || !targetNode)\n return undefined\n\n if (!canMoveNode(sourceNode, targetNode, dropType))\n return undefined\n\n const sourceContainer = getNodeContainer(sourceNode)\n if (!sourceContainer)\n return undefined\n\n let destinationItems: T[]\n let destinationIndex: number\n\n if (dropType === 'inner') {\n destinationItems = options.adapter.ensureChildren(targetNode.data)\n destinationIndex = destinationItems.length\n }\n else {\n const targetContainer = getNodeContainer(targetNode)\n if (!targetContainer)\n return undefined\n\n destinationItems = targetContainer.items\n destinationIndex = dropType === 'prev'\n ? targetContainer.index\n : targetContainer.index + 1\n }\n\n if (destinationItems === sourceContainer.items && sourceContainer.index < destinationIndex)\n destinationIndex -= 1\n\n const [movedData] = sourceContainer.items.splice(sourceContainer.index, 1)\n destinationItems.splice(destinationIndex, 0, movedData)\n\n if (dropType === 'inner')\n setExpandedKey(targetNode.key, true)\n\n sanitizeTreeState()\n return resolveInsertedNode(movedData)\n }\n\n function appendNode(data: T, parent: GrTreeNodeTarget<T>) {\n const parentNode = resolveNodeTarget(parent)\n if (!parentNode)\n return undefined\n\n options.adapter.ensureChildren(parentNode.data).push(data)\n setExpandedKey(parentNode.key, true)\n sanitizeTreeState()\n return resolveInsertedNode(data)\n }\n\n function removeNode(node: GrTreeNodeTarget<T>) {\n if (!options.adapter.hasNodeKey())\n return false\n\n const targetNode = resolveNodeTarget(node)\n if (!targetNode)\n return false\n\n const container = getNodeContainer(targetNode)\n if (!container)\n return false\n\n container.items.splice(container.index, 1)\n sanitizeTreeState()\n return true\n }\n\n function insertNodeBefore(data: T, referenceNode: GrTreeNodeTarget<T>) {\n const targetNode = resolveNodeTarget(referenceNode)\n if (!targetNode)\n return undefined\n\n const container = getNodeContainer(targetNode)\n if (!container)\n return undefined\n\n container.items.splice(container.index, 0, data)\n sanitizeTreeState()\n return resolveInsertedNode(data)\n }\n\n function insertNodeAfter(data: T, referenceNode: GrTreeNodeTarget<T>) {\n const targetNode = resolveNodeTarget(referenceNode)\n if (!targetNode)\n return undefined\n\n const container = getNodeContainer(targetNode)\n if (!container)\n return undefined\n\n container.items.splice(container.index + 1, 0, data)\n sanitizeTreeState()\n return resolveInsertedNode(data)\n }\n\n function filter(value: string) {\n filterValue.value = value\n }\n\n return {\n filterValue,\n expandedKeys,\n currentKey,\n treeModel,\n filterInfo,\n filter,\n isExpandedKey,\n setExpandedKey,\n toggleExpand,\n setCurrentKey,\n getCurrentKey,\n getCurrentNode,\n setCurrentNode,\n getNode,\n canMoveNode,\n moveNode,\n appendNode,\n removeNode,\n insertNodeBefore,\n insertNodeAfter,\n }\n}","<script setup lang=\"ts\" generic=\"T extends Record<string, any> = any\">\nimport { computed } from 'vue'\nimport type {\n GrTreeAllowDropType,\n GrTreeInstance,\n GrTreeNode,\n GrTreeNodeDropType,\n} from './grTreeTypes'\nimport { createGrTreeDataAdapter } from './grTreeDataAdapter'\nimport { createGrTreeInteractionContext } from './grTreeInteractionContext'\nimport { createGrTreeStore } from './grTreeStore'\nimport type {\n GrTreeBranchLineColor,\n GrTreeNodeClass,\n GrTreeProps,\n GrTreeVisibleRow,\n GrTreeVisibleTreeRow,\n} from './grTreeProps'\n\ndefineOptions({\n name: 'GrTree',\n})\n\nconst DEFAULT_BRANCH_LINE_COLOR = 'var(--ds-tree-branch-line-default-color, #e2e8f0)'\n\nconst props = withDefaults(defineProps<GrTreeProps<T>>(), {\n props: () => ({\n children: 'children',\n label: 'label',\n }),\n nodeKey: 'id' as any,\n defaultExpandedKeys: () => [],\n highlightCurrent: true,\n indent: 0,\n expandIcon: 'i-lucide-chevron-right',\n collapseIcon: 'i-lucide-chevron-right',\n toggleIconRotate: true,\n branchLine: false,\n branchLineColor: undefined,\n branchLineActiveColor: undefined,\n draggable: false,\n dragHandleIcon: 'i-lucide-grip-vertical',\n dragLabel: 'Drag',\n expandLabel: 'Expand',\n collapseLabel: 'Collapse',\n rowClass: undefined,\n dragHandleClass: undefined,\n toggleClass: undefined,\n toggleIconClass: undefined,\n toggleSpacerClass: undefined,\n contentClass: undefined,\n internalRows: undefined,\n internalNested: false,\n internalStore: undefined,\n})\n\nconst emit = defineEmits<{\n (event: 'nodeClick', data: T, node: GrTreeNode<T>): void\n (event: 'nodeExpand', data: T, node: GrTreeNode<T>): void\n (event: 'nodeCollapse', data: T, node: GrTreeNode<T>): void\n (event: 'nodeDrop', draggingNode: GrTreeNode<T>, dropNode: GrTreeNode<T>, dropType: GrTreeNodeDropType): void\n}>()\n\ndefineSlots<{\n default?: (props: { node: GrTreeNode<T>; data: T }) => any\n}>()\n\nconst dataAdapter = createGrTreeDataAdapter(props)\nconst treeStore = props.internalStore ?? createGrTreeStore({\n adapter: dataAdapter,\n data: () => props.data,\n defaultExpandedKeys: () => props.defaultExpandedKeys,\n filterNodeMethod: () => props.filterNodeMethod,\n})\nconst interactionContext = props.internalInteractionContext ?? createGrTreeInteractionContext(props, {\n emitNodeClick: (data, node) => emit('nodeClick', data, node),\n emitNodeExpand: (data, node) => emit('nodeExpand', data, node),\n emitNodeCollapse: (data, node) => emit('nodeCollapse', data, node),\n emitNodeDrop: (draggingNode, dropNode, dropType) => emit('nodeDrop', draggingNode, dropNode, dropType),\n})\n\nconst treeProps = props as Readonly<GrTreeProps<T>>\nconst currentKey = treeStore.currentKey\nconst hoveredKey = interactionContext.hoveredKey\nconst dropTarget = interactionContext.dropTarget\n\nconst visibleRows = computed<GrTreeVisibleTreeRow<T>[]>(() => {\n if (props.internalRows)\n return props.internalRows\n\n const { roots } = treeStore.treeModel.value\n const { isActive, subtreeHasMatch, matchedKeys, autoExpandKeys } = treeStore.filterInfo.value\n\n const walk = (nodes: GrTreeNode<T>[]): GrTreeVisibleTreeRow<T>[] => {\n const rows: GrTreeVisibleTreeRow<T>[] = []\n\n for (const node of nodes) {\n if (isActive && !subtreeHasMatch.get(node.key))\n continue\n\n const isLeaf = node.childNodes.length === 0\n const isMatched = matchedKeys.has(node.key)\n const isExpanded = treeStore.isExpandedKey(node.key) || (isActive && autoExpandKeys.has(node.key))\n\n rows.push({\n node,\n isExpanded,\n isLeaf,\n isMatched,\n children: isExpanded ? walk(node.childNodes) : [],\n })\n }\n\n return rows\n }\n\n return walk(roots)\n})\n\nfunction onRowClick(node: GrTreeNode<T>) {\n treeStore.setCurrentKey(node.key)\n interactionContext.emitNodeClick(node.data, node)\n}\n\nfunction onRowMouseEnter(node: GrTreeNode<T>) {\n hoveredKey.value = node.key\n}\n\nfunction onRowMouseLeave(node: GrTreeNode<T>) {\n if (hoveredKey.value === node.key)\n hoveredKey.value = undefined\n}\n\nfunction toggleExpand(node: GrTreeNode<T>) {\n const expanded = !treeStore.isExpandedKey(node.key)\n treeStore.toggleExpand(node)\n\n if (expanded)\n interactionContext.emitNodeExpand(node.data, node)\n else\n interactionContext.emitNodeCollapse(node.data, node)\n}\n\n// Drag & drop\nfunction canDrag(node: GrTreeNode<T>): boolean {\n return interactionContext.canDrag(node)\n}\n\nfunction shouldShowDragHandle(node: GrTreeNode<T>): boolean {\n return canDrag(node) && hoveredKey.value === node.key\n}\n\nfunction resolveDropType(evt: DragEvent, el: HTMLElement): GrTreeNodeDropType {\n const rect = el.getBoundingClientRect()\n const y = evt.clientY - rect.top\n const third = rect.height / 3\n if (y < third)\n return 'prev'\n if (y > third * 2)\n return 'next'\n return 'inner'\n}\n\nfunction canDrop(drag: GrTreeNode<T>, target: GrTreeNode<T>, type: GrTreeAllowDropType): boolean {\n return interactionContext.canDrop(drag, target, type)\n}\n\nfunction onDragStart(evt: DragEvent, node: GrTreeNode<T>) {\n if (!canDrag(node)) {\n evt.preventDefault()\n return\n }\n\n interactionContext.draggingNode.value = node\n interactionContext.dropTarget.value = null\n try {\n evt.dataTransfer?.setData('text/plain', String(node.key))\n }\n catch {\n // ignore\n }\n if (evt.dataTransfer)\n evt.dataTransfer.effectAllowed = 'move'\n}\n\nfunction onDragEnd() {\n interactionContext.resetDragState()\n}\n\nfunction onDragOver(evt: DragEvent, node: GrTreeNode<T>, rowEl: HTMLElement) {\n const drag = interactionContext.draggingNode.value\n if (!treeProps.draggable || !drag)\n return\n\n // required for `drop` to fire\n evt.preventDefault()\n\n const type = resolveDropType(evt, rowEl)\n const allowed = treeStore.canMoveNode(drag, node, type) && canDrop(drag, node, type)\n interactionContext.dropTarget.value = { key: node.key, type, allowed }\n if (evt.dataTransfer)\n evt.dataTransfer.dropEffect = allowed ? 'move' : 'none'\n}\n\nfunction onDrop(evt: DragEvent, node: GrTreeNode<T>) {\n const drag = interactionContext.draggingNode.value\n const target = interactionContext.dropTarget.value\n if (!treeProps.draggable || !drag || !target)\n return\n\n evt.preventDefault()\n\n if (target.key === node.key && target.allowed) {\n const movedNode = treeStore.moveNode(drag, node, target.type)\n if (movedNode) {\n const dropNode = treeStore.getNode(node.key) ?? node\n interactionContext.emitNodeDrop(movedNode, dropNode, target.type)\n }\n }\n\n interactionContext.resetDragState()\n}\n\nfunction filter(value: string) {\n treeStore.filter(value)\n}\n\nfunction resolveNodeClass(classValue: GrTreeNodeClass<T> | undefined, row: GrTreeVisibleRow<T>) {\n if (!classValue)\n return undefined\n\n return typeof classValue === 'function'\n ? classValue(row)\n : classValue\n}\n\nfunction resolveBranchLineColorValue(color: GrTreeBranchLineColor<T> | undefined, node: GrTreeNode<T>) {\n if (!color)\n return undefined\n\n return typeof color === 'function'\n ? color(node) ?? undefined\n : color\n}\n\nfunction isBranchLineActive(node: GrTreeNode<T>) {\n const selectedKey = currentKey.value\n\n if (selectedKey == null)\n return false\n\n if (node.key === selectedKey)\n return true\n\n return node.childNodes.some(child => child.key === selectedKey && !treeStore.isExpandedKey(child.key))\n}\n\nfunction resolveBranchLineColor(node: GrTreeNode<T>) {\n const defaultColor = resolveBranchLineColorValue(treeProps.branchLineColor, node) ?? DEFAULT_BRANCH_LINE_COLOR\n\n if (!isBranchLineActive(node))\n return defaultColor\n\n return resolveBranchLineColorValue(treeProps.branchLineActiveColor, node) ?? defaultColor\n}\n\nfunction resolveChildrenWrapStyle(row: GrTreeVisibleTreeRow<T>) {\n if (!treeProps.branchLine)\n return {\n }\n\n return {\n '--ds-tree-branch-line-color': resolveBranchLineColor(row.node),\n }\n}\n\ndefineExpose<GrTreeInstance<T>>({\n appendNode: treeStore.appendNode,\n filter,\n getCurrentNode: treeStore.getCurrentNode,\n setCurrentKey: treeStore.setCurrentKey,\n getCurrentKey: treeStore.getCurrentKey,\n getNode: treeStore.getNode,\n insertNodeAfter: treeStore.insertNodeAfter,\n insertNodeBefore: treeStore.insertNodeBefore,\n removeNode: treeStore.removeNode,\n setCurrentNode: treeStore.setCurrentNode,\n})\n</script>\n\n<template>\n <div\n :data-ds-tree=\"props.internalNested ? undefined : ''\"\n :class=\"props.internalNested ? 'ds-tree__children' : 'ds-tree'\"\n :role=\"props.internalNested ? 'group' : 'tree'\"\n >\n <div\n v-for=\"row in visibleRows\"\n :key=\"row.node.key\"\n data-ds-tree-node\n role=\"treeitem\"\n :aria-level=\"row.node.level\"\n :aria-expanded=\"row.isLeaf ? undefined : row.isExpanded\"\n >\n <div\n data-ds-tree-row\n class=\"ds-tree__row py-2 px-2\"\n :class=\"[\n treeProps.highlightCurrent && currentKey === row.node.key ? 'ds-tree__row--current' : '',\n row.isMatched ? 'ds-tree__row--matched' : '',\n dropTarget?.key === row.node.key && dropTarget.allowed && dropTarget.type === 'inner' ? 'ds-tree__row--drop-inner' : '',\n dropTarget?.key === row.node.key && dropTarget.allowed && dropTarget.type === 'prev' ? 'ds-tree__row--drop-prev' : '',\n dropTarget?.key === row.node.key && dropTarget.allowed && dropTarget.type === 'next' ? 'ds-tree__row--drop-next' : '',\n resolveNodeClass(treeProps.rowClass, row),\n ]\"\n tabindex=\"0\"\n @click=\"onRowClick(row.node)\"\n @drop=\"onDrop($event, row.node)\"\n @dragover=\"onDragOver($event, row.node, $event.currentTarget as HTMLElement)\"\n @mouseenter=\"onRowMouseEnter(row.node)\"\n @mouseleave=\"onRowMouseLeave(row.node)\"\n >\n <button\n v-if=\"treeProps.draggable\"\n type=\"button\"\n data-ds-tree-drag-handle\n class=\"ds-tree__drag-handle\"\n :class=\"[\n shouldShowDragHandle(row.node) ? 'ds-tree__drag-handle--visible' : '',\n canDrag(row.node) ? '' : 'ds-tree__drag-handle--disabled',\n resolveNodeClass(treeProps.dragHandleClass, row),\n ]\"\n :aria-label=\"treeProps.dragLabel\"\n :draggable=\"canDrag(row.node)\"\n @click.stop\n @mousedown.stop\n @dragstart=\"onDragStart($event, row.node)\"\n @dragend=\"onDragEnd\"\n >\n <span class=\"ds-tree__drag-icon\" :class=\"treeProps.dragHandleIcon\" />\n </button>\n\n <button\n v-if=\"!row.isLeaf\"\n data-ds-tree-toggle\n type=\"button\"\n class=\"ds-tree__toggle\"\n :class=\"resolveNodeClass(treeProps.toggleClass, row)\"\n :aria-label=\"row.isExpanded ? treeProps.collapseLabel : treeProps.expandLabel\"\n @click.stop=\"toggleExpand(row.node)\"\n >\n <span\n class=\"ds-tree__toggle-icon\"\n :class=\"[\n row.isExpanded ? treeProps.collapseIcon : treeProps.expandIcon,\n row.isExpanded && treeProps.toggleIconRotate ? 'ds-tree__toggle-icon--expanded' : '',\n resolveNodeClass(treeProps.toggleIconClass, row),\n ]\"\n />\n </button>\n <span\n v-else\n class=\"ds-tree__toggle-spacer\"\n :class=\"resolveNodeClass(treeProps.toggleSpacerClass, row)\"\n />\n\n <div class=\"ds-tree__content\" :class=\"resolveNodeClass(treeProps.contentClass, row)\">\n <slot\n :node=\"row.node\"\n :data=\"row.node.data\"\n >\n <span class=\"ds-tree__label\">{{ row.node.label }}</span>\n </slot>\n </div>\n </div>\n\n <div\n v-if=\"row.children.length\"\n class=\"ds-tree__children-wrap ml-6\"\n :class=\"treeProps.branchLine ? 'ds-tree__children-wrap--with-branch' : ''\"\n :style=\"resolveChildrenWrapStyle(row)\"\n >\n <GrTree\n v-bind=\"props\"\n :data=\"[]\"\n :internal-rows=\"row.children\"\n internal-nested\n :internal-store=\"treeStore\"\n :internal-interaction-context=\"interactionContext\"\n >\n <template #default=\"slotProps\">\n <slot v-bind=\"slotProps\">\n <span class=\"ds-tree__label\">{{ slotProps.node.label }}</span>\n </slot>\n </template>\n </GrTree>\n </div>\n </div>\n </div>\n</template>\n\n<style scoped>\n.ds-tree {\n --ds-tree-gap: 2px;\n --ds-tree-children-pl: 10px;\n --ds-tree-row-min-height: 28px;\n --ds-tree-row-radius: 8px;\n --ds-tree-row-pr: 8px;\n --ds-tree-row-color: var(--fg);\n --ds-tree-row-hover-bg: color-mix(in srgb, var(--primary, #000) 10%, transparent);\n --ds-tree-row-current-bg: color-mix(in srgb, var(--primary, #000) 5%, transparent);\n --ds-tree-row-current-hover-bg: color-mix(in srgb, var(--primary, #000) 16%, transparent);\n --ds-tree-drag-handle-size: 24px;\n --ds-tree-drag-handle-mr: 0;\n --ds-tree-drag-handle-radius: 6px;\n --ds-tree-drag-handle-color: inherit;\n --ds-tree-drag-handle-opacity: 0.55;\n --ds-tree-drag-handle-hover-bg: color-mix(in srgb, var(--muted, #000) 22%, transparent);\n --ds-tree-drag-handle-hover-color: var(--ds-tree-drag-handle-color);\n --ds-tree-drag-handle-hover-opacity: 0.9;\n --ds-tree-drag-handle-disabled-opacity: 0.25;\n --ds-tree-toggle-size: 24px;\n --ds-tree-toggle-mr: 0;\n --ds-tree-toggle-radius: 6px;\n --ds-tree-toggle-color: inherit;\n --ds-tree-toggle-hover-bg: color-mix(in srgb, var(--muted, #000) 25%, transparent);\n --ds-tree-toggle-hover-color: var(--ds-tree-toggle-color);\n --ds-tree-icon-size: 16px;\n --ds-tree-content-gap: 8px;\n --ds-tree-branch-line-default-color: var(--ds-tree-row-current-bg);\n --ds-tree-branch-line-width: 2px;\n display: flex;\n flex-direction: column;\n gap: var(--ds-tree-gap);\n}\n\n.ds-tree__children {\n display: flex;\n flex-direction: column;\n gap: var(--ds-tree-gap);\n}\n\n.ds-tree__children-wrap {\n --ds-tree-branch-line-color: var(--ds-tree-branch-line-default-color);\n display: flex;\n flex-direction: column;\n gap: var(--ds-tree-gap);\n padding-left: var(--ds-tree-children-pl, 10px);\n border-left: var(--ds-tree-branch-line-width) solid transparent;\n}\n\n.ds-tree__children-wrap--with-branch {\n border-left-color: var(--ds-tree-branch-line-color, var(--ds-tree-branch-line-default-color));\n}\n\n.ds-tree__row {\n position: relative;\n display: flex;\n align-items: center;\n min-height: var(--ds-tree-row-min-height);\n border-radius: var(--ds-tree-row-radius);\n padding-right: var(--ds-tree-row-pr);\n cursor: default;\n user-select: none;\n outline: none;\n color: var(--ds-tree-row-color);\n}\n\n.ds-tree__row:hover {\n background: var(--ds-tree-row-hover-bg);\n}\n\n.ds-tree__row--current {\n background: var(--ds-tree-row-current-bg);\n}\n\n.ds-tree__row--current:hover {\n background: var(--ds-tree-row-current-hover-bg);\n}\n\n.ds-tree__row--matched .ds-tree__label {\n font-weight: 600;\n}\n\n.ds-tree__drag-handle {\n width: var(--ds-tree-drag-handle-size);\n height: var(--ds-tree-drag-handle-size);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n margin-right: var(--ds-tree-drag-handle-mr);\n border-radius: var(--ds-tree-drag-handle-radius);\n color: var(--ds-tree-drag-handle-color);\n cursor: grab;\n visibility: hidden;\n pointer-events: none;\n opacity: 0;\n}\n\n.ds-tree__drag-handle--visible {\n visibility: visible;\n pointer-events: auto;\n opacity: var(--ds-tree-drag-handle-opacity);\n}\n\n.ds-tree__drag-handle:hover {\n background: var(--ds-tree-drag-handle-hover-bg);\n color: var(--ds-tree-drag-handle-hover-color);\n opacity: var(--ds-tree-drag-handle-hover-opacity);\n}\n\n.ds-tree__drag-handle:active {\n cursor: grabbing;\n}\n\n.ds-tree__drag-handle--disabled {\n cursor: default;\n opacity: var(--ds-tree-drag-handle-disabled-opacity);\n}\n\n.ds-tree__drag-icon {\n width: var(--ds-tree-icon-size);\n height: var(--ds-tree-icon-size);\n}\n\n.ds-tree__toggle {\n width: var(--ds-tree-toggle-size);\n height: var(--ds-tree-toggle-size);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n margin-right: var(--ds-tree-toggle-mr);\n border-radius: var(--ds-tree-toggle-radius);\n color: var(--ds-tree-toggle-color);\n}\n\n.ds-tree__toggle:hover {\n background: var(--ds-tree-toggle-hover-bg);\n color: var(--ds-tree-toggle-hover-color);\n}\n\n.ds-tree__toggle-icon {\n width: var(--ds-tree-icon-size);\n height: var(--ds-tree-icon-size);\n transition: transform 120ms ease;\n}\n\n.ds-tree__toggle-icon--expanded {\n transform: rotate(90deg);\n}\n\n.ds-tree__toggle-spacer {\n width: var(--ds-tree-toggle-size);\n height: var(--ds-tree-toggle-size);\n margin-right: var(--ds-tree-toggle-mr);\n display: inline-block;\n}\n\n.ds-tree__content {\n min-width: 0;\n display: flex;\n align-items: center;\n gap: var(--ds-tree-content-gap);\n}\n\n.ds-tree__label {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.ds-tree__row--drop-inner {\n outline: 2px solid color-mix(in srgb, var(--primary, #000) 40%, transparent);\n}\n\n.ds-tree__row--drop-prev::before,\n.ds-tree__row--drop-next::after {\n content: '';\n position: absolute;\n left: 8px;\n right: 8px;\n height: 2px;\n background: color-mix(in srgb, var(--primary, #000) 55%, transparent);\n}\n\n.ds-tree__row--drop-prev::before {\n top: 2px;\n}\n\n.ds-tree__row--drop-next::after {\n bottom: 2px;\n}\n</style>\n","<script setup lang=\"ts\" generic=\"T extends Record<string, any> = any\">\nimport { computed } from 'vue'\nimport type {\n GrTreeAllowDropType,\n GrTreeInstance,\n GrTreeNode,\n GrTreeNodeDropType,\n} from './grTreeTypes'\nimport { createGrTreeDataAdapter } from './grTreeDataAdapter'\nimport { createGrTreeInteractionContext } from './grTreeInteractionContext'\nimport { createGrTreeStore } from './grTreeStore'\nimport type {\n GrTreeBranchLineColor,\n GrTreeNodeClass,\n GrTreeProps,\n GrTreeVisibleRow,\n GrTreeVisibleTreeRow,\n} from './grTreeProps'\n\ndefineOptions({\n name: 'GrTree',\n})\n\nconst DEFAULT_BRANCH_LINE_COLOR = 'var(--ds-tree-branch-line-default-color, #e2e8f0)'\n\nconst props = withDefaults(defineProps<GrTreeProps<T>>(), {\n props: () => ({\n children: 'children',\n label: 'label',\n }),\n nodeKey: 'id' as any,\n defaultExpandedKeys: () => [],\n highlightCurrent: true,\n indent: 0,\n expandIcon: 'i-lucide-chevron-right',\n collapseIcon: 'i-lucide-chevron-right',\n toggleIconRotate: true,\n branchLine: false,\n branchLineColor: undefined,\n branchLineActiveColor: undefined,\n draggable: false,\n dragHandleIcon: 'i-lucide-grip-vertical',\n dragLabel: 'Drag',\n expandLabel: 'Expand',\n collapseLabel: 'Collapse',\n rowClass: undefined,\n dragHandleClass: undefined,\n toggleClass: undefined,\n toggleIconClass: undefined,\n toggleSpacerClass: undefined,\n contentClass: undefined,\n internalRows: undefined,\n internalNested: false,\n internalStore: undefined,\n})\n\nconst emit = defineEmits<{\n (event: 'nodeClick', data: T, node: GrTreeNode<T>): void\n (event: 'nodeExpand', data: T, node: GrTreeNode<T>): void\n (event: 'nodeCollapse', data: T, node: GrTreeNode<T>): void\n (event: 'nodeDrop', draggingNode: GrTreeNode<T>, dropNode: GrTreeNode<T>, dropType: GrTreeNodeDropType): void\n}>()\n\ndefineSlots<{\n default?: (props: { node: GrTreeNode<T>; data: T }) => any\n}>()\n\nconst dataAdapter = createGrTreeDataAdapter(props)\nconst treeStore = props.internalStore ?? createGrTreeStore({\n adapter: dataAdapter,\n data: () => props.data,\n defaultExpandedKeys: () => props.defaultExpandedKeys,\n filterNodeMethod: () => props.filterNodeMethod,\n})\nconst interactionContext = props.internalInteractionContext ?? createGrTreeInteractionContext(props, {\n emitNodeClick: (data, node) => emit('nodeClick', data, node),\n emitNodeExpand: (data, node) => emit('nodeExpand', data, node),\n emitNodeCollapse: (data, node) => emit('nodeCollapse', data, node),\n emitNodeDrop: (draggingNode, dropNode, dropType) => emit('nodeDrop', draggingNode, dropNode, dropType),\n})\n\nconst treeProps = props as Readonly<GrTreeProps<T>>\nconst currentKey = treeStore.currentKey\nconst hoveredKey = interactionContext.hoveredKey\nconst dropTarget = interactionContext.dropTarget\n\nconst visibleRows = computed<GrTreeVisibleTreeRow<T>[]>(() => {\n if (props.internalRows)\n return props.internalRows\n\n const { roots } = treeStore.treeModel.value\n const { isActive, subtreeHasMatch, matchedKeys, autoExpandKeys } = treeStore.filterInfo.value\n\n const walk = (nodes: GrTreeNode<T>[]): GrTreeVisibleTreeRow<T>[] => {\n const rows: GrTreeVisibleTreeRow<T>[] = []\n\n for (const node of nodes) {\n if (isActive && !subtreeHasMatch.get(node.key))\n continue\n\n const isLeaf = node.childNodes.length === 0\n const isMatched = matchedKeys.has(node.key)\n const isExpanded = treeStore.isExpandedKey(node.key) || (isActive && autoExpandKeys.has(node.key))\n\n rows.push({\n node,\n isExpanded,\n isLeaf,\n isMatched,\n children: isExpanded ? walk(node.childNodes) : [],\n })\n }\n\n return rows\n }\n\n return walk(roots)\n})\n\nfunction onRowClick(node: GrTreeNode<T>) {\n treeStore.setCurrentKey(node.key)\n interactionContext.emitNodeClick(node.data, node)\n}\n\nfunction onRowMouseEnter(node: GrTreeNode<T>) {\n hoveredKey.value = node.key\n}\n\nfunction onRowMouseLeave(node: GrTreeNode<T>) {\n if (hoveredKey.value === node.key)\n hoveredKey.value = undefined\n}\n\nfunction toggleExpand(node: GrTreeNode<T>) {\n const expanded = !treeStore.isExpandedKey(node.key)\n treeStore.toggleExpand(node)\n\n if (expanded)\n interactionContext.emitNodeExpand(node.data, node)\n else\n interactionContext.emitNodeCollapse(node.data, node)\n}\n\n// Drag & drop\nfunction canDrag(node: GrTreeNode<T>): boolean {\n return interactionContext.canDrag(node)\n}\n\nfunction shouldShowDragHandle(node: GrTreeNode<T>): boolean {\n return canDrag(node) && hoveredKey.value === node.key\n}\n\nfunction resolveDropType(evt: DragEvent, el: HTMLElement): GrTreeNodeDropType {\n const rect = el.getBoundingClientRect()\n const y = evt.clientY - rect.top\n const third = rect.height / 3\n if (y < third)\n return 'prev'\n if (y > third * 2)\n return 'next'\n return 'inner'\n}\n\nfunction canDrop(drag: GrTreeNode<T>, target: GrTreeNode<T>, type: GrTreeAllowDropType): boolean {\n return interactionContext.canDrop(drag, target, type)\n}\n\nfunction onDragStart(evt: DragEvent, node: GrTreeNode<T>) {\n if (!canDrag(node)) {\n evt.preventDefault()\n return\n }\n\n interactionContext.draggingNode.value = node\n interactionContext.dropTarget.value = null\n try {\n evt.dataTransfer?.setData('text/plain', String(node.key))\n }\n catch {\n // ignore\n }\n if (evt.dataTransfer)\n evt.dataTransfer.effectAllowed = 'move'\n}\n\nfunction onDragEnd() {\n interactionContext.resetDragState()\n}\n\nfunction onDragOver(evt: DragEvent, node: GrTreeNode<T>, rowEl: HTMLElement) {\n const drag = interactionContext.draggingNode.value\n if (!treeProps.draggable || !drag)\n return\n\n // required for `drop` to fire\n evt.preventDefault()\n\n const type = resolveDropType(evt, rowEl)\n const allowed = treeStore.canMoveNode(drag, node, type) && canDrop(drag, node, type)\n interactionContext.dropTarget.value = { key: node.key, type, allowed }\n if (evt.dataTransfer)\n evt.dataTransfer.dropEffect = allowed ? 'move' : 'none'\n}\n\nfunction onDrop(evt: DragEvent, node: GrTreeNode<T>) {\n const drag = interactionContext.draggingNode.value\n const target = interactionContext.dropTarget.value\n if (!treeProps.draggable || !drag || !target)\n return\n\n evt.preventDefault()\n\n if (target.key === node.key && target.allowed) {\n const movedNode = treeStore.moveNode(drag, node, target.type)\n if (movedNode) {\n const dropNode = treeStore.getNode(node.key) ?? node\n interactionContext.emitNodeDrop(movedNode, dropNode, target.type)\n }\n }\n\n interactionContext.resetDragState()\n}\n\nfunction filter(value: string) {\n treeStore.filter(value)\n}\n\nfunction resolveNodeClass(classValue: GrTreeNodeClass<T> | undefined, row: GrTreeVisibleRow<T>) {\n if (!classValue)\n return undefined\n\n return typeof classValue === 'function'\n ? classValue(row)\n : classValue\n}\n\nfunction resolveBranchLineColorValue(color: GrTreeBranchLineColor<T> | undefined, node: GrTreeNode<T>) {\n if (!color)\n return undefined\n\n return typeof color === 'function'\n ? color(node) ?? undefined\n : color\n}\n\nfunction isBranchLineActive(node: GrTreeNode<T>) {\n const selectedKey = currentKey.value\n\n if (selectedKey == null)\n return false\n\n if (node.key === selectedKey)\n return true\n\n return node.childNodes.some(child => child.key === selectedKey && !treeStore.isExpandedKey(child.key))\n}\n\nfunction resolveBranchLineColor(node: GrTreeNode<T>) {\n const defaultColor = resolveBranchLineColorValue(treeProps.branchLineColor, node) ?? DEFAULT_BRANCH_LINE_COLOR\n\n if (!isBranchLineActive(node))\n return defaultColor\n\n return resolveBranchLineColorValue(treeProps.branchLineActiveColor, node) ?? defaultColor\n}\n\nfunction resolveChildrenWrapStyle(row: GrTreeVisibleTreeRow<T>) {\n if (!treeProps.branchLine)\n return {\n }\n\n return {\n '--ds-tree-branch-line-color': resolveBranchLineColor(row.node),\n }\n}\n\ndefineExpose<GrTreeInstance<T>>({\n appendNode: treeStore.appendNode,\n filter,\n getCurrentNode: treeStore.getCurrentNode,\n setCurrentKey: treeStore.setCurrentKey,\n getCurrentKey: treeStore.getCurrentKey,\n getNode: treeStore.getNode,\n insertNodeAfter: treeStore.insertNodeAfter,\n insertNodeBefore: treeStore.insertNodeBefore,\n removeNode: treeStore.removeNode,\n setCurrentNode: treeStore.setCurrentNode,\n})\n</script>\n\n<template>\n <div\n :data-ds-tree=\"props.internalNested ? undefined : ''\"\n :class=\"props.internalNested ? 'ds-tree__children' : 'ds-tree'\"\n :role=\"props.internalNested ? 'group' : 'tree'\"\n >\n <div\n v-for=\"row in visibleRows\"\n :key=\"row.node.key\"\n data-ds-tree-node\n role=\"treeitem\"\n :aria-level=\"row.node.level\"\n :aria-expanded=\"row.isLeaf ? undefined : row.isExpanded\"\n >\n <div\n data-ds-tree-row\n class=\"ds-tree__row py-2 px-2\"\n :class=\"[\n treeProps.highlightCurrent && currentKey === row.node.key ? 'ds-tree__row--current' : '',\n row.isMatched ? 'ds-tree__row--matched' : '',\n dropTarget?.key === row.node.key && dropTarget.allowed && dropTarget.type === 'inner' ? 'ds-tree__row--drop-inner' : '',\n dropTarget?.key === row.node.key && dropTarget.allowed && dropTarget.type === 'prev' ? 'ds-tree__row--drop-prev' : '',\n dropTarget?.key === row.node.key && dropTarget.allowed && dropTarget.type === 'next' ? 'ds-tree__row--drop-next' : '',\n resolveNodeClass(treeProps.rowClass, row),\n ]\"\n tabindex=\"0\"\n @click=\"onRowClick(row.node)\"\n @drop=\"onDrop($event, row.node)\"\n @dragover=\"onDragOver($event, row.node, $event.currentTarget as HTMLElement)\"\n @mouseenter=\"onRowMouseEnter(row.node)\"\n @mouseleave=\"onRowMouseLeave(row.node)\"\n >\n <button\n v-if=\"treeProps.draggable\"\n type=\"button\"\n data-ds-tree-drag-handle\n class=\"ds-tree__drag-handle\"\n :class=\"[\n shouldShowDragHandle(row.node) ? 'ds-tree__drag-handle--visible' : '',\n canDrag(row.node) ? '' : 'ds-tree__drag-handle--disabled',\n resolveNodeClass(treeProps.dragHandleClass, row),\n ]\"\n :aria-label=\"treeProps.dragLabel\"\n :draggable=\"canDrag(row.node)\"\n @click.stop\n @mousedown.stop\n @dragstart=\"onDragStart($event, row.node)\"\n @dragend=\"onDragEnd\"\n >\n <span class=\"ds-tree__drag-icon\" :class=\"treeProps.dragHandleIcon\" />\n </button>\n\n <button\n v-if=\"!row.isLeaf\"\n data-ds-tree-toggle\n type=\"button\"\n class=\"ds-tree__toggle\"\n :class=\"resolveNodeClass(treeProps.toggleClass, row)\"\n :aria-label=\"row.isExpanded ? treeProps.collapseLabel : treeProps.expandLabel\"\n @click.stop=\"toggleExpand(row.node)\"\n >\n <span\n class=\"ds-tree__toggle-icon\"\n :class=\"[\n row.isExpanded ? treeProps.collapseIcon : treeProps.expandIcon,\n row.isExpanded && treeProps.toggleIconRotate ? 'ds-tree__toggle-icon--expanded' : '',\n resolveNodeClass(treeProps.toggleIconClass, row),\n ]\"\n />\n </button>\n <span\n v-else\n class=\"ds-tree__toggle-spacer\"\n :class=\"resolveNodeClass(treeProps.toggleSpacerClass, row)\"\n />\n\n <div class=\"ds-tree__content\" :class=\"resolveNodeClass(treeProps.contentClass, row)\">\n <slot\n :node=\"row.node\"\n :data=\"row.node.data\"\n >\n <span class=\"ds-tree__label\">{{ row.node.label }}</span>\n </slot>\n </div>\n </div>\n\n <div\n v-if=\"row.children.length\"\n class=\"ds-tree__children-wrap ml-6\"\n :class=\"treeProps.branchLine ? 'ds-tree__children-wrap--with-branch' : ''\"\n :style=\"resolveChildrenWrapStyle(row)\"\n >\n <GrTree\n v-bind=\"props\"\n :data=\"[]\"\n :internal-rows=\"row.children\"\n internal-nested\n :internal-store=\"treeStore\"\n :internal-interaction-context=\"interactionContext\"\n >\n <template #default=\"slotProps\">\n <slot v-bind=\"slotProps\">\n <span class=\"ds-tree__label\">{{ slotProps.node.label }}</span>\n </slot>\n </template>\n </GrTree>\n </div>\n </div>\n </div>\n</template>\n\n<style scoped>\n.ds-tree {\n --ds-tree-gap: 2px;\n --ds-tree-children-pl: 10px;\n --ds-tree-row-min-height: 28px;\n --ds-tree-row-radius: 8px;\n --ds-tree-row-pr: 8px;\n --ds-tree-row-color: var(--fg);\n --ds-tree-row-hover-bg: color-mix(in srgb, var(--primary, #000) 10%, transparent);\n --ds-tree-row-current-bg: color-mix(in srgb, var(--primary, #000) 5%, transparent);\n --ds-tree-row-current-hover-bg: color-mix(in srgb, var(--primary, #000) 16%, transparent);\n --ds-tree-drag-handle-size: 24px;\n --ds-tree-drag-handle-mr: 0;\n --ds-tree-drag-handle-radius: 6px;\n --ds-tree-drag-handle-color: inherit;\n --ds-tree-drag-handle-opacity: 0.55;\n --ds-tree-drag-handle-hover-bg: color-mix(in srgb, var(--muted, #000) 22%, transparent);\n --ds-tree-drag-handle-hover-color: var(--ds-tree-drag-handle-color);\n --ds-tree-drag-handle-hover-opacity: 0.9;\n --ds-tree-drag-handle-disabled-opacity: 0.25;\n --ds-tree-toggle-size: 24px;\n --ds-tree-toggle-mr: 0;\n --ds-tree-toggle-radius: 6px;\n --ds-tree-toggle-color: inherit;\n --ds-tree-toggle-hover-bg: color-mix(in srgb, var(--muted, #000) 25%, transparent);\n --ds-tree-toggle-hover-color: var(--ds-tree-toggle-color);\n --ds-tree-icon-size: 16px;\n --ds-tree-content-gap: 8px;\n --ds-tree-branch-line-default-color: var(--ds-tree-row-current-bg);\n --ds-tree-branch-line-width: 2px;\n display: flex;\n flex-direction: column;\n gap: var(--ds-tree-gap);\n}\n\n.ds-tree__children {\n display: flex;\n flex-direction: column;\n gap: var(--ds-tree-gap);\n}\n\n.ds-tree__children-wrap {\n --ds-tree-branch-line-color: var(--ds-tree-branch-line-default-color);\n display: flex;\n flex-direction: column;\n gap: var(--ds-tree-gap);\n padding-left: var(--ds-tree-children-pl, 10px);\n border-left: var(--ds-tree-branch-line-width) solid transparent;\n}\n\n.ds-tree__children-wrap--with-branch {\n border-left-color: var(--ds-tree-branch-line-color, var(--ds-tree-branch-line-default-color));\n}\n\n.ds-tree__row {\n position: relative;\n display: flex;\n align-items: center;\n min-height: var(--ds-tree-row-min-height);\n border-radius: var(--ds-tree-row-radius);\n padding-right: var(--ds-tree-row-pr);\n cursor: default;\n user-select: none;\n outline: none;\n color: var(--ds-tree-row-color);\n}\n\n.ds-tree__row:hover {\n background: var(--ds-tree-row-hover-bg);\n}\n\n.ds-tree__row--current {\n background: var(--ds-tree-row-current-bg);\n}\n\n.ds-tree__row--current:hover {\n background: var(--ds-tree-row-current-hover-bg);\n}\n\n.ds-tree__row--matched .ds-tree__label {\n font-weight: 600;\n}\n\n.ds-tree__drag-handle {\n width: var(--ds-tree-drag-handle-size);\n height: var(--ds-tree-drag-handle-size);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n margin-right: var(--ds-tree-drag-handle-mr);\n border-radius: var(--ds-tree-drag-handle-radius);\n color: var(--ds-tree-drag-handle-color);\n cursor: grab;\n visibility: hidden;\n pointer-events: none;\n opacity: 0;\n}\n\n.ds-tree__drag-handle--visible {\n visibility: visible;\n pointer-events: auto;\n opacity: var(--ds-tree-drag-handle-opacity);\n}\n\n.ds-tree__drag-handle:hover {\n background: var(--ds-tree-drag-handle-hover-bg);\n color: var(--ds-tree-drag-handle-hover-color);\n opacity: var(--ds-tree-drag-handle-hover-opacity);\n}\n\n.ds-tree__drag-handle:active {\n cursor: grabbing;\n}\n\n.ds-tree__drag-handle--disabled {\n cursor: default;\n opacity: var(--ds-tree-drag-handle-disabled-opacity);\n}\n\n.ds-tree__drag-icon {\n width: var(--ds-tree-icon-size);\n height: var(--ds-tree-icon-size);\n}\n\n.ds-tree__toggle {\n width: var(--ds-tree-toggle-size);\n height: var(--ds-tree-toggle-size);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n margin-right: var(--ds-tree-toggle-mr);\n border-radius: var(--ds-tree-toggle-radius);\n color: var(--ds-tree-toggle-color);\n}\n\n.ds-tree__toggle:hover {\n background: var(--ds-tree-toggle-hover-bg);\n color: var(--ds-tree-toggle-hover-color);\n}\n\n.ds-tree__toggle-icon {\n width: var(--ds-tree-icon-size);\n height: var(--ds-tree-icon-size);\n transition: transform 120ms ease;\n}\n\n.ds-tree__toggle-icon--expanded {\n transform: rotate(90deg);\n}\n\n.ds-tree__toggle-spacer {\n width: var(--ds-tree-toggle-size);\n height: var(--ds-tree-toggle-size);\n margin-right: var(--ds-tree-toggle-mr);\n display: inline-block;\n}\n\n.ds-tree__content {\n min-width: 0;\n display: flex;\n align-items: center;\n gap: var(--ds-tree-content-gap);\n}\n\n.ds-tree__label {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.ds-tree__row--drop-inner {\n outline: 2px solid color-mix(in srgb, var(--primary, #000) 40%, transparent);\n}\n\n.ds-tree__row--drop-prev::before,\n.ds-tree__row--drop-next::after {\n content: '';\n position: absolute;\n left: 8px;\n right: 8px;\n height: 2px;\n background: color-mix(in srgb, var(--primary, #000) 55%, transparent);\n}\n\n.ds-tree__row--drop-prev::before {\n top: 2px;\n}\n\n.ds-tree__row--drop-next::after {\n bottom: 2px;\n}\n</style>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"GrTree-uZr5SyQI.js","names":[],"sources":["../../../../src/components/GrTree/grTreeDataAdapter.ts","../../../../src/components/GrTree/grTreeInteractionContext.ts","../../../../src/components/GrTree/grTreeStore.ts","../../../../src/components/GrTree/GrTree.vue","../../../../src/components/GrTree/GrTree.vue"],"sourcesContent":["import type { GrTreeKey } from './grTreeTypes'\nimport type {\n GrTreeDataProps,\n GrTreePropsMap,\n} from './grTreeProps'\n\nconst DEFAULT_CHILDREN_KEY = 'children'\nconst DEFAULT_LABEL_KEY = 'label'\n\nexport type GrTreeDataAdapterOptions<T extends object> = Pick<GrTreeDataProps<T>, 'props' | 'nodeKey'>\n\nexport type GrTreeDataAdapter<T extends object> = {\n hasNodeKey: () => boolean\n getChildrenKey: () => string\n getLabelKey: () => string\n getLabel: (data: T) => string\n getChildren: (data: T) => T[]\n ensureChildren: (data: T) => T[]\n getNodeKey: (data: T, index: number, parentKey: GrTreeKey | undefined) => GrTreeKey\n getExplicitNodeKey: (data: T) => GrTreeKey | undefined\n}\n\nfunction isTreeKey(value: unknown): value is GrTreeKey {\n return typeof value === 'string' || typeof value === 'number'\n}\n\nfunction resolveMapValue(map: GrTreePropsMap | undefined, key: keyof GrTreePropsMap, fallback: string) {\n return map?.[key] ?? fallback\n}\n\nexport function createGrTreeDataAdapter<T extends Record<string, any> = any>(\n options: GrTreeDataAdapterOptions<T>,\n): GrTreeDataAdapter<T> {\n function hasNodeKey() {\n return options.nodeKey != null\n }\n\n function getChildrenKey() {\n return resolveMapValue(options.props, 'children', DEFAULT_CHILDREN_KEY)\n }\n\n function getLabelKey() {\n return resolveMapValue(options.props, 'label', DEFAULT_LABEL_KEY)\n }\n\n function getLabel(data: T): string {\n const key = getLabelKey() as keyof T\n const value = data[key]\n return value == null ? '' : String(value)\n }\n\n function getChildren(data: T): T[] {\n const key = getChildrenKey() as keyof T\n const value = data[key]\n return Array.isArray(value) ? (value as T[]) : []\n }\n\n function ensureChildren(data: T): T[] {\n const key = getChildrenKey()\n const value = (data as Record<string, unknown>)[key]\n if (Array.isArray(value))\n return value as T[]\n\n const children: T[] = []\n ;(data as Record<string, unknown>)[key] = children\n return children\n }\n\n function getExplicitNodeKey(data: T): GrTreeKey | undefined {\n if (options.nodeKey == null)\n return undefined\n\n const keyName = options.nodeKey as keyof T\n const value = data[keyName] as unknown\n return isTreeKey(value) ? value : undefined\n }\n\n function getNodeKey(data: T, index: number, parentKey: GrTreeKey | undefined): GrTreeKey {\n const explicitKey = getExplicitNodeKey(data)\n if (explicitKey != null)\n return explicitKey\n\n return parentKey == null ? index : `${String(parentKey)}:${index}`\n }\n\n return {\n hasNodeKey,\n getChildrenKey,\n getLabelKey,\n getLabel,\n getChildren,\n ensureChildren,\n getNodeKey,\n getExplicitNodeKey,\n }\n}","import type { Ref, ShallowRef } from 'vue'\nimport { ref, shallowRef } from 'vue'\nimport type {\n GrTreeAllowDropType,\n GrTreeKey,\n GrTreeNode,\n GrTreeNodeDropType,\n} from './grTreeTypes'\n\nexport type GrTreeDropTarget = {\n key: GrTreeKey\n type: GrTreeNodeDropType\n allowed: boolean\n}\n\nexport type GrTreeInteractionOptions<T> = {\n draggable?: boolean\n allowDrop?: (draggingNode: GrTreeNode<T>, dropNode: GrTreeNode<T>, type: GrTreeAllowDropType) => boolean\n allowDrag?: (draggingNode: GrTreeNode<T>) => boolean\n}\n\nexport type GrTreeInteractionEmitters<T> = {\n emitNodeClick: (data: T, node: GrTreeNode<T>) => void\n emitNodeExpand: (data: T, node: GrTreeNode<T>) => void\n emitNodeCollapse: (data: T, node: GrTreeNode<T>) => void\n emitNodeDrop: (draggingNode: GrTreeNode<T>, dropNode: GrTreeNode<T>, dropType: GrTreeNodeDropType) => void\n}\n\nexport type GrTreeInteractionContext<T> = {\n hoveredKey: Ref<GrTreeKey | undefined>\n draggingNode: ShallowRef<GrTreeNode<T> | null>\n dropTarget: ShallowRef<GrTreeDropTarget | null>\n canDrag: (node: GrTreeNode<T>) => boolean\n canDrop: (drag: GrTreeNode<T>, target: GrTreeNode<T>, type: GrTreeAllowDropType) => boolean\n resetDragState: () => void\n emitNodeClick: (data: T, node: GrTreeNode<T>) => void\n emitNodeExpand: (data: T, node: GrTreeNode<T>) => void\n emitNodeCollapse: (data: T, node: GrTreeNode<T>) => void\n emitNodeDrop: (draggingNode: GrTreeNode<T>, dropNode: GrTreeNode<T>, dropType: GrTreeNodeDropType) => void\n}\n\nexport function createGrTreeInteractionContext<T>(\n options: GrTreeInteractionOptions<T>,\n emitters: GrTreeInteractionEmitters<T>,\n): GrTreeInteractionContext<T> {\n const hoveredKey = ref<GrTreeKey | undefined>(undefined)\n const draggingNode = shallowRef<GrTreeNode<T> | null>(null)\n const dropTarget = shallowRef<GrTreeDropTarget | null>(null)\n\n function canDrag(node: GrTreeNode<T>): boolean {\n if (!options.draggable)\n return false\n\n if (options.allowDrag)\n return options.allowDrag(node)\n\n return true\n }\n\n function canDrop(drag: GrTreeNode<T>, target: GrTreeNode<T>, type: GrTreeAllowDropType): boolean {\n if (!options.allowDrop)\n return true\n\n return options.allowDrop(drag, target, type)\n }\n\n function resetDragState() {\n draggingNode.value = null\n dropTarget.value = null\n }\n\n return {\n hoveredKey,\n draggingNode,\n dropTarget,\n canDrag,\n canDrop,\n resetDragState,\n ...emitters,\n }\n}","import type { ComputedRef, MaybeRefOrGetter, Ref, ShallowRef } from 'vue'\nimport { computed, ref, shallowRef, toValue, watch } from 'vue'\nimport type {\n GrTreeKey,\n GrTreeNode,\n GrTreeNodeDropType,\n GrTreeNodeTarget,\n} from './grTreeTypes'\nimport type { GrTreeDataAdapter } from './grTreeDataAdapter'\nimport type { GrTreeDataProps, GrTreeFilterNodeMethod } from './grTreeProps'\n\ntype TreeModel<T extends object> = {\n roots: GrTreeNode<T>[]\n byKey: Map<GrTreeKey, GrTreeNode<T>>\n byData: WeakMap<T, GrTreeNode<T>>\n}\n\ntype FilterInfo = {\n isActive: boolean\n subtreeHasMatch: Map<GrTreeKey, boolean>\n matchedKeys: Set<GrTreeKey>\n autoExpandKeys: Set<GrTreeKey>\n}\n\nexport type GrTreeStoreOptions<T extends object> = {\n data: MaybeRefOrGetter<GrTreeDataProps<T>['data']>\n defaultExpandedKeys?: MaybeRefOrGetter<GrTreeDataProps<T>['defaultExpandedKeys']>\n filterNodeMethod?: MaybeRefOrGetter<GrTreeFilterNodeMethod<T> | undefined>\n adapter: GrTreeDataAdapter<T>\n}\n\nexport type GrTreeStore<T extends object> = {\n filterValue: Ref<string>\n expandedKeys: ShallowRef<Set<GrTreeKey>>\n currentKey: Ref<GrTreeKey | undefined>\n treeModel: ComputedRef<TreeModel<T>>\n filterInfo: ComputedRef<FilterInfo>\n filter: (value: string) => void\n isExpandedKey: (key: GrTreeKey) => boolean\n setExpandedKey: (key: GrTreeKey, expanded: boolean) => void\n toggleExpand: (node: GrTreeNode<T>) => void\n setCurrentKey: (key?: GrTreeKey) => void\n getCurrentKey: () => GrTreeKey | undefined\n getCurrentNode: () => GrTreeNode<T> | undefined\n setCurrentNode: (node?: GrTreeNodeTarget<T>) => boolean\n getNode: (key: GrTreeKey) => GrTreeNode<T> | undefined\n canMoveNode: (node: GrTreeNodeTarget<T>, referenceNode: GrTreeNodeTarget<T>, dropType: GrTreeNodeDropType) => boolean\n moveNode: (node: GrTreeNodeTarget<T>, referenceNode: GrTreeNodeTarget<T>, dropType: GrTreeNodeDropType) => GrTreeNode<T> | undefined\n appendNode: (data: T, parent: GrTreeNodeTarget<T>) => GrTreeNode<T> | undefined\n removeNode: (node: GrTreeNodeTarget<T>) => boolean\n insertNodeBefore: (data: T, referenceNode: GrTreeNodeTarget<T>) => GrTreeNode<T> | undefined\n insertNodeAfter: (data: T, referenceNode: GrTreeNodeTarget<T>) => GrTreeNode<T> | undefined\n}\n\nexport function createGrTreeStore<T extends Record<string, any> = any>(\n options: GrTreeStoreOptions<T>,\n): GrTreeStore<T> {\n const filterValue = ref('')\n const expandedKeys = shallowRef<Set<GrTreeKey>>(new Set())\n const currentKey = ref<GrTreeKey | undefined>(undefined)\n const getData = () => toValue(options.data) ?? []\n const getFilterNodeMethod = () => toValue(options.filterNodeMethod)\n\n watch(\n () => toValue(options.defaultExpandedKeys),\n (keys) => {\n expandedKeys.value = new Set(keys ?? [])\n },\n { immediate: true },\n )\n\n const treeModel = computed<TreeModel<T>>(() => {\n const byKey = new Map<GrTreeKey, GrTreeNode<T>>()\n const byData = new WeakMap<T, GrTreeNode<T>>()\n\n const build = (items: T[], parent: GrTreeNode<T> | undefined, level: number): GrTreeNode<T>[] => {\n return items.map((item, index) => {\n const node: GrTreeNode<T> = {\n key: options.adapter.getNodeKey(item, index, parent?.key),\n label: options.adapter.getLabel(item),\n data: item,\n level,\n parent,\n childNodes: [],\n }\n\n byKey.set(node.key, node)\n byData.set(item, node)\n node.childNodes = build(options.adapter.getChildren(item), node, level + 1)\n\n return node\n })\n }\n\n return {\n roots: build(getData(), undefined, 1),\n byKey,\n byData,\n }\n })\n\n const filterInfo = computed<FilterInfo>(() => {\n const value = filterValue.value\n const isActive = value.trim().length > 0\n const valueLower = value.toLowerCase()\n const subtreeHasMatch = new Map<GrTreeKey, boolean>()\n const matchedKeys = new Set<GrTreeKey>()\n const autoExpandKeys = new Set<GrTreeKey>()\n\n if (!isActive) {\n return {\n isActive,\n subtreeHasMatch,\n matchedKeys,\n autoExpandKeys,\n }\n }\n\n const match = (node: GrTreeNode<T>): boolean => {\n const filterNodeMethod = getFilterNodeMethod()\n if (filterNodeMethod)\n return filterNodeMethod(value, node.data, node)\n\n return node.label.toLowerCase().includes(valueLower)\n }\n\n const walk = (nodes: GrTreeNode<T>[]): boolean => {\n let any = false\n\n for (const node of nodes) {\n const self = match(node)\n const childAny = walk(node.childNodes)\n const has = self || childAny\n\n subtreeHasMatch.set(node.key, has)\n\n if (self)\n matchedKeys.add(node.key)\n\n if (childAny)\n autoExpandKeys.add(node.key)\n\n any ||= has\n }\n\n return any\n }\n\n walk(treeModel.value.roots)\n\n return {\n isActive,\n subtreeHasMatch,\n matchedKeys,\n autoExpandKeys,\n }\n })\n\n function getNode(key: GrTreeKey) {\n return treeModel.value.byKey.get(key)\n }\n\n function findNodeByData(data: T): GrTreeNode<T> | undefined {\n return treeModel.value.byData.get(data)\n }\n\n function isTreeNode(target: GrTreeNodeTarget<T>): target is GrTreeNode<T> {\n return typeof target === 'object'\n && target !== null\n && 'key' in target\n && 'data' in target\n && 'childNodes' in target\n }\n\n function resolveNodeTarget(target?: GrTreeNodeTarget<T>): GrTreeNode<T> | undefined {\n if (target == null)\n return undefined\n\n if (typeof target === 'string' || typeof target === 'number')\n return getNode(target)\n\n if (isTreeNode(target))\n return getNode(target.key) ?? target\n\n const key = options.adapter.getExplicitNodeKey(target)\n if (key != null)\n return getNode(key)\n\n return findNodeByData(target)\n }\n\n function getNodeContainer(node: GrTreeNode<T>) {\n const items = node.parent ? options.adapter.ensureChildren(node.parent.data) : getData()\n\n let index = items.findIndex(item => item === node.data)\n if (index >= 0)\n return { items, index }\n\n const key = options.adapter.getExplicitNodeKey(node.data)\n if (key == null)\n return undefined\n\n index = items.findIndex(item => options.adapter.getExplicitNodeKey(item) === key)\n if (index < 0)\n return undefined\n\n return { items, index }\n }\n\n function isDescendantNode(ancestor: GrTreeNode<T>, node: GrTreeNode<T>) {\n let current = node.parent\n\n while (current) {\n if (current.key === ancestor.key)\n return true\n\n current = current.parent\n }\n\n return false\n }\n\n function canMoveNode(node: GrTreeNodeTarget<T>, referenceNode: GrTreeNodeTarget<T>, dropType: GrTreeNodeDropType) {\n const sourceNode = resolveNodeTarget(node)\n const targetNode = resolveNodeTarget(referenceNode)\n\n if (!sourceNode || !targetNode)\n return false\n\n if (sourceNode.key === targetNode.key)\n return false\n\n if (isDescendantNode(sourceNode, targetNode))\n return false\n\n const sourceContainer = getNodeContainer(sourceNode)\n if (!sourceContainer)\n return false\n\n if (dropType === 'inner')\n return true\n\n return Boolean(getNodeContainer(targetNode))\n }\n\n function sanitizeTreeState() {\n const byKey = treeModel.value.byKey\n\n if (currentKey.value != null && !byKey.has(currentKey.value))\n currentKey.value = undefined\n\n const nextExpandedKeys = new Set(Array.from(expandedKeys.value).filter(key => byKey.has(key)))\n if (nextExpandedKeys.size !== expandedKeys.value.size)\n expandedKeys.value = nextExpandedKeys\n }\n\n function isExpandedKey(key: GrTreeKey): boolean {\n return expandedKeys.value.has(key)\n }\n\n function setExpandedKey(key: GrTreeKey, expanded: boolean) {\n const next = new Set(expandedKeys.value)\n\n if (expanded)\n next.add(key)\n else\n next.delete(key)\n\n expandedKeys.value = next\n }\n\n function toggleExpand(node: GrTreeNode<T>) {\n setExpandedKey(node.key, !isExpandedKey(node.key))\n }\n\n function setCurrentKey(key?: GrTreeKey) {\n currentKey.value = key\n }\n\n function getCurrentKey() {\n return currentKey.value\n }\n\n function getCurrentNode() {\n const key = currentKey.value\n return key == null ? undefined : getNode(key)\n }\n\n function setCurrentNode(node?: GrTreeNodeTarget<T>) {\n if (node == null) {\n currentKey.value = undefined\n return true\n }\n\n const targetNode = resolveNodeTarget(node)\n if (!targetNode)\n return false\n\n currentKey.value = targetNode.key\n return true\n }\n\n function resolveInsertedNode(data: T) {\n const key = options.adapter.getExplicitNodeKey(data)\n if (key != null)\n return getNode(key)\n\n return findNodeByData(data)\n }\n\n function moveNode(node: GrTreeNodeTarget<T>, referenceNode: GrTreeNodeTarget<T>, dropType: GrTreeNodeDropType) {\n const sourceNode = resolveNodeTarget(node)\n const targetNode = resolveNodeTarget(referenceNode)\n\n if (!sourceNode || !targetNode)\n return undefined\n\n if (!canMoveNode(sourceNode, targetNode, dropType))\n return undefined\n\n const sourceContainer = getNodeContainer(sourceNode)\n if (!sourceContainer)\n return undefined\n\n let destinationItems: T[]\n let destinationIndex: number\n\n if (dropType === 'inner') {\n destinationItems = options.adapter.ensureChildren(targetNode.data)\n destinationIndex = destinationItems.length\n }\n else {\n const targetContainer = getNodeContainer(targetNode)\n if (!targetContainer)\n return undefined\n\n destinationItems = targetContainer.items\n destinationIndex = dropType === 'prev'\n ? targetContainer.index\n : targetContainer.index + 1\n }\n\n if (destinationItems === sourceContainer.items && sourceContainer.index < destinationIndex)\n destinationIndex -= 1\n\n const [movedData] = sourceContainer.items.splice(sourceContainer.index, 1)\n destinationItems.splice(destinationIndex, 0, movedData)\n\n if (dropType === 'inner')\n setExpandedKey(targetNode.key, true)\n\n sanitizeTreeState()\n return resolveInsertedNode(movedData)\n }\n\n function appendNode(data: T, parent: GrTreeNodeTarget<T>) {\n const parentNode = resolveNodeTarget(parent)\n if (!parentNode)\n return undefined\n\n options.adapter.ensureChildren(parentNode.data).push(data)\n setExpandedKey(parentNode.key, true)\n sanitizeTreeState()\n return resolveInsertedNode(data)\n }\n\n function removeNode(node: GrTreeNodeTarget<T>) {\n if (!options.adapter.hasNodeKey())\n return false\n\n const targetNode = resolveNodeTarget(node)\n if (!targetNode)\n return false\n\n const container = getNodeContainer(targetNode)\n if (!container)\n return false\n\n container.items.splice(container.index, 1)\n sanitizeTreeState()\n return true\n }\n\n function insertNodeBefore(data: T, referenceNode: GrTreeNodeTarget<T>) {\n const targetNode = resolveNodeTarget(referenceNode)\n if (!targetNode)\n return undefined\n\n const container = getNodeContainer(targetNode)\n if (!container)\n return undefined\n\n container.items.splice(container.index, 0, data)\n sanitizeTreeState()\n return resolveInsertedNode(data)\n }\n\n function insertNodeAfter(data: T, referenceNode: GrTreeNodeTarget<T>) {\n const targetNode = resolveNodeTarget(referenceNode)\n if (!targetNode)\n return undefined\n\n const container = getNodeContainer(targetNode)\n if (!container)\n return undefined\n\n container.items.splice(container.index + 1, 0, data)\n sanitizeTreeState()\n return resolveInsertedNode(data)\n }\n\n function filter(value: string) {\n filterValue.value = value\n }\n\n return {\n filterValue,\n expandedKeys,\n currentKey,\n treeModel,\n filterInfo,\n filter,\n isExpandedKey,\n setExpandedKey,\n toggleExpand,\n setCurrentKey,\n getCurrentKey,\n getCurrentNode,\n setCurrentNode,\n getNode,\n canMoveNode,\n moveNode,\n appendNode,\n removeNode,\n insertNodeBefore,\n insertNodeAfter,\n }\n}","<script setup lang=\"ts\" generic=\"T extends Record<string, any> = any\">\nimport { computed } from 'vue'\nimport type {\n GrTreeAllowDropType,\n GrTreeInstance,\n GrTreeNode,\n GrTreeNodeDropType,\n} from './grTreeTypes'\nimport { createGrTreeDataAdapter } from './grTreeDataAdapter'\nimport { createGrTreeInteractionContext } from './grTreeInteractionContext'\nimport { createGrTreeStore } from './grTreeStore'\nimport type {\n GrTreeBranchLineColor,\n GrTreeNodeClass,\n GrTreeProps,\n GrTreeVisibleRow,\n GrTreeVisibleTreeRow,\n} from './grTreeProps'\n\ndefineOptions({\n name: 'GrTree',\n})\n\nconst DEFAULT_BRANCH_LINE_COLOR = 'var(--ds-tree-branch-line-default-color, #e2e8f0)'\n\nconst props = withDefaults(defineProps<GrTreeProps<T>>(), {\n props: () => ({\n children: 'children',\n label: 'label',\n }),\n nodeKey: 'id' as any,\n defaultExpandedKeys: () => [],\n highlightCurrent: true,\n indent: 0,\n expandIcon: 'i-lucide-chevron-right',\n collapseIcon: 'i-lucide-chevron-right',\n toggleIconRotate: true,\n branchLine: false,\n branchLineColor: undefined,\n branchLineActiveColor: undefined,\n draggable: false,\n dragHandleIcon: 'i-lucide-grip-vertical',\n dragLabel: 'Drag',\n expandLabel: 'Expand',\n collapseLabel: 'Collapse',\n rowClass: undefined,\n dragHandleClass: undefined,\n toggleClass: undefined,\n toggleIconClass: undefined,\n toggleSpacerClass: undefined,\n contentClass: undefined,\n internalRows: undefined,\n internalNested: false,\n internalStore: undefined,\n})\n\nconst emit = defineEmits<{\n (event: 'nodeClick', data: T, node: GrTreeNode<T>): void\n (event: 'nodeExpand', data: T, node: GrTreeNode<T>): void\n (event: 'nodeCollapse', data: T, node: GrTreeNode<T>): void\n (event: 'nodeDrop', draggingNode: GrTreeNode<T>, dropNode: GrTreeNode<T>, dropType: GrTreeNodeDropType): void\n}>()\n\ndefineSlots<{\n default?: (props: { node: GrTreeNode<T>; data: T }) => any\n}>()\n\nconst dataAdapter = createGrTreeDataAdapter(props)\nconst treeStore = props.internalStore ?? createGrTreeStore({\n adapter: dataAdapter,\n data: () => props.data,\n defaultExpandedKeys: () => props.defaultExpandedKeys,\n filterNodeMethod: () => props.filterNodeMethod,\n})\nconst interactionContext = props.internalInteractionContext ?? createGrTreeInteractionContext(props, {\n emitNodeClick: (data, node) => emit('nodeClick', data, node),\n emitNodeExpand: (data, node) => emit('nodeExpand', data, node),\n emitNodeCollapse: (data, node) => emit('nodeCollapse', data, node),\n emitNodeDrop: (draggingNode, dropNode, dropType) => emit('nodeDrop', draggingNode, dropNode, dropType),\n})\n\nconst treeProps = props as Readonly<GrTreeProps<T>>\nconst currentKey = treeStore.currentKey\nconst hoveredKey = interactionContext.hoveredKey\nconst dropTarget = interactionContext.dropTarget\n\nconst visibleRows = computed<GrTreeVisibleTreeRow<T>[]>(() => {\n if (props.internalRows)\n return props.internalRows\n\n const { roots } = treeStore.treeModel.value\n const { isActive, subtreeHasMatch, matchedKeys, autoExpandKeys } = treeStore.filterInfo.value\n\n const walk = (nodes: GrTreeNode<T>[]): GrTreeVisibleTreeRow<T>[] => {\n const rows: GrTreeVisibleTreeRow<T>[] = []\n\n for (const node of nodes) {\n if (isActive && !subtreeHasMatch.get(node.key))\n continue\n\n const isLeaf = node.childNodes.length === 0\n const isMatched = matchedKeys.has(node.key)\n const isExpanded = treeStore.isExpandedKey(node.key) || (isActive && autoExpandKeys.has(node.key))\n\n rows.push({\n node,\n isExpanded,\n isLeaf,\n isMatched,\n children: isExpanded ? walk(node.childNodes) : [],\n })\n }\n\n return rows\n }\n\n return walk(roots)\n})\n\nfunction onRowClick(node: GrTreeNode<T>) {\n treeStore.setCurrentKey(node.key)\n interactionContext.emitNodeClick(node.data, node)\n}\n\nfunction onRowMouseEnter(node: GrTreeNode<T>) {\n hoveredKey.value = node.key\n}\n\nfunction onRowMouseLeave(node: GrTreeNode<T>) {\n if (hoveredKey.value === node.key)\n hoveredKey.value = undefined\n}\n\nfunction toggleExpand(node: GrTreeNode<T>) {\n const expanded = !treeStore.isExpandedKey(node.key)\n treeStore.toggleExpand(node)\n\n if (expanded)\n interactionContext.emitNodeExpand(node.data, node)\n else\n interactionContext.emitNodeCollapse(node.data, node)\n}\n\n// Drag & drop\nfunction canDrag(node: GrTreeNode<T>): boolean {\n return interactionContext.canDrag(node)\n}\n\nfunction shouldShowDragHandle(node: GrTreeNode<T>): boolean {\n return canDrag(node) && hoveredKey.value === node.key\n}\n\nfunction resolveDropType(evt: DragEvent, el: HTMLElement): GrTreeNodeDropType {\n const rect = el.getBoundingClientRect()\n const y = evt.clientY - rect.top\n const third = rect.height / 3\n if (y < third)\n return 'prev'\n if (y > third * 2)\n return 'next'\n return 'inner'\n}\n\nfunction canDrop(drag: GrTreeNode<T>, target: GrTreeNode<T>, type: GrTreeAllowDropType): boolean {\n return interactionContext.canDrop(drag, target, type)\n}\n\nfunction onDragStart(evt: DragEvent, node: GrTreeNode<T>) {\n if (!canDrag(node)) {\n evt.preventDefault()\n return\n }\n\n interactionContext.draggingNode.value = node\n interactionContext.dropTarget.value = null\n try {\n evt.dataTransfer?.setData('text/plain', String(node.key))\n }\n catch {\n // ignore\n }\n if (evt.dataTransfer)\n evt.dataTransfer.effectAllowed = 'move'\n}\n\nfunction onDragEnd() {\n interactionContext.resetDragState()\n}\n\nfunction onDragOver(evt: DragEvent, node: GrTreeNode<T>, rowEl: HTMLElement) {\n const drag = interactionContext.draggingNode.value\n if (!treeProps.draggable || !drag)\n return\n\n // required for `drop` to fire\n evt.preventDefault()\n\n const type = resolveDropType(evt, rowEl)\n const allowed = treeStore.canMoveNode(drag, node, type) && canDrop(drag, node, type)\n interactionContext.dropTarget.value = { key: node.key, type, allowed }\n if (evt.dataTransfer)\n evt.dataTransfer.dropEffect = allowed ? 'move' : 'none'\n}\n\nfunction onDrop(evt: DragEvent, node: GrTreeNode<T>) {\n const drag = interactionContext.draggingNode.value\n const target = interactionContext.dropTarget.value\n if (!treeProps.draggable || !drag || !target)\n return\n\n evt.preventDefault()\n\n if (target.key === node.key && target.allowed) {\n const movedNode = treeStore.moveNode(drag, node, target.type)\n if (movedNode) {\n const dropNode = treeStore.getNode(node.key) ?? node\n interactionContext.emitNodeDrop(movedNode, dropNode, target.type)\n }\n }\n\n interactionContext.resetDragState()\n}\n\nfunction filter(value: string) {\n treeStore.filter(value)\n}\n\nfunction resolveNodeClass(classValue: GrTreeNodeClass<T> | undefined, row: GrTreeVisibleRow<T>) {\n if (!classValue)\n return undefined\n\n return typeof classValue === 'function'\n ? classValue(row)\n : classValue\n}\n\nfunction resolveBranchLineColorValue(color: GrTreeBranchLineColor<T> | undefined, node: GrTreeNode<T>) {\n if (!color)\n return undefined\n\n return typeof color === 'function'\n ? color(node) ?? undefined\n : color\n}\n\nfunction isBranchLineActive(node: GrTreeNode<T>) {\n const selectedKey = currentKey.value\n\n if (selectedKey == null)\n return false\n\n if (node.key === selectedKey)\n return true\n\n return node.childNodes.some(child => child.key === selectedKey && !treeStore.isExpandedKey(child.key))\n}\n\nfunction resolveBranchLineColor(node: GrTreeNode<T>) {\n const defaultColor = resolveBranchLineColorValue(treeProps.branchLineColor, node) ?? DEFAULT_BRANCH_LINE_COLOR\n\n if (!isBranchLineActive(node))\n return defaultColor\n\n return resolveBranchLineColorValue(treeProps.branchLineActiveColor, node) ?? defaultColor\n}\n\nfunction resolveChildrenWrapStyle(row: GrTreeVisibleTreeRow<T>) {\n if (!treeProps.branchLine)\n return {\n }\n\n return {\n '--ds-tree-branch-line-color': resolveBranchLineColor(row.node),\n }\n}\n\ndefineExpose<GrTreeInstance<T>>({\n appendNode: treeStore.appendNode,\n filter,\n getCurrentNode: treeStore.getCurrentNode,\n setCurrentKey: treeStore.setCurrentKey,\n getCurrentKey: treeStore.getCurrentKey,\n getNode: treeStore.getNode,\n insertNodeAfter: treeStore.insertNodeAfter,\n insertNodeBefore: treeStore.insertNodeBefore,\n removeNode: treeStore.removeNode,\n setCurrentNode: treeStore.setCurrentNode,\n})\n</script>\n\n<template>\n <div\n :data-ds-tree=\"props.internalNested ? undefined : ''\"\n :class=\"props.internalNested ? 'ds-tree__children' : 'ds-tree'\"\n :role=\"props.internalNested ? 'group' : 'tree'\"\n >\n <div\n v-for=\"row in visibleRows\"\n :key=\"row.node.key\"\n data-ds-tree-node\n role=\"treeitem\"\n :aria-level=\"row.node.level\"\n :aria-expanded=\"row.isLeaf ? undefined : row.isExpanded\"\n >\n <div\n data-ds-tree-row\n class=\"ds-tree__row py-2 px-2\"\n :class=\"[\n treeProps.highlightCurrent && currentKey === row.node.key ? 'ds-tree__row--current' : '',\n row.isMatched ? 'ds-tree__row--matched' : '',\n dropTarget?.key === row.node.key && dropTarget.allowed && dropTarget.type === 'inner' ? 'ds-tree__row--drop-inner' : '',\n dropTarget?.key === row.node.key && dropTarget.allowed && dropTarget.type === 'prev' ? 'ds-tree__row--drop-prev' : '',\n dropTarget?.key === row.node.key && dropTarget.allowed && dropTarget.type === 'next' ? 'ds-tree__row--drop-next' : '',\n resolveNodeClass(treeProps.rowClass, row),\n ]\"\n tabindex=\"0\"\n @click=\"onRowClick(row.node)\"\n @drop=\"onDrop($event, row.node)\"\n @dragover=\"onDragOver($event, row.node, $event.currentTarget as HTMLElement)\"\n @mouseenter=\"onRowMouseEnter(row.node)\"\n @mouseleave=\"onRowMouseLeave(row.node)\"\n >\n <button\n v-if=\"treeProps.draggable\"\n type=\"button\"\n data-ds-tree-drag-handle\n class=\"ds-tree__drag-handle\"\n :class=\"[\n shouldShowDragHandle(row.node) ? 'ds-tree__drag-handle--visible' : '',\n canDrag(row.node) ? '' : 'ds-tree__drag-handle--disabled',\n resolveNodeClass(treeProps.dragHandleClass, row),\n ]\"\n :aria-label=\"treeProps.dragLabel\"\n :draggable=\"canDrag(row.node)\"\n @click.stop\n @mousedown.stop\n @dragstart=\"onDragStart($event, row.node)\"\n @dragend=\"onDragEnd\"\n >\n <span class=\"ds-tree__drag-icon\" :class=\"treeProps.dragHandleIcon\" />\n </button>\n\n <button\n v-if=\"!row.isLeaf\"\n data-ds-tree-toggle\n type=\"button\"\n class=\"ds-tree__toggle\"\n :class=\"resolveNodeClass(treeProps.toggleClass, row)\"\n :aria-label=\"row.isExpanded ? treeProps.collapseLabel : treeProps.expandLabel\"\n @click.stop=\"toggleExpand(row.node)\"\n >\n <span\n class=\"ds-tree__toggle-icon\"\n :class=\"[\n row.isExpanded ? treeProps.collapseIcon : treeProps.expandIcon,\n row.isExpanded && treeProps.toggleIconRotate ? 'ds-tree__toggle-icon--expanded' : '',\n resolveNodeClass(treeProps.toggleIconClass, row),\n ]\"\n />\n </button>\n <span\n v-else\n class=\"ds-tree__toggle-spacer\"\n :class=\"resolveNodeClass(treeProps.toggleSpacerClass, row)\"\n />\n\n <div class=\"ds-tree__content\" :class=\"resolveNodeClass(treeProps.contentClass, row)\">\n <slot\n :node=\"row.node\"\n :data=\"row.node.data\"\n >\n <span class=\"ds-tree__label\">{{ row.node.label }}</span>\n </slot>\n </div>\n </div>\n\n <div\n v-if=\"row.children.length\"\n class=\"ds-tree__children-wrap ml-6\"\n :class=\"treeProps.branchLine ? 'ds-tree__children-wrap--with-branch' : ''\"\n :style=\"resolveChildrenWrapStyle(row)\"\n >\n <GrTree\n v-bind=\"props\"\n :data=\"[]\"\n :internal-rows=\"row.children\"\n internal-nested\n :internal-store=\"treeStore\"\n :internal-interaction-context=\"interactionContext\"\n >\n <template #default=\"slotProps\">\n <slot v-bind=\"slotProps\">\n <span class=\"ds-tree__label\">{{ slotProps.node.label }}</span>\n </slot>\n </template>\n </GrTree>\n </div>\n </div>\n </div>\n</template>\n\n<style scoped>\n.ds-tree {\n --ds-tree-gap: 2px;\n --ds-tree-children-pl: 10px;\n --ds-tree-row-min-height: 28px;\n --ds-tree-row-radius: 8px;\n --ds-tree-row-pr: 8px;\n --ds-tree-row-color: var(--fg);\n --ds-tree-row-hover-bg: color-mix(in srgb, var(--primary, #000) 10%, transparent);\n --ds-tree-row-current-bg: color-mix(in srgb, var(--primary, #000) 5%, transparent);\n --ds-tree-row-current-hover-bg: color-mix(in srgb, var(--primary, #000) 16%, transparent);\n --ds-tree-drag-handle-size: 24px;\n --ds-tree-drag-handle-mr: 0;\n --ds-tree-drag-handle-radius: 6px;\n --ds-tree-drag-handle-color: inherit;\n --ds-tree-drag-handle-opacity: 0.55;\n --ds-tree-drag-handle-hover-bg: color-mix(in srgb, var(--muted, #000) 22%, transparent);\n --ds-tree-drag-handle-hover-color: var(--ds-tree-drag-handle-color);\n --ds-tree-drag-handle-hover-opacity: 0.9;\n --ds-tree-drag-handle-disabled-opacity: 0.25;\n --ds-tree-toggle-size: 24px;\n --ds-tree-toggle-mr: 0;\n --ds-tree-toggle-radius: 6px;\n --ds-tree-toggle-color: inherit;\n --ds-tree-toggle-hover-bg: color-mix(in srgb, var(--muted, #000) 25%, transparent);\n --ds-tree-toggle-hover-color: var(--ds-tree-toggle-color);\n --ds-tree-icon-size: 16px;\n --ds-tree-content-gap: 8px;\n --ds-tree-branch-line-default-color: var(--ds-tree-row-current-bg);\n --ds-tree-branch-line-width: 2px;\n display: flex;\n flex-direction: column;\n gap: var(--ds-tree-gap);\n}\n\n.ds-tree__children {\n display: flex;\n flex-direction: column;\n gap: var(--ds-tree-gap);\n}\n\n.ds-tree__children-wrap {\n --ds-tree-branch-line-color: var(--ds-tree-branch-line-default-color);\n display: flex;\n flex-direction: column;\n gap: var(--ds-tree-gap);\n padding-left: var(--ds-tree-children-pl, 10px);\n border-left: var(--ds-tree-branch-line-width) solid transparent;\n}\n\n.ds-tree__children-wrap--with-branch {\n border-left-color: var(--ds-tree-branch-line-color, var(--ds-tree-branch-line-default-color));\n}\n\n.ds-tree__row {\n position: relative;\n display: flex;\n align-items: center;\n min-height: var(--ds-tree-row-min-height);\n border-radius: var(--ds-tree-row-radius);\n padding-right: var(--ds-tree-row-pr);\n cursor: default;\n user-select: none;\n outline: none;\n color: var(--ds-tree-row-color);\n}\n\n.ds-tree__row:hover {\n background: var(--ds-tree-row-hover-bg);\n}\n\n.ds-tree__row--current {\n background: var(--ds-tree-row-current-bg);\n}\n\n.ds-tree__row--current:hover {\n background: var(--ds-tree-row-current-hover-bg);\n}\n\n.ds-tree__row--matched .ds-tree__label {\n font-weight: 600;\n}\n\n.ds-tree__drag-handle {\n width: var(--ds-tree-drag-handle-size);\n height: var(--ds-tree-drag-handle-size);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n margin-right: var(--ds-tree-drag-handle-mr);\n border-radius: var(--ds-tree-drag-handle-radius);\n color: var(--ds-tree-drag-handle-color);\n cursor: grab;\n visibility: hidden;\n pointer-events: none;\n opacity: 0;\n}\n\n.ds-tree__drag-handle--visible {\n visibility: visible;\n pointer-events: auto;\n opacity: var(--ds-tree-drag-handle-opacity);\n}\n\n.ds-tree__drag-handle:hover {\n background: var(--ds-tree-drag-handle-hover-bg);\n color: var(--ds-tree-drag-handle-hover-color);\n opacity: var(--ds-tree-drag-handle-hover-opacity);\n}\n\n.ds-tree__drag-handle:active {\n cursor: grabbing;\n}\n\n.ds-tree__drag-handle--disabled {\n cursor: default;\n opacity: var(--ds-tree-drag-handle-disabled-opacity);\n}\n\n.ds-tree__drag-icon {\n width: var(--ds-tree-icon-size);\n height: var(--ds-tree-icon-size);\n}\n\n.ds-tree__toggle {\n width: var(--ds-tree-toggle-size);\n height: var(--ds-tree-toggle-size);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n margin-right: var(--ds-tree-toggle-mr);\n border-radius: var(--ds-tree-toggle-radius);\n color: var(--ds-tree-toggle-color);\n}\n\n.ds-tree__toggle:hover {\n background: var(--ds-tree-toggle-hover-bg);\n color: var(--ds-tree-toggle-hover-color);\n}\n\n.ds-tree__toggle-icon {\n width: var(--ds-tree-icon-size);\n height: var(--ds-tree-icon-size);\n transition: transform 120ms ease;\n}\n\n.ds-tree__toggle-icon--expanded {\n transform: rotate(90deg);\n}\n\n.ds-tree__toggle-spacer {\n width: var(--ds-tree-toggle-size);\n height: var(--ds-tree-toggle-size);\n margin-right: var(--ds-tree-toggle-mr);\n display: inline-block;\n}\n\n.ds-tree__content {\n min-width: 0;\n display: flex;\n align-items: center;\n gap: var(--ds-tree-content-gap);\n}\n\n.ds-tree__label {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.ds-tree__row--drop-inner {\n outline: 2px solid color-mix(in srgb, var(--primary, #000) 40%, transparent);\n}\n\n.ds-tree__row--drop-prev::before,\n.ds-tree__row--drop-next::after {\n content: '';\n position: absolute;\n left: 8px;\n right: 8px;\n height: 2px;\n background: color-mix(in srgb, var(--primary, #000) 55%, transparent);\n}\n\n.ds-tree__row--drop-prev::before {\n top: 2px;\n}\n\n.ds-tree__row--drop-next::after {\n bottom: 2px;\n}\n</style>\n","<script setup lang=\"ts\" generic=\"T extends Record<string, any> = any\">\nimport { computed } from 'vue'\nimport type {\n GrTreeAllowDropType,\n GrTreeInstance,\n GrTreeNode,\n GrTreeNodeDropType,\n} from './grTreeTypes'\nimport { createGrTreeDataAdapter } from './grTreeDataAdapter'\nimport { createGrTreeInteractionContext } from './grTreeInteractionContext'\nimport { createGrTreeStore } from './grTreeStore'\nimport type {\n GrTreeBranchLineColor,\n GrTreeNodeClass,\n GrTreeProps,\n GrTreeVisibleRow,\n GrTreeVisibleTreeRow,\n} from './grTreeProps'\n\ndefineOptions({\n name: 'GrTree',\n})\n\nconst DEFAULT_BRANCH_LINE_COLOR = 'var(--ds-tree-branch-line-default-color, #e2e8f0)'\n\nconst props = withDefaults(defineProps<GrTreeProps<T>>(), {\n props: () => ({\n children: 'children',\n label: 'label',\n }),\n nodeKey: 'id' as any,\n defaultExpandedKeys: () => [],\n highlightCurrent: true,\n indent: 0,\n expandIcon: 'i-lucide-chevron-right',\n collapseIcon: 'i-lucide-chevron-right',\n toggleIconRotate: true,\n branchLine: false,\n branchLineColor: undefined,\n branchLineActiveColor: undefined,\n draggable: false,\n dragHandleIcon: 'i-lucide-grip-vertical',\n dragLabel: 'Drag',\n expandLabel: 'Expand',\n collapseLabel: 'Collapse',\n rowClass: undefined,\n dragHandleClass: undefined,\n toggleClass: undefined,\n toggleIconClass: undefined,\n toggleSpacerClass: undefined,\n contentClass: undefined,\n internalRows: undefined,\n internalNested: false,\n internalStore: undefined,\n})\n\nconst emit = defineEmits<{\n (event: 'nodeClick', data: T, node: GrTreeNode<T>): void\n (event: 'nodeExpand', data: T, node: GrTreeNode<T>): void\n (event: 'nodeCollapse', data: T, node: GrTreeNode<T>): void\n (event: 'nodeDrop', draggingNode: GrTreeNode<T>, dropNode: GrTreeNode<T>, dropType: GrTreeNodeDropType): void\n}>()\n\ndefineSlots<{\n default?: (props: { node: GrTreeNode<T>; data: T }) => any\n}>()\n\nconst dataAdapter = createGrTreeDataAdapter(props)\nconst treeStore = props.internalStore ?? createGrTreeStore({\n adapter: dataAdapter,\n data: () => props.data,\n defaultExpandedKeys: () => props.defaultExpandedKeys,\n filterNodeMethod: () => props.filterNodeMethod,\n})\nconst interactionContext = props.internalInteractionContext ?? createGrTreeInteractionContext(props, {\n emitNodeClick: (data, node) => emit('nodeClick', data, node),\n emitNodeExpand: (data, node) => emit('nodeExpand', data, node),\n emitNodeCollapse: (data, node) => emit('nodeCollapse', data, node),\n emitNodeDrop: (draggingNode, dropNode, dropType) => emit('nodeDrop', draggingNode, dropNode, dropType),\n})\n\nconst treeProps = props as Readonly<GrTreeProps<T>>\nconst currentKey = treeStore.currentKey\nconst hoveredKey = interactionContext.hoveredKey\nconst dropTarget = interactionContext.dropTarget\n\nconst visibleRows = computed<GrTreeVisibleTreeRow<T>[]>(() => {\n if (props.internalRows)\n return props.internalRows\n\n const { roots } = treeStore.treeModel.value\n const { isActive, subtreeHasMatch, matchedKeys, autoExpandKeys } = treeStore.filterInfo.value\n\n const walk = (nodes: GrTreeNode<T>[]): GrTreeVisibleTreeRow<T>[] => {\n const rows: GrTreeVisibleTreeRow<T>[] = []\n\n for (const node of nodes) {\n if (isActive && !subtreeHasMatch.get(node.key))\n continue\n\n const isLeaf = node.childNodes.length === 0\n const isMatched = matchedKeys.has(node.key)\n const isExpanded = treeStore.isExpandedKey(node.key) || (isActive && autoExpandKeys.has(node.key))\n\n rows.push({\n node,\n isExpanded,\n isLeaf,\n isMatched,\n children: isExpanded ? walk(node.childNodes) : [],\n })\n }\n\n return rows\n }\n\n return walk(roots)\n})\n\nfunction onRowClick(node: GrTreeNode<T>) {\n treeStore.setCurrentKey(node.key)\n interactionContext.emitNodeClick(node.data, node)\n}\n\nfunction onRowMouseEnter(node: GrTreeNode<T>) {\n hoveredKey.value = node.key\n}\n\nfunction onRowMouseLeave(node: GrTreeNode<T>) {\n if (hoveredKey.value === node.key)\n hoveredKey.value = undefined\n}\n\nfunction toggleExpand(node: GrTreeNode<T>) {\n const expanded = !treeStore.isExpandedKey(node.key)\n treeStore.toggleExpand(node)\n\n if (expanded)\n interactionContext.emitNodeExpand(node.data, node)\n else\n interactionContext.emitNodeCollapse(node.data, node)\n}\n\n// Drag & drop\nfunction canDrag(node: GrTreeNode<T>): boolean {\n return interactionContext.canDrag(node)\n}\n\nfunction shouldShowDragHandle(node: GrTreeNode<T>): boolean {\n return canDrag(node) && hoveredKey.value === node.key\n}\n\nfunction resolveDropType(evt: DragEvent, el: HTMLElement): GrTreeNodeDropType {\n const rect = el.getBoundingClientRect()\n const y = evt.clientY - rect.top\n const third = rect.height / 3\n if (y < third)\n return 'prev'\n if (y > third * 2)\n return 'next'\n return 'inner'\n}\n\nfunction canDrop(drag: GrTreeNode<T>, target: GrTreeNode<T>, type: GrTreeAllowDropType): boolean {\n return interactionContext.canDrop(drag, target, type)\n}\n\nfunction onDragStart(evt: DragEvent, node: GrTreeNode<T>) {\n if (!canDrag(node)) {\n evt.preventDefault()\n return\n }\n\n interactionContext.draggingNode.value = node\n interactionContext.dropTarget.value = null\n try {\n evt.dataTransfer?.setData('text/plain', String(node.key))\n }\n catch {\n // ignore\n }\n if (evt.dataTransfer)\n evt.dataTransfer.effectAllowed = 'move'\n}\n\nfunction onDragEnd() {\n interactionContext.resetDragState()\n}\n\nfunction onDragOver(evt: DragEvent, node: GrTreeNode<T>, rowEl: HTMLElement) {\n const drag = interactionContext.draggingNode.value\n if (!treeProps.draggable || !drag)\n return\n\n // required for `drop` to fire\n evt.preventDefault()\n\n const type = resolveDropType(evt, rowEl)\n const allowed = treeStore.canMoveNode(drag, node, type) && canDrop(drag, node, type)\n interactionContext.dropTarget.value = { key: node.key, type, allowed }\n if (evt.dataTransfer)\n evt.dataTransfer.dropEffect = allowed ? 'move' : 'none'\n}\n\nfunction onDrop(evt: DragEvent, node: GrTreeNode<T>) {\n const drag = interactionContext.draggingNode.value\n const target = interactionContext.dropTarget.value\n if (!treeProps.draggable || !drag || !target)\n return\n\n evt.preventDefault()\n\n if (target.key === node.key && target.allowed) {\n const movedNode = treeStore.moveNode(drag, node, target.type)\n if (movedNode) {\n const dropNode = treeStore.getNode(node.key) ?? node\n interactionContext.emitNodeDrop(movedNode, dropNode, target.type)\n }\n }\n\n interactionContext.resetDragState()\n}\n\nfunction filter(value: string) {\n treeStore.filter(value)\n}\n\nfunction resolveNodeClass(classValue: GrTreeNodeClass<T> | undefined, row: GrTreeVisibleRow<T>) {\n if (!classValue)\n return undefined\n\n return typeof classValue === 'function'\n ? classValue(row)\n : classValue\n}\n\nfunction resolveBranchLineColorValue(color: GrTreeBranchLineColor<T> | undefined, node: GrTreeNode<T>) {\n if (!color)\n return undefined\n\n return typeof color === 'function'\n ? color(node) ?? undefined\n : color\n}\n\nfunction isBranchLineActive(node: GrTreeNode<T>) {\n const selectedKey = currentKey.value\n\n if (selectedKey == null)\n return false\n\n if (node.key === selectedKey)\n return true\n\n return node.childNodes.some(child => child.key === selectedKey && !treeStore.isExpandedKey(child.key))\n}\n\nfunction resolveBranchLineColor(node: GrTreeNode<T>) {\n const defaultColor = resolveBranchLineColorValue(treeProps.branchLineColor, node) ?? DEFAULT_BRANCH_LINE_COLOR\n\n if (!isBranchLineActive(node))\n return defaultColor\n\n return resolveBranchLineColorValue(treeProps.branchLineActiveColor, node) ?? defaultColor\n}\n\nfunction resolveChildrenWrapStyle(row: GrTreeVisibleTreeRow<T>) {\n if (!treeProps.branchLine)\n return {\n }\n\n return {\n '--ds-tree-branch-line-color': resolveBranchLineColor(row.node),\n }\n}\n\ndefineExpose<GrTreeInstance<T>>({\n appendNode: treeStore.appendNode,\n filter,\n getCurrentNode: treeStore.getCurrentNode,\n setCurrentKey: treeStore.setCurrentKey,\n getCurrentKey: treeStore.getCurrentKey,\n getNode: treeStore.getNode,\n insertNodeAfter: treeStore.insertNodeAfter,\n insertNodeBefore: treeStore.insertNodeBefore,\n removeNode: treeStore.removeNode,\n setCurrentNode: treeStore.setCurrentNode,\n})\n</script>\n\n<template>\n <div\n :data-ds-tree=\"props.internalNested ? undefined : ''\"\n :class=\"props.internalNested ? 'ds-tree__children' : 'ds-tree'\"\n :role=\"props.internalNested ? 'group' : 'tree'\"\n >\n <div\n v-for=\"row in visibleRows\"\n :key=\"row.node.key\"\n data-ds-tree-node\n role=\"treeitem\"\n :aria-level=\"row.node.level\"\n :aria-expanded=\"row.isLeaf ? undefined : row.isExpanded\"\n >\n <div\n data-ds-tree-row\n class=\"ds-tree__row py-2 px-2\"\n :class=\"[\n treeProps.highlightCurrent && currentKey === row.node.key ? 'ds-tree__row--current' : '',\n row.isMatched ? 'ds-tree__row--matched' : '',\n dropTarget?.key === row.node.key && dropTarget.allowed && dropTarget.type === 'inner' ? 'ds-tree__row--drop-inner' : '',\n dropTarget?.key === row.node.key && dropTarget.allowed && dropTarget.type === 'prev' ? 'ds-tree__row--drop-prev' : '',\n dropTarget?.key === row.node.key && dropTarget.allowed && dropTarget.type === 'next' ? 'ds-tree__row--drop-next' : '',\n resolveNodeClass(treeProps.rowClass, row),\n ]\"\n tabindex=\"0\"\n @click=\"onRowClick(row.node)\"\n @drop=\"onDrop($event, row.node)\"\n @dragover=\"onDragOver($event, row.node, $event.currentTarget as HTMLElement)\"\n @mouseenter=\"onRowMouseEnter(row.node)\"\n @mouseleave=\"onRowMouseLeave(row.node)\"\n >\n <button\n v-if=\"treeProps.draggable\"\n type=\"button\"\n data-ds-tree-drag-handle\n class=\"ds-tree__drag-handle\"\n :class=\"[\n shouldShowDragHandle(row.node) ? 'ds-tree__drag-handle--visible' : '',\n canDrag(row.node) ? '' : 'ds-tree__drag-handle--disabled',\n resolveNodeClass(treeProps.dragHandleClass, row),\n ]\"\n :aria-label=\"treeProps.dragLabel\"\n :draggable=\"canDrag(row.node)\"\n @click.stop\n @mousedown.stop\n @dragstart=\"onDragStart($event, row.node)\"\n @dragend=\"onDragEnd\"\n >\n <span class=\"ds-tree__drag-icon\" :class=\"treeProps.dragHandleIcon\" />\n </button>\n\n <button\n v-if=\"!row.isLeaf\"\n data-ds-tree-toggle\n type=\"button\"\n class=\"ds-tree__toggle\"\n :class=\"resolveNodeClass(treeProps.toggleClass, row)\"\n :aria-label=\"row.isExpanded ? treeProps.collapseLabel : treeProps.expandLabel\"\n @click.stop=\"toggleExpand(row.node)\"\n >\n <span\n class=\"ds-tree__toggle-icon\"\n :class=\"[\n row.isExpanded ? treeProps.collapseIcon : treeProps.expandIcon,\n row.isExpanded && treeProps.toggleIconRotate ? 'ds-tree__toggle-icon--expanded' : '',\n resolveNodeClass(treeProps.toggleIconClass, row),\n ]\"\n />\n </button>\n <span\n v-else\n class=\"ds-tree__toggle-spacer\"\n :class=\"resolveNodeClass(treeProps.toggleSpacerClass, row)\"\n />\n\n <div class=\"ds-tree__content\" :class=\"resolveNodeClass(treeProps.contentClass, row)\">\n <slot\n :node=\"row.node\"\n :data=\"row.node.data\"\n >\n <span class=\"ds-tree__label\">{{ row.node.label }}</span>\n </slot>\n </div>\n </div>\n\n <div\n v-if=\"row.children.length\"\n class=\"ds-tree__children-wrap ml-6\"\n :class=\"treeProps.branchLine ? 'ds-tree__children-wrap--with-branch' : ''\"\n :style=\"resolveChildrenWrapStyle(row)\"\n >\n <GrTree\n v-bind=\"props\"\n :data=\"[]\"\n :internal-rows=\"row.children\"\n internal-nested\n :internal-store=\"treeStore\"\n :internal-interaction-context=\"interactionContext\"\n >\n <template #default=\"slotProps\">\n <slot v-bind=\"slotProps\">\n <span class=\"ds-tree__label\">{{ slotProps.node.label }}</span>\n </slot>\n </template>\n </GrTree>\n </div>\n </div>\n </div>\n</template>\n\n<style scoped>\n.ds-tree {\n --ds-tree-gap: 2px;\n --ds-tree-children-pl: 10px;\n --ds-tree-row-min-height: 28px;\n --ds-tree-row-radius: 8px;\n --ds-tree-row-pr: 8px;\n --ds-tree-row-color: var(--fg);\n --ds-tree-row-hover-bg: color-mix(in srgb, var(--primary, #000) 10%, transparent);\n --ds-tree-row-current-bg: color-mix(in srgb, var(--primary, #000) 5%, transparent);\n --ds-tree-row-current-hover-bg: color-mix(in srgb, var(--primary, #000) 16%, transparent);\n --ds-tree-drag-handle-size: 24px;\n --ds-tree-drag-handle-mr: 0;\n --ds-tree-drag-handle-radius: 6px;\n --ds-tree-drag-handle-color: inherit;\n --ds-tree-drag-handle-opacity: 0.55;\n --ds-tree-drag-handle-hover-bg: color-mix(in srgb, var(--muted, #000) 22%, transparent);\n --ds-tree-drag-handle-hover-color: var(--ds-tree-drag-handle-color);\n --ds-tree-drag-handle-hover-opacity: 0.9;\n --ds-tree-drag-handle-disabled-opacity: 0.25;\n --ds-tree-toggle-size: 24px;\n --ds-tree-toggle-mr: 0;\n --ds-tree-toggle-radius: 6px;\n --ds-tree-toggle-color: inherit;\n --ds-tree-toggle-hover-bg: color-mix(in srgb, var(--muted, #000) 25%, transparent);\n --ds-tree-toggle-hover-color: var(--ds-tree-toggle-color);\n --ds-tree-icon-size: 16px;\n --ds-tree-content-gap: 8px;\n --ds-tree-branch-line-default-color: var(--ds-tree-row-current-bg);\n --ds-tree-branch-line-width: 2px;\n display: flex;\n flex-direction: column;\n gap: var(--ds-tree-gap);\n}\n\n.ds-tree__children {\n display: flex;\n flex-direction: column;\n gap: var(--ds-tree-gap);\n}\n\n.ds-tree__children-wrap {\n --ds-tree-branch-line-color: var(--ds-tree-branch-line-default-color);\n display: flex;\n flex-direction: column;\n gap: var(--ds-tree-gap);\n padding-left: var(--ds-tree-children-pl, 10px);\n border-left: var(--ds-tree-branch-line-width) solid transparent;\n}\n\n.ds-tree__children-wrap--with-branch {\n border-left-color: var(--ds-tree-branch-line-color, var(--ds-tree-branch-line-default-color));\n}\n\n.ds-tree__row {\n position: relative;\n display: flex;\n align-items: center;\n min-height: var(--ds-tree-row-min-height);\n border-radius: var(--ds-tree-row-radius);\n padding-right: var(--ds-tree-row-pr);\n cursor: default;\n user-select: none;\n outline: none;\n color: var(--ds-tree-row-color);\n}\n\n.ds-tree__row:hover {\n background: var(--ds-tree-row-hover-bg);\n}\n\n.ds-tree__row--current {\n background: var(--ds-tree-row-current-bg);\n}\n\n.ds-tree__row--current:hover {\n background: var(--ds-tree-row-current-hover-bg);\n}\n\n.ds-tree__row--matched .ds-tree__label {\n font-weight: 600;\n}\n\n.ds-tree__drag-handle {\n width: var(--ds-tree-drag-handle-size);\n height: var(--ds-tree-drag-handle-size);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n margin-right: var(--ds-tree-drag-handle-mr);\n border-radius: var(--ds-tree-drag-handle-radius);\n color: var(--ds-tree-drag-handle-color);\n cursor: grab;\n visibility: hidden;\n pointer-events: none;\n opacity: 0;\n}\n\n.ds-tree__drag-handle--visible {\n visibility: visible;\n pointer-events: auto;\n opacity: var(--ds-tree-drag-handle-opacity);\n}\n\n.ds-tree__drag-handle:hover {\n background: var(--ds-tree-drag-handle-hover-bg);\n color: var(--ds-tree-drag-handle-hover-color);\n opacity: var(--ds-tree-drag-handle-hover-opacity);\n}\n\n.ds-tree__drag-handle:active {\n cursor: grabbing;\n}\n\n.ds-tree__drag-handle--disabled {\n cursor: default;\n opacity: var(--ds-tree-drag-handle-disabled-opacity);\n}\n\n.ds-tree__drag-icon {\n width: var(--ds-tree-icon-size);\n height: var(--ds-tree-icon-size);\n}\n\n.ds-tree__toggle {\n width: var(--ds-tree-toggle-size);\n height: var(--ds-tree-toggle-size);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n margin-right: var(--ds-tree-toggle-mr);\n border-radius: var(--ds-tree-toggle-radius);\n color: var(--ds-tree-toggle-color);\n}\n\n.ds-tree__toggle:hover {\n background: var(--ds-tree-toggle-hover-bg);\n color: var(--ds-tree-toggle-hover-color);\n}\n\n.ds-tree__toggle-icon {\n width: var(--ds-tree-icon-size);\n height: var(--ds-tree-icon-size);\n transition: transform 120ms ease;\n}\n\n.ds-tree__toggle-icon--expanded {\n transform: rotate(90deg);\n}\n\n.ds-tree__toggle-spacer {\n width: var(--ds-tree-toggle-size);\n height: var(--ds-tree-toggle-size);\n margin-right: var(--ds-tree-toggle-mr);\n display: inline-block;\n}\n\n.ds-tree__content {\n min-width: 0;\n display: flex;\n align-items: center;\n gap: var(--ds-tree-content-gap);\n}\n\n.ds-tree__label {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.ds-tree__row--drop-inner {\n outline: 2px solid color-mix(in srgb, var(--primary, #000) 40%, transparent);\n}\n\n.ds-tree__row--drop-prev::before,\n.ds-tree__row--drop-next::after {\n content: '';\n position: absolute;\n left: 8px;\n right: 8px;\n height: 2px;\n background: color-mix(in srgb, var(--primary, #000) 55%, transparent);\n}\n\n.ds-tree__row--drop-prev::before {\n top: 2px;\n}\n\n.ds-tree__row--drop-next::after {\n bottom: 2px;\n}\n</style>\n"],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { t as GrTree_default } from "./chunks/GrTree-
|
|
2
|
-
import { n as grTreeSafelist, t as grTreeConfig } from "../../chunks/config-
|
|
1
|
+
import { t as GrTree_default } from "./chunks/GrTree-uZr5SyQI.js";
|
|
2
|
+
import { n as grTreeSafelist, t as grTreeConfig } from "../../chunks/config-BLa1TEGm2.js";
|
|
3
3
|
export { GrTree_default as GrTree, GrTree_default as default, grTreeConfig, grTreeSafelist };
|