@nuralyui/menu 0.0.18 → 0.0.20

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/bundle.js CHANGED
@@ -1,27 +1,468 @@
1
- import{css as e,LitElement as n,html as t,nothing as r}from"lit";import{property as i,customElement as o}from"lit/decorators.js";import{NuralyUIBaseMixin as s}from"@nuralyui/common/mixins";const a=[e`:host{display:block}.menu-root{font-size:var(--nuraly-menu-font-size);font-family:var(--nuraly-menu-font-family);font-weight:var(--nuraly-menu-font-weight);line-height:var(--nuraly-menu-line-height);list-style:none;margin:0;padding:0}.menu-link{list-style:none;display:flex;align-items:center;cursor:pointer;padding:var(--nuraly-menu-link-padding-vertical) var(--nuraly-menu-link-padding-horizontal);color:var(--nuraly-menu-link-color);background-color:var(--nuraly-menu-link-background-color);border-left:4px solid transparent;border-top:2px solid transparent;border-right:2px solid transparent;border-bottom:2px solid transparent;border-radius:var(--nuraly-menu-border-radius);transition:background-color var(--nuraly-menu-transition-duration) var(--nuraly-menu-transition-timing),color var(--nuraly-menu-transition-duration) var(--nuraly-menu-transition-timing),border-color var(--nuraly-menu-transition-duration) var(--nuraly-menu-transition-timing)}.menu-link.disabled{color:var(--nuraly-menu-disabled-link-color);cursor:not-allowed;opacity:.6}.menu-link:not(.disabled):not(.selected):hover{background-color:var(--nuraly-menu-hover-link-background-color);color:var(--nuraly-menu-hover-link-color)}.menu-link.selected{background-color:var(--nuraly-menu-selected-link-background-color);color:var(--nuraly-menu-selected-color);border-left:var(--nuraly-menu-selected-link-border)}.menu-link:not(.disabled):not(.selected):focus{outline:0;border-left:4px solid transparent;border-top:var(--nuraly-menu-focus-border);border-right:var(--nuraly-menu-focus-border);border-bottom:var(--nuraly-menu-focus-border);color:var(--nuraly-menu-focus-color)}.menu-link.selected:not(.disabled):focus{outline:0;border-left:var(--nuraly-menu-selected-link-border);border-top:var(--nuraly-menu-focus-border);border-right:var(--nuraly-menu-focus-border);border-bottom:var(--nuraly-menu-focus-border);color:var(--nuraly-menu-focus-color)}.menu-link:not(.disabled):focus-visible{outline:0;border-top:var(--nuraly-menu-focus-border);border-right:var(--nuraly-menu-focus-border);border-bottom:var(--nuraly-menu-focus-border)}.menu-link:not(.disabled):not(.selected):focus-visible{border-left:var(--nuraly-menu-focus-border);color:var(--nuraly-menu-focus-color)}.menu-link.selected:not(.disabled):focus-visible{border-left:var(--nuraly-menu-selected-link-border)!important;color:var(--nuraly-menu-focus-color)}.menu-link:not(.disabled):not(.selected):active{color:var(--nuraly-menu-active-color);background-color:var(--nuraly-menu-active-background-color)}.menu-link.selected:not(.disabled):active{background-color:var(--nuraly-menu-active-background-color);color:var(--nuraly-menu-active-color);border-left:var(--nuraly-menu-selected-link-border)!important;border-top:2px solid transparent;border-right:2px solid transparent;border-bottom:2px solid transparent}.menu-link .action-text-container{width:100%;display:flex;justify-content:space-between;align-items:center;position:relative}.menu-link .text-container{flex:1;min-width:0}.menu-link nr-icon{display:flex;align-items:center;--nuraly-icon-color:var(--nuraly-menu-link-icon-color)}.menu-link nr-icon:first-child{padding-right:var(--nuraly-menu-icon-padding-right);padding-left:var(--nuraly-menu-icon-padding-left)}.sub-menu{display:flex;flex-direction:column;padding-left:0;list-style:none;color:var(--nuraly-sub-menu-color)}.sub-menu.disabled .sub-menu-header{color:var(--nuraly-sub-menu-disabled-color);cursor:not-allowed;opacity:.6}.sub-menu.highlighted .sub-menu-header{background-color:var(--nuraly-sub-menu-highlighted-background-color);color:var(--nuraly-sub-menu-highlighted-color)}.sub-menu .sub-menu-header{display:flex;justify-content:space-between;align-items:center;cursor:pointer;padding:var(--nuraly-sub-menu-padding-vertical) var(--nuraly-sub-menu-padding-horizontal);border-left:4px solid transparent;border-top:2px solid transparent;border-right:2px solid transparent;border-bottom:2px solid transparent;border-radius:var(--nuraly-menu-border-radius);transition:background-color var(--nuraly-menu-transition-duration) var(--nuraly-menu-transition-timing),color var(--nuraly-menu-transition-duration) var(--nuraly-menu-transition-timing),border-color var(--nuraly-menu-transition-duration) var(--nuraly-menu-transition-timing)}.sub-menu .sub-menu-header span{flex:1;min-width:0;padding-left:var(--nuraly-sub-menu-icon-padding-right)}.sub-menu .text-icon{flex-shrink:0}.sub-menu .icons-container{display:flex;align-items:center;gap:var(--nuraly-sub-menu-icon-padding-right);position:relative;flex-shrink:0;min-width:fit-content;height:100%;min-height:24px}.menu-link .icon-container{display:flex;align-items:center;position:relative;flex-shrink:0;height:100%;min-height:24px}.menu-link nr-dropdown,.sub-menu nr-dropdown{display:inline-flex;flex-shrink:0;flex-grow:0;align-items:center;vertical-align:middle}.menu-link .action-icon,.sub-menu .action-icon{flex-shrink:0;cursor:pointer}.sub-menu .action-icon{--nuraly-icon-color:var(--nuraly-sub-menu-action-icon-color)}.sub-menu .status-icon{--nuraly-icon-color:var(--nuraly-sub-menu-status-icon-color)}.sub-menu .text-icon{--nuraly-icon-color:var(--nuraly-sub-menu-text-icon-color)}.sub-menu #toggle-icon{--nuraly-icon-color:var(--nuraly-sub-menu-toggle-icon-color)}.sub-menu:not(.disabled):not(.selected) .sub-menu-header:focus{outline:0;border-left:4px solid transparent;border-top:var(--nuraly-sub-menu-focus-border);border-right:var(--nuraly-sub-menu-focus-border);border-bottom:var(--nuraly-sub-menu-focus-border);color:var(--nuraly-sub-menu-focus-color)}.sub-menu.selected:not(.disabled) .sub-menu-header:focus{outline:0;border-left:var(--nuraly-menu-selected-link-border);border-top:var(--nuraly-sub-menu-focus-border);border-right:var(--nuraly-sub-menu-focus-border);border-bottom:var(--nuraly-sub-menu-focus-border);color:var(--nuraly-sub-menu-focus-color)}.sub-menu:not(.disabled) .sub-menu-header:focus-visible{outline:0;border-top:var(--nuraly-sub-menu-focus-border);border-right:var(--nuraly-sub-menu-focus-border);border-bottom:var(--nuraly-sub-menu-focus-border)}.sub-menu:not(.disabled):not(.selected) .sub-menu-header:focus-visible{border-left:var(--nuraly-sub-menu-focus-border);color:var(--nuraly-sub-menu-focus-color)}.sub-menu.selected:not(.disabled) .sub-menu-header:focus-visible{border-left:var(--nuraly-menu-selected-link-border)!important;color:var(--nuraly-sub-menu-focus-color)}.sub-menu:not(.disabled) .sub-menu-header:hover{background-color:var(--nuraly-sub-menu-hover-background-color);color:var(--nuraly-sub-menu-hover-color)}.sub-menu.selected:not(.disabled) .sub-menu-header{background-color:var(--nuraly-menu-selected-link-background-color);color:var(--nuraly-menu-selected-color);border-left:var(--nuraly-menu-selected-link-border);border-top:2px solid transparent;border-right:2px solid transparent;border-bottom:2px solid transparent}.sub-menu.selected:not(.disabled) .sub-menu-header:active{background-color:var(--nuraly-sub-menu-active-background-color);color:var(--nuraly-sub-menu-active-color);border-left:var(--nuraly-menu-selected-link-border);border-top:2px solid transparent;border-right:2px solid transparent;border-bottom:2px solid transparent}.sub-menu:not(.disabled):not(.selected) .sub-menu-header:active{background-color:var(--nuraly-sub-menu-active-background-color);color:var(--nuraly-sub-menu-active-color)}.sub-menu-children{padding-left:var(--nuraly-sub-menu-nested-padding-left)}.menu--small .menu-link{padding:var(--nuraly-menu-link-padding-vertical-small) var(--nuraly-menu-link-padding-horizontal-small)}.menu--small .sub-menu .sub-menu-header{padding:var(--nuraly-sub-menu-padding-vertical-small) var(--nuraly-sub-menu-padding-horizontal-small)}.menu--medium .menu-link{padding:var(--nuraly-menu-link-padding-vertical-medium) var(--nuraly-menu-link-padding-horizontal-medium)}.menu--medium .sub-menu .sub-menu-header{padding:var(--nuraly-sub-menu-padding-vertical-medium) var(--nuraly-sub-menu-padding-horizontal-medium)}.menu--large .menu-link{padding:var(--nuraly-menu-link-padding-vertical-large) var(--nuraly-menu-link-padding-horizontal-large)}.menu--large .sub-menu .sub-menu-header{padding:var(--nuraly-sub-menu-padding-vertical-large) var(--nuraly-sub-menu-padding-horizontal-large)}`];
1
+ import{css as e,LitElement as n,html as t,nothing as r}from"lit";import{property as i,customElement as o}from"lit/decorators.js";import{NuralyUIBaseMixin as s}from"@nuralyui/common/mixins";const a=[e`
2
+ /* Root menu container */
3
+ :host {
4
+ display: block;
5
+ }
6
+
7
+ .menu-root {
8
+ font-size: var(--nuraly-menu-font-size);
9
+ font-family: var(--nuraly-menu-font-family);
10
+ font-weight: var(--nuraly-menu-font-weight);
11
+ line-height: var(--nuraly-menu-line-height);
12
+ list-style: none;
13
+ margin: 0;
14
+ padding: 0;
15
+ }
16
+
17
+ /* Menu Link Styles */
18
+ .menu-link {
19
+ list-style: none;
20
+ display: flex;
21
+ align-items: center;
22
+ cursor: pointer;
23
+ padding: var(--nuraly-menu-link-padding, 1px);
24
+ color: var(--nuraly-menu-link-color);
25
+ background-color: var(--nuraly-menu-link-background-color);
26
+ border-left: 4px solid transparent;
27
+ border-top: 2px solid transparent;
28
+ border-right: 2px solid transparent;
29
+ border-bottom: 2px solid transparent;
30
+ border-radius: var(--nuraly-menu-border-radius);
31
+ margin-bottom: 4px;
32
+ gap: 8px;
33
+ }
34
+
35
+ .menu-link.disabled {
36
+ color: var(--nuraly-menu-disabled-link-color);
37
+ cursor: not-allowed;
38
+ opacity: 0.6;
39
+ }
40
+
41
+ .menu-link:not(.disabled):not(.selected):hover {
42
+ background-color: var(--nuraly-menu-hover-link-background-color);
43
+ color: var(--nuraly-menu-hover-link-color);
44
+ }
45
+
46
+ .menu-link.selected {
47
+ background-color: var(--nuraly-menu-selected-link-background-color);
48
+ color: var(--nuraly-menu-selected-color);
49
+ border-left: var(--nuraly-menu-selected-link-border);
50
+ }
51
+
52
+ .menu-link:not(.disabled):not(.selected):focus {
53
+ outline: none;
54
+ border-left: 4px solid transparent;
55
+ border-top: var(--nuraly-menu-focus-border);
56
+ border-right: var(--nuraly-menu-focus-border);
57
+ border-bottom: var(--nuraly-menu-focus-border);
58
+ color: var(--nuraly-menu-focus-color);
59
+ }
60
+
61
+ .menu-link.selected:not(.disabled):focus {
62
+ outline: none;
63
+ border-left: var(--nuraly-menu-selected-link-border);
64
+ border-top: var(--nuraly-menu-focus-border);
65
+ border-right: var(--nuraly-menu-focus-border);
66
+ border-bottom: var(--nuraly-menu-focus-border);
67
+ color: var(--nuraly-menu-focus-color);
68
+ }
69
+
70
+ /* Focus-visible for keyboard navigation */
71
+ .menu-link:not(.disabled):focus-visible {
72
+ outline: none;
73
+ border-top: var(--nuraly-menu-focus-border);
74
+ border-right: var(--nuraly-menu-focus-border);
75
+ border-bottom: var(--nuraly-menu-focus-border);
76
+ }
77
+
78
+ .menu-link:not(.disabled):not(.selected):focus-visible {
79
+ border-left: var(--nuraly-menu-focus-border);
80
+ color: var(--nuraly-menu-focus-color);
81
+ }
82
+
83
+ .menu-link.selected:not(.disabled):focus-visible {
84
+ border-left: var(--nuraly-menu-selected-link-border) !important;
85
+ color: var(--nuraly-menu-focus-color);
86
+ }
87
+
88
+ .menu-link:not(.disabled):not(.selected):active {
89
+ color: var(--nuraly-menu-active-color);
90
+ background-color: var(--nuraly-menu-active-background-color);
91
+ }
92
+
93
+ .menu-link.selected:not(.disabled):active {
94
+ background-color: var(--nuraly-menu-active-background-color);
95
+ color: var(--nuraly-menu-active-color);
96
+ border-left: var(--nuraly-menu-selected-link-border) !important;
97
+ border-top: 2px solid transparent;
98
+ border-right: 2px solid transparent;
99
+ border-bottom: 2px solid transparent;
100
+ }
101
+
102
+ .menu-link .action-text-container {
103
+ width: 100%;
104
+ display: flex;
105
+ justify-content: space-between;
106
+ align-items: center;
107
+ position: relative;
108
+ }
109
+
110
+ .menu-link .text-container {
111
+ flex: 1;
112
+ min-width: 0;
113
+ }
114
+
115
+ .menu-link nr-icon {
116
+ display: flex;
117
+ align-items: center;
118
+ --nuraly-color-icon: var(--nuraly-menu-link-icon-color);
119
+ --nuraly-icon-size: var(--nuraly-menu-icon-size, 20px);
120
+ flex-shrink: 0;
121
+ }
122
+
123
+ .menu-link nr-icon:first-child {
124
+ padding-right: 0;
125
+ padding-left: 0;
126
+ }
127
+
128
+ .menu-link:not(.disabled):not(.selected):hover nr-icon {
129
+ --nuraly-color-icon: var(--nuraly-menu-hover-link-icon-color);
130
+ }
131
+
132
+ .menu-link.selected nr-icon {
133
+ --nuraly-color-icon: var(--nuraly-menu-selected-link-icon-color);
134
+ }
135
+
136
+ /* Sub Menu Styles */
137
+ .sub-menu {
138
+ display: flex;
139
+ flex-direction: column;
140
+ padding-left: 0;
141
+ list-style: none;
142
+ color: var(--nuraly-sub-menu-color);
143
+ margin-bottom: 4px;
144
+ }
145
+
146
+ .sub-menu.disabled .sub-menu-header {
147
+ color: var(--nuraly-sub-menu-disabled-color);
148
+ cursor: not-allowed;
149
+ opacity: 0.6;
150
+ }
151
+
152
+ .sub-menu.highlighted .sub-menu-header {
153
+ background-color: var(--nuraly-sub-menu-highlighted-background-color);
154
+ color: var(--nuraly-sub-menu-highlighted-color);
155
+ }
156
+
157
+ .sub-menu .sub-menu-header {
158
+ display: flex;
159
+ justify-content: space-between;
160
+ align-items: center;
161
+ cursor: pointer;
162
+ padding: var(--nuraly-sub-menu-header-padding, 1px);
163
+ border-left: 4px solid transparent;
164
+ border-top: 2px solid transparent;
165
+ border-right: 2px solid transparent;
166
+ border-bottom: 2px solid transparent;
167
+ border-radius: var(--nuraly-menu-border-radius);
168
+ gap: 8px;
169
+ }
170
+
171
+ .sub-menu .sub-menu-header span {
172
+ flex: 1;
173
+ min-width: 0;
174
+ padding-left: 0;
175
+ }
176
+
177
+ .sub-menu .text-icon {
178
+ flex-shrink: 0;
179
+ --nuraly-color-icon: var(--nuraly-sub-menu-text-icon-color);
180
+ --nuraly-icon-size: var(--nuraly-menu-icon-size, 20px);
181
+ }
182
+
183
+ .sub-menu .icons-container {
184
+ display: flex;
185
+ align-items: center;
186
+ gap: 8px;
187
+ position: relative;
188
+ flex-shrink: 0;
189
+ /* Reserve space for dropdown to prevent layout shift */
190
+ min-width: fit-content;
191
+ /* Fixed height to prevent vertical shifting */
192
+ height: 100%;
193
+ min-height: 20px;
194
+ }
195
+
196
+ .menu-link .icon-container {
197
+ display: flex;
198
+ align-items: center;
199
+ position: relative;
200
+ flex-shrink: 0;
201
+ /* Fixed height to prevent vertical shifting */
202
+ height: 100%;
203
+ min-height: 20px;
204
+ }
205
+
206
+ .sub-menu nr-dropdown,
207
+ .menu-link nr-dropdown {
208
+ /* Keep in normal flow but ensure it doesn't grow/shrink */
209
+ display: inline-flex;
210
+ flex-shrink: 0;
211
+ flex-grow: 0;
212
+ align-items: center;
213
+ vertical-align: middle;
214
+ }
215
+
216
+ .sub-menu .action-icon,
217
+ .menu-link .action-icon {
218
+ flex-shrink: 0;
219
+ cursor: pointer;
220
+ }
221
+
222
+ .sub-menu .action-icon {
223
+ --nuraly-color-icon: var(--nuraly-sub-menu-action-icon-color);
224
+ --nuraly-icon-size: var(--nuraly-menu-icon-size, 16px);
225
+ }
226
+
227
+ .sub-menu .status-icon {
228
+ --nuraly-color-icon: var(--nuraly-sub-menu-status-icon-color);
229
+ --nuraly-icon-size: var(--nuraly-menu-icon-size, 16px);
230
+ }
231
+
232
+ .sub-menu .text-icon {
233
+ --nuraly-color-icon: var(--nuraly-sub-menu-text-icon-color);
234
+ --nuraly-icon-size: var(--nuraly-menu-icon-size, 20px);
235
+ }
236
+
237
+ .sub-menu #toggle-icon {
238
+ --nuraly-color-icon: var(--nuraly-sub-menu-toggle-icon-color);
239
+ --nuraly-icon-size: var(--nuraly-menu-icon-size, 16px);
240
+ }
241
+
242
+ .sub-menu:not(.disabled):not(.selected) .sub-menu-header:focus {
243
+ outline: none;
244
+ border-left: 4px solid transparent;
245
+ border-top: var(--nuraly-sub-menu-focus-border);
246
+ border-right: var(--nuraly-sub-menu-focus-border);
247
+ border-bottom: var(--nuraly-sub-menu-focus-border);
248
+ color: var(--nuraly-sub-menu-focus-color);
249
+ }
250
+
251
+ .sub-menu.selected:not(.disabled) .sub-menu-header:focus {
252
+ outline: none;
253
+ border-left: var(--nuraly-menu-selected-link-border);
254
+ border-top: var(--nuraly-sub-menu-focus-border);
255
+ border-right: var(--nuraly-sub-menu-focus-border);
256
+ border-bottom: var(--nuraly-sub-menu-focus-border);
257
+ color: var(--nuraly-sub-menu-focus-color);
258
+ }
259
+
260
+ /* Focus-visible for keyboard navigation on submenus */
261
+ .sub-menu:not(.disabled) .sub-menu-header:focus-visible {
262
+ outline: none;
263
+ border-top: var(--nuraly-sub-menu-focus-border);
264
+ border-right: var(--nuraly-sub-menu-focus-border);
265
+ border-bottom: var(--nuraly-sub-menu-focus-border);
266
+ }
267
+
268
+ .sub-menu:not(.disabled):not(.selected) .sub-menu-header:focus-visible {
269
+ border-left: var(--nuraly-sub-menu-focus-border);
270
+ color: var(--nuraly-sub-menu-focus-color);
271
+ }
272
+
273
+ .sub-menu.selected:not(.disabled) .sub-menu-header:focus-visible {
274
+ border-left: var(--nuraly-menu-selected-link-border) !important;
275
+ color: var(--nuraly-sub-menu-focus-color);
276
+ }
277
+
278
+ .sub-menu:not(.disabled) .sub-menu-header:hover {
279
+ background-color: var(--nuraly-sub-menu-hover-background-color);
280
+ color: var(--nuraly-sub-menu-hover-color);
281
+ }
282
+
283
+ .sub-menu.selected:not(.disabled) .sub-menu-header {
284
+ background-color: var(--nuraly-menu-selected-link-background-color);
285
+ color: var(--nuraly-menu-selected-color);
286
+ border-left: var(--nuraly-menu-selected-link-border);
287
+ border-top: 2px solid transparent;
288
+ border-right: 2px solid transparent;
289
+ border-bottom: 2px solid transparent;
290
+ }
291
+
292
+ .sub-menu.selected:not(.disabled) .sub-menu-header:active {
293
+ background-color: var(--nuraly-sub-menu-active-background-color);
294
+ color: var(--nuraly-sub-menu-active-color);
295
+ border-left: var(--nuraly-menu-selected-link-border);
296
+ border-top: 2px solid transparent;
297
+ border-right: 2px solid transparent;
298
+ border-bottom: 2px solid transparent;
299
+ }
300
+
301
+ .sub-menu:not(.disabled):not(.selected) .sub-menu-header:active {
302
+ background-color: var(--nuraly-sub-menu-active-background-color);
303
+ color: var(--nuraly-sub-menu-active-color);
304
+ }
305
+
306
+ .sub-menu-children {
307
+ padding-left: var(--nuraly-sub-menu-nested-padding-left);
308
+ }
309
+
310
+ /* Arrow positioning for left arrow */
311
+ .sub-menu.arrow-left .sub-menu-header {
312
+ padding-left: var(--nuraly-sub-menu-arrow-left-padding, 8px); /* Add space for left arrow */
313
+ }
314
+
315
+ .sub-menu.arrow-left .sub-menu-header #toggle-icon {
316
+ margin-right: 8px; /* Space between arrow and text */
317
+ order: -1; /* Place arrow at the beginning */
318
+ }
319
+
320
+ /* Arrow positioning for right arrow (default) */
321
+ .sub-menu.arrow-right .sub-menu-header #toggle-icon {
322
+ margin-left: 8px; /* Space between text and arrow */
323
+ }
324
+
325
+ /* Ensure proper spacing in the header */
326
+ .sub-menu.arrow-left .sub-menu-header span {
327
+ padding-left: 0; /* Remove left padding when arrow is on the left */
328
+ }
329
+
330
+ /* Size Variants */
331
+ .menu--small .menu-link {
332
+ padding: var(--nuraly-menu-link-padding-small, 1px);
333
+ }
334
+
335
+ .menu--small .sub-menu .sub-menu-header {
336
+ padding: var(--nuraly-sub-menu-header-padding-small, 1px);
337
+ }
338
+
339
+ .menu--medium .menu-link {
340
+ padding: var(--nuraly-menu-link-padding-medium, 1px);
341
+ }
342
+
343
+ .menu--medium .sub-menu .sub-menu-header {
344
+ padding: var(--nuraly-sub-menu-header-padding-medium, 1px);
345
+ }
346
+
347
+ .menu--large .menu-link {
348
+ padding: var(--nuraly-menu-link-padding-large, 1px);
349
+ }
350
+
351
+ .menu--large .sub-menu .sub-menu-header {
352
+ padding: var(--nuraly-sub-menu-header-padding-large, 1px);
353
+ }
354
+ `];
2
355
  /**
3
356
  * @license
4
357
  * Copyright 2023 Nuraly, Laabidi Aymen
5
358
  * SPDX-License-Identifier: MIT
6
359
  */
