@itwin/itwinui-react 1.38.1 → 1.40.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/cjs/core/Carousel/Carousel.js +21 -12
  3. package/cjs/core/Carousel/CarouselContext.d.ts +4 -2
  4. package/cjs/core/Carousel/CarouselDotsList.js +1 -0
  5. package/cjs/core/Carousel/CarouselNavigation.js +8 -10
  6. package/cjs/core/Carousel/CarouselSlide.js +3 -7
  7. package/cjs/core/Carousel/CarouselSlider.js +23 -28
  8. package/cjs/core/ColorPicker/ColorPickerContext.d.ts +2 -2
  9. package/cjs/core/ComboBox/ComboBox.d.ts +10 -1
  10. package/cjs/core/ComboBox/ComboBox.js +39 -20
  11. package/cjs/core/ComboBox/ComboBoxDropdown.d.ts +5 -6
  12. package/cjs/core/ComboBox/ComboBoxInput.js +28 -9
  13. package/cjs/core/ComboBox/ComboBoxMenu.js +10 -2
  14. package/cjs/core/ComboBox/helpers.d.ts +1 -1
  15. package/cjs/core/ComboBox/helpers.js +1 -1
  16. package/cjs/core/DatePicker/DatePicker.d.ts +1 -1
  17. package/cjs/core/Menu/MenuItemSkeleton.d.ts +32 -0
  18. package/cjs/core/Menu/MenuItemSkeleton.js +53 -0
  19. package/cjs/core/Menu/index.d.ts +2 -0
  20. package/cjs/core/Menu/index.js +3 -1
  21. package/cjs/core/Table/Table.js +68 -25
  22. package/cjs/core/Table/TableCell.js +10 -3
  23. package/cjs/core/Table/TablePaginator.js +1 -1
  24. package/cjs/core/Table/TableRowMemoized.js +5 -1
  25. package/cjs/core/Table/actionHandlers/resizeHandler.d.ts +8 -0
  26. package/cjs/core/Table/actionHandlers/selectHandler.d.ts +4 -0
  27. package/cjs/core/Table/columns/selectionColumn.js +4 -2
  28. package/cjs/core/Table/filters/tableFilters.d.ts +3 -3
  29. package/cjs/core/Table/hooks/index.d.ts +1 -0
  30. package/cjs/core/Table/hooks/index.js +3 -1
  31. package/cjs/core/Table/hooks/useExpanderCell.js +11 -1
  32. package/cjs/core/Table/hooks/useStickyColumns.d.ts +2 -0
  33. package/cjs/core/Table/hooks/useStickyColumns.js +84 -0
  34. package/cjs/core/Table/utils.d.ts +1 -0
  35. package/cjs/core/Table/utils.js +36 -1
  36. package/cjs/core/Toast/Toaster.js +97 -18
  37. package/cjs/core/index.d.ts +2 -2
  38. package/cjs/core/index.js +4 -3
  39. package/cjs/core/utils/components/Popover.d.ts +1 -18
  40. package/cjs/core/utils/components/VirtualScroll.js +2 -2
  41. package/cjs/core/utils/components/VisuallyHidden.d.ts +9 -0
  42. package/cjs/core/utils/components/VisuallyHidden.js +44 -0
  43. package/cjs/core/utils/components/WithCSSTransition.d.ts +1 -2
  44. package/cjs/core/utils/components/icons.d.ts +4 -4
  45. package/cjs/core/utils/components/index.d.ts +1 -0
  46. package/cjs/core/utils/components/index.js +1 -0
  47. package/cjs/core/utils/hooks/useOverflow.js +4 -2
  48. package/cjs/core/utils/hooks/useTheme.d.ts +1 -1
  49. package/cjs/types/react-table-config.d.ts +9 -0
  50. package/esm/core/Carousel/Carousel.js +21 -12
  51. package/esm/core/Carousel/CarouselContext.d.ts +4 -2
  52. package/esm/core/Carousel/CarouselDotsList.js +1 -0
  53. package/esm/core/Carousel/CarouselNavigation.js +8 -10
  54. package/esm/core/Carousel/CarouselSlide.js +3 -7
  55. package/esm/core/Carousel/CarouselSlider.js +24 -29
  56. package/esm/core/ColorPicker/ColorPickerContext.d.ts +2 -2
  57. package/esm/core/ComboBox/ComboBox.d.ts +10 -1
  58. package/esm/core/ComboBox/ComboBox.js +39 -20
  59. package/esm/core/ComboBox/ComboBoxDropdown.d.ts +5 -6
  60. package/esm/core/ComboBox/ComboBoxInput.js +28 -9
  61. package/esm/core/ComboBox/ComboBoxMenu.js +10 -2
  62. package/esm/core/ComboBox/helpers.d.ts +1 -1
  63. package/esm/core/ComboBox/helpers.js +1 -1
  64. package/esm/core/DatePicker/DatePicker.d.ts +1 -1
  65. package/esm/core/Menu/MenuItemSkeleton.d.ts +32 -0
  66. package/esm/core/Menu/MenuItemSkeleton.js +46 -0
  67. package/esm/core/Menu/index.d.ts +2 -0
  68. package/esm/core/Menu/index.js +1 -0
  69. package/esm/core/Table/Table.js +70 -27
  70. package/esm/core/Table/TableCell.js +11 -4
  71. package/esm/core/Table/TablePaginator.js +1 -1
  72. package/esm/core/Table/TableRowMemoized.js +5 -1
  73. package/esm/core/Table/actionHandlers/resizeHandler.d.ts +8 -0
  74. package/esm/core/Table/actionHandlers/selectHandler.d.ts +4 -0
  75. package/esm/core/Table/columns/selectionColumn.js +4 -2
  76. package/esm/core/Table/filters/tableFilters.d.ts +3 -3
  77. package/esm/core/Table/hooks/index.d.ts +1 -0
  78. package/esm/core/Table/hooks/index.js +1 -0
  79. package/esm/core/Table/hooks/useExpanderCell.js +8 -1
  80. package/esm/core/Table/hooks/useStickyColumns.d.ts +2 -0
  81. package/esm/core/Table/hooks/useStickyColumns.js +80 -0
  82. package/esm/core/Table/utils.d.ts +1 -0
  83. package/esm/core/Table/utils.js +34 -0
  84. package/esm/core/Toast/Toaster.js +75 -19
  85. package/esm/core/index.d.ts +2 -2
  86. package/esm/core/index.js +1 -1
  87. package/esm/core/utils/components/Popover.d.ts +1 -18
  88. package/esm/core/utils/components/VirtualScroll.js +2 -2
  89. package/esm/core/utils/components/VisuallyHidden.d.ts +9 -0
  90. package/esm/core/utils/components/VisuallyHidden.js +38 -0
  91. package/esm/core/utils/components/WithCSSTransition.d.ts +1 -2
  92. package/esm/core/utils/components/icons.d.ts +4 -4
  93. package/esm/core/utils/components/index.d.ts +1 -0
  94. package/esm/core/utils/components/index.js +1 -0
  95. package/esm/core/utils/hooks/useOverflow.js +4 -2
  96. package/esm/core/utils/hooks/useTheme.d.ts +1 -1
  97. package/esm/types/react-table-config.d.ts +9 -0
  98. package/package.json +24 -39
