@mui/material 9.0.0 → 9.1.0
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.js +73 -17
- package/Autocomplete/Autocomplete.mjs +73 -17
- package/Avatar/Avatar.js +4 -0
- package/Avatar/Avatar.mjs +4 -0
- package/Backdrop/Backdrop.d.mts +2 -2
- package/Backdrop/Backdrop.d.ts +2 -2
- package/Badge/Badge.js +31 -24
- package/Badge/Badge.mjs +31 -24
- package/BottomNavigationAction/BottomNavigationAction.js +6 -2
- package/BottomNavigationAction/BottomNavigationAction.mjs +6 -2
- package/Button/Button.js +19 -6
- package/Button/Button.mjs +19 -6
- package/ButtonBase/ButtonBase.d.mts +7 -0
- package/ButtonBase/ButtonBase.d.ts +7 -0
- package/ButtonBase/ButtonBase.js +5 -2
- package/ButtonBase/ButtonBase.mjs +5 -2
- package/ButtonBase/Ripple.js +21 -11
- package/ButtonBase/Ripple.mjs +21 -11
- package/ButtonBase/TouchRipple.js +252 -116
- package/ButtonBase/TouchRipple.mjs +253 -117
- package/CHANGELOG.md +216 -1245
- package/CardActionArea/CardActionArea.js +2 -1
- package/CardActionArea/CardActionArea.mjs +2 -1
- package/Checkbox/Checkbox.js +2 -1
- package/Checkbox/Checkbox.mjs +2 -1
- package/Chip/Chip.js +2 -1
- package/Chip/Chip.mjs +2 -1
- package/CircularProgress/CircularProgress.d.mts +12 -2
- package/CircularProgress/CircularProgress.d.ts +12 -2
- package/CircularProgress/CircularProgress.js +115 -58
- package/CircularProgress/CircularProgress.mjs +114 -58
- package/ClickAwayListener/ClickAwayListener.js +3 -6
- package/ClickAwayListener/ClickAwayListener.mjs +3 -6
- 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 +13 -6
- package/Dialog/Dialog.mjs +13 -6
- package/Drawer/Drawer.d.mts +2 -2
- package/Drawer/Drawer.d.ts +2 -2
- package/Drawer/Drawer.js +18 -4
- package/Drawer/Drawer.mjs +18 -4
- package/Fab/Fab.js +9 -2
- package/Fab/Fab.mjs +9 -2
- 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.d.mts +4 -0
- package/FilledInput/FilledInput.d.ts +4 -0
- package/FilledInput/FilledInput.js +22 -23
- package/FilledInput/FilledInput.mjs +22 -23
- package/FormControl/useFormControl.d.mts +12 -2
- package/FormControl/useFormControl.d.ts +12 -2
- package/FormControl/useFormControl.js +13 -0
- package/FormControl/useFormControl.mjs +12 -0
- package/FormControlLabel/FormControlLabel.js +5 -8
- package/FormControlLabel/FormControlLabel.mjs +5 -8
- package/FormGroup/FormGroup.js +2 -5
- package/FormGroup/FormGroup.mjs +2 -5
- package/FormHelperText/FormHelperText.js +2 -5
- package/FormHelperText/FormHelperText.mjs +2 -5
- package/FormLabel/FormLabel.js +2 -5
- package/FormLabel/FormLabel.mjs +2 -5
- 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 +3 -9
- package/IconButton/IconButton.mjs +3 -9
- package/Input/Input.d.mts +4 -0
- package/Input/Input.d.ts +4 -0
- package/Input/Input.js +9 -2
- package/Input/Input.mjs +9 -2
- package/InputBase/InputBase.d.mts +2 -1
- package/InputBase/InputBase.d.ts +2 -1
- package/InputBase/InputBase.js +52 -16
- package/InputBase/InputBase.mjs +52 -16
- package/InputLabel/InputLabel.js +7 -9
- package/InputLabel/InputLabel.mjs +7 -9
- package/LICENSE +1 -1
- package/LinearProgress/LinearProgress.d.mts +12 -2
- package/LinearProgress/LinearProgress.d.ts +12 -2
- package/LinearProgress/LinearProgress.js +225 -126
- package/LinearProgress/LinearProgress.mjs +224 -126
- package/List/List.js +2 -1
- package/List/List.mjs +2 -1
- package/ListItem/ListItem.js +2 -1
- package/ListItem/ListItem.mjs +2 -1
- package/ListItemButton/ListItemButton.js +9 -2
- package/ListItemButton/ListItemButton.mjs +9 -2
- package/Menu/Menu.d.mts +1 -1
- package/Menu/Menu.d.ts +1 -1
- package/MenuItem/MenuItem.js +7 -1
- package/MenuItem/MenuItem.mjs +7 -1
- package/MenuList/MenuList.js +2 -1
- package/MenuList/MenuList.mjs +2 -1
- package/MobileStepper/MobileStepper.js +2 -1
- package/MobileStepper/MobileStepper.mjs +2 -1
- package/NativeSelect/NativeSelect.js +2 -5
- package/NativeSelect/NativeSelect.mjs +2 -5
- package/OutlinedInput/NotchedOutline.js +4 -3
- package/OutlinedInput/NotchedOutline.mjs +4 -3
- package/OutlinedInput/OutlinedInput.js +13 -23
- package/OutlinedInput/OutlinedInput.mjs +13 -23
- 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/PigmentContainer/PigmentContainer.js +0 -1
- package/PigmentContainer/PigmentContainer.mjs +0 -1
- package/Popover/Popover.d.mts +1 -1
- package/Popover/Popover.d.ts +1 -1
- package/Popper/BasePopper.js +23 -1
- package/Popper/BasePopper.mjs +23 -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/Select.js +2 -5
- package/Select/Select.mjs +2 -5
- package/Select/SelectInput.js +276 -24
- package/Select/SelectInput.mjs +276 -24
- 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 +97 -47
- package/Slide/Slide.mjs +97 -47
- package/Slider/Slider.js +14 -4
- package/Slider/Slider.mjs +14 -4
- package/Slider/useSlider.js +4 -3
- package/Slider/useSlider.mjs +4 -3
- 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/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/SvgIcon/SvgIcon.js +2 -1
- package/SvgIcon/SvgIcon.mjs +2 -1
- package/SwipeableDrawer/SwipeableDrawer.js +21 -6
- package/SwipeableDrawer/SwipeableDrawer.mjs +21 -6
- package/Switch/Switch.js +10 -8
- package/Switch/Switch.mjs +10 -8
- package/TableSortLabel/TableSortLabel.js +2 -1
- package/TableSortLabel/TableSortLabel.mjs +2 -1
- package/Tabs/ScrollbarSize.js +2 -1
- package/Tabs/ScrollbarSize.mjs +2 -1
- package/Tabs/Tabs.js +16 -4
- package/Tabs/Tabs.mjs +16 -4
- package/Tooltip/Tooltip.d.mts +2 -2
- package/Tooltip/Tooltip.d.ts +2 -2
- package/Tooltip/Tooltip.js +29 -108
- package/Tooltip/Tooltip.mjs +29 -108
- package/Unstable_TrapFocus/FocusTrap.js +60 -22
- package/Unstable_TrapFocus/FocusTrap.mjs +60 -22
- 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 +444 -0
- package/internal/Transition.mjs +436 -0
- package/internal/react-transition-group.d.mts +8 -0
- package/internal/react-transition-group.d.ts +8 -0
- package/package.json +50 -50
- 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/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/responsiveFontSizes.js +19 -8
- package/styles/responsiveFontSizes.mjs +19 -8
- 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/styles/useThemeProps.d.mts +3 -3
- package/styles/useThemeProps.d.ts +3 -3
- 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 +51 -2
- package/transitions/utils.d.ts +51 -2
- package/transitions/utils.js +97 -4
- package/transitions/utils.mjs +94 -4
- package/useAutocomplete/useAutocomplete.d.mts +12 -6
- package/useAutocomplete/useAutocomplete.d.ts +12 -6
- package/useAutocomplete/useAutocomplete.js +230 -55
- package/useAutocomplete/useAutocomplete.mjs +230 -55
- package/utils/contains.d.mts +2 -0
- package/utils/contains.d.ts +2 -0
- package/utils/contains.js +9 -0
- package/utils/contains.mjs +2 -0
- package/utils/focusable.d.mts +7 -0
- package/utils/focusable.d.ts +7 -0
- package/utils/focusable.js +20 -0
- package/utils/focusable.mjs +13 -0
- package/utils/getEventTarget.d.mts +2 -0
- package/utils/getEventTarget.d.ts +2 -0
- package/utils/getEventTarget.js +9 -0
- package/utils/getEventTarget.mjs +2 -0
- package/utils/mergeSlotProps.js +2 -8
- package/utils/mergeSlotProps.mjs +1 -8
- package/version/index.js +2 -2
- package/version/index.mjs +2 -2
- package/FormControl/formControlState.js +0 -21
- package/FormControl/formControlState.mjs +0 -15
- /package/transitions/{transition.js → types.js} +0 -0
- /package/transitions/{transition.mjs → types.mjs} +0 -0
package/Select/SelectInput.mjs
CHANGED
|
@@ -9,18 +9,58 @@ import clsx from 'clsx';
|
|
|
9
9
|
import composeClasses from '@mui/utils/composeClasses';
|
|
10
10
|
import useId from '@mui/utils/useId';
|
|
11
11
|
import refType from '@mui/utils/refType';
|
|
12
|
+
import useTimeout from '@mui/utils/useTimeout';
|
|
12
13
|
import ownerDocument from "../utils/ownerDocument.mjs";
|
|
13
14
|
import Menu from "../Menu/Menu.mjs";
|
|
14
15
|
import { StyledSelectSelect, StyledSelectIcon } from "../NativeSelect/NativeSelectInput.mjs";
|
|
15
16
|
import { isFilled } from "../InputBase/utils.mjs";
|
|
16
17
|
import { styled } from "../zero-styled/index.mjs";
|
|
17
18
|
import slotShouldForwardProp from "../styles/slotShouldForwardProp.mjs";
|
|
19
|
+
import useEnhancedEffect from "../utils/useEnhancedEffect.mjs";
|
|
20
|
+
import useEventCallback from "../utils/useEventCallback.mjs";
|
|
18
21
|
import useForkRef from "../utils/useForkRef.mjs";
|
|
19
22
|
import useControlled from "../utils/useControlled.mjs";
|
|
20
23
|
import selectClasses, { getSelectUtilityClasses } from "./selectClasses.mjs";
|
|
21
24
|
import { areEqualValues, isEmpty, getOpenInteractionType } from "./utils/index.mjs";
|
|
25
|
+
import { canCycleRepeatedCharacter, getMatchingOptionIndex, getTypeaheadOptions } from "./utils/closedTypeahead.mjs";
|
|
22
26
|
import { SelectFocusSourceProvider } from "./utils/SelectFocusSourceContext.mjs";
|
|
23
27
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
28
|
+
const OPENING_MOUSE_UP_BOUNDARY_OFFSET = 2;
|
|
29
|
+
// The initial mouseup may land on an item when the menu opens over the trigger.
|
|
30
|
+
const SELECTED_MOUSE_UP_DELAY = 400;
|
|
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';
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Returns true when a native mouse event should be treated as happening inside
|
|
40
|
+
* the element, even if a portal or backdrop retargeted the event away from it.
|
|
41
|
+
*
|
|
42
|
+
* Select uses this for the opening mouseup: when the menu opens over the
|
|
43
|
+
* trigger, the release can target the backdrop or portaled menu even though the
|
|
44
|
+
* pointer is still inside the trigger or menu bounds.
|
|
45
|
+
*/
|
|
46
|
+
function isMouseEventInsideElement(event, element) {
|
|
47
|
+
if (!element) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
const eventPath = event.composedPath();
|
|
51
|
+
if (eventPath.includes(element)) {
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
if (event.target?.nodeType && element.contains(event.target)) {
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
const rect = element.getBoundingClientRect();
|
|
58
|
+
if (rect.width === 0 && rect.height === 0) {
|
|
59
|
+
// Hidden or transition-mounted elements do not have useful bounds to hit-test.
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
return event.clientX >= rect.left - OPENING_MOUSE_UP_BOUNDARY_OFFSET && event.clientX <= rect.right + OPENING_MOUSE_UP_BOUNDARY_OFFSET && event.clientY >= rect.top - OPENING_MOUSE_UP_BOUNDARY_OFFSET && event.clientY <= rect.bottom + OPENING_MOUSE_UP_BOUNDARY_OFFSET;
|
|
63
|
+
}
|
|
24
64
|
const SelectSelect = styled(StyledSelectSelect, {
|
|
25
65
|
name: 'MuiSelect',
|
|
26
66
|
slot: 'Select',
|
|
@@ -147,6 +187,23 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
147
187
|
});
|
|
148
188
|
const inputRef = React.useRef(null);
|
|
149
189
|
const displayRef = React.useRef(null);
|
|
190
|
+
const paperRef = React.useRef(null);
|
|
191
|
+
const openRef = React.useRef(false);
|
|
192
|
+
const hasSelectedItemInListRef = React.useRef(false);
|
|
193
|
+
const openingMouseUpListenerCleanupRef = React.useRef(null);
|
|
194
|
+
const didPointerDownOnItemRef = React.useRef(false);
|
|
195
|
+
const selectionRef = React.useRef({
|
|
196
|
+
allowSelectedMouseUp: false,
|
|
197
|
+
allowUnselectedMouseUp: false
|
|
198
|
+
});
|
|
199
|
+
const closedTypeaheadRef = React.useRef({
|
|
200
|
+
buffer: '',
|
|
201
|
+
previousSearchIndex: null,
|
|
202
|
+
matchedIndex: null
|
|
203
|
+
});
|
|
204
|
+
const selectedMouseUpTimer = useTimeout();
|
|
205
|
+
const unselectedMouseUpTimer = useTimeout();
|
|
206
|
+
const typeaheadResetTimer = useTimeout();
|
|
150
207
|
const [displayNode, setDisplayNode] = React.useState(null);
|
|
151
208
|
const {
|
|
152
209
|
current: isOpenControlled
|
|
@@ -169,6 +226,52 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
169
226
|
value
|
|
170
227
|
}), [value]);
|
|
171
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]);
|
|
235
|
+
useEnhancedEffect(() => {
|
|
236
|
+
openRef.current = open;
|
|
237
|
+
if (open) {
|
|
238
|
+
resetClosedTypeahead();
|
|
239
|
+
}
|
|
240
|
+
}, [open, resetClosedTypeahead]);
|
|
241
|
+
const clearSelectionTimers = React.useCallback(() => {
|
|
242
|
+
selectedMouseUpTimer.clear();
|
|
243
|
+
unselectedMouseUpTimer.clear();
|
|
244
|
+
}, [selectedMouseUpTimer, unselectedMouseUpTimer]);
|
|
245
|
+
const resetMouseUpSelection = React.useCallback(() => {
|
|
246
|
+
clearSelectionTimers();
|
|
247
|
+
didPointerDownOnItemRef.current = false;
|
|
248
|
+
selectionRef.current = {
|
|
249
|
+
allowSelectedMouseUp: false,
|
|
250
|
+
allowUnselectedMouseUp: false
|
|
251
|
+
};
|
|
252
|
+
}, [clearSelectionTimers]);
|
|
253
|
+
const clearOpeningMouseUpListener = React.useCallback(() => {
|
|
254
|
+
if (openingMouseUpListenerCleanupRef.current) {
|
|
255
|
+
openingMouseUpListenerCleanupRef.current();
|
|
256
|
+
openingMouseUpListenerCleanupRef.current = null;
|
|
257
|
+
}
|
|
258
|
+
}, []);
|
|
259
|
+
React.useEffect(() => {
|
|
260
|
+
if (!open) {
|
|
261
|
+
resetMouseUpSelection();
|
|
262
|
+
clearOpeningMouseUpListener();
|
|
263
|
+
}
|
|
264
|
+
}, [open, resetMouseUpSelection, clearOpeningMouseUpListener]);
|
|
265
|
+
|
|
266
|
+
// Keep unmount cleanup separate from the `open` effect. Effect cleanups also run
|
|
267
|
+
// before the next effect, which would clear the opening mouseup listener while opening.
|
|
268
|
+
React.useEffect(() => {
|
|
269
|
+
return () => {
|
|
270
|
+
resetMouseUpSelection();
|
|
271
|
+
clearOpeningMouseUpListener();
|
|
272
|
+
resetClosedTypeahead();
|
|
273
|
+
};
|
|
274
|
+
}, [resetMouseUpSelection, clearOpeningMouseUpListener, resetClosedTypeahead]);
|
|
172
275
|
React.useEffect(() => {
|
|
173
276
|
if (!open || !anchorElement || autoWidth) {
|
|
174
277
|
return undefined;
|
|
@@ -219,8 +322,13 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
219
322
|
}
|
|
220
323
|
return undefined;
|
|
221
324
|
}, [labelId]);
|
|
222
|
-
const update = (openParam, event) => {
|
|
325
|
+
const update = useEventCallback((openParam, event) => {
|
|
326
|
+
if (!openParam) {
|
|
327
|
+
resetMouseUpSelection();
|
|
328
|
+
clearOpeningMouseUpListener();
|
|
329
|
+
}
|
|
223
330
|
if (openParam) {
|
|
331
|
+
resetClosedTypeahead();
|
|
224
332
|
setOpenInteractionType(getOpenInteractionType(event));
|
|
225
333
|
if (onOpen) {
|
|
226
334
|
onOpen(event);
|
|
@@ -232,9 +340,33 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
232
340
|
}
|
|
233
341
|
}
|
|
234
342
|
if (!isOpenControlled) {
|
|
343
|
+
openRef.current = openParam;
|
|
235
344
|
setMenuMinWidthState(autoWidth ? null : anchorElement.clientWidth);
|
|
236
345
|
setOpenState(openParam);
|
|
237
346
|
}
|
|
347
|
+
});
|
|
348
|
+
const scheduleMouseUpSelection = () => {
|
|
349
|
+
resetMouseUpSelection();
|
|
350
|
+
|
|
351
|
+
// When there is no selected item in the list, a mousedown
|
|
352
|
+
// on the trigger followed by a quick mouseup over the first option can accidentally select
|
|
353
|
+
// within 200ms. Delay unselected mouseup to match the safer 400ms window.
|
|
354
|
+
if (!hasSelectedItemInListRef.current) {
|
|
355
|
+
selectedMouseUpTimer.start(SELECTED_MOUSE_UP_DELAY, () => {
|
|
356
|
+
selectionRef.current.allowSelectedMouseUp = true;
|
|
357
|
+
selectionRef.current.allowUnselectedMouseUp = true;
|
|
358
|
+
});
|
|
359
|
+
} else {
|
|
360
|
+
// mousedown -> move to unselected item -> mouseup should not select within 200ms.
|
|
361
|
+
unselectedMouseUpTimer.start(UNSELECTED_MOUSE_UP_DELAY, () => {
|
|
362
|
+
selectionRef.current.allowUnselectedMouseUp = true;
|
|
363
|
+
|
|
364
|
+
// mousedown -> mouseup on selected item should not select within 400ms.
|
|
365
|
+
selectedMouseUpTimer.start(UNSELECTED_MOUSE_UP_DELAY, () => {
|
|
366
|
+
selectionRef.current.allowSelectedMouseUp = true;
|
|
367
|
+
});
|
|
368
|
+
});
|
|
369
|
+
}
|
|
238
370
|
};
|
|
239
371
|
const handleMouseDown = event => {
|
|
240
372
|
onMouseDown?.(event);
|
|
@@ -245,6 +377,29 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
245
377
|
// Hijack the default focus behavior.
|
|
246
378
|
event.preventDefault();
|
|
247
379
|
displayRef.current.focus();
|
|
380
|
+
const doc = ownerDocument(event.currentTarget);
|
|
381
|
+
scheduleMouseUpSelection();
|
|
382
|
+
clearOpeningMouseUpListener();
|
|
383
|
+
const handleMouseUp = mouseEvent => {
|
|
384
|
+
openingMouseUpListenerCleanupRef.current = null;
|
|
385
|
+
if (!displayRef.current) {
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
if (isMouseEventInsideElement(mouseEvent, displayRef.current) || isMouseEventInsideElement(mouseEvent, paperRef.current)) {
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
if (!openRef.current && isOpenControlled) {
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
update(false, mouseEvent);
|
|
395
|
+
};
|
|
396
|
+
doc.addEventListener('mouseup', handleMouseUp, {
|
|
397
|
+
capture: true,
|
|
398
|
+
once: true
|
|
399
|
+
});
|
|
400
|
+
openingMouseUpListenerCleanupRef.current = () => {
|
|
401
|
+
doc.removeEventListener('mouseup', handleMouseUp, true);
|
|
402
|
+
};
|
|
248
403
|
update(true, event);
|
|
249
404
|
};
|
|
250
405
|
const handleClose = event => {
|
|
@@ -263,7 +418,27 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
263
418
|
onChange(event, child);
|
|
264
419
|
}
|
|
265
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
|
+
};
|
|
266
440
|
const handleItemClick = child => event => {
|
|
441
|
+
didPointerDownOnItemRef.current = false;
|
|
267
442
|
let newValue;
|
|
268
443
|
|
|
269
444
|
// We use the tabindex attribute to signal the available options.
|
|
@@ -285,35 +460,76 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
285
460
|
child.props.onClick(event);
|
|
286
461
|
}
|
|
287
462
|
if (value !== newValue) {
|
|
288
|
-
|
|
289
|
-
if (onChange) {
|
|
290
|
-
// Redefine target to allow name and value to be read.
|
|
291
|
-
// This allows seamless integration with the most popular form libraries.
|
|
292
|
-
// https://github.com/mui/material-ui/issues/13485#issuecomment-676048492
|
|
293
|
-
// Clone the event to not override `target` of the original event.
|
|
294
|
-
const nativeEvent = event.nativeEvent || event;
|
|
295
|
-
const clonedEvent = new nativeEvent.constructor(nativeEvent.type, nativeEvent);
|
|
296
|
-
Object.defineProperty(clonedEvent, 'target', {
|
|
297
|
-
writable: true,
|
|
298
|
-
value: {
|
|
299
|
-
value: newValue,
|
|
300
|
-
name
|
|
301
|
-
}
|
|
302
|
-
});
|
|
303
|
-
onChange(clonedEvent, child);
|
|
304
|
-
}
|
|
463
|
+
handleValueChange(event, child, newValue);
|
|
305
464
|
}
|
|
306
465
|
if (!multiple) {
|
|
307
466
|
update(false, event);
|
|
308
467
|
}
|
|
309
468
|
};
|
|
469
|
+
const handleItemMouseUp = (child, selected) => event => {
|
|
470
|
+
child.props.onMouseUp?.(event);
|
|
471
|
+
if (didPointerDownOnItemRef.current) {
|
|
472
|
+
didPointerDownOnItemRef.current = false;
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
const disallowSelectedMouseUp = !selectionRef.current.allowSelectedMouseUp && selected;
|
|
476
|
+
const disallowUnselectedMouseUp = !selectionRef.current.allowUnselectedMouseUp && !selected;
|
|
477
|
+
if (disallowSelectedMouseUp || disallowUnselectedMouseUp) {
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
480
|
+
event.currentTarget.click();
|
|
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
|
+
};
|
|
310
526
|
const handleKeyDown = event => {
|
|
311
527
|
if (!readOnly) {
|
|
312
|
-
const
|
|
313
|
-
// 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
|
|
314
530
|
// https://www.w3.org/WAI/ARIA/apg/patterns/combobox/examples/combobox-select-only/
|
|
315
|
-
|
|
316
|
-
if (
|
|
531
|
+
const isOpenKey = event.key === SPACE || event.key === ARROW_UP || event.key === ARROW_DOWN || event.key === ENTER;
|
|
532
|
+
if (!isClosedTypeaheadHandled && isOpenKey) {
|
|
317
533
|
event.preventDefault();
|
|
318
534
|
update(true, event);
|
|
319
535
|
}
|
|
@@ -321,6 +537,7 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
321
537
|
}
|
|
322
538
|
};
|
|
323
539
|
const handleBlur = event => {
|
|
540
|
+
resetClosedTypeahead();
|
|
324
541
|
// if open event.stopImmediatePropagation
|
|
325
542
|
if (!open && onBlur) {
|
|
326
543
|
// Preact support, target is read only property on a native event.
|
|
@@ -334,6 +551,19 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
334
551
|
onBlur(event);
|
|
335
552
|
}
|
|
336
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
|
+
};
|
|
337
567
|
delete other['aria-invalid'];
|
|
338
568
|
let display;
|
|
339
569
|
let displaySingle;
|
|
@@ -380,9 +610,18 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
380
610
|
}
|
|
381
611
|
return /*#__PURE__*/React.cloneElement(child, {
|
|
382
612
|
'aria-selected': selected ? 'true' : 'false',
|
|
613
|
+
onMouseDown: event => {
|
|
614
|
+
didPointerDownOnItemRef.current = true;
|
|
615
|
+
child.props.onMouseDown?.(event);
|
|
616
|
+
},
|
|
617
|
+
onPointerDown: event => {
|
|
618
|
+
didPointerDownOnItemRef.current = true;
|
|
619
|
+
child.props.onPointerDown?.(event);
|
|
620
|
+
},
|
|
383
621
|
onClick: handleItemClick(child),
|
|
622
|
+
onMouseUp: handleItemMouseUp(child, selected),
|
|
384
623
|
onKeyUp: event => {
|
|
385
|
-
if (event.key ===
|
|
624
|
+
if (event.key === SPACE) {
|
|
386
625
|
// otherwise our MenuItems dispatches a click event
|
|
387
626
|
// it's not behavior of the native <option> and causes
|
|
388
627
|
// the select to close immediately since we open on space keydown
|
|
@@ -392,6 +631,7 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
392
631
|
child.props.onKeyUp(event);
|
|
393
632
|
}
|
|
394
633
|
},
|
|
634
|
+
onKeyDown: handleItemKeyDown(child),
|
|
395
635
|
role: 'option',
|
|
396
636
|
selected,
|
|
397
637
|
value: undefined,
|
|
@@ -399,6 +639,14 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
399
639
|
'data-value': child.props.value // Instead, we provide it as a data attribute.
|
|
400
640
|
});
|
|
401
641
|
});
|
|
642
|
+
|
|
643
|
+
// Keep the opening mouseup guard current without mutating refs during render.
|
|
644
|
+
useEnhancedEffect(() => {
|
|
645
|
+
hasSelectedItemInListRef.current = foundMatch;
|
|
646
|
+
if (!open && !multiple && !foundMatch) {
|
|
647
|
+
resetClosedTypeahead();
|
|
648
|
+
}
|
|
649
|
+
}, [foundMatch, multiple, open, resetClosedTypeahead]);
|
|
402
650
|
if (process.env.NODE_ENV !== 'production') {
|
|
403
651
|
// TODO: uncomment once we enable eslint-plugin-react-compiler // eslint-disable-next-line react-compiler/react-compiler
|
|
404
652
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
@@ -448,6 +696,7 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
448
696
|
};
|
|
449
697
|
const classes = useUtilityClasses(ownerState);
|
|
450
698
|
const menuPaperSlotProps = typeof MenuProps.slotProps?.paper === 'function' ? MenuProps.slotProps.paper(ownerState) : MenuProps.slotProps?.paper;
|
|
699
|
+
const handlePaperRef = useForkRef(menuPaperSlotProps?.ref, paperRef);
|
|
451
700
|
const menuListSlotProps = typeof MenuProps.slotProps?.list === 'function' ? MenuProps.slotProps.list(ownerState) : MenuProps.slotProps?.list;
|
|
452
701
|
const listboxId = useId();
|
|
453
702
|
const nativeInputId = useId();
|
|
@@ -461,8 +710,9 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
461
710
|
"aria-disabled": disabled ? 'true' : undefined,
|
|
462
711
|
"aria-expanded": open ? 'true' : 'false',
|
|
463
712
|
"aria-haspopup": "listbox",
|
|
713
|
+
"aria-readonly": readOnly ? 'true' : undefined,
|
|
464
714
|
"aria-label": ariaLabel,
|
|
465
|
-
"aria-labelledby":
|
|
715
|
+
"aria-labelledby": labelId,
|
|
466
716
|
"aria-describedby": ariaDescribedby,
|
|
467
717
|
"aria-required": required ? 'true' : undefined,
|
|
468
718
|
"aria-invalid": error ? 'true' : undefined,
|
|
@@ -491,6 +741,7 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
491
741
|
onChange: handleChange,
|
|
492
742
|
tabIndex: -1,
|
|
493
743
|
disabled: disabled,
|
|
744
|
+
readOnly: readOnly,
|
|
494
745
|
className: classes.nativeInput,
|
|
495
746
|
autoFocus: autoFocus,
|
|
496
747
|
required: required,
|
|
@@ -529,6 +780,7 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
|
|
|
529
780
|
},
|
|
530
781
|
paper: {
|
|
531
782
|
...menuPaperSlotProps,
|
|
783
|
+
ref: handlePaperRef,
|
|
532
784
|
style: {
|
|
533
785
|
minWidth: menuMinWidth,
|
|
534
786
|
...menuPaperSlotProps?.style
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
|
|
4
|
+
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.canCycleRepeatedCharacter = canCycleRepeatedCharacter;
|
|
9
|
+
exports.getMatchingOptionIndex = getMatchingOptionIndex;
|
|
10
|
+
exports.getTypeaheadOptions = getTypeaheadOptions;
|
|
11
|
+
var React = _interopRequireWildcard(require("react"));
|
|
12
|
+
var _areEqualValues = _interopRequireDefault(require("./areEqualValues"));
|
|
13
|
+
function hasOwnValueProp(child) {
|
|
14
|
+
return Object.prototype.hasOwnProperty.call(child.props, 'value');
|
|
15
|
+
}
|
|
16
|
+
function getTextFromReactNode(node) {
|
|
17
|
+
if (typeof node === 'string' || typeof node === 'number') {
|
|
18
|
+
return String(node);
|
|
19
|
+
}
|
|
20
|
+
let text = '';
|
|
21
|
+
React.Children.forEach(node, child => {
|
|
22
|
+
if (typeof child === 'string' || typeof child === 'number') {
|
|
23
|
+
text += String(child);
|
|
24
|
+
} else if (/*#__PURE__*/React.isValidElement(child)) {
|
|
25
|
+
text += getTextFromReactNode(child.props.children);
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
return text;
|
|
29
|
+
}
|
|
30
|
+
function getMatchingOptionIndex(options, search, startIndex = 0) {
|
|
31
|
+
if (options.length === 0) {
|
|
32
|
+
return -1;
|
|
33
|
+
}
|
|
34
|
+
const normalizedStartIndex = (startIndex % options.length + options.length) % options.length;
|
|
35
|
+
for (let offset = 0; offset < options.length; offset += 1) {
|
|
36
|
+
const index = (normalizedStartIndex + offset) % options.length;
|
|
37
|
+
if (options[index].label.startsWith(search)) {
|
|
38
|
+
return index;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return -1;
|
|
42
|
+
}
|
|
43
|
+
function canCycleRepeatedCharacter(options, key) {
|
|
44
|
+
return !options.some(option => option.label[0] === key && option.label[1] === key);
|
|
45
|
+
}
|
|
46
|
+
function getTypeaheadOptions(childrenArray, value) {
|
|
47
|
+
const options = [];
|
|
48
|
+
let selectedIndex = -1;
|
|
49
|
+
for (let index = 0; index < childrenArray.length; index += 1) {
|
|
50
|
+
const child = childrenArray[index];
|
|
51
|
+
if (! /*#__PURE__*/React.isValidElement(child) || !hasOwnValueProp(child) || child.props.disabled) {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Closed typeahead cannot exclude CSS-hidden text because no option DOM is mounted.
|
|
56
|
+
const label = getTextFromReactNode(child.props.children).trim().toLowerCase();
|
|
57
|
+
if (label === '') {
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
if (selectedIndex === -1 && (0, _areEqualValues.default)(value, child.props.value)) {
|
|
61
|
+
selectedIndex = options.length;
|
|
62
|
+
}
|
|
63
|
+
options.push({
|
|
64
|
+
child,
|
|
65
|
+
label,
|
|
66
|
+
value: child.props.value
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
options,
|
|
71
|
+
selectedIndex
|
|
72
|
+
};
|
|
73
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import areEqualValues from "./areEqualValues.mjs";
|
|
3
|
+
function hasOwnValueProp(child) {
|
|
4
|
+
return Object.prototype.hasOwnProperty.call(child.props, 'value');
|
|
5
|
+
}
|
|
6
|
+
function getTextFromReactNode(node) {
|
|
7
|
+
if (typeof node === 'string' || typeof node === 'number') {
|
|
8
|
+
return String(node);
|
|
9
|
+
}
|
|
10
|
+
let text = '';
|
|
11
|
+
React.Children.forEach(node, child => {
|
|
12
|
+
if (typeof child === 'string' || typeof child === 'number') {
|
|
13
|
+
text += String(child);
|
|
14
|
+
} else if (/*#__PURE__*/React.isValidElement(child)) {
|
|
15
|
+
text += getTextFromReactNode(child.props.children);
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
return text;
|
|
19
|
+
}
|
|
20
|
+
export function getMatchingOptionIndex(options, search, startIndex = 0) {
|
|
21
|
+
if (options.length === 0) {
|
|
22
|
+
return -1;
|
|
23
|
+
}
|
|
24
|
+
const normalizedStartIndex = (startIndex % options.length + options.length) % options.length;
|
|
25
|
+
for (let offset = 0; offset < options.length; offset += 1) {
|
|
26
|
+
const index = (normalizedStartIndex + offset) % options.length;
|
|
27
|
+
if (options[index].label.startsWith(search)) {
|
|
28
|
+
return index;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return -1;
|
|
32
|
+
}
|
|
33
|
+
export function canCycleRepeatedCharacter(options, key) {
|
|
34
|
+
return !options.some(option => option.label[0] === key && option.label[1] === key);
|
|
35
|
+
}
|
|
36
|
+
export function getTypeaheadOptions(childrenArray, value) {
|
|
37
|
+
const options = [];
|
|
38
|
+
let selectedIndex = -1;
|
|
39
|
+
for (let index = 0; index < childrenArray.length; index += 1) {
|
|
40
|
+
const child = childrenArray[index];
|
|
41
|
+
if (! /*#__PURE__*/React.isValidElement(child) || !hasOwnValueProp(child) || child.props.disabled) {
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Closed typeahead cannot exclude CSS-hidden text because no option DOM is mounted.
|
|
46
|
+
const label = getTextFromReactNode(child.props.children).trim().toLowerCase();
|
|
47
|
+
if (label === '') {
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (selectedIndex === -1 && areEqualValues(value, child.props.value)) {
|
|
51
|
+
selectedIndex = options.length;
|
|
52
|
+
}
|
|
53
|
+
options.push({
|
|
54
|
+
child,
|
|
55
|
+
label,
|
|
56
|
+
value: child.props.value
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
options,
|
|
61
|
+
selectedIndex
|
|
62
|
+
};
|
|
63
|
+
}
|
package/Skeleton/Skeleton.js
CHANGED
|
@@ -15,6 +15,7 @@ var _styles = require("../styles");
|
|
|
15
15
|
var _zeroStyled = require("../zero-styled");
|
|
16
16
|
var _memoTheme = _interopRequireDefault(require("../utils/memoTheme"));
|
|
17
17
|
var _DefaultPropsProvider = require("../DefaultPropsProvider");
|
|
18
|
+
var _utils = require("../transitions/utils");
|
|
18
19
|
var _skeletonClasses = require("./skeletonClasses");
|
|
19
20
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
20
21
|
const useUtilityClasses = ownerState => {
|
|
@@ -84,6 +85,15 @@ const SkeletonRoot = (0, _zeroStyled.styled)('span', {
|
|
|
84
85
|
}) => {
|
|
85
86
|
const radiusUnit = (0, _styles.unstable_getUnit)(theme.shape.borderRadius) || 'px';
|
|
86
87
|
const radiusValue = (0, _styles.unstable_toUnitless)(theme.shape.borderRadius);
|
|
88
|
+
const reducedMotionPulseStyles = (0, _utils.getReducedMotionStyles)(theme, {
|
|
89
|
+
animation: 'none'
|
|
90
|
+
});
|
|
91
|
+
const reducedMotionWaveStyles = (0, _utils.getReducedMotionStyles)(theme, {
|
|
92
|
+
'&::after': {
|
|
93
|
+
animation: 'none',
|
|
94
|
+
display: 'none'
|
|
95
|
+
}
|
|
96
|
+
});
|
|
87
97
|
return {
|
|
88
98
|
display: 'block',
|
|
89
99
|
// Create a "on paper" color with sufficient contrast retaining the color
|
|
@@ -148,7 +158,12 @@ const SkeletonRoot = (0, _zeroStyled.styled)('span', {
|
|
|
148
158
|
style: pulseAnimation || {
|
|
149
159
|
animation: `${pulseKeyframe} 2s ease-in-out 0.5s infinite`
|
|
150
160
|
}
|
|
151
|
-
}, {
|
|
161
|
+
}, ...(reducedMotionPulseStyles ? [{
|
|
162
|
+
props: {
|
|
163
|
+
animation: 'pulse'
|
|
164
|
+
},
|
|
165
|
+
style: reducedMotionPulseStyles
|
|
166
|
+
}] : []), {
|
|
152
167
|
props: {
|
|
153
168
|
animation: 'wave'
|
|
154
169
|
},
|
|
@@ -182,7 +197,12 @@ const SkeletonRoot = (0, _zeroStyled.styled)('span', {
|
|
|
182
197
|
animation: `${waveKeyframe} 2s linear 0.5s infinite`
|
|
183
198
|
}
|
|
184
199
|
}
|
|
185
|
-
}
|
|
200
|
+
}, ...(reducedMotionWaveStyles ? [{
|
|
201
|
+
props: {
|
|
202
|
+
animation: 'wave'
|
|
203
|
+
},
|
|
204
|
+
style: reducedMotionWaveStyles
|
|
205
|
+
}] : [])]
|
|
186
206
|
};
|
|
187
207
|
}));
|
|
188
208
|
const Skeleton = /*#__PURE__*/React.forwardRef(function Skeleton(inProps, ref) {
|
package/Skeleton/Skeleton.mjs
CHANGED
|
@@ -8,6 +8,7 @@ import { unstable_getUnit as getUnit, unstable_toUnitless as toUnitless } from "
|
|
|
8
8
|
import { keyframes, css, styled } from "../zero-styled/index.mjs";
|
|
9
9
|
import memoTheme from "../utils/memoTheme.mjs";
|
|
10
10
|
import { useDefaultProps } from "../DefaultPropsProvider/index.mjs";
|
|
11
|
+
import { getReducedMotionStyles } from "../transitions/utils.mjs";
|
|
11
12
|
import { getSkeletonUtilityClass } from "./skeletonClasses.mjs";
|
|
12
13
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
13
14
|
const useUtilityClasses = ownerState => {
|
|
@@ -77,6 +78,15 @@ const SkeletonRoot = styled('span', {
|
|
|
77
78
|
}) => {
|
|
78
79
|
const radiusUnit = getUnit(theme.shape.borderRadius) || 'px';
|
|
79
80
|
const radiusValue = toUnitless(theme.shape.borderRadius);
|
|
81
|
+
const reducedMotionPulseStyles = getReducedMotionStyles(theme, {
|
|
82
|
+
animation: 'none'
|
|
83
|
+
});
|
|
84
|
+
const reducedMotionWaveStyles = getReducedMotionStyles(theme, {
|
|
85
|
+
'&::after': {
|
|
86
|
+
animation: 'none',
|
|
87
|
+
display: 'none'
|
|
88
|
+
}
|
|
89
|
+
});
|
|
80
90
|
return {
|
|
81
91
|
display: 'block',
|
|
82
92
|
// Create a "on paper" color with sufficient contrast retaining the color
|
|
@@ -141,7 +151,12 @@ const SkeletonRoot = styled('span', {
|
|
|
141
151
|
style: pulseAnimation || {
|
|
142
152
|
animation: `${pulseKeyframe} 2s ease-in-out 0.5s infinite`
|
|
143
153
|
}
|
|
144
|
-
}, {
|
|
154
|
+
}, ...(reducedMotionPulseStyles ? [{
|
|
155
|
+
props: {
|
|
156
|
+
animation: 'pulse'
|
|
157
|
+
},
|
|
158
|
+
style: reducedMotionPulseStyles
|
|
159
|
+
}] : []), {
|
|
145
160
|
props: {
|
|
146
161
|
animation: 'wave'
|
|
147
162
|
},
|
|
@@ -175,7 +190,12 @@ const SkeletonRoot = styled('span', {
|
|
|
175
190
|
animation: `${waveKeyframe} 2s linear 0.5s infinite`
|
|
176
191
|
}
|
|
177
192
|
}
|
|
178
|
-
}
|
|
193
|
+
}, ...(reducedMotionWaveStyles ? [{
|
|
194
|
+
props: {
|
|
195
|
+
animation: 'wave'
|
|
196
|
+
},
|
|
197
|
+
style: reducedMotionWaveStyles
|
|
198
|
+
}] : [])]
|
|
179
199
|
};
|
|
180
200
|
}));
|
|
181
201
|
const Skeleton = /*#__PURE__*/React.forwardRef(function Skeleton(inProps, ref) {
|