@jetbrains/ring-ui-built 7.0.124 → 8.0.0-beta.10

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 (262) hide show
  1. package/components/_helpers/anchor.js +1 -1
  2. package/components/_helpers/avatar-info.js +3 -5
  3. package/components/_helpers/caption.js +1 -1
  4. package/components/_helpers/icon-svg.js +37 -52
  5. package/components/_helpers/legacy-table.js +3 -0
  6. package/components/_helpers/tab-link.js +1 -1
  7. package/components/_helpers/table.js +2 -2
  8. package/components/_helpers/theme.js +49 -37
  9. package/components/alert/alert-actions.js +1 -1
  10. package/components/alert/alert-heading.js +1 -1
  11. package/components/alert/alert.js +2 -2
  12. package/components/alert-service/alert-service.js +2 -2
  13. package/components/auth/auth-core.js +2 -2
  14. package/components/auth/auth.js +2 -2
  15. package/components/auth/down-notification.js +2 -2
  16. package/components/auth/iframe-flow.js +1 -1
  17. package/components/auth/storage.js +2 -2
  18. package/components/auth-dialog/auth-dialog.js +2 -2
  19. package/components/auth-dialog-service/auth-dialog-service.js +2 -2
  20. package/components/avatar/avatar-info.js +1 -1
  21. package/components/avatar/avatar-size.d.ts +0 -4
  22. package/components/avatar/avatar-size.js +0 -4
  23. package/components/avatar/avatar.js +1 -8
  24. package/components/avatar/fallback-avatar.js +3 -48
  25. package/components/avatar-stack/avatar-stack.js +5 -5
  26. package/components/banner/banner.js +2 -2
  27. package/components/button/button.d.ts +0 -4
  28. package/components/button/button.js +4 -10
  29. package/components/button-group/button-group.js +1 -1
  30. package/components/button-toolbar/button-toolbar.js +1 -1
  31. package/components/checkbox/checkbox.d.ts +1 -1
  32. package/components/checkbox/checkbox.js +1 -2
  33. package/components/clipboard/clipboard.js +2 -2
  34. package/components/collapse/collapse-content.js +35 -43
  35. package/components/collapse/collapse-context.d.ts +1 -0
  36. package/components/collapse/collapse-context.js +1 -0
  37. package/components/collapse/collapse-control.js +5 -5
  38. package/components/collapse/collapse.js +34 -25
  39. package/components/collapsible-group/collapsible-group.d.ts +5 -1
  40. package/components/collapsible-group/collapsible-group.js +80 -98
  41. package/components/components/util-stories.js +63 -1
  42. package/components/confirm/confirm.js +2 -2
  43. package/components/confirm-service/confirm-service.js +4 -4
  44. package/components/contenteditable/contenteditable.js +4 -5
  45. package/components/control-help/control-help.js +1 -1
  46. package/components/control-label/control-label.js +1 -1
  47. package/components/data-list/data-list.d.ts +4 -4
  48. package/components/data-list/data-list.js +5 -5
  49. package/components/data-list/data-list.mock.d.ts +1 -1
  50. package/components/data-list/data-list.mock.js +2 -2
  51. package/components/data-list/item.d.ts +1 -1
  52. package/components/data-list/item.js +3 -3
  53. package/components/data-list/selection.d.ts +1 -1
  54. package/components/data-list/selection.js +2 -2
  55. package/components/data-list/title.js +1 -2
  56. package/components/date-picker/date-input.js +2 -2
  57. package/components/date-picker/date-picker.js +2 -3
  58. package/components/date-picker/date-popup.js +4 -5
  59. package/components/date-picker/month-names.js +1 -1
  60. package/components/date-picker/month-slider.js +1 -1
  61. package/components/date-picker/month.d.ts +0 -2
  62. package/components/date-picker/month.js +17 -18
  63. package/components/date-picker/months.js +43 -36
  64. package/components/date-picker/use-scroll-behavior.js +45 -45
  65. package/components/date-picker/weekdays.js +1 -1
  66. package/components/date-picker/years.js +61 -55
  67. package/components/dialog/dialog.d.ts +2 -2
  68. package/components/dialog/dialog.js +5 -5
  69. package/components/dropdown/anchor.js +3 -3
  70. package/components/dropdown/dropdown.js +3 -3
  71. package/components/dropdown-menu/dropdown-menu.d.ts +4 -4
  72. package/components/dropdown-menu/dropdown-menu.js +63 -58
  73. package/components/editable-heading/editable-heading.d.ts +1 -2
  74. package/components/editable-heading/editable-heading.js +14 -13
  75. package/components/error-bubble/error-bubble.js +1 -1
  76. package/components/error-message/error-message.js +1 -2
  77. package/components/footer/footer.js +1 -1
  78. package/components/global/compose-refs.d.ts +2 -1
  79. package/components/global/compose-refs.js +44 -8
  80. package/components/global/configuration.d.ts +0 -5
  81. package/components/global/configuration.js +2 -10
  82. package/components/global/controls-height.js +1 -1
  83. package/components/global/create-stateful-context.js +11 -11
  84. package/components/global/focus-sensor-hoc.js +1 -0
  85. package/components/global/focus-with-temporary-tabindex.d.ts +11 -0
  86. package/components/global/focus-with-temporary-tabindex.js +23 -0
  87. package/components/global/intersection-observer-context.d.ts +46 -0
  88. package/components/global/intersection-observer-context.js +138 -0
  89. package/components/global/is-within-interactive-element.d.ts +6 -0
  90. package/components/global/is-within-interactive-element.js +11 -0
  91. package/components/global/is-within-navigable-element.d.ts +6 -0
  92. package/components/global/is-within-navigable-element.js +11 -0
  93. package/components/global/parse-css-duration.d.ts +5 -0
  94. package/components/global/parse-css-duration.js +14 -0
  95. package/components/global/rerender-hoc.d.ts +4 -2
  96. package/components/global/rerender-hoc.js +11 -24
  97. package/components/global/schedule-with-cleanup.d.ts +12 -0
  98. package/components/global/schedule-with-cleanup.js +36 -0
  99. package/components/{table/selection.d.ts → global/table-selection.d.ts} +15 -15
  100. package/components/{table/selection.js → global/table-selection.js} +5 -5
  101. package/components/global/theme.d.ts +4 -3
  102. package/components/global/theme.js +1 -1
  103. package/components/global/variables.interface.d.ts +0 -4
  104. package/components/header/header-icon.js +3 -3
  105. package/components/header/header.js +3 -3
  106. package/components/header/links.js +1 -1
  107. package/components/header/logo.js +1 -2
  108. package/components/header/profile.js +5 -5
  109. package/components/header/services.js +3 -3
  110. package/components/header/smart-profile.js +3 -3
  111. package/components/header/smart-services.js +3 -3
  112. package/components/heading/heading.js +1 -1
  113. package/components/i18n/i18n-context.js +4 -4
  114. package/components/icon/icon-svg.js +1 -2
  115. package/components/icon/icon.d.ts +0 -1
  116. package/components/icon/icon.js +2 -6
  117. package/components/icon/index.js +1 -2
  118. package/components/input/input.d.ts +1 -1
  119. package/components/input/input.js +3 -3
  120. package/components/internal/reorder-animation-context.js +159 -0
  121. package/components/internal/reorder-handle.js +750 -0
  122. package/components/internal/reorder-layout-context.js +141 -0
  123. package/components/internal/table-header.js +685 -0
  124. package/components/internal/virtualization.js +368 -0
  125. package/components/island/adaptive-island-hoc.js +3 -3
  126. package/components/island/content.d.ts +7 -2
  127. package/components/island/content.js +27 -18
  128. package/components/island/header.js +1 -1
  129. package/components/island/island.js +1 -1
  130. package/components/{table → legacy-table}/cell.js +1 -1
  131. package/components/{table → legacy-table}/header-cell.js +2 -3
  132. package/components/{table → legacy-table}/header.js +2 -3
  133. package/components/{table → legacy-table}/multitable.d.ts +1 -1
  134. package/components/{table → legacy-table}/row-with-focus-sensor.js +3 -3
  135. package/components/{table → legacy-table}/row.d.ts +1 -1
  136. package/components/{table → legacy-table}/row.js +5 -5
  137. package/components/legacy-table/selection-adapter.d.ts +6 -0
  138. package/components/{table → legacy-table}/selection-shortcuts-hoc.d.ts +5 -5
  139. package/components/{table → legacy-table}/simple-table.d.ts +2 -2
  140. package/components/{table → legacy-table}/simple-table.js +5 -5
  141. package/components/{table → legacy-table}/smart-table.d.ts +5 -5
  142. package/components/{table → legacy-table}/smart-table.js +6 -6
  143. package/components/legacy-table/table.d.ts +109 -0
  144. package/components/legacy-table/table.js +369 -0
  145. package/components/list/consts.d.ts +0 -1
  146. package/components/list/consts.js +0 -1
  147. package/components/list/list-item.js +3 -5
  148. package/components/list/list-users-groups-source.js +1 -2
  149. package/components/list/list.d.ts +0 -4
  150. package/components/list/list.js +1 -2
  151. package/components/login-dialog/login-dialog.js +3 -3
  152. package/components/login-dialog/service.js +2 -2
  153. package/components/message/message.js +1 -1
  154. package/components/pager/pager.js +3 -3
  155. package/components/popup/popup.js +1 -1
  156. package/components/popup/popup.target.d.ts +3 -2
  157. package/components/popup/popup.target.js +32 -28
  158. package/components/popup-menu/popup-menu.js +1 -1
  159. package/components/query-assist/query-assist-suggestions.js +1 -2
  160. package/components/query-assist/query-assist.d.ts +3 -1
  161. package/components/query-assist/query-assist.js +2 -2
  162. package/components/radio/radio-item.d.ts +3 -3
  163. package/components/radio/radio-item.js +33 -19
  164. package/components/radio/radio.d.ts +2 -2
  165. package/components/radio/radio.js +2 -2
  166. package/components/scrollable-section/scrollable-section.js +1 -1
  167. package/components/select/chevron-button.js +3 -3
  168. package/components/select/select-filter.js +3 -3
  169. package/components/select/select-popup.d.ts +3 -2
  170. package/components/select/select-popup.js +9 -4
  171. package/components/select/select.d.ts +6 -2
  172. package/components/select/select.js +5 -4
  173. package/components/selection-toolbar/selection-toolbar.d.ts +11 -0
  174. package/components/selection-toolbar/selection-toolbar.js +200 -0
  175. package/components/slider/slider.js +100 -97
  176. package/components/storage/storage-local.js +2 -2
  177. package/components/storage/storage.js +2 -2
  178. package/components/style.css +1 -1
  179. package/components/tab-trap/tab-trap.d.ts +3 -3
  180. package/components/tab-trap/tab-trap.js +83 -80
  181. package/components/table/default-item-renderer.d.ts +55 -0
  182. package/components/table/default-item-renderer.js +240 -0
  183. package/components/table/internal/reorder-animation-context.d.ts +21 -0
  184. package/components/table/internal/reorder-handle.d.ts +9 -0
  185. package/components/table/internal/reorder-layout-context.d.ts +16 -0
  186. package/components/table/internal/table-header.d.ts +1 -0
  187. package/components/table/internal/virtualization.d.ts +41 -0
  188. package/components/table/item-virtualization.d.ts +37 -0
  189. package/components/table/item-virtualization.js +73 -0
  190. package/components/table/reorder-animation.d.ts +37 -0
  191. package/components/table/reorder-animation.js +18 -0
  192. package/components/table/reorder-item-layout.d.ts +32 -0
  193. package/components/table/reorder-item-layout.js +57 -0
  194. package/components/table/table-const.d.ts +10 -0
  195. package/components/table/table-const.js +13 -0
  196. package/components/table/table-primitives.d.ts +64 -0
  197. package/components/table/table-primitives.js +180 -0
  198. package/components/table/table-props.d.ts +304 -0
  199. package/components/table/table-props.js +1 -0
  200. package/components/table/table.d.ts +231 -107
  201. package/components/table/table.js +351 -346
  202. package/components/tabs/collapsible-more.js +1 -1
  203. package/components/tabs/collapsible-tab.js +1 -1
  204. package/components/tabs/collapsible-tabs.js +1 -1
  205. package/components/tabs/dumb-tabs.js +1 -1
  206. package/components/tabs/smart-tabs.js +1 -1
  207. package/components/tabs/tab-link.js +1 -1
  208. package/components/tabs/tabs.js +1 -1
  209. package/components/tag/tag.js +1 -1
  210. package/components/tags-input/tags-input.d.ts +3 -1
  211. package/components/tags-input/tags-input.js +4 -4
  212. package/components/tags-list/tags-list.js +2 -2
  213. package/components/toggle/toggle.js +1 -1
  214. package/components/tooltip/tooltip.d.ts +2 -1
  215. package/components/tooltip/tooltip.js +5 -3
  216. package/components/upload/upload.d.ts +4 -3
  217. package/components/upload/upload.js +7 -30
  218. package/components/user-agreement/service.js +3 -3
  219. package/components/user-agreement/user-agreement.js +2 -2
  220. package/components/user-card/card.js +4 -4
  221. package/components/user-card/smart-user-card-tooltip.js +3 -3
  222. package/components/user-card/tooltip.js +3 -3
  223. package/components/user-card/user-card.js +5 -5
  224. package/components/util-stories.d.ts +26 -0
  225. package/package.json +8 -9
  226. package/components/__mocks__/old-browsers-message.js +0 -3
  227. package/components/_helpers/grid.js +0 -3
  228. package/components/_helpers/sidebar.js +0 -110
  229. package/components/content-layout/content-layout.d.ts +0 -20
  230. package/components/content-layout/content-layout.js +0 -50
  231. package/components/content-layout/sidebar.d.ts +0 -26
  232. package/components/content-layout/sidebar.js +0 -5
  233. package/components/date-picker/use-intersection-observer.d.ts +0 -6
  234. package/components/date-picker/use-intersection-observer.js +0 -93
  235. package/components/expand/collapsible-group.d.ts +0 -8
  236. package/components/expand/collapsible-group.js +0 -52
  237. package/components/global/composeRefs.d.ts +0 -6
  238. package/components/global/composeRefs.js +0 -9
  239. package/components/global/use-event-callback.d.ts +0 -4
  240. package/components/global/use-event-callback.js +0 -49
  241. package/components/grid/col.d.ts +0 -16
  242. package/components/grid/col.js +0 -63
  243. package/components/grid/grid.d.ts +0 -13
  244. package/components/grid/grid.js +0 -27
  245. package/components/grid/row.d.ts +0 -21
  246. package/components/grid/row.js +0 -72
  247. package/components/old-browsers-message/old-browsers-message-stop.d.ts +0 -1
  248. package/components/old-browsers-message/old-browsers-message-stop.js +0 -5
  249. package/components/old-browsers-message/old-browsers-message.d.ts +0 -5
  250. package/components/old-browsers-message/old-browsers-message.js +0 -89
  251. package/components/old-browsers-message/white-list.d.ts +0 -2
  252. package/components/old-browsers-message/white-list.js +0 -30
  253. package/components/table/selection-adapter.d.ts +0 -6
  254. /package/components/{table → legacy-table}/cell.d.ts +0 -0
  255. /package/components/{table → legacy-table}/disable-hover-hoc.d.ts +0 -0
  256. /package/components/{table → legacy-table}/disable-hover-hoc.js +0 -0
  257. /package/components/{table → legacy-table}/header-cell.d.ts +0 -0
  258. /package/components/{table → legacy-table}/header.d.ts +0 -0
  259. /package/components/{table → legacy-table}/multitable.js +0 -0
  260. /package/components/{table → legacy-table}/row-with-focus-sensor.d.ts +0 -0
  261. /package/components/{table → legacy-table}/selection-adapter.js +0 -0
  262. /package/components/{table → legacy-table}/selection-shortcuts-hoc.js +0 -0
