@feugene/granularity 0.35.0 → 0.37.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 (377) hide show
  1. package/dist/chunks/config-2ZHRsdOc.js.map +1 -1
  2. package/dist/chunks/config-2vrOFn2f.js.map +1 -1
  3. package/dist/chunks/config-3bQeQvqd.js.map +1 -1
  4. package/dist/chunks/config-87fszqnD.js.map +1 -1
  5. package/dist/chunks/config-8Pcutu1j.js.map +1 -1
  6. package/dist/chunks/config-A-bBiotF.js.map +1 -1
  7. package/dist/chunks/config-B0uvcTPH.js.map +1 -1
  8. package/dist/chunks/config-B3J0alyY.js.map +1 -1
  9. package/dist/chunks/config-B5SBUa6u.js.map +1 -1
  10. package/dist/chunks/config-B7W9VlZ7.js.map +1 -1
  11. package/dist/chunks/config-BDSaD-5p.js.map +1 -1
  12. package/dist/chunks/config-BEO7brpO.js.map +1 -1
  13. package/dist/chunks/config-BNu8lFQB.js.map +1 -1
  14. package/dist/chunks/config-BRESvs9g.js.map +1 -1
  15. package/dist/chunks/config-BTmfQFwi.js.map +1 -1
  16. package/dist/chunks/{config-CuQmUkMw2.js → config-BUNxHnEz.js} +1 -1
  17. package/dist/chunks/config-BUNxHnEz.js.map +1 -0
  18. package/dist/chunks/config-BaWANzzB.js.map +1 -1
  19. package/dist/chunks/config-BcXX7S7B.js.map +1 -1
  20. package/dist/chunks/config-Bd7QfiGj.js.map +1 -1
  21. package/dist/chunks/config-BhfNgyWL.js.map +1 -1
  22. package/dist/chunks/config-Bjn30smH.js.map +1 -1
  23. package/dist/chunks/config-BlJa1Mj9.js.map +1 -1
  24. package/dist/chunks/config-BoUI0t-t.js.map +1 -1
  25. package/dist/chunks/config-BqT6PMzO.js.map +1 -1
  26. package/dist/chunks/config-BscVxZR3.js.map +1 -1
  27. package/dist/chunks/config-BuGlNPE9.js.map +1 -1
  28. package/dist/chunks/config-C0Ea9ePP.js.map +1 -1
  29. package/dist/chunks/config-C0Eu8jpG.js.map +1 -1
  30. package/dist/chunks/config-CDat1wXf.js.map +1 -1
  31. package/dist/chunks/config-CIkdsWUk.js.map +1 -1
  32. package/dist/chunks/config-CJzmDHfI.js.map +1 -1
  33. package/dist/chunks/config-CLjjjPZj.js.map +1 -1
  34. package/dist/chunks/config-CMNfZO7S.js.map +1 -1
  35. package/dist/chunks/config-CQLNjc9X.js.map +1 -0
  36. package/dist/chunks/config-CT4lP6S4.js.map +1 -1
  37. package/dist/chunks/config-CWtfxkM9.js.map +1 -1
  38. package/dist/chunks/config-CYthTVK2.js.map +1 -1
  39. package/dist/chunks/config-CZPDPJlg.js.map +1 -1
  40. package/dist/chunks/config-CbEbLyDE.js.map +1 -1
  41. package/dist/chunks/config-ChPg-BQv.js.map +1 -1
  42. package/dist/chunks/config-CjKpUcmy.js.map +1 -1
  43. package/dist/chunks/config-CjWOTgLL.js.map +1 -1
  44. package/dist/chunks/config-CjXjhphs.js.map +1 -1
  45. package/dist/chunks/config-CnYdE3HZ.js.map +1 -0
  46. package/dist/chunks/config-CsCUuukB.js.map +1 -1
  47. package/dist/chunks/config-CvbVM4ep.js.map +1 -1
  48. package/dist/chunks/config-D0NzGYaE.js.map +1 -1
  49. package/dist/chunks/config-D0W8mGFD.js.map +1 -1
  50. package/dist/chunks/config-D82r782v.js.map +1 -1
  51. package/dist/chunks/{config-mlheIMtV.js → config-DBi0GVce.js} +2 -2
  52. package/dist/chunks/config-DBi0GVce.js.map +1 -0
  53. package/dist/chunks/config-DBmdgoVf.js.map +1 -0
  54. package/dist/chunks/config-DCq4JySZ.js.map +1 -1
  55. package/dist/chunks/config-DGC00bTp.js.map +1 -1
  56. package/dist/chunks/config-DIDz_E5m.js.map +1 -1
  57. package/dist/chunks/config-DM0lsduD.js.map +1 -1
  58. package/dist/chunks/config-DNDgp9bB.js.map +1 -1
  59. package/dist/chunks/config-DOYz_SVK.js.map +1 -1
  60. package/dist/chunks/config-DRbojEzO.js.map +1 -1
  61. package/dist/chunks/config-DUNH02Fg.js.map +1 -1
  62. package/dist/chunks/config-DUbbGcfw.js.map +1 -1
  63. package/dist/chunks/config-DVCNvhIG.js.map +1 -0
  64. package/dist/chunks/config-DWL81-aM.js.map +1 -1
  65. package/dist/chunks/config-DZCUPHPU.js.map +1 -1
  66. package/dist/chunks/config-DeyT9dJl.js.map +1 -1
  67. package/dist/chunks/config-DolULhjJ.js.map +1 -1
  68. package/dist/chunks/config-DpAYidyY.js.map +1 -0
  69. package/dist/chunks/config-Droqn55j.js.map +1 -1
  70. package/dist/chunks/config-DwABJHEo.js.map +1 -1
  71. package/dist/chunks/config-E1cTyRVV.js.map +1 -1
  72. package/dist/chunks/config-MmPym-Z7.js.map +1 -0
  73. package/dist/chunks/config-QaIc_gRa.js.map +1 -1
  74. package/dist/chunks/config-Yy67uWHY.js.map +1 -1
  75. package/dist/chunks/config-Z5LeUXys.js.map +1 -1
  76. package/dist/chunks/config-_jbgsFpw.js.map +1 -1
  77. package/dist/chunks/config-eXB87DOi.js.map +1 -1
  78. package/dist/chunks/config-rLkc9Zn2.js.map +1 -1
  79. package/dist/chunks/{context-CTbuwcYs.js → context-CPMRfwVr.js} +1 -1
  80. package/dist/chunks/{context-CTbuwcYs.js.map → context-CPMRfwVr.js.map} +1 -1
  81. package/dist/chunks/{grModalStyles-EZfuEiw_.js → grModalStyles-BEkiFal_.js} +10 -1
  82. package/dist/chunks/grModalStyles-BEkiFal_.js.map +1 -0
  83. package/dist/chunks/{grRadioStyles-DGL2QLy6.js → grRadioStyles-BwRyCjQQ.js} +4 -2
  84. package/dist/chunks/{grRadioStyles-DGL2QLy6.js.map → grRadioStyles-BwRyCjQQ.js.map} +1 -1
  85. package/dist/chunks/{granular-provider-DCn6fgEs.js → granular-provider-DP2gk0oa.js} +10 -9
  86. package/dist/chunks/{granular-provider-DCn6fgEs.js.map → granular-provider-DP2gk0oa.js.map} +1 -1
  87. package/dist/chunks/{overlayStack-0CZS99Da.js → overlayStack-B_UFaFzk.js} +65 -24
  88. package/dist/chunks/overlayStack-B_UFaFzk.js.map +1 -0
  89. package/dist/chunks/{renamedProp-BwcN-SJg.js → renamedProp-Dy96tT-F.js} +1 -1
  90. package/dist/chunks/{renamedProp-BwcN-SJg.js.map → renamedProp-Dy96tT-F.js.map} +1 -1
  91. package/dist/chunks/{useModalOverlay-BnAGZpcI.js → useModalOverlay-BwX8WEcI.js} +3 -3
  92. package/dist/chunks/{useModalOverlay-BnAGZpcI.js.map → useModalOverlay-BwX8WEcI.js.map} +1 -1
  93. package/dist/chunks/{usePortalTarget-C0p-mhaM.js → usePortalTarget-BhrRgdqW.js} +1 -1
  94. package/dist/chunks/{usePortalTarget-C0p-mhaM.js.map → usePortalTarget-BhrRgdqW.js.map} +1 -1
  95. package/dist/chunks/{validation-5HhpanPP.js → validation-BDjqsuGB.js} +1 -1
  96. package/dist/chunks/{validation-5HhpanPP.js.map → validation-BDjqsuGB.js.map} +1 -1
  97. package/dist/components/GrAlert/chunks/{GrAlert-FAVf-ksH.js → GrAlert-D72y1IEh.js} +1 -1
  98. package/dist/components/GrAlert/chunks/{GrAlert-FAVf-ksH.js.map → GrAlert-D72y1IEh.js.map} +1 -1
  99. package/dist/components/GrAlert/index.js +1 -1
  100. package/dist/components/GrAutocomplete/chunks/{GrAutocomplete-BQsSE7sj.js → GrAutocomplete-BpmFmpKs.js} +4 -6
  101. package/dist/components/GrAutocomplete/chunks/{GrAutocomplete-BQsSE7sj.js.map → GrAutocomplete-BpmFmpKs.js.map} +1 -1
  102. package/dist/components/GrAutocomplete/index.js +1 -1
  103. package/dist/components/GrAvatar/chunks/{GrAvatar-CNmLmgcr.js → GrAvatar-dWEXiCJG.js} +1 -1
  104. package/dist/components/GrAvatar/chunks/{GrAvatar-CNmLmgcr.js.map → GrAvatar-dWEXiCJG.js.map} +1 -1
  105. package/dist/components/GrAvatar/index.js +1 -1
  106. package/dist/components/GrBadge/chunks/{GrBadge-DpUDXKbq.js → GrBadge-DBeQXEir.js} +2 -2
  107. package/dist/components/GrBadge/chunks/{GrBadge-DpUDXKbq.js.map → GrBadge-DBeQXEir.js.map} +1 -1
  108. package/dist/components/GrBadge/index.js +1 -1
  109. package/dist/components/GrBadgeWrap/chunks/{GrBadgeWrap-B-A3PRkE.js → GrBadgeWrap-wdfxaXiu.js} +3 -1
  110. package/dist/components/GrBadgeWrap/chunks/{GrBadgeWrap-B-A3PRkE.js.map → GrBadgeWrap-wdfxaXiu.js.map} +1 -1
  111. package/dist/components/GrBadgeWrap/index.js +1 -1
  112. package/dist/components/GrBottomNav/chunks/{GrBottomNav-wtFatLjB.js → GrBottomNav-nE08pVUJ.js} +1 -1
  113. package/dist/components/GrBottomNav/chunks/{GrBottomNav-wtFatLjB.js.map → GrBottomNav-nE08pVUJ.js.map} +1 -1
  114. package/dist/components/GrBottomNav/index.js +1 -1
  115. package/dist/components/GrBreadcrumbs/chunks/{GrBreadcrumbs-DRDNan_n.js → GrBreadcrumbs-DOpwY2EF.js} +3 -3
  116. package/dist/components/GrBreadcrumbs/chunks/{GrBreadcrumbs-DRDNan_n.js.map → GrBreadcrumbs-DOpwY2EF.js.map} +1 -1
  117. package/dist/components/GrBreadcrumbs/index.js +1 -1
  118. package/dist/components/GrButton/chunks/{GrButton-7GP0zObj.js → GrButton-CS4TqMtG.js} +1 -1
  119. package/dist/components/GrButton/chunks/{GrButton-7GP0zObj.js.map → GrButton-CS4TqMtG.js.map} +1 -1
  120. package/dist/components/GrButton/index.js +1 -1
  121. package/dist/components/GrButtonGroup/chunks/GrButtonGroup-CKyiAV8K.js.map +1 -1
  122. package/dist/components/GrButtonGroup/index.js +1 -1
  123. package/dist/components/GrCard/chunks/{GrCard-BttXz1pQ.js → GrCard-Ck5--lMF.js} +2 -2
  124. package/dist/components/GrCard/chunks/{GrCard-BttXz1pQ.js.map → GrCard-Ck5--lMF.js.map} +1 -1
  125. package/dist/components/GrCard/index.js +1 -1
  126. package/dist/components/GrCheckbox/chunks/{GrCheckbox-CEcHIsXM.js → GrCheckbox-Dp201frb.js} +1 -1
  127. package/dist/components/GrCheckbox/chunks/{GrCheckbox-CEcHIsXM.js.map → GrCheckbox-Dp201frb.js.map} +1 -1
  128. package/dist/components/GrCheckbox/index.js +1 -1
  129. package/dist/components/GrCheckboxGroup/chunks/{GrCheckboxGroup-BOwrVcFr.js → GrCheckboxGroup-IpqG5qwm.js} +2 -2
  130. package/dist/components/GrCheckboxGroup/chunks/{GrCheckboxGroup-BOwrVcFr.js.map → GrCheckboxGroup-IpqG5qwm.js.map} +1 -1
  131. package/dist/components/GrCheckboxGroup/index.js +1 -1
  132. package/dist/components/GrChip/chunks/{GrChip-BTivtwff.js → GrChip-CKqyzYcv.js} +10 -7
  133. package/dist/components/GrChip/chunks/{GrChip-BTivtwff.js.map → GrChip-CKqyzYcv.js.map} +1 -1
  134. package/dist/components/GrChip/index.js +1 -1
  135. package/dist/components/GrChipGroup/chunks/{GrChipGroup-C78Vcwos.js → GrChipGroup-dDGwnC04.js} +1 -1
  136. package/dist/components/GrChipGroup/chunks/{GrChipGroup-C78Vcwos.js.map → GrChipGroup-dDGwnC04.js.map} +1 -1
  137. package/dist/components/GrChipGroup/index.js +1 -1
  138. package/dist/components/GrCodeBlock/chunks/{GrCodeBlock-Dp0eEBTZ.js → GrCodeBlock-BUOwKwQE.js} +2 -2
  139. package/dist/components/GrCodeBlock/chunks/{GrCodeBlock-Dp0eEBTZ.js.map → GrCodeBlock-BUOwKwQE.js.map} +1 -1
  140. package/dist/components/GrCodeBlock/index.js +1 -1
  141. package/dist/components/GrCollapse/chunks/{GrCollapse-BlW6ybdL.js → GrCollapse-DWH3QAnU.js} +6 -5
  142. package/dist/components/GrCollapse/chunks/{GrCollapse-BlW6ybdL.js.map → GrCollapse-DWH3QAnU.js.map} +1 -1
  143. package/dist/components/GrCollapse/index.js +1 -1
  144. package/dist/components/GrColorPicker/chunks/{GrColorPicker-CIgdPXHn.js → GrColorPicker-BNtpj_P6.js} +4 -4
  145. package/dist/components/GrColorPicker/chunks/{GrColorPicker-CIgdPXHn.js.map → GrColorPicker-BNtpj_P6.js.map} +1 -1
  146. package/dist/components/GrColorPicker/index.js +1 -1
  147. package/dist/components/GrCommandPalette/chunks/{GrCommandPalette-BZHUKlux.js → GrCommandPalette-BVZEd4yy.js} +7 -7
  148. package/dist/components/GrCommandPalette/chunks/{GrCommandPalette-BZHUKlux.js.map → GrCommandPalette-BVZEd4yy.js.map} +1 -1
  149. package/dist/components/GrCommandPalette/index.js +1 -1
  150. package/dist/components/GrConfigProvider/chunks/{GrConfigProvider-BF7R3hgg.js → GrConfigProvider-t9x2UToH.js} +13 -12
  151. package/dist/components/GrConfigProvider/chunks/{GrConfigProvider-BF7R3hgg.js.map → GrConfigProvider-t9x2UToH.js.map} +1 -1
  152. package/dist/components/GrConfigProvider/index.js +2 -2
  153. package/dist/components/GrConfirmDialog/chunks/{GrConfirmDialog-jRDs_E6C.js → GrConfirmDialog-K5ht2cYq.js} +4 -4
  154. package/dist/components/GrConfirmDialog/chunks/{GrConfirmDialog-jRDs_E6C.js.map → GrConfirmDialog-K5ht2cYq.js.map} +1 -1
  155. package/dist/components/GrConfirmDialog/index.js +1 -1
  156. package/dist/components/GrContextMenu/chunks/{GrContextMenu-DlFWm0eW.js → GrContextMenu-Dd2tgMoL.js} +1 -1
  157. package/dist/components/GrContextMenu/chunks/{GrContextMenu-DlFWm0eW.js.map → GrContextMenu-Dd2tgMoL.js.map} +1 -1
  158. package/dist/components/GrContextMenu/index.js +1 -1
  159. package/dist/components/GrDataTable/chunks/{GrDataTable-4JAgOQ-7.js → GrDataTable-BYYG_XZA.js} +5 -5
  160. package/dist/components/GrDataTable/chunks/{GrDataTable-4JAgOQ-7.js.map → GrDataTable-BYYG_XZA.js.map} +1 -1
  161. package/dist/components/GrDataTable/index.js +1 -1
  162. package/dist/components/GrDelta/chunks/{GrDelta-BZwkgQW-.js → GrDelta-BpfqebEV.js} +0 -0
  163. package/dist/components/GrDelta/chunks/{GrDelta-BZwkgQW-.js.map → GrDelta-BpfqebEV.js.map} +1 -1
  164. package/dist/components/GrDelta/index.js +1 -1
  165. package/dist/components/GrDescriptionList/chunks/{GrDescriptionList-BMeCgFV3.js → GrDescriptionList-D8ANFpn_.js} +2 -2
  166. package/dist/components/GrDescriptionList/chunks/{GrDescriptionList-BMeCgFV3.js.map → GrDescriptionList-D8ANFpn_.js.map} +1 -1
  167. package/dist/components/GrDescriptionList/index.js +2 -2
  168. package/dist/components/GrDialog/chunks/{GrDialog-C01Hhk6G.js → GrDialog-CeJubnKJ.js} +3 -3
  169. package/dist/components/GrDialog/chunks/{GrDialog-C01Hhk6G.js.map → GrDialog-CeJubnKJ.js.map} +1 -1
  170. package/dist/components/GrDialog/index.js +1 -1
  171. package/dist/components/GrDialogService/chunks/{GrDialogService-CmsJNUmM.js → GrDialogService-BArvw1DV.js} +9 -8
  172. package/dist/components/GrDialogService/chunks/{GrDialogService-CmsJNUmM.js.map → GrDialogService-BArvw1DV.js.map} +1 -1
  173. package/dist/components/GrDialogService/index.js +1 -1
  174. package/dist/components/GrDivider/chunks/{GrDivider-BXavGcMX.js → GrDivider-DxA-zV25.js} +1 -1
  175. package/dist/components/GrDivider/chunks/{GrDivider-BXavGcMX.js.map → GrDivider-DxA-zV25.js.map} +1 -1
  176. package/dist/components/GrDivider/index.js +1 -1
  177. package/dist/components/GrDrawer/chunks/{GrDrawer-xfoy-MCj.js → GrDrawer-BBHNgeH0.js} +5 -5
  178. package/dist/components/GrDrawer/chunks/{GrDrawer-xfoy-MCj.js.map → GrDrawer-BBHNgeH0.js.map} +1 -1
  179. package/dist/components/GrDrawer/index.js +1 -1
  180. package/dist/components/GrDropdown/chunks/{GrDropdown-7r772-Cq.js → GrDropdown-CUlviqMi.js} +6 -8
  181. package/dist/components/GrDropdown/chunks/{GrDropdown-7r772-Cq.js.map → GrDropdown-CUlviqMi.js.map} +1 -1
  182. package/dist/components/GrDropdown/index.js +1 -1
  183. package/dist/components/GrDropdownMenu/chunks/{GrDropdownMenu-DNurbsWc.js → GrDropdownMenu-COOR1LCs.js} +1 -1
  184. package/dist/components/GrDropdownMenu/chunks/{GrDropdownMenu-DNurbsWc.js.map → GrDropdownMenu-COOR1LCs.js.map} +1 -1
  185. package/dist/components/GrDropdownMenu/chunks/GrDropdownMenuList-B33ZzwfB.js.map +1 -1
  186. package/dist/components/GrDropdownMenu/index.js +1 -1
  187. package/dist/components/GrEmptyState/chunks/{GrEmptyState-RqsWvgI9.js → GrEmptyState-BbvwE-E0.js} +2 -2
  188. package/dist/components/GrEmptyState/chunks/{GrEmptyState-RqsWvgI9.js.map → GrEmptyState-BbvwE-E0.js.map} +1 -1
  189. package/dist/components/GrEmptyState/index.js +1 -1
  190. package/dist/components/GrFilePreview/chunks/{GrFilePreview-C9Z7hMK8.js → GrFilePreview-PabkLgYX.js} +1 -1
  191. package/dist/components/GrFilePreview/chunks/{GrFilePreview-C9Z7hMK8.js.map → GrFilePreview-PabkLgYX.js.map} +1 -1
  192. package/dist/components/GrFilePreview/index.js +1 -1
  193. package/dist/components/GrFileUpload/chunks/{GrFileUpload-LL8RZvC0.js → GrFileUpload-BwMR71zN.js} +4 -4
  194. package/dist/components/GrFileUpload/chunks/{GrFileUpload-LL8RZvC0.js.map → GrFileUpload-BwMR71zN.js.map} +1 -1
  195. package/dist/components/GrFileUpload/index.js +1 -1
  196. package/dist/components/GrForm/chunks/{GrForm-CrnfCsgj.js → GrForm-xTtavR-K.js} +1 -1
  197. package/dist/components/GrForm/chunks/{GrForm-CrnfCsgj.js.map → GrForm-xTtavR-K.js.map} +1 -1
  198. package/dist/components/GrForm/index.js +2 -2
  199. package/dist/components/GrFormField/chunks/{GrFormField-DSylU7IU.js → GrFormField-DO61vxpS.js} +2 -2
  200. package/dist/components/GrFormField/chunks/{GrFormField-DSylU7IU.js.map → GrFormField-DO61vxpS.js.map} +1 -1
  201. package/dist/components/GrFormField/index.js +1 -1
  202. package/dist/components/GrFormFile/chunks/{GrFormFile-B1jGZyIj.js → GrFormFile-Dlxx-9zi.js} +3 -3
  203. package/dist/components/GrFormFile/chunks/{GrFormFile-B1jGZyIj.js.map → GrFormFile-Dlxx-9zi.js.map} +1 -1
  204. package/dist/components/GrFormFile/index.js +1 -1
  205. package/dist/components/GrFormSection/chunks/{GrFormSection-ejieOg9H.js → GrFormSection-DV1S6R_N.js} +1 -1
  206. package/dist/components/GrFormSection/chunks/{GrFormSection-ejieOg9H.js.map → GrFormSection-DV1S6R_N.js.map} +1 -1
  207. package/dist/components/GrFormSection/index.js +1 -1
  208. package/dist/components/GrIcon/chunks/{GrIcon-Dmf0c9ba.js → GrIcon-DTZIgmje.js} +1 -1
  209. package/dist/components/GrIcon/chunks/{GrIcon-Dmf0c9ba.js.map → GrIcon-DTZIgmje.js.map} +1 -1
  210. package/dist/components/GrIcon/index.js +1 -1
  211. package/dist/components/GrImageViewer/chunks/{GrImageViewer--BU8yrfx.js → GrImageViewer-BjYw-uTF.js} +2 -4
  212. package/dist/components/GrImageViewer/chunks/{GrImageViewer--BU8yrfx.js.map → GrImageViewer-BjYw-uTF.js.map} +1 -1
  213. package/dist/components/GrImageViewer/index.js +1 -1
  214. package/dist/components/GrInput/chunks/{GrInput-BLywRZUN.js → GrInput-TFeBm3gQ.js} +2 -1
  215. package/dist/components/GrInput/chunks/{GrInput-BLywRZUN.js.map → GrInput-TFeBm3gQ.js.map} +1 -1
  216. package/dist/components/GrInput/index.js +1 -1
  217. package/dist/components/GrInputTag/chunks/{GrInputTag-ByD9NugQ.js → GrInputTag-DhfUNOA5.js} +3 -3
  218. package/dist/components/GrInputTag/chunks/{GrInputTag-ByD9NugQ.js.map → GrInputTag-DhfUNOA5.js.map} +1 -1
  219. package/dist/components/GrInputTag/index.js +1 -1
  220. package/dist/components/GrJsonViewer/chunks/{GrJsonViewer-BCZ7lE2k.js → GrJsonViewer-CdtmUpZ3.js} +6 -6
  221. package/dist/components/GrJsonViewer/chunks/{GrJsonViewer-BCZ7lE2k.js.map → GrJsonViewer-CdtmUpZ3.js.map} +1 -1
  222. package/dist/components/GrJsonViewer/index.js +2 -2
  223. package/dist/components/GrKbd/chunks/{GrKbd-D2ga1H9i.js → GrKbd-D_a1mPLe.js} +1 -1
  224. package/dist/components/GrKbd/chunks/{GrKbd-D2ga1H9i.js.map → GrKbd-D_a1mPLe.js.map} +1 -1
  225. package/dist/components/GrKbd/index.js +1 -1
  226. package/dist/components/GrLink/chunks/{GrLink-DYXw3W9w.js → GrLink-DwWErumU.js} +2 -2
  227. package/dist/components/GrLink/chunks/{GrLink-DYXw3W9w.js.map → GrLink-DwWErumU.js.map} +1 -1
  228. package/dist/components/GrLink/index.js +2 -2
  229. package/dist/components/GrList/chunks/{GrList-B_CRJB4c.js → GrList-Unya-LXb.js} +3 -3
  230. package/dist/components/GrList/chunks/{GrList-B_CRJB4c.js.map → GrList-Unya-LXb.js.map} +1 -1
  231. package/dist/components/GrList/index.js +1 -1
  232. package/dist/components/GrLoading/chunks/{GrLoading-CMD3Ri9P.js → GrLoading-BDrlrup_.js} +1 -1
  233. package/dist/components/GrLoading/chunks/{GrLoading-CMD3Ri9P.js.map → GrLoading-BDrlrup_.js.map} +1 -1
  234. package/dist/components/GrLoading/index.js +1 -1
  235. package/dist/components/GrModal/chunks/{GrModal-_JrDhon-.js → GrModal-xIWaJozo.js} +7 -6
  236. package/dist/components/GrModal/chunks/GrModal-xIWaJozo.js.map +1 -0
  237. package/dist/components/GrModal/index.js +2 -2
  238. package/dist/components/GrNavbar/chunks/{GrNavbar-Dr8e5kW-.js → GrNavbar-BRGuksiy.js} +3 -3
  239. package/dist/components/GrNavbar/chunks/{GrNavbar-Dr8e5kW-.js.map → GrNavbar-BRGuksiy.js.map} +1 -1
  240. package/dist/components/GrNavbar/index.js +1 -1
  241. package/dist/components/GrNumberInput/chunks/{GrNumberInput-DQ59YICu.js → GrNumberInput-BqPydXpK.js} +7 -9
  242. package/dist/components/GrNumberInput/chunks/{GrNumberInput-DQ59YICu.js.map → GrNumberInput-BqPydXpK.js.map} +1 -1
  243. package/dist/components/GrNumberInput/index.js +2 -2
  244. package/dist/components/GrPagination/chunks/{GrPagination-gBoWVHk6.js → GrPagination-DhbNZHEF.js} +26 -11
  245. package/dist/components/GrPagination/chunks/GrPagination-DhbNZHEF.js.map +1 -0
  246. package/dist/components/GrPagination/index.js +1 -1
  247. package/dist/components/GrPopover/chunks/{GrPopover-DEFxDffj.js → GrPopover-BakLcWkX.js} +3 -3
  248. package/dist/components/GrPopover/chunks/{GrPopover-DEFxDffj.js.map → GrPopover-BakLcWkX.js.map} +1 -1
  249. package/dist/components/GrPopover/index.js +2 -2
  250. package/dist/components/GrProgressBar/chunks/{GrProgressBar-hszUOC8f.js → GrProgressBar-C3NRBqIP.js} +6 -3
  251. package/dist/components/GrProgressBar/chunks/GrProgressBar-C3NRBqIP.js.map +1 -0
  252. package/dist/components/GrProgressBar/index.js +1 -1
  253. package/dist/components/GrProgressCircle/chunks/{GrProgressCircle-D3yWXYDa.js → GrProgressCircle-CdvbINQc.js} +2 -2
  254. package/dist/components/GrProgressCircle/chunks/{GrProgressCircle-D3yWXYDa.js.map → GrProgressCircle-CdvbINQc.js.map} +1 -1
  255. package/dist/components/GrProgressCircle/index.js +1 -1
  256. package/dist/components/GrPromptDialog/chunks/{GrPromptDialog-CailXSqW.js → GrPromptDialog-C9Y1ifE_.js} +8 -8
  257. package/dist/components/GrPromptDialog/chunks/{GrPromptDialog-CailXSqW.js.map → GrPromptDialog-C9Y1ifE_.js.map} +1 -1
  258. package/dist/components/GrPromptDialog/index.js +1 -1
  259. package/dist/components/GrRadio/chunks/{GrRadio-Aq3v8XgG.js → GrRadio-B1776V9D.js} +2 -2
  260. package/dist/components/GrRadio/chunks/{GrRadio-Aq3v8XgG.js.map → GrRadio-B1776V9D.js.map} +1 -1
  261. package/dist/components/GrRadio/index.js +2 -2
  262. package/dist/components/GrRadioGroup/chunks/{GrRadioGroup-y9LVdTWh.js → GrRadioGroup-UgitrBFl.js} +2 -2
  263. package/dist/components/GrRadioGroup/chunks/{GrRadioGroup-y9LVdTWh.js.map → GrRadioGroup-UgitrBFl.js.map} +1 -1
  264. package/dist/components/GrRadioGroup/index.js +1 -1
  265. package/dist/components/GrRating/chunks/{GrRating-IEiTOdnF.js → GrRating-DTriyyqG.js} +1 -1
  266. package/dist/components/GrRating/chunks/{GrRating-IEiTOdnF.js.map → GrRating-DTriyyqG.js.map} +1 -1
  267. package/dist/components/GrRating/index.js +1 -1
  268. package/dist/components/GrResponseErrorBanner/chunks/{GrResponseErrorBanner-DMeOWlzj.js → GrResponseErrorBanner-NEEJZ8zi.js} +2 -2
  269. package/dist/components/GrResponseErrorBanner/chunks/{GrResponseErrorBanner-DMeOWlzj.js.map → GrResponseErrorBanner-NEEJZ8zi.js.map} +1 -1
  270. package/dist/components/GrResponseErrorBanner/chunks/{GrResponseErrorBanner-CBVRpgIG.js → GrResponseErrorBanner-ZvBvEQDZ.js} +1 -1
  271. package/dist/components/GrResponseErrorBanner/chunks/{GrResponseErrorBanner-CBVRpgIG.js.map → GrResponseErrorBanner-ZvBvEQDZ.js.map} +1 -1
  272. package/dist/components/GrResponseErrorBanner/index.js +2 -2
  273. package/dist/components/GrSegmented/chunks/{GrSegmented-CB-VR-yL.js → GrSegmented-NKTi9bMG.js} +1 -1
  274. package/dist/components/GrSegmented/chunks/{GrSegmented-CB-VR-yL.js.map → GrSegmented-NKTi9bMG.js.map} +1 -1
  275. package/dist/components/GrSegmented/index.js +1 -1
  276. package/dist/components/GrSelect/chunks/{GrSelect-CZqV1Eg4.js → GrSelect-Do1iAyp1.js} +8 -12
  277. package/dist/components/GrSelect/chunks/GrSelect-Do1iAyp1.js.map +1 -0
  278. package/dist/components/GrSelect/index.js +1 -1
  279. package/dist/components/GrSelect/styles.css +1 -1
  280. package/dist/components/GrSidebar/chunks/{GrSidebar-alkwBUzL.js → GrSidebar-DoKLlHSw.js} +2 -2
  281. package/dist/components/GrSidebar/chunks/{GrSidebar-alkwBUzL.js.map → GrSidebar-DoKLlHSw.js.map} +1 -1
  282. package/dist/components/GrSidebar/index.js +1 -1
  283. package/dist/components/GrSkeleton/chunks/GrSkeleton-CgfXxPQ2.js.map +1 -1
  284. package/dist/components/GrSlider/chunks/{GrSlider-DTTrZTHK.js → GrSlider-Db-jACXz.js} +14 -6
  285. package/dist/components/GrSlider/chunks/GrSlider-Db-jACXz.js.map +1 -0
  286. package/dist/components/GrSlider/index.js +1 -1
  287. package/dist/components/GrSortableList/chunks/{GrSortableList-HyKX--rO.js → GrSortableList-CQCaWivn.js} +1 -1
  288. package/dist/components/GrSortableList/chunks/{GrSortableList-HyKX--rO.js.map → GrSortableList-CQCaWivn.js.map} +1 -1
  289. package/dist/components/GrSortableList/index.js +1 -1
  290. package/dist/components/GrSplitter/chunks/{GrSplitter-MltjaADn.js → GrSplitter-C-XQzq7q.js} +1 -1
  291. package/dist/components/GrSplitter/chunks/{GrSplitter-MltjaADn.js.map → GrSplitter-C-XQzq7q.js.map} +1 -1
  292. package/dist/components/GrSplitter/index.js +1 -1
  293. package/dist/components/GrStatistic/chunks/{GrStatistic-qHVasK37.js → GrStatistic-C1_nY4Gc.js} +8 -4
  294. package/dist/components/GrStatistic/chunks/GrStatistic-C1_nY4Gc.js.map +1 -0
  295. package/dist/components/GrStatistic/index.js +1 -1
  296. package/dist/components/GrSteps/chunks/{GrSteps-C2jxpZoN.js → GrSteps-DXj7m-WO.js} +2 -2
  297. package/dist/components/GrSteps/chunks/{GrSteps-C2jxpZoN.js.map → GrSteps-DXj7m-WO.js.map} +1 -1
  298. package/dist/components/GrSteps/index.js +1 -1
  299. package/dist/components/GrSwitch/chunks/{GrSwitch-7Oe5QfQZ.js → GrSwitch-CriHWT2A.js} +1 -1
  300. package/dist/components/GrSwitch/chunks/{GrSwitch-7Oe5QfQZ.js.map → GrSwitch-CriHWT2A.js.map} +1 -1
  301. package/dist/components/GrSwitch/index.js +1 -1
  302. package/dist/components/GrTabPanels/chunks/{GrTabPanels-BZQS8-JM.js → GrTabPanels-5zsbqS1v.js} +1 -1
  303. package/dist/components/GrTabPanels/chunks/{GrTabPanels-BZQS8-JM.js.map → GrTabPanels-5zsbqS1v.js.map} +1 -1
  304. package/dist/components/GrTabPanels/index.js +1 -1
  305. package/dist/components/GrTable/chunks/{GrTable-jhUTczjv.js → GrTable-iwzHvlMC.js} +1 -1
  306. package/dist/components/GrTable/chunks/{GrTable-jhUTczjv.js.map → GrTable-iwzHvlMC.js.map} +1 -1
  307. package/dist/components/GrTable/index.js +1 -1
  308. package/dist/components/GrTabs/chunks/{GrTabs-CT2nk_HV.js → GrTabs-DHfv67cp.js} +1 -1
  309. package/dist/components/GrTabs/chunks/{GrTabs-CT2nk_HV.js.map → GrTabs-DHfv67cp.js.map} +1 -1
  310. package/dist/components/GrTabs/index.js +1 -1
  311. package/dist/components/GrTextarea/chunks/{GrTextarea-DinXG12-.js → GrTextarea-BII3w61K.js} +1 -1
  312. package/dist/components/GrTextarea/chunks/{GrTextarea-DinXG12-.js.map → GrTextarea-BII3w61K.js.map} +1 -1
  313. package/dist/components/GrTextarea/index.js +1 -1
  314. package/dist/components/GrTimeline/chunks/{GrTimeline-BiHpArsg.js → GrTimeline-Bs60huw0.js} +2 -2
  315. package/dist/components/GrTimeline/chunks/{GrTimeline-BiHpArsg.js.map → GrTimeline-Bs60huw0.js.map} +1 -1
  316. package/dist/components/GrTimeline/index.js +1 -1
  317. package/dist/components/GrToaster/chunks/{GrToaster-COXIBKzq.js → GrToaster-D-sV-9of.js} +4 -4
  318. package/dist/components/GrToaster/chunks/{GrToaster-COXIBKzq.js.map → GrToaster-D-sV-9of.js.map} +1 -1
  319. package/dist/components/GrToaster/index.js +1 -1
  320. package/dist/components/GrTooltip/chunks/{GrTooltip-uYETdbCD.js → GrTooltip-BUiTbROv.js} +3 -3
  321. package/dist/components/GrTooltip/chunks/{GrTooltip-uYETdbCD.js.map → GrTooltip-BUiTbROv.js.map} +1 -1
  322. package/dist/components/GrTooltip/index.js +1 -1
  323. package/dist/components/GrTree/chunks/{GrTree-Ci6CZfKR.js → GrTree-CkELQwR8.js} +1 -2
  324. package/dist/components/GrTree/chunks/{GrTree-Ci6CZfKR.js.map → GrTree-CkELQwR8.js.map} +1 -1
  325. package/dist/components/GrTree/index.js +1 -1
  326. package/dist/components/GrTreeSelect/chunks/{GrTreeSelect-DOXcpWq2.js → GrTreeSelect-DurwZ7Cz.js} +4 -4
  327. package/dist/components/GrTreeSelect/chunks/{GrTreeSelect-DOXcpWq2.js.map → GrTreeSelect-DurwZ7Cz.js.map} +1 -1
  328. package/dist/components/GrTreeSelect/index.js +1 -1
  329. package/dist/components/GrValue/chunks/GrValue-ezkQM05Q.js.map +1 -1
  330. package/dist/composables/useFloating.js +1 -1
  331. package/dist/composables/useGrComponentConfig.js +1 -1
  332. package/dist/composables/useOverlayLayer.js +1 -1
  333. package/dist/composables/usePortalTarget.js +1 -1
  334. package/dist/composables/useTheme.js +1 -1
  335. package/dist/composables/useTheme.js.map +1 -1
  336. package/dist/composables/useToast.js +1 -1
  337. package/dist/composables/useToast.js.map +1 -1
  338. package/dist/composables/useVirtualList.js +3 -5
  339. package/dist/composables/useVirtualList.js.map +1 -1
  340. package/dist/directives/loading.js +1 -1
  341. package/dist/granular-provider-node.js +1 -1
  342. package/dist/granular-provider.js +1 -1
  343. package/dist/index.js +87 -87
  344. package/dist/testing.js +1 -1
  345. package/dist/testing.js.map +1 -1
  346. package/dist/types/components/GrDialog/GrDialog.vue.d.ts +1 -1
  347. package/dist/types/components/GrDrawer/GrDrawer.vue.d.ts +1 -1
  348. package/dist/types/components/GrModal/GrModal.vue.d.ts +1 -1
  349. package/dist/types/components/GrModal/grModalStyles.d.ts +9 -0
  350. package/dist/types/components/GrProgressBar/GrProgressBar.vue.d.ts +1 -1
  351. package/dist/types/internal/devHook.d.ts +53 -0
  352. package/dist/vue/index.js +2 -2
  353. package/dist/vue/index.js.map +1 -1
  354. package/dist/web-types.json +2 -2
  355. package/package.json +17 -17
  356. package/dist/chunks/config-CQLNjc9X2.js.map +0 -1
  357. package/dist/chunks/config-CnYdE3HZ2.js.map +0 -1
  358. package/dist/chunks/config-CuQmUkMw2.js.map +0 -1
  359. package/dist/chunks/config-DBmdgoVf2.js.map +0 -1
  360. package/dist/chunks/config-DVCNvhIG2.js.map +0 -1
  361. package/dist/chunks/config-DpAYidyY2.js.map +0 -1
  362. package/dist/chunks/config-MmPym-Z72.js.map +0 -1
  363. package/dist/chunks/config-mlheIMtV.js.map +0 -1
  364. package/dist/chunks/grModalStyles-EZfuEiw_.js.map +0 -1
  365. package/dist/chunks/overlayStack-0CZS99Da.js.map +0 -1
  366. package/dist/components/GrModal/chunks/GrModal-_JrDhon-.js.map +0 -1
  367. package/dist/components/GrPagination/chunks/GrPagination-gBoWVHk6.js.map +0 -1
  368. package/dist/components/GrProgressBar/chunks/GrProgressBar-hszUOC8f.js.map +0 -1
  369. package/dist/components/GrSelect/chunks/GrSelect-CZqV1Eg4.js.map +0 -1
  370. package/dist/components/GrSlider/chunks/GrSlider-DTTrZTHK.js.map +0 -1
  371. package/dist/components/GrStatistic/chunks/GrStatistic-qHVasK37.js.map +0 -1
  372. /package/dist/chunks/{config-CQLNjc9X2.js → config-CQLNjc9X.js} +0 -0
  373. /package/dist/chunks/{config-CnYdE3HZ2.js → config-CnYdE3HZ.js} +0 -0
  374. /package/dist/chunks/{config-DBmdgoVf2.js → config-DBmdgoVf.js} +0 -0
  375. /package/dist/chunks/{config-DVCNvhIG2.js → config-DVCNvhIG.js} +0 -0
  376. /package/dist/chunks/{config-DpAYidyY2.js → config-DpAYidyY.js} +0 -0
  377. /package/dist/chunks/{config-MmPym-Z72.js → config-MmPym-Z7.js} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"GrDropdownMenuList-B33ZzwfB.js","names":[],"sources":["../../../../src/components/GrDropdownMenu/GrDropdownMenuDivider.vue","../../../../src/components/GrDropdownMenu/GrDropdownMenuDivider.vue","../../../../src/components/GrDropdownMenu/GrDropdownMenuHeader.vue","../../../../src/components/GrDropdownMenu/GrDropdownMenuHeader.vue","../../../../src/components/GrDropdownMenu/GrDropdownMenuGroup.vue","../../../../src/components/GrDropdownMenu/GrDropdownMenuGroup.vue","../../../../src/components/GrDropdownMenu/GrDropdownMenuItem.vue","../../../../src/components/GrDropdownMenu/GrDropdownMenuItem.vue","../../../../src/components/GrDropdownMenu/menuModel.ts","../../../../src/components/GrDropdownMenu/GrDropdownMenuEntries.vue","../../../../src/components/GrDropdownMenu/GrDropdownMenuEntries.vue","../../../../src/components/GrDropdownMenu/GrDropdownMenuList.vue","../../../../src/components/GrDropdownMenu/GrDropdownMenuList.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { dividerClass, dividerInsetClass } from './grDropdownMenuStyles'\n\nexport interface GrDropdownMenuDividerProps {\n inset?: boolean\n}\n\nwithDefaults(defineProps<GrDropdownMenuDividerProps>(), {\n inset: false,\n})\n</script>\n\n<template>\n <div\n data-gr-dropdown-menu-divider\n role=\"separator\"\n :class=\"[dividerClass, inset ? dividerInsetClass : '']\"\n />\n</template>\n","<script setup lang=\"ts\">\nimport { dividerClass, dividerInsetClass } from './grDropdownMenuStyles'\n\nexport interface GrDropdownMenuDividerProps {\n inset?: boolean\n}\n\nwithDefaults(defineProps<GrDropdownMenuDividerProps>(), {\n inset: false,\n})\n</script>\n\n<template>\n <div\n data-gr-dropdown-menu-divider\n role=\"separator\"\n :class=\"[dividerClass, inset ? dividerInsetClass : '']\"\n />\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useSlots } from 'vue'\n\nimport { headerClass, textAlignClass, type GrDropdownMenuHeaderAlign } from './grDropdownMenuStyles'\n\nexport type { GrDropdownMenuHeaderAlign } from './grDropdownMenuStyles'\n\nexport interface GrDropdownMenuHeaderProps {\n title?: string\n align?: GrDropdownMenuHeaderAlign\n uppercase?: boolean\n}\n\nconst props = withDefaults(defineProps<GrDropdownMenuHeaderProps>(), {\n title: undefined,\n align: 'left',\n uppercase: true,\n})\n\n/**\n * Заголовок — подпись, а не пункт меню: `role=\"presentation\"` убирает его из\n * числа потомков `role=\"menu\"`. Имя группе он даёт через `aria-labelledby`\n * у `GrDropdownMenuGroup`.\n */\nconst slots = useSlots()\nconst isVisible = computed(() => Boolean(props.title) || Boolean(slots.default))\n\ndefineSlots<{\n /** Заголовок раздела меню вместо пропа `label`. */\n default?: () => any\n}>()\n</script>\n\n<template>\n <div\n v-if=\"isVisible\"\n data-gr-dropdown-menu-header\n role=\"presentation\"\n :class=\"[headerClass, textAlignClass[align], { uppercase }]\"\n >\n <slot>{{ title }}</slot>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useSlots } from 'vue'\n\nimport { headerClass, textAlignClass, type GrDropdownMenuHeaderAlign } from './grDropdownMenuStyles'\n\nexport type { GrDropdownMenuHeaderAlign } from './grDropdownMenuStyles'\n\nexport interface GrDropdownMenuHeaderProps {\n title?: string\n align?: GrDropdownMenuHeaderAlign\n uppercase?: boolean\n}\n\nconst props = withDefaults(defineProps<GrDropdownMenuHeaderProps>(), {\n title: undefined,\n align: 'left',\n uppercase: true,\n})\n\n/**\n * Заголовок — подпись, а не пункт меню: `role=\"presentation\"` убирает его из\n * числа потомков `role=\"menu\"`. Имя группе он даёт через `aria-labelledby`\n * у `GrDropdownMenuGroup`.\n */\nconst slots = useSlots()\nconst isVisible = computed(() => Boolean(props.title) || Boolean(slots.default))\n\ndefineSlots<{\n /** Заголовок раздела меню вместо пропа `label`. */\n default?: () => any\n}>()\n</script>\n\n<template>\n <div\n v-if=\"isVisible\"\n data-gr-dropdown-menu-header\n role=\"presentation\"\n :class=\"[headerClass, textAlignClass[align], { uppercase }]\"\n >\n <slot>{{ title }}</slot>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useId } from 'vue'\n\nimport GrDropdownMenuHeader from './GrDropdownMenuHeader.vue'\nimport { dividersClass, listBaseClass, type GrDropdownMenuHeaderAlign } from './grDropdownMenuStyles'\n\nexport interface GrDropdownMenuGroupProps {\n title?: string\n titleAlign?: GrDropdownMenuHeaderAlign\n dividers?: boolean\n uppercase?: boolean\n}\n\nconst props = withDefaults(defineProps<GrDropdownMenuGroupProps>(), {\n title: undefined,\n titleAlign: 'left',\n dividers: false,\n uppercase: true,\n})\n\nconst titleId = useId()\n// Имя группы читается диктором при входе в неё; без заголовка называть нечем.\nconst labelledBy = computed(() => (props.title ? titleId : undefined))\n\nconst itemsClass = computed(() => [\n listBaseClass,\n props.dividers ? dividersClass : '',\n].filter(Boolean).join(' '))\n\ndefineSlots<{\n /** Пункты группы. */\n default?: () => any\n}>()\n</script>\n\n<template>\n <div\n data-gr-dropdown-menu-group\n role=\"group\"\n :aria-labelledby=\"labelledBy\"\n class=\"w-full\"\n >\n <GrDropdownMenuHeader\n v-if=\"title\"\n :id=\"titleId\"\n :title=\"title\"\n :align=\"titleAlign\"\n :uppercase=\"uppercase\"\n />\n <div role=\"none\" :class=\"itemsClass\">\n <slot />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useId } from 'vue'\n\nimport GrDropdownMenuHeader from './GrDropdownMenuHeader.vue'\nimport { dividersClass, listBaseClass, type GrDropdownMenuHeaderAlign } from './grDropdownMenuStyles'\n\nexport interface GrDropdownMenuGroupProps {\n title?: string\n titleAlign?: GrDropdownMenuHeaderAlign\n dividers?: boolean\n uppercase?: boolean\n}\n\nconst props = withDefaults(defineProps<GrDropdownMenuGroupProps>(), {\n title: undefined,\n titleAlign: 'left',\n dividers: false,\n uppercase: true,\n})\n\nconst titleId = useId()\n// Имя группы читается диктором при входе в неё; без заголовка называть нечем.\nconst labelledBy = computed(() => (props.title ? titleId : undefined))\n\nconst itemsClass = computed(() => [\n listBaseClass,\n props.dividers ? dividersClass : '',\n].filter(Boolean).join(' '))\n\ndefineSlots<{\n /** Пункты группы. */\n default?: () => any\n}>()\n</script>\n\n<template>\n <div\n data-gr-dropdown-menu-group\n role=\"group\"\n :aria-labelledby=\"labelledBy\"\n class=\"w-full\"\n >\n <GrDropdownMenuHeader\n v-if=\"title\"\n :id=\"titleId\"\n :title=\"title\"\n :align=\"titleAlign\"\n :uppercase=\"uppercase\"\n />\n <div role=\"none\" :class=\"itemsClass\">\n <slot />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue'\nimport type { Component } from 'vue'\n\nimport IconCheck from '~icons/lucide/check'\n\nimport {\n grDropdownMenuItemClass,\n itemIndicatorClass,\n itemShortcutClass,\n type GrDropdownMenuItemAlign,\n type GrDropdownMenuItemVariant,\n} from './grDropdownMenuStyles'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nexport type { GrDropdownMenuItemAlign, GrDropdownMenuItemVariant } from './grDropdownMenuStyles'\n\n/**\n * Роль пункта. `menuitemcheckbox`/`menuitemradio` — пункты-переключатели: они\n * обязаны нести `aria-checked`, иначе AT прочитает их как обычные команды.\n */\nexport type GrDropdownMenuItemRole = 'menuitem' | 'menuitemcheckbox' | 'menuitemradio'\n\nexport interface GrDropdownMenuItemProps {\n as?: string | Component\n disabled?: boolean\n /** Пункт-ссылка. У выключенного пункта не рендерится: ссылка осталась бы рабочей. */\n href?: string\n target?: string\n rel?: string\n /** Шорткат для `target=\"_blank\"` + `rel=\"noopener noreferrer\"`. */\n external?: boolean\n align?: GrDropdownMenuItemAlign\n variant?: GrDropdownMenuItemVariant\n role?: GrDropdownMenuItemRole\n /** Состояние переключателя. Осмысленно с `role=\"menuitemcheckbox|radio\"`. */\n checked?: boolean\n /** Иконка слева. Слот `#icon` сильнее. */\n icon?: Component\n /** Подпись сочетания клавиш справа. Слот `#shortcut` сильнее. */\n shortcut?: string\n}\n\nconst props = withDefaults(defineProps<GrDropdownMenuItemProps>(), {\n as: 'button',\n disabled: false,\n href: undefined,\n target: undefined,\n rel: undefined,\n external: false,\n align: 'left',\n variant: 'default',\n role: 'menuitem',\n checked: undefined,\n icon: undefined,\n shortcut: undefined,\n})\n\nconst attrs = useAttrs()\n\n// Полиморфный корень: явный `as` сильнее всего, иначе `href` сам делает пункт\n// ссылкой — как у `GrButton`, чтобы не приходилось задавать `as=\"a\"` вручную.\nconst renderAs = computed<string | Component>(() => {\n if (props.as && props.as !== 'button')\n return props.as\n return props.href ? 'a' : 'button'\n})\n\nconst isNativeButton = computed(() => renderAs.value === 'button')\n\n// Выключенный пункт остаётся ссылкой, если оставить ему `href`: средняя кнопка и\n// контекстное меню браузера обойдут любой перехват клика (тот же приём в `GrButton`).\nconst resolvedHref = computed(() => (props.disabled ? undefined : props.href))\nconst resolvedTarget = computed(() => props.target ?? (props.external ? '_blank' : undefined))\nconst resolvedRel = computed(() =>\n props.rel ?? (resolvedTarget.value === '_blank' ? 'noopener noreferrer' : undefined),\n)\n// Отметка занимает место всегда, когда пункт переключаемый: иначе строки\n// «включено» и «выключено» разъезжаются по горизонтали.\nconst isCheckable = computed(() => props.role !== 'menuitem')\n\nconst className = computed(() => grDropdownMenuItemClass({\n align: props.align,\n variant: props.variant,\n disabled: props.disabled,\n}))\n\n/**\n * Roving tabindex паттерна menu: табируемым остаётся триггер, а внутри панели\n * фокусом распоряжаются стрелки (`GrDropdown` наводит его программно). Без\n * этого `Tab` ходил бы по пунктам, и меню было бы списком кнопок, а не меню.\n *\n * Выключённый пункт из обхода **не** выпадает: `aria-disabled` вместо нативного\n * `disabled` оставляет его фокусируемым, и пользователь узнаёт, что действие\n * существует, но сейчас недоступно (рекомендация WAI-ARIA APG).\n */\nconst resolvedTabindex = computed(() => (attrs.tabindex as number | string | undefined) ?? -1)\n\nfunction onClickCapture(e: MouseEvent): void {\n if (!props.disabled)\n return\n\n e.preventDefault()\n // `stopImmediatePropagation`, а не `stopPropagation`: обработчик, навешенный\n // на сам пункт через `v-bind=\"attrs\"`, живёт на этом же элементе, и обычная\n // остановка всплытия его не отменяет.\n e.stopImmediatePropagation()\n}\n\ndefineSlots<{\n /** Подпись пункта вместо пропа `label`. */\n default?: () => any\n /** Иконка перед подписью. */\n icon?: () => any\n /** Сочетание клавиш справа — обычно `GrKbd`. */\n shortcut?: () => any\n}>()\n</script>\n\n<template>\n <component\n :is=\"renderAs\"\n v-bind=\"attrs\"\n data-gr-dropdown-menu-item\n :role=\"role\"\n :class=\"className\"\n :type=\"isNativeButton ? (attrs.type as any) ?? 'button' : undefined\"\n :href=\"resolvedHref\"\n :target=\"resolvedHref ? resolvedTarget : undefined\"\n :rel=\"resolvedHref ? resolvedRel : undefined\"\n :aria-disabled=\"disabled ? 'true' : undefined\"\n :aria-checked=\"isCheckable ? (checked ? 'true' : 'false') : undefined\"\n :tabindex=\"resolvedTabindex\"\n @click.capture=\"onClickCapture\"\n >\n <span\n v-if=\"isCheckable\"\n data-gr-dropdown-menu-item-indicator\n :class=\"itemIndicatorClass\"\n aria-hidden=\"true\"\n >\n <IconCheck v-if=\"checked\" :class=\"itemIndicatorClass\" />\n </span>\n\n <slot name=\"icon\">\n <component\n :is=\"icon\"\n v-if=\"icon\"\n :class=\"itemIndicatorClass\"\n aria-hidden=\"true\"\n />\n </slot>\n\n <slot />\n\n <slot name=\"shortcut\">\n <span v-if=\"shortcut\" data-gr-dropdown-menu-item-shortcut :class=\"itemShortcutClass\">{{ shortcut }}</span>\n </slot>\n </component>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue'\nimport type { Component } from 'vue'\n\nimport IconCheck from '~icons/lucide/check'\n\nimport {\n grDropdownMenuItemClass,\n itemIndicatorClass,\n itemShortcutClass,\n type GrDropdownMenuItemAlign,\n type GrDropdownMenuItemVariant,\n} from './grDropdownMenuStyles'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nexport type { GrDropdownMenuItemAlign, GrDropdownMenuItemVariant } from './grDropdownMenuStyles'\n\n/**\n * Роль пункта. `menuitemcheckbox`/`menuitemradio` — пункты-переключатели: они\n * обязаны нести `aria-checked`, иначе AT прочитает их как обычные команды.\n */\nexport type GrDropdownMenuItemRole = 'menuitem' | 'menuitemcheckbox' | 'menuitemradio'\n\nexport interface GrDropdownMenuItemProps {\n as?: string | Component\n disabled?: boolean\n /** Пункт-ссылка. У выключенного пункта не рендерится: ссылка осталась бы рабочей. */\n href?: string\n target?: string\n rel?: string\n /** Шорткат для `target=\"_blank\"` + `rel=\"noopener noreferrer\"`. */\n external?: boolean\n align?: GrDropdownMenuItemAlign\n variant?: GrDropdownMenuItemVariant\n role?: GrDropdownMenuItemRole\n /** Состояние переключателя. Осмысленно с `role=\"menuitemcheckbox|radio\"`. */\n checked?: boolean\n /** Иконка слева. Слот `#icon` сильнее. */\n icon?: Component\n /** Подпись сочетания клавиш справа. Слот `#shortcut` сильнее. */\n shortcut?: string\n}\n\nconst props = withDefaults(defineProps<GrDropdownMenuItemProps>(), {\n as: 'button',\n disabled: false,\n href: undefined,\n target: undefined,\n rel: undefined,\n external: false,\n align: 'left',\n variant: 'default',\n role: 'menuitem',\n checked: undefined,\n icon: undefined,\n shortcut: undefined,\n})\n\nconst attrs = useAttrs()\n\n// Полиморфный корень: явный `as` сильнее всего, иначе `href` сам делает пункт\n// ссылкой — как у `GrButton`, чтобы не приходилось задавать `as=\"a\"` вручную.\nconst renderAs = computed<string | Component>(() => {\n if (props.as && props.as !== 'button')\n return props.as\n return props.href ? 'a' : 'button'\n})\n\nconst isNativeButton = computed(() => renderAs.value === 'button')\n\n// Выключенный пункт остаётся ссылкой, если оставить ему `href`: средняя кнопка и\n// контекстное меню браузера обойдут любой перехват клика (тот же приём в `GrButton`).\nconst resolvedHref = computed(() => (props.disabled ? undefined : props.href))\nconst resolvedTarget = computed(() => props.target ?? (props.external ? '_blank' : undefined))\nconst resolvedRel = computed(() =>\n props.rel ?? (resolvedTarget.value === '_blank' ? 'noopener noreferrer' : undefined),\n)\n// Отметка занимает место всегда, когда пункт переключаемый: иначе строки\n// «включено» и «выключено» разъезжаются по горизонтали.\nconst isCheckable = computed(() => props.role !== 'menuitem')\n\nconst className = computed(() => grDropdownMenuItemClass({\n align: props.align,\n variant: props.variant,\n disabled: props.disabled,\n}))\n\n/**\n * Roving tabindex паттерна menu: табируемым остаётся триггер, а внутри панели\n * фокусом распоряжаются стрелки (`GrDropdown` наводит его программно). Без\n * этого `Tab` ходил бы по пунктам, и меню было бы списком кнопок, а не меню.\n *\n * Выключённый пункт из обхода **не** выпадает: `aria-disabled` вместо нативного\n * `disabled` оставляет его фокусируемым, и пользователь узнаёт, что действие\n * существует, но сейчас недоступно (рекомендация WAI-ARIA APG).\n */\nconst resolvedTabindex = computed(() => (attrs.tabindex as number | string | undefined) ?? -1)\n\nfunction onClickCapture(e: MouseEvent): void {\n if (!props.disabled)\n return\n\n e.preventDefault()\n // `stopImmediatePropagation`, а не `stopPropagation`: обработчик, навешенный\n // на сам пункт через `v-bind=\"attrs\"`, живёт на этом же элементе, и обычная\n // остановка всплытия его не отменяет.\n e.stopImmediatePropagation()\n}\n\ndefineSlots<{\n /** Подпись пункта вместо пропа `label`. */\n default?: () => any\n /** Иконка перед подписью. */\n icon?: () => any\n /** Сочетание клавиш справа — обычно `GrKbd`. */\n shortcut?: () => any\n}>()\n</script>\n\n<template>\n <component\n :is=\"renderAs\"\n v-bind=\"attrs\"\n data-gr-dropdown-menu-item\n :role=\"role\"\n :class=\"className\"\n :type=\"isNativeButton ? (attrs.type as any) ?? 'button' : undefined\"\n :href=\"resolvedHref\"\n :target=\"resolvedHref ? resolvedTarget : undefined\"\n :rel=\"resolvedHref ? resolvedRel : undefined\"\n :aria-disabled=\"disabled ? 'true' : undefined\"\n :aria-checked=\"isCheckable ? (checked ? 'true' : 'false') : undefined\"\n :tabindex=\"resolvedTabindex\"\n @click.capture=\"onClickCapture\"\n >\n <span\n v-if=\"isCheckable\"\n data-gr-dropdown-menu-item-indicator\n :class=\"itemIndicatorClass\"\n aria-hidden=\"true\"\n >\n <IconCheck v-if=\"checked\" :class=\"itemIndicatorClass\" />\n </span>\n\n <slot name=\"icon\">\n <component\n :is=\"icon\"\n v-if=\"icon\"\n :class=\"itemIndicatorClass\"\n aria-hidden=\"true\"\n />\n </slot>\n\n <slot />\n\n <slot name=\"shortcut\">\n <span v-if=\"shortcut\" data-gr-dropdown-menu-item-shortcut :class=\"itemShortcutClass\">{{ shortcut }}</span>\n </slot>\n </component>\n</template>\n","import type { Component } from 'vue'\n\nimport type { GrDropdownMenuItemAlign, GrDropdownMenuItemRole } from './GrDropdownMenuItem.vue'\nimport type { GrDropdownMenuHeaderAlign, GrDropdownMenuItemVariant } from './grDropdownMenuStyles'\n\n/**\n * Декларативная модель меню.\n *\n * Композиция из подкомпонентов остаётся основным способом — она нужна там, где\n * пункт нестандартный. Но девять меню из десяти однотипны («иконка, подпись,\n * шорткат, иногда разделитель»), и собирать их из пяти компонентов вручную\n * значит каждый раз заново решать, где `role`, где `disabled`, где ключ.\n */\nexport interface GrDropdownMenuAction {\n /** Ключ пункта — он же приходит в `select`. */\n key: string\n label: string\n icon?: Component\n shortcut?: string\n disabled?: boolean\n variant?: GrDropdownMenuItemVariant\n role?: GrDropdownMenuItemRole\n /** Состояние переключателя для `menuitemcheckbox`/`menuitemradio`. */\n checked?: boolean\n /** Пункт-ссылка: рендерится как `<a>` с этим `href`. */\n href?: string\n target?: string\n rel?: string\n /** Шорткат для `target=\"_blank\"` + `rel=\"noopener noreferrer\"`. */\n external?: boolean\n /**\n * Чем рендерить пункт: тег или компонент роутера.\n *\n * Без него пункт-ссылка из `items` остаётся обычным `<a>`, то есть в\n * SPA переход идёт перезагрузкой страницы — а обойти это в модели нечем:\n * `itemProps` внутренняя, слота на пункт нет. Проп есть у самого\n * `GrDropdownMenuItem` и у соседей по кольцу (`GrLink`, `GrBreadcrumbs`,\n * `GrSidebarItem`), из этого ряда выпадала только модель меню.\n */\n as?: string | Component\n /** Выравнивание содержимого пункта. */\n align?: GrDropdownMenuItemAlign\n}\n\nexport interface GrDropdownMenuSeparator {\n type: 'divider'\n inset?: boolean\n}\n\nexport interface GrDropdownMenuSection {\n type: 'group'\n title?: string\n /** Выравнивание заголовка группы. */\n titleAlign?: GrDropdownMenuHeaderAlign\n /** Разделители между пунктами группы. */\n dividers?: boolean\n /** Заголовок капсом. */\n uppercase?: boolean\n items: GrDropdownMenuAction[]\n}\n\nexport type GrDropdownMenuEntry = GrDropdownMenuAction | GrDropdownMenuSeparator | GrDropdownMenuSection\n\nexport function isMenuSeparator(entry: GrDropdownMenuEntry): entry is GrDropdownMenuSeparator {\n return 'type' in entry && entry.type === 'divider'\n}\n\nexport function isMenuSection(entry: GrDropdownMenuEntry): entry is GrDropdownMenuSection {\n return 'type' in entry && entry.type === 'group'\n}\n\nexport function isMenuAction(entry: GrDropdownMenuEntry): entry is GrDropdownMenuAction {\n return !isMenuSeparator(entry) && !isMenuSection(entry)\n}\n","<script setup lang=\"ts\">\n/**\n * Рендер декларативной модели меню — без обёртки списка: её ставит потребитель,\n * потому что `dividers`/`borderTop` принадлежат конкретному меню, а не модели.\n *\n * Вынесено из `GrDropdownMenu` ради `GrContextMenu`: модель у них общая, и\n * вторая копия цикла разошлась бы с первой при первом же новом поле пункта.\n */\nimport GrDropdownMenuDivider from './GrDropdownMenuDivider.vue'\nimport GrDropdownMenuGroup from './GrDropdownMenuGroup.vue'\nimport GrDropdownMenuItem from './GrDropdownMenuItem.vue'\nimport type { GrDropdownMenuAction, GrDropdownMenuEntry } from './menuModel'\nimport { isMenuAction, isMenuSection, isMenuSeparator } from './menuModel'\n\nexport interface GrDropdownMenuEntriesProps {\n items?: GrDropdownMenuEntry[]\n}\n\nexport interface GrDropdownMenuEntriesEmits {\n (e: 'select', item: GrDropdownMenuAction): void\n}\n\ndefineProps<GrDropdownMenuEntriesProps>()\n\nconst emit = defineEmits<GrDropdownMenuEntriesEmits>()\n\nfunction itemProps(item: GrDropdownMenuAction): Record<string, unknown> {\n return {\n href: item.href,\n target: item.target,\n rel: item.rel,\n external: item.external,\n disabled: item.disabled,\n variant: item.variant,\n role: item.role,\n checked: item.checked,\n icon: item.icon,\n shortcut: item.shortcut,\n as: item.as,\n align: item.align,\n }\n}\n\nfunction onSelect(item: GrDropdownMenuAction): void {\n if (item.disabled)\n return\n\n emit('select', item)\n}\n</script>\n\n<template>\n <template v-for=\"(entry, index) in items ?? []\">\n <GrDropdownMenuDivider\n v-if=\"isMenuSeparator(entry)\"\n :key=\"`divider-${index}`\"\n :inset=\"entry.inset\"\n />\n\n <GrDropdownMenuGroup\n v-else-if=\"isMenuSection(entry)\"\n :key=\"`group-${entry.title ?? index}`\"\n :title=\"entry.title\"\n :title-align=\"entry.titleAlign\"\n :dividers=\"entry.dividers\"\n :uppercase=\"entry.uppercase\"\n >\n <GrDropdownMenuItem\n v-for=\"item in entry.items\"\n :key=\"item.key\"\n v-bind=\"itemProps(item)\"\n @click=\"onSelect(item)\"\n >\n {{ item.label }}\n </GrDropdownMenuItem>\n </GrDropdownMenuGroup>\n\n <GrDropdownMenuItem\n v-else-if=\"isMenuAction(entry)\"\n :key=\"entry.key\"\n v-bind=\"itemProps(entry)\"\n @click=\"onSelect(entry)\"\n >\n {{ entry.label }}\n </GrDropdownMenuItem>\n </template>\n</template>\n","<script setup lang=\"ts\">\n/**\n * Рендер декларативной модели меню — без обёртки списка: её ставит потребитель,\n * потому что `dividers`/`borderTop` принадлежат конкретному меню, а не модели.\n *\n * Вынесено из `GrDropdownMenu` ради `GrContextMenu`: модель у них общая, и\n * вторая копия цикла разошлась бы с первой при первом же новом поле пункта.\n */\nimport GrDropdownMenuDivider from './GrDropdownMenuDivider.vue'\nimport GrDropdownMenuGroup from './GrDropdownMenuGroup.vue'\nimport GrDropdownMenuItem from './GrDropdownMenuItem.vue'\nimport type { GrDropdownMenuAction, GrDropdownMenuEntry } from './menuModel'\nimport { isMenuAction, isMenuSection, isMenuSeparator } from './menuModel'\n\nexport interface GrDropdownMenuEntriesProps {\n items?: GrDropdownMenuEntry[]\n}\n\nexport interface GrDropdownMenuEntriesEmits {\n (e: 'select', item: GrDropdownMenuAction): void\n}\n\ndefineProps<GrDropdownMenuEntriesProps>()\n\nconst emit = defineEmits<GrDropdownMenuEntriesEmits>()\n\nfunction itemProps(item: GrDropdownMenuAction): Record<string, unknown> {\n return {\n href: item.href,\n target: item.target,\n rel: item.rel,\n external: item.external,\n disabled: item.disabled,\n variant: item.variant,\n role: item.role,\n checked: item.checked,\n icon: item.icon,\n shortcut: item.shortcut,\n as: item.as,\n align: item.align,\n }\n}\n\nfunction onSelect(item: GrDropdownMenuAction): void {\n if (item.disabled)\n return\n\n emit('select', item)\n}\n</script>\n\n<template>\n <template v-for=\"(entry, index) in items ?? []\">\n <GrDropdownMenuDivider\n v-if=\"isMenuSeparator(entry)\"\n :key=\"`divider-${index}`\"\n :inset=\"entry.inset\"\n />\n\n <GrDropdownMenuGroup\n v-else-if=\"isMenuSection(entry)\"\n :key=\"`group-${entry.title ?? index}`\"\n :title=\"entry.title\"\n :title-align=\"entry.titleAlign\"\n :dividers=\"entry.dividers\"\n :uppercase=\"entry.uppercase\"\n >\n <GrDropdownMenuItem\n v-for=\"item in entry.items\"\n :key=\"item.key\"\n v-bind=\"itemProps(item)\"\n @click=\"onSelect(item)\"\n >\n {{ item.label }}\n </GrDropdownMenuItem>\n </GrDropdownMenuGroup>\n\n <GrDropdownMenuItem\n v-else-if=\"isMenuAction(entry)\"\n :key=\"entry.key\"\n v-bind=\"itemProps(entry)\"\n @click=\"onSelect(entry)\"\n >\n {{ entry.label }}\n </GrDropdownMenuItem>\n </template>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport { grDropdownMenuListClass } from './grDropdownMenuStyles'\n\n/**\n * `role=\"none\"` на обёртке обязателен: `role=\"menu\"` у панели объявляет своих\n * потомков презентационными, и любой div между панелью и пунктом ломает\n * `aria-required-children`, а пункты теряют принадлежность к меню.\n */\n\nexport interface GrDropdownMenuListProps {\n dividers?: boolean\n borderTop?: boolean\n borderBottom?: boolean\n}\n\nconst props = withDefaults(defineProps<GrDropdownMenuListProps>(), {\n dividers: false,\n borderTop: false,\n borderBottom: false,\n})\n\nconst className = computed(() => grDropdownMenuListClass({\n dividers: props.dividers,\n borderTop: props.borderTop,\n borderBottom: props.borderBottom,\n}))\n\ndefineSlots<{\n /** Пункты списка меню. */\n default?: () => any\n}>()\n</script>\n\n<template>\n <div\n data-gr-dropdown-menu-list\n role=\"none\"\n :class=\"className\"\n >\n <slot />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport { grDropdownMenuListClass } from './grDropdownMenuStyles'\n\n/**\n * `role=\"none\"` на обёртке обязателен: `role=\"menu\"` у панели объявляет своих\n * потомков презентационными, и любой div между панелью и пунктом ломает\n * `aria-required-children`, а пункты теряют принадлежность к меню.\n */\n\nexport interface GrDropdownMenuListProps {\n dividers?: boolean\n borderTop?: boolean\n borderBottom?: boolean\n}\n\nconst props = withDefaults(defineProps<GrDropdownMenuListProps>(), {\n dividers: false,\n borderTop: false,\n borderBottom: false,\n})\n\nconst className = computed(() => grDropdownMenuListClass({\n dividers: props.dividers,\n borderTop: props.borderTop,\n borderBottom: props.borderBottom,\n}))\n\ndefineSlots<{\n /** Пункты списка меню. */\n default?: () => any\n}>()\n</script>\n\n<template>\n <div\n data-gr-dropdown-menu-list\n role=\"none\"\n :class=\"className\"\n >\n <slot />\n </div>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"GrDropdownMenuList-B33ZzwfB.js","names":[],"sources":["../../../../src/components/GrDropdownMenu/GrDropdownMenuDivider.vue","../../../../src/components/GrDropdownMenu/GrDropdownMenuDivider.vue","../../../../src/components/GrDropdownMenu/GrDropdownMenuHeader.vue","../../../../src/components/GrDropdownMenu/GrDropdownMenuHeader.vue","../../../../src/components/GrDropdownMenu/GrDropdownMenuGroup.vue","../../../../src/components/GrDropdownMenu/GrDropdownMenuGroup.vue","../../../../src/components/GrDropdownMenu/GrDropdownMenuItem.vue","../../../../src/components/GrDropdownMenu/GrDropdownMenuItem.vue","../../../../src/components/GrDropdownMenu/menuModel.ts","../../../../src/components/GrDropdownMenu/GrDropdownMenuEntries.vue","../../../../src/components/GrDropdownMenu/GrDropdownMenuEntries.vue","../../../../src/components/GrDropdownMenu/GrDropdownMenuList.vue","../../../../src/components/GrDropdownMenu/GrDropdownMenuList.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { dividerClass, dividerInsetClass } from './grDropdownMenuStyles'\n\nexport interface GrDropdownMenuDividerProps {\n inset?: boolean\n}\n\nwithDefaults(defineProps<GrDropdownMenuDividerProps>(), {\n inset: false,\n})\n</script>\n\n<template>\n <div\n data-gr-dropdown-menu-divider\n role=\"separator\"\n :class=\"[dividerClass, inset ? dividerInsetClass : '']\"\n />\n</template>\n","<script setup lang=\"ts\">\nimport { dividerClass, dividerInsetClass } from './grDropdownMenuStyles'\n\nexport interface GrDropdownMenuDividerProps {\n inset?: boolean\n}\n\nwithDefaults(defineProps<GrDropdownMenuDividerProps>(), {\n inset: false,\n})\n</script>\n\n<template>\n <div\n data-gr-dropdown-menu-divider\n role=\"separator\"\n :class=\"[dividerClass, inset ? dividerInsetClass : '']\"\n />\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useSlots } from 'vue'\n\nimport { headerClass, textAlignClass, type GrDropdownMenuHeaderAlign } from './grDropdownMenuStyles'\n\nexport type { GrDropdownMenuHeaderAlign } from './grDropdownMenuStyles'\n\nexport interface GrDropdownMenuHeaderProps {\n title?: string\n align?: GrDropdownMenuHeaderAlign\n uppercase?: boolean\n}\n\nconst props = withDefaults(defineProps<GrDropdownMenuHeaderProps>(), {\n title: undefined,\n align: 'left',\n uppercase: true,\n})\n\n/**\n * Заголовок — подпись, а не пункт меню: `role=\"presentation\"` убирает его из\n * числа потомков `role=\"menu\"`. Имя группе он даёт через `aria-labelledby`\n * у `GrDropdownMenuGroup`.\n */\nconst slots = useSlots()\nconst isVisible = computed(() => Boolean(props.title) || Boolean(slots.default))\n\ndefineSlots<{\n /** Заголовок раздела меню вместо пропа `label`. */\n default?: () => any\n}>()\n</script>\n\n<template>\n <div\n v-if=\"isVisible\"\n data-gr-dropdown-menu-header\n role=\"presentation\"\n :class=\"[headerClass, textAlignClass[align], { uppercase }]\"\n >\n <slot>{{ title }}</slot>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useSlots } from 'vue'\n\nimport { headerClass, textAlignClass, type GrDropdownMenuHeaderAlign } from './grDropdownMenuStyles'\n\nexport type { GrDropdownMenuHeaderAlign } from './grDropdownMenuStyles'\n\nexport interface GrDropdownMenuHeaderProps {\n title?: string\n align?: GrDropdownMenuHeaderAlign\n uppercase?: boolean\n}\n\nconst props = withDefaults(defineProps<GrDropdownMenuHeaderProps>(), {\n title: undefined,\n align: 'left',\n uppercase: true,\n})\n\n/**\n * Заголовок — подпись, а не пункт меню: `role=\"presentation\"` убирает его из\n * числа потомков `role=\"menu\"`. Имя группе он даёт через `aria-labelledby`\n * у `GrDropdownMenuGroup`.\n */\nconst slots = useSlots()\nconst isVisible = computed(() => Boolean(props.title) || Boolean(slots.default))\n\ndefineSlots<{\n /** Заголовок раздела меню вместо пропа `label`. */\n default?: () => any\n}>()\n</script>\n\n<template>\n <div\n v-if=\"isVisible\"\n data-gr-dropdown-menu-header\n role=\"presentation\"\n :class=\"[headerClass, textAlignClass[align], { uppercase }]\"\n >\n <slot>{{ title }}</slot>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useId } from 'vue'\n\nimport GrDropdownMenuHeader from './GrDropdownMenuHeader.vue'\nimport { dividersClass, listBaseClass, type GrDropdownMenuHeaderAlign } from './grDropdownMenuStyles'\n\nexport interface GrDropdownMenuGroupProps {\n title?: string\n titleAlign?: GrDropdownMenuHeaderAlign\n dividers?: boolean\n uppercase?: boolean\n}\n\nconst props = withDefaults(defineProps<GrDropdownMenuGroupProps>(), {\n title: undefined,\n titleAlign: 'left',\n dividers: false,\n uppercase: true,\n})\n\nconst titleId = useId()\n// Имя группы читается диктором при входе в неё; без заголовка называть нечем.\nconst labelledBy = computed(() => (props.title ? titleId : undefined))\n\nconst itemsClass = computed(() => [\n listBaseClass,\n props.dividers ? dividersClass : '',\n].filter(Boolean).join(' '))\n\ndefineSlots<{\n /** Пункты группы. */\n default?: () => any\n}>()\n</script>\n\n<template>\n <div\n data-gr-dropdown-menu-group\n role=\"group\"\n :aria-labelledby=\"labelledBy\"\n class=\"w-full\"\n >\n <GrDropdownMenuHeader\n v-if=\"title\"\n :id=\"titleId\"\n :title=\"title\"\n :align=\"titleAlign\"\n :uppercase=\"uppercase\"\n />\n <div role=\"none\" :class=\"itemsClass\">\n <slot />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useId } from 'vue'\n\nimport GrDropdownMenuHeader from './GrDropdownMenuHeader.vue'\nimport { dividersClass, listBaseClass, type GrDropdownMenuHeaderAlign } from './grDropdownMenuStyles'\n\nexport interface GrDropdownMenuGroupProps {\n title?: string\n titleAlign?: GrDropdownMenuHeaderAlign\n dividers?: boolean\n uppercase?: boolean\n}\n\nconst props = withDefaults(defineProps<GrDropdownMenuGroupProps>(), {\n title: undefined,\n titleAlign: 'left',\n dividers: false,\n uppercase: true,\n})\n\nconst titleId = useId()\n// Имя группы читается диктором при входе в неё; без заголовка называть нечем.\nconst labelledBy = computed(() => (props.title ? titleId : undefined))\n\nconst itemsClass = computed(() => [\n listBaseClass,\n props.dividers ? dividersClass : '',\n].filter(Boolean).join(' '))\n\ndefineSlots<{\n /** Пункты группы. */\n default?: () => any\n}>()\n</script>\n\n<template>\n <div\n data-gr-dropdown-menu-group\n role=\"group\"\n :aria-labelledby=\"labelledBy\"\n class=\"w-full\"\n >\n <GrDropdownMenuHeader\n v-if=\"title\"\n :id=\"titleId\"\n :title=\"title\"\n :align=\"titleAlign\"\n :uppercase=\"uppercase\"\n />\n <div role=\"none\" :class=\"itemsClass\">\n <slot />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue'\nimport type { Component } from 'vue'\n\nimport IconCheck from '~icons/lucide/check'\n\nimport {\n grDropdownMenuItemClass,\n itemIndicatorClass,\n itemShortcutClass,\n type GrDropdownMenuItemAlign,\n type GrDropdownMenuItemVariant,\n} from './grDropdownMenuStyles'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nexport type { GrDropdownMenuItemAlign, GrDropdownMenuItemVariant } from './grDropdownMenuStyles'\n\n/**\n * Роль пункта. `menuitemcheckbox`/`menuitemradio` — пункты-переключатели: они\n * обязаны нести `aria-checked`, иначе AT прочитает их как обычные команды.\n */\nexport type GrDropdownMenuItemRole = 'menuitem' | 'menuitemcheckbox' | 'menuitemradio'\n\nexport interface GrDropdownMenuItemProps {\n as?: string | Component\n disabled?: boolean\n /** Пункт-ссылка. У выключенного пункта не рендерится: ссылка осталась бы рабочей. */\n href?: string\n target?: string\n rel?: string\n /** Шорткат для `target=\"_blank\"` + `rel=\"noopener noreferrer\"`. */\n external?: boolean\n align?: GrDropdownMenuItemAlign\n variant?: GrDropdownMenuItemVariant\n role?: GrDropdownMenuItemRole\n /** Состояние переключателя. Осмысленно с `role=\"menuitemcheckbox|radio\"`. */\n checked?: boolean\n /** Иконка слева. Слот `#icon` сильнее. */\n icon?: Component\n /** Подпись сочетания клавиш справа. Слот `#shortcut` сильнее. */\n shortcut?: string\n}\n\nconst props = withDefaults(defineProps<GrDropdownMenuItemProps>(), {\n as: 'button',\n disabled: false,\n href: undefined,\n target: undefined,\n rel: undefined,\n external: false,\n align: 'left',\n variant: 'default',\n role: 'menuitem',\n checked: undefined,\n icon: undefined,\n shortcut: undefined,\n})\n\nconst attrs = useAttrs()\n\n// Полиморфный корень: явный `as` сильнее всего, иначе `href` сам делает пункт\n// ссылкой — как у `GrButton`, чтобы не приходилось задавать `as=\"a\"` вручную.\nconst renderAs = computed<string | Component>(() => {\n if (props.as && props.as !== 'button')\n return props.as\n return props.href ? 'a' : 'button'\n})\n\nconst isNativeButton = computed(() => renderAs.value === 'button')\n\n// Выключенный пункт остаётся ссылкой, если оставить ему `href`: средняя кнопка и\n// контекстное меню браузера обойдут любой перехват клика (тот же приём в `GrButton`).\nconst resolvedHref = computed(() => (props.disabled ? undefined : props.href))\nconst resolvedTarget = computed(() => props.target ?? (props.external ? '_blank' : undefined))\nconst resolvedRel = computed(() =>\n props.rel ?? (resolvedTarget.value === '_blank' ? 'noopener noreferrer' : undefined),\n)\n// Отметка занимает место всегда, когда пункт переключаемый: иначе строки\n// «включено» и «выключено» разъезжаются по горизонтали.\nconst isCheckable = computed(() => props.role !== 'menuitem')\n\nconst className = computed(() => grDropdownMenuItemClass({\n align: props.align,\n variant: props.variant,\n disabled: props.disabled,\n}))\n\n/**\n * Roving tabindex паттерна menu: табируемым остаётся триггер, а внутри панели\n * фокусом распоряжаются стрелки (`GrDropdown` наводит его программно). Без\n * этого `Tab` ходил бы по пунктам, и меню было бы списком кнопок, а не меню.\n *\n * Выключённый пункт из обхода **не** выпадает: `aria-disabled` вместо нативного\n * `disabled` оставляет его фокусируемым, и пользователь узнаёт, что действие\n * существует, но сейчас недоступно (рекомендация WAI-ARIA APG).\n */\nconst resolvedTabindex = computed(() => (attrs.tabindex as number | string | undefined) ?? -1)\n\nfunction onClickCapture(e: MouseEvent): void {\n if (!props.disabled)\n return\n\n e.preventDefault()\n // `stopImmediatePropagation`, а не `stopPropagation`: обработчик, навешенный\n // на сам пункт через `v-bind=\"attrs\"`, живёт на этом же элементе, и обычная\n // остановка всплытия его не отменяет.\n e.stopImmediatePropagation()\n}\n\ndefineSlots<{\n /** Подпись пункта вместо пропа `label`. */\n default?: () => any\n /** Иконка перед подписью. */\n icon?: () => any\n /** Сочетание клавиш справа — обычно `GrKbd`. */\n shortcut?: () => any\n}>()\n</script>\n\n<template>\n <component\n :is=\"renderAs\"\n v-bind=\"attrs\"\n data-gr-dropdown-menu-item\n :role=\"role\"\n :class=\"className\"\n :type=\"isNativeButton ? (attrs.type as any) ?? 'button' : undefined\"\n :href=\"resolvedHref\"\n :target=\"resolvedHref ? resolvedTarget : undefined\"\n :rel=\"resolvedHref ? resolvedRel : undefined\"\n :aria-disabled=\"disabled ? 'true' : undefined\"\n :aria-checked=\"isCheckable ? (checked ? 'true' : 'false') : undefined\"\n :tabindex=\"resolvedTabindex\"\n @click.capture=\"onClickCapture\"\n >\n <span\n v-if=\"isCheckable\"\n data-gr-dropdown-menu-item-indicator\n :class=\"itemIndicatorClass\"\n aria-hidden=\"true\"\n >\n <IconCheck v-if=\"checked\" :class=\"itemIndicatorClass\" />\n </span>\n\n <slot name=\"icon\">\n <component\n :is=\"icon\"\n v-if=\"icon\"\n :class=\"itemIndicatorClass\"\n aria-hidden=\"true\"\n />\n </slot>\n\n <slot />\n\n <slot name=\"shortcut\">\n <span v-if=\"shortcut\" data-gr-dropdown-menu-item-shortcut :class=\"itemShortcutClass\">{{ shortcut }}</span>\n </slot>\n </component>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue'\nimport type { Component } from 'vue'\n\nimport IconCheck from '~icons/lucide/check'\n\nimport {\n grDropdownMenuItemClass,\n itemIndicatorClass,\n itemShortcutClass,\n type GrDropdownMenuItemAlign,\n type GrDropdownMenuItemVariant,\n} from './grDropdownMenuStyles'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nexport type { GrDropdownMenuItemAlign, GrDropdownMenuItemVariant } from './grDropdownMenuStyles'\n\n/**\n * Роль пункта. `menuitemcheckbox`/`menuitemradio` — пункты-переключатели: они\n * обязаны нести `aria-checked`, иначе AT прочитает их как обычные команды.\n */\nexport type GrDropdownMenuItemRole = 'menuitem' | 'menuitemcheckbox' | 'menuitemradio'\n\nexport interface GrDropdownMenuItemProps {\n as?: string | Component\n disabled?: boolean\n /** Пункт-ссылка. У выключенного пункта не рендерится: ссылка осталась бы рабочей. */\n href?: string\n target?: string\n rel?: string\n /** Шорткат для `target=\"_blank\"` + `rel=\"noopener noreferrer\"`. */\n external?: boolean\n align?: GrDropdownMenuItemAlign\n variant?: GrDropdownMenuItemVariant\n role?: GrDropdownMenuItemRole\n /** Состояние переключателя. Осмысленно с `role=\"menuitemcheckbox|radio\"`. */\n checked?: boolean\n /** Иконка слева. Слот `#icon` сильнее. */\n icon?: Component\n /** Подпись сочетания клавиш справа. Слот `#shortcut` сильнее. */\n shortcut?: string\n}\n\nconst props = withDefaults(defineProps<GrDropdownMenuItemProps>(), {\n as: 'button',\n disabled: false,\n href: undefined,\n target: undefined,\n rel: undefined,\n external: false,\n align: 'left',\n variant: 'default',\n role: 'menuitem',\n checked: undefined,\n icon: undefined,\n shortcut: undefined,\n})\n\nconst attrs = useAttrs()\n\n// Полиморфный корень: явный `as` сильнее всего, иначе `href` сам делает пункт\n// ссылкой — как у `GrButton`, чтобы не приходилось задавать `as=\"a\"` вручную.\nconst renderAs = computed<string | Component>(() => {\n if (props.as && props.as !== 'button')\n return props.as\n return props.href ? 'a' : 'button'\n})\n\nconst isNativeButton = computed(() => renderAs.value === 'button')\n\n// Выключенный пункт остаётся ссылкой, если оставить ему `href`: средняя кнопка и\n// контекстное меню браузера обойдут любой перехват клика (тот же приём в `GrButton`).\nconst resolvedHref = computed(() => (props.disabled ? undefined : props.href))\nconst resolvedTarget = computed(() => props.target ?? (props.external ? '_blank' : undefined))\nconst resolvedRel = computed(() =>\n props.rel ?? (resolvedTarget.value === '_blank' ? 'noopener noreferrer' : undefined),\n)\n// Отметка занимает место всегда, когда пункт переключаемый: иначе строки\n// «включено» и «выключено» разъезжаются по горизонтали.\nconst isCheckable = computed(() => props.role !== 'menuitem')\n\nconst className = computed(() => grDropdownMenuItemClass({\n align: props.align,\n variant: props.variant,\n disabled: props.disabled,\n}))\n\n/**\n * Roving tabindex паттерна menu: табируемым остаётся триггер, а внутри панели\n * фокусом распоряжаются стрелки (`GrDropdown` наводит его программно). Без\n * этого `Tab` ходил бы по пунктам, и меню было бы списком кнопок, а не меню.\n *\n * Выключённый пункт из обхода **не** выпадает: `aria-disabled` вместо нативного\n * `disabled` оставляет его фокусируемым, и пользователь узнаёт, что действие\n * существует, но сейчас недоступно (рекомендация WAI-ARIA APG).\n */\nconst resolvedTabindex = computed(() => (attrs.tabindex as number | string | undefined) ?? -1)\n\nfunction onClickCapture(e: MouseEvent): void {\n if (!props.disabled)\n return\n\n e.preventDefault()\n // `stopImmediatePropagation`, а не `stopPropagation`: обработчик, навешенный\n // на сам пункт через `v-bind=\"attrs\"`, живёт на этом же элементе, и обычная\n // остановка всплытия его не отменяет.\n e.stopImmediatePropagation()\n}\n\ndefineSlots<{\n /** Подпись пункта вместо пропа `label`. */\n default?: () => any\n /** Иконка перед подписью. */\n icon?: () => any\n /** Сочетание клавиш справа — обычно `GrKbd`. */\n shortcut?: () => any\n}>()\n</script>\n\n<template>\n <component\n :is=\"renderAs\"\n v-bind=\"attrs\"\n data-gr-dropdown-menu-item\n :role=\"role\"\n :class=\"className\"\n :type=\"isNativeButton ? (attrs.type as any) ?? 'button' : undefined\"\n :href=\"resolvedHref\"\n :target=\"resolvedHref ? resolvedTarget : undefined\"\n :rel=\"resolvedHref ? resolvedRel : undefined\"\n :aria-disabled=\"disabled ? 'true' : undefined\"\n :aria-checked=\"isCheckable ? (checked ? 'true' : 'false') : undefined\"\n :tabindex=\"resolvedTabindex\"\n @click.capture=\"onClickCapture\"\n >\n <span\n v-if=\"isCheckable\"\n data-gr-dropdown-menu-item-indicator\n :class=\"itemIndicatorClass\"\n aria-hidden=\"true\"\n >\n <IconCheck v-if=\"checked\" :class=\"itemIndicatorClass\" />\n </span>\n\n <slot name=\"icon\">\n <component\n :is=\"icon\"\n v-if=\"icon\"\n :class=\"itemIndicatorClass\"\n aria-hidden=\"true\"\n />\n </slot>\n\n <slot />\n\n <slot name=\"shortcut\">\n <span v-if=\"shortcut\" data-gr-dropdown-menu-item-shortcut :class=\"itemShortcutClass\">{{ shortcut }}</span>\n </slot>\n </component>\n</template>\n","import type { Component } from 'vue'\n\nimport type { GrDropdownMenuItemAlign, GrDropdownMenuItemRole } from './GrDropdownMenuItem.vue'\nimport type { GrDropdownMenuHeaderAlign, GrDropdownMenuItemVariant } from './grDropdownMenuStyles'\n\n/**\n * Декларативная модель меню.\n *\n * Композиция из подкомпонентов остаётся основным способом — она нужна там, где\n * пункт нестандартный. Но девять меню из десяти однотипны («иконка, подпись,\n * шорткат, иногда разделитель»), и собирать их из пяти компонентов вручную\n * значит каждый раз заново решать, где `role`, где `disabled`, где ключ.\n */\nexport interface GrDropdownMenuAction {\n /** Ключ пункта — он же приходит в `select`. */\n key: string\n label: string\n icon?: Component\n shortcut?: string\n disabled?: boolean\n variant?: GrDropdownMenuItemVariant\n role?: GrDropdownMenuItemRole\n /** Состояние переключателя для `menuitemcheckbox`/`menuitemradio`. */\n checked?: boolean\n /** Пункт-ссылка: рендерится как `<a>` с этим `href`. */\n href?: string\n target?: string\n rel?: string\n /** Шорткат для `target=\"_blank\"` + `rel=\"noopener noreferrer\"`. */\n external?: boolean\n /**\n * Чем рендерить пункт: тег или компонент роутера.\n *\n * Без него пункт-ссылка из `items` остаётся обычным `<a>`, то есть в\n * SPA переход идёт перезагрузкой страницы — а обойти это в модели нечем:\n * `itemProps` внутренняя, слота на пункт нет. Проп есть у самого\n * `GrDropdownMenuItem` и у соседей по кольцу (`GrLink`, `GrBreadcrumbs`,\n * `GrSidebarItem`), из этого ряда выпадала только модель меню.\n */\n as?: string | Component\n /** Выравнивание содержимого пункта. */\n align?: GrDropdownMenuItemAlign\n}\n\nexport interface GrDropdownMenuSeparator {\n type: 'divider'\n inset?: boolean\n}\n\nexport interface GrDropdownMenuSection {\n type: 'group'\n title?: string\n /** Выравнивание заголовка группы. */\n titleAlign?: GrDropdownMenuHeaderAlign\n /** Разделители между пунктами группы. */\n dividers?: boolean\n /** Заголовок капсом. */\n uppercase?: boolean\n items: GrDropdownMenuAction[]\n}\n\nexport type GrDropdownMenuEntry = GrDropdownMenuAction | GrDropdownMenuSeparator | GrDropdownMenuSection\n\nexport function isMenuSeparator(entry: GrDropdownMenuEntry): entry is GrDropdownMenuSeparator {\n return 'type' in entry && entry.type === 'divider'\n}\n\nexport function isMenuSection(entry: GrDropdownMenuEntry): entry is GrDropdownMenuSection {\n return 'type' in entry && entry.type === 'group'\n}\n\nexport function isMenuAction(entry: GrDropdownMenuEntry): entry is GrDropdownMenuAction {\n return !isMenuSeparator(entry) && !isMenuSection(entry)\n}\n","<script setup lang=\"ts\">\n/**\n * Рендер декларативной модели меню — без обёртки списка: её ставит потребитель,\n * потому что `dividers`/`borderTop` принадлежат конкретному меню, а не модели.\n *\n * Вынесено из `GrDropdownMenu` ради `GrContextMenu`: модель у них общая, и\n * вторая копия цикла разошлась бы с первой при первом же новом поле пункта.\n */\nimport GrDropdownMenuDivider from './GrDropdownMenuDivider.vue'\nimport GrDropdownMenuGroup from './GrDropdownMenuGroup.vue'\nimport GrDropdownMenuItem from './GrDropdownMenuItem.vue'\nimport type { GrDropdownMenuAction, GrDropdownMenuEntry } from './menuModel'\nimport { isMenuAction, isMenuSection, isMenuSeparator } from './menuModel'\n\nexport interface GrDropdownMenuEntriesProps {\n items?: GrDropdownMenuEntry[]\n}\n\nexport interface GrDropdownMenuEntriesEmits {\n (e: 'select', item: GrDropdownMenuAction): void\n}\n\ndefineProps<GrDropdownMenuEntriesProps>()\n\nconst emit = defineEmits<GrDropdownMenuEntriesEmits>()\n\nfunction itemProps(item: GrDropdownMenuAction): Record<string, unknown> {\n return {\n href: item.href,\n target: item.target,\n rel: item.rel,\n external: item.external,\n disabled: item.disabled,\n variant: item.variant,\n role: item.role,\n checked: item.checked,\n icon: item.icon,\n shortcut: item.shortcut,\n as: item.as,\n align: item.align,\n }\n}\n\nfunction onSelect(item: GrDropdownMenuAction): void {\n if (item.disabled)\n return\n\n emit('select', item)\n}\n</script>\n\n<template>\n <template v-for=\"(entry, index) in items ?? []\">\n <GrDropdownMenuDivider\n v-if=\"isMenuSeparator(entry)\"\n :key=\"`divider-${index}`\"\n :inset=\"entry.inset\"\n />\n\n <GrDropdownMenuGroup\n v-else-if=\"isMenuSection(entry)\"\n :key=\"`group-${entry.title ?? index}`\"\n :title=\"entry.title\"\n :title-align=\"entry.titleAlign\"\n :dividers=\"entry.dividers\"\n :uppercase=\"entry.uppercase\"\n >\n <GrDropdownMenuItem\n v-for=\"item in entry.items\"\n :key=\"item.key\"\n v-bind=\"itemProps(item)\"\n @click=\"onSelect(item)\"\n >\n {{ item.label }}\n </GrDropdownMenuItem>\n </GrDropdownMenuGroup>\n\n <GrDropdownMenuItem\n v-else-if=\"isMenuAction(entry)\"\n :key=\"entry.key\"\n v-bind=\"itemProps(entry)\"\n @click=\"onSelect(entry)\"\n >\n {{ entry.label }}\n </GrDropdownMenuItem>\n </template>\n</template>\n","<script setup lang=\"ts\">\n/**\n * Рендер декларативной модели меню — без обёртки списка: её ставит потребитель,\n * потому что `dividers`/`borderTop` принадлежат конкретному меню, а не модели.\n *\n * Вынесено из `GrDropdownMenu` ради `GrContextMenu`: модель у них общая, и\n * вторая копия цикла разошлась бы с первой при первом же новом поле пункта.\n */\nimport GrDropdownMenuDivider from './GrDropdownMenuDivider.vue'\nimport GrDropdownMenuGroup from './GrDropdownMenuGroup.vue'\nimport GrDropdownMenuItem from './GrDropdownMenuItem.vue'\nimport type { GrDropdownMenuAction, GrDropdownMenuEntry } from './menuModel'\nimport { isMenuAction, isMenuSection, isMenuSeparator } from './menuModel'\n\nexport interface GrDropdownMenuEntriesProps {\n items?: GrDropdownMenuEntry[]\n}\n\nexport interface GrDropdownMenuEntriesEmits {\n (e: 'select', item: GrDropdownMenuAction): void\n}\n\ndefineProps<GrDropdownMenuEntriesProps>()\n\nconst emit = defineEmits<GrDropdownMenuEntriesEmits>()\n\nfunction itemProps(item: GrDropdownMenuAction): Record<string, unknown> {\n return {\n href: item.href,\n target: item.target,\n rel: item.rel,\n external: item.external,\n disabled: item.disabled,\n variant: item.variant,\n role: item.role,\n checked: item.checked,\n icon: item.icon,\n shortcut: item.shortcut,\n as: item.as,\n align: item.align,\n }\n}\n\nfunction onSelect(item: GrDropdownMenuAction): void {\n if (item.disabled)\n return\n\n emit('select', item)\n}\n</script>\n\n<template>\n <template v-for=\"(entry, index) in items ?? []\">\n <GrDropdownMenuDivider\n v-if=\"isMenuSeparator(entry)\"\n :key=\"`divider-${index}`\"\n :inset=\"entry.inset\"\n />\n\n <GrDropdownMenuGroup\n v-else-if=\"isMenuSection(entry)\"\n :key=\"`group-${entry.title ?? index}`\"\n :title=\"entry.title\"\n :title-align=\"entry.titleAlign\"\n :dividers=\"entry.dividers\"\n :uppercase=\"entry.uppercase\"\n >\n <GrDropdownMenuItem\n v-for=\"item in entry.items\"\n :key=\"item.key\"\n v-bind=\"itemProps(item)\"\n @click=\"onSelect(item)\"\n >\n {{ item.label }}\n </GrDropdownMenuItem>\n </GrDropdownMenuGroup>\n\n <GrDropdownMenuItem\n v-else-if=\"isMenuAction(entry)\"\n :key=\"entry.key\"\n v-bind=\"itemProps(entry)\"\n @click=\"onSelect(entry)\"\n >\n {{ entry.label }}\n </GrDropdownMenuItem>\n </template>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport { grDropdownMenuListClass } from './grDropdownMenuStyles'\n\n/**\n * `role=\"none\"` на обёртке обязателен: `role=\"menu\"` у панели объявляет своих\n * потомков презентационными, и любой div между панелью и пунктом ломает\n * `aria-required-children`, а пункты теряют принадлежность к меню.\n */\n\nexport interface GrDropdownMenuListProps {\n dividers?: boolean\n borderTop?: boolean\n borderBottom?: boolean\n}\n\nconst props = withDefaults(defineProps<GrDropdownMenuListProps>(), {\n dividers: false,\n borderTop: false,\n borderBottom: false,\n})\n\nconst className = computed(() => grDropdownMenuListClass({\n dividers: props.dividers,\n borderTop: props.borderTop,\n borderBottom: props.borderBottom,\n}))\n\ndefineSlots<{\n /** Пункты списка меню. */\n default?: () => any\n}>()\n</script>\n\n<template>\n <div\n data-gr-dropdown-menu-list\n role=\"none\"\n :class=\"className\"\n >\n <slot />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport { grDropdownMenuListClass } from './grDropdownMenuStyles'\n\n/**\n * `role=\"none\"` на обёртке обязателен: `role=\"menu\"` у панели объявляет своих\n * потомков презентационными, и любой div между панелью и пунктом ломает\n * `aria-required-children`, а пункты теряют принадлежность к меню.\n */\n\nexport interface GrDropdownMenuListProps {\n dividers?: boolean\n borderTop?: boolean\n borderBottom?: boolean\n}\n\nconst props = withDefaults(defineProps<GrDropdownMenuListProps>(), {\n dividers: false,\n borderTop: false,\n borderBottom: false,\n})\n\nconst className = computed(() => grDropdownMenuListClass({\n dividers: props.dividers,\n borderTop: props.borderTop,\n borderBottom: props.borderBottom,\n}))\n\ndefineSlots<{\n /** Пункты списка меню. */\n default?: () => any\n}>()\n</script>\n\n<template>\n <div\n data-gr-dropdown-menu-list\n role=\"none\"\n :class=\"className\"\n >\n <slot />\n </div>\n</template>\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
1
  import { a as GrDropdownMenuItem_default, c as GrDropdownMenuDivider_default, o as GrDropdownMenuGroup_default, s as GrDropdownMenuHeader_default, t as GrDropdownMenuList_default } from "./chunks/GrDropdownMenuList-B33ZzwfB.js";
2
- import { n as GrDropdownMenuColumn_default, r as GrDropdownMenu_default, t as GrDropdownMenuColumns_default } from "./chunks/GrDropdownMenu-DNurbsWc.js";
2
+ import { n as GrDropdownMenuColumn_default, r as GrDropdownMenu_default, t as GrDropdownMenuColumns_default } from "./chunks/GrDropdownMenu-COOR1LCs.js";
3
3
  import { n as grDropdownMenuSafelist, t as grDropdownMenuConfig } from "../../chunks/config-_jbgsFpw.js";
4
4
  export { GrDropdownMenu_default as GrDropdownMenu, GrDropdownMenu_default as default, GrDropdownMenuColumn_default as GrDropdownMenuColumn, GrDropdownMenuColumns_default as GrDropdownMenuColumns, GrDropdownMenuDivider_default as GrDropdownMenuDivider, GrDropdownMenuGroup_default as GrDropdownMenuGroup, GrDropdownMenuHeader_default as GrDropdownMenuHeader, GrDropdownMenuItem_default as GrDropdownMenuItem, GrDropdownMenuList_default as GrDropdownMenuList, grDropdownMenuConfig, grDropdownMenuSafelist };
@@ -1,6 +1,6 @@
1
- import { a as useGrComponentSize, i as useGrComponentProp } from "../../../chunks/context-CTbuwcYs.js";
1
+ import { a as useGrComponentSize, i as useGrComponentProp } from "../../../chunks/context-CPMRfwVr.js";
2
2
  import { n as useGranularityTranslations } from "../../../chunks/granularityI18n-BC5zsj_d.js";
3
- import { t as GrIcon_default } from "../../GrIcon/chunks/GrIcon-Dmf0c9ba.js";
3
+ import { t as GrIcon_default } from "../../GrIcon/chunks/GrIcon-DTZIgmje.js";
4
4
  import { a as descriptionBaseClass, c as iconBoxBaseClass, d as titleBaseClass, f as titleBySize, i as actionsBySize, l as iconBoxBySize, o as descriptionBySize, r as actionsBaseClass, s as grEmptyStateRootClass, u as iconSizeBySize } from "../../../chunks/config-CWtfxkM9.js";
5
5
  import { computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, markRaw, normalizeClass, openBlock, renderSlot, resolveDynamicComponent, toDisplayString, unref, useSlots, withCtx } from "vue";
6
6
  //#region ~icons/lucide/inbox
@@ -1 +1 @@
1
- {"version":3,"file":"GrEmptyState-RqsWvgI9.js","names":["$slots"],"sources":["../../../../src/components/GrEmptyState/GrEmptyState.vue","../../../../src/components/GrEmptyState/GrEmptyState.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport IconInbox from '~icons/lucide/inbox'\n\nimport GrIcon from '../GrIcon/GrIcon.vue'\nimport { useGrComponentProp, useGrComponentSize } from '../GrConfigProvider/context'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\n\nimport {\n actionsBaseClass,\n actionsBySize,\n descriptionBaseClass,\n descriptionBySize,\n grEmptyStateRootClass,\n iconBoxBaseClass,\n iconBoxBySize,\n iconSizeBySize,\n titleBaseClass,\n titleBySize,\n type GrEmptyStateHeadingLevel,\n type GrEmptyStateSize,\n type GrEmptyStateVariant,\n} from './grEmptyStateStyles'\n\nexport type {\n GrEmptyStateHeadingLevel,\n GrEmptyStateSize,\n GrEmptyStateVariant,\n} from './grEmptyStateStyles'\n\n/**\n * GrEmptyState — карточка пустого состояния: иконка, заголовок, описание и\n * слот действий.\n *\n * Заголовок — настоящий heading: без него пустое состояние не находится\n * навигацией по заголовкам, а именно оно и объясняет, почему на экране ничего\n * нет.\n */\nexport interface GrEmptyStateProps {\n /** Заголовок. Не задан — берётся из локали; слот `#title` сильнее обоих. */\n title?: string\n description?: string\n size?: GrEmptyStateSize\n /** `ghost` снимает рамку и фон: карточка внутри карточки рисует вторую рамку. */\n variant?: GrEmptyStateVariant\n headingLevel?: GrEmptyStateHeadingLevel\n}\n\nconst props = withDefaults(defineProps<GrEmptyStateProps>(), {\n title: undefined,\n description: undefined,\n size: undefined,\n variant: undefined,\n headingLevel: undefined,\n})\n\nconst slots = defineSlots<{\n /** Иконка вместо встроенной. */\n icon?: () => unknown\n /** Заголовок разметкой: ссылка, выделение, счётчик. */\n title?: () => unknown\n description?: () => unknown\n /** Действия под текстом: центрируются. */\n default?: () => unknown\n}>()\n\nconst { t } = useGranularityTranslations()\n\nconst resolvedSize = useGrComponentSize(() => props.size, { component: 'GrEmptyState' })\nconst resolvedVariant = useGrComponentProp('GrEmptyState', 'variant', () => props.variant, 'outlined')\nconst headingLevel = useGrComponentProp('GrEmptyState', 'headingLevel', () => props.headingLevel, 3)\n\nconst headingTag = computed(() => `h${headingLevel.value}`)\nconst resolvedTitle = computed(() => props.title ?? t('gr.emptyState.title', 'Nothing here yet'))\nconst hasDescription = computed(() => Boolean(props.description) || Boolean(slots.description))\n</script>\n\n<template>\n <div\n data-gr-empty-state\n :class=\"grEmptyStateRootClass({ variant: resolvedVariant, size: resolvedSize })\"\n >\n <div class=\"flex justify-center\">\n <div data-gr-empty-state-icon :class=\"[iconBoxBaseClass, iconBoxBySize[resolvedSize]]\">\n <slot name=\"icon\">\n <GrIcon :size=\"iconSizeBySize[resolvedSize]\">\n <IconInbox aria-hidden=\"true\" />\n </GrIcon>\n </slot>\n </div>\n </div>\n\n <component\n :is=\"headingTag\"\n data-gr-empty-state-title\n :class=\"[titleBaseClass, titleBySize[resolvedSize]]\"\n >\n <slot name=\"title\">\n {{ resolvedTitle }}\n </slot>\n </component>\n\n <div\n v-if=\"hasDescription\"\n data-gr-empty-state-description\n :class=\"[descriptionBaseClass, descriptionBySize[resolvedSize]]\"\n >\n <slot name=\"description\">\n {{ description }}\n </slot>\n </div>\n\n <div\n v-if=\"$slots.default\"\n data-gr-empty-state-actions\n :class=\"[actionsBaseClass, actionsBySize[resolvedSize]]\"\n >\n <slot />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport IconInbox from '~icons/lucide/inbox'\n\nimport GrIcon from '../GrIcon/GrIcon.vue'\nimport { useGrComponentProp, useGrComponentSize } from '../GrConfigProvider/context'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\n\nimport {\n actionsBaseClass,\n actionsBySize,\n descriptionBaseClass,\n descriptionBySize,\n grEmptyStateRootClass,\n iconBoxBaseClass,\n iconBoxBySize,\n iconSizeBySize,\n titleBaseClass,\n titleBySize,\n type GrEmptyStateHeadingLevel,\n type GrEmptyStateSize,\n type GrEmptyStateVariant,\n} from './grEmptyStateStyles'\n\nexport type {\n GrEmptyStateHeadingLevel,\n GrEmptyStateSize,\n GrEmptyStateVariant,\n} from './grEmptyStateStyles'\n\n/**\n * GrEmptyState — карточка пустого состояния: иконка, заголовок, описание и\n * слот действий.\n *\n * Заголовок — настоящий heading: без него пустое состояние не находится\n * навигацией по заголовкам, а именно оно и объясняет, почему на экране ничего\n * нет.\n */\nexport interface GrEmptyStateProps {\n /** Заголовок. Не задан — берётся из локали; слот `#title` сильнее обоих. */\n title?: string\n description?: string\n size?: GrEmptyStateSize\n /** `ghost` снимает рамку и фон: карточка внутри карточки рисует вторую рамку. */\n variant?: GrEmptyStateVariant\n headingLevel?: GrEmptyStateHeadingLevel\n}\n\nconst props = withDefaults(defineProps<GrEmptyStateProps>(), {\n title: undefined,\n description: undefined,\n size: undefined,\n variant: undefined,\n headingLevel: undefined,\n})\n\nconst slots = defineSlots<{\n /** Иконка вместо встроенной. */\n icon?: () => unknown\n /** Заголовок разметкой: ссылка, выделение, счётчик. */\n title?: () => unknown\n description?: () => unknown\n /** Действия под текстом: центрируются. */\n default?: () => unknown\n}>()\n\nconst { t } = useGranularityTranslations()\n\nconst resolvedSize = useGrComponentSize(() => props.size, { component: 'GrEmptyState' })\nconst resolvedVariant = useGrComponentProp('GrEmptyState', 'variant', () => props.variant, 'outlined')\nconst headingLevel = useGrComponentProp('GrEmptyState', 'headingLevel', () => props.headingLevel, 3)\n\nconst headingTag = computed(() => `h${headingLevel.value}`)\nconst resolvedTitle = computed(() => props.title ?? t('gr.emptyState.title', 'Nothing here yet'))\nconst hasDescription = computed(() => Boolean(props.description) || Boolean(slots.description))\n</script>\n\n<template>\n <div\n data-gr-empty-state\n :class=\"grEmptyStateRootClass({ variant: resolvedVariant, size: resolvedSize })\"\n >\n <div class=\"flex justify-center\">\n <div data-gr-empty-state-icon :class=\"[iconBoxBaseClass, iconBoxBySize[resolvedSize]]\">\n <slot name=\"icon\">\n <GrIcon :size=\"iconSizeBySize[resolvedSize]\">\n <IconInbox aria-hidden=\"true\" />\n </GrIcon>\n </slot>\n </div>\n </div>\n\n <component\n :is=\"headingTag\"\n data-gr-empty-state-title\n :class=\"[titleBaseClass, titleBySize[resolvedSize]]\"\n >\n <slot name=\"title\">\n {{ resolvedTitle }}\n </slot>\n </component>\n\n <div\n v-if=\"hasDescription\"\n data-gr-empty-state-description\n :class=\"[descriptionBaseClass, descriptionBySize[resolvedSize]]\"\n >\n <slot name=\"description\">\n {{ description }}\n </slot>\n </div>\n\n <div\n v-if=\"$slots.default\"\n data-gr-empty-state-actions\n :class=\"[actionsBaseClass, actionsBySize[resolvedSize]]\"\n >\n <slot />\n </div>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiDA,MAAM,QAAQ;EAQd,MAAM,QAAQ,SAAA;EAUd,MAAM,EAAE,MAAM,2BAA2B;EAEzC,MAAM,eAAe,yBAAyB,MAAM,MAAM,EAAE,WAAW,eAAe,CAAC;EACvF,MAAM,kBAAkB,mBAAmB,gBAAgB,iBAAiB,MAAM,SAAS,UAAU;EACrG,MAAM,eAAe,mBAAmB,gBAAgB,sBAAsB,MAAM,cAAc,CAAC;EAEnG,MAAM,aAAa,eAAe,IAAI,aAAa,OAAO;EAC1D,MAAM,gBAAgB,eAAe,MAAM,SAAS,EAAE,uBAAuB,kBAAkB,CAAC;EAChG,MAAM,iBAAiB,eAAe,QAAQ,MAAM,WAAW,KAAK,QAAQ,MAAM,WAAW,CAAC;;uBAI5F,mBAyCM,OAAA;IAxCJ,uBAAA;IACC,OAAK,eAAE,MAAA,qBAAA,CAAqB,CAAA;KAAA,SAAY,MAAA,eAAA;KAAe,MAAQ,MAAA,YAAA;IAAY,CAAA,CAAA;;IAE5E,mBAQM,OARN,YAQM,CAPJ,mBAMM,OAAA;KAND,4BAAA;KAA0B,OAAK,eAAA,CAAG,MAAA,gBAAA,GAAkB,MAAA,aAAA,CAAa,CAAC,MAAA,YAAA,EAAY,CAAA;QACjF,WAIO,KAAA,QAAA,QAAA,CAAA,SAAA,CAHL,YAES,gBAAA,EAFA,MAAM,MAAA,cAAA,CAAc,CAAC,MAAA,YAAA,GAAA,GAAA;4BACI,CAAhC,YAAgC,MAAA,aAAA,GAAA,EAArB,eAAY,OAAM,CAAA,CAAA,CAAA;;;kBAMrC,YAQY,wBAPL,WAAA,KAAU,GAAA;KACf,6BAAA;KACC,OAAK,eAAA,CAAG,MAAA,cAAA,GAAgB,MAAA,WAAA,CAAW,CAAC,MAAA,YAAA,EAAY,CAAA;;4BAI1C,CAFP,WAEO,KAAA,QAAA,SAAA,CAAA,SAAA,CAAA,gBAAA,gBADF,cAAA,KAAa,GAAA,CAAA,CAAA,CAAA,CAAA,CAAA;;;IAKZ,eAAA,SAAA,UAAA,GADR,mBAQM,OAAA;;KANJ,mCAAA;KACC,OAAK,eAAA,CAAG,MAAA,oBAAA,GAAsB,MAAA,iBAAA,CAAiB,CAAC,MAAA,YAAA,EAAY,CAAA;QAE7D,WAEO,KAAA,QAAA,eAAA,CAAA,SAAA,CAAA,gBAAA,gBADF,QAAA,WAAW,GAAA,CAAA,CAAA,CAAA,CAAA,GAAA,CAAA,KAAA,mBAAA,IAAA,IAAA;IAKVA,KAAAA,OAAO,WAAA,UAAA,GADf,mBAMM,OAAA;;KAJJ,+BAAA;KACC,OAAK,eAAA,CAAG,MAAA,gBAAA,GAAkB,MAAA,aAAA,CAAa,CAAC,MAAA,YAAA,EAAY,CAAA;QAErD,WAAQ,KAAA,QAAA,SAAA,CAAA,GAAA,CAAA,KAAA,mBAAA,IAAA,IAAA"}
1
+ {"version":3,"file":"GrEmptyState-BbvwE-E0.js","names":["$slots"],"sources":["../../../../src/components/GrEmptyState/GrEmptyState.vue","../../../../src/components/GrEmptyState/GrEmptyState.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport IconInbox from '~icons/lucide/inbox'\n\nimport GrIcon from '../GrIcon/GrIcon.vue'\nimport { useGrComponentProp, useGrComponentSize } from '../GrConfigProvider/context'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\n\nimport {\n actionsBaseClass,\n actionsBySize,\n descriptionBaseClass,\n descriptionBySize,\n grEmptyStateRootClass,\n iconBoxBaseClass,\n iconBoxBySize,\n iconSizeBySize,\n titleBaseClass,\n titleBySize,\n type GrEmptyStateHeadingLevel,\n type GrEmptyStateSize,\n type GrEmptyStateVariant,\n} from './grEmptyStateStyles'\n\nexport type {\n GrEmptyStateHeadingLevel,\n GrEmptyStateSize,\n GrEmptyStateVariant,\n} from './grEmptyStateStyles'\n\n/**\n * GrEmptyState — карточка пустого состояния: иконка, заголовок, описание и\n * слот действий.\n *\n * Заголовок — настоящий heading: без него пустое состояние не находится\n * навигацией по заголовкам, а именно оно и объясняет, почему на экране ничего\n * нет.\n */\nexport interface GrEmptyStateProps {\n /** Заголовок. Не задан — берётся из локали; слот `#title` сильнее обоих. */\n title?: string\n description?: string\n size?: GrEmptyStateSize\n /** `ghost` снимает рамку и фон: карточка внутри карточки рисует вторую рамку. */\n variant?: GrEmptyStateVariant\n headingLevel?: GrEmptyStateHeadingLevel\n}\n\nconst props = withDefaults(defineProps<GrEmptyStateProps>(), {\n title: undefined,\n description: undefined,\n size: undefined,\n variant: undefined,\n headingLevel: undefined,\n})\n\nconst slots = defineSlots<{\n /** Иконка вместо встроенной. */\n icon?: () => unknown\n /** Заголовок разметкой: ссылка, выделение, счётчик. */\n title?: () => unknown\n description?: () => unknown\n /** Действия под текстом: центрируются. */\n default?: () => unknown\n}>()\n\nconst { t } = useGranularityTranslations()\n\nconst resolvedSize = useGrComponentSize(() => props.size, { component: 'GrEmptyState' })\nconst resolvedVariant = useGrComponentProp('GrEmptyState', 'variant', () => props.variant, 'outlined')\nconst headingLevel = useGrComponentProp('GrEmptyState', 'headingLevel', () => props.headingLevel, 3)\n\nconst headingTag = computed(() => `h${headingLevel.value}`)\nconst resolvedTitle = computed(() => props.title ?? t('gr.emptyState.title', 'Nothing here yet'))\nconst hasDescription = computed(() => Boolean(props.description) || Boolean(slots.description))\n</script>\n\n<template>\n <div\n data-gr-empty-state\n :class=\"grEmptyStateRootClass({ variant: resolvedVariant, size: resolvedSize })\"\n >\n <div class=\"flex justify-center\">\n <div data-gr-empty-state-icon :class=\"[iconBoxBaseClass, iconBoxBySize[resolvedSize]]\">\n <slot name=\"icon\">\n <GrIcon :size=\"iconSizeBySize[resolvedSize]\">\n <IconInbox aria-hidden=\"true\" />\n </GrIcon>\n </slot>\n </div>\n </div>\n\n <component\n :is=\"headingTag\"\n data-gr-empty-state-title\n :class=\"[titleBaseClass, titleBySize[resolvedSize]]\"\n >\n <slot name=\"title\">\n {{ resolvedTitle }}\n </slot>\n </component>\n\n <div\n v-if=\"hasDescription\"\n data-gr-empty-state-description\n :class=\"[descriptionBaseClass, descriptionBySize[resolvedSize]]\"\n >\n <slot name=\"description\">\n {{ description }}\n </slot>\n </div>\n\n <div\n v-if=\"$slots.default\"\n data-gr-empty-state-actions\n :class=\"[actionsBaseClass, actionsBySize[resolvedSize]]\"\n >\n <slot />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport IconInbox from '~icons/lucide/inbox'\n\nimport GrIcon from '../GrIcon/GrIcon.vue'\nimport { useGrComponentProp, useGrComponentSize } from '../GrConfigProvider/context'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\n\nimport {\n actionsBaseClass,\n actionsBySize,\n descriptionBaseClass,\n descriptionBySize,\n grEmptyStateRootClass,\n iconBoxBaseClass,\n iconBoxBySize,\n iconSizeBySize,\n titleBaseClass,\n titleBySize,\n type GrEmptyStateHeadingLevel,\n type GrEmptyStateSize,\n type GrEmptyStateVariant,\n} from './grEmptyStateStyles'\n\nexport type {\n GrEmptyStateHeadingLevel,\n GrEmptyStateSize,\n GrEmptyStateVariant,\n} from './grEmptyStateStyles'\n\n/**\n * GrEmptyState — карточка пустого состояния: иконка, заголовок, описание и\n * слот действий.\n *\n * Заголовок — настоящий heading: без него пустое состояние не находится\n * навигацией по заголовкам, а именно оно и объясняет, почему на экране ничего\n * нет.\n */\nexport interface GrEmptyStateProps {\n /** Заголовок. Не задан — берётся из локали; слот `#title` сильнее обоих. */\n title?: string\n description?: string\n size?: GrEmptyStateSize\n /** `ghost` снимает рамку и фон: карточка внутри карточки рисует вторую рамку. */\n variant?: GrEmptyStateVariant\n headingLevel?: GrEmptyStateHeadingLevel\n}\n\nconst props = withDefaults(defineProps<GrEmptyStateProps>(), {\n title: undefined,\n description: undefined,\n size: undefined,\n variant: undefined,\n headingLevel: undefined,\n})\n\nconst slots = defineSlots<{\n /** Иконка вместо встроенной. */\n icon?: () => unknown\n /** Заголовок разметкой: ссылка, выделение, счётчик. */\n title?: () => unknown\n description?: () => unknown\n /** Действия под текстом: центрируются. */\n default?: () => unknown\n}>()\n\nconst { t } = useGranularityTranslations()\n\nconst resolvedSize = useGrComponentSize(() => props.size, { component: 'GrEmptyState' })\nconst resolvedVariant = useGrComponentProp('GrEmptyState', 'variant', () => props.variant, 'outlined')\nconst headingLevel = useGrComponentProp('GrEmptyState', 'headingLevel', () => props.headingLevel, 3)\n\nconst headingTag = computed(() => `h${headingLevel.value}`)\nconst resolvedTitle = computed(() => props.title ?? t('gr.emptyState.title', 'Nothing here yet'))\nconst hasDescription = computed(() => Boolean(props.description) || Boolean(slots.description))\n</script>\n\n<template>\n <div\n data-gr-empty-state\n :class=\"grEmptyStateRootClass({ variant: resolvedVariant, size: resolvedSize })\"\n >\n <div class=\"flex justify-center\">\n <div data-gr-empty-state-icon :class=\"[iconBoxBaseClass, iconBoxBySize[resolvedSize]]\">\n <slot name=\"icon\">\n <GrIcon :size=\"iconSizeBySize[resolvedSize]\">\n <IconInbox aria-hidden=\"true\" />\n </GrIcon>\n </slot>\n </div>\n </div>\n\n <component\n :is=\"headingTag\"\n data-gr-empty-state-title\n :class=\"[titleBaseClass, titleBySize[resolvedSize]]\"\n >\n <slot name=\"title\">\n {{ resolvedTitle }}\n </slot>\n </component>\n\n <div\n v-if=\"hasDescription\"\n data-gr-empty-state-description\n :class=\"[descriptionBaseClass, descriptionBySize[resolvedSize]]\"\n >\n <slot name=\"description\">\n {{ description }}\n </slot>\n </div>\n\n <div\n v-if=\"$slots.default\"\n data-gr-empty-state-actions\n :class=\"[actionsBaseClass, actionsBySize[resolvedSize]]\"\n >\n <slot />\n </div>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiDA,MAAM,QAAQ;EAQd,MAAM,QAAQ,SAAA;EAUd,MAAM,EAAE,MAAM,2BAA2B;EAEzC,MAAM,eAAe,yBAAyB,MAAM,MAAM,EAAE,WAAW,eAAe,CAAC;EACvF,MAAM,kBAAkB,mBAAmB,gBAAgB,iBAAiB,MAAM,SAAS,UAAU;EACrG,MAAM,eAAe,mBAAmB,gBAAgB,sBAAsB,MAAM,cAAc,CAAC;EAEnG,MAAM,aAAa,eAAe,IAAI,aAAa,OAAO;EAC1D,MAAM,gBAAgB,eAAe,MAAM,SAAS,EAAE,uBAAuB,kBAAkB,CAAC;EAChG,MAAM,iBAAiB,eAAe,QAAQ,MAAM,WAAW,KAAK,QAAQ,MAAM,WAAW,CAAC;;GAI5F,OAAA,UAAA,GAAA,mBAyCM,OAAA;IAxCJ,uBAAA;IACC,OAAK,eAAE,MAAA,qBAAA,CAAqB,CAAA;KAAA,SAAY,MAAA,eAAA;KAAe,MAAQ,MAAA,YAAA;IAAY,CAAA,CAAA;;IAE5E,mBAQM,OARN,YAQM,CAPJ,mBAMM,OAAA;KAND,4BAAA;KAA0B,OAAK,eAAA,CAAG,MAAA,gBAAA,GAAkB,MAAA,aAAA,CAAa,CAAC,MAAA,YAAA,EAAY,CAAA;IACjF,GAAA,CAAA,WAIO,KAAA,QAAA,QAAA,CAAA,SAAA,CAHL,YAES,gBAAA,EAFA,MAAM,MAAA,cAAA,CAAc,CAAC,MAAA,YAAA,GAAA,GAAA;KAC5B,SAAA,cAAgC,CAAhC,YAAgC,MAAA,aAAA,GAAA,EAArB,eAAY,OAAM,CAAA,CAAA,CAAA;;;KAMrC,UAAA,GAAA,YAQY,wBAPL,WAAA,KAAU,GAAA;KACf,6BAAA;KACC,OAAK,eAAA,CAAG,MAAA,cAAA,GAAgB,MAAA,WAAA,CAAW,CAAC,MAAA,YAAA,EAAY,CAAA;;KAEjD,SAAA,cAEO,CAFP,WAEO,KAAA,QAAA,SAAA,CAAA,SAAA,CADF,gBAAA,gBAAA,cAAA,KAAa,GAAA,CAAA,CAAA,CAAA,CAAA,CAAA;;;IAKZ,eAAA,SADR,UAAA,GAAA,mBAQM,OAAA;;KANJ,mCAAA;KACC,OAAK,eAAA,CAAG,MAAA,oBAAA,GAAsB,MAAA,iBAAA,CAAiB,CAAC,MAAA,YAAA,EAAY,CAAA;IAE7D,GAAA,CAAA,WAEO,KAAA,QAAA,eAAA,CAAA,SAAA,CADF,gBAAA,gBAAA,QAAA,WAAW,GAAA,CAAA,CAAA,CAAA,CAAA,GAAA,CAAA,KAAA,mBAAA,IAAA,IAAA;IAKVA,KAAAA,OAAO,WADf,UAAA,GAAA,mBAMM,OAAA;;KAJJ,+BAAA;KACC,OAAK,eAAA,CAAG,MAAA,gBAAA,GAAkB,MAAA,aAAA,CAAa,CAAC,MAAA,YAAA,EAAY,CAAA;IAErD,GAAA,CAAA,WAAQ,KAAA,QAAA,SAAA,CAAA,GAAA,CAAA,KAAA,mBAAA,IAAA,IAAA"}
@@ -1,3 +1,3 @@
1
- import { t as GrEmptyState_default } from "./chunks/GrEmptyState-RqsWvgI9.js";
1
+ import { t as GrEmptyState_default } from "./chunks/GrEmptyState-BbvwE-E0.js";
2
2
  import { n as grEmptyStateSafelist, t as grEmptyStateConfig } from "../../chunks/config-CWtfxkM9.js";
3
3
  export { GrEmptyState_default as GrEmptyState, GrEmptyState_default as default, grEmptyStateConfig, grEmptyStateSafelist };
@@ -1,4 +1,4 @@
1
- import { i as useGrComponentProp } from "../../../chunks/context-CTbuwcYs.js";
1
+ import { i as useGrComponentProp } from "../../../chunks/context-CPMRfwVr.js";
2
2
  import { t as GrSkeleton_default } from "../../GrSkeleton/chunks/GrSkeleton-CgfXxPQ2.js";
3
3
  import { a as filePreviewInteractiveClass, c as filePreviewMediaLoadingClass, d as filePreviewTileWidths, i as filePreviewIconClass, l as filePreviewRatioClass, o as filePreviewLabelClass, r as filePreviewFallbackClass, s as filePreviewMediaClass, u as filePreviewRootClass } from "../../../chunks/config-BaWANzzB.js";
4
4
  import { computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, defineComponent, markRaw, normalizeClass, normalizeStyle, openBlock, ref, resolveDynamicComponent, toDisplayString, unref, watch, withCtx } from "vue";
@@ -1 +1 @@
1
- {"version":3,"file":"GrFilePreview-C9Z7hMK8.js","names":[],"sources":["../../../../src/components/GrFilePreview/fileKindOf.ts","../../../../src/components/GrFilePreview/GrFilePreview.vue","../../../../src/components/GrFilePreview/GrFilePreview.vue"],"sourcesContent":["/**\n * Вид файла по MIME-типу.\n *\n * Тип решает **`mime`, а не расширение**: расширение врёт (`.dat` у выгрузки,\n * `.pdf` у переименованного архива), а бэкенд отдаёт настоящий тип — брать надо\n * его. От вида зависит единственное решение компонента: рисовать `<img>` или\n * иконку.\n */\n\nexport type GrFileKind\n = | 'image'\n | 'pdf'\n | 'document'\n | 'spreadsheet'\n | 'archive'\n /** Тип не опознан, пуст или это `application/octet-stream`. */\n | 'unknown'\n\n/** Точные типы. Порядок не важен — совпадение полное. */\nconst EXACT: Record<string, GrFileKind> = {\n 'application/pdf': 'pdf',\n 'application/x-pdf': 'pdf',\n\n 'application/msword': 'document',\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'document',\n 'application/vnd.oasis.opendocument.text': 'document',\n 'application/rtf': 'document',\n\n 'application/vnd.ms-excel': 'spreadsheet',\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'spreadsheet',\n 'application/vnd.oasis.opendocument.spreadsheet': 'spreadsheet',\n 'text/csv': 'spreadsheet',\n 'text/tab-separated-values': 'spreadsheet',\n\n 'application/zip': 'archive',\n 'application/x-zip-compressed': 'archive',\n 'application/x-rar-compressed': 'archive',\n 'application/vnd.rar': 'archive',\n 'application/x-7z-compressed': 'archive',\n 'application/x-tar': 'archive',\n 'application/gzip': 'archive',\n 'application/x-gzip': 'archive',\n}\n\n/**\n * Приведение к сравнимому виду: тип приходит из БД и бывает с параметрами\n * (`text/plain; charset=utf-8`) и в любом регистре.\n */\nfunction normalize(mime: string): string {\n return mime.split(';')[0].trim().toLowerCase()\n}\n\nexport function fileKindOf(mime: string | null | undefined): GrFileKind {\n if (!mime)\n return 'unknown'\n\n const type = normalize(mime)\n if (!type)\n return 'unknown'\n\n // Картинка — единственный вид, который компонент рисует, а не подписывает.\n if (type.startsWith('image/'))\n return 'image'\n\n const exact = EXACT[type]\n if (exact)\n return exact\n\n // `text/csv` уже разобран выше: таблица важнее общего правила для текста.\n if (type.startsWith('text/'))\n return 'document'\n\n return 'unknown'\n}\n\n/** Картинку показываем, остальное — подписываем иконкой. */\nexport function isPreviewableKind(kind: GrFileKind): boolean {\n return kind === 'image'\n}\n","<script setup lang=\"ts\">\nimport { computed, markRaw, ref, watch, type Component } from 'vue'\n\nimport { useGrComponentProp } from '../GrConfigProvider/context'\nimport GrSkeleton from '../GrSkeleton/GrSkeleton.vue'\n\nimport IconFile from '~icons/lucide/file'\nimport IconFileArchive from '~icons/lucide/file-archive'\nimport IconFileSpreadsheet from '~icons/lucide/file-spreadsheet'\nimport IconFileText from '~icons/lucide/file-text'\nimport IconFileType from '~icons/lucide/file-type'\nimport IconImageOff from '~icons/lucide/image-off'\n\nimport type { GrSizeWithPx } from '../shared/sizes'\n\nimport { fileKindOf, isPreviewableKind, type GrFileKind } from './fileKindOf'\nimport {\n filePreviewFallbackClass,\n filePreviewIconClass,\n filePreviewInteractiveClass,\n filePreviewLabelClass,\n filePreviewMediaClass,\n filePreviewMediaLoadingClass,\n filePreviewRatioClass,\n filePreviewRootClass,\n filePreviewTileWidths,\n type GrFilePreviewRatio,\n} from './grFilePreviewStyles'\n\nexport type { GrFileKind } from './fileKindOf'\nexport type { GrFilePreviewRatio } from './grFilePreviewStyles'\n\n/**\n * Плитка превью файла с фолбэком по типу.\n *\n * Показывает **сохранённый** файл, а не отправляет новый: отправка — это\n * `GrFormFile` и `GrFileUpload`. Просмотрщик во весь экран открывает\n * потребитель по событию `click`.\n */\nexport interface GrFilePreviewProps {\n /** Адрес превью. Пусто — сразу заглушка по типу. */\n src?: string | null\n /** MIME-тип. Он решает, картинка это или файл. */\n mime?: string | null\n /** Имя файла: доступное имя картинки и подпись заглушки. */\n name?: string | null\n /**\n * Ступень канонической шкалы либо произвольная ширина в пикселях. Число —\n * escape-hatch, как диаметр у GrAvatar: плитка 96px в ленте вложений в\n * четыре ступени не укладывается.\n */\n tileSize?: GrSizeWithPx\n ratio?: GrFilePreviewRatio\n /** Ссылка на оригинал — для не-картинок и для перехода мимо просмотрщика. */\n href?: string\n /** Свой корневой тег (`RouterLink`, `Link` от Inertia). Сильнее `href`. */\n as?: string | Component\n /** Плитка кликабельна и эмитит `click` — обычно чтобы открыть просмотрщик. */\n clickable?: boolean\n loading?: 'lazy' | 'eager'\n /**\n * Доступное имя интерактивной плитки. Не задано — имя приходит из содержимого:\n * `alt` картинки или подписи заглушки.\n */\n ariaLabel?: string\n}\n\nexport interface GrFilePreviewEmits {\n (e: 'click', event: MouseEvent): void\n}\n\nconst props = withDefaults(defineProps<GrFilePreviewProps>(), {\n // Дефолты живут в резолверах ниже: Vue подставил бы свой раньше, чем компонент\n // заглянет в `GrConfigProvider`.\n src: undefined,\n mime: undefined,\n name: undefined,\n tileSize: undefined,\n ratio: undefined,\n href: undefined,\n as: undefined,\n clickable: false,\n loading: undefined,\n ariaLabel: undefined,\n})\n\nconst emit = defineEmits<GrFilePreviewEmits>()\n\nconst resolvedTileSize = useGrComponentProp('GrFilePreview', 'tileSize', () => props.tileSize, 'md')\nconst resolvedRatio = useGrComponentProp('GrFilePreview', 'ratio', () => props.ratio, '1:1')\nconst resolvedLoading = useGrComponentProp('GrFilePreview', 'loading', () => props.loading, 'lazy')\n\nconst kind = computed<GrFileKind>(() => fileKindOf(props.mime))\n\n/**\n * Состояний три, а не два. Сорвавшаяся загрузка деградирует в заглушку: превью\n * может исчезнуть с диска, и «сломанная картинка» здесь не информативнее\n * иконки. Отдельное `loading` нужно ленте вложений: два десятка плиток\n * приезжают вразнобой, и без него сетка стоит дырами непонятной природы —\n * «ещё едет» и «файл без превью» выглядят одинаково.\n */\ntype ImageState = 'loading' | 'loaded' | 'error'\n\nconst imageState = ref<ImageState>('loading')\n\n// Новая ссылка не должна наследовать ни ошибку прошлой, ни её готовность.\nwatch(() => props.src, () => {\n imageState.value = 'loading'\n})\n\nconst showImage = computed(() => (\n isPreviewableKind(kind.value) && Boolean(props.src) && imageState.value !== 'error'\n))\n\nconst showSkeleton = computed(() => showImage.value && imageState.value === 'loading')\n\n/**\n * Иконка вида. Картинка попадает сюда только сорвавшейся загрузкой — тогда и\n * значок другой: «изображение не открылось», а не «это файл».\n */\nconst iconByKind: Record<GrFileKind, Component> = {\n image: markRaw(IconImageOff),\n pdf: markRaw(IconFileText),\n document: markRaw(IconFileType),\n spreadsheet: markRaw(IconFileSpreadsheet),\n archive: markRaw(IconFileArchive),\n unknown: markRaw(IconFile),\n}\n\nconst fallbackIcon = computed(() => iconByKind[kind.value])\n\nconst isInteractive = computed(() => Boolean(props.as) || Boolean(props.href) || props.clickable)\n\nconst rootTag = computed<string | Component>(() => {\n if (props.as)\n return typeof props.as === 'string' ? props.as : markRaw(props.as)\n if (props.href)\n return 'a'\n return props.clickable ? 'button' : 'div'\n})\n\n/**\n * Компонент-ссылка (`Link` от Inertia, `RouterLink`) рендерит `<a>` сам, и без\n * `href` он ведёт в никуда. Строковый тег, кроме `a`, атрибут не понимает —\n * там он и гасится.\n */\nconst rootHref = computed(() => (\n typeof rootTag.value === 'string' && rootTag.value !== 'a' ? undefined : props.href\n))\n\nconst rootClass = computed(() => [\n filePreviewRootClass,\n filePreviewRatioClass[resolvedRatio.value],\n typeof resolvedTileSize.value === 'number' ? '' : filePreviewTileWidths[resolvedTileSize.value],\n isInteractive.value ? filePreviewInteractiveClass : '',\n].filter(Boolean).join(' '))\n\nconst rootStyle = computed(() => (\n typeof resolvedTileSize.value === 'number' ? { width: `${resolvedTileSize.value}px` } : undefined\n))\n\n/**\n * `alt` не выдумывается. Есть имя — оно и есть `alt`; нет — картинка\n * декоративна, и придуманное компонентом описание было бы хуже пустого.\n */\nconst alt = computed(() => props.name ?? '')\n\nfunction onClick(event: MouseEvent): void {\n emit('click', event)\n}\n</script>\n\n<template>\n <component\n :is=\"rootTag\"\n data-gr-file-preview\n :data-kind=\"kind\"\n :type=\"rootTag === 'button' ? 'button' : undefined\"\n :href=\"rootHref\"\n :class=\"rootClass\"\n :style=\"rootStyle\"\n :aria-label=\"ariaLabel\"\n @click=\"onClick\"\n >\n <GrSkeleton\n v-if=\"showSkeleton\"\n data-gr-file-preview-skeleton\n width=\"100%\"\n height=\"100%\"\n rounded=\"var(--gr-file-preview-radius, var(--gr-radius-md))\"\n />\n\n <!--\n Условие — `showImage`, а не «картинка готова»: убери её из дерева на\n время загрузки, и браузер не начнёт качать, а `load` не придёт никогда.\n Поэтому она ждёт невидимой и вне потока — иначе поделила бы плитку со\n скелетом как второй flex-элемент.\n -->\n <img\n v-if=\"showImage\"\n :key=\"src ?? ''\"\n data-gr-file-preview-image\n :src=\"src ?? undefined\"\n :alt=\"alt\"\n :loading=\"resolvedLoading\"\n :class=\"[filePreviewMediaClass, showSkeleton ? filePreviewMediaLoadingClass : '']\"\n @load=\"imageState = 'loaded'\"\n @error=\"imageState = 'error'\"\n >\n\n <span v-else data-gr-file-preview-fallback :class=\"filePreviewFallbackClass\">\n <component :is=\"fallbackIcon\" :class=\"filePreviewIconClass\" aria-hidden=\"true\" />\n <span v-if=\"name\" data-gr-file-preview-label :class=\"filePreviewLabelClass\">{{ name }}</span>\n </span>\n </component>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, markRaw, ref, watch, type Component } from 'vue'\n\nimport { useGrComponentProp } from '../GrConfigProvider/context'\nimport GrSkeleton from '../GrSkeleton/GrSkeleton.vue'\n\nimport IconFile from '~icons/lucide/file'\nimport IconFileArchive from '~icons/lucide/file-archive'\nimport IconFileSpreadsheet from '~icons/lucide/file-spreadsheet'\nimport IconFileText from '~icons/lucide/file-text'\nimport IconFileType from '~icons/lucide/file-type'\nimport IconImageOff from '~icons/lucide/image-off'\n\nimport type { GrSizeWithPx } from '../shared/sizes'\n\nimport { fileKindOf, isPreviewableKind, type GrFileKind } from './fileKindOf'\nimport {\n filePreviewFallbackClass,\n filePreviewIconClass,\n filePreviewInteractiveClass,\n filePreviewLabelClass,\n filePreviewMediaClass,\n filePreviewMediaLoadingClass,\n filePreviewRatioClass,\n filePreviewRootClass,\n filePreviewTileWidths,\n type GrFilePreviewRatio,\n} from './grFilePreviewStyles'\n\nexport type { GrFileKind } from './fileKindOf'\nexport type { GrFilePreviewRatio } from './grFilePreviewStyles'\n\n/**\n * Плитка превью файла с фолбэком по типу.\n *\n * Показывает **сохранённый** файл, а не отправляет новый: отправка — это\n * `GrFormFile` и `GrFileUpload`. Просмотрщик во весь экран открывает\n * потребитель по событию `click`.\n */\nexport interface GrFilePreviewProps {\n /** Адрес превью. Пусто — сразу заглушка по типу. */\n src?: string | null\n /** MIME-тип. Он решает, картинка это или файл. */\n mime?: string | null\n /** Имя файла: доступное имя картинки и подпись заглушки. */\n name?: string | null\n /**\n * Ступень канонической шкалы либо произвольная ширина в пикселях. Число —\n * escape-hatch, как диаметр у GrAvatar: плитка 96px в ленте вложений в\n * четыре ступени не укладывается.\n */\n tileSize?: GrSizeWithPx\n ratio?: GrFilePreviewRatio\n /** Ссылка на оригинал — для не-картинок и для перехода мимо просмотрщика. */\n href?: string\n /** Свой корневой тег (`RouterLink`, `Link` от Inertia). Сильнее `href`. */\n as?: string | Component\n /** Плитка кликабельна и эмитит `click` — обычно чтобы открыть просмотрщик. */\n clickable?: boolean\n loading?: 'lazy' | 'eager'\n /**\n * Доступное имя интерактивной плитки. Не задано — имя приходит из содержимого:\n * `alt` картинки или подписи заглушки.\n */\n ariaLabel?: string\n}\n\nexport interface GrFilePreviewEmits {\n (e: 'click', event: MouseEvent): void\n}\n\nconst props = withDefaults(defineProps<GrFilePreviewProps>(), {\n // Дефолты живут в резолверах ниже: Vue подставил бы свой раньше, чем компонент\n // заглянет в `GrConfigProvider`.\n src: undefined,\n mime: undefined,\n name: undefined,\n tileSize: undefined,\n ratio: undefined,\n href: undefined,\n as: undefined,\n clickable: false,\n loading: undefined,\n ariaLabel: undefined,\n})\n\nconst emit = defineEmits<GrFilePreviewEmits>()\n\nconst resolvedTileSize = useGrComponentProp('GrFilePreview', 'tileSize', () => props.tileSize, 'md')\nconst resolvedRatio = useGrComponentProp('GrFilePreview', 'ratio', () => props.ratio, '1:1')\nconst resolvedLoading = useGrComponentProp('GrFilePreview', 'loading', () => props.loading, 'lazy')\n\nconst kind = computed<GrFileKind>(() => fileKindOf(props.mime))\n\n/**\n * Состояний три, а не два. Сорвавшаяся загрузка деградирует в заглушку: превью\n * может исчезнуть с диска, и «сломанная картинка» здесь не информативнее\n * иконки. Отдельное `loading` нужно ленте вложений: два десятка плиток\n * приезжают вразнобой, и без него сетка стоит дырами непонятной природы —\n * «ещё едет» и «файл без превью» выглядят одинаково.\n */\ntype ImageState = 'loading' | 'loaded' | 'error'\n\nconst imageState = ref<ImageState>('loading')\n\n// Новая ссылка не должна наследовать ни ошибку прошлой, ни её готовность.\nwatch(() => props.src, () => {\n imageState.value = 'loading'\n})\n\nconst showImage = computed(() => (\n isPreviewableKind(kind.value) && Boolean(props.src) && imageState.value !== 'error'\n))\n\nconst showSkeleton = computed(() => showImage.value && imageState.value === 'loading')\n\n/**\n * Иконка вида. Картинка попадает сюда только сорвавшейся загрузкой — тогда и\n * значок другой: «изображение не открылось», а не «это файл».\n */\nconst iconByKind: Record<GrFileKind, Component> = {\n image: markRaw(IconImageOff),\n pdf: markRaw(IconFileText),\n document: markRaw(IconFileType),\n spreadsheet: markRaw(IconFileSpreadsheet),\n archive: markRaw(IconFileArchive),\n unknown: markRaw(IconFile),\n}\n\nconst fallbackIcon = computed(() => iconByKind[kind.value])\n\nconst isInteractive = computed(() => Boolean(props.as) || Boolean(props.href) || props.clickable)\n\nconst rootTag = computed<string | Component>(() => {\n if (props.as)\n return typeof props.as === 'string' ? props.as : markRaw(props.as)\n if (props.href)\n return 'a'\n return props.clickable ? 'button' : 'div'\n})\n\n/**\n * Компонент-ссылка (`Link` от Inertia, `RouterLink`) рендерит `<a>` сам, и без\n * `href` он ведёт в никуда. Строковый тег, кроме `a`, атрибут не понимает —\n * там он и гасится.\n */\nconst rootHref = computed(() => (\n typeof rootTag.value === 'string' && rootTag.value !== 'a' ? undefined : props.href\n))\n\nconst rootClass = computed(() => [\n filePreviewRootClass,\n filePreviewRatioClass[resolvedRatio.value],\n typeof resolvedTileSize.value === 'number' ? '' : filePreviewTileWidths[resolvedTileSize.value],\n isInteractive.value ? filePreviewInteractiveClass : '',\n].filter(Boolean).join(' '))\n\nconst rootStyle = computed(() => (\n typeof resolvedTileSize.value === 'number' ? { width: `${resolvedTileSize.value}px` } : undefined\n))\n\n/**\n * `alt` не выдумывается. Есть имя — оно и есть `alt`; нет — картинка\n * декоративна, и придуманное компонентом описание было бы хуже пустого.\n */\nconst alt = computed(() => props.name ?? '')\n\nfunction onClick(event: MouseEvent): void {\n emit('click', event)\n}\n</script>\n\n<template>\n <component\n :is=\"rootTag\"\n data-gr-file-preview\n :data-kind=\"kind\"\n :type=\"rootTag === 'button' ? 'button' : undefined\"\n :href=\"rootHref\"\n :class=\"rootClass\"\n :style=\"rootStyle\"\n :aria-label=\"ariaLabel\"\n @click=\"onClick\"\n >\n <GrSkeleton\n v-if=\"showSkeleton\"\n data-gr-file-preview-skeleton\n width=\"100%\"\n height=\"100%\"\n rounded=\"var(--gr-file-preview-radius, var(--gr-radius-md))\"\n />\n\n <!--\n Условие — `showImage`, а не «картинка готова»: убери её из дерева на\n время загрузки, и браузер не начнёт качать, а `load` не придёт никогда.\n Поэтому она ждёт невидимой и вне потока — иначе поделила бы плитку со\n скелетом как второй flex-элемент.\n -->\n <img\n v-if=\"showImage\"\n :key=\"src ?? ''\"\n data-gr-file-preview-image\n :src=\"src ?? undefined\"\n :alt=\"alt\"\n :loading=\"resolvedLoading\"\n :class=\"[filePreviewMediaClass, showSkeleton ? filePreviewMediaLoadingClass : '']\"\n @load=\"imageState = 'loaded'\"\n @error=\"imageState = 'error'\"\n >\n\n <span v-else data-gr-file-preview-fallback :class=\"filePreviewFallbackClass\">\n <component :is=\"fallbackIcon\" :class=\"filePreviewIconClass\" aria-hidden=\"true\" />\n <span v-if=\"name\" data-gr-file-preview-label :class=\"filePreviewLabelClass\">{{ name }}</span>\n </span>\n </component>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"GrFilePreview-PabkLgYX.js","names":[],"sources":["../../../../src/components/GrFilePreview/fileKindOf.ts","../../../../src/components/GrFilePreview/GrFilePreview.vue","../../../../src/components/GrFilePreview/GrFilePreview.vue"],"sourcesContent":["/**\n * Вид файла по MIME-типу.\n *\n * Тип решает **`mime`, а не расширение**: расширение врёт (`.dat` у выгрузки,\n * `.pdf` у переименованного архива), а бэкенд отдаёт настоящий тип — брать надо\n * его. От вида зависит единственное решение компонента: рисовать `<img>` или\n * иконку.\n */\n\nexport type GrFileKind\n = | 'image'\n | 'pdf'\n | 'document'\n | 'spreadsheet'\n | 'archive'\n /** Тип не опознан, пуст или это `application/octet-stream`. */\n | 'unknown'\n\n/** Точные типы. Порядок не важен — совпадение полное. */\nconst EXACT: Record<string, GrFileKind> = {\n 'application/pdf': 'pdf',\n 'application/x-pdf': 'pdf',\n\n 'application/msword': 'document',\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'document',\n 'application/vnd.oasis.opendocument.text': 'document',\n 'application/rtf': 'document',\n\n 'application/vnd.ms-excel': 'spreadsheet',\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'spreadsheet',\n 'application/vnd.oasis.opendocument.spreadsheet': 'spreadsheet',\n 'text/csv': 'spreadsheet',\n 'text/tab-separated-values': 'spreadsheet',\n\n 'application/zip': 'archive',\n 'application/x-zip-compressed': 'archive',\n 'application/x-rar-compressed': 'archive',\n 'application/vnd.rar': 'archive',\n 'application/x-7z-compressed': 'archive',\n 'application/x-tar': 'archive',\n 'application/gzip': 'archive',\n 'application/x-gzip': 'archive',\n}\n\n/**\n * Приведение к сравнимому виду: тип приходит из БД и бывает с параметрами\n * (`text/plain; charset=utf-8`) и в любом регистре.\n */\nfunction normalize(mime: string): string {\n return mime.split(';')[0].trim().toLowerCase()\n}\n\nexport function fileKindOf(mime: string | null | undefined): GrFileKind {\n if (!mime)\n return 'unknown'\n\n const type = normalize(mime)\n if (!type)\n return 'unknown'\n\n // Картинка — единственный вид, который компонент рисует, а не подписывает.\n if (type.startsWith('image/'))\n return 'image'\n\n const exact = EXACT[type]\n if (exact)\n return exact\n\n // `text/csv` уже разобран выше: таблица важнее общего правила для текста.\n if (type.startsWith('text/'))\n return 'document'\n\n return 'unknown'\n}\n\n/** Картинку показываем, остальное — подписываем иконкой. */\nexport function isPreviewableKind(kind: GrFileKind): boolean {\n return kind === 'image'\n}\n","<script setup lang=\"ts\">\nimport { computed, markRaw, ref, watch, type Component } from 'vue'\n\nimport { useGrComponentProp } from '../GrConfigProvider/context'\nimport GrSkeleton from '../GrSkeleton/GrSkeleton.vue'\n\nimport IconFile from '~icons/lucide/file'\nimport IconFileArchive from '~icons/lucide/file-archive'\nimport IconFileSpreadsheet from '~icons/lucide/file-spreadsheet'\nimport IconFileText from '~icons/lucide/file-text'\nimport IconFileType from '~icons/lucide/file-type'\nimport IconImageOff from '~icons/lucide/image-off'\n\nimport type { GrSizeWithPx } from '../shared/sizes'\n\nimport { fileKindOf, isPreviewableKind, type GrFileKind } from './fileKindOf'\nimport {\n filePreviewFallbackClass,\n filePreviewIconClass,\n filePreviewInteractiveClass,\n filePreviewLabelClass,\n filePreviewMediaClass,\n filePreviewMediaLoadingClass,\n filePreviewRatioClass,\n filePreviewRootClass,\n filePreviewTileWidths,\n type GrFilePreviewRatio,\n} from './grFilePreviewStyles'\n\nexport type { GrFileKind } from './fileKindOf'\nexport type { GrFilePreviewRatio } from './grFilePreviewStyles'\n\n/**\n * Плитка превью файла с фолбэком по типу.\n *\n * Показывает **сохранённый** файл, а не отправляет новый: отправка — это\n * `GrFormFile` и `GrFileUpload`. Просмотрщик во весь экран открывает\n * потребитель по событию `click`.\n */\nexport interface GrFilePreviewProps {\n /** Адрес превью. Пусто — сразу заглушка по типу. */\n src?: string | null\n /** MIME-тип. Он решает, картинка это или файл. */\n mime?: string | null\n /** Имя файла: доступное имя картинки и подпись заглушки. */\n name?: string | null\n /**\n * Ступень канонической шкалы либо произвольная ширина в пикселях. Число —\n * escape-hatch, как диаметр у GrAvatar: плитка 96px в ленте вложений в\n * четыре ступени не укладывается.\n */\n tileSize?: GrSizeWithPx\n ratio?: GrFilePreviewRatio\n /** Ссылка на оригинал — для не-картинок и для перехода мимо просмотрщика. */\n href?: string\n /** Свой корневой тег (`RouterLink`, `Link` от Inertia). Сильнее `href`. */\n as?: string | Component\n /** Плитка кликабельна и эмитит `click` — обычно чтобы открыть просмотрщик. */\n clickable?: boolean\n loading?: 'lazy' | 'eager'\n /**\n * Доступное имя интерактивной плитки. Не задано — имя приходит из содержимого:\n * `alt` картинки или подписи заглушки.\n */\n ariaLabel?: string\n}\n\nexport interface GrFilePreviewEmits {\n (e: 'click', event: MouseEvent): void\n}\n\nconst props = withDefaults(defineProps<GrFilePreviewProps>(), {\n // Дефолты живут в резолверах ниже: Vue подставил бы свой раньше, чем компонент\n // заглянет в `GrConfigProvider`.\n src: undefined,\n mime: undefined,\n name: undefined,\n tileSize: undefined,\n ratio: undefined,\n href: undefined,\n as: undefined,\n clickable: false,\n loading: undefined,\n ariaLabel: undefined,\n})\n\nconst emit = defineEmits<GrFilePreviewEmits>()\n\nconst resolvedTileSize = useGrComponentProp('GrFilePreview', 'tileSize', () => props.tileSize, 'md')\nconst resolvedRatio = useGrComponentProp('GrFilePreview', 'ratio', () => props.ratio, '1:1')\nconst resolvedLoading = useGrComponentProp('GrFilePreview', 'loading', () => props.loading, 'lazy')\n\nconst kind = computed<GrFileKind>(() => fileKindOf(props.mime))\n\n/**\n * Состояний три, а не два. Сорвавшаяся загрузка деградирует в заглушку: превью\n * может исчезнуть с диска, и «сломанная картинка» здесь не информативнее\n * иконки. Отдельное `loading` нужно ленте вложений: два десятка плиток\n * приезжают вразнобой, и без него сетка стоит дырами непонятной природы —\n * «ещё едет» и «файл без превью» выглядят одинаково.\n */\ntype ImageState = 'loading' | 'loaded' | 'error'\n\nconst imageState = ref<ImageState>('loading')\n\n// Новая ссылка не должна наследовать ни ошибку прошлой, ни её готовность.\nwatch(() => props.src, () => {\n imageState.value = 'loading'\n})\n\nconst showImage = computed(() => (\n isPreviewableKind(kind.value) && Boolean(props.src) && imageState.value !== 'error'\n))\n\nconst showSkeleton = computed(() => showImage.value && imageState.value === 'loading')\n\n/**\n * Иконка вида. Картинка попадает сюда только сорвавшейся загрузкой — тогда и\n * значок другой: «изображение не открылось», а не «это файл».\n */\nconst iconByKind: Record<GrFileKind, Component> = {\n image: markRaw(IconImageOff),\n pdf: markRaw(IconFileText),\n document: markRaw(IconFileType),\n spreadsheet: markRaw(IconFileSpreadsheet),\n archive: markRaw(IconFileArchive),\n unknown: markRaw(IconFile),\n}\n\nconst fallbackIcon = computed(() => iconByKind[kind.value])\n\nconst isInteractive = computed(() => Boolean(props.as) || Boolean(props.href) || props.clickable)\n\nconst rootTag = computed<string | Component>(() => {\n if (props.as)\n return typeof props.as === 'string' ? props.as : markRaw(props.as)\n if (props.href)\n return 'a'\n return props.clickable ? 'button' : 'div'\n})\n\n/**\n * Компонент-ссылка (`Link` от Inertia, `RouterLink`) рендерит `<a>` сам, и без\n * `href` он ведёт в никуда. Строковый тег, кроме `a`, атрибут не понимает —\n * там он и гасится.\n */\nconst rootHref = computed(() => (\n typeof rootTag.value === 'string' && rootTag.value !== 'a' ? undefined : props.href\n))\n\nconst rootClass = computed(() => [\n filePreviewRootClass,\n filePreviewRatioClass[resolvedRatio.value],\n typeof resolvedTileSize.value === 'number' ? '' : filePreviewTileWidths[resolvedTileSize.value],\n isInteractive.value ? filePreviewInteractiveClass : '',\n].filter(Boolean).join(' '))\n\nconst rootStyle = computed(() => (\n typeof resolvedTileSize.value === 'number' ? { width: `${resolvedTileSize.value}px` } : undefined\n))\n\n/**\n * `alt` не выдумывается. Есть имя — оно и есть `alt`; нет — картинка\n * декоративна, и придуманное компонентом описание было бы хуже пустого.\n */\nconst alt = computed(() => props.name ?? '')\n\nfunction onClick(event: MouseEvent): void {\n emit('click', event)\n}\n</script>\n\n<template>\n <component\n :is=\"rootTag\"\n data-gr-file-preview\n :data-kind=\"kind\"\n :type=\"rootTag === 'button' ? 'button' : undefined\"\n :href=\"rootHref\"\n :class=\"rootClass\"\n :style=\"rootStyle\"\n :aria-label=\"ariaLabel\"\n @click=\"onClick\"\n >\n <GrSkeleton\n v-if=\"showSkeleton\"\n data-gr-file-preview-skeleton\n width=\"100%\"\n height=\"100%\"\n rounded=\"var(--gr-file-preview-radius, var(--gr-radius-md))\"\n />\n\n <!--\n Условие — `showImage`, а не «картинка готова»: убери её из дерева на\n время загрузки, и браузер не начнёт качать, а `load` не придёт никогда.\n Поэтому она ждёт невидимой и вне потока — иначе поделила бы плитку со\n скелетом как второй flex-элемент.\n -->\n <img\n v-if=\"showImage\"\n :key=\"src ?? ''\"\n data-gr-file-preview-image\n :src=\"src ?? undefined\"\n :alt=\"alt\"\n :loading=\"resolvedLoading\"\n :class=\"[filePreviewMediaClass, showSkeleton ? filePreviewMediaLoadingClass : '']\"\n @load=\"imageState = 'loaded'\"\n @error=\"imageState = 'error'\"\n >\n\n <span v-else data-gr-file-preview-fallback :class=\"filePreviewFallbackClass\">\n <component :is=\"fallbackIcon\" :class=\"filePreviewIconClass\" aria-hidden=\"true\" />\n <span v-if=\"name\" data-gr-file-preview-label :class=\"filePreviewLabelClass\">{{ name }}</span>\n </span>\n </component>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, markRaw, ref, watch, type Component } from 'vue'\n\nimport { useGrComponentProp } from '../GrConfigProvider/context'\nimport GrSkeleton from '../GrSkeleton/GrSkeleton.vue'\n\nimport IconFile from '~icons/lucide/file'\nimport IconFileArchive from '~icons/lucide/file-archive'\nimport IconFileSpreadsheet from '~icons/lucide/file-spreadsheet'\nimport IconFileText from '~icons/lucide/file-text'\nimport IconFileType from '~icons/lucide/file-type'\nimport IconImageOff from '~icons/lucide/image-off'\n\nimport type { GrSizeWithPx } from '../shared/sizes'\n\nimport { fileKindOf, isPreviewableKind, type GrFileKind } from './fileKindOf'\nimport {\n filePreviewFallbackClass,\n filePreviewIconClass,\n filePreviewInteractiveClass,\n filePreviewLabelClass,\n filePreviewMediaClass,\n filePreviewMediaLoadingClass,\n filePreviewRatioClass,\n filePreviewRootClass,\n filePreviewTileWidths,\n type GrFilePreviewRatio,\n} from './grFilePreviewStyles'\n\nexport type { GrFileKind } from './fileKindOf'\nexport type { GrFilePreviewRatio } from './grFilePreviewStyles'\n\n/**\n * Плитка превью файла с фолбэком по типу.\n *\n * Показывает **сохранённый** файл, а не отправляет новый: отправка — это\n * `GrFormFile` и `GrFileUpload`. Просмотрщик во весь экран открывает\n * потребитель по событию `click`.\n */\nexport interface GrFilePreviewProps {\n /** Адрес превью. Пусто — сразу заглушка по типу. */\n src?: string | null\n /** MIME-тип. Он решает, картинка это или файл. */\n mime?: string | null\n /** Имя файла: доступное имя картинки и подпись заглушки. */\n name?: string | null\n /**\n * Ступень канонической шкалы либо произвольная ширина в пикселях. Число —\n * escape-hatch, как диаметр у GrAvatar: плитка 96px в ленте вложений в\n * четыре ступени не укладывается.\n */\n tileSize?: GrSizeWithPx\n ratio?: GrFilePreviewRatio\n /** Ссылка на оригинал — для не-картинок и для перехода мимо просмотрщика. */\n href?: string\n /** Свой корневой тег (`RouterLink`, `Link` от Inertia). Сильнее `href`. */\n as?: string | Component\n /** Плитка кликабельна и эмитит `click` — обычно чтобы открыть просмотрщик. */\n clickable?: boolean\n loading?: 'lazy' | 'eager'\n /**\n * Доступное имя интерактивной плитки. Не задано — имя приходит из содержимого:\n * `alt` картинки или подписи заглушки.\n */\n ariaLabel?: string\n}\n\nexport interface GrFilePreviewEmits {\n (e: 'click', event: MouseEvent): void\n}\n\nconst props = withDefaults(defineProps<GrFilePreviewProps>(), {\n // Дефолты живут в резолверах ниже: Vue подставил бы свой раньше, чем компонент\n // заглянет в `GrConfigProvider`.\n src: undefined,\n mime: undefined,\n name: undefined,\n tileSize: undefined,\n ratio: undefined,\n href: undefined,\n as: undefined,\n clickable: false,\n loading: undefined,\n ariaLabel: undefined,\n})\n\nconst emit = defineEmits<GrFilePreviewEmits>()\n\nconst resolvedTileSize = useGrComponentProp('GrFilePreview', 'tileSize', () => props.tileSize, 'md')\nconst resolvedRatio = useGrComponentProp('GrFilePreview', 'ratio', () => props.ratio, '1:1')\nconst resolvedLoading = useGrComponentProp('GrFilePreview', 'loading', () => props.loading, 'lazy')\n\nconst kind = computed<GrFileKind>(() => fileKindOf(props.mime))\n\n/**\n * Состояний три, а не два. Сорвавшаяся загрузка деградирует в заглушку: превью\n * может исчезнуть с диска, и «сломанная картинка» здесь не информативнее\n * иконки. Отдельное `loading` нужно ленте вложений: два десятка плиток\n * приезжают вразнобой, и без него сетка стоит дырами непонятной природы —\n * «ещё едет» и «файл без превью» выглядят одинаково.\n */\ntype ImageState = 'loading' | 'loaded' | 'error'\n\nconst imageState = ref<ImageState>('loading')\n\n// Новая ссылка не должна наследовать ни ошибку прошлой, ни её готовность.\nwatch(() => props.src, () => {\n imageState.value = 'loading'\n})\n\nconst showImage = computed(() => (\n isPreviewableKind(kind.value) && Boolean(props.src) && imageState.value !== 'error'\n))\n\nconst showSkeleton = computed(() => showImage.value && imageState.value === 'loading')\n\n/**\n * Иконка вида. Картинка попадает сюда только сорвавшейся загрузкой — тогда и\n * значок другой: «изображение не открылось», а не «это файл».\n */\nconst iconByKind: Record<GrFileKind, Component> = {\n image: markRaw(IconImageOff),\n pdf: markRaw(IconFileText),\n document: markRaw(IconFileType),\n spreadsheet: markRaw(IconFileSpreadsheet),\n archive: markRaw(IconFileArchive),\n unknown: markRaw(IconFile),\n}\n\nconst fallbackIcon = computed(() => iconByKind[kind.value])\n\nconst isInteractive = computed(() => Boolean(props.as) || Boolean(props.href) || props.clickable)\n\nconst rootTag = computed<string | Component>(() => {\n if (props.as)\n return typeof props.as === 'string' ? props.as : markRaw(props.as)\n if (props.href)\n return 'a'\n return props.clickable ? 'button' : 'div'\n})\n\n/**\n * Компонент-ссылка (`Link` от Inertia, `RouterLink`) рендерит `<a>` сам, и без\n * `href` он ведёт в никуда. Строковый тег, кроме `a`, атрибут не понимает —\n * там он и гасится.\n */\nconst rootHref = computed(() => (\n typeof rootTag.value === 'string' && rootTag.value !== 'a' ? undefined : props.href\n))\n\nconst rootClass = computed(() => [\n filePreviewRootClass,\n filePreviewRatioClass[resolvedRatio.value],\n typeof resolvedTileSize.value === 'number' ? '' : filePreviewTileWidths[resolvedTileSize.value],\n isInteractive.value ? filePreviewInteractiveClass : '',\n].filter(Boolean).join(' '))\n\nconst rootStyle = computed(() => (\n typeof resolvedTileSize.value === 'number' ? { width: `${resolvedTileSize.value}px` } : undefined\n))\n\n/**\n * `alt` не выдумывается. Есть имя — оно и есть `alt`; нет — картинка\n * декоративна, и придуманное компонентом описание было бы хуже пустого.\n */\nconst alt = computed(() => props.name ?? '')\n\nfunction onClick(event: MouseEvent): void {\n emit('click', event)\n}\n</script>\n\n<template>\n <component\n :is=\"rootTag\"\n data-gr-file-preview\n :data-kind=\"kind\"\n :type=\"rootTag === 'button' ? 'button' : undefined\"\n :href=\"rootHref\"\n :class=\"rootClass\"\n :style=\"rootStyle\"\n :aria-label=\"ariaLabel\"\n @click=\"onClick\"\n >\n <GrSkeleton\n v-if=\"showSkeleton\"\n data-gr-file-preview-skeleton\n width=\"100%\"\n height=\"100%\"\n rounded=\"var(--gr-file-preview-radius, var(--gr-radius-md))\"\n />\n\n <!--\n Условие — `showImage`, а не «картинка готова»: убери её из дерева на\n время загрузки, и браузер не начнёт качать, а `load` не придёт никогда.\n Поэтому она ждёт невидимой и вне потока — иначе поделила бы плитку со\n скелетом как второй flex-элемент.\n -->\n <img\n v-if=\"showImage\"\n :key=\"src ?? ''\"\n data-gr-file-preview-image\n :src=\"src ?? undefined\"\n :alt=\"alt\"\n :loading=\"resolvedLoading\"\n :class=\"[filePreviewMediaClass, showSkeleton ? filePreviewMediaLoadingClass : '']\"\n @load=\"imageState = 'loaded'\"\n @error=\"imageState = 'error'\"\n >\n\n <span v-else data-gr-file-preview-fallback :class=\"filePreviewFallbackClass\">\n <component :is=\"fallbackIcon\" :class=\"filePreviewIconClass\" aria-hidden=\"true\" />\n <span v-if=\"name\" data-gr-file-preview-label :class=\"filePreviewLabelClass\">{{ name }}</span>\n </span>\n </component>\n</template>\n"],"mappings":"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"}
@@ -1,3 +1,3 @@
1
- import { n as fileKindOf, r as isPreviewableKind, t as GrFilePreview_default } from "./chunks/GrFilePreview-C9Z7hMK8.js";
1
+ import { n as fileKindOf, r as isPreviewableKind, t as GrFilePreview_default } from "./chunks/GrFilePreview-PabkLgYX.js";
2
2
  import { n as grFilePreviewSafelist, t as grFilePreviewConfig } from "../../chunks/config-BaWANzzB.js";
3
3
  export { GrFilePreview_default as GrFilePreview, GrFilePreview_default as default, fileKindOf, grFilePreviewConfig, grFilePreviewSafelist, isPreviewableKind };
@@ -1,14 +1,14 @@
1
1
  import { t as x_default } from "../../../chunks/x-2KXnqxiD.js";
2
- import { a as useGrComponentSize } from "../../../chunks/context-CTbuwcYs.js";
2
+ import { a as useGrComponentSize } from "../../../chunks/context-CPMRfwVr.js";
3
3
  import { n as useGranularityTranslations } from "../../../chunks/granularityI18n-BC5zsj_d.js";
4
4
  import { f as runFileValidators, o as acceptValidator, p as FileValidationError } from "../../../chunks/fileValidation-D5TFBhbv.js";
5
- import { t as GrIcon_default } from "../../GrIcon/chunks/GrIcon-Dmf0c9ba.js";
5
+ import { t as GrIcon_default } from "../../GrIcon/chunks/GrIcon-DTZIgmje.js";
6
6
  import { n as useGrFormFieldContext } from "../../../chunks/context-DdNIxa1w.js";
7
7
  import { useGrFormControl } from "../../../composables/useGrFormControl.js";
8
8
  import { t as useFocusWithin } from "../../../chunks/useFocusWithin-BwHE0rzm.js";
9
9
  import { r as meaningfulSlotNodes, t as flattenSlotNodes } from "../../../chunks/slotNodes-DxNXpC7v.js";
10
10
  import { t as arrow_up_default } from "../../../chunks/arrow-up-C_G4jg8M.js";
11
- import { t as GrProgressBar_default } from "../../GrProgressBar/chunks/GrProgressBar-hszUOC8f.js";
11
+ import { t as GrProgressBar_default } from "../../GrProgressBar/chunks/GrProgressBar-C3NRBqIP.js";
12
12
  import { t as useFilePreviews } from "../../../chunks/useFilePreviews-DnwgdyBs.js";
13
13
  import { a as iconGlyphSizes, c as progressBarSizes, i as hintSizes, l as progressTextSizes, o as iconTileSizes, r as grFileUploadZoneClass, s as labelSizes, u as zoneGaps } from "../../../chunks/config-BlJa1Mj9.js";
14
14
  import { Fragment, Text, computed, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, guardReactiveProps, nextTick, normalizeClass, normalizeProps, onBeforeUnmount, onMounted, openBlock, reactive, ref, renderList, renderSlot, toDisplayString, unref, useSlots, watch, withCtx, withModifiers } from "vue";
@@ -899,7 +899,7 @@ var GrFileUpload_default = /* @__PURE__ */ defineComponent({
899
899
  inputRef.value?.blur();
900
900
  }
901
901
  onMounted(() => {
902
- if (!(typeof process !== "undefined" && process.env.NODE_ENV !== "production")) return;
902
+ if (!(process.env.NODE_ENV !== "production")) return;
903
903
  if (props.action || props.request) return;
904
904
  console.warn("[GrFileUpload] не задан ни `action`, ни `request`: отправлять файлы некуда.");
905
905
  });