@deque/cauldron-react 7.0.0 → 7.1.0-canary.0826a4c3

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 (111) hide show
  1. package/lib/add-user.js +1 -1
  2. package/lib/arrow-circle.js +1 -1
  3. package/lib/arrow.js +1 -1
  4. package/lib/arrows-alt.js +1 -1
  5. package/lib/bolt.js +1 -1
  6. package/lib/broken-image.js +1 -1
  7. package/lib/caution.js +1 -1
  8. package/lib/check-circle.js +1 -1
  9. package/lib/check-shield.js +1 -1
  10. package/lib/check-solid.js +1 -1
  11. package/lib/check.js +1 -1
  12. package/lib/checkbox-checked.js +1 -1
  13. package/lib/checkbox-unchecked.js +1 -1
  14. package/lib/chevron-double.js +1 -1
  15. package/lib/chevron.js +1 -1
  16. package/lib/clipboard.js +1 -1
  17. package/lib/clock.js +1 -1
  18. package/lib/close.js +1 -1
  19. package/lib/code.js +1 -1
  20. package/lib/components/Accordion/Accordion.d.ts +1 -1
  21. package/lib/components/ActionList/ActionList.d.ts +1 -1
  22. package/lib/components/ActionMenu/ActionMenu.d.ts +14 -8
  23. package/lib/components/AnchoredOverlay/index.d.ts +2 -2
  24. package/lib/components/Checkbox/index.d.ts +2 -0
  25. package/lib/components/ClickOutsideListener/index.d.ts +1 -1
  26. package/lib/components/Combobox/Combobox.d.ts +1 -1
  27. package/lib/components/Dialog/DialogContext.d.ts +1 -1
  28. package/lib/components/Dialog/index.d.ts +1 -1
  29. package/lib/components/Drawer/index.d.ts +1 -1
  30. package/lib/components/ExpandCollapsePanel/ExpandCollapsePanel.d.ts +1 -1
  31. package/lib/components/Listbox/Listbox.d.ts +7 -2
  32. package/lib/components/MenuBar/index.d.ts +1 -0
  33. package/lib/components/Popover/index.d.ts +2 -2
  34. package/lib/components/Table/TableContext.d.ts +1 -1
  35. package/lib/components/Tabs/Tab.d.ts +1 -1
  36. package/lib/components/Toast/index.d.ts +7 -27
  37. package/lib/components/Tooltip/index.d.ts +2 -2
  38. package/lib/components/TreeView/TreeViewItem.d.ts +7 -0
  39. package/lib/components/TreeView/helpers.d.ts +33 -0
  40. package/lib/components/TreeView/index.d.ts +19 -0
  41. package/lib/components/TreeView/types.d.ts +8 -0
  42. package/lib/copy.js +1 -1
  43. package/lib/download.js +1 -1
  44. package/lib/dropper.js +1 -1
  45. package/lib/exchange.js +1 -1
  46. package/lib/export-solid.js +1 -1
  47. package/lib/external-link.js +1 -1
  48. package/lib/eye.js +1 -1
  49. package/lib/filter.js +1 -1
  50. package/lib/flag.js +1 -1
  51. package/lib/gears.js +1 -1
  52. package/lib/github.js +1 -1
  53. package/lib/grid.js +1 -1
  54. package/lib/hamburger-menu.js +1 -1
  55. package/lib/hashtag.js +1 -1
  56. package/lib/highlight.js +1 -1
  57. package/lib/images.js +1 -1
  58. package/lib/index.d.ts +1 -0
  59. package/lib/index.js +408 -216
  60. package/lib/info-circle-alt.js +1 -1
  61. package/lib/info-circle.js +1 -1
  62. package/lib/info-square.js +1 -1
  63. package/lib/kabob.js +1 -1
  64. package/lib/link.js +1 -1
  65. package/lib/linkedin.js +1 -1
  66. package/lib/list.js +1 -1
  67. package/lib/lock.js +1 -1
  68. package/lib/magnifying-glass.js +1 -1
  69. package/lib/menu.js +1 -1
  70. package/lib/minus.js +1 -1
  71. package/lib/new-releases.js +1 -1
  72. package/lib/new.js +1 -1
  73. package/lib/no.js +1 -1
  74. package/lib/pause.js +1 -1
  75. package/lib/pencil.js +1 -1
  76. package/lib/person-running.js +1 -1
  77. package/lib/play.js +1 -1
  78. package/lib/plus.js +1 -1
  79. package/lib/question-circle-alt.js +1 -1
  80. package/lib/question-circle.js +1 -1
  81. package/lib/radio-checked.js +1 -1
  82. package/lib/radio-unchecked.js +1 -1
  83. package/lib/recycle-square.js +1 -1
  84. package/lib/recycle.js +1 -1
  85. package/lib/resend.js +1 -1
  86. package/lib/robot.js +1 -1
  87. package/lib/run-again.js +1 -1
  88. package/lib/save.js +1 -1
  89. package/lib/share-nodes.js +1 -1
  90. package/lib/share.js +1 -1
  91. package/lib/sort-triangle.js +1 -1
  92. package/lib/sort.js +1 -1
  93. package/lib/star.js +1 -1
  94. package/lib/step-back.js +1 -1
  95. package/lib/step-forward.js +1 -1
  96. package/lib/sun.js +1 -1
  97. package/lib/table-sort-ascending.js +1 -1
  98. package/lib/table-sort-descending.js +1 -1
  99. package/lib/tag.js +1 -1
  100. package/lib/target.js +1 -1
  101. package/lib/trash.js +1 -1
  102. package/lib/triangle.js +1 -1
  103. package/lib/twitter.js +1 -1
  104. package/lib/types.d.ts +1 -1
  105. package/lib/upload.js +1 -1
  106. package/lib/utils/getChildRef.d.ts +2 -0
  107. package/lib/utils/polymorphicComponent.d.ts +1 -1
  108. package/lib/utils/useFocusTrap.d.ts +1 -1
  109. package/lib/utils/useMnemonics.d.ts +2 -2
  110. package/lib/utils/useSharedRef.d.ts +3 -3
  111. package/package.json +30 -24
package/lib/index.js CHANGED
@@ -16,6 +16,7 @@ var js = require('react-syntax-highlighter/dist/cjs/languages/hljs/javascript');
16
16
  var css = require('react-syntax-highlighter/dist/cjs/languages/hljs/css');
17
17
  var xml = require('react-syntax-highlighter/dist/cjs/languages/hljs/xml');
18
18
  var yaml = require('react-syntax-highlighter/dist/cjs/languages/hljs/yaml');
19
+ var reactAriaComponents = require('react-aria-components');
19
20
 
20
21
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
21
22
 
