Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Dialog] Document the scroll property #12025

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions docs/src/pages/demos/dialogs/ScrollDialog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import React from 'react';
import Button from '@material-ui/core/Button';
import Dialog from '@material-ui/core/Dialog';
import DialogActions from '@material-ui/core/DialogActions';
import DialogContent from '@material-ui/core/DialogContent';
import DialogContentText from '@material-ui/core/DialogContentText';
import DialogTitle from '@material-ui/core/DialogTitle';

class ScrollDialog extends React.Component {
state = {
open: false,
scroll: 'paper',
};

handleClickOpen = scroll => () => {
this.setState({ open: true, scroll });
};

handleClose = () => {
this.setState({ open: false });
};

render() {
return (
<div>
<Button onClick={this.handleClickOpen('paper')}>scroll=paper</Button>
<Button onClick={this.handleClickOpen('body')}>scroll=body</Button>
<Dialog
open={this.state.open}
onClose={this.handleClose}
scroll={this.state.scroll}
aria-labelledby="scroll-dialog-title"
>
<DialogTitle id="scroll-dialog-title">Subscribe</DialogTitle>
<DialogContent>
<DialogContentText>
Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac
facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum
at eros. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus
sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean lacinia bibendum
nulla sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur
et. Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla. Cras
mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in,
egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.
Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis
lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean lacinia bibendum nulla
sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.
Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla. Cras mattis
consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in,
egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.
Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis
lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean lacinia bibendum nulla
sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.
Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla. Cras mattis
consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in,
egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.
Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis
lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean lacinia bibendum nulla
sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.
Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla. Cras mattis
consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in,
egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.
Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis
lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean lacinia bibendum nulla
sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.
Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla. Cras mattis
consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in,
egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.
Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis
lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean lacinia bibendum nulla
sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.
Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla.
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={this.handleClose} color="primary">
Cancel
</Button>
<Button onClick={this.handleClose} color="primary">
Subscribe
</Button>
</DialogActions>
</Dialog>
</div>
);
}
}

export default ScrollDialog;
12 changes: 11 additions & 1 deletion docs/src/pages/demos/dialogs/dialogs.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Dialog React component
components: Dialog, DialogTitle, DialogContent, DialogActions, Slide
components: Dialog, DialogTitle, DialogContent, DialogContentText, DialogActions, Slide
---

# Dialogs
Expand Down Expand Up @@ -74,3 +74,13 @@ You may make a `Dialog` responsively full screen the dialog using `withMobileDia
## Accessibility

Be sure to add `aria-labelledby="id..."`, referencing the modal title, to the `Dialog`. Additionally, you may give a description of your modal dialog with the `aria-describedby="id..."` property on the `Dialog`.

## Scrolling long content

When dialogs become too long for the user’s viewport or device, they scroll.
- `scroll=paper` the content of the dialog scrolls within the paper element.
- `scroll=body` the content of the dialog scrolls within the body element.

Try the demo below to see what we mean:

{{"demo": "pages/demos/dialogs/ScrollDialog.js"}}
28 changes: 18 additions & 10 deletions packages/material-ui/src/Modal/Modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,13 @@ if (process.env.NODE_ENV !== 'production' && !React.createContext) {
}

class Modal extends React.Component {
dialogElement = null;
mountNode = null;

mounted = false;
modalNode = null;

mountNode = null;
dialogNode = null;

mounted = false;

constructor(props) {
super(props);
Expand Down Expand Up @@ -105,6 +107,9 @@ class Modal extends React.Component {
handleRendered = () => {
this.autoFocus();

// Fix a bug on Chrome where the scroll isn't initially 0.
this.modalNode.scrollTop = 0;

if (this.props.onRendered) {
this.props.onRendered();
}
Expand Down Expand Up @@ -171,8 +176,8 @@ class Modal extends React.Component {

const currentActiveElement = ownerDocument(this.mountNode).activeElement;

if (this.dialogElement && !this.dialogElement.contains(currentActiveElement)) {
this.dialogElement.focus();
if (this.dialogNode && !this.dialogNode.contains(currentActiveElement)) {
this.dialogNode.focus();
}
};

Expand All @@ -183,10 +188,10 @@ class Modal extends React.Component {

const currentActiveElement = ownerDocument(this.mountNode).activeElement;

if (this.dialogElement && !this.dialogElement.contains(currentActiveElement)) {
if (this.dialogNode && !this.dialogNode.contains(currentActiveElement)) {
this.lastFocus = currentActiveElement;

if (!this.dialogElement.hasAttribute('tabIndex')) {
if (!this.dialogNode.hasAttribute('tabIndex')) {
warning(
false,
[
Expand All @@ -195,10 +200,10 @@ class Modal extends React.Component {
'the tabIndex of the node is being set to "-1".',
].join('\n'),
);
this.dialogElement.setAttribute('tabIndex', -1);
this.dialogNode.setAttribute('tabIndex', -1);
}

this.dialogElement.focus();
this.dialogNode.focus();
}
}

Expand Down Expand Up @@ -277,6 +282,9 @@ class Modal extends React.Component {
>
<div
data-mui-test="Modal"
ref={node => {
this.modalNode = node;
}}
className={classNames(classes.root, className, {
[classes.hidden]: exited,
})}
Expand All @@ -287,7 +295,7 @@ class Modal extends React.Component {
)}
<RootRef
rootRef={node => {
this.dialogElement = node;
this.dialogNode = node;
}}
>
{React.cloneElement(children, childProps)}
Expand Down
4 changes: 4 additions & 0 deletions pages/api/dialog-content-text.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,7 @@ you need to use the following style sheet name: `MuiDialogContentText`.
The properties of the [Typography](/api/typography) component are also available.
You can take advantage of this behavior to [target nested components](/guides/api#spread).

## Demos

- [Dialogs](/demos/dialogs)

7 changes: 7 additions & 0 deletions pages/demos/dialogs.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ module.exports = require('fs')
raw: preval`
module.exports = require('fs')
.readFileSync(require.resolve('docs/src/pages/demos/dialogs/ResponsiveDialog'), 'utf8')
`,
},
'pages/demos/dialogs/ScrollDialog.js': {
js: require('docs/src/pages/demos/dialogs/ScrollDialog').default,
raw: preval`
module.exports = require('fs')
.readFileSync(require.resolve('docs/src/pages/demos/dialogs/ScrollDialog'), 'utf8')
`,
},
}}
Expand Down