UNPKG

materialuiupgraded

Version:

Material-UI's workspace package

328 lines (314 loc) 10.3 kB
import React from 'react'; import PropTypes from 'prop-types'; import { withStyles } from '@material-ui/core/styles'; import FormControlLabel from '@material-ui/core/FormControlLabel'; import MarkdownElement from '@material-ui/docs/MarkdownElement'; import Grid from '@material-ui/core/Grid'; import RootRef from '@material-ui/core/RootRef'; import Typography from '@material-ui/core/Typography'; import Button from '@material-ui/core/Button'; import Popper from '@material-ui/core/Popper'; import Paper from '@material-ui/core/Paper'; 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'; import Switch from '@material-ui/core/Switch'; import TextField from '@material-ui/core/TextField'; const styles = theme => ({ root: { flexGrow: 1, }, scrollContainer: { height: 400, overflow: 'auto', marginBottom: theme.spacing.unit * 3, }, scroll: { position: 'relative', width: '230%', backgroundColor: theme.palette.background.paper, height: '230%', }, legend: { marginTop: theme.spacing.unit * 2, maxWidth: 300, }, paper: { maxWidth: 400, overflow: 'auto', }, select: { width: 200, }, popper: { zIndex: 1, '&[x-placement*="bottom"] $arrow': { top: 0, left: 0, marginTop: '-0.9em', width: '3em', height: '1em', '&::before': { borderWidth: '0 1em 1em 1em', borderColor: `transparent transparent ${theme.palette.common.white} transparent`, }, }, '&[x-placement*="top"] $arrow': { bottom: 0, left: 0, marginBottom: '-0.9em', width: '3em', height: '1em', '&::before': { borderWidth: '1em 1em 0 1em', borderColor: `${theme.palette.common.white} transparent transparent transparent`, }, }, '&[x-placement*="right"] $arrow': { left: 0, marginLeft: '-0.9em', height: '3em', width: '1em', '&::before': { borderWidth: '1em 1em 1em 0', borderColor: `transparent ${theme.palette.common.white} transparent transparent`, }, }, '&[x-placement*="left"] $arrow': { right: 0, marginRight: '-0.9em', height: '3em', width: '1em', '&::before': { borderWidth: '1em 0 1em 1em', borderColor: `transparent transparent transparent ${theme.palette.common.white}`, }, }, }, arrow: { position: 'absolute', fontSize: 7, width: '3em', height: '3em', '&::before': { content: '""', margin: 'auto', display: 'block', width: 0, height: 0, borderStyle: 'solid', }, }, }); class AnchorPlayground extends React.Component { state = { arrow: false, arrowRef: null, disablePortal: false, flip: true, open: false, placement: 'bottom', preventOverflow: 'scrollParent', }; handleChange = key => (event, value) => { this.setState({ [key]: value, }); }; handleChangeTarget = key => event => { this.setState({ [key]: event.target.value, }); }; handleClickButton = () => { this.setState(state => ({ open: !state.open, })); }; handleArrowRef = node => { this.setState({ arrowRef: node, }); }; centerScroll = ref => { if (!ref) { return; } const container = ref.parentElement; container.scrollTop = ref.clientHeight / 4; container.scrollLeft = ref.clientWidth / 4; }; render() { const { classes } = this.props; const { open, placement, disablePortal, flip, preventOverflow, arrow, arrowRef } = this.state; const code = ` \`\`\`jsx <Popper placement="${placement}" disablePortal={${disablePortal}} modifiers={{ flip: { enabled: ${flip}, }, preventOverflow: { enabled: ${preventOverflow !== 'disabled'}, boundariesElement: '${preventOverflow === 'disabled' ? 'scrollParent' : preventOverflow}', }, arrow: { enabled: ${arrow}, element: arrowRef, }, }} > \`\`\` `; const id = open ? 'scroll-playground' : null; return ( <div className={classes.root}> <div className={classes.scrollContainer}> <RootRef rootRef={this.centerScroll}> <Grid className={classes.scroll} container alignItems="center" justify="center"> <div> <Button buttonRef={node => { this.anchorEl = node; }} variant="contained" onClick={this.handleClickButton} aria-describedby={id} > Toggle Popper </Button> <Typography className={classes.legend}> Scroll around this container to experiment with flip and preventOverflow modifiers. </Typography> <Popper id={id} open={open} anchorEl={this.anchorEl} placement={placement} disablePortal={disablePortal} className={classes.popper} modifiers={{ flip: { enabled: flip, }, arrow: { enabled: arrow, element: arrowRef, }, preventOverflow: { enabled: preventOverflow !== 'disabled', boundariesElement: preventOverflow === 'disabled' ? 'scrollParent' : preventOverflow, }, }} > {arrow ? <span className={classes.arrow} ref={this.handleArrowRef} /> : null} <Paper className={classes.paper}> <DialogTitle>{"Use Google's location service?"}</DialogTitle> <DialogContent> <DialogContentText> Let Google help apps determine location. </DialogContentText> </DialogContent> <DialogActions> <Button onClick={this.handleClickButton} color="primary"> Disagree </Button> <Button onClick={this.handleClickButton} color="primary"> Agree </Button> </DialogActions> </Paper> </Popper> </div> </Grid> </RootRef> </div> <Grid container spacing={16}> <Grid item xs={12} sm={6}> <Typography gutterBottom variant="h6"> Appearance </Typography> <div> <TextField margin="normal" className={classes.select} label="Placement" select SelectProps={{ native: true }} value={placement} onChange={this.handleChangeTarget('placement')} > <option value="top-start">top-start</option> <option value="top">top</option> <option value="top-end">top-end</option> <option value="left-start">left-start</option> <option value="left">left</option> <option value="left-end">left-end</option> <option value="right-start">right-start</option> <option value="right">right</option> <option value="right-end">right-end</option> <option value="bottom-start">bottom-start</option> <option value="bottom">bottom</option> <option value="bottom-end">bottom-end</option> </TextField> </div> <FormControlLabel control={ <Switch checked={disablePortal} onChange={this.handleChange('disablePortal')} value="disablePortal" /> } label="Disable portal (the children stay within it's parent DOM hierarchy)" /> </Grid> <Grid item xs={12} sm={6}> <Typography gutterBottom variant="h6"> Modifiers (options from Popper.js) </Typography> <div> <TextField margin="normal" className={classes.select} label="Prevent overflow" select SelectProps={{ native: true }} value={preventOverflow} onChange={this.handleChangeTarget('preventOverflow')} > <option value="disabled">disabled</option> <option value="scrollParent">scrollParent</option> <option value="viewport">viewport</option> <option value="window">window</option> </TextField> </div> <FormControlLabel control={<Switch checked={flip} onChange={this.handleChange('flip')} value="flip" />} label={[ 'Flip', '(flip the popper’s placement when it starts to overlap its reference element)', ].join(' ')} /> <FormControlLabel control={ <Switch checked={arrow} onChange={this.handleChange('arrow')} value="arrow" /> } label="Arrow" /> </Grid> </Grid> <MarkdownElement text={code} /> </div> ); } } AnchorPlayground.propTypes = { classes: PropTypes.object.isRequired, }; export default withStyles(styles)(AnchorPlayground);