2022-03-27 13:04:08 +00:00
|
|
|
import Component from '@glimmer/component';
|
2022-09-07 14:03:33 +00:00
|
|
|
import { action, get } from '@ember/object';
|
2022-03-27 13:04:08 +00:00
|
|
|
import { tracked } from '@glimmer/tracking';
|
2022-09-02 12:01:26 +00:00
|
|
|
import { hbs } from 'ember-template-imports';
|
|
|
|
|
import { Loading } from 'ember-mdi';
|
|
|
|
|
import { on } from '@ember/modifier';
|
|
|
|
|
import eq from '../helpers/eq';
|
|
|
|
|
|
2022-09-07 14:03:33 +00:00
|
|
|
export const sizes = {
|
2022-09-10 08:34:03 +00:00
|
|
|
sm: 'w-20 text-sm px-2.5 py-1',
|
|
|
|
|
md: 'w-24 px-3 py-2',
|
|
|
|
|
lg: 'w-24 px-4 py-3',
|
2022-09-07 14:03:33 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const iconSizes = {
|
|
|
|
|
sm: 18,
|
2022-09-14 12:03:22 +00:00
|
|
|
md: 20,
|
|
|
|
|
lg: 22,
|
2022-09-07 14:03:33 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const styles = {
|
|
|
|
|
default: 'border rounded',
|
|
|
|
|
primary: 'border rounded text-primary border-primary',
|
2022-09-10 14:27:41 +00:00
|
|
|
link: '',
|
2022-09-07 14:03:33 +00:00
|
|
|
};
|
2022-03-27 13:04:08 +00:00
|
|
|
|
|
|
|
|
export default class ButtonComponent extends Component {
|
2022-10-07 11:49:57 +00:00
|
|
|
static template = hbs(
|
|
|
|
|
`<button
|
2022-09-02 12:01:26 +00:00
|
|
|
disabled={{this.disabled}}
|
|
|
|
|
type={{this.type}}
|
2022-10-07 11:49:57 +00:00
|
|
|
class="inline-flex items-center justify-center min-w-min whitespace-nowrap
|
2022-09-07 14:03:33 +00:00
|
|
|
{{get sizes this.size}}
|
|
|
|
|
{{get styles this.style}}
|
2022-10-07 11:49:57 +00:00
|
|
|
"
|
2022-09-02 12:01:26 +00:00
|
|
|
...attributes
|
2022-10-07 11:49:57 +00:00
|
|
|
{{on "click" this.handleClick}}
|
2022-09-02 12:01:26 +00:00
|
|
|
>
|
2022-09-14 12:03:22 +00:00
|
|
|
{{#if this.icon}}
|
|
|
|
|
<this.icon
|
|
|
|
|
@spin={{this.isPending}}
|
|
|
|
|
@size={{get iconSizes this.size}}
|
|
|
|
|
class="mr-1"
|
|
|
|
|
/>
|
2022-09-02 12:01:26 +00:00
|
|
|
{{/if}}
|
2022-09-10 14:27:41 +00:00
|
|
|
|
|
|
|
|
{{#if (has-block)}}
|
|
|
|
|
{{yield}}
|
|
|
|
|
{{else if this.text}}
|
2022-09-07 14:03:33 +00:00
|
|
|
{{this.text}}
|
2022-09-02 12:01:26 +00:00
|
|
|
{{/if}}
|
|
|
|
|
</button>
|
2022-10-07 11:49:57 +00:00
|
|
|
`,
|
|
|
|
|
{
|
|
|
|
|
strictMode: true,
|
|
|
|
|
scope: () => ({ get, on, eq, sizes, styles, iconSizes }),
|
|
|
|
|
}
|
|
|
|
|
);
|
2022-09-02 12:01:26 +00:00
|
|
|
|
2022-03-27 13:04:08 +00:00
|
|
|
@tracked _state = 'default';
|
|
|
|
|
|
2022-09-14 12:03:22 +00:00
|
|
|
get icon() {
|
|
|
|
|
return this.isPending ? Loading : this.args?.icon;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-07 08:36:29 +00:00
|
|
|
get style() {
|
|
|
|
|
return this.args.style ?? 'default';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
get size() {
|
2022-09-07 14:03:33 +00:00
|
|
|
return this.args.size ?? 'md';
|
2022-05-07 08:36:29 +00:00
|
|
|
}
|
|
|
|
|
|
2022-03-30 06:58:35 +00:00
|
|
|
get isActive() {
|
|
|
|
|
return (
|
|
|
|
|
this.args.group &&
|
|
|
|
|
this.args.value &&
|
|
|
|
|
this.args.group.args.value === this.args.value
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-27 13:04:08 +00:00
|
|
|
get disabled() {
|
|
|
|
|
if (this.args.disabled !== undefined) {
|
|
|
|
|
return this.args.disabled;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return this.isPending;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
get type() {
|
|
|
|
|
return this.args.type ?? 'button';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
get state() {
|
|
|
|
|
return this.args.state ?? this._state;
|
|
|
|
|
}
|
2022-09-14 12:03:22 +00:00
|
|
|
|
2022-03-27 13:04:08 +00:00
|
|
|
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() {
|
2022-04-27 11:07:57 +00:00
|
|
|
return this.args[`${this.state}Text`] ?? this.args.text;
|
2022-03-27 13:04:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@action
|
2022-09-02 07:18:37 +00:00
|
|
|
async handleClick(event) {
|
2022-03-27 13:04:08 +00:00
|
|
|
if (typeof this.args.onClick !== 'function') {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-02 07:18:37 +00:00
|
|
|
event.preventDefault();
|
|
|
|
|
|
2022-03-27 13:04:08 +00:00
|
|
|
try {
|
2022-04-27 11:07:57 +00:00
|
|
|
const maybePromise = this.args.onClick(this.args.value);
|
2022-03-27 13:04:08 +00:00
|
|
|
|
2022-04-27 11:07:57 +00:00
|
|
|
if (typeof maybePromise?.then === 'function') {
|
|
|
|
|
this.state = 'pending';
|
|
|
|
|
|
|
|
|
|
await maybePromise;
|
|
|
|
|
|
|
|
|
|
if (!this.isDestroyed) {
|
|
|
|
|
this.state = 'fulfilled';
|
|
|
|
|
}
|
2022-03-27 13:04:08 +00:00
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
if (!this.isDestroyed) {
|
|
|
|
|
this.state = 'rejected';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|