Add component button

This commit is contained in:
Stanislav Romanov 2022-03-27 16:04:08 +03:00
parent abd0b7ed95
commit a25f6caa10
3 changed files with 123 additions and 0 deletions

14
app/components/button.hbs Normal file
View file

@ -0,0 +1,14 @@
<button
disabled={{this.disabled}}
type={{this.type}}
class="inline-flex items-center px-3 py-2 cursor-pointer border border-gray-300 rounded-md shadow-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none"
...attributes
{{on "click" this.handleClick}}
>
{{#if this.icon}}
<MdIcon @icon={{this.icon}} class="mx-1"/>
{{/if}}
{{#if this.text}}
<span class="mx-1">{{this.text}}</span>
{{/if}}
</button>

83
app/components/button.js Normal file
View file

@ -0,0 +1,83 @@
import Component from '@glimmer/component';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';
export default class ButtonComponent extends Component {
@tracked _state = 'default';
get disabled() {
if (this.args.disabled !== undefined) {
return this.args.disabled;
}
return this.isPending;
}
get type() {
return this.args.type ?? 'button';
}
get icon() {
if (this.isPending && this.args.pendingIcon) {
return this.args.pendingIcon;
} else if (this.isFulfilled && this.args.fulfilledIcon) {
return this.args.fulfilledIcon;
} else if (this.isRejected && this.args.rejectedIcon) {
return this.args.rejectedIcon;
} else if (this.isSettled && this.args.settledIcon) {
return this.args.settledIcon;
}
return this.args.icon ?? null;
}
get state() {
return this.args.state ?? this._state;
}
set state(state) {
this._state = state;
}
get isPending() {
return this.state === 'pending';
}
get isFulfilled() {
return this.state === 'fulfilled';
}
get isRejected() {
return this.state === 'rejected';
}
get isSettled() {
return this.isFulfilled || this.isRejected;
}
get text() {
return this.args[`${this.state}Text`] || this.args.text;
}
@action
async handleClick() {
if (typeof this.args.onClick !== 'function') {
return;
}
this.state = 'pending';
try {
await this.args.onClick();
if (!this.isDestroyed) {
this.state = 'fulfilled';
}
} catch (error) {
if (!this.isDestroyed) {
this.state = 'rejected';
}
throw error;
}
}
}

View file

@ -0,0 +1,26 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
module('Integration | Component | button', function (hooks) {
setupRenderingTest(hooks);
test('it renders', async function (assert) {
// Set any properties with this.set('myProperty', 'value');
// Handle any actions with this.set('myAction', function(val) { ... });
await render(hbs`<Button />`);
assert.dom(this.element).hasText('');
// Template block usage:
await render(hbs`
<Button>
template block text
</Button>
`);
assert.dom(this.element).hasText('template block text');
});
});