@deque/cauldron-react 7.1.0-canary.383b8920 → 7.1.0-canary.4271d962

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;
package/lib/index.js CHANGED
@@ -807,9 +807,16 @@ function resolveElement(elementOrRef) {
807
807
  return null;
808
808
  }
809
809
 
810
+ function getChildRef(child, version) {
811
+ if (version === void 0) { version = React__default["default"].version; }
812
+ return parseInt(version, 10) >= 19
813
+ ? child.props.ref
814
+ : child.ref;
815
+ }
816
+
810
817
  function ClickOutsideListener(_a, ref) {
811
818
  var children = _a.children, _b = _a.mouseEvent, mouseEvent = _b === void 0 ? 'click' : _b, _c = _a.touchEvent, touchEvent = _c === void 0 ? 'touchend' : _c, target = _a.target, _d = _a.onClickOutside, onClickOutside = _d === void 0 ? function () { return null; } : _d;
812
- var childElementRef = React.useRef();
819
+ var childElementRef = React.useRef(null);
813
820
  var handleEvent = function (event) {
814
821
  if (event.defaultPrevented) {
815
822
  return;
@@ -832,9 +839,8 @@ function ClickOutsideListener(_a, ref) {
832
839
  childElementRef.current = node;
833
840
  // Ref for this component should pass-through to the child node
834
841
  setRef(ref, node);
835
- // If child has its own ref, we want to update
836
- // its ref with the newly cloned node
837
- var childRef = children.ref;
842
+ // Forward the child's own ref. In React 19 ref lives in props; in 16–18 it's element.ref.
843
+ var childRef = getChildRef(children);
838
844
  setRef(childRef, node);
839
845
  };
840
846
  React.useEffect(function () {
@@ -1343,7 +1349,7 @@ var AriaIsolate = /** @class */ (function () {
1343
1349
 
1344
1350
  /**
1345
1351
  * When a component needs to track an internal ref on a component that has a
1346
- * forwarded ref, useSharedRef will return a MutableRefObject<T> that will
1352
+ * forwarded ref, useSharedRef will return a MutableRefObject<T | null> that will
1347
1353
  * correctly invoke the parent ref as well providing an internal ref.
1348
1354
  *
1349
1355
  * @example
@@ -1356,7 +1362,7 @@ var AriaIsolate = /** @class */ (function () {
1356
1362
  * })
1357
1363
  */
1358
1364
  function useSharedRef(ref) {
1359
- var internalRef = React.useRef();
1365
+ var internalRef = React.useRef(null);
1360
1366
  React.useEffect(function () {
1361
1367
  setRef(ref, internalRef.current);
1362
1368
  return function () { return setRef(ref, null); };
@@ -1489,7 +1495,7 @@ function useFocusTrap(target, options) {
1489
1495
  if (options === void 0) { options = {}; }
1490
1496
  var _a = options.disabled, disabled = _a === void 0 ? false : _a, _b = options.returnFocus, returnFocus = _b === void 0 ? true : _b, initialFocusElementOrRef = options.initialFocusElement, returnFocusElement = options.returnFocusElement;
1491
1497
  var focusTrap = React.useRef(null);
1492
- var returnFocusElementRef = React.useRef();
1498
+ var returnFocusElementRef = React.useRef(null);
1493
1499
  function restoreFocusToReturnFocusElement() {
1494
1500
  var _a;
1495
1501
  var resolvedReturnFocusElement = resolveElement(returnFocusElement);
@@ -1539,7 +1545,7 @@ var Dialog = React.forwardRef(function (_a, ref) {
1539
1545
  var dialogRef = useSharedRef(dialogRefProp || ref);
1540
1546
  var _g = tslib.__read(nextId.useId(1, 'dialog-title-'), 1), headingId = _g[0];
1541
1547
  var headingRef = React.useRef(null);
1542
- var isolatorRef = React.useRef();
1548
+ var isolatorRef = React.useRef(null);
1543
1549
  var headingLevel = typeof heading === 'object' && 'level' in heading && heading.level
1544
1550
  ? heading.level
1545
1551
  : 2;
@@ -2134,7 +2140,7 @@ var looksLikeLink = function (props) {
2134
2140
  };
2135
2141
  var IconButton = React.forwardRef(function (_a, ref) {
2136
2142
  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"]);
2137
- var internalRef = React.useRef();
2143
+ var internalRef = React.useRef(null);
2138
2144
  React.useImperativeHandle(ref, function () { return internalRef.current; });
2139
2145
  // Configure additional properties based on the type of the Component
2140
2146
  // for accessibility
@@ -2696,7 +2702,7 @@ Checkbox.displayName = 'Checkbox';
2696
2702
  */
2697
2703
  function TooltipTabstop(_a) {
2698
2704
  var children = _a.children, className = _a.className, tooltip = _a.tooltip, variant = _a.variant, association = _a.association, show = _a.show, placement = _a.placement, portal = _a.portal, hideElementOnHidden = _a.hideElementOnHidden, buttonProps = tslib.__rest(_a, ["children", "className", "tooltip", "variant", "association", "show", "placement", "portal", "hideElementOnHidden"]);
2699
- var buttonRef = React.useRef();
2705
+ var buttonRef = React.useRef(null);
2700
2706
  return (React__default["default"].createElement(React__default["default"].Fragment, null,
2701
2707
  React__default["default"].createElement("button", tslib.__assign({ type: "button", ref: buttonRef, "aria-disabled": "true", className: classNames__default["default"]('TooltipTabstop', className) }, buttonProps), children),
2702
2708
  React__default["default"].createElement(Tooltip, { target: buttonRef, variant: variant, association: association, show: show, placement: placement, portal: portal, hideElementOnHidden: hideElementOnHidden }, tooltip)));
@@ -3950,10 +3956,10 @@ var ListboxOption = React.forwardRef(function (_a, ref) {
3950
3956
  var element = listboxOptionRef.current;
3951
3957
  setOptions(function (options) {
3952
3958
  var e_1, _a;
3953
- var option = { element: element, value: optionValue };
3954
3959
  // istanbul ignore next
3955
3960
  if (!element)
3956
3961
  return options;
3962
+ var option = { element: element, value: optionValue };
3957
3963
  // Elements are frequently appended, so check to see if the newly rendered
3958
3964
  // element follows the last element first before any other checks
3959
3965
  if (!options.length ||
@@ -3990,7 +3996,7 @@ var ListboxOption = React.forwardRef(function (_a, ref) {
3990
3996
  if (disabled) {
3991
3997
  return;
3992
3998
  }
3993
- onSelect({ element: listboxOptionRef.current, value: optionValue });
3999
+ onSelect({ element: event.target, value: optionValue });
3994
4000
  onClick === null || onClick === void 0 ? void 0 : onClick(event);
3995
4001
  }, [optionValue, onSelect, onClick, disabled]);
3996
4002
  return (React__default["default"].createElement(Component, tslib.__assign({ id: id, className: classNames__default["default"](className, (_b = {},
@@ -4140,7 +4146,7 @@ var ComboboxOption = React.forwardRef(function (_a, ref) {
4140
4146
  // istanbul ignore next
4141
4147
  React.useLayoutEffect(function () {
4142
4148
  var intersectionEntry = intersectionRef.current;
4143
- if (!intersectionEntry || !isActive) {
4149
+ if (!intersectionEntry || !isActive || !comboboxOptionRef.current) {
4144
4150
  return;
4145
4151
  }
4146
4152
  var rect = comboboxOptionRef.current.getBoundingClientRect();
@@ -4184,6 +4190,8 @@ var ComboboxOption = React.forwardRef(function (_a, ref) {
4184
4190
  ? propValue
4185
4191
  : (_a = comboboxOptionRef.current) === null || _a === void 0 ? void 0 : _a.innerText;
4186
4192
  setMatchingOptions(function (options) {
4193
+ if (!comboboxOptionRef.current)
4194
+ return options;
4187
4195
  return new Map(options.set(comboboxOptionRef.current, {
4188
4196
  value: comboboxValue_1,
4189
4197
  displayValue: children,
@@ -4323,6 +4331,17 @@ var Combobox = React.forwardRef(function (_a, ref) {
4323
4331
  return value === lastSelectedValue;
4324
4332
  }) || [], 2), element = _a[0], option = _a[1];
4325
4333
  if (autocomplete === 'manual') {
4334
+ // In multiselect, the listbox manages its own active option via
4335
+ // keyboard navigation. When the last-selected value no longer
4336
+ // matches any option (e.g. after deselecting the only selected
4337
+ // option), preserve the existing active descendant so the next
4338
+ // Enter keypress can re-toggle the highlighted option.
4339
+ if (multiselect &&
4340
+ !element &&
4341
+ activeDescendant &&
4342
+ matchingOptions.has(activeDescendant.element)) {
4343
+ return;
4344
+ }
4326
4345
  setActiveDescendant(!element ? null : tslib.__assign({ element: element }, option));
4327
4346
  }
4328
4347
  else if (autocomplete === 'automatic' &&
@@ -4502,6 +4521,7 @@ var Combobox = React.forwardRef(function (_a, ref) {
4502
4521
  });
4503
4522
  }, [disabled, selectedValues, onSelectionChange]);
4504
4523
  var handlePillKeyDown = React.useCallback(function (event) {
4524
+ var _a, _b;
4505
4525
  if (!PillKeys.includes(event.key)) {
4506
4526
  return;
4507
4527
  }
@@ -4519,7 +4539,7 @@ var Combobox = React.forwardRef(function (_a, ref) {
4519
4539
  handleRemovePill(pillsRef.current[focusedIndex], selectedValues[focusedIndex]);
4520
4540
  var nextIndex = focusedIndex + 1;
4521
4541
  if (nextIndex == pillsLength) {
4522
- inputRef.current.focus();
4542
+ (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
4523
4543
  }
4524
4544
  else {
4525
4545
  pillsRef.current[nextIndex].focus();
@@ -4528,7 +4548,7 @@ var Combobox = React.forwardRef(function (_a, ref) {
4528
4548
  else if (isArrowLeft || isArrowRight) {
4529
4549
  var nextIndex = Math.max(focusedIndex + (isArrowLeft ? -1 : 1), 0);
4530
4550
  if (isArrowRight && nextIndex === pillsLength) {
4531
- inputRef.current.focus();
4551
+ (_b = inputRef.current) === null || _b === void 0 ? void 0 : _b.focus();
4532
4552
  }
4533
4553
  else {
4534
4554
  pillsRef.current[nextIndex].focus();
@@ -4816,10 +4836,12 @@ var TextEllipsis = React__default["default"].forwardRef(function (_a, ref) {
4816
4836
  : overflowElement.clientWidth < overflowElement.scrollWidth);
4817
4837
  });
4818
4838
  };
4839
+ if (!sharedRef.current)
4840
+ return;
4819
4841
  var observer = new ResizeObserver(listener);
4820
4842
  observer.observe(sharedRef.current);
4821
4843
  return function () {
4822
- observer === null || observer === void 0 ? void 0 : observer.disconnect();
4844
+ observer.disconnect();
4823
4845
  };
4824
4846
  }, []);
4825
4847
  React.useEffect(function () {
@@ -4864,7 +4886,7 @@ var Drawer = React.forwardRef(function (_a, ref) {
4864
4886
  openRef.current = open;
4865
4887
  }, [open, setIsTransitioning]);
4866
4888
  React.useEffect(function () {
4867
- if (!isModal) {
4889
+ if (!isModal || !drawerRef.current) {
4868
4890
  return;
4869
4891
  }
4870
4892
  var isolator = new AriaIsolate(drawerRef.current);
@@ -5045,7 +5067,7 @@ function getActiveElement(root) {
5045
5067
  */
5046
5068
  function useMnemonics(_a) {
5047
5069
  var elementOrRef = _a.elementOrRef, matchingElementsSelector = _a.matchingElementsSelector, onMatch = _a.onMatch, _b = _a.enabled, enabled = _b === void 0 ? true : _b;
5048
- var containerRef = React.useRef();
5070
+ var containerRef = React.useRef(null);
5049
5071
  React.useEffect(function () {
5050
5072
  if (elementOrRef instanceof HTMLElement) {
5051
5073
  containerRef.current = elementOrRef;
@@ -5055,7 +5077,8 @@ function useMnemonics(_a) {
5055
5077
  }
5056
5078
  }, [elementOrRef]);
5057
5079
  React.useEffect(function () {
5058
- if (!enabled || !containerRef.current) {
5080
+ var listenerTarget = containerRef.current;
5081
+ if (!enabled || !listenerTarget) {
5059
5082
  return;
5060
5083
  }
5061
5084
  var keyboardHandler = function (event) {
@@ -5068,14 +5091,14 @@ function useMnemonics(_a) {
5068
5091
  if (event.key.length !== 1 || !/[a-z\d]/i.test(event.key)) {
5069
5092
  return;
5070
5093
  }
5071
- var container = containerRef.current;
5072
- if (!container) {
5094
+ var currentContainer = containerRef.current;
5095
+ if (!currentContainer) {
5073
5096
  return;
5074
5097
  }
5075
5098
  // Prevent default behavior and stop propagation for mnemonic keys
5076
5099
  event.preventDefault();
5077
5100
  event.stopPropagation();
5078
- var elements = Array.from(container.querySelectorAll(matchingElementsSelector !== null && matchingElementsSelector !== void 0 ? matchingElementsSelector : focusable__default["default"]));
5101
+ var elements = Array.from(currentContainer.querySelectorAll(matchingElementsSelector !== null && matchingElementsSelector !== void 0 ? matchingElementsSelector : focusable__default["default"]));
5079
5102
  var matchingElements = elements.filter(function (element) {
5080
5103
  return getAccessibleLabel(element).toLowerCase()[0] ===
5081
5104
  event.key.toLowerCase();
@@ -5083,7 +5106,7 @@ function useMnemonics(_a) {
5083
5106
  if (!matchingElements.length) {
5084
5107
  return;
5085
5108
  }
5086
- var currentActiveElement = getActiveElement(containerRef.current);
5109
+ var currentActiveElement = getActiveElement(currentContainer);
5087
5110
  var nextActiveElement = null;
5088
5111
  if (currentActiveElement) {
5089
5112
  nextActiveElement = matchingElements.find(function (element) {
@@ -5097,17 +5120,15 @@ function useMnemonics(_a) {
5097
5120
  onMatch(nextActiveElement !== null && nextActiveElement !== void 0 ? nextActiveElement : matchingElements[0]);
5098
5121
  }
5099
5122
  };
5100
- var container = containerRef.current;
5101
- container.addEventListener('keydown', keyboardHandler);
5102
- return function () { return container.removeEventListener('keydown', keyboardHandler); };
5123
+ listenerTarget.addEventListener('keydown', keyboardHandler);
5124
+ return function () { return listenerTarget.removeEventListener('keydown', keyboardHandler); };
5103
5125
  }, [enabled, containerRef, matchingElementsSelector, onMatch]);
5104
5126
  return containerRef;
5105
5127
  }
5106
5128
 
5107
5129
  var ActionList = React.forwardRef(function (_a, ref) {
5108
5130
  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"]);
5109
- var actionListContext = useActionListContext();
5110
- var activeElement = React.useRef();
5131
+ var activeElement = React.useRef(null);
5111
5132
  var _c = tslib.__read(React.useState(), 2), activeOption = _c[0], setActiveOption = _c[1];
5112
5133
  var handleActiveChange = React.useCallback(function (value) {
5113
5134
  activeElement.current = value === null || value === void 0 ? void 0 : value.element;
@@ -5128,12 +5149,7 @@ var ActionList = React.forwardRef(function (_a, ref) {
5128
5149
  ? '[role=menuitem],[role=menuitemcheckbox],[role=menuitemradio]'
5129
5150
  : '[role=option]'
5130
5151
  });
5131
- return (
5132
- // Note: we should be able to use listbox without passing a prop
5133
- // value for "multiselect"
5134
- // see: https://github.com/dequelabs/cauldron/issues/1890
5135
- // @ts-expect-error this should be allowed
5136
- React__default["default"].createElement(Listbox, tslib.__assign({ ref: function (element) {
5152
+ return (React__default["default"].createElement(Listbox, tslib.__assign({ ref: function (element) {
5137
5153
  if (ref) {
5138
5154
  setRef(ref, element);
5139
5155
  }
@@ -5142,7 +5158,7 @@ var ActionList = React.forwardRef(function (_a, ref) {
5142
5158
  /* Listbox comes with an explicit role of "listbox", but we want to either
5143
5159
  * use the role from props, or default to the intrinsic role */
5144
5160
  // eslint-disable-next-line jsx-a11y/aria-role
5145
- role: undefined, "aria-multiselectable": actionListContext.role === 'listbox' ? undefined : null, className: classNames__default["default"]('ActionList', className), activeOption: activeOption }, props, { onActiveChange: handleActiveChange, navigation: "bound" }),
5161
+ role: undefined, "aria-multiselectable": undefined, className: classNames__default["default"]('ActionList', className), activeOption: activeOption }, props, { onActiveChange: handleActiveChange, navigation: "bound" }),
5146
5162
  React__default["default"].createElement(ActionListProvider, { role: props.role || 'list', onAction: handleAction, selectionType: selectionType }, children)));
5147
5163
  });
5148
5164
  ActionList.displayName = 'ActionList';
@@ -5197,7 +5213,7 @@ var ActionListItem = React.forwardRef(function (_a, ref) {
5197
5213
  // istanbul ignore next
5198
5214
  React.useLayoutEffect(function () {
5199
5215
  var intersectionEntry = intersectionRef.current;
5200
- if (!intersectionEntry || !isActive) {
5216
+ if (!intersectionEntry || !isActive || !actionListItemRef.current) {
5201
5217
  return;
5202
5218
  }
5203
5219
  var rect = actionListItemRef.current.getBoundingClientRect();
@@ -0,0 +1,2 @@
1
+ import React from 'react';
2
+ export declare function getChildRef(child: React.ReactElement, version?: string): React.Ref<HTMLElement> | null | undefined;
@@ -1,4 +1,4 @@
1
- import type { RefObject } from 'react';
1
+ import type { MutableRefObject } from 'react';
2
2
  import type { ElementOrRef } from '../types';
3
3
  type useMnemonicsOptions = {
4
4
  /**
@@ -19,7 +19,7 @@ type useMnemonicsOptions = {
19
19
  */
20
20
  enabled?: boolean;
21
21
  };
22
- type useMnemonicsResults<T extends HTMLElement> = RefObject<T>;
22
+ type useMnemonicsResults<T extends HTMLElement> = MutableRefObject<T | null>;
23
23
  /**
24
24
  * A hook that provides mnemonic navigation for keyboard users.
25
25
  *
@@ -1,7 +1,7 @@
1
1
  import { MutableRefObject, Ref } from 'react';
2
2
  /**
3
3
  * When a component needs to track an internal ref on a component that has a
4
- * forwarded ref, useSharedRef will return a MutableRefObject<T> that will
4
+ * forwarded ref, useSharedRef will return a MutableRefObject<T | null> that will
5
5
  * correctly invoke the parent ref as well providing an internal ref.
6
6
  *
7
7
  * @example
@@ -13,4 +13,4 @@ import { MutableRefObject, Ref } from 'react';
13
13
  * return (<div ref={internalRef}>...</div>)
14
14
  * })
15
15
  */
16
- export default function useSharedRef<T>(ref: Ref<T>): MutableRefObject<T>;
16
+ export default function useSharedRef<T>(ref: Ref<T>): MutableRefObject<T | null>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deque/cauldron-react",
3
- "version": "7.1.0-canary.383b8920",
3
+ "version": "7.1.0-canary.4271d962",
4
4
  "license": "MPL-2.0",
5
5
  "description": "Fully accessible react components library for Deque Cauldron",
6
6
  "homepage": "https://cauldron.dequelabs.com/",