Rotate/Transform Material-UI List - javascript

I'm trying to use React Material-UI and the Drawer API to build a navigation sidebar with the buttons rotated (a stacked list with the buttons turned 90 degrees). I only have a few buttons I'd like to use so I'm trying to do this with the permanent Drawer setup. I was wondering if anyone had any examples or solutions to this. Presently I have this in a CSS file:
.horiz-list {
display: inline-block;
transform: rotate(270deg);
height: 80px;
width: 50px;
}
and this as an example in my sidebar code:
const button = {
text: "Photos",
onClick: () => history.push('/photos')
};
<Drawer
className={classes.drawer}
variant="permanent"
classes={{
paper: classes.drawerPaper,
}}
>
<Toolbar />
<div className={classes.drawerContainer}>
<Divider />
<List>
<ListItem button key={button.text} onClick={button.onClick}>
<ListItemText primary={button.text} className="horiz-list" />
</ListItem>
</List>
<Divider />
</div>
</Drawer>
Right now, some of the labels end up off screen and with the slider at the bottom. Thanks in advance!

Related

Cannot Link to part of page with MUI 5 Drawer

I'm simply trying to link to a specific part of my first page when the user clicks on the Shop button in the navigation Drawer but it doesn't do anything at all:
This is the code for the MUI 5 Drawer component:
<Drawer
anchor="left"
open={open}
onClose={() => setOpen(false)}
PaperProps={{
sx: {
background: "linear-gradient(to top, #9C685B44, #9C685Bff)",
},
}}
>
<IconButton onClick={() => setOpen(false)}>
<ChevronLeftIcon sx={{ color: "white" }} />
</IconButton>
<Divider />
<List>
/////////////////////////////////
<ListItem>
<Button
// Linking to Products Section
href="#products"
startIcon={<PhoneAndroidIcon />}
sx={{
color: "white",
fontFamily: "Montserrat",
}}
>
Shop
</Button>
</ListItem>
//////////////////////////////
<ListItem>
<Badge color="error" badgeContent={badgeNumber}>
<Button
startIcon={<ShoppingCartIcon />}
sx={{
color: "white",
fontFamily: "Montserrat",
}}
>
Cart
</Button>
</Badge>
</ListItem>
</List>
</Drawer>
And in that respective section, I have added an id with the value of products to the container:
<Container maxWidth="xl" id="products">
...
</Container>
Even using the anchor tag results in the same issue.
Is there anyway to fix this?
You can use scrollIntoView and History.pushState() to handle this. Remove the href from your Button component, and instead use its onClick method to call the following:
// id is your section names (e.g. 'products')
// url is optional, and if not specified, is set to the document's current URL
const onNavClick = (event, id, url) =>
{
let element = document.getElementById(id)
event.preventDefault()
element.scrollIntoView()
window.history.pushState(id, id, url)
}
There are various other options you can pass into scrollIntoView, and you can find out more about the available options by following the link above.

MUI Collapse component not allowing encapsulated element flex-grow

