Skip to content

Commit

Permalink
feat(Snackbar): create new component
Browse files Browse the repository at this point in the history
docs: create new page for snackbar
  • Loading branch information
kradio3 committed Feb 22, 2017
1 parent b509e8d commit 26ed5b6
Show file tree
Hide file tree
Showing 6 changed files with 168 additions and 14 deletions.
3 changes: 3 additions & 0 deletions docs/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,6 @@ linkPrefix = "/react-mdc-web"
[[components]]
name = "Text Field"
path = "/components/text_field/"
[[components]]
name = "Snackbar"
path = "/components/snackbar/"
60 changes: 60 additions & 0 deletions docs/pages/components/snackbar/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
title: "Snackbar"
---
Snackbar with single line of text
```jsx
<Snackbar
onTimeout={() => {this.setState({snackbar: false});}}
open={this.state.snackbar}
>
Document modified
</Snackbar>
```

You can add a single action to snackbar. When user clicks on action button, ```onClick``` callback will be fired
```jsx
<Snackbar
action="undo"
onClick={(event) => { console.log(event) }}
onTimeout={() => { this.setState({snackbar: false}); }}
open={this.state.snackbar}
>
Document modified
</Snackbar>
```

Snackbar with multiline text
```jsx
<Snackbar
multiline
onTimeout={() => { this.setState({snackbar: false}); }}
open={this.state.snackbar}
>
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam
</Snackbar>
```

In multiline snackbar you can place action button below text
```jsx
<Snackbar
action="undo"
actionOnBottom
onClick={(event) => { console.log(event) }}
multiline
onTimeout={() => { this.setState({snackbar: false}); }}
open={this.state.snackbar}
>
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam
</Snackbar>
```

Default timeout is 2750 ms. But you can override it by ```timeout``` property
```jsx
<Snackbar
timeout={5000}
onTimeout={() => {this.setState({snackbar: false});}}
open={this.state.snackbar}
>
Loading complete
</Snackbar>
```
14 changes: 0 additions & 14 deletions docs/pages/components/text_field/index.md

This file was deleted.

101 changes: 101 additions & 0 deletions src/Snackbar/Snackbar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import React, { PropTypes } from 'react';
import classnames from 'classnames';
import Button from '../Button/Button';

const ROOT = 'mdc-snackbar';
const ACTIVE = `${ROOT}--active`;
const TEXT = `${ROOT}__text`;
const ACTION_WRAPPER = `${ROOT}__action-wrapper`;
const ACTION_BUTTON = `${ROOT}__action-button`;
const MULTILINE = `${ROOT}--multiline`;
const ACTION_ON_BOTTOM = `${ROOT}--action-on-bottom`;
const MESSAGE_TIMEOUT = 2750;

class Snackbar extends React.PureComponent {

static propTypes = {
action: PropTypes.string,
actionOnBottom: PropTypes.bool,
children: PropTypes.node,
className: PropTypes.string,
multiline: PropTypes.bool,
onClick: PropTypes.func,
onTimeout: PropTypes.func,
open: PropTypes.bool,
timeout: PropTypes.number,
};

static defaultProps = {
timeout: MESSAGE_TIMEOUT,
};

constructor(props) {
super(props);
this.handleTimeout = this.handleTimeout.bind(this);
}

componentDidMount() {
const { open, timeout } = this.props;
if (open) {
setTimeout(this.handleTimeout, timeout);
}
}

componentWillReceiveProps({ open: nextOpen }) {
const { open, timeout } = this.props;
if (nextOpen && !open) {
setTimeout(this.handleTimeout, timeout);
}
}

handleTimeout() {
const { onTimeout } = this.props;
if (onTimeout) {
onTimeout();
}
}

render() {
const {
action,
actionOnBottom,
children,
className,
multiline,
onClick,
onTimeout, // eslint-disable-line no-unused-vars
open,
timeout, // eslint-disable-line no-unused-vars
...otherProps
} = this.props;
return (
<div
aria-live="assertive"
aria-atomic="true"
aria-hidden={!open}
className={classnames(ROOT, {
[ACTIVE]: open,
[MULTILINE]: multiline,
[ACTION_ON_BOTTOM]: multiline && actionOnBottom,
}, className)}
{...otherProps}
>
<div className={TEXT}>
{children}
</div>
<div
aria-hidden={!onClick || !action || !open}
className={ACTION_WRAPPER}
>
<Button
className={ACTION_BUTTON}
onClick={(event) => { if (onClick) onClick(event); }}
>
{action}
</Button>
</div>
</div>
);
}
}
export default Snackbar;
3 changes: 3 additions & 0 deletions src/Snackbar/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import '@material/snackbar/dist/mdc.snackbar.min.css';

export { default } from './Snackbar';
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ export { default as IconToggle } from './IconToggle';
export { default as Icon } from './Icon';
export { Drawer, DrawerSpacer, Navigation, DrawerHeader, DrawerHeaderContent, DrawerContent } from './Drawer';
export { Grid, Cell } from './Layout';
export { default as Snackbar } from './Snackbar';

0 comments on commit 26ed5b6

Please sign in to comment.