@deque/cauldron-react 6.27.0 → 7.0.0-canary.0a6fafe6

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.
@@ -1,8 +1,17 @@
1
1
  import React, { type ButtonHTMLAttributes, type Ref } from 'react';
2
- export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
2
+ import type { TagSize } from '../Tag';
3
+ interface ButtonBaseProps extends ButtonHTMLAttributes<HTMLButtonElement> {
3
4
  buttonRef?: Ref<HTMLButtonElement>;
4
- variant?: 'primary' | 'secondary' | 'tertiary' | 'error' | 'danger' | 'danger-secondary' | 'link' | 'tag' | 'badge';
5
5
  thin?: boolean;
6
6
  }
7
+ interface ButtonTagProps extends ButtonBaseProps {
8
+ variant: 'tag';
9
+ size?: TagSize;
10
+ }
11
+ interface ButtonNonTagProps extends ButtonBaseProps {
12
+ variant?: 'primary' | 'secondary' | 'tertiary' | 'error' | 'danger' | 'danger-secondary' | 'link' | 'badge';
13
+ size?: never;
14
+ }
15
+ export type ButtonProps = ButtonTagProps | ButtonNonTagProps;
7
16
  declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>;
8
17
  export default Button;
@@ -7,6 +7,8 @@ export interface CheckboxProps extends InputHTMLAttributes<HTMLInputElement> {
7
7
  customIcon?: React.ReactNode;
8
8
  checkboxRef?: React.ForwardedRef<HTMLInputElement>;
9
9
  indeterminate?: boolean;
10
+ /** When true, the component does not manage its own checked state — it renders what you pass via `checked` and reports interactions through `onChange`. Use when state is managed by a parent component. */
11
+ controlled?: boolean;
10
12
  }
11
13
  declare const Checkbox: React.ForwardRefExoticComponent<CheckboxProps & React.RefAttributes<HTMLInputElement>>;
12
14
  export default Checkbox;
@@ -3,7 +3,7 @@ import { ContentNode } from '../../types';
3
3
  import Button from '../Button';
4
4
  import Tooltip from '../Tooltip';
5
5
  type ButtonProps = React.ComponentProps<typeof Button>;
6
- export interface CopyButtonProps extends Omit<ButtonProps, 'onCopy' | 'onClick'> {
6
+ export interface CopyButtonProps extends Omit<ButtonProps, 'onCopy' | 'onClick' | 'size'> {
7
7
  value: string;
8
8
  variant?: Extract<ButtonProps['variant'], 'primary' | 'secondary' | 'tertiary'>;
9
9
  children?: ContentNode;
@@ -6,6 +6,7 @@ interface DialogContextValue {
6
6
  onClose: () => void;
7
7
  forceAction: boolean;
8
8
  closeButtonText: string;
9
+ scrollable: boolean;
9
10
  }
10
11
  declare const DialogContext: React.Context<DialogContextValue | null>;
11
12
  declare function useDialogContext(): DialogContextValue;
@@ -12,6 +12,7 @@ export interface DialogProps extends React.HTMLAttributes<HTMLDivElement> {
12
12
  };
13
13
  closeButtonText?: string;
14
14
  portal?: React.RefObject<HTMLElement> | HTMLElement;
15
+ scrollable?: boolean;
15
16
  }
16
17
  declare const Dialog: React.ForwardRefExoticComponent<DialogProps & React.RefAttributes<HTMLDivElement>>;
17
18
  export default Dialog;
@@ -7,18 +7,6 @@ export interface IconButtonProps extends PolymorphicProps<React.HTMLAttributes<H
7
7
  label: React.ReactNode;
8
8
  tooltipProps?: Omit<TooltipProps, 'children' | 'target'>;
9
9
  disabled?: boolean;
10
- /**
11
- * @deprecated use `tooltipProps.placement` instead
12
- */
13
- tooltipPlacement?: TooltipProps['placement'];
14
- /**
15
- * @deprecated use `tooltipProps.variant` instead
16
- */
17
- tooltipVariant?: TooltipProps['variant'];
18
- /**
19
- * @deprecated use `tooltipProps.portal` instead
20
- */
21
- tooltipPortal?: TooltipProps['portal'];
22
10
  variant?: 'primary' | 'secondary' | 'tertiary' | 'error';
23
11
  large?: boolean;
24
12
  }
@@ -2,8 +2,9 @@ import React from 'react';
2
2
  import { DialogProps } from '../Dialog';
3
3
  interface ModalProps extends Omit<DialogProps, 'forceAction'> {
4
4
  variant?: 'info';
5
+ scrollable?: boolean;
5
6
  }
