@itwin/itwinui-react 1.46.0 → 1.47.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 CHANGED
@@ -1,5 +1,16 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.47.0](https://www.github.com/iTwin/iTwinUI-react/compare/v1.46.0...v1.47.0) (2022-10-03)
4
+
5
+ ### What's new
6
+
7
+ * **Table:** Column resize modes ([#835](https://www.github.com/iTwin/iTwinUI-react/issues/835)) ([771a517](https://www.github.com/iTwin/iTwinUI-react/commit/771a517aa2031d5936521764a09613b6433ff283))
8
+
9
+
10
+ ### Fixes
11
+
12
+ * **Table:** Fixed when fast resizing caused Table to throw an error ([#848](https://www.github.com/iTwin/iTwinUI-react/issues/848)) ([058ad3a](https://www.github.com/iTwin/iTwinUI-react/commit/058ad3a7c1bb4a3198a4dde1105cca47a2ef2998))
13
+
3
14
  ## [1.46.0](https://www.github.com/iTwin/iTwinUI-react/compare/v1.45.0...v1.46.0) (2022-09-20)
4
15
 
5
16
  ### What's new
@@ -104,9 +104,9 @@ var flattenColumns = function (columns) {
104
104
  */
105
105
  var Table = function (props) {
106
106
  var _a;
107
- var data = props.data, columns = props.columns, _b = props.isLoading, isLoading = _b === void 0 ? false : _b, emptyTableContent = props.emptyTableContent, className = props.className, style = props.style, id = props.id, _c = props.isSelectable, isSelectable = _c === void 0 ? false : _c, onSelect = props.onSelect, onRowClick = props.onRowClick, _d = props.selectionMode, selectionMode = _d === void 0 ? 'multi' : _d, _e = props.isSortable, isSortable = _e === void 0 ? false : _e, onSort = props.onSort, stateReducer = props.stateReducer, onBottomReached = props.onBottomReached, onRowInViewport = props.onRowInViewport, _f = props.intersectionMargin, intersectionMargin = _f === void 0 ? 300 : _f, subComponent = props.subComponent, onExpand = props.onExpand, onFilter = props.onFilter, globalFilterValue = props.globalFilterValue, emptyFilteredTableContent = props.emptyFilteredTableContent, filterFunctions = props.filterTypes, expanderCell = props.expanderCell, isRowDisabled = props.isRowDisabled, rowProps = props.rowProps, _g = props.density, density = _g === void 0 ? 'default' : _g, _h = props.selectSubRows, selectSubRows = _h === void 0 ? true : _h, getSubRows = props.getSubRows, _j = props.selectRowOnClick, selectRowOnClick = _j === void 0 ? true : _j, paginatorRenderer = props.paginatorRenderer, _k = props.pageSize, pageSize = _k === void 0 ? 25 : _k, _l = props.isResizable, isResizable = _l === void 0 ? false : _l, _m = props.styleType, styleType = _m === void 0 ? 'default' : _m, _o = props.enableVirtualization, enableVirtualization = _o === void 0 ? false : _o, _p = props.enableColumnReordering, enableColumnReordering = _p === void 0 ? false : _p, rest = __rest(props, ["data", "columns", "isLoading", "emptyTableContent", "className", "style", "id", "isSelectable", "onSelect", "onRowClick", "selectionMode", "isSortable", "onSort", "stateReducer", "onBottomReached", "onRowInViewport", "intersectionMargin", "subComponent", "onExpand", "onFilter", "globalFilterValue", "emptyFilteredTableContent", "filterTypes", "expanderCell", "isRowDisabled", "rowProps", "density", "selectSubRows", "getSubRows", "selectRowOnClick", "paginatorRenderer", "pageSize", "isResizable", "styleType", "enableVirtualization", "enableColumnReordering"]);
107
+ var data = props.data, columns = props.columns, _b = props.isLoading, isLoading = _b === void 0 ? false : _b, emptyTableContent = props.emptyTableContent, className = props.className, style = props.style, id = props.id, _c = props.isSelectable, isSelectable = _c === void 0 ? false : _c, onSelect = props.onSelect, onRowClick = props.onRowClick, _d = props.selectionMode, selectionMode = _d === void 0 ? 'multi' : _d, _e = props.isSortable, isSortable = _e === void 0 ? false : _e, onSort = props.onSort, stateReducer = props.stateReducer, onBottomReached = props.onBottomReached, onRowInViewport = props.onRowInViewport, _f = props.intersectionMargin, intersectionMargin = _f === void 0 ? 300 : _f, subComponent = props.subComponent, onExpand = props.onExpand, onFilter = props.onFilter, globalFilterValue = props.globalFilterValue, emptyFilteredTableContent = props.emptyFilteredTableContent, filterFunctions = props.filterTypes, expanderCell = props.expanderCell, isRowDisabled = props.isRowDisabled, rowProps = props.rowProps, _g = props.density, density = _g === void 0 ? 'default' : _g, _h = props.selectSubRows, selectSubRows = _h === void 0 ? true : _h, getSubRows = props.getSubRows, _j = props.selectRowOnClick, selectRowOnClick = _j === void 0 ? true : _j, paginatorRenderer = props.paginatorRenderer, _k = props.pageSize, pageSize = _k === void 0 ? 25 : _k, _l = props.isResizable, isResizable = _l === void 0 ? false : _l, _m = props.columnResizeMode, columnResizeMode = _m === void 0 ? 'fit' : _m, _o = props.styleType, styleType = _o === void 0 ? 'default' : _o, _p = props.enableVirtualization, enableVirtualization = _p === void 0 ? false : _p, _q = props.enableColumnReordering, enableColumnReordering = _q === void 0 ? false : _q, rest = __rest(props, ["data", "columns", "isLoading", "emptyTableContent", "className", "style", "id", "isSelectable", "onSelect", "onRowClick", "selectionMode", "isSortable", "onSort", "stateReducer", "onBottomReached", "onRowInViewport", "intersectionMargin", "subComponent", "onExpand", "onFilter", "globalFilterValue", "emptyFilteredTableContent", "filterTypes", "expanderCell", "isRowDisabled", "rowProps", "density", "selectSubRows", "getSubRows", "selectRowOnClick", "paginatorRenderer", "pageSize", "isResizable", "columnResizeMode", "styleType", "enableVirtualization", "enableColumnReordering"]);
108
108
  (0, utils_1.useTheme)();
109
- var _q = react_1.default.useState(), ownerDocument = _q[0], setOwnerDocument = _q[1];
109
+ var ownerDocument = react_1.default.useRef();
110
110
  var defaultColumn = react_1.default.useMemo(function () { return ({
111
111
  maxWidth: 0,
112
112
  minWidth: 0,
@@ -125,24 +125,26 @@ var Table = function (props) {
125
125
  }, [columns]);
126
126
  var disableUserSelect = react_1.default.useCallback(function (e) {
127
127
  if (e.key === 'Shift') {
128
- ownerDocument &&
129
- (ownerDocument.documentElement.style.userSelect = 'none');
128
+ ownerDocument.current &&
129
+ (ownerDocument.current.documentElement.style.userSelect = 'none');
130
130
  }
131
- }, [ownerDocument]);
131
+ }, []);
132
132
  var enableUserSelect = react_1.default.useCallback(function (e) {
133
133
  if (e.key === 'Shift') {
134
- ownerDocument && (ownerDocument.documentElement.style.userSelect = '');
134
+ ownerDocument.current &&
135
+ (ownerDocument.current.documentElement.style.userSelect = '');
135
136
  }
136
- }, [ownerDocument]);
137
+ }, []);
137
138
  react_1.default.useEffect(function () {
138
139
  if (!isSelectable || selectionMode !== 'multi') {
139
140
  return;
140
141
  }
141
- ownerDocument === null || ownerDocument === void 0 ? void 0 : ownerDocument.addEventListener('keydown', disableUserSelect);
142
- ownerDocument === null || ownerDocument === void 0 ? void 0 : ownerDocument.addEventListener('keyup', enableUserSelect);
142
+ var ownerDoc = ownerDocument.current;
143
+ ownerDoc === null || ownerDoc === void 0 ? void 0 : ownerDoc.addEventListener('keydown', disableUserSelect);
144
+ ownerDoc === null || ownerDoc === void 0 ? void 0 : ownerDoc.addEventListener('keyup', enableUserSelect);
143
145
  return function () {
144
- ownerDocument === null || ownerDocument === void 0 ? void 0 : ownerDocument.removeEventListener('keydown', disableUserSelect);
145
- ownerDocument === null || ownerDocument === void 0 ? void 0 : ownerDocument.removeEventListener('keyup', enableUserSelect);
146
+ ownerDoc === null || ownerDoc === void 0 ? void 0 : ownerDoc.removeEventListener('keydown', disableUserSelect);
147
+ ownerDoc === null || ownerDoc === void 0 ? void 0 : ownerDoc.removeEventListener('keyup', enableUserSelect);
146
148
  };
147
149
  }, [
148
150
  isSelectable,
@@ -212,7 +214,7 @@ var Table = function (props) {
212
214
  return getSubRows ? getSubRows(item, index) : item.subRows;
213
215
  });
214
216
  }, [data, getSubRows]);
215
- 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.useGlobalFilter, 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);
217
+ 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), columnResizeMode: columnResizeMode }), react_table_1.useFlexLayout, (0, hooks_1.useResizeColumns)(ownerDocument), react_table_1.useFilters, (0, hooks_1.useSubRowFiltering)(hasAnySubRows), react_table_1.useGlobalFilter, 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);
216
218
  var getTableProps = instance.getTableProps, rows = instance.rows, headerGroups = instance.headerGroups, getTableBodyProps = instance.getTableBodyProps, prepareRow = instance.prepareRow, state = instance.state, allColumns = instance.allColumns, dispatch = instance.dispatch, page = instance.page, gotoPage = instance.gotoPage, setPageSize = instance.setPageSize, flatHeaders = instance.flatHeaders, visibleColumns = instance.visibleColumns, setGlobalFilter = instance.setGlobalFilter;
