@itwin/itwinui-react 3.15.2 → 3.15.4
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 +19 -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/ProgressIndicators/ProgressLinear.js +2 -1
- 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 +17 -10
- 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/core/TransferList/TransferList.js +18 -6
- 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/ProgressIndicators/ProgressLinear.js +2 -1
- 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 +18 -11
- 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/core/TransferList/TransferList.js +14 -2
- 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/Popover/Popover.d.ts +10 -0
- package/cjs/core/Popover/Popover.js +44 -16
- package/cjs/core/ProgressIndicators/ProgressLinear.js +2 -1
- 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 +13 -10
- 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/core/TransferList/TransferList.d.ts +1 -1
- package/cjs/core/TransferList/TransferList.js +18 -6
- 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/Popover/Popover.d.ts +10 -0
- package/esm/core/Popover/Popover.js +45 -17
- package/esm/core/ProgressIndicators/ProgressLinear.js +2 -1
- 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 +14 -11
- 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/core/TransferList/TransferList.d.ts +1 -1
- package/esm/core/TransferList/TransferList.js +14 -2
- 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
package/esm/core/Table/Table.js
CHANGED
|
@@ -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 {
|
|
@@ -299,7 +299,6 @@ export const Table = (props) => {
|
|
|
299
299
|
gotoPage,
|
|
300
300
|
setPageSize,
|
|
301
301
|
flatHeaders,
|
|
302
|
-
visibleColumns,
|
|
303
302
|
setGlobalFilter,
|
|
304
303
|
} = instance;
|
|
305
304
|
let headerGroups = _headerGroups;
|
|
@@ -543,9 +542,9 @@ export const Table = (props) => {
|
|
|
543
542
|
updateStickyState();
|
|
544
543
|
}, []);
|
|
545
544
|
return React.createElement(
|
|
546
|
-
|
|
545
|
+
TableInstanceContext.Provider,
|
|
547
546
|
{
|
|
548
|
-
value: instance
|
|
547
|
+
value: instance,
|
|
549
548
|
},
|
|
550
549
|
React.createElement(
|
|
551
550
|
Box,
|
|
@@ -604,19 +603,23 @@ export const Table = (props) => {
|
|
|
604
603
|
return React.createElement(ColumnHeader, {
|
|
605
604
|
...dragAndDropProps,
|
|
606
605
|
key: dragAndDropProps.key || column.id || index,
|
|
607
|
-
columnRefs: columnRefs,
|
|
608
606
|
column: column,
|
|
609
|
-
index: index,
|
|
610
607
|
areFiltersSet: areFiltersSet,
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
608
|
+
columnHasExpanders:
|
|
609
|
+
hasAnySubRows &&
|
|
610
|
+
index ===
|
|
611
|
+
headerGroup.headers.findIndex(
|
|
612
|
+
(c) => c.id !== SELECTION_CELL_ID,
|
|
613
|
+
),
|
|
614
|
+
isLast: index === headerGroup.headers.length - 1,
|
|
615
|
+
isTableEmpty: 0 === data.length,
|
|
615
616
|
isResizable: isResizable,
|
|
616
617
|
columnResizeMode: columnResizeMode,
|
|
617
618
|
enableColumnReordering: enableColumnReordering,
|
|
618
619
|
density: density,
|
|
619
|
-
|
|
620
|
+
ref: (el) => {
|
|
621
|
+
if (el) columnRefs.current[column.id] = el;
|
|
622
|
+
},
|
|
620
623
|
});
|
|
621
624
|
}),
|
|
622
625
|
),
|
|
@@ -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: {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import type { ColumnInstance } from '../../react-table/react-table.js';
|
|
2
|
+
import type { ColumnInstance, TableInstance } from '../../react-table/react-table.js';
|
|
3
3
|
export declare const getCellStyle: <T extends Record<string, unknown>>(column: ColumnInstance<T>, isTableResizing: boolean) => React.CSSProperties | undefined;
|
|
4
4
|
export declare const getStickyStyle: <T extends Record<string, unknown>>(column: ColumnInstance<T>, columnList: ColumnInstance<T>[]) => React.CSSProperties;
|
|
5
5
|
export declare const getSubRowStyle: ({ density, depth }: {
|
|
@@ -8,4 +8,4 @@ export declare const getSubRowStyle: ({ density, depth }: {
|
|
|
8
8
|
}) => {
|
|
9
9
|
paddingInlineStart: number;
|
|
10
10
|
};
|
|
11
|
-
export declare const
|
|
11
|
+
export declare const TableInstanceContext: React.Context<TableInstance<Record<string, unknown>> | undefined>;
|
package/esm/core/Table/utils.js
CHANGED
|
@@ -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);
|
|
@@ -54,7 +54,7 @@ export declare const TransferList: PolymorphicForwardRefComponent<"div", {}> & {
|
|
|
54
54
|
/**
|
|
55
55
|
* TransferList toolbar subcomponent
|
|
56
56
|
*/
|
|
57
|
-
Toolbar: PolymorphicForwardRefComponent<"div",
|
|
57
|
+
Toolbar: PolymorphicForwardRefComponent<"div", object>;
|
|
58
58
|
};
|
|
59
59
|
export declare const TransferListContext: React.Context<{
|
|
60
60
|
/**
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
import { List } from '../List/List.js';
|
|
12
12
|
import { ListItem } from '../List/ListItem.js';
|
|
13
13
|
import { Label } from '../Label/Label.js';
|
|
14
|
+
import { ButtonGroup } from '../ButtonGroup/ButtonGroup.js';
|
|
14
15
|
let TransferListComponent = polymorphic.div('iui-transfer-list-wrapper');
|
|
15
16
|
let TransferListListboxWrapper = React.forwardRef((props, ref) => {
|
|
16
17
|
let { className, children, ...rest } = props;
|
|
@@ -147,8 +148,19 @@ let TransferListListboxLabel = React.forwardRef((props, ref) => {
|
|
|
147
148
|
children,
|
|
148
149
|
);
|
|
149
150
|
});
|
|
150
|
-
let TransferListToolbar =
|
|
151
|
-
|
|
151
|
+
let TransferListToolbar = React.forwardRef((props, ref) => {
|
|
152
|
+
let { className, children, ...rest } = props;
|
|
153
|
+
return React.createElement(
|
|
154
|
+
ButtonGroup,
|
|
155
|
+
{
|
|
156
|
+
role: 'toolbar',
|
|
157
|
+
ref: ref,
|
|
158
|
+
...rest,
|
|
159
|
+
orientation: 'vertical',
|
|
160
|
+
className: cx('iui-transfer-list-toolbar', className),
|
|
161
|
+
},
|
|
162
|
+
children,
|
|
163
|
+
);
|
|
152
164
|
});
|
|
153
165
|
export const TransferList = Object.assign(TransferListComponent, {
|
|
154
166
|
ListboxWrapper: TransferListListboxWrapper,
|
package/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,9 +14,22 @@ 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
|
};
|
|
23
|
+
let MiddleTextTruncationContent = (props) => {
|
|
24
|
+
let { text, endCharsCount = 6, textRenderer } = props;
|
|
25
|
+
let { visibleCount } = OverflowContainer.useContext();
|
|
26
|
+
let truncatedText = React.useMemo(() => {
|
|
27
|
+
if (visibleCount < text.length)
|
|
28
|
+
return `${text.substring(
|
|
29
|
+
0,
|
|
30
|
+
visibleCount - endCharsCount - ELLIPSIS_CHAR.length,
|
|
31
|
+
)}${ELLIPSIS_CHAR}${text.substring(text.length - endCharsCount)}`;
|
|
32
|
+
return text;
|
|
33
|
+
}, [endCharsCount, text, visibleCount]);
|
|
34
|
+
return textRenderer?.(truncatedText, text) ?? truncatedText;
|
|
35
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { PolymorphicForwardRefComponent } from '../props.js';
|
|
3
|
+
type OverflowContainerProps = {
|
|
4
|
+
/**
|
|
5
|
+
* The orientation of the overflow in container.
|
|
6
|
+
* @default 'horizontal'
|
|
7
|
+
*/
|
|
8
|
+
overflowOrientation?: 'horizontal' | 'vertical';
|
|
9
|
+
/**
|
|
10
|
+
* Count of the *original* items (i.e. when sufficient space is available).
|
|
11
|
+
*/
|
|
12
|
+
itemsCount: number;
|
|
13
|
+
};
|
|
14
|
+
type OverflowContainerOverflowNodeProps = {
|
|
15
|
+
children: React.ReactNode;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Wrapper over `useOverflow`.
|
|
19
|
+
*
|
|
20
|
+
* - Use `OverflowContainer.useContext()` to get overflow related properties.
|
|
21
|
+
* - Wrap overflow content in `OverflowContainer.OverflowNode` to conditionally render it when overflowing.
|
|
22
|
+
*/
|
|
23
|
+
export declare const OverflowContainer: PolymorphicForwardRefComponent<"div", OverflowContainerProps> & {
|
|
24
|
+
/**
|
|
25
|
+
* Wrap overflow content in this component to conditionally render it when overflowing.
|
|
26
|
+
*/
|
|
27
|
+
OverflowNode: (props: OverflowContainerOverflowNodeProps) => React.ReactNode;
|
|
28
|
+
/**
|
|
29
|
+
* Get overflow related properties of the nearest `OverflowContainer` ancestor.
|
|
30
|
+
*/
|
|
31
|
+
useContext: typeof useOverflowContainerContext;
|
|
32
|
+
};
|
|
33
|
+
declare function useOverflowContainerContext(): {
|
|
34
|
+
visibleCount: number;
|
|
35
|
+
itemsCount: number;
|
|
36
|
+
};
|
|
37
|
+
export {};
|
|
@@ -0,0 +1,49 @@
|
|
|
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
|
+
function useOverflowContainerContext() {
|
|
47
|
+
let overflowContainerContext = useSafeContext(OverflowContainerContext);
|
|
48
|
+
return overflowContainerContext;
|
|
49
|
+
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
1
|
/**
|
|
3
2
|
* Hook that observes the size of an element and returns the number of items
|
|
4
3
|
* that should be visible based on the size of the container element.
|
|
@@ -6,7 +5,7 @@ import * as React from 'react';
|
|
|
6
5
|
* The returned number should be used to render the element with fewer items.
|
|
7
6
|
*
|
|
8
7
|
* @private
|
|
9
|
-
* @param items
|
|
8
|
+
* @param itemsCount Number of items that this element contains.
|
|
10
9
|
* @param disabled Set to true to disconnect the observer.
|
|
11
10
|
* @param dimension 'horizontal' (default) or 'vertical'
|
|
12
11
|
* @returns [callback ref to set on container, stateful count of visible items]
|
|
@@ -21,4 +20,4 @@ import * as React from 'react';
|
|
|
21
20
|
* </div>
|
|
22
21
|
* );
|
|
23
22
|
*/
|
|
24
|
-
export declare const useOverflow: <T extends HTMLElement>(
|
|
23
|
+
export declare const useOverflow: <T extends HTMLElement>(itemsCount: number, disabled?: boolean, orientation?: "horizontal" | "vertical") => readonly [(instance: T | null | undefined) => void, number];
|
|
@@ -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]);
|