React/Material UI - Prevent body scrolling on popover - reactjs

New to React and MUI, and having a UX issue where when we have a popover (dropdown menu, or autoselect dropdown) we can still scroll the main body of the site. I see that its fixed in the new beta V1 for MUI, but using the current stable release, Ive been asked to see if we can hack it up to stop the scrolling - but I cant seem to target/catch anything when we have a popover appear.
Examples: Current MUI - http://www.material-ui.com/#/components/auto-complete
V1 Beta MUI - https://material-ui-next.com/demos/autocomplete/
So, if you were to input something in those examples and trigger the downdown/popover, youll see that in the current MUI, you can still scroll the
I was hoping someone may have had this issue and had a solution they'd like to share?
Thanks guys!

I had a similar problem and solve it using 'disablePortal' Autocomplete property:
You can take a look at 'disablePortal' definition in here:
https://material-ui.com/api/autocomplete/#props
disablePortal: Disable the portal behavior. The children stay within it's parent DOM hierarchy.
I also had to add some styles to get pop up get positioned relative to input component.
Here is some sort of example:
const useStyles = makeStyles({
popperDisablePortal: {
position: 'relative',
}
})
const classes = useStyles()
<Autocomplete
classes={classes}
disablePortal={true}
{...props}
/>
So you may have to:
set up disablePortal property
define associated popperDisablePortal style with 'relative' position
EDIT: actually this error should not happen as part of default MUI Autocomplete set up. In my case, the error was some conflicting CSS property that was generating this scroller bug. Not sure in your case, but to me it happens to be some overflow: auto property defined on page HTML tag (sometimes you can find it on body tag). Replace with overflow: 'visible' and scrolling error should be gone without even changing one line of autocomplete component definition.

Related

toggling a sidebar in React

I created a simple app to work through an issue I'm having toggling a sidebar. I'm trying to use onClicks so that I can open and close a sidebar, and yet can't get it to work. I'm using styled-components, and for whatever reason I can't get the sidebar to toggle. I have a simple piece of state, isOpen, which is initialized to false, and when i click on a button in the 'navbar', i'd like it to toggle state to true via an onClick, and the sidebar should appear, and yet, it isn't working.
Here is the codesandbox link
I tried re-writing the app from scratch, using destructuring vs not using destructuring, and looked for any bugs in the code but couldn't. Any ideas for what I can try next? Also I made sure to use arrow functions for my onClicks.
The first issue I see is that the SidebarContainer is creating an overlay that prevents clicking on the button to open it. You'll need to change the visibility property on the SidebarContainer that's exported from SidebarElements:
visibility: ${(props) => (props.isOpen ? "visible" : "hidden")};
I prefer using the visibility property over setting display to block or none because if you want to you can animate or transition properties like opacity or transform. When toggling the display property your sidebar will just appear and disappear instantly.
Something else, you don't need to use an anonymous callback when calling the toggle from inside of Sidebar and Navbar:
<CloseIcon onClick={toggle}>X</CloseIcon>
<OpenIcon onClick={toggle}>open sidebar</OpenIcon>
I've updated the sandbox link you provided.
There are two problems with your code
You are calling the toggle like onClick={() => toggle} when you should be calling it like onClick={toggle} or onClick={() => toggle()}
Your "sidebar" is a overlapping your navbar (it is position:fixed with opacity:0 and covers the whole screen)
So fix 1 and then either move the sidebar elsewhere (as to not overlap) or change its display from none to block instead of the opacity.

Accessibility issues when using Material-UI 'Menu' on top of a 'Drawer'

I was having an accessibility issue when using Material-UI with React. Specifically when placing a Menu on a Drawer. Essentially the normal behaviour of a Menu is to highlight the top MenuItem. This behaviour is different if that menu is placed on a Material UI Drawer.
I have recreated the problem here using just the example Material-UI Menu and Drawer:
https://codesandbox.io/s/material-ui-menu-and-drawer-accessibility-issues-xjj3h?file=/src/App.js
The following images show the difference between the two menus when opened. I am using the chromevox extension while testing:
A normal menu when using chromevox to show accessability:
A menu when it is placed on a material UI drawer:
Would anyone be able to point out if this is an error in my code or if perhaps there are any workarounds? Was going to raise this as a new github issue but felt it was worth asking the question here first. :)
By default, the drawer enforces (so long as it is open) that focus stays within itself. So when the menu opens and grabs focus, the drawer notices that it lost focus and it grabs it back.
There are two options for fixing this:
You can turn off this drawer behavior by specifying the disableEnforceFocus prop (example here).
You can specify the disablePortal prop on the menu (example here). This will cause the menu to be a descendant of the drawer in the DOM (by default the menu uses portals and is added as a child of the <body> element), so the drawer will not try to "take back" the focus, because when focus is in the menu it will still be within the drawer.
I would recommend option 2 since the drawer's focus enforcement is generally a good thing from an accessibility standpoint.

