@momentum-design/components 0.81.3 → 0.81.4
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 +230 -225
- package/dist/browser/index.js.map +4 -4
- package/dist/components/avatarbutton/avatarbutton.component.js +2 -1
- package/dist/components/badge/badge.component.js +2 -1
- package/dist/components/optgroup/optgroup.component.js +3 -2
- package/dist/components/option/option.component.d.ts +0 -4
- package/dist/components/option/option.component.js +3 -9
- package/dist/components/popover/popover.component.js +4 -4
- package/dist/components/popover/popover.utils.js +7 -7
- package/dist/components/progressbar/progressbar.component.js +2 -1
- package/dist/components/progressspinner/progressspinner.component.js +2 -1
- package/dist/components/radio/radio.component.js +2 -1
- package/dist/components/select/select.component.d.ts +0 -10
- package/dist/components/select/select.component.js +67 -53
- package/dist/components/select/select.constants.d.ts +2 -1
- package/dist/components/select/select.constants.js +2 -1
- package/dist/components/select/select.styles.js +2 -1
- package/dist/components/spinner/spinner.component.js +2 -1
- package/dist/components/tab/tab.component.js +2 -1
- package/dist/components/tablist/tablist.component.js +2 -1
- package/dist/components/toggle/toggle.component.js +2 -1
- package/dist/custom-elements.json +838 -883
- package/dist/react/index.d.ts +2 -2
- package/dist/react/index.js +2 -2
- package/dist/utils/keys.d.ts +1 -0
- package/dist/utils/keys.js +1 -0
- package/dist/utils/mixins/FormInternalsMixin.js +1 -1
- package/dist/utils/roles.d.ts +9 -0
- package/dist/utils/roles.js +9 -0
- package/package.json +1 -1
|
@@ -12,6 +12,7 @@ import { property } from 'lit/decorators.js';
|
|
|
12
12
|
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
13
13
|
import { AvatarComponentMixin } from '../../utils/mixins/AvatarComponentMixin';
|
|
14
14
|
import { IconNameMixin } from '../../utils/mixins/IconNameMixin';
|
|
15
|
+
import { ROLE } from '../../utils/roles';
|
|
15
16
|
import { AVATAR_SIZE, DEFAULTS } from '../avatar/avatar.constants';
|
|
16
17
|
import { DEFAULTS as BUTTON_DEFAULTS } from '../button/button.constants';
|
|
17
18
|
import Buttonsimple from '../buttonsimple/buttonsimple.component';
|
|
@@ -48,7 +49,7 @@ class AvatarButton extends AvatarComponentMixin(IconNameMixin(Buttonsimple)) {
|
|
|
48
49
|
this.active = undefined;
|
|
49
50
|
this.disabled = undefined;
|
|
50
51
|
this.softDisabled = undefined;
|
|
51
|
-
this.role =
|
|
52
|
+
this.role = ROLE.BUTTON;
|
|
52
53
|
this.type = BUTTON_DEFAULTS.TYPE;
|
|
53
54
|
}
|
|
54
55
|
update(changedProperties) {
|
|
@@ -13,6 +13,7 @@ import { property } from 'lit/decorators.js';
|
|
|
13
13
|
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
14
14
|
import { Component } from '../../models';
|
|
15
15
|
import { IconNameMixin } from '../../utils/mixins/IconNameMixin';
|
|
16
|
+
import { ROLE } from '../../utils/roles';
|
|
16
17
|
import { TYPE as FONT_TYPE, VALID_TEXT_TAGS } from '../text/text.constants';
|
|
17
18
|
import { DEFAULTS, ICON_NAMES_LIST, ICON_STATE, ICON_VARIANT, TYPE as BADGE_TYPE } from './badge.constants';
|
|
18
19
|
import styles from './badge.styles';
|
|
@@ -147,7 +148,7 @@ class Badge extends IconNameMixin(Component) {
|
|
|
147
148
|
*/
|
|
148
149
|
setRoleByAriaLabel() {
|
|
149
150
|
if (this.ariaLabel) {
|
|
150
|
-
this.role =
|
|
151
|
+
this.role = ROLE.IMG;
|
|
151
152
|
}
|
|
152
153
|
else {
|
|
153
154
|
this.role = null;
|
|
@@ -12,6 +12,7 @@ import { property, queryAssignedElements } from 'lit/decorators.js';
|
|
|
12
12
|
import { Component } from '../../models';
|
|
13
13
|
import { DataAriaLabelMixin } from '../../utils/mixins/DataAriaLabelMixin';
|
|
14
14
|
import { DisabledMixin } from '../../utils/mixins/DisabledMixin';
|
|
15
|
+
import { ROLE } from '../../utils/roles';
|
|
15
16
|
import { TYPE, VALID_TEXT_TAGS } from '../text/text.constants';
|
|
16
17
|
import { HEADER_ID } from './optgroup.constants';
|
|
17
18
|
import styles from './optgroup.styles';
|
|
@@ -55,12 +56,12 @@ class OptGroup extends DataAriaLabelMixin(DisabledMixin(Component)) {
|
|
|
55
56
|
` : nothing;
|
|
56
57
|
return html `
|
|
57
58
|
<div
|
|
58
|
-
role="
|
|
59
|
+
role="${ROLE.GROUP}"
|
|
59
60
|
aria-labelledby="${this.label ? HEADER_ID : ''}"
|
|
60
61
|
aria-label="${(_a = this.dataAriaLabel) !== null && _a !== void 0 ? _a : ''}"
|
|
61
62
|
>
|
|
62
63
|
${headerText}
|
|
63
|
-
<slot role="
|
|
64
|
+
<slot role="${ROLE.PRESENTATION}"></slot>
|
|
64
65
|
</div>
|
|
65
66
|
`;
|
|
66
67
|
}
|
|
@@ -41,10 +41,6 @@ declare class Option extends Option_base {
|
|
|
41
41
|
* It is called internally when the slot is changed.
|
|
42
42
|
*/
|
|
43
43
|
private handleDefaultSlotChange;
|
|
44
|
-
/**
|
|
45
|
-
* Updates the attribute of the option to reflect the current state.
|
|
46
|
-
*/
|
|
47
|
-
private updateAttribute;
|
|
48
44
|
update(changedProperties: PropertyValues): void;
|
|
49
45
|
render(): import("lit-html").TemplateResult<1>;
|
|
50
46
|
static styles: Array<CSSResult>;
|
|
@@ -51,8 +51,8 @@ class Option extends FormInternalsMixin(ListItem) {
|
|
|
51
51
|
super.connectedCallback();
|
|
52
52
|
this.role = 'option';
|
|
53
53
|
this.variant = LISTITEM_VARIANTS.INSET_RECTANGLE;
|
|
54
|
-
this.
|
|
55
|
-
this.
|
|
54
|
+
this.setAttribute('aria-selected', `${this.selected}`);
|
|
55
|
+
this.setAttribute('aria-disabled', `${!!this.disabled}`);
|
|
56
56
|
// Option will not contain below fields
|
|
57
57
|
this.name = undefined;
|
|
58
58
|
this.secondaryLabel = undefined;
|
|
@@ -71,16 +71,10 @@ class Option extends FormInternalsMixin(ListItem) {
|
|
|
71
71
|
this.label = (_c = (_b = slot.assignedNodes()[0]) === null || _b === void 0 ? void 0 : _b.textContent) === null || _c === void 0 ? void 0 : _c.trim();
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
|
-
/**
|
|
75
|
-
* Updates the attribute of the option to reflect the current state.
|
|
76
|
-
*/
|
|
77
|
-
updateAttribute(attributeName, value) {
|
|
78
|
-
this.setAttribute(attributeName, value);
|
|
79
|
-
}
|
|
80
74
|
update(changedProperties) {
|
|
81
75
|
super.update(changedProperties);
|
|
82
76
|
if (changedProperties.has('selected')) {
|
|
83
|
-
this.
|
|
77
|
+
this.setAttribute('aria-selected', `${this.selected}`);
|
|
84
78
|
}
|
|
85
79
|
}
|
|
86
80
|
render() {
|
|
@@ -370,7 +370,7 @@ class Popover extends FocusTrapMixin(Component) {
|
|
|
370
370
|
this.triggerElement.addEventListener('mouseleave', this.startCloseDelay);
|
|
371
371
|
this.addEventListener('mouseenter', this.cancelCloseDelay);
|
|
372
372
|
this.addEventListener('mouseleave', this.startCloseDelay);
|
|
373
|
-
hoverBridge === null || hoverBridge === void 0 ? void 0 : hoverBridge.addEventListener('mouseenter', this.
|
|
373
|
+
hoverBridge === null || hoverBridge === void 0 ? void 0 : hoverBridge.addEventListener('mouseenter', this.showPopover);
|
|
374
374
|
}
|
|
375
375
|
if (this.trigger.includes('focusin')) {
|
|
376
376
|
this.triggerElement.addEventListener('focusin', this.showPopover);
|
|
@@ -394,7 +394,7 @@ class Popover extends FocusTrapMixin(Component) {
|
|
|
394
394
|
this.removeEventListener('mouseleave', this.startCloseDelay);
|
|
395
395
|
this.triggerElement.removeEventListener('focusin', this.showPopover);
|
|
396
396
|
this.triggerElement.removeEventListener('focusout', this.hidePopover);
|
|
397
|
-
hoverBridge === null || hoverBridge === void 0 ? void 0 : hoverBridge.removeEventListener('mouseenter', this.
|
|
397
|
+
hoverBridge === null || hoverBridge === void 0 ? void 0 : hoverBridge.removeEventListener('mouseenter', this.showPopover);
|
|
398
398
|
this.removeEventListener('focus-trap-exit', this.hidePopover);
|
|
399
399
|
}
|
|
400
400
|
async updated(changedProperties) {
|
|
@@ -553,7 +553,7 @@ class Popover extends FocusTrapMixin(Component) {
|
|
|
553
553
|
if (this.arrowElement) {
|
|
554
554
|
const arrowLen = this.arrowElement.offsetHeight;
|
|
555
555
|
const arrowOffset = Math.sqrt(2 * arrowLen ** 2) / 2;
|
|
556
|
-
popoverOffset
|
|
556
|
+
popoverOffset += arrowOffset;
|
|
557
557
|
middleware.push(arrow({ element: this.arrowElement, padding: 12 }));
|
|
558
558
|
}
|
|
559
559
|
}
|
|
@@ -569,7 +569,7 @@ class Popover extends FocusTrapMixin(Component) {
|
|
|
569
569
|
if (middlewareData.arrow && this.arrowElement) {
|
|
570
570
|
this.utils.updateArrowStyle(middlewareData.arrow, placement);
|
|
571
571
|
}
|
|
572
|
-
if (this.trigger.includes('mouseenter')) {
|
|
572
|
+
if (this.trigger.includes('mouseenter') && this.interactive) {
|
|
573
573
|
this.utils.setupHoverBridge(placement);
|
|
574
574
|
}
|
|
575
575
|
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ROLE } from '../../utils/roles';
|
|
1
2
|
export class PopoverUtils {
|
|
2
3
|
constructor(popover) {
|
|
3
4
|
/** @internal */
|
|
@@ -89,11 +90,13 @@ export class PopoverUtils {
|
|
|
89
90
|
*/
|
|
90
91
|
setupAccessibility() {
|
|
91
92
|
var _a, _b, _c;
|
|
92
|
-
if (this.popover.role ===
|
|
93
|
-
this.popover.
|
|
93
|
+
if (this.popover.role === ROLE.DIALOG || this.popover.role === ROLE.ALERTDIALOG) {
|
|
94
|
+
this.popover.setAttribute('aria-modal', 'true');
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
this.popover.removeAttribute('aria-modal');
|
|
94
98
|
}
|
|
95
99
|
if (this.popover.interactive) {
|
|
96
|
-
this.popover.setAttribute('aria-modal', 'true');
|
|
97
100
|
if (!this.popover.ariaLabel) {
|
|
98
101
|
this.popover.ariaLabel = ((_a = this.popover.triggerElement) === null || _a === void 0 ? void 0 : _a.ariaLabel)
|
|
99
102
|
|| ((_b = this.popover.triggerElement) === null || _b === void 0 ? void 0 : _b.textContent)
|
|
@@ -103,9 +106,6 @@ export class PopoverUtils {
|
|
|
103
106
|
this.popover.ariaLabelledby = ((_c = this.popover.triggerElement) === null || _c === void 0 ? void 0 : _c.id) || '';
|
|
104
107
|
}
|
|
105
108
|
}
|
|
106
|
-
else {
|
|
107
|
-
this.popover.removeAttribute('aria-modal');
|
|
108
|
-
}
|
|
109
109
|
}
|
|
110
110
|
/**
|
|
111
111
|
* Updates the aria-haspopup attribute on the trigger element.
|
|
@@ -185,7 +185,6 @@ export class PopoverUtils {
|
|
|
185
185
|
if (!this.popover.backdropElement) {
|
|
186
186
|
const backdrop = document.createElement('div');
|
|
187
187
|
backdrop.classList.add('popover-backdrop');
|
|
188
|
-
(_a = this.popover.parentElement) === null || _a === void 0 ? void 0 : _a.appendChild(backdrop);
|
|
189
188
|
const styleElement = document.createElement('style');
|
|
190
189
|
styleElement.textContent = `
|
|
191
190
|
.popover-backdrop {
|
|
@@ -199,6 +198,7 @@ export class PopoverUtils {
|
|
|
199
198
|
}
|
|
200
199
|
`;
|
|
201
200
|
backdrop.appendChild(styleElement);
|
|
201
|
+
(_a = this.popover.parentElement) === null || _a === void 0 ? void 0 : _a.appendChild(backdrop);
|
|
202
202
|
this.popover.backdropElement = backdrop;
|
|
203
203
|
}
|
|
204
204
|
}
|
|
@@ -15,6 +15,7 @@ import FormfieldWrapper from '../formfieldwrapper';
|
|
|
15
15
|
import { DEFAULTS, VARIANT } from './progressbar.constants';
|
|
16
16
|
import { DataAriaLabelMixin } from '../../utils/mixins/DataAriaLabelMixin';
|
|
17
17
|
import { VALIDATION } from '../formfieldwrapper/formfieldwrapper.constants';
|
|
18
|
+
import { ROLE } from '../../utils/roles';
|
|
18
19
|
/**
|
|
19
20
|
* mdc-progressbar component visually represents a progress indicator, typically used to show
|
|
20
21
|
* the completion state of an ongoing process (e.g., loading, file upload, etc.).
|
|
@@ -79,7 +80,7 @@ class Progressbar extends DataAriaLabelMixin(FormfieldWrapper) {
|
|
|
79
80
|
return html `
|
|
80
81
|
<div
|
|
81
82
|
part="progress-container ${isGap ? 'gap' : ''}"
|
|
82
|
-
role="
|
|
83
|
+
role="${ROLE.PROGRESSBAR}"
|
|
83
84
|
aria-valuenow="${this.clampedValue}"
|
|
84
85
|
aria-valuemin="0"
|
|
85
86
|
aria-valuemax="100"
|
|
@@ -4,6 +4,7 @@ import { Component } from '../../models';
|
|
|
4
4
|
import Progressbar from '../progressbar/progressbar.component';
|
|
5
5
|
import { DEFAULTS, ICON_NAME } from './progressspinner.constants';
|
|
6
6
|
import { getProgressArc, getProgressOffset, getRemainingArc, getRemainingOffset } from './progressspiner.utils';
|
|
7
|
+
import { ROLE } from '../../utils/roles';
|
|
7
8
|
/**
|
|
8
9
|
* `mdc-progressspinner` is a customizable, circular progress indicator component.
|
|
9
10
|
* It visually represents the current completion state of a process, such as loading,
|
|
@@ -51,7 +52,7 @@ class Progressspinner extends Progressbar {
|
|
|
51
52
|
return html `
|
|
52
53
|
<div
|
|
53
54
|
part="spinner-container ${this.variant}"
|
|
54
|
-
role="
|
|
55
|
+
role="${ROLE.PROGRESSBAR}"
|
|
55
56
|
aria-valuenow="${this.clampedValue}"
|
|
56
57
|
aria-valuemin="0"
|
|
57
58
|
aria-valuemax="100"
|
|
@@ -16,6 +16,7 @@ import FormfieldWrapper from '../formfieldwrapper/formfieldwrapper.component';
|
|
|
16
16
|
import { DataAriaLabelMixin } from '../../utils/mixins/DataAriaLabelMixin';
|
|
17
17
|
import { FormInternalsMixin } from '../../utils/mixins/FormInternalsMixin';
|
|
18
18
|
import { DEFAULTS as FORMFIELD_DEFAULTS } from '../formfieldwrapper/formfieldwrapper.constants';
|
|
19
|
+
import { ROLE } from '../../utils/roles';
|
|
19
20
|
/**
|
|
20
21
|
* Radio allow users to select single options from a list or turn an item/feature on or off.
|
|
21
22
|
* These are often used in forms, settings, and selection in lists.
|
|
@@ -285,7 +286,7 @@ class Radio extends FormInternalsMixin(DataAriaLabelMixin(FormfieldWrapper)) {
|
|
|
285
286
|
<input
|
|
286
287
|
id="${this.id}"
|
|
287
288
|
type="radio"
|
|
288
|
-
role="
|
|
289
|
+
role="${ROLE.RADIO}"
|
|
289
290
|
?autofocus="${this.autofocus}"
|
|
290
291
|
name="${ifDefined(this.name)}"
|
|
291
292
|
value="${ifDefined(this.value)}"
|
|
@@ -55,8 +55,6 @@ declare class Select extends Select_base implements AssociatedFormControl {
|
|
|
55
55
|
displayPopover: boolean;
|
|
56
56
|
/** @internal */
|
|
57
57
|
activeDescendant: string;
|
|
58
|
-
/** @internal */
|
|
59
|
-
popoverWidth: string;
|
|
60
58
|
/**
|
|
61
59
|
* @internal
|
|
62
60
|
* The native select element
|
|
@@ -108,18 +106,10 @@ declare class Select extends Select_base implements AssociatedFormControl {
|
|
|
108
106
|
/** @internal */
|
|
109
107
|
formStateRestoreCallback(state: string): void;
|
|
110
108
|
private dispatchChange;
|
|
111
|
-
/**
|
|
112
|
-
* Handles the keydown event on the select element.
|
|
113
|
-
* If the popover is open, then it calls `handlePopoverOnOpen` with the event.
|
|
114
|
-
* If the popover is closed, then it calls `handlePopoverOnClose` with the event.
|
|
115
|
-
* @param event - The keyboard event.
|
|
116
|
-
*/
|
|
117
|
-
private handleKeydown;
|
|
118
109
|
/**
|
|
119
110
|
* Handles the keydown event on the select element when the popover is open.
|
|
120
111
|
* The options are as follows:
|
|
121
112
|
* - SPACE or ENTER: Selects the currently active option and closes the popover.
|
|
122
|
-
* - ESCAPE: Closes the popover.
|
|
123
113
|
* - HOME: Sets focus and tabindex on the first option.
|
|
124
114
|
* - END: Sets focus and tabindex on the last option.
|
|
125
115
|
* - ARROW_DOWN, ARROW_UP, PAGE_DOWN, PAGE_UP: Handles navigation between options.
|
|
@@ -9,16 +9,18 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
9
9
|
};
|
|
10
10
|
import { html, nothing } from 'lit';
|
|
11
11
|
import { property, query, queryAssignedElements, state } from 'lit/decorators.js';
|
|
12
|
+
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
12
13
|
import { KEYS } from '../../utils/keys';
|
|
13
14
|
import { DataAriaLabelMixin } from '../../utils/mixins/DataAriaLabelMixin';
|
|
14
15
|
import { FormInternalsMixin } from '../../utils/mixins/FormInternalsMixin';
|
|
16
|
+
import { ROLE } from '../../utils/roles';
|
|
15
17
|
import FormfieldWrapper from '../formfieldwrapper/formfieldwrapper.component';
|
|
16
|
-
import { DEFAULTS as FORMFIELD_DEFAULTS } from '../formfieldwrapper/formfieldwrapper.constants';
|
|
18
|
+
import { DEFAULTS as FORMFIELD_DEFAULTS, VALIDATION } from '../formfieldwrapper/formfieldwrapper.constants';
|
|
17
19
|
import { TAG_NAME as OPTION_GROUP_TAG_NAME } from '../optgroup/optgroup.constants';
|
|
18
20
|
import { TAG_NAME as OPTION_TAG_NAME } from '../option/option.constants';
|
|
19
21
|
import { POPOVER_PLACEMENT } from '../popover/popover.constants';
|
|
20
22
|
import { TYPE, VALID_TEXT_TAGS } from '../text/text.constants';
|
|
21
|
-
import { ARROW_ICON } from './select.constants';
|
|
23
|
+
import { ARROW_ICON, TRIGGER_ID } from './select.constants';
|
|
22
24
|
import styles from './select.styles';
|
|
23
25
|
/**
|
|
24
26
|
* The mdc-select component is a dropdown selection control that allows users to pick an option from a predefined list.
|
|
@@ -63,8 +65,6 @@ class Select extends FormInternalsMixin(DataAriaLabelMixin(FormfieldWrapper)) {
|
|
|
63
65
|
this.displayPopover = false;
|
|
64
66
|
/** @internal */
|
|
65
67
|
this.activeDescendant = '';
|
|
66
|
-
/** @internal */
|
|
67
|
-
this.popoverWidth = '100%';
|
|
68
68
|
}
|
|
69
69
|
connectedCallback() {
|
|
70
70
|
super.connectedCallback();
|
|
@@ -118,11 +118,10 @@ class Select extends FormInternalsMixin(DataAriaLabelMixin(FormfieldWrapper)) {
|
|
|
118
118
|
option === null || option === void 0 ? void 0 : option.removeAttribute('selected');
|
|
119
119
|
}
|
|
120
120
|
});
|
|
121
|
-
if (isTabIndexSet) {
|
|
122
|
-
|
|
121
|
+
if (!isTabIndexSet) {
|
|
122
|
+
// if no option is selected, set the first option as focused
|
|
123
|
+
(_a = this.getAllValidOptions()[0]) === null || _a === void 0 ? void 0 : _a.setAttribute('tabindex', '0');
|
|
123
124
|
}
|
|
124
|
-
// if no option is selected, set the first option as focused
|
|
125
|
-
(_a = this.getAllValidOptions()[0]) === null || _a === void 0 ? void 0 : _a.setAttribute('tabindex', '0');
|
|
126
125
|
}
|
|
127
126
|
/**
|
|
128
127
|
* A private method which is called when an option is clicked.
|
|
@@ -197,25 +196,10 @@ class Select extends FormInternalsMixin(DataAriaLabelMixin(FormfieldWrapper)) {
|
|
|
197
196
|
bubbles: true,
|
|
198
197
|
}));
|
|
199
198
|
}
|
|
200
|
-
/**
|
|
201
|
-
* Handles the keydown event on the select element.
|
|
202
|
-
* If the popover is open, then it calls `handlePopoverOnOpen` with the event.
|
|
203
|
-
* If the popover is closed, then it calls `handlePopoverOnClose` with the event.
|
|
204
|
-
* @param event - The keyboard event.
|
|
205
|
-
*/
|
|
206
|
-
handleKeydown(event) {
|
|
207
|
-
if (this.displayPopover) {
|
|
208
|
-
this.handlePopoverOnOpen(event);
|
|
209
|
-
}
|
|
210
|
-
else {
|
|
211
|
-
this.handlePopoverOnClose(event);
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
199
|
/**
|
|
215
200
|
* Handles the keydown event on the select element when the popover is open.
|
|
216
201
|
* The options are as follows:
|
|
217
202
|
* - SPACE or ENTER: Selects the currently active option and closes the popover.
|
|
218
|
-
* - ESCAPE: Closes the popover.
|
|
219
203
|
* - HOME: Sets focus and tabindex on the first option.
|
|
220
204
|
* - END: Sets focus and tabindex on the last option.
|
|
221
205
|
* - ARROW_DOWN, ARROW_UP, PAGE_DOWN, PAGE_UP: Handles navigation between options.
|
|
@@ -224,6 +208,12 @@ class Select extends FormInternalsMixin(DataAriaLabelMixin(FormfieldWrapper)) {
|
|
|
224
208
|
handlePopoverOnOpen(event) {
|
|
225
209
|
var _a;
|
|
226
210
|
switch (event.key) {
|
|
211
|
+
case KEYS.TAB: {
|
|
212
|
+
const focusedOptionIndex = this.getAllValidOptions().findIndex((option) => option === event.target);
|
|
213
|
+
this.setFocusAndTabIndex(focusedOptionIndex);
|
|
214
|
+
event.preventDefault();
|
|
215
|
+
break;
|
|
216
|
+
}
|
|
227
217
|
case KEYS.SPACE:
|
|
228
218
|
this.updateTabIndexForAllOptions(event.target);
|
|
229
219
|
this.closePopover();
|
|
@@ -236,10 +226,6 @@ class Select extends FormInternalsMixin(DataAriaLabelMixin(FormfieldWrapper)) {
|
|
|
236
226
|
// if the popover is closed, then we submit the form.
|
|
237
227
|
(_a = this.form) === null || _a === void 0 ? void 0 : _a.requestSubmit();
|
|
238
228
|
break;
|
|
239
|
-
case KEYS.ESCAPE:
|
|
240
|
-
this.closePopover();
|
|
241
|
-
event.stopPropagation();
|
|
242
|
-
break;
|
|
243
229
|
case KEYS.HOME:
|
|
244
230
|
this.setFocusAndTabIndex(0);
|
|
245
231
|
event.preventDefault();
|
|
@@ -253,7 +239,7 @@ class Select extends FormInternalsMixin(DataAriaLabelMixin(FormfieldWrapper)) {
|
|
|
253
239
|
case KEYS.PAGE_DOWN:
|
|
254
240
|
case KEYS.PAGE_UP:
|
|
255
241
|
this.handleOptionsNavigation(event);
|
|
256
|
-
|
|
242
|
+
event.preventDefault();
|
|
257
243
|
break;
|
|
258
244
|
default:
|
|
259
245
|
break;
|
|
@@ -339,24 +325,44 @@ class Select extends FormInternalsMixin(DataAriaLabelMixin(FormfieldWrapper)) {
|
|
|
339
325
|
return -1;
|
|
340
326
|
}
|
|
341
327
|
updateActivedescendant(target) {
|
|
342
|
-
var _a, _b;
|
|
343
|
-
const
|
|
344
|
-
|
|
328
|
+
var _a, _b, _c, _d, _e;
|
|
329
|
+
const options = this.getAllValidOptions();
|
|
330
|
+
if (target) {
|
|
331
|
+
const currentIndex = options.findIndex((option) => option === target);
|
|
332
|
+
this.activeDescendant = (_b = (_a = options[currentIndex]) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : '';
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
335
|
+
// If no target is provided, find the option with tabindex="0" or the first option
|
|
336
|
+
const focusedOption = options.find((option) => option.getAttribute('tabindex') === '0');
|
|
337
|
+
this.activeDescendant = (_e = (_c = focusedOption === null || focusedOption === void 0 ? void 0 : focusedOption.id) !== null && _c !== void 0 ? _c : (_d = options[0]) === null || _d === void 0 ? void 0 : _d.id) !== null && _e !== void 0 ? _e : '';
|
|
338
|
+
}
|
|
345
339
|
}
|
|
346
340
|
resetActivedescendant() {
|
|
347
341
|
this.activeDescendant = '';
|
|
348
342
|
}
|
|
349
343
|
setFocusAndTabIndex(newIndex) {
|
|
350
344
|
var _a;
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
345
|
+
const options = this.getAllValidOptions();
|
|
346
|
+
const targetOption = options[newIndex];
|
|
347
|
+
if (targetOption) {
|
|
348
|
+
targetOption.focus();
|
|
349
|
+
options.forEach((node, index) => {
|
|
350
|
+
const newTabindex = newIndex === index ? '0' : '-1';
|
|
351
|
+
node === null || node === void 0 ? void 0 : node.setAttribute('tabindex', newTabindex);
|
|
352
|
+
});
|
|
353
|
+
// Update activeDescendant after changing focus
|
|
354
|
+
this.activeDescendant = (_a = targetOption.id) !== null && _a !== void 0 ? _a : '';
|
|
355
|
+
}
|
|
356
356
|
}
|
|
357
357
|
openPopover() {
|
|
358
|
+
var _a, _b;
|
|
358
359
|
this.displayPopover = true;
|
|
359
|
-
|
|
360
|
+
// Find the currently selected option or the first option
|
|
361
|
+
const options = this.getAllValidOptions();
|
|
362
|
+
const selectedOption = options.find((option) => option.hasAttribute('selected'));
|
|
363
|
+
const focusedOption = options.find((option) => option.getAttribute('tabindex') === '0');
|
|
364
|
+
// Set activeDescendant to the selected/focused option or first option
|
|
365
|
+
this.activeDescendant = (_b = (_a = (selectedOption || focusedOption || options[0])) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : '';
|
|
360
366
|
}
|
|
361
367
|
closePopover() {
|
|
362
368
|
this.displayPopover = false;
|
|
@@ -398,6 +404,7 @@ class Select extends FormInternalsMixin(DataAriaLabelMixin(FormfieldWrapper)) {
|
|
|
398
404
|
part="native-select"
|
|
399
405
|
id="${this.id}"
|
|
400
406
|
tabindex="-1"
|
|
407
|
+
aria-hidden="true"
|
|
401
408
|
name="${this.name}"
|
|
402
409
|
size="1"
|
|
403
410
|
.value="${this.selectedValue}"
|
|
@@ -449,21 +456,23 @@ class Select extends FormInternalsMixin(DataAriaLabelMixin(FormfieldWrapper)) {
|
|
|
449
456
|
return html `
|
|
450
457
|
<mdc-popover
|
|
451
458
|
id="options-popover"
|
|
452
|
-
triggerid="
|
|
453
|
-
@keydown="${this.
|
|
459
|
+
triggerid="${TRIGGER_ID}"
|
|
460
|
+
@keydown="${this.handlePopoverOnOpen}"
|
|
454
461
|
interactive
|
|
455
462
|
?visible="${this.displayPopover}"
|
|
456
463
|
hide-on-outside-click
|
|
464
|
+
hide-on-escape
|
|
457
465
|
focus-back-to-trigger
|
|
458
466
|
focus-trap
|
|
459
|
-
role="
|
|
467
|
+
role="${ROLE.LISTBOX}"
|
|
460
468
|
placement="${POPOVER_PLACEMENT.BOTTOM_START}"
|
|
461
469
|
@shown="${this.handlePopoverOpen}"
|
|
462
470
|
@hidden="${this.handlePopoverClose}"
|
|
463
|
-
style="--mdc-popover-max-width:
|
|
471
|
+
style="--mdc-popover-max-width: 100%; --mdc-popover-max-height: ${this.height};"
|
|
464
472
|
>
|
|
465
|
-
|
|
466
|
-
|
|
473
|
+
<slot
|
|
474
|
+
@click="${this.handleOptionsClick}"></slot>
|
|
475
|
+
</mdc-popover>
|
|
467
476
|
`;
|
|
468
477
|
}
|
|
469
478
|
updated(changedProperties) {
|
|
@@ -472,6 +481,14 @@ class Select extends FormInternalsMixin(DataAriaLabelMixin(FormfieldWrapper)) {
|
|
|
472
481
|
this.closePopover();
|
|
473
482
|
this.handlePopoverClose();
|
|
474
483
|
}
|
|
484
|
+
if (changedProperties.has('displayPopover')) {
|
|
485
|
+
if (this.displayPopover) {
|
|
486
|
+
this.openPopover();
|
|
487
|
+
}
|
|
488
|
+
else {
|
|
489
|
+
this.closePopover();
|
|
490
|
+
}
|
|
491
|
+
}
|
|
475
492
|
}
|
|
476
493
|
render() {
|
|
477
494
|
var _a, _b;
|
|
@@ -479,18 +496,19 @@ class Select extends FormInternalsMixin(DataAriaLabelMixin(FormfieldWrapper)) {
|
|
|
479
496
|
${this.renderLabel()}
|
|
480
497
|
<div part="container">
|
|
481
498
|
<div
|
|
482
|
-
id="
|
|
499
|
+
id="${TRIGGER_ID}"
|
|
483
500
|
part="base-container"
|
|
484
|
-
@keydown="${this.
|
|
501
|
+
@keydown="${this.handlePopoverOnClose}"
|
|
485
502
|
tabindex="${this.disabled ? '-1' : '0'}"
|
|
486
503
|
class="${this.disabled ? '' : 'mdc-focus-ring'}"
|
|
487
|
-
role="
|
|
488
|
-
aria-activedescendant="${this.activeDescendant}"
|
|
489
|
-
aria-
|
|
504
|
+
role="${ROLE.COMBOBOX}"
|
|
505
|
+
aria-activedescendant="${ifDefined(this.activeDescendant || undefined)}"
|
|
506
|
+
aria-controls="${(ifDefined(this.displayPopover ? 'options-popover' : undefined))}"
|
|
490
507
|
aria-label="${(_a = this.dataAriaLabel) !== null && _a !== void 0 ? _a : ''}"
|
|
491
508
|
aria-labelledby="${this.label ? FORMFIELD_DEFAULTS.HEADING_ID : ''}"
|
|
492
509
|
aria-expanded="${this.displayPopover ? 'true' : 'false'}"
|
|
493
|
-
aria-
|
|
510
|
+
aria-required="${this.required ? 'true' : 'false'}"
|
|
511
|
+
aria-invalid="${this.helpTextType === VALIDATION.ERROR ? 'true' : 'false'}"
|
|
494
512
|
>
|
|
495
513
|
${this.selectedIcon
|
|
496
514
|
? html `<mdc-icon length-unit="rem" size="1" name="${this.selectedIcon}" part="selected-icon"></mdc-icon>`
|
|
@@ -554,10 +572,6 @@ __decorate([
|
|
|
554
572
|
state(),
|
|
555
573
|
__metadata("design:type", Object)
|
|
556
574
|
], Select.prototype, "activeDescendant", void 0);
|
|
557
|
-
__decorate([
|
|
558
|
-
state(),
|
|
559
|
-
__metadata("design:type", Object)
|
|
560
|
-
], Select.prototype, "popoverWidth", void 0);
|
|
561
575
|
__decorate([
|
|
562
576
|
query('select'),
|
|
563
577
|
__metadata("design:type", HTMLInputElement)
|
|
@@ -28,7 +28,7 @@ const styles = css `
|
|
|
28
28
|
padding: 0;
|
|
29
29
|
position: absolute;
|
|
30
30
|
width: 100%;
|
|
31
|
-
height:
|
|
31
|
+
height: 0;
|
|
32
32
|
z-index: -1;
|
|
33
33
|
}
|
|
34
34
|
:host::part(container) {
|
|
@@ -75,6 +75,7 @@ const styles = css `
|
|
|
75
75
|
}
|
|
76
76
|
:host::part(popover-content) {
|
|
77
77
|
min-width: auto;
|
|
78
|
+
overflow: scroll;
|
|
78
79
|
}
|
|
79
80
|
:host([disabled])::part(base-container),
|
|
80
81
|
:host([readonly])::part(base-container),
|
|
@@ -12,6 +12,7 @@ import { property } from 'lit/decorators.js';
|
|
|
12
12
|
import styles from './spinner.styles';
|
|
13
13
|
import { Component } from '../../models';
|
|
14
14
|
import { DEFAULTS } from './spinner.constants';
|
|
15
|
+
import { ROLE } from '../../utils/roles';
|
|
15
16
|
/**
|
|
16
17
|
* `mdc-spinner` is loading spinner which is an indeterminate progress indicator, meaning
|
|
17
18
|
* it's best for cases where the progress or duration of a process is variable or unknown.
|
|
@@ -85,7 +86,7 @@ class Spinner extends Component {
|
|
|
85
86
|
updated(changedProperties) {
|
|
86
87
|
super.updated(changedProperties);
|
|
87
88
|
if (changedProperties.has('ariaLabel')) {
|
|
88
|
-
this.role = this.ariaLabel ?
|
|
89
|
+
this.role = this.ariaLabel ? ROLE.IMG : null;
|
|
89
90
|
this.ariaHidden = this.ariaLabel ? 'false' : 'true';
|
|
90
91
|
}
|
|
91
92
|
}
|
|
@@ -15,6 +15,7 @@ import { getIconNameWithoutStyle } from '../button/button.utils';
|
|
|
15
15
|
import Buttonsimple from '../buttonsimple/buttonsimple.component';
|
|
16
16
|
import { TYPE, VALID_TEXT_TAGS } from '../text/text.constants';
|
|
17
17
|
import { IconNameMixin } from '../../utils/mixins/IconNameMixin';
|
|
18
|
+
import { ROLE } from '../../utils/roles';
|
|
18
19
|
/**
|
|
19
20
|
* `mdc-tab` is Tab component to be used within the Tabgroup.
|
|
20
21
|
*
|
|
@@ -152,7 +153,7 @@ class Tab extends IconNameMixin(Buttonsimple) {
|
|
|
152
153
|
}
|
|
153
154
|
connectedCallback() {
|
|
154
155
|
super.connectedCallback();
|
|
155
|
-
this.role =
|
|
156
|
+
this.role = ROLE.TAB;
|
|
156
157
|
this.softDisabled = undefined;
|
|
157
158
|
this.size = undefined;
|
|
158
159
|
this.type = undefined;
|
|
@@ -16,6 +16,7 @@ import { ARROW_BUTTON_DIRECTION, KEYCODES } from './tablist.constants';
|
|
|
16
16
|
import Tab from '../tab/tab.component';
|
|
17
17
|
import Button from '../button/button.component';
|
|
18
18
|
import { getFirstTab, getLastTab, getNextTab, getPreviousTab, findTab, getActiveTab } from './tablist.utils';
|
|
19
|
+
import { ROLE } from '../../utils/roles';
|
|
19
20
|
/**
|
|
20
21
|
* Tab list organizes tabs into a container.
|
|
21
22
|
*
|
|
@@ -443,7 +444,7 @@ class TabList extends Component {
|
|
|
443
444
|
return html ` ${arrowButton('backward')}
|
|
444
445
|
<div
|
|
445
446
|
class="container"
|
|
446
|
-
role="
|
|
447
|
+
role="${ROLE.TABLIST}"
|
|
447
448
|
tabindex="-1"
|
|
448
449
|
aria-label="${ifDefined(this.dataAriaLabel)}">
|
|
449
450
|
<slot></slot>
|
|
@@ -12,6 +12,7 @@ import { property } from 'lit/decorators.js';
|
|
|
12
12
|
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
13
13
|
import { DataAriaLabelMixin } from '../../utils/mixins/DataAriaLabelMixin';
|
|
14
14
|
import { FormInternalsMixin } from '../../utils/mixins/FormInternalsMixin';
|
|
15
|
+
import { ROLE } from '../../utils/roles';
|
|
15
16
|
import FormfieldWrapper from '../formfieldwrapper';
|
|
16
17
|
import { DEFAULTS as FORMFIELD_DEFAULTS } from '../formfieldwrapper/formfieldwrapper.constants';
|
|
17
18
|
import { DEFAULTS, TOGGLE_SIZE } from './toggle.constants';
|
|
@@ -189,7 +190,7 @@ class Toggle extends FormInternalsMixin(DataAriaLabelMixin(FormfieldWrapper)) {
|
|
|
189
190
|
id="${this.id}"
|
|
190
191
|
type="checkbox"
|
|
191
192
|
part="toggle-input"
|
|
192
|
-
role="
|
|
193
|
+
role="${ROLE.CHECKBOX}"
|
|
193
194
|
?autofocus="${this.autofocus}"
|
|
194
195
|
?required="${this.required}"
|
|
195
196
|
name="${ifDefined(this.name)}"
|