7
- class u{constructor(e){this.host=e,e.addController(this)}hostConnected(){}hostDisconnected(){}dispatchEvent(e,n,t={}){try{const r=new CustomEvent(e,Object.assign({detail:n,bubbles:!0,composed:!0,cancelable:!0},t));return this.host.dispatchEvent(r)}catch(e){return this.handleError(e,"dispatchEvent"),!1}}handleError(e,n){console.error(`[MenuController:${n}]`,e),this.dispatchEvent("menu-controller-error",{context:n,error:e.message,stack:e.stack,timestamp:Date.now()})}requestUpdate(){this.host.requestUpdate()}isDisabled(){return!1}getElementByPath(e){var n;return(null===(n=this.host.shadowRoot)||void 0===n?void 0:n.querySelector(`[data-path="${e}"]`))||null}getAllMenuLinks(){var e;return Array.from((null===(e=this.host.shadowRoot)||void 0===e?void 0:e.querySelectorAll(".menu-link, .sub-menu"))||[])}isElementInteractive(e){if(!e)return!1;const n=e.classList.contains("disabled"),t=null!==e.offsetParent;return!n&&t}}
360
+ class l{constructor(e){this.host=e,e.addController(this)}hostConnected(){}hostDisconnected(){}dispatchEvent(e,n,t={}){try{const r=new CustomEvent(e,Object.assign({detail:n,bubbles:!0,composed:!0,cancelable:!0},t));return this.host.dispatchEvent(r)}catch(e){return this.handleError(e,"dispatchEvent"),!1}}handleError(e,n){console.error(`[MenuController:${n}]`,e),this.dispatchEvent("menu-controller-error",{context:n,error:e.message,stack:e.stack,timestamp:Date.now()})}requestUpdate(){this.host.requestUpdate()}isDisabled(){return!1}getElementByPath(e){var n;return(null===(n=this.host.shadowRoot)||void 0===n?void 0:n.querySelector(`[data-path="${e}"]`))||null}getAllMenuLinks(){var e;return Array.from((null===(e=this.host.shadowRoot)||void 0===e?void 0:e.querySelectorAll(".menu-link, .sub-menu"))||[])}isElementInteractive(e){if(!e)return!1;const n=e.classList.contains("disabled"),t=null!==e.offsetParent;return!n&&t}}
8
361
  /**
9
362
  * @license
10
363
  * Copyright 2023 Nuraly, Laabidi Aymen
11
364
  * SPDX-License-Identifier: MIT
12
- */class l extends u{constructor(){super(...arguments),this._selectedPath=[],this._openSubMenus=new Set,this._hoveredSubMenus=new Set,this._highlightedSubMenus=new Set}get selectedPath(){return this._selectedPath}set selectedPath(e){this._selectedPath=e}get openSubMenus(){return this._openSubMenus}get hoveredSubMenus(){return this._hoveredSubMenus}get highlightedSubMenus(){return this._highlightedSubMenus}setSelectedPath(e){try{this._selectedPath=e,this.clearHighlights(),this.requestUpdate(),this.dispatchEvent("selection-changed",{path:e,timestamp:Date.now()})}catch(e){this.handleError(e,"setSelectedPath")}}toggleSubMenu(e){try{const n=e.join("-");this._openSubMenus.has(n)?this.closeSubMenu(e):this.openSubMenu(e)}catch(e){this.handleError(e,"toggleSubMenu")}}openSubMenu(e){try{const n=e.join("-");this._openSubMenus.has(n)||(this._openSubMenus.add(n),this.requestUpdate(),this.dispatchEvent("submenu-opened",{path:e,pathKey:n,timestamp:Date.now()}))}catch(e){this.handleError(e,"openSubMenu")}}closeSubMenu(e){try{const n=e.join("-");this._openSubMenus.has(n)&&(this._openSubMenus.delete(n),this.requestUpdate(),this.dispatchEvent("submenu-closed",{path:e,pathKey:n,timestamp:Date.now()}))}catch(e){this.handleError(e,"closeSubMenu")}}closeAllSubMenus(){try{this._openSubMenus.clear(),this.requestUpdate(),this.dispatchEvent("all-submenus-closed",{timestamp:Date.now()})}catch(e){this.handleError(e,"closeAllSubMenus")}}setHovered(e,n){try{const t=e.join("-");n?this._hoveredSubMenus.add(t):this._hoveredSubMenus.delete(t),this.requestUpdate()}catch(e){this.handleError(e,"setHovered")}}setHighlighted(e,n){try{const t=e.join("-");n?this._highlightedSubMenus.add(t):this._highlightedSubMenus.delete(t),this.requestUpdate()}catch(e){this.handleError(e,"setHighlighted")}}clearHighlights(){try{this._highlightedSubMenus.clear(),this.requestUpdate()}catch(e){this.handleError(e,"clearHighlights")}}isPathSelected(e){return e.length===this._selectedPath.length&&e.every(((e,n)=>e===this._selectedPath[n]))}isSubMenuOpen(e){const n=e.join("-");return this._openSubMenus.has(n)}isSubMenuHovered(e){const n=e.join("-");return this._hoveredSubMenus.has(n)}isSubMenuHighlighted(e){const n=e.join("-");return this._highlightedSubMenus.has(n)}reset(){try{this._selectedPath=[],this._openSubMenus.clear(),this._hoveredSubMenus.clear(),this._highlightedSubMenus.clear(),this.requestUpdate(),this.dispatchEvent("state-reset",{timestamp:Date.now()})}catch(e){this.handleError(e,"reset")}}}
365
+ */class u extends l{constructor(){super(...arguments),this._selectedPath=[],this._openSubMenus=new Set,this._hoveredSubMenus=new Set,this._highlightedSubMenus=new Set}get selectedPath(){return this._selectedPath}set selectedPath(e){this._selectedPath=e}get openSubMenus(){return this._openSubMenus}get hoveredSubMenus(){return this._hoveredSubMenus}get highlightedSubMenus(){return this._highlightedSubMenus}setSelectedPath(e){try{this._selectedPath=e,this.clearHighlights(),this.requestUpdate(),this.dispatchEvent("selection-changed",{path:e,timestamp:Date.now()})}catch(e){this.handleError(e,"setSelectedPath")}}toggleSubMenu(e){try{const n=e.join("-");this._openSubMenus.has(n)?this.closeSubMenu(e):this.openSubMenu(e)}catch(e){this.handleError(e,"toggleSubMenu")}}openSubMenu(e){try{const n=e.join("-");this._openSubMenus.has(n)||(this._openSubMenus.add(n),this.requestUpdate(),this.dispatchEvent("submenu-opened",{path:e,pathKey:n,timestamp:Date.now()}))}catch(e){this.handleError(e,"openSubMenu")}}closeSubMenu(e){try{const n=e.join("-");this._openSubMenus.has(n)&&(this._openSubMenus.delete(n),this.requestUpdate(),this.dispatchEvent("submenu-closed",{path:e,pathKey:n,timestamp:Date.now()}))}catch(e){this.handleError(e,"closeSubMenu")}}closeAllSubMenus(){try{this._openSubMenus.clear(),this.requestUpdate(),this.dispatchEvent("all-submenus-closed",{timestamp:Date.now()})}catch(e){this.handleError(e,"closeAllSubMenus")}}setHovered(e,n){try{const t=e.join("-");n?this._hoveredSubMenus.add(t):this._hoveredSubMenus.delete(t),this.requestUpdate()}catch(e){this.handleError(e,"setHovered")}}setHighlighted(e,n){try{const t=e.join("-");n?this._highlightedSubMenus.add(t):this._highlightedSubMenus.delete(t),this.requestUpdate()}catch(e){this.handleError(e,"setHighlighted")}}clearHighlights(){try{this._highlightedSubMenus.clear(),this.requestUpdate()}catch(e){this.handleError(e,"clearHighlights")}}isPathSelected(e){return e.length===this._selectedPath.length&&e.every((e,n)=>e===this._selectedPath[n])}isSubMenuOpen(e){const n=e.join("-");return this._openSubMenus.has(n)}isSubMenuHovered(e){const n=e.join("-");return this._hoveredSubMenus.has(n)}isSubMenuHighlighted(e){const n=e.join("-");return this._highlightedSubMenus.has(n)}reset(){try{this._selectedPath=[],this._openSubMenus.clear(),this._hoveredSubMenus.clear(),this._highlightedSubMenus.clear(),this.requestUpdate(),this.dispatchEvent("state-reset",{timestamp:Date.now()})}catch(e){this.handleError(e,"reset")}}}
13
366
  /**
14
367
  * @license
15
368
  * Copyright 2023 Nuraly, Laabidi Aymen
16
369
  * SPDX-License-Identifier: MIT
17
- */class d extends u{constructor(e,n){super(e),this.typeAheadBuffer="",this.typeAheadTimeout=null,this.currentFocusIndex=-1,this.stateController=n}hostConnected(){this.host.addEventListener("keydown",this.handleKeydown.bind(this))}hostDisconnected(){this.host.removeEventListener("keydown",this.handleKeydown.bind(this)),this.typeAheadTimeout&&clearTimeout(this.typeAheadTimeout)}handleKeydown(e){try{const n=e.key;if(["ArrowUp","ArrowDown","ArrowLeft","ArrowRight"].includes(n))return void this.handleArrowNavigation(e);if("Enter"===n||" "===n)return void this.handleActivation(e);if("Escape"===n)return void this.handleEscape(e);if("Home"===n||"End"===n)return void this.handleHomeEnd(e);if(1===n.length&&!e.ctrlKey&&!e.metaKey&&!e.altKey)return void this.handleTypeAhead(e)}catch(e){this.handleError(e,"handleKeydown")}}handleArrowNavigation(e){var n;try{e.preventDefault();const t=this.getAllMenuLinks(),r=null===(n=this.host.shadowRoot)||void 0===n?void 0:n.activeElement,i=t.indexOf(r);switch(e.key){case"ArrowDown":this.navigateDown(t,i);break;case"ArrowUp":this.navigateUp(t,i);break;case"ArrowRight":this.expandOrNavigate(r);break;case"ArrowLeft":this.collapseOrNavigate(r)}this.dispatchEvent("keyboard-navigation",{key:e.key,currentIndex:i,timestamp:Date.now()})}catch(e){this.handleError(e,"handleArrowNavigation")}}navigateDown(e,n){let t=n+1;for(;t<e.length;){const n=e[t];if(this.isElementInteractive(n))return n.focus(),void(this.currentFocusIndex=t);t++}if(n>=0)for(let n=0;n<e.length;n++)if(this.isElementInteractive(e[n]))return e[n].focus(),void(this.currentFocusIndex=n)}navigateUp(e,n){let t=n-1;for(;t>=0;){const n=e[t];if(this.isElementInteractive(n))return n.focus(),void(this.currentFocusIndex=t);t--}if(n>=0)for(let n=e.length-1;n>=0;n--)if(this.isElementInteractive(e[n]))return e[n].focus(),void(this.currentFocusIndex=n)}expandOrNavigate(e){if(e&&e.classList.contains("sub-menu")){const n=e.getAttribute("data-path");if(n){const e=n.split("-").map(Number);this.stateController.openSubMenu(e)}}}collapseOrNavigate(e){if(e&&e.classList.contains("sub-menu")){const n=e.getAttribute("data-path");if(n){const e=n.split("-").map(Number);this.stateController.closeSubMenu(e)}}}handleActivation(e){var n;try{e.preventDefault();const t=null===(n=this.host.shadowRoot)||void 0===n?void 0:n.activeElement;if(!t||!this.isElementInteractive(t))return;t.click(),this.dispatchEvent("keyboard-activation",{key:e.key,element:t,timestamp:Date.now()})}catch(e){this.handleError(e,"handleActivation")}}handleEscape(e){try{e.preventDefault(),this.stateController.closeAllSubMenus(),this.dispatchEvent("keyboard-escape",{timestamp:Date.now()})}catch(e){this.handleError(e,"handleEscape")}}handleHomeEnd(e){try{e.preventDefault();const n=this.getAllMenuLinks(),t=n.filter((e=>this.isElementInteractive(e)));if(0===t.length)return;if("Home"===e.key)t[0].focus(),this.currentFocusIndex=n.indexOf(t[0]);else{const e=t[t.length-1];e.focus(),this.currentFocusIndex=n.indexOf(e)}this.dispatchEvent("keyboard-home-end",{key:e.key,timestamp:Date.now()})}catch(e){this.handleError(e,"handleHomeEnd")}}handleTypeAhead(e){try{e.preventDefault(),this.typeAheadTimeout&&clearTimeout(this.typeAheadTimeout),this.typeAheadBuffer+=e.key.toLowerCase(),this.typeAheadTimeout=window.setTimeout((()=>{this.typeAheadBuffer="",this.typeAheadTimeout=null}),500);const n=this.getAllMenuLinks(),t=this.currentFocusIndex>=0?this.currentFocusIndex:-1;for(let e=t+1;e<n.length;e++)if(this.matchesTypeAhead(n[e]))return n[e].focus(),void(this.currentFocusIndex=e);for(let e=0;e<=t;e++)if(this.matchesTypeAhead(n[e]))return n[e].focus(),void(this.currentFocusIndex=e);this.dispatchEvent("keyboard-typeahead",{buffer:this.typeAheadBuffer,timestamp:Date.now()})}catch(e){this.handleError(e,"handleTypeAhead")}}matchesTypeAhead(e){var n;if(!this.isElementInteractive(e))return!1;return((null===(n=e.textContent)||void 0===n?void 0:n.trim().toLowerCase())||"").startsWith(this.typeAheadBuffer)}resetTypeAhead(){this.typeAheadBuffer="",this.typeAheadTimeout&&(clearTimeout(this.typeAheadTimeout),this.typeAheadTimeout=null)}}
370
+ */class d extends l{constructor(e,n){super(e),this.typeAheadBuffer="",this.typeAheadTimeout=null,this.currentFocusIndex=-1,this.stateController=n}hostConnected(){this.host.addEventListener("keydown",this.handleKeydown.bind(this))}hostDisconnected(){this.host.removeEventListener("keydown",this.handleKeydown.bind(this)),this.typeAheadTimeout&&clearTimeout(this.typeAheadTimeout)}handleKeydown(e){try{const n=e.key;if(["ArrowUp","ArrowDown","ArrowLeft","ArrowRight"].includes(n))return void this.handleArrowNavigation(e);if("Enter"===n||" "===n)return void this.handleActivation(e);if("Escape"===n)return void this.handleEscape(e);if("Home"===n||"End"===n)return void this.handleHomeEnd(e);if(1===n.length&&!e.ctrlKey&&!e.metaKey&&!e.altKey)return void this.handleTypeAhead(e)}catch(e){this.handleError(e,"handleKeydown")}}handleArrowNavigation(e){var n;try{e.preventDefault();const t=this.getAllMenuLinks(),r=null===(n=this.host.shadowRoot)||void 0===n?void 0:n.activeElement,i=t.indexOf(r);switch(e.key){case"ArrowDown":this.navigateDown(t,i);break;case"ArrowUp":this.navigateUp(t,i);break;case"ArrowRight":this.expandOrNavigate(r);break;case"ArrowLeft":this.collapseOrNavigate(r)}this.dispatchEvent("keyboard-navigation",{key:e.key,currentIndex:i,timestamp:Date.now()})}catch(e){this.handleError(e,"handleArrowNavigation")}}navigateDown(e,n){let t=n+1;for(;t<e.length;){const n=e[t];if(this.isElementInteractive(n))return n.focus(),void(this.currentFocusIndex=t);t++}if(n>=0)for(let n=0;n<e.length;n++)if(this.isElementInteractive(e[n]))return e[n].focus(),void(this.currentFocusIndex=n)}navigateUp(e,n){let t=n-1;for(;t>=0;){const n=e[t];if(this.isElementInteractive(n))return n.focus(),void(this.currentFocusIndex=t);t--}if(n>=0)for(let n=e.length-1;n>=0;n--)if(this.isElementInteractive(e[n]))return e[n].focus(),void(this.currentFocusIndex=n)}expandOrNavigate(e){if(e&&e.classList.contains("sub-menu")){const n=e.getAttribute("data-path");if(n){const e=n.split("-").map(Number);this.stateController.openSubMenu(e)}}}collapseOrNavigate(e){if(e&&e.classList.contains("sub-menu")){const n=e.getAttribute("data-path");if(n){const e=n.split("-").map(Number);this.stateController.closeSubMenu(e)}}}handleActivation(e){var n;try{e.preventDefault();const t=null===(n=this.host.shadowRoot)||void 0===n?void 0:n.activeElement;if(!t||!this.isElementInteractive(t))return;t.click(),this.dispatchEvent("keyboard-activation",{key:e.key,element:t,timestamp:Date.now()})}catch(e){this.handleError(e,"handleActivation")}}handleEscape(e){try{e.preventDefault(),this.stateController.closeAllSubMenus(),this.dispatchEvent("keyboard-escape",{timestamp:Date.now()})}catch(e){this.handleError(e,"handleEscape")}}handleHomeEnd(e){try{e.preventDefault();const n=this.getAllMenuLinks(),t=n.filter(e=>this.isElementInteractive(e));if(0===t.length)return;if("Home"===e.key)t[0].focus(),this.currentFocusIndex=n.indexOf(t[0]);else{const e=t[t.length-1];e.focus(),this.currentFocusIndex=n.indexOf(e)}this.dispatchEvent("keyboard-home-end",{key:e.key,timestamp:Date.now()})}catch(e){this.handleError(e,"handleHomeEnd")}}handleTypeAhead(e){try{e.preventDefault(),this.typeAheadTimeout&&clearTimeout(this.typeAheadTimeout),this.typeAheadBuffer+=e.key.toLowerCase(),this.typeAheadTimeout=window.setTimeout(()=>{this.typeAheadBuffer="",this.typeAheadTimeout=null},500);const n=this.getAllMenuLinks(),t=this.currentFocusIndex>=0?this.currentFocusIndex:-1;for(let e=t+1;e<n.length;e++)if(this.matchesTypeAhead(n[e]))return n[e].focus(),void(this.currentFocusIndex=e);for(let e=0;e<=t;e++)if(this.matchesTypeAhead(n[e]))return n[e].focus(),void(this.currentFocusIndex=e);this.dispatchEvent("keyboard-typeahead",{buffer:this.typeAheadBuffer,timestamp:Date.now()})}catch(e){this.handleError(e,"handleTypeAhead")}}matchesTypeAhead(e){var n;if(!this.isElementInteractive(e))return!1;return((null===(n=e.textContent)||void 0===n?void 0:n.trim().toLowerCase())||"").startsWith(this.typeAheadBuffer)}resetTypeAhead(){this.typeAheadBuffer="",this.typeAheadTimeout&&(clearTimeout(this.typeAheadTimeout),this.typeAheadTimeout=null)}}
18
371
  /**
19
372
  * @license
20
373
  * Copyright 2023 Nuraly, Laabidi Aymen
21
374
  * SPDX-License-Identifier: MIT
22
- */class c extends u{constructor(e,n){super(e),this.announcementElement=null,this.stateController=n}hostConnected(){this.createAnnouncementElement(),this.updateAriaAttributes()}hostDisconnected(){this.removeAnnouncementElement()}createAnnouncementElement(){this.announcementElement||(this.announcementElement=document.createElement("div"),this.announcementElement.setAttribute("role","status"),this.announcementElement.setAttribute("aria-live","polite"),this.announcementElement.setAttribute("aria-atomic","true"),this.announcementElement.style.position="absolute",this.announcementElement.style.left="-10000px",this.announcementElement.style.width="1px",this.announcementElement.style.height="1px",this.announcementElement.style.overflow="hidden",document.body.appendChild(this.announcementElement))}removeAnnouncementElement(){this.announcementElement&&this.announcementElement.parentNode&&(this.announcementElement.parentNode.removeChild(this.announcementElement),this.announcementElement=null)}updateAriaAttributes(){try{this.updateMenuRoot(),this.updateAllMenuItems(),this.updateAllSubMenus()}catch(e){this.handleError(e,"updateAriaAttributes")}}updateMenuRoot(){var e;const n=null===(e=this.host.shadowRoot)||void 0===e?void 0:e.querySelector(".menu-root");n&&(n.setAttribute("role","menu"),n.setAttribute("aria-label","Main menu"))}updateAllMenuItems(){var e;const n=null===(e=this.host.shadowRoot)||void 0===e?void 0:e.querySelectorAll(".menu-link");null==n||n.forEach((e=>{e.setAttribute("role","menuitem"),e.setAttribute("tabindex","0");const n=e.getAttribute("data-path");if(n){const t=n.split("-").map(Number),r=this.stateController.isPathSelected(t);this.setAriaSelected(e,r)}e.classList.contains("disabled")&&e.setAttribute("aria-disabled","true")}))}updateAllSubMenus(){var e;const n=null===(e=this.host.shadowRoot)||void 0===e?void 0:e.querySelectorAll(".sub-menu");null==n||n.forEach((e=>{e.setAttribute("role","menuitem"),e.setAttribute("tabindex","0");const n=e.getAttribute("data-path");if(n){const t=n.split("-").map(Number),r=this.stateController.isSubMenuOpen(t),i=e.querySelector(".sub-menu-header");i&&(i.setAttribute("aria-haspopup","true"),this.setAriaExpanded(i,r))}e.classList.contains("disabled")&&e.setAttribute("aria-disabled","true")}))}setAriaExpanded(e,n){try{e.setAttribute("aria-expanded",n.toString())}catch(e){this.handleError(e,"setAriaExpanded")}}setAriaSelected(e,n){try{n?(e.setAttribute("aria-selected","true"),e.setAttribute("aria-current","page")):(e.removeAttribute("aria-selected"),e.removeAttribute("aria-current"))}catch(e){this.handleError(e,"setAriaSelected")}}manageFocus(e){try{this.isElementInteractive(e)&&(e.focus(),e.scrollIntoView({behavior:"smooth",block:"nearest",inline:"nearest"}))}catch(e){this.handleError(e,"manageFocus")}}announceToScreenReader(e){try{this.announcementElement&&(this.announcementElement.textContent="",setTimeout((()=>{this.announcementElement&&(this.announcementElement.textContent=e)}),100))}catch(e){this.handleError(e,"announceToScreenReader")}}announceSelection(e,n){const t=`Selected ${e}, level ${n.length}`;this.announceToScreenReader(t)}announceSubMenuToggle(e,n){const t=`${e} submenu ${n?"expanded":"collapsed"}`;this.announceToScreenReader(t)}focusFirstItem(){const e=this.getAllMenuLinks().find((e=>this.isElementInteractive(e)));e&&this.manageFocus(e)}focusLastItem(){const e=this.getAllMenuLinks().filter((e=>this.isElementInteractive(e))),n=e[e.length-1];n&&this.manageFocus(n)}}
375
+ */class c extends l{constructor(e,n){super(e),this.announcementElement=null,this.stateController=n}hostConnected(){this.createAnnouncementElement(),this.updateAriaAttributes()}hostDisconnected(){this.removeAnnouncementElement()}createAnnouncementElement(){this.announcementElement||(this.announcementElement=document.createElement("div"),this.announcementElement.setAttribute("role","status"),this.announcementElement.setAttribute("aria-live","polite"),this.announcementElement.setAttribute("aria-atomic","true"),this.announcementElement.style.position="absolute",this.announcementElement.style.left="-10000px",this.announcementElement.style.width="1px",this.announcementElement.style.height="1px",this.announcementElement.style.overflow="hidden",document.body.appendChild(this.announcementElement))}removeAnnouncementElement(){this.announcementElement&&this.announcementElement.parentNode&&(this.announcementElement.parentNode.removeChild(this.announcementElement),this.announcementElement=null)}updateAriaAttributes(){try{this.updateMenuRoot(),this.updateAllMenuItems(),this.updateAllSubMenus()}catch(e){this.handleError(e,"updateAriaAttributes")}}updateMenuRoot(){var e;const n=null===(e=this.host.shadowRoot)||void 0===e?void 0:e.querySelector(".menu-root");n&&(n.setAttribute("role","menu"),n.setAttribute("aria-label","Main menu"))}updateAllMenuItems(){var e;const n=null===(e=this.host.shadowRoot)||void 0===e?void 0:e.querySelectorAll(".menu-link");null==n||n.forEach(e=>{e.setAttribute("role","menuitem"),e.setAttribute("tabindex","0");const n=e.getAttribute("data-path");if(n){const t=n.split("-").map(Number),r=this.stateController.isPathSelected(t);this.setAriaSelected(e,r)}e.classList.contains("disabled")&&e.setAttribute("aria-disabled","true")})}updateAllSubMenus(){var e;const n=null===(e=this.host.shadowRoot)||void 0===e?void 0:e.querySelectorAll(".sub-menu");null==n||n.forEach(e=>{e.setAttribute("role","menuitem"),e.setAttribute("tabindex","0");const n=e.getAttribute("data-path");if(n){const t=n.split("-").map(Number),r=this.stateController.isSubMenuOpen(t),i=e.querySelector(".sub-menu-header");i&&(i.setAttribute("aria-haspopup","true"),this.setAriaExpanded(i,r))}e.classList.contains("disabled")&&e.setAttribute("aria-disabled","true")})}setAriaExpanded(e,n){try{e.setAttribute("aria-expanded",n.toString())}catch(e){this.handleError(e,"setAriaExpanded")}}setAriaSelected(e,n){try{n?(e.setAttribute("aria-selected","true"),e.setAttribute("aria-current","page")):(e.removeAttribute("aria-selected"),e.removeAttribute("aria-current"))}catch(e){this.handleError(e,"setAriaSelected")}}manageFocus(e){try{this.isElementInteractive(e)&&(e.focus(),e.scrollIntoView({behavior:"smooth",block:"nearest",inline:"nearest"}))}catch(e){this.handleError(e,"manageFocus")}}announceToScreenReader(e){try{this.announcementElement&&(this.announcementElement.textContent="",setTimeout(()=>{this.announcementElement&&(this.announcementElement.textContent=e)},100))}catch(e){this.handleError(e,"announceToScreenReader")}}announceSelection(e,n){const t=`Selected ${e}, level ${n.length}`;this.announceToScreenReader(t)}announceSubMenuToggle(e,n){const t=`${e} submenu ${n?"expanded":"collapsed"}`;this.announceToScreenReader(t)}focusFirstItem(){const e=this.getAllMenuLinks().find(e=>this.isElementInteractive(e));e&&this.manageFocus(e)}focusLastItem(){const e=this.getAllMenuLinks().filter(e=>this.isElementInteractive(e)),n=e[e.length-1];n&&this.manageFocus(n)}}
23
376
  /**
24
377
  * @license
25
378
  * Copyright 2023 Nuraly, Laabidi Aymen
26
379
  * SPDX-License-Identifier: MIT
27
- */var h=function(e,n,t,r){for(var i,o=arguments.length,s=o<3?n:null===r?r=Object.getOwnPropertyDescriptor(n,t):r,a=e.length-1;a>=0;a--)(i=e[a])&&(s=(o<3?i(s):o>3?i(n,t,s):i(n,t))||s);return o>3&&s&&Object.defineProperty(n,t,s),s};let m=class extends(s(n)){constructor(){super(),this.requiredComponents=["nr-icon","nr-dropdown"],this.items=[],this.size="medium",this._linkIndex=0,this.stateController=new l(this),this.keyboardController=new d(this,this.stateController),this.accessibilityController=new c(this,this.stateController)}firstUpdated(){this._initializeSelectedState(),this.accessibilityController.updateAriaAttributes()}updated(){this.accessibilityController.updateAriaAttributes()}_initializeSelectedState(){this._linkIndex=0,this._findSelectedPath(this.items)}_findSelectedPath(e,n=[]){for(let t=0;t<e.length;t++){const r=e[t],i=[...n,t];if(r.children){if(this._findSelectedPath(r.children,i))return!0}else if(r.selected)return this.stateController.setSelectedPath(i),!0}return!1}_handleLinkClick(e,n,t){var r;if(!(null===(r=null==t?void 0:t.target)||void 0===r?void 0:r.classList.contains("action-icon"))){if("click"===(null==t?void 0:t.type)){if(t.detail>0)return}this.stateController.setSelectedPath(e),this.dispatchEvent(new CustomEvent("change",{bubbles:!0,composed:!0,detail:{path:e,value:n}})),this.requestUpdate()}}_handleSubMenuClick(e,n,t){const r=t,i=t.target;if("toggle-icon"!==i.id&&!i.closest("#toggle-icon")){if("click"===t.type)return 0===r.detail?(this.stateController.toggleSubMenu(e),void this.requestUpdate()):void 0;this.stateController.setSelectedPath([]),this.stateController.clearHighlights(),this.stateController.setHighlighted(e,!0),this.stateController.toggleSubMenu(e),this.dispatchEvent(new CustomEvent("change",{bubbles:!0,composed:!0,detail:{path:e,value:n}})),this.requestUpdate()}}_toggleSubMenu(e,n){n.stopPropagation(),this.stateController.toggleSubMenu(e),this.requestUpdate()}_handleSubMenuMouseEnter(e){this.stateController.setHovered(e,!0),this.requestUpdate()}_handleSubMenuMouseLeave(e){this.stateController.setHovered(e,!1),this.requestUpdate()}_handleActionClick(e,n){const t=n.detail.item;this.dispatchEvent(new CustomEvent("action-click",{detail:{value:t.value,path:e,item:t},composed:!0,bubbles:!0}))}_isPathSelected(e){return this.stateController.isPathSelected(e)}_convertActionsToDropdownItems(e){return e.map((e=>({id:e.value,label:e.label,value:e.value})))}_renderMenuLink(e,n){var i,o;const s=n.join("-"),a=this._isPathSelected(n),u=this._linkIndex++;return t`<li class="menu-link ${a?"selected":""} ${e.disabled?"disabled":""}" data-path="${s}" data-index="${u}" tabindex="0" @mousedown="${e.disabled?r:t=>this._handleLinkClick(n,e.text,t)}" @click="${e.disabled?r:t=>this._handleLinkClick(n,e.text,t)}"><div class="icon-container">${e.icon?t`${e.text?t`<nr-icon name="${e.icon}"></nr-icon>`:t`<div class="icon-only"><nr-icon name="${e.icon}"></nr-icon></div>`}`:r}</div>${e.text?t`<div class="action-text-container"><div class="text-container"><span>${e.text}</span></div><div class="icon-container">${(null===(i=e.status)||void 0===i?void 0:i.icon)?t`<nr-icon name="${e.status.icon}" class="status-icon"></nr-icon>`:r} ${(null===(o=e.menu)||void 0===o?void 0:o.actions)?t`<nr-dropdown .items="${this._convertActionsToDropdownItems(e.menu.actions)}" trigger="click" placement="bottom-end" @nr-dropdown-item-click="${e=>this._handleActionClick(n,e)}"><nr-icon name="${e.menu.icon}" class="action-icon" slot="trigger"></nr-icon></nr-dropdown>`:r}</div></div>`:r}</li>`}_renderSubMenu(e,n){var i,o;const s=n.join("-"),a=this.stateController.isSubMenuOpen(n)||e.opened,u=this.stateController.isSubMenuHovered(n),l=this.stateController.isSubMenuHighlighted(n),d=e.selected;return t`<ul class="sub-menu ${l?"highlighted":""} ${e.disabled?"disabled":""} ${d?"selected":""}" data-path="${s}" tabindex="0" @mouseenter="${()=>this._handleSubMenuMouseEnter(n)}" @mouseleave="${()=>this._handleSubMenuMouseLeave(n)}" @click="${e.disabled?r:e=>{const t=e;e.target.classList.contains("sub-menu")&&0===t.detail&&(e.stopPropagation(),this.stateController.toggleSubMenu(n),this.requestUpdate())}}"><div class="sub-menu-header" @mousedown="${e.disabled?r:t=>this._handleSubMenuClick(n,e.text,t)}" @click="${e.disabled?r:t=>this._handleSubMenuClick(n,e.text,t)}">${e.icon?t`<nr-icon class="text-icon" name="${e.icon}"></nr-icon>`:r} <span>${e.text}</span><div class="icons-container">${(null===(i=e.status)||void 0===i?void 0:i.icon)?t`<nr-icon name="${e.status.icon}" class="status-icon"></nr-icon>`:r} ${(l||u)&&(null===(o=e.menu)||void 0===o?void 0:o.actions)?t`<nr-dropdown .items="${this._convertActionsToDropdownItems(e.menu.actions)}" trigger="click" placement="bottom-end" @nr-dropdown-item-click="${e=>this._handleActionClick(n,e)}"><nr-icon name="${e.menu.icon}" class="action-icon" slot="trigger"></nr-icon></nr-dropdown>`:r} ${e.children&&e.children.length?t`<nr-icon id="toggle-icon" name="${a?"angle-up":"angle-down"}" @mousedown="${e.disabled?r:e=>this._toggleSubMenu(n,e)}"></nr-icon>`:r}</div></div><div class="sub-menu-children" style="display:${a?"block":"none"}">${e.children?this._renderMenuItems(e.children,n):r}</div></ul>`}_renderMenuItems(e,n=[]){return e.map(((e,t)=>{const r=[...n,t];return e.children?this._renderSubMenu(e,r):this._renderMenuLink(e,r)}))}render(){return this._linkIndex=0,t`<ul class="menu-root menu--${this.size}">${this._renderMenuItems(this.items)}</ul>`}};m.styles=a,h([i({type:Array})],m.prototype,"items",void 0),h([i({type:String})],m.prototype,"size",void 0),m=h([o("nr-menu")],m);export{m as NrMenuElement};
380
+ */var h=function(e,n,t,r){for(var i,o=arguments.length,s=o<3?n:null===r?r=Object.getOwnPropertyDescriptor(n,t):r,a=e.length-1;a>=0;a--)(i=e[a])&&(s=(o<3?i(s):o>3?i(n,t,s):i(n,t))||s);return o>3&&s&&Object.defineProperty(n,t,s),s};let m=class extends(s(n)){constructor(){super(),this.requiredComponents=["nr-icon","nr-dropdown"],this.items=[],this.size="medium",this.arrowPosition="right",this._linkIndex=0,this.stateController=new u(this),this.keyboardController=new d(this,this.stateController),this.accessibilityController=new c(this,this.stateController)}firstUpdated(){this._initializeSelectedState(),this.accessibilityController.updateAriaAttributes()}updated(e){e.has("items")&&(this._initializeSelectedState(),this._initializeOpenedState()),this.accessibilityController.updateAriaAttributes()}_initializeOpenedState(){this._openSubMenusFromItems(this.items,[])}_openSubMenusFromItems(e,n){for(let t=0;t<e.length;t++){const r=e[t],i=[...n,t];r.children&&(r.opened&&this.stateController.openSubMenu(i),this._openSubMenusFromItems(r.children,i))}}_initializeSelectedState(){this._linkIndex=0,this._findSelectedPath(this.items)}_findSelectedPath(e,n=[]){for(let t=0;t<e.length;t++){const r=e[t],i=[...n,t];if(r.children){if(this._findSelectedPath(r.children,i))return!0}else if(r.selected)return this.stateController.setSelectedPath(i),!0}return!1}_handleLinkClick(e,n,t){var r;if(!(null===(r=null==t?void 0:t.target)||void 0===r?void 0:r.classList.contains("action-icon"))){if("click"===(null==t?void 0:t.type)){if(t.detail>0)return}this.stateController.setSelectedPath(e),this.dispatchEvent(new CustomEvent("change",{bubbles:!0,composed:!0,detail:{path:e,value:n}})),this.requestUpdate()}}_handleSubMenuClick(e,n,t){const r=t,i=t.target;if("toggle-icon"!==i.id&&!i.closest("#toggle-icon")){if("click"===t.type)return 0===r.detail?(this.stateController.toggleSubMenu(e),void this.requestUpdate()):void 0;this.stateController.setSelectedPath([]),this.stateController.clearHighlights(),this.stateController.setHighlighted(e,!0),this.stateController.toggleSubMenu(e),this.dispatchEvent(new CustomEvent("change",{bubbles:!0,composed:!0,detail:{path:e,value:n}})),this.requestUpdate()}}_toggleSubMenu(e,n){n.stopPropagation(),this.stateController.toggleSubMenu(e),this.requestUpdate()}_handleSubMenuMouseEnter(e){this.stateController.setHovered(e,!0),this.requestUpdate()}_handleSubMenuMouseLeave(e){this.stateController.setHovered(e,!1),this.requestUpdate()}_handleActionClick(e,n){const t=n.detail.item,r=n.detail.originalEvent,i=n.detail.dropdown;this.dispatchEvent(new CustomEvent("action-click",{detail:{value:t.value,path:e,item:t,originalEvent:r,close:()=>{i&&("function"==typeof i.hide?i.hide():"function"==typeof i.close&&i.close())}},composed:!0,bubbles:!0}))}_isPathSelected(e){return this.stateController.isPathSelected(e)}_convertActionsToDropdownItems(e){return e.map(e=>({id:e.value,label:e.label,value:e.value,icon:e.icon,additionalData:e.additionalData}))}_renderMenuLink(e,n){var i,o;const s=n.join("-"),a=this._isPathSelected(n),l=this._linkIndex++;return t`
381
+ <li
382
+ class="menu-link ${a?"selected":""} ${e.disabled?"disabled":""}"
383
+ data-path=${s}
384
+ data-index=${l}
385
+ tabindex="0"
386
+ @mousedown=${e.disabled?r:t=>this._handleLinkClick(n,e.text,t)}
387
+ @click=${e.disabled?r:t=>this._handleLinkClick(n,e.text,t)}>
388
+ <div class="icon-container">
389
+ ${e.icon?t`
390
+ ${e.text?t`<nr-icon name="${e.icon}" size="small"></nr-icon>`:t`<div class="icon-only"><nr-icon name="${e.icon}"></nr-icon></div>`}
391
+ `:r}
392
+ </div>
393
+ ${e.text?t`
394
+ <div class="action-text-container">
395
+ <div class="text-container">
396
+ <span>${e.text}</span>
397
+ </div>
398
+ <div class="icon-container">
399
+ ${(null===(i=e.status)||void 0===i?void 0:i.icon)?t`
400
+ <nr-icon name=${e.status.icon} class="status-icon" size="small"></nr-icon>
401
+ `:r}
402
+ ${(null===(o=e.menu)||void 0===o?void 0:o.actions)?t`
403
+ <nr-dropdown
404
+ .items=${this._convertActionsToDropdownItems(e.menu.actions)}
405
+ trigger="click"
406
+ placement="bottom-end"
407
+ @nr-dropdown-item-click=${e=>this._handleActionClick(n,e)}>
408
+ <nr-icon name="${e.menu.icon}" class="action-icon" slot="trigger" size="small"></nr-icon>
409
+ </nr-dropdown>
410
+ `:r}
411
+ </div>
412
+ </div>
413
+ `:r}
414
+ </li>
415
+ `}_renderSubMenu(e,n){var i,o;const s=n.join("-"),a=this.stateController.isSubMenuOpen(n)||e.opened,l=this.stateController.isSubMenuHovered(n),u=this.stateController.isSubMenuHighlighted(n),d=e.selected,c=e.iconPosition||this.arrowPosition,h="left"===c||"left"===c;return t`
416
+ <ul
417
+ class="sub-menu ${u?"highlighted":""} ${e.disabled?"disabled":""} ${d?"selected":""} ${h?"arrow-left":"arrow-right"}"
418
+ data-path=${s}
419
+ tabindex="0"
420
+ @mouseenter=${()=>this._handleSubMenuMouseEnter(n)}
421
+ @mouseleave=${()=>this._handleSubMenuMouseLeave(n)}
422
+ @click=${e.disabled?r:e=>{const t=e;e.target.classList.contains("sub-menu")&&0===t.detail&&(e.stopPropagation(),this.stateController.toggleSubMenu(n),this.requestUpdate())}}>
423
+ <div
424
+ class="sub-menu-header"
425
+ @mousedown=${e.disabled?r:t=>this._handleSubMenuClick(n,e.text,t)}
426
+ @click=${e.disabled?r:t=>this._handleSubMenuClick(n,e.text,t)}>
427
+ ${h&&e.children&&e.children.length?t`
428
+ <nr-icon
429
+ id="toggle-icon"
430
+ name="${a?"ChevronDown":"ChevronRight"}"
431
+ @mousedown=${e.disabled?r:e=>this._toggleSubMenu(n,e)}
432
+ size="small">
433
+ </nr-icon>
434
+ `:r}
435
+ ${e.icon?t`<nr-icon class="text-icon" name="${e.icon}" size="small"></nr-icon>`:r}
436
+ <span>${e.text}</span>
437
+ <div class="icons-container">
438
+ ${(null===(i=e.status)||void 0===i?void 0:i.icon)?t`
439
+ <nr-icon name=${e.status.icon} class="status-icon" size="small"></nr-icon>
440
+ `:r}
441
+ ${(u||l)&&(null===(o=e.menu)||void 0===o?void 0:o.actions)?t`
442
+ <nr-dropdown
443
+ .items=${this._convertActionsToDropdownItems(e.menu.actions)}
444
+ trigger="click"
445
+ placement="bottom-end"
446
+ @nr-dropdown-item-click=${e=>this._handleActionClick(n,e)}>
447
+ <nr-icon name="${e.menu.icon}" class="action-icon" slot="trigger" size="small"></nr-icon>
448
+ </nr-dropdown>
449
+ `:r}
450
+ ${!h&&e.children&&e.children.length?t`
451
+ <nr-icon
452
+ id="toggle-icon"
453
+ name="${a?"ChevronDown":"ChevronRight"}"
454
+ @mousedown=${e.disabled?r:e=>this._toggleSubMenu(n,e)}
455
+ size="small">
456
+ </nr-icon>
457
+ `:r}
458
+ </div>
459
+ </div>
460
+ <div class="sub-menu-children" style="display: ${a?"block":"none"}">
461
+ ${e.children?this._renderMenuItems(e.children,n):r}
462
+ </div>
463
+ </ul>
464
+ `}_renderMenuItems(e,n=[]){return e.map((e,t)=>{const r=[...n,t];return e.children?this._renderSubMenu(e,r):this._renderMenuLink(e,r)})}render(){return this._linkIndex=0,t`
465
+ <ul class="menu-root menu--${this.size}">
466
+ ${this._renderMenuItems(this.items)}
467
+ </ul>
468
+ `}};m.styles=a,h([i({type:Array})],m.prototype,"items",void 0),h([i({type:String})],m.prototype,"size",void 0),h([i({type:String})],m.prototype,"arrowPosition",void 0),m=h([o("nr-menu")],m);export{m as NrMenuElement};
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/menu/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC","sourcesContent":["export * from './menu.component.js';\nexport { MenuSize, IconPosition } from './menu.types.js';\nexport type { IMenu, IAction } from './menu.types.js';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/menu/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC","sourcesContent":["export * from './menu.component.js';\nexport { MenuSize, IconPosition } from './menu.types.js';\nexport type { IMenu, IAction } from './menu.types.js';\n"]}
@@ -4,7 +4,7 @@
4
4
  * SPDX-License-Identifier: MIT
