【问题标题】:How to contain the width of the main component in Material UI Drawer component?Material UI Drawer 组件中如何包含主组件的宽度?
【发布时间】:2020-11-02 06:38:07
【问题描述】:

我正在尝试在 Material UI 中使用抽屉。

我希望主 div 的宽度在菜单抽屉用完其空间后占用视口中剩余的任何可用空间。

这是我的组件。我已经尝试将宽度设置为自动并在内容类上继承,但它没有改变任何东西。

我希望渲染主 div(抽屉中列表项的内容),以便在不水平滚动的情况下只占用尽可能多的可用空间。

此代码沙箱显示问题:https://codesandbox.io/s/material-tab-scrolling-h13pi?file=/test.jsx

import React, {  useState, useEffect } from 'react';
import { Switch, Route, Link, BrowserRouter } from "react-router-dom";
import clsx from 'clsx';
import { makeStyles, useTheme } from '@material-ui/core/styles';
import Drawer from '@material-ui/core/Drawer';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import List from '@material-ui/core/List';
import CssBaseline from '@material-ui/core/CssBaseline';
import Typography from '@material-ui/core/Typography';
import Divider from '@material-ui/core/Divider';
import IconButton from '@material-ui/core/IconButton';
import Menu from '@material-ui/core/Menu';
import MenuItem from '@material-ui/core/MenuItem';
import Container from '@material-ui/core/Container'

import MenuIcon from '@material-ui/icons/Menu';
import ChevronLeftIcon from '@material-ui/icons/ChevronLeft';
import ChevronRightIcon from '@material-ui/icons/ChevronRight';
import ListItem from '@material-ui/core/ListItem';
import ListItemIcon from '@material-ui/core/ListItemIcon';
import ListItemText from '@material-ui/core/ListItemText';
import InboxIcon from '@material-ui/icons/MoveToInbox';
import MailIcon from '@material-ui/icons/Mail';
import AccountCircle from '@material-ui/icons/AccountCircle';
import PaletteIcon from '@material-ui/icons/Palette';
import CenterFocusWeakIcon from '@material-ui/icons/CenterFocusWeak';
import RoomServiceIcon from '@material-ui/icons/RoomService';
import StorefrontIcon from '@material-ui/icons/Storefront';
import AssignmentIcon from '@material-ui/icons/Assignment';
import NotificationsIcon from '@material-ui/icons/Notifications';
import AccountBoxIcon from '@material-ui/icons/AccountBox';
import ContactSupportIcon from '@material-ui/icons/ContactSupport';
import BookIcon from '@material-ui/icons/Book';
import TuneIcon from '@material-ui/icons/Tune';
import SettingsIcon from '@material-ui/icons/Settings';
import CloseIcon from '@material-ui/icons/Close';
import DashboardFooter from "./DashboardFooter";

const drawerWidth = 240;

const useStyles = makeStyles((theme) => ({
  root: {
    display: 'flex',
  },
  appBar: {
    zIndex: theme.zIndex.drawer + 1,
    transition: theme.transitions.create(['width', 'margin'], {
      easing: theme.transitions.easing.sharp,
      duration: theme.transitions.duration.leavingScreen,
    }),
  },
  appBarShift: {
    marginLeft: drawerWidth,
    width: `calc(100% - ${drawerWidth}px)`,
    transition: theme.transitions.create(['width', 'margin'], {
      easing: theme.transitions.easing.sharp,
      duration: theme.transitions.duration.enteringScreen,
    }),
  },
  menuButton: {
    marginRight: 36,
  },
  hide: {
    display: 'none',
  },
  drawer: {
    width: drawerWidth,
    flexShrink: 0,
    whiteSpace: 'nowrap',
  },
  drawerOpen: {
    width: drawerWidth,
    transition: theme.transitions.create('width', {
      easing: theme.transitions.easing.sharp,
      duration: theme.transitions.duration.enteringScreen,
    }),
  },
  drawerClose: {
    transition: theme.transitions.create('width', {
      easing: theme.transitions.easing.sharp,
      duration: theme.transitions.duration.leavingScreen,
    }),
    overflowX: 'hidden',
    width: theme.spacing(7) + 1,
    [theme.breakpoints.up('sm')]: {
      width: theme.spacing(9) + 1,
    },
  },
  toolbar: {
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'flex-end',
    padding: theme.spacing(0, 1),
    // necessary for content to be below app bar
    ...theme.mixins.toolbar,
  },
  content: {
    flexGrow: 1,
    padding: theme.spacing(3),
    // autoWidth: false
    
  },
  container: {
    paddingTop: theme.spacing(4),
    paddingBottom: theme.spacing(4),
  },
}));