@@ -0,0 +1,304 @@
1
+ import type { AriaAttributes, ReactNode, RefObject } from 'react';
2
+ export interface TableProps<T> {
3
+ /**
4
+ * The data items to render. `null` and `undefined` items are not supported.
5
+ * Referentially identical items are not supported either.
6
+ */
7
+ data: readonly T[];
8
+ /**
9
+ * Column definitions.
10
+ */
11
+ columns: readonly Column<T>[];
12
+ /**
13
+ * Used as a key in the items list.
14
+ */
15
+ getKey: (item: T, index: number, items: readonly T[]) => React.Key;
16
+ /**
17
+ * If `true`, the table header will not be rendered.
18
+ *
19
+ * Note that this may impact accessibility. If necessary, provide additional
20
+ * information via `aria-label` or `aria-description` on the `Table` element.
21
+ */
22
+ noHeader?: boolean;
23
+ /**
24
+ * If true, renders a sticky header.
25
+ */
26
+ stickyHeader?: boolean;
27
+ /**
28
+ * Called when the user clicks the sort button in a column header.
29
+ * The client is expected to update the `columns` prop with the new
30
+ * sort order for the corresponding column, and update the data accordingly.
31
+ */
32
+ onSort?: (columnIndex: number, newOrder: SortOrder, columns: readonly Column<T>[]) => void;
33
+ /**
34
+ * Called when the user clicks on a column delete button in the header.
35
+ * The client is expected to update the `columns` prop with the column removed.
36
+ */
37
+ onColumnDelete?: (column: Column<T>, columnIndex: number, columns: readonly Column<T>[]) => void;
38
+ /**
39
+ * Called when the user reorders columns by dragging a column.
40
+ * The `insertionIndex` parameter represents an insertion position in the original,
41
+ * unchanged `columns` array before the column is removed.
42
+ *
43
+ * One possible implementation is:
44
+ *
45
+ * ```ts
46
+ * columns.splice(fromIndex, 1);
47
+ * columns.splice(fromIndex < insertionIndex ? insertionIndex - 1 : insertionIndex, 0, columnBeingReordered);
48
+ * ```
49
+ *
50
+ * The callback is not called when the reorder operation would not change the
51
+ * column order, i.e. when
52
+ * `insertionIndex === fromIndex || insertionIndex === fromIndex + 1`.
53
+ */
54
+ onColumnReorder?: (columnBeingReordered: Column<T>, fromIndex: number, insertionIndex: number, columns: readonly Column<T>[]) => void;
55
+ /**
56
+ * By default, when a column is reordered, the moved column is highlighted
57
+ * with a temporary background color. Set `true` to disable this animation.
58
+ */
59
+ noColumnReorderAnimation?: boolean;
60
+ /**
61
+ * If defined, determines whether an item may be reordered to a specific insertion position.
62
+ * If not defined, any item may be reordered to any position.
63
+ */
64
+ canReorderItem?: (itemBeingReordered: T, fromIndex: number, insertionIndex: number, items: readonly T[]) => boolean;
65
+ /**
66
+ * Called when the user reorders items by dragging a handle.
67
+ * The `insertionIndex` parameter represents an insertion position in the original,
68
+ * unchanged `data` array before the item is removed. See {@link TableProps.onColumnReorder}
69
+ * for an example implementation.
70
+ *
71
+ * To make reorder possible, render `ItemReorderHandle` (from `table-primitives`)
72
+ * anywhere in a row.
73
+ *
74
+ * The callback is not called when the reorder operation would not change the
75
+ * item order, i.e. when
76
+ * `insertionIndex === fromIndex || insertionIndex === fromIndex + 1`.
77
+ */
78
+ onItemReorder?: (itemBeingReordered: T, fromIndex: number, insertionIndex: number, items: readonly T[]) => void;
79
+ /**
80
+ * By default, when an item is reordered, the moved item is highlighted
81
+ * with a temporary background color. Set `true` to disable this animation.
82
+ */
83
+ noItemReorderAnimation?: boolean;
84
+ /**
85
+ * Customizes how an item is rendered.
86
+ *
87
+ * Return `DefaultItemRenderer` to configure row-specific behavior such as
88
+ * `clickable`, `keyboardFocusable`, event handlers, `className`, or `ref`.
89
+ *
90
+ * You can also return custom row(s) instead. See the `Table` documentation
91
+ * for details.
92
+ */
93
+ renderItem?: (item: T, index: number, items: readonly T[]) => ReactNode;
94
+ /**
95
+ * Only renders rows near the viewport.
96
+ *
97
+ * Rows may transition between two states:
98
+ * - materialized: rendered as actual table rows. This happens when
99
+ * the corresponding spacer approaches the viewport, as specified by
100
+ * `lookaheadPx`.
101
+ * - virtualized: replaced with spacer rows of the same height. This happens
102
+ * when the row moves sufficiently far from the viewport, as specified by
103
+ * `retentionMarginPx`.
104
+ *
105
+ * Toggling this prop should normally work as expected, but a seamless
106
+ * transition is not guaranteed: the scroll position may reset to the top.
107
+ * However, if row height estimates are accurate and the data has not
108
+ * changed, the browser may apply scroll anchoring, resulting in a smoother
109
+ * transition, possibly with brief flickering but without scroll jumps.
110
+ */
111
+ virtualizeRows?: boolean;
112
+ /**
113
+ * Used with `virtualizeRows` as the source of scroll events, the target of
114
+ * `ResizeObserver`, and the root of `IntersectionObserver`. Required when
115
+ * the scrollable container is not the whole document.
116
+ *
117
+ * If not set:
118
+ * - the scroll listener is attached to `window`
119
+ * - `ResizeObserver` observes `document.body`
120
+ * - `IntersectionObserver` has no root (i.e. the viewport is used)
121
+ *
122
+ * Note that if this scroller is nested inside another scrollable container,
123
+ * the outer container is not tracked. As a result, items may not materialize
124
+ * until the inner scroller is scrolled.
125
+ *
126
+ * Support for nested scroll containers may be added in the future.
127
+ */
128
+ scrollerRef?: RefObject<HTMLElement | null>;
129
+ /**
130
+ * Used with `virtualizeRows` to estimate the height of items that have not
131
+ * been rendered yet. The function should be fast and side-effect free.
132
+ * Do not measure the DOM here. Once a row is rendered, its actual height
133
+ * will be measured and used instead of this estimate.
134
+ *
135
+ * Note the effects of imprecise estimates:
136
+ * - When the height is underestimated, the table may materialize more rows
137
+ * than specified by `lookaheadPx`. If the resulting rows extend beyond
138
+ * `retentionMarginPx`, they will be virtualized again. If this causes
139
+ * relayout flickering, increase `retentionMarginPx`.
140
+ * - When the height is overestimated, the table may materialize fewer rows
141
+ * than specified by `lookaheadPx`, which may leave a spacer partially
142
+ * visible. To avoid this, increase `lookaheadPx` (and `retentionMarginPx`
143
+ * accordingly, since it should be greater than `lookaheadPx`).
144
+ *
145
+ * Default: 37px = 16px padding + 20px line height + 1px border.
146
+ */
147
+ estimateHeight?: (item: T, index: number, items: readonly T[]) => number;
148
+ /**
149
+ * When using `virtualizeRows`, the number of pixels above and below
150
+ * the viewport to materialize in advance.
151
+ *
152
+ * Increase this value if blank space becomes visible during fast scrolling.
153
+ *
154
+ * Default: 400px.
155
+ */
156
+ lookaheadPx?: number;
157
+ /**
158
+ * Used with `virtualizeRows`. Additional margin around the viewport before
159
+ * materialized rows become eligible for virtualization.
160
+ *
161
+ * Increasing this value reduces row churn when heights are underestimated.
162
+ * In that case, the table may materialize more rows than needed and then
163
+ * immediately virtualize them again. A larger margin keeps such rows
164
+ * rendered for longer, at the cost of rendering more rows overall.
165
+ *
166
+ * This value should be greater than `lookaheadPx`. Increase it if you notice
167
+ * table relayouts during initial render or scrolling.
168
+ *
169
+ * Default: 450px.
170
+ */
171
+ retentionMarginPx?: number;
172
+ /**
173
+ * When using `virtualizeRows`, ignore scroll and resize position changes
174
+ * smaller than this value.
175
+ *
176
+ * Measurement inaccuracies and rounding artifacts may slightly change the
177
+ * table layout during materialization and virtualization. With scroll
178
+ * anchoring enabled (the default browser behavior), the browser may then
179
+ * adjust the scroll position, triggering additional scroll or resize events.
180
+ * Small deltas are ignored to prevent such feedback loops from causing
181
+ * oscillations at virtualization boundaries.
182
+ *
183
+ * Increase if you expect high inaccuracy in height measurements, or if you
184
+ * notice oscillations at virtualization boundaries.
185
+ *
186
+ * Default: 50px.
187
+ */
188
+ minScrollAndResizeDeltaPx?: number;
189
+ /**
190
+ * "Column editing mode" is a mode in which controls that are normally hidden
191
+ * become visible, such as column reorder and delete buttons.
192
+ *
193
+ * When this prop is `undefined`, the component manages the mode internally.
194
+ * Users can toggle it by tapping the table header on mobile or by clicking
195
+ * the column edit button, if enabled. Since tapping the table header is not
196
+ * discoverable by assistive technologies, it's recommended to enable
197
+ * `columnEditButton` when using the internal mode.
198
+ *
199
+ * Alternatively, pass `true` or `false` to control the mode externally.
200
+ */
201
+ columnEditing?: boolean;
202
+ /**
203
+ * Called when the user requests to enter or leave column editing mode.
204
+ *
205
+ * The `source` parameter indicates what triggered the request.
206
+ *
207
+ * When `columnEditing` is not controlled, the component automatically
208
+ * applies the requested change internally.
209
+ *
210
+ * When `columnEditing` is controlled externally and you still want to
211
+ * respond to user requests, use this callback to decide whether to
212
+ * update the mode.
213
+ */
214
+ onColumnEditingRequest?: (editing: boolean, source: 'header' | 'edit-button') => void;
215
+ /**
216
+ * Whether to show a small gear button in the top-right corner that
217
+ * toggles column editing mode.
218
+ *
219
+ * For accessibility, it's recommended to enable this button unless you
220
+ * provide an external control for toggling column editing mode.
221
+ */
222
+ columnEditButton?: boolean;
223
+ /**
224
+ * Applied to the `<thead>` element.
225
+ */
226
+ theadClassName?: string;
227
+ /**
228
+ * Applied to the only `<tr>` element within the `<thead>`.
229
+ */
230
+ theadTrClassName?: string;
231
+ /**
232
+ * Applied to the `<tbody>` element.
233
+ */
234
+ tbodyClassName?: string;
235
+ }
236
+ export type SortOrder = Extract<AriaAttributes['aria-sort'], 'none' | 'ascending' | 'descending'>;
237
+ /**
238
+ * The column specification.
239
+ */
240
+ export interface Column<T> {
241
+ /**
242
+ * Used as a key in the columns list.
243
+ */
244
+ key: React.Key;
245
+ /**
246
+ * Used in `aria-label`s of column controls which do not contain text,
247
+ * such as the delete column button. If not set, the `String(key)` is used.
248
+ */
249
+ name?: string;
250
+ /**
251
+ * Renders the content of the column header, excluding controls such as
252
+ * the sort and delete buttons. If not specified, the default behavior is
253
+ * `name ?? String(key)`.
254
+ */
255
+ renderHeader?: () => ReactNode;
256
+ /**
257
+ * Renders the value of a single cell. If not specified, the default
258
+ * behavior is:
259
+ *
260
+ * - If `item` is an `Array`, renders `String(item[columnIndex])`
261
+ * - If `item` is an `Object`, renders `String(item[String(columnKey)])`
262
+ * - Otherwise:
263
+ * - The first column renders `String(item)`
264
+ * - Other columns render an empty string
265
+ */
266
+ renderCell?: (item: T, index: number, items: readonly T[]) => ReactNode;
267
+ /**
268
+ * If the column gets an indent when `DefaultItemRendererProps.level` returns
269
+ * a positive number.
270
+ */
271
+ indent?: boolean;
272
+ /**
273
+ * If set, displays sort button and includes `aria-sort` in the column header.
274
+ * Handle clicks with {@link TableProps.onSort}.
275
+ */
276
+ sortOrder?: AriaAttributes['aria-sort'];
277
+ /**
278
+ * Whether to display a delete button in the column header.
279
+ * Handle delete requests with {@link TableProps.onColumnDelete}.
280
+ * Make sure {@link Column.name} or {@link Column.key} is meaningful,
281
+ * as it will be included in the `aria-label` of the delete button.
282
+ */
283
+ deletable?: boolean;
284
+ /**
285
+ * Displays a reorder handle in the column header.
286
+ * Handle reorder requests with {@link TableProps.onColumnReorder}.
287
+ * If a function is provided, it determines whether the column may be moved
288
+ * to the specified insertion position.
289
+ *
290
+ * Make sure {@link Column.name} or {@link Column.key} is meaningful,
291
+ * as it will be included in the `aria-label` of the reorder button.
292
+ */
293
+ canReorder?: boolean | ((columnBeingReordered: Column<T>, fromIndex: number, insertionIndex: number, columns: readonly Column<T>[]) => boolean);
294
+ /**
295
+ * The class name to apply to the `th` element inside `table > thead`.
296
+ */
297
+ thClassName?: string;
298
+ /**
299
+ * The class name to apply to the `td` element inside `table > tbody`.
300
+ * If a custom `TableProps.renderItem` is provided, this prop is not used,
301
+ * unless the custom renderer falls back to the `DefaultItemRenderer`.
302
+ */
303
+ tdClassName?: string | ((item: T, index: number, items: readonly T[]) => string | undefined);
304
+ }
@@ -0,0 +1 @@
1
+
@@ -1,109 +1,233 @@
1
+ import React, { type ComponentPropsWithRef } from 'react';
2
+ import type { TableProps } from './table-props';
1
3
  /**
2
- * @name Table
4
+ * Table component replacing the tables in the `legacy-table` folder.
5
+ *
6
+ * This documentation provides an overview of the most common usage patterns.
7
+ * See individual props and exported components for detailed behavior.
8
+ *
9
+ * ## Minimal usage
10
+ *
11
+ * You need the following props:
12
+ * - `data`
13
+ * - `getKey`
14
+ * - `columns`
15
+ * - `key`
16
+ * - `name` (optional but needed in most cases)
17
+ * - `renderCell` (optional but needed in most cases)
18
+ *
19
+ * ## Item rendering
20
+ *
21
+ * If `renderItem` is not specified, each item is rendered using
22
+ * `DefaultItemRenderer` (from `table/default-item-renderer`)
23
+ * as if the following code were used:
24
+ *
25
+ * ```tsx
26
+ * <Table
27
+ * renderItem={(_item, index, _items) => (
28
+ * <DefaultItemRenderer index={index} />
29
+ * )}
30
+ * />
31
+ * ```
32
+ *
33
+ * `DefaultItemRenderer` renders a table row using the column definitions
34
+ * (`Column.renderCell`) and provides built-in support for features such as
35
+ * selection, keyboard navigation, and virtualization. It also accepts all
36
+ * standard `tr` attributes, including `ref`.
37
+ *
38
+ * Use `renderItem` to configure `DefaultItemRenderer` for each item:
39
+ *
40
+ * ```tsx
41
+ * <Table
42
+ * renderItem={(item, index, items) => (
43
+ * <DefaultItemRenderer
44
+ * index={index}
45
+ * keyboardFocusable
46
+ * className='my-item'
47
+ * onClick={e => handleClick(e, item, items)}
48
+ * />
49
+ * )}
50
+ * />
51
+ * ```
52
+ *
53
+ * If you need complete control over rendering, `renderItem` can instead
54
+ * return your own table rows. See "Custom item rendering" below.
55
+ *
56
+ * ## Selection
57
+ *
58
+ * Selection is typically implemented using the following props
59
+ * of the `DefaultItemRenderer`:
60
+ *
61
+ * - `clickable`
62
+ * - `selected`
63
+ * - `onClick` or `onPointerUp`, etc.
64
+ *
65
+ * The following utilities (from `global`) may come in handy:
66
+ *
67
+ * - `TableSelection` class to manage selection state
68
+ * - An alternative approach is to keep a `selected` field on each item
69
+ * - `isWithinInteractiveElement()` to check if a click was made on a control
70
+ * or on "empty space"
71
+ *
72
+ * ```tsx
73
+ * <Table
74
+ * renderItem={(item, index) => (
75
+ * <DefaultItemRenderer
76
+ * index={index}
77
+ * clickable
78
+ * selected={selection.isSelected(item)}
79
+ * onClick={e => {
80
+ * if (!isWithinInteractiveElement(e)) {
81
+ * setSelection(selection.toggleSelection(item));
82
+ * }
83
+ * }}
84
+ * />
85
+ * )}
86
+ * />
87
+ * ```
88
+ *
89
+ * Note that for accessibility reasons, you should have a cell with a checkbox
90
+ * to display and toggle item selection.
91
+ *
92
+ * ## Row focus
93
+ *
94
+ * The table implements the ["roving tabindex"](https://developer.mozilla.org/en-US/docs/Web/Accessibility/Guides/Keyboard-navigable_JavaScript_widgets#technique_1_roving_tabindex)
95
+ * technique to focus rows with the up/down arrow keys.
96
+ * Rows can also be focused on click or other pointer events.
97
+ * To support it, use the following props of the `DefaultItemRenderer`:
98
+ *
99
+ * - `keyboardFocusable`
100
+ * - `clickable`, if you want to react to hover
101
+ * - `onClick`, if you want to focus on click
102
+ *
103
+ * Useful utils:
104
+ * - `focusWithTemporaryTabIndex()` from `global` to focus a row temporarily
105
+ * patching its `tabindex`.
106
+ *
107
+ * ```tsx
108
+ * <Table
109
+ * renderItem={(item, index) => (
110
+ * <DefaultItemRenderer
111
+ * index={index}
112
+ * clickable
113
+ * keyboardFocusable
114
+ * onClick={e => {
115
+ * if (!isWithinInteractiveElement(e)) {
116
+ * focusWithTemporaryTabIndex(e.currentTarget);
117
+ * }
118
+ * }}
119
+ * />
120
+ * )}
121
+ * />
122
+ * ```
123
+ *
124
+ * Note that the table does not implement standard accessibility patterns such
125
+ * as `grid` or `treegrid`, so row focus is not announced by screen readers.
126
+ * Make sure all essential actions remain available without row focus, for
127
+ * example via standard Tab navigation.
128
+ *
129
+ * ## Sorting
130
+ *
131
+ * You need the following to support sorting:
132
+ *
133
+ * - Set `Column.sortOrder` to `'none'`, `'ascending'` or `'descending'`
134
+ * to render the sort button, `aria-sort`, and indicate the current
135
+ * sort order.
136
+ * - Handle `TableProps.onSort` callback in the client code.
137
+ *
138
+ * ## Deleting columns
139
+ *
140
+ * You need the following to support deleting columns:
141
+ *
142
+ * - Set `Column.deletable` to `true`. This will render a delete button in the
143
+ * column header.
144
+ * - Make sure the `column` has a proper `name` or `key` prop, which will be
145
+ * automatically included in the aria-label of the column delete button.
146
+ * - Handle `TableProps.onColumnDelete` callback in the client code. It is
147
+ * expected to update `columns` by removing the corresponding column.
148
+ *
149
+ * ## Moving columns
150
+ *
151
+ * - Set `Column.canReorder` to `true` or to predicate specifying possible
152
+ * insertion targets.
153
+ * This will render a reorder button in the column header.
154
+ * - Make sure the `column` has a proper `name` or `key` prop, which will be
155
+ * automatically included in the aria-label of the column reorder button.
156
+ * - Handle `TableProps.onColumnReorder` callback in the client code. It is
157
+ * expected to update `columns` by moving the corresponding column to the
158
+ * new position.
159
+ *
160
+ * ## Item reorder
161
+ *
162
+ * To allow the user to reorder rows by dragging:
163
+ *
164
+ * - Place `ItemReorderHandle` (from `table/table-primitives`) anywhere inside
165
+ * a cell. It renders a drag icon button the user can grab to reorder the row.
166
+ * - Handle `TableProps.onItemReorder`. It is expected to update `data` by
167
+ * moving the item to the new position.
168
+ * - Optionally, set `TableProps.canReorderItem` to restrict which positions
169
+ * an item may be dropped into.
170
+ *
171
+ * By default, dragging shows a drag frame (a border around the dragged row)
172
+ * and an insertion indicator (a line between rows showing where the item will
173
+ * land). To implement fully custom drag visuals, set `noDragFrame` and
174
+ * `noHandleTranslate` on `ItemReorderHandle` and use its `onUserDrag` callback
175
+ * to track the drag lifecycle.
176
+ *
177
+ * ## Row virtualization
178
+ *
179
+ * To render only rows near the viewport while replacing off-screen rows with
180
+ * spacers, use:
181
+ *
182
+ * - `virtualizeRows` prop set to `true`
183
+ * - `scrollerRef` — required when the scrollable container is not the whole
184
+ * document
185
+ * - `estimateHeight` — recommended when rows are expected to be taller than
186
+ * the default height (e.g. multiline or custom content)
187
+ * - Fine-tuning props: `lookaheadPx`, `retentionMarginPx`,
188
+ * `minScrollAndResizeDeltaPx`
189
+ *
190
+ * ## Custom item rendering
191
+ *
192
+ * Use the `renderItem` prop to render an item in a completely custom way.
193
+ * The prop is expected to return one or more table rows for the item.
194
+ * Use `TableRow` and `TableCell` from `table/table-primitives` to apply
195
+ * the default row and cell styles.
196
+ *
197
+ * ### Focus
198
+ *
199
+ * Just like `DefaultItemRenderer`, `TableRow` accepts the
200
+ * `keyboardFocusable` prop.
201
+ *
202
+ * Focusable rows rendered by either component form a single keyboard
203
+ * navigation sequence.
204
+ *
205
+ * ### Virtualization
206
+ *
207
+ * If `Table.virtualizeRows` is set to `true`, you need to handle visibility
208
+ * for your custom-rendered component yourself with the
209
+ * `useItemVirtualization()` hook (from `table/item-virtualization`). The hook
210
+ * allows observing the intersection of one or multiple elements rendered for
211
+ * the item, and, based on their intersection status, reporting the item as
212
+ * eligible for virtualization.
213
+ *
214
+ * If you use `DefaultItemRenderer` as part of your custom row renderer,
215
+ * set the `noItemVirtualization` prop to `true`, otherwise it will also try
216
+ * to control the virtualization, possibly reporting incorrect item height.
217
+ *
218
+ * ### Item reorder
219
+ *
220
+ * If `TableProps.onItemReorder` is set and your item spans multiple rows, call
221
+ * `useReorderItemLayout()` (from `table/reorder-item-layout`) to register the
222
+ * item's boundaries so the insertion indicator and insertion point calculation
223
+ * are correct. If `DefaultItemRenderer` is included inside your custom renderer,
224
+ * set its `noReorderLayout` prop to `true` to prevent double registration.
225
+ *
226
+ * ### Reorder animation
227
+ *
228
+ * After a column or item is reordered, the table briefly highlights the moved
229
+ * element. To apply the same animation in your custom-rendered rows, use
230
+ * `useReorderAnimation()` (from `table/reorder-animation`) to get information
231
+ * about the currently animated column or item.
3
232
  */
