@deque/cauldron-react 6.16.0-canary.d7ad0332 → 6.16.0-canary.dce6ee58

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.
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ import { type ActionListSelectionType, type onActionCallbackFunction } from './ActionListContext';
3
+ interface ActionListProps extends React.HTMLAttributes<HTMLUListElement> {
4
+ children: React.ReactNode;
5
+ /** Limits the amount of selections that can be made within an action list */
6
+ selectionType?: ActionListSelectionType | null;
7
+ /** A callback function that is called when an action list item is selected. */
8
+ onAction?: onActionCallbackFunction;
9
+ }
10
+ declare const ActionList: React.ForwardRefExoticComponent<ActionListProps & React.RefAttributes<HTMLUListElement>>;
11
+ export default ActionList;
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+ export type onActionEvent = React.MouseEvent<HTMLLIElement | HTMLAnchorElement> | React.KeyboardEvent<HTMLLIElement | HTMLAnchorElement>;
3
+ export type onActionCallbackFunction = (key: string, event: onActionEvent) => void;
4
+ export type ActionListSelectionType = 'single' | 'multiple';
5
+ type ActionListContext = {
6
+ role: 'list' | 'menu' | 'listbox' | null;
7
+ selectionType: ActionListSelectionType | null;
8
+ onAction?: onActionCallbackFunction;
9
+ };
10
+ type ActionListProviderProps = {
11
+ children: React.ReactNode;
12
+ } & ActionListContext;
13
+ declare const ActionListContext: React.Context<ActionListContext>;
14
+ declare function ActionListProvider({ role, selectionType, onAction, children }: ActionListProviderProps): React.JSX.Element;
15
+ declare function useActionListContext(): ActionListContext;
16
+ export { ActionListProvider, useActionListContext };
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+ import { type ActionListSelectionType, type onActionCallbackFunction } from './ActionListContext';
3
+ import { ContentNode } from '../../types';
4
+ interface ActionListGroupProps extends React.HTMLAttributes<HTMLLIElement> {
5
+ /** Provides a label for the group of action items */
6
+ label: ContentNode;
7
+ /** Limits the amount of selections that can be made within an action group */
8
+ selectionType?: ActionListSelectionType | null;
9
+ /** A callback function that is called when an action list item is selected. */
10
+ onAction?: onActionCallbackFunction;
11
+ }
12
+ declare const ActionListGroup: React.ForwardRefExoticComponent<ActionListGroupProps & React.RefAttributes<HTMLLIElement>>;
13
+ export default ActionListGroup;
@@ -0,0 +1,25 @@
1
+ import React from 'react';
2
+ import { type IconType } from '../Icon';
3
+ import type { PolymorphicProps, PolymorphicComponent } from '../../utils/polymorphicComponent';
4
+ import { type onActionEvent } from './ActionListContext';
5
+ interface ActionListItemProps extends PolymorphicProps<React.HTMLAttributes<HTMLLIElement>> {
6
+ /**
7
+ * A unique key to identify the action when triggered, when not provided
8
+ * will use the child text content as the key.
9
+ */
10
+ actionKey?: string;
11
+ /** Displays a leading icon for the action item. */
12
+ leadingIcon?: IconType;
13
+ /** Displays a trailing icon for the action item. */
14
+ trailingIcon?: IconType;
15
+ /** Provides an additional description for the action item. */
16
+ description?: React.ReactNode;
17
+ /** Indicates if the current action item is selected. */
18
+ selected?: boolean;
19
+ /** When an action item is disabled, it cannot be selected or activated. */
20
+ disabled?: boolean;
21
+ /** A callback function that is called when an action item is selected. */
22
+ onAction?: (event: onActionEvent) => void;
23
+ }
24
+ declare const ActionListItem: PolymorphicComponent<ActionListItemProps>;
25
+ export default ActionListItem;
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ import ActionListItem from './ActionListItem';
3
+ type ActionListLinkItemProps = React.AnchorHTMLAttributes<HTMLAnchorElement> & Omit<React.ComponentProps<typeof ActionListItem>, keyof React.HTMLAttributes<HTMLLIElement> | 'selected'> & {
4
+ href: string;
5
+ };
6
+ declare const ActionListLinkItem: React.ForwardRefExoticComponent<Omit<ActionListLinkItemProps, "ref"> & React.RefAttributes<HTMLAnchorElement>>;
7
+ export default ActionListLinkItem;
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ type ActionListSeparatorProps = React.HTMLAttributes<HTMLLIElement>;
3
+ declare const ActionListSeparator: React.ForwardRefExoticComponent<ActionListSeparatorProps & React.RefAttributes<HTMLLIElement>>;
4
+ export default ActionListSeparator;
@@ -0,0 +1,5 @@
1
+ export { default as ActionList } from './ActionList';
2
+ export { default as ActionListItem } from './ActionListItem';
3
+ export { default as ActionListGroup } from './ActionListGroup';
4
+ export { default as ActionListSeparator } from './ActionListSeparator';
5
+ export { default as ActionListLinkItem } from './ActionListLinkItem';
@@ -0,0 +1,26 @@
1
+ import React from 'react';
2
+ type ActionMenuTriggerProps = Pick<React.HTMLAttributes<HTMLButtonElement>, 'onClick' | 'onKeyDown' | 'aria-expanded' | 'aria-haspopup'>;
3
+ type ActionMenuTriggerFunction = (props: ActionMenuTriggerProps, open: boolean) => React.ReactElement;
4
+ declare const ActionMenu: React.ForwardRefExoticComponent<{
5
+ children: React.ReactElement;
6
+ trigger: React.ReactElement | ActionMenuTriggerFunction;
7
+ } & Pick<{
8
+ target: HTMLElement | React.RefObject<HTMLElement> | React.MutableRefObject<HTMLElement>;
9
+ placement?: "auto" | import("@floating-ui/utils").Placement | "auto-start" | "auto-end" | undefined;
10
+ open?: boolean | undefined;
11
+ onOpenChange?: ((open: boolean) => void) | undefined;
12
+ onPlacementChange?: ((placement: import("@floating-ui/utils").Placement) => void) | undefined;
13
+ onShiftChange?: ((coords: import("@floating-ui/utils").Coords) => void) | undefined;
14
+ offset?: number | undefined;
15
+ focusTrap?: boolean | undefined;
16
+ focusTrapOptions?: {
17
+ disabled?: boolean | undefined;
18
+ initialFocusElement?: import("../../types").ElementOrRef<HTMLElement> | undefined;
19
+ returnFocus?: boolean | undefined;
20
+ returnFocusElement?: import("../../types").ElementOrRef<HTMLElement> | undefined;
21
+ } | undefined;
22
+ children?: React.ReactNode;
23
+ } & React.HTMLAttributes<HTMLElement> & {
24
+ as?: React.ElementType<any, keyof React.JSX.IntrinsicElements> | undefined;
25
+ } & React.RefAttributes<HTMLElement>, "placement"> & React.HTMLAttributes<HTMLElement> & React.RefAttributes<HTMLElement>>;
26
+ export default ActionMenu;
@@ -0,0 +1 @@
1
+ export { default as ActionMenu } from './ActionMenu';
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+ interface EmptyStateProps extends React.HTMLAttributes<HTMLDivElement> {
3
+ /** Heading text to be displayed for the empty state. */
4
+ heading: React.ReactNode;
5
+ /** Description for the empty state. */
6
+ description: React.ReactNode;
7
+ /** Slot for primary actions. */
8
+ primaryActions?: React.ReactNode;
9
+ /** Slot for secondary actions. */
10
+ secondaryActions?: React.ReactNode;
11
+ }
12
+ declare const EmptyState: React.ForwardRefExoticComponent<EmptyStateProps & React.RefAttributes<HTMLDivElement>>;
13
+ export default EmptyState;
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ interface FieldGroupProps extends React.HTMLAttributes<HTMLDivElement> {
3
+ label: React.ReactNode;
4
+ children: React.ReactNode;
5
+ description?: React.ReactNode;
6
+ error?: React.ReactNode;
7
+ }
8
+ declare const FieldGroup: React.ForwardRefExoticComponent<FieldGroupProps & React.RefAttributes<HTMLDivElement>>;
9
+ export default FieldGroup;
@@ -4,6 +4,8 @@ import type { ListboxValue } from './ListboxOption';
4
4
  import type { PolymorphicProps, PolymorphicComponent } from '../../utils/polymorphicComponent';