So I'm a newbie when it comes to React and thought to get familiar with the concepts utilizing mui. I'm creating a nav bar and one of the features is to have a search bar that is initially collapsed and expand once the search icon is pressed. This will also hide the typography element. My issue seems that no matter if I set flexgrow for both collapse or the text input that's being encapsulated the element doesn't seem to grow despite the extra space. I also observed when I set the width of the element using vw it adjusts but the right icons and search bar begin to overlap after minimizing it to a certain point. I wonder if this is a styling issue or whether if transition is incapable of doing this, if it's a styling issue how do I get the text input to expand the needed space?
Navbar.js
import React, { useState } from "react";
import {
AppBar,
Drawer,
Box,
IconButton,
List,
ListItemButton,
ListItemText,
Toolbar,
TextField,
Typography,
Collapse,
} from "#mui/material";
import MenuIcon from "#mui/icons-material/Menu";
import PersonOutlineOutlinedIcon from "#mui/icons-material/PersonOutlineOutlined";
import SearchOutlinedIcon from "#mui/icons-material/SearchOutlined";
import ShoppingBagOutlinedIcon from "#mui/icons-material/ShoppingBagOutlined";
import { createTheme } from "#mui/material";
const Navbar = () => {
const [drawer, setDrawer] = useState(false);
const [drawer2, setDrawer2] = useState(false);
const [clicked, setClicked] = useState(false);
const theme = createTheme({
typography: {
fontFamily: ["Abril Fatface", "cursive"].join(","),
},
});
return (
<AppBar position="fixed" sx={{ height: 70 }} className="navbar">
<Toolbar>
<IconButton onClick={() => setDrawer(!drawer)} className="id">
<MenuIcon fontSize="large"></MenuIcon>
</IconButton>
<Drawer open={drawer} onClose={() => setDrawer(!drawer)}>
<Box sx={{ width: 400, backgroundColor: "red" }}>
<List>
<ListItemButton>
<ListItemText primary="HI" />
</ListItemButton>
</List>
</Box>
</Drawer>
<Collapse orientation="horizontal" in={clicked} timeout={100} unmountOnExit>
<TextField sx={{ flexGrow: 2 }} />
</Collapse>
<Typography
component="a"
variant="h4"
theme={theme}
className="item"
sx={{
color: "black",
flexGrow: 2,
textAlign: "center",
display: clicked ? "none" : "block",
}}
>
APPSTUFF
</Typography>
<IconButton className="id">
<PersonOutlineOutlinedIcon fontSize="large"></PersonOutlineOutlinedIcon>
</IconButton>
<IconButton className="id" onClick={() => setClicked(!clicked)}>
<SearchOutlinedIcon fontSize="large"></SearchOutlinedIcon>
</IconButton>
<IconButton className="id" onClick={() => setDrawer2(!drawer2)}>
<ShoppingBagOutlinedIcon fontSize="large"></ShoppingBagOutlinedIcon>
</IconButton>
<Drawer
open={drawer2}
onClose={() => setDrawer2(!drawer2)}
anchor="right"
>
<Box sx={{ width: 400, backgroundColor: "red" }}>
<List>
<ListItemButton>
<ListItemText primary="HI" />
</ListItemButton>
</List>
</Box>
</Drawer>
</Toolbar>
</AppBar>
);
};
export default Navbar;
NavbarStyle.css
.id {
color: black;
margin-top: 0.5%;
display: flex;
flex-grow: 0;
}
.navbar {
width: 100vw;
box-shadow: none;
background-color: white;
}

div height doesn't adjust when Accordion is collapsed

I have two charts on top of each other that extend to the bottom of the screen. The first is collapsible via an Accordion.
However, if I do the following two things in sequence:
Make my browser window bigger
Then, collapse the Accordion (i.e., minimize the first graph).
Then there will be unwanted whitespace below the second graph.
<Flex direction="column" height="calc(100vh)" className="flex-wrapper">
<Box fontSize={["sm", "md", "lg", "xl"]}>Font Size</Box>
<Flex className="flex-wrapper0">
<div>123456789010</div>
<Box className="accordion-box-container">
<Accordion className="accordion-wrapper" allowToggle>
<AccordionItem>
<h2 className="accordion-title">
<AccordionButton
className="accordion-button"
borderRadius="md"
borderWidth="0px"
_focus={{ boxShadow: "none" }}
>
<Box
textAlign="left"
h={3}
_focus={{ boxShadow: "none" }}
></Box>
<AccordionIcon />
</AccordionButton>
</h2>
<AccordionPanel p="0">
<Box height="30vh">
<ThreeDataPoint />
</Box>
</AccordionPanel>
</AccordionItem>
</Accordion>
<div className="graph-wrapper">
<ThreeDataPoint />
</div>
</Box>
</Flex>
</Flex>
It seems like some interaction problem between browser resizing and css? I think I need to force a re-rendering of <ThreeDataPoint /> whenever the accordion button is pressed so that it can pick up the new height that it's supposed to be using. I wonder how to force such a re-rendering?
Here's codesandbox:
https://codesandbox.io/s/elegant-fermat-bugv1?file=/src/index.tsx
And the app URL:
https://bugv1.csb.app/
It was because of this !important flag causing troubles in the css file:
.graph-wrapper div {
height: 100% !important;
}
After commenting this out, it worked as expected.

