@feugene/granularity 0.11.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (527) hide show
  1. package/dist/GrBadge.css +1 -1
  2. package/dist/GrFormFile.css +1 -1
  3. package/dist/GrToaster.css +1 -1
  4. package/dist/GrTree.css +1 -1
  5. package/dist/chunks/{config-ClhKPJvg.js → config-23WtUiAL.js} +1 -1
  6. package/dist/chunks/config-23WtUiAL.js.map +1 -0
  7. package/dist/chunks/config-8Pcutu1j.js.map +1 -0
  8. package/dist/chunks/{config-1uSYl98Y.js → config-B0i5r8kH.js} +1 -1
  9. package/dist/chunks/config-B0i5r8kH.js.map +1 -0
  10. package/dist/chunks/{config-BOlr7qw7.js → config-B5Rknzkd.js} +33 -39
  11. package/dist/chunks/config-B5Rknzkd.js.map +1 -0
  12. package/dist/chunks/config-B7W9VlZ7.js +5 -0
  13. package/dist/chunks/config-B7W9VlZ7.js.map +1 -0
  14. package/dist/chunks/config-BDSHekVC.js +84 -0
  15. package/dist/chunks/config-BDSHekVC.js.map +1 -0
  16. package/dist/chunks/config-BLHqZhy-.js.map +1 -0
  17. package/dist/chunks/{config-eYLZYOUS2.js → config-BMKNHFMD2.js} +15 -15
  18. package/dist/chunks/config-BMKNHFMD2.js.map +1 -0
  19. package/dist/chunks/config-BUHuGBik2.js.map +1 -0
  20. package/dist/chunks/config-BWiPnygb.js +5 -0
  21. package/dist/chunks/config-BWiPnygb.js.map +1 -0
  22. package/dist/chunks/config-BX1JTrkV.js.map +1 -0
  23. package/dist/chunks/config-BZFUM3Ky.js +75 -0
  24. package/dist/chunks/config-BZFUM3Ky.js.map +1 -0
  25. package/dist/chunks/{config-DUcu1D68.js → config-BmNT0Fmx.js} +2 -2
  26. package/dist/chunks/config-BmNT0Fmx.js.map +1 -0
  27. package/dist/chunks/{config-C49QUoJL.js → config-BvVq2gbd.js} +1 -1
  28. package/dist/chunks/{config-C49QUoJL.js.map → config-BvVq2gbd.js.map} +1 -1
  29. package/dist/chunks/{config-CrG1XiE7.js → config-C4hJxXDa.js} +5 -5
  30. package/dist/chunks/config-C4hJxXDa.js.map +1 -0
  31. package/dist/chunks/config-CB4RVt9M.js +66 -0
  32. package/dist/chunks/config-CB4RVt9M.js.map +1 -0
  33. package/dist/chunks/config-COE_vZ-l.js +52 -0
  34. package/dist/chunks/config-COE_vZ-l.js.map +1 -0
  35. package/dist/chunks/{config-CziwTDDL.js → config-CPdmr7tC.js} +1 -1
  36. package/dist/chunks/{config-CziwTDDL.js.map → config-CPdmr7tC.js.map} +1 -1
  37. package/dist/chunks/{config-BIRO0vDJ2.js → config-DPDFYzIa.js} +2 -2
  38. package/dist/chunks/config-DPDFYzIa.js.map +1 -0
  39. package/dist/chunks/{config-DnvPqu4g.js → config-DRKXJ9PW2.js} +1 -1
  40. package/dist/chunks/config-DRKXJ9PW2.js.map +1 -0
  41. package/dist/chunks/config-DToHb81g.js +45 -0
  42. package/dist/chunks/config-DToHb81g.js.map +1 -0
  43. package/dist/chunks/{config-jBp9wVv-.js → config-D_myOZbA.js} +1 -1
  44. package/dist/chunks/{config-jBp9wVv-.js.map → config-D_myOZbA.js.map} +1 -1
  45. package/dist/chunks/{config-D_R56_gT.js → config-Dg_6FTvJ.js} +1 -1
  46. package/dist/chunks/config-Dg_6FTvJ.js.map +1 -0
  47. package/dist/chunks/config-Dlm49Jp5.js +5 -0
  48. package/dist/chunks/config-Dlm49Jp5.js.map +1 -0
  49. package/dist/chunks/config-DpqOnJiz.js.map +1 -0
  50. package/dist/chunks/config-Dqy0rPPO2.js.map +1 -0
  51. package/dist/chunks/config-Droqn55j.js +8 -0
  52. package/dist/chunks/config-Droqn55j.js.map +1 -0
  53. package/dist/chunks/{config-C4snOIXg.js → config-KXuionN3.js} +1 -1
  54. package/dist/chunks/{config-C4snOIXg.js.map → config-KXuionN3.js.map} +1 -1
  55. package/dist/chunks/config-LGrZIdaZ.js.map +1 -0
  56. package/dist/chunks/{config-DezDih8_.js → config-LqDC_rvp.js} +2 -2
  57. package/dist/chunks/config-LqDC_rvp.js.map +1 -0
  58. package/dist/chunks/config-QaIc_gRa2.js.map +1 -0
  59. package/dist/chunks/config-U4m9PSql2.js.map +1 -0
  60. package/dist/chunks/{config-B7IIWGt_2.js → config-XmTv4pnI.js} +2 -2
  61. package/dist/chunks/config-XmTv4pnI.js.map +1 -0
  62. package/dist/chunks/config-eXB87DOi.js +9 -0
  63. package/dist/chunks/config-eXB87DOi.js.map +1 -0
  64. package/dist/chunks/{config-C7NpDrfO.js → config-gZWR75Bh2.js} +1 -1
  65. package/dist/chunks/config-gZWR75Bh2.js.map +1 -0
  66. package/dist/chunks/config-ipvU0lzP.js.map +1 -0
  67. package/dist/chunks/config-xR4XVmcy2.js.map +1 -0
  68. package/dist/chunks/context-Bfrgsluh.js +9 -0
  69. package/dist/chunks/context-Bfrgsluh.js.map +1 -0
  70. package/dist/chunks/context-DdNIxa1w.js +9 -0
  71. package/dist/chunks/context-DdNIxa1w.js.map +1 -0
  72. package/dist/chunks/context-DfWYCBB-.js +129 -0
  73. package/dist/chunks/context-DfWYCBB-.js.map +1 -0
  74. package/dist/chunks/{en-BdtiS2d3.js → en-Cr6EkG8c.js} +52 -4
  75. package/dist/chunks/en-Cr6EkG8c.js.map +1 -0
  76. package/dist/chunks/{es-DBhctWg-.js → es-DuYb1Qju.js} +3 -3
  77. package/dist/chunks/{es-DBhctWg-.js.map → es-DuYb1Qju.js.map} +1 -1
  78. package/dist/chunks/{es-BGRMZbe9.js → es-i08e9Sdo.js} +52 -4
  79. package/dist/chunks/es-i08e9Sdo.js.map +1 -0
  80. package/dist/chunks/{grBadgeStyles-DrycBuKT.js → grBadgeStyles-D3dFjr_N.js} +12 -12
  81. package/dist/chunks/grBadgeStyles-D3dFjr_N.js.map +1 -0
  82. package/dist/chunks/{grButtonStyles-C7Yga_Q1.js → grButtonStyles-DRBgDmOp.js} +28 -28
  83. package/dist/chunks/grButtonStyles-DRBgDmOp.js.map +1 -0
  84. package/dist/chunks/{grDropdownStyles-B_-DKytw.js → grDropdownStyles-HBPkghVr.js} +2 -2
  85. package/dist/chunks/{grDropdownStyles-B_-DKytw.js.map → grDropdownStyles-HBPkghVr.js.map} +1 -1
  86. package/dist/chunks/grModalEscStack-BXk-9mv7.js +43 -0
  87. package/dist/chunks/grModalEscStack-BXk-9mv7.js.map +1 -0
  88. package/dist/chunks/{grModalStyles-DWd3i05Q.js → grModalStyles-D8-shx9A.js} +1 -1
  89. package/dist/chunks/grModalStyles-D8-shx9A.js.map +1 -0
  90. package/dist/chunks/{grSelectStyles-CLK5hRd3.js → grSelectStyles-CwMUQrBZ.js} +12 -12
  91. package/dist/chunks/grSelectStyles-CwMUQrBZ.js.map +1 -0
  92. package/dist/chunks/{grStyle-Blc9otAx.js → grStyle-CdvxTXPH.js} +2 -2
  93. package/dist/chunks/grStyle-CdvxTXPH.js.map +1 -0
  94. package/dist/chunks/{granularityI18n-DoV7Ca2m.js → granularityI18n-SH0I--GW.js} +1 -1
  95. package/dist/chunks/{granularityI18n-DoV7Ca2m.js.map → granularityI18n-SH0I--GW.js.map} +1 -1
  96. package/dist/chunks/{ru-BFCnOiML.js → ru-B5XOOYZt.js} +52 -4
  97. package/dist/chunks/ru-B5XOOYZt.js.map +1 -0
  98. package/dist/chunks/{safelist-Do2RtzLB.js → safelist-BvO8HPnE.js} +1 -1
  99. package/dist/chunks/{safelist-Do2RtzLB.js.map → safelist-BvO8HPnE.js.map} +1 -1
  100. package/dist/chunks/shared-D-v9lit0.js +188 -0
  101. package/dist/chunks/shared-D-v9lit0.js.map +1 -0
  102. package/dist/chunks/{transition-TLFw4KBn.js → useScrollLock-K7kaP2Ud.js} +52 -1
  103. package/dist/chunks/useScrollLock-K7kaP2Ud.js.map +1 -0
  104. package/dist/components/GrAlert/chunks/GrAlert-B9gmpoPC.js +251 -0
  105. package/dist/components/GrAlert/chunks/GrAlert-B9gmpoPC.js.map +1 -0
  106. package/dist/components/GrAlert/index.js +2 -2
  107. package/dist/components/GrAutocomplete/chunks/GrAutocomplete-BVLoQ5tZ.js +499 -0
  108. package/dist/components/GrAutocomplete/chunks/GrAutocomplete-BVLoQ5tZ.js.map +1 -0
  109. package/dist/components/GrAutocomplete/index.js +3 -0
  110. package/dist/components/GrAvatar/chunks/{GrAvatar-96CpTCq5.js → GrAvatar-CTOUVBF7.js} +1 -1
  111. package/dist/components/GrAvatar/chunks/GrAvatar-CTOUVBF7.js.map +1 -0
  112. package/dist/components/GrAvatar/index.js +1 -1
  113. package/dist/components/GrBadge/chunks/{GrBadge-B77XlaqE.js → GrBadge-D1jefy4S.js} +12 -8
  114. package/dist/components/GrBadge/chunks/GrBadge-D1jefy4S.js.map +1 -0
  115. package/dist/components/GrBadge/index.js +2 -2
  116. package/dist/components/GrBadgeWrap/chunks/{GrBadgeWrap-CcktMOdg.js → GrBadgeWrap-DWDxHdiQ.js} +1 -1
  117. package/dist/components/GrBadgeWrap/chunks/GrBadgeWrap-DWDxHdiQ.js.map +1 -0
  118. package/dist/components/GrBadgeWrap/index.js +1 -1
  119. package/dist/components/GrBottomNav/chunks/{GrBottomNav-usuMgG8_.js → GrBottomNav-vSE4LXmk.js} +2 -2
  120. package/dist/components/GrBottomNav/chunks/GrBottomNav-vSE4LXmk.js.map +1 -0
  121. package/dist/components/GrBottomNav/index.js +1 -1
  122. package/dist/components/GrButton/chunks/{GrButton-BlffdeJr.js → GrButton-DCi4CUpo.js} +18 -14
  123. package/dist/components/GrButton/chunks/GrButton-DCi4CUpo.js.map +1 -0
  124. package/dist/components/GrButton/index.js +4 -4
  125. package/dist/components/GrCard/chunks/{GrCard-DUNMkuHW.js → GrCard-CxCjyHMb.js} +1 -1
  126. package/dist/components/GrCard/chunks/GrCard-CxCjyHMb.js.map +1 -0
  127. package/dist/components/GrCard/index.js +1 -1
  128. package/dist/components/GrCheckbox/chunks/{GrCheckbox-DJhzZZdO.js → GrCheckbox-BbIDRXtl.js} +5 -5
  129. package/dist/components/GrCheckbox/chunks/GrCheckbox-BbIDRXtl.js.map +1 -0
  130. package/dist/components/GrCheckbox/index.js +1 -1
  131. package/dist/components/GrCollapse/chunks/{GrCollapse-CPPLh_xU.js → GrCollapse-DApXztn8.js} +6 -6
  132. package/dist/components/GrCollapse/chunks/GrCollapse-DApXztn8.js.map +1 -0
  133. package/dist/components/GrCollapse/index.js +2 -2
  134. package/dist/components/GrCommandPalette/chunks/GrCommandPalette-6OyvNbek.js +410 -0
  135. package/dist/components/GrCommandPalette/chunks/GrCommandPalette-6OyvNbek.js.map +1 -0
  136. package/dist/components/GrCommandPalette/index.js +3 -0
  137. package/dist/components/GrConfigProvider/chunks/GrConfigProvider-BtyeBGm8.js +57 -0
  138. package/dist/components/GrConfigProvider/chunks/GrConfigProvider-BtyeBGm8.js.map +1 -0
  139. package/dist/components/GrConfigProvider/index.js +4 -0
  140. package/dist/components/GrConfirmDialog/chunks/{GrConfirmDialog-BWYKCsHd.js → GrConfirmDialog-e4120mWw.js} +5 -5
  141. package/dist/components/GrConfirmDialog/chunks/GrConfirmDialog-e4120mWw.js.map +1 -0
  142. package/dist/components/GrConfirmDialog/index.js +1 -1
  143. package/dist/components/GrDataTable/chunks/GrDataTable-C1CzxV0p.js +307 -0
  144. package/dist/components/GrDataTable/chunks/GrDataTable-C1CzxV0p.js.map +1 -0
  145. package/dist/components/GrDataTable/index.js +2 -2
  146. package/dist/components/GrDialog/chunks/{GrDialog-5DAS-1Lb.js → GrDialog-BPMvDHOz.js} +6 -6
  147. package/dist/components/GrDialog/chunks/GrDialog-BPMvDHOz.js.map +1 -0
  148. package/dist/components/GrDialog/index.js +1 -1
  149. package/dist/components/GrDialogService/chunks/{GrDialogService-DY_fmaMu.js → GrDialogService-CYXCTGm3.js} +36 -11
  150. package/dist/components/GrDialogService/chunks/GrDialogService-CYXCTGm3.js.map +1 -0
  151. package/dist/components/GrDialogService/index.js +2 -2
  152. package/dist/components/GrDivider/chunks/GrDivider-BdENZ1w0.js +54 -0
  153. package/dist/components/GrDivider/chunks/GrDivider-BdENZ1w0.js.map +1 -0
  154. package/dist/components/GrDivider/index.js +3 -0
  155. package/dist/components/GrDrawer/chunks/{GrDrawer-D1kzsjXN.js → GrDrawer-KevdZ5BB.js} +41 -17
  156. package/dist/components/GrDrawer/chunks/GrDrawer-KevdZ5BB.js.map +1 -0
  157. package/dist/components/GrDrawer/index.js +2 -2
  158. package/dist/components/GrDropdown/chunks/{GrDropdown-BXb5Cxxf.js → GrDropdown-BKoy8hm-.js} +91 -5
  159. package/dist/components/GrDropdown/chunks/GrDropdown-BKoy8hm-.js.map +1 -0
  160. package/dist/components/GrDropdown/index.js +2 -2
  161. package/dist/components/GrDropdownMenu/chunks/{GrDropdownMenu-DFEJLPcV.js → GrDropdownMenu-zCatXzmt.js} +11 -11
  162. package/dist/components/GrDropdownMenu/chunks/GrDropdownMenu-zCatXzmt.js.map +1 -0
  163. package/dist/components/GrDropdownMenu/index.js +1 -1
  164. package/dist/components/GrEmptyState/chunks/{GrEmptyState-CA3BiTV7.js → GrEmptyState-CNb0BzjG.js} +3 -3
  165. package/dist/components/GrEmptyState/chunks/GrEmptyState-CNb0BzjG.js.map +1 -0
  166. package/dist/components/GrEmptyState/index.js +1 -1
  167. package/dist/components/GrFileUpload/chunks/{GrFileUpload-DvWPpiJS.js → GrFileUpload-CnLgUGDF.js} +12 -12
  168. package/dist/components/GrFileUpload/chunks/GrFileUpload-CnLgUGDF.js.map +1 -0
  169. package/dist/components/GrFileUpload/index.js +1 -1
  170. package/dist/components/GrForm/chunks/GrForm-CdaFjcyl.js +234 -0
  171. package/dist/components/GrForm/chunks/GrForm-CdaFjcyl.js.map +1 -0
  172. package/dist/components/GrForm/index.js +4 -0
  173. package/dist/components/GrFormField/chunks/GrFormField-CXCDBd99.js +100 -0
  174. package/dist/components/GrFormField/chunks/GrFormField-CXCDBd99.js.map +1 -0
  175. package/dist/components/GrFormField/index.js +3 -2
  176. package/dist/components/GrFormFile/chunks/{GrFormFile-CXcqqdvV.js → GrFormFile-CqacSbUl.js} +9 -9
  177. package/dist/components/GrFormFile/chunks/GrFormFile-CqacSbUl.js.map +1 -0
  178. package/dist/components/GrFormFile/index.js +1 -1
  179. package/dist/components/GrFormSection/chunks/{GrFormSection-Ce21jcgo.js → GrFormSection-C3w9DQJf.js} +1 -1
  180. package/dist/components/GrFormSection/chunks/GrFormSection-C3w9DQJf.js.map +1 -0
  181. package/dist/components/GrFormSection/index.js +1 -1
  182. package/dist/components/GrImageViewer/chunks/{GrImageViewer-OCUIrNh2.js → GrImageViewer-DDLJkvIU.js} +312 -223
  183. package/dist/components/GrImageViewer/chunks/GrImageViewer-DDLJkvIU.js.map +1 -0
  184. package/dist/components/GrImageViewer/index.js +1 -1
  185. package/dist/components/GrInput/chunks/GrInput-C1VBL0dg.js +337 -0
  186. package/dist/components/GrInput/chunks/GrInput-C1VBL0dg.js.map +1 -0
  187. package/dist/components/GrInput/index.js +2 -2
  188. package/dist/components/GrInputTag/chunks/{GrInputTag-zMgFqp2g.js → GrInputTag-BMk9jm42.js} +6 -6
  189. package/dist/components/GrInputTag/chunks/GrInputTag-BMk9jm42.js.map +1 -0
  190. package/dist/components/GrInputTag/index.js +2 -2
  191. package/dist/components/GrKbd/chunks/GrKbd-DTspwtoN.js +22 -0
  192. package/dist/components/GrKbd/chunks/GrKbd-DTspwtoN.js.map +1 -0
  193. package/dist/components/GrKbd/index.js +3 -0
  194. package/dist/components/GrLink/chunks/{GrLink-CYUe-Q8k.js → GrLink-BP0YrnL9.js} +1 -1
  195. package/dist/components/GrLink/chunks/{GrLink-CYUe-Q8k.js.map → GrLink-BP0YrnL9.js.map} +1 -1
  196. package/dist/components/GrLink/index.js +2 -2
  197. package/dist/components/GrList/chunks/{GrList-Dx772Ns4.js → GrList-5RA-tZzE.js} +3 -3
  198. package/dist/components/GrList/chunks/GrList-5RA-tZzE.js.map +1 -0
  199. package/dist/components/GrList/index.js +1 -1
  200. package/dist/components/GrLoading/chunks/{GrLoading--X_7rdbb.js → GrLoading-fRDtVfi7.js} +3 -3
  201. package/dist/components/GrLoading/chunks/GrLoading-fRDtVfi7.js.map +1 -0
  202. package/dist/components/GrLoading/index.js +2 -2
  203. package/dist/components/GrModal/chunks/{GrModal-BkjW9jZS.js → GrModal-BTu1-5eY.js} +4 -57
  204. package/dist/components/GrModal/chunks/GrModal-BTu1-5eY.js.map +1 -0
  205. package/dist/components/GrModal/index.js +3 -3
  206. package/dist/components/GrNavbar/chunks/{GrNavbar-DW3MiIIf.js → GrNavbar-keKT_mIM.js} +3 -3
  207. package/dist/components/GrNavbar/chunks/GrNavbar-keKT_mIM.js.map +1 -0
  208. package/dist/components/GrNavbar/index.js +1 -1
  209. package/dist/components/GrNumberInput/chunks/{GrNumberInput-CldPIWQx.js → GrNumberInput-l9ZOHG9D.js} +112 -28
  210. package/dist/components/GrNumberInput/chunks/GrNumberInput-l9ZOHG9D.js.map +1 -0
  211. package/dist/components/GrNumberInput/index.js +2 -2
  212. package/dist/components/GrPagination/chunks/{GrPagination-Bu9wv6it.js → GrPagination-C5Y69CuK.js} +59 -16
  213. package/dist/components/GrPagination/chunks/GrPagination-C5Y69CuK.js.map +1 -0
  214. package/dist/components/GrPagination/index.js +1 -1
  215. package/dist/components/GrProgressBar/chunks/{GrProgressBar-CC3z-Zqp.js → GrProgressBar-Dqg4Fj9S.js} +2 -2
  216. package/dist/components/GrProgressBar/chunks/GrProgressBar-Dqg4Fj9S.js.map +1 -0
  217. package/dist/components/GrProgressBar/index.js +2 -2
  218. package/dist/components/GrPromptDialog/chunks/{GrPromptDialog-TmWXbpEP.js → GrPromptDialog-DNUjRVB9.js} +7 -7
  219. package/dist/components/GrPromptDialog/chunks/GrPromptDialog-DNUjRVB9.js.map +1 -0
  220. package/dist/components/GrPromptDialog/index.js +2 -2
  221. package/dist/components/GrRadio/chunks/{GrRadio-CPTixXaY.js → GrRadio-DlhxPGqf.js} +5 -7
  222. package/dist/components/GrRadio/chunks/GrRadio-DlhxPGqf.js.map +1 -0
  223. package/dist/components/GrRadio/index.js +2 -2
  224. package/dist/components/GrRadioGroup/chunks/{GrRadioGroup-vKZCbkCp.js → GrRadioGroup-BXt9iw4q.js} +7 -5
  225. package/dist/components/GrRadioGroup/chunks/GrRadioGroup-BXt9iw4q.js.map +1 -0
  226. package/dist/components/GrRadioGroup/index.js +2 -2
  227. package/dist/components/GrRating/chunks/GrRating-Co-3Rk4h.js +241 -0
  228. package/dist/components/GrRating/chunks/GrRating-Co-3Rk4h.js.map +1 -0
  229. package/dist/components/GrRating/index.js +3 -0
  230. package/dist/components/GrResponseErrorBanner/chunks/{GrResponseErrorBanner-BWJNe2gr.js → GrResponseErrorBanner-2CvM7Z08.js} +2 -2
  231. package/dist/components/GrResponseErrorBanner/chunks/{GrResponseErrorBanner-BWJNe2gr.js.map → GrResponseErrorBanner-2CvM7Z08.js.map} +1 -1
  232. package/dist/components/GrResponseErrorBanner/chunks/{GrResponseErrorBanner-Cdu9ekK9.js → GrResponseErrorBanner-C8NGx8pE.js} +3 -3
  233. package/dist/components/GrResponseErrorBanner/chunks/{GrResponseErrorBanner-Cdu9ekK9.js.map → GrResponseErrorBanner-C8NGx8pE.js.map} +1 -1
  234. package/dist/components/GrResponseErrorBanner/index.js +2 -2
  235. package/dist/components/GrSegmented/chunks/{GrSegmented-C1y0UXpQ.js → GrSegmented-CTd3n4PA.js} +14 -11
  236. package/dist/components/GrSegmented/chunks/GrSegmented-CTd3n4PA.js.map +1 -0
  237. package/dist/components/GrSegmented/index.js +2 -2
  238. package/dist/components/GrSelect/chunks/{GrSelect-RShK21lK.js → GrSelect-Dn3FgJ3Z.js} +293 -87
  239. package/dist/components/GrSelect/chunks/GrSelect-Dn3FgJ3Z.js.map +1 -0
  240. package/dist/components/GrSelect/index.js +2 -2
  241. package/dist/components/GrSidebar/chunks/{GrSidebar-DkWozzwA.js → GrSidebar-cvnzBfj3.js} +7 -7
  242. package/dist/components/GrSidebar/chunks/GrSidebar-cvnzBfj3.js.map +1 -0
  243. package/dist/components/GrSidebar/index.js +1 -1
  244. package/dist/components/GrSkeleton/chunks/{GrSkeleton-DsN-_CDZ.js → GrSkeleton-BucA5F4J.js} +1 -1
  245. package/dist/components/GrSkeleton/chunks/GrSkeleton-BucA5F4J.js.map +1 -0
  246. package/dist/components/GrSkeleton/index.js +2 -2
  247. package/dist/components/GrSlider/chunks/GrSlider-CzzJ3bD-.js +286 -0
  248. package/dist/components/GrSlider/chunks/GrSlider-CzzJ3bD-.js.map +1 -0
  249. package/dist/components/GrSlider/index.js +3 -0
  250. package/dist/components/GrStatistic/chunks/GrStatistic-gHiAwrX5.js +128 -0
  251. package/dist/components/GrStatistic/chunks/GrStatistic-gHiAwrX5.js.map +1 -0
  252. package/dist/components/GrStatistic/index.js +3 -0
  253. package/dist/components/GrSwitch/chunks/{GrSwitch-DAioyccZ.js → GrSwitch-CJdRvS0s.js} +16 -7
  254. package/dist/components/GrSwitch/chunks/GrSwitch-CJdRvS0s.js.map +1 -0
  255. package/dist/components/GrSwitch/index.js +2 -2
  256. package/dist/components/GrTabPanels/chunks/GrTabPanels-DeEMgb_y.js +68 -0
  257. package/dist/components/GrTabPanels/chunks/GrTabPanels-DeEMgb_y.js.map +1 -0
  258. package/dist/components/GrTabPanels/index.js +3 -0
  259. package/dist/components/GrTable/chunks/{GrTable-Db3hRnKA.js → GrTable-sNvsA8wa.js} +24 -11
  260. package/dist/components/GrTable/chunks/GrTable-sNvsA8wa.js.map +1 -0
  261. package/dist/components/GrTable/index.js +2 -2
  262. package/dist/components/GrTabs/chunks/{GrTabs-Z-FDJUr_.js → GrTabs-BqTak0SR.js} +9 -4
  263. package/dist/components/GrTabs/chunks/GrTabs-BqTak0SR.js.map +1 -0
  264. package/dist/components/GrTabs/index.js +2 -2
  265. package/dist/components/GrTextarea/chunks/{GrTextarea-D56YxhKq.js → GrTextarea-DIYBAPpP.js} +16 -6
  266. package/dist/components/GrTextarea/chunks/GrTextarea-DIYBAPpP.js.map +1 -0
  267. package/dist/components/GrTextarea/index.js +2 -2
  268. package/dist/components/GrToaster/chunks/{GrToaster-eI8YvnIo.js → GrToaster-BVHjIHcM.js} +52 -11
  269. package/dist/components/GrToaster/chunks/GrToaster-BVHjIHcM.js.map +1 -0
  270. package/dist/components/GrToaster/index.js +2 -2
  271. package/dist/components/GrTooltip/chunks/{GrTooltip-BeyZ8ssR.js → GrTooltip-BMKH2lIx.js} +3 -3
  272. package/dist/components/GrTooltip/chunks/GrTooltip-BMKH2lIx.js.map +1 -0
  273. package/dist/components/GrTooltip/index.js +1 -1
  274. package/dist/components/GrTree/chunks/{GrTree-D3ODe2dB.js → GrTree-_12ChXRQ.js} +108 -9
  275. package/dist/components/GrTree/chunks/GrTree-_12ChXRQ.js.map +1 -0
  276. package/dist/components/GrTree/index.js +2 -2
  277. package/dist/components/GrTreeSelect/chunks/{GrTreeSelect-B2xBKs5Q.js → GrTreeSelect-CdaLG7Xq.js} +10 -10
  278. package/dist/components/GrTreeSelect/chunks/GrTreeSelect-CdaLG7Xq.js.map +1 -0
  279. package/dist/components/GrTreeSelect/index.js +2 -2
  280. package/dist/composables/useToast.js +3 -1
  281. package/dist/composables/useToast.js.map +1 -1
  282. package/dist/directives/loading.js +1 -1
  283. package/dist/granular-provider-node.js +6 -6
  284. package/dist/granular-provider-node.js.map +1 -1
  285. package/dist/granular-provider.js +1 -1
  286. package/dist/i18n/all.js +1 -1
  287. package/dist/i18n/index.js +1 -1
  288. package/dist/index.js +112 -87
  289. package/dist/index.js.map +1 -1
  290. package/dist/styles/base.css +30 -8
  291. package/dist/styles/index.css +6 -3
  292. package/dist/styles/preflight.css +8 -4
  293. package/dist/styles/themes/dark.css +52 -40
  294. package/dist/styles/themes/light.css +70 -45
  295. package/dist/styles/tokens.css +20 -20
  296. package/dist/types/src/components/GrAlert/GrAlert.vue.d.ts +26 -14
  297. package/dist/types/src/components/GrAlert/defaults.d.ts +17 -0
  298. package/dist/types/src/components/GrAlert/grAlertStyles.d.ts +55 -0
  299. package/dist/types/src/components/GrAlert/index.d.ts +4 -1
  300. package/dist/types/src/components/GrAutocomplete/GrAutocomplete.vue.d.ts +153 -0
  301. package/dist/types/src/components/GrAutocomplete/config.d.ts +1 -0
  302. package/dist/types/src/components/GrAutocomplete/defaults.d.ts +15 -0
  303. package/dist/types/src/components/GrAutocomplete/grAutocompleteStyles.d.ts +27 -0
  304. package/dist/types/src/components/GrAutocomplete/index.d.ts +6 -0
  305. package/dist/types/src/components/GrAutocomplete/safelist.d.ts +1 -0
  306. package/dist/types/src/components/GrAvatar/GrAvatar.vue.d.ts +1 -1
  307. package/dist/types/src/components/GrBadge/GrBadge.vue.d.ts +7 -7
  308. package/dist/types/src/components/GrBadge/defaults.d.ts +15 -0
  309. package/dist/types/src/components/GrBadge/index.d.ts +1 -0
  310. package/dist/types/src/components/GrBadgeWrap/GrBadgeWrap.vue.d.ts +1 -1
  311. package/dist/types/src/components/GrButton/GrButton.vue.d.ts +12 -12
  312. package/dist/types/src/components/GrButton/defaults.d.ts +25 -0
  313. package/dist/types/src/components/GrButton/grButtonStyles.d.ts +2 -2
  314. package/dist/types/src/components/GrButton/index.d.ts +1 -0
  315. package/dist/types/src/components/GrCheckbox/GrCheckbox.vue.d.ts +4 -4
  316. package/dist/types/src/components/GrCollapse/GrCollapse.vue.d.ts +2 -2
  317. package/dist/types/src/components/GrCollapse/GrCollapseItem.vue.d.ts +1 -1
  318. package/dist/types/src/components/GrCommandPalette/GrCommandPalette.vue.d.ts +128 -0
  319. package/dist/types/src/components/GrCommandPalette/config.d.ts +1 -0
  320. package/dist/types/src/components/GrCommandPalette/filtering.d.ts +35 -0
  321. package/dist/types/src/components/GrCommandPalette/grCommandPaletteStyles.d.ts +20 -0
  322. package/dist/types/src/components/GrCommandPalette/hotkey.d.ts +23 -0
  323. package/dist/types/src/components/GrCommandPalette/index.d.ts +6 -0
  324. package/dist/types/src/components/GrCommandPalette/safelist.d.ts +1 -0
  325. package/dist/types/src/components/GrConfigProvider/GrConfigProvider.vue.d.ts +59 -0
  326. package/dist/types/src/components/GrConfigProvider/config.d.ts +1 -0
  327. package/dist/types/src/components/GrConfigProvider/context.d.ts +131 -0
  328. package/dist/types/src/components/GrConfigProvider/index.d.ts +5 -0
  329. package/dist/types/src/components/GrConfirmDialog/GrConfirmDialog.vue.d.ts +2 -2
  330. package/dist/types/src/components/GrDataTable/GrDataTable.vue.d.ts +48 -4
  331. package/dist/types/src/components/GrDialog/GrDialog.vue.d.ts +1 -1
  332. package/dist/types/src/components/GrDialogService/store.d.ts +18 -0
  333. package/dist/types/src/components/GrDivider/GrDivider.vue.d.ts +58 -0
  334. package/dist/types/src/components/GrDivider/config.d.ts +1 -0
  335. package/dist/types/src/components/GrDivider/index.d.ts +4 -0
  336. package/dist/types/src/components/GrDrawer/GrDrawer.vue.d.ts +5 -5
  337. package/dist/types/src/components/GrDropdown/GrDropdown.vue.d.ts +8 -1
  338. package/dist/types/src/components/GrDropdownMenu/GrDropdownMenu.vue.d.ts +7 -1
  339. package/dist/types/src/components/GrDropdownMenu/GrDropdownMenuItem.vue.d.ts +1 -1
  340. package/dist/types/src/components/GrFileUpload/GrFileUpload.vue.d.ts +3 -3
  341. package/dist/types/src/components/GrForm/GrForm.vue.d.ts +93 -0
  342. package/dist/types/src/components/GrForm/config.d.ts +1 -0
  343. package/dist/types/src/components/GrForm/context.d.ts +27 -0
  344. package/dist/types/src/components/GrForm/index.d.ts +6 -0
  345. package/dist/types/src/components/GrForm/validation.d.ts +52 -0
  346. package/dist/types/src/components/GrFormField/GrFormField.vue.d.ts +25 -2
  347. package/dist/types/src/components/GrFormField/context.d.ts +20 -0
  348. package/dist/types/src/components/GrFormField/index.d.ts +1 -0
  349. package/dist/types/src/components/GrFormFile/GrFormFile.vue.d.ts +4 -4
  350. package/dist/types/src/components/GrImageViewer/GrImageViewer.vue.d.ts +7 -3
  351. package/dist/types/src/components/GrImageViewer/composables/useViewerKeyboard.d.ts +20 -0
  352. package/dist/types/src/components/GrImageViewer/composables/useWheelGesture.d.ts +16 -0
  353. package/dist/types/src/components/GrImageViewer/composables/useZoomPan.d.ts +50 -0
  354. package/dist/types/src/components/GrInput/GrInput.vue.d.ts +49 -10
  355. package/dist/types/src/components/GrInput/defaults.d.ts +18 -0
  356. package/dist/types/src/components/GrInput/grInputStyles.d.ts +1 -1
  357. package/dist/types/src/components/GrInput/index.d.ts +1 -0
  358. package/dist/types/src/components/GrInputTag/GrInputTag.vue.d.ts +3 -3
  359. package/dist/types/src/components/GrKbd/GrKbd.vue.d.ts +46 -0
  360. package/dist/types/src/components/GrKbd/config.d.ts +1 -0
  361. package/dist/types/src/components/GrKbd/index.d.ts +4 -0
  362. package/dist/types/src/components/GrLink/GrLink.vue.d.ts +3 -3
  363. package/dist/types/src/components/GrLink/grLinkStyles.d.ts +3 -3
  364. package/dist/types/src/components/GrModal/grModalStyles.d.ts +1 -1
  365. package/dist/types/src/components/GrNumberInput/GrNumberInput.vue.d.ts +25 -9
  366. package/dist/types/src/components/GrNumberInput/defaults.d.ts +14 -0
  367. package/dist/types/src/components/GrNumberInput/index.d.ts +1 -0
  368. package/dist/types/src/components/GrPagination/GrPagination.vue.d.ts +18 -0
  369. package/dist/types/src/components/GrPromptDialog/GrPromptDialog.vue.d.ts +4 -4
  370. package/dist/types/src/components/GrRadio/GrRadio.vue.d.ts +5 -5
  371. package/dist/types/src/components/GrRadio/defaults.d.ts +14 -0
  372. package/dist/types/src/components/GrRadio/grRadioStyles.d.ts +3 -3
  373. package/dist/types/src/components/GrRadio/index.d.ts +1 -0
  374. package/dist/types/src/components/GrRadioGroup/GrRadioGroup.vue.d.ts +4 -4
  375. package/dist/types/src/components/GrRadioGroup/defaults.d.ts +14 -0
  376. package/dist/types/src/components/GrRadioGroup/index.d.ts +1 -0
  377. package/dist/types/src/components/GrRating/GrRating.vue.d.ts +124 -0
  378. package/dist/types/src/components/GrRating/config.d.ts +1 -0
  379. package/dist/types/src/components/GrRating/defaults.d.ts +14 -0
  380. package/dist/types/src/components/GrRating/grRatingStyles.d.ts +21 -0
  381. package/dist/types/src/components/GrRating/index.d.ts +6 -0
  382. package/dist/types/src/components/GrRating/safelist.d.ts +1 -0
  383. package/dist/types/src/components/GrResponseErrorBanner/GrUploadErrorBanner.vue.d.ts +1 -1
  384. package/dist/types/src/components/GrSegmented/GrSegmented.vue.d.ts +7 -7
  385. package/dist/types/src/components/GrSegmented/defaults.d.ts +15 -0
  386. package/dist/types/src/components/GrSegmented/grSegmentedStyles.d.ts +1 -1
  387. package/dist/types/src/components/GrSegmented/index.d.ts +1 -0
  388. package/dist/types/src/components/GrSelect/GrSelect.vue.d.ts +57 -17
  389. package/dist/types/src/components/GrSelect/defaults.d.ts +17 -0
  390. package/dist/types/src/components/GrSelect/grSelectStyles.d.ts +3 -3
  391. package/dist/types/src/components/GrSelect/index.d.ts +1 -0
  392. package/dist/types/src/components/GrSidebar/GrSidebarItem.vue.d.ts +2 -2
  393. package/dist/types/src/components/GrSkeleton/GrSkeleton.vue.d.ts +1 -1
  394. package/dist/types/src/components/GrSlider/GrSlider.vue.d.ts +88 -0
  395. package/dist/types/src/components/GrSlider/config.d.ts +1 -0
  396. package/dist/types/src/components/GrSlider/defaults.d.ts +14 -0
  397. package/dist/types/src/components/GrSlider/grSliderStyles.d.ts +36 -0
  398. package/dist/types/src/components/GrSlider/index.d.ts +6 -0
  399. package/dist/types/src/components/GrSlider/safelist.d.ts +1 -0
  400. package/dist/types/src/components/GrStatistic/GrStatistic.vue.d.ts +116 -0
  401. package/dist/types/src/components/GrStatistic/config.d.ts +1 -0
  402. package/dist/types/src/components/GrStatistic/formatStatisticValue.d.ts +16 -0
  403. package/dist/types/src/components/GrStatistic/grStatisticStyles.d.ts +24 -0
  404. package/dist/types/src/components/GrStatistic/index.d.ts +6 -0
  405. package/dist/types/src/components/GrStatistic/safelist.d.ts +1 -0
  406. package/dist/types/src/components/GrSwitch/GrSwitch.vue.d.ts +4 -4
  407. package/dist/types/src/components/GrSwitch/defaults.d.ts +14 -0
  408. package/dist/types/src/components/GrSwitch/grSwitchStyles.d.ts +2 -2
  409. package/dist/types/src/components/GrSwitch/index.d.ts +1 -0
  410. package/dist/types/src/components/GrTabPanels/GrTabPanel.vue.d.ts +46 -0
  411. package/dist/types/src/components/GrTabPanels/GrTabPanels.vue.d.ts +51 -0
  412. package/dist/types/src/components/GrTabPanels/config.d.ts +5 -0
  413. package/dist/types/src/components/GrTabPanels/context.d.ts +9 -0
  414. package/dist/types/src/components/GrTabPanels/index.d.ts +6 -0
  415. package/dist/types/src/components/GrTable/GrTable.vue.d.ts +16 -0
  416. package/dist/types/src/components/GrTabs/GrTabs.vue.d.ts +6 -0
  417. package/dist/types/src/components/GrTextarea/GrTextarea.vue.d.ts +5 -5
  418. package/dist/types/src/components/GrToaster/GrToaster.vue.d.ts +19 -2
  419. package/dist/types/src/components/GrToaster/index.d.ts +1 -1
  420. package/dist/types/src/components/GrTooltip/GrTooltip.vue.d.ts +1 -1
  421. package/dist/types/src/components/GrTree/grTreeInteractionContext.d.ts +2 -0
  422. package/dist/types/src/components/GrTreeSelect/GrTreeSelect.vue.d.ts +1 -1
  423. package/dist/types/src/components/GrTreeSelect/grTreeSelectStyles.d.ts +1 -1
  424. package/dist/types/src/composables/internal/useScrollLock.d.ts +24 -0
  425. package/dist/types/src/composables/useToast.d.ts +24 -0
  426. package/dist/types/src/granular-provider/shared.d.ts +10 -0
  427. package/dist/types/src/i18n/messages/en.d.ts +84 -0
  428. package/dist/types/src/i18n/messages/es.d.ts +84 -0
  429. package/dist/types/src/i18n/messages/ru.d.ts +84 -0
  430. package/dist/types/src/index.d.ts +10 -0
  431. package/dist/web-types.json +1642 -356
  432. package/package.json +41 -1
  433. package/dist/chunks/config-1uSYl98Y.js.map +0 -1
  434. package/dist/chunks/config-8Pcutu1j2.js.map +0 -1
  435. package/dist/chunks/config-B7IIWGt_2.js.map +0 -1
  436. package/dist/chunks/config-BIRO0vDJ2.js.map +0 -1
  437. package/dist/chunks/config-BLHqZhy-2.js.map +0 -1
  438. package/dist/chunks/config-BOlr7qw7.js.map +0 -1
  439. package/dist/chunks/config-BUHuGBik.js.map +0 -1
  440. package/dist/chunks/config-BX1JTrkV2.js.map +0 -1
  441. package/dist/chunks/config-C7NpDrfO.js.map +0 -1
  442. package/dist/chunks/config-ClhKPJvg.js.map +0 -1
  443. package/dist/chunks/config-Cpi9Mh2J.js.map +0 -1
  444. package/dist/chunks/config-CrG1XiE7.js.map +0 -1
  445. package/dist/chunks/config-DUcu1D68.js.map +0 -1
  446. package/dist/chunks/config-D_R56_gT.js.map +0 -1
  447. package/dist/chunks/config-DezDih8_.js.map +0 -1
  448. package/dist/chunks/config-DnvPqu4g.js.map +0 -1
  449. package/dist/chunks/config-DpqOnJiz2.js.map +0 -1
  450. package/dist/chunks/config-LGrZIdaZ2.js.map +0 -1
  451. package/dist/chunks/config-QaIc_gRa.js.map +0 -1
  452. package/dist/chunks/config-U4m9PSql.js.map +0 -1
  453. package/dist/chunks/config-eYLZYOUS2.js.map +0 -1
  454. package/dist/chunks/config-ipvU0lzP2.js.map +0 -1
  455. package/dist/chunks/config-xR4XVmcy.js.map +0 -1
  456. package/dist/chunks/en-BdtiS2d3.js.map +0 -1
  457. package/dist/chunks/es-BGRMZbe9.js.map +0 -1
  458. package/dist/chunks/grBadgeStyles-DrycBuKT.js.map +0 -1
  459. package/dist/chunks/grButtonStyles-C7Yga_Q1.js.map +0 -1
  460. package/dist/chunks/grModalStyles-DWd3i05Q.js.map +0 -1
  461. package/dist/chunks/grSelectStyles-CLK5hRd3.js.map +0 -1
  462. package/dist/chunks/grStyle-Blc9otAx.js.map +0 -1
  463. package/dist/chunks/ru-BFCnOiML.js.map +0 -1
  464. package/dist/chunks/shared-ChvcQgDl.js +0 -168
  465. package/dist/chunks/shared-ChvcQgDl.js.map +0 -1
  466. package/dist/chunks/transition-TLFw4KBn.js.map +0 -1
  467. package/dist/components/GrAlert/chunks/GrAlert-DPJSU_fG.js +0 -163
  468. package/dist/components/GrAlert/chunks/GrAlert-DPJSU_fG.js.map +0 -1
  469. package/dist/components/GrAvatar/chunks/GrAvatar-96CpTCq5.js.map +0 -1
  470. package/dist/components/GrBadge/chunks/GrBadge-B77XlaqE.js.map +0 -1
  471. package/dist/components/GrBadgeWrap/chunks/GrBadgeWrap-CcktMOdg.js.map +0 -1
  472. package/dist/components/GrBottomNav/chunks/GrBottomNav-usuMgG8_.js.map +0 -1
  473. package/dist/components/GrButton/chunks/GrButton-BlffdeJr.js.map +0 -1
  474. package/dist/components/GrCard/chunks/GrCard-DUNMkuHW.js.map +0 -1
  475. package/dist/components/GrCheckbox/chunks/GrCheckbox-DJhzZZdO.js.map +0 -1
  476. package/dist/components/GrCollapse/chunks/GrCollapse-CPPLh_xU.js.map +0 -1
  477. package/dist/components/GrConfirmDialog/chunks/GrConfirmDialog-BWYKCsHd.js.map +0 -1
  478. package/dist/components/GrDataTable/chunks/GrDataTable-ptbARmJ3.js +0 -179
  479. package/dist/components/GrDataTable/chunks/GrDataTable-ptbARmJ3.js.map +0 -1
  480. package/dist/components/GrDialog/chunks/GrDialog-5DAS-1Lb.js.map +0 -1
  481. package/dist/components/GrDialogService/chunks/GrDialogService-DY_fmaMu.js.map +0 -1
  482. package/dist/components/GrDrawer/chunks/GrDrawer-D1kzsjXN.js.map +0 -1
  483. package/dist/components/GrDropdown/chunks/GrDropdown-BXb5Cxxf.js.map +0 -1
  484. package/dist/components/GrDropdownMenu/chunks/GrDropdownMenu-DFEJLPcV.js.map +0 -1
  485. package/dist/components/GrEmptyState/chunks/GrEmptyState-CA3BiTV7.js.map +0 -1
  486. package/dist/components/GrFileUpload/chunks/GrFileUpload-DvWPpiJS.js.map +0 -1
  487. package/dist/components/GrFormField/chunks/GrFormField-BujNQrw8.js +0 -35
  488. package/dist/components/GrFormField/chunks/GrFormField-BujNQrw8.js.map +0 -1
  489. package/dist/components/GrFormFile/chunks/GrFormFile-CXcqqdvV.js.map +0 -1
  490. package/dist/components/GrFormSection/chunks/GrFormSection-Ce21jcgo.js.map +0 -1
  491. package/dist/components/GrImageViewer/chunks/GrImageViewer-OCUIrNh2.js.map +0 -1
  492. package/dist/components/GrInput/chunks/GrInput-C8pOJgCi.js +0 -188
  493. package/dist/components/GrInput/chunks/GrInput-C8pOJgCi.js.map +0 -1
  494. package/dist/components/GrInputTag/chunks/GrInputTag-zMgFqp2g.js.map +0 -1
  495. package/dist/components/GrList/chunks/GrList-Dx772Ns4.js.map +0 -1
  496. package/dist/components/GrLoading/chunks/GrLoading--X_7rdbb.js.map +0 -1
  497. package/dist/components/GrModal/chunks/GrModal-BkjW9jZS.js.map +0 -1
  498. package/dist/components/GrNavbar/chunks/GrNavbar-DW3MiIIf.js.map +0 -1
  499. package/dist/components/GrNumberInput/chunks/GrNumberInput-CldPIWQx.js.map +0 -1
  500. package/dist/components/GrPagination/chunks/GrPagination-Bu9wv6it.js.map +0 -1
  501. package/dist/components/GrProgressBar/chunks/GrProgressBar-CC3z-Zqp.js.map +0 -1
  502. package/dist/components/GrPromptDialog/chunks/GrPromptDialog-TmWXbpEP.js.map +0 -1
  503. package/dist/components/GrRadio/chunks/GrRadio-CPTixXaY.js.map +0 -1
  504. package/dist/components/GrRadioGroup/chunks/GrRadioGroup-vKZCbkCp.js.map +0 -1
  505. package/dist/components/GrSegmented/chunks/GrSegmented-C1y0UXpQ.js.map +0 -1
  506. package/dist/components/GrSelect/chunks/GrSelect-RShK21lK.js.map +0 -1
  507. package/dist/components/GrSidebar/chunks/GrSidebar-DkWozzwA.js.map +0 -1
  508. package/dist/components/GrSkeleton/chunks/GrSkeleton-DsN-_CDZ.js.map +0 -1
  509. package/dist/components/GrSwitch/chunks/GrSwitch-DAioyccZ.js.map +0 -1
  510. package/dist/components/GrTable/chunks/GrTable-Db3hRnKA.js.map +0 -1
  511. package/dist/components/GrTabs/chunks/GrTabs-Z-FDJUr_.js.map +0 -1
  512. package/dist/components/GrTextarea/chunks/GrTextarea-D56YxhKq.js.map +0 -1
  513. package/dist/components/GrToaster/chunks/GrToaster-eI8YvnIo.js.map +0 -1
  514. package/dist/components/GrTooltip/chunks/GrTooltip-BeyZ8ssR.js.map +0 -1
  515. package/dist/components/GrTree/chunks/GrTree-D3ODe2dB.js.map +0 -1
  516. package/dist/components/GrTreeSelect/chunks/GrTreeSelect-B2xBKs5Q.js.map +0 -1
  517. package/dist/chunks/{config-8Pcutu1j2.js → config-8Pcutu1j.js} +0 -0
  518. package/dist/chunks/{config-BLHqZhy-2.js → config-BLHqZhy-.js} +0 -0
  519. package/dist/chunks/{config-BUHuGBik.js → config-BUHuGBik2.js} +0 -0
  520. package/dist/chunks/{config-BX1JTrkV2.js → config-BX1JTrkV.js} +0 -0
  521. package/dist/chunks/{config-DpqOnJiz2.js → config-DpqOnJiz.js} +0 -0
  522. package/dist/chunks/{config-Cpi9Mh2J.js → config-Dqy0rPPO2.js} +1 -1
  523. /package/dist/chunks/{config-LGrZIdaZ2.js → config-LGrZIdaZ.js} +0 -0
  524. /package/dist/chunks/{config-QaIc_gRa.js → config-QaIc_gRa2.js} +0 -0
  525. /package/dist/chunks/{config-U4m9PSql.js → config-U4m9PSql2.js} +0 -0
  526. /package/dist/chunks/{config-ipvU0lzP2.js → config-ipvU0lzP.js} +0 -0
  527. /package/dist/chunks/{config-xR4XVmcy.js → config-xR4XVmcy2.js} +0 -0