5
5
  interface BaseListboxProps extends PolymorphicProps<Omit<React.HTMLAttributes<HTMLElement>, 'onSelect' | 'defaultValue'>> {
6
6
  navigation?: 'cycle' | 'bound';
7
+ focusStrategy?: 'lastSelected' | 'first' | 'last';
8
+ focusDisabledOptions?: boolean;
7
9
  onActiveChange?: (option: ListboxOption) => void;
8
10
  disabled?: boolean;
9
11
  }
@@ -14,7 +14,7 @@ export declare const Step: {
14
14
  (props: StepProps): React.JSX.Element;
15
15
  displayName: string;
16
16
  };
17
- interface StepperProps {
17
+ interface StepperProps extends React.HTMLAttributes<HTMLOListElement> {
18
18
  children: React.ReactNode;
19
19
  className?: string;
20
20
  }
package/lib/index.d.ts CHANGED
@@ -62,8 +62,12 @@ export { default as CopyButton } from './components/CopyButton';
62
62
  export { default as Drawer } from './components/Drawer';
63
63
  export { default as BottomSheet } from './components/BottomSheet';
64
64
  export { default as AnchoredOverlay } from './components/AnchoredOverlay';
65
+ export { default as FieldGroup } from './components/FieldGroup';
65
66
  export { default as PageHeader } from './components/PageHeader';
66
67
  export { default as SectionHeader } from './components/SectionHeader';
68
+ export { default as EmptyState } from './components/EmptyState';
69
+ export { ActionList, ActionListItem, ActionListGroup, ActionListSeparator, ActionListLinkItem } from './components/ActionList';
70
+ export { ActionMenu } from './components/ActionMenu';
67
71
  /**
68
72
  * Helpers / Utils
69
73
  */
package/lib/index.js CHANGED
@@ -859,7 +859,7 @@ function ClickOutsideListener(_a, ref) {
859
859
  ClickOutsideListener.displayName = 'ClickOutsideListener';
860
860
  var ClickOutsideListener$1 = React__default["default"].forwardRef(ClickOutsideListener);
861
861
 
862
- var _a$2 = tslib.__read([38, 40, 9, 13, 32, 27], 6), up = _a$2[0], down$1 = _a$2[1], tab = _a$2[2], enter = _a$2[3], space = _a$2[4], esc = _a$2[5];
862
+ var _a$3 = tslib.__read([38, 40, 9, 13, 32, 27], 6), up = _a$3[0], down$1 = _a$3[1], tab = _a$3[2], enter = _a$3[3], space = _a$3[4], esc = _a$3[5];
863
863
  var OptionsMenuList = function (_a) {
864
864
  var children = _a.children, menuRef = _a.menuRef, show = _a.show, className = _a.className, _b = _a.onClose, onClose = _b === void 0 ? function () { } : _b, // eslint-disable-line @typescript-eslint/no-empty-function
865
865
  _c = _a.onSelect, // eslint-disable-line @typescript-eslint/no-empty-function
@@ -970,7 +970,7 @@ var OptionsMenuList = function (_a) {
970
970
  } }), items)));