5
5
  */
6
6
  import { LitElement } from 'lit';
7
- import { IMenu, MenuSize } from './menu.types.js';
7
+ import { IMenu, MenuSize, IconPosition } from './menu.types.js';
8
8
  declare const NrMenuElement_base: (new (...args: any[]) => import("@nuralyui/common/mixins").DependencyAware) & (new (...args: any[]) => import("@nuralyui/common/mixins").ThemeAware) & (new (...args: any[]) => import("@nuralyui/common/mixins").EventHandlerCapable) & typeof LitElement;
9
9
  /**
10
10
  * Versatile menu component for hierarchical navigation with support for nested submenus.
@@ -12,10 +12,12 @@ declare const NrMenuElement_base: (new (...args: any[]) => import("@nuralyui/com
12
12
  * @example
13
13
  * ```html
14
14
  * <nr-menu .items=${menuItems}></nr-menu>
15
+ * <nr-menu .items=${menuItems} arrowPosition="left"></nr-menu>
15
16
  * ```
16
17
  *
17
18
  * @fires change - Menu item selected
18
19
  * @fires action-click - Menu action clicked
20
+ * @fires label-edit - Menu item label edited (detail: { path, oldValue, newValue })
19
21
  *
20
22
  * @slot - Menu items (auto-generated from items property)
21
23
  */