217
219
  var ariaDataAttributes = Object.entries(rest).reduce(function (result, _a) {
218
220
  var key = _a[0], value = _a[1];
@@ -290,6 +292,7 @@ var Table = function (props) {
290
292
  var previousTableWidth = react_1.default.useRef(0);
291
293
  var onTableResize = react_1.default.useCallback(function (_a) {
292
294
  var width = _a.width;
295
+ instance.tableWidth = width;
293
296
  if (width === previousTableWidth.current) {
294
297
  return;
295
298
  }
@@ -305,7 +308,7 @@ var Table = function (props) {
305
308
  return;
306
309
  }
307
310
  dispatch({ type: exports.tableResizeStartAction });
308
- }, [dispatch, state.columnResizing.columnWidths, flatHeaders]);
311
+ }, [dispatch, state.columnResizing.columnWidths, flatHeaders, instance]);
309
312
  var resizeRef = (0, utils_1.useResizeObserver)(onTableResize)[0];
310
313
  // Flexbox handles columns resize so we take new column widths before browser repaints.
311
314
  react_1.default.useLayoutEffect(function () {
@@ -321,12 +324,10 @@ var Table = function (props) {
321
324
  });
322
325
  var headerRef = react_1.default.useRef(null);
323
326
  var bodyRef = react_1.default.useRef(null);
324
- // Using `useState` to rerender rows when table body ref is available
325
- var _s = react_1.default.useState(null), bodyRefState = _s[0], setBodyRefState = _s[1];
326
327
  var getPreparedRow = react_1.default.useCallback(function (index) {
327
328
  var row = page[index];
328
329
  prepareRow(row);
329
- return (react_1.default.createElement(TableRowMemoized_1.TableRowMemoized, { row: row, rowProps: rowProps, isLast: index === page.length - 1, onRowInViewport: onRowInViewportRef, onBottomReached: onBottomReachedRef, intersectionMargin: intersectionMargin, state: state, key: row.getRowProps().key, onClick: onRowClickHandler, subComponent: subComponent, isDisabled: !!(isRowDisabled === null || isRowDisabled === void 0 ? void 0 : isRowDisabled(row.original)), tableHasSubRows: hasAnySubRows, tableInstance: instance, expanderCell: expanderCell, bodyRef: bodyRefState, tableRowRef: enableVirtualization ? undefined : tableRowRef(row) }));
330
+ return (react_1.default.createElement(TableRowMemoized_1.TableRowMemoized, { row: row, rowProps: rowProps, isLast: index === page.length - 1, onRowInViewport: onRowInViewportRef, onBottomReached: onBottomReachedRef, intersectionMargin: intersectionMargin, state: state, key: row.getRowProps().key, onClick: onRowClickHandler, subComponent: subComponent, isDisabled: !!(isRowDisabled === null || isRowDisabled === void 0 ? void 0 : isRowDisabled(row.original)), tableHasSubRows: hasAnySubRows, tableInstance: instance, expanderCell: expanderCell, bodyRef: bodyRef.current, tableRowRef: enableVirtualization ? undefined : tableRowRef(row) }));
330
331
  }, [
331
332
  page,
332
333
  prepareRow,
@@ -339,7 +340,6 @@ var Table = function (props) {
339
340
  hasAnySubRows,
340
341
  instance,
341
342
  expanderCell,
342
- bodyRefState,
343
343
  enableVirtualization,
344
344
  tableRowRef,
345
345
  ]);
@@ -368,9 +368,10 @@ var Table = function (props) {
368
368
  // Call only on init
369
369
  // eslint-disable-next-line react-hooks/exhaustive-deps
370
370
  }, []);
371
+ var isHeaderDirectClick = react_1.default.useRef(false);
371
372
  return (react_1.default.createElement(react_1.default.Fragment, null,
372
373
  react_1.default.createElement("div", __assign({ ref: function (element) {
373
- setOwnerDocument(element === null || element === void 0 ? void 0 : element.ownerDocument);
374
+ ownerDocument.current = element === null || element === void 0 ? void 0 : element.ownerDocument;
374
375
  if (isResizable) {
375
376
  resizeRef(element);
376
377
  }
@@ -389,7 +390,8 @@ var Table = function (props) {
389
390
  className: 'iui-row',
390
391
  });
391
392
  return (react_1.default.createElement("div", __assign({}, headerGroupProps, { key: headerGroupProps.key }), headerGroup.headers.map(function (column, index) {
392
- var columnProps = column.getHeaderProps(__assign(__assign({}, column.getSortByToggleProps()), { className: (0, classnames_1.default)('iui-cell', {
393
+ var _a = column.getSortByToggleProps(), onClick = _a.onClick, restSortProps = __rest(_a, ["onClick"]);
394
+ var columnProps = column.getHeaderProps(__assign(__assign({}, restSortProps), { className: (0, classnames_1.default)('iui-cell', {
393
395
  'iui-actionable': column.canSort,
394
396
  'iui-sorted': column.isSorted,
395
397
  'iui-cell-sticky': !!column.sticky,
@@ -399,16 +401,25 @@ var Table = function (props) {
399
401
  columnRefs.current[column.id] = el;
400
402
  column.resizeWidth = el.getBoundingClientRect().width;
401
403
  }
404
+ }, onMouseDown: function () {
405
+ isHeaderDirectClick.current = true;
406
+ }, onClick: function (e) {
407
+ // Prevents from triggering sort when resizing and mouse is released in the middle of header
408
+ if (isHeaderDirectClick.current) {
409
+ onClick === null || onClick === void 0 ? void 0 : onClick(e);
410
+ isHeaderDirectClick.current = false;
411
+ }
402
412
  } }),
403
413
  column.render('Header'),
404
414
  (showFilterButton(column) ||
405
415
  showSortButton(column)) && (react_1.default.createElement("div", { className: 'iui-table-header-actions-container' },
406
- showFilterButton(column) && (react_1.default.createElement(filters_1.FilterToggle, { column: column, ownerDocument: ownerDocument })),
416
+ showFilterButton(column) && (react_1.default.createElement(filters_1.FilterToggle, { column: column })),
407
417
  showSortButton(column) && (react_1.default.createElement("div", { className: 'iui-cell-end-icon' }, column.isSortedDesc ||
408
418
  (!column.isSorted && column.sortDescFirst) ? (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 })))))),
409
419
  isResizable &&
410
420
  column.isResizerVisible &&
411
- index !== headerGroup.headers.length - 1 && (react_1.default.createElement("div", __assign({}, column.getResizerProps(), { className: 'iui-resizer' }),
421
+ (index !== headerGroup.headers.length - 1 ||
422
+ columnResizeMode === 'expand') && (react_1.default.createElement("div", __assign({}, column.getResizerProps(), { className: 'iui-resizer' }),
412
423
  react_1.default.createElement("div", { className: 'iui-resizer-bar' }))),
413
424
  enableColumnReordering &&
414
425
  !column.disableReordering && (react_1.default.createElement("div", { className: 'iui-reorder-bar' })),
@@ -423,7 +434,7 @@ var Table = function (props) {
423
434
  'iui-zebra-striping': styleType === 'zebra-rows',
424
435
  }),
425
436
  style: { outline: 0 },
426
- }), { ref: (0, utils_1.mergeRefs)(bodyRef, setBodyRefState), onScroll: function () {
437
+ }), { ref: bodyRef, onScroll: function () {
427
438
  if (headerRef.current && bodyRef.current) {
428
439
  headerRef.current.scrollLeft = bodyRef.current.scrollLeft;
429
440
  updateStickyState();
@@ -4,7 +4,6 @@ import '@itwin/itwinui-css/css/table.css';
4
4
  import { StylingProps } from '../../utils';
5
5
  export declare type FilterToggleProps<T extends Record<string, unknown>> = {
6
6
  column: HeaderGroup<T>;
7
- ownerDocument?: Document;
8
7
  } & StylingProps;
9
8
  /**
10
9
  * Handles showing filter icon and opening filter component.
@@ -41,9 +41,9 @@ var Buttons_1 = require("../../Buttons");
41
41
  * Handles showing filter icon and opening filter component.
42
42
  */
43
43
  var FilterToggle = function (props) {
44
- var column = props.column, _a = props.ownerDocument, ownerDocument = _a === void 0 ? (0, utils_1.getDocument)() : _a, className = props.className, rest = __rest(props, ["column", "ownerDocument", "className"]);
44
+ var column = props.column, className = props.className, rest = __rest(props, ["column", "className"]);
45
45
  (0, utils_1.useTheme)();
46
- var _b = react_1.default.useState(false), isVisible = _b[0], setIsVisible = _b[1];
46
+ var _a = react_1.default.useState(false), isVisible = _a[0], setIsVisible = _a[1];
47
47
  var close = react_1.default.useCallback(function () { return setIsVisible(false); }, []);
48
48
  var setFilter = react_1.default.useCallback(function (filterValue) {
49
49
  column.setFilter(filterValue);
@@ -54,7 +54,7 @@ var FilterToggle = function (props) {
54
54
  close();
55
55
  }, [close, column]);
56
56
  var isColumnFiltered = column.filterValue != null && column.filterValue !== '';
57
- return (react_1.default.createElement(react_1.default.Fragment, null, column.canFilter && column.Filter && (react_1.default.createElement(utils_1.Popover, { content: column.render('Filter', { close: close, setFilter: setFilter, clearFilter: clearFilter }), placement: 'bottom-start', visible: isVisible, onClickOutside: close, appendTo: ownerDocument === null || ownerDocument === void 0 ? void 0 : ownerDocument.body },
57
+ return (react_1.default.createElement(react_1.default.Fragment, null, column.canFilter && column.Filter && (react_1.default.createElement(utils_1.Popover, { content: column.render('Filter', { close: close, setFilter: setFilter, clearFilter: clearFilter }), placement: 'bottom-start', visible: isVisible, onClickOutside: close },
58
58
  react_1.default.createElement(Buttons_1.IconButton, __assign({ styleType: 'borderless', isActive: isVisible || isColumnFiltered, className: (0, classnames_1.default)('iui-filter-button', className), onClick: function (e) {
59
59
  setIsVisible(function (v) { return !v; });
60
60
  // Prevents from triggering sort
@@ -1,5 +1,37 @@
1
+ /**
2
+ * Copied from react-table as useResizeColumns and made some changes:
3
+ * - Added TS typings
4
+ * - Added sibling/next column resize when resizing
5
+ * - Favoring min/max widths when resizing
6
+ * - Added owner document support
7
+ * @link https://github.com/tannerlinsley/react-table/blob/master/src/plugin-hooks/useResizeColumns.js
8
+ */
9
+ /**
10
+ * MIT License
11
+ *
12
+ * Copyright (c) 2016 Tanner Linsley
13
+ *
14
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
15
+ * of this software and associated documentation files (the "Software"), to deal
16
+ * in the Software without restriction, including without limitation the rights
17
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18
+ * copies of the Software, and to permit persons to whom the Software is
19
+ * furnished to do so, subject to the following conditions:
20
+ *
21
+ * The above copyright notice and this permission notice shall be included in all
22
+ * copies or substantial portions of the Software.
23
+ *
24
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30
+ * SOFTWARE.
31
+ */
32
+ import React from 'react';
1
33
  import { Hooks } from 'react-table';
2
34
  export declare const useResizeColumns: {
3
- <T extends Record<string, unknown>>(ownerDocument: Document | undefined): (hooks: Hooks<T>) => void;
35
+ <T extends Record<string, unknown>>(ownerDocument: React.RefObject<Document | undefined>): (hooks: Hooks<T>) => void;
4
36
  pluginName: string;
5
37
  };
@@ -33,24 +33,19 @@ var isTouchEvent = function (event) {
33
33
  };
34
34
  var defaultGetResizerProps = function (ownerDocument) { return function (props, _a) {
35
35
  var instance = _a.instance, header = _a.header, nextHeader = _a.nextHeader;
36
- if (!ownerDocument) {
37
- return props;
38
- }
39
- var dispatch = instance.dispatch, flatHeaders = instance.flatHeaders;
36
+ var dispatch = instance.dispatch;
40
37
  var onResizeStart = function (e, header) {
38
+ var _a, _b, _c;
41
39
  // lets not respond to multiple touches (e.g. 2 or 3 fingers)
42
40
  if (isTouchEvent(e) && e.touches && e.touches.length > 1) {
43
41
  return;
44
42
  }
45
- // Setting `width` here because it might take several rerenders until actual column width is set.
46
- flatHeaders.forEach(function (h) {
47
- if (!h.width) {
48
- h.width = h.resizeWidth;
49
- }
50
- });
51
- var headerIdWidths = getLeafHeaders(header).map(function (d) { return [d.id, d.width]; });
43
+ var headerIdWidths = getLeafHeaders(header).map(function (d) { return [
44
+ d.id,
45
+ getHeaderWidth(d),
46
+ ]; });
52
47
  var nextHeaderIdWidths = nextHeader
53
- ? getLeafHeaders(nextHeader).map(function (d) { return [d.id, d.width]; })
48
+ ? getLeafHeaders(nextHeader).map(function (d) { return [d.id, getHeaderWidth(d)]; })
54
49
  : [];
55
50
  var clientX = isTouchEvent(e)
56
51
  ? Math.round(e.touches[0].clientX)
@@ -69,8 +64,10 @@ var defaultGetResizerProps = function (ownerDocument) { return function (props,
69
64
  moveHandler: function (e) { return dispatchMove(e.clientX); },
70
65
  upEvent: 'mouseup',
71
66
  upHandler: function () {
72
- ownerDocument.removeEventListener('mousemove', handlersAndEvents.mouse.moveHandler);
73
- ownerDocument.removeEventListener('mouseup', handlersAndEvents.mouse.upHandler);
67
+ var _a, _b, _c;
68
+ (_a = ownerDocument.current) === null || _a === void 0 ? void 0 : _a.removeEventListener('mousemove', handlersAndEvents.mouse.moveHandler);
69
+ (_b = ownerDocument.current) === null || _b === void 0 ? void 0 : _b.removeEventListener('mouseup', handlersAndEvents.mouse.upHandler);
70
+ (_c = ownerDocument.current) === null || _c === void 0 ? void 0 : _c.removeEventListener('mouseleave', handlersAndEvents.mouse.upHandler);
74
71
  dispatchEnd();
75
72
  },
76
73
  },
@@ -85,8 +82,9 @@ var defaultGetResizerProps = function (ownerDocument) { return function (props,
85
82
  },
86
83
  upEvent: 'touchend',
87
84
  upHandler: function () {
88
- ownerDocument.removeEventListener(handlersAndEvents.touch.moveEvent, handlersAndEvents.touch.moveHandler);
89
- ownerDocument.removeEventListener(handlersAndEvents.touch.upEvent, handlersAndEvents.touch.moveHandler);
85
+ var _a, _b;
86
+ (_a = ownerDocument.current) === null || _a === void 0 ? void 0 : _a.removeEventListener(handlersAndEvents.touch.moveEvent, handlersAndEvents.touch.moveHandler);
87
+ (_b = ownerDocument.current) === null || _b === void 0 ? void 0 : _b.removeEventListener(handlersAndEvents.touch.upEvent, handlersAndEvents.touch.moveHandler);
90
88
  dispatchEnd();
91
89
  },
92
90
  },
@@ -97,13 +95,16 @@ var defaultGetResizerProps = function (ownerDocument) { return function (props,
97
95
  var passiveIfSupported = passiveEventSupported()
98
96
  ? { passive: false }
99
97
  : false;
100
- ownerDocument.addEventListener(events.moveEvent, events.moveHandler, passiveIfSupported);
101
- ownerDocument.addEventListener(events.upEvent, events.upHandler, passiveIfSupported);
98
+ (_a = ownerDocument.current) === null || _a === void 0 ? void 0 : _a.addEventListener(events.moveEvent, events.moveHandler, passiveIfSupported);
99
+ (_b = ownerDocument.current) === null || _b === void 0 ? void 0 : _b.addEventListener(events.upEvent, events.upHandler, passiveIfSupported);
100
+ if (!isTouchEvent(e)) {
101
+ (_c = ownerDocument.current) === null || _c === void 0 ? void 0 : _c.addEventListener('mouseleave', handlersAndEvents.mouse.upHandler, passiveIfSupported);
102
+ }
102
103
  dispatch({
103
104
  type: react_table_1.actions.columnStartResizing,
104
105
  columnId: header.id,
105
- columnWidth: header.width,
106
- nextColumnWidth: nextHeader === null || nextHeader === void 0 ? void 0 : nextHeader.width,
106
+ columnWidth: getHeaderWidth(header),
107
+ nextColumnWidth: getHeaderWidth(nextHeader),
107
108
  headerIdWidths: headerIdWidths,
108
109
  nextHeaderIdWidths: nextHeaderIdWidths,
109
110
  clientX: clientX,
@@ -120,6 +121,8 @@ var defaultGetResizerProps = function (ownerDocument) { return function (props,
120
121
  e.persist();
121
122
  // Prevents from triggering drag'n'drop
122
123
  e.preventDefault();
124
+ // Prevents from triggering sort
125
+ e.stopPropagation();
123
126
  onResizeStart(e, header);
124
127
  },
125
128
  onTouchStart: function (e) {
@@ -155,13 +158,29 @@ var reducer = function (newState, action, previousState, instance) {
155
158
  if (action.type === react_table_1.actions.columnResizing) {
156
159
  var clientX = action.clientX;
157
160
  var _a = newState.columnResizing, _b = _a.startX, startX = _b === void 0 ? 0 : _b, _c = _a.columnWidth, columnWidth = _c === void 0 ? 1 : _c, _d = _a.nextColumnWidth, nextColumnWidth = _d === void 0 ? 1 : _d, _e = _a.headerIdWidths, headerIdWidths = _e === void 0 ? [] : _e, _f = _a.nextHeaderIdWidths, nextHeaderIdWidths = _f === void 0 ? [] : _f;
161
+ if (!instance) {
162
+ return newState;
163
+ }
158
164
  var deltaX = clientX - startX;
159
165
  var newColumnWidths = getColumnWidths(headerIdWidths, deltaX / columnWidth);
160
- var newNextColumnWidths = getColumnWidths(nextHeaderIdWidths, -deltaX / nextColumnWidth);
161
- if (!isNewColumnWidthsValid(newColumnWidths, instance === null || instance === void 0 ? void 0 : instance.flatHeaders) ||
162
- !isNewColumnWidthsValid(newNextColumnWidths, instance === null || instance === void 0 ? void 0 : instance.flatHeaders)) {
166
+ var isTableWidthDecreasing = calculateTableWidth(newColumnWidths, instance.flatHeaders) <
167
+ instance.tableWidth;
168
+ var newNextColumnWidths = (instance === null || instance === void 0 ? void 0 : instance.columnResizeMode) === 'fit' ||
169
+ ((instance === null || instance === void 0 ? void 0 : instance.columnResizeMode) === 'expand' && isTableWidthDecreasing)
170
+ ? getColumnWidths(nextHeaderIdWidths, -deltaX / nextColumnWidth)
171
+ : {};
172
+ if (!isNewColumnWidthsValid(newColumnWidths, instance.flatHeaders) ||
173
+ !isNewColumnWidthsValid(newNextColumnWidths, instance.flatHeaders) ||
174
+ !isNewTableWidthValid(__assign(__assign({}, newColumnWidths), newNextColumnWidths), instance)) {
163
175
  return newState;
164
176
  }
177
+ // Setting `width` here because it might take several rerenders until actual column width is set.
178
+ // Also setting after the actual resize happened.
179
+ instance === null || instance === void 0 ? void 0 : instance.flatHeaders.forEach(function (h) {
180
+ if (!h.width) {
181
+ h.width = h.resizeWidth;
182
+ }
183
+ });
165
184
  return __assign(__assign({}, newState), { columnResizing: __assign(__assign({}, newState.columnResizing), { columnWidths: __assign(__assign(__assign({}, newState.columnResizing.columnWidths), newColumnWidths), newNextColumnWidths) }) });
166
185
  }
167
186
  if (action.type === react_table_1.actions.columnDoneResizing) {
@@ -201,25 +220,53 @@ var isNewColumnWidthsValid = function (columnWidths, headers) {
201
220
  }
202
221
  return true;
203
222
  };
223
+ var isNewTableWidthValid = function (columnWidths, instance) {
224
+ if (instance.columnResizeMode === 'fit') {
225
+ return true;
226
+ }
227
+ var newTableWidth = 0;
228
+ for (var _i = 0, _a = instance.flatHeaders; _i < _a.length; _i++) {
229
+ var header = _a[_i];
230
+ newTableWidth += columnWidths[header.id]
231
+ ? columnWidths[header.id]
232
+ : getHeaderWidth(header);
233
+ }
234
+ // `tableWidth` is whole number therefore we need to round the `newTableWidth`
235
+ if (Math.round(newTableWidth) < instance.tableWidth) {
236
+ return false;
237
+ }
238
+ return true;
239
+ };
204
240
  var useInstanceBeforeDimensions = function (instance) {
205
- var flatHeaders = instance.flatHeaders, getHooks = instance.getHooks, columnResizing = instance.state.columnResizing;
241
+ var flatHeaders = instance.flatHeaders, getHooks = instance.getHooks, columnResizing = instance.state.columnResizing, columnResizeMode = instance.columnResizeMode;
206
242
  var getInstance = (0, react_table_1.useGetLatest)(instance);
207
243
  flatHeaders.forEach(function (header, index) {
208
244
  var _a;
209
245
  var resizeWidth = columnResizing.columnWidths[header.id];
210
246
  header.width = resizeWidth || header.width || header.originalWidth;
211
247
  header.isResizing = columnResizing.isResizingColumn === header.id;
212
- var headerToResize = header.disableResizing
248
+ var headerToResize = header.disableResizing && columnResizeMode === 'fit'
213
249
  ? getPreviousResizableHeader(header, instance)
214
250
  : header;
215
- var nextResizableHeader = getNextResizableHeader(header, instance);
251
+ // When `columnResizeMode` is `expand` and it is a last column,
252
+ // then try to find some column on the left side to resize
253
+ // when table width is decreasing.
254
+ var nextResizableHeader = columnResizeMode === 'expand' && index === flatHeaders.length - 1
255
+ ? getPreviousResizableHeader(header, instance)
256
+ : getNextResizableHeader(header, instance);
216
257
  header.canResize =
217
258
  header.disableResizing != null ? !header.disableResizing : true;
218
259
  // Show resizer when header is resizable or when next header is resizable
219
260
  // and there is resizable columns on the left side of the resizer.
220
- header.isResizerVisible =
221
- (header.canResize && !!nextResizableHeader) ||
222
- (headerToResize && !!((_a = instance.flatHeaders[index + 1]) === null || _a === void 0 ? void 0 : _a.canResize));
261
+ if (columnResizeMode === 'fit') {
262
+ header.isResizerVisible =
263
+ (header.canResize && !!nextResizableHeader) ||
264
+ (headerToResize && !!((_a = instance.flatHeaders[index + 1]) === null || _a === void 0 ? void 0 : _a.canResize));
265
+ // When resize mode is `expand` show resizer on the current resizable column.
266
+ }
267
+ else {
268
+ header.isResizerVisible = header.canResize && !!headerToResize;
269
+ }
223
270
  header.getResizerProps = (0, react_table_1.makePropGetter)(getHooks().getResizerProps, {
224
271
  instance: getInstance(),
225
272
  header: headerToResize,
@@ -259,6 +306,19 @@ function getLeafHeaders(header) {
259
306
  recurseHeader(header);
260
307
  return leafHeaders;
261
308
  }
309
+ var getHeaderWidth = function (header) {
310
+ return Number(header.width || header.resizeWidth || 0);
311
+ };
312
+ var calculateTableWidth = function (columnWidths, headers) {
313
+ var newTableWidth = 0;
314
+ for (var _i = 0, headers_1 = headers; _i < headers_1.length; _i++) {
315
+ var header = headers_1[_i];
316
+ newTableWidth += columnWidths[header.id]
317
+ ? columnWidths[header.id]
318
+ : getHeaderWidth(header);
319
+ }
320
+ return newTableWidth;
321
+ };
262
322
  // https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#safely_detecting_option_support
263
323
  var passiveSupported = null;
264
324
  var passiveEventSupported = function () {
@@ -28,11 +28,22 @@ declare module 'react-table' {
28
28
  * If some rows don't have sub-data, it is recommended to pass an empty array to `subRows` for consistent spacing.
29
29
  */
30
30
  data: D[];
31
+ /**
32
+ * Column's resize mode.
33
+ * - `fit` - when resizing it affects current and the next column,
34
+ * e.g. when increasing width of current column, next column's width will decrease.
35
+ * - `expand` - when resizing it affects only the current column,
36
+ * e.g. when increasing width of the current column, next column's width remains the same.
37
+ * @default 'fit'
38
+ */
39
+ columnResizeMode?: 'fit' | 'expand';
31
40
  }
32
41
  interface Hooks<D extends object = {}> extends UseExpandedHooks<D>, UseGroupByHooks<D>, UseRowSelectHooks<D>, UseSortByHooks<D> {
33
42
  }
34
43
  interface TableInstance<D extends object = {}> extends UseColumnOrderInstanceProps<D>, UseExpandedInstanceProps<D>, UseFiltersInstanceProps<D>, UseGlobalFiltersInstanceProps<D>, UseGroupByInstanceProps<D>, UsePaginationInstanceProps<D>, UseRowSelectInstanceProps<D>, UseRowStateInstanceProps<D>, UseSortByInstanceProps<D> {
35
44
  initialRows: Row<D>[];
45
+ columnResizeMode: TableOptions['columnResizeMode'];
46
+ tableWidth: number;
36
47
  }
37
48
  interface TableState<D extends object = {}> extends UseColumnOrderState<D>, UseExpandedState<D>, UseFiltersState<D>, UseGlobalFiltersState<D>, UseGroupByState<D>, UsePaginationState<D>, UseRowSelectState<D>, UseRowStateState<D>, UseSortByState<D> {
38
49
  columnResizing: {
@@ -28,7 +28,7 @@ import React from 'react';
28
28
  import cx from 'classnames';
29
29
  import { actions as TableActions, useFlexLayout, useFilters, useRowSelect, useSortBy, useTable, useExpanded, usePagination, useColumnOrder, useGlobalFilter, } from 'react-table';
30
30
  import { ProgressRadial } from '../ProgressIndicators';
31
- import { useTheme, useResizeObserver, mergeRefs } from '../utils';
31
+ import { useTheme, useResizeObserver } from '../utils';
32
32
  import '@itwin/itwinui-css/css/table.css';
33
33
  import SvgSortDown from '@itwin/itwinui-icons-react/cjs/icons/SortDown';
34
34
  import SvgSortUp from '@itwin/itwinui-icons-react/cjs/icons/SortUp';
@@ -98,9 +98,9 @@ var flattenColumns = function (columns) {
98
98
  */
99
99
  export var Table = function (props) {
100
100
  var _a;
101
- var data = props.data, columns = props.columns, _b = props.isLoading, isLoading = _b === void 0 ? false : _b, emptyTableContent = props.emptyTableContent, className = props.className, style = props.style, id = props.id, _c = props.isSelectable, isSelectable = _c === void 0 ? false : _c, onSelect = props.onSelect, onRowClick = props.onRowClick, _d = props.selectionMode, selectionMode = _d === void 0 ? 'multi' : _d, _e = props.isSortable, isSortable = _e === void 0 ? false : _e, onSort = props.onSort, stateReducer = props.stateReducer, onBottomReached = props.onBottomReached, onRowInViewport = props.onRowInViewport, _f = props.intersectionMargin, intersectionMargin = _f === void 0 ? 300 : _f, subComponent = props.subComponent, onExpand = props.onExpand, onFilter = props.onFilter, globalFilterValue = props.globalFilterValue, emptyFilteredTableContent = props.emptyFilteredTableContent, filterFunctions = props.filterTypes, expanderCell = props.expanderCell, isRowDisabled = props.isRowDisabled, rowProps = props.rowProps, _g = props.density, density = _g === void 0 ? 'default' : _g, _h = props.selectSubRows, selectSubRows = _h === void 0 ? true : _h, getSubRows = props.getSubRows, _j = props.selectRowOnClick, selectRowOnClick = _j === void 0 ? true : _j, paginatorRenderer = props.paginatorRenderer, _k = props.pageSize, pageSize = _k === void 0 ? 25 : _k, _l = props.isResizable, isResizable = _l === void 0 ? false : _l, _m = props.styleType, styleType = _m === void 0 ? 'default' : _m, _o = props.enableVirtualization, enableVirtualization = _o === void 0 ? false : _o, _p = props.enableColumnReordering, enableColumnReordering = _p === void 0 ? false : _p, rest = __rest(props, ["data", "columns", "isLoading", "emptyTableContent", "className", "style", "id", "isSelectable", "onSelect", "onRowClick", "selectionMode", "isSortable", "onSort", "stateReducer", "onBottomReached", "onRowInViewport", "intersectionMargin", "subComponent", "onExpand", "onFilter", "globalFilterValue", "emptyFilteredTableContent", "filterTypes", "expanderCell", "isRowDisabled", "rowProps", "density", "selectSubRows", "getSubRows", "selectRowOnClick", "paginatorRenderer", "pageSize", "isResizable", "styleType", "enableVirtualization", "enableColumnReordering"]);
101
+ var data = props.data, columns = props.columns, _b = props.isLoading, isLoading = _b === void 0 ? false : _b, emptyTableContent = props.emptyTableContent, className = props.className, style = props.style, id = props.id, _c = props.isSelectable, isSelectable = _c === void 0 ? false : _c, onSelect = props.onSelect, onRowClick = props.onRowClick, _d = props.selectionMode, selectionMode = _d === void 0 ? 'multi' : _d, _e = props.isSortable, isSortable = _e === void 0 ? false : _e, onSort = props.onSort, stateReducer = props.stateReducer, onBottomReached = props.onBottomReached, onRowInViewport = props.onRowInViewport, _f = props.intersectionMargin, intersectionMargin = _f === void 0 ? 300 : _f, subComponent = props.subComponent, onExpand = props.onExpand, onFilter = props.onFilter, globalFilterValue = props.globalFilterValue, emptyFilteredTableContent = props.emptyFilteredTableContent, filterFunctions = props.filterTypes, expanderCell = props.expanderCell, isRowDisabled = props.isRowDisabled, rowProps = props.rowProps, _g = props.density, density = _g === void 0 ? 'default' : _g, _h = props.selectSubRows, selectSubRows = _h === void 0 ? true : _h, getSubRows = props.getSubRows, _j = props.selectRowOnClick, selectRowOnClick = _j === void 0 ? true : _j, paginatorRenderer = props.paginatorRenderer, _k = props.pageSize, pageSize = _k === void 0 ? 25 : _k, _l = props.isResizable, isResizable = _l === void 0 ? false : _l, _m = props.columnResizeMode, columnResizeMode = _m === void 0 ? 'fit' : _m, _o = props.styleType, styleType = _o === void 0 ? 'default' : _o, _p = props.enableVirtualization, enableVirtualization = _p === void 0 ? false : _p, _q = props.enableColumnReordering, enableColumnReordering = _q === void 0 ? false : _q, rest = __rest(props, ["data", "columns", "isLoading", "emptyTableContent", "className", "style", "id", "isSelectable", "onSelect", "onRowClick", "selectionMode", "isSortable", "onSort", "stateReducer", "onBottomReached", "onRowInViewport", "intersectionMargin", "subComponent", "onExpand", "onFilter", "globalFilterValue", "emptyFilteredTableContent", "filterTypes", "expanderCell", "isRowDisabled", "rowProps", "density", "selectSubRows", "getSubRows", "selectRowOnClick", "paginatorRenderer", "pageSize", "isResizable", "columnResizeMode", "styleType", "enableVirtualization", "enableColumnReordering"]);
102
102
  useTheme();
103
- var _q = React.useState(), ownerDocument = _q[0], setOwnerDocument = _q[1];
103
+ var ownerDocument = React.useRef();
104
104
  var defaultColumn = React.useMemo(function () { return ({
105
105
  maxWidth: 0,
106
106
  minWidth: 0,
@@ -119,24 +119,26 @@ export var Table = function (props) {
119
119
  }, [columns]);
120
120
  var disableUserSelect = React.useCallback(function (e) {
121
121
  if (e.key === 'Shift') {
122
- ownerDocument &&
123
- (ownerDocument.documentElement.style.userSelect = 'none');
122
+ ownerDocument.current &&
123
+ (ownerDocument.current.documentElement.style.userSelect = 'none');
124
124
  }
125
- }, [ownerDocument]);
125
+ }, []);
126
126
  var enableUserSelect = React.useCallback(function (e) {
127
127
  if (e.key === 'Shift') {
128
- ownerDocument && (ownerDocument.documentElement.style.userSelect = '');
128
+ ownerDocument.current &&
129
+ (ownerDocument.current.documentElement.style.userSelect = '');
129
130
  }
130
- }, [ownerDocument]);
131
+ }, []);
131
132
  React.useEffect(function () {
132
133
  if (!isSelectable || selectionMode !== 'multi') {
133
134
  return;
134
135
  }
135
- ownerDocument === null || ownerDocument === void 0 ? void 0 : ownerDocument.addEventListener('keydown', disableUserSelect);
136
- ownerDocument === null || ownerDocument === void 0 ? void 0 : ownerDocument.addEventListener('keyup', enableUserSelect);
136
+ var ownerDoc = ownerDocument.current;
137
+ ownerDoc === null || ownerDoc === void 0 ? void 0 : ownerDoc.addEventListener('keydown', disableUserSelect);
138
+ ownerDoc === null || ownerDoc === void 0 ? void 0 : ownerDoc.addEventListener('keyup', enableUserSelect);
137
139
  return function () {
138
- ownerDocument === null || ownerDocument === void 0 ? void 0 : ownerDocument.removeEventListener('keydown', disableUserSelect);
139
- ownerDocument === null || ownerDocument === void 0 ? void 0 : ownerDocument.removeEventListener('keyup', enableUserSelect);
140
+ ownerDoc === null || ownerDoc === void 0 ? void 0 : ownerDoc.removeEventListener('keydown', disableUserSelect);
141
+ ownerDoc === null || ownerDoc === void 0 ? void 0 : ownerDoc.removeEventListener('keyup', enableUserSelect);
140
142
  };
141
143
  }, [
142
144
  isSelectable,
@@ -206,7 +208,7 @@ export var Table = function (props) {
206
208
  return getSubRows ? getSubRows(item, index) : item.subRows;
207
209
  });
208
210
  }, [data, getSubRows]);
209
- var instance = 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) }), useFlexLayout, useResizeColumns(ownerDocument), useFilters, useSubRowFiltering(hasAnySubRows), useGlobalFilter, useSortBy, useExpanded, usePagination, useRowSelect, useSubRowSelection, useExpanderCell(subComponent, expanderCell, isRowDisabled), useSelectionCell(isSelectable, selectionMode, isRowDisabled), useColumnOrder, useColumnDragAndDrop(enableColumnReordering), useStickyColumns);
211
+ var instance = 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), columnResizeMode: columnResizeMode }), useFlexLayout, useResizeColumns(ownerDocument), useFilters, useSubRowFiltering(hasAnySubRows), useGlobalFilter, useSortBy, useExpanded, usePagination, useRowSelect, useSubRowSelection, useExpanderCell(subComponent, expanderCell, isRowDisabled), useSelectionCell(isSelectable, selectionMode, isRowDisabled), useColumnOrder, useColumnDragAndDrop(enableColumnReordering), useStickyColumns);
210
212
  var getTableProps = instance.getTableProps, rows = instance.rows, headerGroups = instance.headerGroups, getTableBodyProps = instance.getTableBodyProps, prepareRow = instance.prepareRow, state = instance.state, allColumns = instance.allColumns, dispatch = instance.dispatch, page = instance.page, gotoPage = instance.gotoPage, setPageSize = instance.setPageSize, flatHeaders = instance.flatHeaders, visibleColumns = instance.visibleColumns, setGlobalFilter = instance.setGlobalFilter;
211
213
  var ariaDataAttributes = Object.entries(rest).reduce(function (result, _a) {
212
214
  var key = _a[0], value = _a[1];
@@ -284,6 +286,7 @@ export var Table = function (props) {
284
286
  var previousTableWidth = React.useRef(0);
285
287
  var onTableResize = React.useCallback(function (_a) {
286
288
  var width = _a.width;
289
+ instance.tableWidth = width;
287
290
  if (width === previousTableWidth.current) {
288
291
  return;
289
292
  }
@@ -299,7 +302,7 @@ export var Table = function (props) {
299
302
  return;
300
303
  }
301
304
  dispatch({ type: tableResizeStartAction });
302
- }, [dispatch, state.columnResizing.columnWidths, flatHeaders]);
305
+ }, [dispatch, state.columnResizing.columnWidths, flatHeaders, instance]);
303
306
  var resizeRef = useResizeObserver(onTableResize)[0];
304
307
  // Flexbox handles columns resize so we take new column widths before browser repaints.
305
308
  React.useLayoutEffect(function () {
@@ -315,12 +318,10 @@ export var Table = function (props) {
315
318
  });
316
319
  var headerRef = React.useRef(null);
317
320
  var bodyRef = React.useRef(null);
318
- // Using `useState` to rerender rows when table body ref is available
319
- var _s = React.useState(null), bodyRefState = _s[0], setBodyRefState = _s[1];
320
321
  var getPreparedRow = React.useCallback(function (index) {
321
322
  var row = page[index];
322
323
  prepareRow(row);
323
- return (React.createElement(TableRowMemoized, { row: row, rowProps: rowProps, isLast: index === page.length - 1, onRowInViewport: onRowInViewportRef, onBottomReached: onBottomReachedRef, intersectionMargin: intersectionMargin, state: state, key: row.getRowProps().key, onClick: onRowClickHandler, subComponent: subComponent, isDisabled: !!(isRowDisabled === null || isRowDisabled === void 0 ? void 0 : isRowDisabled(row.original)), tableHasSubRows: hasAnySubRows, tableInstance: instance, expanderCell: expanderCell, bodyRef: bodyRefState, tableRowRef: enableVirtualization ? undefined : tableRowRef(row) }));
324
+ return (React.createElement(TableRowMemoized, { row: row, rowProps: rowProps, isLast: index === page.length - 1, onRowInViewport: onRowInViewportRef, onBottomReached: onBottomReachedRef, intersectionMargin: intersectionMargin, state: state, key: row.getRowProps().key, onClick: onRowClickHandler, subComponent: subComponent, isDisabled: !!(isRowDisabled === null || isRowDisabled === void 0 ? void 0 : isRowDisabled(row.original)), tableHasSubRows: hasAnySubRows, tableInstance: instance, expanderCell: expanderCell, bodyRef: bodyRef.current, tableRowRef: enableVirtualization ? undefined : tableRowRef(row) }));
324
325
  }, [
325
326
  page,
326
327
  prepareRow,
@@ -333,7 +334,6 @@ export var Table = function (props) {
333
334
  hasAnySubRows,
334
335
  instance,
335
336
  expanderCell,
336
- bodyRefState,
337
337
  enableVirtualization,
338
338
  tableRowRef,
339
339
  ]);
@@ -362,9 +362,10 @@ export var Table = function (props) {
362
362
  // Call only on init
363
363
  // eslint-disable-next-line react-hooks/exhaustive-deps
364
364
  }, []);
365
+ var isHeaderDirectClick = React.useRef(false);
365
366
  return (React.createElement(React.Fragment, null,
366
367
  React.createElement("div", __assign({ ref: function (element) {
367
- setOwnerDocument(element === null || element === void 0 ? void 0 : element.ownerDocument);
368
+ ownerDocument.current = element === null || element === void 0 ? void 0 : element.ownerDocument;
368
369
  if (isResizable) {
369
370
  resizeRef(element);
370
371
  }
@@ -383,7 +384,8 @@ export var Table = function (props) {
383
384
  className: 'iui-row',
384
385
  });
385
386
  return (React.createElement("div", __assign({}, headerGroupProps, { key: headerGroupProps.key }), headerGroup.headers.map(function (column, index) {
386
- var columnProps = column.getHeaderProps(__assign(__assign({}, column.getSortByToggleProps()), { className: cx('iui-cell', {
387
+ var _a = column.getSortByToggleProps(), onClick = _a.onClick, restSortProps = __rest(_a, ["onClick"]);
388
+ var columnProps = column.getHeaderProps(__assign(__assign({}, restSortProps), { className: cx('iui-cell', {
387
389
  'iui-actionable': column.canSort,
388
390
  'iui-sorted': column.isSorted,
389
391
  'iui-cell-sticky': !!column.sticky,
@@ -393,16 +395,25 @@ export var Table = function (props) {
393
395
  columnRefs.current[column.id] = el;
394
396
  column.resizeWidth = el.getBoundingClientRect().width;
395
397
  }
398
+ }, onMouseDown: function () {
399
+ isHeaderDirectClick.current = true;
400
+ }, onClick: function (e) {
401
+ // Prevents from triggering sort when resizing and mouse is released in the middle of header
402
+ if (isHeaderDirectClick.current) {
403
+ onClick === null || onClick === void 0 ? void 0 : onClick(e);
404
+ isHeaderDirectClick.current = false;
405
+ }
396
406
  } }),
397
407
  column.render('Header'),
398
408
  (showFilterButton(column) ||
399
409
  showSortButton(column)) && (React.createElement("div", { className: 'iui-table-header-actions-container' },
400
- showFilterButton(column) && (React.createElement(FilterToggle, { column: column, ownerDocument: ownerDocument })),
410
+ showFilterButton(column) && (React.createElement(FilterToggle, { column: column })),
401
411
  showSortButton(column) && (React.createElement("div", { className: 'iui-cell-end-icon' }, column.isSortedDesc ||
402
412
  (!column.isSorted && column.sortDescFirst) ? (React.createElement(SvgSortDown, { className: 'iui-icon iui-sort', "aria-hidden": true })) : (React.createElement(SvgSortUp, { className: 'iui-icon iui-sort', "aria-hidden": true })))))),
403
413
  isResizable &&
404
414
  column.isResizerVisible &&
405
- index !== headerGroup.headers.length - 1 && (React.createElement("div", __assign({}, column.getResizerProps(), { className: 'iui-resizer' }),
415
+ (index !== headerGroup.headers.length - 1 ||
416
+ columnResizeMode === 'expand') && (React.createElement("div", __assign({}, column.getResizerProps(), { className: 'iui-resizer' }),
406
417
  React.createElement("div", { className: 'iui-resizer-bar' }))),
407
418
  enableColumnReordering &&
408
419
  !column.disableReordering && (React.createElement("div", { className: 'iui-reorder-bar' })),
@@ -417,7 +428,7 @@ export var Table = function (props) {
417
428
  'iui-zebra-striping': styleType === 'zebra-rows',
418
429
  }),
419
430
  style: { outline: 0 },
420
- }), { ref: mergeRefs(bodyRef, setBodyRefState), onScroll: function () {
431
+ }), { ref: bodyRef, onScroll: function () {
421
432
  if (headerRef.current && bodyRef.current) {
422
433
  headerRef.current.scrollLeft = bodyRef.current.scrollLeft;
423
434
  updateStickyState();
@@ -4,7 +4,6 @@ import '@itwin/itwinui-css/css/table.css';
4
4
  import { StylingProps } from '../../utils';
5
5
  export declare type FilterToggleProps<T extends Record<string, unknown>> = {
6
6
  column: HeaderGroup<T>;
7
- ownerDocument?: Document;
8
7
  } & StylingProps;
9
8
  /**
10
9
  * Handles showing filter icon and opening filter component.
@@ -29,15 +29,15 @@ import SvgFilter from '@itwin/itwinui-icons-react/cjs/icons/Filter';
29
29
  import React from 'react';
30
30
  import cx from 'classnames';
31
31
  import '@itwin/itwinui-css/css/table.css';
32
- import { useTheme, Popover, getDocument } from '../../utils';
32
+ import { useTheme, Popover } from '../../utils';
33
33
  import { IconButton } from '../../Buttons';
34
34
  /**
35
35
  * Handles showing filter icon and opening filter component.
36
36
  */
37
37
  export var FilterToggle = function (props) {
38
- var column = props.column, _a = props.ownerDocument, ownerDocument = _a === void 0 ? getDocument() : _a, className = props.className, rest = __rest(props, ["column", "ownerDocument", "className"]);
38
+ var column = props.column, className = props.className, rest = __rest(props, ["column", "className"]);
39
39
  useTheme();
40
- var _b = React.useState(false), isVisible = _b[0], setIsVisible = _b[1];
40
+ var _a = React.useState(false), isVisible = _a[0], setIsVisible = _a[1];
41
41
  var close = React.useCallback(function () { return setIsVisible(false); }, []);
42
42
  var setFilter = React.useCallback(function (filterValue) {
43
43
  column.setFilter(filterValue);
@@ -48,7 +48,7 @@ export var FilterToggle = function (props) {
48
48
  close();
49
49
  }, [close, column]);
50
50
  var isColumnFiltered = column.filterValue != null && column.filterValue !== '';
51
- return (React.createElement(React.Fragment, null, column.canFilter && column.Filter && (React.createElement(Popover, { content: column.render('Filter', { close: close, setFilter: setFilter, clearFilter: clearFilter }), placement: 'bottom-start', visible: isVisible, onClickOutside: close, appendTo: ownerDocument === null || ownerDocument === void 0 ? void 0 : ownerDocument.body },
51
+ return (React.createElement(React.Fragment, null, column.canFilter && column.Filter && (React.createElement(Popover, { content: column.render('Filter', { close: close, setFilter: setFilter, clearFilter: clearFilter }), placement: 'bottom-start', visible: isVisible, onClickOutside: close },
52
52
  React.createElement(IconButton, __assign({ styleType: 'borderless', isActive: isVisible || isColumnFiltered, className: cx('iui-filter-button', className), onClick: function (e) {
53
53
  setIsVisible(function (v) { return !v; });
54
54
  // Prevents from triggering sort
@@ -1,5 +1,37 @@
1
+ /**
2
+ * Copied from react-table as useResizeColumns and made some changes:
3
+ * - Added TS typings
4
+ * - Added sibling/next column resize when resizing
5
+ * - Favoring min/max widths when resizing
6
+ * - Added owner document support
7
+ * @link https://github.com/tannerlinsley/react-table/blob/master/src/plugin-hooks/useResizeColumns.js
8
+ */
9
+ /**
10
+ * MIT License
11
+ *
12
+ * Copyright (c) 2016 Tanner Linsley
13
+ *
14
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
15
+ * of this software and associated documentation files (the "Software"), to deal
16
+ * in the Software without restriction, including without limitation the rights
17
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18
+ * copies of the Software, and to permit persons to whom the Software is
19
+ * furnished to do so, subject to the following conditions:
20
+ *
21
+ * The above copyright notice and this permission notice shall be included in all
22
+ * copies or substantial portions of the Software.
23
+ *
24
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30
+ * SOFTWARE.
31
+ */
32
+ import React from 'react';
1
33
  import { Hooks } from 'react-table';
2
34
  export declare const useResizeColumns: {
3
- <T extends Record<string, unknown>>(ownerDocument: Document | undefined): (hooks: Hooks<T>) => void;
35
+ <T extends Record<string, unknown>>(ownerDocument: React.RefObject<Document | undefined>): (hooks: Hooks<T>) => void;
4
36
  pluginName: string;
5
37
  };
@@ -29,24 +29,19 @@ var isTouchEvent = function (event) {
29
29
  };
30
30
  var defaultGetResizerProps = function (ownerDocument) { return function (props, _a) {
31
31
  var instance = _a.instance, header = _a.header, nextHeader = _a.nextHeader;
32
- if (!ownerDocument) {
33
- return props;
34
- }
35
- var dispatch = instance.dispatch, flatHeaders = instance.flatHeaders;
32
+ var dispatch = instance.dispatch;
36
33
  var onResizeStart = function (e, header) {
34
+ var _a, _b, _c;
37
35
  // lets not respond to multiple touches (e.g. 2 or 3 fingers)
38
36
  if (isTouchEvent(e) && e.touches && e.touches.length > 1) {
39
37
  return;
40
38
  }
41
- // Setting `width` here because it might take several rerenders until actual column width is set.
42
- flatHeaders.forEach(function (h) {
43
- if (!h.width) {
44
- h.width = h.resizeWidth;
45
- }
46
- });
47
- var headerIdWidths = getLeafHeaders(header).map(function (d) { return [d.id, d.width]; });
39
+ var headerIdWidths = getLeafHeaders(header).map(function (d) { return [
40
+ d.id,
41
+ getHeaderWidth(d),
42
+ ]; });
48
43
  var nextHeaderIdWidths = nextHeader
49
- ? getLeafHeaders(nextHeader).map(function (d) { return [d.id, d.width]; })
44
+ ? getLeafHeaders(nextHeader).map(function (d) { return [d.id, getHeaderWidth(d)]; })
50
45
  : [];
51
46
  var clientX = isTouchEvent(e)
52
47
  ? Math.round(e.touches[0].clientX)
@@ -65,8 +60,10 @@ var defaultGetResizerProps = function (ownerDocument) { return function (props,
65
60
  moveHandler: function (e) { return dispatchMove(e.clientX); },
66
61
  upEvent: 'mouseup',
67
62
  upHandler: function () {
68
- ownerDocument.removeEventListener('mousemove', handlersAndEvents.mouse.moveHandler);
69
- ownerDocument.removeEventListener('mouseup', handlersAndEvents.mouse.upHandler);
63
+ var _a, _b, _c;
64
+ (_a = ownerDocument.current) === null || _a === void 0 ? void 0 : _a.removeEventListener('mousemove', handlersAndEvents.mouse.moveHandler);
65
+ (_b = ownerDocument.current) === null || _b === void 0 ? void 0 : _b.removeEventListener('mouseup', handlersAndEvents.mouse.upHandler);
66
+ (_c = ownerDocument.current) === null || _c === void 0 ? void 0 : _c.removeEventListener('mouseleave', handlersAndEvents.mouse.upHandler);
70
67
  dispatchEnd();
71
68
  },
72
69
  },
@@ -81,8 +78,9 @@ var defaultGetResizerProps = function (ownerDocument) { return function (props,
81
78
  },
82
79
  upEvent: 'touchend',
83
80
  upHandler: function () {
84
- ownerDocument.removeEventListener(handlersAndEvents.touch.moveEvent, handlersAndEvents.touch.moveHandler);
85
- ownerDocument.removeEventListener(handlersAndEvents.touch.upEvent, handlersAndEvents.touch.moveHandler);
81
+ var _a, _b;
82
+ (_a = ownerDocument.current) === null || _a === void 0 ? void 0 : _a.removeEventListener(handlersAndEvents.touch.moveEvent, handlersAndEvents.touch.moveHandler);
83
+ (_b = ownerDocument.current) === null || _b === void 0 ? void 0 : _b.removeEventListener(handlersAndEvents.touch.upEvent, handlersAndEvents.touch.moveHandler);
86
84
  dispatchEnd();
87
85
  },
88
86
  },
@@ -93,13 +91,16 @@ var defaultGetResizerProps = function (ownerDocument) { return function (props,
93
91
  var passiveIfSupported = passiveEventSupported()
94
92
  ? { passive: false }
95
93
  : false;
96
- ownerDocument.addEventListener(events.moveEvent, events.moveHandler, passiveIfSupported);
97
- ownerDocument.addEventListener(events.upEvent, events.upHandler, passiveIfSupported);
94
+ (_a = ownerDocument.current) === null || _a === void 0 ? void 0 : _a.addEventListener(events.moveEvent, events.moveHandler, passiveIfSupported);
95
+ (_b = ownerDocument.current) === null || _b === void 0 ? void 0 : _b.addEventListener(events.upEvent, events.upHandler, passiveIfSupported);
96
+ if (!isTouchEvent(e)) {
97
+ (_c = ownerDocument.current) === null || _c === void 0 ? void 0 : _c.addEventListener('mouseleave', handlersAndEvents.mouse.upHandler, passiveIfSupported);
98
+ }
98
99
  dispatch({
99
100
  type: actions.columnStartResizing,
100
101
  columnId: header.id,
101
- columnWidth: header.width,
102
- nextColumnWidth: nextHeader === null || nextHeader === void 0 ? void 0 : nextHeader.width,
102
+ columnWidth: getHeaderWidth(header),
103
+ nextColumnWidth: getHeaderWidth(nextHeader),
103
104
  headerIdWidths: headerIdWidths,
104
105
  nextHeaderIdWidths: nextHeaderIdWidths,
105
106
  clientX: clientX,
@@ -116,6 +117,8 @@ var defaultGetResizerProps = function (ownerDocument) { return function (props,
116
117
  e.persist();
117
118
  // Prevents from triggering drag'n'drop
118
119
  e.preventDefault();
120
+ // Prevents from triggering sort
121
+ e.stopPropagation();
119
122
  onResizeStart(e, header);
120
123
  },
121
124
  onTouchStart: function (e) {
@@ -151,13 +154,29 @@ var reducer = function (newState, action, previousState, instance) {
151
154
  if (action.type === actions.columnResizing) {
152
155
  var clientX = action.clientX;
153
156
  var _a = newState.columnResizing, _b = _a.startX, startX = _b === void 0 ? 0 : _b, _c = _a.columnWidth, columnWidth = _c === void 0 ? 1 : _c, _d = _a.nextColumnWidth, nextColumnWidth = _d === void 0 ? 1 : _d, _e = _a.headerIdWidths, headerIdWidths = _e === void 0 ? [] : _e, _f = _a.nextHeaderIdWidths, nextHeaderIdWidths = _f === void 0 ? [] : _f;
157
+ if (!instance) {
158
+ return newState;
159
+ }
154
160
  var deltaX = clientX - startX;
155
161
  var newColumnWidths = getColumnWidths(headerIdWidths, deltaX / columnWidth);
156
- var newNextColumnWidths = getColumnWidths(nextHeaderIdWidths, -deltaX / nextColumnWidth);
157
- if (!isNewColumnWidthsValid(newColumnWidths, instance === null || instance === void 0 ? void 0 : instance.flatHeaders) ||
158
- !isNewColumnWidthsValid(newNextColumnWidths, instance === null || instance === void 0 ? void 0 : instance.flatHeaders)) {
162
+ var isTableWidthDecreasing = calculateTableWidth(newColumnWidths, instance.flatHeaders) <
163
+ instance.tableWidth;
164
+ var newNextColumnWidths = (instance === null || instance === void 0 ? void 0 : instance.columnResizeMode) === 'fit' ||
165
+ ((instance === null || instance === void 0 ? void 0 : instance.columnResizeMode) === 'expand' && isTableWidthDecreasing)
166
+ ? getColumnWidths(nextHeaderIdWidths, -deltaX / nextColumnWidth)
167
+ : {};
168
+ if (!isNewColumnWidthsValid(newColumnWidths, instance.flatHeaders) ||
169
+ !isNewColumnWidthsValid(newNextColumnWidths, instance.flatHeaders) ||
170
+ !isNewTableWidthValid(__assign(__assign({}, newColumnWidths), newNextColumnWidths), instance)) {
159
171
  return newState;
160
172
  }
173
+ // Setting `width` here because it might take several rerenders until actual column width is set.
174
+ // Also setting after the actual resize happened.
175
+ instance === null || instance === void 0 ? void 0 : instance.flatHeaders.forEach(function (h) {
176
+ if (!h.width) {
177
+ h.width = h.resizeWidth;
178
+ }
179
+ });
161
180
  return __assign(__assign({}, newState), { columnResizing: __assign(__assign({}, newState.columnResizing), { columnWidths: __assign(__assign(__assign({}, newState.columnResizing.columnWidths), newColumnWidths), newNextColumnWidths) }) });
162
181
  }
163
182
  if (action.type === actions.columnDoneResizing) {
@@ -197,25 +216,53 @@ var isNewColumnWidthsValid = function (columnWidths, headers) {
197
216
  }
198
217
  return true;
199
218
  };
219
+ var isNewTableWidthValid = function (columnWidths, instance) {
220
+ if (instance.columnResizeMode === 'fit') {
221
+ return true;
222
+ }
223
+ var newTableWidth = 0;
224
+ for (var _i = 0, _a = instance.flatHeaders; _i < _a.length; _i++) {
225
+ var header = _a[_i];
226
+ newTableWidth += columnWidths[header.id]
227
+ ? columnWidths[header.id]
228
+ : getHeaderWidth(header);
229
+ }
230
+ // `tableWidth` is whole number therefore we need to round the `newTableWidth`
231
+ if (Math.round(newTableWidth) < instance.tableWidth) {
232
+ return false;
233
+ }
234
+ return true;
235
+ };
200
236
  var useInstanceBeforeDimensions = function (instance) {
201
- var flatHeaders = instance.flatHeaders, getHooks = instance.getHooks, columnResizing = instance.state.columnResizing;
237
+ var flatHeaders = instance.flatHeaders, getHooks = instance.getHooks, columnResizing = instance.state.columnResizing, columnResizeMode = instance.columnResizeMode;
202
238
  var getInstance = useGetLatest(instance);
203
239
  flatHeaders.forEach(function (header, index) {
204
240
  var _a;
205
241
  var resizeWidth = columnResizing.columnWidths[header.id];
206
242
  header.width = resizeWidth || header.width || header.originalWidth;
207
243
  header.isResizing = columnResizing.isResizingColumn === header.id;
208
- var headerToResize = header.disableResizing
244
+ var headerToResize = header.disableResizing && columnResizeMode === 'fit'
209
245
  ? getPreviousResizableHeader(header, instance)
210
246
  : header;
211
- var nextResizableHeader = getNextResizableHeader(header, instance);
247
+ // When `columnResizeMode` is `expand` and it is a last column,
248
+ // then try to find some column on the left side to resize
249
+ // when table width is decreasing.
250
+ var nextResizableHeader = columnResizeMode === 'expand' && index === flatHeaders.length - 1
251
+ ? getPreviousResizableHeader(header, instance)
252
+ : getNextResizableHeader(header, instance);
212
253
  header.canResize =
213
254
  header.disableResizing != null ? !header.disableResizing : true;
214
255
  // Show resizer when header is resizable or when next header is resizable
215
256
  // and there is resizable columns on the left side of the resizer.
216
- header.isResizerVisible =
217
- (header.canResize && !!nextResizableHeader) ||
218
- (headerToResize && !!((_a = instance.flatHeaders[index + 1]) === null || _a === void 0 ? void 0 : _a.canResize));
257
+ if (columnResizeMode === 'fit') {
258
+ header.isResizerVisible =
259
+ (header.canResize && !!nextResizableHeader) ||
260
+ (headerToResize && !!((_a = instance.flatHeaders[index + 1]) === null || _a === void 0 ? void 0 : _a.canResize));
261
+ // When resize mode is `expand` show resizer on the current resizable column.
262
+ }
263
+ else {
264
+ header.isResizerVisible = header.canResize && !!headerToResize;
265
+ }
219
266
  header.getResizerProps = makePropGetter(getHooks().getResizerProps, {
220
267
  instance: getInstance(),
221
268
  header: headerToResize,
@@ -255,6 +302,19 @@ function getLeafHeaders(header) {
255
302
  recurseHeader(header);
256
303
  return leafHeaders;
257
304
  }
305
+ var getHeaderWidth = function (header) {
306
+ return Number(header.width || header.resizeWidth || 0);
307
+ };
308
+ var calculateTableWidth = function (columnWidths, headers) {
309
+ var newTableWidth = 0;
310
+ for (var _i = 0, headers_1 = headers; _i < headers_1.length; _i++) {
311
+ var header = headers_1[_i];
312
+ newTableWidth += columnWidths[header.id]
313
+ ? columnWidths[header.id]
314
+ : getHeaderWidth(header);
315
+ }
316
+ return newTableWidth;
317
+ };
258
318
  // https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#safely_detecting_option_support
259
319
  var passiveSupported = null;
260
320
  var passiveEventSupported = function () {
@@ -28,11 +28,22 @@ declare module 'react-table' {
28
28
  * If some rows don't have sub-data, it is recommended to pass an empty array to `subRows` for consistent spacing.
29
29
  */
30
30
  data: D[];
31
+ /**
32
+ * Column's resize mode.
33
+ * - `fit` - when resizing it affects current and the next column,
34
+ * e.g. when increasing width of current column, next column's width will decrease.
35
+ * - `expand` - when resizing it affects only the current column,
36
+ * e.g. when increasing width of the current column, next column's width remains the same.
37
+ * @default 'fit'
38
+ */
39
+ columnResizeMode?: 'fit' | 'expand';
31
40
  }
32
41
  interface Hooks<D extends object = {}> extends UseExpandedHooks<D>, UseGroupByHooks<D>, UseRowSelectHooks<D>, UseSortByHooks<D> {
33
42
  }
34
43
  interface TableInstance<D extends object = {}> extends UseColumnOrderInstanceProps<D>, UseExpandedInstanceProps<D>, UseFiltersInstanceProps<D>, UseGlobalFiltersInstanceProps<D>, UseGroupByInstanceProps<D>, UsePaginationInstanceProps<D>, UseRowSelectInstanceProps<D>, UseRowStateInstanceProps<D>, UseSortByInstanceProps<D> {
35
44
  initialRows: Row<D>[];
45
+ columnResizeMode: TableOptions['columnResizeMode'];
46
+ tableWidth: number;
36
47
  }
37
48
  interface TableState<D extends object = {}> extends UseColumnOrderState<D>, UseExpandedState<D>, UseFiltersState<D>, UseGlobalFiltersState<D>, UseGroupByState<D>, UsePaginationState<D>, UseRowSelectState<D>, UseRowStateState<D>, UseSortByState<D> {
38
49
  columnResizing: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itwin/itwinui-react",
3
- "version": "1.46.0",
3
+ "version": "1.47.0",
4
4
  "author": "Bentley Systems",
5
5
  "license": "MIT",
6
6
  "main": "cjs/index.js",