@daisforge/ui 1.19.0 → 1.20.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 (420) hide show
  1. package/chunks/{AnalyticalWidget-Cdo6_s1Y.mjs → AnalyticalWidget-BtyWKJuu.mjs} +34 -34
  2. package/chunks/AnalyticalWidget-YytE3Rlw.cjs +43 -0
  3. package/chunks/{ApprovalCenter-DxcvzR8q.mjs → ApprovalCenter-DLKZP2AO.mjs} +2 -2
  4. package/chunks/{ApprovalCenter-CAcC43zn.cjs → ApprovalCenter-DdsLEipZ.cjs} +1 -1
  5. package/chunks/BlockTitle-DC1McGof.cjs +1 -0
  6. package/chunks/BlockTitle-DsXxImR6.mjs +86 -0
  7. package/chunks/{Container-CrB1jwqH.cjs → Container-DHnX1sHY.cjs} +1 -1
  8. package/chunks/{Container-Cy8w2JOq.mjs → Container-DbZwlfIM.mjs} +1 -1
  9. package/chunks/{EmptyState-B205JfZA.mjs → EmptyState-CUCseg9M.mjs} +1 -1
  10. package/chunks/{EmptyState-CcxlsZm0.cjs → EmptyState-DH1xawxg.cjs} +1 -1
  11. package/chunks/{FiltersActions-BKJJH6Mu.cjs → FiltersActions-Cw_JG2O2.cjs} +1 -1
  12. package/chunks/{FiltersActions-CFStLRsU.mjs → FiltersActions-UayfdMLv.mjs} +4 -4
  13. package/chunks/{FormSegmentGroup-CCCqRgCG.cjs → FormSegmentGroup-BYQ6yMK1.cjs} +1 -1
  14. package/chunks/{FormSegmentGroup-E1JurEt7.mjs → FormSegmentGroup-C9qYxYT9.mjs} +1 -1
  15. package/chunks/{GridDND-UMUi8M_Q.mjs → GridDND-CqvpXgCY.mjs} +2 -2
  16. package/chunks/{GridDND-DV-1g1sI.cjs → GridDND-DK6SAO8q.cjs} +1 -1
  17. package/chunks/LeftPanel-AyuV7bGS.cjs +1 -0
  18. package/chunks/{LeftPanel-HZu3ECqD.mjs → LeftPanel-C5SsoRJS.mjs} +47 -45
  19. package/chunks/{ListOfFilters-DJvnT9kw.cjs → ListOfFilters-8rHTfUXT.cjs} +1 -1
  20. package/chunks/{ListOfFilters-DTAZ3wfQ.mjs → ListOfFilters-B3CA32OD.mjs} +3 -3
  21. package/chunks/{MassActions-Z-48g81T.cjs → MassActions-5p7to0R5.cjs} +1 -1
  22. package/chunks/{MassActions-DSAaO1-u.mjs → MassActions-BJxR4H1S.mjs} +3 -3
  23. package/chunks/PageTitle-CrBeieoq.cjs +9 -0
  24. package/chunks/PageTitle-DkfAiZM4.mjs +133 -0
  25. package/chunks/{SplitView-DYHeCnl9.mjs → SplitView-BqS1Jbo4.mjs} +1 -1
  26. package/chunks/{SplitView-UKIBuvTi.cjs → SplitView-DNmd4sJe.cjs} +1 -1
  27. package/chunks/{Stories-Dlwle-SM.mjs → Stories-BnHxMCEZ.mjs} +3 -3
  28. package/chunks/{Stories-CZXv_Ves.cjs → Stories-UYVANawW.cjs} +1 -1
  29. package/chunks/Table--NExtXRi.cjs +31 -0
  30. package/chunks/{Table-B9OAyWAW.mjs → Table-bmvWLH9o.mjs} +2682 -2608
  31. package/chunks/TableCanvas-DTm2pu0r.cjs +30 -0
  32. package/chunks/{TableCanvas-DkZAx-r9.mjs → TableCanvas-DxcB4WOJ.mjs} +7018 -6929
  33. package/chunks/{TableGlide-CkorJrl9.mjs → TableGlide-BMBq6g4-.mjs} +2291 -2230
  34. package/chunks/TableGlide-DtosQrHB.cjs +1 -0
  35. package/chunks/{styles-C-1Srtr7.mjs → styles-CJ5y9FKW.mjs} +1 -1
  36. package/chunks/{styles-AUqEaroI.cjs → styles-kUWPuNSD.cjs} +1 -1
  37. package/chunks/utils-ChDQGRjv.cjs +25 -0
  38. package/chunks/{utils-YKicAHp0.mjs → utils-u1KJ37g3.mjs} +120 -108
  39. package/components/AiAgentPopover/index.cjs +1 -1
  40. package/components/AiAgentPopover/index.mjs +1 -1
  41. package/components/AnalyticalWidget/components/AnalyticalWidgetButtons/index.cjs +1 -1
  42. package/components/AnalyticalWidget/components/AnalyticalWidgetButtons/index.mjs +1 -1
  43. package/components/AnalyticalWidget/components/AnalyticalWidgetChips/index.cjs +1 -1
  44. package/components/AnalyticalWidget/components/AnalyticalWidgetChips/index.mjs +1 -1
  45. package/components/AnalyticalWidget/components/AnalyticalWidgetHeader/index.cjs +1 -1
  46. package/components/AnalyticalWidget/components/AnalyticalWidgetHeader/index.mjs +1 -1
  47. package/components/AnalyticalWidget/index.cjs +1 -1
  48. package/components/AnalyticalWidget/index.mjs +1 -1
  49. package/components/ApprovalCenter/components/index.cjs +1 -1
  50. package/components/ApprovalCenter/components/index.mjs +1 -1
  51. package/components/ApprovalCenter/index.cjs +1 -1
  52. package/components/ApprovalCenter/index.mjs +1 -1
  53. package/components/AutocompleteSearch/index.cjs +1 -1
  54. package/components/AutocompleteSearch/index.mjs +2 -2
  55. package/components/BlockGradientScroll/index.cjs +1 -1
  56. package/components/BlockGradientScroll/index.mjs +1 -1
  57. package/components/BlockTitle/BlockTitle.d.ts +1 -1
  58. package/components/BlockTitle/BlockTitle.types.d.ts +2 -1
  59. package/components/BlockTitle/index.cjs +1 -1
  60. package/components/BlockTitle/index.mjs +1 -1
  61. package/components/BlockTitle/utils/index.cjs +1 -1
  62. package/components/BlockTitle/utils/index.mjs +1 -1
  63. package/components/Collapse/index.cjs +1 -1
  64. package/components/Collapse/index.mjs +1 -1
  65. package/components/Combobox/index.cjs +1 -1
  66. package/components/Combobox/index.mjs +1 -1
  67. package/components/EmptyState/components/index.cjs +1 -1
  68. package/components/EmptyState/components/index.mjs +1 -1
  69. package/components/EmptyState/index.cjs +1 -1
  70. package/components/EmptyState/index.mjs +1 -1
  71. package/components/GridDND/index.cjs +1 -1
  72. package/components/GridDND/index.mjs +1 -1
  73. package/components/GridDND/utils/index.cjs +1 -1
  74. package/components/GridDND/utils/index.mjs +1 -1
  75. package/components/IconButton/index.cjs +1 -1
  76. package/components/IconButton/index.mjs +1 -1
  77. package/components/LeftPanel/components/index.cjs +1 -1
  78. package/components/LeftPanel/components/index.mjs +1 -1
  79. package/components/LeftPanel/hooks/index.cjs +1 -1
  80. package/components/LeftPanel/hooks/index.mjs +1 -1
  81. package/components/LeftPanel/index.cjs +1 -1
  82. package/components/LeftPanel/index.mjs +1 -1
  83. package/components/LeftPanel/styled.d.ts +1 -0
  84. package/components/LeftPanel/utils/index.cjs +1 -1
  85. package/components/LeftPanel/utils/index.mjs +1 -1
  86. package/components/ListOfFilters/index.cjs +1 -1
  87. package/components/ListOfFilters/index.mjs +1 -1
  88. package/components/MassActions/hooks/index.cjs +1 -1
  89. package/components/MassActions/hooks/index.mjs +1 -1
  90. package/components/MassActions/index.cjs +1 -1
  91. package/components/MassActions/index.mjs +1 -1
  92. package/components/ModalDF/index.cjs +1 -1
  93. package/components/ModalDF/index.mjs +1 -1
  94. package/components/Notification/index.cjs +1 -1
  95. package/components/Notification/index.mjs +2 -2
  96. package/components/PageTitle/PageTitle.styled.d.ts +3 -1
  97. package/components/PageTitle/index.cjs +1 -1
  98. package/components/PageTitle/index.mjs +1 -1
  99. package/components/PageTitle/utils/index.cjs +1 -1
  100. package/components/PageTitle/utils/index.mjs +1 -1
  101. package/components/PopoverDF/index.cjs +1 -1
  102. package/components/PopoverDF/index.mjs +1 -1
  103. package/components/PopupDF/index.cjs +1 -1
  104. package/components/PopupDF/index.mjs +1 -1
  105. package/components/SplitView/index.cjs +1 -1
  106. package/components/SplitView/index.mjs +1 -1
  107. package/components/SplitView/utils/index.cjs +1 -1
  108. package/components/SplitView/utils/index.mjs +1 -1
  109. package/components/Stories/components/StoriesBanner/index.cjs +1 -1
  110. package/components/Stories/components/StoriesBanner/index.mjs +1 -1
  111. package/components/Stories/components/StoriesContent/index.cjs +1 -1
  112. package/components/Stories/components/StoriesContent/index.mjs +1 -1
  113. package/components/Stories/components/StoriesPreview/index.cjs +1 -1
  114. package/components/Stories/components/StoriesPreview/index.mjs +1 -1
  115. package/components/Stories/components/StoriesProgress/index.cjs +1 -1
  116. package/components/Stories/components/StoriesProgress/index.mjs +1 -1
  117. package/components/Stories/components/StoriesViewer/index.cjs +1 -1
  118. package/components/Stories/components/StoriesViewer/index.mjs +1 -1
  119. package/components/Stories/index.cjs +1 -1
  120. package/components/Stories/index.mjs +1 -1
  121. package/components/Table/components/TableDropdown/index.cjs +1 -1
  122. package/components/Table/components/TableDropdown/index.mjs +1 -1
  123. package/components/Table/feature-collapse-table/index.cjs +1 -1
  124. package/components/Table/feature-collapse-table/index.mjs +2 -2
  125. package/components/Table/feature-column-control/ColumnsList/index.cjs +1 -1
  126. package/components/Table/feature-column-control/ColumnsList/index.mjs +2 -2
  127. package/components/Table/feature-column-control/index.cjs +1 -1
  128. package/components/Table/feature-column-control/index.mjs +3 -3
  129. package/components/Table/feature-columns-grouping/index.cjs +1 -1
  130. package/components/Table/feature-columns-grouping/index.mjs +1 -1
  131. package/components/Table/feature-context-menu/index.cjs +1 -1
  132. package/components/Table/feature-context-menu/index.mjs +1 -1
  133. package/components/Table/feature-edit/index.cjs +1 -1
  134. package/components/Table/feature-edit/index.mjs +1 -1
  135. package/components/Table/feature-filtering/combobox/combobox.d.ts +3 -2
  136. package/components/Table/feature-filtering/combobox/index.cjs +1 -1
  137. package/components/Table/feature-filtering/combobox/index.d.ts +4 -2
  138. package/components/Table/feature-filtering/combobox/index.mjs +7 -3
  139. package/components/Table/feature-filtering/filter-list-block/index.cjs +1 -1
  140. package/components/Table/feature-filtering/filter-list-block/index.mjs +1 -1
  141. package/components/Table/feature-filtering/header-filter-button/filter-component-in-popover.d.ts +1 -2
  142. package/components/Table/feature-filtering/header-filter-button/index.cjs +1 -1
  143. package/components/Table/feature-filtering/header-filter-button/index.mjs +1 -1
  144. package/components/Table/feature-filtering/index.cjs +1 -1
  145. package/components/Table/feature-filtering/index.d.ts +1 -1
  146. package/components/Table/feature-filtering/index.mjs +13 -9
  147. package/components/Table/feature-filtering/render-slot.d.ts +5 -0
  148. package/components/Table/feature-filtering/sidebar-filter-block/index.cjs +1 -1
  149. package/components/Table/feature-filtering/sidebar-filter-block/index.mjs +2 -2
  150. package/components/Table/feature-filtering/use-focus-search-input.d.ts +2 -0
  151. package/components/Table/feature-infinity-scroll/index.cjs +1 -1
  152. package/components/Table/feature-infinity-scroll/index.mjs +1 -1
  153. package/components/Table/feature-key-text/index.cjs +1 -1
  154. package/components/Table/feature-key-text/index.mjs +3 -3
  155. package/components/Table/feature-pagination/index.cjs +1 -1
  156. package/components/Table/feature-pagination/index.mjs +3 -3
  157. package/components/Table/feature-reorder-columns/handlers.d.ts +4 -0
  158. package/components/Table/feature-right-sidebar/index.cjs +1 -1
  159. package/components/Table/feature-right-sidebar/index.mjs +1 -1
  160. package/components/Table/feature-row-detail/index.cjs +1 -1
  161. package/components/Table/feature-row-detail/index.mjs +1 -1
  162. package/components/Table/feature-row-instruments/index.cjs +1 -1
  163. package/components/Table/feature-row-instruments/index.mjs +5 -5
  164. package/components/Table/feature-row-size/index.cjs +1 -1
  165. package/components/Table/feature-row-size/index.mjs +2 -2
  166. package/components/Table/feature-rows-grouping/index.cjs +1 -1
  167. package/components/Table/feature-rows-grouping/index.mjs +1 -1
  168. package/components/Table/feature-searching/index.cjs +1 -1
  169. package/components/Table/feature-searching/index.mjs +1 -1
  170. package/components/Table/feature-select-row/index.cjs +1 -1
  171. package/components/Table/feature-select-row/index.mjs +1 -1
  172. package/components/Table/feature-sorting/index.cjs +1 -1
  173. package/components/Table/feature-sorting/index.mjs +1 -1
  174. package/components/Table/feature-table-settings/index.cjs +1 -1
  175. package/components/Table/feature-table-settings/index.mjs +1 -1
  176. package/components/Table/feature-tree/index.cjs +1 -1
  177. package/components/Table/feature-tree/index.mjs +2 -2
  178. package/components/Table/index.cjs +1 -1
  179. package/components/Table/index.d.ts +1 -1
  180. package/components/Table/index.mjs +43 -39
  181. package/components/Table/renders/formatCell/index.cjs +1 -1
  182. package/components/Table/renders/formatCell/index.mjs +3 -3
  183. package/components/Table/styles/index.cjs +1 -1
  184. package/components/Table/styles/index.mjs +9 -9
  185. package/components/Table/table-hooks/index.cjs +1 -1
  186. package/components/Table/table-hooks/index.mjs +3 -3
  187. package/components/Table/types/column-config.type.d.ts +1 -0
  188. package/components/Table/types/index.cjs +1 -1
  189. package/components/Table/types/index.mjs +1 -1
  190. package/components/Table/utils/index.cjs +1 -1
  191. package/components/Table/utils/index.mjs +4 -4
  192. package/components/Table/widgets/control-block/index.cjs +1 -1
  193. package/components/Table/widgets/control-block/index.mjs +1 -1
  194. package/components/Table/widgets/control-block/right-side/index.cjs +1 -1
  195. package/components/Table/widgets/control-block/right-side/index.mjs +1 -1
  196. package/components/Table/widgets/index.cjs +1 -1
  197. package/components/Table/widgets/index.mjs +1 -1
  198. package/components/Table/widgets/mass-actions/index.cjs +1 -1
  199. package/components/Table/widgets/mass-actions/index.mjs +1 -1
  200. package/components/TableCanvas/TableGlideInstance/adapters/column/index.cjs +1 -1
  201. package/components/TableCanvas/TableGlideInstance/adapters/column/index.mjs +1 -1
  202. package/components/TableCanvas/TableGlideInstance/adapters/index.cjs +1 -1
  203. package/components/TableCanvas/TableGlideInstance/adapters/index.mjs +1 -1
  204. package/components/TableCanvas/TableGlideInstance/index.cjs +1 -1
  205. package/components/TableCanvas/TableGlideInstance/index.mjs +2 -2
  206. package/components/TableCanvas/TableGlideInstance/utils/column/index.cjs +1 -1
  207. package/components/TableCanvas/TableGlideInstance/utils/column/index.mjs +1 -1
  208. package/components/TableCanvas/TableGlideInstance/utils/index.cjs +1 -1
  209. package/components/TableCanvas/TableGlideInstance/utils/index.mjs +1 -1
  210. package/components/TableCanvas/components/SplitIconButton/index.cjs +1 -1
  211. package/components/TableCanvas/components/SplitIconButton/index.mjs +1 -1
  212. package/components/TableCanvas/components/TableDropdown/index.cjs +1 -1
  213. package/components/TableCanvas/components/TableDropdown/index.mjs +1 -1
  214. package/components/TableCanvas/feature-borders/buildBorderCallbacks.d.ts +16 -0
  215. package/components/TableCanvas/feature-borders/useBorders.d.ts +14 -0
  216. package/components/TableCanvas/feature-cell-transfer/index.cjs +1 -1
  217. package/components/TableCanvas/feature-cell-transfer/index.mjs +1 -1
  218. package/components/TableCanvas/feature-collapse-table/index.cjs +1 -1
  219. package/components/TableCanvas/feature-collapse-table/index.mjs +1 -1
  220. package/components/TableCanvas/feature-column-control/ColumnsList/index.cjs +1 -1
  221. package/components/TableCanvas/feature-column-control/ColumnsList/index.mjs +1 -1
  222. package/components/TableCanvas/feature-column-control/index.cjs +1 -1
  223. package/components/TableCanvas/feature-column-control/index.mjs +1 -1
  224. package/components/TableCanvas/feature-columns-grouping/index.cjs +1 -1
  225. package/components/TableCanvas/feature-columns-grouping/index.mjs +1 -1
  226. package/components/TableCanvas/feature-columns-grouping/useLastLvlColumnConfig.d.ts +1 -0
  227. package/components/TableCanvas/feature-content-state/index.cjs +1 -1
  228. package/components/TableCanvas/feature-content-state/index.mjs +1 -1
  229. package/components/TableCanvas/feature-context-menu/index.cjs +1 -1
  230. package/components/TableCanvas/feature-context-menu/index.mjs +1 -1
  231. package/components/TableCanvas/feature-edit/index.cjs +1 -1
  232. package/components/TableCanvas/feature-edit/index.mjs +1 -1
  233. package/components/TableCanvas/feature-filtering/combobox/combobox.d.ts +3 -2
  234. package/components/TableCanvas/feature-filtering/combobox/index.cjs +1 -1
  235. package/components/TableCanvas/feature-filtering/combobox/index.d.ts +4 -2
  236. package/components/TableCanvas/feature-filtering/combobox/index.mjs +7 -3
  237. package/components/TableCanvas/feature-filtering/filter-list-block/index.cjs +1 -1
  238. package/components/TableCanvas/feature-filtering/filter-list-block/index.mjs +2 -2
  239. package/components/TableCanvas/feature-filtering/header-filter-button/filter-component-in-popover.d.ts +1 -2
  240. package/components/TableCanvas/feature-filtering/header-filter-button/index.cjs +1 -1
  241. package/components/TableCanvas/feature-filtering/header-filter-button/index.mjs +2 -2
  242. package/components/TableCanvas/feature-filtering/index.cjs +1 -1
  243. package/components/TableCanvas/feature-filtering/index.d.ts +1 -1
  244. package/components/TableCanvas/feature-filtering/index.mjs +12 -8
  245. package/components/TableCanvas/feature-filtering/render-slot.d.ts +5 -0
  246. package/components/TableCanvas/feature-filtering/sidebar-filter-block/index.cjs +1 -1
  247. package/components/TableCanvas/feature-filtering/sidebar-filter-block/index.mjs +1 -1
  248. package/components/TableCanvas/feature-infinity-scroll/index.cjs +1 -1
  249. package/components/TableCanvas/feature-infinity-scroll/index.mjs +3 -3
  250. package/components/TableCanvas/feature-key-text/index.cjs +1 -1
  251. package/components/TableCanvas/feature-key-text/index.mjs +1 -1
  252. package/components/TableCanvas/feature-notifications/index.cjs +1 -1
  253. package/components/TableCanvas/feature-notifications/index.mjs +1 -1
  254. package/components/TableCanvas/feature-pagination/index.cjs +1 -1
  255. package/components/TableCanvas/feature-pagination/index.mjs +2 -2
  256. package/components/TableCanvas/feature-popover-table/context/index.cjs +1 -1
  257. package/components/TableCanvas/feature-popover-table/context/index.mjs +1 -1
  258. package/components/TableCanvas/feature-popover-table/hooks/index.cjs +1 -1
  259. package/components/TableCanvas/feature-popover-table/hooks/index.mjs +1 -1
  260. package/components/TableCanvas/feature-popover-table/index.cjs +1 -1
  261. package/components/TableCanvas/feature-popover-table/index.mjs +6 -6
  262. package/components/TableCanvas/feature-popover-table/utils/index.cjs +1 -1
  263. package/components/TableCanvas/feature-popover-table/utils/index.mjs +1 -1
  264. package/components/TableCanvas/feature-reorder-columns/handlers.d.ts +4 -0
  265. package/components/TableCanvas/feature-right-sidebar/index.cjs +1 -1
  266. package/components/TableCanvas/feature-right-sidebar/index.mjs +1 -1
  267. package/components/TableCanvas/feature-row-detail/index.cjs +1 -1
  268. package/components/TableCanvas/feature-row-detail/index.mjs +1 -1
  269. package/components/TableCanvas/feature-row-instruments/index.cjs +1 -1
  270. package/components/TableCanvas/feature-row-instruments/index.mjs +1 -1
  271. package/components/TableCanvas/feature-row-markers/index.cjs +1 -1
  272. package/components/TableCanvas/feature-row-markers/index.mjs +1 -1
  273. package/components/TableCanvas/feature-row-size/index.cjs +1 -1
  274. package/components/TableCanvas/feature-row-size/index.mjs +3 -3
  275. package/components/TableCanvas/feature-rows-grouping/index.cjs +1 -1
  276. package/components/TableCanvas/feature-rows-grouping/index.mjs +1 -1
  277. package/components/TableCanvas/feature-searching/index.cjs +1 -1
  278. package/components/TableCanvas/feature-searching/index.mjs +1 -1
  279. package/components/TableCanvas/feature-select-row/index.cjs +1 -1
  280. package/components/TableCanvas/feature-select-row/index.mjs +1 -1
  281. package/components/TableCanvas/feature-sorting/index.cjs +1 -1
  282. package/components/TableCanvas/feature-sorting/index.mjs +1 -1
  283. package/components/TableCanvas/feature-table-settings/index.cjs +1 -1
  284. package/components/TableCanvas/feature-table-settings/index.mjs +1 -1
  285. package/components/TableCanvas/feature-tooltip/index.cjs +1 -1
  286. package/components/TableCanvas/feature-tooltip/index.mjs +2 -2
  287. package/components/TableCanvas/feature-tooltip/utils/index.cjs +1 -1
  288. package/components/TableCanvas/feature-tooltip/utils/index.mjs +6 -6
  289. package/components/TableCanvas/feature-tree/handlers.d.ts +1 -0
  290. package/components/TableCanvas/feature-tree/index.cjs +1 -1
  291. package/components/TableCanvas/feature-tree/index.mjs +1 -1
  292. package/components/TableCanvas/index.cjs +1 -1
  293. package/components/TableCanvas/index.d.ts +1 -1
  294. package/components/TableCanvas/index.mjs +63 -59
  295. package/components/TableCanvas/renders/formatCell/index.cjs +1 -1
  296. package/components/TableCanvas/renders/formatCell/index.mjs +1 -1
  297. package/components/TableCanvas/styles/index.cjs +1 -1
  298. package/components/TableCanvas/styles/index.mjs +1 -1
  299. package/components/TableCanvas/table-hooks/index.cjs +1 -1
  300. package/components/TableCanvas/table-hooks/index.mjs +12 -12
  301. package/components/TableCanvas/types/column-config.type.d.ts +1 -0
  302. package/components/TableCanvas/types/index.cjs +1 -1
  303. package/components/TableCanvas/types/index.mjs +2 -2
  304. package/components/TableCanvas/types/table-config.type.d.ts +27 -0
  305. package/components/TableCanvas/utils/index.cjs +1 -1
  306. package/components/TableCanvas/utils/index.mjs +2 -2
  307. package/components/TableCanvas/widgets/control-block/compression/index.cjs +1 -1
  308. package/components/TableCanvas/widgets/control-block/compression/index.mjs +2 -2
  309. package/components/TableCanvas/widgets/control-block/index.cjs +1 -1
  310. package/components/TableCanvas/widgets/control-block/index.mjs +3 -3
  311. package/components/TableCanvas/widgets/control-block/right-side/index.cjs +1 -1
  312. package/components/TableCanvas/widgets/control-block/right-side/index.mjs +1 -1
  313. package/components/TableCanvas/widgets/index.cjs +1 -1
  314. package/components/TableCanvas/widgets/index.mjs +5 -5
  315. package/components/TableCanvas/widgets/mass-actions/hooks/index.cjs +1 -1
  316. package/components/TableCanvas/widgets/mass-actions/hooks/index.mjs +8 -8
  317. package/components/TableCanvas/widgets/mass-actions/index.cjs +1 -1
  318. package/components/TableCanvas/widgets/mass-actions/index.mjs +1 -1
  319. package/components/TableContract/index.cjs +1 -1
  320. package/components/TableContract/index.mjs +2 -2
  321. package/components/TableGlide/hooks/selection/index.cjs +1 -1
  322. package/components/TableGlide/hooks/selection/index.d.ts +1 -2
  323. package/components/TableGlide/hooks/selection/index.mjs +6 -7
  324. package/components/TableGlide/hooks/selection/useColoringLayers.d.ts +25 -0
  325. package/components/TableGlide/hooks/useHoverState.d.ts +18 -0
  326. package/components/TableGlide/index.cjs +1 -1
  327. package/components/TableGlide/index.mjs +9 -9
  328. package/components/TableGlide/lib/canvas/cells/buttons/index.cjs +1 -1
  329. package/components/TableGlide/lib/canvas/cells/buttons/index.mjs +1 -1
  330. package/components/TableGlide/lib/canvas/cells/iconSprites/index.cjs +1 -1
  331. package/components/TableGlide/lib/canvas/cells/iconSprites/index.mjs +1 -1
  332. package/components/TableGlide/lib/canvas/cells/index.cjs +1 -1
  333. package/components/TableGlide/lib/canvas/cells/index.mjs +1 -1
  334. package/components/TableGlide/lib/canvas/cells/renderer/index.cjs +1 -1
  335. package/components/TableGlide/lib/canvas/cells/renderer/index.mjs +1 -1
  336. package/components/TableGlide/lib/canvas/core/helpers/index.cjs +1 -1
  337. package/components/TableGlide/lib/canvas/core/helpers/index.mjs +1 -1
  338. package/components/TableGlide/lib/canvas/core/index.cjs +1 -1
  339. package/components/TableGlide/lib/canvas/core/index.mjs +1 -1
  340. package/components/TableGlide/lib/canvas/hooks/index.cjs +1 -1
  341. package/components/TableGlide/lib/canvas/hooks/index.mjs +1 -1
  342. package/components/TableGlide/lib/canvas/index.cjs +1 -1
  343. package/components/TableGlide/lib/canvas/index.mjs +1 -1
  344. package/components/TableGlide/lib/canvas/miniflex/index.cjs +1 -1
  345. package/components/TableGlide/lib/canvas/miniflex/index.mjs +1 -1
  346. package/components/TableGlide/lib/canvas/primitives/index.cjs +1 -1
  347. package/components/TableGlide/lib/canvas/primitives/index.mjs +1 -1
  348. package/components/TableGlide/lib/canvas/utils/index.cjs +1 -1
  349. package/components/TableGlide/lib/canvas/utils/index.mjs +1 -1
  350. package/components/TableGlide/theming/custom-colors.d.ts +1 -1
  351. package/components/TableGlide/theming/index.cjs +1 -1
  352. package/components/TableGlide/theming/index.mjs +3 -3
  353. package/components/TableGlide/types.d.ts +1 -3
  354. package/components/TableTabs/index.cjs +1 -1
  355. package/components/TableTabs/index.mjs +1 -1
  356. package/components/Tooltip/index.cjs +1 -1
  357. package/components/Tooltip/index.mjs +1 -1
  358. package/components/TourWidget/index.cjs +1 -1
  359. package/components/TourWidget/index.mjs +2 -2
  360. package/components/Typography/index.cjs +1 -1
  361. package/components/Typography/index.mjs +1 -1
  362. package/components/Widget/index.cjs +1 -1
  363. package/components/Widget/index.mjs +2 -2
  364. package/formComponents/FormCombobox/index.cjs +1 -1
  365. package/formComponents/FormCombobox/index.mjs +1 -1
  366. package/formComponents/FormRadioGroupBox/index.cjs +1 -1
  367. package/formComponents/FormRadioGroupBox/index.mjs +1 -1
  368. package/formComponents/FormSegments/index.cjs +1 -1
  369. package/formComponents/FormSegments/index.mjs +1 -1
  370. package/formComponents/FormSwitch/index.cjs +1 -1
  371. package/formComponents/FormSwitch/index.mjs +1 -1
  372. package/index.cjs +1 -1
  373. package/index.mjs +1778 -1773
  374. package/layouts/Container/index.cjs +1 -1
  375. package/layouts/Container/index.mjs +1 -1
  376. package/layouts/Container/lib/utils/index.cjs +1 -1
  377. package/layouts/Container/lib/utils/index.mjs +1 -1
  378. package/layouts/ErrorPage/index.cjs +1 -1
  379. package/layouts/ErrorPage/index.mjs +1 -1
  380. package/layouts/FiltersActions/hooks/index.cjs +1 -1
  381. package/layouts/FiltersActions/hooks/index.mjs +1 -1
  382. package/layouts/FiltersActions/index.cjs +1 -1
  383. package/layouts/FiltersActions/index.mjs +1 -1
  384. package/layouts/Layout/index.cjs +1 -1
  385. package/layouts/Layout/index.mjs +1 -1
  386. package/layouts/PageLayout/index.cjs +1 -1
  387. package/layouts/PageLayout/index.mjs +1 -1
  388. package/mcp-data/component-index.json +472 -48
  389. package/mixins/index.cjs +1 -1
  390. package/mixins/index.mjs +1 -1
  391. package/package.json +6 -6
  392. package/styles/index.cjs +1 -1
  393. package/styles/index.mjs +1 -1
  394. package/utils/breakpoint/index.cjs +1 -1
  395. package/utils/breakpoint/index.mjs +1 -1
  396. package/utils/clickStream/index.cjs +1 -1
  397. package/utils/clickStream/index.mjs +1 -1
  398. package/utils/eventBus/index.cjs +1 -1
  399. package/utils/eventBus/index.mjs +1 -1
  400. package/utils/hooks/index.cjs +1 -1
  401. package/utils/hooks/index.mjs +1 -1
  402. package/utils/index.cjs +1 -1
  403. package/utils/index.d.ts +1 -0
  404. package/utils/index.mjs +30 -29
  405. package/utils/react/getMFReactDOMClient.d.ts +7 -0
  406. package/utils/react/index.cjs +1 -0
  407. package/utils/react/index.d.ts +1 -0
  408. package/utils/react/index.mjs +4 -0
  409. package/utils/styles/index.cjs +1 -1
  410. package/utils/styles/index.mjs +1 -1
  411. package/chunks/AnalyticalWidget-wke3Jm3X.cjs +0 -43
  412. package/chunks/BlockTitle-BEIxiECX.cjs +0 -1
  413. package/chunks/BlockTitle-BZxOEdTc.mjs +0 -85
  414. package/chunks/LeftPanel-B3-ySDMW.cjs +0 -1
  415. package/chunks/PageTitle-Bh3g6FUT.cjs +0 -1
  416. package/chunks/PageTitle-CaqXfrrQ.mjs +0 -123
  417. package/chunks/Table-BwhzcFX1.cjs +0 -31
  418. package/chunks/TableCanvas-QmXGAjPk.cjs +0 -30
  419. package/chunks/TableGlide-Bngn5_5l.cjs +0 -1
  420. package/chunks/utils-CUW5bd8S.cjs +0 -25
