@itwin/itwinui-react 2.4.4 → 2.5.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 (33) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/README.md +2 -2
  3. package/cjs/core/Table/SubRowExpander.d.ts +1 -0
  4. package/cjs/core/Table/SubRowExpander.js +4 -2
  5. package/cjs/core/Table/Table.js +20 -4
  6. package/cjs/core/Table/TableCell.d.ts +1 -0
  7. package/cjs/core/Table/TableCell.js +15 -4
  8. package/cjs/core/Table/TableRowMemoized.d.ts +2 -0
  9. package/cjs/core/Table/TableRowMemoized.js +4 -3
  10. package/cjs/core/Table/columns/selectionColumn.d.ts +1 -0
  11. package/cjs/core/Table/columns/selectionColumn.js +5 -4
  12. package/cjs/core/Table/filters/types.d.ts +1 -1
  13. package/cjs/core/Table/hooks/useSelectionCell.d.ts +1 -1
  14. package/cjs/core/Table/hooks/useSelectionCell.js +5 -2
  15. package/cjs/core/ThemeProvider/ThemeProvider.d.ts +11 -1
  16. package/cjs/core/ThemeProvider/ThemeProvider.js +9 -6
  17. package/cjs/types/react-table-config.d.ts +6 -3
  18. package/esm/core/Table/SubRowExpander.d.ts +1 -0
  19. package/esm/core/Table/SubRowExpander.js +4 -2
  20. package/esm/core/Table/Table.js +20 -4
  21. package/esm/core/Table/TableCell.d.ts +1 -0
  22. package/esm/core/Table/TableCell.js +15 -4
  23. package/esm/core/Table/TableRowMemoized.d.ts +2 -0
  24. package/esm/core/Table/TableRowMemoized.js +4 -3
  25. package/esm/core/Table/columns/selectionColumn.d.ts +1 -0
  26. package/esm/core/Table/columns/selectionColumn.js +5 -4
  27. package/esm/core/Table/filters/types.d.ts +1 -1
  28. package/esm/core/Table/hooks/useSelectionCell.d.ts +1 -1
  29. package/esm/core/Table/hooks/useSelectionCell.js +5 -2
  30. package/esm/core/ThemeProvider/ThemeProvider.d.ts +11 -1
  31. package/esm/core/ThemeProvider/ThemeProvider.js +9 -6
  32. package/esm/types/react-table-config.d.ts +6 -3
  33. package/package.json +3 -3
package/CHANGELOG.md CHANGED
@@ -1,5 +1,51 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.5.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 9ad85ff2: The different density settings for table will now also affect horizontal spacing.
8
+
9
+ ## 2.5.0
10
+
11
+ ### Minor Changes
12
+
13
+ - 7e3a17f9: Table: Reintroduced the ability to pass a top-level Header property in the columns objects. This improves compatibility with the previous major version. There will be a warning shown only in dev environments to encourage using the new columns format.
14
+ - 2397ee0c: All styles will now be scoped and always take preference over previous major versions (`@itwin/itwinui-react`@`1.x`).
15
+
16
+ This enables incremental adoption of `@itwin/itwinui-react`@`2.x` for some parts of the app, while still using `1.x` for the rest of the app.
17
+
18
+ To use this feature, make sure that all parts that use v1 are updated to `@itwin/itwinui-css@0.63.2`, and then wrap the v2 parts in `ThemeProvider`:
19
+
20
+ ```html
21
+ <body>
22
+ <!-- rest of your app (v1) -->
23
+
24
+ <ThemeProvider>
25
+ <!-- new UI built using v2 -->
26
+ </ThemeProvider>
27
+ </body>
28
+ ```
29
+
30
+ For packages, there is a new theme `'inherit'`. Setting this enables scoping without forcing the default light theme. When the app eventually updates to v2, it can use its own `ThemeProvider` with any theme, and the components inside your package will inherit the app's theme.
31
+
32
+ ```html
33
+ <body>
34
+ <!-- rest of the app (maybe v1) -->
35
+
36
+ <!-- inside your package ⬇️ -->
37
+ <ThemeProvider theme='inherit'>
38
+ <!-- v2 components inside package -->
39
+ </ThemeProvider>
40
+ </bod
41
+ ```
42
+
43
+ ### Patch Changes
44
+
45
+ - Updated dependencies
46
+ - @itwin/itwinui-variables@2.0.0
47
+ - @itwin/itwinui-css@1.6.0
48
+
3
49
  ## 2.4.4
4
50
 
5
51
  ### Patch Changes
package/README.md CHANGED
@@ -23,7 +23,7 @@
23
23
  ## What is iTwinUI-react?
24
24
 
