@feugene/granularity 0.4.1 → 0.4.3

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.
Files changed (259) hide show
  1. package/dist/chunks/{adapter-C7fKeUa4.js → adapter-K6zZTzBi.js} +0 -2
  2. package/dist/chunks/{adapter-C7fKeUa4.js.map → adapter-K6zZTzBi.js.map} +1 -1
  3. package/dist/chunks/arrow-up-DNXrMoAI.js +0 -2
  4. package/dist/chunks/classTokens-BPeBXNzu.js +0 -2
  5. package/dist/chunks/{config-BUGfFjmC.js → config-1I95Zy4V.js} +0 -2
  6. package/dist/chunks/{config-BUGfFjmC.js.map → config-1I95Zy4V.js.map} +1 -1
  7. package/dist/chunks/config-2wgwWaAB.js +0 -2
  8. package/dist/chunks/{config-DBYCntwl.js → config-BA0BWYzs.js} +0 -2
  9. package/dist/chunks/{config-DBYCntwl.js.map → config-BA0BWYzs.js.map} +1 -1
  10. package/dist/chunks/{config-dD6Po-Cq.js → config-BCPyma1I.js} +0 -2
  11. package/dist/chunks/{config-dD6Po-Cq.js.map → config-BCPyma1I.js.map} +1 -1
  12. package/dist/chunks/{config-CYPU3ztl.js → config-BDlh6iNz.js} +1 -3
  13. package/dist/chunks/{config-CYPU3ztl.js.map → config-BDlh6iNz.js.map} +1 -1
  14. package/dist/chunks/config-BKRmlivc.js +0 -2
  15. package/dist/chunks/{config-CcmeMlic.js → config-BN-B2K4r.js} +1 -3
  16. package/dist/chunks/{config-CcmeMlic.js.map → config-BN-B2K4r.js.map} +1 -1
  17. package/dist/chunks/{config-C0b_3LJV.js → config-BNOf_qjD.js} +0 -2
  18. package/dist/chunks/{config-C0b_3LJV.js.map → config-BNOf_qjD.js.map} +1 -1
  19. package/dist/chunks/config-BaMO9dQh.js +0 -2
  20. package/dist/chunks/config-Bv2G0OU6.js +0 -2
  21. package/dist/chunks/{config-CxCAfXZ1.js → config-BvuQUBtZ.js} +0 -2
  22. package/dist/chunks/{config-CxCAfXZ1.js.map → config-BvuQUBtZ.js.map} +1 -1
  23. package/dist/chunks/config-BzZGpWsj.js +0 -2
  24. package/dist/chunks/{config-KGTIAFD92.js → config-C0j836dC.js} +0 -2
  25. package/dist/chunks/config-C0j836dC.js.map +1 -0
  26. package/dist/chunks/{config-D7iuXJbl.js → config-C2iI7_QX.js} +0 -2
  27. package/dist/chunks/{config-D7iuXJbl.js.map → config-C2iI7_QX.js.map} +1 -1
  28. package/dist/chunks/{config-BcFOkUhh.js → config-C4AlNm912.js} +1 -3
  29. package/dist/chunks/config-C4AlNm912.js.map +1 -0
  30. package/dist/chunks/{config-rFwazRKi.js → config-C5SJXHQ4.js} +0 -2
  31. package/dist/chunks/{config-rFwazRKi.js.map → config-C5SJXHQ4.js.map} +1 -1
  32. package/dist/chunks/config-C6SBJxcH.js +0 -2
  33. package/dist/chunks/{config-BzQ4S4Hb.js → config-CByfsV-z2.js} +0 -2
  34. package/dist/chunks/config-CByfsV-z2.js.map +1 -0
  35. package/dist/chunks/{config-rxFL-6yF2.js → config-CM7nbATU2.js} +0 -2
  36. package/dist/chunks/{config-rxFL-6yF2.js.map → config-CM7nbATU2.js.map} +1 -1
  37. package/dist/chunks/config-CMZE2fu0.js +0 -2
  38. package/dist/chunks/config-CU_CBd0k.js +0 -2
  39. package/dist/chunks/{config-BhvNm4Pp.js → config-CUgvsjZx.js} +0 -2
  40. package/dist/chunks/{config-BhvNm4Pp.js.map → config-CUgvsjZx.js.map} +1 -1
  41. package/dist/chunks/{config-DxqMXzNV2.js → config-CWvHiaqr2.js} +0 -2
  42. package/dist/chunks/{config-DxqMXzNV2.js.map → config-CWvHiaqr2.js.map} +1 -1
  43. package/dist/chunks/{config-CdAx6ify2.js → config-CgAY2WP9.js} +0 -2
  44. package/dist/chunks/config-CgAY2WP9.js.map +1 -0
  45. package/dist/chunks/{config-D1gSaT52.js → config-Cgc-D1K4.js} +0 -2
  46. package/dist/chunks/{config-D1gSaT52.js.map → config-Cgc-D1K4.js.map} +1 -1
  47. package/dist/chunks/{config-cn6knwud.js → config-D19pyP4D.js} +0 -2
  48. package/dist/chunks/{config-cn6knwud.js.map → config-D19pyP4D.js.map} +1 -1
  49. package/dist/chunks/{config-ug8O8epd.js → config-DCQO6H6h.js} +0 -2
  50. package/dist/chunks/{config-ug8O8epd.js.map → config-DCQO6H6h.js.map} +1 -1
  51. package/dist/chunks/{config-BXffa3ta.js → config-DEv4m-ZP.js} +0 -2
  52. package/dist/chunks/{config-BXffa3ta.js.map → config-DEv4m-ZP.js.map} +1 -1
  53. package/dist/chunks/config-DFRYOcrP.js +0 -2
  54. package/dist/chunks/{config-DlLE49_I.js → config-DTpwUHgF.js} +0 -2
  55. package/dist/chunks/{config-DlLE49_I.js.map → config-DTpwUHgF.js.map} +1 -1
  56. package/dist/chunks/{config-C2JKq8-2.js → config-DUtUkSzc.js} +1 -2
  57. package/dist/chunks/config-DUtUkSzc.js.map +1 -0
  58. package/dist/chunks/config-DW_RqmUp.js +0 -2
  59. package/dist/chunks/{config-CJeyaUTp.js → config-Da90XGsi.js} +0 -2
  60. package/dist/chunks/{config-CJeyaUTp.js.map → config-Da90XGsi.js.map} +1 -1
  61. package/dist/chunks/{config-CJbjLC5X.js → config-DgRJlF00.js} +0 -2
  62. package/dist/chunks/{config-CJbjLC5X.js.map → config-DgRJlF00.js.map} +1 -1
  63. package/dist/chunks/config-Dkq0HeLe.js +0 -2
  64. package/dist/chunks/{config-DwB5-qdP2.js → config-DmI1IQvI2.js} +0 -2
  65. package/dist/chunks/{config-DwB5-qdP2.js.map → config-DmI1IQvI2.js.map} +1 -1
  66. package/dist/chunks/{config-BRU5PR8_.js → config-Dnu4VuO0.js} +0 -2
  67. package/dist/chunks/{config-BRU5PR8_.js.map → config-Dnu4VuO0.js.map} +1 -1
  68. package/dist/chunks/config-DxqpV-KM.js +0 -2
  69. package/dist/chunks/config-TyzU6gLf.js +0 -2
  70. package/dist/chunks/{config-Bv5Dok4j.js → config-XwI6t8cn.js} +0 -2
  71. package/dist/chunks/{config-Bv5Dok4j.js.map → config-XwI6t8cn.js.map} +1 -1
  72. package/dist/chunks/{config-DvTUDLT1.js → config-bpQYM5O-.js} +0 -2
  73. package/dist/chunks/{config-DvTUDLT1.js.map → config-bpQYM5O-.js.map} +1 -1
  74. package/dist/chunks/{config-BbtK511H.js → config-etXh7Bsr2.js} +0 -2
  75. package/dist/chunks/config-etXh7Bsr2.js.map +1 -0
  76. package/dist/chunks/{config-BhubOeci.js → config-fCcRwjIB.js} +0 -2
  77. package/dist/chunks/{config-BhubOeci.js.map → config-fCcRwjIB.js.map} +1 -1
  78. package/dist/chunks/{config-D7tRu8u3.js → config-nfOMJXVs.js} +0 -2
  79. package/dist/chunks/{config-D7tRu8u3.js.map → config-nfOMJXVs.js.map} +1 -1
  80. package/dist/chunks/{config-BcpRsZTe.js → config-qJXIIY1E.js} +0 -2
  81. package/dist/chunks/{config-BcpRsZTe.js.map → config-qJXIIY1E.js.map} +1 -1
  82. package/dist/chunks/{config-Dzz9P-GV2.js → config-r6hzn2Bn2.js} +0 -2
  83. package/dist/chunks/{config-Dzz9P-GV2.js.map → config-r6hzn2Bn2.js.map} +1 -1
  84. package/dist/chunks/config-rQlbnEKn.js +0 -2
  85. package/dist/chunks/dialogShared-BtXUk6Zc.js +0 -2
  86. package/dist/chunks/{en-BMjJZttK.js → en-BeJa78lP.js} +0 -2
  87. package/dist/chunks/{en-BMjJZttK.js.map → en-BeJa78lP.js.map} +1 -1
  88. package/dist/chunks/{es-Cu_RlgIr.js → es-BPqm7rLm.js} +3 -5
  89. package/dist/chunks/{es-Cu_RlgIr.js.map → es-BPqm7rLm.js.map} +1 -1
  90. package/dist/chunks/{es-EYCf8G_1.js → es-axYOwwWD.js} +0 -2
  91. package/dist/chunks/{es-EYCf8G_1.js.map → es-axYOwwWD.js.map} +1 -1
  92. package/dist/chunks/{fileValidation-CgjTGoUx.js → fileValidation-CwJA8Vmn.js} +0 -2
  93. package/dist/chunks/{fileValidation-CgjTGoUx.js.map → fileValidation-CwJA8Vmn.js.map} +1 -1
  94. package/dist/chunks/grBadgeStyles-pqqbVgLk.js +0 -2
  95. package/dist/chunks/grButtonStyles-BxZW2x0-.js +0 -2
  96. package/dist/chunks/{grDropdownStyles-DQfLh-bp.js → grDropdownStyles-DMp7RrI9.js} +0 -2
  97. package/dist/chunks/{grDropdownStyles-DQfLh-bp.js.map → grDropdownStyles-DMp7RrI9.js.map} +1 -1
  98. package/dist/chunks/{grLoadingStyles-CERsxyk9.js → grLoadingStyles-CrxZHFL0.js} +0 -2
  99. package/dist/chunks/{grLoadingStyles-CERsxyk9.js.map → grLoadingStyles-CrxZHFL0.js.map} +1 -1
  100. package/dist/chunks/grModalStyles-Dv2NXBKi.js +0 -2
  101. package/dist/chunks/{grSelectStyles-C1zNEkV7.js → grSelectStyles-B7doeAQp.js} +0 -2
  102. package/dist/chunks/{grSelectStyles-C1zNEkV7.js.map → grSelectStyles-B7doeAQp.js.map} +1 -1
  103. package/dist/chunks/{granularityI18n-BEWP9aJs.js → granularityI18n-GCqUz_lo.js} +1 -3
  104. package/dist/chunks/{granularityI18n-BEWP9aJs.js.map → granularityI18n-GCqUz_lo.js.map} +1 -1
  105. package/dist/chunks/info-C0bHmdZq.js +0 -2
  106. package/dist/chunks/loader-circle-B2rWDk5u.js +0 -2
  107. package/dist/chunks/{ru-DKswMSdd.js → ru-Dqh-2C00.js} +0 -2
  108. package/dist/chunks/{ru-DKswMSdd.js.map → ru-Dqh-2C00.js.map} +1 -1
  109. package/dist/chunks/safelist-BF822K15.js +0 -2
  110. package/dist/chunks/safelist-BY7z8fOl.js +0 -2
  111. package/dist/chunks/{shared-Bvjkhhm2.js → shared-buYOkZSv.js} +33 -35
  112. package/dist/chunks/{shared-Bvjkhhm2.js.map → shared-buYOkZSv.js.map} +1 -1
  113. package/dist/chunks/transition-mJ3PZCHH.js +0 -2
  114. package/dist/chunks/x-Pa6C2hwi.js +0 -2
  115. package/dist/chunks/x-circle-DQSlBLmX.js +0 -2
  116. package/dist/components/GrAlert/chunks/GrAlert-BjerGcU8.js +0 -2
  117. package/dist/components/GrAvatar/chunks/GrAvatar-BjnPKNAL.js +0 -2
  118. package/dist/components/GrBadge/chunks/GrBadge-wuIb4_2K.js +0 -2
  119. package/dist/components/GrBadgeWrap/chunks/GrBadgeWrap-CxtamOZ-.js +0 -2
  120. package/dist/components/GrBottomNav/chunks/GrBottomNav-CsmQ7mTJ.js +0 -2
  121. package/dist/components/GrButton/chunks/GrButton-BmGdp8-4.js +0 -2
  122. package/dist/components/GrButtonGroup/chunks/GrButtonGroup-CBj4tpms.js +0 -2
  123. package/dist/components/GrCard/chunks/GrCard-xtDcXBr7.js +0 -2
  124. package/dist/components/GrCheckbox/chunks/GrCheckbox-Bt3d7ckE.js +0 -2
  125. package/dist/components/GrCollapse/chunks/GrCollapse-HU20VTVn.js +0 -2
  126. package/dist/components/GrConfirmDialog/chunks/GrConfirmDialog-DjGOX9Hd.js +0 -2
  127. package/dist/components/GrDataTable/chunks/GrDataTable-QDOJWmdY.js +0 -2
  128. package/dist/components/GrDialog/chunks/GrDialog-gObmaVEl.js +0 -2
  129. package/dist/components/GrDrawer/chunks/GrDrawer-BJL_gTxI.js +0 -2
  130. package/dist/components/GrDropdown/chunks/{GrDropdown-DVTU32T_.js → GrDropdown-BkACCXdp.js} +2 -4
  131. package/dist/components/GrDropdown/chunks/{GrDropdown-DVTU32T_.js.map → GrDropdown-BkACCXdp.js.map} +1 -1
  132. package/dist/components/GrDropdown/index.js +2 -2
  133. package/dist/components/GrDropdownMenu/chunks/{GrDropdownMenu-fePQRcgh.js → GrDropdownMenu-BEenXrJw.js} +1 -3
  134. package/dist/components/GrDropdownMenu/chunks/{GrDropdownMenu-fePQRcgh.js.map → GrDropdownMenu-BEenXrJw.js.map} +1 -1
  135. package/dist/components/GrDropdownMenu/index.js +2 -2
  136. package/dist/components/GrEmptyState/chunks/{GrEmptyState-Bs8d3tgb.js → GrEmptyState-BLbMJFW-.js} +0 -2
  137. package/dist/components/GrEmptyState/chunks/{GrEmptyState-Bs8d3tgb.js.map → GrEmptyState-BLbMJFW-.js.map} +1 -1
  138. package/dist/components/GrEmptyState/index.js +2 -2
  139. package/dist/components/GrFileUpload/chunks/{GrFileUpload-DVv8yXpl.js → GrFileUpload-u01j9S0t.js} +1 -3
  140. package/dist/components/GrFileUpload/chunks/{GrFileUpload-DVv8yXpl.js.map → GrFileUpload-u01j9S0t.js.map} +1 -1
  141. package/dist/components/GrFileUpload/index.js +3 -3
  142. package/dist/components/GrFormField/chunks/{GrFormField-BzezYcS8.js → GrFormField-C6PfAs4u.js} +0 -2
  143. package/dist/components/GrFormField/chunks/{GrFormField-BzezYcS8.js.map → GrFormField-C6PfAs4u.js.map} +1 -1
  144. package/dist/components/GrFormField/index.js +2 -2
  145. package/dist/components/GrFormFile/chunks/{GrFormFile-DtZOypJW.js → GrFormFile-DdM8Bc2B.js} +2 -4
  146. package/dist/components/GrFormFile/chunks/{GrFormFile-DtZOypJW.js.map → GrFormFile-DdM8Bc2B.js.map} +1 -1
  147. package/dist/components/GrFormFile/index.js +2 -2
  148. package/dist/components/GrFormSection/chunks/{GrFormSection-BIPB1RIk.js → GrFormSection-5djEaQZQ.js} +0 -2
  149. package/dist/components/GrFormSection/chunks/{GrFormSection-BIPB1RIk.js.map → GrFormSection-5djEaQZQ.js.map} +1 -1
  150. package/dist/components/GrFormSection/index.js +2 -2
  151. package/dist/components/GrIcon/chunks/GrIcon-BV7RBU_0.js +0 -2
  152. package/dist/components/GrImageViewer/chunks/{GrImageViewer-fn8ilJTA.js → GrImageViewer-CjSnohW7.js} +0 -2
  153. package/dist/components/GrImageViewer/chunks/{GrImageViewer-fn8ilJTA.js.map → GrImageViewer-CjSnohW7.js.map} +1 -1
  154. package/dist/components/GrImageViewer/index.js +2 -2
  155. package/dist/components/GrInput/chunks/{GrInput-DLLRrH1A.js → GrInput-ghxaTf6d.js} +0 -2
  156. package/dist/components/GrInput/chunks/{GrInput-DLLRrH1A.js.map → GrInput-ghxaTf6d.js.map} +1 -1
  157. package/dist/components/GrInput/index.js +2 -2
  158. package/dist/components/GrInputTag/chunks/{GrInputTag-CzrrBxgU.js → GrInputTag-B0x4U0Yk.js} +1 -3
  159. package/dist/components/GrInputTag/chunks/{GrInputTag-CzrrBxgU.js.map → GrInputTag-B0x4U0Yk.js.map} +1 -1
  160. package/dist/components/GrInputTag/index.js +2 -2
  161. package/dist/components/GrLink/chunks/{GrLink-Dhkid3Mp.js → GrLink-BbN7R3iP.js} +1 -3
  162. package/dist/components/GrLink/chunks/{GrLink-Dhkid3Mp.js.map → GrLink-BbN7R3iP.js.map} +1 -1
  163. package/dist/components/GrLink/index.js +2 -2
  164. package/dist/components/GrList/chunks/{GrList-CjgeVjhY.js → GrList--Ib4zLNw.js} +0 -2
  165. package/dist/components/GrList/chunks/{GrList-CjgeVjhY.js.map → GrList--Ib4zLNw.js.map} +1 -1
  166. package/dist/components/GrList/index.js +2 -2
  167. package/dist/components/GrLoading/chunks/{GrLoading-DihGX3ol.js → GrLoading-C3QZKwE-.js} +1 -3
  168. package/dist/components/GrLoading/chunks/{GrLoading-DihGX3ol.js.map → GrLoading-C3QZKwE-.js.map} +1 -1
  169. package/dist/components/GrLoading/index.js +2 -2
  170. package/dist/components/GrModal/chunks/GrModal-gvfvlp7k.js +0 -2
  171. package/dist/components/GrModal/index.js +1 -1
  172. package/dist/components/GrNavbar/chunks/{GrNavbar-CQOAfO6y.js → GrNavbar-nIyuiVj1.js} +1 -3
  173. package/dist/components/GrNavbar/chunks/{GrNavbar-CQOAfO6y.js.map → GrNavbar-nIyuiVj1.js.map} +1 -1
  174. package/dist/components/GrNavbar/index.js +2 -2
  175. package/dist/components/GrNumberInput/chunks/{GrNumberInput-CyHgUotG.js → GrNumberInput-B0mPLjdv.js} +1 -3
  176. package/dist/components/GrNumberInput/chunks/{GrNumberInput-CyHgUotG.js.map → GrNumberInput-B0mPLjdv.js.map} +1 -1
  177. package/dist/components/GrNumberInput/index.js +2 -2
  178. package/dist/components/GrPagination/chunks/{GrPagination-C5cxRJsF.js → GrPagination-BSTO6flk.js} +2 -4
  179. package/dist/components/GrPagination/chunks/{GrPagination-C5cxRJsF.js.map → GrPagination-BSTO6flk.js.map} +1 -1
  180. package/dist/components/GrPagination/index.js +2 -2
  181. package/dist/components/GrProgressBar/chunks/{GrProgressBar-C9wAAFxR.js → GrProgressBar-MvMnzsJl.js} +1 -3
  182. package/dist/components/GrProgressBar/chunks/{GrProgressBar-C9wAAFxR.js.map → GrProgressBar-MvMnzsJl.js.map} +1 -1
  183. package/dist/components/GrProgressBar/index.js +2 -2
  184. package/dist/components/GrPromptDialog/chunks/{GrPromptDialog-Cfq9bvL3.js → GrPromptDialog-DKhbN6ji.js} +2 -4
  185. package/dist/components/GrPromptDialog/chunks/{GrPromptDialog-Cfq9bvL3.js.map → GrPromptDialog-DKhbN6ji.js.map} +1 -1
  186. package/dist/components/GrPromptDialog/index.js +2 -2
  187. package/dist/components/GrRadio/chunks/{GrRadio-B_t_ZNVl.js → GrRadio-BxBs3WHq.js} +1 -3
  188. package/dist/components/GrRadio/chunks/{GrRadio-B_t_ZNVl.js.map → GrRadio-BxBs3WHq.js.map} +1 -1
  189. package/dist/components/GrRadio/index.js +2 -2
  190. package/dist/components/GrRadioGroup/chunks/{GrRadioGroup-CVlgpUBr.js → GrRadioGroup-CEAfJQ6A.js} +1 -3
  191. package/dist/components/GrRadioGroup/chunks/{GrRadioGroup-CVlgpUBr.js.map → GrRadioGroup-CEAfJQ6A.js.map} +1 -1
  192. package/dist/components/GrRadioGroup/index.js +2 -2
  193. package/dist/components/GrSegmented/chunks/{GrSegmented-BPl1koHc.js → GrSegmented-Bwn2qOY4.js} +1 -3
  194. package/dist/components/GrSegmented/chunks/{GrSegmented-BPl1koHc.js.map → GrSegmented-Bwn2qOY4.js.map} +1 -1
  195. package/dist/components/GrSegmented/index.js +2 -2
  196. package/dist/components/GrSelect/chunks/{GrSelect-aVqUL-1F.js → GrSelect-9wRWAu2R.js} +3 -5
  197. package/dist/components/GrSelect/chunks/{GrSelect-aVqUL-1F.js.map → GrSelect-9wRWAu2R.js.map} +1 -1
  198. package/dist/components/GrSelect/index.js +2 -2
  199. package/dist/components/GrSidebar/chunks/{GrSidebar-DVucgcfV.js → GrSidebar-CSZ3RpFB.js} +0 -2
  200. package/dist/components/GrSidebar/chunks/{GrSidebar-DVucgcfV.js.map → GrSidebar-CSZ3RpFB.js.map} +1 -1
  201. package/dist/components/GrSidebar/index.js +2 -2
  202. package/dist/components/GrSkeleton/chunks/{GrSkeleton-CDTvCSoH.js → GrSkeleton-DKXkqWDa.js} +0 -2
  203. package/dist/components/GrSkeleton/chunks/{GrSkeleton-CDTvCSoH.js.map → GrSkeleton-DKXkqWDa.js.map} +1 -1
  204. package/dist/components/GrSkeleton/index.js +2 -2
  205. package/dist/components/GrSwitch/chunks/{GrSwitch-Bnamgqb2.js → GrSwitch-CdBxwV3k.js} +1 -3
  206. package/dist/components/GrSwitch/chunks/{GrSwitch-Bnamgqb2.js.map → GrSwitch-CdBxwV3k.js.map} +1 -1
  207. package/dist/components/GrSwitch/index.js +2 -2
  208. package/dist/components/GrTable/chunks/GrTable-CyQ9uw8A.js +0 -2
  209. package/dist/components/GrTable/index.js +1 -1
  210. package/dist/components/GrTabs/chunks/{GrTabs-CiGmcmvm.js → GrTabs-BpF8AAUz.js} +0 -2
  211. package/dist/components/GrTabs/chunks/{GrTabs-CiGmcmvm.js.map → GrTabs-BpF8AAUz.js.map} +1 -1
  212. package/dist/components/GrTabs/index.js +2 -2
  213. package/dist/components/GrTextarea/chunks/{GrTextarea-VBSc6A7D.js → GrTextarea-DFS9ZkrA.js} +1 -3
  214. package/dist/components/GrTextarea/chunks/{GrTextarea-VBSc6A7D.js.map → GrTextarea-DFS9ZkrA.js.map} +1 -1
  215. package/dist/components/GrTextarea/index.js +2 -2
  216. package/dist/components/GrToaster/chunks/{GrToaster-I1e-zCpf.js → GrToaster-3Mf0Moxt.js} +1 -3
  217. package/dist/components/GrToaster/chunks/{GrToaster-I1e-zCpf.js.map → GrToaster-3Mf0Moxt.js.map} +1 -1
  218. package/dist/components/GrToaster/index.js +2 -2
  219. package/dist/components/GrTooltip/chunks/{GrTooltip-CrV1gI_c.js → GrTooltip-BvmsukLW.js} +0 -2
  220. package/dist/components/GrTooltip/chunks/{GrTooltip-CrV1gI_c.js.map → GrTooltip-BvmsukLW.js.map} +1 -1
  221. package/dist/components/GrTooltip/index.js +2 -2
  222. package/dist/components/GrTree/chunks/{GrTree-Dlev9oBd.js → GrTree-C2kN-O4Q.js} +0 -2
  223. package/dist/components/GrTree/chunks/{GrTree-Dlev9oBd.js.map → GrTree-C2kN-O4Q.js.map} +1 -1
  224. package/dist/components/GrTree/index.js +2 -2
  225. package/dist/components/GrTreeSelect/chunks/{GrTreeSelect-DN6XFjOD.js → GrTreeSelect-Da-CpRqm.js} +5 -7
  226. package/dist/components/GrTreeSelect/chunks/{GrTreeSelect-DN6XFjOD.js.map → GrTreeSelect-Da-CpRqm.js.map} +1 -1
  227. package/dist/components/GrTreeSelect/index.js +2 -2
  228. package/dist/composables/useTheme.js +0 -2
  229. package/dist/composables/useToast.js +0 -2
  230. package/dist/directives/autofocus.js +55 -0
  231. package/dist/directives/autofocus.js.map +1 -0
  232. package/dist/directives/autosize.js +117 -0
  233. package/dist/directives/autosize.js.map +1 -0
  234. package/dist/directives/clickOutside.js +96 -0
  235. package/dist/directives/clickOutside.js.map +1 -0
  236. package/dist/directives/dropzone.js +164 -0
  237. package/dist/directives/dropzone.js.map +1 -0
  238. package/dist/directives/hotkey.js +138 -0
  239. package/dist/directives/hotkey.js.map +1 -0
  240. package/dist/directives/index.js +6 -1
  241. package/dist/directives/loading.js +163 -0
  242. package/dist/directives/loading.js.map +1 -0
  243. package/dist/fileValidation/index.js +1 -1
  244. package/dist/granular-provider-node.js +2 -4
  245. package/dist/granular-provider.js +1 -3
  246. package/dist/i18n/all.js +1 -3
  247. package/dist/i18n/index.js +2 -2
  248. package/dist/index.js +71 -66
  249. package/dist/types/src/components/GrLink/grLinkStyles.d.ts +1 -1
  250. package/dist/vue/index.js +0 -2
  251. package/package.json +25 -1
  252. package/dist/chunks/config-BbtK511H.js.map +0 -1
  253. package/dist/chunks/config-BcFOkUhh.js.map +0 -1
  254. package/dist/chunks/config-BzQ4S4Hb.js.map +0 -1
  255. package/dist/chunks/config-C2JKq8-2.js.map +0 -1
  256. package/dist/chunks/config-CdAx6ify2.js.map +0 -1
  257. package/dist/chunks/config-KGTIAFD92.js.map +0 -1
  258. package/dist/chunks/directives-Cuib0yOO.js +0 -728
  259. package/dist/chunks/directives-Cuib0yOO.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"GrTree-Dlev9oBd.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-C2kN-O4Q.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-Dlev9oBd.js";
