@deque/cauldron-react 7.1.0-canary.cdc8a15a → 7.1.0-canary.d650efcc

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,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { type ActionListSelectionType, type onActionCallbackFunction } from './ActionListContext';
3
- interface ActionListProps extends React.HTMLAttributes<HTMLUListElement> {
3
+ interface ActionListProps extends Omit<React.HTMLAttributes<HTMLUListElement>, 'defaultValue' | 'onSelect'> {
4
4
  children: React.ReactNode;
5
5
  /** Limits the amount of selections that can be made within an action list */
6
6
  selectionType?: ActionListSelectionType | null;
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import type { ListboxOption } from './ListboxContext';
3
3
  import type { ListboxValue } from './ListboxOption';
4
- import type { PolymorphicProps, PolymorphicComponent } from '../../utils/polymorphicComponent';
4
+ import type { PolymorphicProps, PolymorphicComponentProps } from '../../utils/polymorphicComponent';
5
5
  interface BaseListboxProps extends PolymorphicProps<Omit<React.HTMLAttributes<HTMLElement>, 'onSelect' | 'defaultValue'>> {
6
6
  navigation?: 'cycle' | 'bound';
7
7
  focusStrategy?: 'lastSelected' | 'first' | 'last';
@@ -30,5 +30,10 @@ interface MultiSelectListboxProps extends BaseListboxProps {
30
30
  value: ListboxValue[];
31
31
  }) => void;
32
32
  }
33
- declare const Listbox: PolymorphicComponent<SingleSelectListboxProps | MultiSelectListboxProps>;
33
+ type ListboxComponent = Omit<React.ForwardRefExoticComponent<SingleSelectListboxProps | MultiSelectListboxProps>, keyof CallableFunction> & {
34
+ <T extends React.ElementType = React.ElementType>(props: PolymorphicComponentProps<MultiSelectListboxProps, T>): React.ReactElement | null;
35
+ <T extends React.ElementType = React.ElementType>(props: PolymorphicComponentProps<SingleSelectListboxProps, T>): React.ReactElement | null;
36
+ <T extends React.ElementType = React.ElementType>(props: PolymorphicComponentProps<SingleSelectListboxProps | MultiSelectListboxProps, T>): React.ReactElement | null;
37
+ };
38
+ declare const Listbox: ListboxComponent;
34
39
  export default Listbox;
@@ -12,6 +12,7 @@ export default class TopBar extends React.Component<MenuBarProps, MenuBarState>
12
12
  thin: boolean;
13
13
  hasTrigger: boolean;
14
14
  };
15
+ private menuBarRef;
15
16
  constructor(props: MenuBarProps);
16
17
  componentDidMount(): void;
17
18
  componentWillUnmount(): void;