@@ -494,24 +495,25 @@ var Accordion = function (_a) {
494
495
  var childrenArray = React__default["default"].Children.toArray(children);
495
496
  var trigger = childrenArray.find(function (child) {
496
497
  return typeof child === 'string' ||
497
- child.type === AccordionTrigger;
498
+ (React__default["default"].isValidElement(child) && child.type === AccordionTrigger);
498
499
  });
499
500
  var panelElement = childrenArray.find(function (child) {
500
501
  return typeof child === 'string' ||
501
- child.type === AccordionContent;
502
+ (React__default["default"].isValidElement(child) && child.type === AccordionContent);
502
503
  });
503
- var isValid = !!(React__default["default"].isValidElement(trigger) && React__default["default"].isValidElement(panelElement));
504
- if (!isValid) {
504
+ if (!React__default["default"].isValidElement(trigger) ||
505
+ !React__default["default"].isValidElement(panelElement)) {
505
506
  console.warn('Must provide <AccordionTrigger /> and <AccordionContent /> element(s). You provided:', {
506
507
  trigger: trigger,
507
508
  panelElement: panelElement,
508
- isValid: isValid
509
+ isValid: false
509
510
  });
510
511
  return null;
511
512
  }
513
+ var panelProps = panelElement.props;
512
514
  return (React__default["default"].createElement("div", tslib.__assign({ className: "Accordion" }, props),
513
- React__default["default"].createElement(ExpandCollapsePanel, tslib.__assign({ id: panelElement.props.id || "".concat(elementId, "-panel"), open: open, onToggle: onToggle, animationTiming: animationTiming }, panelElement.props),
514
- React__default["default"].createElement(PanelTrigger$1, tslib.__assign({ iconCollapsed: "triangle-right", iconExpanded: "triangle-down", className: classNames__default["default"]('Accordion__trigger', trigger.props.className), "aria-controls": panelElement.props.id || "".concat(elementId, "-panel"), heading: trigger.props.heading }, trigger.props), trigger),
515
+ React__default["default"].createElement(ExpandCollapsePanel, tslib.__assign({ id: panelProps.id || "".concat(elementId, "-panel"), open: open, onToggle: onToggle, animationTiming: animationTiming }, panelProps),
516
+ React__default["default"].createElement(PanelTrigger$1, tslib.__assign({ iconCollapsed: "triangle-right", iconExpanded: "triangle-down", className: classNames__default["default"]('Accordion__trigger', trigger.props.className), "aria-controls": panelProps.id || "".concat(elementId, "-panel"), heading: trigger.props.heading }, trigger.props), trigger),
515
517
  panelElement)));
516
518
  };
517
519
  Accordion.displayName = 'Accordion';
@@ -577,7 +579,9 @@ var Scrim = /** @class */ (function (_super) {
577
579
  if (destroy) {
578
580
  return null;
579
581
  }
580
- return (React__default["default"].createElement("div", { ref: function (el) { return (_this.el = el); }, className: "Scrim ".concat(animationClass) }));
582
+ return (React__default["default"].createElement("div", { ref: function (el) {
583
+ _this.el = el;
584
+ }, className: "Scrim ".concat(animationClass) }));
581
585
  };
582
586
  return Scrim;
583
587
  }(React__default["default"].Component));
@@ -671,6 +675,7 @@ var TopBar$1 = /** @class */ (function (_super) {
671
675
  tslib.__extends(TopBar, _super);
672
676
  function TopBar(props) {
673
677
  var _this = _super.call(this, props) || this;
678
+ _this.menuBarRef = React__default["default"].createRef();
674
679
  _this.onResize = function () {
675
680
  var wide = isWide();
676
681
  if (wide === _this.state.wide) {
@@ -719,10 +724,10 @@ var TopBar$1 = /** @class */ (function (_super) {
719
724
  };
720
725
  TopBar.prototype.onKeyDown = function (e) {
721
726
  var key = keyname__default["default"](e.which);
722
- // This is a temporary workaround until have an opportunity to refactor or replace menubar
723
- // see: https://github.com/dequelabs/cauldron/issues/1934
724
- // eslint-disable-next-line react/no-find-dom-node
725
- var menuBarElement = reactDom.findDOMNode(this);
727
+ var menuBarElement = this.menuBarRef.current;
728
+ if (!menuBarElement) {
729
+ return;
730
+ }
726
731
  var menuItems = Array.from(menuBarElement.children);
727
732
  // account for hidden side bar trigger (hamburger)
728
733
  if (this.state.wide && this.props.hasTrigger) {
@@ -749,7 +754,7 @@ var TopBar$1 = /** @class */ (function (_super) {
749
754
  // disabling no-unused-vars to prevent thin/hasTrigger from being passed through to div
750
755
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
751
756
  var _a = this.props, children = _a.children, className = _a.className; _a.thin; _a.hasTrigger; tslib.__rest(_a, ["children", "className", "thin", "hasTrigger"]);
752
- return (React__default["default"].createElement("ul", { role: "menubar", onKeyDown: this.onKeyDown, className: className }, React.Children.map(children, this.renderChild)));
757
+ return (React__default["default"].createElement("ul", { role: "menubar", onKeyDown: this.onKeyDown, className: className, ref: this.menuBarRef }, React.Children.map(children, this.renderChild)));
753
758
  };
754
759
  TopBar.defaultProps = {
755
760
  thin: false,
@@ -805,9 +810,16 @@ function resolveElement(elementOrRef) {
805
810
  return null;
806
811
  }
807
812
 
813
+ function getChildRef(child, version) {
814
+ if (version === void 0) { version = React__default["default"].version; }
815
+ return parseInt(version, 10) >= 19
816
+ ? child.props.ref
817
+ : child.ref;
818
+ }
819
+
808
820
  function ClickOutsideListener(_a, ref) {
809
821
  var children = _a.children, _b = _a.mouseEvent, mouseEvent = _b === void 0 ? 'click' : _b, _c = _a.touchEvent, touchEvent = _c === void 0 ? 'touchend' : _c, target = _a.target, _d = _a.onClickOutside, onClickOutside = _d === void 0 ? function () { return null; } : _d;
810
- var childElementRef = React.useRef();
822
+ var childElementRef = React.useRef(null);
811
823
  var handleEvent = function (event) {
812
824
  if (event.defaultPrevented) {
813
825
  return;
@@ -830,9 +842,8 @@ function ClickOutsideListener(_a, ref) {
830
842
  childElementRef.current = node;
831
843
  // Ref for this component should pass-through to the child node
832
844
  setRef(ref, node);
833
- // If child has its own ref, we want to update
834
- // its ref with the newly cloned node
835
- var childRef = children.ref;
845
+ // Forward the child's own ref. In React 19 ref lives in props; in 16–18 it's element.ref.
846
+ var childRef = getChildRef(children);
836
847
  setRef(childRef, node);
837
848
  };
838
849
  React.useEffect(function () {
@@ -1341,7 +1352,7 @@ var AriaIsolate = /** @class */ (function () {
1341
1352
 
1342
1353
  /**
1343
1354
  * When a component needs to track an internal ref on a component that has a
1344
- * forwarded ref, useSharedRef will return a MutableRefObject<T> that will
1355
+ * forwarded ref, useSharedRef will return a RefObject<T | null> that will
1345
1356
  * correctly invoke the parent ref as well providing an internal ref.
1346
1357
  *
1347
1358
  * @example
@@ -1354,9 +1365,10 @@ var AriaIsolate = /** @class */ (function () {
1354
1365
  * })
1355
1366
  */
1356
1367
  function useSharedRef(ref) {
1357
- var internalRef = React.useRef();
1368
+ var internalRef = React.useRef(null);
1358
1369
  React.useEffect(function () {
1359
1370
  setRef(ref, internalRef.current);
1371
+ return function () { return setRef(ref, null); };
1360
1372
  }, [ref]);
1361
1373
  return internalRef;
1362
1374
  }
@@ -1486,7 +1498,7 @@ function useFocusTrap(target, options) {
1486
1498
  if (options === void 0) { options = {}; }
1487
1499
  var _a = options.disabled, disabled = _a === void 0 ? false : _a, _b = options.returnFocus, returnFocus = _b === void 0 ? true : _b, initialFocusElementOrRef = options.initialFocusElement, returnFocusElement = options.returnFocusElement;
1488
1500
  var focusTrap = React.useRef(null);
1489
- var returnFocusElementRef = React.useRef();
1501
+ var returnFocusElementRef = React.useRef(null);
1490
1502
  function restoreFocusToReturnFocusElement() {
1491
1503
  var _a;
1492
1504
  var resolvedReturnFocusElement = resolveElement(returnFocusElement);
@@ -1536,7 +1548,7 @@ var Dialog = React.forwardRef(function (_a, ref) {
1536
1548
  var dialogRef = useSharedRef(dialogRefProp || ref);
1537
1549
  var _g = tslib.__read(nextId.useId(1, 'dialog-title-'), 1), headingId = _g[0];
1538
1550
  var headingRef = React.useRef(null);
1539
- var isolatorRef = React.useRef();
1551
+ var isolatorRef = React.useRef(null);
1540
1552
  var headingLevel = typeof heading === 'object' && 'level' in heading && heading.level
1541
1553
  ? heading.level
1542
1554
  : 2;
@@ -2033,10 +2045,17 @@ function Tooltip(_a) {
2033
2045
  fireCustomEvent(false, targetElement);
2034
2046
  }, TIP_HIDE_DELAY);
2035
2047
  }
2048
+ }, [target]);
2049
+ // Cancel any pending hide timeout when the Tooltip unmounts so it
2050
+ // does not fire setShowTooltip on an unmounted component.
2051
+ React.useEffect(function () {
2036
2052
  return function () {
2037
- clearTimeout(hideTimeoutRef.current);
2053
+ if (hideTimeoutRef.current) {
2054
+ clearTimeout(hideTimeoutRef.current);
2055
+ hideTimeoutRef.current = null;
2056
+ }
2038
2057
  };
2039
- }, [target]);
2058
+ }, []);
2040
2059
  React.useEffect(function () {
2041
2060
  if (typeof showProp === 'boolean') {
2042
2061
  setShowTooltip(showProp);
@@ -2124,7 +2143,7 @@ var looksLikeLink = function (props) {
2124
2143
  };
2125
2144
  var IconButton = React.forwardRef(function (_a, ref) {
2126
2145
  var _b = _a.as, Component = _b === void 0 ? 'button' : _b, icon = _a.icon, label = _a.label, _c = _a.tooltipProps, tooltipPropsProp = _c === void 0 ? {} : _c, className = _a.className, _d = _a.variant, variant = _d === void 0 ? 'secondary' : _d, disabled = _a.disabled, _e = _a.tabIndex, tabIndex = _e === void 0 ? 0 : _e, large = _a.large, other = tslib.__rest(_a, ["as", "icon", "label", "tooltipProps", "className", "variant", "disabled", "tabIndex", "large"]);
2127
- var internalRef = React.useRef();
2146
+ var internalRef = React.useRef(null);
2128
2147
  React.useImperativeHandle(ref, function () { return internalRef.current; });
2129
2148
  // Configure additional properties based on the type of the Component
2130
2149
  // for accessibility
@@ -2213,126 +2232,118 @@ var tabIndexHandler = function (reset, toast) {
2213
2232
  };
2214
2233
 
2215
2234
  /**
2216
- * The cauldron toast notification component
2235
+ * Hook to be used similarly to the React.Component#componentDidMount.
2236
+ * Executes the provided `effect` when `dependencies` change but does not
2237
+ * execute the effect initially (on mount) - only on update.
2238
+ *
2239
+ * @param effect {Function} function to be executed when dependencies update
2240
+ * @param dependencies {Any} any valid dependency argument to React.useEffect
2217
2241
  */
2218
- var Toast = /** @class */ (function (_super) {
2219
- tslib.__extends(Toast, _super);
2220
- function Toast(props) {
2221
- var _this = _super.call(this, props) || this;
2222
- _this.state = {
2223
- animationClass: props.show ? 'FadeIn--flex' : 'is--hidden'
2224
- };
2225
- _this.dismissToast = _this.dismissToast.bind(_this);
2226
- _this.showToast = _this.showToast.bind(_this);
2227
- return _this;
2228
- }
2229
- Toast.prototype.componentDidMount = function () {
2230
- var show = this.props.show;
2231
- if (show) {
2232
- // Timeout because CSS display: none/block and opacity:
2233
- // 0/1 properties cannot be toggled in the same tick
2234
- // see: https://codepen.io/isnerms/pen/eyQaLP
2235
- setTimeout(this.showToast);
2242
+ var useDidUpdate = function (effect, dependencies) {
2243
+ var mounted = React__default["default"].useRef(false);
2244
+ React__default["default"].useEffect(function () {
2245
+ if (!mounted.current) {
2246
+ mounted.current = true;
2247
+ return;
2236
2248
  }
2249
+ effect();
2250
+ }, dependencies);
2251
+ };
2252
+
2253
+ /**
2254
+ * The cauldron toast notification component
2255
+ */
2256
+ var Toast = React.forwardRef(function (_a, ref) {
2257
+ var type = _a.type, children = _a.children, _b = _a.onDismiss, onDismiss = _b === void 0 ? function () {
2258
+ // noop
2259
+ } : _b, _c = _a.dismissText, dismissText = _c === void 0 ? 'Dismiss' : _c, toastRef = _a.toastRef, _d = _a.focus, focus = _d === void 0 ? true : _d, _e = _a.show, show = _e === void 0 ? false : _e, _f = _a.dismissible, dismissible = _f === void 0 ? true : _f, className = _a.className, otherProps = tslib.__rest(_a, ["type", "children", "onDismiss", "dismissText", "toastRef", "focus", "show", "dismissible", "className"]);
2260
+ var elRef = useSharedRef(ref);
2261
+ var isolatorRef = React.useRef(null);
2262
+ var timeoutsRef = React.useRef(new Set());
2263
+ var _g = tslib.__read(React.useState(show ? 'FadeIn--flex' : 'is--hidden'), 2), animationClass = _g[0], setAnimationClass = _g[1];
2264
+ // Backwards-compat: propagate to the deprecated toastRef prop as well
2265
+ React.useEffect(function () {
2266
+ var _a;
2267
+ if (!toastRef)
2268
+ return;
2269
+ setRef(toastRef, (_a = elRef.current) !== null && _a !== void 0 ? _a : null);
2270
+ return function () { return setRef(toastRef, null); };
2271
+ }, [toastRef]);
2272
+ // Timeout because CSS display: none/block and opacity:
2273
+ // 0/1 properties cannot be toggled in the same tick
2274
+ // see: https://codepen.io/isnerms/pen/eyQaLP
2275
+ var scheduleNextTick = function (fn) {
2276
+ var id = setTimeout(function () {
2277
+ timeoutsRef.current.delete(id);
2278
+ fn();
2279
+ });
2280
+ timeoutsRef.current.add(id);
2237
2281
  };
2238
- Toast.prototype.componentDidUpdate = function (prevProps) {
2239
- var _this = this;
2240
- var show = this.props.show;
2241
- if (prevProps.show !== show) {
2242
- if (show) {
2243
- this.setState({ animationClass: 'FadeIn--flex' }, function () {
2244
- setTimeout(_this.showToast);
2245
- });
2246
- }
2247
- else {
2248
- this.dismissToast();
2249
- }
2282
+ var showToast = React.useCallback(function () {
2283
+ setAnimationClass('FadeIn--flex FadeIn');
2284
+ if (type === 'action-needed' && elRef.current) {
2285
+ var isolator = new AriaIsolate(elRef.current);
2286
+ tabIndexHandler(false, elRef.current);
2287
+ isolatorRef.current = isolator;
2288
+ isolator.activate();
2250
2289
  }
2251
- };
2252
- Toast.prototype.componentWillUnmount = function () {
2253
- var isolator = this.state.isolator;
2254
- isolator === null || isolator === void 0 ? void 0 : isolator.deactivate();
2255
- };
2256
- Toast.prototype.render = function () {
2257
- var _this = this;
2258
- var animationClass = this.state.animationClass;
2259
- var _a = this.props, type = _a.type, children = _a.children;
2260
- // prevent `onDismiss` from being passed-through to DOM
2261
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
2262
- _a.onDismiss; var dismissText = _a.dismissText, toastRef = _a.toastRef, focus = _a.focus, show = _a.show, dismissible = _a.dismissible, className = _a.className, otherProps = tslib.__rest(_a, ["type", "children", "onDismiss", "dismissText", "toastRef", "focus", "show", "dismissible", "className"]);
2263
- var scrim = type === 'action-needed' && show ? (React__default["default"].createElement("div", { className: "Scrim--light Scrim--show Scrim--fade-in" })) : null;
2264
- var defaultProps = {
2265
- tabIndex: -1,
2266
- className: classNames__default["default"]('Toast', "Toast--".concat(typeMap[type].className), animationClass, { 'Toast--non-dismissible': !dismissible }, className)
2267
- };
2268
- if (!focus) {
2269
- defaultProps.role = 'alert';
2290
+ if (elRef.current && !!focus) {
2291
+ elRef.current.focus();
2270
2292
  }
2271
- return (React__default["default"].createElement(React__default["default"].Fragment, null,
2272
- React__default["default"].createElement("div", tslib.__assign({ ref: function (el) {
2273
- _this.el = el;
2274
- setRef(toastRef, el);
2275
- } }, defaultProps, otherProps),
2276
- React__default["default"].createElement("div", { className: "Toast__message" },
2277
- React__default["default"].createElement(Icon, { type: typeMap[type].icon }),
2278
- React__default["default"].createElement("div", { className: "Toast__message-content" }, children)),
2279
- type !== 'action-needed' && dismissible && (React__default["default"].createElement("button", { type: "button", className: 'Toast__dismiss', "aria-label": dismissText, onClick: this.dismissToast },
2280
- React__default["default"].createElement(Icon, { type: "close" })))),
2281
- scrim));
2282
- };
2283
- Toast.prototype.dismissToast = function () {
2284
- var _this = this;
2285
- if (!this.el) {
2293
+ }, [type, focus]);
2294
+ var dismissToast = React.useCallback(function () {
2295
+ if (!elRef.current) {
2286
2296
  return;
2287
2297
  }
2288
- var _a = this.props, onDismiss = _a.onDismiss, type = _a.type;
2289
- var isolator = this.state.isolator;
2290
- this.setState({
2291
- animationClass: 'FadeIn--flex'
2292
- }, function () {
2293
- // Timeout because CSS display: none/block and opacity:
2294
- // 0/1 properties cannot be toggled in the same tick
2295
- // see: https://codepen.io/isnerms/pen/eyQaLP
2296
- setTimeout(function () {
2297
- if (type === 'action-needed') {
2298
- tabIndexHandler(true, _this.el);
2299
- isolator === null || isolator === void 0 ? void 0 : isolator.deactivate();
2300
- }
2301
- _this.setState({ animationClass: 'is--hidden' }, onDismiss);
2302
- });
2303
- });
2304
- };
2305
- Toast.prototype.showToast = function () {
2306
- var _this = this;
2307
- var _a = this.props, type = _a.type, focus = _a.focus;
2308
- this.setState({
2309
- animationClass: 'FadeIn--flex FadeIn'
2310
- }, function () {
2298
+ setAnimationClass('FadeIn--flex');
2299
+ scheduleNextTick(function () {
2300
+ var _a;
2311
2301
  if (type === 'action-needed') {
2312
- var isolator = new AriaIsolate(_this.el);
2313
- tabIndexHandler(false, _this.el);
2314
- _this.setState({ isolator: isolator });
2315
- isolator.activate();
2316
- }
2317
- if (_this.el && !!focus) {
2318
- // focus the toast
2319
- _this.el.focus();
2302
+ tabIndexHandler(true, elRef.current);
2303
+ (_a = isolatorRef.current) === null || _a === void 0 ? void 0 : _a.deactivate();
2320
2304
  }
2305
+ setAnimationClass('is--hidden');
2306
+ onDismiss();
2321
2307
  });
2308
+ }, [type, onDismiss]);
2309
+ React.useEffect(function () {
2310
+ if (show) {
2311
+ scheduleNextTick(showToast);
2312
+ }
2313
+ return function () {
2314
+ var _a;
2315
+ timeoutsRef.current.forEach(clearTimeout);
2316
+ timeoutsRef.current.clear();
2317
+ (_a = isolatorRef.current) === null || _a === void 0 ? void 0 : _a.deactivate();
2318
+ };
2319
+ }, []);
2320
+ useDidUpdate(function () {
2321
+ if (show) {
2322
+ setAnimationClass('FadeIn--flex');
2323
+ scheduleNextTick(showToast);
2324
+ }
2325
+ else {
2326
+ dismissToast();
2327
+ }
2328
+ }, [show]);
2329
+ var scrim = type === 'action-needed' && show ? (React__default["default"].createElement("div", { className: "Scrim--light Scrim--show Scrim--fade-in" })) : null;
2330
+ var defaultProps = {
2331
+ tabIndex: -1,
2332
+ className: classNames__default["default"]('Toast', "Toast--".concat(typeMap[type].className), animationClass, { 'Toast--non-dismissible': !dismissible }, className)
2322
2333
  };
2323
- Toast.defaultProps = {
2324
- dismissText: 'Dismiss',
2325
- // eslint-disable-next-line @typescript-eslint/no-empty-function
2326
- onDismiss: function () { },
2327
- // eslint-disable-next-line @typescript-eslint/no-empty-function
2328
- toastRef: function () { },
2329
- focus: true,
2330
- show: false,
2331
- dismissible: true
2332
- };
2333
- Toast.displayName = 'Toast';
2334
- return Toast;
2335
- }(React__default["default"].Component));
2334
+ if (!focus) {
2335
+ defaultProps.role = 'alert';
2336
+ }
2337
+ return (React__default["default"].createElement(React__default["default"].Fragment, null,
2338
+ React__default["default"].createElement("div", tslib.__assign({ ref: elRef }, defaultProps, otherProps),
2339
+ React__default["default"].createElement("div", { className: "Toast__message" },
2340
+ React__default["default"].createElement(Icon, { type: typeMap[type].icon }),
2341
+ React__default["default"].createElement("div", { className: "Toast__message-content" }, children)),
2342
+ type !== 'action-needed' && dismissible && (React__default["default"].createElement("button", { type: "button", className: "Toast__dismiss", "aria-label": dismissText, onClick: dismissToast },
2343
+ React__default["default"].createElement(Icon, { type: "close" })))),
2344
+ scrim));
2345
+ });
2346
+ Toast.displayName = 'Toast';
2336
2347
 
2337
2348
  var Link = React.forwardRef(function (_a, ref) {
2338
2349
  var children = _a.children, linkRef = _a.linkRef, className = _a.className, variant = _a.variant, thin = _a.thin, other = tslib.__rest(_a, ["children", "linkRef", "className", "variant", "thin"]);
@@ -2599,10 +2610,10 @@ var RadioCardGroup = function (_a) {
2599
2610
  RadioCardGroup.displayName = 'RadioCardGroup';
2600
2611
 
2601
2612
  var Checkbox = React.forwardRef(function (_a, ref) {
2602
- var id = _a.id, label = _a.label, labelDescription = _a.labelDescription, error = _a.error, checkboxRef = _a.checkboxRef, className = _a.className, onChange = _a.onChange, onFocus = _a.onFocus, onBlur = _a.onBlur, ariaDescribedby = _a["aria-describedby"], _b = _a.disabled, disabled = _b === void 0 ? false : _b, _c = _a.checked, checked = _c === void 0 ? false : _c, _d = _a.indeterminate, indeterminate = _d === void 0 ? false : _d; _a.children; var other = tslib.__rest(_a, ["id", "label", "labelDescription", "error", "checkboxRef", "className", "onChange", "onFocus", "onBlur", 'aria-describedby', "disabled", "checked", "indeterminate", "children"]);
2603
- var _e = tslib.__read(React.useState(checked), 2), isChecked = _e[0], setIsChecked = _e[1];
2604
- var _f = tslib.__read(React.useState(indeterminate), 2), isIndeterminate = _f[0], setIsIndeterminate = _f[1];
2605
- var _g = tslib.__read(React.useState(false), 2), focused = _g[0], setFocused = _g[1];
2613
+ var id = _a.id, label = _a.label, labelDescription = _a.labelDescription, error = _a.error, checkboxRef = _a.checkboxRef, className = _a.className, onChange = _a.onChange, _b = _a.controlled, controlled = _b === void 0 ? false : _b, onFocus = _a.onFocus, onBlur = _a.onBlur, ariaDescribedby = _a["aria-describedby"], _c = _a.disabled, disabled = _c === void 0 ? false : _c, _d = _a.checked, checked = _d === void 0 ? false : _d, _e = _a.indeterminate, indeterminate = _e === void 0 ? false : _e; _a.children; var other = tslib.__rest(_a, ["id", "label", "labelDescription", "error", "checkboxRef", "className", "onChange", "controlled", "onFocus", "onBlur", 'aria-describedby', "disabled", "checked", "indeterminate", "children"]);
2614
+ var _f = tslib.__read(React.useState(checked), 2), isChecked = _f[0], setIsChecked = _f[1];
2615
+ var _g = tslib.__read(React.useState(indeterminate), 2), isIndeterminate = _g[0], setIsIndeterminate = _g[1];
2616
+ var _h = tslib.__read(React.useState(false), 2), focused = _h[0], setFocused = _h[1];
2606
2617
  var checkRef = React.useRef(null);
2607
2618
  React.useEffect(function () {
2608
2619
  setIsChecked(checked);
@@ -2614,12 +2625,12 @@ var Checkbox = React.forwardRef(function (_a, ref) {
2614
2625
  if (typeof refProp === 'function') {
2615
2626
  refProp(checkRef.current);
2616
2627
  }
2617
- var _h = React.useMemo(function () {
2628
+ var _j = React.useMemo(function () {
2618
2629
  return {
2619
2630
  labelDescriptionId: nextId__default["default"](),
2620
2631
  errorId: nextId__default["default"]()
2621
2632
  };
2622
- }, []), errorId = _h.errorId, labelDescriptionId = _h.labelDescriptionId;
2633
+ }, []), errorId = _j.errorId, labelDescriptionId = _j.labelDescriptionId;
2623
2634
  var ariaDescribedbyId = ariaDescribedby;
2624
2635
  if (error) {
2625
2636
  ariaDescribedbyId = addIdRef(ariaDescribedbyId, errorId);
@@ -2658,7 +2669,9 @@ var Checkbox = React.forwardRef(function (_a, ref) {
2658
2669
  if (isIndeterminate) {
2659
2670
  setIsIndeterminate(false);
2660
2671
  }
2661
- setIsChecked(e.target.checked);
2672
+ if (!controlled) {
2673
+ setIsChecked(e.target.checked);
2674
+ }
2662
2675
  if (onChange) {
2663
2676
  onChange(e);
2664
2677
  }
@@ -2692,7 +2705,7 @@ Checkbox.displayName = 'Checkbox';
2692
2705
  */
2693
2706
  function TooltipTabstop(_a) {
2694
2707
  var children = _a.children, className = _a.className, tooltip = _a.tooltip, variant = _a.variant, association = _a.association, show = _a.show, placement = _a.placement, portal = _a.portal, hideElementOnHidden = _a.hideElementOnHidden, buttonProps = tslib.__rest(_a, ["children", "className", "tooltip", "variant", "association", "show", "placement", "portal", "hideElementOnHidden"]);
2695
- var buttonRef = React.useRef();
2708
+ var buttonRef = React.useRef(null);
2696
2709
  return (React__default["default"].createElement(React__default["default"].Fragment, null,
2697
2710
  React__default["default"].createElement("button", tslib.__assign({ type: "button", ref: buttonRef, "aria-disabled": "true", className: classNames__default["default"]('TooltipTabstop', className) }, buttonProps), children),
2698
2711
  React__default["default"].createElement(Tooltip, { target: buttonRef, variant: variant, association: association, show: show, placement: placement, portal: portal, hideElementOnHidden: hideElementOnHidden }, tooltip)));
@@ -3231,25 +3244,6 @@ var Tab = React__default["default"].forwardRef(function (_a, ref) {
3231
3244
  });
3232
3245
  Tab.displayName = 'Tab';
3233
3246
 
3234
- /**
3235
- * Hook to be used similarly to the React.Component#componentDidMount.
3236
- * Executes the provided `effect` when `dependencies` change but does not
3237
- * execute the effect initially (on mount) - only on update.
3238
- *
3239
- * @param effect {Function} function to be executed when dependencies update
3240
- * @param dependencies {Any} any valid dependency argument to React.useEffect
3241
- */
3242
- var useDidUpdate = function (effect, dependencies) {
3243
- var mounted = React__default["default"].useRef(false);
3244
- React__default["default"].useEffect(function () {
3245
- if (!mounted.current) {
3246
- mounted.current = true;
3247
- return;
3248
- }
3249
- effect();
3250
- }, dependencies);
3251
- };
3252
-
3253
3247
  var Tabs = function (_a) {
3254
3248
  var children = _a.children, thin = _a.thin, _b = _a.orientation, orientation = _b === void 0 ? 'horizontal' : _b, _c = _a.initialActiveIndex, initialActiveIndex = _c === void 0 ? 0 : _c, className = _a.className, onChange = _a.onChange, labelProp = tslib.__rest(_a, ["children", "thin", "orientation", "initialActiveIndex", "className", "onChange"]);
3255
3249
  var _d = tslib.__read(React.useState(initialActiveIndex), 2), activeIndex = _d[0], setActiveIndex = _d[1];
@@ -3555,7 +3549,7 @@ var TwoColumnPanel = React.forwardRef(function (_a, ref) {
3555
3549
  var closeButtonRef = React.useRef(null);
3556
3550
  var columnLeftRef = React.useRef(null);
3557
3551
  var columnRightRef = React.useRef(null);
3558
- var columnLeft = React__default["default"].Children.toArray(children).find(function (child) { return child.type === ColumnLeft; });
3552
+ var columnLeft = React__default["default"].Children.toArray(children).find(function (child) { return React__default["default"].isValidElement(child) && child.type === ColumnLeft; });
3559
3553
  var togglePanel = function () {
3560
3554
  var prefersReducedMotion = 'matchMedia' in window &&
3561
3555
  typeof matchMedia === 'function' &&
@@ -3588,16 +3582,17 @@ var TwoColumnPanel = React.forwardRef(function (_a, ref) {
3588
3582
  var ColumnLeftComponent;
3589
3583
  var columnLeftId;
3590
3584
  if (React.isValidElement(columnLeft)) {
3591
- var ref_1 = columnLeft.props.ref || columnLeftRef;
3585
+ var columnLeftProps = columnLeft.props;
3586
+ var ref_1 = columnLeftProps.ref || columnLeftRef;
3592
3587
  var id = (columnLeftId =
3593
- columnLeft.props.id || nextId.useId(undefined, 'sidebar-')[0]);
3588
+ columnLeftProps.id || nextId.useId(undefined, 'sidebar-')[0]);
3594
3589
  var CloseButton = (React__default["default"].createElement("div", { className: "TwoColumnPanel__Close" },
3595
3590
  React__default["default"].createElement("button", { type: "button", onClick: togglePanel, ref: closeButtonRef, "aria-label": hideCollapsedPanelLabel },
3596
3591
  React__default["default"].createElement(Icon, { type: "close" })),
3597
3592
  React__default["default"].createElement(Tooltip, { target: closeButtonRef, association: "aria-labelledby", hideElementOnHidden: true }, hideCollapsedPanelLabel)));
3598
3593
  var children_1 = tslib.__spreadArray([
3599
3594
  CloseButton
3600
- ], tslib.__read(React__default["default"].Children.toArray(columnLeft.props.children)), false);
3595
+ ], tslib.__read(React__default["default"].Children.toArray(columnLeftProps.children)), false);
3601
3596
  ColumnLeftComponent = React.cloneElement(columnLeft, { id: id, ref: ref_1, tabIndex: -1 }, children_1.map(function (child, index) {
3602
3597
  return React.cloneElement(child, {
3603
3598
  key: child.key
@@ -3606,17 +3601,18 @@ var TwoColumnPanel = React.forwardRef(function (_a, ref) {
3606
3601
  });
3607
3602
  }));
3608
3603
  }
3609
- var columnRight = React__default["default"].Children.toArray(children).find(function (child) { return child.type === ColumnRight; });
3604
+ var columnRight = React__default["default"].Children.toArray(children).find(function (child) { return React__default["default"].isValidElement(child) && child.type === ColumnRight; });
3610
3605
  var ColumnRightComponent;
3611
3606
  if (React.isValidElement(columnRight)) {
3612
- var ref_2 = columnRight.props.ref || columnRightRef;
3607
+ var columnRightProps = columnRight.props;
3608
+ var ref_2 = columnRightProps.ref || columnRightRef;
3613
3609
  var ToggleButton = (React__default["default"].createElement("div", { className: "TwoColumnPanel__ButtonToggle" },
3614
3610
  React__default["default"].createElement("button", { type: "button", onClick: togglePanel, ref: toggleButtonRef, "aria-label": !isCollapsed ? hideCollapsedPanelLabel : showCollapsedPanelLabel, "aria-expanded": !isCollapsed, "aria-controls": columnLeftId },
3615
3611
  React__default["default"].createElement(Icon, { type: !isCollapsed ? 'chevron-double-left' : 'chevron-double-right' })),
3616
3612
  React__default["default"].createElement(Tooltip, { target: toggleButtonRef, association: "aria-labelledby", hideElementOnHidden: true }, !isCollapsed ? hideCollapsedPanelLabel : showCollapsedPanelLabel)));
3617
3613
  var children_2 = tslib.__spreadArray([
3618
3614
  ToggleButton
3619
- ], tslib.__read(React__default["default"].Children.toArray(columnRight.props.children)), false);
3615
+ ], tslib.__read(React__default["default"].Children.toArray(columnRightProps.children)), false);
3620
3616
  ColumnRightComponent = React.cloneElement(columnRight, { ref: ref_2, tabIndex: -1 }, children_2.map(function (child, index) {
3621
3617
  return React.cloneElement(child, {
3622
3618
  key: child.key
@@ -3802,7 +3798,8 @@ var Listbox = React.forwardRef(function (_a, ref) {
3802
3798
  }
3803
3799
  }, [activeOption]);
3804
3800
  React.useEffect(function () {
3805
- if (isActiveControlled && controlledActiveOption !== activeOption) {
3801
+ if (isActiveControlled &&
3802
+ (controlledActiveOption === null || controlledActiveOption === void 0 ? void 0 : controlledActiveOption.element) !== (activeOption === null || activeOption === void 0 ? void 0 : activeOption.element)) {
3806
3803
  setActiveOption(controlledActiveOption || null);
3807
3804
  }
3808
3805
  }, [isActiveControlled, controlledActiveOption]);
@@ -3948,11 +3945,11 @@ function isElementPreceding(a, b) {
3948
3945
  }
3949
3946
  var ListboxOption = React.forwardRef(function (_a, ref) {
3950
3947
  var _b;
3951
- var _c;
3952
- var propId = _a.id, className = _a.className, _d = _a.as, Component = _d === void 0 ? 'li' : _d, children = _a.children, value = _a.value, disabled = _a.disabled, selectedProp = _a.selected, _e = _a.activeClass, activeClass = _e === void 0 ? 'ListboxOption--active' : _e, onClick = _a.onClick, props = tslib.__rest(_a, ["id", "className", "as", "children", "value", "disabled", "selected", "activeClass", "onClick"]);
3953
- var _f = useListboxContext(), active = _f.active, selected = _f.selected, setOptions = _f.setOptions, onSelect = _f.onSelect;
3948
+ var _c, _d;
3949
+ var propId = _a.id, className = _a.className, _e = _a.as, Component = _e === void 0 ? 'li' : _e, children = _a.children, value = _a.value, disabled = _a.disabled, selectedProp = _a.selected, _f = _a.activeClass, activeClass = _f === void 0 ? 'ListboxOption--active' : _f, onClick = _a.onClick, props = tslib.__rest(_a, ["id", "className", "as", "children", "value", "disabled", "selected", "activeClass", "onClick"]);
3950
+ var _g = useListboxContext(), active = _g.active, selected = _g.selected, setOptions = _g.setOptions, onSelect = _g.onSelect;
3954
3951
  var listboxOptionRef = useSharedRef(ref);
3955
- var _g = tslib.__read(propId ? [propId] : nextId.useId(1, 'listbox-option'), 1), id = _g[0];
3952
+ var _h = tslib.__read(propId ? [propId] : nextId.useId(1, 'listbox-option'), 1), id = _h[0];
3956
3953
  var isActive = (active === null || active === void 0 ? void 0 : active.element) === listboxOptionRef.current;
3957
3954
  var isSelected = typeof selectedProp === 'boolean'
3958
3955
  ? selectedProp
@@ -3960,15 +3957,15 @@ var ListboxOption = React.forwardRef(function (_a, ref) {
3960
3957
  !!selected.find(function (option) { return option.element === listboxOptionRef.current; });
3961
3958
  var optionValue = typeof value !== 'undefined'
3962
3959
  ? value
3963
- : (_c = listboxOptionRef.current) === null || _c === void 0 ? void 0 : _c.innerText;
3960
+ : ((_d = (_c = listboxOptionRef.current) === null || _c === void 0 ? void 0 : _c.textContent) !== null && _d !== void 0 ? _d : undefined);
3964
3961
  React.useEffect(function () {
3965
3962
  var element = listboxOptionRef.current;
3966
3963
  setOptions(function (options) {
3967
3964
  var e_1, _a;
3968
- var option = { element: element, value: optionValue };
3969
3965
  // istanbul ignore next
3970
3966
  if (!element)
3971
3967
  return options;
3968
+ var option = { element: element, value: optionValue };
3972
3969
  // Elements are frequently appended, so check to see if the newly rendered
3973
3970
  // element follows the last element first before any other checks
3974
3971
  if (!options.length ||
@@ -4155,7 +4152,7 @@ var ComboboxOption = React.forwardRef(function (_a, ref) {
4155
4152
  // istanbul ignore next
4156
4153
  React.useLayoutEffect(function () {
4157
4154
  var intersectionEntry = intersectionRef.current;
4158
- if (!intersectionEntry || !isActive) {
4155
+ if (!intersectionEntry || !isActive || !comboboxOptionRef.current) {
4159
4156
  return;
4160
4157
  }
4161
4158
  var rect = comboboxOptionRef.current.getBoundingClientRect();
@@ -4171,10 +4168,10 @@ var ComboboxOption = React.forwardRef(function (_a, ref) {
4171
4168
  }
4172
4169
  }, [isActive]);
4173
4170
  React.useEffect(function () {
4174
- var _a;
4171
+ var _a, _b;
4175
4172
  var comboboxValue = typeof propValue !== 'undefined'
4176
4173
  ? propValue
4177
- : (_a = comboboxOptionRef.current) === null || _a === void 0 ? void 0 : _a.innerText;
4174
+ : ((_b = (_a = comboboxOptionRef.current) === null || _a === void 0 ? void 0 : _a.textContent) !== null && _b !== void 0 ? _b : undefined);
4178
4175
  var value = typeof formValue === 'undefined' ? comboboxValue : formValue;
4179
4176
  setFormValues(function (prev) {
4180
4177
  var formValues = prev.filter(function (fv) { return fv !== value; });
@@ -4193,12 +4190,14 @@ var ComboboxOption = React.forwardRef(function (_a, ref) {
4193
4190
  });
4194
4191
  }, [selectedValues, formValue]);
4195
4192
  React.useEffect(function () {
4196
- var _a;
4193
+ var _a, _b;
4197
4194
  if (isMatching) {
4198
4195
  var comboboxValue_1 = typeof propValue !== 'undefined'
4199
4196
  ? propValue
4200
- : (_a = comboboxOptionRef.current) === null || _a === void 0 ? void 0 : _a.innerText;
4197
+ : ((_b = (_a = comboboxOptionRef.current) === null || _a === void 0 ? void 0 : _a.textContent) !== null && _b !== void 0 ? _b : undefined);
4201
4198
  setMatchingOptions(function (options) {
4199
+ if (!comboboxOptionRef.current)
4200
+ return options;
4202
4201
  return new Map(options.set(comboboxOptionRef.current, {
4203
4202
  value: comboboxValue_1,
4204
4203
  displayValue: children,
@@ -4338,6 +4337,17 @@ var Combobox = React.forwardRef(function (_a, ref) {
4338
4337
  return value === lastSelectedValue;
4339
4338
  }) || [], 2), element = _a[0], option = _a[1];
4340
4339
  if (autocomplete === 'manual') {
4340
+ // In multiselect, the listbox manages its own active option via
4341
+ // keyboard navigation. When the last-selected value no longer
4342
+ // matches any option (e.g. after deselecting the only selected
4343
+ // option), preserve the existing active descendant so the next
4344
+ // Enter keypress can re-toggle the highlighted option.
4345
+ if (multiselect &&
4346
+ !element &&
4347
+ activeDescendant &&
4348
+ matchingOptions.has(activeDescendant.element)) {
4349
+ return;
4350
+ }
4341
4351
  setActiveDescendant(!element ? null : tslib.__assign({ element: element }, option));
4342
4352
  }
4343
4353
  else if (autocomplete === 'automatic' &&
@@ -4517,6 +4527,7 @@ var Combobox = React.forwardRef(function (_a, ref) {
4517
4527
  });
4518
4528
  }, [disabled, selectedValues, onSelectionChange]);
4519
4529
  var handlePillKeyDown = React.useCallback(function (event) {
4530
+ var _a, _b;
4520
4531
  if (!PillKeys.includes(event.key)) {
4521
4532
  return;
4522
4533
  }
@@ -4534,7 +4545,7 @@ var Combobox = React.forwardRef(function (_a, ref) {
4534
4545
  handleRemovePill(pillsRef.current[focusedIndex], selectedValues[focusedIndex]);
4535
4546
  var nextIndex = focusedIndex + 1;
4536
4547
  if (nextIndex == pillsLength) {
4537
- inputRef.current.focus();
4548
+ (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
4538
4549
  }
4539
4550
  else {
4540
4551
  pillsRef.current[nextIndex].focus();
@@ -4543,7 +4554,7 @@ var Combobox = React.forwardRef(function (_a, ref) {
4543
4554
  else if (isArrowLeft || isArrowRight) {
4544
4555
  var nextIndex = Math.max(focusedIndex + (isArrowLeft ? -1 : 1), 0);
4545
4556
  if (isArrowRight && nextIndex === pillsLength) {
4546
- inputRef.current.focus();
4557
+ (_b = inputRef.current) === null || _b === void 0 ? void 0 : _b.focus();
4547
4558
  }
4548
4559
  else {
4549
4560
  pillsRef.current[nextIndex].focus();
@@ -4831,10 +4842,12 @@ var TextEllipsis = React__default["default"].forwardRef(function (_a, ref) {
4831
4842
  : overflowElement.clientWidth < overflowElement.scrollWidth);
4832
4843
  });
4833
4844
  };
4845
+ if (!sharedRef.current)
4846
+ return;
4834
4847
  var observer = new ResizeObserver(listener);
4835
4848
  observer.observe(sharedRef.current);
4836
4849
  return function () {
4837
- observer === null || observer === void 0 ? void 0 : observer.disconnect();
4850
+ observer.disconnect();
4838
4851
  };
4839
4852
  }, []);
4840
4853
  React.useEffect(function () {
@@ -4879,7 +4892,7 @@ var Drawer = React.forwardRef(function (_a, ref) {
4879
4892
  openRef.current = open;
4880
4893
  }, [open, setIsTransitioning]);
4881
4894
  React.useEffect(function () {
4882
- if (!isModal) {
4895
+ if (!isModal || !drawerRef.current) {
4883
4896
  return;
4884
4897
  }
4885
4898
  var isolator = new AriaIsolate(drawerRef.current);
@@ -5060,7 +5073,7 @@ function getActiveElement(root) {
5060
5073
  */
5061
5074
  function useMnemonics(_a) {
5062
5075
  var elementOrRef = _a.elementOrRef, matchingElementsSelector = _a.matchingElementsSelector, onMatch = _a.onMatch, _b = _a.enabled, enabled = _b === void 0 ? true : _b;
5063
- var containerRef = React.useRef();
5076
+ var containerRef = React.useRef(null);
5064
5077
  React.useEffect(function () {
5065
5078
  if (elementOrRef instanceof HTMLElement) {
5066
5079
  containerRef.current = elementOrRef;
@@ -5070,7 +5083,8 @@ function useMnemonics(_a) {
5070
5083
  }
5071
5084
  }, [elementOrRef]);
5072
5085
  React.useEffect(function () {
5073
- if (!enabled || !containerRef.current) {
5086
+ var listenerTarget = containerRef.current;
5087
+ if (!enabled || !listenerTarget) {
5074
5088
  return;
5075
5089
  }
5076
5090
  var keyboardHandler = function (event) {
@@ -5083,14 +5097,14 @@ function useMnemonics(_a) {
5083
5097
  if (event.key.length !== 1 || !/[a-z\d]/i.test(event.key)) {
5084
5098
  return;
5085
5099
  }
5086
- var container = containerRef.current;
5087
- if (!container) {
5100
+ var currentContainer = containerRef.current;
5101
+ if (!currentContainer) {
5088
5102
  return;
5089
5103
  }
5090
5104
  // Prevent default behavior and stop propagation for mnemonic keys
5091
5105
  event.preventDefault();
5092
5106
  event.stopPropagation();
5093
- var elements = Array.from(container.querySelectorAll(matchingElementsSelector !== null && matchingElementsSelector !== void 0 ? matchingElementsSelector : focusable__default["default"]));
5107
+ var elements = Array.from(currentContainer.querySelectorAll(matchingElementsSelector !== null && matchingElementsSelector !== void 0 ? matchingElementsSelector : focusable__default["default"]));
5094
5108
  var matchingElements = elements.filter(function (element) {
5095
5109
  return getAccessibleLabel(element).toLowerCase()[0] ===
5096
5110
  event.key.toLowerCase();
@@ -5098,7 +5112,7 @@ function useMnemonics(_a) {
5098
5112
  if (!matchingElements.length) {
5099
5113
  return;
5100
5114
  }
5101
- var currentActiveElement = getActiveElement(containerRef.current);
5115
+ var currentActiveElement = getActiveElement(currentContainer);
5102
5116
  var nextActiveElement = null;
5103
5117
  if (currentActiveElement) {
5104
5118
  nextActiveElement = matchingElements.find(function (element) {
@@ -5112,17 +5126,15 @@ function useMnemonics(_a) {
5112
5126
  onMatch(nextActiveElement !== null && nextActiveElement !== void 0 ? nextActiveElement : matchingElements[0]);
5113
5127
  }
5114
5128
  };
5115
- var container = containerRef.current;
5116
- container.addEventListener('keydown', keyboardHandler);
5117
- return function () { return container.removeEventListener('keydown', keyboardHandler); };
5129
+ listenerTarget.addEventListener('keydown', keyboardHandler);
5130
+ return function () { return listenerTarget.removeEventListener('keydown', keyboardHandler); };
5118
5131
  }, [enabled, containerRef, matchingElementsSelector, onMatch]);
5119
5132
  return containerRef;
5120
5133
  }
5121
5134
 
5122
5135
  var ActionList = React.forwardRef(function (_a, ref) {
5123
5136
  var _b = _a.selectionType, selectionType = _b === void 0 ? null : _b, onAction = _a.onAction, className = _a.className, children = _a.children, props = tslib.__rest(_a, ["selectionType", "onAction", "className", "children"]);
5124
- var actionListContext = useActionListContext();
5125
- var activeElement = React.useRef();
5137
+ var activeElement = React.useRef(null);
5126
5138
  var _c = tslib.__read(React.useState(), 2), activeOption = _c[0], setActiveOption = _c[1];
5127
5139
  var handleActiveChange = React.useCallback(function (value) {
5128
5140
  activeElement.current = value === null || value === void 0 ? void 0 : value.element;
@@ -5133,22 +5145,18 @@ var ActionList = React.forwardRef(function (_a, ref) {
5133
5145
  onAction(key, event);
5134
5146
  }
5135
5147
  }, [onAction]);
5148
+ var handleMnemonicMatch = React.useCallback(function (element) {
5149
+ setActiveOption(function (prev) {
5150
+ return (prev === null || prev === void 0 ? void 0 : prev.element) === element ? prev : { element: element };
5151
+ });
5152
+ }, []);
5136
5153
  var containerRef = useMnemonics({
5137
- onMatch: function (element) {
5138
- setActiveOption({
5139
- element: element
5140
- });
5141
- },
5154
+ onMatch: handleMnemonicMatch,
5142
5155
  matchingElementsSelector: props.role === 'menu'
5143
5156
  ? '[role=menuitem],[role=menuitemcheckbox],[role=menuitemradio]'
5144
5157
  : '[role=option]'
5145
5158
  });
5146
- return (
5147
- // Note: we should be able to use listbox without passing a prop
5148
- // value for "multiselect"
5149
- // see: https://github.com/dequelabs/cauldron/issues/1890
5150
- // @ts-expect-error this should be allowed
5151
- React__default["default"].createElement(Listbox, tslib.__assign({ ref: function (element) {
5159
+ return (React__default["default"].createElement(Listbox, tslib.__assign({ ref: function (element) {
5152
5160
  if (ref) {
5153
5161
  setRef(ref, element);
5154
5162
  }
@@ -5157,7 +5165,7 @@ var ActionList = React.forwardRef(function (_a, ref) {
5157
5165
  /* Listbox comes with an explicit role of "listbox", but we want to either
5158
5166
  * use the role from props, or default to the intrinsic role */
5159
5167
  // eslint-disable-next-line jsx-a11y/aria-role
5160
- role: undefined, "aria-multiselectable": actionListContext.role === 'listbox' ? undefined : null, className: classNames__default["default"]('ActionList', className), activeOption: activeOption }, props, { onActiveChange: handleActiveChange, navigation: "bound" }),
5168
+ role: undefined, "aria-multiselectable": undefined, className: classNames__default["default"]('ActionList', className), activeOption: activeOption }, props, { onActiveChange: handleActiveChange, navigation: "bound" }),
5161
5169
  React__default["default"].createElement(ActionListProvider, { role: props.role || 'list', onAction: handleAction, selectionType: selectionType }, children)));
5162
5170
  });
5163
5171
  ActionList.displayName = 'ActionList';
@@ -5175,7 +5183,7 @@ var ActionListItem = React.forwardRef(function (_a, ref) {
5175
5183
  });
5176
5184
  var isActive = !!(active === null || active === void 0 ? void 0 : active.element) && active.element === actionListItemRef.current;
5177
5185
  var handleAction = React.useCallback(function (event) {
5178
- var _a;
5186
+ var _a, _b;
5179
5187
  if (event.defaultPrevented) {
5180
5188
  return;
5181
5189
  }
@@ -5188,7 +5196,7 @@ var ActionListItem = React.forwardRef(function (_a, ref) {
5188
5196
  }
5189
5197
  // istanbul ignore else
5190
5198
  if (typeof onActionListAction === 'function') {
5191
- onActionListAction(actionKey || ((_a = labelRef === null || labelRef === void 0 ? void 0 : labelRef.current) === null || _a === void 0 ? void 0 : _a.innerText.trim()) || '', event);
5199
+ onActionListAction(actionKey || ((_b = (_a = labelRef.current) === null || _a === void 0 ? void 0 : _a.textContent) === null || _b === void 0 ? void 0 : _b.trim()) || '', event);
5192
5200
  }
5193
5201
  }, [onAction, onActionListAction, selectionType, actionKey]);
5194
5202
  var listItemRole = undefined;
@@ -5212,7 +5220,7 @@ var ActionListItem = React.forwardRef(function (_a, ref) {
5212
5220
  // istanbul ignore next
5213
5221
  React.useLayoutEffect(function () {
5214
5222
  var intersectionEntry = intersectionRef.current;
5215
- if (!intersectionEntry || !isActive) {
5223
+ if (!intersectionEntry || !isActive || !actionListItemRef.current) {
5216
5224
  return;
5217
5225
  }
5218
5226
  var rect = actionListItemRef.current.getBoundingClientRect();
@@ -5311,9 +5319,10 @@ var ActionMenu = React.forwardRef(function (_a, ref) {
5311
5319
  var _e = tslib.__read(React.useState('first'), 2), focusStrategy = _e[0], setFocusStrategy = _e[1];
5312
5320
  var triggerRef = React.useRef(null);
5313
5321
  var actionMenuRef = useSharedRef(ref);
5314
- var actionMenuListRef = useSharedRef(actionMenuList.props.ref);
5315
- var _f = tslib.__read(nextId.useId(1, 'menu-trigger'), 1), triggerId = _f[0];
5316
- var _g = tslib.__read(nextId.useId(1, 'menu'), 1), menuId = _g[0];
5322
+ var _f = actionMenuList.props, actionListRef = _f.ref, actionListOnAction = _f.onAction;
5323
+ var actionMenuListRef = useSharedRef(actionListRef !== null && actionListRef !== void 0 ? actionListRef : null);
5324
+ var _g = tslib.__read(nextId.useId(1, 'menu-trigger'), 1), triggerId = _g[0];
5325
+ var _h = tslib.__read(nextId.useId(1, 'menu'), 1), menuId = _h[0];
5317
5326
  var handleTriggerClick = React.useCallback(function (event) {
5318
5327
  // istanbul ignore else
5319
5328
  if (!event.defaultPrevented) {
@@ -5360,11 +5369,10 @@ var ActionMenu = React.forwardRef(function (_a, ref) {
5360
5369
  if (!event.defaultPrevented) {
5361
5370
  setOpen(false);
5362
5371
  }
5363
- var onAction = actionMenuList.props.onAction;
5364
- if (typeof onAction === 'function') {
5365
- onAction(key, event);
5372
+ if (typeof actionListOnAction === 'function') {
5373
+ actionListOnAction(key, event);
5366
5374
  }
5367
- }, [actionMenuList.props.onAction]);
5375
+ }, [actionListOnAction]);
5368
5376
  React.useEffect(function () {
5369
5377
  var _a, _b;
5370
5378
  if (open) {
@@ -5425,6 +5433,189 @@ var ActionMenu = React.forwardRef(function (_a, ref) {
5425
5433
  });
5426
5434
  ActionMenu.displayName = 'ActionMenu';
5427
5435
 
5436
+ var TreeViewItem = function (_a) {
5437
+ var id = _a.id, textValue = _a.textValue, children = _a.children;
5438
+ var checkboxId = React.useMemo(function () { return nextId__default["default"]('tree-view-item-'); }, []);
5439
+ return (React__default["default"].createElement(reactAriaComponents.TreeItem, { id: id, textValue: textValue, className: "TreeView__item" },
5440
+ React__default["default"].createElement(reactAriaComponents.TreeItemContent, null, function (_a) {
5441
+ var selectionMode = _a.selectionMode, isSelected = _a.isSelected, isDisabled = _a.isDisabled;
5442
+ return (React__default["default"].createElement(React__default["default"].Fragment, null,
5443
+ React__default["default"].createElement(reactAriaComponents.Button, { slot: "chevron", className: "TreeView__chevron" },
5444
+ React__default["default"].createElement(Icon, { type: "chevron-right" })),
5445
+ selectionMode !== 'none' ? (React__default["default"].createElement(Checkbox, { id: checkboxId, label: textValue, checked: isSelected, disabled: isDisabled, controlled: true, tabIndex: -1 })) : (React__default["default"].createElement(React__default["default"].Fragment, null, textValue))));
5446
+ }),
5447
+ children && children.length > 0 && (React__default["default"].createElement(reactAriaComponents.Collection, null, children.map(function (child) { return (React__default["default"].createElement(TreeViewItem, tslib.__assign({ key: child.id }, child))); })))));
5448
+ };
5449
+ TreeViewItem.displayName = 'TreeViewItem';
5450
+
5451
+ /** Every node id in the tree, flattened depth-first. */
5452
+ function collectAllKeys(nodes) {
5453
+ return nodes.flatMap(function (node) { return tslib.__spreadArray([
5454
+ node.id
5455
+ ], tslib.__read((node.children ? collectAllKeys(node.children) : [])), false); });
5456
+ }
5457
+ /** Normalize react-aria's `Selection` ("all" | Set) into a concrete Set of keys. */
5458
+ function toKeySet(selection, nodes) {
5459
+ if (selection !== 'all') {
5460
+ return new Set(selection);
5461
+ }
5462
+ // "Select all" only includes selectable (non-disabled) nodes.
5463
+ var disabled = new Set(collectDisabledKeys(nodes));
5464
+ return new Set(collectAllKeys(nodes).filter(function (key) { return !disabled.has(key); }));
5465
+ }
5466
+ /** Locate a node anywhere in the tree by its id. */
5467
+ function findNode(nodes, key) {
5468
+ var e_1, _a;
5469
+ try {
5470
+ for (var nodes_1 = tslib.__values(nodes), nodes_1_1 = nodes_1.next(); !nodes_1_1.done; nodes_1_1 = nodes_1.next()) {
5471
+ var node = nodes_1_1.value;
5472
+ if (node.id === key) {
5473
+ return node;
5474
+ }
5475
+ if (node.children) {
5476
+ var found = findNode(node.children, key);
5477
+ if (found) {
5478
+ return found;
5479
+ }
5480
+ }
5481
+ }
5482
+ }
5483
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
5484
+ finally {
5485
+ try {
5486
+ if (nodes_1_1 && !nodes_1_1.done && (_a = nodes_1.return)) _a.call(nodes_1);
5487
+ }
5488
+ finally { if (e_1) throw e_1.error; }
5489
+ }
5490
+ return undefined;
5491
+ }
5492
+ /** All descendant ids of a node (not including the node itself). */
5493
+ function collectDescendantKeys(node) {
5494
+ if (!node.children) {
5495
+ return [];
5496
+ }
5497
+ return node.children.flatMap(function (child) { return tslib.__spreadArray([
5498
+ child.id
5499
+ ], tslib.__read(collectDescendantKeys(child)), false); });
5500
+ }
5501
+ /** Ids of all disabled nodes (rendered disabled / non-selectable). */
5502
+ function collectDisabledKeys(nodes) {
5503
+ return nodes.flatMap(function (node) { return tslib.__spreadArray(tslib.__spreadArray([], tslib.__read((node.disabled ? [node.id] : [])), false), tslib.__read((node.children ? collectDisabledKeys(node.children) : [])), false); });
5504
+ }
5505
+ /**
5506
+ * Toggle a single node, applying cascade per the options (multiple mode only):
5507
+ * - selecting + `cascadeSelect`: also selects all (non-disabled) descendants.
5508
+ * - deselecting + `cascadeDeselect`: also deselects all descendants.
5509
+ *
5510
+ * In `single` mode only the clicked node is selected (clicking it again clears
5511
+ * it); cascade does not apply.
5512
+ */
5513
+ function toggleSelection(nodes, previous, key, selectionMode, _a) {
5514
+ var cascadeSelect = _a.cascadeSelect, cascadeDeselect = _a.cascadeDeselect;
5515
+ if (selectionMode === 'single') {
5516
+ var result_1 = new Set();
5517
+ if (!previous.has(key)) {
5518
+ result_1.add(key);
5519
+ }
5520
+ return result_1;
5521
+ }
5522
+ var result = new Set(previous);
5523
+ var node = findNode(nodes, key);
5524
+ var descendants = node ? collectDescendantKeys(node) : [];
5525
+ var disabled = new Set(collectDisabledKeys(nodes));
5526
+ if (!previous.has(key)) {
5527
+ result.add(key);
5528
+ if (cascadeSelect) {
5529
+ descendants.forEach(function (k) {
5530
+ if (!disabled.has(k)) {
5531
+ result.add(k);
5532
+ }
5533
+ });
5534
+ }
5535
+ }
5536
+ else {
5537
+ result.delete(key);
5538
+ if (cascadeDeselect) {
5539
+ descendants.forEach(function (k) { return result.delete(k); });
5540
+ }
5541
+ }
5542
+ return result;
5543
+ }
5544
+ /**
5545
+ * Apply react-aria's proposed selection while enforcing cascade. Each key
5546
+ * react-aria added cascades to its descendants when `cascadeSelect` is set; each
5547
+ * key it removed cascades when `cascadeDeselect` is set. In non-multiple modes
5548
+ * (or with both toggles off) the proposed selection is used as-is.
5549
+ */
5550
+ function applyCascade(nodes, previous, next, selectionMode, _a) {
5551
+ var cascadeSelect = _a.cascadeSelect, cascadeDeselect = _a.cascadeDeselect;
5552
+ if (selectionMode !== 'multiple' || (!cascadeSelect && !cascadeDeselect)) {
5553
+ return next;
5554
+ }
5555
+ var result = new Set(previous);
5556
+ var added = tslib.__spreadArray([], tslib.__read(next), false).filter(function (key) { return !previous.has(key); });
5557
+ var removed = tslib.__spreadArray([], tslib.__read(previous), false).filter(function (key) { return !next.has(key); });
5558
+ var disabled = new Set(collectDisabledKeys(nodes));
5559
+ added.forEach(function (key) {
5560
+ result.add(key);
5561
+ if (cascadeSelect) {
5562
+ var node = findNode(nodes, key);
5563
+ (node ? collectDescendantKeys(node) : []).forEach(function (k) {
5564
+ if (!disabled.has(k)) {
5565
+ result.add(k);
5566
+ }
5567
+ });
5568
+ }
5569
+ });
5570
+ removed.forEach(function (key) {
5571
+ result.delete(key);
5572
+ if (cascadeDeselect) {
5573
+ var node = findNode(nodes, key);
5574
+ (node ? collectDescendantKeys(node) : []).forEach(function (k) {
5575
+ return result.delete(k);
5576
+ });
5577
+ }
5578
+ });
5579
+ return result;
5580
+ }
5581
+
5582
+ var TreeView = React.forwardRef(function (_a, ref) {
5583
+ var items = _a.items, onAction = _a.onAction, _b = _a.selectionMode, selectionMode = _b === void 0 ? 'none' : _b, _c = _a.cascadeSelect, cascadeSelect = _c === void 0 ? false : _c, _d = _a.cascadeDeselect, cascadeDeselect = _d === void 0 ? false : _d, defaultExpandedKeys = _a.defaultExpandedKeys, className = _a.className, other = tslib.__rest(_a, ["items", "onAction", "selectionMode", "cascadeSelect", "cascadeDeselect", "defaultExpandedKeys", "className"]);
5584
+ var _e = tslib.__read(React.useState(new Set()), 2), selectedKeys = _e[0], setSelectedKeys = _e[1];
5585
+ var cascade = { cascadeSelect: cascadeSelect, cascadeDeselect: cascadeDeselect };
5586
+ // Cascade only applies to multiple selection.
5587
+ var isCascade = selectionMode === 'multiple' && (cascadeSelect || cascadeDeselect);
5588
+ // Selection driven by react-aria (row/checkbox press, keyboard). When
5589
+ // cascading, reconcile the proposed change; otherwise store react-aria's
5590
+ // selection as-is so the `'all'` sentinel (Ctrl+A) is preserved.
5591
+ var handleSelectionChange = function (selection) {
5592
+ setSelectedKeys(function (prev) {
5593
+ return isCascade
5594
+ ? applyCascade(items, toKeySet(prev, items), toKeySet(selection, items), selectionMode, cascade)
5595
+ : selection;
5596
+ });
5597
+ };
5598
+ // When `onAction` is set, react-aria treats a row press as an action rather
5599
+ // than a selection, so we toggle selection here ourselves.
5600
+ var handleAction = function (key) {
5601
+ if (selectionMode !== 'none') {
5602
+ setSelectedKeys(function (prev) {
5603
+ return toggleSelection(items, toKeySet(prev, items), key, selectionMode, cascade);
5604
+ });
5605
+ }
5606
+ onAction === null || onAction === void 0 ? void 0 : onAction(key);
5607
+ };
5608
+ // Disabled nodes are non-selectable; react-aria disables them via disabledKeys.
5609
+ var disabledKeys = React.useMemo(function () { return collectDisabledKeys(items); }, [items]);
5610
+ // Cascade requires controlling selection. Without it, preserve the original
5611
+ // behavior: selection is only controlled when an `onAction` handler is set.
5612
+ var selectionProps = selectionMode !== 'none' && (isCascade || onAction)
5613
+ ? { selectedKeys: selectedKeys, onSelectionChange: handleSelectionChange }
5614
+ : {};
5615
+ return (React__default["default"].createElement(reactAriaComponents.Tree, tslib.__assign({ ref: ref, className: classNames__default["default"]('TreeView', className), selectionMode: selectionMode, defaultExpandedKeys: defaultExpandedKeys }, (disabledKeys.length > 0 ? { disabledKeys: disabledKeys } : {}), (onAction ? { onAction: handleAction } : {}), selectionProps, other), items.map(function (item) { return (React__default["default"].createElement(TreeViewItem, tslib.__assign({ key: item.id }, item))); })));
5616
+ });
5617
+ TreeView.displayName = 'TreeView';
5618
+
5428
5619
  var LIGHT_THEME_CLASS = 'cauldron--theme-light';
5429
5620
  var DARK_THEME_CLASS = 'cauldron--theme-dark';
5430
5621
  var ThemeContext = React.createContext({
@@ -5620,6 +5811,7 @@ exports.TopBar = TopBar;
5620
5811
  exports.TopBarItem = MenuItem;
5621
5812
  exports.TopBarMenu = TopBarMenu;
5622
5813
  exports.TopBarTrigger = TopBarTrigger;
5814
+ exports.TreeView = TreeView;
5623
5815
  exports.TwoColumnPanel = TwoColumnPanel;
5624
5816
  exports.Workspace = Workspace;
5625
5817
  exports.focusableSelector = focusableSelector;