自定义样式的MUI IconButton与Tooltip兼容及Framer Motion配置问题
Tooltip错位的根因
你最初写的自定义Button是普通函数组件,没有做ref转发处理。MUI的Tooltip组件依赖子组件的ref获取DOM元素的坐标信息来计算提示框的位置,拿不到有效ref时就会默认定位到视口左上角,就是你遇到的问题。
你后续改用styled直接创建组件的写法是对的,MUI的styled API默认会处理ref转发,因此Tooltip可以正常获取按钮的DOM位置,定位就恢复正常了。
兼容Framer Motion动画的最终实现
直接用Framer Motion提供的motion()高阶组件,包装已经处理好样式的IconButton,再通过外层转发ref的函数组件控制动画是否启用即可,完整代码如下:
import { forwardRef } from 'react'; import { styled } from '@mui/material/styles'; import IconButton from '@mui/material/IconButton'; import { motion } from "framer-motion" export const Colors = ['#58b864', '#91d704', '#9ad436', '#fd9828', '#ff7826', '#fc4a41', '#e01f1f', '#4065ac', '#4065ac', '#4065ac', '#4065ac']; const properties = ['color', 'greyed', 'icon'] // 基础样式组件 const StyledIconButton = styled(IconButton, { shouldForwardProp: (prop) => !properties.includes(prop)}) (({ theme, color, greyed, icon }) => ({ borderRadius: '18%', height: '26px', width: '26px', fontSize: '15px', backgroundColor: greyed ? '#293357' : color, color: greyed ? (theme.palette.mode === 'dark' ? '#63697d' : '#bebebe') : '#fff' , '& svg': { fontSize: '16px' }, '&:hover': { color: '#fff', backgroundColor: color, filter: icon ? 'none' : 'brightness(1.2)', cursor: icon ? 'default' : 'pointer' }, '&.Mui-disabled': { backgroundColor: '#293357', color: '#666979' } })); // 包装为支持动画的组件 const MotionStyledButton = motion(StyledIconButton); // 转发ref的最终组件,控制动画逻辑 const Button = forwardRef((props, ref) => { const { icon, ...rest } = props; if (icon) { // 不需要动画的场景直接返回基础组件 return <StyledIconButton ref={ref} {...rest} /> } // 需要动画的场景返回带motion属性的组件 return ( <MotionStyledButton ref={ref} {...rest} whileHover={{ scale: 1.1, transition: { duration: 0.3 } }} whileTap={{ scale: 0.9 }} /> ) }) export default Button;
内容的提问来源于stack exchange,提问作者Teamol
相关产品推荐
相关产品推荐

