diff --git a/js/lib/buttons.js b/js/lib/buttons.js index 7b384ad4..c8ae79ac 100644 --- a/js/lib/buttons.js +++ b/js/lib/buttons.js @@ -1,27 +1,53 @@ +/** + * + */ + +'use strict'; + import React from 'react'; import _Button from 'react-bootstrap/lib/Button'; - -export const Button = React.createClass({ - - render: function render() { - return ( - <_Button> - {this.props.children} - - ) - } - -}); +import classnames from 'classnames'; -export const SecondaryButton = React.createClass({ +const DISABLED_STATUSES = ['loading', 'disabled']; - render: function render() { - return ( - <_Button className='btn-secondary'> - {this.props.children} - - ) - } -}); +function ButtonFactory(btnClassName) { + + let GenericButton = React.createClass({ + propTypes: { + status: React.PropTypes.oneOf(['loading', 'disabled']), + children: React.PropTypes.oneOfType([React.PropTypes.arrayOf(React.PropTypes.element), + React.PropTypes.element]) + }, + + getInitialState: function() { + return { + status: this.props.status + }; + }, + + render: function render() { + let disabled = DISABLED_STATUSES.indexOf(this.state.status) !== -1; + let className = ''; + + if (this.state.status !== 'disabled') { + className = this.state.status; + } + + return ( + <_Button bsStyle={btnClassName} className={classnames(className)} disabled={disabled}> + {this.props.children} + + ); + } + + }); + + return GenericButton; +} + + +export const Button = ButtonFactory('btn-primary'); +export const SecondaryButton = ButtonFactory('btn-secondary'); +export const DangerButton = ButtonFactory('btn-danger'); diff --git a/js/styleguide/components/buttons.js b/js/styleguide/components/buttons.js index e891bdfa..b6b3773d 100644 --- a/js/styleguide/components/buttons.js +++ b/js/styleguide/components/buttons.js @@ -1,7 +1,7 @@ 'use strict'; import React from 'react'; -import { Button, SecondaryButton } from '../../lib/buttons'; +import { Button, SecondaryButton, DangerButton } from '../../lib/buttons'; import Panel from 'react-bootstrap/lib/Panel'; @@ -11,23 +11,54 @@ let Buttons = React.createClass({ return (

Button

-

import { Button } from './js/lib/buttons';

+

import { Button, SecondaryButton, DangerButton } from './js/lib/buttons';

+

In the wild

-

This is a paragraph with - - that should be displayed inline -

+

This is a paragraph with that should be displayed inline

+

Different states

+
+ + + +
+ +

In a form

This is a form with a large submit button

- +
+ +
+
+

+
+ +

In a form with multiple buttons

+
+

This is a form with many buttons +

+
+ + + + + + Cancel + + + + Delete + +

diff --git a/sass/ascribe_custom_styles.scss b/sass/ascribe_custom_styles.scss index 44f6d8cb..59f165fd 100644 --- a/sass/ascribe_custom_styles.scss +++ b/sass/ascribe_custom_styles.scss @@ -1,52 +1,30 @@ +$ascribe-brand-color: #02b6a3; + body { - background-color: $ascribe-color-background + background-color: #fdfdfd; } -.btn-default { +.btn-primary { color: white; background-color: $ascribe-brand-color; border-color: $ascribe-brand-color; - &:hover, &:focus { - background-color: darken($ascribe-brand-color, 10%); - border-color: darken($ascribe-brand-color, 10%); - } } -.btn-default:active:hover, -.btn-default:active:focus, -.btn-default:active.focus, -.btn-default.active:hover, -.btn-default.active:focus, -.btn-default.active.focus, -.open > .btn-default.dropdown-toggle:hover, -.open > .btn-default.dropdown-toggle:focus, -.open > .btn-default.dropdown-toggle.focus { +.btn-primary:active:hover, +.btn-primary:active:focus { background-color: darken($ascribe-brand-color, 20%); border-color: darken($ascribe-brand-color, 20%); } -.btn-default.disabled, -.btn-default.disabled:hover, -.btn-default.disabled:focus, -.btn-default.disabled.focus, -.btn-default.disabled:active, -.btn-default.disabled.active, -.btn-default[disabled], -.btn-default[disabled]:hover, -.btn-default[disabled]:focus, -.btn-default[disabled].focus, -.btn-default[disabled]:active, -.btn-default[disabled].active, -fieldset[disabled] .btn-default, -fieldset[disabled] .btn-default:hover, -fieldset[disabled] .btn-default:focus, -fieldset[disabled] .btn-default.focus, -fieldset[disabled] .btn-default:active, -fieldset[disabled] .btn-default.active { +.btn-primary[disabled], +.btn-primary[disabled]:hover, +.btn-primary[disabled]:focus, +.btn-primary[disabled]:active { background-color: lighten($ascribe-brand-color, 10%); border-color: lighten($ascribe-brand-color, 10%); } +/* .ascribe-piece-list-toolbar-filter-widget { button { color: $ascribe-brand-color; @@ -96,3 +74,4 @@ fieldset[disabled] .btn-default.active { background-color: $ascribe-brand-color !important; border-color: $ascribe-brand-color !important; } +*/ diff --git a/sass/ascribe_login.scss b/sass/ascribe_login.scss index 9060fee5..ac5ae67c 100644 --- a/sass/ascribe_login.scss +++ b/sass/ascribe_login.scss @@ -49,7 +49,6 @@ $break-small: 764px; } } - .ascribe-login-wrapper { margin: 0 auto; max-width: 600px; diff --git a/sass/lib/buttons.scss b/sass/lib/buttons.scss index e69de29b..e3eb63e3 100644 --- a/sass/lib/buttons.scss +++ b/sass/lib/buttons.scss @@ -0,0 +1,56 @@ +/** + * Styles for the buttons + * + * The style of a button is context-dependent. This means that if the button + * is placed in a form, for example, and is the only child, it will be displayed + * with 100% width. If the button is together with other buttons, it will + * be displayed with auto width and pushed on the right. + * + */ + +@import '../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/mixins/_buttons'; + + +// Buttons that are one next to the other will have 1px margin on the left +.btn + .btn { + margin-left: 1px; +} + +// Buttons in the footer of a form are aligned on the right +form .footer { + text-align: right; + + // A single button in the footer of a form will take all the space available + > .btn:only-child { + width: 100%; + } +} + +.btn.loading { + background-image: url('//s3-us-west-2.amazonaws.com/ascribe0/media/thumbnails/ascribe_animated_medium.gif'); + background-position: center center; + background-repeat: no-repeat; + background-size: contain; + + // force transparency so we don't need to go crazy with all the states of the button. + color: rgba(0, 0, 0, 0) !important; +} + +/** + * Colors + */ + +.btn-primary { + @include button-variant($btn-primary-color, $btn-primary-bg, $btn-primary-border); +} + +.btn-secondary { + @include button-variant($btn-secondary-color, $btn-secondary-bg, $btn-secondary-border); +} + +.btn-danger { + @include button-variant($btn-danger-color, $btn-danger-bg, $btn-danger-border); + border-color: transparent; + background-color: transparent; + color: $btn-secondary-color; +} diff --git a/sass/lib/defaults.scss b/sass/lib/defaults.scss new file mode 100644 index 00000000..5420d72f --- /dev/null +++ b/sass/lib/defaults.scss @@ -0,0 +1,11 @@ +$btn-primary-bg: #02b6a3; +$btn-primary-color: #fff; +$btn-primary-border: $btn-primary-bg; + +$btn-secondary-bg: #ddd; +$btn-secondary-color: #666; +$btn-secondary-border: $btn-secondary-bg; + +$btn-danger-bg: #ec4742; +$btn-danger-color: #fff; +$btn-danger-border: $btn-danger-bg; diff --git a/sass/lib/index.scss b/sass/lib/index.scss new file mode 100644 index 00000000..711d754c --- /dev/null +++ b/sass/lib/index.scss @@ -0,0 +1,2 @@ +@import 'defaults'; +@import 'buttons'; diff --git a/sass/main.scss b/sass/main.scss index a267c576..721f6d0d 100644 --- a/sass/main.scss +++ b/sass/main.scss @@ -8,10 +8,11 @@ $BASE_URL: '<%= BASE_URL %>'; @import '../node_modules/bootstrap-sass/assets/stylesheets/bootstrap'; @import '../node_modules/react-star-rating/dist/css/react-star-rating.min'; @import '../node_modules/react-datepicker/dist/react-datepicker'; +@import 'lib/index'; @import 'glyphicons-social'; @import 'ascribe_theme'; -@import './ascribe-fonts/style'; -@import './ascribe-fonts/ascribe-fonts'; +@import 'ascribe-fonts/style'; +@import 'ascribe-fonts/ascribe-fonts'; @import 'ascribe_login'; @import 'ascribe_table'; @import 'ascribe_accordion_list';