@itwin/itwinui-react 3.15.4 → 3.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +30 -0
- package/DEV-cjs/core/Breadcrumbs/Breadcrumbs.js +2 -2
- package/DEV-cjs/core/Checkbox/Checkbox.js +4 -6
- package/DEV-cjs/core/ComboBox/ComboBox.js +10 -6
- package/DEV-cjs/core/DatePicker/DatePicker.js +9 -1
- package/DEV-cjs/core/Dialog/Dialog.js +1 -1
- package/DEV-cjs/core/Panels/Panels.js +319 -0
- package/DEV-cjs/core/Panels/helpers.js +62 -0
- package/DEV-cjs/core/Radio/Radio.js +4 -6
- package/DEV-cjs/core/RadioTiles/RadioTileGroup.js +9 -2
- package/DEV-cjs/core/Select/SelectTag.js +9 -11
- package/DEV-cjs/core/Select/SelectTagContainer.js +2 -2
- package/DEV-cjs/core/Stepper/Stepper.js +1 -0
- package/DEV-cjs/core/Stepper/StepperStep.js +2 -1
- package/DEV-cjs/core/Table/Table.js +64 -47
- package/DEV-cjs/core/Table/TablePaginator.js +15 -3
- package/DEV-cjs/core/Table/actionHandlers/selectHandler.js +10 -7
- package/DEV-cjs/core/Table/columns/selectionColumn.js +6 -1
- package/DEV-cjs/core/Tree/Tree.js +1 -0
- package/DEV-cjs/index.js +4 -0
- package/DEV-cjs/styles.js +1 -1
- package/DEV-cjs/utils/components/MiddleTextTruncation.js +22 -4
- package/DEV-cjs/utils/components/OverflowContainer.js +170 -27
- package/DEV-cjs/utils/hooks/index.js +1 -1
- package/DEV-cjs/utils/hooks/useInstance.js +38 -0
- package/DEV-esm/core/Breadcrumbs/Breadcrumbs.js +2 -2
- package/DEV-esm/core/Checkbox/Checkbox.js +5 -10
- package/DEV-esm/core/ComboBox/ComboBox.js +10 -6
- package/DEV-esm/core/DatePicker/DatePicker.js +11 -1
- package/DEV-esm/core/Dialog/Dialog.js +1 -1
- package/DEV-esm/core/Panels/Panels.js +301 -0
- package/DEV-esm/core/Panels/helpers.js +42 -0
- package/DEV-esm/core/Radio/Radio.js +4 -9
- package/DEV-esm/core/RadioTiles/RadioTileGroup.js +8 -2
- package/DEV-esm/core/Select/SelectTag.js +9 -11
- package/DEV-esm/core/Select/SelectTagContainer.js +2 -2
- package/DEV-esm/core/Stepper/Stepper.js +1 -0
- package/DEV-esm/core/Stepper/StepperStep.js +2 -1
- package/DEV-esm/core/Table/Table.js +61 -47
- package/DEV-esm/core/Table/TablePaginator.js +16 -3
- package/DEV-esm/core/Table/actionHandlers/selectHandler.js +10 -7
- package/DEV-esm/core/Table/columns/selectionColumn.js +6 -1
- package/DEV-esm/core/Tree/Tree.js +1 -0
- package/DEV-esm/index.js +1 -0
- package/DEV-esm/styles.js +1 -1
- package/DEV-esm/utils/components/MiddleTextTruncation.js +22 -4
- package/DEV-esm/utils/components/OverflowContainer.js +143 -4
- package/DEV-esm/utils/hooks/index.js +1 -1
- package/DEV-esm/utils/hooks/useInstance.js +18 -0
- package/cjs/core/Breadcrumbs/Breadcrumbs.js +2 -2
- package/cjs/core/Checkbox/Checkbox.js +4 -6
- package/cjs/core/ComboBox/ComboBox.d.ts +13 -0
- package/cjs/core/ComboBox/ComboBox.js +10 -6
- package/cjs/core/DatePicker/DatePicker.d.ts +2 -2
- package/cjs/core/DatePicker/DatePicker.js +2 -1
- package/cjs/core/Dialog/Dialog.js +1 -1
- package/cjs/core/Dialog/DialogContext.d.ts +6 -2
- package/cjs/core/NonIdealState/NonIdealState.d.ts +15 -11
- package/cjs/core/Panels/Panels.d.ts +174 -0
- package/cjs/core/Panels/Panels.js +312 -0
- package/cjs/core/Panels/helpers.d.ts +23 -0
- package/cjs/core/Panels/helpers.js +61 -0
- package/cjs/core/Radio/Radio.js +4 -6
- package/cjs/core/RadioTiles/RadioTileGroup.d.ts +3 -1
- package/cjs/core/RadioTiles/RadioTileGroup.js +9 -2
- package/cjs/core/Select/SelectTag.d.ts +3 -1
- package/cjs/core/Select/SelectTag.js +9 -11
- package/cjs/core/Select/SelectTagContainer.js +2 -2
- package/cjs/core/Stepper/Stepper.d.ts +4 -0
- package/cjs/core/Stepper/Stepper.js +1 -0
- package/cjs/core/Stepper/StepperStep.d.ts +4 -0
- package/cjs/core/Stepper/StepperStep.js +2 -1
- package/cjs/core/Table/Table.d.ts +1 -0
- package/cjs/core/Table/Table.js +64 -47
- package/cjs/core/Table/TablePaginator.js +15 -3
- package/cjs/core/Table/actionHandlers/selectHandler.js +10 -7
- package/cjs/core/Table/columns/selectionColumn.js +6 -1
- package/cjs/core/Tree/Tree.js +1 -0
- package/cjs/index.d.ts +1 -0
- package/cjs/index.js +4 -0
- package/cjs/styles.js +1 -1
- package/cjs/utils/components/MiddleTextTruncation.d.ts +5 -7
- package/cjs/utils/components/MiddleTextTruncation.js +22 -4
- package/cjs/utils/components/OverflowContainer.d.ts +1 -0
- package/cjs/utils/components/OverflowContainer.js +170 -27
- package/cjs/utils/hooks/index.d.ts +1 -1
- package/cjs/utils/hooks/index.js +1 -1
- package/cjs/utils/hooks/useInstance.d.ts +22 -0
- package/cjs/utils/hooks/useInstance.js +38 -0
- package/esm/core/Breadcrumbs/Breadcrumbs.js +2 -2
- package/esm/core/Checkbox/Checkbox.js +5 -10
- package/esm/core/ComboBox/ComboBox.d.ts +13 -0
- package/esm/core/ComboBox/ComboBox.js +10 -6
- package/esm/core/DatePicker/DatePicker.d.ts +2 -2
- package/esm/core/DatePicker/DatePicker.js +4 -1
- package/esm/core/Dialog/Dialog.js +1 -1
- package/esm/core/Dialog/DialogContext.d.ts +6 -2
- package/esm/core/NonIdealState/NonIdealState.d.ts +15 -11
- package/esm/core/Panels/Panels.d.ts +174 -0
- package/esm/core/Panels/Panels.js +294 -0
- package/esm/core/Panels/helpers.d.ts +23 -0
- package/esm/core/Panels/helpers.js +41 -0
- package/esm/core/Radio/Radio.js +4 -9
- package/esm/core/RadioTiles/RadioTileGroup.d.ts +3 -1
- package/esm/core/RadioTiles/RadioTileGroup.js +8 -2
- package/esm/core/Select/SelectTag.d.ts +3 -1
- package/esm/core/Select/SelectTag.js +9 -11
- package/esm/core/Select/SelectTagContainer.js +2 -2
- package/esm/core/Stepper/Stepper.d.ts +4 -0
- package/esm/core/Stepper/Stepper.js +1 -0
- package/esm/core/Stepper/StepperStep.d.ts +4 -0
- package/esm/core/Stepper/StepperStep.js +2 -1
- package/esm/core/Table/Table.d.ts +1 -0
- package/esm/core/Table/Table.js +61 -47
- package/esm/core/Table/TablePaginator.js +16 -3
- package/esm/core/Table/actionHandlers/selectHandler.js +10 -7
- package/esm/core/Table/columns/selectionColumn.js +6 -1
- package/esm/core/Tree/Tree.js +1 -0
- package/esm/index.d.ts +1 -0
- package/esm/index.js +1 -0
- package/esm/styles.js +1 -1
- package/esm/utils/components/MiddleTextTruncation.d.ts +5 -7
- package/esm/utils/components/MiddleTextTruncation.js +22 -4
- package/esm/utils/components/OverflowContainer.d.ts +1 -0
- package/esm/utils/components/OverflowContainer.js +143 -4
- package/esm/utils/hooks/index.d.ts +1 -1
- package/esm/utils/hooks/index.js +1 -1
- package/esm/utils/hooks/useInstance.d.ts +22 -0
- package/esm/utils/hooks/useInstance.js +18 -0
- package/package.json +2 -2
- package/styles.css +8 -8
- package/DEV-cjs/utils/hooks/useOverflow.js +0 -76
- package/DEV-esm/utils/hooks/useOverflow.js +0 -63
- package/cjs/utils/hooks/useOverflow.d.ts +0 -23
- package/cjs/utils/hooks/useOverflow.js +0 -76
- package/esm/utils/hooks/useOverflow.d.ts +0 -23
- package/esm/utils/hooks/useOverflow.js +0 -63
|
@@ -17,6 +17,7 @@ export const StepperStep = React.forwardRef((props, forwardedRef) => {
|
|
|
17
17
|
trackContentProps,
|
|
18
18
|
circleProps,
|
|
19
19
|
nameProps,
|
|
20
|
+
stepContent,
|
|
20
21
|
...rest
|
|
21
22
|
} = props;
|
|
22
23
|
let isPast = currentStepNumber > index;
|
|
@@ -74,7 +75,7 @@ export const StepperStep = React.forwardRef((props, forwardedRef) => {
|
|
|
74
75
|
...circleProps,
|
|
75
76
|
className: cx('iui-stepper-circle', circleProps?.className),
|
|
76
77
|
},
|
|
77
|
-
index + 1,
|
|
78
|
+
stepContent ? stepContent() : index + 1,
|
|
78
79
|
),
|
|
79
80
|
),
|
|
80
81
|
'default' === type &&
|
|
@@ -3,6 +3,7 @@ import type { CellProps, TableOptions, Row, TableState } from '../../react-table
|
|
|
3
3
|
import type { CommonProps } from '../../utils/index.js';
|
|
4
4
|
import type { TableFilterValue } from './filters/index.js';
|
|
5
5
|
export declare const tableResizeStartAction = "tableResizeStart";
|
|
6
|
+
export declare const iuiId: unique symbol;
|
|
6
7
|
export type TablePaginatorRendererProps = {
|
|
7
8
|
/**
|
|
8
9
|
* The zero-based index of the current page.
|
package/esm/core/Table/Table.js
CHANGED
|
@@ -53,6 +53,7 @@ let singleRowSelectedAction = 'singleRowSelected';
|
|
|
53
53
|
let shiftRowSelectedAction = 'shiftRowSelected';
|
|
54
54
|
export const tableResizeStartAction = 'tableResizeStart';
|
|
55
55
|
let tableResizeEndAction = 'tableResizeEnd';
|
|
56
|
+
export const 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
|
+
];
|
|
251
255
|
},
|
|
252
|
-
[
|
|
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;
|
|
267
|
+
},
|
|
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),
|
|
@@ -461,51 +478,52 @@ export const Table = (props) => {
|
|
|
461
478
|
(index, virtualItem, virtualizer) => {
|
|
462
479
|
let row = page[index];
|
|
463
480
|
prepareRow(row);
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
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
|
-
|
|
481
|
+
let isRowASubComponent = !!row.original[iuiId] && !!subComponent;
|
|
482
|
+
if (isRowASubComponent)
|
|
483
|
+
return React.createElement(
|
|
484
|
+
TableExpandableContentMemoized,
|
|
485
|
+
{
|
|
486
|
+
key: row.getRowProps().key,
|
|
487
|
+
virtualItem: virtualItem,
|
|
488
|
+
ref: enableVirtualization
|
|
489
|
+
? virtualizer?.measureElement
|
|
490
|
+
: tableRowRef(row),
|
|
491
|
+
isDisabled: !!isRowDisabled?.(row.original),
|
|
492
|
+
},
|
|
493
|
+
subComponent(row),
|
|
494
|
+
);
|
|
495
|
+
return React.createElement(TableRowMemoized, {
|
|
496
|
+
row: row,
|
|
497
|
+
rowProps: rowProps,
|
|
498
|
+
isLast: index === page.length - 1,
|
|
499
|
+
onRowInViewport: onRowInViewportRef,
|
|
500
|
+
onBottomReached: onBottomReachedRef,
|
|
501
|
+
intersectionMargin: intersectionMargin,
|
|
502
|
+
state: state,
|
|
503
|
+
key: row.getRowProps().key,
|
|
504
|
+
onClick: onRowClickHandler,
|
|
505
|
+
subComponent: subComponent,
|
|
506
|
+
isDisabled: !!isRowDisabled?.(row.original),
|
|
507
|
+
tableHasSubRows: hasAnySubRows,
|
|
508
|
+
tableInstance: instance,
|
|
509
|
+
expanderCell: expanderCell,
|
|
510
|
+
scrollContainerRef: tableRef.current,
|
|
511
|
+
tableRowRef: enableVirtualization ? void 0 : tableRowRef(row),
|
|
512
|
+
density: density,
|
|
513
|
+
virtualItem: virtualItem,
|
|
514
|
+
virtualizer: virtualizer,
|
|
515
|
+
});
|
|
498
516
|
},
|
|
499
517
|
[
|
|
500
518
|
page,
|
|
501
519
|
prepareRow,
|
|
520
|
+
subComponent,
|
|
502
521
|
rowProps,
|
|
503
522
|
onRowInViewportRef,
|
|
504
523
|
onBottomReachedRef,
|
|
505
524
|
intersectionMargin,
|
|
506
525
|
state,
|
|
507
526
|
onRowClickHandler,
|
|
508
|
-
subComponent,
|
|
509
527
|
isRowDisabled,
|
|
510
528
|
hasAnySubRows,
|
|
511
529
|
instance,
|
|
@@ -639,11 +657,7 @@ export const Table = (props) => {
|
|
|
639
657
|
},
|
|
640
658
|
bodyProps?.className,
|
|
641
659
|
),
|
|
642
|
-
style: {
|
|
643
|
-
outline: 0,
|
|
644
|
-
},
|
|
645
660
|
}),
|
|
646
|
-
tabIndex: -1,
|
|
647
661
|
'aria-multiselectable':
|
|
648
662
|
(isSelectable && 'multi' === selectionMode) || void 0,
|
|
649
663
|
},
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
SvgChevronRight,
|
|
14
14
|
Box,
|
|
15
15
|
OverflowContainer,
|
|
16
|
+
useLayoutEffect,
|
|
16
17
|
} from '../../utils/index.js';
|
|
17
18
|
import { styles } from '../../styles.js';
|
|
18
19
|
let defaultLocalization = {
|
|
@@ -56,7 +57,7 @@ export const TablePaginator = (props) => {
|
|
|
56
57
|
);
|
|
57
58
|
let pageListRef = React.useRef(null);
|
|
58
59
|
let [focusedIndex, setFocusedIndex] = React.useState(currentPage);
|
|
59
|
-
|
|
60
|
+
useLayoutEffect(() => {
|
|
60
61
|
setFocusedIndex(currentPage);
|
|
61
62
|
}, [currentPage]);
|
|
62
63
|
let needFocus = React.useRef(false);
|
|
@@ -178,6 +179,7 @@ export const TablePaginator = (props) => {
|
|
|
178
179
|
: React.createElement(TablePaginatorPageButtons, {
|
|
179
180
|
size: size,
|
|
180
181
|
focusedIndex: focusedIndex,
|
|
182
|
+
setFocusedIndex: setFocusedIndex,
|
|
181
183
|
totalPagesCount: totalPagesCount,
|
|
182
184
|
onPageChange: onPageChange,
|
|
183
185
|
currentPage: currentPage,
|
|
@@ -251,6 +253,7 @@ export const TablePaginator = (props) => {
|
|
|
251
253
|
let TablePaginatorPageButtons = (props) => {
|
|
252
254
|
let {
|
|
253
255
|
focusedIndex,
|
|
256
|
+
setFocusedIndex,
|
|
254
257
|
totalPagesCount,
|
|
255
258
|
onPageChange,
|
|
256
259
|
currentPage,
|
|
@@ -270,14 +273,24 @@ let TablePaginatorPageButtons = (props) => {
|
|
|
270
273
|
styleType: 'borderless',
|
|
271
274
|
size: buttonSize,
|
|
272
275
|
'data-iui-active': index === currentPage,
|
|
273
|
-
onClick: () =>
|
|
276
|
+
onClick: () => {
|
|
277
|
+
setFocusedIndex(index);
|
|
278
|
+
onPageChange(index);
|
|
279
|
+
},
|
|
274
280
|
'aria-current': index === currentPage,
|
|
275
281
|
'aria-label': localization.goToPageLabel?.(index + 1),
|
|
276
282
|
tabIndex: tabIndex,
|
|
277
283
|
},
|
|
278
284
|
index + 1,
|
|
279
285
|
),
|
|
280
|
-
[
|
|
286
|
+
[
|
|
287
|
+
focusedIndex,
|
|
288
|
+
buttonSize,
|
|
289
|
+
currentPage,
|
|
290
|
+
localization,
|
|
291
|
+
setFocusedIndex,
|
|
292
|
+
onPageChange,
|
|
293
|
+
],
|
|
281
294
|
);
|
|
282
295
|
let pageList = React.useMemo(
|
|
283
296
|
() =>
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { iuiId } from '../Table.js';
|
|
1
2
|
let onSelectHandler = (newState, instance, onSelect, isRowDisabled) => {
|
|
2
3
|
if (!instance?.rows.length) {
|
|
3
4
|
onSelect?.([], newState);
|
|
@@ -7,14 +8,16 @@ let onSelectHandler = (newState, instance, onSelect, isRowDisabled) => {
|
|
|
7
8
|
let handleRow = (row) => {
|
|
8
9
|
if (isRowDisabled?.(row.original)) return false;
|
|
9
10
|
let isAllSubSelected = true;
|
|
10
|
-
row.initialSubRows
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
if (row.initialSubRows[0]?.original[iuiId] === void 0)
|
|
12
|
+
row.initialSubRows.forEach((subRow) => {
|
|
13
|
+
let result = handleRow(subRow);
|
|
14
|
+
if (!result) isAllSubSelected = false;
|
|
15
|
+
});
|
|
14
16
|
if (
|
|
15
|
-
|
|
16
|
-
(!
|
|
17
|
-
|
|
17
|
+
newState.selectedRowIds[row.id] &&
|
|
18
|
+
(!instance.selectSubRows ||
|
|
19
|
+
!row.initialSubRows.length ||
|
|
20
|
+
isAllSubSelected)
|
|
18
21
|
)
|
|
19
22
|
newSelectedRowIds[row.id] = true;
|
|
20
23
|
return !!newSelectedRowIds[row.id];
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { Checkbox } from '../../Checkbox/Checkbox.js';
|
|
3
3
|
import { DefaultCell } from '../cells/index.js';
|
|
4
|
+
import { iuiId } from '../Table.js';
|
|
4
5
|
export const SELECTION_CELL_ID = 'iui-table-checkbox-selector';
|
|
5
6
|
export const SelectionColumn = (props = {}) => {
|
|
6
7
|
let { isDisabled, density } = props;
|
|
@@ -50,7 +51,11 @@ export const SelectionColumn = (props = {}) => {
|
|
|
50
51
|
disabled: isDisabled?.(row.original),
|
|
51
52
|
onClick: (e) => e.stopPropagation(),
|
|
52
53
|
onChange: () => {
|
|
53
|
-
if (
|
|
54
|
+
if (
|
|
55
|
+
row.subRows.length > 0 &&
|
|
56
|
+
selectSubRows &&
|
|
57
|
+
void 0 === row.initialSubRows[0].original[iuiId]
|
|
58
|
+
)
|
|
54
59
|
row.toggleRowSelected(
|
|
55
60
|
!row.subRows.every(
|
|
56
61
|
(subRow) => subRow.isSelected || isDisabled?.(subRow.original),
|
package/esm/core/Tree/Tree.js
CHANGED
package/esm/index.d.ts
CHANGED
|
@@ -62,6 +62,7 @@ export { ModalContent } from './core/Modal/ModalContent.js';
|
|
|
62
62
|
export { ModalButtonBar } from './core/Modal/ModalButtonBar.js';
|
|
63
63
|
export { NotificationMarker } from './core/NotificationMarker/NotificationMarker.js';
|
|
64
64
|
export { Overlay } from './core/Overlay/Overlay.js';
|
|
65
|
+
export { Panels as unstable_Panels } from './core/Panels/Panels.js';
|
|
65
66
|
export { ProgressLinear } from './core/ProgressIndicators/ProgressLinear.js';
|
|
66
67
|
export { ProgressRadial } from './core/ProgressIndicators/ProgressRadial.js';
|
|
67
68
|
export { Radio } from './core/Radio/Radio.js';
|
package/esm/index.js
CHANGED
|
@@ -64,6 +64,7 @@ export { ModalContent } from './core/Modal/ModalContent.js';
|
|
|
64
64
|
export { ModalButtonBar } from './core/Modal/ModalButtonBar.js';
|
|
65
65
|
export { NotificationMarker } from './core/NotificationMarker/NotificationMarker.js';
|
|
66
66
|
export { Overlay } from './core/Overlay/Overlay.js';
|
|
67
|
+
export { Panels as unstable_Panels } from './core/Panels/Panels.js';
|
|
67
68
|
export { ProgressLinear } from './core/ProgressIndicators/ProgressLinear.js';
|
|
68
69
|
export { ProgressRadial } from './core/ProgressIndicators/ProgressRadial.js';
|
|
69
70
|
export { Radio } from './core/Radio/Radio.js';
|
package/esm/styles.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import type {
|
|
3
|
-
|
|
2
|
+
import type { PolymorphicForwardRefComponent } from '../props.js';
|
|
3
|
+
type MiddleTextTruncationProps = {
|
|
4
4
|
/**
|
|
5
5
|
* Text to truncate.
|
|
6
6
|
*/
|
|
@@ -14,7 +14,7 @@ export type MiddleTextTruncationProps = {
|
|
|
14
14
|
* Custom renderer for the truncated text.
|
|
15
15
|
*/
|
|
16
16
|
textRenderer?: (truncatedText: string, originalText: string) => React.ReactNode;
|
|
17
|
-
}
|
|
17
|
+
};
|
|
18
18
|
/**
|
|
19
19
|
* Truncates text with the ellipsis in the middle,
|
|
20
20
|
* leaving defined number of chars at the end.
|
|
@@ -31,7 +31,5 @@ export type MiddleTextTruncationProps = {
|
|
|
31
31
|
* )}
|
|
32
32
|
* />
|
|
33
33
|
*/
|
|
34
|
-
export declare const MiddleTextTruncation:
|
|
35
|
-
|
|
36
|
-
displayName: string;
|
|
37
|
-
};
|
|
34
|
+
export declare const MiddleTextTruncation: PolymorphicForwardRefComponent<"span", MiddleTextTruncationProps>;
|
|
35
|
+
export {};
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { OverflowContainer } from './OverflowContainer.js';
|
|
3
|
+
import { VisuallyHidden } from '../../core/VisuallyHidden/VisuallyHidden.js';
|
|
4
|
+
import { ShadowRoot } from './ShadowRoot.js';
|
|
3
5
|
let ELLIPSIS_CHAR = '…';
|
|
4
|
-
export const MiddleTextTruncation = (props) => {
|
|
5
|
-
let { text, style, ...rest } = props;
|
|
6
|
+
export const MiddleTextTruncation = React.forwardRef((props, forwardedRef) => {
|
|
7
|
+
let { text, endCharsCount, textRenderer, style, ...rest } = props;
|
|
6
8
|
return React.createElement(
|
|
7
9
|
OverflowContainer,
|
|
8
10
|
{
|
|
@@ -16,10 +18,26 @@ export const MiddleTextTruncation = (props) => {
|
|
|
16
18
|
},
|
|
17
19
|
itemsCount: text.length,
|
|
18
20
|
...rest,
|
|
21
|
+
ref: forwardedRef,
|
|
19
22
|
},
|
|
20
|
-
React.createElement(
|
|
23
|
+
React.createElement(
|
|
24
|
+
ShadowRoot,
|
|
25
|
+
null,
|
|
26
|
+
React.createElement(VisuallyHidden, null, text),
|
|
27
|
+
React.createElement('slot', {
|
|
28
|
+
'aria-hidden': true,
|
|
29
|
+
style: {
|
|
30
|
+
pointerEvents: 'none',
|
|
31
|
+
},
|
|
32
|
+
}),
|
|
33
|
+
),
|
|
34
|
+
React.createElement(MiddleTextTruncationContent, {
|
|
35
|
+
text: text,
|
|
36
|
+
endCharsCount: endCharsCount,
|
|
37
|
+
textRenderer: textRenderer,
|
|
38
|
+
}),
|
|
21
39
|
);
|
|
22
|
-
};
|
|
40
|
+
});
|
|
23
41
|
let MiddleTextTruncationContent = (props) => {
|
|
24
42
|
let { text, endCharsCount = 6, textRenderer } = props;
|
|
25
43
|
let { visibleCount } = OverflowContainer.useContext();
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { useMergedRefs } from '../hooks/useMergedRefs.js';
|
|
3
3
|
import { Box } from './Box.js';
|
|
4
|
-
import {
|
|
4
|
+
import { useLayoutEffect } from '../hooks/useIsomorphicLayoutEffect.js';
|
|
5
5
|
import { useSafeContext } from '../hooks/useSafeContext.js';
|
|
6
|
-
|
|
6
|
+
import { isUnitTest } from '../functions/dev.js';
|
|
7
|
+
import { useResizeObserver } from '../hooks/useResizeObserver.js';
|
|
8
|
+
let OverflowContainerMain = React.forwardRef((props, forwardedRef) => {
|
|
7
9
|
let { itemsCount, children, overflowOrientation, ...rest } = props;
|
|
8
10
|
let [containerRef, visibleCount] = useOverflow(
|
|
9
11
|
itemsCount,
|
|
10
|
-
false,
|
|
11
12
|
overflowOrientation,
|
|
12
13
|
);
|
|
13
14
|
let overflowContainerContextValue = React.useMemo(
|
|
@@ -25,7 +26,7 @@ let OverflowContainerComponent = React.forwardRef((props, ref) => {
|
|
|
25
26
|
React.createElement(
|
|
26
27
|
Box,
|
|
27
28
|
{
|
|
28
|
-
ref: useMergedRefs(
|
|
29
|
+
ref: useMergedRefs(forwardedRef, containerRef),
|
|
29
30
|
...rest,
|
|
30
31
|
},
|
|
31
32
|
children,
|
|
@@ -38,11 +39,149 @@ let OverflowContainerOverflowNode = (props) => {
|
|
|
38
39
|
let isOverflowing = visibleCount < itemsCount;
|
|
39
40
|
return isOverflowing ? children : null;
|
|
40
41
|
};
|
|
42
|
+
let OverflowContainerComponent = React.forwardRef((props, forwardedRef) => {
|
|
43
|
+
let { itemsCount, overflowOrientation = 'horizontal', ...rest } = props;
|
|
44
|
+
let [size, setSize] = React.useState(null);
|
|
45
|
+
let [resizeRef] = useResizeObserver(setSize);
|
|
46
|
+
let ref = useMergedRefs(resizeRef, forwardedRef);
|
|
47
|
+
let key = `${itemsCount}${
|
|
48
|
+
'vertical' === overflowOrientation ? size?.height : size?.width
|
|
49
|
+
}`;
|
|
50
|
+
return React.createElement(OverflowContainerMain, {
|
|
51
|
+
...rest,
|
|
52
|
+
key: key,
|
|
53
|
+
ref: ref,
|
|
54
|
+
itemsCount: itemsCount,
|
|
55
|
+
overflowOrientation: overflowOrientation,
|
|
56
|
+
});
|
|
57
|
+
});
|
|
41
58
|
export const OverflowContainer = Object.assign(OverflowContainerComponent, {
|
|
42
59
|
OverflowNode: OverflowContainerOverflowNode,
|
|
43
60
|
useContext: useOverflowContainerContext,
|
|
44
61
|
});
|
|
45
62
|
let OverflowContainerContext = React.createContext(void 0);
|
|
63
|
+
let useOverflow = (itemsCount, orientation = 'horizontal') => {
|
|
64
|
+
let [guessState, dispatch] = React.useReducer(
|
|
65
|
+
overflowGuessReducer,
|
|
66
|
+
{
|
|
67
|
+
itemsCount,
|
|
68
|
+
},
|
|
69
|
+
overflowGuessReducerInitialState,
|
|
70
|
+
);
|
|
71
|
+
let containerRef = React.useRef(null);
|
|
72
|
+
let isGuessing = React.useRef(false);
|
|
73
|
+
useLayoutEffect(() => {
|
|
74
|
+
let { minGuess, maxGuess, isStabilized, visibleCount } = guessState;
|
|
75
|
+
if (isStabilized) return;
|
|
76
|
+
guessVisibleCount();
|
|
77
|
+
function guessVisibleCount() {
|
|
78
|
+
if (isStabilized || isGuessing.current || isUnitTest) return;
|
|
79
|
+
try {
|
|
80
|
+
isGuessing.current = true;
|
|
81
|
+
if (null == containerRef.current) return;
|
|
82
|
+
let dimension = 'horizontal' === orientation ? 'Width' : 'Height';
|
|
83
|
+
let availableSize = containerRef.current[`offset${dimension}`];
|
|
84
|
+
let requiredSize = containerRef.current[`scroll${dimension}`];
|
|
85
|
+
let isOverflowing = availableSize < requiredSize;
|
|
86
|
+
if (
|
|
87
|
+
0 === itemsCount ||
|
|
88
|
+
(1 === visibleCount && isOverflowing) ||
|
|
89
|
+
(visibleCount === itemsCount && !isOverflowing) ||
|
|
90
|
+
(maxGuess - minGuess === 1 && visibleCount === minGuess)
|
|
91
|
+
) {
|
|
92
|
+
dispatch({
|
|
93
|
+
type: 'stabilize',
|
|
94
|
+
});
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
if (maxGuess === visibleCount && !isOverflowing) {
|
|
98
|
+
dispatch({
|
|
99
|
+
type: 'shiftGuessRangeForward',
|
|
100
|
+
});
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
isOverflowing
|
|
104
|
+
? dispatch({
|
|
105
|
+
type: 'decreaseMaxGuess',
|
|
106
|
+
currentState: guessState,
|
|
107
|
+
})
|
|
108
|
+
: dispatch({
|
|
109
|
+
type: 'increaseMinGuess',
|
|
110
|
+
currentState: guessState,
|
|
111
|
+
});
|
|
112
|
+
} finally {
|
|
113
|
+
isGuessing.current = false;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}, [guessState, itemsCount, orientation]);
|
|
117
|
+
return [containerRef, guessState.visibleCount];
|
|
118
|
+
};
|
|
119
|
+
let STARTING_MAX_ITEMS_COUNT = 32;
|
|
120
|
+
let overflowGuessReducerInitialState = ({ itemsCount }) => {
|
|
121
|
+
let initialVisibleCount = Math.min(itemsCount, STARTING_MAX_ITEMS_COUNT);
|
|
122
|
+
return isUnitTest
|
|
123
|
+
? {
|
|
124
|
+
isStabilized: true,
|
|
125
|
+
minGuess: null,
|
|
126
|
+
maxGuess: null,
|
|
127
|
+
itemsCount,
|
|
128
|
+
visibleCount: itemsCount,
|
|
129
|
+
}
|
|
130
|
+
: {
|
|
131
|
+
isStabilized: false,
|
|
132
|
+
minGuess: 0,
|
|
133
|
+
maxGuess: initialVisibleCount,
|
|
134
|
+
itemsCount,
|
|
135
|
+
visibleCount: initialVisibleCount,
|
|
136
|
+
};
|
|
137
|
+
};
|
|
138
|
+
let overflowGuessReducer = (state, action) => {
|
|
139
|
+
let getSafeVisibleCount = ({ visibleCount, itemsCount }) =>
|
|
140
|
+
Math.min(itemsCount, visibleCount);
|
|
141
|
+
switch (action.type) {
|
|
142
|
+
case 'decreaseMaxGuess':
|
|
143
|
+
case 'increaseMinGuess':
|
|
144
|
+
if (state.isStabilized) return state;
|
|
145
|
+
let newMinGuess = state.minGuess;
|
|
146
|
+
let newMaxGuess = state.maxGuess;
|
|
147
|
+
if ('decreaseMaxGuess' === action.type)
|
|
148
|
+
newMaxGuess = action.currentState.visibleCount;
|
|
149
|
+
else newMinGuess = action.currentState.visibleCount;
|
|
150
|
+
let newVisibleCount = Math.floor((newMinGuess + newMaxGuess) / 2);
|
|
151
|
+
return {
|
|
152
|
+
...state,
|
|
153
|
+
isStabilized: false,
|
|
154
|
+
minGuess: newMinGuess,
|
|
155
|
+
maxGuess: newMaxGuess,
|
|
156
|
+
visibleCount: getSafeVisibleCount({
|
|
157
|
+
visibleCount: newVisibleCount,
|
|
158
|
+
itemsCount: state.itemsCount,
|
|
159
|
+
}),
|
|
160
|
+
};
|
|
161
|
+
case 'shiftGuessRangeForward':
|
|
162
|
+
if (state.isStabilized) return state;
|
|
163
|
+
let doubleOfMaxGuess = 2 * state.maxGuess;
|
|
164
|
+
return {
|
|
165
|
+
...state,
|
|
166
|
+
isStabilized: false,
|
|
167
|
+
minGuess: state.maxGuess,
|
|
168
|
+
maxGuess: doubleOfMaxGuess,
|
|
169
|
+
visibleCount: getSafeVisibleCount({
|
|
170
|
+
visibleCount: doubleOfMaxGuess,
|
|
171
|
+
itemsCount: state.itemsCount,
|
|
172
|
+
}),
|
|
173
|
+
};
|
|
174
|
+
case 'stabilize':
|
|
175
|
+
return {
|
|
176
|
+
...state,
|
|
177
|
+
isStabilized: true,
|
|
178
|
+
minGuess: null,
|
|
179
|
+
maxGuess: null,
|
|
180
|
+
};
|
|
181
|
+
default:
|
|
182
|
+
return state;
|
|
183
|
+
}
|
|
184
|
+
};
|
|
46
185
|
function useOverflowContainerContext() {
|
|
47
186
|
let overflowContainerContext = useSafeContext(OverflowContainerContext);
|
|
48
187
|
return overflowContainerContext;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export * from './useEventListener.js';
|
|
2
2
|
export * from './useMergedRefs.js';
|
|
3
|
-
export * from './useOverflow.js';
|
|
4
3
|
export * from './useResizeObserver.js';
|
|
5
4
|
export * from './useContainerWidth.js';
|
|
6
5
|
export * from './useGlobals.js';
|
|
@@ -14,4 +13,5 @@ export * from './useId.js';
|
|
|
14
13
|
export * from './useControlledState.js';
|
|
15
14
|
export * from './useSyncExternalStore.js';
|
|
16
15
|
export * from './useVirtualScroll.js';
|
|
16
|
+
export * from './useInstance.js';
|
|
17
17
|
export * from './useWarningLogger.js';
|
package/esm/utils/hooks/index.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export * from './useEventListener.js';
|
|
2
2
|
export * from './useMergedRefs.js';
|
|
3
|
-
export * from './useOverflow.js';
|
|
4
3
|
export * from './useResizeObserver.js';
|
|
5
4
|
export * from './useContainerWidth.js';
|
|
6
5
|
export * from './useGlobals.js';
|
|
@@ -14,4 +13,5 @@ export * from './useId.js';
|
|
|
14
13
|
export * from './useControlledState.js';
|
|
15
14
|
export * from './useSyncExternalStore.js';
|
|
16
15
|
export * from './useVirtualScroll.js';
|
|
16
|
+
export * from './useInstance.js';
|
|
17
17
|
export * from './useWarningLogger.js';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
declare class Instance {
|
|
2
|
+
}
|
|
3
|
+
export declare const useInstance: () => Instance;
|
|
4
|
+
/**
|
|
5
|
+
* Synchronizes the instance with the provided properties.
|
|
6
|
+
*
|
|
7
|
+
* @param instance Instance created by `useInstance`.
|
|
8
|
+
* @param properties Memoized object containing properties to be synchronized.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* const instance = useInstance();
|
|
12
|
+
*
|
|
13
|
+
* const properties = React.useMemo(() => ({
|
|
14
|
+
* show: () => console.log('show'),
|
|
15
|
+
* }), []);
|
|
16
|
+
*
|
|
17
|
+
* useSynchronizeInstance(instance, properties);
|
|
18
|
+
*
|
|
19
|
+
* instance.show(); // logs 'show'
|
|
20
|
+
*/
|
|
21
|
+
export declare const useSynchronizeInstance: <T>(instance: T, properties: T) => T;
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useSyncExternalStore } from './useSyncExternalStore.js';
|
|
3
|
+
class Instance {}
|
|
4
|
+
export const useInstance = () => React.useMemo(() => new Instance(), []);
|
|
5
|
+
export const useSynchronizeInstance = (instance, properties) => {
|
|
6
|
+
let synchronize = React.useCallback(() => {
|
|
7
|
+
if (!(instance instanceof Instance)) return () => {};
|
|
8
|
+
Object.assign(instance, properties);
|
|
9
|
+
return () => {
|
|
10
|
+
for (let key in properties) delete instance[key];
|
|
11
|
+
};
|
|
12
|
+
}, [instance, properties]);
|
|
13
|
+
return useSyncExternalStore(
|
|
14
|
+
synchronize,
|
|
15
|
+
() => instance,
|
|
16
|
+
() => instance,
|
|
17
|
+
);
|
|
18
|
+
};
|