@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
|
@@ -2,16 +2,109 @@
|
|
|
2
2
|
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import PropTypes from 'prop-types';
|
|
5
|
-
import { TransitionGroup } from 'react-transition-group';
|
|
6
5
|
import clsx from 'clsx';
|
|
6
|
+
import useOnMount from '@mui/utils/useOnMount';
|
|
7
7
|
import useTimeout from '@mui/utils/useTimeout';
|
|
8
|
-
import { keyframes, styled } from "../zero-styled/index.mjs";
|
|
8
|
+
import { keyframes, css, styled, useTheme } from "../zero-styled/index.mjs";
|
|
9
9
|
import { useDefaultProps } from "../DefaultPropsProvider/index.mjs";
|
|
10
10
|
import Ripple from "./Ripple.mjs";
|
|
11
11
|
import touchRippleClasses from "./touchRippleClasses.mjs";
|
|
12
|
+
import useEventCallback from "../utils/useEventCallback.mjs";
|
|
13
|
+
import useReducedMotion from "../transitions/useReducedMotion.mjs";
|
|
12
14
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
13
15
|
const DURATION = 550;
|
|
14
16
|
export const DELAY_RIPPLE = 80;
|
|
17
|
+
const EMPTY_OBJ = {};
|
|
18
|
+
const EMPTY_ARRAY = [];
|
|
19
|
+
const NOOP = () => {};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Keep the same DOM order TouchRipple had when it used react-transition-group:
|
|
23
|
+
* exiting ripples stay in place, and new ripples are inserted before the final
|
|
24
|
+
* group of ripples that are waiting for their exit animation to finish.
|
|
25
|
+
*
|
|
26
|
+
* @param {number[]} prevOrder The previous DOM order, including ripples that may be exiting.
|
|
27
|
+
* @param {number[]} nextActiveKeys The ripples that should still be treated as active.
|
|
28
|
+
* @returns {number[]} The next DOM order, preserving the position of exiting ripples where possible.
|
|
29
|
+
*/
|
|
30
|
+
function mergeRippleOrder(prevOrder, nextActiveKeys) {
|
|
31
|
+
const nextKeySet = new Set(nextActiveKeys);
|
|
32
|
+
const nextKeysPending = new Map();
|
|
33
|
+
let pendingKeys = [];
|
|
34
|
+
for (const prevKey of prevOrder) {
|
|
35
|
+
if (nextKeySet.has(prevKey)) {
|
|
36
|
+
if (pendingKeys.length > 0) {
|
|
37
|
+
nextKeysPending.set(prevKey, pendingKeys);
|
|
38
|
+
pendingKeys = [];
|
|
39
|
+
}
|
|
40
|
+
} else {
|
|
41
|
+
pendingKeys.push(prevKey);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const nextOrder = [];
|
|
45
|
+
for (const nextKey of nextActiveKeys) {
|
|
46
|
+
const pendingBefore = nextKeysPending.get(nextKey);
|
|
47
|
+
if (pendingBefore) {
|
|
48
|
+
nextOrder.push(...pendingBefore);
|
|
49
|
+
}
|
|
50
|
+
nextOrder.push(nextKey);
|
|
51
|
+
}
|
|
52
|
+
nextOrder.push(...pendingKeys);
|
|
53
|
+
return nextOrder;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Calculate where the ripple should start and how large it must be to cover the host element.
|
|
58
|
+
*
|
|
59
|
+
* @param {object} params
|
|
60
|
+
* @param {object} params.event The mouse or touch event that started the ripple.
|
|
61
|
+
* @param {HTMLElement | null} params.element The host element used for measurements. Tests pass `null`.
|
|
62
|
+
* @param {boolean} params.center If `true`, start the ripple from the center of the host element.
|
|
63
|
+
* @returns {{ rippleX: number, rippleY: number, rippleSize: number }} The ripple position and size.
|
|
64
|
+
*/
|
|
65
|
+
function computeRippleState({
|
|
66
|
+
event,
|
|
67
|
+
element,
|
|
68
|
+
center
|
|
69
|
+
}) {
|
|
70
|
+
const rect = element ? element.getBoundingClientRect() : {
|
|
71
|
+
width: 0,
|
|
72
|
+
height: 0,
|
|
73
|
+
left: 0,
|
|
74
|
+
top: 0
|
|
75
|
+
};
|
|
76
|
+
let rippleX;
|
|
77
|
+
let rippleY;
|
|
78
|
+
if (center || event === undefined || event.clientX === 0 && event.clientY === 0 || !event.clientX && !event.touches) {
|
|
79
|
+
rippleX = Math.round(rect.width / 2);
|
|
80
|
+
rippleY = Math.round(rect.height / 2);
|
|
81
|
+
} else {
|
|
82
|
+
const {
|
|
83
|
+
clientX,
|
|
84
|
+
clientY
|
|
85
|
+
} = event.touches && event.touches.length > 0 ? event.touches[0] : event;
|
|
86
|
+
rippleX = Math.round(clientX - rect.left);
|
|
87
|
+
rippleY = Math.round(clientY - rect.top);
|
|
88
|
+
}
|
|
89
|
+
let rippleSize;
|
|
90
|
+
if (center) {
|
|
91
|
+
rippleSize = Math.sqrt((2 * rect.width ** 2 + rect.height ** 2) / 3);
|
|
92
|
+
|
|
93
|
+
// Mobile Chrome can skip this animation for even pixel sizes.
|
|
94
|
+
if (rippleSize % 2 === 0) {
|
|
95
|
+
rippleSize += 1;
|
|
96
|
+
}
|
|
97
|
+
} else {
|
|
98
|
+
const sizeX = Math.max(Math.abs((element ? element.clientWidth : 0) - rippleX), rippleX) * 2 + 2;
|
|
99
|
+
const sizeY = Math.max(Math.abs((element ? element.clientHeight : 0) - rippleY), rippleY) * 2 + 2;
|
|
100
|
+
rippleSize = Math.sqrt(sizeX ** 2 + sizeY ** 2);
|
|
101
|
+
}
|
|
102
|
+
return {
|
|
103
|
+
rippleX,
|
|
104
|
+
rippleY,
|
|
105
|
+
rippleSize
|
|
106
|
+
};
|
|
107
|
+
}
|
|
15
108
|
const enterKeyframe = keyframes`
|
|
16
109
|
0% {
|
|
17
110
|
transform: scale(0);
|
|
@@ -45,6 +138,44 @@ const pulsateKeyframe = keyframes`
|
|
|
45
138
|
transform: scale(1);
|
|
46
139
|
}
|
|
47
140
|
`;
|
|
141
|
+
function getAnimationStyles(theme) {
|
|
142
|
+
if (theme.motion.reducedMotion === 'always') {
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
const styles = css`
|
|
146
|
+
&.${touchRippleClasses.rippleVisible} {
|
|
147
|
+
animation-name: ${enterKeyframe};
|
|
148
|
+
animation-duration: ${DURATION}ms;
|
|
149
|
+
animation-timing-function: ${theme.transitions.easing.easeInOut};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
&.${touchRippleClasses.ripplePulsate} {
|
|
153
|
+
animation-duration: ${theme.transitions.duration.shorter}ms;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
& .${touchRippleClasses.childLeaving} {
|
|
157
|
+
animation-name: ${exitKeyframe};
|
|
158
|
+
animation-duration: ${DURATION}ms;
|
|
159
|
+
animation-timing-function: ${theme.transitions.easing.easeInOut};
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
& .${touchRippleClasses.childPulsate} {
|
|
163
|
+
animation-name: ${pulsateKeyframe};
|
|
164
|
+
animation-duration: 2500ms;
|
|
165
|
+
animation-timing-function: ${theme.transitions.easing.easeInOut};
|
|
166
|
+
animation-iteration-count: infinite;
|
|
167
|
+
animation-delay: 200ms;
|
|
168
|
+
}
|
|
169
|
+
`;
|
|
170
|
+
if (theme.motion.reducedMotion === 'system') {
|
|
171
|
+
return css`
|
|
172
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
173
|
+
${styles}
|
|
174
|
+
}
|
|
175
|
+
`;
|
|
176
|
+
}
|
|
177
|
+
return styles;
|
|
178
|
+
}
|
|
48
179
|
export const TouchRippleRoot = styled('span', {
|
|
49
180
|
name: 'MuiTouchRipple',
|
|
50
181
|
slot: 'Root'
|
|
@@ -60,8 +191,8 @@ export const TouchRippleRoot = styled('span', {
|
|
|
60
191
|
borderRadius: 'inherit'
|
|
61
192
|
});
|
|
62
193
|
|
|
63
|
-
// This `styled()`
|
|
64
|
-
// in
|
|
194
|
+
// This `styled()` call uses keyframes. styled-components only supports keyframes
|
|
195
|
+
// in template strings, so do not convert these styles to a JS object.
|
|
65
196
|
export const TouchRippleRipple = styled(Ripple, {
|
|
66
197
|
name: 'MuiTouchRipple',
|
|
67
198
|
slot: 'Ripple'
|
|
@@ -72,35 +203,10 @@ export const TouchRippleRipple = styled(Ripple, {
|
|
|
72
203
|
&.${touchRippleClasses.rippleVisible} {
|
|
73
204
|
opacity: 0.3;
|
|
74
205
|
transform: scale(1);
|
|
75
|
-
animation-name: ${enterKeyframe};
|
|
76
|
-
animation-duration: ${DURATION}ms;
|
|
77
|
-
animation-timing-function: ${({
|
|
78
|
-
theme
|
|
79
|
-
}) => theme.transitions.easing.easeInOut};
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
&.${touchRippleClasses.ripplePulsate} {
|
|
83
|
-
animation-duration: ${({
|
|
84
|
-
theme
|
|
85
|
-
}) => theme.transitions.duration.shorter}ms;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
& .${touchRippleClasses.child} {
|
|
89
|
-
opacity: 1;
|
|
90
|
-
display: block;
|
|
91
|
-
width: 100%;
|
|
92
|
-
height: 100%;
|
|
93
|
-
border-radius: 50%;
|
|
94
|
-
background-color: currentColor;
|
|
95
206
|
}
|
|
96
207
|
|
|
97
208
|
& .${touchRippleClasses.childLeaving} {
|
|
98
209
|
opacity: 0;
|
|
99
|
-
animation-name: ${exitKeyframe};
|
|
100
|
-
animation-duration: ${DURATION}ms;
|
|
101
|
-
animation-timing-function: ${({
|
|
102
|
-
theme
|
|
103
|
-
}) => theme.transitions.easing.easeInOut};
|
|
104
210
|
}
|
|
105
211
|
|
|
106
212
|
& .${touchRippleClasses.childPulsate} {
|
|
@@ -108,35 +214,54 @@ export const TouchRippleRipple = styled(Ripple, {
|
|
|
108
214
|
/* @noflip */
|
|
109
215
|
left: 0px;
|
|
110
216
|
top: 0;
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
${({
|
|
114
220
|
theme
|
|
115
|
-
}) => theme
|
|
116
|
-
|
|
117
|
-
|
|
221
|
+
}) => getAnimationStyles(theme)}
|
|
222
|
+
|
|
223
|
+
& .${touchRippleClasses.child} {
|
|
224
|
+
opacity: 1;
|
|
225
|
+
display: block;
|
|
226
|
+
width: 100%;
|
|
227
|
+
height: 100%;
|
|
228
|
+
border-radius: 50%;
|
|
229
|
+
background-color: currentColor;
|
|
118
230
|
}
|
|
119
231
|
`;
|
|
120
232
|
|
|
121
233
|
/**
|
|
122
234
|
* @ignore - internal component.
|
|
123
|
-
*
|
|
124
|
-
* TODO v5: Make private
|
|
125
235
|
*/
|
|
126
236
|
const TouchRipple = /*#__PURE__*/React.forwardRef(function TouchRipple(inProps, ref) {
|
|
127
237
|
const props = useDefaultProps({
|
|
128
238
|
props: inProps,
|
|
129
239
|
name: 'MuiTouchRipple'
|
|
130
240
|
});
|
|
241
|
+
const theme = useTheme();
|
|
242
|
+
const reducedMotion = useReducedMotion(theme.motion.reducedMotion, false);
|
|
131
243
|
const {
|
|
132
244
|
center: centerProp = false,
|
|
133
|
-
classes =
|
|
245
|
+
classes = EMPTY_OBJ,
|
|
134
246
|
className,
|
|
135
247
|
...other
|
|
136
248
|
} = props;
|
|
137
|
-
|
|
249
|
+
// Store ripples as data so we can keep exiting ripples mounted until their
|
|
250
|
+
// exit animation ends. Ripple calls onExited when it is safe to remove one.
|
|
251
|
+
const [rippleState, setRippleState] = React.useState({
|
|
252
|
+
items: EMPTY_ARRAY,
|
|
253
|
+
order: EMPTY_ARRAY
|
|
254
|
+
});
|
|
255
|
+
const ripples = rippleState.items;
|
|
138
256
|
const nextKey = React.useRef(0);
|
|
139
257
|
const rippleCallback = React.useRef(null);
|
|
258
|
+
const mountedRef = React.useRef(false);
|
|
259
|
+
useOnMount(() => {
|
|
260
|
+
mountedRef.current = true;
|
|
261
|
+
return () => {
|
|
262
|
+
mountedRef.current = false;
|
|
263
|
+
};
|
|
264
|
+
});
|
|
140
265
|
React.useEffect(() => {
|
|
141
266
|
if (rippleCallback.current) {
|
|
142
267
|
rippleCallback.current();
|
|
@@ -150,10 +275,23 @@ const TouchRipple = /*#__PURE__*/React.forwardRef(function TouchRipple(inProps,
|
|
|
150
275
|
// We don't want to display the ripple for touch scroll events.
|
|
151
276
|
const startTimer = useTimeout();
|
|
152
277
|
|
|
153
|
-
//
|
|
278
|
+
// Holds delayed touch-start work until the delay expires or touchend forces it to run.
|
|
154
279
|
const startTimerCommit = React.useRef(null);
|
|
155
280
|
const container = React.useRef(null);
|
|
156
|
-
const
|
|
281
|
+
const handleExited = useEventCallback(key => {
|
|
282
|
+
if (!mountedRef.current) {
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
setRippleState(prevState => {
|
|
286
|
+
const nextItems = prevState.items.filter(ripple => ripple.key !== key);
|
|
287
|
+
const nextOrder = mergeRippleOrder(prevState.order.filter(rippleKey => rippleKey !== key), nextItems.filter(ripple => !ripple.exiting).map(ripple => ripple.key));
|
|
288
|
+
return {
|
|
289
|
+
items: nextItems,
|
|
290
|
+
order: nextOrder
|
|
291
|
+
};
|
|
292
|
+
});
|
|
293
|
+
});
|
|
294
|
+
const startCommit = useEventCallback(params => {
|
|
157
295
|
const {
|
|
158
296
|
pulsate,
|
|
159
297
|
rippleX,
|
|
@@ -161,29 +299,29 @@ const TouchRipple = /*#__PURE__*/React.forwardRef(function TouchRipple(inProps,
|
|
|
161
299
|
rippleSize,
|
|
162
300
|
cb
|
|
163
301
|
} = params;
|
|
164
|
-
|
|
165
|
-
classes: {
|
|
166
|
-
ripple: clsx(classes.ripple, touchRippleClasses.ripple),
|
|
167
|
-
rippleVisible: clsx(classes.rippleVisible, touchRippleClasses.rippleVisible),
|
|
168
|
-
ripplePulsate: clsx(classes.ripplePulsate, touchRippleClasses.ripplePulsate),
|
|
169
|
-
child: clsx(classes.child, touchRippleClasses.child),
|
|
170
|
-
childLeaving: clsx(classes.childLeaving, touchRippleClasses.childLeaving),
|
|
171
|
-
childPulsate: clsx(classes.childPulsate, touchRippleClasses.childPulsate)
|
|
172
|
-
},
|
|
173
|
-
timeout: DURATION,
|
|
174
|
-
pulsate: pulsate,
|
|
175
|
-
rippleX: rippleX,
|
|
176
|
-
rippleY: rippleY,
|
|
177
|
-
rippleSize: rippleSize
|
|
178
|
-
}, nextKey.current)]);
|
|
302
|
+
const key = nextKey.current;
|
|
179
303
|
nextKey.current += 1;
|
|
304
|
+
setRippleState(prevState => {
|
|
305
|
+
const nextItems = [...prevState.items, {
|
|
306
|
+
key,
|
|
307
|
+
pulsate,
|
|
308
|
+
rippleX,
|
|
309
|
+
rippleY,
|
|
310
|
+
rippleSize,
|
|
311
|
+
exiting: false
|
|
312
|
+
}];
|
|
313
|
+
return {
|
|
314
|
+
items: nextItems,
|
|
315
|
+
order: mergeRippleOrder(prevState.order, nextItems.filter(ripple => !ripple.exiting).map(ripple => ripple.key))
|
|
316
|
+
};
|
|
317
|
+
});
|
|
180
318
|
rippleCallback.current = cb;
|
|
181
|
-
}
|
|
182
|
-
const start =
|
|
319
|
+
});
|
|
320
|
+
const start = useEventCallback((event = EMPTY_OBJ, options = EMPTY_OBJ, cb = NOOP) => {
|
|
183
321
|
const {
|
|
184
322
|
pulsate = false,
|
|
185
323
|
center = centerProp || options.pulsate,
|
|
186
|
-
fakeElement = false //
|
|
324
|
+
fakeElement = false // Used only by tests.
|
|
187
325
|
} = options;
|
|
188
326
|
if (event?.type === 'mousedown' && ignoringMouseDown.current) {
|
|
189
327
|
ignoringMouseDown.current = false;
|
|
@@ -193,48 +331,21 @@ const TouchRipple = /*#__PURE__*/React.forwardRef(function TouchRipple(inProps,
|
|
|
193
331
|
ignoringMouseDown.current = true;
|
|
194
332
|
}
|
|
195
333
|
const element = fakeElement ? null : container.current;
|
|
196
|
-
const
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
let rippleY;
|
|
206
|
-
let rippleSize;
|
|
207
|
-
if (center || event === undefined || event.clientX === 0 && event.clientY === 0 || !event.clientX && !event.touches) {
|
|
208
|
-
rippleX = Math.round(rect.width / 2);
|
|
209
|
-
rippleY = Math.round(rect.height / 2);
|
|
210
|
-
} else {
|
|
211
|
-
const {
|
|
212
|
-
clientX,
|
|
213
|
-
clientY
|
|
214
|
-
} = event.touches && event.touches.length > 0 ? event.touches[0] : event;
|
|
215
|
-
rippleX = Math.round(clientX - rect.left);
|
|
216
|
-
rippleY = Math.round(clientY - rect.top);
|
|
217
|
-
}
|
|
218
|
-
if (center) {
|
|
219
|
-
rippleSize = Math.sqrt((2 * rect.width ** 2 + rect.height ** 2) / 3);
|
|
220
|
-
|
|
221
|
-
// For some reason the animation is broken on Mobile Chrome if the size is even.
|
|
222
|
-
if (rippleSize % 2 === 0) {
|
|
223
|
-
rippleSize += 1;
|
|
224
|
-
}
|
|
225
|
-
} else {
|
|
226
|
-
const sizeX = Math.max(Math.abs((element ? element.clientWidth : 0) - rippleX), rippleX) * 2 + 2;
|
|
227
|
-
const sizeY = Math.max(Math.abs((element ? element.clientHeight : 0) - rippleY), rippleY) * 2 + 2;
|
|
228
|
-
rippleSize = Math.sqrt(sizeX ** 2 + sizeY ** 2);
|
|
229
|
-
}
|
|
334
|
+
const {
|
|
335
|
+
rippleX,
|
|
336
|
+
rippleY,
|
|
337
|
+
rippleSize
|
|
338
|
+
} = computeRippleState({
|
|
339
|
+
event,
|
|
340
|
+
element,
|
|
341
|
+
center
|
|
342
|
+
});
|
|
230
343
|
|
|
231
|
-
//
|
|
344
|
+
// Delay touch ripples so scroll gestures do not flash a ripple.
|
|
232
345
|
if (event?.touches) {
|
|
233
|
-
//
|
|
234
|
-
//
|
|
235
|
-
// are running
|
|
346
|
+
// Ignore extra touchstart events from multi-touch. There is only one
|
|
347
|
+
// delayed start callback to clear on unmount.
|
|
236
348
|
if (startTimerCommit.current === null) {
|
|
237
|
-
// Prepare the ripple effect.
|
|
238
349
|
startTimerCommit.current = () => {
|
|
239
350
|
startCommit({
|
|
240
351
|
pulsate,
|
|
@@ -244,8 +355,6 @@ const TouchRipple = /*#__PURE__*/React.forwardRef(function TouchRipple(inProps,
|
|
|
244
355
|
cb
|
|
245
356
|
});
|
|
246
357
|
};
|
|
247
|
-
// Delay the execution of the ripple effect.
|
|
248
|
-
// We have to make a tradeoff with this delay value.
|
|
249
358
|
startTimer.start(DELAY_RIPPLE, () => {
|
|
250
359
|
if (startTimerCommit.current) {
|
|
251
360
|
startTimerCommit.current();
|
|
@@ -262,17 +371,17 @@ const TouchRipple = /*#__PURE__*/React.forwardRef(function TouchRipple(inProps,
|
|
|
262
371
|
cb
|
|
263
372
|
});
|
|
264
373
|
}
|
|
265
|
-
}
|
|
266
|
-
const pulsate =
|
|
267
|
-
start(
|
|
374
|
+
});
|
|
375
|
+
const pulsate = useEventCallback(() => {
|
|
376
|
+
start(EMPTY_OBJ, {
|
|
268
377
|
pulsate: true
|
|
269
378
|
});
|
|
270
|
-
}
|
|
271
|
-
const stop =
|
|
379
|
+
});
|
|
380
|
+
const stop = useEventCallback((event, cb) => {
|
|
272
381
|
startTimer.clear();
|
|
273
382
|
|
|
274
|
-
//
|
|
275
|
-
//
|
|
383
|
+
// If touch ends before the delay finishes, show the ripple now and stop it
|
|
384
|
+
// on the next tick so the user still gets feedback.
|
|
276
385
|
if (event?.type === 'touchend' && startTimerCommit.current) {
|
|
277
386
|
startTimerCommit.current();
|
|
278
387
|
startTimerCommit.current = null;
|
|
@@ -282,28 +391,55 @@ const TouchRipple = /*#__PURE__*/React.forwardRef(function TouchRipple(inProps,
|
|
|
282
391
|
return;
|
|
283
392
|
}
|
|
284
393
|
startTimerCommit.current = null;
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
394
|
+
setRippleState(prevState => {
|
|
395
|
+
const firstActiveIndex = prevState.items.findIndex(ripple => !ripple.exiting);
|
|
396
|
+
if (firstActiveIndex === -1) {
|
|
397
|
+
return prevState;
|
|
288
398
|
}
|
|
289
|
-
|
|
399
|
+
const nextItems = prevState.items.slice();
|
|
400
|
+
nextItems[firstActiveIndex] = {
|
|
401
|
+
...nextItems[firstActiveIndex],
|
|
402
|
+
exiting: true
|
|
403
|
+
};
|
|
404
|
+
return {
|
|
405
|
+
items: nextItems,
|
|
406
|
+
order: mergeRippleOrder(prevState.order, nextItems.filter(ripple => !ripple.exiting).map(ripple => ripple.key))
|
|
407
|
+
};
|
|
290
408
|
});
|
|
291
409
|
rippleCallback.current = cb;
|
|
292
|
-
}
|
|
410
|
+
});
|
|
293
411
|
React.useImperativeHandle(ref, () => ({
|
|
294
412
|
pulsate,
|
|
295
413
|
start,
|
|
296
414
|
stop
|
|
297
415
|
}), [pulsate, start, stop]);
|
|
416
|
+
const rippleByKey = new Map(ripples.map(ripple => [ripple.key, ripple]));
|
|
417
|
+
const orderedRipples = rippleState.order.map(rippleKey => rippleByKey.get(rippleKey)).filter(Boolean);
|
|
418
|
+
|
|
419
|
+
// Keep the old react-transition-group DOM order:
|
|
420
|
+
// exiting ripples stay in place, and new ripples are inserted before the
|
|
421
|
+
// final group waiting for its exit animation to finish.
|
|
298
422
|
return /*#__PURE__*/_jsx(TouchRippleRoot, {
|
|
299
423
|
className: clsx(touchRippleClasses.root, classes.root, className),
|
|
300
424
|
ref: container,
|
|
301
425
|
...other,
|
|
302
|
-
children: /*#__PURE__*/_jsx(
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
426
|
+
children: orderedRipples.map(ripple => /*#__PURE__*/_jsx(TouchRippleRipple, {
|
|
427
|
+
classes: {
|
|
428
|
+
ripple: clsx(classes.ripple, touchRippleClasses.ripple),
|
|
429
|
+
rippleVisible: clsx(classes.rippleVisible, touchRippleClasses.rippleVisible),
|
|
430
|
+
ripplePulsate: clsx(classes.ripplePulsate, touchRippleClasses.ripplePulsate),
|
|
431
|
+
child: clsx(classes.child, touchRippleClasses.child),
|
|
432
|
+
childLeaving: clsx(classes.childLeaving, touchRippleClasses.childLeaving),
|
|
433
|
+
childPulsate: clsx(classes.childPulsate, touchRippleClasses.childPulsate)
|
|
434
|
+
},
|
|
435
|
+
timeout: reducedMotion.shouldReduceMotion ? 0 : DURATION,
|
|
436
|
+
pulsate: ripple.pulsate,
|
|
437
|
+
rippleX: ripple.rippleX,
|
|
438
|
+
rippleY: ripple.rippleY,
|
|
439
|
+
rippleSize: ripple.rippleSize,
|
|
440
|
+
in: !ripple.exiting,
|
|
441
|
+
onExited: () => handleExited(ripple.key)
|
|
442
|
+
}, ripple.key))
|
|
307
443
|
});
|
|
308
444
|
});
|
|
309
445
|
process.env.NODE_ENV !== "production" ? TouchRipple.propTypes /* remove-proptypes */ = {
|