Is there a way to position a ListItem (using React) in the lower left corner in this specific case?

import * as React from 'react';
import { styled, useTheme } from '@mui/material/styles';
import Box from '@mui/material/Box';
import MuiDrawer from '@mui/material/Drawer';
import MuiAppBar from '@mui/material/AppBar';
import Toolbar from '@mui/material/Toolbar';
import List from '@mui/material/List';
import CssBaseline from '@mui/material/CssBaseline';
import Typography from '@mui/material/Typography';
import Divider from '@mui/material/Divider';
import IconButton from '@mui/material/IconButton';
import MenuIcon from '@mui/icons-material/Menu';
import ChevronLeftIcon from '@mui/icons-material/ChevronLeft';
import ChevronRightIcon from '@mui/icons-material/ChevronRight';
import ListItem from '@mui/material/ListItem';
import ListItemButton from '@mui/material/ListItemButton';
import ListItemIcon from '@mui/material/ListItemIcon';
import ListItemText from '@mui/material/ListItemText';
import HomeIcon from '@mui/icons-material/Home';
import SchoolIcon from '@mui/icons-material/School';
import ClassIcon from '@mui/icons-material/Class';

const drawerWidth = 240;
const icons = [<HomeIcon/>, <ClassIcon/>,<SchoolIcon/>]

const openedMixin = (theme) => ({
  width: drawerWidth,
  transition: theme.transitions.create('width', {
    easing: theme.transitions.easing.sharp,
    duration: theme.transitions.duration.enteringScreen,
  }),
  overflowX: 'hidden',
});

const closedMixin = (theme) => ({
  transition: theme.transitions.create('width', {
    easing: theme.transitions.easing.sharp,
    duration: theme.transitions.duration.leavingScreen,
  }),
  overflowX: 'hidden',
  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 AppBar = styled(MuiAppBar, {
  shouldForwardProp: (prop) => prop !== 'open',
})(({ theme, open }) => ({
  zIndex: theme.zIndex.drawer + 1,
  transition: theme.transitions.create(['width', 'margin'], {
    easing: theme.transitions.easing.sharp,
    duration: theme.transitions.duration.leavingScreen,
  }),
  ...(open && {
    marginLeft: drawerWidth,
    width: `calc(100% - ${drawerWidth}px)`,
    transition: theme.transitions.create(['width', 'margin'], {
      easing: theme.transitions.easing.sharp,
      duration: theme.transitions.duration.enteringScreen,
    }),
  }),
}));

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

export default function MiniDrawer({children}) {
  const theme = useTheme();
  const [open, setOpen] = React.useState(false);
  
  const handleDrawerOpen = () => {
    setOpen(true);
  };

  const handleDrawerClose = () => {
    setOpen(false);
  };
  
  return (
    <Box sx={{ display: 'flex' }}>
      <CssBaseline />
      <AppBar position="fixed" open={open}>
        <Toolbar>
          <IconButton
            color="inherit"
            aria-label="open drawer"
            onClick={handleDrawerOpen}
            edge="start"
            sx={{
              marginRight: 5,
              ...(open && { display: 'none' }),
            }}
          >
            <MenuIcon />
          </IconButton>
          <Typography variant="h6" noWrap component="div">
            NOPF
          </Typography>
        </Toolbar>
      </AppBar>
      <Drawer variant="permanent" open={open}>
        <DrawerHeader>
          <IconButton onClick={handleDrawerClose}>
            {theme.direction === 'rtl' ? <ChevronRightIcon /> : <ChevronLeftIcon />}
          </IconButton>
        </DrawerHeader>
        <Divider />
        <List>
          {['Home', 'Klasse', 'Schule'].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',
                  }}
                >
                  {icons[index]}
                </ListItemIcon>
                <ListItemText primary={text} sx={{ opacity: open ? 1 : 0 }} />
              </ListItemButton>
            </ListItem>
          ))}

          <ListItem disablePadding sx={{ display: 'block', position: 'absolute', bottom: 0, left: 0 }}>
            <ListItemButton
              sx={{
                minHeight: 48,
                justifyContent: open ? 'initial' : 'center',
                px: 2.5,
              }}
            >
              <ListItemIcon
                  sx={{
                    minWidth: 0,
                    mr: open ? 3 : 'auto',
                    justifyContent: 'center',
                  }}
              >
                <HomeIcon/>
              </ListItemIcon>
              <ListItemText primary={'Profil'} sx={{ opacity: open ? 1 : 0 }} />
            </ListItemButton>
          </ListItem>

        </List>
      </Drawer>
      <Box component="main" sx={{ flexGrow: 1, p: 3 }}>
        <DrawerHeader />
        {children}
      </Box>
    </Box>
  );
}

