@feugene/granularity 0.8.0 → 0.9.1

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 (268) hide show
  1. package/dist/chunks/{adapter-CRyH4YC8.js.map → adapter-BqqjEZGU.js.map} +1 -1
  2. package/dist/chunks/arrow-up-DZdIrpaF.js.map +1 -0
  3. package/dist/chunks/config-72sW9Bag2.js.map +1 -0
  4. package/dist/chunks/{config-B8rC_K97.js.map → config-B1kFmhpM.js.map} +1 -1
  5. package/dist/chunks/{config-BhvNm4Pp.js.map → config-B2YTEe_h.js.map} +1 -1
  6. package/dist/chunks/{config-C0rHS1-l.js.map → config-BOdu-O_B.js.map} +1 -1
  7. package/dist/chunks/{config-D27BL0H9.js.map → config-BU0olrvr.js.map} +1 -1
  8. package/dist/chunks/{config-XoANT5mU.js → config-BY81UKv0.js} +1 -1
  9. package/dist/chunks/{config-XoANT5mU.js.map → config-BY81UKv0.js.map} +1 -1
  10. package/dist/chunks/config-B_nSBc7W.js.map +1 -0
  11. package/dist/chunks/{config-DbqFk-IW.js.map → config-BbKroFtR.js.map} +1 -1
  12. package/dist/chunks/config-Bcf-8XlK2.js.map +1 -0
  13. package/dist/chunks/config-BduXEXjt.js.map +1 -0
  14. package/dist/chunks/config-BeQuykDk2.js.map +1 -0
  15. package/dist/chunks/{config-Dusr9jcE.js.map → config-BnWSHTEU.js.map} +1 -1
  16. package/dist/chunks/{config-C4AlNm912.js → config-Br_qI3Za.js} +1 -1
  17. package/dist/chunks/config-Br_qI3Za.js.map +1 -0
  18. package/dist/chunks/{config-C5TN9J2Z.js → config-C5OwJM3-.js} +1 -1
  19. package/dist/chunks/{config-C5TN9J2Z.js.map → config-C5OwJM3-.js.map} +1 -1
  20. package/dist/chunks/config-C6zT56Jc2.js.map +1 -0
  21. package/dist/chunks/{config-ZJVOVgqR.js → config-CFf7xaG1.js} +1 -1
  22. package/dist/chunks/{config-ZJVOVgqR.js.map → config-CFf7xaG1.js.map} +1 -1
  23. package/dist/chunks/{config-wo-ncgTH.js.map → config-CdJpnjDj.js.map} +1 -1
  24. package/dist/chunks/config-CetsgpaZ2.js.map +1 -0
  25. package/dist/chunks/{config-D1DI3roo.js.map → config-Ci9nXGUV.js.map} +1 -1
  26. package/dist/chunks/{config-CjEplP6D.js.map → config-CpMYmvVT.js.map} +1 -1
  27. package/dist/chunks/{config-DZAQpfz0.js.map → config-Cp_XHsze.js.map} +1 -1
  28. package/dist/chunks/{config-D98m8iyz.js.map → config-CvGdaXvH.js.map} +1 -1
  29. package/dist/chunks/{config-CtomKf-k.js.map → config-D4s_QWVP.js.map} +1 -1
  30. package/dist/chunks/{config-D32znLtV2.js.map → config-D6Oe3blW2.js.map} +1 -1
  31. package/dist/chunks/{config-CVnluhKO.js.map → config-DF_RlCIO.js.map} +1 -1
  32. package/dist/chunks/{config-C4qAA0Sb.js.map → config-DSBlHQVa.js.map} +1 -1
  33. package/dist/chunks/{config-Mp9DJ9Mq2.js.map → config-DaHI5bD_2.js.map} +1 -1
  34. package/dist/chunks/{config-3SftO0uG.js.map → config-Dcb7xK-C.js.map} +1 -1
  35. package/dist/chunks/config-DmjwIqx1.js.map +1 -0
  36. package/dist/chunks/{config-D6Af6WZw.js.map → config-DoBk_CzG.js.map} +1 -1
  37. package/dist/chunks/config-Dzd6BzIN2.js.map +1 -0
  38. package/dist/chunks/{config-Db4BEG8Y.js.map → config-O1_FTqD3.js.map} +1 -1
  39. package/dist/chunks/config-_3De4HFf.js.map +1 -0
  40. package/dist/chunks/{config-B44QVIge.js → config-d386uO3O.js} +1 -1
  41. package/dist/chunks/{config-B44QVIge.js.map → config-d386uO3O.js.map} +1 -1
  42. package/dist/chunks/{config-DudL02ag.js.map → config-iuMz79Mg.js.map} +1 -1
  43. package/dist/chunks/config-vcDVCYXo.js.map +1 -0
  44. package/dist/chunks/{en-QNZhjmSJ.js.map → en-foQA8imU.js.map} +1 -1
  45. package/dist/chunks/{es-CKLPuE0h.js → es-Bx3Kuy6z.js} +3 -3
  46. package/dist/chunks/{es-CKLPuE0h.js.map → es-Bx3Kuy6z.js.map} +1 -1
  47. package/dist/chunks/{es-C1c5XsIK.js.map → es-DZFSojYL.js.map} +1 -1
  48. package/dist/chunks/{fileValidation-CwJA8Vmn.js.map → fileValidation-c_iBg74s.js.map} +1 -1
  49. package/dist/chunks/{grDropdownStyles-DMp7RrI9.js.map → grDropdownStyles-B41mVR1H.js.map} +1 -1
  50. package/dist/chunks/{grLoadingStyles-CrxZHFL0.js.map → grLoadingStyles-DmI-SJ3i.js.map} +1 -1
  51. package/dist/chunks/{grModalStyles-Dv2NXBKi.js.map → grModalStyles-DS1Vl6EW.js.map} +1 -1
  52. package/dist/chunks/{grSelectStyles-DTAYNzxn.js.map → grSelectStyles-pUt19VGy.js.map} +1 -1
  53. package/dist/chunks/{grStyle-5EMYYctb.js.map → grStyle-CUaTmpyW.js.map} +1 -1
  54. package/dist/chunks/{granularityI18n-CXa_uN7f.js → granularityI18n-LcJ88Vce.js} +1 -1
  55. package/dist/chunks/{granularityI18n-CXa_uN7f.js.map → granularityI18n-LcJ88Vce.js.map} +1 -1
  56. package/dist/chunks/{ru-DcF7ciz0.js.map → ru-LhkPpPIl.js.map} +1 -1
  57. package/dist/chunks/safelist-_UVzJrgE2.js.map +1 -0
  58. package/dist/chunks/{shared-D7q-upeJ.js → shared-BiqXd5MW.js} +37 -37
  59. package/dist/chunks/{shared-D7q-upeJ.js.map → shared-BiqXd5MW.js.map} +1 -1
  60. package/dist/components/GrConfirmDialog/chunks/{GrConfirmDialog-DE-d77Us.js → GrConfirmDialog-DuUQA7nv.js} +31 -8
  61. package/dist/components/GrConfirmDialog/chunks/GrConfirmDialog-DuUQA7nv.js.map +1 -0
  62. package/dist/components/GrConfirmDialog/index.js +2 -2
  63. package/dist/components/GrDataTable/chunks/{GrDataTable-QDOJWmdY.js → GrDataTable-ClcYiyc8.js} +2 -2
  64. package/dist/components/GrDataTable/chunks/{GrDataTable-QDOJWmdY.js.map → GrDataTable-ClcYiyc8.js.map} +1 -1
  65. package/dist/components/GrDataTable/index.js +2 -2
  66. package/dist/components/GrDialog/chunks/{GrDialog-Ba3Ojcsq.js → GrDialog-SYcF-4op.js} +1 -1
  67. package/dist/components/GrDialog/chunks/{GrDialog-Ba3Ojcsq.js.map → GrDialog-SYcF-4op.js.map} +1 -1
  68. package/dist/components/GrDialog/index.js +2 -2
  69. package/dist/components/GrDrawer/chunks/{GrDrawer-h33X403E.js → GrDrawer-BW3wtI7h.js} +1 -1
  70. package/dist/components/GrDrawer/chunks/{GrDrawer-h33X403E.js.map → GrDrawer-BW3wtI7h.js.map} +1 -1
  71. package/dist/components/GrDrawer/index.js +2 -2
  72. package/dist/components/GrDropdown/chunks/{GrDropdown-BkACCXdp.js → GrDropdown-DOvHKnih.js} +1 -1
  73. package/dist/components/GrDropdown/chunks/{GrDropdown-BkACCXdp.js.map → GrDropdown-DOvHKnih.js.map} +1 -1
  74. package/dist/components/GrDropdown/index.js +2 -2
  75. package/dist/components/GrDropdownMenu/chunks/{GrDropdownMenu-BEenXrJw.js → GrDropdownMenu-CLPwbiyG.js} +1 -1
  76. package/dist/components/GrDropdownMenu/chunks/{GrDropdownMenu-BEenXrJw.js.map → GrDropdownMenu-CLPwbiyG.js.map} +1 -1
  77. package/dist/components/GrDropdownMenu/index.js +2 -2
  78. package/dist/components/GrEmptyState/chunks/{GrEmptyState-BLbMJFW-.js.map → GrEmptyState-Dj2V5GaX.js.map} +1 -1
  79. package/dist/components/GrEmptyState/index.js +2 -2
  80. package/dist/components/GrFileUpload/chunks/{GrFileUpload-DYRERhI2.js → GrFileUpload-BEKNB1RM.js} +5 -5
  81. package/dist/components/GrFileUpload/chunks/GrFileUpload-BEKNB1RM.js.map +1 -0
  82. package/dist/components/GrFileUpload/index.js +3 -3
  83. package/dist/components/GrFormField/chunks/{GrFormField-C1oWTT_0.js.map → GrFormField-U7c_aDPJ.js.map} +1 -1
  84. package/dist/components/GrFormField/index.js +2 -2
  85. package/dist/components/GrFormFile/chunks/{GrFormFile-WqF-dPTB.js → GrFormFile-CIleXnfr.js} +1 -1
  86. package/dist/components/GrFormFile/chunks/{GrFormFile-WqF-dPTB.js.map → GrFormFile-CIleXnfr.js.map} +1 -1
  87. package/dist/components/GrFormFile/index.js +2 -2
  88. package/dist/components/GrFormSection/chunks/{GrFormSection-CWBk2EUm.js.map → GrFormSection-DpGhY7MX.js.map} +1 -1
  89. package/dist/components/GrFormSection/index.js +2 -2
  90. package/dist/components/GrImageViewer/chunks/{GrImageViewer-Cpj5zyZQ.js.map → GrImageViewer-Cn1X-sWS.js.map} +1 -1
  91. package/dist/components/GrImageViewer/index.js +2 -2
  92. package/dist/components/GrInput/chunks/{GrInput-CfO2RsM-.js.map → GrInput-gwFQ1sk4.js.map} +1 -1
  93. package/dist/components/GrInput/index.js +2 -2
  94. package/dist/components/GrInputTag/chunks/{GrInputTag-CeEy0IwD.js → GrInputTag-Dcj3F6rQ.js} +1 -1
  95. package/dist/components/GrInputTag/chunks/{GrInputTag-CeEy0IwD.js.map → GrInputTag-Dcj3F6rQ.js.map} +1 -1
  96. package/dist/components/GrInputTag/index.js +2 -2
  97. package/dist/components/GrLink/chunks/{GrLink-BLPigqij.js → GrLink-BMwn2iJ9.js} +1 -1
  98. package/dist/components/GrLink/chunks/{GrLink-BLPigqij.js.map → GrLink-BMwn2iJ9.js.map} +1 -1
  99. package/dist/components/GrLink/index.js +2 -2
  100. package/dist/components/GrList/chunks/{GrList-C2GpK56-.js.map → GrList-D8nM1FuV.js.map} +1 -1
  101. package/dist/components/GrList/index.js +2 -2
  102. package/dist/components/GrLoading/chunks/{GrLoading-CxNgHgNw.js → GrLoading-mfyfghxs.js} +1 -1
  103. package/dist/components/GrLoading/chunks/{GrLoading-CxNgHgNw.js.map → GrLoading-mfyfghxs.js.map} +1 -1
  104. package/dist/components/GrLoading/index.js +2 -2
  105. package/dist/components/GrModal/chunks/{GrModal-gvfvlp7k.js → GrModal-2ALC3kwy.js} +73 -7
  106. package/dist/components/GrModal/chunks/GrModal-2ALC3kwy.js.map +1 -0
  107. package/dist/components/GrModal/index.js +3 -3
  108. package/dist/components/GrNavbar/chunks/{GrNavbar-CxHwBvSG.js → GrNavbar-BH7XiF9q.js} +1 -1
  109. package/dist/components/GrNavbar/chunks/{GrNavbar-CxHwBvSG.js.map → GrNavbar-BH7XiF9q.js.map} +1 -1
  110. package/dist/components/GrNavbar/index.js +2 -2
  111. package/dist/components/GrNumberInput/chunks/{GrNumberInput-ECtFCIKV.js → GrNumberInput-YIWhV85S.js} +1 -1
  112. package/dist/components/GrNumberInput/chunks/{GrNumberInput-ECtFCIKV.js.map → GrNumberInput-YIWhV85S.js.map} +1 -1
  113. package/dist/components/GrNumberInput/index.js +2 -2
  114. package/dist/components/GrPagination/chunks/{GrPagination-dMXZz120.js → GrPagination-cD6rFO9W.js} +2 -2
  115. package/dist/components/GrPagination/chunks/{GrPagination-dMXZz120.js.map → GrPagination-cD6rFO9W.js.map} +1 -1
  116. package/dist/components/GrPagination/index.js +2 -2
  117. package/dist/components/GrProgressBar/chunks/{GrProgressBar-hQQK8cYh.js → GrProgressBar-C2HdYjp4.js} +1 -1
  118. package/dist/components/GrProgressBar/chunks/{GrProgressBar-hQQK8cYh.js.map → GrProgressBar-C2HdYjp4.js.map} +1 -1
  119. package/dist/components/GrProgressBar/index.js +2 -2
  120. package/dist/components/GrPromptDialog/chunks/{GrPromptDialog-CfKf4tPx.js → GrPromptDialog-23x2nZvv.js} +54 -28
  121. package/dist/components/GrPromptDialog/chunks/GrPromptDialog-23x2nZvv.js.map +1 -0
  122. package/dist/components/GrPromptDialog/index.js +2 -2
  123. package/dist/components/GrRadio/chunks/{GrRadio-CQ3w3Bj6.js → GrRadio-IFU9Hiu2.js} +1 -1
  124. package/dist/components/GrRadio/chunks/{GrRadio-CQ3w3Bj6.js.map → GrRadio-IFU9Hiu2.js.map} +1 -1
  125. package/dist/components/GrRadio/index.js +2 -2
  126. package/dist/components/GrRadioGroup/chunks/{GrRadioGroup-DAaVzlPx.js → GrRadioGroup-C8IcJuuF.js} +1 -1
  127. package/dist/components/GrRadioGroup/chunks/{GrRadioGroup-DAaVzlPx.js.map → GrRadioGroup-C8IcJuuF.js.map} +1 -1
  128. package/dist/components/GrRadioGroup/index.js +2 -2
  129. package/dist/components/GrResponseErrorBanner/chunks/GrResponseErrorBanner-BMvXREcv.js +221 -0
  130. package/dist/components/GrResponseErrorBanner/chunks/GrResponseErrorBanner-BMvXREcv.js.map +1 -0
  131. package/dist/components/GrResponseErrorBanner/chunks/GrResponseErrorBanner-CzdTh4gd.js +782 -0
  132. package/dist/components/GrResponseErrorBanner/chunks/GrResponseErrorBanner-CzdTh4gd.js.map +1 -0
  133. package/dist/components/GrResponseErrorBanner/index.js +3 -0
  134. package/dist/components/GrSegmented/chunks/{GrSegmented-BPl1koHc.js → GrSegmented-BRmwBsEG.js} +1 -1
  135. package/dist/components/GrSegmented/chunks/{GrSegmented-BPl1koHc.js.map → GrSegmented-BRmwBsEG.js.map} +1 -1
  136. package/dist/components/GrSegmented/index.js +2 -2
  137. package/dist/components/GrSelect/chunks/{GrSelect-C3NAfTqL.js → GrSelect-W9lbAjRZ.js} +2 -2
  138. package/dist/components/GrSelect/chunks/{GrSelect-C3NAfTqL.js.map → GrSelect-W9lbAjRZ.js.map} +1 -1
  139. package/dist/components/GrSelect/index.js +2 -2
  140. package/dist/components/GrSidebar/chunks/{GrSidebar-DVucgcfV.js.map → GrSidebar-BpBtAGBs.js.map} +1 -1
  141. package/dist/components/GrSidebar/index.js +2 -2
  142. package/dist/components/GrSkeleton/chunks/{GrSkeleton-CDTvCSoH.js.map → GrSkeleton-URyMkBqI.js.map} +1 -1
  143. package/dist/components/GrSkeleton/index.js +2 -2
  144. package/dist/components/GrSwitch/chunks/{GrSwitch-Bnamgqb2.js → GrSwitch-29h0QhMO.js} +1 -1
  145. package/dist/components/GrSwitch/chunks/{GrSwitch-Bnamgqb2.js.map → GrSwitch-29h0QhMO.js.map} +1 -1
  146. package/dist/components/GrSwitch/index.js +2 -2
  147. package/dist/components/GrTable/chunks/{GrTable-CyQ9uw8A.js.map → GrTable-dTWUxzRm.js.map} +1 -1
  148. package/dist/components/GrTable/index.js +2 -2
  149. package/dist/components/GrTabs/chunks/{GrTabs-CiGmcmvm.js.map → GrTabs-D3ntDdtg.js.map} +1 -1
  150. package/dist/components/GrTabs/index.js +2 -2
  151. package/dist/components/GrTextarea/chunks/{GrTextarea-VBSc6A7D.js → GrTextarea-Cv6r2GuC.js} +1 -1
  152. package/dist/components/GrTextarea/chunks/{GrTextarea-VBSc6A7D.js.map → GrTextarea-Cv6r2GuC.js.map} +1 -1
  153. package/dist/components/GrTextarea/index.js +2 -2
  154. package/dist/components/GrToaster/chunks/{GrToaster-BGNNmnr9.js → GrToaster-DluJmR5D.js} +1 -1
  155. package/dist/components/GrToaster/chunks/{GrToaster-BGNNmnr9.js.map → GrToaster-DluJmR5D.js.map} +1 -1
  156. package/dist/components/GrToaster/index.js +2 -2
  157. package/dist/components/GrTooltip/chunks/{GrTooltip-CrV1gI_c.js.map → GrTooltip-B7I1AVIC.js.map} +1 -1
  158. package/dist/components/GrTooltip/index.js +2 -2
  159. package/dist/components/GrTree/chunks/{GrTree-mYa3COxG.js.map → GrTree-B2SMU5Py.js.map} +1 -1
  160. package/dist/components/GrTree/index.js +2 -2
  161. package/dist/components/GrTreeSelect/chunks/{GrTreeSelect-BEdtrjwX.js → GrTreeSelect-C1abr5uH.js} +4 -4
  162. package/dist/components/GrTreeSelect/chunks/{GrTreeSelect-BEdtrjwX.js.map → GrTreeSelect-C1abr5uH.js.map} +1 -1
  163. package/dist/components/GrTreeSelect/index.js +2 -2
  164. package/dist/directives/dropzone.js +1 -1
  165. package/dist/directives/loading.js +1 -1
  166. package/dist/fileValidation/index.js +1 -1
  167. package/dist/granular-provider-node.js +2 -2
  168. package/dist/granular-provider.js +1 -1
  169. package/dist/i18n/all.js +1 -1
  170. package/dist/i18n/index.js +2 -2
  171. package/dist/index.js +474 -1015
  172. package/dist/index.js.map +1 -1
  173. package/dist/types/src/components/GrConfirmDialog/GrConfirmDialog.vue.d.ts +36 -3
  174. package/dist/types/src/components/GrDialogService/GrDialogServiceHost.vue.d.ts +3 -0
  175. package/dist/types/src/components/GrDialogService/config.d.ts +1 -0
  176. package/dist/types/src/components/GrDialogService/index.d.ts +4 -0
  177. package/dist/types/src/components/GrDialogService/store.d.ts +22 -0
  178. package/dist/types/src/components/GrDialogService/types.d.ts +141 -0
  179. package/dist/types/src/components/GrDialogService/useDialogService.d.ts +13 -0
  180. package/dist/types/src/components/GrFileUpload/GrFileUpload.vue.d.ts +3 -3
  181. package/dist/types/src/components/GrFormFile/GrFormFile.vue.d.ts +2 -2
  182. package/dist/types/src/components/GrInput/GrInput.vue.d.ts +2 -2
  183. package/dist/types/src/components/GrInputTag/GrInputTag.vue.d.ts +1 -1
  184. package/dist/types/src/components/GrModal/grModalEscStack.d.ts +30 -0
  185. package/dist/types/src/components/GrNumberInput/GrNumberInput.vue.d.ts +4 -4
  186. package/dist/types/src/components/GrPromptDialog/GrPromptDialog.vue.d.ts +42 -3
  187. package/dist/types/src/components/GrResponseErrorBanner/GrUploadErrorBanner.vue.d.ts +1 -1
  188. package/dist/types/src/components/GrResponseErrorBanner/index.d.ts +2 -2
  189. package/dist/types/src/components/GrResponseErrorBanner/parsers/createResponseErrorClassifier.d.ts +27 -0
  190. package/dist/types/src/components/GrResponseErrorBanner/parsers/index.d.ts +2 -2
  191. package/dist/types/src/components/GrSelect/GrSelect.vue.d.ts +1 -1
  192. package/dist/types/src/components/GrTextarea/GrTextarea.vue.d.ts +2 -2
  193. package/dist/types/src/components/GrToaster/GrToaster.vue.d.ts +1 -1
  194. package/dist/types/src/index.d.ts +1 -0
  195. package/package.json +5 -1
  196. package/dist/chunks/arrow-up-DNXrMoAI.js.map +0 -1
  197. package/dist/chunks/config-C0b_3LJV.js.map +0 -1
  198. package/dist/chunks/config-C4AlNm912.js.map +0 -1
  199. package/dist/chunks/config-CxCAfXZ1.js.map +0 -1
  200. package/dist/chunks/config-DDEWvph-2.js.map +0 -1
  201. package/dist/chunks/config-DDLoUczC.js.map +0 -1
  202. package/dist/chunks/config-DK2NpdyX2.js.map +0 -1
  203. package/dist/chunks/config-DQOSlWvp.js.map +0 -1
  204. package/dist/chunks/config-DnsISjD8.js.map +0 -1
  205. package/dist/chunks/config-DxqMXzNV2.js.map +0 -1
  206. package/dist/chunks/config-DxqpV-KM.js.map +0 -1
  207. package/dist/chunks/config-iDTkWUdh2.js.map +0 -1
  208. package/dist/chunks/config-rxFL-6yF2.js.map +0 -1
  209. package/dist/chunks/safelist-BF822K15.js.map +0 -1
  210. package/dist/components/GrConfirmDialog/chunks/GrConfirmDialog-DE-d77Us.js.map +0 -1
  211. package/dist/components/GrFileUpload/chunks/GrFileUpload-DYRERhI2.js.map +0 -1
  212. package/dist/components/GrModal/chunks/GrModal-gvfvlp7k.js.map +0 -1
  213. package/dist/components/GrPromptDialog/chunks/GrPromptDialog-CfKf4tPx.js.map +0 -1
  214. /package/dist/chunks/{adapter-CRyH4YC8.js → adapter-BqqjEZGU.js} +0 -0
  215. /package/dist/chunks/{arrow-up-DNXrMoAI.js → arrow-up-DZdIrpaF.js} +0 -0
  216. /package/dist/chunks/{config-C0b_3LJV.js → config-72sW9Bag2.js} +0 -0
  217. /package/dist/chunks/{config-B8rC_K97.js → config-B1kFmhpM.js} +0 -0
  218. /package/dist/chunks/{config-BhvNm4Pp.js → config-B2YTEe_h.js} +0 -0
  219. /package/dist/chunks/{config-C0rHS1-l.js → config-BOdu-O_B.js} +0 -0
  220. /package/dist/chunks/{config-D27BL0H9.js → config-BU0olrvr.js} +0 -0
  221. /package/dist/chunks/{config-DxqMXzNV2.js → config-B_nSBc7W.js} +0 -0
  222. /package/dist/chunks/{config-DbqFk-IW.js → config-BbKroFtR.js} +0 -0
  223. /package/dist/chunks/{config-DQOSlWvp.js → config-Bcf-8XlK2.js} +0 -0
  224. /package/dist/chunks/{config-iDTkWUdh2.js → config-BduXEXjt.js} +0 -0
  225. /package/dist/chunks/{config-DnsISjD8.js → config-BeQuykDk2.js} +0 -0
  226. /package/dist/chunks/{config-Dusr9jcE.js → config-BnWSHTEU.js} +0 -0
  227. /package/dist/chunks/{config-DxqpV-KM.js → config-C6zT56Jc2.js} +0 -0
  228. /package/dist/chunks/{config-wo-ncgTH.js → config-CdJpnjDj.js} +0 -0
  229. /package/dist/chunks/{config-CxCAfXZ1.js → config-CetsgpaZ2.js} +0 -0
  230. /package/dist/chunks/{config-D1DI3roo.js → config-Ci9nXGUV.js} +0 -0
  231. /package/dist/chunks/{config-CjEplP6D.js → config-CpMYmvVT.js} +0 -0
  232. /package/dist/chunks/{config-DZAQpfz0.js → config-Cp_XHsze.js} +0 -0
  233. /package/dist/chunks/{config-D98m8iyz.js → config-CvGdaXvH.js} +0 -0
  234. /package/dist/chunks/{config-CtomKf-k.js → config-D4s_QWVP.js} +0 -0
  235. /package/dist/chunks/{config-D32znLtV2.js → config-D6Oe3blW2.js} +0 -0
  236. /package/dist/chunks/{config-CVnluhKO.js → config-DF_RlCIO.js} +0 -0
  237. /package/dist/chunks/{config-C4qAA0Sb.js → config-DSBlHQVa.js} +0 -0
  238. /package/dist/chunks/{config-Mp9DJ9Mq2.js → config-DaHI5bD_2.js} +0 -0
  239. /package/dist/chunks/{config-3SftO0uG.js → config-Dcb7xK-C.js} +0 -0
  240. /package/dist/chunks/{config-DDEWvph-2.js → config-DmjwIqx1.js} +0 -0
  241. /package/dist/chunks/{config-D6Af6WZw.js → config-DoBk_CzG.js} +0 -0
  242. /package/dist/chunks/{config-DDLoUczC.js → config-Dzd6BzIN2.js} +0 -0
  243. /package/dist/chunks/{config-Db4BEG8Y.js → config-O1_FTqD3.js} +0 -0
  244. /package/dist/chunks/{config-rxFL-6yF2.js → config-_3De4HFf.js} +0 -0
  245. /package/dist/chunks/{config-DudL02ag.js → config-iuMz79Mg.js} +0 -0
  246. /package/dist/chunks/{config-DK2NpdyX2.js → config-vcDVCYXo.js} +0 -0
  247. /package/dist/chunks/{en-QNZhjmSJ.js → en-foQA8imU.js} +0 -0
  248. /package/dist/chunks/{es-C1c5XsIK.js → es-DZFSojYL.js} +0 -0
  249. /package/dist/chunks/{fileValidation-CwJA8Vmn.js → fileValidation-c_iBg74s.js} +0 -0
  250. /package/dist/chunks/{grDropdownStyles-DMp7RrI9.js → grDropdownStyles-B41mVR1H.js} +0 -0
  251. /package/dist/chunks/{grLoadingStyles-CrxZHFL0.js → grLoadingStyles-DmI-SJ3i.js} +0 -0
  252. /package/dist/chunks/{grModalStyles-Dv2NXBKi.js → grModalStyles-DS1Vl6EW.js} +0 -0
  253. /package/dist/chunks/{grSelectStyles-DTAYNzxn.js → grSelectStyles-pUt19VGy.js} +0 -0
  254. /package/dist/chunks/{grStyle-5EMYYctb.js → grStyle-CUaTmpyW.js} +0 -0
  255. /package/dist/chunks/{ru-DcF7ciz0.js → ru-LhkPpPIl.js} +0 -0
  256. /package/dist/chunks/{safelist-BF822K15.js → safelist-_UVzJrgE2.js} +0 -0
  257. /package/dist/components/GrEmptyState/chunks/{GrEmptyState-BLbMJFW-.js → GrEmptyState-Dj2V5GaX.js} +0 -0
  258. /package/dist/components/GrFormField/chunks/{GrFormField-C1oWTT_0.js → GrFormField-U7c_aDPJ.js} +0 -0
  259. /package/dist/components/GrFormSection/chunks/{GrFormSection-CWBk2EUm.js → GrFormSection-DpGhY7MX.js} +0 -0
  260. /package/dist/components/GrImageViewer/chunks/{GrImageViewer-Cpj5zyZQ.js → GrImageViewer-Cn1X-sWS.js} +0 -0
  261. /package/dist/components/GrInput/chunks/{GrInput-CfO2RsM-.js → GrInput-gwFQ1sk4.js} +0 -0
  262. /package/dist/components/GrList/chunks/{GrList-C2GpK56-.js → GrList-D8nM1FuV.js} +0 -0
  263. /package/dist/components/GrSidebar/chunks/{GrSidebar-DVucgcfV.js → GrSidebar-BpBtAGBs.js} +0 -0
  264. /package/dist/components/GrSkeleton/chunks/{GrSkeleton-CDTvCSoH.js → GrSkeleton-URyMkBqI.js} +0 -0
  265. /package/dist/components/GrTable/chunks/{GrTable-CyQ9uw8A.js → GrTable-dTWUxzRm.js} +0 -0
  266. /package/dist/components/GrTabs/chunks/{GrTabs-CiGmcmvm.js → GrTabs-D3ntDdtg.js} +0 -0
  267. /package/dist/components/GrTooltip/chunks/{GrTooltip-CrV1gI_c.js → GrTooltip-B7I1AVIC.js} +0 -0
  268. /package/dist/components/GrTree/chunks/{GrTree-mYa3COxG.js → GrTree-B2SMU5Py.js} +0 -0