6
- declare const Modal: ({ children, className, variant, ...other }: ModalProps) => React.JSX.Element;
7
+ declare const Modal: ({ children, className, variant, scrollable, ...other }: ModalProps) => React.JSX.Element;
7
8
  declare const ModalHeader: {
8
9
  ({ children, className, ...other }: import("../Dialog").DialogHeaderProps): React.JSX.Element;
9
10
  displayName: string;
@@ -4,7 +4,9 @@ type SortDirection = 'ascending' | 'descending' | 'none';
4
4
  interface TableHeaderProps extends Omit<React.ThHTMLAttributes<HTMLTableHeaderCellElement>, 'align'> {
5
5
  sortDirection?: SortDirection;
6
6
  onSort?: () => void;
7
+ /** @deprecated No longer used. Sort state is communicated via aria-sort. */
7
8
  sortAscendingAnnouncement?: string;
9
+ /** @deprecated No longer used. Sort state is communicated via aria-sort. */
8
10
  sortDescendingAnnouncement?: string;
9
11
  align?: ColumnAlignment;
10
12
  variant?: 'header' | 'cell';
@@ -1,8 +1,9 @@
1
1
  import React from 'react';
2
+ export type TagSize = 'default' | 'small';
2
3
  interface TagProps {
3
4
  children: React.ReactNode;
4
5
  className?: string;
5
- size?: 'default' | 'small';
6
+ size?: TagSize;
6
7
  }
7
8
  export declare const TagLabel: {
8
9
  ({ children, className, ...other }: TagProps): React.JSX.Element;
@@ -1,11 +1,13 @@
1
- import React from 'react';
1
+ import React, { type ButtonHTMLAttributes } from 'react';
2
2
  import { IconType } from '../Icon';
3
3
  import { ContentNode } from '../../types';
4
- interface TagButtonProps extends React.HTMLAttributes<HTMLButtonElement> {
4
+ import { type TagSize } from '../Tag';
5
+ interface TagButtonProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'value'> {
5
6
  label: ContentNode;
6
7
  value: ContentNode;
7
8
  icon: IconType;
8
9
  onClick: (e: React.MouseEvent<HTMLButtonElement>) => void;
10
+ size?: TagSize;
9
11
  }
10
12
  declare const TagButton: React.ForwardRefExoticComponent<TagButtonProps & React.RefAttributes<HTMLButtonElement>>;
11
13
  export default TagButton;
@@ -1,39 +1,19 @@
1
1
  import React from 'react';
2
- import AriaIsolate from '../../utils/aria-isolate';
3
2
  export interface ToastProps extends React.HTMLAttributes<HTMLDivElement> {
4
3
  type: 'confirmation' | 'caution' | 'error' | 'action-needed' | 'info';
5
- onDismiss: () => void;
4
+ onDismiss?: () => void;
6
5
  dismissText?: string;
7
- toastRef: React.Ref<HTMLDivElement>;
6
+ toastRef?: React.Ref<HTMLDivElement>;
8
7
  focus?: boolean;
9
8
  show?: boolean;
10
9
  dismissible?: boolean;
11
10
  children: React.ReactNode;
12
11
  }
13
- interface ToastState {
14
- animationClass: string;
15
- isolator?: AriaIsolate;
16
- }
17
12
  /**
18
13
  * The cauldron toast notification component
19
14
  */
20
- export default class Toast extends React.Component<ToastProps, ToastState> {
21
- static defaultProps: {
22
- dismissText: string;
23
- onDismiss: () => void;
24
- toastRef: () => void;
25
- focus: boolean;
26
- show: boolean;
27
- dismissible: boolean;
28
- };
29
- static displayName: string;
30
- private el;
31
- constructor(props: ToastProps);
32
- componentDidMount(): void;
33
- componentDidUpdate(prevProps: ToastProps): void;
34
- componentWillUnmount(): void;
35
- render(): React.JSX.Element;
36
- dismissToast(): void;
37
- showToast(): void;
38
- }
39
- export {};
15
+ declare const Toast: {
16
+ ({ type, children, onDismiss, dismissText, toastRef, focus, show, dismissible, className, ...otherProps }: ToastProps): React.JSX.Element;
17
+ displayName: string;
18
+ };
19
+ export default Toast;
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ import { TreeViewNode } from './types';
3
+ declare const TreeViewItem: {
4
+ ({ id, textValue, children }: TreeViewNode): React.JSX.Element;
5
+ displayName: string;
6
+ };
7
+ export default TreeViewItem;
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+ import { Cauldron } from '../../types';
3
+ import { TreeViewNode } from './types';
4
+ export type { TreeViewNode } from './types';
5
+ type TreeViewProps = Cauldron.LabelProps & {
6
+ items: TreeViewNode[];
7
+ onAction?: (key: string) => void;
8
+ selectionMode?: 'none' | 'single' | 'multiple';
9
+ defaultExpandedKeys?: string[];
10
+ className?: string;
11
+ };
12
+ declare const TreeView: React.ForwardRefExoticComponent<TreeViewProps & React.RefAttributes<HTMLDivElement>>;
13
+ export default TreeView;
@@ -0,0 +1,5 @@
1
+ export interface TreeViewNode {
2
+ id: string;
3
+ textValue: string;
4
+ children?: TreeViewNode[];
5
+ }
package/lib/index.d.ts CHANGED
@@ -37,7 +37,7 @@ export { default as Sidebar, SideBarItem } from './components/SideBar';
37
37
  export { default as Code } from './components/Code';
38
38
  export { default as LoaderOverlay } from './components/LoaderOverlay';
39
39
  export { default as Line } from './components/Line';
40
- export { default as Tag, TagLabel } from './components/Tag';
40
+ export { default as Tag, TagLabel, type TagSize } from './components/Tag';
41
41
  export { default as Badge, BadgeLabel } from './components/Badge';
42
42
  export { default as ImpactBadge } from './components/ImpactBadge';
43
43
  export { default as TagButton } from './components/TagButton';
@@ -68,6 +68,7 @@ export { default as SectionHeader } from './components/SectionHeader';
68
68
  export { default as EmptyState } from './components/EmptyState';
69
69
  export { ActionList, ActionListItem, ActionListGroup, ActionListSeparator, ActionListLinkItem } from './components/ActionList';
70
70
  export { ActionMenu } from './components/ActionMenu';
71
+ export { default as TreeView, type TreeViewNode } from './components/TreeView';
71
72
  /**
72
73
  * Helpers / Utils
73
74
  */
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
 
@@ -1357,6 +1358,7 @@ function useSharedRef(ref) {
1357
1358
  var internalRef = React.useRef();
1358
1359
  React.useEffect(function () {
1359
1360
  setRef(ref, internalRef.current);
1361
+ return function () { return setRef(ref, null); };
1360
1362
  }, [ref]);
1361
1363
  return internalRef;
1362
1364
  }
@@ -1532,9 +1534,9 @@ var isEscape = function (event) {
1532
1534
  return event.key === 'Escape' || event.key === 'Esc' || event.keyCode === 27;
1533
1535
  };
1534
1536
  var Dialog = React.forwardRef(function (_a, ref) {
1535
- var dialogRefProp = _a.dialogRef, _b = _a.forceAction, forceAction = _b === void 0 ? false : _b, className = _a.className, children = _a.children, _c = _a.closeButtonText, closeButtonText = _c === void 0 ? 'Close' : _c, heading = _a.heading, _d = _a.show, show = _d === void 0 ? false : _d, portal = _a.portal, _e = _a.onClose, onClose = _e === void 0 ? function () { return null; } : _e, other = tslib.__rest(_a, ["dialogRef", "forceAction", "className", "children", "closeButtonText", "heading", "show", "portal", "onClose"]);
1537
+ var dialogRefProp = _a.dialogRef, _b = _a.forceAction, forceAction = _b === void 0 ? false : _b, className = _a.className, children = _a.children, _c = _a.closeButtonText, closeButtonText = _c === void 0 ? 'Close' : _c, heading = _a.heading, _d = _a.show, show = _d === void 0 ? false : _d, portal = _a.portal, _e = _a.scrollable, scrollable = _e === void 0 ? false : _e, _f = _a.onClose, onClose = _f === void 0 ? function () { return null; } : _f, other = tslib.__rest(_a, ["dialogRef", "forceAction", "className", "children", "closeButtonText", "heading", "show", "portal", "scrollable", "onClose"]);
1536
1538
  var dialogRef = useSharedRef(dialogRefProp || ref);
1537
- var _f = tslib.__read(nextId.useId(1, 'dialog-title-'), 1), headingId = _f[0];
1539
+ var _g = tslib.__read(nextId.useId(1, 'dialog-title-'), 1), headingId = _g[0];
1538
1540
  var headingRef = React.useRef(null);
1539
1541
  var isolatorRef = React.useRef();
1540
1542
  var headingLevel = typeof heading === 'object' && 'level' in heading && heading.level
@@ -1605,14 +1607,16 @@ var Dialog = React.forwardRef(function (_a, ref) {
1605
1607
  headingLevel: headingLevel,
1606
1608
  onClose: handleClose,
1607
1609
  forceAction: forceAction,
1608
- closeButtonText: closeButtonText
1610
+ closeButtonText: closeButtonText,
1611
+ scrollable: scrollable
1609
1612
  }); }, [
1610
1613
  headingId,
1611
1614
  headingRef,
1612
1615
  headingLevel,
1613
1616
  handleClose,
1614
1617
  forceAction,
1615
- closeButtonText
1618
+ closeButtonText,
1619
+ scrollable
1616
1620
  ]);
1617
1621
  if (!show || !isBrowser()) {
1618
1622
  return null;
@@ -1642,11 +1646,12 @@ var Dialog = React.forwardRef(function (_a, ref) {
1642
1646
  Dialog.displayName = 'Dialog';
1643
1647
  var DialogContent = function (_a) {
1644
1648
  var children = _a.children, className = _a.className, align = _a.align, other = tslib.__rest(_a, ["children", "className", "align"]);
1649
+ var context = React.useContext(DialogContext);
1645
1650
  return (React__default["default"].createElement("div", tslib.__assign({ className: classNames__default["default"]('Dialog__content', className, {
1646
1651
  'text--align-left': align === 'left',
1647
1652
  'text--align-center': align === 'center',
1648
1653
  'text--align-right': align === 'right'
1649
- }) }, other), children));
1654
+ }), tabIndex: (context === null || context === void 0 ? void 0 : context.scrollable) ? -1 : undefined }, other), children));
1650
1655
  };
1651
1656
  DialogContent.displayName = 'DialogContent';
1652
1657
  var DialogFooter = function (_a) {
@@ -1700,10 +1705,11 @@ var AlertContent = DialogContent;
1700
1705
  var AlertActions = DialogFooter;
1701
1706
 
1702
1707
  var Modal = function (_a) {
1703
- var children = _a.children, className = _a.className, variant = _a.variant, other = tslib.__rest(_a, ["children", "className", "variant"]);
1708
+ var children = _a.children, className = _a.className, variant = _a.variant, scrollable = _a.scrollable, other = tslib.__rest(_a, ["children", "className", "variant", "scrollable"]);
1704
1709
  return (React__default["default"].createElement(Dialog, tslib.__assign({ className: classNames__default["default"]('Modal', className, {
1705
- 'Modal--info': variant === 'info'
1706
- }) }, other, { forceAction: false }), children));
1710
+ 'Modal--info': variant === 'info',
1711
+ 'Modal--scrollable': scrollable
1712
+ }) }, other, { scrollable: scrollable, forceAction: false }), children));
1707
1713
  };
