@itwin/itwinui-react 1.37.1 → 1.38.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.
Files changed (82) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/cjs/core/Breadcrumbs/Breadcrumbs.js +3 -5
  3. package/cjs/core/ColorPicker/ColorSwatch.d.ts +1 -1
  4. package/cjs/core/ComboBox/ComboBox.d.ts +4 -2
  5. package/cjs/core/ComboBox/ComboBox.js +129 -246
  6. package/cjs/core/ComboBox/ComboBoxDropdown.d.ts +8 -0
  7. package/cjs/core/ComboBox/ComboBoxDropdown.js +55 -0
  8. package/cjs/core/ComboBox/ComboBoxEndIcon.d.ts +5 -0
  9. package/cjs/core/ComboBox/ComboBoxEndIcon.js +54 -0
  10. package/cjs/core/ComboBox/ComboBoxInput.d.ts +5 -0
  11. package/cjs/core/ComboBox/ComboBoxInput.js +134 -0
  12. package/cjs/core/ComboBox/ComboBoxInputContainer.d.ts +8 -0
  13. package/cjs/core/ComboBox/ComboBoxInputContainer.js +45 -0
  14. package/cjs/core/ComboBox/ComboBoxMenu.d.ts +3 -0
  15. package/cjs/core/ComboBox/ComboBoxMenu.js +45 -0
  16. package/cjs/core/ComboBox/ComboBoxMenuItem.d.ts +21 -0
  17. package/cjs/core/ComboBox/ComboBoxMenuItem.js +65 -0
  18. package/cjs/core/ComboBox/helpers.d.ts +27 -0
  19. package/cjs/core/ComboBox/helpers.js +50 -0
  20. package/cjs/core/Modal/Modal.d.ts +1 -1
  21. package/cjs/core/Modal/Modal.js +6 -6
  22. package/cjs/core/Modal/ModalButtonBar.d.ts +1 -1
  23. package/cjs/core/Modal/ModalButtonBar.js +2 -2
  24. package/cjs/core/Modal/ModalContent.d.ts +1 -1
  25. package/cjs/core/Modal/ModalContent.js +2 -2
  26. package/cjs/core/RadioTiles/RadioTile.d.ts +1 -1
  27. package/cjs/core/RadioTiles/RadioTile.js +7 -9
  28. package/cjs/core/Slider/Thumb.js +15 -1
  29. package/cjs/core/Slider/Track.js +23 -12
  30. package/cjs/core/Table/Table.js +19 -7
  31. package/cjs/core/Table/cells/EditableCell.js +2 -1
  32. package/cjs/core/Table/filters/FilterToggle.js +3 -2
  33. package/cjs/core/Toast/ToastWrapper.d.ts +7 -5
  34. package/cjs/core/Toast/ToastWrapper.js +8 -4
  35. package/cjs/core/Toast/Toaster.d.ts +3 -0
  36. package/cjs/core/Toast/Toaster.js +66 -5
  37. package/cjs/core/utils/components/Popover.d.ts +1 -1
  38. package/cjs/core/utils/hooks/index.d.ts +1 -0
  39. package/cjs/core/utils/hooks/index.js +1 -0
  40. package/cjs/core/utils/hooks/useSafeContext.d.ts +6 -0
  41. package/cjs/core/utils/hooks/useSafeContext.js +23 -0
  42. package/esm/core/Breadcrumbs/Breadcrumbs.js +3 -5
  43. package/esm/core/ColorPicker/ColorSwatch.d.ts +1 -1
  44. package/esm/core/ComboBox/ComboBox.d.ts +4 -2
  45. package/esm/core/ComboBox/ComboBox.js +131 -248
  46. package/esm/core/ComboBox/ComboBoxDropdown.d.ts +8 -0
  47. package/esm/core/ComboBox/ComboBoxDropdown.js +49 -0
  48. package/esm/core/ComboBox/ComboBoxEndIcon.d.ts +5 -0
  49. package/esm/core/ComboBox/ComboBoxEndIcon.js +48 -0
  50. package/esm/core/ComboBox/ComboBoxInput.d.ts +5 -0
  51. package/esm/core/ComboBox/ComboBoxInput.js +128 -0
  52. package/esm/core/ComboBox/ComboBoxInputContainer.d.ts +8 -0
  53. package/esm/core/ComboBox/ComboBoxInputContainer.js +38 -0
  54. package/esm/core/ComboBox/ComboBoxMenu.d.ts +3 -0
  55. package/esm/core/ComboBox/ComboBoxMenu.js +39 -0
  56. package/esm/core/ComboBox/ComboBoxMenuItem.d.ts +21 -0
  57. package/esm/core/ComboBox/ComboBoxMenuItem.js +59 -0
  58. package/esm/core/ComboBox/helpers.d.ts +27 -0
  59. package/esm/core/ComboBox/helpers.js +43 -0
  60. package/esm/core/Modal/Modal.d.ts +1 -1
  61. package/esm/core/Modal/Modal.js +6 -6
  62. package/esm/core/Modal/ModalButtonBar.d.ts +1 -1
  63. package/esm/core/Modal/ModalButtonBar.js +2 -2
  64. package/esm/core/Modal/ModalContent.d.ts +1 -1
  65. package/esm/core/Modal/ModalContent.js +2 -2
  66. package/esm/core/RadioTiles/RadioTile.d.ts +1 -1
  67. package/esm/core/RadioTiles/RadioTile.js +7 -9
  68. package/esm/core/Slider/Thumb.js +15 -1
  69. package/esm/core/Slider/Track.js +23 -12
  70. package/esm/core/Table/Table.js +19 -7
  71. package/esm/core/Table/cells/EditableCell.js +2 -1
  72. package/esm/core/Table/filters/FilterToggle.js +3 -2
  73. package/esm/core/Toast/ToastWrapper.d.ts +7 -5
  74. package/esm/core/Toast/ToastWrapper.js +8 -3
  75. package/esm/core/Toast/Toaster.d.ts +3 -0
  76. package/esm/core/Toast/Toaster.js +66 -5
  77. package/esm/core/utils/components/Popover.d.ts +1 -1
  78. package/esm/core/utils/hooks/index.d.ts +1 -0
  79. package/esm/core/utils/hooks/index.js +1 -0
  80. package/esm/core/utils/hooks/useSafeContext.d.ts +6 -0
  81. package/esm/core/utils/hooks/useSafeContext.js +16 -0
  82. package/package.json +6 -34