This is a modified version of the original code snippet provided by the MaterialUI website, in which I added a ListItem at the bottom left corner of the Drawer. The positioning of this new ListItem has been adjusted using "position: absolute" to make it stick to the bottom of the Drawer and prevent unintended clicking when hovering over its area. This solution ensures consistent behavior regardless of device width.

Answer №1

If you want to properly position the items in a drawer, I recommend utilizing the flex CSS. By using the flex CSS property, you can ensure that the list occupies all the vertical space within the drawer. Additionally, employing the margin-top attribute with the value of auto will help push the last item to the bottom corner of the drawer. For a practical application, I made adjustments to the basic drawer example provided in MUI documentation.

const DrawerList = (
  <Box sx={{ display: 'flex', flexDirection: 'column', flex: 1, width: 250 }} role="presentation" onClick={toggleDrawer(false)}>
    <List sx={{ display: 'flex', flexDirection: 'column', flex: 1 }}>
      {['All mail', 'Trash', 'Spam'].map((text, index) => (
        <ListItem key={text} disablePadding>
          <ListItemButton>
            <ListItemIcon>
              {index % 2 === 0 ? <InboxIcon /> : <MailIcon />}
            </ListItemIcon>
            <ListItemText primary={text} />
          </ListItemButton>
        </ListItem>
      ))}
      <ListItem disablePadding sx={{ marginTop: 'auto' }}>
        <ListItemButton>
          <ListItemIcon>
            <AccountCircleIcon />
          </ListItemIcon>
          <ListItemText primary="Last item" />
        </ListItemButton>
      </ListItem>
    </List>
  </Box>
);

To see this implementation in action, feel free to view the complete example on StackBlitz.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

When we typically scroll down the page, the next section should automatically bring us back to the top of the page

When we scroll down the page, the next section should automatically bring us back to the top of the page without having to use the mouse wheel. .bg1 { background-color: #C5876F; height: 1000px; } .bg2 { background-color: #7882BB; height: 1000px; } .bg3 ...

Adjusting the size of Bootstrap alerts while ensuring the close icon remains correctly positioned

Below is the HTML code snippet I am working with: <div class="row mt-2"> <div class="col-lg-5"> <div id="alertmessages"></div> </div> <div class="col-lg-7"> <div class="btn-group-sm"> ...

The Bootstrap navbar collapse fails to expand in the appropriate location

Whenever I try to expand the navigation on mobile mode by clicking the button, it doesn't push the content downwards. Instead, it just opens a small menu next to the button. Did I make a mistake in my code? <div class = "container"> ...

Is there a way to right-align the labels and input fields simultaneously?

Is there a way to line up the labels and inputs on the right side so they all appear in the same row? .radioContainer{ width: fit-content; margin: 5px; margin-top: 20px; background-color: aqua; padding-bottom: 25px; } <div class=" ...

What's the best way to continuously increase my counter using the data received from my AJAX calls?

On the final step of my first ajax project, I have implemented a thumbs-up icon that increments a column in the database when clicked. The following code achieves this: Viewable Page HTML and jQuery: <div id="comment_id">+1</div> <div id=" ...

The styling for buttons links is malfunctioning

I am currently developing my own version of Bootstrap and focusing on buttons and links. I have anchor tags within the button element, but the link styling is not displaying correctly. HTML <button class="btn-danger"><a href="#">Danger</a& ...

Retrieving and displaying data either one by one or in groups, without knowing the exact number of records

Currently, I am developing a Ruby on Rails + React application where I fetch and display records using axios and useEffect. Everything works perfectly as expected, with all the data being displayed after fetching. However, I have a new requirement to fetc ...

The beginning of an HTML document and the viewport (screen view) location

Absolute positioning is relative to a containing block that provides a positioning context, which defaults to the document. a) If absolute positioning is relative to the document, can we visualize the starting point of a document as a two-dimensional coor ...

