@itwin/itwinui-react 3.15.3 → 3.15.5
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/CHANGELOG.md +17 -0
- package/DEV-cjs/core/Breadcrumbs/Breadcrumbs.js +85 -65
- package/DEV-cjs/core/ButtonGroup/ButtonGroup.js +32 -27
- package/DEV-cjs/core/ComboBox/ComboBox.js +9 -6
- package/DEV-cjs/core/DatePicker/DatePicker.js +14 -4
- package/DEV-cjs/core/Popover/Popover.js +44 -16
- package/DEV-cjs/core/Select/SelectTagContainer.js +27 -13
- package/DEV-cjs/core/Table/ColumnHeader.js +21 -28
- package/DEV-cjs/core/Table/Table.js +78 -53
- package/DEV-cjs/core/Table/TablePaginator.js +111 -88
- package/DEV-cjs/core/Table/cells/DefaultCell.js +3 -3
- package/DEV-cjs/core/Table/utils.js +3 -3
- package/DEV-cjs/styles.js +1 -1
- package/DEV-cjs/utils/components/MiddleTextTruncation.js +19 -14
- package/DEV-cjs/utils/components/OverflowContainer.js +63 -0
- package/DEV-cjs/utils/components/index.js +1 -0
- package/DEV-cjs/utils/hooks/useOverflow.js +12 -8
- package/DEV-esm/core/Breadcrumbs/Breadcrumbs.js +86 -67
- package/DEV-esm/core/ButtonGroup/ButtonGroup.js +33 -28
- package/DEV-esm/core/ComboBox/ComboBox.js +9 -6
- package/DEV-esm/core/DatePicker/DatePicker.js +12 -4
- package/DEV-esm/core/Popover/Popover.js +45 -17
- package/DEV-esm/core/Select/SelectTagContainer.js +24 -13
- package/DEV-esm/core/Table/ColumnHeader.js +28 -29
- package/DEV-esm/core/Table/Table.js +79 -54
- package/DEV-esm/core/Table/TablePaginator.js +112 -89
- package/DEV-esm/core/Table/cells/DefaultCell.js +4 -4
- package/DEV-esm/core/Table/utils.js +1 -1
- package/DEV-esm/styles.js +1 -1
- package/DEV-esm/utils/components/MiddleTextTruncation.js +19 -14
- package/DEV-esm/utils/components/OverflowContainer.js +50 -0
- package/DEV-esm/utils/components/index.js +1 -0
- package/DEV-esm/utils/hooks/useOverflow.js +8 -8
- package/cjs/core/Breadcrumbs/Breadcrumbs.js +84 -64
- package/cjs/core/ButtonGroup/ButtonGroup.js +32 -27
- package/cjs/core/ComboBox/ComboBox.js +9 -6
- package/cjs/core/DatePicker/DatePicker.js +14 -4
- package/cjs/core/NonIdealState/NonIdealState.d.ts +15 -11
- package/cjs/core/Popover/Popover.d.ts +10 -0
- package/cjs/core/Popover/Popover.js +44 -16
- package/cjs/core/Select/SelectTagContainer.js +27 -13
- package/cjs/core/Table/ColumnHeader.d.ts +8 -12
- package/cjs/core/Table/ColumnHeader.js +21 -28
- package/cjs/core/Table/Table.js +74 -53
- package/cjs/core/Table/TablePaginator.js +111 -88
- package/cjs/core/Table/cells/DefaultCell.js +3 -3
- package/cjs/core/Table/utils.d.ts +2 -2
- package/cjs/core/Table/utils.js +3 -3
- package/cjs/styles.js +1 -1
- package/cjs/utils/components/MiddleTextTruncation.js +19 -14
- package/cjs/utils/components/OverflowContainer.d.ts +37 -0
- package/cjs/utils/components/OverflowContainer.js +62 -0
- package/cjs/utils/components/index.d.ts +1 -0
- package/cjs/utils/components/index.js +1 -0
- package/cjs/utils/hooks/useOverflow.d.ts +2 -3
- package/cjs/utils/hooks/useOverflow.js +12 -8
- package/esm/core/Breadcrumbs/Breadcrumbs.js +85 -66
- package/esm/core/ButtonGroup/ButtonGroup.js +33 -28
- package/esm/core/ComboBox/ComboBox.js +9 -6
- package/esm/core/DatePicker/DatePicker.js +12 -4
- package/esm/core/NonIdealState/NonIdealState.d.ts +15 -11
- package/esm/core/Popover/Popover.d.ts +10 -0
- package/esm/core/Popover/Popover.js +45 -17
- package/esm/core/Select/SelectTagContainer.js +24 -13
- package/esm/core/Table/ColumnHeader.d.ts +8 -12
- package/esm/core/Table/ColumnHeader.js +28 -29
- package/esm/core/Table/Table.js +75 -54
- package/esm/core/Table/TablePaginator.js +112 -89
- package/esm/core/Table/cells/DefaultCell.js +4 -4
- package/esm/core/Table/utils.d.ts +2 -2
- package/esm/core/Table/utils.js +1 -1
- package/esm/styles.js +1 -1
- package/esm/utils/components/MiddleTextTruncation.js +19 -14
- package/esm/utils/components/OverflowContainer.d.ts +37 -0
- package/esm/utils/components/OverflowContainer.js +49 -0
- package/esm/utils/components/index.d.ts +1 -0
- package/esm/utils/components/index.js +1 -0
- package/esm/utils/hooks/useOverflow.d.ts +2 -3
- package/esm/utils/hooks/useOverflow.js +8 -8
- package/package.json +1 -1
- package/styles.css +8 -8
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
useLatestRef,
|
|
25
25
|
useVirtualScroll,
|
|
26
26
|
} from '../../utils/index.js';
|
|
27
|
-
import {
|
|
27
|
+
import { TableInstanceContext } from './utils.js';
|
|
28
28
|
import { TableRowMemoized } from './TableRowMemoized.js';
|
|
29
29
|
import { customFilterFunctions } from './filters/customFilterFunctions.js';
|
|
30
30
|
import {
|
|
@@ -53,6 +53,7 @@ let singleRowSelectedAction = 'singleRowSelected';
|
|
|
53
53
|
let shiftRowSelectedAction = 'shiftRowSelected';
|
|
54
54
|
export const tableResizeStartAction = 'tableResizeStart';
|
|
55
55
|
let tableResizeEndAction = 'tableResizeEnd';
|
|
56
|
+
let iuiId = Symbol('iui-id');
|
|
56
57
|
let flattenColumns = (columns) => {
|
|
57
58
|
let flatColumns = [];
|
|
58
59
|
columns.forEach((column) => {
|
|
@@ -105,6 +106,7 @@ export const Table = (props) => {
|
|
|
105
106
|
headerProps,
|
|
106
107
|
bodyProps,
|
|
107
108
|
emptyTableContentProps,
|
|
109
|
+
getRowId,
|
|
108
110
|
...rest
|
|
109
111
|
} = props;
|
|
110
112
|
useGlobals();
|
|
@@ -240,16 +242,30 @@ export const Table = (props) => {
|
|
|
240
242
|
),
|
|
241
243
|
[data, getSubRows],
|
|
242
244
|
);
|
|
243
|
-
let [rowHasParent] = React.useState(() => new WeakSet());
|
|
244
245
|
let getSubRowsWithSubComponents = React.useCallback(
|
|
245
|
-
(originalRow) => {
|
|
246
|
-
if (
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
246
|
+
(originalRow, relativeIndex) => {
|
|
247
|
+
if (originalRow[iuiId]) return [];
|
|
248
|
+
if (originalRow.subRows) return originalRow.subRows;
|
|
249
|
+
return [
|
|
250
|
+
{
|
|
251
|
+
[iuiId]: `subcomponent-${relativeIndex}`,
|
|
252
|
+
...originalRow,
|
|
253
|
+
},
|
|
254
|
+
];
|
|
255
|
+
},
|
|
256
|
+
[],
|
|
257
|
+
);
|
|
258
|
+
let getRowIdWithSubComponents = React.useCallback(
|
|
259
|
+
(originalRow, relativeIndex, parent) => {
|
|
260
|
+
let defaultRowId = parent
|
|
261
|
+
? `${parent.id}.${relativeIndex}`
|
|
262
|
+
: `${relativeIndex}`;
|
|
263
|
+
let rowIdFromUser = getRowId?.(originalRow, relativeIndex, parent);
|
|
264
|
+
if (void 0 !== rowIdFromUser && originalRow[iuiId])
|
|
265
|
+
return `${rowIdFromUser}-${defaultRowId}`;
|
|
266
|
+
return rowIdFromUser ?? defaultRowId;
|
|
251
267
|
},
|
|
252
|
-
[
|
|
268
|
+
[getRowId],
|
|
253
269
|
);
|
|
254
270
|
let instance = useTable(
|
|
255
271
|
{
|
|
@@ -269,6 +285,7 @@ export const Table = (props) => {
|
|
|
269
285
|
...props.initialState,
|
|
270
286
|
},
|
|
271
287
|
columnResizeMode,
|
|
288
|
+
getRowId: subComponent ? getRowIdWithSubComponents : getRowId,
|
|
272
289
|
},
|
|
273
290
|
useFlexLayout,
|
|
274
291
|
useResizeColumns(ownerDocument),
|
|
@@ -299,7 +316,6 @@ export const Table = (props) => {
|
|
|
299
316
|
gotoPage,
|
|
300
317
|
setPageSize,
|
|
301
318
|
flatHeaders,
|
|
302
|
-
visibleColumns,
|
|
303
319
|
setGlobalFilter,
|
|
304
320
|
} = instance;
|
|
305
321
|
let headerGroups = _headerGroups;
|
|
@@ -310,6 +326,10 @@ export const Table = (props) => {
|
|
|
310
326
|
"Table's `columns` prop should not have a top-level `Header` or sub-columns. They are only allowed to be passed for backwards compatibility.\n See https://github.com/iTwin/iTwinUI/wiki/iTwinUI-react-v2-migration-guide#breaking-changes",
|
|
311
327
|
);
|
|
312
328
|
}
|
|
329
|
+
if (subComponent && data.some((item) => !!item.subRows?.length))
|
|
330
|
+
logWarning(
|
|
331
|
+
'Passing both `subComponent` and `data` with `subRows` is not supported. There are features designed for `subRows` that are not compatible with `subComponent` and vice versa.',
|
|
332
|
+
);
|
|
313
333
|
let ariaDataAttributes = Object.entries(rest).reduce(
|
|
314
334
|
(result, [key, value]) => {
|
|
315
335
|
if (key.startsWith('data-') || key.startsWith('aria-'))
|
|
@@ -466,51 +486,52 @@ export const Table = (props) => {
|
|
|
466
486
|
(index, virtualItem, virtualizer) => {
|
|
467
487
|
let row = page[index];
|
|
468
488
|
prepareRow(row);
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
489
|
+
let isRowASubComponent = !!row.original[iuiId] && !!subComponent;
|
|
490
|
+
if (isRowASubComponent)
|
|
491
|
+
return React.createElement(
|
|
492
|
+
TableExpandableContentMemoized,
|
|
493
|
+
{
|
|
494
|
+
key: row.getRowProps().key,
|
|
495
|
+
virtualItem: virtualItem,
|
|
496
|
+
ref: enableVirtualization
|
|
497
|
+
? virtualizer?.measureElement
|
|
498
|
+
: tableRowRef(row),
|
|
499
|
+
isDisabled: !!isRowDisabled?.(row.original),
|
|
500
|
+
},
|
|
501
|
+
subComponent(row),
|
|
502
|
+
);
|
|
503
|
+
return React.createElement(TableRowMemoized, {
|
|
504
|
+
row: row,
|
|
505
|
+
rowProps: rowProps,
|
|
506
|
+
isLast: index === page.length - 1,
|
|
507
|
+
onRowInViewport: onRowInViewportRef,
|
|
508
|
+
onBottomReached: onBottomReachedRef,
|
|
509
|
+
intersectionMargin: intersectionMargin,
|
|
510
|
+
state: state,
|
|
511
|
+
key: row.getRowProps().key,
|
|
512
|
+
onClick: onRowClickHandler,
|
|
513
|
+
subComponent: subComponent,
|
|
514
|
+
isDisabled: !!isRowDisabled?.(row.original),
|
|
515
|
+
tableHasSubRows: hasAnySubRows,
|
|
516
|
+
tableInstance: instance,
|
|
517
|
+
expanderCell: expanderCell,
|
|
518
|
+
scrollContainerRef: tableRef.current,
|
|
519
|
+
tableRowRef: enableVirtualization ? void 0 : tableRowRef(row),
|
|
520
|
+
density: density,
|
|
521
|
+
virtualItem: virtualItem,
|
|
522
|
+
virtualizer: virtualizer,
|
|
523
|
+
});
|
|
503
524
|
},
|
|
504
525
|
[
|
|
505
526
|
page,
|
|
506
527
|
prepareRow,
|
|
528
|
+
subComponent,
|
|
507
529
|
rowProps,
|
|
508
530
|
onRowInViewportRef,
|
|
509
531
|
onBottomReachedRef,
|
|
510
532
|
intersectionMargin,
|
|
511
533
|
state,
|
|
512
534
|
onRowClickHandler,
|
|
513
|
-
subComponent,
|
|
514
535
|
isRowDisabled,
|
|
515
536
|
hasAnySubRows,
|
|
516
537
|
instance,
|
|
@@ -547,9 +568,9 @@ export const Table = (props) => {
|
|
|
547
568
|
updateStickyState();
|
|
548
569
|
}, []);
|
|
549
570
|
return React.createElement(
|
|
550
|
-
|
|
571
|
+
TableInstanceContext.Provider,
|
|
551
572
|
{
|
|
552
|
-
value: instance
|
|
573
|
+
value: instance,
|
|
553
574
|
},
|
|
554
575
|
React.createElement(
|
|
555
576
|
Box,
|
|
@@ -608,19 +629,23 @@ export const Table = (props) => {
|
|
|
608
629
|
return React.createElement(ColumnHeader, {
|
|
609
630
|
...dragAndDropProps,
|
|
610
631
|
key: dragAndDropProps.key || column.id || index,
|
|
611
|
-
columnRefs: columnRefs,
|
|
612
632
|
column: column,
|
|
613
|
-
index: index,
|
|
614
633
|
areFiltersSet: areFiltersSet,
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
634
|
+
columnHasExpanders:
|
|
635
|
+
hasAnySubRows &&
|
|
636
|
+
index ===
|
|
637
|
+
headerGroup.headers.findIndex(
|
|
638
|
+
(c) => c.id !== SELECTION_CELL_ID,
|
|
639
|
+
),
|
|
640
|
+
isLast: index === headerGroup.headers.length - 1,
|
|
641
|
+
isTableEmpty: 0 === data.length,
|
|
619
642
|
isResizable: isResizable,
|
|
620
643
|
columnResizeMode: columnResizeMode,
|
|
621
644
|
enableColumnReordering: enableColumnReordering,
|
|
622
645
|
density: density,
|
|
623
|
-
|
|
646
|
+
ref: (el) => {
|
|
647
|
+
if (el) columnRefs.current[column.id] = el;
|
|
648
|
+
},
|
|
624
649
|
});
|
|
625
650
|
}),
|
|
626
651
|
),
|
|
@@ -8,12 +8,13 @@ import { MenuItem } from '../Menu/MenuItem.js';
|
|
|
8
8
|
import {
|
|
9
9
|
getBoundedValue,
|
|
10
10
|
useGlobals,
|
|
11
|
-
useOverflow,
|
|
12
11
|
useContainerWidth,
|
|
13
12
|
SvgChevronLeft,
|
|
14
13
|
SvgChevronRight,
|
|
15
14
|
Box,
|
|
15
|
+
OverflowContainer,
|
|
16
16
|
} from '../../utils/index.js';
|
|
17
|
+
import { styles } from '../../styles.js';
|
|
17
18
|
let defaultLocalization = {
|
|
18
19
|
pageSizeLabel: (size) => `${size} per page`,
|
|
19
20
|
rangeLabel: (startIndex, endIndex, totalRows, isLoading) =>
|
|
@@ -55,7 +56,7 @@ export const TablePaginator = (props) => {
|
|
|
55
56
|
);
|
|
56
57
|
let pageListRef = React.useRef(null);
|
|
57
58
|
let [focusedIndex, setFocusedIndex] = React.useState(currentPage);
|
|
58
|
-
React.
|
|
59
|
+
React.useLayoutEffect(() => {
|
|
59
60
|
setFocusedIndex(currentPage);
|
|
60
61
|
}, [currentPage]);
|
|
61
62
|
let needFocus = React.useRef(false);
|
|
@@ -64,7 +65,7 @@ export const TablePaginator = (props) => {
|
|
|
64
65
|
if (isMounted.current && needFocus.current) {
|
|
65
66
|
let buttonToFocus = Array.from(
|
|
66
67
|
pageListRef.current?.querySelectorAll(
|
|
67
|
-
'
|
|
68
|
+
`.${styles['iui-table-paginator-page-button']}`,
|
|
68
69
|
) ?? [],
|
|
69
70
|
).find((el) => el.textContent?.trim() === (focusedIndex + 1).toString());
|
|
70
71
|
buttonToFocus?.focus();
|
|
@@ -73,35 +74,7 @@ export const TablePaginator = (props) => {
|
|
|
73
74
|
isMounted.current = true;
|
|
74
75
|
}, [focusedIndex]);
|
|
75
76
|
let buttonSize = 'default' != size ? 'small' : void 0;
|
|
76
|
-
let pageButton = React.useCallback(
|
|
77
|
-
(index, tabIndex = index === focusedIndex ? 0 : -1) =>
|
|
78
|
-
React.createElement(
|
|
79
|
-
Button,
|
|
80
|
-
{
|
|
81
|
-
key: index,
|
|
82
|
-
className: 'iui-table-paginator-page-button',
|
|
83
|
-
styleType: 'borderless',
|
|
84
|
-
size: buttonSize,
|
|
85
|
-
'data-iui-active': index === currentPage,
|
|
86
|
-
onClick: () => onPageChange(index),
|
|
87
|
-
'aria-current': index === currentPage,
|
|
88
|
-
'aria-label': localization.goToPageLabel(index + 1),
|
|
89
|
-
tabIndex: tabIndex,
|
|
90
|
-
},
|
|
91
|
-
index + 1,
|
|
92
|
-
),
|
|
93
|
-
[focusedIndex, currentPage, localization, buttonSize, onPageChange],
|
|
94
|
-
);
|
|
95
77
|
let totalPagesCount = Math.ceil(totalRowsCount / pageSize);
|
|
96
|
-
let pageList = React.useMemo(
|
|
97
|
-
() =>
|
|
98
|
-
new Array(totalPagesCount)
|
|
99
|
-
.fill(null)
|
|
100
|
-
.map((_, index) => pageButton(index)),
|
|
101
|
-
[pageButton, totalPagesCount],
|
|
102
|
-
);
|
|
103
|
-
let [overflowRef, visibleCount] = useOverflow(pageList);
|
|
104
|
-
let [paginatorResizeRef, paginatorWidth] = useContainerWidth();
|
|
105
78
|
let onKeyDown = (event) => {
|
|
106
79
|
if (event.altKey) return;
|
|
107
80
|
let focusPage = (delta) => {
|
|
@@ -132,30 +105,10 @@ export const TablePaginator = (props) => {
|
|
|
132
105
|
break;
|
|
133
106
|
}
|
|
134
107
|
};
|
|
135
|
-
let
|
|
136
|
-
let startPage = focusedIndex - halfVisibleCount;
|
|
137
|
-
let endPage = focusedIndex + halfVisibleCount + 1;
|
|
138
|
-
if (startPage < 0) {
|
|
139
|
-
endPage = Math.min(totalPagesCount, endPage + Math.abs(startPage));
|
|
140
|
-
startPage = 0;
|
|
141
|
-
}
|
|
142
|
-
if (endPage > totalPagesCount) {
|
|
143
|
-
startPage = Math.max(0, startPage - (endPage - totalPagesCount));
|
|
144
|
-
endPage = totalPagesCount;
|
|
145
|
-
}
|
|
146
|
-
let hasNoRows = 0 === totalPagesCount;
|
|
108
|
+
let [paginatorResizeRef, paginatorWidth] = useContainerWidth();
|
|
147
109
|
let showPagesList = totalPagesCount > 1 || isLoading;
|
|
148
110
|
let showPageSizeList = pageSizeList && !!onPageSizeChange && !!totalRowsCount;
|
|
149
|
-
let
|
|
150
|
-
Box,
|
|
151
|
-
{
|
|
152
|
-
as: 'span',
|
|
153
|
-
className: cx('iui-table-paginator-ellipsis', {
|
|
154
|
-
'iui-table-paginator-ellipsis-small': 'small' === size,
|
|
155
|
-
}),
|
|
156
|
-
},
|
|
157
|
-
'…',
|
|
158
|
-
);
|
|
111
|
+
let hasNoRows = 0 === totalPagesCount;
|
|
159
112
|
let noRowsContent = React.createElement(
|
|
160
113
|
React.Fragment,
|
|
161
114
|
null,
|
|
@@ -196,10 +149,10 @@ export const TablePaginator = (props) => {
|
|
|
196
149
|
),
|
|
197
150
|
showPagesList &&
|
|
198
151
|
React.createElement(
|
|
199
|
-
|
|
152
|
+
OverflowContainer,
|
|
200
153
|
{
|
|
201
154
|
className: 'iui-center',
|
|
202
|
-
|
|
155
|
+
itemsCount: totalPagesCount,
|
|
203
156
|
},
|
|
204
157
|
React.createElement(
|
|
205
158
|
IconButton,
|
|
@@ -220,40 +173,17 @@ export const TablePaginator = (props) => {
|
|
|
220
173
|
onKeyDown: onKeyDown,
|
|
221
174
|
ref: pageListRef,
|
|
222
175
|
},
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
ellipsis,
|
|
235
|
-
),
|
|
236
|
-
pageList.slice(startPage, endPage),
|
|
237
|
-
endPage !== totalPagesCount &&
|
|
238
|
-
!isLoading &&
|
|
239
|
-
React.createElement(
|
|
240
|
-
React.Fragment,
|
|
241
|
-
null,
|
|
242
|
-
ellipsis,
|
|
243
|
-
pageButton(totalPagesCount - 1, 0),
|
|
244
|
-
),
|
|
245
|
-
isLoading &&
|
|
246
|
-
React.createElement(
|
|
247
|
-
React.Fragment,
|
|
248
|
-
null,
|
|
249
|
-
ellipsis,
|
|
250
|
-
React.createElement(ProgressRadial, {
|
|
251
|
-
indeterminate: true,
|
|
252
|
-
size: 'small',
|
|
253
|
-
}),
|
|
254
|
-
),
|
|
255
|
-
);
|
|
256
|
-
})(),
|
|
176
|
+
hasNoRows
|
|
177
|
+
? noRowsContent
|
|
178
|
+
: React.createElement(TablePaginatorPageButtons, {
|
|
179
|
+
size: size,
|
|
180
|
+
focusedIndex: focusedIndex,
|
|
181
|
+
totalPagesCount: totalPagesCount,
|
|
182
|
+
onPageChange: onPageChange,
|
|
183
|
+
currentPage: currentPage,
|
|
184
|
+
localization: localization,
|
|
185
|
+
isLoading: isLoading,
|
|
186
|
+
}),
|
|
257
187
|
),
|
|
258
188
|
React.createElement(
|
|
259
189
|
IconButton,
|
|
@@ -318,3 +248,96 @@ export const TablePaginator = (props) => {
|
|
|
318
248
|
),
|
|
319
249
|
);
|
|
320
250
|
};
|
|
251
|
+
let TablePaginatorPageButtons = (props) => {
|
|
252
|
+
let {
|
|
253
|
+
focusedIndex,
|
|
254
|
+
totalPagesCount,
|
|
255
|
+
onPageChange,
|
|
256
|
+
currentPage,
|
|
257
|
+
localization,
|
|
258
|
+
isLoading,
|
|
259
|
+
size,
|
|
260
|
+
} = props;
|
|
261
|
+
let { visibleCount } = OverflowContainer.useContext();
|
|
262
|
+
let buttonSize = 'default' != size ? 'small' : void 0;
|
|
263
|
+
let pageButton = React.useCallback(
|
|
264
|
+
(index, tabIndex = index === focusedIndex ? 0 : -1) =>
|
|
265
|
+
React.createElement(
|
|
266
|
+
Button,
|
|
267
|
+
{
|
|
268
|
+
key: index,
|
|
269
|
+
className: 'iui-table-paginator-page-button',
|
|
270
|
+
styleType: 'borderless',
|
|
271
|
+
size: buttonSize,
|
|
272
|
+
'data-iui-active': index === currentPage,
|
|
273
|
+
onClick: () => onPageChange(index),
|
|
274
|
+
'aria-current': index === currentPage,
|
|
275
|
+
'aria-label': localization.goToPageLabel?.(index + 1),
|
|
276
|
+
tabIndex: tabIndex,
|
|
277
|
+
},
|
|
278
|
+
index + 1,
|
|
279
|
+
),
|
|
280
|
+
[focusedIndex, currentPage, localization, buttonSize, onPageChange],
|
|
281
|
+
);
|
|
282
|
+
let pageList = React.useMemo(
|
|
283
|
+
() =>
|
|
284
|
+
new Array(totalPagesCount)
|
|
285
|
+
.fill(null)
|
|
286
|
+
.map((_, index) => pageButton(index)),
|
|
287
|
+
[pageButton, totalPagesCount],
|
|
288
|
+
);
|
|
289
|
+
let halfVisibleCount = Math.floor(visibleCount / 2);
|
|
290
|
+
let startPage = focusedIndex - halfVisibleCount;
|
|
291
|
+
let endPage = focusedIndex + halfVisibleCount + 1;
|
|
292
|
+
if (startPage < 0) {
|
|
293
|
+
endPage = Math.min(totalPagesCount, endPage + Math.abs(startPage));
|
|
294
|
+
startPage = 0;
|
|
295
|
+
}
|
|
296
|
+
if (endPage > totalPagesCount) {
|
|
297
|
+
startPage = Math.max(0, startPage - (endPage - totalPagesCount));
|
|
298
|
+
endPage = totalPagesCount;
|
|
299
|
+
}
|
|
300
|
+
let ellipsis = React.createElement(
|
|
301
|
+
Box,
|
|
302
|
+
{
|
|
303
|
+
as: 'span',
|
|
304
|
+
className: cx('iui-table-paginator-ellipsis', {
|
|
305
|
+
'iui-table-paginator-ellipsis-small': 'small' === size,
|
|
306
|
+
}),
|
|
307
|
+
},
|
|
308
|
+
'…',
|
|
309
|
+
);
|
|
310
|
+
if (1 === visibleCount) return pageButton(focusedIndex);
|
|
311
|
+
let showStartEllipsis = startPage > 1;
|
|
312
|
+
let showEndEllipsis = endPage < totalPagesCount - 1;
|
|
313
|
+
return React.createElement(
|
|
314
|
+
React.Fragment,
|
|
315
|
+
null,
|
|
316
|
+
0 !== startPage &&
|
|
317
|
+
React.createElement(
|
|
318
|
+
React.Fragment,
|
|
319
|
+
null,
|
|
320
|
+
pageButton(0, 0),
|
|
321
|
+
showStartEllipsis ? ellipsis : null,
|
|
322
|
+
),
|
|
323
|
+
pageList.slice(startPage, endPage),
|
|
324
|
+
endPage !== totalPagesCount &&
|
|
325
|
+
!isLoading &&
|
|
326
|
+
React.createElement(
|
|
327
|
+
React.Fragment,
|
|
328
|
+
null,
|
|
329
|
+
showEndEllipsis ? ellipsis : null,
|
|
330
|
+
pageButton(totalPagesCount - 1, 0),
|
|
331
|
+
),
|
|
332
|
+
isLoading &&
|
|
333
|
+
React.createElement(
|
|
334
|
+
React.Fragment,
|
|
335
|
+
null,
|
|
336
|
+
ellipsis,
|
|
337
|
+
React.createElement(ProgressRadial, {
|
|
338
|
+
indeterminate: true,
|
|
339
|
+
size: 'small',
|
|
340
|
+
}),
|
|
341
|
+
),
|
|
342
|
+
);
|
|
343
|
+
};
|
|
@@ -2,14 +2,14 @@ import * as React from 'react';
|
|
|
2
2
|
import { defaultColumn } from 'react-table';
|
|
3
3
|
import cx from 'classnames';
|
|
4
4
|
import { Box, LineClamp, ShadowRoot } from '../../../utils/index.js';
|
|
5
|
-
import {
|
|
5
|
+
import { TableInstanceContext } from '../utils.js';
|
|
6
6
|
export const DefaultCell = (props) => {
|
|
7
|
-
let
|
|
7
|
+
let instance = React.useContext(TableInstanceContext);
|
|
8
8
|
let isCustomCell = React.useMemo(
|
|
9
9
|
() =>
|
|
10
|
-
|
|
10
|
+
instance?.columns.find(({ id }) => props.cellProps.column.id === id)
|
|
11
11
|
?.Cell !== defaultColumn.Cell,
|
|
12
|
-
[
|
|
12
|
+
[instance, props.cellProps.column.id],
|
|
13
13
|
);
|
|
14
14
|
let {
|
|
15
15
|
cellElementProps: {
|
|
@@ -47,4 +47,4 @@ export const getSubRowStyle = ({ density = 'default', depth = 1 }) => {
|
|
|
47
47
|
paddingInlineStart: cellPadding + depth * multiplier,
|
|
48
48
|
};
|
|
49
49
|
};
|
|
50
|
-
export const
|
|
50
|
+
export const TableInstanceContext = React.createContext(void 0);
|
package/DEV-esm/styles.js
CHANGED
|
@@ -1,20 +1,12 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { OverflowContainer } from './OverflowContainer.js';
|
|
3
3
|
let ELLIPSIS_CHAR = '…';
|
|
4
4
|
export const MiddleTextTruncation = (props) => {
|
|
5
|
-
let { text,
|
|
6
|
-
let [ref, visibleCount] = useOverflow(text);
|
|
7
|
-
let truncatedText = React.useMemo(() => {
|
|
8
|
-
if (visibleCount < text.length)
|
|
9
|
-
return `${text.substring(
|
|
10
|
-
0,
|
|
11
|
-
visibleCount - endCharsCount - ELLIPSIS_CHAR.length,
|
|
12
|
-
)}${ELLIPSIS_CHAR}${text.substring(text.length - endCharsCount)}`;
|
|
13
|
-
return text;
|
|
14
|
-
}, [endCharsCount, text, visibleCount]);
|
|
5
|
+
let { text, style, ...rest } = props;
|
|
15
6
|
return React.createElement(
|
|
16
|
-
|
|
7
|
+
OverflowContainer,
|
|
17
8
|
{
|
|
9
|
+
as: 'span',
|
|
18
10
|
style: {
|
|
19
11
|
display: 'flex',
|
|
20
12
|
minWidth: 0,
|
|
@@ -22,10 +14,23 @@ export const MiddleTextTruncation = (props) => {
|
|
|
22
14
|
whiteSpace: 'nowrap',
|
|
23
15
|
...style,
|
|
24
16
|
},
|
|
25
|
-
|
|
17
|
+
itemsCount: text.length,
|
|
26
18
|
...rest,
|
|
27
19
|
},
|
|
28
|
-
|
|
20
|
+
React.createElement(MiddleTextTruncationContent, props),
|
|
29
21
|
);
|
|
30
22
|
};
|
|
31
23
|
MiddleTextTruncation.displayName = 'MiddleTextTruncation';
|
|
24
|
+
let MiddleTextTruncationContent = (props) => {
|
|
25
|
+
let { text, endCharsCount = 6, textRenderer } = props;
|
|
26
|
+
let { visibleCount } = OverflowContainer.useContext();
|
|
27
|
+
let truncatedText = React.useMemo(() => {
|
|
28
|
+
if (visibleCount < text.length)
|
|
29
|
+
return `${text.substring(
|
|
30
|
+
0,
|
|
31
|
+
visibleCount - endCharsCount - ELLIPSIS_CHAR.length,
|
|
32
|
+
)}${ELLIPSIS_CHAR}${text.substring(text.length - endCharsCount)}`;
|
|
33
|
+
return text;
|
|
34
|
+
}, [endCharsCount, text, visibleCount]);
|
|
35
|
+
return textRenderer?.(truncatedText, text) ?? truncatedText;
|
|
36
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { useMergedRefs } from '../hooks/useMergedRefs.js';
|
|
3
|
+
import { Box } from './Box.js';
|
|
4
|
+
import { useOverflow } from '../hooks/useOverflow.js';
|
|
5
|
+
import { useSafeContext } from '../hooks/useSafeContext.js';
|
|
6
|
+
let OverflowContainerComponent = React.forwardRef((props, ref) => {
|
|
7
|
+
let { itemsCount, children, overflowOrientation, ...rest } = props;
|
|
8
|
+
let [containerRef, visibleCount] = useOverflow(
|
|
9
|
+
itemsCount,
|
|
10
|
+
false,
|
|
11
|
+
overflowOrientation,
|
|
12
|
+
);
|
|
13
|
+
let overflowContainerContextValue = React.useMemo(
|
|
14
|
+
() => ({
|
|
15
|
+
visibleCount,
|
|
16
|
+
itemsCount,
|
|
17
|
+
}),
|
|
18
|
+
[itemsCount, visibleCount],
|
|
19
|
+
);
|
|
20
|
+
return React.createElement(
|
|
21
|
+
OverflowContainerContext.Provider,
|
|
22
|
+
{
|
|
23
|
+
value: overflowContainerContextValue,
|
|
24
|
+
},
|
|
25
|
+
React.createElement(
|
|
26
|
+
Box,
|
|
27
|
+
{
|
|
28
|
+
ref: useMergedRefs(ref, containerRef),
|
|
29
|
+
...rest,
|
|
30
|
+
},
|
|
31
|
+
children,
|
|
32
|
+
),
|
|
33
|
+
);
|
|
34
|
+
});
|
|
35
|
+
let OverflowContainerOverflowNode = (props) => {
|
|
36
|
+
let { children } = props;
|
|
37
|
+
let { visibleCount, itemsCount } = useOverflowContainerContext();
|
|
38
|
+
let isOverflowing = visibleCount < itemsCount;
|
|
39
|
+
return isOverflowing ? children : null;
|
|
40
|
+
};
|
|
41
|
+
export const OverflowContainer = Object.assign(OverflowContainerComponent, {
|
|
42
|
+
OverflowNode: OverflowContainerOverflowNode,
|
|
43
|
+
useContext: useOverflowContainerContext,
|
|
44
|
+
});
|
|
45
|
+
let OverflowContainerContext = React.createContext(void 0);
|
|
46
|
+
OverflowContainerContext.displayName = 'OverflowContainerContext';
|
|
47
|
+
function useOverflowContainerContext() {
|
|
48
|
+
let overflowContainerContext = useSafeContext(OverflowContainerContext);
|
|
49
|
+
return overflowContainerContext;
|
|
50
|
+
}
|
|
@@ -4,13 +4,13 @@ import { useResizeObserver } from './useResizeObserver.js';
|
|
|
4
4
|
import { useLayoutEffect } from './useIsomorphicLayoutEffect.js';
|
|
5
5
|
let STARTING_MAX_ITEMS_COUNT = 20;
|
|
6
6
|
export const useOverflow = (
|
|
7
|
-
|
|
7
|
+
itemsCount,
|
|
8
8
|
disabled = false,
|
|
9
9
|
orientation = 'horizontal',
|
|
10
10
|
) => {
|
|
11
11
|
let containerRef = React.useRef(null);
|
|
12
12
|
let [visibleCount, setVisibleCount] = React.useState(() =>
|
|
13
|
-
disabled ?
|
|
13
|
+
disabled ? itemsCount : Math.min(itemsCount, STARTING_MAX_ITEMS_COUNT),
|
|
14
14
|
);
|
|
15
15
|
let needsFullRerender = React.useRef(true);
|
|
16
16
|
let [containerSize, setContainerSize] = React.useState(0);
|
|
@@ -23,12 +23,12 @@ export const useOverflow = (
|
|
|
23
23
|
let [resizeRef, observer] = useResizeObserver(updateContainerSize);
|
|
24
24
|
let resizeObserverRef = React.useRef(observer);
|
|
25
25
|
useLayoutEffect(() => {
|
|
26
|
-
if (disabled) setVisibleCount(
|
|
26
|
+
if (disabled) setVisibleCount(itemsCount);
|
|
27
27
|
else {
|
|
28
|
-
setVisibleCount(Math.min(
|
|
28
|
+
setVisibleCount(Math.min(itemsCount, STARTING_MAX_ITEMS_COUNT));
|
|
29
29
|
needsFullRerender.current = true;
|
|
30
30
|
}
|
|
31
|
-
}, [containerSize, disabled,
|
|
31
|
+
}, [containerSize, disabled, itemsCount]);
|
|
32
32
|
let mergedRefs = useMergedRefs(containerRef, resizeRef);
|
|
33
33
|
useLayoutEffect(() => {
|
|
34
34
|
if (!containerRef.current || disabled) {
|
|
@@ -48,14 +48,14 @@ export const useOverflow = (
|
|
|
48
48
|
0,
|
|
49
49
|
);
|
|
50
50
|
let currentVisibleCount =
|
|
51
|
-
visibleCount || Math.min(
|
|
51
|
+
visibleCount || Math.min(itemsCount, STARTING_MAX_ITEMS_COUNT);
|
|
52
52
|
let avgItemSize = childrenSize / currentVisibleCount;
|
|
53
53
|
let visibleItems = Math.floor(availableSize / avgItemSize);
|
|
54
54
|
if (!isNaN(visibleItems))
|
|
55
|
-
setVisibleCount(Math.min(
|
|
55
|
+
setVisibleCount(Math.min(itemsCount, 2 * visibleItems));
|
|
56
56
|
}
|
|
57
57
|
needsFullRerender.current = false;
|
|
58
|
-
}, [containerSize, visibleCount, disabled,
|
|
58
|
+
}, [containerSize, visibleCount, disabled, itemsCount, orientation]);
|
|
59
59
|
useLayoutEffect(() => {
|
|
60
60
|
previousContainerSize.current = containerSize;
|
|
61
61
|
}, [containerSize]);
|