UNPKG

@mui/material

Version:

Quickly build beautiful React apps. MUI is a simple and customizable component library to build faster, beautiful, and more accessible React applications. Follow your own design system, or start with Material Design.

97 lines (92 loc) 3.4 kB
import * as React from 'react'; import { useEventCallback } from '../utils'; const useTouchRipple = props => { const { disabled, disableFocusRipple, disableRipple, disableTouchRipple, focusVisible, rippleRef } = props; React.useEffect(() => { if (focusVisible && !disableFocusRipple && !disableRipple) { rippleRef.current?.pulsate(); } }, [rippleRef, focusVisible, disableFocusRipple, disableRipple]); function useRippleHandler(rippleAction, skipRippleAction = disableTouchRipple) { return useEventCallback(event => { if (!skipRippleAction && rippleRef.current) { rippleRef.current[rippleAction](event); } return true; }); } const keydownRef = React.useRef(false); const handleKeyDown = useEventCallback(event => { if (!disableFocusRipple && !keydownRef.current && focusVisible && rippleRef.current && event.key === ' ') { keydownRef.current = true; rippleRef.current.stop(event, () => { rippleRef?.current?.start(event); }); } }); const handleKeyUp = useEventCallback(event => { // calling preventDefault in keyUp on a <button> will not dispatch a click event if Space is pressed // https://codesandbox.io/s/button-keyup-preventdefault-dn7f0 if (!disableFocusRipple && event.key === ' ' && rippleRef.current && focusVisible && !event.defaultPrevented) { keydownRef.current = false; rippleRef.current.stop(event, () => { rippleRef?.current?.pulsate(event); }); } }); const handleBlur = useRippleHandler('stop', false); const handleMouseDown = useRippleHandler('start'); const handleContextMenu = useRippleHandler('stop'); const handleDragLeave = useRippleHandler('stop'); const handleMouseUp = useRippleHandler('stop'); const handleMouseLeave = useRippleHandler('stop'); const handleTouchStart = useRippleHandler('start'); const handleTouchEnd = useRippleHandler('stop'); const handleTouchMove = useRippleHandler('stop'); const [mountedState, setMountedState] = React.useState(false); React.useEffect(() => { setMountedState(true); }, []); const enableTouchRipple = mountedState && !disableRipple && !disabled; const getRippleHandlers = React.useMemo(() => { const rippleHandlers = { onBlur: handleBlur, onKeyDown: handleKeyDown, onKeyUp: handleKeyUp, onMouseDown: handleMouseDown, onMouseUp: handleMouseUp, onMouseLeave: handleMouseLeave, onContextMenu: handleContextMenu, onDragLeave: handleDragLeave, onTouchStart: handleTouchStart, onTouchEnd: handleTouchEnd, onTouchMove: handleTouchMove }; return (otherEvents = {}) => { const eventNames = Object.keys(rippleHandlers); const wrappedEvents = eventNames.map(eventName => ({ name: eventName, handler: ev => { otherEvents[eventName]?.(ev); rippleHandlers[eventName](ev); } })); return wrappedEvents.reduce((acc, current) => { acc[current.name] = current.handler; return acc; }, {}); }; }, [handleBlur, handleKeyDown, handleKeyUp, handleMouseDown, handleMouseUp, handleMouseLeave, handleContextMenu, handleDragLeave, handleTouchStart, handleTouchEnd, handleTouchMove]); return { enableTouchRipple, getRippleHandlers }; }; export default useTouchRipple;