971
971
  };
972
972
 
973
- var _a$1 = tslib.__read([40], 1), down = _a$1[0];
973
+ var _a$2 = tslib.__read([40], 1), down = _a$2[0];
974
974
  var OptionsMenu = function (_a) {
975
975
  var children = _a.children, className = _a.className; _a.closeOnSelect; var menuRef = _a.menuRef, trigger = _a.trigger, _b = _a.align, align = _b === void 0 ? 'right' : _b, _c = _a.onClose, onClose = _c === void 0 ? function () { } : _c, // eslint-disable-line @typescript-eslint/no-empty-function
976
976
  _d = _a.onSelect, // eslint-disable-line @typescript-eslint/no-empty-function
@@ -3652,10 +3652,10 @@ var optionMatchesValue = function (option, value) {
3652
3652
  option.value === value;
3653
3653
  };
3654
3654
  var Listbox = React.forwardRef(function (_a, ref) {
3655
- var _b = _a.as, Component = _b === void 0 ? 'ul' : _b, children = _a.children, defaultValue = _a.defaultValue, value = _a.value, _c = _a.navigation, navigation = _c === void 0 ? 'bound' : _c, _d = _a.multiselect, multiselect = _d === void 0 ? false : _d, onKeyDown = _a.onKeyDown, onFocus = _a.onFocus, onSelectionChange = _a.onSelectionChange, onActiveChange = _a.onActiveChange, _e = _a.disabled, disabled = _e === void 0 ? false : _e, props = tslib.__rest(_a, ["as", "children", "defaultValue", "value", "navigation", "multiselect", "onKeyDown", "onFocus", "onSelectionChange", "onActiveChange", "disabled"]);
3656
- var _f = tslib.__read(React.useState([]), 2), options = _f[0], setOptions = _f[1];
3657
- var _g = tslib.__read(React.useState(null), 2), activeOption = _g[0], setActiveOption = _g[1];
3658
- var _h = tslib.__read(React.useState([]), 2), selectedOptions = _h[0], setSelectedOptions = _h[1];
3655
+ var _b = _a.as, Component = _b === void 0 ? 'ul' : _b, children = _a.children, defaultValue = _a.defaultValue, value = _a.value, _c = _a.navigation, navigation = _c === void 0 ? 'bound' : _c, _d = _a.focusStrategy, focusStrategy = _d === void 0 ? 'lastSelected' : _d, _e = _a.focusDisabledOptions, focusDisabledOptions = _e === void 0 ? false : _e, _f = _a.multiselect, multiselect = _f === void 0 ? false : _f, onKeyDown = _a.onKeyDown, onFocus = _a.onFocus, onSelectionChange = _a.onSelectionChange, onActiveChange = _a.onActiveChange, _g = _a.disabled, disabled = _g === void 0 ? false : _g, props = tslib.__rest(_a, ["as", "children", "defaultValue", "value", "navigation", "focusStrategy", "focusDisabledOptions", "multiselect", "onKeyDown", "onFocus", "onSelectionChange", "onActiveChange", "disabled"]);
3656
+ var _h = tslib.__read(React.useState([]), 2), options = _h[0], setOptions = _h[1];
3657
+ var _j = tslib.__read(React.useState(null), 2), activeOption = _j[0], setActiveOption = _j[1];
3658
+ var _k = tslib.__read(React.useState([]), 2), selectedOptions = _k[0], setSelectedOptions = _k[1];
3659
3659
  var listboxRef = useSharedRef(ref);
3660
3660
  var isControlled = typeof value !== 'undefined';
3661
3661
  React.useLayoutEffect(function () {
@@ -3737,7 +3737,9 @@ var Listbox = React.forwardRef(function (_a, ref) {
3737
3737
  return;
3738
3738
  }
3739
3739
  event.preventDefault();
3740
- var enabledOptions = options.filter(function (option) { return !isDisabledOption(option); });
3740
+ var enabledOptions = !focusDisabledOptions
3741
+ ? options.filter(function (option) { return !isDisabledOption(option); })
3742
+ : options;
3741
3743
  // istanbul ignore next
3742
3744
  if (!enabledOptions.length) {
3743
3745
  return;
@@ -3782,9 +3784,29 @@ var Listbox = React.forwardRef(function (_a, ref) {
3782
3784
  }
3783
3785
  }, [options, activeOption, navigation, handleSelect]);
3784
3786
  var handleFocus = React.useCallback(function (event) {
3787
+ if (focusStrategy === 'first') {
3788
+ var firstOption = !focusDisabledOptions
3789
+ ? options.find(function (option) { return !isDisabledOption(option); })
3790
+ : options[0];
3791
+ if (firstOption) {
3792
+ setActiveOption(firstOption);
3793
+ }
3794
+ return;
3795
+ }
3796
+ if (focusStrategy === 'last') {
3797
+ var lastOption = !focusDisabledOptions
3798
+ ? tslib.__spreadArray([], tslib.__read(options), false).reverse().find(function (option) { return !isDisabledOption(option); })
3799
+ : options[options.length - 1];
3800
+ if (lastOption) {
3801
+ setActiveOption(lastOption);
3802
+ }
3803
+ return;
3804
+ }
3785
3805
  if (!activeOption ||
3786
3806
  !options.some(function (option) { return option.element === activeOption.element; })) {
3787
- var firstOption = options.find(function (option) { return !isDisabledOption(option); });
3807
+ var firstOption = !focusDisabledOptions
3808
+ ? options.find(function (option) { return !isDisabledOption(option); })
3809
+ : options[0];
3788
3810
  // istanbul ignore else
3789
3811
  if (firstOption) {
3790
3812
  setActiveOption(firstOption);
@@ -3796,7 +3818,7 @@ var Listbox = React.forwardRef(function (_a, ref) {
3796
3818
  setActiveOption(selectedOptions[selectedOptions.length - 1]);
3797
3819
  }
3798
3820
  onFocus === null || onFocus === void 0 ? void 0 : onFocus(event);
3799
- }, [options, activeOption, selectedOptions]);
3821
+ }, [options, activeOption, selectedOptions, focusStrategy]);
3800
3822
  return (React__default["default"].createElement(Component, tslib.__assign({ role: "listbox", ref: listboxRef, tabIndex: "0", onKeyDown: handleKeyDown, onFocus: handleFocus, "aria-multiselectable": multiselect ? true : undefined, "aria-activedescendant": activeOption ? getOptionId(activeOption) : undefined }, props),
3801
3823
  React__default["default"].createElement(ListboxProvider, { options: options, active: activeOption, multiselect: multiselect, selected: selectedOptions, setOptions: setOptions, onSelect: handleSelect }, children)));
3802
3824
  });
@@ -4105,20 +4127,20 @@ var ComboboxPill = React.forwardRef(function (_a, ref) {
4105
4127
  ComboboxPill.displayName = 'ComboboxPill';
4106
4128
 
4107
4129
  // Event Keys
4108
- var _a = tslib.__read([
4130
+ var _a$1 = tslib.__read([
4109
4131
  'Enter',
4110
4132
  'Escape',
4111
4133
  'Home',
4112
4134
  'End',
4113
4135
  'Backspace',
4114
4136
  'Delete'
4115
- ], 6), Enter = _a[0], Escape = _a[1], Home = _a[2], End = _a[3], Backspace = _a[4], Delete = _a[5];
4137
+ ], 6), Enter = _a$1[0], Escape = _a$1[1], Home = _a$1[2], End = _a$1[3], Backspace = _a$1[4], Delete = _a$1[5];
4116
4138
  var _b = tslib.__read([
4117
4139
  'ArrowDown',
4118
4140
  'ArrowUp',
4119
4141
  'ArrowLeft',
4120
4142
  'ArrowRight'
4121
- ], 4), ArrowDown = _b[0], ArrowUp = _b[1], ArrowLeft = _b[2], ArrowRight = _b[3];
4143
+ ], 4), ArrowDown$1 = _b[0], ArrowUp$1 = _b[1], ArrowLeft = _b[2], ArrowRight = _b[3];
4122
4144
  var PillKeys = [Backspace, Delete, ArrowLeft, ArrowRight];
4123
4145
  var defaultAutoCompleteMatches = function (inputValue, value) {
4124
4146
  // istanbul ignore if
@@ -4290,7 +4312,7 @@ var Combobox = React.forwardRef(function (_a, ref) {
4290
4312
  var escKeypress = event.key === Escape;
4291
4313
  var deleteKeypress = event.key === Delete;
4292
4314
  var backspaceKeypress = event.key === Backspace;
4293
- var listboxArrowKeypress = [ArrowUp, ArrowDown].includes(event.key);
4315
+ var listboxArrowKeypress = [ArrowUp$1, ArrowDown$1].includes(event.key);
4294
4316
  if (
4295
4317
  // prevent the page from scrolling and allow start/end option activation
4296
4318
  [Home, End].includes(event.key) ||
@@ -4790,6 +4812,28 @@ var BottomSheet = React.forwardRef(function (_a, ref) {
4790
4812
  });
4791
4813
  BottomSheet.displayName = 'BottomSheet';
4792
4814
 
4815
+ var FieldGroup = React.forwardRef(function (_a, ref) {
4816
+ var label = _a.label, description = _a.description, error = _a.error, children = _a.children, className = _a.className, propId = _a.id, props = tslib.__rest(_a, ["label", "description", "error", "children", "className", "id"]);
4817
+ var _b = tslib.__read(propId ? [propId] : nextId.useId(1, 'fieldgroup'), 1), id = _b[0];
4818
+ var descriptionId = "".concat(id, "-description");
4819
+ var errorId = "".concat(id, "-error");
4820
+ var ariaDescribedbyId = '';
4821
+ if (description) {
4822
+ ariaDescribedbyId = addIdRef(ariaDescribedbyId, descriptionId);
4823
+ }
4824
+ if (error) {
4825
+ ariaDescribedbyId = addIdRef(ariaDescribedbyId, errorId);
4826
+ }
4827
+ return (React__default["default"].createElement("div", tslib.__assign({ role: "group", className: classNames__default["default"]('FieldGroup', className), ref: ref }, props, { "aria-labelledby": "".concat(id, "-label"), "aria-describedby": ariaDescribedbyId || undefined }),
4828
+ React__default["default"].createElement("label", { id: "".concat(id, "-label"), className: "Field__label" }, label),
4829
+ description && (React__default["default"].createElement("div", { id: descriptionId, className: "Field__description" }, description)),
4830
+ error && (React__default["default"].createElement("div", { className: "Field__error", id: errorId },
4831
+ React__default["default"].createElement(Icon, { type: "caution" }),
4832
+ error)),
4833
+ children));
4834
+ });
4835
+ FieldGroup.displayName = 'FieldGroup';
4836
+
4793
4837
  var SectionHeader = React.forwardRef(function (_a, ref) {
4794
4838
  var className = _a.className, heading = _a.heading, description = _a.description, children = _a.children, otherProps = tslib.__rest(_a, ["className", "heading", "description", "children"]);
4795
4839
  if (typeof heading === 'string') {
@@ -4814,6 +4858,297 @@ var PageHeader = React.forwardRef(function (_a, ref) {
4814
4858
  });
4815
4859
  PageHeader.displayName = 'PageHeader';
4816
4860
 
4861
+ var EmptyState = React.forwardRef(function (_a, ref) {
4862
+ var className = _a.className, heading = _a.heading, description = _a.description, primaryActions = _a.primaryActions, secondaryActions = _a.secondaryActions, props = tslib.__rest(_a, ["className", "heading", "description", "primaryActions", "secondaryActions"]);
4863
+ if (typeof heading === 'string') {
4864
+ heading = React__default["default"].createElement("h2", null, heading);
4865
+ }
4866
+ return (React__default["default"].createElement("div", tslib.__assign({ ref: ref, className: classNames__default["default"]('EmptyState', className) }, props),
4867
+ heading,
4868
+ React__default["default"].createElement("p", null, description),
4869
+ primaryActions && (React__default["default"].createElement("div", { className: "EmptyState__primary" }, primaryActions)),
4870
+ secondaryActions && (React__default["default"].createElement("div", { className: "EmptyState__secondary" }, secondaryActions))));
4871
+ });
4872
+ EmptyState.displayName = 'EmptyState';
4873
+
4874
+ /* istanbul ignore next */
4875
+ var ActionListContext = React.createContext({
4876
+ role: null,
4877
+ selectionType: null,
4878
+ onAction: function () { return null; }
4879
+ });
4880
+ function ActionListProvider(_a) {
4881
+ var role = _a.role, selectionType = _a.selectionType, onAction = _a.onAction, children = _a.children;
4882
+ var Provider = ActionListContext.Provider;
4883
+ var contextValue = React.useMemo(function () { return ({
4884
+ role: role,
4885
+ selectionType: selectionType,
4886
+ onAction: onAction
4887
+ }); }, [role, selectionType, onAction]);
4888
+ return React__default["default"].createElement(Provider, { value: contextValue }, children);
4889
+ }
4890
+ function useActionListContext() {
4891
+ return React.useContext(ActionListContext);
4892
+ }
4893
+
4894
+ var ActionList = React.forwardRef(function (_a, ref) {
4895
+ 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"]);
4896
+ var actionListContext = useActionListContext();
4897
+ var activeElement = React.useRef();
4898
+ var handleActiveChange = React.useCallback(function (value) {
4899
+ activeElement.current = value === null || value === void 0 ? void 0 : value.element;
4900
+ }, []);
4901
+ var handleAction = React.useCallback(function (key, event) {
4902
+ if (typeof onAction === 'function') {
4903
+ onAction(key, event);
4904
+ }
4905
+ }, [onAction]);
4906
+ var handleKeyDown = React.useCallback(function (event) {
4907
+ var _a;
4908
+ if (event.defaultPrevented) {
4909
+ return;
4910
+ }
4911
+ // Since focus is managed in the action list using `aria-activedescendant`
4912
+ // we want to simulate a keypress on the current active list item
4913
+ if (event.key === 'Enter' || event.key === ' ') {
4914
+ (_a = activeElement.current) === null || _a === void 0 ? void 0 : _a.click();
4915
+ }
4916
+ }, []);
4917
+ return (
4918
+ // Note: we should be able to use listbox without passing a prop
4919
+ // value for "multiselect"
4920
+ // see: https://github.com/dequelabs/cauldron/issues/1890
4921
+ // @ts-expect-error this should be allowed
4922
+ React__default["default"].createElement(Listbox, tslib.__assign({ ref: ref,
4923
+ /* Listbox comes with an explicit role of "listbox", but we want to either
4924
+ * use the role from props, or default to the intrinsic role */
4925
+ // eslint-disable-next-line jsx-a11y/aria-role
4926
+ role: undefined, "aria-multiselectable": actionListContext.role === 'listbox' ? undefined : null, className: classNames__default["default"]('ActionList', className) }, props, { onKeyDown: handleKeyDown, onActiveChange: handleActiveChange, navigation: "bound" }),
4927
+ React__default["default"].createElement(ActionListProvider, { role: props.role || 'list', onAction: handleAction, selectionType: selectionType }, children)));
4928
+ });
4929
+ ActionList.displayName = 'ActionList';
4930
+
4931
+ var ActionListItem = React.forwardRef(function (_a, ref) {
4932
+ var _b = _a.as, Component = _b === void 0 ? 'li' : _b, actionKey = _a.actionKey, className = _a.className, description = _a.description, selected = _a.selected, leadingIcon = _a.leadingIcon, trailingIcon = _a.trailingIcon, onAction = _a.onAction, children = _a.children, props = tslib.__rest(_a, ["as", "actionKey", "className", "description", "selected", "leadingIcon", "trailingIcon", "onAction", "children"]);
4933
+ var _c = tslib.__read(nextId.useId(1, 'action-list-item'), 1), id = _c[0];
4934
+ var actionListItemRef = useSharedRef(ref);
4935
+ var labelRef = React.useRef(null);
4936
+ var active = useListboxContext().active;
4937
+ var _d = useActionListContext(), contextRole = _d.role, onActionListAction = _d.onAction, selectionType = _d.selectionType;
4938
+ var intersectionRef = useIntersectionRef(actionListItemRef, {
4939
+ root: null,
4940
+ threshold: 1.0
4941
+ });
4942
+ var isActive = !!(active === null || active === void 0 ? void 0 : active.element) && active.element === actionListItemRef.current;
4943
+ var handleAction = React.useCallback(function (event) {
4944
+ var _a;
4945
+ if (event.defaultPrevented) {
4946
+ return;
4947
+ }
4948
+ if (selectionType === 'multiple') {
4949
+ // If action list is part of a multiselect menu, prevent the menu from closing
4950
+ event.preventDefault();
4951
+ }
4952
+ if (typeof onAction === 'function') {
4953
+ onAction(event);
4954
+ }
4955
+ // istanbul ignore else
4956
+ if (typeof onActionListAction === 'function') {
4957
+ onActionListAction(actionKey || ((_a = labelRef === null || labelRef === void 0 ? void 0 : labelRef.current) === null || _a === void 0 ? void 0 : _a.innerText.trim()) || '', event);
4958
+ }
4959
+ }, [onAction, onActionListAction, selectionType, actionKey]);
4960
+ var listItemRole = undefined;
4961
+ if (contextRole === 'menu') {
4962
+ switch (selectionType) {
4963
+ case 'single':
4964
+ listItemRole = 'menuitemradio';
4965
+ break;
4966
+ case 'multiple':
4967
+ listItemRole = 'menuitemcheckbox';
4968
+ break;
4969
+ default:
4970
+ listItemRole = 'menuitem';
4971
+ break;
4972
+ }
4973
+ }
4974
+ else if (contextRole === 'listbox') {
4975
+ listItemRole = 'option';
4976
+ }
4977
+ // Keep the currently active item on screen when navigating via up/down arrow key navigation
4978
+ // istanbul ignore next
4979
+ React.useLayoutEffect(function () {
4980
+ var intersectionEntry = intersectionRef.current;
4981
+ if (!intersectionEntry || !isActive) {
4982
+ return;
4983
+ }
4984
+ var rect = actionListItemRef.current.getBoundingClientRect();
4985
+ var isInViewport = rect.top >= 0 &&
4986
+ rect.left >= 0 &&
4987
+ rect.bottom <= window.innerHeight &&
4988
+ rect.right <= window.innerWidth;
4989
+ if (!isInViewport || !intersectionEntry.isIntersecting) {
4990
+ actionListItemRef.current.scrollIntoView({
4991
+ inline: 'nearest',
4992
+ block: rect.top <= 0 ? 'end' : 'nearest'
4993
+ });
4994
+ }
4995
+ }, [isActive]);
4996
+ var allowsSelection = !!selectionType;
4997
+ var isSelected = allowsSelection ? !!selected : undefined;
4998
+ return (React__default["default"].createElement(ListboxOption, tslib.__assign({ as: Component, ref: actionListItemRef, id: id, role: listItemRole, className: classNames__default["default"]('ActionListItem', className), activeClass: "ActionListItem--active", "aria-selected": undefined, "aria-checked": listItemRole !== 'option' ? isSelected : undefined, onClick: handleAction }, props),
4999
+ allowsSelection && (React__default["default"].createElement("span", { className: "ActionListItem__selection" },
5000
+ React__default["default"].createElement(Icon, { type: "check" }))),
5001
+ leadingIcon && (React__default["default"].createElement("span", { className: "ActionListItem__leadingIcon" },
5002
+ React__default["default"].createElement(Icon, { type: leadingIcon }))),
5003
+ React__default["default"].createElement("div", { className: "ActionListItem__label", ref: labelRef }, children),
5004
+ description && (React__default["default"].createElement("div", { className: "ActionListItem__description" }, description)),
5005
+ trailingIcon && (React__default["default"].createElement("span", { className: "ActionListItem__trailingIcon" },
5006
+ React__default["default"].createElement(Icon, { type: trailingIcon })))));
5007
+ });
5008
+ ActionListItem.displayName = 'ActionListItem';
5009
+
5010
+ var ActionListGroup = React.forwardRef(function (_a, ref) {
5011
+ var propId = _a.id, label = _a.label, children = _a.children, selectionType = _a.selectionType, onAction = _a.onAction, props = tslib.__rest(_a, ["id", "label", "children", "selectionType", "onAction"]);
5012
+ var _b = tslib.__read(propId ? [propId] : nextId.useId(1, 'actionlist-group-label'), 1), id = _b[0];
5013
+ var actionListContext = useActionListContext();
5014
+ var handleAction = React.useCallback(function (key, event) {
5015
+ // istanbul ignore else
5016
+ if (typeof onAction === 'function') {
5017
+ onAction(key, event);
5018
+ }
5019
+ // istanbul ignore else
5020
+ if (typeof actionListContext.onAction === 'function') {
5021
+ actionListContext.onAction(key, event);
5022
+ }
5023
+ }, [onAction, actionListContext.onAction]);
5024
+ var listItemRole = [
5025
+ 'menu',
5026
+ 'listbox'
5027
+ ].includes(actionListContext.role)
5028
+ ? 'none'
5029
+ : undefined;
5030
+ var groupRole = ['menu', 'listbox'].includes(actionListContext.role)
5031
+ ? 'group'
5032
+ : 'list';
5033
+ return (React__default["default"].createElement("li", tslib.__assign({ ref: ref, role: listItemRole }, props),
5034
+ React__default["default"].createElement(ListboxGroup, { id: id, role: groupRole, className: "ActionListGroup", label: label, as: "ul" },
5035
+ React__default["default"].createElement(ActionListProvider, tslib.__assign({}, actionListContext, { onAction: handleAction, selectionType: selectionType || actionListContext.selectionType }), children))));
5036
+ });
5037
+ ActionListGroup.displayName = 'ActionListGroup';
5038
+
5039
+ var ActionListSeparator = React.forwardRef(function (_a, ref) {
5040
+ var className = _a.className, props = tslib.__rest(_a, ["className"]);
5041
+ var contextRole = useActionListContext().role;
5042
+ // list and listbox roles only support listitem or option roles respectively
5043
+ // see https://github.com/w3c/aria/issues/1889
5044
+ var separatorRole = ['list', 'listbox'].includes(contextRole)
5045
+ ? 'presentation'
5046
+ : 'separator';
5047
+ return (React__default["default"].createElement("li", tslib.__assign({ ref: ref, className: classNames__default["default"]('ActionListSeparator', className), role: separatorRole, "aria-hidden": separatorRole === 'presentation' || undefined }, props)));
5048
+ });
5049
+ ActionListSeparator.displayName = 'ActionListSeparator';
5050
+
5051
+ var ActionListLinkItem = React.forwardRef(function (_a, ref) {
5052
+ var key = _a.key, className = _a.className;
5053
+ // ActionListLinkItem should not be able to be "selected"
5054
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
5055
+ _a.selected; var props = tslib.__rest(_a, ["key", "className", "selected"]);
5056
+ var contextRole = useActionListContext().role;
5057
+ var listItemRole = React.useMemo(function () {
5058
+ if (contextRole === 'menu') {
5059
+ return 'menuitem';
5060
+ }
5061
+ // istanbul ignore next
5062
+ if (contextRole && process.env.NODE_ENV !== 'production') {
5063
+ console.warn('Use of ActionListLinkItem outside of a menu is unsupported and may result in unintentional accessibility issues.');
5064
+ }
5065
+ return undefined;
5066
+ }, [contextRole]);
5067
+ return (React__default["default"].createElement(ActionListItem, tslib.__assign({ key: key, ref: ref, className: classNames__default["default"]('Link ActionListLinkItem', className), as: "a", role: listItemRole }, props)));
5068
+ });
5069
+ ActionListLinkItem.displayName = 'ActionListLinkItem';
5070
+
5071
+ var _a = tslib.__read(['ArrowDown', 'ArrowUp'], 2), ArrowDown = _a[0], ArrowUp = _a[1];
5072
+ var ActionMenu = React.forwardRef(function (_a, ref) {
5073
+ var className = _a.className, style = _a.style, trigger = _a.trigger, _b = _a.placement, placement = _b === void 0 ? 'bottom-start' : _b, actionMenuList = _a.children, props = tslib.__rest(_a, ["className", "style", "trigger", "placement", "children"]);
5074
+ var _c = tslib.__read(React.useState(false), 2), open = _c[0], setOpen = _c[1];
5075
+ var _d = tslib.__read(React.useState('first'), 2), focusStrategy = _d[0], setFocusStrategy = _d[1];
5076
+ var triggerRef = React.useRef(null);
5077
+ var actionMenuRef = useSharedRef(ref);
5078
+ var actionMenuListRef = useSharedRef(actionMenuList.props.ref);
5079
+ var _e = tslib.__read(nextId.useId(1, 'menu-trigger'), 1), triggerId = _e[0];
5080
+ var handleTriggerClick = React.useCallback(function (event) {
5081
+ // istanbul ignore else
5082
+ if (!event.defaultPrevented) {
5083
+ setOpen(!open);
5084
+ setFocusStrategy('first');
5085
+ }
5086
+ }, [open]);
5087
+ var handleTriggerKeyDown = React.useCallback(function (event) {
5088
+ // istanbul ignore else
5089
+ if ([ArrowDown, ArrowUp].includes(event.key) && !open) {
5090
+ // prevent page from scrolling if the user triggers the action menu
5091
+ // via an "ArrowDown" key press
5092
+ event.preventDefault();
5093
+ // allow other functions that may consume the event after
5094
+ // default is prevented to perform as normal
5095
+ event.defaultPrevented = false;
5096
+ setFocusStrategy(event.key === ArrowUp ? 'last' : 'first');
5097
+ setOpen(true);
5098
+ }
5099
+ }, [open]);
5100
+ var triggerProps = React.useMemo(function () {
5101
+ return {
5102
+ ref: triggerRef,
5103
+ id: triggerId,
5104
+ onClick: handleTriggerClick,
5105
+ onKeyDown: handleTriggerKeyDown,
5106
+ 'aria-expanded': open,
5107
+ 'aria-haspopup': 'menu'
5108
+ };
5109
+ }, [handleTriggerClick, open]);
5110
+ var actionMenuTrigger = React__default["default"].isValidElement(trigger)
5111
+ ? React__default["default"].cloneElement(trigger, triggerProps)
5112
+ : trigger(triggerProps, open);
5113
+ var handleClickOutside = React.useCallback(function (event) {
5114
+ var _a, _b;
5115
+ if (!((_a = actionMenuRef.current) === null || _a === void 0 ? void 0 : _a.contains(event.target)) &&
5116
+ !((_b = triggerRef.current) === null || _b === void 0 ? void 0 : _b.contains(event.target))) {
5117
+ setOpen(false);
5118
+ }
5119
+ }, []);
5120
+ var handleAction = React.useCallback(function (key, event) {
5121
+ // istanbul ignore else
5122
+ if (!event.defaultPrevented) {
5123
+ setOpen(false);
5124
+ }
5125
+ var onAction = actionMenuList.props.onAction;
5126
+ if (typeof onAction === 'function') {
5127
+ onAction(key, event);
5128
+ }
5129
+ }, [actionMenuList.props.onAction]);
5130
+ React.useEffect(function () {
5131
+ var _a, _b, _c;
5132
+ if (open) {
5133
+ (_a = actionMenuListRef.current) === null || _a === void 0 ? void 0 : _a.focus();
5134
+ }
5135
+ else if ((_b = actionMenuListRef.current) === null || _b === void 0 ? void 0 : _b.contains(document.activeElement)) {
5136
+ (_c = triggerRef.current) === null || _c === void 0 ? void 0 : _c.focus();
5137
+ }
5138
+ }, [open]);
5139
+ return (React__default["default"].createElement(React__default["default"].Fragment, null,
5140
+ React__default["default"].createElement(ClickOutsideListener$1, { onClickOutside: handleClickOutside, mouseEvent: open ? undefined : false, touchEvent: open ? undefined : false }, actionMenuTrigger),
5141
+ React__default["default"].createElement(AnchoredOverlay, tslib.__assign({ ref: actionMenuRef, role: "presentation", className: classNames__default["default"]('ActionMenu', className), open: open, onOpenChange: setOpen, target: triggerRef, placement: placement, offset: 4, style: tslib.__assign({ display: !open ? 'none' : undefined }, style) }, props), React__default["default"].cloneElement(actionMenuList, {
5142
+ ref: actionMenuListRef,
5143
+ role: 'menu',
5144
+ onAction: handleAction,
5145
+ 'aria-labelledby': triggerId,
5146
+ focusStrategy: focusStrategy,
5147
+ focusDisabledOptions: true
5148
+ }))));
5149
+ });
5150
+ ActionMenu.displayName = 'ActionMenu';
5151
+
4817
5152
  var LIGHT_THEME_CLASS = 'cauldron--theme-light';
4818
5153
  var DARK_THEME_CLASS = 'cauldron--theme-dark';
4819
5154
  var ThemeContext = React.createContext({
@@ -4884,6 +5219,12 @@ function useThemeContext() {
4884
5219
  exports.Accordion = Accordion;
4885
5220
  exports.AccordionContent = AccordionContent;
4886
5221
  exports.AccordionTrigger = AccordionTrigger;
5222
+ exports.ActionList = ActionList;
5223
+ exports.ActionListGroup = ActionListGroup;
5224
+ exports.ActionListItem = ActionListItem;
5225
+ exports.ActionListLinkItem = ActionListLinkItem;
5226
+ exports.ActionListSeparator = ActionListSeparator;
5227
+ exports.ActionMenu = ActionMenu;
4887
5228
  exports.Address = Address;
4888
5229
  exports.AddressCityStateZip = AddressCityStateZip;
4889
5230
  exports.AddressLine = AddressLine;
@@ -4919,7 +5260,9 @@ exports.Dialog = Dialog;
4919
5260
  exports.DialogContent = DialogContent;
4920
5261
  exports.DialogFooter = DialogFooter;
4921
5262
  exports.Drawer = Drawer;
5263
+ exports.EmptyState = EmptyState;
4922
5264
  exports.ExpandCollapsePanel = ExpandCollapsePanel;
5265
+ exports.FieldGroup = FieldGroup;
4923
5266
  exports.FieldWrap = FieldWrap;
4924
5267
  exports.Icon = Icon;
4925
5268
  exports.IconButton = IconButton;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deque/cauldron-react",
3
- "version": "6.16.0-canary.d7ad0332",
3
+ "version": "6.16.0-canary.dce6ee58",
4
4
  "license": "MPL-2.0",
5
5
  "description": "Fully accessible react components library for Deque Cauldron",
6
6
  "homepage": "https://cauldron.dequelabs.com/",