React - Material-UI Modal causing an error with the tabindex - reactjs

I am getting this error when I open a modal on my React app but I can't figure out what it means or how to fix it.
"Warning: Material-UI: the modal content node does not accept focus.
For the benefit of assistive technologies, the tabIndex of the node is being set to "-1"."
<SettingsModal event={this.state.eventDetails} id={this.state.eventDetails.id} delete={this.handleRemoveEvent}/>
returns:
return(
<>
<Paper className={classes.SettingsModal}>
<h1>{this.props.event.name}</h1>
<p>{this.props.event.description}</p>
<p>{this.props.event.id}</p>
<Button onClick={(e) => this.props.delete(this.props.event)}>Delete Event</Button>
</Paper>
</>
);

I've found fix! To remove this error you should wrap your Modal content with DialogContent component like this
import DialogContent from '#material-ui/core/DialogContent';
// ...
render () {
return (
<Modal open={this.state.modalOpened} onClose={() => this.setState({ modalOpened: false, modalContent: null })}>
<DialogContent>
{this.state.modalContent}
</DialogContent>
</Modal>
);
}

All the credit goes to #Idos's comment above since he found the reference to the GitHub Issue. I found that this specific comment was useful.
The wrapping element of the Modal Contents needs to have a prop of
tabIndex: {-1}
In your case looks like you need to do the following:
return(
<Paper tabIndex:{-1} ...>
...
</Paper>
);

i had the same problem. apparently wrapping a div around SettingsModal should fix it.

Following #Wolfman comment, I just used Fragment from React, because it doesn't add any DOM element:
render () {
return (
<Modal open={this.state.modalOpened} onClose={() => this.setState({ modalOpened: false, modalContent: null })}>
<>
{this.state.modalContent}
</>
</Modal>
);
}
Even though, I still don't understand that issue :/

Related

How to make React-Material-UI Popper draggable?

