English 中文(简体)
Grid 装在反应灵敏的集装箱内
原标题:Grid inside responsive Container MUI

我试图取得与你在网站上所做的类似内容,即:

enter image description here enter image description here

基本上,YT公司(种子)的所作所为是,根据集装箱大小来增加/减少电网,因为提炼者是开放的。

Bottom line, my code does not reflect layout change (I suspect MUI listens to the window size instead of the parent size). Is it possible to make it work?

版本:

"@mui/material": "^5.15.0", "next": "^14.0.4", "react": "18.2.0",

增 编

我尝试使用MUI + NextJS做类似的事情,但并不奏效。

相关的信标:

import { Box, Container } from  @mui/material 
import Header from  ../components/Layout/Header 
import { ServerAuthProvider } from  ../../auth/server-auth-provider 

export default function Layout(props: {
    children: React.ReactNode,
    body: React.ReactNode,
    filters: React.ReactNode,
}) {
    return (
        <ServerAuthProvider>
            <Header maxWidth={false}>
                <Container maxWidth={false}>
                    <Box ml={2} mt={10}>
                        {props.filters}
                        {props.body}
                        {props.children}
                    </Box>
                </Container>
            </Header>
        </ServerAuthProvider>
    )
}

(相关部分)

<Box sx={{ mt: 2, mb: 2, ml: -1, mr: -1 }}>
            <Unstable_Grid2 container spacing={2}>
                {events?.map((event: EventSummary) => (
                    <Unstable_Grid2 xs={12} sm={6} md={6} lg={4} xl={3} xxl={12 / 5} key={event.id + event.starts_at}>
                        <EventCard event={event} />
                    </Unstable_Grid2>
                ))}
            </Unstable_Grid2 >
        </Box >
const drawerWidth = 240;

const openedMixin = (theme: Theme): CSSObject => ({
    width: drawerWidth,
    transition: theme.transitions.create( width , {
        easing: theme.transitions.easing.sharp,
        duration: theme.transitions.duration.enteringScreen,
    }),
    overflowX:  hidden ,
    border:  none ,
    borderWidth: 0,
});

const closedMixin = (theme: Theme): CSSObject => ({
    transition: theme.transitions.create( width , {
        easing: theme.transitions.easing.sharp,
        duration: theme.transitions.duration.leavingScreen,
    }),
    overflowX:  hidden ,
    border:  none ,
    borderWidth: 0,
    width: `calc(${theme.spacing(7)} + 1px)`,
    [theme.breakpoints.up( sm )]: {
        width: `calc(${theme.spacing(8)} + 1px)`,
    },
});

const DrawerHeader = styled( div )(({ theme }) => ({
    display:  flex ,
    alignItems:  center ,
    justifyContent:  flex-end ,
    padding: theme.spacing(0, 1),
    // necessary for content to be below app bar
    ...theme.mixins.toolbar,
}));

const Drawer = styled(MuiDrawer, { shouldForwardProp: (prop) => prop !==  open  })(
    ({ theme, open }) => ({
        width: drawerWidth,
        flexShrink: 0,
        whiteSpace:  nowrap ,
        boxSizing:  unset ,
        ...(open && {
            ...openedMixin(theme),
             & .MuiDrawer-paper : openedMixin(theme),
        }),
        ...(!open && {
            ...closedMixin(theme),
             & .MuiDrawer-paper : closedMixin(theme),
        }),
    }),
);

const Main = styled( main , { shouldForwardProp: (prop) => prop !==  open  })<{
    open?: boolean;
}>(({ theme, open }) => ({
    flexGrow: 1,
    // padding: theme.spacing(3),
    // transition: theme.transitions.create( margin , {
    //     easing: theme.transitions.easing.sharp,
    //     duration: theme.transitions.duration.leavingScreen,
    // }),
    // width: `calc(100% - ${drawerWidth}px)`,
    ...(open && {
        transition: theme.transitions.create( margin , {
            easing: theme.transitions.easing.easeOut,
            duration: theme.transitions.duration.enteringScreen,
        }),
        marginLeft: 0,
        overflow:  auto 
    }),
}));

