@feugene/granularity 0.9.4 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (223) hide show
  1. package/dist/chunks/{config-d386uO3O.js.map → config-58Mj2rGH.js.map} +1 -1
  2. package/dist/chunks/{config-D4s_QWVP.js.map → config-8f8624RN.js.map} +1 -1
  3. package/dist/chunks/{config-B_nSBc7W.js.map → config-A-iei0Ux.js.map} +1 -1
  4. package/dist/chunks/{config-CFf7xaG1.js → config-B0uUCaJW.js} +1 -1
  5. package/dist/chunks/{config-CFf7xaG1.js.map → config-B0uUCaJW.js.map} +1 -1
  6. package/dist/chunks/{config-Dcb7xK-C.js.map → config-B3dn-gdC.js.map} +1 -1
  7. package/dist/chunks/{config-D6Oe3blW2.js.map → config-BLa1TEGm2.js.map} +1 -1
  8. package/dist/chunks/{config-Dzd6BzIN2.js.map → config-BeBsN0c12.js.map} +1 -1
  9. package/dist/chunks/{config-BU0olrvr.js.map → config-Bh4NWWsQ.js.map} +1 -1
  10. package/dist/chunks/{config-BeQuykDk2.js.map → config-BuoIngj32.js.map} +1 -1
  11. package/dist/chunks/{config-BbKroFtR.js.map → config-C5-ujXCI.js.map} +1 -1
  12. package/dist/chunks/{config-BY81UKv0.js → config-C8MM2Dg0.js} +1 -1
  13. package/dist/chunks/{config-BY81UKv0.js.map → config-C8MM2Dg0.js.map} +1 -1
  14. package/dist/chunks/{config-DF_RlCIO.js.map → config-CPSdAjUi.js.map} +1 -1
  15. package/dist/chunks/{config-iuMz79Mg.js.map → config-CWTfyPNI.js.map} +1 -1
  16. package/dist/chunks/{config-Br_qI3Za.js → config-C_egzT_K.js} +2 -2
  17. package/dist/chunks/config-C_egzT_K.js.map +1 -0
  18. package/dist/chunks/{config-Ci9nXGUV.js.map → config-C_q_4FrU.js.map} +1 -1
  19. package/dist/chunks/{config-O1_FTqD3.js.map → config-CzgNEHKi.js.map} +1 -1
  20. package/dist/chunks/{config-Bcf-8XlK2.js.map → config-DDUPnue12.js.map} +1 -1
  21. package/dist/chunks/{config-DmjwIqx1.js.map → config-DDwBSoc_.js.map} +1 -1
  22. package/dist/chunks/{config-C5OwJM3-.js → config-DRpkoSvq.js} +1 -1
  23. package/dist/chunks/{config-C5OwJM3-.js.map → config-DRpkoSvq.js.map} +1 -1
  24. package/dist/chunks/{config-DaHI5bD_2.js.map → config-DZrlovR42.js.map} +1 -1
  25. package/dist/chunks/{config-72sW9Bag2.js.map → config-D_Pafsjq2.js.map} +1 -1
  26. package/dist/chunks/{config-B1kFmhpM.js.map → config-DhQc1TRY.js.map} +1 -1
  27. package/dist/chunks/{config-CetsgpaZ2.js.map → config-DkeLkzxj2.js.map} +1 -1
  28. package/dist/chunks/{config-BOdu-O_B.js.map → config-Dl5aZ5VR.js.map} +1 -1
  29. package/dist/chunks/{config-CvGdaXvH.js.map → config-Doa_gU40.js.map} +1 -1
  30. package/dist/chunks/{config-CdJpnjDj.js.map → config-DvDNney3.js.map} +1 -1
  31. package/dist/chunks/{config-CpMYmvVT.js.map → config-NkbzVFZo.js.map} +1 -1
  32. package/dist/chunks/{config-_3De4HFf.js.map → config-RjfJFv1Y.js.map} +1 -1
  33. package/dist/chunks/{config-DoBk_CzG.js.map → config-VJuoznpH.js.map} +1 -1
  34. package/dist/chunks/{config-BnWSHTEU.js.map → config-XspHtPsU.js.map} +1 -1
  35. package/dist/chunks/{config-B2YTEe_h.js.map → config-hSlCXHoG.js.map} +1 -1
  36. package/dist/chunks/{config-DSBlHQVa.js.map → config-lMDE_8A5.js.map} +1 -1
  37. package/dist/chunks/{config-Cp_XHsze.js.map → config-nrOj9p6I.js.map} +1 -1
  38. package/dist/chunks/{en-foQA8imU.js → en-B_fSdoTi.js} +9 -2
  39. package/dist/chunks/en-B_fSdoTi.js.map +1 -0
  40. package/dist/chunks/{es-Bx3Kuy6z.js → es-CISK11Nv.js} +3 -3
  41. package/dist/chunks/{es-Bx3Kuy6z.js.map → es-CISK11Nv.js.map} +1 -1
  42. package/dist/chunks/{es-DZFSojYL.js → es-DKP6fLir.js} +9 -2
  43. package/dist/chunks/es-DKP6fLir.js.map +1 -0
  44. package/dist/chunks/{grDropdownStyles-B41mVR1H.js → grDropdownStyles-Bqx9hOzU.js} +10 -7
  45. package/dist/chunks/grDropdownStyles-Bqx9hOzU.js.map +1 -0
  46. package/dist/chunks/{grModalStyles-DS1Vl6EW.js → grModalStyles-FgaKqx50.js} +1 -1
  47. package/dist/chunks/grModalStyles-FgaKqx50.js.map +1 -0
  48. package/dist/chunks/{grSelectStyles-pUt19VGy.js.map → grSelectStyles-AjWWl007.js.map} +1 -1
  49. package/dist/chunks/{grStyle-CUaTmpyW.js.map → grStyle-D-gPHdyW.js.map} +1 -1
  50. package/dist/chunks/{granularityI18n-LcJ88Vce.js → granularityI18n-D_7jowK2.js} +17 -2
  51. package/dist/chunks/granularityI18n-D_7jowK2.js.map +1 -0
  52. package/dist/chunks/{ru-LhkPpPIl.js → ru-S6VlnurJ.js} +9 -2
  53. package/dist/chunks/ru-S6VlnurJ.js.map +1 -0
  54. package/dist/chunks/{shared-BiqXd5MW.js → shared-DpjTvFno.js} +34 -34
  55. package/dist/chunks/{shared-BiqXd5MW.js.map → shared-DpjTvFno.js.map} +1 -1
  56. package/dist/chunks/useFloating-CLtbU7eD.js +1234 -0
  57. package/dist/chunks/useFloating-CLtbU7eD.js.map +1 -0
  58. package/dist/components/GrConfirmDialog/chunks/{GrConfirmDialog-Br6WJkLE.js → GrConfirmDialog-Bi2KLumL.js} +2 -2
  59. package/dist/components/GrConfirmDialog/chunks/{GrConfirmDialog-Br6WJkLE.js.map → GrConfirmDialog-Bi2KLumL.js.map} +1 -1
  60. package/dist/components/GrConfirmDialog/index.js +1 -1
  61. package/dist/components/GrDialog/chunks/{GrDialog-C7XLxp8e.js → GrDialog-CxK4Lj4F.js} +1 -1
  62. package/dist/components/GrDialog/chunks/{GrDialog-C7XLxp8e.js.map → GrDialog-CxK4Lj4F.js.map} +1 -1
  63. package/dist/components/GrDialog/index.js +1 -1
  64. package/dist/components/GrDropdown/chunks/{GrDropdown-DOvHKnih.js → GrDropdown-BGKeEfZ1.js} +13 -59
  65. package/dist/components/GrDropdown/chunks/GrDropdown-BGKeEfZ1.js.map +1 -0
  66. package/dist/components/GrDropdown/index.js +2 -2
  67. package/dist/components/GrDropdownMenu/chunks/{GrDropdownMenu-CLPwbiyG.js → GrDropdownMenu-CJom_-c2.js} +1 -1
  68. package/dist/components/GrDropdownMenu/chunks/{GrDropdownMenu-CLPwbiyG.js.map → GrDropdownMenu-CJom_-c2.js.map} +1 -1
  69. package/dist/components/GrDropdownMenu/index.js +2 -2
  70. package/dist/components/GrEmptyState/chunks/{GrEmptyState-Dj2V5GaX.js.map → GrEmptyState-yOuZW7-t.js.map} +1 -1
  71. package/dist/components/GrEmptyState/index.js +2 -2
  72. package/dist/components/GrFileUpload/chunks/{GrFileUpload-BEKNB1RM.js → GrFileUpload-CBKK3dgC.js} +1 -1
  73. package/dist/components/GrFileUpload/chunks/{GrFileUpload-BEKNB1RM.js.map → GrFileUpload-CBKK3dgC.js.map} +1 -1
  74. package/dist/components/GrFileUpload/index.js +2 -2
  75. package/dist/components/GrFormField/index.js +1 -1
  76. package/dist/components/GrFormFile/chunks/{GrFormFile-CIleXnfr.js.map → GrFormFile-CkR6cYqf.js.map} +1 -1
  77. package/dist/components/GrFormFile/index.js +2 -2
  78. package/dist/components/GrFormSection/chunks/{GrFormSection-DpGhY7MX.js.map → GrFormSection-dbyzqxYk.js.map} +1 -1
  79. package/dist/components/GrFormSection/index.js +2 -2
  80. package/dist/components/GrImageViewer/chunks/{GrImageViewer-CsvXQHM9.js.map → GrImageViewer-BG40DsHa.js.map} +1 -1
  81. package/dist/components/GrImageViewer/index.js +2 -2
  82. package/dist/components/GrInput/index.js +1 -1
  83. package/dist/components/GrInputTag/chunks/{GrInputTag-Dcj3F6rQ.js → GrInputTag-g-KdUI_Z.js} +1 -1
  84. package/dist/components/GrInputTag/chunks/{GrInputTag-Dcj3F6rQ.js.map → GrInputTag-g-KdUI_Z.js.map} +1 -1
  85. package/dist/components/GrInputTag/index.js +2 -2
  86. package/dist/components/GrLink/chunks/{GrLink-BMwn2iJ9.js → GrLink-KSTmk9Yq.js} +1 -1
  87. package/dist/components/GrLink/chunks/{GrLink-BMwn2iJ9.js.map → GrLink-KSTmk9Yq.js.map} +1 -1
  88. package/dist/components/GrLink/index.js +2 -2
  89. package/dist/components/GrList/chunks/{GrList-D8nM1FuV.js.map → GrList-CUW2sRm_.js.map} +1 -1
  90. package/dist/components/GrList/index.js +2 -2
  91. package/dist/components/GrLoading/index.js +1 -1
  92. package/dist/components/GrModal/chunks/{GrModal-lh0lOmoi.js → GrModal-CSOL3fHQ.js} +1 -1
  93. package/dist/components/GrModal/chunks/{GrModal-lh0lOmoi.js.map → GrModal-CSOL3fHQ.js.map} +1 -1
  94. package/dist/components/GrModal/index.js +3 -3
  95. package/dist/components/GrNavbar/chunks/{GrNavbar-BH7XiF9q.js → GrNavbar-CHxwtFIR.js} +1 -1
  96. package/dist/components/GrNavbar/chunks/{GrNavbar-BH7XiF9q.js.map → GrNavbar-CHxwtFIR.js.map} +1 -1
  97. package/dist/components/GrNavbar/index.js +2 -2
  98. package/dist/components/GrNumberInput/chunks/{GrNumberInput-YIWhV85S.js → GrNumberInput-ClPBwkxx.js} +1 -1
  99. package/dist/components/GrNumberInput/chunks/{GrNumberInput-YIWhV85S.js.map → GrNumberInput-ClPBwkxx.js.map} +1 -1
  100. package/dist/components/GrNumberInput/index.js +2 -2
  101. package/dist/components/GrPagination/chunks/{GrPagination-BNDEqM8_.js → GrPagination-D2GS0ShQ.js} +4 -4
  102. package/dist/components/GrPagination/chunks/GrPagination-D2GS0ShQ.js.map +1 -0
  103. package/dist/components/GrPagination/index.js +2 -2
  104. package/dist/components/GrProgressBar/chunks/{GrProgressBar-C2HdYjp4.js → GrProgressBar-BBSFpVEq.js} +1 -1
  105. package/dist/components/GrProgressBar/chunks/{GrProgressBar-C2HdYjp4.js.map → GrProgressBar-BBSFpVEq.js.map} +1 -1
  106. package/dist/components/GrProgressBar/index.js +2 -2
  107. package/dist/components/GrPromptDialog/chunks/{GrPromptDialog-BV4EW3XO.js → GrPromptDialog-D_TFqKsF.js} +2 -2
  108. package/dist/components/GrPromptDialog/chunks/{GrPromptDialog-BV4EW3XO.js.map → GrPromptDialog-D_TFqKsF.js.map} +1 -1
  109. package/dist/components/GrPromptDialog/index.js +2 -2
  110. package/dist/components/GrRadio/chunks/{GrRadio-IFU9Hiu2.js → GrRadio-CSbTnrom.js} +1 -1
  111. package/dist/components/GrRadio/chunks/{GrRadio-IFU9Hiu2.js.map → GrRadio-CSbTnrom.js.map} +1 -1
  112. package/dist/components/GrRadio/index.js +2 -2
  113. package/dist/components/GrRadioGroup/chunks/{GrRadioGroup-C8IcJuuF.js → GrRadioGroup-DsrnTygR.js} +1 -1
  114. package/dist/components/GrRadioGroup/chunks/{GrRadioGroup-C8IcJuuF.js.map → GrRadioGroup-DsrnTygR.js.map} +1 -1
  115. package/dist/components/GrRadioGroup/index.js +2 -2
  116. package/dist/components/GrResponseErrorBanner/chunks/{GrResponseErrorBanner-BMvXREcv.js → GrResponseErrorBanner-K1uZ1mYD.js} +1 -1
  117. package/dist/components/GrResponseErrorBanner/chunks/{GrResponseErrorBanner-BMvXREcv.js.map → GrResponseErrorBanner-K1uZ1mYD.js.map} +1 -1
  118. package/dist/components/GrResponseErrorBanner/chunks/{GrResponseErrorBanner-CzdTh4gd.js → GrResponseErrorBanner-bM8FC_Bw.js} +1 -1
  119. package/dist/components/GrResponseErrorBanner/chunks/{GrResponseErrorBanner-CzdTh4gd.js.map → GrResponseErrorBanner-bM8FC_Bw.js.map} +1 -1
  120. package/dist/components/GrResponseErrorBanner/index.js +2 -2
  121. package/dist/components/GrSegmented/chunks/{GrSegmented-BRmwBsEG.js → GrSegmented-DpZGs4VX.js} +1 -1
  122. package/dist/components/GrSegmented/chunks/{GrSegmented-BRmwBsEG.js.map → GrSegmented-DpZGs4VX.js.map} +1 -1
  123. package/dist/components/GrSegmented/index.js +2 -2
  124. package/dist/components/GrSelect/chunks/{GrSelect-CnHdbPlf.js → GrSelect-DSz7jvUb.js} +25 -51
  125. package/dist/components/GrSelect/chunks/GrSelect-DSz7jvUb.js.map +1 -0
  126. package/dist/components/GrSelect/index.js +2 -2
  127. package/dist/components/GrSidebar/chunks/{GrSidebar-BpBtAGBs.js.map → GrSidebar-BW8LRMZ-.js.map} +1 -1
  128. package/dist/components/GrSidebar/index.js +2 -2
  129. package/dist/components/GrSkeleton/chunks/{GrSkeleton-URyMkBqI.js.map → GrSkeleton-B05K0QKh.js.map} +1 -1
  130. package/dist/components/GrSkeleton/index.js +2 -2
  131. package/dist/components/GrSwitch/chunks/{GrSwitch-29h0QhMO.js → GrSwitch-CSRtcN5-.js} +1 -1
  132. package/dist/components/GrSwitch/chunks/{GrSwitch-29h0QhMO.js.map → GrSwitch-CSRtcN5-.js.map} +1 -1
  133. package/dist/components/GrSwitch/index.js +2 -2
  134. package/dist/components/GrTable/index.js +1 -1
  135. package/dist/components/GrTabs/chunks/{GrTabs-D3ntDdtg.js.map → GrTabs-BfeVNMFJ.js.map} +1 -1
  136. package/dist/components/GrTabs/index.js +2 -2
  137. package/dist/components/GrTextarea/chunks/{GrTextarea-Cv6r2GuC.js → GrTextarea-CBBzpF2S.js} +1 -1
  138. package/dist/components/GrTextarea/chunks/{GrTextarea-Cv6r2GuC.js.map → GrTextarea-CBBzpF2S.js.map} +1 -1
  139. package/dist/components/GrTextarea/index.js +2 -2
  140. package/dist/components/GrToaster/chunks/{GrToaster-DluJmR5D.js → GrToaster-C6_iHk2J.js} +4 -3
  141. package/dist/components/GrToaster/chunks/GrToaster-C6_iHk2J.js.map +1 -0
  142. package/dist/components/GrToaster/index.js +2 -2
  143. package/dist/components/GrTooltip/chunks/GrTooltip-BC-40SA5.js +109 -0
  144. package/dist/components/GrTooltip/chunks/GrTooltip-BC-40SA5.js.map +1 -0
  145. package/dist/components/GrTooltip/index.js +2 -2
  146. package/dist/components/GrTree/chunks/{GrTree-B2SMU5Py.js.map → GrTree-uZr5SyQI.js.map} +1 -1
  147. package/dist/components/GrTree/index.js +2 -2
  148. package/dist/components/GrTreeSelect/chunks/{GrTreeSelect-C1abr5uH.js → GrTreeSelect-CytivcCa.js} +9 -37
  149. package/dist/components/GrTreeSelect/chunks/GrTreeSelect-CytivcCa.js.map +1 -0
  150. package/dist/components/GrTreeSelect/index.js +2 -2
  151. package/dist/granular-provider-node.js +2 -2
  152. package/dist/granular-provider.js +1 -1
  153. package/dist/i18n/all.js +1 -1
  154. package/dist/i18n/index.js +1 -1
  155. package/dist/index.js +67 -67
  156. package/dist/types/src/components/GrDropdown/grDropdownStyles.d.ts +3 -2
  157. package/dist/types/src/components/GrDropdownMenu/GrDropdownMenu.vue.d.ts +2 -2
  158. package/dist/types/src/components/GrDropdownMenu/GrDropdownMenuGroup.vue.d.ts +1 -1
  159. package/dist/types/src/components/GrDropdownMenu/GrDropdownMenuList.vue.d.ts +2 -2
  160. package/dist/types/src/components/GrFileUpload/GrFileUpload.vue.d.ts +1 -1
  161. package/dist/types/src/components/GrLink/GrLink.vue.d.ts +1 -1
  162. package/dist/types/src/components/GrModal/grModalStyles.d.ts +1 -1
  163. package/dist/types/src/components/GrSegmented/GrSegmented.vue.d.ts +1 -1
  164. package/dist/types/src/components/GrSelect/GrSelect.vue.d.ts +6 -6
  165. package/dist/types/src/composables/internal/useFloating.d.ts +53 -0
  166. package/dist/types/src/i18n/messages/en.d.ts +12 -0
  167. package/dist/types/src/i18n/messages/es.d.ts +12 -0
  168. package/dist/types/src/i18n/messages/ru.d.ts +12 -0
  169. package/package.json +9 -1
  170. package/dist/chunks/config-Br_qI3Za.js.map +0 -1
  171. package/dist/chunks/en-foQA8imU.js.map +0 -1
  172. package/dist/chunks/es-DZFSojYL.js.map +0 -1
  173. package/dist/chunks/grDropdownStyles-B41mVR1H.js.map +0 -1
  174. package/dist/chunks/grModalStyles-DS1Vl6EW.js.map +0 -1
  175. package/dist/chunks/granularityI18n-LcJ88Vce.js.map +0 -1
  176. package/dist/chunks/ru-LhkPpPIl.js.map +0 -1
  177. package/dist/components/GrDropdown/chunks/GrDropdown-DOvHKnih.js.map +0 -1
  178. package/dist/components/GrPagination/chunks/GrPagination-BNDEqM8_.js.map +0 -1
  179. package/dist/components/GrSelect/chunks/GrSelect-CnHdbPlf.js.map +0 -1
  180. package/dist/components/GrToaster/chunks/GrToaster-DluJmR5D.js.map +0 -1
  181. package/dist/components/GrTooltip/chunks/GrTooltip-B7I1AVIC.js +0 -55
  182. package/dist/components/GrTooltip/chunks/GrTooltip-B7I1AVIC.js.map +0 -1
  183. package/dist/components/GrTreeSelect/chunks/GrTreeSelect-C1abr5uH.js.map +0 -1
  184. /package/dist/chunks/{config-d386uO3O.js → config-58Mj2rGH.js} +0 -0
  185. /package/dist/chunks/{config-D4s_QWVP.js → config-8f8624RN.js} +0 -0
  186. /package/dist/chunks/{config-B_nSBc7W.js → config-A-iei0Ux.js} +0 -0
  187. /package/dist/chunks/{config-Dcb7xK-C.js → config-B3dn-gdC.js} +0 -0
  188. /package/dist/chunks/{config-D6Oe3blW2.js → config-BLa1TEGm2.js} +0 -0
  189. /package/dist/chunks/{config-Dzd6BzIN2.js → config-BeBsN0c12.js} +0 -0
  190. /package/dist/chunks/{config-BU0olrvr.js → config-Bh4NWWsQ.js} +0 -0
  191. /package/dist/chunks/{config-BeQuykDk2.js → config-BuoIngj32.js} +0 -0
  192. /package/dist/chunks/{config-BbKroFtR.js → config-C5-ujXCI.js} +0 -0
  193. /package/dist/chunks/{config-DF_RlCIO.js → config-CPSdAjUi.js} +0 -0
  194. /package/dist/chunks/{config-iuMz79Mg.js → config-CWTfyPNI.js} +0 -0
  195. /package/dist/chunks/{config-Ci9nXGUV.js → config-C_q_4FrU.js} +0 -0
  196. /package/dist/chunks/{config-O1_FTqD3.js → config-CzgNEHKi.js} +0 -0
  197. /package/dist/chunks/{config-Bcf-8XlK2.js → config-DDUPnue12.js} +0 -0
  198. /package/dist/chunks/{config-DmjwIqx1.js → config-DDwBSoc_.js} +0 -0
  199. /package/dist/chunks/{config-DaHI5bD_2.js → config-DZrlovR42.js} +0 -0
  200. /package/dist/chunks/{config-72sW9Bag2.js → config-D_Pafsjq2.js} +0 -0
  201. /package/dist/chunks/{config-B1kFmhpM.js → config-DhQc1TRY.js} +0 -0
  202. /package/dist/chunks/{config-CetsgpaZ2.js → config-DkeLkzxj2.js} +0 -0
  203. /package/dist/chunks/{config-BOdu-O_B.js → config-Dl5aZ5VR.js} +0 -0
  204. /package/dist/chunks/{config-CvGdaXvH.js → config-Doa_gU40.js} +0 -0
  205. /package/dist/chunks/{config-CdJpnjDj.js → config-DvDNney3.js} +0 -0
  206. /package/dist/chunks/{config-CpMYmvVT.js → config-NkbzVFZo.js} +0 -0
  207. /package/dist/chunks/{config-_3De4HFf.js → config-RjfJFv1Y.js} +0 -0
  208. /package/dist/chunks/{config-DoBk_CzG.js → config-VJuoznpH.js} +0 -0
  209. /package/dist/chunks/{config-BnWSHTEU.js → config-XspHtPsU.js} +0 -0
  210. /package/dist/chunks/{config-B2YTEe_h.js → config-hSlCXHoG.js} +0 -0
  211. /package/dist/chunks/{config-DSBlHQVa.js → config-lMDE_8A5.js} +0 -0
  212. /package/dist/chunks/{config-Cp_XHsze.js → config-nrOj9p6I.js} +0 -0
  213. /package/dist/chunks/{grSelectStyles-pUt19VGy.js → grSelectStyles-AjWWl007.js} +0 -0
  214. /package/dist/chunks/{grStyle-CUaTmpyW.js → grStyle-D-gPHdyW.js} +0 -0
  215. /package/dist/components/GrEmptyState/chunks/{GrEmptyState-Dj2V5GaX.js → GrEmptyState-yOuZW7-t.js} +0 -0
  216. /package/dist/components/GrFormFile/chunks/{GrFormFile-CIleXnfr.js → GrFormFile-CkR6cYqf.js} +0 -0
  217. /package/dist/components/GrFormSection/chunks/{GrFormSection-DpGhY7MX.js → GrFormSection-dbyzqxYk.js} +0 -0
  218. /package/dist/components/GrImageViewer/chunks/{GrImageViewer-CsvXQHM9.js → GrImageViewer-BG40DsHa.js} +0 -0
  219. /package/dist/components/GrList/chunks/{GrList-D8nM1FuV.js → GrList-CUW2sRm_.js} +0 -0
  220. /package/dist/components/GrSidebar/chunks/{GrSidebar-BpBtAGBs.js → GrSidebar-BW8LRMZ-.js} +0 -0
  221. /package/dist/components/GrSkeleton/chunks/{GrSkeleton-URyMkBqI.js → GrSkeleton-B05K0QKh.js} +0 -0
  222. /package/dist/components/GrTabs/chunks/{GrTabs-D3ntDdtg.js → GrTabs-BfeVNMFJ.js} +0 -0
  223. /package/dist/components/GrTree/chunks/{GrTree-B2SMU5Py.js → GrTree-uZr5SyQI.js} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"GrNumberInput-YIWhV85S.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'\nimport { computed, nextTick, onBeforeUnmount, onMounted, onUpdated, 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'\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 controls?: boolean\n controlsDirection?: GrNumberInputControlsDirection\n\n prefixMinWidth?: string\n prefixMaxWidth?: string\n suffixMinWidth?: string\n suffixMaxWidth?: string\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: 'md',\n\n textAlign: 'left',\n\n decimalSeparator: '.',\n step: 1,\n min: undefined,\n max: undefined,\n precision: undefined,\n\n controls: false,\n controlsDirection: 'vertical',\n\n prefixMinWidth: undefined,\n prefixMaxWidth: undefined,\n suffixMinWidth: undefined,\n suffixMaxWidth: undefined,\n\n increaseLabel: 'Increase',\n decreaseLabel: 'Decrease',\n})\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 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[props.size])\nconst addonLen = computed(() => px(addonPx.value))\nconst basePaddingXLen = computed(() => BASE_PADDING_X_LEN_BY_SIZE[props.size])\n\nconst defaultAddonMinWidth = computed(() => addonLen.value)\nconst prefixMinWidth = computed(() => props.prefixMinWidth ?? defaultAddonMinWidth.value)\nconst suffixMinWidth = computed(() => props.suffixMinWidth ?? defaultAddonMinWidth.value)\n\nconst prefixEl = ref<HTMLElement | null>(null)\nconst suffixEl = ref<HTMLElement | null>(null)\n\nconst measuredPrefixWidth = ref<string | undefined>(undefined)\nconst measuredSuffixWidth = ref<string | undefined>(undefined)\n\nlet ro: ResizeObserver | null = null\nlet scheduled = false\n\nfunction readWidthPx(el: HTMLElement | null): string | undefined {\n if (!el) return undefined\n\n const width = Math.ceil(el.getBoundingClientRect().width || 0)\n if (width <= 0) return undefined\n\n return `${width}px`\n}\n\nfunction measure(): void {\n measuredPrefixWidth.value = hasPrefix.value ? readWidthPx(prefixEl.value) : undefined\n measuredSuffixWidth.value = hasSuffix.value ? readWidthPx(suffixEl.value) : undefined\n}\n\nfunction refreshObserver(): void {\n if (typeof ResizeObserver === 'undefined') return\n if (!ro) ro = new ResizeObserver(() => measure())\n\n ro.disconnect()\n if (prefixEl.value) ro.observe(prefixEl.value)\n if (suffixEl.value) ro.observe(suffixEl.value)\n}\n\nfunction scheduleMeasure(): void {\n if (scheduled) return\n scheduled = true\n\n void nextTick(() => {\n scheduled = false\n measure()\n refreshObserver()\n })\n}\n\nonMounted(() => scheduleMeasure())\nonUpdated(() => scheduleMeasure())\nonBeforeUnmount(() => ro?.disconnect())\n\nfunction addLen(a: string, b: string): string {\n if (a === '0px') return b\n if (b === '0px') return a\n\n const apx = a.endsWith('px') ? Number(a.slice(0, -2)) : null\n const bpx = b.endsWith('px') ? Number(b.slice(0, -2)) : null\n\n if (apx !== null && Number.isFinite(apx) && bpx !== null && Number.isFinite(bpx))\n return `${apx + bpx}px`\n\n return `calc(${a} + ${b})`\n}\n\nconst prefixLen = computed(() => (hasPrefix.value ? measuredPrefixWidth.value ?? prefixMinWidth.value : '0px'))\nconst suffixLen = computed(() => (hasSuffix.value ? measuredSuffixWidth.value ?? suffixMinWidth.value : '0px'))\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 return {\n right: '0px',\n minWidth: suffixMinWidth.value,\n maxWidth: props.suffixMaxWidth,\n }\n})\n\nconst prefixStyle = computed(() => {\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: props.size,\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 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 let s = p === undefined ? String(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 next = sanitize(el.value)\n if (el.value !== next) el.value = next\n emit('update:modelValue', next)\n}\n\nfunction onChange(e: Event): void {\n const el = e.target as HTMLInputElement\n const next = sanitize(el.value)\n if (el.value !== next) el.value = next\n emit('change', next)\n}\n\nfunction stepBy(dir: 1 | -1): void {\n if (props.disabled) return\n\n const current = toNumber(props.modelValue) ?? 0\n const next = clamp(normalize(current + (props.step ?? 1) * dir))\n const nextStr = format(next)\n\n emit('update:modelValue', nextStr)\n emit('change', nextStr)\n focus()\n}\n</script>\n\n<template>\n <div\n data-ds-number-input\n class=\"relative w-full overflow-hidden rounded-md border bg-[var(--bg)] transition-colors duration-150 focus-within:ring-2 focus-within:ring-[var(--ring)]\"\n :class=\"shellClassName\"\n >\n <div\n v-if=\"$slots.prefix\"\n ref=\"prefixEl\"\n data-testid=\"number-input-prefix\"\n data-ds-number-input-prefix\n class=\"absolute inset-y-0 left-0 flex items-center justify-center border-r border-[var(--brd)] px-2 text-[var(--muted-fg)] pointer-events-none select-none truncate\"\n :style=\"prefixStyle\"\n aria-hidden=\"true\"\n >\n <slot name=\"prefix\" />\n </div>\n\n <input\n :id=\"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=\"modelValue\"\n :aria-invalid=\"invalid ? 'true' : undefined\"\n class=\"w-full bg-transparent text-[var(--fg)] placeholder:text-[var(--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 >\n\n <div\n v-if=\"$slots.suffix\"\n ref=\"suffixEl\"\n data-testid=\"number-input-suffix\"\n data-ds-number-input-suffix\n class=\"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\"\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-ds-number-input-controls=\"vertical\"\n class=\"absolute inset-y-0 flex items-center justify-center border-l border-[var(--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(--muted-fg)] hover:bg-[var(--muted)] active:bg-[var(--muted)] disabled:opacity-50 disabled:cursor-not-allowed\"\n :disabled=\"disabled\"\n :aria-label=\"increaseLabel\"\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(--muted-fg)] hover:bg-[var(--muted)] active:bg-[var(--muted)] disabled:opacity-50 disabled:cursor-not-allowed\"\n :disabled=\"disabled\"\n :aria-label=\"decreaseLabel\"\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-ds-number-input-controls=\"horizontal-left\"\n class=\"absolute inset-y-0 flex items-stretch justify-center border-r border-[var(--brd)]\"\n :style=\"horizontalLeftControlsStyle\"\n >\n <button\n type=\"button\"\n 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)]\"\n :disabled=\"disabled\"\n :aria-label=\"decreaseLabel\"\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-ds-number-input-controls=\"horizontal-right\"\n class=\"absolute inset-y-0 flex items-stretch justify-center border-l border-[var(--brd)]\"\n :style=\"horizontalRightControlsStyle\"\n >\n <button\n type=\"button\"\n 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)]\"\n :disabled=\"disabled\"\n :aria-label=\"increaseLabel\"\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'\nimport { computed, nextTick, onBeforeUnmount, onMounted, onUpdated, 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'\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 controls?: boolean\n controlsDirection?: GrNumberInputControlsDirection\n\n prefixMinWidth?: string\n prefixMaxWidth?: string\n suffixMinWidth?: string\n suffixMaxWidth?: string\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: 'md',\n\n textAlign: 'left',\n\n decimalSeparator: '.',\n step: 1,\n min: undefined,\n max: undefined,\n precision: undefined,\n\n controls: false,\n controlsDirection: 'vertical',\n\n prefixMinWidth: undefined,\n prefixMaxWidth: undefined,\n suffixMinWidth: undefined,\n suffixMaxWidth: undefined,\n\n increaseLabel: 'Increase',\n decreaseLabel: 'Decrease',\n})\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 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[props.size])\nconst addonLen = computed(() => px(addonPx.value))\nconst basePaddingXLen = computed(() => BASE_PADDING_X_LEN_BY_SIZE[props.size])\n\nconst defaultAddonMinWidth = computed(() => addonLen.value)\nconst prefixMinWidth = computed(() => props.prefixMinWidth ?? defaultAddonMinWidth.value)\nconst suffixMinWidth = computed(() => props.suffixMinWidth ?? defaultAddonMinWidth.value)\n\nconst prefixEl = ref<HTMLElement | null>(null)\nconst suffixEl = ref<HTMLElement | null>(null)\n\nconst measuredPrefixWidth = ref<string | undefined>(undefined)\nconst measuredSuffixWidth = ref<string | undefined>(undefined)\n\nlet ro: ResizeObserver | null = null\nlet scheduled = false\n\nfunction readWidthPx(el: HTMLElement | null): string | undefined {\n if (!el) return undefined\n\n const width = Math.ceil(el.getBoundingClientRect().width || 0)\n if (width <= 0) return undefined\n\n return `${width}px`\n}\n\nfunction measure(): void {\n measuredPrefixWidth.value = hasPrefix.value ? readWidthPx(prefixEl.value) : undefined\n measuredSuffixWidth.value = hasSuffix.value ? readWidthPx(suffixEl.value) : undefined\n}\n\nfunction refreshObserver(): void {\n if (typeof ResizeObserver === 'undefined') return\n if (!ro) ro = new ResizeObserver(() => measure())\n\n ro.disconnect()\n if (prefixEl.value) ro.observe(prefixEl.value)\n if (suffixEl.value) ro.observe(suffixEl.value)\n}\n\nfunction scheduleMeasure(): void {\n if (scheduled) return\n scheduled = true\n\n void nextTick(() => {\n scheduled = false\n measure()\n refreshObserver()\n })\n}\n\nonMounted(() => scheduleMeasure())\nonUpdated(() => scheduleMeasure())\nonBeforeUnmount(() => ro?.disconnect())\n\nfunction addLen(a: string, b: string): string {\n if (a === '0px') return b\n if (b === '0px') return a\n\n const apx = a.endsWith('px') ? Number(a.slice(0, -2)) : null\n const bpx = b.endsWith('px') ? Number(b.slice(0, -2)) : null\n\n if (apx !== null && Number.isFinite(apx) && bpx !== null && Number.isFinite(bpx))\n return `${apx + bpx}px`\n\n return `calc(${a} + ${b})`\n}\n\nconst prefixLen = computed(() => (hasPrefix.value ? measuredPrefixWidth.value ?? prefixMinWidth.value : '0px'))\nconst suffixLen = computed(() => (hasSuffix.value ? measuredSuffixWidth.value ?? suffixMinWidth.value : '0px'))\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 return {\n right: '0px',\n minWidth: suffixMinWidth.value,\n maxWidth: props.suffixMaxWidth,\n }\n})\n\nconst prefixStyle = computed(() => {\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: props.size,\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 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 let s = p === undefined ? String(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 next = sanitize(el.value)\n if (el.value !== next) el.value = next\n emit('update:modelValue', next)\n}\n\nfunction onChange(e: Event): void {\n const el = e.target as HTMLInputElement\n const next = sanitize(el.value)\n if (el.value !== next) el.value = next\n emit('change', next)\n}\n\nfunction stepBy(dir: 1 | -1): void {\n if (props.disabled) return\n\n const current = toNumber(props.modelValue) ?? 0\n const next = clamp(normalize(current + (props.step ?? 1) * dir))\n const nextStr = format(next)\n\n emit('update:modelValue', nextStr)\n emit('change', nextStr)\n focus()\n}\n</script>\n\n<template>\n <div\n data-ds-number-input\n class=\"relative w-full overflow-hidden rounded-md border bg-[var(--bg)] transition-colors duration-150 focus-within:ring-2 focus-within:ring-[var(--ring)]\"\n :class=\"shellClassName\"\n >\n <div\n v-if=\"$slots.prefix\"\n ref=\"prefixEl\"\n data-testid=\"number-input-prefix\"\n data-ds-number-input-prefix\n class=\"absolute inset-y-0 left-0 flex items-center justify-center border-r border-[var(--brd)] px-2 text-[var(--muted-fg)] pointer-events-none select-none truncate\"\n :style=\"prefixStyle\"\n aria-hidden=\"true\"\n >\n <slot name=\"prefix\" />\n </div>\n\n <input\n :id=\"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=\"modelValue\"\n :aria-invalid=\"invalid ? 'true' : undefined\"\n class=\"w-full bg-transparent text-[var(--fg)] placeholder:text-[var(--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 >\n\n <div\n v-if=\"$slots.suffix\"\n ref=\"suffixEl\"\n data-testid=\"number-input-suffix\"\n data-ds-number-input-suffix\n class=\"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\"\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-ds-number-input-controls=\"vertical\"\n class=\"absolute inset-y-0 flex items-center justify-center border-l border-[var(--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(--muted-fg)] hover:bg-[var(--muted)] active:bg-[var(--muted)] disabled:opacity-50 disabled:cursor-not-allowed\"\n :disabled=\"disabled\"\n :aria-label=\"increaseLabel\"\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(--muted-fg)] hover:bg-[var(--muted)] active:bg-[var(--muted)] disabled:opacity-50 disabled:cursor-not-allowed\"\n :disabled=\"disabled\"\n :aria-label=\"decreaseLabel\"\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-ds-number-input-controls=\"horizontal-left\"\n class=\"absolute inset-y-0 flex items-stretch justify-center border-r border-[var(--brd)]\"\n :style=\"horizontalLeftControlsStyle\"\n >\n <button\n type=\"button\"\n 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)]\"\n :disabled=\"disabled\"\n :aria-label=\"decreaseLabel\"\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-ds-number-input-controls=\"horizontal-right\"\n class=\"absolute inset-y-0 flex items-stretch justify-center border-l border-[var(--brd)]\"\n :style=\"horizontalRightControlsStyle\"\n >\n <button\n type=\"button\"\n 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)]\"\n :disabled=\"disabled\"\n :aria-label=\"increaseLabel\"\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