@@ -3,6 +3,9 @@ export interface ToastProps extends React.HTMLAttributes<HTMLDivElement> {
3
3
  type: 'confirmation' | 'caution' | 'error' | 'action-needed' | 'info';
4
4
  onDismiss?: () => void;
5
5
  dismissText?: string;
6
+ /**
7
+ * @deprecated Use the forwarded `ref` instead. Will be removed in the next major version.
8
+ */
6
9
  toastRef?: React.Ref<HTMLDivElement>;
7
10
  focus?: boolean;
8
11
  show?: boolean;
@@ -12,8 +15,5 @@ export interface ToastProps extends React.HTMLAttributes<HTMLDivElement> {
12
15
  /**
13
16
  * The cauldron toast notification component
14
17
  */
15
- declare const Toast: {
16
- ({ type, children, onDismiss, dismissText, toastRef, focus, show, dismissible, className, ...otherProps }: ToastProps): React.JSX.Element;
17
- displayName: string;
18
- };
18
+ declare const Toast: React.ForwardRefExoticComponent<ToastProps & React.RefAttributes<HTMLDivElement>>;
19
19
  export default Toast;
package/lib/index.js CHANGED
@@ -672,6 +672,7 @@ var TopBar$1 = /** @class */ (function (_super) {
672
672
  tslib.__extends(TopBar, _super);
673
673
  function TopBar(props) {
674
674
  var _this = _super.call(this, props) || this;
675
+ _this.menuBarRef = React__default["default"].createRef();
675
676
  _this.onResize = function () {
676
677
  var wide = isWide();
677
678
  if (wide === _this.state.wide) {
@@ -720,10 +721,10 @@ var TopBar$1 = /** @class */ (function (_super) {
720
721
  };
721
722
  TopBar.prototype.onKeyDown = function (e) {
722
723
  var key = keyname__default["default"](e.which);
723
- // This is a temporary workaround until have an opportunity to refactor or replace menubar
724
- // see: https://github.com/dequelabs/cauldron/issues/1934
725
- // eslint-disable-next-line react/no-find-dom-node
726
- var menuBarElement = reactDom.findDOMNode(this);
724
+ var menuBarElement = this.menuBarRef.current;
725
+ if (!menuBarElement) {
726
+ return;
727
+ }
727
728
  var menuItems = Array.from(menuBarElement.children);
728
729
  // account for hidden side bar trigger (hamburger)
729
730
  if (this.state.wide && this.props.hasTrigger) {
@@ -750,7 +751,7 @@ var TopBar$1 = /** @class */ (function (_super) {
750
751
  // disabling no-unused-vars to prevent thin/hasTrigger from being passed through to div
751
752
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
752
753
  var _a = this.props, children = _a.children, className = _a.className; _a.thin; _a.hasTrigger; tslib.__rest(_a, ["children", "className", "thin", "hasTrigger"]);
753
- return (React__default["default"].createElement("ul", { role: "menubar", onKeyDown: this.onKeyDown, className: className }, React.Children.map(children, this.renderChild)));
754
+ return (React__default["default"].createElement("ul", { role: "menubar", onKeyDown: this.onKeyDown, className: className, ref: this.menuBarRef }, React.Children.map(children, this.renderChild)));
754
755
  };
755
756
  TopBar.defaultProps = {
756
757
  thin: false,
@@ -2243,14 +2244,22 @@ var useDidUpdate = function (effect, dependencies) {
2243
2244
  /**
2244
2245
  * The cauldron toast notification component
2245
2246
  */
2246
- var Toast = function (_a) {
2247
+ var Toast = React.forwardRef(function (_a, ref) {
2247
2248
  var type = _a.type, children = _a.children, _b = _a.onDismiss, onDismiss = _b === void 0 ? function () {
2248
2249
  // noop
2249
2250
  } : _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 elRef = useSharedRef(ref);
2251
2252
  var isolatorRef = React.useRef(null);
2252
2253
  var timeoutsRef = React.useRef(new Set());
2253
2254
  var _g = tslib.__read(React.useState(show ? 'FadeIn--flex' : 'is--hidden'), 2), animationClass = _g[0], setAnimationClass = _g[1];
2255
+ // Backwards-compat: propagate to the deprecated toastRef prop as well
2256
+ React.useEffect(function () {
2257
+ var _a;
2258
+ if (!toastRef)
2259
+ return;
2260
+ setRef(toastRef, (_a = elRef.current) !== null && _a !== void 0 ? _a : null);
2261
+ return function () { return setRef(toastRef, null); };
2262
+ }, [toastRef]);
2254
2263
  // Timeout because CSS display: none/block and opacity:
2255
2264
  // 0/1 properties cannot be toggled in the same tick
2256
2265
  // see: https://codepen.io/isnerms/pen/eyQaLP
@@ -2324,7 +2333,7 @@ var Toast = function (_a) {
2324
2333
  type !== 'action-needed' && dismissible && (React__default["default"].createElement("button", { type: "button", className: "Toast__dismiss", "aria-label": dismissText, onClick: dismissToast },
2325
2334
  React__default["default"].createElement(Icon, { type: "close" })))),
2326
2335
  scrim));
2327
- };
2336
+ });
2328
2337
  Toast.displayName = 'Toast';
2329
2338
 
2330
2339
  var Link = React.forwardRef(function (_a, ref) {
@@ -4314,6 +4323,17 @@ var Combobox = React.forwardRef(function (_a, ref) {
4314
4323
  return value === lastSelectedValue;
4315
4324
  }) || [], 2), element = _a[0], option = _a[1];
4316
4325
  if (autocomplete === 'manual') {
4326
+ // In multiselect, the listbox manages its own active option via
4327
+ // keyboard navigation. When the last-selected value no longer
4328
+ // matches any option (e.g. after deselecting the only selected
4329
+ // option), preserve the existing active descendant so the next
4330
+ // Enter keypress can re-toggle the highlighted option.
4331
+ if (multiselect &&
4332
+ !element &&
4333
+ activeDescendant &&
4334
+ matchingOptions.has(activeDescendant.element)) {
4335
+ return;
4336
+ }
4317
4337
  setActiveDescendant(!element ? null : tslib.__assign({ element: element }, option));
4318
4338
  }
4319
4339
  else if (autocomplete === 'automatic' &&
@@ -5097,7 +5117,6 @@ function useMnemonics(_a) {
5097
5117
 
5098
5118
  var ActionList = React.forwardRef(function (_a, ref) {
5099
5119
  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"]);
5100
- var actionListContext = useActionListContext();
5101
5120
  var activeElement = React.useRef();
5102
5121
  var _c = tslib.__read(React.useState(), 2), activeOption = _c[0], setActiveOption = _c[1];
5103
5122
  var handleActiveChange = React.useCallback(function (value) {
@@ -5119,12 +5138,7 @@ var ActionList = React.forwardRef(function (_a, ref) {
5119
5138
  ? '[role=menuitem],[role=menuitemcheckbox],[role=menuitemradio]'
5120
5139
  : '[role=option]'
5121
5140
  });
5122
- return (
5123
- // Note: we should be able to use listbox without passing a prop
5124
- // value for "multiselect"
5125
- // see: https://github.com/dequelabs/cauldron/issues/1890
5126
- // @ts-expect-error this should be allowed
5127
- React__default["default"].createElement(Listbox, tslib.__assign({ ref: function (element) {
5141
+ return (React__default["default"].createElement(Listbox, tslib.__assign({ ref: function (element) {
5128
5142
  if (ref) {
5129
5143
  setRef(ref, element);
5130
5144
  }
@@ -5133,7 +5147,7 @@ var ActionList = React.forwardRef(function (_a, ref) {
5133
5147
  /* Listbox comes with an explicit role of "listbox", but we want to either
5134
5148
  * use the role from props, or default to the intrinsic role */
5135
5149
  // eslint-disable-next-line jsx-a11y/aria-role
5136
- role: undefined, "aria-multiselectable": actionListContext.role === 'listbox' ? undefined : null, className: classNames__default["default"]('ActionList', className), activeOption: activeOption }, props, { onActiveChange: handleActiveChange, navigation: "bound" }),
5150
+ role: undefined, "aria-multiselectable": undefined, className: classNames__default["default"]('ActionList', className), activeOption: activeOption }, props, { onActiveChange: handleActiveChange, navigation: "bound" }),
5137
5151
  React__default["default"].createElement(ActionListProvider, { role: props.role || 'list', onAction: handleAction, selectionType: selectionType }, children)));
5138
5152
  });
5139
5153
  ActionList.displayName = 'ActionList';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deque/cauldron-react",
3
- "version": "7.1.0-canary.cdc8a15a",
3
+ "version": "7.1.0-canary.d650efcc",
4
4
  "license": "MPL-2.0",
5
5
  "description": "Fully accessible react components library for Deque Cauldron",
6
6
  "homepage": "https://cauldron.dequelabs.com/",
@@ -41,7 +41,7 @@
41
41
  "@babel/preset-env": "^7.22.10",
42
42
  "@babel/preset-react": "^7.22.5",
43
43
  "@babel/preset-typescript": "^7.22.5",
44
- "@figma/code-connect": "^1.4.4",
44
+ "@figma/code-connect": "^1.4.5",
45
45
  "@rollup/plugin-commonjs": "^14.0.0",
46
46
  "@rollup/plugin-dynamic-import-vars": "^1.4.2",
47
47
  "@rollup/plugin-typescript": "^11.1.2",