1 | import * as React from 'react';
|
2 | import { useEventCallback } from '../utils';
|
3 |
|
4 | const useTouchRipple = props => {
|
5 | const {
|
6 | disabled,
|
7 | disableFocusRipple,
|
8 | disableRipple,
|
9 | disableTouchRipple,
|
10 | focusVisible,
|
11 | rippleRef
|
12 | } = props;
|
13 | React.useEffect(() => {
|
14 | if (focusVisible && !disableFocusRipple && !disableRipple) {
|
15 | rippleRef.current?.pulsate();
|
16 | }
|
17 | }, [rippleRef, focusVisible, disableFocusRipple, disableRipple]);
|
18 |
|
19 | function useRippleHandler(rippleAction, skipRippleAction = disableTouchRipple) {
|
20 | return useEventCallback(event => {
|
21 | if (!skipRippleAction && rippleRef.current) {
|
22 | rippleRef.current[rippleAction](event);
|
23 | }
|
24 |
|
25 | return true;
|
26 | });
|
27 | }
|
28 |
|
29 | const keydownRef = React.useRef(false);
|
30 | const handleKeyDown = useEventCallback(event => {
|
31 | if (!disableFocusRipple && !keydownRef.current && focusVisible && rippleRef.current && event.key === ' ') {
|
32 | keydownRef.current = true;
|
33 | rippleRef.current.stop(event, () => {
|
34 | rippleRef?.current?.start(event);
|
35 | });
|
36 | }
|
37 | });
|
38 | const handleKeyUp = useEventCallback(event => {
|
39 |
|
40 |
|
41 | if (!disableFocusRipple && event.key === ' ' && rippleRef.current && focusVisible && !event.defaultPrevented) {
|
42 | keydownRef.current = false;
|
43 | rippleRef.current.stop(event, () => {
|
44 | rippleRef?.current?.pulsate(event);
|
45 | });
|
46 | }
|
47 | });
|
48 | const handleBlur = useRippleHandler('stop', false);
|
49 | const handleMouseDown = useRippleHandler('start');
|
50 | const handleContextMenu = useRippleHandler('stop');
|
51 | const handleDragLeave = useRippleHandler('stop');
|
52 | const handleMouseUp = useRippleHandler('stop');
|
53 | const handleMouseLeave = useRippleHandler('stop');
|
54 | const handleTouchStart = useRippleHandler('start');
|
55 | const handleTouchEnd = useRippleHandler('stop');
|
56 | const handleTouchMove = useRippleHandler('stop');
|
57 | const [mountedState, setMountedState] = React.useState(false);
|
58 | React.useEffect(() => {
|
59 | setMountedState(true);
|
60 | }, []);
|
61 | const enableTouchRipple = mountedState && !disableRipple && !disabled;
|
62 | const getRippleHandlers = React.useMemo(() => {
|
63 | const rippleHandlers = {
|
64 | onBlur: handleBlur,
|
65 | onKeyDown: handleKeyDown,
|
66 | onKeyUp: handleKeyUp,
|
67 | onMouseDown: handleMouseDown,
|
68 | onMouseUp: handleMouseUp,
|
69 | onMouseLeave: handleMouseLeave,
|
70 | onContextMenu: handleContextMenu,
|
71 | onDragLeave: handleDragLeave,
|
72 | onTouchStart: handleTouchStart,
|
73 | onTouchEnd: handleTouchEnd,
|
74 | onTouchMove: handleTouchMove
|
75 | };
|
76 | return (otherEvents = {}) => {
|
77 | const eventNames = Object.keys(rippleHandlers);
|
78 | const wrappedEvents = eventNames.map(eventName => ({
|
79 | name: eventName,
|
80 | handler: ev => {
|
81 | otherEvents[eventName]?.(ev);
|
82 | rippleHandlers[eventName](ev);
|
83 | }
|
84 | }));
|
85 | return wrappedEvents.reduce((acc, current) => {
|
86 | acc[current.name] = current.handler;
|
87 | return acc;
|
88 | }, {});
|
89 | };
|
90 | }, [handleBlur, handleKeyDown, handleKeyUp, handleMouseDown, handleMouseUp, handleMouseLeave, handleContextMenu, handleDragLeave, handleTouchStart, handleTouchEnd, handleTouchMove]);
|
91 | return {
|
92 | enableTouchRipple,
|
93 | getRippleHandlers
|
94 | };
|
95 | };
|
96 |
|
97 | export default useTouchRipple; |
\ | No newline at end of file |