@feugene/granularity 0.23.0 → 0.25.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 (333) hide show
  1. package/dist/chunks/config-BFJIxE8b.js +62 -0
  2. package/dist/chunks/config-BFJIxE8b.js.map +1 -0
  3. package/dist/chunks/{config-DBQQT-WP.js → config-BIa3ilQm.js} +18 -3
  4. package/dist/chunks/config-BIa3ilQm.js.map +1 -0
  5. package/dist/chunks/config-BfsBepkH.js.map +1 -0
  6. package/dist/chunks/config-BoNR7_PD.js.map +1 -0
  7. package/dist/chunks/config-BuGlNPE92.js.map +1 -0
  8. package/dist/chunks/{config-Be9k9bOf.js → config-C8tVRv8i.js} +16 -2
  9. package/dist/chunks/config-C8tVRv8i.js.map +1 -0
  10. package/dist/chunks/config-CPSxM7XE.js +8 -0
  11. package/dist/chunks/config-CPSxM7XE.js.map +1 -0
  12. package/dist/chunks/config-D7zgE_Gr.js +107 -0
  13. package/dist/chunks/config-D7zgE_Gr.js.map +1 -0
  14. package/dist/chunks/config-DAX8Deh1.js.map +1 -0
  15. package/dist/chunks/config-DGCMHPCR.js +19 -0
  16. package/dist/chunks/config-DGCMHPCR.js.map +1 -0
  17. package/dist/chunks/config-DGWFal5h.js +128 -0
  18. package/dist/chunks/config-DGWFal5h.js.map +1 -0
  19. package/dist/chunks/config-DKISz9gR.js +39 -0
  20. package/dist/chunks/config-DKISz9gR.js.map +1 -0
  21. package/dist/chunks/{config-Bm_Sovla.js → config-DYgfMrIF.js} +14 -2
  22. package/dist/chunks/config-DYgfMrIF.js.map +1 -0
  23. package/dist/chunks/{config-BSyiFlbi.js → config-DtgYuGUn2.js} +2 -1
  24. package/dist/chunks/config-DtgYuGUn2.js.map +1 -0
  25. package/dist/chunks/config-Iu684VNI.js +21 -0
  26. package/dist/chunks/config-Iu684VNI.js.map +1 -0
  27. package/dist/chunks/config-T3qdQBgU.js.map +1 -0
  28. package/dist/chunks/{config-DCwQBMmJ.js → config-rkcKArZQ.js} +27 -8
  29. package/dist/chunks/config-rkcKArZQ.js.map +1 -0
  30. package/dist/chunks/config-zjeAJ4ho2.js.map +1 -0
  31. package/dist/chunks/context-BfIQv7m12.js.map +1 -0
  32. package/dist/chunks/context-CTbuwcYs.js.map +1 -1
  33. package/dist/chunks/{en-DCCFP4qu.js → en-NpP9e7lC.js} +16 -2
  34. package/dist/chunks/en-NpP9e7lC.js.map +1 -0
  35. package/dist/chunks/{es-CT34HBVM.js → es-DaeA2Ql-.js} +16 -2
  36. package/dist/chunks/es-DaeA2Ql-.js.map +1 -0
  37. package/dist/chunks/{es-DdJsxlUr.js → es-Do2CNrC2.js} +3 -3
  38. package/dist/chunks/{es-DdJsxlUr.js.map → es-Do2CNrC2.js.map} +1 -1
  39. package/dist/chunks/{generated-CiCrGDQO.js → generated-CJe6hdiE.js} +138 -6
  40. package/dist/chunks/{generated-CiCrGDQO.js.map → generated-CJe6hdiE.js.map} +1 -1
  41. package/dist/chunks/{grBadgeStyles-C2wLlkjF.js → grBadgeStyles-C1S56Alo.js} +6 -1
  42. package/dist/chunks/{grBadgeStyles-C2wLlkjF.js.map → grBadgeStyles-C1S56Alo.js.map} +1 -1
  43. package/dist/chunks/grChipGroupContext-DZXkACap.js +4 -0
  44. package/dist/chunks/grChipGroupContext-DZXkACap.js.map +1 -0
  45. package/dist/chunks/{config-C5mO5DYZ.js → grDropdownMenuStyles-D1LOkdVj.js} +1 -38
  46. package/dist/chunks/grDropdownMenuStyles-D1LOkdVj.js.map +1 -0
  47. package/dist/chunks/{grPopoverStyles-Rz_Z5nLW.js → grPopoverStyles-Cke_BZsM.js} +16 -3
  48. package/dist/chunks/grPopoverStyles-Cke_BZsM.js.map +1 -0
  49. package/dist/chunks/{granular-provider-CQKhl5C_.js → granular-provider-BaHkLjFX.js} +26 -16
  50. package/dist/chunks/granular-provider-BaHkLjFX.js.map +1 -0
  51. package/dist/chunks/{ru-CLiAMwrx.js → ru-Bg9-DPmg.js} +16 -2
  52. package/dist/chunks/ru-Bg9-DPmg.js.map +1 -0
  53. package/dist/chunks/{config-qVg3Zz_A.js → safelist-DOfCQR5O.js} +2 -19
  54. package/dist/chunks/safelist-DOfCQR5O.js.map +1 -0
  55. package/dist/chunks/useMenuItemsFocus-OyOnIAlr.js +117 -0
  56. package/dist/chunks/useMenuItemsFocus-OyOnIAlr.js.map +1 -0
  57. package/dist/components/GrAutocomplete/chunks/{GrAutocomplete-DsevPtiS.js → GrAutocomplete-D9c9BNFg.js} +1 -1
  58. package/dist/components/GrAutocomplete/chunks/{GrAutocomplete-DsevPtiS.js.map → GrAutocomplete-D9c9BNFg.js.map} +1 -1
  59. package/dist/components/GrAutocomplete/index.js +1 -1
  60. package/dist/components/GrBadge/chunks/{GrBadge-u2ZdS7CN.js → GrBadge-_9rCHuE1.js} +1 -1
  61. package/dist/components/GrBadge/chunks/{GrBadge-u2ZdS7CN.js.map → GrBadge-_9rCHuE1.js.map} +1 -1
  62. package/dist/components/GrBadge/index.js +3 -2
  63. package/dist/components/GrButton/chunks/{GrButton-Bw2AH4uX.js → GrButton-DCz-Wn-V.js} +1 -1
  64. package/dist/components/GrButton/chunks/{GrButton-Bw2AH4uX.js.map → GrButton-DCz-Wn-V.js.map} +1 -1
  65. package/dist/components/GrButton/index.js +1 -1
  66. package/dist/components/GrButtonGroup/chunks/{GrButtonGroup-CKyiAV8K.js → GrButtonGroup-BQo5VQ_c.js} +1 -1
  67. package/dist/components/GrButtonGroup/chunks/{GrButtonGroup-CKyiAV8K.js.map → GrButtonGroup-BQo5VQ_c.js.map} +1 -1
  68. package/dist/components/GrButtonGroup/index.js +2 -2
  69. package/dist/components/GrCard/chunks/{GrCard-Bc7nRfbe.js → GrCard-aQIjk6I9.js} +9 -3
  70. package/dist/components/GrCard/chunks/GrCard-aQIjk6I9.js.map +1 -0
  71. package/dist/components/GrCard/index.js +2 -2
  72. package/dist/components/GrCheckboxGroup/index.js +1 -1
  73. package/dist/components/GrChip/chunks/GrChip-BnL2FedO.js +222 -0
  74. package/dist/components/GrChip/chunks/GrChip-BnL2FedO.js.map +1 -0
  75. package/dist/components/GrChip/index.js +3 -0
  76. package/dist/components/GrChipGroup/chunks/GrChipGroup-DefmSdY9.js +209 -0
  77. package/dist/components/GrChipGroup/chunks/GrChipGroup-DefmSdY9.js.map +1 -0
  78. package/dist/components/GrChipGroup/index.js +3 -0
  79. package/dist/components/GrCodeBlock/chunks/{GrCodeBlock-BmXCLgLS.js → GrCodeBlock-CyptiEo4.js} +1 -1
  80. package/dist/components/GrCodeBlock/chunks/{GrCodeBlock-BmXCLgLS.js.map → GrCodeBlock-CyptiEo4.js.map} +1 -1
  81. package/dist/components/GrCodeBlock/index.js +1 -1
  82. package/dist/components/GrCollapse/chunks/{GrCollapse-C1rCfbc0.js → GrCollapse-DUROgAgc.js} +1 -1
  83. package/dist/components/GrCollapse/chunks/{GrCollapse-C1rCfbc0.js.map → GrCollapse-DUROgAgc.js.map} +1 -1
  84. package/dist/components/GrCollapse/index.js +1 -1
  85. package/dist/components/GrColorPicker/chunks/{GrColorPicker-qQdoEPHF.js → GrColorPicker-CDaJRVIM.js} +1 -1
  86. package/dist/components/GrColorPicker/chunks/{GrColorPicker-qQdoEPHF.js.map → GrColorPicker-CDaJRVIM.js.map} +1 -1
  87. package/dist/components/GrColorPicker/index.js +1 -1
  88. package/dist/components/GrCommandPalette/chunks/{GrCommandPalette-BFcMf4Pn.js → GrCommandPalette-BPsVN_XU.js} +3 -3
  89. package/dist/components/GrCommandPalette/chunks/GrCommandPalette-BPsVN_XU.js.map +1 -0
  90. package/dist/components/GrCommandPalette/index.js +1 -1
  91. package/dist/components/GrCommandPalette/styles.css +1 -1
  92. package/dist/components/GrConfigProvider/chunks/{GrConfigProvider-UP-EaoAf.js → GrConfigProvider-BF7R3hgg.js} +1 -1
  93. package/dist/components/GrConfigProvider/chunks/GrConfigProvider-BF7R3hgg.js.map +1 -0
  94. package/dist/components/GrConfigProvider/index.js +1 -1
  95. package/dist/components/GrConfirmDialog/chunks/{GrConfirmDialog-rRtMScJX.js → GrConfirmDialog-CwXNLyzk.js} +3 -3
  96. package/dist/components/GrConfirmDialog/chunks/{GrConfirmDialog-rRtMScJX.js.map → GrConfirmDialog-CwXNLyzk.js.map} +1 -1
  97. package/dist/components/GrConfirmDialog/index.js +1 -1
  98. package/dist/components/GrContextMenu/chunks/GrContextMenu-BbAJholy.js +331 -0
  99. package/dist/components/GrContextMenu/chunks/GrContextMenu-BbAJholy.js.map +1 -0
  100. package/dist/components/GrContextMenu/index.js +3 -0
  101. package/dist/components/GrDataTable/chunks/{GrDataTable-B5MmZFUg.js → GrDataTable-NRbrXpdx.js} +2 -2
  102. package/dist/components/GrDataTable/chunks/GrDataTable-NRbrXpdx.js.map +1 -0
  103. package/dist/components/GrDataTable/index.js +1 -1
  104. package/dist/components/GrDelta/chunks/{GrDelta-DFvxNpmN.js → GrDelta-NE5HhXoo.js} +0 -0
  105. package/dist/components/GrDelta/chunks/GrDelta-NE5HhXoo.js.map +1 -0
  106. package/dist/components/GrDelta/index.js +2 -2
  107. package/dist/components/GrDescriptionList/chunks/{GrDescriptionList-2zFXzX83.js → GrDescriptionList-1mICfrqX.js} +8 -4
  108. package/dist/components/GrDescriptionList/chunks/GrDescriptionList-1mICfrqX.js.map +1 -0
  109. package/dist/components/GrDescriptionList/index.js +2 -2
  110. package/dist/components/GrDialog/chunks/{GrDialog-D0U5iRqV.js → GrDialog-5Y5K87ss.js} +2 -2
  111. package/dist/components/GrDialog/chunks/{GrDialog-D0U5iRqV.js.map → GrDialog-5Y5K87ss.js.map} +1 -1
  112. package/dist/components/GrDialog/index.js +1 -1
  113. package/dist/components/GrDialogService/chunks/{GrDialogService-CrwA4aJq.js → GrDialogService-CHhzGRWy.js} +6 -6
  114. package/dist/components/GrDialogService/chunks/GrDialogService-CHhzGRWy.js.map +1 -0
  115. package/dist/components/GrDialogService/index.js +1 -1
  116. package/dist/components/GrDrawer/chunks/{GrDrawer-C3zAg2tG.js → GrDrawer-CXy3-SVd.js} +2 -2
  117. package/dist/components/GrDrawer/chunks/GrDrawer-CXy3-SVd.js.map +1 -0
  118. package/dist/components/GrDrawer/index.js +1 -1
  119. package/dist/components/GrDropdown/chunks/{GrDropdown-BSfFOcDx.js → GrDropdown-BfTmdPyh.js} +10 -79
  120. package/dist/components/GrDropdown/chunks/GrDropdown-BfTmdPyh.js.map +1 -0
  121. package/dist/components/GrDropdown/index.js +1 -1
  122. package/dist/components/GrDropdownMenu/chunks/GrDropdownMenu-l5HEqzjr.js +130 -0
  123. package/dist/components/GrDropdownMenu/chunks/GrDropdownMenu-l5HEqzjr.js.map +1 -0
  124. package/dist/components/GrDropdownMenu/chunks/{GrDropdownMenu-DyS6dWDp.js → GrDropdownMenuList-BGA_xNVo.js} +57 -159
  125. package/dist/components/GrDropdownMenu/chunks/GrDropdownMenuList-BGA_xNVo.js.map +1 -0
  126. package/dist/components/GrDropdownMenu/index.js +3 -2
  127. package/dist/components/GrFileUpload/chunks/{GrFileUpload-D3-vC-ap.js → GrFileUpload-wNXzHb5N.js} +1 -1
  128. package/dist/components/GrFileUpload/chunks/GrFileUpload-wNXzHb5N.js.map +1 -0
  129. package/dist/components/GrFileUpload/index.js +1 -1
  130. package/dist/components/GrFormField/chunks/{GrFormField-kqfVY30N.js → GrFormField-DSylU7IU.js} +1 -1
  131. package/dist/components/GrFormField/chunks/GrFormField-DSylU7IU.js.map +1 -0
  132. package/dist/components/GrFormField/index.js +1 -1
  133. package/dist/components/GrFormFile/chunks/{GrFormFile-D722xHn8.js → GrFormFile-DhVkB2gm.js} +1 -1
  134. package/dist/components/GrFormFile/chunks/{GrFormFile-D722xHn8.js.map → GrFormFile-DhVkB2gm.js.map} +1 -1
  135. package/dist/components/GrFormFile/index.js +1 -1
  136. package/dist/components/GrInputTag/chunks/{GrInputTag-C7QVPijj.js → GrInputTag-UI8kIB_F.js} +2 -2
  137. package/dist/components/GrInputTag/chunks/{GrInputTag-C7QVPijj.js.map → GrInputTag-UI8kIB_F.js.map} +1 -1
  138. package/dist/components/GrInputTag/index.js +1 -1
  139. package/dist/components/GrJsonViewer/chunks/{GrJsonViewer-DFUppRNb.js → GrJsonViewer-jk3ylOTc.js} +2 -2
  140. package/dist/components/GrJsonViewer/chunks/GrJsonViewer-jk3ylOTc.js.map +1 -0
  141. package/dist/components/GrJsonViewer/index.js +1 -1
  142. package/dist/components/GrList/chunks/{GrList-BRYhpqIe.js → GrList-B5bclmHV.js} +30 -3
  143. package/dist/components/GrList/chunks/GrList-B5bclmHV.js.map +1 -0
  144. package/dist/components/GrList/index.js +1 -1
  145. package/dist/components/GrList/styles.css +1 -1
  146. package/dist/components/GrLoading/chunks/{GrLoading-C3DZSSuh.js → GrLoading-DeBFTvFX.js} +1 -1
  147. package/dist/components/GrLoading/chunks/GrLoading-DeBFTvFX.js.map +1 -0
  148. package/dist/components/GrLoading/index.js +1 -1
  149. package/dist/components/GrModal/chunks/{GrModal-CPz7SWD_.js → GrModal-CCoWZuIl.js} +2 -2
  150. package/dist/components/GrModal/chunks/GrModal-CCoWZuIl.js.map +1 -0
  151. package/dist/components/GrModal/index.js +1 -1
  152. package/dist/components/GrNavbar/chunks/{GrNavbar-DWaaoV7n.js → GrNavbar-DPj30sHX.js} +1 -1
  153. package/dist/components/GrNavbar/chunks/{GrNavbar-DWaaoV7n.js.map → GrNavbar-DPj30sHX.js.map} +1 -1
  154. package/dist/components/GrNavbar/index.js +1 -1
  155. package/dist/components/GrNumberInput/chunks/{GrNumberInput-BotnzW77.js → GrNumberInput-V2mZvDDC.js} +1 -1
  156. package/dist/components/GrNumberInput/chunks/{GrNumberInput-BotnzW77.js.map → GrNumberInput-V2mZvDDC.js.map} +1 -1
  157. package/dist/components/GrNumberInput/index.js +2 -2
  158. package/dist/components/GrPagination/chunks/{GrPagination-GtGtSMJG.js → GrPagination-DG7kp6VL.js} +2 -2
  159. package/dist/components/GrPagination/chunks/{GrPagination-GtGtSMJG.js.map → GrPagination-DG7kp6VL.js.map} +1 -1
  160. package/dist/components/GrPagination/index.js +1 -1
  161. package/dist/components/GrPopover/chunks/{GrPopover-b70bIlQ9.js → GrPopover-DDChM1jD.js} +28 -10
  162. package/dist/components/GrPopover/chunks/GrPopover-DDChM1jD.js.map +1 -0
  163. package/dist/components/GrPopover/index.js +2 -2
  164. package/dist/components/GrPromptDialog/chunks/{GrPromptDialog-CEI8bf-t.js → GrPromptDialog-DjF-5oD9.js} +4 -4
  165. package/dist/components/GrPromptDialog/chunks/{GrPromptDialog-CEI8bf-t.js.map → GrPromptDialog-DjF-5oD9.js.map} +1 -1
  166. package/dist/components/GrPromptDialog/index.js +1 -1
  167. package/dist/components/GrRadioGroup/chunks/{GrRadioGroup-BVmjKXcv.js → GrRadioGroup-7w4bXIg_.js} +1 -1
  168. package/dist/components/GrRadioGroup/chunks/{GrRadioGroup-BVmjKXcv.js.map → GrRadioGroup-7w4bXIg_.js.map} +1 -1
  169. package/dist/components/GrRadioGroup/index.js +1 -1
  170. package/dist/components/GrResponseErrorBanner/chunks/{GrResponseErrorBanner-CZONq8uT.js → GrResponseErrorBanner-BhP-xw2P.js} +1 -1
  171. package/dist/components/GrResponseErrorBanner/chunks/{GrResponseErrorBanner-CZONq8uT.js.map → GrResponseErrorBanner-BhP-xw2P.js.map} +1 -1
  172. package/dist/components/GrResponseErrorBanner/chunks/{GrResponseErrorBanner-CgfAwlg3.js → GrResponseErrorBanner-DA4q90Zt.js} +1 -1
  173. package/dist/components/GrResponseErrorBanner/chunks/{GrResponseErrorBanner-CgfAwlg3.js.map → GrResponseErrorBanner-DA4q90Zt.js.map} +1 -1
  174. package/dist/components/GrResponseErrorBanner/index.js +2 -2
  175. package/dist/components/GrSegmented/chunks/{GrSegmented-D1mjxF_O.js → GrSegmented-DKpo3cnC.js} +30 -5
  176. package/dist/components/GrSegmented/chunks/GrSegmented-DKpo3cnC.js.map +1 -0
  177. package/dist/components/GrSegmented/index.js +1 -1
  178. package/dist/components/GrSelect/chunks/{GrSelect-CaGuyvtb.js → GrSelect-BA1wfX3c.js} +19 -3
  179. package/dist/components/GrSelect/chunks/GrSelect-BA1wfX3c.js.map +1 -0
  180. package/dist/components/GrSelect/index.js +1 -1
  181. package/dist/components/GrSelect/styles.css +1 -1
  182. package/dist/components/GrSidebar/chunks/{GrSidebar-D7WxRtIu.js → GrSidebar-DY-LgIbS.js} +2 -2
  183. package/dist/components/GrSidebar/chunks/{GrSidebar-D7WxRtIu.js.map → GrSidebar-DY-LgIbS.js.map} +1 -1
  184. package/dist/components/GrSidebar/index.js +2 -2
  185. package/dist/components/GrSlider/index.js +1 -1
  186. package/dist/components/GrSortableList/chunks/{GrSortableList-DPjxilmN.js → GrSortableList-BMXyxmRc.js} +3 -3
  187. package/dist/components/GrSortableList/chunks/{GrSortableList-DPjxilmN.js.map → GrSortableList-BMXyxmRc.js.map} +1 -1
  188. package/dist/components/GrSortableList/index.js +2 -2
  189. package/dist/components/GrStatistic/chunks/{GrStatistic-C7wQECeS.js → GrStatistic-BJQv5aOS.js} +41 -26
  190. package/dist/components/GrStatistic/chunks/GrStatistic-BJQv5aOS.js.map +1 -0
  191. package/dist/components/GrStatistic/index.js +2 -2
  192. package/dist/components/GrSteps/chunks/GrSteps-Cce4rfr3.js +282 -0
  193. package/dist/components/GrSteps/chunks/GrSteps-Cce4rfr3.js.map +1 -0
  194. package/dist/components/GrSteps/index.js +3 -0
  195. package/dist/components/GrSwitch/chunks/{GrSwitch-x_vQQ6ao.js → GrSwitch-CHiIj9GT.js} +1 -1
  196. package/dist/components/GrSwitch/chunks/{GrSwitch-x_vQQ6ao.js.map → GrSwitch-CHiIj9GT.js.map} +1 -1
  197. package/dist/components/GrSwitch/index.js +2 -2
  198. package/dist/components/GrTabPanels/chunks/{GrTabPanels-AJt1w1XC.js → GrTabPanels-BZQS8-JM.js} +12 -1
  199. package/dist/components/GrTabPanels/chunks/{GrTabPanels-AJt1w1XC.js.map → GrTabPanels-BZQS8-JM.js.map} +1 -1
  200. package/dist/components/GrTabPanels/index.js +1 -1
  201. package/dist/components/GrTimeline/chunks/{GrTimeline-Ch9sHzwL.js → GrTimeline-DIDdkTn7.js} +12 -1
  202. package/dist/components/GrTimeline/chunks/GrTimeline-DIDdkTn7.js.map +1 -0
  203. package/dist/components/GrTimeline/index.js +1 -1
  204. package/dist/components/GrToaster/chunks/{GrToaster-DJUzx3sR.js → GrToaster-CC49q3a4.js} +1 -1
  205. package/dist/components/GrToaster/chunks/{GrToaster-DJUzx3sR.js.map → GrToaster-CC49q3a4.js.map} +1 -1
  206. package/dist/components/GrToaster/index.js +1 -1
  207. package/dist/components/GrTree/chunks/{GrTree-BvOeQ3xJ.js.map → GrTree-J5q8aCya.js.map} +1 -1
  208. package/dist/components/GrTree/index.js +1 -1
  209. package/dist/components/GrTreeSelect/chunks/{GrTreeSelect-_LjTRR7X.js → GrTreeSelect-DEfxWAc3.js} +1 -1
  210. package/dist/components/GrTreeSelect/chunks/{GrTreeSelect-_LjTRR7X.js.map → GrTreeSelect-DEfxWAc3.js.map} +1 -1
  211. package/dist/components/GrTreeSelect/index.js +1 -1
  212. package/dist/components/GrValue/chunks/GrValue-CZsuZ4x-.js +38 -0
  213. package/dist/components/GrValue/chunks/GrValue-CZsuZ4x-.js.map +1 -0
  214. package/dist/components/GrValue/index.js +3 -0
  215. package/dist/composables/useFloating.js +47 -7
  216. package/dist/composables/useFloating.js.map +1 -1
  217. package/dist/composables/useTheme.js.map +1 -1
  218. package/dist/composables/useToast.js.map +1 -1
  219. package/dist/directives/loading.js +1 -1
  220. package/dist/granular-provider-node.js +1 -1
  221. package/dist/granular-provider.js +1 -1
  222. package/dist/i18n/all.js +1 -1
  223. package/dist/i18n/index.js +1 -1
  224. package/dist/index.js +74 -62
  225. package/dist/styles/themes/dark.css +11 -6
  226. package/dist/styles/themes/light.css +5 -0
  227. package/dist/theme.js +1 -1
  228. package/dist/tokens.js +1 -1
  229. package/dist/types/components/GrBadge/grBadgeStyles.d.ts +7 -0
  230. package/dist/types/components/GrCard/GrCard.vue.d.ts +1 -1
  231. package/dist/types/components/GrCard/grCardStyles.d.ts +11 -0
  232. package/dist/types/components/GrChip/GrChip.vue.d.ts +118 -0
  233. package/dist/types/components/GrChip/config.d.ts +1 -0
  234. package/dist/types/components/GrChip/defaults.d.ts +16 -0
  235. package/dist/types/components/GrChip/grChipGroupContext.d.ts +52 -0
  236. package/dist/types/components/GrChip/grChipStyles.d.ts +64 -0
  237. package/dist/types/components/GrChip/index.d.ts +11 -0
  238. package/dist/types/components/GrChip/safelist.d.ts +7 -0
  239. package/dist/types/components/GrChipGroup/GrChipGroup.vue.d.ts +128 -0
  240. package/dist/types/components/GrChipGroup/config.d.ts +1 -0
  241. package/dist/types/components/GrChipGroup/defaults.d.ts +13 -0
  242. package/dist/types/components/GrChipGroup/grChipGroupStyles.d.ts +7 -0
  243. package/dist/types/components/GrChipGroup/index.d.ts +9 -0
  244. package/dist/types/components/GrChipGroup/safelist.d.ts +1 -0
  245. package/dist/types/components/GrContextMenu/GrContextMenu.vue.d.ts +157 -0
  246. package/dist/types/components/GrContextMenu/config.d.ts +1 -0
  247. package/dist/types/components/GrContextMenu/contextMenuAnchor.d.ts +29 -0
  248. package/dist/types/components/GrContextMenu/index.d.ts +7 -0
  249. package/dist/types/components/GrDataTable/GrDataTable.vue.d.ts +1 -1
  250. package/dist/types/components/GrDelta/grDeltaStyles.d.ts +13 -1
  251. package/dist/types/components/GrDescriptionList/grDescriptionListStyles.d.ts +29 -1
  252. package/dist/types/components/GrDropdownMenu/GrDropdownMenu.vue.d.ts +3 -3
  253. package/dist/types/components/GrDropdownMenu/GrDropdownMenuEntries.vue.d.ts +22 -0
  254. package/dist/types/components/GrFilePreview/GrFilePreview.vue.d.ts +1 -1
  255. package/dist/types/components/GrList/GrListItem.vue.d.ts +1 -1
  256. package/dist/types/components/GrPopover/GrPopover.vue.d.ts +21 -2
  257. package/dist/types/components/GrPopover/grPopoverStyles.d.ts +11 -1
  258. package/dist/types/components/GrPopover/index.d.ts +1 -1
  259. package/dist/types/components/GrStatistic/GrStatistic.vue.d.ts +6 -6
  260. package/dist/types/components/GrStatistic/grStatisticStyles.d.ts +9 -0
  261. package/dist/types/components/GrSteps/GrSteps.vue.d.ts +118 -0
  262. package/dist/types/components/GrSteps/config.d.ts +1 -0
  263. package/dist/types/components/GrSteps/defaults.d.ts +18 -0
  264. package/dist/types/components/GrSteps/grStepsStyles.d.ts +63 -0
  265. package/dist/types/components/GrSteps/index.d.ts +11 -0
  266. package/dist/types/components/GrSteps/safelist.d.ts +1 -0
  267. package/dist/types/components/GrSteps/stepsModel.d.ts +57 -0
  268. package/dist/types/components/GrValue/GrValue.vue.d.ts +51 -0
  269. package/dist/types/components/GrValue/config.d.ts +1 -0
  270. package/dist/types/components/GrValue/grValueStyles.d.ts +34 -0
  271. package/dist/types/components/GrValue/index.d.ts +5 -0
  272. package/dist/types/components/GrValue/safelist.d.ts +1 -0
  273. package/dist/types/components/shared/truncationTitle.d.ts +16 -0
  274. package/dist/types/composables/internal/useMenuItemsFocus.d.ts +24 -0
  275. package/dist/types/composables/internal/useTypeahead.d.ts +30 -0
  276. package/dist/types/composables/useFloating.d.ts +33 -2
  277. package/dist/types/granular-provider/shared.d.ts +5 -0
  278. package/dist/types/i18n/messages/en.d.ts +26 -0
  279. package/dist/types/i18n/messages/es.d.ts +26 -0
  280. package/dist/types/i18n/messages/ru.d.ts +26 -0
  281. package/dist/types/index.d.ts +6 -0
  282. package/dist/web-types.json +799 -195
  283. package/package.json +22 -2
  284. package/tokens/themes/dark.json +26 -6
  285. package/tokens/themes/light.json +20 -0
  286. package/dist/chunks/config-BSyiFlbi.js.map +0 -1
  287. package/dist/chunks/config-Be9k9bOf.js.map +0 -1
  288. package/dist/chunks/config-BfsBepkH2.js.map +0 -1
  289. package/dist/chunks/config-Bm_Sovla.js.map +0 -1
  290. package/dist/chunks/config-BoNR7_PD2.js.map +0 -1
  291. package/dist/chunks/config-BuGlNPE9.js.map +0 -1
  292. package/dist/chunks/config-C5mO5DYZ.js.map +0 -1
  293. package/dist/chunks/config-DAX8Deh12.js.map +0 -1
  294. package/dist/chunks/config-DBQQT-WP.js.map +0 -1
  295. package/dist/chunks/config-DCwQBMmJ.js.map +0 -1
  296. package/dist/chunks/config-T3qdQBgU2.js.map +0 -1
  297. package/dist/chunks/config-qVg3Zz_A.js.map +0 -1
  298. package/dist/chunks/config-zjeAJ4ho.js.map +0 -1
  299. package/dist/chunks/context-BfIQv7m1.js.map +0 -1
  300. package/dist/chunks/en-DCCFP4qu.js.map +0 -1
  301. package/dist/chunks/es-CT34HBVM.js.map +0 -1
  302. package/dist/chunks/grPopoverStyles-Rz_Z5nLW.js.map +0 -1
  303. package/dist/chunks/granular-provider-CQKhl5C_.js.map +0 -1
  304. package/dist/chunks/ru-CLiAMwrx.js.map +0 -1
  305. package/dist/components/GrCard/chunks/GrCard-Bc7nRfbe.js.map +0 -1
  306. package/dist/components/GrCommandPalette/chunks/GrCommandPalette-BFcMf4Pn.js.map +0 -1
  307. package/dist/components/GrConfigProvider/chunks/GrConfigProvider-UP-EaoAf.js.map +0 -1
  308. package/dist/components/GrDataTable/chunks/GrDataTable-B5MmZFUg.js.map +0 -1
  309. package/dist/components/GrDelta/chunks/GrDelta-DFvxNpmN.js.map +0 -1
  310. package/dist/components/GrDescriptionList/chunks/GrDescriptionList-2zFXzX83.js.map +0 -1
  311. package/dist/components/GrDialogService/chunks/GrDialogService-CrwA4aJq.js.map +0 -1
  312. package/dist/components/GrDrawer/chunks/GrDrawer-C3zAg2tG.js.map +0 -1
  313. package/dist/components/GrDropdown/chunks/GrDropdown-BSfFOcDx.js.map +0 -1
  314. package/dist/components/GrDropdownMenu/chunks/GrDropdownMenu-DyS6dWDp.js.map +0 -1
  315. package/dist/components/GrFileUpload/chunks/GrFileUpload-D3-vC-ap.js.map +0 -1
  316. package/dist/components/GrFormField/chunks/GrFormField-kqfVY30N.js.map +0 -1
  317. package/dist/components/GrJsonViewer/chunks/GrJsonViewer-DFUppRNb.js.map +0 -1
  318. package/dist/components/GrList/chunks/GrList-BRYhpqIe.js.map +0 -1
  319. package/dist/components/GrLoading/chunks/GrLoading-C3DZSSuh.js.map +0 -1
  320. package/dist/components/GrModal/chunks/GrModal-CPz7SWD_.js.map +0 -1
  321. package/dist/components/GrPopover/chunks/GrPopover-b70bIlQ9.js.map +0 -1
  322. package/dist/components/GrSegmented/chunks/GrSegmented-D1mjxF_O.js.map +0 -1
  323. package/dist/components/GrSelect/chunks/GrSelect-CaGuyvtb.js.map +0 -1
  324. package/dist/components/GrStatistic/chunks/GrStatistic-C7wQECeS.js.map +0 -1
  325. package/dist/components/GrTimeline/chunks/GrTimeline-Ch9sHzwL.js.map +0 -1
  326. package/dist/chunks/{config-BfsBepkH2.js → config-BfsBepkH.js} +0 -0
  327. package/dist/chunks/{config-BoNR7_PD2.js → config-BoNR7_PD.js} +0 -0
  328. package/dist/chunks/{config-BuGlNPE9.js → config-BuGlNPE92.js} +0 -0
  329. package/dist/chunks/{config-DAX8Deh12.js → config-DAX8Deh1.js} +0 -0
  330. package/dist/chunks/{config-T3qdQBgU2.js → config-T3qdQBgU.js} +0 -0
  331. package/dist/chunks/{config-zjeAJ4ho.js → config-zjeAJ4ho2.js} +0 -0
  332. package/dist/chunks/{context-BfIQv7m1.js → context-BfIQv7m12.js} +0 -0
  333. package/dist/components/GrTree/chunks/{GrTree-BvOeQ3xJ.js → GrTree-J5q8aCya.js} +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"GrDialog-D0U5iRqV.js","names":["$emit","$emit"],"sources":["../../../../src/components/GrDialog/GrDialogFooter.vue","../../../../src/components/GrDialog/GrDialogFooter.vue","../../../../src/components/GrDialog/GrDialogCloseButton.vue","../../../../src/components/GrDialog/GrDialogCloseButton.vue","../../../../src/components/GrDialog/GrDialogHeader.vue","../../../../src/components/GrDialog/GrDialogHeader.vue","../../../../src/components/GrDialog/GrDialog.vue","../../../../src/components/GrDialog/GrDialog.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport {\n DEFAULT_GR_DIALOG_FOOTER_CONFIG,\n resolveGrDialogSectionConfig,\n type GrDialogSectionConfig,\n} from './dialogShared'\n\nexport interface GrDialogFooterProps {\n config?: GrDialogSectionConfig\n}\n\nconst props = withDefaults(defineProps<GrDialogFooterProps>(), {\n config: undefined,\n})\n\nconst resolvedConfig = computed(() => resolveGrDialogSectionConfig(props.config, DEFAULT_GR_DIALOG_FOOTER_CONFIG))\n\nconst rootClass = computed(() => [\n resolvedConfig.value.paddingX,\n resolvedConfig.value.paddingY,\n resolvedConfig.value.bordered ? 'border-t border-[var(--gr-brd)]' : '',\n])\n</script>\n\n<template>\n <div data-gr-dialog-footer :class=\"rootClass\">\n <slot />\n </div>\n</template>","<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport {\n DEFAULT_GR_DIALOG_FOOTER_CONFIG,\n resolveGrDialogSectionConfig,\n type GrDialogSectionConfig,\n} from './dialogShared'\n\nexport interface GrDialogFooterProps {\n config?: GrDialogSectionConfig\n}\n\nconst props = withDefaults(defineProps<GrDialogFooterProps>(), {\n config: undefined,\n})\n\nconst resolvedConfig = computed(() => resolveGrDialogSectionConfig(props.config, DEFAULT_GR_DIALOG_FOOTER_CONFIG))\n\nconst rootClass = computed(() => [\n resolvedConfig.value.paddingX,\n resolvedConfig.value.paddingY,\n resolvedConfig.value.bordered ? 'border-t border-[var(--gr-brd)]' : '',\n])\n</script>\n\n<template>\n <div data-gr-dialog-footer :class=\"rootClass\">\n <slot />\n </div>\n</template>","<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue'\n\nimport GrButton from '../GrButton/GrButton.vue'\nimport IconClose from '~icons/lucide/x'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\n\nexport interface GrDialogCloseButtonEmits {\n (e: 'click'): void\n}\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst { t } = useGranularityTranslations()\n\n// A11y-лейбл: берём из атрибутов (родитель прокидывает `:aria-label=\"closeLabel\"`)\n// или используем i18n-дефолт. Не хардкодим английское \"Close\" — GR должен быть i18n-friendly.\nconst attrs = useAttrs()\nconst ariaLabel = computed(() => (attrs['aria-label'] as string | undefined) ?? t('gr.common.close', 'Close'))\n\ndefineEmits<GrDialogCloseButtonEmits>()\n</script>\n\n<template>\n <GrButton\n v-bind=\"attrs\"\n data-gr-dialog-close\n variant=\"ghost\"\n size=\"sm\"\n square\n :aria-label=\"ariaLabel\"\n @click=\"$emit('click')\"\n >\n <IconClose class=\"h-4 w-4\" aria-hidden=\"true\" />\n </GrButton>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue'\n\nimport GrButton from '../GrButton/GrButton.vue'\nimport IconClose from '~icons/lucide/x'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\n\nexport interface GrDialogCloseButtonEmits {\n (e: 'click'): void\n}\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst { t } = useGranularityTranslations()\n\n// A11y-лейбл: берём из атрибутов (родитель прокидывает `:aria-label=\"closeLabel\"`)\n// или используем i18n-дефолт. Не хардкодим английское \"Close\" — GR должен быть i18n-friendly.\nconst attrs = useAttrs()\nconst ariaLabel = computed(() => (attrs['aria-label'] as string | undefined) ?? t('gr.common.close', 'Close'))\n\ndefineEmits<GrDialogCloseButtonEmits>()\n</script>\n\n<template>\n <GrButton\n v-bind=\"attrs\"\n data-gr-dialog-close\n variant=\"ghost\"\n size=\"sm\"\n square\n :aria-label=\"ariaLabel\"\n @click=\"$emit('click')\"\n >\n <IconClose class=\"h-4 w-4\" aria-hidden=\"true\" />\n </GrButton>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport GrDialogCloseButton from './GrDialogCloseButton.vue'\nimport { useGrModalTitle } from '../GrModal/context'\nimport {\n DEFAULT_GR_DIALOG_HEADER_CONFIG,\n type GrDialogSectionConfig,\n resolveGrDialogSectionConfig,\n resolveGrDialogTitle,\n} from './dialogShared'\n\nexport interface GrDialogHeaderProps {\n title?: string\n showCloseButton?: boolean\n config?: GrDialogSectionConfig\n /** A11y-лейбл кнопки закрытия (i18n). */\n closeLabel?: string\n}\n\nexport interface GrDialogHeaderEmits {\n (e: 'close'): void\n}\n\nconst props = withDefaults(defineProps<GrDialogHeaderProps>(), {\n title: undefined,\n showCloseButton: true,\n config: undefined,\n closeLabel: undefined,\n})\n\nconst slots = defineSlots<{\n default?: (props: { title?: string }) => any\n}>()\n\ndefineEmits<GrDialogHeaderEmits>()\n\nconst resolvedTitle = computed(() => resolveGrDialogTitle(props.title))\n\nconst resolvedConfig = computed(() =>\n resolveGrDialogSectionConfig(props.config, DEFAULT_GR_DIALOG_HEADER_CONFIG),\n)\n\nconst rootClass = computed(() => [\n resolvedConfig.value.paddingX,\n resolvedConfig.value.paddingY,\n resolvedConfig.value.bordered ? 'border-b border-[var(--gr-brd)]' : '',\n 'flex items-center justify-between gap-4',\n])\n\n// Видимый заголовок рендерим только когда нет пользовательского слота:\n// если слот `#header` задан, a11y-title отдаётся через `GrModal #title`\n// на уровне `GrDialog` (см. JSDoc у `GrDialog.vue`).\nconst showVisibleTitle = computed(() => !slots.default && !!resolvedTitle.value)\n\n// Имя окна: заголовок объявляет себя окну, и `GrModal` ставит на него\n// `aria-labelledby`. Вне `GrModal` регистрация — no-op, шапку можно\n// использовать и отдельно.\nconst { titleId } = useGrModalTitle(() => showVisibleTitle.value)\n</script>\n\n<template>\n <div data-gr-dialog-header :class=\"rootClass\">\n <template v-if=\"slots.default\">\n <div class=\"flex-1 min-w-0 flex items-center\">\n <slot :title=\"resolvedTitle\" />\n </div>\n </template>\n <div\n v-else-if=\"showVisibleTitle\"\n :id=\"titleId\"\n data-gr-dialog-title\n class=\"flex-1 min-w-0 text-[length:var(--gr-control-text-md)] font-700\"\n >\n {{ resolvedTitle }}\n </div>\n <div v-else class=\"flex-1 min-w-0\" />\n <GrDialogCloseButton\n v-if=\"showCloseButton\"\n :aria-label=\"closeLabel\"\n @click=\"$emit('close')\"\n />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport GrDialogCloseButton from './GrDialogCloseButton.vue'\nimport { useGrModalTitle } from '../GrModal/context'\nimport {\n DEFAULT_GR_DIALOG_HEADER_CONFIG,\n type GrDialogSectionConfig,\n resolveGrDialogSectionConfig,\n resolveGrDialogTitle,\n} from './dialogShared'\n\nexport interface GrDialogHeaderProps {\n title?: string\n showCloseButton?: boolean\n config?: GrDialogSectionConfig\n /** A11y-лейбл кнопки закрытия (i18n). */\n closeLabel?: string\n}\n\nexport interface GrDialogHeaderEmits {\n (e: 'close'): void\n}\n\nconst props = withDefaults(defineProps<GrDialogHeaderProps>(), {\n title: undefined,\n showCloseButton: true,\n config: undefined,\n closeLabel: undefined,\n})\n\nconst slots = defineSlots<{\n default?: (props: { title?: string }) => any\n}>()\n\ndefineEmits<GrDialogHeaderEmits>()\n\nconst resolvedTitle = computed(() => resolveGrDialogTitle(props.title))\n\nconst resolvedConfig = computed(() =>\n resolveGrDialogSectionConfig(props.config, DEFAULT_GR_DIALOG_HEADER_CONFIG),\n)\n\nconst rootClass = computed(() => [\n resolvedConfig.value.paddingX,\n resolvedConfig.value.paddingY,\n resolvedConfig.value.bordered ? 'border-b border-[var(--gr-brd)]' : '',\n 'flex items-center justify-between gap-4',\n])\n\n// Видимый заголовок рендерим только когда нет пользовательского слота:\n// если слот `#header` задан, a11y-title отдаётся через `GrModal #title`\n// на уровне `GrDialog` (см. JSDoc у `GrDialog.vue`).\nconst showVisibleTitle = computed(() => !slots.default && !!resolvedTitle.value)\n\n// Имя окна: заголовок объявляет себя окну, и `GrModal` ставит на него\n// `aria-labelledby`. Вне `GrModal` регистрация — no-op, шапку можно\n// использовать и отдельно.\nconst { titleId } = useGrModalTitle(() => showVisibleTitle.value)\n</script>\n\n<template>\n <div data-gr-dialog-header :class=\"rootClass\">\n <template v-if=\"slots.default\">\n <div class=\"flex-1 min-w-0 flex items-center\">\n <slot :title=\"resolvedTitle\" />\n </div>\n </template>\n <div\n v-else-if=\"showVisibleTitle\"\n :id=\"titleId\"\n data-gr-dialog-title\n class=\"flex-1 min-w-0 text-[length:var(--gr-control-text-md)] font-700\"\n >\n {{ resolvedTitle }}\n </div>\n <div v-else class=\"flex-1 min-w-0\" />\n <GrDialogCloseButton\n v-if=\"showCloseButton\"\n :aria-label=\"closeLabel\"\n @click=\"$emit('close')\"\n />\n </div>\n</template>\n","<script setup lang=\"ts\">\n/**\n * GrDialog — GR-примитив диалога поверх `GrModal`.\n *\n * Архитектурно:\n * - ширина/радиус/скролл-лок/Esc/бэкдроп — ответственность `GrModal`;\n * - заголовок/подвал/кнопка закрытия/паддинги секций — ответственность `GrDialog`.\n *\n * A11y: ровно один `DialogTitle` на открытое окно.\n * - Если хедер отображается без слота `#header` — видимый `DialogTitle` рендерит\n * `GrDialogHeader`.\n * - В остальных случаях (`!showHeader`, либо `showHeader` со слотом `#header`)\n * `GrDialog` отдаёт sr-only title в слот `#title` у `GrModal`, чтобы\n * `GrModal` корректно проставил `aria-labelledby` на корень окна.\n * - `aria-label` вниз уходит всегда: `GrModal` иначе не отличил бы «заголовок\n * рисует `GrDialogHeader`» от «имени нет вовсе» и подставил бы обобщённое.\n */\nimport { useGrComponentProp } from '../GrConfigProvider/context'\nimport { computed } from 'vue'\n\nimport GrModal from '../GrModal/GrModal.vue'\nimport type { GrModalScrollBehavior } from '../GrModal/grModalStyles'\nimport GrDialogFooter from './GrDialogFooter.vue'\nimport GrDialogHeader from './GrDialogHeader.vue'\nimport {\n DEFAULT_GR_DIALOG_BODY_CONFIG,\n type GrDialogSectionConfig,\n type GrDialogSize,\n resolveGrDialogSectionConfig,\n resolveGrDialogTitle,\n} from './dialogShared'\n\nexport interface GrDialogProps {\n modelValue: boolean\n title?: 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 /**\n * Доступное имя окна, когда заголовка нет вовсе: `showHeader: false` без\n * `title` и без слота `#header` оставил бы окно безымянным.\n */\n ariaLabel?: string\n /**\n * Кто скроллится при длинном содержимом. При `inside` шапка и подвал\n * закреплены, а едет только тело.\n */\n scrollBehavior?: GrModalScrollBehavior\n /**\n * Элемент, получающий фокус при открытии. По умолчанию — панель окна.\n * Элемент **из самого диалога** сюда передавать нельзя: проп, возвращающий\n * наверх то, что рождено внутри поддерева, замыкает рендер в цикл. Фокус на\n * своём содержимом ставится из содержимого — так это сделано в\n * `GrPromptDialog`.\n */\n initialFocus?: HTMLElement | null\n}\n\nexport interface GrDialogEmits {\n (e: 'update:modelValue', value: boolean): void\n /** Окно открылось и анимация закончилась. */\n (e: 'opened'): void\n /** Окно закрылось и анимация закончилась — содержимое можно размонтировать. */\n (e: 'closed'): void\n}\n\nimport './defaults'\n\nconst props = withDefaults(defineProps<GrDialogProps>(), {\n title: undefined,\n closeOnBackdrop: true,\n closeOnEsc: true,\n showHeader: true,\n showCloseButton: true,\n // Дефолт `size` живёт в резолвере ниже, а не здесь: Vue подставил бы его\n // до того, как компонент заглянет в `GrConfigProvider`.\n size: undefined,\n headerConfig: undefined,\n footerConfig: undefined,\n bodyConfig: undefined,\n closeLabel: undefined,\n ariaLabel: undefined,\n scrollBehavior: 'outside',\n initialFocus: null,\n})\n\nconst emit = defineEmits<GrDialogEmits>()\n\nconst slots = defineSlots<{\n default?: () => any\n header?: (props: { title?: string }) => any\n footer?: () => any\n}>()\n\n// Эффективный размер: локальный проп → `GrConfigProvider` → дефолт компонента.\n// Резолвим здесь, а не полагаемся на `GrModal`: иначе дефолт диалога затенил бы\n// конфиг раньше, чем примитив успел бы в него заглянуть.\nconst resolvedSize = useGrComponentProp('GrDialog', 'size', () => props.size, 'md')\n\nconst resolvedTitle = computed(() => resolveGrDialogTitle(props.title))\n\nconst bodyClass = computed(() => {\n const cfg = resolveGrDialogSectionConfig(props.bodyConfig, DEFAULT_GR_DIALOG_BODY_CONFIG)\n return [cfg.paddingX, cfg.paddingY]\n})\n\n// Нужен ли sr-only title через `GrModal #title`:\n// - `!showHeader` — вообще нет заголовка в разметке;\n// - `showHeader && $slots.header` — кастомный хедер не обязан содержать DialogTitle.\n// В обоих случаях даём окну a11y-title, не дублируя его визуально.\nconst useModalSrOnlyTitle = computed(\n () => !!resolvedTitle.value && (!props.showHeader || !!slots.header),\n)\n\nfunction open(): void {\n emit('update:modelValue', true)\n}\n\nfunction close(): void {\n emit('update:modelValue', false)\n}\n\nfunction toggle(): void {\n emit('update:modelValue', !props.modelValue)\n}\n\ndefineExpose({ open, close, toggle })\n</script>\n\n<template>\n <GrModal\n :model-value=\"modelValue\"\n :size=\"resolvedSize\"\n :scroll-behavior=\"scrollBehavior\"\n :initial-focus=\"initialFocus\"\n :close-on-backdrop=\"closeOnBackdrop\"\n :close-on-esc=\"closeOnEsc\"\n :aria-label=\"ariaLabel ?? resolvedTitle\"\n @update:model-value=\"emit('update:modelValue', $event)\"\n @opened=\"emit('opened')\"\n @closed=\"emit('closed')\"\n >\n <template v-if=\"useModalSrOnlyTitle\" #title>\n <span class=\"sr-only\">{{ resolvedTitle }}</span>\n </template>\n\n <!-- Шапка и подвал уходят в layout-слоты `GrModal`: при `inside` они\n остаются вне скроллящегося тела. -->\n <template v-if=\"showHeader\" #header>\n <GrDialogHeader\n :title=\"resolvedTitle\"\n :show-close-button=\"showCloseButton\"\n :config=\"headerConfig\"\n :close-label=\"closeLabel\"\n @close=\"close\"\n >\n <template v-if=\"slots.header\" #default=\"slotProps\">\n <slot name=\"header\" v-bind=\"slotProps\" />\n </template>\n </GrDialogHeader>\n </template>\n\n <div :class=\"bodyClass\">\n <slot />\n </div>\n\n <template v-if=\"slots.footer\" #footer>\n <GrDialogFooter :config=\"footerConfig\">\n <slot name=\"footer\" />\n </GrDialogFooter>\n </template>\n </GrModal>\n</template>\n","<script setup lang=\"ts\">\n/**\n * GrDialog — GR-примитив диалога поверх `GrModal`.\n *\n * Архитектурно:\n * - ширина/радиус/скролл-лок/Esc/бэкдроп — ответственность `GrModal`;\n * - заголовок/подвал/кнопка закрытия/паддинги секций — ответственность `GrDialog`.\n *\n * A11y: ровно один `DialogTitle` на открытое окно.\n * - Если хедер отображается без слота `#header` — видимый `DialogTitle` рендерит\n * `GrDialogHeader`.\n * - В остальных случаях (`!showHeader`, либо `showHeader` со слотом `#header`)\n * `GrDialog` отдаёт sr-only title в слот `#title` у `GrModal`, чтобы\n * `GrModal` корректно проставил `aria-labelledby` на корень окна.\n * - `aria-label` вниз уходит всегда: `GrModal` иначе не отличил бы «заголовок\n * рисует `GrDialogHeader`» от «имени нет вовсе» и подставил бы обобщённое.\n */\nimport { useGrComponentProp } from '../GrConfigProvider/context'\nimport { computed } from 'vue'\n\nimport GrModal from '../GrModal/GrModal.vue'\nimport type { GrModalScrollBehavior } from '../GrModal/grModalStyles'\nimport GrDialogFooter from './GrDialogFooter.vue'\nimport GrDialogHeader from './GrDialogHeader.vue'\nimport {\n DEFAULT_GR_DIALOG_BODY_CONFIG,\n type GrDialogSectionConfig,\n type GrDialogSize,\n resolveGrDialogSectionConfig,\n resolveGrDialogTitle,\n} from './dialogShared'\n\nexport interface GrDialogProps {\n modelValue: boolean\n title?: 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 /**\n * Доступное имя окна, когда заголовка нет вовсе: `showHeader: false` без\n * `title` и без слота `#header` оставил бы окно безымянным.\n */\n ariaLabel?: string\n /**\n * Кто скроллится при длинном содержимом. При `inside` шапка и подвал\n * закреплены, а едет только тело.\n */\n scrollBehavior?: GrModalScrollBehavior\n /**\n * Элемент, получающий фокус при открытии. По умолчанию — панель окна.\n * Элемент **из самого диалога** сюда передавать нельзя: проп, возвращающий\n * наверх то, что рождено внутри поддерева, замыкает рендер в цикл. Фокус на\n * своём содержимом ставится из содержимого — так это сделано в\n * `GrPromptDialog`.\n */\n initialFocus?: HTMLElement | null\n}\n\nexport interface GrDialogEmits {\n (e: 'update:modelValue', value: boolean): void\n /** Окно открылось и анимация закончилась. */\n (e: 'opened'): void\n /** Окно закрылось и анимация закончилась — содержимое можно размонтировать. */\n (e: 'closed'): void\n}\n\nimport './defaults'\n\nconst props = withDefaults(defineProps<GrDialogProps>(), {\n title: undefined,\n closeOnBackdrop: true,\n closeOnEsc: true,\n showHeader: true,\n showCloseButton: true,\n // Дефолт `size` живёт в резолвере ниже, а не здесь: Vue подставил бы его\n // до того, как компонент заглянет в `GrConfigProvider`.\n size: undefined,\n headerConfig: undefined,\n footerConfig: undefined,\n bodyConfig: undefined,\n closeLabel: undefined,\n ariaLabel: undefined,\n scrollBehavior: 'outside',\n initialFocus: null,\n})\n\nconst emit = defineEmits<GrDialogEmits>()\n\nconst slots = defineSlots<{\n default?: () => any\n header?: (props: { title?: string }) => any\n footer?: () => any\n}>()\n\n// Эффективный размер: локальный проп → `GrConfigProvider` → дефолт компонента.\n// Резолвим здесь, а не полагаемся на `GrModal`: иначе дефолт диалога затенил бы\n// конфиг раньше, чем примитив успел бы в него заглянуть.\nconst resolvedSize = useGrComponentProp('GrDialog', 'size', () => props.size, 'md')\n\nconst resolvedTitle = computed(() => resolveGrDialogTitle(props.title))\n\nconst bodyClass = computed(() => {\n const cfg = resolveGrDialogSectionConfig(props.bodyConfig, DEFAULT_GR_DIALOG_BODY_CONFIG)\n return [cfg.paddingX, cfg.paddingY]\n})\n\n// Нужен ли sr-only title через `GrModal #title`:\n// - `!showHeader` — вообще нет заголовка в разметке;\n// - `showHeader && $slots.header` — кастомный хедер не обязан содержать DialogTitle.\n// В обоих случаях даём окну a11y-title, не дублируя его визуально.\nconst useModalSrOnlyTitle = computed(\n () => !!resolvedTitle.value && (!props.showHeader || !!slots.header),\n)\n\nfunction open(): void {\n emit('update:modelValue', true)\n}\n\nfunction close(): void {\n emit('update:modelValue', false)\n}\n\nfunction toggle(): void {\n emit('update:modelValue', !props.modelValue)\n}\n\ndefineExpose({ open, close, toggle })\n</script>\n\n<template>\n <GrModal\n :model-value=\"modelValue\"\n :size=\"resolvedSize\"\n :scroll-behavior=\"scrollBehavior\"\n :initial-focus=\"initialFocus\"\n :close-on-backdrop=\"closeOnBackdrop\"\n :close-on-esc=\"closeOnEsc\"\n :aria-label=\"ariaLabel ?? resolvedTitle\"\n @update:model-value=\"emit('update:modelValue', $event)\"\n @opened=\"emit('opened')\"\n @closed=\"emit('closed')\"\n >\n <template v-if=\"useModalSrOnlyTitle\" #title>\n <span class=\"sr-only\">{{ resolvedTitle }}</span>\n </template>\n\n <!-- Шапка и подвал уходят в layout-слоты `GrModal`: при `inside` они\n остаются вне скроллящегося тела. -->\n <template v-if=\"showHeader\" #header>\n <GrDialogHeader\n :title=\"resolvedTitle\"\n :show-close-button=\"showCloseButton\"\n :config=\"headerConfig\"\n :close-label=\"closeLabel\"\n @close=\"close\"\n >\n <template v-if=\"slots.header\" #default=\"slotProps\">\n <slot name=\"header\" v-bind=\"slotProps\" />\n </template>\n </GrDialogHeader>\n </template>\n\n <div :class=\"bodyClass\">\n <slot />\n </div>\n\n <template v-if=\"slots.footer\" #footer>\n <GrDialogFooter :config=\"footerConfig\">\n <slot name=\"footer\" />\n </GrDialogFooter>\n </template>\n </GrModal>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"GrDialog-5Y5K87ss.js","names":["$emit","$emit"],"sources":["../../../../src/components/GrDialog/GrDialogFooter.vue","../../../../src/components/GrDialog/GrDialogFooter.vue","../../../../src/components/GrDialog/GrDialogCloseButton.vue","../../../../src/components/GrDialog/GrDialogCloseButton.vue","../../../../src/components/GrDialog/GrDialogHeader.vue","../../../../src/components/GrDialog/GrDialogHeader.vue","../../../../src/components/GrDialog/GrDialog.vue","../../../../src/components/GrDialog/GrDialog.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport {\n DEFAULT_GR_DIALOG_FOOTER_CONFIG,\n resolveGrDialogSectionConfig,\n type GrDialogSectionConfig,\n} from './dialogShared'\n\nexport interface GrDialogFooterProps {\n config?: GrDialogSectionConfig\n}\n\nconst props = withDefaults(defineProps<GrDialogFooterProps>(), {\n config: undefined,\n})\n\nconst resolvedConfig = computed(() => resolveGrDialogSectionConfig(props.config, DEFAULT_GR_DIALOG_FOOTER_CONFIG))\n\nconst rootClass = computed(() => [\n resolvedConfig.value.paddingX,\n resolvedConfig.value.paddingY,\n resolvedConfig.value.bordered ? 'border-t border-[var(--gr-brd)]' : '',\n])\n</script>\n\n<template>\n <div data-gr-dialog-footer :class=\"rootClass\">\n <slot />\n </div>\n</template>","<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport {\n DEFAULT_GR_DIALOG_FOOTER_CONFIG,\n resolveGrDialogSectionConfig,\n type GrDialogSectionConfig,\n} from './dialogShared'\n\nexport interface GrDialogFooterProps {\n config?: GrDialogSectionConfig\n}\n\nconst props = withDefaults(defineProps<GrDialogFooterProps>(), {\n config: undefined,\n})\n\nconst resolvedConfig = computed(() => resolveGrDialogSectionConfig(props.config, DEFAULT_GR_DIALOG_FOOTER_CONFIG))\n\nconst rootClass = computed(() => [\n resolvedConfig.value.paddingX,\n resolvedConfig.value.paddingY,\n resolvedConfig.value.bordered ? 'border-t border-[var(--gr-brd)]' : '',\n])\n</script>\n\n<template>\n <div data-gr-dialog-footer :class=\"rootClass\">\n <slot />\n </div>\n</template>","<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue'\n\nimport GrButton from '../GrButton/GrButton.vue'\nimport IconClose from '~icons/lucide/x'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\n\nexport interface GrDialogCloseButtonEmits {\n (e: 'click'): void\n}\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst { t } = useGranularityTranslations()\n\n// A11y-лейбл: берём из атрибутов (родитель прокидывает `:aria-label=\"closeLabel\"`)\n// или используем i18n-дефолт. Не хардкодим английское \"Close\" — GR должен быть i18n-friendly.\nconst attrs = useAttrs()\nconst ariaLabel = computed(() => (attrs['aria-label'] as string | undefined) ?? t('gr.common.close', 'Close'))\n\ndefineEmits<GrDialogCloseButtonEmits>()\n</script>\n\n<template>\n <GrButton\n v-bind=\"attrs\"\n data-gr-dialog-close\n variant=\"ghost\"\n size=\"sm\"\n square\n :aria-label=\"ariaLabel\"\n @click=\"$emit('click')\"\n >\n <IconClose class=\"h-4 w-4\" aria-hidden=\"true\" />\n </GrButton>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue'\n\nimport GrButton from '../GrButton/GrButton.vue'\nimport IconClose from '~icons/lucide/x'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\n\nexport interface GrDialogCloseButtonEmits {\n (e: 'click'): void\n}\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst { t } = useGranularityTranslations()\n\n// A11y-лейбл: берём из атрибутов (родитель прокидывает `:aria-label=\"closeLabel\"`)\n// или используем i18n-дефолт. Не хардкодим английское \"Close\" — GR должен быть i18n-friendly.\nconst attrs = useAttrs()\nconst ariaLabel = computed(() => (attrs['aria-label'] as string | undefined) ?? t('gr.common.close', 'Close'))\n\ndefineEmits<GrDialogCloseButtonEmits>()\n</script>\n\n<template>\n <GrButton\n v-bind=\"attrs\"\n data-gr-dialog-close\n variant=\"ghost\"\n size=\"sm\"\n square\n :aria-label=\"ariaLabel\"\n @click=\"$emit('click')\"\n >\n <IconClose class=\"h-4 w-4\" aria-hidden=\"true\" />\n </GrButton>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport GrDialogCloseButton from './GrDialogCloseButton.vue'\nimport { useGrModalTitle } from '../GrModal/context'\nimport {\n DEFAULT_GR_DIALOG_HEADER_CONFIG,\n type GrDialogSectionConfig,\n resolveGrDialogSectionConfig,\n resolveGrDialogTitle,\n} from './dialogShared'\n\nexport interface GrDialogHeaderProps {\n title?: string\n showCloseButton?: boolean\n config?: GrDialogSectionConfig\n /** A11y-лейбл кнопки закрытия (i18n). */\n closeLabel?: string\n}\n\nexport interface GrDialogHeaderEmits {\n (e: 'close'): void\n}\n\nconst props = withDefaults(defineProps<GrDialogHeaderProps>(), {\n title: undefined,\n showCloseButton: true,\n config: undefined,\n closeLabel: undefined,\n})\n\nconst slots = defineSlots<{\n default?: (props: { title?: string }) => any\n}>()\n\ndefineEmits<GrDialogHeaderEmits>()\n\nconst resolvedTitle = computed(() => resolveGrDialogTitle(props.title))\n\nconst resolvedConfig = computed(() =>\n resolveGrDialogSectionConfig(props.config, DEFAULT_GR_DIALOG_HEADER_CONFIG),\n)\n\nconst rootClass = computed(() => [\n resolvedConfig.value.paddingX,\n resolvedConfig.value.paddingY,\n resolvedConfig.value.bordered ? 'border-b border-[var(--gr-brd)]' : '',\n 'flex items-center justify-between gap-4',\n])\n\n// Видимый заголовок рендерим только когда нет пользовательского слота:\n// если слот `#header` задан, a11y-title отдаётся через `GrModal #title`\n// на уровне `GrDialog` (см. JSDoc у `GrDialog.vue`).\nconst showVisibleTitle = computed(() => !slots.default && !!resolvedTitle.value)\n\n// Имя окна: заголовок объявляет себя окну, и `GrModal` ставит на него\n// `aria-labelledby`. Вне `GrModal` регистрация — no-op, шапку можно\n// использовать и отдельно.\nconst { titleId } = useGrModalTitle(() => showVisibleTitle.value)\n</script>\n\n<template>\n <div data-gr-dialog-header :class=\"rootClass\">\n <template v-if=\"slots.default\">\n <div class=\"flex-1 min-w-0 flex items-center\">\n <slot :title=\"resolvedTitle\" />\n </div>\n </template>\n <div\n v-else-if=\"showVisibleTitle\"\n :id=\"titleId\"\n data-gr-dialog-title\n class=\"flex-1 min-w-0 text-[length:var(--gr-control-text-md)] font-700\"\n >\n {{ resolvedTitle }}\n </div>\n <div v-else class=\"flex-1 min-w-0\" />\n <GrDialogCloseButton\n v-if=\"showCloseButton\"\n :aria-label=\"closeLabel\"\n @click=\"$emit('close')\"\n />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport GrDialogCloseButton from './GrDialogCloseButton.vue'\nimport { useGrModalTitle } from '../GrModal/context'\nimport {\n DEFAULT_GR_DIALOG_HEADER_CONFIG,\n type GrDialogSectionConfig,\n resolveGrDialogSectionConfig,\n resolveGrDialogTitle,\n} from './dialogShared'\n\nexport interface GrDialogHeaderProps {\n title?: string\n showCloseButton?: boolean\n config?: GrDialogSectionConfig\n /** A11y-лейбл кнопки закрытия (i18n). */\n closeLabel?: string\n}\n\nexport interface GrDialogHeaderEmits {\n (e: 'close'): void\n}\n\nconst props = withDefaults(defineProps<GrDialogHeaderProps>(), {\n title: undefined,\n showCloseButton: true,\n config: undefined,\n closeLabel: undefined,\n})\n\nconst slots = defineSlots<{\n default?: (props: { title?: string }) => any\n}>()\n\ndefineEmits<GrDialogHeaderEmits>()\n\nconst resolvedTitle = computed(() => resolveGrDialogTitle(props.title))\n\nconst resolvedConfig = computed(() =>\n resolveGrDialogSectionConfig(props.config, DEFAULT_GR_DIALOG_HEADER_CONFIG),\n)\n\nconst rootClass = computed(() => [\n resolvedConfig.value.paddingX,\n resolvedConfig.value.paddingY,\n resolvedConfig.value.bordered ? 'border-b border-[var(--gr-brd)]' : '',\n 'flex items-center justify-between gap-4',\n])\n\n// Видимый заголовок рендерим только когда нет пользовательского слота:\n// если слот `#header` задан, a11y-title отдаётся через `GrModal #title`\n// на уровне `GrDialog` (см. JSDoc у `GrDialog.vue`).\nconst showVisibleTitle = computed(() => !slots.default && !!resolvedTitle.value)\n\n// Имя окна: заголовок объявляет себя окну, и `GrModal` ставит на него\n// `aria-labelledby`. Вне `GrModal` регистрация — no-op, шапку можно\n// использовать и отдельно.\nconst { titleId } = useGrModalTitle(() => showVisibleTitle.value)\n</script>\n\n<template>\n <div data-gr-dialog-header :class=\"rootClass\">\n <template v-if=\"slots.default\">\n <div class=\"flex-1 min-w-0 flex items-center\">\n <slot :title=\"resolvedTitle\" />\n </div>\n </template>\n <div\n v-else-if=\"showVisibleTitle\"\n :id=\"titleId\"\n data-gr-dialog-title\n class=\"flex-1 min-w-0 text-[length:var(--gr-control-text-md)] font-700\"\n >\n {{ resolvedTitle }}\n </div>\n <div v-else class=\"flex-1 min-w-0\" />\n <GrDialogCloseButton\n v-if=\"showCloseButton\"\n :aria-label=\"closeLabel\"\n @click=\"$emit('close')\"\n />\n </div>\n</template>\n","<script setup lang=\"ts\">\n/**\n * GrDialog — GR-примитив диалога поверх `GrModal`.\n *\n * Архитектурно:\n * - ширина/радиус/скролл-лок/Esc/бэкдроп — ответственность `GrModal`;\n * - заголовок/подвал/кнопка закрытия/паддинги секций — ответственность `GrDialog`.\n *\n * A11y: ровно один `DialogTitle` на открытое окно.\n * - Если хедер отображается без слота `#header` — видимый `DialogTitle` рендерит\n * `GrDialogHeader`.\n * - В остальных случаях (`!showHeader`, либо `showHeader` со слотом `#header`)\n * `GrDialog` отдаёт sr-only title в слот `#title` у `GrModal`, чтобы\n * `GrModal` корректно проставил `aria-labelledby` на корень окна.\n * - `aria-label` вниз уходит всегда: `GrModal` иначе не отличил бы «заголовок\n * рисует `GrDialogHeader`» от «имени нет вовсе» и подставил бы обобщённое.\n */\nimport { useGrComponentProp } from '../GrConfigProvider/context'\nimport { computed } from 'vue'\n\nimport GrModal from '../GrModal/GrModal.vue'\nimport type { GrModalScrollBehavior } from '../GrModal/grModalStyles'\nimport GrDialogFooter from './GrDialogFooter.vue'\nimport GrDialogHeader from './GrDialogHeader.vue'\nimport {\n DEFAULT_GR_DIALOG_BODY_CONFIG,\n type GrDialogSectionConfig,\n type GrDialogSize,\n resolveGrDialogSectionConfig,\n resolveGrDialogTitle,\n} from './dialogShared'\n\nexport interface GrDialogProps {\n modelValue: boolean\n title?: 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 /**\n * Доступное имя окна, когда заголовка нет вовсе: `showHeader: false` без\n * `title` и без слота `#header` оставил бы окно безымянным.\n */\n ariaLabel?: string\n /**\n * Кто скроллится при длинном содержимом. При `inside` шапка и подвал\n * закреплены, а едет только тело.\n */\n scrollBehavior?: GrModalScrollBehavior\n /**\n * Элемент, получающий фокус при открытии. По умолчанию — панель окна.\n * Элемент **из самого диалога** сюда передавать нельзя: проп, возвращающий\n * наверх то, что рождено внутри поддерева, замыкает рендер в цикл. Фокус на\n * своём содержимом ставится из содержимого — так это сделано в\n * `GrPromptDialog`.\n */\n initialFocus?: HTMLElement | null\n}\n\nexport interface GrDialogEmits {\n (e: 'update:modelValue', value: boolean): void\n /** Окно открылось и анимация закончилась. */\n (e: 'opened'): void\n /** Окно закрылось и анимация закончилась — содержимое можно размонтировать. */\n (e: 'closed'): void\n}\n\nimport './defaults'\n\nconst props = withDefaults(defineProps<GrDialogProps>(), {\n title: undefined,\n closeOnBackdrop: true,\n closeOnEsc: true,\n showHeader: true,\n showCloseButton: true,\n // Дефолт `size` живёт в резолвере ниже, а не здесь: Vue подставил бы его\n // до того, как компонент заглянет в `GrConfigProvider`.\n size: undefined,\n headerConfig: undefined,\n footerConfig: undefined,\n bodyConfig: undefined,\n closeLabel: undefined,\n ariaLabel: undefined,\n scrollBehavior: 'outside',\n initialFocus: null,\n})\n\nconst emit = defineEmits<GrDialogEmits>()\n\nconst slots = defineSlots<{\n default?: () => any\n header?: (props: { title?: string }) => any\n footer?: () => any\n}>()\n\n// Эффективный размер: локальный проп → `GrConfigProvider` → дефолт компонента.\n// Резолвим здесь, а не полагаемся на `GrModal`: иначе дефолт диалога затенил бы\n// конфиг раньше, чем примитив успел бы в него заглянуть.\nconst resolvedSize = useGrComponentProp('GrDialog', 'size', () => props.size, 'md')\n\nconst resolvedTitle = computed(() => resolveGrDialogTitle(props.title))\n\nconst bodyClass = computed(() => {\n const cfg = resolveGrDialogSectionConfig(props.bodyConfig, DEFAULT_GR_DIALOG_BODY_CONFIG)\n return [cfg.paddingX, cfg.paddingY]\n})\n\n// Нужен ли sr-only title через `GrModal #title`:\n// - `!showHeader` — вообще нет заголовка в разметке;\n// - `showHeader && $slots.header` — кастомный хедер не обязан содержать DialogTitle.\n// В обоих случаях даём окну a11y-title, не дублируя его визуально.\nconst useModalSrOnlyTitle = computed(\n () => !!resolvedTitle.value && (!props.showHeader || !!slots.header),\n)\n\nfunction open(): void {\n emit('update:modelValue', true)\n}\n\nfunction close(): void {\n emit('update:modelValue', false)\n}\n\nfunction toggle(): void {\n emit('update:modelValue', !props.modelValue)\n}\n\ndefineExpose({ open, close, toggle })\n</script>\n\n<template>\n <GrModal\n :model-value=\"modelValue\"\n :size=\"resolvedSize\"\n :scroll-behavior=\"scrollBehavior\"\n :initial-focus=\"initialFocus\"\n :close-on-backdrop=\"closeOnBackdrop\"\n :close-on-esc=\"closeOnEsc\"\n :aria-label=\"ariaLabel ?? resolvedTitle\"\n @update:model-value=\"emit('update:modelValue', $event)\"\n @opened=\"emit('opened')\"\n @closed=\"emit('closed')\"\n >\n <template v-if=\"useModalSrOnlyTitle\" #title>\n <span class=\"sr-only\">{{ resolvedTitle }}</span>\n </template>\n\n <!-- Шапка и подвал уходят в layout-слоты `GrModal`: при `inside` они\n остаются вне скроллящегося тела. -->\n <template v-if=\"showHeader\" #header>\n <GrDialogHeader\n :title=\"resolvedTitle\"\n :show-close-button=\"showCloseButton\"\n :config=\"headerConfig\"\n :close-label=\"closeLabel\"\n @close=\"close\"\n >\n <template v-if=\"slots.header\" #default=\"slotProps\">\n <slot name=\"header\" v-bind=\"slotProps\" />\n </template>\n </GrDialogHeader>\n </template>\n\n <div :class=\"bodyClass\">\n <slot />\n </div>\n\n <template v-if=\"slots.footer\" #footer>\n <GrDialogFooter :config=\"footerConfig\">\n <slot name=\"footer\" />\n </GrDialogFooter>\n </template>\n </GrModal>\n</template>\n","<script setup lang=\"ts\">\n/**\n * GrDialog — GR-примитив диалога поверх `GrModal`.\n *\n * Архитектурно:\n * - ширина/радиус/скролл-лок/Esc/бэкдроп — ответственность `GrModal`;\n * - заголовок/подвал/кнопка закрытия/паддинги секций — ответственность `GrDialog`.\n *\n * A11y: ровно один `DialogTitle` на открытое окно.\n * - Если хедер отображается без слота `#header` — видимый `DialogTitle` рендерит\n * `GrDialogHeader`.\n * - В остальных случаях (`!showHeader`, либо `showHeader` со слотом `#header`)\n * `GrDialog` отдаёт sr-only title в слот `#title` у `GrModal`, чтобы\n * `GrModal` корректно проставил `aria-labelledby` на корень окна.\n * - `aria-label` вниз уходит всегда: `GrModal` иначе не отличил бы «заголовок\n * рисует `GrDialogHeader`» от «имени нет вовсе» и подставил бы обобщённое.\n */\nimport { useGrComponentProp } from '../GrConfigProvider/context'\nimport { computed } from 'vue'\n\nimport GrModal from '../GrModal/GrModal.vue'\nimport type { GrModalScrollBehavior } from '../GrModal/grModalStyles'\nimport GrDialogFooter from './GrDialogFooter.vue'\nimport GrDialogHeader from './GrDialogHeader.vue'\nimport {\n DEFAULT_GR_DIALOG_BODY_CONFIG,\n type GrDialogSectionConfig,\n type GrDialogSize,\n resolveGrDialogSectionConfig,\n resolveGrDialogTitle,\n} from './dialogShared'\n\nexport interface GrDialogProps {\n modelValue: boolean\n title?: 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 /**\n * Доступное имя окна, когда заголовка нет вовсе: `showHeader: false` без\n * `title` и без слота `#header` оставил бы окно безымянным.\n */\n ariaLabel?: string\n /**\n * Кто скроллится при длинном содержимом. При `inside` шапка и подвал\n * закреплены, а едет только тело.\n */\n scrollBehavior?: GrModalScrollBehavior\n /**\n * Элемент, получающий фокус при открытии. По умолчанию — панель окна.\n * Элемент **из самого диалога** сюда передавать нельзя: проп, возвращающий\n * наверх то, что рождено внутри поддерева, замыкает рендер в цикл. Фокус на\n * своём содержимом ставится из содержимого — так это сделано в\n * `GrPromptDialog`.\n */\n initialFocus?: HTMLElement | null\n}\n\nexport interface GrDialogEmits {\n (e: 'update:modelValue', value: boolean): void\n /** Окно открылось и анимация закончилась. */\n (e: 'opened'): void\n /** Окно закрылось и анимация закончилась — содержимое можно размонтировать. */\n (e: 'closed'): void\n}\n\nimport './defaults'\n\nconst props = withDefaults(defineProps<GrDialogProps>(), {\n title: undefined,\n closeOnBackdrop: true,\n closeOnEsc: true,\n showHeader: true,\n showCloseButton: true,\n // Дефолт `size` живёт в резолвере ниже, а не здесь: Vue подставил бы его\n // до того, как компонент заглянет в `GrConfigProvider`.\n size: undefined,\n headerConfig: undefined,\n footerConfig: undefined,\n bodyConfig: undefined,\n closeLabel: undefined,\n ariaLabel: undefined,\n scrollBehavior: 'outside',\n initialFocus: null,\n})\n\nconst emit = defineEmits<GrDialogEmits>()\n\nconst slots = defineSlots<{\n default?: () => any\n header?: (props: { title?: string }) => any\n footer?: () => any\n}>()\n\n// Эффективный размер: локальный проп → `GrConfigProvider` → дефолт компонента.\n// Резолвим здесь, а не полагаемся на `GrModal`: иначе дефолт диалога затенил бы\n// конфиг раньше, чем примитив успел бы в него заглянуть.\nconst resolvedSize = useGrComponentProp('GrDialog', 'size', () => props.size, 'md')\n\nconst resolvedTitle = computed(() => resolveGrDialogTitle(props.title))\n\nconst bodyClass = computed(() => {\n const cfg = resolveGrDialogSectionConfig(props.bodyConfig, DEFAULT_GR_DIALOG_BODY_CONFIG)\n return [cfg.paddingX, cfg.paddingY]\n})\n\n// Нужен ли sr-only title через `GrModal #title`:\n// - `!showHeader` — вообще нет заголовка в разметке;\n// - `showHeader && $slots.header` — кастомный хедер не обязан содержать DialogTitle.\n// В обоих случаях даём окну a11y-title, не дублируя его визуально.\nconst useModalSrOnlyTitle = computed(\n () => !!resolvedTitle.value && (!props.showHeader || !!slots.header),\n)\n\nfunction open(): void {\n emit('update:modelValue', true)\n}\n\nfunction close(): void {\n emit('update:modelValue', false)\n}\n\nfunction toggle(): void {\n emit('update:modelValue', !props.modelValue)\n}\n\ndefineExpose({ open, close, toggle })\n</script>\n\n<template>\n <GrModal\n :model-value=\"modelValue\"\n :size=\"resolvedSize\"\n :scroll-behavior=\"scrollBehavior\"\n :initial-focus=\"initialFocus\"\n :close-on-backdrop=\"closeOnBackdrop\"\n :close-on-esc=\"closeOnEsc\"\n :aria-label=\"ariaLabel ?? resolvedTitle\"\n @update:model-value=\"emit('update:modelValue', $event)\"\n @opened=\"emit('opened')\"\n @closed=\"emit('closed')\"\n >\n <template v-if=\"useModalSrOnlyTitle\" #title>\n <span class=\"sr-only\">{{ resolvedTitle }}</span>\n </template>\n\n <!-- Шапка и подвал уходят в layout-слоты `GrModal`: при `inside` они\n остаются вне скроллящегося тела. -->\n <template v-if=\"showHeader\" #header>\n <GrDialogHeader\n :title=\"resolvedTitle\"\n :show-close-button=\"showCloseButton\"\n :config=\"headerConfig\"\n :close-label=\"closeLabel\"\n @close=\"close\"\n >\n <template v-if=\"slots.header\" #default=\"slotProps\">\n <slot name=\"header\" v-bind=\"slotProps\" />\n </template>\n </GrDialogHeader>\n </template>\n\n <div :class=\"bodyClass\">\n <slot />\n </div>\n\n <template v-if=\"slots.footer\" #footer>\n <GrDialogFooter :config=\"footerConfig\">\n <slot name=\"footer\" />\n </GrDialogFooter>\n </template>\n </GrModal>\n</template>\n"],"mappings":"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"}
