@mui/material 9.0.1 → 9.1.1
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/Accordion/Accordion.d.mts +2 -2
- package/Accordion/Accordion.d.ts +2 -2
- package/Accordion/Accordion.js +3 -2
- package/Accordion/Accordion.mjs +3 -2
- package/AccordionSummary/AccordionSummary.js +27 -29
- package/AccordionSummary/AccordionSummary.mjs +27 -29
- package/Autocomplete/Autocomplete.d.mts +5 -1
- package/Autocomplete/Autocomplete.d.ts +5 -1
- package/Autocomplete/Autocomplete.js +13 -7
- package/Autocomplete/Autocomplete.mjs +13 -7
- package/Backdrop/Backdrop.d.mts +2 -2
- package/Backdrop/Backdrop.d.ts +2 -2
- package/Badge/Badge.js +28 -24
- package/Badge/Badge.mjs +28 -24
- package/BottomNavigationAction/BottomNavigationAction.js +6 -2
- package/BottomNavigationAction/BottomNavigationAction.mjs +6 -2
- package/Button/Button.js +11 -15
- package/Button/Button.mjs +11 -15
- package/ButtonBase/Ripple.js +21 -11
- package/ButtonBase/Ripple.mjs +21 -11
- package/ButtonBase/TouchRipple.js +252 -108
- package/ButtonBase/TouchRipple.mjs +253 -109
- package/CHANGELOG.md +122 -0
- package/CardActionArea/CardActionArea.js +2 -1
- package/CardActionArea/CardActionArea.mjs +2 -1
- package/Chip/Chip.js +2 -1
- package/Chip/Chip.mjs +2 -1
- package/CircularProgress/CircularProgress.js +85 -55
- package/CircularProgress/CircularProgress.mjs +84 -55
- package/Collapse/Collapse.d.mts +15 -3
- package/Collapse/Collapse.d.ts +15 -3
- package/Collapse/Collapse.js +44 -31
- package/Collapse/Collapse.mjs +43 -30
- package/Dialog/Dialog.d.mts +2 -2
- package/Dialog/Dialog.d.ts +2 -2
- package/Dialog/Dialog.js +2 -0
- package/Dialog/Dialog.mjs +2 -0
- package/Drawer/Drawer.d.mts +2 -2
- package/Drawer/Drawer.d.ts +2 -2
- package/Fab/Fab.js +2 -1
- package/Fab/Fab.mjs +2 -1
- package/Fade/Fade.d.mts +15 -2
- package/Fade/Fade.d.ts +15 -2
- package/Fade/Fade.js +46 -19
- package/Fade/Fade.mjs +45 -18
- package/FilledInput/FilledInput.js +4 -3
- package/FilledInput/FilledInput.mjs +4 -3
- package/Grow/Grow.d.mts +15 -2
- package/Grow/Grow.d.ts +15 -2
- package/Grow/Grow.js +45 -28
- package/Grow/Grow.mjs +44 -27
- package/IconButton/IconButton.js +2 -1
- package/IconButton/IconButton.mjs +2 -1
- package/InitColorSchemeScript/InitColorSchemeScript.d.mts +5 -5
- package/InitColorSchemeScript/InitColorSchemeScript.d.ts +5 -5
- package/Input/Input.js +3 -2
- package/Input/Input.mjs +3 -2
- package/InputBase/InputBase.js +2 -1
- package/InputBase/InputBase.mjs +2 -1
- package/InputLabel/InputLabel.js +2 -1
- package/InputLabel/InputLabel.mjs +2 -1
- package/LICENSE +1 -1
- package/LinearProgress/LinearProgress.js +187 -120
- package/LinearProgress/LinearProgress.mjs +186 -120
- package/ListItem/ListItem.js +2 -1
- package/ListItem/ListItem.mjs +2 -1
- package/ListItemButton/ListItemButton.js +2 -1
- package/ListItemButton/ListItemButton.mjs +2 -1
- package/Menu/Menu.d.mts +1 -1
- package/Menu/Menu.d.ts +1 -1
- package/MobileStepper/MobileStepper.js +2 -1
- package/MobileStepper/MobileStepper.mjs +2 -1
- package/OutlinedInput/NotchedOutline.js +4 -3
- package/OutlinedInput/NotchedOutline.mjs +4 -3
- package/PaginationItem/PaginationItem.js +2 -1
- package/PaginationItem/PaginationItem.mjs +2 -1
- package/Paper/Paper.js +2 -1
- package/Paper/Paper.mjs +2 -1
- package/Popover/Popover.d.mts +1 -1
- package/Popover/Popover.d.ts +1 -1
- package/README.md +3 -2
- package/Radio/RadioButtonIcon.js +3 -2
- package/Radio/RadioButtonIcon.mjs +3 -2
- package/Rating/Rating.js +2 -1
- package/Rating/Rating.mjs +2 -1
- package/Select/SelectInput.js +115 -25
- package/Select/SelectInput.mjs +115 -25
- package/Select/utils/SelectFocusSourceContext.d.mts +2 -2
- package/Select/utils/SelectFocusSourceContext.d.ts +2 -2
- package/Select/utils/closedTypeahead.js +73 -0
- package/Select/utils/closedTypeahead.mjs +63 -0
- package/Skeleton/Skeleton.js +22 -2
- package/Skeleton/Skeleton.mjs +22 -2
- package/Slide/Slide.d.mts +15 -2
- package/Slide/Slide.d.ts +15 -2
- package/Slide/Slide.js +53 -25
- package/Slide/Slide.mjs +52 -24
- package/Slider/Slider.js +4 -3
- package/Slider/Slider.mjs +4 -3
- package/Slider/SliderValueLabel.d.mts +2 -2
- package/Slider/SliderValueLabel.d.ts +2 -2
- package/Slider/useSlider.js +1 -1
- package/Slider/useSlider.mjs +1 -1
- package/Snackbar/Snackbar.d.mts +2 -2
- package/Snackbar/Snackbar.d.ts +2 -2
- package/SpeedDial/SpeedDial.d.mts +1 -1
- package/SpeedDial/SpeedDial.d.ts +1 -1
- package/SpeedDial/SpeedDial.js +6 -2
- package/SpeedDial/SpeedDial.mjs +6 -2
- package/SpeedDialAction/SpeedDialAction.js +11 -2
- package/SpeedDialAction/SpeedDialAction.mjs +12 -3
- package/SpeedDialIcon/SpeedDialIcon.js +40 -37
- package/SpeedDialIcon/SpeedDialIcon.mjs +40 -37
- package/Step/Step.js +47 -15
- package/Step/Step.mjs +47 -15
- package/Step/StepContext.d.mts +1 -1
- package/Step/StepContext.d.ts +1 -1
- package/StepButton/StepButton.js +9 -3
- package/StepButton/StepButton.mjs +9 -3
- package/StepConnector/StepConnector.js +10 -0
- package/StepConnector/StepConnector.mjs +10 -0
- package/StepContent/StepContent.d.mts +2 -2
- package/StepContent/StepContent.d.ts +2 -2
- package/StepContent/StepContent.js +26 -2
- package/StepContent/StepContent.mjs +26 -2
- package/StepIcon/StepIcon.js +2 -1
- package/StepIcon/StepIcon.mjs +2 -1
- package/StepLabel/StepLabel.js +52 -7
- package/StepLabel/StepLabel.mjs +52 -7
- package/Stepper/Stepper.d.mts +2 -0
- package/Stepper/Stepper.d.ts +2 -0
- package/Stepper/Stepper.js +18 -0
- package/Stepper/Stepper.mjs +18 -0
- package/Stepper/StepperContext.d.mts +1 -1
- package/Stepper/StepperContext.d.ts +1 -1
- package/SvgIcon/SvgIcon.js +2 -1
- package/SvgIcon/SvgIcon.mjs +2 -1
- package/SwipeableDrawer/SwipeableDrawer.js +14 -3
- package/SwipeableDrawer/SwipeableDrawer.mjs +14 -3
- package/Switch/Switch.js +3 -2
- package/Switch/Switch.mjs +3 -2
- package/TableSortLabel/TableSortLabel.js +2 -1
- package/TableSortLabel/TableSortLabel.mjs +2 -1
- package/Tabs/Tabs.js +14 -3
- package/Tabs/Tabs.mjs +14 -3
- package/Tooltip/Tooltip.d.mts +2 -2
- package/Tooltip/Tooltip.d.ts +2 -2
- package/Tooltip/Tooltip.js +3 -0
- package/Tooltip/Tooltip.mjs +3 -0
- package/Unstable_TrapFocus/FocusTrap.js +42 -8
- package/Unstable_TrapFocus/FocusTrap.mjs +42 -8
- package/Zoom/Zoom.d.mts +15 -2
- package/Zoom/Zoom.d.ts +15 -2
- package/Zoom/Zoom.js +43 -16
- package/Zoom/Zoom.mjs +42 -15
- package/index.js +1 -1
- package/index.mjs +1 -1
- package/internal/Transition.d.mts +34 -0
- package/internal/Transition.d.ts +34 -0
- package/internal/Transition.js +450 -0
- package/internal/Transition.mjs +442 -0
- package/internal/react-transition-group.d.mts +8 -0
- package/internal/react-transition-group.d.ts +8 -0
- package/package.json +7 -7
- package/styles/ThemeProviderWithVars.d.mts +7 -7
- package/styles/ThemeProviderWithVars.d.ts +7 -7
- package/styles/createGetSelector.d.mts +2 -2
- package/styles/createGetSelector.d.ts +2 -2
- package/styles/createMotion.d.mts +8 -0
- package/styles/createMotion.d.ts +8 -0
- package/styles/createMotion.js +13 -0
- package/styles/createMotion.mjs +7 -0
- package/styles/createThemeFoundation.d.mts +2 -0
- package/styles/createThemeFoundation.d.ts +2 -0
- package/styles/createThemeNoVars.d.mts +3 -0
- package/styles/createThemeNoVars.d.ts +3 -0
- package/styles/createThemeNoVars.js +5 -0
- package/styles/createThemeNoVars.mjs +5 -0
- package/styles/createTransitions.d.mts +6 -2
- package/styles/createTransitions.d.ts +6 -2
- package/styles/createTransitions.js +12 -4
- package/styles/createTransitions.mjs +12 -4
- package/styles/enhanceHighContrast.d.mts +70 -0
- package/styles/enhanceHighContrast.d.ts +70 -0
- package/styles/enhanceHighContrast.js +502 -0
- package/styles/enhanceHighContrast.mjs +495 -0
- package/styles/identifier.d.mts +1 -1
- package/styles/identifier.d.ts +1 -1
- package/styles/index.d.mts +2 -0
- package/styles/index.d.ts +2 -0
- package/styles/index.js +8 -0
- package/styles/index.mjs +1 -0
- package/styles/reducedMotion.d.mts +7 -0
- package/styles/reducedMotion.d.ts +7 -0
- package/styles/reducedMotion.js +21 -0
- package/styles/reducedMotion.mjs +14 -0
- package/styles/shouldSkipGeneratingVar.js +1 -1
- package/styles/shouldSkipGeneratingVar.mjs +1 -1
- package/styles/stringifyTheme.js +1 -0
- package/styles/stringifyTheme.mjs +1 -0
- package/transitions/index.d.mts +1 -1
- package/transitions/index.d.ts +1 -1
- package/transitions/index.js +0 -11
- package/transitions/index.mjs +1 -1
- package/transitions/transition.d.mts +1 -12
- package/transitions/transition.d.ts +1 -12
- package/transitions/types.d.mts +73 -0
- package/transitions/types.d.ts +73 -0
- package/transitions/useReducedMotion.d.mts +14 -0
- package/transitions/useReducedMotion.d.ts +14 -0
- package/transitions/useReducedMotion.js +117 -0
- package/transitions/useReducedMotion.mjs +110 -0
- package/transitions/utils.d.mts +34 -2
- package/transitions/utils.d.ts +34 -2
- package/transitions/utils.js +33 -4
- package/transitions/utils.mjs +31 -4
- package/useAutocomplete/useAutocomplete.d.mts +8 -1
- package/useAutocomplete/useAutocomplete.d.ts +8 -1
- package/useAutocomplete/useAutocomplete.js +66 -4
- package/useAutocomplete/useAutocomplete.mjs +66 -4
- package/utils/memoTheme.d.mts +1 -1
- package/utils/memoTheme.d.ts +1 -1
- package/utils/useSlot.d.mts +1 -1
- package/utils/useSlot.d.ts +1 -1
- package/version/index.js +2 -2
- package/version/index.mjs +2 -2
- /package/transitions/{transition.js → types.js} +0 -0
- /package/transitions/{transition.mjs → types.mjs} +0 -0
package/Popover/Popover.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { Theme } from "../styles/index.js";
|
|
|
6
6
|
import { InternalStandardProps as StandardProps } from "../internal/index.js";
|
|
7
7
|
import { PaperProps } from "../Paper/index.js";
|
|
8
8
|
import { ModalProps } from "../Modal/index.js";
|
|
9
|
-
import { TransitionProps } from "../transitions/
|
|
9
|
+
import { TransitionProps } from "../transitions/types.js";
|
|
10
10
|
import { PopoverClasses } from "./popoverClasses.js";
|
|
11
11
|
import { CreateSlotsAndSlotProps, SlotProps } from "../utils/types.js";
|
|
12
12
|
export interface PopoverSlots {
|
package/README.md
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
<!-- #host-reference -->
|
|
2
|
-
<!--
|
|
2
|
+
<!-- lint disable mui-first-block-heading -->
|
|
3
|
+
|
|
3
4
|
<p align="center">
|
|
4
|
-
<a href="https://mui.com/material-ui/"
|
|
5
|
+
<a href="https://mui.com/material-ui/" target="_blank"><img width="150" height="133" src="https://mui.com/static/logo.svg" alt="Material UI logo"></a>
|
|
5
6
|
</p>
|
|
6
7
|
|
|
7
8
|
<h1 align="center">Material UI</h1>
|
package/Radio/RadioButtonIcon.js
CHANGED
|
@@ -12,6 +12,7 @@ var _RadioButtonChecked = _interopRequireDefault(require("../internal/svg-icons/
|
|
|
12
12
|
var _rootShouldForwardProp = _interopRequireDefault(require("../styles/rootShouldForwardProp"));
|
|
13
13
|
var _zeroStyled = require("../zero-styled");
|
|
14
14
|
var _memoTheme = _interopRequireDefault(require("../utils/memoTheme"));
|
|
15
|
+
var _utils = require("../transitions/utils");
|
|
15
16
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
16
17
|
const RadioButtonIconRoot = (0, _zeroStyled.styled)('span', {
|
|
17
18
|
name: 'MuiRadioButtonIcon',
|
|
@@ -34,7 +35,7 @@ const RadioButtonIconDot = (0, _zeroStyled.styled)(_RadioButtonChecked.default,
|
|
|
34
35
|
left: 0,
|
|
35
36
|
position: 'absolute',
|
|
36
37
|
transform: 'scale(0)',
|
|
37
|
-
|
|
38
|
+
...(0, _utils.getTransitionStyles)(theme, 'transform', {
|
|
38
39
|
easing: theme.transitions.easing.easeIn,
|
|
39
40
|
duration: theme.transitions.duration.shortest
|
|
40
41
|
}),
|
|
@@ -44,7 +45,7 @@ const RadioButtonIconDot = (0, _zeroStyled.styled)(_RadioButtonChecked.default,
|
|
|
44
45
|
},
|
|
45
46
|
style: {
|
|
46
47
|
transform: 'scale(1)',
|
|
47
|
-
|
|
48
|
+
...(0, _utils.getTransitionStyles)(theme, 'transform', {
|
|
48
49
|
easing: theme.transitions.easing.easeOut,
|
|
49
50
|
duration: theme.transitions.duration.shortest
|
|
50
51
|
})
|
|
@@ -6,6 +6,7 @@ import RadioButtonCheckedIcon from "../internal/svg-icons/RadioButtonChecked.mjs
|
|
|
6
6
|
import rootShouldForwardProp from "../styles/rootShouldForwardProp.mjs";
|
|
7
7
|
import { styled } from "../zero-styled/index.mjs";
|
|
8
8
|
import memoTheme from "../utils/memoTheme.mjs";
|
|
9
|
+
import { getTransitionStyles } from "../transitions/utils.mjs";
|
|
9
10
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
10
11
|
const RadioButtonIconRoot = styled('span', {
|
|
11
12
|
name: 'MuiRadioButtonIcon',
|
|
@@ -28,7 +29,7 @@ const RadioButtonIconDot = styled(RadioButtonCheckedIcon, {
|
|
|
28
29
|
left: 0,
|
|
29
30
|
position: 'absolute',
|
|
30
31
|
transform: 'scale(0)',
|
|
31
|
-
|
|
32
|
+
...getTransitionStyles(theme, 'transform', {
|
|
32
33
|
easing: theme.transitions.easing.easeIn,
|
|
33
34
|
duration: theme.transitions.duration.shortest
|
|
34
35
|
}),
|
|
@@ -38,7 +39,7 @@ const RadioButtonIconDot = styled(RadioButtonCheckedIcon, {
|
|
|
38
39
|
},
|
|
39
40
|
style: {
|
|
40
41
|
transform: 'scale(1)',
|
|
41
|
-
|
|
42
|
+
...getTransitionStyles(theme, 'transform', {
|
|
42
43
|
easing: theme.transitions.easing.easeOut,
|
|
43
44
|
duration: theme.transitions.duration.shortest
|
|
44
45
|
})
|
package/Rating/Rating.js
CHANGED
|
@@ -26,6 +26,7 @@ var _DefaultPropsProvider = require("../DefaultPropsProvider");
|
|
|
26
26
|
var _slotShouldForwardProp = _interopRequireDefault(require("../styles/slotShouldForwardProp"));
|
|
27
27
|
var _ratingClasses = _interopRequireWildcard(require("./ratingClasses"));
|
|
28
28
|
var _useSlot = _interopRequireDefault(require("../utils/useSlot"));
|
|
29
|
+
var _utils2 = require("../transitions/utils");
|
|
29
30
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
30
31
|
function getDecimalPrecision(num) {
|
|
31
32
|
const decimalPart = num.toString().split('.')[1];
|
|
@@ -152,7 +153,7 @@ const RatingIcon = (0, _zeroStyled.styled)('span', {
|
|
|
152
153
|
}) => ({
|
|
153
154
|
// Fit wrapper to actual icon size.
|
|
154
155
|
display: 'flex',
|
|
155
|
-
|
|
156
|
+
...(0, _utils2.getTransitionStyles)(theme, 'transform', {
|
|
156
157
|
duration: theme.transitions.duration.shortest
|
|
157
158
|
}),
|
|
158
159
|
// Fix mouseLeave issue.
|
package/Rating/Rating.mjs
CHANGED
|
@@ -18,6 +18,7 @@ import { useDefaultProps } from "../DefaultPropsProvider/index.mjs";
|
|
|
18
18
|
import slotShouldForwardProp from "../styles/slotShouldForwardProp.mjs";
|
|
19
19
|
import ratingClasses, { getRatingUtilityClass } from "./ratingClasses.mjs";
|
|
20
20
|
import useSlot from "../utils/useSlot.mjs";
|
|
21
|
+
import { getTransitionStyles } from "../transitions/utils.mjs";
|
|
21
22
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
22
23
|
import { createElement as _createElement } from "react";
|
|
23
24
|
function getDecimalPrecision(num) {
|
|
@@ -145,7 +146,7 @@ const RatingIcon = styled('span', {
|
|
|
145
146
|
}) => ({
|
|
146
147
|
// Fit wrapper to actual icon size.
|
|
147
148
|
display: 'flex',
|
|
148
|
-
|
|
149
|
+
...getTransitionStyles(theme, 'transform', {
|
|
149
150
|
duration: theme.transitions.duration.shortest
|
|
150
151
|
}),
|
|
151
152
|
// Fix mouseLeave issue.
|
package/Select/SelectInput.js
CHANGED
|
@@ -28,6 +28,7 @@ var _useForkRef = _interopRequireDefault(require("../utils/useForkRef"));
|
|
|
28
28
|
var _useControlled = _interopRequireDefault(require("../utils/useControlled"));
|
|
29
29
|
var _selectClasses = _interopRequireWildcard(require("./selectClasses"));
|
|
30
30
|
var _utils2 = require("./utils");
|
|
31
|
+
var _closedTypeahead = require("./utils/closedTypeahead");
|
|
31
32
|
var _SelectFocusSourceContext = require("./utils/SelectFocusSourceContext");
|
|
32
33
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
33
34
|
var _span;
|
|
@@ -35,6 +36,11 @@ const OPENING_MOUSE_UP_BOUNDARY_OFFSET = 2;
|
|
|
35
36
|
// The initial mouseup may land on an item when the menu opens over the trigger.
|
|
36
37
|
const SELECTED_MOUSE_UP_DELAY = 400;
|
|
37
38
|
const UNSELECTED_MOUSE_UP_DELAY = 200;
|
|
39
|
+
const TYPEAHEAD_RESET_MS = 750;
|
|
40
|
+
const SPACE = ' ';
|
|
41
|
+
const ARROW_UP = 'ArrowUp';
|
|
42
|
+
const ARROW_DOWN = 'ArrowDown';
|
|
43
|
+
const ENTER = 'Enter';
|
|
38
44
|
|
|
39
45
|
/**
|
|
40
46
|
* Returns true when a native mouse event should be treated as happening inside
|
|
@@ -197,8 +203,14 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
197
203
|
allowSelectedMouseUp: false,
|
|
198
204
|
allowUnselectedMouseUp: false
|
|
199
205
|
});
|
|
206
|
+
const closedTypeaheadRef = React.useRef({
|
|
207
|
+
buffer: '',
|
|
208
|
+
previousSearchIndex: null,
|
|
209
|
+
matchedIndex: null
|
|
210
|
+
});
|
|
200
211
|
const selectedMouseUpTimer = (0, _useTimeout.default)();
|
|
201
212
|
const unselectedMouseUpTimer = (0, _useTimeout.default)();
|
|
213
|
+
const typeaheadResetTimer = (0, _useTimeout.default)();
|
|
202
214
|
const [displayNode, setDisplayNode] = React.useState(null);
|
|
203
215
|
const {
|
|
204
216
|
current: isOpenControlled
|
|
@@ -221,9 +233,18 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
221
233
|
value
|
|
222
234
|
}), [value]);
|
|
223
235
|
const open = displayNode !== null && openState;
|
|
236
|
+
const resetClosedTypeahead = React.useCallback(() => {
|
|
237
|
+
typeaheadResetTimer.clear();
|
|
238
|
+
closedTypeaheadRef.current.buffer = '';
|
|
239
|
+
closedTypeaheadRef.current.previousSearchIndex = null;
|
|
240
|
+
closedTypeaheadRef.current.matchedIndex = null;
|
|
241
|
+
}, [typeaheadResetTimer]);
|
|
224
242
|
(0, _useEnhancedEffect.default)(() => {
|
|
225
243
|
openRef.current = open;
|
|
226
|
-
|
|
244
|
+
if (open) {
|
|
245
|
+
resetClosedTypeahead();
|
|
246
|
+
}
|
|
247
|
+
}, [open, resetClosedTypeahead]);
|
|
227
248
|
const clearSelectionTimers = React.useCallback(() => {
|
|
228
249
|
selectedMouseUpTimer.clear();
|
|
229
250
|
unselectedMouseUpTimer.clear();
|
|
@@ -255,8 +276,9 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
255
276
|
return () => {
|
|
256
277
|
resetMouseUpSelection();
|
|
257
278
|
clearOpeningMouseUpListener();
|
|
279
|
+
resetClosedTypeahead();
|
|
258
280
|
};
|
|
259
|
-
}, [resetMouseUpSelection, clearOpeningMouseUpListener]);
|
|
281
|
+
}, [resetMouseUpSelection, clearOpeningMouseUpListener, resetClosedTypeahead]);
|
|
260
282
|
React.useEffect(() => {
|
|
261
283
|
if (!open || !anchorElement || autoWidth) {
|
|
262
284
|
return undefined;
|
|
@@ -313,6 +335,7 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
313
335
|
clearOpeningMouseUpListener();
|
|
314
336
|
}
|
|
315
337
|
if (openParam) {
|
|
338
|
+
resetClosedTypeahead();
|
|
316
339
|
setOpenInteractionType((0, _utils2.getOpenInteractionType)(event));
|
|
317
340
|
if (onOpen) {
|
|
318
341
|
onOpen(event);
|
|
@@ -402,6 +425,25 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
402
425
|
onChange(event, child);
|
|
403
426
|
}
|
|
404
427
|
};
|
|
428
|
+
const handleValueChange = (event, child, newValue) => {
|
|
429
|
+
setValueState(newValue);
|
|
430
|
+
if (onChange) {
|
|
431
|
+
// Redefine target to allow name and value to be read.
|
|
432
|
+
// This allows seamless integration with the most popular form libraries.
|
|
433
|
+
// https://github.com/mui/material-ui/issues/13485#issuecomment-676048492
|
|
434
|
+
// Clone the event to not override `target` of the original event.
|
|
435
|
+
const nativeEvent = event.nativeEvent || event;
|
|
436
|
+
const clonedEvent = new nativeEvent.constructor(nativeEvent.type, nativeEvent);
|
|
437
|
+
Object.defineProperty(clonedEvent, 'target', {
|
|
438
|
+
writable: true,
|
|
439
|
+
value: {
|
|
440
|
+
value: newValue,
|
|
441
|
+
name
|
|
442
|
+
}
|
|
443
|
+
});
|
|
444
|
+
onChange(clonedEvent, child);
|
|
445
|
+
}
|
|
446
|
+
};
|
|
405
447
|
const handleItemClick = child => event => {
|
|
406
448
|
didPointerDownOnItemRef.current = false;
|
|
407
449
|
let newValue;
|
|
@@ -425,23 +467,7 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
425
467
|
child.props.onClick(event);
|
|
426
468
|
}
|
|
427
469
|
if (value !== newValue) {
|
|
428
|
-
|
|
429
|
-
if (onChange) {
|
|
430
|
-
// Redefine target to allow name and value to be read.
|
|
431
|
-
// This allows seamless integration with the most popular form libraries.
|
|
432
|
-
// https://github.com/mui/material-ui/issues/13485#issuecomment-676048492
|
|
433
|
-
// Clone the event to not override `target` of the original event.
|
|
434
|
-
const nativeEvent = event.nativeEvent || event;
|
|
435
|
-
const clonedEvent = new nativeEvent.constructor(nativeEvent.type, nativeEvent);
|
|
436
|
-
Object.defineProperty(clonedEvent, 'target', {
|
|
437
|
-
writable: true,
|
|
438
|
-
value: {
|
|
439
|
-
value: newValue,
|
|
440
|
-
name
|
|
441
|
-
}
|
|
442
|
-
});
|
|
443
|
-
onChange(clonedEvent, child);
|
|
444
|
-
}
|
|
470
|
+
handleValueChange(event, child, newValue);
|
|
445
471
|
}
|
|
446
472
|
if (!multiple) {
|
|
447
473
|
update(false, event);
|
|
@@ -460,13 +486,57 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
460
486
|
}
|
|
461
487
|
event.currentTarget.click();
|
|
462
488
|
};
|
|
489
|
+
const handleClosedTypeahead = event => {
|
|
490
|
+
const state = closedTypeaheadRef.current;
|
|
491
|
+
const hasActiveBuffer = state.buffer !== '';
|
|
492
|
+
if (open || multiple || disabled || event.defaultPrevented || event.nativeEvent?.isComposing || event.key.length !== 1 || event.ctrlKey || event.metaKey || event.altKey || event.key === SPACE && !hasActiveBuffer) {
|
|
493
|
+
return false;
|
|
494
|
+
}
|
|
495
|
+
if (event.key === SPACE) {
|
|
496
|
+
event.preventDefault();
|
|
497
|
+
}
|
|
498
|
+
const isNewSession = state.buffer === '';
|
|
499
|
+
const {
|
|
500
|
+
options: searchableOptions,
|
|
501
|
+
selectedIndex
|
|
502
|
+
} = (0, _closedTypeahead.getTypeaheadOptions)(childrenArray, value);
|
|
503
|
+
if (searchableOptions.length === 0) {
|
|
504
|
+
if (event.key !== SPACE) {
|
|
505
|
+
resetClosedTypeahead();
|
|
506
|
+
}
|
|
507
|
+
return true;
|
|
508
|
+
}
|
|
509
|
+
if (isNewSession) {
|
|
510
|
+
state.previousSearchIndex = selectedIndex;
|
|
511
|
+
}
|
|
512
|
+
const key = event.key.toLowerCase();
|
|
513
|
+
if (state.buffer === key && (0, _closedTypeahead.canCycleRepeatedCharacter)(searchableOptions, key)) {
|
|
514
|
+
state.buffer = '';
|
|
515
|
+
state.previousSearchIndex = state.matchedIndex;
|
|
516
|
+
}
|
|
517
|
+
state.buffer += key;
|
|
518
|
+
typeaheadResetTimer.start(TYPEAHEAD_RESET_MS, resetClosedTypeahead);
|
|
519
|
+
const matchingIndex = (0, _closedTypeahead.getMatchingOptionIndex)(searchableOptions, state.buffer, (state.previousSearchIndex ?? -1) + 1);
|
|
520
|
+
if (matchingIndex !== -1) {
|
|
521
|
+
const matchedOption = searchableOptions[matchingIndex];
|
|
522
|
+
state.matchedIndex = matchingIndex;
|
|
523
|
+
if (!(0, _utils2.areEqualValues)(value, matchedOption.value)) {
|
|
524
|
+
handleValueChange(event, matchedOption.child, matchedOption.value);
|
|
525
|
+
}
|
|
526
|
+
return true;
|
|
527
|
+
}
|
|
528
|
+
if (event.key !== SPACE) {
|
|
529
|
+
resetClosedTypeahead();
|
|
530
|
+
}
|
|
531
|
+
return true;
|
|
532
|
+
};
|
|
463
533
|
const handleKeyDown = event => {
|
|
464
534
|
if (!readOnly) {
|
|
465
|
-
const
|
|
466
|
-
// The native select doesn't respond to
|
|
535
|
+
const isClosedTypeaheadHandled = handleClosedTypeahead(event);
|
|
536
|
+
// The native select doesn't respond to Enter on macOS, but it's recommended by
|
|
467
537
|
// https://www.w3.org/WAI/ARIA/apg/patterns/combobox/examples/combobox-select-only/
|
|
468
|
-
|
|
469
|
-
if (
|
|
538
|
+
const isOpenKey = event.key === SPACE || event.key === ARROW_UP || event.key === ARROW_DOWN || event.key === ENTER;
|
|
539
|
+
if (!isClosedTypeaheadHandled && isOpenKey) {
|
|
470
540
|
event.preventDefault();
|
|
471
541
|
update(true, event);
|
|
472
542
|
}
|
|
@@ -474,6 +544,7 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
474
544
|
}
|
|
475
545
|
};
|
|
476
546
|
const handleBlur = event => {
|
|
547
|
+
resetClosedTypeahead();
|
|
477
548
|
// if open event.stopImmediatePropagation
|
|
478
549
|
if (!open && onBlur) {
|
|
479
550
|
// Preact support, target is read only property on a native event.
|
|
@@ -487,6 +558,19 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
487
558
|
onBlur(event);
|
|
488
559
|
}
|
|
489
560
|
};
|
|
561
|
+
const handleItemKeyDown = child => event => {
|
|
562
|
+
child?.props?.onKeyDown?.(event);
|
|
563
|
+
if (event.key === SPACE && event.target === event.currentTarget && !event.defaultPrevented) {
|
|
564
|
+
// Prevent the browser from scrolling the page
|
|
565
|
+
event.preventDefault();
|
|
566
|
+
// Ignore auto-repeated keydowns to avoid toggling multiple times
|
|
567
|
+
if (!event.repeat) {
|
|
568
|
+
// Trigger via click so that onClick receives a click event,
|
|
569
|
+
// consistent with Enter and pointer interactions.
|
|
570
|
+
event.currentTarget.click();
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
};
|
|
490
574
|
delete other['aria-invalid'];
|
|
491
575
|
let display;
|
|
492
576
|
let displaySingle;
|
|
@@ -544,7 +628,7 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
544
628
|
onClick: handleItemClick(child),
|
|
545
629
|
onMouseUp: handleItemMouseUp(child, selected),
|
|
546
630
|
onKeyUp: event => {
|
|
547
|
-
if (event.key ===
|
|
631
|
+
if (event.key === SPACE) {
|
|
548
632
|
// otherwise our MenuItems dispatches a click event
|
|
549
633
|
// it's not behavior of the native <option> and causes
|
|
550
634
|
// the select to close immediately since we open on space keydown
|
|
@@ -554,6 +638,7 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
554
638
|
child.props.onKeyUp(event);
|
|
555
639
|
}
|
|
556
640
|
},
|
|
641
|
+
onKeyDown: handleItemKeyDown(child),
|
|
557
642
|
role: 'option',
|
|
558
643
|
selected,
|
|
559
644
|
value: undefined,
|
|
@@ -565,7 +650,10 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
565
650
|
// Keep the opening mouseup guard current without mutating refs during render.
|
|
566
651
|
(0, _useEnhancedEffect.default)(() => {
|
|
567
652
|
hasSelectedItemInListRef.current = foundMatch;
|
|
568
|
-
|
|
653
|
+
if (!open && !multiple && !foundMatch) {
|
|
654
|
+
resetClosedTypeahead();
|
|
655
|
+
}
|
|
656
|
+
}, [foundMatch, multiple, open, resetClosedTypeahead]);
|
|
569
657
|
if (process.env.NODE_ENV !== 'production') {
|
|
570
658
|
// TODO: uncomment once we enable eslint-plugin-react-compiler // eslint-disable-next-line react-compiler/react-compiler
|
|
571
659
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
@@ -629,6 +717,7 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
629
717
|
"aria-disabled": disabled ? 'true' : undefined,
|
|
630
718
|
"aria-expanded": open ? 'true' : 'false',
|
|
631
719
|
"aria-haspopup": "listbox",
|
|
720
|
+
"aria-readonly": readOnly ? 'true' : undefined,
|
|
632
721
|
"aria-label": ariaLabel,
|
|
633
722
|
"aria-labelledby": labelId,
|
|
634
723
|
"aria-describedby": ariaDescribedby,
|
|
@@ -659,6 +748,7 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
659
748
|
onChange: handleChange,
|
|
660
749
|
tabIndex: -1,
|
|
661
750
|
disabled: disabled,
|
|
751
|
+
readOnly: readOnly,
|
|
662
752
|
className: classes.nativeInput,
|
|
663
753
|
autoFocus: autoFocus,
|
|
664
754
|
required: required,
|
package/Select/SelectInput.mjs
CHANGED
|
@@ -22,12 +22,18 @@ import useForkRef from "../utils/useForkRef.mjs";
|
|
|
22
22
|
import useControlled from "../utils/useControlled.mjs";
|
|
23
23
|
import selectClasses, { getSelectUtilityClasses } from "./selectClasses.mjs";
|
|
24
24
|
import { areEqualValues, isEmpty, getOpenInteractionType } from "./utils/index.mjs";
|
|
25
|
+
import { canCycleRepeatedCharacter, getMatchingOptionIndex, getTypeaheadOptions } from "./utils/closedTypeahead.mjs";
|
|
25
26
|
import { SelectFocusSourceProvider } from "./utils/SelectFocusSourceContext.mjs";
|
|
26
27
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
27
28
|
const OPENING_MOUSE_UP_BOUNDARY_OFFSET = 2;
|
|
28
29
|
// The initial mouseup may land on an item when the menu opens over the trigger.
|
|
29
30
|
const SELECTED_MOUSE_UP_DELAY = 400;
|
|
30
31
|
const UNSELECTED_MOUSE_UP_DELAY = 200;
|
|
32
|
+
const TYPEAHEAD_RESET_MS = 750;
|
|
33
|
+
const SPACE = ' ';
|
|
34
|
+
const ARROW_UP = 'ArrowUp';
|
|
35
|
+
const ARROW_DOWN = 'ArrowDown';
|
|
36
|
+
const ENTER = 'Enter';
|
|
31
37
|
|
|
32
38
|
/**
|
|
33
39
|
* Returns true when a native mouse event should be treated as happening inside
|
|
@@ -190,8 +196,14 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
190
196
|
allowSelectedMouseUp: false,
|
|
191
197
|
allowUnselectedMouseUp: false
|
|
192
198
|
});
|
|
199
|
+
const closedTypeaheadRef = React.useRef({
|
|
200
|
+
buffer: '',
|
|
201
|
+
previousSearchIndex: null,
|
|
202
|
+
matchedIndex: null
|
|
203
|
+
});
|
|
193
204
|
const selectedMouseUpTimer = useTimeout();
|
|
194
205
|
const unselectedMouseUpTimer = useTimeout();
|
|
206
|
+
const typeaheadResetTimer = useTimeout();
|
|
195
207
|
const [displayNode, setDisplayNode] = React.useState(null);
|
|
196
208
|
const {
|
|
197
209
|
current: isOpenControlled
|
|
@@ -214,9 +226,18 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
214
226
|
value
|
|
215
227
|
}), [value]);
|
|
216
228
|
const open = displayNode !== null && openState;
|
|
229
|
+
const resetClosedTypeahead = React.useCallback(() => {
|
|
230
|
+
typeaheadResetTimer.clear();
|
|
231
|
+
closedTypeaheadRef.current.buffer = '';
|
|
232
|
+
closedTypeaheadRef.current.previousSearchIndex = null;
|
|
233
|
+
closedTypeaheadRef.current.matchedIndex = null;
|
|
234
|
+
}, [typeaheadResetTimer]);
|
|
217
235
|
useEnhancedEffect(() => {
|
|
218
236
|
openRef.current = open;
|
|
219
|
-
|
|
237
|
+
if (open) {
|
|
238
|
+
resetClosedTypeahead();
|
|
239
|
+
}
|
|
240
|
+
}, [open, resetClosedTypeahead]);
|
|
220
241
|
const clearSelectionTimers = React.useCallback(() => {
|
|
221
242
|
selectedMouseUpTimer.clear();
|
|
222
243
|
unselectedMouseUpTimer.clear();
|
|
@@ -248,8 +269,9 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
248
269
|
return () => {
|
|
249
270
|
resetMouseUpSelection();
|
|
250
271
|
clearOpeningMouseUpListener();
|
|
272
|
+
resetClosedTypeahead();
|
|
251
273
|
};
|
|
252
|
-
}, [resetMouseUpSelection, clearOpeningMouseUpListener]);
|
|
274
|
+
}, [resetMouseUpSelection, clearOpeningMouseUpListener, resetClosedTypeahead]);
|
|
253
275
|
React.useEffect(() => {
|
|
254
276
|
if (!open || !anchorElement || autoWidth) {
|
|
255
277
|
return undefined;
|
|
@@ -306,6 +328,7 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
306
328
|
clearOpeningMouseUpListener();
|
|
307
329
|
}
|
|
308
330
|
if (openParam) {
|
|
331
|
+
resetClosedTypeahead();
|
|
309
332
|
setOpenInteractionType(getOpenInteractionType(event));
|
|
310
333
|
if (onOpen) {
|
|
311
334
|
onOpen(event);
|
|
@@ -395,6 +418,25 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
395
418
|
onChange(event, child);
|
|
396
419
|
}
|
|
397
420
|
};
|
|
421
|
+
const handleValueChange = (event, child, newValue) => {
|
|
422
|
+
setValueState(newValue);
|
|
423
|
+
if (onChange) {
|
|
424
|
+
// Redefine target to allow name and value to be read.
|
|
425
|
+
// This allows seamless integration with the most popular form libraries.
|
|
426
|
+
// https://github.com/mui/material-ui/issues/13485#issuecomment-676048492
|
|
427
|
+
// Clone the event to not override `target` of the original event.
|
|
428
|
+
const nativeEvent = event.nativeEvent || event;
|
|
429
|
+
const clonedEvent = new nativeEvent.constructor(nativeEvent.type, nativeEvent);
|
|
430
|
+
Object.defineProperty(clonedEvent, 'target', {
|
|
431
|
+
writable: true,
|
|
432
|
+
value: {
|
|
433
|
+
value: newValue,
|
|
434
|
+
name
|
|
435
|
+
}
|
|
436
|
+
});
|
|
437
|
+
onChange(clonedEvent, child);
|
|
438
|
+
}
|
|
439
|
+
};
|
|
398
440
|
const handleItemClick = child => event => {
|
|
399
441
|
didPointerDownOnItemRef.current = false;
|
|
400
442
|
let newValue;
|
|
@@ -418,23 +460,7 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
418
460
|
child.props.onClick(event);
|
|
419
461
|
}
|
|
420
462
|
if (value !== newValue) {
|
|
421
|
-
|
|
422
|
-
if (onChange) {
|
|
423
|
-
// Redefine target to allow name and value to be read.
|
|
424
|
-
// This allows seamless integration with the most popular form libraries.
|
|
425
|
-
// https://github.com/mui/material-ui/issues/13485#issuecomment-676048492
|
|
426
|
-
// Clone the event to not override `target` of the original event.
|
|
427
|
-
const nativeEvent = event.nativeEvent || event;
|
|
428
|
-
const clonedEvent = new nativeEvent.constructor(nativeEvent.type, nativeEvent);
|
|
429
|
-
Object.defineProperty(clonedEvent, 'target', {
|
|
430
|
-
writable: true,
|
|
431
|
-
value: {
|
|
432
|
-
value: newValue,
|
|
433
|
-
name
|
|
434
|
-
}
|
|
435
|
-
});
|
|
436
|
-
onChange(clonedEvent, child);
|
|
437
|
-
}
|
|
463
|
+
handleValueChange(event, child, newValue);
|
|
438
464
|
}
|
|
439
465
|
if (!multiple) {
|
|
440
466
|
update(false, event);
|
|
@@ -453,13 +479,57 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
453
479
|
}
|
|
454
480
|
event.currentTarget.click();
|
|
455
481
|
};
|
|
482
|
+
const handleClosedTypeahead = event => {
|
|
483
|
+
const state = closedTypeaheadRef.current;
|
|
484
|
+
const hasActiveBuffer = state.buffer !== '';
|
|
485
|
+
if (open || multiple || disabled || event.defaultPrevented || event.nativeEvent?.isComposing || event.key.length !== 1 || event.ctrlKey || event.metaKey || event.altKey || event.key === SPACE && !hasActiveBuffer) {
|
|
486
|
+
return false;
|
|
487
|
+
}
|
|
488
|
+
if (event.key === SPACE) {
|
|
489
|
+
event.preventDefault();
|
|
490
|
+
}
|
|
491
|
+
const isNewSession = state.buffer === '';
|
|
492
|
+
const {
|
|
493
|
+
options: searchableOptions,
|
|
494
|
+
selectedIndex
|
|
495
|
+
} = getTypeaheadOptions(childrenArray, value);
|
|
496
|
+
if (searchableOptions.length === 0) {
|
|
497
|
+
if (event.key !== SPACE) {
|
|
498
|
+
resetClosedTypeahead();
|
|
499
|
+
}
|
|
500
|
+
return true;
|
|
501
|
+
}
|
|
502
|
+
if (isNewSession) {
|
|
503
|
+
state.previousSearchIndex = selectedIndex;
|
|
504
|
+
}
|
|
505
|
+
const key = event.key.toLowerCase();
|
|
506
|
+
if (state.buffer === key && canCycleRepeatedCharacter(searchableOptions, key)) {
|
|
507
|
+
state.buffer = '';
|
|
508
|
+
state.previousSearchIndex = state.matchedIndex;
|
|
509
|
+
}
|
|
510
|
+
state.buffer += key;
|
|
511
|
+
typeaheadResetTimer.start(TYPEAHEAD_RESET_MS, resetClosedTypeahead);
|
|
512
|
+
const matchingIndex = getMatchingOptionIndex(searchableOptions, state.buffer, (state.previousSearchIndex ?? -1) + 1);
|
|
513
|
+
if (matchingIndex !== -1) {
|
|
514
|
+
const matchedOption = searchableOptions[matchingIndex];
|
|
515
|
+
state.matchedIndex = matchingIndex;
|
|
516
|
+
if (!areEqualValues(value, matchedOption.value)) {
|
|
517
|
+
handleValueChange(event, matchedOption.child, matchedOption.value);
|
|
518
|
+
}
|
|
519
|
+
return true;
|
|
520
|
+
}
|
|
521
|
+
if (event.key !== SPACE) {
|
|
522
|
+
resetClosedTypeahead();
|
|
523
|
+
}
|
|
524
|
+
return true;
|
|
525
|
+
};
|
|
456
526
|
const handleKeyDown = event => {
|
|
457
527
|
if (!readOnly) {
|
|
458
|
-
const
|
|
459
|
-
// The native select doesn't respond to
|
|
528
|
+
const isClosedTypeaheadHandled = handleClosedTypeahead(event);
|
|
529
|
+
// The native select doesn't respond to Enter on macOS, but it's recommended by
|
|
460
530
|
// https://www.w3.org/WAI/ARIA/apg/patterns/combobox/examples/combobox-select-only/
|
|
461
|
-
|
|
462
|
-
if (
|
|
531
|
+
const isOpenKey = event.key === SPACE || event.key === ARROW_UP || event.key === ARROW_DOWN || event.key === ENTER;
|
|
532
|
+
if (!isClosedTypeaheadHandled && isOpenKey) {
|
|
463
533
|
event.preventDefault();
|
|
464
534
|
update(true, event);
|
|
465
535
|
}
|
|
@@ -467,6 +537,7 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
467
537
|
}
|
|
468
538
|
};
|
|
469
539
|
const handleBlur = event => {
|
|
540
|
+
resetClosedTypeahead();
|
|
470
541
|
// if open event.stopImmediatePropagation
|
|
471
542
|
if (!open && onBlur) {
|
|
472
543
|
// Preact support, target is read only property on a native event.
|
|
@@ -480,6 +551,19 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
480
551
|
onBlur(event);
|
|
481
552
|
}
|
|
482
553
|
};
|
|
554
|
+
const handleItemKeyDown = child => event => {
|
|
555
|
+
child?.props?.onKeyDown?.(event);
|
|
556
|
+
if (event.key === SPACE && event.target === event.currentTarget && !event.defaultPrevented) {
|
|
557
|
+
// Prevent the browser from scrolling the page
|
|
558
|
+
event.preventDefault();
|
|
559
|
+
// Ignore auto-repeated keydowns to avoid toggling multiple times
|
|
560
|
+
if (!event.repeat) {
|
|
561
|
+
// Trigger via click so that onClick receives a click event,
|
|
562
|
+
// consistent with Enter and pointer interactions.
|
|
563
|
+
event.currentTarget.click();
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
};
|
|
483
567
|
delete other['aria-invalid'];
|
|
484
568
|
let display;
|
|
485
569
|
let displaySingle;
|
|
@@ -537,7 +621,7 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
537
621
|
onClick: handleItemClick(child),
|
|
538
622
|
onMouseUp: handleItemMouseUp(child, selected),
|
|
539
623
|
onKeyUp: event => {
|
|
540
|
-
if (event.key ===
|
|
624
|
+
if (event.key === SPACE) {
|
|
541
625
|
// otherwise our MenuItems dispatches a click event
|
|
542
626
|
// it's not behavior of the native <option> and causes
|
|
543
627
|
// the select to close immediately since we open on space keydown
|
|
@@ -547,6 +631,7 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
547
631
|
child.props.onKeyUp(event);
|
|
548
632
|
}
|
|
549
633
|
},
|
|
634
|
+
onKeyDown: handleItemKeyDown(child),
|
|
550
635
|
role: 'option',
|
|
551
636
|
selected,
|
|
552
637
|
value: undefined,
|
|
@@ -558,7 +643,10 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
558
643
|
// Keep the opening mouseup guard current without mutating refs during render.
|
|
559
644
|
useEnhancedEffect(() => {
|
|
560
645
|
hasSelectedItemInListRef.current = foundMatch;
|
|
561
|
-
|
|
646
|
+
if (!open && !multiple && !foundMatch) {
|
|
647
|
+
resetClosedTypeahead();
|
|
648
|
+
}
|
|
649
|
+
}, [foundMatch, multiple, open, resetClosedTypeahead]);
|
|
562
650
|
if (process.env.NODE_ENV !== 'production') {
|
|
563
651
|
// TODO: uncomment once we enable eslint-plugin-react-compiler // eslint-disable-next-line react-compiler/react-compiler
|
|
564
652
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
@@ -622,6 +710,7 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
622
710
|
"aria-disabled": disabled ? 'true' : undefined,
|
|
623
711
|
"aria-expanded": open ? 'true' : 'false',
|
|
624
712
|
"aria-haspopup": "listbox",
|
|
713
|
+
"aria-readonly": readOnly ? 'true' : undefined,
|
|
625
714
|
"aria-label": ariaLabel,
|
|
626
715
|
"aria-labelledby": labelId,
|
|
627
716
|
"aria-describedby": ariaDescribedby,
|
|
@@ -652,6 +741,7 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
652
741
|
onChange: handleChange,
|
|
653
742
|
tabIndex: -1,
|
|
654
743
|
disabled: disabled,
|
|
744
|
+
readOnly: readOnly,
|
|
655
745
|
className: classes.nativeInput,
|
|
656
746
|
autoFocus: autoFocus,
|
|
657
747
|
required: required,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
declare function useSelectFocusSource(): "
|
|
3
|
-
declare const SelectFocusSourceProvider: React.Provider<"
|
|
2
|
+
declare function useSelectFocusSource(): "keyboard" | "mouse" | "touch" | null;
|
|
3
|
+
declare const SelectFocusSourceProvider: React.Provider<"keyboard" | "mouse" | "touch" | null>;
|
|
4
4
|
export { useSelectFocusSource, SelectFocusSourceProvider };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
declare function useSelectFocusSource(): "
|
|
3
|
-
declare const SelectFocusSourceProvider: React.Provider<"
|
|
2
|
+
declare function useSelectFocusSource(): "keyboard" | "mouse" | "touch" | null;
|
|
3
|
+
declare const SelectFocusSourceProvider: React.Provider<"keyboard" | "mouse" | "touch" | null>;
|
|
4
4
|
export { useSelectFocusSource, SelectFocusSourceProvider };
|