@@ -43,6 +43,16 @@ import { SELECTION_CELL_ID } from './columns';
43
43
  var singleRowSelectedAction = 'singleRowSelected';
44
44
  export var tableResizeStartAction = 'tableResizeStart';
45
45
  var tableResizeEndAction = 'tableResizeEnd';
46
+ var flattenColumns = function (columns) {
47
+ var flatColumns = [];
48
+ columns.forEach(function (column) {
49
+ flatColumns.push(column);
50
+ if (column.columns) {
51
+ flatColumns.push.apply(flatColumns, flattenColumns(column.columns));
52
+ }
53
+ });
54
+ return flatColumns;
55
+ };
46
56
  /**
47
57
  * Table based on [react-table](https://react-table.tanstack.com/docs/api/overview).
48
58
  * @example
@@ -87,10 +97,9 @@ var tableResizeEndAction = 'tableResizeEnd';
87
97
  */
88
98
  export var Table = function (props) {
89
99
  var _a;
90
- var _b;
91
- var data = props.data, columns = props.columns, _c = props.isLoading, isLoading = _c === void 0 ? false : _c, emptyTableContent = props.emptyTableContent, className = props.className, style = props.style, id = props.id, _d = props.isSelectable, isSelectable = _d === void 0 ? false : _d, onSelect = props.onSelect, onRowClick = props.onRowClick, _e = props.selectionMode, selectionMode = _e === void 0 ? 'multi' : _e, _f = props.isSortable, isSortable = _f === void 0 ? false : _f, onSort = props.onSort, stateReducer = props.stateReducer, onBottomReached = props.onBottomReached, onRowInViewport = props.onRowInViewport, _g = props.intersectionMargin, intersectionMargin = _g === void 0 ? 300 : _g, subComponent = props.subComponent, onExpand = props.onExpand, onFilter = props.onFilter, emptyFilteredTableContent = props.emptyFilteredTableContent, filterFunctions = props.filterTypes, expanderCell = props.expanderCell, isRowDisabled = props.isRowDisabled, rowProps = props.rowProps, _h = props.density, density = _h === void 0 ? 'default' : _h, _j = props.selectSubRows, selectSubRows = _j === void 0 ? true : _j, getSubRows = props.getSubRows, _k = props.selectRowOnClick, selectRowOnClick = _k === void 0 ? true : _k, paginatorRenderer = props.paginatorRenderer, _l = props.pageSize, pageSize = _l === void 0 ? 25 : _l, _m = props.isResizable, isResizable = _m === void 0 ? false : _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", "emptyFilteredTableContent", "filterTypes", "expanderCell", "isRowDisabled", "rowProps", "density", "selectSubRows", "getSubRows", "selectRowOnClick", "paginatorRenderer", "pageSize", "isResizable", "styleType", "enableVirtualization", "enableColumnReordering"]);
100
+ 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, 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", "emptyFilteredTableContent", "filterTypes", "expanderCell", "isRowDisabled", "rowProps", "density", "selectSubRows", "getSubRows", "selectRowOnClick", "paginatorRenderer", "pageSize", "isResizable", "styleType", "enableVirtualization", "enableColumnReordering"]);
92
101
  useTheme();
93
- var _r = React.useState(), ownerDocument = _r[0], setOwnerDocument = _r[1];
102
+ var _q = React.useState(), ownerDocument = _q[0], setOwnerDocument = _q[1];
94
103
  var defaultColumn = React.useMemo(function () { return ({
95
104
  maxWidth: 0,
96
105
  minWidth: 0,
@@ -103,7 +112,10 @@ export var Table = function (props) {
103
112
  onBottomReachedRef.current = onBottomReached;
104
113
  onRowInViewportRef.current = onRowInViewport;
105
114
  }, [onBottomReached, onRowInViewport]);
106
- var hasManualSelectionColumn = (_b = columns[0]) === null || _b === void 0 ? void 0 : _b.columns.some(function (column) { return column.id === SELECTION_CELL_ID; });
115
+ var hasManualSelectionColumn = React.useMemo(function () {
116
+ var flatColumns = flattenColumns(columns);
117
+ return flatColumns.some(function (column) { return column.id === SELECTION_CELL_ID; });
118
+ }, [columns]);
107
119
  var tableStateReducer = React.useCallback(function (newState, action, previousState, instance) {
108
120
  switch (action.type) {
109
121
  case TableActions.toggleSortBy:
@@ -168,7 +180,7 @@ export var Table = function (props) {
168
180
  }
169
181
  return result;
170
182
  }, {});
171
- var areFiltersSet = allColumns.some(function (column) { return !!column.filterValue; });
183
+ var areFiltersSet = allColumns.some(function (column) { return column.filterValue != null && column.filterValue !== ''; });
172
184
  var onRowClickHandler = React.useCallback(function (event, row) {
173
185
  var isDisabled = isRowDisabled === null || isRowDisabled === void 0 ? void 0 : isRowDisabled(row.original);
174
186
  if (!isDisabled) {
@@ -284,7 +296,7 @@ export var Table = function (props) {
284
296
  className: 'iui-row',
285
297
  });
286
298
  return (React.createElement("div", __assign({}, headerGroupProps, { key: headerGroupProps.key }), headerGroup.headers.map(function (column, index) {
287
- var columnProps = column.getHeaderProps(__assign(__assign({}, column.getSortByToggleProps()), { className: cx('iui-cell', { 'iui-actionable': column.canSort }, { 'iui-sorted': column.isSorted }, column.columnClassName), style: __assign({}, getCellStyle(column, !!state.isTableResizing)) }));
299
+ var columnProps = column.getHeaderProps(__assign(__assign({}, column.getSortByToggleProps()), { className: cx('iui-cell', { 'iui-actionable': column.canSort }, { 'iui-sorted': column.isSorted }, column.columnClassName), style: __assign(__assign({}, getCellStyle(column, !!state.isTableResizing)), { flexWrap: 'unset' }) }));
288
300
  return (React.createElement("div", __assign({}, columnProps, column.getDragAndDropProps(), { key: columnProps.key, title: undefined, ref: function (el) {
289
301
  if (el && isResizable) {
290
302
  columnRefs.current[column.id] = el;
@@ -293,7 +305,7 @@ export var Table = function (props) {
293
305
  } }),
294
306
  column.render('Header'),
295
307
  (data.length !== 0 || areFiltersSet) && (React.createElement(FilterToggle, { column: column, ownerDocument: ownerDocument })),
296
- data.length !== 0 && column.canSort && (React.createElement("div", { className: 'iui-cell-end-icon' }, column.isSorted && column.isSortedDesc ? (React.createElement(SvgSortUp, { className: 'iui-icon iui-sort', "aria-hidden": true })) : (React.createElement(SvgSortDown, { className: 'iui-icon iui-sort', "aria-hidden": true })))),
308
+ data.length !== 0 && column.canSort && (React.createElement("div", { className: 'iui-cell-end-icon' }, column.isSorted && column.isSortedDesc ? (React.createElement(SvgSortDown, { className: 'iui-icon iui-sort', "aria-hidden": true })) : (React.createElement(SvgSortUp, { className: 'iui-icon iui-sort', "aria-hidden": true })))),
297
309
  isResizable &&
298
310
  column.isResizerVisible &&
299
311
  index !== headerGroup.headers.length - 1 && (React.createElement("div", __assign({}, column.getResizerProps(), { className: 'iui-resizer' }),
@@ -36,7 +36,8 @@ import React from 'react';
36
36
  * }
37
37
  */
38
38
  export var EditableCell = function (props) {
39
- var cellElementProps = props.cellElementProps, cellProps = props.cellProps, onCellEdit = props.onCellEdit, children = props.children, rest = __rest(props, ["cellElementProps", "cellProps", "onCellEdit", "children"]);
39
+ var cellElementProps = props.cellElementProps, cellProps = props.cellProps, onCellEdit = props.onCellEdit, children = props.children, isDisabled = props.isDisabled, rest = __rest(props, ["cellElementProps", "cellProps", "onCellEdit", "children", "isDisabled"]);
40
+ isDisabled; // To omit and prevent eslint error.
40
41
  var sanitizeString = function (text) {
41
42
  return text.replace(/(\r\n|\n|\r)+/gm, ' ');
42
43
  };
@@ -47,10 +47,11 @@ export var FilterToggle = function (props) {
47
47
  column.setFilter(undefined);
48
48
  close();
49
49
  }, [close, column]);
50
+ var isColumnFiltered = column.filterValue != null && column.filterValue !== '';
50
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
- React.createElement(IconButton, __assign({ styleType: 'borderless', isActive: isVisible || column.filterValue, className: cx('iui-filter-button', className), onClick: function (e) {
52
+ React.createElement(IconButton, __assign({ styleType: 'borderless', isActive: isVisible || isColumnFiltered, className: cx('iui-filter-button', className), onClick: function (e) {
52
53
  setIsVisible(function (v) { return !v; });
53
54
  // Prevents from triggering sort
54
55
  e.stopPropagation();
55
- } }, rest), column.filterValue ? React.createElement(SvgFilter, null) : React.createElement(SvgFilterHollow, null))))));
56
+ } }, rest), isColumnFiltered ? React.createElement(SvgFilter, null) : React.createElement(SvgFilterHollow, null))))));
56
57
  };
@@ -1,9 +1,11 @@
1
- /// <reference types="react" />
2
1
  import '@itwin/itwinui-css/css/toast-notification.css';
2
+ import React from 'react';
3
3
  import { ToastProps } from './Toast';
4
4
  import { ToasterSettings } from './Toaster';
5
- declare type ToastWrapperProps = {
6
- toasts: ToastProps[];
7
- } & Pick<ToasterSettings, 'placement'>;
8
- export declare const ToastWrapper: (props: ToastWrapperProps) => JSX.Element;
5
+ declare type ToastPlacement = NonNullable<ToasterSettings['placement']>;
6
+ export declare type ToastWrapperHandle = {
7
+ setToasts: (toasts: ToastProps[]) => void;
8
+ setPlacement: (placement: ToastPlacement) => void;
9
+ };
10
+ export declare const ToastWrapper: React.ForwardRefExoticComponent<React.RefAttributes<ToastWrapperHandle>>;
9
11
  export {};
@@ -17,10 +17,15 @@ import '@itwin/itwinui-css/css/toast-notification.css';
17
17
  import React from 'react';
18
18
  import cx from 'classnames';
19
19
  import Toast from './Toast';
20
- export var ToastWrapper = function (props) {
21
- var toasts = props.toasts, _a = props.placement, placement = _a === void 0 ? 'top' : _a;
20
+ export var ToastWrapper = React.forwardRef(function (_, ref) {
21
+ var _a = React.useState([]), toasts = _a[0], setToasts = _a[1];
22
+ var _b = React.useState('top'), placement = _b[0], setPlacement = _b[1];
22
23
  var placementPosition = placement.startsWith('top') ? 'top' : 'bottom';
24
+ React.useImperativeHandle(ref, function () { return ({
25
+ setToasts: setToasts,
26
+ setPlacement: setPlacement,
27
+ }); }, []);
23
28
  return (React.createElement("span", { className: cx("iui-toast-wrapper", "iui-placement-".concat(placement)) }, toasts.map(function (toastProps) {
24
29
  return (React.createElement(Toast, __assign({ key: toastProps.id, placementPosition: placementPosition }, toastProps)));
25
30
  })));
26
- };
31
+ });
@@ -20,6 +20,8 @@ export default class Toaster {
20
20
  private toasts;
21
21
  private lastId;
22
22
  private settings;
23
+ private toastsRef;
24
+ private isInitialized;
23
25
  /**
24
26
  * Set global Toaster settings for toasts order and placement.
25
27
  * Settings will be applied to new toasts on the page.
@@ -39,6 +41,7 @@ export default class Toaster {
39
41
  };
40
42
  private createToast;
41
43
  private removeToast;
44
+ private createContainer;
42
45
  private updateView;
43
46
  private closeToast;
44
47
  closeAll(): void;
@@ -9,6 +9,42 @@ var __assign = (this && this.__assign) || function () {
9
9
  };
10
10
  return __assign.apply(this, arguments);
11
11
  };
12
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
13
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
14
+ return new (P || (P = Promise))(function (resolve, reject) {
15
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
16
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
17
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
18
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
19
+ });
20
+ };
21
+ var __generator = (this && this.__generator) || function (thisArg, body) {
22
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
23
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
24
+ function verb(n) { return function (v) { return step([n, v]); }; }
25
+ function step(op) {
26
+ if (f) throw new TypeError("Generator is already executing.");
27
+ while (_) try {
28
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
29
+ if (y = 0, t) op = [op[0] & 2, t.value];
30
+ switch (op[0]) {
31
+ case 0: case 1: t = op; break;
32
+ case 4: _.label++; return { value: op[1], done: false };
33
+ case 5: _.label++; y = op[1]; op = [0]; continue;
34
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
35
+ default:
36
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
37
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
38
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
39
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
40
+ if (t[2]) _.ops.pop();
41
+ _.trys.pop(); continue;
42
+ }
43
+ op = body.call(thisArg, _);
44
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
45
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
46
+ }
47
+ };
12
48
  var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
13
49
  if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
14
50
  if (ar || !(i in from)) {
@@ -35,18 +71,21 @@ var Toaster = /** @class */ (function () {
35
71
  order: 'descending',
36
72
  placement: 'top',
37
73
  };
74
+ this.toastsRef = React.createRef();
75
+ this.isInitialized = false;
38
76
  }
39
77
  /**
40
78
  * Set global Toaster settings for toasts order and placement.
41
79
  * Settings will be applied to new toasts on the page.
42
80
  */
43
81
  Toaster.prototype.setSettings = function (newSettings) {
44
- var _a, _b, _c;
82
+ var _a, _b, _c, _d, _e;
45
83
  (_a = newSettings.placement) !== null && _a !== void 0 ? _a : (newSettings.placement = this.settings.placement);
46
84
  (_b = newSettings.order) !== null && _b !== void 0 ? _b : (newSettings.order = ((_c = newSettings.placement) === null || _c === void 0 ? void 0 : _c.startsWith('bottom'))
47
85
  ? 'ascending'
48
86
  : 'descending');
49
87
  this.settings = newSettings;
88
+ (_d = this.toastsRef.current) === null || _d === void 0 ? void 0 : _d.setPlacement((_e = this.settings.placement) !== null && _e !== void 0 ? _e : 'top');
50
89
  };
51
90
  Toaster.prototype.positive = function (content, options) {
52
91
  return this.createToast(content, 'positive', options);
@@ -78,12 +117,34 @@ var Toaster = /** @class */ (function () {
78
117
  this.toasts = this.toasts.filter(function (toast) { return toast.id !== id; });
79
118
  this.updateView();
80
119
  };
120
+ // Create container on demand.
121
+ // Cannot do it in constructor, because SSG/SSR apps would fail.
122
+ Toaster.prototype.createContainer = function () {
123
+ return __awaiter(this, void 0, void 0, function () {
124
+ var container;
125
+ return __generator(this, function (_a) {
126
+ container = getContainer(TOASTS_CONTAINER_ID);
127
+ if (!container) {
128
+ return [2 /*return*/];
129
+ }
130
+ ReactDOM.render(React.createElement(ToastWrapper, { ref: this.toastsRef }), container);
131
+ return [2 /*return*/];
132
+ });
133
+ });
134
+ };
81
135
  Toaster.prototype.updateView = function () {
82
- var container = getContainer(TOASTS_CONTAINER_ID);
83
- if (!container) {
84
- return;
136
+ var _this = this;
137
+ var _a;
138
+ if (!this.isInitialized) {
139
+ this.createContainer().then(function () {
140
+ var _a;
141
+ _this.isInitialized = true;
142
+ (_a = _this.toastsRef.current) === null || _a === void 0 ? void 0 : _a.setToasts(_this.toasts);
143
+ });
144
+ }
145
+ else {
146
+ (_a = this.toastsRef.current) === null || _a === void 0 ? void 0 : _a.setToasts(this.toasts);
85
147
  }
86
- ReactDOM.render(React.createElement(ToastWrapper, { toasts: this.toasts, placement: this.settings.placement }), container);
87
148
  };
88
149
  Toaster.prototype.closeToast = function (toastId) {
89
150
  this.toasts = this.toasts.map(function (toast) {
@@ -43,7 +43,7 @@ export declare const Popover: React.ForwardRefExoticComponent<Pick<{
43
43
  * @see [tippy.js placement prop](https://atomiks.github.io/tippyjs/v6/all-props/#placement).
44
44
  */
45
45
  placement?: import("@popperjs/core").Placement | undefined;
46
- } & Omit<TippyProps, "placement" | "trigger" | "visible">, "disabled" | "placement" | "trigger" | "visible" | "content" | "render" | "animateFill" | "appendTo" | "aria" | "delay" | "duration" | "followCursor" | "getReferenceClientRect" | "hideOnClick" | "ignoreAttributes" | "inlinePositioning" | "interactive" | "interactiveBorder" | "interactiveDebounce" | "moveTransition" | "offset" | "plugins" | "popperOptions" | "showOnCreate" | "sticky" | "touch" | "triggerTarget" | "onAfterUpdate" | "onBeforeUpdate" | "onCreate" | "onDestroy" | "onHidden" | "onHide" | "onMount" | "onShow" | "onShown" | "onTrigger" | "onUntrigger" | "onClickOutside" | "allowHTML" | "animation" | "arrow" | "inertia" | "maxWidth" | "role" | "theme" | "zIndex" | "children" | "className" | "singleton" | "reference"> & React.RefAttributes<unknown>>;
46
+ } & Omit<TippyProps, "placement" | "trigger" | "visible">, "disabled" | "children" | "placement" | "trigger" | "visible" | "content" | "render" | "animateFill" | "appendTo" | "aria" | "delay" | "duration" | "followCursor" | "getReferenceClientRect" | "hideOnClick" | "ignoreAttributes" | "inlinePositioning" | "interactive" | "interactiveBorder" | "interactiveDebounce" | "moveTransition" | "offset" | "plugins" | "popperOptions" | "showOnCreate" | "sticky" | "touch" | "triggerTarget" | "onAfterUpdate" | "onBeforeUpdate" | "onCreate" | "onDestroy" | "onHidden" | "onHide" | "onMount" | "onShow" | "onShown" | "onTrigger" | "onUntrigger" | "onClickOutside" | "allowHTML" | "animation" | "arrow" | "inertia" | "maxWidth" | "role" | "theme" | "zIndex" | "className" | "singleton" | "reference"> & React.RefAttributes<unknown>>;
47
47
  /**
48
48
  * Plugin to hide Popover when either Esc key is pressed,
49
49
  * or when the content inside is not tabbable and Tab key is pressed.
@@ -6,3 +6,4 @@ export * from './useContainerWidth';
6
6
  export * from './useTheme';
7
7
  export * from './useIntersection';
8
8
  export * from './useMediaQuery';
9
+ export * from './useSafeContext';
@@ -10,3 +10,4 @@ export * from './useContainerWidth';
10
10
  export * from './useTheme';
11
11
  export * from './useIntersection';
12
12
  export * from './useMediaQuery';
13
+ export * from './useSafeContext';
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ /**
3
+ * Wrapper hook around `useContext` that throws an error if the context is not provided.
4
+ * @param context Context to use. Must have a `displayName` for useful errors.
5
+ */
6
+ export declare const useSafeContext: <T>(context: React.Context<T>) => NonNullable<T>;
@@ -0,0 +1,16 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the project root for license terms and full copyright notice.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import React from 'react';
6
+ /**
7
+ * Wrapper hook around `useContext` that throws an error if the context is not provided.
8
+ * @param context Context to use. Must have a `displayName` for useful errors.
9
+ */
10
+ export var useSafeContext = function (context) {
11
+ var value = React.useContext(context);
12
+ if (!value) {
13
+ throw new Error("".concat(context.displayName, " is undefined"));
14
+ }
15
+ return value; // eslint-disable-line @typescript-eslint/no-non-null-assertion -- we already checked for undefined
16
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itwin/itwinui-react",
3
- "version": "1.37.1",
3
+ "version": "1.38.0",
4
4
  "author": "Bentley Systems",
5
5
  "license": "MIT",
6
6
  "main": "cjs/index.js",
@@ -38,15 +38,14 @@
38
38
  "createComponent": "node scripts/createComponent.js",
39
39
  "format": "prettier --config .prettierrc **/*.{tsx,ts,js} --ignore-path .gitignore --write",
40
40
  "lint": "eslint \"**/*.{js,ts,tsx}\" --max-warnings=0",
41
- "lint:fix": "yarn lint --fix && yarn lint:copyright --fix */**/*.{js,ts,tsx}",
42
- "lint:copyright": "node scripts/copyrightLinter.js",
43
- "copy-files": "cpx \"../../{README,LICENSE}.md\" .",
41
+ "lint:fix": "yarn lint --fix && node ../configs/copyrightLinter.js --fix \"*/**/*.{js,ts,tsx}\"",
42
+ "copy-files": "cpy \"../../{README,LICENSE}.md\" .",
44
43
  "storybook": "start-storybook -p 6006",
45
44
  "dev": "yarn storybook",
46
- "build-storybook": "build-storybook"
45
+ "build-storybook": "yarn copy-files && build-storybook"
47
46
  },
48
47
  "dependencies": {
49
- "@itwin/itwinui-css": "^0.55.0",
48
+ "@itwin/itwinui-css": "^0.58.0",
50
49
  "@itwin/itwinui-icons-react": "^1.5.0",
51
50
  "@itwin/itwinui-illustrations-react": "^1.0.1",
52
51
  "@tippyjs/react": "^4.2.5",
@@ -84,20 +83,14 @@
84
83
  "babel-loader": "^8.2.2",
85
84
  "concurrently": "^5.3.0",
86
85
  "configs": "*",
87
- "cpx": "^1.5.0",
88
86
  "creevey": "^0.8.0-beta.0",
89
- "fast-glob": "^3.2.5",
90
- "husky": "^4.0.0",
91
87
  "inquirer": "^6.2.2",
92
88
  "jest": "^27.0.6",
93
89
  "jest-cli": "^27.0.6",
94
90
  "jest-junit": "^12.0.0",
95
- "lint-staged": "^12.1.2",
96
91
  "markdown-to-jsx": "6.11.4",
97
- "mkdirp": "^1.0.4",
98
92
  "react": "^17.0.2",
99
93
  "react-dom": "^17.0.2",
100
- "rimraf": "^2.6.2",
101
94
  "storybook-dark-mode": "^1.0.9",
102
95
  "tippy.js": "^6.3.1",
103
96
  "ts-jest": "^27.0.4",
@@ -110,32 +103,11 @@
110
103
  "react": "^16.8.6 || ^17.0.0",
111
104
  "react-dom": "^16.8.6 || ^17.0.0"
112
105
  },
113
- "resolutions": {
114
- "braces": "^2.3.1",
115
- "hosted-git-info": ">=3.0.8",
116
- "trim": "^0.0.3",
117
- "browserslist": "^4.16.6",
118
- "glob-parent": "^5.1.2",
119
- "css-what": "^5.0.1",
120
- "immer": "^9.0.6",
121
- "set-value": "^4.1.0",
122
- "prismjs": "^1.25.0",
123
- "nth-check": "^2.0.1",
124
- "ansi-regex": "^5.0.1",
125
- "@pmmmwh/react-refresh-webpack-plugin": "^0.5.1",
126
- "postcss": "8",
127
- "nanoid": "^3.1.31"
128
- },
129
- "husky": {
130
- "hooks": {
131
- "pre-commit": "lint-staged"
132
- }
133
- },
134
106
  "lint-staged": {
135
107
  "*.{tsx,ts,jsx,js}": [
136
108
  "prettier --write",
137
109
  "eslint --max-warnings=0 --fix",
138
- "yarn lint:copyright --fix"
110
+ "node ../configs/copyrightLinter.js --fix"
139
111
  ]
140
112
  },
141
113
  "prettier": "configs/prettier-config",