@@ -1,3 +1,3 @@
1
- import { i as GrDialogFooter_default, n as GrDialogHeader_default, r as GrDialogCloseButton_default, t as GrDialog_default } from "./chunks/GrDialog-D0U5iRqV.js";
1
+ import { i as GrDialogFooter_default, n as GrDialogHeader_default, r as GrDialogCloseButton_default, t as GrDialog_default } from "./chunks/GrDialog-5Y5K87ss.js";
2
2
  import { t as grDialogSafelist } from "../../chunks/safelist-CkF4v7DC.js";
3
3
  export { GrDialog_default as GrDialog, GrDialog_default as default, GrDialogCloseButton_default as GrDialogCloseButton, GrDialogFooter_default as GrDialogFooter, GrDialogHeader_default as GrDialogHeader, grDialogSafelist };
@@ -2,10 +2,10 @@ import { o as useGrConfig, t as GR_CONFIG_KEY } from "../../../chunks/context-CT
2
2
  import { t as GRANULARITY_I18N_KEY } from "../../../chunks/adapter-CAOxmn2G.js";
3
3
  import { n as useGranularityTranslations, t as resolveGranularityI18n } from "../../../chunks/granularityI18n-BC5zsj_d.js";
4
4
  import { t as ensurePortalRoot } from "../../../chunks/portalRoot-CVhCgdG6.js";