@@ -0,0 +1,234 @@
1
+ import { n as useGranularityTranslations } from "../../../chunks/granularityI18n-SH0I--GW.js";
2
+ import { t as GR_FORM_KEY } from "../../../chunks/context-Bfrgsluh.js";
3
+ import { computed, createElementBlock, defineComponent, onBeforeUnmount, openBlock, provide, ref, renderSlot, watch, withModifiers } from "vue";
4
+ //#region src/components/GrForm/validation.ts
5
+ var EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
6
+ function isUrl(value) {
7
+ return URL.canParse(value);
8
+ }
9
+ /** Пустое значение: `null`/`undefined`/пустая (или пробельная) строка/пустой массив. */
10
+ function isEmpty(value) {
11
+ if (value == null) return true;
12
+ if (typeof value === "string") return value.trim() === "";
13
+ if (Array.isArray(value)) return value.length === 0;
14
+ return false;
15
+ }
16
+ /** Мера значения для min/max/len: число → само значение, строка/массив → длина. */
17
+ function measure(value) {
18
+ if (typeof value === "number") return value;
19
+ if (typeof value === "string") return value.length;
20
+ if (Array.isArray(value)) return value.length;
21
+ return Number(value);
22
+ }
23
+ /** Достаёт значение из объекта по dot-path (`address.city`). */
24
+ function getByPath(obj, path) {
25
+ if (!path.includes(".")) return obj[path];
26
+ return path.split(".").reduce((acc, key) => {
27
+ if (acc && typeof acc === "object") return acc[key];
28
+ }, obj);
29
+ }
30
+ /** Записывает значение в объект по dot-path (создаёт промежуточные объекты). */
31
+ function setByPath(obj, path, value) {
32
+ const keys = path.split(".");
33
+ const last = keys.pop();
34
+ let target = obj;
35
+ for (const key of keys) {
36
+ if (!target[key] || typeof target[key] !== "object") target[key] = {};
37
+ target = target[key];
38
+ }
39
+ target[last] = value;
40
+ }
41
+ /** Нормализует правило(а) поля в массив. */
42
+ function toRuleArray(rules) {
43
+ if (!rules) return [];
44
+ return Array.isArray(rules) ? rules : [rules];
45
+ }
46
+ function ruleMatchesTrigger(rule, trigger) {
47
+ if (!trigger) return true;
48
+ if (!rule.trigger) return true;
49
+ return (Array.isArray(rule.trigger) ? rule.trigger : [rule.trigger]).includes(trigger);
50
+ }
51
+ /** Правила поля, применимые для данного триггера (undefined = все). */
52
+ function rulesForTrigger(rules, trigger) {
53
+ return rules.filter((rule) => ruleMatchesTrigger(rule, trigger));
54
+ }
55
+ /** Есть ли среди правил `required` (для маркера обязательности в поле). */
56
+ function rulesRequired(rules) {
57
+ return rules.some((rule) => rule.required === true);
58
+ }
59
+ /**
60
+ * Прогоняет правила по порядку, возвращает первое сообщение об ошибке или `undefined`.
61
+ * Пустое необязательное значение проходит все проверки (кроме `required`).
62
+ */
63
+ async function runFieldRules(value, rules, model, resolveMessage) {
64
+ for (const rule of rules) {
65
+ const empty = isEmpty(value);
66
+ if (rule.required && empty) return resolveMessage("required", rule, {});
67
+ if (empty) continue;
68
+ if (rule.type === "email" && !EMAIL_RE.test(String(value))) return resolveMessage("email", rule, {});
69
+ if (rule.type === "url" && !isUrl(String(value))) return resolveMessage("url", rule, {});
70
+ if (rule.len != null && measure(value) !== rule.len) return resolveMessage("len", rule, { len: rule.len });
71
+ if (rule.min != null && measure(value) < rule.min) return resolveMessage("min", rule, { min: rule.min });
72
+ if (rule.max != null && measure(value) > rule.max) return resolveMessage("max", rule, { max: rule.max });
73
+ if (rule.pattern && !rule.pattern.test(String(value))) return resolveMessage("pattern", rule, {});
74
+ if (rule.validator) {
75
+ const result = await rule.validator(value, model);
76
+ if (result === false) return rule.message ?? resolveMessage("invalid", rule, {});
77
+ if (typeof result === "string") return result;
78
+ }
79
+ }
80
+ }
81
+ //#endregion
82
+ //#region src/components/GrForm/GrForm.vue
83
+ var GrForm_default = /* @__PURE__ */ defineComponent({
84
+ __name: "GrForm",
85
+ props: {
86
+ model: {},
87
+ rules: { default: void 0 },
88
+ validateOnBlur: {
89
+ type: Boolean,
90
+ default: true
91
+ },
92
+ validateOnChange: {
93
+ type: Boolean,
94
+ default: false
95
+ },
96
+ scrollToError: {
97
+ type: Boolean,
98
+ default: true
99
+ },
100
+ scrollBehavior: { default: "smooth" }
101
+ },
102
+ emits: ["submit", "validate"],
103
+ setup(__props, { expose: __expose, emit: __emit }) {
104
+ const props = __props;
105
+ const emit = __emit;
106
+ const { t } = useGranularityTranslations();
107
+ const errors = ref({});
108
+ const fieldRegistry = /* @__PURE__ */ new Map();
109
+ function getRules(name) {
110
+ return toRuleArray(props.rules?.[name]);
111
+ }
112
+ function getValue(name) {
113
+ return getByPath(props.model, name);
114
+ }
115
+ const requiredFields = computed(() => {
116
+ const set = /* @__PURE__ */ new Set();
117
+ for (const name of Object.keys(props.rules ?? {})) if (rulesRequired(getRules(name))) set.add(name);
118
+ return set;
119
+ });
120
+ const resolveMessage = (kind, rule, params) => {
121
+ if (rule.message) return rule.message;
122
+ return t(`gr.form.${kind}`, {
123
+ required: "This field is required",
124
+ min: "Minimum is {min}",
125
+ max: "Maximum is {max}",
126
+ len: "Length must be {len}",
127
+ pattern: "Invalid format",
128
+ email: "Enter a valid email",
129
+ url: "Enter a valid URL",
130
+ invalid: "Invalid value"
131
+ }[kind], params);
132
+ };
133
+ async function validateField(name, trigger) {
134
+ if (trigger === "blur" && !props.validateOnBlur) return !errors.value[name];
135
+ const rules = rulesForTrigger(getRules(name), trigger);
136
+ if (!rules.length) return !errors.value[name];
137
+ const message = await runFieldRules(getValue(name), rules, props.model, resolveMessage);
138
+ errors.value = {
139
+ ...errors.value,
140
+ [name]: message
141
+ };
142
+ emit("validate", name, !message, message);
143
+ return !message;
144
+ }
145
+ async function validate() {
146
+ const names = Object.keys(props.rules ?? {});
147
+ const valid = (await Promise.all(names.map((name) => validateField(name)))).every(Boolean);
148
+ if (!valid && props.scrollToError) scrollToFirstError();
149
+ return valid;
150
+ }
151
+ function clearValidate(names) {
152
+ if (!names) {
153
+ errors.value = {};
154
+ return;
155
+ }
156
+ const list = Array.isArray(names) ? names : [names];
157
+ const next = { ...errors.value };
158
+ for (const name of list) delete next[name];
159
+ errors.value = next;
160
+ }
161
+ function cloneData(value) {
162
+ return value === void 0 ? value : JSON.parse(JSON.stringify(value));
163
+ }
164
+ const initialSnapshot = ref(cloneData(props.model));
165
+ function resetFields() {
166
+ const snapshot = initialSnapshot.value;
167
+ for (const key of Object.keys(props.model)) setByPath(props.model, key, cloneData(snapshot[key]));
168
+ clearValidate();
169
+ }
170
+ function scrollToField(name) {
171
+ const el = fieldRegistry.get(name)?.();
172
+ if (!el) return;
173
+ el.scrollIntoView({
174
+ behavior: props.scrollBehavior,
175
+ block: "center"
176
+ });
177
+ el.querySelector("input, select, textarea, button, [tabindex]:not([tabindex=\"-1\"])")?.focus?.();
178
+ }
179
+ function scrollToFirstError() {
180
+ const elements = [...fieldRegistry.entries()].filter(([name]) => errors.value[name]).map(([, getEl]) => getEl()).filter((el) => Boolean(el));
181
+ elements.sort((a, b) => a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1);
182
+ const first = elements[0];
183
+ if (!first) return;
184
+ first.scrollIntoView({
185
+ behavior: props.scrollBehavior,
186
+ block: "center"
187
+ });
188
+ first.querySelector("input, select, textarea, button, [tabindex]:not([tabindex=\"-1\"])")?.focus?.();
189
+ }
190
+ let stopWatchers = [];
191
+ watch(() => Object.keys(props.rules ?? {}), (names) => {
192
+ stopWatchers.forEach((stop) => stop());
193
+ stopWatchers = names.map((name) => watch(() => getValue(name), () => {
194
+ if (props.validateOnChange) validateField(name, "change");
195
+ else if (errors.value[name]) validateField(name);
196
+ }, { deep: true }));
197
+ }, { immediate: true });
198
+ onBeforeUnmount(() => stopWatchers.forEach((stop) => stop()));
199
+ provide(GR_FORM_KEY, {
200
+ errors,
201
+ requiredFields,
202
+ hasField: (name) => getRules(name).length > 0,
203
+ registerField: (name, getEl) => {
204
+ fieldRegistry.set(name, getEl);
205
+ return () => fieldRegistry.delete(name);
206
+ },
207
+ validateField
208
+ });
209
+ function onSubmit() {
210
+ validate().then((valid) => {
211
+ if (valid) emit("submit", props.model);
212
+ });
213
+ }
214
+ __expose({
215
+ validate,
216
+ validateField,
217
+ clearValidate,
218
+ resetFields,
219
+ scrollToField
220
+ });
221
+ return (_ctx, _cache) => {
222
+ return openBlock(), createElementBlock("form", {
223
+ "data-gr-form": "",
224
+ novalidate: "",
225
+ onSubmit: withModifiers(onSubmit, ["prevent"])
226
+ }, [renderSlot(_ctx.$slots, "default", {
227
+ validate,
228
+ errors: errors.value
229
+ })], 32);
230
+ };
231
+ }
232
+ });
233
+ //#endregion
234
+ export { runFieldRules as i, getByPath as n, isEmpty as r, GrForm_default as t };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GrForm-CdaFjcyl.js","names":[],"sources":["../../../../src/components/GrForm/validation.ts","../../../../src/components/GrForm/GrForm.vue","../../../../src/components/GrForm/GrForm.vue"],"sourcesContent":["/**\n * Движок валидации `GrForm` — чистый (без Vue/i18n), тестируется изолированно.\n *\n * Правило описывает набор проверок значения поля; `runFieldRules` прогоняет их по\n * порядку и возвращает первое сообщение об ошибке (или `undefined`, если валидно).\n * Сообщения резолвит потребитель (компонент) через `resolveMessage` — так i18n и\n * дефолтные тексты остаются в компоненте, а движок ничего о них не знает.\n */\n\nexport type GrFormTrigger = 'blur' | 'change' | 'submit'\n\n/** Результат кастомного валидатора: `true`/void — ок; `false` — ошибка (дефолт-текст); строка — текст ошибки. */\nexport type GrFormValidatorResult = boolean | string | void\n\nexport interface GrFormRule {\n /** Значение обязательно (не пустое). */\n required?: boolean\n /** Готовый текст ошибки — перекрывает дефолтное сообщение любой проверки этого правила. */\n message?: string\n /** Минимум: длина для строки/массива, значение для числа. */\n min?: number\n /** Максимум: длина для строки/массива, значение для числа. */\n max?: number\n /** Точная длина/значение. */\n len?: number\n /** Регулярное выражение (проверяется по `String(value)`). */\n pattern?: RegExp\n /** Встроенный тип-валидатор. */\n type?: 'email' | 'url'\n /** Кастомный (в т.ч. async) валидатор. Второй аргумент — весь `model`. */\n validator?: (value: unknown, model: Record<string, unknown>) => GrFormValidatorResult | Promise<GrFormValidatorResult>\n /** Когда правило срабатывает. По умолчанию — на любом триггере (blur/change/submit). */\n trigger?: GrFormTrigger | GrFormTrigger[]\n}\n\nexport type GrFormRules = Record<string, GrFormRule | GrFormRule[]>\n\n/** Вид сработавшей проверки — ключ для дефолтного i18n-сообщения. */\nexport type GrFormRuleFailure = 'required' | 'min' | 'max' | 'len' | 'pattern' | 'email' | 'url' | 'invalid'\n\nexport type GrFormMessageResolver = (\n kind: GrFormRuleFailure,\n rule: GrFormRule,\n params: Record<string, unknown>,\n) => string\n\nconst EMAIL_RE = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/\n\nfunction isUrl(value: string): boolean {\n return URL.canParse(value)\n}\n\n/** Пустое значение: `null`/`undefined`/пустая (или пробельная) строка/пустой массив. */\nexport function isEmpty(value: unknown): boolean {\n if (value == null) return true\n if (typeof value === 'string') return value.trim() === ''\n if (Array.isArray(value)) return value.length === 0\n return false\n}\n\n/** Мера значения для min/max/len: число → само значение, строка/массив → длина. */\nfunction measure(value: unknown): number {\n if (typeof value === 'number') return value\n if (typeof value === 'string') return value.length\n if (Array.isArray(value)) return value.length\n return Number(value)\n}\n\n/** Достаёт значение из объекта по dot-path (`address.city`). */\nexport function getByPath(obj: Record<string, unknown>, path: string): unknown {\n if (!path.includes('.')) return obj[path]\n return path.split('.').reduce<unknown>((acc, key) => {\n if (acc && typeof acc === 'object') return (acc as Record<string, unknown>)[key]\n return undefined\n }, obj)\n}\n\n/** Записывает значение в объект по dot-path (создаёт промежуточные объекты). */\nexport function setByPath(obj: Record<string, unknown>, path: string, value: unknown): void {\n const keys = path.split('.')\n const last = keys.pop() as string\n let target = obj\n for (const key of keys) {\n if (!target[key] || typeof target[key] !== 'object') target[key] = {}\n target = target[key] as Record<string, unknown>\n }\n target[last] = value\n}\n\n/** Нормализует правило(а) поля в массив. */\nexport function toRuleArray(rules: GrFormRule | GrFormRule[] | undefined): GrFormRule[] {\n if (!rules) return []\n return Array.isArray(rules) ? rules : [rules]\n}\n\nfunction ruleMatchesTrigger(rule: GrFormRule, trigger?: GrFormTrigger): boolean {\n if (!trigger) return true // полная валидация (validate()) — все правила\n if (!rule.trigger) return true // правило без триггера срабатывает на любом\n const triggers = Array.isArray(rule.trigger) ? rule.trigger : [rule.trigger]\n return triggers.includes(trigger)\n}\n\n/** Правила поля, применимые для данного триггера (undefined = все). */\nexport function rulesForTrigger(rules: GrFormRule[], trigger?: GrFormTrigger): GrFormRule[] {\n return rules.filter(rule => ruleMatchesTrigger(rule, trigger))\n}\n\n/** Есть ли среди правил `required` (для маркера обязательности в поле). */\nexport function rulesRequired(rules: GrFormRule[]): boolean {\n return rules.some(rule => rule.required === true)\n}\n\n/**\n * Прогоняет правила по порядку, возвращает первое сообщение об ошибке или `undefined`.\n * Пустое необязательное значение проходит все проверки (кроме `required`).\n */\nexport async function runFieldRules(\n value: unknown,\n rules: GrFormRule[],\n model: Record<string, unknown>,\n resolveMessage: GrFormMessageResolver,\n): Promise<string | undefined> {\n for (const rule of rules) {\n const empty = isEmpty(value)\n\n if (rule.required && empty) return resolveMessage('required', rule, {})\n // Необязательное пустое значение — остальные проверки этого правила пропускаем.\n if (empty) continue\n\n if (rule.type === 'email' && !EMAIL_RE.test(String(value))) return resolveMessage('email', rule, {})\n if (rule.type === 'url' && !isUrl(String(value))) return resolveMessage('url', rule, {})\n\n if (rule.len != null && measure(value) !== rule.len) return resolveMessage('len', rule, { len: rule.len })\n if (rule.min != null && measure(value) < rule.min) return resolveMessage('min', rule, { min: rule.min })\n if (rule.max != null && measure(value) > rule.max) return resolveMessage('max', rule, { max: rule.max })\n\n if (rule.pattern && !rule.pattern.test(String(value))) return resolveMessage('pattern', rule, {})\n\n if (rule.validator) {\n const result = await rule.validator(value, model)\n if (result === false) return rule.message ?? resolveMessage('invalid', rule, {})\n if (typeof result === 'string') return result\n }\n }\n\n return undefined\n}\n","<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, provide, ref, watch } from 'vue'\n\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport { GR_FORM_KEY } from './context'\nimport {\n getByPath,\n rulesForTrigger,\n rulesRequired,\n runFieldRules,\n setByPath,\n toRuleArray,\n type GrFormMessageResolver,\n type GrFormRule,\n type GrFormRules,\n type GrFormTrigger,\n} from './validation'\n\nexport type {\n GrFormRule,\n GrFormRules,\n GrFormTrigger,\n GrFormValidatorResult,\n} from './validation'\n\n/**\n * Публичный GR-примитив «Form» — оркестрация валидации над `GrFormField`.\n *\n * Модель формы (`v-model`-объект приложения) + декларативные `rules` по имени поля.\n * Форма прогоняет правила, раскладывает ошибки по контексту, скроллит к первой\n * ошибке и эмитит `submit` только при валидной форме. Императивный API — через\n * template ref (`validate` / `validateField` / `clearValidate` / `resetFields` /\n * `scrollToField`).\n */\nexport interface GrFormProps {\n /** Реактивный объект данных формы. Поля адресуются по `name` (`GrFormField`), в т.ч. dot-path. */\n model: Record<string, unknown>\n /** Правила валидации по имени поля: `{ email: [{ required: true, type: 'email' }] }`. */\n rules?: GrFormRules\n /** Валидировать поле при потере фокуса. */\n validateOnBlur?: boolean\n /** Валидировать поле при каждом изменении значения. */\n validateOnChange?: boolean\n /** Скроллить к первому невалидному полю после `validate()`. */\n scrollToError?: boolean\n scrollBehavior?: ScrollBehavior\n}\n\nconst props = withDefaults(\n defineProps<GrFormProps>(),\n {\n rules: undefined,\n validateOnBlur: true,\n validateOnChange: false,\n scrollToError: true,\n scrollBehavior: 'smooth',\n },\n)\n\nconst emit = defineEmits<{\n /** Форма прошла валидацию по submit. Отдаёт `model`. */\n (e: 'submit', model: Record<string, unknown>): void\n /** Результат валидации одного поля. */\n (e: 'validate', name: string, valid: boolean, message: string | undefined): void\n}>()\n\nconst { t } = useGranularityTranslations()\n\n// ————— Ошибки и реестр полей.\nconst errors = ref<Record<string, string | undefined>>({})\nconst fieldRegistry = new Map<string, () => HTMLElement | null>()\n\nfunction getRules(name: string): GrFormRule[] {\n return toRuleArray(props.rules?.[name])\n}\n\nfunction getValue(name: string): unknown {\n return getByPath(props.model, name)\n}\n\nconst requiredFields = computed(() => {\n const set = new Set<string>()\n for (const name of Object.keys(props.rules ?? {})) {\n if (rulesRequired(getRules(name))) set.add(name)\n }\n return set\n})\n\n// Дефолтные i18n-сообщения (перекрываются `rule.message`).\nconst resolveMessage: GrFormMessageResolver = (kind, rule, params) => {\n if (rule.message) return rule.message\n const fallback: Record<string, string> = {\n required: 'This field is required',\n min: 'Minimum is {min}',\n max: 'Maximum is {max}',\n len: 'Length must be {len}',\n pattern: 'Invalid format',\n email: 'Enter a valid email',\n url: 'Enter a valid URL',\n invalid: 'Invalid value',\n }\n return t(`gr.form.${kind}`, fallback[kind], params)\n}\n\n// ————— Валидация.\nasync function validateField(name: string, trigger?: GrFormTrigger): Promise<boolean> {\n if (trigger === 'blur' && !props.validateOnBlur) return !errors.value[name]\n\n const rules = rulesForTrigger(getRules(name), trigger)\n if (!rules.length) return !errors.value[name]\n\n const message = await runFieldRules(getValue(name), rules, props.model, resolveMessage)\n errors.value = { ...errors.value, [name]: message }\n emit('validate', name, !message, message)\n return !message\n}\n\nasync function validate(): Promise<boolean> {\n const names = Object.keys(props.rules ?? {})\n const results = await Promise.all(names.map(name => validateField(name)))\n const valid = results.every(Boolean)\n if (!valid && props.scrollToError) scrollToFirstError()\n return valid\n}\n\nfunction clearValidate(names?: string | string[]): void {\n if (!names) {\n errors.value = {}\n return\n }\n const list = Array.isArray(names) ? names : [names]\n const next = { ...errors.value }\n for (const name of list) delete next[name]\n errors.value = next\n}\n\n// Снимок начальных значений для `resetFields`. JSON-клон читает «сквозь» reactive-\n// прокси и даёт простой снимок (модель формы — JSON-данные); `structuredClone` на\n// прокси падает с DataCloneError.\nfunction cloneData<T>(value: T): T {\n return value === undefined ? value : (JSON.parse(JSON.stringify(value)) as T)\n}\n\nconst initialSnapshot = ref<Record<string, unknown>>(cloneData(props.model))\n\nfunction resetFields(): void {\n const snapshot = initialSnapshot.value\n for (const key of Object.keys(props.model)) {\n setByPath(props.model, key, cloneData(snapshot[key]))\n }\n clearValidate()\n}\n\n// ————— Scroll-to-error.\nfunction scrollToField(name: string): void {\n const el = fieldRegistry.get(name)?.()\n if (!el) return\n el.scrollIntoView({ behavior: props.scrollBehavior, block: 'center' })\n const focusable = el.querySelector<HTMLElement>('input, select, textarea, button, [tabindex]:not([tabindex=\"-1\"])')\n focusable?.focus?.()\n}\n\nfunction scrollToFirstError(): void {\n const elements = [...fieldRegistry.entries()]\n .filter(([name]) => errors.value[name])\n .map(([, getEl]) => getEl())\n .filter((el): el is HTMLElement => Boolean(el))\n\n // Первое по порядку в DOM — «самое верхнее» невалидное поле на экране.\n elements.sort((a, b) =>\n (a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING) ? -1 : 1,\n )\n\n const first = elements[0]\n if (!first) return\n first.scrollIntoView({ behavior: props.scrollBehavior, block: 'center' })\n first.querySelector<HTMLElement>('input, select, textarea, button, [tabindex]:not([tabindex=\"-1\"])')?.focus?.()\n}\n\n// ————— «Умный» change: чистим ошибку по мере исправления; валидируем при validateOnChange.\nlet stopWatchers: Array<() => void> = []\nwatch(\n () => Object.keys(props.rules ?? {}),\n (names) => {\n stopWatchers.forEach(stop => stop())\n stopWatchers = names.map(name =>\n watch(\n () => getValue(name),\n () => {\n if (props.validateOnChange) void validateField(name, 'change')\n else if (errors.value[name]) void validateField(name) // ре-валидация, чтобы снять ошибку\n },\n { deep: true },\n ),\n )\n },\n { immediate: true },\n)\n\nonBeforeUnmount(() => stopWatchers.forEach(stop => stop()))\n\n// ————— Контекст для `GrFormField`.\nprovide(GR_FORM_KEY, {\n errors,\n requiredFields,\n hasField: (name: string) => getRules(name).length > 0,\n registerField: (name, getEl) => {\n fieldRegistry.set(name, getEl)\n return () => fieldRegistry.delete(name)\n },\n validateField,\n})\n\nfunction onSubmit(): void {\n void validate().then((valid) => {\n if (valid) emit('submit', props.model)\n })\n}\n\ndefineExpose({\n validate,\n validateField,\n clearValidate,\n resetFields,\n scrollToField,\n})\n</script>\n\n<template>\n <form data-gr-form novalidate @submit.prevent=\"onSubmit\">\n <slot :validate=\"validate\" :errors=\"errors\" />\n </form>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, provide, ref, watch } from 'vue'\n\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport { GR_FORM_KEY } from './context'\nimport {\n getByPath,\n rulesForTrigger,\n rulesRequired,\n runFieldRules,\n setByPath,\n toRuleArray,\n type GrFormMessageResolver,\n type GrFormRule,\n type GrFormRules,\n type GrFormTrigger,\n} from './validation'\n\nexport type {\n GrFormRule,\n GrFormRules,\n GrFormTrigger,\n GrFormValidatorResult,\n} from './validation'\n\n/**\n * Публичный GR-примитив «Form» — оркестрация валидации над `GrFormField`.\n *\n * Модель формы (`v-model`-объект приложения) + декларативные `rules` по имени поля.\n * Форма прогоняет правила, раскладывает ошибки по контексту, скроллит к первой\n * ошибке и эмитит `submit` только при валидной форме. Императивный API — через\n * template ref (`validate` / `validateField` / `clearValidate` / `resetFields` /\n * `scrollToField`).\n */\nexport interface GrFormProps {\n /** Реактивный объект данных формы. Поля адресуются по `name` (`GrFormField`), в т.ч. dot-path. */\n model: Record<string, unknown>\n /** Правила валидации по имени поля: `{ email: [{ required: true, type: 'email' }] }`. */\n rules?: GrFormRules\n /** Валидировать поле при потере фокуса. */\n validateOnBlur?: boolean\n /** Валидировать поле при каждом изменении значения. */\n validateOnChange?: boolean\n /** Скроллить к первому невалидному полю после `validate()`. */\n scrollToError?: boolean\n scrollBehavior?: ScrollBehavior\n}\n\nconst props = withDefaults(\n defineProps<GrFormProps>(),\n {\n rules: undefined,\n validateOnBlur: true,\n validateOnChange: false,\n scrollToError: true,\n scrollBehavior: 'smooth',\n },\n)\n\nconst emit = defineEmits<{\n /** Форма прошла валидацию по submit. Отдаёт `model`. */\n (e: 'submit', model: Record<string, unknown>): void\n /** Результат валидации одного поля. */\n (e: 'validate', name: string, valid: boolean, message: string | undefined): void\n}>()\n\nconst { t } = useGranularityTranslations()\n\n// ————— Ошибки и реестр полей.\nconst errors = ref<Record<string, string | undefined>>({})\nconst fieldRegistry = new Map<string, () => HTMLElement | null>()\n\nfunction getRules(name: string): GrFormRule[] {\n return toRuleArray(props.rules?.[name])\n}\n\nfunction getValue(name: string): unknown {\n return getByPath(props.model, name)\n}\n\nconst requiredFields = computed(() => {\n const set = new Set<string>()\n for (const name of Object.keys(props.rules ?? {})) {\n if (rulesRequired(getRules(name))) set.add(name)\n }\n return set\n})\n\n// Дефолтные i18n-сообщения (перекрываются `rule.message`).\nconst resolveMessage: GrFormMessageResolver = (kind, rule, params) => {\n if (rule.message) return rule.message\n const fallback: Record<string, string> = {\n required: 'This field is required',\n min: 'Minimum is {min}',\n max: 'Maximum is {max}',\n len: 'Length must be {len}',\n pattern: 'Invalid format',\n email: 'Enter a valid email',\n url: 'Enter a valid URL',\n invalid: 'Invalid value',\n }\n return t(`gr.form.${kind}`, fallback[kind], params)\n}\n\n// ————— Валидация.\nasync function validateField(name: string, trigger?: GrFormTrigger): Promise<boolean> {\n if (trigger === 'blur' && !props.validateOnBlur) return !errors.value[name]\n\n const rules = rulesForTrigger(getRules(name), trigger)\n if (!rules.length) return !errors.value[name]\n\n const message = await runFieldRules(getValue(name), rules, props.model, resolveMessage)\n errors.value = { ...errors.value, [name]: message }\n emit('validate', name, !message, message)\n return !message\n}\n\nasync function validate(): Promise<boolean> {\n const names = Object.keys(props.rules ?? {})\n const results = await Promise.all(names.map(name => validateField(name)))\n const valid = results.every(Boolean)\n if (!valid && props.scrollToError) scrollToFirstError()\n return valid\n}\n\nfunction clearValidate(names?: string | string[]): void {\n if (!names) {\n errors.value = {}\n return\n }\n const list = Array.isArray(names) ? names : [names]\n const next = { ...errors.value }\n for (const name of list) delete next[name]\n errors.value = next\n}\n\n// Снимок начальных значений для `resetFields`. JSON-клон читает «сквозь» reactive-\n// прокси и даёт простой снимок (модель формы — JSON-данные); `structuredClone` на\n// прокси падает с DataCloneError.\nfunction cloneData<T>(value: T): T {\n return value === undefined ? value : (JSON.parse(JSON.stringify(value)) as T)\n}\n\nconst initialSnapshot = ref<Record<string, unknown>>(cloneData(props.model))\n\nfunction resetFields(): void {\n const snapshot = initialSnapshot.value\n for (const key of Object.keys(props.model)) {\n setByPath(props.model, key, cloneData(snapshot[key]))\n }\n clearValidate()\n}\n\n// ————— Scroll-to-error.\nfunction scrollToField(name: string): void {\n const el = fieldRegistry.get(name)?.()\n if (!el) return\n el.scrollIntoView({ behavior: props.scrollBehavior, block: 'center' })\n const focusable = el.querySelector<HTMLElement>('input, select, textarea, button, [tabindex]:not([tabindex=\"-1\"])')\n focusable?.focus?.()\n}\n\nfunction scrollToFirstError(): void {\n const elements = [...fieldRegistry.entries()]\n .filter(([name]) => errors.value[name])\n .map(([, getEl]) => getEl())\n .filter((el): el is HTMLElement => Boolean(el))\n\n // Первое по порядку в DOM — «самое верхнее» невалидное поле на экране.\n elements.sort((a, b) =>\n (a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING) ? -1 : 1,\n )\n\n const first = elements[0]\n if (!first) return\n first.scrollIntoView({ behavior: props.scrollBehavior, block: 'center' })\n first.querySelector<HTMLElement>('input, select, textarea, button, [tabindex]:not([tabindex=\"-1\"])')?.focus?.()\n}\n\n// ————— «Умный» change: чистим ошибку по мере исправления; валидируем при validateOnChange.\nlet stopWatchers: Array<() => void> = []\nwatch(\n () => Object.keys(props.rules ?? {}),\n (names) => {\n stopWatchers.forEach(stop => stop())\n stopWatchers = names.map(name =>\n watch(\n () => getValue(name),\n () => {\n if (props.validateOnChange) void validateField(name, 'change')\n else if (errors.value[name]) void validateField(name) // ре-валидация, чтобы снять ошибку\n },\n { deep: true },\n ),\n )\n },\n { immediate: true },\n)\n\nonBeforeUnmount(() => stopWatchers.forEach(stop => stop()))\n\n// ————— Контекст для `GrFormField`.\nprovide(GR_FORM_KEY, {\n errors,\n requiredFields,\n hasField: (name: string) => getRules(name).length > 0,\n registerField: (name, getEl) => {\n fieldRegistry.set(name, getEl)\n return () => fieldRegistry.delete(name)\n },\n validateField,\n})\n\nfunction onSubmit(): void {\n void validate().then((valid) => {\n if (valid) emit('submit', props.model)\n })\n}\n\ndefineExpose({\n validate,\n validateField,\n clearValidate,\n resetFields,\n scrollToField,\n})\n</script>\n\n<template>\n <form data-gr-form novalidate @submit.prevent=\"onSubmit\">\n <slot :validate=\"validate\" :errors=\"errors\" />\n </form>\n</template>\n"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { n as useGrFormContext, t as GR_FORM_KEY } from "../../chunks/context-Bfrgsluh.js";
2
+ import { i as runFieldRules, n as getByPath, r as isEmpty, t as GrForm_default } from "./chunks/GrForm-CdaFjcyl.js";
3
+ import { t as grFormConfig } from "../../chunks/config-Droqn55j.js";
4
+ export { GR_FORM_KEY, GrForm_default as GrForm, GrForm_default as default, getByPath, grFormConfig, isEmpty, runFieldRules, useGrFormContext };
@@ -0,0 +1,100 @@
1
+ import { t as GR_FORM_FIELD_KEY } from "../../../chunks/context-DdNIxa1w.js";
2
+ import { n as useGrFormContext } from "../../../chunks/context-Bfrgsluh.js";
3
+ import { computed, createCommentVNode, createElementBlock, createTextVNode, defineComponent, normalizeClass, onBeforeUnmount, onMounted, openBlock, provide, ref, renderSlot, toDisplayString, unref, useId, useSlots } from "vue";
4
+ //#region src/components/GrFormField/GrFormField.vue?vue&type=script&setup=true&lang.ts
5
+ var _hoisted_1 = ["for"];
6
+ var _hoisted_2 = {
7
+ key: 0,
8
+ "data-gr-form-field-required": "",
9
+ "aria-hidden": "true",
10
+ class: "text-[var(--gr-danger)]"
11
+ };
12
+ var _hoisted_3 = ["id"];
13
+ var _hoisted_4 = ["id"];
14
+ //#endregion
15
+ //#region src/components/GrFormField/GrFormField.vue
16
+ var GrFormField_default = /* @__PURE__ */ defineComponent({
17
+ __name: "GrFormField",
18
+ props: {
19
+ label: { default: void 0 },
20
+ name: { default: void 0 },
21
+ forId: { default: void 0 },
22
+ error: { default: void 0 },
23
+ hint: { default: void 0 },
24
+ required: {
25
+ type: Boolean,
26
+ default: false
27
+ },
28
+ labelClass: { default: void 0 }
29
+ },
30
+ setup(__props) {
31
+ const props = __props;
32
+ const slots = useSlots();
33
+ const form = useGrFormContext();
34
+ const boundToForm = computed(() => Boolean(form && props.name && form.hasField(props.name)));
35
+ const generatedId = useId();
36
+ const fieldId = computed(() => props.forId ?? generatedId);
37
+ const errorId = useId();
38
+ const hintId = useId();
39
+ const resolvedError = computed(() => {
40
+ if (props.error) return props.error;
41
+ if (boundToForm.value && props.name) return form.errors.value[props.name];
42
+ });
43
+ const isRequired = computed(() => {
44
+ if (props.required) return true;
45
+ if (boundToForm.value && props.name) return form.requiredFields.value.has(props.name);
46
+ return false;
47
+ });
48
+ const hasHint = computed(() => Boolean(props.hint) || Boolean(slots.hint));
49
+ const hasError = computed(() => Boolean(resolvedError.value));
50
+ provide(GR_FORM_FIELD_KEY, {
51
+ id: fieldId,
52
+ describedById: computed(() => {
53
+ const ids = [hasHint.value ? hintId : null, hasError.value ? errorId : null].filter(Boolean);
54
+ return ids.length ? ids.join(" ") : void 0;
55
+ }),
56
+ invalid: hasError,
57
+ required: isRequired
58
+ });
59
+ const fieldRootEl = ref(null);
60
+ let unregister;
61
+ onMounted(() => {
62
+ if (form && props.name) unregister = form.registerField(props.name, () => fieldRootEl.value);
63
+ });
64
+ onBeforeUnmount(() => unregister?.());
65
+ function onFocusOut() {
66
+ if (form && props.name) form.validateField(props.name, "blur");
67
+ }
68
+ return (_ctx, _cache) => {
69
+ return openBlock(), createElementBlock("div", {
70
+ ref_key: "fieldRootEl",
71
+ ref: fieldRootEl,
72
+ "data-gr-form-field": "",
73
+ class: "flex flex-col gap-2",
74
+ onFocusout: onFocusOut
75
+ }, [
76
+ props.label ? (openBlock(), createElementBlock("label", {
77
+ key: 0,
78
+ for: fieldId.value,
79
+ class: normalizeClass(["text-sm text-[var(--gr-muted-fg)]", props.labelClass])
80
+ }, [createTextVNode(toDisplayString(props.label) + " ", 1), isRequired.value ? (openBlock(), createElementBlock("span", _hoisted_2, "*")) : createCommentVNode("", true)], 10, _hoisted_1)) : createCommentVNode("", true),
81
+ hasHint.value ? (openBlock(), createElementBlock("p", {
82
+ key: 1,
83
+ id: unref(hintId),
84
+ "data-gr-form-field-hint": "",
85
+ class: "text-xs text-[var(--gr-muted-fg)]"
86
+ }, [renderSlot(_ctx.$slots, "hint", {}, () => [createTextVNode(toDisplayString(props.hint), 1)])], 8, _hoisted_3)) : createCommentVNode("", true),
87
+ renderSlot(_ctx.$slots, "default"),
88
+ hasError.value ? (openBlock(), createElementBlock("div", {
89
+ key: 2,
90
+ id: unref(errorId),
91
+ "data-gr-form-field-error": "",
92
+ role: "alert",
93
+ class: "text-sm text-[var(--gr-danger)]"
94
+ }, toDisplayString(resolvedError.value), 9, _hoisted_4)) : createCommentVNode("", true)
95
+ ], 544);
96
+ };
97
+ }
98
+ });
99
+ //#endregion
100
+ export { GrFormField_default as t };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GrFormField-CXCDBd99.js","names":[],"sources":["../../../../src/components/GrFormField/GrFormField.vue","../../../../src/components/GrFormField/GrFormField.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, onMounted, provide, ref, useId, useSlots } from 'vue'\n\nimport { useGrFormContext } from '../GrForm/context'\nimport { GR_FORM_FIELD_KEY } from './context'\n\ntype LabelClass = string | string[] | Record<string, boolean>\n\nconst props = withDefaults(\n defineProps<{\n label?: string\n /**\n * Имя поля в модели `GrForm` (в т.ч. dot-path `address.city`). Когда поле внутри\n * `GrForm` и задан `name`, ошибка и признак обязательности берутся из формы по\n * этому имени, а потеря фокуса триггерит валидацию поля.\n */\n name?: string\n /** Явный id контрола. Если не задан — генерируется автоматически. */\n forId?: string\n /** Явная ошибка. Перекрывает ошибку из `GrForm` (ручной режим без формы — тоже здесь). */\n error?: string\n /** Подсказка под лейблом/над контролом (можно также через слот `#hint`). */\n hint?: string\n /** Помечает поле обязательным (маркер `*` + `aria-required` у контрола). */\n required?: boolean\n labelClass?: LabelClass\n }>(),\n {\n label: undefined,\n name: undefined,\n forId: undefined,\n error: undefined,\n hint: undefined,\n required: false,\n labelClass: undefined,\n },\n)\n\nconst slots = useSlots()\n\n// Контекст `GrForm` (если поле внутри формы). Контролы про форму не знают —\n// оркестрация подключается здесь, на уровне поля.\nconst form = useGrFormContext()\nconst boundToForm = computed(() => Boolean(form && props.name && form.hasField(props.name)))\n\n// Автогенерация id: контрол внутри читает его через inject и связывается с\n// лейблом (`for`) без ручного дублирования `forId`.\nconst generatedId = useId()\nconst fieldId = computed(() => props.forId ?? generatedId)\n\nconst errorId = useId()\nconst hintId = useId()\n\n// Ошибка: явный проп `error` имеет приоритет, иначе — из формы по `name`.\nconst resolvedError = computed(() => {\n if (props.error) return props.error\n if (boundToForm.value && props.name) return form!.errors.value[props.name]\n return undefined\n})\n\n// Обязательность: проп `required` ИЛИ наличие `required`-правила в форме.\nconst isRequired = computed(() => {\n if (props.required) return true\n if (boundToForm.value && props.name) return form!.requiredFields.value.has(props.name)\n return false\n})\n\nconst hasHint = computed(() => Boolean(props.hint) || Boolean(slots.hint))\nconst hasError = computed(() => Boolean(resolvedError.value))\n\n// `aria-describedby` контрола: подсказка и/или ошибка.\nconst describedById = computed(() => {\n const ids = [hasHint.value ? hintId : null, hasError.value ? errorId : null].filter(Boolean)\n return ids.length ? ids.join(' ') : undefined\n})\n\nprovide(GR_FORM_FIELD_KEY, {\n id: fieldId,\n describedById,\n invalid: hasError,\n required: isRequired,\n})\n\n// ————— Интеграция с формой: регистрация (scroll-to-error) + валидация по blur.\nconst fieldRootEl = ref<HTMLElement | null>(null)\nlet unregister: (() => void) | undefined\n\nonMounted(() => {\n if (form && props.name) unregister = form.registerField(props.name, () => fieldRootEl.value)\n})\nonBeforeUnmount(() => unregister?.())\n\n// `focusout` всплывает от любого фокусируемого контрола внутри поля (native и\n// кастомного) — единый способ поймать blur без правок самих контролов.\nfunction onFocusOut(): void {\n if (form && props.name) void form.validateField(props.name, 'blur')\n}\n</script>\n\n<template>\n <div\n ref=\"fieldRootEl\"\n data-gr-form-field\n class=\"flex flex-col gap-2\"\n @focusout=\"onFocusOut\"\n >\n <label\n v-if=\"props.label\"\n :for=\"fieldId\"\n class=\"text-sm text-[var(--gr-muted-fg)]\"\n :class=\"props.labelClass\"\n >\n {{ props.label }}\n <span v-if=\"isRequired\" data-gr-form-field-required aria-hidden=\"true\" class=\"text-[var(--gr-danger)]\">*</span>\n </label>\n\n <p\n v-if=\"hasHint\"\n :id=\"hintId\"\n data-gr-form-field-hint\n class=\"text-xs text-[var(--gr-muted-fg)]\"\n >\n <slot name=\"hint\">\n {{ props.hint }}\n </slot>\n </p>\n\n <slot />\n\n <div\n v-if=\"hasError\"\n :id=\"errorId\"\n data-gr-form-field-error\n role=\"alert\"\n class=\"text-sm text-[var(--gr-danger)]\"\n >\n {{ resolvedError }}\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, onMounted, provide, ref, useId, useSlots } from 'vue'\n\nimport { useGrFormContext } from '../GrForm/context'\nimport { GR_FORM_FIELD_KEY } from './context'\n\ntype LabelClass = string | string[] | Record<string, boolean>\n\nconst props = withDefaults(\n defineProps<{\n label?: string\n /**\n * Имя поля в модели `GrForm` (в т.ч. dot-path `address.city`). Когда поле внутри\n * `GrForm` и задан `name`, ошибка и признак обязательности берутся из формы по\n * этому имени, а потеря фокуса триггерит валидацию поля.\n */\n name?: string\n /** Явный id контрола. Если не задан — генерируется автоматически. */\n forId?: string\n /** Явная ошибка. Перекрывает ошибку из `GrForm` (ручной режим без формы — тоже здесь). */\n error?: string\n /** Подсказка под лейблом/над контролом (можно также через слот `#hint`). */\n hint?: string\n /** Помечает поле обязательным (маркер `*` + `aria-required` у контрола). */\n required?: boolean\n labelClass?: LabelClass\n }>(),\n {\n label: undefined,\n name: undefined,\n forId: undefined,\n error: undefined,\n hint: undefined,\n required: false,\n labelClass: undefined,\n },\n)\n\nconst slots = useSlots()\n\n// Контекст `GrForm` (если поле внутри формы). Контролы про форму не знают —\n// оркестрация подключается здесь, на уровне поля.\nconst form = useGrFormContext()\nconst boundToForm = computed(() => Boolean(form && props.name && form.hasField(props.name)))\n\n// Автогенерация id: контрол внутри читает его через inject и связывается с\n// лейблом (`for`) без ручного дублирования `forId`.\nconst generatedId = useId()\nconst fieldId = computed(() => props.forId ?? generatedId)\n\nconst errorId = useId()\nconst hintId = useId()\n\n// Ошибка: явный проп `error` имеет приоритет, иначе — из формы по `name`.\nconst resolvedError = computed(() => {\n if (props.error) return props.error\n if (boundToForm.value && props.name) return form!.errors.value[props.name]\n return undefined\n})\n\n// Обязательность: проп `required` ИЛИ наличие `required`-правила в форме.\nconst isRequired = computed(() => {\n if (props.required) return true\n if (boundToForm.value && props.name) return form!.requiredFields.value.has(props.name)\n return false\n})\n\nconst hasHint = computed(() => Boolean(props.hint) || Boolean(slots.hint))\nconst hasError = computed(() => Boolean(resolvedError.value))\n\n// `aria-describedby` контрола: подсказка и/или ошибка.\nconst describedById = computed(() => {\n const ids = [hasHint.value ? hintId : null, hasError.value ? errorId : null].filter(Boolean)\n return ids.length ? ids.join(' ') : undefined\n})\n\nprovide(GR_FORM_FIELD_KEY, {\n id: fieldId,\n describedById,\n invalid: hasError,\n required: isRequired,\n})\n\n// ————— Интеграция с формой: регистрация (scroll-to-error) + валидация по blur.\nconst fieldRootEl = ref<HTMLElement | null>(null)\nlet unregister: (() => void) | undefined\n\nonMounted(() => {\n if (form && props.name) unregister = form.registerField(props.name, () => fieldRootEl.value)\n})\nonBeforeUnmount(() => unregister?.())\n\n// `focusout` всплывает от любого фокусируемого контрола внутри поля (native и\n// кастомного) — единый способ поймать blur без правок самих контролов.\nfunction onFocusOut(): void {\n if (form && props.name) void form.validateField(props.name, 'blur')\n}\n</script>\n\n<template>\n <div\n ref=\"fieldRootEl\"\n data-gr-form-field\n class=\"flex flex-col gap-2\"\n @focusout=\"onFocusOut\"\n >\n <label\n v-if=\"props.label\"\n :for=\"fieldId\"\n class=\"text-sm text-[var(--gr-muted-fg)]\"\n :class=\"props.labelClass\"\n >\n {{ props.label }}\n <span v-if=\"isRequired\" data-gr-form-field-required aria-hidden=\"true\" class=\"text-[var(--gr-danger)]\">*</span>\n </label>\n\n <p\n v-if=\"hasHint\"\n :id=\"hintId\"\n data-gr-form-field-hint\n class=\"text-xs text-[var(--gr-muted-fg)]\"\n >\n <slot name=\"hint\">\n {{ props.hint }}\n </slot>\n </p>\n\n <slot />\n\n <div\n v-if=\"hasError\"\n :id=\"errorId\"\n data-gr-form-field-error\n role=\"alert\"\n class=\"text-sm text-[var(--gr-danger)]\"\n >\n {{ resolvedError }}\n </div>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAQA,MAAM,QAAQ;EA8Bd,MAAM,QAAQ,SAAS;EAIvB,MAAM,OAAO,iBAAiB;EAC9B,MAAM,cAAc,eAAe,QAAQ,QAAQ,MAAM,QAAQ,KAAK,SAAS,MAAM,IAAI,CAAC,CAAC;EAI3F,MAAM,cAAc,MAAM;EAC1B,MAAM,UAAU,eAAe,MAAM,SAAS,WAAW;EAEzD,MAAM,UAAU,MAAM;EACtB,MAAM,SAAS,MAAM;EAGrB,MAAM,gBAAgB,eAAe;GACnC,IAAI,MAAM,OAAO,OAAO,MAAM;GAC9B,IAAI,YAAY,SAAS,MAAM,MAAM,OAAO,KAAM,OAAO,MAAM,MAAM;EAEvE,CAAC;EAGD,MAAM,aAAa,eAAe;GAChC,IAAI,MAAM,UAAU,OAAO;GAC3B,IAAI,YAAY,SAAS,MAAM,MAAM,OAAO,KAAM,eAAe,MAAM,IAAI,MAAM,IAAI;GACrF,OAAO;EACT,CAAC;EAED,MAAM,UAAU,eAAe,QAAQ,MAAM,IAAI,KAAK,QAAQ,MAAM,IAAI,CAAC;EACzE,MAAM,WAAW,eAAe,QAAQ,cAAc,KAAK,CAAC;EAQ5D,QAAQ,mBAAmB;GACzB,IAAI;GACJ,eAPoB,eAAe;IACnC,MAAM,MAAM,CAAC,QAAQ,QAAQ,SAAS,MAAM,SAAS,QAAQ,UAAU,IAAI,CAAC,CAAC,OAAO,OAAO;IAC3F,OAAO,IAAI,SAAS,IAAI,KAAK,GAAG,IAAI,KAAA;GACtC,CAIE;GACA,SAAS;GACT,UAAU;EACZ,CAAC;EAGD,MAAM,cAAc,IAAwB,IAAI;EAChD,IAAI;EAEJ,gBAAgB;GACd,IAAI,QAAQ,MAAM,MAAM,aAAa,KAAK,cAAc,MAAM,YAAY,YAAY,KAAK;EAC7F,CAAC;EACD,sBAAsB,aAAa,CAAC;EAIpC,SAAS,aAAmB;GAC1B,IAAI,QAAQ,MAAM,MAAM,KAAU,cAAc,MAAM,MAAM,MAAM;EACpE;;uBAIE,mBAsCM,OAAA;aArCA;IAAJ,KAAI;IACJ,sBAAA;IACA,OAAM;IACL,YAAU;;IAGH,MAAM,SAAA,UAAA,GADd,mBAQQ,SAAA;;KANL,KAAK,QAAA;KACN,OAAK,eAAA,CAAC,qCACE,MAAM,UAAU,CAAA;wCAErB,MAAM,KAAK,IAAG,KACjB,CAAA,GAAY,WAAA,SAAA,UAAA,GAAZ,mBAA+G,QAA/G,YAAuG,GAAC,KAAA,mBAAA,IAAA,IAAA,CAAA,GAAA,IAAA,UAAA,KAAA,mBAAA,IAAA,IAAA;IAIlG,QAAA,SAAA,UAAA,GADR,mBASI,KAAA;;KAPD,IAAI,MAAA,MAAA;KACL,2BAAA;KACA,OAAM;QAEN,WAEO,KAAA,QAAA,QAAA,CAAA,SAAA,CAAA,gBAAA,gBADF,MAAM,IAAI,GAAA,CAAA,CAAA,CAAA,CAAA,GAAA,GAAA,UAAA,KAAA,mBAAA,IAAA,IAAA;IAIjB,WAAQ,KAAA,QAAA,SAAA;IAGA,SAAA,SAAA,UAAA,GADR,mBAQM,OAAA;;KANH,IAAI,MAAA,OAAA;KACL,4BAAA;KACA,MAAK;KACL,OAAM;uBAEH,cAAA,KAAa,GAAA,GAAA,UAAA,KAAA,mBAAA,IAAA,IAAA"}
@@ -1,3 +1,4 @@
1
- import { t as GrFormField_default } from "./chunks/GrFormField-BujNQrw8.js";
1
+ import { n as useGrFormFieldContext, t as GR_FORM_FIELD_KEY } from "../../chunks/context-DdNIxa1w.js";
2
+ import { t as GrFormField_default } from "./chunks/GrFormField-CXCDBd99.js";
2
3
  import { t as grFormFieldConfig } from "../../chunks/config-PFg39mYo.js";
