@feugene/granularity 0.36.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 (363) 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-DBi0GVce.js.map +1 -1
  52. package/dist/chunks/config-DBmdgoVf.js.map +1 -0
  53. package/dist/chunks/config-DCq4JySZ.js.map +1 -1
  54. package/dist/chunks/config-DGC00bTp.js.map +1 -1
  55. package/dist/chunks/config-DIDz_E5m.js.map +1 -1
  56. package/dist/chunks/config-DM0lsduD.js.map +1 -1
  57. package/dist/chunks/config-DNDgp9bB.js.map +1 -1
  58. package/dist/chunks/config-DOYz_SVK.js.map +1 -1
  59. package/dist/chunks/config-DRbojEzO.js.map +1 -1
  60. package/dist/chunks/config-DUNH02Fg.js.map +1 -1
  61. package/dist/chunks/config-DUbbGcfw.js.map +1 -1
  62. package/dist/chunks/config-DVCNvhIG.js.map +1 -0
  63. package/dist/chunks/config-DWL81-aM.js.map +1 -1
  64. package/dist/chunks/config-DZCUPHPU.js.map +1 -1
  65. package/dist/chunks/config-DeyT9dJl.js.map +1 -1
  66. package/dist/chunks/config-DolULhjJ.js.map +1 -1
  67. package/dist/chunks/config-DpAYidyY.js.map +1 -0
  68. package/dist/chunks/config-Droqn55j.js.map +1 -1
  69. package/dist/chunks/config-DwABJHEo.js.map +1 -1
  70. package/dist/chunks/config-E1cTyRVV.js.map +1 -1
  71. package/dist/chunks/config-MmPym-Z7.js.map +1 -0
  72. package/dist/chunks/config-QaIc_gRa.js.map +1 -1
  73. package/dist/chunks/config-Yy67uWHY.js.map +1 -1
  74. package/dist/chunks/config-Z5LeUXys.js.map +1 -1
  75. package/dist/chunks/config-_jbgsFpw.js.map +1 -1
  76. package/dist/chunks/config-eXB87DOi.js.map +1 -1
  77. package/dist/chunks/config-rLkc9Zn2.js.map +1 -1
  78. package/dist/chunks/{context-CTbuwcYs.js → context-CPMRfwVr.js} +1 -1
  79. package/dist/chunks/{context-CTbuwcYs.js.map → context-CPMRfwVr.js.map} +1 -1
  80. package/dist/chunks/{grRadioStyles-DGL2QLy6.js → grRadioStyles-BwRyCjQQ.js} +4 -2
  81. package/dist/chunks/{grRadioStyles-DGL2QLy6.js.map → grRadioStyles-BwRyCjQQ.js.map} +1 -1
  82. package/dist/chunks/{granular-provider-Bp_BCBnr.js → granular-provider-DP2gk0oa.js} +9 -8
  83. package/dist/chunks/{granular-provider-Bp_BCBnr.js.map → granular-provider-DP2gk0oa.js.map} +1 -1
  84. package/dist/chunks/{overlayStack-0CZS99Da.js → overlayStack-B_UFaFzk.js} +65 -24
  85. package/dist/chunks/overlayStack-B_UFaFzk.js.map +1 -0
  86. package/dist/chunks/{renamedProp-BwcN-SJg.js → renamedProp-Dy96tT-F.js} +1 -1
  87. package/dist/chunks/{renamedProp-BwcN-SJg.js.map → renamedProp-Dy96tT-F.js.map} +1 -1
  88. package/dist/chunks/{useModalOverlay-BnAGZpcI.js → useModalOverlay-BwX8WEcI.js} +3 -3
  89. package/dist/chunks/{useModalOverlay-BnAGZpcI.js.map → useModalOverlay-BwX8WEcI.js.map} +1 -1
  90. package/dist/chunks/{usePortalTarget-C0p-mhaM.js → usePortalTarget-BhrRgdqW.js} +1 -1
  91. package/dist/chunks/{usePortalTarget-C0p-mhaM.js.map → usePortalTarget-BhrRgdqW.js.map} +1 -1
  92. package/dist/chunks/{validation-5HhpanPP.js → validation-BDjqsuGB.js} +1 -1
  93. package/dist/chunks/{validation-5HhpanPP.js.map → validation-BDjqsuGB.js.map} +1 -1
  94. package/dist/components/GrAlert/chunks/{GrAlert-FAVf-ksH.js → GrAlert-D72y1IEh.js} +1 -1
  95. package/dist/components/GrAlert/chunks/{GrAlert-FAVf-ksH.js.map → GrAlert-D72y1IEh.js.map} +1 -1
  96. package/dist/components/GrAlert/index.js +1 -1
  97. package/dist/components/GrAutocomplete/chunks/{GrAutocomplete-BQsSE7sj.js → GrAutocomplete-BpmFmpKs.js} +4 -6
  98. package/dist/components/GrAutocomplete/chunks/{GrAutocomplete-BQsSE7sj.js.map → GrAutocomplete-BpmFmpKs.js.map} +1 -1
  99. package/dist/components/GrAutocomplete/index.js +1 -1
  100. package/dist/components/GrAvatar/chunks/{GrAvatar-CNmLmgcr.js → GrAvatar-dWEXiCJG.js} +1 -1
  101. package/dist/components/GrAvatar/chunks/{GrAvatar-CNmLmgcr.js.map → GrAvatar-dWEXiCJG.js.map} +1 -1
  102. package/dist/components/GrAvatar/index.js +1 -1
  103. package/dist/components/GrBadge/chunks/{GrBadge-DpUDXKbq.js → GrBadge-DBeQXEir.js} +2 -2
  104. package/dist/components/GrBadge/chunks/{GrBadge-DpUDXKbq.js.map → GrBadge-DBeQXEir.js.map} +1 -1
  105. package/dist/components/GrBadge/index.js +1 -1
  106. package/dist/components/GrBadgeWrap/chunks/{GrBadgeWrap-B-A3PRkE.js → GrBadgeWrap-wdfxaXiu.js} +3 -1
  107. package/dist/components/GrBadgeWrap/chunks/{GrBadgeWrap-B-A3PRkE.js.map → GrBadgeWrap-wdfxaXiu.js.map} +1 -1
  108. package/dist/components/GrBadgeWrap/index.js +1 -1
  109. package/dist/components/GrBottomNav/chunks/{GrBottomNav-wtFatLjB.js → GrBottomNav-nE08pVUJ.js} +1 -1
  110. package/dist/components/GrBottomNav/chunks/{GrBottomNav-wtFatLjB.js.map → GrBottomNav-nE08pVUJ.js.map} +1 -1
  111. package/dist/components/GrBottomNav/index.js +1 -1
  112. package/dist/components/GrBreadcrumbs/chunks/{GrBreadcrumbs-DRDNan_n.js → GrBreadcrumbs-DOpwY2EF.js} +3 -3
  113. package/dist/components/GrBreadcrumbs/chunks/{GrBreadcrumbs-DRDNan_n.js.map → GrBreadcrumbs-DOpwY2EF.js.map} +1 -1
  114. package/dist/components/GrBreadcrumbs/index.js +1 -1
  115. package/dist/components/GrButton/chunks/{GrButton-7GP0zObj.js → GrButton-CS4TqMtG.js} +1 -1
  116. package/dist/components/GrButton/chunks/{GrButton-7GP0zObj.js.map → GrButton-CS4TqMtG.js.map} +1 -1
  117. package/dist/components/GrButton/index.js +1 -1
  118. package/dist/components/GrButtonGroup/chunks/GrButtonGroup-CKyiAV8K.js.map +1 -1
  119. package/dist/components/GrButtonGroup/index.js +1 -1
  120. package/dist/components/GrCard/chunks/{GrCard-BttXz1pQ.js → GrCard-Ck5--lMF.js} +2 -2
  121. package/dist/components/GrCard/chunks/{GrCard-BttXz1pQ.js.map → GrCard-Ck5--lMF.js.map} +1 -1
  122. package/dist/components/GrCard/index.js +1 -1
  123. package/dist/components/GrCheckbox/chunks/{GrCheckbox-CEcHIsXM.js → GrCheckbox-Dp201frb.js} +1 -1
  124. package/dist/components/GrCheckbox/chunks/{GrCheckbox-CEcHIsXM.js.map → GrCheckbox-Dp201frb.js.map} +1 -1
  125. package/dist/components/GrCheckbox/index.js +1 -1
  126. package/dist/components/GrCheckboxGroup/chunks/{GrCheckboxGroup-BOwrVcFr.js → GrCheckboxGroup-IpqG5qwm.js} +2 -2
  127. package/dist/components/GrCheckboxGroup/chunks/{GrCheckboxGroup-BOwrVcFr.js.map → GrCheckboxGroup-IpqG5qwm.js.map} +1 -1
  128. package/dist/components/GrCheckboxGroup/index.js +1 -1
  129. package/dist/components/GrChip/chunks/{GrChip-BTivtwff.js → GrChip-CKqyzYcv.js} +10 -7
  130. package/dist/components/GrChip/chunks/{GrChip-BTivtwff.js.map → GrChip-CKqyzYcv.js.map} +1 -1
  131. package/dist/components/GrChip/index.js +1 -1
  132. package/dist/components/GrChipGroup/chunks/{GrChipGroup-C78Vcwos.js → GrChipGroup-dDGwnC04.js} +1 -1
  133. package/dist/components/GrChipGroup/chunks/{GrChipGroup-C78Vcwos.js.map → GrChipGroup-dDGwnC04.js.map} +1 -1
  134. package/dist/components/GrChipGroup/index.js +1 -1
  135. package/dist/components/GrCodeBlock/chunks/{GrCodeBlock-Dp0eEBTZ.js → GrCodeBlock-BUOwKwQE.js} +2 -2
  136. package/dist/components/GrCodeBlock/chunks/{GrCodeBlock-Dp0eEBTZ.js.map → GrCodeBlock-BUOwKwQE.js.map} +1 -1
  137. package/dist/components/GrCodeBlock/index.js +1 -1
  138. package/dist/components/GrCollapse/chunks/{GrCollapse-BlW6ybdL.js → GrCollapse-DWH3QAnU.js} +6 -5
  139. package/dist/components/GrCollapse/chunks/{GrCollapse-BlW6ybdL.js.map → GrCollapse-DWH3QAnU.js.map} +1 -1
  140. package/dist/components/GrCollapse/index.js +1 -1
  141. package/dist/components/GrColorPicker/chunks/{GrColorPicker-B-L4CWMt.js → GrColorPicker-BNtpj_P6.js} +4 -4
  142. package/dist/components/GrColorPicker/chunks/{GrColorPicker-B-L4CWMt.js.map → GrColorPicker-BNtpj_P6.js.map} +1 -1
  143. package/dist/components/GrColorPicker/index.js +1 -1
  144. package/dist/components/GrCommandPalette/chunks/{GrCommandPalette-8HkYmMVP.js → GrCommandPalette-BVZEd4yy.js} +7 -7
  145. package/dist/components/GrCommandPalette/chunks/{GrCommandPalette-8HkYmMVP.js.map → GrCommandPalette-BVZEd4yy.js.map} +1 -1
  146. package/dist/components/GrCommandPalette/index.js +1 -1
  147. package/dist/components/GrConfigProvider/chunks/{GrConfigProvider-BF7R3hgg.js → GrConfigProvider-t9x2UToH.js} +13 -12
  148. package/dist/components/GrConfigProvider/chunks/{GrConfigProvider-BF7R3hgg.js.map → GrConfigProvider-t9x2UToH.js.map} +1 -1
  149. package/dist/components/GrConfigProvider/index.js +2 -2
  150. package/dist/components/GrConfirmDialog/chunks/{GrConfirmDialog-CZEO2JR4.js → GrConfirmDialog-K5ht2cYq.js} +4 -4
  151. package/dist/components/GrConfirmDialog/chunks/{GrConfirmDialog-CZEO2JR4.js.map → GrConfirmDialog-K5ht2cYq.js.map} +1 -1
  152. package/dist/components/GrConfirmDialog/index.js +1 -1
  153. package/dist/components/GrContextMenu/chunks/{GrContextMenu-DlFWm0eW.js → GrContextMenu-Dd2tgMoL.js} +1 -1
  154. package/dist/components/GrContextMenu/chunks/{GrContextMenu-DlFWm0eW.js.map → GrContextMenu-Dd2tgMoL.js.map} +1 -1
  155. package/dist/components/GrContextMenu/index.js +1 -1
  156. package/dist/components/GrDataTable/chunks/{GrDataTable-4JAgOQ-7.js → GrDataTable-BYYG_XZA.js} +5 -5
  157. package/dist/components/GrDataTable/chunks/{GrDataTable-4JAgOQ-7.js.map → GrDataTable-BYYG_XZA.js.map} +1 -1
  158. package/dist/components/GrDataTable/index.js +1 -1
  159. package/dist/components/GrDelta/chunks/{GrDelta-BZwkgQW-.js → GrDelta-BpfqebEV.js} +0 -0
  160. package/dist/components/GrDelta/chunks/{GrDelta-BZwkgQW-.js.map → GrDelta-BpfqebEV.js.map} +1 -1
  161. package/dist/components/GrDelta/index.js +1 -1
  162. package/dist/components/GrDescriptionList/chunks/{GrDescriptionList-BMeCgFV3.js → GrDescriptionList-D8ANFpn_.js} +2 -2
  163. package/dist/components/GrDescriptionList/chunks/{GrDescriptionList-BMeCgFV3.js.map → GrDescriptionList-D8ANFpn_.js.map} +1 -1
  164. package/dist/components/GrDescriptionList/index.js +2 -2
  165. package/dist/components/GrDialog/chunks/{GrDialog-CKNbnxwO.js → GrDialog-CeJubnKJ.js} +3 -3
  166. package/dist/components/GrDialog/chunks/{GrDialog-CKNbnxwO.js.map → GrDialog-CeJubnKJ.js.map} +1 -1
  167. package/dist/components/GrDialog/index.js +1 -1
  168. package/dist/components/GrDialogService/chunks/{GrDialogService-Ut8iiBQh.js → GrDialogService-BArvw1DV.js} +9 -8
  169. package/dist/components/GrDialogService/chunks/{GrDialogService-Ut8iiBQh.js.map → GrDialogService-BArvw1DV.js.map} +1 -1
  170. package/dist/components/GrDialogService/index.js +1 -1
  171. package/dist/components/GrDivider/chunks/{GrDivider-BXavGcMX.js → GrDivider-DxA-zV25.js} +1 -1
  172. package/dist/components/GrDivider/chunks/{GrDivider-BXavGcMX.js.map → GrDivider-DxA-zV25.js.map} +1 -1
  173. package/dist/components/GrDivider/index.js +1 -1
  174. package/dist/components/GrDrawer/chunks/{GrDrawer-xfoy-MCj.js → GrDrawer-BBHNgeH0.js} +5 -5
  175. package/dist/components/GrDrawer/chunks/{GrDrawer-xfoy-MCj.js.map → GrDrawer-BBHNgeH0.js.map} +1 -1
  176. package/dist/components/GrDrawer/index.js +1 -1
  177. package/dist/components/GrDropdown/chunks/{GrDropdown-7r772-Cq.js → GrDropdown-CUlviqMi.js} +6 -8
  178. package/dist/components/GrDropdown/chunks/{GrDropdown-7r772-Cq.js.map → GrDropdown-CUlviqMi.js.map} +1 -1
  179. package/dist/components/GrDropdown/index.js +1 -1
  180. package/dist/components/GrDropdownMenu/chunks/{GrDropdownMenu-DNurbsWc.js → GrDropdownMenu-COOR1LCs.js} +1 -1
  181. package/dist/components/GrDropdownMenu/chunks/{GrDropdownMenu-DNurbsWc.js.map → GrDropdownMenu-COOR1LCs.js.map} +1 -1
  182. package/dist/components/GrDropdownMenu/chunks/GrDropdownMenuList-B33ZzwfB.js.map +1 -1
  183. package/dist/components/GrDropdownMenu/index.js +1 -1
  184. package/dist/components/GrEmptyState/chunks/{GrEmptyState-RqsWvgI9.js → GrEmptyState-BbvwE-E0.js} +2 -2
  185. package/dist/components/GrEmptyState/chunks/{GrEmptyState-RqsWvgI9.js.map → GrEmptyState-BbvwE-E0.js.map} +1 -1
  186. package/dist/components/GrEmptyState/index.js +1 -1
  187. package/dist/components/GrFilePreview/chunks/{GrFilePreview-C9Z7hMK8.js → GrFilePreview-PabkLgYX.js} +1 -1
  188. package/dist/components/GrFilePreview/chunks/{GrFilePreview-C9Z7hMK8.js.map → GrFilePreview-PabkLgYX.js.map} +1 -1
  189. package/dist/components/GrFilePreview/index.js +1 -1
  190. package/dist/components/GrFileUpload/chunks/{GrFileUpload-C0ROpmOY.js → GrFileUpload-BwMR71zN.js} +4 -4
  191. package/dist/components/GrFileUpload/chunks/{GrFileUpload-C0ROpmOY.js.map → GrFileUpload-BwMR71zN.js.map} +1 -1
  192. package/dist/components/GrFileUpload/index.js +1 -1
  193. package/dist/components/GrForm/chunks/{GrForm-CrnfCsgj.js → GrForm-xTtavR-K.js} +1 -1
  194. package/dist/components/GrForm/chunks/{GrForm-CrnfCsgj.js.map → GrForm-xTtavR-K.js.map} +1 -1
  195. package/dist/components/GrForm/index.js +2 -2
  196. package/dist/components/GrFormField/chunks/{GrFormField-DSylU7IU.js → GrFormField-DO61vxpS.js} +2 -2
  197. package/dist/components/GrFormField/chunks/{GrFormField-DSylU7IU.js.map → GrFormField-DO61vxpS.js.map} +1 -1
  198. package/dist/components/GrFormField/index.js +1 -1
  199. package/dist/components/GrFormFile/chunks/{GrFormFile-B1jGZyIj.js → GrFormFile-Dlxx-9zi.js} +3 -3
  200. package/dist/components/GrFormFile/chunks/{GrFormFile-B1jGZyIj.js.map → GrFormFile-Dlxx-9zi.js.map} +1 -1
  201. package/dist/components/GrFormFile/index.js +1 -1
  202. package/dist/components/GrFormSection/chunks/{GrFormSection-ejieOg9H.js → GrFormSection-DV1S6R_N.js} +1 -1
  203. package/dist/components/GrFormSection/chunks/{GrFormSection-ejieOg9H.js.map → GrFormSection-DV1S6R_N.js.map} +1 -1
  204. package/dist/components/GrFormSection/index.js +1 -1
  205. package/dist/components/GrIcon/chunks/{GrIcon-Dmf0c9ba.js → GrIcon-DTZIgmje.js} +1 -1
  206. package/dist/components/GrIcon/chunks/{GrIcon-Dmf0c9ba.js.map → GrIcon-DTZIgmje.js.map} +1 -1
  207. package/dist/components/GrIcon/index.js +1 -1
  208. package/dist/components/GrImageViewer/chunks/{GrImageViewer--BU8yrfx.js → GrImageViewer-BjYw-uTF.js} +2 -4
  209. package/dist/components/GrImageViewer/chunks/{GrImageViewer--BU8yrfx.js.map → GrImageViewer-BjYw-uTF.js.map} +1 -1
  210. package/dist/components/GrImageViewer/index.js +1 -1
  211. package/dist/components/GrInput/chunks/{GrInput-CJ7eu3fR.js → GrInput-TFeBm3gQ.js} +1 -1
  212. package/dist/components/GrInput/chunks/{GrInput-CJ7eu3fR.js.map → GrInput-TFeBm3gQ.js.map} +1 -1
  213. package/dist/components/GrInput/index.js +1 -1
  214. package/dist/components/GrInputTag/chunks/{GrInputTag-ByD9NugQ.js → GrInputTag-DhfUNOA5.js} +3 -3
  215. package/dist/components/GrInputTag/chunks/{GrInputTag-ByD9NugQ.js.map → GrInputTag-DhfUNOA5.js.map} +1 -1
  216. package/dist/components/GrInputTag/index.js +1 -1
  217. package/dist/components/GrJsonViewer/chunks/{GrJsonViewer-BXG7DdTe.js → GrJsonViewer-CdtmUpZ3.js} +6 -6
  218. package/dist/components/GrJsonViewer/chunks/{GrJsonViewer-BXG7DdTe.js.map → GrJsonViewer-CdtmUpZ3.js.map} +1 -1
  219. package/dist/components/GrJsonViewer/index.js +2 -2
  220. package/dist/components/GrKbd/chunks/{GrKbd-D2ga1H9i.js → GrKbd-D_a1mPLe.js} +1 -1
  221. package/dist/components/GrKbd/chunks/{GrKbd-D2ga1H9i.js.map → GrKbd-D_a1mPLe.js.map} +1 -1
  222. package/dist/components/GrKbd/index.js +1 -1
  223. package/dist/components/GrLink/chunks/{GrLink-DYXw3W9w.js → GrLink-DwWErumU.js} +2 -2
  224. package/dist/components/GrLink/chunks/{GrLink-DYXw3W9w.js.map → GrLink-DwWErumU.js.map} +1 -1
  225. package/dist/components/GrLink/index.js +2 -2
  226. package/dist/components/GrList/chunks/{GrList-B_CRJB4c.js → GrList-Unya-LXb.js} +3 -3
  227. package/dist/components/GrList/chunks/{GrList-B_CRJB4c.js.map → GrList-Unya-LXb.js.map} +1 -1
  228. package/dist/components/GrList/index.js +1 -1
  229. package/dist/components/GrLoading/chunks/{GrLoading-CMD3Ri9P.js → GrLoading-BDrlrup_.js} +1 -1
  230. package/dist/components/GrLoading/chunks/{GrLoading-CMD3Ri9P.js.map → GrLoading-BDrlrup_.js.map} +1 -1
  231. package/dist/components/GrLoading/index.js +1 -1
  232. package/dist/components/GrModal/chunks/{GrModal-DixnhJcu.js → GrModal-xIWaJozo.js} +4 -4
  233. package/dist/components/GrModal/chunks/{GrModal-DixnhJcu.js.map → GrModal-xIWaJozo.js.map} +1 -1
  234. package/dist/components/GrModal/index.js +1 -1
  235. package/dist/components/GrNavbar/chunks/{GrNavbar-Dr8e5kW-.js → GrNavbar-BRGuksiy.js} +3 -3
  236. package/dist/components/GrNavbar/chunks/{GrNavbar-Dr8e5kW-.js.map → GrNavbar-BRGuksiy.js.map} +1 -1
  237. package/dist/components/GrNavbar/index.js +1 -1
  238. package/dist/components/GrNumberInput/chunks/{GrNumberInput-DQ59YICu.js → GrNumberInput-BqPydXpK.js} +7 -9
  239. package/dist/components/GrNumberInput/chunks/{GrNumberInput-DQ59YICu.js.map → GrNumberInput-BqPydXpK.js.map} +1 -1
  240. package/dist/components/GrNumberInput/index.js +2 -2
  241. package/dist/components/GrPagination/chunks/{GrPagination-68iyAwQz.js → GrPagination-DhbNZHEF.js} +4 -4
  242. package/dist/components/GrPagination/chunks/{GrPagination-68iyAwQz.js.map → GrPagination-DhbNZHEF.js.map} +1 -1
  243. package/dist/components/GrPagination/index.js +1 -1
  244. package/dist/components/GrPopover/chunks/{GrPopover-DEFxDffj.js → GrPopover-BakLcWkX.js} +3 -3
  245. package/dist/components/GrPopover/chunks/{GrPopover-DEFxDffj.js.map → GrPopover-BakLcWkX.js.map} +1 -1
  246. package/dist/components/GrPopover/index.js +2 -2
  247. package/dist/components/GrProgressBar/chunks/{GrProgressBar-Cd7AaJtR.js → GrProgressBar-C3NRBqIP.js} +2 -2
  248. package/dist/components/GrProgressBar/chunks/{GrProgressBar-Cd7AaJtR.js.map → GrProgressBar-C3NRBqIP.js.map} +1 -1
  249. package/dist/components/GrProgressBar/index.js +1 -1
  250. package/dist/components/GrProgressCircle/chunks/{GrProgressCircle-D3yWXYDa.js → GrProgressCircle-CdvbINQc.js} +2 -2
  251. package/dist/components/GrProgressCircle/chunks/{GrProgressCircle-D3yWXYDa.js.map → GrProgressCircle-CdvbINQc.js.map} +1 -1
  252. package/dist/components/GrProgressCircle/index.js +1 -1
  253. package/dist/components/GrPromptDialog/chunks/{GrPromptDialog-Ckeombia.js → GrPromptDialog-C9Y1ifE_.js} +8 -8
  254. package/dist/components/GrPromptDialog/chunks/{GrPromptDialog-Ckeombia.js.map → GrPromptDialog-C9Y1ifE_.js.map} +1 -1
  255. package/dist/components/GrPromptDialog/index.js +1 -1
  256. package/dist/components/GrRadio/chunks/{GrRadio-Aq3v8XgG.js → GrRadio-B1776V9D.js} +2 -2
  257. package/dist/components/GrRadio/chunks/{GrRadio-Aq3v8XgG.js.map → GrRadio-B1776V9D.js.map} +1 -1
  258. package/dist/components/GrRadio/index.js +2 -2
  259. package/dist/components/GrRadioGroup/chunks/{GrRadioGroup-y9LVdTWh.js → GrRadioGroup-UgitrBFl.js} +2 -2
  260. package/dist/components/GrRadioGroup/chunks/{GrRadioGroup-y9LVdTWh.js.map → GrRadioGroup-UgitrBFl.js.map} +1 -1
  261. package/dist/components/GrRadioGroup/index.js +1 -1
  262. package/dist/components/GrRating/chunks/{GrRating-IEiTOdnF.js → GrRating-DTriyyqG.js} +1 -1
  263. package/dist/components/GrRating/chunks/{GrRating-IEiTOdnF.js.map → GrRating-DTriyyqG.js.map} +1 -1
  264. package/dist/components/GrRating/index.js +1 -1
  265. package/dist/components/GrResponseErrorBanner/chunks/{GrResponseErrorBanner-DMeOWlzj.js → GrResponseErrorBanner-NEEJZ8zi.js} +2 -2
  266. package/dist/components/GrResponseErrorBanner/chunks/{GrResponseErrorBanner-DMeOWlzj.js.map → GrResponseErrorBanner-NEEJZ8zi.js.map} +1 -1
  267. package/dist/components/GrResponseErrorBanner/chunks/{GrResponseErrorBanner-CBVRpgIG.js → GrResponseErrorBanner-ZvBvEQDZ.js} +1 -1
  268. package/dist/components/GrResponseErrorBanner/chunks/{GrResponseErrorBanner-CBVRpgIG.js.map → GrResponseErrorBanner-ZvBvEQDZ.js.map} +1 -1
  269. package/dist/components/GrResponseErrorBanner/index.js +2 -2
  270. package/dist/components/GrSegmented/chunks/{GrSegmented-CB-VR-yL.js → GrSegmented-NKTi9bMG.js} +1 -1
  271. package/dist/components/GrSegmented/chunks/{GrSegmented-CB-VR-yL.js.map → GrSegmented-NKTi9bMG.js.map} +1 -1
  272. package/dist/components/GrSegmented/index.js +1 -1
  273. package/dist/components/GrSelect/chunks/{GrSelect-Bm3Jugx8.js → GrSelect-Do1iAyp1.js} +6 -6
  274. package/dist/components/GrSelect/chunks/{GrSelect-Bm3Jugx8.js.map → GrSelect-Do1iAyp1.js.map} +1 -1
  275. package/dist/components/GrSelect/index.js +1 -1
  276. package/dist/components/GrSidebar/chunks/{GrSidebar-alkwBUzL.js → GrSidebar-DoKLlHSw.js} +2 -2
  277. package/dist/components/GrSidebar/chunks/{GrSidebar-alkwBUzL.js.map → GrSidebar-DoKLlHSw.js.map} +1 -1
  278. package/dist/components/GrSidebar/index.js +1 -1
  279. package/dist/components/GrSkeleton/chunks/GrSkeleton-CgfXxPQ2.js.map +1 -1
  280. package/dist/components/GrSlider/chunks/{GrSlider-DM6W6U9c.js → GrSlider-Db-jACXz.js} +6 -4
  281. package/dist/components/GrSlider/chunks/{GrSlider-DM6W6U9c.js.map → GrSlider-Db-jACXz.js.map} +1 -1
  282. package/dist/components/GrSlider/index.js +1 -1
  283. package/dist/components/GrSortableList/chunks/{GrSortableList-HyKX--rO.js → GrSortableList-CQCaWivn.js} +1 -1
  284. package/dist/components/GrSortableList/chunks/{GrSortableList-HyKX--rO.js.map → GrSortableList-CQCaWivn.js.map} +1 -1
  285. package/dist/components/GrSortableList/index.js +1 -1
  286. package/dist/components/GrSplitter/chunks/{GrSplitter-MltjaADn.js → GrSplitter-C-XQzq7q.js} +1 -1
  287. package/dist/components/GrSplitter/chunks/{GrSplitter-MltjaADn.js.map → GrSplitter-C-XQzq7q.js.map} +1 -1
  288. package/dist/components/GrSplitter/index.js +1 -1
  289. package/dist/components/GrStatistic/chunks/{GrStatistic-BoLkXw7F.js → GrStatistic-C1_nY4Gc.js} +2 -2
  290. package/dist/components/GrStatistic/chunks/{GrStatistic-BoLkXw7F.js.map → GrStatistic-C1_nY4Gc.js.map} +1 -1
  291. package/dist/components/GrStatistic/index.js +1 -1
  292. package/dist/components/GrSteps/chunks/{GrSteps-CpGHXLOc.js → GrSteps-DXj7m-WO.js} +2 -2
  293. package/dist/components/GrSteps/chunks/{GrSteps-CpGHXLOc.js.map → GrSteps-DXj7m-WO.js.map} +1 -1
  294. package/dist/components/GrSteps/index.js +1 -1
  295. package/dist/components/GrSwitch/chunks/{GrSwitch-7Oe5QfQZ.js → GrSwitch-CriHWT2A.js} +1 -1
  296. package/dist/components/GrSwitch/chunks/{GrSwitch-7Oe5QfQZ.js.map → GrSwitch-CriHWT2A.js.map} +1 -1
  297. package/dist/components/GrSwitch/index.js +1 -1
  298. package/dist/components/GrTabPanels/chunks/{GrTabPanels-BZQS8-JM.js → GrTabPanels-5zsbqS1v.js} +1 -1
  299. package/dist/components/GrTabPanels/chunks/{GrTabPanels-BZQS8-JM.js.map → GrTabPanels-5zsbqS1v.js.map} +1 -1
  300. package/dist/components/GrTabPanels/index.js +1 -1
  301. package/dist/components/GrTable/chunks/{GrTable-jhUTczjv.js → GrTable-iwzHvlMC.js} +1 -1
  302. package/dist/components/GrTable/chunks/{GrTable-jhUTczjv.js.map → GrTable-iwzHvlMC.js.map} +1 -1
  303. package/dist/components/GrTable/index.js +1 -1
  304. package/dist/components/GrTabs/chunks/{GrTabs-CT2nk_HV.js → GrTabs-DHfv67cp.js} +1 -1
  305. package/dist/components/GrTabs/chunks/{GrTabs-CT2nk_HV.js.map → GrTabs-DHfv67cp.js.map} +1 -1
  306. package/dist/components/GrTabs/index.js +1 -1
  307. package/dist/components/GrTextarea/chunks/{GrTextarea-DinXG12-.js → GrTextarea-BII3w61K.js} +1 -1
  308. package/dist/components/GrTextarea/chunks/{GrTextarea-DinXG12-.js.map → GrTextarea-BII3w61K.js.map} +1 -1
  309. package/dist/components/GrTextarea/index.js +1 -1
  310. package/dist/components/GrTimeline/chunks/{GrTimeline-BiHpArsg.js → GrTimeline-Bs60huw0.js} +2 -2
  311. package/dist/components/GrTimeline/chunks/{GrTimeline-BiHpArsg.js.map → GrTimeline-Bs60huw0.js.map} +1 -1
  312. package/dist/components/GrTimeline/index.js +1 -1
  313. package/dist/components/GrToaster/chunks/{GrToaster-COXIBKzq.js → GrToaster-D-sV-9of.js} +4 -4
  314. package/dist/components/GrToaster/chunks/{GrToaster-COXIBKzq.js.map → GrToaster-D-sV-9of.js.map} +1 -1
  315. package/dist/components/GrToaster/index.js +1 -1
  316. package/dist/components/GrTooltip/chunks/{GrTooltip-uYETdbCD.js → GrTooltip-BUiTbROv.js} +3 -3
  317. package/dist/components/GrTooltip/chunks/{GrTooltip-uYETdbCD.js.map → GrTooltip-BUiTbROv.js.map} +1 -1
  318. package/dist/components/GrTooltip/index.js +1 -1
  319. package/dist/components/GrTree/chunks/{GrTree-Ci6CZfKR.js → GrTree-CkELQwR8.js} +1 -2
  320. package/dist/components/GrTree/chunks/{GrTree-Ci6CZfKR.js.map → GrTree-CkELQwR8.js.map} +1 -1
  321. package/dist/components/GrTree/index.js +1 -1
  322. package/dist/components/GrTreeSelect/chunks/{GrTreeSelect-MGsyvkJV.js → GrTreeSelect-DurwZ7Cz.js} +4 -4
  323. package/dist/components/GrTreeSelect/chunks/{GrTreeSelect-MGsyvkJV.js.map → GrTreeSelect-DurwZ7Cz.js.map} +1 -1
  324. package/dist/components/GrTreeSelect/index.js +1 -1
  325. package/dist/components/GrValue/chunks/GrValue-ezkQM05Q.js.map +1 -1
  326. package/dist/composables/useFloating.js +1 -1
  327. package/dist/composables/useGrComponentConfig.js +1 -1
  328. package/dist/composables/useOverlayLayer.js +1 -1
  329. package/dist/composables/usePortalTarget.js +1 -1
  330. package/dist/composables/useTheme.js +1 -1
  331. package/dist/composables/useTheme.js.map +1 -1
  332. package/dist/composables/useToast.js +1 -1
  333. package/dist/composables/useToast.js.map +1 -1
  334. package/dist/composables/useVirtualList.js +3 -5
  335. package/dist/composables/useVirtualList.js.map +1 -1
  336. package/dist/directives/loading.js +1 -1
  337. package/dist/granular-provider-node.js +1 -1
  338. package/dist/granular-provider.js +1 -1
  339. package/dist/index.js +86 -86
  340. package/dist/testing.js +1 -1
  341. package/dist/testing.js.map +1 -1
  342. package/dist/types/components/GrDialog/GrDialog.vue.d.ts +1 -1
  343. package/dist/types/components/GrDrawer/GrDrawer.vue.d.ts +1 -1
  344. package/dist/types/components/GrModal/GrModal.vue.d.ts +1 -1
  345. package/dist/types/internal/devHook.d.ts +53 -0
  346. package/dist/vue/index.js +2 -2
  347. package/dist/vue/index.js.map +1 -1
  348. package/dist/web-types.json +1 -1
  349. package/package.json +16 -16
  350. package/dist/chunks/config-CQLNjc9X2.js.map +0 -1
  351. package/dist/chunks/config-CnYdE3HZ2.js.map +0 -1
  352. package/dist/chunks/config-CuQmUkMw2.js.map +0 -1
  353. package/dist/chunks/config-DBmdgoVf2.js.map +0 -1
  354. package/dist/chunks/config-DVCNvhIG2.js.map +0 -1
  355. package/dist/chunks/config-DpAYidyY2.js.map +0 -1
  356. package/dist/chunks/config-MmPym-Z72.js.map +0 -1
  357. package/dist/chunks/overlayStack-0CZS99Da.js.map +0 -1
  358. /package/dist/chunks/{config-CQLNjc9X2.js → config-CQLNjc9X.js} +0 -0
  359. /package/dist/chunks/{config-CnYdE3HZ2.js → config-CnYdE3HZ.js} +0 -0
  360. /package/dist/chunks/{config-DBmdgoVf2.js → config-DBmdgoVf.js} +0 -0
  361. /package/dist/chunks/{config-DVCNvhIG2.js → config-DVCNvhIG.js} +0 -0
  362. /package/dist/chunks/{config-DpAYidyY2.js → config-DpAYidyY.js} +0 -0
  363. /package/dist/chunks/{config-MmPym-Z72.js → config-MmPym-Z7.js} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"useToast.js","names":[],"sources":["../../src/composables/useToast.ts"],"sourcesContent":["import { computed, hasInjectionContext, inject, reactive } from 'vue'\nimport type { App, InjectionKey } from 'vue'\n\nimport type { GrButtonSize, GrButtonVariant } from '../components/GrButton/grButtonStyles'\nimport type { GrTone } from '../components/shared/tones'\n\nexport type GrToastTone = GrTone\n\n/**\n * Опциональная action-кнопка тоста: `label` — текст, `onClick` — обработчик.\n * По клику вызывается `onClick`, затем тост закрывается (если `dismissOnClick`\n * не установлен в `false`). `size`/`variant` настраивают вид кнопки.\n */\nexport type ToastAction = {\n label: string\n onClick: () => void\n /** Закрывать ли тост после клика по действию. По умолчанию `true`. */\n dismissOnClick?: boolean\n /** Размер кнопки действия. По умолчанию `sm`. */\n size?: GrButtonSize\n /** Вариант кнопки действия. По умолчанию `outline`. */\n variant?: GrButtonVariant\n}\n\nexport type ToastInput = {\n title: string\n message?: string\n tone?: GrToastTone\n /**\n * Автозакрытие через N мс. `0` или отрицательное значение — «навсегда»\n * (до явного вызова `dismiss(id)` / `clear()`). По умолчанию: `3500`.\n */\n timeoutMs?: number\n /** Одна action-кнопка в теле тоста (шорткат для `actions: [action]`). */\n action?: ToastAction\n /** Несколько action-кнопок в теле тоста. Рендерятся после `action`. */\n actions?: ToastAction[]\n /**\n * Схлопывать повтор: `push` с уже занятым ключом обновляет **живой** тост\n * и перезапускает его автозакрытие вместо того, чтобы завести второй.\n *\n * Ключ действует только пока тост на экране. Это не то же самое, что помнить\n * последнее показанное: повтор действия с тем же текстом обязан показаться\n * снова, иначе второе «Сохранено» пропадёт молча.\n */\n dedupeKey?: string\n}\n\n/**\n * Сообщения для `promise`. Строка — шорткат для `{ title }`; функция получает\n * результат промиса (или причину отказа), чтобы подставить его в текст.\n */\nexport type ToastPromiseMessages<T> = {\n loading: string | ToastInput\n success: string | ToastInput | ((value: T) => string | ToastInput)\n error: string | ToastInput | ((reason: unknown) => string | ToastInput)\n}\n\nexport type Toast = {\n id: string\n title: string\n message?: string\n tone: GrToastTone\n /** Исходный таймаут автозакрытия, мс (`0` — без автозакрытия). Нужен для progress-бара. */\n timeoutMs: number\n /** Одна action-кнопка в теле тоста. */\n action?: ToastAction\n /** Несколько action-кнопок в теле тоста. */\n actions?: ToastAction[]\n /** Ключ схлопывания повторов, если тост создан с ним. */\n dedupeKey?: string\n}\n\nconst DEFAULT_TIMEOUT_MS = 3500\nconst IS_SERVER = typeof window === 'undefined'\n\n// Метаданные таймера автозакрытия с поддержкой pause/resume (WCAG 2.2.1: под\n// курсором/фокусом отсчёт должен останавливаться).\ntype ToastTimer = {\n handle: number | null\n /** Сколько мс осталось до автозакрытия на момент последней паузы/старта. */\n remaining: number\n /** `performance.now()` момента запуска текущего отрезка (для вычисления остатка). */\n startedAt: number\n}\n\nexport type ToastState = {\n toasts: Toast[]\n timers: Map<string, ToastTimer>\n /** Потолок очереди: сверх него самые старые тосты вытесняются. */\n maxToasts: number\n}\n\n/**\n * Потолок очереди по умолчанию. `maxVisible` у `GrToaster` режет только видимые,\n * поэтому без него поток событий (переподключение сокета, цикл ошибок) копил бы\n * очередь и вываливал её на пользователя, когда стек освободится.\n */\nconst DEFAULT_MAX_TOASTS = 20\n\nexport type GranularityToastPluginOptions = {\n /** Потолок очереди. По умолчанию `20`. */\n maxToasts?: number\n}\n\nfunction createToastState(maxToasts = DEFAULT_MAX_TOASTS): ToastState {\n return {\n toasts: reactive<Toast[]>([]),\n timers: new Map<string, ToastTimer>(),\n maxToasts: Math.max(1, Math.trunc(maxToasts)),\n }\n}\n\n/** Ключ provide/inject для app-scoped состояния тостов (устанавливает плагин ниже). */\nexport const GRANULARITY_TOAST_STATE: InjectionKey<ToastState> = Symbol.for('@feugene/granularity/toast-state')\n\n/**\n * Vue-плагин: даёт каждому приложению собственное изолированное состояние тостов\n * через `app.provide`. Обязателен для (а) нескольких Vue-приложений на одной\n * странице (микрофронтенды — иначе делят один стек тостов) и (б) SSR (иначе\n * модульное состояние течёт между запросами).\n *\n * ```ts\n * app.use(granularityToastPlugin)\n * app.use(granularityToastPlugin, { maxToasts: 50 })\n * ```\n */\n// Где-то на странице установлен плагин: фолбэк в синглтон для такого приложения —\n// почти наверняка ошибка вызова, а не осознанный выбор.\nlet appScopedToastProvided = false\nlet contextFallbackWarned = false\n\nexport const granularityToastPlugin = {\n install(app: App, options: GranularityToastPluginOptions = {}) {\n appScopedToastProvided = true\n app.provide(GRANULARITY_TOAST_STATE, createToastState(options.maxToasts))\n },\n}\n\n// Ленивый модульный синглтон — канонический фолбэк для простых SPA без плагина.\nlet moduleToastState: ToastState | null = null\n\n/** Сброс dev-предупреждения о фолбэке. Внутреннее API — нужно тестам. */\nexport function resetToastContextWarning(): void {\n contextFallbackWarned = false\n}\n\nfunction resolveToastState(): ToastState {\n // App-scoped состояние (provide через плагин): setup-контекст ИЛИ\n // `app.runWithContext(() => useToast())` — `hasInjectionContext` покрывает оба,\n // поэтому вызов из router guard / интерцептора достаёт состояние приложения.\n if (hasInjectionContext()) {\n const provided = inject(GRANULARITY_TOAST_STATE, null)\n if (provided)\n return provided\n }\n\n // В SSR модульный фолбэк запрещён: одно mutable-состояние на модуль утекало бы\n // между запросами. Требуем установленный плагин (app.provide).\n if (IS_SERVER) {\n throw new Error(\n '[granularity] useToast requires `app.use(granularityToastPlugin)` during SSR — '\n + 'the module-singleton fallback is disabled server-side to avoid state leaking between requests.',\n )\n }\n\n // Дедуп и текст — прямо под гардом: `__GR_DEV__` разворачивается в условие\n // на сборке, и у потребителя вся ветка выкидывается вместе с сообщением.\n if (\n appScopedToastProvided && !contextFallbackWarned\n && __GR_DEV__\n ) {\n contextFallbackWarned = true\n console.warn(\n '[granularity] useToast() вызван вне setup/inject-контекста: app-scoped состояние '\n + 'granularityToastPlugin недоступно, использован модульный синглтон — эти тосты не попадут '\n + 'в GrToaster приложения. Оберните вызов: app.runWithContext(() => useToast()).',\n )\n }\n\n if (!moduleToastState)\n moduleToastState = createToastState()\n\n return moduleToastState\n}\n\nfunction now(): number {\n return typeof performance !== 'undefined' ? performance.now() : Date.now()\n}\n\nfunction makeId(): string {\n return `${Date.now()}-${Math.random().toString(16).slice(2)}`\n}\n\nexport function useToast() {\n const state = resolveToastState()\n const list = computed(() => state.toasts)\n\n function armTimer(id: string, timer: ToastTimer): void {\n if (timer.remaining <= 0 || typeof window === 'undefined')\n return\n timer.startedAt = now()\n timer.handle = window.setTimeout(() => {\n state.timers.delete(id)\n dismiss(id)\n }, timer.remaining)\n }\n\n function clearTimer(id: string): void {\n const timer = state.timers.get(id)\n if (timer?.handle != null) {\n clearTimeout(timer.handle)\n timer.handle = null\n }\n state.timers.delete(id)\n }\n\n function push(input: ToastInput): string {\n const timeout = input.timeoutMs ?? DEFAULT_TIMEOUT_MS\n\n // Схлопывание ищет тост только среди живых. Помнить последний показанный\n // ключ нельзя: тогда повтор того же действия («Сохранено» второй раз)\n // не показался бы вообще — тост уже ушёл, а ключ ещё занят.\n if (input.dedupeKey !== undefined) {\n const existing = state.toasts.find(item => item.dedupeKey === input.dedupeKey)\n if (existing) {\n // Замена целиком, а не патч: повторный `push` — это законченное\n // высказывание, и `message` от прошлого раза донашивать он не должен.\n applyStage(existing.id, { ...input, tone: input.tone ?? 'info', timeoutMs: timeout })\n return existing.id\n }\n }\n\n const id = makeId()\n const toast: Toast = {\n id,\n title: input.title,\n message: input.message,\n tone: input.tone ?? 'info',\n timeoutMs: timeout > 0 ? timeout : 0,\n action: input.action,\n actions: input.actions,\n dedupeKey: input.dedupeKey,\n }\n\n state.toasts.unshift(toast)\n trimQueue()\n\n if (toast.timeoutMs > 0) {\n const timer: ToastTimer = { handle: null, remaining: toast.timeoutMs, startedAt: now() }\n state.timers.set(id, timer)\n armTimer(id, timer)\n }\n\n return id\n }\n\n // Вытесняем с хвоста — там самые старые: при потоке событий устаревшее\n // уведомление менее ценно, чем свежее. Таймеры снимаем, иначе остались бы\n // висящие `setTimeout` на тосты, которых больше нет.\n //\n // Это флуд-защита уровня состояния, а не очередь показа (`GrToaster` держит\n // видимыми старейших): при переполнении потолка вытеснен может быть и тост,\n // который сейчас на экране, — осознанный компромисс.\n function trimQueue(): void {\n while (state.toasts.length > state.maxToasts) {\n const dropped = state.toasts.pop()\n if (dropped)\n clearTimer(dropped.id)\n }\n }\n\n /**\n * Меняет показанный тост на месте. `timeoutMs` в патче перезапускает таймер\n * (`0` — снова «навсегда»), поэтому «вечный» loading может стать\n * самозакрывающимся success.\n *\n * Возвращает `false`, если тоста уже нет: пользователь мог закрыть его руками,\n * и воскрешать его нельзя.\n */\n function update(id: string, patch: Partial<ToastInput>): boolean {\n const toast = state.toasts.find(item => item.id === id)\n if (!toast)\n return false\n\n if (patch.title !== undefined)\n toast.title = patch.title\n if (patch.message !== undefined)\n toast.message = patch.message\n if (patch.tone !== undefined)\n toast.tone = patch.tone\n if (patch.action !== undefined)\n toast.action = patch.action\n if (patch.actions !== undefined)\n toast.actions = patch.actions\n\n if (patch.timeoutMs !== undefined)\n toast.timeoutMs = rearmTimer(id, patch.timeoutMs)\n\n return true\n }\n\n /** Перезапускает автозакрытие с нового таймаута; `0` и меньше — «навсегда». */\n function rearmTimer(id: string, timeoutMs: number): number {\n clearTimer(id)\n const next = timeoutMs > 0 ? timeoutMs : 0\n\n if (next > 0) {\n const timer: ToastTimer = { handle: null, remaining: next, startedAt: now() }\n state.timers.set(id, timer)\n armTimer(id, timer)\n }\n\n return next\n }\n\n /**\n * Полная замена стадии для `promise()`. В отличие от `update`, поле без\n * значения очищается: успех не должен донашивать `message` и action-кнопки\n * загрузки — патч-семантика оставляла бы их в тосте навсегда.\n */\n function applyStage(id: string, stage: ToastInput & { tone: GrToastTone, timeoutMs: number }): void {\n const toast = state.toasts.find(item => item.id === id)\n if (!toast)\n return\n\n toast.title = stage.title\n toast.message = stage.message\n toast.tone = stage.tone\n toast.action = stage.action\n toast.actions = stage.actions\n toast.timeoutMs = rearmTimer(id, stage.timeoutMs)\n }\n\n /**\n * Один тост на весь жизненный цикл промиса: «загружаем» переписывается в\n * успех или ошибку, а не закрывается ради нового — стек не дёргается.\n *\n * Каждая стадия **заменяет** предыдущую целиком: поле, не заданное в\n * success/error, очищается, а не наследуется от loading.\n *\n * Возвращает исходный промис и **не глотает отказ**: тост не заменяет\n * обработку ошибки, вызывающий по-прежнему обязан её обработать.\n */\n function promise<T>(input: Promise<T>, messages: ToastPromiseMessages<T>): Promise<T> {\n const id = push({ tone: 'info', ...toToastInput(messages.loading), timeoutMs: 0 })\n\n input.then(\n (value) => {\n const stage = resolveMessage(messages.success, value)\n applyStage(id, { ...stage, tone: stage.tone ?? 'success', timeoutMs: stage.timeoutMs ?? DEFAULT_TIMEOUT_MS })\n },\n (reason: unknown) => {\n const stage = resolveMessage(messages.error, reason)\n applyStage(id, { ...stage, tone: stage.tone ?? 'danger', timeoutMs: stage.timeoutMs ?? DEFAULT_TIMEOUT_MS })\n },\n )\n\n return input\n }\n\n /** Останавливает отсчёт автозакрытия, сохраняя остаток (идемпотентно). */\n function pause(id: string): void {\n const timer = state.timers.get(id)\n if (!timer || timer.handle == null)\n return\n\n clearTimeout(timer.handle)\n timer.handle = null\n timer.remaining = Math.max(0, timer.remaining - (now() - timer.startedAt))\n }\n\n /** Возобновляет отсчёт с сохранённого остатка (идемпотентно). */\n function resume(id: string): void {\n const timer = state.timers.get(id)\n if (!timer || timer.handle != null)\n return\n\n armTimer(id, timer)\n }\n\n function dismiss(id: string): void {\n clearTimer(id)\n const index = state.toasts.findIndex(toast => toast.id === id)\n if (index >= 0)\n state.toasts.splice(index, 1)\n }\n\n function clear(): void {\n for (const id of [...state.timers.keys()]) clearTimer(id)\n state.toasts.splice(0, state.toasts.length)\n }\n\n return {\n list,\n push,\n update,\n promise,\n dismiss,\n clear,\n pause,\n resume,\n }\n}\n\nfunction toToastInput(message: string | ToastInput): ToastInput {\n return typeof message === 'string' ? { title: message } : message\n}\n\nfunction resolveMessage<T>(\n message: string | ToastInput | ((value: T) => string | ToastInput),\n value: T,\n): ToastInput {\n return toToastInput(typeof message === 'function' ? message(value) : message)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useToast.js","names":[],"sources":["../../src/composables/useToast.ts"],"sourcesContent":["import { computed, hasInjectionContext, inject, reactive } from 'vue'\nimport type { App, InjectionKey } from 'vue'\n\nimport type { GrButtonSize, GrButtonVariant } from '../components/GrButton/grButtonStyles'\nimport type { GrTone } from '../components/shared/tones'\n\nexport type GrToastTone = GrTone\n\n/**\n * Опциональная action-кнопка тоста: `label` — текст, `onClick` — обработчик.\n * По клику вызывается `onClick`, затем тост закрывается (если `dismissOnClick`\n * не установлен в `false`). `size`/`variant` настраивают вид кнопки.\n */\nexport type ToastAction = {\n label: string\n onClick: () => void\n /** Закрывать ли тост после клика по действию. По умолчанию `true`. */\n dismissOnClick?: boolean\n /** Размер кнопки действия. По умолчанию `sm`. */\n size?: GrButtonSize\n /** Вариант кнопки действия. По умолчанию `outline`. */\n variant?: GrButtonVariant\n}\n\nexport type ToastInput = {\n title: string\n message?: string\n tone?: GrToastTone\n /**\n * Автозакрытие через N мс. `0` или отрицательное значение — «навсегда»\n * (до явного вызова `dismiss(id)` / `clear()`). По умолчанию: `3500`.\n */\n timeoutMs?: number\n /** Одна action-кнопка в теле тоста (шорткат для `actions: [action]`). */\n action?: ToastAction\n /** Несколько action-кнопок в теле тоста. Рендерятся после `action`. */\n actions?: ToastAction[]\n /**\n * Схлопывать повтор: `push` с уже занятым ключом обновляет **живой** тост\n * и перезапускает его автозакрытие вместо того, чтобы завести второй.\n *\n * Ключ действует только пока тост на экране. Это не то же самое, что помнить\n * последнее показанное: повтор действия с тем же текстом обязан показаться\n * снова, иначе второе «Сохранено» пропадёт молча.\n */\n dedupeKey?: string\n}\n\n/**\n * Сообщения для `promise`. Строка — шорткат для `{ title }`; функция получает\n * результат промиса (или причину отказа), чтобы подставить его в текст.\n */\nexport type ToastPromiseMessages<T> = {\n loading: string | ToastInput\n success: string | ToastInput | ((value: T) => string | ToastInput)\n error: string | ToastInput | ((reason: unknown) => string | ToastInput)\n}\n\nexport type Toast = {\n id: string\n title: string\n message?: string\n tone: GrToastTone\n /** Исходный таймаут автозакрытия, мс (`0` — без автозакрытия). Нужен для progress-бара. */\n timeoutMs: number\n /** Одна action-кнопка в теле тоста. */\n action?: ToastAction\n /** Несколько action-кнопок в теле тоста. */\n actions?: ToastAction[]\n /** Ключ схлопывания повторов, если тост создан с ним. */\n dedupeKey?: string\n}\n\nconst DEFAULT_TIMEOUT_MS = 3500\nconst IS_SERVER = typeof window === 'undefined'\n\n// Метаданные таймера автозакрытия с поддержкой pause/resume (WCAG 2.2.1: под\n// курсором/фокусом отсчёт должен останавливаться).\ntype ToastTimer = {\n handle: number | null\n /** Сколько мс осталось до автозакрытия на момент последней паузы/старта. */\n remaining: number\n /** `performance.now()` момента запуска текущего отрезка (для вычисления остатка). */\n startedAt: number\n}\n\nexport type ToastState = {\n toasts: Toast[]\n timers: Map<string, ToastTimer>\n /** Потолок очереди: сверх него самые старые тосты вытесняются. */\n maxToasts: number\n}\n\n/**\n * Потолок очереди по умолчанию. `maxVisible` у `GrToaster` режет только видимые,\n * поэтому без него поток событий (переподключение сокета, цикл ошибок) копил бы\n * очередь и вываливал её на пользователя, когда стек освободится.\n */\nconst DEFAULT_MAX_TOASTS = 20\n\nexport type GranularityToastPluginOptions = {\n /** Потолок очереди. По умолчанию `20`. */\n maxToasts?: number\n}\n\nfunction createToastState(maxToasts = DEFAULT_MAX_TOASTS): ToastState {\n return {\n toasts: reactive<Toast[]>([]),\n timers: new Map<string, ToastTimer>(),\n maxToasts: Math.max(1, Math.trunc(maxToasts)),\n }\n}\n\n/** Ключ provide/inject для app-scoped состояния тостов (устанавливает плагин ниже). */\nexport const GRANULARITY_TOAST_STATE: InjectionKey<ToastState> = Symbol.for('@feugene/granularity/toast-state')\n\n/**\n * Vue-плагин: даёт каждому приложению собственное изолированное состояние тостов\n * через `app.provide`. Обязателен для (а) нескольких Vue-приложений на одной\n * странице (микрофронтенды — иначе делят один стек тостов) и (б) SSR (иначе\n * модульное состояние течёт между запросами).\n *\n * ```ts\n * app.use(granularityToastPlugin)\n * app.use(granularityToastPlugin, { maxToasts: 50 })\n * ```\n */\n// Где-то на странице установлен плагин: фолбэк в синглтон для такого приложения —\n// почти наверняка ошибка вызова, а не осознанный выбор.\nlet appScopedToastProvided = false\nlet contextFallbackWarned = false\n\nexport const granularityToastPlugin = {\n install(app: App, options: GranularityToastPluginOptions = {}) {\n appScopedToastProvided = true\n app.provide(GRANULARITY_TOAST_STATE, createToastState(options.maxToasts))\n },\n}\n\n// Ленивый модульный синглтон — канонический фолбэк для простых SPA без плагина.\nlet moduleToastState: ToastState | null = null\n\n/** Сброс dev-предупреждения о фолбэке. Внутреннее API — нужно тестам. */\nexport function resetToastContextWarning(): void {\n contextFallbackWarned = false\n}\n\nfunction resolveToastState(): ToastState {\n // App-scoped состояние (provide через плагин): setup-контекст ИЛИ\n // `app.runWithContext(() => useToast())` — `hasInjectionContext` покрывает оба,\n // поэтому вызов из router guard / интерцептора достаёт состояние приложения.\n if (hasInjectionContext()) {\n const provided = inject(GRANULARITY_TOAST_STATE, null)\n if (provided)\n return provided\n }\n\n // В SSR модульный фолбэк запрещён: одно mutable-состояние на модуль утекало бы\n // между запросами. Требуем установленный плагин (app.provide).\n if (IS_SERVER) {\n throw new Error(\n '[granularity] useToast requires `app.use(granularityToastPlugin)` during SSR — '\n + 'the module-singleton fallback is disabled server-side to avoid state leaking between requests.',\n )\n }\n\n // Дедуп и текст — прямо под гардом: `__GR_DEV__` разворачивается в условие\n // на сборке, и у потребителя вся ветка выкидывается вместе с сообщением.\n if (\n appScopedToastProvided && !contextFallbackWarned\n && __GR_DEV__\n ) {\n contextFallbackWarned = true\n console.warn(\n '[granularity] useToast() вызван вне setup/inject-контекста: app-scoped состояние '\n + 'granularityToastPlugin недоступно, использован модульный синглтон — эти тосты не попадут '\n + 'в GrToaster приложения. Оберните вызов: app.runWithContext(() => useToast()).',\n )\n }\n\n if (!moduleToastState)\n moduleToastState = createToastState()\n\n return moduleToastState\n}\n\nfunction now(): number {\n return typeof performance !== 'undefined' ? performance.now() : Date.now()\n}\n\nfunction makeId(): string {\n return `${Date.now()}-${Math.random().toString(16).slice(2)}`\n}\n\nexport function useToast() {\n const state = resolveToastState()\n const list = computed(() => state.toasts)\n\n function armTimer(id: string, timer: ToastTimer): void {\n if (timer.remaining <= 0 || typeof window === 'undefined')\n return\n timer.startedAt = now()\n timer.handle = window.setTimeout(() => {\n state.timers.delete(id)\n dismiss(id)\n }, timer.remaining)\n }\n\n function clearTimer(id: string): void {\n const timer = state.timers.get(id)\n if (timer?.handle != null) {\n clearTimeout(timer.handle)\n timer.handle = null\n }\n state.timers.delete(id)\n }\n\n function push(input: ToastInput): string {\n const timeout = input.timeoutMs ?? DEFAULT_TIMEOUT_MS\n\n // Схлопывание ищет тост только среди живых. Помнить последний показанный\n // ключ нельзя: тогда повтор того же действия («Сохранено» второй раз)\n // не показался бы вообще — тост уже ушёл, а ключ ещё занят.\n if (input.dedupeKey !== undefined) {\n const existing = state.toasts.find(item => item.dedupeKey === input.dedupeKey)\n if (existing) {\n // Замена целиком, а не патч: повторный `push` — это законченное\n // высказывание, и `message` от прошлого раза донашивать он не должен.\n applyStage(existing.id, { ...input, tone: input.tone ?? 'info', timeoutMs: timeout })\n return existing.id\n }\n }\n\n const id = makeId()\n const toast: Toast = {\n id,\n title: input.title,\n message: input.message,\n tone: input.tone ?? 'info',\n timeoutMs: timeout > 0 ? timeout : 0,\n action: input.action,\n actions: input.actions,\n dedupeKey: input.dedupeKey,\n }\n\n state.toasts.unshift(toast)\n trimQueue()\n\n if (toast.timeoutMs > 0) {\n const timer: ToastTimer = { handle: null, remaining: toast.timeoutMs, startedAt: now() }\n state.timers.set(id, timer)\n armTimer(id, timer)\n }\n\n return id\n }\n\n // Вытесняем с хвоста — там самые старые: при потоке событий устаревшее\n // уведомление менее ценно, чем свежее. Таймеры снимаем, иначе остались бы\n // висящие `setTimeout` на тосты, которых больше нет.\n //\n // Это флуд-защита уровня состояния, а не очередь показа (`GrToaster` держит\n // видимыми старейших): при переполнении потолка вытеснен может быть и тост,\n // который сейчас на экране, — осознанный компромисс.\n function trimQueue(): void {\n while (state.toasts.length > state.maxToasts) {\n const dropped = state.toasts.pop()\n if (dropped)\n clearTimer(dropped.id)\n }\n }\n\n /**\n * Меняет показанный тост на месте. `timeoutMs` в патче перезапускает таймер\n * (`0` — снова «навсегда»), поэтому «вечный» loading может стать\n * самозакрывающимся success.\n *\n * Возвращает `false`, если тоста уже нет: пользователь мог закрыть его руками,\n * и воскрешать его нельзя.\n */\n function update(id: string, patch: Partial<ToastInput>): boolean {\n const toast = state.toasts.find(item => item.id === id)\n if (!toast)\n return false\n\n if (patch.title !== undefined)\n toast.title = patch.title\n if (patch.message !== undefined)\n toast.message = patch.message\n if (patch.tone !== undefined)\n toast.tone = patch.tone\n if (patch.action !== undefined)\n toast.action = patch.action\n if (patch.actions !== undefined)\n toast.actions = patch.actions\n\n if (patch.timeoutMs !== undefined)\n toast.timeoutMs = rearmTimer(id, patch.timeoutMs)\n\n return true\n }\n\n /** Перезапускает автозакрытие с нового таймаута; `0` и меньше — «навсегда». */\n function rearmTimer(id: string, timeoutMs: number): number {\n clearTimer(id)\n const next = timeoutMs > 0 ? timeoutMs : 0\n\n if (next > 0) {\n const timer: ToastTimer = { handle: null, remaining: next, startedAt: now() }\n state.timers.set(id, timer)\n armTimer(id, timer)\n }\n\n return next\n }\n\n /**\n * Полная замена стадии для `promise()`. В отличие от `update`, поле без\n * значения очищается: успех не должен донашивать `message` и action-кнопки\n * загрузки — патч-семантика оставляла бы их в тосте навсегда.\n */\n function applyStage(id: string, stage: ToastInput & { tone: GrToastTone, timeoutMs: number }): void {\n const toast = state.toasts.find(item => item.id === id)\n if (!toast)\n return\n\n toast.title = stage.title\n toast.message = stage.message\n toast.tone = stage.tone\n toast.action = stage.action\n toast.actions = stage.actions\n toast.timeoutMs = rearmTimer(id, stage.timeoutMs)\n }\n\n /**\n * Один тост на весь жизненный цикл промиса: «загружаем» переписывается в\n * успех или ошибку, а не закрывается ради нового — стек не дёргается.\n *\n * Каждая стадия **заменяет** предыдущую целиком: поле, не заданное в\n * success/error, очищается, а не наследуется от loading.\n *\n * Возвращает исходный промис и **не глотает отказ**: тост не заменяет\n * обработку ошибки, вызывающий по-прежнему обязан её обработать.\n */\n function promise<T>(input: Promise<T>, messages: ToastPromiseMessages<T>): Promise<T> {\n const id = push({ tone: 'info', ...toToastInput(messages.loading), timeoutMs: 0 })\n\n input.then(\n (value) => {\n const stage = resolveMessage(messages.success, value)\n applyStage(id, { ...stage, tone: stage.tone ?? 'success', timeoutMs: stage.timeoutMs ?? DEFAULT_TIMEOUT_MS })\n },\n (reason: unknown) => {\n const stage = resolveMessage(messages.error, reason)\n applyStage(id, { ...stage, tone: stage.tone ?? 'danger', timeoutMs: stage.timeoutMs ?? DEFAULT_TIMEOUT_MS })\n },\n )\n\n return input\n }\n\n /** Останавливает отсчёт автозакрытия, сохраняя остаток (идемпотентно). */\n function pause(id: string): void {\n const timer = state.timers.get(id)\n if (!timer || timer.handle == null)\n return\n\n clearTimeout(timer.handle)\n timer.handle = null\n timer.remaining = Math.max(0, timer.remaining - (now() - timer.startedAt))\n }\n\n /** Возобновляет отсчёт с сохранённого остатка (идемпотентно). */\n function resume(id: string): void {\n const timer = state.timers.get(id)\n if (!timer || timer.handle != null)\n return\n\n armTimer(id, timer)\n }\n\n function dismiss(id: string): void {\n clearTimer(id)\n const index = state.toasts.findIndex(toast => toast.id === id)\n if (index >= 0)\n state.toasts.splice(index, 1)\n }\n\n function clear(): void {\n for (const id of [...state.timers.keys()]) clearTimer(id)\n state.toasts.splice(0, state.toasts.length)\n }\n\n return {\n list,\n push,\n update,\n promise,\n dismiss,\n clear,\n pause,\n resume,\n }\n}\n\nfunction toToastInput(message: string | ToastInput): ToastInput {\n return typeof message === 'string' ? { title: message } : message\n}\n\nfunction resolveMessage<T>(\n message: string | ToastInput | ((value: T) => string | ToastInput),\n value: T,\n): ToastInput {\n return toToastInput(typeof message === 'function' ? message(value) : message)\n}\n"],"mappings":";;AAyEA,IAAM,qBAAqB;AAC3B,IAAM,YAAY,OAAO,WAAW;;;;;;AAwBpC,IAAM,qBAAqB;AAO3B,SAAS,iBAAiB,YAAY,oBAAgC;CACpE,OAAO;EACL,QAAQ,SAAkB,CAAC,CAAC;EAC5B,wBAAQ,IAAI,IAAwB;EACpC,WAAW,KAAK,IAAI,GAAG,KAAK,MAAM,SAAS,CAAC;CAC9C;AACF;;AAGA,IAAa,0BAAoD,OAAO,IAAI,kCAAkC;;;;;;;;;;;;AAe9G,IAAI,yBAAyB;AAC7B,IAAI,wBAAwB;AAE5B,IAAa,yBAAyB,EACpC,QAAQ,KAAU,UAAyC,CAAC,GAAG;CAC7D,yBAAyB;CACzB,IAAI,QAAQ,yBAAyB,iBAAiB,QAAQ,SAAS,CAAC;AAC1E,EACF;AAGA,IAAI,mBAAsC;;AAG1C,SAAgB,2BAAiC;CAC/C,wBAAwB;AAC1B;AAEA,SAAS,oBAAgC;CAIvC,IAAI,oBAAoB,GAAG;EACzB,MAAM,WAAW,OAAO,yBAAyB,IAAI;EACrD,IAAI,UACF,OAAO;CACX;CAIA,IAAI,WACF,MAAM,IAAI,MACR,+KAEF;CAKF,IACE,0BAA0B,CAAC,yBAAA,QAAA,IAAA,aAAA,cAE3B;EACA,wBAAwB;EACxB,QAAQ,KACN,yPAGF;CACF;CAEA,IAAI,CAAC,kBACH,mBAAmB,iBAAiB;CAEtC,OAAO;AACT;AAEA,SAAS,MAAc;CACrB,OAAO,OAAO,gBAAgB,cAAc,YAAY,IAAI,IAAI,KAAK,IAAI;AAC3E;AAEA,SAAS,SAAiB;CACxB,OAAO,GAAG,KAAK,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC;AAC5D;AAEA,SAAgB,WAAW;CACzB,MAAM,QAAQ,kBAAkB;CAChC,MAAM,OAAO,eAAe,MAAM,MAAM;CAExC,SAAS,SAAS,IAAY,OAAyB;EACrD,IAAI,MAAM,aAAa,KAAK,OAAO,WAAW,aAC5C;EACF,MAAM,YAAY,IAAI;EACtB,MAAM,SAAS,OAAO,iBAAiB;GACrC,MAAM,OAAO,OAAO,EAAE;GACtB,QAAQ,EAAE;EACZ,GAAG,MAAM,SAAS;CACpB;CAEA,SAAS,WAAW,IAAkB;EACpC,MAAM,QAAQ,MAAM,OAAO,IAAI,EAAE;EACjC,IAAI,OAAO,UAAU,MAAM;GACzB,aAAa,MAAM,MAAM;GACzB,MAAM,SAAS;EACjB;EACA,MAAM,OAAO,OAAO,EAAE;CACxB;CAEA,SAAS,KAAK,OAA2B;EACvC,MAAM,UAAU,MAAM,aAAa;EAKnC,IAAI,MAAM,cAAc,KAAA,GAAW;GACjC,MAAM,WAAW,MAAM,OAAO,MAAK,SAAQ,KAAK,cAAc,MAAM,SAAS;GAC7E,IAAI,UAAU;IAGZ,WAAW,SAAS,IAAI;KAAE,GAAG;KAAO,MAAM,MAAM,QAAQ;KAAQ,WAAW;IAAQ,CAAC;IACpF,OAAO,SAAS;GAClB;EACF;EAEA,MAAM,KAAK,OAAO;EAClB,MAAM,QAAe;GACnB;GACA,OAAO,MAAM;GACb,SAAS,MAAM;GACf,MAAM,MAAM,QAAQ;GACpB,WAAW,UAAU,IAAI,UAAU;GACnC,QAAQ,MAAM;GACd,SAAS,MAAM;GACf,WAAW,MAAM;EACnB;EAEA,MAAM,OAAO,QAAQ,KAAK;EAC1B,UAAU;EAEV,IAAI,MAAM,YAAY,GAAG;GACvB,MAAM,QAAoB;IAAE,QAAQ;IAAM,WAAW,MAAM;IAAW,WAAW,IAAI;GAAE;GACvF,MAAM,OAAO,IAAI,IAAI,KAAK;GAC1B,SAAS,IAAI,KAAK;EACpB;EAEA,OAAO;CACT;CASA,SAAS,YAAkB;EACzB,OAAO,MAAM,OAAO,SAAS,MAAM,WAAW;GAC5C,MAAM,UAAU,MAAM,OAAO,IAAI;GACjC,IAAI,SACF,WAAW,QAAQ,EAAE;EACzB;CACF;;;;;;;;;CAUA,SAAS,OAAO,IAAY,OAAqC;EAC/D,MAAM,QAAQ,MAAM,OAAO,MAAK,SAAQ,KAAK,OAAO,EAAE;EACtD,IAAI,CAAC,OACH,OAAO;EAET,IAAI,MAAM,UAAU,KAAA,GAClB,MAAM,QAAQ,MAAM;EACtB,IAAI,MAAM,YAAY,KAAA,GACpB,MAAM,UAAU,MAAM;EACxB,IAAI,MAAM,SAAS,KAAA,GACjB,MAAM,OAAO,MAAM;EACrB,IAAI,MAAM,WAAW,KAAA,GACnB,MAAM,SAAS,MAAM;EACvB,IAAI,MAAM,YAAY,KAAA,GACpB,MAAM,UAAU,MAAM;EAExB,IAAI,MAAM,cAAc,KAAA,GACtB,MAAM,YAAY,WAAW,IAAI,MAAM,SAAS;EAElD,OAAO;CACT;;CAGA,SAAS,WAAW,IAAY,WAA2B;EACzD,WAAW,EAAE;EACb,MAAM,OAAO,YAAY,IAAI,YAAY;EAEzC,IAAI,OAAO,GAAG;GACZ,MAAM,QAAoB;IAAE,QAAQ;IAAM,WAAW;IAAM,WAAW,IAAI;GAAE;GAC5E,MAAM,OAAO,IAAI,IAAI,KAAK;GAC1B,SAAS,IAAI,KAAK;EACpB;EAEA,OAAO;CACT;;;;;;CAOA,SAAS,WAAW,IAAY,OAAoE;EAClG,MAAM,QAAQ,MAAM,OAAO,MAAK,SAAQ,KAAK,OAAO,EAAE;EACtD,IAAI,CAAC,OACH;EAEF,MAAM,QAAQ,MAAM;EACpB,MAAM,UAAU,MAAM;EACtB,MAAM,OAAO,MAAM;EACnB,MAAM,SAAS,MAAM;EACrB,MAAM,UAAU,MAAM;EACtB,MAAM,YAAY,WAAW,IAAI,MAAM,SAAS;CAClD;;;;;;;;;;;CAYA,SAAS,QAAW,OAAmB,UAA+C;EACpF,MAAM,KAAK,KAAK;GAAE,MAAM;GAAQ,GAAG,aAAa,SAAS,OAAO;GAAG,WAAW;EAAE,CAAC;EAEjF,MAAM,MACH,UAAU;GACT,MAAM,QAAQ,eAAe,SAAS,SAAS,KAAK;GACpD,WAAW,IAAI;IAAE,GAAG;IAAO,MAAM,MAAM,QAAQ;IAAW,WAAW,MAAM,aAAa;GAAmB,CAAC;EAC9G,IACC,WAAoB;GACnB,MAAM,QAAQ,eAAe,SAAS,OAAO,MAAM;GACnD,WAAW,IAAI;IAAE,GAAG;IAAO,MAAM,MAAM,QAAQ;IAAU,WAAW,MAAM,aAAa;GAAmB,CAAC;EAC7G,CACF;EAEA,OAAO;CACT;;CAGA,SAAS,MAAM,IAAkB;EAC/B,MAAM,QAAQ,MAAM,OAAO,IAAI,EAAE;EACjC,IAAI,CAAC,SAAS,MAAM,UAAU,MAC5B;EAEF,aAAa,MAAM,MAAM;EACzB,MAAM,SAAS;EACf,MAAM,YAAY,KAAK,IAAI,GAAG,MAAM,aAAa,IAAI,IAAI,MAAM,UAAU;CAC3E;;CAGA,SAAS,OAAO,IAAkB;EAChC,MAAM,QAAQ,MAAM,OAAO,IAAI,EAAE;EACjC,IAAI,CAAC,SAAS,MAAM,UAAU,MAC5B;EAEF,SAAS,IAAI,KAAK;CACpB;CAEA,SAAS,QAAQ,IAAkB;EACjC,WAAW,EAAE;EACb,MAAM,QAAQ,MAAM,OAAO,WAAU,UAAS,MAAM,OAAO,EAAE;EAC7D,IAAI,SAAS,GACX,MAAM,OAAO,OAAO,OAAO,CAAC;CAChC;CAEA,SAAS,QAAc;EACrB,KAAK,MAAM,MAAM,CAAC,GAAG,MAAM,OAAO,KAAK,CAAC,GAAG,WAAW,EAAE;EACxD,MAAM,OAAO,OAAO,GAAG,MAAM,OAAO,MAAM;CAC5C;CAEA,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;AACF;AAEA,SAAS,aAAa,SAA0C;CAC9D,OAAO,OAAO,YAAY,WAAW,EAAE,OAAO,QAAQ,IAAI;AAC5D;AAEA,SAAS,eACP,SACA,OACY;CACZ,OAAO,aAAa,OAAO,YAAY,aAAa,QAAQ,KAAK,IAAI,OAAO;AAC9E"}