5
- import { t as GrButton_default } from "../../GrButton/chunks/GrButton-Bw2AH4uX.js";
6
- import { n as coreResponseErrorParsers, o as responseErrorParserPresets, r as createResponseErrorClassifier } from "../../GrResponseErrorBanner/chunks/GrResponseErrorBanner-CZONq8uT.js";
7
- import { t as GrConfirmDialog_default } from "../../GrConfirmDialog/chunks/GrConfirmDialog-rRtMScJX.js";
8
- import { t as GrPromptDialog_default } from "../../GrPromptDialog/chunks/GrPromptDialog-CEI8bf-t.js";
5
+ import { t as GrButton_default } from "../../GrButton/chunks/GrButton-DCz-Wn-V.js";
6
+ import { n as coreResponseErrorParsers, o as responseErrorParserPresets, r as createResponseErrorClassifier } from "../../GrResponseErrorBanner/chunks/GrResponseErrorBanner-BhP-xw2P.js";
7
+ import { t as GrConfirmDialog_default } from "../../GrConfirmDialog/chunks/GrConfirmDialog-CwXNLyzk.js";
8
+ import { t as GrPromptDialog_default } from "../../GrPromptDialog/chunks/GrPromptDialog-DjF-5oD9.js";
9
9
  import { Fragment, computed, createBlock, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, getCurrentInstance, inject, markRaw, mergeProps, nextTick, onBeforeUnmount, onMounted, openBlock, provide, reactive, ref, render, renderList, shallowRef, toDisplayString, withCtx } from "vue";
