@feugene/granularity 0.16.0 → 0.18.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 (343) hide show
  1. package/dist/chunks/{config-Zc_bUvZY2.js → config-BDfTXHo12.js} +1 -1
  2. package/dist/chunks/{config-Zc_bUvZY2.js.map → config-BDfTXHo12.js.map} +1 -1
  3. package/dist/chunks/config-BE6n20np2.js.map +1 -0
  4. package/dist/chunks/{config-CpwwkFBO.js → config-Baj7Wvx-.js} +1 -1
  5. package/dist/chunks/{config-CpwwkFBO.js.map → config-Baj7Wvx-.js.map} +1 -1
  6. package/dist/chunks/config-BoNR7_PD2.js.map +1 -0
  7. package/dist/chunks/{config-DxCTVBfx.js → config-BsPDQ0dS.js} +2 -2
  8. package/dist/chunks/config-BsPDQ0dS.js.map +1 -0
  9. package/dist/chunks/config-CN2ULSQL.js.map +1 -0
  10. package/dist/chunks/{config-Cw6TDzWv2.js → config-COpuWGr_.js} +1 -1
  11. package/dist/chunks/config-COpuWGr_.js.map +1 -0
  12. package/dist/chunks/config-D2aNP7Es.js +70 -0
  13. package/dist/chunks/config-D2aNP7Es.js.map +1 -0
  14. package/dist/chunks/config-D94Z9po5.js.map +1 -0
  15. package/dist/chunks/{config-B-g6lT19.js → config-DA6SnEoy.js} +5 -2
  16. package/dist/chunks/config-DA6SnEoy.js.map +1 -0
  17. package/dist/chunks/config-DCFvmHEv2.js.map +1 -0
  18. package/dist/chunks/config-DEvsMTQE.js +150 -0
  19. package/dist/chunks/config-DEvsMTQE.js.map +1 -0
  20. package/dist/chunks/{config-CvC0sX8p.js → config-MRvhUl-O.js} +1 -1
  21. package/dist/chunks/{config-CvC0sX8p.js.map → config-MRvhUl-O.js.map} +1 -1
  22. package/dist/chunks/config-ScuvHw6k2.js +42 -0
  23. package/dist/chunks/config-ScuvHw6k2.js.map +1 -0
  24. package/dist/chunks/config-T3qdQBgU2.js.map +1 -0
  25. package/dist/chunks/config-eXB87DOi.js.map +1 -0
  26. package/dist/chunks/{config-D8tSR2uS.js → config-gvq_hWNM.js} +1 -1
  27. package/dist/chunks/{config-D8tSR2uS.js.map → config-gvq_hWNM.js.map} +1 -1
  28. package/dist/chunks/context-BSYR7RZs.js.map +1 -1
  29. package/dist/chunks/{en-B3xMeswz.js → en-COdzxgAX.js} +30 -5
  30. package/dist/chunks/en-COdzxgAX.js.map +1 -0
  31. package/dist/chunks/{es-CA-mkU--.js → es-ClqJ-4hr.js} +30 -5
  32. package/dist/chunks/es-ClqJ-4hr.js.map +1 -0
  33. package/dist/chunks/{es-Bv8vvqdT.js → es-DGMHwknJ.js} +3 -3
  34. package/dist/chunks/{es-Bv8vvqdT.js.map → es-DGMHwknJ.js.map} +1 -1
  35. package/dist/chunks/grKbdStyles-CeZhGQHr.js +43 -0
  36. package/dist/chunks/grKbdStyles-CeZhGQHr.js.map +1 -0
  37. package/dist/chunks/{grTextareaStyles-CWI2SqC8.js → grTextareaStyles-iOcHuVMM.js} +2 -2
  38. package/dist/chunks/{grTextareaStyles-CWI2SqC8.js.map → grTextareaStyles-iOcHuVMM.js.map} +1 -1
  39. package/dist/chunks/{granular-provider-CtrXGa7c.js → granular-provider-B9nXQCMu.js} +18 -16
  40. package/dist/chunks/granular-provider-B9nXQCMu.js.map +1 -0
  41. package/dist/chunks/{keyboard-zYvvyHd4.js → keyboard-DE2yhz_b.js} +10 -1
  42. package/dist/chunks/keyboard-DE2yhz_b.js.map +1 -0
  43. package/dist/chunks/{optionFilter-BVY988pC.js → optionFilter-DYw9XPPx.js} +1 -71
  44. package/dist/chunks/optionFilter-DYw9XPPx.js.map +1 -0
  45. package/dist/chunks/{useOverlayLayer-BupuP_hs.js → overlayStack-C8cfsqXa.js} +11 -61
  46. package/dist/chunks/overlayStack-C8cfsqXa.js.map +1 -0
  47. package/dist/chunks/{ru-COWxgh2A.js → ru-9z8ix45c.js} +30 -5
  48. package/dist/chunks/ru-9z8ix45c.js.map +1 -0
  49. package/dist/chunks/useDragSort-0l47h4yb.js +265 -0
  50. package/dist/chunks/useDragSort-0l47h4yb.js.map +1 -0
  51. package/dist/chunks/{useModalOverlay-DCM4d3yA.js → useModalOverlay-BTq-0ImG.js} +1 -1
  52. package/dist/chunks/{useModalOverlay-DCM4d3yA.js.map → useModalOverlay-BTq-0ImG.js.map} +1 -1
  53. package/dist/components/GrAutocomplete/chunks/{GrAutocomplete-CQ9T7Lly.js → GrAutocomplete-CPEQxmLZ.js} +4 -3
  54. package/dist/components/GrAutocomplete/chunks/GrAutocomplete-CPEQxmLZ.js.map +1 -0
  55. package/dist/components/GrAutocomplete/index.js +1 -1
  56. package/dist/components/GrAutocomplete/styles.css +1 -1
  57. package/dist/components/GrColorPicker/chunks/{GrColorPicker-bnYBRGk8.js → GrColorPicker-DAdQ-Gc3.js} +4 -4
  58. package/dist/components/GrColorPicker/chunks/{GrColorPicker-bnYBRGk8.js.map → GrColorPicker-DAdQ-Gc3.js.map} +1 -1
  59. package/dist/components/GrColorPicker/index.js +2 -2
  60. package/dist/components/GrCommandPalette/chunks/{GrCommandPalette-MWDYDPNC.js → GrCommandPalette-DMeSqkEv.js} +6 -7
  61. package/dist/components/GrCommandPalette/chunks/GrCommandPalette-DMeSqkEv.js.map +1 -0
  62. package/dist/components/GrCommandPalette/index.js +1 -1
  63. package/dist/components/GrCommandPalette/styles.css +1 -1
  64. package/dist/components/GrConfigProvider/index.js +2 -2
  65. package/dist/components/GrConfirmDialog/chunks/{GrConfirmDialog-DaQmlp1_.js → GrConfirmDialog-hUTi-GdJ.js} +1 -1
  66. package/dist/components/GrConfirmDialog/chunks/{GrConfirmDialog-DaQmlp1_.js.map → GrConfirmDialog-hUTi-GdJ.js.map} +1 -1
  67. package/dist/components/GrConfirmDialog/index.js +1 -1
  68. package/dist/components/GrDataTable/chunks/{GrDataTable-DVFho9Cj.js → GrDataTable-DzaGLG3A.js} +495 -47
  69. package/dist/components/GrDataTable/chunks/GrDataTable-DzaGLG3A.js.map +1 -0
  70. package/dist/components/GrDataTable/index.js +2 -2
  71. package/dist/components/GrDialog/chunks/{GrDialog-AE1gIZuz.js → GrDialog-MD9Fzy9C.js} +1 -1
  72. package/dist/components/GrDialog/chunks/{GrDialog-AE1gIZuz.js.map → GrDialog-MD9Fzy9C.js.map} +1 -1
  73. package/dist/components/GrDialog/index.js +1 -1
  74. package/dist/components/GrDialogService/chunks/{GrDialogService-B4DYWDkA.js → GrDialogService-DtgUijMj.js} +2 -2
  75. package/dist/components/GrDialogService/chunks/{GrDialogService-B4DYWDkA.js.map → GrDialogService-DtgUijMj.js.map} +1 -1
  76. package/dist/components/GrDialogService/index.js +1 -1
  77. package/dist/components/GrDrawer/chunks/{GrDrawer-DQwi6aRw.js → GrDrawer-DWHdZZzW.js} +2 -2
  78. package/dist/components/GrDrawer/chunks/{GrDrawer-DQwi6aRw.js.map → GrDrawer-DWHdZZzW.js.map} +1 -1
  79. package/dist/components/GrDrawer/index.js +2 -2
  80. package/dist/components/GrDropdown/chunks/{GrDropdown-BLng6V1m.js → GrDropdown-0tJK01Kq.js} +2 -2
  81. package/dist/components/GrDropdown/chunks/{GrDropdown-BLng6V1m.js.map → GrDropdown-0tJK01Kq.js.map} +1 -1
  82. package/dist/components/GrDropdown/index.js +1 -1
  83. package/dist/components/GrDropdownMenu/chunks/{GrDropdownMenu-BImk2Vs7.js → GrDropdownMenu-VPPrpCoA.js} +1 -1
  84. package/dist/components/GrDropdownMenu/chunks/{GrDropdownMenu-BImk2Vs7.js.map → GrDropdownMenu-VPPrpCoA.js.map} +1 -1
  85. package/dist/components/GrDropdownMenu/index.js +1 -1
  86. package/dist/components/GrFileUpload/chunks/{GrFileUpload-D0B-BEsd.js → GrFileUpload-DuDzC43S.js} +2 -2
  87. package/dist/components/GrFileUpload/chunks/{GrFileUpload-D0B-BEsd.js.map → GrFileUpload-DuDzC43S.js.map} +1 -1
  88. package/dist/components/GrFileUpload/index.js +1 -1
  89. package/dist/components/GrImageViewer/chunks/{GrImageViewer-BeCnE8XQ.js → GrImageViewer-DE7MBbF8.js} +46 -22
  90. package/dist/components/GrImageViewer/chunks/GrImageViewer-DE7MBbF8.js.map +1 -0
  91. package/dist/components/GrImageViewer/index.js +1 -1
  92. package/dist/components/GrInput/chunks/{GrInput-DD2gYdqS.js → GrInput-2wd7Crs0.js} +1 -1
  93. package/dist/components/GrInput/chunks/GrInput-2wd7Crs0.js.map +1 -0
  94. package/dist/components/GrInput/index.js +1 -1
  95. package/dist/components/GrInputTag/chunks/{GrInputTag-DmNunixz.js → GrInputTag-CyV2eY7Z.js} +20 -33
  96. package/dist/components/GrInputTag/chunks/GrInputTag-CyV2eY7Z.js.map +1 -0
  97. package/dist/components/GrInputTag/index.js +1 -1
  98. package/dist/components/GrKbd/chunks/{GrKbd-DRFPvW3G.js → GrKbd-DU2lBkRV.js} +218 -52
  99. package/dist/components/GrKbd/chunks/GrKbd-DU2lBkRV.js.map +1 -0
  100. package/dist/components/GrKbd/index.js +3 -3
  101. package/dist/components/GrModal/chunks/{GrModal-B8I78T0N.js → GrModal-BbhcsDQ8.js} +1 -1
  102. package/dist/components/GrModal/chunks/{GrModal-B8I78T0N.js.map → GrModal-BbhcsDQ8.js.map} +1 -1
  103. package/dist/components/GrModal/index.js +1 -1
  104. package/dist/components/GrPagination/chunks/{GrPagination-B6N0QZBf.js → GrPagination-waKhxBP7.js} +4 -4
  105. package/dist/components/GrPagination/chunks/GrPagination-waKhxBP7.js.map +1 -0
  106. package/dist/components/GrPagination/index.js +1 -1
  107. package/dist/components/GrPopover/chunks/{GrPopover-B1eRCOoO.js → GrPopover-DuqeoFaI.js} +1 -1
  108. package/dist/components/GrPopover/chunks/{GrPopover-B1eRCOoO.js.map → GrPopover-DuqeoFaI.js.map} +1 -1
  109. package/dist/components/GrPopover/index.js +1 -1
  110. package/dist/components/GrProgressBar/chunks/{GrProgressBar-BiHnaitu.js → GrProgressBar-xwbNM9QB.js} +1 -1
  111. package/dist/components/GrProgressBar/chunks/GrProgressBar-xwbNM9QB.js.map +1 -0
  112. package/dist/components/GrProgressBar/index.js +1 -1
  113. package/dist/components/GrProgressCircle/chunks/{GrProgressCircle-CTogjcHz.js → GrProgressCircle-B8olXRo5.js} +1 -1
  114. package/dist/components/GrProgressCircle/chunks/{GrProgressCircle-CTogjcHz.js.map → GrProgressCircle-B8olXRo5.js.map} +1 -1
  115. package/dist/components/GrProgressCircle/index.js +2 -2
  116. package/dist/components/GrPromptDialog/chunks/{GrPromptDialog-Ct174NVD.js → GrPromptDialog-JVVqBsPY.js} +3 -3
  117. package/dist/components/GrPromptDialog/chunks/{GrPromptDialog-Ct174NVD.js.map → GrPromptDialog-JVVqBsPY.js.map} +1 -1
  118. package/dist/components/GrPromptDialog/index.js +1 -1
  119. package/dist/components/GrRadio/chunks/{GrRadio-DksDro_U.js → GrRadio-DWiRaMzt.js} +8 -32
  120. package/dist/components/GrRadio/chunks/GrRadio-DWiRaMzt.js.map +1 -0
  121. package/dist/components/GrRadio/index.js +1 -1
  122. package/dist/components/GrRadioGroup/chunks/{GrRadioGroup-BOIhejE6.js → GrRadioGroup-DIuBw0wk.js} +34 -27
  123. package/dist/components/GrRadioGroup/chunks/GrRadioGroup-DIuBw0wk.js.map +1 -0
  124. package/dist/components/GrRadioGroup/index.js +1 -1
  125. package/dist/components/GrRating/chunks/{GrRating-JrHXz0Rv.js → GrRating-LarIiwJL.js} +2 -2
  126. package/dist/components/GrRating/chunks/GrRating-LarIiwJL.js.map +1 -0
  127. package/dist/components/GrRating/index.js +2 -2
  128. package/dist/components/GrSegmented/chunks/{GrSegmented-BQIlH5KI.js → GrSegmented-CQw3ijqa.js} +47 -65
  129. package/dist/components/GrSegmented/chunks/GrSegmented-CQw3ijqa.js.map +1 -0
  130. package/dist/components/GrSegmented/index.js +1 -1
  131. package/dist/components/GrSelect/chunks/{GrSelect-aqkPCqjd.js → GrSelect-DAdu044K.js} +4 -3
  132. package/dist/components/GrSelect/chunks/GrSelect-DAdu044K.js.map +1 -0
  133. package/dist/components/GrSelect/index.js +1 -1
  134. package/dist/components/GrSlider/chunks/{GrSlider-DkU9IQSX.js → GrSlider-CyhVsNKn.js} +21 -34
  135. package/dist/components/GrSlider/chunks/GrSlider-CyhVsNKn.js.map +1 -0
  136. package/dist/components/GrSlider/index.js +2 -2
  137. package/dist/components/GrSortableList/chunks/GrSortableList-BefVfWKh.js +276 -0
  138. package/dist/components/GrSortableList/chunks/GrSortableList-BefVfWKh.js.map +1 -0
  139. package/dist/components/GrSortableList/index.js +3 -0
  140. package/dist/components/GrSplitter/chunks/{GrSplitter-7To8jbJ8.js → GrSplitter-BzxVQwbY.js} +17 -37
  141. package/dist/components/GrSplitter/chunks/GrSplitter-BzxVQwbY.js.map +1 -0
  142. package/dist/components/GrSplitter/index.js +2 -2
  143. package/dist/components/GrStatistic/chunks/{GrStatistic-CttyoYPT.js → GrStatistic-J4qLs3TH.js} +1 -1
  144. package/dist/components/GrStatistic/chunks/{GrStatistic-CttyoYPT.js.map → GrStatistic-J4qLs3TH.js.map} +1 -1
  145. package/dist/components/GrStatistic/index.js +2 -2
  146. package/dist/components/GrSwitch/chunks/{GrSwitch-B9TYbiih.js → GrSwitch-DpyvVrZG.js} +1 -1
  147. package/dist/components/GrSwitch/chunks/{GrSwitch-B9TYbiih.js.map → GrSwitch-DpyvVrZG.js.map} +1 -1
  148. package/dist/components/GrSwitch/index.js +2 -2
  149. package/dist/components/GrTabPanels/index.js +1 -1
  150. package/dist/components/GrTable/chunks/{GrTable-BB-mI_NM.js → GrTable-BfqgwETQ.js} +7 -1
  151. package/dist/components/GrTable/chunks/GrTable-BfqgwETQ.js.map +1 -0
  152. package/dist/components/GrTable/index.js +1 -1
  153. package/dist/components/GrTabs/chunks/{GrTabs-B8CDq2D9.js → GrTabs-TeXaU5Uh.js} +50 -61
  154. package/dist/components/GrTabs/chunks/GrTabs-TeXaU5Uh.js.map +1 -0
  155. package/dist/components/GrTabs/index.js +1 -1
  156. package/dist/components/GrTextarea/chunks/{GrTextarea-DUh5Tlo4.js → GrTextarea-DSvd1nSy.js} +1 -1
  157. package/dist/components/GrTextarea/chunks/{GrTextarea-DUh5Tlo4.js.map → GrTextarea-DSvd1nSy.js.map} +1 -1
  158. package/dist/components/GrTextarea/index.js +2 -2
  159. package/dist/components/GrTimeline/chunks/{GrTimeline-CE9b3s18.js → GrTimeline-B-h2Yanw.js} +1 -1
  160. package/dist/components/GrTimeline/chunks/{GrTimeline-CE9b3s18.js.map → GrTimeline-B-h2Yanw.js.map} +1 -1
  161. package/dist/components/GrTimeline/index.js +2 -2
  162. package/dist/components/GrToaster/chunks/{GrToaster-BKQy3Srm.js → GrToaster-Ct-39hga.js} +113 -12
  163. package/dist/components/GrToaster/chunks/GrToaster-Ct-39hga.js.map +1 -0
  164. package/dist/components/GrToaster/index.js +2 -2
  165. package/dist/components/GrToaster/styles.css +1 -1
  166. package/dist/components/GrTooltip/chunks/{GrTooltip-DEbejfhA.js → GrTooltip-xAcqs0bP.js} +1 -1
  167. package/dist/components/GrTooltip/chunks/{GrTooltip-DEbejfhA.js.map → GrTooltip-xAcqs0bP.js.map} +1 -1
  168. package/dist/components/GrTooltip/index.js +2 -2
  169. package/dist/components/GrTree/chunks/{GrTree-wfdbvygw.js → GrTree-CaYK8dGZ.js} +124 -92
  170. package/dist/components/GrTree/chunks/GrTree-CaYK8dGZ.js.map +1 -0
  171. package/dist/components/GrTree/index.js +1 -1
  172. package/dist/components/GrTree/styles.css +1 -1
  173. package/dist/components/GrTreeSelect/chunks/{GrTreeSelect-lLWmAMtI.js → GrTreeSelect-DZp7CqqW.js} +4 -4
  174. package/dist/components/GrTreeSelect/chunks/{GrTreeSelect-lLWmAMtI.js.map → GrTreeSelect-DZp7CqqW.js.map} +1 -1
  175. package/dist/components/GrTreeSelect/index.js +2 -2
  176. package/dist/composables/useComboboxNavigation.js +71 -0
  177. package/dist/composables/useComboboxNavigation.js.map +1 -0
  178. package/dist/composables/useDismissible.js +1 -1
  179. package/dist/composables/useDragGesture.js +55 -0
  180. package/dist/composables/useDragGesture.js.map +1 -0
  181. package/dist/composables/useDragSort.js +2 -0
  182. package/dist/composables/useFloating.js +22 -1
  183. package/dist/composables/useFloating.js.map +1 -1
  184. package/dist/composables/useGrComponentConfig.js +2 -0
  185. package/dist/composables/useGranularityTranslations.js +2 -0
  186. package/dist/composables/useOverlayLayer.js +64 -1
  187. package/dist/composables/useOverlayLayer.js.map +1 -0
  188. package/dist/composables/useRovingFocus.js +150 -0
  189. package/dist/composables/useRovingFocus.js.map +1 -0
  190. package/dist/directives/hotkey.js +13 -7
  191. package/dist/directives/hotkey.js.map +1 -1
  192. package/dist/granular-provider-node.js +1 -1
  193. package/dist/granular-provider.js +1 -1
  194. package/dist/i18n/all.js +1 -1
  195. package/dist/i18n/index.js +1 -1
  196. package/dist/index.js +67 -58
  197. package/dist/tokens.js +84 -0
  198. package/dist/tokens.js.map +1 -1
  199. package/dist/types/src/components/GrAlert/defaults.d.ts +1 -1
  200. package/dist/types/src/components/GrAutocomplete/defaults.d.ts +1 -1
  201. package/dist/types/src/components/GrAvatar/defaults.d.ts +1 -1
  202. package/dist/types/src/components/GrBadge/defaults.d.ts +1 -1
  203. package/dist/types/src/components/GrBottomNav/defaults.d.ts +1 -1
  204. package/dist/types/src/components/GrBreadcrumbs/defaults.d.ts +1 -1
  205. package/dist/types/src/components/GrButton/defaults.d.ts +1 -1
  206. package/dist/types/src/components/GrCard/defaults.d.ts +1 -1
  207. package/dist/types/src/components/GrCheckbox/defaults.d.ts +1 -1
  208. package/dist/types/src/components/GrCheckboxGroup/defaults.d.ts +1 -1
  209. package/dist/types/src/components/GrCollapse/defaults.d.ts +1 -1
  210. package/dist/types/src/components/GrColorPicker/defaults.d.ts +1 -1
  211. package/dist/types/src/components/GrColorPicker/grColorPickerStyles.d.ts +2 -2
  212. package/dist/types/src/components/GrCommandPalette/defaults.d.ts +1 -1
  213. package/dist/types/src/components/GrConfigProvider/context.d.ts +6 -22
  214. package/dist/types/src/components/GrConfigProvider/index.d.ts +1 -1
  215. package/dist/types/src/components/GrConfirmDialog/defaults.d.ts +1 -1
  216. package/dist/types/src/components/GrDataTable/GrDataTable.vue.d.ts +53 -0
  217. package/dist/types/src/components/GrDataTable/defaults.d.ts +1 -1
  218. package/dist/types/src/components/GrDataTable/grDataTableStyles.d.ts +39 -0
  219. package/dist/types/src/components/GrDialog/defaults.d.ts +1 -1
  220. package/dist/types/src/components/GrDivider/defaults.d.ts +1 -1
  221. package/dist/types/src/components/GrDrawer/defaults.d.ts +1 -1
  222. package/dist/types/src/components/GrEmptyState/defaults.d.ts +1 -1
  223. package/dist/types/src/components/GrFileUpload/defaults.d.ts +1 -1
  224. package/dist/types/src/components/GrFormField/defaults.d.ts +1 -1
  225. package/dist/types/src/components/GrFormFile/defaults.d.ts +1 -1
  226. package/dist/types/src/components/GrFormSection/defaults.d.ts +1 -1
  227. package/dist/types/src/components/GrIcon/defaults.d.ts +1 -1
  228. package/dist/types/src/components/GrImageViewer/composables/usePointerGestures.d.ts +1 -0
  229. package/dist/types/src/components/GrImageViewer/composables/useZoomPan.d.ts +1 -2
  230. package/dist/types/src/components/GrInput/defaults.d.ts +1 -1
  231. package/dist/types/src/components/GrInputTag/defaults.d.ts +1 -1
  232. package/dist/types/src/components/GrKbd/GrKbd.vue.d.ts +18 -3
  233. package/dist/types/src/components/GrKbd/defaults.d.ts +1 -1
  234. package/dist/types/src/components/GrKbd/grKbdStyles.d.ts +20 -3
  235. package/dist/types/src/components/GrKbd/index.d.ts +6 -0
  236. package/dist/types/src/components/GrLink/defaults.d.ts +1 -1
  237. package/dist/types/src/components/GrModal/defaults.d.ts +1 -1
  238. package/dist/types/src/components/GrNumberInput/defaults.d.ts +1 -1
  239. package/dist/types/src/components/GrPagination/defaults.d.ts +1 -1
  240. package/dist/types/src/components/GrPopover/GrPopover.vue.d.ts +1 -1
  241. package/dist/types/src/components/GrPopover/defaults.d.ts +1 -1
  242. package/dist/types/src/components/GrProgressBar/defaults.d.ts +1 -1
  243. package/dist/types/src/components/GrProgressCircle/defaults.d.ts +1 -1
  244. package/dist/types/src/components/GrProgressCircle/grProgressCircleStyles.d.ts +1 -1
  245. package/dist/types/src/components/GrPromptDialog/defaults.d.ts +1 -1
  246. package/dist/types/src/components/GrRadio/defaults.d.ts +1 -1
  247. package/dist/types/src/components/GrRadio/grRadioGroupContext.d.ts +12 -4
  248. package/dist/types/src/components/GrRadioGroup/defaults.d.ts +1 -1
  249. package/dist/types/src/components/GrRating/defaults.d.ts +1 -1
  250. package/dist/types/src/components/GrSegmented/defaults.d.ts +1 -1
  251. package/dist/types/src/components/GrSelect/defaults.d.ts +1 -1
  252. package/dist/types/src/components/GrSlider/defaults.d.ts +1 -1
  253. package/dist/types/src/components/GrSortableList/GrSortableList.vue.d.ts +68 -0
  254. package/dist/types/src/components/GrSortableList/config.d.ts +1 -0
  255. package/dist/types/src/components/GrSortableList/grSortableListStyles.d.ts +38 -0
  256. package/dist/types/src/components/GrSortableList/index.d.ts +9 -0
  257. package/dist/types/src/components/GrSortableList/safelist.d.ts +1 -0
  258. package/dist/types/src/components/GrSplitter/defaults.d.ts +1 -1
  259. package/dist/types/src/components/GrStatistic/defaults.d.ts +1 -1
  260. package/dist/types/src/components/GrStatistic/grStatisticStyles.d.ts +1 -1
  261. package/dist/types/src/components/GrSwitch/defaults.d.ts +1 -1
  262. package/dist/types/src/components/GrTable/GrTable.vue.d.ts +13 -0
  263. package/dist/types/src/components/GrTable/defaults.d.ts +1 -1
  264. package/dist/types/src/components/GrTabs/defaults.d.ts +1 -1
  265. package/dist/types/src/components/GrTextarea/defaults.d.ts +1 -1
  266. package/dist/types/src/components/GrTextarea/grTextareaStyles.d.ts +2 -2
  267. package/dist/types/src/components/GrTimeline/defaults.d.ts +1 -1
  268. package/dist/types/src/components/GrTimeline/grTimelineStyles.d.ts +1 -1
  269. package/dist/types/src/components/GrToaster/GrToaster.vue.d.ts +8 -0
  270. package/dist/types/src/components/GrToaster/grToasterStyles.d.ts +27 -0
  271. package/dist/types/src/components/GrTooltip/defaults.d.ts +1 -1
  272. package/dist/types/src/components/GrTree/defaults.d.ts +1 -1
  273. package/dist/types/src/components/GrTree/grTreeInteractionContext.d.ts +0 -1
  274. package/dist/types/src/components/GrTreeSelect/defaults.d.ts +1 -1
  275. package/dist/types/src/components/shared/hotkey.d.ts +7 -15
  276. package/dist/types/src/components/shared/hotkeyTokens.d.ts +37 -0
  277. package/dist/types/src/composables/internal/dragSortGeometry.d.ts +59 -0
  278. package/dist/types/src/composables/internal/overlayStack.d.ts +11 -0
  279. package/dist/types/src/composables/useDragGesture.d.ts +63 -0
  280. package/dist/types/src/composables/useDragSort.d.ts +80 -0
  281. package/dist/types/src/composables/useFloating.d.ts +5 -1
  282. package/dist/types/src/composables/useGrComponentConfig.d.ts +41 -0
  283. package/dist/types/src/composables/useGranularityTranslations.d.ts +13 -0
  284. package/dist/types/src/composables/useRovingFocus.d.ts +108 -0
  285. package/dist/types/src/granular-provider/shared.d.ts +1 -0
  286. package/dist/types/src/i18n/messages/en.d.ts +48 -0
  287. package/dist/types/src/i18n/messages/es.d.ts +48 -0
  288. package/dist/types/src/i18n/messages/ru.d.ts +48 -0
  289. package/dist/types/src/index.d.ts +12 -0
  290. package/dist/types/src/internal/keyboard.d.ts +6 -0
  291. package/dist/web-types.json +201 -3
  292. package/package.json +31 -3
  293. package/dist/chunks/config-B-g6lT19.js.map +0 -1
  294. package/dist/chunks/config-BE6n20np.js.map +0 -1
  295. package/dist/chunks/config-BNfQwyL4.js +0 -97
  296. package/dist/chunks/config-BNfQwyL4.js.map +0 -1
  297. package/dist/chunks/config-BoNR7_PD.js.map +0 -1
  298. package/dist/chunks/config-CN2ULSQL2.js.map +0 -1
  299. package/dist/chunks/config-Cw6TDzWv2.js.map +0 -1
  300. package/dist/chunks/config-D94Z9po52.js.map +0 -1
  301. package/dist/chunks/config-DCFvmHEv.js.map +0 -1
  302. package/dist/chunks/config-DxCTVBfx.js.map +0 -1
  303. package/dist/chunks/config-LGrZIdaZ.js +0 -21
  304. package/dist/chunks/config-LGrZIdaZ.js.map +0 -1
  305. package/dist/chunks/config-T3qdQBgU.js.map +0 -1
  306. package/dist/chunks/config-eXB87DOi2.js.map +0 -1
  307. package/dist/chunks/en-B3xMeswz.js.map +0 -1
  308. package/dist/chunks/es-CA-mkU--.js.map +0 -1
  309. package/dist/chunks/grKbdStyles-DAoxiytu.js +0 -31
  310. package/dist/chunks/grKbdStyles-DAoxiytu.js.map +0 -1
  311. package/dist/chunks/granular-provider-CtrXGa7c.js.map +0 -1
  312. package/dist/chunks/keyboard-zYvvyHd4.js.map +0 -1
  313. package/dist/chunks/optionFilter-BVY988pC.js.map +0 -1
  314. package/dist/chunks/ru-COWxgh2A.js.map +0 -1
  315. package/dist/chunks/useOverlayLayer-BupuP_hs.js.map +0 -1
  316. package/dist/components/GrAutocomplete/chunks/GrAutocomplete-CQ9T7Lly.js.map +0 -1
  317. package/dist/components/GrCommandPalette/chunks/GrCommandPalette-MWDYDPNC.js.map +0 -1
  318. package/dist/components/GrDataTable/chunks/GrDataTable-DVFho9Cj.js.map +0 -1
  319. package/dist/components/GrImageViewer/chunks/GrImageViewer-BeCnE8XQ.js.map +0 -1
  320. package/dist/components/GrInput/chunks/GrInput-DD2gYdqS.js.map +0 -1
  321. package/dist/components/GrInputTag/chunks/GrInputTag-DmNunixz.js.map +0 -1
  322. package/dist/components/GrKbd/chunks/GrKbd-DRFPvW3G.js.map +0 -1
  323. package/dist/components/GrPagination/chunks/GrPagination-B6N0QZBf.js.map +0 -1
  324. package/dist/components/GrProgressBar/chunks/GrProgressBar-BiHnaitu.js.map +0 -1
  325. package/dist/components/GrRadio/chunks/GrRadio-DksDro_U.js.map +0 -1
  326. package/dist/components/GrRadioGroup/chunks/GrRadioGroup-BOIhejE6.js.map +0 -1
  327. package/dist/components/GrRating/chunks/GrRating-JrHXz0Rv.js.map +0 -1
  328. package/dist/components/GrSegmented/chunks/GrSegmented-BQIlH5KI.js.map +0 -1
  329. package/dist/components/GrSelect/chunks/GrSelect-aqkPCqjd.js.map +0 -1
  330. package/dist/components/GrSlider/chunks/GrSlider-DkU9IQSX.js.map +0 -1
  331. package/dist/components/GrSplitter/chunks/GrSplitter-7To8jbJ8.js.map +0 -1
  332. package/dist/components/GrTable/chunks/GrTable-BB-mI_NM.js.map +0 -1
  333. package/dist/components/GrTabs/chunks/GrTabs-B8CDq2D9.js.map +0 -1
  334. package/dist/components/GrToaster/chunks/GrToaster-BKQy3Srm.js.map +0 -1
  335. package/dist/components/GrTree/chunks/GrTree-wfdbvygw.js.map +0 -1
  336. /package/dist/chunks/{config-BE6n20np.js → config-BE6n20np2.js} +0 -0
  337. /package/dist/chunks/{config-BoNR7_PD.js → config-BoNR7_PD2.js} +0 -0
  338. /package/dist/chunks/{config-CN2ULSQL2.js → config-CN2ULSQL.js} +0 -0
  339. /package/dist/chunks/{config-D94Z9po52.js → config-D94Z9po5.js} +0 -0
  340. /package/dist/chunks/{config-DCFvmHEv.js → config-DCFvmHEv2.js} +0 -0
  341. /package/dist/chunks/{config-T3qdQBgU.js → config-T3qdQBgU2.js} +0 -0
  342. /package/dist/chunks/{config-eXB87DOi2.js → config-eXB87DOi.js} +0 -0
  343. /package/dist/types/src/composables/{internal/useComboboxNavigation.d.ts → useComboboxNavigation.d.ts} +0 -0
