@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
@@ -1,6 +1,7 @@
1
- import { t as useGranularityTranslations } from "../../../chunks/granularityI18n-DoV7Ca2m.js";
1
+ import { o as useGrComponentSize } from "../../../chunks/context-DfWYCBB-.js";
2
+ import { n as useGranularityTranslations } from "../../../chunks/granularityI18n-SH0I--GW.js";
2
3
  import { n as useAddonMeasurement, t as addLen } from "../../../chunks/useAddonMeasurement-DM0akF4C.js";
3
- import { i as grNumberInputShellClass, r as grNumberInputInputClass } from "../../../chunks/config-C7NpDrfO.js";
4
+ import { i as grNumberInputShellClass, r as grNumberInputInputClass } from "../../../chunks/config-gZWR75Bh2.js";
4
5
  import { computed, createCommentVNode, createElementBlock, createElementVNode, defineComponent, mergeProps, normalizeClass, normalizeStyle, openBlock, ref, renderSlot, useSlots, withModifiers } from "vue";
5
6
  //#region src/components/GrNumberInput/GrNumberInput.vue?vue&type=script&setup=true&lang.ts
6
7
  var _hoisted_1 = [
@@ -11,6 +12,9 @@ var _hoisted_1 = [
11
12
  "placeholder",
12
13
  "disabled",
13
14
  "value",
15
+ "aria-valuenow",
16
+ "aria-valuemin",
17
+ "aria-valuemax",
14
18
  "aria-invalid"
15
19
  ];
16
20
  var _hoisted_2 = { class: "flex flex-col justify-center gap-1" };
@@ -39,13 +43,18 @@ var GrNumberInput_default = /* @__PURE__ */ defineComponent({
39
43
  state: { default: "default" },
40
44
  name: { default: void 0 },
41
45
  id: { default: void 0 },
42
- size: { default: "md" },
46
+ size: { default: void 0 },
43
47
  textAlign: { default: "left" },
44
48
  decimalSeparator: { default: "." },
45
49
  step: { default: 1 },
46
50
  min: { default: void 0 },
47
51
  max: { default: void 0 },
48
52
  precision: { default: void 0 },
53
+ locale: { default: void 0 },
54
+ useGrouping: {
55
+ type: Boolean,
56
+ default: false
57
+ },
49
58
  controls: {
50
59
  type: Boolean,
51
60
  default: false
@@ -84,6 +93,7 @@ var GrNumberInput_default = /* @__PURE__ */ defineComponent({
84
93
  return `${n}px`;
85
94
  }
86
95
  const props = __props;
96
+ const resolvedSize = useGrComponentSize(() => props.size, { component: "GrNumberInput" });
87
97
  const emit = __emit;
88
98
  const inputEl = ref(null);
89
99
  function focus() {
@@ -98,9 +108,9 @@ var GrNumberInput_default = /* @__PURE__ */ defineComponent({
98
108
  const hasSuffix = computed(() => Boolean(slots.suffix));
99
109
  const hasHorizontalControls = computed(() => props.controls && props.controlsDirection === "horizontal");
100
110
  const hasVerticalControls = computed(() => props.controls && props.controlsDirection === "vertical");
101
- const addonPx = computed(() => ADDON_PX_BY_SIZE[props.size]);
111
+ const addonPx = computed(() => ADDON_PX_BY_SIZE[resolvedSize.value]);
102
112
  const addonLen = computed(() => px(addonPx.value));
103
- const basePaddingXLen = computed(() => BASE_PADDING_X_LEN_BY_SIZE[props.size]);
113
+ const basePaddingXLen = computed(() => BASE_PADDING_X_LEN_BY_SIZE[resolvedSize.value]);
104
114
  const defaultAddonMinWidth = computed(() => addonLen.value);
105
115
  const prefixMinWidth = computed(() => props.prefixMinWidth ?? defaultAddonMinWidth.value);
106
116
  const suffixMinWidth = computed(() => props.suffixMinWidth ?? defaultAddonMinWidth.value);
@@ -167,7 +177,7 @@ var GrNumberInput_default = /* @__PURE__ */ defineComponent({
167
177
  });
168
178
  const inputClassName = computed(() => {
169
179
  return grNumberInputInputClass({
170
- size: props.size,
180
+ size: resolvedSize.value,
171
181
  textAlign: props.textAlign
172
182
  });
173
183
  });
@@ -180,6 +190,10 @@ var GrNumberInput_default = /* @__PURE__ */ defineComponent({
180
190
  let hasSepLocal = false;
181
191
  for (let i = 0; i < raw.length; i++) {
182
192
  const ch = raw[i];
193
+ if (ch === "-" && out.length === 0) {
194
+ out += "-";
195
+ continue;
196
+ }
183
197
  if (isDigit(ch)) {
184
198
  out += ch;
185
199
  continue;
@@ -212,33 +226,96 @@ var GrNumberInput_default = /* @__PURE__ */ defineComponent({
212
226
  function format(n) {
213
227
  const sep = props.decimalSeparator || ".";
214
228
  const p = props.precision;
215
- let s = p === void 0 ? String(n) : n.toFixed(Math.max(0, p));
229
+ let s = p === void 0 ? n.toLocaleString("en-US", {
230
+ useGrouping: false,
231
+ maximumFractionDigits: 20
232
+ }) : n.toFixed(Math.max(0, p));
216
233
  if (sep !== ".") s = s.replace(".", sep);
217
234
  return s;
218
235
  }
219
236
  function onInput(e) {
220
237
  const el = e.target;
221
- const next = sanitize(el.value);
222
- if (el.value !== next) el.value = next;
238
+ const raw = el.value;
239
+ const next = sanitize(raw);
240
+ if (raw !== next) {
241
+ const caret = el.selectionStart ?? raw.length;
242
+ const keptBefore = sanitize(raw.slice(0, caret)).length;
243
+ el.value = next;
244
+ el.setSelectionRange(keptBefore, keptBefore);
245
+ }
223
246
  emit("update:modelValue", next);
224
247
  }
225
- function onChange(e) {
226
- const el = e.target;
227
- const next = sanitize(el.value);
248
+ function commit(el) {
249
+ const num = toNumber(sanitize(el.value));
250
+ const next = num === null ? sanitize(el.value) : format(clamp(normalize(num)));
228
251
  if (el.value !== next) el.value = next;
252
+ if (next !== props.modelValue) emit("update:modelValue", next);
229
253
  emit("change", next);
230
254
  }
231
- function stepBy(dir) {
232
- if (props.disabled) return;
233
- const nextStr = format(clamp(normalize((toNumber(props.modelValue) ?? 0) + (props.step ?? 1) * dir)));
255
+ function onChange(e) {
256
+ commit(e.target);
257
+ }
258
+ function setValue(n) {
259
+ const nextStr = format(clamp(normalize(n)));
234
260
  emit("update:modelValue", nextStr);
235
261
  emit("change", nextStr);
262
+ }
263
+ function stepBy(dir) {
264
+ if (props.disabled) return;
265
+ setValue((toNumber(props.modelValue) ?? 0) + (props.step ?? 1) * dir);
236
266
  focus();
237
267
  }
268
+ function onKeydown(e) {
269
+ if (props.disabled) return;
270
+ switch (e.key) {
271
+ case "ArrowUp":
272
+ e.preventDefault();
273
+ stepBy(1);
274
+ break;
275
+ case "ArrowDown":
276
+ e.preventDefault();
277
+ stepBy(-1);
278
+ break;
279
+ case "Home":
280
+ if (props.min !== void 0) {
281
+ e.preventDefault();
282
+ setValue(props.min);
283
+ }
284
+ break;
285
+ case "End":
286
+ if (props.max !== void 0) {
287
+ e.preventDefault();
288
+ setValue(props.max);
289
+ }
290
+ break;
291
+ }
292
+ }
293
+ const ariaValueNow = computed(() => toNumber(props.modelValue) ?? void 0);
294
+ const isFocused = ref(false);
295
+ function formatGrouped(value) {
296
+ const num = toNumber(value);
297
+ if (num === null) return value;
298
+ const sep = props.decimalSeparator || ".";
299
+ return new Intl.NumberFormat(props.locale, {
300
+ useGrouping: true,
301
+ minimumFractionDigits: props.precision ?? 0,
302
+ maximumFractionDigits: props.precision ?? 20
303
+ }).formatToParts(num).map((part) => part.type === "decimal" ? sep : part.value).join("");
304
+ }
305
+ const displayValue = computed(() => {
306
+ if (!props.useGrouping || isFocused.value) return props.modelValue;
307
+ return formatGrouped(props.modelValue);
308
+ });
309
+ function onFocus() {
310
+ isFocused.value = true;
311
+ }
312
+ function onBlur() {
313
+ isFocused.value = false;
314
+ }
238
315
  return (_ctx, _cache) => {
239
316
  return openBlock(), createElementBlock("div", {
240
317
  "data-gr-number-input": "",
241
- class: normalizeClass(["relative w-full overflow-hidden rounded-md border bg-[var(--bg)] transition-colors duration-150 focus-within:ring-2 focus-within:ring-[var(--ring)]", shellClassName.value])
318
+ class: normalizeClass(["relative w-full overflow-hidden rounded-md border bg-[var(--gr-bg)] transition-colors duration-150 focus-within:ring-2 focus-within:ring-[var(--gr-ring)]", shellClassName.value])
242
319
  }, [
243
320
  _ctx.$slots.prefix ? (openBlock(), createElementBlock("div", {
244
321
  key: 0,
@@ -246,7 +323,7 @@ var GrNumberInput_default = /* @__PURE__ */ defineComponent({
246
323
  ref: prefixEl,
247
324
  "data-testid": "number-input-prefix",
248
325
  "data-gr-number-input-prefix": "",
249
- class: "absolute inset-y-0 left-0 flex items-center justify-center border-r border-[var(--brd)] px-2 text-[var(--muted-fg)] pointer-events-none select-none truncate",
326
+ class: "absolute inset-y-0 left-0 flex items-center justify-center border-r border-[var(--gr-brd)] px-2 text-[var(--gr-muted-fg)] pointer-events-none select-none truncate",
250
327
  style: normalizeStyle(prefixStyle.value),
251
328
  "aria-hidden": "true"
252
329
  }, [renderSlot(_ctx.$slots, "prefix")], 4)) : createCommentVNode("", true),
@@ -261,12 +338,19 @@ var GrNumberInput_default = /* @__PURE__ */ defineComponent({
261
338
  autocomplete: __props.autocomplete,
262
339
  placeholder: __props.placeholder,
263
340
  disabled: __props.disabled,
264
- value: __props.modelValue,
341
+ value: displayValue.value,
342
+ role: "spinbutton",
343
+ "aria-valuenow": ariaValueNow.value,
344
+ "aria-valuemin": __props.min,
345
+ "aria-valuemax": __props.max,
265
346
  "aria-invalid": __props.invalid ? "true" : void 0,
266
- class: ["w-full bg-transparent text-[var(--fg)] placeholder:text-[var(--muted-fg)] focus:placeholder:text-transparent focus:outline-none disabled:cursor-not-allowed", inputClassName.value],
347
+ class: ["w-full bg-transparent text-[var(--gr-fg)] placeholder:text-[var(--gr-muted-fg)] focus:placeholder:text-transparent focus:outline-none disabled:cursor-not-allowed", inputClassName.value],
267
348
  style: inputStyle.value,
268
349
  onInput,
269
- onChange
350
+ onChange,
351
+ onKeydown,
352
+ onFocus,
353
+ onBlur
270
354
  }), null, 16, _hoisted_1),
271
355
  _ctx.$slots.suffix ? (openBlock(), createElementBlock("div", {
272
356
  key: 1,
@@ -274,7 +358,7 @@ var GrNumberInput_default = /* @__PURE__ */ defineComponent({
274
358
  ref: suffixEl,
275
359
  "data-testid": "number-input-suffix",
276
360
  "data-gr-number-input-suffix": "",
277
- class: normalizeClass(["absolute inset-y-0 flex items-center justify-center border-l border-[var(--brd)] px-2 text-[var(--muted-fg)] pointer-events-none select-none truncate", __props.suffixFixed ? "[direction:rtl]" : ""]),
361
+ class: normalizeClass(["absolute inset-y-0 flex items-center justify-center border-l border-[var(--gr-brd)] px-2 text-[var(--gr-muted-fg)] pointer-events-none select-none truncate", __props.suffixFixed ? "[direction:rtl]" : ""]),
278
362
  style: normalizeStyle(suffixStyle.value),
279
363
  "aria-hidden": "true"
280
364
  }, [renderSlot(_ctx.$slots, "suffix")], 6)) : createCommentVNode("", true),
@@ -282,11 +366,11 @@ var GrNumberInput_default = /* @__PURE__ */ defineComponent({
282
366
  key: 2,
283
367
  "data-testid": "number-input-controls-vertical",
284
368
  "data-gr-number-input-controls": "vertical",
285
- class: "absolute inset-y-0 flex items-center justify-center border-l border-[var(--brd)]",
369
+ class: "absolute inset-y-0 flex items-center justify-center border-l border-[var(--gr-brd)]",
286
370
  style: normalizeStyle(verticalControlsStyle.value)
287
371
  }, [createElementVNode("div", _hoisted_2, [createElementVNode("button", {
288
372
  type: "button",
289
- class: "h-4 w-7 inline-flex items-center justify-center rounded text-[10px] text-[var(--muted-fg)] hover:bg-[var(--muted)] active:bg-[var(--muted)] disabled:opacity-50 disabled:cursor-not-allowed",
373
+ class: "h-4 w-7 inline-flex items-center justify-center rounded text-[10px] text-[var(--gr-muted-fg)] hover:bg-[var(--gr-muted)] active:bg-[var(--gr-muted)] disabled:opacity-50 disabled:cursor-not-allowed",
290
374
  disabled: __props.disabled,
291
375
  "aria-label": resolvedIncreaseLabel.value,
292
376
  onMousedown: _cache[0] || (_cache[0] = withModifiers(() => {}, ["prevent"])),
@@ -306,7 +390,7 @@ var GrNumberInput_default = /* @__PURE__ */ defineComponent({
306
390
  "stroke-linejoin": "round"
307
391
  })], -1)])], 40, _hoisted_3), createElementVNode("button", {
308
392
  type: "button",
309
- class: "h-4 w-7 inline-flex items-center justify-center rounded text-[10px] text-[var(--muted-fg)] hover:bg-[var(--muted)] active:bg-[var(--muted)] disabled:opacity-50 disabled:cursor-not-allowed",
393
+ class: "h-4 w-7 inline-flex items-center justify-center rounded text-[10px] text-[var(--gr-muted-fg)] hover:bg-[var(--gr-muted)] active:bg-[var(--gr-muted)] disabled:opacity-50 disabled:cursor-not-allowed",
310
394
  disabled: __props.disabled,
311
395
  "aria-label": resolvedDecreaseLabel.value,
312
396
  onMousedown: _cache[2] || (_cache[2] = withModifiers(() => {}, ["prevent"])),
@@ -329,11 +413,11 @@ var GrNumberInput_default = /* @__PURE__ */ defineComponent({
329
413
  key: 3,
330
414
  "data-testid": "number-input-controls-horizontal-left",
331
415
  "data-gr-number-input-controls": "horizontal-left",
332
- class: "absolute inset-y-0 flex items-stretch justify-center border-r border-[var(--brd)]",
416
+ class: "absolute inset-y-0 flex items-stretch justify-center border-r border-[var(--gr-brd)]",
333
417
  style: normalizeStyle(horizontalLeftControlsStyle.value)
334
418
  }, [createElementVNode("button", {
335
419
  type: "button",
336
- class: "h-full w-full inline-flex items-center justify-center text-[var(--muted-fg)] hover:bg-[var(--muted)] active:bg-[var(--muted)] disabled:opacity-50 disabled:cursor-not-allowed focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)]",
420
+ class: "h-full w-full inline-flex items-center justify-center text-[var(--gr-muted-fg)] hover:bg-[var(--gr-muted)] active:bg-[var(--gr-muted)] disabled:opacity-50 disabled:cursor-not-allowed focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--gr-ring)]",
337
421
  disabled: __props.disabled,
338
422
  "aria-label": resolvedDecreaseLabel.value,
339
423
  onMousedown: _cache[4] || (_cache[4] = withModifiers(() => {}, ["prevent"])),
@@ -356,11 +440,11 @@ var GrNumberInput_default = /* @__PURE__ */ defineComponent({
356
440
  key: 4,
357
441
  "data-testid": "number-input-controls-horizontal-right",
358
442
  "data-gr-number-input-controls": "horizontal-right",
359
- class: "absolute inset-y-0 flex items-stretch justify-center border-l border-[var(--brd)]",
443
+ class: "absolute inset-y-0 flex items-stretch justify-center border-l border-[var(--gr-brd)]",
360
444
  style: normalizeStyle(horizontalRightControlsStyle.value)
361
445
  }, [createElementVNode("button", {
362
446
  type: "button",
363
- class: "h-full w-full inline-flex items-center justify-center text-[var(--muted-fg)] hover:bg-[var(--muted)] active:bg-[var(--muted)] disabled:opacity-50 disabled:cursor-not-allowed focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)]",
447
+ class: "h-full w-full inline-flex items-center justify-center text-[var(--gr-muted-fg)] hover:bg-[var(--gr-muted)] active:bg-[var(--gr-muted)] disabled:opacity-50 disabled:cursor-not-allowed focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--gr-ring)]",
364
448
  disabled: __props.disabled,
365
449
  "aria-label": resolvedIncreaseLabel.value,
366
450
  onMousedown: _cache[6] || (_cache[6] = withModifiers(() => {}, ["prevent"])),
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GrNumberInput-l9ZOHG9D.js","names":["$slots","$attrs"],"sources":["../../../../src/components/GrNumberInput/GrNumberInput.vue","../../../../src/components/GrNumberInput/GrNumberInput.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { InputHTMLAttributes } from 'vue'\n\nimport { useGrComponentSize } from '../GrConfigProvider/context'\nimport { computed, ref, useSlots } from 'vue'\n\nimport {\n grNumberInputInputClass,\n grNumberInputShellClass,\n type GrNumberInputControlsDirection,\n type GrNumberInputSize,\n type GrNumberInputState,\n type GrNumberInputTextAlign,\n} from './grNumberInputStyles'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport { addLen, useAddonMeasurement } from '../../composables/internal/useAddonMeasurement'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst ADDON_PX_BY_SIZE: Record<GrNumberInputSize, number> = {\n xs: 32,\n sm: 36,\n md: 40,\n lg: 48,\n}\n\nconst BASE_PADDING_X_LEN_BY_SIZE: Record<GrNumberInputSize, string> = {\n xs: '10px',\n sm: '12px',\n md: '12px',\n lg: '16px',\n}\n\nfunction px(n: number): string {\n return `${n}px`\n}\n\nexport interface GrNumberInputProps {\n /** Значение (строка — контролируем форматирование внутри). */\n modelValue: string\n placeholder?: string\n autocomplete?: string\n inputmode?: InputHTMLAttributes['inputmode']\n disabled?: boolean\n /** Быстрый флаг невалидности; эквивалент `state='danger'` + `aria-invalid`. */\n invalid?: boolean\n state?: GrNumberInputState\n name?: string\n id?: string\n size?: GrNumberInputSize\n\n textAlign?: GrNumberInputTextAlign\n\n decimalSeparator?: string\n step?: number\n min?: number\n max?: number\n precision?: number\n\n /**\n * BCP-47 локаль для отображения значения (группировка разрядов и разделители\n * через `Intl.NumberFormat`). Работает вместе с `useGrouping`.\n */\n locale?: string\n /**\n * Группировать разряды при отображении (когда поле не в фокусе). При фокусе\n * показывается «сырое» значение для редактирования. По умолчанию выключено.\n */\n useGrouping?: boolean\n\n /** Показывать кнопки +/-. */\n controls?: boolean\n controlsDirection?: GrNumberInputControlsDirection\n\n prefixMinWidth?: string\n prefixMaxWidth?: string\n suffixMinWidth?: string\n suffixMaxWidth?: string\n /**\n * Фиксированная ширина у prefix/suffix: жёсткая ширина (из `*MaxWidth` →\n * `*MinWidth` → дефолт) + обрезка контента по краю (prefix — справа,\n * suffix — слева). По умолчанию аддоны растягиваются под контент.\n */\n prefixFixed?: boolean\n suffixFixed?: boolean\n\n /** i18n-friendly aria-label для кнопки \"увеличить\". */\n increaseLabel?: string\n /** i18n-friendly aria-label для кнопки \"уменьшить\". */\n decreaseLabel?: string\n}\n\nconst props = withDefaults(defineProps<GrNumberInputProps>(), {\n placeholder: undefined,\n autocomplete: undefined,\n inputmode: 'decimal',\n disabled: false,\n invalid: false,\n state: 'default',\n name: undefined,\n id: undefined,\n size: undefined,\n\n textAlign: 'left',\n\n decimalSeparator: '.',\n step: 1,\n min: undefined,\n max: undefined,\n precision: undefined,\n locale: undefined,\n useGrouping: false,\n\n controls: false,\n controlsDirection: 'vertical',\n\n prefixMinWidth: undefined,\n prefixMaxWidth: undefined,\n suffixMinWidth: undefined,\n suffixMaxWidth: undefined,\n prefixFixed: false,\n suffixFixed: false,\n\n increaseLabel: undefined,\n decreaseLabel: undefined,\n})\n\n// Эффективный размер: локальный проп → `GrConfigProvider` → дефолт компонента.\nconst resolvedSize = useGrComponentSize(() => props.size, { component: 'GrNumberInput' })\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string): void\n (e: 'change', value: string): void\n}>()\n\nconst inputEl = ref<HTMLInputElement | null>(null)\n\nfunction focus(): void {\n inputEl.value?.focus()\n}\n\ndefineExpose({\n focus,\n})\n\nconst slots = useSlots()\n\nconst { t } = useGranularityTranslations()\nconst resolvedIncreaseLabel = computed(() => props.increaseLabel ?? t('gr.numberInput.increase', 'Increase'))\nconst resolvedDecreaseLabel = computed(() => props.decreaseLabel ?? t('gr.numberInput.decrease', 'Decrease'))\n\nconst hasPrefix = computed(() => Boolean(slots.prefix))\nconst hasSuffix = computed(() => Boolean(slots.suffix))\n\nconst hasHorizontalControls = computed(() => props.controls && props.controlsDirection === 'horizontal')\nconst hasVerticalControls = computed(() => props.controls && props.controlsDirection === 'vertical')\n\nconst addonPx = computed(() => ADDON_PX_BY_SIZE[resolvedSize.value])\nconst addonLen = computed(() => px(addonPx.value))\nconst basePaddingXLen = computed(() => BASE_PADDING_X_LEN_BY_SIZE[resolvedSize.value])\n\nconst defaultAddonMinWidth = computed(() => addonLen.value)\nconst prefixMinWidth = computed(() => props.prefixMinWidth ?? defaultAddonMinWidth.value)\nconst suffixMinWidth = computed(() => props.suffixMinWidth ?? defaultAddonMinWidth.value)\n\n// Жёсткая ширина для fixed-режима: max → min → дефолт.\nconst prefixFixedWidth = computed(() => props.prefixMaxWidth ?? props.prefixMinWidth ?? defaultAddonMinWidth.value)\nconst suffixFixedWidth = computed(() => props.suffixMaxWidth ?? props.suffixMinWidth ?? defaultAddonMinWidth.value)\n\nconst { prefixEl, suffixEl, measuredPrefixWidth, measuredSuffixWidth } = useAddonMeasurement(hasPrefix, hasSuffix)\n\nconst prefixLen = computed(() => {\n if (!hasPrefix.value) return '0px'\n return props.prefixFixed ? prefixFixedWidth.value : measuredPrefixWidth.value ?? prefixMinWidth.value\n})\nconst suffixLen = computed(() => {\n if (!hasSuffix.value) return '0px'\n return props.suffixFixed ? suffixFixedWidth.value : measuredSuffixWidth.value ?? suffixMinWidth.value\n})\n\nfunction addonStyle(side: 'left' | 'right', offset: string): Record<string, string> {\n return {\n width: addonLen.value,\n [side]: offset,\n }\n}\n\nconst inputStyle = computed(() => {\n const leftControls = hasHorizontalControls.value ? addonLen.value : '0px'\n const rightControlsCount = (hasHorizontalControls.value ? 1 : 0) + (hasVerticalControls.value ? 1 : 0)\n const rightControls = rightControlsCount > 0 ? px(addonPx.value * rightControlsCount) : '0px'\n\n const leftReserved = addLen(prefixLen.value, leftControls)\n const rightReserved = addLen(suffixLen.value, rightControls)\n\n const left = hasPrefix.value || hasHorizontalControls.value ? addLen(leftReserved, basePaddingXLen.value) : undefined\n const right = hasSuffix.value || rightControlsCount > 0 ? addLen(rightReserved, basePaddingXLen.value) : undefined\n\n return {\n paddingLeft: left,\n paddingRight: right,\n } as Record<string, string | undefined>\n})\n\nconst suffixStyle = computed(() => {\n if (props.suffixFixed) {\n return {\n right: '0px',\n width: suffixFixedWidth.value,\n minWidth: suffixFixedWidth.value,\n maxWidth: suffixFixedWidth.value,\n }\n }\n\n return {\n right: '0px',\n minWidth: suffixMinWidth.value,\n maxWidth: props.suffixMaxWidth,\n }\n})\n\nconst prefixStyle = computed(() => {\n if (props.prefixFixed) {\n return {\n width: prefixFixedWidth.value,\n minWidth: prefixFixedWidth.value,\n maxWidth: prefixFixedWidth.value,\n }\n }\n\n return {\n minWidth: prefixMinWidth.value,\n maxWidth: props.prefixMaxWidth,\n }\n})\n\nconst verticalControlsStyle = computed(() => addonStyle('right', suffixLen.value))\nconst horizontalLeftControlsStyle = computed(() => addonStyle('left', prefixLen.value))\nconst horizontalRightControlsStyle = computed(() => addonStyle('right', suffixLen.value))\n\nconst shellClassName = computed(() => {\n return grNumberInputShellClass({\n disabled: props.disabled,\n state: props.invalid ? 'danger' : props.state,\n })\n})\n\nconst inputClassName = computed(() => {\n return grNumberInputInputClass({\n size: resolvedSize.value,\n textAlign: props.textAlign,\n })\n})\n\nfunction isDigit(ch: string): boolean {\n return ch >= '0' && ch <= '9'\n}\n\nfunction sanitize(raw: string): string {\n const sep = props.decimalSeparator || '.'\n\n let out = ''\n let hasSepLocal = false\n\n for (let i = 0; i < raw.length; i++) {\n const ch = raw[i]\n\n // Ведущий минус: разрешаем один в начале, чтобы можно было ввести\n // отрицательное значение с клавиатуры (границы проверит `clamp` на change).\n if (ch === '-' && out.length === 0) {\n out += '-'\n continue\n }\n\n if (isDigit(ch)) {\n out += ch\n continue\n }\n\n if ((ch === sep || ch === '.' || ch === ',') && !hasSepLocal) {\n out += sep\n hasSepLocal = true\n }\n }\n\n return out\n}\n\nfunction toNumber(value: string): number | null {\n if (value.trim() === '') return null\n const sep = props.decimalSeparator || '.'\n const normalized = sep === '.' ? value : value.replace(sep, '.')\n const n = Number(normalized)\n if (!Number.isFinite(n)) return null\n return n\n}\n\nfunction clamp(v: number): number {\n if (props.min !== undefined) v = Math.max(props.min, v)\n if (props.max !== undefined) v = Math.min(props.max, v)\n return v\n}\n\nfunction normalize(v: number): number {\n if (props.precision === undefined) return v\n const p = Math.max(0, props.precision)\n return Number(v.toFixed(p))\n}\n\nfunction format(n: number): string {\n const sep = props.decimalSeparator || '.'\n const p = props.precision\n\n // Без `precision` избегаем экспоненциальной записи (`String(1e21)` → `\"1e+21\"`),\n // форматируя через `Intl` без группировки разрядов.\n let s = p === undefined\n ? n.toLocaleString('en-US', { useGrouping: false, maximumFractionDigits: 20 })\n : n.toFixed(Math.max(0, p))\n if (sep !== '.') s = s.replace('.', sep)\n return s\n}\n\nfunction onInput(e: Event): void {\n const el = e.target as HTMLInputElement\n const raw = el.value\n const next = sanitize(raw)\n\n if (raw !== next) {\n // Сохраняем позицию каретки: считаем, сколько валидных символов было ДО\n // каретки, и ставим её после стольких же в очищенной строке — иначе при\n // редактировании середины числа каретка прыгала в конец.\n const caret = el.selectionStart ?? raw.length\n const keptBefore = sanitize(raw.slice(0, caret)).length\n el.value = next\n el.setSelectionRange(keptBefore, keptBefore)\n }\n\n emit('update:modelValue', next)\n}\n\nfunction commit(el: HTMLInputElement): void {\n const num = toNumber(sanitize(el.value))\n // Пустое значение (или незавершённый ввод `-`) оставляем как есть.\n const next = num === null ? sanitize(el.value) : format(clamp(normalize(num)))\n\n if (el.value !== next) el.value = next\n if (next !== props.modelValue) emit('update:modelValue', next)\n emit('change', next)\n}\n\nfunction onChange(e: Event): void {\n // Клампинг границ (`min`/`max`) и нормализация — на `change`/`blur`, а не только\n // в кнопках: раньше ручной ввод «999» при `max=10` оставался невалидным.\n commit(e.target as HTMLInputElement)\n}\n\nfunction setValue(n: number): void {\n const nextStr = format(clamp(normalize(n)))\n emit('update:modelValue', nextStr)\n emit('change', nextStr)\n}\n\nfunction stepBy(dir: 1 | -1): void {\n if (props.disabled) return\n\n const current = toNumber(props.modelValue) ?? 0\n setValue(current + (props.step ?? 1) * dir)\n focus()\n}\n\n// Клавиатура спинбаттона (WAI-ARIA spinbutton): стрелки шагают, Home/End —\n// к границам `min`/`max` (если заданы).\nfunction onKeydown(e: KeyboardEvent): void {\n if (props.disabled) return\n\n switch (e.key) {\n case 'ArrowUp':\n e.preventDefault()\n stepBy(1)\n break\n case 'ArrowDown':\n e.preventDefault()\n stepBy(-1)\n break\n case 'Home':\n if (props.min !== undefined) {\n e.preventDefault()\n setValue(props.min)\n }\n break\n case 'End':\n if (props.max !== undefined) {\n e.preventDefault()\n setValue(props.max)\n }\n break\n }\n}\n\n// `aria-valuenow` — числовое значение для скринридеров; отсутствует, если поле пусто.\nconst ariaValueNow = computed(() => toNumber(props.modelValue) ?? undefined)\n\n// Локале-зависимое отображение: при фокусе показываем «сырое» значение для\n// редактирования, иначе — сгруппированное через `Intl.NumberFormat`.\nconst isFocused = ref(false)\n\nfunction formatGrouped(value: string): string {\n const num = toNumber(value)\n if (num === null) return value\n const sep = props.decimalSeparator || '.'\n // formatToParts позволяет оставить локале-зависимый групповой разделитель,\n // но принудительно подставить наш десятичный разделитель (`decimalSeparator`),\n // корректно работая для любой локали (в т.ч. de-DE, где группа — '.').\n return new Intl.NumberFormat(props.locale, {\n useGrouping: true,\n minimumFractionDigits: props.precision ?? 0,\n maximumFractionDigits: props.precision ?? 20,\n })\n .formatToParts(num)\n .map(part => (part.type === 'decimal' ? sep : part.value))\n .join('')\n}\n\nconst displayValue = computed(() => {\n if (!props.useGrouping || isFocused.value) return props.modelValue\n return formatGrouped(props.modelValue)\n})\n\nfunction onFocus(): void {\n isFocused.value = true\n}\n\nfunction onBlur(): void {\n isFocused.value = false\n}\n</script>\n\n<template>\n <div\n data-gr-number-input\n class=\"relative w-full overflow-hidden rounded-md border bg-[var(--gr-bg)] transition-colors duration-150 focus-within:ring-2 focus-within:ring-[var(--gr-ring)]\"\n :class=\"shellClassName\"\n >\n <div\n v-if=\"$slots.prefix\"\n ref=\"prefixEl\"\n data-testid=\"number-input-prefix\"\n data-gr-number-input-prefix\n class=\"absolute inset-y-0 left-0 flex items-center justify-center border-r border-[var(--gr-brd)] px-2 text-[var(--gr-muted-fg)] pointer-events-none select-none truncate\"\n :style=\"prefixStyle\"\n aria-hidden=\"true\"\n >\n <slot name=\"prefix\" />\n </div>\n\n <input\n :id=\"id\"\n ref=\"inputEl\"\n v-bind=\"$attrs\"\n :name=\"name\"\n type=\"text\"\n :inputmode=\"inputmode\"\n :autocomplete=\"autocomplete\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :value=\"displayValue\"\n role=\"spinbutton\"\n :aria-valuenow=\"ariaValueNow\"\n :aria-valuemin=\"min\"\n :aria-valuemax=\"max\"\n :aria-invalid=\"invalid ? 'true' : undefined\"\n class=\"w-full bg-transparent text-[var(--gr-fg)] placeholder:text-[var(--gr-muted-fg)] focus:placeholder:text-transparent focus:outline-none disabled:cursor-not-allowed\"\n :class=\"inputClassName\"\n :style=\"inputStyle\"\n @input=\"onInput\"\n @change=\"onChange\"\n @keydown=\"onKeydown\"\n @focus=\"onFocus\"\n @blur=\"onBlur\"\n >\n\n <div\n v-if=\"$slots.suffix\"\n ref=\"suffixEl\"\n data-testid=\"number-input-suffix\"\n data-gr-number-input-suffix\n class=\"absolute inset-y-0 flex items-center justify-center border-l border-[var(--gr-brd)] px-2 text-[var(--gr-muted-fg)] pointer-events-none select-none truncate\"\n :class=\"suffixFixed ? '[direction:rtl]' : ''\"\n :style=\"suffixStyle\"\n aria-hidden=\"true\"\n >\n <slot name=\"suffix\" />\n </div>\n\n <div\n v-if=\"hasVerticalControls\"\n data-testid=\"number-input-controls-vertical\"\n data-gr-number-input-controls=\"vertical\"\n class=\"absolute inset-y-0 flex items-center justify-center border-l border-[var(--gr-brd)]\"\n :style=\"verticalControlsStyle\"\n >\n <div class=\"flex flex-col justify-center gap-1\">\n <button\n type=\"button\"\n class=\"h-4 w-7 inline-flex items-center justify-center rounded text-[10px] text-[var(--gr-muted-fg)] hover:bg-[var(--gr-muted)] active:bg-[var(--gr-muted)] disabled:opacity-50 disabled:cursor-not-allowed\"\n :disabled=\"disabled\"\n :aria-label=\"resolvedIncreaseLabel\"\n @mousedown.prevent\n @click=\"stepBy(1)\"\n >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n d=\"M7 14l5-5 5 5\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n <button\n type=\"button\"\n class=\"h-4 w-7 inline-flex items-center justify-center rounded text-[10px] text-[var(--gr-muted-fg)] hover:bg-[var(--gr-muted)] active:bg-[var(--gr-muted)] disabled:opacity-50 disabled:cursor-not-allowed\"\n :disabled=\"disabled\"\n :aria-label=\"resolvedDecreaseLabel\"\n @mousedown.prevent\n @click=\"stepBy(-1)\"\n >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n d=\"M7 10l5 5 5-5\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n </div>\n </div>\n\n <div\n v-if=\"hasHorizontalControls\"\n data-testid=\"number-input-controls-horizontal-left\"\n data-gr-number-input-controls=\"horizontal-left\"\n class=\"absolute inset-y-0 flex items-stretch justify-center border-r border-[var(--gr-brd)]\"\n :style=\"horizontalLeftControlsStyle\"\n >\n <button\n type=\"button\"\n class=\"h-full w-full inline-flex items-center justify-center text-[var(--gr-muted-fg)] hover:bg-[var(--gr-muted)] active:bg-[var(--gr-muted)] disabled:opacity-50 disabled:cursor-not-allowed focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--gr-ring)]\"\n :disabled=\"disabled\"\n :aria-label=\"resolvedDecreaseLabel\"\n @mousedown.prevent\n @click=\"stepBy(-1)\"\n >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n d=\"M14 7l-5 5 5 5\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n </div>\n\n <div\n v-if=\"hasHorizontalControls\"\n data-testid=\"number-input-controls-horizontal-right\"\n data-gr-number-input-controls=\"horizontal-right\"\n class=\"absolute inset-y-0 flex items-stretch justify-center border-l border-[var(--gr-brd)]\"\n :style=\"horizontalRightControlsStyle\"\n >\n <button\n type=\"button\"\n class=\"h-full w-full inline-flex items-center justify-center text-[var(--gr-muted-fg)] hover:bg-[var(--gr-muted)] active:bg-[var(--gr-muted)] disabled:opacity-50 disabled:cursor-not-allowed focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--gr-ring)]\"\n :disabled=\"disabled\"\n :aria-label=\"resolvedIncreaseLabel\"\n @mousedown.prevent\n @click=\"stepBy(1)\"\n >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n d=\"M10 7l5 5-5 5\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport type { InputHTMLAttributes } from 'vue'\n\nimport { useGrComponentSize } from '../GrConfigProvider/context'\nimport { computed, ref, useSlots } from 'vue'\n\nimport {\n grNumberInputInputClass,\n grNumberInputShellClass,\n type GrNumberInputControlsDirection,\n type GrNumberInputSize,\n type GrNumberInputState,\n type GrNumberInputTextAlign,\n} from './grNumberInputStyles'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport { addLen, useAddonMeasurement } from '../../composables/internal/useAddonMeasurement'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst ADDON_PX_BY_SIZE: Record<GrNumberInputSize, number> = {\n xs: 32,\n sm: 36,\n md: 40,\n lg: 48,\n}\n\nconst BASE_PADDING_X_LEN_BY_SIZE: Record<GrNumberInputSize, string> = {\n xs: '10px',\n sm: '12px',\n md: '12px',\n lg: '16px',\n}\n\nfunction px(n: number): string {\n return `${n}px`\n}\n\nexport interface GrNumberInputProps {\n /** Значение (строка — контролируем форматирование внутри). */\n modelValue: string\n placeholder?: string\n autocomplete?: string\n inputmode?: InputHTMLAttributes['inputmode']\n disabled?: boolean\n /** Быстрый флаг невалидности; эквивалент `state='danger'` + `aria-invalid`. */\n invalid?: boolean\n state?: GrNumberInputState\n name?: string\n id?: string\n size?: GrNumberInputSize\n\n textAlign?: GrNumberInputTextAlign\n\n decimalSeparator?: string\n step?: number\n min?: number\n max?: number\n precision?: number\n\n /**\n * BCP-47 локаль для отображения значения (группировка разрядов и разделители\n * через `Intl.NumberFormat`). Работает вместе с `useGrouping`.\n */\n locale?: string\n /**\n * Группировать разряды при отображении (когда поле не в фокусе). При фокусе\n * показывается «сырое» значение для редактирования. По умолчанию выключено.\n */\n useGrouping?: boolean\n\n /** Показывать кнопки +/-. */\n controls?: boolean\n controlsDirection?: GrNumberInputControlsDirection\n\n prefixMinWidth?: string\n prefixMaxWidth?: string\n suffixMinWidth?: string\n suffixMaxWidth?: string\n /**\n * Фиксированная ширина у prefix/suffix: жёсткая ширина (из `*MaxWidth` →\n * `*MinWidth` → дефолт) + обрезка контента по краю (prefix — справа,\n * suffix — слева). По умолчанию аддоны растягиваются под контент.\n */\n prefixFixed?: boolean\n suffixFixed?: boolean\n\n /** i18n-friendly aria-label для кнопки \"увеличить\". */\n increaseLabel?: string\n /** i18n-friendly aria-label для кнопки \"уменьшить\". */\n decreaseLabel?: string\n}\n\nconst props = withDefaults(defineProps<GrNumberInputProps>(), {\n placeholder: undefined,\n autocomplete: undefined,\n inputmode: 'decimal',\n disabled: false,\n invalid: false,\n state: 'default',\n name: undefined,\n id: undefined,\n size: undefined,\n\n textAlign: 'left',\n\n decimalSeparator: '.',\n step: 1,\n min: undefined,\n max: undefined,\n precision: undefined,\n locale: undefined,\n useGrouping: false,\n\n controls: false,\n controlsDirection: 'vertical',\n\n prefixMinWidth: undefined,\n prefixMaxWidth: undefined,\n suffixMinWidth: undefined,\n suffixMaxWidth: undefined,\n prefixFixed: false,\n suffixFixed: false,\n\n increaseLabel: undefined,\n decreaseLabel: undefined,\n})\n\n// Эффективный размер: локальный проп → `GrConfigProvider` → дефолт компонента.\nconst resolvedSize = useGrComponentSize(() => props.size, { component: 'GrNumberInput' })\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string): void\n (e: 'change', value: string): void\n}>()\n\nconst inputEl = ref<HTMLInputElement | null>(null)\n\nfunction focus(): void {\n inputEl.value?.focus()\n}\n\ndefineExpose({\n focus,\n})\n\nconst slots = useSlots()\n\nconst { t } = useGranularityTranslations()\nconst resolvedIncreaseLabel = computed(() => props.increaseLabel ?? t('gr.numberInput.increase', 'Increase'))\nconst resolvedDecreaseLabel = computed(() => props.decreaseLabel ?? t('gr.numberInput.decrease', 'Decrease'))\n\nconst hasPrefix = computed(() => Boolean(slots.prefix))\nconst hasSuffix = computed(() => Boolean(slots.suffix))\n\nconst hasHorizontalControls = computed(() => props.controls && props.controlsDirection === 'horizontal')\nconst hasVerticalControls = computed(() => props.controls && props.controlsDirection === 'vertical')\n\nconst addonPx = computed(() => ADDON_PX_BY_SIZE[resolvedSize.value])\nconst addonLen = computed(() => px(addonPx.value))\nconst basePaddingXLen = computed(() => BASE_PADDING_X_LEN_BY_SIZE[resolvedSize.value])\n\nconst defaultAddonMinWidth = computed(() => addonLen.value)\nconst prefixMinWidth = computed(() => props.prefixMinWidth ?? defaultAddonMinWidth.value)\nconst suffixMinWidth = computed(() => props.suffixMinWidth ?? defaultAddonMinWidth.value)\n\n// Жёсткая ширина для fixed-режима: max → min → дефолт.\nconst prefixFixedWidth = computed(() => props.prefixMaxWidth ?? props.prefixMinWidth ?? defaultAddonMinWidth.value)\nconst suffixFixedWidth = computed(() => props.suffixMaxWidth ?? props.suffixMinWidth ?? defaultAddonMinWidth.value)\n\nconst { prefixEl, suffixEl, measuredPrefixWidth, measuredSuffixWidth } = useAddonMeasurement(hasPrefix, hasSuffix)\n\nconst prefixLen = computed(() => {\n if (!hasPrefix.value) return '0px'\n return props.prefixFixed ? prefixFixedWidth.value : measuredPrefixWidth.value ?? prefixMinWidth.value\n})\nconst suffixLen = computed(() => {\n if (!hasSuffix.value) return '0px'\n return props.suffixFixed ? suffixFixedWidth.value : measuredSuffixWidth.value ?? suffixMinWidth.value\n})\n\nfunction addonStyle(side: 'left' | 'right', offset: string): Record<string, string> {\n return {\n width: addonLen.value,\n [side]: offset,\n }\n}\n\nconst inputStyle = computed(() => {\n const leftControls = hasHorizontalControls.value ? addonLen.value : '0px'\n const rightControlsCount = (hasHorizontalControls.value ? 1 : 0) + (hasVerticalControls.value ? 1 : 0)\n const rightControls = rightControlsCount > 0 ? px(addonPx.value * rightControlsCount) : '0px'\n\n const leftReserved = addLen(prefixLen.value, leftControls)\n const rightReserved = addLen(suffixLen.value, rightControls)\n\n const left = hasPrefix.value || hasHorizontalControls.value ? addLen(leftReserved, basePaddingXLen.value) : undefined\n const right = hasSuffix.value || rightControlsCount > 0 ? addLen(rightReserved, basePaddingXLen.value) : undefined\n\n return {\n paddingLeft: left,\n paddingRight: right,\n } as Record<string, string | undefined>\n})\n\nconst suffixStyle = computed(() => {\n if (props.suffixFixed) {\n return {\n right: '0px',\n width: suffixFixedWidth.value,\n minWidth: suffixFixedWidth.value,\n maxWidth: suffixFixedWidth.value,\n }\n }\n\n return {\n right: '0px',\n minWidth: suffixMinWidth.value,\n maxWidth: props.suffixMaxWidth,\n }\n})\n\nconst prefixStyle = computed(() => {\n if (props.prefixFixed) {\n return {\n width: prefixFixedWidth.value,\n minWidth: prefixFixedWidth.value,\n maxWidth: prefixFixedWidth.value,\n }\n }\n\n return {\n minWidth: prefixMinWidth.value,\n maxWidth: props.prefixMaxWidth,\n }\n})\n\nconst verticalControlsStyle = computed(() => addonStyle('right', suffixLen.value))\nconst horizontalLeftControlsStyle = computed(() => addonStyle('left', prefixLen.value))\nconst horizontalRightControlsStyle = computed(() => addonStyle('right', suffixLen.value))\n\nconst shellClassName = computed(() => {\n return grNumberInputShellClass({\n disabled: props.disabled,\n state: props.invalid ? 'danger' : props.state,\n })\n})\n\nconst inputClassName = computed(() => {\n return grNumberInputInputClass({\n size: resolvedSize.value,\n textAlign: props.textAlign,\n })\n})\n\nfunction isDigit(ch: string): boolean {\n return ch >= '0' && ch <= '9'\n}\n\nfunction sanitize(raw: string): string {\n const sep = props.decimalSeparator || '.'\n\n let out = ''\n let hasSepLocal = false\n\n for (let i = 0; i < raw.length; i++) {\n const ch = raw[i]\n\n // Ведущий минус: разрешаем один в начале, чтобы можно было ввести\n // отрицательное значение с клавиатуры (границы проверит `clamp` на change).\n if (ch === '-' && out.length === 0) {\n out += '-'\n continue\n }\n\n if (isDigit(ch)) {\n out += ch\n continue\n }\n\n if ((ch === sep || ch === '.' || ch === ',') && !hasSepLocal) {\n out += sep\n hasSepLocal = true\n }\n }\n\n return out\n}\n\nfunction toNumber(value: string): number | null {\n if (value.trim() === '') return null\n const sep = props.decimalSeparator || '.'\n const normalized = sep === '.' ? value : value.replace(sep, '.')\n const n = Number(normalized)\n if (!Number.isFinite(n)) return null\n return n\n}\n\nfunction clamp(v: number): number {\n if (props.min !== undefined) v = Math.max(props.min, v)\n if (props.max !== undefined) v = Math.min(props.max, v)\n return v\n}\n\nfunction normalize(v: number): number {\n if (props.precision === undefined) return v\n const p = Math.max(0, props.precision)\n return Number(v.toFixed(p))\n}\n\nfunction format(n: number): string {\n const sep = props.decimalSeparator || '.'\n const p = props.precision\n\n // Без `precision` избегаем экспоненциальной записи (`String(1e21)` → `\"1e+21\"`),\n // форматируя через `Intl` без группировки разрядов.\n let s = p === undefined\n ? n.toLocaleString('en-US', { useGrouping: false, maximumFractionDigits: 20 })\n : n.toFixed(Math.max(0, p))\n if (sep !== '.') s = s.replace('.', sep)\n return s\n}\n\nfunction onInput(e: Event): void {\n const el = e.target as HTMLInputElement\n const raw = el.value\n const next = sanitize(raw)\n\n if (raw !== next) {\n // Сохраняем позицию каретки: считаем, сколько валидных символов было ДО\n // каретки, и ставим её после стольких же в очищенной строке — иначе при\n // редактировании середины числа каретка прыгала в конец.\n const caret = el.selectionStart ?? raw.length\n const keptBefore = sanitize(raw.slice(0, caret)).length\n el.value = next\n el.setSelectionRange(keptBefore, keptBefore)\n }\n\n emit('update:modelValue', next)\n}\n\nfunction commit(el: HTMLInputElement): void {\n const num = toNumber(sanitize(el.value))\n // Пустое значение (или незавершённый ввод `-`) оставляем как есть.\n const next = num === null ? sanitize(el.value) : format(clamp(normalize(num)))\n\n if (el.value !== next) el.value = next\n if (next !== props.modelValue) emit('update:modelValue', next)\n emit('change', next)\n}\n\nfunction onChange(e: Event): void {\n // Клампинг границ (`min`/`max`) и нормализация — на `change`/`blur`, а не только\n // в кнопках: раньше ручной ввод «999» при `max=10` оставался невалидным.\n commit(e.target as HTMLInputElement)\n}\n\nfunction setValue(n: number): void {\n const nextStr = format(clamp(normalize(n)))\n emit('update:modelValue', nextStr)\n emit('change', nextStr)\n}\n\nfunction stepBy(dir: 1 | -1): void {\n if (props.disabled) return\n\n const current = toNumber(props.modelValue) ?? 0\n setValue(current + (props.step ?? 1) * dir)\n focus()\n}\n\n// Клавиатура спинбаттона (WAI-ARIA spinbutton): стрелки шагают, Home/End —\n// к границам `min`/`max` (если заданы).\nfunction onKeydown(e: KeyboardEvent): void {\n if (props.disabled) return\n\n switch (e.key) {\n case 'ArrowUp':\n e.preventDefault()\n stepBy(1)\n break\n case 'ArrowDown':\n e.preventDefault()\n stepBy(-1)\n break\n case 'Home':\n if (props.min !== undefined) {\n e.preventDefault()\n setValue(props.min)\n }\n break\n case 'End':\n if (props.max !== undefined) {\n e.preventDefault()\n setValue(props.max)\n }\n break\n }\n}\n\n// `aria-valuenow` — числовое значение для скринридеров; отсутствует, если поле пусто.\nconst ariaValueNow = computed(() => toNumber(props.modelValue) ?? undefined)\n\n// Локале-зависимое отображение: при фокусе показываем «сырое» значение для\n// редактирования, иначе — сгруппированное через `Intl.NumberFormat`.\nconst isFocused = ref(false)\n\nfunction formatGrouped(value: string): string {\n const num = toNumber(value)\n if (num === null) return value\n const sep = props.decimalSeparator || '.'\n // formatToParts позволяет оставить локале-зависимый групповой разделитель,\n // но принудительно подставить наш десятичный разделитель (`decimalSeparator`),\n // корректно работая для любой локали (в т.ч. de-DE, где группа — '.').\n return new Intl.NumberFormat(props.locale, {\n useGrouping: true,\n minimumFractionDigits: props.precision ?? 0,\n maximumFractionDigits: props.precision ?? 20,\n })\n .formatToParts(num)\n .map(part => (part.type === 'decimal' ? sep : part.value))\n .join('')\n}\n\nconst displayValue = computed(() => {\n if (!props.useGrouping || isFocused.value) return props.modelValue\n return formatGrouped(props.modelValue)\n})\n\nfunction onFocus(): void {\n isFocused.value = true\n}\n\nfunction onBlur(): void {\n isFocused.value = false\n}\n</script>\n\n<template>\n <div\n data-gr-number-input\n class=\"relative w-full overflow-hidden rounded-md border bg-[var(--gr-bg)] transition-colors duration-150 focus-within:ring-2 focus-within:ring-[var(--gr-ring)]\"\n :class=\"shellClassName\"\n >\n <div\n v-if=\"$slots.prefix\"\n ref=\"prefixEl\"\n data-testid=\"number-input-prefix\"\n data-gr-number-input-prefix\n class=\"absolute inset-y-0 left-0 flex items-center justify-center border-r border-[var(--gr-brd)] px-2 text-[var(--gr-muted-fg)] pointer-events-none select-none truncate\"\n :style=\"prefixStyle\"\n aria-hidden=\"true\"\n >\n <slot name=\"prefix\" />\n </div>\n\n <input\n :id=\"id\"\n ref=\"inputEl\"\n v-bind=\"$attrs\"\n :name=\"name\"\n type=\"text\"\n :inputmode=\"inputmode\"\n :autocomplete=\"autocomplete\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :value=\"displayValue\"\n role=\"spinbutton\"\n :aria-valuenow=\"ariaValueNow\"\n :aria-valuemin=\"min\"\n :aria-valuemax=\"max\"\n :aria-invalid=\"invalid ? 'true' : undefined\"\n class=\"w-full bg-transparent text-[var(--gr-fg)] placeholder:text-[var(--gr-muted-fg)] focus:placeholder:text-transparent focus:outline-none disabled:cursor-not-allowed\"\n :class=\"inputClassName\"\n :style=\"inputStyle\"\n @input=\"onInput\"\n @change=\"onChange\"\n @keydown=\"onKeydown\"\n @focus=\"onFocus\"\n @blur=\"onBlur\"\n >\n\n <div\n v-if=\"$slots.suffix\"\n ref=\"suffixEl\"\n data-testid=\"number-input-suffix\"\n data-gr-number-input-suffix\n class=\"absolute inset-y-0 flex items-center justify-center border-l border-[var(--gr-brd)] px-2 text-[var(--gr-muted-fg)] pointer-events-none select-none truncate\"\n :class=\"suffixFixed ? '[direction:rtl]' : ''\"\n :style=\"suffixStyle\"\n aria-hidden=\"true\"\n >\n <slot name=\"suffix\" />\n </div>\n\n <div\n v-if=\"hasVerticalControls\"\n data-testid=\"number-input-controls-vertical\"\n data-gr-number-input-controls=\"vertical\"\n class=\"absolute inset-y-0 flex items-center justify-center border-l border-[var(--gr-brd)]\"\n :style=\"verticalControlsStyle\"\n >\n <div class=\"flex flex-col justify-center gap-1\">\n <button\n type=\"button\"\n class=\"h-4 w-7 inline-flex items-center justify-center rounded text-[10px] text-[var(--gr-muted-fg)] hover:bg-[var(--gr-muted)] active:bg-[var(--gr-muted)] disabled:opacity-50 disabled:cursor-not-allowed\"\n :disabled=\"disabled\"\n :aria-label=\"resolvedIncreaseLabel\"\n @mousedown.prevent\n @click=\"stepBy(1)\"\n >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n d=\"M7 14l5-5 5 5\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n <button\n type=\"button\"\n class=\"h-4 w-7 inline-flex items-center justify-center rounded text-[10px] text-[var(--gr-muted-fg)] hover:bg-[var(--gr-muted)] active:bg-[var(--gr-muted)] disabled:opacity-50 disabled:cursor-not-allowed\"\n :disabled=\"disabled\"\n :aria-label=\"resolvedDecreaseLabel\"\n @mousedown.prevent\n @click=\"stepBy(-1)\"\n >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n d=\"M7 10l5 5 5-5\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n </div>\n </div>\n\n <div\n v-if=\"hasHorizontalControls\"\n data-testid=\"number-input-controls-horizontal-left\"\n data-gr-number-input-controls=\"horizontal-left\"\n class=\"absolute inset-y-0 flex items-stretch justify-center border-r border-[var(--gr-brd)]\"\n :style=\"horizontalLeftControlsStyle\"\n >\n <button\n type=\"button\"\n class=\"h-full w-full inline-flex items-center justify-center text-[var(--gr-muted-fg)] hover:bg-[var(--gr-muted)] active:bg-[var(--gr-muted)] disabled:opacity-50 disabled:cursor-not-allowed focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--gr-ring)]\"\n :disabled=\"disabled\"\n :aria-label=\"resolvedDecreaseLabel\"\n @mousedown.prevent\n @click=\"stepBy(-1)\"\n >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n d=\"M14 7l-5 5 5 5\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n </div>\n\n <div\n v-if=\"hasHorizontalControls\"\n data-testid=\"number-input-controls-horizontal-right\"\n data-gr-number-input-controls=\"horizontal-right\"\n class=\"absolute inset-y-0 flex items-stretch justify-center border-l border-[var(--gr-brd)]\"\n :style=\"horizontalRightControlsStyle\"\n >\n <button\n type=\"button\"\n class=\"h-full w-full inline-flex items-center justify-center text-[var(--gr-muted-fg)] hover:bg-[var(--gr-muted)] active:bg-[var(--gr-muted)] disabled:opacity-50 disabled:cursor-not-allowed focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--gr-ring)]\"\n :disabled=\"disabled\"\n :aria-label=\"resolvedIncreaseLabel\"\n @mousedown.prevent\n @click=\"stepBy(1)\"\n >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path\n d=\"M10 7l5 5-5 5\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n </div>\n </div>\n</template>\n"],"mappings":"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"}
@@ -1,3 +1,3 @@
1
- import { n as grNumberInputSafelist, t as grNumberInputConfig } from "../../chunks/config-C7NpDrfO.js";
2
- import { t as GrNumberInput_default } from "./chunks/GrNumberInput-CldPIWQx.js";
1
+ import { n as grNumberInputSafelist, t as grNumberInputConfig } from "../../chunks/config-gZWR75Bh2.js";
2
+ import { t as GrNumberInput_default } from "./chunks/GrNumberInput-l9ZOHG9D.js";
3
3
  export { GrNumberInput_default as GrNumberInput, GrNumberInput_default as default, grNumberInputConfig, grNumberInputSafelist };
@@ -1,22 +1,36 @@
1
- import { t as useGranularityTranslations } from "../../../chunks/granularityI18n-DoV7Ca2m.js";
2
- import { t as GrButton_default } from "../../GrButton/chunks/GrButton-BlffdeJr.js";
3
- import { t as GrSelect_default } from "../../GrSelect/chunks/GrSelect-RShK21lK.js";
4
- import { Fragment, computed, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, normalizeClass, openBlock, renderList, toDisplayString, unref, watch, withCtx } from "vue";
1
+ import { n as useGranularityTranslations } from "../../../chunks/granularityI18n-SH0I--GW.js";
2
+ import { t as GrButton_default } from "../../GrButton/chunks/GrButton-DCi4CUpo.js";
3
+ import { t as GrSelect_default } from "../../GrSelect/chunks/GrSelect-Dn3FgJ3Z.js";
4
+ import { Fragment, computed, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, normalizeClass, openBlock, ref, renderList, toDisplayString, unref, vModelText, watch, withCtx, withDirectives, withKeys } from "vue";
5
5
  //#region src/components/GrPagination/GrPagination.vue?vue&type=script&setup=true&lang.ts
6
6
  var _hoisted_1 = ["aria-label"];
7
7
  var _hoisted_2 = { class: "min-w-[100px]" };
8
- var _hoisted_3 = { class: "flex items-center gap-1" };
8
+ var _hoisted_3 = {
9
+ key: 0,
10
+ "data-gr-pagination-compact": "",
11
+ class: "px-2 text-sm text-[var(--gr-fg)] tabular-nums",
12
+ "aria-live": "polite"
13
+ };
9
14
  var _hoisted_4 = {
15
+ key: 1,
16
+ class: "flex items-center gap-1"
17
+ };
18
+ var _hoisted_5 = {
10
19
  key: 0,
11
20
  "data-gr-pagination-ellipsis": "",
12
21
  "aria-hidden": "true",
13
- class: "h-8 min-w-8 px-1 grid place-items-center text-sm text-[var(--muted-fg)]"
22
+ class: "h-8 min-w-8 px-1 grid place-items-center text-sm text-[var(--gr-muted-fg)]"
14
23
  };
15
- var _hoisted_5 = [
24
+ var _hoisted_6 = [
16
25
  "aria-current",
17
26
  "aria-label",
18
27
  "onClick"
19
28
  ];
29
+ var _hoisted_7 = {
30
+ key: 2,
31
+ class: "flex items-center gap-2 text-sm text-[var(--gr-muted-fg)]"
32
+ };
33
+ var _hoisted_8 = ["max", "aria-label"];
20
34
  //#endregion
21
35
  //#region src/components/GrPagination/GrPagination.vue
22
36
  var GrPagination_default = /* @__PURE__ */ defineComponent({
@@ -31,7 +45,16 @@ var GrPagination_default = /* @__PURE__ */ defineComponent({
31
45
  50
32
46
  ] },
33
47
  siblingCount: { default: 1 },
34
- boundaryCount: { default: 1 }
48
+ boundaryCount: { default: 1 },
49
+ compact: {
50
+ type: Boolean,
51
+ default: false
52
+ },
53
+ showJumper: {
54
+ type: Boolean,
55
+ default: false
56
+ },
57
+ jumperLabel: { default: void 0 }
35
58
  },
36
59
  emits: ["update:page", "update:pageSize"],
37
60
  setup(__props, { emit: __emit }) {
@@ -87,6 +110,14 @@ var GrPagination_default = /* @__PURE__ */ defineComponent({
87
110
  function last() {
88
111
  goTo(pageCount.value);
89
112
  }
113
+ const jumperValue = ref("");
114
+ function submitJumper() {
115
+ const parsed = Number.parseInt(jumperValue.value, 10);
116
+ jumperValue.value = "";
117
+ if (Number.isNaN(parsed)) return;
118
+ goTo(Math.min(pageCount.value, Math.max(1, parsed)));
119
+ }
120
+ const resolvedJumperLabel = computed(() => props.jumperLabel ?? t("gr.pagination.jumpTo", "Go to"));
90
121
  return (_ctx, _cache) => {
91
122
  return openBlock(), createElementBlock("div", {
92
123
  class: "flex flex-wrap items-center justify-end gap-3",
@@ -112,7 +143,7 @@ var GrPagination_default = /* @__PURE__ */ defineComponent({
112
143
  "data-gr-pagination-first": "",
113
144
  onClick: first
114
145
  }, {
115
- default: withCtx(() => [..._cache[1] || (_cache[1] = [createTextVNode(" « ", -1)])]),
146
+ default: withCtx(() => [..._cache[2] || (_cache[2] = [createTextVNode(" « ", -1)])]),
116
147
  _: 1
117
148
  }, 8, ["disabled", "aria-label"]),
118
149
  createVNode(GrButton_default, {
@@ -125,17 +156,17 @@ var GrPagination_default = /* @__PURE__ */ defineComponent({
125
156
  default: withCtx(() => [createTextVNode(toDisplayString(unref(t)("gr.pagination.prev", "Prev")), 1)]),
126
157
  _: 1
127
158
  }, 8, ["disabled"]),
128
- createElementVNode("div", _hoisted_3, [(openBlock(true), createElementBlock(Fragment, null, renderList(items.value, (item, index) => {
129
- return openBlock(), createElementBlock(Fragment, { key: index }, [item === "ellipsis-start" || item === "ellipsis-end" ? (openBlock(), createElementBlock("span", _hoisted_4, "…")) : (openBlock(), createElementBlock("button", {
159
+ __props.compact ? (openBlock(), createElementBlock("div", _hoisted_3, toDisplayString(__props.page) + " / " + toDisplayString(pageCount.value), 1)) : (openBlock(), createElementBlock("div", _hoisted_4, [(openBlock(true), createElementBlock(Fragment, null, renderList(items.value, (item, index) => {
160
+ return openBlock(), createElementBlock(Fragment, { key: index }, [item === "ellipsis-start" || item === "ellipsis-end" ? (openBlock(), createElementBlock("span", _hoisted_5, "…")) : (openBlock(), createElementBlock("button", {
130
161
  key: 1,
131
162
  type: "button",
132
163
  "data-gr-pagination-page": "",
133
164
  "aria-current": item === __props.page ? "page" : void 0,
134
165
  "aria-label": unref(t)("gr.pagination.page", "Page {n}", { n: item }),
135
- class: normalizeClass(["h-8 min-w-8 px-2 rounded-md text-sm font-600 transition-colors duration-150 focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)]", item === __props.page ? "bg-[var(--primary)] text-[var(--primary-fg)]" : "text-[var(--muted-fg)] hover:bg-[var(--muted)] hover:text-[var(--fg)]"]),
166
+ class: normalizeClass(["h-8 min-w-8 px-2 rounded-md text-sm font-600 transition-colors duration-150 focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--gr-ring)]", item === __props.page ? "bg-[var(--gr-primary)] text-[var(--gr-primary-fg)]" : "text-[var(--gr-muted-fg)] hover:bg-[var(--gr-muted)] hover:text-[var(--gr-fg)]"]),
136
167
  onClick: ($event) => goTo(item)
137
- }, toDisplayString(item), 11, _hoisted_5))], 64);
138
- }), 128))]),
168
+ }, toDisplayString(item), 11, _hoisted_6))], 64);
169
+ }), 128))])),
139
170
  createVNode(GrButton_default, {
140
171
  variant: "ghost",
141
172
  size: "sm",
@@ -154,9 +185,21 @@ var GrPagination_default = /* @__PURE__ */ defineComponent({
154
185
  "data-gr-pagination-last": "",
155
186
  onClick: last
156
187
  }, {
157
- default: withCtx(() => [..._cache[2] || (_cache[2] = [createTextVNode(" » ", -1)])]),
188
+ default: withCtx(() => [..._cache[3] || (_cache[3] = [createTextVNode(" » ", -1)])]),
158
189
  _: 1
159
- }, 8, ["disabled", "aria-label"])
190
+ }, 8, ["disabled", "aria-label"]),
191
+ __props.showJumper ? (openBlock(), createElementBlock("div", _hoisted_7, [createElementVNode("span", null, toDisplayString(resolvedJumperLabel.value), 1), withDirectives(createElementVNode("input", {
192
+ "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => jumperValue.value = $event),
193
+ type: "number",
194
+ min: "1",
195
+ max: pageCount.value,
196
+ inputmode: "numeric",
197
+ "data-gr-pagination-jumper": "",
198
+ "aria-label": resolvedJumperLabel.value,
199
+ class: "h-8 w-14 rounded-md border border-[var(--gr-brd)] bg-[var(--gr-bg)] px-2 text-center text-sm text-[var(--gr-fg)] tabular-nums transition-colors duration-150 focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--gr-ring)]",
200
+ onKeydown: withKeys(submitJumper, ["enter"]),
201
+ onBlur: submitJumper
202
+ }, null, 40, _hoisted_8), [[vModelText, jumperValue.value]])])) : createCommentVNode("", true)
160
203
  ], 8, _hoisted_1);
161
204
  };
162
205
  }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GrPagination-C5Y69CuK.js","names":[],"sources":["../../../../src/components/GrPagination/GrPagination.vue","../../../../src/components/GrPagination/GrPagination.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue'\n\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport GrButton from '../GrButton/GrButton.vue'\nimport GrSelect from '../GrSelect/GrSelect.vue'\n\n/**\n * Пропы пагинации.\n *\n * `total` интерпретируется как общее количество элементов; число страниц\n * вычисляется из `total` и `pageSize`. Номера усекаются многоточием\n * (алгоритм boundary/sibling, как у MUI): всегда видны первая/последняя страница\n * и `siblingCount` соседей вокруг текущей.\n */\nexport interface GrPaginationProps {\n page: number\n pageSize: number\n total: number\n pageSizes?: number[]\n /** Сколько соседних страниц показывать вокруг текущей. По умолчанию `1`. */\n siblingCount?: number\n /** Сколько крайних страниц всегда показывать с каждого края. По умолчанию `1`. */\n boundaryCount?: number\n /**\n * Компактный вариант: вместо нумерованных страниц показывается индикатор\n * «текущая / всего» — удобно для узких мест (мобайл, тулбары таблиц).\n */\n compact?: boolean\n /** Показывать поле «перейти к странице» с быстрым переходом по вводу номера. */\n showJumper?: boolean\n /** i18n-подпись перед полем перехода. По умолчанию — `gr.pagination.jumpTo`. */\n jumperLabel?: string\n}\n\nconst { t } = useGranularityTranslations()\n\nconst props = withDefaults(defineProps<GrPaginationProps>(), {\n pageSizes: () => [10, 20, 50],\n siblingCount: 1,\n boundaryCount: 1,\n compact: false,\n showJumper: false,\n jumperLabel: undefined,\n})\n\nconst emit = defineEmits<{\n (e: 'update:page', value: number): void\n (e: 'update:pageSize', value: number): void\n}>()\n\nconst pageCount = computed(() => Math.max(1, Math.ceil(props.total / props.pageSize)))\n\n// Контролируемый компонент: если `total`/`pageSize` уменьшились и текущая `page`\n// вышла за диапазон — просим родителя подтянуть её к последней странице.\nwatch(pageCount, (count) => {\n if (props.page > count)\n emit('update:page', count)\n})\n\nconst pageSizeModel = computed({\n get: () => String(props.pageSize),\n set: (value: string) => emit('update:pageSize', Number(value)),\n})\n\nconst pageSizeOptions = computed(() =>\n props.pageSizes.map(pageSize => ({\n value: String(pageSize),\n label: String(pageSize),\n })),\n)\n\ntype PaginationItem = number | 'ellipsis-start' | 'ellipsis-end'\n\nfunction range(start: number, end: number): number[] {\n const list: number[] = []\n for (let page = start; page <= end; page += 1)\n list.push(page)\n return list\n}\n\n// Алгоритм usePagination как в MUI: крайние `boundaryCount` страниц + `siblingCount`\n// соседей вокруг текущей, разрывы схлопываются в многоточие. Одиночный «пропущенный»\n// номер показываем как номер, а не как «…» (визуально ровнее).\nconst items = computed<PaginationItem[]>(() => {\n const count = pageCount.value\n const current = props.page\n const boundaryCount = Math.max(0, props.boundaryCount)\n const siblingCount = Math.max(0, props.siblingCount)\n\n const startPages = range(1, Math.min(boundaryCount, count))\n const endPages = range(Math.max(count - boundaryCount + 1, boundaryCount + 1), count)\n\n const siblingsStart = Math.max(\n Math.min(current - siblingCount, count - boundaryCount - siblingCount * 2 - 1),\n boundaryCount + 2,\n )\n const siblingsEnd = Math.min(\n Math.max(current + siblingCount, boundaryCount + siblingCount * 2 + 2),\n endPages.length > 0 ? endPages[0] - 2 : count - 1,\n )\n\n return [\n ...startPages,\n ...(siblingsStart > boundaryCount + 2\n ? ['ellipsis-start' as const]\n : boundaryCount + 1 < count - boundaryCount\n ? [boundaryCount + 1]\n : []),\n ...range(siblingsStart, siblingsEnd),\n ...(siblingsEnd < count - boundaryCount - 1\n ? ['ellipsis-end' as const]\n : count - boundaryCount > boundaryCount\n ? [count - boundaryCount]\n : []),\n ...endPages,\n ]\n})\n\nfunction goTo(page: number): void {\n emit('update:page', page)\n}\n\nfunction prev(): void {\n goTo(Math.max(1, props.page - 1))\n}\n\nfunction next(): void {\n goTo(Math.min(pageCount.value, props.page + 1))\n}\n\nfunction first(): void {\n goTo(1)\n}\n\nfunction last(): void {\n goTo(pageCount.value)\n}\n\n// «Перейти к странице»: клампим введённый номер к диапазону [1, pageCount]\n// и сбрасываем поле после перехода.\nconst jumperValue = ref('')\n\nfunction submitJumper(): void {\n const parsed = Number.parseInt(jumperValue.value, 10)\n jumperValue.value = ''\n if (Number.isNaN(parsed))\n return\n\n goTo(Math.min(pageCount.value, Math.max(1, parsed)))\n}\n\nconst resolvedJumperLabel = computed(() => props.jumperLabel ?? t('gr.pagination.jumpTo', 'Go to'))\n</script>\n\n<template>\n <div\n class=\"flex flex-wrap items-center justify-end gap-3\"\n data-gr-pagination\n role=\"navigation\"\n :aria-label=\"t('gr.pagination.label', 'Pagination')\"\n >\n <div class=\"min-w-[100px]\">\n <GrSelect\n v-model=\"pageSizeModel\"\n :options=\"pageSizeOptions\"\n :aria-label=\"t('gr.pagination.pageSize', 'Page size')\"\n />\n </div>\n\n <GrButton variant=\"ghost\" size=\"sm\" :disabled=\"page <= 1\" :aria-label=\"t('gr.pagination.first', 'First page')\" data-gr-pagination-first @click=\"first\">\n «\n </GrButton>\n\n <GrButton variant=\"ghost\" size=\"sm\" :disabled=\"page <= 1\" data-gr-pagination-prev @click=\"prev\">\n {{ t('gr.pagination.prev', 'Prev') }}\n </GrButton>\n\n <!-- Компактный вариант: индикатор «текущая / всего» вместо нумерованных страниц. -->\n <div\n v-if=\"compact\"\n data-gr-pagination-compact\n class=\"px-2 text-sm text-[var(--gr-fg)] tabular-nums\"\n aria-live=\"polite\"\n >\n {{ page }} / {{ pageCount }}\n </div>\n\n <div v-else class=\"flex items-center gap-1\">\n <template v-for=\"(item, index) in items\" :key=\"index\">\n <span\n v-if=\"item === 'ellipsis-start' || item === 'ellipsis-end'\"\n data-gr-pagination-ellipsis\n aria-hidden=\"true\"\n class=\"h-8 min-w-8 px-1 grid place-items-center text-sm text-[var(--gr-muted-fg)]\"\n >…</span>\n <button\n v-else\n type=\"button\"\n data-gr-pagination-page\n :aria-current=\"item === page ? 'page' : undefined\"\n :aria-label=\"t('gr.pagination.page', 'Page {n}', { n: item })\"\n class=\"h-8 min-w-8 px-2 rounded-md text-sm font-600 transition-colors duration-150 focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--gr-ring)]\"\n :class=\"item === page ? 'bg-[var(--gr-primary)] text-[var(--gr-primary-fg)]' : 'text-[var(--gr-muted-fg)] hover:bg-[var(--gr-muted)] hover:text-[var(--gr-fg)]'\"\n @click=\"goTo(item)\"\n >\n {{ item }}\n </button>\n </template>\n </div>\n\n <GrButton variant=\"ghost\" size=\"sm\" :disabled=\"page >= pageCount\" data-gr-pagination-next @click=\"next\">\n {{ t('gr.pagination.next', 'Next') }}\n </GrButton>\n\n <GrButton variant=\"ghost\" size=\"sm\" :disabled=\"page >= pageCount\" :aria-label=\"t('gr.pagination.last', 'Last page')\" data-gr-pagination-last @click=\"last\">\n »\n </GrButton>\n\n <!-- «Перейти к странице»: Enter или blur применяют введённый номер. -->\n <div v-if=\"showJumper\" class=\"flex items-center gap-2 text-sm text-[var(--gr-muted-fg)]\">\n <span>{{ resolvedJumperLabel }}</span>\n <input\n v-model=\"jumperValue\"\n type=\"number\"\n min=\"1\"\n :max=\"pageCount\"\n inputmode=\"numeric\"\n data-gr-pagination-jumper\n :aria-label=\"resolvedJumperLabel\"\n class=\"h-8 w-14 rounded-md border border-[var(--gr-brd)] bg-[var(--gr-bg)] px-2 text-center text-sm text-[var(--gr-fg)] tabular-nums transition-colors duration-150 focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--gr-ring)]\"\n @keydown.enter=\"submitJumper\"\n @blur=\"submitJumper\"\n >\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue'\n\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport GrButton from '../GrButton/GrButton.vue'\nimport GrSelect from '../GrSelect/GrSelect.vue'\n\n/**\n * Пропы пагинации.\n *\n * `total` интерпретируется как общее количество элементов; число страниц\n * вычисляется из `total` и `pageSize`. Номера усекаются многоточием\n * (алгоритм boundary/sibling, как у MUI): всегда видны первая/последняя страница\n * и `siblingCount` соседей вокруг текущей.\n */\nexport interface GrPaginationProps {\n page: number\n pageSize: number\n total: number\n pageSizes?: number[]\n /** Сколько соседних страниц показывать вокруг текущей. По умолчанию `1`. */\n siblingCount?: number\n /** Сколько крайних страниц всегда показывать с каждого края. По умолчанию `1`. */\n boundaryCount?: number\n /**\n * Компактный вариант: вместо нумерованных страниц показывается индикатор\n * «текущая / всего» — удобно для узких мест (мобайл, тулбары таблиц).\n */\n compact?: boolean\n /** Показывать поле «перейти к странице» с быстрым переходом по вводу номера. */\n showJumper?: boolean\n /** i18n-подпись перед полем перехода. По умолчанию — `gr.pagination.jumpTo`. */\n jumperLabel?: string\n}\n\nconst { t } = useGranularityTranslations()\n\nconst props = withDefaults(defineProps<GrPaginationProps>(), {\n pageSizes: () => [10, 20, 50],\n siblingCount: 1,\n boundaryCount: 1,\n compact: false,\n showJumper: false,\n jumperLabel: undefined,\n})\n\nconst emit = defineEmits<{\n (e: 'update:page', value: number): void\n (e: 'update:pageSize', value: number): void\n}>()\n\nconst pageCount = computed(() => Math.max(1, Math.ceil(props.total / props.pageSize)))\n\n// Контролируемый компонент: если `total`/`pageSize` уменьшились и текущая `page`\n// вышла за диапазон — просим родителя подтянуть её к последней странице.\nwatch(pageCount, (count) => {\n if (props.page > count)\n emit('update:page', count)\n})\n\nconst pageSizeModel = computed({\n get: () => String(props.pageSize),\n set: (value: string) => emit('update:pageSize', Number(value)),\n})\n\nconst pageSizeOptions = computed(() =>\n props.pageSizes.map(pageSize => ({\n value: String(pageSize),\n label: String(pageSize),\n })),\n)\n\ntype PaginationItem = number | 'ellipsis-start' | 'ellipsis-end'\n\nfunction range(start: number, end: number): number[] {\n const list: number[] = []\n for (let page = start; page <= end; page += 1)\n list.push(page)\n return list\n}\n\n// Алгоритм usePagination как в MUI: крайние `boundaryCount` страниц + `siblingCount`\n// соседей вокруг текущей, разрывы схлопываются в многоточие. Одиночный «пропущенный»\n// номер показываем как номер, а не как «…» (визуально ровнее).\nconst items = computed<PaginationItem[]>(() => {\n const count = pageCount.value\n const current = props.page\n const boundaryCount = Math.max(0, props.boundaryCount)\n const siblingCount = Math.max(0, props.siblingCount)\n\n const startPages = range(1, Math.min(boundaryCount, count))\n const endPages = range(Math.max(count - boundaryCount + 1, boundaryCount + 1), count)\n\n const siblingsStart = Math.max(\n Math.min(current - siblingCount, count - boundaryCount - siblingCount * 2 - 1),\n boundaryCount + 2,\n )\n const siblingsEnd = Math.min(\n Math.max(current + siblingCount, boundaryCount + siblingCount * 2 + 2),\n endPages.length > 0 ? endPages[0] - 2 : count - 1,\n )\n\n return [\n ...startPages,\n ...(siblingsStart > boundaryCount + 2\n ? ['ellipsis-start' as const]\n : boundaryCount + 1 < count - boundaryCount\n ? [boundaryCount + 1]\n : []),\n ...range(siblingsStart, siblingsEnd),\n ...(siblingsEnd < count - boundaryCount - 1\n ? ['ellipsis-end' as const]\n : count - boundaryCount > boundaryCount\n ? [count - boundaryCount]\n : []),\n ...endPages,\n ]\n})\n\nfunction goTo(page: number): void {\n emit('update:page', page)\n}\n\nfunction prev(): void {\n goTo(Math.max(1, props.page - 1))\n}\n\nfunction next(): void {\n goTo(Math.min(pageCount.value, props.page + 1))\n}\n\nfunction first(): void {\n goTo(1)\n}\n\nfunction last(): void {\n goTo(pageCount.value)\n}\n\n// «Перейти к странице»: клампим введённый номер к диапазону [1, pageCount]\n// и сбрасываем поле после перехода.\nconst jumperValue = ref('')\n\nfunction submitJumper(): void {\n const parsed = Number.parseInt(jumperValue.value, 10)\n jumperValue.value = ''\n if (Number.isNaN(parsed))\n return\n\n goTo(Math.min(pageCount.value, Math.max(1, parsed)))\n}\n\nconst resolvedJumperLabel = computed(() => props.jumperLabel ?? t('gr.pagination.jumpTo', 'Go to'))\n</script>\n\n<template>\n <div\n class=\"flex flex-wrap items-center justify-end gap-3\"\n data-gr-pagination\n role=\"navigation\"\n :aria-label=\"t('gr.pagination.label', 'Pagination')\"\n >\n <div class=\"min-w-[100px]\">\n <GrSelect\n v-model=\"pageSizeModel\"\n :options=\"pageSizeOptions\"\n :aria-label=\"t('gr.pagination.pageSize', 'Page size')\"\n />\n </div>\n\n <GrButton variant=\"ghost\" size=\"sm\" :disabled=\"page <= 1\" :aria-label=\"t('gr.pagination.first', 'First page')\" data-gr-pagination-first @click=\"first\">\n «\n </GrButton>\n\n <GrButton variant=\"ghost\" size=\"sm\" :disabled=\"page <= 1\" data-gr-pagination-prev @click=\"prev\">\n {{ t('gr.pagination.prev', 'Prev') }}\n </GrButton>\n\n <!-- Компактный вариант: индикатор «текущая / всего» вместо нумерованных страниц. -->\n <div\n v-if=\"compact\"\n data-gr-pagination-compact\n class=\"px-2 text-sm text-[var(--gr-fg)] tabular-nums\"\n aria-live=\"polite\"\n >\n {{ page }} / {{ pageCount }}\n </div>\n\n <div v-else class=\"flex items-center gap-1\">\n <template v-for=\"(item, index) in items\" :key=\"index\">\n <span\n v-if=\"item === 'ellipsis-start' || item === 'ellipsis-end'\"\n data-gr-pagination-ellipsis\n aria-hidden=\"true\"\n class=\"h-8 min-w-8 px-1 grid place-items-center text-sm text-[var(--gr-muted-fg)]\"\n >…</span>\n <button\n v-else\n type=\"button\"\n data-gr-pagination-page\n :aria-current=\"item === page ? 'page' : undefined\"\n :aria-label=\"t('gr.pagination.page', 'Page {n}', { n: item })\"\n class=\"h-8 min-w-8 px-2 rounded-md text-sm font-600 transition-colors duration-150 focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--gr-ring)]\"\n :class=\"item === page ? 'bg-[var(--gr-primary)] text-[var(--gr-primary-fg)]' : 'text-[var(--gr-muted-fg)] hover:bg-[var(--gr-muted)] hover:text-[var(--gr-fg)]'\"\n @click=\"goTo(item)\"\n >\n {{ item }}\n </button>\n </template>\n </div>\n\n <GrButton variant=\"ghost\" size=\"sm\" :disabled=\"page >= pageCount\" data-gr-pagination-next @click=\"next\">\n {{ t('gr.pagination.next', 'Next') }}\n </GrButton>\n\n <GrButton variant=\"ghost\" size=\"sm\" :disabled=\"page >= pageCount\" :aria-label=\"t('gr.pagination.last', 'Last page')\" data-gr-pagination-last @click=\"last\">\n »\n </GrButton>\n\n <!-- «Перейти к странице»: Enter или blur применяют введённый номер. -->\n <div v-if=\"showJumper\" class=\"flex items-center gap-2 text-sm text-[var(--gr-muted-fg)]\">\n <span>{{ resolvedJumperLabel }}</span>\n <input\n v-model=\"jumperValue\"\n type=\"number\"\n min=\"1\"\n :max=\"pageCount\"\n inputmode=\"numeric\"\n data-gr-pagination-jumper\n :aria-label=\"resolvedJumperLabel\"\n class=\"h-8 w-14 rounded-md border border-[var(--gr-brd)] bg-[var(--gr-bg)] px-2 text-center text-sm text-[var(--gr-fg)] tabular-nums transition-colors duration-150 focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--gr-ring)]\"\n @keydown.enter=\"submitJumper\"\n @blur=\"submitJumper\"\n >\n </div>\n </div>\n</template>\n"],"mappings":"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"}
@@ -1,3 +1,3 @@
1
- import { t as GrPagination_default } from "./chunks/GrPagination-Bu9wv6it.js";
1
+ import { t as GrPagination_default } from "./chunks/GrPagination-C5Y69CuK.js";
2
2
  import { t as grPaginationConfig } from "../../chunks/config-JpHA4Xx0.js";
3
3
  export { GrPagination_default as GrPagination, GrPagination_default as default, grPaginationConfig };
@@ -1,4 +1,4 @@
1
- import { t as grProgressBarFillClass } from "../../../chunks/grStyle-Blc9otAx.js";
1
+ import { t as grProgressBarFillClass } from "../../../chunks/grStyle-CdvxTXPH.js";
2
2
  import { computed, createElementBlock, createElementVNode, defineComponent, normalizeClass, normalizeStyle, openBlock } from "vue";
3
3
  //#region src/components/GrProgressBar/GrProgressBar.vue?vue&type=script&setup=true&lang.ts
4
4
  var _hoisted_1 = ["aria-label", "aria-valuenow"];
@@ -26,7 +26,7 @@ var GrProgressBar_default = /* @__PURE__ */ defineComponent({
26
26
  "aria-valuenow": safe.value,
27
27
  "aria-valuemin": "0",
28
28
  "aria-valuemax": "100",
29
- class: "h-2 w-full rounded-full bg-[var(--muted)] border border-[var(--brd)] overflow-hidden"
29
+ class: "h-2 w-full rounded-full bg-[var(--gr-muted)] border border-[var(--gr-brd)] overflow-hidden"
30
30
  }, [createElementVNode("div", {
31
31
  "data-gr-progress-bar-fill": "",
32
32
  class: normalizeClass(["h-full", fillClassName.value]),