25
25
  iTwinUI-react is a React component library for [iTwinUI](https://github.com/iTwin/iTwinUI).
26
- The goal of this package is to provide React components that make it easier to use the styles from [`@itwin/itwinui-css`](https://github.com/iTwin/iTwinUI/tree/main/packages/itwinui-css). Check out the [demo website](https://itwin.github.io/iTwinUI-react) to see the components in action.
26
+ The goal of this package is to provide React components that make it easier to use the styles from [`@itwin/itwinui-css`](https://github.com/iTwin/iTwinUI/tree/main/packages/itwinui-css). Check out the [demo website](https://itwin.github.io/iTwinUI/react) to see the components in action.
27
27
 
28
28
  ---
29
29
 
@@ -53,7 +53,7 @@ const App = () => (
53
53
 
54
54
  Yes, that's really all you need as you can see in this live interactive demo:
55
55
 
56
- [![Edit Button](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/itwinui-react-minimal-example-xq2t3)
56
+ [![Edit in CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/s/github/iTwin/iTwinUI/tree/main/playgrounds/cra?file=/src/App.jsx)
57
57
 
58
58
  ---
59
59
 
@@ -5,6 +5,7 @@ export declare type SubRowExpanderProps<T extends Record<string, unknown>> = {
5
5
  expanderCell?: (cellProps: CellProps<T>) => React.ReactNode;
6
6
  isDisabled: boolean;
7
7
  cellProps: CellProps<T>;
8
+ density?: 'default' | 'condensed' | 'extra-condensed';
8
9
  };
9
10
  export declare const SubRowExpander: <T extends Record<string, unknown>>(props: SubRowExpanderProps<T>) => JSX.Element;
10
11
  export default SubRowExpander;
@@ -12,8 +12,10 @@ const react_1 = __importDefault(require("react"));
12
12
  const utils_1 = require("../utils");
13
13
  const Buttons_1 = require("../Buttons");
14
14
  const SubRowExpander = (props) => {
15
- const { cell, isDisabled, cellProps, expanderCell } = props;
16
- return (react_1.default.createElement(react_1.default.Fragment, null, expanderCell ? (expanderCell(cellProps)) : (react_1.default.createElement(Buttons_1.IconButton, { style: { marginRight: 8 }, className: 'iui-table-row-expander', styleType: 'borderless', size: 'small', onClick: (e) => {
15
+ const { cell, isDisabled, cellProps, expanderCell, density } = props;
16
+ return (react_1.default.createElement(react_1.default.Fragment, null, expanderCell ? (expanderCell(cellProps)) : (react_1.default.createElement(Buttons_1.IconButton, { style: {
17
+ marginRight: density === 'default' || density === undefined ? 8 : 4,
18
+ }, className: 'iui-table-row-expander', styleType: 'borderless', size: 'small', onClick: (e) => {
17
19
  e.stopPropagation();
18
20
  cell.row.toggleRowExpanded();
19
21
  }, disabled: isDisabled }, react_1.default.createElement(utils_1.SvgChevronRight, { style: {
@@ -26,11 +26,18 @@ const singleRowSelectedAction = 'singleRowSelected';
26
26
  const shiftRowSelectedAction = 'shiftRowSelected';
27
27
  exports.tableResizeStartAction = 'tableResizeStart';
28
28
  const tableResizeEndAction = 'tableResizeEnd';
29
+ let didLogWarning = false;
30
+ let isDev = false;
31
+ // wrapping in try-catch because process might be undefined
32
+ try {
33
+ isDev = process.env.NODE_ENV !== 'production';
34
+ }
35
+ catch (_a) { }
29
36
  const flattenColumns = (columns) => {
30
37
  const flatColumns = [];
31
38
  columns.forEach((column) => {
32
39
  flatColumns.push(column);
33
- if (column.columns) {
40
+ if ('columns' in column) {
34
41
  flatColumns.push(...flattenColumns(column.columns));
35
42
  }
36
43
  });
@@ -197,8 +204,16 @@ const Table = (props) => {
197
204
  getSubRows,
198
205
  initialState: { pageSize, ...props.initialState },
199
206
  columnResizeMode,
200
- }, 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);
201
- const { getTableProps, rows, headerGroups, getTableBodyProps, prepareRow, state, allColumns, dispatch, page, gotoPage, setPageSize, flatHeaders, visibleColumns, setGlobalFilter, } = instance;
207
+ }, 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, density), react_table_1.useColumnOrder, (0, hooks_1.useColumnDragAndDrop)(enableColumnReordering), hooks_1.useStickyColumns);
208
+ const { getTableProps, rows, headerGroups: _headerGroups, getTableBodyProps, prepareRow, state, allColumns, dispatch, page, gotoPage, setPageSize, flatHeaders, visibleColumns, setGlobalFilter, } = instance;
209
+ let headerGroups = _headerGroups;
210
+ if (columns.length === 1 && 'columns' in columns[0]) {
211
+ headerGroups = _headerGroups.slice(1);
212
+ if (isDev && !didLogWarning) {
213
+ console.warn(`Table's \`columns\` prop should not have a top-level \`Header\` or sub-columns. They are only allowed to be passed for backwards compatibility.\n See https://github.com/iTwin/iTwinUI/wiki/iTwinUI-react-v2-migration-guide#breaking-changes`);
214
+ didLogWarning = true;
215
+ }
216
+ }
202
217
  const ariaDataAttributes = Object.entries(rest).reduce((result, [key, value]) => {
203
218
  if (key.startsWith('data-') || key.startsWith('aria-')) {
204
219
  result[key] = value;
@@ -327,7 +342,7 @@ const Table = (props) => {
327
342
  const getPreparedRow = react_1.default.useCallback((index) => {
328
343
  const row = page[index];
329
344
  prepareRow(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) }));
345
+ 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), density: density }));
331
346
  }, [
332
347
  page,
333
348
  prepareRow,
@@ -342,6 +357,7 @@ const Table = (props) => {
342
357
  expanderCell,
343
358
  enableVirtualization,
344
359
  tableRowRef,
360
+ density,
345
361
  ]);
346
362
  const virtualizedItemRenderer = react_1.default.useCallback((index) => getPreparedRow(index), [getPreparedRow]);
347
363
  const updateStickyState = () => {
@@ -7,6 +7,7 @@ export declare type TableCellProps<T extends Record<string, unknown>> = {
7
7
  tableHasSubRows: boolean;
8
8
  tableInstance: TableInstance<T>;
9
9
  expanderCell?: (cellProps: CellProps<T>) => React.ReactNode;
10
+ density?: 'default' | 'condensed' | 'extra-condensed';
10
11
  };
11
12
  export declare const TableCell: <T extends Record<string, unknown>>(props: TableCellProps<T>) => JSX.Element;
12
13
  export default TableCell;
@@ -15,7 +15,7 @@ const SubRowExpander_1 = require("./SubRowExpander");
15
15
  const columns_1 = require("./columns");
16
16
  const cells_1 = require("./cells");
17
17
  const TableCell = (props) => {
18
- const { cell, cellIndex, isDisabled, tableHasSubRows, tableInstance, expanderCell, } = props;
18
+ const { cell, cellIndex, isDisabled, tableHasSubRows, tableInstance, expanderCell, density, } = props;
19
19
  const hasSubRowExpander = cellIndex ===
20
20
  cell.row.cells.findIndex((c) => c.column.id !== columns_1.SELECTION_CELL_ID);
21
21
  const getSubRowStyle = () => {
@@ -23,9 +23,20 @@ const TableCell = (props) => {
23
23
  return undefined;
24
24
  }
25
25
  // If it doesn't have sub-rows then shift by another level to align with expandable rows on the same depth
26
- // 16 = initial_cell_padding, 35 = 27 + 8 = expander_width + margin
26
+ const dynamicMargin = cell.row.depth + (cell.row.canExpand ? 0 : 1);
27
+ let cellPadding = 16;
28
+ let expanderMargin = 8;
29
+ if (density === 'condensed') {
30
+ cellPadding = 12;
31
+ expanderMargin = 4;
32
+ }
33
+ else if (density === 'extra-condensed') {
34
+ cellPadding = 8;
35
+ expanderMargin = 4;
36
+ }
37
+ const multiplier = 26 + expanderMargin; // 26 = expander width
27
38
  return {
28
- paddingLeft: 16 + (cell.row.depth + (cell.row.canExpand ? 0 : 1)) * 35,
39
+ paddingLeft: cellPadding + dynamicMargin * multiplier,
29
40
  };
30
41
  };
31
42
  const cellElementProps = cell.getCellProps({
@@ -43,7 +54,7 @@ const TableCell = (props) => {
43
54
  ...{ cell, row: cell.row, value: cell.value, column: cell.column },
44
55
  };
45
56
  const cellContent = (react_1.default.createElement(react_1.default.Fragment, null,
46
- tableHasSubRows && hasSubRowExpander && cell.row.canExpand && (react_1.default.createElement(SubRowExpander_1.SubRowExpander, { cell: cell, isDisabled: isDisabled, cellProps: cellProps, expanderCell: expanderCell })),
57
+ tableHasSubRows && hasSubRowExpander && cell.row.canExpand && (react_1.default.createElement(SubRowExpander_1.SubRowExpander, { cell: cell, isDisabled: isDisabled, cellProps: cellProps, expanderCell: expanderCell, density: density })),
47
58
  cell.render('Cell')));
48
59
  const cellRendererProps = {
49
60
  cellElementProps,
@@ -25,6 +25,7 @@ export declare const TableRow: <T extends Record<string, unknown>>(props: {
25
25
  expanderCell?: ((cellProps: CellProps<T, any>) => React.ReactNode) | undefined;
26
26
  bodyRef: HTMLDivElement | null;
27
27
  tableRowRef?: React.Ref<HTMLDivElement> | undefined;
28
+ density?: "default" | "condensed" | "extra-condensed" | undefined;
28
29
  }) => JSX.Element;
29
30
  export declare const TableRowMemoized: <T extends Record<string, unknown>>(props: {
30
31
  row: Row<T>;
@@ -45,4 +46,5 @@ export declare const TableRowMemoized: <T extends Record<string, unknown>>(props
45
46
  expanderCell?: ((cellProps: CellProps<T, any>) => React.ReactNode) | undefined;
46
47
  bodyRef: HTMLDivElement | null;
47
48
  tableRowRef?: React.Ref<HTMLDivElement> | undefined;
49
+ density?: "default" | "condensed" | "extra-condensed" | undefined;
48
50
  }) => JSX.Element;
@@ -20,7 +20,7 @@ const TableCell_1 = require("./TableCell");
20
20
  */
21
21
  const TableRow = (props) => {
22
22
  var _a;
23
- const { row, rowProps, isLast, onRowInViewport, onBottomReached, intersectionMargin, onClick, subComponent, isDisabled, tableHasSubRows, tableInstance, expanderCell, bodyRef, tableRowRef, } = props;
23
+ const { row, rowProps, isLast, onRowInViewport, onBottomReached, intersectionMargin, onClick, subComponent, isDisabled, tableHasSubRows, tableInstance, expanderCell, bodyRef, tableRowRef, density, } = props;
24
24
  const onIntersect = react_1.default.useCallback(() => {
25
25
  var _a, _b;
26
26
  (_a = onRowInViewport.current) === null || _a === void 0 ? void 0 : _a.call(onRowInViewport, row.original);
@@ -62,7 +62,7 @@ const TableRow = (props) => {
62
62
  (_a = mergedProps === null || mergedProps === void 0 ? void 0 : mergedProps.onClick) === null || _a === void 0 ? void 0 : _a.call(mergedProps, event);
63
63
  onClick === null || onClick === void 0 ? void 0 : onClick(event, row);
64
64
  } }, row.cells.map((cell, index) => {
65
- return (react_1.default.createElement(TableCell_1.TableCell, { key: cell.getCellProps().key, cell: cell, cellIndex: index, isDisabled: isDisabled, tableHasSubRows: tableHasSubRows, tableInstance: tableInstance, expanderCell: expanderCell }));
65
+ return (react_1.default.createElement(TableCell_1.TableCell, { key: cell.getCellProps().key, cell: cell, cellIndex: index, isDisabled: isDisabled, tableHasSubRows: tableHasSubRows, tableInstance: tableInstance, expanderCell: expanderCell, density: density }));
66
66
  })),
67
67
  subComponent && (react_1.default.createElement(utils_1.WithCSSTransition, { in: row.isExpanded },
68
68
  react_1.default.createElement("div", { className: (0, classnames_1.default)('iui-table-row', 'iui-table-expanded-content'), "aria-disabled": isDisabled }, subComponent(row))))));
@@ -104,5 +104,6 @@ exports.TableRowMemoized = react_1.default.memo(exports.TableRow, (prevProp, nex
104
104
  prevProp.state.sticky.isScrolledToLeft ===
105
105
  nextProp.state.sticky.isScrolledToLeft &&
106
106
  prevProp.state.sticky.isScrolledToRight ===
107
- nextProp.state.sticky.isScrolledToRight;
107
+ nextProp.state.sticky.isScrolledToRight &&
108
+ prevProp.density === nextProp.density;
108
109
  });
@@ -16,6 +16,7 @@ export declare const SELECTION_CELL_ID = "iui-table-checkbox-selector";
16
16
  export declare const SelectionColumn: <T extends Record<string, unknown>>(props?: {
17
17
  /** Function that returns whether row checkbox should be disabled. */
18
18
  isDisabled?: ((rowData: T) => boolean) | undefined;
19
+ density?: "default" | "condensed" | "extra-condensed" | undefined;
19
20
  }) => {
20
21
  id: string;
21
22
  disableResizing: boolean;
@@ -25,15 +25,16 @@ exports.SELECTION_CELL_ID = 'iui-table-checkbox-selector';
25
25
  * ], [isCheckboxDisabled]);
26
26
  */
27
27
  const SelectionColumn = (props = {}) => {
28
- const { isDisabled } = props;
28
+ const { isDisabled, density } = props;
29
+ const densityWidth = density === 'condensed' ? 42 : density === 'extra-condensed' ? 34 : 48;
29
30
  return {
30
31
  id: exports.SELECTION_CELL_ID,
31
32
  disableResizing: true,
32
33
  disableGroupBy: true,
33
34
  disableReordering: true,
34
- minWidth: 48,
35
- width: 48,
36
- maxWidth: 48,
35
+ minWidth: densityWidth,
36
+ width: densityWidth,
37
+ maxWidth: densityWidth,
37
38
  columnClassName: 'iui-slot',
38
39
  cellClassName: 'iui-slot',
39
40
  Header: ({ getToggleAllRowsSelectedProps, toggleAllRowsSelected, rows, initialRows, state, }) => {
@@ -17,7 +17,7 @@ export interface TableFilterValue<T extends Record<string, unknown>> {
17
17
  */
18
18
  filterType: FilterType<T>;
19
19
  }
20
- export declare type TableFilterProps<T extends Record<string, unknown>> = FilterProps<T> & {
20
+ export declare type TableFilterProps<T extends Record<string, unknown> | object> = FilterProps<T> & {
21
21
  /**
22
22
  * Data of column on which filter is opened. It is provided by the table it self.
23
23
  */
@@ -1,2 +1,2 @@
1
1
  import { Hooks } from 'react-table';
2
- export declare const useSelectionCell: <T extends Record<string, unknown>>(isSelectable: boolean, selectionMode: 'multi' | 'single', isRowDisabled?: ((rowData: T) => boolean) | undefined) => (hooks: Hooks<T>) => void;
2
+ export declare const useSelectionCell: <T extends Record<string, unknown>>(isSelectable: boolean, selectionMode: 'multi' | 'single', isRowDisabled?: ((rowData: T) => boolean) | undefined, density?: 'default' | 'condensed' | 'extra-condensed') => (hooks: Hooks<T>) => void;
@@ -2,13 +2,16 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useSelectionCell = void 0;
4
4
  const columns_1 = require("../columns");
5
- const useSelectionCell = (isSelectable, selectionMode, isRowDisabled) => (hooks) => {
5
+ const useSelectionCell = (isSelectable, selectionMode, isRowDisabled, density = 'default') => (hooks) => {
6
6
  if (!isSelectable) {
7
7
  return;
8
8
  }
9
9
  hooks.allColumns.push((columns) => selectionMode === 'single' ||
10
10
  columns.find((c) => c.id === columns_1.SELECTION_CELL_ID)
11
11
  ? columns
12
- : [(0, columns_1.SelectionColumn)({ isDisabled: isRowDisabled }), ...columns]);
12
+ : [
13
+ (0, columns_1.SelectionColumn)({ isDisabled: isRowDisabled, density: density }),
14
+ ...columns,
15
+ ]);
13
16
  };
14
17
  exports.useSelectionCell = useSelectionCell;
@@ -11,9 +11,12 @@ declare type RootProps = {
11
11
  * in SSR environments because it is not possible detect system preference on the server.
12
12
  * This can cause a flash of incorrect theme on first render.
13
13
  *
14
+ * The 'inherit' option is intended to be used by packages, to enable incremental adoption
15
+ * of iTwinUI v2 in app that might be using v1 in other places.
16
+ *
14
17
  * @default 'light'
15
18
  */
16
- theme?: ThemeType;
19
+ theme?: ThemeType | 'inherit';
17
20
  themeOptions?: Pick<ThemeOptions, 'highContrast'> & {
18
21
  /**
19
22
  * Whether or not the element should apply the recommended `background-color` on itself.
@@ -22,10 +25,17 @@ declare type RootProps = {
22
25
  * if it is the topmost `ThemeProvider` in the tree. Nested `ThemeProvider`s will
23
26
  * be detected using React Context and will not apply a background-color.
24
27
  *
28
+ * Additionally, if theme is set to `'inherit'`, then this will default to false.
29
+ *
25
30
  * When set to true or false, it will override the default behavior.
26
31
  */
27
32
  applyBackground?: boolean;
28
33
  };
34
+ /**
35
+ * Whether theme was set to `'inherit'`.
36
+ * This will be used to determine if applyBackground will default to false.
37
+ */
38
+ isInheritingTheme?: boolean;
29
39
  };
30
40
  declare type ThemeProviderOwnProps = Pick<RootProps, 'theme'> & ({
31
41
  themeOptions?: RootProps['themeOptions'];
@@ -40,25 +40,27 @@ require("@itwin/itwinui-variables/index.css");
40
40
  * </ThemeProvider>
41
41
  */
42
42
  exports.ThemeProvider = react_1.default.forwardRef((props, ref) => {
43
- const { theme, children, themeOptions, ...rest } = props;
43
+ var _a;
44
+ const { theme: themeProp, children, themeOptions, ...rest } = props;
44
45
  const rootRef = react_1.default.useRef(null);
45
46
  const mergedRefs = (0, utils_1.useMergedRefs)(rootRef, ref);
46
47
  const hasChildren = react_1.default.Children.count(children) > 0;
47
48
  const parentContext = react_1.default.useContext(exports.ThemeContext);
49
+ const theme = themeProp === 'inherit' ? (_a = parentContext === null || parentContext === void 0 ? void 0 : parentContext.theme) !== null && _a !== void 0 ? _a : 'light' : themeProp;
48
50
  const contextValue = react_1.default.useMemo(() => ({ theme, themeOptions, rootRef }), [theme, themeOptions]);
49
51
  // if no children, then fallback to this wrapper component which calls useTheme
50
52
  if (!hasChildren) {
51
- return (react_1.default.createElement(ThemeLogicWrapper, { theme: theme !== null && theme !== void 0 ? theme : parentContext === null || parentContext === void 0 ? void 0 : parentContext.theme, themeOptions: themeOptions !== null && themeOptions !== void 0 ? themeOptions : parentContext === null || parentContext === void 0 ? void 0 : parentContext.themeOptions }));
53
+ return (react_1.default.createElement(ThemeLogicWrapper, { theme: theme, themeOptions: themeOptions !== null && themeOptions !== void 0 ? themeOptions : parentContext === null || parentContext === void 0 ? void 0 : parentContext.themeOptions }));
52
54
  }
53
55
  // now that we know there are children, we can render the root and provide the context value
54
- return (react_1.default.createElement(Root, { theme: theme, themeOptions: themeOptions, ref: mergedRefs, ...rest },
56
+ return (react_1.default.createElement(Root, { theme: theme, isInheritingTheme: themeProp === 'inherit', themeOptions: themeOptions, ref: mergedRefs, ...rest },
55
57
  react_1.default.createElement(exports.ThemeContext.Provider, { value: contextValue }, children)));
56
58
  });
57
59
  exports.default = exports.ThemeProvider;
58
60
  exports.ThemeContext = react_1.default.createContext(undefined);
59
61
  const Root = react_1.default.forwardRef((props, forwardedRef) => {
60
62
  var _a, _b, _c;
61
- const { theme, children, themeOptions, as: Element = 'div', className, ...rest } = props;
63
+ const { theme, children, themeOptions, as: Element = 'div', className, isInheritingTheme, ...rest } = props;
62
64
  const ref = react_1.default.useRef(null);
63
65
  const mergedRefs = (0, utils_1.useMergedRefs)(ref, forwardedRef);
64
66
  const prefersDark = (0, utils_1.useMediaQuery)('(prefers-color-scheme: dark)');
@@ -66,10 +68,11 @@ const Root = react_1.default.forwardRef((props, forwardedRef) => {
66
68
  const shouldApplyDark = theme === 'dark' || (theme === 'os' && prefersDark);
67
69
  const shouldApplyHC = (_a = themeOptions === null || themeOptions === void 0 ? void 0 : themeOptions.highContrast) !== null && _a !== void 0 ? _a : prefersHighContrast;
68
70
  const isThemeAlreadySet = (0, utils_1.useIsThemeAlreadySet)((_b = ref.current) === null || _b === void 0 ? void 0 : _b.ownerDocument);
69
- const shouldApplyBackground = (_c = themeOptions === null || themeOptions === void 0 ? void 0 : themeOptions.applyBackground) !== null && _c !== void 0 ? _c : !isThemeAlreadySet.current;
71
+ const shouldApplyBackground = (_c = themeOptions === null || themeOptions === void 0 ? void 0 : themeOptions.applyBackground) !== null && _c !== void 0 ? _c : (isInheritingTheme ? false : !isThemeAlreadySet.current);
70
72
  return (react_1.default.createElement(Element, { className: (0, classnames_1.default)('iui-root', { 'iui-root-background': shouldApplyBackground }, className), "data-iui-theme": shouldApplyDark ? 'dark' : 'light', "data-iui-contrast": shouldApplyHC ? 'high' : 'default', ref: mergedRefs, ...rest }, children));
71
73
  });
72
- const ThemeLogicWrapper = ({ theme, themeOptions }) => {
74
+ const ThemeLogicWrapper = (props) => {
75
+ const { theme, themeOptions } = props;
73
76
  (0, utils_1.useTheme)(theme, themeOptions);
74
77
  return react_1.default.createElement(react_1.default.Fragment, null);
75
78
  };
@@ -1,4 +1,5 @@
1
1
  /// <reference types="react" />
2
+ import { TableFilterProps } from '../core';
2
3
  declare module 'react-table' {
3
4
  type FieldType = 'text' | 'number' | 'date' | string;
4
5
  type CellRendererProps<D extends object = {}> = {
@@ -22,8 +23,11 @@ declare module 'react-table' {
22
23
  interface TableOptions<D extends object = {}> extends Omit<UseTableOptions<D>, 'data' | 'columns'>, UseRowSelectOptions<D>, UseExpandedOptions<D>, UseFiltersOptions<D>, UsePaginationOptions<D>, UseGlobalFiltersOptions<D>, UseGlobalFiltersColumnOptions<D>, Omit<UseResizeColumnsOptions<D>, 'disableResizing'>, UseSortByOptions<D> {
23
24
  /**
24
25
  * List of columns.
26
+ *
27
+ * Should not have a top-level `Header` or a `columns` sub-property. They are only allowed to be passed for backwards compatibility.
28
+ * See [migration guide](https://github.com/iTwin/iTwinUI/wiki/iTwinUI-react-v2-migration-guide#breaking-changes).
25
29
  */
26
- columns: Array<Column<any>>;
30
+ columns: Array<Column<D>>;
27
31
  /**
28
32
  * Table data list.
29
33
  * Must be memoized.
@@ -83,7 +87,7 @@ declare module 'react-table' {
83
87
  /**
84
88
  * Filter component used as a column filter. Should use filters from `tableFilters`.
85
89
  */
86
- Filter?: Renderer<FilterProps<D>>;
90
+ Filter?: Renderer<FilterProps<D>> | Renderer<TableFilterProps<D>>;
87
91
  /**
88
92
  * String value or custom function to use for filtering.
89
93
  * Possible string values: `text`, `exactText`, `exactTextCase`, `includes`, `includesAll`, `exact`, `equals`, `between`.
@@ -129,4 +133,3 @@ declare module 'react-table' {
129
133
  initialSubRows: Row<D>[];
130
134
  }
131
135
  }
132
- export {};
@@ -5,6 +5,7 @@ export declare type SubRowExpanderProps<T extends Record<string, unknown>> = {
5
5
  expanderCell?: (cellProps: CellProps<T>) => React.ReactNode;
6
6
  isDisabled: boolean;
7
7
  cellProps: CellProps<T>;
8
+ density?: 'default' | 'condensed' | 'extra-condensed';
8
9
  };
9
10
  export declare const SubRowExpander: <T extends Record<string, unknown>>(props: SubRowExpanderProps<T>) => JSX.Element;
10
11
  export default SubRowExpander;
@@ -6,8 +6,10 @@ import React from 'react';
6
6
  import { SvgChevronRight } from '../utils';
7
7
  import { IconButton } from '../Buttons';
8
8
  export const SubRowExpander = (props) => {
9
- const { cell, isDisabled, cellProps, expanderCell } = props;
10
- return (React.createElement(React.Fragment, null, expanderCell ? (expanderCell(cellProps)) : (React.createElement(IconButton, { style: { marginRight: 8 }, className: 'iui-table-row-expander', styleType: 'borderless', size: 'small', onClick: (e) => {
9
+ const { cell, isDisabled, cellProps, expanderCell, density } = props;
10
+ return (React.createElement(React.Fragment, null, expanderCell ? (expanderCell(cellProps)) : (React.createElement(IconButton, { style: {
11
+ marginRight: density === 'default' || density === undefined ? 8 : 4,
12
+ }, className: 'iui-table-row-expander', styleType: 'borderless', size: 'small', onClick: (e) => {
11
13
  e.stopPropagation();
12
14
  cell.row.toggleRowExpanded();
13
15
  }, disabled: isDisabled }, React.createElement(SvgChevronRight, { style: {
@@ -20,11 +20,18 @@ const singleRowSelectedAction = 'singleRowSelected';
20
20
  const shiftRowSelectedAction = 'shiftRowSelected';
21
21
  export const tableResizeStartAction = 'tableResizeStart';
22
22
  const tableResizeEndAction = 'tableResizeEnd';
23
+ let didLogWarning = false;
24
+ let isDev = false;
25
+ // wrapping in try-catch because process might be undefined
26
+ try {
27
+ isDev = process.env.NODE_ENV !== 'production';
28
+ }
29
+ catch (_a) { }
23
30
  const flattenColumns = (columns) => {
24
31
  const flatColumns = [];
25
32
  columns.forEach((column) => {
26
33
  flatColumns.push(column);
27
- if (column.columns) {
34
+ if ('columns' in column) {
28
35
  flatColumns.push(...flattenColumns(column.columns));
29
36
  }
30
37
  });
@@ -191,8 +198,16 @@ export const Table = (props) => {
191
198
  getSubRows,
192
199
  initialState: { pageSize, ...props.initialState },
193
200
  columnResizeMode,
194
- }, useFlexLayout, useResizeColumns(ownerDocument), useFilters, useSubRowFiltering(hasAnySubRows), useGlobalFilter, useSortBy, useExpanded, usePagination, useRowSelect, useSubRowSelection, useExpanderCell(subComponent, expanderCell, isRowDisabled), useSelectionCell(isSelectable, selectionMode, isRowDisabled), useColumnOrder, useColumnDragAndDrop(enableColumnReordering), useStickyColumns);
195
- const { getTableProps, rows, headerGroups, getTableBodyProps, prepareRow, state, allColumns, dispatch, page, gotoPage, setPageSize, flatHeaders, visibleColumns, setGlobalFilter, } = instance;
201
+ }, useFlexLayout, useResizeColumns(ownerDocument), useFilters, useSubRowFiltering(hasAnySubRows), useGlobalFilter, useSortBy, useExpanded, usePagination, useRowSelect, useSubRowSelection, useExpanderCell(subComponent, expanderCell, isRowDisabled), useSelectionCell(isSelectable, selectionMode, isRowDisabled, density), useColumnOrder, useColumnDragAndDrop(enableColumnReordering), useStickyColumns);
202
+ const { getTableProps, rows, headerGroups: _headerGroups, getTableBodyProps, prepareRow, state, allColumns, dispatch, page, gotoPage, setPageSize, flatHeaders, visibleColumns, setGlobalFilter, } = instance;
203
+ let headerGroups = _headerGroups;
204
+ if (columns.length === 1 && 'columns' in columns[0]) {
205
+ headerGroups = _headerGroups.slice(1);
206
+ if (isDev && !didLogWarning) {
207
+ console.warn(`Table's \`columns\` prop should not have a top-level \`Header\` or sub-columns. They are only allowed to be passed for backwards compatibility.\n See https://github.com/iTwin/iTwinUI/wiki/iTwinUI-react-v2-migration-guide#breaking-changes`);
208
+ didLogWarning = true;
209
+ }
210
+ }
196
211
  const ariaDataAttributes = Object.entries(rest).reduce((result, [key, value]) => {
197
212
  if (key.startsWith('data-') || key.startsWith('aria-')) {
198
213
  result[key] = value;
@@ -321,7 +336,7 @@ export const Table = (props) => {
321
336
  const getPreparedRow = React.useCallback((index) => {
322
337
  const row = page[index];
323
338
  prepareRow(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) }));
339
+ 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), density: density }));
325
340
  }, [
326
341
  page,
327
342
  prepareRow,
@@ -336,6 +351,7 @@ export const Table = (props) => {
336
351
  expanderCell,
337
352
  enableVirtualization,
338
353
  tableRowRef,
354
+ density,
339
355
  ]);
340
356
  const virtualizedItemRenderer = React.useCallback((index) => getPreparedRow(index), [getPreparedRow]);
341
357
  const updateStickyState = () => {
@@ -7,6 +7,7 @@ export declare type TableCellProps<T extends Record<string, unknown>> = {
7
7
  tableHasSubRows: boolean;
8
8
  tableInstance: TableInstance<T>;
9
9
  expanderCell?: (cellProps: CellProps<T>) => React.ReactNode;
10
+ density?: 'default' | 'condensed' | 'extra-condensed';
10
11
  };
11
12
  export declare const TableCell: <T extends Record<string, unknown>>(props: TableCellProps<T>) => JSX.Element;
12
13
  export default TableCell;
@@ -9,7 +9,7 @@ import { SubRowExpander } from './SubRowExpander';
9
9
  import { SELECTION_CELL_ID } from './columns';
10
10
  import { DefaultCell } from './cells';
11
11
  export const TableCell = (props) => {
12
- const { cell, cellIndex, isDisabled, tableHasSubRows, tableInstance, expanderCell, } = props;
12
+ const { cell, cellIndex, isDisabled, tableHasSubRows, tableInstance, expanderCell, density, } = props;
13
13
  const hasSubRowExpander = cellIndex ===
14
14
  cell.row.cells.findIndex((c) => c.column.id !== SELECTION_CELL_ID);
15
15
  const getSubRowStyle = () => {
@@ -17,9 +17,20 @@ export const TableCell = (props) => {
17
17
  return undefined;
18
18
  }
19
19
  // If it doesn't have sub-rows then shift by another level to align with expandable rows on the same depth
20
- // 16 = initial_cell_padding, 35 = 27 + 8 = expander_width + margin
20
+ const dynamicMargin = cell.row.depth + (cell.row.canExpand ? 0 : 1);
21
+ let cellPadding = 16;
22
+ let expanderMargin = 8;
23
+ if (density === 'condensed') {
24
+ cellPadding = 12;
25
+ expanderMargin = 4;
26
+ }
27
+ else if (density === 'extra-condensed') {
28
+ cellPadding = 8;
29
+ expanderMargin = 4;
30
+ }
31
+ const multiplier = 26 + expanderMargin; // 26 = expander width
21
32
  return {
22
- paddingLeft: 16 + (cell.row.depth + (cell.row.canExpand ? 0 : 1)) * 35,
33
+ paddingLeft: cellPadding + dynamicMargin * multiplier,
23
34
  };
24
35
  };
25
36
  const cellElementProps = cell.getCellProps({
@@ -37,7 +48,7 @@ export const TableCell = (props) => {
37
48
  ...{ cell, row: cell.row, value: cell.value, column: cell.column },
38
49
  };
39
50
  const cellContent = (React.createElement(React.Fragment, null,
40
- tableHasSubRows && hasSubRowExpander && cell.row.canExpand && (React.createElement(SubRowExpander, { cell: cell, isDisabled: isDisabled, cellProps: cellProps, expanderCell: expanderCell })),
51
+ tableHasSubRows && hasSubRowExpander && cell.row.canExpand && (React.createElement(SubRowExpander, { cell: cell, isDisabled: isDisabled, cellProps: cellProps, expanderCell: expanderCell, density: density })),
41
52
  cell.render('Cell')));
42
53
  const cellRendererProps = {
43
54
  cellElementProps,
@@ -25,6 +25,7 @@ export declare const TableRow: <T extends Record<string, unknown>>(props: {
25
25
  expanderCell?: ((cellProps: CellProps<T, any>) => React.ReactNode) | undefined;
26
26
  bodyRef: HTMLDivElement | null;
27
27
  tableRowRef?: React.Ref<HTMLDivElement> | undefined;
28
+ density?: "default" | "condensed" | "extra-condensed" | undefined;
28
29
  }) => JSX.Element;
29
30
  export declare const TableRowMemoized: <T extends Record<string, unknown>>(props: {
30
31
  row: Row<T>;
@@ -45,4 +46,5 @@ export declare const TableRowMemoized: <T extends Record<string, unknown>>(props
45
46
  expanderCell?: ((cellProps: CellProps<T, any>) => React.ReactNode) | undefined;
46
47
  bodyRef: HTMLDivElement | null;
47
48
  tableRowRef?: React.Ref<HTMLDivElement> | undefined;
49
+ density?: "default" | "condensed" | "extra-condensed" | undefined;
48
50
  }) => JSX.Element;
@@ -14,7 +14,7 @@ import { TableCell } from './TableCell';
14
14
  */
15
15
  export const TableRow = (props) => {
16
16
  var _a;
17
- const { row, rowProps, isLast, onRowInViewport, onBottomReached, intersectionMargin, onClick, subComponent, isDisabled, tableHasSubRows, tableInstance, expanderCell, bodyRef, tableRowRef, } = props;
17
+ const { row, rowProps, isLast, onRowInViewport, onBottomReached, intersectionMargin, onClick, subComponent, isDisabled, tableHasSubRows, tableInstance, expanderCell, bodyRef, tableRowRef, density, } = props;
18
18
  const onIntersect = React.useCallback(() => {
19
19
  var _a, _b;
20
20
  (_a = onRowInViewport.current) === null || _a === void 0 ? void 0 : _a.call(onRowInViewport, row.original);
@@ -56,7 +56,7 @@ export const TableRow = (props) => {
56
56
  (_a = mergedProps === null || mergedProps === void 0 ? void 0 : mergedProps.onClick) === null || _a === void 0 ? void 0 : _a.call(mergedProps, event);
57
57
  onClick === null || onClick === void 0 ? void 0 : onClick(event, row);
58
58
  } }, row.cells.map((cell, index) => {
59
- return (React.createElement(TableCell, { key: cell.getCellProps().key, cell: cell, cellIndex: index, isDisabled: isDisabled, tableHasSubRows: tableHasSubRows, tableInstance: tableInstance, expanderCell: expanderCell }));
59
+ return (React.createElement(TableCell, { key: cell.getCellProps().key, cell: cell, cellIndex: index, isDisabled: isDisabled, tableHasSubRows: tableHasSubRows, tableInstance: tableInstance, expanderCell: expanderCell, density: density }));
60
60
  })),
61
61
  subComponent && (React.createElement(WithCSSTransition, { in: row.isExpanded },
62
62
  React.createElement("div", { className: cx('iui-table-row', 'iui-table-expanded-content'), "aria-disabled": isDisabled }, subComponent(row))))));
@@ -97,5 +97,6 @@ export const TableRowMemoized = React.memo(TableRow, (prevProp, nextProp) => {
97
97
  prevProp.state.sticky.isScrolledToLeft ===
98
98
  nextProp.state.sticky.isScrolledToLeft &&
99
99
  prevProp.state.sticky.isScrolledToRight ===
100
- nextProp.state.sticky.isScrolledToRight;
100
+ nextProp.state.sticky.isScrolledToRight &&
101
+ prevProp.density === nextProp.density;
101
102
  });
@@ -16,6 +16,7 @@ export declare const SELECTION_CELL_ID = "iui-table-checkbox-selector";
16
16
  export declare const SelectionColumn: <T extends Record<string, unknown>>(props?: {
17
17
  /** Function that returns whether row checkbox should be disabled. */
18
18
  isDisabled?: ((rowData: T) => boolean) | undefined;
19
+ density?: "default" | "condensed" | "extra-condensed" | undefined;
19
20
  }) => {
20
21
  id: string;
21
22
  disableResizing: boolean;
@@ -19,15 +19,16 @@ export const SELECTION_CELL_ID = 'iui-table-checkbox-selector';
19
19
  * ], [isCheckboxDisabled]);
20
20
  */
21
21
  export const SelectionColumn = (props = {}) => {
22
- const { isDisabled } = props;
22
+ const { isDisabled, density } = props;
23
+ const densityWidth = density === 'condensed' ? 42 : density === 'extra-condensed' ? 34 : 48;
23
24
  return {
24
25
  id: SELECTION_CELL_ID,
25
26
  disableResizing: true,
26
27
  disableGroupBy: true,
27
28
  disableReordering: true,
28
- minWidth: 48,
29
- width: 48,
30
- maxWidth: 48,
29
+ minWidth: densityWidth,
30
+ width: densityWidth,
31
+ maxWidth: densityWidth,
31
32
  columnClassName: 'iui-slot',
32
33
  cellClassName: 'iui-slot',
33
34
  Header: ({ getToggleAllRowsSelectedProps, toggleAllRowsSelected, rows, initialRows, state, }) => {
@@ -17,7 +17,7 @@ export interface TableFilterValue<T extends Record<string, unknown>> {
17
17
  */
18
18
  filterType: FilterType<T>;
19
19
  }
20
- export declare type TableFilterProps<T extends Record<string, unknown>> = FilterProps<T> & {
20
+ export declare type TableFilterProps<T extends Record<string, unknown> | object> = FilterProps<T> & {
21
21
  /**
22
22
  * Data of column on which filter is opened. It is provided by the table it self.
23
23
  */
@@ -1,2 +1,2 @@
1
1
  import { Hooks } from 'react-table';
2
- export declare const useSelectionCell: <T extends Record<string, unknown>>(isSelectable: boolean, selectionMode: 'multi' | 'single', isRowDisabled?: ((rowData: T) => boolean) | undefined) => (hooks: Hooks<T>) => void;
2
+ export declare const useSelectionCell: <T extends Record<string, unknown>>(isSelectable: boolean, selectionMode: 'multi' | 'single', isRowDisabled?: ((rowData: T) => boolean) | undefined, density?: 'default' | 'condensed' | 'extra-condensed') => (hooks: Hooks<T>) => void;
@@ -1,10 +1,13 @@
1
1
  import { SelectionColumn, SELECTION_CELL_ID } from '../columns';
2
- export const useSelectionCell = (isSelectable, selectionMode, isRowDisabled) => (hooks) => {
2
+ export const useSelectionCell = (isSelectable, selectionMode, isRowDisabled, density = 'default') => (hooks) => {
3
3
  if (!isSelectable) {
4
4
  return;
5
5
  }
6
6
  hooks.allColumns.push((columns) => selectionMode === 'single' ||
7
7
  columns.find((c) => c.id === SELECTION_CELL_ID)
8
8
  ? columns
9
- : [SelectionColumn({ isDisabled: isRowDisabled }), ...columns]);
9
+ : [
10
+ SelectionColumn({ isDisabled: isRowDisabled, density: density }),
11
+ ...columns,
12
+ ]);
10
13
  };
@@ -11,9 +11,12 @@ declare type RootProps = {
11
11
  * in SSR environments because it is not possible detect system preference on the server.
12
12
  * This can cause a flash of incorrect theme on first render.
13
13
  *
14
+ * The 'inherit' option is intended to be used by packages, to enable incremental adoption
15
+ * of iTwinUI v2 in app that might be using v1 in other places.
16
+ *
14
17
  * @default 'light'
15
18
  */
16
- theme?: ThemeType;
19
+ theme?: ThemeType | 'inherit';
17
20
  themeOptions?: Pick<ThemeOptions, 'highContrast'> & {
18
21
  /**
19
22
  * Whether or not the element should apply the recommended `background-color` on itself.
@@ -22,10 +25,17 @@ declare type RootProps = {
22
25
  * if it is the topmost `ThemeProvider` in the tree. Nested `ThemeProvider`s will
23
26
  * be detected using React Context and will not apply a background-color.
24
27
  *
28
+ * Additionally, if theme is set to `'inherit'`, then this will default to false.
29
+ *
25
30
  * When set to true or false, it will override the default behavior.
26
31
  */
27
32
  applyBackground?: boolean;
28
33
  };
34
+ /**
35
+ * Whether theme was set to `'inherit'`.
36
+ * This will be used to determine if applyBackground will default to false.
37
+ */
38
+ isInheritingTheme?: boolean;
29
39
  };
30
40
  declare type ThemeProviderOwnProps = Pick<RootProps, 'theme'> & ({
31
41
  themeOptions?: RootProps['themeOptions'];
@@ -34,25 +34,27 @@ import '@itwin/itwinui-variables/index.css';
34
34
  * </ThemeProvider>
35
35
  */
36
36
  export const ThemeProvider = React.forwardRef((props, ref) => {
37
- const { theme, children, themeOptions, ...rest } = props;
37
+ var _a;
38
+ const { theme: themeProp, children, themeOptions, ...rest } = props;
38
39
  const rootRef = React.useRef(null);
39
40
  const mergedRefs = useMergedRefs(rootRef, ref);
40
41
  const hasChildren = React.Children.count(children) > 0;
41
42
  const parentContext = React.useContext(ThemeContext);
43
+ const theme = themeProp === 'inherit' ? (_a = parentContext === null || parentContext === void 0 ? void 0 : parentContext.theme) !== null && _a !== void 0 ? _a : 'light' : themeProp;
42
44
  const contextValue = React.useMemo(() => ({ theme, themeOptions, rootRef }), [theme, themeOptions]);
43
45
  // if no children, then fallback to this wrapper component which calls useTheme
44
46
  if (!hasChildren) {
45
- return (React.createElement(ThemeLogicWrapper, { theme: theme !== null && theme !== void 0 ? theme : parentContext === null || parentContext === void 0 ? void 0 : parentContext.theme, themeOptions: themeOptions !== null && themeOptions !== void 0 ? themeOptions : parentContext === null || parentContext === void 0 ? void 0 : parentContext.themeOptions }));
47
+ return (React.createElement(ThemeLogicWrapper, { theme: theme, themeOptions: themeOptions !== null && themeOptions !== void 0 ? themeOptions : parentContext === null || parentContext === void 0 ? void 0 : parentContext.themeOptions }));
46
48
  }
47
49
  // now that we know there are children, we can render the root and provide the context value
48
- return (React.createElement(Root, { theme: theme, themeOptions: themeOptions, ref: mergedRefs, ...rest },
50
+ return (React.createElement(Root, { theme: theme, isInheritingTheme: themeProp === 'inherit', themeOptions: themeOptions, ref: mergedRefs, ...rest },
49
51
  React.createElement(ThemeContext.Provider, { value: contextValue }, children)));
50
52
  });
51
53
  export default ThemeProvider;
52
54
  export const ThemeContext = React.createContext(undefined);
53
55
  const Root = React.forwardRef((props, forwardedRef) => {
54
56
  var _a, _b, _c;
55
- const { theme, children, themeOptions, as: Element = 'div', className, ...rest } = props;
57
+ const { theme, children, themeOptions, as: Element = 'div', className, isInheritingTheme, ...rest } = props;
56
58
  const ref = React.useRef(null);
57
59
  const mergedRefs = useMergedRefs(ref, forwardedRef);
58
60
  const prefersDark = useMediaQuery('(prefers-color-scheme: dark)');
@@ -60,10 +62,11 @@ const Root = React.forwardRef((props, forwardedRef) => {
60
62
  const shouldApplyDark = theme === 'dark' || (theme === 'os' && prefersDark);
61
63
  const shouldApplyHC = (_a = themeOptions === null || themeOptions === void 0 ? void 0 : themeOptions.highContrast) !== null && _a !== void 0 ? _a : prefersHighContrast;
62
64
  const isThemeAlreadySet = useIsThemeAlreadySet((_b = ref.current) === null || _b === void 0 ? void 0 : _b.ownerDocument);
63
- const shouldApplyBackground = (_c = themeOptions === null || themeOptions === void 0 ? void 0 : themeOptions.applyBackground) !== null && _c !== void 0 ? _c : !isThemeAlreadySet.current;
65
+ const shouldApplyBackground = (_c = themeOptions === null || themeOptions === void 0 ? void 0 : themeOptions.applyBackground) !== null && _c !== void 0 ? _c : (isInheritingTheme ? false : !isThemeAlreadySet.current);
64
66
  return (React.createElement(Element, { className: cx('iui-root', { 'iui-root-background': shouldApplyBackground }, className), "data-iui-theme": shouldApplyDark ? 'dark' : 'light', "data-iui-contrast": shouldApplyHC ? 'high' : 'default', ref: mergedRefs, ...rest }, children));
65
67
  });
66
- const ThemeLogicWrapper = ({ theme, themeOptions }) => {
68
+ const ThemeLogicWrapper = (props) => {
69
+ const { theme, themeOptions } = props;
67
70
  useTheme(theme, themeOptions);
68
71
  return React.createElement(React.Fragment, null);
69
72
  };
@@ -1,4 +1,5 @@
1
1
  /// <reference types="react" />
2
+ import { TableFilterProps } from '../core';
2
3
  declare module 'react-table' {
3
4
  type FieldType = 'text' | 'number' | 'date' | string;
4
5
  type CellRendererProps<D extends object = {}> = {
@@ -22,8 +23,11 @@ declare module 'react-table' {
22
23
  interface TableOptions<D extends object = {}> extends Omit<UseTableOptions<D>, 'data' | 'columns'>, UseRowSelectOptions<D>, UseExpandedOptions<D>, UseFiltersOptions<D>, UsePaginationOptions<D>, UseGlobalFiltersOptions<D>, UseGlobalFiltersColumnOptions<D>, Omit<UseResizeColumnsOptions<D>, 'disableResizing'>, UseSortByOptions<D> {
23
24
  /**
24
25
  * List of columns.
26
+ *
27
+ * Should not have a top-level `Header` or a `columns` sub-property. They are only allowed to be passed for backwards compatibility.
28
+ * See [migration guide](https://github.com/iTwin/iTwinUI/wiki/iTwinUI-react-v2-migration-guide#breaking-changes).
25
29
  */
26
- columns: Array<Column<any>>;
30
+ columns: Array<Column<D>>;
27
31
  /**
28
32
  * Table data list.
29
33
  * Must be memoized.
@@ -83,7 +87,7 @@ declare module 'react-table' {
83
87
  /**
84
88
  * Filter component used as a column filter. Should use filters from `tableFilters`.
85
89
  */
86
- Filter?: Renderer<FilterProps<D>>;
90
+ Filter?: Renderer<FilterProps<D>> | Renderer<TableFilterProps<D>>;
87
91
  /**
88
92
  * String value or custom function to use for filtering.
89
93
  * Possible string values: `text`, `exactText`, `exactTextCase`, `includes`, `includesAll`, `exact`, `equals`, `between`.
@@ -129,4 +133,3 @@ declare module 'react-table' {
129
133
  initialSubRows: Row<D>[];
130
134
  }
131
135
  }
132
- export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itwin/itwinui-react",
3
- "version": "2.4.4",
3
+ "version": "2.5.1",
4
4
  "author": "Bentley Systems",
5
5
  "license": "MIT",
6
6
  "main": "cjs/index.js",
@@ -62,9 +62,9 @@
62
62
  "dev:types": "concurrently \"tsc -p tsconfig.cjs.json --emitDeclarationOnly --watch --preserveWatchOutput\" \"tsc -p tsconfig.esm.json --emitDeclarationOnly --watch --preserveWatchOutput\""
63
63
  },
64
64
  "dependencies": {
65
- "@itwin/itwinui-css": "^1.5.0",
65
+ "@itwin/itwinui-css": "^1.6.0",
66
66
  "@itwin/itwinui-illustrations-react": "^2.0.0",
67
- "@itwin/itwinui-variables": "^1.0.0",
67
+ "@itwin/itwinui-variables": "^2.0.0",
68
68
  "@tippyjs/react": "^4.2.6",
69
69
  "@types/react-table": "^7.0.18",
70
70
  "classnames": "^2.2.6",