@@ -183,11 +183,9 @@ function useVirtualList(options) {
183
183
  case "center":
184
184
  next = start + size / 2 - height / 2;
185
185
  break;
186
- case "auto":
187
- if (start < el.scrollTop) next = start;
188
- else if (end > el.scrollTop + height) next = end - height;
189
- else return;
190
- break;
186
+ case "auto": if (start < el.scrollTop) next = start;
187
+ else if (end > el.scrollTop + height) next = end - height;
188
+ else return;
191
189
  }
192
190
  el.scrollTop = Math.max(0, Math.min(next, offsetAt(count) - height));
193
191
  scrollTop.value = el.scrollTop;
@@ -1 +1 @@
1
- {"version":3,"file":"useVirtualList.js","names":[],"sources":["../../src/composables/useVirtualList.ts"],"sourcesContent":["import type { ComputedRef, Ref } from 'vue'\nimport { computed, onScopeDispose, ref, watch } from 'vue'\n\n/**\n * Виртуализация длинного списка: в DOM живёт только окно вокруг вьюпорта.\n *\n * Композабл считает геометрию и отдаёт три числа — какой срез рисовать\n * (`range`), какой высоты держать распорку (`totalSize`) и на сколько сдвинуть\n * отрисованное (`offset`). Разметку строит потребитель: примитив ничего не\n * рендерит и ничего не знает про роли и клавиатуру своего списка.\n *\n * Скролл-протяжённость держат псевдоэлементы контейнера: `spacerStyle` отдаёт\n * их высоты переменными, а правило живёт в `<style>` компонента. Так\n * отрисованные строки остаются **прямыми детьми** контейнера, и роль вроде\n * `tree` или `listbox` не теряет обязательных потомков.\n *\n * ```vue\n * const container = useTemplateRef('scroller')\n * const { range, spacerStyle, measure } = useVirtualList({\n * container,\n * count: () => rows.value.length,\n * itemSize: 28,\n * viewportSize: () => props.maxHeight,\n * })\n *\n * <div\n * ref=\"scroller\"\n * role=\"tree\"\n * data-gr-virtual\n * :style=\"{ overflow: 'auto', maxHeight: '280px', ...spacerStyle }\"\n * >\n * <Row v-for=\"i in window\" :key=\"…\" :ref=\"el => measure(i, el)\" />\n * </div>\n *\n * <style scoped>\n * [data-gr-virtual]::before,\n * [data-gr-virtual]::after { content: ''; display: block; flex: none; }\n * [data-gr-virtual]::before { height: var(--gr-virtual-before, 0px); }\n * [data-gr-virtual]::after { height: var(--gr-virtual-after, 0px); }\n * </style>\n * ```\n *\n * Почему правило повторяется в каждом компоненте, а не лежит в одном файле:\n * единственный глобальный стиль пакета (`styles/base.css`) потребитель вправе\n * не подключать, и уехавшее туда правило молча ломало бы прокрутку. Сверяет\n * копии гейт `src/__tests__/virtualSpacer.test.ts`.\n */\n\n/** Куда поставить элемент относительно вьюпорта при прокрутке к нему. */\nexport type GrVirtualAlign = 'auto' | 'start' | 'center' | 'end'\n\nexport interface UseVirtualListOptions {\n /** Скроллящийся контейнер. До монтирования — `null`. */\n container: Ref<HTMLElement | null>\n /** Сколько элементов в списке. */\n count: () => number\n /**\n * Оценка высоты элемента. Фактическая берётся из замера, как только элемент\n * отрисован, — строки пакета заданы через `min-height`, и точного числа тут\n * знать неоткуда.\n */\n itemSize: number | ((index: number) => number)\n /**\n * Высота вьюпорта до первого замера контейнера. Нужна, чтобы **первый рендер\n * был детерминированным**: на сервере контейнера нет вовсе, а на клиенте он\n * ещё не измерен. Без неё сервер и клиент нарисовали бы разные окна и\n * гидрация разъехалась бы; с ней оба считают окно от одного числа.\n */\n viewportSize?: () => number | undefined\n /**\n * Идентити-токен данных списка — обычно сам массив. Смена идентичности\n * сбрасывает все замеры (`invalidate()`): они привязаны к индексам, и после\n * сортировки или замены массива хранили бы высоты чужих строк.\n *\n * Правило потребителя: **мутация массива на месте сохраняет замеры, замена\n * массива сбрасывает**. Append в тот же реактивный массив (инфинити-скролл)\n * идентичность не меняет — префикс замеров остаётся валидным.\n */\n source?: () => unknown\n /**\n * Зазор между элементами в пикселях (`gap` у flex/grid-контейнера).\n *\n * Замер элемента его не видит — `getBoundingClientRect` меряет коробку, а не\n * шаг раскладки. Без этого числа список считался бы короче, чем он есть,\n * и окно уползало бы тем сильнее, чем дальше прокрутка.\n */\n gap?: number\n /** Сколько элементов рисовать за пределами вьюпорта. По умолчанию `4`. */\n overscan?: number\n}\n\nexport interface UseVirtualListReturn {\n /** Полуинтервал индексов к отрисовке: `[start, end)`. */\n range: ComputedRef<{ start: number, end: number }>\n /** Полная высота содержимого: распорка, которая держит скроллбар. */\n totalSize: ComputedRef<number>\n /** Отступ сверху: высота срезанного до окна. */\n offset: ComputedRef<number>\n /** Отступ снизу: высота срезанного после окна. */\n offsetEnd: ComputedRef<number>\n /**\n * Стиль контейнера: высоты распорок и выключенный scroll anchoring.\n *\n * Имена переменных приезжают готовыми, поэтому написать их руками — и\n * разойтись с правилом в `<style>` — нельзя. Опечатка в имени давала бы\n * список без прокрутки, и увидеть это можно было бы только глазами.\n */\n spacerStyle: ComputedRef<Record<string, string>>\n /** Регистрация отрисованного элемента: замер и подписка на изменение высоты. */\n measure: (index: number, el: Element | null) => void\n /** Прокрутка к элементу. Без выравнивания — минимальным движением. */\n scrollToIndex: (index: number, align?: GrVirtualAlign) => void\n /**\n * Сбрасывает замеры с индекса `from` (по умолчанию — все) к оценкам.\n * Видимые строки перемеряются первым же рендером; для смены данных обычно\n * достаточно опции `source` — ручной вызов нужен, когда высоты строк\n * изменились без замены массива (смена плотности, ресайз колонок).\n */\n invalidate: (from?: number) => void\n}\n\nconst DEFAULT_OVERSCAN = 4\n\n/** Порог, ниже которого разницу замеров считаем шумом округления. */\nconst SIZE_EPSILON = 0.5\n\nfunction readSize(el: Element): number {\n const box = el.getBoundingClientRect().height\n if (box > 0)\n return box\n\n // jsdom не считает layout: `getBoundingClientRect` там всегда нулевой, а\n // `offsetHeight` тест может задать сам.\n return (el as HTMLElement).offsetHeight ?? 0\n}\n\nexport function useVirtualList(options: UseVirtualListOptions): UseVirtualListReturn {\n const overscan = Math.max(0, Math.trunc(options.overscan ?? DEFAULT_OVERSCAN))\n const gap = Math.max(0, options.gap ?? 0)\n const estimateOf = typeof options.itemSize === 'function'\n ? options.itemSize\n : () => options.itemSize as number\n\n const scrollTop = ref(0)\n const measuredViewport = ref(0)\n\n const measured = new Map<number, number>()\n const observedIndex = new WeakMap<Element, number>()\n\n // `ResizeObserver` нет ни на сервере, ни в jsdom. Без него композабл работает\n // на оценках и явных замерах из `measure()` — это рабочий режим, а не отказ.\n const hasResizeObserver = typeof ResizeObserver !== 'undefined'\n const sizeObserver = hasResizeObserver\n ? new ResizeObserver((entries) => {\n for (const entry of entries) {\n const index = observedIndex.get(entry.target)\n if (index !== undefined)\n applySize(index, readSize(entry.target))\n }\n })\n : null\n const viewportObserver = hasResizeObserver ? new ResizeObserver(() => syncViewport()) : null\n let attachedTo: HTMLElement | null = null\n let offsets: number[] = [0]\n /** До какого индекса префикс-суммы актуальны. */\n let builtTo = 0\n\n /** Шаг раскладки: коробка элемента плюс зазор до следующего. */\n function sizeAt(index: number): number {\n return (measured.get(index) ?? estimateOf(index)) + gap\n }\n\n /**\n * Достраивает префикс-суммы до нужного индекса.\n *\n * Замер инвалидирует хвост от своего индекса, а не весь массив: иначе каждая\n * отрисованная строка стоила бы полного пересчёта по всему списку.\n */\n function buildTo(index: number): void {\n const limit = Math.min(index, options.count())\n while (builtTo < limit) {\n offsets[builtTo + 1] = offsets[builtTo] + sizeAt(builtTo)\n builtTo += 1\n }\n }\n\n function offsetAt(index: number): number {\n buildTo(index)\n return offsets[Math.min(Math.max(index, 0), builtTo)] ?? 0\n }\n\n function invalidateFrom(index: number): void {\n if (index < builtTo)\n builtTo = Math.max(0, index)\n }\n\n /** Последний индекс, чьё начало не ниже `px`. */\n function indexAt(px: number): number {\n const count = options.count()\n if (count === 0)\n return 0\n\n buildTo(count)\n\n let low = 0\n let high = builtTo\n while (low < high) {\n const mid = (low + high + 1) >> 1\n if ((offsets[mid] ?? 0) <= px)\n low = mid\n else high = mid - 1\n }\n\n return Math.min(low, count - 1)\n }\n\n function viewportSize(): number {\n return measuredViewport.value || options.viewportSize?.() || 0\n }\n\n /**\n * Геометрия окна одним снимком.\n *\n * Считается явно, а не `computed`'ом поверх смещений: массив префикс-сумм\n * мутируется на месте (иначе каждый замер пересоздавал бы десять тысяч чисел),\n * и вывести из него реактивную зависимость нечем — трекер увидел бы только те\n * индексы, которые пересчитывались в последний проход.\n */\n const geometry = ref({ start: 0, end: 0, offset: 0, offsetEnd: 0, total: 0 })\n\n function recompute(): void {\n const count = options.count()\n if (count === 0) {\n geometry.value = { start: 0, end: 0, offset: 0, offsetEnd: 0, total: 0 }\n return\n }\n\n const totalSize = offsetAt(count)\n const height = viewportSize()\n\n // Высота неизвестна (контейнера нет и оценки не дали) — рисуем всё: меньше\n // «списка целиком» отрисовать нечего без риска, что до замера так и не\n // дойдёт ни одна строка.\n if (height <= 0) {\n geometry.value = { start: 0, end: count, offset: 0, offsetEnd: 0, total: totalSize }\n return\n }\n\n const start = Math.max(0, indexAt(scrollTop.value) - overscan)\n const end = Math.min(count, indexAt(scrollTop.value + height) + 1 + overscan)\n\n geometry.value = {\n start,\n end,\n offset: offsetAt(start),\n offsetEnd: Math.max(0, totalSize - offsetAt(end)),\n total: totalSize,\n }\n }\n\n const range = computed(() => ({ start: geometry.value.start, end: geometry.value.end }))\n const total = computed(() => geometry.value.total)\n const offset = computed(() => geometry.value.offset)\n const offsetEnd = computed(() => geometry.value.offsetEnd)\n\n const spacerStyle = computed(() => ({\n // Браузерный scroll anchoring обязан быть выключен. Он удерживает видимый\n // узел на месте, подправляя `scrollTop`, когда меняется высота содержимого\n // выше него, — а окно меняет её на каждом кадре прокрутки. Дальше пересчёт\n // окна и якорь начинают двигать список навстречу друг другу, и прокрутка\n // уезжает тем сильнее, чем дальше оценка строки от фактической высоты.\n 'overflow-anchor': 'none',\n '--gr-virtual-before': `${geometry.value.offset}px`,\n '--gr-virtual-after': `${geometry.value.offsetEnd}px`,\n }))\n\n function syncScrollTop(): void {\n const el = options.container.value\n if (!el)\n return\n\n scrollTop.value = el.scrollTop\n recompute()\n }\n\n function syncViewport(): void {\n const el = options.container.value\n if (!el)\n return\n\n measuredViewport.value = el.clientHeight\n recompute()\n }\n\n function measure(index: number, el: Element | null): void {\n if (!el)\n return\n\n observedIndex.set(el, index)\n sizeObserver?.observe(el)\n\n applySize(index, readSize(el))\n }\n\n function applySize(index: number, size: number): void {\n if (size <= 0)\n return\n\n const previous = measured.get(index)\n if (previous !== undefined && Math.abs(previous - size) < SIZE_EPSILON)\n return\n\n // Считаем смещение ДО правки: строка ниже вьюпорта позицию не двигает, а\n // строка выше — двигает всё содержимое под курсором.\n const start = offsetAt(index)\n const delta = size - (previous ?? estimateOf(index))\n\n measured.set(index, size)\n invalidateFrom(index)\n\n const el = options.container.value\n // Компенсация: без неё уточнение высоты уже прокрученных строк выглядит как\n // рывок списка вверх или вниз ровно в момент замера.\n if (delta !== 0 && start < scrollTop.value && el) {\n el.scrollTop += delta\n scrollTop.value = el.scrollTop\n }\n\n recompute()\n }\n\n function scrollToIndex(index: number, align: GrVirtualAlign = 'auto'): void {\n const el = options.container.value\n const count = options.count()\n if (!el || count === 0)\n return\n\n const clamped = Math.min(Math.max(index, 0), count - 1)\n const start = offsetAt(clamped)\n const size = sizeAt(clamped)\n const height = el.clientHeight || viewportSize()\n const end = start + size\n\n let next: number\n switch (align) {\n case 'start':\n next = start\n break\n case 'end':\n next = end - height\n break\n case 'center':\n next = start + size / 2 - height / 2\n break\n case 'auto':\n if (start < el.scrollTop)\n next = start\n else if (end > el.scrollTop + height)\n next = end - height\n else return\n break\n }\n\n el.scrollTop = Math.max(0, Math.min(next, offsetAt(count) - height))\n scrollTop.value = el.scrollTop\n recompute()\n }\n\n function detach(): void {\n if (!attachedTo)\n return\n attachedTo.removeEventListener('scroll', syncScrollTop)\n viewportObserver?.unobserve(attachedTo)\n attachedTo = null\n }\n\n // Первый снимок до всякого монтирования: на сервере и на первом клиентском\n // рендере контейнера ещё нет, а окно уже должно быть посчитано — и одинаково.\n recompute()\n\n watch(options.container, (el) => {\n detach()\n if (!el)\n return\n\n attachedTo = el\n el.addEventListener('scroll', syncScrollTop, { passive: true })\n viewportObserver?.observe(el)\n syncViewport()\n syncScrollTop()\n }, { immediate: true })\n\n // Длина списка изменилась. Сокращение дополнительно чистит хвост смещений и\n // замеров: он относится к строкам, которых больше нет.\n watch(() => options.count(), (count) => {\n if (count < builtTo)\n truncate(count)\n recompute()\n })\n\n function invalidate(from = 0): void {\n for (const index of [...measured.keys()]) {\n if (index >= from)\n measured.delete(index)\n }\n invalidateFrom(from)\n recompute()\n }\n\n if (options.source) {\n // Идентичность данных сменилась — замеры принадлежат прошлому набору.\n watch(options.source, () => invalidate())\n }\n\n function truncate(count: number): void {\n builtTo = count\n offsets = offsets.slice(0, count + 1)\n for (const index of [...measured.keys()]) {\n if (index >= count)\n measured.delete(index)\n }\n }\n\n onScopeDispose(() => {\n detach()\n sizeObserver?.disconnect()\n viewportObserver?.disconnect()\n })\n\n return { range, totalSize: total, offset, offsetEnd, spacerStyle, measure, scrollToIndex, invalidate }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useVirtualList.js","names":[],"sources":["../../src/composables/useVirtualList.ts"],"sourcesContent":["import type { ComputedRef, Ref } from 'vue'\nimport { computed, onScopeDispose, ref, watch } from 'vue'\n\n/**\n * Виртуализация длинного списка: в DOM живёт только окно вокруг вьюпорта.\n *\n * Композабл считает геометрию и отдаёт три числа — какой срез рисовать\n * (`range`), какой высоты держать распорку (`totalSize`) и на сколько сдвинуть\n * отрисованное (`offset`). Разметку строит потребитель: примитив ничего не\n * рендерит и ничего не знает про роли и клавиатуру своего списка.\n *\n * Скролл-протяжённость держат псевдоэлементы контейнера: `spacerStyle` отдаёт\n * их высоты переменными, а правило живёт в `<style>` компонента. Так\n * отрисованные строки остаются **прямыми детьми** контейнера, и роль вроде\n * `tree` или `listbox` не теряет обязательных потомков.\n *\n * ```vue\n * const container = useTemplateRef('scroller')\n * const { range, spacerStyle, measure } = useVirtualList({\n * container,\n * count: () => rows.value.length,\n * itemSize: 28,\n * viewportSize: () => props.maxHeight,\n * })\n *\n * <div\n * ref=\"scroller\"\n * role=\"tree\"\n * data-gr-virtual\n * :style=\"{ overflow: 'auto', maxHeight: '280px', ...spacerStyle }\"\n * >\n * <Row v-for=\"i in window\" :key=\"…\" :ref=\"el => measure(i, el)\" />\n * </div>\n *\n * <style scoped>\n * [data-gr-virtual]::before,\n * [data-gr-virtual]::after { content: ''; display: block; flex: none; }\n * [data-gr-virtual]::before { height: var(--gr-virtual-before, 0px); }\n * [data-gr-virtual]::after { height: var(--gr-virtual-after, 0px); }\n * </style>\n * ```\n *\n * Почему правило повторяется в каждом компоненте, а не лежит в одном файле:\n * единственный глобальный стиль пакета (`styles/base.css`) потребитель вправе\n * не подключать, и уехавшее туда правило молча ломало бы прокрутку. Сверяет\n * копии гейт `src/__tests__/virtualSpacer.test.ts`.\n */\n\n/** Куда поставить элемент относительно вьюпорта при прокрутке к нему. */\nexport type GrVirtualAlign = 'auto' | 'start' | 'center' | 'end'\n\nexport interface UseVirtualListOptions {\n /** Скроллящийся контейнер. До монтирования — `null`. */\n container: Ref<HTMLElement | null>\n /** Сколько элементов в списке. */\n count: () => number\n /**\n * Оценка высоты элемента. Фактическая берётся из замера, как только элемент\n * отрисован, — строки пакета заданы через `min-height`, и точного числа тут\n * знать неоткуда.\n */\n itemSize: number | ((index: number) => number)\n /**\n * Высота вьюпорта до первого замера контейнера. Нужна, чтобы **первый рендер\n * был детерминированным**: на сервере контейнера нет вовсе, а на клиенте он\n * ещё не измерен. Без неё сервер и клиент нарисовали бы разные окна и\n * гидрация разъехалась бы; с ней оба считают окно от одного числа.\n */\n viewportSize?: () => number | undefined\n /**\n * Идентити-токен данных списка — обычно сам массив. Смена идентичности\n * сбрасывает все замеры (`invalidate()`): они привязаны к индексам, и после\n * сортировки или замены массива хранили бы высоты чужих строк.\n *\n * Правило потребителя: **мутация массива на месте сохраняет замеры, замена\n * массива сбрасывает**. Append в тот же реактивный массив (инфинити-скролл)\n * идентичность не меняет — префикс замеров остаётся валидным.\n */\n source?: () => unknown\n /**\n * Зазор между элементами в пикселях (`gap` у flex/grid-контейнера).\n *\n * Замер элемента его не видит — `getBoundingClientRect` меряет коробку, а не\n * шаг раскладки. Без этого числа список считался бы короче, чем он есть,\n * и окно уползало бы тем сильнее, чем дальше прокрутка.\n */\n gap?: number\n /** Сколько элементов рисовать за пределами вьюпорта. По умолчанию `4`. */\n overscan?: number\n}\n\nexport interface UseVirtualListReturn {\n /** Полуинтервал индексов к отрисовке: `[start, end)`. */\n range: ComputedRef<{ start: number, end: number }>\n /** Полная высота содержимого: распорка, которая держит скроллбар. */\n totalSize: ComputedRef<number>\n /** Отступ сверху: высота срезанного до окна. */\n offset: ComputedRef<number>\n /** Отступ снизу: высота срезанного после окна. */\n offsetEnd: ComputedRef<number>\n /**\n * Стиль контейнера: высоты распорок и выключенный scroll anchoring.\n *\n * Имена переменных приезжают готовыми, поэтому написать их руками — и\n * разойтись с правилом в `<style>` — нельзя. Опечатка в имени давала бы\n * список без прокрутки, и увидеть это можно было бы только глазами.\n */\n spacerStyle: ComputedRef<Record<string, string>>\n /** Регистрация отрисованного элемента: замер и подписка на изменение высоты. */\n measure: (index: number, el: Element | null) => void\n /** Прокрутка к элементу. Без выравнивания — минимальным движением. */\n scrollToIndex: (index: number, align?: GrVirtualAlign) => void\n /**\n * Сбрасывает замеры с индекса `from` (по умолчанию — все) к оценкам.\n * Видимые строки перемеряются первым же рендером; для смены данных обычно\n * достаточно опции `source` — ручной вызов нужен, когда высоты строк\n * изменились без замены массива (смена плотности, ресайз колонок).\n */\n invalidate: (from?: number) => void\n}\n\nconst DEFAULT_OVERSCAN = 4\n\n/** Порог, ниже которого разницу замеров считаем шумом округления. */\nconst SIZE_EPSILON = 0.5\n\nfunction readSize(el: Element): number {\n const box = el.getBoundingClientRect().height\n if (box > 0)\n return box\n\n // jsdom не считает layout: `getBoundingClientRect` там всегда нулевой, а\n // `offsetHeight` тест может задать сам.\n return (el as HTMLElement).offsetHeight ?? 0\n}\n\nexport function useVirtualList(options: UseVirtualListOptions): UseVirtualListReturn {\n const overscan = Math.max(0, Math.trunc(options.overscan ?? DEFAULT_OVERSCAN))\n const gap = Math.max(0, options.gap ?? 0)\n const estimateOf = typeof options.itemSize === 'function'\n ? options.itemSize\n : () => options.itemSize as number\n\n const scrollTop = ref(0)\n const measuredViewport = ref(0)\n\n const measured = new Map<number, number>()\n const observedIndex = new WeakMap<Element, number>()\n\n // `ResizeObserver` нет ни на сервере, ни в jsdom. Без него композабл работает\n // на оценках и явных замерах из `measure()` — это рабочий режим, а не отказ.\n const hasResizeObserver = typeof ResizeObserver !== 'undefined'\n const sizeObserver = hasResizeObserver\n ? new ResizeObserver((entries) => {\n for (const entry of entries) {\n const index = observedIndex.get(entry.target)\n if (index !== undefined)\n applySize(index, readSize(entry.target))\n }\n })\n : null\n const viewportObserver = hasResizeObserver ? new ResizeObserver(() => syncViewport()) : null\n let attachedTo: HTMLElement | null = null\n let offsets: number[] = [0]\n /** До какого индекса префикс-суммы актуальны. */\n let builtTo = 0\n\n /** Шаг раскладки: коробка элемента плюс зазор до следующего. */\n function sizeAt(index: number): number {\n return (measured.get(index) ?? estimateOf(index)) + gap\n }\n\n /**\n * Достраивает префикс-суммы до нужного индекса.\n *\n * Замер инвалидирует хвост от своего индекса, а не весь массив: иначе каждая\n * отрисованная строка стоила бы полного пересчёта по всему списку.\n */\n function buildTo(index: number): void {\n const limit = Math.min(index, options.count())\n while (builtTo < limit) {\n offsets[builtTo + 1] = offsets[builtTo] + sizeAt(builtTo)\n builtTo += 1\n }\n }\n\n function offsetAt(index: number): number {\n buildTo(index)\n return offsets[Math.min(Math.max(index, 0), builtTo)] ?? 0\n }\n\n function invalidateFrom(index: number): void {\n if (index < builtTo)\n builtTo = Math.max(0, index)\n }\n\n /** Последний индекс, чьё начало не ниже `px`. */\n function indexAt(px: number): number {\n const count = options.count()\n if (count === 0)\n return 0\n\n buildTo(count)\n\n let low = 0\n let high = builtTo\n while (low < high) {\n const mid = (low + high + 1) >> 1\n if ((offsets[mid] ?? 0) <= px)\n low = mid\n else high = mid - 1\n }\n\n return Math.min(low, count - 1)\n }\n\n function viewportSize(): number {\n return measuredViewport.value || options.viewportSize?.() || 0\n }\n\n /**\n * Геометрия окна одним снимком.\n *\n * Считается явно, а не `computed`'ом поверх смещений: массив префикс-сумм\n * мутируется на месте (иначе каждый замер пересоздавал бы десять тысяч чисел),\n * и вывести из него реактивную зависимость нечем — трекер увидел бы только те\n * индексы, которые пересчитывались в последний проход.\n */\n const geometry = ref({ start: 0, end: 0, offset: 0, offsetEnd: 0, total: 0 })\n\n function recompute(): void {\n const count = options.count()\n if (count === 0) {\n geometry.value = { start: 0, end: 0, offset: 0, offsetEnd: 0, total: 0 }\n return\n }\n\n const totalSize = offsetAt(count)\n const height = viewportSize()\n\n // Высота неизвестна (контейнера нет и оценки не дали) — рисуем всё: меньше\n // «списка целиком» отрисовать нечего без риска, что до замера так и не\n // дойдёт ни одна строка.\n if (height <= 0) {\n geometry.value = { start: 0, end: count, offset: 0, offsetEnd: 0, total: totalSize }\n return\n }\n\n const start = Math.max(0, indexAt(scrollTop.value) - overscan)\n const end = Math.min(count, indexAt(scrollTop.value + height) + 1 + overscan)\n\n geometry.value = {\n start,\n end,\n offset: offsetAt(start),\n offsetEnd: Math.max(0, totalSize - offsetAt(end)),\n total: totalSize,\n }\n }\n\n const range = computed(() => ({ start: geometry.value.start, end: geometry.value.end }))\n const total = computed(() => geometry.value.total)\n const offset = computed(() => geometry.value.offset)\n const offsetEnd = computed(() => geometry.value.offsetEnd)\n\n const spacerStyle = computed(() => ({\n // Браузерный scroll anchoring обязан быть выключен. Он удерживает видимый\n // узел на месте, подправляя `scrollTop`, когда меняется высота содержимого\n // выше него, — а окно меняет её на каждом кадре прокрутки. Дальше пересчёт\n // окна и якорь начинают двигать список навстречу друг другу, и прокрутка\n // уезжает тем сильнее, чем дальше оценка строки от фактической высоты.\n 'overflow-anchor': 'none',\n '--gr-virtual-before': `${geometry.value.offset}px`,\n '--gr-virtual-after': `${geometry.value.offsetEnd}px`,\n }))\n\n function syncScrollTop(): void {\n const el = options.container.value\n if (!el)\n return\n\n scrollTop.value = el.scrollTop\n recompute()\n }\n\n function syncViewport(): void {\n const el = options.container.value\n if (!el)\n return\n\n measuredViewport.value = el.clientHeight\n recompute()\n }\n\n function measure(index: number, el: Element | null): void {\n if (!el)\n return\n\n observedIndex.set(el, index)\n sizeObserver?.observe(el)\n\n applySize(index, readSize(el))\n }\n\n function applySize(index: number, size: number): void {\n if (size <= 0)\n return\n\n const previous = measured.get(index)\n if (previous !== undefined && Math.abs(previous - size) < SIZE_EPSILON)\n return\n\n // Считаем смещение ДО правки: строка ниже вьюпорта позицию не двигает, а\n // строка выше — двигает всё содержимое под курсором.\n const start = offsetAt(index)\n const delta = size - (previous ?? estimateOf(index))\n\n measured.set(index, size)\n invalidateFrom(index)\n\n const el = options.container.value\n // Компенсация: без неё уточнение высоты уже прокрученных строк выглядит как\n // рывок списка вверх или вниз ровно в момент замера.\n if (delta !== 0 && start < scrollTop.value && el) {\n el.scrollTop += delta\n scrollTop.value = el.scrollTop\n }\n\n recompute()\n }\n\n function scrollToIndex(index: number, align: GrVirtualAlign = 'auto'): void {\n const el = options.container.value\n const count = options.count()\n if (!el || count === 0)\n return\n\n const clamped = Math.min(Math.max(index, 0), count - 1)\n const start = offsetAt(clamped)\n const size = sizeAt(clamped)\n const height = el.clientHeight || viewportSize()\n const end = start + size\n\n let next: number\n switch (align) {\n case 'start':\n next = start\n break\n case 'end':\n next = end - height\n break\n case 'center':\n next = start + size / 2 - height / 2\n break\n case 'auto':\n if (start < el.scrollTop)\n next = start\n else if (end > el.scrollTop + height)\n next = end - height\n else return\n break\n }\n\n el.scrollTop = Math.max(0, Math.min(next, offsetAt(count) - height))\n scrollTop.value = el.scrollTop\n recompute()\n }\n\n function detach(): void {\n if (!attachedTo)\n return\n attachedTo.removeEventListener('scroll', syncScrollTop)\n viewportObserver?.unobserve(attachedTo)\n attachedTo = null\n }\n\n // Первый снимок до всякого монтирования: на сервере и на первом клиентском\n // рендере контейнера ещё нет, а окно уже должно быть посчитано — и одинаково.\n recompute()\n\n watch(options.container, (el) => {\n detach()\n if (!el)\n return\n\n attachedTo = el\n el.addEventListener('scroll', syncScrollTop, { passive: true })\n viewportObserver?.observe(el)\n syncViewport()\n syncScrollTop()\n }, { immediate: true })\n\n // Длина списка изменилась. Сокращение дополнительно чистит хвост смещений и\n // замеров: он относится к строкам, которых больше нет.\n watch(() => options.count(), (count) => {\n if (count < builtTo)\n truncate(count)\n recompute()\n })\n\n function invalidate(from = 0): void {\n for (const index of [...measured.keys()]) {\n if (index >= from)\n measured.delete(index)\n }\n invalidateFrom(from)\n recompute()\n }\n\n if (options.source) {\n // Идентичность данных сменилась — замеры принадлежат прошлому набору.\n watch(options.source, () => invalidate())\n }\n\n function truncate(count: number): void {\n builtTo = count\n offsets = offsets.slice(0, count + 1)\n for (const index of [...measured.keys()]) {\n if (index >= count)\n measured.delete(index)\n }\n }\n\n onScopeDispose(() => {\n detach()\n sizeObserver?.disconnect()\n viewportObserver?.disconnect()\n })\n\n return { range, totalSize: total, offset, offsetEnd, spacerStyle, measure, scrollToIndex, invalidate }\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { t as ensurePortalRoot } from "../chunks/portalRoot-CVhCgdG6.js";
2
2
  import { n as markInert, t as inertableOutside } from "../chunks/inert-DIHCCn_1.js";
3
- import { t as GrLoading_default } from "../components/GrLoading/chunks/GrLoading-CMD3Ri9P.js";
3
+ import { t as GrLoading_default } from "../components/GrLoading/chunks/GrLoading-BDrlrup_.js";
4
4
  import { createVNode, render } from "vue";
5
5
  //#region src/directives/loading.ts
6
6
  function isHTMLElement(value) {
@@ -1,2 +1,2 @@
1
- import { a as granularityDefaultThemes, i as granularityComponentConfigs, n as GRANULARITY_PROVIDER_ID, o as granularityThemeNames, r as createGranularityProvider, t as granularityProvider } from "./chunks/granular-provider-Bp_BCBnr.js";
1
+ import { a as granularityDefaultThemes, i as granularityComponentConfigs, n as GRANULARITY_PROVIDER_ID, o as granularityThemeNames, r as createGranularityProvider, t as granularityProvider } from "./chunks/granular-provider-DP2gk0oa.js";
2
2
  export { GRANULARITY_PROVIDER_ID, createGranularityProvider, granularityProvider as default, granularityProvider, granularityComponentConfigs, granularityDefaultThemes, granularityThemeNames };
@@ -1,2 +1,2 @@
1
- import { a as granularityDefaultThemes, i as granularityComponentConfigs, n as GRANULARITY_PROVIDER_ID, o as granularityThemeNames, r as createGranularityProvider, t as granularityProvider } from "./chunks/granular-provider-Bp_BCBnr.js";
1
+ import { a as granularityDefaultThemes, i as granularityComponentConfigs, n as GRANULARITY_PROVIDER_ID, o as granularityThemeNames, r as createGranularityProvider, t as granularityProvider } from "./chunks/granular-provider-DP2gk0oa.js";
2
2
  export { GRANULARITY_PROVIDER_ID, createGranularityProvider, granularityProvider as default, granularityProvider, granularityComponentConfigs, granularityDefaultThemes, granularityThemeNames };
package/dist/index.js CHANGED
@@ -1,17 +1,17 @@
1
- import { a as useGrComponentSize, i as useGrComponentProp, n as resolveGrConfig, o as useGrConfig, r as useGrComponentDefaults, s as useGrThemeAttrs } from "./chunks/context-CTbuwcYs.js";
1
+ import { a as useGrComponentSize, i as useGrComponentProp, n as resolveGrConfig, o as useGrConfig, r as useGrComponentDefaults, s as useGrThemeAttrs } from "./chunks/context-CPMRfwVr.js";
2
2
  import { n as useGranularityTranslations } from "./chunks/granularityI18n-BC5zsj_d.js";
3
- import { t as GrAlert_default } from "./components/GrAlert/chunks/GrAlert-FAVf-ksH.js";
3
+ import { t as GrAlert_default } from "./components/GrAlert/chunks/GrAlert-D72y1IEh.js";
4
4
  import { t as grAlertConfig } from "./chunks/config-BNu8lFQB.js";
5
5
  import "./components/GrAlert/index.js";
6
- import { t as usePortalTarget } from "./chunks/usePortalTarget-C0p-mhaM.js";
6
+ import { t as usePortalTarget } from "./chunks/usePortalTarget-BhrRgdqW.js";
7
7
  import { vAutofocus } from "./directives/autofocus.js";
8
8
  import { vAutosize } from "./directives/autosize.js";
9
9
  import { vClickOutside } from "./directives/clickOutside.js";
10
10
  import { p as FileValidationError } from "./chunks/fileValidation-D5TFBhbv.js";
11
11
  import { vDropzone } from "./directives/dropzone.js";
12
12
  import { vHotkey } from "./directives/hotkey.js";
13
- import { t as GrIcon_default } from "./components/GrIcon/chunks/GrIcon-Dmf0c9ba.js";
14
- import { t as GrLoading_default } from "./components/GrLoading/chunks/GrLoading-CMD3Ri9P.js";
13
+ import { t as GrIcon_default } from "./components/GrIcon/chunks/GrIcon-DTZIgmje.js";
14
+ import { t as GrLoading_default } from "./components/GrLoading/chunks/GrLoading-BDrlrup_.js";
15
15
  import { createLoading, vLoading } from "./directives/loading.js";
16
16
  import { useFloating } from "./composables/useFloating.js";
17
17
  import { useOverlayLayer } from "./composables/useOverlayLayer.js";
@@ -21,191 +21,191 @@ import { n as useGrFormFieldContext } from "./chunks/context-DdNIxa1w.js";
21
21
  import { useGrFormControl } from "./composables/useGrFormControl.js";
22
22
  import { useComboboxNavigation } from "./composables/useComboboxNavigation.js";
23
23
  import { useRovingFocus } from "./composables/useRovingFocus.js";
24
- import { t as GrChip_default } from "./components/GrChip/chunks/GrChip-BTivtwff.js";
24
+ import { t as GrChip_default } from "./components/GrChip/chunks/GrChip-CKqyzYcv.js";
25
25
  import { n as grAutocompleteSafelist, t as grAutocompleteConfig } from "./chunks/config-CYthTVK2.js";
26
- import { t as GrAutocomplete_default } from "./components/GrAutocomplete/chunks/GrAutocomplete-BQsSE7sj.js";
26
+ import { t as GrAutocomplete_default } from "./components/GrAutocomplete/chunks/GrAutocomplete-BpmFmpKs.js";
27
27
  import { t as GrSkeleton_default } from "./components/GrSkeleton/chunks/GrSkeleton-CgfXxPQ2.js";
28
- import { n as GrAvatar_default, t as GrAvatarGroup_default } from "./components/GrAvatar/chunks/GrAvatar-CNmLmgcr.js";
28
+ import { n as GrAvatar_default, t as GrAvatarGroup_default } from "./components/GrAvatar/chunks/GrAvatar-dWEXiCJG.js";
29
29
  import { c as initialsFrom, n as grAvatarSafelist, t as grAvatarConfig } from "./chunks/config-B3J0alyY.js";
30
- import { t as GrBadge_default } from "./components/GrBadge/chunks/GrBadge-DpUDXKbq.js";
30
+ import { t as GrBadge_default } from "./components/GrBadge/chunks/GrBadge-DBeQXEir.js";
31
31
  import { t as grBadgeSafelist } from "./chunks/safelist-x8USecK8.js";
32
32
  import { t as grBadgeConfig } from "./chunks/config-BscVxZR3.js";
33
33
  import { n as grBadgeWrapSafelist, o as formatBadgeValue, t as grBadgeWrapConfig } from "./chunks/config-DwABJHEo.js";
34
- import { t as GrBadgeWrap_default } from "./components/GrBadgeWrap/chunks/GrBadgeWrap-B-A3PRkE.js";
34
+ import { t as GrBadgeWrap_default } from "./components/GrBadgeWrap/chunks/GrBadgeWrap-wdfxaXiu.js";
35
35
  import { n as grBottomNavSafelist, t as grBottomNavConfig } from "./chunks/config-DM0lsduD.js";
36
- import { t as GrBottomNav_default } from "./components/GrBottomNav/chunks/GrBottomNav-wtFatLjB.js";
37
- import { t as GrLink_default } from "./components/GrLink/chunks/GrLink-DYXw3W9w.js";
36
+ import { t as GrBottomNav_default } from "./components/GrBottomNav/chunks/GrBottomNav-nE08pVUJ.js";
37
+ import { t as GrLink_default } from "./components/GrLink/chunks/GrLink-DwWErumU.js";
38
38
  import { g as resolveBreadcrumbsLayout, h as resolveBreadcrumbsFit, n as grBreadcrumbsSafelist, t as grBreadcrumbsConfig } from "./chunks/config-C0Eu8jpG.js";
39
- import { t as GrBreadcrumbs_default } from "./components/GrBreadcrumbs/chunks/GrBreadcrumbs-DRDNan_n.js";
39
+ import { t as GrBreadcrumbs_default } from "./components/GrBreadcrumbs/chunks/GrBreadcrumbs-DOpwY2EF.js";
40
40
  import { n as useGrButtonGroup } from "./chunks/context-BfIQv7m1.js";
41
- import { t as GrButton_default } from "./components/GrButton/chunks/GrButton-7GP0zObj.js";
41
+ import { t as GrButton_default } from "./components/GrButton/chunks/GrButton-CS4TqMtG.js";
42
42
  import { t as grButtonSafelist } from "./chunks/safelist-DxkMj5IW.js";
43
43
  import { t as grButtonConfig } from "./chunks/config-87fszqnD.js";
44
44
  import { t as GrButtonGroup_default } from "./components/GrButtonGroup/chunks/GrButtonGroup-CKyiAV8K.js";
45
- import { t as grButtonGroupConfig } from "./chunks/config-DBmdgoVf2.js";
45
+ import { t as grButtonGroupConfig } from "./chunks/config-DBmdgoVf.js";
46
46
  import "./components/GrButtonGroup/index.js";
47
47
  import { n as grCardSafelist, t as grCardConfig } from "./chunks/config-DUbbGcfw.js";
48
- import { t as GrCard_default } from "./components/GrCard/chunks/GrCard-BttXz1pQ.js";
49
- import { t as GrCheckbox_default } from "./components/GrCheckbox/chunks/GrCheckbox-CEcHIsXM.js";
48
+ import { t as GrCard_default } from "./components/GrCard/chunks/GrCard-Ck5--lMF.js";
49
+ import { t as GrCheckbox_default } from "./components/GrCheckbox/chunks/GrCheckbox-Dp201frb.js";
50
50
  import { n as grCheckboxSafelist, t as grCheckboxConfig } from "./chunks/config-DZCUPHPU.js";
51
51
  import "./components/GrCheckbox/index.js";
52
- import { t as GrCheckboxGroup_default } from "./components/GrCheckboxGroup/chunks/GrCheckboxGroup-BOwrVcFr.js";
52
+ import { t as GrCheckboxGroup_default } from "./components/GrCheckboxGroup/chunks/GrCheckboxGroup-IpqG5qwm.js";
53
53
  import { t as grCheckboxGroupConfig } from "./chunks/config-BuGlNPE9.js";
54
54
  import { n as grChipSafelist, t as grChipConfig } from "./chunks/config-2vrOFn2f.js";
55
55
  import "./components/GrChip/index.js";
56
56
  import { n as grChipGroupSafelist, t as grChipGroupConfig } from "./chunks/config-CZPDPJlg.js";
57
- import { t as GrChipGroup_default } from "./components/GrChipGroup/chunks/GrChipGroup-C78Vcwos.js";
57
+ import { t as GrChipGroup_default } from "./components/GrChipGroup/chunks/GrChipGroup-dDGwnC04.js";
58
58
  import { useAnnouncer } from "./composables/useAnnouncer.js";
59
- import { t as GrCodeBlock_default } from "./components/GrCodeBlock/chunks/GrCodeBlock-Dp0eEBTZ.js";
59
+ import { t as GrCodeBlock_default } from "./components/GrCodeBlock/chunks/GrCodeBlock-BUOwKwQE.js";
60
60
  import { n as grCodeBlockSafelist, t as grCodeBlockConfig } from "./chunks/config-DolULhjJ.js";
61
61
  import { n as grCollapseSafelist, t as grCollapseConfig } from "./chunks/config-BoUI0t-t.js";
62
- import { n as GrCollapse_default, t as GrCollapseItem_default } from "./components/GrCollapse/chunks/GrCollapse-BlW6ybdL.js";
62
+ import { n as GrCollapse_default, t as GrCollapseItem_default } from "./components/GrCollapse/chunks/GrCollapse-DWH3QAnU.js";
63
63
  import { n as grIconSafelist, t as grIconConfig } from "./chunks/config-3bQeQvqd.js";
64
- import { t as GrInput_default } from "./components/GrInput/chunks/GrInput-CJ7eu3fR.js";
64
+ import { t as GrInput_default } from "./components/GrInput/chunks/GrInput-TFeBm3gQ.js";
65
65
  import { t as useFocusTrap } from "./chunks/useFocusTrap-D9bIPNF6.js";
66
- import { t as GrPopover_default } from "./components/GrPopover/chunks/GrPopover-DEFxDffj.js";
66
+ import { t as GrPopover_default } from "./components/GrPopover/chunks/GrPopover-BakLcWkX.js";
67
67
  import { useDragGesture } from "./composables/useDragGesture.js";
68
- import { t as GrSlider_default } from "./components/GrSlider/chunks/GrSlider-DM6W6U9c.js";
69
- import { t as GrColorPicker_default } from "./components/GrColorPicker/chunks/GrColorPicker-B-L4CWMt.js";
68
+ import { t as GrSlider_default } from "./components/GrSlider/chunks/GrSlider-Db-jACXz.js";
69
+ import { t as GrColorPicker_default } from "./components/GrColorPicker/chunks/GrColorPicker-BNtpj_P6.js";
70
70
  import { n as grColorPickerSafelist, t as grColorPickerConfig } from "./chunks/config-DIDz_E5m.js";
71
- import { a as GR_KBD_TOKENS, o as findKbdToken, t as GrKbd_default } from "./components/GrKbd/chunks/GrKbd-D2ga1H9i.js";
72
- import { t as GrModal_default } from "./components/GrModal/chunks/GrModal-DixnhJcu.js";
73
- import { t as GrCommandPalette_default } from "./components/GrCommandPalette/chunks/GrCommandPalette-8HkYmMVP.js";
71
+ import { a as GR_KBD_TOKENS, o as findKbdToken, t as GrKbd_default } from "./components/GrKbd/chunks/GrKbd-D_a1mPLe.js";
72
+ import { t as GrModal_default } from "./components/GrModal/chunks/GrModal-xIWaJozo.js";
73
+ import { t as GrCommandPalette_default } from "./components/GrCommandPalette/chunks/GrCommandPalette-BVZEd4yy.js";
74
74
  import { n as grCommandPaletteSafelist, t as grCommandPaletteConfig } from "./chunks/config-D0NzGYaE.js";
75
- import { t as GrConfigProvider_default } from "./components/GrConfigProvider/chunks/GrConfigProvider-BF7R3hgg.js";
75
+ import { t as GrConfigProvider_default } from "./components/GrConfigProvider/chunks/GrConfigProvider-t9x2UToH.js";
76
76
  import { t as grConfigProviderConfig } from "./chunks/config-B7W9VlZ7.js";
77
- import { i as GrDialogFooter_default, n as GrDialogHeader_default, r as GrDialogCloseButton_default, t as GrDialog_default } from "./components/GrDialog/chunks/GrDialog-CKNbnxwO.js";
78
- import { a as extendDefaultParsers, n as coreResponseErrorParsers, r as createResponseErrorClassifier, s as normalizeError, t as GrResponseErrorBanner_default } from "./components/GrResponseErrorBanner/chunks/GrResponseErrorBanner-DMeOWlzj.js";
79
- import { t as GrConfirmDialog_default } from "./components/GrConfirmDialog/chunks/GrConfirmDialog-CZEO2JR4.js";
77
+ import { i as GrDialogFooter_default, n as GrDialogHeader_default, r as GrDialogCloseButton_default, t as GrDialog_default } from "./components/GrDialog/chunks/GrDialog-CeJubnKJ.js";
78
+ import { a as extendDefaultParsers, n as coreResponseErrorParsers, r as createResponseErrorClassifier, s as normalizeError, t as GrResponseErrorBanner_default } from "./components/GrResponseErrorBanner/chunks/GrResponseErrorBanner-NEEJZ8zi.js";
79
+ import { t as GrConfirmDialog_default } from "./components/GrConfirmDialog/chunks/GrConfirmDialog-K5ht2cYq.js";
80
80
  import { t as grConfirmDialogConfig } from "./chunks/config-A-bBiotF.js";
81
81
  import "./components/GrConfirmDialog/index.js";
82
82
  import { a as GrDropdownMenuItem_default, c as GrDropdownMenuDivider_default, o as GrDropdownMenuGroup_default, s as GrDropdownMenuHeader_default, t as GrDropdownMenuList_default } from "./components/GrDropdownMenu/chunks/GrDropdownMenuList-B33ZzwfB.js";
83
- import { t as GrContextMenu_default } from "./components/GrContextMenu/chunks/GrContextMenu-DlFWm0eW.js";
83
+ import { t as GrContextMenu_default } from "./components/GrContextMenu/chunks/GrContextMenu-Dd2tgMoL.js";
84
84
  import { t as grContextMenuConfig } from "./chunks/config-CsCUuukB.js";
85
- import { t as GrTable_default } from "./components/GrTable/chunks/GrTable-jhUTczjv.js";
85
+ import { t as GrTable_default } from "./components/GrTable/chunks/GrTable-iwzHvlMC.js";
86
86
  import { t as useDragSort } from "./chunks/useDragSort-0l47h4yb.js";
87
- import { t as GrDataTable_default } from "./components/GrDataTable/chunks/GrDataTable-4JAgOQ-7.js";
87
+ import { t as GrDataTable_default } from "./components/GrDataTable/chunks/GrDataTable-BYYG_XZA.js";
88
88
  import { n as grDataTableSafelist, t as grDataTableConfig } from "./chunks/config-DeyT9dJl.js";
89
- import { t as GrDelta_default } from "./components/GrDelta/chunks/GrDelta-BZwkgQW-.js";
89
+ import { t as GrDelta_default } from "./components/GrDelta/chunks/GrDelta-BpfqebEV.js";
90
90
  import { n as grValueSafelist, t as grValueConfig } from "./chunks/config-Z5LeUXys.js";
91
91
  import { t as GrValue_default } from "./components/GrValue/chunks/GrValue-ezkQM05Q.js";
92
92
  import { n as deltaTone, t as deltaDirection } from "./chunks/deltaTone-B5OoS1vo.js";
93
93
  import { n as grDeltaSafelist, t as grDeltaConfig } from "./chunks/config-CjWOTgLL.js";
94
- import { n as grDescriptionListSafelist, t as grDescriptionListConfig } from "./chunks/config-CnYdE3HZ2.js";
95
- import { t as GrDescriptionList_default } from "./components/GrDescriptionList/chunks/GrDescriptionList-BMeCgFV3.js";
94
+ import { n as grDescriptionListSafelist, t as grDescriptionListConfig } from "./chunks/config-CnYdE3HZ.js";
95
+ import { t as GrDescriptionList_default } from "./components/GrDescriptionList/chunks/GrDescriptionList-D8ANFpn_.js";
96
96
  import { t as grDialogSafelist } from "./chunks/safelist-Y3zrlhOa.js";
97
97
  import "./components/GrDialog/index.js";
98
98
  import { n as useGrFormContext } from "./chunks/context-Bfrgsluh.js";
99
- import { t as GrFormField_default } from "./components/GrFormField/chunks/GrFormField-DSylU7IU.js";
100
- import { t as GrTextarea_default } from "./components/GrTextarea/chunks/GrTextarea-DinXG12-.js";
101
- import { n as getByPath, o as runFieldRules, r as isEmpty, s as setByPath, t as createGrFormMessageResolver } from "./chunks/validation-5HhpanPP.js";
102
- import { t as GrPromptDialog_default } from "./components/GrPromptDialog/chunks/GrPromptDialog-Ckeombia.js";
103
- import { a as useDialogService, i as teardownDialogService, n as dialogService, r as granularityDialogServicePlugin, t as GrDialogServiceHost_default } from "./components/GrDialogService/chunks/GrDialogService-Ut8iiBQh.js";
99
+ import { t as GrFormField_default } from "./components/GrFormField/chunks/GrFormField-DO61vxpS.js";
100
+ import { t as GrTextarea_default } from "./components/GrTextarea/chunks/GrTextarea-BII3w61K.js";
101
+ import { n as getByPath, o as runFieldRules, r as isEmpty, s as setByPath, t as createGrFormMessageResolver } from "./chunks/validation-BDjqsuGB.js";
102
+ import { t as GrPromptDialog_default } from "./components/GrPromptDialog/chunks/GrPromptDialog-C9Y1ifE_.js";
103
+ import { a as useDialogService, i as teardownDialogService, n as dialogService, r as granularityDialogServicePlugin, t as GrDialogServiceHost_default } from "./components/GrDialogService/chunks/GrDialogService-BArvw1DV.js";
104
104
  import { t as grDialogServiceConfig } from "./chunks/config-CjXjhphs.js";
105
105
  import { n as grDividerSafelist, t as grDividerConfig } from "./chunks/config-D82r782v.js";
106
- import { t as GrDivider_default } from "./components/GrDivider/chunks/GrDivider-BXavGcMX.js";
106
+ import { t as GrDivider_default } from "./components/GrDivider/chunks/GrDivider-DxA-zV25.js";
107
107
  import { n as grDrawerSafelist, t as grDrawerConfig } from "./chunks/config-ChPg-BQv.js";
108
- import { t as GrDrawer_default } from "./components/GrDrawer/chunks/GrDrawer-xfoy-MCj.js";
109
- import { t as GrDropdown_default } from "./components/GrDropdown/chunks/GrDropdown-7r772-Cq.js";
108
+ import { t as GrDrawer_default } from "./components/GrDrawer/chunks/GrDrawer-BBHNgeH0.js";
109
+ import { t as GrDropdown_default } from "./components/GrDropdown/chunks/GrDropdown-CUlviqMi.js";
110
110
  import { n as grDropdownSafelist, t as grDropdownConfig } from "./chunks/config-CT4lP6S4.js";
111
111
  import "./components/GrDropdown/index.js";
112
- import { n as GrDropdownMenuColumn_default, r as GrDropdownMenu_default, t as GrDropdownMenuColumns_default } from "./components/GrDropdownMenu/chunks/GrDropdownMenu-DNurbsWc.js";
112
+ import { n as GrDropdownMenuColumn_default, r as GrDropdownMenu_default, t as GrDropdownMenuColumns_default } from "./components/GrDropdownMenu/chunks/GrDropdownMenu-COOR1LCs.js";
113
113
  import { n as grDropdownMenuSafelist, t as grDropdownMenuConfig } from "./chunks/config-_jbgsFpw.js";
114
- import { t as GrEmptyState_default } from "./components/GrEmptyState/chunks/GrEmptyState-RqsWvgI9.js";
114
+ import { t as GrEmptyState_default } from "./components/GrEmptyState/chunks/GrEmptyState-BbvwE-E0.js";
115
115
  import { n as grEmptyStateSafelist, t as grEmptyStateConfig } from "./chunks/config-CWtfxkM9.js";
116
- import { n as fileKindOf, r as isPreviewableKind, t as GrFilePreview_default } from "./components/GrFilePreview/chunks/GrFilePreview-C9Z7hMK8.js";
116
+ import { n as fileKindOf, r as isPreviewableKind, t as GrFilePreview_default } from "./components/GrFilePreview/chunks/GrFilePreview-PabkLgYX.js";
117
117
  import { n as grFilePreviewSafelist, t as grFilePreviewConfig } from "./chunks/config-BaWANzzB.js";
118
- import { t as GrProgressBar_default } from "./components/GrProgressBar/chunks/GrProgressBar-Cd7AaJtR.js";
119
- import { n as GrUploadAbortError, r as GrUploadHttpError, t as GrFileUpload_default } from "./components/GrFileUpload/chunks/GrFileUpload-C0ROpmOY.js";
118
+ import { t as GrProgressBar_default } from "./components/GrProgressBar/chunks/GrProgressBar-C3NRBqIP.js";
119
+ import { n as GrUploadAbortError, r as GrUploadHttpError, t as GrFileUpload_default } from "./components/GrFileUpload/chunks/GrFileUpload-BwMR71zN.js";
120
120
  import { n as grFileUploadSafelist, t as grFileUploadConfig } from "./chunks/config-BlJa1Mj9.js";
121
- import { t as GrForm_default } from "./components/GrForm/chunks/GrForm-CrnfCsgj.js";
121
+ import { t as GrForm_default } from "./components/GrForm/chunks/GrForm-xTtavR-K.js";
122
122
  import { t as grFormConfig } from "./chunks/config-Droqn55j.js";
123
123
  import { n as grFormFieldSafelist, t as grFormFieldConfig } from "./chunks/config-B0uvcTPH.js";
124
124
  import "./components/GrFormField/index.js";
125
- import { t as GrFormFile_default } from "./components/GrFormFile/chunks/GrFormFile-B1jGZyIj.js";
125
+ import { t as GrFormFile_default } from "./components/GrFormFile/chunks/GrFormFile-Dlxx-9zi.js";
126
126
  import { n as grFormFileSafelist, t as grFormFileConfig } from "./chunks/config-BcXX7S7B.js";
127
127
  import { n as grFormSectionSafelist, t as grFormSectionConfig } from "./chunks/config-BEO7brpO.js";
128
- import { t as GrFormSection_default } from "./components/GrFormSection/chunks/GrFormSection-ejieOg9H.js";
129
- import { t as GrImageViewer_default } from "./components/GrImageViewer/chunks/GrImageViewer--BU8yrfx.js";
128
+ import { t as GrFormSection_default } from "./components/GrFormSection/chunks/GrFormSection-DV1S6R_N.js";
129
+ import { t as GrImageViewer_default } from "./components/GrImageViewer/chunks/GrImageViewer-BjYw-uTF.js";
130
130
  import { n as grImageViewerSafelist, t as grImageViewerConfig } from "./chunks/config-BDSaD-5p.js";
131
131
  import { n as grInputSafelist, t as grInputConfig } from "./chunks/config-CIkdsWUk.js";
132
132
  import "./components/GrInput/index.js";
133
133
  import { n as grInputTagSafelist, t as grInputTagConfig } from "./chunks/config-BqT6PMzO.js";
134
- import { t as GrInputTag_default } from "./components/GrInputTag/chunks/GrInputTag-ByD9NugQ.js";
135
- import { t as GrTree_default } from "./components/GrTree/chunks/GrTree-Ci6CZfKR.js";
136
- import { t as GrJsonViewer_default } from "./components/GrJsonViewer/chunks/GrJsonViewer-BXG7DdTe.js";
137
- import { n as grJsonViewerSafelist, t as grJsonViewerConfig } from "./chunks/config-DpAYidyY2.js";
134
+ import { t as GrInputTag_default } from "./components/GrInputTag/chunks/GrInputTag-DhfUNOA5.js";
135
+ import { t as GrTree_default } from "./components/GrTree/chunks/GrTree-CkELQwR8.js";
136
+ import { t as GrJsonViewer_default } from "./components/GrJsonViewer/chunks/GrJsonViewer-CdtmUpZ3.js";
137
+ import { n as grJsonViewerSafelist, t as grJsonViewerConfig } from "./chunks/config-DpAYidyY.js";
138
138
  import { n as grKbdSafelist, t as grKbdConfig } from "./chunks/config-BRESvs9g.js";
139
139
  import "./components/GrKbd/index.js";
140
- import { n as grLinkSafelist, t as grLinkConfig } from "./chunks/config-CQLNjc9X2.js";
140
+ import { n as grLinkSafelist, t as grLinkConfig } from "./chunks/config-CQLNjc9X.js";
141
141
  import "./components/GrLink/index.js";
142
142
  import { n as grListSafelist, t as grListConfig } from "./chunks/config-D0W8mGFD.js";
143
- import { n as GrList_default, t as GrListItem_default } from "./components/GrList/chunks/GrList-B_CRJB4c.js";
143
+ import { n as GrList_default, t as GrListItem_default } from "./components/GrList/chunks/GrList-Unya-LXb.js";
144
144
  import { n as grLoadingSafelist, t as grLoadingConfig } from "./chunks/config-Bjn30smH.js";
145
145
  import "./components/GrLoading/index.js";
146
146
  import { n as grModalSafelist, t as grModalConfig } from "./chunks/config-DBi0GVce.js";
147
147
  import "./components/GrModal/index.js";
148
- import { t as GrNavbar_default } from "./components/GrNavbar/chunks/GrNavbar-Dr8e5kW-.js";
148
+ import { t as GrNavbar_default } from "./components/GrNavbar/chunks/GrNavbar-BRGuksiy.js";
149
149
  import { n as grNavbarSafelist, t as grNavbarConfig } from "./chunks/config-2ZHRsdOc.js";
150
- import { n as grNumberInputSafelist, t as grNumberInputConfig } from "./chunks/config-MmPym-Z72.js";
151
- import { t as GrNumberInput_default } from "./components/GrNumberInput/chunks/GrNumberInput-DQ59YICu.js";
152
- import { t as GrSelect_default } from "./components/GrSelect/chunks/GrSelect-Bm3Jugx8.js";
150
+ import { n as grNumberInputSafelist, t as grNumberInputConfig } from "./chunks/config-MmPym-Z7.js";
151
+ import { t as GrNumberInput_default } from "./components/GrNumberInput/chunks/GrNumberInput-BqPydXpK.js";
152
+ import { t as GrSelect_default } from "./components/GrSelect/chunks/GrSelect-Do1iAyp1.js";
153
153
  import { n as grPaginationSafelist, t as grPaginationConfig } from "./chunks/config-CjKpUcmy.js";
154
- import { t as GrPagination_default } from "./components/GrPagination/chunks/GrPagination-68iyAwQz.js";
155
- import { n as grPopoverSafelist, t as grPopoverConfig } from "./chunks/config-DVCNvhIG2.js";
154
+ import { t as GrPagination_default } from "./components/GrPagination/chunks/GrPagination-DhbNZHEF.js";
155
+ import { n as grPopoverSafelist, t as grPopoverConfig } from "./chunks/config-DVCNvhIG.js";
156
156
  import "./components/GrPopover/index.js";
157
157
  import { n as grProgressBarSafelist, r as GR_TONES, t as grProgressBarConfig } from "./chunks/config-DWL81-aM.js";
158
158
  import "./components/GrProgressBar/index.js";
159
- import { t as GrProgressCircle_default } from "./components/GrProgressCircle/chunks/GrProgressCircle-D3yWXYDa.js";
159
+ import { t as GrProgressCircle_default } from "./components/GrProgressCircle/chunks/GrProgressCircle-CdvbINQc.js";
160
160
  import { n as grProgressCircleSafelist, t as grProgressCircleConfig } from "./chunks/config-CJzmDHfI.js";
161
161
  import { t as grPromptDialogConfig } from "./chunks/config-C0Ea9ePP.js";
162
162
  import "./components/GrPromptDialog/index.js";
163
- import { t as GrRadio_default } from "./components/GrRadio/chunks/GrRadio-Aq3v8XgG.js";
164
- import { n as grRadioSafelist, t as grRadioConfig } from "./chunks/config-CuQmUkMw2.js";
163
+ import { t as GrRadio_default } from "./components/GrRadio/chunks/GrRadio-B1776V9D.js";
164
+ import { n as grRadioSafelist, t as grRadioConfig } from "./chunks/config-BUNxHnEz.js";
165
165
  import "./components/GrRadio/index.js";
166
- import { t as GrRadioGroup_default } from "./components/GrRadioGroup/chunks/GrRadioGroup-y9LVdTWh.js";
166
+ import { t as GrRadioGroup_default } from "./components/GrRadioGroup/chunks/GrRadioGroup-UgitrBFl.js";
167
167
  import { t as grRadioGroupConfig } from "./chunks/config-QaIc_gRa.js";
168
168
  import { n as grRatingSafelist, t as grRatingConfig } from "./chunks/config-DRbojEzO.js";
169
- import { t as GrRating_default } from "./components/GrRating/chunks/GrRating-IEiTOdnF.js";
170
- import { n as GrFormErrorBanner_default, r as GrUploadErrorBanner_default, t as useResponseError } from "./components/GrResponseErrorBanner/chunks/GrResponseErrorBanner-CBVRpgIG.js";
171
- import { n as titleWhenTruncated, t as GrSegmented_default } from "./components/GrSegmented/chunks/GrSegmented-CB-VR-yL.js";
169
+ import { t as GrRating_default } from "./components/GrRating/chunks/GrRating-DTriyyqG.js";
170
+ import { n as GrFormErrorBanner_default, r as GrUploadErrorBanner_default, t as useResponseError } from "./components/GrResponseErrorBanner/chunks/GrResponseErrorBanner-ZvBvEQDZ.js";
171
+ import { n as titleWhenTruncated, t as GrSegmented_default } from "./components/GrSegmented/chunks/GrSegmented-NKTi9bMG.js";
172
172
  import { n as grSegmentedSafelist, t as grSegmentedConfig } from "./chunks/config-rLkc9Zn2.js";
173
173
  import { n as grSelectSafelist, t as grSelectConfig } from "./chunks/config-DOYz_SVK.js";
174
174
  import "./components/GrSelect/index.js";
175
175
  import { n as grSidebarSafelist, t as grSidebarConfig } from "./chunks/config-DNDgp9bB.js";
176
- import { n as GrSidebarItem_default, r as GrSidebar_default, t as GrSidebarGroup_default } from "./components/GrSidebar/chunks/GrSidebar-alkwBUzL.js";
176
+ import { n as GrSidebarItem_default, r as GrSidebar_default, t as GrSidebarGroup_default } from "./components/GrSidebar/chunks/GrSidebar-DoKLlHSw.js";
177
177
  import { t as grSkeletonConfig } from "./chunks/config-8Pcutu1j.js";
178
178
  import "./components/GrSkeleton/index.js";
179
179
  import { n as grSliderSafelist, t as grSliderConfig } from "./chunks/config-E1cTyRVV.js";
180
180
  import "./components/GrSlider/index.js";
181
181
  import { n as grSortableListSafelist, t as grSortableListConfig } from "./chunks/config-CbEbLyDE.js";
182
- import { t as GrSortableList_default } from "./components/GrSortableList/chunks/GrSortableList-HyKX--rO.js";
182
+ import { t as GrSortableList_default } from "./components/GrSortableList/chunks/GrSortableList-CQCaWivn.js";
183
183
  import { n as grSplitterSafelist, t as grSplitterConfig } from "./chunks/config-CvbVM4ep.js";
184
- import { n as sizeFromPointer, t as GrSplitter_default } from "./components/GrSplitter/chunks/GrSplitter-MltjaADn.js";
185
- import { n as formatStatisticValue, t as GrStatistic_default } from "./components/GrStatistic/chunks/GrStatistic-BoLkXw7F.js";
184
+ import { n as sizeFromPointer, t as GrSplitter_default } from "./components/GrSplitter/chunks/GrSplitter-C-XQzq7q.js";
185
+ import { n as formatStatisticValue, t as GrStatistic_default } from "./components/GrStatistic/chunks/GrStatistic-C1_nY4Gc.js";
186
186
  import { n as grStatisticSafelist, t as grStatisticConfig } from "./chunks/config-DGC00bTp.js";
187
187
  import { n as grStepsSafelist, t as grStepsConfig } from "./chunks/config-CLjjjPZj.js";
188
- import { t as GrSteps_default } from "./components/GrSteps/chunks/GrSteps-CpGHXLOc.js";
188
+ import { t as GrSteps_default } from "./components/GrSteps/chunks/GrSteps-DXj7m-WO.js";
189
189
  import { n as grSwitchSafelist, t as grSwitchConfig } from "./chunks/config-Yy67uWHY.js";
190
- import { t as GrSwitch_default } from "./components/GrSwitch/chunks/GrSwitch-7Oe5QfQZ.js";
190
+ import { t as GrSwitch_default } from "./components/GrSwitch/chunks/GrSwitch-CriHWT2A.js";
191
191
  import { n as grTableSafelist, t as grTableConfig } from "./chunks/config-DCq4JySZ.js";
192
192
  import "./components/GrTable/index.js";
193
- import { n as GrTabPanels_default, t as GrTabPanel_default } from "./components/GrTabPanels/chunks/GrTabPanels-BZQS8-JM.js";
193
+ import { n as GrTabPanels_default, t as GrTabPanel_default } from "./components/GrTabPanels/chunks/GrTabPanels-5zsbqS1v.js";
194
194
  import { t as grTabPanelsConfig } from "./chunks/config-eXB87DOi.js";
195
- import { t as GrTabs_default } from "./components/GrTabs/chunks/GrTabs-CT2nk_HV.js";
195
+ import { t as GrTabs_default } from "./components/GrTabs/chunks/GrTabs-DHfv67cp.js";
196
196
  import { n as grTabsSafelist, t as grTabsConfig } from "./chunks/config-CMNfZO7S.js";
197
197
  import { n as grTextareaSafelist, t as grTextareaConfig } from "./chunks/config-BhfNgyWL.js";
198
198
  import "./components/GrTextarea/index.js";
199
- import { n as GrTimeline_default, t as GrTimelineItem_default } from "./components/GrTimeline/chunks/GrTimeline-BiHpArsg.js";
199
+ import { n as GrTimeline_default, t as GrTimelineItem_default } from "./components/GrTimeline/chunks/GrTimeline-Bs60huw0.js";
200
200
  import { n as grTimelineSafelist, t as grTimelineConfig } from "./chunks/config-Bd7QfiGj.js";
201
201
  import { GRANULARITY_TOAST_STATE, granularityToastPlugin, useToast } from "./composables/useToast.js";
202
202
  import { n as grToasterSafelist, t as grToasterConfig } from "./chunks/config-B5SBUa6u.js";
203
- import { t as GrToaster_default } from "./components/GrToaster/chunks/GrToaster-COXIBKzq.js";
203
+ import { t as GrToaster_default } from "./components/GrToaster/chunks/GrToaster-D-sV-9of.js";
204
204
  import { n as grTooltipSafelist, t as grTooltipConfig } from "./chunks/config-BTmfQFwi.js";
205
- import { t as GrTooltip_default } from "./components/GrTooltip/chunks/GrTooltip-uYETdbCD.js";
205
+ import { t as GrTooltip_default } from "./components/GrTooltip/chunks/GrTooltip-BUiTbROv.js";
206
206
  import { n as grTreeSafelist, t as grTreeConfig } from "./chunks/config-CDat1wXf.js";
207
207
  import { n as grTreeSelectSafelist, t as grTreeSelectConfig } from "./chunks/config-DUNH02Fg.js";
208
- import { t as GrTreeSelect_default } from "./components/GrTreeSelect/chunks/GrTreeSelect-MGsyvkJV.js";
208
+ import { t as GrTreeSelect_default } from "./components/GrTreeSelect/chunks/GrTreeSelect-DurwZ7Cz.js";
209
209
  import "./composables/useGrComponentConfig.js";
210
210
  import "./composables/useGranularityTranslations.js";
211
211
  import { GRANULARITY_THEME_STATE, granularityThemePlugin, initThemeEarly, useTheme } from "./composables/useTheme.js";
package/dist/testing.js CHANGED
@@ -1,4 +1,4 @@
1
- import { t as GR_CONFIG_KEY } from "./chunks/context-CTbuwcYs.js";
1
+ import { t as GR_CONFIG_KEY } from "./chunks/context-CPMRfwVr.js";
2
2
  import { t as GRANULARITY_I18N_KEY } from "./chunks/adapter-CAOxmn2G.js";
3
3
  import { n as resetPortalRoot } from "./chunks/portalRoot-CVhCgdG6.js";
4
4
  import { resetAnnouncer } from "./composables/useAnnouncer.js";