export default function MiniDrawer() {
  const classes = useStyles();
  const theme = useTheme();
  const [open, setOpen] = React.useState(false);
 //   const { performingAction, user, userData, roles } = this.props;

  
  const handleDrawerOpen = () => {
    setOpen(true);
  };

  const handleDrawerClose = () => {
    setOpen(false);
  };
 
  return (
    <div className={classes.root}>
      <CssBaseline />
      <AppBar
        position="fixed"
        className={clsx(classes.appBar, {
          [classes.appBarShift]: open,
        })}
      >
        <Toolbar>
          <IconButton
            color="inherit"
            aria-label="open drawer"
            onClick={handleDrawerOpen}
            edge="start"
            className={clsx(classes.menuButton, {
              [classes.hide]: open,
            })}
          >
            <MenuIcon />
          </IconButton>
          <Typography variant="h6" noWrap>
            {process.env.REACT_APP_TITLE}
            
          </Typography>
            
          <IconButton color="inherit"><CloseIcon /></IconButton>    
        </Toolbar>
      </AppBar>
      <BrowserRouter>
        <Drawer
            variant="permanent"
            className={clsx(classes.drawer, {
            [classes.drawerOpen]: open,
            [classes.drawerClose]: !open,
            })}
            classes={{
            paper: clsx({
                [classes.drawerOpen]: open,
                [classes.drawerClose]: !open,
            }),
            }}
        >
            <div className={classes.toolbar}>
            <IconButton onClick={handleDrawerClose}>
                {theme.direction === 'rtl' ? <ChevronRightIcon /> : <ChevronLeftIcon />}
            </IconButton>
            </div>
            
            <List>
            
                <ListItem button key="1" component={Link} to={"/DSM" }>
                    <ListItemIcon><PaletteIcon /></ListItemIcon>
                    <ListItemText primary="DS"></ListItemText> 
                </ListItem>
                <ListItem button key="2" component={Link} to={"/MMM" }>
                    <ListItemIcon><CenterFocusWeakIcon /></ListItemIcon>
                    <ListItemText>MM</ListItemText> 
                </ListItem>
                <ListItem button key="3" component={Link} to={"/RCM" }>
                    <ListItemIcon><StorefrontIcon /></ListItemIcon>
                    <ListItemText>Centre</ListItemText> 
                </ListItem>
                <ListItem button key="4" component={Link} to={"/TT" }>
                    <ListItemIcon><AssignmentIcon /></ListItemIcon>
                    <ListItemText>TT</ListItemText> 
                </ListItem>
                
            </List>
            <Divider />
            <List>
                <ListItem button key="5"  component={Link} to={"/Profile" }>
                <ListItemIcon> <AccountBoxIcon /></ListItemIcon>
                <ListItemText>Profile</ListItemText> 
                </ListItem>
                <ListItem button key="6"  component={Link} to={"/Account" }>
                <ListItemIcon> <SettingsIcon /></ListItemIcon>
                <ListItemText>Account</ListItemText> 
                </ListItem>
                <ListItem button key="7"  component={Link} to={"/Mail" }>
                <ListItemIcon> <MailIcon /></ListItemIcon>
                <ListItemText>Mail</ListItemText> 
                </ListItem>
                <ListItem button key="8"  component={Link} to={"/Notifications" }>
                <ListItemIcon> <NotificationsIcon /></ListItemIcon>
                <ListItemText>Notifications</ListItemText>
                </ListItem>
            
            </List>
            <Divider />
            <List>
                
                <ListItem button key="9"  component={Link} to={"/CM" }>
                    <ListItemIcon> <BookIcon /></ListItemIcon>
                    <ListItemText>Centre</ListItemText> 
                </ListItem>
                <ListItem button key="10"  component={Link} to={"/DCM" }>
                    <ListItemIcon><RoomServiceIcon /></ListItemIcon>
                    <ListItemText>Desk</ListItemText> 
                </ListItem>
                <ListItem button key="11"  component={Link} to={"/Support" }>
                <ListItemIcon> <ContactSupportIcon /></ListItemIcon>
                <ListItemText>Help and Support</ListItemText>
                </ListItem>
            
            
            </List>
        </Drawer>
        <main className={classes.content}>
          <div className={classes.toolbar} />

            <Switch>
                <Route path="/DCM" component={""} />
                <Route path="/MMM" render={() => <div>Page mm</div>} />
            </Switch>
            <DashboardFooter />
        </main>
     </BrowserRouter>   
     
    </div>
      
      
  );
}