+ {"version":3,"file":"GrNumberInput-ClPBwkxx.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'\nimport { computed, nextTick, onBeforeUnmount, onMounted, onUpdated, 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'\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 controls?: boolean\n controlsDirection?: GrNumberInputControlsDirection\n\n prefixMinWidth?: string\n prefixMaxWidth?: string\n suffixMinWidth?: string\n suffixMaxWidth?: string\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: 'md',\n\n textAlign: 'left',\n\n decimalSeparator: '.',\n step: 1,\n min: undefined,\n max: undefined,\n precision: undefined,\n\n controls: false,\n controlsDirection: 'vertical',\n\n prefixMinWidth: undefined,\n prefixMaxWidth: undefined,\n suffixMinWidth: undefined,\n suffixMaxWidth: undefined,\n\n increaseLabel: 'Increase',\n decreaseLabel: 'Decrease',\n})\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 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[props.size])\nconst addonLen = computed(() => px(addonPx.value))\nconst basePaddingXLen = computed(() => BASE_PADDING_X_LEN_BY_SIZE[props.size])\n\nconst defaultAddonMinWidth = computed(() => addonLen.value)\nconst prefixMinWidth = computed(() => props.prefixMinWidth ?? defaultAddonMinWidth.value)\nconst suffixMinWidth = computed(() => props.suffixMinWidth ?? defaultAddonMinWidth.value)\n\nconst prefixEl = ref<HTMLElement | null>(null)\nconst suffixEl = ref<HTMLElement | null>(null)\n\nconst measuredPrefixWidth = ref<string | undefined>(undefined)\nconst measuredSuffixWidth = ref<string | undefined>(undefined)\n\nlet ro: ResizeObserver | null = null\nlet scheduled = false\n\nfunction readWidthPx(el: HTMLElement | null): string | undefined {\n if (!el) return undefined\n\n const width = Math.ceil(el.getBoundingClientRect().width || 0)\n if (width <= 0) return undefined\n\n return `${width}px`\n}\n\nfunction measure(): void {\n measuredPrefixWidth.value = hasPrefix.value ? readWidthPx(prefixEl.value) : undefined\n measuredSuffixWidth.value = hasSuffix.value ? readWidthPx(suffixEl.value) : undefined\n}\n\nfunction refreshObserver(): void {\n if (typeof ResizeObserver === 'undefined') return\n if (!ro) ro = new ResizeObserver(() => measure())\n\n ro.disconnect()\n if (prefixEl.value) ro.observe(prefixEl.value)\n if (suffixEl.value) ro.observe(suffixEl.value)\n}\n\nfunction scheduleMeasure(): void {\n if (scheduled) return\n scheduled = true\n\n void nextTick(() => {\n scheduled = false\n measure()\n refreshObserver()\n })\n}\n\nonMounted(() => scheduleMeasure())\nonUpdated(() => scheduleMeasure())\nonBeforeUnmount(() => ro?.disconnect())\n\nfunction addLen(a: string, b: string): string {\n if (a === '0px') return b\n if (b === '0px') return a\n\n const apx = a.endsWith('px') ? Number(a.slice(0, -2)) : null\n const bpx = b.endsWith('px') ? Number(b.slice(0, -2)) : null\n\n if (apx !== null && Number.isFinite(apx) && bpx !== null && Number.isFinite(bpx))\n return `${apx + bpx}px`\n\n return `calc(${a} + ${b})`\n}\n\nconst prefixLen = computed(() => (hasPrefix.value ? measuredPrefixWidth.value ?? prefixMinWidth.value : '0px'))\nconst suffixLen = computed(() => (hasSuffix.value ? measuredSuffixWidth.value ?? suffixMinWidth.value : '0px'))\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 return {\n right: '0px',\n minWidth: suffixMinWidth.value,\n maxWidth: props.suffixMaxWidth,\n }\n})\n\nconst prefixStyle = computed(() => {\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: props.size,\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 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 let s = p === undefined ? String(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 next = sanitize(el.value)\n if (el.value !== next) el.value = next\n emit('update:modelValue', next)\n}\n\nfunction onChange(e: Event): void {\n const el = e.target as HTMLInputElement\n const next = sanitize(el.value)\n if (el.value !== next) el.value = next\n emit('change', next)\n}\n\nfunction stepBy(dir: 1 | -1): void {\n if (props.disabled) return\n\n const current = toNumber(props.modelValue) ?? 0\n const next = clamp(normalize(current + (props.step ?? 1) * dir))\n const nextStr = format(next)\n\n emit('update:modelValue', nextStr)\n emit('change', nextStr)\n focus()\n}\n</script>\n\n<template>\n <div\n data-ds-number-input\n class=\"relative w-full overflow-hidden rounded-md border bg-[var(--bg)] transition-colors duration-150 focus-within:ring-2 focus-within:ring-[var(--ring)]\"\n :class=\"shellClassName\"\n >\n <div\n v-if=\"$slots.prefix\"\n ref=\"prefixEl\"\n data-testid=\"number-input-prefix\"\n data-ds-number-input-prefix\n class=\"absolute inset-y-0 left-0 flex items-center justify-center border-r border-[var(--brd)] px-2 text-[var(--muted-fg)] pointer-events-none select-none truncate\"\n :style=\"prefixStyle\"\n aria-hidden=\"true\"\n >\n <slot name=\"prefix\" />\n </div>\n\n <input\n :id=\"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=\"modelValue\"\n :aria-invalid=\"invalid ? 'true' : undefined\"\n class=\"w-full bg-transparent text-[var(--fg)] placeholder:text-[var(--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 >\n\n <div\n v-if=\"$slots.suffix\"\n ref=\"suffixEl\"\n data-testid=\"number-input-suffix\"\n data-ds-number-input-suffix\n class=\"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\"\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-ds-number-input-controls=\"vertical\"\n class=\"absolute inset-y-0 flex items-center justify-center border-l border-[var(--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(--muted-fg)] hover:bg-[var(--muted)] active:bg-[var(--muted)] disabled:opacity-50 disabled:cursor-not-allowed\"\n :disabled=\"disabled\"\n :aria-label=\"increaseLabel\"\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(--muted-fg)] hover:bg-[var(--muted)] active:bg-[var(--muted)] disabled:opacity-50 disabled:cursor-not-allowed\"\n :disabled=\"disabled\"\n :aria-label=\"decreaseLabel\"\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-ds-number-input-controls=\"horizontal-left\"\n class=\"absolute inset-y-0 flex items-stretch justify-center border-r border-[var(--brd)]\"\n :style=\"horizontalLeftControlsStyle\"\n >\n <button\n type=\"button\"\n 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)]\"\n :disabled=\"disabled\"\n :aria-label=\"decreaseLabel\"\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-ds-number-input-controls=\"horizontal-right\"\n class=\"absolute inset-y-0 flex items-stretch justify-center border-l border-[var(--brd)]\"\n :style=\"horizontalRightControlsStyle\"\n >\n <button\n type=\"button\"\n 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)]\"\n :disabled=\"disabled\"\n :aria-label=\"increaseLabel\"\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'\nimport { computed, nextTick, onBeforeUnmount, onMounted, onUpdated, 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'\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 controls?: boolean\n controlsDirection?: GrNumberInputControlsDirection\n\n prefixMinWidth?: string\n prefixMaxWidth?: string\n suffixMinWidth?: string\n suffixMaxWidth?: string\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: 'md',\n\n textAlign: 'left',\n\n decimalSeparator: '.',\n step: 1,\n min: undefined,\n max: undefined,\n precision: undefined,\n\n controls: false,\n controlsDirection: 'vertical',\n\n prefixMinWidth: undefined,\n prefixMaxWidth: undefined,\n suffixMinWidth: undefined,\n suffixMaxWidth: undefined,\n\n increaseLabel: 'Increase',\n decreaseLabel: 'Decrease',\n})\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 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[props.size])\nconst addonLen = computed(() => px(addonPx.value))\nconst basePaddingXLen = computed(() => BASE_PADDING_X_LEN_BY_SIZE[props.size])\n\nconst defaultAddonMinWidth = computed(() => addonLen.value)\nconst prefixMinWidth = computed(() => props.prefixMinWidth ?? defaultAddonMinWidth.value)\nconst suffixMinWidth = computed(() => props.suffixMinWidth ?? defaultAddonMinWidth.value)\n\nconst prefixEl = ref<HTMLElement | null>(null)\nconst suffixEl = ref<HTMLElement | null>(null)\n\nconst measuredPrefixWidth = ref<string | undefined>(undefined)\nconst measuredSuffixWidth = ref<string | undefined>(undefined)\n\nlet ro: ResizeObserver | null = null\nlet scheduled = false\n\nfunction readWidthPx(el: HTMLElement | null): string | undefined {\n if (!el) return undefined\n\n const width = Math.ceil(el.getBoundingClientRect().width || 0)\n if (width <= 0) return undefined\n\n return `${width}px`\n}\n\nfunction measure(): void {\n measuredPrefixWidth.value = hasPrefix.value ? readWidthPx(prefixEl.value) : undefined\n measuredSuffixWidth.value = hasSuffix.value ? readWidthPx(suffixEl.value) : undefined\n}\n\nfunction refreshObserver(): void {\n if (typeof ResizeObserver === 'undefined') return\n if (!ro) ro = new ResizeObserver(() => measure())\n\n ro.disconnect()\n if (prefixEl.value) ro.observe(prefixEl.value)\n if (suffixEl.value) ro.observe(suffixEl.value)\n}\n\nfunction scheduleMeasure(): void {\n if (scheduled) return\n scheduled = true\n\n void nextTick(() => {\n scheduled = false\n measure()\n refreshObserver()\n })\n}\n\nonMounted(() => scheduleMeasure())\nonUpdated(() => scheduleMeasure())\nonBeforeUnmount(() => ro?.disconnect())\n\nfunction addLen(a: string, b: string): string {\n if (a === '0px') return b\n if (b === '0px') return a\n\n const apx = a.endsWith('px') ? Number(a.slice(0, -2)) : null\n const bpx = b.endsWith('px') ? Number(b.slice(0, -2)) : null\n\n if (apx !== null && Number.isFinite(apx) && bpx !== null && Number.isFinite(bpx))\n return `${apx + bpx}px`\n\n return `calc(${a} + ${b})`\n}\n\nconst prefixLen = computed(() => (hasPrefix.value ? measuredPrefixWidth.value ?? prefixMinWidth.value : '0px'))\nconst suffixLen = computed(() => (hasSuffix.value ? measuredSuffixWidth.value ?? suffixMinWidth.value : '0px'))\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 return {\n right: '0px',\n minWidth: suffixMinWidth.value,\n maxWidth: props.suffixMaxWidth,\n }\n})\n\nconst prefixStyle = computed(() => {\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: props.size,\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 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 let s = p === undefined ? String(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 next = sanitize(el.value)\n if (el.value !== next) el.value = next\n emit('update:modelValue', next)\n}\n\nfunction onChange(e: Event): void {\n const el = e.target as HTMLInputElement\n const next = sanitize(el.value)\n if (el.value !== next) el.value = next\n emit('change', next)\n}\n\nfunction stepBy(dir: 1 | -1): void {\n if (props.disabled) return\n\n const current = toNumber(props.modelValue) ?? 0\n const next = clamp(normalize(current + (props.step ?? 1) * dir))\n const nextStr = format(next)\n\n emit('update:modelValue', nextStr)\n emit('change', nextStr)\n focus()\n}\n</script>\n\n<template>\n <div\n data-ds-number-input\n class=\"relative w-full overflow-hidden rounded-md border bg-[var(--bg)] transition-colors duration-150 focus-within:ring-2 focus-within:ring-[var(--ring)]\"\n :class=\"shellClassName\"\n >\n <div\n v-if=\"$slots.prefix\"\n ref=\"prefixEl\"\n data-testid=\"number-input-prefix\"\n data-ds-number-input-prefix\n class=\"absolute inset-y-0 left-0 flex items-center justify-center border-r border-[var(--brd)] px-2 text-[var(--muted-fg)] pointer-events-none select-none truncate\"\n :style=\"prefixStyle\"\n aria-hidden=\"true\"\n >\n <slot name=\"prefix\" />\n </div>\n\n <input\n :id=\"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=\"modelValue\"\n :aria-invalid=\"invalid ? 'true' : undefined\"\n class=\"w-full bg-transparent text-[var(--fg)] placeholder:text-[var(--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 >\n\n <div\n v-if=\"$slots.suffix\"\n ref=\"suffixEl\"\n data-testid=\"number-input-suffix\"\n data-ds-number-input-suffix\n class=\"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\"\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-ds-number-input-controls=\"vertical\"\n class=\"absolute inset-y-0 flex items-center justify-center border-l border-[var(--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(--muted-fg)] hover:bg-[var(--muted)] active:bg-[var(--muted)] disabled:opacity-50 disabled:cursor-not-allowed\"\n :disabled=\"disabled\"\n :aria-label=\"increaseLabel\"\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(--muted-fg)] hover:bg-[var(--muted)] active:bg-[var(--muted)] disabled:opacity-50 disabled:cursor-not-allowed\"\n :disabled=\"disabled\"\n :aria-label=\"decreaseLabel\"\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-ds-number-input-controls=\"horizontal-left\"\n class=\"absolute inset-y-0 flex items-stretch justify-center border-r border-[var(--brd)]\"\n :style=\"horizontalLeftControlsStyle\"\n >\n <button\n type=\"button\"\n 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)]\"\n :disabled=\"disabled\"\n :aria-label=\"decreaseLabel\"\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-ds-number-input-controls=\"horizontal-right\"\n class=\"absolute inset-y-0 flex items-stretch justify-center border-l border-[var(--brd)]\"\n :style=\"horizontalRightControlsStyle\"\n >\n <button\n type=\"button\"\n 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)]\"\n :disabled=\"disabled\"\n :aria-label=\"increaseLabel\"\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-CdJpnjDj.js";
2
- import { t as GrNumberInput_default } from "./chunks/GrNumberInput-YIWhV85S.js";
1
+ import { n as grNumberInputSafelist, t as grNumberInputConfig } from "../../chunks/config-DvDNney3.js";
2
+ import { t as GrNumberInput_default } from "./chunks/GrNumberInput-ClPBwkxx.js";
3
3
  export { GrNumberInput_default as GrNumberInput, GrNumberInput_default as default, grNumberInputConfig, grNumberInputSafelist };
@@ -1,6 +1,6 @@
1
1
  import { t as GrButton_default } from "../../GrButton/chunks/GrButton-CPDKonoB.js";
2
- import { t as useGranularityTranslations } from "../../../chunks/granularityI18n-LcJ88Vce.js";
3
- import { t as GrSelect_default } from "../../GrSelect/chunks/GrSelect-CnHdbPlf.js";
2
+ import { t as useGranularityTranslations } from "../../../chunks/granularityI18n-D_7jowK2.js";
3
+ import { t as GrSelect_default } from "../../GrSelect/chunks/GrSelect-DSz7jvUb.js";
4
4
  import { Fragment, computed, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, normalizeClass, openBlock, renderList, toDisplayString, unref, withCtx } from "vue";
5
5
  //#region src/components/GrPagination/GrPagination.vue?vue&type=script&setup=true&lang.ts
6
6
  var _hoisted_1 = ["aria-label"];
@@ -65,7 +65,7 @@ var GrPagination_default = /* @__PURE__ */ defineComponent({
65
65
  class: "flex flex-wrap items-center justify-end gap-3",
66
66
  "data-ds-pagination": "",
67
67
  role: "navigation",
68
- "aria-label": unref(t)("gr.pagination.pageSize", "Pagination")
68
+ "aria-label": unref(t)("gr.pagination.label", "Pagination")
69
69
  }, [
70
70
  createElementVNode("div", _hoisted_2, [createVNode(GrSelect_default, {
71
71
  modelValue: pageSizeModel.value,
@@ -92,7 +92,7 @@ var GrPagination_default = /* @__PURE__ */ defineComponent({
92
92
  type: "button",
93
93
  "data-ds-pagination-page": "",
94
94
  "aria-current": pageNumber === __props.page ? "page" : void 0,
95
- "aria-label": `Page ${pageNumber}`,
95
+ "aria-label": unref(t)("gr.pagination.page", "Page {n}", { n: pageNumber }),
96
96
  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)]", pageNumber === __props.page ? "bg-[var(--primary)] text-[var(--primary-fg)]" : "text-[var(--muted-fg)] hover:bg-[var(--muted)] hover:text-[var(--fg)]"]),
97
97
  onClick: ($event) => goTo(pageNumber)
98
98
  }, toDisplayString(pageNumber), 11, _hoisted_4);
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GrPagination-D2GS0ShQ.js","names":[],"sources":["../../../../src/components/GrPagination/GrPagination.vue","../../../../src/components/GrPagination/GrPagination.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } 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`. Окно отображаемых номеров — 5.\n */\nexport interface GrPaginationProps {\n page: number\n pageSize: number\n total: number\n pageSizes?: number[]\n}\n\nconst { t } = useGranularityTranslations()\n\nconst props = withDefaults(defineProps<GrPaginationProps>(), {\n pageSizes: () => [10, 20, 50],\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\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\nconst pages = computed(() => {\n const max = pageCount.value\n const current = props.page\n const windowSize = 5\n const half = Math.floor(windowSize / 2)\n\n let start = Math.max(1, current - half)\n const end = Math.min(max, start + windowSize - 1)\n start = Math.max(1, end - windowSize + 1)\n\n const list: number[] = []\n for (let page = start; page <= end; page += 1)\n list.push(page)\n\n return list\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</script>\n\n<template>\n <div\n class=\"flex flex-wrap items-center justify-end gap-3\"\n data-ds-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\" @click=\"prev\">\n {{ t('gr.pagination.prev', 'Prev') }}\n </GrButton>\n\n <div class=\"flex items-center gap-1\">\n <button\n v-for=\"pageNumber in pages\"\n :key=\"pageNumber\"\n type=\"button\"\n data-ds-pagination-page\n :aria-current=\"pageNumber === page ? 'page' : undefined\"\n :aria-label=\"t('gr.pagination.page', 'Page {n}', { n: pageNumber })\"\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(--ring)]\"\n :class=\"pageNumber === page ? 'bg-[var(--primary)] text-[var(--primary-fg)]' : 'text-[var(--muted-fg)] hover:bg-[var(--muted)] hover:text-[var(--fg)]'\"\n @click=\"goTo(pageNumber)\"\n >\n {{ pageNumber }}\n </button>\n </div>\n\n <GrButton variant=\"ghost\" size=\"sm\" :disabled=\"page >= pageCount\" @click=\"next\">\n {{ t('gr.pagination.next', 'Next') }}\n </GrButton>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } 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`. Окно отображаемых номеров — 5.\n */\nexport interface GrPaginationProps {\n page: number\n pageSize: number\n total: number\n pageSizes?: number[]\n}\n\nconst { t } = useGranularityTranslations()\n\nconst props = withDefaults(defineProps<GrPaginationProps>(), {\n pageSizes: () => [10, 20, 50],\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\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\nconst pages = computed(() => {\n const max = pageCount.value\n const current = props.page\n const windowSize = 5\n const half = Math.floor(windowSize / 2)\n\n let start = Math.max(1, current - half)\n const end = Math.min(max, start + windowSize - 1)\n start = Math.max(1, end - windowSize + 1)\n\n const list: number[] = []\n for (let page = start; page <= end; page += 1)\n list.push(page)\n\n return list\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</script>\n\n<template>\n <div\n class=\"flex flex-wrap items-center justify-end gap-3\"\n data-ds-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\" @click=\"prev\">\n {{ t('gr.pagination.prev', 'Prev') }}\n </GrButton>\n\n <div class=\"flex items-center gap-1\">\n <button\n v-for=\"pageNumber in pages\"\n :key=\"pageNumber\"\n type=\"button\"\n data-ds-pagination-page\n :aria-current=\"pageNumber === page ? 'page' : undefined\"\n :aria-label=\"t('gr.pagination.page', 'Page {n}', { n: pageNumber })\"\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(--ring)]\"\n :class=\"pageNumber === page ? 'bg-[var(--primary)] text-[var(--primary-fg)]' : 'text-[var(--muted-fg)] hover:bg-[var(--muted)] hover:text-[var(--fg)]'\"\n @click=\"goTo(pageNumber)\"\n >\n {{ pageNumber }}\n </button>\n </div>\n\n <GrButton variant=\"ghost\" size=\"sm\" :disabled=\"page >= pageCount\" @click=\"next\">\n {{ t('gr.pagination.next', 'Next') }}\n </GrButton>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoBA,MAAM,EAAE,MAAM,4BAA2B;EAEzC,MAAM,QAAQ;EAId,MAAM,OAAO;EAKb,MAAM,YAAY,eAAe,KAAK,IAAI,GAAG,KAAK,KAAK,MAAM,QAAQ,MAAM,SAAS,CAAC,CAAA;EAErF,MAAM,gBAAgB,SAAS;GAC7B,WAAW,OAAO,MAAM,SAAS;GACjC,MAAM,UAAkB,KAAK,mBAAmB,OAAO,MAAM,CAAC;GAC/D,CAAA;EAED,MAAM,kBAAkB,eACtB,MAAM,UAAU,KAAI,cAAa;GAC/B,OAAO,OAAO,SAAS;GACvB,OAAO,OAAO,SAAS;GACxB,EAAE,CACL;EAEA,MAAM,QAAQ,eAAe;GAC3B,MAAM,MAAM,UAAU;GACtB,MAAM,UAAU,MAAM;GACtB,MAAM,aAAa;GACnB,MAAM,OAAO,KAAK,MAAM,aAAa,EAAC;GAEtC,IAAI,QAAQ,KAAK,IAAI,GAAG,UAAU,KAAI;GACtC,MAAM,MAAM,KAAK,IAAI,KAAK,QAAQ,aAAa,EAAC;AAChD,WAAQ,KAAK,IAAI,GAAG,MAAM,aAAa,EAAC;GAExC,MAAM,OAAiB,EAAC;AACxB,QAAK,IAAI,OAAO,OAAO,QAAQ,KAAK,QAAQ,EAC1C,MAAK,KAAK,KAAI;AAEhB,UAAO;IACR;EAED,SAAS,KAAK,MAAoB;AAChC,QAAK,eAAe,KAAI;;EAG1B,SAAS,OAAa;AACpB,QAAK,KAAK,IAAI,GAAG,MAAM,OAAO,EAAE,CAAA;;EAGlC,SAAS,OAAa;AACpB,QAAK,KAAK,IAAI,UAAU,OAAO,MAAM,OAAO,EAAE,CAAA;;;uBAK9C,mBAqCM,OAAA;IApCJ,OAAM;IACN,sBAAA;IACA,MAAK;IACJ,cAAY,MAAA,EAAC,CAAA,uBAAA,aAAA;;IAEd,mBAMM,OANN,YAMM,CALJ,YAIE,kBAAA;iBAHS,cAAA;gFAAa,QAAA;KACrB,SAAS,gBAAA;KACT,cAAY,MAAA,EAAC,CAAA,0BAAA,YAAA;;;;;;IAIlB,YAEW,kBAAA;KAFD,SAAQ;KAAQ,MAAK;KAAM,UAAU,QAAA,QAAI;KAAQ,SAAO;;4BAC3B,CAAA,gBAAA,gBAAlC,MAAA,EAAC,CAAA,sBAAA,OAAA,CAAA,EAAA,EAAA,CAAA,CAAA;;;IAGN,mBAcM,OAdN,YAcM,EAAA,UAAA,KAAA,EAbJ,mBAYS,UAAA,MAAA,WAXc,MAAA,QAAd,eAAU;yBADnB,mBAYS,UAAA;MAVN,KAAK;MACN,MAAK;MACL,2BAAA;MACC,gBAAc,eAAe,QAAA,OAAI,SAAY,KAAA;MAC7C,cAAY,MAAA,EAAC,CAAA,sBAAA,YAAA,EAAA,GAAwC,YAAU,CAAA;MAChE,OAAK,eAAA,CAAC,wJACE,eAAe,QAAA,OAAI,iDAAA,wEAAA,CAAA;MAC1B,UAAK,WAAE,KAAK,WAAU;wBAEpB,WAAU,EAAA,IAAA,WAAA;;IAIjB,YAEW,kBAAA;KAFD,SAAQ;KAAQ,MAAK;KAAM,UAAU,QAAA,QAAQ,UAAA;KAAY,SAAO;;4BACnC,CAAA,gBAAA,gBAAlC,MAAA,EAAC,CAAA,sBAAA,OAAA,CAAA,EAAA,EAAA,CAAA,CAAA"}
@@ -1,3 +1,3 @@
1
- import { t as GrPagination_default } from "./chunks/GrPagination-BNDEqM8_.js";
2
- import { t as grPaginationConfig } from "../../chunks/config-iuMz79Mg.js";
1
+ import { t as GrPagination_default } from "./chunks/GrPagination-D2GS0ShQ.js";
2
+ import { t as grPaginationConfig } from "../../chunks/config-CWTfyPNI.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-CUaTmpyW.js";
1
+ import { t as grProgressBarFillClass } from "../../../chunks/grStyle-D-gPHdyW.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"];
@@ -1 +1 @@
1
- {"version":3,"file":"GrProgressBar-C2HdYjp4.js","names":[],"sources":["../../../../src/components/GrProgressBar/GrProgressBar.vue","../../../../src/components/GrProgressBar/GrProgressBar.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport { grProgressBarFillClass, type GrProgressBarTone } from './grStyle'\n\n/**\n * GrProgressBar — линейный индикатор прогресса.\n *\n * @prop value — текущее значение `0..100`; выходящие за границы значения клампятся, `NaN` → `0`.\n * @prop ariaLabel — метка для скринридера (обязательна, если рядом нет видимого заголовка).\n * @prop tone — цветовая тональность заливки (CSS-переменная из `tokens.css`).\n */\nexport interface GrProgressBarProps {\n value: number\n ariaLabel?: string\n tone?: GrProgressBarTone\n}\n\nconst props = withDefaults(defineProps<GrProgressBarProps>(), {\n ariaLabel: undefined,\n tone: 'primary',\n})\n\nconst safe = computed(() => {\n if (Number.isNaN(props.value))\n return 0\n return Math.min(100, Math.max(0, props.value))\n})\n\nconst fillClassName = computed(() => grProgressBarFillClass(props.tone))\n</script>\n\n<template>\n <div\n data-ds-progress-bar\n role=\"progressbar\"\n :aria-label=\"ariaLabel\"\n :aria-valuenow=\"safe\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n class=\"h-2 w-full rounded-full bg-[var(--muted)] border border-[var(--brd)] overflow-hidden\"\n >\n <div\n data-ds-progress-bar-fill\n class=\"h-full\"\n :class=\"fillClassName\"\n :style=\"{ width: `${safe}%` }\"\n />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport { grProgressBarFillClass, type GrProgressBarTone } from './grStyle'\n\n/**\n * GrProgressBar — линейный индикатор прогресса.\n *\n * @prop value — текущее значение `0..100`; выходящие за границы значения клампятся, `NaN` → `0`.\n * @prop ariaLabel — метка для скринридера (обязательна, если рядом нет видимого заголовка).\n * @prop tone — цветовая тональность заливки (CSS-переменная из `tokens.css`).\n */\nexport interface GrProgressBarProps {\n value: number\n ariaLabel?: string\n tone?: GrProgressBarTone\n}\n\nconst props = withDefaults(defineProps<GrProgressBarProps>(), {\n ariaLabel: undefined,\n tone: 'primary',\n})\n\nconst safe = computed(() => {\n if (Number.isNaN(props.value))\n return 0\n return Math.min(100, Math.max(0, props.value))\n})\n\nconst fillClassName = computed(() => grProgressBarFillClass(props.tone))\n</script>\n\n<template>\n <div\n data-ds-progress-bar\n role=\"progressbar\"\n :aria-label=\"ariaLabel\"\n :aria-valuenow=\"safe\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n class=\"h-2 w-full rounded-full bg-[var(--muted)] border border-[var(--brd)] overflow-hidden\"\n >\n <div\n data-ds-progress-bar-fill\n class=\"h-full\"\n :class=\"fillClassName\"\n :style=\"{ width: `${safe}%` }\"\n />\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;EAkBA,MAAM,QAAQ;EAKd,MAAM,OAAO,eAAe;AAC1B,OAAI,OAAO,MAAM,MAAM,MAAM,CAC3B,QAAO;AACT,UAAO,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG,MAAM,MAAM,CAAA;IAC9C;EAED,MAAM,gBAAgB,eAAe,uBAAuB,MAAM,KAAK,CAAA;;uBAIrE,mBAeM,OAAA;IAdJ,wBAAA;IACA,MAAK;IACJ,cAAY,QAAA;IACZ,iBAAe,KAAA;IAChB,iBAAc;IACd,iBAAc;IACd,OAAM;OAEN,mBAKE,OAAA;IAJA,6BAAA;IACA,OAAK,eAAA,CAAC,UACE,cAAA,MAAa,CAAA;IACpB,OAAK,eAAA,EAAA,OAAA,GAAc,KAAA,MAAI,IAAA,CAAA"}
1
+ {"version":3,"file":"GrProgressBar-BBSFpVEq.js","names":[],"sources":["../../../../src/components/GrProgressBar/GrProgressBar.vue","../../../../src/components/GrProgressBar/GrProgressBar.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport { grProgressBarFillClass, type GrProgressBarTone } from './grStyle'\n\n/**\n * GrProgressBar — линейный индикатор прогресса.\n *\n * @prop value — текущее значение `0..100`; выходящие за границы значения клампятся, `NaN` → `0`.\n * @prop ariaLabel — метка для скринридера (обязательна, если рядом нет видимого заголовка).\n * @prop tone — цветовая тональность заливки (CSS-переменная из `tokens.css`).\n */\nexport interface GrProgressBarProps {\n value: number\n ariaLabel?: string\n tone?: GrProgressBarTone\n}\n\nconst props = withDefaults(defineProps<GrProgressBarProps>(), {\n ariaLabel: undefined,\n tone: 'primary',\n})\n\nconst safe = computed(() => {\n if (Number.isNaN(props.value))\n return 0\n return Math.min(100, Math.max(0, props.value))\n})\n\nconst fillClassName = computed(() => grProgressBarFillClass(props.tone))\n</script>\n\n<template>\n <div\n data-ds-progress-bar\n role=\"progressbar\"\n :aria-label=\"ariaLabel\"\n :aria-valuenow=\"safe\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n class=\"h-2 w-full rounded-full bg-[var(--muted)] border border-[var(--brd)] overflow-hidden\"\n >\n <div\n data-ds-progress-bar-fill\n class=\"h-full\"\n :class=\"fillClassName\"\n :style=\"{ width: `${safe}%` }\"\n />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport { grProgressBarFillClass, type GrProgressBarTone } from './grStyle'\n\n/**\n * GrProgressBar — линейный индикатор прогресса.\n *\n * @prop value — текущее значение `0..100`; выходящие за границы значения клампятся, `NaN` → `0`.\n * @prop ariaLabel — метка для скринридера (обязательна, если рядом нет видимого заголовка).\n * @prop tone — цветовая тональность заливки (CSS-переменная из `tokens.css`).\n */\nexport interface GrProgressBarProps {\n value: number\n ariaLabel?: string\n tone?: GrProgressBarTone\n}\n\nconst props = withDefaults(defineProps<GrProgressBarProps>(), {\n ariaLabel: undefined,\n tone: 'primary',\n})\n\nconst safe = computed(() => {\n if (Number.isNaN(props.value))\n return 0\n return Math.min(100, Math.max(0, props.value))\n})\n\nconst fillClassName = computed(() => grProgressBarFillClass(props.tone))\n</script>\n\n<template>\n <div\n data-ds-progress-bar\n role=\"progressbar\"\n :aria-label=\"ariaLabel\"\n :aria-valuenow=\"safe\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n class=\"h-2 w-full rounded-full bg-[var(--muted)] border border-[var(--brd)] overflow-hidden\"\n >\n <div\n data-ds-progress-bar-fill\n class=\"h-full\"\n :class=\"fillClassName\"\n :style=\"{ width: `${safe}%` }\"\n />\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;EAkBA,MAAM,QAAQ;EAKd,MAAM,OAAO,eAAe;AAC1B,OAAI,OAAO,MAAM,MAAM,MAAM,CAC3B,QAAO;AACT,UAAO,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG,MAAM,MAAM,CAAA;IAC9C;EAED,MAAM,gBAAgB,eAAe,uBAAuB,MAAM,KAAK,CAAA;;uBAIrE,mBAeM,OAAA;IAdJ,wBAAA;IACA,MAAK;IACJ,cAAY,QAAA;IACZ,iBAAe,KAAA;IAChB,iBAAc;IACd,iBAAc;IACd,OAAM;OAEN,mBAKE,OAAA;IAJA,6BAAA;IACA,OAAK,eAAA,CAAC,UACE,cAAA,MAAa,CAAA;IACpB,OAAK,eAAA,EAAA,OAAA,GAAc,KAAA,MAAI,IAAA,CAAA"}
@@ -1,3 +1,3 @@
1
- import { t as GrProgressBar_default } from "./chunks/GrProgressBar-C2HdYjp4.js";
2
- import { n as grProgressBarSafelist, t as grProgressBarConfig } from "../../chunks/config-CFf7xaG1.js";
1
+ import { t as GrProgressBar_default } from "./chunks/GrProgressBar-BBSFpVEq.js";
2
+ import { n as grProgressBarSafelist, t as grProgressBarConfig } from "../../chunks/config-B0uUCaJW.js";
3
3
  export { GrProgressBar_default as GrProgressBar, GrProgressBar_default as default, grProgressBarConfig, grProgressBarSafelist };
@@ -1,6 +1,6 @@
1
1
  import { t as GrButton_default } from "../../GrButton/chunks/GrButton-CPDKonoB.js";
2
- import { t as GrDialog_default } from "../../GrDialog/chunks/GrDialog-C7XLxp8e.js";
3
- import { t as GrResponseErrorBanner_default } from "../../GrResponseErrorBanner/chunks/GrResponseErrorBanner-CzdTh4gd.js";
2
+ import { t as GrDialog_default } from "../../GrDialog/chunks/GrDialog-CxK4Lj4F.js";
3
+ import { t as GrResponseErrorBanner_default } from "../../GrResponseErrorBanner/chunks/GrResponseErrorBanner-bM8FC_Bw.js";
4
4
  import { t as GrFormField_default } from "../../GrFormField/chunks/GrFormField-U7c_aDPJ.js";
5
5
  import { t as GrInput_default } from "../../GrInput/chunks/GrInput-gwFQ1sk4.js";
6
6
  import { computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, openBlock, ref, renderSlot, toDisplayString, watch, withCtx } from "vue";
@@ -1 +1 @@
1
- {"version":3,"file":"GrPromptDialog-BV4EW3XO.js","names":[],"sources":["../../../../src/components/GrPromptDialog/GrPromptDialog.vue","../../../../src/components/GrPromptDialog/GrPromptDialog.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * GrPromptDialog — DS-примитив диалога ввода значения поверх `GrDialog`.\n *\n * Синхронизирован с `GrDialog` по набору проп-проксирования:\n * `size`, `closeOnBackdrop`, `closeOnEsc`, `showHeader`, `showCloseButton`,\n * `headerConfig`, `footerConfig`, `bodyConfig`, `closeLabel`.\n *\n * Поведение `required=true` (по умолчанию): пустое значение подсвечивается\n * ошибкой только после первого «касания» (blur или попытка confirm),\n * чтобы не шуметь при открытии.\n */\nimport { computed, ref, watch } from 'vue'\n\nimport GrButton from '../GrButton/GrButton.vue'\nimport GrDialog from '../GrDialog/GrDialog.vue'\nimport GrFormField from '../GrFormField/GrFormField.vue'\nimport GrInput from '../GrInput/GrInput.vue'\nimport GrResponseErrorBanner from '../GrResponseErrorBanner/GrResponseErrorBanner.vue'\nimport type { GrButtonSize, GrButtonTone, GrButtonVariant } from '../GrButton'\nimport type { GrDialogSectionConfig, GrDialogSize } from '../GrDialog'\nimport type { ResponseErrorInfo } from '../GrResponseErrorBanner'\n\nexport interface GrPromptDialogProps {\n modelValue: boolean\n value: string\n title?: string\n description?: string\n label?: string\n placeholder?: string\n closeOnBackdrop?: boolean\n closeOnEsc?: boolean\n showHeader?: boolean\n showCloseButton?: boolean\n size?: GrDialogSize\n headerConfig?: GrDialogSectionConfig\n footerConfig?: GrDialogSectionConfig\n bodyConfig?: GrDialogSectionConfig\n /** A11y-лейбл кнопки закрытия (i18n). */\n closeLabel?: string\n buttonSize?: GrButtonSize\n confirmText?: string\n cancelText?: string\n /** Текст ошибки для пустого значения при `required=true` (i18n). */\n requiredErrorText?: string\n confirmVariant?: GrButtonVariant\n confirmTone?: GrButtonTone\n required?: boolean\n /**\n * Структура ошибки ответа сервера для показа общим блоком в теле диалога\n * (через `GrResponseErrorBanner`). `null` — блок скрыт.\n */\n error?: ResponseErrorInfo | null\n /**\n * Внешняя ошибка поля ввода (например, серверная валидация). Имеет приоритет\n * над встроенной проверкой `required`. `null`/`undefined` — нет внешней ошибки.\n */\n fieldError?: string | null\n /** Состояние загрузки кнопки Confirm (async-`onConfirm` in-flight). */\n confirmLoading?: boolean\n /** Принудительно дизейблит кнопку Confirm. */\n confirmDisabled?: boolean\n /**\n * Закрывать ли диалог автоматически по клику Confirm. По умолчанию `true`.\n * `false` — отдаёт управление закрытием наружу (нужно `useDialogService`).\n */\n closeOnConfirm?: boolean\n}\n\nconst props = withDefaults(defineProps<GrPromptDialogProps>(), {\n title: 'Prompt',\n description: undefined,\n label: 'Value',\n placeholder: undefined,\n closeOnBackdrop: true,\n closeOnEsc: true,\n showHeader: true,\n showCloseButton: true,\n size: 'md',\n headerConfig: undefined,\n footerConfig: undefined,\n bodyConfig: undefined,\n closeLabel: 'Close',\n buttonSize: undefined,\n confirmText: 'Confirm',\n cancelText: 'Cancel',\n requiredErrorText: 'Enter a value.',\n confirmVariant: 'primary',\n confirmTone: 'primary',\n required: true,\n error: null,\n fieldError: null,\n confirmLoading: false,\n confirmDisabled: false,\n closeOnConfirm: true,\n})\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: boolean): void\n (e: 'update:value', value: string): void\n (e: 'confirm', value: string): void\n (e: 'cancel'): void\n}>()\n\nconst open = computed({\n get: () => props.modelValue,\n set: (v: boolean) => emit('update:modelValue', v),\n})\n\nconst valueModel = computed({\n get: () => props.value,\n set: (v: string) => emit('update:value', v),\n})\n\nconst touched = ref(false)\nconst inputRef = ref<InstanceType<typeof GrInput> | null>(null)\n\nwatch(\n () => props.modelValue,\n (v) => {\n if (v) touched.value = false\n },\n)\n\nconst canConfirm = computed(() => {\n if (!props.required) return true\n return valueModel.value.trim().length > 0\n})\n\nconst validationError = computed(() => {\n if (!props.required) return undefined\n if (!touched.value) return undefined\n return valueModel.value.trim().length > 0\n ? undefined\n : props.requiredErrorText\n})\n\n// Внешняя ошибка поля (серверная валидация) имеет приоритет над встроенной.\nconst fieldErrorMessage = computed(() => props.fieldError ?? validationError.value ?? undefined)\n\nfunction onCancel(): void {\n emit('cancel')\n emit('update:modelValue', false)\n}\n\nfunction onConfirm(): void {\n if (!canConfirm.value) {\n touched.value = true\n inputRef.value?.focus()\n return\n }\n\n emit('confirm', valueModel.value)\n if (props.closeOnConfirm)\n emit('update:modelValue', false)\n}\n</script>\n\n<template>\n <GrDialog\n v-model=\"open\"\n :title=\"title\"\n :size=\"size\"\n :close-on-backdrop=\"closeOnBackdrop\"\n :close-on-esc=\"closeOnEsc\"\n :show-header=\"showHeader\"\n :show-close-button=\"showCloseButton\"\n :header-config=\"headerConfig\"\n :footer-config=\"footerConfig\"\n :body-config=\"bodyConfig\"\n :close-label=\"closeLabel\"\n >\n <div class=\"grid gap-4\">\n <slot>\n <div v-if=\"description\" class=\"text-[14px] text-[var(--muted-fg)]\">\n {{ description }}\n </div>\n </slot>\n\n <GrFormField :label=\"label\" :error=\"fieldErrorMessage\" for-id=\"ds-prompt-input\">\n <GrInput\n id=\"ds-prompt-input\"\n ref=\"inputRef\"\n v-model=\"valueModel\"\n data-testid=\"ds-prompt-input\"\n :placeholder=\"placeholder\"\n :invalid=\"!!fieldErrorMessage\"\n @blur=\"touched = true\"\n />\n </GrFormField>\n\n <slot name=\"error\" :error=\"error\">\n <GrResponseErrorBanner v-if=\"error\" :error=\"error\" :can-dismiss=\"false\" />\n </slot>\n </div>\n\n <template #footer>\n <slot name=\"footer\">\n <div class=\"flex items-center justify-end gap-3\">\n <GrButton data-testid=\"ds-prompt-cancel\" variant=\"outline\" :size=\"buttonSize\" @click=\"onCancel\">\n {{ cancelText }}\n </GrButton>\n <GrButton\n data-testid=\"ds-prompt-confirm\"\n :variant=\"confirmVariant\"\n :tone=\"confirmTone\"\n :size=\"buttonSize\"\n :loading=\"confirmLoading\"\n :disabled=\"confirmDisabled || (required && touched && !canConfirm)\"\n @click=\"onConfirm\"\n >\n {{ confirmText }}\n </GrButton>\n </div>\n </slot>\n </template>\n </GrDialog>\n</template>\n","<script setup lang=\"ts\">\n/**\n * GrPromptDialog — DS-примитив диалога ввода значения поверх `GrDialog`.\n *\n * Синхронизирован с `GrDialog` по набору проп-проксирования:\n * `size`, `closeOnBackdrop`, `closeOnEsc`, `showHeader`, `showCloseButton`,\n * `headerConfig`, `footerConfig`, `bodyConfig`, `closeLabel`.\n *\n * Поведение `required=true` (по умолчанию): пустое значение подсвечивается\n * ошибкой только после первого «касания» (blur или попытка confirm),\n * чтобы не шуметь при открытии.\n */\nimport { computed, ref, watch } from 'vue'\n\nimport GrButton from '../GrButton/GrButton.vue'\nimport GrDialog from '../GrDialog/GrDialog.vue'\nimport GrFormField from '../GrFormField/GrFormField.vue'\nimport GrInput from '../GrInput/GrInput.vue'\nimport GrResponseErrorBanner from '../GrResponseErrorBanner/GrResponseErrorBanner.vue'\nimport type { GrButtonSize, GrButtonTone, GrButtonVariant } from '../GrButton'\nimport type { GrDialogSectionConfig, GrDialogSize } from '../GrDialog'\nimport type { ResponseErrorInfo } from '../GrResponseErrorBanner'\n\nexport interface GrPromptDialogProps {\n modelValue: boolean\n value: string\n title?: string\n description?: string\n label?: string\n placeholder?: string\n closeOnBackdrop?: boolean\n closeOnEsc?: boolean\n showHeader?: boolean\n showCloseButton?: boolean\n size?: GrDialogSize\n headerConfig?: GrDialogSectionConfig\n footerConfig?: GrDialogSectionConfig\n bodyConfig?: GrDialogSectionConfig\n /** A11y-лейбл кнопки закрытия (i18n). */\n closeLabel?: string\n buttonSize?: GrButtonSize\n confirmText?: string\n cancelText?: string\n /** Текст ошибки для пустого значения при `required=true` (i18n). */\n requiredErrorText?: string\n confirmVariant?: GrButtonVariant\n confirmTone?: GrButtonTone\n required?: boolean\n /**\n * Структура ошибки ответа сервера для показа общим блоком в теле диалога\n * (через `GrResponseErrorBanner`). `null` — блок скрыт.\n */\n error?: ResponseErrorInfo | null\n /**\n * Внешняя ошибка поля ввода (например, серверная валидация). Имеет приоритет\n * над встроенной проверкой `required`. `null`/`undefined` — нет внешней ошибки.\n */\n fieldError?: string | null\n /** Состояние загрузки кнопки Confirm (async-`onConfirm` in-flight). */\n confirmLoading?: boolean\n /** Принудительно дизейблит кнопку Confirm. */\n confirmDisabled?: boolean\n /**\n * Закрывать ли диалог автоматически по клику Confirm. По умолчанию `true`.\n * `false` — отдаёт управление закрытием наружу (нужно `useDialogService`).\n */\n closeOnConfirm?: boolean\n}\n\nconst props = withDefaults(defineProps<GrPromptDialogProps>(), {\n title: 'Prompt',\n description: undefined,\n label: 'Value',\n placeholder: undefined,\n closeOnBackdrop: true,\n closeOnEsc: true,\n showHeader: true,\n showCloseButton: true,\n size: 'md',\n headerConfig: undefined,\n footerConfig: undefined,\n bodyConfig: undefined,\n closeLabel: 'Close',\n buttonSize: undefined,\n confirmText: 'Confirm',\n cancelText: 'Cancel',\n requiredErrorText: 'Enter a value.',\n confirmVariant: 'primary',\n confirmTone: 'primary',\n required: true,\n error: null,\n fieldError: null,\n confirmLoading: false,\n confirmDisabled: false,\n closeOnConfirm: true,\n})\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: boolean): void\n (e: 'update:value', value: string): void\n (e: 'confirm', value: string): void\n (e: 'cancel'): void\n}>()\n\nconst open = computed({\n get: () => props.modelValue,\n set: (v: boolean) => emit('update:modelValue', v),\n})\n\nconst valueModel = computed({\n get: () => props.value,\n set: (v: string) => emit('update:value', v),\n})\n\nconst touched = ref(false)\nconst inputRef = ref<InstanceType<typeof GrInput> | null>(null)\n\nwatch(\n () => props.modelValue,\n (v) => {\n if (v) touched.value = false\n },\n)\n\nconst canConfirm = computed(() => {\n if (!props.required) return true\n return valueModel.value.trim().length > 0\n})\n\nconst validationError = computed(() => {\n if (!props.required) return undefined\n if (!touched.value) return undefined\n return valueModel.value.trim().length > 0\n ? undefined\n : props.requiredErrorText\n})\n\n// Внешняя ошибка поля (серверная валидация) имеет приоритет над встроенной.\nconst fieldErrorMessage = computed(() => props.fieldError ?? validationError.value ?? undefined)\n\nfunction onCancel(): void {\n emit('cancel')\n emit('update:modelValue', false)\n}\n\nfunction onConfirm(): void {\n if (!canConfirm.value) {\n touched.value = true\n inputRef.value?.focus()\n return\n }\n\n emit('confirm', valueModel.value)\n if (props.closeOnConfirm)\n emit('update:modelValue', false)\n}\n</script>\n\n<template>\n <GrDialog\n v-model=\"open\"\n :title=\"title\"\n :size=\"size\"\n :close-on-backdrop=\"closeOnBackdrop\"\n :close-on-esc=\"closeOnEsc\"\n :show-header=\"showHeader\"\n :show-close-button=\"showCloseButton\"\n :header-config=\"headerConfig\"\n :footer-config=\"footerConfig\"\n :body-config=\"bodyConfig\"\n :close-label=\"closeLabel\"\n >\n <div class=\"grid gap-4\">\n <slot>\n <div v-if=\"description\" class=\"text-[14px] text-[var(--muted-fg)]\">\n {{ description }}\n </div>\n </slot>\n\n <GrFormField :label=\"label\" :error=\"fieldErrorMessage\" for-id=\"ds-prompt-input\">\n <GrInput\n id=\"ds-prompt-input\"\n ref=\"inputRef\"\n v-model=\"valueModel\"\n data-testid=\"ds-prompt-input\"\n :placeholder=\"placeholder\"\n :invalid=\"!!fieldErrorMessage\"\n @blur=\"touched = true\"\n />\n </GrFormField>\n\n <slot name=\"error\" :error=\"error\">\n <GrResponseErrorBanner v-if=\"error\" :error=\"error\" :can-dismiss=\"false\" />\n </slot>\n </div>\n\n <template #footer>\n <slot name=\"footer\">\n <div class=\"flex items-center justify-end gap-3\">\n <GrButton data-testid=\"ds-prompt-cancel\" variant=\"outline\" :size=\"buttonSize\" @click=\"onCancel\">\n {{ cancelText }}\n </GrButton>\n <GrButton\n data-testid=\"ds-prompt-confirm\"\n :variant=\"confirmVariant\"\n :tone=\"confirmTone\"\n :size=\"buttonSize\"\n :loading=\"confirmLoading\"\n :disabled=\"confirmDisabled || (required && touched && !canConfirm)\"\n @click=\"onConfirm\"\n >\n {{ confirmText }}\n </GrButton>\n </div>\n </slot>\n </template>\n </GrDialog>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"GrPromptDialog-D_TFqKsF.js","names":[],"sources":["../../../../src/components/GrPromptDialog/GrPromptDialog.vue","../../../../src/components/GrPromptDialog/GrPromptDialog.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * GrPromptDialog — DS-примитив диалога ввода значения поверх `GrDialog`.\n *\n * Синхронизирован с `GrDialog` по набору проп-проксирования:\n * `size`, `closeOnBackdrop`, `closeOnEsc`, `showHeader`, `showCloseButton`,\n * `headerConfig`, `footerConfig`, `bodyConfig`, `closeLabel`.\n *\n * Поведение `required=true` (по умолчанию): пустое значение подсвечивается\n * ошибкой только после первого «касания» (blur или попытка confirm),\n * чтобы не шуметь при открытии.\n */\nimport { computed, ref, watch } from 'vue'\n\nimport GrButton from '../GrButton/GrButton.vue'\nimport GrDialog from '../GrDialog/GrDialog.vue'\nimport GrFormField from '../GrFormField/GrFormField.vue'\nimport GrInput from '../GrInput/GrInput.vue'\nimport GrResponseErrorBanner from '../GrResponseErrorBanner/GrResponseErrorBanner.vue'\nimport type { GrButtonSize, GrButtonTone, GrButtonVariant } from '../GrButton'\nimport type { GrDialogSectionConfig, GrDialogSize } from '../GrDialog'\nimport type { ResponseErrorInfo } from '../GrResponseErrorBanner'\n\nexport interface GrPromptDialogProps {\n modelValue: boolean\n value: string\n title?: string\n description?: string\n label?: string\n placeholder?: string\n closeOnBackdrop?: boolean\n closeOnEsc?: boolean\n showHeader?: boolean\n showCloseButton?: boolean\n size?: GrDialogSize\n headerConfig?: GrDialogSectionConfig\n footerConfig?: GrDialogSectionConfig\n bodyConfig?: GrDialogSectionConfig\n /** A11y-лейбл кнопки закрытия (i18n). */\n closeLabel?: string\n buttonSize?: GrButtonSize\n confirmText?: string\n cancelText?: string\n /** Текст ошибки для пустого значения при `required=true` (i18n). */\n requiredErrorText?: string\n confirmVariant?: GrButtonVariant\n confirmTone?: GrButtonTone\n required?: boolean\n /**\n * Структура ошибки ответа сервера для показа общим блоком в теле диалога\n * (через `GrResponseErrorBanner`). `null` — блок скрыт.\n */\n error?: ResponseErrorInfo | null\n /**\n * Внешняя ошибка поля ввода (например, серверная валидация). Имеет приоритет\n * над встроенной проверкой `required`. `null`/`undefined` — нет внешней ошибки.\n */\n fieldError?: string | null\n /** Состояние загрузки кнопки Confirm (async-`onConfirm` in-flight). */\n confirmLoading?: boolean\n /** Принудительно дизейблит кнопку Confirm. */\n confirmDisabled?: boolean\n /**\n * Закрывать ли диалог автоматически по клику Confirm. По умолчанию `true`.\n * `false` — отдаёт управление закрытием наружу (нужно `useDialogService`).\n */\n closeOnConfirm?: boolean\n}\n\nconst props = withDefaults(defineProps<GrPromptDialogProps>(), {\n title: 'Prompt',\n description: undefined,\n label: 'Value',\n placeholder: undefined,\n closeOnBackdrop: true,\n closeOnEsc: true,\n showHeader: true,\n showCloseButton: true,\n size: 'md',\n headerConfig: undefined,\n footerConfig: undefined,\n bodyConfig: undefined,\n closeLabel: 'Close',\n buttonSize: undefined,\n confirmText: 'Confirm',\n cancelText: 'Cancel',\n requiredErrorText: 'Enter a value.',\n confirmVariant: 'primary',\n confirmTone: 'primary',\n required: true,\n error: null,\n fieldError: null,\n confirmLoading: false,\n confirmDisabled: false,\n closeOnConfirm: true,\n})\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: boolean): void\n (e: 'update:value', value: string): void\n (e: 'confirm', value: string): void\n (e: 'cancel'): void\n}>()\n\nconst open = computed({\n get: () => props.modelValue,\n set: (v: boolean) => emit('update:modelValue', v),\n})\n\nconst valueModel = computed({\n get: () => props.value,\n set: (v: string) => emit('update:value', v),\n})\n\nconst touched = ref(false)\nconst inputRef = ref<InstanceType<typeof GrInput> | null>(null)\n\nwatch(\n () => props.modelValue,\n (v) => {\n if (v) touched.value = false\n },\n)\n\nconst canConfirm = computed(() => {\n if (!props.required) return true\n return valueModel.value.trim().length > 0\n})\n\nconst validationError = computed(() => {\n if (!props.required) return undefined\n if (!touched.value) return undefined\n return valueModel.value.trim().length > 0\n ? undefined\n : props.requiredErrorText\n})\n\n// Внешняя ошибка поля (серверная валидация) имеет приоритет над встроенной.\nconst fieldErrorMessage = computed(() => props.fieldError ?? validationError.value ?? undefined)\n\nfunction onCancel(): void {\n emit('cancel')\n emit('update:modelValue', false)\n}\n\nfunction onConfirm(): void {\n if (!canConfirm.value) {\n touched.value = true\n inputRef.value?.focus()\n return\n }\n\n emit('confirm', valueModel.value)\n if (props.closeOnConfirm)\n emit('update:modelValue', false)\n}\n</script>\n\n<template>\n <GrDialog\n v-model=\"open\"\n :title=\"title\"\n :size=\"size\"\n :close-on-backdrop=\"closeOnBackdrop\"\n :close-on-esc=\"closeOnEsc\"\n :show-header=\"showHeader\"\n :show-close-button=\"showCloseButton\"\n :header-config=\"headerConfig\"\n :footer-config=\"footerConfig\"\n :body-config=\"bodyConfig\"\n :close-label=\"closeLabel\"\n >\n <div class=\"grid gap-4\">\n <slot>\n <div v-if=\"description\" class=\"text-[14px] text-[var(--muted-fg)]\">\n {{ description }}\n </div>\n </slot>\n\n <GrFormField :label=\"label\" :error=\"fieldErrorMessage\" for-id=\"ds-prompt-input\">\n <GrInput\n id=\"ds-prompt-input\"\n ref=\"inputRef\"\n v-model=\"valueModel\"\n data-testid=\"ds-prompt-input\"\n :placeholder=\"placeholder\"\n :invalid=\"!!fieldErrorMessage\"\n @blur=\"touched = true\"\n />\n </GrFormField>\n\n <slot name=\"error\" :error=\"error\">\n <GrResponseErrorBanner v-if=\"error\" :error=\"error\" :can-dismiss=\"false\" />\n </slot>\n </div>\n\n <template #footer>\n <slot name=\"footer\">\n <div class=\"flex items-center justify-end gap-3\">\n <GrButton data-testid=\"ds-prompt-cancel\" variant=\"outline\" :size=\"buttonSize\" @click=\"onCancel\">\n {{ cancelText }}\n </GrButton>\n <GrButton\n data-testid=\"ds-prompt-confirm\"\n :variant=\"confirmVariant\"\n :tone=\"confirmTone\"\n :size=\"buttonSize\"\n :loading=\"confirmLoading\"\n :disabled=\"confirmDisabled || (required && touched && !canConfirm)\"\n @click=\"onConfirm\"\n >\n {{ confirmText }}\n </GrButton>\n </div>\n </slot>\n </template>\n </GrDialog>\n</template>\n","<script setup lang=\"ts\">\n/**\n * GrPromptDialog — DS-примитив диалога ввода значения поверх `GrDialog`.\n *\n * Синхронизирован с `GrDialog` по набору проп-проксирования:\n * `size`, `closeOnBackdrop`, `closeOnEsc`, `showHeader`, `showCloseButton`,\n * `headerConfig`, `footerConfig`, `bodyConfig`, `closeLabel`.\n *\n * Поведение `required=true` (по умолчанию): пустое значение подсвечивается\n * ошибкой только после первого «касания» (blur или попытка confirm),\n * чтобы не шуметь при открытии.\n */\nimport { computed, ref, watch } from 'vue'\n\nimport GrButton from '../GrButton/GrButton.vue'\nimport GrDialog from '../GrDialog/GrDialog.vue'\nimport GrFormField from '../GrFormField/GrFormField.vue'\nimport GrInput from '../GrInput/GrInput.vue'\nimport GrResponseErrorBanner from '../GrResponseErrorBanner/GrResponseErrorBanner.vue'\nimport type { GrButtonSize, GrButtonTone, GrButtonVariant } from '../GrButton'\nimport type { GrDialogSectionConfig, GrDialogSize } from '../GrDialog'\nimport type { ResponseErrorInfo } from '../GrResponseErrorBanner'\n\nexport interface GrPromptDialogProps {\n modelValue: boolean\n value: string\n title?: string\n description?: string\n label?: string\n placeholder?: string\n closeOnBackdrop?: boolean\n closeOnEsc?: boolean\n showHeader?: boolean\n showCloseButton?: boolean\n size?: GrDialogSize\n headerConfig?: GrDialogSectionConfig\n footerConfig?: GrDialogSectionConfig\n bodyConfig?: GrDialogSectionConfig\n /** A11y-лейбл кнопки закрытия (i18n). */\n closeLabel?: string\n buttonSize?: GrButtonSize\n confirmText?: string\n cancelText?: string\n /** Текст ошибки для пустого значения при `required=true` (i18n). */\n requiredErrorText?: string\n confirmVariant?: GrButtonVariant\n confirmTone?: GrButtonTone\n required?: boolean\n /**\n * Структура ошибки ответа сервера для показа общим блоком в теле диалога\n * (через `GrResponseErrorBanner`). `null` — блок скрыт.\n */\n error?: ResponseErrorInfo | null\n /**\n * Внешняя ошибка поля ввода (например, серверная валидация). Имеет приоритет\n * над встроенной проверкой `required`. `null`/`undefined` — нет внешней ошибки.\n */\n fieldError?: string | null\n /** Состояние загрузки кнопки Confirm (async-`onConfirm` in-flight). */\n confirmLoading?: boolean\n /** Принудительно дизейблит кнопку Confirm. */\n confirmDisabled?: boolean\n /**\n * Закрывать ли диалог автоматически по клику Confirm. По умолчанию `true`.\n * `false` — отдаёт управление закрытием наружу (нужно `useDialogService`).\n */\n closeOnConfirm?: boolean\n}\n\nconst props = withDefaults(defineProps<GrPromptDialogProps>(), {\n title: 'Prompt',\n description: undefined,\n label: 'Value',\n placeholder: undefined,\n closeOnBackdrop: true,\n closeOnEsc: true,\n showHeader: true,\n showCloseButton: true,\n size: 'md',\n headerConfig: undefined,\n footerConfig: undefined,\n bodyConfig: undefined,\n closeLabel: 'Close',\n buttonSize: undefined,\n confirmText: 'Confirm',\n cancelText: 'Cancel',\n requiredErrorText: 'Enter a value.',\n confirmVariant: 'primary',\n confirmTone: 'primary',\n required: true,\n error: null,\n fieldError: null,\n confirmLoading: false,\n confirmDisabled: false,\n closeOnConfirm: true,\n})\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: boolean): void\n (e: 'update:value', value: string): void\n (e: 'confirm', value: string): void\n (e: 'cancel'): void\n}>()\n\nconst open = computed({\n get: () => props.modelValue,\n set: (v: boolean) => emit('update:modelValue', v),\n})\n\nconst valueModel = computed({\n get: () => props.value,\n set: (v: string) => emit('update:value', v),\n})\n\nconst touched = ref(false)\nconst inputRef = ref<InstanceType<typeof GrInput> | null>(null)\n\nwatch(\n () => props.modelValue,\n (v) => {\n if (v) touched.value = false\n },\n)\n\nconst canConfirm = computed(() => {\n if (!props.required) return true\n return valueModel.value.trim().length > 0\n})\n\nconst validationError = computed(() => {\n if (!props.required) return undefined\n if (!touched.value) return undefined\n return valueModel.value.trim().length > 0\n ? undefined\n : props.requiredErrorText\n})\n\n// Внешняя ошибка поля (серверная валидация) имеет приоритет над встроенной.\nconst fieldErrorMessage = computed(() => props.fieldError ?? validationError.value ?? undefined)\n\nfunction onCancel(): void {\n emit('cancel')\n emit('update:modelValue', false)\n}\n\nfunction onConfirm(): void {\n if (!canConfirm.value) {\n touched.value = true\n inputRef.value?.focus()\n return\n }\n\n emit('confirm', valueModel.value)\n if (props.closeOnConfirm)\n emit('update:modelValue', false)\n}\n</script>\n\n<template>\n <GrDialog\n v-model=\"open\"\n :title=\"title\"\n :size=\"size\"\n :close-on-backdrop=\"closeOnBackdrop\"\n :close-on-esc=\"closeOnEsc\"\n :show-header=\"showHeader\"\n :show-close-button=\"showCloseButton\"\n :header-config=\"headerConfig\"\n :footer-config=\"footerConfig\"\n :body-config=\"bodyConfig\"\n :close-label=\"closeLabel\"\n >\n <div class=\"grid gap-4\">\n <slot>\n <div v-if=\"description\" class=\"text-[14px] text-[var(--muted-fg)]\">\n {{ description }}\n </div>\n </slot>\n\n <GrFormField :label=\"label\" :error=\"fieldErrorMessage\" for-id=\"ds-prompt-input\">\n <GrInput\n id=\"ds-prompt-input\"\n ref=\"inputRef\"\n v-model=\"valueModel\"\n data-testid=\"ds-prompt-input\"\n :placeholder=\"placeholder\"\n :invalid=\"!!fieldErrorMessage\"\n @blur=\"touched = true\"\n />\n </GrFormField>\n\n <slot name=\"error\" :error=\"error\">\n <GrResponseErrorBanner v-if=\"error\" :error=\"error\" :can-dismiss=\"false\" />\n </slot>\n </div>\n\n <template #footer>\n <slot name=\"footer\">\n <div class=\"flex items-center justify-end gap-3\">\n <GrButton data-testid=\"ds-prompt-cancel\" variant=\"outline\" :size=\"buttonSize\" @click=\"onCancel\">\n {{ cancelText }}\n </GrButton>\n <GrButton\n data-testid=\"ds-prompt-confirm\"\n :variant=\"confirmVariant\"\n :tone=\"confirmTone\"\n :size=\"buttonSize\"\n :loading=\"confirmLoading\"\n :disabled=\"confirmDisabled || (required && touched && !canConfirm)\"\n @click=\"onConfirm\"\n >\n {{ confirmText }}\n </GrButton>\n </div>\n </slot>\n </template>\n </GrDialog>\n</template>\n"],"mappings":"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"}
@@ -1,3 +1,3 @@
1
- import { t as GrPromptDialog_default } from "./chunks/GrPromptDialog-BV4EW3XO.js";
2
- import { t as grPromptDialogConfig } from "../../chunks/config-B1kFmhpM.js";
1
+ import { t as GrPromptDialog_default } from "./chunks/GrPromptDialog-D_TFqKsF.js";
2
+ import { t as grPromptDialogConfig } from "../../chunks/config-DhQc1TRY.js";
3
3
  export { GrPromptDialog_default as GrPromptDialog, GrPromptDialog_default as default, grPromptDialogConfig };
@@ -1,4 +1,4 @@
1
- import { a as grRadioDotBaseClass, i as grRadioControlClass, o as grRadioDotClass, r as grRadioButtonClass, s as grRadioRootClass } from "../../../chunks/config-Cp_XHsze.js";
1
+ import { a as grRadioDotBaseClass, i as grRadioControlClass, o as grRadioDotClass, r as grRadioButtonClass, s as grRadioRootClass } from "../../../chunks/config-nrOj9p6I.js";
2
2
  import { computed, createElementBlock, createElementVNode, defineComponent, inject, normalizeClass, openBlock, renderSlot, unref, withKeys, withModifiers } from "vue";
3
3
  //#region src/components/GrRadio/grRadioGroupContext.ts
4
4
  var GR_RADIO_GROUP_CONTEXT = Symbol("GR_RADIO_GROUP_CONTEXT");
@@ -1 +1 @@
1
- {"version":3,"file":"GrRadio-IFU9Hiu2.js","names":[],"sources":["../../../../src/components/GrRadio/grRadioGroupContext.ts","../../../../src/components/GrRadio/GrRadio.vue","../../../../src/components/GrRadio/GrRadio.vue"],"sourcesContent":["import type { ComputedRef, InjectionKey } from 'vue'\n\nimport type { GrButtonSize } from '../GrButton/grButtonStyles'\n\nexport type GrRadioGroupContext = {\n modelValue: ComputedRef<string>\n name: ComputedRef<string | undefined>\n disabled: ComputedRef<boolean>\n size: ComputedRef<GrButtonSize>\n setValue: (value: string) => void\n}\n\nexport const GR_RADIO_GROUP_CONTEXT: InjectionKey<GrRadioGroupContext> = Symbol('GR_RADIO_GROUP_CONTEXT')","<script setup lang=\"ts\">\nimport { computed, inject } from 'vue'\n\nimport type { GrButtonSize, GrButtonTone, GrButtonVariant } from '../GrButton'\n\nimport {\n grRadioButtonClass,\n grRadioControlClass,\n grRadioDotBaseClass,\n grRadioDotClass,\n grRadioRootClass,\n type GrRadioVariant,\n} from './grRadioStyles'\nimport { GR_RADIO_GROUP_CONTEXT } from './grRadioGroupContext'\n\n/**\n * GrRadio — одиночный элемент группы выбора.\n *\n * Может работать автономно (через `v-model`) либо внутри `GrRadioGroup`\n * (тогда `modelValue`/`disabled`/`size`/`name` приходят через `inject`).\n *\n * @prop value — значение этого элемента, сравнивается с `modelValue` группы.\n * @prop variant — визуальное представление: `radiobox` (круг+dot) или `button` (стиль `GrButton`).\n */\nexport interface GrRadioProps {\n value: string\n modelValue?: string\n disabled?: boolean\n name?: string\n required?: boolean\n form?: string\n id?: string\n size?: GrButtonSize\n variant?: GrRadioVariant\n buttonVariant?: GrButtonVariant\n buttonTone?: GrButtonTone\n selectedButtonVariant?: GrButtonVariant\n selectedButtonTone?: GrButtonTone\n ariaLabel?: string\n}\n\nconst hiddenInputStyle = {\n position: 'absolute',\n opacity: '0',\n width: '0',\n height: '0',\n pointerEvents: 'none',\n} as const\n\nconst props = withDefaults(defineProps<GrRadioProps>(), {\n modelValue: undefined,\n disabled: undefined,\n name: undefined,\n required: false,\n form: undefined,\n id: undefined,\n size: undefined,\n variant: 'radiobox',\n buttonVariant: 'outline',\n buttonTone: 'neutral',\n selectedButtonVariant: 'primary',\n selectedButtonTone: 'primary',\n ariaLabel: undefined,\n})\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string): void\n}>()\n\nconst group = inject(GR_RADIO_GROUP_CONTEXT, null)\n\nconst resolvedModelValue = computed(() => {\n if (props.modelValue !== undefined)\n return props.modelValue\n\n return group?.modelValue.value ?? ''\n})\n\nconst resolvedDisabled = computed(() => {\n if (props.disabled !== undefined)\n return props.disabled\n\n return group?.disabled.value ?? false\n})\n\nconst resolvedName = computed(() => {\n if (props.name)\n return props.name\n\n return group?.name.value\n})\n\nconst resolvedSize = computed<GrButtonSize>(() => {\n if (props.size)\n return props.size\n\n return group?.size.value ?? 'md'\n})\n\nconst checked = computed(() => resolvedModelValue.value === props.value)\n\nconst buttonClassName = computed(() => {\n return grRadioButtonClass({\n checked: checked.value,\n disabled: resolvedDisabled.value,\n size: resolvedSize.value,\n buttonVariant: props.buttonVariant,\n buttonTone: props.buttonTone,\n selectedButtonVariant: props.selectedButtonVariant,\n selectedButtonTone: props.selectedButtonTone,\n })\n})\n\nconst rootClassName = computed(() => grRadioRootClass(resolvedDisabled.value))\nconst controlClassName = computed(() => grRadioControlClass(checked.value))\nconst dotClassName = computed(() => grRadioDotClass(checked.value))\n\nfunction setValue(next: string): void {\n if (resolvedDisabled.value)\n return\n\n if (props.modelValue !== undefined) {\n emit('update:modelValue', next)\n return\n }\n\n group?.setValue(next)\n}\n\nfunction onButtonClick(): void {\n setValue(props.value)\n}\n</script>\n\n<template>\n <div\n v-if=\"variant === 'button'\"\n data-ds-button\n data-ds-radio\n role=\"radio\"\n :aria-checked=\"checked ? 'true' : 'false'\"\n :aria-label=\"ariaLabel\"\n :aria-disabled=\"resolvedDisabled ? 'true' : undefined\"\n :tabindex=\"resolvedDisabled ? -1 : 0\"\n :class=\"buttonClassName\"\n @click=\"onButtonClick\"\n @keydown.space.prevent=\"onButtonClick\"\n @keydown.enter.prevent=\"onButtonClick\"\n >\n <input\n :id=\"id\"\n type=\"radio\"\n :checked=\"checked\"\n :disabled=\"resolvedDisabled\"\n :name=\"resolvedName\"\n :value=\"value\"\n :required=\"required\"\n :form=\"form\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n :style=\"hiddenInputStyle\"\n >\n\n <slot />\n </div>\n\n <div\n v-else\n data-ds-radio\n role=\"radio\"\n :aria-checked=\"checked ? 'true' : 'false'\"\n :aria-label=\"ariaLabel\"\n :aria-disabled=\"resolvedDisabled ? 'true' : undefined\"\n :tabindex=\"resolvedDisabled ? -1 : 0\"\n class=\"inline-flex items-center gap-2 select-none focus-visible:outline-none focus-visible:rounded-[8px] focus-visible:shadow-[0_0_0_2px_var(--ring),0_0_0_4px_var(--bg)]\"\n :class=\"rootClassName\"\n @click=\"onButtonClick\"\n @keydown.space.prevent=\"onButtonClick\"\n @keydown.enter.prevent=\"onButtonClick\"\n >\n <input\n :id=\"id\"\n type=\"radio\"\n :checked=\"checked\"\n :disabled=\"resolvedDisabled\"\n :name=\"resolvedName\"\n :value=\"value\"\n :required=\"required\"\n :form=\"form\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n :style=\"hiddenInputStyle\"\n >\n\n <span\n data-ds-radio-control\n aria-hidden=\"true\"\n class=\"h-4 w-4 rounded-full border flex items-center justify-center transition-colors duration-150\"\n :class=\"controlClassName\"\n >\n <span\n data-ds-radio-dot\n :class=\"[grRadioDotBaseClass, dotClassName]\"\n />\n </span>\n\n <span class=\"text-sm text-[var(--muted-fg)]\">\n <slot />\n </span>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, inject } from 'vue'\n\nimport type { GrButtonSize, GrButtonTone, GrButtonVariant } from '../GrButton'\n\nimport {\n grRadioButtonClass,\n grRadioControlClass,\n grRadioDotBaseClass,\n grRadioDotClass,\n grRadioRootClass,\n type GrRadioVariant,\n} from './grRadioStyles'\nimport { GR_RADIO_GROUP_CONTEXT } from './grRadioGroupContext'\n\n/**\n * GrRadio — одиночный элемент группы выбора.\n *\n * Может работать автономно (через `v-model`) либо внутри `GrRadioGroup`\n * (тогда `modelValue`/`disabled`/`size`/`name` приходят через `inject`).\n *\n * @prop value — значение этого элемента, сравнивается с `modelValue` группы.\n * @prop variant — визуальное представление: `radiobox` (круг+dot) или `button` (стиль `GrButton`).\n */\nexport interface GrRadioProps {\n value: string\n modelValue?: string\n disabled?: boolean\n name?: string\n required?: boolean\n form?: string\n id?: string\n size?: GrButtonSize\n variant?: GrRadioVariant\n buttonVariant?: GrButtonVariant\n buttonTone?: GrButtonTone\n selectedButtonVariant?: GrButtonVariant\n selectedButtonTone?: GrButtonTone\n ariaLabel?: string\n}\n\nconst hiddenInputStyle = {\n position: 'absolute',\n opacity: '0',\n width: '0',\n height: '0',\n pointerEvents: 'none',\n} as const\n\nconst props = withDefaults(defineProps<GrRadioProps>(), {\n modelValue: undefined,\n disabled: undefined,\n name: undefined,\n required: false,\n form: undefined,\n id: undefined,\n size: undefined,\n variant: 'radiobox',\n buttonVariant: 'outline',\n buttonTone: 'neutral',\n selectedButtonVariant: 'primary',\n selectedButtonTone: 'primary',\n ariaLabel: undefined,\n})\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string): void\n}>()\n\nconst group = inject(GR_RADIO_GROUP_CONTEXT, null)\n\nconst resolvedModelValue = computed(() => {\n if (props.modelValue !== undefined)\n return props.modelValue\n\n return group?.modelValue.value ?? ''\n})\n\nconst resolvedDisabled = computed(() => {\n if (props.disabled !== undefined)\n return props.disabled\n\n return group?.disabled.value ?? false\n})\n\nconst resolvedName = computed(() => {\n if (props.name)\n return props.name\n\n return group?.name.value\n})\n\nconst resolvedSize = computed<GrButtonSize>(() => {\n if (props.size)\n return props.size\n\n return group?.size.value ?? 'md'\n})\n\nconst checked = computed(() => resolvedModelValue.value === props.value)\n\nconst buttonClassName = computed(() => {\n return grRadioButtonClass({\n checked: checked.value,\n disabled: resolvedDisabled.value,\n size: resolvedSize.value,\n buttonVariant: props.buttonVariant,\n buttonTone: props.buttonTone,\n selectedButtonVariant: props.selectedButtonVariant,\n selectedButtonTone: props.selectedButtonTone,\n })\n})\n\nconst rootClassName = computed(() => grRadioRootClass(resolvedDisabled.value))\nconst controlClassName = computed(() => grRadioControlClass(checked.value))\nconst dotClassName = computed(() => grRadioDotClass(checked.value))\n\nfunction setValue(next: string): void {\n if (resolvedDisabled.value)\n return\n\n if (props.modelValue !== undefined) {\n emit('update:modelValue', next)\n return\n }\n\n group?.setValue(next)\n}\n\nfunction onButtonClick(): void {\n setValue(props.value)\n}\n</script>\n\n<template>\n <div\n v-if=\"variant === 'button'\"\n data-ds-button\n data-ds-radio\n role=\"radio\"\n :aria-checked=\"checked ? 'true' : 'false'\"\n :aria-label=\"ariaLabel\"\n :aria-disabled=\"resolvedDisabled ? 'true' : undefined\"\n :tabindex=\"resolvedDisabled ? -1 : 0\"\n :class=\"buttonClassName\"\n @click=\"onButtonClick\"\n @keydown.space.prevent=\"onButtonClick\"\n @keydown.enter.prevent=\"onButtonClick\"\n >\n <input\n :id=\"id\"\n type=\"radio\"\n :checked=\"checked\"\n :disabled=\"resolvedDisabled\"\n :name=\"resolvedName\"\n :value=\"value\"\n :required=\"required\"\n :form=\"form\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n :style=\"hiddenInputStyle\"\n >\n\n <slot />\n </div>\n\n <div\n v-else\n data-ds-radio\n role=\"radio\"\n :aria-checked=\"checked ? 'true' : 'false'\"\n :aria-label=\"ariaLabel\"\n :aria-disabled=\"resolvedDisabled ? 'true' : undefined\"\n :tabindex=\"resolvedDisabled ? -1 : 0\"\n class=\"inline-flex items-center gap-2 select-none focus-visible:outline-none focus-visible:rounded-[8px] focus-visible:shadow-[0_0_0_2px_var(--ring),0_0_0_4px_var(--bg)]\"\n :class=\"rootClassName\"\n @click=\"onButtonClick\"\n @keydown.space.prevent=\"onButtonClick\"\n @keydown.enter.prevent=\"onButtonClick\"\n >\n <input\n :id=\"id\"\n type=\"radio\"\n :checked=\"checked\"\n :disabled=\"resolvedDisabled\"\n :name=\"resolvedName\"\n :value=\"value\"\n :required=\"required\"\n :form=\"form\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n :style=\"hiddenInputStyle\"\n >\n\n <span\n data-ds-radio-control\n aria-hidden=\"true\"\n class=\"h-4 w-4 rounded-full border flex items-center justify-center transition-colors duration-150\"\n :class=\"controlClassName\"\n >\n <span\n data-ds-radio-dot\n :class=\"[grRadioDotBaseClass, dotClassName]\"\n />\n </span>\n\n <span class=\"text-sm text-[var(--muted-fg)]\">\n <slot />\n </span>\n </div>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"GrRadio-CSbTnrom.js","names":[],"sources":["../../../../src/components/GrRadio/grRadioGroupContext.ts","../../../../src/components/GrRadio/GrRadio.vue","../../../../src/components/GrRadio/GrRadio.vue"],"sourcesContent":["import type { ComputedRef, InjectionKey } from 'vue'\n\nimport type { GrButtonSize } from '../GrButton/grButtonStyles'\n\nexport type GrRadioGroupContext = {\n modelValue: ComputedRef<string>\n name: ComputedRef<string | undefined>\n disabled: ComputedRef<boolean>\n size: ComputedRef<GrButtonSize>\n setValue: (value: string) => void\n}\n\nexport const GR_RADIO_GROUP_CONTEXT: InjectionKey<GrRadioGroupContext> = Symbol('GR_RADIO_GROUP_CONTEXT')","<script setup lang=\"ts\">\nimport { computed, inject } from 'vue'\n\nimport type { GrButtonSize, GrButtonTone, GrButtonVariant } from '../GrButton'\n\nimport {\n grRadioButtonClass,\n grRadioControlClass,\n grRadioDotBaseClass,\n grRadioDotClass,\n grRadioRootClass,\n type GrRadioVariant,\n} from './grRadioStyles'\nimport { GR_RADIO_GROUP_CONTEXT } from './grRadioGroupContext'\n\n/**\n * GrRadio — одиночный элемент группы выбора.\n *\n * Может работать автономно (через `v-model`) либо внутри `GrRadioGroup`\n * (тогда `modelValue`/`disabled`/`size`/`name` приходят через `inject`).\n *\n * @prop value — значение этого элемента, сравнивается с `modelValue` группы.\n * @prop variant — визуальное представление: `radiobox` (круг+dot) или `button` (стиль `GrButton`).\n */\nexport interface GrRadioProps {\n value: string\n modelValue?: string\n disabled?: boolean\n name?: string\n required?: boolean\n form?: string\n id?: string\n size?: GrButtonSize\n variant?: GrRadioVariant\n buttonVariant?: GrButtonVariant\n buttonTone?: GrButtonTone\n selectedButtonVariant?: GrButtonVariant\n selectedButtonTone?: GrButtonTone\n ariaLabel?: string\n}\n\nconst hiddenInputStyle = {\n position: 'absolute',\n opacity: '0',\n width: '0',\n height: '0',\n pointerEvents: 'none',\n} as const\n\nconst props = withDefaults(defineProps<GrRadioProps>(), {\n modelValue: undefined,\n disabled: undefined,\n name: undefined,\n required: false,\n form: undefined,\n id: undefined,\n size: undefined,\n variant: 'radiobox',\n buttonVariant: 'outline',\n buttonTone: 'neutral',\n selectedButtonVariant: 'primary',\n selectedButtonTone: 'primary',\n ariaLabel: undefined,\n})\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string): void\n}>()\n\nconst group = inject(GR_RADIO_GROUP_CONTEXT, null)\n\nconst resolvedModelValue = computed(() => {\n if (props.modelValue !== undefined)\n return props.modelValue\n\n return group?.modelValue.value ?? ''\n})\n\nconst resolvedDisabled = computed(() => {\n if (props.disabled !== undefined)\n return props.disabled\n\n return group?.disabled.value ?? false\n})\n\nconst resolvedName = computed(() => {\n if (props.name)\n return props.name\n\n return group?.name.value\n})\n\nconst resolvedSize = computed<GrButtonSize>(() => {\n if (props.size)\n return props.size\n\n return group?.size.value ?? 'md'\n})\n\nconst checked = computed(() => resolvedModelValue.value === props.value)\n\nconst buttonClassName = computed(() => {\n return grRadioButtonClass({\n checked: checked.value,\n disabled: resolvedDisabled.value,\n size: resolvedSize.value,\n buttonVariant: props.buttonVariant,\n buttonTone: props.buttonTone,\n selectedButtonVariant: props.selectedButtonVariant,\n selectedButtonTone: props.selectedButtonTone,\n })\n})\n\nconst rootClassName = computed(() => grRadioRootClass(resolvedDisabled.value))\nconst controlClassName = computed(() => grRadioControlClass(checked.value))\nconst dotClassName = computed(() => grRadioDotClass(checked.value))\n\nfunction setValue(next: string): void {\n if (resolvedDisabled.value)\n return\n\n if (props.modelValue !== undefined) {\n emit('update:modelValue', next)\n return\n }\n\n group?.setValue(next)\n}\n\nfunction onButtonClick(): void {\n setValue(props.value)\n}\n</script>\n\n<template>\n <div\n v-if=\"variant === 'button'\"\n data-ds-button\n data-ds-radio\n role=\"radio\"\n :aria-checked=\"checked ? 'true' : 'false'\"\n :aria-label=\"ariaLabel\"\n :aria-disabled=\"resolvedDisabled ? 'true' : undefined\"\n :tabindex=\"resolvedDisabled ? -1 : 0\"\n :class=\"buttonClassName\"\n @click=\"onButtonClick\"\n @keydown.space.prevent=\"onButtonClick\"\n @keydown.enter.prevent=\"onButtonClick\"\n >\n <input\n :id=\"id\"\n type=\"radio\"\n :checked=\"checked\"\n :disabled=\"resolvedDisabled\"\n :name=\"resolvedName\"\n :value=\"value\"\n :required=\"required\"\n :form=\"form\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n :style=\"hiddenInputStyle\"\n >\n\n <slot />\n </div>\n\n <div\n v-else\n data-ds-radio\n role=\"radio\"\n :aria-checked=\"checked ? 'true' : 'false'\"\n :aria-label=\"ariaLabel\"\n :aria-disabled=\"resolvedDisabled ? 'true' : undefined\"\n :tabindex=\"resolvedDisabled ? -1 : 0\"\n class=\"inline-flex items-center gap-2 select-none focus-visible:outline-none focus-visible:rounded-[8px] focus-visible:shadow-[0_0_0_2px_var(--ring),0_0_0_4px_var(--bg)]\"\n :class=\"rootClassName\"\n @click=\"onButtonClick\"\n @keydown.space.prevent=\"onButtonClick\"\n @keydown.enter.prevent=\"onButtonClick\"\n >\n <input\n :id=\"id\"\n type=\"radio\"\n :checked=\"checked\"\n :disabled=\"resolvedDisabled\"\n :name=\"resolvedName\"\n :value=\"value\"\n :required=\"required\"\n :form=\"form\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n :style=\"hiddenInputStyle\"\n >\n\n <span\n data-ds-radio-control\n aria-hidden=\"true\"\n class=\"h-4 w-4 rounded-full border flex items-center justify-center transition-colors duration-150\"\n :class=\"controlClassName\"\n >\n <span\n data-ds-radio-dot\n :class=\"[grRadioDotBaseClass, dotClassName]\"\n />\n </span>\n\n <span class=\"text-sm text-[var(--muted-fg)]\">\n <slot />\n </span>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, inject } from 'vue'\n\nimport type { GrButtonSize, GrButtonTone, GrButtonVariant } from '../GrButton'\n\nimport {\n grRadioButtonClass,\n grRadioControlClass,\n grRadioDotBaseClass,\n grRadioDotClass,\n grRadioRootClass,\n type GrRadioVariant,\n} from './grRadioStyles'\nimport { GR_RADIO_GROUP_CONTEXT } from './grRadioGroupContext'\n\n/**\n * GrRadio — одиночный элемент группы выбора.\n *\n * Может работать автономно (через `v-model`) либо внутри `GrRadioGroup`\n * (тогда `modelValue`/`disabled`/`size`/`name` приходят через `inject`).\n *\n * @prop value — значение этого элемента, сравнивается с `modelValue` группы.\n * @prop variant — визуальное представление: `radiobox` (круг+dot) или `button` (стиль `GrButton`).\n */\nexport interface GrRadioProps {\n value: string\n modelValue?: string\n disabled?: boolean\n name?: string\n required?: boolean\n form?: string\n id?: string\n size?: GrButtonSize\n variant?: GrRadioVariant\n buttonVariant?: GrButtonVariant\n buttonTone?: GrButtonTone\n selectedButtonVariant?: GrButtonVariant\n selectedButtonTone?: GrButtonTone\n ariaLabel?: string\n}\n\nconst hiddenInputStyle = {\n position: 'absolute',\n opacity: '0',\n width: '0',\n height: '0',\n pointerEvents: 'none',\n} as const\n\nconst props = withDefaults(defineProps<GrRadioProps>(), {\n modelValue: undefined,\n disabled: undefined,\n name: undefined,\n required: false,\n form: undefined,\n id: undefined,\n size: undefined,\n variant: 'radiobox',\n buttonVariant: 'outline',\n buttonTone: 'neutral',\n selectedButtonVariant: 'primary',\n selectedButtonTone: 'primary',\n ariaLabel: undefined,\n})\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string): void\n}>()\n\nconst group = inject(GR_RADIO_GROUP_CONTEXT, null)\n\nconst resolvedModelValue = computed(() => {\n if (props.modelValue !== undefined)\n return props.modelValue\n\n return group?.modelValue.value ?? ''\n})\n\nconst resolvedDisabled = computed(() => {\n if (props.disabled !== undefined)\n return props.disabled\n\n return group?.disabled.value ?? false\n})\n\nconst resolvedName = computed(() => {\n if (props.name)\n return props.name\n\n return group?.name.value\n})\n\nconst resolvedSize = computed<GrButtonSize>(() => {\n if (props.size)\n return props.size\n\n return group?.size.value ?? 'md'\n})\n\nconst checked = computed(() => resolvedModelValue.value === props.value)\n\nconst buttonClassName = computed(() => {\n return grRadioButtonClass({\n checked: checked.value,\n disabled: resolvedDisabled.value,\n size: resolvedSize.value,\n buttonVariant: props.buttonVariant,\n buttonTone: props.buttonTone,\n selectedButtonVariant: props.selectedButtonVariant,\n selectedButtonTone: props.selectedButtonTone,\n })\n})\n\nconst rootClassName = computed(() => grRadioRootClass(resolvedDisabled.value))\nconst controlClassName = computed(() => grRadioControlClass(checked.value))\nconst dotClassName = computed(() => grRadioDotClass(checked.value))\n\nfunction setValue(next: string): void {\n if (resolvedDisabled.value)\n return\n\n if (props.modelValue !== undefined) {\n emit('update:modelValue', next)\n return\n }\n\n group?.setValue(next)\n}\n\nfunction onButtonClick(): void {\n setValue(props.value)\n}\n</script>\n\n<template>\n <div\n v-if=\"variant === 'button'\"\n data-ds-button\n data-ds-radio\n role=\"radio\"\n :aria-checked=\"checked ? 'true' : 'false'\"\n :aria-label=\"ariaLabel\"\n :aria-disabled=\"resolvedDisabled ? 'true' : undefined\"\n :tabindex=\"resolvedDisabled ? -1 : 0\"\n :class=\"buttonClassName\"\n @click=\"onButtonClick\"\n @keydown.space.prevent=\"onButtonClick\"\n @keydown.enter.prevent=\"onButtonClick\"\n >\n <input\n :id=\"id\"\n type=\"radio\"\n :checked=\"checked\"\n :disabled=\"resolvedDisabled\"\n :name=\"resolvedName\"\n :value=\"value\"\n :required=\"required\"\n :form=\"form\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n :style=\"hiddenInputStyle\"\n >\n\n <slot />\n </div>\n\n <div\n v-else\n data-ds-radio\n role=\"radio\"\n :aria-checked=\"checked ? 'true' : 'false'\"\n :aria-label=\"ariaLabel\"\n :aria-disabled=\"resolvedDisabled ? 'true' : undefined\"\n :tabindex=\"resolvedDisabled ? -1 : 0\"\n class=\"inline-flex items-center gap-2 select-none focus-visible:outline-none focus-visible:rounded-[8px] focus-visible:shadow-[0_0_0_2px_var(--ring),0_0_0_4px_var(--bg)]\"\n :class=\"rootClassName\"\n @click=\"onButtonClick\"\n @keydown.space.prevent=\"onButtonClick\"\n @keydown.enter.prevent=\"onButtonClick\"\n >\n <input\n :id=\"id\"\n type=\"radio\"\n :checked=\"checked\"\n :disabled=\"resolvedDisabled\"\n :name=\"resolvedName\"\n :value=\"value\"\n :required=\"required\"\n :form=\"form\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n :style=\"hiddenInputStyle\"\n >\n\n <span\n data-ds-radio-control\n aria-hidden=\"true\"\n class=\"h-4 w-4 rounded-full border flex items-center justify-center transition-colors duration-150\"\n :class=\"controlClassName\"\n >\n <span\n data-ds-radio-dot\n :class=\"[grRadioDotBaseClass, dotClassName]\"\n />\n </span>\n\n <span class=\"text-sm text-[var(--muted-fg)]\">\n <slot />\n </span>\n </div>\n</template>\n"],"mappings":";;;AAYA,IAAa,yBAA4D,OAAO,yBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EC6BhF,MAAM,mBAAmB;GACvB,UAAU;GACV,SAAS;GACT,OAAO;GACP,QAAQ;GACR,eAAe;GAChB;EAED,MAAM,QAAQ;EAgBd,MAAM,OAAO;EAIb,MAAM,QAAQ,OAAO,wBAAwB,KAAI;EAEjD,MAAM,qBAAqB,eAAe;AACxC,OAAI,MAAM,eAAe,KAAA,EACvB,QAAO,MAAM;AAEf,UAAO,OAAO,WAAW,SAAS;IACnC;EAED,MAAM,mBAAmB,eAAe;AACtC,OAAI,MAAM,aAAa,KAAA,EACrB,QAAO,MAAM;AAEf,UAAO,OAAO,SAAS,SAAS;IACjC;EAED,MAAM,eAAe,eAAe;AAClC,OAAI,MAAM,KACR,QAAO,MAAM;AAEf,UAAO,OAAO,KAAK;IACpB;EAED,MAAM,eAAe,eAA6B;AAChD,OAAI,MAAM,KACR,QAAO,MAAM;AAEf,UAAO,OAAO,KAAK,SAAS;IAC7B;EAED,MAAM,UAAU,eAAe,mBAAmB,UAAU,MAAM,MAAK;EAEvE,MAAM,kBAAkB,eAAe;AACrC,UAAO,mBAAmB;IACxB,SAAS,QAAQ;IACjB,UAAU,iBAAiB;IAC3B,MAAM,aAAa;IACnB,eAAe,MAAM;IACrB,YAAY,MAAM;IAClB,uBAAuB,MAAM;IAC7B,oBAAoB,MAAM;IAC3B,CAAA;IACF;EAED,MAAM,gBAAgB,eAAe,iBAAiB,iBAAiB,MAAM,CAAA;EAC7E,MAAM,mBAAmB,eAAe,oBAAoB,QAAQ,MAAM,CAAA;EAC1E,MAAM,eAAe,eAAe,gBAAgB,QAAQ,MAAM,CAAA;EAElE,SAAS,SAAS,MAAoB;AACpC,OAAI,iBAAiB,MACnB;AAEF,OAAI,MAAM,eAAe,KAAA,GAAW;AAClC,SAAK,qBAAqB,KAAI;AAC9B;;AAGF,UAAO,SAAS,KAAI;;EAGtB,SAAS,gBAAsB;AAC7B,YAAS,MAAM,MAAK;;;UAMZ,QAAA,YAAO,YAAA,WAAA,EADf,mBA6BM,OAAA;;IA3BJ,kBAAA;IACA,iBAAA;IACA,MAAK;IACJ,gBAAc,QAAA,QAAO,SAAA;IACrB,cAAY,QAAA;IACZ,iBAAe,iBAAA,QAAgB,SAAY,KAAA;IAC3C,UAAU,iBAAA,QAAgB,KAAA;IAC1B,OAAK,eAAE,gBAAA,MAAe;IACtB,SAAO;IACP,WAAO,CAAA,SAAA,cAAgB,eAAa,CAAA,UAAA,CAAA,EAAA,CAAA,QAAA,CAAA,EAAA,SAAA,cACb,eAAa,CAAA,UAAA,CAAA,EAAA,CAAA,QAAA,CAAA,CAAA;OAErC,mBAYC,SAAA;IAXE,IAAI,QAAA;IACL,MAAK;IACJ,SAAS,QAAA;IACT,UAAU,iBAAA;IACV,MAAM,aAAA;IACN,OAAO,QAAA;IACP,UAAU,QAAA;IACV,MAAM,QAAA;IACP,UAAS;IACT,eAAY;IACX,OAAO;4BAGV,WAAQ,KAAA,QAAA,UAAA,CAAA,EAAA,IAAA,WAAA,KAAA,WAAA,EAGV,mBA2CM,OAAA;;IAzCJ,iBAAA;IACA,MAAK;IACJ,gBAAc,QAAA,QAAO,SAAA;IACrB,cAAY,QAAA;IACZ,iBAAe,iBAAA,QAAgB,SAAY,KAAA;IAC3C,UAAU,iBAAA,QAAgB,KAAA;IAC3B,OAAK,eAAA,CAAC,sKACE,cAAA,MAAa,CAAA;IACpB,SAAO;IACP,WAAO,CAAA,SAAA,cAAgB,eAAa,CAAA,UAAA,CAAA,EAAA,CAAA,QAAA,CAAA,EAAA,SAAA,cACb,eAAa,CAAA,UAAA,CAAA,EAAA,CAAA,QAAA,CAAA,CAAA;;IAErC,mBAYC,SAAA;KAXE,IAAI,QAAA;KACL,MAAK;KACJ,SAAS,QAAA;KACT,UAAU,iBAAA;KACV,MAAM,aAAA;KACN,OAAO,QAAA;KACP,UAAU,QAAA;KACV,MAAM,QAAA;KACP,UAAS;KACT,eAAY;KACX,OAAO;;IAGV,mBAUO,QAAA;KATL,yBAAA;KACA,eAAY;KACZ,OAAK,eAAA,CAAC,+FACE,iBAAA,MAAgB,CAAA;QAExB,mBAGE,QAAA;KAFA,qBAAA;KACC,OAAK,eAAA,CAAG,MAAA,oBAAmB,EAAE,aAAA,MAAY,CAAA;;IAI9C,mBAEO,QAFP,YAEO,CADL,WAAQ,KAAA,QAAA,UAAA,CAAA,CAAA"}
@@ -1,3 +1,3 @@
1
- import { n as grRadioSafelist, t as grRadioConfig } from "../../chunks/config-Cp_XHsze.js";
2
- import { n as GR_RADIO_GROUP_CONTEXT, t as GrRadio_default } from "./chunks/GrRadio-IFU9Hiu2.js";
1
+ import { n as grRadioSafelist, t as grRadioConfig } from "../../chunks/config-nrOj9p6I.js";
2
+ import { n as GR_RADIO_GROUP_CONTEXT, t as GrRadio_default } from "./chunks/GrRadio-CSbTnrom.js";
3
3
  export { GR_RADIO_GROUP_CONTEXT, GrRadio_default as GrRadio, GrRadio_default as default, grRadioConfig, grRadioSafelist };
@@ -1,5 +1,5 @@
1
1
  import { t as GrButtonGroup_default } from "../../GrButtonGroup/chunks/GrButtonGroup-CPOH6V-P.js";
2
- import { n as GR_RADIO_GROUP_CONTEXT, t as GrRadio_default } from "../../GrRadio/chunks/GrRadio-IFU9Hiu2.js";
2
+ import { n as GR_RADIO_GROUP_CONTEXT, t as GrRadio_default } from "../../GrRadio/chunks/GrRadio-CSbTnrom.js";
3
3
  import { Fragment, computed, createBlock, createElementBlock, createTextVNode, defineComponent, openBlock, provide, renderList, renderSlot, toDisplayString, withCtx } from "vue";
4
4
  //#region src/components/GrRadioGroup/GrRadioGroup.vue?vue&type=script&setup=true&lang.ts
5
5
  var _hoisted_1 = ["aria-label", "aria-disabled"];
@@ -1 +1 @@
1
- {"version":3,"file":"GrRadioGroup-C8IcJuuF.js","names":["$slots"],"sources":["../../../../src/components/GrRadioGroup/GrRadioGroup.vue","../../../../src/components/GrRadioGroup/GrRadioGroup.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, provide } from 'vue'\n\nimport type { GrButtonSize } from '../GrButton'\nimport GrButtonGroup from '../GrButtonGroup/GrButtonGroup.vue'\nimport GrRadio from '../GrRadio/GrRadio.vue'\nimport { GR_RADIO_GROUP_CONTEXT } from '../GrRadio'\n\nexport type GrRadioGroupVariant = 'radiobox' | 'button'\nexport interface GrRadioGroupOption { value: string, label: string }\n\n/**\n * GrRadioGroup — контейнер группы `GrRadio`.\n *\n * Может работать как через слот (ручной рендер `GrRadio`), так и через проп `options`.\n * Предоставляет дочерним `GrRadio` общий `modelValue`/`disabled`/`size`/`name` через `inject`.\n */\nexport interface GrRadioGroupProps {\n modelValue: string\n options?: GrRadioGroupOption[]\n name?: string\n disabled?: boolean\n variant?: GrRadioGroupVariant\n size?: GrButtonSize\n ariaLabel?: string\n}\n\nconst props = withDefaults(defineProps<GrRadioGroupProps>(), {\n options: undefined,\n name: undefined,\n disabled: false,\n variant: 'radiobox',\n size: 'md',\n ariaLabel: undefined,\n})\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string): void\n}>()\n\nfunction setValue(next: string): void {\n if (props.disabled)\n return\n emit('update:modelValue', next)\n}\n\nprovide(GR_RADIO_GROUP_CONTEXT, {\n modelValue: computed(() => props.modelValue),\n name: computed(() => props.name),\n disabled: computed(() => props.disabled),\n size: computed(() => props.size),\n setValue,\n})\n</script>\n\n<template>\n <div\n data-ds-radio-group\n role=\"radiogroup\"\n :aria-label=\"ariaLabel\"\n :aria-disabled=\"disabled ? 'true' : undefined\"\n >\n <template v-if=\"$slots.default\">\n <GrButtonGroup v-if=\"variant === 'button'\">\n <slot />\n </GrButtonGroup>\n <div v-else class=\"grid gap-2\">\n <slot />\n </div>\n </template>\n <template v-else>\n <GrButtonGroup v-if=\"variant === 'button'\">\n <GrRadio\n v-for=\"opt in options ?? []\"\n :key=\"opt.value\"\n :value=\"opt.value\"\n variant=\"button\"\n :size=\"size\"\n >\n {{ opt.label }}\n </GrRadio>\n </GrButtonGroup>\n <div v-else class=\"grid gap-2\">\n <GrRadio v-for=\"opt in options ?? []\" :key=\"opt.value\" :value=\"opt.value\">\n {{ opt.label }}\n </GrRadio>\n </div>\n </template>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, provide } from 'vue'\n\nimport type { GrButtonSize } from '../GrButton'\nimport GrButtonGroup from '../GrButtonGroup/GrButtonGroup.vue'\nimport GrRadio from '../GrRadio/GrRadio.vue'\nimport { GR_RADIO_GROUP_CONTEXT } from '../GrRadio'\n\nexport type GrRadioGroupVariant = 'radiobox' | 'button'\nexport interface GrRadioGroupOption { value: string, label: string }\n\n/**\n * GrRadioGroup — контейнер группы `GrRadio`.\n *\n * Может работать как через слот (ручной рендер `GrRadio`), так и через проп `options`.\n * Предоставляет дочерним `GrRadio` общий `modelValue`/`disabled`/`size`/`name` через `inject`.\n */\nexport interface GrRadioGroupProps {\n modelValue: string\n options?: GrRadioGroupOption[]\n name?: string\n disabled?: boolean\n variant?: GrRadioGroupVariant\n size?: GrButtonSize\n ariaLabel?: string\n}\n\nconst props = withDefaults(defineProps<GrRadioGroupProps>(), {\n options: undefined,\n name: undefined,\n disabled: false,\n variant: 'radiobox',\n size: 'md',\n ariaLabel: undefined,\n})\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string): void\n}>()\n\nfunction setValue(next: string): void {\n if (props.disabled)\n return\n emit('update:modelValue', next)\n}\n\nprovide(GR_RADIO_GROUP_CONTEXT, {\n modelValue: computed(() => props.modelValue),\n name: computed(() => props.name),\n disabled: computed(() => props.disabled),\n size: computed(() => props.size),\n setValue,\n})\n</script>\n\n<template>\n <div\n data-ds-radio-group\n role=\"radiogroup\"\n :aria-label=\"ariaLabel\"\n :aria-disabled=\"disabled ? 'true' : undefined\"\n >\n <template v-if=\"$slots.default\">\n <GrButtonGroup v-if=\"variant === 'button'\">\n <slot />\n </GrButtonGroup>\n <div v-else class=\"grid gap-2\">\n <slot />\n </div>\n </template>\n <template v-else>\n <GrButtonGroup v-if=\"variant === 'button'\">\n <GrRadio\n v-for=\"opt in options ?? []\"\n :key=\"opt.value\"\n :value=\"opt.value\"\n variant=\"button\"\n :size=\"size\"\n >\n {{ opt.label }}\n </GrRadio>\n </GrButtonGroup>\n <div v-else class=\"grid gap-2\">\n <GrRadio v-for=\"opt in options ?? []\" :key=\"opt.value\" :value=\"opt.value\">\n {{ opt.label }}\n </GrRadio>\n </div>\n </template>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2BA,MAAM,QAAQ;EASd,MAAM,OAAO;EAIb,SAAS,SAAS,MAAoB;AACpC,OAAI,MAAM,SACR;AACF,QAAK,qBAAqB,KAAI;;AAGhC,UAAQ,wBAAwB;GAC9B,YAAY,eAAe,MAAM,WAAW;GAC5C,MAAM,eAAe,MAAM,KAAK;GAChC,UAAU,eAAe,MAAM,SAAS;GACxC,MAAM,eAAe,MAAM,KAAK;GAChC;GACD,CAAA;;uBAIC,mBAgCM,OAAA;IA/BJ,uBAAA;IACA,MAAK;IACJ,cAAY,QAAA;IACZ,iBAAe,QAAA,WAAQ,SAAY,KAAA;OAEpBA,KAAAA,OAAO,WAAA,WAAA,EAAvB,mBAOW,UAAA,EAAA,KAAA,GAAA,EAAA,CANY,QAAA,YAAO,YAAA,WAAA,EAA5B,YAEgB,uBAAA,EAAA,KAAA,GAAA,EAAA;2BADN,CAAR,WAAQ,KAAA,QAAA,UAAA,CAAA,CAAA;;uBAEV,mBAEM,OAFN,YAEM,CADJ,WAAQ,KAAA,QAAA,UAAA,CAAA,CAAA,EAAA,EAAA,GAAA,KAAA,WAAA,EAGZ,mBAiBW,UAAA,EAAA,KAAA,GAAA,EAAA,CAhBY,QAAA,YAAO,YAAA,WAAA,EAA5B,YAUgB,uBAAA,EAAA,KAAA,GAAA,EAAA;2BARgB,EAAA,UAAA,KAAA,EAD9B,mBAQU,UAAA,MAAA,WAPM,QAAA,WAAO,EAAA,GAAd,QAAG;yBADZ,YAQU,iBAAA;MANP,KAAK,IAAI;MACT,OAAO,IAAI;MACZ,SAAQ;MACP,MAAM,QAAA;;6BAEQ,CAAA,gBAAA,gBAAZ,IAAI,MAAK,EAAA,EAAA,CAAA,CAAA;;;;;uBAGhB,mBAIM,OAJN,YAIM,EAAA,UAAA,KAAA,EAHJ,mBAEU,UAAA,MAAA,WAFa,QAAA,WAAO,EAAA,GAAd,QAAG;wBAAnB,YAEU,iBAAA;KAF6B,KAAK,IAAI;KAAQ,OAAO,IAAI;;4BAClD,CAAA,gBAAA,gBAAZ,IAAI,MAAK,EAAA,EAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"GrRadioGroup-DsrnTygR.js","names":["$slots"],"sources":["../../../../src/components/GrRadioGroup/GrRadioGroup.vue","../../../../src/components/GrRadioGroup/GrRadioGroup.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, provide } from 'vue'\n\nimport type { GrButtonSize } from '../GrButton'\nimport GrButtonGroup from '../GrButtonGroup/GrButtonGroup.vue'\nimport GrRadio from '../GrRadio/GrRadio.vue'\nimport { GR_RADIO_GROUP_CONTEXT } from '../GrRadio'\n\nexport type GrRadioGroupVariant = 'radiobox' | 'button'\nexport interface GrRadioGroupOption { value: string, label: string }\n\n/**\n * GrRadioGroup — контейнер группы `GrRadio`.\n *\n * Может работать как через слот (ручной рендер `GrRadio`), так и через проп `options`.\n * Предоставляет дочерним `GrRadio` общий `modelValue`/`disabled`/`size`/`name` через `inject`.\n */\nexport interface GrRadioGroupProps {\n modelValue: string\n options?: GrRadioGroupOption[]\n name?: string\n disabled?: boolean\n variant?: GrRadioGroupVariant\n size?: GrButtonSize\n ariaLabel?: string\n}\n\nconst props = withDefaults(defineProps<GrRadioGroupProps>(), {\n options: undefined,\n name: undefined,\n disabled: false,\n variant: 'radiobox',\n size: 'md',\n ariaLabel: undefined,\n})\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string): void\n}>()\n\nfunction setValue(next: string): void {\n if (props.disabled)\n return\n emit('update:modelValue', next)\n}\n\nprovide(GR_RADIO_GROUP_CONTEXT, {\n modelValue: computed(() => props.modelValue),\n name: computed(() => props.name),\n disabled: computed(() => props.disabled),\n size: computed(() => props.size),\n setValue,\n})\n</script>\n\n<template>\n <div\n data-ds-radio-group\n role=\"radiogroup\"\n :aria-label=\"ariaLabel\"\n :aria-disabled=\"disabled ? 'true' : undefined\"\n >\n <template v-if=\"$slots.default\">\n <GrButtonGroup v-if=\"variant === 'button'\">\n <slot />\n </GrButtonGroup>\n <div v-else class=\"grid gap-2\">\n <slot />\n </div>\n </template>\n <template v-else>\n <GrButtonGroup v-if=\"variant === 'button'\">\n <GrRadio\n v-for=\"opt in options ?? []\"\n :key=\"opt.value\"\n :value=\"opt.value\"\n variant=\"button\"\n :size=\"size\"\n >\n {{ opt.label }}\n </GrRadio>\n </GrButtonGroup>\n <div v-else class=\"grid gap-2\">\n <GrRadio v-for=\"opt in options ?? []\" :key=\"opt.value\" :value=\"opt.value\">\n {{ opt.label }}\n </GrRadio>\n </div>\n </template>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, provide } from 'vue'\n\nimport type { GrButtonSize } from '../GrButton'\nimport GrButtonGroup from '../GrButtonGroup/GrButtonGroup.vue'\nimport GrRadio from '../GrRadio/GrRadio.vue'\nimport { GR_RADIO_GROUP_CONTEXT } from '../GrRadio'\n\nexport type GrRadioGroupVariant = 'radiobox' | 'button'\nexport interface GrRadioGroupOption { value: string, label: string }\n\n/**\n * GrRadioGroup — контейнер группы `GrRadio`.\n *\n * Может работать как через слот (ручной рендер `GrRadio`), так и через проп `options`.\n * Предоставляет дочерним `GrRadio` общий `modelValue`/`disabled`/`size`/`name` через `inject`.\n */\nexport interface GrRadioGroupProps {\n modelValue: string\n options?: GrRadioGroupOption[]\n name?: string\n disabled?: boolean\n variant?: GrRadioGroupVariant\n size?: GrButtonSize\n ariaLabel?: string\n}\n\nconst props = withDefaults(defineProps<GrRadioGroupProps>(), {\n options: undefined,\n name: undefined,\n disabled: false,\n variant: 'radiobox',\n size: 'md',\n ariaLabel: undefined,\n})\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string): void\n}>()\n\nfunction setValue(next: string): void {\n if (props.disabled)\n return\n emit('update:modelValue', next)\n}\n\nprovide(GR_RADIO_GROUP_CONTEXT, {\n modelValue: computed(() => props.modelValue),\n name: computed(() => props.name),\n disabled: computed(() => props.disabled),\n size: computed(() => props.size),\n setValue,\n})\n</script>\n\n<template>\n <div\n data-ds-radio-group\n role=\"radiogroup\"\n :aria-label=\"ariaLabel\"\n :aria-disabled=\"disabled ? 'true' : undefined\"\n >\n <template v-if=\"$slots.default\">\n <GrButtonGroup v-if=\"variant === 'button'\">\n <slot />\n </GrButtonGroup>\n <div v-else class=\"grid gap-2\">\n <slot />\n </div>\n </template>\n <template v-else>\n <GrButtonGroup v-if=\"variant === 'button'\">\n <GrRadio\n v-for=\"opt in options ?? []\"\n :key=\"opt.value\"\n :value=\"opt.value\"\n variant=\"button\"\n :size=\"size\"\n >\n {{ opt.label }}\n </GrRadio>\n </GrButtonGroup>\n <div v-else class=\"grid gap-2\">\n <GrRadio v-for=\"opt in options ?? []\" :key=\"opt.value\" :value=\"opt.value\">\n {{ opt.label }}\n </GrRadio>\n </div>\n </template>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2BA,MAAM,QAAQ;EASd,MAAM,OAAO;EAIb,SAAS,SAAS,MAAoB;AACpC,OAAI,MAAM,SACR;AACF,QAAK,qBAAqB,KAAI;;AAGhC,UAAQ,wBAAwB;GAC9B,YAAY,eAAe,MAAM,WAAW;GAC5C,MAAM,eAAe,MAAM,KAAK;GAChC,UAAU,eAAe,MAAM,SAAS;GACxC,MAAM,eAAe,MAAM,KAAK;GAChC;GACD,CAAA;;uBAIC,mBAgCM,OAAA;IA/BJ,uBAAA;IACA,MAAK;IACJ,cAAY,QAAA;IACZ,iBAAe,QAAA,WAAQ,SAAY,KAAA;OAEpBA,KAAAA,OAAO,WAAA,WAAA,EAAvB,mBAOW,UAAA,EAAA,KAAA,GAAA,EAAA,CANY,QAAA,YAAO,YAAA,WAAA,EAA5B,YAEgB,uBAAA,EAAA,KAAA,GAAA,EAAA;2BADN,CAAR,WAAQ,KAAA,QAAA,UAAA,CAAA,CAAA;;uBAEV,mBAEM,OAFN,YAEM,CADJ,WAAQ,KAAA,QAAA,UAAA,CAAA,CAAA,EAAA,EAAA,GAAA,KAAA,WAAA,EAGZ,mBAiBW,UAAA,EAAA,KAAA,GAAA,EAAA,CAhBY,QAAA,YAAO,YAAA,WAAA,EAA5B,YAUgB,uBAAA,EAAA,KAAA,GAAA,EAAA;2BARgB,EAAA,UAAA,KAAA,EAD9B,mBAQU,UAAA,MAAA,WAPM,QAAA,WAAO,EAAA,GAAd,QAAG;yBADZ,YAQU,iBAAA;MANP,KAAK,IAAI;MACT,OAAO,IAAI;MACZ,SAAQ;MACP,MAAM,QAAA;;6BAEQ,CAAA,gBAAA,gBAAZ,IAAI,MAAK,EAAA,EAAA,CAAA,CAAA;;;;;uBAGhB,mBAIM,OAJN,YAIM,EAAA,UAAA,KAAA,EAHJ,mBAEU,UAAA,MAAA,WAFa,QAAA,WAAO,EAAA,GAAd,QAAG;wBAAnB,YAEU,iBAAA;KAF6B,KAAK,IAAI;KAAQ,OAAO,IAAI;;4BAClD,CAAA,gBAAA,gBAAZ,IAAI,MAAK,EAAA,EAAA,CAAA,CAAA"}
@@ -1,3 +1,3 @@
1
- import { t as GrRadioGroup_default } from "./chunks/GrRadioGroup-C8IcJuuF.js";
2
- import { t as grRadioGroupConfig } from "../../chunks/config-BU0olrvr.js";
1
+ import { t as GrRadioGroup_default } from "./chunks/GrRadioGroup-DsrnTygR.js";
2
+ import { t as grRadioGroupConfig } from "../../chunks/config-Bh4NWWsQ.js";
3
3
  export { GrRadioGroup_default as GrRadioGroup, GrRadioGroup_default as default, grRadioGroupConfig };
@@ -1,4 +1,4 @@
1
- import { _ as DEFAULT_AUTO_HIDE_KINDS, i as defaultResponseErrorParsers, r as createResponseErrorClassifier, t as GrResponseErrorBanner_default } from "./GrResponseErrorBanner-CzdTh4gd.js";
1
+ import { _ as DEFAULT_AUTO_HIDE_KINDS, i as defaultResponseErrorParsers, r as createResponseErrorClassifier, t as GrResponseErrorBanner_default } from "./GrResponseErrorBanner-bM8FC_Bw.js";
2
2
  import { computed, createBlock, defineComponent, openBlock, ref, shallowRef } from "vue";
3
3
  //#endregion
4
4
  //#region src/components/GrResponseErrorBanner/GrUploadErrorBanner.vue