@deque/cauldron-react 7.5.0-canary.7edd719e → 7.5.0-canary.a93c1d1c
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.
- package/lib/index.js +33 -12
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -1659,7 +1659,11 @@ var DialogContent = function (_a) {
|
|
|
1659
1659
|
'text--align-left': align === 'left',
|
|
1660
1660
|
'text--align-center': align === 'center',
|
|
1661
1661
|
'text--align-right': align === 'right'
|
|
1662
|
-
}),
|
|
1662
|
+
}),
|
|
1663
|
+
// A keyboard user can only scroll this region if it is tabbable (WCAG
|
|
1664
|
+
// 2.1.1). The rule allows that on role="tabpanel" only. See #680.
|
|
1665
|
+
// eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
|
|
1666
|
+
tabIndex: (context === null || context === void 0 ? void 0 : context.scrollable) ? 0 : undefined }, other), children));
|
|
1663
1667
|
};
|
|
1664
1668
|
DialogContent.displayName = 'DialogContent';
|
|
1665
1669
|
var DialogFooter = function (_a) {
|
|
@@ -3783,6 +3787,20 @@ var Listbox = React.forwardRef(function (_a, ref) {
|
|
|
3783
3787
|
var listboxRef = useSharedRef(ref);
|
|
3784
3788
|
var isControlled = typeof value !== 'undefined';
|
|
3785
3789
|
var isActiveControlled = typeof controlledActiveOption !== 'undefined';
|
|
3790
|
+
var hasActiveChangeHandler = typeof onActiveChange === 'function';
|
|
3791
|
+
React.useEffect(function () {
|
|
3792
|
+
if (process.env.NODE_ENV !== 'production' &&
|
|
3793
|
+
isActiveControlled &&
|
|
3794
|
+
hasActiveChangeHandler) {
|
|
3795
|
+
console.warn('Listbox received both `activeOption` and `onActiveChange`. Do not ' +
|
|
3796
|
+
'write the option reported by `onActiveChange` back into ' +
|
|
3797
|
+
'`activeOption`: the two copies then race, and a stale downward ' +
|
|
3798
|
+
'sync can revert a newer value and re-render without settling. ' +
|
|
3799
|
+
'Let Listbox own the active option, or use `activeOption` only as ' +
|
|
3800
|
+
'a one-shot request. ' +
|
|
3801
|
+
'See https://github.com/dequelabs/cauldron/issues/2512');
|
|
3802
|
+
}
|
|
3803
|
+
}, [isActiveControlled, hasActiveChangeHandler]);
|
|
3786
3804
|
React.useLayoutEffect(function () {
|
|
3787
3805
|
if (!isControlled && selectedOptions.length > 0) {
|
|
3788
3806
|
return;
|
|
@@ -3924,7 +3942,7 @@ var Listbox = React.forwardRef(function (_a, ref) {
|
|
|
3924
3942
|
var firstOption = !focusDisabledOptions
|
|
3925
3943
|
? options.find(function (option) { return !isDisabledOption(option); })
|
|
3926
3944
|
: options[0];
|
|
3927
|
-
if (firstOption) {
|
|
3945
|
+
if (firstOption && firstOption.element !== (activeOption === null || activeOption === void 0 ? void 0 : activeOption.element)) {
|
|
3928
3946
|
setActiveOption(firstOption);
|
|
3929
3947
|
}
|
|
3930
3948
|
return;
|
|
@@ -3933,7 +3951,7 @@ var Listbox = React.forwardRef(function (_a, ref) {
|
|
|
3933
3951
|
var lastOption = !focusDisabledOptions
|
|
3934
3952
|
? tslib.__spreadArray([], tslib.__read(options), false).reverse().find(function (option) { return !isDisabledOption(option); })
|
|
3935
3953
|
: options[options.length - 1];
|
|
3936
|
-
if (lastOption) {
|
|
3954
|
+
if (lastOption && lastOption.element !== (activeOption === null || activeOption === void 0 ? void 0 : activeOption.element)) {
|
|
3937
3955
|
setActiveOption(lastOption);
|
|
3938
3956
|
}
|
|
3939
3957
|
return;
|
|
@@ -5154,21 +5172,24 @@ function useMnemonics(_a) {
|
|
|
5154
5172
|
|
|
5155
5173
|
var ActionList = React.forwardRef(function (_a, ref) {
|
|
5156
5174
|
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"]);
|
|
5157
|
-
|
|
5175
|
+
// Listbox owns the active option. ActionList must not mirror it back down
|
|
5176
|
+
// as a controlled prop: the two copies then race, and a downward sync
|
|
5177
|
+
// carrying an already-stale value can revert a newer one and oscillate.
|
|
5178
|
+
// `activeOption` below is only a one-shot mnemonic request, never a
|
|
5179
|
+
// mirror. See cauldron#2512; cauldron#2522 tracks making `activeOption`
|
|
5180
|
+
// properly controlled so this constraint lives in the interface instead.
|
|
5158
5181
|
var _c = tslib.__read(React.useState(), 2), activeOption = _c[0], setActiveOption = _c[1];
|
|
5159
|
-
var handleActiveChange = React.useCallback(function (value) {
|
|
5160
|
-
activeElement.current = value === null || value === void 0 ? void 0 : value.element;
|
|
5161
|
-
setActiveOption(value);
|
|
5162
|
-
}, []);
|
|
5163
5182
|
var handleAction = React.useCallback(function (key, event) {
|
|
5164
5183
|
if (typeof onAction === 'function') {
|
|
5165
5184
|
onAction(key, event);
|
|
5166
5185
|
}
|
|
5167
5186
|
}, [onAction]);
|
|
5187
|
+
// A new object every match, even for the same element: this is a one-shot
|
|
5188
|
+
// request to Listbox rather than a mirror of its state, so re-using the
|
|
5189
|
+
// previous object would leave the controlled prop unchanged and the
|
|
5190
|
+
// request would never reach Listbox.
|
|
5168
5191
|
var handleMnemonicMatch = React.useCallback(function (element) {
|
|
5169
|
-
setActiveOption(
|
|
5170
|
-
return (prev === null || prev === void 0 ? void 0 : prev.element) === element ? prev : { element: element };
|
|
5171
|
-
});
|
|
5192
|
+
setActiveOption({ element: element });
|
|
5172
5193
|
}, []);
|
|
5173
5194
|
var containerRef = useMnemonics({
|
|
5174
5195
|
onMatch: handleMnemonicMatch,
|
|
@@ -5185,7 +5206,7 @@ var ActionList = React.forwardRef(function (_a, ref) {
|
|
|
5185
5206
|
/* Listbox comes with an explicit role of "listbox", but we want to either
|
|
5186
5207
|
* use the role from props, or default to the intrinsic role */
|
|
5187
5208
|
// eslint-disable-next-line jsx-a11y/aria-role
|
|
5188
|
-
role: undefined, "aria-multiselectable": undefined, className: classNames__default["default"]('ActionList', className), activeOption: activeOption }, props, {
|
|
5209
|
+
role: undefined, "aria-multiselectable": undefined, className: classNames__default["default"]('ActionList', className), activeOption: activeOption }, props, { navigation: "bound" }),
|
|
5189
5210
|
React__default["default"].createElement(ActionListProvider, { role: props.role || 'list', onAction: handleAction, selectionType: selectionType }, children)));
|
|
5190
5211
|
});
|
|
5191
5212
|
ActionList.displayName = 'ActionList';
|
package/package.json
CHANGED