Unable to fix popper placement in autocomplete - reactjs

I am using the <Autocomplete /> component of Material-UI and I have a situation where I want my drop-down to always appear at the bottom. Therefore I did this:
PopperComponent={(props) => <Popper {...props} placement='bottom-start' />}
My drop-down still appear at the top sometimes.
Moreover, when i did the above, the width of my popper is no longer the width of my autocomplete.
I decided then that i want to change the zIndex of the popper so that the app bar won't cover it if the position of the popper switches to the top.
How can i fix it?

Yes, placement appears to be broken when used in Autocomplete's Popper (material-ui v. 4.11.4).
A hack that worked for me is as follows:
<Autocomplete
// Force menu to open below, with the correct width
PopperComponent={({ style, ...props }) => (
<Popper
{...props}
style={{ ...style, height: 0 }} // width is passed in 'style' prop
/>
)}
// Set menu max height (optional)
ListboxProps={{ style: { maxHeight: '30vh' } }}
/>

I am using MUI 5.4.4 and ran into a similar issue where the Autocompeletes Popper component was trying to flip to the top (and therefor disappearing) when there wasn't enough space on the bottom of the page. I fixed the issue by creating custom popper component with a flip modifier with the fallbackPlacements option set to an empty array and setting the popperOptions placement to bottom so that the Popper menu is always at the bottom regardless of if there is enough space or not.
The popper docs for the flip modifier explained it pretty well.
Custom popper:
const CustomerPopper = (props) => {
const modifiers = [
{
name: 'flip',
options: {
fallbackPlacements: []
},
},
]
return (
<Popper
{...props}
modifiers={modifiers}
popperOptions={{
placement: 'bottom',
}}
/>
)
}
Autocomplete:
<Autocomplete
{...otherStuff}
PopperComponent={(props) => <CustomerPopper {...props} />}
/>

If anyone is still looking for an answer. You can achieve this by using flip modifier
const CustomerPopper = (props: any) => <Popper
{...props}
modifiers={{
flip: {
enabled: false,
}
}}
popperOptions={{
placement:'bottom',
}}
/>;

Related

Remove highlight on mouse leave in MUI Autocomplete

Using Autocomplete and hovering over the list of options, and moving the mouse out of it leaves the latest option, that the mouse was hovering over, still highlighted.
What's the best way to remove highlight when the mouse pointer is outside of the list altogether?
You can add mouseenter and mouseleave handlers to know when the mouse is inside the Listbox and override the background if the mouse is outside and the option is focused. Note that the double ampersand is necessary to increase the CSS specificity and put your styles above the one from MUI:
const [mouseInListBox, setMouseInListBox] = React.useState(false);
return (
<Autocomplete
{...props}
ListboxProps={{
onMouseEnter: () => setMouseInListBox(true),
onMouseLeave: () => setMouseInListBox(false),
sx: {
'&& li.Mui-focused': {
bgcolor: !mouseInListBox ? 'white' : undefined,
},
},
}}
renderInput={(params) => <TextField {...params} label="Movie" />}
/>
);
Live Demo

How to make dialog appear over Snackbar?

Codesandbox: https://codesandbox.io/s/elegant-wind-mv842
As can be seen in the sandbox, I am using Notistack for snackbars. I also want to use MUI Dialogs, but the Snackbars appear over the dialogs, which I don't want. Is there a way to make the dialog appear over the snackbars, without closing them?
<div>
<SnackbarProvider maxSnack={3}>
<MessageButtons />
</SnackbarProvider>
<SimpleDialogDemo />
</div>
Is the only component that I am producing in the demo, and it is enough to see the issue.
Just decrease z-index of notistack, e.g.:
const useStyles = makeStyles((theme) => ({
snackbar: {
zIndex: '10 !important',
}
}));
and provide appropriate props for SnackbarProvider
<SnackbarProvider classes={{containerRoot: classes.snackbar}}>
...
</SnackbarProvider>

MUI pop over not appearing on React-Table Cell click(AnchorEl error)

