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

[docs] Add Snackbars TypeScript Demos #15087

Merged
merged 5 commits into from
Mar 30, 2019
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
13 changes: 8 additions & 5 deletions docs/src/pages/demos/snackbars/ConsecutiveSnackbars.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@ const styles = theme => ({
class ConsecutiveSnackbars extends React.Component {
queue = [];

state = {
open: false,
messageInfo: {},
};
constructor(props) {
super(props);

this.state = {
open: false,
};
}

handleClick = message => () => {
this.queue.push({
Expand Down Expand Up @@ -57,7 +60,7 @@ class ConsecutiveSnackbars extends React.Component {

render() {
const { classes } = this.props;
const { messageInfo } = this.state;
const { messageInfo = {} } = this.state;

return (
<div>
Expand Down
121 changes: 121 additions & 0 deletions docs/src/pages/demos/snackbars/ConsecutiveSnackbars.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import React, { SyntheticEvent } from 'react';
import PropTypes, { number } from 'prop-types';
import { createStyles, withStyles, WithStyles, Theme } from '@material-ui/core/styles';
import Button from '@material-ui/core/Button';
import Snackbar from '@material-ui/core/Snackbar';
import IconButton from '@material-ui/core/IconButton';
import CloseIcon from '@material-ui/icons/Close';
import { string } from 'parsimmon';

const styles = (theme: Theme) =>
createStyles({
close: {
padding: theme.spacing(0.5),
},
});

export interface SnackbarMessage {
message: string;
key: number;
}

export type Props = WithStyles<typeof styles>;

export interface State {
open: boolean;
messageInfo?: SnackbarMessage;
}

class ConsecutiveSnackbars extends React.Component<Props, State> {
queue: SnackbarMessage[] = [];

constructor(props: Props) {
super(props);

this.state = {
open: false,
};
}

handleClick = (message: string) => () => {
this.queue.push({
message,
key: new Date().getTime(),
});

if (this.state.open) {
// immediately begin dismissing current message
// to start showing new one
this.setState({ open: false });
} else {
this.processQueue();
}
};

processQueue = () => {
if (this.queue.length > 0) {
this.setState({
messageInfo: this.queue.shift(),
open: true,
});
}
};

handleClose = (event: SyntheticEvent | MouseEvent, reason?: string) => {
if (reason === 'clickaway') {
return;
}
this.setState({ open: false });
};

handleExited = () => {
this.processQueue();
};

render() {
const { classes } = this.props;
const { messageInfo = {} as SnackbarMessage } = this.state;

return (
<div>
<Button onClick={this.handleClick('message a')}>Show message A</Button>
<Button onClick={this.handleClick('message b')}>Show message B</Button>
<Snackbar
key={messageInfo.key}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}
open={this.state.open}
autoHideDuration={6000}
onClose={this.handleClose}
onExited={this.handleExited}
ContentProps={{
'aria-describedby': 'message-id',
}}
message={<span id="message-id">{messageInfo.message}</span>}
action={[
<Button key="undo" color="secondary" size="small" onClick={this.handleClose}>
UNDO
</Button>,
<IconButton
key="close"
aria-label="Close"
color="inherit"
className={classes.close}
onClick={this.handleClose}
>
<CloseIcon />
</IconButton>,
]}
/>
</div>
);
}
}

(ConsecutiveSnackbars as React.ComponentClass<Props>).propTypes = {
classes: PropTypes.object.isRequired,
} as any;

export default withStyles(styles)(ConsecutiveSnackbars);
162 changes: 162 additions & 0 deletions docs/src/pages/demos/snackbars/CustomizedSnackbars.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
import React, { SyntheticEvent } from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import Button from '@material-ui/core/Button';
import CheckCircleIcon from '@material-ui/icons/CheckCircle';
import ErrorIcon from '@material-ui/icons/Error';
import InfoIcon from '@material-ui/icons/Info';
import CloseIcon from '@material-ui/icons/Close';
import green from '@material-ui/core/colors/green';
import amber from '@material-ui/core/colors/amber';
import IconButton from '@material-ui/core/IconButton';
import Snackbar from '@material-ui/core/Snackbar';
import SnackbarContent from '@material-ui/core/SnackbarContent';
import WarningIcon from '@material-ui/icons/Warning';
import { makeStyles, Theme } from '@material-ui/core/styles';

const variantIcon = {
success: CheckCircleIcon,
warning: WarningIcon,
error: ErrorIcon,
info: InfoIcon,
};

const useStyles1 = makeStyles((theme: Theme) => ({
success: {
backgroundColor: green[600],
},
error: {
backgroundColor: theme.palette.error.dark,
},
info: {
backgroundColor: theme.palette.primary.dark,
},
warning: {
backgroundColor: amber[700],
},
icon: {
fontSize: 20,
},
iconVariant: {
opacity: 0.9,
marginRight: theme.spacing(1),
},
message: {
display: 'flex',
alignItems: 'center',
},
}));

export interface Props {
className?: string;
message?: string;
onClose?: () => void;
variant: keyof typeof variantIcon;
}

function MySnackbarContentWrapper(props: Props) {
const classes = useStyles1();
const { className, message, onClose, variant, ...other } = props;
const Icon = variantIcon[variant];

return (
<SnackbarContent
className={clsx(classes[variant], className)}
aria-describedby="client-snackbar"
message={
<span id="client-snackbar" className={classes.message}>
<Icon className={clsx(classes.icon, classes.iconVariant)} />
{message}
</span>
}
action={[
<IconButton
edge="end"
key="close"
aria-label="Close"
color="inherit"
className={classes.close}
onClick={onClose}
>
<CloseIcon className={classes.icon} />
</IconButton>,
]}
{...other}
/>
);
}

MySnackbarContentWrapper.propTypes = {
className: PropTypes.string,
message: PropTypes.node,
onClose: PropTypes.func,
variant: PropTypes.oneOf(['success', 'warning', 'error', 'info']).isRequired,
};

const useStyles2 = makeStyles((theme: Theme) => ({
margin: {
margin: theme.spacing(1),
},
}));

function CustomizedSnackbars() {
const classes = useStyles2();
const [open, setOpen] = React.useState(false);

function handleClick() {
setOpen(true);
}

function handleClose(event?: SyntheticEvent, reason?: string) {
if (reason === 'clickaway') {
return;
}

setOpen(false);
}

return (
<div>
<Button className={classes.margin} onClick={handleClick}>
Open success snackbar
</Button>
<Snackbar
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}
open={open}
autoHideDuration={6000}
onClose={handleClose}
>
<MySnackbarContentWrapper
onClose={handleClose}
variant="success"
message="This is a success message!"
/>
</Snackbar>
<MySnackbarContentWrapper
variant="error"
className={classes.margin}
message="This is an error message!"
/>
<MySnackbarContentWrapper
variant="warning"
className={classes.margin}
message="This is a warning message!"
/>
<MySnackbarContentWrapper
variant="info"
className={classes.margin}
message="This is an information message!"
/>
<MySnackbarContentWrapper
variant="success"
className={classes.margin}
message="This is a success message!"
/>
</div>
);
}

export default CustomizedSnackbars;
11 changes: 7 additions & 4 deletions docs/src/pages/demos/snackbars/DirectionSnackbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,13 @@ function TransitionDown(props) {
}

class DirectionSnackbar extends React.Component {
state = {
open: false,
Transition: null,
};
constructor() {
super();

this.state = {
open: false,
};
}

handleClick = Transition => () => {
this.setState({ open: true, Transition });
Expand Down
66 changes: 66 additions & 0 deletions docs/src/pages/demos/snackbars/DirectionSnackbar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import React from 'react';
import Button from '@material-ui/core/Button';
import Snackbar from '@material-ui/core/Snackbar';
import Slide from '@material-ui/core/Slide';
import { TransitionProps } from '@material-ui/core/transitions/transition';

function TransitionLeft(props: TransitionProps) {
return <Slide {...props} direction="left" />;
}

function TransitionUp(props: TransitionProps) {
return <Slide {...props} direction="up" />;
}

function TransitionRight(props: TransitionProps) {
return <Slide {...props} direction="right" />;
}

function TransitionDown(props: TransitionProps) {
return <Slide {...props} direction="down" />;
}

export interface State {
open: boolean;
Transition?: React.ComponentType<TransitionProps>;
}

class DirectionSnackbar extends React.Component<void, State> {
constructor() {
super();

this.state = {
open: false,
};
}

handleClick = (Transition: React.ComponentType<TransitionProps>) => () => {
this.setState({ open: true, Transition });
};

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

render() {
return (
<div>
<Button onClick={this.handleClick(TransitionLeft)}>Right</Button>
<Button onClick={this.handleClick(TransitionUp)}>Up</Button>
<Button onClick={this.handleClick(TransitionRight)}>Left</Button>
<Button onClick={this.handleClick(TransitionDown)}>Down</Button>
<Snackbar
open={this.state.open}
onClose={this.handleClose}
TransitionComponent={this.state.Transition}
ContentProps={{
'aria-describedby': 'message-id',
}}
message={<span id="message-id">I love snacks</span>}
/>
</div>
);
}
}

export default DirectionSnackbar;
Loading