Hover on ListItemSecondaryAction of List component

I'm trying to implement a hover on the Delete button of my list. I want to have it hidden on default, but show it when you hover on a list item. This would be the result:
Before hover:
On hover:
This is my code:
<ListItem className='resourcesInfo-listItem'>
<ListItemAvatar>
<Avatar>
<img alt='borrar recurso' className='resourcesInfo-icon' src={pdf}></img>
</Avatar>
</ListItemAvatar>
<ListItemText
primary="Single-line item"
secondary={secondary ? 'Secondary text' : null}
/>
<ListItemSecondaryAction className='resourcesInfo-deleteButton'>
<IconButton edge="end" aria-label="delete">
<DeleteIcon />
</IconButton>
</ListItemSecondaryAction>
</ListItem>
I have tried both searching for the default classes on the Chrome inspector and creating my own classes ('resourcesInfo-listItem' and 'resourcesInfo-deleteButton'), but it doesn't work.
My CSS attempts:
With my own classes:
.resourcesInfo-deleteButton {
display: none;
}
.resourcesInfo-listItem:hover> .resourcesInfo-deleteButton {
display: block!important;
background-color: red!important;
}
With the default classes:
.MuiIconButton-edgeEnd {
display: none;
}
.MuiListItem-root:hover > .MuiIconButton-edgeEnd {
display: block;
}

Using Dividers inside Material-UI Tabs

If I want to use a Divider or something else that isn't a Tab inside Material-UI Tabs, I get DOM warnings in the console.
<Tabs ...>
//...
<Divider />
//...
</Tabs>
A workaround for this is to create a middleman-kind class like this:
<Tabs ...>
//...
<MDivider />
//...
</Tabs>
function MDivider(props) {
return <Divider />;
}
But I was thinking if this is the best solution to solve the issue or if there are other, better ways to stop getting the warning.
codesandbox with error here
codesandbox with fix here
Ok, so I think I found the best fix based on how the MUI Tabs are meant to be used. If Tabs are only meant to have MUI Tab children inside, then the MUI-intended way to do this would be to add the Divider like this:
<Tab label="" icon={<Divider />} disabled />
, give it a className and style it accordingly. The Tab component is a button with stuff inside, so you would need to override some paddings and min-heights in css.
you can use the Dividers in between each Tab as follows:
<Box
style={{
display: "flex",
justifyContent: "flex-end",
marginRight: 20,
}}
>
<Tabs
sx={{ backgroundColor: "#EAEBEF", borderRadius: 4 }}
value={tab}
onChange={(e, v) => setTab(v)}
>
<Tab label="Item One" />
<Divider
orientation="vertical"
style={{ height: 30, alignSelf: "center" }}
/>
<Tab label="Item Two" />
<Divider
orientation="vertical"
style={{ height: 30, alignSelf: "center" }}
/>
<Tab label="Item Three" />
</Tabs>
</Box>
Using CSS to add a border to the top of the tab seems to work well for me.
const useStyles = (theme) => ({
withDivider: {
borderTop: `1px solid ${theme.palette.divider}`,
},
});
<Tabs>
<Tab>...<Tab/>
<Tab>...<Tab/>
<Tab className={classes.withDivider}>...<Tab/>
<Tab>...<Tab/>
</Tabs>
Just for anyone wondering why the divider doesn´t show up, add the orientation property and set it to "vertical" so the divider can be visible in horizontal Tabs.
<Tab label="" icon={<Divider orientation="vertical" />} disabled />

Categories