making a table that looks like this
I am using React-Table and MUI as libraries for my UI
Now having issue in calling the Popover when the ... button is clicked
the function that invokes the popover is
usersMore = (row) => (event) => {
this.setState({
anchorEl: event.currentTarget,
open: !this.state.open,
});
};
And Code for PopOver Is
<Popper
open={this.state.open}
anchorEl={this.state.anchorEl}
placement={"bottom-start"}
transition
>
{({ TransitionProps }) => (
<Fade {...TransitionProps} timeout={350}>
<Paper elevation={3}>
Something
</Paper>
</Fade>
)}
</Popper>
Whenever I click the Cell (code below) I get the error
Material-UI: The `anchorEl` prop provided to the component is invalid.
The anchor element should be part of the document layout.
Make sure the element is present in the document or that it's not display none.
Code for Setting up this cell is:
{
Header: "",
accessor: "id",
Cell: ({ row }) => {
const { id } = row.values;
return (
<DetailsButton key={id} onClick={this.usersMore(row)}>
<MoreIcon src={more}></MoreIcon>
</DetailsButton>
);
},
},
I have tried many things but gotten absolutely nowhere I even tried replacing popover to a simple div that has absoloute but it aint working ar well, tried putting pop over in the cell itself still, no luck

React Date Picker is Being Hidden Behind Overflow Parent (popover fixed placement issue)

I'm trying to have the date selection popover from react datepicker to open from a material UI menu item.
I have made my menu item the react datepicker input field. The issue is that my input field is the anchor for the selection date popover and the popover opens within my menu. I would like the popover to open above the menu.
The react datepicker documentation doesn't have a lot of information about the popover placement. Any idea how to achieve that ?
here is a screenshot of the unwanted behavior with the popover being "trapped" in the menu
quick overview of my menu code:
// this icon is the anchor for the menu
<MoreIcon onClick={handleClick} />
<Menu
id="simple-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleClose}
>
//this is my Date picker component
<Reschedule handleReschedule={handleReschedule} />
</Menu>
and my date picker component (with a custom input field as a Menu Item):
export const Reschedule = ({ handleReschedule }) => {
// ref to the datePicker to control open/close
const calendar = createRef();
//to Open the date picker
const openDatepicker = (e) => {
calendar.current.setOpen(true);
};
//to close the date picker
const closeDatepicker = (e) => {
calendar.current.setOpen(false);
};
const RescheduleButton = ({ onClick }) => {
return (
<MenuItem
className="overdue__rescheduleButton"
onClick={() => {
onClick();
}}
>
Reschedule
</MenuItem>
);
};
return (
<DatePicker
selected={null}
onChange={(date) => {
handleReschedule(date);
}}
ref={calendar}
minDate={subDays(new Date(), 0)}
customInput={<RescheduleButton onClick={openDatepicker} />}
popperPlacement="bottom-end"
/>
);
};
Thanks in advance
This prop is not documented as of this writing but you can use popperProps to configure the popper properties - they use Popper.js. In your case use positionFixed: true so that it would be relative to the initial containing block of the viewport (i.e., <html>)
<DatePicker
popperProps={{
positionFixed: true // use this to make the popper position: fixed
}}
/>
https://github.com/Hacker0x01/react-datepicker/blob/master/src/popper_component.jsx
Another way to achieve this can be to give React datepicker the id of the div you want to attach the picker to. For example a div near the very top of your application:
<DatePicker
portalId="root"
/>
Maybe the problem is solved, but I'm using TailwindCSS, and using this, the problem continues.
<DatePicker
popperProps={{
strategy: "fixed" // use this to make the popper position: fixed
}}
/>
Adding to the parent the classname overflow-visible it works.

how to pass the overlayProps into Panel

How can I pass the styles overlayProps into the Panel component as it is stated in https://developer.microsoft.com/en-us/fluentui#/controls/web/panel
I tried:
<Panel
overlayProps={{styles:{backgroundColor:'red'}}}
/>
But does not seems to work
The only thing missing from the original source is root, which is the target element in the overlay.
This snippet (full example) shows a Panel with a red overlay. (full example)
const PanelBasicExample: React.FunctionComponent = () => {
return (
<div>
<Panel
headerText="Sample panel"
isOpen={true}
overlayProps={{ className: "foo", styles: { root: { backgroundColor: "red" }}}}
>
<p>Content goes here.</p>
</Panel>
</div>
);
};
layerProps is an optional props to pass to the Layer component hosting the panel.Do you have a Layer Component?
Also, styles can have a className as properties, you may try to give the component a customised name and adapt the css.
i guess you can check out the "Panel - custom navigation" provided in your link.
it has something like below to override searchbox. I think Panel should be the same since it also accepts a similar styles prop.
const searchboxStyles = { root: { margin: '5px', height: 'auto', width: '100%' } };
<SearchBox
placeholder="Search here..."
styles={searchboxStyles}
ariaLabel="Sample search box. Does not actually search anything."
/>

Resources