@momentum-design/components 0.85.6 → 0.85.7
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 +225 -201
- package/dist/browser/index.js.map +4 -4
- package/dist/components/menuitem/menuitem.component.d.ts +21 -1
- package/dist/components/menuitem/menuitem.component.js +29 -1
- package/dist/components/menuitemcheckbox/menuitemcheckbox.component.d.ts +26 -15
- package/dist/components/menuitemcheckbox/menuitemcheckbox.component.js +42 -25
- package/dist/components/menuitemcheckbox/menuitemcheckbox.constants.d.ts +1 -1
- package/dist/components/menuitemcheckbox/menuitemcheckbox.constants.js +1 -2
- package/dist/components/menuitemcheckbox/menuitemcheckbox.styles.js +0 -6
- package/dist/components/menuitemradio/menuitemradio.component.d.ts +61 -12
- package/dist/components/menuitemradio/menuitemradio.component.js +125 -40
- package/dist/components/menuitemradio/menuitemradio.constants.d.ts +9 -1
- package/dist/components/menuitemradio/menuitemradio.constants.js +9 -1
- package/dist/components/menuitemradio/menuitemradio.styles.d.ts +2 -0
- package/dist/components/menuitemradio/menuitemradio.styles.js +7 -0
- package/dist/components/menuitemradio/menuitemradio.types.d.ts +4 -1
- package/dist/components/menupopover/menupopover.component.d.ts +6 -0
- package/dist/components/menupopover/menupopover.component.js +11 -3
- package/dist/components/menupopover/menupopover.styles.js +4 -0
- package/dist/components/menupopover/menupopover.types.d.ts +11 -0
- package/dist/components/menupopover/menupopover.types.js +1 -0
- package/dist/components/menupopover/menupopover.utils.d.ts +4 -2
- package/dist/components/menupopover/menupopover.utils.js +1 -1
- package/dist/components/menusection/menusection.component.d.ts +15 -2
- package/dist/components/menusection/menusection.component.js +55 -4
- package/dist/components/menusection/menusection.constants.d.ts +1 -5
- package/dist/components/menusection/menusection.constants.js +1 -5
- package/dist/components/menusection/menusection.styles.d.ts +2 -0
- package/dist/components/menusection/menusection.styles.js +11 -0
- package/dist/components/menusection/menusection.types.d.ts +7 -4
- package/dist/custom-elements.json +611 -293
- package/dist/index.d.ts +3 -1
- package/dist/react/menuitem/index.d.ts +12 -1
- package/dist/react/menuitem/index.js +12 -1
- package/dist/react/menuitemcheckbox/index.d.ts +18 -7
- package/dist/react/menuitemcheckbox/index.js +18 -7
- package/dist/react/menuitemradio/index.d.ts +25 -2
- package/dist/react/menuitemradio/index.js +25 -2
- package/dist/react/menupopover/index.d.ts +8 -0
- package/dist/react/menupopover/index.js +8 -0
- package/dist/react/menusection/index.d.ts +6 -1
- package/dist/react/menusection/index.js +5 -1
- package/dist/utils/types.d.ts +10 -0
- package/package.json +1 -1
@@ -7,29 +7,54 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
7
7
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
8
8
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
9
9
|
};
|
10
|
-
import { html } from 'lit';
|
10
|
+
import { html, nothing } from 'lit';
|
11
11
|
import { property } from 'lit/decorators.js';
|
12
12
|
import { ROLE } from '../../utils/roles';
|
13
13
|
import MenuItem from '../menuitem/menuitem.component';
|
14
14
|
import { TYPE } from '../text/text.constants';
|
15
|
-
import {
|
15
|
+
import { TAG_NAME as MENUSECTION_TAGNAME } from '../menusection/menusection.constants';
|
16
16
|
import { TAG_NAME as MENUPOPOVER_TAGNAME } from '../menupopover/menupopover.constants';
|
17
|
+
import { INDICATOR, DEFAULTS } from './menuitemradio.constants';
|
18
|
+
import styles from './menuitemradio.styles';
|
17
19
|
/**
|
18
20
|
* A menuitemradio component is a checkable menuitem that is used in a menu.
|
19
21
|
* A menuitemradio should be checked only one at a time. <br/>
|
20
22
|
* There should be no focusable descendants inside this menuitemradio component.
|
21
23
|
*
|
22
|
-
* The `
|
24
|
+
* The `checked` menuitemradio attribute is used to indicate that the menuitemradio is checked or not.
|
25
|
+
*
|
26
|
+
* Menu item radio has `name` and `value` attribute that can be used to identify the menu item when it is selected.
|
23
27
|
*
|
24
28
|
* If you want more than one item in a group to be checked, consider using menuitemcheckbox component.
|
25
29
|
*
|
26
|
-
*
|
30
|
+
* The `indicator` attribute is used to differentiate between <b>radio</b>, <b>checkmark</b> and <b>none</b>.
|
31
|
+
* By default, the `indicator` is set to <b>radio</b>.<br/>
|
32
|
+
*
|
33
|
+
* The checkbox will always be positioned on the leading side of the menuitem label and
|
34
|
+
* the checkmark will always be positioned on the trailing side.
|
35
|
+
*
|
36
|
+
* The radio will have the possible states of `true` or `false`.
|
37
|
+
* If the indicator is set to <b>checkmark</b> and if the `checked` attribute is set to `true`,
|
38
|
+
* then the checkmark will be displayed. if not, then no indicator will be displayed.
|
39
|
+
*
|
40
|
+
* The third options for the `indicator` is <b>none</b>, which will not display any indicator at all.
|
41
|
+
* It is intended to be used for customised menu items where the indicator is implemented differently.
|
42
|
+
* For example, you can use a custom icon or a different visual element to indicate the state of the menu item.
|
43
|
+
* Make sure the new indicator is accessible.
|
27
44
|
*
|
28
45
|
* @dependency mdc-staticradio
|
29
46
|
* @dependency mdc-text
|
30
47
|
*
|
31
48
|
* @tagname mdc-menuitemradio
|
32
49
|
*
|
50
|
+
* @slot leading-controls - slot for menu item radio controls to appear of leading end.
|
51
|
+
* @slot leading-text-primary-label - slot for menu item radio primary label.
|
52
|
+
* @slot leading-text-secondary-label - slot for menu item radio secondary label.
|
53
|
+
* @slot leading-text-tertiary-label - slot for menu item radio tertiary label.
|
54
|
+
* @slot trailing-text-side-header - slot for menu item radio side header text.
|
55
|
+
* @slot trailing-text-subline - slot for menu item radio subline text.
|
56
|
+
* @slot trailing-controls - slot for menu item radio controls to appear of trailing end.
|
57
|
+
*
|
33
58
|
* @event change - (React: onChange) This event is dispatched when the menuitemradio changes.
|
34
59
|
* @event click - (React: onClick) This event is dispatched when the menuitemradio is clicked.
|
35
60
|
* @event focus - (React: onFocus) This event is dispatched when the menuitemradio receives focus.
|
@@ -39,63 +64,123 @@ class MenuItemRadio extends MenuItem {
|
|
39
64
|
super();
|
40
65
|
/**
|
41
66
|
* The aria-checked attribute is used to indicate that the menuitemradio is checked or not.
|
42
|
-
* @default
|
67
|
+
* @default false
|
43
68
|
*/
|
44
|
-
this.
|
69
|
+
this.checked = false;
|
45
70
|
/**
|
46
|
-
* The
|
71
|
+
* The indicator attribute is used to differentiate between <b>radio</b>, <b>checkmark</b> and <b>none</b>.
|
72
|
+
* @default 'radio'
|
47
73
|
*/
|
48
|
-
this.
|
74
|
+
this.indicator = DEFAULTS.INDICATOR;
|
49
75
|
/**
|
50
76
|
* Handles click events to set checked state and uncheck siblings in the same group and container.
|
51
|
-
* If the menuitemradio is not checked, it sets its
|
52
|
-
* and sets all other menuitemradio elements of the same group with
|
77
|
+
* If the menuitemradio is not checked, it sets its checked state to `true`
|
78
|
+
* and sets all other menuitemradio elements of the same group with checked state to `false`.
|
53
79
|
*/
|
54
|
-
this.
|
55
|
-
|
80
|
+
this.radioHandleClick = (event) => {
|
81
|
+
event.stopPropagation();
|
82
|
+
if (this.disabled || this.checked)
|
56
83
|
return;
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
const radios = Array.from(container.querySelectorAll(this.tagName));
|
61
|
-
radios.forEach(item => {
|
62
|
-
const radio = item;
|
63
|
-
if (radio.name === this.name) {
|
64
|
-
radio.ariaChecked = ARIA_CHECKED_STATES.FALSE;
|
65
|
-
}
|
66
|
-
});
|
67
|
-
}
|
68
|
-
this.ariaChecked = ARIA_CHECKED_STATES.TRUE;
|
84
|
+
this.updateOtherRadiosCheckedState();
|
85
|
+
this.checked = true;
|
86
|
+
this.dispatchEvent(new Event('change', { bubbles: true, composed: true }));
|
69
87
|
};
|
70
|
-
this.addEventListener('click', this.
|
88
|
+
this.addEventListener('click', this.radioHandleClick);
|
71
89
|
}
|
72
90
|
connectedCallback() {
|
73
91
|
super.connectedCallback();
|
74
92
|
this.role = ROLE.MENUITEMRADIO;
|
75
93
|
}
|
94
|
+
/**
|
95
|
+
* Returns all radios within the same group (name).
|
96
|
+
*/
|
97
|
+
getAllRadiosWithinSameGroup() {
|
98
|
+
const container = this.closest(`${MENUSECTION_TAGNAME}, ${MENUPOPOVER_TAGNAME}`);
|
99
|
+
if (!container || !this.name)
|
100
|
+
return [];
|
101
|
+
return Array.from(container.querySelectorAll(`${this.tagName}[name="${this.name}"]`));
|
102
|
+
}
|
103
|
+
/**
|
104
|
+
* Updates the checked state of all other radios in the same group.
|
105
|
+
* This method is called when a radio is clicked to ensure that only one radio in the group can be checked at a time.
|
106
|
+
* It sets the `checked` property of all other radios in the same group to `false`.
|
107
|
+
*/
|
108
|
+
updateOtherRadiosCheckedState() {
|
109
|
+
const radios = this.getAllRadiosWithinSameGroup();
|
110
|
+
radios.forEach(radio => {
|
111
|
+
// eslint-disable-next-line no-param-reassign
|
112
|
+
if (radio !== this)
|
113
|
+
radio.checked = false;
|
114
|
+
});
|
115
|
+
}
|
116
|
+
update(changedProperties) {
|
117
|
+
super.update(changedProperties);
|
118
|
+
if (changedProperties.has('checked')) {
|
119
|
+
this.ariaChecked = `${this.checked}`;
|
120
|
+
if (changedProperties.get('checked') === false && this.checked) {
|
121
|
+
this.updateOtherRadiosCheckedState();
|
122
|
+
}
|
123
|
+
}
|
124
|
+
}
|
125
|
+
/**
|
126
|
+
* Returns a static checkbox element if the indicator is set to checkbox.
|
127
|
+
* If the indicator is not set to checkbox, it returns nothing.
|
128
|
+
* @returns TemplateResult | typeof nothing
|
129
|
+
*/
|
130
|
+
renderStaticRadio() {
|
131
|
+
if (this.indicator !== INDICATOR.RADIO) {
|
132
|
+
return nothing;
|
133
|
+
}
|
134
|
+
return html `
|
135
|
+
<mdc-staticradio
|
136
|
+
slot="leading-controls"
|
137
|
+
?checked="${this.checked}"
|
138
|
+
?disabled="${this.disabled}"
|
139
|
+
></mdc-staticradio>
|
140
|
+
`;
|
141
|
+
}
|
142
|
+
/**
|
143
|
+
* Returns a checkmark icon if the indicator is set to checkmark and the checked state is true.
|
144
|
+
* If the indicator is not set to checkmark or the checked state is false, it returns nothing.
|
145
|
+
*
|
146
|
+
* The checkmark icon will always be positioned on the trailing side of the menuitem label.
|
147
|
+
* @returns TemplateResult | typeof nothing
|
148
|
+
*/
|
149
|
+
renderCheckmarkIcon() {
|
150
|
+
if (this.checked && this.indicator === INDICATOR.CHECKMARK) {
|
151
|
+
return html ` <mdc-icon slot="trailing-controls" name="check-bold" part="checkmark-icon"></mdc-icon> `;
|
152
|
+
}
|
153
|
+
return nothing;
|
154
|
+
}
|
76
155
|
render() {
|
77
156
|
return html `
|
78
|
-
<div part="leading
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
157
|
+
<div part="leading">
|
158
|
+
${this.renderStaticRadio()}
|
159
|
+
<slot name="leading-controls"></slot>
|
160
|
+
<div part="leading-text">
|
161
|
+
${this.getText('leading-text-primary-label', TYPE.BODY_MIDSIZE_REGULAR, this.label)}
|
162
|
+
${this.getText('leading-text-secondary-label', TYPE.BODY_SMALL_REGULAR, this.secondaryLabel)}
|
163
|
+
${this.getText('leading-text-tertiary-label', TYPE.BODY_SMALL_REGULAR, this.tertiaryLabel)}
|
164
|
+
</div>
|
84
165
|
</div>
|
85
|
-
<div part="
|
86
|
-
|
87
|
-
|
166
|
+
<div part="trailing">
|
167
|
+
<div part="trailing-text">
|
168
|
+
${this.getText('trailing-text-side-header', TYPE.BODY_MIDSIZE_REGULAR, this.sideHeaderText)}
|
169
|
+
${this.getText('trailing-text-subline', TYPE.BODY_SMALL_REGULAR, this.sublineText)}
|
170
|
+
</div>
|
171
|
+
<slot name="trailing-controls"></slot>
|
172
|
+
${this.renderCheckmarkIcon()}
|
88
173
|
</div>
|
89
174
|
`;
|
90
175
|
}
|
91
176
|
}
|
92
|
-
MenuItemRadio.styles = [...MenuItem.styles];
|
177
|
+
MenuItemRadio.styles = [...MenuItem.styles, ...styles];
|
93
178
|
__decorate([
|
94
|
-
property({ type:
|
95
|
-
__metadata("design:type",
|
96
|
-
], MenuItemRadio.prototype, "
|
179
|
+
property({ type: Boolean, reflect: true }),
|
180
|
+
__metadata("design:type", Boolean)
|
181
|
+
], MenuItemRadio.prototype, "checked", void 0);
|
97
182
|
__decorate([
|
98
183
|
property({ type: String, reflect: true }),
|
99
|
-
__metadata("design:type",
|
100
|
-
], MenuItemRadio.prototype, "
|
184
|
+
__metadata("design:type", String)
|
185
|
+
], MenuItemRadio.prototype, "indicator", void 0);
|
101
186
|
export default MenuItemRadio;
|
@@ -1,2 +1,10 @@
|
|
1
1
|
declare const TAG_NAME: "mdc-menuitemradio";
|
2
|
-
|
2
|
+
declare const INDICATOR: {
|
3
|
+
readonly NONE: "none";
|
4
|
+
readonly RADIO: "radio";
|
5
|
+
readonly CHECKMARK: "checkmark";
|
6
|
+
};
|
7
|
+
declare const DEFAULTS: {
|
8
|
+
readonly INDICATOR: "radio";
|
9
|
+
};
|
10
|
+
export { TAG_NAME, INDICATOR, DEFAULTS };
|
@@ -1,3 +1,11 @@
|
|
1
1
|
import utils from '../../utils/tag-name';
|
2
2
|
const TAG_NAME = utils.constructTagName('menuitemradio');
|
3
|
-
|
3
|
+
const INDICATOR = {
|
4
|
+
NONE: 'none',
|
5
|
+
RADIO: 'radio',
|
6
|
+
CHECKMARK: 'checkmark',
|
7
|
+
};
|
8
|
+
const DEFAULTS = {
|
9
|
+
INDICATOR: INDICATOR.RADIO,
|
10
|
+
};
|
11
|
+
export { TAG_NAME, INDICATOR, DEFAULTS };
|
@@ -1,6 +1,9 @@
|
|
1
|
+
import { ValueOf } from '../../utils/types';
|
2
|
+
import { INDICATOR } from './menuitemradio.constants';
|
3
|
+
type Indicator = ValueOf<typeof INDICATOR>;
|
1
4
|
interface Events {
|
2
5
|
onChangeEvent: Event;
|
3
6
|
onClickEvent: MouseEvent;
|
4
7
|
onFocusEvent: FocusEvent;
|
5
8
|
}
|
6
|
-
export type { Events };
|
9
|
+
export type { Events, Indicator };
|
@@ -19,6 +19,12 @@ import { PopoverPlacement } from '../popover/popover.types';
|
|
19
19
|
* The orientation of the menu popover is always set to `vertical`.
|
20
20
|
*
|
21
21
|
* @tagname mdc-menupopover
|
22
|
+
*
|
23
|
+
* @slot - Default slot for the menu popover content
|
24
|
+
*
|
25
|
+
* @event change - (React: onChange) This event is dispatched when a `menuitemcheckbox`, or `menuitemradio` changes.
|
26
|
+
* @event action - (React: onAction) This event is dispatched when a menuItem selected and the menu closes.
|
27
|
+
*
|
22
28
|
* @slot default - Contains the menu items to be displayed in the popover
|
23
29
|
*/
|
24
30
|
declare class MenuPopover extends Popover {
|
@@ -35,6 +35,12 @@ import { isActiveMenuItem, isValidMenuItem, isValidPopover } from './menupopover
|
|
35
35
|
* The orientation of the menu popover is always set to `vertical`.
|
36
36
|
*
|
37
37
|
* @tagname mdc-menupopover
|
38
|
+
*
|
39
|
+
* @slot - Default slot for the menu popover content
|
40
|
+
*
|
41
|
+
* @event change - (React: onChange) This event is dispatched when a `menuitemcheckbox`, or `menuitemradio` changes.
|
42
|
+
* @event action - (React: onAction) This event is dispatched when a menuItem selected and the menu closes.
|
43
|
+
*
|
38
44
|
* @slot default - Contains the menu items to be displayed in the popover
|
39
45
|
*/
|
40
46
|
class MenuPopover extends Popover {
|
@@ -73,9 +79,8 @@ class MenuPopover extends Popover {
|
|
73
79
|
this.closeAllMenuPopovers(popoverOfTarget);
|
74
80
|
return;
|
75
81
|
}
|
76
|
-
let insidePopoverClick = false;
|
77
82
|
const path = event.composedPath();
|
78
|
-
insidePopoverClick = this.contains(event.target) || path.includes(this.triggerElement);
|
83
|
+
const insidePopoverClick = this.contains(event.target) || path.includes(this.triggerElement);
|
79
84
|
const clickedOnBackdrop = this.backdropElement ? path.includes(this.backdropElement) : false;
|
80
85
|
if (!insidePopoverClick || clickedOnBackdrop) {
|
81
86
|
this.closeAllMenuPopovers();
|
@@ -199,8 +204,11 @@ class MenuPopover extends Popover {
|
|
199
204
|
const target = event.target;
|
200
205
|
const triggerId = target.getAttribute('id');
|
201
206
|
if (isActiveMenuItem(target) && // menuitemcheckbox and menuitemradio are not supposed to close the popover
|
202
|
-
!this.hasSubmenuWithTriggerId(triggerId)
|
207
|
+
!this.hasSubmenuWithTriggerId(triggerId) &&
|
208
|
+
this === target.closest(MENU_POPOVER) // Ensure close all popover called only once
|
209
|
+
) {
|
203
210
|
this.closeAllMenuPopovers();
|
211
|
+
target.dispatchEvent(new Event('action', { bubbles: true, composed: true }));
|
204
212
|
}
|
205
213
|
}
|
206
214
|
/**
|
@@ -0,0 +1,11 @@
|
|
1
|
+
import type MenuItem from '../menuitem';
|
2
|
+
export type MenuPopoverChangeEvent = Event & {
|
3
|
+
target: MenuItem;
|
4
|
+
};
|
5
|
+
export type MenuPopoverActionEvent = Event & {
|
6
|
+
target: MenuItem;
|
7
|
+
};
|
8
|
+
export interface Events {
|
9
|
+
onChangeEvent: MenuPopoverChangeEvent;
|
10
|
+
onActionEvent: MenuPopoverActionEvent;
|
11
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -1,9 +1,11 @@
|
|
1
|
+
import type MenuItem from '../menuitem';
|
2
|
+
import type MenuPopover from './menupopover.component';
|
1
3
|
/**
|
2
4
|
* Checks if the given menu item is a valid menu item.
|
3
5
|
* @param menuItem - The menu item to check.
|
4
6
|
* @returns True if the menu item is a valid menu item, false otherwise.
|
5
7
|
*/
|
6
8
|
declare const isValidMenuItem: (menuItem: Element | null) => boolean;
|
7
|
-
declare const isValidPopover: (
|
8
|
-
declare const isActiveMenuItem: (menuItem: Element | null) =>
|
9
|
+
declare const isValidPopover: (el: Element | null) => el is MenuPopover;
|
10
|
+
declare const isActiveMenuItem: (menuItem: Element | null) => menuItem is MenuItem;
|
9
11
|
export { isValidMenuItem, isValidPopover, isActiveMenuItem };
|
@@ -11,6 +11,6 @@ const isValidMenuItem = (menuItem) => {
|
|
11
11
|
var _a, _b;
|
12
12
|
return [MENUITEM_TAGNAME, MENUITEMCHECKBOX_TAGNAME, MENUITEMRADIO_TAGNAME].includes((_b = (_a = menuItem === null || menuItem === void 0 ? void 0 : menuItem.tagName) === null || _a === void 0 ? void 0 : _a.toLowerCase) === null || _b === void 0 ? void 0 : _b.call(_a));
|
13
13
|
};
|
14
|
-
const isValidPopover = (
|
14
|
+
const isValidPopover = (el) => { var _a; return ((_a = el === null || el === void 0 ? void 0 : el.tagName) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === MENUPOPOVER_TAGNAME; };
|
15
15
|
const isActiveMenuItem = (menuItem) => { var _a, _b; return ((_b = (_a = menuItem === null || menuItem === void 0 ? void 0 : menuItem.tagName) === null || _a === void 0 ? void 0 : _a.toLowerCase) === null || _b === void 0 ? void 0 : _b.call(_a)) === MENUITEM_TAGNAME && !menuItem.hasAttribute('disabled'); };
|
16
16
|
export { isValidMenuItem, isValidPopover, isActiveMenuItem };
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import { CSSResult } from 'lit';
|
1
|
+
import { CSSResult, PropertyValues } from 'lit';
|
2
2
|
import { Component } from '../../models';
|
3
3
|
/**
|
4
4
|
* `mdc-menusection` is a container element used to group a set of menu items.
|
@@ -12,10 +12,23 @@ import { Component } from '../../models';
|
|
12
12
|
* @tagname mdc-menusection
|
13
13
|
*
|
14
14
|
* @slot - Default slot for inserting `menuitem`, `menuitemcheckbox`, or `menuitemradio`
|
15
|
+
*
|
16
|
+
* @event change - (React: onChange) This event is dispatched when a `menuitemcheckbox`, or `menuitemradio` changes.
|
15
17
|
*/
|
16
18
|
declare class MenuSection extends Component {
|
19
|
+
/**
|
20
|
+
* The primary headerText of the list item.
|
21
|
+
* This appears on the leading side of the list item.
|
22
|
+
*/
|
23
|
+
ariaLabel: string | null;
|
24
|
+
/**
|
25
|
+
* The primary headerText of the list item.
|
26
|
+
* This appears on the leading side of the list item.
|
27
|
+
*/
|
28
|
+
headerText: string | null;
|
17
29
|
connectedCallback(): void;
|
18
|
-
|
30
|
+
update(changedProperties: PropertyValues): void;
|
31
|
+
private renderLabel;
|
19
32
|
render(): import("lit-html").TemplateResult<1>;
|
20
33
|
static styles: CSSResult[];
|
21
34
|
}
|
@@ -1,6 +1,18 @@
|
|
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
|
+
};
|
1
10
|
import { html } from 'lit';
|
11
|
+
import { property } from 'lit/decorators.js';
|
2
12
|
import { Component } from '../../models';
|
3
13
|
import { ROLE } from '../../utils/roles';
|
14
|
+
import { TYPE, VALID_TEXT_TAGS } from '../text/text.constants';
|
15
|
+
import styles from './menusection.styles';
|
4
16
|
/**
|
5
17
|
* `mdc-menusection` is a container element used to group a set of menu items.
|
6
18
|
*
|
@@ -13,18 +25,57 @@ import { ROLE } from '../../utils/roles';
|
|
13
25
|
* @tagname mdc-menusection
|
14
26
|
*
|
15
27
|
* @slot - Default slot for inserting `menuitem`, `menuitemcheckbox`, or `menuitemradio`
|
28
|
+
*
|
29
|
+
* @event change - (React: onChange) This event is dispatched when a `menuitemcheckbox`, or `menuitemradio` changes.
|
16
30
|
*/
|
17
31
|
class MenuSection extends Component {
|
32
|
+
constructor() {
|
33
|
+
super(...arguments);
|
34
|
+
/**
|
35
|
+
* The primary headerText of the list item.
|
36
|
+
* This appears on the leading side of the list item.
|
37
|
+
*/
|
38
|
+
this.ariaLabel = null;
|
39
|
+
/**
|
40
|
+
* The primary headerText of the list item.
|
41
|
+
* This appears on the leading side of the list item.
|
42
|
+
*/
|
43
|
+
this.headerText = null;
|
44
|
+
}
|
18
45
|
connectedCallback() {
|
19
46
|
super.connectedCallback();
|
20
47
|
this.setAttribute('role', ROLE.GROUP);
|
21
48
|
}
|
22
|
-
|
23
|
-
super.
|
49
|
+
update(changedProperties) {
|
50
|
+
super.update(changedProperties);
|
51
|
+
if ((changedProperties.has('ariaLabel') || changedProperties.has('headerText')) &&
|
52
|
+
(!this.ariaLabel || this.ariaLabel === changedProperties.get('headerText'))) {
|
53
|
+
// Because IDREF attribute reflection does not work across light and shadow DOM, we either set the
|
54
|
+
// `aria-label` directly or use the `ariaLabelledByElements`.
|
55
|
+
// Since the later one just released in the major browsers, we do the first one for now.
|
56
|
+
// more details: https://nolanlawson.com/2022/11/28/shadow-dom-and-accessibility-the-trouble-with-aria/
|
57
|
+
this.ariaLabel = this.headerText || '';
|
58
|
+
}
|
59
|
+
}
|
60
|
+
renderLabel() {
|
61
|
+
if (this.headerText) {
|
62
|
+
return html `<mdc-text part="header-text" type=${TYPE.BODY_MIDSIZE_BOLD} tagname=${VALID_TEXT_TAGS.DIV}>
|
63
|
+
${this.headerText}
|
64
|
+
</mdc-text> `;
|
65
|
+
}
|
66
|
+
return null;
|
24
67
|
}
|
25
68
|
render() {
|
26
|
-
return html
|
69
|
+
return html `${this.renderLabel()}<slot></slot>`;
|
27
70
|
}
|
28
71
|
}
|
29
|
-
MenuSection.styles = [...Component.styles];
|
72
|
+
MenuSection.styles = [...Component.styles, ...styles];
|
73
|
+
__decorate([
|
74
|
+
property({ type: String, reflect: true, attribute: 'aria-label' }),
|
75
|
+
__metadata("design:type", Object)
|
76
|
+
], MenuSection.prototype, "ariaLabel", void 0);
|
77
|
+
__decorate([
|
78
|
+
property({ type: String, reflect: true }),
|
79
|
+
__metadata("design:type", Object)
|
80
|
+
], MenuSection.prototype, "headerText", void 0);
|
30
81
|
export default MenuSection;
|
@@ -1,4 +1,7 @@
|
|
1
|
-
import
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
import type MenuItem from '../menuitem';
|
2
|
+
export type MenuSectionChangeEvent = Event & {
|
3
|
+
target: MenuItem;
|
4
|
+
};
|
5
|
+
export interface Events {
|
6
|
+
onChangeEvent: MenuSectionChangeEvent;
|
7
|
+
}
|