@@ -0,0 +1,32 @@
1
+ /// <reference types="react" />
2
+ import { CommonProps } from '../utils';
3
+ import '@itwin/itwinui-css/css/menu.css';
4
+ export declare type MenuItemSkeletonProps = {
5
+ /**
6
+ * Flag whether to show skeleton for sub-label.
7
+ */
8
+ hasSublabel?: boolean;
9
+ /**
10
+ * Flag whether to show skeleton for icon.
11
+ */
12
+ hasIcon?: boolean;
13
+ /**
14
+ * Skeleton content width.
15
+ */
16
+ contentWidth?: string;
17
+ /**
18
+ * Translated strings used for accessibility.
19
+ */
20
+ translatedStrings?: {
21
+ /**
22
+ * Label for loading state. Defaults to "Loading…".
23
+ * It is only visible for the screen readers.
24
+ */
25
+ loading: string;
26
+ };
27
+ } & CommonProps;
28
+ /**
29
+ * Menu item that uses skeletons to indicate loading state.
30
+ */
31
+ export declare const MenuItemSkeleton: (props: MenuItemSkeletonProps) => JSX.Element;
32
+ export default MenuItemSkeleton;
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __rest = (this && this.__rest) || function (s, e) {
14
+ var t = {};
15
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
16
+ t[p] = s[p];
17
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
18
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
19
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
20
+ t[p[i]] = s[p[i]];
21
+ }
22
+ return t;
23
+ };
24
+ var __importDefault = (this && this.__importDefault) || function (mod) {
25
+ return (mod && mod.__esModule) ? mod : { "default": mod };
26
+ };
27
+ Object.defineProperty(exports, "__esModule", { value: true });
28
+ exports.MenuItemSkeleton = void 0;
29
+ /*---------------------------------------------------------------------------------------------
30
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
31
+ * See LICENSE.md in the project root for license terms and full copyright notice.
32
+ *--------------------------------------------------------------------------------------------*/
33
+ var react_1 = __importDefault(require("react"));
34
+ var classnames_1 = __importDefault(require("classnames"));
35
+ var utils_1 = require("../utils");
36
+ require("@itwin/itwinui-css/css/menu.css");
37
+ /**
38
+ * Menu item that uses skeletons to indicate loading state.
39
+ */
40
+ var MenuItemSkeleton = function (props) {
41
+ var hasSublabel = props.hasSublabel, hasIcon = props.hasIcon, contentWidth = props.contentWidth, _a = props.translatedStrings, translatedStrings = _a === void 0 ? { loading: 'Loading…' } : _a, className = props.className, style = props.style, rest = __rest(props, ["hasSublabel", "hasIcon", "contentWidth", "translatedStrings", "className", "style"]);
42
+ (0, utils_1.useTheme)();
43
+ return (react_1.default.createElement("li", __assign({ className: (0, classnames_1.default)('iui-menu-item', 'iui-menu-item-skeleton', { 'iui-large': hasSublabel }, className), style: __assign({
44
+ '--iui-menu-item-content-skeleton-max-width': contentWidth,
45
+ }, style) }, rest),
46
+ hasIcon && react_1.default.createElement("div", { className: 'iui-icon iui-skeleton', "aria-hidden": true }),
47
+ react_1.default.createElement("span", { className: 'iui-content' },
48
+ react_1.default.createElement("div", { className: 'iui-menu-label iui-skeleton', "aria-hidden": true }),
49
+ hasSublabel && (react_1.default.createElement("div", { className: 'iui-menu-description iui-skeleton', "aria-hidden": true })),
50
+ react_1.default.createElement(utils_1.VisuallyHidden, null, translatedStrings.loading))));
51
+ };
52
+ exports.MenuItemSkeleton = MenuItemSkeleton;
53
+ exports.default = exports.MenuItemSkeleton;
@@ -6,3 +6,5 @@ export { MenuDivider } from './MenuDivider';
6
6
  export type { MenuDividerProps } from './MenuDivider';
