Skip to content

Commit b8cc7f8

Browse files
jedwards1211oliviertassinari
authored andcommitted
[docs] Add some Render Props demos (#12366)
* feat: create MenuState component * fix(MenuState): fix some issues and test MenuState * docs: try and fail to add all MenuState docs * fix(MenuState): drop render prop * refactor(MenuState): rename event handlers * refactor: rename MenuState to PopupState * docs(PopupState): fix children function docs * fix: add variant property to PopupState and add Popper demo * docs(api): regen docs * fix(PopupState): use exactProp * refactor(PopupState): make API more flexible * docs(PopperPopupState): remove variant prop * test(PopupState): add bindHover/bindPopover tests * chore(PopupState): fix eslint errors * docs(PopupState): document bind functions * let's merge
1 parent 1230787 commit b8cc7f8

15 files changed

+240
-10
lines changed

docs/src/pages/demos/menus/FadeMenu.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,12 @@ class FadeMenu extends React.Component {
1919

2020
render() {
2121
const { anchorEl } = this.state;
22+
const open = Boolean(anchorEl);
2223

2324
return (
2425
<div>
2526
<Button
26-
aria-owns={anchorEl ? 'fade-menu' : null}
27+
aria-owns={open ? 'fade-menu' : null}
2728
aria-haspopup="true"
2829
onClick={this.handleClick}
2930
>
@@ -32,7 +33,7 @@ class FadeMenu extends React.Component {
3233
<Menu
3334
id="fade-menu"
3435
anchorEl={anchorEl}
35-
open={Boolean(anchorEl)}
36+
open={open}
3637
onClose={this.handleClose}
3738
TransitionComponent={Fade}
3839
>

docs/src/pages/demos/menus/LongMenu.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,13 @@ class LongMenu extends React.Component {
3838

3939
render() {
4040
const { anchorEl } = this.state;
41+
const open = Boolean(anchorEl);
4142

4243
return (
4344
<div>
4445
<IconButton
4546
aria-label="More"
46-
aria-owns={anchorEl ? 'long-menu' : null}
47+
aria-owns={open ? 'long-menu' : null}
4748
aria-haspopup="true"
4849
onClick={this.handleClick}
4950
>
@@ -52,7 +53,7 @@ class LongMenu extends React.Component {
5253
<Menu
5354
id="long-menu"
5455
anchorEl={anchorEl}
55-
open={Boolean(anchorEl)}
56+
open={open}
5657
onClose={this.handleClose}
5758
PaperProps={{
5859
style: {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import React from 'react';
2+
import Button from '@material-ui/core/Button';
3+
import Menu from '@material-ui/core/Menu';
4+
import MenuItem from '@material-ui/core/MenuItem';
5+
import toRenderProps from 'recompose/toRenderProps';
6+
import withState from 'recompose/withState';
7+
8+
const WithState = toRenderProps(withState('anchorEl', 'updateAnchorEl', null));
9+
10+
function RenderPropsMenu() {
11+
return (
12+
<WithState>
13+
{({ anchorEl, updateAnchorEl }) => {
14+
const open = Boolean(anchorEl);
15+
const handleClose = () => {
16+
updateAnchorEl(null);
17+
};
18+
19+
return (
20+
<React.Fragment>
21+
<Button
22+
aria-owns={open ? 'render-props-menu' : null}
23+
aria-haspopup="true"
24+
onClick={event => {
25+
updateAnchorEl(event.currentTarget);
26+
}}
27+
>
28+
Open Menu
29+
</Button>
30+
<Menu id="render-props-menu" anchorEl={anchorEl} open={open} onClose={handleClose}>
31+
<MenuItem onClick={handleClose}>Profile</MenuItem>
32+
<MenuItem onClick={handleClose}>My account</MenuItem>
33+
<MenuItem onClick={handleClose}>Logout</MenuItem>
34+
</Menu>
35+
</React.Fragment>
36+
);
37+
}}
38+
</WithState>
39+
);
40+
}
41+
42+
export default RenderPropsMenu;

docs/src/pages/demos/menus/menus.md

+7
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,10 @@ You can use the same list composition features with the `MenuItem` component:
5555
Use a different transition altogether.
5656

5757
{{"demo": "pages/demos/menus/FadeMenu.js"}}
58+
59+
## Render Props
60+
61+
It is a [render props](https://reactjs.org/docs/render-props.html) demo that
62+
keeps track of the local state for a single menu.
63+
64+
{{"demo": "pages/demos/menus/RenderPropsMenu.js"}}

docs/src/pages/utils/popover/MouseOverPopover.js

+8-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class MouseOverPopover extends React.Component {
2121
};
2222

2323
handlePopoverOpen = event => {
24-
this.setState({ anchorEl: event.target });
24+
this.setState({ anchorEl: event.currentTarget });
2525
};
2626

2727
handlePopoverClose = () => {
@@ -35,10 +35,16 @@ class MouseOverPopover extends React.Component {
3535

3636
return (
3737
<div>
38-
<Typography onMouseEnter={this.handlePopoverOpen} onMouseLeave={this.handlePopoverClose}>
38+
<Typography
39+
aria-owns={open ? 'mouse-over-popover' : null}
40+
aria-haspopup="true"
41+
onMouseEnter={this.handlePopoverOpen}
42+
onMouseLeave={this.handlePopoverClose}
43+
>
3944
Hover with a Popover.
4045
</Typography>
4146
<Popover
47+
id="mouse-over-popover"
4248
className={classes.popover}
4349
classes={{
4450
paper: classes.paper,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import React from 'react';
2+
import PropTypes from 'prop-types';
3+
import { withStyles } from '@material-ui/core/styles';
4+
import Typography from '@material-ui/core/Typography';
5+
import Button from '@material-ui/core/Button';
6+
import Popover from '@material-ui/core/Popover';
7+
import toRenderProps from 'recompose/toRenderProps';
8+
import withState from 'recompose/withState';
9+
10+
const WithState = toRenderProps(withState('anchorEl', 'updateAnchorEl', null));
11+
12+
const styles = theme => ({
13+
typography: {
14+
margin: theme.spacing.unit * 2,
15+
},
16+
});
17+
18+
function RenderPropsPopover(props) {
19+
const { classes } = props;
20+
21+
return (
22+
<WithState>
23+
{({ anchorEl, updateAnchorEl }) => {
24+
const open = Boolean(anchorEl);
25+
return (
26+
<React.Fragment>
27+
<Button
28+
aria-owns={open ? 'render-props-popover' : null}
29+
aria-haspopup="true"
30+
variant="contained"
31+
onClick={event => {
32+
updateAnchorEl(event.currentTarget);
33+
}}
34+
>
35+
Open Popover
36+
</Button>
37+
<Popover
38+
id="render-props-popover"
39+
open={open}
40+
anchorEl={anchorEl}
41+
onClose={() => {
42+
updateAnchorEl(null);
43+
}}
44+
anchorOrigin={{
45+
vertical: 'bottom',
46+
horizontal: 'center',
47+
}}
48+
transformOrigin={{
49+
vertical: 'top',
50+
horizontal: 'center',
51+
}}
52+
>
53+
<Typography className={classes.typography}>The content of the Popover.</Typography>
54+
</Popover>
55+
</React.Fragment>
56+
);
57+
}}
58+
</WithState>
59+
);
60+
}
61+
62+
RenderPropsPopover.propTypes = {
63+
classes: PropTypes.object.isRequired,
64+
};
65+
66+
export default withStyles(styles)(RenderPropsPopover);

docs/src/pages/utils/popover/SimplePopover.js

+9-2
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,21 @@ class SimplePopover extends React.Component {
3131
render() {
3232
const { classes } = this.props;
3333
const { anchorEl } = this.state;
34+
const open = Boolean(anchorEl);
3435

3536
return (
3637
<div>
37-
<Button variant="contained" onClick={this.handleClick}>
38+
<Button
39+
aria-owns={open ? 'simple-popper' : null}
40+
aria-haspopup="true"
41+
variant="contained"
42+
onClick={this.handleClick}
43+
>
3844
Open Popover
3945
</Button>
4046
<Popover
41-
open={Boolean(anchorEl)}
47+
id="simple-popper"
48+
open={open}
4249
anchorEl={anchorEl}
4350
onClose={this.handleClose}
4451
anchorOrigin={{

docs/src/pages/utils/popover/popover.md

+7
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,10 @@ the position of the popover.
3030
We demonstrate how to use the `Popover` component to implement a popover behavior based on the mouse over event.
3131

3232
{{"demo": "pages/utils/popover/MouseOverPopover.js"}}
33+
34+
## Render Props
35+
36+
It is a [render props](https://reactjs.org/docs/render-props.html) demo that
37+
keeps track of the local state for a single popover.
38+
39+
{{"demo": "pages/utils/popover/RenderPropsPopover.js"}}

docs/src/pages/utils/popper/FakedReferencePopper.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,11 @@ class FakedReferencePopper extends React.Component {
5050
render() {
5151
const { classes } = this.props;
5252
const { anchorEl, open } = this.state;
53+
const id = open ? 'faked-reference-popper' : null;
5354

5455
return (
5556
<div onMouseLeave={this.handleClose}>
56-
<Typography onMouseUp={this.handleMouseUp}>
57+
<Typography aria-describedby={id} onMouseUp={this.handleMouseUp}>
5758
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam ipsum purus, bibendum sit
5859
amet vulputate eget, porta semper ligula. Donec bibendum vulputate erat, ac fringilla mi
5960
finibus nec. Donec ac dolor sed dolor porttitor blandit vel vel purus. Fusce vel malesuada
@@ -62,7 +63,7 @@ class FakedReferencePopper extends React.Component {
6263
facilisis neque enim sed neque. Quisque accumsan metus vel maximus consequat. Suspendisse
6364
lacinia tellus a libero volutpat maximus.
6465
</Typography>
65-
<Popper open={open} anchorEl={anchorEl} transition placement="bottom-start">
66+
<Popper id={id} open={open} anchorEl={anchorEl} transition placement="bottom-start">
6667
{({ TransitionProps }) => (
6768
<Fade {...TransitionProps} timeout={350}>
6869
<Paper>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import React from 'react';
2+
import PropTypes from 'prop-types';
3+
import { withStyles } from '@material-ui/core/styles';
4+
import Popper from '@material-ui/core/Popper';
5+
import Typography from '@material-ui/core/Typography';
6+
import Button from '@material-ui/core/Button';
7+
import Fade from '@material-ui/core/Fade';
8+
import Paper from '@material-ui/core/Paper';
9+
import toRenderProps from 'recompose/toRenderProps';
10+
import withState from 'recompose/withState';
11+
12+
const WithState = toRenderProps(withState('anchorEl', 'updateAnchorEl', null));
13+
14+
const styles = theme => ({
15+
typography: {
16+
padding: theme.spacing.unit * 2,
17+
},
18+
});
19+
20+
function RenderPropsPopper(props) {
21+
const { classes } = props;
22+
23+
return (
24+
<WithState>
25+
{({ anchorEl, updateAnchorEl }) => {
26+
const open = Boolean(anchorEl);
27+
const id = open ? 'render-props-popper' : null;
28+
return (
29+
<React.Fragment>
30+
<Button
31+
aria-describedby={id}
32+
variant="contained"
33+
onClick={event => {
34+
updateAnchorEl(anchorEl ? null : event.currentTarget);
35+
}}
36+
>
37+
Toggle Popper
38+
</Button>
39+
<Popper id={id} open={open} anchorEl={anchorEl} transition>
40+
{({ TransitionProps }) => (
41+
<Fade {...TransitionProps} timeout={350}>
42+
<Paper>
43+
<Typography className={classes.typography}>
44+
The content of the Popper.
45+
</Typography>
46+
</Paper>
47+
</Fade>
48+
)}
49+
</Popper>
50+
</React.Fragment>
51+
);
52+
}}
53+
</WithState>
54+
);
55+
}
56+
57+
RenderPropsPopper.propTypes = {
58+
classes: PropTypes.object.isRequired,
59+
};
60+
61+
export default withStyles(styles)(RenderPropsPopper);

docs/src/pages/utils/popper/ScrollPlayground.js

+3
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ class AnchorPlayground extends React.Component {
175175
>
176176
\`\`\`
177177
`;
178+
const id = open ? 'scroll-playground' : null;
178179

179180
return (
180181
<div className={classes.root}>
@@ -188,6 +189,7 @@ class AnchorPlayground extends React.Component {
188189
}}
189190
variant="contained"
190191
onClick={this.handleClickButton}
192+
aria-describedby={id}
191193
>
192194
Toggle Popper
193195
</Button>
@@ -196,6 +198,7 @@ class AnchorPlayground extends React.Component {
196198
modifiers.
197199
</Typography>
198200
<Popper
201+
id={id}
199202
open={open}
200203
anchorEl={this.anchorEl}
201204
placement={placement}

docs/src/pages/utils/popper/popper.md

+7
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,10 @@ You just need to create an object shaped like the [`ReferenceObject`](https://gi
4040
Highlight part of the text to see the popper:
4141

4242
{{"demo": "pages/utils/popper/FakedReferencePopper.js"}}
43+
44+
## Render Props
45+
46+
It is a [render props](https://reactjs.org/docs/render-props.html) demo that
47+
keeps track of the local state for a single popper.
48+
49+
{{"demo": "pages/utils/popper/RenderPropsPopper.js"}}

pages/demos/menus.js

+7
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,13 @@ module.exports = require('fs')
4848
raw: preval`
4949
module.exports = require('fs')
5050
.readFileSync(require.resolve('docs/src/pages/demos/menus/FadeMenu'), 'utf8')
51+
`,
52+
},
53+
'pages/demos/menus/RenderPropsMenu.js': {
54+
js: require('docs/src/pages/demos/menus/RenderPropsMenu').default,
55+
raw: preval`
56+
module.exports = require('fs')
57+
.readFileSync(require.resolve('docs/src/pages/demos/menus/RenderPropsMenu'), 'utf8')
5158
`,
5259
},
5360
}}

pages/utils/popover.js

+7
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ module.exports = require('fs')
2727
raw: preval`
2828
module.exports = require('fs')
2929
.readFileSync(require.resolve('docs/src/pages/utils/popover/MouseOverPopover'), 'utf8')
30+
`,
31+
},
32+
'pages/utils/popover/RenderPropsPopover.js': {
33+
js: require('docs/src/pages/utils/popover/RenderPropsPopover').default,
34+
raw: preval`
35+
module.exports = require('fs')
36+
.readFileSync(require.resolve('docs/src/pages/utils/popover/RenderPropsPopover'), 'utf8')
3037
`,
3138
},
3239
}}

pages/utils/popper.js

+7
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,13 @@ module.exports = require('fs')
4141
raw: preval`
4242
module.exports = require('fs')
4343
.readFileSync(require.resolve('docs/src/pages/utils/popper/ScrollPlayground'), 'utf8')
44+
`,
45+
},
46+
'pages/utils/popper/RenderPropsPopper.js': {
47+
js: require('docs/src/pages/utils/popper/RenderPropsPopper').default,
48+
raw: preval`
49+
module.exports = require('fs')
50+
.readFileSync(require.resolve('docs/src/pages/utils/popper/RenderPropsPopper'), 'utf8')
4451
`,
4552
},
4653
}}

0 commit comments

Comments
 (0)