@itwin/itwinui-react 1.37.3 → 1.39.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 (112) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/cjs/core/Breadcrumbs/Breadcrumbs.js +3 -5
  3. package/cjs/core/Carousel/Carousel.js +21 -12
  4. package/cjs/core/Carousel/CarouselContext.d.ts +4 -2
  5. package/cjs/core/Carousel/CarouselDotsList.js +1 -0
  6. package/cjs/core/Carousel/CarouselNavigation.js +8 -10
  7. package/cjs/core/Carousel/CarouselSlide.js +3 -7
  8. package/cjs/core/Carousel/CarouselSlider.js +23 -28
  9. package/cjs/core/ColorPicker/ColorPickerContext.d.ts +2 -2
  10. package/cjs/core/ColorPicker/ColorSwatch.d.ts +1 -1
  11. package/cjs/core/ComboBox/ComboBox.d.ts +11 -2
  12. package/cjs/core/ComboBox/ComboBox.js +138 -246
  13. package/cjs/core/ComboBox/ComboBoxDropdown.d.ts +7 -0
  14. package/cjs/core/ComboBox/ComboBoxDropdown.js +55 -0
  15. package/cjs/core/ComboBox/ComboBoxEndIcon.d.ts +5 -0
  16. package/cjs/core/ComboBox/ComboBoxEndIcon.js +54 -0
  17. package/cjs/core/ComboBox/ComboBoxInput.d.ts +5 -0
  18. package/cjs/core/ComboBox/ComboBoxInput.js +152 -0
  19. package/cjs/core/ComboBox/ComboBoxInputContainer.d.ts +8 -0
  20. package/cjs/core/ComboBox/ComboBoxInputContainer.js +45 -0
  21. package/cjs/core/ComboBox/ComboBoxMenu.d.ts +3 -0
  22. package/cjs/core/ComboBox/ComboBoxMenu.js +89 -0
  23. package/cjs/core/ComboBox/ComboBoxMenuItem.d.ts +21 -0
  24. package/cjs/core/ComboBox/ComboBoxMenuItem.js +64 -0
  25. package/cjs/core/ComboBox/helpers.d.ts +32 -0
  26. package/cjs/core/ComboBox/helpers.js +50 -0
  27. package/cjs/core/DatePicker/DatePicker.d.ts +1 -1
  28. package/cjs/core/Modal/Modal.d.ts +1 -1
  29. package/cjs/core/Modal/Modal.js +6 -6
  30. package/cjs/core/Modal/ModalButtonBar.d.ts +1 -1
  31. package/cjs/core/Modal/ModalButtonBar.js +2 -2
  32. package/cjs/core/Modal/ModalContent.d.ts +1 -1
  33. package/cjs/core/Modal/ModalContent.js +2 -2
  34. package/cjs/core/RadioTiles/RadioTile.d.ts +1 -1
  35. package/cjs/core/RadioTiles/RadioTile.js +7 -9
  36. package/cjs/core/Select/Select.js +1 -1
  37. package/cjs/core/Table/Table.js +33 -23
  38. package/cjs/core/Table/TablePaginator.js +1 -1
  39. package/cjs/core/Table/filters/FilterToggle.js +3 -2
  40. package/cjs/core/Table/filters/tableFilters.d.ts +3 -3
  41. package/cjs/core/Table/hooks/useExpanderCell.js +11 -1
  42. package/cjs/core/Toast/ToastWrapper.d.ts +7 -5
  43. package/cjs/core/Toast/ToastWrapper.js +8 -4
  44. package/cjs/core/Toast/Toaster.d.ts +3 -0
  45. package/cjs/core/Toast/Toaster.js +110 -6
  46. package/cjs/core/utils/components/Popover.d.ts +1 -18
  47. package/cjs/core/utils/components/VirtualScroll.d.ts +35 -1
  48. package/cjs/core/utils/components/VirtualScroll.js +159 -26
  49. package/cjs/core/utils/components/WithCSSTransition.d.ts +1 -2
  50. package/cjs/core/utils/components/icons.d.ts +4 -4
  51. package/cjs/core/utils/hooks/index.d.ts +1 -0
  52. package/cjs/core/utils/hooks/index.js +1 -0
  53. package/cjs/core/utils/hooks/useOverflow.js +4 -2
  54. package/cjs/core/utils/hooks/useSafeContext.d.ts +6 -0
  55. package/cjs/core/utils/hooks/useSafeContext.js +23 -0
  56. package/cjs/core/utils/hooks/useTheme.d.ts +1 -1
  57. package/esm/core/Breadcrumbs/Breadcrumbs.js +3 -5
  58. package/esm/core/Carousel/Carousel.js +21 -12
  59. package/esm/core/Carousel/CarouselContext.d.ts +4 -2
  60. package/esm/core/Carousel/CarouselDotsList.js +1 -0
  61. package/esm/core/Carousel/CarouselNavigation.js +8 -10
  62. package/esm/core/Carousel/CarouselSlide.js +3 -7
  63. package/esm/core/Carousel/CarouselSlider.js +24 -29
  64. package/esm/core/ColorPicker/ColorPickerContext.d.ts +2 -2
  65. package/esm/core/ColorPicker/ColorSwatch.d.ts +1 -1
  66. package/esm/core/ComboBox/ComboBox.d.ts +11 -2
  67. package/esm/core/ComboBox/ComboBox.js +140 -248
  68. package/esm/core/ComboBox/ComboBoxDropdown.d.ts +7 -0
  69. package/esm/core/ComboBox/ComboBoxDropdown.js +49 -0
  70. package/esm/core/ComboBox/ComboBoxEndIcon.d.ts +5 -0
  71. package/esm/core/ComboBox/ComboBoxEndIcon.js +48 -0
  72. package/esm/core/ComboBox/ComboBoxInput.d.ts +5 -0
  73. package/esm/core/ComboBox/ComboBoxInput.js +146 -0
  74. package/esm/core/ComboBox/ComboBoxInputContainer.d.ts +8 -0
  75. package/esm/core/ComboBox/ComboBoxInputContainer.js +38 -0
  76. package/esm/core/ComboBox/ComboBoxMenu.d.ts +3 -0
  77. package/esm/core/ComboBox/ComboBoxMenu.js +83 -0
  78. package/esm/core/ComboBox/ComboBoxMenuItem.d.ts +21 -0
  79. package/esm/core/ComboBox/ComboBoxMenuItem.js +58 -0
  80. package/esm/core/ComboBox/helpers.d.ts +32 -0
  81. package/esm/core/ComboBox/helpers.js +43 -0
  82. package/esm/core/DatePicker/DatePicker.d.ts +1 -1
  83. package/esm/core/Modal/Modal.d.ts +1 -1
  84. package/esm/core/Modal/Modal.js +6 -6
  85. package/esm/core/Modal/ModalButtonBar.d.ts +1 -1
  86. package/esm/core/Modal/ModalButtonBar.js +2 -2
  87. package/esm/core/Modal/ModalContent.d.ts +1 -1
  88. package/esm/core/Modal/ModalContent.js +2 -2
  89. package/esm/core/RadioTiles/RadioTile.d.ts +1 -1
  90. package/esm/core/RadioTiles/RadioTile.js +7 -9
  91. package/esm/core/Select/Select.js +1 -1
  92. package/esm/core/Table/Table.js +33 -23
  93. package/esm/core/Table/TablePaginator.js +1 -1
  94. package/esm/core/Table/filters/FilterToggle.js +3 -2
  95. package/esm/core/Table/filters/tableFilters.d.ts +3 -3
  96. package/esm/core/Table/hooks/useExpanderCell.js +8 -1
  97. package/esm/core/Toast/ToastWrapper.d.ts +7 -5
  98. package/esm/core/Toast/ToastWrapper.js +8 -3
  99. package/esm/core/Toast/Toaster.d.ts +3 -0
  100. package/esm/core/Toast/Toaster.js +88 -7
  101. package/esm/core/utils/components/Popover.d.ts +1 -18
  102. package/esm/core/utils/components/VirtualScroll.d.ts +35 -1
  103. package/esm/core/utils/components/VirtualScroll.js +157 -25
  104. package/esm/core/utils/components/WithCSSTransition.d.ts +1 -2
  105. package/esm/core/utils/components/icons.d.ts +4 -4
  106. package/esm/core/utils/hooks/index.d.ts +1 -0
  107. package/esm/core/utils/hooks/index.js +1 -0
  108. package/esm/core/utils/hooks/useOverflow.js +4 -2
  109. package/esm/core/utils/hooks/useSafeContext.d.ts +6 -0
  110. package/esm/core/utils/hooks/useSafeContext.js +16 -0
  111. package/esm/core/utils/hooks/useTheme.d.ts +1 -1
  112. package/package.json +27 -70