1708
1714
  var ModalHeader = DialogHeader;
1709
1715
  var ModalHeading = DialogHeading;
@@ -1768,7 +1774,7 @@ var SkipLink = /** @class */ (function (_super) {
1768
1774
  }(React__default["default"].Component));
1769
1775
 
1770
1776
  var Button = React.forwardRef(function (_a, ref) {
1771
- var _b = _a.variant, variant = _b === void 0 ? 'primary' : _b, thin = _a.thin, children = _a.children, className = _a.className, buttonRef = _a.buttonRef, other = tslib.__rest(_a, ["variant", "thin", "children", "className", "buttonRef"]);
1777
+ var _b = _a.variant, variant = _b === void 0 ? 'primary' : _b, thin = _a.thin, size = _a.size, children = _a.children, className = _a.className, buttonRef = _a.buttonRef, other = tslib.__rest(_a, ["variant", "thin", "size", "children", "className", "buttonRef"]);
1772
1778
  return (React__default["default"].createElement("button", tslib.__assign({ type: "button", className: classNames__default["default"](className, {
1773
1779
  'Button--primary': variant === 'primary',
1774
1780
  'Button--secondary': variant === 'secondary',
@@ -1779,6 +1785,7 @@ var Button = React.forwardRef(function (_a, ref) {
1779
1785
  Link: variant === 'link',
1780
1786
  Tag: variant === 'tag',
1781
1787
  'Button--tag': variant === 'tag',
1788
+ 'Tag--small': variant === 'tag' && size === 'small',
1782
1789
  'Button--thin': thin,
1783
1790
  'Button--badge': variant === 'badge'
1784
1791
  }), ref: ref || buttonRef }, other), children));
@@ -2028,10 +2035,17 @@ function Tooltip(_a) {
2028
2035
  fireCustomEvent(false, targetElement);
2029
2036
  }, TIP_HIDE_DELAY);
2030
2037
  }
2038
+ }, [target]);
2039
+ // Cancel any pending hide timeout when the Tooltip unmounts so it
2040
+ // does not fire setShowTooltip on an unmounted component.
2041
+ React.useEffect(function () {
2031
2042
  return function () {
2032
- clearTimeout(hideTimeoutRef.current);
2043
+ if (hideTimeoutRef.current) {
2044
+ clearTimeout(hideTimeoutRef.current);
2045
+ hideTimeoutRef.current = null;
2046
+ }
2033
2047
  };
2034
- }, [target]);
2048
+ }, []);
2035
2049
  React.useEffect(function () {
2036
2050
  if (typeof showProp === 'boolean') {
2037
2051
  setShowTooltip(showProp);
@@ -2118,7 +2132,7 @@ var looksLikeLink = function (props) {
2118
2132
  return 'to' in props || 'href' in props;
2119
2133
  };
2120
2134
  var IconButton = React.forwardRef(function (_a, ref) {
2121
- var _b = _a.as, Component = _b === void 0 ? 'button' : _b, icon = _a.icon, label = _a.label, tooltipPlacement = _a.tooltipPlacement, tooltipVariant = _a.tooltipVariant, tooltipPortal = _a.tooltipPortal, _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", "tooltipPlacement", "tooltipVariant", "tooltipPortal", "tooltipProps", "className", "variant", "disabled", "tabIndex", "large"]);
2135
+ 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"]);
2122
2136
  var internalRef = React.useRef();
2123
2137
  React.useImperativeHandle(ref, function () { return internalRef.current; });
2124
2138
  // Configure additional properties based on the type of the Component
@@ -2136,15 +2150,7 @@ var IconButton = React.forwardRef(function (_a, ref) {
2136
2150
  accessibilityProps['aria-disabled'] = disabled;
2137
2151
  }
2138
2152
  }
2139
- if (process.env.NODE_ENV !== 'production') {
2140
- if (!!tooltipPlacement || !!tooltipVariant || !!tooltipPortal) {
2141
- React__default["default"].useEffect(function () {
2142
- console.warn('[IconButton] The following props are deprecated: tooltipPlacement, tooltipVariant, tooltipPortal. ' +
2143
- 'See https://cauldron.dequelabs.com/components/IconButton for recommended replacement.');
2144
- }, []);
2145
- }
2146
- }
2147
- var tooltipProps = tslib.__assign({ placement: tooltipPlacement || 'auto', variant: tooltipVariant, portal: tooltipPortal, association: 'aria-labelledby', hideElementOnHidden: true }, tooltipPropsProp);
2153
+ var tooltipProps = tslib.__assign({ placement: 'auto', association: 'aria-labelledby', hideElementOnHidden: true }, tooltipPropsProp);
2148
2154
  return (React__default["default"].createElement(React__default["default"].Fragment, null,
2149
2155
  React__default["default"].createElement(Component, tslib.__assign({ className: classNames__default["default"](className, {
2150
2156
  IconButton: true,
@@ -2216,126 +2222,110 @@ var tabIndexHandler = function (reset, toast) {
2216
2222
  };
2217
2223
 
2218
2224
  /**
2219
- * The cauldron toast notification component
2225
+ * Hook to be used similarly to the React.Component#componentDidMount.
2226
+ * Executes the provided `effect` when `dependencies` change but does not
2227
+ * execute the effect initially (on mount) - only on update.
2228
+ *
2229
+ * @param effect {Function} function to be executed when dependencies update
2230
+ * @param dependencies {Any} any valid dependency argument to React.useEffect
2220
2231
  */
2221
- var Toast = /** @class */ (function (_super) {
2222
- tslib.__extends(Toast, _super);
2223
- function Toast(props) {
2224
- var _this = _super.call(this, props) || this;
2225
- _this.state = {
2226
- animationClass: props.show ? 'FadeIn--flex' : 'is--hidden'
2227
- };
2228
- _this.dismissToast = _this.dismissToast.bind(_this);
2229
- _this.showToast = _this.showToast.bind(_this);
2230
- return _this;
2231
- }
2232
- Toast.prototype.componentDidMount = function () {
2233
- var show = this.props.show;
2234
- if (show) {
2235
- // Timeout because CSS display: none/block and opacity:
2236
- // 0/1 properties cannot be toggled in the same tick
2237
- // see: https://codepen.io/isnerms/pen/eyQaLP
2238
- setTimeout(this.showToast);
2232
+ var useDidUpdate = function (effect, dependencies) {
2233
+ var mounted = React__default["default"].useRef(false);
2234
+ React__default["default"].useEffect(function () {
2235
+ if (!mounted.current) {
2236
+ mounted.current = true;
2237
+ return;
2239
2238
  }
2239
+ effect();
2240
+ }, dependencies);
2241
+ };
2242
+
2243
+ /**
2244
+ * The cauldron toast notification component
2245
+ */
2246
+ var Toast = function (_a) {
2247
+ var type = _a.type, children = _a.children, _b = _a.onDismiss, onDismiss = _b === void 0 ? function () {
2248
+ // noop
2249
+ } : _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"]);
2250
+ var elRef = useSharedRef(toastRef !== null && toastRef !== void 0 ? toastRef : null);
2251
+ var isolatorRef = React.useRef(null);
2252
+ var timeoutsRef = React.useRef(new Set());
2253
+ var _g = tslib.__read(React.useState(show ? 'FadeIn--flex' : 'is--hidden'), 2), animationClass = _g[0], setAnimationClass = _g[1];
2254
+ // Timeout because CSS display: none/block and opacity:
2255
+ // 0/1 properties cannot be toggled in the same tick
2256
+ // see: https://codepen.io/isnerms/pen/eyQaLP
2257
+ var scheduleNextTick = function (fn) {
2258
+ var id = setTimeout(function () {
2259
+ timeoutsRef.current.delete(id);
2260
+ fn();
2261
+ });
2262
+ timeoutsRef.current.add(id);
2240
2263
  };
2241
- Toast.prototype.componentDidUpdate = function (prevProps) {
2242
- var _this = this;
2243
- var show = this.props.show;
2244
- if (prevProps.show !== show) {
2245
- if (show) {
2246
- this.setState({ animationClass: 'FadeIn--flex' }, function () {
2247
- setTimeout(_this.showToast);
2248
- });
2249
- }
2250
- else {
2251
- this.dismissToast();
2252
- }
2264
+ var showToast = React.useCallback(function () {
2265
+ setAnimationClass('FadeIn--flex FadeIn');
2266
+ if (type === 'action-needed' && elRef.current) {
2267
+ var isolator = new AriaIsolate(elRef.current);
2268
+ tabIndexHandler(false, elRef.current);
2269
+ isolatorRef.current = isolator;
2270
+ isolator.activate();
2253
2271
  }
2254
- };
2255
- Toast.prototype.componentWillUnmount = function () {
2256
- var isolator = this.state.isolator;
2257
- isolator === null || isolator === void 0 ? void 0 : isolator.deactivate();
2258
- };
2259
- Toast.prototype.render = function () {
2260
- var _this = this;
2261
- var animationClass = this.state.animationClass;
2262
- var _a = this.props, type = _a.type, children = _a.children;
2263
- // prevent `onDismiss` from being passed-through to DOM
2264
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
2265
- _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"]);
2266
- var scrim = type === 'action-needed' && show ? (React__default["default"].createElement("div", { className: "Scrim--light Scrim--show Scrim--fade-in" })) : null;
2267
- var defaultProps = {
2268
- tabIndex: -1,
2269
- className: classNames__default["default"]('Toast', "Toast--".concat(typeMap[type].className), animationClass, { 'Toast--non-dismissible': !dismissible }, className)
2270
- };
2271
- if (!focus) {
2272
- defaultProps.role = 'alert';
2272
+ if (elRef.current && !!focus) {
2273
+ elRef.current.focus();
2273
2274
  }
2274
- return (React__default["default"].createElement(React__default["default"].Fragment, null,
2275
- React__default["default"].createElement("div", tslib.__assign({ ref: function (el) {
2276
- _this.el = el;
2277
- setRef(toastRef, el);
2278
- } }, defaultProps, otherProps),
2279
- React__default["default"].createElement("div", { className: "Toast__message" },
2280
- React__default["default"].createElement(Icon, { type: typeMap[type].icon }),
2281
- React__default["default"].createElement("div", { className: "Toast__message-content" }, children)),
2282
- type !== 'action-needed' && dismissible && (React__default["default"].createElement("button", { type: "button", className: 'Toast__dismiss', "aria-label": dismissText, onClick: this.dismissToast },
2283
- React__default["default"].createElement(Icon, { type: "close" })))),
2284
- scrim));
2285
- };
2286
- Toast.prototype.dismissToast = function () {
2287
- var _this = this;
2288
- if (!this.el) {
2275
+ }, [type, focus]);
2276
+ var dismissToast = React.useCallback(function () {
2277
+ if (!elRef.current) {
2289
2278
  return;
2290
2279
  }
2291
- var _a = this.props, onDismiss = _a.onDismiss, type = _a.type;
2292
- var isolator = this.state.isolator;
2293
- this.setState({
2294
- animationClass: 'FadeIn--flex'
2295
- }, function () {
2296
- // Timeout because CSS display: none/block and opacity:
2297
- // 0/1 properties cannot be toggled in the same tick
2298
- // see: https://codepen.io/isnerms/pen/eyQaLP
2299
- setTimeout(function () {
2300
- if (type === 'action-needed') {
2301
- tabIndexHandler(true, _this.el);
2302
- isolator === null || isolator === void 0 ? void 0 : isolator.deactivate();
2303
- }
2304
- _this.setState({ animationClass: 'is--hidden' }, onDismiss);
2305
- });
2306
- });
2307
- };
2308
- Toast.prototype.showToast = function () {
2309
- var _this = this;
2310
- var _a = this.props, type = _a.type, focus = _a.focus;
2311
- this.setState({
2312
- animationClass: 'FadeIn--flex FadeIn'
2313
- }, function () {
2280
+ setAnimationClass('FadeIn--flex');
2281
+ scheduleNextTick(function () {
2282
+ var _a;
2314
2283
  if (type === 'action-needed') {
2315
- var isolator = new AriaIsolate(_this.el);
2316
- tabIndexHandler(false, _this.el);
2317
- _this.setState({ isolator: isolator });
2318
- isolator.activate();
2319
- }
2320
- if (_this.el && !!focus) {
2321
- // focus the toast
2322
- _this.el.focus();
2284
+ tabIndexHandler(true, elRef.current);
2285
+ (_a = isolatorRef.current) === null || _a === void 0 ? void 0 : _a.deactivate();
2323
2286
  }
2287
+ setAnimationClass('is--hidden');
2288
+ onDismiss();
2324
2289
  });
2290
+ }, [type, onDismiss]);
2291
+ React.useEffect(function () {
2292
+ if (show) {
2293
+ scheduleNextTick(showToast);
2294
+ }
2295
+ return function () {
2296
+ var _a;
2297
+ timeoutsRef.current.forEach(clearTimeout);
2298
+ timeoutsRef.current.clear();
2299
+ (_a = isolatorRef.current) === null || _a === void 0 ? void 0 : _a.deactivate();
2300
+ };
2301
+ }, []);
2302
+ useDidUpdate(function () {
2303
+ if (show) {
2304
+ setAnimationClass('FadeIn--flex');
2305
+ scheduleNextTick(showToast);
2306
+ }
2307
+ else {
2308
+ dismissToast();
2309
+ }
2310
+ }, [show]);
2311
+ var scrim = type === 'action-needed' && show ? (React__default["default"].createElement("div", { className: "Scrim--light Scrim--show Scrim--fade-in" })) : null;
2312
+ var defaultProps = {
2313
+ tabIndex: -1,
2314
+ className: classNames__default["default"]('Toast', "Toast--".concat(typeMap[type].className), animationClass, { 'Toast--non-dismissible': !dismissible }, className)
2325
2315
  };
2326
- Toast.defaultProps = {
2327
- dismissText: 'Dismiss',
2328
- // eslint-disable-next-line @typescript-eslint/no-empty-function
2329
- onDismiss: function () { },
2330
- // eslint-disable-next-line @typescript-eslint/no-empty-function
2331
- toastRef: function () { },
2332
- focus: true,
2333
- show: false,
2334
- dismissible: true
2335
- };
2336
- Toast.displayName = 'Toast';
2337
- return Toast;
2338
- }(React__default["default"].Component));
2316
+ if (!focus) {
2317
+ defaultProps.role = 'alert';
2318
+ }
2319
+ return (React__default["default"].createElement(React__default["default"].Fragment, null,
2320
+ React__default["default"].createElement("div", tslib.__assign({ ref: elRef }, defaultProps, otherProps),
2321
+ React__default["default"].createElement("div", { className: "Toast__message" },
2322
+ React__default["default"].createElement(Icon, { type: typeMap[type].icon }),
2323
+ React__default["default"].createElement("div", { className: "Toast__message-content" }, children)),
2324
+ type !== 'action-needed' && dismissible && (React__default["default"].createElement("button", { type: "button", className: "Toast__dismiss", "aria-label": dismissText, onClick: dismissToast },
2325
+ React__default["default"].createElement(Icon, { type: "close" })))),
2326
+ scrim));
2327
+ };
2328
+ Toast.displayName = 'Toast';
2339
2329
 
2340
2330
  var Link = React.forwardRef(function (_a, ref) {
2341
2331
  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"]);
@@ -2602,10 +2592,10 @@ var RadioCardGroup = function (_a) {
2602
2592
  RadioCardGroup.displayName = 'RadioCardGroup';
2603
2593
 
2604
2594
  var Checkbox = React.forwardRef(function (_a, ref) {
2605
- 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"]);
2606
- var _e = tslib.__read(React.useState(checked), 2), isChecked = _e[0], setIsChecked = _e[1];
2607
- var _f = tslib.__read(React.useState(indeterminate), 2), isIndeterminate = _f[0], setIsIndeterminate = _f[1];
2608
- var _g = tslib.__read(React.useState(false), 2), focused = _g[0], setFocused = _g[1];
2595
+ 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"]);
2596
+ var _f = tslib.__read(React.useState(checked), 2), isChecked = _f[0], setIsChecked = _f[1];
2597
+ var _g = tslib.__read(React.useState(indeterminate), 2), isIndeterminate = _g[0], setIsIndeterminate = _g[1];
2598
+ var _h = tslib.__read(React.useState(false), 2), focused = _h[0], setFocused = _h[1];
2609
2599
  var checkRef = React.useRef(null);
2610
2600
  React.useEffect(function () {
2611
2601
  setIsChecked(checked);
@@ -2617,12 +2607,12 @@ var Checkbox = React.forwardRef(function (_a, ref) {
2617
2607
  if (typeof refProp === 'function') {
2618
2608
  refProp(checkRef.current);
2619
2609
  }
2620
- var _h = React.useMemo(function () {
2610
+ var _j = React.useMemo(function () {
2621
2611
  return {
2622
2612
  labelDescriptionId: nextId__default["default"](),
2623
2613
  errorId: nextId__default["default"]()
2624
2614
  };
2625
- }, []), errorId = _h.errorId, labelDescriptionId = _h.labelDescriptionId;
2615
+ }, []), errorId = _j.errorId, labelDescriptionId = _j.labelDescriptionId;
2626
2616
  var ariaDescribedbyId = ariaDescribedby;
2627
2617
  if (error) {
2628
2618
  ariaDescribedbyId = addIdRef(ariaDescribedbyId, errorId);
@@ -2661,7 +2651,9 @@ var Checkbox = React.forwardRef(function (_a, ref) {
2661
2651
  if (isIndeterminate) {
2662
2652
  setIsIndeterminate(false);
2663
2653
  }
2664
- setIsChecked(e.target.checked);
2654
+ if (!controlled) {
2655
+ setIsChecked(e.target.checked);
2656
+ }
2665
2657
  if (onChange) {
2666
2658
  onChange(e);
2667
2659
  }
@@ -3042,8 +3034,8 @@ var ImpactBadge = React.forwardRef(function (_a, ref) {
3042
3034
  ImpactBadge.displayName = 'ImpactBadge';
3043
3035
 
3044
3036
  var TagButton = React__default["default"].forwardRef(function (_a, ref) {
3045
- var label = _a.label, value = _a.value, icon = _a.icon, className = _a.className, rest = tslib.__rest(_a, ["label", "value", "icon", "className"]);
3046
- return (React__default["default"].createElement(Button, tslib.__assign({ variant: "tag", className: classNames__default["default"]('TagButton', className), ref: ref }, rest),
3037
+ var label = _a.label, value = _a.value, icon = _a.icon, className = _a.className, size = _a.size, rest = tslib.__rest(_a, ["label", "value", "icon", "className", "size"]);
3038
+ return (React__default["default"].createElement(Button, tslib.__assign({ variant: "tag", className: classNames__default["default"]('TagButton', className), size: size, ref: ref }, rest),
3047
3039
  React__default["default"].createElement(TagLabel, null, label),
3048
3040
  value,
3049
3041
  React__default["default"].createElement(Icon, { className: "TagButton__icon", type: icon })));
@@ -3186,23 +3178,25 @@ var TableHead = React.forwardRef(function (_a, ref) {
3186
3178
  TableHead.displayName = 'TableHead';
3187
3179
 
3188
3180
  var TableHeader = React.forwardRef(function (_a, ref) {
3189
- var children = _a.children, sortDirection = _a.sortDirection, onSort = _a.onSort, className = _a.className, _b = _a.sortAscendingAnnouncement, sortAscendingAnnouncement = _b === void 0 ? 'sorted ascending' : _b, _c = _a.sortDescendingAnnouncement, sortDescendingAnnouncement = _c === void 0 ? 'sorted descending' : _c, align = _a.align, _d = _a.variant, variant = _d === void 0 ? 'header' : _d, style = _a.style, other = tslib.__rest(_a, ["children", "sortDirection", "onSort", "className", "sortAscendingAnnouncement", "sortDescendingAnnouncement", "align", "variant", "style"]);
3181
+ var children = _a.children, sortDirection = _a.sortDirection, onSort = _a.onSort, className = _a.className, _sortAscendingAnnouncement = _a.sortAscendingAnnouncement, _sortDescendingAnnouncement = _a.sortDescendingAnnouncement, align = _a.align, _b = _a.variant, variant = _b === void 0 ? 'header' : _b, style = _a.style, other = tslib.__rest(_a, ["children", "sortDirection", "onSort", "className", "sortAscendingAnnouncement", "sortDescendingAnnouncement", "align", "variant", "style"]);
3190
3182
  var tableHeaderRef = useSharedRef(ref);
3191
- var _e = useTable(), layout = _e.layout, columns = _e.columns;
3183
+ var _c = useTable(), layout = _c.layout, columns = _c.columns;
3192
3184
  var tableGridStyles = useTableGridStyles({
3193
3185
  elementRef: tableHeaderRef,
3194
3186
  align: align,
3195
3187
  columns: columns,
3196
3188
  layout: layout
3197
3189
  });
3198
- // When the sort direction changes, we want to announce the change in a live region
3199
- // because changes to the sort value is not widely supported yet
3200
- // see: https://a11ysupport.io/tech/aria/aria-sort_attribute
3201
- var announcement = sortDirection === 'ascending'
3202
- ? sortAscendingAnnouncement
3203
- : sortDirection === 'descending'
3204
- ? sortDescendingAnnouncement
3205
- : '';
3190
+ React.useEffect(function () {
3191
+ if (process.env.NODE_ENV === 'production')
3192
+ return;
3193
+ if (_sortAscendingAnnouncement !== undefined ||
3194
+ _sortDescendingAnnouncement !== undefined) {
3195
+ console.warn('[TableHeader] The following props are deprecated and no longer used: sortAscendingAnnouncement, sortDescendingAnnouncement. ' +
3196
+ 'Sort state is communicated via aria-sort. ' +
3197
+ 'See https://cauldron.dequelabs.com/components/Table for more information.');
3198
+ }
3199
+ }, [_sortAscendingAnnouncement, _sortDescendingAnnouncement]);
3206
3200
  return (React__default["default"].createElement("th", tslib.__assign({ ref: tableHeaderRef, "aria-sort": sortDirection, className: classNames__default["default"](variant === 'cell'
3207
3201
  ? ['TableCell', 'TableHeader--cell-variant']
3208
3202
  : 'TableHeader', className, {
@@ -3210,9 +3204,7 @@ var TableHeader = React.forwardRef(function (_a, ref) {
3210
3204
  'TableHeader--sort-descending': sortDirection === 'descending'
3211
3205
  }), style: tslib.__assign(tslib.__assign({}, tableGridStyles), style) }, other), !!onSort && !!sortDirection ? (React__default["default"].createElement("button", { onClick: onSort, className: "TableHeader__sort-button", type: "button" },
3212
3206
  children,
3213
- React__default["default"].createElement("span", { "aria-hidden": "true" }, sortDirection === 'none' ? (React__default["default"].createElement(Icon, { type: "sort-triangle" })) : sortDirection === 'ascending' ? (React__default["default"].createElement(Icon, { type: "table-sort-ascending" })) : (React__default["default"].createElement(Icon, { type: "table-sort-descending" }))),
3214
- React__default["default"].createElement(Offscreen, null,
3215
- React__default["default"].createElement("span", { role: "status", "aria-live": "polite" }, announcement)))) : (children)));
3207
+ React__default["default"].createElement("span", { "aria-hidden": "true" }, sortDirection === 'none' ? (React__default["default"].createElement(Icon, { type: "sort-triangle" })) : sortDirection === 'ascending' ? (React__default["default"].createElement(Icon, { type: "table-sort-ascending" })) : (React__default["default"].createElement(Icon, { type: "table-sort-descending" }))))) : (children)));
3216
3208
  });
3217
3209
  TableHeader.displayName = 'TableHeader';
3218
3210
 
@@ -3234,25 +3226,6 @@ var Tab = React__default["default"].forwardRef(function (_a, ref) {
3234
3226
  });
3235
3227
  Tab.displayName = 'Tab';
3236
3228
 
3237
- /**
3238
- * Hook to be used similarly to the React.Component#componentDidMount.
3239
- * Executes the provided `effect` when `dependencies` change but does not
3240
- * execute the effect initially (on mount) - only on update.
3241
- *
3242
- * @param effect {Function} function to be executed when dependencies update
3243
- * @param dependencies {Any} any valid dependency argument to React.useEffect
3244
- */
3245
- var useDidUpdate = function (effect, dependencies) {
3246
- var mounted = React__default["default"].useRef(false);
3247
- React__default["default"].useEffect(function () {
3248
- if (!mounted.current) {
3249
- mounted.current = true;
3250
- return;
3251
- }
3252
- effect();
3253
- }, dependencies);
3254
- };
3255
-
3256
3229
  var Tabs = function (_a) {
3257
3230
  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"]);
3258
3231
  var _d = tslib.__read(React.useState(initialActiveIndex), 2), activeIndex = _d[0], setActiveIndex = _d[1];
@@ -4609,16 +4582,6 @@ var Combobox = React.forwardRef(function (_a, ref) {
4609
4582
  : ComboboxNoResults;
4610
4583
  }, [renderNoResults]);
4611
4584
  var noMatchingOptions = !!inputValue && !matchingOptions.size && (React__default["default"].createElement(NoMatchingOptions, null));
4612
- var comboboxListbox = (
4613
- // eslint-disable-next-line
4614
- // @ts-expect-error
4615
- // multiselect & value props are passed to Listbox, but TS is unable to infer that
4616
- // it's a correct mapping from Combobox's multiselect & value props
4617
- React__default["default"].createElement(Listbox, { className: classNames__default["default"]('Combobox__listbox', {
4618
- 'Combobox__listbox--open': open
4619
- }), role: noMatchingOptions ? 'presentation' : 'listbox', "aria-labelledby": noMatchingOptions ? undefined : "".concat(id, "-label"), id: "".concat(id, "-listbox"), value: multiselect ? selectedValues : selectedValues[0], onMouseDown: handleComboboxOptionMouseDown, onClick: handleComboboxOptionClick, onSelectionChange: handleSelectionChange, onActiveChange: handleActiveChange, ref: listboxRef, tabIndex: noMatchingOptions ? undefined : -1, "aria-activedescendant": undefined, multiselect: multiselect, disabled: disabled },
4620
- comboboxOptions,
4621
- noMatchingOptions));
4622
4585
  var errorId = "".concat(id, "-error");
4623
4586
  var descriptionId = "".concat(id, "-description");
4624
4587
  var describedby = ariaDescribedby;
@@ -4629,6 +4592,16 @@ var Combobox = React.forwardRef(function (_a, ref) {
4629
4592
  describedby = addIdRef(describedby, errorId);
4630
4593
  }
4631
4594
  var inputProps = tslib.__assign(tslib.__assign({}, props), { 'aria-describedby': describedby });
4595
+ var comboboxListbox = (
4596
+ // eslint-disable-next-line
4597
+ // @ts-expect-error
4598
+ // multiselect & value props are passed to Listbox, but TS is unable to infer that
4599
+ // it's a correct mapping from Combobox's multiselect & value props
4600
+ React__default["default"].createElement(Listbox, { className: classNames__default["default"]('Combobox__listbox', {
4601
+ 'Combobox__listbox--open': open
4602
+ }), role: noMatchingOptions ? 'presentation' : 'listbox', "aria-labelledby": noMatchingOptions ? undefined : "".concat(id, "-label"), "aria-describedby": describedby, id: "".concat(id, "-listbox"), value: multiselect ? selectedValues : selectedValues[0], onMouseDown: handleComboboxOptionMouseDown, onClick: handleComboboxOptionClick, onSelectionChange: handleSelectionChange, onActiveChange: handleActiveChange, ref: listboxRef, tabIndex: noMatchingOptions ? undefined : -1, "aria-activedescendant": undefined, multiselect: multiselect, disabled: disabled },
4603
+ comboboxOptions,
4604
+ noMatchingOptions));
4632
4605
  return (React__default["default"].createElement("div", { id: id, className: classNames__default["default"]('Combobox', { 'Combobox--multiselect': multiselect }, className), ref: comboboxRef },
4633
4606
  name &&
4634
4607
  formValues.map(function (formValue, index) { return (React__default["default"].createElement("input", { type: "hidden", key: index, name: name, value: formValue })); }),
@@ -4661,7 +4634,7 @@ var Combobox = React.forwardRef(function (_a, ref) {
4661
4634
  };
4662
4635
  return (React__default["default"].createElement(ComboboxPill, { ref: refCallback, key: value, value: value, removeOptionLabel: removeOptionLabels[index], disabled: disabled, onClick: handleClick, onKeyDown: handlePillKeyDown }));
4663
4636
  }),
4664
- React__default["default"].createElement("input", tslib.__assign({ type: "text", id: "".concat(id, "-input"), ref: inputRef, value: inputValue, role: "combobox", disabled: disabled, "aria-autocomplete": !isAutoComplete ? 'none' : 'list', "aria-controls": "".concat(id, "-listbox"), "aria-expanded": open, "aria-haspopup": "listbox", "aria-activedescendant": open && activeDescendant ? activeDescendant.element.id : undefined }, inputProps, { onChange: handleChange, onKeyDown: handleKeyDown, onFocus: handleFocus, onBlur: handleBlur })),
4637
+ React__default["default"].createElement("input", tslib.__assign({ type: "text", id: "".concat(id, "-input"), ref: inputRef, value: inputValue, role: "combobox", disabled: disabled, "aria-invalid": error ? true : undefined, "aria-autocomplete": !isAutoComplete ? 'none' : 'list', "aria-controls": "".concat(id, "-listbox"), "aria-expanded": open, "aria-haspopup": "listbox", "aria-activedescendant": open && activeDescendant ? activeDescendant.element.id : undefined }, inputProps, { onChange: handleChange, onKeyDown: handleKeyDown, onFocus: handleFocus, onBlur: handleBlur })),
4665
4638
  React__default["default"].createElement("span", { className: "Combobox__arrow" })),
4666
4639
  React__default["default"].createElement(ComboboxProvider, { autocomplete: autocomplete, inputValue: inputValue, formValues: formValues, selectedValues: selectedValues, removeOptionLabels: removeOptionLabels, setRemoveOptionLabels: setRemoveOptionLabels, matches: !isAutoComplete || defaultAutoCompleteMatches, matchingOptions: matchingOptions, setMatchingOptions: setMatchingOptions, setFormValues: setFormValues }, portal && typeof document !== 'undefined'
4667
4640
  ? reactDom.createPortal(comboboxListbox,
@@ -5428,6 +5401,57 @@ var ActionMenu = React.forwardRef(function (_a, ref) {
5428
5401
  });
5429
5402
  ActionMenu.displayName = 'ActionMenu';
5430
5403
 
5404
+ var TreeViewItem = function (_a) {
5405
+ var id = _a.id, textValue = _a.textValue, children = _a.children;
5406
+ var checkboxId = React.useMemo(function () { return nextId__default["default"]('tree-view-item-'); }, []);
5407
+ return (React__default["default"].createElement(reactAriaComponents.TreeItem, { id: id, textValue: textValue, className: "TreeView__item" },
5408
+ React__default["default"].createElement(reactAriaComponents.TreeItemContent, null, function (_a) {
5409
+ var selectionMode = _a.selectionMode, isSelected = _a.isSelected;
5410
+ return (React__default["default"].createElement(React__default["default"].Fragment, null,
5411
+ React__default["default"].createElement(reactAriaComponents.Button, { slot: "chevron", className: "TreeView__chevron" },
5412
+ React__default["default"].createElement(Icon, { type: "chevron-right" })),
5413
+ selectionMode !== 'none' ? (React__default["default"].createElement(Checkbox, { id: checkboxId, label: textValue, checked: isSelected, controlled: true, tabIndex: -1 })) : (React__default["default"].createElement(React__default["default"].Fragment, null, textValue))));
5414
+ }),
5415
+ 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))); })))));
5416
+ };
5417
+ TreeViewItem.displayName = 'TreeViewItem';
5418
+
5419
+ function collectAllKeys(nodes) {
5420
+ return nodes.flatMap(function (node) { return tslib.__spreadArray([
5421
+ node.id
5422
+ ], tslib.__read((node.children ? collectAllKeys(node.children) : [])), false); });
5423
+ }
5424
+ var TreeView = React.forwardRef(function (_a, ref) {
5425
+ var items = _a.items, onAction = _a.onAction, _b = _a.selectionMode, selectionMode = _b === void 0 ? 'none' : _b, defaultExpandedKeys = _a.defaultExpandedKeys, className = _a.className, other = tslib.__rest(_a, ["items", "onAction", "selectionMode", "defaultExpandedKeys", "className"]);
5426
+ var _c = tslib.__read(React.useState(new Set()), 2), selectedKeys = _c[0], setSelectedKeys = _c[1];
5427
+ var handleAction = function (key) {
5428
+ setSelectedKeys(function (prev) {
5429
+ var prevSet = prev === 'all' ? new Set(collectAllKeys(items)) : new Set(prev);
5430
+ var next = new Set(prevSet);
5431
+ if (next.has(key)) {
5432
+ next.delete(key);
5433
+ }
5434
+ else {
5435
+ if (selectionMode === 'single') {
5436
+ next.clear();
5437
+ }
5438
+ next.add(key);
5439
+ }
5440
+ return next;
5441
+ });
5442
+ onAction === null || onAction === void 0 ? void 0 : onAction(key);
5443
+ };
5444
+ var actionProps = onAction
5445
+ ? {
5446
+ onAction: handleAction,
5447
+ selectedKeys: selectedKeys,
5448
+ onSelectionChange: setSelectedKeys
5449
+ }
5450
+ : {};
5451
+ return (React__default["default"].createElement(reactAriaComponents.Tree, tslib.__assign({ ref: ref, className: classNames__default["default"]('TreeView', className), selectionMode: selectionMode, defaultExpandedKeys: defaultExpandedKeys }, actionProps, other), items.map(function (item) { return (React__default["default"].createElement(TreeViewItem, tslib.__assign({ key: item.id }, item))); })));
5452
+ });
5453
+ TreeView.displayName = 'TreeView';
5454
+
5431
5455
  var LIGHT_THEME_CLASS = 'cauldron--theme-light';
5432
5456
  var DARK_THEME_CLASS = 'cauldron--theme-dark';
5433
5457
  var ThemeContext = React.createContext({
@@ -5623,6 +5647,7 @@ exports.TopBar = TopBar;
5623
5647
  exports.TopBarItem = MenuItem;
5624
5648
  exports.TopBarMenu = TopBarMenu;
5625
5649
  exports.TopBarTrigger = TopBarTrigger;
5650
+ exports.TreeView = TreeView;
5626
5651
  exports.TwoColumnPanel = TwoColumnPanel;
5627
5652
  exports.Workspace = Workspace;
5628
5653
  exports.focusableSelector = focusableSelector;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deque/cauldron-react",
3
- "version": "6.27.0",
3
+ "version": "7.0.0-canary.0a6fafe6",
4
4
  "license": "MPL-2.0",
5
5
  "description": "Fully accessible react components library for Deque Cauldron",
6
6
  "homepage": "https://cauldron.dequelabs.com/",
@@ -27,6 +27,7 @@
27
27
  "classnames": "^2.2.6",
28
28
  "focusable": "^2.3.0",
29
29
  "keyname": "^0.1.0",
30
+ "react-aria-components": "^1.13.0",
30
31
  "react-id-generator": "^3.0.1",
31
32
  "react-syntax-highlighter": "^16.0.1",
32
33
  "tslib": "^2.4.0"