2
- import { n as grTreeSafelist, t as grTreeConfig } from "../../chunks/config-ug8O8epd.js";
1
+ import { t as GrTree_default } from "./chunks/GrTree-C2kN-O4Q.js";
2
+ import { n as grTreeSafelist, t as grTreeConfig } from "../../chunks/config-DCQO6H6h.js";
3
3
  export { GrTree_default as GrTree, GrTree_default as default, grTreeConfig, grTreeSafelist };
@@ -1,8 +1,8 @@
1
- import { a as vClickOutside } from "../../../chunks/directives-Cuib0yOO.js";
2
- import { t as GrInput_default } from "../../GrInput/chunks/GrInput-DLLRrH1A.js";
3
- import { t as useGranularityTranslations } from "../../../chunks/granularityI18n-BEWP9aJs.js";
4
- import { t as GrTree_default } from "../../GrTree/chunks/GrTree-Dlev9oBd.js";
5
- import { i as grTreeSelectPanelClass, r as grTreeSelectClass } from "../../../chunks/config-C0b_3LJV.js";
1
+ import { vClickOutside } from "../../../directives/clickOutside.js";
2
+ import { t as GrInput_default } from "../../GrInput/chunks/GrInput-ghxaTf6d.js";
3
+ import { t as useGranularityTranslations } from "../../../chunks/granularityI18n-GCqUz_lo.js";
4
+ import { t as GrTree_default } from "../../GrTree/chunks/GrTree-C2kN-O4Q.js";
5
+ import { i as grTreeSelectPanelClass, r as grTreeSelectClass } from "../../../chunks/config-BNOf_qjD.js";
6
6
  import { Teleport, Transition, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, nextTick, normalizeClass, normalizeStyle, onUnmounted, openBlock, ref, renderSlot, toDisplayString, unref, vShow, watch, withCtx, withDirectives, withModifiers } from "vue";
