@daisforge/ui 1.21.0 → 1.22.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 (275) hide show
  1. package/chunks/{FiltersActions-CDZSO0MM.mjs → FiltersActions-BJ5gD6Nx.mjs} +26 -24
  2. package/chunks/FiltersActions-Bg5wvHFG.cjs +1 -0
  3. package/chunks/{ListOfFilters-Bd8CZHDq.mjs → ListOfFilters-CfV2bs_4.mjs} +2 -2
  4. package/chunks/{ListOfFilters-BAPz0OY9.cjs → ListOfFilters-mqTsQbq_.cjs} +1 -1
  5. package/chunks/MassActions-BTrj9l-R.cjs +1 -0
  6. package/chunks/{MassActions-D5UwHcNG.mjs → MassActions-C6LY-g9r.mjs} +214 -213
  7. package/chunks/{Table-DYSssxRS.mjs → Table-tUWuA3Ri.mjs} +1113 -1112
  8. package/chunks/Table-vv1HTrxe.cjs +31 -0
  9. package/chunks/{TableCanvas-DDNRdQjN.mjs → TableCanvas-BX5aciu7.mjs} +2850 -2793
  10. package/chunks/TableCanvas-qnwh4c5g.cjs +30 -0
  11. package/chunks/{TableGlide-DAnTJtye.mjs → TableGlide-BLbbkn4C.mjs} +5669 -5326
  12. package/chunks/TableGlide-CZ2mkokV.cjs +1 -0
  13. package/components/Combobox/index.cjs +1 -1
  14. package/components/Combobox/index.mjs +1 -1
  15. package/components/ListOfFilters/index.cjs +1 -1
  16. package/components/ListOfFilters/index.mjs +1 -1
  17. package/components/MassActions/hooks/index.cjs +1 -1
  18. package/components/MassActions/hooks/index.mjs +1 -1
  19. package/components/MassActions/index.cjs +1 -1
  20. package/components/MassActions/index.mjs +1 -1
  21. package/components/MassActions/types.d.ts +1 -0
  22. package/components/Table/components/TableDropdown/index.cjs +1 -1
  23. package/components/Table/components/TableDropdown/index.mjs +1 -1
  24. package/components/Table/feature-collapse-table/index.cjs +1 -1
  25. package/components/Table/feature-collapse-table/index.mjs +1 -1
  26. package/components/Table/feature-column-control/ColumnsList/index.cjs +1 -1
  27. package/components/Table/feature-column-control/ColumnsList/index.mjs +1 -1
  28. package/components/Table/feature-column-control/index.cjs +1 -1
  29. package/components/Table/feature-column-control/index.mjs +1 -1
  30. package/components/Table/feature-columns-grouping/index.cjs +1 -1
  31. package/components/Table/feature-columns-grouping/index.mjs +1 -1
  32. package/components/Table/feature-context-menu/index.cjs +1 -1
  33. package/components/Table/feature-context-menu/index.mjs +1 -1
  34. package/components/Table/feature-edit/index.cjs +1 -1
  35. package/components/Table/feature-edit/index.mjs +1 -1
  36. package/components/Table/feature-filtering/combobox/index.cjs +1 -1
  37. package/components/Table/feature-filtering/combobox/index.mjs +1 -1
  38. package/components/Table/feature-filtering/filter-list-block/index.cjs +1 -1
  39. package/components/Table/feature-filtering/filter-list-block/index.mjs +1 -1
  40. package/components/Table/feature-filtering/header-filter-button/index.cjs +1 -1
  41. package/components/Table/feature-filtering/header-filter-button/index.mjs +1 -1
  42. package/components/Table/feature-filtering/index.cjs +1 -1
  43. package/components/Table/feature-filtering/index.mjs +1 -1
  44. package/components/Table/feature-filtering/sidebar-filter-block/index.cjs +1 -1
  45. package/components/Table/feature-filtering/sidebar-filter-block/index.mjs +1 -1
  46. package/components/Table/feature-infinity-scroll/index.cjs +1 -1
  47. package/components/Table/feature-infinity-scroll/index.mjs +1 -1
  48. package/components/Table/feature-key-text/index.cjs +1 -1
  49. package/components/Table/feature-key-text/index.mjs +1 -1
  50. package/components/Table/feature-pagination/index.cjs +1 -1
  51. package/components/Table/feature-pagination/index.mjs +1 -1
  52. package/components/Table/feature-right-sidebar/index.cjs +1 -1
  53. package/components/Table/feature-right-sidebar/index.mjs +1 -1
  54. package/components/Table/feature-row-detail/index.cjs +1 -1
  55. package/components/Table/feature-row-detail/index.mjs +1 -1
  56. package/components/Table/feature-row-instruments/index.cjs +1 -1
  57. package/components/Table/feature-row-instruments/index.mjs +1 -1
  58. package/components/Table/feature-row-size/index.cjs +1 -1
  59. package/components/Table/feature-row-size/index.mjs +1 -1
  60. package/components/Table/feature-rows-grouping/index.cjs +1 -1
  61. package/components/Table/feature-rows-grouping/index.mjs +1 -1
  62. package/components/Table/feature-searching/index.cjs +1 -1
  63. package/components/Table/feature-searching/index.mjs +1 -1
  64. package/components/Table/feature-select-row/index.cjs +1 -1
  65. package/components/Table/feature-select-row/index.mjs +1 -1
  66. package/components/Table/feature-sorting/index.cjs +1 -1
  67. package/components/Table/feature-sorting/index.mjs +1 -1
  68. package/components/Table/feature-table-settings/index.cjs +1 -1
  69. package/components/Table/feature-table-settings/index.mjs +1 -1
  70. package/components/Table/feature-tree/index.cjs +1 -1
  71. package/components/Table/feature-tree/index.mjs +1 -1
  72. package/components/Table/index.cjs +1 -1
  73. package/components/Table/index.mjs +1 -1
  74. package/components/Table/renders/formatCell/index.cjs +1 -1
  75. package/components/Table/renders/formatCell/index.mjs +1 -1
  76. package/components/Table/styles/index.cjs +1 -1
  77. package/components/Table/styles/index.mjs +1 -1
  78. package/components/Table/table-hooks/index.cjs +1 -1
  79. package/components/Table/table-hooks/index.mjs +1 -1
  80. package/components/Table/types/index.cjs +1 -1
  81. package/components/Table/types/index.mjs +1 -1
  82. package/components/Table/types/table-config.type.d.ts +1 -0
  83. package/components/Table/utils/index.cjs +1 -1
  84. package/components/Table/utils/index.mjs +1 -1
  85. package/components/Table/widgets/control-block/index.cjs +1 -1
  86. package/components/Table/widgets/control-block/index.mjs +1 -1
  87. package/components/Table/widgets/control-block/right-side/index.cjs +1 -1
  88. package/components/Table/widgets/control-block/right-side/index.mjs +1 -1
  89. package/components/Table/widgets/index.cjs +1 -1
  90. package/components/Table/widgets/index.mjs +1 -1
  91. package/components/Table/widgets/mass-actions/index.cjs +1 -1
  92. package/components/Table/widgets/mass-actions/index.mjs +1 -1
  93. package/components/TableCanvas/TableGlideInstance/adapters/column/index.cjs +1 -1
  94. package/components/TableCanvas/TableGlideInstance/adapters/column/index.mjs +1 -1
  95. package/components/TableCanvas/TableGlideInstance/adapters/index.cjs +1 -1
  96. package/components/TableCanvas/TableGlideInstance/adapters/index.mjs +1 -1
  97. package/components/TableCanvas/TableGlideInstance/index.cjs +1 -1
  98. package/components/TableCanvas/TableGlideInstance/index.mjs +2 -2
  99. package/components/TableCanvas/TableGlideInstance/reexports-for-external.d.ts +4 -1
  100. package/components/TableCanvas/TableGlideInstance/type.d.ts +1 -1
  101. package/components/TableCanvas/TableGlideInstance/utils/column/index.cjs +1 -1
  102. package/components/TableCanvas/TableGlideInstance/utils/column/index.mjs +1 -1
  103. package/components/TableCanvas/TableGlideInstance/utils/index.cjs +1 -1
  104. package/components/TableCanvas/TableGlideInstance/utils/index.mjs +1 -1
  105. package/components/TableCanvas/components/SplitIconButton/index.cjs +1 -1
  106. package/components/TableCanvas/components/SplitIconButton/index.mjs +1 -1
  107. package/components/TableCanvas/components/TableDropdown/index.cjs +1 -1
  108. package/components/TableCanvas/components/TableDropdown/index.mjs +1 -1
  109. package/components/TableCanvas/feature-cell-transfer/index.cjs +1 -1
  110. package/components/TableCanvas/feature-cell-transfer/index.mjs +1 -1
  111. package/components/TableCanvas/feature-collapse-table/index.cjs +1 -1
  112. package/components/TableCanvas/feature-collapse-table/index.mjs +1 -1
  113. package/components/TableCanvas/feature-column-control/ColumnsList/index.cjs +1 -1
  114. package/components/TableCanvas/feature-column-control/ColumnsList/index.mjs +1 -1
  115. package/components/TableCanvas/feature-column-control/index.cjs +1 -1
  116. package/components/TableCanvas/feature-column-control/index.mjs +1 -1
  117. package/components/TableCanvas/feature-columns-grouping/index.cjs +1 -1
  118. package/components/TableCanvas/feature-columns-grouping/index.mjs +1 -1
  119. package/components/TableCanvas/feature-content-state/index.cjs +1 -1
  120. package/components/TableCanvas/feature-content-state/index.mjs +1 -1
  121. package/components/TableCanvas/feature-context-menu/index.cjs +1 -1
  122. package/components/TableCanvas/feature-context-menu/index.mjs +1 -1
  123. package/components/TableCanvas/feature-edit/index.cjs +1 -1
  124. package/components/TableCanvas/feature-edit/index.mjs +1 -1
  125. package/components/TableCanvas/feature-edit/types.d.ts +1 -1
  126. package/components/TableCanvas/feature-filtering/combobox/index.cjs +1 -1
  127. package/components/TableCanvas/feature-filtering/combobox/index.mjs +1 -1
  128. package/components/TableCanvas/feature-filtering/filter-list-block/index.cjs +1 -1
  129. package/components/TableCanvas/feature-filtering/filter-list-block/index.mjs +1 -1
  130. package/components/TableCanvas/feature-filtering/header-filter-button/index.cjs +1 -1
  131. package/components/TableCanvas/feature-filtering/header-filter-button/index.mjs +1 -1
  132. package/components/TableCanvas/feature-filtering/index.cjs +1 -1
  133. package/components/TableCanvas/feature-filtering/index.mjs +1 -1
  134. package/components/TableCanvas/feature-filtering/sidebar-filter-block/index.cjs +1 -1
  135. package/components/TableCanvas/feature-filtering/sidebar-filter-block/index.mjs +1 -1
  136. package/components/TableCanvas/feature-infinity-scroll/index.cjs +1 -1
  137. package/components/TableCanvas/feature-infinity-scroll/index.mjs +1 -1
  138. package/components/TableCanvas/feature-key-text/index.cjs +1 -1
  139. package/components/TableCanvas/feature-key-text/index.mjs +1 -1
  140. package/components/TableCanvas/feature-notifications/index.cjs +1 -1
  141. package/components/TableCanvas/feature-notifications/index.mjs +1 -1
  142. package/components/TableCanvas/feature-pagination/index.cjs +1 -1
  143. package/components/TableCanvas/feature-pagination/index.mjs +1 -1
  144. package/components/TableCanvas/feature-popover-table/context/index.cjs +1 -1
  145. package/components/TableCanvas/feature-popover-table/context/index.mjs +1 -1
  146. package/components/TableCanvas/feature-popover-table/hooks/index.cjs +1 -1
  147. package/components/TableCanvas/feature-popover-table/hooks/index.mjs +1 -1
  148. package/components/TableCanvas/feature-popover-table/index.cjs +1 -1
  149. package/components/TableCanvas/feature-popover-table/index.mjs +1 -1
  150. package/components/TableCanvas/feature-popover-table/utils/index.cjs +1 -1
  151. package/components/TableCanvas/feature-popover-table/utils/index.mjs +1 -1
  152. package/components/TableCanvas/feature-right-sidebar/index.cjs +1 -1
  153. package/components/TableCanvas/feature-right-sidebar/index.mjs +1 -1
  154. package/components/TableCanvas/feature-row-detail/index.cjs +1 -1
  155. package/components/TableCanvas/feature-row-detail/index.mjs +1 -1
  156. package/components/TableCanvas/feature-row-instruments/index.cjs +1 -1
  157. package/components/TableCanvas/feature-row-instruments/index.mjs +1 -1
  158. package/components/TableCanvas/feature-row-markers/index.cjs +1 -1
  159. package/components/TableCanvas/feature-row-markers/index.mjs +1 -1
  160. package/components/TableCanvas/feature-row-size/index.cjs +1 -1
  161. package/components/TableCanvas/feature-row-size/index.mjs +1 -1
  162. package/components/TableCanvas/feature-rows-grouping/index.cjs +1 -1
  163. package/components/TableCanvas/feature-rows-grouping/index.mjs +1 -1
  164. package/components/TableCanvas/feature-searching/index.cjs +1 -1
  165. package/components/TableCanvas/feature-searching/index.mjs +1 -1
  166. package/components/TableCanvas/feature-select-row/index.cjs +1 -1
  167. package/components/TableCanvas/feature-select-row/index.mjs +1 -1
  168. package/components/TableCanvas/feature-select-row/types.d.ts +1 -0
  169. package/components/TableCanvas/feature-select-row/useSelectRow.d.ts +1 -0
  170. package/components/TableCanvas/feature-sorting/index.cjs +1 -1
  171. package/components/TableCanvas/feature-sorting/index.mjs +1 -1
  172. package/components/TableCanvas/feature-table-settings/index.cjs +1 -1
  173. package/components/TableCanvas/feature-table-settings/index.mjs +1 -1
  174. package/components/TableCanvas/feature-tooltip/index.cjs +1 -1
  175. package/components/TableCanvas/feature-tooltip/index.mjs +1 -1
  176. package/components/TableCanvas/feature-tooltip/utils/index.cjs +1 -1
  177. package/components/TableCanvas/feature-tooltip/utils/index.mjs +1 -1
  178. package/components/TableCanvas/feature-tree/index.cjs +1 -1
  179. package/components/TableCanvas/feature-tree/index.mjs +1 -1
  180. package/components/TableCanvas/index.cjs +1 -1
  181. package/components/TableCanvas/index.mjs +2 -2
  182. package/components/TableCanvas/renders/formatCell/index.cjs +1 -1
  183. package/components/TableCanvas/renders/formatCell/index.mjs +1 -1
  184. package/components/TableCanvas/renders/renderEditCell.d.ts +1 -1
  185. package/components/TableCanvas/styles/index.cjs +1 -1
  186. package/components/TableCanvas/styles/index.mjs +1 -1
  187. package/components/TableCanvas/table-hooks/index.cjs +1 -1
  188. package/components/TableCanvas/table-hooks/index.mjs +1 -1
  189. package/components/TableCanvas/types/index.cjs +1 -1
  190. package/components/TableCanvas/types/index.mjs +1 -1
  191. package/components/TableCanvas/types/table-config.type.d.ts +1 -0
  192. package/components/TableCanvas/utils/index.cjs +1 -1
  193. package/components/TableCanvas/utils/index.mjs +1 -1
  194. package/components/TableCanvas/widgets/control-block/compression/index.cjs +1 -1
  195. package/components/TableCanvas/widgets/control-block/compression/index.mjs +1 -1
  196. package/components/TableCanvas/widgets/control-block/index.cjs +1 -1
  197. package/components/TableCanvas/widgets/control-block/index.mjs +1 -1
  198. package/components/TableCanvas/widgets/control-block/right-side/index.cjs +1 -1
  199. package/components/TableCanvas/widgets/control-block/right-side/index.mjs +1 -1
  200. package/components/TableCanvas/widgets/index.cjs +1 -1
  201. package/components/TableCanvas/widgets/index.mjs +1 -1
  202. package/components/TableCanvas/widgets/mass-actions/hooks/index.cjs +1 -1
  203. package/components/TableCanvas/widgets/mass-actions/hooks/index.mjs +1 -1
  204. package/components/TableCanvas/widgets/mass-actions/index.cjs +1 -1
  205. package/components/TableCanvas/widgets/mass-actions/index.mjs +1 -1
  206. package/components/TableContract/index.cjs +1 -1
  207. package/components/TableContract/index.mjs +1 -1
  208. package/components/TableGlide/cellRenderer.d.ts +2 -1
  209. package/components/TableGlide/hooks/selection/index.cjs +1 -1
  210. package/components/TableGlide/hooks/selection/index.mjs +1 -1
  211. package/components/TableGlide/index.cjs +1 -1
  212. package/components/TableGlide/index.mjs +92 -89
  213. package/components/TableGlide/lib/canvas/cells/CellCanvasRoot.d.ts +2 -1
  214. package/components/TableGlide/lib/canvas/cells/buttons/index.cjs +1 -1
  215. package/components/TableGlide/lib/canvas/cells/buttons/index.mjs +1 -1
  216. package/components/TableGlide/lib/canvas/cells/iconSprites/index.cjs +1 -1
  217. package/components/TableGlide/lib/canvas/cells/iconSprites/index.mjs +1 -1
  218. package/components/TableGlide/lib/canvas/cells/index.cjs +1 -1
  219. package/components/TableGlide/lib/canvas/cells/index.mjs +19 -19
  220. package/components/TableGlide/lib/canvas/cells/renderer/index.cjs +1 -1
  221. package/components/TableGlide/lib/canvas/cells/renderer/index.mjs +1 -1
  222. package/components/TableGlide/lib/canvas/cells/renderer/types.d.ts +4 -2
  223. package/components/TableGlide/lib/canvas/cells/types.d.ts +3 -1
  224. package/components/TableGlide/lib/canvas/components/index.d.ts +31 -4
  225. package/components/TableGlide/lib/canvas/core/CanvasImageResources.d.ts +7 -0
  226. package/components/TableGlide/lib/canvas/core/CanvasImageTransitions.d.ts +11 -0
  227. package/components/TableGlide/lib/canvas/core/DrawBatcher.d.ts +5 -0
  228. package/components/TableGlide/lib/canvas/core/helpers/index.cjs +1 -1
  229. package/components/TableGlide/lib/canvas/core/helpers/index.mjs +1 -1
  230. package/components/TableGlide/lib/canvas/core/index.cjs +1 -1
  231. package/components/TableGlide/lib/canvas/core/index.mjs +1 -1
  232. package/components/TableGlide/lib/canvas/hooks/index.cjs +1 -1
  233. package/components/TableGlide/lib/canvas/hooks/index.mjs +4 -4
  234. package/components/TableGlide/lib/canvas/index.cjs +1 -1
  235. package/components/TableGlide/lib/canvas/index.d.ts +7 -7
  236. package/components/TableGlide/lib/canvas/index.mjs +70 -67
  237. package/components/TableGlide/lib/canvas/miniflex/index.cjs +1 -1
  238. package/components/TableGlide/lib/canvas/miniflex/index.mjs +1 -1
  239. package/components/TableGlide/lib/canvas/primitives/CanvasAvatar.d.ts +58 -0
  240. package/components/TableGlide/lib/canvas/primitives/CanvasAvatarGroup.d.ts +45 -0
  241. package/components/TableGlide/lib/canvas/primitives/CanvasImage.d.ts +17 -0
  242. package/components/TableGlide/lib/canvas/primitives/avatar/geometry.d.ts +6 -0
  243. package/components/TableGlide/lib/canvas/primitives/image/image.d.ts +20 -0
  244. package/components/TableGlide/lib/canvas/primitives/index.cjs +1 -1
  245. package/components/TableGlide/lib/canvas/primitives/index.d.ts +11 -4
  246. package/components/TableGlide/lib/canvas/primitives/index.mjs +14 -11
  247. package/components/TableGlide/lib/canvas/utils/index.cjs +1 -1
  248. package/components/TableGlide/lib/canvas/utils/index.mjs +1 -1
  249. package/components/TableGlide/theming/index.cjs +1 -1
  250. package/components/TableGlide/theming/index.mjs +1 -1
  251. package/components/TableGlide/tokens.d.ts +3 -0
  252. package/components/TourWidget/TourWidget.palette.d.ts +36 -0
  253. package/components/TourWidget/TourWidget.styled.d.ts +4 -0
  254. package/components/TourWidget/TourWidget.tokens.d.ts +52 -0
  255. package/components/TourWidget/hooks/useIsDarkTheme.d.ts +1 -0
  256. package/components/TourWidget/index.cjs +22 -22
  257. package/components/TourWidget/index.d.ts +1 -0
  258. package/components/TourWidget/index.mjs +269 -179
  259. package/formComponents/FormCombobox/index.cjs +1 -1
  260. package/formComponents/FormCombobox/index.mjs +1 -1
  261. package/formComponents/FormSwitch/index.cjs +1 -1
  262. package/formComponents/FormSwitch/index.mjs +1 -1
  263. package/index.cjs +1 -1
  264. package/index.mjs +1609 -1608
  265. package/layouts/FiltersActions/hooks/index.cjs +1 -1
  266. package/layouts/FiltersActions/hooks/index.mjs +1 -1
  267. package/layouts/FiltersActions/index.cjs +1 -1
  268. package/layouts/FiltersActions/index.mjs +1 -1
  269. package/mcp-data/component-index.json +848 -254
  270. package/package.json +2 -2
  271. package/chunks/FiltersActions-CVtgAJnC.cjs +0 -1
  272. package/chunks/MassActions-C08IgW4a.cjs +0 -1
  273. package/chunks/Table-CdaMPDkg.cjs +0 -31
  274. package/chunks/TableCanvas-DPHSYfH3.cjs +0 -30
  275. package/chunks/TableGlide-am_w97mF.cjs +0 -1
@@ -1,6 +1,6 @@
1
1
  {
2
- "generatedAt": "2026-09-25T13:25:33.162Z",
3
- "libVersion": "1.21.0",
2
+ "generatedAt": "2026-10-05T14:44:55.582Z",
3
+ "libVersion": "1.22.0",
4
4
  "components": {
5
5
  "Accordion": {
6
6
  "name": "Accordion",
@@ -16110,6 +16110,12 @@
16110
16110
  "required": false,
16111
16111
  "description": "Indeterminate состояние чекбокса"
16112
16112
  },
16113
+ {
16114
+ "name": "maxCount",
16115
+ "type": "number | undefined",
16116
+ "required": false,
16117
+ "description": "Максимальное отображаемое число. Если selectedCount больше — показывается «N+»\n(например, при maxCount={99} и selectedCount={5000} отобразится «99+»)."
16118
+ },
16113
16119
  {
16114
16120
  "name": "onCheckboxChange",
16115
16121
  "type": "((event: React.ChangeEvent<HTMLInputElement>) => void) | undefined",
@@ -16135,7 +16141,7 @@
16135
16141
  "панель выбора строк"
16136
16142
  ],
16137
16143
  "docs": "# MassActions\n\nБазовый адаптивный компонент панели массовых действий. Независим от таблицы - может использоваться с любым контейнером. Поддерживает автоматическую компрессию кнопок при нехватке места, сворачивание/разворачивание, удобное позиционирование и другие возможности.\n\n## Ключевые особенности\n\n- Автоматическая компрессия кнопок при нехватке места\n- Accent-кнопки всегда остаются видимыми\n- Автоцентрирование относительно контейнера\n- Поддержка двух типов кнопок: Button и LinkButton\n- Размеры кнопок подбираются автоматически — передавать `size` кнопкам не нужно (если задан, используется как есть)\n\n## Compound-компоненты\n\n### Counter\n\n`MassActions.Counter` — компонент счетчика выбранных элементов. Может отображать чекбокс, текст и анимированный badge с количеством.\n\n#### Логика работы чекбокса\n\nЧекбокс в Counter имеет три состояния:\n\n- **checked = true** — когда все элементы выбраны (`selectedCount === totalCount`)\n- **indeterminate = true** — когда выбрано частично (`0 < selectedCount < totalCount`)\n- **checked = false, indeterminate = false** — когда ничего не выбрано (`selectedCount === 0`)\n\n**Важно:** Состояние чекбокса должно вычисляться на основе `selectedCount` и общего количества элементов, а не храниться в отдельном состоянии. Это обеспечивает синхронизацию между ручным выделением элементов и состоянием чекбокса.\n\n```tsx\n// Правильная реализация логики чекбокса\nconst items = [...]; // массив всех элементов\nconst [selectedItems, setSelectedItems] = useState<Set<number>>(new Set());\n\n// Вычисляем состояние на основе selectedItems\nconst allSelected = selectedItems.size === items.length;\nconst someSelected = selectedItems.size > 0 && selectedItems.size < items.length;\nconst checked = allSelected;\nconst indeterminate = someSelected;\n\nconst handleCheckboxChange = (isChecked: boolean) => {\n if (isChecked) {\n // Выделяем все элементы\n setSelectedItems(new Set(items.map((item) => item.id)));\n } else {\n // Снимаем выделение со всех элементов\n setSelectedItems(new Set());\n }\n};\n\n<MassActions.Counter\n selectedCount={selectedItems.size}\n showCheckbox\n checked={checked}\n indeterminate={indeterminate}\n onCheckboxChange={(e) => handleCheckboxChange(e.target.checked)}\n/>\n```\n\n## MassActionsStatic\n\nСтатический компонент панели действий без адаптивной компрессии. Предназначен для использования в местах, где не требуется автоматическое скрытие кнопок (например, в боковых панелях LeftPanel).\n\nВ отличие от `MassActions`, `MassActionsStatic` не поддерживает компрессию кнопок и позиционирование относительно контейнера. Поддерживает блочное отображение через проп `position` (`static` или `relative`), что позволяет использовать компонент как обычный блок без абсолютного позиционирования.\n\n## Особенности\n\n### Компрессия кнопок\n\nПри нехватке места кнопки автоматически скрываются в дропдауне скрытых действий:\n\n1. Все accent-кнопки всегда видимы\n2. Обычные кнопки добавляются по порядку, пока помещаются\n3. Остальные кнопки идут в дропдаун скрытых действий\n\n### Позиционирование\n\nПанель автоматически центрируется относительно переданного контейнера (`containerRef`). В большинстве сценариев достаточно просто передать корректный контейнер, дополнительная настройка через `sidebarConfig` нужна только для продвинутых кейсов.\n\n### Размеры кнопок\n\nРазмеры кнопок и дропдаунов панель подбирает сама — по режиму отображения. В обычном режиме кнопки рендерятся размером `s`, в компактном (узкий вьюпорт, до 1280px включительно) — `xs`. Передавать `size` кнопкам отдельно **не нужно**. Если `size` всё же задан — он используется как есть.\n\n## Типы кнопок\n\nКаждый элемент массива `buttons` — это либо обычная кнопка (`type: 'button'`, компонент `Button`), либо кнопка-ссылка (`type: 'linkButton'`, компонент `LinkButton`). Кнопки с `view: 'accent'` никогда не скрываются в дропдауне скрытых действий.\n\n```tsx\nbuttons={[\n {\n type: 'button',\n text: 'Действие',\n view: 'secondary', // 'accent' / 'critical' / 'primary' и т.д.\n onClick: () => {},\n },\n {\n type: 'linkButton',\n text: 'Ссылка-действие',\n view: 'linkSecondary', // link-стили: 'linkAccent' / 'linkDefault' и т.д.\n onClick: () => {},\n },\n]}\n```\n\n## Disabled-состояние\n\nЕсли у кнопки `disabled: true`, можно передать `disabledTooltipProps` — подсказку, которая покажется при наведении на неактивную кнопку:\n\n```tsx\n{\n type: 'button',\n text: 'Действие',\n view: 'secondary',\n disabled: true,\n disabledTooltipProps: {\n text: 'Выберите элементы для выполнения действия',\n },\n onClick: () => {},\n}\n```\n\n**Важно:** disabled-кнопка остаётся неактивной и после ухода в дропдаун скрытых действий — `disabled` пробрасывается на пункт меню. Подсказка `disabledTooltipProps` при этом показывается только у кнопок на самой панели, в меню её нет.\n\n## Dropdown в кнопках\n\nКнопка может открывать вложенный dropdown:\n\n```tsx\n{\n type: 'button',\n text: 'Действие с меню',\n view: 'secondary',\n dropdown: {\n items: [\n { label: 'Опция 1', value: '1' },\n { label: 'Опция 2', value: '2' },\n ],\n onItemSelect: (item) => {},\n },\n}\n```\n\n> Подробнее о типах и пропсах — [MassActions API](?path=/docs/локальные-компоненты-massactions-api--docs)",
16138
- "apiDocs": "# MassActions API\n\n## MassActionsProps\n\n```typescript\ntype MassActionsProps = {\n /**\n * Ref на контейнер относительно которого будет позиционироваться панель\n * Может быть RefObject, MutableRefObject или функция возвращающая элемент\n */\n containerRef:\n | RefObject<HTMLElement>\n | MutableRefObject<HTMLElement | null>\n | (() => HTMLElement | null);\n\n /**\n * Левая секция панели (чекбокс + счетчик или кастомный контент)\n */\n leftSection: ReactNode;\n\n /**\n * Средняя секция (например, кнопка \"Сбросить всё\")\n * Опционально - для standalone версии не используется\n */\n middleSection?: ReactNode;\n\n /**\n * Кнопки действий\n */\n buttons?: MassActionsButtonProps[];\n\n /**\n * Конфигурация сайдбара (если есть)\n */\n sidebarConfig?: MassActionsSidebarConfig;\n\n /**\n * Есть ли какая-то фича в сайдбаре (влияет на расчет ширины)\n */\n isHaveSomeFeatureInSidebar?: boolean;\n\n /**\n * Конфигурация dropdown для скрытых кнопок\n */\n collapsedDropdownProps?: TableDropdownConfigProps;\n\n /**\n * Количество выбранных элементов\n * Используется для внутренней логики видимости панели (если show не указан)\n * Если selectedCount === 0 и show не указан, панель не отображается\n */\n selectedCount: number;\n\n /**\n * Явный контроль видимости панели\n * Если указан, имеет приоритет над автоматической логикой на основе selectedCount\n * Позволяет показывать панель даже при selectedCount === 0\n * По умолчанию: undefined (используется логика selectedCount > 0)\n */\n show?: boolean;\n\n /**\n * Использовать TableDropdown (для таблиц) вместо обычного Dropdown\n * По умолчанию false (используется обычный Dropdown)\n */\n useTableDropdown?: boolean;\n /**\n * Включить отладочное логирование в консоль\n * Полезно для отладки проблем с компрессией и позиционированием\n * По умолчанию false\n */\n enableDebugLogs?: boolean;\n /**\n * Отступ снизу от контейнера (в пикселях)\n * По умолчанию: 16px для standalone, 24px для таблицы\n */\n bottom?: number;\n\n /**\n * Минимальный отступ панели от краев контейнера (в пикселях)\n * Используется для:\n * - CSS padding панели (симметрично: minPadding слева и справа)\n * - Расчетов компрессии (максимальная ширина панели с учетом отступов)\n * - Позиционирования (гарантирует минимальный отступ от левого края контейнера)\n * По умолчанию: 16px для standalone, 24px для таблицы\n */\n minPadding?: number;\n\n /**\n * Статический размер панели (для использования ВНУТРИ таблиц).\n * Если задан — перекрывает viewport-логику (медиазапрос 1280 не используется):\n * `m`/`s` = обычный размер (кнопки `s`), `xs` = уменьшенный (кнопки `xxs`, «ещё» `xs`, счётчик Body XS, свои паддинги).\n * НЕ задавать для standalone — там компактность определяется по ширине вьюпорта (`down('xl')`).\n */\n size?: MassActionsSize;\n};\n```\n\n## MassActionsButtonProps\n\n```typescript\ntype MassActionsButtonPropsButton = DataAttributes &\n Partial<ButtonCompProps> & {\n type: 'button';\n view?: ButtonCompProps['view'];\n /**\n * Dropdown для кнопки.\n * Используется универсальный DropdownProps, который работает и с обычным Dropdown, и с TableDropdown\n */\n dropdown?: DropdownProps & { $css?: CSSObject };\n disabledTooltipProps?: TooltipProps;\n };\n```\n\n## Compound types\n\n### MassActions.Counter\n\n```typescript\ntype MassActionsCounterProps = {\n /** Количество выбранных элементов */\n selectedCount: number;\n /** Текст метки (по умолчанию \"Выбрано\") */\n label?: string;\n /** Показывать ли чекбокс */\n showCheckbox?: boolean;\n /** Состояние чекбокса */\n checked?: boolean;\n /** Indeterminate состояние чекбокса */\n indeterminate?: boolean;\n /** Колбэк при изменении чекбокса */\n onCheckboxChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;\n /** Кастомный className */\n className?: string;\n};\n```\n\n## MassActionsStatic\n\n```typescript\ntype MassActionsStaticProps = {\n children: ReactNode;\n className?: string;\n style?: CSSProperties;\n /**\n * Позиционирование компонента\n * - 'absolute' - абсолютное позиционирование (по умолчанию)\n * - 'static' - обычный блок без абсолютного позиционирования\n * - 'relative' - относительное позиционирование\n */\n position?: 'absolute' | 'static' | 'relative';\n /**\n * Явный контроль видимости компонента\n * Если не указан, компонент всегда виден\n * Если указан, компонент отображается только при show === true\n */\n show?: boolean;\n /**\n * Включить/отключить анимацию появления/исчезновения\n * @default true\n */\n animate?: boolean;\n};\n```",
16144
+ "apiDocs": "# MassActions API\n\n## MassActionsProps\n\n```typescript\ntype MassActionsProps = {\n /**\n * Ref на контейнер относительно которого будет позиционироваться панель\n * Может быть RefObject, MutableRefObject или функция возвращающая элемент\n */\n containerRef:\n | RefObject<HTMLElement>\n | MutableRefObject<HTMLElement | null>\n | (() => HTMLElement | null);\n\n /**\n * Левая секция панели (чекбокс + счетчик или кастомный контент)\n */\n leftSection: ReactNode;\n\n /**\n * Средняя секция (например, кнопка \"Сбросить всё\")\n * Опционально - для standalone версии не используется\n */\n middleSection?: ReactNode;\n\n /**\n * Кнопки действий\n */\n buttons?: MassActionsButtonProps[];\n\n /**\n * Конфигурация сайдбара (если есть)\n */\n sidebarConfig?: MassActionsSidebarConfig;\n\n /**\n * Есть ли какая-то фича в сайдбаре (влияет на расчет ширины)\n */\n isHaveSomeFeatureInSidebar?: boolean;\n\n /**\n * Конфигурация dropdown для скрытых кнопок\n */\n collapsedDropdownProps?: TableDropdownConfigProps;\n\n /**\n * Количество выбранных элементов\n * Используется для внутренней логики видимости панели (если show не указан)\n * Если selectedCount === 0 и show не указан, панель не отображается\n */\n selectedCount: number;\n\n /**\n * Явный контроль видимости панели\n * Если указан, имеет приоритет над автоматической логикой на основе selectedCount\n * Позволяет показывать панель даже при selectedCount === 0\n * По умолчанию: undefined (используется логика selectedCount > 0)\n */\n show?: boolean;\n\n /**\n * Использовать TableDropdown (для таблиц) вместо обычного Dropdown\n * По умолчанию false (используется обычный Dropdown)\n */\n useTableDropdown?: boolean;\n /**\n * Включить отладочное логирование в консоль\n * Полезно для отладки проблем с компрессией и позиционированием\n * По умолчанию false\n */\n enableDebugLogs?: boolean;\n /**\n * Отступ снизу от контейнера (в пикселях)\n * По умолчанию: 16px для standalone, 24px для таблицы\n */\n bottom?: number;\n\n /**\n * Минимальный отступ панели от краев контейнера (в пикселях)\n * Используется для:\n * - CSS padding панели (симметрично: minPadding слева и справа)\n * - Расчетов компрессии (максимальная ширина панели с учетом отступов)\n * - Позиционирования (гарантирует минимальный отступ от левого края контейнера)\n * По умолчанию: 16px для standalone, 24px для таблицы\n */\n minPadding?: number;\n\n /**\n * Статический размер панели (для использования ВНУТРИ таблиц).\n * Если задан — перекрывает viewport-логику (медиазапрос 1280 не используется):\n * `m`/`s` = обычный размер (кнопки `s`), `xs` = уменьшенный (кнопки `xxs`, «ещё» `xs`, счётчик Body XS, свои паддинги).\n * НЕ задавать для standalone — там компактность определяется по ширине вьюпорта (`down('xl')`).\n */\n size?: MassActionsSize;\n};\n```\n\n## MassActionsButtonProps\n\n```typescript\ntype MassActionsButtonPropsButton = DataAttributes &\n Partial<ButtonCompProps> & {\n type: 'button';\n view?: ButtonCompProps['view'];\n /**\n * Dropdown для кнопки.\n * Используется универсальный DropdownProps, который работает и с обычным Dropdown, и с TableDropdown\n */\n dropdown?: DropdownProps & { $css?: CSSObject };\n disabledTooltipProps?: TooltipProps;\n };\n```\n\n## Compound types\n\n### MassActions.Counter\n\n```typescript\ntype MassActionsCounterProps = {\n /** Количество выбранных элементов */\n selectedCount: number;\n /**\n * Максимальное отображаемое число. Если selectedCount больше — показывается «N+»\n * (например, при maxCount={99} и selectedCount={5000} отобразится «99+»).\n */\n maxCount?: number;\n /** Текст метки (по умолчанию \"Выбрано\") */\n label?: string;\n /** Показывать ли чекбокс */\n showCheckbox?: boolean;\n /** Состояние чекбокса */\n checked?: boolean;\n /** Indeterminate состояние чекбокса */\n indeterminate?: boolean;\n /** Колбэк при изменении чекбокса */\n onCheckboxChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;\n /** Кастомный className */\n className?: string;\n};\n```\n\n## MassActionsStatic\n\n```typescript\ntype MassActionsStaticProps = {\n children: ReactNode;\n className?: string;\n style?: CSSProperties;\n /**\n * Позиционирование компонента\n * - 'absolute' - абсолютное позиционирование (по умолчанию)\n * - 'static' - обычный блок без абсолютного позиционирования\n * - 'relative' - относительное позиционирование\n */\n position?: 'absolute' | 'static' | 'relative';\n /**\n * Явный контроль видимости компонента\n * Если не указан, компонент всегда виден\n * Если указан, компонент отображается только при show === true\n */\n show?: boolean;\n /**\n * Включить/отключить анимацию появления/исчезновения\n * @default true\n */\n animate?: boolean;\n};\n```",
16139
16145
  "curatedStories": [
16140
16146
  {
16141
16147
  "exportName": "Standalone",
@@ -16166,6 +16172,12 @@
16166
16172
  "displayName": "1280 Адаптив",
16167
16173
  "type": "full-code",
16168
16174
  "code": "import { useRef, useState } from 'react';\nimport { MassActions } from '@ui-kit/components/MassActions';\n\n${getFuncAsString(\n 'packages/storybook/src/stories/MassActions/MassActions.stories.tsx',\n 'StandaloneExample',\n)}"
16175
+ },
16176
+ {
16177
+ "exportName": "CounterMaxCount",
16178
+ "displayName": "Ограничение счётчика (99+)",
16179
+ "type": "full-code",
16180
+ "code": "import { useRef, useState } from 'react';\nimport { MassActions } from '@ui-kit/components/MassActions';\n\n${getFuncAsString(\n 'packages/storybook/src/stories/MassActions/MassActions.stories.tsx',\n 'CounterMaxCountExample',\n)}"
16169
16181
  }
16170
16182
  ],
16171
16183
  "hasCuratedMeta": true,
@@ -16308,6 +16320,12 @@
16308
16320
  "required": false,
16309
16321
  "description": "Indeterminate состояние чекбокса"
16310
16322
  },
16323
+ {
16324
+ "name": "maxCount",
16325
+ "type": "number | undefined",
16326
+ "required": false,
16327
+ "description": "Максимальное отображаемое число. Если selectedCount больше — показывается «N+»\n(например, при maxCount={99} и selectedCount={5000} отобразится «99+»)."
16328
+ },
16311
16329
  {
16312
16330
  "name": "onCheckboxChange",
16313
16331
  "type": "((event: React.ChangeEvent<HTMLInputElement>) => void) | undefined",
@@ -16345,14 +16363,14 @@
16345
16363
  "exportName": "Usage1",
16346
16364
  "displayName": "Использование в MassActions.stories.tsx",
16347
16365
  "type": "usage",
16348
- "code": "<MassActions.Counter\n selectedCount={selectedItems.size}\n showCheckbox\n checked={checked}\n indeterminate={indeterminate}\n onCheckboxChange={(e: React.ChangeEvent<HTMLInputElement>) =>\n handleCheckboxChange(e.target.checked)\n }\n />",
16366
+ "code": "<MassActions.Counter\n selectedCount={selectedItems.size}\n maxCount={99}\n showCheckbox\n checked={allSelected}\n indeterminate={someSelected}\n onCheckboxChange={(e: React.ChangeEvent<HTMLInputElement>) =>\n handleCheckboxChange(e.target.checked)\n }\n />",
16349
16367
  "sourceFile": "packages/storybook/src/stories/MassActions/MassActions.stories.tsx"
16350
16368
  },
16351
16369
  {
16352
16370
  "exportName": "Usage2",
16353
16371
  "displayName": "Использование в MassActions.stories.tsx",
16354
16372
  "type": "usage",
16355
- "code": "<MassActions.Counter\n selectedCount={selectedItems.size}\n showCheckbox\n checked={checked}\n indeterminate={indeterminate}\n onCheckboxChange={(e: React.ChangeEvent<HTMLInputElement>) =>\n handleCheckboxChange(e.target.checked)\n }\n />",
16373
+ "code": "<MassActions.Counter\n selectedCount={selectedItems.size}\n showCheckbox\n checked={checked}\n indeterminate={indeterminate}\n onCheckboxChange={(e: React.ChangeEvent<HTMLInputElement>) =>\n handleCheckboxChange(e.target.checked)\n }\n />",
16356
16374
  "sourceFile": "packages/storybook/src/stories/MassActions/MassActions.stories.tsx"
16357
16375
  }
16358
16376
  ]
@@ -27817,7 +27835,14 @@
27817
27835
  "minimalUsage": "<Slider max={0} min={0} />",
27818
27836
  "examples": [
27819
27837
  {
27820
- "exportName": "Usage",
27838
+ "exportName": "Usage1",
27839
+ "displayName": "Использование в TableCanvas.headerRowHeight.stories.tsx",
27840
+ "type": "usage",
27841
+ "code": "<Slider\n value={headerRowHeight}\n onChange={setHeaderRowHeight}\n min={24}\n max={96}\n step={1}\n />",
27842
+ "sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.HeaderRowHeight/TableCanvas.headerRowHeight.stories.tsx"
27843
+ },
27844
+ {
27845
+ "exportName": "Usage2",
27821
27846
  "displayName": "Использование в TableCanvas.bigData.stories.tsx",
27822
27847
  "type": "usage",
27823
27848
  "code": "<Slider\n value={cols}\n min={1}\n max={1500}\n onChangeCommitted={(value) => setCols(value)}\n />",
@@ -30059,9 +30084,9 @@
30059
30084
  "props": [
30060
30085
  {
30061
30086
  "name": "autoFocusType",
30062
- "type": "\"autoFocus\" | \"none\" | \"autoFocusAndSelect\"",
30087
+ "type": "\"autoFocus\" | \"none\" | \"autoFocusAndSelect\" | \"autoFocusBeforeDecimals\"",
30063
30088
  "required": true,
30064
- "description": ""
30089
+ "description": "Поведение фокуса/каретки при открытии редактора:\n- `autoFocus` — фокус, каретка в конец значения;\n- `autoFocusAndSelect` — фокус и выделение всего значения (вход через\n Enter/двойной клик — набор заменяет значение целиком);\n- `autoFocusBeforeDecimals` — фокус, каретка в конец целой части (перед\n дробной). Для входа «перезаписью»: после набранной цифры можно сразу\n продолжать ввод, не попадая в нули дробной части. Длина дробной части\n берётся из `decimalScale`/`fixedDecimalScale` и не зависит от символа\n разделителя;\n- `none` — фокусом/кареткой компонент не управляет."
30065
30090
  },
30066
30091
  {
30067
30092
  "name": "cellHeight",
@@ -33021,14 +33046,17 @@
33021
33046
  "relatedExports": [
33022
33047
  "CanvasContainer",
33023
33048
  "CanvasNode",
33049
+ "CanvasAvatar",
33050
+ "CanvasAvatarGroup",
33024
33051
  "CanvasBadge",
33025
33052
  "CanvasButton",
33026
33053
  "CanvasEmbedIconButton",
33027
33054
  "CanvasIcon",
33028
33055
  "CanvasIconButton",
33056
+ "CanvasImage",
33057
+ "CanvasLink",
33029
33058
  "CanvasRect",
33030
33059
  "CanvasText",
33031
- "CanvasLink",
33032
33060
  "Canvas",
33033
33061
  "RootBridge"
33034
33062
  ],
@@ -33285,72 +33313,90 @@
33285
33313
  "minimalUsage": "<CanvasNode />",
33286
33314
  "examples": []
33287
33315
  },
33288
- "CanvasBadge": {
33289
- "name": "CanvasBadge",
33316
+ "CanvasAvatar": {
33317
+ "name": "CanvasAvatar",
33290
33318
  "group": "components",
33291
33319
  "folderName": "TableGlide",
33292
33320
  "role": "internal",
33293
- "description": "Значок-бейдж (текст+иконки) для отрисовки в canvas-ячейках TableGlide",
33321
+ "description": "",
33294
33322
  "props": [
33295
33323
  {
33296
- "name": "text",
33297
- "type": "string",
33298
- "required": true,
33299
- "description": "Badge text content"
33324
+ "name": "bottom",
33325
+ "type": "PositionValue | undefined",
33326
+ "required": false,
33327
+ "description": "Отступ от нижнего края родителя при абсолютном позиционировании."
33300
33328
  },
33301
33329
  {
33302
- "name": "clear",
33303
- "type": "boolean | undefined",
33330
+ "name": "children",
33331
+ "type": "undefined",
33304
33332
  "required": false,
33305
- "description": "No background, only text"
33333
+ "description": "Дочерние JSX-элементы запрещены: содержимое задаётся через свойства примитива."
33306
33334
  },
33307
33335
  {
33308
- "name": "customBackgroundColor",
33309
- "type": "string | undefined",
33336
+ "name": "interaction",
33337
+ "type": "CanvasInteractionOptions | undefined",
33310
33338
  "required": false,
33311
- "description": "Кастомный цвет фона. Только конкретные значения: hex, rgb(), rgba(). CSS-переменные не поддерживаются."
33339
+ "description": "Декларативное описание поведения зоны внутри ячейки.\n\nСамый частый сценарий:\n`interaction={{ selection: 'keep', cellClick: 'stop', editor: 'never' }}`\n— элемент выполняет собственное действие и не должен менять selection,\nзапускать editor или вызывать внешний `onCellClicked`.\n\n`interaction={{ editor: 'open-on-click' }}` — элемент просит открыть\neditor текущей ячейки. Например стрелка select-ячейки."
33312
33340
  },
33313
33341
  {
33314
- "name": "customColor",
33315
- "type": "string | undefined",
33342
+ "name": "left",
33343
+ "type": "PositionValue | undefined",
33316
33344
  "required": false,
33317
- "description": "Кастомный цвет текста. Только конкретные значения: hex, rgb(), rgba(). CSS-переменные не поддерживаются."
33345
+ "description": "Отступ от левого края родителя при абсолютном позиционировании."
33318
33346
  },
33319
33347
  {
33320
- "name": "interaction",
33321
- "type": "CanvasInteractionOptions | undefined",
33348
+ "name": "onClick",
33349
+ "type": "((event: CanvasEvent<CanvasAvatar>) => void) | undefined",
33322
33350
  "required": false,
33323
- "description": "Декларативное описание поведения зоны внутри ячейки.\n\nСамый частый сценарий:\n`interaction={{ selection: 'keep', cellClick: 'stop', editor: 'never' }}`\n— элемент выполняет собственное действие и не должен менять selection,\nзапускать editor или вызывать внешний `onCellClicked`.\n\n`interaction={{ editor: 'open-on-click' }}` — элемент просит открыть\neditor текущей ячейки. Например стрелка select-ячейки."
33351
+ "description": "Обработчик клика по элементу; дополняет внутреннее поведение примитива."
33324
33352
  },
33325
33353
  {
33326
- "name": "leftIcon",
33327
- "type": "ButtonIcon",
33354
+ "name": "onMouseEnter",
33355
+ "type": "((event: CanvasEvent<CanvasAvatar>) => void) | undefined",
33328
33356
  "required": false,
33329
- "description": "Left icon (SVG string or image)"
33357
+ "description": "Обработчик входа указателя в элемент; дополняет внутреннее поведение примитива."
33330
33358
  },
33331
33359
  {
33332
- "name": "rightIcon",
33333
- "type": "ButtonIcon",
33360
+ "name": "onMouseLeave",
33361
+ "type": "((event: CanvasEvent<CanvasAvatar>) => void) | undefined",
33334
33362
  "required": false,
33335
- "description": "Right icon (SVG string or image)"
33363
+ "description": "Обработчик выхода указателя из элемента; дополняет внутреннее поведение примитива."
33336
33364
  },
33337
33365
  {
33338
- "name": "size",
33339
- "type": "BadgeSize | undefined",
33366
+ "name": "portalHoverEnabled",
33367
+ "type": "boolean | undefined",
33340
33368
  "required": false,
33341
- "description": "Badge size"
33369
+ "description": "Включает передачу hover-событий в портал; наличие tooltip также включает её."
33342
33370
  },
33343
33371
  {
33344
- "name": "transparent",
33345
- "type": "boolean | undefined",
33372
+ "name": "position",
33373
+ "type": "\"relative\" | \"absolute\" | undefined",
33346
33374
  "required": false,
33347
- "description": "Use transparent background"
33375
+ "description": "Способ размещения: в потоке flex-layout или по абсолютным отступам."
33348
33376
  },
33349
33377
  {
33350
- "name": "view",
33351
- "type": "BadgeView | undefined",
33378
+ "name": "right",
33379
+ "type": "PositionValue | undefined",
33352
33380
  "required": false,
33353
- "description": "Badge view style"
33381
+ "description": "Отступ от правого края родителя при абсолютном позиционировании."
33382
+ },
33383
+ {
33384
+ "name": "style",
33385
+ "type": "Partial<CanvasFlexStyle> | undefined",
33386
+ "required": false,
33387
+ "description": "Параметры flex-layout, размеры и курсор canvas-ноды."
33388
+ },
33389
+ {
33390
+ "name": "tooltip",
33391
+ "type": "CanvasNodeTooltipConfig | undefined",
33392
+ "required": false,
33393
+ "description": "Подсказка элемента, отображаемая через портал таблицы."
33394
+ },
33395
+ {
33396
+ "name": "top",
33397
+ "type": "PositionValue | undefined",
33398
+ "required": false,
33399
+ "description": "Отступ от верхнего края родителя при абсолютном позиционировании."
33354
33400
  },
33355
33401
  {
33356
33402
  "name": "zIndex",
@@ -33358,105 +33404,225 @@
33358
33404
  "required": false,
33359
33405
  "description": "Локальный слой внутри canvas-root; рекомендуется использовать zIndex >= 0.\nЗначение суммируется по цепочке родителей и не является DOM z-index."
33360
33406
  },
33407
+ {
33408
+ "name": "customText",
33409
+ "type": "string | undefined",
33410
+ "required": false,
33411
+ "description": "Непустой текст вместо фотографии и инициалов, например счётчик +N."
33412
+ },
33413
+ {
33414
+ "name": "size",
33415
+ "type": "AvatarSize | undefined",
33416
+ "required": false,
33417
+ "description": "Размер аватара: s — 24, m — 36, l — 48, xxl — 88 px. По умолчанию s."
33418
+ },
33419
+ {
33420
+ "name": "url",
33421
+ "type": "string | undefined",
33422
+ "required": false,
33423
+ "description": "URL фотографии; пока фото недоступно, отображаются инициалы."
33424
+ }
33425
+ ],
33426
+ "propsTypeName": "CanvasAvatarProps",
33427
+ "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/primitives/CanvasAvatar.ts",
33428
+ "type": "standalone",
33429
+ "parentComponent": "TableGlide",
33430
+ "atomicMcpVersion": "0.360.0",
33431
+ "importPath": "@daisforge/ui/components/TableGlide",
33432
+ "importStatement": "import { CanvasAvatar } from '@daisforge/ui/components/TableGlide';",
33433
+ "minimalUsage": "<CanvasAvatar />",
33434
+ "examples": [
33435
+ {
33436
+ "exportName": "Usage",
33437
+ "displayName": "Использование в CanvasAvatar.stories.tsx",
33438
+ "type": "usage",
33439
+ "code": "<Canvas.Avatar\n name=\"Анна Иванова\"\n size={row.size}\n {...content}\n tooltip=\"Анна Иванова\"\n />",
33440
+ "sourceFile": "packages/storybook/src/stories/TableCanvas/CanvasElements/CanvasAvatar/CanvasAvatar.stories.tsx"
33441
+ }
33442
+ ]
33443
+ },
33444
+ "CanvasAvatarGroup": {
33445
+ "name": "CanvasAvatarGroup",
33446
+ "group": "components",
33447
+ "folderName": "TableGlide",
33448
+ "role": "internal",
33449
+ "description": "",
33450
+ "props": [
33451
+ {
33452
+ "name": "items",
33453
+ "type": "readonly CanvasAvatarItem[]",
33454
+ "required": true,
33455
+ "description": "Известные участники в порядке отображения; id должны быть уникальны внутри группы."
33456
+ },
33361
33457
  {
33362
33458
  "name": "bottom",
33363
33459
  "type": "PositionValue | undefined",
33364
33460
  "required": false,
33365
- "description": ""
33461
+ "description": "Отступ от нижнего края родителя при абсолютном позиционировании."
33462
+ },
33463
+ {
33464
+ "name": "children",
33465
+ "type": "undefined",
33466
+ "required": false,
33467
+ "description": "Дочерние JSX-элементы запрещены: содержимое задаётся через свойства примитива."
33468
+ },
33469
+ {
33470
+ "name": "interaction",
33471
+ "type": "CanvasInteractionOptions | undefined",
33472
+ "required": false,
33473
+ "description": "Декларативное описание поведения зоны внутри ячейки.\n\nСамый частый сценарий:\n`interaction={{ selection: 'keep', cellClick: 'stop', editor: 'never' }}`\n— элемент выполняет собственное действие и не должен менять selection,\nзапускать editor или вызывать внешний `onCellClicked`.\n\n`interaction={{ editor: 'open-on-click' }}` — элемент просит открыть\neditor текущей ячейки. Например стрелка select-ячейки."
33366
33474
  },
33367
33475
  {
33368
33476
  "name": "left",
33369
33477
  "type": "PositionValue | undefined",
33370
33478
  "required": false,
33371
- "description": ""
33479
+ "description": "Отступ от левого края родителя при абсолютном позиционировании."
33372
33480
  },
33373
33481
  {
33374
- "name": "pilled",
33375
- "type": "boolean | undefined",
33482
+ "name": "onClick",
33483
+ "type": "((event: CanvasEvent<CanvasAvatarGroup>) => void) | undefined",
33376
33484
  "required": false,
33377
- "description": ""
33485
+ "description": "Обработчик клика по элементу; дополняет внутреннее поведение примитива."
33486
+ },
33487
+ {
33488
+ "name": "onMouseEnter",
33489
+ "type": "((event: CanvasEvent<CanvasAvatarGroup>) => void) | undefined",
33490
+ "required": false,
33491
+ "description": "Обработчик входа указателя в элемент; дополняет внутреннее поведение примитива."
33492
+ },
33493
+ {
33494
+ "name": "onMouseLeave",
33495
+ "type": "((event: CanvasEvent<CanvasAvatarGroup>) => void) | undefined",
33496
+ "required": false,
33497
+ "description": "Обработчик выхода указателя из элемента; дополняет внутреннее поведение примитива."
33378
33498
  },
33379
33499
  {
33380
33500
  "name": "portalHoverEnabled",
33381
33501
  "type": "boolean | undefined",
33382
33502
  "required": false,
33383
- "description": ""
33503
+ "description": "Включает передачу hover-событий в портал; наличие tooltip также включает её."
33384
33504
  },
33385
33505
  {
33386
33506
  "name": "position",
33387
- "type": "\"absolute\" | undefined",
33507
+ "type": "\"relative\" | \"absolute\" | undefined",
33388
33508
  "required": false,
33389
- "description": ""
33509
+ "description": "Способ размещения: в потоке flex-layout или по абсолютным отступам."
33390
33510
  },
33391
33511
  {
33392
33512
  "name": "right",
33393
33513
  "type": "PositionValue | undefined",
33394
33514
  "required": false,
33395
- "description": ""
33515
+ "description": "Отступ от правого края родителя при абсолютном позиционировании."
33396
33516
  },
33397
33517
  {
33398
33518
  "name": "style",
33399
33519
  "type": "Partial<CanvasFlexStyle> | undefined",
33400
33520
  "required": false,
33401
- "description": ""
33521
+ "description": "Параметры flex-layout, размеры и курсор canvas-ноды."
33402
33522
  },
33403
33523
  {
33404
33524
  "name": "tooltip",
33405
33525
  "type": "CanvasNodeTooltipConfig | undefined",
33406
33526
  "required": false,
33407
- "description": ""
33527
+ "description": "Подсказка элемента, отображаемая через портал таблицы."
33408
33528
  },
33409
33529
  {
33410
33530
  "name": "top",
33411
33531
  "type": "PositionValue | undefined",
33412
33532
  "required": false,
33413
- "description": ""
33533
+ "description": "Отступ от верхнего края родителя при абсолютном позиционировании."
33534
+ },
33535
+ {
33536
+ "name": "zIndex",
33537
+ "type": "number | undefined",
33538
+ "required": false,
33539
+ "description": "Локальный слой внутри canvas-root; рекомендуется использовать zIndex >= 0.\nЗначение суммируется по цепочке родителей и не является DOM z-index."
33540
+ },
33541
+ {
33542
+ "name": "onItemClick",
33543
+ "type": "((args: AvatarGroupItemClick) => void) | undefined",
33544
+ "required": false,
33545
+ "description": "Обработчик клика по видимому участнику."
33546
+ },
33547
+ {
33548
+ "name": "onOverflowClick",
33549
+ "type": "((args: AvatarGroupOverflowClick) => void) | undefined",
33550
+ "required": false,
33551
+ "description": "Обработчик клика по счётчику скрытых участников +N."
33552
+ },
33553
+ {
33554
+ "name": "overflowTooltip",
33555
+ "type": "CanvasNodeTooltipConfig | undefined",
33556
+ "required": false,
33557
+ "description": "Подсказка счётчика; по умолчанию текст +N."
33558
+ },
33559
+ {
33560
+ "name": "size",
33561
+ "type": "AvatarSize | undefined",
33562
+ "required": false,
33563
+ "description": "Размер аватара: s — 24, m — 36, l — 48, xxl — 88 px. По умолчанию s."
33564
+ },
33565
+ {
33566
+ "name": "totalCount",
33567
+ "type": "number | undefined",
33568
+ "required": false,
33569
+ "description": "Общее число участников, включая ещё не загруженных. По умолчанию длина items; меньшие значения игнорируются."
33570
+ },
33571
+ {
33572
+ "name": "visibleCount",
33573
+ "type": "number | undefined",
33574
+ "required": false,
33575
+ "description": "Максимум видимых участников без учёта +N. По умолчанию 3, но не больше длины items."
33414
33576
  }
33415
33577
  ],
33416
- "propsTypeName": "CanvasBadgeProps",
33417
- "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/primitives/CanvasBadge.ts",
33578
+ "propsTypeName": "CanvasAvatarGroupProps",
33579
+ "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/primitives/CanvasAvatarGroup.ts",
33418
33580
  "type": "standalone",
33419
- "category": "Локальные компоненты",
33420
- "keywords": [
33421
- "метка статуса",
33422
- "лейбл",
33423
- "status label"
33424
- ],
33425
- "hasCuratedMeta": true,
33426
33581
  "parentComponent": "TableGlide",
33427
33582
  "atomicMcpVersion": "0.360.0",
33428
33583
  "importPath": "@daisforge/ui/components/TableGlide",
33429
- "importStatement": "import { CanvasBadge } from '@daisforge/ui/components/TableGlide';",
33430
- "minimalUsage": "<CanvasBadge text={'значение'} />",
33584
+ "importStatement": "import { CanvasAvatarGroup } from '@daisforge/ui/components/TableGlide';",
33585
+ "minimalUsage": "<CanvasAvatarGroup items={[]} />",
33431
33586
  "examples": [
33432
33587
  {
33433
- "exportName": "Usage1",
33434
- "displayName": "Использование в CanvasBadge.stories.tsx",
33435
- "type": "usage",
33436
- "code": "<Canvas.Badge\n text={text}\n view={row.view}\n size={size}\n transparent={transparent}\n clear={clear}\n pilled={pilled}\n />",
33437
- "sourceFile": "packages/storybook/src/stories/TableCanvas/CanvasElements/CanvasBadge/CanvasBadge.stories.tsx"
33438
- },
33439
- {
33440
- "exportName": "Usage2",
33441
- "displayName": "Использование в TableCanvas.subRows.stories.tsx",
33588
+ "exportName": "Usage",
33589
+ "displayName": "Использование в CanvasAvatarGroup.stories.tsx",
33442
33590
  "type": "usage",
33443
- "code": "<Canvas.Badge\n id=\"kek\"\n text={props.row?.tribeZone}\n view=\"accent\"\n size=\"m\"\n />",
33444
- "sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.SubRows/TableCanvas.subRows.stories.tsx"
33591
+ "code": "<Canvas.AvatarGroup\n items={row.items}\n totalCount={row.total}\n visibleCount={row.visible}\n />",
33592
+ "sourceFile": "packages/storybook/src/stories/TableCanvas/CanvasElements/CanvasAvatarGroup/CanvasAvatarGroup.stories.tsx"
33445
33593
  }
33446
33594
  ]
33447
33595
  },
33448
- "CanvasButton": {
33449
- "name": "CanvasButton",
33596
+ "CanvasBadge": {
33597
+ "name": "CanvasBadge",
33450
33598
  "group": "components",
33451
33599
  "folderName": "TableGlide",
33452
33600
  "role": "internal",
33453
- "description": "Кнопка с текстом и иконками для canvas-ячеек TableGlide (аналог Button)",
33601
+ "description": "Значок-бейдж (текст+иконки) для отрисовки в canvas-ячейках TableGlide",
33454
33602
  "props": [
33455
33603
  {
33456
- "name": "children",
33604
+ "name": "text",
33457
33605
  "type": "string",
33458
33606
  "required": true,
33459
- "description": ""
33607
+ "description": "Badge text content"
33608
+ },
33609
+ {
33610
+ "name": "clear",
33611
+ "type": "boolean | undefined",
33612
+ "required": false,
33613
+ "description": "No background, only text"
33614
+ },
33615
+ {
33616
+ "name": "customBackgroundColor",
33617
+ "type": "string | undefined",
33618
+ "required": false,
33619
+ "description": "Кастомный цвет фона. Только конкретные значения: hex, rgb(), rgba(). CSS-переменные не поддерживаются."
33620
+ },
33621
+ {
33622
+ "name": "customColor",
33623
+ "type": "string | undefined",
33624
+ "required": false,
33625
+ "description": "Кастомный цвет текста. Только конкретные значения: hex, rgb(), rgba(). CSS-переменные не поддерживаются."
33460
33626
  },
33461
33627
  {
33462
33628
  "name": "interaction",
@@ -33478,15 +33644,21 @@
33478
33644
  },
33479
33645
  {
33480
33646
  "name": "size",
33481
- "type": "ButtonSize | undefined",
33647
+ "type": "BadgeSize | undefined",
33482
33648
  "required": false,
33483
- "description": "Button size"
33649
+ "description": "Badge size"
33650
+ },
33651
+ {
33652
+ "name": "transparent",
33653
+ "type": "boolean | undefined",
33654
+ "required": false,
33655
+ "description": "Use transparent background"
33484
33656
  },
33485
33657
  {
33486
33658
  "name": "view",
33487
- "type": "ButtonView | undefined",
33659
+ "type": "BadgeView | undefined",
33488
33660
  "required": false,
33489
- "description": "Button view style based on sdds_finai__light theme"
33661
+ "description": "Badge view style"
33490
33662
  },
33491
33663
  {
33492
33664
  "name": "zIndex",
@@ -33507,8 +33679,144 @@
33507
33679
  "description": ""
33508
33680
  },
33509
33681
  {
33510
- "name": "onClick",
33511
- "type": "((event: CanvasEvent<CanvasButton>) => void) | undefined",
33682
+ "name": "pilled",
33683
+ "type": "boolean | undefined",
33684
+ "required": false,
33685
+ "description": ""
33686
+ },
33687
+ {
33688
+ "name": "portalHoverEnabled",
33689
+ "type": "boolean | undefined",
33690
+ "required": false,
33691
+ "description": ""
33692
+ },
33693
+ {
33694
+ "name": "position",
33695
+ "type": "\"absolute\" | undefined",
33696
+ "required": false,
33697
+ "description": ""
33698
+ },
33699
+ {
33700
+ "name": "right",
33701
+ "type": "PositionValue | undefined",
33702
+ "required": false,
33703
+ "description": ""
33704
+ },
33705
+ {
33706
+ "name": "style",
33707
+ "type": "Partial<CanvasFlexStyle> | undefined",
33708
+ "required": false,
33709
+ "description": ""
33710
+ },
33711
+ {
33712
+ "name": "tooltip",
33713
+ "type": "CanvasNodeTooltipConfig | undefined",
33714
+ "required": false,
33715
+ "description": ""
33716
+ },
33717
+ {
33718
+ "name": "top",
33719
+ "type": "PositionValue | undefined",
33720
+ "required": false,
33721
+ "description": ""
33722
+ }
33723
+ ],
33724
+ "propsTypeName": "CanvasBadgeProps",
33725
+ "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/primitives/CanvasBadge.ts",
33726
+ "type": "standalone",
33727
+ "category": "Локальные компоненты",
33728
+ "keywords": [
33729
+ "метка статуса",
33730
+ "лейбл",
33731
+ "status label"
33732
+ ],
33733
+ "hasCuratedMeta": true,
33734
+ "parentComponent": "TableGlide",
33735
+ "atomicMcpVersion": "0.360.0",
33736
+ "importPath": "@daisforge/ui/components/TableGlide",
33737
+ "importStatement": "import { CanvasBadge } from '@daisforge/ui/components/TableGlide';",
33738
+ "minimalUsage": "<CanvasBadge text={'значение'} />",
33739
+ "examples": [
33740
+ {
33741
+ "exportName": "Usage1",
33742
+ "displayName": "Использование в CanvasBadge.stories.tsx",
33743
+ "type": "usage",
33744
+ "code": "<Canvas.Badge\n text={text}\n view={row.view}\n size={size}\n transparent={transparent}\n clear={clear}\n pilled={pilled}\n />",
33745
+ "sourceFile": "packages/storybook/src/stories/TableCanvas/CanvasElements/CanvasBadge/CanvasBadge.stories.tsx"
33746
+ },
33747
+ {
33748
+ "exportName": "Usage2",
33749
+ "displayName": "Использование в TableCanvas.subRows.stories.tsx",
33750
+ "type": "usage",
33751
+ "code": "<Canvas.Badge\n id=\"kek\"\n text={props.row?.tribeZone}\n view=\"accent\"\n size=\"m\"\n />",
33752
+ "sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.SubRows/TableCanvas.subRows.stories.tsx"
33753
+ }
33754
+ ]
33755
+ },
33756
+ "CanvasButton": {
33757
+ "name": "CanvasButton",
33758
+ "group": "components",
33759
+ "folderName": "TableGlide",
33760
+ "role": "internal",
33761
+ "description": "Кнопка с текстом и иконками для canvas-ячеек TableGlide (аналог Button)",
33762
+ "props": [
33763
+ {
33764
+ "name": "children",
33765
+ "type": "string",
33766
+ "required": true,
33767
+ "description": ""
33768
+ },
33769
+ {
33770
+ "name": "interaction",
33771
+ "type": "CanvasInteractionOptions | undefined",
33772
+ "required": false,
33773
+ "description": "Декларативное описание поведения зоны внутри ячейки.\n\nСамый частый сценарий:\n`interaction={{ selection: 'keep', cellClick: 'stop', editor: 'never' }}`\n— элемент выполняет собственное действие и не должен менять selection,\nзапускать editor или вызывать внешний `onCellClicked`.\n\n`interaction={{ editor: 'open-on-click' }}` — элемент просит открыть\neditor текущей ячейки. Например стрелка select-ячейки."
33774
+ },
33775
+ {
33776
+ "name": "leftIcon",
33777
+ "type": "ButtonIcon",
33778
+ "required": false,
33779
+ "description": "Left icon (SVG string or image)"
33780
+ },
33781
+ {
33782
+ "name": "rightIcon",
33783
+ "type": "ButtonIcon",
33784
+ "required": false,
33785
+ "description": "Right icon (SVG string or image)"
33786
+ },
33787
+ {
33788
+ "name": "size",
33789
+ "type": "ButtonSize | undefined",
33790
+ "required": false,
33791
+ "description": "Button size"
33792
+ },
33793
+ {
33794
+ "name": "view",
33795
+ "type": "ButtonView | undefined",
33796
+ "required": false,
33797
+ "description": "Button view style based on sdds_finai__light theme"
33798
+ },
33799
+ {
33800
+ "name": "zIndex",
33801
+ "type": "number | undefined",
33802
+ "required": false,
33803
+ "description": "Локальный слой внутри canvas-root; рекомендуется использовать zIndex >= 0.\nЗначение суммируется по цепочке родителей и не является DOM z-index."
33804
+ },
33805
+ {
33806
+ "name": "bottom",
33807
+ "type": "PositionValue | undefined",
33808
+ "required": false,
33809
+ "description": ""
33810
+ },
33811
+ {
33812
+ "name": "left",
33813
+ "type": "PositionValue | undefined",
33814
+ "required": false,
33815
+ "description": ""
33816
+ },
33817
+ {
33818
+ "name": "onClick",
33819
+ "type": "((event: CanvasEvent<CanvasButton>) => void) | undefined",
33512
33820
  "required": false,
33513
33821
  "description": ""
33514
33822
  },
@@ -34015,109 +34323,128 @@
34015
34323
  }
34016
34324
  ]
34017
34325
  },
34018
- "CanvasRect": {
34019
- "name": "CanvasRect",
34326
+ "CanvasImage": {
34327
+ "name": "CanvasImage",
34020
34328
  "group": "components",
34021
34329
  "folderName": "TableGlide",
34022
34330
  "role": "internal",
34023
- "description": "Прямоугольник с заливкой и рамкой — примитив фона/разделителя в canvas-ячейке",
34331
+ "description": "",
34024
34332
  "props": [
34025
34333
  {
34026
- "name": "interaction",
34027
- "type": "CanvasInteractionOptions | undefined",
34334
+ "name": "bottom",
34335
+ "type": "PositionValue | undefined",
34028
34336
  "required": false,
34029
- "description": "Декларативное описание поведения зоны внутри ячейки.\n\nСамый частый сценарий:\n`interaction={{ selection: 'keep', cellClick: 'stop', editor: 'never' }}`\n— элемент выполняет собственное действие и не должен менять selection,\nзапускать editor или вызывать внешний `onCellClicked`.\n\n`interaction={{ editor: 'open-on-click' }}` — элемент просит открыть\neditor текущей ячейки. Например стрелка select-ячейки."
34337
+ "description": "Отступ от нижнего края родителя при абсолютном позиционировании."
34030
34338
  },
34031
34339
  {
34032
- "name": "zIndex",
34033
- "type": "number | undefined",
34340
+ "name": "children",
34341
+ "type": "undefined",
34034
34342
  "required": false,
34035
- "description": "Локальный слой внутри canvas-root; рекомендуется использовать zIndex >= 0.\nЗначение суммируется по цепочке родителей и не является DOM z-index."
34343
+ "description": "Дочерние JSX-элементы запрещены: содержимое задаётся через свойства примитива."
34036
34344
  },
34037
34345
  {
34038
- "name": "borderColor",
34039
- "type": "string | undefined",
34346
+ "name": "interaction",
34347
+ "type": "CanvasInteractionOptions | undefined",
34040
34348
  "required": false,
34041
- "description": ""
34349
+ "description": "Декларативное описание поведения зоны внутри ячейки.\n\nСамый частый сценарий:\n`interaction={{ selection: 'keep', cellClick: 'stop', editor: 'never' }}`\n— элемент выполняет собственное действие и не должен менять selection,\nзапускать editor или вызывать внешний `onCellClicked`.\n\n`interaction={{ editor: 'open-on-click' }}` — элемент просит открыть\neditor текущей ячейки. Например стрелка select-ячейки."
34042
34350
  },
34043
34351
  {
34044
- "name": "borderWidth",
34045
- "type": "number | undefined",
34352
+ "name": "left",
34353
+ "type": "PositionValue | undefined",
34046
34354
  "required": false,
34047
- "description": ""
34355
+ "description": "Отступ от левого края родителя при абсолютном позиционировании."
34048
34356
  },
34049
34357
  {
34050
- "name": "bottom",
34051
- "type": "PositionValue | undefined",
34358
+ "name": "onClick",
34359
+ "type": "((event: CanvasEvent<CanvasImage>) => void) | undefined",
34052
34360
  "required": false,
34053
- "description": ""
34361
+ "description": "Обработчик клика по элементу; дополняет внутреннее поведение примитива."
34054
34362
  },
34055
34363
  {
34056
- "name": "left",
34057
- "type": "PositionValue | undefined",
34364
+ "name": "onMouseEnter",
34365
+ "type": "((event: CanvasEvent<CanvasImage>) => void) | undefined",
34058
34366
  "required": false,
34059
- "description": ""
34367
+ "description": "Обработчик входа указателя в элемент; дополняет внутреннее поведение примитива."
34368
+ },
34369
+ {
34370
+ "name": "onMouseLeave",
34371
+ "type": "((event: CanvasEvent<CanvasImage>) => void) | undefined",
34372
+ "required": false,
34373
+ "description": "Обработчик выхода указателя из элемента; дополняет внутреннее поведение примитива."
34060
34374
  },
34061
34375
  {
34062
34376
  "name": "portalHoverEnabled",
34063
34377
  "type": "boolean | undefined",
34064
34378
  "required": false,
34065
- "description": ""
34379
+ "description": "Включает передачу hover-событий в портал; наличие tooltip также включает её."
34066
34380
  },
34067
34381
  {
34068
34382
  "name": "position",
34069
- "type": "\"absolute\" | undefined",
34383
+ "type": "\"relative\" | \"absolute\" | undefined",
34070
34384
  "required": false,
34071
- "description": ""
34385
+ "description": "Способ размещения: в потоке flex-layout или по абсолютным отступам."
34072
34386
  },
34073
34387
  {
34074
34388
  "name": "right",
34075
34389
  "type": "PositionValue | undefined",
34076
34390
  "required": false,
34077
- "description": ""
34391
+ "description": "Отступ от правого края родителя при абсолютном позиционировании."
34078
34392
  },
34079
34393
  {
34080
34394
  "name": "style",
34081
34395
  "type": "Partial<CanvasFlexStyle> | undefined",
34082
34396
  "required": false,
34083
- "description": ""
34397
+ "description": "Параметры flex-layout, размеры и курсор canvas-ноды."
34084
34398
  },
34085
34399
  {
34086
34400
  "name": "tooltip",
34087
34401
  "type": "CanvasNodeTooltipConfig | undefined",
34088
34402
  "required": false,
34089
- "description": ""
34403
+ "description": "Подсказка элемента, отображаемая через портал таблицы."
34090
34404
  },
34091
34405
  {
34092
34406
  "name": "top",
34093
34407
  "type": "PositionValue | undefined",
34094
34408
  "required": false,
34095
- "description": ""
34409
+ "description": "Отступ от верхнего края родителя при абсолютном позиционировании."
34410
+ },
34411
+ {
34412
+ "name": "zIndex",
34413
+ "type": "number | undefined",
34414
+ "required": false,
34415
+ "description": "Локальный слой внутри canvas-root; рекомендуется использовать zIndex >= 0.\nЗначение суммируется по цепочке родителей и не является DOM z-index."
34416
+ },
34417
+ {
34418
+ "name": "fit",
34419
+ "type": "ImageFit | undefined",
34420
+ "required": false,
34421
+ "description": "Масштабирование в границах элемента: cover — обрезка, contain — вписывание, fill — растяжение. По умолчанию cover."
34096
34422
  }
34097
34423
  ],
34098
- "propsTypeName": "CanvasRectProps",
34099
- "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/primitives/CanvasRect.ts",
34424
+ "propsTypeName": "CanvasImageProps",
34425
+ "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/primitives/CanvasImage.ts",
34100
34426
  "type": "standalone",
34101
- "category": "Локальные компоненты",
34102
- "keywords": [
34103
- "фон ячейки",
34104
- "разделитель",
34105
- "прямоугольник"
34106
- ],
34107
- "hasCuratedMeta": true,
34108
34427
  "parentComponent": "TableGlide",
34109
34428
  "atomicMcpVersion": "0.360.0",
34110
34429
  "importPath": "@daisforge/ui/components/TableGlide",
34111
- "importStatement": "import { CanvasRect } from '@daisforge/ui/components/TableGlide';",
34112
- "minimalUsage": "<CanvasRect />",
34113
- "examples": []
34430
+ "importStatement": "import { CanvasImage } from '@daisforge/ui/components/TableGlide';",
34431
+ "minimalUsage": "<CanvasImage />",
34432
+ "examples": [
34433
+ {
34434
+ "exportName": "Usage",
34435
+ "displayName": "Использование в CanvasImage.stories.tsx",
34436
+ "type": "usage",
34437
+ "code": "<Canvas.Image\n src={row.src}\n fit={fit}\n style={{ width: 88, height: 88 }}\n />",
34438
+ "sourceFile": "packages/storybook/src/stories/TableCanvas/CanvasElements/CanvasImage/CanvasImage.stories.tsx"
34439
+ }
34440
+ ]
34114
34441
  },
34115
- "CanvasText": {
34116
- "name": "CanvasText",
34442
+ "CanvasLink": {
34443
+ "name": "CanvasLink",
34117
34444
  "group": "components",
34118
34445
  "folderName": "TableGlide",
34119
34446
  "role": "internal",
34120
- "description": "Текстовый узел canvas TableGlide: перенос строк, ellipsis, авто-тултип при обрезке",
34447
+ "description": "Ссылка с подчёркиванием и переходом по href внутри canvas-ячейки TableGlide",
34121
34448
  "props": [
34122
34449
  {
34123
34450
  "name": "interaction",
@@ -34149,6 +34476,12 @@
34149
34476
  "required": false,
34150
34477
  "description": ""
34151
34478
  },
34479
+ {
34480
+ "name": "onClick",
34481
+ "type": "((event: CanvasEvent<CanvasLink>) => void) | undefined",
34482
+ "required": false,
34483
+ "description": ""
34484
+ },
34152
34485
  {
34153
34486
  "name": "portalHoverEnabled",
34154
34487
  "type": "boolean | undefined",
@@ -34228,44 +34561,88 @@
34228
34561
  "description": ""
34229
34562
  }
34230
34563
  ],
34231
- "propsTypeName": "CanvasTextProps",
34232
- "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/primitives/CanvasText.ts",
34233
- "type": "standalone",
34564
+ "propsTypeName": "CanvasLinkProps",
34565
+ "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/primitives/CanvasLink.ts",
34566
+ "type": "wrapper",
34567
+ "atomicBase": "Link",
34568
+ "wrapsInternal": "Link",
34234
34569
  "category": "Локальные компоненты",
34235
34570
  "keywords": [
34236
- "перенос текста",
34237
- "обрезка текста",
34238
- "многострочный текст"
34571
+ "гиперссылка",
34572
+ "переход по клику",
34573
+ "canvas hyperlink"
34239
34574
  ],
34240
34575
  "hasCuratedMeta": true,
34241
34576
  "parentComponent": "TableGlide",
34577
+ "inheritedProps": [
34578
+ {
34579
+ "name": "disabled",
34580
+ "type": "boolean",
34581
+ "required": false,
34582
+ "inheritedFrom": "Link",
34583
+ "inheritedPackage": "@salutejs/sdds-finai"
34584
+ },
34585
+ {
34586
+ "name": "size",
34587
+ "type": "string",
34588
+ "required": false,
34589
+ "inheritedFrom": "Link",
34590
+ "inheritedPackage": "@salutejs/sdds-finai"
34591
+ },
34592
+ {
34593
+ "name": "underline",
34594
+ "type": "\"none\" | \"hover\" | \"always\"",
34595
+ "required": false,
34596
+ "inheritedFrom": "Link",
34597
+ "inheritedPackage": "@salutejs/sdds-finai"
34598
+ },
34599
+ {
34600
+ "name": "view",
34601
+ "type": "\"clear\" | \"default\" | \"accent\" | \"positive\" | \"warning\" | \"negative\" | \"secondary\" | \"tertiary\" | \"paragraph\"",
34602
+ "required": false,
34603
+ "inheritedFrom": "Link",
34604
+ "inheritedPackage": "@salutejs/sdds-finai"
34605
+ }
34606
+ ],
34242
34607
  "atomicMcpVersion": "0.360.0",
34243
34608
  "importPath": "@daisforge/ui/components/TableGlide",
34244
- "importStatement": "import { CanvasText } from '@daisforge/ui/components/TableGlide';",
34245
- "minimalUsage": "<CanvasText />",
34609
+ "importStatement": "import { CanvasLink } from '@daisforge/ui/components/TableGlide';",
34610
+ "minimalUsage": "<CanvasLink />",
34246
34611
  "examples": [
34247
34612
  {
34248
34613
  "exportName": "Usage1",
34249
- "displayName": "Использование в CanvasText.stories.tsx",
34614
+ "displayName": "Использование в CanvasLink.stories.tsx",
34250
34615
  "type": "usage",
34251
- "code": "<Canvas.Text\n color={color || theme.textDark}\n font={font || theme.baseFontStyle}\n wordWrap={wordWrap}\n overflow={overflow}\n textOverflow={textOverflow}\n ellipsis={ellipsis}\n maxLines={resolvedMaxLines}\n lineHeight={lineHeight}\n style={{ flexGrow: 1 }}\n autoTooltip={{\n enabled: true,\n }}\n >\n {row.id === 1 ? text : row.longText}\n </Canvas.Text>",
34252
- "sourceFile": "packages/storybook/src/stories/TableCanvas/CanvasElements/CanvasText/CanvasText.stories.tsx"
34616
+ "code": "<Canvas.Link\n view={row.view}\n href={href}\n target=\"_blank\"\n disabled={disabled}\n >\n {text}\n </Canvas.Link>",
34617
+ "sourceFile": "packages/storybook/src/stories/TableCanvas/CanvasElements/CanvasLink/CanvasLink.stories.tsx"
34253
34618
  },
34254
34619
  {
34255
34620
  "exportName": "Usage2",
34256
- "displayName": "Использование в TableCanvasTooltip.stories.tsx",
34621
+ "displayName": "Использование в CanvasText.stories.tsx",
34257
34622
  "type": "usage",
34258
- "code": "<Canvas.Text\n overflow=\"hidden\"\n textOverflow=\"ellipsis\"\n autoTooltip\n style={{ flexGrow: 1 }}\n >\n {`${row.task}: ${longText}`}\n </Canvas.Text>",
34259
- "sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.Tooltip/TableCanvasTooltip.stories.tsx"
34623
+ "code": "<Canvas.Link>{row.shortName}</Canvas.Link>",
34624
+ "sourceFile": "packages/storybook/src/stories/TableCanvas/CanvasElements/CanvasText/CanvasText.stories.tsx"
34625
+ },
34626
+ {
34627
+ "exportName": "Vendor1",
34628
+ "displayName": "Использование Использование",
34629
+ "type": "vendor",
34630
+ "code": "import React from 'react';\nimport { TextS, Link } from '@daisforge/ui/components/TableGlide';\nexport function App() {\n return (\n <TextS>\n Скачайте <Link href=\"/\" target=\"_blank\">приложение.</Link>\n </TextS>\n );\n}"
34631
+ },
34632
+ {
34633
+ "exportName": "Vendor2",
34634
+ "displayName": "Подчёркивание Подчёркивание Prop underline управляет режимом подчёркивания ссылки",
34635
+ "type": "vendor",
34636
+ "code": "import React from 'react';\nimport { TextS, Link } from '@daisforge/ui/components/TableGlide';\nexport function App() {\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>\n <TextS><Link href=\"/\" underline=\"none\">Без подчёркивания</Link></TextS>\n <TextS><Link href=\"/\" underline=\"hover\">Подчёркивание при наведении</Link></TextS>\n <TextS><Link href=\"/\" underline=\"always\">Всегда подчёркнута</Link></TextS>\n </div>\n );\n}"
34260
34637
  }
34261
34638
  ]
34262
34639
  },
34263
- "CanvasLink": {
34264
- "name": "CanvasLink",
34640
+ "CanvasRect": {
34641
+ "name": "CanvasRect",
34265
34642
  "group": "components",
34266
34643
  "folderName": "TableGlide",
34267
34644
  "role": "internal",
34268
- "description": "Ссылка с подчёркиванием и переходом по href внутри canvas-ячейки TableGlide",
34645
+ "description": "Прямоугольник с заливкой и рамкой — примитив фона/разделителя в canvas-ячейке",
34269
34646
  "props": [
34270
34647
  {
34271
34648
  "name": "interaction",
@@ -34279,6 +34656,18 @@
34279
34656
  "required": false,
34280
34657
  "description": "Локальный слой внутри canvas-root; рекомендуется использовать zIndex >= 0.\nЗначение суммируется по цепочке родителей и не является DOM z-index."
34281
34658
  },
34659
+ {
34660
+ "name": "borderColor",
34661
+ "type": "string | undefined",
34662
+ "required": false,
34663
+ "description": ""
34664
+ },
34665
+ {
34666
+ "name": "borderWidth",
34667
+ "type": "number | undefined",
34668
+ "required": false,
34669
+ "description": ""
34670
+ },
34282
34671
  {
34283
34672
  "name": "bottom",
34284
34673
  "type": "PositionValue | undefined",
@@ -34286,20 +34675,107 @@
34286
34675
  "description": ""
34287
34676
  },
34288
34677
  {
34289
- "name": "font",
34290
- "type": "string | undefined",
34678
+ "name": "left",
34679
+ "type": "PositionValue | undefined",
34291
34680
  "required": false,
34292
34681
  "description": ""
34293
34682
  },
34294
34683
  {
34295
- "name": "left",
34684
+ "name": "portalHoverEnabled",
34685
+ "type": "boolean | undefined",
34686
+ "required": false,
34687
+ "description": ""
34688
+ },
34689
+ {
34690
+ "name": "position",
34691
+ "type": "\"absolute\" | undefined",
34692
+ "required": false,
34693
+ "description": ""
34694
+ },
34695
+ {
34696
+ "name": "right",
34296
34697
  "type": "PositionValue | undefined",
34297
34698
  "required": false,
34298
34699
  "description": ""
34299
34700
  },
34300
34701
  {
34301
- "name": "onClick",
34302
- "type": "((event: CanvasEvent<CanvasLink>) => void) | undefined",
34702
+ "name": "style",
34703
+ "type": "Partial<CanvasFlexStyle> | undefined",
34704
+ "required": false,
34705
+ "description": ""
34706
+ },
34707
+ {
34708
+ "name": "tooltip",
34709
+ "type": "CanvasNodeTooltipConfig | undefined",
34710
+ "required": false,
34711
+ "description": ""
34712
+ },
34713
+ {
34714
+ "name": "top",
34715
+ "type": "PositionValue | undefined",
34716
+ "required": false,
34717
+ "description": ""
34718
+ }
34719
+ ],
34720
+ "propsTypeName": "CanvasRectProps",
34721
+ "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/primitives/CanvasRect.ts",
34722
+ "type": "standalone",
34723
+ "category": "Локальные компоненты",
34724
+ "keywords": [
34725
+ "фон ячейки",
34726
+ "разделитель",
34727
+ "прямоугольник"
34728
+ ],
34729
+ "hasCuratedMeta": true,
34730
+ "parentComponent": "TableGlide",
34731
+ "atomicMcpVersion": "0.360.0",
34732
+ "importPath": "@daisforge/ui/components/TableGlide",
34733
+ "importStatement": "import { CanvasRect } from '@daisforge/ui/components/TableGlide';",
34734
+ "minimalUsage": "<CanvasRect />",
34735
+ "examples": [
34736
+ {
34737
+ "exportName": "Usage",
34738
+ "displayName": "Использование в CanvasImage.stories.tsx",
34739
+ "type": "usage",
34740
+ "code": "<Canvas.Rect\n position=\"absolute\"\n left={0}\n top={0}\n style={{ width: 88, height: 88 }}\n borderColor={theme.tokens.outlineAccent}\n borderWidth={1}\n zIndex={1}\n />",
34741
+ "sourceFile": "packages/storybook/src/stories/TableCanvas/CanvasElements/CanvasImage/CanvasImage.stories.tsx"
34742
+ }
34743
+ ]
34744
+ },
34745
+ "CanvasText": {
34746
+ "name": "CanvasText",
34747
+ "group": "components",
34748
+ "folderName": "TableGlide",
34749
+ "role": "internal",
34750
+ "description": "Текстовый узел canvas TableGlide: перенос строк, ellipsis, авто-тултип при обрезке",
34751
+ "props": [
34752
+ {
34753
+ "name": "interaction",
34754
+ "type": "CanvasInteractionOptions | undefined",
34755
+ "required": false,
34756
+ "description": "Декларативное описание поведения зоны внутри ячейки.\n\nСамый частый сценарий:\n`interaction={{ selection: 'keep', cellClick: 'stop', editor: 'never' }}`\n— элемент выполняет собственное действие и не должен менять selection,\nзапускать editor или вызывать внешний `onCellClicked`.\n\n`interaction={{ editor: 'open-on-click' }}` — элемент просит открыть\neditor текущей ячейки. Например стрелка select-ячейки."
34757
+ },
34758
+ {
34759
+ "name": "zIndex",
34760
+ "type": "number | undefined",
34761
+ "required": false,
34762
+ "description": "Локальный слой внутри canvas-root; рекомендуется использовать zIndex >= 0.\nЗначение суммируется по цепочке родителей и не является DOM z-index."
34763
+ },
34764
+ {
34765
+ "name": "bottom",
34766
+ "type": "PositionValue | undefined",
34767
+ "required": false,
34768
+ "description": ""
34769
+ },
34770
+ {
34771
+ "name": "font",
34772
+ "type": "string | undefined",
34773
+ "required": false,
34774
+ "description": ""
34775
+ },
34776
+ {
34777
+ "name": "left",
34778
+ "type": "PositionValue | undefined",
34303
34779
  "required": false,
34304
34780
  "description": ""
34305
34781
  },
@@ -34382,79 +34858,35 @@
34382
34858
  "description": ""
34383
34859
  }
34384
34860
  ],
34385
- "propsTypeName": "CanvasLinkProps",
34386
- "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/primitives/CanvasLink.ts",
34387
- "type": "wrapper",
34388
- "atomicBase": "Link",
34389
- "wrapsInternal": "Link",
34861
+ "propsTypeName": "CanvasTextProps",
34862
+ "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/primitives/CanvasText.ts",
34863
+ "type": "standalone",
34390
34864
  "category": "Локальные компоненты",
34391
34865
  "keywords": [
34392
- "гиперссылка",
34393
- "переход по клику",
34394
- "canvas hyperlink"
34866
+ "перенос текста",
34867
+ "обрезка текста",
34868
+ "многострочный текст"
34395
34869
  ],
34396
34870
  "hasCuratedMeta": true,
34397
34871
  "parentComponent": "TableGlide",
34398
- "inheritedProps": [
34399
- {
34400
- "name": "disabled",
34401
- "type": "boolean",
34402
- "required": false,
34403
- "inheritedFrom": "Link",
34404
- "inheritedPackage": "@salutejs/sdds-finai"
34405
- },
34406
- {
34407
- "name": "size",
34408
- "type": "string",
34409
- "required": false,
34410
- "inheritedFrom": "Link",
34411
- "inheritedPackage": "@salutejs/sdds-finai"
34412
- },
34413
- {
34414
- "name": "underline",
34415
- "type": "\"none\" | \"hover\" | \"always\"",
34416
- "required": false,
34417
- "inheritedFrom": "Link",
34418
- "inheritedPackage": "@salutejs/sdds-finai"
34419
- },
34420
- {
34421
- "name": "view",
34422
- "type": "\"clear\" | \"default\" | \"accent\" | \"positive\" | \"warning\" | \"negative\" | \"secondary\" | \"tertiary\" | \"paragraph\"",
34423
- "required": false,
34424
- "inheritedFrom": "Link",
34425
- "inheritedPackage": "@salutejs/sdds-finai"
34426
- }
34427
- ],
34428
34872
  "atomicMcpVersion": "0.360.0",
34429
34873
  "importPath": "@daisforge/ui/components/TableGlide",
34430
- "importStatement": "import { CanvasLink } from '@daisforge/ui/components/TableGlide';",
34431
- "minimalUsage": "<CanvasLink />",
34874
+ "importStatement": "import { CanvasText } from '@daisforge/ui/components/TableGlide';",
34875
+ "minimalUsage": "<CanvasText />",
34432
34876
  "examples": [
34433
34877
  {
34434
34878
  "exportName": "Usage1",
34435
- "displayName": "Использование в CanvasLink.stories.tsx",
34436
- "type": "usage",
34437
- "code": "<Canvas.Link\n view={row.view}\n href={href}\n target=\"_blank\"\n disabled={disabled}\n >\n {text}\n </Canvas.Link>",
34438
- "sourceFile": "packages/storybook/src/stories/TableCanvas/CanvasElements/CanvasLink/CanvasLink.stories.tsx"
34439
- },
34440
- {
34441
- "exportName": "Usage2",
34442
34879
  "displayName": "Использование в CanvasText.stories.tsx",
34443
34880
  "type": "usage",
34444
- "code": "<Canvas.Link>{row.shortName}</Canvas.Link>",
34881
+ "code": "<Canvas.Text\n color={color || theme.textDark}\n font={font || theme.baseFontStyle}\n wordWrap={wordWrap}\n overflow={overflow}\n textOverflow={textOverflow}\n ellipsis={ellipsis}\n maxLines={resolvedMaxLines}\n lineHeight={lineHeight}\n style={{ flexGrow: 1 }}\n autoTooltip={{\n enabled: true,\n }}\n >\n {row.id === 1 ? text : row.longText}\n </Canvas.Text>",
34445
34882
  "sourceFile": "packages/storybook/src/stories/TableCanvas/CanvasElements/CanvasText/CanvasText.stories.tsx"
34446
34883
  },
34447
34884
  {
34448
- "exportName": "Vendor1",
34449
- "displayName": "Использование Использование",
34450
- "type": "vendor",
34451
- "code": "import React from 'react';\nimport { TextS, Link } from '@daisforge/ui/components/TableGlide';\nexport function App() {\n return (\n <TextS>\n Скачайте <Link href=\"/\" target=\"_blank\">приложение.</Link>\n </TextS>\n );\n}"
34452
- },
34453
- {
34454
- "exportName": "Vendor2",
34455
- "displayName": "Подчёркивание Подчёркивание Prop underline управляет режимом подчёркивания ссылки",
34456
- "type": "vendor",
34457
- "code": "import React from 'react';\nimport { TextS, Link } from '@daisforge/ui/components/TableGlide';\nexport function App() {\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>\n <TextS><Link href=\"/\" underline=\"none\">Без подчёркивания</Link></TextS>\n <TextS><Link href=\"/\" underline=\"hover\">Подчёркивание при наведении</Link></TextS>\n <TextS><Link href=\"/\" underline=\"always\">Всегда подчёркнута</Link></TextS>\n </div>\n );\n}"
34885
+ "exportName": "Usage2",
34886
+ "displayName": "Использование в TableCanvasTooltip.stories.tsx",
34887
+ "type": "usage",
34888
+ "code": "<Canvas.Text\n overflow=\"hidden\"\n textOverflow=\"ellipsis\"\n autoTooltip\n style={{ flexGrow: 1 }}\n >\n {`${row.task}: ${longText}`}\n </Canvas.Text>",
34889
+ "sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.Tooltip/TableCanvasTooltip.stories.tsx"
34458
34890
  }
34459
34891
  ]
34460
34892
  },
@@ -35257,14 +35689,17 @@
35257
35689
  "relatedExports": [
35258
35690
  "CanvasContainer",
35259
35691
  "CanvasNode",
35692
+ "CanvasAvatar",
35693
+ "CanvasAvatarGroup",
35260
35694
  "CanvasBadge",
35261
35695
  "CanvasButton",
35262
35696
  "CanvasEmbedIconButton",
35263
35697
  "CanvasIcon",
35264
35698
  "CanvasIconButton",
35699
+ "CanvasImage",
35700
+ "CanvasLink",
35265
35701
  "CanvasRect",
35266
35702
  "CanvasText",
35267
- "CanvasLink",
35268
35703
  "Canvas",
35269
35704
  "RootBridge"
35270
35705
  ],
@@ -39360,7 +39795,7 @@
39360
39795
  "exportName": "Usage1",
39361
39796
  "displayName": "Использование в TourWidget.examples.tsx",
39362
39797
  "type": "usage",
39363
- "code": "<TourWidget.Bullets\n count={tourStepsCount}\n $css={{ marginInline: 'auto' }}\n />",
39798
+ "code": "<TourWidget.Bullets\n count={tourStepsCount}\n $css={{ marginInline: 'auto' }}\n />",
39364
39799
  "sourceFile": "packages/storybook/src/stories/TourWidget/TourWidget.examples.tsx"
39365
39800
  },
39366
39801
  {
@@ -39410,14 +39845,14 @@
39410
39845
  "exportName": "Usage1",
39411
39846
  "displayName": "Использование в TourWidget.examples.tsx",
39412
39847
  "type": "usage",
39413
- "code": "<TourWidget.Content>\n <MediaPlaceholder width={266} height={266} />\n </TourWidget.Content>",
39848
+ "code": "<TourWidget.Content>\n <MediaPlaceholder width={266} height={266} />\n </TourWidget.Content>",
39414
39849
  "sourceFile": "packages/storybook/src/stories/TourWidget/TourWidget.examples.tsx"
39415
39850
  },
39416
39851
  {
39417
39852
  "exportName": "Usage2",
39418
39853
  "displayName": "Использование в TourWidget.examples.tsx",
39419
39854
  "type": "usage",
39420
- "code": "<TourWidget.Content>\n <MediaPlaceholder width={240} height={240} />\n </TourWidget.Content>",
39855
+ "code": "<TourWidget.Content>\n <MediaPlaceholder width={240} height={240} />\n </TourWidget.Content>",
39421
39856
  "sourceFile": "packages/storybook/src/stories/TourWidget/TourWidget.examples.tsx"
39422
39857
  }
39423
39858
  ]
@@ -39460,14 +39895,14 @@
39460
39895
  "exportName": "Usage1",
39461
39896
  "displayName": "Использование в TourWidget.examples.tsx",
39462
39897
  "type": "usage",
39463
- "code": "<TourWidget.Footer>\n <Box\n $css={{\n display: 'flex',\n flexDirection: 'column',\n }}\n >\n <TourWidget.Bullets\n count={tourStepsCount}\n $css={{ marginInline: 'auto' }}\n />\n <Box\n $css={{\n display: 'flex',\n flexDirection: 'row',\n gap: '4px',\n marginTop: '20px',\n }}\n >\n <Button\n size=\"s\"\n stretching=\"filled\"\n view=\"secondary\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current - 1, tourStepsCount),\n )\n }\n >\n Назад\n </Button>\n <Button\n stretching=\"filled\"\n size=\"s\"\n view=\"white\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current + 1, tourStepsCount),\n )\n }\n >\n Далее\n </Button>\n </Box>\n <LinkButton\n size=\"s\"\n view=\"default\"\n onClick={() => setActiveStepIndex(0)}\n >\n Пропустить всё\n </LinkButton>\n </Box>\n </TourWidget.Footer>",
39898
+ "code": "<TourWidget.Footer>\n <Box\n $css={{\n display: 'flex',\n flexDirection: 'column',\n }}\n >\n <TourWidget.Bullets\n count={tourStepsCount}\n $css={{ marginInline: 'auto' }}\n />\n <Box\n $css={{\n display: 'flex',\n flexDirection: 'row',\n gap: '4px',\n marginTop: '20px',\n }}\n >\n <Button\n size=\"s\"\n stretching=\"filled\"\n view=\"secondary\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current - 1, tourStepsCount),\n )\n }\n >\n Назад\n </Button>\n <Button\n stretching=\"filled\"\n size=\"s\"\n view=\"default\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current + 1, tourStepsCount),\n )\n }\n >\n Далее\n </Button>\n </Box>\n <LinkButton\n size=\"s\"\n view=\"default\"\n onClick={() => setActiveStepIndex(0)}\n >\n Пропустить всё\n </LinkButton>\n </Box>\n </TourWidget.Footer>",
39464
39899
  "sourceFile": "packages/storybook/src/stories/TourWidget/TourWidget.examples.tsx"
39465
39900
  },
39466
39901
  {
39467
39902
  "exportName": "Usage2",
39468
39903
  "displayName": "Использование в TourWidget.examples.tsx",
39469
39904
  "type": "usage",
39470
- "code": "<TourWidget.Footer>\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: '32px',\n width: '100%',\n }}\n >\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n gap: '32px',\n minWidth: 0,\n }}\n >\n <LinkButton\n size=\"s\"\n view=\"default\"\n onClick={() => setActiveStepIndex(0)}\n >\n Пропустить всё\n </LinkButton>\n <TourWidget.Bullets count={tourStepsCount} />\n </Box>\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n }}\n >\n <Button\n size=\"s\"\n view=\"secondary\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current - 1, tourStepsCount),\n )\n }\n >\n Назад\n </Button>\n <Button\n size=\"s\"\n view=\"white\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current + 1, tourStepsCount),\n )\n }\n >\n Далее\n </Button>\n </Box>\n </Box>\n </TourWidget.Footer>",
39905
+ "code": "<TourWidget.Footer>\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: '32px',\n width: '100%',\n }}\n >\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n gap: '32px',\n minWidth: 0,\n }}\n >\n <LinkButton\n size=\"s\"\n view=\"default\"\n onClick={() => setActiveStepIndex(0)}\n >\n Пропустить всё\n </LinkButton>\n <TourWidget.Bullets count={tourStepsCount} />\n </Box>\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n }}\n >\n <Button\n size=\"s\"\n view=\"secondary\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current - 1, tourStepsCount),\n )\n }\n >\n Назад\n </Button>\n <Button\n size=\"s\"\n view=\"default\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current + 1, tourStepsCount),\n )\n }\n >\n Далее\n </Button>\n </Box>\n </Box>\n </TourWidget.Footer>",
39471
39906
  "sourceFile": "packages/storybook/src/stories/TourWidget/TourWidget.examples.tsx"
39472
39907
  }
39473
39908
  ]
@@ -39529,7 +39964,7 @@
39529
39964
  "exportName": "Usage2",
39530
39965
  "displayName": "Использование в TourWidget.examples.tsx",
39531
39966
  "type": "usage",
39532
- "code": "<TourWidget.Header\n title={'Знакомьтесь:\\nновые возможности'}\n description={\n 'Режимы просмотра\\nОбщий реестр — все пилоты со статусом «В реестре»\\n• Мои пилоты — только ваши проекты, включая черновики'\n }\n />",
39967
+ "code": "<TourWidget.Header\n title={'Знакомьтесь:\\nновые возможности'}\n description={\n 'Режимы просмотра\\nОбщий реестр — все пилоты со статусом «В реестре»\\n• Мои пилоты — только ваши проекты, включая черновики'\n }\n />",
39533
39968
  "sourceFile": "packages/storybook/src/stories/TourWidget/TourWidget.examples.tsx"
39534
39969
  }
39535
39970
  ]
@@ -39662,44 +40097,44 @@
39662
40097
  "онбординг",
39663
40098
  "степ-виджет"
39664
40099
  ],
39665
- "docs": "# TourWidget\n\n`TourWidget` — локальная compound-обертка для карточки тура. Компонент отвечает за внешний вид, раскладку, фон, буллеты и пульсацию через mixin, но не управляет сценарием тура, переходами между шагами и позиционированием относительно target-элемента.\n\n## Ключевые особенности\n\n- Две ориентации: `vertical` и `horizontal`.\n- Compound API: `TourWidget.Header`, `TourWidget.Content`, `TourWidget.Footer`, `TourWidget.Bullets`, `TourWidget.Bullet`.\n- Заголовок и описание сохраняют переводы строк `\\n` (`white-space: pre-line`); повторяющиеся пробелы схлопываются, автоматический перенос по ширине сохраняется.\n- Активный шаг передается в `TourWidget` через `activeStepIndex`, а `Bullet` читает его автоматически.\n- `Content` не фиксирует размер вложенного элемента и дает ему занять `100%`.\n- `$css` есть у корневого компонента и compound-частей для локального переопределения стилей.\n- Пульсация вынесена в `tourPulseMixin` и применяется отдельно к target-элементу.\n\n## Использование\n\n```tsx\n\n```\n\nБазовая схема работы:\n\n```tsx\nconst [activeStepIndex, setActiveStepIndex] = useState(0);\n\n<ViewContainer view=\"onDark\">\n <TourWidget\n activeStepIndex={activeStepIndex}\n $css={{ width: '286px', height: '480px' }}\n >\n <TourWidget.Content>\n <Box as=\"img\" src={imageSrc} alt=\"\" $css={{ width: '100%' }} />\n </TourWidget.Content>\n <TourWidget.Header title=\"Title\" description=\"Description\" />\n <TourWidget.Footer>\n <TourWidget.Bullets count={steps.length} />\n <Button onClick={() => setActiveStepIndex((step) => step + 1)}>\n Далее\n </Button>\n </TourWidget.Footer>\n </TourWidget>\n</ViewContainer>;\n```\n\n## Compound-компоненты\n\n- `TourWidget.Header` — выводит `title`, `description` и дополнительные `children`.\n- `TourWidget.Content` — область под изображение, видео, иллюстрацию или любой ReactNode.\n- `TourWidget.Footer` — произвольная зона для кнопок, ссылки пропуска и буллетов.\n- `TourWidget.Bullets` — контейнер, который рисует массив буллетов по `count`; если буллетов больше семи, отображает окно максимум на 7 точек, прокручивает его по `activeStepIndex`, а крайние видимые точки уменьшаются до `6px`, когда за ними есть скрытые шаги.\n- `TourWidget.Bullet` — низкоуровневый визуальный индикатор шага. Активность считается как `active ?? index === activeStepIndex`.\n\n## Правильная композиция\n\n`TourWidget.Header`, `TourWidget.Content` и `TourWidget.Footer` нужно вкладывать напрямую в `TourWidget`. Компонент использует эти части как слоты: так он понимает, есть ли в туре медиа-зона, и выбирает корректную раскладку для `horizontal` и `vertical`.\n\nПравильно:\n\n```tsx\n<TourWidget orientation=\"horizontal\">\n <TourWidget.Content>\n <Box as=\"img\" src={imageSrc} alt=\"\" $css={{ width: '100%' }} />\n </TourWidget.Content>\n <TourWidget.Header title=\"Title\" description=\"Description\" />\n <TourWidget.Footer>\n <TourWidget.Bullets count={steps.length} />\n </TourWidget.Footer>\n</TourWidget>\n```\n\nЕсли нужен свой wrapper для картинки, кнопок или текста, размещайте его внутри соответствующего slot-компонента.\n\n```tsx\n<TourWidget orientation=\"horizontal\">\n <TourWidget.Content>\n <MyImageWrapper>\n <Box as=\"img\" src={imageSrc} alt=\"\" />\n </MyImageWrapper>\n </TourWidget.Content>\n <TourWidget.Header>\n <MyHeaderContent />\n </TourWidget.Header>\n <TourWidget.Footer>\n <MyFooterContent />\n </TourWidget.Footer>\n</TourWidget>\n```\n\nНе оборачивайте сам `TourWidget.Content` во внешний компонент. В таком случае `TourWidget` не сможет определить медиа-зону как свой прямой slot и горизонтальная раскладка будет работать как вариант без `Content`.\n\n```tsx\n<TourWidget orientation=\"horizontal\">\n <MyContentWrapper>\n <TourWidget.Content>\n <Box as=\"img\" src={imageSrc} alt=\"\" />\n </TourWidget.Content>\n </MyContentWrapper>\n <TourWidget.Header title=\"Title\" />\n <TourWidget.Footer />\n</TourWidget>\n```\n\n## Активный шаг\n\n`activeStepIndex` хранится на корневом `TourWidget`. Внутри компонент создает локальный context, поэтому не нужно импортировать `Provider` или прокидывать `active` в каждый буллет.\n\n```tsx\n<TourWidget activeStepIndex={5}>\n <TourWidget.Footer>\n <TourWidget.Bullets count={10} />\n </TourWidget.Footer>\n</TourWidget>\n```\n\nДля переключения шагов используйте свои кнопки или другой внешний контрол. `TourWidget.Bullets` не кликабельный и только отображает `activeStepIndex`.\n\n```tsx\n<TourWidget activeStepIndex={activeStepIndex}>\n <TourWidget.Footer>\n <TourWidget.Bullets count={10} />\n <Button onClick={() => setActiveStepIndex((step) => step + 1)}>\n Далее\n </Button>\n </TourWidget.Footer>\n</TourWidget>\n```\n\nЕсли нужна полностью ручная раскладка или состояние отдельной точки, используйте низкоуровневый `TourWidget.Bullet` и передайте `active`.\n\n## Content\n\n`TourWidget.Content` не задает жесткий размер медиа. Размер определяет вложенная нода или стиль самого `Content`.\n\n```tsx\n<TourWidget.Content>\n <Box\n as=\"img\"\n src={imageSrc}\n alt=\"\"\n $css={{ width: '270px', height: '270px' }}\n />\n</TourWidget.Content>\n```\n\n## Пульсация\n\nПульсация не встроена в `TourWidget`, потому что target-элемент и позиционирование тура контролируются снаружи. Для target используется `tourPulseMixin`.\n\n```tsx\n\nconst Target = styled(Box)`\n position: relative;\n\n &::after {\n content: '';\n position: absolute;\n ${tourPulseMixin()}\n }\n`;\n```\n\nПо умолчанию `tourPulseMixin` сам задает `inset: -4px` и `border-radius: 16px` и не добавляет заливку на target.\n\n## Темная тема\n\n`TourWidget` всегда используется на темной поверхности. Если внутри футера есть SDDS-кнопки или ссылки, оборачивайте композицию в `ViewContainer view=\"onDark\"`, чтобы вложенные controls взяли on-dark токены без ручных переопределений цвета.\n\n```tsx\n<ViewContainer view=\"onDark\">\n <TourWidget activeStepIndex={activeStepIndex}>\n <TourWidget.Footer>\n <Button view=\"secondary\">Назад</Button>\n <Button view=\"white\">Далее</Button>\n </TourWidget.Footer>\n </TourWidget>\n</ViewContainer>\n```\n\n## CSS-переменные\n\nКорневой `$css` можно использовать для точечной настройки внешнего вида.\n\n```tsx\n<TourWidget\n $css={{\n '--tour-widget-min-width': '0',\n '--tour-widget-border-radius': '16px',\n '--tour-widget-gradient-frame-height': '34%',\n '--tour-widget-gradient-frame-fade': '56%',\n }}\n/>\n```\n\n## Особенности\n\n- `TourWidget` не содержит positioner и не добавляет зависимость на `floating-ui`.\n- Компонент не хранит шаги и не переключает их сам, только отображает `activeStepIndex`.\n- `TourWidget.Bullet` — это span-индикатор, а не интерактивная кнопка.\n- `TourWidget.Bullets` — это div-viewport со сдвигающимся треком точек; при `count > 7` видны максимум семь буллетов.\n\nОписание типов — в разделе [API](?path=/docs/локальные-компоненты-tourwidget-api--docs).",
39666
- "apiDocs": "# TourWidget API\n\n## TourWidgetOrientation\n\n```typescript\ntype TourWidgetOrientation = 'vertical' | 'horizontal';\n```\n\n## TourWidgetCss\n\n```typescript\ntype TourWidgetCss = string | CSSObject | FlattenSimpleInterpolation;\n```\n\n## TourWidgetProps\n\n```typescript\ntype TourWidgetProps = ComponentPropsWithoutRef<'div'> & {\n /**\n * @default 'vertical'\n */\n orientation?: TourWidgetOrientation;\n /**\n * Активный шаг тура. Нумерация с нуля.\n */\n activeStepIndex?: number;\n $css?: TourWidgetCss;\n};\n```\n\n## TourWidget.Header\n\n```typescript\ntype TourWidgetHeaderProps = Omit<\n ComponentPropsWithoutRef<'div'>,\n 'title'\n> & {\n title?: ReactNode;\n description?: ReactNode;\n $css?: TourWidgetCss;\n};\n```\n\n## TourWidget.Content\n\n```typescript\ntype TourWidgetContentProps = ComponentPropsWithoutRef<'div'> & {\n children?: ReactNode;\n $css?: TourWidgetCss;\n};\n```\n\n## TourWidget.Footer\n\n```typescript\ntype TourWidgetFooterProps = ComponentPropsWithoutRef<'div'> & {\n children?: ReactNode;\n $css?: TourWidgetCss;\n};\n```\n\n## TourWidget.Bullets\n\n```typescript\ntype TourWidgetBulletsProps = Omit<\n ComponentPropsWithoutRef<'div'>,\n 'children' | 'onClick'\n> & {\n count: number;\n $css?: TourWidgetCss;\n};\n```\n\n## TourWidget.Bullet\n\n```typescript\ntype TourWidgetBulletProps = Omit<\n ComponentPropsWithoutRef<'span'>,\n 'onClick'\n> & {\n /**\n * Индекс буллета. Сравнивается с `TourWidget.activeStepIndex`.\n */\n index?: number;\n /**\n * Ручное переопределение активного состояния.\n */\n active?: boolean;\n $css?: TourWidgetCss;\n};\n```",
40100
+ "docs": "# TourWidget\n\n`TourWidget` — локальная compound-обертка для карточки тура. Компонент отвечает за внешний вид, раскладку, фон, буллеты и пульсацию через mixin, но не управляет сценарием тура, переходами между шагами и позиционированием относительно target-элемента.\n\n## Ключевые особенности\n\n- Две ориентации: `vertical` и `horizontal`.\n- Compound API: `TourWidget.Header`, `TourWidget.Content`, `TourWidget.Footer`, `TourWidget.Bullets`, `TourWidget.Bullet`.\n- Заголовок и описание сохраняют переводы строк `\\n` (`white-space: pre-line`); повторяющиеся пробелы схлопываются, автоматический перенос по ширине сохраняется.\n- Активный шаг передается в `TourWidget` через `activeStepIndex`, а `Bullet` читает его автоматически.\n- `Content` не фиксирует размер вложенного элемента и дает ему занять `100%`.\n- `$css` есть у корневого компонента и compound-частей для локального переопределения стилей.\n- Пульсация вынесена в `tourPulseMixin` и применяется отдельно к target-элементу.\n\n## Использование\n\n```tsx\n\n```\n\nБазовая схема работы:\n\n```tsx\nconst [activeStepIndex, setActiveStepIndex] = useState(0);\n\n<TourWidget activeStepIndex={activeStepIndex} $css={{ width: '306px' }}>\n <TourWidget.Content>\n <Box as=\"img\" src={imageSrc} alt=\"\" $css={{ width: '100%' }} />\n </TourWidget.Content>\n <TourWidget.Header title=\"Title\" description=\"Description\" />\n <TourWidget.Footer>\n <TourWidget.Bullets count={steps.length} />\n <Button onClick={() => setActiveStepIndex((step) => step + 1)}>\n Далее\n </Button>\n </TourWidget.Footer>\n</TourWidget>;\n```\n\n## Compound-компоненты\n\n- `TourWidget.Header` — выводит `title`, `description` и дополнительные `children`.\n- `TourWidget.Content` — область под изображение, видео, иллюстрацию или любой ReactNode.\n- `TourWidget.Footer` — произвольная зона для кнопок, ссылки пропуска и буллетов.\n- `TourWidget.Bullets` — контейнер, который рисует массив буллетов по `count`; если буллетов больше семи, отображает окно максимум на 7 точек, прокручивает его по `activeStepIndex`, а крайние видимые точки уменьшаются до `6px`, когда за ними есть скрытые шаги.\n- `TourWidget.Bullet` — низкоуровневый визуальный индикатор шага. Активность считается как `active ?? index === activeStepIndex`.\n\n## Правильная композиция\n\n`TourWidget.Header`, `TourWidget.Content` и `TourWidget.Footer` нужно вкладывать напрямую в `TourWidget`. Компонент использует эти части как слоты: так он понимает, есть ли в туре медиа-зона, и выбирает корректную раскладку для `horizontal` и `vertical`.\n\nПравильно:\n\n```tsx\n<TourWidget orientation=\"horizontal\">\n <TourWidget.Content>\n <Box as=\"img\" src={imageSrc} alt=\"\" $css={{ width: '100%' }} />\n </TourWidget.Content>\n <TourWidget.Header title=\"Title\" description=\"Description\" />\n <TourWidget.Footer>\n <TourWidget.Bullets count={steps.length} />\n </TourWidget.Footer>\n</TourWidget>\n```\n\nЕсли нужен свой wrapper для картинки, кнопок или текста, размещайте его внутри соответствующего slot-компонента.\n\n```tsx\n<TourWidget orientation=\"horizontal\">\n <TourWidget.Content>\n <MyImageWrapper>\n <Box as=\"img\" src={imageSrc} alt=\"\" />\n </MyImageWrapper>\n </TourWidget.Content>\n <TourWidget.Header>\n <MyHeaderContent />\n </TourWidget.Header>\n <TourWidget.Footer>\n <MyFooterContent />\n </TourWidget.Footer>\n</TourWidget>\n```\n\nНе оборачивайте сам `TourWidget.Content` во внешний компонент. В таком случае `TourWidget` не сможет определить медиа-зону как свой прямой slot и горизонтальная раскладка будет работать как вариант без `Content`.\n\n```tsx\n<TourWidget orientation=\"horizontal\">\n <MyContentWrapper>\n <TourWidget.Content>\n <Box as=\"img\" src={imageSrc} alt=\"\" />\n </TourWidget.Content>\n </MyContentWrapper>\n <TourWidget.Header title=\"Title\" />\n <TourWidget.Footer />\n</TourWidget>\n```\n\n## Активный шаг\n\n`activeStepIndex` хранится на корневом `TourWidget`. Внутри компонент создает локальный context, поэтому не нужно импортировать `Provider` или прокидывать `active` в каждый буллет.\n\n```tsx\n<TourWidget activeStepIndex={5}>\n <TourWidget.Footer>\n <TourWidget.Bullets count={10} />\n </TourWidget.Footer>\n</TourWidget>\n```\n\nДля переключения шагов используйте свои кнопки или другой внешний контрол. `TourWidget.Bullets` не кликабельный и только отображает `activeStepIndex`.\n\n```tsx\n<TourWidget activeStepIndex={activeStepIndex}>\n <TourWidget.Footer>\n <TourWidget.Bullets count={10} />\n <Button onClick={() => setActiveStepIndex((step) => step + 1)}>\n Далее\n </Button>\n </TourWidget.Footer>\n</TourWidget>\n```\n\nЕсли нужна полностью ручная раскладка или состояние отдельной точки, используйте низкоуровневый `TourWidget.Bullet` и передайте `active`.\n\n## Content\n\n`TourWidget.Content` не задает жесткий размер медиа. Размер определяет вложенная нода или стиль самого `Content`.\n\n```tsx\n<TourWidget.Content>\n <Box\n as=\"img\"\n src={imageSrc}\n alt=\"\"\n $css={{ width: '270px', height: '270px' }}\n />\n</TourWidget.Content>\n```\n\n## Пульсация\n\nПульсация не встроена в `TourWidget`, потому что target-элемент и позиционирование тура контролируются снаружи. Для target используется `tourPulseMixin`.\n\n```tsx\n\nconst Target = styled(Box)`\n position: relative;\n\n &::after {\n content: '';\n position: absolute;\n ${tourPulseMixin()}\n }\n`;\n```\n\nПо умолчанию `tourPulseMixin` сам задает `inset: -4px` и `border-radius: 16px` и не добавляет заливку на target.\n\n## Темы\n\n`TourWidget` автоматически использует глобальную тему приложения.\n\n## CSS-переменные\n\nКорневой `$css` можно использовать для точечной настройки внешнего вида.\n\n```tsx\n\n<TourWidget\n $css={{\n [tourWidgetTokens.minWidth]: '0',\n [tourWidgetTokens.borderRadius]: '16px',\n [tourWidgetTokens.gradientFrameHeight]: '34%',\n [tourWidgetTokens.gradientFrameFade]: '56%',\n }}\n/>;\n```\n\n## Особенности\n\n- `TourWidget` не содержит positioner и не добавляет зависимость на `floating-ui`.\n- Компонент не хранит шаги и не переключает их сам, только отображает `activeStepIndex`.\n- `TourWidget.Bullet` — это span-индикатор, а не интерактивная кнопка.\n- `TourWidget.Bullets` — это div-viewport со сдвигающимся треком точек; при `count > 7` видны максимум семь буллетов.\n\nОписание типов — в разделе [API](?path=/docs/локальные-компоненты-tourwidget-api--docs).",
40101
+ "apiDocs": "# TourWidget API\n\n## TourWidgetOrientation\n\n```typescript\ntype TourWidgetOrientation = 'vertical' | 'horizontal';\n```\n\n## TourWidgetCss\n\n```typescript\ntype TourWidgetCss = string | CSSObject | FlattenSimpleInterpolation;\n```\n\n## TourWidgetProps\n\n```typescript\ntype TourWidgetProps = ComponentPropsWithoutRef<'div'> & {\n /**\n * @default 'vertical'\n */\n orientation?: TourWidgetOrientation;\n /**\n * Активный шаг тура. Нумерация с нуля.\n */\n activeStepIndex?: number;\n $css?: TourWidgetCss;\n};\n```\n\n## TourWidget.Header\n\n```typescript\ntype TourWidgetHeaderProps = Omit<\n ComponentPropsWithoutRef<'div'>,\n 'title'\n> & {\n title?: ReactNode;\n description?: ReactNode;\n $css?: TourWidgetCss;\n};\n```\n\n## TourWidget.Content\n\n```typescript\ntype TourWidgetContentProps = ComponentPropsWithoutRef<'div'> & {\n children?: ReactNode;\n $css?: TourWidgetCss;\n};\n```\n\n## TourWidget.Footer\n\n```typescript\ntype TourWidgetFooterProps = ComponentPropsWithoutRef<'div'> & {\n children?: ReactNode;\n $css?: TourWidgetCss;\n};\n```\n\n## TourWidget.Bullets\n\n```typescript\ntype TourWidgetBulletsProps = Omit<\n ComponentPropsWithoutRef<'div'>,\n 'children' | 'onClick'\n> & {\n count: number;\n $css?: TourWidgetCss;\n};\n```\n\n## TourWidget.Bullet\n\n```typescript\ntype TourWidgetBulletProps = Omit<\n ComponentPropsWithoutRef<'span'>,\n 'onClick'\n> & {\n /**\n * Индекс буллета. Сравнивается с `TourWidget.activeStepIndex`.\n */\n index?: number;\n /**\n * Ручное переопределение активного состояния.\n */\n active?: boolean;\n $css?: TourWidgetCss;\n};\n```\n\n## tourWidgetTokens\n\n```typescript\nexport const tourWidgetTokens = {\n background: '--tour-widget-background',\n borderRadius: '--tour-widget-border-radius',\n bulletActiveBackground: '--tour-widget-bullet-active-background',\n bulletBackground: '--tour-widget-bullet-background',\n bulletsOffset: '--tour-widget-bullets-offset',\n bulletsWidth: '--tour-widget-bullets-width',\n contentBorderRadius: '--tour-widget-content-border-radius',\n gradientBackground: '--tour-widget-gradient-background',\n gradientBlur: '--tour-widget-gradient-blur',\n gradientFrameBottom: '--tour-widget-gradient-frame-bottom',\n gradientFrameFade: '--tour-widget-gradient-frame-fade',\n gradientFrameHeight: '--tour-widget-gradient-frame-height',\n gradientFrameLeft: '--tour-widget-gradient-frame-left',\n gradientFrameRight: '--tour-widget-gradient-frame-right',\n gradientHeight: '--tour-widget-gradient-height',\n gradientLeft: '--tour-widget-gradient-left',\n gradientOpacity: '--tour-widget-gradient-opacity',\n gradientTop: '--tour-widget-gradient-top',\n gradientWidth: '--tour-widget-gradient-width',\n inlineOvalDisplay: '--tour-widget-inline-oval-display',\n minWidth: '--tour-widget-min-width',\n ovalBackground: '--tour-widget-oval-background',\n ovalBlur: '--tour-widget-oval-blur',\n ovalBorderRadius: '--tour-widget-oval-border-radius',\n ovalFrameDisplay: '--tour-widget-oval-frame-display',\n ovalFrameHeight: '--tour-widget-oval-frame-height',\n ovalHeight: '--tour-widget-oval-height',\n ovalLeft: '--tour-widget-oval-left',\n ovalOpacity: '--tour-widget-oval-opacity',\n ovalTop: '--tour-widget-oval-top',\n ovalWidth: '--tour-widget-oval-width',\n shapeGradientMaskMiddle: '--tour-widget-shape-gradient-mask-middle',\n shapeGradientMaskStart: '--tour-widget-shape-gradient-mask-start',\n shapeGradientOpacity: '--tour-widget-shape-gradient-opacity',\n shapeGradientPathOpacity: '--tour-widget-shape-gradient-path-opacity',\n themeBackground: '--tour-widget-theme-background',\n themeGradientHorizontal: '--tour-widget-theme-gradient-horizontal',\n themeGradientHorizontalBlur: '--tour-widget-theme-gradient-horizontal-blur',\n themeGradientOpacity: '--tour-widget-theme-gradient-opacity',\n themeGradientVertical: '--tour-widget-theme-gradient-vertical',\n themeGradientVerticalBlur: '--tour-widget-theme-gradient-vertical-blur',\n themeOvalBackground: '--tour-widget-theme-oval-background',\n themeOvalHorizontalBlur: '--tour-widget-theme-oval-horizontal-blur',\n themeOvalHorizontalOpacity: '--tour-widget-theme-oval-horizontal-opacity',\n themeOvalVerticalBlur: '--tour-widget-theme-oval-vertical-blur',\n themeOvalVerticalOpacity: '--tour-widget-theme-oval-vertical-opacity',\n themeShapeEnd: '--tour-widget-theme-shape-end',\n themeShapeMiddle: '--tour-widget-theme-shape-middle',\n themeShapeOpacity: '--tour-widget-theme-shape-opacity',\n themeShapeStart: '--tour-widget-theme-shape-start',\n} as const;\n```",
39667
40102
  "curatedStories": [
39668
40103
  {
39669
40104
  "exportName": "Vertical",
39670
40105
  "displayName": "Вертикальный тур",
39671
40106
  "type": "full-code",
39672
- "code": "function VerticalExample() {\n const tourStepsCount = 14;\n const [activeStepIndex, setActiveStepIndex] = useState(0);\n\n return (\n <TourView>\n <TourWidget\n activeStepIndex={activeStepIndex}\n $css={{ width: '286px', height: '480px' }}\n >\n <TourWidget.Content>\n <MediaPlaceholder width={266} height={266} />\n </TourWidget.Content>\n <TourWidget.Header title=\"Title\" />\n <TourWidget.Footer>\n <Box\n $css={{\n display: 'flex',\n flexDirection: 'column',\n }}\n >\n <TourWidget.Bullets\n count={tourStepsCount}\n $css={{ marginInline: 'auto' }}\n />\n <Box\n $css={{\n display: 'flex',\n flexDirection: 'row',\n gap: '4px',\n marginTop: '20px',\n }}\n >\n <Button\n size=\"s\"\n stretching=\"filled\"\n view=\"secondary\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current - 1, tourStepsCount),\n )\n }\n >\n Назад\n </Button>\n <Button\n stretching=\"filled\"\n size=\"s\"\n view=\"white\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current + 1, tourStepsCount),\n )\n }\n >\n Далее\n </Button>\n </Box>\n <LinkButton\n size=\"s\"\n view=\"default\"\n onClick={() => setActiveStepIndex(0)}\n >\n Пропустить всё\n </LinkButton>\n </Box>\n </TourWidget.Footer>\n </TourWidget>\n </TourView>\n );\n};"
40107
+ "code": "function VerticalExample() {\n const tourStepsCount = 14;\n const [activeStepIndex, setActiveStepIndex] = useState(0);\n\n return (\n <TourWidget activeStepIndex={activeStepIndex} $css={{ width: '298px' }}>\n <TourWidget.Content>\n <MediaPlaceholder width={266} height={266} />\n </TourWidget.Content>\n <TourWidget.Header title=\"Title\" description=\"Description\" />\n <TourWidget.Footer>\n <Box\n $css={{\n display: 'flex',\n flexDirection: 'column',\n }}\n >\n <TourWidget.Bullets\n count={tourStepsCount}\n $css={{ marginInline: 'auto' }}\n />\n <Box\n $css={{\n display: 'flex',\n flexDirection: 'row',\n gap: '4px',\n marginTop: '20px',\n }}\n >\n <Button\n size=\"s\"\n stretching=\"filled\"\n view=\"secondary\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current - 1, tourStepsCount),\n )\n }\n >\n Назад\n </Button>\n <Button\n stretching=\"filled\"\n size=\"s\"\n view=\"default\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current + 1, tourStepsCount),\n )\n }\n >\n Далее\n </Button>\n </Box>\n <LinkButton\n size=\"s\"\n view=\"default\"\n onClick={() => setActiveStepIndex(0)}\n >\n Пропустить всё\n </LinkButton>\n </Box>\n </TourWidget.Footer>\n </TourWidget>\n );\n};"
39673
40108
  },
39674
40109
  {
39675
40110
  "exportName": "Horizontal",
39676
40111
  "displayName": "Горизонтальный тур",
39677
40112
  "type": "full-code",
39678
- "code": "function HorizontalExample() {\n const tourStepsCount = 14;\n const [activeStepIndex, setActiveStepIndex] = useState(5);\n\n return (\n <TourView>\n <TourWidget\n orientation=\"horizontal\"\n activeStepIndex={activeStepIndex}\n $css={{ width: '720px', height: '260px' }}\n >\n <TourWidget.Content>\n <MediaPlaceholder width={240} height={240} />\n </TourWidget.Content>\n <TourWidget.Header title=\"Title\" description=\"Description\" />\n <TourWidget.Footer>\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: '32px',\n width: '100%',\n }}\n >\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n gap: '32px',\n minWidth: 0,\n }}\n >\n <LinkButton\n size=\"s\"\n view=\"default\"\n onClick={() => setActiveStepIndex(0)}\n >\n Пропустить всё\n </LinkButton>\n <TourWidget.Bullets count={tourStepsCount} />\n </Box>\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n }}\n >\n <Button\n size=\"s\"\n view=\"secondary\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current - 1, tourStepsCount),\n )\n }\n >\n Назад\n </Button>\n <Button\n size=\"s\"\n view=\"white\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current + 1, tourStepsCount),\n )\n }\n >\n Далее\n </Button>\n </Box>\n </Box>\n </TourWidget.Footer>\n </TourWidget>\n </TourView>\n );\n};"
40113
+ "code": "function HorizontalExample() {\n const tourStepsCount = 14;\n const [activeStepIndex, setActiveStepIndex] = useState(5);\n\n return (\n <TourWidget\n orientation=\"horizontal\"\n activeStepIndex={activeStepIndex}\n $css={{ width: '732px', height: '272px' }}\n >\n <TourWidget.Content>\n <MediaPlaceholder width={240} height={240} />\n </TourWidget.Content>\n <TourWidget.Header title=\"Title\" description=\"Description\" />\n <TourWidget.Footer>\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: '32px',\n width: '100%',\n }}\n >\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n gap: '32px',\n minWidth: 0,\n }}\n >\n <LinkButton\n size=\"s\"\n view=\"default\"\n onClick={() => setActiveStepIndex(0)}\n >\n Пропустить всё\n </LinkButton>\n <TourWidget.Bullets count={tourStepsCount} />\n </Box>\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n }}\n >\n <Button\n size=\"s\"\n view=\"secondary\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current - 1, tourStepsCount),\n )\n }\n >\n Назад\n </Button>\n <Button\n size=\"s\"\n view=\"default\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current + 1, tourStepsCount),\n )\n }\n >\n Далее\n </Button>\n </Box>\n </Box>\n </TourWidget.Footer>\n </TourWidget>\n );\n};"
39679
40114
  },
39680
40115
  {
39681
40116
  "exportName": "LineBreaks",
39682
40117
  "displayName": "Переносы строк",
39683
40118
  "type": "full-code",
39684
- "code": "function LineBreaksExample() {\n return (\n <TourView>\n <TourWidget $css={{ width: '320px', paddingBottom: '24px' }}>\n <TourWidget.Header\n title={'Знакомьтесь:\\nновые возможности'}\n description={\n 'Режимы просмотра\\nОбщий реестр — все пилоты со статусом «В реестре»\\n• Мои пилоты — только ваши проекты, включая черновики'\n }\n />\n </TourWidget>\n </TourView>\n );\n};"
40119
+ "code": "function LineBreaksExample() {\n return (\n <TourWidget $css={{ width: '340px', paddingBottom: '24px' }}>\n <TourWidget.Header\n title={'Знакомьтесь:\\nновые возможности'}\n description={\n 'Режимы просмотра\\nОбщий реестр — все пилоты со статусом «В реестре»\\n• Мои пилоты — только ваши проекты, включая черновики'\n }\n />\n </TourWidget>\n );\n};"
39685
40120
  },
39686
40121
  {
39687
40122
  "exportName": "TourWithPulse",
39688
40123
  "displayName": "Тур рядом с пульсацией",
39689
40124
  "type": "full-code",
39690
- "code": "function TourWithPulseExample() {\n const tourStepsCount = 14;\n const [activeStepIndex, setActiveStepIndex] = useState(2);\n\n return (\n <TourView>\n <Box\n $css={{\n display: 'grid',\n gridTemplateColumns: '220px minmax(0, max-content)',\n gap: '14px',\n alignItems: 'center',\n }}\n >\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n minHeight: '300px',\n }}\n >\n <PulseTarget />\n </Box>\n <TourWidget\n orientation=\"horizontal\"\n activeStepIndex={activeStepIndex}\n $css={{ width: '720px', height: '264px' }}\n >\n <TourWidget.Content>\n <MediaPlaceholder width={240} height={240} />\n </TourWidget.Content>\n <TourWidget.Header title=\"Title\" description=\"Description\" />\n <TourWidget.Footer>\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: '32px',\n width: '100%',\n }}\n >\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n gap: '32px',\n minWidth: 0,\n }}\n >\n <LinkButton\n size=\"s\"\n view=\"default\"\n onClick={() => setActiveStepIndex(0)}\n >\n Пропустить всё\n </LinkButton>\n <TourWidget.Bullets count={tourStepsCount} />\n </Box>\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n }}\n >\n <Button\n size=\"s\"\n view=\"secondary\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current - 1, tourStepsCount),\n )\n }\n >\n Назад\n </Button>\n <Button\n size=\"s\"\n view=\"white\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current + 1, tourStepsCount),\n )\n }\n >\n Далее\n </Button>\n </Box>\n </Box>\n </TourWidget.Footer>\n </TourWidget>\n </Box>\n </TourView>\n );\n};"
40125
+ "code": "function TourWithPulseExample() {\n const tourStepsCount = 14;\n const [activeStepIndex, setActiveStepIndex] = useState(2);\n\n return (\n <Box\n $css={{\n display: 'grid',\n gridTemplateColumns: '220px minmax(0, max-content)',\n gap: '14px',\n alignItems: 'center',\n }}\n >\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n minHeight: '300px',\n }}\n >\n <PulseTarget />\n </Box>\n <TourWidget\n orientation=\"horizontal\"\n activeStepIndex={activeStepIndex}\n $css={{ width: '732px', height: '272px' }}\n >\n <TourWidget.Content>\n <MediaPlaceholder width={240} height={240} />\n </TourWidget.Content>\n <TourWidget.Header title=\"Title\" description=\"Description\" />\n <TourWidget.Footer>\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: '32px',\n width: '100%',\n }}\n >\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n gap: '32px',\n minWidth: 0,\n }}\n >\n <LinkButton\n size=\"s\"\n view=\"default\"\n onClick={() => setActiveStepIndex(0)}\n >\n Пропустить всё\n </LinkButton>\n <TourWidget.Bullets count={tourStepsCount} />\n </Box>\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n }}\n >\n <Button\n size=\"s\"\n view=\"secondary\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current - 1, tourStepsCount),\n )\n }\n >\n Назад\n </Button>\n <Button\n size=\"s\"\n view=\"default\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current + 1, tourStepsCount),\n )\n }\n >\n Далее\n </Button>\n </Box>\n </Box>\n </TourWidget.Footer>\n </TourWidget>\n </Box>\n );\n};"
39691
40126
  },
39692
40127
  {
39693
40128
  "exportName": "Pulse",
39694
40129
  "displayName": "Пульсация",
39695
40130
  "type": "full-code",
39696
- "code": "function PulseExample() {\n return (\n <TourView>\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n minHeight: '300px',\n }}\n >\n <PulseTarget />\n </Box>\n </TourView>\n );\n};"
40131
+ "code": "function PulseExample() {\n return (\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n minHeight: '300px',\n }}\n >\n <PulseTarget />\n </Box>\n );\n};"
39697
40132
  },
39698
40133
  {
39699
40134
  "exportName": "TourWithoutContent",
39700
40135
  "displayName": "Тур без контента",
39701
40136
  "type": "full-code",
39702
- "code": "function TourWithoutContentExample() {\n const tourStepsCount = 14;\n const [activeStepIndex, setActiveStepIndex] = useState(2);\n\n return (\n <TourView>\n <Box\n $css={{\n display: 'grid',\n gridTemplateColumns: '220px minmax(0, max-content)',\n gap: '14px',\n alignItems: 'center',\n }}\n >\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n minHeight: '300px',\n }}\n >\n <PulseTarget />\n </Box>\n <TourWidget\n orientation=\"horizontal\"\n activeStepIndex={activeStepIndex}\n $css={{ width: '480px' }}\n >\n <TourWidget.Header title=\"Title\" description=\"Description\" />\n <TourWidget.Footer>\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: '32px',\n width: '100%',\n }}\n >\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n gap: '32px',\n minWidth: 0,\n }}\n >\n <LinkButton\n size=\"s\"\n view=\"default\"\n onClick={() => setActiveStepIndex(0)}\n >\n Пропустить всё\n </LinkButton>\n </Box>\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n }}\n >\n <Button\n size=\"s\"\n view=\"secondary\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current - 1, tourStepsCount),\n )\n }\n >\n Назад\n </Button>\n <Button\n size=\"s\"\n view=\"white\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current + 1, tourStepsCount),\n )\n }\n >\n Далее\n </Button>\n </Box>\n </Box>\n </TourWidget.Footer>\n </TourWidget>\n </Box>\n </TourView>\n );\n};"
40137
+ "code": "function TourWithoutContentExample() {\n const tourStepsCount = 14;\n const [activeStepIndex, setActiveStepIndex] = useState(2);\n\n return (\n <Box\n $css={{\n display: 'grid',\n gridTemplateColumns: '220px minmax(0, max-content)',\n gap: '14px',\n alignItems: 'center',\n }}\n >\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n minHeight: '300px',\n }}\n >\n <PulseTarget />\n </Box>\n <TourWidget\n orientation=\"horizontal\"\n activeStepIndex={activeStepIndex}\n $css={{ width: '500px' }}\n >\n <TourWidget.Header title=\"Title\" description=\"Description\" />\n <TourWidget.Footer>\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: '32px',\n width: '100%',\n }}\n >\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n gap: '32px',\n minWidth: 0,\n }}\n >\n <LinkButton\n size=\"s\"\n view=\"default\"\n onClick={() => setActiveStepIndex(0)}\n >\n Пропустить всё\n </LinkButton>\n </Box>\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n }}\n >\n <Button\n size=\"s\"\n view=\"secondary\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current - 1, tourStepsCount),\n )\n }\n >\n Назад\n </Button>\n <Button\n size=\"s\"\n view=\"default\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current + 1, tourStepsCount),\n )\n }\n >\n Далее\n </Button>\n </Box>\n </Box>\n </TourWidget.Footer>\n </TourWidget>\n </Box>\n );\n};"
39703
40138
  }
39704
40139
  ],
39705
40140
  "hasCuratedMeta": true,
@@ -39719,25 +40154,25 @@
39719
40154
  "exportName": "Vertical",
39720
40155
  "displayName": "Вертикальный тур",
39721
40156
  "type": "full-code",
39722
- "code": "function VerticalExample() {\n const tourStepsCount = 14;\n const [activeStepIndex, setActiveStepIndex] = useState(0);\n\n return (\n <TourView>\n <TourWidget\n activeStepIndex={activeStepIndex}\n $css={{ width: '286px', height: '480px' }}\n >\n <TourWidget.Content>\n <MediaPlaceholder width={266} height={266} />\n </TourWidget.Content>\n <TourWidget.Header title=\"Title\" />\n <TourWidget.Footer>\n <Box\n $css={{\n display: 'flex',\n flexDirection: 'column',\n }}\n >\n <TourWidget.Bullets\n count={tourStepsCount}\n $css={{ marginInline: 'auto' }}\n />\n <Box\n $css={{\n display: 'flex',\n flexDirection: 'row',\n gap: '4px',\n marginTop: '20px',\n }}\n >\n <Button\n size=\"s\"\n stretching=\"filled\"\n view=\"secondary\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current - 1, tourStepsCount),\n )\n }\n >\n Назад\n </Button>\n <Button\n stretching=\"filled\"\n size=\"s\"\n view=\"white\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current + 1, tourStepsCount),\n )\n }\n >\n Далее\n </Button>\n </Box>\n <LinkButton\n size=\"s\"\n view=\"default\"\n onClick={() => setActiveStepIndex(0)}\n >\n Пропустить всё\n </LinkButton>\n </Box>\n </TourWidget.Footer>\n </TourWidget>\n </TourView>\n );\n};"
40157
+ "code": "function VerticalExample() {\n const tourStepsCount = 14;\n const [activeStepIndex, setActiveStepIndex] = useState(0);\n\n return (\n <TourWidget activeStepIndex={activeStepIndex} $css={{ width: '298px' }}>\n <TourWidget.Content>\n <MediaPlaceholder width={266} height={266} />\n </TourWidget.Content>\n <TourWidget.Header title=\"Title\" description=\"Description\" />\n <TourWidget.Footer>\n <Box\n $css={{\n display: 'flex',\n flexDirection: 'column',\n }}\n >\n <TourWidget.Bullets\n count={tourStepsCount}\n $css={{ marginInline: 'auto' }}\n />\n <Box\n $css={{\n display: 'flex',\n flexDirection: 'row',\n gap: '4px',\n marginTop: '20px',\n }}\n >\n <Button\n size=\"s\"\n stretching=\"filled\"\n view=\"secondary\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current - 1, tourStepsCount),\n )\n }\n >\n Назад\n </Button>\n <Button\n stretching=\"filled\"\n size=\"s\"\n view=\"default\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current + 1, tourStepsCount),\n )\n }\n >\n Далее\n </Button>\n </Box>\n <LinkButton\n size=\"s\"\n view=\"default\"\n onClick={() => setActiveStepIndex(0)}\n >\n Пропустить всё\n </LinkButton>\n </Box>\n </TourWidget.Footer>\n </TourWidget>\n );\n};"
39723
40158
  },
39724
40159
  {
39725
40160
  "exportName": "Horizontal",
39726
40161
  "displayName": "Горизонтальный тур",
39727
40162
  "type": "full-code",
39728
- "code": "function HorizontalExample() {\n const tourStepsCount = 14;\n const [activeStepIndex, setActiveStepIndex] = useState(5);\n\n return (\n <TourView>\n <TourWidget\n orientation=\"horizontal\"\n activeStepIndex={activeStepIndex}\n $css={{ width: '720px', height: '260px' }}\n >\n <TourWidget.Content>\n <MediaPlaceholder width={240} height={240} />\n </TourWidget.Content>\n <TourWidget.Header title=\"Title\" description=\"Description\" />\n <TourWidget.Footer>\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: '32px',\n width: '100%',\n }}\n >\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n gap: '32px',\n minWidth: 0,\n }}\n >\n <LinkButton\n size=\"s\"\n view=\"default\"\n onClick={() => setActiveStepIndex(0)}\n >\n Пропустить всё\n </LinkButton>\n <TourWidget.Bullets count={tourStepsCount} />\n </Box>\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n }}\n >\n <Button\n size=\"s\"\n view=\"secondary\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current - 1, tourStepsCount),\n )\n }\n >\n Назад\n </Button>\n <Button\n size=\"s\"\n view=\"white\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current + 1, tourStepsCount),\n )\n }\n >\n Далее\n </Button>\n </Box>\n </Box>\n </TourWidget.Footer>\n </TourWidget>\n </TourView>\n );\n};"
40163
+ "code": "function HorizontalExample() {\n const tourStepsCount = 14;\n const [activeStepIndex, setActiveStepIndex] = useState(5);\n\n return (\n <TourWidget\n orientation=\"horizontal\"\n activeStepIndex={activeStepIndex}\n $css={{ width: '732px', height: '272px' }}\n >\n <TourWidget.Content>\n <MediaPlaceholder width={240} height={240} />\n </TourWidget.Content>\n <TourWidget.Header title=\"Title\" description=\"Description\" />\n <TourWidget.Footer>\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: '32px',\n width: '100%',\n }}\n >\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n gap: '32px',\n minWidth: 0,\n }}\n >\n <LinkButton\n size=\"s\"\n view=\"default\"\n onClick={() => setActiveStepIndex(0)}\n >\n Пропустить всё\n </LinkButton>\n <TourWidget.Bullets count={tourStepsCount} />\n </Box>\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n }}\n >\n <Button\n size=\"s\"\n view=\"secondary\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current - 1, tourStepsCount),\n )\n }\n >\n Назад\n </Button>\n <Button\n size=\"s\"\n view=\"default\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current + 1, tourStepsCount),\n )\n }\n >\n Далее\n </Button>\n </Box>\n </Box>\n </TourWidget.Footer>\n </TourWidget>\n );\n};"
39729
40164
  },
39730
40165
  {
39731
40166
  "exportName": "LineBreaks",
39732
40167
  "displayName": "Переносы строк",
39733
40168
  "type": "full-code",
39734
- "code": "function LineBreaksExample() {\n return (\n <TourView>\n <TourWidget $css={{ width: '320px', paddingBottom: '24px' }}>\n <TourWidget.Header\n title={'Знакомьтесь:\\nновые возможности'}\n description={\n 'Режимы просмотра\\nОбщий реестр — все пилоты со статусом «В реестре»\\n• Мои пилоты — только ваши проекты, включая черновики'\n }\n />\n </TourWidget>\n </TourView>\n );\n};"
40169
+ "code": "function LineBreaksExample() {\n return (\n <TourWidget $css={{ width: '340px', paddingBottom: '24px' }}>\n <TourWidget.Header\n title={'Знакомьтесь:\\nновые возможности'}\n description={\n 'Режимы просмотра\\nОбщий реестр — все пилоты со статусом «В реестре»\\n• Мои пилоты — только ваши проекты, включая черновики'\n }\n />\n </TourWidget>\n );\n};"
39735
40170
  },
39736
40171
  {
39737
40172
  "exportName": "TourWithPulse",
39738
40173
  "displayName": "Тур рядом с пульсацией",
39739
40174
  "type": "full-code",
39740
- "code": "function TourWithPulseExample() {\n const tourStepsCount = 14;\n const [activeStepIndex, setActiveStepIndex] = useState(2);\n\n return (\n <TourView>\n <Box\n $css={{\n display: 'grid',\n gridTemplateColumns: '220px minmax(0, max-content)',\n gap: '14px',\n alignItems: 'center',\n }}\n >\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n minHeight: '300px',\n }}\n >\n <PulseTarget />\n </Box>\n <TourWidget\n orientation=\"horizontal\"\n activeStepIndex={activeStepIndex}\n $css={{ width: '720px', height: '264px' }}\n >\n <TourWidget.Content>\n <MediaPlaceholder width={240} height={240} />\n </TourWidget.Content>\n <TourWidget.Header title=\"Title\" description=\"Description\" />\n <TourWidget.Footer>\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: '32px',\n width: '100%',\n }}\n >\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n gap: '32px',\n minWidth: 0,\n }}\n >\n <LinkButton\n size=\"s\"\n view=\"default\"\n onClick={() => setActiveStepIndex(0)}\n >\n Пропустить всё\n </LinkButton>\n <TourWidget.Bullets count={tourStepsCount} />\n </Box>\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n }}\n >\n <Button\n size=\"s\"\n view=\"secondary\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current - 1, tourStepsCount),\n )\n }\n >\n Назад\n </Button>\n <Button\n size=\"s\"\n view=\"white\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current + 1, tourStepsCount),\n )\n }\n >\n Далее\n </Button>\n </Box>\n </Box>\n </TourWidget.Footer>\n </TourWidget>\n </Box>\n </TourView>\n );\n};"
40175
+ "code": "function TourWithPulseExample() {\n const tourStepsCount = 14;\n const [activeStepIndex, setActiveStepIndex] = useState(2);\n\n return (\n <Box\n $css={{\n display: 'grid',\n gridTemplateColumns: '220px minmax(0, max-content)',\n gap: '14px',\n alignItems: 'center',\n }}\n >\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n minHeight: '300px',\n }}\n >\n <PulseTarget />\n </Box>\n <TourWidget\n orientation=\"horizontal\"\n activeStepIndex={activeStepIndex}\n $css={{ width: '732px', height: '272px' }}\n >\n <TourWidget.Content>\n <MediaPlaceholder width={240} height={240} />\n </TourWidget.Content>\n <TourWidget.Header title=\"Title\" description=\"Description\" />\n <TourWidget.Footer>\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: '32px',\n width: '100%',\n }}\n >\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n gap: '32px',\n minWidth: 0,\n }}\n >\n <LinkButton\n size=\"s\"\n view=\"default\"\n onClick={() => setActiveStepIndex(0)}\n >\n Пропустить всё\n </LinkButton>\n <TourWidget.Bullets count={tourStepsCount} />\n </Box>\n <Box\n $css={{\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n }}\n >\n <Button\n size=\"s\"\n view=\"secondary\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current - 1, tourStepsCount),\n )\n }\n >\n Назад\n </Button>\n <Button\n size=\"s\"\n view=\"default\"\n onClick={() =>\n setActiveStepIndex((current) =>\n clampStep(current + 1, tourStepsCount),\n )\n }\n >\n Далее\n </Button>\n </Box>\n </Box>\n </TourWidget.Footer>\n </TourWidget>\n </Box>\n );\n};"
39741
40176
  }
39742
40177
  ]
39743
40178
  },
@@ -42525,19 +42960,12 @@
42525
42960
  "minimalUsage": "<ViewContainer />",
42526
42961
  "examples": [
42527
42962
  {
42528
- "exportName": "Usage1",
42963
+ "exportName": "Usage",
42529
42964
  "displayName": "Использование в CopyCodeAbsoluteButton.tsx",
42530
42965
  "type": "usage",
42531
42966
  "code": "<ViewContainer\n view=\"onDark\"\n style={{\n position: 'absolute',\n bottom: '8px',\n right: '8px',\n }}\n >\n <IconButton\n size=\"xxs\"\n view=\"clear\"\n onClick={handleCopy}\n title={copied ? 'Скопировано' : 'Скопировать код'}\n onMouseEnter={(e) => {\n (e.currentTarget as HTMLButtonElement).style.opacity = '1';\n }}\n onMouseLeave={(e) => {\n (e.currentTarget as HTMLButtonElement).style.opacity = '0.6';\n }}\n >\n {copied ? (\n <IconDone size=\"xs\" color=\"inherit\" />\n ) : (\n <IconCopyFill size=\"xs\" color=\"inherit\" />\n )}\n </IconButton>\n </ViewContainer>",
42532
42967
  "sourceFile": "packages/storybook/src/stories/AiChatDAIS/components/CopyCodeAbsoluteButton.tsx"
42533
42968
  },
42534
- {
42535
- "exportName": "Usage2",
42536
- "displayName": "Использование в TourWidget.examples.tsx",
42537
- "type": "usage",
42538
- "code": "<ViewContainer view=\"onDark\">{children}</ViewContainer>",
42539
- "sourceFile": "packages/storybook/src/stories/TourWidget/TourWidget.examples.tsx"
42540
- },
42541
42969
  {
42542
42970
  "exportName": "Vendor1",
42543
42971
  "displayName": "Пример использования",
@@ -52719,6 +53147,78 @@
52719
53147
  }
52720
53148
  },
52721
53149
  "features": [
53150
+ {
53151
+ "component": "TableCanvas",
53152
+ "feature": "CanvasElements/CanvasAvatar",
53153
+ "legacy": false,
53154
+ "summary": "Круглый аватар с фотографией, инициалами или коротким текстом для ячеек `TableCanvas`.",
53155
+ "docs": "# Canvas.Avatar\n\nКруглый аватар с фотографией, инициалами или коротким текстом для ячеек `TableCanvas`.\n\n## Ключевые особенности\n\n- Размеры FinAI: `s` — 24 px, `m` — 36 px, `l` — 48 px, `xxl` — 88 px.\n- Размер по умолчанию — `s`.\n- Приоритет содержимого: непустой `customText`, фотография, инициалы из `name`.\n- Поддержка тултипов и кликов.\n\n## Особенности\n\nПри первой загрузке фотографии или если исходный URL недоступен отображаются инициалы. Если имя не задано, остаётся фон. При заданном `customText` фотография не загружается.\n\nПри смене URL у того же аватара предыдущее фото остаётся до готовности нового, без промежуточного показа инициалов. Если новое фото недоступно, сохраняется предыдущее, пока оно есть в загрузчике.\n\nДля разных участников задавайте разные `id` или React `key`, особенно если имена совпадают. Смена `id` или имени, удаление URL и переход на `customText` сбрасывают предыдущее фото.\n\nФотография растягивается до размеров аватара. Инициалы под загруженным изображением не рисуются.\n\nДля размещения используйте `Canvas.Container`. Примитив не принимает `children`.\n\nОписание типов — в разделе [API](?path=/docs/локальные-компоненты-tablecanvas-canvaselements-canvasavatar-api--docs).",
53156
+ "apiDocs": "# Canvas.Avatar API\n\n## CanvasAvatarProps\n\n```typescript\ntype CanvasAvatarProps = PublicCanvasProps<InternalCanvasAvatarProps>;\n```\n\n## AvatarContent\n\n```typescript\ninterface AvatarContent {\n /** Имя участника для инициалов; также определяет, можно ли сохранить старое фото при смене URL. */\n name?: string;\n /** URL фотографии; пока фото недоступно, отображаются инициалы. */\n url?: string;\n /** Непустой текст вместо фотографии и инициалов, например счётчик +N. */\n customText?: string;\n}\n```\n\n## AvatarSize\n\n```typescript\ntype AvatarSize = 's' | 'm' | 'l' | 'xxl';\n```",
53157
+ "api": [
53158
+ {
53159
+ "typeName": "CanvasAvatarProps",
53160
+ "source": "type CanvasAvatarProps = PublicCanvasProps<InternalCanvasAvatarProps>;"
53161
+ },
53162
+ {
53163
+ "typeName": "AvatarContent",
53164
+ "source": "interface AvatarContent {\n /** Имя участника для инициалов; также определяет, можно ли сохранить старое фото при смене URL. */\n name?: string;\n /** URL фотографии; пока фото недоступно, отображаются инициалы. */\n url?: string;\n /** Непустой текст вместо фотографии и инициалов, например счётчик +N. */\n customText?: string;\n}"
53165
+ },
53166
+ {
53167
+ "typeName": "AvatarSize",
53168
+ "source": "type AvatarSize = 's' | 'm' | 'l' | 'xxl';"
53169
+ }
53170
+ ],
53171
+ "stories": [
53172
+ {
53173
+ "exportName": "ContentAndSizes",
53174
+ "displayName": "Содержимое и размеры",
53175
+ "type": "full-code",
53176
+ "code": "import React from 'react';\nimport { Canvas, TableCanvas, type ColumnConfig, type AvatarSize } from '@daisforge/ui/components/TableCanvas';\nimport { avatarItems } from './avatarFixtures';\n\nfunction AvatarContentAndSizesExample() {\n const rows = ['s', 'm', 'l', 'xxl'].map((size, id) => ({\n id,\n size: size as AvatarSize,\n }));\n const columns: ColumnConfig<(typeof rows)[number]>[] = [\n {\n key: 'size',\n name: 'Размер',\n width: 110,\n renderCell: ({ row }) => <Canvas.Text>{row.size}</Canvas.Text>,\n },\n ...[\n { key: 'photo', name: 'Фото', url: avatarItems[0]!.url },\n { key: 'initials', name: 'Инициалы' },\n {\n key: 'custom',\n name: 'customText',\n customText: 'AI',\n url: avatarItems[0]!.url,\n },\n {\n key: 'broken',\n name: 'Ошибка первой загрузки',\n url: '/canvas-images/missing.png',\n },\n ].map(({ key, name, ...content }) => ({\n key,\n name,\n width: 150,\n copyData: 'Анна Иванова',\n renderCell: ({ row }: { row: (typeof rows)[number] }) => (\n <Canvas.Container padding={8}>\n <Canvas.Avatar\n name=\"Анна Иванова\"\n size={row.size}\n {...content}\n tooltip=\"Анна Иванова\"\n />\n </Canvas.Container>\n ),\n })),\n ];\n return (\n <TableCanvas\n rows={rows}\n columnConfig={columns}\n tableConfig={{ rowHeight: 104, containerStyle: { height: '490px' } }}\n />\n );\n};"
53177
+ }
53178
+ ]
53179
+ },
53180
+ {
53181
+ "component": "TableCanvas",
53182
+ "feature": "CanvasElements/CanvasAvatarGroup",
53183
+ "legacy": false,
53184
+ "summary": "Группа аватаров участников с отдельным счётчиком скрытых элементов в ячейке `TableCanvas`.",
53185
+ "docs": "# Canvas.AvatarGroup\n\nГруппа аватаров участников с отдельным счётчиком скрытых элементов в ячейке `TableCanvas`.\n\n## Ключевые особенности\n\n- Пять участников при `visibleCount={3}` отображаются как три аватара и круг `+2`.\n- Содержимое задаётся массивом `items`; у каждого участника должен быть уникальный `id`.\n- Общий размер группы: `s`, `m`, `l` или `xxl`; по умолчанию — `s`.\n- Аватар раскрывается при наведении, а вырез соседнего элемента меняется.\n- Отдельные обработчики клика по участнику и счётчику, индивидуальные тултипы.\n\n## Особенности\n\nПри смене URL у участника с тем же `id` и именем его предыдущее фото сохраняется до загрузки нового. При первой загрузке отображаются инициалы.\n\n`visibleCount` ограничивает число обычных аватаров и по умолчанию равен `3`. Счётчик занимает дополнительное место. `totalCount` учитывает всех участников, включая отсутствующих в `items`, и не может быть меньше длины массива при расчёте.\n\nПустая группа без `totalCount` не занимает места. При `visibleCount={0}` отображается только счётчик. В узкой колонке группа обрезается: диаметр и число видимых аватаров автоматически не меняются.\n\nВ `+N` выводится точное число. Длинный текст обрезается границами круга, а полное значение доступно в тултипе. `overflowTooltip` позволяет заменить этот тултип.\n\nДля текстового представления ячейки и копирования задайте `column.copyData`: перечислите известные имена и число неизвестных участников.\n\nОписание типов — в разделе [API](?path=/docs/локальные-компоненты-tablecanvas-canvaselements-canvasavatargroup-api--docs).",
53186
+ "apiDocs": "# Canvas.AvatarGroup API\n\n## CanvasAvatarGroupProps\n\n```typescript\ntype CanvasAvatarGroupProps =\n PublicCanvasProps<InternalCanvasAvatarGroupProps>;\n```\n\n## CanvasAvatarItem\n\n```typescript\ninterface CanvasAvatarItem extends AvatarContent {\n /** Стабильный уникальный идентификатор участника внутри группы; используется в ID canvas-ноды. */\n id: string;\n /** Подсказка при наведении на этого участника. */\n tooltip?: CanvasNodeTooltipConfig;\n}\n```\n\n## AvatarContent\n\n```typescript\ninterface AvatarContent {\n /** Имя участника для инициалов; также определяет, можно ли сохранить старое фото при смене URL. */\n name?: string;\n /** URL фотографии; пока фото недоступно, отображаются инициалы. */\n url?: string;\n /** Непустой текст вместо фотографии и инициалов, например счётчик +N. */\n customText?: string;\n}\n```\n\n## AvatarSize\n\n```typescript\ntype AvatarSize = 's' | 'm' | 'l' | 'xxl';\n```\n\n## AvatarGroupItemClick\n\n```typescript\ninterface AvatarGroupItemClick {\n /** Участник, по аватару которого нажали. */\n item: CanvasAvatarItem;\n /** Индекс участника в исходном массиве items, начиная с нуля. */\n index: number;\n /** Canvas-событие клика по аватару с координатами и управлением всплытием. */\n event: CanvasEvent<CanvasAvatar>;\n}\n```\n\n## AvatarGroupOverflowClick\n\n```typescript\ninterface AvatarGroupOverflowClick {\n /** Число участников за счётчиком +N, включая отсутствующих в items. */\n hiddenCount: number;\n /** Известные скрытые участники: часть items после видимых аватаров. */\n hiddenItems: readonly CanvasAvatarItem[];\n /** Общее число участников после нормализации; не меньше длины items. */\n totalCount: number;\n /** Canvas-событие клика по счётчику +N. */\n event: CanvasEvent<CanvasAvatar>;\n}\n```",
53187
+ "api": [
53188
+ {
53189
+ "typeName": "CanvasAvatarGroupProps",
53190
+ "source": "type CanvasAvatarGroupProps =\n PublicCanvasProps<InternalCanvasAvatarGroupProps>;"
53191
+ },
53192
+ {
53193
+ "typeName": "CanvasAvatarItem",
53194
+ "source": "interface CanvasAvatarItem extends AvatarContent {\n /** Стабильный уникальный идентификатор участника внутри группы; используется в ID canvas-ноды. */\n id: string;\n /** Подсказка при наведении на этого участника. */\n tooltip?: CanvasNodeTooltipConfig;\n}"
53195
+ },
53196
+ {
53197
+ "typeName": "AvatarContent",
53198
+ "source": "interface AvatarContent {\n /** Имя участника для инициалов; также определяет, можно ли сохранить старое фото при смене URL. */\n name?: string;\n /** URL фотографии; пока фото недоступно, отображаются инициалы. */\n url?: string;\n /** Непустой текст вместо фотографии и инициалов, например счётчик +N. */\n customText?: string;\n}"
53199
+ },
53200
+ {
53201
+ "typeName": "AvatarSize",
53202
+ "source": "type AvatarSize = 's' | 'm' | 'l' | 'xxl';"
53203
+ },
53204
+ {
53205
+ "typeName": "AvatarGroupItemClick",
53206
+ "source": "interface AvatarGroupItemClick {\n /** Участник, по аватару которого нажали. */\n item: CanvasAvatarItem;\n /** Индекс участника в исходном массиве items, начиная с нуля. */\n index: number;\n /** Canvas-событие клика по аватару с координатами и управлением всплытием. */\n event: CanvasEvent<CanvasAvatar>;\n}"
53207
+ },
53208
+ {
53209
+ "typeName": "AvatarGroupOverflowClick",
53210
+ "source": "interface AvatarGroupOverflowClick {\n /** Число участников за счётчиком +N, включая отсутствующих в items. */\n hiddenCount: number;\n /** Известные скрытые участники: часть items после видимых аватаров. */\n hiddenItems: readonly CanvasAvatarItem[];\n /** Общее число участников после нормализации; не меньше длины items. */\n totalCount: number;\n /** Canvas-событие клика по счётчику +N. */\n event: CanvasEvent<CanvasAvatar>;\n}"
53211
+ }
53212
+ ],
53213
+ "stories": [
53214
+ {
53215
+ "exportName": "Virtualized",
53216
+ "displayName": "Количество участников, узкая колонка и прокрутка",
53217
+ "type": "full-code",
53218
+ "code": "import React, { useMemo } from 'react';\nimport { Canvas, TableCanvas, type ColumnConfig } from '@daisforge/ui/components/TableCanvas';\nimport { avatarCopyText, avatarItems } from '../CanvasAvatar/avatarFixtures';\n\nfunction VirtualTable() {\n const rows = useMemo(() => {\n const cases = [\n { label: '5 → 3 +2', items: avatarItems, total: 5, visible: 3 },\n {\n label: '2 загружено из 5',\n items: avatarItems.slice(0, 2),\n total: 5,\n visible: 3,\n },\n { label: 'Пустая группа', items: [], total: 0, visible: 3 },\n { label: 'Известен только total', items: [], total: 5, visible: 3 },\n { label: 'visibleCount=0', items: avatarItems, total: 5, visible: 0 },\n ];\n return Array.from({ length: 700 }, (_, id) => {\n const scenario = cases[id % cases.length]!;\n return {\n ...scenario,\n id,\n label: `Строка ${id + 1}: ${scenario.label}`,\n items: scenario.items.map((item, index) => ({\n ...item,\n url: `/canvas-images/virtual/${index}?row=${id}`,\n })),\n };\n });\n }, []);\n const columns = useMemo<ColumnConfig<(typeof rows)[number]>[]>(\n () => [\n { key: 'label', name: 'Строка и сценарий', width: 280 },\n ...[200, 60].map<ColumnConfig<(typeof rows)[number]>>((width) => ({\n key: `team-${width}`,\n name: width === 60 ? 'Узко' : 'Группа',\n width,\n copyData: (row) => avatarCopyText(row.items, row.total),\n renderCell: ({ row }) => (\n <Canvas.Container padding={8}>\n <Canvas.AvatarGroup\n items={row.items}\n totalCount={row.total}\n visibleCount={row.visible}\n />\n </Canvas.Container>\n ),\n })),\n ],\n [],\n );\n return (\n <TableCanvas\n rows={rows}\n columnConfig={columns}\n tableConfig={{ rowHeight: 44, containerStyle: { height: '360px' } }}\n />\n );\n};\nfunction AvatarGroupExample() {\n return (\n <>\n <p>\n 700 строк с локальными PNG-фотографиями и разным количеством участников\n в обычной и узкой колонках. У каждой строки свои URL фотографий —\n прокрутите таблицу, чтобы увидеть загрузку новых изображений.\n </p>\n <VirtualTable />\n </>\n );\n};"
53219
+ }
53220
+ ]
53221
+ },
52722
53222
  {
52723
53223
  "component": "TableCanvas",
52724
53224
  "feature": "CanvasElements/CanvasBadge",
@@ -52895,6 +53395,32 @@
52895
53395
  }
52896
53396
  ]
52897
53397
  },
53398
+ {
53399
+ "component": "TableCanvas",
53400
+ "feature": "CanvasElements/CanvasImage",
53401
+ "legacy": false,
53402
+ "summary": "Изображение по URL в ячейке `TableCanvas` с заранее заданными размерами.",
53403
+ "docs": "# Canvas.Image\n\nИзображение по URL в ячейке `TableCanvas` с заранее заданными размерами.\n\n## Ключевые особенности\n\n- Три режима вписывания: `cover`, `contain` и `fill`.\n- Выравнивание изображения по центру.\n- Поддержка прозрачных изображений, тултипов и кликов.\n- Размеры через `style.width` и `style.height` не меняются после загрузки.\n\n## Особенности\n\nПо умолчанию используется `cover`: изображение заполняет область с обрезкой по краям. `contain` сохраняет изображение целиком, а `fill` растягивает его до заданных размеров.\n\nПока изображение загружается или если URL недоступен, зарезервированная область остаётся пустой. Загрузка поддерживается в ячейках данных; в заголовках она недоступна.\n\nДля размещения используйте `Canvas.Container`. Примитив не принимает `children`.\n\nОписание типов — в разделе [API](?path=/docs/локальные-компоненты-tablecanvas-canvaselements-canvasimage-api--docs).",
53404
+ "apiDocs": "# Canvas.Image API\n\n## CanvasImageProps\n\n```typescript\ntype CanvasImageProps = PublicCanvasProps<InternalCanvasImageProps>;\n```\n\n## ImageFit\n\n```typescript\ntype ImageFit = 'fill' | 'cover' | 'contain';\n```",
53405
+ "api": [
53406
+ {
53407
+ "typeName": "CanvasImageProps",
53408
+ "source": "type CanvasImageProps = PublicCanvasProps<InternalCanvasImageProps>;"
53409
+ },
53410
+ {
53411
+ "typeName": "ImageFit",
53412
+ "source": "type ImageFit = 'fill' | 'cover' | 'contain';"
53413
+ }
53414
+ ],
53415
+ "stories": [
53416
+ {
53417
+ "exportName": "Fits",
53418
+ "displayName": "Режимы вписывания",
53419
+ "type": "full-code",
53420
+ "code": "import React from 'react';\nimport { Canvas, TableCanvas, type ColumnConfig, type ImageFit } from '@daisforge/ui/components/TableCanvas';\nimport wideImage from '../CanvasAvatar/images/wide.png';\n\nfunction ImageFitsExample() {\n const rows = [\n {\n id: 0,\n image: 'Горы',\n src: wideImage,\n },\n ];\n const fits: ImageFit[] = ['cover', 'contain', 'fill'];\n const columns: ColumnConfig<(typeof rows)[number]>[] = fits.map((fit) => ({\n key: fit,\n name: fit,\n width: 170,\n copyData: (row) => row.image,\n renderCell: ({ row, theme }) => (\n <Canvas.Container padding={8}>\n <Canvas.Container\n position=\"relative\"\n style={{ width: 88, height: 88 }}\n tooltip={`${row.image}: ${fit}`}\n >\n <Canvas.Image\n src={row.src}\n fit={fit}\n style={{ width: 88, height: 88 }}\n />\n <Canvas.Rect\n position=\"absolute\"\n left={0}\n top={0}\n style={{ width: 88, height: 88 }}\n borderColor={theme.tokens.outlineAccent}\n borderWidth={1}\n zIndex={1}\n />\n </Canvas.Container>\n </Canvas.Container>\n ),\n }));\n return (\n <TableCanvas\n rows={rows}\n columnConfig={columns}\n tableConfig={{ rowHeight: 104, containerStyle: { height: '160px' } }}\n />\n );\n};"
53421
+ }
53422
+ ]
53423
+ },
52898
53424
  {
52899
53425
  "component": "TableCanvas",
52900
53426
  "feature": "CanvasElements/CanvasLink",
@@ -53883,11 +54409,11 @@
53883
54409
  "legacy": false,
53884
54410
  "summary": "*tableConfig.filtering**",
53885
54411
  "docs": "# Filtering\n\n**tableConfig.filtering**\n\nФильтрация данных таблицы с поддержкой автоматического и ручного режимов.\n\n## Ключевые особенности\n\n- Три типа фильтров: `input`, `select`, `custom`\n- Автоматическая фильтрация по умолчанию, ручная через `manualFiltering: true`\n- Отображение активных фильтров в виде chip-элементов\n- Поддержка фильтрации через sidebar с настройкой порядка и глобальных фильтров\n- Кастомизация chip-стилей и лейблов\n\n## Типы фильтров\n\n### Input\n\nТекстовый фильтр с режимами: `'includes'`, `'startWith'`, `'equal'` или кастомная функция.\n\n### Select\n\nФильтр выбором из списка. Поддержка одиночного (`'single'`) и множественного (`'multiple'`) выбора.\n\n### Custom\n\nПолностью кастомный компонент фильтра через `customRender`.\n\n## Конфигурация FilteringConfig\n\n- **`state`** `[T, setState]` — стейт фильтров (обязательный)\n- **`manualFiltering`** `boolean` — ручная фильтрация (данные не фильтруются таблицей)\n- **`filtersInfo`** `Record<keyof T, { label, clearedValue }>` — метки и дефолтные значения фильтров\n- **`sidebarConfig`** `{ order?, items }` — конфигурация sidebar с фильтрами\n- **`chipStyle`** `(itemOrGroup, item) => CSSObject` — кастомные стили для chip-элементов\n- **`renderGroupLabel`** `(group) => string` — кастомный заголовок группы чипсов\n- **`renderChipLabel`** `(group, item) => string` — кастомный текст чипса\n\n## Кастомизация чипсов\n\n### chipStyle\n\nПозволяет динамически задавать стили для каждого чипа фильтра в зависимости от его типа и содержимого.\n\n### renderGroupLabel\n\nФорматтер заголовка группы чипсов. Полезен для i18n или добавления счётчика выбранных элементов.\n\n### renderChipLabel\n\nФорматтер текста внутри чипса. Полезен при серверной пагинации, когда в стейте хранится только `value`, а `label` подставляется из кэша.\n\n## Особенности\n\n- При `manualFiltering: true` таблица не фильтрует данные — ожидается внешняя логика (серверная)\n- `sidebarConfig` позволяет добавлять глобальные фильтры, не привязанные к колонкам\n- `filtersInfo` задаёт лейблы и значения по умолчанию для каждого фильтра\n\n> Подробнее о типах — [Filtering API](?path=/docs/локальные-компоненты-tablecanvas-filtering-api--docs)",
53886
- "apiDocs": "# Filtering API\n\n## FilteringConfig\n\n```typescript\ntype FilteringConfig<T> = {\n state: [T, React.Dispatch<React.SetStateAction<T>>];\n /**\n * @deprecated Использовать filtersInfo\n *\n * clearedValue - состояние фильтров после очистки. Используется для сравнения:\n * Например, был ли фильтр конкретной колонки изменен рассчитывается посредством сравнения текущего значения фильтра и значения фильтра в clearedValue.\n * Если они равны, то фильтр считается не измененным.\n */\n clearedValue?: T;\n /**\n * Информация о фильтрах для каждой колонки.\n * Используется для:\n * 1. Хранения меток (label) фильтров для отображения в UI\n * 2. Хранения значений по умолчанию (clearedValue) для каждого фильтра\n * 3. Определения, был ли фильтр изменен (сравнение текущего значения с clearedValue)\n */\n filtersInfo?: Record<\n keyof T,\n {\n label: string;\n clearedValue: T[keyof T];\n }\n >;\n /**\n * manualFiltering - пропс, активирующий ручную-кастомную (или на стороне бэка) фильтрацию.\n * @remarks\n * Для автоматической фильтрации (когда не используется manualFiltering в tableConfig):\n * - Для всех типов фильтров обязательно должен быть указан `valueInRow`\n * - Для component: 'select' дополнительно должен быть указан `filteringType`\n * - Для component: 'input' с кастомным фильтром (когда filter - функция)\n * функция фильтрации должна быть передана явно\n *\n * Если используется manualFiltering, эти параметры не обязательны,\n * так как вся логика фильтрации реализуется извне.\n */\n manualFiltering?: boolean;\n /**\n * Конфигурация для отображения фильтров в правом сайдбаре.\n *\n * Позволяет:\n * 1. Добавлять глобальные фильтры (не привязанные к конкретной колонке)\n * 2. Управлять порядком отображения фильтров\n * 3. Переопределять рендер и заголовки колоночных фильтров\n *\n * Логика работы:\n * - По умолчанию в сайдбаре отображаются все колоночные фильтры (из columnConfig)\n * - Ключом фильтра считается `key` колонки, если его нет, то пытаемся взять `keyInFilterState` (если указан), иначе это не будет работать\n * - Заголовком фильтра по умолчанию является `name` колонки или ключ фильтра (name || key)\n * - Глобальные фильтры добавляются через `items` с уникальными ключами\n *\n * Особенности:\n * 1. Порядок отображения:\n * - Сначала фильтры из `order` (в указанной последовательности)\n * - Затем остальные колоночные фильтры (в порядке columnConfig)\n * - В конце - глобальные фильтры (в алфавитном порядке ключей)\n *\n * 2. Переопределение колоночных фильтров:\n * - Чтобы изменить заголовок: укажите ключ колонки в `items` с новым `label`\n * - Чтобы заменить рендер: укажите ключ колонки с `customRenderFn`\n * - Оригинальный фильтр из колонки будет проигнорирован\n *\n * 3. Глобальные фильтры:\n * - Ключ не должен совпадать с ключами колонок\n * - Обязательно указать `label` и `customRenderFn`\n * - Отображаются после всех колоночных фильтров, если не переопределены в order\n *\n * @example\n * // Добавление глобального фильтра и изменение порядка\n * sidebarConfig: {\n * order: ['status', 'tasks', 'type'], // Сначала статус, затем глобальный поиск\n * items: {\n * tasks: { // Уникальный ключ\n * label: 'Поиск по всем полям',\n * customRenderFn: () => <TaskComponent />\n * },\n * status: { // Переопределение колоночного фильтра\n * label: 'Статус заявки', // Новый заголовок\n * customRenderFn: () => <CustomStatusFilter /> // Кастомный рендер\n * }\n * type: { // Переопределение только Label колоночного фильтра\n * label: 'Тип', // Новый заголовок\n * }\n * }\n * }\n */\n sidebarConfig?: {\n /**\n * Определяет порядок отображения фильтров.\n * - Указываются ключи фильтров (колоночных или глобальных)\n * - Не указанные в order фильтры отображаются после\n * - Если order пуст, сохраняется порядок: глобальные фильтры + columnConfig фильтры в конце\n */\n order?: string[];\n /**\n * Конфигурация фильтров для сайдбара.\n * Ключом может быть:\n * - Ключ колонки (для переопределения колоночного фильтра)\n * - Уникальный ключ (для добавления глобального фильтра)\n */\n items: Partial<\n Record<\n keyof T,\n {\n /** Заголовок фильтра (обязателен для глобальных фильтров), можно использовать для переопределения для локальных фильтров */\n label: string;\n /**\n * Функция рендера компонента фильтра.\n * Для колоночных фильтров переопределяет оригинальный рендер.\n * Для глобальных фильтров обязательна.\n */\n customRenderFn?: (\n filters: T,\n setFilters: React.Dispatch<React.SetStateAction<T>>,\n ) => React.ReactNode;\n }\n >\n >;\n };\n /**\n * Callback для кастомизации стилей чипсов (фильтров) в списке\n *\n * @param {ItemOrGroup} itemOrGroup - Текущий элемент или группа фильтров\n * @param {Item | undefined} item - Конкретный элемент фильтра (если есть)\n * @returns {CSSObject} Объект стилей, который будет применен к чипсу\n *\n * @description\n * Позволяет динамически задавать стили для каждого чипса в зависимости от его типа и содержимого.\n * Вызывается для каждого отображаемого чипса (как для отдельных элементов, так и для элементов внутри групп).\n *\n * @example\n * // Пример 1: Стилизация чипсов по типу\n * chipStyle: (itemOrGroup, item) => {\n * if (isGroup(itemOrGroup)) {\n * return { backgroundColor: '#f0f0f0' };\n * }\n * return { backgroundColor: '#e0e0e0' };\n * }\n *\n * @example\n * // Пример 2: Стилизация по значению фильтра\n * chipStyle: (itemOrGroup, item) => {\n * if (item?.label === 'Высокий приоритет') {\n * return {\n * backgroundColor: '#ffebee',\n * color: '#d32f2f'\n * };\n * }\n * return {};\n * }\n *\n * @example\n * // Пример 3: Разные стили для элементов в группе и одиночных\n * chipStyle: (itemOrGroup, item) => {\n * if (item) {\n * // Стиль для элемента внутри группы\n * return { maxWidth: 180 };\n * }\n * // Стиль для одиночного чипа\n * return { maxWidth: 150 };\n * }\n */\n chipStyle?: (itemOrGroup: ItemOrGroup, item: Item | undefined) => CSSObject;\n /**\n * Пользовательский форматтер заголовка группы чипсов.\n *\n * Используется в блоке активных фильтров для подмены текста заголовка\n * группы (например, “Статус”, “Тип”, “Автор”). Полезно, когда нужно\n * динамически менять подпись (добавить счётчик, i18n и т.п.).\n *\n * @param {ItemOrGroup} itemOrGroup Объект группы (тип Group). Вызов происходит только для групп,\n * поэтому безопасно кастовать к Group.\n * @returns {string} Текст заголовка группы чипсов.\n *\n * @default Возвращается `group.groupLabel`.\n *\n * @remarks\n * - Функция должна быть чистой и быстрой (без сетевых запросов и побочных эффектов).\n * - Возвращайте ТОЛЬКО строку — чипы отображают текстовое значение.\n * - Для длинных строк применяется усечение (overflow с многоточием) на уровне компонента.\n *\n * @example\n * // Добавить двоеточие и количество выбранных элементов\n * renderGroupLabel: (group) => `${group.groupLabel}: ${group.items.length}`\n *\n * @example\n * // Локализация заголовка группы\n * const i18n = { status: 'Статус', type: 'Тип' };\n * renderGroupLabel: (group) => i18n[group.groupId] ?? group.groupLabel\n */\n renderGroupLabel?: (group: Group) => string;\n\n /**\n * Пользовательский форматтер текста чипса (элемента внутри группы или одиночного фильтра).\n *\n * Позволяет управлять тем, что именно отображается внутри каждого чипса. Особенно полезен\n * при серверной пагинации/ленивой загрузке, когда в состоянии фильтра хранится только value,\n * а label необходимо подставить из локального кэша.\n *\n * @param {Group | null } group Группа, внутри которой рендерится чип (или null).\n * @param {Item} item Сам элемент чипса. В группах передаётся конкретный `Item`,\n * для одиночного чипа может быть `undefined`.\n * @returns {string} Текст, который будет показан в чипсе.\n *\n * @default Используется `item?.label.toString()` (или строковое представление value).\n *\n * @remarks\n * - Функция должна быть чистой и быстрой;\n * - Возвращайте ТОЛЬКО строку.\n *\n * @example\n * // 1) Отображение label из кэша при серверной пагинации\n * const labelsCacheRef = useRef(new Map<string, string>());\n * renderChipLabel: (group, item) => {\n * if (item?.id != null) {\n * const key = String(item.id);\n * const fromCache = labelsCacheRef.current.get(key);\n * if (fromCache) return fromCache; // красивый label, если уже загрузили\n * return String(item.label ?? key); // фоллбэк: временно показываем value/label из item\n * }\n * return ''; // безопасный фоллбэк для одиночных случаев\n * }\n *\n * @example\n * // 2) Нормализация отображения числовых значений\n * renderChipLabel: (_group, item) => {\n * const v = Number(item?.label);\n * return Number.isFinite(v) ? v.toLocaleString('ru-RU') : String(item?.label ?? '');\n * }\n *\n * @example\n * // 3) Префикс по типу группы\n * renderChipLabel: (group, item) => {\n * const prefix = group.groupId === 'status' ? '' : '#';\n * return `${prefix}${item?.label ?? item?.id ?? ''}`;\n * }\n */\n renderChipLabel?: (group: Group | null, item: Item) => string;\n};\n\nexport type DefaultSidebarTabIds = 'columns' | 'tableSettings' | 'filtering';\n\n/**\n * Конфигурация sidebar\n */\nexport type SidebarConfig = {\n /**\n * Включен ли sidebar. Отвечает только за UI. Не влияет на перерасчёт фичей.\n * @default true\n */\n enabled?: boolean;\n /**\n * Открыт ли sidebar при первом рендере (uncontrolled-режим).\n * Игнорируется, если передан openState.\n * @default false\n */\n defaultOpen?: boolean;\n /**\n * Внешний контроль открытия/закрытия sidebar.\n * Если передан — источник истины, defaultOpen игнорируется.\n */\n openState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n /**\n * id вкладки, выбранной по умолчанию (актуально при открытом сайдбаре).\n * Если id не найден или у вкладки showInSidebar=false — используется первая доступная.\n */\n defaultActiveTabId?: string;\n /**\n * Внешний контроль активной вкладки (controlled-режим).\n * Если передан — источник истины, defaultActiveTabId игнорируется.\n */\n activeTabState?: [\n string | null,\n React.Dispatch<React.SetStateAction<string | null>>,\n ];\n /**\n * Колбэк смены активной вкладки. Вызывается и в uncontrolled-режиме.\n * При закрытии сайдбара приходит null.\n */\n onActiveTabChange?: (tabId: string | null, tab?: SidebarTab) => void;\n /**\n * Кастомные табы\n */\n customTabs?: Array<\n Omit<SidebarTab, 'id'> & {\n id: Exclude<string, DefaultSidebarTabIds>;\n }\n >;\n /**\n * Порядок отображения кастомных вкладок\n */\n customTabsOrder?: Array<Exclude<string, DefaultSidebarTabIds>>;\n defaultTabs?: Array<\n | {\n id: 'filtering' | 'columns';\n /** название таба в рамках горизонтального табов внутри таба настройки */\n label?: string;\n /** название таба в рамках вертикальных табов сайдбара (если данный таб окажется единственным табом в настройках) */\n title?: string;\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n domMetadata?: DomMetadata;\n /**\n * Кастомный элемент справа от title в шапке сайдбара\n */\n titleRightSlot?: React.ReactNode;\n /** @default true */\n showInSidebar?: boolean;\n /** тултип иконки шестеренки (для табов с id = filtering и columns - недоступен. Настраивается через таб с id='tableSettings') */\n iconTooltipText?: undefined;\n }\n | {\n id: 'tableSettings';\n /** название таба в рамках горизонтального табов внутри таба настройки */\n label?: string;\n /** название таба в рамках вертикальных табов сайдбара */\n title?: string;\n\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n domMetadata?: DomMetadata;\n /**\n * Кастомный слот для вкладки tableSettings (рендерится после общих настроек)\n * Только дл id: 'tableSettings'\n */\n customGeneralSettingsSlot?: React.ReactNode;\n /**\n * Кастомный элемент справа от title в шапке сайдбара\n */\n titleRightSlot?: React.ReactNode;\n /** @default true */\n showInSidebar?: boolean;\n /** тултип иконки шестеренки @default 'Настройки' */\n iconTooltipText?: string;\n }\n >;\n};\n\nexport function activeViewIs<T extends 'cards' | 'rows'>(\n checkType: T,\n viewState: 'cards' | 'rows',\n view: View,\n): view is ViewMods[T] {\n return checkType === viewState;\n}\n\n/** Размер controlBlock: 'm' и 's' — одинаковые стили, 'xs' — уменьшенный */\nexport type ControlBlockSize = 'm' | 's' | 'xs';\n\nexport type ControlBlockConfig = {\n /**\n * show - наличие controlBlock-а\n * @default true\n */\n show?: boolean;\n /**\n * Размер controlBlock и его элементов (кнопки, иконки, поиск, отступы).\n * 'm' и 's' — стандартные стили, 'xs' — компактный режим.\n * Не влияет на customFeatures и кастомные слоты — они контролируются разработчиком.\n * @default 'm'\n */\n size?: ControlBlockSize;\n /**\n * @deprecated Используйте кастомные кнопки через rightSideInner или customFeatures.\n * leftSideInner - пропс для добавления кнопок в левую часть контролблока.\n * Продолжает работать для обратной совместимости.\n */\n leftSideInner?: ControlBlockButtonProps[];\n /**\n * rightSideInner - пропс для добавления кнопок в правую часть контролблока\n */\n rightSideInner?: ControlBlockButtonProps[];\n /**\n * customFeatures - пропс для добавления кастомных фичей (кнопки-иконки)\n */\n customFeatures?: FeatureItem[];\n /**\n * pinningMenu - нативная фича закрепления столбцов (SplitIconButton с\n * дропдауном) в правой зоне иконок. Появляется, когда активировано\n * закрепление колонок (columnsControl.pinning). Продукт может донастроить\n * и дополнить пункты меню (см. PinningMenuConfig).\n */\n pinningMenu?: PinningMenuConfig;\n /**\n * Пропсы для компонента dropdown в котором будут скрыты левые фичи при адаптивной компрессии\n */\n leftSideDropdownProps?: TableDropdownConfigProps;\n /**\n * Пропсы для компонента dropdown в котором будут скрыты правые фичи при адаптивной компрессии\n */\n rightSideDropdownProps?: TableDropdownConfigProps;\n /**\n * Активна ли фича компрессии (сжатие ToolsMenu при адаптиве)\n * @default true\n */\n enableAdaptiveCompress?: boolean;\n /**\n * Панель массовых действий\n */\n massActionPanel?: {\n /**\n * Кнопки панели. Размеры кнопок/дропдаунов панель подбирает сама (по `size` панели и компактности) —\n * передавать `size` кнопкам не нужно. Если `size` на кнопке всё же задан — он используется как есть.\n */\n buttons: MassActionButtonProps[];\n /**\n * Пропсы для Dropdown, в который сжались кнопки\n */\n collapsedDropdownProps?: TableDropdownConfigProps;\n /**\n * Отступ панели снизу от контейнера (px)\n * @default 24\n */\n bottom?: number;\n /**\n * Управление отображением панели массовых действий.\n * - `undefined` (по умолчанию) — стандартное поведение (показывается при selecting + выбранных строках)\n * - `false` — панель не рендерится, разработчик управляет действиями самостоятельно\n * - `true` — панель показывается всегда, даже без активного selecting и выбранных строк\n */\n show?: boolean;\n /**\n * Размерная сетка панели внутри таблицы: `m`/`s` — обычный размер, `xs` — уменьшенный (кнопки `xxs`, «ещё» `xs`, счётчик Body XS).\n * Viewport-логика (1280) в таблице не используется.\n * @default 's'\n */\n size?: MassActionsSize;\n };\n};\n\n/** Пропсы кнопки редактирования. onClick исключён — используйте onSave/onCancel/onEnableEditing. */\nexport type EditingButtonProps = Omit<\n Partial<ControlBlockButtonProps>,\n | 'onClick'\n | 'size'\n | 'dropdown'\n | 'isTargetAction'\n | 'skipRightDivider'\n | 'tooltipText'\n>;\n\nexport type EditingConfig<\n RowType extends ObjectForExtending,\n RowIdType,\n SummaryRowType,\n> = {\n /**\n * Функция обработки изменений в редактируемой строке\n */\n onRowsChange: Maybe<\n (rows: RowType[], data: RowsChangeData<RowType, SummaryRowType>) => void\n >;\n /**\n * свойство, необходимое для корректного изменения дочерних строк.\n * Данное свойство обязательно, если ваши дочерние строки установлены не под ключом \"subRows\" внутри строки.\n *\n * Как дочерние строки можно указывать свойство, которые вложено в другое свойство.\n * В таком случае \".\" будет знаком для обозначения сл. уровня вложенности.\n *\n * @example \"child\" или \"uvh367.children\"\n */\n subRowsKey?: string;\n /**\n * Глубокое копирование строк перед применением правки в режиме редактирования.\n *\n * Включите, если строки, передаваемые в таблицу, иммутабельны/заморожены\n * (напр. стейт под управлением Redux Toolkit или Immer — они вызывают\n * Object.freeze в dev). При редактировании дочерней строки таблица записывает\n * изменение ВНУТРЬ объекта родителя; на замороженном объекте это падает с\n * `TypeError: Cannot assign to read only property`.\n *\n * Когда флаг включён, таблица сама делает structuredClone редактируемой строки\n * перед записью — ваш иммутабельный стейт не мутируется, и редактирование\n * дочерних строк работает без действий с вашей стороны.\n *\n * ⚠️ Данные строки должны быть сериализуемыми. Где доступен structuredClone —\n * Date/Map/Set и вложенные структуры копируются корректно; на старых средах\n * без structuredClone используется JSON-фоллбэк (теряет Date/Map/Set, undefined\n * и функции). Не включайте без необходимости — глубокое копирование добавляет\n * накладные расходы.\n *\n * @default false\n */\n deepCloneRows?: boolean;\n /**\n * Функция определения уникального id строки\n * @param row\n * @returns\n */\n rowKeyGetter: (row: RowType) => RowIdType;\n /**\n * Функция определения возможности редактирования строки\n * @param row\n * @returns\n */\n rowEditable?: (row: RowType) => boolean;\n /**\n * defaultEnabled - пропс, отвечающий за то, будет ли активен режим редактирования или нет. По умолчанию - не активно.\n * @default false\n */\n defaultEnabled?: boolean;\n /**\n * enabled - необходим для управления режимом редактирования снаружи компонента Таблицы.\n * По умолчанию, управление происходит в компоненте.\n * Приоритетнее, чем defaultEnabled.\n *\n * @type boolean - если НЕ нужно переключение в самой таблице\n * @type [boolean, React.Dispatch<React.SetStateAction<boolean>>] - если нужно переключение в самой таблице\n *\n */\n enabled?: boolean | [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n /**\n * Cостояние скрытия/раскрытия кнопки включения/выключения фичи\n * @default true\n */\n showButtons?: boolean;\n /**\n * Функция, вызывающаяся при включении фичи.\n * @param enableEditorMode - функция включающая режим редактирования\n */\n onEnableEditing?: (enableEditorMode: () => void) => void;\n /**\n * Функция, вызывающаяся при сохранении отредактированного.\n * @param disableEditorMode - функция выключающая режим редактирования\n */\n onSave?: (disableEditorMode: () => void) => void;\n /**\n * Функция, вызывающаяся при отмене отредактированного.\n * @param disableEditorMode - функция выключающая режим редактирования\n */\n onCancel?: (disableEditorMode: () => void) => void;\n /** Пропсы кнопок в controlBlock. */\n buttons?: {\n save?: EditingButtonProps;\n cancel?: EditingButtonProps;\n edit?: EditingButtonProps;\n };\n /**\n * Кастомный слот, отображаемый левее кнопок «Отменить» / «Сохранить».\n * Виден только когда режим редактирования активен (editMode = true).\n * Зона ответственности разработчика — размерная сетка controlBlock не влияет на этот слот.\n */\n editModeLeftSlot?: React.ReactNode;\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n domMetadata?: {\n enableButton?: DomMetadata;\n saveButton?: DomMetadata;\n cancelButton?: DomMetadata;\n };\n};\n\nexport type SummaryRowsConfig = {\n showDefault: boolean;\n showInControl: boolean;\n /**\n * callback при переключении тогла «Итоговые строки» в настройках таблицы.\n * Вызывается только по действию пользователя (не при монтировании),\n * поэтому подходит для сохранения выбора, например, в localStorage.\n * Сохранённое значение передавайте обратно в `showDefault`.\n */\n onChange?: (checked: boolean) => void;\n} & {\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n domMetadata?: DomMetadata;\n};\n\n/**\n * Конфиг тултипа при hover по canvas-элементам.\n * Для активации фичи необходимо заполнить данный конфиг,\n * а также добавить нужные изменения в Canvas-элементах или в конфиге колонки.\n */\nexport type TableConfigTooltip = {\n /**\n * Включить/выключить колоночные и кастомные тултипы (cellTooltip, headerCellTooltip).\n * Внутренние тултипы (drag-иконка в шапке и другие по nodeId) работают всегда.\n * @default false\n */\n enabled?: boolean;\n /** Глобальная задержка перед показом тултипа (мс). Per-node переопределяет. @default 500 */\n mouseEnterDelay?: number;\n /** Глобальная задержка перед скрытием тултипа (мс). Per-node переопределяет. @default 0 */\n mouseLeaveDelay?: number;\n /**\n * Минимальная ширина тултипа. Число трактуется как px, строка с единицей\n * (например '20rem', '50%') отдаётся как есть. Действует на все canvas-тултипы,\n * включая авто-тултип Canvas.Text. Если ширина задана на самом тултипе\n * (per-node), приоритет у неё.\n */\n minWidth?: number | string;\n /**\n * Максимальная ширина тултипа. Число трактуется как px, строка с единицей\n * (например '20rem', '50%') отдаётся как есть. Действует на все canvas-тултипы,\n * включая авто-тултип Canvas.Text. Если ширина задана на самом тултипе\n * (per-node), приоритет у неё.\n */\n maxWidth?: number | string;\n};\n\nexport type InfinityScrollConfig<RowType extends ObjectForExtending> = {\n /** Триггер достижения скроллом зоны подгрузки данных. */\n onTrigger: (rows: RowType[]) => Promise<void> | void;\n /** Состояние загрузки (скелетоны) новых строк. */\n isLoading: boolean;\n /**\n * Флаг, когда все данные загружены — false.\n * @default true\n */\n hasMore?: boolean;\n /**\n * Для mode='region': за сколько строк до конца триггерить загрузку.\n * @default 5\n */\n rowThreshold?: number;\n};\n\nexport type { TableCanvasEmptyStateConfig, TableCanvasErrorStateConfig };\n\n/**\n * Настройка выделения ячеек/колонок/строк в TableCanvas — единый объект.\n * Это отдельная ось взаимодействия — не зависит от `highlightActiveType`.\n */\nexport type CellsSelectionConfig = {\n /**\n * Режим фактического выделения ячеек (нативный glide selection). По нему\n * работают copy/paste, рамка, fill-handle и затемнение шапки/нумерации.\n * @default \"range-cell\"\n */\n mode?: CellsSelectionMode;\n /**\n * Выделение колонок по клику на шапку. Ctrl/Cmd — добавить/убрать колонку,\n * Shift — диапазон колонок. Клик по иконкам сортировки/фильтрации в шапке\n * выделение НЕ вызывает. Поддерживает copy/paste по выделенным колонкам.\n * @default true\n */\n enableColumnSelection?: boolean;\n /**\n * Выделение строк по клику/драгу на колонке нумерации (`rowMarkers`).\n * Ctrl/Cmd — несмежный выбор отдельных строк, драг — смежный диапазон.\n * Поддерживает copy/paste по выделенным строкам. Требует включённой колонки\n * нумерации (`rowMarkers`). При `false` клик по нумерации ничего не выделяет.\n * @default true\n */\n enableRowSelection?: boolean;\n /**\n * Выделение всей таблицы кликом по «нулевой» ячейке — шапке колонки нумерации\n * (левый верхний угол). Выделяет все строки данных по всем колонкам одним\n * диапазоном; поддерживает copy/paste. Требует включённой колонки нумерации\n * (`rowMarkers`) и активного `mode` (≠ `disabled`).\n * @default true\n */\n enableSelectAll?: boolean;\n /**\n * Внешний (controlled) контроль НАТИВНОГО выделения (ячейки/диапазон/смежные\n * строки и колонки). `state` — кортеж `[value, setter]` как у `selecting.state`.\n * Сброс: `setter({ current: undefined, rows: empty, columns: empty })`.\n * Несмежный Ctrl-выбор колонок/строк (own-state) сюда не входит — он внутренний.\n */\n state?: [GridSelection, React.Dispatch<React.SetStateAction<GridSelection>>];\n};\n\n/** Один объединённый блок: какие строки и колонки слить. */\nexport type MergedCellsRegion = {\n rowKeys: Array<string | number>;\n colKeys: string[];\n /** Выравнивание контента этого блока. Важнее колоночного и общего. */\n mergedCellsAlign?: MergedCellsAlign;\n};\n\n/**\n * Видимость сторон рамки ячейки: true рисовать, false не рисовать, не задано -\n * работает уровень ниже (настройка колонки, строки или общая).\n */\nexport type CellBorderVisibility = {\n top?: boolean;\n right?: boolean;\n bottom?: boolean;\n left?: boolean;\n};\n\n/**\n * Управление рамками (линиями) таблицы: включение и выключение. Уровни, от\n * слабого к сильному: общие настройки (vertical, horizontal), затем колонка\n * (getVerticalBorder) и строка (getHorizontalBorder), затем ячейка\n * (getCellBorder).\n */\nexport type BordersConfig<RowType = ObjectForExtending> = {\n /** Рисовать ли вертикальные линии между колонками. @default true */\n vertical?: boolean;\n /** Рисовать ли горизонтальные линии между строками тела. @default true */\n horizontal?: boolean;\n /**\n * Точечное управление вертикальной линией справа от колонки (разделитель\n * после неё). Вернуть true или false, чтобы переопределить общую настройку\n * vertical, или undefined, чтобы оставить её. Зовётся на каждую видимую\n * колонку при перерисовке, поэтому функция должна быть быстрой.\n */\n getVerticalBorder?: (params: {\n /** Ключ колонки, справа от которой рисуется линия. */\n columnKey: string;\n /** Индекс колонки в порядке отрисовки (закреплённые в начале). */\n columnIndex: number;\n }) => boolean | undefined;\n /**\n * Точечное управление горизонтальной линией сверху строки. Вернуть true или\n * false, чтобы переопределить общую настройку horizontal, или undefined,\n * чтобы оставить её. Для summary-строк не вызывается. Зовётся на каждую\n * видимую строку при перерисовке, поэтому функция должна быть быстрой.\n */\n getHorizontalBorder?: (params: {\n /** Строка под линией (линия рисуется сверху этой строки). */\n row: RowType;\n /** Индекс строки среди отображаемых. При раскрытии subRows индексы сдвигаются. */\n rowIndex: number;\n /** Уровень вложенности subRows: 0 корень, 1 и больше дочерние. */\n treeLvl: number;\n }) => boolean | undefined;\n /**\n * Стороны рамки конкретной ячейки, вкл и выкл. Для ячеек без переопределений\n * возвращать undefined. Включает отрисовку линий с разбивкой по ячейкам,\n * поэтому функция должна быть быстрой: без тяжёлых вычислений и с готовыми\n * объектами-константами вместо новых на каждый вызов. Для summary-строк не\n * вызывается.\n */\n getCellBorder?: (params: {\n /** Индекс колонки среди отображаемых (без служебных). */\n col: number;\n /** Ключ колонки. */\n columnKey: string | undefined;\n /** Строка ячейки. */\n row: RowType;\n /** Индекс строки среди отображаемых. */\n rowIndex: number;\n /** Уровень вложенности subRows: 0 корень, 1 и больше дочерние. */\n treeLvl: number;\n }) => CellBorderVisibility | undefined;\n};\n\nexport type TableConfig<\n RowType extends ObjectForExtending,\n SummaryRowType,\n RowIdType extends string | number,\n FilterStateType extends ObjectForExtending,\n // SubRowType\n> = {\n /**\n * Группировка колонок (многоуровневая шапка через `columnConfig.children`):\n * объединение пустых ячеек шапки (`squashEmptyCells`, по умолчанию включено) и\n * дефолт выравнивания в объединённых ячейках (`squashedHeaderAlign`).\n */\n columnsGrouping?: ColumnsGroupingConfig;\n /**\n * Подсветка активной сущности в canvas-таблице.\n * @deprecated Значения `'cell'`/`'range-cell'` устарели — используйте\n * `cellsSelection.mode`. Актуальны `'row'` (подсветка строки) и `'disabled'`.\n */\n highlightActiveType?: HighlightActiveType;\n /**\n * Единый конфиг выделения ячеек: режим (`mode`), оси\n * (`enableColumnSelection`/`enableRowSelection`/`enableSelectAll`) и controlled\n * (`state`). См. {@link CellsSelectionConfig}.\n */\n cellsSelection?: CellsSelectionConfig;\n /**\n * Подсвеченная строка (`highlightActiveType='row'`).\n * `state` (опционально) — controlled-кортеж `[value, setter]`: задан — значением\n * владеешь снаружи (сброс `setter(undefined)`); не задан — таблица крутит\n * подсветку внутренним стейтом, а `onChange` всё равно срабатывает (подписка\n * без владения значением).\n */\n highlightActiveRow?: {\n state?: [\n number | undefined,\n React.Dispatch<React.SetStateAction<number | undefined>>,\n ];\n /**\n * Колбэк смены подсвеченной строки: отдаёт её флэт-индекс и сам объект\n * строки (`rows[index]`). Позволяет открывать данные подсвеченной строки\n * (например, в SplitView) без `onCellClicked`.\n */\n onChange?: (params: {\n index: number | undefined;\n row: RowType | undefined;\n }) => void;\n };\n /**\n * Эффекты при наведении (hover)\n * `row` — подсветка строки под курсором.\n * Независимая визуальная ось: селектинг (`cellsSelection`) и `highlightActiveType='row'`\n * рисуются ПОВЕРХ hover-подсветки и визуально перекрывают её (hover\n * «остаётся под ними» и снова виден после сброса выделения).\n *\n * `{ row: true }` — включить с цветами из темы;\n * `{ row: { color: '#F7F9FB' } }` — переопределить цвет data-ячеек.\n * @default undefined (выключено)\n */\n hoverEffects?: HoverEffectsConfig;\n /**\n * Включает компенсацию тонких canvas-линий при browser zoom ниже 100%, когда devicePixelRatio меньше 1.\n * Влияет только на grid/header/sticky hairline borders.\n * @default false\n */\n enableLowDprHairline?: boolean;\n /**\n * Управление рамками (линиями) таблицы: включение и выключение.\n *\n * Уровни, от слабого к сильному: общие настройки (vertical, horizontal),\n * затем колонка (getVerticalBorder) и строка (getHorizontalBorder), затем\n * ячейка (getCellBorder).\n *\n * `vertical: false` и `horizontal: false` убирают все вертикальные или\n * горизонтальные линии тела. `getCellBorder` включает и выключает стороны\n * рамки конкретной ячейки; при его использовании линии рисуются с разбивкой\n * по ячейкам.\n */\n borders?: BordersConfig<RowType>;\n /**\n * rowSize - размеры строк таблицы\n */\n rowSize?: Prettify<RowSize>;\n /**\n * rowHeight - размер высоты строк таблицы\n */\n rowHeight?: Maybe<number | RowHeightFunc<RowType>>;\n /**\n * sorting - активация сортировки. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={sorting: {sortingState}}\n *\n * columnConfig=[{sortingType: 'numberSort'}]\n */\n sorting?: {\n state: [\n readonly SortColumn[],\n React.Dispatch<React.SetStateAction<readonly SortColumn[]>>,\n ];\n /**\n * manualSorting - пропс, активирующий ручную-кастомную (или на стороне бэкенда) сортировку\n */\n manualSorting?: boolean;\n };\n /** @deprecated Свойство view не используется и будет удалено в следующей мажорной версии. */\n view?: View;\n /**\n * filtering - активация фильтрации. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={filtering: {stateAndSetter, ...}}\n *\n * columnConfig=[{filtering: {...}}]\n */\n filtering?: FilteringConfig<FilterStateType>;\n /**\n * Сворачивание / разворачивание таблицы\n */\n collapsing?: TableCollapseConfig;\n /**\n * selecting - активация выбора строк. Условие активации - это наличие данного свойства.\n * Есть поддержка выбора строк с многоуровневой вложенностью.\n *\n * Пример:\n *\n *```jsx\n * import { Table } from '@daisforge/ui';\n *\n * <Table\n * tableConfig={{selecting: {stateAndSetter, rowKeyGetter}}}\n * {...rest}\n * />\n * ```\n */\n selecting?: {\n state: [\n ReadonlySet<RowIdType>,\n React.Dispatch<React.SetStateAction<ReadonlySet<RowIdType>>>,\n ];\n rowKeyGetter: (row: RowType) => RowIdType;\n } & Prettify<SelectingRowConfig<RowType, RowIdType>> & {\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n controlBlock?: {\n domMetadata?: DomMetadata;\n };\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам RightSidebar\n */\n sidebar?: {\n domMetadata?: DomMetadata;\n };\n };\n /**\n * editing - активация редактирования. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={editing: {onRowsChange, rowKeyGetter}}\n *\n * columnConfig=[{editingCell: {...}}]\n */\n editing?: EditingConfig<RowType, RowIdType, SummaryRowType>;\n\n /**\n * cellTransfer — конфигурация копирования, вставки и fill handle.\n * По умолчанию копирование (Ctrl+C) работает в режиме редактирования.\n * Данные копируются в формате TSV (tab-separated values), совместимом с Excel.\n *\n * Пример:\n *\n * tableConfig={{ cellTransfer: { enabled: true, onBeforeCopy: (data) => data } }}\n */\n cellTransfer?: CellTransferConfig;\n\n /**\n * Объединение ячеек тела таблицы.\n *\n * mergeByCellValues — колонки, в которых подряд идущие одинаковые значения\n * сливаются в один блок (по вертикали). Границы блоков таблица считает сама из\n * данных; сортировка и фильтр их пересобирают. Данные не меняются — значение и\n * так повторяется в строках, объединение лишь показывает его одной ячейкой.\n *\n * mergedCellsRegions — список блоков, заданных снаружи (как выделение): каждый\n * блок описан ключами строк (rowKeys) и колонок (colKeys). Нужен rowKeyGetter.\n * Если после сортировки или скрытия колонок строки/колонки блока перестали идти\n * подряд — блок не рисуется. Важнее mergeByCellValues.\n *\n * Примеры: mergeCells={{ mergeByCellValues: ['dept', 'role'] }},\n * mergeCells={{ mergedCellsRegions, rowKeyGetter: (r) => r.id }}.\n */\n mergeCells?: {\n mergeByCellValues?: Array<\n string | { colKey: string; value: (row: RowType) => unknown }\n >;\n /** Список блоков, заданных снаружи (по ключам строк и колонок). */\n mergedCellsRegions?: MergedCellsRegion[];\n /**\n * Нужен для mergedCellsRegions: находит строку по её ключу. Должна быть\n * стабильной функцией; менять её на лету не нужно — в пересборку таблицы она\n * не входит.\n */\n rowKeyGetter?: (row: RowType) => string | number;\n /**\n * Выравнивание по умолчанию для всех блоков. Колоночный mergedCellsAlign и\n * выравнивание конкретного региона важнее.\n */\n mergedCellsAlign?: MergedCellsAlign;\n };\n\n /**\n * Модуль нотификаций: стандартизированный канал событий для внешних\n * потребителей. Таблица UI не рисует — вызывает `onNotification`, потребитель\n * показывает тост/модалку на своей стороне. Сейчас эмитятся ошибки copy/paste\n * (в т.ч. multi-range 2D-разброс, readonly/overflow-abort, пропуск валидацией).\n */\n notifications?: TableNotificationsConfig;\n\n /**\n * subRows - активация иерархии, отображения вложенных строк. Условие активации - наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={subRows: {getSubRows, rowKeyGetter}}\n *\n * columnConfig=[{subRow: {...}}]\n */\n subRows?: SubRows<RowType, RowIdType>;\n /**\n * Столбец с нумерацией строк.\n * Активируется наличием этого свойства. Поддерживает `subRows` любой глубины.\n *\n * @see {@link RowMarkersTableConfig} — полное описание конфигурации и примеры.\n */\n rowMarkers?: RowMarkersTableConfig<RowType>;\n rowsGrouping?: RowsGrouping<RowType, SummaryRowType>;\n\n /**\n * resizableColumn - активация изменения ширины колонки с помощью курсора. Условие активации - resizableColumn: true. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={resizableColumn: true}\n *\n * columnConfig=[{resizable: true}]\n */\n resizableColumn?: boolean;\n /**\n * style - inline-стили. Для стилей самой таблицы (без вложенности).\n *\n * Исключены свойства 'width' | 'height' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'. Их следует стилизовать через свойства containerStyle.\n */\n style?: Omit<\n CSSProperties,\n 'width' | 'height' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'\n >;\n /**\n * css - для стилей простых и сложных(например, для стилизации cell, headerCell, ...).\n *\n * Пример:\n *\n * ```css\n * & > .rdg-header-row > .rdgCell {\n * background-color: red;\n * }\n * ```\n *\n */\n css?: string | CSSObject;\n\n summaryRows?: SummaryRowsConfig;\n /**\n * controlBlock - пропс для активации, кастомизации контролблока.\n */\n controlBlock?: ControlBlockConfig;\n /**\n * containerStyle - инлайновые стили контейнера таблицы и контролблока. высоту и ширину для таблицы рекомендуется задавать в этом пропсе.\n * Пример:\n *\n * ```tsx\n tableConfig={{ containerStyle: { height: '70vh' } }}\n * ```\n */\n containerStyle?: CSSProperties | undefined;\n /**\n * containerCss - стили для контейнера таблицы и контролблока.\n * Через этот пропс можно дополнительно кастомизировать контейнер и все его дочерние элементы.\n */\n containerCss?: string | CSSObject | undefined;\n /**\n * containerId - html-атрибут id контейнера таблицы.\n */\n containerId?: string | undefined;\n\n /**\n * unstickyHeader - откреплённая шапка. Header уезжает вместе со скроллом контента.\n * @default false\n */\n unstickyHeader?: boolean;\n\n /** Тултип при hover по canvas-элементам.\n * Для активации фичи необходимо заполнить данный конфиг,\n * а также добавить нужные изменения в Canvas-элементах или в конфиге колонки.\n */\n tooltip?: TableConfigTooltip;\n\n /**\n * infinityScroll - бесконечная подгрузка данных при скролле.\n *\n * Условие активации - наличие самого пропса infinityScroll.\n *\n * При активации infinityScroll отключается дефолтная сортировка и фильтрация.\n * (Предполагается, что если есть infinityScroll,\n * то в таблице представлен не весь объем данных,\n * по этой причине дефолтная сортировка и фильтрация не подходят и будут отображать некорректные данные)\n *\n */\n infinityScroll?: InfinityScrollConfig<RowType>;\n /**\n * @isLoading - состояние загрузки данных для таблицы.\n */\n isLoading?: boolean | { boolean: boolean; skeletonRowsCount: number };\n /**\n * loadingOverlay - конфигурация для отображения оверлея загрузки.\n * Показывает индикатор загрузки поверх таблицы с возможностью кастомизации.\n */\n loadingOverlay?: {\n /**\n * Активен ли оверлей загрузки\n * @default true\n */\n active?: boolean;\n /**\n * Кастомный компонент спиннера\n * @default <Spinner view=\"secondary\" size=\"36\" /> (внутренний компонент)\n */\n spinner?: ReactNode;\n /**\n * Основной заголовок оверлея\n * @default \"Загрузка таблицы\"\n */\n title?: string;\n /**\n * Подзаголовок, который появится после задержки, пустая строка - значит он не появится\n * @default \"\"\n */\n subtitle?: string;\n /**\n * Задержка перед показом подзаголовка (мс)\n * @default 10000 (10 секунд)\n */\n showSubtitleDelay?: number;\n };\n /**\n * Empty state внутри content-области canvas-таблицы.\n * Не заменяет control block, header или pagination.\n */\n emptyState?: TableCanvasEmptyStateConfig;\n /**\n * Error state внутри content-области canvas-таблицы.\n * Не заменяет control block, header или pagination.\n */\n errorState?: TableCanvasErrorStateConfig;\n // FIXME:\n // noRowsFallback?: boolean | { custom: ReactNode };\n columnsControl?: ColumnsControlConfig;\n // FIXME:\n // rowDetailPanel?: RowDetailConfig<RowType>;\n // FIXME: Временно комментирую использование, пока не адаптируем TableCanvas\n // rowInstruments?: {\n // getRowDropdownConfig: RowInstrumentsType<RowType>;\n // /**\n // * @default false\n // */\n // defaultOpened?: boolean;\n // /**\n // * @default true\n // */\n // showInControl?: boolean;\n // /**\n // * Внешний стейт видимости\n // */\n // openedState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n // };\n fullScreenEnabled?: FullScreen;\n /**\n * Переносит портал editor overlay внутрь контейнера таблицы вместо document.body.\n * Решает проблему focus trap и сдвига координат при рендере таблицы в модалке с CSS transform.\n * @default undefined (overlay рендерится в document.body — стандартное поведение)\n */\n editorOverlayPortal?: 'inside';\n keyText?: boolean | KeyTextConfig;\n /**\n * pagination - пропс для пагинации.\n *\n * Условие активации - наличие самого пропса pagination.\n *\n * При активации pagination отключается дефолтные поиск, сортировка и фильтрация.\n * (поиск работает на уровне с фильтрацией и сортировкой, сначала поиск, затем фильтрация, затем сортировка)\n *\n */\n pagination?: PaginationProps;\n /**\n * searching - пропс для поиска по таблицу.\n *\n * Условие активации - наличие searching.enabled: true\n *\n */\n /**\n * Конфигурация табов в сайдбаре\n */\n sidebarConfig?: SidebarConfig;\n searching?: SearchingProps;\n /**\n * onHeaderContextMenu - callback открытия контекстного меню.\n */\n onHeaderContextMenu?: TableGlideInstanceProps<\n RowType,\n SummaryRowType\n >['onHeaderContextMenu'];\n onHeaderContextMenuDropdown?: TableGlideInstanceProps<\n RowType,\n SummaryRowType\n >['onHeaderContextMenuDropdown'];\n onCellContextMenuDropdown?: TableGlideInstanceProps<\n RowType,\n SummaryRowType\n >['onCellContextMenuDropdown'];\n onCellContextMenu?: TableGlideInstanceProps<\n RowType,\n SummaryRowType\n >['onCellContextMenu'];\n /**\n * Обработчик клика по ячейке.\n *\n * Получает `cell` readonly [colIndex, rowIndex] от glide, и `info` обогащённый объект\n * с row, column, ctxs, refTable (аналогично onCellContextMenu).\n */\n onCellClicked?: (\n cell: readonly [number, number],\n info: TableInfoWithRow<RowType, SummaryRowType>,\n ) => void;\n} & GlideInstanceOmitted<RowType, SummaryRowType>;\n\ntype GlideInstanceOmitted<\n RowType extends ObjectForExtending,\n SummaryRowType,\n> = Pick<\n Omit<\n TableGlideInstanceProps<RowType, SummaryRowType>,\n | keyof TableGlideCustomProps<RowType, SummaryRowType>\n | 'CellReadOnlyEditor' /* CellReadOnlyEditor - свойство только для GlideInstance */\n >,\n | 'className'\n | 'columnSelect'\n | 'minColumnWidth'\n | 'maxColumnWidth'\n | 'maxColumnAutoWidth'\n | 'onVisibleRegionChanged'\n | 'onCellClicked'\n // | 'CellReadOnlyEditor'\n // | 'onGroupHeaderClicked'\n | 'onHeaderClicked'\n | 'onItemHovered'\n | 'trapFocus'\n | 'onColumnResize'\n>;\nexport type CellReadOnlyEditorProps<\n RowType extends ObjectForExtending,\n SummaryRowType,\n> = CellReadOnlyEditorGlideInstanceStaticProps &\n EditingCellInfo<RowType, SummaryRowType>;\n\n// & Pick<\n// DataGridPropsDefault<RowType, SummaryRowType, RowIdType>,\n// | 'summaryRowHeight'\n// | 'onFill'\n// | 'onCopy'\n// | 'onPaste'\n// | 'onCellClick'\n// | 'onCellDoubleClick'\n// | 'onCellContextMenu'\n// | 'onCellKeyDown'\n// | 'onSelectedCellChange'\n// | 'onScroll'\n// | 'onColumnResize'\n// | 'onColumnsReorder'\n// | 'enableVirtualization'\n// | 'rowClass'\n// | 'data-testid'\n// | 'headerRowHeight'\n// >;\n\n/**\n * Конфигурация фичи rowMarkers (столбец с нумерацией строк).\n *\n * Столбец frozen, вставляется первым, исключён из reorder/pin/hide/sort/grouping.\n * Поддерживает плоский и древовидный (`subRows`) режимы любой глубины вложенности.\n *\n * **Дефолтное поведение** (без `getRowMarker`): root-only нумерация —\n * корневые строки получают номер (`startIndex + rootIndex`), дочерние — пустую строку.\n *\n * @example\n * ```tsx\n * // Минимальная конфигурация\n * tableConfig={{ rowMarkers: { startIndex: 1 } }}\n *\n * // Сквозная стабильная нумерация\n * tableConfig={{ rowMarkers: { getRowMarker: ({ flatIndex }) => flatIndex + 1 } }}\n * ```\n */\nexport type RowMarkersTableConfig<\n RowType extends ObjectForExtending = ObjectForExtending,\n> = {\n /**\n * Стартовый индекс нумерации (для дефолтной логики без `getRowMarker`).\n * @default 1\n */\n startIndex?: number;\n\n /**\n * Ширина столбца с нумерацией (в px).\n * Если задан `size` — он приоритетнее.\n+ * Если ни `size`, ни `width` не заданы — ширина подстраивается\n+ * под глобальный `tableConfig.rowSize` (small=20, medium=32, big=48).\n * @default 32\n */\n width?: number;\n /**\n * Размер столбца. Приоритетнее `width`.\n * - `xs` = 20px\n * - `s` = 32px\n * - `m` = 48px\n */\n size?: 'xs' | 's' | 'm';\n /**\n * Кастомная функция нумерации. Полностью переопределяет дефолтную root-only логику.\n * Вызывается при рендере каждой ячейки столбца нумерации.\n *\n * ⚠️ Вызывается не только при полной отрисовке таблицы, но и при ховере/скролле —\n * для **одной** ячейки. Не используйте внешние переменные-счётчики —\n * используйте аргументы (`siblingPath`, `flatIndex` и др.), они всегда актуальны.\n *\n * @example\n * // Сквозная стабильная нумерация (все строки, номера не прыгают при сворачивании)\n * getRowMarker: ({ flatIndex }) => flatIndex + 1\n *\n * @example\n * // Корневые — номер, дочерние — прочерк\n * getRowMarker: ({ isSubRow, flatIndex }) => isSubRow ? '—' : flatIndex + 1\n *\n * @example\n * // Иерархическая нумерация любой глубины: 1, 1.1, 1.1.1, 1.2, 2\n * getRowMarker: ({ siblingPath }) => siblingPath.map(i => i + 1).join('.')\n */\n getRowMarker?: (args: {\n /** Данные текущей строки. */\n row: RowType;\n /** Уровень строки в дереве: `0` — корневая, `1` — дочерняя, `2` — внучка, и т.д. */\n level: number;\n /** `true`, если строка дочерняя (`level > 0`). */\n isSubRow: boolean;\n /**\n * Индекс строки в **видимых** строках.\n * **Нестабильный** — меняется при сворачивании и разворачивании веток.\n */\n rowIndex: number;\n /**\n * Стабильный 0-based индекс строки в **полном** дереве (включая скрытые/свёрнутые).\n * Не меняется при collapse/expand — подходит для сквозной нумерации.\n */\n flatIndex: number;\n /**\n * Порядковый номер среди siblings одного родителя (0-based).\n * Для корневых строк — порядковый номер среди всех корневых.\n * Для дочерних — порядковый номер среди children одного `parentKey`.\n */\n siblingIndex: number;\n /**\n * Путь siblingIndex-ов от корня до текущей строки (каждый элемент 0-based).\n *\n * Примеры:\n * - корневая строка (2-я): `[1]`\n * - дочерняя (3-й ребёнок 2-го корня): `[1, 2]`\n * - внучка (1-й ребёнок 1-го ребёнка 1-го корня): `[0, 0, 0]`\n *\n * Для иерархической нумерации: `siblingPath.map(i => i + 1).join('.')` → `\"1.1.1\"`\n *\n * Для плоской таблицы (без subRows): всегда `[siblingIndex]` (один элемент).\n */\n siblingPath: number[];\n /**\n * Ключ родительской строки (`rowKeyGetter(parent)`).\n * `null` для корневых строк. Работает для **любой** глубины вложенности.\n */\n parentKey: string | number | null;\n /** Текущий видимый `flattened` массив строк. */\n rows: readonly RowType[];\n }) => string | number;\n};\n```\n\n## FilterComponentInPopoverProps\n\nПропсы, доступные в кастомном компоненте фильтра (`component: 'custom'`).\n\n```typescript\ntype FilterComponentInPopoverProps<\n FilterStateType extends ObjectForExtending,\n ColumnConfig,\n> = {\n popoverIsOpen: boolean;\n setPopoverIsOpen: React.Dispatch<React.SetStateAction<boolean>>;\n columnConfig: ColumnConfig;\n tabIndex: number;\n headerContextState: HeaderContextValueTypeInstance<FilterStateType> &\n FiltersVariables &\n HeaderContextValueTypeInstance<ObjectForExtending>;\n /**\n * Источник открытия фильтра: из шапки таблицы или из сайдбара\n * Полезно для условной логики в customRender (например, alwaysOpened для combobox)\n */\n filterSource?: 'header' | 'sidebar';\n};\n```",
54412
+ "apiDocs": "# Filtering API\n\n## FilteringConfig\n\n```typescript\ntype FilteringConfig<T> = {\n state: [T, React.Dispatch<React.SetStateAction<T>>];\n /**\n * @deprecated Использовать filtersInfo\n *\n * clearedValue - состояние фильтров после очистки. Используется для сравнения:\n * Например, был ли фильтр конкретной колонки изменен рассчитывается посредством сравнения текущего значения фильтра и значения фильтра в clearedValue.\n * Если они равны, то фильтр считается не измененным.\n */\n clearedValue?: T;\n /**\n * Информация о фильтрах для каждой колонки.\n * Используется для:\n * 1. Хранения меток (label) фильтров для отображения в UI\n * 2. Хранения значений по умолчанию (clearedValue) для каждого фильтра\n * 3. Определения, был ли фильтр изменен (сравнение текущего значения с clearedValue)\n */\n filtersInfo?: Record<\n keyof T,\n {\n label: string;\n clearedValue: T[keyof T];\n }\n >;\n /**\n * manualFiltering - пропс, активирующий ручную-кастомную (или на стороне бэка) фильтрацию.\n * @remarks\n * Для автоматической фильтрации (когда не используется manualFiltering в tableConfig):\n * - Для всех типов фильтров обязательно должен быть указан `valueInRow`\n * - Для component: 'select' дополнительно должен быть указан `filteringType`\n * - Для component: 'input' с кастомным фильтром (когда filter - функция)\n * функция фильтрации должна быть передана явно\n *\n * Если используется manualFiltering, эти параметры не обязательны,\n * так как вся логика фильтрации реализуется извне.\n */\n manualFiltering?: boolean;\n /**\n * Конфигурация для отображения фильтров в правом сайдбаре.\n *\n * Позволяет:\n * 1. Добавлять глобальные фильтры (не привязанные к конкретной колонке)\n * 2. Управлять порядком отображения фильтров\n * 3. Переопределять рендер и заголовки колоночных фильтров\n *\n * Логика работы:\n * - По умолчанию в сайдбаре отображаются все колоночные фильтры (из columnConfig)\n * - Ключом фильтра считается `key` колонки, если его нет, то пытаемся взять `keyInFilterState` (если указан), иначе это не будет работать\n * - Заголовком фильтра по умолчанию является `name` колонки или ключ фильтра (name || key)\n * - Глобальные фильтры добавляются через `items` с уникальными ключами\n *\n * Особенности:\n * 1. Порядок отображения:\n * - Сначала фильтры из `order` (в указанной последовательности)\n * - Затем остальные колоночные фильтры (в порядке columnConfig)\n * - В конце - глобальные фильтры (в алфавитном порядке ключей)\n *\n * 2. Переопределение колоночных фильтров:\n * - Чтобы изменить заголовок: укажите ключ колонки в `items` с новым `label`\n * - Чтобы заменить рендер: укажите ключ колонки с `customRenderFn`\n * - Оригинальный фильтр из колонки будет проигнорирован\n *\n * 3. Глобальные фильтры:\n * - Ключ не должен совпадать с ключами колонок\n * - Обязательно указать `label` и `customRenderFn`\n * - Отображаются после всех колоночных фильтров, если не переопределены в order\n *\n * @example\n * // Добавление глобального фильтра и изменение порядка\n * sidebarConfig: {\n * order: ['status', 'tasks', 'type'], // Сначала статус, затем глобальный поиск\n * items: {\n * tasks: { // Уникальный ключ\n * label: 'Поиск по всем полям',\n * customRenderFn: () => <TaskComponent />\n * },\n * status: { // Переопределение колоночного фильтра\n * label: 'Статус заявки', // Новый заголовок\n * customRenderFn: () => <CustomStatusFilter /> // Кастомный рендер\n * }\n * type: { // Переопределение только Label колоночного фильтра\n * label: 'Тип', // Новый заголовок\n * }\n * }\n * }\n */\n sidebarConfig?: {\n /**\n * Определяет порядок отображения фильтров.\n * - Указываются ключи фильтров (колоночных или глобальных)\n * - Не указанные в order фильтры отображаются после\n * - Если order пуст, сохраняется порядок: глобальные фильтры + columnConfig фильтры в конце\n */\n order?: string[];\n /**\n * Конфигурация фильтров для сайдбара.\n * Ключом может быть:\n * - Ключ колонки (для переопределения колоночного фильтра)\n * - Уникальный ключ (для добавления глобального фильтра)\n */\n items: Partial<\n Record<\n keyof T,\n {\n /** Заголовок фильтра (обязателен для глобальных фильтров), можно использовать для переопределения для локальных фильтров */\n label: string;\n /**\n * Функция рендера компонента фильтра.\n * Для колоночных фильтров переопределяет оригинальный рендер.\n * Для глобальных фильтров обязательна.\n */\n customRenderFn?: (\n filters: T,\n setFilters: React.Dispatch<React.SetStateAction<T>>,\n ) => React.ReactNode;\n }\n >\n >;\n };\n /**\n * Callback для кастомизации стилей чипсов (фильтров) в списке\n *\n * @param {ItemOrGroup} itemOrGroup - Текущий элемент или группа фильтров\n * @param {Item | undefined} item - Конкретный элемент фильтра (если есть)\n * @returns {CSSObject} Объект стилей, который будет применен к чипсу\n *\n * @description\n * Позволяет динамически задавать стили для каждого чипса в зависимости от его типа и содержимого.\n * Вызывается для каждого отображаемого чипса (как для отдельных элементов, так и для элементов внутри групп).\n *\n * @example\n * // Пример 1: Стилизация чипсов по типу\n * chipStyle: (itemOrGroup, item) => {\n * if (isGroup(itemOrGroup)) {\n * return { backgroundColor: '#f0f0f0' };\n * }\n * return { backgroundColor: '#e0e0e0' };\n * }\n *\n * @example\n * // Пример 2: Стилизация по значению фильтра\n * chipStyle: (itemOrGroup, item) => {\n * if (item?.label === 'Высокий приоритет') {\n * return {\n * backgroundColor: '#ffebee',\n * color: '#d32f2f'\n * };\n * }\n * return {};\n * }\n *\n * @example\n * // Пример 3: Разные стили для элементов в группе и одиночных\n * chipStyle: (itemOrGroup, item) => {\n * if (item) {\n * // Стиль для элемента внутри группы\n * return { maxWidth: 180 };\n * }\n * // Стиль для одиночного чипа\n * return { maxWidth: 150 };\n * }\n */\n chipStyle?: (itemOrGroup: ItemOrGroup, item: Item | undefined) => CSSObject;\n /**\n * Пользовательский форматтер заголовка группы чипсов.\n *\n * Используется в блоке активных фильтров для подмены текста заголовка\n * группы (например, “Статус”, “Тип”, “Автор”). Полезно, когда нужно\n * динамически менять подпись (добавить счётчик, i18n и т.п.).\n *\n * @param {ItemOrGroup} itemOrGroup Объект группы (тип Group). Вызов происходит только для групп,\n * поэтому безопасно кастовать к Group.\n * @returns {string} Текст заголовка группы чипсов.\n *\n * @default Возвращается `group.groupLabel`.\n *\n * @remarks\n * - Функция должна быть чистой и быстрой (без сетевых запросов и побочных эффектов).\n * - Возвращайте ТОЛЬКО строку — чипы отображают текстовое значение.\n * - Для длинных строк применяется усечение (overflow с многоточием) на уровне компонента.\n *\n * @example\n * // Добавить двоеточие и количество выбранных элементов\n * renderGroupLabel: (group) => `${group.groupLabel}: ${group.items.length}`\n *\n * @example\n * // Локализация заголовка группы\n * const i18n = { status: 'Статус', type: 'Тип' };\n * renderGroupLabel: (group) => i18n[group.groupId] ?? group.groupLabel\n */\n renderGroupLabel?: (group: Group) => string;\n\n /**\n * Пользовательский форматтер текста чипса (элемента внутри группы или одиночного фильтра).\n *\n * Позволяет управлять тем, что именно отображается внутри каждого чипса. Особенно полезен\n * при серверной пагинации/ленивой загрузке, когда в состоянии фильтра хранится только value,\n * а label необходимо подставить из локального кэша.\n *\n * @param {Group | null } group Группа, внутри которой рендерится чип (или null).\n * @param {Item} item Сам элемент чипса. В группах передаётся конкретный `Item`,\n * для одиночного чипа может быть `undefined`.\n * @returns {string} Текст, который будет показан в чипсе.\n *\n * @default Используется `item?.label.toString()` (или строковое представление value).\n *\n * @remarks\n * - Функция должна быть чистой и быстрой;\n * - Возвращайте ТОЛЬКО строку.\n *\n * @example\n * // 1) Отображение label из кэша при серверной пагинации\n * const labelsCacheRef = useRef(new Map<string, string>());\n * renderChipLabel: (group, item) => {\n * if (item?.id != null) {\n * const key = String(item.id);\n * const fromCache = labelsCacheRef.current.get(key);\n * if (fromCache) return fromCache; // красивый label, если уже загрузили\n * return String(item.label ?? key); // фоллбэк: временно показываем value/label из item\n * }\n * return ''; // безопасный фоллбэк для одиночных случаев\n * }\n *\n * @example\n * // 2) Нормализация отображения числовых значений\n * renderChipLabel: (_group, item) => {\n * const v = Number(item?.label);\n * return Number.isFinite(v) ? v.toLocaleString('ru-RU') : String(item?.label ?? '');\n * }\n *\n * @example\n * // 3) Префикс по типу группы\n * renderChipLabel: (group, item) => {\n * const prefix = group.groupId === 'status' ? '' : '#';\n * return `${prefix}${item?.label ?? item?.id ?? ''}`;\n * }\n */\n renderChipLabel?: (group: Group | null, item: Item) => string;\n};\n\nexport type DefaultSidebarTabIds = 'columns' | 'tableSettings' | 'filtering';\n\n/**\n * Конфигурация sidebar\n */\nexport type SidebarConfig = {\n /**\n * Включен ли sidebar. Отвечает только за UI. Не влияет на перерасчёт фичей.\n * @default true\n */\n enabled?: boolean;\n /**\n * Открыт ли sidebar при первом рендере (uncontrolled-режим).\n * Игнорируется, если передан openState.\n * @default false\n */\n defaultOpen?: boolean;\n /**\n * Внешний контроль открытия/закрытия sidebar.\n * Если передан — источник истины, defaultOpen игнорируется.\n */\n openState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n /**\n * id вкладки, выбранной по умолчанию (актуально при открытом сайдбаре).\n * Если id не найден или у вкладки showInSidebar=false — используется первая доступная.\n */\n defaultActiveTabId?: string;\n /**\n * Внешний контроль активной вкладки (controlled-режим).\n * Если передан — источник истины, defaultActiveTabId игнорируется.\n */\n activeTabState?: [\n string | null,\n React.Dispatch<React.SetStateAction<string | null>>,\n ];\n /**\n * Колбэк смены активной вкладки. Вызывается и в uncontrolled-режиме.\n * При закрытии сайдбара приходит null.\n */\n onActiveTabChange?: (tabId: string | null, tab?: SidebarTab) => void;\n /**\n * Кастомные табы\n */\n customTabs?: Array<\n Omit<SidebarTab, 'id'> & {\n id: Exclude<string, DefaultSidebarTabIds>;\n }\n >;\n /**\n * Порядок отображения кастомных вкладок\n */\n customTabsOrder?: Array<Exclude<string, DefaultSidebarTabIds>>;\n defaultTabs?: Array<\n | {\n id: 'filtering' | 'columns';\n /** название таба в рамках горизонтального табов внутри таба настройки */\n label?: string;\n /** название таба в рамках вертикальных табов сайдбара (если данный таб окажется единственным табом в настройках) */\n title?: string;\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n domMetadata?: DomMetadata;\n /**\n * Кастомный элемент справа от title в шапке сайдбара\n */\n titleRightSlot?: React.ReactNode;\n /** @default true */\n showInSidebar?: boolean;\n /** тултип иконки шестеренки (для табов с id = filtering и columns - недоступен. Настраивается через таб с id='tableSettings') */\n iconTooltipText?: undefined;\n }\n | {\n id: 'tableSettings';\n /** название таба в рамках горизонтального табов внутри таба настройки */\n label?: string;\n /** название таба в рамках вертикальных табов сайдбара */\n title?: string;\n\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n domMetadata?: DomMetadata;\n /**\n * Кастомный слот для вкладки tableSettings (рендерится после общих настроек)\n * Только дл id: 'tableSettings'\n */\n customGeneralSettingsSlot?: React.ReactNode;\n /**\n * Кастомный элемент справа от title в шапке сайдбара\n */\n titleRightSlot?: React.ReactNode;\n /** @default true */\n showInSidebar?: boolean;\n /** тултип иконки шестеренки @default 'Настройки' */\n iconTooltipText?: string;\n }\n >;\n};\n\nexport function activeViewIs<T extends 'cards' | 'rows'>(\n checkType: T,\n viewState: 'cards' | 'rows',\n view: View,\n): view is ViewMods[T] {\n return checkType === viewState;\n}\n\n/** Размер controlBlock: 'm' и 's' — одинаковые стили, 'xs' — уменьшенный */\nexport type ControlBlockSize = 'm' | 's' | 'xs';\n\nexport type ControlBlockConfig = {\n /**\n * show - наличие controlBlock-а\n * @default true\n */\n show?: boolean;\n /**\n * Размер controlBlock и его элементов (кнопки, иконки, поиск, отступы).\n * 'm' и 's' — стандартные стили, 'xs' — компактный режим.\n * Не влияет на customFeatures и кастомные слоты — они контролируются разработчиком.\n * @default 'm'\n */\n size?: ControlBlockSize;\n /**\n * @deprecated Используйте кастомные кнопки через rightSideInner или customFeatures.\n * leftSideInner - пропс для добавления кнопок в левую часть контролблока.\n * Продолжает работать для обратной совместимости.\n */\n leftSideInner?: ControlBlockButtonProps[];\n /**\n * rightSideInner - пропс для добавления кнопок в правую часть контролблока\n */\n rightSideInner?: ControlBlockButtonProps[];\n /**\n * customFeatures - пропс для добавления кастомных фичей (кнопки-иконки)\n */\n customFeatures?: FeatureItem[];\n /**\n * pinningMenu - нативная фича закрепления столбцов (SplitIconButton с\n * дропдауном) в правой зоне иконок. Появляется, когда активировано\n * закрепление колонок (columnsControl.pinning). Продукт может донастроить\n * и дополнить пункты меню (см. PinningMenuConfig).\n */\n pinningMenu?: PinningMenuConfig;\n /**\n * Пропсы для компонента dropdown в котором будут скрыты левые фичи при адаптивной компрессии\n */\n leftSideDropdownProps?: TableDropdownConfigProps;\n /**\n * Пропсы для компонента dropdown в котором будут скрыты правые фичи при адаптивной компрессии\n */\n rightSideDropdownProps?: TableDropdownConfigProps;\n /**\n * Активна ли фича компрессии (сжатие ToolsMenu при адаптиве)\n * @default true\n */\n enableAdaptiveCompress?: boolean;\n /**\n * Панель массовых действий\n */\n massActionPanel?: {\n /**\n * Кнопки панели. Размеры кнопок/дропдаунов панель подбирает сама (по `size` панели и компактности) —\n * передавать `size` кнопкам не нужно. Если `size` на кнопке всё же задан — он используется как есть.\n */\n buttons: MassActionButtonProps[];\n /**\n * Пропсы для Dropdown, в который сжались кнопки\n */\n collapsedDropdownProps?: TableDropdownConfigProps;\n /**\n * Отступ панели снизу от контейнера (px)\n * @default 24\n */\n bottom?: number;\n /**\n * Управление отображением панели массовых действий.\n * - `undefined` (по умолчанию) — стандартное поведение (показывается при selecting + выбранных строках)\n * - `false` — панель не рендерится, разработчик управляет действиями самостоятельно\n * - `true` — панель показывается всегда, даже без активного selecting и выбранных строк\n */\n show?: boolean;\n /**\n * Размерная сетка панели внутри таблицы: `m`/`s` — обычный размер, `xs` — уменьшенный (кнопки `xxs`, «ещё» `xs`, счётчик Body XS).\n * Viewport-логика (1280) в таблице не используется.\n * @default 's'\n */\n size?: MassActionsSize;\n };\n};\n\n/** Пропсы кнопки редактирования. onClick исключён — используйте onSave/onCancel/onEnableEditing. */\nexport type EditingButtonProps = Omit<\n Partial<ControlBlockButtonProps>,\n | 'onClick'\n | 'size'\n | 'dropdown'\n | 'isTargetAction'\n | 'skipRightDivider'\n | 'tooltipText'\n>;\n\nexport type EditingConfig<\n RowType extends ObjectForExtending,\n RowIdType,\n SummaryRowType,\n> = {\n /**\n * Функция обработки изменений в редактируемой строке\n */\n onRowsChange: Maybe<\n (rows: RowType[], data: RowsChangeData<RowType, SummaryRowType>) => void\n >;\n /**\n * свойство, необходимое для корректного изменения дочерних строк.\n * Данное свойство обязательно, если ваши дочерние строки установлены не под ключом \"subRows\" внутри строки.\n *\n * Как дочерние строки можно указывать свойство, которые вложено в другое свойство.\n * В таком случае \".\" будет знаком для обозначения сл. уровня вложенности.\n *\n * @example \"child\" или \"uvh367.children\"\n */\n subRowsKey?: string;\n /**\n * Глубокое копирование строк перед применением правки в режиме редактирования.\n *\n * Включите, если строки, передаваемые в таблицу, иммутабельны/заморожены\n * (напр. стейт под управлением Redux Toolkit или Immer — они вызывают\n * Object.freeze в dev). При редактировании дочерней строки таблица записывает\n * изменение ВНУТРЬ объекта родителя; на замороженном объекте это падает с\n * `TypeError: Cannot assign to read only property`.\n *\n * Когда флаг включён, таблица сама делает structuredClone редактируемой строки\n * перед записью — ваш иммутабельный стейт не мутируется, и редактирование\n * дочерних строк работает без действий с вашей стороны.\n *\n * ⚠️ Данные строки должны быть сериализуемыми. Где доступен structuredClone —\n * Date/Map/Set и вложенные структуры копируются корректно; на старых средах\n * без structuredClone используется JSON-фоллбэк (теряет Date/Map/Set, undefined\n * и функции). Не включайте без необходимости — глубокое копирование добавляет\n * накладные расходы.\n *\n * @default false\n */\n deepCloneRows?: boolean;\n /**\n * Функция определения уникального id строки\n * @param row\n * @returns\n */\n rowKeyGetter: (row: RowType) => RowIdType;\n /**\n * Функция определения возможности редактирования строки\n * @param row\n * @returns\n */\n rowEditable?: (row: RowType) => boolean;\n /**\n * defaultEnabled - пропс, отвечающий за то, будет ли активен режим редактирования или нет. По умолчанию - не активно.\n * @default false\n */\n defaultEnabled?: boolean;\n /**\n * enabled - необходим для управления режимом редактирования снаружи компонента Таблицы.\n * По умолчанию, управление происходит в компоненте.\n * Приоритетнее, чем defaultEnabled.\n *\n * @type boolean - если НЕ нужно переключение в самой таблице\n * @type [boolean, React.Dispatch<React.SetStateAction<boolean>>] - если нужно переключение в самой таблице\n *\n */\n enabled?: boolean | [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n /**\n * Cостояние скрытия/раскрытия кнопки включения/выключения фичи\n * @default true\n */\n showButtons?: boolean;\n /**\n * Функция, вызывающаяся при включении фичи.\n * @param enableEditorMode - функция включающая режим редактирования\n */\n onEnableEditing?: (enableEditorMode: () => void) => void;\n /**\n * Функция, вызывающаяся при сохранении отредактированного.\n * @param disableEditorMode - функция выключающая режим редактирования\n */\n onSave?: (disableEditorMode: () => void) => void;\n /**\n * Функция, вызывающаяся при отмене отредактированного.\n * @param disableEditorMode - функция выключающая режим редактирования\n */\n onCancel?: (disableEditorMode: () => void) => void;\n /** Пропсы кнопок в controlBlock. */\n buttons?: {\n save?: EditingButtonProps;\n cancel?: EditingButtonProps;\n edit?: EditingButtonProps;\n };\n /**\n * Кастомный слот, отображаемый левее кнопок «Отменить» / «Сохранить».\n * Виден только когда режим редактирования активен (editMode = true).\n * Зона ответственности разработчика — размерная сетка controlBlock не влияет на этот слот.\n */\n editModeLeftSlot?: React.ReactNode;\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n domMetadata?: {\n enableButton?: DomMetadata;\n saveButton?: DomMetadata;\n cancelButton?: DomMetadata;\n };\n};\n\nexport type SummaryRowsConfig = {\n showDefault: boolean;\n showInControl: boolean;\n /**\n * callback при переключении тогла «Итоговые строки» в настройках таблицы.\n * Вызывается только по действию пользователя (не при монтировании),\n * поэтому подходит для сохранения выбора, например, в localStorage.\n * Сохранённое значение передавайте обратно в `showDefault`.\n */\n onChange?: (checked: boolean) => void;\n} & {\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n domMetadata?: DomMetadata;\n};\n\n/**\n * Конфиг тултипа при hover по canvas-элементам.\n * Для активации фичи необходимо заполнить данный конфиг,\n * а также добавить нужные изменения в Canvas-элементах или в конфиге колонки.\n */\nexport type TableConfigTooltip = {\n /**\n * Включить/выключить колоночные и кастомные тултипы (cellTooltip, headerCellTooltip).\n * Внутренние тултипы (drag-иконка в шапке и другие по nodeId) работают всегда.\n * @default false\n */\n enabled?: boolean;\n /** Глобальная задержка перед показом тултипа (мс). Per-node переопределяет. @default 500 */\n mouseEnterDelay?: number;\n /** Глобальная задержка перед скрытием тултипа (мс). Per-node переопределяет. @default 0 */\n mouseLeaveDelay?: number;\n /**\n * Минимальная ширина тултипа. Число трактуется как px, строка с единицей\n * (например '20rem', '50%') отдаётся как есть. Действует на все canvas-тултипы,\n * включая авто-тултип Canvas.Text. Если ширина задана на самом тултипе\n * (per-node), приоритет у неё.\n */\n minWidth?: number | string;\n /**\n * Максимальная ширина тултипа. Число трактуется как px, строка с единицей\n * (например '20rem', '50%') отдаётся как есть. Действует на все canvas-тултипы,\n * включая авто-тултип Canvas.Text. Если ширина задана на самом тултипе\n * (per-node), приоритет у неё.\n */\n maxWidth?: number | string;\n};\n\nexport type InfinityScrollConfig<RowType extends ObjectForExtending> = {\n /** Триггер достижения скроллом зоны подгрузки данных. */\n onTrigger: (rows: RowType[]) => Promise<void> | void;\n /** Состояние загрузки (скелетоны) новых строк. */\n isLoading: boolean;\n /**\n * Флаг, когда все данные загружены — false.\n * @default true\n */\n hasMore?: boolean;\n /**\n * Для mode='region': за сколько строк до конца триггерить загрузку.\n * @default 5\n */\n rowThreshold?: number;\n};\n\nexport type { TableCanvasEmptyStateConfig, TableCanvasErrorStateConfig };\n\n/**\n * Настройка выделения ячеек/колонок/строк в TableCanvas — единый объект.\n * Это отдельная ось взаимодействия — не зависит от `highlightActiveType`.\n */\nexport type CellsSelectionConfig = {\n /**\n * Режим фактического выделения ячеек (нативный glide selection). По нему\n * работают copy/paste, рамка, fill-handle и затемнение шапки/нумерации.\n * @default \"range-cell\"\n */\n mode?: CellsSelectionMode;\n /**\n * Выделение колонок по клику на шапку. Ctrl/Cmd — добавить/убрать колонку,\n * Shift — диапазон колонок. Клик по иконкам сортировки/фильтрации в шапке\n * выделение НЕ вызывает. Поддерживает copy/paste по выделенным колонкам.\n * @default true\n */\n enableColumnSelection?: boolean;\n /**\n * Выделение строк по клику/драгу на колонке нумерации (`rowMarkers`).\n * Ctrl/Cmd — несмежный выбор отдельных строк, драг — смежный диапазон.\n * Поддерживает copy/paste по выделенным строкам. Требует включённой колонки\n * нумерации (`rowMarkers`). При `false` клик по нумерации ничего не выделяет.\n * @default true\n */\n enableRowSelection?: boolean;\n /**\n * Выделение всей таблицы кликом по «нулевой» ячейке — шапке колонки нумерации\n * (левый верхний угол). Выделяет все строки данных по всем колонкам одним\n * диапазоном; поддерживает copy/paste. Требует включённой колонки нумерации\n * (`rowMarkers`) и активного `mode` (≠ `disabled`).\n * @default true\n */\n enableSelectAll?: boolean;\n /**\n * Внешний (controlled) контроль НАТИВНОГО выделения (ячейки/диапазон/смежные\n * строки и колонки). `state` — кортеж `[value, setter]` как у `selecting.state`.\n * Сброс: `setter({ current: undefined, rows: empty, columns: empty })`.\n * Несмежный Ctrl-выбор колонок/строк (own-state) сюда не входит — он внутренний.\n */\n state?: [GridSelection, React.Dispatch<React.SetStateAction<GridSelection>>];\n};\n\n/** Один объединённый блок: какие строки и колонки слить. */\nexport type MergedCellsRegion = {\n rowKeys: Array<string | number>;\n colKeys: string[];\n /** Выравнивание контента этого блока. Важнее колоночного и общего. */\n mergedCellsAlign?: MergedCellsAlign;\n};\n\n/**\n * Видимость сторон рамки ячейки: true рисовать, false не рисовать, не задано -\n * работает уровень ниже (настройка колонки, строки или общая).\n */\nexport type CellBorderVisibility = {\n top?: boolean;\n right?: boolean;\n bottom?: boolean;\n left?: boolean;\n};\n\n/**\n * Управление рамками (линиями) таблицы: включение и выключение. Уровни, от\n * слабого к сильному: общие настройки (vertical, horizontal), затем колонка\n * (getVerticalBorder) и строка (getHorizontalBorder), затем ячейка\n * (getCellBorder).\n */\nexport type BordersConfig<RowType = ObjectForExtending> = {\n /** Рисовать ли вертикальные линии между колонками. @default true */\n vertical?: boolean;\n /** Рисовать ли горизонтальные линии между строками тела. @default true */\n horizontal?: boolean;\n /**\n * Точечное управление вертикальной линией справа от колонки (разделитель\n * после неё). Вернуть true или false, чтобы переопределить общую настройку\n * vertical, или undefined, чтобы оставить её. Зовётся на каждую видимую\n * колонку при перерисовке, поэтому функция должна быть быстрой.\n */\n getVerticalBorder?: (params: {\n /** Ключ колонки, справа от которой рисуется линия. */\n columnKey: string;\n /** Индекс колонки в порядке отрисовки (закреплённые в начале). */\n columnIndex: number;\n }) => boolean | undefined;\n /**\n * Точечное управление горизонтальной линией сверху строки. Вернуть true или\n * false, чтобы переопределить общую настройку horizontal, или undefined,\n * чтобы оставить её. Для summary-строк не вызывается. Зовётся на каждую\n * видимую строку при перерисовке, поэтому функция должна быть быстрой.\n */\n getHorizontalBorder?: (params: {\n /** Строка под линией (линия рисуется сверху этой строки). */\n row: RowType;\n /** Индекс строки среди отображаемых. При раскрытии subRows индексы сдвигаются. */\n rowIndex: number;\n /** Уровень вложенности subRows: 0 корень, 1 и больше дочерние. */\n treeLvl: number;\n }) => boolean | undefined;\n /**\n * Стороны рамки конкретной ячейки, вкл и выкл. Для ячеек без переопределений\n * возвращать undefined. Включает отрисовку линий с разбивкой по ячейкам,\n * поэтому функция должна быть быстрой: без тяжёлых вычислений и с готовыми\n * объектами-константами вместо новых на каждый вызов. Для summary-строк не\n * вызывается.\n */\n getCellBorder?: (params: {\n /** Индекс колонки среди отображаемых (без служебных). */\n col: number;\n /** Ключ колонки. */\n columnKey: string | undefined;\n /** Строка ячейки. */\n row: RowType;\n /** Индекс строки среди отображаемых. */\n rowIndex: number;\n /** Уровень вложенности subRows: 0 корень, 1 и больше дочерние. */\n treeLvl: number;\n }) => CellBorderVisibility | undefined;\n};\n\nexport type TableConfig<\n RowType extends ObjectForExtending,\n SummaryRowType,\n RowIdType extends string | number,\n FilterStateType extends ObjectForExtending,\n // SubRowType\n> = {\n /**\n * Группировка колонок (многоуровневая шапка через `columnConfig.children`):\n * объединение пустых ячеек шапки (`squashEmptyCells`, по умолчанию включено) и\n * дефолт выравнивания в объединённых ячейках (`squashedHeaderAlign`).\n */\n columnsGrouping?: ColumnsGroupingConfig;\n /**\n * Подсветка активной сущности в canvas-таблице.\n * @deprecated Значения `'cell'`/`'range-cell'` устарели — используйте\n * `cellsSelection.mode`. Актуальны `'row'` (подсветка строки) и `'disabled'`.\n */\n highlightActiveType?: HighlightActiveType;\n /**\n * Единый конфиг выделения ячеек: режим (`mode`), оси\n * (`enableColumnSelection`/`enableRowSelection`/`enableSelectAll`) и controlled\n * (`state`). См. {@link CellsSelectionConfig}.\n */\n cellsSelection?: CellsSelectionConfig;\n /**\n * Подсвеченная строка (`highlightActiveType='row'`).\n * `state` (опционально) — controlled-кортеж `[value, setter]`: задан — значением\n * владеешь снаружи (сброс `setter(undefined)`); не задан — таблица крутит\n * подсветку внутренним стейтом, а `onChange` всё равно срабатывает (подписка\n * без владения значением).\n */\n highlightActiveRow?: {\n state?: [\n number | undefined,\n React.Dispatch<React.SetStateAction<number | undefined>>,\n ];\n /**\n * Колбэк смены подсвеченной строки: отдаёт её флэт-индекс и сам объект\n * строки (`rows[index]`). Позволяет открывать данные подсвеченной строки\n * (например, в SplitView) без `onCellClicked`.\n */\n onChange?: (params: {\n index: number | undefined;\n row: RowType | undefined;\n }) => void;\n };\n /**\n * Эффекты при наведении (hover)\n * `row` — подсветка строки под курсором.\n * Независимая визуальная ось: селектинг (`cellsSelection`) и `highlightActiveType='row'`\n * рисуются ПОВЕРХ hover-подсветки и визуально перекрывают её (hover\n * «остаётся под ними» и снова виден после сброса выделения).\n *\n * `{ row: true }` — включить с цветами из темы;\n * `{ row: { color: '#F7F9FB' } }` — переопределить цвет data-ячеек.\n * @default undefined (выключено)\n */\n hoverEffects?: HoverEffectsConfig;\n /**\n * Включает компенсацию тонких canvas-линий при browser zoom ниже 100%, когда devicePixelRatio меньше 1.\n * Влияет только на grid/header/sticky hairline borders.\n * @default false\n */\n enableLowDprHairline?: boolean;\n /**\n * Управление рамками (линиями) таблицы: включение и выключение.\n *\n * Уровни, от слабого к сильному: общие настройки (vertical, horizontal),\n * затем колонка (getVerticalBorder) и строка (getHorizontalBorder), затем\n * ячейка (getCellBorder).\n *\n * `vertical: false` и `horizontal: false` убирают все вертикальные или\n * горизонтальные линии тела. `getCellBorder` включает и выключает стороны\n * рамки конкретной ячейки; при его использовании линии рисуются с разбивкой\n * по ячейкам.\n */\n borders?: BordersConfig<RowType>;\n /**\n * rowSize - размеры строк таблицы\n */\n rowSize?: Prettify<RowSize>;\n /**\n * rowHeight - размер высоты строк таблицы\n */\n rowHeight?: Maybe<number | RowHeightFunc<RowType>>;\n /**\n * headerRowHeight - высота одного ряда шапки (в px). По умолчанию 33.\n *\n * Значение применяется к КАЖДОМУ уровню шапки: как к листовому (нижнему) ряду\n * колонок, так и к каждому уровню объединённых (групповых) заголовков. Поэтому\n * при N уровнях группировки итоговая высота шапки = headerRowHeight * (1 + N).\n * Например, headerRowHeight={50} при 2 уровнях групп даст шапку 50 + 50 + 50 = 150px.\n */\n headerRowHeight?: Maybe<number>;\n /**\n * sorting - активация сортировки. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={sorting: {sortingState}}\n *\n * columnConfig=[{sortingType: 'numberSort'}]\n */\n sorting?: {\n state: [\n readonly SortColumn[],\n React.Dispatch<React.SetStateAction<readonly SortColumn[]>>,\n ];\n /**\n * manualSorting - пропс, активирующий ручную-кастомную (или на стороне бэкенда) сортировку\n */\n manualSorting?: boolean;\n };\n /** @deprecated Свойство view не используется и будет удалено в следующей мажорной версии. */\n view?: View;\n /**\n * filtering - активация фильтрации. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={filtering: {stateAndSetter, ...}}\n *\n * columnConfig=[{filtering: {...}}]\n */\n filtering?: FilteringConfig<FilterStateType>;\n /**\n * Сворачивание / разворачивание таблицы\n */\n collapsing?: TableCollapseConfig;\n /**\n * selecting - активация выбора строк. Условие активации - это наличие данного свойства.\n * Есть поддержка выбора строк с многоуровневой вложенностью.\n *\n * Пример:\n *\n *```jsx\n * import { Table } from '@daisforge/ui';\n *\n * <Table\n * tableConfig={{selecting: {stateAndSetter, rowKeyGetter}}}\n * {...rest}\n * />\n * ```\n */\n selecting?: {\n state: [\n ReadonlySet<RowIdType>,\n React.Dispatch<React.SetStateAction<ReadonlySet<RowIdType>>>,\n ];\n rowKeyGetter: (row: RowType) => RowIdType;\n } & Prettify<SelectingRowConfig<RowType, RowIdType>> & {\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n controlBlock?: {\n domMetadata?: DomMetadata;\n };\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам RightSidebar\n */\n sidebar?: {\n domMetadata?: DomMetadata;\n };\n };\n /**\n * editing - активация редактирования. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={editing: {onRowsChange, rowKeyGetter}}\n *\n * columnConfig=[{editingCell: {...}}]\n */\n editing?: EditingConfig<RowType, RowIdType, SummaryRowType>;\n\n /**\n * cellTransfer — конфигурация копирования, вставки и fill handle.\n * По умолчанию копирование (Ctrl+C) работает в режиме редактирования.\n * Данные копируются в формате TSV (tab-separated values), совместимом с Excel.\n *\n * Пример:\n *\n * tableConfig={{ cellTransfer: { enabled: true, onBeforeCopy: (data) => data } }}\n */\n cellTransfer?: CellTransferConfig;\n\n /**\n * Объединение ячеек тела таблицы.\n *\n * mergeByCellValues — колонки, в которых подряд идущие одинаковые значения\n * сливаются в один блок (по вертикали). Границы блоков таблица считает сама из\n * данных; сортировка и фильтр их пересобирают. Данные не меняются — значение и\n * так повторяется в строках, объединение лишь показывает его одной ячейкой.\n *\n * mergedCellsRegions — список блоков, заданных снаружи (как выделение): каждый\n * блок описан ключами строк (rowKeys) и колонок (colKeys). Нужен rowKeyGetter.\n * Если после сортировки или скрытия колонок строки/колонки блока перестали идти\n * подряд — блок не рисуется. Важнее mergeByCellValues.\n *\n * Примеры: mergeCells={{ mergeByCellValues: ['dept', 'role'] }},\n * mergeCells={{ mergedCellsRegions, rowKeyGetter: (r) => r.id }}.\n */\n mergeCells?: {\n mergeByCellValues?: Array<\n string | { colKey: string; value: (row: RowType) => unknown }\n >;\n /** Список блоков, заданных снаружи (по ключам строк и колонок). */\n mergedCellsRegions?: MergedCellsRegion[];\n /**\n * Нужен для mergedCellsRegions: находит строку по её ключу. Должна быть\n * стабильной функцией; менять её на лету не нужно — в пересборку таблицы она\n * не входит.\n */\n rowKeyGetter?: (row: RowType) => string | number;\n /**\n * Выравнивание по умолчанию для всех блоков. Колоночный mergedCellsAlign и\n * выравнивание конкретного региона важнее.\n */\n mergedCellsAlign?: MergedCellsAlign;\n };\n\n /**\n * Модуль нотификаций: стандартизированный канал событий для внешних\n * потребителей. Таблица UI не рисует — вызывает `onNotification`, потребитель\n * показывает тост/модалку на своей стороне. Сейчас эмитятся ошибки copy/paste\n * (в т.ч. multi-range 2D-разброс, readonly/overflow-abort, пропуск валидацией).\n */\n notifications?: TableNotificationsConfig;\n\n /**\n * subRows - активация иерархии, отображения вложенных строк. Условие активации - наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={subRows: {getSubRows, rowKeyGetter}}\n *\n * columnConfig=[{subRow: {...}}]\n */\n subRows?: SubRows<RowType, RowIdType>;\n /**\n * Столбец с нумерацией строк.\n * Активируется наличием этого свойства. Поддерживает `subRows` любой глубины.\n *\n * @see {@link RowMarkersTableConfig} — полное описание конфигурации и примеры.\n */\n rowMarkers?: RowMarkersTableConfig<RowType>;\n rowsGrouping?: RowsGrouping<RowType, SummaryRowType>;\n\n /**\n * resizableColumn - активация изменения ширины колонки с помощью курсора. Условие активации - resizableColumn: true. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={resizableColumn: true}\n *\n * columnConfig=[{resizable: true}]\n */\n resizableColumn?: boolean;\n /**\n * style - inline-стили. Для стилей самой таблицы (без вложенности).\n *\n * Исключены свойства 'width' | 'height' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'. Их следует стилизовать через свойства containerStyle.\n */\n style?: Omit<\n CSSProperties,\n 'width' | 'height' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'\n >;\n /**\n * css - для стилей простых и сложных(например, для стилизации cell, headerCell, ...).\n *\n * Пример:\n *\n * ```css\n * & > .rdg-header-row > .rdgCell {\n * background-color: red;\n * }\n * ```\n *\n */\n css?: string | CSSObject;\n\n summaryRows?: SummaryRowsConfig;\n /**\n * controlBlock - пропс для активации, кастомизации контролблока.\n */\n controlBlock?: ControlBlockConfig;\n /**\n * containerStyle - инлайновые стили контейнера таблицы и контролблока. высоту и ширину для таблицы рекомендуется задавать в этом пропсе.\n * Пример:\n *\n * ```tsx\n tableConfig={{ containerStyle: { height: '70vh' } }}\n * ```\n */\n containerStyle?: CSSProperties | undefined;\n /**\n * containerCss - стили для контейнера таблицы и контролблока.\n * Через этот пропс можно дополнительно кастомизировать контейнер и все его дочерние элементы.\n */\n containerCss?: string | CSSObject | undefined;\n /**\n * containerId - html-атрибут id контейнера таблицы.\n */\n containerId?: string | undefined;\n\n /**\n * unstickyHeader - откреплённая шапка. Header уезжает вместе со скроллом контента.\n * @default false\n */\n unstickyHeader?: boolean;\n\n /** Тултип при hover по canvas-элементам.\n * Для активации фичи необходимо заполнить данный конфиг,\n * а также добавить нужные изменения в Canvas-элементах или в конфиге колонки.\n */\n tooltip?: TableConfigTooltip;\n\n /**\n * infinityScroll - бесконечная подгрузка данных при скролле.\n *\n * Условие активации - наличие самого пропса infinityScroll.\n *\n * При активации infinityScroll отключается дефолтная сортировка и фильтрация.\n * (Предполагается, что если есть infinityScroll,\n * то в таблице представлен не весь объем данных,\n * по этой причине дефолтная сортировка и фильтрация не подходят и будут отображать некорректные данные)\n *\n */\n infinityScroll?: InfinityScrollConfig<RowType>;\n /**\n * @isLoading - состояние загрузки данных для таблицы.\n */\n isLoading?: boolean | { boolean: boolean; skeletonRowsCount: number };\n /**\n * loadingOverlay - конфигурация для отображения оверлея загрузки.\n * Показывает индикатор загрузки поверх таблицы с возможностью кастомизации.\n */\n loadingOverlay?: {\n /**\n * Активен ли оверлей загрузки\n * @default true\n */\n active?: boolean;\n /**\n * Кастомный компонент спиннера\n * @default <Spinner view=\"secondary\" size=\"36\" /> (внутренний компонент)\n */\n spinner?: ReactNode;\n /**\n * Основной заголовок оверлея\n * @default \"Загрузка таблицы\"\n */\n title?: string;\n /**\n * Подзаголовок, который появится после задержки, пустая строка - значит он не появится\n * @default \"\"\n */\n subtitle?: string;\n /**\n * Задержка перед показом подзаголовка (мс)\n * @default 10000 (10 секунд)\n */\n showSubtitleDelay?: number;\n };\n /**\n * Empty state внутри content-области canvas-таблицы.\n * Не заменяет control block, header или pagination.\n */\n emptyState?: TableCanvasEmptyStateConfig;\n /**\n * Error state внутри content-области canvas-таблицы.\n * Не заменяет control block, header или pagination.\n */\n errorState?: TableCanvasErrorStateConfig;\n // FIXME:\n // noRowsFallback?: boolean | { custom: ReactNode };\n columnsControl?: ColumnsControlConfig;\n // FIXME:\n // rowDetailPanel?: RowDetailConfig<RowType>;\n // FIXME: Временно комментирую использование, пока не адаптируем TableCanvas\n // rowInstruments?: {\n // getRowDropdownConfig: RowInstrumentsType<RowType>;\n // /**\n // * @default false\n // */\n // defaultOpened?: boolean;\n // /**\n // * @default true\n // */\n // showInControl?: boolean;\n // /**\n // * Внешний стейт видимости\n // */\n // openedState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n // };\n fullScreenEnabled?: FullScreen;\n /**\n * Переносит портал editor overlay внутрь контейнера таблицы вместо document.body.\n * Решает проблему focus trap и сдвига координат при рендере таблицы в модалке с CSS transform.\n * @default undefined (overlay рендерится в document.body — стандартное поведение)\n */\n editorOverlayPortal?: 'inside';\n keyText?: boolean | KeyTextConfig;\n /**\n * pagination - пропс для пагинации.\n *\n * Условие активации - наличие самого пропса pagination.\n *\n * При активации pagination отключается дефолтные поиск, сортировка и фильтрация.\n * (поиск работает на уровне с фильтрацией и сортировкой, сначала поиск, затем фильтрация, затем сортировка)\n *\n */\n pagination?: PaginationProps;\n /**\n * searching - пропс для поиска по таблицу.\n *\n * Условие активации - наличие searching.enabled: true\n *\n */\n /**\n * Конфигурация табов в сайдбаре\n */\n sidebarConfig?: SidebarConfig;\n searching?: SearchingProps;\n /**\n * onHeaderContextMenu - callback открытия контекстного меню.\n */\n onHeaderContextMenu?: TableGlideInstanceProps<\n RowType,\n SummaryRowType\n >['onHeaderContextMenu'];\n onHeaderContextMenuDropdown?: TableGlideInstanceProps<\n RowType,\n SummaryRowType\n >['onHeaderContextMenuDropdown'];\n onCellContextMenuDropdown?: TableGlideInstanceProps<\n RowType,\n SummaryRowType\n >['onCellContextMenuDropdown'];\n onCellContextMenu?: TableGlideInstanceProps<\n RowType,\n SummaryRowType\n >['onCellContextMenu'];\n /**\n * Обработчик клика по ячейке.\n *\n * Получает `cell` readonly [colIndex, rowIndex] от glide, и `info` обогащённый объект\n * с row, column, ctxs, refTable (аналогично onCellContextMenu).\n */\n onCellClicked?: (\n cell: readonly [number, number],\n info: TableInfoWithRow<RowType, SummaryRowType>,\n ) => void;\n} & GlideInstanceOmitted<RowType, SummaryRowType>;\n\ntype GlideInstanceOmitted<\n RowType extends ObjectForExtending,\n SummaryRowType,\n> = Pick<\n Omit<\n TableGlideInstanceProps<RowType, SummaryRowType>,\n | keyof TableGlideCustomProps<RowType, SummaryRowType>\n | 'CellReadOnlyEditor' /* CellReadOnlyEditor - свойство только для GlideInstance */\n >,\n | 'className'\n | 'columnSelect'\n | 'minColumnWidth'\n | 'maxColumnWidth'\n | 'maxColumnAutoWidth'\n | 'onVisibleRegionChanged'\n | 'onCellClicked'\n // | 'CellReadOnlyEditor'\n // | 'onGroupHeaderClicked'\n | 'onHeaderClicked'\n | 'onItemHovered'\n | 'trapFocus'\n | 'onColumnResize'\n>;\nexport type CellReadOnlyEditorProps<\n RowType extends ObjectForExtending,\n SummaryRowType,\n> = CellReadOnlyEditorGlideInstanceStaticProps &\n EditingCellInfo<RowType, SummaryRowType>;\n\n// & Pick<\n// DataGridPropsDefault<RowType, SummaryRowType, RowIdType>,\n// | 'summaryRowHeight'\n// | 'onFill'\n// | 'onCopy'\n// | 'onPaste'\n// | 'onCellClick'\n// | 'onCellDoubleClick'\n// | 'onCellContextMenu'\n// | 'onCellKeyDown'\n// | 'onSelectedCellChange'\n// | 'onScroll'\n// | 'onColumnResize'\n// | 'onColumnsReorder'\n// | 'enableVirtualization'\n// | 'rowClass'\n// | 'data-testid'\n// | 'headerRowHeight'\n// >;\n\n/**\n * Конфигурация фичи rowMarkers (столбец с нумерацией строк).\n *\n * Столбец frozen, вставляется первым, исключён из reorder/pin/hide/sort/grouping.\n * Поддерживает плоский и древовидный (`subRows`) режимы любой глубины вложенности.\n *\n * **Дефолтное поведение** (без `getRowMarker`): root-only нумерация —\n * корневые строки получают номер (`startIndex + rootIndex`), дочерние — пустую строку.\n *\n * @example\n * ```tsx\n * // Минимальная конфигурация\n * tableConfig={{ rowMarkers: { startIndex: 1 } }}\n *\n * // Сквозная стабильная нумерация\n * tableConfig={{ rowMarkers: { getRowMarker: ({ flatIndex }) => flatIndex + 1 } }}\n * ```\n */\nexport type RowMarkersTableConfig<\n RowType extends ObjectForExtending = ObjectForExtending,\n> = {\n /**\n * Стартовый индекс нумерации (для дефолтной логики без `getRowMarker`).\n * @default 1\n */\n startIndex?: number;\n\n /**\n * Ширина столбца с нумерацией (в px).\n * Если задан `size` — он приоритетнее.\n+ * Если ни `size`, ни `width` не заданы — ширина подстраивается\n+ * под глобальный `tableConfig.rowSize` (small=20, medium=32, big=48).\n * @default 32\n */\n width?: number;\n /**\n * Размер столбца. Приоритетнее `width`.\n * - `xs` = 20px\n * - `s` = 32px\n * - `m` = 48px\n */\n size?: 'xs' | 's' | 'm';\n /**\n * Кастомная функция нумерации. Полностью переопределяет дефолтную root-only логику.\n * Вызывается при рендере каждой ячейки столбца нумерации.\n *\n * ⚠️ Вызывается не только при полной отрисовке таблицы, но и при ховере/скролле —\n * для **одной** ячейки. Не используйте внешние переменные-счётчики —\n * используйте аргументы (`siblingPath`, `flatIndex` и др.), они всегда актуальны.\n *\n * @example\n * // Сквозная стабильная нумерация (все строки, номера не прыгают при сворачивании)\n * getRowMarker: ({ flatIndex }) => flatIndex + 1\n *\n * @example\n * // Корневые — номер, дочерние — прочерк\n * getRowMarker: ({ isSubRow, flatIndex }) => isSubRow ? '—' : flatIndex + 1\n *\n * @example\n * // Иерархическая нумерация любой глубины: 1, 1.1, 1.1.1, 1.2, 2\n * getRowMarker: ({ siblingPath }) => siblingPath.map(i => i + 1).join('.')\n */\n getRowMarker?: (args: {\n /** Данные текущей строки. */\n row: RowType;\n /** Уровень строки в дереве: `0` — корневая, `1` — дочерняя, `2` — внучка, и т.д. */\n level: number;\n /** `true`, если строка дочерняя (`level > 0`). */\n isSubRow: boolean;\n /**\n * Индекс строки в **видимых** строках.\n * **Нестабильный** — меняется при сворачивании и разворачивании веток.\n */\n rowIndex: number;\n /**\n * Стабильный 0-based индекс строки в **полном** дереве (включая скрытые/свёрнутые).\n * Не меняется при collapse/expand — подходит для сквозной нумерации.\n */\n flatIndex: number;\n /**\n * Порядковый номер среди siblings одного родителя (0-based).\n * Для корневых строк — порядковый номер среди всех корневых.\n * Для дочерних — порядковый номер среди children одного `parentKey`.\n */\n siblingIndex: number;\n /**\n * Путь siblingIndex-ов от корня до текущей строки (каждый элемент 0-based).\n *\n * Примеры:\n * - корневая строка (2-я): `[1]`\n * - дочерняя (3-й ребёнок 2-го корня): `[1, 2]`\n * - внучка (1-й ребёнок 1-го ребёнка 1-го корня): `[0, 0, 0]`\n *\n * Для иерархической нумерации: `siblingPath.map(i => i + 1).join('.')` → `\"1.1.1\"`\n *\n * Для плоской таблицы (без subRows): всегда `[siblingIndex]` (один элемент).\n */\n siblingPath: number[];\n /**\n * Ключ родительской строки (`rowKeyGetter(parent)`).\n * `null` для корневых строк. Работает для **любой** глубины вложенности.\n */\n parentKey: string | number | null;\n /** Текущий видимый `flattened` массив строк. */\n rows: readonly RowType[];\n }) => string | number;\n};\n```\n\n## FilterComponentInPopoverProps\n\nПропсы, доступные в кастомном компоненте фильтра (`component: 'custom'`).\n\n```typescript\ntype FilterComponentInPopoverProps<\n FilterStateType extends ObjectForExtending,\n ColumnConfig,\n> = {\n popoverIsOpen: boolean;\n setPopoverIsOpen: React.Dispatch<React.SetStateAction<boolean>>;\n columnConfig: ColumnConfig;\n tabIndex: number;\n headerContextState: HeaderContextValueTypeInstance<FilterStateType> &\n FiltersVariables &\n HeaderContextValueTypeInstance<ObjectForExtending>;\n /**\n * Источник открытия фильтра: из шапки таблицы или из сайдбара\n * Полезно для условной логики в customRender (например, alwaysOpened для combobox)\n */\n filterSource?: 'header' | 'sidebar';\n};\n```",
53887
54413
  "api": [
53888
54414
  {
53889
54415
  "typeName": "FilteringConfig",
53890
- "source": "type FilteringConfig<T> = {\n state: [T, React.Dispatch<React.SetStateAction<T>>];\n /**\n * @deprecated Использовать filtersInfo\n *\n * clearedValue - состояние фильтров после очистки. Используется для сравнения:\n * Например, был ли фильтр конкретной колонки изменен рассчитывается посредством сравнения текущего значения фильтра и значения фильтра в clearedValue.\n * Если они равны, то фильтр считается не измененным.\n */\n clearedValue?: T;\n /**\n * Информация о фильтрах для каждой колонки.\n * Используется для:\n * 1. Хранения меток (label) фильтров для отображения в UI\n * 2. Хранения значений по умолчанию (clearedValue) для каждого фильтра\n * 3. Определения, был ли фильтр изменен (сравнение текущего значения с clearedValue)\n */\n filtersInfo?: Record<\n keyof T,\n {\n label: string;\n clearedValue: T[keyof T];\n }\n >;\n /**\n * manualFiltering - пропс, активирующий ручную-кастомную (или на стороне бэка) фильтрацию.\n * @remarks\n * Для автоматической фильтрации (когда не используется manualFiltering в tableConfig):\n * - Для всех типов фильтров обязательно должен быть указан `valueInRow`\n * - Для component: 'select' дополнительно должен быть указан `filteringType`\n * - Для component: 'input' с кастомным фильтром (когда filter - функция)\n * функция фильтрации должна быть передана явно\n *\n * Если используется manualFiltering, эти параметры не обязательны,\n * так как вся логика фильтрации реализуется извне.\n */\n manualFiltering?: boolean;\n /**\n * Конфигурация для отображения фильтров в правом сайдбаре.\n *\n * Позволяет:\n * 1. Добавлять глобальные фильтры (не привязанные к конкретной колонке)\n * 2. Управлять порядком отображения фильтров\n * 3. Переопределять рендер и заголовки колоночных фильтров\n *\n * Логика работы:\n * - По умолчанию в сайдбаре отображаются все колоночные фильтры (из columnConfig)\n * - Ключом фильтра считается `key` колонки, если его нет, то пытаемся взять `keyInFilterState` (если указан), иначе это не будет работать\n * - Заголовком фильтра по умолчанию является `name` колонки или ключ фильтра (name || key)\n * - Глобальные фильтры добавляются через `items` с уникальными ключами\n *\n * Особенности:\n * 1. Порядок отображения:\n * - Сначала фильтры из `order` (в указанной последовательности)\n * - Затем остальные колоночные фильтры (в порядке columnConfig)\n * - В конце - глобальные фильтры (в алфавитном порядке ключей)\n *\n * 2. Переопределение колоночных фильтров:\n * - Чтобы изменить заголовок: укажите ключ колонки в `items` с новым `label`\n * - Чтобы заменить рендер: укажите ключ колонки с `customRenderFn`\n * - Оригинальный фильтр из колонки будет проигнорирован\n *\n * 3. Глобальные фильтры:\n * - Ключ не должен совпадать с ключами колонок\n * - Обязательно указать `label` и `customRenderFn`\n * - Отображаются после всех колоночных фильтров, если не переопределены в order\n *\n * @example\n * // Добавление глобального фильтра и изменение порядка\n * sidebarConfig: {\n * order: ['status', 'tasks', 'type'], // Сначала статус, затем глобальный поиск\n * items: {\n * tasks: { // Уникальный ключ\n * label: 'Поиск по всем полям',\n * customRenderFn: () => <TaskComponent />\n * },\n * status: { // Переопределение колоночного фильтра\n * label: 'Статус заявки', // Новый заголовок\n * customRenderFn: () => <CustomStatusFilter /> // Кастомный рендер\n * }\n * type: { // Переопределение только Label колоночного фильтра\n * label: 'Тип', // Новый заголовок\n * }\n * }\n * }\n */\n sidebarConfig?: {\n /**\n * Определяет порядок отображения фильтров.\n * - Указываются ключи фильтров (колоночных или глобальных)\n * - Не указанные в order фильтры отображаются после\n * - Если order пуст, сохраняется порядок: глобальные фильтры + columnConfig фильтры в конце\n */\n order?: string[];\n /**\n * Конфигурация фильтров для сайдбара.\n * Ключом может быть:\n * - Ключ колонки (для переопределения колоночного фильтра)\n * - Уникальный ключ (для добавления глобального фильтра)\n */\n items: Partial<\n Record<\n keyof T,\n {\n /** Заголовок фильтра (обязателен для глобальных фильтров), можно использовать для переопределения для локальных фильтров */\n label: string;\n /**\n * Функция рендера компонента фильтра.\n * Для колоночных фильтров переопределяет оригинальный рендер.\n * Для глобальных фильтров обязательна.\n */\n customRenderFn?: (\n filters: T,\n setFilters: React.Dispatch<React.SetStateAction<T>>,\n ) => React.ReactNode;\n }\n >\n >;\n };\n /**\n * Callback для кастомизации стилей чипсов (фильтров) в списке\n *\n * @param {ItemOrGroup} itemOrGroup - Текущий элемент или группа фильтров\n * @param {Item | undefined} item - Конкретный элемент фильтра (если есть)\n * @returns {CSSObject} Объект стилей, который будет применен к чипсу\n *\n * @description\n * Позволяет динамически задавать стили для каждого чипса в зависимости от его типа и содержимого.\n * Вызывается для каждого отображаемого чипса (как для отдельных элементов, так и для элементов внутри групп).\n *\n * @example\n * // Пример 1: Стилизация чипсов по типу\n * chipStyle: (itemOrGroup, item) => {\n * if (isGroup(itemOrGroup)) {\n * return { backgroundColor: '#f0f0f0' };\n * }\n * return { backgroundColor: '#e0e0e0' };\n * }\n *\n * @example\n * // Пример 2: Стилизация по значению фильтра\n * chipStyle: (itemOrGroup, item) => {\n * if (item?.label === 'Высокий приоритет') {\n * return {\n * backgroundColor: '#ffebee',\n * color: '#d32f2f'\n * };\n * }\n * return {};\n * }\n *\n * @example\n * // Пример 3: Разные стили для элементов в группе и одиночных\n * chipStyle: (itemOrGroup, item) => {\n * if (item) {\n * // Стиль для элемента внутри группы\n * return { maxWidth: 180 };\n * }\n * // Стиль для одиночного чипа\n * return { maxWidth: 150 };\n * }\n */\n chipStyle?: (itemOrGroup: ItemOrGroup, item: Item | undefined) => CSSObject;\n /**\n * Пользовательский форматтер заголовка группы чипсов.\n *\n * Используется в блоке активных фильтров для подмены текста заголовка\n * группы (например, “Статус”, “Тип”, “Автор”). Полезно, когда нужно\n * динамически менять подпись (добавить счётчик, i18n и т.п.).\n *\n * @param {ItemOrGroup} itemOrGroup Объект группы (тип Group). Вызов происходит только для групп,\n * поэтому безопасно кастовать к Group.\n * @returns {string} Текст заголовка группы чипсов.\n *\n * @default Возвращается `group.groupLabel`.\n *\n * @remarks\n * - Функция должна быть чистой и быстрой (без сетевых запросов и побочных эффектов).\n * - Возвращайте ТОЛЬКО строку — чипы отображают текстовое значение.\n * - Для длинных строк применяется усечение (overflow с многоточием) на уровне компонента.\n *\n * @example\n * // Добавить двоеточие и количество выбранных элементов\n * renderGroupLabel: (group) => `${group.groupLabel}: ${group.items.length}`\n *\n * @example\n * // Локализация заголовка группы\n * const i18n = { status: 'Статус', type: 'Тип' };\n * renderGroupLabel: (group) => i18n[group.groupId] ?? group.groupLabel\n */\n renderGroupLabel?: (group: Group) => string;\n\n /**\n * Пользовательский форматтер текста чипса (элемента внутри группы или одиночного фильтра).\n *\n * Позволяет управлять тем, что именно отображается внутри каждого чипса. Особенно полезен\n * при серверной пагинации/ленивой загрузке, когда в состоянии фильтра хранится только value,\n * а label необходимо подставить из локального кэша.\n *\n * @param {Group | null } group Группа, внутри которой рендерится чип (или null).\n * @param {Item} item Сам элемент чипса. В группах передаётся конкретный `Item`,\n * для одиночного чипа может быть `undefined`.\n * @returns {string} Текст, который будет показан в чипсе.\n *\n * @default Используется `item?.label.toString()` (или строковое представление value).\n *\n * @remarks\n * - Функция должна быть чистой и быстрой;\n * - Возвращайте ТОЛЬКО строку.\n *\n * @example\n * // 1) Отображение label из кэша при серверной пагинации\n * const labelsCacheRef = useRef(new Map<string, string>());\n * renderChipLabel: (group, item) => {\n * if (item?.id != null) {\n * const key = String(item.id);\n * const fromCache = labelsCacheRef.current.get(key);\n * if (fromCache) return fromCache; // красивый label, если уже загрузили\n * return String(item.label ?? key); // фоллбэк: временно показываем value/label из item\n * }\n * return ''; // безопасный фоллбэк для одиночных случаев\n * }\n *\n * @example\n * // 2) Нормализация отображения числовых значений\n * renderChipLabel: (_group, item) => {\n * const v = Number(item?.label);\n * return Number.isFinite(v) ? v.toLocaleString('ru-RU') : String(item?.label ?? '');\n * }\n *\n * @example\n * // 3) Префикс по типу группы\n * renderChipLabel: (group, item) => {\n * const prefix = group.groupId === 'status' ? '' : '#';\n * return `${prefix}${item?.label ?? item?.id ?? ''}`;\n * }\n */\n renderChipLabel?: (group: Group | null, item: Item) => string;\n};\n\nexport type DefaultSidebarTabIds = 'columns' | 'tableSettings' | 'filtering';\n\n/**\n * Конфигурация sidebar\n */\nexport type SidebarConfig = {\n /**\n * Включен ли sidebar. Отвечает только за UI. Не влияет на перерасчёт фичей.\n * @default true\n */\n enabled?: boolean;\n /**\n * Открыт ли sidebar при первом рендере (uncontrolled-режим).\n * Игнорируется, если передан openState.\n * @default false\n */\n defaultOpen?: boolean;\n /**\n * Внешний контроль открытия/закрытия sidebar.\n * Если передан — источник истины, defaultOpen игнорируется.\n */\n openState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n /**\n * id вкладки, выбранной по умолчанию (актуально при открытом сайдбаре).\n * Если id не найден или у вкладки showInSidebar=false — используется первая доступная.\n */\n defaultActiveTabId?: string;\n /**\n * Внешний контроль активной вкладки (controlled-режим).\n * Если передан — источник истины, defaultActiveTabId игнорируется.\n */\n activeTabState?: [\n string | null,\n React.Dispatch<React.SetStateAction<string | null>>,\n ];\n /**\n * Колбэк смены активной вкладки. Вызывается и в uncontrolled-режиме.\n * При закрытии сайдбара приходит null.\n */\n onActiveTabChange?: (tabId: string | null, tab?: SidebarTab) => void;\n /**\n * Кастомные табы\n */\n customTabs?: Array<\n Omit<SidebarTab, 'id'> & {\n id: Exclude<string, DefaultSidebarTabIds>;\n }\n >;\n /**\n * Порядок отображения кастомных вкладок\n */\n customTabsOrder?: Array<Exclude<string, DefaultSidebarTabIds>>;\n defaultTabs?: Array<\n | {\n id: 'filtering' | 'columns';\n /** название таба в рамках горизонтального табов внутри таба настройки */\n label?: string;\n /** название таба в рамках вертикальных табов сайдбара (если данный таб окажется единственным табом в настройках) */\n title?: string;\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n domMetadata?: DomMetadata;\n /**\n * Кастомный элемент справа от title в шапке сайдбара\n */\n titleRightSlot?: React.ReactNode;\n /** @default true */\n showInSidebar?: boolean;\n /** тултип иконки шестеренки (для табов с id = filtering и columns - недоступен. Настраивается через таб с id='tableSettings') */\n iconTooltipText?: undefined;\n }\n | {\n id: 'tableSettings';\n /** название таба в рамках горизонтального табов внутри таба настройки */\n label?: string;\n /** название таба в рамках вертикальных табов сайдбара */\n title?: string;\n\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n domMetadata?: DomMetadata;\n /**\n * Кастомный слот для вкладки tableSettings (рендерится после общих настроек)\n * Только дл id: 'tableSettings'\n */\n customGeneralSettingsSlot?: React.ReactNode;\n /**\n * Кастомный элемент справа от title в шапке сайдбара\n */\n titleRightSlot?: React.ReactNode;\n /** @default true */\n showInSidebar?: boolean;\n /** тултип иконки шестеренки @default 'Настройки' */\n iconTooltipText?: string;\n }\n >;\n};\n\nexport function activeViewIs<T extends 'cards' | 'rows'>(\n checkType: T,\n viewState: 'cards' | 'rows',\n view: View,\n): view is ViewMods[T] {\n return checkType === viewState;\n}\n\n/** Размер controlBlock: 'm' и 's' — одинаковые стили, 'xs' — уменьшенный */\nexport type ControlBlockSize = 'm' | 's' | 'xs';\n\nexport type ControlBlockConfig = {\n /**\n * show - наличие controlBlock-а\n * @default true\n */\n show?: boolean;\n /**\n * Размер controlBlock и его элементов (кнопки, иконки, поиск, отступы).\n * 'm' и 's' — стандартные стили, 'xs' — компактный режим.\n * Не влияет на customFeatures и кастомные слоты — они контролируются разработчиком.\n * @default 'm'\n */\n size?: ControlBlockSize;\n /**\n * @deprecated Используйте кастомные кнопки через rightSideInner или customFeatures.\n * leftSideInner - пропс для добавления кнопок в левую часть контролблока.\n * Продолжает работать для обратной совместимости.\n */\n leftSideInner?: ControlBlockButtonProps[];\n /**\n * rightSideInner - пропс для добавления кнопок в правую часть контролблока\n */\n rightSideInner?: ControlBlockButtonProps[];\n /**\n * customFeatures - пропс для добавления кастомных фичей (кнопки-иконки)\n */\n customFeatures?: FeatureItem[];\n /**\n * pinningMenu - нативная фича закрепления столбцов (SplitIconButton с\n * дропдауном) в правой зоне иконок. Появляется, когда активировано\n * закрепление колонок (columnsControl.pinning). Продукт может донастроить\n * и дополнить пункты меню (см. PinningMenuConfig).\n */\n pinningMenu?: PinningMenuConfig;\n /**\n * Пропсы для компонента dropdown в котором будут скрыты левые фичи при адаптивной компрессии\n */\n leftSideDropdownProps?: TableDropdownConfigProps;\n /**\n * Пропсы для компонента dropdown в котором будут скрыты правые фичи при адаптивной компрессии\n */\n rightSideDropdownProps?: TableDropdownConfigProps;\n /**\n * Активна ли фича компрессии (сжатие ToolsMenu при адаптиве)\n * @default true\n */\n enableAdaptiveCompress?: boolean;\n /**\n * Панель массовых действий\n */\n massActionPanel?: {\n /**\n * Кнопки панели. Размеры кнопок/дропдаунов панель подбирает сама (по `size` панели и компактности) —\n * передавать `size` кнопкам не нужно. Если `size` на кнопке всё же задан — он используется как есть.\n */\n buttons: MassActionButtonProps[];\n /**\n * Пропсы для Dropdown, в который сжались кнопки\n */\n collapsedDropdownProps?: TableDropdownConfigProps;\n /**\n * Отступ панели снизу от контейнера (px)\n * @default 24\n */\n bottom?: number;\n /**\n * Управление отображением панели массовых действий.\n * - `undefined` (по умолчанию) — стандартное поведение (показывается при selecting + выбранных строках)\n * - `false` — панель не рендерится, разработчик управляет действиями самостоятельно\n * - `true` — панель показывается всегда, даже без активного selecting и выбранных строк\n */\n show?: boolean;\n /**\n * Размерная сетка панели внутри таблицы: `m`/`s` — обычный размер, `xs` — уменьшенный (кнопки `xxs`, «ещё» `xs`, счётчик Body XS).\n * Viewport-логика (1280) в таблице не используется.\n * @default 's'\n */\n size?: MassActionsSize;\n };\n};\n\n/** Пропсы кнопки редактирования. onClick исключён — используйте onSave/onCancel/onEnableEditing. */\nexport type EditingButtonProps = Omit<\n Partial<ControlBlockButtonProps>,\n | 'onClick'\n | 'size'\n | 'dropdown'\n | 'isTargetAction'\n | 'skipRightDivider'\n | 'tooltipText'\n>;\n\nexport type EditingConfig<\n RowType extends ObjectForExtending,\n RowIdType,\n SummaryRowType,\n> = {\n /**\n * Функция обработки изменений в редактируемой строке\n */\n onRowsChange: Maybe<\n (rows: RowType[], data: RowsChangeData<RowType, SummaryRowType>) => void\n >;\n /**\n * свойство, необходимое для корректного изменения дочерних строк.\n * Данное свойство обязательно, если ваши дочерние строки установлены не под ключом \"subRows\" внутри строки.\n *\n * Как дочерние строки можно указывать свойство, которые вложено в другое свойство.\n * В таком случае \".\" будет знаком для обозначения сл. уровня вложенности.\n *\n * @example \"child\" или \"uvh367.children\"\n */\n subRowsKey?: string;\n /**\n * Глубокое копирование строк перед применением правки в режиме редактирования.\n *\n * Включите, если строки, передаваемые в таблицу, иммутабельны/заморожены\n * (напр. стейт под управлением Redux Toolkit или Immer — они вызывают\n * Object.freeze в dev). При редактировании дочерней строки таблица записывает\n * изменение ВНУТРЬ объекта родителя; на замороженном объекте это падает с\n * `TypeError: Cannot assign to read only property`.\n *\n * Когда флаг включён, таблица сама делает structuredClone редактируемой строки\n * перед записью — ваш иммутабельный стейт не мутируется, и редактирование\n * дочерних строк работает без действий с вашей стороны.\n *\n * ⚠️ Данные строки должны быть сериализуемыми. Где доступен structuredClone —\n * Date/Map/Set и вложенные структуры копируются корректно; на старых средах\n * без structuredClone используется JSON-фоллбэк (теряет Date/Map/Set, undefined\n * и функции). Не включайте без необходимости — глубокое копирование добавляет\n * накладные расходы.\n *\n * @default false\n */\n deepCloneRows?: boolean;\n /**\n * Функция определения уникального id строки\n * @param row\n * @returns\n */\n rowKeyGetter: (row: RowType) => RowIdType;\n /**\n * Функция определения возможности редактирования строки\n * @param row\n * @returns\n */\n rowEditable?: (row: RowType) => boolean;\n /**\n * defaultEnabled - пропс, отвечающий за то, будет ли активен режим редактирования или нет. По умолчанию - не активно.\n * @default false\n */\n defaultEnabled?: boolean;\n /**\n * enabled - необходим для управления режимом редактирования снаружи компонента Таблицы.\n * По умолчанию, управление происходит в компоненте.\n * Приоритетнее, чем defaultEnabled.\n *\n * @type boolean - если НЕ нужно переключение в самой таблице\n * @type [boolean, React.Dispatch<React.SetStateAction<boolean>>] - если нужно переключение в самой таблице\n *\n */\n enabled?: boolean | [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n /**\n * Cостояние скрытия/раскрытия кнопки включения/выключения фичи\n * @default true\n */\n showButtons?: boolean;\n /**\n * Функция, вызывающаяся при включении фичи.\n * @param enableEditorMode - функция включающая режим редактирования\n */\n onEnableEditing?: (enableEditorMode: () => void) => void;\n /**\n * Функция, вызывающаяся при сохранении отредактированного.\n * @param disableEditorMode - функция выключающая режим редактирования\n */\n onSave?: (disableEditorMode: () => void) => void;\n /**\n * Функция, вызывающаяся при отмене отредактированного.\n * @param disableEditorMode - функция выключающая режим редактирования\n */\n onCancel?: (disableEditorMode: () => void) => void;\n /** Пропсы кнопок в controlBlock. */\n buttons?: {\n save?: EditingButtonProps;\n cancel?: EditingButtonProps;\n edit?: EditingButtonProps;\n };\n /**\n * Кастомный слот, отображаемый левее кнопок «Отменить» / «Сохранить».\n * Виден только когда режим редактирования активен (editMode = true).\n * Зона ответственности разработчика — размерная сетка controlBlock не влияет на этот слот.\n */\n editModeLeftSlot?: React.ReactNode;\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n domMetadata?: {\n enableButton?: DomMetadata;\n saveButton?: DomMetadata;\n cancelButton?: DomMetadata;\n };\n};\n\nexport type SummaryRowsConfig = {\n showDefault: boolean;\n showInControl: boolean;\n /**\n * callback при переключении тогла «Итоговые строки» в настройках таблицы.\n * Вызывается только по действию пользователя (не при монтировании),\n * поэтому подходит для сохранения выбора, например, в localStorage.\n * Сохранённое значение передавайте обратно в `showDefault`.\n */\n onChange?: (checked: boolean) => void;\n} & {\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n domMetadata?: DomMetadata;\n};\n\n/**\n * Конфиг тултипа при hover по canvas-элементам.\n * Для активации фичи необходимо заполнить данный конфиг,\n * а также добавить нужные изменения в Canvas-элементах или в конфиге колонки.\n */\nexport type TableConfigTooltip = {\n /**\n * Включить/выключить колоночные и кастомные тултипы (cellTooltip, headerCellTooltip).\n * Внутренние тултипы (drag-иконка в шапке и другие по nodeId) работают всегда.\n * @default false\n */\n enabled?: boolean;\n /** Глобальная задержка перед показом тултипа (мс). Per-node переопределяет. @default 500 */\n mouseEnterDelay?: number;\n /** Глобальная задержка перед скрытием тултипа (мс). Per-node переопределяет. @default 0 */\n mouseLeaveDelay?: number;\n /**\n * Минимальная ширина тултипа. Число трактуется как px, строка с единицей\n * (например '20rem', '50%') отдаётся как есть. Действует на все canvas-тултипы,\n * включая авто-тултип Canvas.Text. Если ширина задана на самом тултипе\n * (per-node), приоритет у неё.\n */\n minWidth?: number | string;\n /**\n * Максимальная ширина тултипа. Число трактуется как px, строка с единицей\n * (например '20rem', '50%') отдаётся как есть. Действует на все canvas-тултипы,\n * включая авто-тултип Canvas.Text. Если ширина задана на самом тултипе\n * (per-node), приоритет у неё.\n */\n maxWidth?: number | string;\n};\n\nexport type InfinityScrollConfig<RowType extends ObjectForExtending> = {\n /** Триггер достижения скроллом зоны подгрузки данных. */\n onTrigger: (rows: RowType[]) => Promise<void> | void;\n /** Состояние загрузки (скелетоны) новых строк. */\n isLoading: boolean;\n /**\n * Флаг, когда все данные загружены — false.\n * @default true\n */\n hasMore?: boolean;\n /**\n * Для mode='region': за сколько строк до конца триггерить загрузку.\n * @default 5\n */\n rowThreshold?: number;\n};\n\nexport type { TableCanvasEmptyStateConfig, TableCanvasErrorStateConfig };\n\n/**\n * Настройка выделения ячеек/колонок/строк в TableCanvas — единый объект.\n * Это отдельная ось взаимодействия — не зависит от `highlightActiveType`.\n */\nexport type CellsSelectionConfig = {\n /**\n * Режим фактического выделения ячеек (нативный glide selection). По нему\n * работают copy/paste, рамка, fill-handle и затемнение шапки/нумерации.\n * @default \"range-cell\"\n */\n mode?: CellsSelectionMode;\n /**\n * Выделение колонок по клику на шапку. Ctrl/Cmd — добавить/убрать колонку,\n * Shift — диапазон колонок. Клик по иконкам сортировки/фильтрации в шапке\n * выделение НЕ вызывает. Поддерживает copy/paste по выделенным колонкам.\n * @default true\n */\n enableColumnSelection?: boolean;\n /**\n * Выделение строк по клику/драгу на колонке нумерации (`rowMarkers`).\n * Ctrl/Cmd — несмежный выбор отдельных строк, драг — смежный диапазон.\n * Поддерживает copy/paste по выделенным строкам. Требует включённой колонки\n * нумерации (`rowMarkers`). При `false` клик по нумерации ничего не выделяет.\n * @default true\n */\n enableRowSelection?: boolean;\n /**\n * Выделение всей таблицы кликом по «нулевой» ячейке — шапке колонки нумерации\n * (левый верхний угол). Выделяет все строки данных по всем колонкам одним\n * диапазоном; поддерживает copy/paste. Требует включённой колонки нумерации\n * (`rowMarkers`) и активного `mode` (≠ `disabled`).\n * @default true\n */\n enableSelectAll?: boolean;\n /**\n * Внешний (controlled) контроль НАТИВНОГО выделения (ячейки/диапазон/смежные\n * строки и колонки). `state` — кортеж `[value, setter]` как у `selecting.state`.\n * Сброс: `setter({ current: undefined, rows: empty, columns: empty })`.\n * Несмежный Ctrl-выбор колонок/строк (own-state) сюда не входит — он внутренний.\n */\n state?: [GridSelection, React.Dispatch<React.SetStateAction<GridSelection>>];\n};\n\n/** Один объединённый блок: какие строки и колонки слить. */\nexport type MergedCellsRegion = {\n rowKeys: Array<string | number>;\n colKeys: string[];\n /** Выравнивание контента этого блока. Важнее колоночного и общего. */\n mergedCellsAlign?: MergedCellsAlign;\n};\n\n/**\n * Видимость сторон рамки ячейки: true рисовать, false не рисовать, не задано -\n * работает уровень ниже (настройка колонки, строки или общая).\n */\nexport type CellBorderVisibility = {\n top?: boolean;\n right?: boolean;\n bottom?: boolean;\n left?: boolean;\n};\n\n/**\n * Управление рамками (линиями) таблицы: включение и выключение. Уровни, от\n * слабого к сильному: общие настройки (vertical, horizontal), затем колонка\n * (getVerticalBorder) и строка (getHorizontalBorder), затем ячейка\n * (getCellBorder).\n */\nexport type BordersConfig<RowType = ObjectForExtending> = {\n /** Рисовать ли вертикальные линии между колонками. @default true */\n vertical?: boolean;\n /** Рисовать ли горизонтальные линии между строками тела. @default true */\n horizontal?: boolean;\n /**\n * Точечное управление вертикальной линией справа от колонки (разделитель\n * после неё). Вернуть true или false, чтобы переопределить общую настройку\n * vertical, или undefined, чтобы оставить её. Зовётся на каждую видимую\n * колонку при перерисовке, поэтому функция должна быть быстрой.\n */\n getVerticalBorder?: (params: {\n /** Ключ колонки, справа от которой рисуется линия. */\n columnKey: string;\n /** Индекс колонки в порядке отрисовки (закреплённые в начале). */\n columnIndex: number;\n }) => boolean | undefined;\n /**\n * Точечное управление горизонтальной линией сверху строки. Вернуть true или\n * false, чтобы переопределить общую настройку horizontal, или undefined,\n * чтобы оставить её. Для summary-строк не вызывается. Зовётся на каждую\n * видимую строку при перерисовке, поэтому функция должна быть быстрой.\n */\n getHorizontalBorder?: (params: {\n /** Строка под линией (линия рисуется сверху этой строки). */\n row: RowType;\n /** Индекс строки среди отображаемых. При раскрытии subRows индексы сдвигаются. */\n rowIndex: number;\n /** Уровень вложенности subRows: 0 корень, 1 и больше дочерние. */\n treeLvl: number;\n }) => boolean | undefined;\n /**\n * Стороны рамки конкретной ячейки, вкл и выкл. Для ячеек без переопределений\n * возвращать undefined. Включает отрисовку линий с разбивкой по ячейкам,\n * поэтому функция должна быть быстрой: без тяжёлых вычислений и с готовыми\n * объектами-константами вместо новых на каждый вызов. Для summary-строк не\n * вызывается.\n */\n getCellBorder?: (params: {\n /** Индекс колонки среди отображаемых (без служебных). */\n col: number;\n /** Ключ колонки. */\n columnKey: string | undefined;\n /** Строка ячейки. */\n row: RowType;\n /** Индекс строки среди отображаемых. */\n rowIndex: number;\n /** Уровень вложенности subRows: 0 корень, 1 и больше дочерние. */\n treeLvl: number;\n }) => CellBorderVisibility | undefined;\n};\n\nexport type TableConfig<\n RowType extends ObjectForExtending,\n SummaryRowType,\n RowIdType extends string | number,\n FilterStateType extends ObjectForExtending,\n // SubRowType\n> = {\n /**\n * Группировка колонок (многоуровневая шапка через `columnConfig.children`):\n * объединение пустых ячеек шапки (`squashEmptyCells`, по умолчанию включено) и\n * дефолт выравнивания в объединённых ячейках (`squashedHeaderAlign`).\n */\n columnsGrouping?: ColumnsGroupingConfig;\n /**\n * Подсветка активной сущности в canvas-таблице.\n * @deprecated Значения `'cell'`/`'range-cell'` устарели — используйте\n * `cellsSelection.mode`. Актуальны `'row'` (подсветка строки) и `'disabled'`.\n */\n highlightActiveType?: HighlightActiveType;\n /**\n * Единый конфиг выделения ячеек: режим (`mode`), оси\n * (`enableColumnSelection`/`enableRowSelection`/`enableSelectAll`) и controlled\n * (`state`). См. {@link CellsSelectionConfig}.\n */\n cellsSelection?: CellsSelectionConfig;\n /**\n * Подсвеченная строка (`highlightActiveType='row'`).\n * `state` (опционально) — controlled-кортеж `[value, setter]`: задан — значением\n * владеешь снаружи (сброс `setter(undefined)`); не задан — таблица крутит\n * подсветку внутренним стейтом, а `onChange` всё равно срабатывает (подписка\n * без владения значением).\n */\n highlightActiveRow?: {\n state?: [\n number | undefined,\n React.Dispatch<React.SetStateAction<number | undefined>>,\n ];\n /**\n * Колбэк смены подсвеченной строки: отдаёт её флэт-индекс и сам объект\n * строки (`rows[index]`). Позволяет открывать данные подсвеченной строки\n * (например, в SplitView) без `onCellClicked`.\n */\n onChange?: (params: {\n index: number | undefined;\n row: RowType | undefined;\n }) => void;\n };\n /**\n * Эффекты при наведении (hover)\n * `row` — подсветка строки под курсором.\n * Независимая визуальная ось: селектинг (`cellsSelection`) и `highlightActiveType='row'`\n * рисуются ПОВЕРХ hover-подсветки и визуально перекрывают её (hover\n * «остаётся под ними» и снова виден после сброса выделения).\n *\n * `{ row: true }` — включить с цветами из темы;\n * `{ row: { color: '#F7F9FB' } }` — переопределить цвет data-ячеек.\n * @default undefined (выключено)\n */\n hoverEffects?: HoverEffectsConfig;\n /**\n * Включает компенсацию тонких canvas-линий при browser zoom ниже 100%, когда devicePixelRatio меньше 1.\n * Влияет только на grid/header/sticky hairline borders.\n * @default false\n */\n enableLowDprHairline?: boolean;\n /**\n * Управление рамками (линиями) таблицы: включение и выключение.\n *\n * Уровни, от слабого к сильному: общие настройки (vertical, horizontal),\n * затем колонка (getVerticalBorder) и строка (getHorizontalBorder), затем\n * ячейка (getCellBorder).\n *\n * `vertical: false` и `horizontal: false` убирают все вертикальные или\n * горизонтальные линии тела. `getCellBorder` включает и выключает стороны\n * рамки конкретной ячейки; при его использовании линии рисуются с разбивкой\n * по ячейкам.\n */\n borders?: BordersConfig<RowType>;\n /**\n * rowSize - размеры строк таблицы\n */\n rowSize?: Prettify<RowSize>;\n /**\n * rowHeight - размер высоты строк таблицы\n */\n rowHeight?: Maybe<number | RowHeightFunc<RowType>>;\n /**\n * sorting - активация сортировки. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={sorting: {sortingState}}\n *\n * columnConfig=[{sortingType: 'numberSort'}]\n */\n sorting?: {\n state: [\n readonly SortColumn[],\n React.Dispatch<React.SetStateAction<readonly SortColumn[]>>,\n ];\n /**\n * manualSorting - пропс, активирующий ручную-кастомную (или на стороне бэкенда) сортировку\n */\n manualSorting?: boolean;\n };\n /** @deprecated Свойство view не используется и будет удалено в следующей мажорной версии. */\n view?: View;\n /**\n * filtering - активация фильтрации. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={filtering: {stateAndSetter, ...}}\n *\n * columnConfig=[{filtering: {...}}]\n */\n filtering?: FilteringConfig<FilterStateType>;\n /**\n * Сворачивание / разворачивание таблицы\n */\n collapsing?: TableCollapseConfig;\n /**\n * selecting - активация выбора строк. Условие активации - это наличие данного свойства.\n * Есть поддержка выбора строк с многоуровневой вложенностью.\n *\n * Пример:\n *\n *"
54416
+ "source": "type FilteringConfig<T> = {\n state: [T, React.Dispatch<React.SetStateAction<T>>];\n /**\n * @deprecated Использовать filtersInfo\n *\n * clearedValue - состояние фильтров после очистки. Используется для сравнения:\n * Например, был ли фильтр конкретной колонки изменен рассчитывается посредством сравнения текущего значения фильтра и значения фильтра в clearedValue.\n * Если они равны, то фильтр считается не измененным.\n */\n clearedValue?: T;\n /**\n * Информация о фильтрах для каждой колонки.\n * Используется для:\n * 1. Хранения меток (label) фильтров для отображения в UI\n * 2. Хранения значений по умолчанию (clearedValue) для каждого фильтра\n * 3. Определения, был ли фильтр изменен (сравнение текущего значения с clearedValue)\n */\n filtersInfo?: Record<\n keyof T,\n {\n label: string;\n clearedValue: T[keyof T];\n }\n >;\n /**\n * manualFiltering - пропс, активирующий ручную-кастомную (или на стороне бэка) фильтрацию.\n * @remarks\n * Для автоматической фильтрации (когда не используется manualFiltering в tableConfig):\n * - Для всех типов фильтров обязательно должен быть указан `valueInRow`\n * - Для component: 'select' дополнительно должен быть указан `filteringType`\n * - Для component: 'input' с кастомным фильтром (когда filter - функция)\n * функция фильтрации должна быть передана явно\n *\n * Если используется manualFiltering, эти параметры не обязательны,\n * так как вся логика фильтрации реализуется извне.\n */\n manualFiltering?: boolean;\n /**\n * Конфигурация для отображения фильтров в правом сайдбаре.\n *\n * Позволяет:\n * 1. Добавлять глобальные фильтры (не привязанные к конкретной колонке)\n * 2. Управлять порядком отображения фильтров\n * 3. Переопределять рендер и заголовки колоночных фильтров\n *\n * Логика работы:\n * - По умолчанию в сайдбаре отображаются все колоночные фильтры (из columnConfig)\n * - Ключом фильтра считается `key` колонки, если его нет, то пытаемся взять `keyInFilterState` (если указан), иначе это не будет работать\n * - Заголовком фильтра по умолчанию является `name` колонки или ключ фильтра (name || key)\n * - Глобальные фильтры добавляются через `items` с уникальными ключами\n *\n * Особенности:\n * 1. Порядок отображения:\n * - Сначала фильтры из `order` (в указанной последовательности)\n * - Затем остальные колоночные фильтры (в порядке columnConfig)\n * - В конце - глобальные фильтры (в алфавитном порядке ключей)\n *\n * 2. Переопределение колоночных фильтров:\n * - Чтобы изменить заголовок: укажите ключ колонки в `items` с новым `label`\n * - Чтобы заменить рендер: укажите ключ колонки с `customRenderFn`\n * - Оригинальный фильтр из колонки будет проигнорирован\n *\n * 3. Глобальные фильтры:\n * - Ключ не должен совпадать с ключами колонок\n * - Обязательно указать `label` и `customRenderFn`\n * - Отображаются после всех колоночных фильтров, если не переопределены в order\n *\n * @example\n * // Добавление глобального фильтра и изменение порядка\n * sidebarConfig: {\n * order: ['status', 'tasks', 'type'], // Сначала статус, затем глобальный поиск\n * items: {\n * tasks: { // Уникальный ключ\n * label: 'Поиск по всем полям',\n * customRenderFn: () => <TaskComponent />\n * },\n * status: { // Переопределение колоночного фильтра\n * label: 'Статус заявки', // Новый заголовок\n * customRenderFn: () => <CustomStatusFilter /> // Кастомный рендер\n * }\n * type: { // Переопределение только Label колоночного фильтра\n * label: 'Тип', // Новый заголовок\n * }\n * }\n * }\n */\n sidebarConfig?: {\n /**\n * Определяет порядок отображения фильтров.\n * - Указываются ключи фильтров (колоночных или глобальных)\n * - Не указанные в order фильтры отображаются после\n * - Если order пуст, сохраняется порядок: глобальные фильтры + columnConfig фильтры в конце\n */\n order?: string[];\n /**\n * Конфигурация фильтров для сайдбара.\n * Ключом может быть:\n * - Ключ колонки (для переопределения колоночного фильтра)\n * - Уникальный ключ (для добавления глобального фильтра)\n */\n items: Partial<\n Record<\n keyof T,\n {\n /** Заголовок фильтра (обязателен для глобальных фильтров), можно использовать для переопределения для локальных фильтров */\n label: string;\n /**\n * Функция рендера компонента фильтра.\n * Для колоночных фильтров переопределяет оригинальный рендер.\n * Для глобальных фильтров обязательна.\n */\n customRenderFn?: (\n filters: T,\n setFilters: React.Dispatch<React.SetStateAction<T>>,\n ) => React.ReactNode;\n }\n >\n >;\n };\n /**\n * Callback для кастомизации стилей чипсов (фильтров) в списке\n *\n * @param {ItemOrGroup} itemOrGroup - Текущий элемент или группа фильтров\n * @param {Item | undefined} item - Конкретный элемент фильтра (если есть)\n * @returns {CSSObject} Объект стилей, который будет применен к чипсу\n *\n * @description\n * Позволяет динамически задавать стили для каждого чипса в зависимости от его типа и содержимого.\n * Вызывается для каждого отображаемого чипса (как для отдельных элементов, так и для элементов внутри групп).\n *\n * @example\n * // Пример 1: Стилизация чипсов по типу\n * chipStyle: (itemOrGroup, item) => {\n * if (isGroup(itemOrGroup)) {\n * return { backgroundColor: '#f0f0f0' };\n * }\n * return { backgroundColor: '#e0e0e0' };\n * }\n *\n * @example\n * // Пример 2: Стилизация по значению фильтра\n * chipStyle: (itemOrGroup, item) => {\n * if (item?.label === 'Высокий приоритет') {\n * return {\n * backgroundColor: '#ffebee',\n * color: '#d32f2f'\n * };\n * }\n * return {};\n * }\n *\n * @example\n * // Пример 3: Разные стили для элементов в группе и одиночных\n * chipStyle: (itemOrGroup, item) => {\n * if (item) {\n * // Стиль для элемента внутри группы\n * return { maxWidth: 180 };\n * }\n * // Стиль для одиночного чипа\n * return { maxWidth: 150 };\n * }\n */\n chipStyle?: (itemOrGroup: ItemOrGroup, item: Item | undefined) => CSSObject;\n /**\n * Пользовательский форматтер заголовка группы чипсов.\n *\n * Используется в блоке активных фильтров для подмены текста заголовка\n * группы (например, “Статус”, “Тип”, “Автор”). Полезно, когда нужно\n * динамически менять подпись (добавить счётчик, i18n и т.п.).\n *\n * @param {ItemOrGroup} itemOrGroup Объект группы (тип Group). Вызов происходит только для групп,\n * поэтому безопасно кастовать к Group.\n * @returns {string} Текст заголовка группы чипсов.\n *\n * @default Возвращается `group.groupLabel`.\n *\n * @remarks\n * - Функция должна быть чистой и быстрой (без сетевых запросов и побочных эффектов).\n * - Возвращайте ТОЛЬКО строку — чипы отображают текстовое значение.\n * - Для длинных строк применяется усечение (overflow с многоточием) на уровне компонента.\n *\n * @example\n * // Добавить двоеточие и количество выбранных элементов\n * renderGroupLabel: (group) => `${group.groupLabel}: ${group.items.length}`\n *\n * @example\n * // Локализация заголовка группы\n * const i18n = { status: 'Статус', type: 'Тип' };\n * renderGroupLabel: (group) => i18n[group.groupId] ?? group.groupLabel\n */\n renderGroupLabel?: (group: Group) => string;\n\n /**\n * Пользовательский форматтер текста чипса (элемента внутри группы или одиночного фильтра).\n *\n * Позволяет управлять тем, что именно отображается внутри каждого чипса. Особенно полезен\n * при серверной пагинации/ленивой загрузке, когда в состоянии фильтра хранится только value,\n * а label необходимо подставить из локального кэша.\n *\n * @param {Group | null } group Группа, внутри которой рендерится чип (или null).\n * @param {Item} item Сам элемент чипса. В группах передаётся конкретный `Item`,\n * для одиночного чипа может быть `undefined`.\n * @returns {string} Текст, который будет показан в чипсе.\n *\n * @default Используется `item?.label.toString()` (или строковое представление value).\n *\n * @remarks\n * - Функция должна быть чистой и быстрой;\n * - Возвращайте ТОЛЬКО строку.\n *\n * @example\n * // 1) Отображение label из кэша при серверной пагинации\n * const labelsCacheRef = useRef(new Map<string, string>());\n * renderChipLabel: (group, item) => {\n * if (item?.id != null) {\n * const key = String(item.id);\n * const fromCache = labelsCacheRef.current.get(key);\n * if (fromCache) return fromCache; // красивый label, если уже загрузили\n * return String(item.label ?? key); // фоллбэк: временно показываем value/label из item\n * }\n * return ''; // безопасный фоллбэк для одиночных случаев\n * }\n *\n * @example\n * // 2) Нормализация отображения числовых значений\n * renderChipLabel: (_group, item) => {\n * const v = Number(item?.label);\n * return Number.isFinite(v) ? v.toLocaleString('ru-RU') : String(item?.label ?? '');\n * }\n *\n * @example\n * // 3) Префикс по типу группы\n * renderChipLabel: (group, item) => {\n * const prefix = group.groupId === 'status' ? '' : '#';\n * return `${prefix}${item?.label ?? item?.id ?? ''}`;\n * }\n */\n renderChipLabel?: (group: Group | null, item: Item) => string;\n};\n\nexport type DefaultSidebarTabIds = 'columns' | 'tableSettings' | 'filtering';\n\n/**\n * Конфигурация sidebar\n */\nexport type SidebarConfig = {\n /**\n * Включен ли sidebar. Отвечает только за UI. Не влияет на перерасчёт фичей.\n * @default true\n */\n enabled?: boolean;\n /**\n * Открыт ли sidebar при первом рендере (uncontrolled-режим).\n * Игнорируется, если передан openState.\n * @default false\n */\n defaultOpen?: boolean;\n /**\n * Внешний контроль открытия/закрытия sidebar.\n * Если передан — источник истины, defaultOpen игнорируется.\n */\n openState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n /**\n * id вкладки, выбранной по умолчанию (актуально при открытом сайдбаре).\n * Если id не найден или у вкладки showInSidebar=false — используется первая доступная.\n */\n defaultActiveTabId?: string;\n /**\n * Внешний контроль активной вкладки (controlled-режим).\n * Если передан — источник истины, defaultActiveTabId игнорируется.\n */\n activeTabState?: [\n string | null,\n React.Dispatch<React.SetStateAction<string | null>>,\n ];\n /**\n * Колбэк смены активной вкладки. Вызывается и в uncontrolled-режиме.\n * При закрытии сайдбара приходит null.\n */\n onActiveTabChange?: (tabId: string | null, tab?: SidebarTab) => void;\n /**\n * Кастомные табы\n */\n customTabs?: Array<\n Omit<SidebarTab, 'id'> & {\n id: Exclude<string, DefaultSidebarTabIds>;\n }\n >;\n /**\n * Порядок отображения кастомных вкладок\n */\n customTabsOrder?: Array<Exclude<string, DefaultSidebarTabIds>>;\n defaultTabs?: Array<\n | {\n id: 'filtering' | 'columns';\n /** название таба в рамках горизонтального табов внутри таба настройки */\n label?: string;\n /** название таба в рамках вертикальных табов сайдбара (если данный таб окажется единственным табом в настройках) */\n title?: string;\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n domMetadata?: DomMetadata;\n /**\n * Кастомный элемент справа от title в шапке сайдбара\n */\n titleRightSlot?: React.ReactNode;\n /** @default true */\n showInSidebar?: boolean;\n /** тултип иконки шестеренки (для табов с id = filtering и columns - недоступен. Настраивается через таб с id='tableSettings') */\n iconTooltipText?: undefined;\n }\n | {\n id: 'tableSettings';\n /** название таба в рамках горизонтального табов внутри таба настройки */\n label?: string;\n /** название таба в рамках вертикальных табов сайдбара */\n title?: string;\n\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n domMetadata?: DomMetadata;\n /**\n * Кастомный слот для вкладки tableSettings (рендерится после общих настроек)\n * Только дл id: 'tableSettings'\n */\n customGeneralSettingsSlot?: React.ReactNode;\n /**\n * Кастомный элемент справа от title в шапке сайдбара\n */\n titleRightSlot?: React.ReactNode;\n /** @default true */\n showInSidebar?: boolean;\n /** тултип иконки шестеренки @default 'Настройки' */\n iconTooltipText?: string;\n }\n >;\n};\n\nexport function activeViewIs<T extends 'cards' | 'rows'>(\n checkType: T,\n viewState: 'cards' | 'rows',\n view: View,\n): view is ViewMods[T] {\n return checkType === viewState;\n}\n\n/** Размер controlBlock: 'm' и 's' — одинаковые стили, 'xs' — уменьшенный */\nexport type ControlBlockSize = 'm' | 's' | 'xs';\n\nexport type ControlBlockConfig = {\n /**\n * show - наличие controlBlock-а\n * @default true\n */\n show?: boolean;\n /**\n * Размер controlBlock и его элементов (кнопки, иконки, поиск, отступы).\n * 'm' и 's' — стандартные стили, 'xs' — компактный режим.\n * Не влияет на customFeatures и кастомные слоты — они контролируются разработчиком.\n * @default 'm'\n */\n size?: ControlBlockSize;\n /**\n * @deprecated Используйте кастомные кнопки через rightSideInner или customFeatures.\n * leftSideInner - пропс для добавления кнопок в левую часть контролблока.\n * Продолжает работать для обратной совместимости.\n */\n leftSideInner?: ControlBlockButtonProps[];\n /**\n * rightSideInner - пропс для добавления кнопок в правую часть контролблока\n */\n rightSideInner?: ControlBlockButtonProps[];\n /**\n * customFeatures - пропс для добавления кастомных фичей (кнопки-иконки)\n */\n customFeatures?: FeatureItem[];\n /**\n * pinningMenu - нативная фича закрепления столбцов (SplitIconButton с\n * дропдауном) в правой зоне иконок. Появляется, когда активировано\n * закрепление колонок (columnsControl.pinning). Продукт может донастроить\n * и дополнить пункты меню (см. PinningMenuConfig).\n */\n pinningMenu?: PinningMenuConfig;\n /**\n * Пропсы для компонента dropdown в котором будут скрыты левые фичи при адаптивной компрессии\n */\n leftSideDropdownProps?: TableDropdownConfigProps;\n /**\n * Пропсы для компонента dropdown в котором будут скрыты правые фичи при адаптивной компрессии\n */\n rightSideDropdownProps?: TableDropdownConfigProps;\n /**\n * Активна ли фича компрессии (сжатие ToolsMenu при адаптиве)\n * @default true\n */\n enableAdaptiveCompress?: boolean;\n /**\n * Панель массовых действий\n */\n massActionPanel?: {\n /**\n * Кнопки панели. Размеры кнопок/дропдаунов панель подбирает сама (по `size` панели и компактности) —\n * передавать `size` кнопкам не нужно. Если `size` на кнопке всё же задан — он используется как есть.\n */\n buttons: MassActionButtonProps[];\n /**\n * Пропсы для Dropdown, в который сжались кнопки\n */\n collapsedDropdownProps?: TableDropdownConfigProps;\n /**\n * Отступ панели снизу от контейнера (px)\n * @default 24\n */\n bottom?: number;\n /**\n * Управление отображением панели массовых действий.\n * - `undefined` (по умолчанию) — стандартное поведение (показывается при selecting + выбранных строках)\n * - `false` — панель не рендерится, разработчик управляет действиями самостоятельно\n * - `true` — панель показывается всегда, даже без активного selecting и выбранных строк\n */\n show?: boolean;\n /**\n * Размерная сетка панели внутри таблицы: `m`/`s` — обычный размер, `xs` — уменьшенный (кнопки `xxs`, «ещё» `xs`, счётчик Body XS).\n * Viewport-логика (1280) в таблице не используется.\n * @default 's'\n */\n size?: MassActionsSize;\n };\n};\n\n/** Пропсы кнопки редактирования. onClick исключён — используйте onSave/onCancel/onEnableEditing. */\nexport type EditingButtonProps = Omit<\n Partial<ControlBlockButtonProps>,\n | 'onClick'\n | 'size'\n | 'dropdown'\n | 'isTargetAction'\n | 'skipRightDivider'\n | 'tooltipText'\n>;\n\nexport type EditingConfig<\n RowType extends ObjectForExtending,\n RowIdType,\n SummaryRowType,\n> = {\n /**\n * Функция обработки изменений в редактируемой строке\n */\n onRowsChange: Maybe<\n (rows: RowType[], data: RowsChangeData<RowType, SummaryRowType>) => void\n >;\n /**\n * свойство, необходимое для корректного изменения дочерних строк.\n * Данное свойство обязательно, если ваши дочерние строки установлены не под ключом \"subRows\" внутри строки.\n *\n * Как дочерние строки можно указывать свойство, которые вложено в другое свойство.\n * В таком случае \".\" будет знаком для обозначения сл. уровня вложенности.\n *\n * @example \"child\" или \"uvh367.children\"\n */\n subRowsKey?: string;\n /**\n * Глубокое копирование строк перед применением правки в режиме редактирования.\n *\n * Включите, если строки, передаваемые в таблицу, иммутабельны/заморожены\n * (напр. стейт под управлением Redux Toolkit или Immer — они вызывают\n * Object.freeze в dev). При редактировании дочерней строки таблица записывает\n * изменение ВНУТРЬ объекта родителя; на замороженном объекте это падает с\n * `TypeError: Cannot assign to read only property`.\n *\n * Когда флаг включён, таблица сама делает structuredClone редактируемой строки\n * перед записью — ваш иммутабельный стейт не мутируется, и редактирование\n * дочерних строк работает без действий с вашей стороны.\n *\n * ⚠️ Данные строки должны быть сериализуемыми. Где доступен structuredClone —\n * Date/Map/Set и вложенные структуры копируются корректно; на старых средах\n * без structuredClone используется JSON-фоллбэк (теряет Date/Map/Set, undefined\n * и функции). Не включайте без необходимости — глубокое копирование добавляет\n * накладные расходы.\n *\n * @default false\n */\n deepCloneRows?: boolean;\n /**\n * Функция определения уникального id строки\n * @param row\n * @returns\n */\n rowKeyGetter: (row: RowType) => RowIdType;\n /**\n * Функция определения возможности редактирования строки\n * @param row\n * @returns\n */\n rowEditable?: (row: RowType) => boolean;\n /**\n * defaultEnabled - пропс, отвечающий за то, будет ли активен режим редактирования или нет. По умолчанию - не активно.\n * @default false\n */\n defaultEnabled?: boolean;\n /**\n * enabled - необходим для управления режимом редактирования снаружи компонента Таблицы.\n * По умолчанию, управление происходит в компоненте.\n * Приоритетнее, чем defaultEnabled.\n *\n * @type boolean - если НЕ нужно переключение в самой таблице\n * @type [boolean, React.Dispatch<React.SetStateAction<boolean>>] - если нужно переключение в самой таблице\n *\n */\n enabled?: boolean | [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n /**\n * Cостояние скрытия/раскрытия кнопки включения/выключения фичи\n * @default true\n */\n showButtons?: boolean;\n /**\n * Функция, вызывающаяся при включении фичи.\n * @param enableEditorMode - функция включающая режим редактирования\n */\n onEnableEditing?: (enableEditorMode: () => void) => void;\n /**\n * Функция, вызывающаяся при сохранении отредактированного.\n * @param disableEditorMode - функция выключающая режим редактирования\n */\n onSave?: (disableEditorMode: () => void) => void;\n /**\n * Функция, вызывающаяся при отмене отредактированного.\n * @param disableEditorMode - функция выключающая режим редактирования\n */\n onCancel?: (disableEditorMode: () => void) => void;\n /** Пропсы кнопок в controlBlock. */\n buttons?: {\n save?: EditingButtonProps;\n cancel?: EditingButtonProps;\n edit?: EditingButtonProps;\n };\n /**\n * Кастомный слот, отображаемый левее кнопок «Отменить» / «Сохранить».\n * Виден только когда режим редактирования активен (editMode = true).\n * Зона ответственности разработчика — размерная сетка controlBlock не влияет на этот слот.\n */\n editModeLeftSlot?: React.ReactNode;\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n domMetadata?: {\n enableButton?: DomMetadata;\n saveButton?: DomMetadata;\n cancelButton?: DomMetadata;\n };\n};\n\nexport type SummaryRowsConfig = {\n showDefault: boolean;\n showInControl: boolean;\n /**\n * callback при переключении тогла «Итоговые строки» в настройках таблицы.\n * Вызывается только по действию пользователя (не при монтировании),\n * поэтому подходит для сохранения выбора, например, в localStorage.\n * Сохранённое значение передавайте обратно в `showDefault`.\n */\n onChange?: (checked: boolean) => void;\n} & {\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n domMetadata?: DomMetadata;\n};\n\n/**\n * Конфиг тултипа при hover по canvas-элементам.\n * Для активации фичи необходимо заполнить данный конфиг,\n * а также добавить нужные изменения в Canvas-элементах или в конфиге колонки.\n */\nexport type TableConfigTooltip = {\n /**\n * Включить/выключить колоночные и кастомные тултипы (cellTooltip, headerCellTooltip).\n * Внутренние тултипы (drag-иконка в шапке и другие по nodeId) работают всегда.\n * @default false\n */\n enabled?: boolean;\n /** Глобальная задержка перед показом тултипа (мс). Per-node переопределяет. @default 500 */\n mouseEnterDelay?: number;\n /** Глобальная задержка перед скрытием тултипа (мс). Per-node переопределяет. @default 0 */\n mouseLeaveDelay?: number;\n /**\n * Минимальная ширина тултипа. Число трактуется как px, строка с единицей\n * (например '20rem', '50%') отдаётся как есть. Действует на все canvas-тултипы,\n * включая авто-тултип Canvas.Text. Если ширина задана на самом тултипе\n * (per-node), приоритет у неё.\n */\n minWidth?: number | string;\n /**\n * Максимальная ширина тултипа. Число трактуется как px, строка с единицей\n * (например '20rem', '50%') отдаётся как есть. Действует на все canvas-тултипы,\n * включая авто-тултип Canvas.Text. Если ширина задана на самом тултипе\n * (per-node), приоритет у неё.\n */\n maxWidth?: number | string;\n};\n\nexport type InfinityScrollConfig<RowType extends ObjectForExtending> = {\n /** Триггер достижения скроллом зоны подгрузки данных. */\n onTrigger: (rows: RowType[]) => Promise<void> | void;\n /** Состояние загрузки (скелетоны) новых строк. */\n isLoading: boolean;\n /**\n * Флаг, когда все данные загружены — false.\n * @default true\n */\n hasMore?: boolean;\n /**\n * Для mode='region': за сколько строк до конца триггерить загрузку.\n * @default 5\n */\n rowThreshold?: number;\n};\n\nexport type { TableCanvasEmptyStateConfig, TableCanvasErrorStateConfig };\n\n/**\n * Настройка выделения ячеек/колонок/строк в TableCanvas — единый объект.\n * Это отдельная ось взаимодействия — не зависит от `highlightActiveType`.\n */\nexport type CellsSelectionConfig = {\n /**\n * Режим фактического выделения ячеек (нативный glide selection). По нему\n * работают copy/paste, рамка, fill-handle и затемнение шапки/нумерации.\n * @default \"range-cell\"\n */\n mode?: CellsSelectionMode;\n /**\n * Выделение колонок по клику на шапку. Ctrl/Cmd — добавить/убрать колонку,\n * Shift — диапазон колонок. Клик по иконкам сортировки/фильтрации в шапке\n * выделение НЕ вызывает. Поддерживает copy/paste по выделенным колонкам.\n * @default true\n */\n enableColumnSelection?: boolean;\n /**\n * Выделение строк по клику/драгу на колонке нумерации (`rowMarkers`).\n * Ctrl/Cmd — несмежный выбор отдельных строк, драг — смежный диапазон.\n * Поддерживает copy/paste по выделенным строкам. Требует включённой колонки\n * нумерации (`rowMarkers`). При `false` клик по нумерации ничего не выделяет.\n * @default true\n */\n enableRowSelection?: boolean;\n /**\n * Выделение всей таблицы кликом по «нулевой» ячейке — шапке колонки нумерации\n * (левый верхний угол). Выделяет все строки данных по всем колонкам одним\n * диапазоном; поддерживает copy/paste. Требует включённой колонки нумерации\n * (`rowMarkers`) и активного `mode` (≠ `disabled`).\n * @default true\n */\n enableSelectAll?: boolean;\n /**\n * Внешний (controlled) контроль НАТИВНОГО выделения (ячейки/диапазон/смежные\n * строки и колонки). `state` — кортеж `[value, setter]` как у `selecting.state`.\n * Сброс: `setter({ current: undefined, rows: empty, columns: empty })`.\n * Несмежный Ctrl-выбор колонок/строк (own-state) сюда не входит — он внутренний.\n */\n state?: [GridSelection, React.Dispatch<React.SetStateAction<GridSelection>>];\n};\n\n/** Один объединённый блок: какие строки и колонки слить. */\nexport type MergedCellsRegion = {\n rowKeys: Array<string | number>;\n colKeys: string[];\n /** Выравнивание контента этого блока. Важнее колоночного и общего. */\n mergedCellsAlign?: MergedCellsAlign;\n};\n\n/**\n * Видимость сторон рамки ячейки: true рисовать, false не рисовать, не задано -\n * работает уровень ниже (настройка колонки, строки или общая).\n */\nexport type CellBorderVisibility = {\n top?: boolean;\n right?: boolean;\n bottom?: boolean;\n left?: boolean;\n};\n\n/**\n * Управление рамками (линиями) таблицы: включение и выключение. Уровни, от\n * слабого к сильному: общие настройки (vertical, horizontal), затем колонка\n * (getVerticalBorder) и строка (getHorizontalBorder), затем ячейка\n * (getCellBorder).\n */\nexport type BordersConfig<RowType = ObjectForExtending> = {\n /** Рисовать ли вертикальные линии между колонками. @default true */\n vertical?: boolean;\n /** Рисовать ли горизонтальные линии между строками тела. @default true */\n horizontal?: boolean;\n /**\n * Точечное управление вертикальной линией справа от колонки (разделитель\n * после неё). Вернуть true или false, чтобы переопределить общую настройку\n * vertical, или undefined, чтобы оставить её. Зовётся на каждую видимую\n * колонку при перерисовке, поэтому функция должна быть быстрой.\n */\n getVerticalBorder?: (params: {\n /** Ключ колонки, справа от которой рисуется линия. */\n columnKey: string;\n /** Индекс колонки в порядке отрисовки (закреплённые в начале). */\n columnIndex: number;\n }) => boolean | undefined;\n /**\n * Точечное управление горизонтальной линией сверху строки. Вернуть true или\n * false, чтобы переопределить общую настройку horizontal, или undefined,\n * чтобы оставить её. Для summary-строк не вызывается. Зовётся на каждую\n * видимую строку при перерисовке, поэтому функция должна быть быстрой.\n */\n getHorizontalBorder?: (params: {\n /** Строка под линией (линия рисуется сверху этой строки). */\n row: RowType;\n /** Индекс строки среди отображаемых. При раскрытии subRows индексы сдвигаются. */\n rowIndex: number;\n /** Уровень вложенности subRows: 0 корень, 1 и больше дочерние. */\n treeLvl: number;\n }) => boolean | undefined;\n /**\n * Стороны рамки конкретной ячейки, вкл и выкл. Для ячеек без переопределений\n * возвращать undefined. Включает отрисовку линий с разбивкой по ячейкам,\n * поэтому функция должна быть быстрой: без тяжёлых вычислений и с готовыми\n * объектами-константами вместо новых на каждый вызов. Для summary-строк не\n * вызывается.\n */\n getCellBorder?: (params: {\n /** Индекс колонки среди отображаемых (без служебных). */\n col: number;\n /** Ключ колонки. */\n columnKey: string | undefined;\n /** Строка ячейки. */\n row: RowType;\n /** Индекс строки среди отображаемых. */\n rowIndex: number;\n /** Уровень вложенности subRows: 0 корень, 1 и больше дочерние. */\n treeLvl: number;\n }) => CellBorderVisibility | undefined;\n};\n\nexport type TableConfig<\n RowType extends ObjectForExtending,\n SummaryRowType,\n RowIdType extends string | number,\n FilterStateType extends ObjectForExtending,\n // SubRowType\n> = {\n /**\n * Группировка колонок (многоуровневая шапка через `columnConfig.children`):\n * объединение пустых ячеек шапки (`squashEmptyCells`, по умолчанию включено) и\n * дефолт выравнивания в объединённых ячейках (`squashedHeaderAlign`).\n */\n columnsGrouping?: ColumnsGroupingConfig;\n /**\n * Подсветка активной сущности в canvas-таблице.\n * @deprecated Значения `'cell'`/`'range-cell'` устарели — используйте\n * `cellsSelection.mode`. Актуальны `'row'` (подсветка строки) и `'disabled'`.\n */\n highlightActiveType?: HighlightActiveType;\n /**\n * Единый конфиг выделения ячеек: режим (`mode`), оси\n * (`enableColumnSelection`/`enableRowSelection`/`enableSelectAll`) и controlled\n * (`state`). См. {@link CellsSelectionConfig}.\n */\n cellsSelection?: CellsSelectionConfig;\n /**\n * Подсвеченная строка (`highlightActiveType='row'`).\n * `state` (опционально) — controlled-кортеж `[value, setter]`: задан — значением\n * владеешь снаружи (сброс `setter(undefined)`); не задан — таблица крутит\n * подсветку внутренним стейтом, а `onChange` всё равно срабатывает (подписка\n * без владения значением).\n */\n highlightActiveRow?: {\n state?: [\n number | undefined,\n React.Dispatch<React.SetStateAction<number | undefined>>,\n ];\n /**\n * Колбэк смены подсвеченной строки: отдаёт её флэт-индекс и сам объект\n * строки (`rows[index]`). Позволяет открывать данные подсвеченной строки\n * (например, в SplitView) без `onCellClicked`.\n */\n onChange?: (params: {\n index: number | undefined;\n row: RowType | undefined;\n }) => void;\n };\n /**\n * Эффекты при наведении (hover)\n * `row` — подсветка строки под курсором.\n * Независимая визуальная ось: селектинг (`cellsSelection`) и `highlightActiveType='row'`\n * рисуются ПОВЕРХ hover-подсветки и визуально перекрывают её (hover\n * «остаётся под ними» и снова виден после сброса выделения).\n *\n * `{ row: true }` — включить с цветами из темы;\n * `{ row: { color: '#F7F9FB' } }` — переопределить цвет data-ячеек.\n * @default undefined (выключено)\n */\n hoverEffects?: HoverEffectsConfig;\n /**\n * Включает компенсацию тонких canvas-линий при browser zoom ниже 100%, когда devicePixelRatio меньше 1.\n * Влияет только на grid/header/sticky hairline borders.\n * @default false\n */\n enableLowDprHairline?: boolean;\n /**\n * Управление рамками (линиями) таблицы: включение и выключение.\n *\n * Уровни, от слабого к сильному: общие настройки (vertical, horizontal),\n * затем колонка (getVerticalBorder) и строка (getHorizontalBorder), затем\n * ячейка (getCellBorder).\n *\n * `vertical: false` и `horizontal: false` убирают все вертикальные или\n * горизонтальные линии тела. `getCellBorder` включает и выключает стороны\n * рамки конкретной ячейки; при его использовании линии рисуются с разбивкой\n * по ячейкам.\n */\n borders?: BordersConfig<RowType>;\n /**\n * rowSize - размеры строк таблицы\n */\n rowSize?: Prettify<RowSize>;\n /**\n * rowHeight - размер высоты строк таблицы\n */\n rowHeight?: Maybe<number | RowHeightFunc<RowType>>;\n /**\n * headerRowHeight - высота одного ряда шапки (в px). По умолчанию 33.\n *\n * Значение применяется к КАЖДОМУ уровню шапки: как к листовому (нижнему) ряду\n * колонок, так и к каждому уровню объединённых (групповых) заголовков. Поэтому\n * при N уровнях группировки итоговая высота шапки = headerRowHeight * (1 + N).\n * Например, headerRowHeight={50} при 2 уровнях групп даст шапку 50 + 50 + 50 = 150px.\n */\n headerRowHeight?: Maybe<number>;\n /**\n * sorting - активация сортировки. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={sorting: {sortingState}}\n *\n * columnConfig=[{sortingType: 'numberSort'}]\n */\n sorting?: {\n state: [\n readonly SortColumn[],\n React.Dispatch<React.SetStateAction<readonly SortColumn[]>>,\n ];\n /**\n * manualSorting - пропс, активирующий ручную-кастомную (или на стороне бэкенда) сортировку\n */\n manualSorting?: boolean;\n };\n /** @deprecated Свойство view не используется и будет удалено в следующей мажорной версии. */\n view?: View;\n /**\n * filtering - активация фильтрации. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={filtering: {stateAndSetter, ...}}\n *\n * columnConfig=[{filtering: {...}}]\n */\n filtering?: FilteringConfig<FilterStateType>;\n /**\n * Сворачивание / разворачивание таблицы\n */\n collapsing?: TableCollapseConfig;\n /**\n * selecting - активация выбора строк. Условие активации - это наличие данного свойства.\n * Есть поддержка выбора строк с многоуровневой вложенностью.\n *\n * Пример:\n *\n *"
53891
54417
  },
53892
54418
  {
53893
54419
  "typeName": "FilterComponentInPopoverProps",
@@ -54037,6 +54563,23 @@
54037
54563
  }
54038
54564
  ]
54039
54565
  },
54566
+ {
54567
+ "component": "TableCanvas",
54568
+ "feature": "HeaderRowHeight",
54569
+ "legacy": false,
54570
+ "summary": "*tableConfig.headerRowHeight**",
54571
+ "docs": "# HeaderRowHeight (TableCanvas)\n\n**tableConfig.headerRowHeight**\n\nНастройка высоты ряда шапки таблицы. Одно число задаёт высоту заголовков. По умолчанию `33`.\n\n## Ключевые особенности\n\n- Фиксированная высота ряда шапки (`number`)\n- Значение задаётся один раз в `tableConfig`\n- Применяется ко всем уровням объединённой (групповой) шапки одинаково\n\n## tableConfig.headerRowHeight\n\n- **`number`** — высота одного ряда шапки в пикселях\n- **по умолчанию** — `33`\n\n## Поведение с объединёнными шапками\n\nЗначение применяется к **каждому** уровню шапки: и к листовому (нижнему) ряду\nколонок, и к каждому уровню объединённых заголовков. Поэтому при `N` уровнях\nгруппировки итоговая высота шапки считается так:\n\n```\nитоговая высота = headerRowHeight * (1 + число уровней групп)\n```\n\n> Подробнее о пропсах — [API tableConfig](?path=/docs/локальные-компоненты-tablecanvas-api-tableconfig--api)",
54572
+ "apiDocs": "",
54573
+ "api": [],
54574
+ "stories": [
54575
+ {
54576
+ "exportName": "Playground",
54577
+ "displayName": "Высота шапки (3 уровня)",
54578
+ "type": "full-code",
54579
+ "code": "import {\n ColumnOrColumnGroupConfig,\n TableCanvas,\n} from '@daisforge/ui/components/TableCanvas';\n\n() => {\n const [headerRowHeight, setHeaderRowHeight] = useState<number>(33);\n\n // 2 уровня групп + листовой ряд => всего 3 уровня.\n const levels = 3;\n const total = useMemo(() => headerRowHeight * levels, [headerRowHeight]);\n\n return (\n <div>\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 16,\n marginBottom: 16,\n maxWidth: 520,\n }}\n >\n <div style={{ flex: 1 }}>\n <Slider\n value={headerRowHeight}\n onChange={setHeaderRowHeight}\n min={24}\n max={96}\n step={1}\n />\n </div>\n <span style={{ whiteSpace: 'nowrap' }}>\n headerRowHeight: {headerRowHeight}px\n </span>\n <span style={{ whiteSpace: 'nowrap', opacity: 0.7 }}>\n итог: {headerRowHeight} × {levels} = {total}px\n </span>\n </div>\n <TableCanvas\n tableConfig={{ containerStyle: { height: 420 }, headerRowHeight }}\n columnConfig={threeLevelColumns}\n rows={rows}\n />\n </div>\n );\n }"
54580
+ }
54581
+ ]
54582
+ },
54040
54583
  {
54041
54584
  "component": "TableCanvas",
54042
54585
  "feature": "HighlightActiveType",
@@ -54435,17 +54978,13 @@
54435
54978
  "component": "TableCanvas",
54436
54979
  "feature": "Selecting",
54437
54980
  "legacy": false,
54438
- "summary": "*tableConfig.selecting**",
54439
- "docs": "# Selecting Row\n\n**tableConfig.selecting**\n\nВыбор строк таблицы с помощью чекбоксов.\n\n## Ключевые особенности\n\n- Управляемое состояние через `ReadonlySet<string | number>`\n- Кнопка переключения видимости в control block (`showInControl: true`)\n- Контроль на уровне строк: `rowCheckboxDisabled`, `rowShowCheckbox`\n- Поддержка иерархических таблиц через `selectingRules.levels`\n- Кастомизация summary-чекбокса через `summaryChecked`\n\n## Особенности\n\n- `rowKeyGetter` должен возвращать уникальный идентификатор строки\n- В иерархических таблицах `selectingRules.levels` определяет, на каких уровнях доступен выбор\n- `rowGetStates` позволяет полностью переопределить логику чекбоксов (checked, indeterminate, disabled)\n- Accent-кнопки в mass action panel всегда видимы при компрессии\n\n> Подробнее о типах и пропсах — [Selecting API](?path=/docs/локальные-компоненты-tablecanvas-selecting-api--docs)\n\n## Выделение колонок — `tableConfig.cellsSelection`\n\nОтдельный от чекбоксов механизм: выделение **колонок** кликом по шапке. Не зависит\nот `highlightActiveType` — самостоятельная ось взаимодействия. По умолчанию включено.\n\n- **`enableColumnSelection`** — клик по шапке выделяет колонку. Ctrl/Cmd —\n добавить/убрать колонку, Shift — диапазон. Клик по иконкам сортировки/фильтрации\n в шапке выделение не вызывает. Поддерживается copy/paste по выделенным колонкам.\n- **`enableSelectAll`** — клик по «нулевой» ячейке (шапка колонки нумерации, левый\n верхний угол) выделяет всю таблицу целиком: все строки данных по всем колонкам.\n Поддерживает copy/paste. Требует включённой нумерации (`rowMarkers`) и активного\n `cellsSelection.mode`. По умолчанию включено.\n\n### Как читать состояние выделения\n\nВыделенные колонки приходят в обычный коллбэк\n`tableConfig.onGridSelectionChange(selection)` в поле `selection.columns`\n(`CompactSelection`, индексы колонок). Ячейки/диапазоны — там же в\n`selection.current`.\n\nЧекбоксный выбор строк (`tableConfig.selecting`) — независимый механизм со своим\nсостоянием и коллбэками, с этим API не пересекается.\n\n> Типы — раздел `CellsSelectionConfig` в [Selecting API](?path=/docs/локальные-компоненты-tablecanvas-selecting-api--docs)\n\n# SelectingRow + RowsGrouping\n\nПример кастомного выбора строк в группированной таблице.\n\nКомбинация `tableConfig.selecting` и `tableConfig.rowsGrouping` с `columnConfig.rowsGrouping`.\n\n> Типы SelectingRow — [SelectingRow API](?path=/docs/локальные-компоненты-tablecanvas-selectingrow-api--docs)\n\n> Типы RowsGrouping — [RowsGrouping API](?path=/docs/локальные-компоненты-tablecanvas-rowsgrouping-api--docs)",
54440
- "apiDocs": "# SelectingRow API\n\n> **Важно:** `tableConfig.selecting` (этот раздел) — выбор строк **чекбоксами**.\n> Это отдельный механизм от `tableConfig.cellsSelection` (см. ниже) — выделения\n> колонок по клику на шапку.\n\n## SelectingRowConfig\n\nКонфиг чекбоксного выбора строк (`tableConfig.selecting`).\n\n```typescript\ntype SelectingRowConfig<RowType, RowIdType extends string | number> = {\n /**\n * showDefault - состояние, отвечающее за то, видно ли по дефолту чекбоксы.\n */\n showDefault?: boolean;\n /**\n * showState - состояние, отвечающее за то, видны ли чекбоксы.\n */\n showState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n /**\n * showInControl - состояние, отвечающее за то, добавлять ли выбор строк как фичу, которую можно скрывать и раскрывать в правой части контролблока.\n */\n showInControl?: boolean;\n /**\n * selectingRules - пропс, отвечающий за кастомизацию логики выбора строк.\n */\n selectingRules?: {\n // TODO доработать логику\n // changeableOfRowWithoutCheckbox?: boolean;\n // changeableDisabledRow?: boolean;\n /**\n * levels - логика активации чекбоксов у строк с определенным уровнем вложенности.\n */\n levels?: number | 'all' | number[] | ((lvl: number) => boolean);\n };\n disableSummaryCheckboxInHeader?: boolean;\n hideSummaryCheckboxInHeader?: boolean;\n /**\n * hideSummaryCheckbox - в островке массовых действий\n */\n hideSummaryCheckbox?: boolean;\n /**\n * summaryChecked - пропс, отвечающий за логику состояния checked у итогового чекбокса в левой части контролблока.\n */\n summaryChecked?: {\n checked: boolean | SummaryCheckedFunc<RowType, boolean>;\n indeterminate:\n | boolean\n | SummaryCheckedFunc<RowType, boolean, { checkedAll: boolean }>;\n getCountOfChecked: SummaryCheckedFunc<RowType, number>;\n onChange: SummaryCheckedFunc<\n RowType,\n void,\n {\n checkedAll: boolean;\n clearButtonClicked?: boolean;\n setSelectedRowsIds: React.Dispatch<\n React.SetStateAction<ReadonlySet<string | number>>\n >;\n }\n >;\n };\n\n /**\n * summaryCheckedUncontrolled - пропс отвечающий за колбеки в неконтролируемом режиме\n */\n summaryCheckedUncontrolled?: {\n onChange: (event: ChangeEvent<HTMLInputElement>) => void;\n };\n\n /**\n * rowShowCheckbox - пропс, отвечающий за то, будет ли у конкретной строки отрендерен чекбокс.\n */\n rowShowCheckbox?: RowShowCheckbox<RowType>;\n /**\n * rowCheckboxDisabled - пропс, отвечающий за то, будет ли у конкретной строки чекбокс задизейблен.\n */\n rowCheckboxDisabled?: RowCheckboxDisabled<RowType>;\n /**\n * Функция для переопределения checked, indeterminate для каждой строки.\n * Что будет возвращено функцией в объекте, то будет переопределено.\n */\n rowGetStates?: (\n p: RowGetStatesProps<RowType, RowIdType>,\n ) => RowGetStatesReturnType<RowType, RowIdType> | null;\n groupedRow?: {\n /**\n * Функция для переопределения checked, indeterminate, showCheckbox, checkboxDisabled для группированных строк.\n * Что будет возвращено функцией в объекте, то будет переопределено.\n */\n getStates: (p: {\n checkedCalculated: boolean;\n indeterminateCalculated: boolean;\n row: GroupRow<RowType>;\n selectedRows: ReadonlySet<string | number>;\n selectedChildCount: number;\n childCount: number;\n }) => {\n checked?: boolean | null;\n indeterminate?: boolean | null;\n showCheckbox?: boolean | null;\n checkboxDisabled?: boolean | null;\n } | null;\n onChange?: (p: {\n row: GroupRow<RowType>;\n\n setSelectedRows: React.Dispatch<\n React.SetStateAction<ReadonlySet<string | number>>\n >;\n checked: boolean;\n indeterminate: boolean;\n checkboxDisabled: boolean;\n showCheckbox: boolean;\n defaultSetter: () => void;\n }) => void;\n };\n};\n```\n\n## CellsSelectionConfig\n\nКонфиг выделения **колонок** по клику на шапку — `tableConfig.cellsSelection`. Не\nзависит от `highlightActiveType`, по умолчанию включено. Поддерживает copy/paste\nпо выделенным колонкам.\n\n```typescript\ntype CellsSelectionConfig = {\n /**\n * Режим фактического выделения ячеек (нативный glide selection). По нему\n * работают copy/paste, рамка, fill-handle и затемнение шапки/нумерации.\n * @default \"range-cell\"\n */\n mode?: CellsSelectionMode;\n /**\n * Выделение колонок по клику на шапку. Ctrl/Cmd — добавить/убрать колонку,\n * Shift — диапазон колонок. Клик по иконкам сортировки/фильтрации в шапке\n * выделение НЕ вызывает. Поддерживает copy/paste по выделенным колонкам.\n * @default true\n */\n enableColumnSelection?: boolean;\n /**\n * Выделение строк по клику/драгу на колонке нумерации (`rowMarkers`).\n * Ctrl/Cmd — несмежный выбор отдельных строк, драг — смежный диапазон.\n * Поддерживает copy/paste по выделенным строкам. Требует включённой колонки\n * нумерации (`rowMarkers`). При `false` клик по нумерации ничего не выделяет.\n * @default true\n */\n enableRowSelection?: boolean;\n /**\n * Выделение всей таблицы кликом по «нулевой» ячейке — шапке колонки нумерации\n * (левый верхний угол). Выделяет все строки данных по всем колонкам одним\n * диапазоном; поддерживает copy/paste. Требует включённой колонки нумерации\n * (`rowMarkers`) и активного `mode` (≠ `disabled`).\n * @default true\n */\n enableSelectAll?: boolean;\n /**\n * Внешний (controlled) контроль НАТИВНОГО выделения (ячейки/диапазон/смежные\n * строки и колонки). `state` — кортеж `[value, setter]` как у `selecting.state`.\n * Сброс: `setter({ current: undefined, rows: empty, columns: empty })`.\n * Несмежный Ctrl-выбор колонок/строк (own-state) сюда не входит — он внутренний.\n */\n state?: [GridSelection, React.Dispatch<React.SetStateAction<GridSelection>>];\n};\n```\n\n## RowGetStatesProps\n\nАргумент функции `rowGetStates` — позволяет полностью переопределить поведение чекбоксов для каждой строки.\n\n```typescript\ntype RowGetStatesProps<RowType, RowIdType> = {\n /**\n * просчитанное по умолчанию значение наличия чекбокса у строки\n */\n isHaveCheckboxCalculated: boolean;\n /**\n * просчитанное по умолчанию значение checked у строки\n */\n isRowSelectedCalculated: boolean;\n /**\n * просчитанное по умолчанию значение indeterminate у строки\n */\n isIndeterminateCalculated: boolean;\n /**\n * просчитанное по умолчанию значение disabled у строки\n */\n isRowSelectionDisabled: boolean;\n\n rowKeyGetter: RowKeyGetter<RowType, RowIdType>;\n row: RowType;\n /**\n * Все строки таблицы в плоском виде с информацией об уровне и родительской строке\n */\n flattenedRowsMap: Map<\n RowIdType,\n RowType & {\n level?: number;\n parent?: RowType | null | undefined;\n }\n >;\n /**\n * стейт всех выбранных строк (Set)\n */\n selectedRows: ReadonlySet<RowIdType>;\n /**\n * сеттер стейта всех выбранных строк\n */\n setSelectedRows: React.Dispatch<React.SetStateAction<ReadonlySet<RowIdType>>>;\n /**\n * уровень вложенности текущей строки\n */\n level: number;\n /**\n * родительская строка для текущей строки\n */\n parent: RowType | null;\n /**\n * хендлер для получения детальных данных о дочерних строках текущей строки\n */\n getRowChildrenInfo: () => ChildrenInfo<RowType, RowIdType>;\n rowShowCheckbox: RowShowCheckbox<RowType> | undefined;\n rowCheckboxDisabled: RowCheckboxDisabled<RowType> | undefined;\n};\n```\n\n## RowGetStatesReturnType\n\nВозвращаемое значение `rowGetStates`.\n\n```typescript\ntype RowGetStatesReturnType<RowType, RowIdType> = {\n /**\n * состояние checked, которое будет окончательным. Если не передано, то будет взято из расчетов по умолчанию\n */\n checked?: boolean | null;\n /**\n * состояние indeterminate, которое будет окончательным. Если не передано, то будет взято из расчетов по умолчанию\n */\n indeterminate?: boolean | null;\n /**\n * состояние showCheckbox, которое будет окончательным. Если не передано, то будет взято из расчетов по умолчанию\n */\n showCheckbox?: boolean | null;\n /**\n * состояние checkboxDisabled, которое будет окончательным. Если не передано, то будет взято из расчетов по умолчанию\n */\n checkboxDisabled?: boolean | null;\n /**\n * onChange у чекбокса, который будет окончательным. Если не передан, то будет взят из расчетов по умолчанию\n */\n onChange?:\n | ((p: {\n allParentsMap: Map<RowIdType, RowType>;\n isRowInLevels: (row: RowType) => boolean;\n defaultSetter: () => void;\n getRowParentsInfo: () => {\n all: RowType[];\n getShouldBeSelectedInfo: (\n actualSelecteds: ReadonlySet<RowIdType>,\n ) => {\n shouldBeSelected: RowIdType[];\n shouldNotBeSelected: RowIdType[];\n };\n };\n }) => void)\n | null;\n};\n```\n\n## ChildrenInfo\n\nИнформация о дочерних строках, доступная через `getRowChildrenInfo()`.\n\n```typescript\ntype ChildrenInfo<RowType, RowIdType> = {\n /**\n * все дочерние строки\n */\n all: RowType[];\n /**\n * все дочерние строки, которые disabled\n */\n disabled: RowIdType[];\n /**\n * все дочерние строки, которые НЕ disabled\n */\n notDisabled: RowIdType[];\n /**\n * все дочерние строки, которые НЕ disabled и НЕ скрыты через rowShowCheckbox\n */\n notDisabledAndNotHidden: RowIdType[];\n /**\n * все дочерние строки, которые НЕ disabled и НЕ скрыты через rowShowCheckbox все выбраны\n */\n notDisabledAndNotHiddenAreSelected: boolean;\n /**\n * все дочерние строки, которые скрыты через rowShowCheckbox\n */\n hidden: RowIdType[];\n /**\n * все дочерние строки, которые НЕ скрыты через rowShowCheckbox\n */\n notHidden: RowIdType[];\n /**\n * все дочерние строки, которые selected (уже выбраны, у которых чекбокс проставлен)\n */\n selected: RowIdType[];\n /**\n * все дочерние строки, которые НЕ selected (не выбраны, у которых чекбокс НЕ проставлен)\n */\n notSelected: RowIdType[];\n /**\n * есть ли хоть одна дочерная строка, которая выбрана (у которой чекбокс проставлен)\n */\n someChildrenIsSelected: boolean;\n};\n```",
54981
+ "summary": "*tableConfig.selecting.summaryCounterMaxCount**",
54982
+ "docs": "# SelectingRow — ограничение счётчика (99+)\n\n**tableConfig.selecting.summaryCounterMaxCount**\n\nОграничивает максимальное отображаемое число в счётчике выбранных строк — и в шапке\nтаблицы, и в панели массовых действий. Если выбрано больше — счётчик показывает «N+».\n\nНе ограничивает само выделение (выбрать можно сколько угодно), влияет только на\nотображение числа.\n\n## Использование\n\n```tsx\n<TableCanvas\n tableConfig={{\n selecting: {\n state: selectingRowState,\n rowKeyGetter: (r) => r.id,\n // при > 99 выбранных счётчик покажет «99+»\n summaryCounterMaxCount: 99,\n },\n }}\n columnConfig={columns}\n rows={rows}\n/>\n```\n\n## Поведение\n\n- `selectedCount <= summaryCounterMaxCount` — показывается точное число.\n- `selectedCount > summaryCounterMaxCount` — показывается `«summaryCounterMaxCount+»`\n (например, `99+`).\n- Поле опционально: без него счётчик показывает точное число без ограничения.\n\n> Типы SelectingRow — [SelectingRow API](?path=/docs/локальные-компоненты-tablecanvas-selectingrow-api--docs)\n\n# SelectingRow — ручная настройка выбора строк\n\nТонкая настройка выбора строк через `tableConfig.selecting`: управление тем, у каких\nстрок показывать чекбокс (`rowShowCheckbox`), какие дизейблить (`rowCheckboxDisabled`),\nа также кастомизация summary-чекбокса в шапке через `summaryChecked`.\n\n> Типы SelectingRow — [SelectingRow API](?path=/docs/локальные-компоненты-tablecanvas-selectingrow-api--docs)\n\n# SelectingRow + SubRows + InfinityScroll\n\nВыбор строк в древовидной таблице (`subRows`) с бесконечной подгрузкой.\n\nКомбинация `tableConfig.selecting` с `tableConfig.subRows` и бесконечным скроллом:\nвыбор сохраняется по мере подгрузки новых строк.\n\n> Типы SelectingRow — [SelectingRow API](?path=/docs/локальные-компоненты-tablecanvas-selectingrow-api--docs)\n\n# Selecting Row\n\n**tableConfig.selecting**\n\nВыбор строк таблицы с помощью чекбоксов.\n\n## Ключевые особенности\n\n- Управляемое состояние через `ReadonlySet<string | number>`\n- Кнопка переключения видимости в control block (`showInControl: true`)\n- Контроль на уровне строк: `rowCheckboxDisabled`, `rowShowCheckbox`\n- Поддержка иерархических таблиц через `selectingRules.levels`\n- Кастомизация summary-чекбокса через `summaryChecked`\n- Ограничение числа в счётчике выбранных — `summaryCounterMaxCount` (при превышении показывает «N+», например `99+`). См. [Ограничение счётчика (99+)](?path=/docs/локальные-компоненты-tablecanvas-selectingrow-countermaxcount--docs)\n\n## Особенности\n\n- `rowKeyGetter` должен возвращать уникальный идентификатор строки\n- В иерархических таблицах `selectingRules.levels` определяет, на каких уровнях доступен выбор\n- `rowGetStates` позволяет полностью переопределить логику чекбоксов (checked, indeterminate, disabled)\n- Accent-кнопки в mass action panel всегда видимы при компрессии\n\n> Подробнее о типах и пропсах — [Selecting API](?path=/docs/локальные-компоненты-tablecanvas-selecting-api--docs)\n\n# SelectingRow + RowsGrouping\n\nПример кастомного выбора строк в группированной таблице.\n\nКомбинация `tableConfig.selecting` и `tableConfig.rowsGrouping` с `columnConfig.rowsGrouping`.\n\n> Типы SelectingRow — [SelectingRow API](?path=/docs/локальные-компоненты-tablecanvas-selectingrow-api--docs)\n\n> Типы RowsGrouping — [RowsGrouping API](?path=/docs/локальные-компоненты-tablecanvas-rowsgrouping-api--docs)\n\n# SelectingRow + SubRows\n\nВыбор строк в древовидной таблице с вложенными строками (`tableConfig.subRows`).\n\n`selectingRules.levels` определяет, на каких уровнях вложенности доступен выбор.\n\n> Типы SelectingRow — [SelectingRow API](?path=/docs/локальные-компоненты-tablecanvas-selectingrow-api--docs)",
54983
+ "apiDocs": "# SelectingRow API\n\n## SelectingRowConfig\n\nКонфиг чекбоксного выбора строк (`tableConfig.selecting`).\n\n```typescript\ntype SelectingRowConfig<RowType, RowIdType extends string | number> = {\n /**\n * showDefault - состояние, отвечающее за то, видно ли по дефолту чекбоксы.\n */\n showDefault?: boolean;\n /**\n * showState - состояние, отвечающее за то, видны ли чекбоксы.\n */\n showState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n /**\n * showInControl - состояние, отвечающее за то, добавлять ли выбор строк как фичу, которую можно скрывать и раскрывать в правой части контролблока.\n */\n showInControl?: boolean;\n /**\n * selectingRules - пропс, отвечающий за кастомизацию логики выбора строк.\n */\n selectingRules?: {\n // TODO доработать логику\n // changeableOfRowWithoutCheckbox?: boolean;\n // changeableDisabledRow?: boolean;\n /**\n * levels - логика активации чекбоксов у строк с определенным уровнем вложенности.\n */\n levels?: number | 'all' | number[] | ((lvl: number) => boolean);\n };\n disableSummaryCheckboxInHeader?: boolean;\n hideSummaryCheckboxInHeader?: boolean;\n /**\n * hideSummaryCheckbox - в островке массовых действий\n */\n hideSummaryCheckbox?: boolean;\n /**\n * summaryCounterMaxCount - максимальное отображаемое число в счётчике выбранных\n * строк (в шапке и в панели массовых действий). Если выбрано больше — счётчик\n * показывает «N+» (например, при значении 99 и 5000 выбранных отобразится «99+»).\n * Не ограничивает само выделение, влияет только на отображение.\n */\n summaryCounterMaxCount?: number;\n /**\n * summaryChecked - пропс, отвечающий за логику состояния checked у итогового чекбокса в левой части контролблока.\n */\n summaryChecked?: {\n checked: boolean | SummaryCheckedFunc<RowType, boolean>;\n indeterminate:\n | boolean\n | SummaryCheckedFunc<RowType, boolean, { checkedAll: boolean }>;\n getCountOfChecked: SummaryCheckedFunc<RowType, number>;\n onChange: SummaryCheckedFunc<\n RowType,\n void,\n {\n checkedAll: boolean;\n clearButtonClicked?: boolean;\n setSelectedRowsIds: React.Dispatch<\n React.SetStateAction<ReadonlySet<string | number>>\n >;\n }\n >;\n };\n\n /**\n * summaryCheckedUncontrolled - пропс отвечающий за колбеки в неконтролируемом режиме\n */\n summaryCheckedUncontrolled?: {\n onChange: (event: ChangeEvent<HTMLInputElement>) => void;\n };\n\n /**\n * rowShowCheckbox - пропс, отвечающий за то, будет ли у конкретной строки отрендерен чекбокс.\n */\n rowShowCheckbox?: RowShowCheckbox<RowType>;\n /**\n * rowCheckboxDisabled - пропс, отвечающий за то, будет ли у конкретной строки чекбокс задизейблен.\n */\n rowCheckboxDisabled?: RowCheckboxDisabled<RowType>;\n /**\n * Функция для переопределения checked, indeterminate для каждой строки.\n * Что будет возвращено функцией в объекте, то будет переопределено.\n */\n rowGetStates?: (\n p: RowGetStatesProps<RowType, RowIdType>,\n ) => RowGetStatesReturnType<RowType, RowIdType> | null;\n groupedRow?: {\n /**\n * Функция для переопределения checked, indeterminate, showCheckbox, checkboxDisabled для группированных строк.\n * Что будет возвращено функцией в объекте, то будет переопределено.\n */\n getStates: (p: {\n checkedCalculated: boolean;\n indeterminateCalculated: boolean;\n row: GroupRow<RowType>;\n selectedRows: ReadonlySet<string | number>;\n selectedChildCount: number;\n childCount: number;\n }) => {\n checked?: boolean | null;\n indeterminate?: boolean | null;\n showCheckbox?: boolean | null;\n checkboxDisabled?: boolean | null;\n } | null;\n onChange?: (p: {\n row: GroupRow<RowType>;\n\n setSelectedRows: React.Dispatch<\n React.SetStateAction<ReadonlySet<string | number>>\n >;\n checked: boolean;\n indeterminate: boolean;\n checkboxDisabled: boolean;\n showCheckbox: boolean;\n defaultSetter: () => void;\n }) => void;\n };\n};\n```\n\n## RowGetStatesProps\n\nАргумент функции `rowGetStates` — позволяет полностью переопределить поведение чекбоксов для каждой строки.\n\n```typescript\ntype RowGetStatesProps<RowType, RowIdType> = {\n /**\n * просчитанное по умолчанию значение наличия чекбокса у строки\n */\n isHaveCheckboxCalculated: boolean;\n /**\n * просчитанное по умолчанию значение checked у строки\n */\n isRowSelectedCalculated: boolean;\n /**\n * просчитанное по умолчанию значение indeterminate у строки\n */\n isIndeterminateCalculated: boolean;\n /**\n * просчитанное по умолчанию значение disabled у строки\n */\n isRowSelectionDisabled: boolean;\n\n rowKeyGetter: RowKeyGetter<RowType, RowIdType>;\n row: RowType;\n /**\n * Все строки таблицы в плоском виде с информацией об уровне и родительской строке\n */\n flattenedRowsMap: Map<\n RowIdType,\n RowType & {\n level?: number;\n parent?: RowType | null | undefined;\n }\n >;\n /**\n * стейт всех выбранных строк (Set)\n */\n selectedRows: ReadonlySet<RowIdType>;\n /**\n * сеттер стейта всех выбранных строк\n */\n setSelectedRows: React.Dispatch<React.SetStateAction<ReadonlySet<RowIdType>>>;\n /**\n * уровень вложенности текущей строки\n */\n level: number;\n /**\n * родительская строка для текущей строки\n */\n parent: RowType | null;\n /**\n * хендлер для получения детальных данных о дочерних строках текущей строки\n */\n getRowChildrenInfo: () => ChildrenInfo<RowType, RowIdType>;\n rowShowCheckbox: RowShowCheckbox<RowType> | undefined;\n rowCheckboxDisabled: RowCheckboxDisabled<RowType> | undefined;\n};\n```\n\n## RowGetStatesReturnType\n\nВозвращаемое значение `rowGetStates`.\n\n```typescript\ntype RowGetStatesReturnType<RowType, RowIdType> = {\n /**\n * состояние checked, которое будет окончательным. Если не передано, то будет взято из расчетов по умолчанию\n */\n checked?: boolean | null;\n /**\n * состояние indeterminate, которое будет окончательным. Если не передано, то будет взято из расчетов по умолчанию\n */\n indeterminate?: boolean | null;\n /**\n * состояние showCheckbox, которое будет окончательным. Если не передано, то будет взято из расчетов по умолчанию\n */\n showCheckbox?: boolean | null;\n /**\n * состояние checkboxDisabled, которое будет окончательным. Если не передано, то будет взято из расчетов по умолчанию\n */\n checkboxDisabled?: boolean | null;\n /**\n * onChange у чекбокса, который будет окончательным. Если не передан, то будет взят из расчетов по умолчанию\n */\n onChange?:\n | ((p: {\n allParentsMap: Map<RowIdType, RowType>;\n isRowInLevels: (row: RowType) => boolean;\n defaultSetter: () => void;\n getRowParentsInfo: () => {\n all: RowType[];\n getShouldBeSelectedInfo: (\n actualSelecteds: ReadonlySet<RowIdType>,\n ) => {\n shouldBeSelected: RowIdType[];\n shouldNotBeSelected: RowIdType[];\n };\n };\n }) => void)\n | null;\n};\n```\n\n## ChildrenInfo\n\nИнформация о дочерних строках, доступная через `getRowChildrenInfo()`.\n\n```typescript\ntype ChildrenInfo<RowType, RowIdType> = {\n /**\n * все дочерние строки\n */\n all: RowType[];\n /**\n * все дочерние строки, которые disabled\n */\n disabled: RowIdType[];\n /**\n * все дочерние строки, которые НЕ disabled\n */\n notDisabled: RowIdType[];\n /**\n * все дочерние строки, которые НЕ disabled и НЕ скрыты через rowShowCheckbox\n */\n notDisabledAndNotHidden: RowIdType[];\n /**\n * все дочерние строки, которые НЕ disabled и НЕ скрыты через rowShowCheckbox все выбраны\n */\n notDisabledAndNotHiddenAreSelected: boolean;\n /**\n * все дочерние строки, которые скрыты через rowShowCheckbox\n */\n hidden: RowIdType[];\n /**\n * все дочерние строки, которые НЕ скрыты через rowShowCheckbox\n */\n notHidden: RowIdType[];\n /**\n * все дочерние строки, которые selected (уже выбраны, у которых чекбокс проставлен)\n */\n selected: RowIdType[];\n /**\n * все дочерние строки, которые НЕ selected (не выбраны, у которых чекбокс НЕ проставлен)\n */\n notSelected: RowIdType[];\n /**\n * есть ли хоть одна дочерная строка, которая выбрана (у которой чекбокс проставлен)\n */\n someChildrenIsSelected: boolean;\n};\n```",
54441
54984
  "api": [
54442
54985
  {
54443
54986
  "typeName": "SelectingRowConfig",
54444
- "source": "type SelectingRowConfig<RowType, RowIdType extends string | number> = {\n /**\n * showDefault - состояние, отвечающее за то, видно ли по дефолту чекбоксы.\n */\n showDefault?: boolean;\n /**\n * showState - состояние, отвечающее за то, видны ли чекбоксы.\n */\n showState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n /**\n * showInControl - состояние, отвечающее за то, добавлять ли выбор строк как фичу, которую можно скрывать и раскрывать в правой части контролблока.\n */\n showInControl?: boolean;\n /**\n * selectingRules - пропс, отвечающий за кастомизацию логики выбора строк.\n */\n selectingRules?: {\n // TODO доработать логику\n // changeableOfRowWithoutCheckbox?: boolean;\n // changeableDisabledRow?: boolean;\n /**\n * levels - логика активации чекбоксов у строк с определенным уровнем вложенности.\n */\n levels?: number | 'all' | number[] | ((lvl: number) => boolean);\n };\n disableSummaryCheckboxInHeader?: boolean;\n hideSummaryCheckboxInHeader?: boolean;\n /**\n * hideSummaryCheckbox - в островке массовых действий\n */\n hideSummaryCheckbox?: boolean;\n /**\n * summaryChecked - пропс, отвечающий за логику состояния checked у итогового чекбокса в левой части контролблока.\n */\n summaryChecked?: {\n checked: boolean | SummaryCheckedFunc<RowType, boolean>;\n indeterminate:\n | boolean\n | SummaryCheckedFunc<RowType, boolean, { checkedAll: boolean }>;\n getCountOfChecked: SummaryCheckedFunc<RowType, number>;\n onChange: SummaryCheckedFunc<\n RowType,\n void,\n {\n checkedAll: boolean;\n clearButtonClicked?: boolean;\n setSelectedRowsIds: React.Dispatch<\n React.SetStateAction<ReadonlySet<string | number>>\n >;\n }\n >;\n };\n\n /**\n * summaryCheckedUncontrolled - пропс отвечающий за колбеки в неконтролируемом режиме\n */\n summaryCheckedUncontrolled?: {\n onChange: (event: ChangeEvent<HTMLInputElement>) => void;\n };\n\n /**\n * rowShowCheckbox - пропс, отвечающий за то, будет ли у конкретной строки отрендерен чекбокс.\n */\n rowShowCheckbox?: RowShowCheckbox<RowType>;\n /**\n * rowCheckboxDisabled - пропс, отвечающий за то, будет ли у конкретной строки чекбокс задизейблен.\n */\n rowCheckboxDisabled?: RowCheckboxDisabled<RowType>;\n /**\n * Функция для переопределения checked, indeterminate для каждой строки.\n * Что будет возвращено функцией в объекте, то будет переопределено.\n */\n rowGetStates?: (\n p: RowGetStatesProps<RowType, RowIdType>,\n ) => RowGetStatesReturnType<RowType, RowIdType> | null;\n groupedRow?: {\n /**\n * Функция для переопределения checked, indeterminate, showCheckbox, checkboxDisabled для группированных строк.\n * Что будет возвращено функцией в объекте, то будет переопределено.\n */\n getStates: (p: {\n checkedCalculated: boolean;\n indeterminateCalculated: boolean;\n row: GroupRow<RowType>;\n selectedRows: ReadonlySet<string | number>;\n selectedChildCount: number;\n childCount: number;\n }) => {\n checked?: boolean | null;\n indeterminate?: boolean | null;\n showCheckbox?: boolean | null;\n checkboxDisabled?: boolean | null;\n } | null;\n onChange?: (p: {\n row: GroupRow<RowType>;\n\n setSelectedRows: React.Dispatch<\n React.SetStateAction<ReadonlySet<string | number>>\n >;\n checked: boolean;\n indeterminate: boolean;\n checkboxDisabled: boolean;\n showCheckbox: boolean;\n defaultSetter: () => void;\n }) => void;\n };\n};"
54445
- },
54446
- {
54447
- "typeName": "CellsSelectionConfig",
54448
- "source": "type CellsSelectionConfig = {\n /**\n * Режим фактического выделения ячеек (нативный glide selection). По нему\n * работают copy/paste, рамка, fill-handle и затемнение шапки/нумерации.\n * @default \"range-cell\"\n */\n mode?: CellsSelectionMode;\n /**\n * Выделение колонок по клику на шапку. Ctrl/Cmd — добавить/убрать колонку,\n * Shift — диапазон колонок. Клик по иконкам сортировки/фильтрации в шапке\n * выделение НЕ вызывает. Поддерживает copy/paste по выделенным колонкам.\n * @default true\n */\n enableColumnSelection?: boolean;\n /**\n * Выделение строк по клику/драгу на колонке нумерации (`rowMarkers`).\n * Ctrl/Cmd — несмежный выбор отдельных строк, драг — смежный диапазон.\n * Поддерживает copy/paste по выделенным строкам. Требует включённой колонки\n * нумерации (`rowMarkers`). При `false` клик по нумерации ничего не выделяет.\n * @default true\n */\n enableRowSelection?: boolean;\n /**\n * Выделение всей таблицы кликом по «нулевой» ячейке — шапке колонки нумерации\n * (левый верхний угол). Выделяет все строки данных по всем колонкам одним\n * диапазоном; поддерживает copy/paste. Требует включённой колонки нумерации\n * (`rowMarkers`) и активного `mode` (≠ `disabled`).\n * @default true\n */\n enableSelectAll?: boolean;\n /**\n * Внешний (controlled) контроль НАТИВНОГО выделения (ячейки/диапазон/смежные\n * строки и колонки). `state` — кортеж `[value, setter]` как у `selecting.state`.\n * Сброс: `setter({ current: undefined, rows: empty, columns: empty })`.\n * Несмежный Ctrl-выбор колонок/строк (own-state) сюда не входит — он внутренний.\n */\n state?: [GridSelection, React.Dispatch<React.SetStateAction<GridSelection>>];\n};"
54987
+ "source": "type SelectingRowConfig<RowType, RowIdType extends string | number> = {\n /**\n * showDefault - состояние, отвечающее за то, видно ли по дефолту чекбоксы.\n */\n showDefault?: boolean;\n /**\n * showState - состояние, отвечающее за то, видны ли чекбоксы.\n */\n showState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n /**\n * showInControl - состояние, отвечающее за то, добавлять ли выбор строк как фичу, которую можно скрывать и раскрывать в правой части контролблока.\n */\n showInControl?: boolean;\n /**\n * selectingRules - пропс, отвечающий за кастомизацию логики выбора строк.\n */\n selectingRules?: {\n // TODO доработать логику\n // changeableOfRowWithoutCheckbox?: boolean;\n // changeableDisabledRow?: boolean;\n /**\n * levels - логика активации чекбоксов у строк с определенным уровнем вложенности.\n */\n levels?: number | 'all' | number[] | ((lvl: number) => boolean);\n };\n disableSummaryCheckboxInHeader?: boolean;\n hideSummaryCheckboxInHeader?: boolean;\n /**\n * hideSummaryCheckbox - в островке массовых действий\n */\n hideSummaryCheckbox?: boolean;\n /**\n * summaryCounterMaxCount - максимальное отображаемое число в счётчике выбранных\n * строк (в шапке и в панели массовых действий). Если выбрано больше — счётчик\n * показывает «N+» (например, при значении 99 и 5000 выбранных отобразится «99+»).\n * Не ограничивает само выделение, влияет только на отображение.\n */\n summaryCounterMaxCount?: number;\n /**\n * summaryChecked - пропс, отвечающий за логику состояния checked у итогового чекбокса в левой части контролблока.\n */\n summaryChecked?: {\n checked: boolean | SummaryCheckedFunc<RowType, boolean>;\n indeterminate:\n | boolean\n | SummaryCheckedFunc<RowType, boolean, { checkedAll: boolean }>;\n getCountOfChecked: SummaryCheckedFunc<RowType, number>;\n onChange: SummaryCheckedFunc<\n RowType,\n void,\n {\n checkedAll: boolean;\n clearButtonClicked?: boolean;\n setSelectedRowsIds: React.Dispatch<\n React.SetStateAction<ReadonlySet<string | number>>\n >;\n }\n >;\n };\n\n /**\n * summaryCheckedUncontrolled - пропс отвечающий за колбеки в неконтролируемом режиме\n */\n summaryCheckedUncontrolled?: {\n onChange: (event: ChangeEvent<HTMLInputElement>) => void;\n };\n\n /**\n * rowShowCheckbox - пропс, отвечающий за то, будет ли у конкретной строки отрендерен чекбокс.\n */\n rowShowCheckbox?: RowShowCheckbox<RowType>;\n /**\n * rowCheckboxDisabled - пропс, отвечающий за то, будет ли у конкретной строки чекбокс задизейблен.\n */\n rowCheckboxDisabled?: RowCheckboxDisabled<RowType>;\n /**\n * Функция для переопределения checked, indeterminate для каждой строки.\n * Что будет возвращено функцией в объекте, то будет переопределено.\n */\n rowGetStates?: (\n p: RowGetStatesProps<RowType, RowIdType>,\n ) => RowGetStatesReturnType<RowType, RowIdType> | null;\n groupedRow?: {\n /**\n * Функция для переопределения checked, indeterminate, showCheckbox, checkboxDisabled для группированных строк.\n * Что будет возвращено функцией в объекте, то будет переопределено.\n */\n getStates: (p: {\n checkedCalculated: boolean;\n indeterminateCalculated: boolean;\n row: GroupRow<RowType>;\n selectedRows: ReadonlySet<string | number>;\n selectedChildCount: number;\n childCount: number;\n }) => {\n checked?: boolean | null;\n indeterminate?: boolean | null;\n showCheckbox?: boolean | null;\n checkboxDisabled?: boolean | null;\n } | null;\n onChange?: (p: {\n row: GroupRow<RowType>;\n\n setSelectedRows: React.Dispatch<\n React.SetStateAction<ReadonlySet<string | number>>\n >;\n checked: boolean;\n indeterminate: boolean;\n checkboxDisabled: boolean;\n showCheckbox: boolean;\n defaultSetter: () => void;\n }) => void;\n };\n};"
54449
54988
  },
54450
54989
  {
54451
54990
  "typeName": "RowGetStatesProps",
@@ -54461,6 +55000,12 @@
54461
55000
  }
54462
55001
  ],
54463
55002
  "stories": [
55003
+ {
55004
+ "exportName": "CounterMaxCount",
55005
+ "displayName": "Ограничение счётчика (99+)",
55006
+ "type": "full-code",
55007
+ "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n const [rows] = useState(() => createRows()); // 200 строк\n\n const columns = useMemo<readonly ColumnConfig<Row>[]>(\n () => [\n { key: 'id', name: 'ID' },\n { key: 'task', name: 'Задача' },\n { key: 'priority', name: 'Приоритет' },\n ],\n [],\n );\n\n // Изначально выбираем все строки, чтобы счётчик сразу показал «99+».\n const selectingRowStateAndSetter = useState(\n (): ReadonlySet<string | number> => new Set(rows.map((r) => r.id)),\n );\n\n return (\n <TableCanvas\n tableConfig={{\n containerStyle: { height: '700px' },\n selecting: {\n state: selectingRowStateAndSetter,\n rowKeyGetter: (r) => r.id,\n // 👇 то, ради чего пример: при > 99 выбранных счётчик покажет «99+»\n summaryCounterMaxCount: 99,\n },\n controlBlock: {\n massActionPanel: {\n buttons: [\n {\n type: 'button',\n text: 'Экспорт',\n view: 'secondary',\n onClick: () => alert('Экспорт выбранных строк'),\n },\n ],\n },\n },\n }}\n columnConfig={columns}\n rows={rows}\n />\n );\n }"
55008
+ },
54464
55009
  {
54465
55010
  "exportName": "CustomRowSelection",
54466
55011
  "displayName": "Независимый выбор строк в иерархии",
@@ -55718,11 +56263,11 @@
55718
56263
  "legacy": true,
55719
56264
  "summary": "*tableConfig.selecting**",
55720
56265
  "docs": "# Selecting Row\n\n**tableConfig.selecting**\n\nВыбор строк таблицы с помощью чекбоксов.\n\n## Ключевые особенности\n\n- Управляемое состояние через `ReadonlySet<string | number>`\n- Кнопка переключения видимости в control block (`showInControl: true`)\n- Контроль на уровне строк: `rowCheckboxDisabled`, `rowShowCheckbox`\n- Поддержка иерархических таблиц через `selectingRules.levels`\n- Кастомизация summary-чекбокса через `summaryChecked`\n- Полное переопределение логики через `rowGetStates`\n\n## Особенности\n\n- `rowKeyGetter` должен возвращать уникальный идентификатор строки\n- В иерархических таблицах `selectingRules.levels` определяет, на каких уровнях доступен выбор\n- `summaryChecked` позволяет кастомизировать логику «Выбрать все»\n- `rowGetStates` переопределяет `checked`, `indeterminate`, `showCheckbox`, `checkboxDisabled` для каждой строки\n\n> Подробнее о типах и пропсах — [Selecting Row API](?path=/docs/локальные-компоненты-table-selectingrow-api--docs)\n\n# TableRowsGrouping\n\n## Ключевые особенности\n\n- Выбор строк в группированной таблице\n- Кастомная логика checked/indeterminate для групп\n- Совместная работа selecting и rowsGrouping\n\n**tableConfig.selecting**\n\n**tableConfig.rowsGrouping**\n\n**columnConfig.rowsGrouping**\n\nОписание типов - в разделах [Selecting API](?path=/docs/локальные-компоненты-table-selectingrow-api--docs) и [RowsGrouping API](?path=/docs/локальные-компоненты-table-rowsgrouping-api--docs).",
55721
- "apiDocs": "# Selecting Row API\n\n## SelectingRowConfig\n\n```typescript\ntype SelectingRowConfig<\n RowType,\n RowIdType extends string | number = string | number,\n> = {\n rowKeyGetter: (row: RowType) => RowIdType;\n /**\n * showDefault - состояние, отвечающее за то, видно ли по дефолту чекбоксы.\n */\n showDefault?: boolean;\n /**\n * showState - состояние, отвечающее за то, видны ли чекбоксы.\n */\n showState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n /**\n * showInControl - состояние, отвечающее за то, добавлять ли выбор строк как фичу, которую можно скрывать и раскрывать в правой части контролблока.\n */\n showInControl?: boolean;\n /**\n * selectingRules - пропс, отвечающий за кастомизацию логики выбора строк.\n */\n selectingRules?: {\n /**\n * изменять ли скрытые строки при клике на чекбокс-ы родительских строк\n * @default true\n */\n // changeableOfRowWithoutCheckbox?: boolean;\n /**\n * изменять ли задизейбленные строки при клике на чекбокс-ы родительских строк\n * @default true\n */\n // changeableDisabledRow?: boolean;\n /**\n * levels - логика активации чекбоксов у строк с определенным уровнем вложенности.\n */\n levels?: number | 'all' | number[] | ((lvl: number) => boolean);\n };\n disableSummaryCheckboxInHeader?: boolean;\n hideSummaryCheckboxInHeader?: boolean;\n /**\n * hideSummaryCheckbox - в островке массовых действий\n */\n hideSummaryCheckbox?: boolean;\n /**\n * summaryChecked - пропс, отвечающий за логику состояния checked у итогового чекбокса в левой части контролблока.\n */\n summaryChecked?: {\n checked: boolean | SummaryCheckedFunc<RowType, boolean>;\n indeterminate:\n | boolean\n | SummaryCheckedFunc<RowType, boolean, { checkedAll: boolean }>;\n getCountOfChecked: SummaryCheckedFunc<RowType, number>;\n onChange: SummaryCheckedFunc<\n RowType,\n void,\n {\n checkedAll: boolean;\n clearButtonClicked?: boolean;\n setSelectedRowsIds: React.Dispatch<\n React.SetStateAction<ReadonlySet<string | number>>\n >;\n }\n >;\n };\n\n /**\n * summaryCheckedUncontrolled - пропс отвечающий за колбеки в неконтролируемом режиме\n */\n summaryCheckedUncontrolled?: {\n onChange: (event: ChangeEvent<HTMLInputElement>) => void;\n };\n\n /**\n * rowShowCheckbox - пропс, отвечающий за то, будет ли у конкретной строки отрендерен чекбокс.\n */\n rowShowCheckbox?: RowShowCheckbox<RowType>;\n /**\n * rowCheckboxDisabled - пропс, отвечающий за то, будет ли у конкретной строки чекбокс задизейблен.\n */\n rowCheckboxDisabled?: RowCheckboxDisabled<RowType>;\n\n /**\n * Функция для переопределения checked, indeterminate для каждой строки.\n * Что будет возвращено функцией в объекте, то будет переопределено.\n */\n rowGetStates?: (\n p: RowGetStatesProps<RowType, RowIdType>,\n ) => RowGetStatesReturnType<RowType, RowIdType> | null;\n\n groupedRow?: {\n /**\n * Функция для переопределения checked, indeterminate, showCheckbox, checkboxDisabled для группированных строк.\n * Что будет возвращено функцией в объекте, то будет переопределено.\n */\n getStates: (p: {\n checkedCalculated: boolean;\n indeterminateCalculated: boolean;\n row: GroupRow<RowType>;\n selectedRows: ReadonlySet<string | number>;\n selectedChildCount: number;\n childCount: number;\n }) => {\n checked?: boolean | null;\n indeterminate?: boolean | null;\n showCheckbox?: boolean | null;\n checkboxDisabled?: boolean | null;\n } | null;\n onChange?: (p: {\n row: GroupRow<RowType>;\n\n setSelectedRows: React.Dispatch<\n React.SetStateAction<ReadonlySet<string | number>>\n >;\n checked: boolean;\n indeterminate: boolean;\n checkboxDisabled: boolean;\n showCheckbox: boolean;\n defaultSetter: () => void;\n }) => void;\n };\n};\n```\n\n## ChildrenInfo\n\n```typescript\ntype ChildrenInfo<RowType, RowIdType> = {\n /**\n * все дочерние строки\n */\n all: RowType[];\n /**\n * все дочерние строки, которые disabled\n */\n disabled: RowIdType[];\n /**\n * все дочерние строки, которые НЕ disabled\n */\n notDisabled: RowIdType[];\n /**\n * все дочерние строки, которые НЕ disabled и НЕ скрыты через rowShowCheckbox\n */\n notDisabledAndNotHidden: RowIdType[];\n /**\n * все дочерние строки, которые НЕ disabled и НЕ скрыты через rowShowCheckbox все выбраны\n */\n notDisabledAndNotHiddenAreSelected: boolean;\n /**\n * все дочерние строки, которые скрыты через rowShowCheckbox\n */\n hidden: RowIdType[];\n /**\n * все дочерние строки, которые НЕ скрыты через rowShowCheckbox\n */\n notHidden: RowIdType[];\n /**\n * все дочерние строки, которые selected (уже выбраны, у которых чекбокс проставлен)\n */\n selected: RowIdType[];\n /**\n * все дочерние строки, которые НЕ selected (не выбраны, у которых чекбокс НЕ проставлен)\n */\n notSelected: RowIdType[];\n /**\n * есть ли хоть одна дочерная строка, которая выбрана (у которой чекбокс проставлен)\n */\n someChildrenIsSelected: boolean;\n};\n```\n\n## RowShowCheckbox\n\n```typescript\ntype RowShowCheckbox<RowType> = (\n row: RowType,\n lvl?: number,\n parent?: RowType | null,\n) => boolean;\n```\n\n## RowCheckboxDisabled\n\n```typescript\ntype RowCheckboxDisabled<RowType> = (\n row: RowType,\n lvl?: number,\n parent?: RowType | null,\n) => boolean;\n```\n\n## RowGetStatesProps\n\n```typescript\ntype RowGetStatesProps<RowType, RowIdType> = {\n /**\n * просчитанное по умолчанию значение наличия чекбокса у строки\n */\n isHaveCheckboxCalculated: boolean;\n /**\n * просчитанное по умолчанию значение checked у строки\n */\n isRowSelectedCalculated: boolean;\n /**\n * просчитанное по умолчанию значение indeterminate у строки\n */\n isIndeterminateCalculated: boolean;\n /**\n * просчитанное по умолчанию значение disabled у строки\n */\n isRowSelectionDisabled: boolean;\n\n rowKeyGetter: RowKeyGetter<RowType, RowIdType>;\n row: RowType;\n /**\n * Все строки таблицы в плоском виде с информацией об уровне и родительской строке\n */\n flattenedRowsMap: Map<\n RowIdType,\n RowType & {\n level?: number;\n parent?: RowType | null | undefined;\n }\n >;\n /**\n * стейт всех выбранных строк (Set)\n */\n selectedRows: ReadonlySet<RowIdType>;\n /**\n * сеттер стейта всех выбранных строк\n */\n setSelectedRows: React.Dispatch<React.SetStateAction<ReadonlySet<RowIdType>>>;\n /**\n * уровень вложенности текущей строки\n */\n level: number;\n /**\n * родительская строка для текущей строки\n */\n parent: RowType | null;\n /**\n * хендлер для получения детальных данных о дочерних строках текущей строки\n */\n getRowChildrenInfo: () => ChildrenInfo<RowType, RowIdType>;\n rowShowCheckbox: RowShowCheckbox<RowType> | undefined;\n rowCheckboxDisabled: RowCheckboxDisabled<RowType> | undefined;\n};\n```\n\n## RowGetStatesReturnType\n\n```typescript\ntype RowGetStatesReturnType<RowType, RowIdType> = {\n /**\n * состояние checked, которое будет окончательным. Если не передано, то будет взято из расчетов по умолчанию\n */\n checked?: boolean | null;\n /**\n * состояние indeterminate, которое будет окончательным. Если не передано, то будет взято из расчетов по умолчанию\n */\n indeterminate?: boolean | null;\n /**\n * состояние showCheckbox, которое будет окончательным. Если не передано, то будет взято из расчетов по умолчанию\n */\n showCheckbox?: boolean | null;\n /**\n * состояние checkboxDisabled, которое будет окончательным. Если не передано, то будет взято из расчетов по умолчанию\n */\n checkboxDisabled?: boolean | null;\n /**\n * onChange у чекбокса, который будет окончательным. Если не передан, то будет взят из расчетов по умолчанию\n */\n onChange?:\n | ((p: {\n allParentsMap: Map<RowIdType, RowType>;\n isRowInLevels: (row: RowType) => boolean;\n defaultSetter: () => void;\n getRowParentsInfo: () => {\n all: RowType[];\n getShouldBeSelectedInfo: (\n actualSelecteds: ReadonlySet<RowIdType>,\n ) => {\n shouldBeSelected: RowIdType[];\n shouldNotBeSelected: RowIdType[];\n };\n };\n }) => void)\n | null;\n};\n```",
56266
+ "apiDocs": "# Selecting Row API\n\n## SelectingRowConfig\n\n```typescript\ntype SelectingRowConfig<\n RowType,\n RowIdType extends string | number = string | number,\n> = {\n rowKeyGetter: (row: RowType) => RowIdType;\n /**\n * showDefault - состояние, отвечающее за то, видно ли по дефолту чекбоксы.\n */\n showDefault?: boolean;\n /**\n * showState - состояние, отвечающее за то, видны ли чекбоксы.\n */\n showState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n /**\n * showInControl - состояние, отвечающее за то, добавлять ли выбор строк как фичу, которую можно скрывать и раскрывать в правой части контролблока.\n */\n showInControl?: boolean;\n /**\n * selectingRules - пропс, отвечающий за кастомизацию логики выбора строк.\n */\n selectingRules?: {\n /**\n * изменять ли скрытые строки при клике на чекбокс-ы родительских строк\n * @default true\n */\n // changeableOfRowWithoutCheckbox?: boolean;\n /**\n * изменять ли задизейбленные строки при клике на чекбокс-ы родительских строк\n * @default true\n */\n // changeableDisabledRow?: boolean;\n /**\n * levels - логика активации чекбоксов у строк с определенным уровнем вложенности.\n */\n levels?: number | 'all' | number[] | ((lvl: number) => boolean);\n };\n disableSummaryCheckboxInHeader?: boolean;\n hideSummaryCheckboxInHeader?: boolean;\n /**\n * hideSummaryCheckbox - в островке массовых действий\n */\n hideSummaryCheckbox?: boolean;\n /**\n * summaryCounterMaxCount - максимальное отображаемое число в счётчике выбранных\n * строк (в шапке и в панели массовых действий). Если выбрано больше — счётчик\n * показывает «N+» (например, при значении 99 и 5000 выбранных отобразится «99+»).\n * Не ограничивает само выделение, влияет только на отображение.\n */\n summaryCounterMaxCount?: number;\n /**\n * summaryChecked - пропс, отвечающий за логику состояния checked у итогового чекбокса в левой части контролблока.\n */\n summaryChecked?: {\n checked: boolean | SummaryCheckedFunc<RowType, boolean>;\n indeterminate:\n | boolean\n | SummaryCheckedFunc<RowType, boolean, { checkedAll: boolean }>;\n getCountOfChecked: SummaryCheckedFunc<RowType, number>;\n onChange: SummaryCheckedFunc<\n RowType,\n void,\n {\n checkedAll: boolean;\n clearButtonClicked?: boolean;\n setSelectedRowsIds: React.Dispatch<\n React.SetStateAction<ReadonlySet<string | number>>\n >;\n }\n >;\n };\n\n /**\n * summaryCheckedUncontrolled - пропс отвечающий за колбеки в неконтролируемом режиме\n */\n summaryCheckedUncontrolled?: {\n onChange: (event: ChangeEvent<HTMLInputElement>) => void;\n };\n\n /**\n * rowShowCheckbox - пропс, отвечающий за то, будет ли у конкретной строки отрендерен чекбокс.\n */\n rowShowCheckbox?: RowShowCheckbox<RowType>;\n /**\n * rowCheckboxDisabled - пропс, отвечающий за то, будет ли у конкретной строки чекбокс задизейблен.\n */\n rowCheckboxDisabled?: RowCheckboxDisabled<RowType>;\n\n /**\n * Функция для переопределения checked, indeterminate для каждой строки.\n * Что будет возвращено функцией в объекте, то будет переопределено.\n */\n rowGetStates?: (\n p: RowGetStatesProps<RowType, RowIdType>,\n ) => RowGetStatesReturnType<RowType, RowIdType> | null;\n\n groupedRow?: {\n /**\n * Функция для переопределения checked, indeterminate, showCheckbox, checkboxDisabled для группированных строк.\n * Что будет возвращено функцией в объекте, то будет переопределено.\n */\n getStates: (p: {\n checkedCalculated: boolean;\n indeterminateCalculated: boolean;\n row: GroupRow<RowType>;\n selectedRows: ReadonlySet<string | number>;\n selectedChildCount: number;\n childCount: number;\n }) => {\n checked?: boolean | null;\n indeterminate?: boolean | null;\n showCheckbox?: boolean | null;\n checkboxDisabled?: boolean | null;\n } | null;\n onChange?: (p: {\n row: GroupRow<RowType>;\n\n setSelectedRows: React.Dispatch<\n React.SetStateAction<ReadonlySet<string | number>>\n >;\n checked: boolean;\n indeterminate: boolean;\n checkboxDisabled: boolean;\n showCheckbox: boolean;\n defaultSetter: () => void;\n }) => void;\n };\n};\n```\n\n## ChildrenInfo\n\n```typescript\ntype ChildrenInfo<RowType, RowIdType> = {\n /**\n * все дочерние строки\n */\n all: RowType[];\n /**\n * все дочерние строки, которые disabled\n */\n disabled: RowIdType[];\n /**\n * все дочерние строки, которые НЕ disabled\n */\n notDisabled: RowIdType[];\n /**\n * все дочерние строки, которые НЕ disabled и НЕ скрыты через rowShowCheckbox\n */\n notDisabledAndNotHidden: RowIdType[];\n /**\n * все дочерние строки, которые НЕ disabled и НЕ скрыты через rowShowCheckbox все выбраны\n */\n notDisabledAndNotHiddenAreSelected: boolean;\n /**\n * все дочерние строки, которые скрыты через rowShowCheckbox\n */\n hidden: RowIdType[];\n /**\n * все дочерние строки, которые НЕ скрыты через rowShowCheckbox\n */\n notHidden: RowIdType[];\n /**\n * все дочерние строки, которые selected (уже выбраны, у которых чекбокс проставлен)\n */\n selected: RowIdType[];\n /**\n * все дочерние строки, которые НЕ selected (не выбраны, у которых чекбокс НЕ проставлен)\n */\n notSelected: RowIdType[];\n /**\n * есть ли хоть одна дочерная строка, которая выбрана (у которой чекбокс проставлен)\n */\n someChildrenIsSelected: boolean;\n};\n```\n\n## RowShowCheckbox\n\n```typescript\ntype RowShowCheckbox<RowType> = (\n row: RowType,\n lvl?: number,\n parent?: RowType | null,\n) => boolean;\n```\n\n## RowCheckboxDisabled\n\n```typescript\ntype RowCheckboxDisabled<RowType> = (\n row: RowType,\n lvl?: number,\n parent?: RowType | null,\n) => boolean;\n```\n\n## RowGetStatesProps\n\n```typescript\ntype RowGetStatesProps<RowType, RowIdType> = {\n /**\n * просчитанное по умолчанию значение наличия чекбокса у строки\n */\n isHaveCheckboxCalculated: boolean;\n /**\n * просчитанное по умолчанию значение checked у строки\n */\n isRowSelectedCalculated: boolean;\n /**\n * просчитанное по умолчанию значение indeterminate у строки\n */\n isIndeterminateCalculated: boolean;\n /**\n * просчитанное по умолчанию значение disabled у строки\n */\n isRowSelectionDisabled: boolean;\n\n rowKeyGetter: RowKeyGetter<RowType, RowIdType>;\n row: RowType;\n /**\n * Все строки таблицы в плоском виде с информацией об уровне и родительской строке\n */\n flattenedRowsMap: Map<\n RowIdType,\n RowType & {\n level?: number;\n parent?: RowType | null | undefined;\n }\n >;\n /**\n * стейт всех выбранных строк (Set)\n */\n selectedRows: ReadonlySet<RowIdType>;\n /**\n * сеттер стейта всех выбранных строк\n */\n setSelectedRows: React.Dispatch<React.SetStateAction<ReadonlySet<RowIdType>>>;\n /**\n * уровень вложенности текущей строки\n */\n level: number;\n /**\n * родительская строка для текущей строки\n */\n parent: RowType | null;\n /**\n * хендлер для получения детальных данных о дочерних строках текущей строки\n */\n getRowChildrenInfo: () => ChildrenInfo<RowType, RowIdType>;\n rowShowCheckbox: RowShowCheckbox<RowType> | undefined;\n rowCheckboxDisabled: RowCheckboxDisabled<RowType> | undefined;\n};\n```\n\n## RowGetStatesReturnType\n\n```typescript\ntype RowGetStatesReturnType<RowType, RowIdType> = {\n /**\n * состояние checked, которое будет окончательным. Если не передано, то будет взято из расчетов по умолчанию\n */\n checked?: boolean | null;\n /**\n * состояние indeterminate, которое будет окончательным. Если не передано, то будет взято из расчетов по умолчанию\n */\n indeterminate?: boolean | null;\n /**\n * состояние showCheckbox, которое будет окончательным. Если не передано, то будет взято из расчетов по умолчанию\n */\n showCheckbox?: boolean | null;\n /**\n * состояние checkboxDisabled, которое будет окончательным. Если не передано, то будет взято из расчетов по умолчанию\n */\n checkboxDisabled?: boolean | null;\n /**\n * onChange у чекбокса, который будет окончательным. Если не передан, то будет взят из расчетов по умолчанию\n */\n onChange?:\n | ((p: {\n allParentsMap: Map<RowIdType, RowType>;\n isRowInLevels: (row: RowType) => boolean;\n defaultSetter: () => void;\n getRowParentsInfo: () => {\n all: RowType[];\n getShouldBeSelectedInfo: (\n actualSelecteds: ReadonlySet<RowIdType>,\n ) => {\n shouldBeSelected: RowIdType[];\n shouldNotBeSelected: RowIdType[];\n };\n };\n }) => void)\n | null;\n};\n```",
55722
56267
  "api": [
55723
56268
  {
55724
56269
  "typeName": "SelectingRowConfig",
55725
- "source": "type SelectingRowConfig<\n RowType,\n RowIdType extends string | number = string | number,\n> = {\n rowKeyGetter: (row: RowType) => RowIdType;\n /**\n * showDefault - состояние, отвечающее за то, видно ли по дефолту чекбоксы.\n */\n showDefault?: boolean;\n /**\n * showState - состояние, отвечающее за то, видны ли чекбоксы.\n */\n showState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n /**\n * showInControl - состояние, отвечающее за то, добавлять ли выбор строк как фичу, которую можно скрывать и раскрывать в правой части контролблока.\n */\n showInControl?: boolean;\n /**\n * selectingRules - пропс, отвечающий за кастомизацию логики выбора строк.\n */\n selectingRules?: {\n /**\n * изменять ли скрытые строки при клике на чекбокс-ы родительских строк\n * @default true\n */\n // changeableOfRowWithoutCheckbox?: boolean;\n /**\n * изменять ли задизейбленные строки при клике на чекбокс-ы родительских строк\n * @default true\n */\n // changeableDisabledRow?: boolean;\n /**\n * levels - логика активации чекбоксов у строк с определенным уровнем вложенности.\n */\n levels?: number | 'all' | number[] | ((lvl: number) => boolean);\n };\n disableSummaryCheckboxInHeader?: boolean;\n hideSummaryCheckboxInHeader?: boolean;\n /**\n * hideSummaryCheckbox - в островке массовых действий\n */\n hideSummaryCheckbox?: boolean;\n /**\n * summaryChecked - пропс, отвечающий за логику состояния checked у итогового чекбокса в левой части контролблока.\n */\n summaryChecked?: {\n checked: boolean | SummaryCheckedFunc<RowType, boolean>;\n indeterminate:\n | boolean\n | SummaryCheckedFunc<RowType, boolean, { checkedAll: boolean }>;\n getCountOfChecked: SummaryCheckedFunc<RowType, number>;\n onChange: SummaryCheckedFunc<\n RowType,\n void,\n {\n checkedAll: boolean;\n clearButtonClicked?: boolean;\n setSelectedRowsIds: React.Dispatch<\n React.SetStateAction<ReadonlySet<string | number>>\n >;\n }\n >;\n };\n\n /**\n * summaryCheckedUncontrolled - пропс отвечающий за колбеки в неконтролируемом режиме\n */\n summaryCheckedUncontrolled?: {\n onChange: (event: ChangeEvent<HTMLInputElement>) => void;\n };\n\n /**\n * rowShowCheckbox - пропс, отвечающий за то, будет ли у конкретной строки отрендерен чекбокс.\n */\n rowShowCheckbox?: RowShowCheckbox<RowType>;\n /**\n * rowCheckboxDisabled - пропс, отвечающий за то, будет ли у конкретной строки чекбокс задизейблен.\n */\n rowCheckboxDisabled?: RowCheckboxDisabled<RowType>;\n\n /**\n * Функция для переопределения checked, indeterminate для каждой строки.\n * Что будет возвращено функцией в объекте, то будет переопределено.\n */\n rowGetStates?: (\n p: RowGetStatesProps<RowType, RowIdType>,\n ) => RowGetStatesReturnType<RowType, RowIdType> | null;\n\n groupedRow?: {\n /**\n * Функция для переопределения checked, indeterminate, showCheckbox, checkboxDisabled для группированных строк.\n * Что будет возвращено функцией в объекте, то будет переопределено.\n */\n getStates: (p: {\n checkedCalculated: boolean;\n indeterminateCalculated: boolean;\n row: GroupRow<RowType>;\n selectedRows: ReadonlySet<string | number>;\n selectedChildCount: number;\n childCount: number;\n }) => {\n checked?: boolean | null;\n indeterminate?: boolean | null;\n showCheckbox?: boolean | null;\n checkboxDisabled?: boolean | null;\n } | null;\n onChange?: (p: {\n row: GroupRow<RowType>;\n\n setSelectedRows: React.Dispatch<\n React.SetStateAction<ReadonlySet<string | number>>\n >;\n checked: boolean;\n indeterminate: boolean;\n checkboxDisabled: boolean;\n showCheckbox: boolean;\n defaultSetter: () => void;\n }) => void;\n };\n};"
56270
+ "source": "type SelectingRowConfig<\n RowType,\n RowIdType extends string | number = string | number,\n> = {\n rowKeyGetter: (row: RowType) => RowIdType;\n /**\n * showDefault - состояние, отвечающее за то, видно ли по дефолту чекбоксы.\n */\n showDefault?: boolean;\n /**\n * showState - состояние, отвечающее за то, видны ли чекбоксы.\n */\n showState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n /**\n * showInControl - состояние, отвечающее за то, добавлять ли выбор строк как фичу, которую можно скрывать и раскрывать в правой части контролблока.\n */\n showInControl?: boolean;\n /**\n * selectingRules - пропс, отвечающий за кастомизацию логики выбора строк.\n */\n selectingRules?: {\n /**\n * изменять ли скрытые строки при клике на чекбокс-ы родительских строк\n * @default true\n */\n // changeableOfRowWithoutCheckbox?: boolean;\n /**\n * изменять ли задизейбленные строки при клике на чекбокс-ы родительских строк\n * @default true\n */\n // changeableDisabledRow?: boolean;\n /**\n * levels - логика активации чекбоксов у строк с определенным уровнем вложенности.\n */\n levels?: number | 'all' | number[] | ((lvl: number) => boolean);\n };\n disableSummaryCheckboxInHeader?: boolean;\n hideSummaryCheckboxInHeader?: boolean;\n /**\n * hideSummaryCheckbox - в островке массовых действий\n */\n hideSummaryCheckbox?: boolean;\n /**\n * summaryCounterMaxCount - максимальное отображаемое число в счётчике выбранных\n * строк (в шапке и в панели массовых действий). Если выбрано больше — счётчик\n * показывает «N+» (например, при значении 99 и 5000 выбранных отобразится «99+»).\n * Не ограничивает само выделение, влияет только на отображение.\n */\n summaryCounterMaxCount?: number;\n /**\n * summaryChecked - пропс, отвечающий за логику состояния checked у итогового чекбокса в левой части контролблока.\n */\n summaryChecked?: {\n checked: boolean | SummaryCheckedFunc<RowType, boolean>;\n indeterminate:\n | boolean\n | SummaryCheckedFunc<RowType, boolean, { checkedAll: boolean }>;\n getCountOfChecked: SummaryCheckedFunc<RowType, number>;\n onChange: SummaryCheckedFunc<\n RowType,\n void,\n {\n checkedAll: boolean;\n clearButtonClicked?: boolean;\n setSelectedRowsIds: React.Dispatch<\n React.SetStateAction<ReadonlySet<string | number>>\n >;\n }\n >;\n };\n\n /**\n * summaryCheckedUncontrolled - пропс отвечающий за колбеки в неконтролируемом режиме\n */\n summaryCheckedUncontrolled?: {\n onChange: (event: ChangeEvent<HTMLInputElement>) => void;\n };\n\n /**\n * rowShowCheckbox - пропс, отвечающий за то, будет ли у конкретной строки отрендерен чекбокс.\n */\n rowShowCheckbox?: RowShowCheckbox<RowType>;\n /**\n * rowCheckboxDisabled - пропс, отвечающий за то, будет ли у конкретной строки чекбокс задизейблен.\n */\n rowCheckboxDisabled?: RowCheckboxDisabled<RowType>;\n\n /**\n * Функция для переопределения checked, indeterminate для каждой строки.\n * Что будет возвращено функцией в объекте, то будет переопределено.\n */\n rowGetStates?: (\n p: RowGetStatesProps<RowType, RowIdType>,\n ) => RowGetStatesReturnType<RowType, RowIdType> | null;\n\n groupedRow?: {\n /**\n * Функция для переопределения checked, indeterminate, showCheckbox, checkboxDisabled для группированных строк.\n * Что будет возвращено функцией в объекте, то будет переопределено.\n */\n getStates: (p: {\n checkedCalculated: boolean;\n indeterminateCalculated: boolean;\n row: GroupRow<RowType>;\n selectedRows: ReadonlySet<string | number>;\n selectedChildCount: number;\n childCount: number;\n }) => {\n checked?: boolean | null;\n indeterminate?: boolean | null;\n showCheckbox?: boolean | null;\n checkboxDisabled?: boolean | null;\n } | null;\n onChange?: (p: {\n row: GroupRow<RowType>;\n\n setSelectedRows: React.Dispatch<\n React.SetStateAction<ReadonlySet<string | number>>\n >;\n checked: boolean;\n indeterminate: boolean;\n checkboxDisabled: boolean;\n showCheckbox: boolean;\n defaultSetter: () => void;\n }) => void;\n };\n};"
55726
56271
  },
55727
56272
  {
55728
56273
  "typeName": "ChildrenInfo",
@@ -56272,6 +56817,13 @@
56272
56817
  "importNotice": "Тип \"CanvasInteractionOptions\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
56273
56818
  "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/core/canvasInteraction.ts"
56274
56819
  },
56820
+ "CanvasAvatarItem": {
56821
+ "name": "CanvasAvatarItem",
56822
+ "definition": "export interface CanvasAvatarItem extends AvatarContent {\n /** Стабильный уникальный идентификатор участника внутри группы; используется в ID canvas-ноды. */\n id: string;\n /** Подсказка при наведении на этого участника. */\n tooltip?: CanvasNodeTooltipConfig;\n}",
56823
+ "importPath": "@daisforge/ui/components/TableCanvas",
56824
+ "importStatement": "import { CanvasAvatarItem } from '@daisforge/ui/components/TableCanvas';",
56825
+ "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/primitives/CanvasAvatarGroup.ts"
56826
+ },
56275
56827
  "ButtonIcon": {
56276
56828
  "name": "ButtonIcon",
56277
56829
  "definition": "export type ButtonIcon =\n | string\n | HTMLImageElement\n | ReactElement\n | null\n | undefined;",
@@ -57212,7 +57764,7 @@
57212
57764
  },
57213
57765
  "TableCanvas.TableConfig": {
57214
57766
  "name": "TableConfig",
57215
- "definition": "export type TableConfig<\n RowType extends ObjectForExtending,\n SummaryRowType,\n RowIdType extends string | number,\n FilterStateType extends ObjectForExtending,\n // SubRowType\n> = {\n /**\n * Группировка колонок (многоуровневая шапка через `columnConfig.children`):\n * объединение пустых ячеек шапки (`squashEmptyCells`, по умолчанию включено) и\n * дефолт выравнивания в объединённых ячейках (`squashedHeaderAlign`).\n */\n columnsGrouping?: ColumnsGroupingConfig;\n /**\n * Подсветка активной сущности в canvas-таблице.\n * @deprecated Значения `'cell'`/`'range-cell'` устарели — используйте\n * `cellsSelection.mode`. Актуальны `'row'` (подсветка строки) и `'disabled'`.\n */\n highlightActiveType?: HighlightActiveType;\n /**\n * Единый конфиг выделения ячеек: режим (`mode`), оси\n * (`enableColumnSelection`/`enableRowSelection`/`enableSelectAll`) и controlled\n * (`state`). См. {@link CellsSelectionConfig}.\n */\n cellsSelection?: CellsSelectionConfig;\n /**\n * Подсвеченная строка (`highlightActiveType='row'`).\n * `state` (опционально) — controlled-кортеж `[value, setter]`: задан — значением\n * владеешь снаружи (сброс `setter(undefined)`); не задан — таблица крутит\n * подсветку внутренним стейтом, а `onChange` всё равно срабатывает (подписка\n * без владения значением).\n */\n highlightActiveRow?: {\n state?: [\n number | undefined,\n React.Dispatch<React.SetStateAction<number | undefined>>,\n ];\n /**\n * Колбэк смены подсвеченной строки: отдаёт её флэт-индекс и сам объект\n * строки (`rows[index]`). Позволяет открывать данные подсвеченной строки\n * (например, в SplitView) без `onCellClicked`.\n */\n onChange?: (params: {\n index: number | undefined;\n row: RowType | undefined;\n }) => void;\n };\n /**\n * Эффекты при наведении (hover)\n * `row` — подсветка строки под курсором.\n * Независимая визуальная ось: селектинг (`cellsSelection`) и `highlightActiveType='row'`\n * рисуются ПОВЕРХ hover-подсветки и визуально перекрывают её (hover\n * «остаётся под ними» и снова виден после сброса выделения).\n *\n * `{ row: true }` — включить с цветами из темы;\n * `{ row: { color: '#F7F9FB' } }` — переопределить цвет data-ячеек.\n * @default undefined (выключено)\n */\n hoverEffects?: HoverEffectsConfig;\n /**\n * Включает компенсацию тонких canvas-линий при browser zoom ниже 100%, когда devicePixelRatio меньше 1.\n * Влияет только на grid/header/sticky hairline borders.\n * @default false\n */\n enableLowDprHairline?: boolean;\n /**\n * Управление рамками (линиями) таблицы: включение и выключение.\n *\n * Уровни, от слабого к сильному: общие настройки (vertical, horizontal),\n * затем колонка (getVerticalBorder) и строка (getHorizontalBorder), затем\n * ячейка (getCellBorder).\n *\n * `vertical: false` и `horizontal: false` убирают все вертикальные или\n * горизонтальные линии тела. `getCellBorder` включает и выключает стороны\n * рамки конкретной ячейки; при его использовании линии рисуются с разбивкой\n * по ячейкам.\n */\n borders?: BordersConfig<RowType>;\n /**\n * rowSize - размеры строк таблицы\n */\n rowSize?: Prettify<RowSize>;\n /**\n * rowHeight - размер высоты строк таблицы\n */\n rowHeight?: Maybe<number | RowHeightFunc<RowType>>;\n /**\n * sorting - активация сортировки. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={sorting: {sortingState}}\n *\n * columnConfig=[{sortingType: 'numberSort'}]\n */\n sorting?: {\n state: [\n readonly SortColumn[],\n React.Dispatch<React.SetStateAction<readonly SortColumn[]>>,\n ];\n /**\n * manualSorting - пропс, активирующий ручную-кастомную (или на стороне бэкенда) сортировку\n */\n manualSorting?: boolean;\n };\n /** @deprecated Свойство view не используется и будет удалено в следующей мажорной версии. */\n view?: View;\n /**\n * filtering - активация фильтрации. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={filtering: {stateAndSetter, ...}}\n *\n * columnConfig=[{filtering: {...}}]\n */\n filtering?: FilteringConfig<FilterStateType>;\n /**\n * Сворачивание / разворачивание таблицы\n */\n collapsing?: TableCollapseConfig;\n /**\n * selecting - активация выбора строк. Условие активации - это наличие данного свойства.\n * Есть поддержка выбора строк с многоуровневой вложенностью.\n *\n * Пример:\n *\n *```jsx\n * import { Table } from '@daisforge/ui';\n *\n * <Table\n * tableConfig={{selecting: {stateAndSetter, rowKeyGetter}}}\n * {...rest}\n * />\n * ```\n */\n selecting?: {\n state: [\n ReadonlySet<RowIdType>,\n React.Dispatch<React.SetStateAction<ReadonlySet<RowIdType>>>,\n ];\n rowKeyGetter: (row: RowType) => RowIdType;\n } & Prettify<SelectingRowConfig<RowType, RowIdType>> & {\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n controlBlock?: {\n domMetadata?: DomMetadata;\n };\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам RightSidebar\n */\n sidebar?: {\n domMetadata?: DomMetadata;\n };\n };\n /**\n * editing - активация редактирования. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={editing: {onRowsChange, rowKeyGetter}}\n *\n * columnConfig=[{editingCell: {...}}]\n */\n editing?: EditingConfig<RowType, RowIdType, SummaryRowType>;\n\n /**\n * cellTransfer — конфигурация копирования, вставки и fill handle.\n * По умолчанию копирование (Ctrl+C) работает в режиме редактирования.\n * Данные копируются в формате TSV (tab-separated values), совместимом с Excel.\n *\n * Пример:\n *\n * tableConfig={{ cellTransfer: { enabled: true,…",
57767
+ "definition": "export type TableConfig<\n RowType extends ObjectForExtending,\n SummaryRowType,\n RowIdType extends string | number,\n FilterStateType extends ObjectForExtending,\n // SubRowType\n> = {\n /**\n * Группировка колонок (многоуровневая шапка через `columnConfig.children`):\n * объединение пустых ячеек шапки (`squashEmptyCells`, по умолчанию включено) и\n * дефолт выравнивания в объединённых ячейках (`squashedHeaderAlign`).\n */\n columnsGrouping?: ColumnsGroupingConfig;\n /**\n * Подсветка активной сущности в canvas-таблице.\n * @deprecated Значения `'cell'`/`'range-cell'` устарели — используйте\n * `cellsSelection.mode`. Актуальны `'row'` (подсветка строки) и `'disabled'`.\n */\n highlightActiveType?: HighlightActiveType;\n /**\n * Единый конфиг выделения ячеек: режим (`mode`), оси\n * (`enableColumnSelection`/`enableRowSelection`/`enableSelectAll`) и controlled\n * (`state`). См. {@link CellsSelectionConfig}.\n */\n cellsSelection?: CellsSelectionConfig;\n /**\n * Подсвеченная строка (`highlightActiveType='row'`).\n * `state` (опционально) — controlled-кортеж `[value, setter]`: задан — значением\n * владеешь снаружи (сброс `setter(undefined)`); не задан — таблица крутит\n * подсветку внутренним стейтом, а `onChange` всё равно срабатывает (подписка\n * без владения значением).\n */\n highlightActiveRow?: {\n state?: [\n number | undefined,\n React.Dispatch<React.SetStateAction<number | undefined>>,\n ];\n /**\n * Колбэк смены подсвеченной строки: отдаёт её флэт-индекс и сам объект\n * строки (`rows[index]`). Позволяет открывать данные подсвеченной строки\n * (например, в SplitView) без `onCellClicked`.\n */\n onChange?: (params: {\n index: number | undefined;\n row: RowType | undefined;\n }) => void;\n };\n /**\n * Эффекты при наведении (hover)\n * `row` — подсветка строки под курсором.\n * Независимая визуальная ось: селектинг (`cellsSelection`) и `highlightActiveType='row'`\n * рисуются ПОВЕРХ hover-подсветки и визуально перекрывают её (hover\n * «остаётся под ними» и снова виден после сброса выделения).\n *\n * `{ row: true }` — включить с цветами из темы;\n * `{ row: { color: '#F7F9FB' } }` — переопределить цвет data-ячеек.\n * @default undefined (выключено)\n */\n hoverEffects?: HoverEffectsConfig;\n /**\n * Включает компенсацию тонких canvas-линий при browser zoom ниже 100%, когда devicePixelRatio меньше 1.\n * Влияет только на grid/header/sticky hairline borders.\n * @default false\n */\n enableLowDprHairline?: boolean;\n /**\n * Управление рамками (линиями) таблицы: включение и выключение.\n *\n * Уровни, от слабого к сильному: общие настройки (vertical, horizontal),\n * затем колонка (getVerticalBorder) и строка (getHorizontalBorder), затем\n * ячейка (getCellBorder).\n *\n * `vertical: false` и `horizontal: false` убирают все вертикальные или\n * горизонтальные линии тела. `getCellBorder` включает и выключает стороны\n * рамки конкретной ячейки; при его использовании линии рисуются с разбивкой\n * по ячейкам.\n */\n borders?: BordersConfig<RowType>;\n /**\n * rowSize - размеры строк таблицы\n */\n rowSize?: Prettify<RowSize>;\n /**\n * rowHeight - размер высоты строк таблицы\n */\n rowHeight?: Maybe<number | RowHeightFunc<RowType>>;\n /**\n * headerRowHeight - высота одного ряда шапки (в px). По умолчанию 33.\n *\n * Значение применяется к КАЖДОМУ уровню шапки: как к листовому (нижнему) ряду\n * колонок, так и к каждому уровню объединённых (групповых) заголовков. Поэтому\n * при N уровнях группировки итоговая высота шапки = headerRowHeight * (1 + N).\n * Например, headerRowHeight={50} при 2 уровнях групп даст шапку 50 + 50 + 50 = 150px.\n */\n headerRowHeight?: Maybe<number>;\n /**\n * sorting - активация сортировки. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={sorting: {sortingState}}\n *\n * columnConfig=[{sortingType: 'numberSort'}]\n */\n sorting?: {\n state: [\n readonly SortColumn[],\n React.Dispatch<React.SetStateAction<readonly SortColumn[]>>,\n ];\n /**\n * manualSorting - пропс, активирующий ручную-кастомную (или на стороне бэкенда) сортировку\n */\n manualSorting?: boolean;\n };\n /** @deprecated Свойство view не используется и будет удалено в следующей мажорной версии. */\n view?: View;\n /**\n * filtering - активация фильтрации. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={filtering: {stateAndSetter, ...}}\n *\n * columnConfig=[{filtering: {...}}]\n */\n filtering?: FilteringConfig<FilterStateType>;\n /**\n * Сворачивание / разворачивание таблицы\n */\n collapsing?: TableCollapseConfig;\n /**\n * selecting - активация выбора строк. Условие активации - это наличие данного свойства.\n * Есть поддержка выбора строк с многоуровневой вложенностью.\n *\n * Пример:\n *\n *```jsx\n * import { Table } from '@daisforge/ui';\n *\n * <Table\n * tableConfig={{selecting: {stateAndSetter, rowKeyGetter}}}\n * {...rest}\n * />\n * ```\n */\n selecting?: {\n state: [\n ReadonlySet<RowIdType>,\n React.Dispatch<React.SetStateAction<ReadonlySet<RowIdType>>>,\n ];\n rowKeyGetter: (row: RowType) => RowIdType;\n } & Prettify<SelectingRowConfig<RowType, RowIdType>> & {\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n */\n controlBlock?: {\n domMetadata?: DomMetadata;\n };\n /**\n * Метки для автоматизированного тестирования и аналитики\n * Добавляет data-атрибуты и CSS-классы к элементам RightSidebar\n */\n sidebar?: {\n domMetadata?: DomMetadata;\n };\n };\n /**\n * editing - активация редактирования. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig=…",
57216
57768
  "importPath": "@daisforge/ui/components/TableCanvas",
57217
57769
  "importStatement": "import { TableConfig } from '@daisforge/ui/components/TableCanvas';",
57218
57770
  "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/table-config.type.ts"
@@ -57240,7 +57792,7 @@
57240
57792
  },
57241
57793
  "CustomCellStyleNumberFormatProps": {
57242
57794
  "name": "CustomCellStyleNumberFormatProps",
57243
- "definition": "export type CustomCellStyleNumberFormatProps = {\n align?: 'left' | 'center' | 'right';\n autoFocusType: 'autoFocus' | 'autoFocusAndSelect' | 'none';\n} & CustomCellStyleProps;",
57795
+ "definition": "export type CustomCellStyleNumberFormatProps = {\n align?: 'left' | 'center' | 'right';\n /**\n * Поведение фокуса/каретки при открытии редактора:\n * - `autoFocus` — фокус, каретка в конец значения;\n * - `autoFocusAndSelect` — фокус и выделение всего значения (вход через\n * Enter/двойной клик — набор заменяет значение целиком);\n * - `autoFocusBeforeDecimals` — фокус, каретка в конец целой части (перед\n * дробной). Для входа «перезаписью»: после набранной цифры можно сразу\n * продолжать ввод, не попадая в нули дробной части. Длина дробной части\n * берётся из `decimalScale`/`fixedDecimalScale` и не зависит от символа\n * разделителя;\n * - `none` — фокусом/кареткой компонент не управляет.\n */\n autoFocusType:\n | 'autoFocus'\n | 'autoFocusAndSelect'\n | 'autoFocusBeforeDecimals'\n | 'none';\n} & CustomCellStyleProps;",
57244
57796
  "internal": true,
57245
57797
  "importNotice": "Тип \"CustomCellStyleNumberFormatProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
57246
57798
  "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-edit/types.ts"
@@ -57378,6 +57930,20 @@
57378
57930
  "importStatement": "import { CanvasEvent } from '@daisforge/ui/components/TableCanvas';",
57379
57931
  "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/core/CanvasNode.type.ts"
57380
57932
  },
57933
+ "CanvasAvatarOptions": {
57934
+ "name": "CanvasAvatarOptions",
57935
+ "definition": "export interface CanvasAvatarOptions extends AvatarContent {\n /** Размер аватара: s — 24, m — 36, l — 48, xxl — 88 px. По умолчанию s. */\n size?: AvatarSize;\n /** Тема таблицы с цветами и шрифтом; в JSX передаётся автоматически. */\n theme?: GlideThemeForRender;\n}",
57936
+ "internal": true,
57937
+ "importNotice": "Тип \"CanvasAvatarOptions\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
57938
+ "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/primitives/CanvasAvatar.ts"
57939
+ },
57940
+ "CanvasAvatarGroupOptions": {
57941
+ "name": "CanvasAvatarGroupOptions",
57942
+ "definition": "export interface CanvasAvatarGroupOptions\n extends Pick<CanvasAvatarOptions, 'size' | 'theme'> {\n /** Известные участники в порядке отображения; id должны быть уникальны внутри группы. */\n items: readonly CanvasAvatarItem[];\n /** Максимум видимых участников без учёта +N. По умолчанию 3, но не больше длины items. */\n visibleCount?: number;\n /** Общее число участников, включая ещё не загруженных. По умолчанию длина items; меньшие значения игнорируются. */\n totalCount?: number;\n /** Обработчик клика по видимому участнику. */\n onItemClick?: (args: AvatarGroupItemClick) => void;\n /** Обработчик клика по счётчику скрытых участников +N. */\n onOverflowClick?: (args: AvatarGroupOverflowClick) => void;\n /** Подсказка счётчика; по умолчанию текст +N. */\n overflowTooltip?: CanvasNodeTooltipConfig;\n}",
57943
+ "internal": true,
57944
+ "importNotice": "Тип \"CanvasAvatarGroupOptions\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
57945
+ "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/primitives/CanvasAvatarGroup.ts"
57946
+ },
57381
57947
  "BadgeView": {
57382
57948
  "name": "BadgeView",
57383
57949
  "definition": "export type BadgeView =\n | 'default'\n | 'accent'\n | 'positive'\n | 'warning'\n | 'negative'\n | 'dark'\n | 'light';",
@@ -58185,14 +58751,14 @@
58185
58751
  },
58186
58752
  "Table.SelectingRowConfig": {
58187
58753
  "name": "SelectingRowConfig",
58188
- "definition": "export type SelectingRowConfig<\n RowType,\n RowIdType extends string | number = string | number,\n> = {\n rowKeyGetter: (row: RowType) => RowIdType;\n /**\n * showDefault - состояние, отвечающее за то, видно ли по дефолту чекбоксы.\n */\n showDefault?: boolean;\n /**\n * showState - состояние, отвечающее за то, видны ли чекбоксы.\n */\n showState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n /**\n * showInControl - состояние, отвечающее за то, добавлять ли выбор строк как фичу, которую можно скрывать и раскрывать в правой части контролблока.\n */\n showInControl?: boolean;\n /**\n * selectingRules - пропс, отвечающий за кастомизацию логики выбора строк.\n */\n selectingRules?: {\n /**\n * изменять ли скрытые строки при клике на чекбокс-ы родительских строк\n * @default true\n */\n // changeableOfRowWithoutCheckbox?: boolean;\n /**\n * изменять ли задизейбленные строки при клике на чекбокс-ы родительских строк\n * @default true\n */\n // changeableDisabledRow?: boolean;\n /**\n * levels - логика активации чекбоксов у строк с определенным уровнем вложенности.\n */\n levels?: number | 'all' | number[] | ((lvl: number) => boolean);\n };\n disableSummaryCheckboxInHeader?: boolean;\n hideSummaryCheckboxInHeader?: boolean;\n /**\n * hideSummaryCheckbox - в островке массовых действий\n */\n hideSummaryCheckbox?: boolean;\n /**\n * summaryChecked - пропс, отвечающий за логику состояния checked у итогового чекбокса в левой части контролблока.\n */\n summaryChecked?: {\n checked: boolean | SummaryCheckedFunc<RowType, boolean>;\n indeterminate:\n | boolean\n | SummaryCheckedFunc<RowType, boolean, { checkedAll: boolean }>;\n getCountOfChecked: SummaryCheckedFunc<RowType, number>;\n onChange: SummaryCheckedFunc<\n RowType,\n void,\n {\n checkedAll: boolean;\n clearButtonClicked?: boolean;\n setSelectedRowsIds: React.Dispatch<\n React.SetStateAction<ReadonlySet<string | number>>\n >;\n }\n >;\n };\n\n /**\n * summaryCheckedUncontrolled - пропс отвечающий за колбеки в неконтролируемом режиме\n */\n summaryCheckedUncontrolled?: {\n onChange: (event: ChangeEvent<HTMLInputElement>) => void;\n };\n\n /**\n * rowShowCheckbox - пропс, отвечающий за то, будет ли у конкретной строки отрендерен чекбокс.\n */\n rowShowCheckbox?: RowShowCheckbox<RowType>;\n /**\n * rowCheckboxDisabled - пропс, отвечающий за то, будет ли у конкретной строки чекбокс задизейблен.\n */\n rowCheckboxDisabled?: RowCheckboxDisabled<RowType>;\n\n /**\n * Функция для переопределения checked, indeterminate для каждой строки.\n * Что будет возвращено функцией в объекте, то будет переопределено.\n */\n rowGetStates?: (\n p: RowGetStatesProps<RowType, RowIdType>,\n ) => RowGetStatesReturnType<RowType, RowIdType> | null;\n\n groupedRow?: {\n /**\n * Функция для переопределения checked, indeterminate, showCheckbox, checkboxDisabled для группированных строк.\n * Что будет возвращено функцией в объекте, то будет переопределено.\n */\n getStates: (p: {\n checkedCalculated: boolean;\n indeterminateCalculated: boolean;\n row: GroupRow<RowType>;\n selectedRows: ReadonlySet<string | number>;\n selectedChildCount: number;\n childCount: number;\n }) => {\n checked?: boolean | null;\n indeterminate?: boolean | null;\n showCheckbox?: boolean | null;\n checkboxDisabled?: boolean | null;\n } | null;\n onChange?: (p: {\n row: GroupRow<RowType>;\n\n setSelectedRows: React.Dispatch<\n React.SetStateAction<ReadonlySet<string | number>>\n >;\n checked: boolean;\n indeterminate: boolean;\n checkboxDisabled: boolean;\n showCheckbox: boolean;\n defaultSetter: () => void;\n }) => void;\n };\n};",
58754
+ "definition": "export type SelectingRowConfig<\n RowType,\n RowIdType extends string | number = string | number,\n> = {\n rowKeyGetter: (row: RowType) => RowIdType;\n /**\n * showDefault - состояние, отвечающее за то, видно ли по дефолту чекбоксы.\n */\n showDefault?: boolean;\n /**\n * showState - состояние, отвечающее за то, видны ли чекбоксы.\n */\n showState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n /**\n * showInControl - состояние, отвечающее за то, добавлять ли выбор строк как фичу, которую можно скрывать и раскрывать в правой части контролблока.\n */\n showInControl?: boolean;\n /**\n * selectingRules - пропс, отвечающий за кастомизацию логики выбора строк.\n */\n selectingRules?: {\n /**\n * изменять ли скрытые строки при клике на чекбокс-ы родительских строк\n * @default true\n */\n // changeableOfRowWithoutCheckbox?: boolean;\n /**\n * изменять ли задизейбленные строки при клике на чекбокс-ы родительских строк\n * @default true\n */\n // changeableDisabledRow?: boolean;\n /**\n * levels - логика активации чекбоксов у строк с определенным уровнем вложенности.\n */\n levels?: number | 'all' | number[] | ((lvl: number) => boolean);\n };\n disableSummaryCheckboxInHeader?: boolean;\n hideSummaryCheckboxInHeader?: boolean;\n /**\n * hideSummaryCheckbox - в островке массовых действий\n */\n hideSummaryCheckbox?: boolean;\n /**\n * summaryCounterMaxCount - максимальное отображаемое число в счётчике выбранных\n * строк (в шапке и в панели массовых действий). Если выбрано больше — счётчик\n * показывает «N+» (например, при значении 99 и 5000 выбранных отобразится «99+»).\n * Не ограничивает само выделение, влияет только на отображение.\n */\n summaryCounterMaxCount?: number;\n /**\n * summaryChecked - пропс, отвечающий за логику состояния checked у итогового чекбокса в левой части контролблока.\n */\n summaryChecked?: {\n checked: boolean | SummaryCheckedFunc<RowType, boolean>;\n indeterminate:\n | boolean\n | SummaryCheckedFunc<RowType, boolean, { checkedAll: boolean }>;\n getCountOfChecked: SummaryCheckedFunc<RowType, number>;\n onChange: SummaryCheckedFunc<\n RowType,\n void,\n {\n checkedAll: boolean;\n clearButtonClicked?: boolean;\n setSelectedRowsIds: React.Dispatch<\n React.SetStateAction<ReadonlySet<string | number>>\n >;\n }\n >;\n };\n\n /**\n * summaryCheckedUncontrolled - пропс отвечающий за колбеки в неконтролируемом режиме\n */\n summaryCheckedUncontrolled?: {\n onChange: (event: ChangeEvent<HTMLInputElement>) => void;\n };\n\n /**\n * rowShowCheckbox - пропс, отвечающий за то, будет ли у конкретной строки отрендерен чекбокс.\n */\n rowShowCheckbox?: RowShowCheckbox<RowType>;\n /**\n * rowCheckboxDisabled - пропс, отвечающий за то, будет ли у конкретной строки чекбокс задизейблен.\n */\n rowCheckboxDisabled?: RowCheckboxDisabled<RowType>;\n\n /**\n * Функция для переопределения checked, indeterminate для каждой строки.\n * Что будет возвращено функцией в объекте, то будет переопределено.\n */\n rowGetStates?: (\n p: RowGetStatesProps<RowType, RowIdType>,\n ) => RowGetStatesReturnType<RowType, RowIdType> | null;\n\n groupedRow?: {\n /**\n * Функция для переопределения checked, indeterminate, showCheckbox, checkboxDisabled для группированных строк.\n * Что будет возвращено функцией в объекте, то будет переопределено.\n */\n getStates: (p: {\n checkedCalculated: boolean;\n indeterminateCalculated: boolean;\n row: GroupRow<RowType>;\n selectedRows: ReadonlySet<string | number>;\n selectedChildCount: number;\n childCount: number;\n }) => {\n checked?: boolean | null;\n indeterminate?: boolean | null;\n showCheckbox?: boolean | null;\n checkboxDisabled?: boolean | null;\n } | null;\n onChange?: (p: {\n row: GroupRow<RowType>;\n\n setSelectedRows: React.Dispatch<\n React.SetStateAction<ReadonlySet<string | number>>\n >;\n checked: boolean;\n indeterminate: boolean;\n checkboxDisabled: boolean;\n showCheckbox: boolean;\n defaultSetter: () => void;\n }) => void;\n };\n};",
58189
58755
  "importPath": "@daisforge/ui",
58190
58756
  "importStatement": "import { SelectingRowConfig } from '@daisforge/ui';",
58191
58757
  "sourceFile": "packages/ui-kit/src/components/Table/types/table-config.type.ts"
58192
58758
  },
58193
58759
  "TableCanvas.SelectingRowConfig": {
58194
58760
  "name": "SelectingRowConfig",
58195
- "definition": "export type SelectingRowConfig<RowType, RowIdType extends string | number> = {\n /**\n * showDefault - состояние, отвечающее за то, видно ли по дефолту чекбоксы.\n */\n showDefault?: boolean;\n /**\n * showState - состояние, отвечающее за то, видны ли чекбоксы.\n */\n showState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n /**\n * showInControl - состояние, отвечающее за то, добавлять ли выбор строк как фичу, которую можно скрывать и раскрывать в правой части контролблока.\n */\n showInControl?: boolean;\n /**\n * selectingRules - пропс, отвечающий за кастомизацию логики выбора строк.\n */\n selectingRules?: {\n // TODO доработать логику\n // changeableOfRowWithoutCheckbox?: boolean;\n // changeableDisabledRow?: boolean;\n /**\n * levels - логика активации чекбоксов у строк с определенным уровнем вложенности.\n */\n levels?: number | 'all' | number[] | ((lvl: number) => boolean);\n };\n disableSummaryCheckboxInHeader?: boolean;\n hideSummaryCheckboxInHeader?: boolean;\n /**\n * hideSummaryCheckbox - в островке массовых действий\n */\n hideSummaryCheckbox?: boolean;\n /**\n * summaryChecked - пропс, отвечающий за логику состояния checked у итогового чекбокса в левой части контролблока.\n */\n summaryChecked?: {\n checked: boolean | SummaryCheckedFunc<RowType, boolean>;\n indeterminate:\n | boolean\n | SummaryCheckedFunc<RowType, boolean, { checkedAll: boolean }>;\n getCountOfChecked: SummaryCheckedFunc<RowType, number>;\n onChange: SummaryCheckedFunc<\n RowType,\n void,\n {\n checkedAll: boolean;\n clearButtonClicked?: boolean;\n setSelectedRowsIds: React.Dispatch<\n React.SetStateAction<ReadonlySet<string | number>>\n >;\n }\n >;\n };\n\n /**\n * summaryCheckedUncontrolled - пропс отвечающий за колбеки в неконтролируемом режиме\n */\n summaryCheckedUncontrolled?: {\n onChange: (event: ChangeEvent<HTMLInputElement>) => void;\n };\n\n /**\n * rowShowCheckbox - пропс, отвечающий за то, будет ли у конкретной строки отрендерен чекбокс.\n */\n rowShowCheckbox?: RowShowCheckbox<RowType>;\n /**\n * rowCheckboxDisabled - пропс, отвечающий за то, будет ли у конкретной строки чекбокс задизейблен.\n */\n rowCheckboxDisabled?: RowCheckboxDisabled<RowType>;\n /**\n * Функция для переопределения checked, indeterminate для каждой строки.\n * Что будет возвращено функцией в объекте, то будет переопределено.\n */\n rowGetStates?: (\n p: RowGetStatesProps<RowType, RowIdType>,\n ) => RowGetStatesReturnType<RowType, RowIdType> | null;\n groupedRow?: {\n /**\n * Функция для переопределения checked, indeterminate, showCheckbox, checkboxDisabled для группированных строк.\n * Что будет возвращено функцией в объекте, то будет переопределено.\n */\n getStates: (p: {\n checkedCalculated: boolean;\n indeterminateCalculated: boolean;\n row: GroupRow<RowType>;\n selectedRows: ReadonlySet<string | number>;\n selectedChildCount: number;\n childCount: number;\n }) => {\n checked?: boolean | null;\n indeterminate?: boolean | null;\n showCheckbox?: boolean | null;\n checkboxDisabled?: boolean | null;\n } | null;\n onChange?: (p: {\n row: GroupRow<RowType>;\n\n setSelectedRows: React.Dispatch<\n React.SetStateAction<ReadonlySet<string | number>>\n >;\n checked: boolean;\n indeterminate: boolean;\n checkboxDisabled: boolean;\n showCheckbox: boolean;\n defaultSetter: () => void;\n }) => void;\n };\n};",
58761
+ "definition": "export type SelectingRowConfig<RowType, RowIdType extends string | number> = {\n /**\n * showDefault - состояние, отвечающее за то, видно ли по дефолту чекбоксы.\n */\n showDefault?: boolean;\n /**\n * showState - состояние, отвечающее за то, видны ли чекбоксы.\n */\n showState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n /**\n * showInControl - состояние, отвечающее за то, добавлять ли выбор строк как фичу, которую можно скрывать и раскрывать в правой части контролблока.\n */\n showInControl?: boolean;\n /**\n * selectingRules - пропс, отвечающий за кастомизацию логики выбора строк.\n */\n selectingRules?: {\n // TODO доработать логику\n // changeableOfRowWithoutCheckbox?: boolean;\n // changeableDisabledRow?: boolean;\n /**\n * levels - логика активации чекбоксов у строк с определенным уровнем вложенности.\n */\n levels?: number | 'all' | number[] | ((lvl: number) => boolean);\n };\n disableSummaryCheckboxInHeader?: boolean;\n hideSummaryCheckboxInHeader?: boolean;\n /**\n * hideSummaryCheckbox - в островке массовых действий\n */\n hideSummaryCheckbox?: boolean;\n /**\n * summaryCounterMaxCount - максимальное отображаемое число в счётчике выбранных\n * строк (в шапке и в панели массовых действий). Если выбрано больше — счётчик\n * показывает «N+» (например, при значении 99 и 5000 выбранных отобразится «99+»).\n * Не ограничивает само выделение, влияет только на отображение.\n */\n summaryCounterMaxCount?: number;\n /**\n * summaryChecked - пропс, отвечающий за логику состояния checked у итогового чекбокса в левой части контролблока.\n */\n summaryChecked?: {\n checked: boolean | SummaryCheckedFunc<RowType, boolean>;\n indeterminate:\n | boolean\n | SummaryCheckedFunc<RowType, boolean, { checkedAll: boolean }>;\n getCountOfChecked: SummaryCheckedFunc<RowType, number>;\n onChange: SummaryCheckedFunc<\n RowType,\n void,\n {\n checkedAll: boolean;\n clearButtonClicked?: boolean;\n setSelectedRowsIds: React.Dispatch<\n React.SetStateAction<ReadonlySet<string | number>>\n >;\n }\n >;\n };\n\n /**\n * summaryCheckedUncontrolled - пропс отвечающий за колбеки в неконтролируемом режиме\n */\n summaryCheckedUncontrolled?: {\n onChange: (event: ChangeEvent<HTMLInputElement>) => void;\n };\n\n /**\n * rowShowCheckbox - пропс, отвечающий за то, будет ли у конкретной строки отрендерен чекбокс.\n */\n rowShowCheckbox?: RowShowCheckbox<RowType>;\n /**\n * rowCheckboxDisabled - пропс, отвечающий за то, будет ли у конкретной строки чекбокс задизейблен.\n */\n rowCheckboxDisabled?: RowCheckboxDisabled<RowType>;\n /**\n * Функция для переопределения checked, indeterminate для каждой строки.\n * Что будет возвращено функцией в объекте, то будет переопределено.\n */\n rowGetStates?: (\n p: RowGetStatesProps<RowType, RowIdType>,\n ) => RowGetStatesReturnType<RowType, RowIdType> | null;\n groupedRow?: {\n /**\n * Функция для переопределения checked, indeterminate, showCheckbox, checkboxDisabled для группированных строк.\n * Что будет возвращено функцией в объекте, то будет переопределено.\n */\n getStates: (p: {\n checkedCalculated: boolean;\n indeterminateCalculated: boolean;\n row: GroupRow<RowType>;\n selectedRows: ReadonlySet<string | number>;\n selectedChildCount: number;\n childCount: number;\n }) => {\n checked?: boolean | null;\n indeterminate?: boolean | null;\n showCheckbox?: boolean | null;\n checkboxDisabled?: boolean | null;\n } | null;\n onChange?: (p: {\n row: GroupRow<RowType>;\n\n setSelectedRows: React.Dispatch<\n React.SetStateAction<ReadonlySet<string | number>>\n >;\n checked: boolean;\n indeterminate: boolean;\n checkboxDisabled: boolean;\n showCheckbox: boolean;\n defaultSetter: () => void;\n }) => void;\n };\n};",
58196
58762
  "internal": true,
58197
58763
  "importNotice": "Тип \"SelectingRowConfig\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
58198
58764
  "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-select-row/types.ts"
@@ -58498,6 +59064,34 @@
58498
59064
  "importNotice": "Тип \"Rect\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
58499
59065
  "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/core/CanvasNode.type.ts"
58500
59066
  },
59067
+ "AvatarSize": {
59068
+ "name": "AvatarSize",
59069
+ "definition": "export type AvatarSize = 's' | 'm' | 'l' | 'xxl';",
59070
+ "importPath": "@daisforge/ui/components/TableCanvas",
59071
+ "importStatement": "import { AvatarSize } from '@daisforge/ui/components/TableCanvas';",
59072
+ "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/primitives/CanvasAvatar.ts"
59073
+ },
59074
+ "GlideThemeForRender": {
59075
+ "name": "GlideThemeForRender",
59076
+ "definition": "export interface GlideThemeForRender extends GlideThemePartial {\n accentColor: string;\n accentLight?: string;\n accentFg?: string;\n bgCell: string;\n bgHeader?: string;\n borderColor: string;\n textLight: string;\n textDark: string;\n textMedium?: string;\n baseFontFull: string;\n cellHorizontalPadding?: number;\n}",
59077
+ "internal": true,
59078
+ "importNotice": "Тип \"GlideThemeForRender\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
59079
+ "sourceFile": "packages/ui-kit/src/components/TableGlide/theming/types.ts"
59080
+ },
59081
+ "AvatarGroupItemClick": {
59082
+ "name": "AvatarGroupItemClick",
59083
+ "definition": "export interface AvatarGroupItemClick {\n /** Участник, по аватару которого нажали. */\n item: CanvasAvatarItem;\n /** Индекс участника в исходном массиве items, начиная с нуля. */\n index: number;\n /** Canvas-событие клика по аватару с координатами и управлением всплытием. */\n event: CanvasEvent<CanvasAvatar>;\n}",
59084
+ "importPath": "@daisforge/ui/components/TableCanvas",
59085
+ "importStatement": "import { AvatarGroupItemClick } from '@daisforge/ui/components/TableCanvas';",
59086
+ "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/primitives/CanvasAvatarGroup.ts"
59087
+ },
59088
+ "AvatarGroupOverflowClick": {
59089
+ "name": "AvatarGroupOverflowClick",
59090
+ "definition": "export interface AvatarGroupOverflowClick {\n /** Число участников за счётчиком +N, включая отсутствующих в items. */\n hiddenCount: number;\n /** Известные скрытые участники: часть items после видимых аватаров. */\n hiddenItems: readonly CanvasAvatarItem[];\n /** Общее число участников после нормализации; не меньше длины items. */\n totalCount: number;\n /** Canvas-событие клика по счётчику +N. */\n event: CanvasEvent<CanvasAvatar>;\n}",
59091
+ "importPath": "@daisforge/ui/components/TableCanvas",
59092
+ "importStatement": "import { AvatarGroupOverflowClick } from '@daisforge/ui/components/TableCanvas';",
59093
+ "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/primitives/CanvasAvatarGroup.ts"
59094
+ },
58501
59095
  "CanvasTextOverflowMode": {
58502
59096
  "name": "CanvasTextOverflowMode",
58503
59097
  "definition": "export type CanvasTextOverflowMode = 'visible' | 'hidden';",