@@ -1,6 +1,6 @@
1
1
  {
2
- "generatedAt": "2026-09-15T09:09:39.134Z",
3
- "libVersion": "1.19.0",
2
+ "generatedAt": "2026-09-21T13:53:31.646Z",
3
+ "libVersion": "1.20.0",
4
4
  "components": {
5
5
  "Accordion": {
6
6
  "name": "Accordion",
@@ -881,7 +881,7 @@
881
881
  "type": "\"default\" | \"secondary\" | \"accent\" | \"positive\" | \"warning\" | \"negative\" | \"gradient\" | \"info\" | undefined",
882
882
  "required": false,
883
883
  "description": "",
884
- "default": "'secondary'"
884
+ "default": "'default'"
885
885
  }
886
886
  ]
887
887
  },
@@ -2922,6 +2922,12 @@
2922
2922
  "description": "Размер заголовка",
2923
2923
  "default": "'H2'"
2924
2924
  },
2925
+ {
2926
+ "name": "titleTooltipProps",
2927
+ "type": "Omit<TooltipProps, \"text\" | \"target\" | \"trigger\" | \"opened\"> | undefined",
2928
+ "required": false,
2929
+ "description": "Пропсы тултипа, которым оборачивается обрезанный `title`."
2930
+ },
2925
2931
  {
2926
2932
  "name": "topSlot",
2927
2933
  "type": "BlockTitleAdaptiveSlot",
@@ -2946,8 +2952,8 @@
2946
2952
  "page heading",
2947
2953
  "шапка блока"
2948
2954
  ],
2949
- "docs": "# BlockTitle\n\nКомпонент заголовка блока с поддержкой слотов для дополнительных элементов и кнопки «назад».\n\n## Ключевые особенности\n\n- Настраиваемый размер заголовка через вариант типографики (`titleSize`)\n- Описание под заголовком (`description`)\n- Слоты: `titleLeftSlot`, `titleRightSlot`, `topSlot`, `rightSlot`\n- Кнопка «назад» через `onBackButtonClick`\n- Кастомизация контейнера через `containerProps` (Box с `$css`)\n\n## Особенности\n\n- Компонент можно стилизовать: обернув в `styled`, используя `$css` в `containerProps`, или используя объект `blockTitleClassNames` для обращения к подэлементам\n- Слоты `titleLeftSlot`, `titleRightSlot`, `topSlot`, `rightSlot` принимают `ReactNode` или callback с размерами для адаптива\n- По умолчанию адаптив на viewport `<= 1280px` включен; временно отключить его можно через deprecated-проп `disableMediaAdaptive`\n\n## Использование адаптивных слотов\n\nЕсли слот не должен менять размеры, передавайте обычный `ReactNode`:\n\n```tsx\n<BlockTitle title=\"Title\" titleRightSlot={<IconPlasma size=\"s\" />} />\n```\n\nЕсли в слоте есть иконка, Badge или кнопки, передавайте callback и используйте размеры из аргумента:\n\n```tsx\n<BlockTitle\n title=\"Страница\"\n titleSize=\"H4\"\n titleRightSlot={({ titleBadgeSize }) => (\n <Badge size={titleBadgeSize} view=\"default\" text=\"Label\" />\n )}\n rightSlot={({ buttonSize, actionIconSize }) => (\n <div style={{ display: 'flex', gap: s.x4 }}>\n <IconButton size={buttonSize} view=\"secondary\">\n <IconDotsVerticalCenteredOutline\n size={actionIconSize}\n color=\"inherit\"\n />\n </IconButton>\n <Button size={buttonSize} view=\"secondary\">\n Label\n </Button>\n <Button size={buttonSize} view=\"accent\">\n Label\n </Button>\n </div>\n )}\n/>\n```\n\nРазмеры, которые приходят в callback (в зависимости от viewport):\n\n```\n| Поле | <= 1280px | > 1280px |\n| -------------------------------------------- | --------- | -------- |\n| buttonSize | xs | s |\n| actionIconSize | xs | s |\n| titleIconSize (для H4/H5) | xs | s |\n| titleBadgeSize (для H4/H5) | s | m |\n| titleIconSize (для остальных) | s | s |\n| titleBadgeSize (для остальных) | m | m |\n```\n\n> Подробнее о типах и пропсах — [BlockTitle API](?path=/docs/композиции-blocktitle-api--docs)",
2950
- "apiDocs": "# BlockTitle API\n\n## BlockTitleProps\n\n```typescript\ntype BlockTitleProps = {\n /**\n * Текст заголовка\n */\n title?: string;\n /**\n * Размер заголовка\n */\n titleSize?: ComponentProps<typeof Typography>['variant'];\n /**\n * Иконка слева от заголовка (обычно используется иконка)\n */\n titleLeftSlot?: BlockTitleAdaptiveSlot;\n /**\n * Иконка справа от заголовка (обычно используется иконка)\n */\n titleRightSlot?: BlockTitleAdaptiveSlot;\n /**\n * Текст Заголовка\n */\n description?: string;\n /**\n * Слот для верхней части\n */\n topSlot?: BlockTitleAdaptiveSlot;\n /**\n * Слот для правой части\n */\n rightSlot?: BlockTitleAdaptiveSlot;\n /**\n * Отключает принудительный адаптив компонента на viewport <= 1280px.\n *\n * @deprecated Используйте только в крайних случаях, когда команда временно не готова адаптировать вёрстку под 1280px.\n *\n * @remarks\n * При `true` компонент использует desktop-размеры для слотов и кнопки назад даже на viewport <= 1280px.\n * Это временный escape hatch, не основной сценарий использования.\n *\n * @default false\n */\n disableMediaAdaptive?: boolean;\n /**\n * Передача props в контейнер\n */\n containerProps?: ComponentProps<typeof Box>;\n /**\n * Callback при клике на кнопку со стрелкой назад слева от заголовка\n */\n onBackButtonClick?: () => void;\n};\n```\n\n## BlockTitleSlotSizesProps\n\n```typescript\ntype BlockTitleSlotSizesProps = {\n /**\n * Размер иконки рядом с заголовком\n */\n titleIconSize: 's' | 'xs';\n /**\n * Размер Badge рядом с заголовком\n */\n titleBadgeSize: 'm' | 's';\n /**\n * Размер кнопок в правом слоте\n */\n buttonSize: 's' | 'xs';\n /**\n * Размер иконок внутри кнопок в правом слоте\n */\n actionIconSize: 's' | 'xs';\n};\n```\n\n## BlockTitleAdaptiveSlot\n\n```typescript\ntype BlockTitleAdaptiveSlot =\n | ReactNode\n | ((props: BlockTitleSlotSizesProps) => ReactNode);\n```",
2955
+ "docs": "# BlockTitle\n\nКомпонент заголовка блока с поддержкой слотов для дополнительных элементов и кнопки «назад».\n\n## Ключевые особенности\n\n- Настраиваемый размер заголовка через вариант типографики (`titleSize`)\n- Описание под заголовком (`description`)\n- Слоты: `titleLeftSlot`, `titleRightSlot`, `topSlot`, `rightSlot`\n- Настройка тултипа обрезанного заголовка (ширина, позиция) через `titleTooltipProps`\n- Кнопка «назад» через `onBackButtonClick`\n- Кастомизация контейнера через `containerProps` (Box с `$css`)\n\n## Особенности\n\n- Компонент можно стилизовать: обернув в `styled`, используя `$css` в `containerProps`, или используя объект `blockTitleClassNames` для обращения к подэлементам\n- Слоты `titleLeftSlot`, `titleRightSlot`, `topSlot`, `rightSlot` принимают `ReactNode` или callback с размерами для адаптива\n- По умолчанию адаптив на viewport `<= 1280px` включен; временно отключить его можно через deprecated-проп `disableMediaAdaptive`\n\n## Тултип заголовка\n\n`title` оборачивается в `TypographyWithAutoTooltip`: если текст не помещается в две строки, при наведении показывается тултип с полным заголовком. По умолчанию ширина тултипа не ограничена, поэтому длинный заголовок вытягивается в одну строку. Ограничить ширину и задать позицию можно через `titleTooltipProps`:\n\n```tsx\n<BlockTitle\n title=\"Очень длинный заголовок страницы\"\n titleTooltipProps={{ maxWidth: '300px', placement: 'bottom-start' }}\n/>\n```\n\n`titleTooltipProps` принимает пропсы `Tooltip` (кроме `text`, `target`, `trigger`, `opened`, которыми управляет сам компонент): `maxWidth`, `minWidth`, `placement`, `view`, `offset`, `mouseEnterDelay` и другие.\n\n## Использование адаптивных слотов\n\nЕсли слот не должен менять размеры, передавайте обычный `ReactNode`:\n\n```tsx\n<BlockTitle title=\"Title\" titleRightSlot={<IconPlasma size=\"s\" />} />\n```\n\nЕсли в слоте есть иконка, Badge или кнопки, передавайте callback и используйте размеры из аргумента:\n\n```tsx\n<BlockTitle\n title=\"Страница\"\n titleSize=\"H4\"\n titleRightSlot={({ titleBadgeSize }) => (\n <Badge size={titleBadgeSize} view=\"default\" text=\"Label\" />\n )}\n rightSlot={({ buttonSize, actionIconSize }) => (\n <div style={{ display: 'flex', gap: s.x4 }}>\n <IconButton size={buttonSize} view=\"secondary\">\n <IconDotsVerticalCenteredOutline\n size={actionIconSize}\n color=\"inherit\"\n />\n </IconButton>\n <Button size={buttonSize} view=\"secondary\">\n Label\n </Button>\n <Button size={buttonSize} view=\"accent\">\n Label\n </Button>\n </div>\n )}\n/>\n```\n\nРазмеры, которые приходят в callback (в зависимости от viewport):\n\n```\n| Поле | <= 1280px | > 1280px |\n| -------------------------------------------- | --------- | -------- |\n| buttonSize | xs | s |\n| actionIconSize | xs | s |\n| titleIconSize (для H4/H5) | xs | s |\n| titleBadgeSize (для H4/H5) | s | m |\n| titleIconSize (для остальных) | s | s |\n| titleBadgeSize (для остальных) | m | m |\n```\n\n> Подробнее о типах и пропсах — [BlockTitle API](?path=/docs/композиции-blocktitle-api--docs)",
2956
+ "apiDocs": "# BlockTitle API\n\n## BlockTitleProps\n\n```typescript\ntype BlockTitleProps = {\n /**\n * Текст заголовка\n */\n title?: string;\n /**\n * Размер заголовка\n */\n titleSize?: ComponentProps<typeof Typography>['variant'];\n /**\n * Пропсы тултипа, которым оборачивается обрезанный `title`.\n *\n * @remarks\n * Тултип показывается автоматически, когда `title` не помещается в две строки.\n * По умолчанию ширина тултипа не ограничена, из-за чего длинный заголовок\n * растягивается в одну строку — ограничьте её через `maxWidth`.\n *\n * @example\n * ```tsx\n * <BlockTitle\n * title=\"Очень длинный заголовок\"\n * titleTooltipProps={{ maxWidth: '300px', placement: 'auto-start' }}\n * />\n * ```\n */\n titleTooltipProps?: TypographyWithAutoTooltipProps<'H2'>['tooltipProps'];\n /**\n * Иконка слева от заголовка (обычно используется иконка)\n */\n titleLeftSlot?: BlockTitleAdaptiveSlot;\n /**\n * Иконка справа от заголовка (обычно используется иконка)\n */\n titleRightSlot?: BlockTitleAdaptiveSlot;\n /**\n * Текст Заголовка\n */\n description?: string;\n /**\n * Слот для верхней части\n */\n topSlot?: BlockTitleAdaptiveSlot;\n /**\n * Слот для правой части\n */\n rightSlot?: BlockTitleAdaptiveSlot;\n /**\n * Отключает принудительный адаптив компонента на viewport <= 1280px.\n *\n * @deprecated Используйте только в крайних случаях, когда команда временно не готова адаптировать вёрстку под 1280px.\n *\n * @remarks\n * При `true` компонент использует desktop-размеры для слотов и кнопки назад даже на viewport <= 1280px.\n * Это временный escape hatch, не основной сценарий использования.\n *\n * @default false\n */\n disableMediaAdaptive?: boolean;\n /**\n * Передача props в контейнер\n */\n containerProps?: ComponentProps<typeof Box>;\n /**\n * Callback при клике на кнопку со стрелкой назад слева от заголовка\n */\n onBackButtonClick?: () => void;\n};\n```\n\n## BlockTitleSlotSizesProps\n\n```typescript\ntype BlockTitleSlotSizesProps = {\n /**\n * Размер иконки рядом с заголовком\n */\n titleIconSize: 's' | 'xs';\n /**\n * Размер Badge рядом с заголовком\n */\n titleBadgeSize: 'm' | 's';\n /**\n * Размер кнопок в правом слоте\n */\n buttonSize: 's' | 'xs';\n /**\n * Размер иконок внутри кнопок в правом слоте\n */\n actionIconSize: 's' | 'xs';\n};\n```\n\n## BlockTitleAdaptiveSlot\n\n```typescript\ntype BlockTitleAdaptiveSlot =\n | ReactNode\n | ((props: BlockTitleSlotSizesProps) => ReactNode);\n```",
2951
2957
  "curatedStories": [
2952
2958
  {
2953
2959
  "exportName": "BlockTitleSlots",
@@ -2978,6 +2984,12 @@
2978
2984
  "displayName": "BlockTitle с кнопкой назад и иконкой",
2979
2985
  "type": "full-code",
2980
2986
  "code": "import { useState } from 'react';\n import {\n Box,\n Button,\n IconButton,\n BlockTitle,\n type BlockTitleSlotSizesProps\n } from '@daisforge/ui';\n import { br, s } from '@daisforge/ui/constants';\n\n() => (\n <div\n style={{\n height: '100vh',\n padding: '20px',\n display: 'flex',\n backgroundColor: lightBackgroundPrimary,\n }}\n >\n <LeftPanelBlock />\n <div\n style={{\n flex: 1,\n padding: s.x8,\n boxShadow: shadowDownSoftS,\n backgroundColor: surfaceSolidCard,\n borderRadius: s.x8,\n }}\n >\n <BlockTitle\n title=\"Title\"\n description=\"Description\"\n // eslint-disable-next-line no-alert\n onBackButtonClick={() => alert('onBackClick')}\n titleRightSlot={({ titleIconSize }: BlockTitleSlotSizesProps) => (\n <IconPlasma size={titleIconSize} />\n )}\n rightSlot={renderRightActionsSlot}\n />\n </div>\n </div>\n )"
2987
+ },
2988
+ {
2989
+ "exportName": "BlockTitleWithTooltipProps",
2990
+ "displayName": "BlockTitle с настройкой тултипа заголовка",
2991
+ "type": "full-code",
2992
+ "code": "import { useState } from 'react';\n import {\n Box,\n Button,\n IconButton,\n BlockTitle,\n type BlockTitleSlotSizesProps\n } from '@daisforge/ui';\n import { br, s } from '@daisforge/ui/constants';\n\n() => (\n <div\n style={{\n height: '100vh',\n padding: '20px',\n display: 'flex',\n backgroundColor: lightBackgroundPrimary,\n }}\n >\n <LeftPanelBlock />\n <div\n style={{\n flex: 1,\n padding: s.x8,\n boxShadow: shadowDownSoftS,\n backgroundColor: surfaceSolidCard,\n borderRadius: s.x8,\n }}\n >\n <BlockTitle\n title={longTitle}\n description=\"Наведите на заголовок — тултип ограничен по ширине и раскрывается вниз\"\n /* Ограничиваем ширину тултипа и задаём его позицию */\n titleTooltipProps={{ maxWidth: '300px', placement: 'bottom-start' }}\n rightSlot={renderRightActionsSlot}\n />\n </div>\n </div>\n )"
2981
2993
  }
2982
2994
  ],
2983
2995
  "hasCuratedMeta": true,
@@ -5856,6 +5868,12 @@
5856
5868
  "role": "primary",
5857
5869
  "description": "Поле ввода одноразового OTP-кода с подписью и обработкой ошибок",
5858
5870
  "props": [
5871
+ {
5872
+ "name": "enableWebOTP",
5873
+ "type": "boolean | undefined",
5874
+ "required": false,
5875
+ "description": ""
5876
+ },
5859
5877
  {
5860
5878
  "name": "autoComplete",
5861
5879
  "type": "React.HTMLInputAutoCompleteAttribute | undefined",
@@ -6946,10 +6964,10 @@
6946
6964
  },
6947
6965
  {
6948
6966
  "exportName": "Usage2",
6949
- "displayName": "Использование в TooltipList.stories.tsx",
6967
+ "displayName": "Использование в TableCanvas.filtering.stories.tsx",
6950
6968
  "type": "usage",
6951
- "code": "<Combobox\n size=\"s\"\n multiple\n value={selectedValues}\n onChange={setSelectedValues}\n items={mockOptions}\n placeholder=\"Выберите блоки\"\n style={{ width: '100%' }}\n />",
6952
- "sourceFile": "packages/storybook/src/stories/TooltipList/TooltipList.stories.tsx"
6969
+ "code": "<Combobox\n multiple\n size=\"s\"\n items={sidebarIssueTypeOptions}\n value={draftValue}\n onChange={(next: string[]) => setDraftValue(next)}\n closeAfterSelect={false}\n placeholder=\"Выберите Issue Type\"\n afterList={\n <Box $css=\"display: grid; gap: 4px; margin-top: 4px;\">\n <Divider />\n <Button\n size=\"xs\"\n view=\"accent\"\n style={{ marginLeft: 'auto' }}\n onClick={() =>\n setFilters((prev) => ({\n ...prev,\n issueTypeCustom: draftValue,\n }))\n }\n >\n Применить\n </Button>\n </Box>\n }\n />",
6970
+ "sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.Filtering/TableCanvas.filtering.stories.tsx"
6953
6971
  },
6954
6972
  {
6955
6973
  "exportName": "Vendor1",
@@ -8349,6 +8367,12 @@
8349
8367
  "required": false,
8350
8368
  "description": "Обработчик изменения отображаемых месяца или года при навигации по календарю."
8351
8369
  },
8370
+ {
8371
+ "name": "hasTimeFormat",
8372
+ "type": "boolean | undefined",
8373
+ "required": false,
8374
+ "description": ""
8375
+ },
8352
8376
  {
8353
8377
  "name": "enterKeyHint",
8354
8378
  "type": "\"search\" | \"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"send\" | undefined",
@@ -28532,6 +28556,133 @@
28532
28556
  }
28533
28557
  ]
