@react-fabric/data 1.0.0-beta.6 → 1.0.0-beta.61
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.
- package/{src/histogram/Histogram.module.css → css/_histogram.css} +16 -13
- package/{dist/esm/tree/types.js → css/styles.css} +2 -7
- package/dist/cjs/checklist/CheckList.js +27 -4
- package/dist/cjs/histogram/Histogram.js +39 -9
- package/dist/cjs/hooks/useFilteredList.js +88 -10
- package/dist/cjs/hooks/usePagination.js +27 -4
- package/dist/cjs/hooks/useSelectableList.js +29 -0
- package/dist/cjs/i18n/ar.json.js +8 -1
- package/dist/cjs/i18n/en.json.js +8 -1
- package/dist/cjs/json/JsonViewer.js +68 -28
- package/dist/cjs/pagination/Pagination.js +14 -4
- package/dist/cjs/table/AddColumn.js +3 -3
- package/dist/cjs/table/BodyCell.js +14 -6
- package/dist/cjs/table/BodyRow.js +4 -4
- package/dist/cjs/table/CheckboxCell.js +2 -2
- package/dist/cjs/table/ColumnFilters.js +97 -0
- package/dist/cjs/table/HeaderCell.js +71 -43
- package/dist/cjs/table/Table.js +62 -13
- package/dist/cjs/table/types.js +29 -0
- package/dist/cjs/table/useResizer.js +4 -4
- package/dist/cjs/table/useVirtualTable.js +127 -19
- package/dist/cjs/tree/TreeNode.js +50 -32
- package/dist/cjs/tree/TreePanel.js +52 -19
- package/dist/cjs/tree/useTree.js +199 -38
- package/dist/cjs/tree/utils.js +39 -12
- package/dist/cjs/virtual/Gallery.js +97 -45
- package/dist/cjs/virtual/List.js +93 -39
- package/dist/cjs/virtual/Scroller.js +16 -8
- package/dist/esm/checklist/CheckList.js +28 -5
- package/dist/esm/histogram/Histogram.js +41 -11
- package/dist/esm/hooks/useFilteredList.js +89 -11
- package/dist/esm/hooks/usePagination.js +27 -4
- package/dist/esm/hooks/useSelectableList.js +29 -0
- package/dist/esm/i18n/ar.json.js +8 -2
- package/dist/esm/i18n/en.json.js +8 -2
- package/dist/esm/json/JsonViewer.js +69 -29
- package/dist/esm/pagination/Pagination.js +15 -5
- package/dist/esm/table/AddColumn.js +4 -4
- package/dist/esm/table/BodyCell.js +15 -7
- package/dist/esm/table/BodyRow.js +4 -4
- package/dist/esm/table/CheckboxCell.js +3 -3
- package/dist/esm/table/ColumnFilters.js +97 -0
- package/dist/esm/table/HeaderCell.js +72 -44
- package/dist/esm/table/Table.js +63 -14
- package/dist/esm/table/types.js +29 -0
- package/dist/esm/table/useResizer.js +4 -4
- package/dist/esm/table/useVirtualTable.js +129 -21
- package/dist/esm/tree/TreeNode.js +53 -35
- package/dist/esm/tree/TreePanel.js +54 -21
- package/dist/esm/tree/useTree.js +202 -41
- package/dist/esm/tree/utils.js +40 -13
- package/dist/esm/virtual/Gallery.js +97 -45
- package/dist/esm/virtual/List.js +93 -39
- package/dist/esm/virtual/Scroller.js +17 -9
- package/dist/types/checklist/CheckList.d.ts +22 -0
- package/dist/types/histogram/Histogram.d.ts +28 -1
- package/dist/types/hooks/useFilteredList.d.ts +66 -5
- package/dist/types/hooks/usePagination.d.ts +19 -0
- package/dist/types/hooks/useSelectableList.d.ts +29 -0
- package/dist/types/json/JsonViewer.d.ts +27 -2
- package/dist/types/pagination/Pagination.d.ts +10 -1
- package/dist/types/table/ColumnFilters.d.ts +9 -0
- package/dist/types/table/HeaderCell.d.ts +1 -1
- package/dist/types/table/Table.d.ts +14 -1
- package/dist/types/table/types.d.ts +46 -7
- package/dist/types/table/useVirtualTable.d.ts +23 -9
- package/dist/types/tree/TreeNode.d.ts +1 -1
- package/dist/types/tree/TreePanel.d.ts +42 -1
- package/dist/types/tree/types.d.ts +65 -21
- package/dist/types/tree/useTree.d.ts +9 -10
- package/dist/types/tree/utils.d.ts +10 -3
- package/dist/types/virtual/Gallery.d.ts +42 -3
- package/dist/types/virtual/List.d.ts +42 -3
- package/package.json +16 -14
- package/src/checklist/CheckList.tsx +39 -7
- package/src/histogram/Histogram.tsx +43 -19
- package/src/hooks/useFilteredList.tsx +109 -9
- package/src/hooks/usePagination.tsx +32 -7
- package/src/hooks/useSelectableList.ts +29 -0
- package/src/i18n/ar.json +5 -0
- package/src/i18n/en.json +5 -0
- package/src/json/JsonViewer.tsx +76 -37
- package/src/pagination/Pagination.tsx +15 -5
- package/src/table/AddColumn.tsx +4 -4
- package/src/table/BodyCell.tsx +24 -7
- package/src/table/BodyRow.tsx +7 -4
- package/src/table/CheckboxCell.tsx +5 -5
- package/src/table/ColumnFilters.tsx +105 -0
- package/src/table/HeaderCell.tsx +74 -21
- package/src/table/Table.tsx +107 -12
- package/src/table/types.ts +49 -10
- package/src/table/useResizer.ts +5 -3
- package/src/table/useVirtualTable.ts +158 -27
- package/src/tree/TreeNode.tsx +96 -62
- package/src/tree/TreePanel.tsx +88 -22
- package/src/tree/types.ts +73 -23
- package/src/tree/useTree.ts +220 -44
- package/src/tree/utils.ts +58 -20
- package/src/virtual/Gallery.tsx +118 -54
- package/src/virtual/List.tsx +99 -39
- package/src/virtual/Scroller.tsx +25 -9
- package/dist/cjs/histogram/Histogram.module.css +0 -1
- package/dist/cjs/tree/types.js +0 -30
- package/dist/esm/histogram/Histogram.module.css +0 -1
package/src/table/HeaderCell.tsx
CHANGED
|
@@ -22,14 +22,18 @@
|
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
24
|
import {
|
|
25
|
-
|
|
25
|
+
Button,
|
|
26
|
+
Divider,
|
|
26
27
|
DropdownTool,
|
|
28
|
+
getIconProps,
|
|
27
29
|
Icon,
|
|
28
30
|
Menu,
|
|
29
31
|
MenuItem,
|
|
30
32
|
Tooltip,
|
|
31
33
|
} from "@react-fabric/core";
|
|
34
|
+
import { isEmpty } from "@react-fabric/utilities";
|
|
32
35
|
import { useCallback, useMemo } from "react";
|
|
36
|
+
import { ColumnFilters } from "./ColumnFilters";
|
|
33
37
|
import { useTableContext } from "./Context";
|
|
34
38
|
import {
|
|
35
39
|
COL_DEFAULT_WIDTH,
|
|
@@ -41,13 +45,15 @@ import {
|
|
|
41
45
|
|
|
42
46
|
export const HeaderCell = ({
|
|
43
47
|
id,
|
|
48
|
+
field,
|
|
49
|
+
dataType,
|
|
44
50
|
label,
|
|
45
51
|
icon,
|
|
46
|
-
iconBg,
|
|
47
|
-
iconColor,
|
|
48
|
-
rtlFlip,
|
|
49
52
|
actions,
|
|
50
53
|
locked,
|
|
54
|
+
filter,
|
|
55
|
+
filterable,
|
|
56
|
+
filterOptions,
|
|
51
57
|
tooltip,
|
|
52
58
|
sortable,
|
|
53
59
|
resizable,
|
|
@@ -56,7 +62,8 @@ export const HeaderCell = ({
|
|
|
56
62
|
minWidth,
|
|
57
63
|
sort,
|
|
58
64
|
onSort,
|
|
59
|
-
|
|
65
|
+
onFilter,
|
|
66
|
+
}: TableColumn & Pick<TableProps, "sort" | "onSort" | "onFilter">) => {
|
|
60
67
|
const { startResize, widths } = useTableContext();
|
|
61
68
|
|
|
62
69
|
const width = useMemo(
|
|
@@ -64,39 +71,77 @@ export const HeaderCell = ({
|
|
|
64
71
|
[widths, _width, id],
|
|
65
72
|
);
|
|
66
73
|
|
|
67
|
-
const handleSort = useCallback(
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
+
const handleSort = useCallback(
|
|
75
|
+
(order?: "asc" | "desc") => {
|
|
76
|
+
sortable &&
|
|
77
|
+
onSort?.({
|
|
78
|
+
id: id.toString(),
|
|
79
|
+
order:
|
|
80
|
+
order ?? (sort?.id === id && sort.order === "asc" ? "desc" : "asc"),
|
|
81
|
+
});
|
|
82
|
+
},
|
|
83
|
+
[onSort, sort, sortable],
|
|
84
|
+
);
|
|
74
85
|
|
|
75
86
|
const menus = useMemo(() => {
|
|
76
|
-
|
|
87
|
+
let ret = [];
|
|
88
|
+
if (filterable && (dataType ?? filterOptions)) {
|
|
89
|
+
ret.push(
|
|
90
|
+
<Menu
|
|
91
|
+
key="filters"
|
|
92
|
+
label="Filter"
|
|
93
|
+
icon={filter ? "icon-[mdi--check]" : ""}
|
|
94
|
+
trigger="click"
|
|
95
|
+
>
|
|
96
|
+
<ColumnFilters
|
|
97
|
+
type={dataType}
|
|
98
|
+
list={filterOptions}
|
|
99
|
+
filter={filter}
|
|
100
|
+
onFilter={(value) => onFilter?.(field ?? id, value)}
|
|
101
|
+
/>
|
|
102
|
+
</Menu>,
|
|
103
|
+
);
|
|
104
|
+
}
|
|
77
105
|
if (sortable) {
|
|
78
106
|
ret.push(
|
|
79
107
|
<MenuItem
|
|
80
108
|
key="sort-asc"
|
|
81
109
|
label="Sort ascending"
|
|
82
|
-
icon=
|
|
110
|
+
icon="icon-[mdi--sort-ascending]"
|
|
111
|
+
onClick={() => handleSort("asc")}
|
|
83
112
|
/>,
|
|
84
113
|
<MenuItem
|
|
85
114
|
key="sort-desc"
|
|
86
115
|
label="Sort descending"
|
|
87
|
-
icon=
|
|
116
|
+
icon="icon-[mdi--sort-descending]"
|
|
117
|
+
onClick={() => handleSort("desc")}
|
|
88
118
|
/>,
|
|
89
119
|
);
|
|
90
120
|
}
|
|
121
|
+
if (actions) {
|
|
122
|
+
ret.push(<Divider key="div" />);
|
|
123
|
+
ret.push(...actions);
|
|
124
|
+
}
|
|
125
|
+
if (ret.length === 1) {
|
|
126
|
+
ret = [
|
|
127
|
+
<ColumnFilters
|
|
128
|
+
key="filters"
|
|
129
|
+
type={dataType}
|
|
130
|
+
list={filterOptions}
|
|
131
|
+
filter={filter}
|
|
132
|
+
onFilter={(value) => onFilter?.(field ?? id, value)}
|
|
133
|
+
/>,
|
|
134
|
+
];
|
|
135
|
+
}
|
|
91
136
|
return ret;
|
|
92
|
-
}, [sortable]);
|
|
137
|
+
}, [sortable, actions, onFilter, handleSort]);
|
|
93
138
|
|
|
94
139
|
return (
|
|
95
140
|
<div
|
|
96
141
|
role="none"
|
|
97
142
|
data-id={id}
|
|
98
|
-
onClick={handleSort}
|
|
99
|
-
className="group font-medium border-e flex flex-nowrap text-start items-center table-header-cell"
|
|
143
|
+
onClick={() => handleSort()}
|
|
144
|
+
className="group/tool font-medium border-e flex flex-nowrap text-start items-center table-header-cell"
|
|
100
145
|
style={{
|
|
101
146
|
width: width ?? COL_DEFAULT_WIDTH,
|
|
102
147
|
minWidth: minWidth ?? COL_MIN_WIDTH,
|
|
@@ -105,9 +150,7 @@ export const HeaderCell = ({
|
|
|
105
150
|
>
|
|
106
151
|
<Tooltip content={tooltip ?? label} disabled={!(tooltip ?? label)}>
|
|
107
152
|
<div className="flex-initial px-2 py-1 text-sm truncate sticky start-0">
|
|
108
|
-
{icon && (
|
|
109
|
-
<Icon icon={icon} bg={iconBg} color={iconColor} rtlFlip={rtlFlip} />
|
|
110
|
-
)}
|
|
153
|
+
{icon && <Icon {...getIconProps(icon)} />}
|
|
111
154
|
<span>{label ?? " "}</span>
|
|
112
155
|
</div>
|
|
113
156
|
</Tooltip>
|
|
@@ -123,6 +166,16 @@ export const HeaderCell = ({
|
|
|
123
166
|
<Menu className="text-sm">{menus}</Menu>
|
|
124
167
|
</DropdownTool>
|
|
125
168
|
)}
|
|
169
|
+
{filterable && !isEmpty(filter) && (
|
|
170
|
+
<Button
|
|
171
|
+
size="sm"
|
|
172
|
+
variant="link"
|
|
173
|
+
aria-label="clear filter"
|
|
174
|
+
stopPropagation
|
|
175
|
+
icon="icon-[mdi--filter-remove]"
|
|
176
|
+
onClick={() => onFilter?.(id)}
|
|
177
|
+
/>
|
|
178
|
+
)}
|
|
126
179
|
{resizable && (
|
|
127
180
|
<div
|
|
128
181
|
role="none"
|
package/src/table/Table.tsx
CHANGED
|
@@ -21,8 +21,14 @@
|
|
|
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 {
|
|
24
|
+
import {
|
|
25
|
+
EmptyContent,
|
|
26
|
+
Icon,
|
|
27
|
+
LoadingLine,
|
|
28
|
+
useDebounce,
|
|
29
|
+
} from "@react-fabric/core";
|
|
25
30
|
import { debounce } from "@react-fabric/utilities";
|
|
31
|
+
import classNames from "classnames";
|
|
26
32
|
import {
|
|
27
33
|
useEffect,
|
|
28
34
|
useImperativeHandle,
|
|
@@ -41,23 +47,42 @@ import { type TableProps } from "./types";
|
|
|
41
47
|
import { useTableColumns } from "./useTableColumns";
|
|
42
48
|
import { useVirtualTable } from "./useVirtualTable";
|
|
43
49
|
|
|
50
|
+
/**
|
|
51
|
+
* Table component for displaying data in a tabular format with features like sorting, filtering, and virtual scrolling.
|
|
52
|
+
* It supports expandable rows, checkable rows, and customizable columns.
|
|
53
|
+
* The component is designed to handle large datasets efficiently by rendering only the visible rows.
|
|
54
|
+
* It also provides a way to manage column visibility and allows for custom rendering of group headers.
|
|
55
|
+
* Uses TanStack's `useVirtual` for virtualization and React's `useMemo` for performance optimization.
|
|
56
|
+
*
|
|
57
|
+
* @param {TableProps<T>} props - The properties for the Table component.
|
|
58
|
+
* @returns {JSX.Element} The rendered Table component.
|
|
59
|
+
*
|
|
60
|
+
* @see {@link https://adarshpastakia.github.io/react-fabric/?path=/story/data-table--table}
|
|
61
|
+
* @see {@link https://tanstack.com/table/v8/docs/api/virtual}
|
|
62
|
+
*/
|
|
44
63
|
export const Table = <T extends KeyValue = KeyValue>({
|
|
45
64
|
ref,
|
|
46
65
|
data,
|
|
47
66
|
columns,
|
|
48
|
-
keyProperty,
|
|
67
|
+
keyProperty = "id" as any,
|
|
68
|
+
groupProperty,
|
|
49
69
|
checkableRows,
|
|
50
70
|
initialScroll,
|
|
51
71
|
hideableColumns,
|
|
52
72
|
sort,
|
|
53
73
|
loading,
|
|
74
|
+
checked,
|
|
54
75
|
emptyDisplay,
|
|
76
|
+
groupRenderer,
|
|
55
77
|
canExpand,
|
|
56
78
|
children,
|
|
57
79
|
onSort,
|
|
80
|
+
onFilter,
|
|
58
81
|
onScroll,
|
|
59
82
|
onRowClick,
|
|
60
83
|
onCheckedChanged,
|
|
84
|
+
total = 0,
|
|
85
|
+
onLoadMore,
|
|
61
86
|
}: TableProps<T>) => {
|
|
62
87
|
const { t } = useTranslation("data");
|
|
63
88
|
const fireCheckChanged = useDebounce(
|
|
@@ -72,13 +97,24 @@ export const Table = <T extends KeyValue = KeyValue>({
|
|
|
72
97
|
top,
|
|
73
98
|
checkState,
|
|
74
99
|
virtualizer,
|
|
100
|
+
hasActiveSticky,
|
|
75
101
|
toggleExpand,
|
|
76
102
|
toggleChecked,
|
|
77
103
|
toggleAllChecked,
|
|
104
|
+
toggleGroupExpand,
|
|
78
105
|
getData,
|
|
79
106
|
totalSize,
|
|
107
|
+
isActiveSticky,
|
|
80
108
|
measureElement,
|
|
81
|
-
} = useVirtualTable(data,
|
|
109
|
+
} = useVirtualTable(data, {
|
|
110
|
+
checked,
|
|
111
|
+
keyProperty,
|
|
112
|
+
groupProperty,
|
|
113
|
+
total,
|
|
114
|
+
loading,
|
|
115
|
+
onLoadMore,
|
|
116
|
+
onCheckChanged: fireCheckChanged,
|
|
117
|
+
});
|
|
82
118
|
const refBody = useRef<HTMLDivElement>(null);
|
|
83
119
|
|
|
84
120
|
const wrapperStart = useMemo(
|
|
@@ -142,9 +178,13 @@ export const Table = <T extends KeyValue = KeyValue>({
|
|
|
142
178
|
style={{
|
|
143
179
|
gridTemplate: `"head" auto "loader" auto "content" 1fr "foot" auto/1fr`,
|
|
144
180
|
}}
|
|
181
|
+
data-ref="tableScroller"
|
|
145
182
|
ref={scrollerRef}
|
|
146
183
|
>
|
|
147
|
-
<div
|
|
184
|
+
<div
|
|
185
|
+
data-ref="tableHeader"
|
|
186
|
+
className="bg-base font-medium sticky top-0 h-8 area-head border-b select-none flex flex-nowrap z-3"
|
|
187
|
+
>
|
|
148
188
|
<div className={wrapperStart}>
|
|
149
189
|
{canExpand && <div className="w-6" />}
|
|
150
190
|
{checkableRows && (
|
|
@@ -154,15 +194,33 @@ export const Table = <T extends KeyValue = KeyValue>({
|
|
|
154
194
|
/>
|
|
155
195
|
)}
|
|
156
196
|
{state.start?.map((col, idx) => (
|
|
157
|
-
<HeaderCell
|
|
197
|
+
<HeaderCell
|
|
198
|
+
key={idx}
|
|
199
|
+
{...col}
|
|
200
|
+
sort={sort}
|
|
201
|
+
onSort={onSort}
|
|
202
|
+
onFilter={onFilter}
|
|
203
|
+
/>
|
|
158
204
|
))}
|
|
159
205
|
</div>
|
|
160
206
|
{state.cols?.map((col, idx) => (
|
|
161
|
-
<HeaderCell
|
|
207
|
+
<HeaderCell
|
|
208
|
+
key={idx}
|
|
209
|
+
{...col}
|
|
210
|
+
sort={sort}
|
|
211
|
+
onSort={onSort}
|
|
212
|
+
onFilter={onFilter}
|
|
213
|
+
/>
|
|
162
214
|
))}
|
|
163
215
|
<div className={wrapperEnd}>
|
|
164
216
|
{state.end?.map((col, idx) => (
|
|
165
|
-
<HeaderCell
|
|
217
|
+
<HeaderCell
|
|
218
|
+
key={idx}
|
|
219
|
+
{...col}
|
|
220
|
+
sort={sort}
|
|
221
|
+
onSort={onSort}
|
|
222
|
+
onFilter={onFilter}
|
|
223
|
+
/>
|
|
166
224
|
))}
|
|
167
225
|
|
|
168
226
|
{hideableColumns && (
|
|
@@ -173,19 +231,56 @@ export const Table = <T extends KeyValue = KeyValue>({
|
|
|
173
231
|
)}
|
|
174
232
|
</div>
|
|
175
233
|
</div>
|
|
176
|
-
{loading && <
|
|
234
|
+
{loading && <LoadingLine />}
|
|
177
235
|
{data.length > 0 && (
|
|
178
236
|
<div
|
|
179
|
-
className="area-content flex flex-col flex-nowrap"
|
|
237
|
+
className="area-content flex flex-col flex-nowrap min-h-full"
|
|
180
238
|
style={{ height: totalSize() }}
|
|
181
239
|
ref={refBody}
|
|
182
240
|
>
|
|
183
|
-
<div
|
|
241
|
+
<div
|
|
242
|
+
style={{
|
|
243
|
+
height: items[hasActiveSticky ? 1 : 0]?.start,
|
|
244
|
+
}}
|
|
245
|
+
/>
|
|
184
246
|
{items.map(({ index, key }) => {
|
|
185
247
|
const data = getData(index);
|
|
186
|
-
return (
|
|
248
|
+
return "__GROUP__" in data ? (
|
|
249
|
+
<div
|
|
250
|
+
key={key}
|
|
251
|
+
ref={measureElement}
|
|
252
|
+
data-index={index}
|
|
253
|
+
className={classNames(
|
|
254
|
+
"text-md bg-base border-y border-tint-100 border-t-0 cursor-pointer flex items-center justify-start gap-1 z-2",
|
|
255
|
+
isActiveSticky(index) && "sticky top-8",
|
|
256
|
+
)}
|
|
257
|
+
role="none"
|
|
258
|
+
onClick={() => toggleGroupExpand(data.key)}
|
|
259
|
+
>
|
|
260
|
+
<div
|
|
261
|
+
className={classNames(
|
|
262
|
+
"px-2 py-1 flex items-center gap-1 z-2 sticky start-0",
|
|
263
|
+
)}
|
|
264
|
+
>
|
|
265
|
+
<Icon
|
|
266
|
+
rtlFlip
|
|
267
|
+
icon={
|
|
268
|
+
data.open
|
|
269
|
+
? "icon-[mdi--chevron-down]"
|
|
270
|
+
: "icon-[mdi--chevron-right]"
|
|
271
|
+
}
|
|
272
|
+
/>
|
|
273
|
+
{groupRenderer?.(data) ?? (
|
|
274
|
+
<div className="flex gap-1 items-center">
|
|
275
|
+
<span>{data.key}</span>
|
|
276
|
+
<span className="text-sm">({data.itemCount})</span>
|
|
277
|
+
</div>
|
|
278
|
+
)}
|
|
279
|
+
</div>
|
|
280
|
+
</div>
|
|
281
|
+
) : (
|
|
187
282
|
<BodyRow
|
|
188
|
-
rowKey={key}
|
|
283
|
+
rowKey={key.toString()}
|
|
189
284
|
index={index}
|
|
190
285
|
checkableRows={checkableRows}
|
|
191
286
|
checked={
|
package/src/table/types.ts
CHANGED
|
@@ -21,10 +21,11 @@
|
|
|
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 { type IconProps } from "@react-fabric/core/dist/types/components/icon/Icon";
|
|
24
25
|
import {
|
|
25
26
|
type CssProp,
|
|
26
27
|
type Elements,
|
|
27
|
-
type
|
|
28
|
+
type NestedKeys,
|
|
28
29
|
type RefProp,
|
|
29
30
|
type TestProps,
|
|
30
31
|
} from "@react-fabric/core/dist/types/types";
|
|
@@ -34,22 +35,51 @@ export const COL_MIN_WIDTH = "3rem";
|
|
|
34
35
|
export const COL_MAX_WIDTH = "64rem";
|
|
35
36
|
export const COL_DEFAULT_WIDTH = "12rem";
|
|
36
37
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
/**
|
|
39
|
+
* TableColumn interface defines the structure of a column in a table.
|
|
40
|
+
* It includes properties for column identification, display options, alignment,
|
|
41
|
+
* visibility, resizing, sorting, filtering, and rendering.
|
|
42
|
+
*
|
|
43
|
+
* @template T - The type of data the column will represent, defaulting to KeyValue.
|
|
44
|
+
* @property {keyof T | string} id - Unique identifier for the column.
|
|
45
|
+
* @property {"string" | "number" | "boolean" | "datetime" | "date" | "time" | "unknown"} [dataType] - Data type of the column values.
|
|
46
|
+
* @property {string} [label] - Display label for the column header.
|
|
47
|
+
* @property {string} [tooltip] - Tooltip text for the column header.
|
|
48
|
+
* @property {string} [format] - Format string for displaying the column values.
|
|
49
|
+
* @property {"start" | "center" | "end"} [align] - Text alignment within the column.
|
|
50
|
+
* @property {"start" | "end"} [locked] - Indicates if the column is locked at the start or end.
|
|
51
|
+
* @property {boolean} [hidden] - Whether the column is hidden.
|
|
52
|
+
* @property {boolean} [truncate] - Whether to truncate the text in the column.
|
|
53
|
+
* @property {boolean} [hideable] - Whether the column can be hidden by the user.
|
|
54
|
+
* @property {boolean} [resizable] - Whether the column can be resized by the user.
|
|
55
|
+
* @property {boolean} [sortable] - Whether the column can be sorted.
|
|
56
|
+
* @property {boolean} [filterable] - Whether the column can be filtered.
|
|
57
|
+
* @property {AnyObject} [filter] - Filter criteria for the column.
|
|
58
|
+
* @property {ReactElement[]} [actions] - Array of action elements to be displayed in the column.
|
|
59
|
+
* @property {AnyObject[]} [filterOptions] - Options for filtering the column.
|
|
60
|
+
* @property {string | number} [width] - Width of the column.
|
|
61
|
+
* @property {string | number} [minWidth] - Minimum width of the column.
|
|
62
|
+
* @property {string | number} [maxWidth] - Maximum width of the column.
|
|
63
|
+
* @property {KeyValue} [valueMap] - Mapping of values for the column.
|
|
64
|
+
* @property {(value: AnyObject, data: T, index: number) => Elements<AnyObject>} [renderer] - Custom renderer function for the column values.
|
|
65
|
+
*/
|
|
66
|
+
export interface TableColumn<T = KeyValue> extends CssProp, TestProps {
|
|
67
|
+
id: NestedKeys<T>;
|
|
68
|
+
field?: string;
|
|
42
69
|
label?: string;
|
|
43
70
|
tooltip?: string;
|
|
44
|
-
|
|
71
|
+
icon?: IconProps;
|
|
72
|
+
actions?: ReactElement[];
|
|
45
73
|
align?: "start" | "center" | "end";
|
|
46
74
|
locked?: "start" | "end";
|
|
47
75
|
hidden?: boolean;
|
|
76
|
+
truncate?: boolean;
|
|
48
77
|
hideable?: boolean;
|
|
49
78
|
resizable?: boolean;
|
|
50
79
|
sortable?: boolean;
|
|
51
80
|
filterable?: boolean;
|
|
52
|
-
|
|
81
|
+
filter?: AnyObject;
|
|
82
|
+
filterOptions?: AnyObject[];
|
|
53
83
|
width?: string | number;
|
|
54
84
|
minWidth?: string | number;
|
|
55
85
|
maxWidth?: string | number;
|
|
@@ -75,13 +105,17 @@ export interface TableRef {
|
|
|
75
105
|
export interface TableProps<T = KeyValue> extends RefProp<TableRef> {
|
|
76
106
|
columns: Array<TableColumn<T>>;
|
|
77
107
|
data: T[];
|
|
78
|
-
keyProperty?:
|
|
108
|
+
keyProperty?: NestedKeys<T>;
|
|
109
|
+
groupProperty?: NestedKeys<T>;
|
|
110
|
+
groupRenderer?: (key: AnyObject) => ReactElement;
|
|
79
111
|
emptyDisplay?: ReactElement;
|
|
112
|
+
|
|
80
113
|
/**
|
|
81
114
|
* checkable rows
|
|
82
115
|
*/
|
|
116
|
+
checked?: AnyObject[];
|
|
83
117
|
checkableRows?: boolean;
|
|
84
|
-
onCheckedChanged?: (rows:
|
|
118
|
+
onCheckedChanged?: (rows: AnyObject[]) => void;
|
|
85
119
|
/**
|
|
86
120
|
* sorting
|
|
87
121
|
*/
|
|
@@ -98,4 +132,9 @@ export interface TableProps<T = KeyValue> extends RefProp<TableRef> {
|
|
|
98
132
|
|
|
99
133
|
canExpand?: (record: T) => boolean;
|
|
100
134
|
children?: (record: T) => Elements<AnyObject>;
|
|
135
|
+
|
|
136
|
+
onFilter?: (id: NestedKeys<T> | string, value?: AnyObject) => void;
|
|
137
|
+
|
|
138
|
+
total?: number;
|
|
139
|
+
onLoadMore?: (lastIndex?: number) => void;
|
|
101
140
|
}
|
package/src/table/useResizer.ts
CHANGED
|
@@ -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
|
|
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 = `${
|
|
55
|
+
placeholder.style.right = `${parentBox.width - box.right}px`;
|
|
54
56
|
} else {
|
|
55
57
|
placeholder.style.right = "unset";
|
|
56
|
-
placeholder.style.left = `${box.left
|
|
58
|
+
placeholder.style.left = `${box.left}px`;
|
|
57
59
|
}
|
|
58
60
|
}
|
|
59
61
|
placeholder.style.width = `${colEl.offsetWidth}px`;
|