@m3e/menu 1.0.0-rc.1
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/LICENSE +22 -0
- package/README.md +315 -0
- package/cem.config.mjs +16 -0
- package/demo/index.html +112 -0
- package/dist/css-custom-data.json +362 -0
- package/dist/custom-elements.json +1590 -0
- package/dist/html-custom-data.json +106 -0
- package/dist/index.js +1274 -0
- package/dist/index.js.map +1 -0
- package/dist/index.min.js +276 -0
- package/dist/index.min.js.map +1 -0
- package/dist/src/MenuElement.d.ts +143 -0
- package/dist/src/MenuElement.d.ts.map +1 -0
- package/dist/src/MenuItemCheckboxElement.d.ts +76 -0
- package/dist/src/MenuItemCheckboxElement.d.ts.map +1 -0
- package/dist/src/MenuItemElement.d.ts +113 -0
- package/dist/src/MenuItemElement.d.ts.map +1 -0
- package/dist/src/MenuItemElementBase.d.ts +21 -0
- package/dist/src/MenuItemElementBase.d.ts.map +1 -0
- package/dist/src/MenuItemGroupElement.d.ts +28 -0
- package/dist/src/MenuItemGroupElement.d.ts.map +1 -0
- package/dist/src/MenuItemRadioElement.d.ts +77 -0
- package/dist/src/MenuItemRadioElement.d.ts.map +1 -0
- package/dist/src/MenuPosition.d.ts +5 -0
- package/dist/src/MenuPosition.d.ts.map +1 -0
- package/dist/src/MenuTriggerElement.d.ts +86 -0
- package/dist/src/MenuTriggerElement.d.ts.map +1 -0
- package/dist/src/index.d.ts +8 -0
- package/dist/src/index.d.ts.map +1 -0
- package/eslint.config.mjs +13 -0
- package/package.json +48 -0
- package/rollup.config.js +32 -0
- package/src/MenuElement.ts +449 -0
- package/src/MenuItemCheckboxElement.ts +178 -0
- package/src/MenuItemElement.ts +210 -0
- package/src/MenuItemElementBase.ts +158 -0
- package/src/MenuItemGroupElement.ts +37 -0
- package/src/MenuItemRadioElement.ts +169 -0
- package/src/MenuPosition.ts +5 -0
- package/src/MenuTriggerElement.ts +154 -0
- package/src/index.ts +7 -0
- package/tsconfig.json +9 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { css, CSSResultGroup, html, LitElement } from "lit";
|
|
2
|
+
import { customElement } from "lit/decorators.js";
|
|
3
|
+
|
|
4
|
+
import { HtmlFor, Role } from "@m3e/core";
|
|
5
|
+
import { addAriaReferencedId, removeAriaReferencedId } from "@m3e/core/a11y";
|
|
6
|
+
|
|
7
|
+
import type { M3eMenuElement } from "./MenuElement";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @summary
|
|
11
|
+
* An element, nested within a clickable element, used to open a menu.
|
|
12
|
+
*
|
|
13
|
+
* @description
|
|
14
|
+
* The `m3e-menu-trigger` component is used to open a menu when nested within a clickable element
|
|
15
|
+
* such as a button or menu item. It anchors the menu to its invoker, enabling contextual flows and
|
|
16
|
+
* nested hierarchies.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* The following example illustrates a basic menu. The `m3e-menu-trigger` is used to trigger a `m3e-menu` specified
|
|
20
|
+
* by the `for` attribute when its parenting element is activated.
|
|
21
|
+
* ```html
|
|
22
|
+
* <m3e-button>
|
|
23
|
+
* <m3e-menu-trigger for="menu1">Basic menu</m3e-menu-trigger>
|
|
24
|
+
* </m3e-button>
|
|
25
|
+
* <m3e-menu id="menu1">
|
|
26
|
+
* <m3e-menu-item>Apple</m3e-menu-item>
|
|
27
|
+
* <m3e-menu-item>Apricot</m3e-menu-item>
|
|
28
|
+
* <m3e-menu-item>Avocado</m3e-menu-item>
|
|
29
|
+
* <m3e-menu-item>Green Apple</m3e-menu-item>
|
|
30
|
+
* <m3e-menu-item>Green Grapes</m3e-menu-item>
|
|
31
|
+
* <m3e-menu-item>Olive</m3e-menu-item>
|
|
32
|
+
* <m3e-menu-item>Orange</m3e-menu-item>
|
|
33
|
+
* </m3e-menu>
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* The next example illustrates nested menus. Submenus are triggered by placing a `m3e-menu-trigger` inside a `m3e-menu-item`.
|
|
38
|
+
* ```html
|
|
39
|
+
* <m3e-button>
|
|
40
|
+
* <m3e-menu-trigger for="menu2">Nested menus</m3e-menu-trigger>
|
|
41
|
+
* </m3e-button>
|
|
42
|
+
* <m3e-menu id="menu2">
|
|
43
|
+
* <m3e-menu-item>
|
|
44
|
+
* <m3e-menu-trigger for="menu3">Fruits with A</m3e-menu-trigger>
|
|
45
|
+
* </m3e-menu-item>
|
|
46
|
+
* <m3e-menu-item>Grapes</m3e-menu-item>
|
|
47
|
+
* <m3e-menu-item>Olive</m3e-menu-item>
|
|
48
|
+
* <m3e-menu-item>Orange</m3e-menu-item>
|
|
49
|
+
* </m3e-menu>
|
|
50
|
+
* <m3e-menu id="menu3">
|
|
51
|
+
* <m3e-menu-item>Apricot</m3e-menu-item>
|
|
52
|
+
* <m3e-menu-item>Avocado</m3e-menu-item>
|
|
53
|
+
* <m3e-menu-item>
|
|
54
|
+
* <m3e-menu-trigger for="menu4">Apples</m3e-menu-trigger>
|
|
55
|
+
* </m3e-menu-item>
|
|
56
|
+
* </m3e-menu>
|
|
57
|
+
* <m3e-menu id="menu4">
|
|
58
|
+
* <m3e-menu-item>Fuji</m3e-menu-item>
|
|
59
|
+
* <m3e-menu-item>Granny Smith</m3e-menu-item>
|
|
60
|
+
* <m3e-menu-item>Red Delicious</m3e-menu-item>
|
|
61
|
+
* </m3e-menu>
|
|
62
|
+
* ```
|
|
63
|
+
*
|
|
64
|
+
* @tag m3e-menu-trigger
|
|
65
|
+
*
|
|
66
|
+
* @slot - Renders the contents of the trigger.
|
|
67
|
+
*/
|
|
68
|
+
@customElement("m3e-menu-trigger")
|
|
69
|
+
export class M3eMenuTriggerElement extends HtmlFor(Role(LitElement, "none")) {
|
|
70
|
+
/** The styles of the element. */
|
|
71
|
+
static override styles: CSSResultGroup = css`
|
|
72
|
+
:host {
|
|
73
|
+
display: contents;
|
|
74
|
+
}
|
|
75
|
+
::slotted(.material-icons) {
|
|
76
|
+
font-size: inherit !important;
|
|
77
|
+
}
|
|
78
|
+
`;
|
|
79
|
+
|
|
80
|
+
/** @private */ readonly #clickHandler = async (e: Event) => this.#handleClick(e);
|
|
81
|
+
|
|
82
|
+
/** The menu triggered by the element. */
|
|
83
|
+
get menu(): M3eMenuElement | null {
|
|
84
|
+
return this.control?.tagName === "M3E-MENU" ? <M3eMenuElement>this.control : null;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** @inheritdoc */
|
|
88
|
+
override connectedCallback(): void {
|
|
89
|
+
super.connectedCallback();
|
|
90
|
+
this.parentElement?.addEventListener("click", this.#clickHandler);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** @inheritdoc */
|
|
94
|
+
override disconnectedCallback(): void {
|
|
95
|
+
super.disconnectedCallback();
|
|
96
|
+
this.parentElement?.removeEventListener("click", this.#clickHandler);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** @inheritdoc */
|
|
100
|
+
override attach(control: HTMLElement): void {
|
|
101
|
+
super.attach(control);
|
|
102
|
+
|
|
103
|
+
const menu = this.menu;
|
|
104
|
+
if (menu) {
|
|
105
|
+
if (this.parentElement) {
|
|
106
|
+
this.parentElement.ariaHasPopup = "menu";
|
|
107
|
+
this.parentElement.ariaExpanded = "false";
|
|
108
|
+
if (menu.id) {
|
|
109
|
+
addAriaReferencedId(this.parentElement, "aria-controls", menu.id);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if (this.closest("m3e-menu")) {
|
|
113
|
+
menu.submenu = true;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** @inheritdoc */
|
|
119
|
+
override detach(): void {
|
|
120
|
+
if (this.parentElement) {
|
|
121
|
+
this.parentElement.ariaHasPopup = null;
|
|
122
|
+
this.parentElement.ariaExpanded = null;
|
|
123
|
+
|
|
124
|
+
const menu = this.menu;
|
|
125
|
+
if (menu?.id) {
|
|
126
|
+
removeAriaReferencedId(this.parentElement, "aria-controls", menu.id);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
super.detach();
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/** @inheritdoc */
|
|
134
|
+
protected override render(): unknown {
|
|
135
|
+
return html`<slot></slot>`;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/** @private */
|
|
139
|
+
#handleClick(e: Event): void {
|
|
140
|
+
if (!e.defaultPrevented && this.parentElement) {
|
|
141
|
+
if (this.parentElement.tagName === "M3E-MENU-ITEM") {
|
|
142
|
+
this.menu?.show(this.parentElement);
|
|
143
|
+
} else {
|
|
144
|
+
this.menu?.toggle(this.parentElement);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
declare global {
|
|
151
|
+
interface HTMLElementTagNameMap {
|
|
152
|
+
"m3e-menu-trigger": M3eMenuTriggerElement;
|
|
153
|
+
}
|
|
154
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export * from "./MenuElement";
|
|
2
|
+
export * from "./MenuItemCheckboxElement";
|
|
3
|
+
export * from "./MenuItemElement";
|
|
4
|
+
export * from "./MenuItemGroupElement";
|
|
5
|
+
export * from "./MenuItemRadioElement";
|
|
6
|
+
export * from "./MenuPosition";
|
|
7
|
+
export * from "./MenuTriggerElement";
|