Add component button
This commit is contained in:
parent
abd0b7ed95
commit
a25f6caa10
3 changed files with 123 additions and 0 deletions
14
app/components/button.hbs
Normal file
14
app/components/button.hbs
Normal 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
83
app/components/button.js
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
26
tests/integration/components/button-test.js
Normal file
26
tests/integration/components/button-test.js
Normal 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');
|
||||
});
|
||||
});
|
||||
Loading…
Reference in a new issue