@@ -1,3 +1,3 @@
1
- import { n as grToasterSafelist, t as grToasterConfig } from "../../chunks/config-LGrZIdaZ.js";
2
- import { t as GrToaster_default } from "./chunks/GrToaster-BKQy3Srm.js";
1
+ import { n as grToasterSafelist, t as grToasterConfig } from "../../chunks/config-ScuvHw6k2.js";
2
+ import { t as GrToaster_default } from "./chunks/GrToaster-Ct-39hga.js";
3
3
  export { GrToaster_default as GrToaster, GrToaster_default as default, grToasterConfig, grToasterSafelist };
@@ -1 +1 @@
1
- .gr-toast-progress[data-v-0cce147a]{animation-name:gr-toast-progress-0cce147a;animation-timing-function:linear;animation-fill-mode:forwards}@keyframes gr-toast-progress-0cce147a{0%{transform:scaleX(1)}to{transform:scaleX(0)}}@media (prefers-reduced-motion:reduce){.gr-toast-progress[data-v-0cce147a]{display:none}}
1
+ .gr-toast-progress[data-v-3ad9ca7d]{animation-name:gr-toast-progress-3ad9ca7d;animation-timing-function:linear;animation-fill-mode:forwards}@keyframes gr-toast-progress-3ad9ca7d{0%{transform:scaleX(1)}to{transform:scaleX(0)}}@media (prefers-reduced-motion:reduce){.gr-toast-progress[data-v-3ad9ca7d]{display:none}}
@@ -5,7 +5,7 @@ import { vClickOutside } from "../../../directives/clickOutside.js";
5
5
  import { t as GrIcon_default } from "../../GrIcon/chunks/GrIcon-BvA2ZGXP.js";
