From 91846cdbc5228bcb8b1fa76a9254bffd847141b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A1ssio=20Zen?= Date: Wed, 14 Sep 2016 11:59:59 -0300 Subject: [PATCH] Toast component --- src/components/UI/card/Card.css | 7 ++- src/components/UI/index.js | 1 + src/components/UI/theme.css | 1 + src/components/UI/toast/Toast.css | 40 +++++++++++++++++ src/components/UI/toast/Toast.js | 74 +++++++++++++++++++++++++++++++ src/components/stories/Toast.js | 19 ++++++++ src/components/stories/index.js | 1 + 7 files changed, 139 insertions(+), 4 deletions(-) create mode 100644 src/components/UI/toast/Toast.css create mode 100644 src/components/UI/toast/Toast.js create mode 100644 src/components/stories/Toast.js diff --git a/src/components/UI/card/Card.css b/src/components/UI/card/Card.css index 592cfd1e..43d7392e 100644 --- a/src/components/UI/card/Card.css +++ b/src/components/UI/card/Card.css @@ -1,8 +1,7 @@ +@import "../theme.css"; + .card { - composes: base from "../theme.css"; - composes: container from "../theme.css"; - composes: rounded from "../theme.css"; - composes: depth from "../theme.css"; + composes: base container rounded depth; overflow: hidden; width: 240px; } diff --git a/src/components/UI/index.js b/src/components/UI/index.js index 7f538b2a..87b473a5 100644 --- a/src/components/UI/index.js +++ b/src/components/UI/index.js @@ -1,3 +1,4 @@ export { default as Card } from './card/Card'; export { default as Loader } from './loader/Loader'; export { default as Icon } from './icon/Icon'; +export { default as Toast } from './toast/Toast'; diff --git a/src/components/UI/theme.css b/src/components/UI/theme.css index b8add9c7..87c78c64 100644 --- a/src/components/UI/theme.css +++ b/src/components/UI/theme.css @@ -1,5 +1,6 @@ :root { --defaultColor: #333; + --defaultColorLight: #eee; --backgroundColor: #fff; --shadowColor: rgba(0, 0, 0, 0.117647); --successColor: #1c7; diff --git a/src/components/UI/toast/Toast.css b/src/components/UI/toast/Toast.css new file mode 100644 index 00000000..2c5bb930 --- /dev/null +++ b/src/components/UI/toast/Toast.css @@ -0,0 +1,40 @@ +@import "../theme.css"; + +.toast { + composes: base container rounded depth; + position: absolute; + top: 10px; + right: 10px; + z-index: 100; + width: 350px; + padding: 20px 10px; + font-size: 0.9rem; + text-align: center; + color: var(--defaultColorLight); + overflow: hidden; + opacity: 1; + transition: opacity .3s ease-in; +} + +.hidden { + opacity: 0; +} + +.icon { + position: absolute; + top: calc(50% - 15px); + left: 15px; + font-size: 30px; +} + +.success { + background-color: var(--successColor); +} + +.warning { + background-color: var(--warningColor); +} + +.error { + background-color: var(--errorColor); +} diff --git a/src/components/UI/toast/Toast.js b/src/components/UI/toast/Toast.js new file mode 100644 index 00000000..34671df4 --- /dev/null +++ b/src/components/UI/toast/Toast.js @@ -0,0 +1,74 @@ +import React, { PropTypes } from 'react'; +import { Icon } from '../index'; +import styles from './Toast.css'; + +export default class Toast extends React.Component { + constructor(props) { + super(props); + this.state = { + shown: false + }; + + this.autoHideTimeout = this.autoHideTimeout.bind(this); + } + + componentWillMount() { + if (this.props.show) { + this.autoHideTimeout(); + this.setState({ shown: true }); + } + } + + componentWillReceiveProps(nextProps) { + if (nextProps !== this.props) { + if (nextProps.show) this.autoHideTimeout(); + this.setState({ shown: nextProps.show }); + } + } + + componentWillUnmount() { + if (this.timeOut) { + clearTimeout(this.timeOut); + } + } + + autoHideTimeout() { + clearTimeout(this.timeOut); + this.timeOut = setTimeout(() => { + this.setState({ shown: false }); + }, 4000); + } + + render() { + const { style, type, className, children } = this.props; + const icons = { + success: 'check', + warning: 'attention', + error: 'alert' + }; + const classes = [styles.toast]; + if (className) classes.push(className); + + let icon = ''; + if (type) { + classes.push(styles[type]); + icon = ; + } + + if (!this.state.shown) { + classes.push(styles.hidden); + } + + return ( +
{icon}{children}
+ ); + } +} + +Toast.propTypes = { + style: PropTypes.object, + type: PropTypes.oneOf(['success', 'warning', 'error']).isRequired, + className: PropTypes.string, + show: PropTypes.bool, + children: PropTypes.node +}; diff --git a/src/components/stories/Toast.js b/src/components/stories/Toast.js new file mode 100644 index 00000000..6ac4b7c6 --- /dev/null +++ b/src/components/stories/Toast.js @@ -0,0 +1,19 @@ +import React from 'react'; +import { Toast } from '../UI'; +import { storiesOf } from '@kadira/storybook'; + + +storiesOf('Toast', module) + .add('Success', () => ( +
+ A Toast Message +
+ )).add('Waring', () => ( +
+ A Toast Message +
+ )).add('Error', () => ( +
+ A Toast Message +
+ )); diff --git a/src/components/stories/index.js b/src/components/stories/index.js index a966ecf4..21f91079 100644 --- a/src/components/stories/index.js +++ b/src/components/stories/index.js @@ -1,2 +1,3 @@ import './Card'; import './Icon'; +import './Toast';