@momentum-design/components 0.9.5 → 0.9.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/index.js +236 -27
- package/dist/browser/index.js.map +4 -4
- package/dist/components/button/button.component.d.ts +227 -0
- package/dist/components/button/button.component.js +438 -0
- package/dist/components/button/button.constants.d.ts +46 -0
- package/dist/components/button/button.constants.js +44 -0
- package/dist/components/button/button.styles.d.ts +2 -0
- package/dist/components/button/button.styles.js +195 -0
- package/dist/components/button/button.types.d.ts +9 -0
- package/dist/components/button/button.types.js +1 -0
- package/dist/components/button/button.utils.d.ts +16 -0
- package/dist/components/button/button.utils.js +27 -0
- package/dist/components/button/index.d.ts +8 -0
- package/dist/components/button/index.js +5 -0
- package/dist/custom-elements.json +439 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/react/button/index.d.ts +35 -0
- package/dist/react/button/index.js +44 -0
- package/dist/react/index.d.ts +1 -0
- package/dist/react/index.js +1 -0
- package/dist/utils/styles/index.js +3 -1
- package/package.json +1 -1
@@ -0,0 +1,227 @@
|
|
1
|
+
import { CSSResult, PropertyValueMap } from 'lit';
|
2
|
+
import { Component } from '../../models';
|
3
|
+
import type { ButtonColor, ButtonType, ButtonVariant, PillButtonSize, IconButtonSize } from './button.types';
|
4
|
+
/**
|
5
|
+
* `mdc-button` is a component that can be configured in various ways to suit different use cases.
|
6
|
+
*
|
7
|
+
* Button Variants:
|
8
|
+
* - **Primary**: Solid background color.
|
9
|
+
* - **Secondary**: Transparent background with a solid border.
|
10
|
+
* - **Tertiary**: No background or border, appears as plain text but retains all button functionalities.
|
11
|
+
*
|
12
|
+
* Button Colors:
|
13
|
+
* - **Positive**: Green color.
|
14
|
+
* - **Negative**: Red color.
|
15
|
+
* - **Accent**: Blue color.
|
16
|
+
* - **Promotional**: Purple color.
|
17
|
+
* - **Default**: White color.
|
18
|
+
*
|
19
|
+
* Button Sizes (in REM units):
|
20
|
+
* - **Pill button**: 40, 32, 28, 24.
|
21
|
+
* - **Icon button**: 64, 52, 40, 32, 28, 24.
|
22
|
+
* - **Tertiary icon button**: 20.
|
23
|
+
*
|
24
|
+
* Button Types:
|
25
|
+
* - **Pill button**: A button that contains text value. Commonly used for call to action, tags, or filters.
|
26
|
+
* - **Pill button with icons**: A button containing an icon either on the left or right side of the button.
|
27
|
+
* - **Icon button**: A button represented by just an icon without any text.
|
28
|
+
* The type of button is inferred based on the presence of slot and/or prefix and postfix icons.
|
29
|
+
*
|
30
|
+
* @dependency mdc-icon
|
31
|
+
*
|
32
|
+
* @tagname mdc-button
|
33
|
+
*
|
34
|
+
* @slot - Text label of the button.
|
35
|
+
*/
|
36
|
+
declare class Button extends Component {
|
37
|
+
/**
|
38
|
+
* The button's active state indicates whether it is currently toggled on (active) or off (inactive).
|
39
|
+
* When the active state is true, the button is considered to be in an active state, meaning it is toggled on.
|
40
|
+
* Conversely, when the active state is false, the button is in an inactive state, indicating it is toggled off.
|
41
|
+
* @default false
|
42
|
+
*/
|
43
|
+
active: boolean;
|
44
|
+
/**
|
45
|
+
* Indicates whether the button is disabled.
|
46
|
+
* The button is currently disabled for user interaction; it is not focusable or clickable.
|
47
|
+
* @default false
|
48
|
+
*/
|
49
|
+
disabled: boolean;
|
50
|
+
/**
|
51
|
+
* Indicates whether the button is soft disabled.
|
52
|
+
* When set to `true`, the button appears visually disabled but still allows
|
53
|
+
* focus, click, and keyboard actions to be passed through.
|
54
|
+
*
|
55
|
+
* **Important:** When using soft disabled, consumers must ensure that
|
56
|
+
* the button behaves like a disabled button, allowing only focus and
|
57
|
+
* preventing any interactions (clicks or keyboard actions) from triggering unintended actions.
|
58
|
+
* @default false
|
59
|
+
*/
|
60
|
+
softDisabled: boolean;
|
61
|
+
/**
|
62
|
+
* The name of the icon to display as a prefix.
|
63
|
+
* The icon is displayed on the left side of the button.
|
64
|
+
*/
|
65
|
+
prefixIcon?: string;
|
66
|
+
/**
|
67
|
+
* The name of the icon to display as a postfix.
|
68
|
+
* The icon is displayed on the right side of the button.
|
69
|
+
*/
|
70
|
+
postfixIcon?: string;
|
71
|
+
/**
|
72
|
+
* There are 3 variants of button: primary, secondary, tertiary. They are styled differently.
|
73
|
+
* - **Primary**: Solid background color.
|
74
|
+
* - **Secondary**: Transparent background with a solid border.
|
75
|
+
* - **Tertiary**: No background or border, appears as plain text but retains all button functionalities.
|
76
|
+
* @default primary
|
77
|
+
*/
|
78
|
+
variant: ButtonVariant;
|
79
|
+
/**
|
80
|
+
* Button sizing is based on the button type.
|
81
|
+
* - **Pill button**: 40, 32, 28, 24.
|
82
|
+
* - **Icon button**: 64, 52, 40, 32, 28, 24.
|
83
|
+
* - Tertiary icon button cam also be 20.
|
84
|
+
* @default 32
|
85
|
+
*/
|
86
|
+
size: PillButtonSize | IconButtonSize;
|
87
|
+
/**
|
88
|
+
* There are 5 colors for button: positive, negative, accent, promotional, default.
|
89
|
+
* @default default
|
90
|
+
*/
|
91
|
+
color: ButtonColor;
|
92
|
+
/**
|
93
|
+
* The tabindex of the button.
|
94
|
+
* @default 0
|
95
|
+
*/
|
96
|
+
tabIndex: number;
|
97
|
+
/**
|
98
|
+
* This property defines the ARIA role for the element. By default, it is set to 'button'.
|
99
|
+
* Consumers should override this role when:
|
100
|
+
* - The element is being used in a context where a different role is more appropriate.
|
101
|
+
* - Custom behaviors are implemented that require a specific ARIA role for accessibility purposes.
|
102
|
+
* @default button
|
103
|
+
*/
|
104
|
+
role: string;
|
105
|
+
/**
|
106
|
+
* This property defines the type attribute for the button element.
|
107
|
+
* The type attribute specifies the behavior of the button when it is clicked.
|
108
|
+
* - **submit**: The button submits the form data to the server.
|
109
|
+
* - **reset**: The button resets the form data to its initial state.
|
110
|
+
* - **button**: The button does nothing when clicked.
|
111
|
+
* @default button
|
112
|
+
*/
|
113
|
+
type: ButtonType;
|
114
|
+
/** @internal */
|
115
|
+
private typeInternal;
|
116
|
+
/** @internal */
|
117
|
+
private iconSize;
|
118
|
+
/**
|
119
|
+
* @internal
|
120
|
+
*/
|
121
|
+
private prevTabindex;
|
122
|
+
/**
|
123
|
+
* @internal
|
124
|
+
*/
|
125
|
+
private prevPrefixIcon?;
|
126
|
+
/**
|
127
|
+
* @internal
|
128
|
+
*/
|
129
|
+
private prevPostfixIcon?;
|
130
|
+
/** @internal */
|
131
|
+
static formAssociated: boolean;
|
132
|
+
/** @internal */
|
133
|
+
private internals;
|
134
|
+
/** @internal */
|
135
|
+
get form(): HTMLFormElement | null;
|
136
|
+
constructor();
|
137
|
+
update(changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): void;
|
138
|
+
private executeAction;
|
139
|
+
/**
|
140
|
+
* Modifies the icon name based on the active state.
|
141
|
+
* If the button is active, the icon name is suffixed with '-filled'.
|
142
|
+
* If the button is inactive, the icon name is restored to its original value.
|
143
|
+
* If '-filled' icon is not available, the icon name remains unchanged.
|
144
|
+
*
|
145
|
+
* @param active - The active state.
|
146
|
+
*/
|
147
|
+
private modifyIconName;
|
148
|
+
/**
|
149
|
+
* Sets the class of 'icon' for icon buttons.
|
150
|
+
* @param type - The type of the button.
|
151
|
+
*/
|
152
|
+
private setClassBasedOnType;
|
153
|
+
/**
|
154
|
+
* Sets the variant attribute for the button component.
|
155
|
+
* If the provided variant is not included in the BUTTON_VARIANTS,
|
156
|
+
* it defaults to the value specified in DEFAULTS.VARIANT.
|
157
|
+
*
|
158
|
+
* @param variant - The variant to set.
|
159
|
+
*/
|
160
|
+
private setVariant;
|
161
|
+
/**
|
162
|
+
* Sets the size attribute for the button component.
|
163
|
+
* Validates the size based on the button type (icon, pill, or tertiary).
|
164
|
+
* Defaults to DEFAULTS.SIZE if invalid.
|
165
|
+
*
|
166
|
+
* @param size - The size to set.
|
167
|
+
*/
|
168
|
+
private setSize;
|
169
|
+
/**
|
170
|
+
* Sets the color attribute for the button.
|
171
|
+
* Defaults to DEFAULTS.COLOR if invalid or for tertiary buttons.
|
172
|
+
*
|
173
|
+
* @param color - The color to set.
|
174
|
+
*/
|
175
|
+
private setColor;
|
176
|
+
/**
|
177
|
+
* Sets or removes the aria-pressed attribute based on the active state.
|
178
|
+
*
|
179
|
+
* @param element - The target element.
|
180
|
+
* @param active - The active state.
|
181
|
+
*/
|
182
|
+
private setAriaPressed;
|
183
|
+
/**
|
184
|
+
* Sets the soft-disabled attribute for the button.
|
185
|
+
* When soft-disabled, the button looks to be disabled but remains focusable and clickable.
|
186
|
+
* Also sets/removes aria-disabled attribute.
|
187
|
+
*
|
188
|
+
* @param element - The button element.
|
189
|
+
* @param softDisabled - The soft-disabled state.
|
190
|
+
*/
|
191
|
+
private setSoftDisabled;
|
192
|
+
/**
|
193
|
+
* Sets the disabled attribute for the button.
|
194
|
+
* When disabled, the button is not focusable or clickable, and tabindex is set to -1.
|
195
|
+
* The previous tabindex is stored and restored when enabled.
|
196
|
+
* Also sets/removes aria-disabled attribute.
|
197
|
+
*
|
198
|
+
* @param element - The button element.
|
199
|
+
* @param disabled - The disabled state.
|
200
|
+
*/
|
201
|
+
private setDisabled;
|
202
|
+
private triggerClickEvent;
|
203
|
+
/**
|
204
|
+
* Handles the keydown event on the button.
|
205
|
+
* If the key is 'Enter' or 'Space', the button is pressed.
|
206
|
+
* If the key is 'Enter', the button is pressed. The native HTML button works in the same way.
|
207
|
+
*
|
208
|
+
* @param event - The keyboard event.
|
209
|
+
*/
|
210
|
+
private handleKeyDown;
|
211
|
+
/**
|
212
|
+
* Handles the keyup event on the button.
|
213
|
+
* If the key is 'Enter' or 'Space', the button is clicked.
|
214
|
+
* If the key is 'Space', the button is pressed. The native HTML button works in the same way.
|
215
|
+
*
|
216
|
+
* @param event - The keyboard event.
|
217
|
+
*/
|
218
|
+
private handleKeyUp;
|
219
|
+
/**
|
220
|
+
* Infers the type of button based on the presence of slot and/or prefix and postfix icons.
|
221
|
+
* @param slot - default slot of button
|
222
|
+
*/
|
223
|
+
private inferButtonType;
|
224
|
+
render(): import("lit-html").TemplateResult<1>;
|
225
|
+
static styles: Array<CSSResult>;
|
226
|
+
}
|
227
|
+
export default Button;
|
@@ -0,0 +1,438 @@
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
6
|
+
};
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
9
|
+
};
|
10
|
+
import { html } from 'lit';
|
11
|
+
import { property, state } from 'lit/decorators.js';
|
12
|
+
import styles from './button.styles';
|
13
|
+
import { Component } from '../../models';
|
14
|
+
import { BUTTON_COLORS, BUTTON_TYPE_INTERNAL, BUTTON_VARIANTS, DEFAULTS, ICON_BUTTON_SIZES, PILL_BUTTON_SIZES, } from './button.constants';
|
15
|
+
import { getIconNameWithoutStyle, getIconSize } from './button.utils';
|
16
|
+
/**
|
17
|
+
* `mdc-button` is a component that can be configured in various ways to suit different use cases.
|
18
|
+
*
|
19
|
+
* Button Variants:
|
20
|
+
* - **Primary**: Solid background color.
|
21
|
+
* - **Secondary**: Transparent background with a solid border.
|
22
|
+
* - **Tertiary**: No background or border, appears as plain text but retains all button functionalities.
|
23
|
+
*
|
24
|
+
* Button Colors:
|
25
|
+
* - **Positive**: Green color.
|
26
|
+
* - **Negative**: Red color.
|
27
|
+
* - **Accent**: Blue color.
|
28
|
+
* - **Promotional**: Purple color.
|
29
|
+
* - **Default**: White color.
|
30
|
+
*
|
31
|
+
* Button Sizes (in REM units):
|
32
|
+
* - **Pill button**: 40, 32, 28, 24.
|
33
|
+
* - **Icon button**: 64, 52, 40, 32, 28, 24.
|
34
|
+
* - **Tertiary icon button**: 20.
|
35
|
+
*
|
36
|
+
* Button Types:
|
37
|
+
* - **Pill button**: A button that contains text value. Commonly used for call to action, tags, or filters.
|
38
|
+
* - **Pill button with icons**: A button containing an icon either on the left or right side of the button.
|
39
|
+
* - **Icon button**: A button represented by just an icon without any text.
|
40
|
+
* The type of button is inferred based on the presence of slot and/or prefix and postfix icons.
|
41
|
+
*
|
42
|
+
* @dependency mdc-icon
|
43
|
+
*
|
44
|
+
* @tagname mdc-button
|
45
|
+
*
|
46
|
+
* @slot - Text label of the button.
|
47
|
+
*/
|
48
|
+
class Button extends Component {
|
49
|
+
/** @internal */
|
50
|
+
get form() {
|
51
|
+
return this.internals.form;
|
52
|
+
}
|
53
|
+
constructor() {
|
54
|
+
super();
|
55
|
+
/**
|
56
|
+
* The button's active state indicates whether it is currently toggled on (active) or off (inactive).
|
57
|
+
* When the active state is true, the button is considered to be in an active state, meaning it is toggled on.
|
58
|
+
* Conversely, when the active state is false, the button is in an inactive state, indicating it is toggled off.
|
59
|
+
* @default false
|
60
|
+
*/
|
61
|
+
this.active = false;
|
62
|
+
/**
|
63
|
+
* Indicates whether the button is disabled.
|
64
|
+
* The button is currently disabled for user interaction; it is not focusable or clickable.
|
65
|
+
* @default false
|
66
|
+
*/
|
67
|
+
this.disabled = false;
|
68
|
+
/**
|
69
|
+
* Indicates whether the button is soft disabled.
|
70
|
+
* When set to `true`, the button appears visually disabled but still allows
|
71
|
+
* focus, click, and keyboard actions to be passed through.
|
72
|
+
*
|
73
|
+
* **Important:** When using soft disabled, consumers must ensure that
|
74
|
+
* the button behaves like a disabled button, allowing only focus and
|
75
|
+
* preventing any interactions (clicks or keyboard actions) from triggering unintended actions.
|
76
|
+
* @default false
|
77
|
+
*/
|
78
|
+
this.softDisabled = false;
|
79
|
+
/**
|
80
|
+
* There are 3 variants of button: primary, secondary, tertiary. They are styled differently.
|
81
|
+
* - **Primary**: Solid background color.
|
82
|
+
* - **Secondary**: Transparent background with a solid border.
|
83
|
+
* - **Tertiary**: No background or border, appears as plain text but retains all button functionalities.
|
84
|
+
* @default primary
|
85
|
+
*/
|
86
|
+
this.variant = DEFAULTS.VARIANT;
|
87
|
+
/**
|
88
|
+
* Button sizing is based on the button type.
|
89
|
+
* - **Pill button**: 40, 32, 28, 24.
|
90
|
+
* - **Icon button**: 64, 52, 40, 32, 28, 24.
|
91
|
+
* - Tertiary icon button cam also be 20.
|
92
|
+
* @default 32
|
93
|
+
*/
|
94
|
+
this.size = DEFAULTS.SIZE;
|
95
|
+
/**
|
96
|
+
* There are 5 colors for button: positive, negative, accent, promotional, default.
|
97
|
+
* @default default
|
98
|
+
*/
|
99
|
+
this.color = DEFAULTS.COLOR;
|
100
|
+
/**
|
101
|
+
* The tabindex of the button.
|
102
|
+
* @default 0
|
103
|
+
*/
|
104
|
+
this.tabIndex = 0;
|
105
|
+
/**
|
106
|
+
* This property defines the ARIA role for the element. By default, it is set to 'button'.
|
107
|
+
* Consumers should override this role when:
|
108
|
+
* - The element is being used in a context where a different role is more appropriate.
|
109
|
+
* - Custom behaviors are implemented that require a specific ARIA role for accessibility purposes.
|
110
|
+
* @default button
|
111
|
+
*/
|
112
|
+
this.role = 'button';
|
113
|
+
/**
|
114
|
+
* This property defines the type attribute for the button element.
|
115
|
+
* The type attribute specifies the behavior of the button when it is clicked.
|
116
|
+
* - **submit**: The button submits the form data to the server.
|
117
|
+
* - **reset**: The button resets the form data to its initial state.
|
118
|
+
* - **button**: The button does nothing when clicked.
|
119
|
+
* @default button
|
120
|
+
*/
|
121
|
+
this.type = DEFAULTS.TYPE;
|
122
|
+
/** @internal */
|
123
|
+
this.typeInternal = DEFAULTS.TYPE_INTERNAL;
|
124
|
+
/** @internal */
|
125
|
+
this.iconSize = 1;
|
126
|
+
/**
|
127
|
+
* @internal
|
128
|
+
*/
|
129
|
+
this.prevTabindex = 0;
|
130
|
+
this.addEventListener('click', this.executeAction.bind(this));
|
131
|
+
this.addEventListener('keydown', this.handleKeyDown.bind(this));
|
132
|
+
this.addEventListener('keyup', this.handleKeyUp.bind(this));
|
133
|
+
/** @internal */
|
134
|
+
this.internals = this.attachInternals();
|
135
|
+
}
|
136
|
+
update(changedProperties) {
|
137
|
+
super.update(changedProperties);
|
138
|
+
if (changedProperties.has('disabled')) {
|
139
|
+
this.setDisabled(this, this.disabled);
|
140
|
+
}
|
141
|
+
if (changedProperties.has('softDisabled')) {
|
142
|
+
this.setSoftDisabled(this, this.softDisabled);
|
143
|
+
}
|
144
|
+
if (changedProperties.has('active')) {
|
145
|
+
this.setAriaPressed(this, this.active);
|
146
|
+
this.modifyIconName(this.active);
|
147
|
+
}
|
148
|
+
if (changedProperties.has('size')) {
|
149
|
+
this.setSize(this.size);
|
150
|
+
}
|
151
|
+
if (changedProperties.has('variant')) {
|
152
|
+
this.setVariant(this.variant);
|
153
|
+
this.setSize(this.size);
|
154
|
+
}
|
155
|
+
if (changedProperties.has('color')) {
|
156
|
+
this.setColor(this.color);
|
157
|
+
}
|
158
|
+
if (changedProperties.has('typeInternal')) {
|
159
|
+
this.setSize(this.size);
|
160
|
+
this.setClassBasedOnType(this.typeInternal);
|
161
|
+
}
|
162
|
+
if (changedProperties.has('prefixIcon') || changedProperties.has('postfixIcon')) {
|
163
|
+
this.inferButtonType();
|
164
|
+
}
|
165
|
+
}
|
166
|
+
executeAction() {
|
167
|
+
if (this.type === 'submit' && this.internals.form) {
|
168
|
+
this.internals.form.requestSubmit();
|
169
|
+
}
|
170
|
+
if (this.type === 'reset' && this.internals.form) {
|
171
|
+
this.internals.form.reset();
|
172
|
+
}
|
173
|
+
}
|
174
|
+
/**
|
175
|
+
* Modifies the icon name based on the active state.
|
176
|
+
* If the button is active, the icon name is suffixed with '-filled'.
|
177
|
+
* If the button is inactive, the icon name is restored to its original value.
|
178
|
+
* If '-filled' icon is not available, the icon name remains unchanged.
|
179
|
+
*
|
180
|
+
* @param active - The active state.
|
181
|
+
*/
|
182
|
+
modifyIconName(active) {
|
183
|
+
if (active) {
|
184
|
+
if (this.prefixIcon) {
|
185
|
+
this.prevPrefixIcon = this.prefixIcon;
|
186
|
+
this.prefixIcon = `${getIconNameWithoutStyle(this.prefixIcon)}-filled`;
|
187
|
+
}
|
188
|
+
if (this.postfixIcon) {
|
189
|
+
this.prevPostfixIcon = this.postfixIcon;
|
190
|
+
this.postfixIcon = `${getIconNameWithoutStyle(this.postfixIcon)}-filled`;
|
191
|
+
}
|
192
|
+
}
|
193
|
+
else {
|
194
|
+
if (this.prevPrefixIcon) {
|
195
|
+
this.prefixIcon = this.prevPrefixIcon;
|
196
|
+
}
|
197
|
+
if (this.prevPostfixIcon) {
|
198
|
+
this.postfixIcon = this.prevPostfixIcon;
|
199
|
+
}
|
200
|
+
}
|
201
|
+
}
|
202
|
+
/**
|
203
|
+
* Sets the class of 'icon' for icon buttons.
|
204
|
+
* @param type - The type of the button.
|
205
|
+
*/
|
206
|
+
setClassBasedOnType(type) {
|
207
|
+
if (type === BUTTON_TYPE_INTERNAL.ICON) {
|
208
|
+
this.classList.add('mdc-icon-button');
|
209
|
+
}
|
210
|
+
else {
|
211
|
+
this.classList.remove('mdc-icon-button');
|
212
|
+
}
|
213
|
+
}
|
214
|
+
/**
|
215
|
+
* Sets the variant attribute for the button component.
|
216
|
+
* If the provided variant is not included in the BUTTON_VARIANTS,
|
217
|
+
* it defaults to the value specified in DEFAULTS.VARIANT.
|
218
|
+
*
|
219
|
+
* @param variant - The variant to set.
|
220
|
+
*/
|
221
|
+
setVariant(variant) {
|
222
|
+
this.setAttribute('variant', Object.values(BUTTON_VARIANTS).includes(variant) ? variant : DEFAULTS.VARIANT);
|
223
|
+
}
|
224
|
+
/**
|
225
|
+
* Sets the size attribute for the button component.
|
226
|
+
* Validates the size based on the button type (icon, pill, or tertiary).
|
227
|
+
* Defaults to DEFAULTS.SIZE if invalid.
|
228
|
+
*
|
229
|
+
* @param size - The size to set.
|
230
|
+
*/
|
231
|
+
setSize(size) {
|
232
|
+
const isIconType = this.typeInternal === BUTTON_TYPE_INTERNAL.ICON;
|
233
|
+
const isValidSize = isIconType
|
234
|
+
? (Object.values(ICON_BUTTON_SIZES).includes(size)
|
235
|
+
&& !(size === ICON_BUTTON_SIZES[20] && this.variant !== BUTTON_VARIANTS.TERTIARY))
|
236
|
+
: Object.values(PILL_BUTTON_SIZES).includes(size);
|
237
|
+
this.setAttribute('size', isValidSize ? `${size}` : `${DEFAULTS.SIZE}`);
|
238
|
+
this.iconSize = getIconSize(size);
|
239
|
+
}
|
240
|
+
/**
|
241
|
+
* Sets the color attribute for the button.
|
242
|
+
* Defaults to DEFAULTS.COLOR if invalid or for tertiary buttons.
|
243
|
+
*
|
244
|
+
* @param color - The color to set.
|
245
|
+
*/
|
246
|
+
setColor(color) {
|
247
|
+
if (!Object.values(BUTTON_COLORS).includes(color) || this.variant === BUTTON_VARIANTS.TERTIARY) {
|
248
|
+
this.setAttribute('color', `${DEFAULTS.COLOR}`);
|
249
|
+
}
|
250
|
+
else {
|
251
|
+
this.setAttribute('color', color);
|
252
|
+
}
|
253
|
+
}
|
254
|
+
/**
|
255
|
+
* Sets or removes the aria-pressed attribute based on the active state.
|
256
|
+
*
|
257
|
+
* @param element - The target element.
|
258
|
+
* @param active - The active state.
|
259
|
+
*/
|
260
|
+
setAriaPressed(element, active) {
|
261
|
+
if (active) {
|
262
|
+
element.setAttribute('aria-pressed', 'true');
|
263
|
+
}
|
264
|
+
else {
|
265
|
+
element.removeAttribute('aria-pressed');
|
266
|
+
}
|
267
|
+
}
|
268
|
+
/**
|
269
|
+
* Sets the soft-disabled attribute for the button.
|
270
|
+
* When soft-disabled, the button looks to be disabled but remains focusable and clickable.
|
271
|
+
* Also sets/removes aria-disabled attribute.
|
272
|
+
*
|
273
|
+
* @param element - The button element.
|
274
|
+
* @param softDisabled - The soft-disabled state.
|
275
|
+
*/
|
276
|
+
setSoftDisabled(element, softDisabled) {
|
277
|
+
if (softDisabled) {
|
278
|
+
element.setAttribute('aria-disabled', 'true');
|
279
|
+
}
|
280
|
+
else {
|
281
|
+
element.removeAttribute('aria-disabled');
|
282
|
+
}
|
283
|
+
}
|
284
|
+
/**
|
285
|
+
* Sets the disabled attribute for the button.
|
286
|
+
* When disabled, the button is not focusable or clickable, and tabindex is set to -1.
|
287
|
+
* The previous tabindex is stored and restored when enabled.
|
288
|
+
* Also sets/removes aria-disabled attribute.
|
289
|
+
*
|
290
|
+
* @param element - The button element.
|
291
|
+
* @param disabled - The disabled state.
|
292
|
+
*/
|
293
|
+
setDisabled(element, disabled) {
|
294
|
+
if (disabled) {
|
295
|
+
element.setAttribute('aria-disabled', 'true');
|
296
|
+
this.prevTabindex = this.tabIndex;
|
297
|
+
this.tabIndex = -1;
|
298
|
+
}
|
299
|
+
else {
|
300
|
+
this.tabIndex = this.prevTabindex;
|
301
|
+
element.removeAttribute('aria-disabled');
|
302
|
+
}
|
303
|
+
}
|
304
|
+
triggerClickEvent() {
|
305
|
+
const clickEvent = new MouseEvent('click', {
|
306
|
+
bubbles: true,
|
307
|
+
cancelable: true,
|
308
|
+
view: window,
|
309
|
+
});
|
310
|
+
this.dispatchEvent(clickEvent);
|
311
|
+
this.executeAction();
|
312
|
+
}
|
313
|
+
/**
|
314
|
+
* Handles the keydown event on the button.
|
315
|
+
* If the key is 'Enter' or 'Space', the button is pressed.
|
316
|
+
* If the key is 'Enter', the button is pressed. The native HTML button works in the same way.
|
317
|
+
*
|
318
|
+
* @param event - The keyboard event.
|
319
|
+
*/
|
320
|
+
handleKeyDown(event) {
|
321
|
+
if (['Enter', ' '].includes(event.key)) {
|
322
|
+
this.classList.add('pressed');
|
323
|
+
if (event.key === 'Enter') {
|
324
|
+
this.triggerClickEvent();
|
325
|
+
}
|
326
|
+
}
|
327
|
+
}
|
328
|
+
/**
|
329
|
+
* Handles the keyup event on the button.
|
330
|
+
* If the key is 'Enter' or 'Space', the button is clicked.
|
331
|
+
* If the key is 'Space', the button is pressed. The native HTML button works in the same way.
|
332
|
+
*
|
333
|
+
* @param event - The keyboard event.
|
334
|
+
*/
|
335
|
+
handleKeyUp(event) {
|
336
|
+
if (['Enter', ' '].includes(event.key)) {
|
337
|
+
this.classList.remove('pressed');
|
338
|
+
if (event.key === ' ') {
|
339
|
+
this.triggerClickEvent();
|
340
|
+
}
|
341
|
+
}
|
342
|
+
}
|
343
|
+
/**
|
344
|
+
* Infers the type of button based on the presence of slot and/or prefix and postfix icons.
|
345
|
+
* @param slot - default slot of button
|
346
|
+
*/
|
347
|
+
inferButtonType() {
|
348
|
+
var _a, _b;
|
349
|
+
const slot = (_b = (_a = this.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('slot')) === null || _b === void 0 ? void 0 : _b.assignedNodes().length;
|
350
|
+
if (slot && (this.prefixIcon || this.postfixIcon)) {
|
351
|
+
this.typeInternal = BUTTON_TYPE_INTERNAL.PILL_WITH_ICON;
|
352
|
+
}
|
353
|
+
else if (!slot && (this.prefixIcon || this.postfixIcon)) {
|
354
|
+
this.typeInternal = BUTTON_TYPE_INTERNAL.ICON;
|
355
|
+
}
|
356
|
+
else {
|
357
|
+
this.typeInternal = BUTTON_TYPE_INTERNAL.PILL;
|
358
|
+
}
|
359
|
+
}
|
360
|
+
// Note: @click is attached to each of the children of the button.
|
361
|
+
// Adding click listener within the constructor will not work properly when button is disabled.
|
362
|
+
// https://discord.com/channels/1012791295170859069/1047015641225371718/threads/1309446072413720576
|
363
|
+
render() {
|
364
|
+
return html `
|
365
|
+
${this.prefixIcon ? html `
|
366
|
+
<mdc-icon
|
367
|
+
name="${this.prefixIcon}"
|
368
|
+
part="prefix-icon"
|
369
|
+
size=${this.iconSize}
|
370
|
+
length-unit="rem">
|
371
|
+
</mdc-icon>` : ''}
|
372
|
+
<slot @slotchange=${this.inferButtonType}></slot>
|
373
|
+
${this.postfixIcon ? html `
|
374
|
+
<mdc-icon
|
375
|
+
name="${this.postfixIcon}"
|
376
|
+
part="postfix-icon"
|
377
|
+
size=${this.iconSize}
|
378
|
+
length-unit="rem">
|
379
|
+
</mdc-icon>` : ''}
|
380
|
+
`;
|
381
|
+
}
|
382
|
+
}
|
383
|
+
/** @internal */
|
384
|
+
Button.formAssociated = true;
|
385
|
+
Button.styles = [...Component.styles, ...styles];
|
386
|
+
__decorate([
|
387
|
+
property({ type: Boolean }),
|
388
|
+
__metadata("design:type", Object)
|
389
|
+
], Button.prototype, "active", void 0);
|
390
|
+
__decorate([
|
391
|
+
property({ type: Boolean }),
|
392
|
+
__metadata("design:type", Object)
|
393
|
+
], Button.prototype, "disabled", void 0);
|
394
|
+
__decorate([
|
395
|
+
property({ type: Boolean, attribute: 'soft-disabled' }),
|
396
|
+
__metadata("design:type", Object)
|
397
|
+
], Button.prototype, "softDisabled", void 0);
|
398
|
+
__decorate([
|
399
|
+
property({ type: String, attribute: 'prefix-icon' }),
|
400
|
+
__metadata("design:type", String)
|
401
|
+
], Button.prototype, "prefixIcon", void 0);
|
402
|
+
__decorate([
|
403
|
+
property({ type: String, attribute: 'postfix-icon' }),
|
404
|
+
__metadata("design:type", String)
|
405
|
+
], Button.prototype, "postfixIcon", void 0);
|
406
|
+
__decorate([
|
407
|
+
property({ type: String }),
|
408
|
+
__metadata("design:type", String)
|
409
|
+
], Button.prototype, "variant", void 0);
|
410
|
+
__decorate([
|
411
|
+
property({ type: Number }),
|
412
|
+
__metadata("design:type", Number)
|
413
|
+
], Button.prototype, "size", void 0);
|
414
|
+
__decorate([
|
415
|
+
property({ type: String }),
|
416
|
+
__metadata("design:type", String)
|
417
|
+
], Button.prototype, "color", void 0);
|
418
|
+
__decorate([
|
419
|
+
property({ type: Number, reflect: true }),
|
420
|
+
__metadata("design:type", Object)
|
421
|
+
], Button.prototype, "tabIndex", void 0);
|
422
|
+
__decorate([
|
423
|
+
property({ type: String, reflect: true }),
|
424
|
+
__metadata("design:type", Object)
|
425
|
+
], Button.prototype, "role", void 0);
|
426
|
+
__decorate([
|
427
|
+
property({ reflect: true }),
|
428
|
+
__metadata("design:type", String)
|
429
|
+
], Button.prototype, "type", void 0);
|
430
|
+
__decorate([
|
431
|
+
state(),
|
432
|
+
__metadata("design:type", String)
|
433
|
+
], Button.prototype, "typeInternal", void 0);
|
434
|
+
__decorate([
|
435
|
+
state(),
|
436
|
+
__metadata("design:type", Object)
|
437
|
+
], Button.prototype, "iconSize", void 0);
|
438
|
+
export default Button;
|