@deque/cauldron-react 7.0.0 → 7.1.0-canary.062b0906

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