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
+
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';