downshift 5.1.0 → 5.2.2
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/README.md +24 -15
- package/dist/downshift.cjs.js +317 -219
- package/dist/downshift.esm.js +318 -220
- package/dist/downshift.native.cjs.js +317 -219
- package/dist/downshift.umd.js +317 -219
- package/dist/downshift.umd.js.map +1 -1
- package/dist/downshift.umd.min.js +2 -2
- package/dist/downshift.umd.min.js.map +1 -1
- package/package.json +2 -2
- package/preact/dist/downshift.cjs.js +317 -219
- package/preact/dist/downshift.esm.js +318 -220
- package/preact/dist/downshift.umd.js +317 -219
- package/preact/dist/downshift.umd.js.map +1 -1
- package/preact/dist/downshift.umd.min.js +2 -2
- package/preact/dist/downshift.umd.min.js.map +1 -1
- package/typings/index.d.ts +7 -3
package/dist/downshift.umd.js
CHANGED
|
@@ -1460,7 +1460,8 @@
|
|
|
1460
1460
|
|
|
1461
1461
|
function getA11yStatusMessage(_ref2) {
|
|
1462
1462
|
var isOpen = _ref2.isOpen,
|
|
1463
|
-
resultCount = _ref2.resultCount
|
|
1463
|
+
resultCount = _ref2.resultCount,
|
|
1464
|
+
previousResultCount = _ref2.previousResultCount;
|
|
1464
1465
|
|
|
1465
1466
|
if (!isOpen) {
|
|
1466
1467
|
return '';
|
|
@@ -1470,7 +1471,11 @@
|
|
|
1470
1471
|
return 'No results are available.';
|
|
1471
1472
|
}
|
|
1472
1473
|
|
|
1473
|
-
|
|
1474
|
+
if (resultCount !== previousResultCount) {
|
|
1475
|
+
return resultCount + " result" + (resultCount === 1 ? ' is' : 's are') + " available, use up and down arrow keys to navigate. Press Enter key to select.";
|
|
1476
|
+
}
|
|
1477
|
+
|
|
1478
|
+
return '';
|
|
1474
1479
|
}
|
|
1475
1480
|
/**
|
|
1476
1481
|
* Takes an argument and if it's an array, returns the first item in the array
|
|
@@ -2954,6 +2959,65 @@
|
|
|
2954
2959
|
inputValue: ''
|
|
2955
2960
|
};
|
|
2956
2961
|
|
|
2962
|
+
function callOnChangeProps(action, state, newState) {
|
|
2963
|
+
var props = action.props,
|
|
2964
|
+
type = action.type;
|
|
2965
|
+
var changes = {};
|
|
2966
|
+
Object.keys(state).forEach(function (key) {
|
|
2967
|
+
invokeOnChangeHandler(key, props, state, newState);
|
|
2968
|
+
|
|
2969
|
+
if (newState[key] !== state[key]) {
|
|
2970
|
+
changes[key] = newState[key];
|
|
2971
|
+
}
|
|
2972
|
+
});
|
|
2973
|
+
|
|
2974
|
+
if (props.onStateChange && Object.keys(changes).length) {
|
|
2975
|
+
props.onStateChange(_extends({
|
|
2976
|
+
type: type
|
|
2977
|
+
}, changes));
|
|
2978
|
+
}
|
|
2979
|
+
}
|
|
2980
|
+
|
|
2981
|
+
function invokeOnChangeHandler(key, props, state, newState) {
|
|
2982
|
+
var handler = "on" + capitalizeString(key) + "Change";
|
|
2983
|
+
|
|
2984
|
+
if (props[handler] && newState[key] !== undefined && newState[key] !== state[key]) {
|
|
2985
|
+
props[handler](newState);
|
|
2986
|
+
}
|
|
2987
|
+
}
|
|
2988
|
+
/**
|
|
2989
|
+
* Default state reducer that returns the changes.
|
|
2990
|
+
*
|
|
2991
|
+
* @param {Object} s state.
|
|
2992
|
+
* @param {Object} a action with changes.
|
|
2993
|
+
* @returns {Object} changes.
|
|
2994
|
+
*/
|
|
2995
|
+
|
|
2996
|
+
|
|
2997
|
+
function stateReducer(s, a) {
|
|
2998
|
+
return a.changes;
|
|
2999
|
+
}
|
|
3000
|
+
/**
|
|
3001
|
+
* Returns a message to be added to aria-live region when item is selected.
|
|
3002
|
+
*
|
|
3003
|
+
* @param {Object} selectionParameters Parameters required to build the message.
|
|
3004
|
+
* @returns {string} The a11y message.
|
|
3005
|
+
*/
|
|
3006
|
+
|
|
3007
|
+
|
|
3008
|
+
function getA11ySelectionMessage(selectionParameters) {
|
|
3009
|
+
var selectedItem = selectionParameters.selectedItem,
|
|
3010
|
+
itemToStringLocal = selectionParameters.itemToString;
|
|
3011
|
+
return selectedItem ? itemToStringLocal(selectedItem) + " has been selected." : '';
|
|
3012
|
+
}
|
|
3013
|
+
/**
|
|
3014
|
+
* Debounced call for updating the a11y message.
|
|
3015
|
+
*/
|
|
3016
|
+
|
|
3017
|
+
|
|
3018
|
+
var updateA11yStatus = debounce(function (getA11yMessage, document) {
|
|
3019
|
+
setStatus(getA11yMessage(), document);
|
|
3020
|
+
}, 200);
|
|
2957
3021
|
function getElementIds(_ref) {
|
|
2958
3022
|
var id = _ref.id,
|
|
2959
3023
|
labelId = _ref.labelId,
|
|
@@ -2970,7 +3034,6 @@
|
|
|
2970
3034
|
toggleButtonId: toggleButtonId || uniqueId + "-toggle-button"
|
|
2971
3035
|
};
|
|
2972
3036
|
}
|
|
2973
|
-
|
|
2974
3037
|
function getItemIndex(index, item, items) {
|
|
2975
3038
|
if (index !== undefined) {
|
|
2976
3039
|
return index;
|
|
@@ -2999,57 +3062,39 @@
|
|
|
2999
3062
|
});
|
|
3000
3063
|
};
|
|
3001
3064
|
}
|
|
3002
|
-
|
|
3003
3065
|
function isAcceptedCharacterKey(key) {
|
|
3004
3066
|
return /^\S{1}$/.test(key);
|
|
3005
3067
|
}
|
|
3006
|
-
|
|
3007
3068
|
function capitalizeString(string) {
|
|
3008
3069
|
return "" + string.slice(0, 1).toUpperCase() + string.slice(1);
|
|
3009
3070
|
}
|
|
3071
|
+
/**
|
|
3072
|
+
* Computes the controlled state using a the previous state, props,
|
|
3073
|
+
* two reducers, one from downshift and an optional one from the user.
|
|
3074
|
+
* Also calls the onChange handlers for state values that have changed.
|
|
3075
|
+
*
|
|
3076
|
+
* @param {Function} reducer Reducer function from downshift.
|
|
3077
|
+
* @param {Object} initialState Initial state of the hook.
|
|
3078
|
+
* @param {Object} props The hook props.
|
|
3079
|
+
* @returns {Array} An array with the state and an action dispatcher.
|
|
3080
|
+
*/
|
|
3010
3081
|
|
|
3011
|
-
function
|
|
3012
|
-
var
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
props[handler](newState);
|
|
3016
|
-
}
|
|
3017
|
-
}
|
|
3018
|
-
|
|
3019
|
-
function callOnChangeProps(action, state, newState) {
|
|
3020
|
-
var props = action.props,
|
|
3021
|
-
type = action.type;
|
|
3022
|
-
var changes = {};
|
|
3023
|
-
Object.keys(state).forEach(function (key) {
|
|
3024
|
-
invokeOnChangeHandler(key, props, state, newState);
|
|
3025
|
-
|
|
3026
|
-
if (newState[key] !== state[key]) {
|
|
3027
|
-
changes[key] = newState[key];
|
|
3028
|
-
}
|
|
3029
|
-
});
|
|
3082
|
+
function useControlledState(reducer, initialState, props) {
|
|
3083
|
+
var _useState = react.useState(initialState),
|
|
3084
|
+
uncontrolledState = _useState[0],
|
|
3085
|
+
setState = _useState[1];
|
|
3030
3086
|
|
|
3031
|
-
|
|
3032
|
-
props.onStateChange(_extends({
|
|
3033
|
-
type: type
|
|
3034
|
-
}, changes));
|
|
3035
|
-
}
|
|
3036
|
-
}
|
|
3087
|
+
var state = getState(uncontrolledState, props);
|
|
3037
3088
|
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
state = getState(state, action.props);
|
|
3041
|
-
var stateReduceLocal = action.props.stateReducer;
|
|
3089
|
+
var dispatch = function (action) {
|
|
3090
|
+
var stateReducerFromProps = action.props.stateReducer;
|
|
3042
3091
|
var changes = reducer(state, action);
|
|
3043
|
-
var newState =
|
|
3092
|
+
var newState = stateReducerFromProps(state, _extends({}, action, {
|
|
3044
3093
|
changes: changes
|
|
3045
3094
|
}));
|
|
3046
3095
|
callOnChangeProps(action, state, newState);
|
|
3047
|
-
|
|
3048
|
-
}
|
|
3049
|
-
|
|
3050
|
-
var _useReducer = react.useReducer(enhancedReducer, initialState),
|
|
3051
|
-
state = _useReducer[0],
|
|
3052
|
-
dispatch = _useReducer[1];
|
|
3096
|
+
setState(newState);
|
|
3097
|
+
};
|
|
3053
3098
|
|
|
3054
3099
|
return [getState(state, props), function dispatchWithProps(action) {
|
|
3055
3100
|
return dispatch(_extends({
|
|
@@ -3057,32 +3102,6 @@
|
|
|
3057
3102
|
}, action));
|
|
3058
3103
|
}];
|
|
3059
3104
|
}
|
|
3060
|
-
/**
|
|
3061
|
-
* Default state reducer that returns the changes.
|
|
3062
|
-
*
|
|
3063
|
-
* @param {Object} s state.
|
|
3064
|
-
* @param {Object} a action with changes.
|
|
3065
|
-
* @returns {Object} changes.
|
|
3066
|
-
*/
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
function stateReducer(s, a) {
|
|
3070
|
-
return a.changes;
|
|
3071
|
-
}
|
|
3072
|
-
/**
|
|
3073
|
-
* Returns a message to be added to aria-live region when item is selected.
|
|
3074
|
-
*
|
|
3075
|
-
* @param {Object} selectionParameters Parameters required to build the message.
|
|
3076
|
-
* @returns {string} The a11y message.
|
|
3077
|
-
*/
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
function getA11ySelectionMessage(selectionParameters) {
|
|
3081
|
-
var selectedItem = selectionParameters.selectedItem,
|
|
3082
|
-
itemToStringLocal = selectionParameters.itemToString;
|
|
3083
|
-
return itemToStringLocal(selectedItem) + " has been selected.";
|
|
3084
|
-
}
|
|
3085
|
-
|
|
3086
3105
|
var defaultProps = {
|
|
3087
3106
|
itemToString: itemToString,
|
|
3088
3107
|
stateReducer: stateReducer,
|
|
@@ -3093,7 +3112,6 @@
|
|
|
3093
3112
|
/* istanbul ignore next (ssr) */
|
|
3094
3113
|
? {} : window
|
|
3095
3114
|
};
|
|
3096
|
-
|
|
3097
3115
|
function getDefaultValue(props, propKey, defaultStateValues) {
|
|
3098
3116
|
if (defaultStateValues === void 0) {
|
|
3099
3117
|
defaultStateValues = dropdownDefaultStateValues;
|
|
@@ -3107,7 +3125,6 @@
|
|
|
3107
3125
|
|
|
3108
3126
|
return defaultStateValues[propKey];
|
|
3109
3127
|
}
|
|
3110
|
-
|
|
3111
3128
|
function getInitialValue(props, propKey, defaultStateValues) {
|
|
3112
3129
|
if (defaultStateValues === void 0) {
|
|
3113
3130
|
defaultStateValues = dropdownDefaultStateValues;
|
|
@@ -3125,7 +3142,6 @@
|
|
|
3125
3142
|
|
|
3126
3143
|
return getDefaultValue(props, propKey, defaultStateValues);
|
|
3127
3144
|
}
|
|
3128
|
-
|
|
3129
3145
|
function getInitialState(props) {
|
|
3130
3146
|
var selectedItem = getInitialValue(props, 'selectedItem');
|
|
3131
3147
|
var isOpen = getInitialValue(props, 'isOpen');
|
|
@@ -3138,7 +3154,6 @@
|
|
|
3138
3154
|
inputValue: inputValue
|
|
3139
3155
|
};
|
|
3140
3156
|
}
|
|
3141
|
-
|
|
3142
3157
|
function getHighlightedIndexOnOpen(props, state, offset, getItemNodeFromIndex) {
|
|
3143
3158
|
var items = props.items,
|
|
3144
3159
|
initialHighlightedIndex = props.initialHighlightedIndex,
|
|
@@ -3245,7 +3260,8 @@
|
|
|
3245
3260
|
|
|
3246
3261
|
function getA11yStatusMessage$1(_ref) {
|
|
3247
3262
|
var isOpen = _ref.isOpen,
|
|
3248
|
-
resultCount = _ref.resultCount
|
|
3263
|
+
resultCount = _ref.resultCount,
|
|
3264
|
+
previousResultCount = _ref.previousResultCount;
|
|
3249
3265
|
|
|
3250
3266
|
if (!isOpen) {
|
|
3251
3267
|
return '';
|
|
@@ -3255,7 +3271,11 @@
|
|
|
3255
3271
|
return 'No results are available.';
|
|
3256
3272
|
}
|
|
3257
3273
|
|
|
3258
|
-
|
|
3274
|
+
if (resultCount !== previousResultCount) {
|
|
3275
|
+
return resultCount + " result" + (resultCount === 1 ? ' is' : 's are') + " available, use up and down arrow keys to navigate. Press Enter or Space Bar keys to select.";
|
|
3276
|
+
}
|
|
3277
|
+
|
|
3278
|
+
return '';
|
|
3259
3279
|
}
|
|
3260
3280
|
|
|
3261
3281
|
var defaultProps$1 = _extends({}, defaultProps, {
|
|
@@ -3502,82 +3522,91 @@
|
|
|
3502
3522
|
var props = _extends({}, defaultProps$1, {}, userProps);
|
|
3503
3523
|
|
|
3504
3524
|
var items = props.items,
|
|
3505
|
-
itemToString = props.itemToString,
|
|
3506
|
-
getA11yStatusMessage = props.getA11yStatusMessage,
|
|
3507
|
-
getA11ySelectionMessage = props.getA11ySelectionMessage,
|
|
3508
3525
|
scrollIntoView = props.scrollIntoView,
|
|
3509
3526
|
environment = props.environment,
|
|
3510
3527
|
initialIsOpen = props.initialIsOpen,
|
|
3511
|
-
defaultIsOpen = props.defaultIsOpen
|
|
3528
|
+
defaultIsOpen = props.defaultIsOpen,
|
|
3529
|
+
itemToString = props.itemToString,
|
|
3530
|
+
getA11ySelectionMessage = props.getA11ySelectionMessage,
|
|
3531
|
+
getA11yStatusMessage = props.getA11yStatusMessage; // Initial state depending on controlled props.
|
|
3512
3532
|
|
|
3513
3533
|
var initialState = getInitialState(props); // Reducer init.
|
|
3514
3534
|
|
|
3515
|
-
var
|
|
3516
|
-
|
|
3517
|
-
isOpen =
|
|
3518
|
-
highlightedIndex =
|
|
3519
|
-
selectedItem =
|
|
3520
|
-
inputValue =
|
|
3521
|
-
dispatch =
|
|
3522
|
-
/* Refs */
|
|
3535
|
+
var _useControlledState = useControlledState(downshiftSelectReducer, initialState, props),
|
|
3536
|
+
_useControlledState$ = _useControlledState[0],
|
|
3537
|
+
isOpen = _useControlledState$.isOpen,
|
|
3538
|
+
highlightedIndex = _useControlledState$.highlightedIndex,
|
|
3539
|
+
selectedItem = _useControlledState$.selectedItem,
|
|
3540
|
+
inputValue = _useControlledState$.inputValue,
|
|
3541
|
+
dispatch = _useControlledState[1]; // Refs
|
|
3523
3542
|
|
|
3524
3543
|
|
|
3525
3544
|
var toggleButtonRef = react.useRef(null);
|
|
3526
3545
|
var menuRef = react.useRef(null);
|
|
3527
|
-
var
|
|
3528
|
-
var
|
|
3529
|
-
var
|
|
3530
|
-
var
|
|
3546
|
+
var isInitialMountRef = react.useRef(true);
|
|
3547
|
+
var shouldScrollRef = react.useRef(true);
|
|
3548
|
+
var shouldBlurRef = react.useRef(true);
|
|
3549
|
+
var clearTimeoutRef = react.useRef(null);
|
|
3550
|
+
var mouseAndTouchTrackersRef = react.useRef({
|
|
3531
3551
|
isMouseDown: false,
|
|
3532
3552
|
isTouchMove: false
|
|
3533
3553
|
});
|
|
3534
|
-
var
|
|
3554
|
+
var elementIdsRef = react.useRef(getElementIds(props));
|
|
3555
|
+
var previousResultCountRef = react.useRef(); // Some utils.
|
|
3535
3556
|
|
|
3536
3557
|
var getItemNodeFromIndex = function (index) {
|
|
3537
|
-
return environment.document.getElementById(
|
|
3558
|
+
return environment.document.getElementById(elementIdsRef.current.getItemId(index));
|
|
3538
3559
|
}; // Effects.
|
|
3539
3560
|
|
|
3540
|
-
/* Sets a11y status message on changes in
|
|
3561
|
+
/* Sets a11y status message on changes in state. */
|
|
3541
3562
|
|
|
3542
3563
|
|
|
3543
3564
|
react.useEffect(function () {
|
|
3544
|
-
if (
|
|
3565
|
+
if (isInitialMountRef.current) {
|
|
3545
3566
|
return;
|
|
3546
3567
|
}
|
|
3547
3568
|
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3569
|
+
var previousResultCount = previousResultCountRef.current;
|
|
3570
|
+
updateA11yStatus(function () {
|
|
3571
|
+
return getA11yStatusMessage({
|
|
3572
|
+
isOpen: isOpen,
|
|
3573
|
+
highlightedIndex: highlightedIndex,
|
|
3574
|
+
selectedItem: selectedItem,
|
|
3575
|
+
inputValue: inputValue,
|
|
3576
|
+
highlightedItem: items[highlightedIndex],
|
|
3577
|
+
resultCount: items.length,
|
|
3578
|
+
itemToString: itemToString,
|
|
3579
|
+
previousResultCount: previousResultCount
|
|
3580
|
+
});
|
|
3581
|
+
}, environment.document); // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3582
|
+
}, [isOpen, highlightedIndex, selectedItem, inputValue]);
|
|
3558
3583
|
/* Sets a11y status message on changes in selectedItem. */
|
|
3559
3584
|
|
|
3560
3585
|
react.useEffect(function () {
|
|
3561
|
-
if (
|
|
3586
|
+
if (isInitialMountRef.current) {
|
|
3562
3587
|
return;
|
|
3563
3588
|
}
|
|
3564
3589
|
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
|
|
3590
|
+
var previousResultCount = previousResultCountRef.current;
|
|
3591
|
+
updateA11yStatus(function () {
|
|
3592
|
+
return getA11ySelectionMessage({
|
|
3593
|
+
isOpen: isOpen,
|
|
3594
|
+
highlightedIndex: highlightedIndex,
|
|
3595
|
+
selectedItem: selectedItem,
|
|
3596
|
+
inputValue: inputValue,
|
|
3597
|
+
highlightedItem: items[highlightedIndex],
|
|
3598
|
+
resultCount: items.length,
|
|
3599
|
+
itemToString: itemToString,
|
|
3600
|
+
previousResultCount: previousResultCount
|
|
3601
|
+
});
|
|
3602
|
+
}, environment.document); // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3574
3603
|
}, [selectedItem]);
|
|
3575
3604
|
/* Sets cleanup for the keysSoFar after 500ms. */
|
|
3576
3605
|
|
|
3577
3606
|
react.useEffect(function () {
|
|
3578
3607
|
// init the clean function here as we need access to dispatch.
|
|
3579
|
-
if (
|
|
3580
|
-
|
|
3608
|
+
if (isInitialMountRef.current) {
|
|
3609
|
+
clearTimeoutRef.current = debounce(function (outerDispatch) {
|
|
3581
3610
|
outerDispatch({
|
|
3582
3611
|
type: FunctionSetInputValue,
|
|
3583
3612
|
inputValue: ''
|
|
@@ -3589,13 +3618,13 @@
|
|
|
3589
3618
|
return;
|
|
3590
3619
|
}
|
|
3591
3620
|
|
|
3592
|
-
|
|
3621
|
+
clearTimeoutRef.current(dispatch); // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3593
3622
|
}, [inputValue]);
|
|
3594
3623
|
/* Controls the focus on the menu or the toggle button. */
|
|
3595
3624
|
|
|
3596
3625
|
react.useEffect(function () {
|
|
3597
3626
|
// Don't focus menu on first render.
|
|
3598
|
-
if (
|
|
3627
|
+
if (isInitialMountRef.current) {
|
|
3599
3628
|
// Unless it was initialised as open.
|
|
3600
3629
|
if ((initialIsOpen || defaultIsOpen || isOpen) && menuRef.current) {
|
|
3601
3630
|
menuRef.current.focus();
|
|
@@ -3603,13 +3632,23 @@
|
|
|
3603
3632
|
|
|
3604
3633
|
return;
|
|
3605
3634
|
} // Focus menu on open.
|
|
3606
|
-
// istanbul ignore next
|
|
3607
3635
|
|
|
3608
3636
|
|
|
3609
|
-
if (isOpen
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3637
|
+
if (isOpen) {
|
|
3638
|
+
// istanbul ignore else
|
|
3639
|
+
if (menuRef.current) {
|
|
3640
|
+
menuRef.current.focus();
|
|
3641
|
+
return;
|
|
3642
|
+
}
|
|
3643
|
+
} // Focus toggleButton on close, but on if was closed with (Shift+)Tab.
|
|
3644
|
+
|
|
3645
|
+
|
|
3646
|
+
if (environment.document.activeElement === menuRef.current) {
|
|
3647
|
+
// istanbul ignore else
|
|
3648
|
+
if (toggleButtonRef.current) {
|
|
3649
|
+
shouldBlurRef.current = false;
|
|
3650
|
+
toggleButtonRef.current.focus();
|
|
3651
|
+
}
|
|
3613
3652
|
} // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3614
3653
|
|
|
3615
3654
|
}, [isOpen]);
|
|
@@ -3620,17 +3659,24 @@
|
|
|
3620
3659
|
return;
|
|
3621
3660
|
}
|
|
3622
3661
|
|
|
3623
|
-
if (
|
|
3624
|
-
|
|
3662
|
+
if (shouldScrollRef.current === false) {
|
|
3663
|
+
shouldScrollRef.current = true;
|
|
3625
3664
|
} else {
|
|
3626
3665
|
scrollIntoView(getItemNodeFromIndex(highlightedIndex), menuRef.current);
|
|
3627
3666
|
} // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3628
3667
|
|
|
3629
3668
|
}, [highlightedIndex]);
|
|
3669
|
+
react.useEffect(function () {
|
|
3670
|
+
if (isInitialMountRef.current) {
|
|
3671
|
+
return;
|
|
3672
|
+
}
|
|
3673
|
+
|
|
3674
|
+
previousResultCountRef.current = items.length;
|
|
3675
|
+
});
|
|
3630
3676
|
/* Make initial ref false. */
|
|
3631
3677
|
|
|
3632
3678
|
react.useEffect(function () {
|
|
3633
|
-
|
|
3679
|
+
isInitialMountRef.current = false;
|
|
3634
3680
|
}, []);
|
|
3635
3681
|
/* Add mouse/touch events to document. */
|
|
3636
3682
|
|
|
@@ -3638,11 +3684,11 @@
|
|
|
3638
3684
|
// The same strategy for checking if a click occurred inside or outside downsift
|
|
3639
3685
|
// as in downshift.js.
|
|
3640
3686
|
var onMouseDown = function () {
|
|
3641
|
-
|
|
3687
|
+
mouseAndTouchTrackersRef.current.isMouseDown = true;
|
|
3642
3688
|
};
|
|
3643
3689
|
|
|
3644
3690
|
var onMouseUp = function (event) {
|
|
3645
|
-
|
|
3691
|
+
mouseAndTouchTrackersRef.current.isMouseDown = false;
|
|
3646
3692
|
|
|
3647
3693
|
if (isOpen && !targetWithinDownshift(event.target, [toggleButtonRef.current, menuRef.current], environment.document)) {
|
|
3648
3694
|
dispatch({
|
|
@@ -3652,15 +3698,15 @@
|
|
|
3652
3698
|
};
|
|
3653
3699
|
|
|
3654
3700
|
var onTouchStart = function () {
|
|
3655
|
-
|
|
3701
|
+
mouseAndTouchTrackersRef.current.isTouchMove = false;
|
|
3656
3702
|
};
|
|
3657
3703
|
|
|
3658
3704
|
var onTouchMove = function () {
|
|
3659
|
-
|
|
3705
|
+
mouseAndTouchTrackersRef.current.isTouchMove = true;
|
|
3660
3706
|
};
|
|
3661
3707
|
|
|
3662
3708
|
var onTouchEnd = function (event) {
|
|
3663
|
-
if (isOpen && !
|
|
3709
|
+
if (isOpen && !mouseAndTouchTrackersRef.current.isTouchMove && !targetWithinDownshift(event.target, [toggleButtonRef.current, menuRef.current], environment.document, false)) {
|
|
3664
3710
|
dispatch({
|
|
3665
3711
|
type: MenuBlur
|
|
3666
3712
|
});
|
|
@@ -3764,7 +3810,13 @@
|
|
|
3764
3810
|
};
|
|
3765
3811
|
|
|
3766
3812
|
var menuHandleBlur = function () {
|
|
3767
|
-
|
|
3813
|
+
// if the blur was a result of selection, we don't trigger this action.
|
|
3814
|
+
if (shouldBlurRef.current === false) {
|
|
3815
|
+
shouldBlurRef.current = true;
|
|
3816
|
+
return;
|
|
3817
|
+
}
|
|
3818
|
+
|
|
3819
|
+
var shouldBlur = !mouseAndTouchTrackersRef.current.isMouseDown;
|
|
3768
3820
|
/* istanbul ignore else */
|
|
3769
3821
|
|
|
3770
3822
|
if (shouldBlur) {
|
|
@@ -3805,7 +3857,7 @@
|
|
|
3805
3857
|
return;
|
|
3806
3858
|
}
|
|
3807
3859
|
|
|
3808
|
-
|
|
3860
|
+
shouldScrollRef.current = false;
|
|
3809
3861
|
dispatch({
|
|
3810
3862
|
type: ItemMouseMove,
|
|
3811
3863
|
index: index
|
|
@@ -3835,7 +3887,7 @@
|
|
|
3835
3887
|
|
|
3836
3888
|
var toggleProps = _extends((_extends3 = {}, _extends3[refKey] = handleRefs(ref, function (toggleButtonNode) {
|
|
3837
3889
|
toggleButtonRef.current = toggleButtonNode;
|
|
3838
|
-
}), _extends3.id =
|
|
3890
|
+
}), _extends3.id = elementIdsRef.current.toggleButtonId, _extends3['aria-haspopup'] = 'listbox', _extends3['aria-expanded'] = isOpen, _extends3['aria-labelledby'] = elementIdsRef.current.labelId + " " + elementIdsRef.current.toggleButtonId, _extends3), rest);
|
|
3839
3891
|
|
|
3840
3892
|
if (!rest.disabled) {
|
|
3841
3893
|
toggleProps.onClick = callAllEventHandlers(onClick, toggleButtonHandleClick);
|
|
@@ -3846,8 +3898,8 @@
|
|
|
3846
3898
|
},
|
|
3847
3899
|
getLabelProps: function getLabelProps(labelProps) {
|
|
3848
3900
|
return _extends({
|
|
3849
|
-
id:
|
|
3850
|
-
htmlFor:
|
|
3901
|
+
id: elementIdsRef.current.labelId,
|
|
3902
|
+
htmlFor: elementIdsRef.current.toggleButtonId
|
|
3851
3903
|
}, labelProps);
|
|
3852
3904
|
},
|
|
3853
3905
|
getMenuProps: function getMenuProps(_temp) {
|
|
@@ -3864,8 +3916,8 @@
|
|
|
3864
3916
|
|
|
3865
3917
|
return _extends((_extends2 = {}, _extends2[refKey] = handleRefs(ref, function (menuNode) {
|
|
3866
3918
|
menuRef.current = menuNode;
|
|
3867
|
-
}), _extends2.id =
|
|
3868
|
-
'aria-activedescendant':
|
|
3919
|
+
}), _extends2.id = elementIdsRef.current.menuId, _extends2.role = 'listbox', _extends2['aria-labelledby'] = elementIdsRef.current.labelId, _extends2.tabIndex = -1, _extends2), isOpen && highlightedIndex > -1 && {
|
|
3920
|
+
'aria-activedescendant': elementIdsRef.current.getItemId(highlightedIndex)
|
|
3869
3921
|
}, {
|
|
3870
3922
|
onMouseLeave: callAllEventHandlers(onMouseLeave, menuHandleMouseLeave),
|
|
3871
3923
|
onKeyDown: callAllEventHandlers(onKeyDown, menuHandleKeyDown),
|
|
@@ -3889,7 +3941,7 @@
|
|
|
3889
3941
|
var itemProps = _extends({
|
|
3890
3942
|
role: 'option',
|
|
3891
3943
|
'aria-selected': "" + (itemIndex === highlightedIndex),
|
|
3892
|
-
id:
|
|
3944
|
+
id: elementIdsRef.current.getItemId(itemIndex)
|
|
3893
3945
|
}, rest);
|
|
3894
3946
|
|
|
3895
3947
|
if (!rest.disabled) {
|
|
@@ -3950,6 +4002,51 @@
|
|
|
3950
4002
|
};
|
|
3951
4003
|
}
|
|
3952
4004
|
|
|
4005
|
+
var InputKeyDownArrowDown = '__input_keydown_arrow_down__';
|
|
4006
|
+
var InputKeyDownArrowUp = '__input_keydown_arrow_up__';
|
|
4007
|
+
var InputKeyDownEscape = '__input_keydown_escape__';
|
|
4008
|
+
var InputKeyDownHome = '__input_keydown_home__';
|
|
4009
|
+
var InputKeyDownEnd = '__input_keydown_end__';
|
|
4010
|
+
var InputKeyDownEnter = '__input_keydown_enter__';
|
|
4011
|
+
var InputChange = '__input_change__';
|
|
4012
|
+
var InputBlur = '__input_blur__';
|
|
4013
|
+
var MenuMouseLeave$1 = '__menu_mouse_leave__';
|
|
4014
|
+
var ItemMouseMove$1 = '__item_mouse_move__';
|
|
4015
|
+
var ItemClick$1 = '__item_click__';
|
|
4016
|
+
var ToggleButtonClick$1 = '__togglebutton_click__';
|
|
4017
|
+
var FunctionToggleMenu$1 = '__function_toggle_menu__';
|
|
4018
|
+
var FunctionOpenMenu$1 = '__function_open_menu__';
|
|
4019
|
+
var FunctionCloseMenu$1 = '__function_close_menu__';
|
|
4020
|
+
var FunctionSetHighlightedIndex$1 = '__function_set_highlighted_index__';
|
|
4021
|
+
var FunctionSelectItem$1 = '__function_select_item__';
|
|
4022
|
+
var FunctionSetInputValue$1 = '__function_set_input_value__';
|
|
4023
|
+
var FunctionReset$1 = '__function_reset__';
|
|
4024
|
+
var ControlledPropUpdatedSelectedItem = '__controlled_prop_updated_selected_item__';
|
|
4025
|
+
|
|
4026
|
+
var stateChangeTypes$2 = /*#__PURE__*/Object.freeze({
|
|
4027
|
+
__proto__: null,
|
|
4028
|
+
InputKeyDownArrowDown: InputKeyDownArrowDown,
|
|
4029
|
+
InputKeyDownArrowUp: InputKeyDownArrowUp,
|
|
4030
|
+
InputKeyDownEscape: InputKeyDownEscape,
|
|
4031
|
+
InputKeyDownHome: InputKeyDownHome,
|
|
4032
|
+
InputKeyDownEnd: InputKeyDownEnd,
|
|
4033
|
+
InputKeyDownEnter: InputKeyDownEnter,
|
|
4034
|
+
InputChange: InputChange,
|
|
4035
|
+
InputBlur: InputBlur,
|
|
4036
|
+
MenuMouseLeave: MenuMouseLeave$1,
|
|
4037
|
+
ItemMouseMove: ItemMouseMove$1,
|
|
4038
|
+
ItemClick: ItemClick$1,
|
|
4039
|
+
ToggleButtonClick: ToggleButtonClick$1,
|
|
4040
|
+
FunctionToggleMenu: FunctionToggleMenu$1,
|
|
4041
|
+
FunctionOpenMenu: FunctionOpenMenu$1,
|
|
4042
|
+
FunctionCloseMenu: FunctionCloseMenu$1,
|
|
4043
|
+
FunctionSetHighlightedIndex: FunctionSetHighlightedIndex$1,
|
|
4044
|
+
FunctionSelectItem: FunctionSelectItem$1,
|
|
4045
|
+
FunctionSetInputValue: FunctionSetInputValue$1,
|
|
4046
|
+
FunctionReset: FunctionReset$1,
|
|
4047
|
+
ControlledPropUpdatedSelectedItem: ControlledPropUpdatedSelectedItem
|
|
4048
|
+
});
|
|
4049
|
+
|
|
3953
4050
|
function getElementIds$1(_ref) {
|
|
3954
4051
|
var id = _ref.id,
|
|
3955
4052
|
inputId = _ref.inputId,
|
|
@@ -3962,7 +4059,6 @@
|
|
|
3962
4059
|
id: id
|
|
3963
4060
|
}, rest)));
|
|
3964
4061
|
}
|
|
3965
|
-
|
|
3966
4062
|
function getInitialState$1(props) {
|
|
3967
4063
|
var initialState = getInitialState(props);
|
|
3968
4064
|
var selectedItem = initialState.selectedItem;
|
|
@@ -3976,7 +4072,6 @@
|
|
|
3976
4072
|
inputValue: inputValue
|
|
3977
4073
|
});
|
|
3978
4074
|
}
|
|
3979
|
-
|
|
3980
4075
|
var propTypes$2 = {
|
|
3981
4076
|
items: propTypes.array.isRequired,
|
|
3982
4077
|
itemToString: propTypes.func,
|
|
@@ -4017,55 +4112,43 @@
|
|
|
4017
4112
|
})
|
|
4018
4113
|
})
|
|
4019
4114
|
};
|
|
4115
|
+
/**
|
|
4116
|
+
* The useCombobox version of useControlledState, which also
|
|
4117
|
+
* checks if the controlled prop selectedItem changed between
|
|
4118
|
+
* renders. If so, it will also update inputValue with its
|
|
4119
|
+
* string equivalent. It uses the common useControlledState to
|
|
4120
|
+
* compute the rest of the state.
|
|
4121
|
+
*
|
|
4122
|
+
* @param {Function} reducer Reducer function from downshift.
|
|
4123
|
+
* @param {Object} initialState Initial state of the hook.
|
|
4124
|
+
* @param {Object} props The hook props.
|
|
4125
|
+
* @returns {Array} An array with the state and an action dispatcher.
|
|
4126
|
+
*/
|
|
4127
|
+
|
|
4128
|
+
function useControlledState$1(reducer, initialState, props) {
|
|
4129
|
+
var _useControlledStateCo = useControlledState(reducer, initialState, props),
|
|
4130
|
+
newState = _useControlledStateCo[0],
|
|
4131
|
+
dispatch = _useControlledStateCo[1];
|
|
4132
|
+
|
|
4133
|
+
var previousSelectedItemRef = react.useRef(null);
|
|
4134
|
+
var selectedItem = props.selectedItem,
|
|
4135
|
+
itemToString = props.itemToString; // ToDo: if needed, make same approach as selectedItemChanged from Downshift.
|
|
4020
4136
|
|
|
4137
|
+
if (isControlledProp(props, 'selectedItem') && previousSelectedItemRef.current !== selectedItem) {
|
|
4138
|
+
dispatch({
|
|
4139
|
+
type: ControlledPropUpdatedSelectedItem,
|
|
4140
|
+
inputValue: itemToString(selectedItem)
|
|
4141
|
+
});
|
|
4142
|
+
}
|
|
4143
|
+
|
|
4144
|
+
previousSelectedItemRef.current = selectedItem;
|
|
4145
|
+
return [newState, dispatch];
|
|
4146
|
+
}
|
|
4021
4147
|
var defaultProps$2 = _extends({}, defaultProps, {
|
|
4022
4148
|
getA11yStatusMessage: getA11yStatusMessage,
|
|
4023
4149
|
circularNavigation: true
|
|
4024
4150
|
});
|
|
4025
4151
|
|
|
4026
|
-
var InputKeyDownArrowDown = '__input_keydown_arrow_down__';
|
|
4027
|
-
var InputKeyDownArrowUp = '__input_keydown_arrow_up__';
|
|
4028
|
-
var InputKeyDownEscape = '__input_keydown_escape__';
|
|
4029
|
-
var InputKeyDownHome = '__input_keydown_home__';
|
|
4030
|
-
var InputKeyDownEnd = '__input_keydown_end__';
|
|
4031
|
-
var InputKeyDownEnter = '__input_keydown_enter__';
|
|
4032
|
-
var InputChange = '__input_change__';
|
|
4033
|
-
var InputBlur = '__input_blur__';
|
|
4034
|
-
var MenuMouseLeave$1 = '__menu_mouse_leave__';
|
|
4035
|
-
var ItemMouseMove$1 = '__item_mouse_move__';
|
|
4036
|
-
var ItemClick$1 = '__item_click__';
|
|
4037
|
-
var ToggleButtonClick$1 = '__togglebutton_click__';
|
|
4038
|
-
var FunctionToggleMenu$1 = '__function_toggle_menu__';
|
|
4039
|
-
var FunctionOpenMenu$1 = '__function_open_menu__';
|
|
4040
|
-
var FunctionCloseMenu$1 = '__function_close_menu__';
|
|
4041
|
-
var FunctionSetHighlightedIndex$1 = '__function_set_highlighted_index__';
|
|
4042
|
-
var FunctionSelectItem$1 = '__function_select_item__';
|
|
4043
|
-
var FunctionSetInputValue$1 = '__function_set_input_value__';
|
|
4044
|
-
var FunctionReset$1 = '__function_reset__';
|
|
4045
|
-
|
|
4046
|
-
var stateChangeTypes$2 = /*#__PURE__*/Object.freeze({
|
|
4047
|
-
__proto__: null,
|
|
4048
|
-
InputKeyDownArrowDown: InputKeyDownArrowDown,
|
|
4049
|
-
InputKeyDownArrowUp: InputKeyDownArrowUp,
|
|
4050
|
-
InputKeyDownEscape: InputKeyDownEscape,
|
|
4051
|
-
InputKeyDownHome: InputKeyDownHome,
|
|
4052
|
-
InputKeyDownEnd: InputKeyDownEnd,
|
|
4053
|
-
InputKeyDownEnter: InputKeyDownEnter,
|
|
4054
|
-
InputChange: InputChange,
|
|
4055
|
-
InputBlur: InputBlur,
|
|
4056
|
-
MenuMouseLeave: MenuMouseLeave$1,
|
|
4057
|
-
ItemMouseMove: ItemMouseMove$1,
|
|
4058
|
-
ItemClick: ItemClick$1,
|
|
4059
|
-
ToggleButtonClick: ToggleButtonClick$1,
|
|
4060
|
-
FunctionToggleMenu: FunctionToggleMenu$1,
|
|
4061
|
-
FunctionOpenMenu: FunctionOpenMenu$1,
|
|
4062
|
-
FunctionCloseMenu: FunctionCloseMenu$1,
|
|
4063
|
-
FunctionSetHighlightedIndex: FunctionSetHighlightedIndex$1,
|
|
4064
|
-
FunctionSelectItem: FunctionSelectItem$1,
|
|
4065
|
-
FunctionSetInputValue: FunctionSetInputValue$1,
|
|
4066
|
-
FunctionReset: FunctionReset$1
|
|
4067
|
-
});
|
|
4068
|
-
|
|
4069
4152
|
/* eslint-disable complexity */
|
|
4070
4153
|
|
|
4071
4154
|
function downshiftUseComboboxReducer(state, action) {
|
|
@@ -4205,6 +4288,7 @@
|
|
|
4205
4288
|
};
|
|
4206
4289
|
break;
|
|
4207
4290
|
|
|
4291
|
+
case ControlledPropUpdatedSelectedItem:
|
|
4208
4292
|
case FunctionSetInputValue$1:
|
|
4209
4293
|
changes = {
|
|
4210
4294
|
inputValue: action.inputValue
|
|
@@ -4245,20 +4329,20 @@
|
|
|
4245
4329
|
defaultIsOpen = props.defaultIsOpen,
|
|
4246
4330
|
items = props.items,
|
|
4247
4331
|
scrollIntoView = props.scrollIntoView,
|
|
4248
|
-
|
|
4332
|
+
environment = props.environment,
|
|
4249
4333
|
getA11yStatusMessage = props.getA11yStatusMessage,
|
|
4250
|
-
|
|
4251
|
-
|
|
4334
|
+
getA11ySelectionMessage = props.getA11ySelectionMessage,
|
|
4335
|
+
itemToString = props.itemToString; // Initial state depending on controlled props.
|
|
4252
4336
|
|
|
4253
4337
|
var initialState = getInitialState$1(props); // Reducer init.
|
|
4254
4338
|
|
|
4255
|
-
var
|
|
4256
|
-
|
|
4257
|
-
isOpen =
|
|
4258
|
-
highlightedIndex =
|
|
4259
|
-
selectedItem =
|
|
4260
|
-
inputValue =
|
|
4261
|
-
dispatch =
|
|
4339
|
+
var _useControlledState = useControlledState$1(downshiftUseComboboxReducer, initialState, props),
|
|
4340
|
+
_useControlledState$ = _useControlledState[0],
|
|
4341
|
+
isOpen = _useControlledState$.isOpen,
|
|
4342
|
+
highlightedIndex = _useControlledState$.highlightedIndex,
|
|
4343
|
+
selectedItem = _useControlledState$.selectedItem,
|
|
4344
|
+
inputValue = _useControlledState$.inputValue,
|
|
4345
|
+
dispatch = _useControlledState[1];
|
|
4262
4346
|
/* Refs */
|
|
4263
4347
|
|
|
4264
4348
|
|
|
@@ -4275,25 +4359,30 @@
|
|
|
4275
4359
|
isTouchMove: false
|
|
4276
4360
|
});
|
|
4277
4361
|
var elementIds = react.useRef(getElementIds$1(props));
|
|
4362
|
+
var previousResultCountRef = react.useRef();
|
|
4278
4363
|
/* Effects */
|
|
4279
4364
|
|
|
4280
|
-
/* Sets a11y status message on changes in
|
|
4365
|
+
/* Sets a11y status message on changes in state. */
|
|
4281
4366
|
|
|
4282
4367
|
react.useEffect(function () {
|
|
4283
4368
|
if (isInitialMount.current) {
|
|
4284
4369
|
return;
|
|
4285
4370
|
}
|
|
4286
4371
|
|
|
4287
|
-
|
|
4288
|
-
|
|
4289
|
-
|
|
4290
|
-
|
|
4291
|
-
|
|
4292
|
-
|
|
4293
|
-
|
|
4294
|
-
|
|
4295
|
-
|
|
4296
|
-
|
|
4372
|
+
var previousResultCount = previousResultCountRef.current;
|
|
4373
|
+
updateA11yStatus(function () {
|
|
4374
|
+
return getA11yStatusMessage({
|
|
4375
|
+
isOpen: isOpen,
|
|
4376
|
+
highlightedIndex: highlightedIndex,
|
|
4377
|
+
selectedItem: selectedItem,
|
|
4378
|
+
inputValue: inputValue,
|
|
4379
|
+
highlightedItem: items[highlightedIndex],
|
|
4380
|
+
resultCount: items.length,
|
|
4381
|
+
itemToString: itemToString,
|
|
4382
|
+
previousResultCount: previousResultCount
|
|
4383
|
+
});
|
|
4384
|
+
}, environment.document); // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
4385
|
+
}, [isOpen, highlightedIndex, selectedItem, inputValue]);
|
|
4297
4386
|
/* Sets a11y status message on changes in selectedItem. */
|
|
4298
4387
|
|
|
4299
4388
|
react.useEffect(function () {
|
|
@@ -4301,15 +4390,19 @@
|
|
|
4301
4390
|
return;
|
|
4302
4391
|
}
|
|
4303
4392
|
|
|
4304
|
-
|
|
4305
|
-
|
|
4306
|
-
|
|
4307
|
-
|
|
4308
|
-
|
|
4309
|
-
|
|
4310
|
-
|
|
4311
|
-
|
|
4312
|
-
|
|
4393
|
+
var previousResultCount = previousResultCountRef.current;
|
|
4394
|
+
updateA11yStatus(function () {
|
|
4395
|
+
return getA11ySelectionMessage({
|
|
4396
|
+
isOpen: isOpen,
|
|
4397
|
+
highlightedIndex: highlightedIndex,
|
|
4398
|
+
selectedItem: selectedItem,
|
|
4399
|
+
inputValue: inputValue,
|
|
4400
|
+
highlightedItem: items[highlightedIndex],
|
|
4401
|
+
resultCount: items.length,
|
|
4402
|
+
itemToString: itemToString,
|
|
4403
|
+
previousResultCount: previousResultCount
|
|
4404
|
+
});
|
|
4405
|
+
}, environment.document); // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
4313
4406
|
}, [selectedItem]);
|
|
4314
4407
|
/* Scroll on highlighted item if change comes from keyboard. */
|
|
4315
4408
|
|
|
@@ -4339,8 +4432,13 @@
|
|
|
4339
4432
|
} // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
4340
4433
|
|
|
4341
4434
|
}, [isOpen]);
|
|
4342
|
-
|
|
4435
|
+
react.useEffect(function () {
|
|
4436
|
+
if (isInitialMount.current) {
|
|
4437
|
+
return;
|
|
4438
|
+
}
|
|
4343
4439
|
|
|
4440
|
+
previousResultCountRef.current = items.length;
|
|
4441
|
+
});
|
|
4344
4442
|
react.useEffect(function () {
|
|
4345
4443
|
isInitialMount.current = false;
|
|
4346
4444
|
}, []);
|
|
@@ -4971,11 +5069,11 @@
|
|
|
4971
5069
|
keyNavigationNext = props.keyNavigationNext,
|
|
4972
5070
|
keyNavigationPrevious = props.keyNavigationPrevious; // Reducer init.
|
|
4973
5071
|
|
|
4974
|
-
var
|
|
4975
|
-
|
|
4976
|
-
activeIndex =
|
|
4977
|
-
selectedItems =
|
|
4978
|
-
dispatch =
|
|
5072
|
+
var _useControlledState = useControlledState(downshiftMultipleSelectionReducer, getInitialState$2(props), props),
|
|
5073
|
+
_useControlledState$ = _useControlledState[0],
|
|
5074
|
+
activeIndex = _useControlledState$.activeIndex,
|
|
5075
|
+
selectedItems = _useControlledState$.selectedItems,
|
|
5076
|
+
dispatch = _useControlledState[1]; // Refs.
|
|
4979
5077
|
|
|
4980
5078
|
|
|
4981
5079
|
var isInitialMount = react.useRef(true);
|