Commit 35c73197 authored by Randall Leeds's avatar Randall Leeds

Merge pull request #1359 from hypothesis/button-indicator

Add directive for providing saving updates to buttons 
parents 20a89fea 755cdd3d
# Augments a button to provide loading/status flags for asynchronous actions.
#
# Requires that the attribute provide a "target" form name. It will then listen
# to "formState" events on the scope. These events are expected to provide a
# the form name and a status.
#
# Example
#
# <button status-button="test-form">Submit</button>
statusButton = ->
STATE_ATTRIBUTE = 'status-button-state'
STATE_LOADING = 'loading'
STATE_SUCCESS = 'success'
template = '''
<span class="btn-with-message">
<span class="btn-message btn-message-loading">
<span class="btn-icon spinner"><span><span></span></span></span>
</span>
<span class="btn-message btn-message-success">
<span class="btn-message-text">Saved!</span> <i class="btn-message-icon icon-checkmark2"></i>
</span>
</span>
'''
link: (scope, placeholder, attr, ctrl, transclude) ->
targetForm = attr.statusButton
unless targetForm
throw new Error('status-button attribute should provide a form name')
elem = angular.element(template)
placeholder.after(elem)
transclude(scope, (clone) -> elem.append(clone))
scope.$on 'formState', (event, formName, formState) ->
return unless formName == targetForm
unless formState in [STATE_LOADING, STATE_SUCCESS]
formState = ''
elem.attr(STATE_ATTRIBUTE, formState)
transclude: 'element'
angular.module('h.directives').directive('statusButton', statusButton)
......@@ -190,12 +190,12 @@
@include pie-clearfix;
float: right;
* {
> * {
float: left;
margin-left: 10px;
}
*:first-child {
> *:first-child {
margin-left: 0;
}
}
......@@ -325,33 +325,33 @@
}
// Handles state transitions from "default" -> "loading" -> "success"
[data-btn-message-state] .btn-message {
[status-button-state] .btn-message {
top: -999em;
left: -999em;
right: auto;
}
[data-btn-message-state=success] .btn-message-success,
[data-btn-message-state=loading] .btn-message-loading {
[status-button-state=success] .btn-message-success,
[status-button-state=loading] .btn-message-loading {
top: 50%;
left: auto;
right: 100%;
}
[data-btn-message-state] .btn-message-text {
[status-button-state] .btn-message-text {
@include transition(opacity 0.2s 0.6s ease-in);
opacity: 0;
}
[data-btn-message-state=success] .btn-message-success .btn-message-text {
[status-button-state=success] .btn-message-success .btn-message-text {
opacity: 1;
}
[data-btn-message-state] .btn-message-success .btn-message-icon {
[status-button-state] .btn-message-success .btn-message-icon {
@include transform(scale(0));
}
[data-btn-message-state=success] .btn-message-success .btn-message-icon {
[status-button-state=success] .btn-message-success .btn-message-icon {
@include transition(transform 0.15s 0 cubic-bezier(0, 1.8, 1, 1.8));
@include transform(scale(1));
}
......
assert = chai.assert
describe 'h.directives.statusButton', ->
$scope = null
$compile = null
$element = null
beforeEach module('h.directives')
beforeEach inject (_$compile_, _$rootScope_) ->
$compile = _$compile_
$scope = _$rootScope_.$new()
beforeEach ->
template = '''
<button status-button="test">Test Button</button>
'''
$element = $compile(angular.element(template))($scope).next()
it 'wraps the button with status labels', ->
assert.include($element.prop('className'), 'btn-with-message')
assert.equal($element.find('.btn-message-loading').length, 1)
assert.equal($element.find('.btn-message-success').length, 1)
it 'sets the status-button-state attribute when a loading event is triggered', ->
$scope.$emit('formState', 'test', 'loading')
assert.equal($element.attr('status-button-state'), 'loading')
it 'sets the status-button-state attribute when a success event is triggered', ->
$scope.$emit('formState', 'test', 'success')
assert.equal($element.attr('status-button-state'), 'success')
it 'unsets the status-button-state attribute when another event is triggered', ->
$scope.$emit('formState', 'test', 'reset')
assert.equal($element.attr('status-button-state'), '')
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment