@react-fabric/data 1.0.0-beta.5 → 1.0.0-beta.52

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 (109) hide show
  1. package/{src/histogram/Histogram.module.css → css/_histogram.css} +16 -13
  2. package/css/styles.css +24 -0
  3. package/dist/cjs/checklist/CheckList.js +48 -16
  4. package/dist/cjs/histogram/Histogram.js +48 -10
  5. package/dist/cjs/hooks/useFilteredList.js +20 -0
  6. package/dist/cjs/hooks/usePagination.js +27 -4
  7. package/dist/cjs/hooks/useSelectableList.js +29 -0
  8. package/dist/cjs/i18n/ar.json.js +8 -1
  9. package/dist/cjs/i18n/en.json.js +8 -1
  10. package/dist/cjs/json/JsonViewer.js +67 -27
  11. package/dist/cjs/pagination/Pagination.js +10 -0
  12. package/dist/cjs/table/AddColumn.js +1 -1
  13. package/dist/cjs/table/BodyCell.js +38 -5
  14. package/dist/cjs/table/BodyRow.js +107 -0
  15. package/dist/cjs/table/CheckboxCell.js +1 -1
  16. package/dist/cjs/table/ColumnFilters.js +97 -0
  17. package/dist/cjs/table/HeaderCell.js +70 -37
  18. package/dist/cjs/table/Table.js +113 -71
  19. package/dist/cjs/table/types.js +29 -0
  20. package/dist/cjs/table/useResizer.js +4 -4
  21. package/dist/cjs/table/useVirtualTable.js +122 -18
  22. package/dist/cjs/tree/TreeNode.js +45 -25
  23. package/dist/cjs/tree/TreePanel.js +28 -10
  24. package/dist/cjs/tree/useTree.js +97 -15
  25. package/dist/cjs/tree/utils.js +20 -5
  26. package/dist/cjs/virtual/Gallery.js +84 -35
  27. package/dist/cjs/virtual/List.js +82 -32
  28. package/dist/esm/checklist/CheckList.js +50 -18
  29. package/dist/esm/histogram/Histogram.js +49 -11
  30. package/dist/esm/hooks/useFilteredList.js +20 -0
  31. package/dist/esm/hooks/usePagination.js +27 -4
  32. package/dist/esm/hooks/useSelectableList.js +29 -0
  33. package/dist/esm/i18n/ar.json.js +8 -2
  34. package/dist/esm/i18n/en.json.js +8 -2
  35. package/dist/esm/json/JsonViewer.js +68 -28
  36. package/dist/esm/pagination/Pagination.js +10 -0
  37. package/dist/esm/table/AddColumn.js +1 -1
  38. package/dist/esm/table/BodyCell.js +38 -5
  39. package/dist/esm/table/BodyRow.js +107 -0
  40. package/dist/esm/table/CheckboxCell.js +1 -1
  41. package/dist/esm/table/ColumnFilters.js +97 -0
  42. package/dist/esm/table/HeaderCell.js +71 -38
  43. package/dist/esm/table/Table.js +115 -73
  44. package/dist/esm/table/types.js +29 -0
  45. package/dist/esm/table/useResizer.js +4 -4
  46. package/dist/esm/table/useVirtualTable.js +124 -20
  47. package/dist/esm/tree/TreeNode.js +47 -27
  48. package/dist/esm/tree/TreePanel.js +28 -10
  49. package/dist/esm/tree/useTree.js +99 -17
  50. package/dist/esm/tree/utils.js +20 -5
  51. package/dist/esm/virtual/Gallery.js +84 -35
  52. package/dist/esm/virtual/List.js +82 -32
  53. package/dist/types/checklist/CheckList.d.ts +24 -2
  54. package/dist/types/histogram/Histogram.d.ts +31 -4
  55. package/dist/types/hooks/useFilteredList.d.ts +20 -2
  56. package/dist/types/hooks/usePagination.d.ts +19 -0
  57. package/dist/types/hooks/useSelectableList.d.ts +29 -0
  58. package/dist/types/index.d.ts +1 -1
  59. package/dist/types/json/JsonViewer.d.ts +27 -2
  60. package/dist/types/pagination/Pagination.d.ts +10 -1
  61. package/dist/types/table/AddColumn.d.ts +2 -2
  62. package/dist/types/table/BodyCell.d.ts +4 -3
  63. package/dist/types/table/BodyRow.d.ts +20 -0
  64. package/dist/types/table/ColumnFilters.d.ts +9 -0
  65. package/dist/types/table/EmptyCell.d.ts +2 -2
  66. package/dist/types/table/HeaderCell.d.ts +2 -2
  67. package/dist/types/table/Table.d.ts +14 -1
  68. package/dist/types/table/types.d.ts +48 -7
  69. package/dist/types/table/useTableColumns.d.ts +6 -6
  70. package/dist/types/table/useVirtualTable.d.ts +23 -8
  71. package/dist/types/tree/TreeNode.d.ts +1 -1
  72. package/dist/types/tree/TreePanel.d.ts +42 -1
  73. package/dist/types/tree/types.d.ts +25 -5
  74. package/dist/types/tree/useTree.d.ts +3 -10
  75. package/dist/types/tree/utils.d.ts +4 -1
  76. package/dist/types/virtual/Gallery.d.ts +44 -4
  77. package/dist/types/virtual/List.d.ts +44 -4
  78. package/package.json +13 -10
  79. package/src/checklist/CheckList.tsx +103 -77
  80. package/src/histogram/Histogram.tsx +45 -11
  81. package/src/hooks/useFilteredList.tsx +19 -0
  82. package/src/hooks/usePagination.tsx +32 -7
  83. package/src/hooks/useSelectableList.ts +29 -0
  84. package/src/i18n/ar.json +5 -0
  85. package/src/i18n/en.json +5 -0
  86. package/src/index.ts +1 -1
  87. package/src/json/JsonViewer.tsx +71 -35
  88. package/src/pagination/Pagination.tsx +10 -0
  89. package/src/table/AddColumn.tsx +3 -3
  90. package/src/table/BodyCell.tsx +34 -5
  91. package/src/table/BodyRow.tsx +143 -0
  92. package/src/table/CheckboxCell.tsx +1 -1
  93. package/src/table/ColumnFilters.tsx +105 -0
  94. package/src/table/EmptyCell.tsx +2 -2
  95. package/src/table/HeaderCell.tsx +72 -14
  96. package/src/table/Table.tsx +177 -77
  97. package/src/table/types.ts +52 -6
  98. package/src/table/useResizer.ts +5 -3
  99. package/src/table/useTableColumns.ts +7 -7
  100. package/src/table/useVirtualTable.ts +146 -24
  101. package/src/tree/TreeNode.tsx +98 -56
  102. package/src/tree/TreePanel.tsx +64 -3
  103. package/src/tree/types.ts +32 -4
  104. package/src/tree/useTree.ts +109 -26
  105. package/src/tree/utils.ts +23 -8
  106. package/src/virtual/Gallery.tsx +96 -42
  107. package/src/virtual/List.tsx +82 -33
  108. package/dist/cjs/histogram/Histogram.module.css +0 -1
  109. package/dist/esm/histogram/Histogram.module.css +0 -1
@@ -21,12 +21,25 @@
21
21
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
22
  */
23
23
 
24
- import { EmptyContent, Loading, useDebounce } from "@react-fabric/core";
24
+ import {
25
+ CoreIcons,
26
+ EmptyContent,
27
+ Icon,
28
+ Loading,
29
+ useDebounce,
30
+ } from "@react-fabric/core";
31
+ import { debounce } from "@react-fabric/utilities";
25
32
  import classNames from "classnames";
26
- import { useImperativeHandle, useMemo, useRef } from "react";
33
+ import {
34
+ useEffect,
35
+ useImperativeHandle,
36
+ useLayoutEffect,
37
+ useMemo,
38
+ useRef,
39
+ } from "react";
27
40
  import { useTranslation } from "react-i18next";
28
41
  import { AddColumn } from "./AddColumn";
29
- import { BodyCell } from "./BodyCell";
42
+ import { BodyRow } from "./BodyRow";
30
43
  import { CheckboxCell } from "./CheckboxCell";
31
44
  import { TableProvider } from "./Context";
32
45
  import { EmptyCell } from "./EmptyCell";
@@ -35,16 +48,38 @@ import { type TableProps } from "./types";
35
48
  import { useTableColumns } from "./useTableColumns";
36
49
  import { useVirtualTable } from "./useVirtualTable";