3
- export { GrFormField_default as GrFormField, GrFormField_default as default, grFormFieldConfig };
4
+ export { GR_FORM_FIELD_KEY, GrFormField_default as GrFormField, GrFormField_default as default, grFormFieldConfig, useGrFormFieldContext };
@@ -1,10 +1,10 @@
1
1
  import { t as x_default } from "../../../chunks/x-2KXnqxiD.js";
2
- import { t as useGranularityTranslations } from "../../../chunks/granularityI18n-DoV7Ca2m.js";
3
- import { t as _plugin_vue_export_helper_default } from "../../../chunks/_plugin-vue_export-helper-BOaGB7Aw.js";
4
- import { t as GrButton_default } from "../../GrButton/chunks/GrButton-BlffdeJr.js";
5
- import { t as GrIcon_default } from "../../GrIcon/chunks/GrIcon-D9AWQLk2.js";
2
+ import { n as useGranularityTranslations } from "../../../chunks/granularityI18n-SH0I--GW.js";
6
3
  import { l as runFileValidators, o as acceptValidator, u as FileValidationError } from "../../../chunks/fileValidation-C3WFaWU2.js";
7
4
  import { vDropzone } from "../../../directives/dropzone.js";
5
+ import { t as _plugin_vue_export_helper_default } from "../../../chunks/_plugin-vue_export-helper-BOaGB7Aw.js";
6
+ import { t as GrButton_default } from "../../GrButton/chunks/GrButton-DCi4CUpo.js";
7
+ import { t as GrIcon_default } from "../../GrIcon/chunks/GrIcon-D9AWQLk2.js";
8
8
  import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, markRaw, nextTick, normalizeClass, openBlock, ref, renderList, renderSlot, toDisplayString, unref, watch, withCtx, withDirectives, withModifiers } from "vue";
