@itwin/itwinui-react 1.40.1 → 1.43.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 (148) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/cjs/core/Backdrop/Backdrop.d.ts +10 -0
  3. package/cjs/core/Backdrop/Backdrop.js +41 -0
  4. package/cjs/core/Backdrop/index.d.ts +2 -0
  5. package/cjs/core/Backdrop/index.js +9 -0
  6. package/cjs/core/Breadcrumbs/Breadcrumbs.js +18 -18
  7. package/cjs/core/ButtonGroup/ButtonGroup.js +11 -4
  8. package/cjs/core/ComboBox/ComboBox.js +22 -18
  9. package/cjs/core/Dialog/Dialog.d.ts +41 -0
  10. package/cjs/core/Dialog/Dialog.js +59 -0
  11. package/cjs/core/Dialog/DialogBackdrop.d.ts +12 -0
  12. package/cjs/core/Dialog/DialogBackdrop.js +61 -0
  13. package/cjs/core/Dialog/DialogButtonBar.d.ts +18 -0
  14. package/cjs/core/Dialog/DialogButtonBar.js +50 -0
  15. package/cjs/core/Dialog/DialogContent.d.ts +17 -0
  16. package/cjs/core/Dialog/DialogContent.js +49 -0
  17. package/cjs/core/Dialog/DialogContext.d.ts +39 -0
  18. package/cjs/core/Dialog/DialogContext.js +16 -0
  19. package/cjs/core/Dialog/DialogMain.d.ts +36 -0
  20. package/cjs/core/Dialog/DialogMain.js +120 -0
  21. package/cjs/core/Dialog/DialogTitleBar.d.ts +34 -0
  22. package/cjs/core/Dialog/DialogTitleBar.js +69 -0
  23. package/cjs/core/Dialog/DialogTitleBarTitle.d.ts +15 -0
  24. package/cjs/core/Dialog/DialogTitleBarTitle.js +47 -0
  25. package/cjs/core/Dialog/index.d.ts +8 -0
  26. package/cjs/core/Dialog/index.js +10 -0
  27. package/cjs/core/ErrorPage/ErrorPage.d.ts +3 -1
  28. package/cjs/core/ErrorPage/ErrorPage.js +31 -1
  29. package/cjs/core/Footer/Footer.d.ts +16 -2
  30. package/cjs/core/Footer/Footer.js +57 -45
  31. package/cjs/core/Footer/FooterItem.d.ts +8 -0
  32. package/cjs/core/Footer/FooterItem.js +46 -0
  33. package/cjs/core/Footer/FooterList.d.ts +8 -0
  34. package/cjs/core/Footer/FooterList.js +46 -0
  35. package/cjs/core/Footer/FooterSeparator.d.ts +8 -0
  36. package/cjs/core/Footer/FooterSeparator.js +46 -0
  37. package/cjs/core/Footer/index.d.ts +1 -1
  38. package/cjs/core/Footer/index.js +2 -1
  39. package/cjs/core/Modal/Modal.d.ts +4 -13
  40. package/cjs/core/Modal/Modal.js +9 -71
  41. package/cjs/core/Modal/ModalButtonBar.d.ts +1 -2
  42. package/cjs/core/Modal/ModalButtonBar.js +2 -39
  43. package/cjs/core/Modal/ModalContent.d.ts +1 -2
  44. package/cjs/core/Modal/ModalContent.js +2 -39
  45. package/cjs/core/Slider/Slider.d.ts +10 -0
  46. package/cjs/core/Slider/Slider.js +20 -14
  47. package/cjs/core/Slider/Thumb.d.ts +2 -1
  48. package/cjs/core/Slider/Thumb.js +5 -3
  49. package/cjs/core/Slider/Track.d.ts +2 -1
  50. package/cjs/core/Slider/Track.js +23 -4
  51. package/cjs/core/Table/Table.d.ts +24 -0
  52. package/cjs/core/Table/Table.js +21 -10
  53. package/cjs/core/Table/TableRowMemoized.d.ts +4 -0
  54. package/cjs/core/Table/TableRowMemoized.js +15 -3
  55. package/cjs/core/Table/cells/EditableCell.js +7 -2
  56. package/cjs/core/Table/columns/actionColumn.d.ts +8 -3
  57. package/cjs/core/Table/columns/actionColumn.js +33 -2
  58. package/cjs/core/Table/hooks/index.d.ts +1 -0
  59. package/cjs/core/Table/hooks/index.js +3 -1
  60. package/cjs/core/Table/hooks/useScrollToRow.d.ts +11 -0
  61. package/cjs/core/Table/hooks/useScrollToRow.js +49 -0
  62. package/cjs/core/Tree/Tree.d.ts +9 -0
  63. package/cjs/core/Tree/Tree.js +67 -19
  64. package/cjs/core/Tree/TreeContext.d.ts +4 -0
  65. package/cjs/core/Tree/TreeNode.js +8 -9
  66. package/cjs/core/Typography/Small/Small.js +1 -1
  67. package/cjs/core/index.d.ts +3 -1
  68. package/cjs/core/index.js +6 -3
  69. package/cjs/core/utils/components/FocusTrap.js +1 -1
  70. package/cjs/core/utils/components/MiddleTextTruncation.js +1 -1
  71. package/cjs/core/utils/hooks/index.d.ts +1 -0
  72. package/cjs/core/utils/hooks/index.js +1 -0
  73. package/cjs/core/utils/hooks/useLatestRef.d.ts +9 -0
  74. package/cjs/core/utils/hooks/useLatestRef.js +26 -0
  75. package/esm/core/Backdrop/Backdrop.d.ts +10 -0
  76. package/esm/core/Backdrop/Backdrop.js +35 -0
  77. package/esm/core/Backdrop/index.d.ts +2 -0
  78. package/esm/core/Backdrop/index.js +5 -0
  79. package/esm/core/Breadcrumbs/Breadcrumbs.js +18 -18
  80. package/esm/core/ButtonGroup/ButtonGroup.js +11 -4
  81. package/esm/core/ComboBox/ComboBox.js +23 -19
  82. package/esm/core/Dialog/Dialog.d.ts +41 -0
  83. package/esm/core/Dialog/Dialog.js +53 -0
  84. package/esm/core/Dialog/DialogBackdrop.d.ts +12 -0
  85. package/esm/core/Dialog/DialogBackdrop.js +55 -0
  86. package/esm/core/Dialog/DialogButtonBar.d.ts +18 -0
  87. package/esm/core/Dialog/DialogButtonBar.js +44 -0
  88. package/esm/core/Dialog/DialogContent.d.ts +17 -0
  89. package/esm/core/Dialog/DialogContent.js +43 -0
  90. package/esm/core/Dialog/DialogContext.d.ts +39 -0
  91. package/esm/core/Dialog/DialogContext.js +9 -0
  92. package/esm/core/Dialog/DialogMain.d.ts +36 -0
  93. package/esm/core/Dialog/DialogMain.js +114 -0
  94. package/esm/core/Dialog/DialogTitleBar.d.ts +34 -0
  95. package/esm/core/Dialog/DialogTitleBar.js +63 -0
  96. package/esm/core/Dialog/DialogTitleBarTitle.d.ts +15 -0
  97. package/esm/core/Dialog/DialogTitleBarTitle.js +41 -0
  98. package/esm/core/Dialog/index.d.ts +8 -0
  99. package/esm/core/Dialog/index.js +6 -0
  100. package/esm/core/ErrorPage/ErrorPage.d.ts +3 -1
  101. package/esm/core/ErrorPage/ErrorPage.js +31 -1
  102. package/esm/core/Footer/Footer.d.ts +16 -2
  103. package/esm/core/Footer/Footer.js +56 -43
  104. package/esm/core/Footer/FooterItem.d.ts +8 -0
  105. package/esm/core/Footer/FooterItem.js +39 -0
  106. package/esm/core/Footer/FooterList.d.ts +8 -0
  107. package/esm/core/Footer/FooterList.js +39 -0
  108. package/esm/core/Footer/FooterSeparator.d.ts +8 -0
  109. package/esm/core/Footer/FooterSeparator.js +39 -0
  110. package/esm/core/Footer/index.d.ts +1 -1
  111. package/esm/core/Footer/index.js +1 -1
  112. package/esm/core/Modal/Modal.d.ts +4 -13
  113. package/esm/core/Modal/Modal.js +10 -72
  114. package/esm/core/Modal/ModalButtonBar.d.ts +1 -2
  115. package/esm/core/Modal/ModalButtonBar.js +2 -35
  116. package/esm/core/Modal/ModalContent.d.ts +1 -2
  117. package/esm/core/Modal/ModalContent.js +2 -35
  118. package/esm/core/Slider/Slider.d.ts +10 -0
  119. package/esm/core/Slider/Slider.js +20 -14
  120. package/esm/core/Slider/Thumb.d.ts +2 -1
  121. package/esm/core/Slider/Thumb.js +5 -3
  122. package/esm/core/Slider/Track.d.ts +2 -1
  123. package/esm/core/Slider/Track.js +23 -4
  124. package/esm/core/Table/Table.d.ts +24 -0
  125. package/esm/core/Table/Table.js +23 -12
  126. package/esm/core/Table/TableRowMemoized.d.ts +4 -0
  127. package/esm/core/Table/TableRowMemoized.js +15 -3
  128. package/esm/core/Table/cells/EditableCell.js +7 -2
  129. package/esm/core/Table/columns/actionColumn.d.ts +8 -3
  130. package/esm/core/Table/columns/actionColumn.js +33 -2
  131. package/esm/core/Table/hooks/index.d.ts +1 -0
  132. package/esm/core/Table/hooks/index.js +1 -0
  133. package/esm/core/Table/hooks/useScrollToRow.d.ts +11 -0
  134. package/esm/core/Table/hooks/useScrollToRow.js +42 -0
  135. package/esm/core/Tree/Tree.d.ts +9 -0
  136. package/esm/core/Tree/Tree.js +68 -20
  137. package/esm/core/Tree/TreeContext.d.ts +4 -0
  138. package/esm/core/Tree/TreeNode.js +8 -9
  139. package/esm/core/Typography/Small/Small.js +1 -1
  140. package/esm/core/index.d.ts +3 -1
  141. package/esm/core/index.js +2 -1
  142. package/esm/core/utils/components/FocusTrap.js +1 -1
  143. package/esm/core/utils/components/MiddleTextTruncation.js +1 -1
  144. package/esm/core/utils/hooks/index.d.ts +1 -0
  145. package/esm/core/utils/hooks/index.js +1 -0
  146. package/esm/core/utils/hooks/useLatestRef.d.ts +9 -0
  147. package/esm/core/utils/hooks/useLatestRef.js +19 -0
  148. package/package.json +8 -7