7
7
  export { MenuExtraContent } from './MenuExtraContent';
8
8
  export type { MenuExtraContentProps } from './MenuExtraContent';
9
+ export { MenuItemSkeleton } from './MenuItemSkeleton';
10
+ export type { MenuItemSkeletonProps } from './MenuItemSkeleton';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MenuExtraContent = exports.MenuDivider = exports.MenuItem = exports.Menu = void 0;
3
+ exports.MenuItemSkeleton = exports.MenuExtraContent = exports.MenuDivider = exports.MenuItem = exports.Menu = void 0;
4
4
  /*---------------------------------------------------------------------------------------------
5
5
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
6
6
  * See LICENSE.md in the project root for license terms and full copyright notice.
@@ -13,3 +13,5 @@ var MenuDivider_1 = require("./MenuDivider");
13
13
  Object.defineProperty(exports, "MenuDivider", { enumerable: true, get: function () { return MenuDivider_1.MenuDivider; } });
14
14
  var MenuExtraContent_1 = require("./MenuExtraContent");
15
15
  Object.defineProperty(exports, "MenuExtraContent", { enumerable: true, get: function () { return MenuExtraContent_1.MenuExtraContent; } });
16
+ var MenuItemSkeleton_1 = require("./MenuItemSkeleton");
17
+ Object.defineProperty(exports, "MenuItemSkeleton", { enumerable: true, get: function () { return MenuItemSkeleton_1.MenuItemSkeleton; } });
@@ -177,8 +177,8 @@ var Table = function (props) {
177
177
  return getSubRows ? getSubRows(item, index) : item.subRows;
178
178
  });
179
179
  }, [data, getSubRows]);
180
- var instance = (0, react_table_1.useTable)(__assign(__assign({ manualPagination: !paginatorRenderer, paginateExpandedRows: false }, props), { columns: columns, defaultColumn: defaultColumn, disableSortBy: !isSortable, stateReducer: tableStateReducer, filterTypes: filterTypes, selectSubRows: selectSubRows, data: data, getSubRows: getSubRows, initialState: __assign({ pageSize: pageSize }, props.initialState) }), react_table_1.useFlexLayout, (0, hooks_1.useResizeColumns)(ownerDocument), react_table_1.useFilters, (0, hooks_1.useSubRowFiltering)(hasAnySubRows), react_table_1.useSortBy, react_table_1.useExpanded, react_table_1.usePagination, react_table_1.useRowSelect, hooks_1.useSubRowSelection, (0, hooks_1.useExpanderCell)(subComponent, expanderCell, isRowDisabled), (0, hooks_1.useSelectionCell)(isSelectable, selectionMode, isRowDisabled), react_table_1.useColumnOrder, (0, hooks_1.useColumnDragAndDrop)(enableColumnReordering));
181
- var getTableProps = instance.getTableProps, rows = instance.rows, headerGroups = instance.headerGroups, getTableBodyProps = instance.getTableBodyProps, prepareRow = instance.prepareRow, state = instance.state, allColumns = instance.allColumns, filteredFlatRows = instance.filteredFlatRows, dispatch = instance.dispatch, page = instance.page, gotoPage = instance.gotoPage, setPageSize = instance.setPageSize, flatHeaders = instance.flatHeaders;
180
+ var instance = (0, react_table_1.useTable)(__assign(__assign({ manualPagination: !paginatorRenderer, paginateExpandedRows: false }, props), { columns: columns, defaultColumn: defaultColumn, disableSortBy: !isSortable, stateReducer: tableStateReducer, filterTypes: filterTypes, selectSubRows: selectSubRows, data: data, getSubRows: getSubRows, initialState: __assign({ pageSize: pageSize }, props.initialState) }), react_table_1.useFlexLayout, (0, hooks_1.useResizeColumns)(ownerDocument), react_table_1.useFilters, (0, hooks_1.useSubRowFiltering)(hasAnySubRows), react_table_1.useSortBy, react_table_1.useExpanded, react_table_1.usePagination, react_table_1.useRowSelect, hooks_1.useSubRowSelection, (0, hooks_1.useExpanderCell)(subComponent, expanderCell, isRowDisabled), (0, hooks_1.useSelectionCell)(isSelectable, selectionMode, isRowDisabled), react_table_1.useColumnOrder, (0, hooks_1.useColumnDragAndDrop)(enableColumnReordering), hooks_1.useStickyColumns);
181
+ var getTableProps = instance.getTableProps, rows = instance.rows, headerGroups = instance.headerGroups, getTableBodyProps = instance.getTableBodyProps, prepareRow = instance.prepareRow, state = instance.state, allColumns = instance.allColumns, filteredFlatRows = instance.filteredFlatRows, dispatch = instance.dispatch, page = instance.page, gotoPage = instance.gotoPage, setPageSize = instance.setPageSize, flatHeaders = instance.flatHeaders, visibleColumns = instance.visibleColumns;
182
182
  var ariaDataAttributes = Object.entries(rest).reduce(function (result, _a) {
183
183
  var key = _a[0], value = _a[1];
184
184
  if (key.startsWith('data-') || key.startsWith('aria-')) {
@@ -187,6 +187,12 @@ var Table = function (props) {
187
187
  return result;
188
188
  }, {});
189
189
  var areFiltersSet = allColumns.some(function (column) { return column.filterValue != null && column.filterValue !== ''; });
190
+ var showFilterButton = function (column) {
191
+ return (data.length !== 0 || areFiltersSet) && column.canFilter;
192
+ };
193
+ var showSortButton = function (column) {
194
+ return data.length !== 0 && column.canSort;
195
+ };
190
196
  var onRowClickHandler = react_1.default.useCallback(function (event, row) {
191
197
  var isDisabled = isRowDisabled === null || isRowDisabled === void 0 ? void 0 : isRowDisabled(row.original);
192
198
  if (!isDisabled) {
@@ -287,6 +293,30 @@ var Table = function (props) {
287
293
  subComponent,
288
294
  ]);
289
295
  var virtualizedItemRenderer = react_1.default.useCallback(function (index) { return getPreparedRow(index); }, [getPreparedRow]);
296
+ var updateStickyState = function () {
297
+ if (!bodyRef.current || flatHeaders.every(function (header) { return !header.sticky; })) {
298
+ return;
299
+ }
300
+ if (bodyRef.current.scrollLeft !== 0) {
301
+ dispatch({ type: react_table_1.actions.setScrolledRight, value: true });
302
+ }
303
+ else {
304
+ dispatch({ type: react_table_1.actions.setScrolledRight, value: false });
305
+ }
306
+ // If scrolled a bit to the left looking from the right side
307
+ if (bodyRef.current.scrollLeft !==
308
+ bodyRef.current.scrollWidth - bodyRef.current.clientWidth) {
309
+ dispatch({ type: react_table_1.actions.setScrolledLeft, value: true });
310
+ }
311
+ else {
312
+ dispatch({ type: react_table_1.actions.setScrolledLeft, value: false });
313
+ }
314
+ };
315
+ react_1.default.useEffect(function () {
316
+ updateStickyState();
317
+ // Call only on init
318
+ // eslint-disable-next-line react-hooks/exhaustive-deps
319
+ }, []);
290
320
  return (react_1.default.createElement(react_1.default.Fragment, null,
291
321
  react_1.default.createElement("div", __assign({ ref: function (element) {
292
322
  setOwnerDocument(element === null || element === void 0 ? void 0 : element.ownerDocument);
@@ -295,30 +325,42 @@ var Table = function (props) {
295
325
  }
296
326
  }, id: id }, getTableProps({
297
327
  className: (0, classnames_1.default)('iui-table', (_a = {}, _a["iui-".concat(density)] = density !== 'default', _a), className),
298
- style: style,
328
+ style: __assign({ minWidth: 0 }, style),
299
329
  }), ariaDataAttributes),
300
- react_1.default.createElement("div", { className: 'iui-table-header', ref: headerRef }, headerGroups.slice(1).map(function (headerGroup) {
301
- var headerGroupProps = headerGroup.getHeaderGroupProps({
302
- className: 'iui-row',
303
- });
304
- return (react_1.default.createElement("div", __assign({}, headerGroupProps, { key: headerGroupProps.key }), headerGroup.headers.map(function (column, index) {
305
- var columnProps = column.getHeaderProps(__assign(__assign({}, column.getSortByToggleProps()), { className: (0, classnames_1.default)('iui-cell', { 'iui-actionable': column.canSort }, { 'iui-sorted': column.isSorted }, column.columnClassName), style: __assign(__assign({}, (0, utils_2.getCellStyle)(column, !!state.isTableResizing)), { flexWrap: 'unset' }) }));
306
- return (react_1.default.createElement("div", __assign({}, columnProps, column.getDragAndDropProps(), { key: columnProps.key, title: undefined, ref: function (el) {
307
- if (el && isResizable) {
308
- columnRefs.current[column.id] = el;
309
- column.resizeWidth = el.getBoundingClientRect().width;
310
- }
311
- } }),
312
- column.render('Header'),
313
- (data.length !== 0 || areFiltersSet) && (react_1.default.createElement(filters_1.FilterToggle, { column: column, ownerDocument: ownerDocument })),
314
- data.length !== 0 && column.canSort && (react_1.default.createElement("div", { className: 'iui-cell-end-icon' }, column.isSorted && column.isSortedDesc ? (react_1.default.createElement(SortDown_1.default, { className: 'iui-icon iui-sort', "aria-hidden": true })) : (react_1.default.createElement(SortUp_1.default, { className: 'iui-icon iui-sort', "aria-hidden": true })))),
315
- isResizable &&
316
- column.isResizerVisible &&
317
- index !== headerGroup.headers.length - 1 && (react_1.default.createElement("div", __assign({}, column.getResizerProps(), { className: 'iui-resizer' }),
318
- react_1.default.createElement("div", { className: 'iui-resizer-bar' }))),
319
- enableColumnReordering && !column.disableReordering && (react_1.default.createElement("div", { className: 'iui-reorder-bar' }))));
320
- })));
321
- })),
330
+ react_1.default.createElement("div", { className: 'iui-table-header-wrapper', ref: headerRef },
331
+ react_1.default.createElement("div", { className: 'iui-table-header' }, headerGroups.slice(1).map(function (headerGroup) {
332
+ var headerGroupProps = headerGroup.getHeaderGroupProps({
333
+ className: 'iui-row',
334
+ });
335
+ return (react_1.default.createElement("div", __assign({}, headerGroupProps, { key: headerGroupProps.key }), headerGroup.headers.map(function (column, index) {
336
+ var columnProps = column.getHeaderProps(__assign(__assign({}, column.getSortByToggleProps()), { className: (0, classnames_1.default)('iui-cell', {
337
+ 'iui-actionable': column.canSort,
338
+ 'iui-sorted': column.isSorted,
339
+ 'iui-cell-sticky': !!column.sticky,
340
+ }, column.columnClassName), style: __assign(__assign(__assign({}, (0, utils_2.getCellStyle)(column, !!state.isTableResizing)), (0, utils_2.getStickyStyle)(column, visibleColumns)), { flexWrap: 'unset' }) }));
341
+ return (react_1.default.createElement("div", __assign({}, columnProps, column.getDragAndDropProps(), { key: columnProps.key, title: undefined, ref: function (el) {
342
+ if (el) {
343
+ columnRefs.current[column.id] = el;
344
+ column.resizeWidth = el.getBoundingClientRect().width;
345
+ }
346
+ } }),
347
+ column.render('Header'),
348
+ (showFilterButton(column) ||
349
+ showSortButton(column)) && (react_1.default.createElement("div", { className: 'iui-table-header-actions-container' },
350
+ showFilterButton(column) && (react_1.default.createElement(filters_1.FilterToggle, { column: column, ownerDocument: ownerDocument })),
351
+ showSortButton(column) && (react_1.default.createElement("div", { className: 'iui-cell-end-icon' }, column.isSorted && column.isSortedDesc ? (react_1.default.createElement(SortDown_1.default, { className: 'iui-icon iui-sort', "aria-hidden": true })) : (react_1.default.createElement(SortUp_1.default, { className: 'iui-icon iui-sort', "aria-hidden": true })))))),
352
+ isResizable &&
353
+ column.isResizerVisible &&
354
+ index !== headerGroup.headers.length - 1 && (react_1.default.createElement("div", __assign({}, column.getResizerProps(), { className: 'iui-resizer' }),
355
+ react_1.default.createElement("div", { className: 'iui-resizer-bar' }))),
356
+ enableColumnReordering &&
357
+ !column.disableReordering && (react_1.default.createElement("div", { className: 'iui-reorder-bar' })),
358
+ column.sticky === 'left' &&
359
+ state.sticky.isScrolledToRight && (react_1.default.createElement("div", { className: 'iui-cell-shadow-right' })),
360
+ column.sticky === 'right' &&
361
+ state.sticky.isScrolledToLeft && (react_1.default.createElement("div", { className: 'iui-cell-shadow-left' }))));
362
+ })));
363
+ }))),
322
364
  react_1.default.createElement("div", __assign({}, getTableBodyProps({
323
365
  className: (0, classnames_1.default)('iui-table-body', {
324
366
  'iui-zebra-striping': styleType === 'zebra-rows',
@@ -327,6 +369,7 @@ var Table = function (props) {
327
369
  }), { ref: bodyRef, onScroll: function () {
328
370
  if (headerRef.current && bodyRef.current) {
329
371
  headerRef.current.scrollLeft = bodyRef.current.scrollLeft;
372
+ updateStickyState();
330
373
  }
331
374
  }, tabIndex: -1 }),
332
375
  data.length !== 0 && (react_1.default.createElement(react_1.default.Fragment, null, enableVirtualization ? (react_1.default.createElement(VirtualScroll_1.default, { itemsLength: page.length, itemRenderer: virtualizedItemRenderer })) : (page.map(function (_, index) { return getPreparedRow(index); })))),
@@ -40,8 +40,10 @@ var TableCell = function (props) {
40
40
  };
41
41
  };
42
42
  var cellElementProps = cell.getCellProps({
43
- className: (0, classnames_1.default)('iui-cell', cell.column.cellClassName),
44
- style: __assign(__assign({}, (0, utils_1.getCellStyle)(cell.column, !!tableInstance.state.isTableResizing)), getSubRowStyle()),
43
+ className: (0, classnames_1.default)('iui-cell', cell.column.cellClassName, {
44
+ 'iui-cell-sticky': !!cell.column.sticky,
45
+ }),
46
+ style: __assign(__assign(__assign({}, (0, utils_1.getCellStyle)(cell.column, !!tableInstance.state.isTableResizing)), getSubRowStyle()), (0, utils_1.getStickyStyle)(cell.column, tableInstance.visibleColumns)),
45
47
  });
46
48
  var cellProps = __assign(__assign({}, tableInstance), { cell: cell, row: cell.row, value: cell.value, column: cell.column });
47
49
  var cellContent = (react_1.default.createElement(react_1.default.Fragment, null,
@@ -50,7 +52,12 @@ var TableCell = function (props) {
50
52
  var cellRendererProps = {
51
53
  cellElementProps: cellElementProps,
52
54
  cellProps: cellProps,
53
- children: cellContent,
55
+ children: (react_1.default.createElement(react_1.default.Fragment, null,
56
+ cellContent,
57
+ cell.column.sticky === 'left' &&
58
+ tableInstance.state.sticky.isScrolledToRight && (react_1.default.createElement("div", { className: 'iui-cell-shadow-right' })),
59
+ cell.column.sticky === 'right' &&
60
+ tableInstance.state.sticky.isScrolledToLeft && (react_1.default.createElement("div", { className: 'iui-cell-shadow-left' })))),
54
61
  };
55
62
  return (react_1.default.createElement(react_1.default.Fragment, null, cell.column.cellRenderer ? (cell.column.cellRenderer(__assign(__assign({}, cellRendererProps), { isDisabled: function () { return isDisabled; } }))) : (react_1.default.createElement(cells_1.DefaultCell, __assign({}, cellRendererProps, { isDisabled: function () { return isDisabled; } })))));
56
63
  };
@@ -149,7 +149,7 @@ var TablePaginator = function (props) {
149
149
  }
150
150
  var hasNoRows = totalPagesCount === 0;
151
151
  var showPagesList = totalPagesCount > 1 || isLoading;
152
- var showPageSizeList = pageSizeList && onPageSizeChange && !!totalRowsCount;
152
+ var showPageSizeList = pageSizeList && !!onPageSizeChange && !!totalRowsCount;
153
153
  var ellipsis = (react_1.default.createElement("span", { className: (0, classnames_1.default)('iui-paginator-ellipsis', {
154
154
  'iui-paginator-ellipsis-small': size === 'small',
155
155
  }) }, "\u2026"));
@@ -99,5 +99,9 @@ exports.TableRowMemoized = react_1.default.memo(exports.TableRow, function (prev
99
99
  prevProp.tableHasSubRows === nextProp.tableHasSubRows &&
100
100
  prevProp.state.columnOrder === nextProp.state.columnOrder &&
101
101
  !nextProp.state.columnResizing.isResizingColumn &&
102
- prevProp.state.isTableResizing === nextProp.state.isTableResizing;
102
+ prevProp.state.isTableResizing === nextProp.state.isTableResizing &&
103
+ prevProp.state.sticky.isScrolledToLeft ===
104
+ nextProp.state.sticky.isScrolledToLeft &&
105
+ prevProp.state.sticky.isScrolledToRight ===
106
+ nextProp.state.sticky.isScrolledToRight;
103
107
  });
@@ -12,6 +12,10 @@ export declare const onTableResizeStart: <T extends Record<string, unknown>>(sta
12
12
  isResizingColumn?: string | undefined;
13
13
  };
14
14
  columnReorderStartIndex: number;
15
+ sticky: {
16
+ isScrolledToRight?: boolean | undefined;
17
+ isScrolledToLeft?: boolean | undefined;
18
+ };
15
19
  columnOrder: import("react-table").IdType<T>[];
16
20
  expanded: Record<import("react-table").IdType<T>, boolean>;
17
21
  filters: import("react-table").Filters<T>;
@@ -38,6 +42,10 @@ export declare const onTableResizeEnd: <T extends Record<string, unknown>>(state
38
42
  };
39
43
  hiddenColumns?: import("react-table").IdType<T>[] | undefined;
40
44
  columnReorderStartIndex: number;
45
+ sticky: {
46
+ isScrolledToRight?: boolean | undefined;
47
+ isScrolledToLeft?: boolean | undefined;
48
+ };
41
49
  columnOrder: import("react-table").IdType<T>[];
42
50
  expanded: Record<import("react-table").IdType<T>, boolean>;
43
51
  filters: import("react-table").Filters<T>;
@@ -20,6 +20,10 @@ export declare const onSingleSelectHandler: <T extends Record<string, unknown>>(
20
20
  };
21
21
  isTableResizing?: boolean | undefined;
22
22
  columnReorderStartIndex: number;
23
+ sticky: {
24
+ isScrolledToRight?: boolean | undefined;
25
+ isScrolledToLeft?: boolean | undefined;
26
+ };
23
27
  columnOrder: import("react-table").IdType<T>[];
24
28
  expanded: Record<import("react-table").IdType<T>, boolean>;
25
29
  filters: import("react-table").Filters<T>;
@@ -55,11 +55,13 @@ var SelectionColumn = function (props) {
55
55
  var getToggleAllRowsSelectedProps = _a.getToggleAllRowsSelectedProps, rows = _a.rows, initialRows = _a.initialRows, state = _a.state;
56
56
  var disabled = rows.every(function (row) { return isDisabled === null || isDisabled === void 0 ? void 0 : isDisabled(row.original); });
57
57
  var checked = initialRows.every(function (row) { return state.selectedRowIds[row.id] || (isDisabled === null || isDisabled === void 0 ? void 0 : isDisabled(row.original)); });
58
- return (react_1.default.createElement(Checkbox_1.Checkbox, __assign({}, getToggleAllRowsSelectedProps(), { style: {}, checked: checked && !disabled, indeterminate: !checked && Object.keys(state.selectedRowIds).length > 0, disabled: disabled })));
58
+ return (react_1.default.createElement(Checkbox_1.Checkbox, __assign({}, getToggleAllRowsSelectedProps(), { style: {}, title: '' // Removes default title that comes from react-table
59
+ , checked: checked && !disabled, indeterminate: !checked && Object.keys(state.selectedRowIds).length > 0, disabled: disabled })));
59
60
  },
60
61
  Cell: function (_a) {
61
62
  var row = _a.row;
62
- return (react_1.default.createElement(Checkbox_1.Checkbox, __assign({}, row.getToggleRowSelectedProps(), { style: {}, disabled: isDisabled === null || isDisabled === void 0 ? void 0 : isDisabled(row.original), onClick: function (e) { return e.stopPropagation(); } })));
63
+ return (react_1.default.createElement(Checkbox_1.Checkbox, __assign({}, row.getToggleRowSelectedProps(), { style: {}, title: '' // Removes default title that comes from react-table
64
+ , disabled: isDisabled === null || isDisabled === void 0 ? void 0 : isDisabled(row.original), onClick: function (e) { return e.stopPropagation(); } })));
63
65
  },
64
66
  cellRenderer: function (props) { return (react_1.default.createElement(cells_1.DefaultCell, __assign({}, props, { isDisabled: function (rowData) { return !!(isDisabled === null || isDisabled === void 0 ? void 0 : isDisabled(rowData)); } }))); },
65
67
  };
@@ -28,7 +28,7 @@ export declare const tableFilters: {
28
28
  * Basic filter with a single input field.
29
29
  * @param translatedLabels Translated filter labels.
30
30
  */