9
9
  import '../../../GrFormFile.css';//#region ~icons/lucide/upload
10
10
  var _hoisted_1$1 = {
@@ -41,7 +41,7 @@ var _hoisted_6 = { class: "ml-2" };
41
41
  var _hoisted_7 = ["title"];
42
42
  var _hoisted_8 = {
43
43
  key: 3,
44
- class: "text-sm text-[var(--muted-fg)]",
44
+ class: "text-sm text-[var(--gr-muted-fg)]",
45
45
  "data-gr-form-file-placeholder": ""
46
46
  };
47
47
  var _hoisted_9 = {
@@ -283,7 +283,7 @@ var GrFormFile_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__P
283
283
  }, 8, ["disabled"])) : createCommentVNode("", true),
284
284
  !__props.multiple && hasFiles.value ? (openBlock(), createElementBlock("span", {
285
285
  key: 2,
286
- class: "text-sm text-[var(--muted-fg)] truncate max-w-[240px]",
286
+ class: "text-sm text-[var(--gr-muted-fg)] truncate max-w-[240px]",
287
287
  "data-gr-form-file-single-name": "",
288
288
  title: files.value[0]?.name
289
289
  }, toDisplayString(files.value[0]?.name), 9, _hoisted_7)) : createCommentVNode("", true),