It appears that IE 10 is having trouble displaying modals, possibly due to a compatibility issue with jQuery 1.7.1's animate function

By visiting www.carsense.com and clicking on the login link in the top-right corner, you may notice that the curtain appears but the modal itself does not display, even though it exists: If you locate id="content1" and modify the inline opacity to 1, the ...

Is there a similar command to "mvn package" when using npm?

Looking to establish a continuous integration and continuous deployment pipeline for a React application. The pipeline should include stages like build, test, package.. For Maven projects, common commands used are mvn compile, mvn test, and mvn package ...

Does the Pure Component behave similarly to a regular component when passing an object as a prop?

Is this a correct implementation of a pure Component? interface CheckBoxOptions { multiSelected?: boolean showOuterCheckBoxOnSelected?: boolean } interface Props { checkBoxKey?: any itemTitle?: string isCheckBoxSelected?: boolean checkBoxStyl ...

Issue arises where multiple asynchronous functions cause infinite re-rendering due to the shared loading state

Currently, I am integrating zustand 4.1.5 into my React application. Upon clicking the LogDetails tab, two asynchronous functions with identical loading state settings are triggered simultaneously, leading to an endless rerendering cycle and causing the & ...

What is the method to show a tag while dragging content in html5?

How can I make a div element track the mouse movement while dragging an item on my website? I need the div to only appear when the user drags content that has been enabled for dragging. I'm looking for a straightforward method to customize the appea ...

The combination of UseState and useContext in React Typescript may lead to compatibility issues

I attempted to integrate the context API with the useState hook but encountered difficulties when using TypeScript. First, let's create App.tsx: const App = () => { const [exampleId, updateExampleId] = useState(0); return ( <div> ...

Having trouble eliminating the underline on Vue router-link?

I've experimented with various approaches in an attempt to remove the underline from router-link. This is the code I have: <router-link :to="{name: 'Plan'}"> <div>Plan Your Trip</div> <div class=&apos ...

React component fails to update upon state change via Redux

I've noticed that my state is changing in the console, but my Book component isn't being refreshed when the state changes. In my app, I have two containers/components: BookList, which renders a list of all available books, and the Book component, ...

What is the reasoning behind the repetitive use of @media (max-width: 767px) in the Twitter Bootstrap

Why is the media query @media (max-width: 767px) repeated in the bootstrap-responsive.css file? To find out, you can view the file by visiting ...

Tips for preventing the overwriting of a JSON object in a React application

I'm trying to compare two JSON objects and identify the differing values in the second JSON object based on a specific key. My goal is to store these mismatched values in a new JSON object. The current issue I'm facing is that when there are mult ...

Troubleshooting Problem with Accordion Size in CSS

I am facing an issue with a dropdown menu that I have created. The dropdown has parent and child rows to display controls, but the width of the Accordion is not stretching as expected despite being set to 100%. Using Chrome and Edge developer tools, I insp ...

Erase data from MySQL database by leveraging React.js and Express

I'm currently facing an issue when trying to delete a post using React and MySQL. Despite not encountering any errors or warnings, the posts do not get deleted. When I check the affected rows using console.log, it returns 0. deleteNote = id => { ...