28534
28558
  },
28559
+ "TableFilterSelect": {
28560
+ "name": "TableFilterSelect",
28561
+ "group": "components",
28562
+ "folderName": "TableCanvas",
28563
+ "role": "primary",
28564
+ "description": "",
28565
+ "props": [
28566
+ {
28567
+ "name": "onChange",
28568
+ "type": "((v: string) => void) | ((v: string[]) => void)",
28569
+ "required": true,
28570
+ "description": ""
28571
+ },
28572
+ {
28573
+ "name": "options",
28574
+ "type": "{ text: string; value: string; }[]",
28575
+ "required": true,
28576
+ "description": ""
28577
+ },
28578
+ {
28579
+ "name": "value",
28580
+ "type": "string | string[]",
28581
+ "required": true,
28582
+ "description": ""
28583
+ },
28584
+ {
28585
+ "name": "afterList",
28586
+ "type": "React.ReactNode",
28587
+ "required": false,
28588
+ "description": ""
28589
+ },
28590
+ {
28591
+ "name": "beforeList",
28592
+ "type": "React.ReactNode",
28593
+ "required": false,
28594
+ "description": ""
28595
+ },
28596
+ {
28597
+ "name": "listMaxHeight",
28598
+ "type": "string | undefined",
28599
+ "required": false,
28600
+ "description": "",
28601
+ "default": "'360px'"
28602
+ },
28603
+ {
28604
+ "name": "mode",
28605
+ "type": "\"multiple\" | \"single\" | undefined",
28606
+ "required": false,
28607
+ "description": "",
28608
+ "default": "'single'"
28609
+ },
28610
+ {
28611
+ "name": "size",
28612
+ "type": "\"big\" | \"small\" | \"medium\" | undefined",
28613
+ "required": false,
28614
+ "description": "",
28615
+ "default": "'medium'"
28616
+ },
28617
+ {
28618
+ "name": "width",
28619
+ "type": "string | undefined",
28620
+ "required": false,
28621
+ "description": ""
28622
+ }
28623
+ ],
28624
+ "propsTypeName": "TableFilterSelectProps",
28625
+ "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-filtering/combobox/combobox.tsx",
28626
+ "type": "composition",
28627
+ "relatedExports": [
28628
+ "SplitIconButton",
28629
+ "CellEditorCombobox",
28630
+ "CellEditorNumberFormat",
28631
+ "CellEditorTextArea",
28632
+ "TableFilterSelectListItem",
28633
+ "ContainerStyled",
28634
+ "TextCellEntry",
28635
+ "Canvas",
28636
+ "TextCellEntryType"
28637
+ ],
28638
+ "atomicMcpVersion": "0.355.0",
28639
+ "importPath": "@daisforge/ui/components/TableCanvas",
28640
+ "importStatement": "import { TableFilterSelect } from '@daisforge/ui/components/TableCanvas';",
28641
+ "minimalUsage": "<TableFilterSelect onChange={() => {}} options={[]} value={[]} />",
28642
+ "examples": [
28643
+ {
28644
+ "exportName": "Usage",
28645
+ "displayName": "Использование в TableCanvas.filtering.stories.tsx",
28646
+ "type": "usage",
28647
+ "code": "<TableFilterSelect\n mode=\"multiple\"\n value={draftValue}\n onChange={setDraftValue}\n options={issueTypeOptions}\n size={rowSize}\n width=\"232px\"\n beforeList={\n <TableFilterSelectListItem $size={rowSize}>\n Произвольный вспомогательный элемент заголовка списка с\n подсказкой\n </TableFilterSelectListItem>\n }\n afterList={\n <Box\n $css={`position: sticky; bottom: 0; background-color: white; display: grid; gap: ${\n rowSize === 'big' ? '4px' : '4px'\n }; margin-top: 4px;`}\n >\n <Divider />\n <Button\n size={rowSize === 'small' ? 'xxs' : 's'}\n style={{ marginLeft: 'auto ' }}\n view=\"accent\"\n onClick={apply}\n >\n Применить\n </Button>\n </Box>\n }\n />",
28648
+ "sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.Filtering/TableCanvas.filtering.stories.tsx"
28649
+ }
28650
+ ]
28651
+ },
28652
+ "TableFilterSelectList": {
28653
+ "name": "TableFilterSelectList",
28654
+ "group": "components",
28655
+ "folderName": "TableCanvas",
28656
+ "role": "primary",
28657
+ "description": "",
28658
+ "props": [
28659
+ {
28660
+ "name": "as",
28661
+ "type": "string | React.ComponentType<any> | undefined",
28662
+ "required": false,
28663
+ "description": ""
28664
+ }
28665
+ ],
28666
+ "propsTypeName": "ComponentProps<typeof TableFilterSelectList>",
28667
+ "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-filtering/combobox/styled.ts",
28668
+ "type": "composition",
28669
+ "relatedExports": [
28670
+ "SplitIconButton",
28671
+ "CellEditorCombobox",
28672
+ "CellEditorNumberFormat",
28673
+ "CellEditorTextArea",
28674
+ "TableFilterSelectListItem",
28675
+ "ContainerStyled",
28676
+ "TextCellEntry",
28677
+ "Canvas",
28678
+ "TextCellEntryType"
28679
+ ],
28680
+ "atomicMcpVersion": "0.355.0",
28681
+ "importPath": "@daisforge/ui/components/TableCanvas",
28682
+ "importStatement": "import { TableFilterSelectList } from '@daisforge/ui/components/TableCanvas';",
28683
+ "minimalUsage": "<TableFilterSelectList />",
28684
+ "examples": []
28685
+ },
28535
28686
  "TableFilterSelectListItem": {
28536
28687
  "name": "TableFilterSelectListItem",
28537
28688
  "group": "components",
@@ -28563,14 +28714,89 @@
28563
28714
  "minimalUsage": "<TableFilterSelectListItem />",
28564
28715
  "examples": [
28565
28716
  {
28566
- "exportName": "Usage",
28717
+ "exportName": "Usage1",
28567
28718
  "displayName": "Использование в TableCanvas.multipleFeatures.stories.tsx",
28568
28719
  "type": "usage",
28569
28720
  "code": "<TableFilterSelectListItem\n $size={props.headerContextState.rowSize}\n >\n custom beforeList\n </TableFilterSelectListItem>",
28570
28721
  "sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.MultipleFeatures/TableCanvas.multipleFeatures.stories.tsx"
28722
+ },
28723
+ {
28724
+ "exportName": "Usage2",
28725
+ "displayName": "Использование в TableCanvas.filtering.stories.tsx",
28726
+ "type": "usage",
28727
+ "code": "<TableFilterSelectListItem $size={rowSize}>\n Произвольный вспомогательный элемент заголовка списка с\n подсказкой\n </TableFilterSelectListItem>",
28728
+ "sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.Filtering/TableCanvas.filtering.stories.tsx"
28571
28729
  }
28572
28730
  ]
28573
28731
  },
28732
+ "TableFilterSelectSearchTextfield": {
28733
+ "name": "TableFilterSelectSearchTextfield",
28734
+ "group": "components",
28735
+ "folderName": "TableCanvas",
28736
+ "role": "primary",
28737
+ "description": "",
28738
+ "props": [
28739
+ {
28740
+ "name": "as",
28741
+ "type": "string | React.ComponentType<any> | undefined",
28742
+ "required": false,
28743
+ "description": ""
28744
+ }
28745
+ ],
28746
+ "propsTypeName": "ComponentProps<typeof TableFilterSelectSearchTextfield>",
28747
+ "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-filtering/combobox/styled.ts",
28748
+ "type": "composition",
28749
+ "relatedExports": [
28750
+ "SplitIconButton",
28751
+ "CellEditorCombobox",
28752
+ "CellEditorNumberFormat",
28753
+ "CellEditorTextArea",
28754
+ "TableFilterSelectListItem",
28755
+ "ContainerStyled",
28756
+ "TextCellEntry",
28757
+ "Canvas",
28758
+ "TextCellEntryType"
28759
+ ],
28760
+ "atomicMcpVersion": "0.355.0",
28761
+ "importPath": "@daisforge/ui/components/TableCanvas",
28762
+ "importStatement": "import { TableFilterSelectSearchTextfield } from '@daisforge/ui/components/TableCanvas';",
28763
+ "minimalUsage": "<TableFilterSelectSearchTextfield />",
28764
+ "examples": []
28765
+ },
28766
+ "TableFilterSelectTotalListItemContainer": {
28767
+ "name": "TableFilterSelectTotalListItemContainer",
28768
+ "group": "components",
28769
+ "folderName": "TableCanvas",
28770
+ "role": "primary",
28771
+ "description": "",
28772
+ "props": [
28773
+ {
28774
+ "name": "as",
28775
+ "type": "string | React.ComponentType<any> | undefined",
28776
+ "required": false,
28777
+ "description": ""
28778
+ }
28779
+ ],
28780
+ "propsTypeName": "ComponentProps<typeof TableFilterSelectTotalListItemContainer>",
28781
+ "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-filtering/combobox/styled.ts",
28782
+ "type": "composition",
28783
+ "relatedExports": [
28784
+ "SplitIconButton",
28785
+ "CellEditorCombobox",
28786
+ "CellEditorNumberFormat",
28787
+ "CellEditorTextArea",
28788
+ "TableFilterSelectListItem",
28789
+ "ContainerStyled",
28790
+ "TextCellEntry",
28791
+ "Canvas",
28792
+ "TextCellEntryType"
28793
+ ],
28794
+ "atomicMcpVersion": "0.355.0",
28795
+ "importPath": "@daisforge/ui/components/TableCanvas",
28796
+ "importStatement": "import { TableFilterSelectTotalListItemContainer } from '@daisforge/ui/components/TableCanvas';",
28797
+ "minimalUsage": "<TableFilterSelectTotalListItemContainer />",
28798
+ "examples": []
28799
+ },
28574
28800
  "Table": {
28575
28801
  "name": "Table",
28576
28802
  "group": "components",
@@ -28647,7 +28873,7 @@
28647
28873
  "react-data-grid"
28648
28874
  ],
28649
28875
  "docs": "# Table\n\n`Table` - legacy HTML-таблица на базе `react-data-grid` и `react-table`-подходов, которая поддерживается для существующих продуктов. Для новых таблиц по умолчанию используйте `TableCanvas`.\n\n## Ключевые особенности\n\n- Отображение строк и колонок через `rows`, `columnConfig` и `tableConfig`\n- Сортировка, фильтрация, поиск, пагинация и infinity scroll\n- Выбор строк, вложенные строки, группировка строк и группировка колонок\n- Настройка колонок, изменение ширины, кастомный render ячеек и итоговые строки\n- ControlBlock, sidebar, context menu, row instruments и состояния загрузки/пустых данных\n\n## Legacy-статус\n\n`Table` оставлен для поддержки проектов, которые уже используют HTML-таблицу. Если задача не требует совместимости с legacy API, выбирайте `TableCanvas`: он является основной таблицей библиотеки и лучше подходит для больших данных, canvas-render и новых сценариев.\n\n## Основные сущности\n\n- `TableProps` - публичные props компонента\n- `TableConfig` - конфигурация фич таблицы\n- `ColumnConfig` - конфигурация колонок, render-ов, сортировки, фильтрации и редактирования\n\nОписание типов - в разделе [API](?path=/docs/локальные-компоненты-table-api--docs).",