@@ -25,6 +25,7 @@ var __rest = (this && this.__rest) || function (s, e) {
25
25
  * See LICENSE.md in the project root for license terms and full copyright notice.
26
26
  *--------------------------------------------------------------------------------------------*/
27
27
  import React from 'react';
28
+ import { mergeRefs } from '../hooks';
28
29
  import { useResizeObserver } from '../hooks/useResizeObserver';
29
30
  var getScrollableParent = function (element, ownerDocument) {
30
31
  if (ownerDocument === void 0) { ownerDocument = document; }
@@ -46,6 +47,14 @@ var getElementHeight = function (element) {
46
47
  var _a;
47
48
  return (_a = element === null || element === void 0 ? void 0 : element.getBoundingClientRect().height) !== null && _a !== void 0 ? _a : 0;
48
49
  };
50
+ var getElementHeightWithMargins = function (element) {
51
+ if (!element) {
52
+ return undefined;
53
+ }
54
+ var margin = parseFloat(getElementStyle(element, 'margin-top')) +
55
+ parseFloat(getElementStyle(element, 'margin-bottom'));
56
+ return getElementHeight(element) + (isNaN(margin) ? 0 : margin);
57
+ };
49
58
  var getNumberOfNodesInHeight = function (childHeight, totalHeight) {
50
59
  if (!childHeight) {
51
60
  return 0;
@@ -53,7 +62,10 @@ var getNumberOfNodesInHeight = function (childHeight, totalHeight) {
53
62
  return Math.floor(totalHeight / childHeight);
54
63
  };
55
64
  var getTranslateValue = function (childHeight, startIndex) {
56
- return childHeight * startIndex;
65
+ if (startIndex > 0) {
66
+ return childHeight * startIndex;
67
+ }
68
+ return 0;
57
69
  };
58
70
  var getVisibleNodeCount = function (childHeight, startIndex, childrenLength, scrollContainer) {
59
71
  return Math.min(childrenLength - startIndex, getNumberOfNodesInHeight(childHeight, getElementHeight(scrollContainer)));
@@ -79,21 +91,55 @@ var getVisibleNodeCount = function (childHeight, startIndex, childrenLength, scr
79
91
  * />
80
92
  * @private
81
93
  */
82
- export var VirtualScroll = React.forwardRef(function (_a, ref) {
83
- var itemsLength = _a.itemsLength, itemRenderer = _a.itemRenderer, _b = _a.bufferSize, bufferSize = _b === void 0 ? 10 : _b, style = _a.style, rest = __rest(_a, ["itemsLength", "itemRenderer", "bufferSize", "style"]);
84
- var _c = React.useState(0), startNode = _c[0], setStartNode = _c[1];
85
- var _d = React.useState(0), visibleNodeCount = _d[0], setVisibleNodeCount = _d[1];
94
+ export var VirtualScroll = React.forwardRef(function (props, ref) {
95
+ var _a = useVirtualization(props), innerProps = _a.innerProps, outerProps = _a.outerProps, visibleChildren = _a.visibleChildren;
96
+ return (React.createElement("div", __assign({}, outerProps, { ref: ref }),
97
+ React.createElement("div", __assign({}, innerProps), visibleChildren)));
98
+ });
99
+ /**
100
+ * `useVirtualization` is used for efficiently rendering only the visible rows from a large list.
101
+ * It returns `outerProps` and `innerProps`, which need to be applied on 2 container elements and `visibleChildren` which is a list of virtualized items.
102
+ * @example
103
+ * const itemRenderer = React.useCallback((index: number) => (
104
+ * <li key={index}>
105
+ * This is my item #{index}
106
+ * </li>
107
+ * ), [])
108
+ *
109
+ * const { outerProps, innerProps, visibleChildren } = useVirtualization({itemsLength: 1000, itemRenderer: itemRenderer});
110
+ * return (
111
+ * <div {...outerProps}>
112
+ * <ul {...innerProps}>
113
+ * {visibleChildren}
114
+ * </ul>
115
+ * </div>
116
+ * );
117
+ * @private
118
+ */
119
+ export var useVirtualization = function (props) {
120
+ var itemsLength = props.itemsLength, itemRenderer = props.itemRenderer, _a = props.bufferSize, bufferSize = _a === void 0 ? 10 : _a, scrollToIndex = props.scrollToIndex, style = props.style, rest = __rest(props, ["itemsLength", "itemRenderer", "bufferSize", "scrollToIndex", "style"]);
121
+ var _b = React.useState(0), startNode = _b[0], setStartNode = _b[1];
122
+ var _c = React.useState(0), visibleNodeCount = _c[0], setVisibleNodeCount = _c[1];
86
123
  var scrollContainer = React.useRef();
87
124
  var parentRef = React.useRef(null);
88
- var childHeight = React.useRef(0);
125
+ var childHeight = React.useRef({ first: 0, middle: 0, last: 0 });
89
126
  var onScrollRef = React.useRef();
90
127
  // Used only to recalculate on resize
91
- var _e = React.useState(0), scrollContainerHeight = _e[0], setScrollContainerHeight = _e[1];
128
+ var _d = React.useState(0), scrollContainerHeight = _d[0], setScrollContainerHeight = _d[1];
129
+ var visibleIndex = React.useRef({ start: 0, end: 0 });
130
+ // Used to mark when scroll container has height (updated by resize observer)
131
+ // because before that calculations are not right
132
+ var _e = React.useState(false), isMounted = _e[0], setIsMounted = _e[1];
92
133
  var onResize = React.useCallback(function (_a) {
93
134
  var height = _a.height;
135
+ // Initial value returned by resize observer is 0
136
+ // So wait for the next one
137
+ if (height > 0) {
138
+ setIsMounted(true);
139
+ }
94
140
  setScrollContainerHeight(height);
95
141
  }, []);
96
- var resizeRef = useResizeObserver(onResize)[0];
142
+ var _f = useResizeObserver(onResize), resizeRef = _f[0], resizeObserver = _f[1];
97
143
  // Find scrollable parent
98
144
  // Needed only on init
99
145
  React.useLayoutEffect(function () {
@@ -102,6 +148,14 @@ export var VirtualScroll = React.forwardRef(function (_a, ref) {
102
148
  scrollContainer.current = scrollableParent;
103
149
  resizeRef(scrollableParent);
104
150
  }, [resizeRef]);
151
+ // Stop watching resize, when virtual scroll is unmounted
152
+ React.useLayoutEffect(function () {
153
+ return function () { return resizeObserver === null || resizeObserver === void 0 ? void 0 : resizeObserver.disconnect(); };
154
+ }, [resizeObserver]);
155
+ var getScrollableContainer = function () {
156
+ var _a, _b;
157
+ return (_a = scrollContainer.current) !== null && _a !== void 0 ? _a : (_b = parentRef.current) === null || _b === void 0 ? void 0 : _b.ownerDocument.scrollingElement;
158
+ };
105
159
  var visibleChildren = React.useMemo(function () {
106
160
  var arr = [];
107
161
  var endIndex = Math.min(itemsLength, startNode + visibleNodeCount + bufferSize * 2);
@@ -112,27 +166,42 @@ export var VirtualScroll = React.forwardRef(function (_a, ref) {
112
166
  }, [itemsLength, itemRenderer, bufferSize, startNode, visibleNodeCount]);
113
167
  // Get child height when children available
114
168
  React.useLayoutEffect(function () {
169
+ var _a, _b, _c, _d, _e, _f;
115
170
  if (!parentRef.current || !visibleChildren.length) {
116
171
  return;
117
172
  }
118
173
  var firstChild = parentRef.current.children.item(0);
119
- childHeight.current = Number(getElementHeight(firstChild).toFixed(2));
174
+ var secondChild = parentRef.current.children.item(1);
175
+ var lastChild = parentRef.current.children.item(parentRef.current.children.length - 1);
176
+ var firstChildHeight = Number((_b = (_a = getElementHeightWithMargins(firstChild)) === null || _a === void 0 ? void 0 : _a.toFixed(2)) !== null && _b !== void 0 ? _b : 0);
177
+ childHeight.current = {
178
+ first: firstChildHeight,
179
+ middle: Number((_d = (_c = getElementHeightWithMargins(secondChild)) === null || _c === void 0 ? void 0 : _c.toFixed(2)) !== null && _d !== void 0 ? _d : firstChildHeight),
180
+ last: Number((_f = (_e = getElementHeightWithMargins(lastChild)) === null || _e === void 0 ? void 0 : _e.toFixed(2)) !== null && _f !== void 0 ? _f : firstChildHeight),
181
+ };
120
182
  }, [visibleChildren.length]);
121
183
  var updateVirtualScroll = React.useCallback(function () {
122
- var _a, _b;
123
- var scrollableContainer = (_a = scrollContainer.current) !== null && _a !== void 0 ? _a : (_b = parentRef.current) === null || _b === void 0 ? void 0 : _b.ownerDocument.scrollingElement;
184
+ var scrollableContainer = getScrollableContainer();
124
185
  if (!scrollableContainer) {
125
186
  return;
126
187
  }
127
- var start = getNumberOfNodesInHeight(childHeight.current, scrollableContainer.scrollTop);
128
- var startIndex = Math.max(0, start - bufferSize);
188
+ var start = getNumberOfNodesInHeight(childHeight.current.middle, Math.round(scrollableContainer.scrollTop));
189
+ var visibleNodes = getVisibleNodeCount(childHeight.current.middle, start, itemsLength, scrollableContainer);
190
+ // If there are less items at the end than buffer size
191
+ // show more items at the start.
192
+ // Have boundaries for edge cases, e.g. 1 item length
193
+ var startIndex = Math.min(Math.max(0, start - bufferSize), Math.max(0, itemsLength - bufferSize * 2 - visibleNodes));
194
+ visibleIndex.current = { start: start, end: start + visibleNodes };
129
195
  setStartNode(startIndex);
130
- setVisibleNodeCount(getVisibleNodeCount(childHeight.current, start, itemsLength, scrollableContainer));
196
+ setVisibleNodeCount(visibleNodes);
131
197
  if (!parentRef.current) {
132
198
  return;
133
199
  }
134
- parentRef.current.style.transform = "translateY(".concat(getTranslateValue(childHeight.current, startIndex), "px)");
200
+ parentRef.current.style.transform = "translateY(".concat(getTranslateValue(childHeight.current.middle, startIndex), "px)");
135
201
  }, [bufferSize, itemsLength]);
202
+ var onScroll = React.useCallback(function () {
203
+ updateVirtualScroll();
204
+ }, [updateVirtualScroll]);
136
205
  var removeScrollListener = React.useCallback(function () {
137
206
  var _a, _b;
138
207
  if (!onScrollRef.current) {
@@ -147,22 +216,85 @@ export var VirtualScroll = React.forwardRef(function (_a, ref) {
147
216
  React.useLayoutEffect(function () {
148
217
  var _a, _b;
149
218
  removeScrollListener();
150
- onScrollRef.current = updateVirtualScroll;
219
+ onScrollRef.current = onScroll;
151
220
  if (!scrollContainer.current ||
152
221
  scrollContainer.current === ((_a = parentRef.current) === null || _a === void 0 ? void 0 : _a.ownerDocument.body)) {
153
- (_b = parentRef.current) === null || _b === void 0 ? void 0 : _b.ownerDocument.addEventListener('scroll', updateVirtualScroll);
222
+ (_b = parentRef.current) === null || _b === void 0 ? void 0 : _b.ownerDocument.addEventListener('scroll', onScroll);
154
223
  }
155
224
  else {
156
- scrollContainer.current.addEventListener('scroll', updateVirtualScroll);
225
+ scrollContainer.current.addEventListener('scroll', onScroll);
157
226
  }
158
227
  return removeScrollListener;
159
- }, [updateVirtualScroll, removeScrollListener]);
228
+ }, [onScroll, removeScrollListener]);
229
+ React.useLayoutEffect(function () {
230
+ if (!isMounted) {
231
+ return;
232
+ }
233
+ var scrollableContainer = getScrollableContainer();
234
+ if (!scrollableContainer || scrollToIndex == null) {
235
+ return;
236
+ }
237
+ // if `scrollToIndex` is not visible, scroll to it
238
+ if (scrollToIndex > visibleIndex.current.end ||
239
+ scrollToIndex < visibleIndex.current.start) {
240
+ var indexDiff = scrollToIndex > visibleIndex.current.end
241
+ ? scrollToIndex - visibleIndex.current.end
242
+ : scrollToIndex - visibleIndex.current.start;
243
+ if (scrollToIndex === 0) {
244
+ scrollableContainer.scrollTo({ top: 0 });
245
+ return;
246
+ }
247
+ // If go down: add to the existing scrollTop needed height
248
+ // If go up: calculate the exact scroll top
249
+ scrollableContainer.scrollTo({
250
+ top: indexDiff > 0
251
+ ? Math.ceil(scrollableContainer.scrollTop) +
252
+ indexDiff * childHeight.current.middle
253
+ : scrollToIndex * childHeight.current.middle,
254
+ });
255
+ }
256
+ // if `scrollToIndex` is the first visible node
257
+ // ensure it is fully visible
258
+ if (scrollToIndex === visibleIndex.current.start) {
259
+ var roundedScrollTop = Math.round(scrollableContainer.scrollTop);
260
+ var diff = roundedScrollTop % childHeight.current.middle;
261
+ diff > 0 &&
262
+ scrollableContainer.scrollTo({
263
+ top: roundedScrollTop - diff,
264
+ });
265
+ return;
266
+ }
267
+ // if `scrollToIndex` is the last visible node
268
+ // ensure it is fully visible
269
+ if (scrollToIndex === visibleIndex.current.end) {
270
+ var diff = (scrollableContainer.offsetHeight - childHeight.current.first) %
271
+ childHeight.current.middle;
272
+ var roundedScrollTop = Math.ceil(scrollableContainer.scrollTop);
273
+ var scrollTopMod = roundedScrollTop % childHeight.current.middle;
274
+ if (diff > 0 && scrollTopMod === 0) {
275
+ scrollableContainer.scrollTo({
276
+ top: roundedScrollTop + childHeight.current.middle - diff,
277
+ });
278
+ }
279
+ }
280
+ }, [scrollToIndex, isMounted]);
160
281
  React.useLayoutEffect(function () {
282
+ if (!scrollContainerHeight) {
283
+ return;
284
+ }
161
285
  updateVirtualScroll();
162
- }, [scrollContainerHeight, itemsLength, updateVirtualScroll]);
163
- return (React.createElement("div", __assign({ style: __assign({ overflow: 'hidden', minHeight: itemsLength * childHeight.current, width: '100%' }, style), ref: ref }, rest),
164
- React.createElement("div", { style: {
165
- willChange: 'transform',
166
- }, ref: parentRef }, visibleChildren)));
167
- });
286
+ }, [scrollContainerHeight, updateVirtualScroll]);
287
+ return {
288
+ outerProps: __assign({ style: __assign({ overflow: 'hidden', minHeight: itemsLength > 1
289
+ ? Math.max(itemsLength - 2, 0) * childHeight.current.middle +
290
+ childHeight.current.first +
291
+ childHeight.current.last
292
+ : childHeight.current.middle, width: '100%' }, style) }, rest),
293
+ innerProps: {
294
+ style: { willChange: 'transform' },
295
+ ref: mergeRefs(parentRef), // convert object ref to callback ref for better types
296
+ },
297
+ visibleChildren: visibleChildren,
298
+ };
299
+ };
168
300
  export default VirtualScroll;
@@ -1,7 +1,6 @@
1
1
  /// <reference types="react" />
2
- import { CSSTransition } from 'react-transition-group';
3
2
  import { CSSTransitionProps } from 'react-transition-group/CSSTransition';
4
- export declare const WithCSSTransition: (props: Partial<CSSTransition.CSSTransitionProps> & {
3
+ export declare const WithCSSTransition: (props: Partial<CSSTransitionProps<undefined>> & {
5
4
  children: JSX.Element;
6
5
  dimension?: "width" | "height" | undefined;
7
6
  }) => JSX.Element;
@@ -1,8 +1,8 @@
1
1
  /// <reference types="react" />
2
2
  import { CommonProps } from '../props';
3
3
  export declare const StatusIconMap: {
4
- negative: (args?: CommonProps | undefined) => JSX.Element;
5
- positive: (args?: CommonProps | undefined) => JSX.Element;
6
- warning: (args?: CommonProps | undefined) => JSX.Element;
7
- informational: (args?: CommonProps | undefined) => JSX.Element;
4
+ negative: (args?: CommonProps) => JSX.Element;
5
+ positive: (args?: CommonProps) => JSX.Element;
6
+ warning: (args?: CommonProps) => JSX.Element;
7
+ informational: (args?: CommonProps) => JSX.Element;
8
8
  };
@@ -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';
@@ -72,8 +72,10 @@ export var useOverflow = function (items, disabled, orientation) {
72
72
  var childrenSize = Array.from(containerRef.current.children).reduce(function (sum, child) { return sum + child["offset".concat(dimension)]; }, 0);
73
73
  var avgItemSize = childrenSize / visibleCount;
74
74
  var visibleItems = Math.floor(availableSize / avgItemSize);
75
- // Doubling the visible items to overflow the container. Just to be safe.
76
- setVisibleCount(Math.min(items.length, visibleItems * 2));
75
+ if (!isNaN(visibleItems)) {
76
+ // Doubling the visible items to overflow the container. Just to be safe.
77
+ setVisibleCount(Math.min(items.length, visibleItems * 2));
78
+ }
77
79
  }
78
80
  needsFullRerender.current = false;
79
81
  }, [containerSize, visibleCount, disabled, items.length, orientation]);
@@ -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
+ };
@@ -19,4 +19,4 @@ export declare type ThemeType = 'light' | 'dark' | 'os';
19
19
  * @param theme Light, dark, or based on OS setting.
20
20
  * @param themeOptions Options that override default theming behavior.
21
21
  */
22
- export declare const useTheme: (theme?: ThemeType | undefined, themeOptions?: ThemeOptions | undefined) => void;
22
+ export declare const useTheme: (theme?: ThemeType, themeOptions?: ThemeOptions) => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itwin/itwinui-react",
3
- "version": "1.37.3",
3
+ "version": "1.39.0",
4
4
  "author": "Bentley Systems",
5
5
  "license": "MIT",
6
6
  "main": "cjs/index.js",
@@ -38,104 +38,61 @@
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\" .",
44
- "storybook": "start-storybook -p 6006",
45
- "dev": "yarn storybook",
46
- "build-storybook": "yarn copy-files && build-storybook"
41
+ "lint:fix": "yarn lint --fix && node ../configs/copyrightLinter.js --fix \"*/**/*.{js,ts,tsx}\"",
42
+ "copy-files": "cpy \"../../{README,LICENSE}.md\" .",
43
+ "dev": "yarn build:watch"
47
44
  },
48
45
  "dependencies": {
49
- "@itwin/itwinui-css": "^0.55.0",
50
- "@itwin/itwinui-icons-react": "^1.5.0",
51
- "@itwin/itwinui-illustrations-react": "^1.0.1",
46
+ "@itwin/itwinui-css": "^0.59.1",
47
+ "@itwin/itwinui-icons-react": "^1.10.1",
48
+ "@itwin/itwinui-illustrations-react": "^1.3.1",
52
49
  "@tippyjs/react": "^4.2.5",
53
50
  "@types/react-table": "^7.0.18",
54
51
  "classnames": "^2.2.6",
55
52
  "react-table": "^7.1.0",
56
- "react-transition-group": "^4.1.1"
53
+ "react-transition-group": "^4.4.2"
57
54
  },
58
55
  "devDependencies": {
59
56
  "@babel/core": "^7.12.10",
60
- "@storybook/addon-a11y": "^6.4.19",
61
- "@storybook/addon-essentials": "~6.4.19",
62
- "@storybook/addon-storysource": "~6.4.19",
63
- "@storybook/addons": "~6.4.19",
64
- "@storybook/api": "~6.4.19",
65
- "@storybook/builder-webpack5": "~6.4.19",
66
- "@storybook/components": "~6.4.19",
67
- "@storybook/core-events": "~6.4.19",
68
- "@storybook/manager-webpack5": "~6.4.19",
69
- "@storybook/preset-typescript": "^3.0.0",
70
- "@storybook/react": "~6.4.19",
71
- "@storybook/theming": "~6.4.19",
72
- "@testing-library/jest-dom": "^5.14.1",
73
- "@testing-library/react": "^12.0.0",
74
- "@testing-library/react-hooks": "^7.0.1",
75
- "@testing-library/user-event": "^13.5.0",
57
+ "@testing-library/jest-dom": "^5.16.4",
58
+ "@testing-library/react": "^13.2.0",
59
+ "@testing-library/user-event": "^14.1.1",
76
60
  "@types/classnames": "^2.2.7",
77
61
  "@types/jest": "^27.0.0",
78
62
  "@types/node": "^10.12.2",
79
- "@types/react": "^17.0.3",
80
- "@types/react-dom": "^17.0.3",
81
- "@types/react-transition-group": "^2.9.2",
63
+ "@types/react": "^18.0.6",
64
+ "@types/react-dom": "^18.0.2",
65
+ "@types/react-transition-group": "^4.4.4",
82
66
  "@typescript-eslint/eslint-plugin": "^5.17.0",
83
67
  "@typescript-eslint/parser": "^5.17.0",
84
68
  "babel-loader": "^8.2.2",
85
69
  "concurrently": "^5.3.0",
86
70
  "configs": "*",
87
- "cpx": "^1.5.0",
88
- "creevey": "^0.8.0-beta.0",
89
- "fast-glob": "^3.2.5",
90
- "husky": "^4.0.0",
71
+ "eslint": "^8.12.0",
72
+ "eslint-config-prettier": "^8.5.0",
91
73
  "inquirer": "^6.2.2",
92
- "jest": "^27.0.6",
93
- "jest-cli": "^27.0.6",
94
- "jest-junit": "^12.0.0",
95
- "lint-staged": "^12.1.2",
74
+ "jest": "^28.1.0",
75
+ "jest-cli": "^28.1.0",
76
+ "jest-environment-jsdom": "^28.1.0",
77
+ "jest-junit": "^13.2.0",
96
78
  "markdown-to-jsx": "6.11.4",
97
- "mkdirp": "^1.0.4",
98
- "react": "^17.0.2",
99
- "react-dom": "^17.0.2",
100
- "rimraf": "^2.6.2",
101
- "storybook-dark-mode": "^1.0.9",
79
+ "react": "^18.0.0",
80
+ "react-dom": "^18.0.0",
102
81
  "tippy.js": "^6.3.1",
103
- "ts-jest": "^27.0.4",
82
+ "ts-jest": "^28.0.2",
104
83
  "ts-loader": "^9.2.8",
105
84
  "ts-node": "^8.0.2",
106
- "typescript": "^4.4.3",
107
- "webpack": "5"
85
+ "typescript": "^4.4.3"
108
86
  },
109
87
  "peerDependencies": {
110
- "react": "^16.8.6 || ^17.0.0",
111
- "react-dom": "^16.8.6 || ^17.0.0"
112
- },
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
- }
88
+ "react": ">=16.8.6 < 19.0.0",
89
+ "react-dom": ">=16.8.6 < 19.0.0"
133
90
  },
134
91
  "lint-staged": {
135
92
  "*.{tsx,ts,jsx,js}": [
136
93
  "prettier --write",
137
94
  "eslint --max-warnings=0 --fix",
138
- "yarn lint:copyright --fix"
95
+ "node ../configs/copyrightLinter.js --fix"
139
96
  ]
140
97
  },
141
98
  "prettier": "configs/prettier-config",