-
Notifications
You must be signed in to change notification settings - Fork 690
Expand file tree
/
Copy pathbutton.ts
More file actions
118 lines (102 loc) · 3.51 KB
/
button.ts
File metadata and controls
118 lines (102 loc) · 3.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import {LionButtonSubmit} from '@lion/ui/button.js';
import {html, nothing} from 'lit';
import {property, state} from 'lit/decorators.js';
import styles from './button.styles.js';
import '../spinner/spinner.js';
import '../icon/icon.js';
import {computeAccessibleName} from 'dom-accessibility-api';
import {classMap} from 'lit/directives/class-map.js';
/**
* @summary Interactive element that triggers an action or event.
* @since 1.0
*
* @dependency craft-spinner
*
* @slot - The button's label.
* @slot prefix - Content to display before the label (typically an icon).
* @slot suffix - Content to display after the label (typically an icon).
*
* @csspart content - The button's content wrapper.
* @csspart prefix - The button's prefix slot.
* @csspart label - The button's label slot.
* @csspart suffix - The button's suffix slot.
* @csspart spinner - Spinner that shows when the button is in a loading state.
*/
export default class CraftButton extends LionButtonSubmit {
static override get styles() {
return [...super.styles, styles];
}
override async firstUpdated(changedProperties: Map<string, any>) {
super.firstUpdated(changedProperties);
await this.updateComplete;
const childComponents = this.querySelectorAll('craft-icon, craft-spinner');
await Promise.all(
Array.from(childComponents).map((child: any) => child.updateComplete)
);
if (!this.accessibleName) {
this.accessibleName = computeAccessibleName(this);
}
this._hasAccessibilityError =
!this.accessibleName || this.accessibleName.trim() === '';
}
/** The computed accessible name */
@property() accessibleName: string;
/** Visual appearance of the button */
@property({reflect: true}) appearance:
| 'accent'
| 'plain'
| 'filled'
| 'dashed' = 'accent';
/**
* Theme variant of the button. Defaults to "default"
*
* Primary: The primary action on a page
* Default: Used in most cases
* Danger: Indicates a dangerous action, when data will be removed or deleted
* Inherit: Useful for colorable elements, button will reflect the parent theme
*/
@property({reflect: true}) variant:
| 'primary'
| 'default'
| 'danger'
| 'inherit' = 'default';
/** Size of the button. Defaults to "medium" */
@property({reflect: true}) size: 'zero' | 'small' | 'medium' | 'large' =
'medium';
/** Show a spinner instead of the label */
@property({reflect: true, type: Boolean}) loading: boolean = false;
/** Set align-items for the content */
@property() align: 'start' | 'end' | 'center' = 'center';
@state()
private _hasAccessibilityError: boolean = false;
override render() {
return html`
<!--@TODO need to figure this out-->
<!--<div role="status" class="sr-only"></div>-->
<div
class="${classMap({
'button-content': true,
'button-content--start': this.align === 'start',
'button-content--end': this.align === 'end',
'a11y-error': this._hasAccessibilityError,
})}"
part="content"
>
<slot name="prefix" class="prefix" part="prefix"></slot>
<slot class="label" part="label"></slot>
<slot name="suffix" class="suffix" part="suffix"></slot>
</div>
${this.loading
? html`<craft-spinner part="spinner"></craft-spinner>`
: nothing}
`;
}
}
if (!customElements.get('craft-button')) {
customElements.define('craft-button', CraftButton);
}
declare global {
interface HTMLElementTagNameMap {
'craft-button': CraftButton;
}
}