【问题讨论】:

  • 我将您的代码放入代码沙箱(DashboardFooter 除外),但没有发现任何问题...即没有水平滚动或任何东西......你可以分享一些截图......如果适用的话还有DashboardFooter代码......如果你可以将你的代码放入codesandbox并分享链接 - 更好
  • 此代码沙箱显示滚动。我找不到扩展主容器宽度以超出视口宽度的属性:codesandbox.io/s/material-tab-scrolling-h13pi?file=/test.jsx

标签: reactjs material-ui


【解决方案1】:

主要问题是 dash.jsx 中的以下内容:

  root: {
    display: 'flex',
  },

这在某种程度上破坏了Tabs 中的机制,因为它的“可滚动标签”功能并导致Tabs 占用了显示其所有标签按钮而不是显示滚动按钮所需的宽度。 display: 'flex' 使管理内容宽度变得更容易(这样它会根据抽屉宽度自动调整),但以其他方式管理这一点并不难。

备选方案 1

在我修改过的沙箱版本中,为了弥补从根目录中删除 display: 'flex' 的效果,我将 padding-left 添加到与抽屉宽度相同的内容中:

  content: {
    padding: theme.spacing(3),
    paddingLeft: theme.spacing(7) + 1,
    [theme.breakpoints.up("sm")]: {
      paddingLeft: theme.spacing(9) + 1
    }
  },
  contentDrawerOpen: {
    paddingLeft: drawerWidth
  },
...
<main className={clsx(classes.content, {[classes.contentDrawerOpen]: open})}>


备选方案 2

另一种选择是保留display: 'flex',但在内容上适当地指定max-width

  content: {
    padding: theme.spacing(3),
    maxWidth: `calc(100vw - ${theme.spacing(7) + 1}px)`,
    [theme.breakpoints.up("sm")]: {
      maxWidth: `calc(100vw - ${theme.spacing(9) + 1}px)`
    }
  },
  contentDrawerOpen: {
    maxWidth: `calc(100vw - ${drawerWidth}px)`
  },


备选方案 3(灵感来自 Ahmed Mokhtar 的回答)

overflow: "auto" 添加到content 类的&lt;main&gt; 元素似乎也足够了:

  content: {
    padding: theme.spacing(3),
    overflow: "auto"
  },

最后一个选择绝对是最简单的。

【讨论】:

  • 谢谢。我需要再等 12 个小时才能将积分发送给您。
  • 我也使用第二种方法修复了它,但后来我发现只将overflow: auto 添加到容器中就像一个魅力。
  • 感谢大家,我也遇到了这个问题,我在容器中添加了溢出:自动,这就解决了。
【解决方案2】:

我通过将overflow: auto 添加到main 来解决此问题,我将其更改为使用Container 组件:

container: {
  overflow: "auto"
}

{/* I added overflow: auto to this container*/}
<Container
  component="main"
  maxWidth={false}
  className={classes.container}
>
  <div className={classes.toolbar} />

  <Switch>
    <Route path="/dash" component={Dash} />
    <Route path="/MatchmakerMenu" component={Dash} />
  </Switch>
</Container>

CodeSandbox

【讨论】:

  • 只需将overflow: "auto" 添加到&lt;main&gt; 元素上已经存在的类中似乎就足够了(不需要Container 组件)。
  • 我知道我只是想表明一个流体Container 组件已经存在,能够将maxWidth 属性定义为smmdlgxlfalse.
  • 太棒了!我无法让 Plotly 调整大小以触发,因为父 div 没有缩小而是溢出:内容类上的“auto”解决了它。
猜你喜欢
  • 1970-01-01
  • 2019-05-24
  • 2021-06-28
  • 1970-01-01
  • 2018-09-14
  • 1970-01-01
  • 2021-11-25
  • 2018-09-14
  • 1970-01-01
相关资源
最近更新 更多