UX: Add consistent classes to buttons

This commit is contained in:
Robin Ward 2017-08-01 15:33:31 -04:00
parent 71ad3a48c2
commit 75d10a4098
6 changed files with 108 additions and 11 deletions

View File

@ -5,9 +5,20 @@ export default Ember.Component.extend({
layoutName: 'components/d-button',
tagName: 'button',
classNameBindings: [':btn', 'noText'],
classNameBindings: [':btn', 'noText', 'btnType'],
attributeBindings: ['disabled', 'translatedTitle:title'],
btnIcon: Ember.computed.notEmpty('icon'),
@computed('icon', 'translatedLabel')
btnType(icon, translatedLabel) {
if (icon) {
return translatedLabel ? "btn-icon-text" : "btn-icon";
} else if (translatedLabel) {
return "btn-text";
}
},
noText: Ember.computed.empty('translatedLabel'),
@computed("title")

View File

@ -1,15 +1,26 @@
import { createWidget } from 'discourse/widgets/widget';
import { iconNode } from 'discourse-common/lib/icon-library';
import { h } from 'virtual-dom';
const ButtonClass = {
tagName: 'button.widget-button',
tagName: 'button.widget-button.btn',
buildClasses(attrs) {
const className = this.attrs.className || '';
let className = this.attrs.className || '';
if (!attrs.label && !attrs.contents) {
return className + ' no-text';
let hasText = attrs.label || attrs.contents;
if (!hasText) {
className += ' no-text';
}
if (attrs.icon) {
className += ' btn-icon';
if (hasText) {
className += '-text';
}
} else if (hasText) {
className += 'btn-text';
}
return className;
@ -39,7 +50,9 @@ const ButtonClass = {
const contents = [];
const left = !attrs.iconRight;
if (attrs.icon && left) { contents.push(iconNode(attrs.icon, { class: attrs.iconClass })); }
if (attrs.label) { contents.push(I18n.t(attrs.label, attrs.labelOptions)); }
if (attrs.label) {
contents.push(h('span.d-button-label', I18n.t(attrs.label, attrs.labelOptions)));
}
if (attrs.contents) { contents.push(attrs.contents); }
if (attrs.icon && !left) { contents.push(iconNode(attrs.icon, { class: attrs.iconClass })); }

View File

@ -32,7 +32,7 @@ createWidget('topic-admin-menu-button', {
// We don't show the button when expanded on the right side
if (!(attrs.rightSide && state.expanded)) {
result.push(this.attach('button', {
className: 'btn toggle-admin-menu' + (attrs.fixed ? " show-topic-admin" : ""),
className: 'toggle-admin-menu' + (attrs.fixed ? " show-topic-admin" : ""),
title: 'topic_admin_menu',
icon: 'wrench',
action: 'showAdminMenu',

View File

@ -15,7 +15,7 @@ function clamp(p, min=0.0, max=1.0) {
function attachBackButton(widget) {
return widget.attach('button', {
className: 'btn btn-primary btn-small back-button',
className: 'btn-primary btn-small back-button',
label: 'topic.timeline.back',
title: 'topic.timeline.back_description',
action: 'goBack'
@ -371,7 +371,7 @@ export default createWidget('topic-timeline', {
if (currentUser && !attrs.fullScreen) {
if (attrs.topic.get('details.can_create_post')) {
controls.push(this.attach('button', {
className: 'btn create',
className: 'create',
icon: 'reply',
title: 'topic.reply.help',
action: 'replyToPost'
@ -382,7 +382,7 @@ export default createWidget('topic-timeline', {
if (attrs.fullScreen) {
controls.push(this.attach('button', {
className: 'btn jump-to-post',
className: 'jump-to-post',
title: 'topic.progress.jump_prompt_long',
label: 'topic.progress.jump_prompt',
action: 'jumpToPostPrompt'

View File

@ -0,0 +1,30 @@
import componentTest from 'helpers/component-test';
moduleForComponent('d-button', {integration: true});
componentTest('icon only button', {
template: '{{d-button icon="plus"}}',
test(assert) {
assert.ok(this.$('button.btn.btn-icon.no-text').length, 'it has all the classes');
assert.ok(this.$('button .d-icon.d-icon-plus').length, 'it has the icon');
}
});
componentTest('icon and text button', {
template: '{{d-button icon="plus" label="topic.create"}}',
test(assert) {
assert.ok(this.$('button.btn.btn-icon-text').length, 'it has all the classes');
assert.ok(this.$('button .d-icon.d-icon-plus').length, 'it has the icon');
assert.ok(this.$('button span.d-button-label').length, 'it has the label');
}
});
componentTest('text only button', {
template: '{{d-button label="topic.create"}}',
test(assert) {
assert.ok(this.$('button.btn.btn-text').length, 'it has all the classes');
assert.ok(this.$('button span.d-button-label').length, 'it has the label');
}
});

View File

@ -0,0 +1,43 @@
import { moduleForWidget, widgetTest } from 'helpers/widget-test';
moduleForWidget('button');
widgetTest('icon only button', {
template: '{{mount-widget widget="button" args=args}}',
beforeEach() {
this.set('args', { icon: 'smile-o' });
},
test(assert) {
assert.ok(this.$('button.btn.btn-icon.no-text').length, 'it has all the classes');
assert.ok(this.$('button .d-icon.d-icon-smile-o').length, 'it has the icon');
}
});
widgetTest('icon and text button', {
template: '{{mount-widget widget="button" args=args}}',
beforeEach() {
this.set('args', { icon: 'plus', label: 'topic.create' });
},
test(assert) {
assert.ok(this.$('button.btn.btn-icon-text').length, 'it has all the classes');
assert.ok(this.$('button .d-icon.d-icon-plus').length, 'it has the icon');
assert.ok(this.$('button span.d-button-label').length, 'it has the label');
}
});
widgetTest('text only button', {
template: '{{mount-widget widget="button" args=args}}',
beforeEach() {
this.set('args', { label: 'topic.create' });
},
test(assert) {
assert.ok(this.$('button.btn.btn-text').length, 'it has all the classes');
assert.ok(this.$('button span.d-button-label').length, 'it has the label');
}
});