@@ -1,3 +1,3 @@
1
- import { t as GrImageViewer_default } from "./chunks/GrImageViewer-Cpj5zyZQ.js";
2
- import { t as grImageViewerConfig } from "../../chunks/config-D98m8iyz.js";
1
+ import { t as GrImageViewer_default } from "./chunks/GrImageViewer-Cn1X-sWS.js";
2
+ import { t as grImageViewerConfig } from "../../chunks/config-CvGdaXvH.js";
3
3
  export { GrImageViewer_default as GrImageViewer, GrImageViewer_default as default, grImageViewerConfig };
@@ -1 +1 @@
1
- {"version":3,"file":"GrInput-CfO2RsM-.js","names":["$slots","$attrs"],"sources":["../../../../src/components/GrInput/GrInput.vue","../../../../src/components/GrInput/GrInput.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {computed, nextTick, onBeforeUnmount, onMounted, onUpdated, ref, useSlots} from 'vue'\nimport type {InputHTMLAttributes} from 'vue'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nexport type GrInputSize = 'xs' | 'sm' | 'md' | 'lg'\nexport type GrInputTextAlign = 'left' | 'center' | 'right'\n\nconst props = withDefaults(\n defineProps<{\n modelValue: string\n type?: 'text' | 'email' | 'password' | 'number' | 'search'\n placeholder?: string\n autocomplete?: string\n inputmode?: InputHTMLAttributes['inputmode']\n disabled?: boolean\n invalid?: boolean\n state?: 'default' | 'success' | 'warning' | 'danger'\n name?: string\n id?: string\n size?: GrInputSize\n\n textAlign?: GrInputTextAlign\n\n prefixMinWidth?: string\n prefixMaxWidth?: string\n suffixMinWidth?: string\n suffixMaxWidth?: string\n }>(),\n {\n type: 'text',\n placeholder: undefined,\n autocomplete: undefined,\n inputmode: undefined,\n disabled: false,\n invalid: false,\n state: 'default',\n name: undefined,\n id: undefined,\n size: 'md',\n\n textAlign: 'left',\n\n prefixMinWidth: undefined,\n prefixMaxWidth: undefined,\n suffixMinWidth: undefined,\n suffixMaxWidth: undefined,\n },\n)\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string): void\n}>()\n\nconst inputEl = ref<HTMLInputElement | null>(null)\n\nfunction focus(): void {\n inputEl.value?.focus()\n}\n\ndefineExpose({\n focus,\n})\n\nconst slots = useSlots()\n\nconst hasPrefix = computed(() => Boolean(slots.prefix))\nconst hasSuffix = computed(() => Boolean(slots.suffix))\n\nconst defaultAddonMinWidth = computed(() => {\n const map: Record<NonNullable<typeof props.size>, string> = {\n xs: '2rem', // w-8\n sm: '2.25rem', // w-9\n md: '2.5rem', // w-10\n lg: '3rem', // w-12\n }\n\n return map[props.size]\n})\n\nconst prefixMinWidth = computed(() => props.prefixMinWidth ?? defaultAddonMinWidth.value)\nconst suffixMinWidth = computed(() => props.suffixMinWidth ?? defaultAddonMinWidth.value)\n\nconst prefixEl = ref<HTMLElement | null>(null)\nconst suffixEl = ref<HTMLElement | null>(null)\n\nconst measuredPrefixWidth = ref<string | undefined>(undefined)\nconst measuredSuffixWidth = ref<string | undefined>(undefined)\n\nlet ro: ResizeObserver | null = null\nlet scheduled = false\n\nfunction readWidthPx(el: HTMLElement | null): string | undefined {\n if (!el) return undefined\n\n const width = Math.ceil(el.getBoundingClientRect().width || 0)\n // jsdom often reports 0; don't overwrite fallback minWidth in that case.\n if (width <= 0) return undefined\n\n return `${width}px`\n}\n\nfunction measure(): void {\n measuredPrefixWidth.value = hasPrefix.value ? readWidthPx(prefixEl.value) : undefined\n measuredSuffixWidth.value = hasSuffix.value ? readWidthPx(suffixEl.value) : undefined\n}\n\nfunction refreshObserver(): void {\n if (typeof ResizeObserver === 'undefined') return\n if (!ro) ro = new ResizeObserver(() => measure())\n\n ro.disconnect()\n if (prefixEl.value) ro.observe(prefixEl.value)\n if (suffixEl.value) ro.observe(suffixEl.value)\n}\n\nfunction scheduleMeasure(): void {\n if (scheduled) return\n scheduled = true\n\n void nextTick(() => {\n scheduled = false\n measure()\n refreshObserver()\n })\n}\n\nonMounted(() => scheduleMeasure())\nonUpdated(() => scheduleMeasure())\nonBeforeUnmount(() => ro?.disconnect())\n\nfunction addLen(a: string, b: string): string {\n if (a === '0px') return b\n if (b === '0px') return a\n\n const apx = a.endsWith('px') ? Number(a.slice(0, -2)) : null\n const bpx = b.endsWith('px') ? Number(b.slice(0, -2)) : null\n\n if (apx !== null && Number.isFinite(apx) && bpx !== null && Number.isFinite(bpx)) {\n return `${apx + bpx}px`\n }\n\n return `calc(${a} + ${b})`\n}\n\nconst basePaddingXLen = computed(() => {\n // Must mirror `sizeClass` horizontal padding (px-*) because inline paddings override class paddings.\n const map: Record<NonNullable<typeof props.size>, string> = {\n xs: '10px', // px-2.5\n sm: '12px', // px-3\n md: '12px', // px-3\n lg: '16px', // px-4\n }\n\n return map[props.size]\n})\n\nconst inputStyle = computed(() => {\n const leftReserved = hasPrefix.value ? measuredPrefixWidth.value ?? prefixMinWidth.value : '0px'\n const rightReserved = hasSuffix.value ? measuredSuffixWidth.value ?? suffixMinWidth.value : '0px'\n\n // Keep the same visual text padding as without addons (px-*), but add it on top of reserved space.\n const left = hasPrefix.value ? addLen(leftReserved, basePaddingXLen.value) : undefined\n const right = hasSuffix.value ? addLen(rightReserved, basePaddingXLen.value) : undefined\n\n return {\n paddingLeft: left,\n paddingRight: right,\n } as Record<string, string | undefined>\n})\n\nconst prefixStyle = computed(() => {\n return {\n minWidth: prefixMinWidth.value,\n maxWidth: props.prefixMaxWidth,\n } as Record<string, string | undefined>\n})\n\nconst suffixStyle = computed(() => {\n return {\n minWidth: suffixMinWidth.value,\n maxWidth: props.suffixMaxWidth,\n } as Record<string, string | undefined>\n})\n\nconst sizeClass = computed(() => {\n const map: Record<NonNullable<typeof props.size>, string> = {\n xs: 'h-7 px-2.5 text-[12px]',\n sm: 'h-8 px-3 text-[13px]',\n md: 'h-10 px-3 text-[14px]',\n lg: 'h-11 px-4 text-[16px]',\n }\n\n return map[props.size]\n})\n\nconst textAlignClass = computed(() => {\n const map: Record<NonNullable<typeof props.textAlign>, string> = {\n left: 'text-left',\n center: 'text-center',\n right: 'text-right',\n }\n\n return map[props.textAlign]\n})\n\nconst className = computed(() => {\n const state = props.state\n\n const borderByState: Record<typeof state, string> = {\n default: 'border-[var(--brd)]',\n success: 'border-[var(--ds-success)] focus-visible:ring-[var(--ds-success)]',\n warning: 'border-[var(--ds-warning)] focus-visible:ring-[var(--ds-warning)]',\n danger: 'border-[var(--ds-danger)] focus-visible:ring-[var(--ds-danger)]',\n }\n\n return [\n sizeClass.value,\n textAlignClass.value,\n props.invalid ? borderByState.danger : borderByState[state],\n ].join(' ')\n})\n\nfunction onInput(e: Event): void {\n emit('update:modelValue', (e.target as HTMLInputElement).value)\n}\n</script>\n\n<template>\n <div class=\"relative w-full\">\n <div\n v-if=\"$slots.prefix\"\n ref=\"prefixEl\"\n data-testid=\"ds-input-prefix\"\n class=\"absolute inset-y-0 left-0 flex items-center justify-center border-r border-[var(--brd)] px-2 text-[var(--muted-fg)] pointer-events-none select-none truncate\"\n :style=\"prefixStyle\"\n aria-hidden=\"true\"\n >\n <slot name=\"prefix\" />\n </div>\n\n <input\n :id=\"props.id\"\n ref=\"inputEl\"\n v-bind=\"$attrs\"\n :name=\"props.name\"\n :type=\"props.type\"\n :inputmode=\"props.inputmode\"\n :autocomplete=\"props.autocomplete\"\n :placeholder=\"props.placeholder\"\n :disabled=\"props.disabled\"\n :value=\"props.modelValue\"\n :aria-invalid=\"props.invalid ? 'true' : undefined\"\n class=\"w-full rounded-md border bg-[var(--bg)] text-[var(--fg)] placeholder:text-[var(--muted-fg)] focus:placeholder:text-transparent 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\"\n :style=\"inputStyle\"\n @input=\"onInput\"\n >\n\n <div\n v-if=\"$slots.suffix\"\n ref=\"suffixEl\"\n data-testid=\"ds-input-suffix\"\n class=\"absolute inset-y-0 right-0 flex items-center justify-center border-l border-[var(--brd)] px-2 text-[var(--muted-fg)] pointer-events-none select-none truncate\"\n :style=\"suffixStyle\"\n aria-hidden=\"true\"\n >\n <slot name=\"suffix\" />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport {computed, nextTick, onBeforeUnmount, onMounted, onUpdated, ref, useSlots} from 'vue'\nimport type {InputHTMLAttributes} from 'vue'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nexport type GrInputSize = 'xs' | 'sm' | 'md' | 'lg'\nexport type GrInputTextAlign = 'left' | 'center' | 'right'\n\nconst props = withDefaults(\n defineProps<{\n modelValue: string\n type?: 'text' | 'email' | 'password' | 'number' | 'search'\n placeholder?: string\n autocomplete?: string\n inputmode?: InputHTMLAttributes['inputmode']\n disabled?: boolean\n invalid?: boolean\n state?: 'default' | 'success' | 'warning' | 'danger'\n name?: string\n id?: string\n size?: GrInputSize\n\n textAlign?: GrInputTextAlign\n\n prefixMinWidth?: string\n prefixMaxWidth?: string\n suffixMinWidth?: string\n suffixMaxWidth?: string\n }>(),\n {\n type: 'text',\n placeholder: undefined,\n autocomplete: undefined,\n inputmode: undefined,\n disabled: false,\n invalid: false,\n state: 'default',\n name: undefined,\n id: undefined,\n size: 'md',\n\n textAlign: 'left',\n\n prefixMinWidth: undefined,\n prefixMaxWidth: undefined,\n suffixMinWidth: undefined,\n suffixMaxWidth: undefined,\n },\n)\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string): void\n}>()\n\nconst inputEl = ref<HTMLInputElement | null>(null)\n\nfunction focus(): void {\n inputEl.value?.focus()\n}\n\ndefineExpose({\n focus,\n})\n\nconst slots = useSlots()\n\nconst hasPrefix = computed(() => Boolean(slots.prefix))\nconst hasSuffix = computed(() => Boolean(slots.suffix))\n\nconst defaultAddonMinWidth = computed(() => {\n const map: Record<NonNullable<typeof props.size>, string> = {\n xs: '2rem', // w-8\n sm: '2.25rem', // w-9\n md: '2.5rem', // w-10\n lg: '3rem', // w-12\n }\n\n return map[props.size]\n})\n\nconst prefixMinWidth = computed(() => props.prefixMinWidth ?? defaultAddonMinWidth.value)\nconst suffixMinWidth = computed(() => props.suffixMinWidth ?? defaultAddonMinWidth.value)\n\nconst prefixEl = ref<HTMLElement | null>(null)\nconst suffixEl = ref<HTMLElement | null>(null)\n\nconst measuredPrefixWidth = ref<string | undefined>(undefined)\nconst measuredSuffixWidth = ref<string | undefined>(undefined)\n\nlet ro: ResizeObserver | null = null\nlet scheduled = false\n\nfunction readWidthPx(el: HTMLElement | null): string | undefined {\n if (!el) return undefined\n\n const width = Math.ceil(el.getBoundingClientRect().width || 0)\n // jsdom often reports 0; don't overwrite fallback minWidth in that case.\n if (width <= 0) return undefined\n\n return `${width}px`\n}\n\nfunction measure(): void {\n measuredPrefixWidth.value = hasPrefix.value ? readWidthPx(prefixEl.value) : undefined\n measuredSuffixWidth.value = hasSuffix.value ? readWidthPx(suffixEl.value) : undefined\n}\n\nfunction refreshObserver(): void {\n if (typeof ResizeObserver === 'undefined') return\n if (!ro) ro = new ResizeObserver(() => measure())\n\n ro.disconnect()\n if (prefixEl.value) ro.observe(prefixEl.value)\n if (suffixEl.value) ro.observe(suffixEl.value)\n}\n\nfunction scheduleMeasure(): void {\n if (scheduled) return\n scheduled = true\n\n void nextTick(() => {\n scheduled = false\n measure()\n refreshObserver()\n })\n}\n\nonMounted(() => scheduleMeasure())\nonUpdated(() => scheduleMeasure())\nonBeforeUnmount(() => ro?.disconnect())\n\nfunction addLen(a: string, b: string): string {\n if (a === '0px') return b\n if (b === '0px') return a\n\n const apx = a.endsWith('px') ? Number(a.slice(0, -2)) : null\n const bpx = b.endsWith('px') ? Number(b.slice(0, -2)) : null\n\n if (apx !== null && Number.isFinite(apx) && bpx !== null && Number.isFinite(bpx)) {\n return `${apx + bpx}px`\n }\n\n return `calc(${a} + ${b})`\n}\n\nconst basePaddingXLen = computed(() => {\n // Must mirror `sizeClass` horizontal padding (px-*) because inline paddings override class paddings.\n const map: Record<NonNullable<typeof props.size>, string> = {\n xs: '10px', // px-2.5\n sm: '12px', // px-3\n md: '12px', // px-3\n lg: '16px', // px-4\n }\n\n return map[props.size]\n})\n\nconst inputStyle = computed(() => {\n const leftReserved = hasPrefix.value ? measuredPrefixWidth.value ?? prefixMinWidth.value : '0px'\n const rightReserved = hasSuffix.value ? measuredSuffixWidth.value ?? suffixMinWidth.value : '0px'\n\n // Keep the same visual text padding as without addons (px-*), but add it on top of reserved space.\n const left = hasPrefix.value ? addLen(leftReserved, basePaddingXLen.value) : undefined\n const right = hasSuffix.value ? addLen(rightReserved, basePaddingXLen.value) : undefined\n\n return {\n paddingLeft: left,\n paddingRight: right,\n } as Record<string, string | undefined>\n})\n\nconst prefixStyle = computed(() => {\n return {\n minWidth: prefixMinWidth.value,\n maxWidth: props.prefixMaxWidth,\n } as Record<string, string | undefined>\n})\n\nconst suffixStyle = computed(() => {\n return {\n minWidth: suffixMinWidth.value,\n maxWidth: props.suffixMaxWidth,\n } as Record<string, string | undefined>\n})\n\nconst sizeClass = computed(() => {\n const map: Record<NonNullable<typeof props.size>, string> = {\n xs: 'h-7 px-2.5 text-[12px]',\n sm: 'h-8 px-3 text-[13px]',\n md: 'h-10 px-3 text-[14px]',\n lg: 'h-11 px-4 text-[16px]',\n }\n\n return map[props.size]\n})\n\nconst textAlignClass = computed(() => {\n const map: Record<NonNullable<typeof props.textAlign>, string> = {\n left: 'text-left',\n center: 'text-center',\n right: 'text-right',\n }\n\n return map[props.textAlign]\n})\n\nconst className = computed(() => {\n const state = props.state\n\n const borderByState: Record<typeof state, string> = {\n default: 'border-[var(--brd)]',\n success: 'border-[var(--ds-success)] focus-visible:ring-[var(--ds-success)]',\n warning: 'border-[var(--ds-warning)] focus-visible:ring-[var(--ds-warning)]',\n danger: 'border-[var(--ds-danger)] focus-visible:ring-[var(--ds-danger)]',\n }\n\n return [\n sizeClass.value,\n textAlignClass.value,\n props.invalid ? borderByState.danger : borderByState[state],\n ].join(' ')\n})\n\nfunction onInput(e: Event): void {\n emit('update:modelValue', (e.target as HTMLInputElement).value)\n}\n</script>\n\n<template>\n <div class=\"relative w-full\">\n <div\n v-if=\"$slots.prefix\"\n ref=\"prefixEl\"\n data-testid=\"ds-input-prefix\"\n class=\"absolute inset-y-0 left-0 flex items-center justify-center border-r border-[var(--brd)] px-2 text-[var(--muted-fg)] pointer-events-none select-none truncate\"\n :style=\"prefixStyle\"\n aria-hidden=\"true\"\n >\n <slot name=\"prefix\" />\n </div>\n\n <input\n :id=\"props.id\"\n ref=\"inputEl\"\n v-bind=\"$attrs\"\n :name=\"props.name\"\n :type=\"props.type\"\n :inputmode=\"props.inputmode\"\n :autocomplete=\"props.autocomplete\"\n :placeholder=\"props.placeholder\"\n :disabled=\"props.disabled\"\n :value=\"props.modelValue\"\n :aria-invalid=\"props.invalid ? 'true' : undefined\"\n class=\"w-full rounded-md border bg-[var(--bg)] text-[var(--fg)] placeholder:text-[var(--muted-fg)] focus:placeholder:text-transparent 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\"\n :style=\"inputStyle\"\n @input=\"onInput\"\n >\n\n <div\n v-if=\"$slots.suffix\"\n ref=\"suffixEl\"\n data-testid=\"ds-input-suffix\"\n class=\"absolute inset-y-0 right-0 flex items-center justify-center border-l border-[var(--brd)] px-2 text-[var(--muted-fg)] pointer-events-none select-none truncate\"\n :style=\"suffixStyle\"\n aria-hidden=\"true\"\n >\n <slot name=\"suffix\" />\n </div>\n </div>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"GrInput-gwFQ1sk4.js","names":["$slots","$attrs"],"sources":["../../../../src/components/GrInput/GrInput.vue","../../../../src/components/GrInput/GrInput.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {computed, nextTick, onBeforeUnmount, onMounted, onUpdated, ref, useSlots} from 'vue'\nimport type {InputHTMLAttributes} from 'vue'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nexport type GrInputSize = 'xs' | 'sm' | 'md' | 'lg'\nexport type GrInputTextAlign = 'left' | 'center' | 'right'\n\nconst props = withDefaults(\n defineProps<{\n modelValue: string\n type?: 'text' | 'email' | 'password' | 'number' | 'search'\n placeholder?: string\n autocomplete?: string\n inputmode?: InputHTMLAttributes['inputmode']\n disabled?: boolean\n invalid?: boolean\n state?: 'default' | 'success' | 'warning' | 'danger'\n name?: string\n id?: string\n size?: GrInputSize\n\n textAlign?: GrInputTextAlign\n\n prefixMinWidth?: string\n prefixMaxWidth?: string\n suffixMinWidth?: string\n suffixMaxWidth?: string\n }>(),\n {\n type: 'text',\n placeholder: undefined,\n autocomplete: undefined,\n inputmode: undefined,\n disabled: false,\n invalid: false,\n state: 'default',\n name: undefined,\n id: undefined,\n size: 'md',\n\n textAlign: 'left',\n\n prefixMinWidth: undefined,\n prefixMaxWidth: undefined,\n suffixMinWidth: undefined,\n suffixMaxWidth: undefined,\n },\n)\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string): void\n}>()\n\nconst inputEl = ref<HTMLInputElement | null>(null)\n\nfunction focus(): void {\n inputEl.value?.focus()\n}\n\ndefineExpose({\n focus,\n})\n\nconst slots = useSlots()\n\nconst hasPrefix = computed(() => Boolean(slots.prefix))\nconst hasSuffix = computed(() => Boolean(slots.suffix))\n\nconst defaultAddonMinWidth = computed(() => {\n const map: Record<NonNullable<typeof props.size>, string> = {\n xs: '2rem', // w-8\n sm: '2.25rem', // w-9\n md: '2.5rem', // w-10\n lg: '3rem', // w-12\n }\n\n return map[props.size]\n})\n\nconst prefixMinWidth = computed(() => props.prefixMinWidth ?? defaultAddonMinWidth.value)\nconst suffixMinWidth = computed(() => props.suffixMinWidth ?? defaultAddonMinWidth.value)\n\nconst prefixEl = ref<HTMLElement | null>(null)\nconst suffixEl = ref<HTMLElement | null>(null)\n\nconst measuredPrefixWidth = ref<string | undefined>(undefined)\nconst measuredSuffixWidth = ref<string | undefined>(undefined)\n\nlet ro: ResizeObserver | null = null\nlet scheduled = false\n\nfunction readWidthPx(el: HTMLElement | null): string | undefined {\n if (!el) return undefined\n\n const width = Math.ceil(el.getBoundingClientRect().width || 0)\n // jsdom often reports 0; don't overwrite fallback minWidth in that case.\n if (width <= 0) return undefined\n\n return `${width}px`\n}\n\nfunction measure(): void {\n measuredPrefixWidth.value = hasPrefix.value ? readWidthPx(prefixEl.value) : undefined\n measuredSuffixWidth.value = hasSuffix.value ? readWidthPx(suffixEl.value) : undefined\n}\n\nfunction refreshObserver(): void {\n if (typeof ResizeObserver === 'undefined') return\n if (!ro) ro = new ResizeObserver(() => measure())\n\n ro.disconnect()\n if (prefixEl.value) ro.observe(prefixEl.value)\n if (suffixEl.value) ro.observe(suffixEl.value)\n}\n\nfunction scheduleMeasure(): void {\n if (scheduled) return\n scheduled = true\n\n void nextTick(() => {\n scheduled = false\n measure()\n refreshObserver()\n })\n}\n\nonMounted(() => scheduleMeasure())\nonUpdated(() => scheduleMeasure())\nonBeforeUnmount(() => ro?.disconnect())\n\nfunction addLen(a: string, b: string): string {\n if (a === '0px') return b\n if (b === '0px') return a\n\n const apx = a.endsWith('px') ? Number(a.slice(0, -2)) : null\n const bpx = b.endsWith('px') ? Number(b.slice(0, -2)) : null\n\n if (apx !== null && Number.isFinite(apx) && bpx !== null && Number.isFinite(bpx)) {\n return `${apx + bpx}px`\n }\n\n return `calc(${a} + ${b})`\n}\n\nconst basePaddingXLen = computed(() => {\n // Must mirror `sizeClass` horizontal padding (px-*) because inline paddings override class paddings.\n const map: Record<NonNullable<typeof props.size>, string> = {\n xs: '10px', // px-2.5\n sm: '12px', // px-3\n md: '12px', // px-3\n lg: '16px', // px-4\n }\n\n return map[props.size]\n})\n\nconst inputStyle = computed(() => {\n const leftReserved = hasPrefix.value ? measuredPrefixWidth.value ?? prefixMinWidth.value : '0px'\n const rightReserved = hasSuffix.value ? measuredSuffixWidth.value ?? suffixMinWidth.value : '0px'\n\n // Keep the same visual text padding as without addons (px-*), but add it on top of reserved space.\n const left = hasPrefix.value ? addLen(leftReserved, basePaddingXLen.value) : undefined\n const right = hasSuffix.value ? addLen(rightReserved, basePaddingXLen.value) : undefined\n\n return {\n paddingLeft: left,\n paddingRight: right,\n } as Record<string, string | undefined>\n})\n\nconst prefixStyle = computed(() => {\n return {\n minWidth: prefixMinWidth.value,\n maxWidth: props.prefixMaxWidth,\n } as Record<string, string | undefined>\n})\n\nconst suffixStyle = computed(() => {\n return {\n minWidth: suffixMinWidth.value,\n maxWidth: props.suffixMaxWidth,\n } as Record<string, string | undefined>\n})\n\nconst sizeClass = computed(() => {\n const map: Record<NonNullable<typeof props.size>, string> = {\n xs: 'h-7 px-2.5 text-[12px]',\n sm: 'h-8 px-3 text-[13px]',\n md: 'h-10 px-3 text-[14px]',\n lg: 'h-11 px-4 text-[16px]',\n }\n\n return map[props.size]\n})\n\nconst textAlignClass = computed(() => {\n const map: Record<NonNullable<typeof props.textAlign>, string> = {\n left: 'text-left',\n center: 'text-center',\n right: 'text-right',\n }\n\n return map[props.textAlign]\n})\n\nconst className = computed(() => {\n const state = props.state\n\n const borderByState: Record<typeof state, string> = {\n default: 'border-[var(--brd)]',\n success: 'border-[var(--ds-success)] focus-visible:ring-[var(--ds-success)]',\n warning: 'border-[var(--ds-warning)] focus-visible:ring-[var(--ds-warning)]',\n danger: 'border-[var(--ds-danger)] focus-visible:ring-[var(--ds-danger)]',\n }\n\n return [\n sizeClass.value,\n textAlignClass.value,\n props.invalid ? borderByState.danger : borderByState[state],\n ].join(' ')\n})\n\nfunction onInput(e: Event): void {\n emit('update:modelValue', (e.target as HTMLInputElement).value)\n}\n</script>\n\n<template>\n <div class=\"relative w-full\">\n <div\n v-if=\"$slots.prefix\"\n ref=\"prefixEl\"\n data-testid=\"ds-input-prefix\"\n class=\"absolute inset-y-0 left-0 flex items-center justify-center border-r border-[var(--brd)] px-2 text-[var(--muted-fg)] pointer-events-none select-none truncate\"\n :style=\"prefixStyle\"\n aria-hidden=\"true\"\n >\n <slot name=\"prefix\" />\n </div>\n\n <input\n :id=\"props.id\"\n ref=\"inputEl\"\n v-bind=\"$attrs\"\n :name=\"props.name\"\n :type=\"props.type\"\n :inputmode=\"props.inputmode\"\n :autocomplete=\"props.autocomplete\"\n :placeholder=\"props.placeholder\"\n :disabled=\"props.disabled\"\n :value=\"props.modelValue\"\n :aria-invalid=\"props.invalid ? 'true' : undefined\"\n class=\"w-full rounded-md border bg-[var(--bg)] text-[var(--fg)] placeholder:text-[var(--muted-fg)] focus:placeholder:text-transparent 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\"\n :style=\"inputStyle\"\n @input=\"onInput\"\n >\n\n <div\n v-if=\"$slots.suffix\"\n ref=\"suffixEl\"\n data-testid=\"ds-input-suffix\"\n class=\"absolute inset-y-0 right-0 flex items-center justify-center border-l border-[var(--brd)] px-2 text-[var(--muted-fg)] pointer-events-none select-none truncate\"\n :style=\"suffixStyle\"\n aria-hidden=\"true\"\n >\n <slot name=\"suffix\" />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport {computed, nextTick, onBeforeUnmount, onMounted, onUpdated, ref, useSlots} from 'vue'\nimport type {InputHTMLAttributes} from 'vue'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nexport type GrInputSize = 'xs' | 'sm' | 'md' | 'lg'\nexport type GrInputTextAlign = 'left' | 'center' | 'right'\n\nconst props = withDefaults(\n defineProps<{\n modelValue: string\n type?: 'text' | 'email' | 'password' | 'number' | 'search'\n placeholder?: string\n autocomplete?: string\n inputmode?: InputHTMLAttributes['inputmode']\n disabled?: boolean\n invalid?: boolean\n state?: 'default' | 'success' | 'warning' | 'danger'\n name?: string\n id?: string\n size?: GrInputSize\n\n textAlign?: GrInputTextAlign\n\n prefixMinWidth?: string\n prefixMaxWidth?: string\n suffixMinWidth?: string\n suffixMaxWidth?: string\n }>(),\n {\n type: 'text',\n placeholder: undefined,\n autocomplete: undefined,\n inputmode: undefined,\n disabled: false,\n invalid: false,\n state: 'default',\n name: undefined,\n id: undefined,\n size: 'md',\n\n textAlign: 'left',\n\n prefixMinWidth: undefined,\n prefixMaxWidth: undefined,\n suffixMinWidth: undefined,\n suffixMaxWidth: undefined,\n },\n)\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string): void\n}>()\n\nconst inputEl = ref<HTMLInputElement | null>(null)\n\nfunction focus(): void {\n inputEl.value?.focus()\n}\n\ndefineExpose({\n focus,\n})\n\nconst slots = useSlots()\n\nconst hasPrefix = computed(() => Boolean(slots.prefix))\nconst hasSuffix = computed(() => Boolean(slots.suffix))\n\nconst defaultAddonMinWidth = computed(() => {\n const map: Record<NonNullable<typeof props.size>, string> = {\n xs: '2rem', // w-8\n sm: '2.25rem', // w-9\n md: '2.5rem', // w-10\n lg: '3rem', // w-12\n }\n\n return map[props.size]\n})\n\nconst prefixMinWidth = computed(() => props.prefixMinWidth ?? defaultAddonMinWidth.value)\nconst suffixMinWidth = computed(() => props.suffixMinWidth ?? defaultAddonMinWidth.value)\n\nconst prefixEl = ref<HTMLElement | null>(null)\nconst suffixEl = ref<HTMLElement | null>(null)\n\nconst measuredPrefixWidth = ref<string | undefined>(undefined)\nconst measuredSuffixWidth = ref<string | undefined>(undefined)\n\nlet ro: ResizeObserver | null = null\nlet scheduled = false\n\nfunction readWidthPx(el: HTMLElement | null): string | undefined {\n if (!el) return undefined\n\n const width = Math.ceil(el.getBoundingClientRect().width || 0)\n // jsdom often reports 0; don't overwrite fallback minWidth in that case.\n if (width <= 0) return undefined\n\n return `${width}px`\n}\n\nfunction measure(): void {\n measuredPrefixWidth.value = hasPrefix.value ? readWidthPx(prefixEl.value) : undefined\n measuredSuffixWidth.value = hasSuffix.value ? readWidthPx(suffixEl.value) : undefined\n}\n\nfunction refreshObserver(): void {\n if (typeof ResizeObserver === 'undefined') return\n if (!ro) ro = new ResizeObserver(() => measure())\n\n ro.disconnect()\n if (prefixEl.value) ro.observe(prefixEl.value)\n if (suffixEl.value) ro.observe(suffixEl.value)\n}\n\nfunction scheduleMeasure(): void {\n if (scheduled) return\n scheduled = true\n\n void nextTick(() => {\n scheduled = false\n measure()\n refreshObserver()\n })\n}\n\nonMounted(() => scheduleMeasure())\nonUpdated(() => scheduleMeasure())\nonBeforeUnmount(() => ro?.disconnect())\n\nfunction addLen(a: string, b: string): string {\n if (a === '0px') return b\n if (b === '0px') return a\n\n const apx = a.endsWith('px') ? Number(a.slice(0, -2)) : null\n const bpx = b.endsWith('px') ? Number(b.slice(0, -2)) : null\n\n if (apx !== null && Number.isFinite(apx) && bpx !== null && Number.isFinite(bpx)) {\n return `${apx + bpx}px`\n }\n\n return `calc(${a} + ${b})`\n}\n\nconst basePaddingXLen = computed(() => {\n // Must mirror `sizeClass` horizontal padding (px-*) because inline paddings override class paddings.\n const map: Record<NonNullable<typeof props.size>, string> = {\n xs: '10px', // px-2.5\n sm: '12px', // px-3\n md: '12px', // px-3\n lg: '16px', // px-4\n }\n\n return map[props.size]\n})\n\nconst inputStyle = computed(() => {\n const leftReserved = hasPrefix.value ? measuredPrefixWidth.value ?? prefixMinWidth.value : '0px'\n const rightReserved = hasSuffix.value ? measuredSuffixWidth.value ?? suffixMinWidth.value : '0px'\n\n // Keep the same visual text padding as without addons (px-*), but add it on top of reserved space.\n const left = hasPrefix.value ? addLen(leftReserved, basePaddingXLen.value) : undefined\n const right = hasSuffix.value ? addLen(rightReserved, basePaddingXLen.value) : undefined\n\n return {\n paddingLeft: left,\n paddingRight: right,\n } as Record<string, string | undefined>\n})\n\nconst prefixStyle = computed(() => {\n return {\n minWidth: prefixMinWidth.value,\n maxWidth: props.prefixMaxWidth,\n } as Record<string, string | undefined>\n})\n\nconst suffixStyle = computed(() => {\n return {\n minWidth: suffixMinWidth.value,\n maxWidth: props.suffixMaxWidth,\n } as Record<string, string | undefined>\n})\n\nconst sizeClass = computed(() => {\n const map: Record<NonNullable<typeof props.size>, string> = {\n xs: 'h-7 px-2.5 text-[12px]',\n sm: 'h-8 px-3 text-[13px]',\n md: 'h-10 px-3 text-[14px]',\n lg: 'h-11 px-4 text-[16px]',\n }\n\n return map[props.size]\n})\n\nconst textAlignClass = computed(() => {\n const map: Record<NonNullable<typeof props.textAlign>, string> = {\n left: 'text-left',\n center: 'text-center',\n right: 'text-right',\n }\n\n return map[props.textAlign]\n})\n\nconst className = computed(() => {\n const state = props.state\n\n const borderByState: Record<typeof state, string> = {\n default: 'border-[var(--brd)]',\n success: 'border-[var(--ds-success)] focus-visible:ring-[var(--ds-success)]',\n warning: 'border-[var(--ds-warning)] focus-visible:ring-[var(--ds-warning)]',\n danger: 'border-[var(--ds-danger)] focus-visible:ring-[var(--ds-danger)]',\n }\n\n return [\n sizeClass.value,\n textAlignClass.value,\n props.invalid ? borderByState.danger : borderByState[state],\n ].join(' ')\n})\n\nfunction onInput(e: Event): void {\n emit('update:modelValue', (e.target as HTMLInputElement).value)\n}\n</script>\n\n<template>\n <div class=\"relative w-full\">\n <div\n v-if=\"$slots.prefix\"\n ref=\"prefixEl\"\n data-testid=\"ds-input-prefix\"\n class=\"absolute inset-y-0 left-0 flex items-center justify-center border-r border-[var(--brd)] px-2 text-[var(--muted-fg)] pointer-events-none select-none truncate\"\n :style=\"prefixStyle\"\n aria-hidden=\"true\"\n >\n <slot name=\"prefix\" />\n </div>\n\n <input\n :id=\"props.id\"\n ref=\"inputEl\"\n v-bind=\"$attrs\"\n :name=\"props.name\"\n :type=\"props.type\"\n :inputmode=\"props.inputmode\"\n :autocomplete=\"props.autocomplete\"\n :placeholder=\"props.placeholder\"\n :disabled=\"props.disabled\"\n :value=\"props.modelValue\"\n :aria-invalid=\"props.invalid ? 'true' : undefined\"\n class=\"w-full rounded-md border bg-[var(--bg)] text-[var(--fg)] placeholder:text-[var(--muted-fg)] focus:placeholder:text-transparent 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\"\n :style=\"inputStyle\"\n @input=\"onInput\"\n >\n\n <div\n v-if=\"$slots.suffix\"\n ref=\"suffixEl\"\n data-testid=\"ds-input-suffix\"\n class=\"absolute inset-y-0 right-0 flex items-center justify-center border-l border-[var(--brd)] px-2 text-[var(--muted-fg)] pointer-events-none select-none truncate\"\n :style=\"suffixStyle\"\n aria-hidden=\"true\"\n >\n <slot name=\"suffix\" />\n </div>\n </div>\n</template>\n"],"mappings":"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"}
@@ -1,3 +1,3 @@
1
- import { t as GrInput_default } from "./chunks/GrInput-CfO2RsM-.js";
2
- import { n as grInputSafelist, t as grInputConfig } from "../../chunks/config-CtomKf-k.js";
1
+ import { t as GrInput_default } from "./chunks/GrInput-gwFQ1sk4.js";
2
+ import { n as grInputSafelist, t as grInputConfig } from "../../chunks/config-D4s_QWVP.js";
3
3
  export { GrInput_default as GrInput, GrInput_default as default, grInputConfig, grInputSafelist };
@@ -1,7 +1,7 @@
1
1
  import { t as x_default } from "../../../chunks/x-Pa6C2hwi.js";
2
2
  import { t as GrBadge_default } from "../../GrBadge/chunks/GrBadge-Cs_cVfuO.js";
3
3
  import { t as GrIcon_default } from "../../GrIcon/chunks/GrIcon-BV7RBU_0.js";
4
- import { i as grInputTagWrapperClass, r as grInputTagInputClass } from "../../../chunks/config-Dusr9jcE.js";
4
+ import { i as grInputTagWrapperClass, r as grInputTagInputClass } from "../../../chunks/config-BnWSHTEU.js";
5
5
  import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, normalizeClass, openBlock, ref, renderList, renderSlot, toDisplayString, unref, withCtx, withModifiers } from "vue";
6
6
  //#region src/components/GrInputTag/GrInputTag.vue?vue&type=script&setup=true&lang.ts
7
7
  var _hoisted_1 = { class: "truncate max-w-[18rem]" };
@@ -1 +1 @@
1
- {"version":3,"file":"GrInputTag-CeEy0IwD.js","names":[],"sources":["../../../../src/components/GrInputTag/GrInputTag.vue","../../../../src/components/GrInputTag/GrInputTag.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\n\nimport GrBadge from '../GrBadge/GrBadge.vue'\nimport type { GrBadgeRadius, GrBadgeSize, GrBadgeTone } from '../GrBadge'\nimport GrIcon from '../GrIcon/GrIcon.vue'\nimport IconClose from '~icons/lucide/x'\n\nimport {\n grInputTagInputClass,\n grInputTagWrapperClass,\n type GrInputTagSize,\n type GrInputTagState,\n} from './grInputTagStyles'\n\nexport type { GrInputTagSize, GrInputTagState } from './grInputTagStyles'\n\nconst REGEX_SPECIAL_CHAR_RE = /[.*+?^${}()|[\\]\\\\]/g\n\n/**\n * Props for {@link GrInputTag}.\n * Tag-input primitive: renders a set of badges with an inline `<input>` for entering new tags.\n * Splits input by configurable `separators`, supports paste, Enter and Backspace editing.\n */\nexport interface GrInputTagProps {\n modelValue: string[]\n placeholder?: string\n disabled?: boolean\n readonly?: boolean\n invalid?: boolean\n state?: GrInputTagState\n size?: GrInputTagSize\n separators?: string[]\n allowDuplicates?: boolean\n trim?: boolean\n max?: number\n addOnBlur?: boolean\n clearInputOnAdd?: boolean\n tagTone?: GrBadgeTone\n tagDark?: boolean\n tagSize?: GrBadgeSize\n tagRadius?: GrBadgeRadius\n tagClosable?: boolean\n /** i18n-friendly aria-label for the per-tag remove button. */\n removeTagLabel?: string\n}\n\nconst props = withDefaults(\n defineProps<GrInputTagProps>(),\n {\n placeholder: undefined,\n disabled: false,\n readonly: false,\n invalid: false,\n state: 'default',\n size: 'md',\n separators: () => [','],\n allowDuplicates: false,\n trim: true,\n max: undefined,\n addOnBlur: false,\n clearInputOnAdd: true,\n tagTone: 'neutral',\n tagDark: false,\n tagSize: 'md',\n tagRadius: 'round',\n tagClosable: true,\n removeTagLabel: 'Remove tag',\n },\n)\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string[]): void\n (e: 'add', value: string): void\n (e: 'remove', value: string, index: number): void\n}>()\n\nconst inputValue = ref('')\nconst inputEl = ref<HTMLInputElement | null>(null)\n\nfunction focus(): void {\n inputEl.value?.focus()\n}\n\ndefineExpose({ focus })\n\nconst isMaxed = computed(() => props.max !== undefined && props.modelValue.length >= props.max)\nconst canEdit = computed(() => !props.disabled && !props.readonly)\nconst showRemove = computed(() => props.tagClosable && canEdit.value)\n\nfunction escapeRegexChar(ch: string): string {\n return ch.replace(REGEX_SPECIAL_CHAR_RE, '\\\\$&')\n}\n\nconst splitRegex = computed(() => {\n const seps = (props.separators ?? []).filter(Boolean).map(s => s[0]!)\n const uniq = [...new Set([...seps, '\\n', '\\r', '\\t'])]\n const body = uniq.map(escapeRegexChar).join('')\n return new RegExp(`[${body}]+`, 'g')\n})\n\nfunction normalizeTag(raw: string): string {\n return props.trim ? raw.trim() : raw\n}\n\nfunction splitToTags(raw: string): string[] {\n return raw\n .split(splitRegex.value)\n .map(v => normalizeTag(v))\n .filter(Boolean)\n}\n\nfunction addMany(rawTags: string[]): boolean {\n if (!canEdit.value || isMaxed.value)\n return false\n\n const next = props.modelValue.slice()\n let changed = false\n\n for (const raw of rawTags) {\n const tag = normalizeTag(raw)\n if (!tag)\n continue\n\n if (!props.allowDuplicates && next.includes(tag))\n continue\n\n if (props.max !== undefined && next.length >= props.max)\n break\n\n next.push(tag)\n changed = true\n emit('add', tag)\n }\n\n if (!changed)\n return false\n\n emit('update:modelValue', next)\n return true\n}\n\nfunction commitInput(): void {\n if (!canEdit.value || isMaxed.value || !inputValue.value)\n return\n\n const tags = splitToTags(inputValue.value)\n if (!tags.length)\n return\n\n const changed = addMany(tags)\n if (changed && props.clearInputOnAdd)\n inputValue.value = ''\n}\n\nfunction removeAt(index: number): void {\n if (!canEdit.value)\n return\n\n const next = props.modelValue.slice()\n const removed = next[index]\n if (removed === undefined)\n return\n\n next.splice(index, 1)\n emit('update:modelValue', next)\n emit('remove', removed, index)\n}\n\nfunction onInput(e: Event): void {\n inputValue.value = (e.target as HTMLInputElement).value\n}\n\nfunction onKeydown(e: KeyboardEvent): void {\n if (!canEdit.value)\n return\n\n if (e.key === 'Enter') {\n e.preventDefault()\n commitInput()\n return\n }\n\n if ((props.separators ?? []).includes(e.key)) {\n e.preventDefault()\n commitInput()\n return\n }\n\n if (e.key === 'Backspace' && inputValue.value.length === 0 && props.modelValue.length > 0) {\n e.preventDefault()\n removeAt(props.modelValue.length - 1)\n }\n}\n\nfunction onBlur(): void {\n if (props.addOnBlur)\n commitInput()\n}\n\nfunction onPaste(e: ClipboardEvent): void {\n if (!canEdit.value || isMaxed.value)\n return\n\n const pasted = e.clipboardData?.getData('text')\n if (!pasted)\n return\n\n const tags = splitToTags(pasted)\n if (tags.length <= 1)\n return\n\n e.preventDefault()\n addMany(tags)\n}\n\nconst wrapperClassName = computed(() => {\n return grInputTagWrapperClass({\n size: props.size,\n state: props.state,\n invalid: props.invalid,\n disabled: props.disabled,\n })\n})\n\nconst inputClassName = computed(() => {\n return grInputTagInputClass(props.size)\n})\n\nconst placeholderText = computed(() => props.modelValue.length > 0 ? undefined : props.placeholder)\n</script>\n\n<template>\n <div\n data-ds-input-tag\n data-testid=\"ds-input-tag\"\n class=\"w-full flex flex-wrap items-center rounded-md border bg-[var(--bg)] text-[var(--fg)] transition-colors duration-150 focus-within:ring-2 focus-within:ring-[var(--ring)]\"\n :class=\"wrapperClassName\"\n @click=\"focus\"\n >\n <GrBadge\n v-for=\"(tag, i) in modelValue\"\n :key=\"`${tag}-${i}`\"\n :tone=\"tagTone\"\n :dark=\"tagDark\"\n :size=\"tagSize\"\n :radius=\"tagRadius\"\n class=\"gap-1\"\n data-ds-input-tag-item\n data-testid=\"ds-input-tag-item\"\n :data-index=\"i\"\n >\n <slot name=\"tag\" :tag=\"tag\" :index=\"i\" :remove=\"() => removeAt(i)\">\n <span class=\"truncate max-w-[18rem]\">{{ tag }}</span>\n </slot>\n\n <button\n v-if=\"showRemove\"\n type=\"button\"\n class=\"-mr-0.5 inline-flex items-center justify-center rounded-[6px] p-0.5 opacity-70 hover:opacity-100 focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)]\"\n :aria-label=\"removeTagLabel\"\n data-ds-input-tag-remove\n data-testid=\"ds-input-tag-remove\"\n :data-index=\"i\"\n @mousedown.prevent.stop\n @click.stop=\"removeAt(i)\"\n >\n <GrIcon size=\"sm\" aria-hidden=\"true\">\n <IconClose />\n </GrIcon>\n </button>\n </GrBadge>\n\n <input\n ref=\"inputEl\"\n data-ds-input-tag-input\n data-testid=\"ds-input-tag-input\"\n :value=\"inputValue\"\n :disabled=\"disabled || isMaxed\"\n :readonly=\"readonly\"\n :placeholder=\"placeholderText\"\n :aria-invalid=\"invalid ? 'true' : undefined\"\n class=\"flex-1 min-w-[120px] bg-transparent border-none outline-none placeholder:text-[var(--muted-fg)]\"\n :class=\"inputClassName\"\n @input=\"onInput\"\n @keydown=\"onKeydown\"\n @blur=\"onBlur\"\n @paste=\"onPaste\"\n >\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\n\nimport GrBadge from '../GrBadge/GrBadge.vue'\nimport type { GrBadgeRadius, GrBadgeSize, GrBadgeTone } from '../GrBadge'\nimport GrIcon from '../GrIcon/GrIcon.vue'\nimport IconClose from '~icons/lucide/x'\n\nimport {\n grInputTagInputClass,\n grInputTagWrapperClass,\n type GrInputTagSize,\n type GrInputTagState,\n} from './grInputTagStyles'\n\nexport type { GrInputTagSize, GrInputTagState } from './grInputTagStyles'\n\nconst REGEX_SPECIAL_CHAR_RE = /[.*+?^${}()|[\\]\\\\]/g\n\n/**\n * Props for {@link GrInputTag}.\n * Tag-input primitive: renders a set of badges with an inline `<input>` for entering new tags.\n * Splits input by configurable `separators`, supports paste, Enter and Backspace editing.\n */\nexport interface GrInputTagProps {\n modelValue: string[]\n placeholder?: string\n disabled?: boolean\n readonly?: boolean\n invalid?: boolean\n state?: GrInputTagState\n size?: GrInputTagSize\n separators?: string[]\n allowDuplicates?: boolean\n trim?: boolean\n max?: number\n addOnBlur?: boolean\n clearInputOnAdd?: boolean\n tagTone?: GrBadgeTone\n tagDark?: boolean\n tagSize?: GrBadgeSize\n tagRadius?: GrBadgeRadius\n tagClosable?: boolean\n /** i18n-friendly aria-label for the per-tag remove button. */\n removeTagLabel?: string\n}\n\nconst props = withDefaults(\n defineProps<GrInputTagProps>(),\n {\n placeholder: undefined,\n disabled: false,\n readonly: false,\n invalid: false,\n state: 'default',\n size: 'md',\n separators: () => [','],\n allowDuplicates: false,\n trim: true,\n max: undefined,\n addOnBlur: false,\n clearInputOnAdd: true,\n tagTone: 'neutral',\n tagDark: false,\n tagSize: 'md',\n tagRadius: 'round',\n tagClosable: true,\n removeTagLabel: 'Remove tag',\n },\n)\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string[]): void\n (e: 'add', value: string): void\n (e: 'remove', value: string, index: number): void\n}>()\n\nconst inputValue = ref('')\nconst inputEl = ref<HTMLInputElement | null>(null)\n\nfunction focus(): void {\n inputEl.value?.focus()\n}\n\ndefineExpose({ focus })\n\nconst isMaxed = computed(() => props.max !== undefined && props.modelValue.length >= props.max)\nconst canEdit = computed(() => !props.disabled && !props.readonly)\nconst showRemove = computed(() => props.tagClosable && canEdit.value)\n\nfunction escapeRegexChar(ch: string): string {\n return ch.replace(REGEX_SPECIAL_CHAR_RE, '\\\\$&')\n}\n\nconst splitRegex = computed(() => {\n const seps = (props.separators ?? []).filter(Boolean).map(s => s[0]!)\n const uniq = [...new Set([...seps, '\\n', '\\r', '\\t'])]\n const body = uniq.map(escapeRegexChar).join('')\n return new RegExp(`[${body}]+`, 'g')\n})\n\nfunction normalizeTag(raw: string): string {\n return props.trim ? raw.trim() : raw\n}\n\nfunction splitToTags(raw: string): string[] {\n return raw\n .split(splitRegex.value)\n .map(v => normalizeTag(v))\n .filter(Boolean)\n}\n\nfunction addMany(rawTags: string[]): boolean {\n if (!canEdit.value || isMaxed.value)\n return false\n\n const next = props.modelValue.slice()\n let changed = false\n\n for (const raw of rawTags) {\n const tag = normalizeTag(raw)\n if (!tag)\n continue\n\n if (!props.allowDuplicates && next.includes(tag))\n continue\n\n if (props.max !== undefined && next.length >= props.max)\n break\n\n next.push(tag)\n changed = true\n emit('add', tag)\n }\n\n if (!changed)\n return false\n\n emit('update:modelValue', next)\n return true\n}\n\nfunction commitInput(): void {\n if (!canEdit.value || isMaxed.value || !inputValue.value)\n return\n\n const tags = splitToTags(inputValue.value)\n if (!tags.length)\n return\n\n const changed = addMany(tags)\n if (changed && props.clearInputOnAdd)\n inputValue.value = ''\n}\n\nfunction removeAt(index: number): void {\n if (!canEdit.value)\n return\n\n const next = props.modelValue.slice()\n const removed = next[index]\n if (removed === undefined)\n return\n\n next.splice(index, 1)\n emit('update:modelValue', next)\n emit('remove', removed, index)\n}\n\nfunction onInput(e: Event): void {\n inputValue.value = (e.target as HTMLInputElement).value\n}\n\nfunction onKeydown(e: KeyboardEvent): void {\n if (!canEdit.value)\n return\n\n if (e.key === 'Enter') {\n e.preventDefault()\n commitInput()\n return\n }\n\n if ((props.separators ?? []).includes(e.key)) {\n e.preventDefault()\n commitInput()\n return\n }\n\n if (e.key === 'Backspace' && inputValue.value.length === 0 && props.modelValue.length > 0) {\n e.preventDefault()\n removeAt(props.modelValue.length - 1)\n }\n}\n\nfunction onBlur(): void {\n if (props.addOnBlur)\n commitInput()\n}\n\nfunction onPaste(e: ClipboardEvent): void {\n if (!canEdit.value || isMaxed.value)\n return\n\n const pasted = e.clipboardData?.getData('text')\n if (!pasted)\n return\n\n const tags = splitToTags(pasted)\n if (tags.length <= 1)\n return\n\n e.preventDefault()\n addMany(tags)\n}\n\nconst wrapperClassName = computed(() => {\n return grInputTagWrapperClass({\n size: props.size,\n state: props.state,\n invalid: props.invalid,\n disabled: props.disabled,\n })\n})\n\nconst inputClassName = computed(() => {\n return grInputTagInputClass(props.size)\n})\n\nconst placeholderText = computed(() => props.modelValue.length > 0 ? undefined : props.placeholder)\n</script>\n\n<template>\n <div\n data-ds-input-tag\n data-testid=\"ds-input-tag\"\n class=\"w-full flex flex-wrap items-center rounded-md border bg-[var(--bg)] text-[var(--fg)] transition-colors duration-150 focus-within:ring-2 focus-within:ring-[var(--ring)]\"\n :class=\"wrapperClassName\"\n @click=\"focus\"\n >\n <GrBadge\n v-for=\"(tag, i) in modelValue\"\n :key=\"`${tag}-${i}`\"\n :tone=\"tagTone\"\n :dark=\"tagDark\"\n :size=\"tagSize\"\n :radius=\"tagRadius\"\n class=\"gap-1\"\n data-ds-input-tag-item\n data-testid=\"ds-input-tag-item\"\n :data-index=\"i\"\n >\n <slot name=\"tag\" :tag=\"tag\" :index=\"i\" :remove=\"() => removeAt(i)\">\n <span class=\"truncate max-w-[18rem]\">{{ tag }}</span>\n </slot>\n\n <button\n v-if=\"showRemove\"\n type=\"button\"\n class=\"-mr-0.5 inline-flex items-center justify-center rounded-[6px] p-0.5 opacity-70 hover:opacity-100 focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)]\"\n :aria-label=\"removeTagLabel\"\n data-ds-input-tag-remove\n data-testid=\"ds-input-tag-remove\"\n :data-index=\"i\"\n @mousedown.prevent.stop\n @click.stop=\"removeAt(i)\"\n >\n <GrIcon size=\"sm\" aria-hidden=\"true\">\n <IconClose />\n </GrIcon>\n </button>\n </GrBadge>\n\n <input\n ref=\"inputEl\"\n data-ds-input-tag-input\n data-testid=\"ds-input-tag-input\"\n :value=\"inputValue\"\n :disabled=\"disabled || isMaxed\"\n :readonly=\"readonly\"\n :placeholder=\"placeholderText\"\n :aria-invalid=\"invalid ? 'true' : undefined\"\n class=\"flex-1 min-w-[120px] bg-transparent border-none outline-none placeholder:text-[var(--muted-fg)]\"\n :class=\"inputClassName\"\n @input=\"onInput\"\n @keydown=\"onKeydown\"\n @blur=\"onBlur\"\n @paste=\"onPaste\"\n >\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiBA,MAAM,wBAAwB;;;;;;EA8B9B,MAAM,QAAQ;EAwBd,MAAM,OAAO;EAMb,MAAM,aAAa,IAAI,GAAE;EACzB,MAAM,UAAU,IAA6B,KAAI;EAEjD,SAAS,QAAc;AACrB,WAAQ,OAAO,OAAM;;AAGvB,WAAa,EAAE,OAAO,CAAA;EAEtB,MAAM,UAAU,eAAe,MAAM,QAAQ,KAAA,KAAa,MAAM,WAAW,UAAU,MAAM,IAAG;EAC9F,MAAM,UAAU,eAAe,CAAC,MAAM,YAAY,CAAC,MAAM,SAAQ;EACjE,MAAM,aAAa,eAAe,MAAM,eAAe,QAAQ,MAAK;EAEpE,SAAS,gBAAgB,IAAoB;AAC3C,UAAO,GAAG,QAAQ,uBAAuB,OAAM;;EAGjD,MAAM,aAAa,eAAe;GAChC,MAAM,QAAQ,MAAM,cAAc,EAAE,EAAE,OAAO,QAAQ,CAAC,KAAI,MAAK,EAAE,GAAG;GAEpE,MAAM,OADO,CAAC,GAAG,IAAI,IAAI;IAAC,GAAG;IAAM;IAAM;IAAM;IAAK,CAAC,CAAA,CACnC,IAAI,gBAAgB,CAAC,KAAK,GAAE;AAC9C,UAAO,IAAI,OAAO,IAAI,KAAK,KAAK,IAAG;IACpC;EAED,SAAS,aAAa,KAAqB;AACzC,UAAO,MAAM,OAAO,IAAI,MAAM,GAAG;;EAGnC,SAAS,YAAY,KAAuB;AAC1C,UAAO,IACJ,MAAM,WAAW,MAAK,CACtB,KAAI,MAAK,aAAa,EAAE,CAAA,CACxB,OAAO,QAAO;;EAGnB,SAAS,QAAQ,SAA4B;AAC3C,OAAI,CAAC,QAAQ,SAAS,QAAQ,MAC5B,QAAO;GAET,MAAM,OAAO,MAAM,WAAW,OAAM;GACpC,IAAI,UAAU;AAEd,QAAK,MAAM,OAAO,SAAS;IACzB,MAAM,MAAM,aAAa,IAAG;AAC5B,QAAI,CAAC,IACH;AAEF,QAAI,CAAC,MAAM,mBAAmB,KAAK,SAAS,IAAI,CAC9C;AAEF,QAAI,MAAM,QAAQ,KAAA,KAAa,KAAK,UAAU,MAAM,IAClD;AAEF,SAAK,KAAK,IAAG;AACb,cAAU;AACV,SAAK,OAAO,IAAG;;AAGjB,OAAI,CAAC,QACH,QAAO;AAET,QAAK,qBAAqB,KAAI;AAC9B,UAAO;;EAGT,SAAS,cAAoB;AAC3B,OAAI,CAAC,QAAQ,SAAS,QAAQ,SAAS,CAAC,WAAW,MACjD;GAEF,MAAM,OAAO,YAAY,WAAW,MAAK;AACzC,OAAI,CAAC,KAAK,OACR;AAGF,OADgB,QAAQ,KAAI,IACb,MAAM,gBACnB,YAAW,QAAQ;;EAGvB,SAAS,SAAS,OAAqB;AACrC,OAAI,CAAC,QAAQ,MACX;GAEF,MAAM,OAAO,MAAM,WAAW,OAAM;GACpC,MAAM,UAAU,KAAK;AACrB,OAAI,YAAY,KAAA,EACd;AAEF,QAAK,OAAO,OAAO,EAAC;AACpB,QAAK,qBAAqB,KAAI;AAC9B,QAAK,UAAU,SAAS,MAAK;;EAG/B,SAAS,QAAQ,GAAgB;AAC/B,cAAW,QAAS,EAAE,OAA4B;;EAGpD,SAAS,UAAU,GAAwB;AACzC,OAAI,CAAC,QAAQ,MACX;AAEF,OAAI,EAAE,QAAQ,SAAS;AACrB,MAAE,gBAAe;AACjB,iBAAY;AACZ;;AAGF,QAAK,MAAM,cAAc,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE;AAC5C,MAAE,gBAAe;AACjB,iBAAY;AACZ;;AAGF,OAAI,EAAE,QAAQ,eAAe,WAAW,MAAM,WAAW,KAAK,MAAM,WAAW,SAAS,GAAG;AACzF,MAAE,gBAAe;AACjB,aAAS,MAAM,WAAW,SAAS,EAAC;;;EAIxC,SAAS,SAAe;AACtB,OAAI,MAAM,UACR,cAAY;;EAGhB,SAAS,QAAQ,GAAyB;AACxC,OAAI,CAAC,QAAQ,SAAS,QAAQ,MAC5B;GAEF,MAAM,SAAS,EAAE,eAAe,QAAQ,OAAM;AAC9C,OAAI,CAAC,OACH;GAEF,MAAM,OAAO,YAAY,OAAM;AAC/B,OAAI,KAAK,UAAU,EACjB;AAEF,KAAE,gBAAe;AACjB,WAAQ,KAAI;;EAGd,MAAM,mBAAmB,eAAe;AACtC,UAAO,uBAAuB;IAC5B,MAAM,MAAM;IACZ,OAAO,MAAM;IACb,SAAS,MAAM;IACf,UAAU,MAAM;IACjB,CAAA;IACF;EAED,MAAM,iBAAiB,eAAe;AACpC,UAAO,qBAAqB,MAAM,KAAI;IACvC;EAED,MAAM,kBAAkB,eAAe,MAAM,WAAW,SAAS,IAAI,KAAA,IAAY,MAAM,YAAW;;uBAIhG,mBAwDM,OAAA;IAvDJ,qBAAA;IACA,eAAY;IACZ,OAAK,eAAA,CAAC,2KACE,iBAAA,MAAgB,CAAA;IACvB,SAAO;yBAER,mBA+BU,UAAA,MAAA,WA9BW,QAAA,aAAX,KAAK,MAAC;wBADhB,YA+BU,iBAAA;KA7BP,KAAG,GAAK,IAAG,GAAI;KACf,MAAM,QAAA;KACN,MAAM,QAAA;KACN,MAAM,QAAA;KACN,QAAQ,QAAA;KACT,OAAM;KACN,0BAAA;KACA,eAAY;KACX,cAAY;;4BAIN,CAFP,WAEO,KAAA,QAAA,OAAA;MAFgB;MAAM,OAAO;MAAI,cAAc,SAAS,EAAC;cAEzD,CADL,mBAAqD,QAArD,YAAqD,gBAAb,IAAG,EAAA,EAAA,CAAA,CAAA,EAIrC,WAAA,SAAA,WAAA,EADR,mBAcS,UAAA;;MAZP,MAAK;MACL,OAAM;MACL,cAAY,QAAA;MACb,4BAAA;MACA,eAAY;MACX,cAAY;MACZ,aAAS,OAAA,OAAA,OAAA,KAAA,oBAAV,IAAuB,CAAA,WAAA,OAAA,CAAA;MACtB,SAAK,eAAA,WAAO,SAAS,EAAC,EAAA,CAAA,OAAA,CAAA;SAEvB,YAES,gBAAA;MAFD,MAAK;MAAK,eAAY;;6BACf,CAAb,YAAa,MAAA,UAAA,CAAA,CAAA,CAAA;;;;;;;;;;;cAKnB,mBAeC,SAAA;aAdK;IAAJ,KAAI;IACJ,2BAAA;IACA,eAAY;IACX,OAAO,WAAA;IACP,UAAU,QAAA,YAAY,QAAA;IACtB,UAAU,QAAA;IACV,aAAa,gBAAA;IACb,gBAAc,QAAA,UAAO,SAAY,KAAA;IAClC,OAAK,eAAA,CAAC,mGACE,eAAA,MAAc,CAAA;IACd;IACE;IACH;IACC"}
1
+ {"version":3,"file":"GrInputTag-Dcj3F6rQ.js","names":[],"sources":["../../../../src/components/GrInputTag/GrInputTag.vue","../../../../src/components/GrInputTag/GrInputTag.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\n\nimport GrBadge from '../GrBadge/GrBadge.vue'\nimport type { GrBadgeRadius, GrBadgeSize, GrBadgeTone } from '../GrBadge'\nimport GrIcon from '../GrIcon/GrIcon.vue'\nimport IconClose from '~icons/lucide/x'\n\nimport {\n grInputTagInputClass,\n grInputTagWrapperClass,\n type GrInputTagSize,\n type GrInputTagState,\n} from './grInputTagStyles'\n\nexport type { GrInputTagSize, GrInputTagState } from './grInputTagStyles'\n\nconst REGEX_SPECIAL_CHAR_RE = /[.*+?^${}()|[\\]\\\\]/g\n\n/**\n * Props for {@link GrInputTag}.\n * Tag-input primitive: renders a set of badges with an inline `<input>` for entering new tags.\n * Splits input by configurable `separators`, supports paste, Enter and Backspace editing.\n */\nexport interface GrInputTagProps {\n modelValue: string[]\n placeholder?: string\n disabled?: boolean\n readonly?: boolean\n invalid?: boolean\n state?: GrInputTagState\n size?: GrInputTagSize\n separators?: string[]\n allowDuplicates?: boolean\n trim?: boolean\n max?: number\n addOnBlur?: boolean\n clearInputOnAdd?: boolean\n tagTone?: GrBadgeTone\n tagDark?: boolean\n tagSize?: GrBadgeSize\n tagRadius?: GrBadgeRadius\n tagClosable?: boolean\n /** i18n-friendly aria-label for the per-tag remove button. */\n removeTagLabel?: string\n}\n\nconst props = withDefaults(\n defineProps<GrInputTagProps>(),\n {\n placeholder: undefined,\n disabled: false,\n readonly: false,\n invalid: false,\n state: 'default',\n size: 'md',\n separators: () => [','],\n allowDuplicates: false,\n trim: true,\n max: undefined,\n addOnBlur: false,\n clearInputOnAdd: true,\n tagTone: 'neutral',\n tagDark: false,\n tagSize: 'md',\n tagRadius: 'round',\n tagClosable: true,\n removeTagLabel: 'Remove tag',\n },\n)\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string[]): void\n (e: 'add', value: string): void\n (e: 'remove', value: string, index: number): void\n}>()\n\nconst inputValue = ref('')\nconst inputEl = ref<HTMLInputElement | null>(null)\n\nfunction focus(): void {\n inputEl.value?.focus()\n}\n\ndefineExpose({ focus })\n\nconst isMaxed = computed(() => props.max !== undefined && props.modelValue.length >= props.max)\nconst canEdit = computed(() => !props.disabled && !props.readonly)\nconst showRemove = computed(() => props.tagClosable && canEdit.value)\n\nfunction escapeRegexChar(ch: string): string {\n return ch.replace(REGEX_SPECIAL_CHAR_RE, '\\\\$&')\n}\n\nconst splitRegex = computed(() => {\n const seps = (props.separators ?? []).filter(Boolean).map(s => s[0]!)\n const uniq = [...new Set([...seps, '\\n', '\\r', '\\t'])]\n const body = uniq.map(escapeRegexChar).join('')\n return new RegExp(`[${body}]+`, 'g')\n})\n\nfunction normalizeTag(raw: string): string {\n return props.trim ? raw.trim() : raw\n}\n\nfunction splitToTags(raw: string): string[] {\n return raw\n .split(splitRegex.value)\n .map(v => normalizeTag(v))\n .filter(Boolean)\n}\n\nfunction addMany(rawTags: string[]): boolean {\n if (!canEdit.value || isMaxed.value)\n return false\n\n const next = props.modelValue.slice()\n let changed = false\n\n for (const raw of rawTags) {\n const tag = normalizeTag(raw)\n if (!tag)\n continue\n\n if (!props.allowDuplicates && next.includes(tag))\n continue\n\n if (props.max !== undefined && next.length >= props.max)\n break\n\n next.push(tag)\n changed = true\n emit('add', tag)\n }\n\n if (!changed)\n return false\n\n emit('update:modelValue', next)\n return true\n}\n\nfunction commitInput(): void {\n if (!canEdit.value || isMaxed.value || !inputValue.value)\n return\n\n const tags = splitToTags(inputValue.value)\n if (!tags.length)\n return\n\n const changed = addMany(tags)\n if (changed && props.clearInputOnAdd)\n inputValue.value = ''\n}\n\nfunction removeAt(index: number): void {\n if (!canEdit.value)\n return\n\n const next = props.modelValue.slice()\n const removed = next[index]\n if (removed === undefined)\n return\n\n next.splice(index, 1)\n emit('update:modelValue', next)\n emit('remove', removed, index)\n}\n\nfunction onInput(e: Event): void {\n inputValue.value = (e.target as HTMLInputElement).value\n}\n\nfunction onKeydown(e: KeyboardEvent): void {\n if (!canEdit.value)\n return\n\n if (e.key === 'Enter') {\n e.preventDefault()\n commitInput()\n return\n }\n\n if ((props.separators ?? []).includes(e.key)) {\n e.preventDefault()\n commitInput()\n return\n }\n\n if (e.key === 'Backspace' && inputValue.value.length === 0 && props.modelValue.length > 0) {\n e.preventDefault()\n removeAt(props.modelValue.length - 1)\n }\n}\n\nfunction onBlur(): void {\n if (props.addOnBlur)\n commitInput()\n}\n\nfunction onPaste(e: ClipboardEvent): void {\n if (!canEdit.value || isMaxed.value)\n return\n\n const pasted = e.clipboardData?.getData('text')\n if (!pasted)\n return\n\n const tags = splitToTags(pasted)\n if (tags.length <= 1)\n return\n\n e.preventDefault()\n addMany(tags)\n}\n\nconst wrapperClassName = computed(() => {\n return grInputTagWrapperClass({\n size: props.size,\n state: props.state,\n invalid: props.invalid,\n disabled: props.disabled,\n })\n})\n\nconst inputClassName = computed(() => {\n return grInputTagInputClass(props.size)\n})\n\nconst placeholderText = computed(() => props.modelValue.length > 0 ? undefined : props.placeholder)\n</script>\n\n<template>\n <div\n data-ds-input-tag\n data-testid=\"ds-input-tag\"\n class=\"w-full flex flex-wrap items-center rounded-md border bg-[var(--bg)] text-[var(--fg)] transition-colors duration-150 focus-within:ring-2 focus-within:ring-[var(--ring)]\"\n :class=\"wrapperClassName\"\n @click=\"focus\"\n >\n <GrBadge\n v-for=\"(tag, i) in modelValue\"\n :key=\"`${tag}-${i}`\"\n :tone=\"tagTone\"\n :dark=\"tagDark\"\n :size=\"tagSize\"\n :radius=\"tagRadius\"\n class=\"gap-1\"\n data-ds-input-tag-item\n data-testid=\"ds-input-tag-item\"\n :data-index=\"i\"\n >\n <slot name=\"tag\" :tag=\"tag\" :index=\"i\" :remove=\"() => removeAt(i)\">\n <span class=\"truncate max-w-[18rem]\">{{ tag }}</span>\n </slot>\n\n <button\n v-if=\"showRemove\"\n type=\"button\"\n class=\"-mr-0.5 inline-flex items-center justify-center rounded-[6px] p-0.5 opacity-70 hover:opacity-100 focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)]\"\n :aria-label=\"removeTagLabel\"\n data-ds-input-tag-remove\n data-testid=\"ds-input-tag-remove\"\n :data-index=\"i\"\n @mousedown.prevent.stop\n @click.stop=\"removeAt(i)\"\n >\n <GrIcon size=\"sm\" aria-hidden=\"true\">\n <IconClose />\n </GrIcon>\n </button>\n </GrBadge>\n\n <input\n ref=\"inputEl\"\n data-ds-input-tag-input\n data-testid=\"ds-input-tag-input\"\n :value=\"inputValue\"\n :disabled=\"disabled || isMaxed\"\n :readonly=\"readonly\"\n :placeholder=\"placeholderText\"\n :aria-invalid=\"invalid ? 'true' : undefined\"\n class=\"flex-1 min-w-[120px] bg-transparent border-none outline-none placeholder:text-[var(--muted-fg)]\"\n :class=\"inputClassName\"\n @input=\"onInput\"\n @keydown=\"onKeydown\"\n @blur=\"onBlur\"\n @paste=\"onPaste\"\n >\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\n\nimport GrBadge from '../GrBadge/GrBadge.vue'\nimport type { GrBadgeRadius, GrBadgeSize, GrBadgeTone } from '../GrBadge'\nimport GrIcon from '../GrIcon/GrIcon.vue'\nimport IconClose from '~icons/lucide/x'\n\nimport {\n grInputTagInputClass,\n grInputTagWrapperClass,\n type GrInputTagSize,\n type GrInputTagState,\n} from './grInputTagStyles'\n\nexport type { GrInputTagSize, GrInputTagState } from './grInputTagStyles'\n\nconst REGEX_SPECIAL_CHAR_RE = /[.*+?^${}()|[\\]\\\\]/g\n\n/**\n * Props for {@link GrInputTag}.\n * Tag-input primitive: renders a set of badges with an inline `<input>` for entering new tags.\n * Splits input by configurable `separators`, supports paste, Enter and Backspace editing.\n */\nexport interface GrInputTagProps {\n modelValue: string[]\n placeholder?: string\n disabled?: boolean\n readonly?: boolean\n invalid?: boolean\n state?: GrInputTagState\n size?: GrInputTagSize\n separators?: string[]\n allowDuplicates?: boolean\n trim?: boolean\n max?: number\n addOnBlur?: boolean\n clearInputOnAdd?: boolean\n tagTone?: GrBadgeTone\n tagDark?: boolean\n tagSize?: GrBadgeSize\n tagRadius?: GrBadgeRadius\n tagClosable?: boolean\n /** i18n-friendly aria-label for the per-tag remove button. */\n removeTagLabel?: string\n}\n\nconst props = withDefaults(\n defineProps<GrInputTagProps>(),\n {\n placeholder: undefined,\n disabled: false,\n readonly: false,\n invalid: false,\n state: 'default',\n size: 'md',\n separators: () => [','],\n allowDuplicates: false,\n trim: true,\n max: undefined,\n addOnBlur: false,\n clearInputOnAdd: true,\n tagTone: 'neutral',\n tagDark: false,\n tagSize: 'md',\n tagRadius: 'round',\n tagClosable: true,\n removeTagLabel: 'Remove tag',\n },\n)\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string[]): void\n (e: 'add', value: string): void\n (e: 'remove', value: string, index: number): void\n}>()\n\nconst inputValue = ref('')\nconst inputEl = ref<HTMLInputElement | null>(null)\n\nfunction focus(): void {\n inputEl.value?.focus()\n}\n\ndefineExpose({ focus })\n\nconst isMaxed = computed(() => props.max !== undefined && props.modelValue.length >= props.max)\nconst canEdit = computed(() => !props.disabled && !props.readonly)\nconst showRemove = computed(() => props.tagClosable && canEdit.value)\n\nfunction escapeRegexChar(ch: string): string {\n return ch.replace(REGEX_SPECIAL_CHAR_RE, '\\\\$&')\n}\n\nconst splitRegex = computed(() => {\n const seps = (props.separators ?? []).filter(Boolean).map(s => s[0]!)\n const uniq = [...new Set([...seps, '\\n', '\\r', '\\t'])]\n const body = uniq.map(escapeRegexChar).join('')\n return new RegExp(`[${body}]+`, 'g')\n})\n\nfunction normalizeTag(raw: string): string {\n return props.trim ? raw.trim() : raw\n}\n\nfunction splitToTags(raw: string): string[] {\n return raw\n .split(splitRegex.value)\n .map(v => normalizeTag(v))\n .filter(Boolean)\n}\n\nfunction addMany(rawTags: string[]): boolean {\n if (!canEdit.value || isMaxed.value)\n return false\n\n const next = props.modelValue.slice()\n let changed = false\n\n for (const raw of rawTags) {\n const tag = normalizeTag(raw)\n if (!tag)\n continue\n\n if (!props.allowDuplicates && next.includes(tag))\n continue\n\n if (props.max !== undefined && next.length >= props.max)\n break\n\n next.push(tag)\n changed = true\n emit('add', tag)\n }\n\n if (!changed)\n return false\n\n emit('update:modelValue', next)\n return true\n}\n\nfunction commitInput(): void {\n if (!canEdit.value || isMaxed.value || !inputValue.value)\n return\n\n const tags = splitToTags(inputValue.value)\n if (!tags.length)\n return\n\n const changed = addMany(tags)\n if (changed && props.clearInputOnAdd)\n inputValue.value = ''\n}\n\nfunction removeAt(index: number): void {\n if (!canEdit.value)\n return\n\n const next = props.modelValue.slice()\n const removed = next[index]\n if (removed === undefined)\n return\n\n next.splice(index, 1)\n emit('update:modelValue', next)\n emit('remove', removed, index)\n}\n\nfunction onInput(e: Event): void {\n inputValue.value = (e.target as HTMLInputElement).value\n}\n\nfunction onKeydown(e: KeyboardEvent): void {\n if (!canEdit.value)\n return\n\n if (e.key === 'Enter') {\n e.preventDefault()\n commitInput()\n return\n }\n\n if ((props.separators ?? []).includes(e.key)) {\n e.preventDefault()\n commitInput()\n return\n }\n\n if (e.key === 'Backspace' && inputValue.value.length === 0 && props.modelValue.length > 0) {\n e.preventDefault()\n removeAt(props.modelValue.length - 1)\n }\n}\n\nfunction onBlur(): void {\n if (props.addOnBlur)\n commitInput()\n}\n\nfunction onPaste(e: ClipboardEvent): void {\n if (!canEdit.value || isMaxed.value)\n return\n\n const pasted = e.clipboardData?.getData('text')\n if (!pasted)\n return\n\n const tags = splitToTags(pasted)\n if (tags.length <= 1)\n return\n\n e.preventDefault()\n addMany(tags)\n}\n\nconst wrapperClassName = computed(() => {\n return grInputTagWrapperClass({\n size: props.size,\n state: props.state,\n invalid: props.invalid,\n disabled: props.disabled,\n })\n})\n\nconst inputClassName = computed(() => {\n return grInputTagInputClass(props.size)\n})\n\nconst placeholderText = computed(() => props.modelValue.length > 0 ? undefined : props.placeholder)\n</script>\n\n<template>\n <div\n data-ds-input-tag\n data-testid=\"ds-input-tag\"\n class=\"w-full flex flex-wrap items-center rounded-md border bg-[var(--bg)] text-[var(--fg)] transition-colors duration-150 focus-within:ring-2 focus-within:ring-[var(--ring)]\"\n :class=\"wrapperClassName\"\n @click=\"focus\"\n >\n <GrBadge\n v-for=\"(tag, i) in modelValue\"\n :key=\"`${tag}-${i}`\"\n :tone=\"tagTone\"\n :dark=\"tagDark\"\n :size=\"tagSize\"\n :radius=\"tagRadius\"\n class=\"gap-1\"\n data-ds-input-tag-item\n data-testid=\"ds-input-tag-item\"\n :data-index=\"i\"\n >\n <slot name=\"tag\" :tag=\"tag\" :index=\"i\" :remove=\"() => removeAt(i)\">\n <span class=\"truncate max-w-[18rem]\">{{ tag }}</span>\n </slot>\n\n <button\n v-if=\"showRemove\"\n type=\"button\"\n class=\"-mr-0.5 inline-flex items-center justify-center rounded-[6px] p-0.5 opacity-70 hover:opacity-100 focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)]\"\n :aria-label=\"removeTagLabel\"\n data-ds-input-tag-remove\n data-testid=\"ds-input-tag-remove\"\n :data-index=\"i\"\n @mousedown.prevent.stop\n @click.stop=\"removeAt(i)\"\n >\n <GrIcon size=\"sm\" aria-hidden=\"true\">\n <IconClose />\n </GrIcon>\n </button>\n </GrBadge>\n\n <input\n ref=\"inputEl\"\n data-ds-input-tag-input\n data-testid=\"ds-input-tag-input\"\n :value=\"inputValue\"\n :disabled=\"disabled || isMaxed\"\n :readonly=\"readonly\"\n :placeholder=\"placeholderText\"\n :aria-invalid=\"invalid ? 'true' : undefined\"\n class=\"flex-1 min-w-[120px] bg-transparent border-none outline-none placeholder:text-[var(--muted-fg)]\"\n :class=\"inputClassName\"\n @input=\"onInput\"\n @keydown=\"onKeydown\"\n @blur=\"onBlur\"\n @paste=\"onPaste\"\n >\n </div>\n</template>\n"],"mappings":"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"}
@@ -1,3 +1,3 @@
1
- import { n as grInputTagSafelist, t as grInputTagConfig } from "../../chunks/config-Dusr9jcE.js";
2
- import { t as GrInputTag_default } from "./chunks/GrInputTag-CeEy0IwD.js";
1
+ import { n as grInputTagSafelist, t as grInputTagConfig } from "../../chunks/config-BnWSHTEU.js";
2
+ import { t as GrInputTag_default } from "./chunks/GrInputTag-Dcj3F6rQ.js";
3
3
  export { GrInputTag_default as GrInputTag, GrInputTag_default as default, grInputTagConfig, grInputTagSafelist };
@@ -1,4 +1,4 @@
1
- import { a as grLinkClass, i as focusRingClass, r as baseRootClass } from "../../../chunks/config-CjEplP6D.js";
1
+ import { a as grLinkClass, i as focusRingClass, r as baseRootClass } from "../../../chunks/config-CpMYmvVT.js";
2
2
  import { computed, createBlock, defineComponent, markRaw, mergeProps, openBlock, renderSlot, resolveDynamicComponent, unref, useAttrs, withCtx } from "vue";
3
3
  //#endregion
4
4
  //#region src/components/GrLink/GrLink.vue
@@ -1 +1 @@
1
- {"version":3,"file":"GrLink-BLPigqij.js","names":[],"sources":["../../../../src/components/GrLink/GrLink.vue","../../../../src/components/GrLink/GrLink.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * GrLink — DS-примитив ссылки.\n *\n * Корневой тег зависит от пропов:\n * - кастомный компонент/тег из пропа `as` — когда `as` передан и не `disabled`\n * (например, `Link` от `@inertiajs/vue3` или `RouterLink` от Vue Router);\n * - `<a>` — когда задан `href` и не `disabled`;\n * - `<span>` — во всех остальных случаях (включая `disabled`, даже если задан\n * `href`/`as`).\n *\n * Это осознанное решение, чтобы отключённая ссылка не была кликабельной и\n * не участвовала в порядке табуляции. Учтите это в внешних CSS-селекторах.\n *\n * Проп `as` нужен для интеграции с роутерами (Inertia, Vue Router и пр.):\n * стили/поведение DS остаются едиными, а тег корня подменяется. Все\n * специфичные для роутера атрибуты (`method`, `replace`, `preserve-scroll` и т.п.)\n * проходят через fallthrough-attrs.\n */\nimport { computed, markRaw, useAttrs, type Component } from 'vue'\n\nimport {\n baseRootClass,\n focusRingClass,\n type GrLinkSize,\n type GrLinkUnderline,\n type GrLinkVariant,\n grLinkClass,\n} from './grLinkStyles'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = withDefaults(defineProps<{\n /**\n * Кастомный корневой тег/компонент. Если передан и компонент не `disabled` —\n * рендерится через `<component :is=\"as\">`. Игнорируется при `disabled`.\n */\n as?: string | Component\n href?: string\n external?: boolean\n target?: string\n rel?: string\n disabled?: boolean\n ariaLabel?: string\n variant?: GrLinkVariant\n underline?: GrLinkUnderline\n size?: GrLinkSize\n}>(), {\n as: undefined,\n href: undefined,\n external: false,\n target: undefined,\n rel: undefined,\n disabled: false,\n ariaLabel: undefined,\n variant: 'primary',\n underline: 'auto',\n size: 'md',\n})\n\nconst attrs = useAttrs()\n\n// Кастомный корень имеет приоритет над `<a>` — DS не пытается угадывать\n// «правильный» тег за пользователя, если он явно его указал.\nconst isInteractive = computed(() => !props.disabled && (!!props.as || !!props.href))\n\nconst renderAs = computed<string | Component>(() => {\n if (!isInteractive.value) return 'span'\n if (props.as) {\n // Если `as` — объект-компонент, помечаем его как нереактивный, чтобы избежать\n // оверхеда от Vue-прокси и предупреждений в консоли. Строки (нативные теги)\n // оставляем как есть.\n return typeof props.as === 'string' ? props.as : markRaw(props.as)\n }\n return 'a'\n})\n\nconst resolvedTarget = computed(() => {\n if (props.target)\n return props.target\n\n if (props.external)\n return '_blank'\n\n return undefined\n})\n\nconst resolvedRel = computed(() => {\n if (props.rel)\n return props.rel\n\n // Авто-защита для любых ссылок, открывающихся в новой вкладке,\n // а не только когда выставлен `external`.\n if (resolvedTarget.value === '_blank')\n return 'noopener noreferrer'\n\n return undefined\n})\n\nconst rootClass = computed(() => {\n const variantClass = grLinkClass({\n size: props.size,\n underline: props.underline,\n variant: props.variant,\n disabled: props.disabled,\n })\n\n // На disabled-ветке (`<span>`) focus-ring не нужен: элемент не фокусируется,\n // а если снаружи ему навесят `tabindex`, фокус-рамка на «отключённой» ссылке смотрелась бы странно.\n return props.disabled\n ? `${baseRootClass} ${variantClass}`\n : `${baseRootClass} ${focusRingClass} ${variantClass}`\n})\n</script>\n\n<template>\n <component\n :is=\"renderAs\"\n v-bind=\"attrs\"\n :href=\"isInteractive ? href : undefined\"\n :target=\"isInteractive ? resolvedTarget : undefined\"\n :rel=\"isInteractive ? resolvedRel : undefined\"\n :aria-label=\"ariaLabel\"\n :aria-disabled=\"disabled ? 'true' : undefined\"\n :class=\"rootClass\"\n >\n <slot />\n </component>\n</template>\n","<script setup lang=\"ts\">\n/**\n * GrLink — DS-примитив ссылки.\n *\n * Корневой тег зависит от пропов:\n * - кастомный компонент/тег из пропа `as` — когда `as` передан и не `disabled`\n * (например, `Link` от `@inertiajs/vue3` или `RouterLink` от Vue Router);\n * - `<a>` — когда задан `href` и не `disabled`;\n * - `<span>` — во всех остальных случаях (включая `disabled`, даже если задан\n * `href`/`as`).\n *\n * Это осознанное решение, чтобы отключённая ссылка не была кликабельной и\n * не участвовала в порядке табуляции. Учтите это в внешних CSS-селекторах.\n *\n * Проп `as` нужен для интеграции с роутерами (Inertia, Vue Router и пр.):\n * стили/поведение DS остаются едиными, а тег корня подменяется. Все\n * специфичные для роутера атрибуты (`method`, `replace`, `preserve-scroll` и т.п.)\n * проходят через fallthrough-attrs.\n */\nimport { computed, markRaw, useAttrs, type Component } from 'vue'\n\nimport {\n baseRootClass,\n focusRingClass,\n type GrLinkSize,\n type GrLinkUnderline,\n type GrLinkVariant,\n grLinkClass,\n} from './grLinkStyles'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = withDefaults(defineProps<{\n /**\n * Кастомный корневой тег/компонент. Если передан и компонент не `disabled` —\n * рендерится через `<component :is=\"as\">`. Игнорируется при `disabled`.\n */\n as?: string | Component\n href?: string\n external?: boolean\n target?: string\n rel?: string\n disabled?: boolean\n ariaLabel?: string\n variant?: GrLinkVariant\n underline?: GrLinkUnderline\n size?: GrLinkSize\n}>(), {\n as: undefined,\n href: undefined,\n external: false,\n target: undefined,\n rel: undefined,\n disabled: false,\n ariaLabel: undefined,\n variant: 'primary',\n underline: 'auto',\n size: 'md',\n})\n\nconst attrs = useAttrs()\n\n// Кастомный корень имеет приоритет над `<a>` — DS не пытается угадывать\n// «правильный» тег за пользователя, если он явно его указал.\nconst isInteractive = computed(() => !props.disabled && (!!props.as || !!props.href))\n\nconst renderAs = computed<string | Component>(() => {\n if (!isInteractive.value) return 'span'\n if (props.as) {\n // Если `as` — объект-компонент, помечаем его как нереактивный, чтобы избежать\n // оверхеда от Vue-прокси и предупреждений в консоли. Строки (нативные теги)\n // оставляем как есть.\n return typeof props.as === 'string' ? props.as : markRaw(props.as)\n }\n return 'a'\n})\n\nconst resolvedTarget = computed(() => {\n if (props.target)\n return props.target\n\n if (props.external)\n return '_blank'\n\n return undefined\n})\n\nconst resolvedRel = computed(() => {\n if (props.rel)\n return props.rel\n\n // Авто-защита для любых ссылок, открывающихся в новой вкладке,\n // а не только когда выставлен `external`.\n if (resolvedTarget.value === '_blank')\n return 'noopener noreferrer'\n\n return undefined\n})\n\nconst rootClass = computed(() => {\n const variantClass = grLinkClass({\n size: props.size,\n underline: props.underline,\n variant: props.variant,\n disabled: props.disabled,\n })\n\n // На disabled-ветке (`<span>`) focus-ring не нужен: элемент не фокусируется,\n // а если снаружи ему навесят `tabindex`, фокус-рамка на «отключённой» ссылке смотрелась бы странно.\n return props.disabled\n ? `${baseRootClass} ${variantClass}`\n : `${baseRootClass} ${focusRingClass} ${variantClass}`\n})\n</script>\n\n<template>\n <component\n :is=\"renderAs\"\n v-bind=\"attrs\"\n :href=\"isInteractive ? href : undefined\"\n :target=\"isInteractive ? resolvedTarget : undefined\"\n :rel=\"isInteractive ? resolvedRel : undefined\"\n :aria-label=\"ariaLabel\"\n :aria-disabled=\"disabled ? 'true' : undefined\"\n :class=\"rootClass\"\n >\n <slot />\n </component>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkCA,MAAM,QAAQ;EA4Bd,MAAM,QAAQ,UAAS;EAIvB,MAAM,gBAAgB,eAAe,CAAC,MAAM,aAAa,CAAC,CAAC,MAAM,MAAM,CAAC,CAAC,MAAM,MAAK;EAEpF,MAAM,WAAW,eAAmC;AAClD,OAAI,CAAC,cAAc,MAAO,QAAO;AACjC,OAAI,MAAM,GAIR,QAAO,OAAO,MAAM,OAAO,WAAW,MAAM,KAAK,QAAQ,MAAM,GAAE;AAEnE,UAAO;IACR;EAED,MAAM,iBAAiB,eAAe;AACpC,OAAI,MAAM,OACR,QAAO,MAAM;AAEf,OAAI,MAAM,SACR,QAAO;IAGV;EAED,MAAM,cAAc,eAAe;AACjC,OAAI,MAAM,IACR,QAAO,MAAM;AAIf,OAAI,eAAe,UAAU,SAC3B,QAAO;IAGV;EAED,MAAM,YAAY,eAAe;GAC/B,MAAM,eAAe,YAAY;IAC/B,MAAM,MAAM;IACZ,WAAW,MAAM;IACjB,SAAS,MAAM;IACf,UAAU,MAAM;IACjB,CAAA;AAID,UAAO,MAAM,WACT,GAAG,cAAc,GAAG,iBACpB,GAAG,cAAc,GAAG,eAAe,GAAG;IAC3C;;uBAIC,YAWY,wBAVL,SAAA,MAAQ,EADf,WAEU,MASE,MATG,EAAA;IACZ,MAAM,cAAA,QAAgB,QAAA,OAAO,KAAA;IAC7B,QAAQ,cAAA,QAAgB,eAAA,QAAiB,KAAA;IACzC,KAAK,cAAA,QAAgB,YAAA,QAAc,KAAA;IACnC,cAAY,QAAA;IACZ,iBAAe,QAAA,WAAQ,SAAY,KAAA;IACnC,OAAO,UAAA;;2BAEA,CAAR,WAAQ,KAAA,QAAA,UAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"GrLink-BMwn2iJ9.js","names":[],"sources":["../../../../src/components/GrLink/GrLink.vue","../../../../src/components/GrLink/GrLink.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * GrLink — DS-примитив ссылки.\n *\n * Корневой тег зависит от пропов:\n * - кастомный компонент/тег из пропа `as` — когда `as` передан и не `disabled`\n * (например, `Link` от `@inertiajs/vue3` или `RouterLink` от Vue Router);\n * - `<a>` — когда задан `href` и не `disabled`;\n * - `<span>` — во всех остальных случаях (включая `disabled`, даже если задан\n * `href`/`as`).\n *\n * Это осознанное решение, чтобы отключённая ссылка не была кликабельной и\n * не участвовала в порядке табуляции. Учтите это в внешних CSS-селекторах.\n *\n * Проп `as` нужен для интеграции с роутерами (Inertia, Vue Router и пр.):\n * стили/поведение DS остаются едиными, а тег корня подменяется. Все\n * специфичные для роутера атрибуты (`method`, `replace`, `preserve-scroll` и т.п.)\n * проходят через fallthrough-attrs.\n */\nimport { computed, markRaw, useAttrs, type Component } from 'vue'\n\nimport {\n baseRootClass,\n focusRingClass,\n type GrLinkSize,\n type GrLinkUnderline,\n type GrLinkVariant,\n grLinkClass,\n} from './grLinkStyles'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = withDefaults(defineProps<{\n /**\n * Кастомный корневой тег/компонент. Если передан и компонент не `disabled` —\n * рендерится через `<component :is=\"as\">`. Игнорируется при `disabled`.\n */\n as?: string | Component\n href?: string\n external?: boolean\n target?: string\n rel?: string\n disabled?: boolean\n ariaLabel?: string\n variant?: GrLinkVariant\n underline?: GrLinkUnderline\n size?: GrLinkSize\n}>(), {\n as: undefined,\n href: undefined,\n external: false,\n target: undefined,\n rel: undefined,\n disabled: false,\n ariaLabel: undefined,\n variant: 'primary',\n underline: 'auto',\n size: 'md',\n})\n\nconst attrs = useAttrs()\n\n// Кастомный корень имеет приоритет над `<a>` — DS не пытается угадывать\n// «правильный» тег за пользователя, если он явно его указал.\nconst isInteractive = computed(() => !props.disabled && (!!props.as || !!props.href))\n\nconst renderAs = computed<string | Component>(() => {\n if (!isInteractive.value) return 'span'\n if (props.as) {\n // Если `as` — объект-компонент, помечаем его как нереактивный, чтобы избежать\n // оверхеда от Vue-прокси и предупреждений в консоли. Строки (нативные теги)\n // оставляем как есть.\n return typeof props.as === 'string' ? props.as : markRaw(props.as)\n }\n return 'a'\n})\n\nconst resolvedTarget = computed(() => {\n if (props.target)\n return props.target\n\n if (props.external)\n return '_blank'\n\n return undefined\n})\n\nconst resolvedRel = computed(() => {\n if (props.rel)\n return props.rel\n\n // Авто-защита для любых ссылок, открывающихся в новой вкладке,\n // а не только когда выставлен `external`.\n if (resolvedTarget.value === '_blank')\n return 'noopener noreferrer'\n\n return undefined\n})\n\nconst rootClass = computed(() => {\n const variantClass = grLinkClass({\n size: props.size,\n underline: props.underline,\n variant: props.variant,\n disabled: props.disabled,\n })\n\n // На disabled-ветке (`<span>`) focus-ring не нужен: элемент не фокусируется,\n // а если снаружи ему навесят `tabindex`, фокус-рамка на «отключённой» ссылке смотрелась бы странно.\n return props.disabled\n ? `${baseRootClass} ${variantClass}`\n : `${baseRootClass} ${focusRingClass} ${variantClass}`\n})\n</script>\n\n<template>\n <component\n :is=\"renderAs\"\n v-bind=\"attrs\"\n :href=\"isInteractive ? href : undefined\"\n :target=\"isInteractive ? resolvedTarget : undefined\"\n :rel=\"isInteractive ? resolvedRel : undefined\"\n :aria-label=\"ariaLabel\"\n :aria-disabled=\"disabled ? 'true' : undefined\"\n :class=\"rootClass\"\n >\n <slot />\n </component>\n</template>\n","<script setup lang=\"ts\">\n/**\n * GrLink — DS-примитив ссылки.\n *\n * Корневой тег зависит от пропов:\n * - кастомный компонент/тег из пропа `as` — когда `as` передан и не `disabled`\n * (например, `Link` от `@inertiajs/vue3` или `RouterLink` от Vue Router);\n * - `<a>` — когда задан `href` и не `disabled`;\n * - `<span>` — во всех остальных случаях (включая `disabled`, даже если задан\n * `href`/`as`).\n *\n * Это осознанное решение, чтобы отключённая ссылка не была кликабельной и\n * не участвовала в порядке табуляции. Учтите это в внешних CSS-селекторах.\n *\n * Проп `as` нужен для интеграции с роутерами (Inertia, Vue Router и пр.):\n * стили/поведение DS остаются едиными, а тег корня подменяется. Все\n * специфичные для роутера атрибуты (`method`, `replace`, `preserve-scroll` и т.п.)\n * проходят через fallthrough-attrs.\n */\nimport { computed, markRaw, useAttrs, type Component } from 'vue'\n\nimport {\n baseRootClass,\n focusRingClass,\n type GrLinkSize,\n type GrLinkUnderline,\n type GrLinkVariant,\n grLinkClass,\n} from './grLinkStyles'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = withDefaults(defineProps<{\n /**\n * Кастомный корневой тег/компонент. Если передан и компонент не `disabled` —\n * рендерится через `<component :is=\"as\">`. Игнорируется при `disabled`.\n */\n as?: string | Component\n href?: string\n external?: boolean\n target?: string\n rel?: string\n disabled?: boolean\n ariaLabel?: string\n variant?: GrLinkVariant\n underline?: GrLinkUnderline\n size?: GrLinkSize\n}>(), {\n as: undefined,\n href: undefined,\n external: false,\n target: undefined,\n rel: undefined,\n disabled: false,\n ariaLabel: undefined,\n variant: 'primary',\n underline: 'auto',\n size: 'md',\n})\n\nconst attrs = useAttrs()\n\n// Кастомный корень имеет приоритет над `<a>` — DS не пытается угадывать\n// «правильный» тег за пользователя, если он явно его указал.\nconst isInteractive = computed(() => !props.disabled && (!!props.as || !!props.href))\n\nconst renderAs = computed<string | Component>(() => {\n if (!isInteractive.value) return 'span'\n if (props.as) {\n // Если `as` — объект-компонент, помечаем его как нереактивный, чтобы избежать\n // оверхеда от Vue-прокси и предупреждений в консоли. Строки (нативные теги)\n // оставляем как есть.\n return typeof props.as === 'string' ? props.as : markRaw(props.as)\n }\n return 'a'\n})\n\nconst resolvedTarget = computed(() => {\n if (props.target)\n return props.target\n\n if (props.external)\n return '_blank'\n\n return undefined\n})\n\nconst resolvedRel = computed(() => {\n if (props.rel)\n return props.rel\n\n // Авто-защита для любых ссылок, открывающихся в новой вкладке,\n // а не только когда выставлен `external`.\n if (resolvedTarget.value === '_blank')\n return 'noopener noreferrer'\n\n return undefined\n})\n\nconst rootClass = computed(() => {\n const variantClass = grLinkClass({\n size: props.size,\n underline: props.underline,\n variant: props.variant,\n disabled: props.disabled,\n })\n\n // На disabled-ветке (`<span>`) focus-ring не нужен: элемент не фокусируется,\n // а если снаружи ему навесят `tabindex`, фокус-рамка на «отключённой» ссылке смотрелась бы странно.\n return props.disabled\n ? `${baseRootClass} ${variantClass}`\n : `${baseRootClass} ${focusRingClass} ${variantClass}`\n})\n</script>\n\n<template>\n <component\n :is=\"renderAs\"\n v-bind=\"attrs\"\n :href=\"isInteractive ? href : undefined\"\n :target=\"isInteractive ? resolvedTarget : undefined\"\n :rel=\"isInteractive ? resolvedRel : undefined\"\n :aria-label=\"ariaLabel\"\n :aria-disabled=\"disabled ? 'true' : undefined\"\n :class=\"rootClass\"\n >\n <slot />\n </component>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkCA,MAAM,QAAQ;EA4Bd,MAAM,QAAQ,UAAS;EAIvB,MAAM,gBAAgB,eAAe,CAAC,MAAM,aAAa,CAAC,CAAC,MAAM,MAAM,CAAC,CAAC,MAAM,MAAK;EAEpF,MAAM,WAAW,eAAmC;AAClD,OAAI,CAAC,cAAc,MAAO,QAAO;AACjC,OAAI,MAAM,GAIR,QAAO,OAAO,MAAM,OAAO,WAAW,MAAM,KAAK,QAAQ,MAAM,GAAE;AAEnE,UAAO;IACR;EAED,MAAM,iBAAiB,eAAe;AACpC,OAAI,MAAM,OACR,QAAO,MAAM;AAEf,OAAI,MAAM,SACR,QAAO;IAGV;EAED,MAAM,cAAc,eAAe;AACjC,OAAI,MAAM,IACR,QAAO,MAAM;AAIf,OAAI,eAAe,UAAU,SAC3B,QAAO;IAGV;EAED,MAAM,YAAY,eAAe;GAC/B,MAAM,eAAe,YAAY;IAC/B,MAAM,MAAM;IACZ,WAAW,MAAM;IACjB,SAAS,MAAM;IACf,UAAU,MAAM;IACjB,CAAA;AAID,UAAO,MAAM,WACT,GAAG,cAAc,GAAG,iBACpB,GAAG,cAAc,GAAG,eAAe,GAAG;IAC3C;;uBAIC,YAWY,wBAVL,SAAA,MAAQ,EADf,WAEU,MASE,MATG,EAAA;IACZ,MAAM,cAAA,QAAgB,QAAA,OAAO,KAAA;IAC7B,QAAQ,cAAA,QAAgB,eAAA,QAAiB,KAAA;IACzC,KAAK,cAAA,QAAgB,YAAA,QAAc,KAAA;IACnC,cAAY,QAAA;IACZ,iBAAe,QAAA,WAAQ,SAAY,KAAA;IACnC,OAAO,UAAA;;2BAEA,CAAR,WAAQ,KAAA,QAAA,UAAA,CAAA,CAAA"}
@@ -1,3 +1,3 @@
1
- import { n as grLinkSafelist, t as grLinkConfig } from "../../chunks/config-CjEplP6D.js";
2
- import { t as GrLink_default } from "./chunks/GrLink-BLPigqij.js";
1
+ import { n as grLinkSafelist, t as grLinkConfig } from "../../chunks/config-CpMYmvVT.js";
2
+ import { t as GrLink_default } from "./chunks/GrLink-BMwn2iJ9.js";
3
3
  export { GrLink_default as GrLink, GrLink_default as default, grLinkConfig, grLinkSafelist };
@@ -1 +1 @@
1
- {"version":3,"file":"GrList-C2GpK56-.js","names":["$slots"],"sources":["../../../../src/components/GrList/GrList.vue","../../../../src/components/GrList/GrList.vue","../../../../src/components/GrList/GrListItem.vue","../../../../src/components/GrList/GrListItem.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport GrCard from '../GrCard'\n\nexport interface GrListProps {\n /** Показывать ли горизонтальные разделители между элементами (по умолчанию — да). */\n divided?: boolean\n}\n\nwithDefaults(defineProps<GrListProps>(), {\n divided: true,\n})\n</script>\n\n<template>\n <GrCard>\n <div\n v-if=\"divided\"\n role=\"list\"\n class=\"divide-y divide-[var(--brd)]\"\n >\n <slot />\n </div>\n <div\n v-else\n role=\"list\"\n >\n <slot />\n </div>\n </GrCard>\n</template>","<script setup lang=\"ts\">\nimport GrCard from '../GrCard'\n\nexport interface GrListProps {\n /** Показывать ли горизонтальные разделители между элементами (по умолчанию — да). */\n divided?: boolean\n}\n\nwithDefaults(defineProps<GrListProps>(), {\n divided: true,\n})\n</script>\n\n<template>\n <GrCard>\n <div\n v-if=\"divided\"\n role=\"list\"\n class=\"divide-y divide-[var(--brd)]\"\n >\n <slot />\n </div>\n <div\n v-else\n role=\"list\"\n >\n <slot />\n </div>\n </GrCard>\n</template>","<script setup lang=\"ts\">\nimport { computed, useSlots } from 'vue'\n\nexport type GrListItemDensity = 'compact' | 'regular'\n\nexport interface GrListItemProps {\n /** Заголовок строки. Если передан слот `#title`, проп игнорируется. */\n title?: string\n /** Описание под заголовком. Если передан слот `#description`, проп игнорируется. */\n description?: string\n /** Плотность вертикальных отступов: `regular` — 12px, `compact` — 8px. */\n density?: GrListItemDensity\n}\n\nconst props = withDefaults(defineProps<GrListItemProps>(), {\n title: undefined,\n description: undefined,\n density: 'regular',\n})\n\nconst slots = useSlots()\n\nconst paddingClass = computed(() =>\n props.density === 'compact' ? 'px-4 py-2' : 'px-4 py-3',\n)\n\nconst hasTitle = computed(() => !!slots.title || !!props.title)\nconst hasDescription = computed(() => !!slots.description || !!props.description)\n</script>\n\n<template>\n <div\n role=\"listitem\"\n class=\"flex items-start justify-between gap-4\"\n :class=\"paddingClass\"\n >\n <div v-if=\"$slots.prefix\" class=\"shrink-0\">\n <slot name=\"prefix\" />\n </div>\n <div class=\"min-w-0 flex-1\">\n <div v-if=\"hasTitle\" class=\"text-[13px] font-700\">\n <slot name=\"title\">\n{{ title }}\n</slot>\n </div>\n <div\n v-if=\"hasDescription\"\n class=\"text-[13px] text-[var(--muted-fg)] mt-0.5\"\n >\n <slot name=\"description\">\n{{ description }}\n</slot>\n </div>\n </div>\n <div v-if=\"$slots.default\" class=\"shrink-0\">\n <slot />\n </div>\n </div>\n</template>","<script setup lang=\"ts\">\nimport { computed, useSlots } from 'vue'\n\nexport type GrListItemDensity = 'compact' | 'regular'\n\nexport interface GrListItemProps {\n /** Заголовок строки. Если передан слот `#title`, проп игнорируется. */\n title?: string\n /** Описание под заголовком. Если передан слот `#description`, проп игнорируется. */\n description?: string\n /** Плотность вертикальных отступов: `regular` — 12px, `compact` — 8px. */\n density?: GrListItemDensity\n}\n\nconst props = withDefaults(defineProps<GrListItemProps>(), {\n title: undefined,\n description: undefined,\n density: 'regular',\n})\n\nconst slots = useSlots()\n\nconst paddingClass = computed(() =>\n props.density === 'compact' ? 'px-4 py-2' : 'px-4 py-3',\n)\n\nconst hasTitle = computed(() => !!slots.title || !!props.title)\nconst hasDescription = computed(() => !!slots.description || !!props.description)\n</script>\n\n<template>\n <div\n role=\"listitem\"\n class=\"flex items-start justify-between gap-4\"\n :class=\"paddingClass\"\n >\n <div v-if=\"$slots.prefix\" class=\"shrink-0\">\n <slot name=\"prefix\" />\n </div>\n <div class=\"min-w-0 flex-1\">\n <div v-if=\"hasTitle\" class=\"text-[13px] font-700\">\n <slot name=\"title\">\n{{ title }}\n</slot>\n </div>\n <div\n v-if=\"hasDescription\"\n class=\"text-[13px] text-[var(--muted-fg)] mt-0.5\"\n >\n <slot name=\"description\">\n{{ description }}\n</slot>\n </div>\n </div>\n <div v-if=\"$slots.default\" class=\"shrink-0\">\n <slot />\n </div>\n </div>\n</template>"],"mappings":";;;;;;;;;;;;;;;;;;;;;;uBAcE,YAcS,MAAA,eAAA,EAAA,MAAA;2BAPD,CALE,QAAA,WAAA,WAAA,EADR,mBAMM,OANN,cAMM,CADJ,WAAQ,KAAA,QAAA,UAAA,CAAA,CAAA,KAAA,WAAA,EAEV,mBAKM,OALN,cAKM,CADJ,WAAQ,KAAA,QAAA,UAAA,CAAA,CAAA,EAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EEZd,MAAM,QAAQ;EAMd,MAAM,QAAQ,UAAS;EAEvB,MAAM,eAAe,eACnB,MAAM,YAAY,YAAY,cAAc,YAC9C;EAEA,MAAM,WAAW,eAAe,CAAC,CAAC,MAAM,SAAS,CAAC,CAAC,MAAM,MAAK;EAC9D,MAAM,iBAAiB,eAAe,CAAC,CAAC,MAAM,eAAe,CAAC,CAAC,MAAM,YAAW;;uBAI9E,mBA0BM,OAAA;IAzBJ,MAAK;IACL,OAAK,eAAA,CAAC,0CACE,aAAA,MAAY,CAAA;;IAETA,KAAAA,OAAO,UAAA,WAAA,EAAlB,mBAEM,OAFN,YAEM,CADJ,WAAsB,KAAA,QAAA,SAAA,CAAA,CAAA,IAAA,mBAAA,IAAA,KAAA;IAExB,mBAcM,OAdN,YAcM,CAbO,SAAA,SAAA,WAAA,EAAX,mBAIM,OAJN,YAIM,CAHJ,WAED,KAAA,QAAA,SAAA,EAAA,QAAA,CAAA,gBAAA,gBADJ,QAAA,MAAK,EAAA,EAAA,CAAA,CAAA,CAAA,CAAA,IAAA,mBAAA,IAAA,KAAA,EAIM,eAAA,SAAA,WAAA,EADR,mBAOM,OAPN,YAOM,CAHJ,WAED,KAAA,QAAA,eAAA,EAAA,QAAA,CAAA,gBAAA,gBADJ,QAAA,YAAW,EAAA,EAAA,CAAA,CAAA,CAAA,CAAA,IAAA,mBAAA,IAAA,KAAA,CAAA,CAAA;IAICA,KAAAA,OAAO,WAAA,WAAA,EAAlB,mBAEM,OAFN,YAEM,CADJ,WAAQ,KAAA,QAAA,UAAA,CAAA,CAAA,IAAA,mBAAA,IAAA,KAAA"}
1
+ {"version":3,"file":"GrList-D8nM1FuV.js","names":["$slots"],"sources":["../../../../src/components/GrList/GrList.vue","../../../../src/components/GrList/GrList.vue","../../../../src/components/GrList/GrListItem.vue","../../../../src/components/GrList/GrListItem.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport GrCard from '../GrCard'\n\nexport interface GrListProps {\n /** Показывать ли горизонтальные разделители между элементами (по умолчанию — да). */\n divided?: boolean\n}\n\nwithDefaults(defineProps<GrListProps>(), {\n divided: true,\n})\n</script>\n\n<template>\n <GrCard>\n <div\n v-if=\"divided\"\n role=\"list\"\n class=\"divide-y divide-[var(--brd)]\"\n >\n <slot />\n </div>\n <div\n v-else\n role=\"list\"\n >\n <slot />\n </div>\n </GrCard>\n</template>","<script setup lang=\"ts\">\nimport GrCard from '../GrCard'\n\nexport interface GrListProps {\n /** Показывать ли горизонтальные разделители между элементами (по умолчанию — да). */\n divided?: boolean\n}\n\nwithDefaults(defineProps<GrListProps>(), {\n divided: true,\n})\n</script>\n\n<template>\n <GrCard>\n <div\n v-if=\"divided\"\n role=\"list\"\n class=\"divide-y divide-[var(--brd)]\"\n >\n <slot />\n </div>\n <div\n v-else\n role=\"list\"\n >\n <slot />\n </div>\n </GrCard>\n</template>","<script setup lang=\"ts\">\nimport { computed, useSlots } from 'vue'\n\nexport type GrListItemDensity = 'compact' | 'regular'\n\nexport interface GrListItemProps {\n /** Заголовок строки. Если передан слот `#title`, проп игнорируется. */\n title?: string\n /** Описание под заголовком. Если передан слот `#description`, проп игнорируется. */\n description?: string\n /** Плотность вертикальных отступов: `regular` — 12px, `compact` — 8px. */\n density?: GrListItemDensity\n}\n\nconst props = withDefaults(defineProps<GrListItemProps>(), {\n title: undefined,\n description: undefined,\n density: 'regular',\n})\n\nconst slots = useSlots()\n\nconst paddingClass = computed(() =>\n props.density === 'compact' ? 'px-4 py-2' : 'px-4 py-3',\n)\n\nconst hasTitle = computed(() => !!slots.title || !!props.title)\nconst hasDescription = computed(() => !!slots.description || !!props.description)\n</script>\n\n<template>\n <div\n role=\"listitem\"\n class=\"flex items-start justify-between gap-4\"\n :class=\"paddingClass\"\n >\n <div v-if=\"$slots.prefix\" class=\"shrink-0\">\n <slot name=\"prefix\" />\n </div>\n <div class=\"min-w-0 flex-1\">\n <div v-if=\"hasTitle\" class=\"text-[13px] font-700\">\n <slot name=\"title\">\n{{ title }}\n</slot>\n </div>\n <div\n v-if=\"hasDescription\"\n class=\"text-[13px] text-[var(--muted-fg)] mt-0.5\"\n >\n <slot name=\"description\">\n{{ description }}\n</slot>\n </div>\n </div>\n <div v-if=\"$slots.default\" class=\"shrink-0\">\n <slot />\n </div>\n </div>\n</template>","<script setup lang=\"ts\">\nimport { computed, useSlots } from 'vue'\n\nexport type GrListItemDensity = 'compact' | 'regular'\n\nexport interface GrListItemProps {\n /** Заголовок строки. Если передан слот `#title`, проп игнорируется. */\n title?: string\n /** Описание под заголовком. Если передан слот `#description`, проп игнорируется. */\n description?: string\n /** Плотность вертикальных отступов: `regular` — 12px, `compact` — 8px. */\n density?: GrListItemDensity\n}\n\nconst props = withDefaults(defineProps<GrListItemProps>(), {\n title: undefined,\n description: undefined,\n density: 'regular',\n})\n\nconst slots = useSlots()\n\nconst paddingClass = computed(() =>\n props.density === 'compact' ? 'px-4 py-2' : 'px-4 py-3',\n)\n\nconst hasTitle = computed(() => !!slots.title || !!props.title)\nconst hasDescription = computed(() => !!slots.description || !!props.description)\n</script>\n\n<template>\n <div\n role=\"listitem\"\n class=\"flex items-start justify-between gap-4\"\n :class=\"paddingClass\"\n >\n <div v-if=\"$slots.prefix\" class=\"shrink-0\">\n <slot name=\"prefix\" />\n </div>\n <div class=\"min-w-0 flex-1\">\n <div v-if=\"hasTitle\" class=\"text-[13px] font-700\">\n <slot name=\"title\">\n{{ title }}\n</slot>\n </div>\n <div\n v-if=\"hasDescription\"\n class=\"text-[13px] text-[var(--muted-fg)] mt-0.5\"\n >\n <slot name=\"description\">\n{{ description }}\n</slot>\n </div>\n </div>\n <div v-if=\"$slots.default\" class=\"shrink-0\">\n <slot />\n </div>\n </div>\n</template>"],"mappings":";;;;;;;;;;;;;;;;;;;;;;uBAcE,YAcS,MAAA,eAAA,EAAA,MAAA;2BAPD,CALE,QAAA,WAAA,WAAA,EADR,mBAMM,OANN,cAMM,CADJ,WAAQ,KAAA,QAAA,UAAA,CAAA,CAAA,KAAA,WAAA,EAEV,mBAKM,OALN,cAKM,CADJ,WAAQ,KAAA,QAAA,UAAA,CAAA,CAAA,EAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EEZd,MAAM,QAAQ;EAMd,MAAM,QAAQ,UAAS;EAEvB,MAAM,eAAe,eACnB,MAAM,YAAY,YAAY,cAAc,YAC9C;EAEA,MAAM,WAAW,eAAe,CAAC,CAAC,MAAM,SAAS,CAAC,CAAC,MAAM,MAAK;EAC9D,MAAM,iBAAiB,eAAe,CAAC,CAAC,MAAM,eAAe,CAAC,CAAC,MAAM,YAAW;;uBAI9E,mBA0BM,OAAA;IAzBJ,MAAK;IACL,OAAK,eAAA,CAAC,0CACE,aAAA,MAAY,CAAA;;IAETA,KAAAA,OAAO,UAAA,WAAA,EAAlB,mBAEM,OAFN,YAEM,CADJ,WAAsB,KAAA,QAAA,SAAA,CAAA,CAAA,IAAA,mBAAA,IAAA,KAAA;IAExB,mBAcM,OAdN,YAcM,CAbO,SAAA,SAAA,WAAA,EAAX,mBAIM,OAJN,YAIM,CAHJ,WAED,KAAA,QAAA,SAAA,EAAA,QAAA,CAAA,gBAAA,gBADJ,QAAA,MAAK,EAAA,EAAA,CAAA,CAAA,CAAA,CAAA,IAAA,mBAAA,IAAA,KAAA,EAIM,eAAA,SAAA,WAAA,EADR,mBAOM,OAPN,YAOM,CAHJ,WAED,KAAA,QAAA,eAAA,EAAA,QAAA,CAAA,gBAAA,gBADJ,QAAA,YAAW,EAAA,EAAA,CAAA,CAAA,CAAA,CAAA,IAAA,mBAAA,IAAA,KAAA,CAAA,CAAA;IAICA,KAAAA,OAAO,WAAA,WAAA,EAAlB,mBAEM,OAFN,YAEM,CADJ,WAAQ,KAAA,QAAA,UAAA,CAAA,CAAA,IAAA,mBAAA,IAAA,KAAA"}
@@ -1,3 +1,3 @@
1
- import { n as GrList_default, t as GrListItem_default } from "./chunks/GrList-C2GpK56-.js";
2
- import { t as grListConfig } from "../../chunks/config-C4qAA0Sb.js";
1
+ import { n as GrList_default, t as GrListItem_default } from "./chunks/GrList-D8nM1FuV.js";
2
+ import { t as grListConfig } from "../../chunks/config-DSBlHQVa.js";
3
3
  export { GrList_default as GrList, GrList_default as default, GrListItem_default as GrListItem, grListConfig };
@@ -1,5 +1,5 @@
1
1
  import { t as loader_circle_default } from "../../../chunks/loader-circle-BUntgosj.js";
2
- import { t as grLoadingRootClass } from "../../../chunks/grLoadingStyles-CrxZHFL0.js";
2
+ import { t as grLoadingRootClass } from "../../../chunks/grLoadingStyles-DmI-SJ3i.js";
3
3
  import { computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, defineComponent, normalizeClass, normalizeStyle, openBlock, resolveDynamicComponent, toDisplayString } from "vue";
4
4
  import '../../../GrLoading.css';//#region src/components/GrLoading/GrLoading.vue?vue&type=script&setup=true&lang.ts
5
5
  var _hoisted_1 = {
@@ -1 +1 @@
1
- {"version":3,"file":"GrLoading-CxNgHgNw.js","names":[],"sources":["../../../../src/components/GrLoading/GrLoading.vue","../../../../src/components/GrLoading/GrLoading.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, type Component } from 'vue'\n\nimport IconLoader from '~icons/lucide/loader-circle'\n\nimport { grLoadingRootClass } from './grLoadingStyles'\n\nconst DEFAULT_LOADING_TEXT = 'Loading...'\n\n/**\n * Props for {@link GrLoading}.\n * Overlay primitive that renders a centered spinner with optional text above sibling content.\n * Use `fullscreen` to cover the whole viewport, otherwise overlays the nearest positioned ancestor.\n */\nexport interface GrLoadingProps {\n /** Text under the spinner. Pass an empty string to hide the text entirely. Defaults to `'Loading...'`. */\n text?: string\n /** Custom spinner component (rendered instead of the default loader icon). */\n spinner?: Component\n /** Extra classes for the spinner element. */\n spinnerClass?: string\n /** When `true` (default), the default spinner rotates via `@keyframes ds-loading-spin`. */\n animated?: boolean\n /** Custom CSS `background-color`. When set, disables the default `bg-black/25` dim. */\n background?: string\n /** Cover the whole viewport (`position: fixed`) instead of the nearest positioned ancestor. */\n fullscreen?: boolean\n /** Custom `z-index`. */\n zIndex?: number\n /** Extra classes appended to the overlay root. */\n customClass?: string\n}\n\nconst props = withDefaults(\n defineProps<GrLoadingProps>(),\n {\n text: undefined,\n spinner: undefined,\n spinnerClass: undefined,\n animated: true,\n background: undefined,\n fullscreen: false,\n zIndex: undefined,\n customClass: undefined,\n },\n)\n\nconst Spinner = computed(() => props.spinner ?? IconLoader)\n\nconst displayText = computed(() => props.text ?? DEFAULT_LOADING_TEXT)\n\nconst rootClass = computed(() => {\n return grLoadingRootClass({\n fullscreen: props.fullscreen,\n hasBackground: props.background !== undefined,\n customClass: props.customClass,\n })\n})\n\nconst rootStyle = computed(() => {\n return {\n backgroundColor: props.background,\n zIndex: props.zIndex != null ? String(props.zIndex) : undefined,\n } as Record<string, string | undefined>\n})\n\nconst spinnerClassName = computed(() => props.spinnerClass)\n</script>\n\n<template>\n <div\n data-ds-loading\n class=\"flex items-center justify-center cursor-wait select-none pointer-events-auto\"\n :class=\"rootClass\"\n :style=\"rootStyle\"\n role=\"status\"\n aria-live=\"polite\"\n >\n <div\n data-ds-loading-panel\n class=\"flex flex-col items-center justify-center gap-2 text-center rounded-lg bg-[var(--bg)]/55 px-5 py-4 shadow-lg\"\n >\n <component\n :is=\"Spinner\"\n data-ds-loading-spinner\n class=\"ds-loading__spinner h-7 w-7 text-[var(--muted-fg)]\"\n :class=\"[animated ? 'ds-loading__spinner--animated' : '', spinnerClassName]\"\n aria-hidden=\"true\"\n />\n <div v-if=\"displayText\" data-ds-loading-text class=\"text-sm text-[var(--muted-fg)]\">\n {{ displayText }}\n </div>\n </div>\n </div>\n</template>\n\n<style>\n@keyframes ds-loading-spin {\n to {\n transform: rotate(360deg);\n }\n}\n.ds-loading__spinner--animated {\n transform-origin: center;\n animation: ds-loading-spin 1s linear infinite;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, type Component } from 'vue'\n\nimport IconLoader from '~icons/lucide/loader-circle'\n\nimport { grLoadingRootClass } from './grLoadingStyles'\n\nconst DEFAULT_LOADING_TEXT = 'Loading...'\n\n/**\n * Props for {@link GrLoading}.\n * Overlay primitive that renders a centered spinner with optional text above sibling content.\n * Use `fullscreen` to cover the whole viewport, otherwise overlays the nearest positioned ancestor.\n */\nexport interface GrLoadingProps {\n /** Text under the spinner. Pass an empty string to hide the text entirely. Defaults to `'Loading...'`. */\n text?: string\n /** Custom spinner component (rendered instead of the default loader icon). */\n spinner?: Component\n /** Extra classes for the spinner element. */\n spinnerClass?: string\n /** When `true` (default), the default spinner rotates via `@keyframes ds-loading-spin`. */\n animated?: boolean\n /** Custom CSS `background-color`. When set, disables the default `bg-black/25` dim. */\n background?: string\n /** Cover the whole viewport (`position: fixed`) instead of the nearest positioned ancestor. */\n fullscreen?: boolean\n /** Custom `z-index`. */\n zIndex?: number\n /** Extra classes appended to the overlay root. */\n customClass?: string\n}\n\nconst props = withDefaults(\n defineProps<GrLoadingProps>(),\n {\n text: undefined,\n spinner: undefined,\n spinnerClass: undefined,\n animated: true,\n background: undefined,\n fullscreen: false,\n zIndex: undefined,\n customClass: undefined,\n },\n)\n\nconst Spinner = computed(() => props.spinner ?? IconLoader)\n\nconst displayText = computed(() => props.text ?? DEFAULT_LOADING_TEXT)\n\nconst rootClass = computed(() => {\n return grLoadingRootClass({\n fullscreen: props.fullscreen,\n hasBackground: props.background !== undefined,\n customClass: props.customClass,\n })\n})\n\nconst rootStyle = computed(() => {\n return {\n backgroundColor: props.background,\n zIndex: props.zIndex != null ? String(props.zIndex) : undefined,\n } as Record<string, string | undefined>\n})\n\nconst spinnerClassName = computed(() => props.spinnerClass)\n</script>\n\n<template>\n <div\n data-ds-loading\n class=\"flex items-center justify-center cursor-wait select-none pointer-events-auto\"\n :class=\"rootClass\"\n :style=\"rootStyle\"\n role=\"status\"\n aria-live=\"polite\"\n >\n <div\n data-ds-loading-panel\n class=\"flex flex-col items-center justify-center gap-2 text-center rounded-lg bg-[var(--bg)]/55 px-5 py-4 shadow-lg\"\n >\n <component\n :is=\"Spinner\"\n data-ds-loading-spinner\n class=\"ds-loading__spinner h-7 w-7 text-[var(--muted-fg)]\"\n :class=\"[animated ? 'ds-loading__spinner--animated' : '', spinnerClassName]\"\n aria-hidden=\"true\"\n />\n <div v-if=\"displayText\" data-ds-loading-text class=\"text-sm text-[var(--muted-fg)]\">\n {{ displayText }}\n </div>\n </div>\n </div>\n</template>\n\n<style>\n@keyframes ds-loading-spin {\n to {\n transform: rotate(360deg);\n }\n}\n.ds-loading__spinner--animated {\n transform-origin: center;\n animation: ds-loading-spin 1s linear infinite;\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;AAOA,IAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;EA0B7B,MAAM,QAAQ;EAcd,MAAM,UAAU,eAAe,MAAM,WAAW,sBAAU;EAE1D,MAAM,cAAc,eAAe,MAAM,QAAQ,qBAAoB;EAErE,MAAM,YAAY,eAAe;AAC/B,UAAO,mBAAmB;IACxB,YAAY,MAAM;IAClB,eAAe,MAAM,eAAe,KAAA;IACpC,aAAa,MAAM;IACpB,CAAA;IACF;EAED,MAAM,YAAY,eAAe;AAC/B,UAAO;IACL,iBAAiB,MAAM;IACvB,QAAQ,MAAM,UAAU,OAAO,OAAO,MAAM,OAAO,GAAG,KAAA;IACvD;IACF;EAED,MAAM,mBAAmB,eAAe,MAAM,aAAY;;uBAIxD,mBAuBM,OAAA;IAtBJ,mBAAA;IACA,OAAK,eAAA,CAAC,gFACE,UAAA,MAAS,CAAA;IAChB,OAAK,eAAE,UAAA,MAAS;IACjB,MAAK;IACL,aAAU;OAEV,mBAcM,OAdN,YAcM,EAAA,WAAA,EAVJ,YAME,wBALK,QAAA,MAAO,EAAA;IACZ,2BAAA;IACA,OAAK,eAAA,CAAC,sDAAoD,CACjD,QAAA,WAAQ,kCAAA,IAAyC,iBAAA,MAAgB,CAAA,CAAA;IAC1E,eAAY;4BAEH,YAAA,SAAA,WAAA,EAAX,mBAEM,OAFN,YAEM,gBADD,YAAA,MAAW,EAAA,EAAA,IAAA,mBAAA,IAAA,KAAA,CAAA,CAAA,CAAA,EAAA,EAAA"}
1
+ {"version":3,"file":"GrLoading-mfyfghxs.js","names":[],"sources":["../../../../src/components/GrLoading/GrLoading.vue","../../../../src/components/GrLoading/GrLoading.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, type Component } from 'vue'\n\nimport IconLoader from '~icons/lucide/loader-circle'\n\nimport { grLoadingRootClass } from './grLoadingStyles'\n\nconst DEFAULT_LOADING_TEXT = 'Loading...'\n\n/**\n * Props for {@link GrLoading}.\n * Overlay primitive that renders a centered spinner with optional text above sibling content.\n * Use `fullscreen` to cover the whole viewport, otherwise overlays the nearest positioned ancestor.\n */\nexport interface GrLoadingProps {\n /** Text under the spinner. Pass an empty string to hide the text entirely. Defaults to `'Loading...'`. */\n text?: string\n /** Custom spinner component (rendered instead of the default loader icon). */\n spinner?: Component\n /** Extra classes for the spinner element. */\n spinnerClass?: string\n /** When `true` (default), the default spinner rotates via `@keyframes ds-loading-spin`. */\n animated?: boolean\n /** Custom CSS `background-color`. When set, disables the default `bg-black/25` dim. */\n background?: string\n /** Cover the whole viewport (`position: fixed`) instead of the nearest positioned ancestor. */\n fullscreen?: boolean\n /** Custom `z-index`. */\n zIndex?: number\n /** Extra classes appended to the overlay root. */\n customClass?: string\n}\n\nconst props = withDefaults(\n defineProps<GrLoadingProps>(),\n {\n text: undefined,\n spinner: undefined,\n spinnerClass: undefined,\n animated: true,\n background: undefined,\n fullscreen: false,\n zIndex: undefined,\n customClass: undefined,\n },\n)\n\nconst Spinner = computed(() => props.spinner ?? IconLoader)\n\nconst displayText = computed(() => props.text ?? DEFAULT_LOADING_TEXT)\n\nconst rootClass = computed(() => {\n return grLoadingRootClass({\n fullscreen: props.fullscreen,\n hasBackground: props.background !== undefined,\n customClass: props.customClass,\n })\n})\n\nconst rootStyle = computed(() => {\n return {\n backgroundColor: props.background,\n zIndex: props.zIndex != null ? String(props.zIndex) : undefined,\n } as Record<string, string | undefined>\n})\n\nconst spinnerClassName = computed(() => props.spinnerClass)\n</script>\n\n<template>\n <div\n data-ds-loading\n class=\"flex items-center justify-center cursor-wait select-none pointer-events-auto\"\n :class=\"rootClass\"\n :style=\"rootStyle\"\n role=\"status\"\n aria-live=\"polite\"\n >\n <div\n data-ds-loading-panel\n class=\"flex flex-col items-center justify-center gap-2 text-center rounded-lg bg-[var(--bg)]/55 px-5 py-4 shadow-lg\"\n >\n <component\n :is=\"Spinner\"\n data-ds-loading-spinner\n class=\"ds-loading__spinner h-7 w-7 text-[var(--muted-fg)]\"\n :class=\"[animated ? 'ds-loading__spinner--animated' : '', spinnerClassName]\"\n aria-hidden=\"true\"\n />\n <div v-if=\"displayText\" data-ds-loading-text class=\"text-sm text-[var(--muted-fg)]\">\n {{ displayText }}\n </div>\n </div>\n </div>\n</template>\n\n<style>\n@keyframes ds-loading-spin {\n to {\n transform: rotate(360deg);\n }\n}\n.ds-loading__spinner--animated {\n transform-origin: center;\n animation: ds-loading-spin 1s linear infinite;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, type Component } from 'vue'\n\nimport IconLoader from '~icons/lucide/loader-circle'\n\nimport { grLoadingRootClass } from './grLoadingStyles'\n\nconst DEFAULT_LOADING_TEXT = 'Loading...'\n\n/**\n * Props for {@link GrLoading}.\n * Overlay primitive that renders a centered spinner with optional text above sibling content.\n * Use `fullscreen` to cover the whole viewport, otherwise overlays the nearest positioned ancestor.\n */\nexport interface GrLoadingProps {\n /** Text under the spinner. Pass an empty string to hide the text entirely. Defaults to `'Loading...'`. */\n text?: string\n /** Custom spinner component (rendered instead of the default loader icon). */\n spinner?: Component\n /** Extra classes for the spinner element. */\n spinnerClass?: string\n /** When `true` (default), the default spinner rotates via `@keyframes ds-loading-spin`. */\n animated?: boolean\n /** Custom CSS `background-color`. When set, disables the default `bg-black/25` dim. */\n background?: string\n /** Cover the whole viewport (`position: fixed`) instead of the nearest positioned ancestor. */\n fullscreen?: boolean\n /** Custom `z-index`. */\n zIndex?: number\n /** Extra classes appended to the overlay root. */\n customClass?: string\n}\n\nconst props = withDefaults(\n defineProps<GrLoadingProps>(),\n {\n text: undefined,\n spinner: undefined,\n spinnerClass: undefined,\n animated: true,\n background: undefined,\n fullscreen: false,\n zIndex: undefined,\n customClass: undefined,\n },\n)\n\nconst Spinner = computed(() => props.spinner ?? IconLoader)\n\nconst displayText = computed(() => props.text ?? DEFAULT_LOADING_TEXT)\n\nconst rootClass = computed(() => {\n return grLoadingRootClass({\n fullscreen: props.fullscreen,\n hasBackground: props.background !== undefined,\n customClass: props.customClass,\n })\n})\n\nconst rootStyle = computed(() => {\n return {\n backgroundColor: props.background,\n zIndex: props.zIndex != null ? String(props.zIndex) : undefined,\n } as Record<string, string | undefined>\n})\n\nconst spinnerClassName = computed(() => props.spinnerClass)\n</script>\n\n<template>\n <div\n data-ds-loading\n class=\"flex items-center justify-center cursor-wait select-none pointer-events-auto\"\n :class=\"rootClass\"\n :style=\"rootStyle\"\n role=\"status\"\n aria-live=\"polite\"\n >\n <div\n data-ds-loading-panel\n class=\"flex flex-col items-center justify-center gap-2 text-center rounded-lg bg-[var(--bg)]/55 px-5 py-4 shadow-lg\"\n >\n <component\n :is=\"Spinner\"\n data-ds-loading-spinner\n class=\"ds-loading__spinner h-7 w-7 text-[var(--muted-fg)]\"\n :class=\"[animated ? 'ds-loading__spinner--animated' : '', spinnerClassName]\"\n aria-hidden=\"true\"\n />\n <div v-if=\"displayText\" data-ds-loading-text class=\"text-sm text-[var(--muted-fg)]\">\n {{ displayText }}\n </div>\n </div>\n </div>\n</template>\n\n<style>\n@keyframes ds-loading-spin {\n to {\n transform: rotate(360deg);\n }\n}\n.ds-loading__spinner--animated {\n transform-origin: center;\n animation: ds-loading-spin 1s linear infinite;\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;AAOA,IAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;EA0B7B,MAAM,QAAQ;EAcd,MAAM,UAAU,eAAe,MAAM,WAAW,sBAAU;EAE1D,MAAM,cAAc,eAAe,MAAM,QAAQ,qBAAoB;EAErE,MAAM,YAAY,eAAe;AAC/B,UAAO,mBAAmB;IACxB,YAAY,MAAM;IAClB,eAAe,MAAM,eAAe,KAAA;IACpC,aAAa,MAAM;IACpB,CAAA;IACF;EAED,MAAM,YAAY,eAAe;AAC/B,UAAO;IACL,iBAAiB,MAAM;IACvB,QAAQ,MAAM,UAAU,OAAO,OAAO,MAAM,OAAO,GAAG,KAAA;IACvD;IACF;EAED,MAAM,mBAAmB,eAAe,MAAM,aAAY;;uBAIxD,mBAuBM,OAAA;IAtBJ,mBAAA;IACA,OAAK,eAAA,CAAC,gFACE,UAAA,MAAS,CAAA;IAChB,OAAK,eAAE,UAAA,MAAS;IACjB,MAAK;IACL,aAAU;OAEV,mBAcM,OAdN,YAcM,EAAA,WAAA,EAVJ,YAME,wBALK,QAAA,MAAO,EAAA;IACZ,2BAAA;IACA,OAAK,eAAA,CAAC,sDAAoD,CACjD,QAAA,WAAQ,kCAAA,IAAyC,iBAAA,MAAgB,CAAA,CAAA;IAC1E,eAAY;4BAEH,YAAA,SAAA,WAAA,EAAX,mBAEM,OAFN,YAEM,gBADD,YAAA,MAAW,EAAA,EAAA,IAAA,mBAAA,IAAA,KAAA,CAAA,CAAA,CAAA,EAAA,EAAA"}
@@ -1,3 +1,3 @@
1
- import { t as GrLoading_default } from "./chunks/GrLoading-CxNgHgNw.js";
2
- import { n as grLoadingSafelist, t as grLoadingConfig } from "../../chunks/config-B44QVIge.js";
1
+ import { t as GrLoading_default } from "./chunks/GrLoading-mfyfghxs.js";
2
+ import { n as grLoadingSafelist, t as grLoadingConfig } from "../../chunks/config-d386uO3O.js";
3
3
  export { GrLoading_default as GrLoading, GrLoading_default as default, grLoadingConfig, grLoadingSafelist };
@@ -1,6 +1,47 @@
1
1
  import { a as Ve, i as Je, n as he, o as Ye, r as Ge, t as Se } from "../../../chunks/transition-mJ3PZCHH.js";
2
- import { c as panelTransition, d as shell, i as overlayTransition, n as layout, r as overlay, t as getGrModalPanelClass, u as root } from "../../../chunks/grModalStyles-Dv2NXBKi.js";
2
+ import { c as panelTransition, d as shell, i as overlayTransition, n as layout, r as overlay, t as getGrModalPanelClass, u as root } from "../../../chunks/grModalStyles-DS1Vl6EW.js";
3
3
  import { Teleport, computed, createBlock, createCommentVNode, createElementVNode, createVNode, defineComponent, normalizeClass, onBeforeUnmount, openBlock, ref, renderSlot, unref, watch, withCtx } from "vue";
4
+ //#region src/components/GrModal/grModalEscStack.ts
5
+ var stack = [];
6
+ var listening = false;
7
+ var nextId = 1;
8
+ function handleKeydown(event) {
9
+ if (event.key !== "Escape") return;
10
+ if (stack.length === 0) return;
11
+ const top = stack[stack.length - 1];
12
+ event.preventDefault();
13
+ event.stopPropagation();
14
+ if (typeof event.stopImmediatePropagation === "function") event.stopImmediatePropagation();
15
+ if (top.shouldClose()) top.close();
16
+ }
17
+ function startListening() {
18
+ if (listening) return;
19
+ if (typeof window === "undefined") return;
20
+ window.addEventListener("keydown", handleKeydown, true);
21
+ listening = true;
22
+ }
23
+ function stopListening() {
24
+ if (!listening) return;
25
+ if (typeof window === "undefined") return;
26
+ window.removeEventListener("keydown", handleKeydown, true);
27
+ listening = false;
28
+ }
29
+ /** Регистрирует открытую модалку как верхнюю и возвращает её id. */
30
+ function pushGrModalEsc(entry) {
31
+ const id = nextId++;
32
+ stack.push({
33
+ ...entry,
34
+ id
35
+ });
36
+ startListening();
37
+ return id;
38
+ }
39
+ /** Снимает модалку со стека (при закрытии или размонтировании). */
40
+ function removeGrModalEsc(id) {
41
+ const index = stack.findIndex((item) => item.id === id);
42
+ if (index >= 0) stack.splice(index, 1);
43
+ if (stack.length === 0) stopListening();
44
+ }
4
45
  //#endregion
5
46
  //#region src/components/GrModal/GrModal.vue
6
47
  var GrModal_default = /* @__PURE__ */ defineComponent({
@@ -31,9 +72,13 @@ var GrModal_default = /* @__PURE__ */ defineComponent({
31
72
  * `DialogTitle` / `DialogDescription` (связь через `aria-labelledby` /
32
73
  * `aria-describedby` ставится HeadlessUI автоматически).
33
74
  *
34
- * Esc обрабатывается штатно через событие `@close` у HeadlessUI `<Dialog>`,
35
- * чтобы не конфликтовать с его внутренней логикой. Источник закрытия
36
- * различается через ref `closeReasonRef`.
75
+ * Esc обрабатывается через общий стек открытых модалок (`grModalEscStack`):
76
+ * единый capture-обработчик на `window` закрывает только верхнюю (последнюю
77
+ * открытую) модалку и опережает window-обработчик Escape HeadlessUI. Это
78
+ * чинит кейс, когда поверх `GrModal` открыт диалог `useDialogService` (другое
79
+ * дерево рендера): Esc закрывает именно верхний диалог, а не нижнее окно.
80
+ * Клик по оверлею (backdrop) по-прежнему идёт через `@close` HeadlessUI;
81
+ * источник закрытия различается через ref `closeReason`.
37
82
  */
38
83
  const props = __props;
39
84
  const emit = __emit;
@@ -55,6 +100,19 @@ var GrModal_default = /* @__PURE__ */ defineComponent({
55
100
  function onRootKeydown(event) {
56
101
  if (event.key === "Escape") closeReason.value = "esc";
57
102
  }
103
+ let escEntryId = null;
104
+ function registerEsc() {
105
+ if (escEntryId !== null) return;
106
+ escEntryId = pushGrModalEsc({
107
+ shouldClose: () => props.closeOnEsc,
108
+ close
109
+ });
110
+ }
111
+ function unregisterEsc() {
112
+ if (escEntryId === null) return;
113
+ removeGrModalEsc(escEntryId);
114
+ escEntryId = null;
115
+ }
58
116
  function onOverlayPointerDown() {
59
117
  closeReason.value = "backdrop";
60
118
  }
@@ -72,10 +130,18 @@ var GrModal_default = /* @__PURE__ */ defineComponent({
72
130
  savedBodyOverflow = null;
73
131
  }
74
132
  watch(() => props.modelValue, (value) => {
75
- if (value) lockBodyScroll();
76
- else unlockBodyScroll();
133
+ if (value) {
134
+ lockBodyScroll();
135
+ registerEsc();
136
+ } else {
137
+ unlockBodyScroll();
138
+ unregisterEsc();
139
+ }
77
140
  }, { immediate: true });
78
- onBeforeUnmount(unlockBodyScroll);
141
+ onBeforeUnmount(() => {
142
+ unlockBodyScroll();
143
+ unregisterEsc();
144
+ });
79
145
  return (_ctx, _cache) => {
80
146
  return openBlock(), createBlock(Teleport, {
81
147
  to: "body",
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GrModal-2ALC3kwy.js","names":["$slots"],"sources":["../../../../src/components/GrModal/grModalEscStack.ts","../../../../src/components/GrModal/GrModal.vue","../../../../src/components/GrModal/GrModal.vue"],"sourcesContent":["/**\n * grModalEscStack — общий стек открытых `GrModal` для корректной обработки Esc.\n *\n * Зачем нужен:\n * HeadlessUI вешает обработчик Escape на `window` у каждого открытого `<Dialog>`.\n * Когда модалки рендерятся в разных деревьях приложения (например, диалоги\n * `useDialogService` монтируются отдельным `render()` в `document.body`), их\n * HeadlessUI-стек не общий, и каждый `<Dialog>` считает себя верхним. В итоге\n * Esc перехватывает обработчик той модалки, что смонтирована раньше (нижней),\n * а реально верхнее окно (последнее открытое) остаётся.\n *\n * Решение: единый capture-обработчик на `window`, который срабатывает раньше\n * обработчиков HeadlessUI, гасит событие (`stopImmediatePropagation`) и\n * закрывает только верхнюю (последнюю зарегистрированную) модалку. Так Esc\n * всегда адресуется верхнему окну независимо от дерева рендера.\n */\n\nexport interface GrModalEscEntry {\n /** Уникальный id зарегистрированной модалки. */\n id: number\n /** Должна ли модалка закрываться по Esc (реактивный геттер `closeOnEsc`). */\n shouldClose: () => boolean\n /** Закрыть модалку (эмит `update:modelValue=false`). */\n close: () => void\n}\n\nconst stack: GrModalEscEntry[] = []\nlet listening = false\nlet nextId = 1\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (event.key !== 'Escape') return\n if (stack.length === 0) return\n\n // Верхняя модалка — последняя зарегистрированная.\n const top = stack[stack.length - 1]\n\n // Перехватываем Esc раньше HeadlessUI и нижних модалок: даже если верхнее\n // окно не закрывается (`closeOnEsc=false`), событие не должно «проваливаться»\n // к нижним окнам.\n event.preventDefault()\n event.stopPropagation()\n if (typeof event.stopImmediatePropagation === 'function')\n event.stopImmediatePropagation()\n\n if (top.shouldClose()) top.close()\n}\n\nfunction startListening(): void {\n if (listening) return\n if (typeof window === 'undefined') return\n // Capture-фаза, чтобы опередить window-обработчик Escape HeadlessUI.\n window.addEventListener('keydown', handleKeydown, true)\n listening = true\n}\n\nfunction stopListening(): void {\n if (!listening) return\n if (typeof window === 'undefined') return\n window.removeEventListener('keydown', handleKeydown, true)\n listening = false\n}\n\n/** Регистрирует открытую модалку как верхнюю и возвращает её id. */\nexport function pushGrModalEsc(entry: Omit<GrModalEscEntry, 'id'>): number {\n const id = nextId++\n stack.push({ ...entry, id })\n startListening()\n return id\n}\n\n/** Снимает модалку со стека (при закрытии или размонтировании). */\nexport function removeGrModalEsc(id: number): void {\n const index = stack.findIndex(item => item.id === id)\n if (index >= 0) stack.splice(index, 1)\n if (stack.length === 0) stopListening()\n}\n\n/** Тестовая/служебная очистка стека. */\nexport function resetGrModalEscStack(): void {\n stack.splice(0, stack.length)\n stopListening()\n}\n","<script setup lang=\"ts\">\n/**\n * GrModal — DS-примитив модального окна на базе `@headlessui/vue`.\n *\n * Публичный API:\n * - `modelValue` (v-model) — открыто/закрыто;\n * - `size` — размер панели (`sm | md | lg | xl | full`);\n * - `closeOnBackdrop` (default: true) — закрывать при клике по оверлею;\n * - `closeOnEsc` (default: true) — закрывать по Esc;\n * - слоты `#title` / `#description` — если переданы, оборачиваются в\n * `DialogTitle` / `DialogDescription` (связь через `aria-labelledby` /\n * `aria-describedby` ставится HeadlessUI автоматически).\n *\n * Esc обрабатывается через общий стек открытых модалок (`grModalEscStack`):\n * единый capture-обработчик на `window` закрывает только верхнюю (последнюю\n * открытую) модалку и опережает window-обработчик Escape HeadlessUI. Это\n * чинит кейс, когда поверх `GrModal` открыт диалог `useDialogService` (другое\n * дерево рендера): Esc закрывает именно верхний диалог, а не нижнее окно.\n * Клик по оверлею (backdrop) по-прежнему идёт через `@close` HeadlessUI;\n * источник закрытия различается через ref `closeReason`.\n */\nimport { computed, onBeforeUnmount, ref, watch } from 'vue'\nimport { Dialog, DialogDescription, DialogPanel, DialogTitle, TransitionChild, TransitionRoot } from '@headlessui/vue'\n\nimport { pushGrModalEsc, removeGrModalEsc } from './grModalEscStack'\n\nimport {\n type GrModalSize,\n getGrModalPanelClass,\n layout,\n overlay as overlayClass,\n overlayTransition,\n panelTransition,\n root as rootClass,\n shell,\n} from './grModalStyles'\n\nexport interface GrModalProps {\n modelValue: boolean\n closeOnBackdrop?: boolean\n closeOnEsc?: boolean\n size?: GrModalSize\n}\n\nconst props = withDefaults(defineProps<GrModalProps>(), {\n closeOnBackdrop: true,\n closeOnEsc: true,\n size: 'md',\n})\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: boolean): void\n}>()\n\nconst panelClass = computed(() => getGrModalPanelClass(props.size))\n\n// SSR-guard: на сервере `document.body` недоступен — отключаем teleport,\n// а в клиенте включаем после маунта.\nconst isClient = typeof window !== 'undefined'\n\n// Источник закрытия от HeadlessUI `<Dialog>` — либо Esc, либо клик по оверлею.\n// Различаем их, чтобы `closeOnBackdrop` и `closeOnEsc` работали независимо.\nconst closeReason = ref<'backdrop' | 'esc' | null>(null)\n\nfunction close(): void {\n emit('update:modelValue', false)\n}\n\nfunction onDialogClose(): void {\n const reason = closeReason.value\n closeReason.value = null\n\n if (reason === 'esc') {\n if (props.closeOnEsc) close()\n return\n }\n\n // По умолчанию (клик по оверлею или программный вызов `@close`)\n // уважаем `closeOnBackdrop`.\n if (props.closeOnBackdrop) close()\n}\n\nfunction onRootKeydown(event: KeyboardEvent): void {\n if (event.key === 'Escape') closeReason.value = 'esc'\n}\n\n// ————— Esc-стек: гарантирует, что Esc закрывает именно верхнюю (последнюю\n// открытую) модалку, даже если окна живут в разных деревьях рендера\n// (например, диалоги `useDialogService` поверх `GrModal`).\nlet escEntryId: number | null = null\n\nfunction registerEsc(): void {\n if (escEntryId !== null) return\n escEntryId = pushGrModalEsc({\n shouldClose: () => props.closeOnEsc,\n close,\n })\n}\n\nfunction unregisterEsc(): void {\n if (escEntryId === null) return\n removeGrModalEsc(escEntryId)\n escEntryId = null\n}\n\nfunction onOverlayPointerDown(): void {\n closeReason.value = 'backdrop'\n}\n\n// ————— Scroll lock на `<body>` на время открытия.\n// HeadlessUI Vue этого не делает автоматически, а фон скроллится —\n// для DS-примитива это мешающий UX.\nlet savedBodyOverflow: string | null = null\n\nfunction lockBodyScroll(): void {\n if (!isClient) return\n if (savedBodyOverflow !== null) return\n savedBodyOverflow = document.body.style.overflow\n document.body.style.overflow = 'hidden'\n}\n\nfunction unlockBodyScroll(): void {\n if (!isClient) return\n if (savedBodyOverflow === null) return\n document.body.style.overflow = savedBodyOverflow\n savedBodyOverflow = null\n}\n\nwatch(\n () => props.modelValue,\n (value) => {\n if (value) {\n lockBodyScroll()\n registerEsc()\n }\n else {\n unlockBodyScroll()\n unregisterEsc()\n }\n },\n { immediate: true },\n)\n\nonBeforeUnmount(() => {\n unlockBodyScroll()\n unregisterEsc()\n})\n\n</script>\n\n<template>\n <teleport to=\"body\" :disabled=\"!isClient\">\n <TransitionRoot :show=\"modelValue\" as=\"template\">\n <Dialog\n as=\"div\"\n :class=\"rootClass\"\n @close=\"onDialogClose\"\n @keydown.capture=\"onRootKeydown\"\n >\n <div :class=\"shell\">\n <div :class=\"layout\">\n <TransitionChild\n as=\"template\"\n :enter=\"overlayTransition.enter\"\n :enter-from=\"overlayTransition.enterFrom\"\n :enter-to=\"overlayTransition.enterTo\"\n :leave=\"overlayTransition.leave\"\n :leave-from=\"overlayTransition.leaveFrom\"\n :leave-to=\"overlayTransition.leaveTo\"\n >\n <div\n data-ds-modal-overlay\n :class=\"overlayClass\"\n aria-hidden=\"true\"\n @pointerdown=\"onOverlayPointerDown\"\n />\n </TransitionChild>\n\n <TransitionChild\n as=\"template\"\n :enter=\"panelTransition.enter\"\n :enter-from=\"panelTransition.enterFrom\"\n :enter-to=\"panelTransition.enterTo\"\n :leave=\"panelTransition.leave\"\n :leave-from=\"panelTransition.leaveFrom\"\n :leave-to=\"panelTransition.leaveTo\"\n >\n <DialogPanel\n data-ds-modal-panel\n tabindex=\"-1\"\n :class=\"panelClass\"\n >\n <DialogTitle v-if=\"$slots.title\" as=\"div\" data-ds-modal-title>\n <slot name=\"title\" />\n </DialogTitle>\n <DialogDescription v-if=\"$slots.description\" as=\"div\" data-ds-modal-description>\n <slot name=\"description\" />\n </DialogDescription>\n <slot />\n </DialogPanel>\n </TransitionChild>\n </div>\n </div>\n </Dialog>\n </TransitionRoot>\n </teleport>\n</template>\n","<script setup lang=\"ts\">\n/**\n * GrModal — DS-примитив модального окна на базе `@headlessui/vue`.\n *\n * Публичный API:\n * - `modelValue` (v-model) — открыто/закрыто;\n * - `size` — размер панели (`sm | md | lg | xl | full`);\n * - `closeOnBackdrop` (default: true) — закрывать при клике по оверлею;\n * - `closeOnEsc` (default: true) — закрывать по Esc;\n * - слоты `#title` / `#description` — если переданы, оборачиваются в\n * `DialogTitle` / `DialogDescription` (связь через `aria-labelledby` /\n * `aria-describedby` ставится HeadlessUI автоматически).\n *\n * Esc обрабатывается через общий стек открытых модалок (`grModalEscStack`):\n * единый capture-обработчик на `window` закрывает только верхнюю (последнюю\n * открытую) модалку и опережает window-обработчик Escape HeadlessUI. Это\n * чинит кейс, когда поверх `GrModal` открыт диалог `useDialogService` (другое\n * дерево рендера): Esc закрывает именно верхний диалог, а не нижнее окно.\n * Клик по оверлею (backdrop) по-прежнему идёт через `@close` HeadlessUI;\n * источник закрытия различается через ref `closeReason`.\n */\nimport { computed, onBeforeUnmount, ref, watch } from 'vue'\nimport { Dialog, DialogDescription, DialogPanel, DialogTitle, TransitionChild, TransitionRoot } from '@headlessui/vue'\n\nimport { pushGrModalEsc, removeGrModalEsc } from './grModalEscStack'\n\nimport {\n type GrModalSize,\n getGrModalPanelClass,\n layout,\n overlay as overlayClass,\n overlayTransition,\n panelTransition,\n root as rootClass,\n shell,\n} from './grModalStyles'\n\nexport interface GrModalProps {\n modelValue: boolean\n closeOnBackdrop?: boolean\n closeOnEsc?: boolean\n size?: GrModalSize\n}\n\nconst props = withDefaults(defineProps<GrModalProps>(), {\n closeOnBackdrop: true,\n closeOnEsc: true,\n size: 'md',\n})\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: boolean): void\n}>()\n\nconst panelClass = computed(() => getGrModalPanelClass(props.size))\n\n// SSR-guard: на сервере `document.body` недоступен — отключаем teleport,\n// а в клиенте включаем после маунта.\nconst isClient = typeof window !== 'undefined'\n\n// Источник закрытия от HeadlessUI `<Dialog>` — либо Esc, либо клик по оверлею.\n// Различаем их, чтобы `closeOnBackdrop` и `closeOnEsc` работали независимо.\nconst closeReason = ref<'backdrop' | 'esc' | null>(null)\n\nfunction close(): void {\n emit('update:modelValue', false)\n}\n\nfunction onDialogClose(): void {\n const reason = closeReason.value\n closeReason.value = null\n\n if (reason === 'esc') {\n if (props.closeOnEsc) close()\n return\n }\n\n // По умолчанию (клик по оверлею или программный вызов `@close`)\n // уважаем `closeOnBackdrop`.\n if (props.closeOnBackdrop) close()\n}\n\nfunction onRootKeydown(event: KeyboardEvent): void {\n if (event.key === 'Escape') closeReason.value = 'esc'\n}\n\n// ————— Esc-стек: гарантирует, что Esc закрывает именно верхнюю (последнюю\n// открытую) модалку, даже если окна живут в разных деревьях рендера\n// (например, диалоги `useDialogService` поверх `GrModal`).\nlet escEntryId: number | null = null\n\nfunction registerEsc(): void {\n if (escEntryId !== null) return\n escEntryId = pushGrModalEsc({\n shouldClose: () => props.closeOnEsc,\n close,\n })\n}\n\nfunction unregisterEsc(): void {\n if (escEntryId === null) return\n removeGrModalEsc(escEntryId)\n escEntryId = null\n}\n\nfunction onOverlayPointerDown(): void {\n closeReason.value = 'backdrop'\n}\n\n// ————— Scroll lock на `<body>` на время открытия.\n// HeadlessUI Vue этого не делает автоматически, а фон скроллится —\n// для DS-примитива это мешающий UX.\nlet savedBodyOverflow: string | null = null\n\nfunction lockBodyScroll(): void {\n if (!isClient) return\n if (savedBodyOverflow !== null) return\n savedBodyOverflow = document.body.style.overflow\n document.body.style.overflow = 'hidden'\n}\n\nfunction unlockBodyScroll(): void {\n if (!isClient) return\n if (savedBodyOverflow === null) return\n document.body.style.overflow = savedBodyOverflow\n savedBodyOverflow = null\n}\n\nwatch(\n () => props.modelValue,\n (value) => {\n if (value) {\n lockBodyScroll()\n registerEsc()\n }\n else {\n unlockBodyScroll()\n unregisterEsc()\n }\n },\n { immediate: true },\n)\n\nonBeforeUnmount(() => {\n unlockBodyScroll()\n unregisterEsc()\n})\n\n</script>\n\n<template>\n <teleport to=\"body\" :disabled=\"!isClient\">\n <TransitionRoot :show=\"modelValue\" as=\"template\">\n <Dialog\n as=\"div\"\n :class=\"rootClass\"\n @close=\"onDialogClose\"\n @keydown.capture=\"onRootKeydown\"\n >\n <div :class=\"shell\">\n <div :class=\"layout\">\n <TransitionChild\n as=\"template\"\n :enter=\"overlayTransition.enter\"\n :enter-from=\"overlayTransition.enterFrom\"\n :enter-to=\"overlayTransition.enterTo\"\n :leave=\"overlayTransition.leave\"\n :leave-from=\"overlayTransition.leaveFrom\"\n :leave-to=\"overlayTransition.leaveTo\"\n >\n <div\n data-ds-modal-overlay\n :class=\"overlayClass\"\n aria-hidden=\"true\"\n @pointerdown=\"onOverlayPointerDown\"\n />\n </TransitionChild>\n\n <TransitionChild\n as=\"template\"\n :enter=\"panelTransition.enter\"\n :enter-from=\"panelTransition.enterFrom\"\n :enter-to=\"panelTransition.enterTo\"\n :leave=\"panelTransition.leave\"\n :leave-from=\"panelTransition.leaveFrom\"\n :leave-to=\"panelTransition.leaveTo\"\n >\n <DialogPanel\n data-ds-modal-panel\n tabindex=\"-1\"\n :class=\"panelClass\"\n >\n <DialogTitle v-if=\"$slots.title\" as=\"div\" data-ds-modal-title>\n <slot name=\"title\" />\n </DialogTitle>\n <DialogDescription v-if=\"$slots.description\" as=\"div\" data-ds-modal-description>\n <slot name=\"description\" />\n </DialogDescription>\n <slot />\n </DialogPanel>\n </TransitionChild>\n </div>\n </div>\n </Dialog>\n </TransitionRoot>\n </teleport>\n</template>\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { t as getGrModalPanelClass } from "../../chunks/grModalStyles-Dv2NXBKi.js";
2
- import { t as GrModal_default } from "./chunks/GrModal-gvfvlp7k.js";
3
- import { n as grModalClassTokens, r as grModalSafelist, t as grModalConfig } from "../../chunks/config-C5TN9J2Z.js";
1
+ import { t as GrModal_default } from "./chunks/GrModal-2ALC3kwy.js";
2
+ import { t as getGrModalPanelClass } from "../../chunks/grModalStyles-DS1Vl6EW.js";
3
+ import { n as grModalClassTokens, r as grModalSafelist, t as grModalConfig } from "../../chunks/config-C5OwJM3-.js";
4
4
  export { GrModal_default as GrModal, GrModal_default as default, getGrModalPanelClass, grModalClassTokens, grModalConfig, grModalSafelist };