@@ -86,7 +86,7 @@ var TreeContext_1 = require("./TreeContext");
86
86
  />
87
87
  */
88
88
  var Tree = function (props) {
89
- var data = props.data, className = props.className, nodeRenderer = props.nodeRenderer, getNode = props.getNode, rest = __rest(props, ["data", "className", "nodeRenderer", "getNode"]);
89
+ var data = props.data, className = props.className, nodeRenderer = props.nodeRenderer, getNode = props.getNode, _a = props.enableVirtualization, enableVirtualization = _a === void 0 ? false : _a, style = props.style, rest = __rest(props, ["data", "className", "nodeRenderer", "getNode", "enableVirtualization", "style"]);
90
90
  (0, utils_1.useTheme)();
91
91
  var treeRef = react_1.default.useRef(null);
92
92
  var focusedIndex = react_1.default.useRef(0);
@@ -124,7 +124,7 @@ var Tree = function (props) {
124
124
  break;
125
125
  }
126
126
  };
127
- var _a = react_1.default.useMemo(function () {
127
+ var _b = react_1.default.useMemo(function () {
128
128
  var flatList = [];
129
129
  var firstLevelNodes = [];
130
130
  var flattenNodes = function (nodes, depth, parentNode) {
@@ -153,25 +153,73 @@ var Tree = function (props) {
153
153
  };
154
154
  flattenNodes(data);
155
155
  return [flatList, firstLevelNodes];
156
- }, [data, getNode]), flatNodesList = _a[0], firstLevelNodesList = _a[1];
157
- return (react_1.default.createElement("ul", __assign({ className: (0, classnames_1.default)('iui-tree', className), role: 'tree', onKeyDown: handleKeyDown, ref: treeRef, tabIndex: 0, onFocus: function () {
158
- var _a;
159
- var items = getFocusableNodes();
160
- if (items.length > 0) {
161
- (_a = items[focusedIndex.current]) === null || _a === void 0 ? void 0 : _a.focus();
162
- }
163
- } }, rest), flatNodesList.map(function (flatNode) {
156
+ }, [data, getNode]), flatNodesList = _b[0], firstLevelNodesList = _b[1];
157
+ var itemRenderer = react_1.default.useCallback(function (index) {
164
158
  var _a, _b, _c, _d;
165
- return (react_1.default.createElement(TreeContext_1.TreeContext.Provider, { key: flatNode.nodeProps.nodeId, value: {
166
- nodeDepth: flatNode.depth,
167
- subNodeIds: flatNode.subNodeIds,
168
- groupSize: flatNode.depth === 0
159
+ var node = flatNodesList[index];
160
+ return (react_1.default.createElement(TreeContext_1.TreeContext.Provider, { key: node.nodeProps.nodeId, value: {
161
+ nodeDepth: node.depth,
162
+ subNodeIds: node.subNodeIds,
163
+ groupSize: node.depth === 0
169
164
  ? firstLevelNodesList.length
170
- : (_c = (_b = (_a = flatNode.parentNode) === null || _a === void 0 ? void 0 : _a.subNodeIds) === null || _b === void 0 ? void 0 : _b.length) !== null && _c !== void 0 ? _c : 0,
171
- indexInGroup: flatNode.indexInGroup,
172
- parentNodeId: (_d = flatNode.parentNode) === null || _d === void 0 ? void 0 : _d.nodeProps.nodeId,
173
- } }, nodeRenderer(flatNode.nodeProps)));
174
- })));
165
+ : (_c = (_b = (_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.subNodeIds) === null || _b === void 0 ? void 0 : _b.length) !== null && _c !== void 0 ? _c : 0,
166
+ indexInGroup: node.indexInGroup,
167
+ parentNodeId: (_d = node.parentNode) === null || _d === void 0 ? void 0 : _d.nodeProps.nodeId,
168
+ scrollToParent: node.parentNode
169
+ ? function () {
170
+ var _a;
171
+ var parentNodeId = (_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.nodeProps.nodeId;
172
+ var parentNodeIndex = flatNodesList.findIndex(function (n) { return n.nodeProps.nodeId === parentNodeId; });
173
+ setScrollToIndex(parentNodeIndex);
174
+ }
175
+ : undefined,
176
+ } }, nodeRenderer(node.nodeProps)));
177
+ }, [firstLevelNodesList.length, flatNodesList, nodeRenderer]);
178
+ var _c = react_1.default.useState(), scrollToIndex = _c[0], setScrollToIndex = _c[1];
179
+ var flatNodesListRef = react_1.default.useRef(flatNodesList);
180
+ react_1.default.useEffect(function () {
181
+ flatNodesListRef.current = flatNodesList;
182
+ }, [flatNodesList]);
183
+ react_1.default.useEffect(function () {
184
+ setTimeout(function () {
185
+ var _a;
186
+ if (scrollToIndex !== undefined) {
187
+ var nodeId = flatNodesListRef.current[scrollToIndex].nodeProps.nodeId;
188
+ var nodeElement = (_a = treeRef.current) === null || _a === void 0 ? void 0 : _a.ownerDocument.querySelector("#".concat(nodeId));
189
+ nodeElement === null || nodeElement === void 0 ? void 0 : nodeElement.focus();
190
+ // Need to reset that if navigating with mouse and keyboard,
191
+ // e.g. pressing arrow left to go to parent node and then with mouse
192
+ // clicking some other child node and then pressing arrow left
193
+ setScrollToIndex(undefined);
194
+ }
195
+ });
196
+ }, [scrollToIndex]);
197
+ var handleFocus = function (event) {
198
+ var _a, _b;
199
+ if ((_a = treeRef.current) === null || _a === void 0 ? void 0 : _a.contains(event.relatedTarget)) {
200
+ return;
201
+ }
202
+ var items = getFocusableNodes();
203
+ if (items.length > 0) {
204
+ (_b = items[focusedIndex.current]) === null || _b === void 0 ? void 0 : _b.focus();
205
+ }
206
+ };
207
+ return (react_1.default.createElement(react_1.default.Fragment, null, enableVirtualization ? (react_1.default.createElement(VirtualizedTree, __assign({ flatNodesList: flatNodesList, itemRenderer: itemRenderer, scrollToIndex: scrollToIndex, onFocus: handleFocus, onKeyDown: handleKeyDown, ref: treeRef, className: className, style: style }, rest))) : (react_1.default.createElement(TreeElement, __assign({ onKeyDown: handleKeyDown, onFocus: handleFocus, className: className, style: style, ref: treeRef }, rest), flatNodesList.map(function (_, i) { return itemRenderer(i); })))));
175
208
  };
176
209
  exports.Tree = Tree;
210
+ var TreeElement = react_1.default.forwardRef(function (_a, ref) {
211
+ var children = _a.children, className = _a.className, rest = __rest(_a, ["children", "className"]);
212
+ return (react_1.default.createElement("ul", __assign({ className: (0, classnames_1.default)('iui-tree', className), role: 'tree', ref: ref, tabIndex: 0 }, rest), children));
213
+ });
214
+ // Having virtualized tree separately prevents from running all virtualization logic
215
+ var VirtualizedTree = react_1.default.forwardRef(function (_a, ref) {
216
+ var flatNodesList = _a.flatNodesList, itemRenderer = _a.itemRenderer, scrollToIndex = _a.scrollToIndex, className = _a.className, style = _a.style, rest = __rest(_a, ["flatNodesList", "itemRenderer", "scrollToIndex", "className", "style"]);
217
+ var _b = (0, utils_1.useVirtualization)({
218
+ itemsLength: flatNodesList.length,
219
+ itemRenderer: itemRenderer,
220
+ scrollToIndex: scrollToIndex,
221
+ }), outerProps = _b.outerProps, innerProps = _b.innerProps, visibleChildren = _b.visibleChildren;
222
+ return (react_1.default.createElement("div", __assign({}, __assign(__assign({}, outerProps), { className: (0, classnames_1.default)(className, outerProps.className), style: __assign(__assign({}, style), outerProps.style) })),
223
+ react_1.default.createElement(TreeElement, __assign({}, innerProps, rest, { ref: (0, utils_1.mergeRefs)(ref, innerProps.ref) }), visibleChildren)));
224
+ });
177
225
  exports.default = exports.Tree;
@@ -20,6 +20,10 @@ export declare type TreeContextProps = {
20
20
  * Node index in the list of nodes under the same parent node or in the root. Used for an accessibility attribute.
21
21
  */
22
22
  indexInGroup: number;
23
+ /**
24
+ * Function that scrolls to the node's parent node.
25
+ */
26
+ scrollToParent?: () => void;
23
27
  };
24
28
  export declare const TreeContext: React.Context<TreeContextProps | undefined>;
25
29
  export declare const useTreeContext: () => TreeContextProps;
@@ -58,7 +58,7 @@ var TreeContext_1 = require("./TreeContext");
58
58
  var TreeNode = function (props) {
59
59
  var nodeId = props.nodeId, label = props.label, sublabel = props.sublabel, children = props.children, className = props.className, icon = props.icon, _a = props.hasSubNodes, hasSubNodes = _a === void 0 ? false : _a, _b = props.isDisabled, isDisabled = _b === void 0 ? false : _b, _c = props.isExpanded, isExpanded = _c === void 0 ? false : _c, _d = props.isSelected, isSelected = _d === void 0 ? false : _d, onSelected = props.onSelected, onExpanded = props.onExpanded, checkbox = props.checkbox, expander = props.expander, rest = __rest(props, ["nodeId", "label", "sublabel", "children", "className", "icon", "hasSubNodes", "isDisabled", "isExpanded", "isSelected", "onSelected", "onExpanded", "checkbox", "expander"]);
60
60
  (0, utils_1.useTheme)();
61
- var _e = (0, TreeContext_1.useTreeContext)(), nodeDepth = _e.nodeDepth, _f = _e.subNodeIds, subNodeIds = _f === void 0 ? [] : _f, parentNodeId = _e.parentNodeId, groupSize = _e.groupSize, indexInGroup = _e.indexInGroup;
61
+ var _e = (0, TreeContext_1.useTreeContext)(), nodeDepth = _e.nodeDepth, _f = _e.subNodeIds, subNodeIds = _f === void 0 ? [] : _f, parentNodeId = _e.parentNodeId, scrollToParent = _e.scrollToParent, groupSize = _e.groupSize, indexInGroup = _e.indexInGroup;
62
62
  var _g = react_1.default.useState(false), isFocused = _g[0], setIsFocused = _g[1];
63
63
  var nodeRef = react_1.default.useRef(null);
64
64
  var styleDepth = react_1.default.useMemo(function () {
@@ -68,7 +68,7 @@ var TreeNode = function (props) {
68
68
  : { marginLeft: nodeDepth ? nodeDepth * 28 : 0 };
69
69
  }, [nodeDepth]);
70
70
  var onKeyDown = function (event) {
71
- var _a, _b, _c, _d, _e, _f, _g;
71
+ var _a, _b, _c, _d, _e, _f;
72
72
  var isNodeFocused = nodeRef.current === ((_a = nodeRef.current) === null || _a === void 0 ? void 0 : _a.ownerDocument.activeElement);
73
73
  switch (event.key) {
74
74
  case 'ArrowLeft': {
@@ -79,20 +79,19 @@ var TreeNode = function (props) {
79
79
  break;
80
80
  }
81
81
  if (parentNodeId) {
82
- var parentNode = (_b = nodeRef.current) === null || _b === void 0 ? void 0 : _b.ownerDocument.querySelector("#".concat(parentNodeId));
83
- parentNode === null || parentNode === void 0 ? void 0 : parentNode.focus();
82
+ scrollToParent === null || scrollToParent === void 0 ? void 0 : scrollToParent();
84
83
  break;
85
84
  }
86
85
  // If it is top level node (doesn't have parent node), then do nothing.
87
86
  break;
88
87
  }
89
88
  var focusableElements = (0, utils_1.getFocusableElements)(nodeRef.current);
90
- var currentIndex = focusableElements.indexOf((_c = nodeRef.current) === null || _c === void 0 ? void 0 : _c.ownerDocument.activeElement);
89
+ var currentIndex = focusableElements.indexOf((_b = nodeRef.current) === null || _b === void 0 ? void 0 : _b.ownerDocument.activeElement);
91
90
  if (currentIndex === 0) {
92
- (_d = nodeRef.current) === null || _d === void 0 ? void 0 : _d.focus();
91
+ (_c = nodeRef.current) === null || _c === void 0 ? void 0 : _c.focus();
93
92
  }
94
93
  else {
95
- (_e = focusableElements[currentIndex - 1]) === null || _e === void 0 ? void 0 : _e.focus();
94
+ (_d = focusableElements[currentIndex - 1]) === null || _d === void 0 ? void 0 : _d.focus();
96
95
  }
97
96
  break;
98
97
  }
@@ -104,10 +103,10 @@ var TreeNode = function (props) {
104
103
  onExpanded(nodeId, true);
105
104
  break;
106
105
  }
107
- (_f = focusableElements[0]) === null || _f === void 0 ? void 0 : _f.focus();
106
+ (_e = focusableElements[0]) === null || _e === void 0 ? void 0 : _e.focus();
108
107
  break;
109
108
  }
110
- var currentIndex = focusableElements.indexOf((_g = nodeRef.current) === null || _g === void 0 ? void 0 : _g.ownerDocument.activeElement);
109
+ var currentIndex = focusableElements.indexOf((_f = nodeRef.current) === null || _f === void 0 ? void 0 : _f.ownerDocument.activeElement);
111
110
  if (currentIndex < focusableElements.length - 1) {
112
111
  focusableElements[currentIndex + 1].focus();
113
112
  break;
@@ -43,6 +43,6 @@ require("@itwin/itwinui-css/css/text.css");
43
43
  exports.Small = react_1.default.forwardRef(function (props, ref) {
44
44
  var className = props.className, _a = props.isMuted, isMuted = _a === void 0 ? false : _a, rest = __rest(props, ["className", "isMuted"]);
45
45
  (0, utils_1.useTheme)();
46
- return (react_1.default.createElement("p", __assign({ ref: ref, className: (0, classnames_1.default)('iui-text-small', { 'iui-text-muted': isMuted }, className) }, rest)));
46
+ return (react_1.default.createElement("small", __assign({ ref: ref, className: (0, classnames_1.default)('iui-text-small', { 'iui-text-muted': isMuted }, className) }, rest)));
47
47
  });
48
48
  exports.default = exports.Small;
@@ -1,5 +1,7 @@
1
1
  export { Alert } from './Alert';
2
2
  export type { AlertProps } from './Alert';
3
+ export { Backdrop } from './Backdrop';
4
+ export type { BackdropProps } from './Backdrop';
3
5
  export { Badge } from './Badge';
4
6
  export type { BadgeProps } from './Badge';
5
7
  export { Breadcrumbs } from './Breadcrumbs';
@@ -28,7 +30,7 @@ export { Fieldset } from './Fieldset';
28
30
  export type { FieldsetProps } from './Fieldset';
29
31
  export { FileUpload, FileUploadTemplate } from './FileUpload';
30
32
  export type { FileUploadProps, FileUploadTemplateProps } from './FileUpload';
31
- export { Footer } from './Footer';
33
+ export { Footer, defaultFooterElements } from './Footer';
32
34
  export type { FooterProps, FooterElement, TitleTranslations } from './Footer';
33
35
  export { Header, HeaderBreadcrumbs, HeaderButton, HeaderLogo } from './Header';
34
36
  export type { HeaderProps, HeaderBreadcrumbsProps, HeaderButtonProps, HeaderLogoProps, } from './Header';
package/cjs/core/index.js CHANGED
@@ -3,15 +3,17 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.MenuItemSkeleton = exports.MenuExtraContent = exports.MenuDivider = exports.MenuItem = exports.Menu = exports.LabeledTextarea = exports.LabeledSelect = exports.InputGroup = exports.LabeledInput = exports.Label = exports.Input = exports.InformationPanelContent = exports.InformationPanelBody = exports.InformationPanelHeader = exports.InformationPanelWrapper = exports.InformationPanel = exports.HorizontalTab = exports.HorizontalTabs = exports.Tab = exports.VerticalTabs = exports.HeaderLogo = exports.HeaderButton = exports.HeaderBreadcrumbs = exports.Header = exports.Footer = exports.FileUploadTemplate = exports.FileUpload = exports.Fieldset = exports.ExpandableBlock = exports.ErrorPage = exports.DropdownMenu = exports.generateLocalizedStrings = exports.DatePicker = exports.ComboBox = exports.ColorPalette = exports.ColorInputPanel = exports.ColorBuilder = exports.ColorSwatch = exports.ColorPicker = exports.Checkbox = exports.Carousel = exports.ButtonGroup = exports.SplitButton = exports.IdeasButton = exports.IconButton = exports.DropdownButton = exports.Button = exports.Breadcrumbs = exports.Badge = exports.Alert = void 0;
7
- exports.Text = exports.KbdKeys = exports.Kbd = exports.Code = exports.Blockquote = exports.Title = exports.Subheading = exports.Small = exports.Leading = exports.Headline = exports.Body = exports.Anchor = exports.TreeNodeExpander = exports.TreeNode = exports.Tree = exports.Tooltip = exports.ToggleSwitch = exports.ThemeProvider = exports.toaster = exports.TimePicker = exports.Tile = exports.Textarea = exports.TagContainer = exports.Tag = exports.SelectionColumn = exports.ExpanderColumn = exports.ActionColumn = exports.TablePaginator = exports.EditableCell = exports.DefaultCell = exports.FilterButtonBar = exports.tableFilters = exports.Table = exports.Surface = exports.StatusMessage = exports.Slider = exports.SkipToContentLink = exports.SidenavSubmenuHeader = exports.SidenavSubmenu = exports.SidenavButton = exports.SideNavigation = exports.Select = exports.RadioTileGroup = exports.RadioTile = exports.Radio = exports.ProgressRadial = exports.ProgressLinear = exports.ModalContent = exports.ModalButtonBar = exports.Modal = void 0;
8
- exports.MiddleTextTruncation = exports.ColorValue = exports.useTheme = exports.getUserColor = exports.Wizard = exports.UserIconGroup = exports.UserIcon = void 0;
6
+ exports.MenuDivider = exports.MenuItem = exports.Menu = exports.LabeledTextarea = exports.LabeledSelect = exports.InputGroup = exports.LabeledInput = exports.Label = exports.Input = exports.InformationPanelContent = exports.InformationPanelBody = exports.InformationPanelHeader = exports.InformationPanelWrapper = exports.InformationPanel = exports.HorizontalTab = exports.HorizontalTabs = exports.Tab = exports.VerticalTabs = exports.HeaderLogo = exports.HeaderButton = exports.HeaderBreadcrumbs = exports.Header = exports.defaultFooterElements = exports.Footer = exports.FileUploadTemplate = exports.FileUpload = exports.Fieldset = exports.ExpandableBlock = exports.ErrorPage = exports.DropdownMenu = exports.generateLocalizedStrings = exports.DatePicker = exports.ComboBox = exports.ColorPalette = exports.ColorInputPanel = exports.ColorBuilder = exports.ColorSwatch = exports.ColorPicker = exports.Checkbox = exports.Carousel = exports.ButtonGroup = exports.SplitButton = exports.IdeasButton = exports.IconButton = exports.DropdownButton = exports.Button = exports.Breadcrumbs = exports.Badge = exports.Backdrop = exports.Alert = void 0;
7
+ exports.Kbd = exports.Code = exports.Blockquote = exports.Title = exports.Subheading = exports.Small = exports.Leading = exports.Headline = exports.Body = exports.Anchor = exports.TreeNodeExpander = exports.TreeNode = exports.Tree = exports.Tooltip = exports.ToggleSwitch = exports.ThemeProvider = exports.toaster = exports.TimePicker = exports.Tile = exports.Textarea = exports.TagContainer = exports.Tag = exports.SelectionColumn = exports.ExpanderColumn = exports.ActionColumn = exports.TablePaginator = exports.EditableCell = exports.DefaultCell = exports.FilterButtonBar = exports.tableFilters = exports.Table = exports.Surface = exports.StatusMessage = exports.Slider = exports.SkipToContentLink = exports.SidenavSubmenuHeader = exports.SidenavSubmenu = exports.SidenavButton = exports.SideNavigation = exports.Select = exports.RadioTileGroup = exports.RadioTile = exports.Radio = exports.ProgressRadial = exports.ProgressLinear = exports.ModalContent = exports.ModalButtonBar = exports.Modal = exports.MenuItemSkeleton = exports.MenuExtraContent = void 0;
8
+ exports.MiddleTextTruncation = exports.ColorValue = exports.useTheme = exports.getUserColor = exports.Wizard = exports.UserIconGroup = exports.UserIcon = exports.Text = exports.KbdKeys = void 0;
9
9
  /*---------------------------------------------------------------------------------------------
10
10
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
11
11
  * See LICENSE.md in the project root for license terms and full copyright notice.
12
12
  *--------------------------------------------------------------------------------------------*/
13
13
  var Alert_1 = require("./Alert");
14
14
  Object.defineProperty(exports, "Alert", { enumerable: true, get: function () { return Alert_1.Alert; } });
15
+ var Backdrop_1 = require("./Backdrop");
16
+ Object.defineProperty(exports, "Backdrop", { enumerable: true, get: function () { return Backdrop_1.Backdrop; } });
15
17
  var Badge_1 = require("./Badge");
16
18
  Object.defineProperty(exports, "Badge", { enumerable: true, get: function () { return Badge_1.Badge; } });
17
19
  var Breadcrumbs_1 = require("./Breadcrumbs");
@@ -52,6 +54,7 @@ Object.defineProperty(exports, "FileUpload", { enumerable: true, get: function (
52
54
  Object.defineProperty(exports, "FileUploadTemplate", { enumerable: true, get: function () { return FileUpload_1.FileUploadTemplate; } });
53
55
  var Footer_1 = require("./Footer");
54
56
  Object.defineProperty(exports, "Footer", { enumerable: true, get: function () { return Footer_1.Footer; } });
57
+ Object.defineProperty(exports, "defaultFooterElements", { enumerable: true, get: function () { return Footer_1.defaultFooterElements; } });
55
58
  var Header_1 = require("./Header");
56
59
  Object.defineProperty(exports, "Header", { enumerable: true, get: function () { return Header_1.Header; } });
57
60
  Object.defineProperty(exports, "HeaderBreadcrumbs", { enumerable: true, get: function () { return Header_1.HeaderBreadcrumbs; } });
@@ -42,7 +42,7 @@ var FocusTrap = function (props) {
42
42
  lastElement === null || lastElement === void 0 ? void 0 : lastElement.focus();
43
43
  }
44
44
  };
45
- return (react_1.default.createElement("div", null,
45
+ return (react_1.default.createElement(react_1.default.Fragment, null,
46
46
  react_1.default.createElement("div", { tabIndex: 0, onFocus: onFirstFocus, "aria-hidden": true }),
47
47
  react_1.default.cloneElement(children, {
48
48
  ref: (0, useMergedRefs_1.mergeRefs)(children.ref, childRef),
@@ -44,7 +44,7 @@ var MiddleTextTruncation = function (props) {
44
44
  var _b = (0, useOverflow_1.useOverflow)(text), ref = _b[0], visibleCount = _b[1];
45
45
  var truncatedText = react_1.default.useMemo(function () {
46
46
  if (visibleCount < text.length) {
47
- return "".concat(text.substr(0, visibleCount - endCharsCount - ELLIPSIS_CHAR.length)).concat(ELLIPSIS_CHAR).concat(text.substr(text.length - endCharsCount));
47
+ return "".concat(text.substring(0, visibleCount - endCharsCount - ELLIPSIS_CHAR.length)).concat(ELLIPSIS_CHAR).concat(text.substring(text.length - endCharsCount));
48
48
  }
49
49
  else {
50
50
  return text;
@@ -7,3 +7,4 @@ export * from './useTheme';
7
7
  export * from './useIntersection';
8
8
  export * from './useMediaQuery';
9
9
  export * from './useSafeContext';
10
+ export * from './useLatestRef';
@@ -27,3 +27,4 @@ __exportStar(require("./useTheme"), exports);
27
27
  __exportStar(require("./useIntersection"), exports);
28
28
  __exportStar(require("./useMediaQuery"), exports);
29
29
  __exportStar(require("./useSafeContext"), exports);
30
+ __exportStar(require("./useLatestRef"), exports);
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ /**
3
+ * Hook that keeps track of the latest value in a ref.
4
+ * @private
5
+ * @example
6
+ * const { value } = props;
7
+ * const valueRef = useLatestRef(value);
8
+ */
9
+ export declare const useLatestRef: <T>(value: T) => React.MutableRefObject<T>;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.useLatestRef = void 0;
7
+ /*---------------------------------------------------------------------------------------------
8
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
9
+ * See LICENSE.md in the project root for license terms and full copyright notice.
10
+ *--------------------------------------------------------------------------------------------*/
11
+ var react_1 = __importDefault(require("react"));
12
+ /**
13
+ * Hook that keeps track of the latest value in a ref.
14
+ * @private
15
+ * @example
16
+ * const { value } = props;
17
+ * const valueRef = useLatestRef(value);
18
+ */
19
+ var useLatestRef = function (value) {
20
+ var valueRef = react_1.default.useRef(value);
21
+ react_1.default.useEffect(function () {
22
+ valueRef.current = value;
23
+ }, [value]);
24
+ return valueRef;
25
+ };
26
+ exports.useLatestRef = useLatestRef;
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ import '@itwin/itwinui-css/css/backdrop.css';
3
+ export declare type BackdropProps = {
4
+ /**
5
+ * Flag whether backdrop should be shown.
6
+ * @default true
7
+ */
8
+ isVisible?: boolean;
9
+ } & React.ComponentPropsWithRef<'div'>;
10
+ export declare const Backdrop: React.ForwardRefExoticComponent<Pick<BackdropProps, "key" | keyof React.HTMLAttributes<HTMLDivElement> | "isVisible"> & React.RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,35 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ var __rest = (this && this.__rest) || function (s, e) {
13
+ var t = {};
14
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
15
+ t[p] = s[p];
16
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
17
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
18
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
19
+ t[p[i]] = s[p[i]];
20
+ }
21
+ return t;
22
+ };
23
+ /*---------------------------------------------------------------------------------------------
24
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
25
+ * See LICENSE.md in the project root for license terms and full copyright notice.
26
+ *--------------------------------------------------------------------------------------------*/
27
+ import React from 'react';
28
+ import cx from 'classnames';
29
+ import { useTheme } from '../utils';
30
+ import '@itwin/itwinui-css/css/backdrop.css';
31
+ export var Backdrop = React.forwardRef(function (props, ref) {
32
+ var _a = props.isVisible, isVisible = _a === void 0 ? true : _a, className = props.className, rest = __rest(props, ["isVisible", "className"]);
33
+ useTheme();
34
+ return (React.createElement("div", __assign({ className: cx('iui-backdrop', { 'iui-backdrop-visible': isVisible }, className), ref: ref }, rest)));
35
+ });
@@ -0,0 +1,2 @@
1
+ export { Backdrop } from './Backdrop';
2
+ export type { BackdropProps } from './Backdrop';
@@ -0,0 +1,5 @@
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
+ export { Backdrop } from './Backdrop';
@@ -56,28 +56,15 @@ export var Breadcrumbs = React.forwardRef(function (props, ref) {
56
56
  useTheme();
57
57
  var _b = useOverflow(items), overflowRef = _b[0], visibleCount = _b[1];
58
58
  var refs = useMergedRefs(overflowRef, ref);
59
- var Separator = function () { return (React.createElement("li", { className: 'iui-breadcrumbs-separator', "aria-hidden": true }, separator !== null && separator !== void 0 ? separator : React.createElement(SvgChevronRight, null))); };
60
- var ListItem = function (_a) {
61
- var _b;
62
- var index = _a.index;
63
- var item = items[index];
64
- return (React.createElement("li", { className: 'iui-breadcrumbs-item iui-breadcrumbs-item-overrides' }, React.isValidElement(item)
65
- ? React.cloneElement(item, {
66
- 'aria-current': ((_b = item.props['aria-current']) !== null && _b !== void 0 ? _b : currentIndex === index)
67
- ? 'location'
68
- : undefined,
69
- })
70
- : item));
71
- };
72
59
  return (React.createElement("nav", __assign({ className: cx('iui-breadcrumbs', className), ref: refs, "aria-label": 'Breadcrumb' }, rest),
73
60
  React.createElement("ol", { className: 'iui-breadcrumbs-list' },
74
61
  visibleCount > 1 && (React.createElement(React.Fragment, null,
75
- React.createElement(ListItem, { index: 0 }),
76
- React.createElement(Separator, null))),
62
+ React.createElement(ListItem, { item: items[0], isActive: currentIndex === 0 }),
63
+ React.createElement(Separator, { separator: separator }))),
77
64
  items.length - visibleCount > 0 && (React.createElement(React.Fragment, null,
78
65
  React.createElement("li", { className: 'iui-breadcrumbs-item iui-breadcrumbs-item-overrides' },
79
66
  React.createElement("span", { className: 'iui-breadcrumbs-text' }, "\u2026")),
80
- React.createElement(Separator, null))),
67
+ React.createElement(Separator, { separator: separator }))),
81
68
  items
82
69
  .slice(visibleCount > 1
83
70
  ? items.length - visibleCount + 1
@@ -87,8 +74,21 @@ export var Breadcrumbs = React.forwardRef(function (props, ref) {
87
74
  ? 1 + (items.length - visibleCount) + _index
88
75
  : items.length - 1;
89
76
  return (React.createElement(React.Fragment, { key: index },
90
- React.createElement(ListItem, { index: index }),
91
- index < items.length - 1 && React.createElement(Separator, null)));
77
+ React.createElement(ListItem, { item: items[index], isActive: currentIndex === index }),
78
+ index < items.length - 1 && (React.createElement(Separator, { separator: separator }))));
92
79
  }))));
93
80
  });
81
+ var ListItem = function (_a) {
82
+ var _b;
83
+ var item = _a.item, isActive = _a.isActive;
84
+ return (React.createElement("li", { className: 'iui-breadcrumbs-item iui-breadcrumbs-item-overrides' }, React.isValidElement(item)
85
+ ? React.cloneElement(item, {
86
+ 'aria-current': ((_b = item.props['aria-current']) !== null && _b !== void 0 ? _b : isActive) ? 'location' : undefined,
87
+ })
88
+ : item));
89
+ };
90
+ var Separator = function (_a) {
91
+ var separator = _a.separator;
92
+ return (React.createElement("li", { className: 'iui-breadcrumbs-separator', "aria-hidden": true }, separator !== null && separator !== void 0 ? separator : React.createElement(SvgChevronRight, null)));
93
+ };
94
94
  export default Breadcrumbs;
@@ -66,9 +66,16 @@ export var ButtonGroup = React.forwardRef(function (props, ref) {
66
66
  'iui-button-group': orientation === 'horizontal',
67
67
  'iui-button-group-vertical': orientation === 'vertical',
68
68
  'iui-button-group-overflow-x': !!overflowButton && orientation === 'horizontal',
69
- }, className), "aria-orientation": orientation, ref: refs }, rest), !!overflowButton && visibleCount < items.length ? (React.createElement(React.Fragment, null,
70
- overflowButton && overflowPlacement === 'start' && (React.createElement("div", null, overflowButton(visibleCount))),
71
- items.slice(0, visibleCount - 1),
72
- overflowButton && overflowPlacement === 'end' && (React.createElement("div", null, overflowButton(visibleCount))))) : (items)));
69
+ }, className), "aria-orientation": orientation, ref: refs }, rest),
70
+ React.createElement(React.Fragment, null,
71
+ visibleCount < items.length &&
72
+ overflowButton &&
73
+ overflowPlacement === 'start' && (React.createElement("div", null, overflowButton(visibleCount))),
74
+ visibleCount < items.length
75
+ ? items.slice(0, visibleCount - 1)
76
+ : items,
77
+ visibleCount < items.length &&
78
+ overflowButton &&
79
+ overflowPlacement === 'end' && (React.createElement("div", null, overflowButton(visibleCount))))));
73
80
  });
