@zanichelli/albe-web-components 16.3.1 → 16.3.2
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/CHANGELOG.md +2 -0
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/web-components-library.cjs.js +1 -1
- package/dist/cjs/z-app-header_12.cjs.entry.js +67 -17
- package/dist/cjs/z-app-header_12.cjs.entry.js.map +1 -1
- package/dist/cjs/z-menu-section.cjs.entry.js +28 -13
- package/dist/cjs/z-menu-section.cjs.entry.js.map +1 -1
- package/dist/cjs/z-menu.cjs.entry.js +89 -43
- package/dist/cjs/z-menu.cjs.entry.js.map +1 -1
- package/dist/collection/components/z-app-header/index.js +55 -13
- package/dist/collection/components/z-app-header/index.js.map +1 -1
- package/dist/collection/components/z-app-header/index.stories.js +50 -116
- package/dist/collection/components/z-app-header/index.stories.js.map +1 -1
- package/dist/collection/components/z-app-header/styles.css +34 -25
- package/dist/collection/components/z-menu/index.js +93 -42
- package/dist/collection/components/z-menu/index.js.map +1 -1
- package/dist/collection/components/z-menu/styles.css +40 -52
- package/dist/collection/components/z-menu-section/index.js +31 -16
- package/dist/collection/components/z-menu-section/index.js.map +1 -1
- package/dist/collection/components/z-menu-section/styles.css +8 -0
- package/dist/collection/components/z-searchbar/index.js +14 -5
- package/dist/collection/components/z-searchbar/index.js.map +1 -1
- package/dist/components/index23.js +14 -5
- package/dist/components/index23.js.map +1 -1
- package/dist/components/z-app-header.js +56 -14
- package/dist/components/z-app-header.js.map +1 -1
- package/dist/components/z-menu-section.js +30 -15
- package/dist/components/z-menu-section.js.map +1 -1
- package/dist/components/z-menu.js +89 -44
- package/dist/components/z-menu.js.map +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/esm/web-components-library.js +1 -1
- package/dist/esm/z-app-header_12.entry.js +67 -17
- package/dist/esm/z-app-header_12.entry.js.map +1 -1
- package/dist/esm/z-menu-section.entry.js +28 -13
- package/dist/esm/z-menu-section.entry.js.map +1 -1
- package/dist/esm/z-menu.entry.js +89 -43
- package/dist/esm/z-menu.entry.js.map +1 -1
- package/dist/types/components/z-app-header/index.d.ts +4 -3
- package/dist/types/components/z-menu/index.d.ts +9 -1
- package/dist/types/components/z-menu-section/index.d.ts +4 -2
- package/dist/types/components/z-searchbar/index.d.ts +1 -0
- package/dist/web-components-library/p-8e5f1ae0.entry.js +2 -0
- package/dist/web-components-library/p-8e5f1ae0.entry.js.map +1 -0
- package/dist/web-components-library/p-b6e7866f.entry.js +2 -0
- package/dist/web-components-library/p-b6e7866f.entry.js.map +1 -0
- package/dist/web-components-library/p-fb0b11cd.entry.js +2 -0
- package/dist/web-components-library/p-fb0b11cd.entry.js.map +1 -0
- package/dist/web-components-library/web-components-library.esm.js +1 -1
- package/dist/web-components-library/web-components-library.esm.js.map +1 -1
- package/package.json +1 -1
- package/www/build/p-38bf2bfc.js +2 -0
- package/www/build/p-8e5f1ae0.entry.js +2 -0
- package/www/build/p-8e5f1ae0.entry.js.map +1 -0
- package/www/build/p-b6e7866f.entry.js +2 -0
- package/www/build/p-b6e7866f.entry.js.map +1 -0
- package/www/build/p-fb0b11cd.entry.js +2 -0
- package/www/build/p-fb0b11cd.entry.js.map +1 -0
- package/www/build/web-components-library.esm.js +1 -1
- package/www/build/web-components-library.esm.js.map +1 -1
- package/www/index.html +1 -1
- package/dist/web-components-library/p-04c39e8a.entry.js +0 -2
- package/dist/web-components-library/p-04c39e8a.entry.js.map +0 -1
- package/dist/web-components-library/p-0542a3c9.entry.js +0 -2
- package/dist/web-components-library/p-0542a3c9.entry.js.map +0 -1
- package/dist/web-components-library/p-16d625b3.entry.js +0 -2
- package/dist/web-components-library/p-16d625b3.entry.js.map +0 -1
- package/www/build/p-04c39e8a.entry.js +0 -2
- package/www/build/p-04c39e8a.entry.js.map +0 -1
- package/www/build/p-0542a3c9.entry.js +0 -2
- package/www/build/p-0542a3c9.entry.js.map +0 -1
- package/www/build/p-16d625b3.entry.js +0 -2
- package/www/build/p-16d625b3.entry.js.map +0 -1
- package/www/build/p-ae5cec65.js +0 -2
|
@@ -2,7 +2,7 @@ import { proxyCustomElement, HTMLElement, createEvent, h, Host } from '@stencil/
|
|
|
2
2
|
import { g as KeyboardCode } from './index2.js';
|
|
3
3
|
import { d as defineCustomElement$2 } from './index9.js';
|
|
4
4
|
|
|
5
|
-
const stylesCss = ":host{display:flex;flex-direction:column;align-items:flex-start;justify-content:center;padding:0;font-family:var(--font-family-sans)}:host,::slotted(*),*{box-sizing:border-box}::slotted(a){text-decoration:none}::slotted(*){color:var(--color-default-text);font-family:var(--font-family-sans);font-weight:var(--font-rg)}.label{display:flex;width:100%;align-items:center;padding:var(--space-unit) 0;border:0;border-bottom:var(--border-size-small) solid var(--color-surface03);margin:0;background:transparent;border-radius:0;cursor:pointer;text-align:left}:host(:is([active],[open])) .label,.label:focus:focus-visible,.label:hover{border-color:var(--color-secondary01)}.label:focus:focus-visible{box-shadow:var(--shadow-focus-primary);outline:none}:host(:is([active],[open])) .label ::slotted(*),.label:focus:focus-visible ::slotted(*),.label:hover ::slotted(*){font-weight:var(--font-bd)}::slotted([data-text]){display:inline-flex;flex-direction:column}::slotted([data-text])::after{overflow:hidden;height:0;content:attr(data-text);content:attr(data-text) / \"\";font-weight:var(--font-bd);pointer-events:none;user-select:none;visibility:hidden}@media speech{::slotted([data-text])::after{display:none}}.label ::slotted(*){width:100%;margin:0;font-size:var(--font-size-3);line-height:1.5}.label z-icon{margin-left:calc(var(--space-unit) * 4);fill:var(--color-default-icon)}.items{display:flex;width:100%;flex-direction:column;padding:calc(var(--space-unit) / 2);padding-bottom:calc(var(--space-unit) * 1.5)}::slotted([slot=\"section\"]){display:inline-flex;padding:calc(var(--space-unit) / 2);margin:0;font-size:var(--font-size-1);line-height:1.333;outline:none}::slotted([slot=\"section\"]:last-of-type){border:none}::slotted([slot=\"section\"]:focus:focus-visible){box-shadow:var(--shadow-focus-primary);color:var(--color-secondary01)}::slotted([slot=\"section\"]:hover),::slotted([slot=\"section\"]:focus:focus-visible),::slotted([slot=\"section\"][active]){color:var(--color-secondary01);font-weight:var(--font-bd)}";
|
|
5
|
+
const stylesCss = ":host{display:flex;flex-direction:column;align-items:flex-start;justify-content:center;padding:0;font-family:var(--font-family-sans)}:host,::slotted(*),*{box-sizing:border-box}::slotted(a){text-decoration:none}::slotted(*){color:var(--color-default-text);font-family:var(--font-family-sans);font-weight:var(--font-rg)}.label{display:flex;width:100%;align-items:center;padding:var(--space-unit) 0;border:0;border-bottom:var(--border-size-small) solid var(--color-surface03);margin:0;background:transparent;border-radius:0;cursor:pointer;text-align:left}:host(:last-child:not([open])) .label{border-bottom:none}:host(:is([active],[open])) .label,.label:focus:focus-visible,.label:hover{border-color:var(--color-secondary01)}.label:focus:focus-visible{box-shadow:var(--shadow-focus-primary);outline:none}:host(:is([active],[open])) .label ::slotted(*),.label:focus:focus-visible ::slotted(*),.label:hover ::slotted(*){font-weight:var(--font-bd)}::slotted([data-text]){display:inline-flex;flex-direction:column}::slotted([data-text])::after{overflow:hidden;height:0;content:attr(data-text);content:attr(data-text) / \"\";font-weight:var(--font-bd);pointer-events:none;user-select:none;visibility:hidden}@media speech{::slotted([data-text])::after{display:none}}.label ::slotted(*){width:100%;margin:0;font-size:var(--font-size-3);line-height:1.5}.label z-icon{margin-left:calc(var(--space-unit) * 4);fill:var(--color-default-icon)}.items{display:flex;width:100%;flex-direction:column;padding:calc(var(--space-unit) / 2);padding-bottom:calc(var(--space-unit) * 1.5)}.items[hidden]{display:none}::slotted([slot=\"section\"]){display:inline-flex;padding:calc(var(--space-unit) / 2);margin:0;font-size:var(--font-size-1);line-height:1.333;outline:none}::slotted([slot=\"section\"]:last-of-type){border:none}::slotted([slot=\"section\"]:focus:focus-visible){box-shadow:var(--shadow-focus-primary);color:var(--color-secondary01)}::slotted([slot=\"section\"]:hover),::slotted([slot=\"section\"]:focus:focus-visible),::slotted([slot=\"section\"][active]){color:var(--color-secondary01);font-weight:var(--font-bd)}";
|
|
6
6
|
const ZMenuSectionStyle0 = stylesCss;
|
|
7
7
|
|
|
8
8
|
const ZMenuSection$1 = /*@__PURE__*/ proxyCustomElement(class ZMenuSection extends HTMLElement {
|
|
@@ -14,15 +14,14 @@ const ZMenuSection$1 = /*@__PURE__*/ proxyCustomElement(class ZMenuSection exten
|
|
|
14
14
|
return;
|
|
15
15
|
}
|
|
16
16
|
this.open = !this.open;
|
|
17
|
-
this.setFocus();
|
|
18
17
|
}
|
|
19
18
|
setItemsA11yAttrs() {
|
|
20
19
|
if (!this.hasItems) {
|
|
21
20
|
return;
|
|
22
21
|
}
|
|
23
|
-
this.items.forEach((item
|
|
22
|
+
this.items.forEach((item) => {
|
|
24
23
|
item.setAttribute("role", "menuitem");
|
|
25
|
-
item.
|
|
24
|
+
item.tabIndex = -1;
|
|
26
25
|
});
|
|
27
26
|
}
|
|
28
27
|
onItemsChange() {
|
|
@@ -38,11 +37,18 @@ const ZMenuSection$1 = /*@__PURE__*/ proxyCustomElement(class ZMenuSection exten
|
|
|
38
37
|
const labelElement = ev.target.assignedElements()[0];
|
|
39
38
|
labelElement.dataset.text = labelElement === null || labelElement === void 0 ? void 0 : labelElement.textContent;
|
|
40
39
|
}
|
|
40
|
+
onLabelClick() {
|
|
41
|
+
this.toggle();
|
|
42
|
+
this.setFocus();
|
|
43
|
+
}
|
|
41
44
|
onLabelKeydown(ev) {
|
|
42
45
|
if (ev.key === KeyboardCode.ENTER || ev.key === KeyboardCode.SPACE) {
|
|
43
46
|
ev.preventDefault();
|
|
44
47
|
ev.stopPropagation();
|
|
45
48
|
this.toggle();
|
|
49
|
+
if (this.open) {
|
|
50
|
+
this.focustFirstItem();
|
|
51
|
+
}
|
|
46
52
|
}
|
|
47
53
|
}
|
|
48
54
|
/**
|
|
@@ -58,6 +64,13 @@ const ZMenuSection$1 = /*@__PURE__*/ proxyCustomElement(class ZMenuSection exten
|
|
|
58
64
|
current.tabIndex = -1;
|
|
59
65
|
}
|
|
60
66
|
}
|
|
67
|
+
focustFirstItem() {
|
|
68
|
+
this.moveFocus(this.items[0]);
|
|
69
|
+
}
|
|
70
|
+
/** Focus the last item. */
|
|
71
|
+
async focusLastItem() {
|
|
72
|
+
this.moveFocus(this.items[this.items.length - 1]);
|
|
73
|
+
}
|
|
61
74
|
/** Set tabindex of the label to 0, then focus it. */
|
|
62
75
|
async setFocus() {
|
|
63
76
|
this.htmlTabindex = 0;
|
|
@@ -65,15 +78,10 @@ const ZMenuSection$1 = /*@__PURE__*/ proxyCustomElement(class ZMenuSection exten
|
|
|
65
78
|
this.label.focus();
|
|
66
79
|
}, 100);
|
|
67
80
|
}
|
|
68
|
-
/** Focus the last item. */
|
|
69
|
-
async focusLastItem() {
|
|
70
|
-
this.htmlTabindex = 0;
|
|
71
|
-
this.moveFocus(this.items[this.items.length - 1]);
|
|
72
|
-
}
|
|
73
81
|
onOpenChange() {
|
|
74
82
|
if (!this.open) {
|
|
75
|
-
this.closed.emit();
|
|
76
83
|
this.setItemsA11yAttrs();
|
|
84
|
+
this.closed.emit();
|
|
77
85
|
}
|
|
78
86
|
else {
|
|
79
87
|
this.opened.emit();
|
|
@@ -91,7 +99,7 @@ const ZMenuSection$1 = /*@__PURE__*/ proxyCustomElement(class ZMenuSection exten
|
|
|
91
99
|
}
|
|
92
100
|
ev.preventDefault();
|
|
93
101
|
ev.stopPropagation();
|
|
94
|
-
this.label.
|
|
102
|
+
this.moveFocus(this.label, this.focusableItem);
|
|
95
103
|
this.open = false;
|
|
96
104
|
break;
|
|
97
105
|
case KeyboardCode.ARROW_RIGHT:
|
|
@@ -101,6 +109,7 @@ const ZMenuSection$1 = /*@__PURE__*/ proxyCustomElement(class ZMenuSection exten
|
|
|
101
109
|
ev.preventDefault();
|
|
102
110
|
ev.stopPropagation();
|
|
103
111
|
this.open = true;
|
|
112
|
+
this.focustFirstItem();
|
|
104
113
|
break;
|
|
105
114
|
case KeyboardCode.ARROW_DOWN: {
|
|
106
115
|
if (!this.open) {
|
|
@@ -109,7 +118,7 @@ const ZMenuSection$1 = /*@__PURE__*/ proxyCustomElement(class ZMenuSection exten
|
|
|
109
118
|
if (document.activeElement === this.host) {
|
|
110
119
|
ev.preventDefault();
|
|
111
120
|
ev.stopPropagation();
|
|
112
|
-
this.
|
|
121
|
+
this.focustFirstItem();
|
|
113
122
|
break;
|
|
114
123
|
}
|
|
115
124
|
const currentIndex = this.items.indexOf(this.focusableItem);
|
|
@@ -119,6 +128,10 @@ const ZMenuSection$1 = /*@__PURE__*/ proxyCustomElement(class ZMenuSection exten
|
|
|
119
128
|
ev.stopPropagation();
|
|
120
129
|
this.moveFocus(receiver, this.focusableItem);
|
|
121
130
|
}
|
|
131
|
+
else {
|
|
132
|
+
this.htmlTabindex = 0;
|
|
133
|
+
this.focusableItem.tabIndex = -1;
|
|
134
|
+
}
|
|
122
135
|
break;
|
|
123
136
|
}
|
|
124
137
|
case KeyboardCode.ARROW_UP: {
|
|
@@ -134,6 +147,7 @@ const ZMenuSection$1 = /*@__PURE__*/ proxyCustomElement(class ZMenuSection exten
|
|
|
134
147
|
}
|
|
135
148
|
else {
|
|
136
149
|
// since there isn't a previous item to focus, give the focus to the label element
|
|
150
|
+
this.focusableItem.tabIndex = -1;
|
|
137
151
|
this.setFocus();
|
|
138
152
|
}
|
|
139
153
|
break;
|
|
@@ -154,6 +168,7 @@ const ZMenuSection$1 = /*@__PURE__*/ proxyCustomElement(class ZMenuSection exten
|
|
|
154
168
|
this.toggle = this.toggle.bind(this);
|
|
155
169
|
this.onItemsChange = this.onItemsChange.bind(this);
|
|
156
170
|
this.onLabelSlotChange = this.onLabelSlotChange.bind(this);
|
|
171
|
+
this.onLabelClick = this.onLabelClick.bind(this);
|
|
157
172
|
this.onLabelKeydown = this.onLabelKeydown.bind(this);
|
|
158
173
|
this.onItemsKeydown = this.onItemsKeydown.bind(this);
|
|
159
174
|
}
|
|
@@ -161,7 +176,7 @@ const ZMenuSection$1 = /*@__PURE__*/ proxyCustomElement(class ZMenuSection exten
|
|
|
161
176
|
this.onItemsChange();
|
|
162
177
|
}
|
|
163
178
|
render() {
|
|
164
|
-
return (h(Host, { key: '
|
|
179
|
+
return (h(Host, { key: '4d9223bebf25df5eb224a7674c920ebc17470826', open: this.open }, h("button", { key: '2f75c046ad4519df706283d3b37c2d9feb8734d3', ref: (el) => (this.label = el), class: "label", "aria-haspopup": `${!!this.hasItems}`, "aria-expanded": `${!!this.open}`, role: "menuitem", tabindex: this.htmlTabindex, onClick: this.onLabelClick, onKeyDown: this.onLabelKeydown }, h("slot", { key: '0a3b20723371deac12792436d977c343c237720b', onSlotchange: this.onLabelSlotChange }), this.hasItems && h("z-icon", { key: '7fe5e9dc4a9eac28f0f3a381fedbe0ec3e7ca99d', name: this.open ? "chevron-up" : "chevron-down" })), h("div", { key: '80e167ce90df12c27eddc1e28b6bf6dd3b5d0dd7', class: "items", role: "menu", hidden: !this.open }, h("slot", { key: 'a0e88a56848abf198ced22e4fc390267aea6114e', name: "section", onSlotchange: this.onItemsChange }))));
|
|
165
180
|
}
|
|
166
181
|
get host() { return this; }
|
|
167
182
|
static get watchers() { return {
|
|
@@ -175,8 +190,8 @@ const ZMenuSection$1 = /*@__PURE__*/ proxyCustomElement(class ZMenuSection exten
|
|
|
175
190
|
"open": [1028],
|
|
176
191
|
"hasItems": [32],
|
|
177
192
|
"items": [32],
|
|
178
|
-
"
|
|
179
|
-
"
|
|
193
|
+
"focusLastItem": [64],
|
|
194
|
+
"setFocus": [64]
|
|
180
195
|
}, [[0, "keydown", "onItemsKeydown"]], {
|
|
181
196
|
"open": ["onOpenChange"],
|
|
182
197
|
"htmlTabindex": ["onTabindexChange"]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"file":"z-menu-section.js","mappings":"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","names":["ZMenuSection"],"sources":["src/components/z-menu-section/styles.css?tag=z-menu-section&encapsulation=shadow","src/components/z-menu-section/index.tsx"],"sourcesContent":[":host {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n justify-content: center;\n padding: 0;\n font-family: var(--font-family-sans);\n}\n\n:host,\n::slotted(*),\n* {\n box-sizing: border-box;\n}\n\n::slotted(a) {\n text-decoration: none;\n}\n\n::slotted(*) {\n color: var(--color-default-text);\n font-family: var(--font-family-sans);\n font-weight: var(--font-rg);\n}\n\n.label {\n display: flex;\n width: 100%;\n align-items: center;\n padding: var(--space-unit) 0;\n border: 0;\n border-bottom: var(--border-size-small) solid var(--color-surface03);\n margin: 0;\n background: transparent;\n border-radius: 0;\n cursor: pointer;\n text-align: left;\n}\n\n:host(:is([active], [open])) .label,\n.label:focus:focus-visible,\n.label:hover {\n border-color: var(--color-secondary01);\n}\n\n.label:focus:focus-visible {\n box-shadow: var(--shadow-focus-primary);\n outline: none;\n}\n\n:host(:is([active], [open])) .label ::slotted(*),\n.label:focus:focus-visible ::slotted(*),\n.label:hover ::slotted(*) {\n font-weight: var(--font-bd);\n}\n\n::slotted([data-text]) {\n display: inline-flex;\n flex-direction: column;\n}\n\n/* Trick to prevent layout shifts on font-weight changes.\nThe trick is to put an hidden copy of the text already set to bold,\nso the needed space is correctly calculated before any hover/active state changes the\nfont-weight of the real text.\nThe hidden text has an height of 0px so it can expand the width without changing the height\nwhen placed below the real text using `flex-direction: column`. */\n::slotted([data-text])::after {\n overflow: hidden;\n height: 0;\n content: attr(data-text);\n content: attr(data-text) / \"\";\n font-weight: var(--font-bd);\n pointer-events: none;\n user-select: none;\n visibility: hidden;\n}\n\n@media speech {\n ::slotted([data-text])::after {\n display: none;\n }\n}\n\n.label ::slotted(*) {\n width: 100%;\n margin: 0;\n font-size: var(--font-size-3);\n line-height: 1.5;\n}\n\n.label z-icon {\n margin-left: calc(var(--space-unit) * 4);\n fill: var(--color-default-icon);\n}\n\n.items {\n display: flex;\n width: 100%;\n flex-direction: column;\n padding: calc(var(--space-unit) / 2);\n padding-bottom: calc(var(--space-unit) * 1.5);\n}\n\n::slotted([slot=\"section\"]) {\n display: inline-flex;\n padding: calc(var(--space-unit) / 2);\n margin: 0;\n font-size: var(--font-size-1);\n line-height: 1.333;\n outline: none;\n}\n\n::slotted([slot=\"section\"]:last-of-type) {\n border: none;\n}\n\n::slotted([slot=\"section\"]:focus:focus-visible) {\n box-shadow: var(--shadow-focus-primary);\n color: var(--color-secondary01);\n}\n\n::slotted([slot=\"section\"]:hover),\n::slotted([slot=\"section\"]:focus:focus-visible),\n::slotted([slot=\"section\"][active]) {\n color: var(--color-secondary01);\n font-weight: var(--font-bd);\n}\n","import {Component, Element, Event, EventEmitter, Host, Listen, Method, Prop, State, Watch, h} from \"@stencil/core\";\nimport {KeyboardCode} from \"../../beans\";\n\n/**\n * A component to create submenus inside the ZMenu.\n * @slot - Label of the menu section.\n * @slot item - Single entry of the section. Set the same slot name to different items to put many of them. Add the `active` attribute to a slotted item to highlight it.\n */\n@Component({\n tag: \"z-menu-section\",\n styleUrl: \"styles.css\",\n shadow: true,\n})\nexport class ZMenuSection {\n @Element() host: HTMLZMenuSectionElement;\n\n /** Active state */\n @Prop({reflect: true})\n active?: boolean;\n\n /**\n * Tabindex value to set on the label button.\n * Useful to manage keyboard navigation focus with roving tabindex handled by this component's parent (usually ZMenu).\n */\n @Prop()\n htmlTabindex = -1;\n\n /** The opening state of the section. */\n @Prop({mutable: true})\n open: boolean;\n\n @State()\n hasItems: boolean;\n\n @State()\n items: HTMLElement[];\n\n /** The section has been opened. */\n @Event()\n opened: EventEmitter;\n\n /** The section has been closed. */\n @Event()\n closed: EventEmitter;\n\n private label: HTMLButtonElement;\n\n private get focusableItem(): HTMLElement {\n return this.items.find(({tabIndex}) => tabIndex === 0);\n }\n\n private toggle(): void {\n if (!this.hasItems) {\n return;\n }\n\n this.open = !this.open;\n this.setFocus();\n }\n\n private setItemsA11yAttrs(): void {\n if (!this.hasItems) {\n return;\n }\n\n this.items.forEach((item, index) => {\n item.setAttribute(\"role\", \"menuitem\");\n item.setAttribute(\"tabindex\", index === 0 ? \"0\" : \"-1\");\n });\n }\n\n private onItemsChange(): void {\n this.items = Array.from(this.host.querySelectorAll('[slot=\"section\"]')) as HTMLElement[];\n this.hasItems = this.items.length > 0;\n this.setItemsA11yAttrs();\n }\n\n /**\n * Sets slotted item text as `data-text` attribute value, to let CSS use it through `attr()`.\n * @param ev Slotchange event\n */\n private onLabelSlotChange(ev: Event): void {\n const labelElement = (ev.target as HTMLSlotElement).assignedElements()[0] as HTMLElement;\n labelElement.dataset.text = labelElement?.textContent;\n }\n\n private onLabelKeydown(ev: KeyboardEvent): void {\n if (ev.key === KeyboardCode.ENTER || ev.key === KeyboardCode.SPACE) {\n ev.preventDefault();\n ev.stopPropagation();\n this.toggle();\n }\n }\n\n /**\n * Move focus and adjust the tabindex value of `receiver` and `current` elements,\n * setting -1 to the `current` and 0 to the `receiver`, then focus the `receiver` element.\n */\n private moveFocus(receiver: HTMLElement, current?: HTMLElement): void {\n receiver.tabIndex = 0;\n setTimeout(() => {\n receiver.focus();\n }, 100);\n if (current) {\n current.tabIndex = -1;\n }\n }\n\n /** Set tabindex of the label to 0, then focus it. */\n @Method()\n async setFocus(): Promise<void> {\n this.htmlTabindex = 0;\n setTimeout(() => {\n this.label.focus();\n }, 100);\n }\n\n /** Focus the last item. */\n @Method()\n async focusLastItem(): Promise<void> {\n this.htmlTabindex = 0;\n this.moveFocus(this.items[this.items.length - 1]);\n }\n\n @Watch(\"open\")\n onOpenChange(): void {\n if (!this.open) {\n this.closed.emit();\n this.setItemsA11yAttrs();\n } else {\n this.opened.emit();\n }\n }\n\n @Watch(\"htmlTabindex\")\n onTabindexChange(): void {\n this.label.tabIndex = this.htmlTabindex;\n }\n\n @Listen(\"keydown\")\n private onItemsKeydown(ev: KeyboardEvent): void {\n switch (ev.key) {\n case KeyboardCode.ESC:\n case KeyboardCode.ARROW_LEFT:\n if (!this.open) {\n break;\n }\n ev.preventDefault();\n ev.stopPropagation();\n this.label.focus();\n this.open = false;\n break;\n case KeyboardCode.ARROW_RIGHT:\n if (this.open) {\n break;\n }\n ev.preventDefault();\n ev.stopPropagation();\n this.open = true;\n break;\n case KeyboardCode.ARROW_DOWN: {\n if (!this.open) {\n break;\n }\n if (document.activeElement === this.host) {\n ev.preventDefault();\n ev.stopPropagation();\n this.moveFocus(this.items[0]);\n break;\n }\n const currentIndex = this.items.indexOf(this.focusableItem);\n const receiver = this.items[currentIndex + 1];\n if (receiver) {\n ev.preventDefault();\n ev.stopPropagation();\n this.moveFocus(receiver, this.focusableItem);\n }\n break;\n }\n case KeyboardCode.ARROW_UP: {\n if (!this.open || document.activeElement === this.host) {\n break;\n }\n const currentIndex = this.items.indexOf(this.focusableItem);\n const receiver = this.items[currentIndex - 1];\n ev.preventDefault();\n ev.stopPropagation();\n if (receiver) {\n this.moveFocus(receiver, this.focusableItem);\n } else {\n // since there isn't a previous item to focus, give the focus to the label element\n this.setFocus();\n }\n break;\n }\n }\n }\n\n constructor() {\n this.toggle = this.toggle.bind(this);\n this.onItemsChange = this.onItemsChange.bind(this);\n this.onLabelSlotChange = this.onLabelSlotChange.bind(this);\n this.onLabelKeydown = this.onLabelKeydown.bind(this);\n this.onItemsKeydown = this.onItemsKeydown.bind(this);\n }\n\n connectedCallback(): void {\n this.onItemsChange();\n }\n\n render(): HTMLZMenuSectionElement {\n return (\n <Host open={this.open}>\n <button\n ref={(el) => (this.label = el)}\n class=\"label\"\n aria-haspopup={`${this.hasItems}`}\n aria-expanded={`${!!this.open}`}\n role=\"menuitem\"\n tabindex={this.htmlTabindex}\n onClick={this.toggle}\n onKeyDown={this.onLabelKeydown}\n >\n <slot onSlotchange={this.onLabelSlotChange} />\n {this.hasItems && <z-icon name={this.open ? \"chevron-up\" : \"chevron-down\"} />}\n </button>\n {this.open && (\n <div\n class=\"items\"\n role=\"menu\"\n >\n <slot\n name=\"section\"\n onSlotchange={this.onItemsChange}\n />\n </div>\n )}\n </Host>\n );\n }\n}\n"],"version":3}
|
|
1
|
+
{"file":"z-menu-section.js","mappings":"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","names":["ZMenuSection"],"sources":["src/components/z-menu-section/styles.css?tag=z-menu-section&encapsulation=shadow","src/components/z-menu-section/index.tsx"],"sourcesContent":[":host {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n justify-content: center;\n padding: 0;\n font-family: var(--font-family-sans);\n}\n\n:host,\n::slotted(*),\n* {\n box-sizing: border-box;\n}\n\n::slotted(a) {\n text-decoration: none;\n}\n\n::slotted(*) {\n color: var(--color-default-text);\n font-family: var(--font-family-sans);\n font-weight: var(--font-rg);\n}\n\n.label {\n display: flex;\n width: 100%;\n align-items: center;\n padding: var(--space-unit) 0;\n border: 0;\n border-bottom: var(--border-size-small) solid var(--color-surface03);\n margin: 0;\n background: transparent;\n border-radius: 0;\n cursor: pointer;\n text-align: left;\n}\n\n:host(:last-child:not([open])) .label {\n border-bottom: none;\n}\n\n:host(:is([active], [open])) .label,\n.label:focus:focus-visible,\n.label:hover {\n border-color: var(--color-secondary01);\n}\n\n.label:focus:focus-visible {\n box-shadow: var(--shadow-focus-primary);\n outline: none;\n}\n\n:host(:is([active], [open])) .label ::slotted(*),\n.label:focus:focus-visible ::slotted(*),\n.label:hover ::slotted(*) {\n font-weight: var(--font-bd);\n}\n\n::slotted([data-text]) {\n display: inline-flex;\n flex-direction: column;\n}\n\n/* Trick to prevent layout shifts on font-weight changes.\nThe trick is to put an hidden copy of the text already set to bold,\nso the needed space is correctly calculated before any hover/active state changes the\nfont-weight of the real text.\nThe hidden text has an height of 0px so it can expand the width without changing the height\nwhen placed below the real text using `flex-direction: column`. */\n::slotted([data-text])::after {\n overflow: hidden;\n height: 0;\n content: attr(data-text);\n content: attr(data-text) / \"\";\n font-weight: var(--font-bd);\n pointer-events: none;\n user-select: none;\n visibility: hidden;\n}\n\n@media speech {\n ::slotted([data-text])::after {\n display: none;\n }\n}\n\n.label ::slotted(*) {\n width: 100%;\n margin: 0;\n font-size: var(--font-size-3);\n line-height: 1.5;\n}\n\n.label z-icon {\n margin-left: calc(var(--space-unit) * 4);\n fill: var(--color-default-icon);\n}\n\n.items {\n display: flex;\n width: 100%;\n flex-direction: column;\n padding: calc(var(--space-unit) / 2);\n padding-bottom: calc(var(--space-unit) * 1.5);\n}\n\n.items[hidden] {\n display: none;\n}\n\n::slotted([slot=\"section\"]) {\n display: inline-flex;\n padding: calc(var(--space-unit) / 2);\n margin: 0;\n font-size: var(--font-size-1);\n line-height: 1.333;\n outline: none;\n}\n\n::slotted([slot=\"section\"]:last-of-type) {\n border: none;\n}\n\n::slotted([slot=\"section\"]:focus:focus-visible) {\n box-shadow: var(--shadow-focus-primary);\n color: var(--color-secondary01);\n}\n\n::slotted([slot=\"section\"]:hover),\n::slotted([slot=\"section\"]:focus:focus-visible),\n::slotted([slot=\"section\"][active]) {\n color: var(--color-secondary01);\n font-weight: var(--font-bd);\n}\n","import {Component, Element, Event, EventEmitter, Host, Listen, Method, Prop, State, Watch, h} from \"@stencil/core\";\nimport {KeyboardCode} from \"../../beans\";\n\n/**\n * A component to create submenus inside the ZMenu.\n * @slot - Label of the menu section.\n * @slot item - Single entry of the section. Set the same slot name to different items to put many of them. Add the `active` attribute to a slotted item to highlight it.\n */\n@Component({\n tag: \"z-menu-section\",\n styleUrl: \"styles.css\",\n shadow: true,\n})\nexport class ZMenuSection {\n @Element() host: HTMLZMenuSectionElement;\n\n /** Active state */\n @Prop({reflect: true})\n active?: boolean;\n\n /**\n * Tabindex value to set on the label button.\n * Useful to manage keyboard navigation focus with roving tabindex handled by this component's parent (usually ZMenu).\n */\n @Prop()\n htmlTabindex = -1;\n\n /** The opening state of the section. */\n @Prop({mutable: true})\n open: boolean;\n\n @State()\n hasItems: boolean;\n\n @State()\n items: HTMLElement[];\n\n /** The section has been opened. */\n @Event()\n opened: EventEmitter;\n\n /** The section has been closed. */\n @Event()\n closed: EventEmitter;\n\n private label: HTMLButtonElement;\n\n private get focusableItem(): HTMLElement {\n return this.items.find(({tabIndex}) => tabIndex === 0);\n }\n\n private toggle(): void {\n if (!this.hasItems) {\n return;\n }\n\n this.open = !this.open;\n }\n\n private setItemsA11yAttrs(): void {\n if (!this.hasItems) {\n return;\n }\n\n this.items.forEach((item) => {\n item.setAttribute(\"role\", \"menuitem\");\n item.tabIndex = -1;\n });\n }\n\n private onItemsChange(): void {\n this.items = Array.from(this.host.querySelectorAll('[slot=\"section\"]')) as HTMLElement[];\n this.hasItems = this.items.length > 0;\n this.setItemsA11yAttrs();\n }\n\n /**\n * Sets slotted item text as `data-text` attribute value, to let CSS use it through `attr()`.\n * @param ev Slotchange event\n */\n private onLabelSlotChange(ev: Event): void {\n const labelElement = (ev.target as HTMLSlotElement).assignedElements()[0] as HTMLElement;\n labelElement.dataset.text = labelElement?.textContent;\n }\n\n private onLabelClick(): void {\n this.toggle();\n this.setFocus();\n }\n\n private onLabelKeydown(ev: KeyboardEvent): void {\n if (ev.key === KeyboardCode.ENTER || ev.key === KeyboardCode.SPACE) {\n ev.preventDefault();\n ev.stopPropagation();\n this.toggle();\n if (this.open) {\n this.focustFirstItem();\n }\n }\n }\n\n /**\n * Move focus and adjust the tabindex value of `receiver` and `current` elements,\n * setting -1 to the `current` and 0 to the `receiver`, then focus the `receiver` element.\n */\n private moveFocus(receiver: HTMLElement, current?: HTMLElement): void {\n receiver.tabIndex = 0;\n setTimeout(() => {\n receiver.focus();\n }, 100);\n if (current) {\n current.tabIndex = -1;\n }\n }\n\n private focustFirstItem(): void {\n this.moveFocus(this.items[0]);\n }\n\n /** Focus the last item. */\n @Method()\n async focusLastItem(): Promise<void> {\n this.moveFocus(this.items[this.items.length - 1]);\n }\n\n /** Set tabindex of the label to 0, then focus it. */\n @Method()\n async setFocus(): Promise<void> {\n this.htmlTabindex = 0;\n setTimeout(() => {\n this.label.focus();\n }, 100);\n }\n\n @Watch(\"open\")\n onOpenChange(): void {\n if (!this.open) {\n this.setItemsA11yAttrs();\n this.closed.emit();\n } else {\n this.opened.emit();\n }\n }\n\n @Watch(\"htmlTabindex\")\n onTabindexChange(): void {\n this.label.tabIndex = this.htmlTabindex;\n }\n\n @Listen(\"keydown\")\n private onItemsKeydown(ev: KeyboardEvent): void {\n switch (ev.key) {\n case KeyboardCode.ESC:\n case KeyboardCode.ARROW_LEFT:\n if (!this.open) {\n break;\n }\n ev.preventDefault();\n ev.stopPropagation();\n this.moveFocus(this.label, this.focusableItem);\n this.open = false;\n break;\n case KeyboardCode.ARROW_RIGHT:\n if (this.open) {\n break;\n }\n ev.preventDefault();\n ev.stopPropagation();\n this.open = true;\n this.focustFirstItem();\n break;\n case KeyboardCode.ARROW_DOWN: {\n if (!this.open) {\n break;\n }\n if (document.activeElement === this.host) {\n ev.preventDefault();\n ev.stopPropagation();\n this.focustFirstItem();\n break;\n }\n const currentIndex = this.items.indexOf(this.focusableItem);\n const receiver = this.items[currentIndex + 1];\n if (receiver) {\n ev.preventDefault();\n ev.stopPropagation();\n this.moveFocus(receiver, this.focusableItem);\n } else {\n this.htmlTabindex = 0;\n this.focusableItem.tabIndex = -1;\n }\n break;\n }\n case KeyboardCode.ARROW_UP: {\n if (!this.open || document.activeElement === this.host) {\n break;\n }\n const currentIndex = this.items.indexOf(this.focusableItem);\n const receiver = this.items[currentIndex - 1];\n ev.preventDefault();\n ev.stopPropagation();\n if (receiver) {\n this.moveFocus(receiver, this.focusableItem);\n } else {\n // since there isn't a previous item to focus, give the focus to the label element\n this.focusableItem.tabIndex = -1;\n this.setFocus();\n }\n break;\n }\n }\n }\n\n constructor() {\n this.toggle = this.toggle.bind(this);\n this.onItemsChange = this.onItemsChange.bind(this);\n this.onLabelSlotChange = this.onLabelSlotChange.bind(this);\n this.onLabelClick = this.onLabelClick.bind(this);\n this.onLabelKeydown = this.onLabelKeydown.bind(this);\n this.onItemsKeydown = this.onItemsKeydown.bind(this);\n }\n\n connectedCallback(): void {\n this.onItemsChange();\n }\n\n render(): HTMLZMenuSectionElement {\n return (\n <Host open={this.open}>\n <button\n ref={(el) => (this.label = el)}\n class=\"label\"\n aria-haspopup={`${!!this.hasItems}`}\n aria-expanded={`${!!this.open}`}\n role=\"menuitem\"\n tabindex={this.htmlTabindex}\n onClick={this.onLabelClick}\n onKeyDown={this.onLabelKeydown}\n >\n <slot onSlotchange={this.onLabelSlotChange} />\n {this.hasItems && <z-icon name={this.open ? \"chevron-up\" : \"chevron-down\"} />}\n </button>\n <div\n class=\"items\"\n role=\"menu\"\n hidden={!this.open}\n >\n <slot\n name=\"section\"\n onSlotchange={this.onItemsChange}\n />\n </div>\n </Host>\n );\n }\n}\n"],"version":3}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { proxyCustomElement, HTMLElement, createEvent, h, Host } from '@stencil/core/internal/client';
|
|
2
2
|
import { g as KeyboardCode } from './index2.js';
|
|
3
|
+
import { a as containsElement } from './utils.js';
|
|
3
4
|
import { d as defineCustomElement$2 } from './index9.js';
|
|
4
5
|
|
|
5
|
-
const stylesCss = ":host,::slotted(*),*{box-sizing:border-box;outline:none}:host{position:relative;display:inline-flex;height:fit-content;flex-direction:column}::slotted(a){text-decoration:none}::slotted(*){color:var(--color-default-text);font-family:var(--font-family-sans);font-weight:var(--font-rg)}.menu-label{position:relative;width:100%;padding:0;border:0;margin:0;background:transparent;border-radius:0;color:inherit;text-align:left}
|
|
6
|
+
const stylesCss = ":host,::slotted(*),*{box-sizing:border-box;outline:none}:host{position:relative;display:inline-flex;height:fit-content;flex-direction:column}::slotted(a){text-decoration:none}::slotted(*){color:var(--color-default-text);font-family:var(--font-family-sans);font-weight:var(--font-rg)}.menu-label{position:relative;display:flex;width:100%;align-items:center;padding:0;border:0;border-bottom:var(--border-size-large) solid transparent;margin:0;background:transparent;border-radius:0;color:inherit;text-align:left}button.menu-label{cursor:pointer}.menu-label:focus-visible,div.menu-label:focus-within{box-shadow:var(--shadow-focus-primary)}:host(:is([active],[open])) .menu-label ::slotted(*),.menu-label:focus-visible ::slotted(*),div.menu-label:focus-within ::slotted(*){color:var(--color-primary01);font-weight:var(--font-bd)}:host([vertical-context]) .menu-label{padding:var(--space-unit) 0;border-width:var(--border-size-small);border-color:var(--color-surface03)}:host(:is([active],[open])) .menu-label,.menu-label:hover,.menu-label:focus-visible,div.menu-label:focus-within{border-color:var(--color-secondary01)}:host([vertical-context]:is([active],[open])) .menu-label::after,:host([vertical-context]) .menu-label:hover::after,:host([vertical-context]) .menu-label:focus-visible::after,:host([vertical-context]) div.menu-label:focus-within::after{position:absolute;bottom:0;left:0;width:100%;height:var(--border-size-large);background-color:var(--color-secondary01);content:\"\"}:host([vertical-context]) .menu-label ::slotted(*){padding:0}.menu-label ::slotted(*){display:inline-flex;width:100%;min-width:fit-content;padding-bottom:2px;margin:0;appearance:none;color:var(--z-menu-label-color, var(--color-default-text));font-family:var(--font-family-sans);font-size:var(--font-size-3);font-weight:inherit;line-height:1.5}.menu-label z-icon{margin-left:calc(var(--space-unit) * 1.5);fill:var(--color-default-icon)}::slotted([data-text]:not([slot]))::after{height:0;content:attr(data-text);content:attr(data-text) / \"\";font-weight:var(--font-bd);letter-spacing:normal;pointer-events:none;user-select:none;visibility:hidden}@media speech{::slotted([data-text]:not([slot]))::after{display:none}}::slotted([data-text]:not([slot])){display:inline-flex;flex-direction:column}.content{background:var(--color-surface01)}:host(:not([open])) .content{display:none}:host([floating]:not([vertical-context])) .content{position:absolute;top:100%;left:0;width:375px;min-width:100%;max-width:100vw;padding:0 calc(var(--space-unit) * 2);box-shadow:var(--shadow-2)}:host(:not([floating])) .content{width:100%}.header{display:flex;align-items:center;padding:var(--space-unit) 0 calc(var(--space-unit) * 2)}.header ::slotted(img[slot=\"header\"]){width:calc(var(--space-unit) * 11.25);height:auto;object-fit:contain}.header ::slotted([slot=\"header\"]:not(:first-child)){margin:auto 0;margin-left:calc(var(--space-unit) * 2.5);font-size:var(--font-size-3);font-weight:var(--font-sb);line-height:1.5}.items{display:flex;flex-direction:column;align-items:flex-start;background:inherit}.items>::slotted([slot=\"item\"]){width:100%;margin:0;font-size:var(--font-size-3);line-height:1.5}.items>::slotted([slot=\"item\"]:focus:focus-visible){box-shadow:var(--shadow-focus-primary)}.items>::slotted([slot=\"item\"]:not(z-menu-section)){padding:var(--space-unit) 0;border-bottom:var(--border-size-small) solid var(--color-surface03)}:host(:not([vertical-context])) .items>::slotted([slot=\"item\"]:last-child){border-bottom:0}.items>::slotted([slot=\"item\"]:hover),.items>::slotted([slot=\"item\"]:focus:focus-visible),.items>::slotted([slot=\"item\"]:active){border-color:var(--color-secondary01);font-weight:var(--font-bd)}";
|
|
6
7
|
const ZMenuStyle0 = stylesCss;
|
|
7
8
|
|
|
8
9
|
const isZMenuSection = (el) => (el === null || el === void 0 ? void 0 : el.tagName) === "Z-MENU-SECTION";
|
|
@@ -56,12 +57,9 @@ const ZMenu$1 = /*@__PURE__*/ proxyCustomElement(class ZMenu extends HTMLElement
|
|
|
56
57
|
setItemsA11yAttrs() {
|
|
57
58
|
this.items.forEach((item, index) => {
|
|
58
59
|
const tabindex = index === 0 ? 0 : -1;
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
60
|
+
this.setItemTabindex(item, tabindex);
|
|
61
|
+
if (!isZMenuSection(item)) {
|
|
63
62
|
item.setAttribute("role", "menuitem");
|
|
64
|
-
item.tabIndex = tabindex;
|
|
65
63
|
}
|
|
66
64
|
});
|
|
67
65
|
}
|
|
@@ -75,6 +73,14 @@ const ZMenu$1 = /*@__PURE__*/ proxyCustomElement(class ZMenu extends HTMLElement
|
|
|
75
73
|
}
|
|
76
74
|
});
|
|
77
75
|
}
|
|
76
|
+
setItemTabindex(item, tabIndex) {
|
|
77
|
+
if (isZMenuSection(item)) {
|
|
78
|
+
item.htmlTabindex = tabIndex;
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
item.tabIndex = tabIndex;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
78
84
|
/**
|
|
79
85
|
* Move focus and adjust the tabindex value of `receiver` and `current` elements,
|
|
80
86
|
* setting -1 to the `current` and 0 to the `receiver`, then focus the `receiver` element.
|
|
@@ -93,18 +99,21 @@ const ZMenu$1 = /*@__PURE__*/ proxyCustomElement(class ZMenu extends HTMLElement
|
|
|
93
99
|
if (!current) {
|
|
94
100
|
return;
|
|
95
101
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
+
this.setItemTabindex(current, -1);
|
|
103
|
+
}
|
|
104
|
+
onLabelClick() {
|
|
105
|
+
this.toggle();
|
|
106
|
+
this.setFocus();
|
|
102
107
|
}
|
|
103
108
|
onLabelKeydown(ev) {
|
|
104
109
|
if (ev.key === KeyboardCode.ENTER || ev.key === KeyboardCode.SPACE) {
|
|
105
110
|
ev.preventDefault();
|
|
106
111
|
ev.stopPropagation();
|
|
107
112
|
this.toggle();
|
|
113
|
+
if (this.open) {
|
|
114
|
+
this.moveFocus(this.items[0]);
|
|
115
|
+
}
|
|
116
|
+
return;
|
|
108
117
|
}
|
|
109
118
|
if (!this.verticalContext) {
|
|
110
119
|
return;
|
|
@@ -113,12 +122,7 @@ const ZMenu$1 = /*@__PURE__*/ proxyCustomElement(class ZMenu extends HTMLElement
|
|
|
113
122
|
ev.preventDefault();
|
|
114
123
|
ev.stopPropagation();
|
|
115
124
|
this.open = true;
|
|
116
|
-
|
|
117
|
-
}
|
|
118
|
-
if (ev.key === KeyboardCode.ARROW_LEFT && this.open) {
|
|
119
|
-
ev.preventDefault();
|
|
120
|
-
ev.stopPropagation();
|
|
121
|
-
this.open = false;
|
|
125
|
+
this.moveFocus(this.items[0]);
|
|
122
126
|
}
|
|
123
127
|
}
|
|
124
128
|
/** Set tabindex of the label to 0, then focus it. */
|
|
@@ -127,13 +131,18 @@ const ZMenu$1 = /*@__PURE__*/ proxyCustomElement(class ZMenu extends HTMLElement
|
|
|
127
131
|
const label = this.hasContent ? this.labelButton : this.host.firstElementChild;
|
|
128
132
|
label.focus();
|
|
129
133
|
}
|
|
130
|
-
/**
|
|
134
|
+
/**
|
|
135
|
+
* Focus the last item.
|
|
136
|
+
*/
|
|
131
137
|
async focusLastItem() {
|
|
132
|
-
this.
|
|
133
|
-
|
|
138
|
+
const lastItem = this.items[this.items.length - 1];
|
|
139
|
+
if (isZMenuSection(lastItem) && lastItem.open) {
|
|
140
|
+
lastItem.focusLastItem();
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
this.moveFocus(lastItem);
|
|
134
144
|
}
|
|
135
145
|
onOpenChanged() {
|
|
136
|
-
this.setItemsA11yAttrs();
|
|
137
146
|
if (!this.open) {
|
|
138
147
|
cancelAnimationFrame(this.raf);
|
|
139
148
|
this.closed.emit();
|
|
@@ -144,6 +153,7 @@ const ZMenu$1 = /*@__PURE__*/ proxyCustomElement(class ZMenu extends HTMLElement
|
|
|
144
153
|
});
|
|
145
154
|
return;
|
|
146
155
|
}
|
|
156
|
+
this.setItemsA11yAttrs();
|
|
147
157
|
this.opened.emit();
|
|
148
158
|
if (this.floating) {
|
|
149
159
|
this.reflow(true);
|
|
@@ -161,74 +171,108 @@ const ZMenu$1 = /*@__PURE__*/ proxyCustomElement(class ZMenu extends HTMLElement
|
|
|
161
171
|
slottedLabel.role = "menuitem";
|
|
162
172
|
slottedLabel.tabIndex = this.htmlTabindex;
|
|
163
173
|
}
|
|
174
|
+
/**
|
|
175
|
+
* Set tabindex to -1 to all siblings of the clicked item.
|
|
176
|
+
*/
|
|
177
|
+
onItemClick(ev) {
|
|
178
|
+
const clickedItem = this.items.find((item) => containsElement(item, ev.target));
|
|
179
|
+
if (clickedItem) {
|
|
180
|
+
this.items.forEach((item) => {
|
|
181
|
+
if (item === clickedItem) {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
if (isZMenuSection(item)) {
|
|
185
|
+
item.htmlTabindex = -1;
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
item.tabIndex = -1;
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
}
|
|
164
193
|
onKeyDown(ev) {
|
|
194
|
+
var _a;
|
|
165
195
|
if (!this.hasContent) {
|
|
166
196
|
return;
|
|
167
197
|
}
|
|
168
198
|
switch (ev.key) {
|
|
169
199
|
case KeyboardCode.ESC:
|
|
200
|
+
if (!this.open) {
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
170
203
|
ev.stopPropagation();
|
|
171
204
|
ev.preventDefault();
|
|
172
205
|
this.open = false;
|
|
173
206
|
this.setFocus();
|
|
174
207
|
break;
|
|
175
208
|
case KeyboardCode.ARROW_DOWN: {
|
|
176
|
-
if (this.verticalContext && document.activeElement === this.host && !this.open) {
|
|
177
|
-
break;
|
|
178
|
-
}
|
|
179
209
|
if (document.activeElement === this.host) {
|
|
180
|
-
if (!this.open) {
|
|
181
|
-
|
|
210
|
+
if (this.verticalContext && !this.open) {
|
|
211
|
+
break;
|
|
182
212
|
}
|
|
183
213
|
ev.stopPropagation();
|
|
184
214
|
ev.preventDefault();
|
|
215
|
+
if (!this.open) {
|
|
216
|
+
this.open = true;
|
|
217
|
+
}
|
|
185
218
|
this.moveFocus(this.items[0]);
|
|
186
219
|
break;
|
|
187
220
|
}
|
|
188
221
|
const currentIndex = this.items.indexOf(this.focusableItem);
|
|
189
|
-
|
|
190
|
-
|
|
222
|
+
if (this.verticalContext && currentIndex === this.items.length - 1) {
|
|
223
|
+
// navigation is going to leave this menu. restore tabindex to the label and let the parent handle it
|
|
224
|
+
this.setItemTabindex(this.items[currentIndex], -1);
|
|
225
|
+
this.htmlTabindex = 0;
|
|
191
226
|
break;
|
|
192
227
|
}
|
|
193
228
|
ev.stopPropagation();
|
|
194
229
|
ev.preventDefault();
|
|
230
|
+
const receiver = this.items[currentIndex + 1];
|
|
195
231
|
// if the last item is already focused, navigate to the first one
|
|
196
232
|
this.moveFocus(receiver !== null && receiver !== void 0 ? receiver : this.items[0], this.focusableItem);
|
|
197
233
|
break;
|
|
198
234
|
}
|
|
199
235
|
case KeyboardCode.ARROW_UP: {
|
|
200
|
-
if (this.verticalContext && document.activeElement === this.host) {
|
|
201
|
-
break;
|
|
202
|
-
}
|
|
203
236
|
if (document.activeElement === this.host) {
|
|
237
|
+
if (this.verticalContext) {
|
|
238
|
+
break;
|
|
239
|
+
}
|
|
240
|
+
ev.stopPropagation();
|
|
241
|
+
ev.preventDefault();
|
|
204
242
|
// open the menu and focus the last item
|
|
205
243
|
if (!this.open) {
|
|
206
244
|
this.open = true;
|
|
207
245
|
}
|
|
208
|
-
ev.stopPropagation();
|
|
209
|
-
ev.preventDefault();
|
|
210
246
|
this.moveFocus(this.items[this.items.length - 1], this.focusableItem);
|
|
211
247
|
break;
|
|
212
248
|
}
|
|
213
249
|
ev.stopPropagation();
|
|
214
250
|
ev.preventDefault();
|
|
215
251
|
const currentIndex = this.items.indexOf(this.focusableItem);
|
|
216
|
-
|
|
217
|
-
|
|
252
|
+
if (currentIndex === 0 && this.verticalContext) {
|
|
253
|
+
this.setItemTabindex(this.focusableItem, -1);
|
|
218
254
|
this.setFocus();
|
|
219
255
|
break;
|
|
220
256
|
}
|
|
257
|
+
const receiver = (_a = this.items[currentIndex - 1]) !== null && _a !== void 0 ? _a : this.items[this.items.length - 1];
|
|
258
|
+
// if the receiver is a ZMenuSection and it's open, focus its last item
|
|
221
259
|
if (isZMenuSection(receiver) && receiver.open) {
|
|
222
|
-
|
|
223
|
-
? (this.focusableItem.htmlTabindex = -1)
|
|
224
|
-
: (this.focusableItem.tabIndex = -1);
|
|
260
|
+
this.setItemTabindex(this.focusableItem, -1);
|
|
225
261
|
receiver.focusLastItem();
|
|
226
262
|
break;
|
|
227
263
|
}
|
|
228
|
-
|
|
229
|
-
this.moveFocus(receiver !== null && receiver !== void 0 ? receiver : this.items[this.items.length - 1], this.focusableItem);
|
|
264
|
+
this.moveFocus(receiver, this.focusableItem);
|
|
230
265
|
break;
|
|
231
266
|
}
|
|
267
|
+
case KeyboardCode.ARROW_LEFT:
|
|
268
|
+
if (!this.open || !this.verticalContext) {
|
|
269
|
+
break;
|
|
270
|
+
}
|
|
271
|
+
// close the menu and focus the label
|
|
272
|
+
ev.preventDefault();
|
|
273
|
+
ev.stopPropagation();
|
|
274
|
+
this.open = false;
|
|
275
|
+
this.setFocus();
|
|
232
276
|
}
|
|
233
277
|
}
|
|
234
278
|
constructor() {
|
|
@@ -247,6 +291,7 @@ const ZMenu$1 = /*@__PURE__*/ proxyCustomElement(class ZMenu extends HTMLElement
|
|
|
247
291
|
this.toggle = this.toggle.bind(this);
|
|
248
292
|
this.checkContent = this.checkContent.bind(this);
|
|
249
293
|
this.onLabelSlotChange = this.onLabelSlotChange.bind(this);
|
|
294
|
+
this.onLabelClick = this.onLabelClick.bind(this);
|
|
250
295
|
this.onItemsChange = this.onItemsChange.bind(this);
|
|
251
296
|
this.onLabelKeydown = this.onLabelKeydown.bind(this);
|
|
252
297
|
}
|
|
@@ -256,9 +301,9 @@ const ZMenu$1 = /*@__PURE__*/ proxyCustomElement(class ZMenu extends HTMLElement
|
|
|
256
301
|
}
|
|
257
302
|
render() {
|
|
258
303
|
if (!this.hasContent) {
|
|
259
|
-
return (h("div", { class: "menu-
|
|
304
|
+
return (h("div", { class: "menu-label" }, h("slot", { onSlotchange: this.onLabelSlotChange })));
|
|
260
305
|
}
|
|
261
|
-
return (h(Host, null, h("
|
|
306
|
+
return (h(Host, null, h("button", { ref: (el) => (this.labelButton = el), class: "menu-label", "aria-expanded": `${!!this.open}`, "aria-haspopup": `${this.hasContent}`, "aria-label": this.open ? "Chiudi menù" : "Apri menù", role: "menuitem", tabIndex: this.htmlTabindex, onClick: this.onLabelClick, onKeyDown: this.onLabelKeydown }, h("slot", { onSlotchange: this.onLabelSlotChange }), h("z-icon", { name: this.open ? "chevron-up" : "chevron-down" })), h("div", { class: "content", ref: (el) => (this.content = el) }, this.hasHeader && (h("header", { class: "header" }, h("slot", { name: "header", onSlotchange: this.checkContent }))), h("div", { class: "items", role: "menu" }, h("slot", { name: "item", onSlotchange: this.onItemsChange })))));
|
|
262
307
|
}
|
|
263
308
|
get host() { return this; }
|
|
264
309
|
static get watchers() { return {
|
|
@@ -276,7 +321,7 @@ const ZMenu$1 = /*@__PURE__*/ proxyCustomElement(class ZMenu extends HTMLElement
|
|
|
276
321
|
"hasContent": [32],
|
|
277
322
|
"setFocus": [64],
|
|
278
323
|
"focusLastItem": [64]
|
|
279
|
-
}, [[0, "keydown", "onKeyDown"]], {
|
|
324
|
+
}, [[4, "click", "onItemClick"], [0, "keydown", "onKeyDown"]], {
|
|
280
325
|
"open": ["onOpenChanged"],
|
|
281
326
|
"htmlTabindex": ["setLabelA11yAttrs"]
|
|
282
327
|
}]);
|