10
10
  //#region src/components/GrDialogService/store.ts
11
11
  function createDialogServiceState() {
@@ -136,7 +136,7 @@ function getModuleState() {
136
136
  var ambiguousStateWarned = false;
137
137
  function warnAmbiguousState() {
138
138
  if (ambiguousStateWarned) return;
139
- if (typeof process !== "undefined" && process.env.NODE_ENV === "production") return;
139
+ if (!(typeof process !== "undefined" && process.env.NODE_ENV !== "production")) return;
140
140
  ambiguousStateWarned = true;
141
141
  console.warn("[granularity] useDialogService: плагин установлен в нескольких приложениях, а сервис запрошен вне `setup` — какое из них имелось в виду, знать неоткуда. Используется модульное состояние. Вызовите `useDialogService()` внутри `setup` нужного приложения.");
142
142
  }
@@ -169,7 +169,7 @@ function ensureMounted(state, appContext) {
169
169
  }
170
170
  function warnIfContextless(state, context) {
171
171
  if (state.contextlessWarned || context?.config || context?.i18n) return;
172
- if (typeof process !== "undefined" && process.env.NODE_ENV === "production") return;
172
+ if (!(typeof process !== "undefined" && process.env.NODE_ENV !== "production")) return;
173
173
  state.contextlessWarned = true;
174
174
  console.warn("[granularity] useDialogService: диалог открыт без контекста приложения — ни `GrConfigProvider`, ни адаптер i18n не найдены, будут использованы дефолты. Вызовите `useDialogService()` внутри `setup` хотя бы один раз или передайте `setAppContext`.");
175
175
  }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GrDialogService-CHhzGRWy.js","names":[],"sources":["../../../../src/components/GrDialogService/store.ts","../../../../src/components/GrDialogService/useDialogService.ts","../../../../src/components/GrDialogService/GrDialogServiceItem.vue","../../../../src/components/GrDialogService/GrDialogServiceItem.vue","../../../../src/components/GrDialogService/GrDialogServiceHost.vue","../../../../src/components/GrDialogService/GrDialogServiceHost.vue"],"sourcesContent":["import { reactive } from 'vue'\nimport type { AppContext, Raw } from 'vue'\n\nimport type { GrConfigContext } from '../GrConfigProvider/context'\nimport type { GranularityI18nLike } from '../../internal/granularityI18n'\n\nimport type {\n DialogBaseOptions,\n DialogKind,\n DialogOnConfirm,\n DialogResult,\n} from './types'\n\n/**\n * Внутреннее описание одного запроса диалога в очереди. Создаётся методами\n * сервиса (`confirm`/`alert`/`prompt`/`open`) и потребляется хостом\n * (`GrDialogServiceHost`), который рендерит видимую часть очереди.\n */\nexport interface DialogRequest {\n id: string\n kind: DialogKind\n message: string\n options: DialogBaseOptions\n onConfirm?: DialogOnConfirm<any>\n /** Позиция среди ожидающих: больше — раньше. При равенстве порядок FIFO. */\n priority: number\n /**\n * Заявка создана из `onConfirm` уже открытого диалога и показывается **поверх**\n * него, а не за ним. Без этого вложенный вызов вставал бы в очередь за тем,\n * кто его ждёт: внешнее окно висело бы в загрузке, а промис не резолвился бы\n * никогда.\n */\n nested: boolean\n /**\n * Заявка уже завершена. Флаг живёт на самой заявке, а не на хосте: завершить\n * её могут трое (кнопка в окне, `close()` промиса, `closeAll()`), и общее\n * состояние на хосте означало бы, что второй и третий путь про первый не\n * знают.\n */\n settled: boolean\n /** Резолвит промис вызова детальным результатом `{ action, value }`. */\n resolve: (result: DialogResult<any>) => void\n /**\n * Конфиг и i18n, захваченные в месте вызова сервиса (в `setup`, где вызывающий\n * компонент ещё находится внутри дерева провайдера). Хост монтируется в\n * `document.body` вне дерева, поэтому сам их не увидит — см.\n * `SPEC-GrConfig-resolver.md`.\n *\n * Лежат в запросе, а не в состоянии сервиса: два поддерева с разными\n * провайдерами должны получать каждое свой конфиг.\n *\n * `Raw<…>` обязателен: очередь — `reactive`, а он разворачивает вложенные рефы.\n * Без `markRaw` контекст превратился бы в объект значений, `size.value` стало\n * бы `undefined`, и мост молча перестал бы работать.\n */\n config?: Raw<GrConfigContext> | null\n i18n?: Raw<GranularityI18nLike> | null\n}\n\n/** Контекст, захваченный вызовом `useDialogService()` внутри `setup`. */\nexport interface CapturedDialogContext {\n config: Raw<GrConfigContext> | null\n i18n: Raw<GranularityI18nLike> | null\n}\n\n/**\n * Состояние одного инстанса сервиса: очередь, смонтированный хост и захваченный\n * контекст приложения. Живёт либо в приложении (через\n * `granularityDialogServicePlugin`), либо в ленивом модульном фолбэке для\n * простых SPA — см. `useDialogService.ts`.\n */\nexport interface DialogServiceState {\n /** Очередь заявок. Видимую часть выбирает хост, остальные ждут. */\n queue: DialogRequest[]\n mounted: boolean\n container: HTMLElement | null\n appContext: AppContext | null\n lastCapturedContext: CapturedDialogContext | null\n contextlessWarned: boolean\n /**\n * Заявки, чей `onConfirm` сейчас в полёте, от внешней к самой глубокой.\n * По ним определяется вложенность нового вызова.\n */\n inFlight: DialogRequest[]\n}\n\nexport function createDialogServiceState(): DialogServiceState {\n return {\n queue: reactive<DialogRequest[]>([]),\n mounted: false,\n container: null,\n appContext: null,\n lastCapturedContext: null,\n contextlessWarned: false,\n inFlight: [],\n }\n}\n\nlet counter = 0\n\nexport function makeDialogId(): string {\n counter += 1\n return `gr-dialog-${Date.now()}-${counter}`\n}\n\n/**\n * Видимая часть очереди: голова и непрерывный хвост вложенных заявок за ней.\n * Всё остальное ждёт — обычные вызовы по-прежнему идут по одному, чтобы три\n * алерта из цикла не легли стопкой.\n */\nexport function visibleDialogRequests(state: DialogServiceState): DialogRequest[] {\n const visible: DialogRequest[] = []\n\n for (const request of state.queue) {\n if (visible.length === 0 || request.nested)\n visible.push(request)\n else\n break\n }\n\n return visible\n}\n\n/**\n * Ставит заявку в очередь. Единственное место, где решается её позиция:\n *\n * - вложенная (создана, пока `onConfirm` другой заявки в полёте) встаёт сразу\n * за своим родителем и показывается поверх него;\n * - обычная — перед всеми ожидающими с меньшим приоритетом; показанные окна не\n * трогаются, выдёргивать фокус-ловушку из-под пользователя нельзя.\n */\nexport function enqueueDialogRequest(state: DialogServiceState, request: DialogRequest): void {\n const parent = state.inFlight[state.inFlight.length - 1]\n\n if (parent) {\n request.nested = true\n const parentIndex = state.queue.findIndex(item => item.id === parent.id)\n state.queue.splice(parentIndex + 1, 0, request)\n return\n }\n\n const visibleCount = visibleDialogRequests(state).length\n const insertAt = state.queue.findIndex(\n (item, index) => index >= visibleCount && item.priority < request.priority,\n )\n\n if (insertAt < 0)\n state.queue.push(request)\n else\n state.queue.splice(insertAt, 0, request)\n}\n\n/**\n * Заявка входит в «полёт»: пока её `onConfirm` не вернулся, новые вызовы\n * считаются вложенными в неё.\n */\nexport function startDialogInFlight(state: DialogServiceState, request: DialogRequest): void {\n state.inFlight.push(request)\n}\n\n/** Заявка вышла из полёта (колбэк вернулся или окно размонтировано). */\nexport function finishDialogInFlight(state: DialogServiceState, request: DialogRequest): void {\n const index = state.inFlight.indexOf(request)\n if (index >= 0)\n state.inFlight.splice(index, 1)\n}\n\n/**\n * Единственный способ завершить заявку: идемпотентно резолвит промис и снимает\n * её из очереди.\n *\n * `removeFromQueue: false` нужен окну: оно гасит себя и даёт анимации закрытия\n * доиграть, прежде чем заявка исчезнет из очереди. Корректность от этой\n * отсрочки не зависит: повторное завершение отсекается флагом на заявке.\n */\nexport function settleDialogRequest(\n state: DialogServiceState,\n request: DialogRequest,\n result: DialogResult<any>,\n { removeFromQueue = true }: { removeFromQueue?: boolean } = {},\n): boolean {\n if (request.settled)\n return false\n\n request.settled = true\n request.resolve(result)\n\n if (removeFromQueue)\n removeDialogRequest(state, request)\n\n return true\n}\n\n/** Снимает заявку из очереди, если она ещё там. */\nexport function removeDialogRequest(state: DialogServiceState, request: DialogRequest): void {\n const index = state.queue.findIndex(item => item.id === request.id)\n if (index >= 0)\n state.queue.splice(index, 1)\n}\n","import { createVNode, getCurrentInstance, inject, markRaw, render } from 'vue'\nimport type { App, AppContext, InjectionKey } from 'vue'\n\nimport { ensurePortalRoot } from '../../composables/internal/portalRoot'\nimport GrDialogServiceHost from './GrDialogServiceHost.vue'\nimport { useGrConfig } from '../GrConfigProvider/context'\nimport { resolveGranularityI18n } from '../../internal/granularityI18n'\nimport {\n createDialogServiceState,\n enqueueDialogRequest,\n makeDialogId,\n settleDialogRequest,\n} from './store'\nimport type { CapturedDialogContext, DialogRequest, DialogServiceState } from './store'\nimport type {\n DialogAlertOptions,\n DialogBaseOptions,\n DialogConfirmOptions,\n DialogKind,\n DialogOnConfirm,\n DialogPromise,\n DialogPromptOptions,\n DialogResult,\n DialogService,\n DialogServiceDefaults,\n} from './types'\n\n/**\n * `useDialogService` — императивный сервис диалогов (в духе Element Plus\n * `ElMessageBox`). Позволяет вызывать `confirm`/`alert`/`prompt` из `<script>`\n * или `.ts` без вставки компонента в шаблон.\n *\n * Поверх существующих `GrConfirmDialog`/`GrPromptDialog`: лениво монтирует\n * единый хост (`GrDialogServiceHost`) в `document.body`, наследуя контекст\n * приложения (i18n / тема / `granular-provider`).\n */\n\n/** Ключ provide/inject для app-scoped состояния сервиса (устанавливает плагин ниже). */\nexport const GRANULARITY_DIALOG_SERVICE_STATE: InjectionKey<DialogServiceState>\n = Symbol.for('@feugene/granularity/dialog-service-state')\n\n/**\n * Инстансы, заведённые плагином. Реестр нужен готовому синглтону\n * `dialogService`: он создаётся на импорте модуля, где `inject` не работает\n * вовсе, и сам до app-scoped состояния не дотянется. Ровно один\n * зарегистрированный — ответ однозначен; несколько — выбирать за пользователя\n * нечего, и он получает предупреждение с модульным фолбэком.\n */\nconst registeredStates = new Set<DialogServiceState>()\n\n/**\n * Vue-плагин: даёт каждому приложению собственное состояние сервиса и снимает\n * его хост вместе с приложением. Обязателен для нескольких Vue-приложений на\n * одной странице (микрофронтенды — иначе они делят одну очередь и один хост) и\n * для HMR, где контейнер прошлого приложения иначе остаётся в `document.body`.\n *\n * ```ts\n * app.use(granularityDialogServicePlugin)\n * ```\n */\nexport const granularityDialogServicePlugin = {\n install(app: App) {\n const state = createDialogServiceState()\n\n app.provide(GRANULARITY_DIALOG_SERVICE_STATE, state)\n registeredStates.add(state)\n\n app.onUnmount(() => {\n teardownDialogServiceState(state)\n registeredStates.delete(state)\n })\n },\n}\n\n// Ленивый модульный фолбэк — канонический вариант для простого SPA без плагина.\nlet moduleState: DialogServiceState | null = null\n\nfunction getModuleState(): DialogServiceState {\n if (!moduleState)\n moduleState = createDialogServiceState()\n\n return moduleState\n}\n\nlet ambiguousStateWarned = false\n\nfunction warnAmbiguousState(): void {\n if (ambiguousStateWarned) return\n if (!__GR_DEV__) return\n\n ambiguousStateWarned = true\n console.warn(\n '[granularity] useDialogService: плагин установлен в нескольких приложениях, '\n + 'а сервис запрошен вне `setup` — какое из них имелось в виду, знать неоткуда. '\n + 'Используется модульное состояние. Вызовите `useDialogService()` внутри `setup` нужного приложения.',\n )\n}\n\n/**\n * Состояние текущего вызова: app-scoped (плагин) → единственный\n * зарегистрированный инстанс → модульный фолбэк.\n */\nfunction resolveDialogServiceState(): DialogServiceState {\n // `inject` работает только в `setup` — там ответ точный.\n if (getCurrentInstance()) {\n const provided = inject(GRANULARITY_DIALOG_SERVICE_STATE, null)\n if (provided) return provided\n }\n\n if (registeredStates.size === 1)\n return registeredStates.values().next().value!\n\n if (registeredStates.size > 1)\n warnAmbiguousState()\n\n return getModuleState()\n}\n\nfunction ensureMounted(state: DialogServiceState, appContext?: AppContext | null): void {\n if (typeof window === 'undefined' || typeof document === 'undefined') return\n\n if (appContext) state.appContext = appContext\n if (state.mounted) return\n\n const container = document.createElement('div')\n container.setAttribute('data-gr-dialog-service-host', '')\n container.setAttribute('data-gr-overlay-root', '')\n // Хост уезжает в общий портал оверлеев: он должен лежать в той же ветке, что\n // и остальные слои, иначе правило `inert` пометит его вместе со страницей.\n ;(ensurePortalRoot() ?? document.body).appendChild(container)\n state.container = container\n\n // Состояние отдаём пропом: хост монтируется вне дерева и своим `inject` до\n // app-scoped состояния не дотянулся бы. `markRaw` — чтобы Vue не пытался\n // сделать реактивной саму обёртку: реактивна очередь внутри неё.\n const vnode = createVNode(GrDialogServiceHost, { state: markRaw(state) })\n vnode.appContext = state.appContext ?? null\n render(vnode, container)\n state.mounted = true\n}\n\nfunction warnIfContextless(state: DialogServiceState, context: CapturedDialogContext | null): void {\n if (state.contextlessWarned || context?.config || context?.i18n) return\n if (!__GR_DEV__) return\n\n state.contextlessWarned = true\n console.warn(\n '[granularity] useDialogService: диалог открыт без контекста приложения — '\n + 'ни `GrConfigProvider`, ни адаптер i18n не найдены, будут использованы дефолты. '\n + 'Вызовите `useDialogService()` внутри `setup` хотя бы один раз или передайте `setAppContext`.',\n )\n}\n\n/** Снимает смонтированный хост и сбрасывает захваченный контекст одного инстанса. */\nfunction teardownDialogServiceState(state: DialogServiceState): void {\n if (state.container) {\n render(null, state.container)\n state.container.remove()\n state.container = null\n }\n state.mounted = false\n // Сбрасываем и кэш контекста приложения: без этого он переживает teardown и\n // протекает в следующее приложение (в тестах — в следующий тест), из-за чего\n // диалог может подхватить чужие provides и проверка соврёт.\n state.appContext = null\n state.lastCapturedContext = null\n state.contextlessWarned = false\n state.queue.splice(0, state.queue.length)\n state.inFlight.splice(0, state.inFlight.length)\n}\n\n/**\n * Тестовая/служебная очистка смонтированного хоста. Работает над тем же\n * состоянием, что и сам сервис: app-scoped при вызове из `setup` или при\n * единственном зарегистрированном приложении, иначе — модульным.\n */\nexport function teardownDialogService(): void {\n teardownDialogServiceState(resolveDialogServiceState())\n}\n\nfunction enqueue(\n state: DialogServiceState,\n kind: DialogKind,\n message: string,\n options: DialogBaseOptions,\n onConfirm: DialogOnConfirm<any> | undefined,\n captured: CapturedDialogContext,\n): { promise: Promise<DialogResult<any>>, close: () => void } {\n // Императивный сервис клиент-only: монтирует хост в `document.body`. В SSR\n // выполнять его нельзя — очередь мутировалась бы на сервере и текла между\n // запросами. Явно запрещаем вместо тихого no-op.\n if (typeof window === 'undefined' || typeof document === 'undefined') {\n throw new Error(\n '[granularity] useDialogService is client-only and cannot be called during SSR '\n + '(it mounts a host into document.body). Guard imperative dialog calls behind a client-side check.',\n )\n }\n\n ensureMounted(state, options.appContext ?? state.appContext)\n\n const id = makeDialogId()\n let resolveFn!: (result: DialogResult<any>) => void\n const promise = new Promise<DialogResult<any>>((resolve) => {\n resolveFn = resolve\n })\n\n // Синглтон `dialogService` создаётся на импорте модуля, вне `setup`, и своего\n // контекста не имеет в принципе. Берём последний захваченный — иначе такие\n // вызовы навсегда остаются без i18n и без `GrConfigProvider`.\n const context = captured.config || captured.i18n ? captured : state.lastCapturedContext\n warnIfContextless(state, context)\n\n const request: DialogRequest = {\n id,\n kind,\n message,\n options: { ...options, message },\n onConfirm,\n priority: options.priority ?? 0,\n nested: false,\n settled: false,\n resolve: resolveFn,\n config: context?.config ?? null,\n i18n: context?.i18n ?? null,\n }\n\n enqueueDialogRequest(state, request)\n\n // Закрытие через промис идёт тем же путём, что и кнопка в окне: заявка сама\n // знает, завершена ли она, а окно по её исчезновению свернёт всё, что под неё\n // заведено (в т.ч. оборвёт in-flight `onConfirm` через `abort()`).\n const close = (): void => {\n settleDialogRequest(state, request, { action: 'close' })\n }\n\n return { promise, close }\n}\n\nfunction withClose<T>(promise: Promise<T>, close: () => void): DialogPromise<T> {\n const result = promise as DialogPromise<T>\n result.close = close\n return result\n}\n\nfunction mergeErrorDefaults(\n defaults: DialogServiceDefaults,\n options: DialogBaseOptions,\n): DialogBaseOptions & Pick<DialogConfirmOptions, 'cancelText'> {\n return {\n size: defaults.size,\n confirmText: defaults.confirmText,\n confirmVariant: defaults.confirmVariant,\n confirmTone: defaults.confirmTone,\n cancelText: defaults.cancelText,\n buttonSize: defaults.buttonSize,\n closeOnBackdrop: defaults.closeOnBackdrop,\n closeOnEsc: defaults.closeOnEsc,\n errorParsers: defaults.errorParsers,\n errorTexts: defaults.errorTexts,\n errorMessageKey: defaults.errorMessageKey,\n fieldLabels: defaults.fieldLabels,\n ...options,\n }\n}\n\n/**\n * Создаёт сервис диалогов. Опциональные `defaults` применяются ко всем\n * вызовам (можно переопределить в каждом конкретном вызове).\n *\n * Контекст приложения кэшируется автоматически при первом вызове внутри\n * `setup`. Для вызовов вне компонента используйте `setAppContext`.\n */\nexport function useDialogService(defaults: DialogServiceDefaults = {}): DialogService {\n const state = resolveDialogServiceState()\n\n // Авто-кэш appContext из текущего компонента (если вызвано в setup).\n const instance = getCurrentInstance()\n if (instance?.appContext && !state.appContext) {\n state.appContext = instance.appContext\n }\n\n // Конфиг и i18n захватываем здесь и только здесь: `inject` работает лишь в\n // `setup`, а хост монтируется вне дерева и сам до провайдера не дотянется.\n // Храним в замыкании сервиса, а не в состоянии, — иначе два поддерева с\n // разными провайдерами делили бы конфиг первого.\n // i18n захватываем не «на всякий случай»: дочерний `GrConfirmDialog` сам зовёт\n // `useGranularityTranslations()`, но его `inject` из хоста уходит в\n // `appContext.provides` — то есть видит только установку через `app.use()`.\n // Адаптер, переданный пропом `<GrConfigProvider i18n>`, живёт в дереве, и без\n // захвата диалог откатился бы на встроенные английские строки.\n //\n // `markRaw` — потому что дальше контекст ложится в `reactive`-очередь, а она\n // разворачивает вложенные рефы (см. комментарий в `store.ts`).\n const capturedI18n = instance ? resolveGranularityI18n() : null\n const captured: CapturedDialogContext = {\n config: instance ? markRaw(useGrConfig()) : null,\n i18n: capturedI18n ? markRaw(capturedI18n) : null,\n }\n\n if (captured.config || captured.i18n)\n state.lastCapturedContext = captured\n\n function confirm(message: string, options: DialogConfirmOptions = {}): DialogPromise<boolean> {\n const merged = mergeErrorDefaults(defaults, options)\n const { promise, close } = enqueue(state, 'confirm', message, merged, options.onConfirm, captured)\n return withClose(promise.then(r => r.action === 'confirm'), close)\n }\n\n function alert(message: string, options: DialogAlertOptions = {}): DialogPromise<void> {\n const merged = mergeErrorDefaults(defaults, options)\n const { promise, close } = enqueue(state, 'alert', message, merged, options.onConfirm, captured)\n return withClose(promise.then(() => undefined), close)\n }\n\n function prompt(message: string, options: DialogPromptOptions = {}): DialogPromise<string | null> {\n const merged = mergeErrorDefaults(defaults, options)\n const { promise, close } = enqueue(state, 'prompt', message, merged, options.onConfirm, captured)\n return withClose(\n promise.then(r => (r.action === 'confirm' ? ((r.value as string) ?? '') : null)),\n close,\n )\n }\n\n function open<V = unknown>(\n kind: DialogKind,\n message: string,\n options: DialogBaseOptions = {},\n ): DialogPromise<DialogResult<V>> {\n const merged = mergeErrorDefaults(defaults, options)\n const { promise, close } = enqueue(\n state,\n kind,\n message,\n merged,\n (options as DialogConfirmOptions).onConfirm,\n captured,\n )\n return withClose(promise as Promise<DialogResult<V>>, close)\n }\n\n // Порядок разбора — FIFO, как и порядок показа: `pop()` резолвил промисы\n // задом наперёд, и вызывающий получал результаты в обратном порядке.\n function closeAll(): void {\n for (const request of [...state.queue])\n settleDialogRequest(state, request, { action: 'close' })\n }\n\n function setAppContext(ctx: AppContext | null): void {\n state.appContext = ctx\n }\n\n return { confirm, alert, prompt, open, closeAll, setAppContext }\n}\n\n/** Готовый синглтон-сервис с дефолтными настройками. */\nexport const dialogService: DialogService = {\n confirm: (message, options) => useDialogService().confirm(message, options),\n alert: (message, options) => useDialogService().alert(message, options),\n prompt: (message, options) => useDialogService().prompt(message, options),\n open: (kind, message, options) => useDialogService().open(kind, message, options),\n closeAll: () => useDialogService().closeAll(),\n setAppContext: ctx => useDialogService().setAppContext(ctx),\n}\n","<script setup lang=\"ts\">\n/**\n * GrDialogServiceItem — одно окно императивного сервиса. Внутренний компонент,\n * в шаблонах напрямую не используется.\n *\n * Всё состояние живёт здесь, а не на хосте, ровно потому, что окон может быть\n * несколько: вложенный вызов из `onConfirm` показывается поверх родителя, и\n * общий `loading` с общей ошибкой означали бы, что верхнее окно пишет в нижнее.\n */\nimport { computed, inject, nextTick, onBeforeUnmount, onMounted, provide, ref, shallowRef } from 'vue'\n\nimport GrButton from '../GrButton/GrButton.vue'\nimport GrConfirmDialog from '../GrConfirmDialog/GrConfirmDialog.vue'\nimport GrPromptDialog from '../GrPromptDialog/GrPromptDialog.vue'\nimport {\n coreResponseErrorParsers,\n createResponseErrorClassifier,\n responseErrorParserPresets,\n} from '../GrResponseErrorBanner/parsers'\nimport type { ResponseErrorInfo } from '../GrResponseErrorBanner'\n\nimport { GR_CONFIG_KEY, type GrComponentDefaults, type GrConfigContext } from '../GrConfigProvider/context'\nimport { GRANULARITY_I18N_KEY } from '../../i18n/adapter'\nimport { resolveGranularityI18n, useGranularityTranslations } from '../../internal/granularityI18n'\n\nimport { finishDialogInFlight, removeDialogRequest, settleDialogRequest, startDialogInFlight } from './store'\nimport type { DialogRequest, DialogServiceState } from './store'\nimport { GRANULARITY_DIALOG_SERVICE_STATE } from './useDialogService'\nimport type { DialogCloseAction, DialogConfirmContext, DialogConfirmOptions, DialogPromptOptions } from './types'\n\nconst props = defineProps<{\n request: DialogRequest\n}>()\n\n// Состояние инстанса приходит через `provide` хоста, а не пропом: окно его\n// мутирует (очередь, список заявок в полёте), а мутировать проп — значит писать\n// в чужое владение.\nconst state = inject(GRANULARITY_DIALOG_SERVICE_STATE) as DialogServiceState\n\n// ————— Мост конфига и i18n.\n//\n// Окно рендерится через `render(vnode, container)` в `document.body`, то есть вне\n// дерева компонентов. Vue в этом случае берёт `provides` только из `appContext`,\n// куда попадает лишь `app.provide()` — значения от `<GrConfigProvider>` до сюда\n// не доходят. Поэтому вызов сервиса захватывает их в `setup` и кладёт в заявку,\n// а окно раздаёт вниз конфиг **своей** заявки.\nconst EMPTY_DEFAULTS: GrComponentDefaults = Object.freeze({})\n\nprovide<GrConfigContext>(GR_CONFIG_KEY, {\n size: computed(() => props.request.config?.size.value),\n componentDefaults: computed(() => props.request.config?.componentDefaults.value ?? EMPTY_DEFAULTS),\n})\n\n// i18n: тот же приём. Адаптер хоста (из `appContext`) — запасной вариант для\n// вызова без захваченного: без него установка через `app.use()` осталась бы\n// незамеченной.\nconst hostI18n = resolveGranularityI18n()\n\nprovide(GRANULARITY_I18N_KEY, {\n t: (key: string, params?: Record<string, unknown>) => {\n const adapter = props.request.i18n ?? hostI18n\n // Вернуть сам ключ — принятый в пакете сигнал «перевода нет»: потребитель\n // подставит свой fallback-текст (см. `useGranularityTranslations`).\n return adapter?.t(key, params) ?? key\n },\n get locale() {\n return (props.request.i18n ?? hostI18n)?.locale\n },\n})\n\n// Подвал alert-ветки рисуется здесь, поэтому и перевод кнопки достаётся здесь.\n// Адаптер берём тот же, что раздан вниз: собственный `provide` компонента его\n// же `inject` не видит, и `useGranularityTranslations()` без аргумента ушёл бы\n// мимо захваченного вызовом адаптера — в фолбэк из `appContext`.\nconst alertConfirmText = computed(() => {\n const { t } = useGranularityTranslations(props.request.i18n ?? hostI18n)\n return t('gr.dialog.ok', 'OK')\n})\n\nconst open = ref(false)\nconst loading = ref(false)\nconst currentError = shallowRef<ResponseErrorInfo | null>(null)\n/**\n * Ошибки по именам полей. Карта, а не одна строка: `setFieldError(field, …)`\n * обещает адресность, и обещание должно быть правдой ещё до того, как в\n * диалоге появится второе поле.\n */\nconst fieldErrors = ref<Record<string, string>>({})\nconst promptValue = ref(\n props.request.options && 'value' in props.request.options\n ? ((props.request.options as { value?: string }).value ?? '')\n : '',\n)\n\n/** Единственное поле `GrPromptDialog` называется `value`. */\nconst PROMPT_FIELD = 'value'\n\n// Одна запись — её и показываем: адрес не важен, когда адресат один.\nconst promptFieldError = computed<string | null>(() => {\n const own = fieldErrors.value[PROMPT_FIELD]\n if (own != null) return own\n\n const entries = Object.values(fieldErrors.value)\n return entries.length === 1 ? entries[0] : null\n})\n\nconst hasFieldError = computed(() => Object.keys(fieldErrors.value).length > 0)\n\nconst controller = new AbortController()\nlet externalAbortCleanup: (() => void) | null = null\n\nfunction buildClassifier() {\n const opts = props.request.options\n const parsers = typeof opts.errorParsers === 'function'\n ? opts.errorParsers(responseErrorParserPresets)\n : opts.errorParsers ?? coreResponseErrorParsers\n\n return createResponseErrorClassifier({\n parsers,\n texts: opts.errorTexts,\n messageKey: opts.errorMessageKey,\n })\n}\n\nonMounted(() => {\n // Внешний AbortSignal закрывает диалог как `close`.\n const sig = props.request.options.signal\n if (sig) {\n if (sig.aborted) {\n finish('close')\n return\n }\n const onAbort = () => finish('close')\n sig.addEventListener('abort', onAbort)\n externalAbortCleanup = () => sig.removeEventListener('abort', onAbort)\n }\n\n void nextTick(() => {\n open.value = true\n })\n})\n\nonBeforeUnmount(() => {\n // Снимаем всё, что заведено под заявку: подписку на внешний сигнал и свой\n // контроллер. Размонтирование — единственная точка, которую видят все три\n // пути завершения (кнопка, `close()` промиса, `closeAll()`), поэтому обрыв\n // in-flight `onConfirm` живёт именно здесь.\n externalAbortCleanup?.()\n externalAbortCleanup = null\n controller.abort()\n\n finishDialogInFlight(state, props.request)\n})\n\nfunction finish(action: DialogCloseAction, value?: unknown): void {\n // Снятие заявки из очереди откладываем на тик: окно должно успеть закрыться\n // до того, как исчезнет из разметки.\n if (!settleDialogRequest(state, props.request, { action, value }, { removeFromQueue: false }))\n return\n\n open.value = false\n void nextTick(() => removeDialogRequest(state, props.request))\n}\n\nfunction buildContext(value: unknown): DialogConfirmContext<any> & { _errorSet: () => boolean } {\n let errorSet = false\n\n const setError = (message: string | null): void => {\n if (message == null) {\n currentError.value = null\n return\n }\n errorSet = true\n currentError.value = { kind: 'unknown', message, raw: message }\n }\n\n const setFieldError = (field: string, message: string | null): void => {\n const next = { ...fieldErrors.value }\n if (message == null) {\n delete next[field]\n fieldErrors.value = next\n return\n }\n errorSet = true\n next[field] = message\n fieldErrors.value = next\n }\n\n const clearErrors = (): void => {\n currentError.value = null\n fieldErrors.value = {}\n }\n\n const setRawError = async (raw: unknown, meta?: Record<string, unknown>): Promise<ResponseErrorInfo | null> => {\n const info = await buildClassifier()(raw, meta)\n if (info.fieldErrors?.length) {\n const next = { ...fieldErrors.value }\n for (const entry of info.fieldErrors)\n next[entry.field] = entry.messages.join(' ')\n fieldErrors.value = next\n }\n currentError.value = info\n errorSet = true\n return info\n }\n\n return {\n value,\n signal: controller.signal,\n setError,\n setRawError,\n setFieldError,\n clearErrors,\n setLoading: (v: boolean) => { loading.value = v },\n close: (action: DialogCloseAction = 'close') => finish(action),\n _errorSet: () => errorSet,\n }\n}\n\nasync function handleConfirm(): Promise<void> {\n const req = props.request\n const value = req.kind === 'prompt' ? promptValue.value : undefined\n\n if (!req.onConfirm) {\n finish('confirm', value)\n return\n }\n\n currentError.value = null\n fieldErrors.value = {}\n loading.value = true\n\n const ctx = buildContext(value)\n\n // Пока колбэк в полёте, заявка считается родителем для новых вызовов: диалог,\n // открытый изнутри `onConfirm`, показывается поверх, а не встаёт в очередь за\n // тем, кто его ждёт.\n startDialogInFlight(state, req)\n\n try {\n const result = await req.onConfirm(ctx)\n // Сначала проверка «диалог ещё жив», потом запись состояния: за время\n // `await` заявку мог завершить `ctx.close()` или `closeAll()`.\n if (req.settled) return\n loading.value = false\n if (result === false) return // оставить открытым без ошибки\n if (currentError.value || hasFieldError.value || ctx._errorSet()) return // есть ошибка — не закрывать\n finish('confirm', value)\n }\n catch (error) {\n if (req.settled) return\n loading.value = false\n if (!ctx._errorSet()) await ctx.setRawError(error)\n // оставить диалог открытым с показанной ошибкой\n }\n finally {\n finishDialogInFlight(state, req)\n }\n}\n\nfunction handleCancel(): void {\n finish('cancel')\n}\n\nfunction handleModelUpdate(value: boolean): void {\n if (!value) finish('close')\n}\n\n// Опции веток читаются типизированно, без `as any` в шаблоне.\nconst promptOptions = computed<DialogPromptOptions>(() => props.request.options as DialogPromptOptions)\nconst confirmOptions = computed<DialogConfirmOptions>(() => props.request.options as DialogConfirmOptions)\n\n// Прокидываемые в дочерний диалог общие пропы.\nconst sharedProps = computed(() => {\n const o = props.request.options\n return {\n title: o.title,\n size: o.size,\n closeOnBackdrop: o.closeOnBackdrop,\n closeOnEsc: o.closeOnEsc,\n // Подавление «мягкого» закрытия на время `onConfirm` считает сам диалог по\n // `confirmLoading` — здесь только включаем режим, чтобы механизм жил в\n // одном месте, а не дублировался сервисом.\n persistent: true,\n showHeader: o.showHeader,\n showCloseButton: o.showCloseButton,\n headerConfig: o.headerConfig,\n footerConfig: o.footerConfig,\n bodyConfig: o.bodyConfig,\n closeLabel: o.closeLabel,\n buttonSize: o.buttonSize,\n confirmText: o.confirmText,\n confirmVariant: o.confirmVariant,\n confirmTone: o.confirmTone,\n }\n})\n</script>\n\n<template>\n <!-- prompt -->\n <GrPromptDialog\n v-if=\"request.kind === 'prompt'\"\n v-bind=\"sharedProps\"\n v-model:value=\"promptValue\"\n :model-value=\"open\"\n :description=\"request.options.message ?? request.options.description\"\n :label=\"promptOptions.label\"\n :placeholder=\"promptOptions.placeholder\"\n :required=\"promptOptions.required ?? false\"\n :required-error-text=\"promptOptions.requiredErrorText\"\n :cancel-text=\"promptOptions.cancelText\"\n :input-type=\"promptOptions.inputType\"\n :inputmode=\"promptOptions.inputmode\"\n :maxlength=\"promptOptions.maxlength\"\n :show-count=\"promptOptions.showCount\"\n :multiline=\"promptOptions.multiline\"\n :rows=\"promptOptions.rows\"\n :autosize=\"promptOptions.autosize\"\n :rules=\"promptOptions.rules\"\n :error=\"currentError\"\n :field-error=\"promptFieldError\"\n :confirm-loading=\"loading\"\n :close-on-confirm=\"false\"\n @update:model-value=\"handleModelUpdate\"\n @confirm=\"handleConfirm\"\n @cancel=\"handleCancel\"\n />\n\n <!-- alert: confirm-диалог без кнопки Cancel -->\n <GrConfirmDialog\n v-else-if=\"request.kind === 'alert'\"\n :model-value=\"open\"\n v-bind=\"sharedProps\"\n :description=\"request.options.message ?? request.options.description\"\n :error=\"currentError\"\n :confirm-loading=\"loading\"\n :close-on-confirm=\"false\"\n @update:model-value=\"handleModelUpdate\"\n @confirm=\"handleConfirm\"\n >\n <template #footer>\n <div class=\"flex items-center justify-end gap-3\">\n <GrButton\n data-testid=\"gr-alert-confirm\"\n :variant=\"sharedProps.confirmVariant ?? 'primary'\"\n :tone=\"sharedProps.confirmTone ?? 'primary'\"\n :size=\"sharedProps.buttonSize\"\n :loading=\"loading\"\n @click=\"handleConfirm\"\n >\n {{ sharedProps.confirmText ?? alertConfirmText }}\n </GrButton>\n </div>\n </template>\n </GrConfirmDialog>\n\n <!-- confirm -->\n <GrConfirmDialog\n v-else\n :model-value=\"open\"\n v-bind=\"sharedProps\"\n :description=\"request.options.message ?? request.options.description\"\n :cancel-text=\"confirmOptions.cancelText\"\n :error=\"currentError\"\n :confirm-loading=\"loading\"\n :close-on-confirm=\"false\"\n @update:model-value=\"handleModelUpdate\"\n @confirm=\"handleConfirm\"\n @cancel=\"handleCancel\"\n />\n</template>\n","<script setup lang=\"ts\">\n/**\n * GrDialogServiceItem — одно окно императивного сервиса. Внутренний компонент,\n * в шаблонах напрямую не используется.\n *\n * Всё состояние живёт здесь, а не на хосте, ровно потому, что окон может быть\n * несколько: вложенный вызов из `onConfirm` показывается поверх родителя, и\n * общий `loading` с общей ошибкой означали бы, что верхнее окно пишет в нижнее.\n */\nimport { computed, inject, nextTick, onBeforeUnmount, onMounted, provide, ref, shallowRef } from 'vue'\n\nimport GrButton from '../GrButton/GrButton.vue'\nimport GrConfirmDialog from '../GrConfirmDialog/GrConfirmDialog.vue'\nimport GrPromptDialog from '../GrPromptDialog/GrPromptDialog.vue'\nimport {\n coreResponseErrorParsers,\n createResponseErrorClassifier,\n responseErrorParserPresets,\n} from '../GrResponseErrorBanner/parsers'\nimport type { ResponseErrorInfo } from '../GrResponseErrorBanner'\n\nimport { GR_CONFIG_KEY, type GrComponentDefaults, type GrConfigContext } from '../GrConfigProvider/context'\nimport { GRANULARITY_I18N_KEY } from '../../i18n/adapter'\nimport { resolveGranularityI18n, useGranularityTranslations } from '../../internal/granularityI18n'\n\nimport { finishDialogInFlight, removeDialogRequest, settleDialogRequest, startDialogInFlight } from './store'\nimport type { DialogRequest, DialogServiceState } from './store'\nimport { GRANULARITY_DIALOG_SERVICE_STATE } from './useDialogService'\nimport type { DialogCloseAction, DialogConfirmContext, DialogConfirmOptions, DialogPromptOptions } from './types'\n\nconst props = defineProps<{\n request: DialogRequest\n}>()\n\n// Состояние инстанса приходит через `provide` хоста, а не пропом: окно его\n// мутирует (очередь, список заявок в полёте), а мутировать проп — значит писать\n// в чужое владение.\nconst state = inject(GRANULARITY_DIALOG_SERVICE_STATE) as DialogServiceState\n\n// ————— Мост конфига и i18n.\n//\n// Окно рендерится через `render(vnode, container)` в `document.body`, то есть вне\n// дерева компонентов. Vue в этом случае берёт `provides` только из `appContext`,\n// куда попадает лишь `app.provide()` — значения от `<GrConfigProvider>` до сюда\n// не доходят. Поэтому вызов сервиса захватывает их в `setup` и кладёт в заявку,\n// а окно раздаёт вниз конфиг **своей** заявки.\nconst EMPTY_DEFAULTS: GrComponentDefaults = Object.freeze({})\n\nprovide<GrConfigContext>(GR_CONFIG_KEY, {\n size: computed(() => props.request.config?.size.value),\n componentDefaults: computed(() => props.request.config?.componentDefaults.value ?? EMPTY_DEFAULTS),\n})\n\n// i18n: тот же приём. Адаптер хоста (из `appContext`) — запасной вариант для\n// вызова без захваченного: без него установка через `app.use()` осталась бы\n// незамеченной.\nconst hostI18n = resolveGranularityI18n()\n\nprovide(GRANULARITY_I18N_KEY, {\n t: (key: string, params?: Record<string, unknown>) => {\n const adapter = props.request.i18n ?? hostI18n\n // Вернуть сам ключ — принятый в пакете сигнал «перевода нет»: потребитель\n // подставит свой fallback-текст (см. `useGranularityTranslations`).\n return adapter?.t(key, params) ?? key\n },\n get locale() {\n return (props.request.i18n ?? hostI18n)?.locale\n },\n})\n\n// Подвал alert-ветки рисуется здесь, поэтому и перевод кнопки достаётся здесь.\n// Адаптер берём тот же, что раздан вниз: собственный `provide` компонента его\n// же `inject` не видит, и `useGranularityTranslations()` без аргумента ушёл бы\n// мимо захваченного вызовом адаптера — в фолбэк из `appContext`.\nconst alertConfirmText = computed(() => {\n const { t } = useGranularityTranslations(props.request.i18n ?? hostI18n)\n return t('gr.dialog.ok', 'OK')\n})\n\nconst open = ref(false)\nconst loading = ref(false)\nconst currentError = shallowRef<ResponseErrorInfo | null>(null)\n/**\n * Ошибки по именам полей. Карта, а не одна строка: `setFieldError(field, …)`\n * обещает адресность, и обещание должно быть правдой ещё до того, как в\n * диалоге появится второе поле.\n */\nconst fieldErrors = ref<Record<string, string>>({})\nconst promptValue = ref(\n props.request.options && 'value' in props.request.options\n ? ((props.request.options as { value?: string }).value ?? '')\n : '',\n)\n\n/** Единственное поле `GrPromptDialog` называется `value`. */\nconst PROMPT_FIELD = 'value'\n\n// Одна запись — её и показываем: адрес не важен, когда адресат один.\nconst promptFieldError = computed<string | null>(() => {\n const own = fieldErrors.value[PROMPT_FIELD]\n if (own != null) return own\n\n const entries = Object.values(fieldErrors.value)\n return entries.length === 1 ? entries[0] : null\n})\n\nconst hasFieldError = computed(() => Object.keys(fieldErrors.value).length > 0)\n\nconst controller = new AbortController()\nlet externalAbortCleanup: (() => void) | null = null\n\nfunction buildClassifier() {\n const opts = props.request.options\n const parsers = typeof opts.errorParsers === 'function'\n ? opts.errorParsers(responseErrorParserPresets)\n : opts.errorParsers ?? coreResponseErrorParsers\n\n return createResponseErrorClassifier({\n parsers,\n texts: opts.errorTexts,\n messageKey: opts.errorMessageKey,\n })\n}\n\nonMounted(() => {\n // Внешний AbortSignal закрывает диалог как `close`.\n const sig = props.request.options.signal\n if (sig) {\n if (sig.aborted) {\n finish('close')\n return\n }\n const onAbort = () => finish('close')\n sig.addEventListener('abort', onAbort)\n externalAbortCleanup = () => sig.removeEventListener('abort', onAbort)\n }\n\n void nextTick(() => {\n open.value = true\n })\n})\n\nonBeforeUnmount(() => {\n // Снимаем всё, что заведено под заявку: подписку на внешний сигнал и свой\n // контроллер. Размонтирование — единственная точка, которую видят все три\n // пути завершения (кнопка, `close()` промиса, `closeAll()`), поэтому обрыв\n // in-flight `onConfirm` живёт именно здесь.\n externalAbortCleanup?.()\n externalAbortCleanup = null\n controller.abort()\n\n finishDialogInFlight(state, props.request)\n})\n\nfunction finish(action: DialogCloseAction, value?: unknown): void {\n // Снятие заявки из очереди откладываем на тик: окно должно успеть закрыться\n // до того, как исчезнет из разметки.\n if (!settleDialogRequest(state, props.request, { action, value }, { removeFromQueue: false }))\n return\n\n open.value = false\n void nextTick(() => removeDialogRequest(state, props.request))\n}\n\nfunction buildContext(value: unknown): DialogConfirmContext<any> & { _errorSet: () => boolean } {\n let errorSet = false\n\n const setError = (message: string | null): void => {\n if (message == null) {\n currentError.value = null\n return\n }\n errorSet = true\n currentError.value = { kind: 'unknown', message, raw: message }\n }\n\n const setFieldError = (field: string, message: string | null): void => {\n const next = { ...fieldErrors.value }\n if (message == null) {\n delete next[field]\n fieldErrors.value = next\n return\n }\n errorSet = true\n next[field] = message\n fieldErrors.value = next\n }\n\n const clearErrors = (): void => {\n currentError.value = null\n fieldErrors.value = {}\n }\n\n const setRawError = async (raw: unknown, meta?: Record<string, unknown>): Promise<ResponseErrorInfo | null> => {\n const info = await buildClassifier()(raw, meta)\n if (info.fieldErrors?.length) {\n const next = { ...fieldErrors.value }\n for (const entry of info.fieldErrors)\n next[entry.field] = entry.messages.join(' ')\n fieldErrors.value = next\n }\n currentError.value = info\n errorSet = true\n return info\n }\n\n return {\n value,\n signal: controller.signal,\n setError,\n setRawError,\n setFieldError,\n clearErrors,\n setLoading: (v: boolean) => { loading.value = v },\n close: (action: DialogCloseAction = 'close') => finish(action),\n _errorSet: () => errorSet,\n }\n}\n\nasync function handleConfirm(): Promise<void> {\n const req = props.request\n const value = req.kind === 'prompt' ? promptValue.value : undefined\n\n if (!req.onConfirm) {\n finish('confirm', value)\n return\n }\n\n currentError.value = null\n fieldErrors.value = {}\n loading.value = true\n\n const ctx = buildContext(value)\n\n // Пока колбэк в полёте, заявка считается родителем для новых вызовов: диалог,\n // открытый изнутри `onConfirm`, показывается поверх, а не встаёт в очередь за\n // тем, кто его ждёт.\n startDialogInFlight(state, req)\n\n try {\n const result = await req.onConfirm(ctx)\n // Сначала проверка «диалог ещё жив», потом запись состояния: за время\n // `await` заявку мог завершить `ctx.close()` или `closeAll()`.\n if (req.settled) return\n loading.value = false\n if (result === false) return // оставить открытым без ошибки\n if (currentError.value || hasFieldError.value || ctx._errorSet()) return // есть ошибка — не закрывать\n finish('confirm', value)\n }\n catch (error) {\n if (req.settled) return\n loading.value = false\n if (!ctx._errorSet()) await ctx.setRawError(error)\n // оставить диалог открытым с показанной ошибкой\n }\n finally {\n finishDialogInFlight(state, req)\n }\n}\n\nfunction handleCancel(): void {\n finish('cancel')\n}\n\nfunction handleModelUpdate(value: boolean): void {\n if (!value) finish('close')\n}\n\n// Опции веток читаются типизированно, без `as any` в шаблоне.\nconst promptOptions = computed<DialogPromptOptions>(() => props.request.options as DialogPromptOptions)\nconst confirmOptions = computed<DialogConfirmOptions>(() => props.request.options as DialogConfirmOptions)\n\n// Прокидываемые в дочерний диалог общие пропы.\nconst sharedProps = computed(() => {\n const o = props.request.options\n return {\n title: o.title,\n size: o.size,\n closeOnBackdrop: o.closeOnBackdrop,\n closeOnEsc: o.closeOnEsc,\n // Подавление «мягкого» закрытия на время `onConfirm` считает сам диалог по\n // `confirmLoading` — здесь только включаем режим, чтобы механизм жил в\n // одном месте, а не дублировался сервисом.\n persistent: true,\n showHeader: o.showHeader,\n showCloseButton: o.showCloseButton,\n headerConfig: o.headerConfig,\n footerConfig: o.footerConfig,\n bodyConfig: o.bodyConfig,\n closeLabel: o.closeLabel,\n buttonSize: o.buttonSize,\n confirmText: o.confirmText,\n confirmVariant: o.confirmVariant,\n confirmTone: o.confirmTone,\n }\n})\n</script>\n\n<template>\n <!-- prompt -->\n <GrPromptDialog\n v-if=\"request.kind === 'prompt'\"\n v-bind=\"sharedProps\"\n v-model:value=\"promptValue\"\n :model-value=\"open\"\n :description=\"request.options.message ?? request.options.description\"\n :label=\"promptOptions.label\"\n :placeholder=\"promptOptions.placeholder\"\n :required=\"promptOptions.required ?? false\"\n :required-error-text=\"promptOptions.requiredErrorText\"\n :cancel-text=\"promptOptions.cancelText\"\n :input-type=\"promptOptions.inputType\"\n :inputmode=\"promptOptions.inputmode\"\n :maxlength=\"promptOptions.maxlength\"\n :show-count=\"promptOptions.showCount\"\n :multiline=\"promptOptions.multiline\"\n :rows=\"promptOptions.rows\"\n :autosize=\"promptOptions.autosize\"\n :rules=\"promptOptions.rules\"\n :error=\"currentError\"\n :field-error=\"promptFieldError\"\n :confirm-loading=\"loading\"\n :close-on-confirm=\"false\"\n @update:model-value=\"handleModelUpdate\"\n @confirm=\"handleConfirm\"\n @cancel=\"handleCancel\"\n />\n\n <!-- alert: confirm-диалог без кнопки Cancel -->\n <GrConfirmDialog\n v-else-if=\"request.kind === 'alert'\"\n :model-value=\"open\"\n v-bind=\"sharedProps\"\n :description=\"request.options.message ?? request.options.description\"\n :error=\"currentError\"\n :confirm-loading=\"loading\"\n :close-on-confirm=\"false\"\n @update:model-value=\"handleModelUpdate\"\n @confirm=\"handleConfirm\"\n >\n <template #footer>\n <div class=\"flex items-center justify-end gap-3\">\n <GrButton\n data-testid=\"gr-alert-confirm\"\n :variant=\"sharedProps.confirmVariant ?? 'primary'\"\n :tone=\"sharedProps.confirmTone ?? 'primary'\"\n :size=\"sharedProps.buttonSize\"\n :loading=\"loading\"\n @click=\"handleConfirm\"\n >\n {{ sharedProps.confirmText ?? alertConfirmText }}\n </GrButton>\n </div>\n </template>\n </GrConfirmDialog>\n\n <!-- confirm -->\n <GrConfirmDialog\n v-else\n :model-value=\"open\"\n v-bind=\"sharedProps\"\n :description=\"request.options.message ?? request.options.description\"\n :cancel-text=\"confirmOptions.cancelText\"\n :error=\"currentError\"\n :confirm-loading=\"loading\"\n :close-on-confirm=\"false\"\n @update:model-value=\"handleModelUpdate\"\n @confirm=\"handleConfirm\"\n @cancel=\"handleCancel\"\n />\n</template>\n","<script setup lang=\"ts\">\n/**\n * GrDialogServiceHost — внутренний компонент-оркестратор императивного\n * `useDialogService`. Не предназначен для прямого использования в шаблонах.\n *\n * Держит раскладку очереди и ничего больше: состояние каждой заявки — загрузка,\n * ошибки, введённое значение, мост конфига и i18n — живёт в\n * `GrDialogServiceItem`, потому что окон может быть несколько.\n *\n * Видимы голова очереди и её вложенные окна (`store.visibleDialogRequests`):\n * обычные вызовы по-прежнему показываются по одному, а диалог, открытый из\n * `onConfirm` другого диалога, ложится поверх родителя — иначе он ждал бы в\n * очереди того, кто ждёт его.\n */\nimport { computed, inject, provide } from 'vue'\n\nimport GrDialogServiceItem from './GrDialogServiceItem.vue'\nimport { visibleDialogRequests } from './store'\nimport type { DialogRequest, DialogServiceState } from './store'\nimport { GRANULARITY_DIALOG_SERVICE_STATE } from './useDialogService'\n\nexport interface GrDialogServiceHostProps {\n /**\n * Состояние инстанса сервиса. Приходит пропом при программном монтировании:\n * хост живёт вне дерева и своим `inject` до app-scoped состояния не дотянулся\n * бы. `inject` остаётся для случая, когда хост поставили в шаблон руками.\n */\n state?: DialogServiceState | null\n}\n\nconst props = defineProps<GrDialogServiceHostProps>()\n\nconst injected = inject(GRANULARITY_DIALOG_SERVICE_STATE, null)\n\nconst activeState = computed<DialogServiceState | null>(() => props.state ?? injected)\n\nconst visible = computed<DialogRequest[]>(() =>\n activeState.value ? visibleDialogRequests(activeState.value) : [],\n)\n\n// Окна берут состояние отсюда, а не пропом: они его мутируют (очередь, список\n// заявок в полёте), а мутировать проп — значит писать в чужое владение.\nprovide(GRANULARITY_DIALOG_SERVICE_STATE, activeState.value!)\n</script>\n\n<template>\n <GrDialogServiceItem\n v-for=\"request in visible\"\n :key=\"request.id\"\n :request=\"request\"\n />\n</template>\n","<script setup lang=\"ts\">\n/**\n * GrDialogServiceHost — внутренний компонент-оркестратор императивного\n * `useDialogService`. Не предназначен для прямого использования в шаблонах.\n *\n * Держит раскладку очереди и ничего больше: состояние каждой заявки — загрузка,\n * ошибки, введённое значение, мост конфига и i18n — живёт в\n * `GrDialogServiceItem`, потому что окон может быть несколько.\n *\n * Видимы голова очереди и её вложенные окна (`store.visibleDialogRequests`):\n * обычные вызовы по-прежнему показываются по одному, а диалог, открытый из\n * `onConfirm` другого диалога, ложится поверх родителя — иначе он ждал бы в\n * очереди того, кто ждёт его.\n */\nimport { computed, inject, provide } from 'vue'\n\nimport GrDialogServiceItem from './GrDialogServiceItem.vue'\nimport { visibleDialogRequests } from './store'\nimport type { DialogRequest, DialogServiceState } from './store'\nimport { GRANULARITY_DIALOG_SERVICE_STATE } from './useDialogService'\n\nexport interface GrDialogServiceHostProps {\n /**\n * Состояние инстанса сервиса. Приходит пропом при программном монтировании:\n * хост живёт вне дерева и своим `inject` до app-scoped состояния не дотянулся\n * бы. `inject` остаётся для случая, когда хост поставили в шаблон руками.\n */\n state?: DialogServiceState | null\n}\n\nconst props = defineProps<GrDialogServiceHostProps>()\n\nconst injected = inject(GRANULARITY_DIALOG_SERVICE_STATE, null)\n\nconst activeState = computed<DialogServiceState | null>(() => props.state ?? injected)\n\nconst visible = computed<DialogRequest[]>(() =>\n activeState.value ? visibleDialogRequests(activeState.value) : [],\n)\n\n// Окна берут состояние отсюда, а не пропом: они его мутируют (очередь, список\n// заявок в полёте), а мутировать проп — значит писать в чужое владение.\nprovide(GRANULARITY_DIALOG_SERVICE_STATE, activeState.value!)\n</script>\n\n<template>\n <GrDialogServiceItem\n v-for=\"request in visible\"\n :key=\"request.id\"\n :request=\"request\"\n />\n</template>\n"],"mappings":"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"}
@@ -1,3 +1,3 @@
1
- import { a as useDialogService, i as teardownDialogService, n as dialogService, r as granularityDialogServicePlugin, t as GrDialogServiceHost_default } from "./chunks/GrDialogService-CrwA4aJq.js";
1
+ import { a as useDialogService, i as teardownDialogService, n as dialogService, r as granularityDialogServicePlugin, t as GrDialogServiceHost_default } from "./chunks/GrDialogService-CHhzGRWy.js";
2
2
  import { t as grDialogServiceConfig } from "../../chunks/config-CjXjhphs.js";
3
3
  export { GrDialogServiceHost_default as GrDialogServiceHost, dialogService, grDialogServiceConfig, granularityDialogServicePlugin, teardownDialogService, useDialogService };
@@ -2,7 +2,7 @@ import { t as x_default } from "../../../chunks/x-2KXnqxiD.js";
2
2
  import { i as useGrComponentProp } from "../../../chunks/context-CTbuwcYs.js";
3
3
  import { n as useGranularityTranslations } from "../../../chunks/granularityI18n-BC5zsj_d.js";
4
4
  import { t as GrIcon_default } from "../../GrIcon/chunks/GrIcon-bQwtZtYT.js";
5
- import { t as GrButton_default } from "../../GrButton/chunks/GrButton-Bw2AH4uX.js";
5
+ import { t as GrButton_default } from "../../GrButton/chunks/GrButton-DCz-Wn-V.js";
6
6
  import { t as useModalOverlay } from "../../../chunks/useModalOverlay-Cv5hF63W.js";
7
7
  import { a as DEFAULT_GR_DRAWER_HEADER_CONFIG, c as grDrawerPanelClass, d as overlayClass, f as resolveGrDrawerSectionConfig, g as titleClass, h as srOnlyTitleClass, i as DEFAULT_GR_DRAWER_FOOTER_CONFIG, l as grDrawerPanelEnterFrom, m as rootPassThroughClass, o as footerBorderClass, p as rootClass, r as DEFAULT_GR_DRAWER_BODY_CONFIG, s as grDrawerAxis, u as headerBorderClass } from "../../../chunks/config-D94Z9po5.js";
8
8
  import { Teleport, Transition, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, mergeProps, normalizeClass, openBlock, ref, renderSlot, toDisplayString, toHandlers, unref, useId, useSlots, watch, withCtx } from "vue";
@@ -107,7 +107,7 @@ var GrDrawer_default = /* @__PURE__ */ defineComponent({
107
107
  const value = typeof length === "number" ? `${length}px` : length;
108
108
  return axis.value === "horizontal" ? { width: value } : { height: value };
109
109
  });
110
- if (process.env.NODE_ENV !== "production") watch([
110
+ if (typeof process !== "undefined" && process.env.NODE_ENV !== "production") watch([
111
111
  axis,
112
112
  () => props.width,
113
113
  () => props.height
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GrDrawer-CXy3-SVd.js","names":["$slots"],"sources":["../../../../src/components/GrDrawer/GrDrawer.vue","../../../../src/components/GrDrawer/GrDrawer.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, useId, watch } from 'vue'\n\nimport GrButton from '../GrButton/GrButton.vue'\nimport GrIcon from '../GrIcon/GrIcon.vue'\nimport { useGrComponentProp } from '../GrConfigProvider/context'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\n// Модальный слой целиком: стек (Esc верхнему, `inert` нижним модалкам), ловушка\n// фокуса, скролл-лок, портал. Немодальная панель регистрируется в стеке как\n// обычный dismissible-слой и страницу под собой не трогает.\nimport { useModalOverlay } from '../../composables/internal/useModalOverlay'\nimport {\n DEFAULT_GR_DRAWER_BODY_CONFIG,\n DEFAULT_GR_DRAWER_FOOTER_CONFIG,\n DEFAULT_GR_DRAWER_HEADER_CONFIG,\n footerBorderClass,\n grDrawerAxis,\n grDrawerPanelClass,\n grDrawerPanelEnterFrom,\n headerBorderClass,\n overlayClass,\n resolveGrDrawerSectionConfig,\n rootClass,\n rootPassThroughClass,\n srOnlyTitleClass,\n titleClass,\n type GrDrawerSectionConfig,\n type GrDrawerSide,\n type GrDrawerSize,\n} from './grDrawerStyles'\n\nimport IconClose from '~icons/lucide/x'\n\nimport './defaults'\n\nexport interface GrDrawerProps {\n /** Контроль открытия через v-model. */\n modelValue: boolean\n /** Заголовок; если передан — покажется в хедере. Можно переопределить слотом `#title`. */\n title?: string\n /**\n * Модальная панель: подложка, блокировка скролла, `inert` остальной странице\n * и ловушка фокуса. `false` — панель живёт рядом со страницей: с ней работают,\n * не закрывая, а Tab уходит наружу.\n */\n modal?: boolean\n /** Закрывать при клике по бэкдропу. В немодальном режиме подложки нет. */\n closeOnBackdrop?: boolean\n /** Закрывать по Esc. */\n closeOnEsc?: boolean\n /**\n * Запрет закрытия «мягкими» способами (бэкдроп, Esc) — на время операции,\n * которую нельзя бросить на полпути. Кнопка закрытия при этом остаётся:\n * панель без единого выхода — ловушка.\n */\n persistent?: boolean\n /** Сторона, с которой выезжает панель. */\n side?: GrDrawerSide\n /** Размер панели по её оси: ширина у боковых, высота у верхней и нижней. */\n size?: GrDrawerSize\n /** Произвольная ширина боковой панели. Число трактуется как пиксели; сильнее `size`. */\n width?: string | number\n /** Произвольная высота верхней или нижней панели. Число трактуется как пиксели. */\n height?: string | number\n /** Рендерить ли хедер (заголовок + кнопка закрытия). */\n showHeader?: boolean\n /** Рендерить ли кнопку закрытия в хедере. */\n showCloseButton?: boolean\n /** Паддинги и рамка секций — как у `GrDialog`. */\n headerConfig?: GrDrawerSectionConfig\n bodyConfig?: GrDrawerSectionConfig\n footerConfig?: GrDrawerSectionConfig\n /** Элемент, получающий фокус при открытии. По умолчанию — сама панель. */\n initialFocus?: HTMLElement | null\n /** i18n-friendly aria-label для кнопки закрытия. */\n closeLabel?: string\n}\n\nexport interface GrDrawerEmits {\n (e: 'update:modelValue', value: boolean): void\n /** Панель выехала и анимация закончилась. */\n (e: 'opened'): void\n /** Панель уехала и анимация закончилась. */\n (e: 'closed'): void\n}\n\n// Дефолты оформления намеренно `undefined`: «настоящий» дефолт живёт в\n// `useGrComponentProp`, иначе `GrConfigProvider` не отличит заданный\n// пользователем проп от подставленного Vue.\nconst props = withDefaults(defineProps<GrDrawerProps>(), {\n title: undefined,\n modal: true,\n closeOnBackdrop: true,\n closeOnEsc: true,\n persistent: false,\n side: undefined,\n size: undefined,\n width: undefined,\n height: undefined,\n showHeader: true,\n showCloseButton: true,\n headerConfig: undefined,\n bodyConfig: undefined,\n footerConfig: undefined,\n initialFocus: null,\n closeLabel: undefined,\n})\n\nconst { t } = useGranularityTranslations()\nconst resolvedCloseLabel = computed(() => props.closeLabel ?? t('gr.common.close', 'Close'))\n\nconst emit = defineEmits<GrDrawerEmits>()\n\nconst slots = defineSlots<{\n default?: () => any\n title?: () => any\n /** Своя шапка целиком: заголовок, кнопка закрытия и всё, что нужно рядом. */\n header?: (props: { title?: string, close: () => void }) => any\n footer?: () => any\n}>()\n\nconst titleId = useId()\n\nconst size = useGrComponentProp('GrDrawer', 'size', () => props.size, 'md')\nconst side = useGrComponentProp('GrDrawer', 'side', () => props.side, 'right')\n\nconst axis = computed(() => grDrawerAxis(side.value))\n\n// Пустой/пробельный заголовок считается отсутствующим — иначе хедер занимал бы\n// место ради строки-заглушки.\nconst resolvedTitle = computed(() => props.title?.trim() || undefined)\nconst hasTitle = computed(() => Boolean(resolvedTitle.value) || Boolean(slots.title))\nconst hasCustomHeader = computed(() => Boolean(slots.header))\nconst hasHeader = computed(() =>\n props.showHeader && (hasCustomHeader.value || hasTitle.value || props.showCloseButton),\n)\n\n/**\n * Видимый заголовок рисуется только в стандартной шапке. Со своей шапкой и без\n * шапки вовсе заголовок всё равно нужен — но скрытым: имя слоя обязано остаться\n * осмысленным, а не свалиться на обобщённое «Drawer» из локали.\n */\nconst showVisibleTitle = computed(() =>\n props.showHeader && !hasCustomHeader.value && hasTitle.value,\n)\nconst showSrOnlyTitle = computed(() => hasTitle.value && !showVisibleTitle.value)\n\n// Имя модального слоя обязательно: без него axe роняет `aria-dialog-name`.\n// Есть заголовок — связываем `aria-labelledby`, иначе даём `aria-label` из i18n.\nconst labelledBy = computed(() => (hasTitle.value ? titleId : undefined))\nconst ariaLabel = computed(() => (labelledBy.value ? undefined : t('gr.drawer.title', 'Drawer')))\n\nconst panelEl = ref<HTMLElement | null>(null)\n\n/** Произвольный размер — только по оси панели: у боковой ширина, у нижней высота. */\nconst customLength = computed(() => (axis.value === 'horizontal' ? props.width : props.height))\n\nconst panelClass = computed(() => grDrawerPanelClass({\n side: side.value,\n size: size.value,\n hasCustomLength: customLength.value !== undefined,\n}))\n\nconst panelStyle = computed(() => {\n const length = customLength.value\n if (length === undefined) return undefined\n\n const value = typeof length === 'number' ? `${length}px` : length\n return axis.value === 'horizontal' ? { width: value } : { height: value }\n})\n\n// Проп не своей оси молча не работал бы — а выглядит это как баг компонента.\nif (__GR_DEV__) {\n watch(\n [axis, () => props.width, () => props.height],\n ([currentAxis, width, height]) => {\n const ignored = currentAxis === 'horizontal' ? 'height' : 'width'\n const value = currentAxis === 'horizontal' ? height : width\n if (value === undefined) return\n\n console.warn(\n `[GrDrawer] Проп \\`${ignored}\\` не применяется к стороне \"${side.value}\": `\n + `панель по этой оси растянута. Задайте \\`${ignored === 'height' ? 'width' : 'height'}\\`.`,\n )\n },\n { immediate: true },\n )\n}\n\nconst panelEnterFrom = computed(() => grDrawerPanelEnterFrom(side.value))\n\nconst headerSection = computed(() => resolveGrDrawerSectionConfig(props.headerConfig, DEFAULT_GR_DRAWER_HEADER_CONFIG))\nconst bodySection = computed(() => resolveGrDrawerSectionConfig(props.bodyConfig, DEFAULT_GR_DRAWER_BODY_CONFIG))\nconst footerSection = computed(() => resolveGrDrawerSectionConfig(props.footerConfig, DEFAULT_GR_DRAWER_FOOTER_CONFIG))\n\nfunction sectionClass(\n section: { paddingX: string, paddingY: string, bordered: boolean },\n borderClass: string,\n): string[] {\n return [section.paddingX, section.paddingY, section.bordered ? borderClass : '']\n}\n\nfunction close(): void {\n emit('update:modelValue', false)\n}\n\n/** Закрытие «мягким» способом: бэкдроп или Esc. `persistent` их и запрещает. */\nfunction closeSoftly(): void {\n if (props.persistent)\n return\n\n close()\n}\n\nconst rootClasses = computed(() => [rootClass, props.modal ? '' : rootPassThroughClass].filter(Boolean))\n\n// Немодальная панель остаётся в очереди Esc, но модалки под собой в `inert` не\n// отправляет и скролл не блокирует: она существует ровно ради работы со\n// страницей под ней, и Tab обязан уводить фокус туда.\nconst {\n rootEl,\n isMounted,\n isVisible,\n inertAttr,\n portalTarget,\n teleportEnabled,\n themeAttrs,\n onPanelAfterLeave: releasePresence,\n backdrop,\n} = useModalOverlay(computed(() => props.modelValue), closeSoftly, {\n panel: panelEl,\n modal: () => props.modal,\n closeOnEscape: () => props.closeOnEsc && !props.persistent,\n closeOnBackdrop: () => props.closeOnBackdrop,\n initialFocus: () => props.initialFocus ?? panelEl.value,\n})\n\nfunction onPanelAfterLeave(): void {\n releasePresence()\n emit('closed')\n}\n\ndefineExpose({\n /** Закрыть панель (эквивалент `v-model = false`), минуя `persistent`. */\n close,\n /** Вернуть фокус на панель — например после операции, уведшей его наружу. */\n focus: () => panelEl.value?.focus(),\n})\n</script>\n\n<template>\n <teleport :to=\"portalTarget\" :disabled=\"!teleportEnabled\">\n <div\n v-if=\"teleportEnabled && isMounted\"\n ref=\"rootEl\"\n data-gr-drawer\n data-gr-overlay-root\n role=\"dialog\"\n :aria-modal=\"modal ? 'true' : undefined\"\n :class=\"rootClasses\"\n :inert=\"inertAttr\"\n :aria-labelledby=\"labelledBy\"\n :aria-label=\"ariaLabel\"\n >\n <Transition\n appear\n enter-active-class=\"duration-[var(--gr-duration-base)] ease-[var(--gr-ease-out)]\"\n enter-from-class=\"opacity-0\"\n leave-active-class=\"duration-[var(--gr-duration-fast)] ease-[var(--gr-ease-in)]\"\n leave-to-class=\"opacity-0\"\n >\n <div\n v-if=\"isVisible && modal\"\n data-gr-drawer-overlay\n :class=\"overlayClass\"\n aria-hidden=\"true\"\n v-on=\"backdrop\"\n />\n </Transition>\n\n <Transition\n appear\n enter-active-class=\"duration-[var(--gr-duration-base)] ease-[var(--gr-ease-out)]\"\n :enter-from-class=\"panelEnterFrom\"\n leave-active-class=\"duration-[var(--gr-duration-fast)] ease-[var(--gr-ease-in)]\"\n :leave-to-class=\"panelEnterFrom\"\n @after-enter=\"emit('opened')\"\n @after-leave=\"onPanelAfterLeave\"\n >\n <div\n v-if=\"isVisible\"\n ref=\"panelEl\"\n v-bind=\"themeAttrs\"\n data-gr-drawer-panel\n tabindex=\"-1\"\n :class=\"panelClass\"\n :style=\"panelStyle\"\n >\n <!-- Заголовок без видимой шапки: имя слоя обязано остаться своим. -->\n <div\n v-if=\"showSrOnlyTitle\"\n :id=\"titleId\"\n data-gr-drawer-title\n :class=\"srOnlyTitleClass\"\n >\n <slot name=\"title\">\n {{ resolvedTitle }}\n </slot>\n </div>\n\n <div\n v-if=\"hasHeader\"\n data-gr-drawer-header\n :class=\"[hasCustomHeader ? '' : 'flex items-center justify-between gap-4', sectionClass(headerSection, headerBorderClass)]\"\n >\n <slot name=\"header\" :title=\"resolvedTitle\" :close=\"close\">\n <div\n v-if=\"showVisibleTitle\"\n :id=\"titleId\"\n data-gr-drawer-title\n :class=\"titleClass\"\n >\n <slot name=\"title\">\n {{ resolvedTitle }}\n </slot>\n </div>\n <div v-else class=\"min-w-0 flex-1\" />\n\n <GrButton\n v-if=\"showCloseButton\"\n variant=\"ghost\"\n size=\"sm\"\n square\n data-gr-drawer-close\n :aria-label=\"resolvedCloseLabel\"\n @click=\"close\"\n >\n <GrIcon size=\"sm\">\n <IconClose />\n </GrIcon>\n </GrButton>\n </slot>\n </div>\n\n <!-- Тело скроллится, поэтому обязано попадать в таб-порядок: длинный\n текст без единого фокусируемого элемента иначе не прокрутить с\n клавиатуры (axe: `scrollable-region-focusable`). -->\n <div\n data-gr-drawer-body\n tabindex=\"0\"\n class=\"min-h-0 flex-1 overflow-y-auto\"\n >\n <div :class=\"sectionClass(bodySection, '')\">\n <slot />\n </div>\n </div>\n\n <div\n v-if=\"$slots.footer\"\n data-gr-drawer-footer\n :class=\"sectionClass(footerSection, footerBorderClass)\"\n >\n <slot name=\"footer\" />\n </div>\n </div>\n </Transition>\n </div>\n </teleport>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, ref, useId, watch } from 'vue'\n\nimport GrButton from '../GrButton/GrButton.vue'\nimport GrIcon from '../GrIcon/GrIcon.vue'\nimport { useGrComponentProp } from '../GrConfigProvider/context'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\n// Модальный слой целиком: стек (Esc верхнему, `inert` нижним модалкам), ловушка\n// фокуса, скролл-лок, портал. Немодальная панель регистрируется в стеке как\n// обычный dismissible-слой и страницу под собой не трогает.\nimport { useModalOverlay } from '../../composables/internal/useModalOverlay'\nimport {\n DEFAULT_GR_DRAWER_BODY_CONFIG,\n DEFAULT_GR_DRAWER_FOOTER_CONFIG,\n DEFAULT_GR_DRAWER_HEADER_CONFIG,\n footerBorderClass,\n grDrawerAxis,\n grDrawerPanelClass,\n grDrawerPanelEnterFrom,\n headerBorderClass,\n overlayClass,\n resolveGrDrawerSectionConfig,\n rootClass,\n rootPassThroughClass,\n srOnlyTitleClass,\n titleClass,\n type GrDrawerSectionConfig,\n type GrDrawerSide,\n type GrDrawerSize,\n} from './grDrawerStyles'\n\nimport IconClose from '~icons/lucide/x'\n\nimport './defaults'\n\nexport interface GrDrawerProps {\n /** Контроль открытия через v-model. */\n modelValue: boolean\n /** Заголовок; если передан — покажется в хедере. Можно переопределить слотом `#title`. */\n title?: string\n /**\n * Модальная панель: подложка, блокировка скролла, `inert` остальной странице\n * и ловушка фокуса. `false` — панель живёт рядом со страницей: с ней работают,\n * не закрывая, а Tab уходит наружу.\n */\n modal?: boolean\n /** Закрывать при клике по бэкдропу. В немодальном режиме подложки нет. */\n closeOnBackdrop?: boolean\n /** Закрывать по Esc. */\n closeOnEsc?: boolean\n /**\n * Запрет закрытия «мягкими» способами (бэкдроп, Esc) — на время операции,\n * которую нельзя бросить на полпути. Кнопка закрытия при этом остаётся:\n * панель без единого выхода — ловушка.\n */\n persistent?: boolean\n /** Сторона, с которой выезжает панель. */\n side?: GrDrawerSide\n /** Размер панели по её оси: ширина у боковых, высота у верхней и нижней. */\n size?: GrDrawerSize\n /** Произвольная ширина боковой панели. Число трактуется как пиксели; сильнее `size`. */\n width?: string | number\n /** Произвольная высота верхней или нижней панели. Число трактуется как пиксели. */\n height?: string | number\n /** Рендерить ли хедер (заголовок + кнопка закрытия). */\n showHeader?: boolean\n /** Рендерить ли кнопку закрытия в хедере. */\n showCloseButton?: boolean\n /** Паддинги и рамка секций — как у `GrDialog`. */\n headerConfig?: GrDrawerSectionConfig\n bodyConfig?: GrDrawerSectionConfig\n footerConfig?: GrDrawerSectionConfig\n /** Элемент, получающий фокус при открытии. По умолчанию — сама панель. */\n initialFocus?: HTMLElement | null\n /** i18n-friendly aria-label для кнопки закрытия. */\n closeLabel?: string\n}\n\nexport interface GrDrawerEmits {\n (e: 'update:modelValue', value: boolean): void\n /** Панель выехала и анимация закончилась. */\n (e: 'opened'): void\n /** Панель уехала и анимация закончилась. */\n (e: 'closed'): void\n}\n\n// Дефолты оформления намеренно `undefined`: «настоящий» дефолт живёт в\n// `useGrComponentProp`, иначе `GrConfigProvider` не отличит заданный\n// пользователем проп от подставленного Vue.\nconst props = withDefaults(defineProps<GrDrawerProps>(), {\n title: undefined,\n modal: true,\n closeOnBackdrop: true,\n closeOnEsc: true,\n persistent: false,\n side: undefined,\n size: undefined,\n width: undefined,\n height: undefined,\n showHeader: true,\n showCloseButton: true,\n headerConfig: undefined,\n bodyConfig: undefined,\n footerConfig: undefined,\n initialFocus: null,\n closeLabel: undefined,\n})\n\nconst { t } = useGranularityTranslations()\nconst resolvedCloseLabel = computed(() => props.closeLabel ?? t('gr.common.close', 'Close'))\n\nconst emit = defineEmits<GrDrawerEmits>()\n\nconst slots = defineSlots<{\n default?: () => any\n title?: () => any\n /** Своя шапка целиком: заголовок, кнопка закрытия и всё, что нужно рядом. */\n header?: (props: { title?: string, close: () => void }) => any\n footer?: () => any\n}>()\n\nconst titleId = useId()\n\nconst size = useGrComponentProp('GrDrawer', 'size', () => props.size, 'md')\nconst side = useGrComponentProp('GrDrawer', 'side', () => props.side, 'right')\n\nconst axis = computed(() => grDrawerAxis(side.value))\n\n// Пустой/пробельный заголовок считается отсутствующим — иначе хедер занимал бы\n// место ради строки-заглушки.\nconst resolvedTitle = computed(() => props.title?.trim() || undefined)\nconst hasTitle = computed(() => Boolean(resolvedTitle.value) || Boolean(slots.title))\nconst hasCustomHeader = computed(() => Boolean(slots.header))\nconst hasHeader = computed(() =>\n props.showHeader && (hasCustomHeader.value || hasTitle.value || props.showCloseButton),\n)\n\n/**\n * Видимый заголовок рисуется только в стандартной шапке. Со своей шапкой и без\n * шапки вовсе заголовок всё равно нужен — но скрытым: имя слоя обязано остаться\n * осмысленным, а не свалиться на обобщённое «Drawer» из локали.\n */\nconst showVisibleTitle = computed(() =>\n props.showHeader && !hasCustomHeader.value && hasTitle.value,\n)\nconst showSrOnlyTitle = computed(() => hasTitle.value && !showVisibleTitle.value)\n\n// Имя модального слоя обязательно: без него axe роняет `aria-dialog-name`.\n// Есть заголовок — связываем `aria-labelledby`, иначе даём `aria-label` из i18n.\nconst labelledBy = computed(() => (hasTitle.value ? titleId : undefined))\nconst ariaLabel = computed(() => (labelledBy.value ? undefined : t('gr.drawer.title', 'Drawer')))\n\nconst panelEl = ref<HTMLElement | null>(null)\n\n/** Произвольный размер — только по оси панели: у боковой ширина, у нижней высота. */\nconst customLength = computed(() => (axis.value === 'horizontal' ? props.width : props.height))\n\nconst panelClass = computed(() => grDrawerPanelClass({\n side: side.value,\n size: size.value,\n hasCustomLength: customLength.value !== undefined,\n}))\n\nconst panelStyle = computed(() => {\n const length = customLength.value\n if (length === undefined) return undefined\n\n const value = typeof length === 'number' ? `${length}px` : length\n return axis.value === 'horizontal' ? { width: value } : { height: value }\n})\n\n// Проп не своей оси молча не работал бы — а выглядит это как баг компонента.\nif (__GR_DEV__) {\n watch(\n [axis, () => props.width, () => props.height],\n ([currentAxis, width, height]) => {\n const ignored = currentAxis === 'horizontal' ? 'height' : 'width'\n const value = currentAxis === 'horizontal' ? height : width\n if (value === undefined) return\n\n console.warn(\n `[GrDrawer] Проп \\`${ignored}\\` не применяется к стороне \"${side.value}\": `\n + `панель по этой оси растянута. Задайте \\`${ignored === 'height' ? 'width' : 'height'}\\`.`,\n )\n },\n { immediate: true },\n )\n}\n\nconst panelEnterFrom = computed(() => grDrawerPanelEnterFrom(side.value))\n\nconst headerSection = computed(() => resolveGrDrawerSectionConfig(props.headerConfig, DEFAULT_GR_DRAWER_HEADER_CONFIG))\nconst bodySection = computed(() => resolveGrDrawerSectionConfig(props.bodyConfig, DEFAULT_GR_DRAWER_BODY_CONFIG))\nconst footerSection = computed(() => resolveGrDrawerSectionConfig(props.footerConfig, DEFAULT_GR_DRAWER_FOOTER_CONFIG))\n\nfunction sectionClass(\n section: { paddingX: string, paddingY: string, bordered: boolean },\n borderClass: string,\n): string[] {\n return [section.paddingX, section.paddingY, section.bordered ? borderClass : '']\n}\n\nfunction close(): void {\n emit('update:modelValue', false)\n}\n\n/** Закрытие «мягким» способом: бэкдроп или Esc. `persistent` их и запрещает. */\nfunction closeSoftly(): void {\n if (props.persistent)\n return\n\n close()\n}\n\nconst rootClasses = computed(() => [rootClass, props.modal ? '' : rootPassThroughClass].filter(Boolean))\n\n// Немодальная панель остаётся в очереди Esc, но модалки под собой в `inert` не\n// отправляет и скролл не блокирует: она существует ровно ради работы со\n// страницей под ней, и Tab обязан уводить фокус туда.\nconst {\n rootEl,\n isMounted,\n isVisible,\n inertAttr,\n portalTarget,\n teleportEnabled,\n themeAttrs,\n onPanelAfterLeave: releasePresence,\n backdrop,\n} = useModalOverlay(computed(() => props.modelValue), closeSoftly, {\n panel: panelEl,\n modal: () => props.modal,\n closeOnEscape: () => props.closeOnEsc && !props.persistent,\n closeOnBackdrop: () => props.closeOnBackdrop,\n initialFocus: () => props.initialFocus ?? panelEl.value,\n})\n\nfunction onPanelAfterLeave(): void {\n releasePresence()\n emit('closed')\n}\n\ndefineExpose({\n /** Закрыть панель (эквивалент `v-model = false`), минуя `persistent`. */\n close,\n /** Вернуть фокус на панель — например после операции, уведшей его наружу. */\n focus: () => panelEl.value?.focus(),\n})\n</script>\n\n<template>\n <teleport :to=\"portalTarget\" :disabled=\"!teleportEnabled\">\n <div\n v-if=\"teleportEnabled && isMounted\"\n ref=\"rootEl\"\n data-gr-drawer\n data-gr-overlay-root\n role=\"dialog\"\n :aria-modal=\"modal ? 'true' : undefined\"\n :class=\"rootClasses\"\n :inert=\"inertAttr\"\n :aria-labelledby=\"labelledBy\"\n :aria-label=\"ariaLabel\"\n >\n <Transition\n appear\n enter-active-class=\"duration-[var(--gr-duration-base)] ease-[var(--gr-ease-out)]\"\n enter-from-class=\"opacity-0\"\n leave-active-class=\"duration-[var(--gr-duration-fast)] ease-[var(--gr-ease-in)]\"\n leave-to-class=\"opacity-0\"\n >\n <div\n v-if=\"isVisible && modal\"\n data-gr-drawer-overlay\n :class=\"overlayClass\"\n aria-hidden=\"true\"\n v-on=\"backdrop\"\n />\n </Transition>\n\n <Transition\n appear\n enter-active-class=\"duration-[var(--gr-duration-base)] ease-[var(--gr-ease-out)]\"\n :enter-from-class=\"panelEnterFrom\"\n leave-active-class=\"duration-[var(--gr-duration-fast)] ease-[var(--gr-ease-in)]\"\n :leave-to-class=\"panelEnterFrom\"\n @after-enter=\"emit('opened')\"\n @after-leave=\"onPanelAfterLeave\"\n >\n <div\n v-if=\"isVisible\"\n ref=\"panelEl\"\n v-bind=\"themeAttrs\"\n data-gr-drawer-panel\n tabindex=\"-1\"\n :class=\"panelClass\"\n :style=\"panelStyle\"\n >\n <!-- Заголовок без видимой шапки: имя слоя обязано остаться своим. -->\n <div\n v-if=\"showSrOnlyTitle\"\n :id=\"titleId\"\n data-gr-drawer-title\n :class=\"srOnlyTitleClass\"\n >\n <slot name=\"title\">\n {{ resolvedTitle }}\n </slot>\n </div>\n\n <div\n v-if=\"hasHeader\"\n data-gr-drawer-header\n :class=\"[hasCustomHeader ? '' : 'flex items-center justify-between gap-4', sectionClass(headerSection, headerBorderClass)]\"\n >\n <slot name=\"header\" :title=\"resolvedTitle\" :close=\"close\">\n <div\n v-if=\"showVisibleTitle\"\n :id=\"titleId\"\n data-gr-drawer-title\n :class=\"titleClass\"\n >\n <slot name=\"title\">\n {{ resolvedTitle }}\n </slot>\n </div>\n <div v-else class=\"min-w-0 flex-1\" />\n\n <GrButton\n v-if=\"showCloseButton\"\n variant=\"ghost\"\n size=\"sm\"\n square\n data-gr-drawer-close\n :aria-label=\"resolvedCloseLabel\"\n @click=\"close\"\n >\n <GrIcon size=\"sm\">\n <IconClose />\n </GrIcon>\n </GrButton>\n </slot>\n </div>\n\n <!-- Тело скроллится, поэтому обязано попадать в таб-порядок: длинный\n текст без единого фокусируемого элемента иначе не прокрутить с\n клавиатуры (axe: `scrollable-region-focusable`). -->\n <div\n data-gr-drawer-body\n tabindex=\"0\"\n class=\"min-h-0 flex-1 overflow-y-auto\"\n >\n <div :class=\"sectionClass(bodySection, '')\">\n <slot />\n </div>\n </div>\n\n <div\n v-if=\"$slots.footer\"\n data-gr-drawer-footer\n :class=\"sectionClass(footerSection, footerBorderClass)\"\n >\n <slot name=\"footer\" />\n </div>\n </div>\n </Transition>\n </div>\n </teleport>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyFA,MAAM,QAAQ;EAmBd,MAAM,EAAE,MAAM,2BAA2B;EACzC,MAAM,qBAAqB,eAAe,MAAM,cAAc,EAAE,mBAAmB,OAAO,CAAC;EAE3F,MAAM,OAAO;EAEb,MAAM,QAAQ,SAAA;EAQd,MAAM,UAAU,MAAM;EAEtB,MAAM,OAAO,mBAAmB,YAAY,cAAc,MAAM,MAAM,IAAI;EAC1E,MAAM,OAAO,mBAAmB,YAAY,cAAc,MAAM,MAAM,OAAO;EAE7E,MAAM,OAAO,eAAe,aAAa,KAAK,KAAK,CAAC;EAIpD,MAAM,gBAAgB,eAAe,MAAM,OAAO,KAAK,KAAK,KAAA,CAAS;EACrE,MAAM,WAAW,eAAe,QAAQ,cAAc,KAAK,KAAK,QAAQ,MAAM,KAAK,CAAC;EACpF,MAAM,kBAAkB,eAAe,QAAQ,MAAM,MAAM,CAAC;EAC5D,MAAM,YAAY,eAChB,MAAM,eAAe,gBAAgB,SAAS,SAAS,SAAS,MAAM,gBACxE;;;;;;EAOA,MAAM,mBAAmB,eACvB,MAAM,cAAc,CAAC,gBAAgB,SAAS,SAAS,KACzD;EACA,MAAM,kBAAkB,eAAe,SAAS,SAAS,CAAC,iBAAiB,KAAK;EAIhF,MAAM,aAAa,eAAgB,SAAS,QAAQ,UAAU,KAAA,CAAU;EACxE,MAAM,YAAY,eAAgB,WAAW,QAAQ,KAAA,IAAY,EAAE,mBAAmB,QAAQ,CAAE;EAEhG,MAAM,UAAU,IAAwB,IAAI;;EAG5C,MAAM,eAAe,eAAgB,KAAK,UAAU,eAAe,MAAM,QAAQ,MAAM,MAAO;EAE9F,MAAM,aAAa,eAAe,mBAAmB;GACnD,MAAM,KAAK;GACX,MAAM,KAAK;GACX,iBAAiB,aAAa,UAAU,KAAA;EAC1C,CAAC,CAAC;EAEF,MAAM,aAAa,eAAe;GAChC,MAAM,SAAS,aAAa;GAC5B,IAAI,WAAW,KAAA,GAAW,OAAO,KAAA;GAEjC,MAAM,QAAQ,OAAO,WAAW,WAAW,GAAG,OAAO,MAAM;GAC3D,OAAO,KAAK,UAAU,eAAe,EAAE,OAAO,MAAM,IAAI,EAAE,QAAQ,MAAM;EAC1E,CAAC;EAGD,IAAA,OAAA,YAAA,eAAA,QAAA,IAAA,aAAA,cACE,MACE;GAAC;SAAY,MAAM;SAAa,MAAM;EAAM,IAC3C,CAAC,aAAa,OAAO,YAAY;GAChC,MAAM,UAAU,gBAAgB,eAAe,WAAW;GAE1D,KADc,gBAAgB,eAAe,SAAS,WACxC,KAAA,GAAW;GAEzB,QAAQ,KACN,qBAAqB,QAAQ,+BAA+B,KAAK,MAAM,6CAC1B,YAAY,WAAW,UAAU,SAAS,IACzF;EACF,GACA,EAAE,WAAW,KAAK,CACpB;EAGF,MAAM,iBAAiB,eAAe,uBAAuB,KAAK,KAAK,CAAC;EAExE,MAAM,gBAAgB,eAAe,6BAA6B,MAAM,cAAc,+BAA+B,CAAC;EACtH,MAAM,cAAc,eAAe,6BAA6B,MAAM,YAAY,6BAA6B,CAAC;EAChH,MAAM,gBAAgB,eAAe,6BAA6B,MAAM,cAAc,+BAA+B,CAAC;EAEtH,SAAS,aACP,SACA,aACU;GACV,OAAO;IAAC,QAAQ;IAAU,QAAQ;IAAU,QAAQ,WAAW,cAAc;GAAE;EACjF;EAEA,SAAS,QAAc;GACrB,KAAK,qBAAqB,KAAK;EACjC;;EAGA,SAAS,cAAoB;GAC3B,IAAI,MAAM,YACR;GAEF,MAAM;EACR;EAEA,MAAM,cAAc,eAAe,CAAC,WAAW,MAAM,QAAQ,KAAK,oBAAoB,CAAC,CAAC,OAAO,OAAO,CAAC;EAKvG,MAAM,EACJ,QACA,WACA,WACA,WACA,cACA,iBACA,YACA,mBAAmB,iBACnB,aACE,gBAAgB,eAAe,MAAM,UAAU,GAAG,aAAa;GACjE,OAAO;GACP,aAAa,MAAM;GACnB,qBAAqB,MAAM,cAAc,CAAC,MAAM;GAChD,uBAAuB,MAAM;GAC7B,oBAAoB,MAAM,gBAAgB,QAAQ;EACpD,CAAC;EAED,SAAS,oBAA0B;GACjC,gBAAgB;GAChB,KAAK,QAAQ;EACf;EAEA,SAAa;;GAEX;;GAEA,aAAa,QAAQ,OAAO,MAAM;EACpC,CAAC;;uBAIC,YAoHW,UAAA;IApHA,IAAI,MAAA,YAAA;IAAe,UAAQ,CAAG,MAAA,eAAA;OAE/B,MAAA,eAAA,KAAmB,MAAA,SAAA,KAAA,UAAA,GAD3B,mBAkHM,OAAA;;aAhHA;IAAJ,KAAI;IACJ,kBAAA;IACA,wBAAA;IACA,MAAK;IACJ,cAAY,QAAA,QAAK,SAAY,KAAA;IAC7B,OAAK,eAAE,YAAA,KAAW;IAClB,OAAO,MAAA,SAAA;IACP,mBAAiB,WAAA;IACjB,cAAY,UAAA;OAEb,YAca,YAAA;IAbX,QAAA;IACA,sBAAmB;IACnB,oBAAiB;IACjB,sBAAmB;IACnB,kBAAe;;2BAQb,CALM,MAAA,SAAA,KAAa,QAAA,SAAA,UAAA,GADrB,mBAME,OANF,WAME;;KAJA,0BAAA;KACC,OAAO,MAAA,YAAA;KACR,eAAY;OACZ,WAAM,MAAS,QAAA,GAAD,IAAA,CAAA,GAAA,MAAA,EAAA,KAAA,mBAAA,IAAA,IAAA,CAAA,CAAA;;OAIlB,YAqFa,YAAA;IApFX,QAAA;IACA,sBAAmB;IAClB,oBAAkB,eAAA;IACnB,sBAAmB;IAClB,kBAAgB,eAAA;IAChB,cAAW,OAAA,OAAA,OAAA,MAAA,WAAE,KAAI,QAAA;IACjB,cAAa;;2BA6ER,CA1EE,MAAA,SAAA,KAAA,UAAA,GADR,mBA2EM,OA3EN,WA2EM;;cAzEA;KAAJ,KAAI;OACI,MAAA,UAAA,GAAU;KAClB,wBAAA;KACA,UAAS;KACR,OAAO,WAAA;KACP,OAAO,WAAA;;KAIA,gBAAA,SAAA,UAAA,GADR,mBASM,OAAA;;MAPH,IAAI,MAAA,OAAA;MACL,wBAAA;MACC,OAAK,eAAE,MAAA,gBAAA,CAAgB;SAExB,WAEO,KAAA,QAAA,SAAA,CAAA,SAAA,CAAA,gBAAA,gBADF,cAAA,KAAa,GAAA,CAAA,CAAA,CAAA,CAAA,GAAA,IAAA,UAAA,KAAA,mBAAA,IAAA,IAAA;KAKZ,UAAA,SAAA,UAAA,GADR,mBAgCM,OAAA;;MA9BJ,yBAAA;MACC,OAAK,eAAA,CAAG,gBAAA,QAAe,KAAA,2CAAmD,aAAa,cAAA,OAAe,MAAA,iBAAA,CAAiB,CAAA,CAAA;SAExH,WA0BO,KAAA,QAAA,UAAA;MA1Bc,OAAO,cAAA;MAAuB;cA0B5C,CAxBG,iBAAA,SAAA,UAAA,GADR,mBASM,OAAA;;MAPH,IAAI,MAAA,OAAA;MACL,wBAAA;MACC,OAAK,eAAE,MAAA,UAAA,CAAU;SAElB,WAEO,KAAA,QAAA,SAAA,CAAA,SAAA,CAAA,gBAAA,gBADF,cAAA,KAAa,GAAA,CAAA,CAAA,CAAA,CAAA,GAAA,IAAA,UAAA,MAAA,UAAA,GAGpB,mBAAqC,OAArC,UAAqC,IAG7B,QAAA,mBAAA,UAAA,GADR,YAYW,kBAAA;;MAVT,SAAQ;MACR,MAAK;MACL,QAAA;MACA,wBAAA;MACC,cAAY,mBAAA;MACZ,SAAO;;6BAIC,CAFT,YAES,gBAAA,EAFD,MAAK,KAAI,GAAA;8BACF,CAAb,YAAa,MAAA,SAAA,CAAA,CAAA,CAAA;;;;;KASrB,mBAQM,OARN,YAQM,CAHJ,mBAEM,OAAA,EAFA,OAAK,eAAE,aAAa,YAAA,OAAW,EAAA,CAAA,EAAA,GAAA,CACnC,WAAQ,KAAA,QAAA,SAAA,CAAA,GAAA,CAAA,CAAA,CAAA;KAKJA,KAAAA,OAAO,UAAA,UAAA,GADf,mBAMM,OAAA;;MAJJ,yBAAA;MACC,OAAK,eAAE,aAAa,cAAA,OAAe,MAAA,iBAAA,CAAiB,CAAA;SAErD,WAAsB,KAAA,QAAA,QAAA,CAAA,GAAA,CAAA,KAAA,mBAAA,IAAA,IAAA"}
@@ -1,3 +1,3 @@
1
1
  import { n as grDrawerSafelist, t as grDrawerConfig } from "../../chunks/config-D94Z9po5.js";
2
- import { t as GrDrawer_default } from "./chunks/GrDrawer-C3zAg2tG.js";
2
+ import { t as GrDrawer_default } from "./chunks/GrDrawer-CXy3-SVd.js";
3
3
  export { GrDrawer_default as GrDrawer, GrDrawer_default as default, grDrawerConfig, grDrawerSafelist };