I am using material ui in react. I have a Popover component, which has a Grid component inside it. The size of the Grid component is dynamic, i.e. it's height can increase. The regular behavior of Popover is to make sure that it stays on the screen. But when I use a Grid component inside Popover , and when the height of the Grid increases, the Popover is overflowing and going below the screen.
return (
<Popover
open={Boolean(anchorEl)}
anchorEl={anchorEl}
onClose={handleClose}
anchorOrigin={{
vertical: 'top',
horizontal: 'left',
}}
transformOrigin={{
vertical: "top",
horizontal: "left"
}}
aria-labelledby="draggable-dialog-title"
>
<div>
<DemoGrid />
</div>
</Popover>
);
function DemoGrid(){
const [list,setList] = useState(["hi"]);
return <Grid container spacing={2} >
<button onClick={()=>setList(prev=>[...prev,"hi"])}>add new</button>
{list.map((i,j)=><Grid item xs={8} key={i+j}>
<p>{`${j} ${i}`}</p>
</Grid>)}
</Grid>;
}
So the DemoGrid component, basically is the component which consists of a button, whose on click will add a new Grid item and thereby increase the height of the Grid component, now when the Grid items are too many, the Popover overflows below the screen as shown below.
What can I do so that the Popover stays on the screen. And why isn't the Popover retaining its properties when I use a display:flex (Grid component) inside it?
Related
This is my mui-datatables options:
const options = {
responsive: "standard",
pagination: false,
tableBodyHeight: '80vh',
};
return (
<MUIDataTable
title={"ACME Employee list"}
data={data}
columns={columns}
options={options}
/>
);
What I wanted to achieve was to get the Table's Body to automatically/dynamically expand to fill the remaining height in the parent's div. Note that I have pagination: false, so everything will be shown and scrollable while the header locks in place (sticky header).
See this image: Image Link
I have tried style the Table with flexGrow: 1 but I don't know where to put it. The mui-datatables docs doesn't have a list of children components in <MUIDataTable /> unlike if I were using the original Material-UI Tables.
So now my current janky solution is to set tableBodyHeight: '80vh' which is terrible because at different breakpoints, the parent div height changes, and the table overflows.
Try to add mui-datatables predefined prop called tableBodyMaxHeight and give css property overflow-y: auto to the tablebody
I would like to have a band over a component when the component is locked.
The Review component root is a Material UI Paper element that has a host of other elements inside this Paper. There are a half dozen of these particular elements on the page. When locked===true for each element, I want something to sit, centered (vert and horz), on top of the review element.
I found that a Popover element works fine as it can be moved to center/center. However, being a Modal, it doesn't allow interaction with the rest of the page.
<Popover
id={"id"}
open={Boolean(anchorEl)}
anchorEl={anchorEl}
onClose={handleClose}
anchorOrigin={{
vertical: 'center',
horizontal: 'center',
}}
transformOrigin={{
vertical: 'center',
horizontal: 'center',
}}
>The content of the Popover.</Popover>
I then ensure that anchorEl points to the correct Paper. This works for a 'popover'... The popper element, which is one that isn't in the modal tree (and thus allows multiple and doesn't steal control of the entire app) doesn't have the positioning needed.
<Popper id={'popperID'} open={Boolean(anchorEl)} anchorEl={anchorEl} placement={'top'} transition>
{({ TransitionProps }) => (
<Fade {...TransitionProps}>
<div className={classes.busy}>The content of the Popper.</div>
</Fade>
)}
</Popper>
This puts the element vertically on top (y-axis) my anchorEl... which is not what I want.
I've also tried just putting another Paper in there, but it just ends up vertically 'below' my component.
EDIT: Worth noting I have also tried to position it with CSS. The problem is that absolute positioning (that should position it relative to the parent) seems to position it relative to the entire app instead of the JSX parent/component.
How can I do this?
Use absolute positioning as you said, but you have to give the parent component/element display: relative. Absolute positioning works from the closest ancestor that is not statically positioned. https://www.w3schools.com/cssref/pr_class_position.asp
I'm using react-beautiful-dnd to make some draggable list items using Material UI ListItems.
My ListItems have a ListItemText and a ListItemSecondaryAction which is a target (that wraps an icon) for opening a context menu.
const DraggableListItem = ({ leaf, index, path, handleClick }) => {
return (
<Draggable draggableId={String(leaf.id)} index={index}>
{(provided) => (
<ListItem
{...provided.draggableProps}
{...provided.dragHandleProps}
innerRef={provided.innerRef}
button component={NavLink}
to={path + '/' + leaf.id}
>
<ListItemText primary={leaf.content} />
<ListItemSecondaryAction>
<IconButton edge="end" aria-label="more options" value={JSON.stringify(leaf)} onClick={handleClick}>
<MoreHorizIcon />
</IconButton>
</ListItemSecondaryAction>
</ListItem>
)}
</Draggable>
)
}
The problem I'm facing is that when dragging the Draggable, the context menu icon inside the ListItemSecondaryAction moves up a little bit and then freezes, despite the ListItemText being dragged around as expected.
Below you can see the item is being dragged to the top of the list and the other ListItemTexts are rearranging themselves around the placeholder/where the dragged item will be dropped. The context menu icon of the item being dragged however, is frozen a little above where it used to be, and the context menu icons for the other items haven't moved into new positions with them.
Simply replacing the ListItemSecondaryAction with a div fixes the issue, but I need the target provided by the ListItemSecondaryAction.
The below works as expected in terms of dragging the items: the IconButton is dragged inside the Draggable.
<div>
<IconButton>
<MoreHorizIcon />
</IconButton>
</div>
I have tried only rendering the ListItemSecondaryAction when not dragging (as opposed to a div when dragging) but there is still a delay in which the context menu of the item being dragged shows up stuck in one spot for a brief period of time. I can also just not render the context menu's target + icon at all when dragging but the same unsightly icon-stuck-in-a-weird-place-for-a-second issue happens.
How can I ensure that the IconButton is dragged with the Draggable when it's inside the ListItemSecondaryAction?
I fixed the icon issue using a variant of the solution here, but rather than rendering a separate ListItemIcon and still rendering the ListItemSecondaryAction, which changed the layout of each item, I found it works better to not render the ListItemSecondaryAction at all when dragging and simply render an Icon without any ListItemIcon or IconButton wrapper. The lone Icon is darker when rendered as a child of the ListItem though. After styling the icon on its own to match the color of the icon inside the secondary action, it looks good.
dragInProgress is a piece of state passed to all list items from the parent list so that they render just the icon when dragging. snapshot is from the snapshot passed by the function in the Draggable, as shown in the linked question. snapshot.isDragging is also checked to avoid the momentary jump of the dragged item's icon while the state dragInProgress is updating and causing the items to re-render.
<ListItem
{...provided.draggableProps}
{...provided.dragHandleProps}
ref={provided.innerRef}
>
<ListItemText primary={item.content} />
{dragInProgress || snapshot.isDragging ?
<MoreHorizIcon style={{color:'rgba(0, 0, 0, 0.54)'}} />
:
<ListItemSecondaryAction>
<IconButton>
<MoreHorizIcon />
</IconButton>
</ListItemSecondaryAction>
}
</ListItem>
Note:
Unfortunately the ListItemSecondaryAction rendered when not dragging doesn't play well with touch (tested on android on chrome) and must be dragged twice to start moving the items. I may put this more specific issue in a separate question.
Edit: This is the only page with problems. Other pages of the same website display correctly.
I've made a web page with React and Material-UI. The top components are Grid and Container. It looks good in desktop, but in mobile.. well.. this is the side of the screen:
There's extra space created (light grey) and the Pictures and cards venture outside the screen max width. The header (blue) and the background (light blue) have the correct width (the width of the screen).
i'm using Grid and Container.
This is the root component that contains the cards:
<Grid
container
spacing={0}
direction="row"
justify="space-around"
alignItems="center"
style={{ minHeight: "20vh" }}
> ....
This is another container that scapes the width:
<Container maxWidth="lg" style={{ marginBottom: "5vh" }}>
<Paper style={{ padding: 20 }}>
<Grid
container
spacing={0}
direction="column"
justify="flex-start"
alignItems="center"
> ....
The Header that displays correctly it's just an AppBar.
The image at the top that overflows returns:
<div className={classes.heroContent}>
<Container maxWidth="md" align="center">
<Grid
container
direction="column"
justify="flex-end"
alignItems="center"
> ...
And the classes.heroContent is:
heroContent: {
backgroundImage: `url(${grupo})`,
backgroundSize: "cover",
backgroundRepeat: "no-repeat",
backgroundPosition: "center",
padding: theme.spacing(8, 0, 8),
minHeight: "20vh",
}, ...
What could be the reason of this overflow thing? I've been reading the documentation and I can't find the bug.
I`ve solve it. There where two problems.
Problem 1:
One grid component that was the root component of the cards was designated as container but not as item.
Explanation of problem 1:
As the cards are inside the Grid of the parent component, there are also an item. After I designated all Grid components that had at least one Grid inside as a container, and all the Grid that where inside a Grid container directly or indirectly as a parent component as item it almost worked.
Problem 2:
The combination of media sizes inside the cards and margins of the cards where too big for the screen. The solution is to change the margin and width units.
Explanation problem 2:
the cards have this css now:
cards: {
margin: "5vw",
marginBottom: "0vh",
},
media: {
height: "35vh",
width: "45vw",
},
The problem was the units. I was using margin: '5vh' so the margins where calculated according to the height of the vierport. In viewports with bigger heights than widths (mobile) a fraction of the height was still bigger than the width.
I am attempting to implement a responsive app with antd.
One of the things I have is a Sider menu as my main navigation. One of the things I would like to do is that on small screens this sider be collapsed (as the hamburguer icon preferrably). I have no idea how to even start this. My component with the sidebar looks something like this:
class App extends React.Component {
render() {
return (
<Layout>
<Sider width={200} collapsedWidth={500}>
<Menu
mode="inline"
defaultSelectedKeys={['1']}
defaultOpenKeys={['sub1']}
style={{ height: '100%' }}
>
<Menu.Item key="1">option1</Menu.Item>
<Menu.Item key="2">option2</Menu.Item>
<Menu.Item key="3">option3</Menu.Item>
<Menu.Item key="4">option4</Menu.Item>
</Menu>
</Sider>
</Layout>
);
}
}
I should probably also point out that from the Layout docs, the following is said:
Note: You can get a responsive layout by setting breakpoint, the Sider will collapse to the width of collapsedWidth when window width is below the breakpoint. And a special trigger will appear if the collapsedWidth is set to 0.
However I could not get this to work. Perhaps I misunderstand it.
Unfortunately I am not able to embed my sample app in the editor here, so I here is my working sample app. All I would like to do is collapse my Sider navbar into a hamburguer icon or even an arrow like icon on small screens. Where do I go from here?
You have a collapsible sider official example.
From here you can choose whatever width \ icons you need based on state.
Also, you have a good example of antd components, especially a sidebar with the hamburger icon.