diff --git a/src/alert/card.js b/src/alert/card.js new file mode 100644 index 0000000..d2ac7d1 --- /dev/null +++ b/src/alert/card.js @@ -0,0 +1,42 @@ +import devboard from 'devboard'; +import React from 'react'; +import Alert from './index.js'; + +const devcard = devboard.ns('alerts'); + +devcard( + 'Alerts', + ` + Patternity Alerts + + * success + * error + * info + * warning + `, +
+ Success + Error + Info + Warning +
+); + + +devcard( + 'Alerts with close', + ' ', +
+ Closable +
+); + + +devcard( + 'Alerts with title and close', + ' ', +
+ This is the body +
+); + diff --git a/src/alert/index.js b/src/alert/index.js new file mode 100644 index 0000000..4048566 --- /dev/null +++ b/src/alert/index.js @@ -0,0 +1,116 @@ +import React, { PropTypes, Component } from 'react'; +import styles from './styles.css'; +import cn from 'classnames'; +import { Icon } from 'infl-icons'; + +export default class Alert extends Component { + static propTypes = { + title: PropTypes.string, + type: PropTypes.oneOf(['success', 'error', 'info', 'warning']), + showIcon: PropTypes.bool, + closeable: PropTypes.bool, + showAlert: PropTypes.bool, + onClose: PropTypes.func, + hideIn: PropTypes.number + }; + + static defaultProps = { + title: '', + showIcon: false, + closeable: false, + showAlert: true, + onClose() {}, + hideIn: 0 + } + + hideInTimeout = null; + + state = { + showAlert: this.props.showAlert, + closeable: this.props.closeable + }; + + componentWillReceiveProps = (newProps) => { + this.clearHideInTimeout(); + this.setState({ + showAlert: newProps.showAlert, + closeable: newProps.closeable + }); + }; + + componentDidMount = () => { + this.hideAlert(); + }; + + componentWillUpdate = (nextProps) => { + this.clearHideInTimeout(); + this.hideAlert(nextProps.hideIn); + }; + + clearHideInTimeout = () =>{ + window.clearTimeout(this.hideInTimeout); + }; + + hideAlert = () => { + const { hideIn } = this.props; + if (hideIn > 0) { + this.hideInTimeout = setTimeout(this.close, hideIn * 1000); + } + }; + + render = () =>
+
+ {this.title()} +
+ {this.props.children} +
+
+ {this.closeable()} +
; + + classes = () => + cn( + styles.alertMsg, + { + [styles.hasIcon]: this.props.showIcon, + [styles.hide]: !this.props.showAlert, + [styles[this.props.type]]: this.props.type + } + ); + + title = () => { + if (this.props.title) { + return ( +

+ {this.icon()} + {this.props.title} +

+ ); + } + return null; + }; + + icon = () => { + const { showIcon } = this.props; + + if (!showIcon) + return null; + + return + + ; + }; + + close = () => { + this.setState({ showAlert: false }); + this.props.onClose(); + }; + + closeable = () => { + return this.state.closeable + ? + + + : null; + }; +} \ No newline at end of file diff --git a/src/alert/styles.css b/src/alert/styles.css new file mode 100644 index 0000000..cd548b3 --- /dev/null +++ b/src/alert/styles.css @@ -0,0 +1,198 @@ +.alertMsg { + padding: 10px 20px; + border-radius: 2px; + background-color: lighten($info-color, 0.55); + display: flex; + justify-content: space-between; + position: relative; + color: $info-color; + + &.hide { + display: none; + } + + h4 { + margin: 0px; + line-height: 35px; + font-size: 16px; + text-align: left; + + span { + vertical-align: middle; + } + } + + .alertIcon { + margin-right: 10px; + } + + .close { + padding: 10px; + position: absolute; + right: 5px; + top: 0px; + color: $info-color; + cursor: pointer; + font-weight: bold; + z-index: 3; + + &:hover { + color: darken($info-color, 0.1); + transition: color 0.5s ease-out; + } + } + + .alertBody { + overflow: hidden; + position: relative; + line-height: 1.2em; + } + + &.hasIcon { + .alertBody { + padding-left: 26px; + + .detailed { + margin-left: -26px; + } + } + } + + &.warning { + background-color: lighten($warning-color, 0.45); + color: darken($warning-color, 0.1); + + .close { + color: darken($warning-color, 0.1); + + &:hover { + color: darken($warning-color, 0.15); + } + } + + .alertAction { + button { + border-color: darken($warning-color, 0.1); + color: darken($warning-color, 0.1) !important; + + &:hover { + border-color: darken($warning-color, 0.15); + color: darken($warning-color, 0.15) !important; + } + } + } + } + + &.success { + background-color: lighten($success-color, 0.4); + color: darken($success-color, 0.15); + + .close { + color: darken($success-color, 0.15); + + &:hover { + color : darken($success-color, 0.1); + } + } + + .alertAction { + button { + border-color: darken($success-color, 0.15); + color: darken($success-color, 0.15) !important; + + &:hover { + border-color: darken($success-color, 0.1); + color: darken($success-color, 0.1) !important; + } + } + } + } + + &.error { + background-color: lighten($error-color, 0.4); + color: $error-color; + + .close { + color: $error-color; + + &:hover { + color : darken($error-color, 0.1); + } + } + + .alertAction { + button { + border-color: $error-color; + color: $error-color !important; + + &:hover { + border-color: darken($error-color, 0.1); + color: darken($error-color, 0.1) !important; + } + } + } + } + + .alertAction { + position: absolute; + top: 10px; + right: 20px; + z-index: 3; + + button { + border-color: $info-color; + color: $info-color !important; + + &:hover { + border-color: lighten($info-color, 0.02); + color: lighten($info-color, 0.02) !important; + } + } + + & + .alertBody { + padding-right: 0.4; + min-height: 12px; + } + } + + .alertDetailed { + background-color: #fff; + padding: 20px; + margin-top: 20px; + color: $darker-gray; + margin-bottom: 10px; + position: relative; + overflow: hidden; + + h4 { + margin-bottom: 1.33em; + } + + .alertDetailedAction { + position: absolute; + right: 20px; + top: 15px; + } + + a { + text-decoration: none; + color: $info-color; + } + } +} + +@media only screen and (max-width : 480px) { + .alertMsg { + .alertAction { + bottom: 15px; + left: 46px; + right: auto; + top: auto; + + & + .alertBody { + padding-right: 0px; + padding-bottom: 50px; + } + } + } +} diff --git a/src/shared/form-styles.css b/src/shared/form-styles.css new file mode 100644 index 0000000..f034d0a --- /dev/null +++ b/src/shared/form-styles.css @@ -0,0 +1,94 @@ +.isRequired { + position: relative; + display: inline-block; + + .requiredInput { + position: absolute; + top: 11px; + left: 2px; + color: $error-color; + font-size: 15px; + } + + input { + padding-left: 15px; + } +} + +.isError { + input, + textarea, + select, + .selectBox { + border-color: $error-color; + color: $error-color; + background-color: lighten($error-color, 0.4); + } + + .inputMessage { + color: $error-color; + } +} + +.isValid { + input, + textarea, + select, + .selectBox { + border-color: $success-color; + color: darken($success-color, 0.07); + background-color: lighten($success-color, 0.4); + } + + .inputMessage { + color: $success-color; + } +} + +.isClearable { + position: relative; + display: inline-block; + + input { + padding-right: 30px; + } + + .clearInput { + position: absolute; + right: 0px; + top: 0px; + cursor: pointer; + padding: 10px; + + &:hover { + color: $darker-gray; + } + } +} + +.isDisabled { + input, + .selectBox { + background-color: $lighter-gray; + color: $medium-gray; + } +} + +.searchInput { + position: relative; + display: inline-block; + + .searchInput { + position: absolute; + top: 5px; + z-index: 1; + left: 10px; + font-size: 20px; + } + + input[type='search'] { + padding-left: 40px; + height: 2.21em; + line-height: 2.21em; + } +} \ No newline at end of file diff --git a/src/text-area/card.js b/src/text-area/card.js new file mode 100644 index 0000000..9566dd1 --- /dev/null +++ b/src/text-area/card.js @@ -0,0 +1,35 @@ +import devboard from 'devboard'; +import React from 'react'; +import TextArea from './index.js'; + +const devcard = devboard.ns('textarea'); + +devcard( + 'TextArea', + ` + Patternity TextArea + `, +
+