6
6
  import { useFloating } from "../../../composables/useFloating.js";
7
7
  import { useDismissible } from "../../../composables/useDismissible.js";
8
- import { a as triggerIconSizes, i as panelWidths, r as panelSizes } from "../../../chunks/config-CN2ULSQL2.js";
8
+ import { a as triggerIconSizes, i as panelWidths, r as panelSizes } from "../../../chunks/config-CN2ULSQL.js";
9
9
  import { Teleport, Transition, computed, createBlock, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, mergeProps, normalizeStyle, onMounted, onUnmounted, onUpdated, openBlock, ref, renderSlot, toDisplayString, unref, useId, useSlots, vShow, watchEffect, withCtx, withDirectives } from "vue";
10
10
  //#region src/components/GrTooltip/GrTooltip.vue?vue&type=script&setup=true&lang.ts
11
11
  var _hoisted_1 = {
@@ -1 +1 @@
1
- {"version":3,"file":"GrTooltip-DEbejfhA.js","names":[],"sources":["../../../../src/components/GrTooltip/GrTooltip.vue","../../../../src/components/GrTooltip/GrTooltip.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * GrTooltip — GR-примитив инлайн-подсказки на hover/focus.\n *\n * По умолчанию триггер — иконка info; можно заменить через слот.\n * A11y:\n * - `role=\"tooltip\"` связывается с триггером через уникальный `aria-describedby`;\n * - подсказка закрывается по `Escape` (WCAG 1.4.13 «Content on Hover or Focus» —\n * dismissible без необходимости двигать курсор/фокус);\n * - панель не интерактивна (`pointer-events-none`), поэтому «hoverable»-требование\n * того же критерия неприменимо — навести курсор на саму подсказку невозможно.\n *\n * Позиционирование — через общий `useFloating` (см. `composables/internal`):\n * `placement` задаёт предпочтительную сторону, `flip` переворачивает подсказку,\n * если места не хватает, а `shift` не даёт ей вылезти за края viewport.\n */\nimport { computed, onMounted, onUnmounted, onUpdated, ref, useId, useSlots, watchEffect } from 'vue'\n\nimport { usePortalTarget } from '../../composables/usePortalTarget'\n\nimport { vClickOutside } from '../../directives'\nimport GrIcon from '../GrIcon'\nimport { useFloating, type UseFloatingPlacement } from '../../composables/useFloating'\nimport { useDismissible } from '../../composables/useDismissible'\nimport { useGrComponentSize, useGrThemeAttrs } from '../GrConfigProvider/context'\nimport { type GrTooltipSize, panelSizes, panelWidths, triggerIconSizes } from './grTooltipStyles'\n\nimport IconInfo from '~icons/lucide/info'\n\nexport type GrTooltipPlacement = UseFloatingPlacement\n\nexport interface GrTooltipProps {\n /** Текст подсказки. Разметка вместо текста — слот `#content`. */\n text?: string\n /** Цвет триггер-иконки (CSS color). По умолчанию — `var(--gr-muted-fg)`. */\n iconColor?: string\n /** Размер панели и дефолтной триггер-иконки. */\n size?: GrTooltipSize\n /** Предпочтительная сторона панели; `flip` может её изменить. */\n placement?: GrTooltipPlacement\n /** Зазор между триггером и панелью, px. */\n offsetPx?: number\n /** Задержка перед показом, мс. Спасает от мигания при проведении курсором по панели кнопок. */\n openDelay?: number\n /** Задержка перед скрытием, мс. */\n closeDelay?: number\n /** Подсказка не показывается ничем — ни курсором, ни фокусом, ни `v-model:open`. */\n disabled?: boolean\n /** Управляемая видимость. Без неё компонент ведёт видимость сам. */\n open?: boolean\n}\n\nexport interface GrTooltipEmits {\n (e: 'update:open', value: boolean): void\n}\n\nconst props = withDefaults(defineProps<GrTooltipProps>(), {\n text: undefined,\n iconColor: 'var(--gr-muted-fg)',\n size: undefined,\n placement: 'top',\n offsetPx: undefined,\n openDelay: 0,\n closeDelay: 0,\n disabled: false,\n open: undefined,\n})\n\nconst emit = defineEmits<GrTooltipEmits>()\n\ndefineSlots<{\n /** Триггер. По умолчанию — иконка info. */\n default?: () => unknown\n /** Содержимое подсказки; заменяет проп `text`. */\n content?: () => unknown\n}>()\n\nconst slots = useSlots()\n\nconst resolvedSize = useGrComponentSize(() => props.size, { component: 'GrTooltip' })\n\nconst panelClass = computed(() => [\n panelSizes[resolvedSize.value],\n panelWidths[resolvedSize.value],\n].join(' '))\nconst triggerIconSize = computed(() => triggerIconSizes[resolvedSize.value])\n\nconst tooltipId = `gr-tooltip-${useId()}`\n\nconst triggerStyle = computed(() => ({ color: props.iconColor }))\n\n// Телепорт включается только ПОСЛЕ монтирования: иначе первый клиентский\n// рендер не совпадает с серверным и ломается гидрация (см. композабл).\nconst { target: portalTarget, enabled: teleportEnabled } = usePortalTarget()\n\n// Тема поддерева на телепортированную панель: в DOM она уезжает в `body`, то\n// есть вне обёртки провайдера, и `data-theme` с неё не наследуется. В дереве\n// компонентов панель остаётся внутри — `inject` доходит, и тему она ставит себе\n// сама.\nconst themeAttrs = useGrThemeAttrs()\n\nconst uncontrolledOpen = ref(false)\nconst triggerEl = ref<HTMLElement | null>(null)\nconst panelEl = ref<HTMLElement | null>(null)\n\n/** Показывать нечего — пустая панель хуже отсутствующей. */\nconst hasContent = computed(() => Boolean(slots.content) || Boolean(props.text))\n\nconst open = computed<boolean>({\n get: () => {\n if (props.disabled || !hasContent.value) return false\n return props.open ?? uncontrolledOpen.value\n },\n set: (next) => {\n uncontrolledOpen.value = next\n emit('update:open', next)\n },\n})\n\nconst { floatingStyle } = useFloating(triggerEl, panelEl, open, {\n placement: () => props.placement,\n // Геттер, а не значение: `useFloating` читает опцию на каждом пересчёте, и\n // так проп остаётся живым, а не замирает на моменте setup.\n get offsetPx() { return props.offsetPx },\n zIndexVar: '--gr-z-tooltip',\n})\n\nlet delayTimer: ReturnType<typeof setTimeout> | undefined\n\nfunction schedule(next: boolean, delayMs: number): void {\n clearTimeout(delayTimer)\n\n if (delayMs <= 0) {\n open.value = next\n return\n }\n\n delayTimer = setTimeout(() => { open.value = next }, delayMs)\n}\n\nfunction show(): void {\n if (props.disabled) return\n schedule(true, props.openDelay)\n}\n\nfunction hide(): void {\n schedule(false, props.closeDelay)\n}\n\n/** Escape и клик вне закрывают мгновенно: задержка тут читалась бы как залипание. */\nfunction dismiss(): void {\n clearTimeout(delayTimer)\n if (open.value) open.value = false\n}\n\n// Нужен только тач-режиму: курсор и фокус закрывают подсказку сами.\nconst dismissOnOutside = computed(() => ({ handler: dismiss, enabled: open.value }))\n\n/**\n * На тач-устройствах hover не существует, а фокус по тапу не гарантирован —\n * без этого подсказка там недоступна вовсе. Тап по триггеру переключает\n * панель, тап вне — закрывает (`vClickOutside`).\n */\nfunction onTouch(): void {\n if (open.value) dismiss()\n else show()\n}\n\nonUnmounted(() => clearTimeout(delayTimer))\n\nuseDismissible(open, dismiss)\n\nconst FOCUSABLE_SELECTOR = 'a[href],button,input,select,textarea,[tabindex]:not([tabindex=\"-1\"])'\n\n/**\n * Типовое употребление — подсказка у кнопки. Фокусируемая обёртка вокруг\n * фокусируемого контрола дала бы два таб-стопа на один визуальный элемент,\n * поэтому обёртка забирает `tabindex` только когда в слоте фокусироваться\n * нечему (текст, иконка). Разметку слота пишет потребитель, привязать к ней\n * `aria-describedby` из шаблона нельзя — отсюда единственная точка, где атрибут\n * ставится вручную.\n */\nconst slotFocusableEl = ref<HTMLElement | null>(null)\n\nfunction syncSlotFocusable(): void {\n slotFocusableEl.value = slots.default\n ? triggerEl.value?.querySelector<HTMLElement>(FOCUSABLE_SELECTOR) ?? null\n : null\n}\n\nonMounted(syncSlotFocusable)\nonUpdated(syncSlotFocusable)\n\nwatchEffect((onCleanup) => {\n const el = slotFocusableEl.value\n if (!el) return\n\n el.setAttribute('aria-describedby', tooltipId)\n onCleanup(() => el.removeAttribute('aria-describedby'))\n})\n\nconst wrapperTabindex = computed(() => (slotFocusableEl.value ? undefined : 0))\nconst wrapperDescribedBy = computed(() => (slotFocusableEl.value ? undefined : tooltipId))\n</script>\n\n<template>\n <span\n v-click-outside=\"dismissOnOutside\"\n data-gr-tooltip\n class=\"relative inline-flex\"\n >\n <span\n ref=\"triggerEl\"\n data-gr-tooltip-trigger\n data-testid=\"gr-tooltip-trigger\"\n :tabindex=\"wrapperTabindex\"\n :aria-describedby=\"wrapperDescribedBy\"\n class=\"inline-flex items-center justify-center focus:outline-none\"\n :style=\"triggerStyle\"\n @mouseenter=\"show\"\n @mouseleave=\"hide\"\n @focusin=\"show\"\n @focusout=\"hide\"\n @touchstart.passive=\"onTouch\"\n >\n <slot>\n <GrIcon :size=\"triggerIconSize\">\n <IconInfo />\n </GrIcon>\n </slot>\n </span>\n\n <teleport :to=\"portalTarget\" :disabled=\"!teleportEnabled\">\n <transition\n enter-active-class=\"transition-opacity duration-[var(--gr-duration-fast)]\"\n enter-from-class=\"opacity-0\"\n enter-to-class=\"opacity-100\"\n leave-active-class=\"transition-opacity duration-[var(--gr-duration-fast)]\"\n leave-from-class=\"opacity-100\"\n leave-to-class=\"opacity-0\"\n >\n <span\n v-show=\"open\"\n :id=\"tooltipId\"\n ref=\"panelEl\"\n role=\"tooltip\"\n v-bind=\"themeAttrs\"\n data-gr-tooltip-panel\n data-gr-overlay-root\n class=\"pointer-events-none rounded-[var(--gr-radius-control)] border border-[var(--gr-brd)] bg-[var(--gr-popover)] text-[var(--gr-popover-fg)] shadow-[var(--gr-shadow-1)]\"\n :class=\"panelClass\"\n :style=\"floatingStyle\"\n >\n <slot name=\"content\">{{ text }}</slot>\n </span>\n </transition>\n </teleport>\n </span>\n</template>\n","<script setup lang=\"ts\">\n/**\n * GrTooltip — GR-примитив инлайн-подсказки на hover/focus.\n *\n * По умолчанию триггер — иконка info; можно заменить через слот.\n * A11y:\n * - `role=\"tooltip\"` связывается с триггером через уникальный `aria-describedby`;\n * - подсказка закрывается по `Escape` (WCAG 1.4.13 «Content on Hover or Focus» —\n * dismissible без необходимости двигать курсор/фокус);\n * - панель не интерактивна (`pointer-events-none`), поэтому «hoverable»-требование\n * того же критерия неприменимо — навести курсор на саму подсказку невозможно.\n *\n * Позиционирование — через общий `useFloating` (см. `composables/internal`):\n * `placement` задаёт предпочтительную сторону, `flip` переворачивает подсказку,\n * если места не хватает, а `shift` не даёт ей вылезти за края viewport.\n */\nimport { computed, onMounted, onUnmounted, onUpdated, ref, useId, useSlots, watchEffect } from 'vue'\n\nimport { usePortalTarget } from '../../composables/usePortalTarget'\n\nimport { vClickOutside } from '../../directives'\nimport GrIcon from '../GrIcon'\nimport { useFloating, type UseFloatingPlacement } from '../../composables/useFloating'\nimport { useDismissible } from '../../composables/useDismissible'\nimport { useGrComponentSize, useGrThemeAttrs } from '../GrConfigProvider/context'\nimport { type GrTooltipSize, panelSizes, panelWidths, triggerIconSizes } from './grTooltipStyles'\n\nimport IconInfo from '~icons/lucide/info'\n\nexport type GrTooltipPlacement = UseFloatingPlacement\n\nexport interface GrTooltipProps {\n /** Текст подсказки. Разметка вместо текста — слот `#content`. */\n text?: string\n /** Цвет триггер-иконки (CSS color). По умолчанию — `var(--gr-muted-fg)`. */\n iconColor?: string\n /** Размер панели и дефолтной триггер-иконки. */\n size?: GrTooltipSize\n /** Предпочтительная сторона панели; `flip` может её изменить. */\n placement?: GrTooltipPlacement\n /** Зазор между триггером и панелью, px. */\n offsetPx?: number\n /** Задержка перед показом, мс. Спасает от мигания при проведении курсором по панели кнопок. */\n openDelay?: number\n /** Задержка перед скрытием, мс. */\n closeDelay?: number\n /** Подсказка не показывается ничем — ни курсором, ни фокусом, ни `v-model:open`. */\n disabled?: boolean\n /** Управляемая видимость. Без неё компонент ведёт видимость сам. */\n open?: boolean\n}\n\nexport interface GrTooltipEmits {\n (e: 'update:open', value: boolean): void\n}\n\nconst props = withDefaults(defineProps<GrTooltipProps>(), {\n text: undefined,\n iconColor: 'var(--gr-muted-fg)',\n size: undefined,\n placement: 'top',\n offsetPx: undefined,\n openDelay: 0,\n closeDelay: 0,\n disabled: false,\n open: undefined,\n})\n\nconst emit = defineEmits<GrTooltipEmits>()\n\ndefineSlots<{\n /** Триггер. По умолчанию — иконка info. */\n default?: () => unknown\n /** Содержимое подсказки; заменяет проп `text`. */\n content?: () => unknown\n}>()\n\nconst slots = useSlots()\n\nconst resolvedSize = useGrComponentSize(() => props.size, { component: 'GrTooltip' })\n\nconst panelClass = computed(() => [\n panelSizes[resolvedSize.value],\n panelWidths[resolvedSize.value],\n].join(' '))\nconst triggerIconSize = computed(() => triggerIconSizes[resolvedSize.value])\n\nconst tooltipId = `gr-tooltip-${useId()}`\n\nconst triggerStyle = computed(() => ({ color: props.iconColor }))\n\n// Телепорт включается только ПОСЛЕ монтирования: иначе первый клиентский\n// рендер не совпадает с серверным и ломается гидрация (см. композабл).\nconst { target: portalTarget, enabled: teleportEnabled } = usePortalTarget()\n\n// Тема поддерева на телепортированную панель: в DOM она уезжает в `body`, то\n// есть вне обёртки провайдера, и `data-theme` с неё не наследуется. В дереве\n// компонентов панель остаётся внутри — `inject` доходит, и тему она ставит себе\n// сама.\nconst themeAttrs = useGrThemeAttrs()\n\nconst uncontrolledOpen = ref(false)\nconst triggerEl = ref<HTMLElement | null>(null)\nconst panelEl = ref<HTMLElement | null>(null)\n\n/** Показывать нечего — пустая панель хуже отсутствующей. */\nconst hasContent = computed(() => Boolean(slots.content) || Boolean(props.text))\n\nconst open = computed<boolean>({\n get: () => {\n if (props.disabled || !hasContent.value) return false\n return props.open ?? uncontrolledOpen.value\n },\n set: (next) => {\n uncontrolledOpen.value = next\n emit('update:open', next)\n },\n})\n\nconst { floatingStyle } = useFloating(triggerEl, panelEl, open, {\n placement: () => props.placement,\n // Геттер, а не значение: `useFloating` читает опцию на каждом пересчёте, и\n // так проп остаётся живым, а не замирает на моменте setup.\n get offsetPx() { return props.offsetPx },\n zIndexVar: '--gr-z-tooltip',\n})\n\nlet delayTimer: ReturnType<typeof setTimeout> | undefined\n\nfunction schedule(next: boolean, delayMs: number): void {\n clearTimeout(delayTimer)\n\n if (delayMs <= 0) {\n open.value = next\n return\n }\n\n delayTimer = setTimeout(() => { open.value = next }, delayMs)\n}\n\nfunction show(): void {\n if (props.disabled) return\n schedule(true, props.openDelay)\n}\n\nfunction hide(): void {\n schedule(false, props.closeDelay)\n}\n\n/** Escape и клик вне закрывают мгновенно: задержка тут читалась бы как залипание. */\nfunction dismiss(): void {\n clearTimeout(delayTimer)\n if (open.value) open.value = false\n}\n\n// Нужен только тач-режиму: курсор и фокус закрывают подсказку сами.\nconst dismissOnOutside = computed(() => ({ handler: dismiss, enabled: open.value }))\n\n/**\n * На тач-устройствах hover не существует, а фокус по тапу не гарантирован —\n * без этого подсказка там недоступна вовсе. Тап по триггеру переключает\n * панель, тап вне — закрывает (`vClickOutside`).\n */\nfunction onTouch(): void {\n if (open.value) dismiss()\n else show()\n}\n\nonUnmounted(() => clearTimeout(delayTimer))\n\nuseDismissible(open, dismiss)\n\nconst FOCUSABLE_SELECTOR = 'a[href],button,input,select,textarea,[tabindex]:not([tabindex=\"-1\"])'\n\n/**\n * Типовое употребление — подсказка у кнопки. Фокусируемая обёртка вокруг\n * фокусируемого контрола дала бы два таб-стопа на один визуальный элемент,\n * поэтому обёртка забирает `tabindex` только когда в слоте фокусироваться\n * нечему (текст, иконка). Разметку слота пишет потребитель, привязать к ней\n * `aria-describedby` из шаблона нельзя — отсюда единственная точка, где атрибут\n * ставится вручную.\n */\nconst slotFocusableEl = ref<HTMLElement | null>(null)\n\nfunction syncSlotFocusable(): void {\n slotFocusableEl.value = slots.default\n ? triggerEl.value?.querySelector<HTMLElement>(FOCUSABLE_SELECTOR) ?? null\n : null\n}\n\nonMounted(syncSlotFocusable)\nonUpdated(syncSlotFocusable)\n\nwatchEffect((onCleanup) => {\n const el = slotFocusableEl.value\n if (!el) return\n\n el.setAttribute('aria-describedby', tooltipId)\n onCleanup(() => el.removeAttribute('aria-describedby'))\n})\n\nconst wrapperTabindex = computed(() => (slotFocusableEl.value ? undefined : 0))\nconst wrapperDescribedBy = computed(() => (slotFocusableEl.value ? undefined : tooltipId))\n</script>\n\n<template>\n <span\n v-click-outside=\"dismissOnOutside\"\n data-gr-tooltip\n class=\"relative inline-flex\"\n >\n <span\n ref=\"triggerEl\"\n data-gr-tooltip-trigger\n data-testid=\"gr-tooltip-trigger\"\n :tabindex=\"wrapperTabindex\"\n :aria-describedby=\"wrapperDescribedBy\"\n class=\"inline-flex items-center justify-center focus:outline-none\"\n :style=\"triggerStyle\"\n @mouseenter=\"show\"\n @mouseleave=\"hide\"\n @focusin=\"show\"\n @focusout=\"hide\"\n @touchstart.passive=\"onTouch\"\n >\n <slot>\n <GrIcon :size=\"triggerIconSize\">\n <IconInfo />\n </GrIcon>\n </slot>\n </span>\n\n <teleport :to=\"portalTarget\" :disabled=\"!teleportEnabled\">\n <transition\n enter-active-class=\"transition-opacity duration-[var(--gr-duration-fast)]\"\n enter-from-class=\"opacity-0\"\n enter-to-class=\"opacity-100\"\n leave-active-class=\"transition-opacity duration-[var(--gr-duration-fast)]\"\n leave-from-class=\"opacity-100\"\n leave-to-class=\"opacity-0\"\n >\n <span\n v-show=\"open\"\n :id=\"tooltipId\"\n ref=\"panelEl\"\n role=\"tooltip\"\n v-bind=\"themeAttrs\"\n data-gr-tooltip-panel\n data-gr-overlay-root\n class=\"pointer-events-none rounded-[var(--gr-radius-control)] border border-[var(--gr-brd)] bg-[var(--gr-popover)] text-[var(--gr-popover-fg)] shadow-[var(--gr-shadow-1)]\"\n :class=\"panelClass\"\n :style=\"floatingStyle\"\n >\n <slot name=\"content\">{{ text }}</slot>\n </span>\n </transition>\n </teleport>\n </span>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"GrTooltip-xAcqs0bP.js","names":[],"sources":["../../../../src/components/GrTooltip/GrTooltip.vue","../../../../src/components/GrTooltip/GrTooltip.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * GrTooltip — GR-примитив инлайн-подсказки на hover/focus.\n *\n * По умолчанию триггер — иконка info; можно заменить через слот.\n * A11y:\n * - `role=\"tooltip\"` связывается с триггером через уникальный `aria-describedby`;\n * - подсказка закрывается по `Escape` (WCAG 1.4.13 «Content on Hover or Focus» —\n * dismissible без необходимости двигать курсор/фокус);\n * - панель не интерактивна (`pointer-events-none`), поэтому «hoverable»-требование\n * того же критерия неприменимо — навести курсор на саму подсказку невозможно.\n *\n * Позиционирование — через общий `useFloating` (см. `composables/internal`):\n * `placement` задаёт предпочтительную сторону, `flip` переворачивает подсказку,\n * если места не хватает, а `shift` не даёт ей вылезти за края viewport.\n */\nimport { computed, onMounted, onUnmounted, onUpdated, ref, useId, useSlots, watchEffect } from 'vue'\n\nimport { usePortalTarget } from '../../composables/usePortalTarget'\n\nimport { vClickOutside } from '../../directives'\nimport GrIcon from '../GrIcon'\nimport { useFloating, type UseFloatingPlacement } from '../../composables/useFloating'\nimport { useDismissible } from '../../composables/useDismissible'\nimport { useGrComponentSize, useGrThemeAttrs } from '../GrConfigProvider/context'\nimport { type GrTooltipSize, panelSizes, panelWidths, triggerIconSizes } from './grTooltipStyles'\n\nimport IconInfo from '~icons/lucide/info'\n\nexport type GrTooltipPlacement = UseFloatingPlacement\n\nexport interface GrTooltipProps {\n /** Текст подсказки. Разметка вместо текста — слот `#content`. */\n text?: string\n /** Цвет триггер-иконки (CSS color). По умолчанию — `var(--gr-muted-fg)`. */\n iconColor?: string\n /** Размер панели и дефолтной триггер-иконки. */\n size?: GrTooltipSize\n /** Предпочтительная сторона панели; `flip` может её изменить. */\n placement?: GrTooltipPlacement\n /** Зазор между триггером и панелью, px. */\n offsetPx?: number\n /** Задержка перед показом, мс. Спасает от мигания при проведении курсором по панели кнопок. */\n openDelay?: number\n /** Задержка перед скрытием, мс. */\n closeDelay?: number\n /** Подсказка не показывается ничем — ни курсором, ни фокусом, ни `v-model:open`. */\n disabled?: boolean\n /** Управляемая видимость. Без неё компонент ведёт видимость сам. */\n open?: boolean\n}\n\nexport interface GrTooltipEmits {\n (e: 'update:open', value: boolean): void\n}\n\nconst props = withDefaults(defineProps<GrTooltipProps>(), {\n text: undefined,\n iconColor: 'var(--gr-muted-fg)',\n size: undefined,\n placement: 'top',\n offsetPx: undefined,\n openDelay: 0,\n closeDelay: 0,\n disabled: false,\n open: undefined,\n})\n\nconst emit = defineEmits<GrTooltipEmits>()\n\ndefineSlots<{\n /** Триггер. По умолчанию — иконка info. */\n default?: () => unknown\n /** Содержимое подсказки; заменяет проп `text`. */\n content?: () => unknown\n}>()\n\nconst slots = useSlots()\n\nconst resolvedSize = useGrComponentSize(() => props.size, { component: 'GrTooltip' })\n\nconst panelClass = computed(() => [\n panelSizes[resolvedSize.value],\n panelWidths[resolvedSize.value],\n].join(' '))\nconst triggerIconSize = computed(() => triggerIconSizes[resolvedSize.value])\n\nconst tooltipId = `gr-tooltip-${useId()}`\n\nconst triggerStyle = computed(() => ({ color: props.iconColor }))\n\n// Телепорт включается только ПОСЛЕ монтирования: иначе первый клиентский\n// рендер не совпадает с серверным и ломается гидрация (см. композабл).\nconst { target: portalTarget, enabled: teleportEnabled } = usePortalTarget()\n\n// Тема поддерева на телепортированную панель: в DOM она уезжает в `body`, то\n// есть вне обёртки провайдера, и `data-theme` с неё не наследуется. В дереве\n// компонентов панель остаётся внутри — `inject` доходит, и тему она ставит себе\n// сама.\nconst themeAttrs = useGrThemeAttrs()\n\nconst uncontrolledOpen = ref(false)\nconst triggerEl = ref<HTMLElement | null>(null)\nconst panelEl = ref<HTMLElement | null>(null)\n\n/** Показывать нечего — пустая панель хуже отсутствующей. */\nconst hasContent = computed(() => Boolean(slots.content) || Boolean(props.text))\n\nconst open = computed<boolean>({\n get: () => {\n if (props.disabled || !hasContent.value) return false\n return props.open ?? uncontrolledOpen.value\n },\n set: (next) => {\n uncontrolledOpen.value = next\n emit('update:open', next)\n },\n})\n\nconst { floatingStyle } = useFloating(triggerEl, panelEl, open, {\n placement: () => props.placement,\n // Геттер, а не значение: `useFloating` читает опцию на каждом пересчёте, и\n // так проп остаётся живым, а не замирает на моменте setup.\n get offsetPx() { return props.offsetPx },\n zIndexVar: '--gr-z-tooltip',\n})\n\nlet delayTimer: ReturnType<typeof setTimeout> | undefined\n\nfunction schedule(next: boolean, delayMs: number): void {\n clearTimeout(delayTimer)\n\n if (delayMs <= 0) {\n open.value = next\n return\n }\n\n delayTimer = setTimeout(() => { open.value = next }, delayMs)\n}\n\nfunction show(): void {\n if (props.disabled) return\n schedule(true, props.openDelay)\n}\n\nfunction hide(): void {\n schedule(false, props.closeDelay)\n}\n\n/** Escape и клик вне закрывают мгновенно: задержка тут читалась бы как залипание. */\nfunction dismiss(): void {\n clearTimeout(delayTimer)\n if (open.value) open.value = false\n}\n\n// Нужен только тач-режиму: курсор и фокус закрывают подсказку сами.\nconst dismissOnOutside = computed(() => ({ handler: dismiss, enabled: open.value }))\n\n/**\n * На тач-устройствах hover не существует, а фокус по тапу не гарантирован —\n * без этого подсказка там недоступна вовсе. Тап по триггеру переключает\n * панель, тап вне — закрывает (`vClickOutside`).\n */\nfunction onTouch(): void {\n if (open.value) dismiss()\n else show()\n}\n\nonUnmounted(() => clearTimeout(delayTimer))\n\nuseDismissible(open, dismiss)\n\nconst FOCUSABLE_SELECTOR = 'a[href],button,input,select,textarea,[tabindex]:not([tabindex=\"-1\"])'\n\n/**\n * Типовое употребление — подсказка у кнопки. Фокусируемая обёртка вокруг\n * фокусируемого контрола дала бы два таб-стопа на один визуальный элемент,\n * поэтому обёртка забирает `tabindex` только когда в слоте фокусироваться\n * нечему (текст, иконка). Разметку слота пишет потребитель, привязать к ней\n * `aria-describedby` из шаблона нельзя — отсюда единственная точка, где атрибут\n * ставится вручную.\n */\nconst slotFocusableEl = ref<HTMLElement | null>(null)\n\nfunction syncSlotFocusable(): void {\n slotFocusableEl.value = slots.default\n ? triggerEl.value?.querySelector<HTMLElement>(FOCUSABLE_SELECTOR) ?? null\n : null\n}\n\nonMounted(syncSlotFocusable)\nonUpdated(syncSlotFocusable)\n\nwatchEffect((onCleanup) => {\n const el = slotFocusableEl.value\n if (!el) return\n\n el.setAttribute('aria-describedby', tooltipId)\n onCleanup(() => el.removeAttribute('aria-describedby'))\n})\n\nconst wrapperTabindex = computed(() => (slotFocusableEl.value ? undefined : 0))\nconst wrapperDescribedBy = computed(() => (slotFocusableEl.value ? undefined : tooltipId))\n</script>\n\n<template>\n <span\n v-click-outside=\"dismissOnOutside\"\n data-gr-tooltip\n class=\"relative inline-flex\"\n >\n <span\n ref=\"triggerEl\"\n data-gr-tooltip-trigger\n data-testid=\"gr-tooltip-trigger\"\n :tabindex=\"wrapperTabindex\"\n :aria-describedby=\"wrapperDescribedBy\"\n class=\"inline-flex items-center justify-center focus:outline-none\"\n :style=\"triggerStyle\"\n @mouseenter=\"show\"\n @mouseleave=\"hide\"\n @focusin=\"show\"\n @focusout=\"hide\"\n @touchstart.passive=\"onTouch\"\n >\n <slot>\n <GrIcon :size=\"triggerIconSize\">\n <IconInfo />\n </GrIcon>\n </slot>\n </span>\n\n <teleport :to=\"portalTarget\" :disabled=\"!teleportEnabled\">\n <transition\n enter-active-class=\"transition-opacity duration-[var(--gr-duration-fast)]\"\n enter-from-class=\"opacity-0\"\n enter-to-class=\"opacity-100\"\n leave-active-class=\"transition-opacity duration-[var(--gr-duration-fast)]\"\n leave-from-class=\"opacity-100\"\n leave-to-class=\"opacity-0\"\n >\n <span\n v-show=\"open\"\n :id=\"tooltipId\"\n ref=\"panelEl\"\n role=\"tooltip\"\n v-bind=\"themeAttrs\"\n data-gr-tooltip-panel\n data-gr-overlay-root\n class=\"pointer-events-none rounded-[var(--gr-radius-control)] border border-[var(--gr-brd)] bg-[var(--gr-popover)] text-[var(--gr-popover-fg)] shadow-[var(--gr-shadow-1)]\"\n :class=\"panelClass\"\n :style=\"floatingStyle\"\n >\n <slot name=\"content\">{{ text }}</slot>\n </span>\n </transition>\n </teleport>\n </span>\n</template>\n","<script setup lang=\"ts\">\n/**\n * GrTooltip — GR-примитив инлайн-подсказки на hover/focus.\n *\n * По умолчанию триггер — иконка info; можно заменить через слот.\n * A11y:\n * - `role=\"tooltip\"` связывается с триггером через уникальный `aria-describedby`;\n * - подсказка закрывается по `Escape` (WCAG 1.4.13 «Content on Hover or Focus» —\n * dismissible без необходимости двигать курсор/фокус);\n * - панель не интерактивна (`pointer-events-none`), поэтому «hoverable»-требование\n * того же критерия неприменимо — навести курсор на саму подсказку невозможно.\n *\n * Позиционирование — через общий `useFloating` (см. `composables/internal`):\n * `placement` задаёт предпочтительную сторону, `flip` переворачивает подсказку,\n * если места не хватает, а `shift` не даёт ей вылезти за края viewport.\n */\nimport { computed, onMounted, onUnmounted, onUpdated, ref, useId, useSlots, watchEffect } from 'vue'\n\nimport { usePortalTarget } from '../../composables/usePortalTarget'\n\nimport { vClickOutside } from '../../directives'\nimport GrIcon from '../GrIcon'\nimport { useFloating, type UseFloatingPlacement } from '../../composables/useFloating'\nimport { useDismissible } from '../../composables/useDismissible'\nimport { useGrComponentSize, useGrThemeAttrs } from '../GrConfigProvider/context'\nimport { type GrTooltipSize, panelSizes, panelWidths, triggerIconSizes } from './grTooltipStyles'\n\nimport IconInfo from '~icons/lucide/info'\n\nexport type GrTooltipPlacement = UseFloatingPlacement\n\nexport interface GrTooltipProps {\n /** Текст подсказки. Разметка вместо текста — слот `#content`. */\n text?: string\n /** Цвет триггер-иконки (CSS color). По умолчанию — `var(--gr-muted-fg)`. */\n iconColor?: string\n /** Размер панели и дефолтной триггер-иконки. */\n size?: GrTooltipSize\n /** Предпочтительная сторона панели; `flip` может её изменить. */\n placement?: GrTooltipPlacement\n /** Зазор между триггером и панелью, px. */\n offsetPx?: number\n /** Задержка перед показом, мс. Спасает от мигания при проведении курсором по панели кнопок. */\n openDelay?: number\n /** Задержка перед скрытием, мс. */\n closeDelay?: number\n /** Подсказка не показывается ничем — ни курсором, ни фокусом, ни `v-model:open`. */\n disabled?: boolean\n /** Управляемая видимость. Без неё компонент ведёт видимость сам. */\n open?: boolean\n}\n\nexport interface GrTooltipEmits {\n (e: 'update:open', value: boolean): void\n}\n\nconst props = withDefaults(defineProps<GrTooltipProps>(), {\n text: undefined,\n iconColor: 'var(--gr-muted-fg)',\n size: undefined,\n placement: 'top',\n offsetPx: undefined,\n openDelay: 0,\n closeDelay: 0,\n disabled: false,\n open: undefined,\n})\n\nconst emit = defineEmits<GrTooltipEmits>()\n\ndefineSlots<{\n /** Триггер. По умолчанию — иконка info. */\n default?: () => unknown\n /** Содержимое подсказки; заменяет проп `text`. */\n content?: () => unknown\n}>()\n\nconst slots = useSlots()\n\nconst resolvedSize = useGrComponentSize(() => props.size, { component: 'GrTooltip' })\n\nconst panelClass = computed(() => [\n panelSizes[resolvedSize.value],\n panelWidths[resolvedSize.value],\n].join(' '))\nconst triggerIconSize = computed(() => triggerIconSizes[resolvedSize.value])\n\nconst tooltipId = `gr-tooltip-${useId()}`\n\nconst triggerStyle = computed(() => ({ color: props.iconColor }))\n\n// Телепорт включается только ПОСЛЕ монтирования: иначе первый клиентский\n// рендер не совпадает с серверным и ломается гидрация (см. композабл).\nconst { target: portalTarget, enabled: teleportEnabled } = usePortalTarget()\n\n// Тема поддерева на телепортированную панель: в DOM она уезжает в `body`, то\n// есть вне обёртки провайдера, и `data-theme` с неё не наследуется. В дереве\n// компонентов панель остаётся внутри — `inject` доходит, и тему она ставит себе\n// сама.\nconst themeAttrs = useGrThemeAttrs()\n\nconst uncontrolledOpen = ref(false)\nconst triggerEl = ref<HTMLElement | null>(null)\nconst panelEl = ref<HTMLElement | null>(null)\n\n/** Показывать нечего — пустая панель хуже отсутствующей. */\nconst hasContent = computed(() => Boolean(slots.content) || Boolean(props.text))\n\nconst open = computed<boolean>({\n get: () => {\n if (props.disabled || !hasContent.value) return false\n return props.open ?? uncontrolledOpen.value\n },\n set: (next) => {\n uncontrolledOpen.value = next\n emit('update:open', next)\n },\n})\n\nconst { floatingStyle } = useFloating(triggerEl, panelEl, open, {\n placement: () => props.placement,\n // Геттер, а не значение: `useFloating` читает опцию на каждом пересчёте, и\n // так проп остаётся живым, а не замирает на моменте setup.\n get offsetPx() { return props.offsetPx },\n zIndexVar: '--gr-z-tooltip',\n})\n\nlet delayTimer: ReturnType<typeof setTimeout> | undefined\n\nfunction schedule(next: boolean, delayMs: number): void {\n clearTimeout(delayTimer)\n\n if (delayMs <= 0) {\n open.value = next\n return\n }\n\n delayTimer = setTimeout(() => { open.value = next }, delayMs)\n}\n\nfunction show(): void {\n if (props.disabled) return\n schedule(true, props.openDelay)\n}\n\nfunction hide(): void {\n schedule(false, props.closeDelay)\n}\n\n/** Escape и клик вне закрывают мгновенно: задержка тут читалась бы как залипание. */\nfunction dismiss(): void {\n clearTimeout(delayTimer)\n if (open.value) open.value = false\n}\n\n// Нужен только тач-режиму: курсор и фокус закрывают подсказку сами.\nconst dismissOnOutside = computed(() => ({ handler: dismiss, enabled: open.value }))\n\n/**\n * На тач-устройствах hover не существует, а фокус по тапу не гарантирован —\n * без этого подсказка там недоступна вовсе. Тап по триггеру переключает\n * панель, тап вне — закрывает (`vClickOutside`).\n */\nfunction onTouch(): void {\n if (open.value) dismiss()\n else show()\n}\n\nonUnmounted(() => clearTimeout(delayTimer))\n\nuseDismissible(open, dismiss)\n\nconst FOCUSABLE_SELECTOR = 'a[href],button,input,select,textarea,[tabindex]:not([tabindex=\"-1\"])'\n\n/**\n * Типовое употребление — подсказка у кнопки. Фокусируемая обёртка вокруг\n * фокусируемого контрола дала бы два таб-стопа на один визуальный элемент,\n * поэтому обёртка забирает `tabindex` только когда в слоте фокусироваться\n * нечему (текст, иконка). Разметку слота пишет потребитель, привязать к ней\n * `aria-describedby` из шаблона нельзя — отсюда единственная точка, где атрибут\n * ставится вручную.\n */\nconst slotFocusableEl = ref<HTMLElement | null>(null)\n\nfunction syncSlotFocusable(): void {\n slotFocusableEl.value = slots.default\n ? triggerEl.value?.querySelector<HTMLElement>(FOCUSABLE_SELECTOR) ?? null\n : null\n}\n\nonMounted(syncSlotFocusable)\nonUpdated(syncSlotFocusable)\n\nwatchEffect((onCleanup) => {\n const el = slotFocusableEl.value\n if (!el) return\n\n el.setAttribute('aria-describedby', tooltipId)\n onCleanup(() => el.removeAttribute('aria-describedby'))\n})\n\nconst wrapperTabindex = computed(() => (slotFocusableEl.value ? undefined : 0))\nconst wrapperDescribedBy = computed(() => (slotFocusableEl.value ? undefined : tooltipId))\n</script>\n\n<template>\n <span\n v-click-outside=\"dismissOnOutside\"\n data-gr-tooltip\n class=\"relative inline-flex\"\n >\n <span\n ref=\"triggerEl\"\n data-gr-tooltip-trigger\n data-testid=\"gr-tooltip-trigger\"\n :tabindex=\"wrapperTabindex\"\n :aria-describedby=\"wrapperDescribedBy\"\n class=\"inline-flex items-center justify-center focus:outline-none\"\n :style=\"triggerStyle\"\n @mouseenter=\"show\"\n @mouseleave=\"hide\"\n @focusin=\"show\"\n @focusout=\"hide\"\n @touchstart.passive=\"onTouch\"\n >\n <slot>\n <GrIcon :size=\"triggerIconSize\">\n <IconInfo />\n </GrIcon>\n </slot>\n </span>\n\n <teleport :to=\"portalTarget\" :disabled=\"!teleportEnabled\">\n <transition\n enter-active-class=\"transition-opacity duration-[var(--gr-duration-fast)]\"\n enter-from-class=\"opacity-0\"\n enter-to-class=\"opacity-100\"\n leave-active-class=\"transition-opacity duration-[var(--gr-duration-fast)]\"\n leave-from-class=\"opacity-100\"\n leave-to-class=\"opacity-0\"\n >\n <span\n v-show=\"open\"\n :id=\"tooltipId\"\n ref=\"panelEl\"\n role=\"tooltip\"\n v-bind=\"themeAttrs\"\n data-gr-tooltip-panel\n data-gr-overlay-root\n class=\"pointer-events-none rounded-[var(--gr-radius-control)] border border-[var(--gr-brd)] bg-[var(--gr-popover)] text-[var(--gr-popover-fg)] shadow-[var(--gr-shadow-1)]\"\n :class=\"panelClass\"\n :style=\"floatingStyle\"\n >\n <slot name=\"content\">{{ text }}</slot>\n </span>\n </transition>\n </teleport>\n </span>\n</template>\n"],"mappings":"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"}
@@ -1,3 +1,3 @@
1
- import { n as grTooltipSafelist, t as grTooltipConfig } from "../../chunks/config-CN2ULSQL2.js";
2
- import { t as GrTooltip_default } from "./chunks/GrTooltip-DEbejfhA.js";
1
+ import { n as grTooltipSafelist, t as grTooltipConfig } from "../../chunks/config-CN2ULSQL.js";
2
+ import { t as GrTooltip_default } from "./chunks/GrTooltip-xAcqs0bP.js";
3
3
  export { GrTooltip_default as GrTooltip, GrTooltip_default as default, grTooltipConfig, grTooltipSafelist };
@@ -2,6 +2,9 @@ import { o as useGrComponentSize } from "../../../chunks/context-BSYR7RZs.js";
2
2
  import { n as useGranularityTranslations } from "../../../chunks/granularityI18n-BC5zsj_d.js";
3
3
  import { useVirtualList } from "../../../composables/useVirtualList.js";
4
4
  import { t as _plugin_vue_export_helper_default } from "../../../chunks/_plugin-vue_export-helper-BOaGB7Aw.js";
5
+ import { useAnnouncer } from "../../../composables/useAnnouncer.js";
6
+ import { t as useDragSort } from "../../../chunks/useDragSort-0l47h4yb.js";
7
+ import { useRovingFocus } from "../../../composables/useRovingFocus.js";
5
8
  import { Fragment, computed, createCommentVNode, createElementBlock, createElementVNode, defineComponent, nextTick, normalizeClass, normalizeStyle, onBeforeUnmount, onUnmounted, openBlock, ref, renderList, renderSlot, shallowRef, toDisplayString, toValue, unref, watch, withModifiers } from "vue";
6
9
  import '../styles.css';//#region src/components/GrTree/grTreeDataAdapter.ts
7
10
  var DEFAULT_CHILDREN_KEY = "children";
@@ -68,7 +71,6 @@ function createGrTreeDataAdapter(options) {
68
71
  //#region src/components/GrTree/grTreeInteractionContext.ts
69
72
  function createGrTreeInteractionContext(options, emitters) {
70
73
  const hoveredKey = ref(void 0);
71
- const focusedKey = ref(void 0);
72
74
  const draggingNode = shallowRef(null);
73
75
  const dropTarget = shallowRef(null);
74
76
  const nodeEls = /* @__PURE__ */ new Map();
@@ -95,7 +97,6 @@ function createGrTreeInteractionContext(options, emitters) {
95
97
  }
96
98
  return {
97
99
  hoveredKey,
98
- focusedKey,
99
100
  nodeEls,
100
101
  registerNodeEl,
101
102
  draggingNode,
@@ -597,15 +598,13 @@ var _hoisted_2 = [
597
598
  var _hoisted_3 = [
598
599
  "onClick",
599
600
  "onContextmenu",
600
- "onDrop",
601
- "onDragover",
602
601
  "onMouseenter",
603
602
  "onMouseleave"
604
603
  ];
605
604
  var _hoisted_4 = [
606
605
  "aria-label",
607
- "draggable",
608
- "onDragstart"
606
+ "aria-disabled",
607
+ "onPointerdown"
609
608
  ];
610
609
  var _hoisted_5 = ["aria-label", "onClick"];
611
610
  var _hoisted_6 = {
@@ -616,6 +615,7 @@ var _hoisted_6 = {
616
615
  var _hoisted_7 = ["onClick"];
617
616
  var _hoisted_8 = { class: "gr-tree__label" };
618
617
  var DEFAULT_BRANCH_LINE_COLOR = "var(--gr-tree-branch-line-default-color, var(--gr-brd))";
618
+ /** Стрелки, которые вместе с `Shift` двигают узел, а не фокус. */
619
619
  var TREE_ROW_GAP = 2;
620
620
  var TYPEAHEAD_RESET_MS = 600;
621
621
  //#endregion
@@ -777,6 +777,12 @@ var GrTree_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE_
777
777
  "check"
778
778
  ],
779
779
  setup(__props, { expose: __expose, emit: __emit }) {
780
+ const MOVE_KEYS = /* @__PURE__ */ new Set([
781
+ "ArrowUp",
782
+ "ArrowDown",
783
+ "ArrowLeft",
784
+ "ArrowRight"
785
+ ]);
780
786
  const props = __props;
781
787
  const emit = __emit;
782
788
  const treeStore = createGrTreeStore({
@@ -800,12 +806,12 @@ var GrTree_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE_
800
806
  });
801
807
  const treeProps = props;
802
808
  const { t } = useGranularityTranslations();
809
+ const { announce } = useAnnouncer();
803
810
  const dragLabel = computed(() => treeProps.dragLabel ?? t("gr.tree.drag", "Drag"));
804
811
  const expandLabel = computed(() => treeProps.expandLabel ?? t("gr.tree.expand", "Expand"));
805
812
  const collapseLabel = computed(() => treeProps.collapseLabel ?? t("gr.tree.collapse", "Collapse"));
806
813
  const currentKey = treeStore.currentKey;
807
814
  const hoveredKey = interactionContext.hoveredKey;
808
- const focusedKey = interactionContext.focusedKey;
809
815
  const dropTarget = interactionContext.dropTarget;
810
816
  const treeRootEl = ref(null);
811
817
  /**
@@ -842,9 +848,25 @@ var GrTree_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE_
842
848
  walk(roots, []);
843
849
  return rows;
844
850
  });
851
+ /**
852
+ * Кольцо roving-фокуса: ровно один `treeitem` на всё дерево держит `tabindex=0`.
853
+ *
854
+ * Ориентация вертикальная намеренно: влево-вправо в дереве заняты раскрытием
855
+ * ветки и переходом к родителю, и примитив их не трогает — это доменная логика,
856
+ * она осталась в `onTreeKeydown`.
857
+ */
858
+ const roving = useRovingFocus({
859
+ items: () => visibleRows.value.map((row) => row.node.key),
860
+ elementFor: (key) => interactionContext.nodeEls.get(key),
861
+ orientation: () => "vertical",
862
+ wrap: () => false,
863
+ onOverflow: () => true,
864
+ initialKey: () => currentKey.value ?? void 0,
865
+ beforeFocus: (key) => scrollRowIntoView(key)
866
+ });
845
867
  function onRowClick(node) {
846
868
  treeStore.setCurrentKey(node.key);
847
- focusedKey.value = node.key;
869
+ roving.setActive(node.key);
848
870
  interactionContext.emitNodeClick(node.data, node);
849
871
  }
850
872
  function onRowActivate(row) {
@@ -855,7 +877,7 @@ var GrTree_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE_
855
877
  interactionContext.emitNodeContextMenu(evt, node.data, node);
856
878
  }
857
879
  function isRovingItem(key) {
858
- return focusedKey.value === key;
880
+ return roving.rovingKey.value === key;
859
881
  }
860
882
  const resolvedSize = useGrComponentSize(() => props.size, { component: "GrTree" });
861
883
  const sizeStyle = computed(() => treeSizeVars[resolvedSize.value]);
@@ -935,13 +957,20 @@ var GrTree_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE_
935
957
  interactionContext.registerNodeEl(key, null);
936
958
  if (heldFocus && !isUnmounting) treeRootEl.value?.focus({ preventScroll: true });
937
959
  }
938
- function focusRow(key) {
939
- focusedKey.value = key;
960
+ /**
961
+ * При виртуализации узла вне окна в DOM нет: `nodeEls.get` вернул бы
962
+ * `undefined`, а фокус уехал бы на `body` вместе с размонтированной строкой.
963
+ * Поэтому сперва прокрутка, и только следующим тиком — фокус.
964
+ */
965
+ function scrollRowIntoView(key) {
940
966
  if (treeProps.virtual) {
941
967
  const index = visibleRows.value.findIndex((row) => row.node.key === key);
942
968
  if (index >= 0) virtualizer.scrollToIndex(index);
943
969
  }
944
- nextTick(() => interactionContext.nodeEls.get(key)?.focus());
970
+ return nextTick();
971
+ }
972
+ function focusRow(key) {
973
+ roving.focusKey(key);
945
974
  }
946
975
  /**
947
976
  * Typeahead паттерна tree: печатные символы копятся в буфер и переводят фокус
@@ -982,7 +1011,7 @@ var GrTree_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE_
982
1011
  }
983
1012
  const rows = visibleRows.value;
984
1013
  if (rows.length === 0) return;
985
- const idx = Math.max(0, rows.findIndex((r) => r.node.key === focusedKey.value));
1014
+ const idx = Math.max(0, rows.findIndex((r) => r.node.key === roving.rovingKey.value));
986
1015
  const cur = rows[idx];
987
1016
  if (event.key === "*") {
988
1017
  event.preventDefault();
@@ -994,15 +1023,14 @@ var GrTree_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE_
994
1023
  onTypeahead(event.key, rows, idx);
995
1024
  return;
996
1025
  }
1026
+ if (event.shiftKey && MOVE_KEYS.has(event.key)) {
1027
+ if (!treeProps.draggable) return;
1028
+ event.preventDefault();
1029
+ onNodeMoveKey(cur.node, event.key);
1030
+ return;
1031
+ }
1032
+ if (roving.handleNavigationKeys(event)) return;
997
1033
  switch (event.key) {
998
- case "ArrowDown":
999
- event.preventDefault();
1000
- if (idx < rows.length - 1) focusRow(rows[idx + 1].node.key);
1001
- break;
1002
- case "ArrowUp":
1003
- event.preventDefault();
1004
- if (idx > 0) focusRow(rows[idx - 1].node.key);
1005
- break;
1006
1034
  case "ArrowRight":
1007
1035
  event.preventDefault();
1008
1036
  if (!cur.isLeaf) {
@@ -1015,14 +1043,6 @@ var GrTree_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE_
1015
1043
  if (!cur.isLeaf && cur.isExpanded) toggleExpand(cur.node);
1016
1044
  else if (cur.node.parent && rows.some((r) => r.node.key === cur.node.parent.key)) focusRow(cur.node.parent.key);
1017
1045
  break;
1018
- case "Home":
1019
- event.preventDefault();
1020
- focusRow(rows[0].node.key);
1021
- break;
1022
- case "End":
1023
- event.preventDefault();
1024
- focusRow(rows[rows.length - 1].node.key);
1025
- break;
1026
1046
  case "Enter":
1027
1047
  event.preventDefault();
1028
1048
  onRowClick(cur.node);
@@ -1034,17 +1054,6 @@ var GrTree_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE_
1034
1054
  break;
1035
1055
  }
1036
1056
  }
1037
- function normalizeFocusedKey() {
1038
- const rows = visibleRows.value;
1039
- if (rows.length === 0) {
1040
- focusedKey.value = void 0;
1041
- return;
1042
- }
1043
- if (focusedKey.value !== void 0 && rows.some((r) => r.node.key === focusedKey.value)) return;
1044
- focusedKey.value = currentKey.value != null && rows.some((r) => r.node.key === currentKey.value) ? currentKey.value : rows[0].node.key;
1045
- }
1046
- normalizeFocusedKey();
1047
- watch(visibleRows, normalizeFocusedKey, { flush: "sync" });
1048
1057
  function onRowMouseEnter(node) {
1049
1058
  hoveredKey.value = node.key;
1050
1059
  }
@@ -1107,58 +1116,84 @@ var GrTree_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE_
1107
1116
  function shouldShowDragHandle(node) {
1108
1117
  return canDrag(node) && hoveredKey.value === node.key;
1109
1118
  }
1110
- function resolveDropType(evt, el) {
1111
- const rect = el.getBoundingClientRect();
1112
- const y = evt.clientY - rect.top;
1113
- const third = rect.height / 3;
1114
- if (y < third) return "prev";
1115
- if (y > third * 2) return "next";
1119
+ /**
1120
+ * Треть строки сверху — «до», треть снизу — «после», середина — «внутрь».
1121
+ * Зоны нарезает компонент: примитив отдаёт только долю вдоль строки.
1122
+ */
1123
+ function dropTypeFromFraction(fraction) {
1124
+ if (fraction < 1 / 3) return "prev";
1125
+ if (fraction > 2 / 3) return "next";
1116
1126
  return "inner";
1117
1127
  }
1118
1128
  function canDrop(drag, target, type) {
1119
1129
  return interactionContext.canDrop(drag, target, type);
1120
1130
  }
1121
- function onDragStart(evt, node) {
1122
- if (!canDrag(node)) {
1123
- evt.preventDefault();
1124
- return;
1125
- }
1126
- interactionContext.draggingNode.value = node;
1127
- interactionContext.dropTarget.value = null;
1128
- try {
1129
- evt.dataTransfer?.setData("text/plain", String(node.key));
1130
- } catch {}
1131
- if (evt.dataTransfer) evt.dataTransfer.effectAllowed = "move";
1131
+ /** Перенос состоялся: одна дорога и для указателя, и для клавиатуры. */
1132
+ function applyMove(source, targetKey, type) {
1133
+ const reference = treeStore.getNode(targetKey);
1134
+ if (!reference) return false;
1135
+ const movedNode = treeStore.moveNode(source, reference, type);
1136
+ if (!movedNode) return false;
1137
+ const dropNode = treeStore.getNode(reference.key) ?? reference;
1138
+ interactionContext.emitNodeDrop(movedNode, dropNode, type);
1139
+ return true;
1132
1140
  }
1133
- function onDragEnd() {
1134
- interactionContext.resetDragState();
1141
+ const dragSort = useDragSort({
1142
+ items: () => visibleRows.value.map((row) => row.node.key),
1143
+ elementFor: (key) => interactionContext.nodeEls.get(key) ?? null,
1144
+ scroller: () => treeRootEl.value,
1145
+ disabled: () => !treeProps.draggable,
1146
+ canDrag: (key) => {
1147
+ const node = treeStore.getNode(key);
1148
+ return node ? canDrag(node) : false;
1149
+ },
1150
+ resolveTarget: (hit, sourceKey, previous) => {
1151
+ const source = treeStore.getNode(sourceKey);
1152
+ const node = treeStore.getNode(hit.key);
1153
+ if (!source || !node) return null;
1154
+ const type = dropTypeFromFraction(hit.fraction);
1155
+ const allowed = treeStore.canMoveNode(source, node, type) && canDrop(source, node, type);
1156
+ if (previous && previous.key === node.key && previous.type === type && previous.allowed === allowed) return previous;
1157
+ return {
1158
+ key: node.key,
1159
+ type,
1160
+ allowed
1161
+ };
1162
+ },
1163
+ onDrop: (sourceKey, target) => {
1164
+ const source = treeStore.getNode(sourceKey);
1165
+ if (!source || !target.allowed) return;
1166
+ applyMove(source, target.key, target.type);
1167
+ },
1168
+ onUpdate: (sourceKey, target) => {
1169
+ interactionContext.draggingNode.value = sourceKey === null ? null : treeStore.getNode(sourceKey) ?? null;
1170
+ interactionContext.dropTarget.value = target;
1171
+ }
1172
+ });
1173
+ function onHandlePointerDown(event, node) {
1174
+ if (!treeProps.draggable) return;
1175
+ dragSort.startFrom(node.key)(event);
1135
1176
  }
1136
- function onDragOver(evt, node, rowEl) {
1137
- const drag = interactionContext.draggingNode.value;
1138
- if (!treeProps.draggable || !drag) return;
1139
- evt.preventDefault();
1140
- const type = resolveDropType(evt, rowEl);
1141
- const allowed = treeStore.canMoveNode(drag, node, type) && canDrop(drag, node, type);
1142
- interactionContext.dropTarget.value = {
1143
- key: node.key,
1144
- type,
1145
- allowed
1146
- };
1147
- if (evt.dataTransfer) evt.dataTransfer.dropEffect = allowed ? "move" : "none";
1177
+ /**
1178
+ * Клавиатурный перенос — раскладка аутлайнера: `Shift` со стрелкой сразу
1179
+ * двигает узел, без режима «взято». Режим здесь был бы лишним: `Space` в дереве
1180
+ * уже отмечает чекбокс, а стрелки водят фокус по веткам.
1181
+ */
1182
+ function moveByKeyboard(node, key) {
1183
+ const siblings = node.parent ? node.parent.childNodes : treeStore.treeModel.value.roots;
1184
+ const index = siblings.findIndex((sibling) => sibling.key === node.key);
1185
+ if (key === "ArrowUp" && index > 0) return applyMove(node, siblings[index - 1].key, "prev");
1186
+ if (key === "ArrowDown" && index >= 0 && index < siblings.length - 1) return applyMove(node, siblings[index + 1].key, "next");
1187
+ if (key === "ArrowRight" && index > 0) return applyMove(node, siblings[index - 1].key, "inner");
1188
+ if (key === "ArrowLeft" && node.parent) return applyMove(node, node.parent.key, "next");
1189
+ return false;
1148
1190
  }
1149
- function onDrop(evt, node) {
1150
- evt.preventDefault();
1151
- const drag = interactionContext.draggingNode.value;
1152
- const target = interactionContext.dropTarget.value;
1153
- if (!treeProps.draggable || !drag || !target) return;
1154
- if (target.key === node.key && target.allowed) {
1155
- const movedNode = treeStore.moveNode(drag, node, target.type);
1156
- if (movedNode) {
1157
- const dropNode = treeStore.getNode(node.key) ?? node;
1158
- interactionContext.emitNodeDrop(movedNode, dropNode, target.type);
1159
- }
1160
- }
1161
- interactionContext.resetDragState();
1191
+ async function onNodeMoveKey(node, key) {
1192
+ if (!treeProps.draggable || !canDrag(node)) return;
1193
+ if (!moveByKeyboard(node, key)) return;
1194
+ announce(t("gr.tree.moved", "Moved {label}", { label: node.label }));
1195
+ await nextTick();
1196
+ focusRow(node.key);
1162
1197
  }
1163
1198
  function filter(value) {
1164
1199
  treeStore.filter(value);
@@ -1190,7 +1225,7 @@ var GrTree_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE_
1190
1225
  function focus(key) {
1191
1226
  const rows = visibleRows.value;
1192
1227
  if (rows.length === 0) return false;
1193
- focusRow(key != null && rows.some((row) => row.node.key === key) ? key : focusedKey.value ?? rows[0].node.key);
1228
+ focusRow(key != null && rows.some((row) => row.node.key === key) ? key : roving.rovingKey.value ?? rows[0].node.key);
1194
1229
  return true;
1195
1230
  }
1196
1231
  onUnmounted(() => clearTimeout(typeaheadTimer));
@@ -1266,8 +1301,7 @@ var GrTree_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE_
1266
1301
  style: normalizeStyle(rowStyle(row)),
1267
1302
  onClick: ($event) => onRowActivate(row),
1268
1303
  onContextmenu: ($event) => onRowContextMenu($event, row.node),
1269
- onDrop: ($event) => onDrop($event, row.node),
1270
- onDragover: ($event) => onDragOver($event, row.node, $event.currentTarget),
1304
+ onDrop: _cache[1] || (_cache[1] = withModifiers(() => {}, ["prevent"])),
1271
1305
  onMouseenter: ($event) => onRowMouseEnter(row.node),
1272
1306
  onMouseleave: ($event) => onRowMouseLeave(row.node)
1273
1307
  }, [
@@ -1291,11 +1325,9 @@ var GrTree_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE_
1291
1325
  resolveNodeClass(unref(treeProps).dragHandleClass, row)
1292
1326
  ]]),
1293
1327
  "aria-label": dragLabel.value,
1294
- draggable: canDrag(row.node),
1328
+ "aria-disabled": canDrag(row.node) ? void 0 : "true",
1295
1329
  onClick: _cache[0] || (_cache[0] = withModifiers(() => {}, ["stop"])),
1296
- onMousedown: _cache[1] || (_cache[1] = withModifiers(() => {}, ["stop"])),
1297
- onDragstart: ($event) => onDragStart($event, row.node),
1298
- onDragend: onDragEnd
1330
+ onPointerdown: ($event) => onHandlePointerDown($event, row.node)
1299
1331
  }, [createElementVNode("span", { class: normalizeClass(["gr-tree__drag-icon", unref(treeProps).dragHandleIcon]) }, null, 2)], 42, _hoisted_4)) : createCommentVNode("", true),
1300
1332
  !row.isLeaf ? (openBlock(), createElementBlock("button", {
1301
1333
  key: 1,
@@ -1334,6 +1366,6 @@ var GrTree_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE_
1334
1366
  }), 128))], 44, _hoisted_1);
1335
1367
  };
1336
1368
  }
1337
- }), [["__scopeId", "data-v-0ed35387"]]);
1369
+ }), [["__scopeId", "data-v-d84c923c"]]);
1338
1370
  //#endregion
1339
1371
  export { GrTree_default as t };