Material-UI Popper remains visible when `open` prop is set to `true`

I'm using Material-UI Popper component and using it with its keepMounted prop set.
The issue I'm having is that when the Popper's component open prop is false the popper goes of out of the window boundaries but remain visible.
Q: What approach should I use to ensure that the popper is not visibled/displayed when the Popper component's open is false?
I've looked into it (see below for more details) but without success.
I've setup a small repro and example code here:
https://codesandbox.io/embed/389w75jpom
Scroll to the bottom when the tooltip/popper "isn't shown" and notice that it's still visible. Clicking the button toggles the value of the Popper component's open property.
I'm hoping for the popper to be hidden when open is false while still using keepMounted. I would prefer if it wouldn't be shown at all (e.g display: none) not just go out of sight.
From Material-UI docs, I’ve seen that popper.js modifiers can be passed using the modifiers prop and look at modifiers~hide specifically.
In the doc it's mentioned that the hide modifier:
[...] will set a x-out-of-boundaries attribute which can be used to hide with a CSS selector the popper when its reference is out of boundaries.
As per the doc this modifier should be enabled by default but it seems that the x-out-of-boundaries attribute doesn't seem to be applied to the popper container div at all.
So I haven't been able to rely on a CSS selector in this case.
I've also found this GH issue that I believe led to the implementation of the hide modifier.
I've tried to pass down [1] to the modifier a hidePopper function similar to the one suggested in the same GH issue here to detect when the popper goes in and out of the boundaries and set its style accordingly. Here's a fork of the previous repro with the code updated to reflect this:
https://codesandbox.io/embed/jvr6oy95j3
But the boundaries attribute is not present on the data object passed to the function (see the console logs) when testing here:
https://jvr6oy95j3.codesandbox.io/
Sorry if I'm missing something and would really appreciate any guidance on this. Thanks
[1] via the hide.fn modifier attribute.

Bootstrap DropdownButton Styling

I have the following code:
header_contents.push(<DropdownButton bsSize='xsmall' bsStyle='link' pullRight={true} id={1} title='Menu'>
{item_menu}
</DropdownButton>);
I want to have the styling in Bootstrap to be white lettering (currently blue) as I think the link option is defaulted to that. How can you change the styling for Bootstrap to pass link color, and other properties like if you want to move the link down a little on the page?
I should mention we do very little CSS styling as most of that is done within the ReactJS components.
Either override bootstrap CSS in a css file (that is what your seem to avoid I understand): it is the better way to ensure a global effect over every link in your application.
Or do no sent bsStyle='link' as DropdownButton property but instead, insert a style property with custom CSS. Yet you can insert style even if you don't remove bsStyle. You could then create your own component wrapping DropdownButton to ensure the same graphic chart in your application.
I figured it out with the help of an online chat room. Here's what I did.
I first made a style (dropDownLinkStyle) in the react component like this.
let dropDownLinkStyle = {
color: 'white'
};
Then I used it (dropDownLinkStyle) in the dropdownButton like this.
header_contents.push(<DropdownButton bsSize='large' style={dropDownLinkStyle} bsStyle='link' pullRight={true} id={1 /* avoids react warning */} title='Menu'>
{item_menu}
</DropdownButton>);
I hope this helps. This allowed me to keep my bsStyle which is link (tells Bootstrap I want a link type on my screen instead of a button) and allows me to change that link to white lettering. I could also pass more styling by just adding it to the object -- dropDownLinkStyle

Material-ui Stepper height not adjusted properly

The new Stepper component is awesome, except that the height of each step won't adjust properly when its child components change from hidden to visible, or vice versa via CSS. Specifically, if a component's style changes from display: 'none' to display: 'inline', the height of content will remain the same. As a result, the newly visible component won't show properly.
However, if the component is dynamically created (as opposed to be made visible with CSS), the height would adjust properly. Unfortunately in my case, I do need the component to be there even when they're not visible.
Has anyone encountered similar problem? I'm using react.js v0.14 and material-ui v0.15.0-beta.1.

Resources