28650
- "apiDocs": "# Table API\n\n## TableProps\n\n```typescript\ntype TableProps<\n FilterStateType extends ObjectForExtending,\n RowIdType extends string | number,\n HeaderContextValueType extends ObjectForExtending,\n RowContextValueType extends ObjectForExtending,\n RowType extends ObjectForExtending,\n SummaryRowType = unknown,\n> = {\n /**\n * columnConfig - Конфигурация колонок.\n *\n * (рекомендуется минимальное количество зависимостей для данной сущности - в идеале, чтобы не пересоздавался)\n */\n columnConfig: readonly ColumnConfig<RowType, SummaryRowType>[];\n /**\n * rows - данные для таблицы. ```RowType extends Record<string | number, any>```\n */\n rows: RowType[];\n /**\n * topSummaryRows - данные для итоговой строки в верхней части таблицы. ```SummaryRowType[]```\n */\n topSummaryRows?: SummaryRowType[];\n /**\n * rows - данные для итоговой строки в нижней части таблицы. ```SummaryRowType[]```\n */\n bottomSummaryRows?: SummaryRowType[];\n /**\n * tableConfig - Конфигурация фичей таблицы (их активация и отключение)\n */\n tableConfig?: Prettify<\n TableConfig<RowType, SummaryRowType, RowIdType, FilterStateType>\n >;\n /**\n * headerContextValue: любые стейты, которые нужны в headerCell - кладем в headerContextValue. И получаем доступ с помощью useHeaderContext.\n */\n headerContextValue?: HeaderContextValueType;\n /**\n * rowContextValue: любые стейты, которые нужны в cell - кладем в rowContextValue. И получаем доступ с помощью useRowContext.\n */\n rowContextValue?: RowContextValueType;\n refTable?: Ref<DataGridHandle>;\n refTableContainer?: React.Ref<HTMLDivElement>;\n};\n```\n\n## TableConfig\n\n```typescript\ntype TableConfig<\n RowType extends ObjectForExtending,\n SummaryRowType,\n RowIdType extends string | number,\n FilterStateType extends ObjectForExtending,\n // SubRowType\n> = {\n /**\n * Тип выделения активной (кликнутой) сущности `'cell' | 'row'`\n * @default 'cell'\n */\n highlightActiveType?: HighlightActiveType;\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 } & 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 * subRows - активация иерархии, отображения вложенных строк. Условие активации - наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={subRows: {getSubRows, rowKeyGetter}}\n *\n * columnConfig=[{subRow: {...}}]\n */\n subRows?: SubRows<RowType, RowIdType>;\n rowsGrouping?: RowsGrouping<RowType>;\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 * infinityScroll - бесконечная подгрузка данных при скролле.\n *\n * Условие активации - наличие самого пропса infinityScroll.\n *\n * При активации infinityScroll отключается дефолтная сортировка и фильтрация.\n * (Предполагается, что если есть infinityScroll,\n * то в таблице представлен не весь объем данных,\n * по этой причине дефолтная сортировка и фильтрация не подходят и будут отображать некорректные данные)\n *\n */\n infinityScroll?: {\n onTrigger: (rows: RowType[]) => Promise<void> | void;\n isLoading: boolean;\n /**\n * @default true\n */\n hasMore?: boolean;\n /**\n * @default 100 (px)\n */\n scrollThreshold?: number;\n };\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 noRowsFallback?: boolean | { custom: ReactNode };\n columnsControl?: ColumnsControlConfig;\n rowDetailPanel?: RowDetailConfig<RowType>;\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 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 - пропс для активации открытия контекстного меню.\n *\n */\n onHeaderContextMenu?: HeaderContextMenuProps;\n onHeaderContextMenuDropDown?: HeaderContextMenuDropDownProps;\n onCellContextMenuDropDown?: CellContextMenuDropDownProps<\n RowType,\n 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## ColumnConfig\n\n```typescript\ntype ColumnConfig<\n Row extends ObjectForExtending,\n SummRow = unknown,\n> = ColumnDefaultOmitted<Row, SummRow> & {\n /**\n * Если в поле name был передан jsx, то нужно заполнить nameAsString для указания label в разделе Настройки столбцов, либо для отображения label в фильтрах в правом сайдбаре (но приоритет для фильтро будет ниже, чем то, что указали в filtering.sidebarConfig.items, там отдельно можно перезаписать label для фильтров сайдабара)\n */\n nameAsString?: string;\n sortingType?: 'stringSort' | 'numberSort' | Comparator<Row>;\n searching?: {\n valueInRow: (row: Row) => string | number;\n };\n filtering?: {\n keyInFilterState: string;\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n valueInRow?: (row: Row) => string | number;\n /**\n * ```FilterCb - (filterValue: string, rowValue: string) => boolean```\n */\n } & (\n | {\n component: 'input';\n filter: 'includes' | 'startWith' | 'equal' | FilterCb<'single'>;\n }\n | {\n component: 'select';\n beforeList?: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter:\n | {\n typeOfValue: 'single';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'single'>;\n }\n | {\n typeOfValue: 'multiple';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'multiple'>;\n };\n selectOptions:\n | {\n type: 'constant';\n options: SelectOptions[];\n }\n | {\n type: 'stateInHeaderContext';\n /**\n * тип optionsState, который будет в HeaderContext:\n * ```ts\n * {\n * value: string | number;\n * text: string | number;\n * }[];\n * ```\n */\n optionsKeyInHeaderContext: string;\n };\n /**\n * Максимальна высота выпадающего списка в фильтрах колонок / правом сайдбаре.\n * @default \"360px\"\n */\n listMaxHeight?: string;\n }\n | {\n component: 'custom';\n customRender: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter?: (filterValue: unknown, rowValue: unknown) => boolean;\n compareWithClearedValue?: (\n clearedValue: unknown,\n currV: unknown,\n ) => boolean;\n }\n );\n\n contentFormat?: ContentFormat;\n\n editingCell?: Editing<Row>;\n\n subRow?: {\n /**\n * @default false\n */\n isColumnWithArrow?: boolean | ((props: { keyText: KeyText }) => boolean);\n /**\n * @default false\n */\n hideHeaderExpandAllArrow?: boolean;\n /**\n * @default false\n */\n parentKeyAsDefault?: boolean;\n /**\n * @default undefined\n */\n contentFormat?: ContentFormat;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n renderSubRowCell?: RenderSubRowCell<any>;\n } & (\n | {\n keyOfColumnInSubRow:\n | string\n | number\n | ((lvl: number) => string | number);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n editingCell: Editing<any>;\n }\n | {\n editingCell?: undefined;\n keyOfColumnInSubRow?:\n | string\n | number\n | ((lvl: number) => string | number);\n }\n );\n rowsGrouping?: ColumnRowsGrouping<Row, SummRow>;\n keyText?: KeyTextColumnConfig<Row, SummRow>;\n};\n```",
28876
+ "apiDocs": "# Table API\n\n## TableProps\n\n```typescript\ntype TableProps<\n FilterStateType extends ObjectForExtending,\n RowIdType extends string | number,\n HeaderContextValueType extends ObjectForExtending,\n RowContextValueType extends ObjectForExtending,\n RowType extends ObjectForExtending,\n SummaryRowType = unknown,\n> = {\n /**\n * columnConfig - Конфигурация колонок.\n *\n * (рекомендуется минимальное количество зависимостей для данной сущности - в идеале, чтобы не пересоздавался)\n */\n columnConfig: readonly ColumnConfig<RowType, SummaryRowType>[];\n /**\n * rows - данные для таблицы. ```RowType extends Record<string | number, any>```\n */\n rows: RowType[];\n /**\n * topSummaryRows - данные для итоговой строки в верхней части таблицы. ```SummaryRowType[]```\n */\n topSummaryRows?: SummaryRowType[];\n /**\n * rows - данные для итоговой строки в нижней части таблицы. ```SummaryRowType[]```\n */\n bottomSummaryRows?: SummaryRowType[];\n /**\n * tableConfig - Конфигурация фичей таблицы (их активация и отключение)\n */\n tableConfig?: Prettify<\n TableConfig<RowType, SummaryRowType, RowIdType, FilterStateType>\n >;\n /**\n * headerContextValue: любые стейты, которые нужны в headerCell - кладем в headerContextValue. И получаем доступ с помощью useHeaderContext.\n */\n headerContextValue?: HeaderContextValueType;\n /**\n * rowContextValue: любые стейты, которые нужны в cell - кладем в rowContextValue. И получаем доступ с помощью useRowContext.\n */\n rowContextValue?: RowContextValueType;\n refTable?: Ref<DataGridHandle>;\n refTableContainer?: React.Ref<HTMLDivElement>;\n};\n```\n\n## TableConfig\n\n```typescript\ntype TableConfig<\n RowType extends ObjectForExtending,\n SummaryRowType,\n RowIdType extends string | number,\n FilterStateType extends ObjectForExtending,\n // SubRowType\n> = {\n /**\n * Тип выделения активной (кликнутой) сущности `'cell' | 'row'`\n * @default 'cell'\n */\n highlightActiveType?: HighlightActiveType;\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 } & 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 * subRows - активация иерархии, отображения вложенных строк. Условие активации - наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={subRows: {getSubRows, rowKeyGetter}}\n *\n * columnConfig=[{subRow: {...}}]\n */\n subRows?: SubRows<RowType, RowIdType>;\n rowsGrouping?: RowsGrouping<RowType>;\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 * infinityScroll - бесконечная подгрузка данных при скролле.\n *\n * Условие активации - наличие самого пропса infinityScroll.\n *\n * При активации infinityScroll отключается дефолтная сортировка и фильтрация.\n * (Предполагается, что если есть infinityScroll,\n * то в таблице представлен не весь объем данных,\n * по этой причине дефолтная сортировка и фильтрация не подходят и будут отображать некорректные данные)\n *\n */\n infinityScroll?: {\n onTrigger: (rows: RowType[]) => Promise<void> | void;\n isLoading: boolean;\n /**\n * @default true\n */\n hasMore?: boolean;\n /**\n * @default 100 (px)\n */\n scrollThreshold?: number;\n };\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 noRowsFallback?: boolean | { custom: ReactNode };\n columnsControl?: ColumnsControlConfig;\n rowDetailPanel?: RowDetailConfig<RowType>;\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 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 - пропс для активации открытия контекстного меню.\n *\n */\n onHeaderContextMenu?: HeaderContextMenuProps;\n onHeaderContextMenuDropDown?: HeaderContextMenuDropDownProps;\n onCellContextMenuDropDown?: CellContextMenuDropDownProps<\n RowType,\n 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## ColumnConfig\n\n```typescript\ntype ColumnConfig<\n Row extends ObjectForExtending,\n SummRow = unknown,\n> = ColumnDefaultOmitted<Row, SummRow> & {\n /**\n * Если в поле name был передан jsx, то нужно заполнить nameAsString для указания label в разделе Настройки столбцов, либо для отображения label в фильтрах в правом сайдбаре (но приоритет для фильтро будет ниже, чем то, что указали в filtering.sidebarConfig.items, там отдельно можно перезаписать label для фильтров сайдабара)\n */\n nameAsString?: string;\n sortingType?: 'stringSort' | 'numberSort' | Comparator<Row>;\n searching?: {\n valueInRow: (row: Row) => string | number;\n };\n filtering?: {\n keyInFilterState: string;\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n valueInRow?: (row: Row) => string | number;\n /**\n * ```FilterCb - (filterValue: string, rowValue: string) => boolean```\n */\n } & (\n | {\n component: 'input';\n filter: 'includes' | 'startWith' | 'equal' | FilterCb<'single'>;\n }\n | {\n component: 'select';\n /**\n * Произвольное содержимое над списком опций фильтра.\n *\n * Рендерится и в поповере фильтра в шапке колонки, и в сайдбаре\n * фильтров. Рендерится как компонент, поэтому внутри можно\n * использовать хуки и локальное состояние.\n *\n * @example\n * beforeList: ({ headerContextState }) => (\n * <TableFilterSelectListItem $size={headerContextState.rowSize}>\n * Подсказка над списком\n * </TableFilterSelectListItem>\n * )\n */\n beforeList?: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n /**\n * Произвольное содержимое под списком опций фильтра.\n *\n * Рендерится и в поповере фильтра в шапке колонки, и в сайдбаре\n * фильтров. Рендерится как компонент, поэтому внутри можно\n * использовать хуки и локальное состояние — например, чтобы держать\n * черновик выбора и применять его по кнопке.\n *\n * @example\n * afterList: ({ headerContextState, setPopoverIsOpen }) => (\n * <TableFilterSelectListItem $size={headerContextState.rowSize}>\n * Подсказка под списком\n * </TableFilterSelectListItem>\n * )\n */\n afterList?: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter:\n | {\n typeOfValue: 'single';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'single'>;\n }\n | {\n typeOfValue: 'multiple';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'multiple'>;\n };\n selectOptions:\n | {\n type: 'constant';\n options: SelectOptions[];\n }\n | {\n type: 'stateInHeaderContext';\n /**\n * тип optionsState, который будет в HeaderContext:\n * ```ts\n * {\n * value: string | number;\n * text: string | number;\n * }[];\n * ```\n */\n optionsKeyInHeaderContext: string;\n };\n /**\n * Максимальна высота выпадающего списка в фильтрах колонок / правом сайдбаре.\n * @default \"360px\"\n */\n listMaxHeight?: string;\n }\n | {\n component: 'custom';\n customRender: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter?: (filterValue: unknown, rowValue: unknown) => boolean;\n compareWithClearedValue?: (\n clearedValue: unknown,\n currV: unknown,\n ) => boolean;\n }\n );\n\n contentFormat?: ContentFormat;\n\n editingCell?: Editing<Row>;\n\n subRow?: {\n /**\n * @default false\n */\n isColumnWithArrow?: boolean | ((props: { keyText: KeyText }) => boolean);\n /**\n * @default false\n */\n hideHeaderExpandAllArrow?: boolean;\n /**\n * @default false\n */\n parentKeyAsDefault?: boolean;\n /**\n * @default undefined\n */\n contentFormat?: ContentFormat;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n renderSubRowCell?: RenderSubRowCell<any>;\n } & (\n | {\n keyOfColumnInSubRow:\n | string\n | number\n | ((lvl: number) => string | number);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n editingCell: Editing<any>;\n }\n | {\n editingCell?: undefined;\n keyOfColumnInSubRow?:\n | string\n | number\n | ((lvl: number) => string | number);\n }\n );\n rowsGrouping?: ColumnRowsGrouping<Row, SummRow>;\n keyText?: KeyTextColumnConfig<Row, SummRow>;\n};\n```",
28651
28877
  "curatedStories": [
28652
28878
  {
28653
28879
  "exportName": "Docs",
@@ -30512,6 +30738,12 @@
30512
30738
  "required": false,
30513
30739
  "description": "Флаг fullscreen - пересканирование DOM при переключении"
30514
30740
  },
30741
+ {
30742
+ "name": "getCellBorder",
30743
+ "type": "CellBorderResolver | undefined",
30744
+ "required": false,
30745
+ "description": "Настройка рамок отдельных ячеек: стороны top, right, bottom, left,\nвкл/выкл и цвет. Перекрывает `verticalBorder`, `horizontalBorder` и тему.\nЕсли не задано, линии рисуются сплошными без разбивки по ячейкам.\nrow и col приходят в пользовательских индексах, без служебных колонок."
30746
+ },
30515
30747
  {
30516
30748
  "name": "getCellsForSelection",
30517
30749
  "type": "true | ((selection: Rectangle, abortSignal: AbortSignal) => GetCellsThunk | CellArray) | undefined",
@@ -30591,6 +30823,12 @@
30591
30823
  "required": false,
30592
30824
  "description": "Highlight regions provide hints to users about relations between cells and selections."
30593
30825
  },
30826
+ {
30827
+ "name": "horizontalBorder",
30828
+ "type": "boolean | ((row: number) => boolean) | undefined",
30829
+ "required": false,
30830
+ "description": "Управление горизонтальной линией сверху строки. Функция `(row) => boolean` — точечно\nпо строкам, boolean — сразу для всех строк тела. Не задано — линии рисуются (как раньше)."
30831
+ },
30594
30832
  {
30595
30833
  "name": "hoverEffects",
30596
30834
  "type": "HoverEffectsConfig | undefined",
@@ -31913,6 +32151,12 @@
31913
32151
  "required": false,
31914
32152
  "description": "The number of columns which should remain in place when scrolling horizontally. The row marker column, if\nenabled is always frozen and is not included in this count."
31915
32153
  },
32154
+ {
32155
+ "name": "getCellBorder",
32156
+ "type": "CellBorderResolver | undefined",
32157
+ "required": false,
32158
+ "description": "Настройка рамок отдельных ячеек: стороны top, right, bottom, left,\nвкл/выкл и цвет. Перекрывает `verticalBorder`, `horizontalBorder` и тему.\nЕсли не задано, линии рисуются сплошными без разбивки по ячейкам.\nrow и col приходят в пользовательских индексах, без служебных колонок."
32159
+ },
31916
32160
  {
31917
32161
  "name": "getCellsForSelection",
31918
32162
  "type": "true | ((selection: Rectangle, abortSignal: AbortSignal) => GetCellsThunk | CellArray) | undefined",
@@ -31961,6 +32205,12 @@
31961
32205
  "required": false,
31962
32206
  "description": "Highlight regions provide hints to users about relations between cells and selections."
31963
32207
  },
32208
+ {
32209
+ "name": "horizontalBorder",
32210
+ "type": "boolean | ((row: number) => boolean) | undefined",
32211
+ "required": false,
32212
+ "description": "Управление горизонтальной линией сверху строки. Функция `(row) => boolean` — точечно\nпо строкам, boolean — сразу для всех строк тела. Не задано — линии рисуются (как раньше)."
32213
+ },
31964
32214
  {
31965
32215
  "name": "imageEditorOverride",
31966
32216
  "type": "ImageEditorType | undefined",
@@ -34185,6 +34435,12 @@
34185
34435
  "required": false,
34186
34436
  "description": "The number of columns which should remain in place when scrolling horizontally. The row marker column, if\nenabled is always frozen and is not included in this count."
34187
34437
  },
34438
+ {
34439
+ "name": "getCellBorder",
34440
+ "type": "CellBorderResolver | undefined",
34441
+ "required": false,
34442
+ "description": "Настройка рамок отдельных ячеек: стороны top, right, bottom, left,\nвкл/выкл и цвет. Перекрывает `verticalBorder`, `horizontalBorder` и тему.\nЕсли не задано, линии рисуются сплошными без разбивки по ячейкам.\nrow и col приходят в пользовательских индексах, без служебных колонок."
34443
+ },
34188
34444
  {
34189
34445
  "name": "getCellsForSelection",
34190
34446
  "type": "true | ((selection: Rectangle, abortSignal: AbortSignal) => GetCellsThunk | CellArray) | undefined",
@@ -34239,6 +34495,12 @@
34239
34495
  "required": false,
34240
34496
  "description": "Highlight regions provide hints to users about relations between cells and selections."
34241
34497
  },
34498
+ {
34499
+ "name": "horizontalBorder",
34500
+ "type": "boolean | ((row: number) => boolean) | undefined",
34501
+ "required": false,
34502
+ "description": "Управление горизонтальной линией сверху строки. Функция `(row) => boolean` — точечно\nпо строкам, boolean — сразу для всех строк тела. Не задано — линии рисуются (как раньше)."
34503
+ },
34242
34504
  {
34243
34505
  "name": "imageEditorOverride",
34244
34506
  "type": "ImageEditorType | undefined",
@@ -37185,7 +37447,14 @@
37185
37447
  "folderName": "TimePicker",
37186
37448
  "role": "primary",
37187
37449
  "description": "Поле ввода времени с масками часов/минут/секунд и ограничением диапазона.",
37188
- "props": [],
37450
+ "props": [
37451
+ {
37452
+ "name": "hasTimeFormat",
37453
+ "type": "boolean | undefined",
37454
+ "required": false,
37455
+ "description": ""
37456
+ }
37457
+ ],
37189
37458
  "propsTypeName": "TimePickerProps",
37190
37459
  "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/TimePicker/TimePicker.d.ts",
37191
37460
  "type": "wrapper",
@@ -52672,6 +52941,18 @@
52672
52941
  "type": "full-code",
52673
52942
  "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n const [rows] = useState(createRows);\n\n const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n () => [\n {\n key: 'id',\n name: 'ID',\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n renderCell(cellInfo) {\n return (\n <Canvas.Button\n id=\"header-tooltip-drag\"\n portalHoverEnabled\n onClick={() => {}}\n >\n 123\n </Canvas.Button>\n );\n },\n },\n {\n key: 'task',\n name: 'Title',\n },\n {\n key: 'priority',\n name: 'Priority',\n },\n {\n key: 'issueType',\n name: 'Issue Type',\n },\n {\n key: 'developer',\n name: 'Developer',\n },\n {\n key: 'tr1',\n name: 'TR',\n },\n {\n key: 'complete',\n name: '% Complete',\n },\n ],\n [],\n );\n\n return (\n <TableCanvas\n tableConfig={{\n containerStyle: { height: 700 },\n columnsControl: {\n enable: true,\n hiding: true,\n disableHiding: ['id'],\n pinning: true,\n disablePinning: ['developer'],\n reorderingAside: true,\n reorderingHeader: true,\n columnsLabel: {\n task: 'Задачи',\n },\n orderDefault: ['id', 'issueType', 'task'],\n hiddenDefault: ['tr1'],\n pinnedDefault: ['complete'],\n onConfirm: ({ order, hidden, pinned }, _setters) => {\n // eslint-disable-next-line no-alert\n alert(`\n order: ${order.join(', ')}\n pinned: ${pinned.join(', ')}\n hidden: ${hidden.join(', ')}\n `);\n },\n },\n }}\n columnConfig={columnConfig}\n rows={rows}\n />\n );\n }"
52674
52943
  },
52944
+ {
52945
+ "exportName": "ColumnsControlDynamicColumn",
52946
+ "displayName": "ColumnsControl: динамическое добавление колонки",
52947
+ "type": "full-code",
52948
+ "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n const [rows] = useState(createRows);\n const [developerIsShown, setDeveloperIsShown] = useState(false);\n\n const filteringStateAndSetter = useState({\n id: '',\n task: '',\n priority: 'All',\n issueType: [],\n complete: '',\n date: '',\n globalFilter: '',\n });\n const sortingStateAndSetter = useState<readonly SortColumn[]>([]);\n\n const themeOverride = useCallback<\n NonNullable<ColumnConfig<Row>['themeOverride']>\n >((cellInfo) => {\n if (cellInfo.hovered.rowHover) {\n return { bgCell: cellInfo.theme.bgHeader };\n }\n return {};\n }, []);\n\n const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n () => [\n {\n key: 'id',\n name: 'ID',\n themeOverride,\n },\n {\n key: 'task',\n name: 'Title',\n themeOverride,\n minWidth: 200,\n width: 250,\n },\n ...(developerIsShown\n ? [\n {\n key: 'developer',\n name: 'Developer',\n themeOverride,\n } satisfies ColumnConfig<Row>,\n ]\n : []),\n {\n key: 'priority',\n name: 'Priority',\n sortingType: 'stringSort',\n themeOverride,\n filtering: {\n component: 'select',\n selectOptions: {\n type: 'constant',\n options: [\n { value: 'All', text: 'All' },\n { value: 'High', text: 'High' },\n { value: 'Critical', text: 'Critical' },\n { value: 'Medium', text: 'Medium' },\n { value: 'Low', text: 'Low' },\n ],\n },\n keyInFilterState: 'priority',\n valueInRow: (r) => r.priority,\n filter: {\n typeOfValue: 'single',\n filteringType: (fv, rv) => (fv !== 'All' ? rv === fv : true),\n },\n },\n },\n {\n key: 'issueType',\n name: 'Issue Type',\n themeOverride,\n filtering: {\n component: 'input',\n filter: 'includes',\n valueInRow: (r) => `${r.task} ${r.id}`,\n keyInFilterState: 'task',\n },\n },\n {\n key: 'complete',\n name: '% Complete',\n themeOverride,\n },\n ],\n [developerIsShown, themeOverride],\n );\n\n return (\n <Box $css={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>\n <Box>\n <Button\n size=\"s\"\n view=\"secondary\"\n onClick={() => setDeveloperIsShown((prev) => !prev)}\n >\n {developerIsShown\n ? 'Удалить колонку Developer'\n : 'Добавить колонку Developer'}\n </Button>\n </Box>\n <TableCanvas\n tableConfig={{\n containerStyle: { height: '60vh' },\n highlightActiveType: 'row',\n columnsControl: {\n enable: true,\n hiding: true,\n pinning: true,\n reorderingAside: true,\n reorderingHeader: true,\n },\n filtering: {\n state: filteringStateAndSetter,\n filtersInfo: {\n id: { label: 'id', clearedValue: '' },\n task: { label: 'task', clearedValue: '' },\n priority: { label: 'Some Label', clearedValue: 'All' },\n issueType: { label: 'issueType', clearedValue: [] },\n complete: { label: 'complete', clearedValue: '' },\n date: { label: 'Дата', clearedValue: '' },\n globalFilter: { label: 'Global filter', clearedValue: '' },\n },\n },\n sorting: {\n state: sortingStateAndSetter,\n },\n }}\n columnConfig={columnConfig}\n rows={rows}\n />\n </Box>\n );\n }"
52949
+ },
52950
+ {
52951
+ "exportName": "SimpleTableDynamicColumn",
52952
+ "displayName": "SimpleTable: динамическое добавление колонки",
52953
+ "type": "full-code",
52954
+ "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n const [rows] = useState(createRows);\n const [isFavorite, setIsFavorite] = useState(true);\n const [developerIsShown, setDeveloperIsShown] = useState(false);\n\n const filteringStateAndSetter = useState({\n id: '',\n task: '',\n priority: 'All',\n issueType: [],\n complete: '',\n date: '',\n globalFilter: '',\n });\n const themeOverride = useCallback<\n NonNullable<ColumnConfig<Row>['themeOverride']>\n >((cellInfo) => {\n if (cellInfo.hovered.rowHover) {\n return { bgCell: cellInfo.theme.bgHeader };\n }\n return {};\n }, []);\n\n const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n () => [\n {\n key: 'id',\n name: 'id',\n themeOverride,\n renderHeaderCell: ({ theme }) => (\n <Canvas.Container\n direction=\"row\"\n alignItems=\"center\"\n gap={8}\n padding={{\n left: theme.cellHorizontalPadding,\n right: theme.cellHorizontalPadding,\n }}\n >\n <Canvas.Container position=\"relative\">\n <Canvas.Icon icon={<IconChevronCircleDownFill />} />\n <Canvas.Icon\n position=\"absolute\"\n top={-5}\n right={-5}\n icon={<IconBrightness0Fill color=\"#d70101\" size=\"xs\" />}\n />\n </Canvas.Container>\n <Canvas.Container position=\"relative\">\n <Canvas.Icon icon={<IconAddOutline />} />\n <Canvas.Icon\n position=\"absolute\"\n top={-5}\n right={-5}\n icon={<IconBrightness0Fill color=\"#d70101\" size=\"xs\" />}\n />\n </Canvas.Container>\n </Canvas.Container>\n ),\n renderCell: ({ theme }) => (\n <Canvas.Container\n direction=\"row\"\n alignItems=\"center\"\n justifyContent=\"space-between\"\n gap={8}\n padding={{\n left: theme.cellHorizontalPadding,\n right: theme.cellHorizontalPadding,\n }}\n >\n <Canvas.Container position=\"relative\">\n <Canvas.Icon icon={<IconChevronCircleDownFill />} />\n <Canvas.Icon\n position=\"absolute\"\n top={-5}\n right={-5}\n icon={<IconBrightness0Fill color=\"#d70101\" size=\"xs\" />}\n />\n </Canvas.Container>\n <Canvas.Container position=\"relative\">\n <Canvas.Icon icon={<IconAddOutline />} />\n <Canvas.Icon\n position=\"absolute\"\n top={-5}\n right={-5}\n icon={<IconBrightness0Fill color=\"#d70101\" size=\"xs\" />}\n />\n </Canvas.Container>\n </Canvas.Container>\n ),\n },\n {\n key: 'task',\n name: 'Title',\n themeOverride,\n minWidth: 200,\n width: 250,\n renderCell: ({ row, theme }) => (\n <Canvas.Container\n direction=\"row\"\n alignItems=\"center\"\n justifyContent=\"space-between\"\n gap={8}\n wrap=\"wrap\"\n padding={{\n left: theme.cellHorizontalPadding,\n right: theme.cellHorizontalPadding,\n }}\n style={{ width: '100%' }}\n >\n <Canvas.Container direction=\"column\" gap={2}>\n <Canvas.Text\n font={theme.baseFontStyle}\n color={theme.accentFg}\n style={{ flexGrow: 1 }}\n >\n {row.task ?? '—'}\n </Canvas.Text>\n <Canvas.Text\n font={theme.baseFontStyle}\n color={theme.textHeader}\n style={{ flexGrow: 1 }}\n >\n {row.priority ?? '—'}\n </Canvas.Text>\n </Canvas.Container>\n <Canvas.Button\n portalHoverEnabled\n variant=\"secondary\"\n onClick={() =>\n // eslint-disable-next-line no-console\n console.log('Подробнее по сотруднику', row.complete)\n }\n >\n Подробнее\n </Canvas.Button>\n </Canvas.Container>\n ),\n },\n ...(developerIsShown\n ? [\n {\n key: 'developer',\n name: 'Developer',\n themeOverride,\n } satisfies ColumnConfig<Row>,\n ]\n : []),\n {\n key: 'priority',\n name: 'Priority',\n sortingType: 'stringSort',\n themeOverride,\n filtering: {\n component: 'select',\n selectOptions: {\n type: 'constant',\n options: [\n { value: 'All', text: 'All' },\n { value: 'High', text: 'High' },\n { value: 'Critical', text: 'Critical' },\n { value: 'Medium', text: 'Medium' },\n { value: 'Low', text: 'Low' },\n ],\n },\n\n keyInFilterState: 'priority',\n valueInRow: (r) => r.priority,\n filter: {\n typeOfValue: 'single',\n filteringType: (fv, rv) => (fv !== 'All' ? rv === fv : true),\n },\n },\n },\n {\n key: 'issueType',\n name: 'Issue Type',\n themeOverride,\n filtering: {\n component: 'input',\n filter: 'includes',\n\n valueInRow: (r) => `${r.task} ${r.id}`,\n\n keyInFilterState: 'task',\n },\n },\n {\n key: 'complete',\n name: '% Complete',\n themeOverride,\n },\n ],\n [developerIsShown, themeOverride],\n );\n\n const sortingStateAndSetter = useState<readonly SortColumn[]>([]);\n\n return (\n <Box $css={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>\n <Box>\n <Button\n size=\"s\"\n view=\"secondary\"\n onClick={() => setDeveloperIsShown((prev) => !prev)}\n >\n {developerIsShown\n ? 'Удалить колонку Developer'\n : 'Добавить колонку Developer'}\n </Button>\n </Box>\n <TableCanvas\n tableConfig={{\n containerStyle: { height: '60vh' },\n rowSize: {\n default: 'big',\n showInControl: true,\n },\n highlightActiveType: 'row',\n\n fullScreenEnabled: true,\n controlBlock: {\n customFeatures: [\n // Обязательная кастомная фича\n {\n value: 'favorite',\n label: 'Удалить из избранного',\n Icon: IconStar,\n onClick: () => {},\n mandatory: true,\n details: {\n type: 'switch',\n label: 'В избранном',\n checked: isFavorite,\n onChange: (e) => setIsFavorite(e.target.checked),\n },\n },\n ],\n },\n filtering: {\n state: filteringStateAndSetter,\n filtersInfo: {\n id: {\n label: 'id',\n clearedValue: '',\n },\n task: {\n label: 'task',\n clearedValue: '',\n },\n priority: {\n label: 'Some Label',\n clearedValue: 'All',\n },\n issueType: {\n label: 'issueType',\n clearedValue: [],\n },\n complete: {\n label: 'complete',\n clearedValue: '',\n },\n date: {\n label: 'Дата',\n clearedValue: '',\n },\n globalFilter: {\n label: 'Global filter',\n clearedValue: '',\n },\n },\n },\n sorting: {\n state: sortingStateAndSetter,\n },\n }}\n columnConfig={columnConfig}\n rows={rows}\n />\n </Box>\n );\n }"
52955
+ },
52675
52956
  {
52676
52957
  "exportName": "ColumnsControlPinningMenu",
52677
52958
  "displayName": "ColumnsControl: доп. пункты меню закрепления",
@@ -53353,11 +53634,11 @@
53353
53634
  "legacy": false,
53354
53635
  "summary": "*tableConfig.filtering**",
53355
53636
  "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)",
53356
- "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 /**\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\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 * 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```",
53637
+ "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 /**\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```",
53357
53638
  "api": [
53358
53639
  {
53359
53640
  "typeName": "FilteringConfig",
53360
- "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 /**\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\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 * 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 *"
53641
+ "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 /**\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 *"
53361
53642
  },
53362
53643
  {
53363
53644
  "typeName": "FilterComponentInPopoverProps",
@@ -53369,7 +53650,7 @@
53369
53650
  "exportName": "FilteringTable",
53370
53651
  "displayName": "Filtering Table",
53371
53652
  "type": "full-code",
53372
- "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui';\n\n() => {\n const [isFavorite, setIsFavorite] = useState(true);\n const [rows] = useState(() => {\n const seededRandom = createSeededRandom(42);\n return createRows().map((el) => ({\n ...el,\n id: Math.floor(seededRandom() * 1000),\n date: (() => {\n const date = new Date(\n FIXED_DATE_TIMESTAMP +\n (Math.floor(seededRandom() * 61) - 30) * 86400000,\n );\n return `${String(date.getDate()).padStart(2, '0')}.${String(\n date.getMonth() + 1,\n ).padStart(2, '0')}.${date.getFullYear()}`;\n })(),\n }));\n });\n\n const filteringStateAndSetter = useState({\n id: '',\n task: '',\n priority: 'All',\n issueType: [],\n complete: '',\n globalFilter: '',\n date: undefined as string | undefined,\n });\n\n const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n () => [\n {\n key: 'id',\n name: 'id',\n },\n {\n key: 'task',\n name: 'Title',\n },\n {\n key: 'date',\n name: 'Date',\n filtering: {\n component: 'custom',\n customRender: (props) => {\n const {\n headerContextState: { filters, setFilters },\n } = props;\n return (\n <Calendar\n value={filters?.['date']}\n onChangeValue={(v) => {\n if (setFilters)\n setFilters((prev) => ({\n ...prev,\n date: v,\n }));\n }}\n />\n );\n },\n filter: (filterValue, rowValue) =>\n filterValue ? rowValue === filterValue : true,\n valueInRow: (r) => (r as Row & { date: string })?.date,\n compareWithClearedValue: (clearedValue, currV) =>\n clearedValue === currV,\n keyInFilterState: 'date',\n },\n },\n\n {\n key: 'priority',\n name: 'Priority',\n filtering: {\n component: 'select',\n selectOptions: {\n type: 'constant',\n options: [\n { value: 'All', text: 'All' },\n { value: 'High', text: 'High' },\n { value: 'Critical', text: 'Critical' },\n { value: 'Medium', text: 'Medium' },\n { value: 'Low', text: 'Low' },\n ],\n },\n\n keyInFilterState: 'priority',\n valueInRow: (r) => r.priority,\n filter: {\n typeOfValue: 'single',\n filteringType: (fv, rv) => (fv !== 'All' ? rv === fv : true),\n },\n },\n },\n {\n key: 'issueType',\n name: 'Issue Type',\n filtering: {\n beforeList(props) {\n return (\n <TableFilterSelectListItem\n $size={props.headerContextState.rowSize}\n >\n custom beforeList\n </TableFilterSelectListItem>\n );\n },\n component: 'select',\n selectOptions: {\n type: 'stateInHeaderContext',\n optionsKeyInHeaderContext: 'issueTypeOptions',\n },\n keyInFilterState: 'issueType',\n valueInRow: (r) => r.issueType,\n filter: {\n typeOfValue: 'multiple',\n filteringType: (fv, rv) =>\n !fv.length || fv.some((fvCurr) => fvCurr === rv),\n },\n },\n },\n {\n key: 'complete',\n name: '% Complete',\n },\n ],\n [],\n );\n\n const headerContextValue = useMemo(\n () => ({\n issueTypeOptions: [\n { text: 'Bug', value: 'Bug' },\n { text: 'Improvement', value: 'Improvement' },\n { text: 'Epic', value: 'Epic' },\n { text: 'Story', value: 'Story' },\n ],\n }),\n [],\n );\n\n return (\n <TableCanvas\n tableConfig={{\n containerStyle: { height: '60vh' },\n rowSize: {\n default: 'big',\n showInControl: true,\n },\n fullScreenEnabled: true,\n controlBlock: {\n customFeatures: [\n // Обязательная кастомная фича\n {\n value: 'favorite',\n label: 'Удалить из избранного',\n Icon: IconStar,\n onClick: () => {},\n mandatory: true,\n details: {\n type: 'switch',\n label: 'В избранном',\n checked: isFavorite,\n onChange: (e) => setIsFavorite(e.target.checked),\n },\n },\n ],\n },\n filtering: {\n state: filteringStateAndSetter,\n filtersInfo: {\n id: {\n label: 'id',\n clearedValue: '',\n },\n task: {\n label: 'task',\n clearedValue: '',\n },\n priority: {\n label: 'Some Label',\n clearedValue: 'All',\n },\n issueType: {\n label: 'issueType',\n clearedValue: [],\n },\n complete: {\n label: 'complete',\n clearedValue: '',\n },\n date: {\n label: 'Дата',\n clearedValue: undefined,\n },\n globalFilter: {\n label: 'Global filter',\n clearedValue: '',\n },\n },\n },\n }}\n columnConfig={columnConfig}\n rows={rows}\n headerContextValue={headerContextValue}\n />\n );\n }"
53653
+ "code": "import React, { useMemo, useState } from 'react';\nimport {\n Box,\n Button,\n Calendar,\n Combobox,\n ComboboxItemOption,\n Divider,\n} from '@daisforge/ui';\nimport { IconStar } from '@daisforge/ui/icons';\nimport {\n ColumnConfig,\n TableCanvas,\n TableFilterSelect,\n TableFilterSelectListItem,\n} from '@daisforge/ui/components/TableCanvas';\n\nimport { createRows, type Row } from './data/tableData';\n\n() => {\n const [isFavorite, setIsFavorite] = useState(true);\n const [rows] = useState(() => {\n const seededRandom = createSeededRandom(42);\n return createRows().map((el) => ({\n ...el,\n id: Math.floor(seededRandom() * 1000),\n date: (() => {\n const date = new Date(\n FIXED_DATE_TIMESTAMP +\n (Math.floor(seededRandom() * 61) - 30) * 86400000,\n );\n return `${String(date.getDate()).padStart(2, '0')}.${String(\n date.getMonth() + 1,\n ).padStart(2, '0')}.${date.getFullYear()}`;\n })(),\n }));\n });\n\n const filteringStateAndSetter = useState({\n id: '',\n task: '',\n priority: 'All',\n issueType: [],\n issueTypeCustom: [] as string[],\n complete: '',\n globalFilter: '',\n date: undefined as string | undefined,\n });\n\n const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n () => [\n {\n key: 'id',\n name: 'id',\n },\n {\n key: 'task',\n name: 'Title',\n },\n {\n key: 'date',\n name: 'Date',\n filtering: {\n component: 'custom',\n customRender: (props) => {\n const {\n headerContextState: { filters, setFilters },\n } = props;\n return (\n <Calendar\n value={filters?.['date']}\n onChangeValue={(v) => {\n if (setFilters)\n setFilters((prev) => ({\n ...prev,\n date: v,\n }));\n }}\n />\n );\n },\n filter: (filterValue, rowValue) =>\n filterValue ? rowValue === filterValue : true,\n valueInRow: (r) => (r as Row & { date: string })?.date,\n compareWithClearedValue: (clearedValue, currV) =>\n clearedValue === currV,\n keyInFilterState: 'date',\n },\n },\n\n {\n key: 'priority',\n name: 'Priority',\n filtering: {\n component: 'select',\n selectOptions: {\n type: 'constant',\n options: [\n {\n value: 'All',\n text: 'Все инциденты и запросы на доработку без ограничения по срочности',\n },\n {\n value: 'High',\n text: 'Высокий приоритет критически важного инцидента',\n },\n {\n value: 'Critical',\n text: 'Критическая ошибка блокирующая работу сервиса',\n },\n {\n value: 'Medium',\n text: 'Средний приоритет плановой доработки функциональности',\n },\n {\n value: 'Low',\n text: 'Низкий приоритет косметического усовершенствования интерфейса',\n },\n ],\n },\n\n keyInFilterState: 'priority',\n valueInRow: (r) => r.priority,\n filter: {\n typeOfValue: 'single',\n filteringType: (fv, rv) => (fv !== 'All' ? rv === fv : true),\n },\n },\n },\n {\n key: 'issueType',\n name: 'Issue Type',\n filtering: {\n beforeList(props) {\n return (\n <TableFilterSelectListItem\n $size={props.headerContextState.rowSize}\n >\n Произвольный вспомогательный элемент заголовка списка с\n подсказкой сверху списка\n </TableFilterSelectListItem>\n );\n },\n afterList(props) {\n return (\n <TableFilterSelectListItem\n $size={props.headerContextState.rowSize}\n >\n Произвольный вспомогательный элемент заголовка списка с\n подсказкой внизу списка\n </TableFilterSelectListItem>\n );\n },\n component: 'select',\n selectOptions: {\n type: 'stateInHeaderContext',\n optionsKeyInHeaderContext: 'issueTypeOptions',\n },\n keyInFilterState: 'issueType',\n valueInRow: (r) => r.issueType,\n filter: {\n typeOfValue: 'multiple',\n filteringType: (fv, rv) =>\n !fv.length || fv.some((fvCurr) => fvCurr === rv),\n },\n },\n },\n {\n key: 'issueTypeCustom',\n name: 'Issue Type (custom render) ',\n renderCell({ row }) {\n return row.issueType;\n },\n filtering: {\n component: 'custom',\n customRender: (props) => {\n const {\n headerContextState: { filters, setFilters, rowSize },\n setPopoverIsOpen,\n } = props;\n // Опции для выпадашки берутся из headerContextValue (см. headerContextValue ниже)\n const headerContextState = props.headerContextState as Record<\n string,\n unknown\n >;\n const issueTypeOptions = (headerContextState.issueTypeOptions ??\n []) as { text: string; value: string }[];\n\n // Локальный черновик выбранных значений: меняется при кликах по айтемам,\n // а в реальный стейт фильтров попадает по кнопке «Применить» (afterList).\n const [draftValue, setDraftValue] = useState<string[]>(\n (filters?.['issueTypeCustom'] as string[] | undefined) ?? [],\n );\n\n const apply = () => {\n if (setFilters) {\n setFilters((prev) => ({\n ...prev,\n issueTypeCustom: draftValue,\n }));\n setPopoverIsOpen(false);\n }\n };\n\n return (\n <TableFilterSelect\n mode=\"multiple\"\n value={draftValue}\n onChange={setDraftValue}\n options={issueTypeOptions}\n size={rowSize}\n width=\"232px\"\n beforeList={\n <TableFilterSelectListItem $size={rowSize}>\n Произвольный вспомогательный элемент заголовка списка с\n подсказкой\n </TableFilterSelectListItem>\n }\n afterList={\n <Box\n $css={`position: sticky; bottom: 0; background-color: white; display: grid; gap: ${\n rowSize === 'big' ? '4px' : '4px'\n }; margin-top: 4px;`}\n >\n <Divider />\n <Button\n size={rowSize === 'small' ? 'xxs' : 's'}\n style={{ marginLeft: 'auto ' }}\n view=\"accent\"\n onClick={apply}\n >\n Применить\n </Button>\n </Box>\n }\n />\n );\n },\n filter: (filterValue, rowValue) =>\n !Array.isArray(filterValue) ||\n !(filterValue as string[]).length ||\n (filterValue as string[]).some((fvCurr) => fvCurr === rowValue),\n valueInRow: (r) => r.issueType,\n compareWithClearedValue: (clearedValue, currV) =>\n JSON.stringify(clearedValue) === JSON.stringify(currV),\n keyInFilterState: 'issueTypeCustom',\n },\n },\n {\n key: 'complete',\n name: '% Complete',\n },\n ],\n [],\n );\n\n const headerContextValue = useMemo(\n () => ({\n issueTypeOptions: [\n {\n // Ошибка-1212---3232-3---4343434 - для визуальной проверки длинных текстов без пробелов\n text: 'Ошибка-1212---3232-3---4343434 при формировании выписки по счету',\n value: 'Bug',\n },\n {\n text: 'Улучшение производительности загрузки списка документов',\n value: 'Improvement',\n },\n {\n text: 'Эпик крупной функциональности платежного модуля',\n value: 'Epic',\n },\n {\n text: 'История пользовательского сценария оформления кредита',\n value: 'Story',\n },\n ],\n }),\n [],\n );\n\n // Combobox из sdds-finai ожидает items в формате { value, label }.\n const sidebarIssueTypeOptions = useMemo<ComboboxItemOption[]>(\n () =>\n headerContextValue.issueTypeOptions.map((option) => ({\n value: option.value,\n label: option.text,\n })),\n [headerContextValue],\n );\n\n return (\n <TableCanvas\n tableConfig={{\n containerStyle: { height: '60vh' },\n rowSize: {\n default: 'big',\n showInControl: true,\n },\n fullScreenEnabled: true,\n controlBlock: {\n customFeatures: [\n // Обязательная кастомная фича\n {\n value: 'favorite',\n label: 'Удалить из избранного',\n Icon: IconStar,\n onClick: () => {},\n mandatory: true,\n details: {\n type: 'switch',\n label: 'В избранном',\n checked: isFavorite,\n onChange: (e) => setIsFavorite(e.target.checked),\n },\n },\n ],\n },\n filtering: {\n state: filteringStateAndSetter,\n sidebarConfig: {\n items: {\n // Переопределяем рендер колоночного фильтра именно для сайдбара:\n // колоночный customRender остаётся в поповере шапки.\n issueTypeCustom: {\n label: 'Issue Type (custom render)',\n customRenderFn: (filters, setFilters) => {\n // Хуки здесь допустимы: customRenderFn рендерится как\n // компонент (см. RenderSlot в feature-filtering).\n // Черновик выбора уезжает в фильтры сайдбара по кнопке\n // «Применить» внутри выпадающего списка (afterList).\n const [draftValue, setDraftValue] = useState<string[]>(\n filters.issueTypeCustom,\n );\n\n return (\n <Combobox\n multiple\n size=\"s\"\n items={sidebarIssueTypeOptions}\n value={draftValue}\n onChange={(next: string[]) => setDraftValue(next)}\n closeAfterSelect={false}\n placeholder=\"Выберите Issue Type\"\n afterList={\n <Box $css=\"display: grid; gap: 4px; margin-top: 4px;\">\n <Divider />\n <Button\n size=\"xs\"\n view=\"accent\"\n style={{ marginLeft: 'auto' }}\n onClick={() =>\n setFilters((prev) => ({\n ...prev,\n issueTypeCustom: draftValue,\n }))\n }\n >\n Применить\n </Button>\n </Box>\n }\n />\n );\n },\n },\n },\n },\n filtersInfo: {\n id: {\n label: 'id',\n clearedValue: '',\n },\n task: {\n label: 'task',\n clearedValue: '',\n },\n priority: {\n label: 'Some Label',\n clearedValue: 'All',\n },\n issueType: {\n label: 'issueType',\n clearedValue: [],\n },\n issueTypeCustom: {\n label: 'issueTypeCustom',\n clearedValue: [],\n },\n complete: {\n label: 'complete',\n clearedValue: '',\n },\n date: {\n label: 'Дата',\n clearedValue: undefined,\n },\n globalFilter: {\n label: 'Global filter',\n clearedValue: '',\n },\n },\n },\n }}\n columnConfig={columnConfig}\n rows={rows}\n headerContextValue={headerContextValue}\n />\n );\n }"
53373
53654
  },
53374
53655
  {
53375
53656
  "exportName": "ManualFiltering",
@@ -53401,6 +53682,74 @@
53401
53682
  }
53402
53683
  ]
53403
53684
  },
53685
+ {
53686
+ "component": "TableCanvas",
53687
+ "feature": "Borders",
53688
+ "legacy": false,
53689
+ "summary": "*tableConfig.borders**",
53690
+ "docs": "# Borders (TableCanvas)\n\n**tableConfig.borders**\n\nУправление линиями сетки таблицы: их включение и выключение.\n\nНастраивается на четырёх уровнях, от общего к точечному. Каждый следующий уровень\nсильнее предыдущего: настройка ячейки важнее настройки колонки и строки, а те\nважнее общих настроек.\n\n## Уровни\n\n- **вся таблица** — `borders.vertical` и `borders.horizontal`: убрать все\n вертикальные или все горизонтальные линии тела (по умолчанию линии есть);\n- **колонка** — `borders.getVerticalBorder`: вернуть для колонки `true` или\n `false`, чтобы переопределить общую настройку вертикалей, или `undefined`,\n чтобы оставить её (например, убрать разделитель справа от одной колонки);\n- **строка** — `borders.getHorizontalBorder`: вернуть для строки `true` или\n `false`, чтобы переопределить общую настройку горизонталей, или `undefined`,\n чтобы оставить её;\n- **ячейка** — `borders.getCellBorder`: включить или выключить каждую из\n четырёх сторон рамки ячейки; для ячеек без переопределений вернуть `undefined`.\n\n## Точечные колбэки\n\n`getHorizontalBorder` и `getCellBorder` получают саму строку (`row`), её индекс\n(`rowIndex`) и уровень вложенности subRows (`treeLvl`, где `0` это корень). При\nраскрытии дерева индексы строк сдвигаются, поэтому настройку удобно привязывать к\nстроке или к уровню, а не к номеру. Для summary-строк колбэки не вызываются.\n\nТипичные сценарии:\n\n- выключить все линии и точечно дорисовать нужные (например, только контур\n объединённого блока);\n- оставить горизонтали, но не рисовать их внутри раскрытых subRows\n (`treeLvl > 0` вернуть `false`), чтобы родитель с детьми выглядел цельным.\n\n## Объединённые ячейки\n\nВнутрь объединённого блока линии не рисуются никогда: остаётся только внешний\nконтур. Чтобы оформить рамку блока, задавайте стороны у его крайних ячеек через\n`getCellBorder` — внутренние рамки всё равно отсекаются.\n\n## Итоговые (summary) строки\n\nНастройки вертикали действуют и на итоговую строку: разделители колонок проходят\nчерез неё насквозь, а `getVerticalBorder` убирает разделитель у выбранной колонки\nи в теле, и в итоге.\n\nТочечные горизонтали (`getHorizontalBorder`) и рамки отдельных ячеек\n(`getCellBorder`) в итоговых строках пока не поддержаны: на их линии влияют только\nпо-колоночная вертикаль и общие настройки. Полное управление линиями внутри\nитоговых строк появится позже.\n\n> Подробнее о типах — [Borders API](?path=/docs/локальные-компоненты-tablecanvas-borders-api--docs)",
53691
+ "apiDocs": "# Borders API\n\n## tableConfig.borders\n\n```typescript\ntype 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```\n\n## CellBorderVisibility\n\nСтороны рамки одной ячейки, которые возвращает `getCellBorder`. Для каждой\nстороны:\n\n- `true` — рисовать линию;\n- `false` — не рисовать линию;\n- поле не задано — сторона берётся с уровня ниже (настройка колонки, строки или\n общая).\n\n```typescript\ntype CellBorderVisibility = {\n top?: boolean;\n right?: boolean;\n bottom?: boolean;\n left?: boolean;\n};\n```\n\n## borders.getVerticalBorder\n\nТочечная вертикальная линия справа от колонки. Колбэк получает `columnKey` и\n`columnIndex` (в порядке отрисовки, закреплённые в начале) и возвращает `true`\nили `false`, чтобы переопределить общую настройку `borders.vertical`, или\n`undefined`, чтобы оставить её.\n\nКолбэк зовётся на каждую видимую колонку при каждой перерисовке, поэтому должен\nбыть быстрым. Если условие зависит от набора колонок, держите этот набор в `Set`\nзаранее (вне колбэка) и проверяйте через `has` — так проверка остаётся дешёвой\nи не растёт с числом колонок:\n\n```tsx\nconst COLUMNS_WITHOUT_RIGHT_BORDER = new Set(['priority', 'issueType']);\n\nborders={{\n getVerticalBorder: ({ columnKey }) =>\n COLUMNS_WITHOUT_RIGHT_BORDER.has(columnKey) ? false : undefined,\n}}\n```\n\nТот же приём подходит и для `getHorizontalBorder` и `getCellBorder`: тяжёлые\nвычисления и наборы данных готовьте заранее, а в колбэке оставляйте только\nбыструю проверку.",
53692
+ "api": [
53693
+ {
53694
+ "typeName": "BordersConfig",
53695
+ "source": "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};"
53696
+ },
53697
+ {
53698
+ "typeName": "CellBorderVisibility",
53699
+ "source": "type CellBorderVisibility = {\n top?: boolean;\n right?: boolean;\n bottom?: boolean;\n left?: boolean;\n};"
53700
+ }
53701
+ ],
53702
+ "stories": [
53703
+ {
53704
+ "exportName": "NoVerticalLines",
53705
+ "displayName": "NoVerticalLines",
53706
+ "type": "full-code",
53707
+ "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\nconst COLS: ColumnConfig<Row>[] = [\n { key: 'id', name: 'ID', width: 120 },\n { key: 'task', name: 'Title', width: 160 },\n { key: 'priority', name: 'Priority', width: 140 },\n { key: 'issueType', name: 'Issue Type', width: 140 },\n { key: 'complete', name: '% Complete', width: 140 },\n];\n\n<TableCanvas\n tableConfig={{ borders: { vertical: false } }}\n columnConfig={COLS}\n rows={rows}\n/>"
53708
+ },
53709
+ {
53710
+ "exportName": "HideColumnBorder",
53711
+ "displayName": "HideColumnBorder",
53712
+ "type": "full-code",
53713
+ "code": "import { useMemo } from 'react';\nimport { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\nconst COLS: ColumnConfig<Row>[] = [\n { key: 'id', name: 'ID', width: 120 },\n { key: 'task', name: 'Title', width: 160 },\n { key: 'priority', name: 'Priority', width: 140 },\n { key: 'issueType', name: 'Issue Type', width: 140 },\n { key: 'complete', name: '% Complete', width: 140 },\n];\n\nconst columnsWithoutRightBorder = useMemo(\n () => new Set(['priority', 'issueType']),\n [],\n);\n\n<TableCanvas\n tableConfig={{\n borders: {\n getVerticalBorder: ({ columnKey }) =>\n columnsWithoutRightBorder.has(columnKey) ? false : undefined,\n },\n }}\n columnConfig={COLS}\n rows={rows}\n/>"
53714
+ },
53715
+ {
53716
+ "exportName": "NoHorizontalLines",
53717
+ "displayName": "NoHorizontalLines",
53718
+ "type": "full-code",
53719
+ "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\nconst COLS: ColumnConfig<Row>[] = [\n { key: 'id', name: 'ID', width: 120 },\n { key: 'task', name: 'Title', width: 160 },\n { key: 'priority', name: 'Priority', width: 140 },\n { key: 'issueType', name: 'Issue Type', width: 140 },\n { key: 'complete', name: '% Complete', width: 140 },\n];\n\n<TableCanvas\n tableConfig={{ borders: { horizontal: false } }}\n columnConfig={COLS}\n rows={rows}\n/>"
53720
+ },
53721
+ {
53722
+ "exportName": "PerCellBorders",
53723
+ "displayName": "PerCellBorders",
53724
+ "type": "full-code",
53725
+ "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\nconst COLS: ColumnConfig<Row>[] = [\n { key: 'id', name: 'ID', width: 120 },\n { key: 'task', name: 'Title', width: 160 },\n { key: 'priority', name: 'Priority', width: 140 },\n { key: 'issueType', name: 'Issue Type', width: 140 },\n { key: 'complete', name: '% Complete', width: 140 },\n];\n\nconst BOTTOM_ON = { bottom: true } as const;\n\n<TableCanvas\n tableConfig={{\n borders: {\n horizontal: false,\n getCellBorder: ({ columnKey, row }) =>\n columnKey === 'complete' && row.complete >= 50 ? BOTTOM_ON : undefined,\n },\n }}\n columnConfig={COLS}\n rows={rows}\n/>"
53726
+ },
53727
+ {
53728
+ "exportName": "SubRowsWithoutInnerLines",
53729
+ "displayName": "Title",
53730
+ "type": "full-code",
53731
+ "code": "() => {\n const [rows] = useState(createRows);\n const cols: readonly ColumnConfig<Row>[] = [\n {\n key: 'task',\n name: 'Title',\n width: 220,\n subRow: { keyOfColumnInSubRow: 'task', isColumnWithArrow: true },\n },\n { key: 'priority', name: 'Priority', width: 140 },\n { key: 'issueType', name: 'Issue Type', width: 140 },\n { key: 'complete', name: '% Complete', width: 140 },\n ];\n return (\n <TableCanvas\n tableConfig={{\n containerStyle: { height: 420 },\n rowMarkers: { startIndex: 1 },\n subRows: {\n getSubRows: (row) => row.subRows,\n rowKeyGetter: (row) => row.id,\n },\n borders: {\n vertical: false,\n getHorizontalBorder: ({ treeLvl }) =>\n treeLvl > 0 ? false : undefined,\n },\n }}\n columnConfig={cols}\n rows={rows}\n />\n );\n }"
53732
+ },
53733
+ {
53734
+ "exportName": "MillionRows",
53735
+ "displayName": "Строк",
53736
+ "type": "full-code",
53737
+ "code": "({\n rowsCount,\n colsCount,\n perCell,\n }: {\n rowsCount: number;\n colsCount: number;\n perCell: boolean;\n }) => {\n const rows = useMemo(() => makeLeanRows(rowsCount), [rowsCount]);\n const columnConfig = useMemo(() => makeManyCols(colsCount), [colsCount]);\n return (\n <TableCanvas\n tableConfig={{\n containerStyle: { height: 480 },\n rowMarkers: { startIndex: 1 },\n borders: perCell\n ? {\n horizontal: false,\n getCellBorder: ({ columnKey, row, rowIndex }) => {\n if (rowIndex % 10 === 9) return BOTTOM_ON;\n if (columnKey !== 'complete') return undefined;\n return row.complete >= 50 ? BOTTOM_ON : undefined;\n },\n }\n : { vertical: false },\n }}\n columnConfig={columnConfig}\n rows={rows}\n />\n );\n }"
53738
+ },
53739
+ {
53740
+ "exportName": "WithMergedCells",
53741
+ "displayName": "Регион",
53742
+ "type": "full-code",
53743
+ "code": "() => {\n const [rows] = useState(makeMergeRows);\n return (\n <TableCanvas\n tableConfig={{\n containerStyle: { height: 420 },\n rowMarkers: { startIndex: 1 },\n mergeCells: { mergeByCellValues: ['region', 'dept'] },\n hoverEffects: { row: true },\n cellsSelection: { mode: 'range-cell' },\n borders: {\n vertical: false,\n horizontal: false,\n getCellBorder: ({ columnKey, row }) => {\n if (columnKey === 'region' || columnKey === 'dept') {\n return FRAME_ON;\n }\n if (columnKey === 'metric') {\n return row.metric >= 50 ? SIDES_WITH_BOTTOM : SIDES_ON;\n }\n if (columnKey === 'status') {\n return SIDES_ON;\n }\n return undefined;\n },\n },\n }}\n columnConfig={MERGE_COLS}\n rows={rows}\n />\n );\n }"
53744
+ },
53745
+ {
53746
+ "exportName": "SummaryVerticalBorders",
53747
+ "displayName": "ID",
53748
+ "type": "full-code",
53749
+ "code": "() => {\n const [rows] = useState(createRows);\n const avgComplete = useMemo(\n () =>\n Math.round(rows.reduce((sum, r) => sum + r.complete, 0) / rows.length),\n [rows],\n );\n return (\n <TableCanvas\n tableConfig={{\n containerStyle: { height: 420 },\n rowMarkers: { startIndex: 1 },\n summaryRows: { showDefault: true, showInControl: false },\n borders: {\n getVerticalBorder: ({ columnKey }) =>\n columnKey === 'priority' ? false : undefined,\n },\n }}\n columnConfig={SUMMARY_COLS}\n rows={rows}\n bottomSummaryRows={[avgComplete]}\n />\n );\n }"
53750
+ }
53751
+ ]
53752
+ },
53404
53753
  {
53405
53754
  "component": "TableCanvas",
53406
53755
  "feature": "FullScreenMode",
@@ -53468,6 +53817,34 @@
53468
53817
  }
53469
53818
  ]