31
- TextFilter: (translatedLabels?: FilterButtonBarTranslation | undefined) => <T extends Record<string, unknown>>(props: TableFilterProps<T>) => JSX.Element;
31
+ TextFilter: (translatedLabels?: FilterButtonBarTranslation) => <T extends Record<string, unknown>>(props: TableFilterProps<T>) => JSX.Element;
32
32
  /**
33
33
  * Date range filter.
34
34
  *
@@ -39,7 +39,7 @@ export declare const tableFilters: {
39
39
  * If your data is different type e.g. `string`, you can use `accessor` property in column description:
40
40
  * `accessor: (rowData) => new Date(rowData.date)`.
41
41
  */
42
- DateRangeFilter: (options?: DateRangeFilterOptions | undefined) => <T_1 extends Record<string, unknown>>(props: TableFilterProps<T_1>) => JSX.Element;
42
+ DateRangeFilter: (options?: DateRangeFilterOptions) => <T_1 extends Record<string, unknown>>(props: TableFilterProps<T_1>) => JSX.Element;
43
43
  /**
44
44
  * Number range filter.
45
45
  *
@@ -48,5 +48,5 @@ export declare const tableFilters: {
48
48
  * `accessor: (rowData) => Number(rowData.numberProp)`.
49
49
  * @param translatedLabels Translated filter labels.
50
50
  */