37
50
 
51
+ /**
52
+ * Table component for displaying data in a tabular format with features like sorting, filtering, and virtual scrolling.
53
+ * It supports expandable rows, checkable rows, and customizable columns.
54
+ * The component is designed to handle large datasets efficiently by rendering only the visible rows.
55
+ * It also provides a way to manage column visibility and allows for custom rendering of group headers.
56
+ * Uses TanStack's `useVirtual` for virtualization and React's `useMemo` for performance optimization.
57
+ *
58
+ * @param {TableProps<T>} props - The properties for the Table component.
59
+ * @returns {JSX.Element} The rendered Table component.
60
+ *
61
+ * @see {@link https://adarshpastakia.github.io/react-fabric/?path=/story/data-table--table}
62
+ * @see {@link https://tanstack.com/table/v8/docs/api/virtual}
63
+ */
38
64
  export const Table = <T extends KeyValue = KeyValue>({
39
65
  ref,
40
66
  data,
41
67
  columns,
42
- keyProperty,
68
+ keyProperty = "id",
69
+ groupProperty,
43
70
  checkableRows,
71
+ initialScroll,
44
72
  hideableColumns,
45
73
  sort,
46
74
  loading,
75
+ checked,
76
+ emptyDisplay,
77
+ groupRenderer,
78
+ canExpand,
79
+ children,
47
80
  onSort,
81
+ onFilter,
82
+ onScroll,
48
83
  onRowClick,
49
84
  onCheckedChanged,
50
85
  }: TableProps<T>) => {
@@ -58,13 +93,24 @@ export const Table = <T extends KeyValue = KeyValue>({
58
93
  const {
59
94
  scrollerRef,
60
95
  items,
96
+ top,
61
97
  checkState,
98
+ virtualizer,
99
+ hasActiveSticky,
100
+ toggleExpand,
62
101
  toggleChecked,
63
102
  toggleAllChecked,
103
+ toggleGroupExpand,
64
104
  getData,
65
105
  totalSize,
106
+ isActiveSticky,
66
107
  measureElement,
67
- } = useVirtualTable(data, keyProperty, fireCheckChanged);
108
+ } = useVirtualTable(data, {
109
+ checked,
110
+ keyProperty,
111
+ groupProperty,
112
+ onCheckChanged: fireCheckChanged,
113
+ });
68
114
  const refBody = useRef<HTMLDivElement>(null);
69
115
 
70
116
  const wrapperStart = useMemo(
@@ -76,32 +122,51 @@ export const Table = <T extends KeyValue = KeyValue>({
76
122
  [],
77
123
  );
78
124
 
125
+ useLayoutEffect(() => {
126
+ setTimeout(() => {
127
+ initialScroll &&
128
+ virtualizer.scrollToIndex(initialScroll, { align: "start" });
129
+ }, 100);
130
+ }, []);
131
+
79
132
  useImperativeHandle(
80
133
  ref,
81
134
  () => ({
82
- hilight: (row: number) => {
83
- refBody.current
84
- ?.querySelectorAll<HTMLElement>(`.datatable-row[data-hilight="true"]`)
85
- .forEach((el) => el && (el.dataset.hilight = undefined));
86
- const el = refBody.current?.querySelector<HTMLElement>(
87
- `[data-row="${row}"]`,
88
- );
89
- el?.scrollIntoView({ behavior: "smooth", block: "center" });
90
- el && (el.dataset.hilight = "true");
135
+ scrollTo: (row: number) => {
136
+ virtualizer.scrollToIndex(row, { align: "start" });
91
137
  },
92
- unhilight: () => {
93
- refBody.current
94
- ?.querySelectorAll<HTMLElement>(`.datatable-row[data-hilight="true"]`)
95
- .forEach((el) => el && (el.dataset.hilight = undefined));
138
+ hilight(row) {
139
+ scrollerRef.current
140
+ ?.querySelector(".hilight")
141
+ ?.classList.remove("hilight", "ring-1");
142
+ virtualizer.scrollToIndex(Math.floor(row), {
143
+ align: "start",
144
+ });
145
+ setTimeout(() => {
146
+ scrollerRef.current
147
+ ?.querySelector(`[data-index="${row}"]`)
148
+ ?.classList.add("hilight", "ring-1");
149
+ }, 100);
96
150
  },
97
- scrollTo: (row: number) => {
98
- const el = refBody.current?.querySelector(`[data-row="${row}"]`);
99
- el?.scrollIntoView({ behavior: "smooth" });
151
+ unhilight() {
152
+ scrollerRef.current
153
+ ?.querySelector(".hilight")
154
+ ?.classList.remove("hilight", "ring-1");
100
155
  },
101
156
  }),
102
157
  [],
103
158
  );
104
159
 
160
+ useEffect(() => {
161
+ const handle = debounce((top: number) => {
162
+ onScroll?.(top ?? 0);
163
+ });
164
+ handle(top);
165
+ return () => {
166
+ handle.cancel();
167
+ };
168
+ }, [top]);
169
+
105
170
  return (
106
171
  <TableProvider>
107
172
  <div
@@ -109,10 +174,15 @@ export const Table = <T extends KeyValue = KeyValue>({
109
174
  style={{
110
175
  gridTemplate: `"head" auto "loader" auto "content" 1fr "foot" auto/1fr`,
111
176
  }}
177
+ data-ref="tableScroller"
112
178
  ref={scrollerRef}
113
179
  >
114
- <div className="bg-base font-medium sticky top-0 area-head border-b select-none flex flex-nowrap z-2">
180
+ <div
181
+ data-ref="tableHeader"
182
+ className="bg-base font-medium sticky top-0 h-8 area-head border-b select-none flex flex-nowrap z-2"
183
+ >
115
184
  <div className={wrapperStart}>
185
+ {canExpand && <div className="w-6" />}
116
186
  {checkableRows && (
117
187
  <CheckboxCell
118
188
  state={checkState.allChecked}
@@ -120,15 +190,33 @@ export const Table = <T extends KeyValue = KeyValue>({
120
190
  />
121
191
  )}
122
192
  {state.start?.map((col, idx) => (
123
- <HeaderCell key={idx} {...col} sort={sort} onSort={onSort} />
193
+ <HeaderCell
194
+ key={idx}
195
+ {...col}
196
+ sort={sort}
197
+ onSort={onSort}
198
+ onFilter={onFilter}
199
+ />
124
200
  ))}
125
201
  </div>
126
202
  {state.cols?.map((col, idx) => (
127
- <HeaderCell key={idx} {...col} sort={sort} onSort={onSort} />
203
+ <HeaderCell
204
+ key={idx}
205
+ {...col}
206
+ sort={sort}
207
+ onSort={onSort}
208
+ onFilter={onFilter}
209
+ />
128
210
  ))}
129
211
  <div className={wrapperEnd}>
130
212
  {state.end?.map((col, idx) => (
131
- <HeaderCell key={idx} {...col} sort={sort} onSort={onSort} />
213
+ <HeaderCell
214
+ key={idx}
215
+ {...col}
216
+ sort={sort}
217
+ onSort={onSort}
218
+ onFilter={onFilter}
219
+ />
132
220
  ))}
133
221
 
134
222
  {hideableColumns && (
@@ -142,66 +230,76 @@ export const Table = <T extends KeyValue = KeyValue>({
142
230
  {loading && <Loading />}
143
231
  {data.length > 0 && (
144
232
  <div
145
- className="area-content flex flex-col flex-nowrap"
233
+ className="area-content flex flex-col flex-nowrap min-h-full"
146
234
  style={{ height: totalSize() }}
147
235
  ref={refBody}
148
236
  >
149
- <div style={{ height: items[0]?.start }} />
237
+ <div
238
+ style={{
239
+ height: items[hasActiveSticky ? 1 : 0]?.start,
240
+ }}
241
+ />
150
242
  {items.map(({ index, key }) => {
151
243
  const data = getData(index);
152
- return (
244
+ return "__GROUP__" in data ? (
153
245
  <div
154
246
  key={key}
155
- role="none"
156
- data-row={index}
247
+ ref={measureElement}
248
+ data-index={index}
157
249
  className={classNames(
158
- "flex flex-nowrap datatable-row data-[hilight]:outline-1 -outline-offset-1 outline-primary-500",
159
- index % 2 ? "bg-even" : "bg-odd",
160
- onRowClick && "hover:bg-primary-50 active:bg-primary-100",
250
+ "px-2 py-1 text-md bg-base border-y border-tint-100 cursor-pointer flex items-center gap-1 z-1",
251
+ isActiveSticky(index) && "sticky top-8",
161
252
  )}
162
- onClick={() =>
163
- checkableRows && keyProperty && !onRowClick
164
- ? toggleChecked(data[keyProperty])
165
- : onRowClick?.(data)
166
- }
167
- data-index={index}
168
- ref={measureElement}
253
+ role="none"
254
+ onClick={() => toggleGroupExpand(data.key)}
169
255
  >
170
- <div className={wrapperStart}>
171
- {checkableRows && keyProperty && (
172
- <CheckboxCell
173
- onClick={() => toggleChecked(data[keyProperty])}
174
- state={
175
- checkState.checked.includes(data[keyProperty]) ? 1 : 0
176
- }
177
- />
178
- )}
179
- {state.start?.map((col, ids) => (
180
- <BodyCell
181
- key={`${key}:${ids}`}
182
- column={col}
183
- item={data}
184
- />
185
- ))}
186
- </div>
187
- {state.cols?.map((col, idc) => (
188
- <BodyCell key={`${key}:${idc}`} column={col} item={data} />
189
- ))}
190
- <div className={wrapperEnd}>
191
- {state.end?.map((col, ide) => (
192
- <BodyCell
193
- key={`${key}:${ide}`}
194
- column={col}
195
- item={data}
196
- />
197
- ))}
198
- {hideableColumns && <div className="w-6" />}
199
- </div>
256
+ <Icon
257
+ rtlFlip
258
+ icon={
259
+ data.open ? CoreIcons.chevronDown : CoreIcons.chevronRight
260
+ }
261
+ />
262
+ {groupRenderer?.(data) ?? (
263
+ <div className="flex gap-1 items-center">
264
+ <span>{data.key}</span>
265
+ <span className="text-sm">({data.itemCount})</span>
266
+ </div>
267
+ )}
200
268
  </div>
269
+ ) : (
270
+ <BodyRow
271
+ rowKey={key.toString()}
272
+ index={index}
273
+ checkableRows={checkableRows}
274
+ checked={
275
+ keyProperty &&
276
+ checkState.checked.includes(data[keyProperty])
277
+ ? 1
278
+ : 0
279
+ }
280
+ expanded={
281
+ !!keyProperty &&
282
+ checkState.expanded.includes(data[keyProperty])
283
+ }
284
+ data={data}
285
+ hideableColumns={hideableColumns}
286
+ keyProperty={keyProperty}
287
+ measureElement={measureElement}
288
+ onRowClick={onRowClick}
289
+ state={state}
290
+ canExpand={canExpand}
291
+ toggleExpand={toggleExpand}
292
+ expandRow={children}
293
+ toggleChecked={toggleChecked}
294
+ wrapperEnd={wrapperEnd}
295
+ wrapperStart={wrapperStart}
296
+ key={key}
297
+ />
201
298
  );
202
299
  })}
203
300
  <div className="flex-1 flex flex-nowrap">
204
301
  <div className={wrapperStart}>
302
+ {canExpand && <div className="w-6" />}
205
303
  {checkableRows && <div className="w-6" />}
206
304
  {state.start?.map((col) => (
207
305
  <EmptyCell key={String(col.id)} {...col} />
@@ -220,13 +318,15 @@ export const Table = <T extends KeyValue = KeyValue>({
220
318
  </div>
221
319
  </div>
222
320
  )}
223
- {!loading && data.length === 0 && (
224
- <EmptyContent
225
- size="sm"
226
- className="bg-dimmed"
227
- message={t("datagrid.empty")}
228
- />
229
- )}
321
+ {!loading &&
322
+ data.length === 0 &&
323
+ (emptyDisplay ?? (
324
+ <EmptyContent
325
+ size="sm"
326
+ className="bg-dimmed"
327
+ message={t("datagrid.empty")}
328
+ />
329
+ ))}
230
330
  </div>
231
331
  </TableProvider>
232
332
  );
@@ -23,6 +23,7 @@
23
23
 
24
24
  import {
25
25
  type CssProp,
26
+ type Elements,
26
27
  type IconProps,
27
28
  type RefProp,
28
29
  type TestProps,
@@ -33,21 +34,52 @@ export const COL_MIN_WIDTH = "3rem";
33
34
  export const COL_MAX_WIDTH = "64rem";
34
35
  export const COL_DEFAULT_WIDTH = "12rem";
35
36
 
36
- export interface ColumnType<T = KeyValue>
37
+ /**
38
+ * TableColumn interface defines the structure of a column in a table.
39
+ * It includes properties for column identification, display options, alignment,
40
+ * visibility, resizing, sorting, filtering, and rendering.
41
+ *
42
+ * @template T - The type of data the column will represent, defaulting to KeyValue.
43
+ * @property {keyof T | string} id - Unique identifier for the column.
44
+ * @property {"string" | "number" | "boolean" | "datetime" | "date" | "time" | "unknown"} [dataType] - Data type of the column values.
45
+ * @property {string} [label] - Display label for the column header.
46
+ * @property {string} [tooltip] - Tooltip text for the column header.
47
+ * @property {string} [format] - Format string for displaying the column values.
48
+ * @property {"start" | "center" | "end"} [align] - Text alignment within the column.
49
+ * @property {"start" | "end"} [locked] - Indicates if the column is locked at the start or end.
50
+ * @property {boolean} [hidden] - Whether the column is hidden.
51
+ * @property {boolean} [truncate] - Whether to truncate the text in the column.
52
+ * @property {boolean} [hideable] - Whether the column can be hidden by the user.
53
+ * @property {boolean} [resizable] - Whether the column can be resized by the user.
54
+ * @property {boolean} [sortable] - Whether the column can be sorted.
55
+ * @property {boolean} [filterable] - Whether the column can be filtered.
56
+ * @property {AnyObject} [filter] - Filter criteria for the column.
57
+ * @property {ReactElement[]} [actions] - Array of action elements to be displayed in the column.
58
+ * @property {AnyObject[]} [filterOptions] - Options for filtering the column.
59
+ * @property {string | number} [width] - Width of the column.
60
+ * @property {string | number} [minWidth] - Minimum width of the column.
61
+ * @property {string | number} [maxWidth] - Maximum width of the column.
62
+ * @property {KeyValue} [valueMap] - Mapping of values for the column.
63
+ * @property {(value: AnyObject, data: T, index: number) => Elements<AnyObject>} [renderer] - Custom renderer function for the column values.
64
+ */
65
+ export interface TableColumn<T = KeyValue>
37
66
  extends CssProp,
38
67
  IconProps,
39
68
  TestProps {
40
69
  id: keyof T | string;
41
70
  label?: string;
42
- actions?: ReactElement;
71
+ tooltip?: string;
72
+ actions?: ReactElement[];
43
73
  align?: "start" | "center" | "end";
44
74
  locked?: "start" | "end";
45
75
  hidden?: boolean;
76
+ truncate?: boolean;
46
77
  hideable?: boolean;
47
78
  resizable?: boolean;
48
79
  sortable?: boolean;
49
80
  filterable?: boolean;
50
- filterList?: AnyObject[];
81
+ filter?: AnyObject;
82
+ filterOptions?: AnyObject[];
51
83
  width?: string | number;
52
84
  minWidth?: string | number;
53
85
  maxWidth?: string | number;
@@ -60,7 +92,8 @@ export interface ColumnType<T = KeyValue>
60
92
  | "time"
61
93
  | "unknown";
62
94
  format?: string;
63
- renderer?: (value: AnyObject, data: T) => void;
95
+ valueMap?: KeyValue;
96
+ renderer?: (value: AnyObject, data: T, index: number) => Elements<AnyObject>;
64
97
  }
65
98
 
66
99
  export interface TableRef {
@@ -70,14 +103,19 @@ export interface TableRef {
70
103
  }
71
104
 
72
105
  export interface TableProps<T = KeyValue> extends RefProp<TableRef> {
73
- columns: Array<ColumnType<T>>;
106
+ columns: Array<TableColumn<T>>;
74
107
  data: T[];
75
108
  keyProperty?: keyof T;
109
+ groupProperty?: keyof T;
110
+ groupRenderer?: (key: AnyObject) => ReactElement;
111
+ emptyDisplay?: ReactElement;
112
+
76
113
  /**
77
114
  * checkable rows
78
115
  */
116
+ checked?: AnyObject[];
79
117
  checkableRows?: boolean;
80
- onCheckedChanged?: (rows: Array<keyof T>) => void;
118
+ onCheckedChanged?: (rows: AnyObject[]) => void;
81
119
  /**
82
120
  * sorting
83
121
  */
@@ -88,4 +126,12 @@ export interface TableProps<T = KeyValue> extends RefProp<TableRef> {
88
126
  hideableColumns?: boolean;
89
127
 
90
128
  onRowClick?: (data: T) => void;
129
+
130
+ initialScroll?: number;
131
+ onScroll?: (firstItem: number) => void;
132
+
133
+ canExpand?: (record: T) => boolean;
134
+ children?: (record: T) => Elements<AnyObject>;
135
+
136
+ onFilter?: (id: keyof T | string, value?: AnyObject) => void;
91
137
  }
@@ -47,13 +47,15 @@ export const useResizer = (
47
47
  /** ***************** attach handlers *******************/
48
48
  const box = colEl.getBoundingClientRect();
49
49
  if (colEl.parentElement != null) {
50
- const parentBox = colEl.parentElement?.getBoundingClientRect();
50
+ const parentBox = colEl
51
+ .closest("[data-ref='tableScroller']")
52
+ ?.getBoundingClientRect() as unknown as DOMRect;
51
53
  if (isRtl) {
52
54
  placeholder.style.left = "unset";
53
- placeholder.style.right = `${box.right - parentBox.right}px`;
55
+ placeholder.style.right = `${parentBox.width - box.right}px`;
54
56
  } else {
55
57
  placeholder.style.right = "unset";
56
- placeholder.style.left = `${box.left - parentBox.left}px`;
58
+ placeholder.style.left = `${box.left}px`;
57
59
  }
58
60
  }
59
61
  placeholder.style.width = `${colEl.offsetWidth}px`;
@@ -23,20 +23,20 @@
23
23
 
24
24
  import { groupBy } from "@react-fabric/utilities";
25
25
  import { useEffect, useReducer } from "react";
26
- import { type ColumnType } from "./types";
26
+ import { type TableColumn } from "./types";
27
27
 
28
28
  interface ColumnState {
29
- columns: ColumnType[];
30
- start: ColumnType[];
31
- end: ColumnType[];
32
- cols: ColumnType[];
29
+ columns: TableColumn[];
30
+ start: TableColumn[];
31
+ end: TableColumn[];
32
+ cols: TableColumn[];
33
33
  }
34
34
 
35
35
  type ColumnActions =
36
- | { type: "columns"; columns: ColumnType[] }
36
+ | { type: "columns"; columns: TableColumn[] }
37
37
  | { type: "hide"; id: string };
38
38
 
39
- export const useTableColumns = (columns: ColumnType[]) => {
39
+ export const useTableColumns = (columns: TableColumn[]) => {
40
40
  const [state, dispatch] = useReducer(
41
41
  (state: ColumnState, action: ColumnActions) => {
42
42
  if (action.type === "columns") {