4
- import { Component, PureComponent, type ReactNode, type SyntheticEvent } from 'react';
5
- import * as React from 'react';
6
- import { type OnChangeMeta } from 'react-movable/lib/types';
7
- import { type FocusSensorAddProps, type FocusSensorProps } from '../global/focus-sensor-hoc';
8
- import { type SelectionShortcutsAddProps, type SelectionShortcutsProps } from './selection-shortcuts-hoc';
9
- import { type DisableHoverAddProps, type DisableHoverProps } from './disable-hover-hoc';
10
- import Row from './row-with-focus-sensor';
11
- import { type Column, type SortParams } from './header-cell';
12
- export interface ReorderParams<T> {
13
- data: T[];
14
- oldIndex: number;
15
- newIndex: number;
16
- }
17
- export interface TableProps<T extends object> extends FocusSensorAddProps<HTMLTableRowElement>, SelectionShortcutsAddProps<T>, DisableHoverAddProps {
18
- data: readonly T[];
19
- columns: readonly Column<T>[] | ((item: T | null) => readonly Column<T>[]);
20
- isItemSelectable: (item: T) => boolean;
21
- loading: boolean;
22
- onSort: (params: SortParams) => void;
23
- onReorder: (params: ReorderParams<T>) => void;
24
- getItemKey: (item: T) => string | number;
25
- sortKey: string;
26
- sortOrder: boolean;
27
- draggable: boolean;
28
- alwaysShowDragHandle: boolean;
29
- dragHandleTitle?: string;
30
- stickyHeader: boolean;
31
- wideFirstColumn: boolean;
32
- getItemLevel: (item: T) => number;
33
- getItemClassName: (item: T) => string | null | undefined;
34
- getMetaColumnClassName: (item: T) => string | null | undefined;
35
- getItemDataTest: (item: T) => string | null | undefined;
36
- isItemCollapsible: (item: T) => boolean;
37
- isParentCollapsible: (item: T) => boolean;
38
- isItemCollapsed: (item: T) => boolean;
39
- onItemCollapse: (item: T) => void;
40
- onItemExpand: (item: T) => void;
41
- onItemDoubleClick: (item: T) => void;
42
- onItemClick: (item: T, e: React.MouseEvent<HTMLTableRowElement>) => void;
43
- remoteSelection: boolean;
44
- isDisabledSelectionVisible: (item: T) => boolean;
45
- getCheckboxTooltip: (item: T) => string | undefined;
46
- className?: string | null | undefined;
47
- wrapperClassName?: string | null | undefined;
48
- headerClassName?: string | null | undefined;
49
- cellClassName?: string | null | undefined;
50
- loaderClassName?: string | undefined;
51
- caption?: string | null | undefined;
52
- stickyHeaderOffset?: string | undefined;
53
- renderEmpty?: (() => ReactNode) | null | undefined;
54
- RowComponent: typeof Row;
55
- renderLoader?: ((loaderClassName?: string) => ReactNode) | null | undefined;
56
- }
57
- /**
58
- * Interactive table with selection and keyboard navigation support.
59
- */
60
- export declare class Table<T extends object> extends PureComponent<TableProps<T>> {
61
- static defaultProps: {
62
- isItemSelectable: () => boolean;
63
- loading: boolean;
64
- onSort: () => void;
65
- onReorder: () => void;
66
- getItemKey: (item: object) => string | number;
67
- sortKey: string;
68
- sortOrder: boolean;
69
- draggable: boolean;
70
- alwaysShowDragHandle: boolean;
71
- stickyHeader: boolean;
72
- getItemLevel: () => number;
73
- getItemClassName: () => null;
74
- getMetaColumnClassName: () => null;
75
- getItemDataTest: () => null;
76
- isItemCollapsible: () => boolean;
77
- isParentCollapsible: () => boolean;
78
- isItemCollapsed: () => boolean;
79
- onItemCollapse: () => void;
80
- onItemExpand: () => void;
81
- onItemDoubleClick: () => void;
82
- onItemClick: () => void;
83
- remoteSelection: boolean;
84
- isDisabledSelectionVisible: () => boolean;
85
- getCheckboxTooltip: () => undefined;
86
- RowComponent: typeof Row;
87
- wideFirstColumn: boolean;
88
- };
89
- state: {
90
- shortcutsScope: string;
91
- userSelectNone: boolean;
92
- };
93
- componentDidMount(): void;
94
- componentDidUpdate({ data, selection, onSelect, selectable, remoteSelection }: TableProps<T>): void;
95
- componentWillUnmount(): void;
96
- onMouseDown: (e: React.MouseEvent) => void;
97
- onMouseUp: () => void;
98
- onRowFocus: (row: T) => void;
99
- onRowSelect: (row: T, selected: boolean) => void;
100
- onSortEnd: ({ oldIndex, newIndex }: OnChangeMeta) => void;
101
- onCheckboxChange: (e: SyntheticEvent<HTMLInputElement>) => void;
102
- restoreFocusWithoutScroll: () => void;
103
- render(): React.JSX.Element;
104
- }
105
- export type TableAttrs<T extends object> = DisableHoverProps<SelectionShortcutsProps<T, FocusSensorProps<TableProps<T>, HTMLTableRowElement, typeof Table>>>;
106
- export default class TableContainer<T extends object> extends Component<TableAttrs<T>> {
107
- Table: React.ComponentClass<DisableHoverProps<SelectionShortcutsProps<T, FocusSensorProps<TableProps<T>, HTMLTableRowElement, typeof Table>>>, any>;
108
- render(): React.JSX.Element;
109
- }
233
+ export default function Table<T>(props: TableProps<T> & ComponentPropsWithRef<'table'>): React.JSX.Element;