51
- NumberRangeFilter: (translatedLabels?: (NumberRangeTranslation & FilterButtonBarTranslation) | undefined) => <T_2 extends Record<string, unknown>>(props: NumberRangeFilterProps<T_2>) => JSX.Element;
51
+ NumberRangeFilter: (translatedLabels?: NumberRangeTranslation & FilterButtonBarTranslation) => <T_2 extends Record<string, unknown>>(props: NumberRangeFilterProps<T_2>) => JSX.Element;
52
52
  };
@@ -4,3 +4,4 @@ export { useSubRowFiltering } from './useSubRowFiltering';
4
4
  export { useSubRowSelection } from './useSubRowSelection';
5
5
  export { useResizeColumns } from './useResizeColumns';
6
6
  export { useColumnDragAndDrop } from './useColumnDragAndDrop';
7
+ export { useStickyColumns } from './useStickyColumns';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useColumnDragAndDrop = exports.useResizeColumns = exports.useSubRowSelection = exports.useSubRowFiltering = exports.useSelectionCell = exports.useExpanderCell = void 0;
3
+ exports.useStickyColumns = exports.useColumnDragAndDrop = exports.useResizeColumns = exports.useSubRowSelection = exports.useSubRowFiltering = exports.useSelectionCell = exports.useExpanderCell = void 0;
4
4
  /*---------------------------------------------------------------------------------------------
5
5
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
6
6
  * See LICENSE.md in the project root for license terms and full copyright notice.
@@ -17,3 +17,5 @@ var useResizeColumns_1 = require("./useResizeColumns");
17
17
  Object.defineProperty(exports, "useResizeColumns", { enumerable: true, get: function () { return useResizeColumns_1.useResizeColumns; } });
18
18
  var useColumnDragAndDrop_1 = require("./useColumnDragAndDrop");
19
19
  Object.defineProperty(exports, "useColumnDragAndDrop", { enumerable: true, get: function () { return useColumnDragAndDrop_1.useColumnDragAndDrop; } });
20
+ var useStickyColumns_1 = require("./useStickyColumns");
21
+ Object.defineProperty(exports, "useStickyColumns", { enumerable: true, get: function () { return useStickyColumns_1.useStickyColumns; } });
@@ -19,8 +19,16 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
19
19
  }
20
20
  return to.concat(ar || Array.prototype.slice.call(from));
21
21
  };
22
+ var __importDefault = (this && this.__importDefault) || function (mod) {
23
+ return (mod && mod.__esModule) ? mod : { "default": mod };
24
+ };
22
25
  Object.defineProperty(exports, "__esModule", { value: true });
23
26
  exports.useExpanderCell = void 0;
27
+ /*---------------------------------------------------------------------------------------------
28
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
29
+ * See LICENSE.md in the project root for license terms and full copyright notice.
30
+ *--------------------------------------------------------------------------------------------*/
31
+ var react_1 = __importDefault(require("react"));
24
32
  var columns_1 = require("../columns");