74
81
  export default ButtonGroup;
@@ -28,7 +28,7 @@ import React from 'react';
28
28
  import cx from 'classnames';
29
29
  import { MenuExtraContent } from '../Menu';
30
30
  import { Text } from '../Typography';
31
- import { useTheme, getRandomValue, mergeRefs, } from '../utils';
31
+ import { useTheme, getRandomValue, mergeRefs, useLatestRef, } from '../utils';
32
32
  import 'tippy.js/animations/shift-away.css';
33
33
  import { ComboBoxActionContext, comboBoxReducer, ComboBoxRefsContext, ComboBoxStateContext, } from './helpers';
34
34
  import { ComboBoxDropdown } from './ComboBoxDropdown';
@@ -68,11 +68,10 @@ export var ComboBox = function (props) {
68
68
  var inputRef = React.useRef(null);
69
69
  var menuRef = React.useRef(null);
70
70
  var toggleButtonRef = React.useRef(null);
71
- // Latest value of the onChange prop
72
- var onChangeProp = React.useRef(onChange);
73
- React.useEffect(function () {
74
- onChangeProp.current = onChange;
75
- }, [onChange]);
71
+ var mounted = React.useRef(false);
72
+ var valuePropRef = useLatestRef(valueProp);
73
+ var onChangeProp = useLatestRef(onChange);
74
+ var optionsRef = useLatestRef(options);
76
75
  // Record to store all extra information (e.g. original indexes), where the key is the id of the option
77
76
  var optionsExtraInfoRef = React.useRef({});
78
77
  // Clear the extra info when the options change so that it can be reinitialized below
@@ -91,7 +90,9 @@ export var ComboBox = function (props) {
91
90
  // Reducer where all the component-wide state is stored
92
91
  var _e = React.useReducer(comboBoxReducer, {
93
92
  isOpen: false,
94
- selectedIndex: -1,
93
+ selectedIndex: valueProp
94
+ ? optionsRef.current.findIndex(function (option) { return option.value === valueProp; })
95
+ : -1,
95
96
  focusedIndex: -1,
96
97
  }), _f = _e[0], isOpen = _f.isOpen, selectedIndex = _f.selectedIndex, focusedIndex = _f.focusedIndex, dispatch = _e[1];
97
98
  React.useLayoutEffect(function () {
@@ -99,7 +100,7 @@ export var ComboBox = function (props) {
99
100
  // When the dropdown opens
100
101
  if (isOpen) {
101
102
  (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus(); // Focus the input
102
- setFilteredOptions(options); // Reset the filtered list
103
+ setFilteredOptions(optionsRef.current); // Reset the filtered list
103
104
  dispatch(['focus']);
104
105
  }
105
106
  // When the dropdown closes
@@ -108,10 +109,10 @@ export var ComboBox = function (props) {
108
109
  dispatch(['focus']);
109
110
  // Reset the input value
110
111
  setInputValue(selectedIndex != undefined && selectedIndex >= 0
111
- ? (_b = options[selectedIndex]) === null || _b === void 0 ? void 0 : _b.label
112
+ ? (_b = optionsRef.current[selectedIndex]) === null || _b === void 0 ? void 0 : _b.label
112
113
  : '');
113
114
  }
114
- }, [isOpen, options, selectedIndex]);
115
+ }, [isOpen, optionsRef, selectedIndex]);
115
116
  // Set min-width of menu to be same as input
116
117
  var _g = React.useState(0), minWidth = _g[0], setMinWidth = _g[1];
117
118
  React.useEffect(function () {
@@ -142,14 +143,14 @@ export var ComboBox = function (props) {
142
143
  var value = event.currentTarget.value;
143
144
  setInputValue(value);
144
145
  dispatch(['open']); // reopen when typing
145
- setFilteredOptions((_a = filterFunction === null || filterFunction === void 0 ? void 0 : filterFunction(options, value)) !== null && _a !== void 0 ? _a : options.filter(function (option) {
146
+ setFilteredOptions((_a = filterFunction === null || filterFunction === void 0 ? void 0 : filterFunction(optionsRef.current, value)) !== null && _a !== void 0 ? _a : optionsRef.current.filter(function (option) {
146
147
  return option.label.toLowerCase().includes(value.toLowerCase());
147
148
  }));
148
149
  if (focusedIndex != -1) {
149
150
  dispatch(['focus', -1]);
150
151
  }
151
152
  (_b = inputProps === null || inputProps === void 0 ? void 0 : inputProps.onChange) === null || _b === void 0 ? void 0 : _b.call(inputProps, event);
152
- }, [filterFunction, focusedIndex, inputProps, options]);
153
+ }, [filterFunction, focusedIndex, inputProps, optionsRef]);
153
154
  // When the value prop changes, update the selectedIndex
154
155
  React.useEffect(function () {
155
156
  dispatch([
@@ -160,14 +161,17 @@ export var ComboBox = function (props) {
160
161
  // Call user-defined onChange when the value actually changes
161
162
  React.useEffect(function () {
162
163
  var _a, _b;
163
- if (selectedIndex != undefined && selectedIndex >= 0) {
164
- var value = (_a = options[selectedIndex]) === null || _a === void 0 ? void 0 : _a.value;
165
- if (value === valueProp) {
166
- return;
167
- }
168
- (_b = onChangeProp.current) === null || _b === void 0 ? void 0 : _b.call(onChangeProp, value);
164
+ // Prevent user-defined onChange to be called on mount
165
+ if (!mounted.current) {
166
+ mounted.current = true;
167
+ return;
168
+ }
169
+ var currentValue = (_a = optionsRef.current[selectedIndex]) === null || _a === void 0 ? void 0 : _a.value;
170
+ if (currentValue === valuePropRef.current || selectedIndex === -1) {
171
+ return;
169
172
  }
170
- }, [options, selectedIndex, valueProp]);
173
+ (_b = onChangeProp.current) === null || _b === void 0 ? void 0 : _b.call(onChangeProp, currentValue);
174
+ }, [onChangeProp, optionsRef, selectedIndex, valuePropRef]);
171
175
  var getMenuItem = React.useCallback(function (option, filteredIndex) {
172
176
  var optionId = getOptionId(option, id);
173
177
  var __originalIndex = optionsExtraInfoRef.current[optionId].__originalIndex;
@@ -0,0 +1,41 @@
1
+ import React from 'react';
2
+ import '@itwin/itwinui-css/css/dialog.css';
3
+ import { DialogContextProps } from './DialogContext';
4
+ export declare type DialogProps = {
5
+ /**
6
+ * Dialog content.
7
+ */
8
+ children: React.ReactNode;
9
+ } & DialogContextProps;
10
+ /**
11
+ * Dialog component.
12
+ * @example
13
+ * <Dialog
14
+ * isOpen={isOpen}
15
+ * onClose={() => setIsOpen(false)}
16
+ * trapFocus
17
+ * preventDocumentScroll
18
+ * >
19
+ * <Dialog.Backdrop />
20
+ * <Dialog.Main aria-modal>
21
+ * <Dialog.TitleBar>My dialog title</Dialog.TitleBar>
22
+ * <Dialog.Content>
23
+ * Here is my dialog content
24
+ * </Dialog.Content>
25
+ * <Dialog.ButtonBar>
26
+ * <Button styleType='high-visibility'>Confirm</Button>
27
+ * <Button>Close</Button>
28
+ * </Dialog.ButtonBar>
29
+ * </Dialog.Main>
30
+ * </Dialog>
31
+ */
32
+ export declare const Dialog: ((props: DialogProps) => JSX.Element) & {
33
+ Backdrop: React.ForwardRefExoticComponent<Pick<import("./DialogBackdrop").DialogBackdropProps, "onClose" | "key" | keyof React.HTMLAttributes<HTMLDivElement> | "isVisible" | "isDismissible" | "closeOnExternalClick"> & React.RefAttributes<HTMLDivElement>>;
34
+ Main: React.ForwardRefExoticComponent<Pick<import("./DialogMain").DialogMainProps, "onClose" | "key" | keyof React.HTMLAttributes<HTMLDivElement> | "styleType" | "isOpen" | "isDismissible" | "closeOnEsc" | "trapFocus" | "preventDocumentScroll"> & React.RefAttributes<HTMLDivElement>>;
35
+ TitleBar: React.ForwardRefExoticComponent<Pick<import("./DialogTitleBar").DialogTitleBarProps, "onClose" | "key" | keyof React.HTMLAttributes<HTMLDivElement> | "isDismissible" | "titleText"> & React.RefAttributes<HTMLDivElement>> & {
36
+ Title: React.ForwardRefExoticComponent<Pick<import("./DialogTitleBarTitle").DialogTitleBarTitleProps, "key" | keyof React.HTMLAttributes<HTMLDivElement>> & React.RefAttributes<HTMLDivElement>>;
37
+ };
38
+ Content: React.ForwardRefExoticComponent<Pick<import("./DialogContent").DialogContentProps, "key" | keyof React.HTMLAttributes<HTMLDivElement>> & React.RefAttributes<HTMLDivElement>>;
39
+ ButtonBar: React.ForwardRefExoticComponent<Pick<import("./DialogButtonBar").DialogButtonBarProps, "key" | keyof React.HTMLAttributes<HTMLDivElement>> & React.RefAttributes<HTMLDivElement>>;
40
+ };
41
+ export default Dialog;