53470
53819
  },
53820
+ {
53821
+ "component": "TableCanvas",
53822
+ "feature": "HoverEffects",
53823
+ "legacy": false,
53824
+ "summary": "Эффекты при наведении — единый расширяемый конфиг `tableConfig.hoverEffects`.",
53825
+ "docs": "# Hover Effects\n\nЭффекты при наведении — единый расширяемый конфиг `tableConfig.hoverEffects`.\nСейчас поддерживается **подсветка строки под курсором** (`row`). Чисто визуальная фича, по умолчанию\n**выключена**. В будущем в этом же объекте появятся hover по ячейке и т.д.\n\n## Как включить\n\n```tsx\ntableConfig={{ hoverEffects: { row: true } }} // цвета из темы\n```\n\n## Цвета (уровень темы)\n\n- **data-ячейки** hovered-строки — серый `bgRowHovered`;\n- **служебные колонки** (нумерация / чекбокс / инструменты строк) hovered-строки\n не сереют — темнеют голубым `bgServiceRowHovered`, тем же цветом, что\n сервис-зона при селектинге;\n- строка, **отмеченная чекбоксом** (`selecting`), под курсором темнеет целиком —\n `bgSelectedRowHovered` (как hover шапки), вместо серого.\n\n## Приоритеты слоёв (важно)\n\nHover — **самый нижний визуальный слой**, он не конкурирует с выделением:\n\n- выделение ячеек/строк/колонок (`cellsSelection`) и «залипшая» активная строка\n (`highlightActiveType='row'`) рисуются **поверх** и перекрывают hover;\n- после сброса выделения hover под курсором снова виден;\n- summary-строки hover не получают.\n\n## Особенности\n\n- Работает по всей строке: hover срабатывает над любой ячейкой строки,\n включая нумерацию и чекбокс.\n- Уход мыши с таблицы (или на шапку/групп-хедер) сбрасывает подсветку.\n- Не требует `themeOverride` и не влияет на copy/paste и прочую логику\n выделения — ось полностью независимая. Не путать с `highlightActiveType` —\n тот подсвечивает строку по **клику** («залипает»), hover — по наведению.\n\n> Подробнее о типах — [HoverEffects API](?path=/docs/локальные-компоненты-tablecanvas-hovereffects-api--docs)\n\n> Внутреннее устройство и почему такие приоритеты — в доке\n> `packages/ui-kit/src/components/TableCanvas/docs/SelectionAndHighlighting.md`,\n> раздел 7.",
53826
+ "apiDocs": "# HoverEffects API\n\n## HoverEffectsConfig\n\n`tableConfig.hoverEffects` — единый конфиг эффектов при наведении. Значения,\nцвета по зонам строки и приоритет слоёв описаны в комментариях к типу.\n\n```typescript\ntype HoverEffectsConfig = {\n /**\n * Подсветка строки под курсором. По умолчанию выключена.\n * - не задано или `false` — выключена;\n * - `true` — включена, цвета из темы.\n *\n * Цвета по зонам строки берутся из темы:\n * - data-ячейки — `bgRowHovered`;\n * - служебные колонки (нумерация, чекбокс) — `bgServiceRowHovered`, тот же\n * цвет, что у сервис-зоны при выделении;\n * - строка, отмеченная чекбоксом, темнеет целиком `bgSelectedRowHovered`.\n *\n * Hover — самый нижний слой: выделение ячеек, строк, колонок и залипшая\n * активная строка (`highlightActiveType: 'row'`) рисуются поверх и\n * перекрывают его; после сброса выделения он снова виден. Summary-строки\n * hover не получают.\n */\n row?: boolean;\n};\n```",
53827
+ "api": [
53828
+ {
53829
+ "typeName": "HoverEffectsConfig",
53830
+ "source": "type HoverEffectsConfig = {\n /**\n * Подсветка строки под курсором. По умолчанию выключена.\n * - не задано или `false` — выключена;\n * - `true` — включена, цвета из темы.\n *\n * Цвета по зонам строки берутся из темы:\n * - data-ячейки — `bgRowHovered`;\n * - служебные колонки (нумерация, чекбокс) — `bgServiceRowHovered`, тот же\n * цвет, что у сервис-зоны при выделении;\n * - строка, отмеченная чекбоксом, темнеет целиком `bgSelectedRowHovered`.\n *\n * Hover — самый нижний слой: выделение ячеек, строк, колонок и залипшая\n * активная строка (`highlightActiveType: 'row'`) рисуются поверх и\n * перекрывают его; после сброса выделения он снова виден. Summary-строки\n * hover не получают.\n */\n row?: boolean;\n};"
53831
+ }
53832
+ ],
53833
+ "stories": [
53834
+ {
53835
+ "exportName": "HoverEffectsPlayground",
53836
+ "displayName": "HoverEffectsPlayground",
53837
+ "type": "full-code",
53838
+ "code": "import { useMemo, useState } from 'react';\nimport { Select } from '@daisforge/ui/components/Select';\nimport {\n type CellsSelectionMode,\n type ColumnConfig,\n type HighlightActiveType,\n type HoverEffectsConfig,\n TableCanvas,\n} from '@daisforge/ui/components/TableCanvas';\n\n// Варианты значения tableConfig.hoverEffects для селекта.\ntype HoverEffectsOption = 'disabled' | 'row';\n\nconst HOVER_EFFECTS_OPTIONS: readonly HoverEffectsOption[] = ['row', 'disabled'];\n\n// Каждый вариант это готовое значение tableConfig.hoverEffects.\nconst HOVER_EFFECTS_BY_OPTION: Record<HoverEffectsOption, HoverEffectsConfig> = {\n disabled: {},\n row: { row: true },\n};\n\nconst HIGHLIGHT_ACTIVE_TYPE_OPTIONS: readonly HighlightActiveType[] = [\n 'row',\n 'disabled',\n];\n\nconst SELECTION_MODE_OPTIONS: readonly CellsSelectionMode[] = [\n 'range-cell',\n 'multi-range-cell',\n 'cell',\n 'disabled',\n];\n\nconst COLUMN_CONFIG: readonly ColumnConfig<Row>[] = [\n { key: 'id', name: 'ID', width: 90 },\n { key: 'task', name: 'Title', width: 260 },\n { key: 'priority', name: 'Priority', width: 180 },\n { key: 'issueType', name: 'Issue Type', width: 180 },\n { key: 'complete', name: '% Complete', width: 160 },\n];\nconst getRowSelectionKey = (row: Row) => row.id + row.issueType;\n\n() => {\n const [hoverOption, setHoverOption] = useState<HoverEffectsOption>('row');\n const [highlightActiveType, setHighlightActiveType] =\n useState<HighlightActiveType>('row');\n const [selectionMode, setSelectionMode] =\n useState<CellsSelectionMode>('range-cell');\n const [rows] = useState(createRows);\n\n const selectingStateAndSetter = useState<ReadonlySet<string | number>>(\n () =>\n new Set(\n rows\n .filter((row) => [3, 5].includes(Number(row.id)))\n .map(getRowSelectionKey),\n ),\n );\n\n const columnConfig = useMemo<readonly ColumnConfig<TableRow>[]>(\n () => COLUMN_CONFIG,\n [],\n );\n\n return (\n <>\n <div\n style={{ display: 'grid', gap: 12, maxWidth: 420, marginBottom: 16 }}\n >\n <div>\n hoverEffects (эффекты при наведении)\n <Select\n value={hoverOption}\n onChange={(value) => setHoverOption(value as HoverEffectsOption)}\n items={HOVER_EFFECTS_OPTIONS.map((item) => ({\n label: item,\n value: item,\n }))}\n />\n </div>\n\n <div>\n highlightActiveType (залипшая активная строка)\n <Select\n value={highlightActiveType}\n onChange={(value) =>\n setHighlightActiveType(value as HighlightActiveType)\n }\n items={HIGHLIGHT_ACTIVE_TYPE_OPTIONS.map((item) => ({\n label: item,\n value: item,\n }))}\n />\n </div>\n\n <div>\n cellsSelection.mode (режим выделения)\n <Select\n value={selectionMode}\n onChange={(value) =>\n setSelectionMode(value as CellsSelectionMode)\n }\n items={SELECTION_MODE_OPTIONS.map((item) => ({\n label: item,\n value: item,\n }))}\n />\n </div>\n </div>\n\n <StoryHint>\n Водите мышью по строкам — data-ячейки подсвечиваются серым, служебные\n колонки (нумерация/чекбокс) — голубым, как при селектинге.\n Checkbox-строки (3 и 5) под курсором темнеют целиком. Клик по строке\n (активная строка / выделение) рисуется <b>поверх</b> hover-подсветки и\n перекрывает её; после сброса выделения hover снова виден.\n </StoryHint>\n\n <TableCanvas\n key={[hoverOption, highlightActiveType, selectionMode].join('-')}\n tableConfig={{\n containerStyle: { height: '700px', maxWidth: 980 },\n hoverEffects: HOVER_EFFECTS_BY_OPTION[hoverOption],\n highlightActiveType,\n cellsSelection: { mode: selectionMode },\n rowMarkers: { startIndex: 1 },\n selecting: {\n state: selectingStateAndSetter,\n rowKeyGetter: getRowSelectionKey,\n },\n }}\n columnConfig={columnConfig}\n rows={rows}\n />\n </>\n );\n }"
53839
+ },
53840
+ {
53841
+ "exportName": "HoverEffectsRowSimple",
53842
+ "displayName": "Минимальное включение",
53843
+ "type": "full-code",
53844
+ "code": "import {\n type CellsSelectionMode,\n type ColumnConfig,\n type HighlightActiveType,\n type HoverEffectsConfig,\n TableCanvas,\n} from '@daisforge/ui/components/TableCanvas';\n\nconst COLUMN_CONFIG: readonly ColumnConfig<Row>[] = [\n { key: 'id', name: 'ID', width: 90 },\n { key: 'task', name: 'Title', width: 260 },\n { key: 'priority', name: 'Priority', width: 180 },\n { key: 'issueType', name: 'Issue Type', width: 180 },\n { key: 'complete', name: '% Complete', width: 160 },\n];\nconst getRowSelectionKey = (row: Row) => row.id + row.issueType;\n\n() => {\n const [rows] = useState(createRows);\n const columnConfig = useMemo<readonly ColumnConfig<TableRow>[]>(\n () => COLUMN_CONFIG,\n [],\n );\n\n return (\n <TableCanvas\n tableConfig={{\n containerStyle: { height: '600px' },\n hoverEffects: { row: true },\n }}\n columnConfig={columnConfig}\n rows={rows}\n />\n );\n }"
53845
+ }
53846
+ ]
53847
+ },
53471
53848
  {
53472
53849
  "component": "TableCanvas",
53473
53850
  "feature": "InfinityScroll",
@@ -54220,7 +54597,7 @@
54220
54597
  "legacy": true,
54221
54598
  "summary": "Базовые примеры legacy `Table`: минимальная HTML-таблица и нагрузочный пример с большим количеством ячеек.",
54222
54599
  "docs": "# SimpleTable\n\nБазовые примеры legacy `Table`: минимальная HTML-таблица и нагрузочный пример с большим количеством ячеек.\n\n## Ключевые особенности\n\n- Минимальная связка `rows`, `columnConfig` и `tableConfig`\n- Кастомный заголовок колонки через React-разметку\n- Пример render-функции ячейки для большого набора строк и колонок\n- Управление размерами таблицы через `tableConfig.containerStyle`\n\n## Особенности\n\n`MillionCells` показывает сценарий проверки виртуализации и производительности. Для новых сценариев больших таблиц предпочтительнее `TableCanvas`.\n\nОписание типов - в разделе [API](?path=/docs/локальные-компоненты-table-simple-api--docs).",
54223
- "apiDocs": "# Simple Table API\n\n## TableProps\n\n```typescript\ntype TableProps<\n FilterStateType extends ObjectForExtending,\n RowIdType extends string | number,\n HeaderContextValueType extends ObjectForExtending,\n RowContextValueType extends ObjectForExtending,\n RowType extends ObjectForExtending,\n SummaryRowType = unknown,\n> = {\n /**\n * columnConfig - Конфигурация колонок.\n *\n * (рекомендуется минимальное количество зависимостей для данной сущности - в идеале, чтобы не пересоздавался)\n */\n columnConfig: readonly ColumnConfig<RowType, SummaryRowType>[];\n /**\n * rows - данные для таблицы. ```RowType extends Record<string | number, any>```\n */\n rows: RowType[];\n /**\n * topSummaryRows - данные для итоговой строки в верхней части таблицы. ```SummaryRowType[]```\n */\n topSummaryRows?: SummaryRowType[];\n /**\n * rows - данные для итоговой строки в нижней части таблицы. ```SummaryRowType[]```\n */\n bottomSummaryRows?: SummaryRowType[];\n /**\n * tableConfig - Конфигурация фичей таблицы (их активация и отключение)\n */\n tableConfig?: Prettify<\n TableConfig<RowType, SummaryRowType, RowIdType, FilterStateType>\n >;\n /**\n * headerContextValue: любые стейты, которые нужны в headerCell - кладем в headerContextValue. И получаем доступ с помощью useHeaderContext.\n */\n headerContextValue?: HeaderContextValueType;\n /**\n * rowContextValue: любые стейты, которые нужны в cell - кладем в rowContextValue. И получаем доступ с помощью useRowContext.\n */\n rowContextValue?: RowContextValueType;\n refTable?: Ref<DataGridHandle>;\n refTableContainer?: React.Ref<HTMLDivElement>;\n};\n```\n\n## TableConfig\n\n```typescript\ntype TableConfig<\n RowType extends ObjectForExtending,\n SummaryRowType,\n RowIdType extends string | number,\n FilterStateType extends ObjectForExtending,\n // SubRowType\n> = {\n /**\n * Тип выделения активной (кликнутой) сущности `'cell' | 'row'`\n * @default 'cell'\n */\n highlightActiveType?: HighlightActiveType;\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 } & 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 * subRows - активация иерархии, отображения вложенных строк. Условие активации - наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={subRows: {getSubRows, rowKeyGetter}}\n *\n * columnConfig=[{subRow: {...}}]\n */\n subRows?: SubRows<RowType, RowIdType>;\n rowsGrouping?: RowsGrouping<RowType>;\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 * infinityScroll - бесконечная подгрузка данных при скролле.\n *\n * Условие активации - наличие самого пропса infinityScroll.\n *\n * При активации infinityScroll отключается дефолтная сортировка и фильтрация.\n * (Предполагается, что если есть infinityScroll,\n * то в таблице представлен не весь объем данных,\n * по этой причине дефолтная сортировка и фильтрация не подходят и будут отображать некорректные данные)\n *\n */\n infinityScroll?: {\n onTrigger: (rows: RowType[]) => Promise<void> | void;\n isLoading: boolean;\n /**\n * @default true\n */\n hasMore?: boolean;\n /**\n * @default 100 (px)\n */\n scrollThreshold?: number;\n };\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 noRowsFallback?: boolean | { custom: ReactNode };\n columnsControl?: ColumnsControlConfig;\n rowDetailPanel?: RowDetailConfig<RowType>;\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 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 - пропс для активации открытия контекстного меню.\n *\n */\n onHeaderContextMenu?: HeaderContextMenuProps;\n onHeaderContextMenuDropDown?: HeaderContextMenuDropDownProps;\n onCellContextMenuDropDown?: CellContextMenuDropDownProps<\n RowType,\n 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## ColumnConfig\n\n```typescript\ntype ColumnConfig<\n Row extends ObjectForExtending,\n SummRow = unknown,\n> = ColumnDefaultOmitted<Row, SummRow> & {\n /**\n * Если в поле name был передан jsx, то нужно заполнить nameAsString для указания label в разделе Настройки столбцов, либо для отображения label в фильтрах в правом сайдбаре (но приоритет для фильтро будет ниже, чем то, что указали в filtering.sidebarConfig.items, там отдельно можно перезаписать label для фильтров сайдабара)\n */\n nameAsString?: string;\n sortingType?: 'stringSort' | 'numberSort' | Comparator<Row>;\n searching?: {\n valueInRow: (row: Row) => string | number;\n };\n filtering?: {\n keyInFilterState: string;\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n valueInRow?: (row: Row) => string | number;\n /**\n * ```FilterCb - (filterValue: string, rowValue: string) => boolean```\n */\n } & (\n | {\n component: 'input';\n filter: 'includes' | 'startWith' | 'equal' | FilterCb<'single'>;\n }\n | {\n component: 'select';\n beforeList?: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter:\n | {\n typeOfValue: 'single';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'single'>;\n }\n | {\n typeOfValue: 'multiple';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'multiple'>;\n };\n selectOptions:\n | {\n type: 'constant';\n options: SelectOptions[];\n }\n | {\n type: 'stateInHeaderContext';\n /**\n * тип optionsState, который будет в HeaderContext:\n * ```ts\n * {\n * value: string | number;\n * text: string | number;\n * }[];\n * ```\n */\n optionsKeyInHeaderContext: string;\n };\n /**\n * Максимальна высота выпадающего списка в фильтрах колонок / правом сайдбаре.\n * @default \"360px\"\n */\n listMaxHeight?: string;\n }\n | {\n component: 'custom';\n customRender: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter?: (filterValue: unknown, rowValue: unknown) => boolean;\n compareWithClearedValue?: (\n clearedValue: unknown,\n currV: unknown,\n ) => boolean;\n }\n );\n\n contentFormat?: ContentFormat;\n\n editingCell?: Editing<Row>;\n\n subRow?: {\n /**\n * @default false\n */\n isColumnWithArrow?: boolean | ((props: { keyText: KeyText }) => boolean);\n /**\n * @default false\n */\n hideHeaderExpandAllArrow?: boolean;\n /**\n * @default false\n */\n parentKeyAsDefault?: boolean;\n /**\n * @default undefined\n */\n contentFormat?: ContentFormat;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n renderSubRowCell?: RenderSubRowCell<any>;\n } & (\n | {\n keyOfColumnInSubRow:\n | string\n | number\n | ((lvl: number) => string | number);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n editingCell: Editing<any>;\n }\n | {\n editingCell?: undefined;\n keyOfColumnInSubRow?:\n | string\n | number\n | ((lvl: number) => string | number);\n }\n );\n rowsGrouping?: ColumnRowsGrouping<Row, SummRow>;\n keyText?: KeyTextColumnConfig<Row, SummRow>;\n};\n```",
54600
+ "apiDocs": "# Simple Table API\n\n## TableProps\n\n```typescript\ntype TableProps<\n FilterStateType extends ObjectForExtending,\n RowIdType extends string | number,\n HeaderContextValueType extends ObjectForExtending,\n RowContextValueType extends ObjectForExtending,\n RowType extends ObjectForExtending,\n SummaryRowType = unknown,\n> = {\n /**\n * columnConfig - Конфигурация колонок.\n *\n * (рекомендуется минимальное количество зависимостей для данной сущности - в идеале, чтобы не пересоздавался)\n */\n columnConfig: readonly ColumnConfig<RowType, SummaryRowType>[];\n /**\n * rows - данные для таблицы. ```RowType extends Record<string | number, any>```\n */\n rows: RowType[];\n /**\n * topSummaryRows - данные для итоговой строки в верхней части таблицы. ```SummaryRowType[]```\n */\n topSummaryRows?: SummaryRowType[];\n /**\n * rows - данные для итоговой строки в нижней части таблицы. ```SummaryRowType[]```\n */\n bottomSummaryRows?: SummaryRowType[];\n /**\n * tableConfig - Конфигурация фичей таблицы (их активация и отключение)\n */\n tableConfig?: Prettify<\n TableConfig<RowType, SummaryRowType, RowIdType, FilterStateType>\n >;\n /**\n * headerContextValue: любые стейты, которые нужны в headerCell - кладем в headerContextValue. И получаем доступ с помощью useHeaderContext.\n */\n headerContextValue?: HeaderContextValueType;\n /**\n * rowContextValue: любые стейты, которые нужны в cell - кладем в rowContextValue. И получаем доступ с помощью useRowContext.\n */\n rowContextValue?: RowContextValueType;\n refTable?: Ref<DataGridHandle>;\n refTableContainer?: React.Ref<HTMLDivElement>;\n};\n```\n\n## TableConfig\n\n```typescript\ntype TableConfig<\n RowType extends ObjectForExtending,\n SummaryRowType,\n RowIdType extends string | number,\n FilterStateType extends ObjectForExtending,\n // SubRowType\n> = {\n /**\n * Тип выделения активной (кликнутой) сущности `'cell' | 'row'`\n * @default 'cell'\n */\n highlightActiveType?: HighlightActiveType;\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 } & 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 * subRows - активация иерархии, отображения вложенных строк. Условие активации - наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={subRows: {getSubRows, rowKeyGetter}}\n *\n * columnConfig=[{subRow: {...}}]\n */\n subRows?: SubRows<RowType, RowIdType>;\n rowsGrouping?: RowsGrouping<RowType>;\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 * infinityScroll - бесконечная подгрузка данных при скролле.\n *\n * Условие активации - наличие самого пропса infinityScroll.\n *\n * При активации infinityScroll отключается дефолтная сортировка и фильтрация.\n * (Предполагается, что если есть infinityScroll,\n * то в таблице представлен не весь объем данных,\n * по этой причине дефолтная сортировка и фильтрация не подходят и будут отображать некорректные данные)\n *\n */\n infinityScroll?: {\n onTrigger: (rows: RowType[]) => Promise<void> | void;\n isLoading: boolean;\n /**\n * @default true\n */\n hasMore?: boolean;\n /**\n * @default 100 (px)\n */\n scrollThreshold?: number;\n };\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 noRowsFallback?: boolean | { custom: ReactNode };\n columnsControl?: ColumnsControlConfig;\n rowDetailPanel?: RowDetailConfig<RowType>;\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 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 - пропс для активации открытия контекстного меню.\n *\n */\n onHeaderContextMenu?: HeaderContextMenuProps;\n onHeaderContextMenuDropDown?: HeaderContextMenuDropDownProps;\n onCellContextMenuDropDown?: CellContextMenuDropDownProps<\n RowType,\n 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## ColumnConfig\n\n```typescript\ntype ColumnConfig<\n Row extends ObjectForExtending,\n SummRow = unknown,\n> = ColumnDefaultOmitted<Row, SummRow> & {\n /**\n * Если в поле name был передан jsx, то нужно заполнить nameAsString для указания label в разделе Настройки столбцов, либо для отображения label в фильтрах в правом сайдбаре (но приоритет для фильтро будет ниже, чем то, что указали в filtering.sidebarConfig.items, там отдельно можно перезаписать label для фильтров сайдабара)\n */\n nameAsString?: string;\n sortingType?: 'stringSort' | 'numberSort' | Comparator<Row>;\n searching?: {\n valueInRow: (row: Row) => string | number;\n };\n filtering?: {\n keyInFilterState: string;\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n valueInRow?: (row: Row) => string | number;\n /**\n * ```FilterCb - (filterValue: string, rowValue: string) => boolean```\n */\n } & (\n | {\n component: 'input';\n filter: 'includes' | 'startWith' | 'equal' | FilterCb<'single'>;\n }\n | {\n component: 'select';\n /**\n * Произвольное содержимое над списком опций фильтра.\n *\n * Рендерится и в поповере фильтра в шапке колонки, и в сайдбаре\n * фильтров. Рендерится как компонент, поэтому внутри можно\n * использовать хуки и локальное состояние.\n *\n * @example\n * beforeList: ({ headerContextState }) => (\n * <TableFilterSelectListItem $size={headerContextState.rowSize}>\n * Подсказка над списком\n * </TableFilterSelectListItem>\n * )\n */\n beforeList?: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n /**\n * Произвольное содержимое под списком опций фильтра.\n *\n * Рендерится и в поповере фильтра в шапке колонки, и в сайдбаре\n * фильтров. Рендерится как компонент, поэтому внутри можно\n * использовать хуки и локальное состояние — например, чтобы держать\n * черновик выбора и применять его по кнопке.\n *\n * @example\n * afterList: ({ headerContextState, setPopoverIsOpen }) => (\n * <TableFilterSelectListItem $size={headerContextState.rowSize}>\n * Подсказка под списком\n * </TableFilterSelectListItem>\n * )\n */\n afterList?: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter:\n | {\n typeOfValue: 'single';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'single'>;\n }\n | {\n typeOfValue: 'multiple';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'multiple'>;\n };\n selectOptions:\n | {\n type: 'constant';\n options: SelectOptions[];\n }\n | {\n type: 'stateInHeaderContext';\n /**\n * тип optionsState, который будет в HeaderContext:\n * ```ts\n * {\n * value: string | number;\n * text: string | number;\n * }[];\n * ```\n */\n optionsKeyInHeaderContext: string;\n };\n /**\n * Максимальна высота выпадающего списка в фильтрах колонок / правом сайдбаре.\n * @default \"360px\"\n */\n listMaxHeight?: string;\n }\n | {\n component: 'custom';\n customRender: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter?: (filterValue: unknown, rowValue: unknown) => boolean;\n compareWithClearedValue?: (\n clearedValue: unknown,\n currV: unknown,\n ) => boolean;\n }\n );\n\n contentFormat?: ContentFormat;\n\n editingCell?: Editing<Row>;\n\n subRow?: {\n /**\n * @default false\n */\n isColumnWithArrow?: boolean | ((props: { keyText: KeyText }) => boolean);\n /**\n * @default false\n */\n hideHeaderExpandAllArrow?: boolean;\n /**\n * @default false\n */\n parentKeyAsDefault?: boolean;\n /**\n * @default undefined\n */\n contentFormat?: ContentFormat;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n renderSubRowCell?: RenderSubRowCell<any>;\n } & (\n | {\n keyOfColumnInSubRow:\n | string\n | number\n | ((lvl: number) => string | number);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n editingCell: Editing<any>;\n }\n | {\n editingCell?: undefined;\n keyOfColumnInSubRow?:\n | string\n | number\n | ((lvl: number) => string | number);\n }\n );\n rowsGrouping?: ColumnRowsGrouping<Row, SummRow>;\n keyText?: KeyTextColumnConfig<Row, SummRow>;\n};\n```",
54224
54601
  "api": [
54225
54602
  {
54226
54603
  "typeName": "TableProps",
@@ -54296,6 +54673,18 @@
54296
54673
  "type": "full-code",
54297
54674
  "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n Badge,\n Box,\n Button,\n ColumnConfig,\n ColumnOrColumnGroupConfig,\n RenderCellProps,\n RowHeightFunc,\n SIZES,\n Select,\n Switch,\n Table,\n TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n const [rows] = useState(createRows);\n\n const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n () => [\n {\n key: 'id',\n name: 'ID',\n },\n {\n key: 'task',\n name: 'Title',\n },\n {\n key: 'priority',\n name: 'Priority',\n },\n {\n key: 'issueType',\n name: 'Issue Type',\n },\n {\n key: 'developer',\n name: 'Developer',\n },\n {\n key: 'tr1',\n name: 'TR',\n },\n {\n key: 'complete',\n name: '% Complete',\n },\n ],\n [],\n );\n\n return (\n <Table\n tableConfig={{\n containerStyle: { height: 700 },\n columnsControl: {\n enable: true,\n hiding: true,\n disableHiding: ['id'],\n pinning: true,\n disablePinning: ['developer'],\n reorderingAside: true,\n reorderingHeader: true,\n columnsLabel: {\n task: 'Задачи',\n },\n orderDefault: ['id', 'issueType', 'task'],\n hiddenDefault: ['tr1'],\n pinnedDefault: ['complete'],\n onConfirm: ({ order, hidden, pinned }, _setters) => {\n // eslint-disable-next-line no-alert\n alert(`\n order: ${order.join(', ')}\n pinned: ${pinned.join(', ')}\n hidden: ${hidden.join(', ')}\n `);\n },\n },\n }}\n columnConfig={columnConfig}\n rows={rows}\n />\n );\n }"
54298
54675
  },
54676
+ {
54677
+ "exportName": "ColumnsControlDynamicColumn",
54678
+ "displayName": "ColumnsControl: динамическое добавление колонки",
54679
+ "type": "full-code",
54680
+ "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n Badge,\n Box,\n Button,\n ColumnConfig,\n ColumnOrColumnGroupConfig,\n RenderCellProps,\n RowHeightFunc,\n SIZES,\n Select,\n Switch,\n Table,\n TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n const [rows] = useState(createRows);\n const [developerIsShown, setDeveloperIsShown] = useState(false);\n\n const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n () => [\n {\n key: 'id',\n name: 'ID',\n },\n {\n key: 'task',\n name: 'Title',\n },\n ...(developerIsShown\n ? [\n {\n key: 'developer',\n name: 'Developer',\n } satisfies ColumnConfig<Row>,\n ]\n : []),\n {\n key: 'priority',\n name: 'Priority',\n },\n {\n key: 'issueType',\n name: 'Issue Type',\n },\n {\n key: 'complete',\n name: '% Complete',\n },\n ],\n [developerIsShown],\n );\n\n return (\n <Box $css={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>\n <Box>\n <Button\n size=\"s\"\n view=\"secondary\"\n onClick={() => setDeveloperIsShown((prev) => !prev)}\n >\n {developerIsShown\n ? 'Удалить колонку Developer'\n : 'Добавить колонку Developer'}\n </Button>\n </Box>\n <Table\n tableConfig={{\n containerStyle: { height: 700 },\n columnsControl: {\n enable: true,\n hiding: true,\n pinning: true,\n reorderingAside: true,\n reorderingHeader: true,\n },\n }}\n columnConfig={columnConfig}\n rows={rows}\n />\n </Box>\n );\n }"
54681
+ },
54682
+ {
54683
+ "exportName": "SimpleTableDynamicColumn",
54684
+ "displayName": "SimpleTable: динамическое добавление колонки",
54685
+ "type": "full-code",
54686
+ "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n Badge,\n Box,\n Button,\n ColumnConfig,\n ColumnOrColumnGroupConfig,\n RenderCellProps,\n RowHeightFunc,\n SIZES,\n Select,\n Switch,\n Table,\n TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n const [rows] = useState(createRows);\n const [developerIsShown, setDeveloperIsShown] = useState(false);\n\n const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n () => [\n {\n key: 'id',\n name: (\n <div\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n }}\n >\n id\n <IconSber size=\"xs\" color=\"inherit\" />\n </div>\n ),\n },\n {\n key: 'task',\n name: 'Title',\n },\n ...(developerIsShown\n ? [\n {\n key: 'developer',\n name: 'Developer',\n } satisfies ColumnConfig<Row>,\n ]\n : []),\n {\n key: 'priority',\n name: 'Priority',\n },\n {\n key: 'issueType',\n name: 'Issue Type',\n },\n {\n key: 'complete',\n name: '% Complete',\n },\n ],\n [developerIsShown],\n );\n\n return (\n <Box $css={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>\n <Box>\n <Button\n size=\"s\"\n view=\"secondary\"\n onClick={() => setDeveloperIsShown((prev) => !prev)}\n >\n {developerIsShown\n ? 'Удалить колонку Developer'\n : 'Добавить колонку Developer'}\n </Button>\n </Box>\n <Table\n tableConfig={{ containerStyle: { height: 700 } }}\n columnConfig={columnConfig}\n rows={rows}\n />\n </Box>\n );\n }"
54687
+ },
54299
54688
  {
54300
54689
  "exportName": "ColumnsControlWithServiceColumnsForTest",
54301
54690
  "displayName": "ID",
@@ -55190,7 +55579,7 @@
55190
55579
  "legacy": true,
55191
55580
  "summary": "Сортировка по колонкам",
55192
55581
  "docs": "# Sorting\n\n## Ключевые особенности\n\n- Сортировка по колонкам\n- Строковый, числовой и кастомный компаратор\n- Ручная сортировка для серверных сценариев\n\nКомпонент `Table` поддерживает сортировку данных по колонкам.\n\n## Быстрый старт\n\nДля включения сортировки необходимо:\n\n1. Передать `sorting` в `tableConfig`\n2. Указать `sortingType` в конфигурации колонок\n\n```tsx\nconst sortingState = useState<readonly SortColumn[]>([]);\n\n<Table\n tableConfig={{\n sorting: {\n state: sortingState,\n },\n }}\n columnConfig={[\n { key: 'name', name: 'Название', sortingType: 'stringSort' },\n { key: 'amount', name: 'Сумма', sortingType: 'numberSort' },\n ]}\n rows={rows}\n/>;\n```\n\n## Стратегии сортировки\n\n<table>\n <thead>\n <tr>\n <th>sortingType</th>\n <th>Когда использовать</th>\n <th>Пример данных</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td>\n <code>stringSort</code>\n </td>\n <td>Текстовые поля, названия, описания</td>\n <td>\n <code>\"Яблоко\"</code>, <code>\"Apple\"</code>, <code>\"100 дней\"</code>\n </td>\n </tr>\n <tr>\n <td>\n <code>numberSort</code>\n </td>\n <td>Числа, ID, коды (даже строковые)</td>\n <td>\n <code>\"42\"</code>, <code>\"1 000\"</code>, <code>\"3,14\"</code>\n </td>\n </tr>\n <tr>\n <td>\n <code>Comparator&lt;Row&gt;</code>\n </td>\n <td>Кастомная логика (enum-приоритеты, даты, и т.д.)</td>\n <td>\n <code>Critical → High → Medium → Low</code>\n </td>\n </tr>\n </tbody>\n</table>\n\n### stringSort\n\nСтроковое сравнение с учётом русской локали.\n\n- Строковые числа сортируются как числа: `\"2\" < \"10\"` (не посимвольно)\n- Регистр не влияет: `\"яблоко\"` = `\"Яблоко\"`\n- Пустые значения всегда внизу\n\nПорядок символов при ASC (локаль `'ru'`):\n\n<table>\n <thead>\n <tr>\n <th>Порядок</th>\n <th>Категория</th>\n <th>Пример</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td>1</td>\n <td>Спецсимволы</td>\n <td>\n <code>\"#tag\"</code>, <code>\"@user\"</code>, <code>\"-\"</code>\n </td>\n </tr>\n <tr>\n <td>2</td>\n <td>Цифры</td>\n <td>\n <code>\"31.10\"</code>, <code>\"100\"</code>\n </td>\n </tr>\n <tr>\n <td>3</td>\n <td>Кириллица</td>\n <td>\n <code>\"Авто\"</code>, <code>\"Яблоко\"</code>\n </td>\n </tr>\n <tr>\n <td>4</td>\n <td>Латиница</td>\n <td>\n <code>\"Apple\"</code>, <code>\"MYCHANGE\"</code>\n </td>\n </tr>\n <tr>\n <td>—</td>\n <td>Пустые</td>\n <td>Всегда внизу</td>\n </tr>\n </tbody>\n</table>\n> Порядок между кириллицей и латиницей определяется русской локалью браузера — кириллица\nидёт первой.\n\n### numberSort\n\nЧисловое сравнение с поддержкой локальных форматов.\n\n<table>\n <thead>\n <tr>\n <th>Входное значение</th>\n <th>Результат</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td>\n <code>\"42\"</code>\n </td>\n <td>\n <code>42</code>\n </td>\n </tr>\n <tr>\n <td>\n <code>\"1 000\"</code>\n </td>\n <td>\n <code>1000</code> (пробелы-разделители)\n </td>\n </tr>\n <tr>\n <td>\n <code>\"3,14\"</code>\n </td>\n <td>\n <code>3.14</code> (запятая как десятичный)\n </td>\n </tr>\n <tr>\n <td>\n <code>\"abc\"</code>, <code>\"\"</code>\n </td>\n <td>Уходят вниз</td>\n </tr>\n </tbody>\n</table>\n\n### Кастомный компаратор\n\nФункция `(a: Row, b: Row) => number`. Направление (ASC/DESC) применяется автоматически.\n\n```tsx\n{\n key: 'priority',\n name: 'Приоритет',\n sortingType: (a, b) => {\n const order = { Critical: 0, High: 1, Medium: 2, Low: 3 };\n return (order[a.priority] ?? 99) - (order[b.priority] ?? 99);\n },\n}\n```\n\n## Направление сортировки\n\nКлик по заголовку переключает направление циклически:\n\n**нет сортировки → ASC (↓) → DESC (↑) → нет сортировки**\n\n<table>\n <thead>\n <tr>\n <th>Иконка</th>\n <th>Направление</th>\n <th>Описание</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td>↓</td>\n <td>ASC</td>\n <td>По возрастанию (от меньшего к большему)</td>\n </tr>\n <tr>\n <td>↑</td>\n <td>DESC</td>\n <td>По убыванию (от большего к меньшему)</td>\n </tr>\n <tr>\n <td>↕</td>\n <td>—</td>\n <td>Сортировка не активна</td>\n </tr>\n </tbody>\n</table>\n\nПустые значения (`null`, `undefined`, `\"\"`, строка из пробелов) всегда остаются внизу, независимо от направления.\n\n## Серверная сортировка\n\nЕсли сортировка выполняется на бэкенде, включите `manualSorting`. Таблица не будет сортировать данные сама, но будет обновлять `state` при кликах по заголовкам.\n\n```tsx\nconst [sortColumns, setSortColumns] = useState<readonly SortColumn[]>([]);\n\n// Реагируем на изменение sortColumns и делаем запрос на сервер\nuseEffect(() => {\n fetchData({ sort: sortColumns });\n}, [sortColumns]);\n\n<Table\n tableConfig={{\n sorting: {\n state: [sortColumns, setSortColumns],\n manualSorting: true,\n },\n }}\n ...\n/>\n```\n\n## API\n\nПодробное описание типов доступно в разделе [API](?path=/docs/локальные-компоненты-table-sorting-api--docs).",
55193
- "apiDocs": "# Sorting API\n\n## Comparator\n\n```typescript\ntype Comparator<Row extends ObjectForExtending> = (\n a: Row,\n b: Row,\n) => number;\n```\n\n## TableConfig\n\n```typescript\ntype TableConfig<\n RowType extends ObjectForExtending,\n SummaryRowType,\n RowIdType extends string | number,\n FilterStateType extends ObjectForExtending,\n // SubRowType\n> = {\n /**\n * Тип выделения активной (кликнутой) сущности `'cell' | 'row'`\n * @default 'cell'\n */\n highlightActiveType?: HighlightActiveType;\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 } & 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 * subRows - активация иерархии, отображения вложенных строк. Условие активации - наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={subRows: {getSubRows, rowKeyGetter}}\n *\n * columnConfig=[{subRow: {...}}]\n */\n subRows?: SubRows<RowType, RowIdType>;\n rowsGrouping?: RowsGrouping<RowType>;\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 * infinityScroll - бесконечная подгрузка данных при скролле.\n *\n * Условие активации - наличие самого пропса infinityScroll.\n *\n * При активации infinityScroll отключается дефолтная сортировка и фильтрация.\n * (Предполагается, что если есть infinityScroll,\n * то в таблице представлен не весь объем данных,\n * по этой причине дефолтная сортировка и фильтрация не подходят и будут отображать некорректные данные)\n *\n */\n infinityScroll?: {\n onTrigger: (rows: RowType[]) => Promise<void> | void;\n isLoading: boolean;\n /**\n * @default true\n */\n hasMore?: boolean;\n /**\n * @default 100 (px)\n */\n scrollThreshold?: number;\n };\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 noRowsFallback?: boolean | { custom: ReactNode };\n columnsControl?: ColumnsControlConfig;\n rowDetailPanel?: RowDetailConfig<RowType>;\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 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 - пропс для активации открытия контекстного меню.\n *\n */\n onHeaderContextMenu?: HeaderContextMenuProps;\n onHeaderContextMenuDropDown?: HeaderContextMenuDropDownProps;\n onCellContextMenuDropDown?: CellContextMenuDropDownProps<\n RowType,\n 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## ColumnConfig\n\n`sortingType` настраивается в конфигурации колонки.\n\n```typescript\ntype ColumnConfig<\n Row extends ObjectForExtending,\n SummRow = unknown,\n> = ColumnDefaultOmitted<Row, SummRow> & {\n /**\n * Если в поле name был передан jsx, то нужно заполнить nameAsString для указания label в разделе Настройки столбцов, либо для отображения label в фильтрах в правом сайдбаре (но приоритет для фильтро будет ниже, чем то, что указали в filtering.sidebarConfig.items, там отдельно можно перезаписать label для фильтров сайдабара)\n */\n nameAsString?: string;\n sortingType?: 'stringSort' | 'numberSort' | Comparator<Row>;\n searching?: {\n valueInRow: (row: Row) => string | number;\n };\n filtering?: {\n keyInFilterState: string;\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n valueInRow?: (row: Row) => string | number;\n /**\n * ```FilterCb - (filterValue: string, rowValue: string) => boolean```\n */\n } & (\n | {\n component: 'input';\n filter: 'includes' | 'startWith' | 'equal' | FilterCb<'single'>;\n }\n | {\n component: 'select';\n beforeList?: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter:\n | {\n typeOfValue: 'single';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'single'>;\n }\n | {\n typeOfValue: 'multiple';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'multiple'>;\n };\n selectOptions:\n | {\n type: 'constant';\n options: SelectOptions[];\n }\n | {\n type: 'stateInHeaderContext';\n /**\n * тип optionsState, который будет в HeaderContext:\n * ```ts\n * {\n * value: string | number;\n * text: string | number;\n * }[];\n * ```\n */\n optionsKeyInHeaderContext: string;\n };\n /**\n * Максимальна высота выпадающего списка в фильтрах колонок / правом сайдбаре.\n * @default \"360px\"\n */\n listMaxHeight?: string;\n }\n | {\n component: 'custom';\n customRender: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter?: (filterValue: unknown, rowValue: unknown) => boolean;\n compareWithClearedValue?: (\n clearedValue: unknown,\n currV: unknown,\n ) => boolean;\n }\n );\n\n contentFormat?: ContentFormat;\n\n editingCell?: Editing<Row>;\n\n subRow?: {\n /**\n * @default false\n */\n isColumnWithArrow?: boolean | ((props: { keyText: KeyText }) => boolean);\n /**\n * @default false\n */\n hideHeaderExpandAllArrow?: boolean;\n /**\n * @default false\n */\n parentKeyAsDefault?: boolean;\n /**\n * @default undefined\n */\n contentFormat?: ContentFormat;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n renderSubRowCell?: RenderSubRowCell<any>;\n } & (\n | {\n keyOfColumnInSubRow:\n | string\n | number\n | ((lvl: number) => string | number);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n editingCell: Editing<any>;\n }\n | {\n editingCell?: undefined;\n keyOfColumnInSubRow?:\n | string\n | number\n | ((lvl: number) => string | number);\n }\n );\n rowsGrouping?: ColumnRowsGrouping<Row, SummRow>;\n keyText?: KeyTextColumnConfig<Row, SummRow>;\n};\n```",
55582
+ "apiDocs": "# Sorting API\n\n## Comparator\n\n```typescript\ntype Comparator<Row extends ObjectForExtending> = (\n a: Row,\n b: Row,\n) => number;\n```\n\n## TableConfig\n\n```typescript\ntype TableConfig<\n RowType extends ObjectForExtending,\n SummaryRowType,\n RowIdType extends string | number,\n FilterStateType extends ObjectForExtending,\n // SubRowType\n> = {\n /**\n * Тип выделения активной (кликнутой) сущности `'cell' | 'row'`\n * @default 'cell'\n */\n highlightActiveType?: HighlightActiveType;\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 } & 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 * subRows - активация иерархии, отображения вложенных строк. Условие активации - наличие данного свойства. Нужно также сконфигурировать колонки.\n *\n * Пример:\n *\n * tableConfig={subRows: {getSubRows, rowKeyGetter}}\n *\n * columnConfig=[{subRow: {...}}]\n */\n subRows?: SubRows<RowType, RowIdType>;\n rowsGrouping?: RowsGrouping<RowType>;\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 * infinityScroll - бесконечная подгрузка данных при скролле.\n *\n * Условие активации - наличие самого пропса infinityScroll.\n *\n * При активации infinityScroll отключается дефолтная сортировка и фильтрация.\n * (Предполагается, что если есть infinityScroll,\n * то в таблице представлен не весь объем данных,\n * по этой причине дефолтная сортировка и фильтрация не подходят и будут отображать некорректные данные)\n *\n */\n infinityScroll?: {\n onTrigger: (rows: RowType[]) => Promise<void> | void;\n isLoading: boolean;\n /**\n * @default true\n */\n hasMore?: boolean;\n /**\n * @default 100 (px)\n */\n scrollThreshold?: number;\n };\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 noRowsFallback?: boolean | { custom: ReactNode };\n columnsControl?: ColumnsControlConfig;\n rowDetailPanel?: RowDetailConfig<RowType>;\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 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 - пропс для активации открытия контекстного меню.\n *\n */\n onHeaderContextMenu?: HeaderContextMenuProps;\n onHeaderContextMenuDropDown?: HeaderContextMenuDropDownProps;\n onCellContextMenuDropDown?: CellContextMenuDropDownProps<\n RowType,\n 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## ColumnConfig\n\n`sortingType` настраивается в конфигурации колонки.\n\n```typescript\ntype ColumnConfig<\n Row extends ObjectForExtending,\n SummRow = unknown,\n> = ColumnDefaultOmitted<Row, SummRow> & {\n /**\n * Если в поле name был передан jsx, то нужно заполнить nameAsString для указания label в разделе Настройки столбцов, либо для отображения label в фильтрах в правом сайдбаре (но приоритет для фильтро будет ниже, чем то, что указали в filtering.sidebarConfig.items, там отдельно можно перезаписать label для фильтров сайдабара)\n */\n nameAsString?: string;\n sortingType?: 'stringSort' | 'numberSort' | Comparator<Row>;\n searching?: {\n valueInRow: (row: Row) => string | number;\n };\n filtering?: {\n keyInFilterState: string;\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n valueInRow?: (row: Row) => string | number;\n /**\n * ```FilterCb - (filterValue: string, rowValue: string) => boolean```\n */\n } & (\n | {\n component: 'input';\n filter: 'includes' | 'startWith' | 'equal' | FilterCb<'single'>;\n }\n | {\n component: 'select';\n /**\n * Произвольное содержимое над списком опций фильтра.\n *\n * Рендерится и в поповере фильтра в шапке колонки, и в сайдбаре\n * фильтров. Рендерится как компонент, поэтому внутри можно\n * использовать хуки и локальное состояние.\n *\n * @example\n * beforeList: ({ headerContextState }) => (\n * <TableFilterSelectListItem $size={headerContextState.rowSize}>\n * Подсказка над списком\n * </TableFilterSelectListItem>\n * )\n */\n beforeList?: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n /**\n * Произвольное содержимое под списком опций фильтра.\n *\n * Рендерится и в поповере фильтра в шапке колонки, и в сайдбаре\n * фильтров. Рендерится как компонент, поэтому внутри можно\n * использовать хуки и локальное состояние — например, чтобы держать\n * черновик выбора и применять его по кнопке.\n *\n * @example\n * afterList: ({ headerContextState, setPopoverIsOpen }) => (\n * <TableFilterSelectListItem $size={headerContextState.rowSize}>\n * Подсказка под списком\n * </TableFilterSelectListItem>\n * )\n */\n afterList?: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter:\n | {\n typeOfValue: 'single';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'single'>;\n }\n | {\n typeOfValue: 'multiple';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'multiple'>;\n };\n selectOptions:\n | {\n type: 'constant';\n options: SelectOptions[];\n }\n | {\n type: 'stateInHeaderContext';\n /**\n * тип optionsState, который будет в HeaderContext:\n * ```ts\n * {\n * value: string | number;\n * text: string | number;\n * }[];\n * ```\n */\n optionsKeyInHeaderContext: string;\n };\n /**\n * Максимальна высота выпадающего списка в фильтрах колонок / правом сайдбаре.\n * @default \"360px\"\n */\n listMaxHeight?: string;\n }\n | {\n component: 'custom';\n customRender: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter?: (filterValue: unknown, rowValue: unknown) => boolean;\n compareWithClearedValue?: (\n clearedValue: unknown,\n currV: unknown,\n ) => boolean;\n }\n );\n\n contentFormat?: ContentFormat;\n\n editingCell?: Editing<Row>;\n\n subRow?: {\n /**\n * @default false\n */\n isColumnWithArrow?: boolean | ((props: { keyText: KeyText }) => boolean);\n /**\n * @default false\n */\n hideHeaderExpandAllArrow?: boolean;\n /**\n * @default false\n */\n parentKeyAsDefault?: boolean;\n /**\n * @default undefined\n */\n contentFormat?: ContentFormat;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n renderSubRowCell?: RenderSubRowCell<any>;\n } & (\n | {\n keyOfColumnInSubRow:\n | string\n | number\n | ((lvl: number) => string | number);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n editingCell: Editing<any>;\n }\n | {\n editingCell?: undefined;\n keyOfColumnInSubRow?:\n | string\n | number\n | ((lvl: number) => string | number);\n }\n );\n rowsGrouping?: ColumnRowsGrouping<Row, SummRow>;\n keyText?: KeyTextColumnConfig<Row, SummRow>;\n};\n```",
55194
55583
  "api": [
55195
55584
  {
55196
55585
  "typeName": "Comparator",
@@ -55519,14 +55908,14 @@
55519
55908
  },
55520
55909
  "Table.ColumnConfig": {
55521
55910
  "name": "ColumnConfig",
55522
- "definition": "export type ColumnConfig<\n Row extends ObjectForExtending,\n SummRow = unknown,\n> = ColumnDefaultOmitted<Row, SummRow> & {\n /**\n * Если в поле name был передан jsx, то нужно заполнить nameAsString для указания label в разделе Настройки столбцов, либо для отображения label в фильтрах в правом сайдбаре (но приоритет для фильтро будет ниже, чем то, что указали в filtering.sidebarConfig.items, там отдельно можно перезаписать label для фильтров сайдабара)\n */\n nameAsString?: string;\n sortingType?: 'stringSort' | 'numberSort' | Comparator<Row>;\n searching?: {\n valueInRow: (row: Row) => string | number;\n };\n filtering?: {\n keyInFilterState: string;\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n valueInRow?: (row: Row) => string | number;\n /**\n * ```FilterCb - (filterValue: string, rowValue: string) => boolean```\n */\n } & (\n | {\n component: 'input';\n filter: 'includes' | 'startWith' | 'equal' | FilterCb<'single'>;\n }\n | {\n component: 'select';\n beforeList?: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter:\n | {\n typeOfValue: 'single';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'single'>;\n }\n | {\n typeOfValue: 'multiple';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'multiple'>;\n };\n selectOptions:\n | {\n type: 'constant';\n options: SelectOptions[];\n }\n | {\n type: 'stateInHeaderContext';\n /**\n * тип optionsState, который будет в HeaderContext:\n * ```ts\n * {\n * value: string | number;\n * text: string | number;\n * }[];\n * ```\n */\n optionsKeyInHeaderContext: string;\n };\n /**\n * Максимальна высота выпадающего списка в фильтрах колонок / правом сайдбаре.\n * @default \"360px\"\n */\n listMaxHeight?: string;\n }\n | {\n component: 'custom';\n customRender: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter?: (filterValue: unknown, rowValue: unknown) => boolean;\n compareWithClearedValue?: (\n clearedValue: unknown,\n currV: unknown,\n ) => boolean;\n }\n );\n\n contentFormat?: ContentFormat;\n\n editingCell?: Editing<Row>;\n\n subRow?: {\n /**\n * @default false\n */\n isColumnWithArrow?: boolean | ((props: { keyText: KeyText }) => boolean);\n /**\n * @default false\n */\n hideHeaderExpandAllArrow?: boolean;\n /**\n * @default false\n */\n parentKeyAsDefault?: boolean;\n /**\n * @default undefined\n */\n contentFormat?: ContentFormat;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n renderSubRowCell?: RenderSubRowCell<any>;\n } & (\n | {\n keyOfColumnInSubRow:\n | string\n | number\n | ((lvl: number) => string | number);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n editingCell: Editing<any>;\n }\n | {\n editingCell?: undefined;\n keyOfColumnInSubRow?:\n | string\n | number\n | ((lvl: number) => string | number);\n }\n );\n rowsGrouping?: ColumnRowsGrouping<Row, SummRow>;\n keyText?: KeyTextColumnConfig<Row, SummRow>;\n};",
55911
+ "definition": "export type ColumnConfig<\n Row extends ObjectForExtending,\n SummRow = unknown,\n> = ColumnDefaultOmitted<Row, SummRow> & {\n /**\n * Если в поле name был передан jsx, то нужно заполнить nameAsString для указания label в разделе Настройки столбцов, либо для отображения label в фильтрах в правом сайдбаре (но приоритет для фильтро будет ниже, чем то, что указали в filtering.sidebarConfig.items, там отдельно можно перезаписать label для фильтров сайдабара)\n */\n nameAsString?: string;\n sortingType?: 'stringSort' | 'numberSort' | Comparator<Row>;\n searching?: {\n valueInRow: (row: Row) => string | number;\n };\n filtering?: {\n keyInFilterState: string;\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n valueInRow?: (row: Row) => string | number;\n /**\n * ```FilterCb - (filterValue: string, rowValue: string) => boolean```\n */\n } & (\n | {\n component: 'input';\n filter: 'includes' | 'startWith' | 'equal' | FilterCb<'single'>;\n }\n | {\n component: 'select';\n /**\n * Произвольное содержимое над списком опций фильтра.\n *\n * Рендерится и в поповере фильтра в шапке колонки, и в сайдбаре\n * фильтров. Рендерится как компонент, поэтому внутри можно\n * использовать хуки и локальное состояние.\n *\n * @example\n * beforeList: ({ headerContextState }) => (\n * <TableFilterSelectListItem $size={headerContextState.rowSize}>\n * Подсказка над списком\n * </TableFilterSelectListItem>\n * )\n */\n beforeList?: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n /**\n * Произвольное содержимое под списком опций фильтра.\n *\n * Рендерится и в поповере фильтра в шапке колонки, и в сайдбаре\n * фильтров. Рендерится как компонент, поэтому внутри можно\n * использовать хуки и локальное состояние — например, чтобы держать\n * черновик выбора и применять его по кнопке.\n *\n * @example\n * afterList: ({ headerContextState, setPopoverIsOpen }) => (\n * <TableFilterSelectListItem $size={headerContextState.rowSize}>\n * Подсказка под списком\n * </TableFilterSelectListItem>\n * )\n */\n afterList?: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter:\n | {\n typeOfValue: 'single';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'single'>;\n }\n | {\n typeOfValue: 'multiple';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'multiple'>;\n };\n selectOptions:\n | {\n type: 'constant';\n options: SelectOptions[];\n }\n | {\n type: 'stateInHeaderContext';\n /**\n * тип optionsState, который будет в HeaderContext:\n * ```ts\n * {\n * value: string | number;\n * text: string | number;\n * }[];\n * ```\n */\n optionsKeyInHeaderContext: string;\n };\n /**\n * Максимальна высота выпадающего списка в фильтрах колонок / правом сайдбаре.\n * @default \"360px\"\n */\n listMaxHeight?: string;\n }\n | {\n component: 'custom';\n customRender: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter?: (filterValue: unknown, rowValue: unknown) => boolean;\n compareWithClearedValue?: (\n clearedValue: unknown,\n currV: unknown,\n ) => boolean;\n }\n );\n\n contentFormat?: ContentFormat;\n\n editingCell?: Editing<Row>;\n\n subRow?: {\n /**\n * @default false\n */\n isColumnWithArrow?: boolean | ((props: { keyText: KeyText }) => boolean);\n /**\n * @default false\n */\n hideHeaderExpandAllArrow?: boolean;\n /**\n * @default false\n */\n parentKeyAsDefault?: boolean;\n /**\n * @default undefined\n */\n contentFormat?: ContentFormat;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n renderSubRowCell?: RenderSubRowCell<any>;\n } & (\n | {\n keyOfColumnInSubRow:\n | string\n | number\n | ((lvl: number) => string | number);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n editingCell: Editing<any>;\n }\n | {\n editingCell?: undefined;\n keyOfColumnInSubRow?:\n | string\n | number\n | ((lvl: number) => string | number);\n }\n );\n rowsGrouping?: ColumnRowsGrouping<Row, SummRow>;\n keyText?: KeyTextColumnConfig<Row, SummRow>;\n};",
55523
55912
  "importPath": "@daisforge/ui",
55524
55913
  "importStatement": "import { ColumnConfig } from '@daisforge/ui';",
55525
55914
  "sourceFile": "packages/ui-kit/src/components/Table/types/column-config.type.ts"
55526
55915
  },
55527
55916
  "TableCanvas.ColumnConfig": {
55528
55917
  "name": "ColumnConfig",
55529
- "definition": "export type ColumnConfig<\n Row extends ObjectForExtending,\n SummRow = unknown,\n CustomCtxs extends ObjectForExtending = {},\n> = ColumnDefaultOmitted<Row, SummRow, CustomCtxs> & {\n renderCell?: (cellInfo: CellInfo<Row, SummRow, CustomCtxs>) => CellContent;\n renderCellPreview?: RenderCellPreview<Row, SummRow, CustomCtxs>;\n /**\n * Если в поле name был передан jsx, то нужно заполнить nameAsString для указания label в разделе Настройки столбцов, либо для отображения label в фильтрах в правом сайдбаре (но приоритет для фильтро будет ниже, чем то, что указали в filtering.sidebarConfig.items, там отдельно можно перезаписать label для фильтров сайдабара)\n */\n nameAsString?: string;\n /**\n * Текстовое представление ячейки для копирования в clipboard (Ctrl+C).\n * Если не задан, используется `row[column.key]?.toString()`.\n * Для кастомных canvas-ячеек (бейджи, кнопки) рекомендуется указывать явно.\n */\n copyData?: string | ((row: Row) => string);\n sortingType?: 'stringSort' | 'numberSort' | Comparator<Row>;\n searching?: {\n valueInRow: (row: Row) => string | number;\n };\n filtering?: {\n keyInFilterState: string;\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n valueInRow?: (row: Row) => string | number;\n /**\n * ```FilterCb - (filterValue: string, rowValue: string) => boolean```\n */\n } & (\n | {\n component: 'input';\n filter: 'includes' | 'startWith' | 'equal' | FilterCb<'single'>;\n }\n | {\n component: 'select';\n beforeList?: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter:\n | {\n typeOfValue: 'single';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'single'>;\n }\n | {\n typeOfValue: 'multiple';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'multiple'>;\n };\n selectOptions:\n | {\n type: 'constant';\n options: SelectOptions[];\n }\n | {\n type: 'stateInHeaderContext';\n /**\n * тип optionsState, который будет в HeaderContext:\n * ```ts\n * {\n * value: string | number;\n * text: string | number;\n * }[];\n * ```\n */\n optionsKeyInHeaderContext: string;\n };\n /**\n * Максимальна высота выпадающего списка в фильтрах колонок / правом сайдбаре.\n * @default \"360px\"\n */\n listMaxHeight?: string;\n }\n | {\n component: 'custom';\n customRender: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter?: (filterValue: unknown, rowValue: unknown) => boolean;\n compareWithClearedValue?: (\n clearedValue: unknown,\n currV: unknown,\n ) => boolean;\n }\n );\n\n contentFormat?: ContentFormat;\n\n editingCell?: Editing<Row, SummRow>;\n\n /**\n * Настройки колонки для дерева subRows (шеврон, свой контент и редактор на\n * вложенных уровнях). Работает только в виде дерева. При\n * `subRows.view: 'merged'` не действует: там листья рисуются как обычные\n * строки, вложенных уровней нет.\n */\n subRow?: {\n /**\n * @default false\n */\n isColumnWithArrow?: boolean | ((props: { keyText: KeyText }) => boolean);\n /**\n * @default false\n */\n hideHeaderExpandAllArrow?: boolean;\n /**\n * @default false\n */\n parentKeyAsDefault?: boolean;\n /**\n * @default undefined\n */\n contentFormat?: ContentFormat;\n\n renderSubRowCell?: RenderSubRowCell<ObjectForExtending>;\n } & (\n | {\n keyOfColumnInSubRow:\n | string\n | number\n | ((lvl: number) => string | number);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n editingCell: Editing<any, any>;\n }\n | {\n editingCell?: undefined;\n keyOfColumnInSubRow?:\n | string\n | number\n | ((lvl: number) => string | number);\n }\n );\n rowsGrouping?: ColumnRowsGrouping<Row, ColumnConfig<Row, SummRow>>;\n keyText?: KeyTextColumnConfig<Row, SummRow>;\n /**\n * Переопределение темы на уровне ячейки. Позволяет менять фон и паддинги для конкретных ячеек.\n * @param cellInfo — информация о ячейке (row, column, ctxs, theme)\n * @param lvl — уровень вложенности (0 для обычных строк, 1+ для subRows)\n * @returns Partial<Theme> — объект переопределений (bgCell, cellHorizontalPadding и др.)\n */\n themeOverride?: (\n cellInfo: CellInfo<Row, SummRow, CustomCtxs>,\n lvl: number,\n ) => CellThemeOverrideResult | undefined;\n /**\n * Выравнивание текста в объединённой шапке этой колонки. Действует, когда шапка\n * колонки объединена (`tableConfig.columnsGrouping.squashEmptyCells`); перекрывает\n * табличный `columnsGrouping.squashedHeaderAlign`.\n */\n squashedHeaderAlign?: HeaderAlignment;\n /**\n * Выравнивание контента в объединённых ячейках этой колонки. Перекрывает общий\n * дефолт; важнее только выравнивание конкретного региона.\n *\n * Значение — одинаково для всех блоков колонки. Функция (row) => выравнивание —\n * по данным строки: разным блокам можно задать разное выравнивание (в том числе\n * в merged-видах группировки/subRows, где блоки формирует таблица).\n…",
55918
+ "definition": "export type ColumnConfig<\n Row extends ObjectForExtending,\n SummRow = unknown,\n CustomCtxs extends ObjectForExtending = {},\n> = ColumnDefaultOmitted<Row, SummRow, CustomCtxs> & {\n renderCell?: (cellInfo: CellInfo<Row, SummRow, CustomCtxs>) => CellContent;\n renderCellPreview?: RenderCellPreview<Row, SummRow, CustomCtxs>;\n /**\n * Если в поле name был передан jsx, то нужно заполнить nameAsString для указания label в разделе Настройки столбцов, либо для отображения label в фильтрах в правом сайдбаре (но приоритет для фильтро будет ниже, чем то, что указали в filtering.sidebarConfig.items, там отдельно можно перезаписать label для фильтров сайдабара)\n */\n nameAsString?: string;\n /**\n * Текстовое представление ячейки для копирования в clipboard (Ctrl+C).\n * Если не задан, используется `row[column.key]?.toString()`.\n * Для кастомных canvas-ячеек (бейджи, кнопки) рекомендуется указывать явно.\n */\n copyData?: string | ((row: Row) => string);\n sortingType?: 'stringSort' | 'numberSort' | Comparator<Row>;\n searching?: {\n valueInRow: (row: Row) => string | number;\n };\n filtering?: {\n keyInFilterState: string;\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n valueInRow?: (row: Row) => string | number;\n /**\n * ```FilterCb - (filterValue: string, rowValue: string) => boolean```\n */\n } & (\n | {\n component: 'input';\n filter: 'includes' | 'startWith' | 'equal' | FilterCb<'single'>;\n }\n | {\n component: 'select';\n /**\n * Произвольное содержимое над списком опций фильтра.\n *\n * Рендерится и в поповере фильтра в шапке колонки, и в сайдбаре\n * фильтров. Рендерится как компонент, поэтому внутри можно\n * использовать хуки и локальное состояние.\n *\n * @example\n * beforeList: ({ headerContextState }) => (\n * <TableFilterSelectListItem $size={headerContextState.rowSize}>\n * Подсказка над списком\n * </TableFilterSelectListItem>\n * )\n */\n beforeList?: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n /**\n * Произвольное содержимое под списком опций фильтра.\n *\n * Рендерится и в поповере фильтра в шапке колонки, и в сайдбаре\n * фильтров. Рендерится как компонент, поэтому внутри можно\n * использовать хуки и локальное состояние — например, чтобы держать\n * черновик выбора и применять его по кнопке.\n *\n * @example\n * afterList: ({ headerContextState, setPopoverIsOpen }) => (\n * <TableFilterSelectListItem $size={headerContextState.rowSize}>\n * Подсказка под списком\n * </TableFilterSelectListItem>\n * )\n */\n afterList?: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter:\n | {\n typeOfValue: 'single';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'single'>;\n }\n | {\n typeOfValue: 'multiple';\n /**\n * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n */\n filteringType?: FilterCb<'multiple'>;\n };\n selectOptions:\n | {\n type: 'constant';\n options: SelectOptions[];\n }\n | {\n type: 'stateInHeaderContext';\n /**\n * тип optionsState, который будет в HeaderContext:\n * ```ts\n * {\n * value: string | number;\n * text: string | number;\n * }[];\n * ```\n */\n optionsKeyInHeaderContext: string;\n };\n /**\n * Максимальна высота выпадающего списка в фильтрах колонок / правом сайдбаре.\n * @default \"360px\"\n */\n listMaxHeight?: string;\n }\n | {\n component: 'custom';\n customRender: (\n props: FilterComponentInPopoverProps<\n ObjectForExtending,\n ColumnConfig<Row, SummRow>\n >,\n ) => ReactNode;\n filter?: (filterValue: unknown, rowValue: unknown) => boolean;\n compareWithClearedValue?: (\n clearedValue: unknown,\n currV: unknown,\n ) => boolean;\n }\n );\n\n contentFormat?: ContentFormat;\n\n editingCell?: Editing<Row, SummRow>;\n\n /**\n * Настройки колонки для дерева subRows (шеврон, свой контент и редактор на\n * вложенных уровнях). Работает только в виде дерева. При\n * `subRows.view: 'merged'` не действует: там листья рисуются как обычные\n * строки, вложенных уровней нет.\n */\n subRow?: {\n /**\n * @default false\n */\n isColumnWithArrow?: boolean | ((props: { keyText: KeyText }) => boolean);\n /**\n * @default false\n */\n hideHeaderExpandAllArrow?: boolean;\n /**\n * @default false\n */\n parentKeyAsDefault?: boolean;\n /**\n * @default undefined\n */\n contentFormat?: ContentFormat;\n\n renderSubRowCell?: RenderSubRowCell<ObjectForExtending>;\n } & (\n | {\n keyOfColumnInSubRow:\n | string\n | number\n | ((lvl: number) => string | number);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n editingCell: Editing<any, any>;\n }\n | {\n editingCell?: undefined;\n keyOfColumnInSubRow?:\n …",
55530
55919
  "importPath": "@daisforge/ui/components/TableCanvas",
55531
55920
  "importStatement": "import { ColumnConfig } from '@daisforge/ui/components/TableCanvas';",
55532
55921
  "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/column-config.type.ts"
@@ -55554,7 +55943,7 @@
55554
55943
  },
55555
55944
  "HoverEffectsConfig": {
55556
55945
  "name": "HoverEffectsConfig",
55557
- "definition": "export type HoverEffectsConfig = {\n /**\n * Подсветка строки под курсором.\n * `true` — цвет data-ячеек из темы (`bgRowHovered`); объект — свой цвет.\n * Служебные колонки темнеют `bgServiceRowHovered`, checkbox-строки —\n * `bgSelectedRowHovered` (всегда из темы, `color` их не переопределяет).\n */\n row?: boolean | { color?: string };\n};",
55946
+ "definition": "export type HoverEffectsConfig = {\n /**\n * Подсветка строки под курсором. По умолчанию выключена.\n * - не задано или `false` — выключена;\n * - `true` — включена, цвета из темы.\n *\n * Цвета по зонам строки берутся из темы:\n * - data-ячейки — `bgRowHovered`;\n * - служебные колонки (нумерация, чекбокс) — `bgServiceRowHovered`, тот же\n * цвет, что у сервис-зоны при выделении;\n * - строка, отмеченная чекбоксом, темнеет целиком `bgSelectedRowHovered`.\n *\n * Hover — самый нижний слой: выделение ячеек, строк, колонок и залипшая\n * активная строка (`highlightActiveType: 'row'`) рисуются поверх и\n * перекрывают его; после сброса выделения он снова виден. Summary-строки\n * hover не получают.\n */\n row?: boolean;\n};",
55558
55947
  "importPath": "@daisforge/ui/components/TableCanvas",
55559
55948
  "importStatement": "import { HoverEffectsConfig } from '@daisforge/ui/components/TableCanvas';",
55560
55949
  "sourceFile": "packages/ui-kit/src/components/TableGlide/types.ts"
@@ -56259,6 +56648,13 @@
56259
56648
  "importStatement": "import { BlockGradientScrollVariant } from '@daisforge/ui';",
56260
56649
  "sourceFile": "packages/ui-kit/src/mixins/blockGradientScroll/types.ts"
56261
56650
  },
56651
+ "TypographyWithAutoTooltipProps": {
56652
+ "name": "TypographyWithAutoTooltipProps",
56653
+ "definition": "export type TypographyWithAutoTooltipProps<T extends TypographyVariant> = {\n tooltipText?: React.ReactNode;\n tooltipProps?: Omit<TooltipProps, 'text' | 'target' | 'trigger' | 'opened'>;\n lines?: number;\n} & Omit<TypographyProps<T>, 'frame'>;",
56654
+ "importPath": "@daisforge/ui",
56655
+ "importStatement": "import { TypographyWithAutoTooltipProps } from '@daisforge/ui';",
56656
+ "sourceFile": "packages/ui-kit/src/components/Typography/TypographyWithAutoTooltip.types.ts"
56657
+ },
56262
56658
  "DrawerProps": {
56263
56659
  "name": "DrawerProps",
56264
56660
  "definition": "export type DrawerProps = ComponentProps<typeof Drawer>;",
@@ -56399,13 +56795,6 @@
56399
56795
  "importStatement": "import { NumberFormatCompProps } from '@daisforge/ui';",
56400
56796
  "sourceFile": "packages/ui-kit/src/components/NumberFormat/NumberFormat.tsx"
56401
56797
  },
56402
- "TypographyWithAutoTooltipProps": {
56403
- "name": "TypographyWithAutoTooltipProps",
56404
- "definition": "export type TypographyWithAutoTooltipProps<T extends TypographyVariant> = {\n tooltipText?: React.ReactNode;\n tooltipProps?: Omit<TooltipProps, 'text' | 'target' | 'trigger' | 'opened'>;\n lines?: number;\n} & Omit<TypographyProps<T>, 'frame'>;",
56405
- "importPath": "@daisforge/ui",
56406
- "importStatement": "import { TypographyWithAutoTooltipProps } from '@daisforge/ui';",
56407
- "sourceFile": "packages/ui-kit/src/components/Typography/TypographyWithAutoTooltip.types.ts"
56408
- },
56409
56798
  "BreadcrumbsPropsComp": {
56410
56799
  "name": "BreadcrumbsPropsComp",
56411
56800
  "definition": "export type BreadcrumbsPropsComp = ComponentProps<typeof Breadcrumbs>;",
@@ -56497,6 +56886,48 @@
56497
56886
  "importNotice": "Тип \"BaseSwitchProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
56498
56887
  "sourceFile": "packages/ui-kit/src/components/Switch/types.ts"
56499
56888
  },
56889
+ "Table.Single": {
56890
+ "name": "Single",
56891
+ "definition": "type Single = {\n mode?: 'single';\n value: string;\n onChange: (v: string) => void;\n};",
56892
+ "internal": true,
56893
+ "importNotice": "Тип \"Single\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
56894
+ "sourceFile": "packages/ui-kit/src/components/Table/feature-filtering/combobox/combobox.tsx"
56895
+ },
56896
+ "TableCanvas.Single": {
56897
+ "name": "Single",
56898
+ "definition": "type Single = {\n mode?: 'single';\n value: string;\n onChange: (v: string) => void;\n};",
56899
+ "internal": true,
56900
+ "importNotice": "Тип \"Single\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
56901
+ "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-filtering/combobox/combobox.tsx"
56902
+ },
56903
+ "Table.Multiple": {
56904
+ "name": "Multiple",
56905
+ "definition": "type Multiple = {\n mode?: 'multiple';\n value: string[];\n onChange: (v: string[]) => void;\n};",
56906
+ "internal": true,
56907
+ "importNotice": "Тип \"Multiple\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
56908
+ "sourceFile": "packages/ui-kit/src/components/Table/feature-filtering/combobox/combobox.tsx"
56909
+ },
56910
+ "TableCanvas.Multiple": {
56911
+ "name": "Multiple",
56912
+ "definition": "type Multiple = {\n mode?: 'multiple';\n value: string[];\n onChange: (v: string[]) => void;\n};",
56913
+ "internal": true,
56914
+ "importNotice": "Тип \"Multiple\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
56915
+ "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-filtering/combobox/combobox.tsx"
56916
+ },
56917
+ "Table.SIZE": {
56918
+ "name": "SIZE",
56919
+ "definition": "export type SIZE = keyof typeof SIZES;",
56920
+ "importPath": "@daisforge/ui",
56921
+ "importStatement": "import { SIZE } from '@daisforge/ui';",
56922
+ "sourceFile": "packages/ui-kit/src/components/Table/styles/styles.constants.ts"
56923
+ },
56924
+ "TableGlide.SIZE": {
56925
+ "name": "SIZE",
56926
+ "definition": "export type SIZE = keyof GlideSizes;",
56927
+ "importPath": "@daisforge/ui/components/TableCanvas",
56928
+ "importStatement": "import { SIZE } from '@daisforge/ui/components/TableCanvas';",
56929
+ "sourceFile": "packages/ui-kit/src/components/TableGlide/constants.ts"
56930
+ },
56500
56931
  "Table.Prettify": {
56501
56932
  "name": "Prettify",
56502
56933
  "definition": "export type Prettify<T> = {\n [K in keyof T]: T[K];\n // eslint-disable-next-line @typescript-eslint/ban-types\n} & {};",
@@ -56520,7 +56951,7 @@
56520
56951
  },
56521
56952
  "TableCanvas.TableConfig": {
56522
56953
  "name": "TableConfig",
56523
- "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 * 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 * блок описан кл…",
56954
+ "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,…",
56524
56955
  "importPath": "@daisforge/ui/components/TableCanvas",
56525
56956
  "importStatement": "import { TableConfig } from '@daisforge/ui/components/TableCanvas';",
56526
56957
  "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/table-config.type.ts"
@@ -57708,6 +58139,13 @@
57708
58139
  "importNotice": "Тип \"ComboboxType\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
57709
58140
  "sourceFile": "packages/ui-kit/src/components/Combobox/index.ts"
57710
58141
  },
58142
+ "GlideSizes": {
58143
+ "name": "GlideSizes",
58144
+ "definition": "export type GlideSizes = typeof SIZES;",
58145
+ "internal": true,
58146
+ "importNotice": "Тип \"GlideSizes\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
58147
+ "sourceFile": "packages/ui-kit/src/components/TableGlide/constants.ts"
58148
+ },
57711
58149
  "CellReadOnlyEditorGlideInstanceStaticProps": {
57712
58150
  "name": "CellReadOnlyEditorGlideInstanceStaticProps",
57713
58151
  "definition": "export type CellReadOnlyEditorGlideInstanceStaticProps = {\n formatOptions: ContentFormat | undefined;\n disableLeftOffset: boolean | undefined;\n contentAlign: 'right' | 'left' | 'center';\n};",
@@ -57729,20 +58167,6 @@
57729
58167
  "importNotice": "Тип \"FillMeta\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
57730
58168
  "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-cell-transfer/types.ts"
57731
58169
  },
57732
- "TableGlide.SIZE": {
57733
- "name": "SIZE",
57734
- "definition": "export type SIZE = keyof GlideSizes;",
57735
- "importPath": "@daisforge/ui/components/TableCanvas",
57736
- "importStatement": "import { SIZE } from '@daisforge/ui/components/TableCanvas';",
57737
- "sourceFile": "packages/ui-kit/src/components/TableGlide/constants.ts"
57738
- },
57739
- "Table.SIZE": {
57740
- "name": "SIZE",
57741
- "definition": "export type SIZE = keyof typeof SIZES;",
57742
- "importPath": "@daisforge/ui",
57743
- "importStatement": "import { SIZE } from '@daisforge/ui';",
57744
- "sourceFile": "packages/ui-kit/src/components/Table/styles/styles.constants.ts"
57745
- },
57746
58170
  "RenderGroupHeaderArgs": {
57747
58171
  "name": "RenderGroupHeaderArgs",
57748
58172
  "definition": "export type RenderGroupHeaderArgs = Parameters<\n NonNullable<GlideProps['drawGroupHeader']>\n>[0];",
@@ -58184,6 +58608,13 @@
58184
58608
  "importStatement": "import { CellsSelectionConfig } from '@daisforge/ui/components/TableCanvas';",
58185
58609
  "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/table-config.type.ts"
58186
58610
  },
58611
+ "BordersConfig": {
58612
+ "name": "BordersConfig",
58613
+ "definition": "export 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};",
58614
+ "importPath": "@daisforge/ui/components/TableCanvas",
58615
+ "importStatement": "import { BordersConfig } from '@daisforge/ui/components/TableCanvas';",
58616
+ "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/table-config.type.ts"
58617
+ },
58187
58618
  "CellTransferConfig": {
58188
58619
  "name": "CellTransferConfig",
58189
58620
  "definition": "export type CellTransferConfig = {\n /**\n * Явное включение/выключение всей фичи.\n * По умолчанию copy работает всегда, а paste и fill handle следуют\n * за `editModeEnabled`. При `false` отключается всё.\n */\n enabled?: boolean;\n /**\n * Переопределение хоткеев.\n * Можно передать один `HotkeyConfig` или массив альтернативных комбинаций.\n * По умолчанию: copy = Ctrl+C / Cmd+C, paste = Ctrl+V / Cmd+V.\n */\n hotkeys?: {\n /** Хоткей(и) для копирования */\n copy?: HotkeyConfig | HotkeyConfig[];\n /** Хоткей(и) для вставки */\n paste?: HotkeyConfig | HotkeyConfig[];\n };\n /** Настройки paste (readonly, overflow, broadcast, validation) */\n paste?: PasteConfig;\n /** Настройки fill handle. `true/false` — быстрое вкл/выкл без деталей */\n fillHandle?: boolean | FillHandleConfig;\n /**\n * Колбэк перед копированием.\n * Можно модифицировать данные (вернуть новый `string[][]`) или отменить\n * операцию (вернуть `false`).\n * Если onBeforeCopy нужен для side-эффектов, то функция должна вернуть data из первого аргумента без изменений.\n */\n onBeforeCopy?: (data: string[][], meta: CopyMeta) => string[][] | false;\n /**\n * Колбэк перед вставкой.\n * Можно модифицировать данные (вернуть новый `string[][]`) или отменить\n * операцию (вернуть `false`).\n * Если onBeforePaste нужен для side-эффектов, то функция должна вернуть data из первого аргумента без изменений.\n */\n onBeforePaste?: (data: string[][], meta: PasteMeta) => string[][] | false;\n /**\n * Колбэк перед fill handle (drag-to-fill).\n * Вызывается перед применением значений. Можно модифицировать данные\n * (вернуть новый `string[][]`) или отменить операцию (вернуть `false`).\n *\n * `meta.sourceCells` содержит полную информацию об исходных ячейках,\n * включая объекты строк (`row`) — позволяет получить source row\n * и использовать данные из соседних колонок.\n * Если onBeforeFill нужен для side-эффектов, то функция должна вернуть data из первого аргумента без изменений.\n */\n onBeforeFill?: (data: string[][], meta: FillMeta) => string[][] | false;\n};",
@@ -58261,13 +58692,6 @@
58261
58692
  "importNotice": "Тип \"CellTransferCellInfo\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
58262
58693
  "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-cell-transfer/types.ts"
58263
58694
  },
58264
- "GlideSizes": {
58265
- "name": "GlideSizes",
58266
- "definition": "export type GlideSizes = typeof SIZES;",
58267
- "internal": true,
58268
- "importNotice": "Тип \"GlideSizes\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
58269
- "sourceFile": "packages/ui-kit/src/components/TableGlide/constants.ts"
58270
- },
58271
58695
  "CrossAxisSizing": {
58272
58696
  "name": "CrossAxisSizing",
58273
58697
  "definition": "export type CrossAxisSizing = 'auto' | 'deferred-percent-stretch';",