@@ -26,27 +28,60 @@ export declare class NrMenuElement extends NrMenuElement_base {
26
28
  items: IMenu[];
27
29
  /** Menu size variant (small, medium, large) */
28
30
  size: MenuSize | string;
31
+ /** Default arrow icon position for submenus (left or right) */
32
+ arrowPosition: IconPosition | string;
33
+ /** Callback for label edit events (alternative to event listener) */
34
+ onLabelEdit?: (detail: {
35
+ path: number[];
36
+ oldValue: string;
37
+ newValue: string;
38
+ }) => void;
39
+ /** Track context menu state */
40
+ private _contextMenuState;
41
+ /** Track which menu item is currently being edited (path as string for comparison) */
42
+ private _editingPath;
43
+ /** Temporary value while editing */
44
+ private _editingValue;
45
+ /** Pending click timeout for double-click detection */
46
+ private _pendingClickTimeout;
47
+ /** Path of pending click */
48
+ private _pendingClickPath;
29
49
  private stateController;
30
50
  private keyboardController;
31
51
  private accessibilityController;
32
52
  private _linkIndex;
33
53
  constructor();
34
54
  firstUpdated(): void;
35
- updated(): void;
55
+ updated(changedProperties: Map<string, unknown>): void;
56
+ private _initializeOpenedState;
57
+ private _openSubMenusFromItems;
36
58
  private _initializeSelectedState;
37
59
  private _findSelectedPath;
38
60
  private _handleLinkClick;
61
+ private _executeClick;
39
62
  private _handleSubMenuClick;
63
+ private _executeSubMenuClick;
40
64
  private _toggleSubMenu;
41
65
  private _handleSubMenuMouseEnter;
42
66
  private _handleSubMenuMouseLeave;
43
67
  private _handleActionClick;
68
+ private _handleContextMenu;
69
+ private _handleContextMenuAction;
70
+ private _handleContextMenuClose;
71
+ private _handleDoubleClick;
72
+ private _handleEditInput;
73
+ private _handleEditKeyDown;
74
+ private _handleEditBlur;
75
+ private _saveEdit;
76
+ private _cancelEdit;
77
+ private _isEditing;
44
78
  private _isPathSelected;
45
79
  private _convertActionsToDropdownItems;
46
80
  private _renderMenuLink;
47
81
  private _renderSubMenu;
48
82
  private _renderMenuItems;
49
- render(): import("lit").TemplateResult<1>;
83
+ private _renderContextMenu;
84
+ render(): import("lit-html").TemplateResult<1>;
50
85
  }
51
86
  export {};
52
87
  //# sourceMappingURL=menu.component.d.ts.map