diff --git a/client/components/notice/index.jsx b/client/components/notice/index.jsx
index 21af4fd..caeb52a 100644
--- a/client/components/notice/index.jsx
+++ b/client/components/notice/index.jsx
@@ -1,51 +1,61 @@
/**
* External dependencies
*/
-var React = require( 'react/addons' ),
- joinClasses = require( 'react/lib/joinClasses' ),
- noop = require( 'lodash/noop' );
+import React, { PropTypes } from 'react';
+import classnames from 'classnames';
+import noop from 'lodash/noop';
+import ScreenReaderText from '../screen-reader-text';
+import i18n from 'lib/mixins/i18n';
+
+require( './style.scss' );
/**
* Internal dependencies
*/
-var Button = require( '../button' ),
- Gridicon = require( '../gridicon' ),
- ScreenReaderText = require( '../screen-reader-text' );
-
-require( './style.scss' );
+import Gridicon from '../gridicon';
-module.exports = React.createClass( {
+export default React.createClass( {
+ mixins: [ i18n.mixin ],
displayName: 'SimpleNotice',
+ dismissTimeout: null,
- getDefaultProps: function() {
+ getDefaultProps() {
return {
- status: 'is-info',
+ duration: 0,
+ status: null,
showDismiss: true,
className: '',
- onClick: noop
+ onDismissClick: noop
};
},
propTypes: {
// we should validate the allowed statuses
- status: React.PropTypes.string,
- showDismiss: React.PropTypes.bool,
+ status: PropTypes.string,
+ showDismiss: PropTypes.bool,
+ isCompact: PropTypes.bool,
duration: React.PropTypes.number,
- isCompact: React.PropTypes.bool,
- text: React.PropTypes.oneOfType( [
- React.PropTypes.string,
- React.PropTypes.object
+ text: PropTypes.oneOfType( [
+ PropTypes.oneOfType( [ PropTypes.string, PropTypes.node ] ),
+ PropTypes.arrayOf( PropTypes.oneOfType( [ PropTypes.string, PropTypes.node ] ) )
] ),
- className: React.PropTypes.string
+ icon: PropTypes.string,
+ className: PropTypes.string
},
- componentDidMount: function() {
+ componentDidMount() {
if ( this.props.duration > 0 ) {
- setTimeout( this.props.onClick, this.props.duration );
+ this.dismissTimeout = setTimeout( this.props.onDismissClick, this.props.duration );
+ }
+ },
+
+ componentWillUnmount() {
+ if ( this.dismissTimeout ) {
+ clearTimeout( this.dismissTimeout );
}
},
- renderChildren: function() {
+ renderChildren() {
let content;
if ( typeof this.props.children === 'string' ) {
@@ -62,35 +72,159 @@ module.exports = React.createClass( {
return content;
},
- render: function() {
- var noticeClass, dismiss;
+ getIcon() {
+ let icon;
+
+ switch ( this.props.status ) {
+ case 'is-info':
+ icon = 'info';
+ break;
+ case 'is-success':
+ icon = 'checkmark';
+ break;
+ case 'is-error':
+ icon = 'notice';
+ break;
+ case 'is-warning':
+ icon = 'notice';
+ break;
+ default:
+ icon = 'info';
+ break;
+ }
+
+ return icon;
+ },
+
+ render() {
+ let dismiss;
// The class determines the nature of a notice
// and its status.
- noticeClass = joinClasses( 'notice', this.props.status );
+ let noticeClass = classnames( 'notice', this.props.status );
if ( this.props.isCompact ) {
- noticeClass = joinClasses( noticeClass, 'is-compact' );
+ noticeClass = classnames( noticeClass, 'is-compact' );
}
// By default, a dismiss button is rendered to
// allow the user to hide the notice
if ( this.props.showDismiss ) {
- noticeClass = joinClasses( noticeClass, 'is-dismissable' );
+ noticeClass = classnames( noticeClass, 'is-dismissable' );
dismiss = (
-
+
);
}
return (
-
- { this.renderChildren() }
+
+
+
+ { this.renderChildren() }
+
{ dismiss }
);
}
-
} );
+
+
+// /**
+// * External dependencies
+// */
+// var React = require( 'react/addons' ),
+// joinClasses = require( 'react/lib/joinClasses' ),
+// noop = require( 'lodash/noop' );
+
+// /**
+// * Internal dependencies
+// */
+// var Button = require( '../button' ),
+// Gridicon = require( '../gridicon' ),
+// ScreenReaderText = require( '../screen-reader-text' );
+
+// require( './style.scss' );
+
+// module.exports = React.createClass( {
+// displayName: 'SimpleNotice',
+
+// getDefaultProps: function() {
+// return {
+// status: 'is-info',
+// showDismiss: true,
+// className: '',
+// onClick: noop
+// };
+// },
+
+// propTypes: {
+// // we should validate the allowed statuses
+// status: React.PropTypes.string,
+// showDismiss: React.PropTypes.bool,
+// duration: React.PropTypes.number,
+// isCompact: React.PropTypes.bool,
+// text: React.PropTypes.oneOfType( [
+// React.PropTypes.string,
+// React.PropTypes.object
+// ] ),
+// className: React.PropTypes.string
+// },
+
+// componentDidMount: function() {
+// if ( this.props.duration > 0 ) {
+// setTimeout( this.props.onClick, this.props.duration );
+// }
+// },
+
+// renderChildren: function() {
+// let content;
+
+// if ( typeof this.props.children === 'string' ) {
+// return
{ this.props.children };
+// }
+
+// if ( this.props.text ) {
+// content = [ this.props.children ];
+// content.unshift(
{ this.props.text } );
+// } else {
+// content =
{ this.props.children };
+// }
+
+// return content;
+// },
+
+// render: function() {
+// var noticeClass, dismiss;
+
+// // The class determines the nature of a notice
+// // and its status.
+// noticeClass = joinClasses( 'notice', this.props.status );
+
+// if ( this.props.isCompact ) {
+// noticeClass = joinClasses( noticeClass, 'is-compact' );
+// }
+
+// // By default, a dismiss button is rendered to
+// // allow the user to hide the notice
+// if ( this.props.showDismiss ) {
+// noticeClass = joinClasses( noticeClass, 'is-dismissable' );
+// dismiss = (
+//
+// );
+// }
+
+// return (
+//
+// { this.renderChildren() }
+// { dismiss }
+//
+// );
+// }
+
+// } );
diff --git a/client/components/notice/style.scss b/client/components/notice/style.scss
index 7da33fd..74fd403 100644
--- a/client/components/notice/style.scss
+++ b/client/components/notice/style.scss
@@ -3,121 +3,88 @@
@import '../../scss/extends';
.notice {
- flex: 1 100%;
display: flex;
- flex-wrap: wrap;
position: relative;
margin-bottom: 24px;
border-radius: 1px;
- background: $gray-light;
+ background: lighten( $gray, 30 );
box-sizing: border-box;
font-size: 14px;
- line-height: 1.4285;
animation: appear .3s ease-in-out;
- .notice__text {
- flex-grow: 1;
- flex-basis: 100px;
-
- padding: 11px 24px;
- padding-right: 0;
-
- @include breakpoint( ">660px" ) {
- padding: 13px 48px;
- }
- }
-
@include breakpoint( ">660px" ) {
font-size: inherit;
-
- &::before {
- @extend %noticon;
- content: '\f456';
- position: absolute;
- top: 26px;
- left: 20px;
- margin: -12px 0px 0 -8px;
- font-size: 24px;
- line-height: 1;
- }
- }
-
- .notice__dismiss:focus {
- box-shadow: 0 0 4px darken( $gray-light, 10 );
}
// Success!
&.is-success {
background: $alert-green;
-
- .notice__dismiss:focus {
- box-shadow: 0 0 4px darken( $alert-green, 10 );
- }
-
- @include breakpoint( ">660px" ) {
- &:before {
- content: '\f418';
- }
- }
}
// Warning
&.is-warning {
background: $alert-yellow;
-
- .notice__dismiss:focus {
- box-shadow: 0 0 4px darken( $alert-yellow, 10 );
- }
-
- &:before {
- }
}
// Error! OHNO!
&.is-error {
background: $alert-red;
-
- .notice__dismiss:focus {
- box-shadow: 0 0 4px darken( $alert-red, 10 );
- }
-
- &:before {
- }
}
- // Information
+ // General notice
&.is-info {
background: $blue-wordpress;
+ }
+
+ &.is-success,
+ &.is-error,
+ &.is-warning,
+ &.is-info {
+ color: $white;
- .notice__dismiss:focus {
- box-shadow: 0 0 4px darken( $blue-wordpress, 10 );
+ .notice__text a {
+ color: $white;
}
- @include breakpoint( ">660px" ) {
- &:before {
- content: '\f455';
- }
+ .notice__dismiss {
+ color: $white;
}
}
}
-// General styles for html elements
-// rendered inside a notice
-.notice {
+.notice__icon {
+ flex-shrink: 0;
+ padding: 13px 0 13px 16px;
- a,
- button.is-link {
- display: inline;
- margin-left: 8px;
- text-align: left;
- line-height: 1.4285;
- font-weight: 600;
- text-decoration: underline;
+ @include breakpoint( "<660px" ) {
+ display: none;
+ }
+}
+
+.notice__content {
+ display: flex;
+ flex-grow: 1;
+
+ @include breakpoint( "<480px" ) {
+ flex-direction: column;
+ }
+}
+
+.notice__text {
+ font-size: 15px;
+ padding: 11px 24px;
+
+ & > span,
+ & > div {
+ max-width: 680px;
+ }
+
+ @include breakpoint( ">660px" ) {
+ padding: 13px;
+ }
- // @media not all, only screen and (min-resolution: 2dppx), only screen and (-webkit-min-device-pixel-ratio: 2) {
- // background-image: linear-gradient(to bottom, rgba(0,0,0,0) 75%, #fff 75%);
- // background-repeat: repeat-x;
- // }
+ a {
+ text-decoration: underline;
}
ul {
@@ -138,31 +105,6 @@
margin-top: 0;
}
}
-
- &.is-success, // TODO fix this in pre-oss to be less bad
- &.is-error,
- &.is-warning,
- &.is-info {
- color: $white;
-
- span {
- color: inherit;
- }
-
- a,
- button.is-link {
- color: rgba( $white, 0.85 );
-
- &:hover,
- &:focus {
- color: $white;
- }
- }
-
- .notice__dismiss {
- color: $white;
- }
- }
}
.notice__button {
@@ -173,14 +115,11 @@
// "X" for dismissing a notice
.notice__dismiss {
display: flex;
- padding: 9px 16px;
+ flex-shrink: 0;
+ padding: 11px 16px;
cursor: pointer;
color: $gray;
- background: transparent;
- border: none;
- border-radius: 0;
-
@include breakpoint( ">660px" ) {
padding: 13px 16px;
}
@@ -201,51 +140,111 @@
}
}
-// Compact notices
-.notice.is-compact {
- margin-bottom: 8px;
- font-size: 14px;
-
- .notice__text {
- padding: 11px 0px 11px 16px;
- }
-
- &::before {
- display: none;
- }
-
- .notice__dismiss {
- padding: 9px 16px;
- }
-
- a.notice__arrow-link .gridicon {
- width: 18px;
- height: 18px;
- }
-}
-
-// ArrowLink sub-component
// specificity for general `a` elements within notice is too great
-.notice a.notice__arrow-link {
- background: rgba( 0, 0, 0, 0.2 );
- box-sizing: border-box;
- color: $white;
- cursor: pointer;
+a.notice__action {
display: flex;
align-items: center;
+ flex-shrink: 0;
+ box-sizing: border-box;
+ cursor: pointer;
+ font-size: 15px;
font-weight: 400;
- line-height: 1.2;
margin-left: auto; // forces the element to the right;
- padding: 13px 10px 13px 16px;
+ padding: 13px 16px;
text-decoration: none;
white-space: nowrap;
+ .is-success &,
+ .is-error &,
+ .is-warning &,
+ .is-info & {
+ color: $white;
+ }
+
+ .is-success & { background: darken( $alert-green, 15 ); }
+ .is-error & { background: darken( $alert-red, 15 ); }
+ .is-warning & { background: darken( $alert-yellow, 15 ); }
+ .is-info & { background: darken( $blue-wordpress, 15 ); }
+
.gridicon {
margin-left: 8px;
+ opacity: 0.7;
}
&:hover,
&:focus {
background: rgba( 255, 255, 255, 0.2 );
}
+
+ @include breakpoint( "<480px" ) {
+ margin: 0;
+ justify-content: flex-end;
+ }
+}
+
+// Compact notices
+.notice.is-compact {
+ border-radius: 2px;
+ display: inline-flex;
+ flex-wrap: nowrap;
+ min-height: 20px;
+ margin: 0;
+ padding: 0;
+ text-decoration: none;
+ text-transform: none;
+ vertical-align: middle;
+
+ &.is-success,
+ &.is-error,
+ &.is-warning,
+ &.is-info {
+ color: $white;
+ }
+
+ .notice__text {
+ font-size: 12px;
+ padding: 6px 8px;
+ line-height: 1;
+ }
+
+ .notice__icon {
+ align-self: center;
+ flex-shrink: 0;
+ margin: 0 0 0 8px;
+ padding: 0;
+ width: 18px;
+ height: 18px;
+ vertical-align: middle;
+ }
+
+ .notice__dismiss {
+ display: none;
+ }
+
+ a.notice__action {
+ background: transparent;
+ display: inline-block;
+ font-size: 11px;
+ font-weight: 600;
+ align-self: center;
+ margin-left: 16px;
+ padding: 0 8px;
+ text-decoration: underline;
+ text-transform: uppercase;
+
+ &:hover,
+ &:active,
+ &:focus {
+ background: transparent;
+ text-decoration: none;
+ }
+
+ .gridicon {
+ margin-left: 8px;
+ width: 14px;
+ height: 14px;
+ vertical-align: sub;
+ opacity: 1;
+ }
+ }
}
diff --git a/package.json b/package.json
index 9352029..ea5bde2 100644
--- a/package.json
+++ b/package.json
@@ -8,6 +8,7 @@
"babel-core": "5.8.12",
"babel-eslint": "^4.1.1",
"babel-loader": "^5.3.2",
+ "babel-runtime": "^5.8.12",
"codemirror": "^5.6.0",
"css-loader": "^0.16.0",
"eslint": "^1.9.0",