@@ -295,12 +295,12 @@ var GrFormFile_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__P
295
295
  class: "flex items-center gap-2",
296
296
  "data-gr-form-file-item": ""
297
297
  }, [createElementVNode("span", {
298
- class: "text-sm text-[var(--muted-fg)] truncate max-w-[240px]",
298
+ class: "text-sm text-[var(--gr-muted-fg)] truncate max-w-[240px]",
299
299
  title: file.name,
300
300
  "data-gr-form-file-item-name": ""
301
301
  }, toDisplayString(file.name), 9, _hoisted_10), createElementVNode("button", {
302
302
  type: "button",
303
- class: "text-xs text-[var(--muted-fg)] hover:text-[var(--fg)]",
303
+ class: "text-xs text-[var(--gr-muted-fg)] hover:text-[var(--gr-fg)]",
304
304
  "data-gr-form-file-item-remove": "",
305
305
  disabled: __props.disabled,
306
306
  onClick: withModifiers(($event) => removeAt(index), ["prevent"])
@@ -315,6 +315,6 @@ var GrFormFile_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__P
315
315
  ])], 2)), [[unref(vDropzone), dropzone.value]]);
316
316
  };
317
317
  }
318
- }), [["__scopeId", "data-v-ff219d2a"]]);
318
+ }), [["__scopeId", "data-v-e96c4b59"]]);
319
319
  //#endregion