export default function PrimaryHeader({ maxWidth, children }: { maxWidth?: false | undefined, children?: ReactNode }) {
    const [anchorElNav, setAnchorElNav] = React.useState<null | HTMLElement>(null);
    const [open, setOpen] = useState(false)

    const { user } = useAuth();
    const { getFirebaseAuth } = useFirebaseAuth()
    const router = useRouter()

    const theme = useTheme()
    const isXl = useMediaQuery(theme.breakpoints.only( xl ))
    const isMd = useMediaQuery(theme.breakpoints.up( md ))

    const logout = async () => {
        const auth = getFirebaseAuth()
        await signOut(auth)
        await fetch( /api/logout )
        window.location.reload()
    }

    const loggedOptions = [{ title:  Logout , callback: logout }]
    const notLoggedOptions = [{ title:  Entrar , callback: () => router.push( /login ) }]
    return (
        <Box sx={{ display:  flex  }}>
            <CssBaseline />
            <AppBar position="fixed" sx={{ bgcolor:  white , zIndex: theme.zIndex.drawer + 1, }} elevation={0}>
                <Container disableGutters maxWidth={maxWidth}>
                    <Toolbar>
                        {!!children && <IconButton
                            color="inherit"
                            aria-label="open drawer"
                            onClick={() => { setOpen((prev) => !prev) }}
                            edge="start"
                            sx={{ mr: 2 }}
                        >
                            <MenuIcon sx={{ color:  black  }} />
                        </IconButton>}
                    </Toolbar>
                </Container>
            </AppBar>
            {!!children && <>
                <Drawer
                    variant="permanent"
                    open={open}
                >
                    <DrawerHeader />
                    <List>
                        {[ Inbox ,  Starred ,  Send email ,  Drafts ].map((text, index) => (
                            <ListItem key={text} disablePadding sx={{ display:  block  }}>
                                <ListItemButton
                                    sx={{
                                        minHeight: 48,
                                        justifyContent: open ?  initial  :  center ,
                                        px: 2.5,
                                    }}
                                >
                                    <ListItemIcon
                                        sx={{
                                            minWidth: 0,
                                            mr: open ? 3 :  auto ,
                                            justifyContent:  center ,
                                        }}
                                    >
                                        {index % 2 === 0 ? <InboxIcon /> : <MailIcon />}
                                    </ListItemIcon>
                                    <ListItemText primary={text} sx={{ opacity: open ? 1 : 0 }} />
                                </ListItemButton>
                            </ListItem>
                        ))}
                    </List>
                </Drawer>
                <Main open={open}><Container maxWidth={maxWidth}>{children}</Container></Main>
            </>}
        </Box>
    )
}
问题回答

更正确的是,断点是以眼光、而不是目前的集装箱宽度为基础的。

但是,你所期望的用基本的CSS网可以实现:

const { useState } = React
const App = () => {
  const [isSidebarOpen, setIsSidebarOpen] = useState(false)
  return (
    <div className={ App  + (isSidebarOpen ?   sidebar-open  :   )}>
      <header className="header">Header</header>
      <div className="sidebar" onClick={() => setIsSidebarOpen(!isSidebarOpen)}>
        {isSidebarOpen ?  <  :  > }
      </div>
      <main>
        {Array.from({ length: 29 }).map((_, key) => (
          <div className="box" key={key}>{key + 1}</div>
        ))}
      </main>
    </div>
  )
}

ReactDOM.createRoot(root).render(<App />)
body { 
  margin: 0;
}
.App {
  min-height: 100vh;
  display: grid;
  grid-template:  header header  auto  sidebar main  1fr / 3rem 1fr;
}
.App.sidebar-open {
  grid-template-columns: 16rem 1fr;
}
.App > * {
  padding: 1rem;
}
header {
  background-color: lightcoral;
  grid-area: header;
  text-align: center;
}

.sidebar {
  grid-area: sidebar;
  background-color: lightblue;
}

main {
  grid-area: main;
  align-self: stretch;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  grid-gap: 1rem;
  background-color: #f5f5f5;
}
.box {
  aspect-ratio: 1/0.7;
  border: 1px solid #eee;
  font-size: 3rem;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #fff;
  box-shadow: 0 2px 4px -1px rgba(0,0,0,.1), 0 4px 5px 0 rgba(0,0,0,.07), 0 1px 10px 0 rgba(0,0,0,.06)
}
<script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
<div id="root"></div>

Click on thesidebar toggle it.

关键在于:

main {
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr))
}

......尽量将<条码>150px的栏目列入现有的宽度。 任何额外宽度均在各栏之间平分。

Change 150px to whatever makes sense for your case.
Everything else is not particularly relevant; I added it in to make the example look more like a "layout".





相关问题
How to use one react app into another react app?

I have two react apps, parent app and child app. and child app have an hash router. I have build the child app using npm run build, It creates build folder. That build folder moved into inside the ...

how to get selected value in Ant Design

I want to print the selected value, and below is my option list: const vesselName = [ { value: 0 , label: ALBIDDA , }, { value: 1 , label: ALRUMEILA , }, { value: 2 ,...

How to add a <br> tag in reactjs between two strings?

I am using react. I want to add a line break <br> between strings No results and Please try another search term. . I have tried No results.<br>Please try another search term. but ...

热门标签