7
7
  //#region src/components/GrTreeSelect/GrTreeSelect.vue?vue&type=script&setup=true&lang.ts
8
8
  var _hoisted_1 = { class: "relative" };
@@ -452,5 +452,3 @@ var GrTreeSelect_default = /* @__PURE__ */ defineComponent({
452
452
  });
453
453
  //#endregion
454
454
  export { GrTreeSelect_default as t };
455
-
456
- //# sourceMappingURL=GrTreeSelect-DN6XFjOD.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"GrTreeSelect-DN6XFjOD.js","names":["$slots"],"sources":["../../../../src/components/GrTreeSelect/GrTreeSelect.vue","../../../../src/components/GrTreeSelect/GrTreeSelect.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"T extends Record<string, any> = any\">\nimport { computed, nextTick, onUnmounted, ref, watch } from 'vue'\n\nimport { vClickOutside } from '../../directives'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport GrInput from '../GrInput/GrInput.vue'\nimport GrTree, {\n type GrTreeInstance,\n type GrTreeKey,\n type GrTreeNode,\n} from '../GrTree'\nimport type { GrTreeSelectModelValue, GrTreeSelectProps } from './grTreeSelectTypes'\nimport { grTreeSelectClass, grTreeSelectPanelClass } from './grTreeSelectStyles'\n\nconst props = withDefaults(\n defineProps<GrTreeSelectProps<T>>(),\n {\n props: () => ({\n children: 'children',\n label: 'label',\n }),\n nodeKey: 'id' as any,\n defaultExpandedKeys: () => [],\n disabled: false,\n placeholder: undefined,\n size: 'md',\n invalid: false,\n state: 'default',\n multiple: false,\n clearable: false,\n valueDisplay: 'label',\n filterable: false,\n filterPlaceholder: undefined,\n filterInputmode: undefined,\n filterNodeMethod: undefined,\n closeOnSelect: undefined,\n dropdownMaxHeight: 320,\n },\n)\n\nconst { t } = useGranularityTranslations()\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: GrTreeSelectModelValue): void\n (e: 'change', value: GrTreeSelectModelValue): void\n (e: 'visibleChange', visible: boolean): void\n (e: 'clear'): void\n (e: 'nodeClick', data: T, node: GrTreeNode<T>): void\n}>()\n\ndefineSlots<{\n /** Рендер значения внутри триггера (вместо дефолтного текста). */\n value?: (props: { value: GrTreeSelectModelValue; labels: string[]; displayValue: string; pathLabels?: string[] }) => any\n /** Рендер строки дерева. */\n node?: (props: { node: GrTreeNode<T>; data: T; selected: boolean }) => any\n /** Содержимое пустого состояния (когда нет данных). */\n empty?: () => any\n}>()\n\nconst rootEl = ref<HTMLElement | null>(null)\nconst triggerEl = ref<HTMLInputElement | null>(null)\nconst filterInputRef = ref<InstanceType<typeof GrInput> | null>(null)\nconst treeRef = ref<GrTreeInstance | null>(null)\nconst panelEl = ref<HTMLElement | null>(null)\n\nconst clickOutsideExclude = [() => panelEl.value]\n\nlet hadPointerDownOnTrigger = false\n\nconst open = ref(false)\nconst filterValue = ref('')\n\nconst panelStyle = ref<Record<string, string>>({\n left: '0px',\n top: '0px',\n width: '0px',\n zIndex: '2147483647',\n})\n\nfunction syncPanelPosition(): void {\n if (typeof window === 'undefined')\n return\n\n const root = rootEl.value\n if (!root)\n return\n\n const rect = root.getBoundingClientRect()\n\n panelStyle.value = {\n left: `${rect.left}px`,\n top: `${rect.bottom + 8}px`,\n width: `${rect.width}px`,\n zIndex: '2147483647',\n }\n}\n\nfunction bindPanelPositionListeners(): void {\n if (typeof window === 'undefined')\n return\n window.addEventListener('resize', syncPanelPosition)\n window.addEventListener('scroll', syncPanelPosition, true)\n}\n\nfunction unbindPanelPositionListeners(): void {\n if (typeof window === 'undefined')\n return\n window.removeEventListener('resize', syncPanelPosition)\n window.removeEventListener('scroll', syncPanelPosition, true)\n}\n\nconst closeOnSelectResolved = computed(() => {\n return props.closeOnSelect ?? !props.multiple\n})\n\nfunction getChildrenKey() {\n return props.props.children ?? 'children'\n}\n\nfunction getLabelKey() {\n return props.props.label ?? 'label'\n}\n\nfunction nodeLabel(data: T): string {\n const key = getLabelKey() as keyof T\n const v = data[key]\n return v == null ? '' : String(v)\n}\n\nfunction nodeChildren(data: T): T[] {\n const key = getChildrenKey() as keyof T\n const v = data[key]\n return Array.isArray(v) ? (v as any) : []\n}\n\nfunction nodeKeyOf(data: T, index: number, parentKey: GrTreeKey | undefined): GrTreeKey {\n const keyName = props.nodeKey as keyof T\n const v = data[keyName]\n if (v != null)\n return v as GrTreeKey\n\n return parentKey == null ? index : `${String(parentKey)}:${index}`\n}\n\nconst labelByKey = computed(() => {\n const map = new Map<GrTreeKey, string>()\n\n const walk = (items: T[], parentKey: GrTreeKey | undefined) => {\n for (let i = 0; i < items.length; i++) {\n const item = items[i]\n const key = nodeKeyOf(item, i, parentKey)\n map.set(key, nodeLabel(item))\n walk(nodeChildren(item), key)\n }\n }\n\n walk(props.data ?? [], undefined)\n return map\n})\n\nconst pathLabelsByKey = computed(() => {\n const map = new Map<GrTreeKey, string[]>()\n\n const walk = (items: T[], parentKey: GrTreeKey | undefined, parentPath: string[]) => {\n for (let i = 0; i < items.length; i++) {\n const item = items[i]\n const key = nodeKeyOf(item, i, parentKey)\n const label = nodeLabel(item)\n const path = [...parentPath, label]\n map.set(key, path)\n walk(nodeChildren(item), key, path)\n }\n }\n\n walk(props.data ?? [], undefined, [])\n return map\n})\n\nconst selectedKeys = computed<GrTreeKey[]>(() => {\n if (props.multiple) {\n return Array.isArray(props.modelValue) ? props.modelValue : []\n }\n\n const v = props.modelValue\n if (v == null || Array.isArray(v))\n return []\n return [v]\n})\n\nconst selectedKeySet = computed(() => new Set(selectedKeys.value))\n\nconst selectedLabels = computed(() => {\n const map = labelByKey.value\n return selectedKeys.value.map((k) => map.get(k) ?? String(k))\n})\n\nconst selectedPathLabels = computed<string[] | undefined>(() => {\n if (props.multiple)\n return undefined\n\n const key = selectedKeys.value[0]\n if (key == null)\n return undefined\n\n const path = pathLabelsByKey.value.get(key)\n if (path?.length)\n return path\n\n const labels = selectedLabels.value\n return labels.length ? [labels[0]] : undefined\n})\n\nconst displayValue = computed(() => {\n const labels = selectedLabels.value\n if (labels.length === 0)\n return ''\n\n if (!props.multiple) {\n if (props.valueDisplay === 'path') {\n const path = selectedPathLabels.value\n if (path?.length)\n return path.join(' / ')\n }\n return labels[0]\n }\n\n if (labels.length === 1)\n return labels[0]\n return `${labels[0]} +${labels.length - 1}`\n})\n\nconst hasSelection = computed(() => selectedKeys.value.length > 0)\n\nconst resolvedFilterPlaceholder = computed(() => {\n return props.filterPlaceholder ?? t('gr.treeSelect.filterPlaceholder', 'Search…')\n})\n\nconst className = computed(() => {\n return grTreeSelectClass({\n size: props.size,\n state: props.state,\n invalid: props.invalid,\n })\n})\n\nconst panelClasses = computed(() => {\n return grTreeSelectPanelClass\n})\n\nfunction setOpen(next: boolean) {\n if (props.disabled)\n return\n\n if (open.value === next)\n return\n\n open.value = next\n emit('visibleChange', next)\n}\n\nfunction onClickOutside(): void {\n setOpen(false)\n}\n\nfunction openDropdown(): void {\n setOpen(true)\n}\n\nfunction closeDropdown(): void {\n setOpen(false)\n}\n\nfunction toggleDropdown(): void {\n setOpen(!open.value)\n}\n\nfunction onTriggerPointerDown(): void {\n hadPointerDownOnTrigger = true\n if (typeof window !== 'undefined') {\n window.setTimeout(() => {\n hadPointerDownOnTrigger = false\n }, 0)\n }\n else {\n // SSR / no window: reset sync\n hadPointerDownOnTrigger = false\n }\n}\n\nfunction onTriggerFocus(): void {\n if (hadPointerDownOnTrigger)\n return\n openDropdown()\n}\n\nfunction closeOnEscape(e: KeyboardEvent): void {\n if (e.key === 'Escape') {\n closeDropdown()\n nextTick(() => triggerEl.value?.focus())\n }\n}\n\nwatch(\n open,\n async (isOpen) => {\n if (typeof document === 'undefined')\n return\n\n document.removeEventListener('keydown', closeOnEscape)\n unbindPanelPositionListeners()\n\n if (isOpen)\n document.addEventListener('keydown', closeOnEscape)\n\n if (!isOpen)\n return\n\n bindPanelPositionListeners()\n await nextTick()\n syncPanelPosition()\n\n // sync tree highlight\n if (!props.multiple) {\n const v = props.modelValue\n if (v != null && !Array.isArray(v))\n treeRef.value?.setCurrentKey(v)\n }\n\n // focus filter input\n if (props.filterable) {\n await nextTick()\n filterInputRef.value?.focus()\n }\n },\n { immediate: true },\n)\n\nonUnmounted(() => {\n if (typeof document === 'undefined')\n return\n document.removeEventListener('keydown', closeOnEscape)\n unbindPanelPositionListeners()\n})\n\nwatch(\n () => props.modelValue,\n (v) => {\n if (props.multiple)\n return\n if (v == null || Array.isArray(v)) {\n treeRef.value?.setCurrentKey(undefined)\n return\n }\n treeRef.value?.setCurrentKey(v)\n },\n)\n\nwatch(\n filterValue,\n (v) => {\n treeRef.value?.filter(v)\n },\n)\n\nwatch(\n open,\n (isOpen) => {\n if (isOpen)\n return\n if (filterValue.value.trim().length > 0)\n filterValue.value = ''\n },\n)\n\nfunction emitModel(next: GrTreeSelectModelValue) {\n emit('update:modelValue', next)\n emit('change', next)\n}\n\nfunction clear(): void {\n if (props.disabled)\n return\n\n const next: GrTreeSelectModelValue = props.multiple ? [] : null\n emitModel(next)\n emit('clear')\n if (!props.multiple)\n treeRef.value?.setCurrentKey(undefined)\n}\n\nfunction onTriggerKeydown(e: KeyboardEvent): void {\n if (props.disabled)\n return\n\n if (e.key === 'ArrowDown' || e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n openDropdown()\n }\n if (e.key === 'Escape') {\n e.preventDefault()\n closeDropdown()\n }\n}\n\nfunction onNodeClick(data: T, node: GrTreeNode<T>): void {\n emit('nodeClick', data, node)\n\n if (props.disabled)\n return\n\n if (props.multiple) {\n const next = new Set(selectedKeySet.value)\n if (next.has(node.key))\n next.delete(node.key)\n else\n next.add(node.key)\n emitModel([...next])\n\n if (closeOnSelectResolved.value) {\n closeDropdown()\n }\n return\n }\n\n emitModel(node.key)\n if (closeOnSelectResolved.value) {\n closeDropdown()\n }\n}\n</script>\n\n<template>\n <div\n ref=\"rootEl\"\n v-click-outside=\"{ handler: onClickOutside, enabled: open, exclude: clickOutsideExclude }\"\n data-ds-tree-select\n class=\"relative\"\n >\n <div class=\"relative\">\n <input\n ref=\"triggerEl\"\n data-testid=\"ds-tree-select-trigger\"\n data-ds-tree-select-trigger\n type=\"text\"\n :value=\"displayValue\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n readonly\n role=\"combobox\"\n aria-readonly=\"true\"\n :aria-expanded=\"open ? 'true' : 'false'\"\n :aria-invalid=\"invalid ? 'true' : undefined\"\n class=\"w-full rounded-md border bg-[var(--bg)] text-[var(--fg)] placeholder:text-[var(--muted-fg)] transition-colors duration-150 focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)] disabled:opacity-50 disabled:cursor-not-allowed\"\n :class=\"[className, $slots.value ? 'text-transparent placeholder:text-transparent' : '']\"\n @pointerdown=\"onTriggerPointerDown\"\n @click=\"toggleDropdown\"\n @focus=\"onTriggerFocus\"\n @keydown=\"onTriggerKeydown\"\n >\n\n <button\n v-if=\"clearable && hasSelection\"\n data-testid=\"ds-tree-select-clear\"\n data-ds-tree-select-clear\n type=\"button\"\n class=\"absolute top-1/2 -translate-y-1/2 right-3 h-6 w-6 inline-flex items-center justify-center rounded-md text-[var(--muted-fg)] hover:text-[var(--fg)] hover:bg-[color-mix(in_srgb,var(--muted)_25%,transparent)] disabled:opacity-50\"\n :disabled=\"disabled\"\n :aria-label=\"t('gr.common.clear', 'Clear')\"\n @click.stop=\"clear\"\n >\n <span class=\"i-lucide-x h-4 w-4\" />\n </button>\n\n <span\n v-else\n data-testid=\"ds-tree-select-chevron\"\n data-ds-tree-select-chevron\n class=\"absolute top-1/2 -translate-y-1/2 right-3 text-[var(--muted-fg)] pointer-events-none\"\n >\n <span\n class=\"i-lucide-chevron-down h-4 w-4 transition-transform duration-150\"\n :class=\"open ? 'rotate-180' : ''\"\n />\n </span>\n\n <div\n v-if=\"$slots.value\"\n class=\"absolute inset-y-0 left-3 right-9 flex items-center pointer-events-none\"\n >\n <slot\n name=\"value\"\n :value=\"modelValue\"\n :labels=\"selectedLabels\"\n :display-value=\"displayValue\"\n :path-labels=\"selectedPathLabels\"\n />\n </div>\n </div>\n\n <teleport to=\"body\">\n <transition\n enter-active-class=\"transition ease-out duration-150\"\n enter-from-class=\"transform opacity-0 scale-95\"\n enter-to-class=\"transform opacity-100 scale-100\"\n leave-active-class=\"transition ease-in duration-100\"\n leave-from-class=\"transform opacity-100 scale-100\"\n leave-to-class=\"transform opacity-0 scale-95\"\n >\n <div\n v-show=\"open\"\n ref=\"panelEl\"\n data-testid=\"ds-tree-select-panel\"\n data-ds-tree-select-panel\n class=\"fixed w-full\"\n :style=\"panelStyle\"\n >\n <div :class=\"panelClasses\">\n <div v-if=\"filterable\" class=\"p-2 border-b border-[var(--brd)]\">\n <GrInput\n ref=\"filterInputRef\"\n v-model=\"filterValue\"\n data-testid=\"ds-tree-select-filter\"\n data-ds-tree-select-filter\n type=\"search\"\n :inputmode=\"filterInputmode\"\n :placeholder=\"resolvedFilterPlaceholder\"\n size=\"sm\"\n />\n </div>\n\n <div\n class=\"p-1 overflow-auto\"\n :style=\"{ maxHeight: `${dropdownMaxHeight}px` }\"\n >\n <div v-if=\"(data?.length ?? 0) === 0\" class=\"px-3 py-2 text-[13px] text-[var(--muted-fg)]\">\n <slot name=\"empty\">\n {{ t('gr.treeSelect.empty', 'No data') }}\n </slot>\n </div>\n\n <GrTree\n v-else\n ref=\"treeRef\"\n :data=\"data\"\n :props=\"props.props\"\n :node-key=\"nodeKey as any\"\n :default-expanded-keys=\"defaultExpandedKeys\"\n :filter-node-method=\"filterNodeMethod\"\n :highlight-current=\"!multiple\"\n @node-click=\"onNodeClick\"\n >\n <template #default=\"{ node, data }\">\n <slot\n name=\"node\"\n :node=\"node\"\n :data=\"data\"\n :selected=\"selectedKeySet.has(node.key)\"\n >\n <div class=\"flex items-center gap-2 min-w-0\">\n <span\n class=\"h-4 w-4 shrink-0\"\n :class=\"selectedKeySet.has(node.key) ? 'i-lucide-check text-[var(--primary)]' : ''\"\n aria-hidden=\"true\"\n />\n <span class=\"truncate\">{{ node.label }}</span>\n </div>\n </slot>\n </template>\n </GrTree>\n </div>\n </div>\n </div>\n </transition>\n </teleport>\n </div>\n</template>\n","<script setup lang=\"ts\" generic=\"T extends Record<string, any> = any\">\nimport { computed, nextTick, onUnmounted, ref, watch } from 'vue'\n\nimport { vClickOutside } from '../../directives'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport GrInput from '../GrInput/GrInput.vue'\nimport GrTree, {\n type GrTreeInstance,\n type GrTreeKey,\n type GrTreeNode,\n} from '../GrTree'\nimport type { GrTreeSelectModelValue, GrTreeSelectProps } from './grTreeSelectTypes'\nimport { grTreeSelectClass, grTreeSelectPanelClass } from './grTreeSelectStyles'\n\nconst props = withDefaults(\n defineProps<GrTreeSelectProps<T>>(),\n {\n props: () => ({\n children: 'children',\n label: 'label',\n }),\n nodeKey: 'id' as any,\n defaultExpandedKeys: () => [],\n disabled: false,\n placeholder: undefined,\n size: 'md',\n invalid: false,\n state: 'default',\n multiple: false,\n clearable: false,\n valueDisplay: 'label',\n filterable: false,\n filterPlaceholder: undefined,\n filterInputmode: undefined,\n filterNodeMethod: undefined,\n closeOnSelect: undefined,\n dropdownMaxHeight: 320,\n },\n)\n\nconst { t } = useGranularityTranslations()\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: GrTreeSelectModelValue): void\n (e: 'change', value: GrTreeSelectModelValue): void\n (e: 'visibleChange', visible: boolean): void\n (e: 'clear'): void\n (e: 'nodeClick', data: T, node: GrTreeNode<T>): void\n}>()\n\ndefineSlots<{\n /** Рендер значения внутри триггера (вместо дефолтного текста). */\n value?: (props: { value: GrTreeSelectModelValue; labels: string[]; displayValue: string; pathLabels?: string[] }) => any\n /** Рендер строки дерева. */\n node?: (props: { node: GrTreeNode<T>; data: T; selected: boolean }) => any\n /** Содержимое пустого состояния (когда нет данных). */\n empty?: () => any\n}>()\n\nconst rootEl = ref<HTMLElement | null>(null)\nconst triggerEl = ref<HTMLInputElement | null>(null)\nconst filterInputRef = ref<InstanceType<typeof GrInput> | null>(null)\nconst treeRef = ref<GrTreeInstance | null>(null)\nconst panelEl = ref<HTMLElement | null>(null)\n\nconst clickOutsideExclude = [() => panelEl.value]\n\nlet hadPointerDownOnTrigger = false\n\nconst open = ref(false)\nconst filterValue = ref('')\n\nconst panelStyle = ref<Record<string, string>>({\n left: '0px',\n top: '0px',\n width: '0px',\n zIndex: '2147483647',\n})\n\nfunction syncPanelPosition(): void {\n if (typeof window === 'undefined')\n return\n\n const root = rootEl.value\n if (!root)\n return\n\n const rect = root.getBoundingClientRect()\n\n panelStyle.value = {\n left: `${rect.left}px`,\n top: `${rect.bottom + 8}px`,\n width: `${rect.width}px`,\n zIndex: '2147483647',\n }\n}\n\nfunction bindPanelPositionListeners(): void {\n if (typeof window === 'undefined')\n return\n window.addEventListener('resize', syncPanelPosition)\n window.addEventListener('scroll', syncPanelPosition, true)\n}\n\nfunction unbindPanelPositionListeners(): void {\n if (typeof window === 'undefined')\n return\n window.removeEventListener('resize', syncPanelPosition)\n window.removeEventListener('scroll', syncPanelPosition, true)\n}\n\nconst closeOnSelectResolved = computed(() => {\n return props.closeOnSelect ?? !props.multiple\n})\n\nfunction getChildrenKey() {\n return props.props.children ?? 'children'\n}\n\nfunction getLabelKey() {\n return props.props.label ?? 'label'\n}\n\nfunction nodeLabel(data: T): string {\n const key = getLabelKey() as keyof T\n const v = data[key]\n return v == null ? '' : String(v)\n}\n\nfunction nodeChildren(data: T): T[] {\n const key = getChildrenKey() as keyof T\n const v = data[key]\n return Array.isArray(v) ? (v as any) : []\n}\n\nfunction nodeKeyOf(data: T, index: number, parentKey: GrTreeKey | undefined): GrTreeKey {\n const keyName = props.nodeKey as keyof T\n const v = data[keyName]\n if (v != null)\n return v as GrTreeKey\n\n return parentKey == null ? index : `${String(parentKey)}:${index}`\n}\n\nconst labelByKey = computed(() => {\n const map = new Map<GrTreeKey, string>()\n\n const walk = (items: T[], parentKey: GrTreeKey | undefined) => {\n for (let i = 0; i < items.length; i++) {\n const item = items[i]\n const key = nodeKeyOf(item, i, parentKey)\n map.set(key, nodeLabel(item))\n walk(nodeChildren(item), key)\n }\n }\n\n walk(props.data ?? [], undefined)\n return map\n})\n\nconst pathLabelsByKey = computed(() => {\n const map = new Map<GrTreeKey, string[]>()\n\n const walk = (items: T[], parentKey: GrTreeKey | undefined, parentPath: string[]) => {\n for (let i = 0; i < items.length; i++) {\n const item = items[i]\n const key = nodeKeyOf(item, i, parentKey)\n const label = nodeLabel(item)\n const path = [...parentPath, label]\n map.set(key, path)\n walk(nodeChildren(item), key, path)\n }\n }\n\n walk(props.data ?? [], undefined, [])\n return map\n})\n\nconst selectedKeys = computed<GrTreeKey[]>(() => {\n if (props.multiple) {\n return Array.isArray(props.modelValue) ? props.modelValue : []\n }\n\n const v = props.modelValue\n if (v == null || Array.isArray(v))\n return []\n return [v]\n})\n\nconst selectedKeySet = computed(() => new Set(selectedKeys.value))\n\nconst selectedLabels = computed(() => {\n const map = labelByKey.value\n return selectedKeys.value.map((k) => map.get(k) ?? String(k))\n})\n\nconst selectedPathLabels = computed<string[] | undefined>(() => {\n if (props.multiple)\n return undefined\n\n const key = selectedKeys.value[0]\n if (key == null)\n return undefined\n\n const path = pathLabelsByKey.value.get(key)\n if (path?.length)\n return path\n\n const labels = selectedLabels.value\n return labels.length ? [labels[0]] : undefined\n})\n\nconst displayValue = computed(() => {\n const labels = selectedLabels.value\n if (labels.length === 0)\n return ''\n\n if (!props.multiple) {\n if (props.valueDisplay === 'path') {\n const path = selectedPathLabels.value\n if (path?.length)\n return path.join(' / ')\n }\n return labels[0]\n }\n\n if (labels.length === 1)\n return labels[0]\n return `${labels[0]} +${labels.length - 1}`\n})\n\nconst hasSelection = computed(() => selectedKeys.value.length > 0)\n\nconst resolvedFilterPlaceholder = computed(() => {\n return props.filterPlaceholder ?? t('gr.treeSelect.filterPlaceholder', 'Search…')\n})\n\nconst className = computed(() => {\n return grTreeSelectClass({\n size: props.size,\n state: props.state,\n invalid: props.invalid,\n })\n})\n\nconst panelClasses = computed(() => {\n return grTreeSelectPanelClass\n})\n\nfunction setOpen(next: boolean) {\n if (props.disabled)\n return\n\n if (open.value === next)\n return\n\n open.value = next\n emit('visibleChange', next)\n}\n\nfunction onClickOutside(): void {\n setOpen(false)\n}\n\nfunction openDropdown(): void {\n setOpen(true)\n}\n\nfunction closeDropdown(): void {\n setOpen(false)\n}\n\nfunction toggleDropdown(): void {\n setOpen(!open.value)\n}\n\nfunction onTriggerPointerDown(): void {\n hadPointerDownOnTrigger = true\n if (typeof window !== 'undefined') {\n window.setTimeout(() => {\n hadPointerDownOnTrigger = false\n }, 0)\n }\n else {\n // SSR / no window: reset sync\n hadPointerDownOnTrigger = false\n }\n}\n\nfunction onTriggerFocus(): void {\n if (hadPointerDownOnTrigger)\n return\n openDropdown()\n}\n\nfunction closeOnEscape(e: KeyboardEvent): void {\n if (e.key === 'Escape') {\n closeDropdown()\n nextTick(() => triggerEl.value?.focus())\n }\n}\n\nwatch(\n open,\n async (isOpen) => {\n if (typeof document === 'undefined')\n return\n\n document.removeEventListener('keydown', closeOnEscape)\n unbindPanelPositionListeners()\n\n if (isOpen)\n document.addEventListener('keydown', closeOnEscape)\n\n if (!isOpen)\n return\n\n bindPanelPositionListeners()\n await nextTick()\n syncPanelPosition()\n\n // sync tree highlight\n if (!props.multiple) {\n const v = props.modelValue\n if (v != null && !Array.isArray(v))\n treeRef.value?.setCurrentKey(v)\n }\n\n // focus filter input\n if (props.filterable) {\n await nextTick()\n filterInputRef.value?.focus()\n }\n },\n { immediate: true },\n)\n\nonUnmounted(() => {\n if (typeof document === 'undefined')\n return\n document.removeEventListener('keydown', closeOnEscape)\n unbindPanelPositionListeners()\n})\n\nwatch(\n () => props.modelValue,\n (v) => {\n if (props.multiple)\n return\n if (v == null || Array.isArray(v)) {\n treeRef.value?.setCurrentKey(undefined)\n return\n }\n treeRef.value?.setCurrentKey(v)\n },\n)\n\nwatch(\n filterValue,\n (v) => {\n treeRef.value?.filter(v)\n },\n)\n\nwatch(\n open,\n (isOpen) => {\n if (isOpen)\n return\n if (filterValue.value.trim().length > 0)\n filterValue.value = ''\n },\n)\n\nfunction emitModel(next: GrTreeSelectModelValue) {\n emit('update:modelValue', next)\n emit('change', next)\n}\n\nfunction clear(): void {\n if (props.disabled)\n return\n\n const next: GrTreeSelectModelValue = props.multiple ? [] : null\n emitModel(next)\n emit('clear')\n if (!props.multiple)\n treeRef.value?.setCurrentKey(undefined)\n}\n\nfunction onTriggerKeydown(e: KeyboardEvent): void {\n if (props.disabled)\n return\n\n if (e.key === 'ArrowDown' || e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n openDropdown()\n }\n if (e.key === 'Escape') {\n e.preventDefault()\n closeDropdown()\n }\n}\n\nfunction onNodeClick(data: T, node: GrTreeNode<T>): void {\n emit('nodeClick', data, node)\n\n if (props.disabled)\n return\n\n if (props.multiple) {\n const next = new Set(selectedKeySet.value)\n if (next.has(node.key))\n next.delete(node.key)\n else\n next.add(node.key)\n emitModel([...next])\n\n if (closeOnSelectResolved.value) {\n closeDropdown()\n }\n return\n }\n\n emitModel(node.key)\n if (closeOnSelectResolved.value) {\n closeDropdown()\n }\n}\n</script>\n\n<template>\n <div\n ref=\"rootEl\"\n v-click-outside=\"{ handler: onClickOutside, enabled: open, exclude: clickOutsideExclude }\"\n data-ds-tree-select\n class=\"relative\"\n >\n <div class=\"relative\">\n <input\n ref=\"triggerEl\"\n data-testid=\"ds-tree-select-trigger\"\n data-ds-tree-select-trigger\n type=\"text\"\n :value=\"displayValue\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n readonly\n role=\"combobox\"\n aria-readonly=\"true\"\n :aria-expanded=\"open ? 'true' : 'false'\"\n :aria-invalid=\"invalid ? 'true' : undefined\"\n class=\"w-full rounded-md border bg-[var(--bg)] text-[var(--fg)] placeholder:text-[var(--muted-fg)] transition-colors duration-150 focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)] disabled:opacity-50 disabled:cursor-not-allowed\"\n :class=\"[className, $slots.value ? 'text-transparent placeholder:text-transparent' : '']\"\n @pointerdown=\"onTriggerPointerDown\"\n @click=\"toggleDropdown\"\n @focus=\"onTriggerFocus\"\n @keydown=\"onTriggerKeydown\"\n >\n\n <button\n v-if=\"clearable && hasSelection\"\n data-testid=\"ds-tree-select-clear\"\n data-ds-tree-select-clear\n type=\"button\"\n class=\"absolute top-1/2 -translate-y-1/2 right-3 h-6 w-6 inline-flex items-center justify-center rounded-md text-[var(--muted-fg)] hover:text-[var(--fg)] hover:bg-[color-mix(in_srgb,var(--muted)_25%,transparent)] disabled:opacity-50\"\n :disabled=\"disabled\"\n :aria-label=\"t('gr.common.clear', 'Clear')\"\n @click.stop=\"clear\"\n >\n <span class=\"i-lucide-x h-4 w-4\" />\n </button>\n\n <span\n v-else\n data-testid=\"ds-tree-select-chevron\"\n data-ds-tree-select-chevron\n class=\"absolute top-1/2 -translate-y-1/2 right-3 text-[var(--muted-fg)] pointer-events-none\"\n >\n <span\n class=\"i-lucide-chevron-down h-4 w-4 transition-transform duration-150\"\n :class=\"open ? 'rotate-180' : ''\"\n />\n </span>\n\n <div\n v-if=\"$slots.value\"\n class=\"absolute inset-y-0 left-3 right-9 flex items-center pointer-events-none\"\n >\n <slot\n name=\"value\"\n :value=\"modelValue\"\n :labels=\"selectedLabels\"\n :display-value=\"displayValue\"\n :path-labels=\"selectedPathLabels\"\n />\n </div>\n </div>\n\n <teleport to=\"body\">\n <transition\n enter-active-class=\"transition ease-out duration-150\"\n enter-from-class=\"transform opacity-0 scale-95\"\n enter-to-class=\"transform opacity-100 scale-100\"\n leave-active-class=\"transition ease-in duration-100\"\n leave-from-class=\"transform opacity-100 scale-100\"\n leave-to-class=\"transform opacity-0 scale-95\"\n >\n <div\n v-show=\"open\"\n ref=\"panelEl\"\n data-testid=\"ds-tree-select-panel\"\n data-ds-tree-select-panel\n class=\"fixed w-full\"\n :style=\"panelStyle\"\n >\n <div :class=\"panelClasses\">\n <div v-if=\"filterable\" class=\"p-2 border-b border-[var(--brd)]\">\n <GrInput\n ref=\"filterInputRef\"\n v-model=\"filterValue\"\n data-testid=\"ds-tree-select-filter\"\n data-ds-tree-select-filter\n type=\"search\"\n :inputmode=\"filterInputmode\"\n :placeholder=\"resolvedFilterPlaceholder\"\n size=\"sm\"\n />\n </div>\n\n <div\n class=\"p-1 overflow-auto\"\n :style=\"{ maxHeight: `${dropdownMaxHeight}px` }\"\n >\n <div v-if=\"(data?.length ?? 0) === 0\" class=\"px-3 py-2 text-[13px] text-[var(--muted-fg)]\">\n <slot name=\"empty\">\n {{ t('gr.treeSelect.empty', 'No data') }}\n </slot>\n </div>\n\n <GrTree\n v-else\n ref=\"treeRef\"\n :data=\"data\"\n :props=\"props.props\"\n :node-key=\"nodeKey as any\"\n :default-expanded-keys=\"defaultExpandedKeys\"\n :filter-node-method=\"filterNodeMethod\"\n :highlight-current=\"!multiple\"\n @node-click=\"onNodeClick\"\n >\n <template #default=\"{ node, data }\">\n <slot\n name=\"node\"\n :node=\"node\"\n :data=\"data\"\n :selected=\"selectedKeySet.has(node.key)\"\n >\n <div class=\"flex items-center gap-2 min-w-0\">\n <span\n class=\"h-4 w-4 shrink-0\"\n :class=\"selectedKeySet.has(node.key) ? 'i-lucide-check text-[var(--primary)]' : ''\"\n aria-hidden=\"true\"\n />\n <span class=\"truncate\">{{ node.label }}</span>\n </div>\n </slot>\n </template>\n </GrTree>\n </div>\n </div>\n </div>\n </transition>\n </teleport>\n </div>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"GrTreeSelect-Da-CpRqm.js","names":["$slots"],"sources":["../../../../src/components/GrTreeSelect/GrTreeSelect.vue","../../../../src/components/GrTreeSelect/GrTreeSelect.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"T extends Record<string, any> = any\">\nimport { computed, nextTick, onUnmounted, ref, watch } from 'vue'\n\nimport { vClickOutside } from '../../directives'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport GrInput from '../GrInput/GrInput.vue'\nimport GrTree, {\n type GrTreeInstance,\n type GrTreeKey,\n type GrTreeNode,\n} from '../GrTree'\nimport type { GrTreeSelectModelValue, GrTreeSelectProps } from './grTreeSelectTypes'\nimport { grTreeSelectClass, grTreeSelectPanelClass } from './grTreeSelectStyles'\n\nconst props = withDefaults(\n defineProps<GrTreeSelectProps<T>>(),\n {\n props: () => ({\n children: 'children',\n label: 'label',\n }),\n nodeKey: 'id' as any,\n defaultExpandedKeys: () => [],\n disabled: false,\n placeholder: undefined,\n size: 'md',\n invalid: false,\n state: 'default',\n multiple: false,\n clearable: false,\n valueDisplay: 'label',\n filterable: false,\n filterPlaceholder: undefined,\n filterInputmode: undefined,\n filterNodeMethod: undefined,\n closeOnSelect: undefined,\n dropdownMaxHeight: 320,\n },\n)\n\nconst { t } = useGranularityTranslations()\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: GrTreeSelectModelValue): void\n (e: 'change', value: GrTreeSelectModelValue): void\n (e: 'visibleChange', visible: boolean): void\n (e: 'clear'): void\n (e: 'nodeClick', data: T, node: GrTreeNode<T>): void\n}>()\n\ndefineSlots<{\n /** Рендер значения внутри триггера (вместо дефолтного текста). */\n value?: (props: { value: GrTreeSelectModelValue; labels: string[]; displayValue: string; pathLabels?: string[] }) => any\n /** Рендер строки дерева. */\n node?: (props: { node: GrTreeNode<T>; data: T; selected: boolean }) => any\n /** Содержимое пустого состояния (когда нет данных). */\n empty?: () => any\n}>()\n\nconst rootEl = ref<HTMLElement | null>(null)\nconst triggerEl = ref<HTMLInputElement | null>(null)\nconst filterInputRef = ref<InstanceType<typeof GrInput> | null>(null)\nconst treeRef = ref<GrTreeInstance | null>(null)\nconst panelEl = ref<HTMLElement | null>(null)\n\nconst clickOutsideExclude = [() => panelEl.value]\n\nlet hadPointerDownOnTrigger = false\n\nconst open = ref(false)\nconst filterValue = ref('')\n\nconst panelStyle = ref<Record<string, string>>({\n left: '0px',\n top: '0px',\n width: '0px',\n zIndex: '2147483647',\n})\n\nfunction syncPanelPosition(): void {\n if (typeof window === 'undefined')\n return\n\n const root = rootEl.value\n if (!root)\n return\n\n const rect = root.getBoundingClientRect()\n\n panelStyle.value = {\n left: `${rect.left}px`,\n top: `${rect.bottom + 8}px`,\n width: `${rect.width}px`,\n zIndex: '2147483647',\n }\n}\n\nfunction bindPanelPositionListeners(): void {\n if (typeof window === 'undefined')\n return\n window.addEventListener('resize', syncPanelPosition)\n window.addEventListener('scroll', syncPanelPosition, true)\n}\n\nfunction unbindPanelPositionListeners(): void {\n if (typeof window === 'undefined')\n return\n window.removeEventListener('resize', syncPanelPosition)\n window.removeEventListener('scroll', syncPanelPosition, true)\n}\n\nconst closeOnSelectResolved = computed(() => {\n return props.closeOnSelect ?? !props.multiple\n})\n\nfunction getChildrenKey() {\n return props.props.children ?? 'children'\n}\n\nfunction getLabelKey() {\n return props.props.label ?? 'label'\n}\n\nfunction nodeLabel(data: T): string {\n const key = getLabelKey() as keyof T\n const v = data[key]\n return v == null ? '' : String(v)\n}\n\nfunction nodeChildren(data: T): T[] {\n const key = getChildrenKey() as keyof T\n const v = data[key]\n return Array.isArray(v) ? (v as any) : []\n}\n\nfunction nodeKeyOf(data: T, index: number, parentKey: GrTreeKey | undefined): GrTreeKey {\n const keyName = props.nodeKey as keyof T\n const v = data[keyName]\n if (v != null)\n return v as GrTreeKey\n\n return parentKey == null ? index : `${String(parentKey)}:${index}`\n}\n\nconst labelByKey = computed(() => {\n const map = new Map<GrTreeKey, string>()\n\n const walk = (items: T[], parentKey: GrTreeKey | undefined) => {\n for (let i = 0; i < items.length; i++) {\n const item = items[i]\n const key = nodeKeyOf(item, i, parentKey)\n map.set(key, nodeLabel(item))\n walk(nodeChildren(item), key)\n }\n }\n\n walk(props.data ?? [], undefined)\n return map\n})\n\nconst pathLabelsByKey = computed(() => {\n const map = new Map<GrTreeKey, string[]>()\n\n const walk = (items: T[], parentKey: GrTreeKey | undefined, parentPath: string[]) => {\n for (let i = 0; i < items.length; i++) {\n const item = items[i]\n const key = nodeKeyOf(item, i, parentKey)\n const label = nodeLabel(item)\n const path = [...parentPath, label]\n map.set(key, path)\n walk(nodeChildren(item), key, path)\n }\n }\n\n walk(props.data ?? [], undefined, [])\n return map\n})\n\nconst selectedKeys = computed<GrTreeKey[]>(() => {\n if (props.multiple) {\n return Array.isArray(props.modelValue) ? props.modelValue : []\n }\n\n const v = props.modelValue\n if (v == null || Array.isArray(v))\n return []\n return [v]\n})\n\nconst selectedKeySet = computed(() => new Set(selectedKeys.value))\n\nconst selectedLabels = computed(() => {\n const map = labelByKey.value\n return selectedKeys.value.map((k) => map.get(k) ?? String(k))\n})\n\nconst selectedPathLabels = computed<string[] | undefined>(() => {\n if (props.multiple)\n return undefined\n\n const key = selectedKeys.value[0]\n if (key == null)\n return undefined\n\n const path = pathLabelsByKey.value.get(key)\n if (path?.length)\n return path\n\n const labels = selectedLabels.value\n return labels.length ? [labels[0]] : undefined\n})\n\nconst displayValue = computed(() => {\n const labels = selectedLabels.value\n if (labels.length === 0)\n return ''\n\n if (!props.multiple) {\n if (props.valueDisplay === 'path') {\n const path = selectedPathLabels.value\n if (path?.length)\n return path.join(' / ')\n }\n return labels[0]\n }\n\n if (labels.length === 1)\n return labels[0]\n return `${labels[0]} +${labels.length - 1}`\n})\n\nconst hasSelection = computed(() => selectedKeys.value.length > 0)\n\nconst resolvedFilterPlaceholder = computed(() => {\n return props.filterPlaceholder ?? t('gr.treeSelect.filterPlaceholder', 'Search…')\n})\n\nconst className = computed(() => {\n return grTreeSelectClass({\n size: props.size,\n state: props.state,\n invalid: props.invalid,\n })\n})\n\nconst panelClasses = computed(() => {\n return grTreeSelectPanelClass\n})\n\nfunction setOpen(next: boolean) {\n if (props.disabled)\n return\n\n if (open.value === next)\n return\n\n open.value = next\n emit('visibleChange', next)\n}\n\nfunction onClickOutside(): void {\n setOpen(false)\n}\n\nfunction openDropdown(): void {\n setOpen(true)\n}\n\nfunction closeDropdown(): void {\n setOpen(false)\n}\n\nfunction toggleDropdown(): void {\n setOpen(!open.value)\n}\n\nfunction onTriggerPointerDown(): void {\n hadPointerDownOnTrigger = true\n if (typeof window !== 'undefined') {\n window.setTimeout(() => {\n hadPointerDownOnTrigger = false\n }, 0)\n }\n else {\n // SSR / no window: reset sync\n hadPointerDownOnTrigger = false\n }\n}\n\nfunction onTriggerFocus(): void {\n if (hadPointerDownOnTrigger)\n return\n openDropdown()\n}\n\nfunction closeOnEscape(e: KeyboardEvent): void {\n if (e.key === 'Escape') {\n closeDropdown()\n nextTick(() => triggerEl.value?.focus())\n }\n}\n\nwatch(\n open,\n async (isOpen) => {\n if (typeof document === 'undefined')\n return\n\n document.removeEventListener('keydown', closeOnEscape)\n unbindPanelPositionListeners()\n\n if (isOpen)\n document.addEventListener('keydown', closeOnEscape)\n\n if (!isOpen)\n return\n\n bindPanelPositionListeners()\n await nextTick()\n syncPanelPosition()\n\n // sync tree highlight\n if (!props.multiple) {\n const v = props.modelValue\n if (v != null && !Array.isArray(v))\n treeRef.value?.setCurrentKey(v)\n }\n\n // focus filter input\n if (props.filterable) {\n await nextTick()\n filterInputRef.value?.focus()\n }\n },\n { immediate: true },\n)\n\nonUnmounted(() => {\n if (typeof document === 'undefined')\n return\n document.removeEventListener('keydown', closeOnEscape)\n unbindPanelPositionListeners()\n})\n\nwatch(\n () => props.modelValue,\n (v) => {\n if (props.multiple)\n return\n if (v == null || Array.isArray(v)) {\n treeRef.value?.setCurrentKey(undefined)\n return\n }\n treeRef.value?.setCurrentKey(v)\n },\n)\n\nwatch(\n filterValue,\n (v) => {\n treeRef.value?.filter(v)\n },\n)\n\nwatch(\n open,\n (isOpen) => {\n if (isOpen)\n return\n if (filterValue.value.trim().length > 0)\n filterValue.value = ''\n },\n)\n\nfunction emitModel(next: GrTreeSelectModelValue) {\n emit('update:modelValue', next)\n emit('change', next)\n}\n\nfunction clear(): void {\n if (props.disabled)\n return\n\n const next: GrTreeSelectModelValue = props.multiple ? [] : null\n emitModel(next)\n emit('clear')\n if (!props.multiple)\n treeRef.value?.setCurrentKey(undefined)\n}\n\nfunction onTriggerKeydown(e: KeyboardEvent): void {\n if (props.disabled)\n return\n\n if (e.key === 'ArrowDown' || e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n openDropdown()\n }\n if (e.key === 'Escape') {\n e.preventDefault()\n closeDropdown()\n }\n}\n\nfunction onNodeClick(data: T, node: GrTreeNode<T>): void {\n emit('nodeClick', data, node)\n\n if (props.disabled)\n return\n\n if (props.multiple) {\n const next = new Set(selectedKeySet.value)\n if (next.has(node.key))\n next.delete(node.key)\n else\n next.add(node.key)\n emitModel([...next])\n\n if (closeOnSelectResolved.value) {\n closeDropdown()\n }\n return\n }\n\n emitModel(node.key)\n if (closeOnSelectResolved.value) {\n closeDropdown()\n }\n}\n</script>\n\n<template>\n <div\n ref=\"rootEl\"\n v-click-outside=\"{ handler: onClickOutside, enabled: open, exclude: clickOutsideExclude }\"\n data-ds-tree-select\n class=\"relative\"\n >\n <div class=\"relative\">\n <input\n ref=\"triggerEl\"\n data-testid=\"ds-tree-select-trigger\"\n data-ds-tree-select-trigger\n type=\"text\"\n :value=\"displayValue\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n readonly\n role=\"combobox\"\n aria-readonly=\"true\"\n :aria-expanded=\"open ? 'true' : 'false'\"\n :aria-invalid=\"invalid ? 'true' : undefined\"\n class=\"w-full rounded-md border bg-[var(--bg)] text-[var(--fg)] placeholder:text-[var(--muted-fg)] transition-colors duration-150 focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)] disabled:opacity-50 disabled:cursor-not-allowed\"\n :class=\"[className, $slots.value ? 'text-transparent placeholder:text-transparent' : '']\"\n @pointerdown=\"onTriggerPointerDown\"\n @click=\"toggleDropdown\"\n @focus=\"onTriggerFocus\"\n @keydown=\"onTriggerKeydown\"\n >\n\n <button\n v-if=\"clearable && hasSelection\"\n data-testid=\"ds-tree-select-clear\"\n data-ds-tree-select-clear\n type=\"button\"\n class=\"absolute top-1/2 -translate-y-1/2 right-3 h-6 w-6 inline-flex items-center justify-center rounded-md text-[var(--muted-fg)] hover:text-[var(--fg)] hover:bg-[color-mix(in_srgb,var(--muted)_25%,transparent)] disabled:opacity-50\"\n :disabled=\"disabled\"\n :aria-label=\"t('gr.common.clear', 'Clear')\"\n @click.stop=\"clear\"\n >\n <span class=\"i-lucide-x h-4 w-4\" />\n </button>\n\n <span\n v-else\n data-testid=\"ds-tree-select-chevron\"\n data-ds-tree-select-chevron\n class=\"absolute top-1/2 -translate-y-1/2 right-3 text-[var(--muted-fg)] pointer-events-none\"\n >\n <span\n class=\"i-lucide-chevron-down h-4 w-4 transition-transform duration-150\"\n :class=\"open ? 'rotate-180' : ''\"\n />\n </span>\n\n <div\n v-if=\"$slots.value\"\n class=\"absolute inset-y-0 left-3 right-9 flex items-center pointer-events-none\"\n >\n <slot\n name=\"value\"\n :value=\"modelValue\"\n :labels=\"selectedLabels\"\n :display-value=\"displayValue\"\n :path-labels=\"selectedPathLabels\"\n />\n </div>\n </div>\n\n <teleport to=\"body\">\n <transition\n enter-active-class=\"transition ease-out duration-150\"\n enter-from-class=\"transform opacity-0 scale-95\"\n enter-to-class=\"transform opacity-100 scale-100\"\n leave-active-class=\"transition ease-in duration-100\"\n leave-from-class=\"transform opacity-100 scale-100\"\n leave-to-class=\"transform opacity-0 scale-95\"\n >\n <div\n v-show=\"open\"\n ref=\"panelEl\"\n data-testid=\"ds-tree-select-panel\"\n data-ds-tree-select-panel\n class=\"fixed w-full\"\n :style=\"panelStyle\"\n >\n <div :class=\"panelClasses\">\n <div v-if=\"filterable\" class=\"p-2 border-b border-[var(--brd)]\">\n <GrInput\n ref=\"filterInputRef\"\n v-model=\"filterValue\"\n data-testid=\"ds-tree-select-filter\"\n data-ds-tree-select-filter\n type=\"search\"\n :inputmode=\"filterInputmode\"\n :placeholder=\"resolvedFilterPlaceholder\"\n size=\"sm\"\n />\n </div>\n\n <div\n class=\"p-1 overflow-auto\"\n :style=\"{ maxHeight: `${dropdownMaxHeight}px` }\"\n >\n <div v-if=\"(data?.length ?? 0) === 0\" class=\"px-3 py-2 text-[13px] text-[var(--muted-fg)]\">\n <slot name=\"empty\">\n {{ t('gr.treeSelect.empty', 'No data') }}\n </slot>\n </div>\n\n <GrTree\n v-else\n ref=\"treeRef\"\n :data=\"data\"\n :props=\"props.props\"\n :node-key=\"nodeKey as any\"\n :default-expanded-keys=\"defaultExpandedKeys\"\n :filter-node-method=\"filterNodeMethod\"\n :highlight-current=\"!multiple\"\n @node-click=\"onNodeClick\"\n >\n <template #default=\"{ node, data }\">\n <slot\n name=\"node\"\n :node=\"node\"\n :data=\"data\"\n :selected=\"selectedKeySet.has(node.key)\"\n >\n <div class=\"flex items-center gap-2 min-w-0\">\n <span\n class=\"h-4 w-4 shrink-0\"\n :class=\"selectedKeySet.has(node.key) ? 'i-lucide-check text-[var(--primary)]' : ''\"\n aria-hidden=\"true\"\n />\n <span class=\"truncate\">{{ node.label }}</span>\n </div>\n </slot>\n </template>\n </GrTree>\n </div>\n </div>\n </div>\n </transition>\n </teleport>\n </div>\n</template>\n","<script setup lang=\"ts\" generic=\"T extends Record<string, any> = any\">\nimport { computed, nextTick, onUnmounted, ref, watch } from 'vue'\n\nimport { vClickOutside } from '../../directives'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport GrInput from '../GrInput/GrInput.vue'\nimport GrTree, {\n type GrTreeInstance,\n type GrTreeKey,\n type GrTreeNode,\n} from '../GrTree'\nimport type { GrTreeSelectModelValue, GrTreeSelectProps } from './grTreeSelectTypes'\nimport { grTreeSelectClass, grTreeSelectPanelClass } from './grTreeSelectStyles'\n\nconst props = withDefaults(\n defineProps<GrTreeSelectProps<T>>(),\n {\n props: () => ({\n children: 'children',\n label: 'label',\n }),\n nodeKey: 'id' as any,\n defaultExpandedKeys: () => [],\n disabled: false,\n placeholder: undefined,\n size: 'md',\n invalid: false,\n state: 'default',\n multiple: false,\n clearable: false,\n valueDisplay: 'label',\n filterable: false,\n filterPlaceholder: undefined,\n filterInputmode: undefined,\n filterNodeMethod: undefined,\n closeOnSelect: undefined,\n dropdownMaxHeight: 320,\n },\n)\n\nconst { t } = useGranularityTranslations()\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: GrTreeSelectModelValue): void\n (e: 'change', value: GrTreeSelectModelValue): void\n (e: 'visibleChange', visible: boolean): void\n (e: 'clear'): void\n (e: 'nodeClick', data: T, node: GrTreeNode<T>): void\n}>()\n\ndefineSlots<{\n /** Рендер значения внутри триггера (вместо дефолтного текста). */\n value?: (props: { value: GrTreeSelectModelValue; labels: string[]; displayValue: string; pathLabels?: string[] }) => any\n /** Рендер строки дерева. */\n node?: (props: { node: GrTreeNode<T>; data: T; selected: boolean }) => any\n /** Содержимое пустого состояния (когда нет данных). */\n empty?: () => any\n}>()\n\nconst rootEl = ref<HTMLElement | null>(null)\nconst triggerEl = ref<HTMLInputElement | null>(null)\nconst filterInputRef = ref<InstanceType<typeof GrInput> | null>(null)\nconst treeRef = ref<GrTreeInstance | null>(null)\nconst panelEl = ref<HTMLElement | null>(null)\n\nconst clickOutsideExclude = [() => panelEl.value]\n\nlet hadPointerDownOnTrigger = false\n\nconst open = ref(false)\nconst filterValue = ref('')\n\nconst panelStyle = ref<Record<string, string>>({\n left: '0px',\n top: '0px',\n width: '0px',\n zIndex: '2147483647',\n})\n\nfunction syncPanelPosition(): void {\n if (typeof window === 'undefined')\n return\n\n const root = rootEl.value\n if (!root)\n return\n\n const rect = root.getBoundingClientRect()\n\n panelStyle.value = {\n left: `${rect.left}px`,\n top: `${rect.bottom + 8}px`,\n width: `${rect.width}px`,\n zIndex: '2147483647',\n }\n}\n\nfunction bindPanelPositionListeners(): void {\n if (typeof window === 'undefined')\n return\n window.addEventListener('resize', syncPanelPosition)\n window.addEventListener('scroll', syncPanelPosition, true)\n}\n\nfunction unbindPanelPositionListeners(): void {\n if (typeof window === 'undefined')\n return\n window.removeEventListener('resize', syncPanelPosition)\n window.removeEventListener('scroll', syncPanelPosition, true)\n}\n\nconst closeOnSelectResolved = computed(() => {\n return props.closeOnSelect ?? !props.multiple\n})\n\nfunction getChildrenKey() {\n return props.props.children ?? 'children'\n}\n\nfunction getLabelKey() {\n return props.props.label ?? 'label'\n}\n\nfunction nodeLabel(data: T): string {\n const key = getLabelKey() as keyof T\n const v = data[key]\n return v == null ? '' : String(v)\n}\n\nfunction nodeChildren(data: T): T[] {\n const key = getChildrenKey() as keyof T\n const v = data[key]\n return Array.isArray(v) ? (v as any) : []\n}\n\nfunction nodeKeyOf(data: T, index: number, parentKey: GrTreeKey | undefined): GrTreeKey {\n const keyName = props.nodeKey as keyof T\n const v = data[keyName]\n if (v != null)\n return v as GrTreeKey\n\n return parentKey == null ? index : `${String(parentKey)}:${index}`\n}\n\nconst labelByKey = computed(() => {\n const map = new Map<GrTreeKey, string>()\n\n const walk = (items: T[], parentKey: GrTreeKey | undefined) => {\n for (let i = 0; i < items.length; i++) {\n const item = items[i]\n const key = nodeKeyOf(item, i, parentKey)\n map.set(key, nodeLabel(item))\n walk(nodeChildren(item), key)\n }\n }\n\n walk(props.data ?? [], undefined)\n return map\n})\n\nconst pathLabelsByKey = computed(() => {\n const map = new Map<GrTreeKey, string[]>()\n\n const walk = (items: T[], parentKey: GrTreeKey | undefined, parentPath: string[]) => {\n for (let i = 0; i < items.length; i++) {\n const item = items[i]\n const key = nodeKeyOf(item, i, parentKey)\n const label = nodeLabel(item)\n const path = [...parentPath, label]\n map.set(key, path)\n walk(nodeChildren(item), key, path)\n }\n }\n\n walk(props.data ?? [], undefined, [])\n return map\n})\n\nconst selectedKeys = computed<GrTreeKey[]>(() => {\n if (props.multiple) {\n return Array.isArray(props.modelValue) ? props.modelValue : []\n }\n\n const v = props.modelValue\n if (v == null || Array.isArray(v))\n return []\n return [v]\n})\n\nconst selectedKeySet = computed(() => new Set(selectedKeys.value))\n\nconst selectedLabels = computed(() => {\n const map = labelByKey.value\n return selectedKeys.value.map((k) => map.get(k) ?? String(k))\n})\n\nconst selectedPathLabels = computed<string[] | undefined>(() => {\n if (props.multiple)\n return undefined\n\n const key = selectedKeys.value[0]\n if (key == null)\n return undefined\n\n const path = pathLabelsByKey.value.get(key)\n if (path?.length)\n return path\n\n const labels = selectedLabels.value\n return labels.length ? [labels[0]] : undefined\n})\n\nconst displayValue = computed(() => {\n const labels = selectedLabels.value\n if (labels.length === 0)\n return ''\n\n if (!props.multiple) {\n if (props.valueDisplay === 'path') {\n const path = selectedPathLabels.value\n if (path?.length)\n return path.join(' / ')\n }\n return labels[0]\n }\n\n if (labels.length === 1)\n return labels[0]\n return `${labels[0]} +${labels.length - 1}`\n})\n\nconst hasSelection = computed(() => selectedKeys.value.length > 0)\n\nconst resolvedFilterPlaceholder = computed(() => {\n return props.filterPlaceholder ?? t('gr.treeSelect.filterPlaceholder', 'Search…')\n})\n\nconst className = computed(() => {\n return grTreeSelectClass({\n size: props.size,\n state: props.state,\n invalid: props.invalid,\n })\n})\n\nconst panelClasses = computed(() => {\n return grTreeSelectPanelClass\n})\n\nfunction setOpen(next: boolean) {\n if (props.disabled)\n return\n\n if (open.value === next)\n return\n\n open.value = next\n emit('visibleChange', next)\n}\n\nfunction onClickOutside(): void {\n setOpen(false)\n}\n\nfunction openDropdown(): void {\n setOpen(true)\n}\n\nfunction closeDropdown(): void {\n setOpen(false)\n}\n\nfunction toggleDropdown(): void {\n setOpen(!open.value)\n}\n\nfunction onTriggerPointerDown(): void {\n hadPointerDownOnTrigger = true\n if (typeof window !== 'undefined') {\n window.setTimeout(() => {\n hadPointerDownOnTrigger = false\n }, 0)\n }\n else {\n // SSR / no window: reset sync\n hadPointerDownOnTrigger = false\n }\n}\n\nfunction onTriggerFocus(): void {\n if (hadPointerDownOnTrigger)\n return\n openDropdown()\n}\n\nfunction closeOnEscape(e: KeyboardEvent): void {\n if (e.key === 'Escape') {\n closeDropdown()\n nextTick(() => triggerEl.value?.focus())\n }\n}\n\nwatch(\n open,\n async (isOpen) => {\n if (typeof document === 'undefined')\n return\n\n document.removeEventListener('keydown', closeOnEscape)\n unbindPanelPositionListeners()\n\n if (isOpen)\n document.addEventListener('keydown', closeOnEscape)\n\n if (!isOpen)\n return\n\n bindPanelPositionListeners()\n await nextTick()\n syncPanelPosition()\n\n // sync tree highlight\n if (!props.multiple) {\n const v = props.modelValue\n if (v != null && !Array.isArray(v))\n treeRef.value?.setCurrentKey(v)\n }\n\n // focus filter input\n if (props.filterable) {\n await nextTick()\n filterInputRef.value?.focus()\n }\n },\n { immediate: true },\n)\n\nonUnmounted(() => {\n if (typeof document === 'undefined')\n return\n document.removeEventListener('keydown', closeOnEscape)\n unbindPanelPositionListeners()\n})\n\nwatch(\n () => props.modelValue,\n (v) => {\n if (props.multiple)\n return\n if (v == null || Array.isArray(v)) {\n treeRef.value?.setCurrentKey(undefined)\n return\n }\n treeRef.value?.setCurrentKey(v)\n },\n)\n\nwatch(\n filterValue,\n (v) => {\n treeRef.value?.filter(v)\n },\n)\n\nwatch(\n open,\n (isOpen) => {\n if (isOpen)\n return\n if (filterValue.value.trim().length > 0)\n filterValue.value = ''\n },\n)\n\nfunction emitModel(next: GrTreeSelectModelValue) {\n emit('update:modelValue', next)\n emit('change', next)\n}\n\nfunction clear(): void {\n if (props.disabled)\n return\n\n const next: GrTreeSelectModelValue = props.multiple ? [] : null\n emitModel(next)\n emit('clear')\n if (!props.multiple)\n treeRef.value?.setCurrentKey(undefined)\n}\n\nfunction onTriggerKeydown(e: KeyboardEvent): void {\n if (props.disabled)\n return\n\n if (e.key === 'ArrowDown' || e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n openDropdown()\n }\n if (e.key === 'Escape') {\n e.preventDefault()\n closeDropdown()\n }\n}\n\nfunction onNodeClick(data: T, node: GrTreeNode<T>): void {\n emit('nodeClick', data, node)\n\n if (props.disabled)\n return\n\n if (props.multiple) {\n const next = new Set(selectedKeySet.value)\n if (next.has(node.key))\n next.delete(node.key)\n else\n next.add(node.key)\n emitModel([...next])\n\n if (closeOnSelectResolved.value) {\n closeDropdown()\n }\n return\n }\n\n emitModel(node.key)\n if (closeOnSelectResolved.value) {\n closeDropdown()\n }\n}\n</script>\n\n<template>\n <div\n ref=\"rootEl\"\n v-click-outside=\"{ handler: onClickOutside, enabled: open, exclude: clickOutsideExclude }\"\n data-ds-tree-select\n class=\"relative\"\n >\n <div class=\"relative\">\n <input\n ref=\"triggerEl\"\n data-testid=\"ds-tree-select-trigger\"\n data-ds-tree-select-trigger\n type=\"text\"\n :value=\"displayValue\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n readonly\n role=\"combobox\"\n aria-readonly=\"true\"\n :aria-expanded=\"open ? 'true' : 'false'\"\n :aria-invalid=\"invalid ? 'true' : undefined\"\n class=\"w-full rounded-md border bg-[var(--bg)] text-[var(--fg)] placeholder:text-[var(--muted-fg)] transition-colors duration-150 focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)] disabled:opacity-50 disabled:cursor-not-allowed\"\n :class=\"[className, $slots.value ? 'text-transparent placeholder:text-transparent' : '']\"\n @pointerdown=\"onTriggerPointerDown\"\n @click=\"toggleDropdown\"\n @focus=\"onTriggerFocus\"\n @keydown=\"onTriggerKeydown\"\n >\n\n <button\n v-if=\"clearable && hasSelection\"\n data-testid=\"ds-tree-select-clear\"\n data-ds-tree-select-clear\n type=\"button\"\n class=\"absolute top-1/2 -translate-y-1/2 right-3 h-6 w-6 inline-flex items-center justify-center rounded-md text-[var(--muted-fg)] hover:text-[var(--fg)] hover:bg-[color-mix(in_srgb,var(--muted)_25%,transparent)] disabled:opacity-50\"\n :disabled=\"disabled\"\n :aria-label=\"t('gr.common.clear', 'Clear')\"\n @click.stop=\"clear\"\n >\n <span class=\"i-lucide-x h-4 w-4\" />\n </button>\n\n <span\n v-else\n data-testid=\"ds-tree-select-chevron\"\n data-ds-tree-select-chevron\n class=\"absolute top-1/2 -translate-y-1/2 right-3 text-[var(--muted-fg)] pointer-events-none\"\n >\n <span\n class=\"i-lucide-chevron-down h-4 w-4 transition-transform duration-150\"\n :class=\"open ? 'rotate-180' : ''\"\n />\n </span>\n\n <div\n v-if=\"$slots.value\"\n class=\"absolute inset-y-0 left-3 right-9 flex items-center pointer-events-none\"\n >\n <slot\n name=\"value\"\n :value=\"modelValue\"\n :labels=\"selectedLabels\"\n :display-value=\"displayValue\"\n :path-labels=\"selectedPathLabels\"\n />\n </div>\n </div>\n\n <teleport to=\"body\">\n <transition\n enter-active-class=\"transition ease-out duration-150\"\n enter-from-class=\"transform opacity-0 scale-95\"\n enter-to-class=\"transform opacity-100 scale-100\"\n leave-active-class=\"transition ease-in duration-100\"\n leave-from-class=\"transform opacity-100 scale-100\"\n leave-to-class=\"transform opacity-0 scale-95\"\n >\n <div\n v-show=\"open\"\n ref=\"panelEl\"\n data-testid=\"ds-tree-select-panel\"\n data-ds-tree-select-panel\n class=\"fixed w-full\"\n :style=\"panelStyle\"\n >\n <div :class=\"panelClasses\">\n <div v-if=\"filterable\" class=\"p-2 border-b border-[var(--brd)]\">\n <GrInput\n ref=\"filterInputRef\"\n v-model=\"filterValue\"\n data-testid=\"ds-tree-select-filter\"\n data-ds-tree-select-filter\n type=\"search\"\n :inputmode=\"filterInputmode\"\n :placeholder=\"resolvedFilterPlaceholder\"\n size=\"sm\"\n />\n </div>\n\n <div\n class=\"p-1 overflow-auto\"\n :style=\"{ maxHeight: `${dropdownMaxHeight}px` }\"\n >\n <div v-if=\"(data?.length ?? 0) === 0\" class=\"px-3 py-2 text-[13px] text-[var(--muted-fg)]\">\n <slot name=\"empty\">\n {{ t('gr.treeSelect.empty', 'No data') }}\n </slot>\n </div>\n\n <GrTree\n v-else\n ref=\"treeRef\"\n :data=\"data\"\n :props=\"props.props\"\n :node-key=\"nodeKey as any\"\n :default-expanded-keys=\"defaultExpandedKeys\"\n :filter-node-method=\"filterNodeMethod\"\n :highlight-current=\"!multiple\"\n @node-click=\"onNodeClick\"\n >\n <template #default=\"{ node, data }\">\n <slot\n name=\"node\"\n :node=\"node\"\n :data=\"data\"\n :selected=\"selectedKeySet.has(node.key)\"\n >\n <div class=\"flex items-center gap-2 min-w-0\">\n <span\n class=\"h-4 w-4 shrink-0\"\n :class=\"selectedKeySet.has(node.key) ? 'i-lucide-check text-[var(--primary)]' : ''\"\n aria-hidden=\"true\"\n />\n <span class=\"truncate\">{{ node.label }}</span>\n </div>\n </slot>\n </template>\n </GrTree>\n </div>\n </div>\n </div>\n </transition>\n </teleport>\n </div>\n</template>\n"],"mappings":"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"}
@@ -1,3 +1,3 @@
1
- import { n as grTreeSelectSafelist, t as grTreeSelectConfig } from "../../chunks/config-C0b_3LJV.js";
2
- import { t as GrTreeSelect_default } from "./chunks/GrTreeSelect-DN6XFjOD.js";
1
+ import { n as grTreeSelectSafelist, t as grTreeSelectConfig } from "../../chunks/config-BNOf_qjD.js";
2
+ import { t as GrTreeSelect_default } from "./chunks/GrTreeSelect-Da-CpRqm.js";
3
3
  export { GrTreeSelect_default as GrTreeSelect, GrTreeSelect_default as default, grTreeSelectConfig, grTreeSelectSafelist };
@@ -51,5 +51,3 @@ function useTheme(options = {}) {
51
51
  }
52
52
  //#endregion
53
53
  export { initThemeEarly, useTheme };
54
-
55
- //# sourceMappingURL=useTheme.js.map
@@ -52,5 +52,3 @@ function useToast() {
52
52
  }
53
53
  //#endregion
54
54
  export { useToast };
55
-
56
- //# sourceMappingURL=useToast.js.map