320
320
  export { GrFormFile_default as t };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GrFormFile-CqacSbUl.js","names":[],"sources":["../../../../src/components/GrFormFile/GrFormFile.vue","../../../../src/components/GrFormFile/GrFormFile.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, nextTick, ref, watch } from 'vue'\n\nimport IconUpload from '~icons/lucide/upload'\nimport IconX from '~icons/lucide/x'\n\nimport GrButton from '../GrButton/GrButton.vue'\nimport GrIcon from '../GrIcon/GrIcon.vue'\nimport { vDropzone } from '../../directives'\nimport { acceptValidator, FileValidationError, runFileValidators } from '../../fileValidation'\nimport type { FileValidationIssue, FileValidator } from '../../fileValidation'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\n\ndefineOptions({\n name: 'GrFormFile',\n})\n\nexport type GrFormFileError = FileValidationIssue\n\n/**\n * Пропы `GrFormFile` — форма-поле для выбора файлов с встроенной валидацией,\n * drag&drop (через `v-dropzone`) и списком выбранных файлов.\n *\n * Все `*Text`/`placeholder` — i18n-friendly, принимают готовые строки локали.\n */\nexport interface GrFormFileProps {\n modelValue: File | File[] | null\n multiple?: boolean\n disabled?: boolean\n /** W3C `accept` для `<input type=\"file\">` + sugar к `acceptValidator(...)`. */\n accept?: string\n validators?: FileValidator[]\n uploadText?: string\n changeText?: string\n removeText?: string\n clearAllText?: string\n placeholder?: string\n /** Дополнительная (кастомная) валидация на стороне потребителя. */\n validate?: (files: File[]) => GrFormFileError[] | Promise<GrFormFileError[]>\n}\n\nconst props = withDefaults(\n defineProps<GrFormFileProps>(),\n {\n multiple: false,\n disabled: false,\n accept: undefined,\n uploadText: undefined,\n changeText: undefined,\n removeText: undefined,\n clearAllText: undefined,\n placeholder: undefined,\n validators: undefined,\n validate: undefined,\n },\n)\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: File | File[] | null): void\n (e: 'change', value: File | File[] | null): void\n (e: 'clear'): void\n (e: 'validation', errors: GrFormFileError[]): void\n (e: 'update:errors', errors: GrFormFileError[]): void\n}>()\n\nconst { t } = useGranularityTranslations()\nconst resolvedUploadText = computed(() => props.uploadText ?? t('gr.formFile.upload', 'Upload file'))\nconst resolvedChangeText = computed(() => props.changeText ?? t('gr.formFile.change', 'Change file'))\nconst resolvedRemoveText = computed(() => props.removeText ?? t('gr.formFile.remove', 'Remove'))\nconst resolvedClearAllText = computed(() => props.clearAllText ?? t('gr.formFile.clearAll', 'Clear all'))\nconst resolvedPlaceholder = computed(() => props.placeholder ?? t('gr.formFile.placeholder', 'No files selected'))\n\nconst inputRef = ref<HTMLInputElement | null>(null)\nconst localErrors = ref<GrFormFileError[]>([])\n\nconst files = computed<File[]>(() => {\n if (props.multiple) {\n return Array.isArray(props.modelValue) ? props.modelValue : []\n }\n\n return props.modelValue instanceof File ? [props.modelValue] : []\n})\n\nconst hasFiles = computed(() => files.value.length > 0)\n\nfunction clearInputValue() {\n if (!inputRef.value) return\n inputRef.value.value = ''\n}\n\nfunction setErrors(next: GrFormFileError[]) {\n localErrors.value = next\n emit('validation', next)\n emit('update:errors', next)\n}\n\nfunction clearErrors() {\n if (localErrors.value.length === 0) return\n setErrors([])\n}\n\nfunction openDialog() {\n if (props.disabled) return\n inputRef.value?.click()\n}\n\nfunction emitModel(nextFiles: File[]) {\n const value: File | File[] | null = props.multiple\n ? nextFiles\n : (nextFiles[0] ?? null)\n\n emit('update:modelValue', value)\n emit('change', value)\n}\n\nasync function applyFiles(nextFiles: File[]) {\n const isPromiseLike = (value: unknown): value is PromiseLike<any> => {\n return !!value && typeof (value as any).then === 'function'\n }\n\n const customValidator: FileValidator | undefined = props.validate\n ? async ({ files }) => (await props.validate?.(files)) ?? []\n : undefined\n\n const validators: FileValidator[] = [\n acceptValidator(props.accept),\n ...(props.validators ?? []),\n ...(customValidator ? [customValidator] : []),\n ]\n\n const res = runFileValidators(nextFiles, validators, {\n source: 'input',\n multiple: props.multiple,\n })\n\n const { files: picked, issues } = isPromiseLike(res) ? await res : res\n\n if (issues.length > 0) {\n setErrors(issues)\n clearInputValue()\n await nextTick()\n return\n }\n\n clearErrors()\n emitModel(picked)\n clearInputValue()\n await nextTick()\n}\n\nasync function onInputChange(event: Event) {\n if (props.disabled) return\n\n const target = event.target as HTMLInputElement | null\n const nextFiles = target?.files ? Array.prototype.slice.call(target.files) as File[] : []\n\n // Reset value so selecting the same file twice triggers change.\n if (target) target.value = ''\n await nextTick()\n\n await applyFiles(nextFiles)\n}\n\nfunction clearAll() {\n if (props.disabled) return\n clearErrors()\n clearInputValue()\n emit('clear')\n\n emit('update:modelValue', props.multiple ? [] : null)\n emit('change', props.multiple ? [] : null)\n}\n\nfunction removeAt(index: number) {\n if (props.disabled) return\n if (!props.multiple) {\n clearAll()\n return\n }\n\n const next = files.value.slice()\n next.splice(index, 1)\n\n emit('update:modelValue', next)\n emit('change', next)\n}\n\nfunction issueMessage(issue: GrFormFileError): string {\n if (issue.fileName) return `${issue.fileName}: ${issue.message}`\n return issue.message\n}\n\nconst dropzone = computed(() => {\n const customValidator: FileValidator | undefined = props.validate\n ? async ({ files }) => (await props.validate?.(files)) ?? []\n : undefined\n\n const validators: FileValidator[] = [\n acceptValidator(props.accept),\n ...(props.validators ?? []),\n ...(customValidator ? [customValidator] : []),\n ]\n\n return {\n enabled: !props.disabled,\n multiple: props.multiple,\n validators,\n onFiles: async (dropped: File[]) => {\n // `v-dropzone` уже выполнил валидаторы и нормализацию по `multiple`.\n clearErrors()\n emitModel(dropped)\n clearInputValue()\n await nextTick()\n },\n onError: (error: unknown) => {\n if (error instanceof FileValidationError) {\n setErrors(error.issues)\n }\n else {\n setErrors([\n {\n code: 'accept',\n message: t('gr.formFile.validateError', 'Failed to validate dropped files'),\n },\n ])\n }\n },\n }\n})\n\nwatch(\n () => props.modelValue,\n (value) => {\n if (!inputRef.value) return\n\n if (!value || (Array.isArray(value) && value.length === 0)) {\n // Позволяет выбрать тот же файл снова после внешнего сброса.\n inputRef.value.value = ''\n }\n },\n)\n</script>\n\n<template>\n <div\n v-dropzone=\"dropzone\"\n data-gr-form-file\n class=\"rounded-[var(--gr-radius-md)]\"\n :class=\"disabled ? 'opacity-60 cursor-not-allowed' : ''\"\n >\n <input\n ref=\"inputRef\"\n data-gr-form-file-input\n type=\"file\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n class=\"absolute opacity-0 w-px h-px pointer-events-none\"\n :multiple=\"multiple\"\n :accept=\"accept\"\n :disabled=\"disabled\"\n @change=\"onInputChange\"\n >\n\n <div class=\"flex flex-col gap-2\">\n <div class=\"flex flex-wrap items-center gap-3\">\n <GrButton\n variant=\"secondary\"\n size=\"sm\"\n data-gr-form-file-upload-btn\n :disabled=\"disabled\"\n @click.prevent=\"openDialog\"\n >\n <GrIcon size=\"sm\" aria-hidden=\"true\">\n <IconUpload />\n </GrIcon>\n <span class=\"ml-2\">{{ hasFiles ? resolvedChangeText : resolvedUploadText }}</span>\n </GrButton>\n\n <GrButton\n v-if=\"hasFiles && !multiple\"\n variant=\"secondary\"\n size=\"sm\"\n data-gr-form-file-clear-btn\n :disabled=\"disabled\"\n @click.prevent=\"clearAll\"\n >\n <GrIcon size=\"sm\" aria-hidden=\"true\">\n <IconX />\n </GrIcon>\n <span class=\"ml-2\">{{ resolvedRemoveText }}</span>\n </GrButton>\n\n <GrButton\n v-if=\"multiple && hasFiles\"\n variant=\"secondary\"\n size=\"sm\"\n data-gr-form-file-clear-all-btn\n :disabled=\"disabled\"\n @click.prevent=\"clearAll\"\n >\n <GrIcon size=\"sm\" aria-hidden=\"true\">\n <IconX />\n </GrIcon>\n <span class=\"ml-2\">{{ resolvedClearAllText }}</span>\n </GrButton>\n\n <span\n v-if=\"!multiple && hasFiles\"\n class=\"text-sm text-[var(--gr-muted-fg)] truncate max-w-[240px]\"\n data-gr-form-file-single-name\n :title=\"files[0]?.name\"\n >\n {{ files[0]?.name }}\n </span>\n\n <span\n v-if=\"!hasFiles\"\n class=\"text-sm text-[var(--gr-muted-fg)]\"\n data-gr-form-file-placeholder\n >\n {{ resolvedPlaceholder }}\n </span>\n </div>\n\n <div v-if=\"multiple && hasFiles\" class=\"flex flex-col gap-2\">\n <div\n v-for=\"(file, index) in files\"\n :key=\"`${file.name}-${file.size}-${index}`\"\n class=\"flex items-center gap-2\"\n data-gr-form-file-item\n >\n <span\n class=\"text-sm text-[var(--gr-muted-fg)] truncate max-w-[240px]\"\n :title=\"file.name\"\n data-gr-form-file-item-name\n >\n {{ file.name }}\n </span>\n\n <button\n type=\"button\"\n class=\"text-xs text-[var(--gr-muted-fg)] hover:text-[var(--gr-fg)]\"\n data-gr-form-file-item-remove\n :disabled=\"disabled\"\n @click.prevent=\"removeAt(index)\"\n >\n {{ removeText }}\n </button>\n </div>\n </div>\n\n <slot name=\"errors\" :errors=\"localErrors\">\n <div v-if=\"localErrors.length\" class=\"text-sm text-[var(--gr-danger)]\" data-gr-form-file-errors>\n <div v-for=\"(e, i) in localErrors\" :key=\"i\" data-gr-form-file-error>\n {{ issueMessage(e) }}\n </div>\n </div>\n </slot>\n </div>\n </div>\n</template>\n\n<style scoped>\n[data-gr-form-file].gr-dropzone--over {\n outline: 2px solid var(--gr-ring);\n outline-offset: 2px;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, nextTick, ref, watch } from 'vue'\n\nimport IconUpload from '~icons/lucide/upload'\nimport IconX from '~icons/lucide/x'\n\nimport GrButton from '../GrButton/GrButton.vue'\nimport GrIcon from '../GrIcon/GrIcon.vue'\nimport { vDropzone } from '../../directives'\nimport { acceptValidator, FileValidationError, runFileValidators } from '../../fileValidation'\nimport type { FileValidationIssue, FileValidator } from '../../fileValidation'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\n\ndefineOptions({\n name: 'GrFormFile',\n})\n\nexport type GrFormFileError = FileValidationIssue\n\n/**\n * Пропы `GrFormFile` — форма-поле для выбора файлов с встроенной валидацией,\n * drag&drop (через `v-dropzone`) и списком выбранных файлов.\n *\n * Все `*Text`/`placeholder` — i18n-friendly, принимают готовые строки локали.\n */\nexport interface GrFormFileProps {\n modelValue: File | File[] | null\n multiple?: boolean\n disabled?: boolean\n /** W3C `accept` для `<input type=\"file\">` + sugar к `acceptValidator(...)`. */\n accept?: string\n validators?: FileValidator[]\n uploadText?: string\n changeText?: string\n removeText?: string\n clearAllText?: string\n placeholder?: string\n /** Дополнительная (кастомная) валидация на стороне потребителя. */\n validate?: (files: File[]) => GrFormFileError[] | Promise<GrFormFileError[]>\n}\n\nconst props = withDefaults(\n defineProps<GrFormFileProps>(),\n {\n multiple: false,\n disabled: false,\n accept: undefined,\n uploadText: undefined,\n changeText: undefined,\n removeText: undefined,\n clearAllText: undefined,\n placeholder: undefined,\n validators: undefined,\n validate: undefined,\n },\n)\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: File | File[] | null): void\n (e: 'change', value: File | File[] | null): void\n (e: 'clear'): void\n (e: 'validation', errors: GrFormFileError[]): void\n (e: 'update:errors', errors: GrFormFileError[]): void\n}>()\n\nconst { t } = useGranularityTranslations()\nconst resolvedUploadText = computed(() => props.uploadText ?? t('gr.formFile.upload', 'Upload file'))\nconst resolvedChangeText = computed(() => props.changeText ?? t('gr.formFile.change', 'Change file'))\nconst resolvedRemoveText = computed(() => props.removeText ?? t('gr.formFile.remove', 'Remove'))\nconst resolvedClearAllText = computed(() => props.clearAllText ?? t('gr.formFile.clearAll', 'Clear all'))\nconst resolvedPlaceholder = computed(() => props.placeholder ?? t('gr.formFile.placeholder', 'No files selected'))\n\nconst inputRef = ref<HTMLInputElement | null>(null)\nconst localErrors = ref<GrFormFileError[]>([])\n\nconst files = computed<File[]>(() => {\n if (props.multiple) {\n return Array.isArray(props.modelValue) ? props.modelValue : []\n }\n\n return props.modelValue instanceof File ? [props.modelValue] : []\n})\n\nconst hasFiles = computed(() => files.value.length > 0)\n\nfunction clearInputValue() {\n if (!inputRef.value) return\n inputRef.value.value = ''\n}\n\nfunction setErrors(next: GrFormFileError[]) {\n localErrors.value = next\n emit('validation', next)\n emit('update:errors', next)\n}\n\nfunction clearErrors() {\n if (localErrors.value.length === 0) return\n setErrors([])\n}\n\nfunction openDialog() {\n if (props.disabled) return\n inputRef.value?.click()\n}\n\nfunction emitModel(nextFiles: File[]) {\n const value: File | File[] | null = props.multiple\n ? nextFiles\n : (nextFiles[0] ?? null)\n\n emit('update:modelValue', value)\n emit('change', value)\n}\n\nasync function applyFiles(nextFiles: File[]) {\n const isPromiseLike = (value: unknown): value is PromiseLike<any> => {\n return !!value && typeof (value as any).then === 'function'\n }\n\n const customValidator: FileValidator | undefined = props.validate\n ? async ({ files }) => (await props.validate?.(files)) ?? []\n : undefined\n\n const validators: FileValidator[] = [\n acceptValidator(props.accept),\n ...(props.validators ?? []),\n ...(customValidator ? [customValidator] : []),\n ]\n\n const res = runFileValidators(nextFiles, validators, {\n source: 'input',\n multiple: props.multiple,\n })\n\n const { files: picked, issues } = isPromiseLike(res) ? await res : res\n\n if (issues.length > 0) {\n setErrors(issues)\n clearInputValue()\n await nextTick()\n return\n }\n\n clearErrors()\n emitModel(picked)\n clearInputValue()\n await nextTick()\n}\n\nasync function onInputChange(event: Event) {\n if (props.disabled) return\n\n const target = event.target as HTMLInputElement | null\n const nextFiles = target?.files ? Array.prototype.slice.call(target.files) as File[] : []\n\n // Reset value so selecting the same file twice triggers change.\n if (target) target.value = ''\n await nextTick()\n\n await applyFiles(nextFiles)\n}\n\nfunction clearAll() {\n if (props.disabled) return\n clearErrors()\n clearInputValue()\n emit('clear')\n\n emit('update:modelValue', props.multiple ? [] : null)\n emit('change', props.multiple ? [] : null)\n}\n\nfunction removeAt(index: number) {\n if (props.disabled) return\n if (!props.multiple) {\n clearAll()\n return\n }\n\n const next = files.value.slice()\n next.splice(index, 1)\n\n emit('update:modelValue', next)\n emit('change', next)\n}\n\nfunction issueMessage(issue: GrFormFileError): string {\n if (issue.fileName) return `${issue.fileName}: ${issue.message}`\n return issue.message\n}\n\nconst dropzone = computed(() => {\n const customValidator: FileValidator | undefined = props.validate\n ? async ({ files }) => (await props.validate?.(files)) ?? []\n : undefined\n\n const validators: FileValidator[] = [\n acceptValidator(props.accept),\n ...(props.validators ?? []),\n ...(customValidator ? [customValidator] : []),\n ]\n\n return {\n enabled: !props.disabled,\n multiple: props.multiple,\n validators,\n onFiles: async (dropped: File[]) => {\n // `v-dropzone` уже выполнил валидаторы и нормализацию по `multiple`.\n clearErrors()\n emitModel(dropped)\n clearInputValue()\n await nextTick()\n },\n onError: (error: unknown) => {\n if (error instanceof FileValidationError) {\n setErrors(error.issues)\n }\n else {\n setErrors([\n {\n code: 'accept',\n message: t('gr.formFile.validateError', 'Failed to validate dropped files'),\n },\n ])\n }\n },\n }\n})\n\nwatch(\n () => props.modelValue,\n (value) => {\n if (!inputRef.value) return\n\n if (!value || (Array.isArray(value) && value.length === 0)) {\n // Позволяет выбрать тот же файл снова после внешнего сброса.\n inputRef.value.value = ''\n }\n },\n)\n</script>\n\n<template>\n <div\n v-dropzone=\"dropzone\"\n data-gr-form-file\n class=\"rounded-[var(--gr-radius-md)]\"\n :class=\"disabled ? 'opacity-60 cursor-not-allowed' : ''\"\n >\n <input\n ref=\"inputRef\"\n data-gr-form-file-input\n type=\"file\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n class=\"absolute opacity-0 w-px h-px pointer-events-none\"\n :multiple=\"multiple\"\n :accept=\"accept\"\n :disabled=\"disabled\"\n @change=\"onInputChange\"\n >\n\n <div class=\"flex flex-col gap-2\">\n <div class=\"flex flex-wrap items-center gap-3\">\n <GrButton\n variant=\"secondary\"\n size=\"sm\"\n data-gr-form-file-upload-btn\n :disabled=\"disabled\"\n @click.prevent=\"openDialog\"\n >\n <GrIcon size=\"sm\" aria-hidden=\"true\">\n <IconUpload />\n </GrIcon>\n <span class=\"ml-2\">{{ hasFiles ? resolvedChangeText : resolvedUploadText }}</span>\n </GrButton>\n\n <GrButton\n v-if=\"hasFiles && !multiple\"\n variant=\"secondary\"\n size=\"sm\"\n data-gr-form-file-clear-btn\n :disabled=\"disabled\"\n @click.prevent=\"clearAll\"\n >\n <GrIcon size=\"sm\" aria-hidden=\"true\">\n <IconX />\n </GrIcon>\n <span class=\"ml-2\">{{ resolvedRemoveText }}</span>\n </GrButton>\n\n <GrButton\n v-if=\"multiple && hasFiles\"\n variant=\"secondary\"\n size=\"sm\"\n data-gr-form-file-clear-all-btn\n :disabled=\"disabled\"\n @click.prevent=\"clearAll\"\n >\n <GrIcon size=\"sm\" aria-hidden=\"true\">\n <IconX />\n </GrIcon>\n <span class=\"ml-2\">{{ resolvedClearAllText }}</span>\n </GrButton>\n\n <span\n v-if=\"!multiple && hasFiles\"\n class=\"text-sm text-[var(--gr-muted-fg)] truncate max-w-[240px]\"\n data-gr-form-file-single-name\n :title=\"files[0]?.name\"\n >\n {{ files[0]?.name }}\n </span>\n\n <span\n v-if=\"!hasFiles\"\n class=\"text-sm text-[var(--gr-muted-fg)]\"\n data-gr-form-file-placeholder\n >\n {{ resolvedPlaceholder }}\n </span>\n </div>\n\n <div v-if=\"multiple && hasFiles\" class=\"flex flex-col gap-2\">\n <div\n v-for=\"(file, index) in files\"\n :key=\"`${file.name}-${file.size}-${index}`\"\n class=\"flex items-center gap-2\"\n data-gr-form-file-item\n >\n <span\n class=\"text-sm text-[var(--gr-muted-fg)] truncate max-w-[240px]\"\n :title=\"file.name\"\n data-gr-form-file-item-name\n >\n {{ file.name }}\n </span>\n\n <button\n type=\"button\"\n class=\"text-xs text-[var(--gr-muted-fg)] hover:text-[var(--gr-fg)]\"\n data-gr-form-file-item-remove\n :disabled=\"disabled\"\n @click.prevent=\"removeAt(index)\"\n >\n {{ removeText }}\n </button>\n </div>\n </div>\n\n <slot name=\"errors\" :errors=\"localErrors\">\n <div v-if=\"localErrors.length\" class=\"text-sm text-[var(--gr-danger)]\" data-gr-form-file-errors>\n <div v-for=\"(e, i) in localErrors\" :key=\"i\" data-gr-form-file-error>\n {{ issueMessage(e) }}\n </div>\n </div>\n </slot>\n </div>\n </div>\n</template>\n\n<style scoped>\n[data-gr-form-file].gr-dropzone--over {\n outline: 2px solid var(--gr-ring);\n outline-offset: 2px;\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyCA,MAAM,QAAQ;EAgBd,MAAM,OAAO;EAQb,MAAM,EAAE,MAAM,2BAA2B;EACzC,MAAM,qBAAqB,eAAe,MAAM,cAAc,EAAE,sBAAsB,aAAa,CAAC;EACpG,MAAM,qBAAqB,eAAe,MAAM,cAAc,EAAE,sBAAsB,aAAa,CAAC;EACpG,MAAM,qBAAqB,eAAe,MAAM,cAAc,EAAE,sBAAsB,QAAQ,CAAC;EAC/F,MAAM,uBAAuB,eAAe,MAAM,gBAAgB,EAAE,wBAAwB,WAAW,CAAC;EACxG,MAAM,sBAAsB,eAAe,MAAM,eAAe,EAAE,2BAA2B,mBAAmB,CAAC;EAEjH,MAAM,WAAW,IAA6B,IAAI;EAClD,MAAM,cAAc,IAAuB,CAAC,CAAC;EAE7C,MAAM,QAAQ,eAAuB;GACnC,IAAI,MAAM,UACR,OAAO,MAAM,QAAQ,MAAM,UAAU,IAAI,MAAM,aAAa,CAAC;GAG/D,OAAO,MAAM,sBAAsB,OAAO,CAAC,MAAM,UAAU,IAAI,CAAC;EAClE,CAAC;EAED,MAAM,WAAW,eAAe,MAAM,MAAM,SAAS,CAAC;EAEtD,SAAS,kBAAkB;GACzB,IAAI,CAAC,SAAS,OAAO;GACrB,SAAS,MAAM,QAAQ;EACzB;EAEA,SAAS,UAAU,MAAyB;GAC1C,YAAY,QAAQ;GACpB,KAAK,cAAc,IAAI;GACvB,KAAK,iBAAiB,IAAI;EAC5B;EAEA,SAAS,cAAc;GACrB,IAAI,YAAY,MAAM,WAAW,GAAG;GACpC,UAAU,CAAC,CAAC;EACd;EAEA,SAAS,aAAa;GACpB,IAAI,MAAM,UAAU;GACpB,SAAS,OAAO,MAAM;EACxB;EAEA,SAAS,UAAU,WAAmB;GACpC,MAAM,QAA8B,MAAM,WACtC,YACC,UAAU,MAAM;GAErB,KAAK,qBAAqB,KAAK;GAC/B,KAAK,UAAU,KAAK;EACtB;EAEA,eAAe,WAAW,WAAmB;GAC3C,MAAM,iBAAiB,UAA8C;IACnE,OAAO,CAAC,CAAC,SAAS,OAAQ,MAAc,SAAS;GACnD;GAEA,MAAM,kBAA6C,MAAM,WACrD,OAAO,EAAE,YAAa,MAAM,MAAM,WAAW,KAAK,KAAM,CAAC,IACzD,KAAA;GAQJ,MAAM,MAAM,kBAAkB,WAAW;IALvC,gBAAgB,MAAM,MAAM;IAC5B,GAAI,MAAM,cAAc,CAAC;IACzB,GAAI,kBAAkB,CAAC,eAAe,IAAI,CAAC;GAGJ,GAAY;IACnD,QAAQ;IACR,UAAU,MAAM;GAClB,CAAC;GAED,MAAM,EAAE,OAAO,QAAQ,WAAW,cAAc,GAAG,IAAI,MAAM,MAAM;GAEnE,IAAI,OAAO,SAAS,GAAG;IACrB,UAAU,MAAM;IAChB,gBAAgB;IAChB,MAAM,SAAS;IACf;GACF;GAEA,YAAY;GACZ,UAAU,MAAM;GAChB,gBAAgB;GAChB,MAAM,SAAS;EACjB;EAEA,eAAe,cAAc,OAAc;GACzC,IAAI,MAAM,UAAU;GAEpB,MAAM,SAAS,MAAM;GACrB,MAAM,YAAY,QAAQ,QAAQ,MAAM,UAAU,MAAM,KAAK,OAAO,KAAK,IAAc,CAAC;GAGxF,IAAI,QAAQ,OAAO,QAAQ;GAC3B,MAAM,SAAS;GAEf,MAAM,WAAW,SAAS;EAC5B;EAEA,SAAS,WAAW;GAClB,IAAI,MAAM,UAAU;GACpB,YAAY;GACZ,gBAAgB;GAChB,KAAK,OAAO;GAEZ,KAAK,qBAAqB,MAAM,WAAW,CAAC,IAAI,IAAI;GACpD,KAAK,UAAU,MAAM,WAAW,CAAC,IAAI,IAAI;EAC3C;EAEA,SAAS,SAAS,OAAe;GAC/B,IAAI,MAAM,UAAU;GACpB,IAAI,CAAC,MAAM,UAAU;IACnB,SAAS;IACT;GACF;GAEA,MAAM,OAAO,MAAM,MAAM,MAAM;GAC/B,KAAK,OAAO,OAAO,CAAC;GAEpB,KAAK,qBAAqB,IAAI;GAC9B,KAAK,UAAU,IAAI;EACrB;EAEA,SAAS,aAAa,OAAgC;GACpD,IAAI,MAAM,UAAU,OAAO,GAAG,MAAM,SAAS,IAAI,MAAM;GACvD,OAAO,MAAM;EACf;EAEA,MAAM,WAAW,eAAe;GAC9B,MAAM,kBAA6C,MAAM,WACrD,OAAO,EAAE,YAAa,MAAM,MAAM,WAAW,KAAK,KAAM,CAAC,IACzD,KAAA;GAEJ,MAAM,aAA8B;IAClC,gBAAgB,MAAM,MAAM;IAC5B,GAAI,MAAM,cAAc,CAAC;IACzB,GAAI,kBAAkB,CAAC,eAAe,IAAI,CAAC;GAC7C;GAEA,OAAO;IACL,SAAS,CAAC,MAAM;IAChB,UAAU,MAAM;IAChB;IACA,SAAS,OAAO,YAAoB;KAElC,YAAY;KACZ,UAAU,OAAO;KACjB,gBAAgB;KAChB,MAAM,SAAS;IACjB;IACA,UAAU,UAAmB;KAC3B,IAAI,iBAAiB,qBACnB,UAAU,MAAM,MAAM;UAGtB,UAAU,CACR;MACE,MAAM;MACN,SAAS,EAAE,6BAA6B,kCAAkC;KAC5E,CACF,CAAC;IAEL;GACF;EACF,CAAC;EAED,YACQ,MAAM,aACX,UAAU;GACT,IAAI,CAAC,SAAS,OAAO;GAErB,IAAI,CAAC,SAAU,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW,GAEtD,SAAS,MAAM,QAAQ;EAE3B,CACF;;uCAIE,mBAmHM,OAAA;IAjHJ,qBAAA;IACA,OAAK,eAAA,CAAC,iCACE,QAAA,WAAQ,kCAAA,EAAA,CAAA;OAEhB,mBAWC,SAAA;aAVK;IAAJ,KAAI;IACJ,2BAAA;IACA,MAAK;IACL,UAAS;IACT,eAAY;IACZ,OAAM;IACL,UAAU,QAAA;IACV,QAAQ,QAAA;IACR,UAAU,QAAA;IACV,UAAQ;6BAGX,mBA+FM,OA/FN,YA+FM;IA9FJ,mBA0DM,OA1DN,YA0DM;KAzDJ,YAWW,kBAAA;MAVT,SAAQ;MACR,MAAK;MACL,gCAAA;MACC,UAAU,QAAA;MACV,SAAK,cAAU,YAAU,CAAA,SAAA,CAAA;;6BAIjB,CAFT,YAES,gBAAA;OAFD,MAAK;OAAK,eAAY;;8BACd,CAAd,YAAc,MAAA,cAAA,CAAA,CAAA,CAAA;;UAEhB,mBAAkF,QAAlF,YAAkF,gBAA5D,SAAA,QAAW,mBAAA,QAAqB,mBAAA,KAAkB,GAAA,CAAA,CAAA,CAAA;;;KAIlE,SAAA,SAAQ,CAAK,QAAA,YAAA,UAAA,GADrB,YAYW,kBAAA;;MAVT,SAAQ;MACR,MAAK;MACL,+BAAA;MACC,UAAU,QAAA;MACV,SAAK,cAAU,UAAQ,CAAA,SAAA,CAAA;;6BAIf,CAFT,YAES,gBAAA;OAFD,MAAK;OAAK,eAAY;;8BACnB,CAAT,YAAS,MAAA,SAAA,CAAA,CAAA,CAAA;;UAEX,mBAAkD,QAAlD,YAAkD,gBAA5B,mBAAA,KAAkB,GAAA,CAAA,CAAA,CAAA;;;KAIlC,QAAA,YAAY,SAAA,SAAA,UAAA,GADpB,YAYW,kBAAA;;MAVT,SAAQ;MACR,MAAK;MACL,mCAAA;MACC,UAAU,QAAA;MACV,SAAK,cAAU,UAAQ,CAAA,SAAA,CAAA;;6BAIf,CAFT,YAES,gBAAA;OAFD,MAAK;OAAK,eAAY;;8BACnB,CAAT,YAAS,MAAA,SAAA,CAAA,CAAA,CAAA;;UAEX,mBAAoD,QAApD,YAAoD,gBAA9B,qBAAA,KAAoB,GAAA,CAAA,CAAA,CAAA;;;MAInC,QAAA,YAAY,SAAA,SAAA,UAAA,GADrB,mBAOO,QAAA;;MALL,OAAM;MACN,iCAAA;MACC,OAAO,MAAA,MAAK,EAAA,EAAK;wBAEf,MAAA,MAAK,EAAA,EAAK,IAAI,GAAA,GAAA,UAAA,KAAA,mBAAA,IAAA,IAAA;MAIV,SAAA,SAAA,UAAA,GADT,mBAMO,QANP,YAMO,gBADF,oBAAA,KAAmB,GAAA,CAAA,KAAA,mBAAA,IAAA,IAAA;;IAIf,QAAA,YAAY,SAAA,SAAA,UAAA,GAAvB,mBAyBM,OAzBN,YAyBM,EAAA,UAAA,IAAA,GAxBJ,mBAuBM,UAAA,MAAA,WAtBoB,MAAA,QAAhB,MAAM,UAAK;yBADrB,mBAuBM,OAAA;MArBH,KAAG,GAAK,KAAK,KAAI,GAAI,KAAK,KAAI,GAAI;MACnC,OAAM;MACN,0BAAA;SAEA,mBAMO,QAAA;MALL,OAAM;MACL,OAAO,KAAK;MACb,+BAAA;wBAEG,KAAK,IAAI,GAAA,GAAA,WAAA,GAGd,mBAQS,UAAA;MAPP,MAAK;MACL,OAAM;MACN,iCAAA;MACC,UAAU,QAAA;MACV,SAAK,eAAA,WAAU,SAAS,KAAK,GAAA,CAAA,SAAA,CAAA;wBAE3B,QAAA,UAAU,GAAA,GAAA,WAAA,CAAA,CAAA;;IAKnB,WAMO,KAAA,QAAA,UAAA,EANc,QAAQ,YAAA,MAAW,SAMjC,CALM,YAAA,MAAY,UAAA,UAAA,GAAvB,mBAIM,OAJN,aAIM,EAAA,UAAA,IAAA,GAHJ,mBAEM,UAAA,MAAA,WAFgB,YAAA,QAAT,GAAG,MAAC;yBAAjB,mBAEM,OAAA;MAF8B,KAAK;MAAG,2BAAA;wBACvC,aAAa,CAAC,CAAA,GAAA,CAAA;;iCA7Gb,SAAA,KAAQ,CAAA,CAAA"}
@@ -1,3 +1,3 @@
1
- import { t as GrFormFile_default } from "./chunks/GrFormFile-CXcqqdvV.js";
1
+ import { t as GrFormFile_default } from "./chunks/GrFormFile-CqacSbUl.js";
2
2
  import { t as grFormFileConfig } from "../../chunks/config-D7GZO-Dx.js";
3
3
  export { GrFormFile_default as GrFormFile, GrFormFile_default as default, grFormFileConfig };
@@ -26,7 +26,7 @@ var GrFormSection_default = /* @__PURE__ */ defineComponent({
26
26
  }, toDisplayString(__props.title), 9, _hoisted_2), __props.description ? (openBlock(), createElementBlock("div", {
27
27
  key: 0,
28
28
  id: unref(descriptionId),
29
- class: "mt-1 text-[13px] text-[var(--muted-fg)]"
29
+ class: "mt-1 text-[13px] text-[var(--gr-muted-fg)]"
30
30
  }, toDisplayString(__props.description), 9, _hoisted_3)) : createCommentVNode("", true)]), renderSlot(_ctx.$slots, "default")], 8, _hoisted_1);
