mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-22 19:32:54 +03:00
Fixed signin and signup button failure state hover colors
ref https://linear.app/tryghost/issue/ENG-1653 - we were always setting a `style="background-color: #123456"` attribute on the buttons but that didn't allow for different button states such as the red failure state to correctly override meaning there was some odd behaviour when hovering - removed the fixed `style` attribute and adjusted `<GhTaskButton>` - added `@useAccentColor` prop - when `@useAccentColor` is true, add the necessary `style` attribute except when showing the failure state
This commit is contained in:
parent
2e0293c99f
commit
2fb88e65ca
@ -3,7 +3,7 @@ module.exports = {
|
||||
|
||||
rules: {
|
||||
'no-forbidden-elements': ['meta', 'html', 'script'],
|
||||
'no-implicit-this': {allow: ['noop', 'now', 'site-icon-style', 'accent-color-background']},
|
||||
'no-implicit-this': {allow: ['noop', 'now', 'site-icon-style']},
|
||||
'no-inline-styles': false,
|
||||
'no-duplicate-landmark-elements': false,
|
||||
'no-pointer-down-event-binding': false,
|
||||
|
@ -27,7 +27,7 @@
|
||||
@showSuccess={{false}}
|
||||
@task={{this.reauthenticateTask}}
|
||||
@class="login gh-btn gh-btn-login gh-btn-block gh-btn-icon"
|
||||
style={{accent-color-background}}
|
||||
@useAccentColor={{true}}
|
||||
/>
|
||||
|
||||
{{#if this.authenticationError}}
|
||||
|
@ -1,6 +1,8 @@
|
||||
import Component from '@ember/component';
|
||||
import config from 'ghost-admin/config/environment';
|
||||
import {action, computed} from '@ember/object';
|
||||
import {htmlSafe} from '@ember/template';
|
||||
import {inject} from 'ghost-admin/decorators/inject';
|
||||
import {isBlank} from '@ember/utils';
|
||||
import {reads} from '@ember/object/computed';
|
||||
import {task, timeout} from 'ember-concurrency';
|
||||
@ -25,7 +27,7 @@ const GhTaskButton = Component.extend({
|
||||
'isSuccessClass',
|
||||
'isFailureClass'
|
||||
],
|
||||
attributeBindings: ['disabled', 'form', 'type', 'tabindex', 'data-test-button'],
|
||||
attributeBindings: ['disabled', 'form', 'type', 'tabindex', 'data-test-button', 'style'],
|
||||
|
||||
task: null,
|
||||
taskArgs: undefined,
|
||||
@ -49,6 +51,8 @@ const GhTaskButton = Component.extend({
|
||||
// Allowed actions
|
||||
action: () => {},
|
||||
|
||||
config: inject(),
|
||||
|
||||
runningText: reads('buttonText'),
|
||||
|
||||
// hasRun is needed so that a newly rendered button does not show the last
|
||||
@ -113,6 +117,13 @@ const GhTaskButton = Component.extend({
|
||||
return !this.isRunning && !this.isSuccess && !this.isFailure;
|
||||
}),
|
||||
|
||||
style: computed('useAccentColor', 'isFailure', function () {
|
||||
if (this.useAccentColor && !this.isFailure) {
|
||||
return htmlSafe(`background-color: ${this.config.accent_color}`);
|
||||
}
|
||||
return null;
|
||||
}),
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this._initialPerformCount = this.get('task.performCount');
|
||||
|
@ -1,12 +0,0 @@
|
||||
import Helper from '@ember/component/helper';
|
||||
import {htmlSafe} from '@ember/template';
|
||||
import {inject} from 'ghost-admin/decorators/inject';
|
||||
|
||||
export default class AccentColorBackgroundHelper extends Helper {
|
||||
@inject config;
|
||||
|
||||
compute() {
|
||||
const color = this.config.accent_color;
|
||||
return htmlSafe(`background: ${color};`);
|
||||
}
|
||||
}
|
@ -69,7 +69,7 @@
|
||||
@showSuccess={{false}}
|
||||
@class="login gh-btn gh-btn-login gh-btn-block gh-btn-icon"
|
||||
@type="submit"
|
||||
style={{accent-color-background}}
|
||||
@useAccentColor={{true}}
|
||||
data-test-button="sign-in" />
|
||||
</form>
|
||||
|
||||
|
@ -75,10 +75,10 @@
|
||||
@task={{this.signupTask}}
|
||||
@defaultClick={{true}}
|
||||
@showSuccess={{false}}
|
||||
@useAccentColor={{true}}
|
||||
type="submit"
|
||||
form="signup"
|
||||
class="gh-btn gh-btn-signup gh-btn-block gh-btn-icon"
|
||||
style={{accent-color-background}}
|
||||
data-test-button="signup"
|
||||
/>
|
||||
</form>
|
||||
|
@ -3,13 +3,17 @@ import {click, find, render, settled, waitFor} from '@ember/test-helpers';
|
||||
import {defineProperty} from '@ember/object';
|
||||
import {describe, it} from 'mocha';
|
||||
import {expect} from 'chai';
|
||||
import {run} from '@ember/runloop';
|
||||
import {setupRenderingTest} from 'ember-mocha';
|
||||
import {task, timeout} from 'ember-concurrency';
|
||||
|
||||
describe('Integration: Component: gh-task-button', function () {
|
||||
setupRenderingTest();
|
||||
|
||||
beforeEach(function () {
|
||||
const config = this.owner.lookup('config:main');
|
||||
config.accent_color = '#123456';
|
||||
});
|
||||
|
||||
it('renders', async function () {
|
||||
// sets button text using positional param
|
||||
await render(hbs`<GhTaskButton @buttonText="Test" />`);
|
||||
@ -47,7 +51,6 @@ describe('Integration: Component: gh-task-button', function () {
|
||||
this.myTask.perform();
|
||||
|
||||
await waitFor('button svg', {timeout: 50});
|
||||
await settled();
|
||||
});
|
||||
|
||||
it('shows running text when passed whilst running', async function () {
|
||||
@ -61,8 +64,6 @@ describe('Integration: Component: gh-task-button', function () {
|
||||
|
||||
await waitFor('button svg', {timeout: 50});
|
||||
expect(find('button')).to.contain.text('Running');
|
||||
|
||||
await settled();
|
||||
});
|
||||
|
||||
it('appears disabled whilst running', async function () {
|
||||
@ -83,7 +84,7 @@ describe('Integration: Component: gh-task-button', function () {
|
||||
|
||||
it('shows success on success', async function () {
|
||||
defineProperty(this, 'myTask', task(function* () {
|
||||
yield timeout(50);
|
||||
yield timeout(1);
|
||||
return true;
|
||||
}));
|
||||
|
||||
@ -97,7 +98,7 @@ describe('Integration: Component: gh-task-button', function () {
|
||||
|
||||
it('assigns specified success class on success', async function () {
|
||||
defineProperty(this, 'myTask', task(function* () {
|
||||
yield timeout(50);
|
||||
yield timeout(1);
|
||||
return true;
|
||||
}));
|
||||
|
||||
@ -113,7 +114,7 @@ describe('Integration: Component: gh-task-button', function () {
|
||||
it('shows failure when task errors', async function () {
|
||||
defineProperty(this, 'myTask', task(function* () {
|
||||
try {
|
||||
yield timeout(50);
|
||||
yield timeout(1);
|
||||
throw new ReferenceError('test error');
|
||||
} catch (error) {
|
||||
// noop, prevent mocha triggering unhandled error assert
|
||||
@ -126,13 +127,11 @@ describe('Integration: Component: gh-task-button', function () {
|
||||
await waitFor('button.is-failed');
|
||||
|
||||
expect(find('button')).to.contain.text('Retry');
|
||||
|
||||
await settled();
|
||||
});
|
||||
|
||||
it('shows failure on falsy response', async function () {
|
||||
defineProperty(this, 'myTask', task(function* () {
|
||||
yield timeout(50);
|
||||
yield timeout(1);
|
||||
return false;
|
||||
}));
|
||||
|
||||
@ -142,13 +141,11 @@ describe('Integration: Component: gh-task-button', function () {
|
||||
await waitFor('button.gh-btn-red', {timeout: 50});
|
||||
|
||||
expect(find('button')).to.contain.text('Retry');
|
||||
|
||||
await settled();
|
||||
});
|
||||
|
||||
it('shows idle on canceled response', async function () {
|
||||
defineProperty(this, 'myTask', task(function* () {
|
||||
yield timeout(50);
|
||||
yield timeout(1);
|
||||
return 'canceled';
|
||||
}));
|
||||
|
||||
@ -156,13 +153,11 @@ describe('Integration: Component: gh-task-button', function () {
|
||||
|
||||
this.myTask.perform();
|
||||
await waitFor('[data-test-task-button-state="idle"]', {timeout: 50});
|
||||
|
||||
await settled();
|
||||
});
|
||||
|
||||
it('assigns specified failure class on failure', async function () {
|
||||
defineProperty(this, 'myTask', task(function* () {
|
||||
yield timeout(50);
|
||||
yield timeout(1);
|
||||
return false;
|
||||
}));
|
||||
|
||||
@ -174,15 +169,13 @@ describe('Integration: Component: gh-task-button', function () {
|
||||
|
||||
expect(find('button')).to.not.have.class('gh-btn-red');
|
||||
expect(find('button')).to.contain.text('Retry');
|
||||
|
||||
await settled();
|
||||
});
|
||||
|
||||
it('performs task on click', async function () {
|
||||
let taskCount = 0;
|
||||
|
||||
defineProperty(this, 'myTask', task(function* () {
|
||||
yield timeout(50);
|
||||
yield timeout(1);
|
||||
taskCount = taskCount + 1;
|
||||
}));
|
||||
|
||||
@ -192,33 +185,37 @@ describe('Integration: Component: gh-task-button', function () {
|
||||
expect(taskCount, 'taskCount').to.equal(1);
|
||||
});
|
||||
|
||||
it.skip('keeps button size when showing spinner', async function () {
|
||||
it('@useAccentColor=true adds style attr', async function () {
|
||||
defineProperty(this, 'myTask', task(function* () {
|
||||
yield timeout(50);
|
||||
yield timeout(1);
|
||||
}));
|
||||
|
||||
await render(hbs`<GhTaskButton @task={{myTask}} />`);
|
||||
let width = find('button').clientWidth;
|
||||
let height = find('button').clientHeight;
|
||||
expect(find('button')).to.not.have.attr('style');
|
||||
await render(hbs`<GhTaskButton @task={{myTask}} @useAccentColor={{true}} />`);
|
||||
|
||||
this.myTask.perform();
|
||||
expect(find('button')).to.have.attr('style', 'background-color: #123456');
|
||||
});
|
||||
|
||||
run.later(this, function () {
|
||||
// we can't test exact width/height because Chrome/Firefox use different rounding methods
|
||||
// expect(find('button')).to.have.attr('style', `width: ${width}px; height: ${height}px;`);
|
||||
it('@useAccentColor=true removes style attr when in failure state', async function () {
|
||||
defineProperty(this, 'myTask', task(function* () {
|
||||
yield timeout(1);
|
||||
return false;
|
||||
}));
|
||||
|
||||
let [widthInt] = width.toString().split('.');
|
||||
let [heightInt] = height.toString().split('.');
|
||||
await render(hbs`<GhTaskButton @task={{myTask}} @useAccentColor={{false}} />`);
|
||||
await click('button');
|
||||
await waitFor('button.gh-btn-red', {timeout: 50});
|
||||
|
||||
expect(find('button')).to.have.attr('style', `width: ${widthInt}`);
|
||||
expect(find('button')).to.have.attr('style', `height: ${heightInt}`);
|
||||
}, 20);
|
||||
expect(find('button')).to.contain.text('Retry');
|
||||
expect(find('button')).not.to.have.attr('style');
|
||||
});
|
||||
|
||||
run.later(this, function () {
|
||||
expect(find('button').getAttribute('style')).to.be.empty;
|
||||
}, 100);
|
||||
it('@useAccentColor=false does not add style attr', async function () {
|
||||
defineProperty(this, 'myTask', task(function* () {
|
||||
yield timeout(1);
|
||||
}));
|
||||
|
||||
await settled();
|
||||
await render(hbs`<GhTaskButton @task={{myTask}} @useAccentColor={{false}} />`);
|
||||
|
||||
expect(find('button')).not.to.have.attr('style');
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user