25
33
  var useExpanderCell = function (subComponent, expanderCell, isRowDisabled) { return function (hooks) {
26
34
  if (!subComponent) {
@@ -36,7 +44,9 @@ var useExpanderCell = function (subComponent, expanderCell, isRowDisabled) { ret
36
44
  isDisabled: isRowDisabled,
37
45
  });
38
46
  return __spreadArray([
39
- __assign(__assign({}, expanderColumn), { Cell: expanderCell !== null && expanderCell !== void 0 ? expanderCell : expanderColumn.Cell })
47
+ __assign(__assign({}, expanderColumn), { Cell: expanderCell
48
+ ? function (cellProps) { return react_1.default.createElement(react_1.default.Fragment, null, expanderCell(cellProps)); }
49
+ : expanderColumn.Cell })
40
50
  ], columns, true);
41
51
  });
42
52
  }; };
@@ -0,0 +1,2 @@
1
+ import { Hooks } from 'react-table';
2
+ export declare const useStickyColumns: <T extends Record<string, unknown>>(hooks: Hooks<T>) => void;
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
14
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
15
+ if (ar || !(i in from)) {
16
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
17
+ ar[i] = from[i];
18
+ }
19
+ }
20
+ return to.concat(ar || Array.prototype.slice.call(from));
21
+ };
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ exports.useStickyColumns = void 0;
24
+ /*---------------------------------------------------------------------------------------------
25
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
26
+ * See LICENSE.md in the project root for license terms and full copyright notice.
27
+ *--------------------------------------------------------------------------------------------*/
28
+ var react_table_1 = require("react-table");
29
+ react_table_1.actions.setScrolledLeft = 'setScrolledLeft';
30
+ react_table_1.actions.setScrolledRight = 'setScrolledRight';
31
+ var useStickyColumns = function (hooks) {
32
+ hooks.stateReducers.push(reducer);
33
+ hooks.useInstance.push(useInstance);
34
+ };
35
+ exports.useStickyColumns = useStickyColumns;
36
+ var reducer = function (newState, action) {
37
+ var _a, _b;
38
+ if (action.type === react_table_1.actions.init) {
39
+ return __assign(__assign({}, newState), { sticky: {} });
40
+ }
41
+ if (action.type === react_table_1.actions.setScrolledLeft &&
42
+ ((_a = newState.sticky) === null || _a === void 0 ? void 0 : _a.isScrolledToLeft) !== action.value // Prevents unnecessary re-render
43
+ ) {
44
+ return __assign(__assign({}, newState), { sticky: __assign(__assign({}, newState.sticky), { isScrolledToLeft: action.value }) });
45
+ }
46
+ if (action.type === react_table_1.actions.setScrolledRight &&
47
+ ((_b = newState.sticky) === null || _b === void 0 ? void 0 : _b.isScrolledToRight) !== action.value // Prevents unnecessary re-render
48
+ ) {
49
+ return __assign(__assign({}, newState), { sticky: __assign(__assign({}, newState.sticky), { isScrolledToRight: action.value }) });
50
+ }
51
+ return newState;
52
+ };
53
+ var useInstance = function (instance) {
54
+ var flatHeaders = instance.flatHeaders;
55
+ // Edge case. Saving original sticky state in case sticky columns are reordered.
56
+ flatHeaders.forEach(function (header) {
57
+ var _a;
58
+ if (!header.originalSticky) {
59
+ header.originalSticky = (_a = header.sticky) !== null && _a !== void 0 ? _a : 'none';
60
+ }
61
+ header.sticky =
62
+ header.originalSticky === 'none' ? undefined : header.originalSticky;
63
+ });
64
+ // If there is a column that is sticked to the left, make every column prior to that sticky too.
65
+ var hasLeftStickyColumn = false;
66
+ __spreadArray([], flatHeaders, true).reverse().forEach(function (header) {
67
+ if (header.sticky === 'left') {
68
+ hasLeftStickyColumn = true;
69
+ }
70
+ if (hasLeftStickyColumn) {
71
+ header.sticky = 'left';
72
+ }
73
+ });
74
+ // If there is a column that is sticked to the right, make every column after to that sticky too.
75
+ var hasRightStickyColumn = false;
76
+ flatHeaders.forEach(function (header) {
77
+ if (header.sticky === 'right') {
78
+ hasRightStickyColumn = true;
79
+ }
80
+ if (hasRightStickyColumn) {
81
+ header.sticky = 'right';
82
+ }
83
+ });
84
+ };
@@ -1,2 +1,3 @@
1
1
  import { ColumnInstance } from 'react-table';
2
2
  export declare const getCellStyle: <T extends Record<string, unknown>>(column: ColumnInstance<T>, isTableResizing: boolean) => React.CSSProperties | undefined;
3
+ export declare const getStickyStyle: <T extends Record<string, unknown>>(column: ColumnInstance<T>, columnList: ColumnInstance<T>[]) => React.CSSProperties;
@@ -1,6 +1,15 @@
1
1
  "use strict";
2
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
3
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
4
+ if (ar || !(i in from)) {
5
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
6
+ ar[i] = from[i];
7
+ }
8
+ }
9
+ return to.concat(ar || Array.prototype.slice.call(from));
10
+ };
2
11
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getCellStyle = void 0;
12
+ exports.getStickyStyle = exports.getCellStyle = void 0;
4
13
  var getCellStyle = function (column, isTableResizing) {
5
14
  var style = {};
6
15
  style.flex = "1 1 145px";
@@ -24,3 +33,29 @@ var getCellStyle = function (column, isTableResizing) {
24
33
  return style;
25
34
  };
26
35
  exports.getCellStyle = getCellStyle;
36
+ var getStickyStyle = function (column, columnList) {
37
+ if (!column.sticky) {
38
+ return {};
39
+ }
40
+ var left = 0;
41
+ for (var _i = 0, columnList_1 = columnList; _i < columnList_1.length; _i++) {
42
+ var col = columnList_1[_i];
43
+ if (col.id === column.id) {
44
+ break;
45
+ }
46
+ left += Number(col.width || col.resizeWidth || 0);
47
+ }
48
+ var right = 0;
49
+ for (var _a = 0, _b = __spreadArray([], columnList, true).reverse(); _a < _b.length; _a++) {
50
+ var col = _b[_a];
51
+ if (col.id === column.id) {
52
+ break;
53
+ }
54
+ right += Number(col.width || col.resizeWidth || 0);
55
+ }
56
+ return {
57
+ '--iui-table-sticky-left': column.sticky === 'left' ? "".concat(left, "px") : undefined,
58
+ '--iui-table-sticky-right': column.sticky === 'right' ? "".concat(right, "px") : undefined,
59
+ };
60
+ };
61
+ exports.getStickyStyle = getStickyStyle;