31
31
  };
32
32
  }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GrFormSection-C3w9DQJf.js","names":[],"sources":["../../../../src/components/GrFormSection/GrFormSection.vue","../../../../src/components/GrFormSection/GrFormSection.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { useId } from 'vue'\n\n/**\n * GrFormSection — секция формы с заголовком, опциональным описанием и контентом.\n *\n * - `section` связан с заголовком через `aria-labelledby` и c описанием\n * (если есть) через `aria-describedby` — для a11y.\n */\nexport interface GrFormSectionProps {\n title: string\n description?: string\n}\n\nwithDefaults(defineProps<GrFormSectionProps>(), {\n description: undefined,\n})\n\nconst titleId = useId()\nconst descriptionId = useId()\n</script>\n\n<template>\n <section\n data-gr-form-section\n class=\"grid gap-4\"\n :aria-labelledby=\"titleId\"\n :aria-describedby=\"description ? descriptionId : undefined\"\n >\n <div>\n <div :id=\"titleId\" class=\"text-[14px] font-700\">\n {{ title }}\n </div>\n <div\n v-if=\"description\"\n :id=\"descriptionId\"\n class=\"mt-1 text-[13px] text-[var(--gr-muted-fg)]\"\n >\n {{ description }}\n </div>\n </div>\n <slot />\n </section>\n</template>\n","<script setup lang=\"ts\">\nimport { useId } from 'vue'\n\n/**\n * GrFormSection — секция формы с заголовком, опциональным описанием и контентом.\n *\n * - `section` связан с заголовком через `aria-labelledby` и c описанием\n * (если есть) через `aria-describedby` — для a11y.\n */\nexport interface GrFormSectionProps {\n title: string\n description?: string\n}\n\nwithDefaults(defineProps<GrFormSectionProps>(), {\n description: undefined,\n})\n\nconst titleId = useId()\nconst descriptionId = useId()\n</script>\n\n<template>\n <section\n data-gr-form-section\n class=\"grid gap-4\"\n :aria-labelledby=\"titleId\"\n :aria-describedby=\"description ? descriptionId : undefined\"\n >\n <div>\n <div :id=\"titleId\" class=\"text-[14px] font-700\">\n {{ title }}\n </div>\n <div\n v-if=\"description\"\n :id=\"descriptionId\"\n class=\"mt-1 text-[13px] text-[var(--gr-muted-fg)]\"\n >\n {{ description }}\n </div>\n </div>\n <slot />\n </section>\n</template>\n"],"mappings":";;;;;;;;;;;;;;EAkBA,MAAM,UAAU,MAAM;EACtB,MAAM,gBAAgB,MAAM;;uBAI1B,mBAmBU,WAAA;IAlBR,wBAAA;IACA,OAAM;IACL,mBAAiB,MAAA,OAAA;IACjB,oBAAkB,QAAA,cAAc,MAAA,aAAA,IAAgB,KAAA;OAEjD,mBAWM,OAAA,MAAA,CAVJ,mBAEM,OAAA;IAFA,IAAI,MAAA,OAAA;IAAS,OAAM;sBACpB,QAAA,KAAK,GAAA,GAAA,UAAA,GAGF,QAAA,eAAA,UAAA,GADR,mBAMM,OAAA;;IAJH,IAAI,MAAA,aAAA;IACL,OAAM;sBAEH,QAAA,WAAW,GAAA,GAAA,UAAA,KAAA,mBAAA,IAAA,IAAA,CAAA,CAAA,GAGlB,WAAQ,KAAA,QAAA,SAAA,CAAA,GAAA,GAAA,UAAA"}
@@ -1,3 +1,3 @@
1
- import { t as GrFormSection_default } from "./chunks/GrFormSection-Ce21jcgo.js";
1
+ import { t as GrFormSection_default } from "./chunks/GrFormSection-C3w9DQJf.js";
2
2
  import { t as grFormSectionConfig } from "../../chunks/config-B0qIpo8m.js";
3
3
  export { GrFormSection_default as GrFormSection, GrFormSection_default as default, grFormSectionConfig };