I want to dynamically change Popper position on the screen with react-draggable.
Here's my code:
import PopupState, {bindPopper, bindToggle} from "material-ui-popup-state";
...
return (
<PopupState variant={"popper"} popupId='demo-popper'>
{(popupState) => {
// popupState.anchorEl = undefined <-- THIS WORKS BUT ERROR WITH 'anchorEl' IS RAISED
return (
<div>
<Button variant="contained" color="primary" {...bindToggle(popupState)}>
Toggle Popper
</Button>
<Draggable defaultPosition={position}>
<Popper {...bindPopper(popupState)}
transition
className={classes.popper}
placement='bottom-start'
>
<Paper elevation={5}>
<Typography variant={"h2"} className={classes.typography}>
POPUP BODY
</Typography>
</Paper>
</Popper>
</Draggable>
</div>
)
}}
</PopupState>
)
... and CODE Sandbox
As you can see, when I make popupState.anchorEl = undefined dragging functionality works, but error with anchorEl occurs.
Failed prop type: Material-UI: The anchorEl prop provided to the component is invalid.
It should be an HTML element instance or a referenceObject (https://popper.js.org/docs/v1/#referenceObject).
When anchorEl is set, <Draggable> is not working.
I think that on every component render, caused by dragging, Popup's position is being changed, but it's immediately going back to default, due to set anchorEl
Popper.js docs
Does anyone know how to solve that problem?
You do not need to use Popper.
Just use the Draggable component with the Paper.
https://codesandbox.io/s/react-material-ui-popup-draggable-forked-lmylb

Observed this Error: Material-UI: The `anchorEl` prop provided to the component is invalid

Observed the error when tried to open a popper in grid table. Error Details
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.
below is sample code I am using in grid table:
<>
<MoreVertIcon
ref={anchorRef}
aria-controls={open ? 'menu-list-grow' : undefined}
aria-haspopup="true"
// key={uuidv4()}
onClick={handleToggle}
style={{ color: theme.palette.primary.main }}
/>
<Popper open={open} anchorEl={anchorRef.current} role={undefined} transition disablePortal>
hello world
</Popper>
</>
found a reference but not sure where I am breaking this norm. Any help is appreciated.
Finally got the reason, child component was re-rendering because I added dynamic key on map iteration which were causing props to change, as I used iteration index as key issue resolved.
Another way that this error can occur is when using a react ref. There can be a 'race condition' where the element is created before it is rendered, it can be solved by delaying setting the anchor by a frame:
const MyComponent = () => {
const anchorRef = React.useRef()
const [anchorEl, setAnchorEl] = React.useState()
React.useEffect(() => {
setTimeout(() => setAnchorEl(anchorRef?.current), 1)
}, [anchorRef])
return <div ref={anchorRef}>
{anchorEl && <Popper anchorEl={anchorEl}>hello world</Popper>}
</div>
}
In my case the issue was due to the fact my button IconButton was not receiving the actual ref={anchorRef}. Yep, that silly issue...
Also, in my case, I could do well with a name key other than an index like:
{optionsArray.map(option => (
<MenuItem key={option} onClick={handleClose}>
{option}
</MenuItem>
))}

How to hide antd Modal header

my question is how to hide ant modal header
how to remove my modal section ?
the simple code is :
export default React.memo(() => {
return <Modal
width={800}
footer={<div/>}
>
</Modal>
});
i try to put header in property but not working
The header text can be changed via the title prop. If you don't want a title at all, you can pass an empty string.
export default React.memo(() => {
return (
<Modal
title=""
width={800}
footer={<div />}
>
</Modal>
);
});
As of right now it seems you can get rid of the top part by just not supplying a value to the "title" prop.

Toast message showing behind the Semantic-UI modal when dimmer is set to {'blurring'}

I am using the toast messages in reachjs together with the semantic-ui. The problem is that the toast message is showing behind the modal when dimmer is set to blurring. Otherwise it is showing on the top of the page as expected.
Do you have the same issues? How this can be corrected?
Thanks for your help!
<Modal
centered
size={'large'}
open={this.props.openVariationGeometry}
onClose={() => this.props.closeVariationGeometryModal()}
closeIcon
dimmer={'blurring'}
>
<Header icon="cube" content={'Change the Gemetry of the Selected Variation.'} />
<Modal.Content>
<VariationGeometryForm />
</Modal.Content>
</Modal>
Example
define a css rule for your toast with filter: none, or a general rule like this
.toast-container {
filter: none !important;
}
It is very old question but I ended here looking for a solution to the same problem so I wrote this down. At first, as this issue says, the only way I found to show the toasts with a modal present is by putting the Toast Container inside the modal. This method has the problem that you could see also the "main" toast blurred under the modal.
Later I found a final solution here. Both the toast container and the modal must be mounted on the same DOM node (I used #App).
First you have to put the toast container in the App component:
const App = () => (
<div id='App'>
<YourComponents />
<ToastContainer
className='dimmer toast-container' // 'dimmer' class is required to avoid blurring by modal
/>
</div>
)
After that you need the following css rule:
.blurring.dimmable > .toast-container {
// this prevents the toast from darkening by the modal
background-color: unset;
}
And finally the modal must be mounted in the same node:
<Modal
centered
size={'large'}
open={this.props.openVariationGeometry}
onClose={() => this.props.closeVariationGeometryModal()}
closeIcon
dimmer={'blurring'}
mountNode={document.getElementById('App')} // modal mounted on #App
>
<Header icon="cube" content={'Change the Gemetry of the Selected Variation.'} />
<Modal.Content>
<VariationGeometryForm />
</Modal.Content>
</Modal>

Flickering issue with antd

I am using the Ant Design components for some interfaces in a React App but I'm noticing an issue with Modals and Tooltips. Usually when the modal is empty or is simple - e.g has only a text it is going to show properly but in case there are more elements on it (on production scenario) it flickers.
You can visually watch the flickering issue here: https://drive.google.com/file/d/1ODsj-aGz6saHJLXLI7sJaesgHKKPrvD2/view
Hope to get some answers :-) Thank you!
The visibleRequest state variable is triggered true by a button in the interface.
EDIT: As requested here's my code:
renderRequests=()=>{
const data = [
{name:"Request #1",description:"Request description",status:"0"},
{name:"Request #1",description:"Request description",status:"1"},
{name:"Request #1",description:"Request description",status:"2"}
];
const handleOk = ()=>{
console.log("Submitted");
this.setState({visibleRequest:false})
}
const handleCancel = ()=>{
this.setState({visibleRequest:false})
}
return(
<div style={{overflowY:"scroll"}}>
<Modal
title="Submit new request"
visible={this.state.visibleRequest}
onOk={handleOk}
onCancel={handleCancel}
>
<Input placeholder="Title"/>
<Input.TextArea placeholder="Description"/>
<DatePicker/>
</Modal>
<List
dataSource={data}
renderItem={item=>{
return(
<List.Item>
<List.Item.Meta
title={item.name}
description={item.description}
/>
{item.status==1?<Tooltip title="Request approved">
<Icon type="check-circle" theme="twoTone" twoToneColor="#52c41a" />
</Tooltip>:
item.status==2?<Icon type="close-circle" theme="twoTone" twoToneColor="#7F1C43" />:<Icon type="ellipsis" theme="outlined" />}
</List.Item>
)
}}/>
<Pagination total={20}/>
</div>
)
}

Resources