如何让Material UI的SwipeableDrawer在桌面端支持拖拽?
实现Material UI SwipeableDrawer桌面端拖拽功能
可以实现桌面端鼠标拖拽开关SwipeableDrawer,默认组件仅响应移动端触摸拖拽,通过配置参数+自定义拖拽边缘区域,就能让桌面端支持鼠标拖拽操作。以下是基于你提供的代码改造后的实现方案:
核心修改点
- 启用桌面端拖拽触发:通过
disableSwipeToOpen和disableSwipeToClose参数开启拖拽开关权限 - 添加可见拖拽指示器:自定义拖拽边缘组件,给用户明确的拖拽交互提示
- 调整Drawer样式:让拖拽区域露出,确保鼠标能触发拖拽事件
完整实现代码
import * as React from 'react'; import { styled } from '@mui/material/styles'; import Button from '@mui/material/Button'; import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; import SwipeableDrawer from '@mui/material/SwipeableDrawer'; const drawerBleeding = 56; // 自定义拖拽指示器组件 const Puller = styled(Box)(({ theme, anchor }) => { const positionStyles = { left: anchor === 'left' ? '8px' : anchor === 'right' ? 'auto' : 'calc(50% - 15px)', right: anchor === 'right' ? '8px' : 'auto', top: anchor === 'top' ? '8px' : anchor === 'bottom' ? 'auto' : 'calc(50% - 3px)', bottom: anchor === 'bottom' ? '8px' : 'auto', }; return { width: anchor === 'top' || anchor === 'bottom' ? 30 : 6, height: anchor === 'top' || anchor === 'bottom' ? 6 : 30, backgroundColor: theme.palette.mode === 'light' ? '#e0e0e0' : '#333', borderRadius: 3, position: 'absolute', ...positionStyles, cursor: 'grab', }; }); // 自定义Drawer内容容器 const StyledDrawerContent = styled(Box)(({ theme, anchor }) => { const offsetStyles = { [anchor]: -drawerBleeding, borderRadius: { topLeft: anchor === 'top' || anchor === 'left' ? 8 : 0, topRight: anchor === 'top' || anchor === 'right' ? 8 : 0, bottomLeft: anchor === 'bottom' || anchor === 'left' ? 8 : 0, bottomRight: anchor === 'bottom' || anchor === 'right' ? 8 : 0, }, }; return { position: 'absolute', visibility: 'visible', left: anchor === 'left' || anchor === 'right' ? 0 : 'auto', right: anchor === 'left' || anchor === 'right' ? 0 : 'auto', top: anchor === 'top' || anchor === 'bottom' ? 0 : 'auto', bottom: anchor === 'top' || anchor === 'bottom' ? 0 : 'auto', ...offsetStyles, width: anchor === 'left' || anchor === 'right' ? `calc(100% + ${drawerBleeding}px)` : '100%', height: anchor === 'top' || anchor === 'bottom' ? `calc(100% + ${drawerBleeding}px)` : '100%', backgroundColor: theme.palette.mode === 'light' ? '#fff' : '#1a1a1a', }; }); export default function MultiAnchorSwipeableDrawer() { const [state, setState] = React.useState({ left: false, right: false, top: false, bottom: false, }); const toggleDrawer = (anchor, open) => () => { setState({ ...state, [anchor]: open }); }; const list = (anchor) => ( <StyledDrawerContent anchor={anchor} sx={{ p: 2 }}> <Puller anchor={anchor} /> <Typography variant="h6">{anchor} Drawer</Typography> <Box sx={{ mt: 2 }}> {/* 这里添加你的Drawer内容 */} <Typography>拖拽边缘可以在桌面端打开/关闭我</Typography> </Box> </StyledDrawerContent> ); return ( <Box sx={{ display: 'flex', gap: 2, p: 2 }}> {(['left', 'right', 'top', 'bottom']).map((anchor) => ( <React.Fragment key={anchor}> <Button onClick={toggleDrawer(anchor, true)}>{anchor}</Button> <SwipeableDrawer anchor={anchor} open={state[anchor]} onClose={toggleDrawer(anchor, false)} onOpen={toggleDrawer(anchor, true)} swipeAreaWidth={drawerBleeding} disableSwipeToOpen={false} disableSwipeToClose={false} ModalProps={{ keepMounted: true }} > {list(anchor)} </SwipeableDrawer> </React.Fragment> ))} </Box> ); }
关键配置说明
swipeAreaWidth={drawerBleeding}:设置拖拽触发区域的宽度,确保鼠标在Drawer边缘区域能触发拖拽事件disableSwipeToOpen={false}/disableSwipeToClose={false}:强制开启拖拽打开/关闭功能,覆盖默认仅移动端生效的限制- 自定义
Puller组件:根据Drawer的锚点位置(left/right/top/bottom)调整指示器的样式和位置,给用户明确的拖拽交互提示 StyledDrawerContent样式调整:让Drawer内容容器超出原区域,露出拖拽边缘,同时添加圆角优化视觉效果
内容的提问来源于stack exchange,提问作者AG_HIHI
相关产品推荐
相关产品推荐

