@nuralyui/menu 0.0.19 → 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 +94 -51
- package/index.js.map +1 -1
- package/menu.component.d.ts +38 -3
- package/menu.component.js +351 -45
- package/menu.component.js.map +1 -1
- package/menu.constants.js.map +1 -1
- package/menu.style.js +113 -64
- package/menu.style.js.map +1 -1
- package/menu.types.d.ts +4 -0
- package/menu.types.js.map +1 -1
- package/package.json +1 -1
- package/react.js.map +1 -1
package/bundle.js
CHANGED
|
@@ -20,7 +20,7 @@ import{css as e,LitElement as n,html as t,nothing as r}from"lit";import{property
|
|
|
20
20
|
display: flex;
|
|
21
21
|
align-items: center;
|
|
22
22
|
cursor: pointer;
|
|
23
|
-
padding: var(--nuraly-menu-link-padding
|
|
23
|
+
padding: var(--nuraly-menu-link-padding, 1px);
|
|
24
24
|
color: var(--nuraly-menu-link-color);
|
|
25
25
|
background-color: var(--nuraly-menu-link-background-color);
|
|
26
26
|
border-left: 4px solid transparent;
|
|
@@ -28,9 +28,8 @@ import{css as e,LitElement as n,html as t,nothing as r}from"lit";import{property
|
|
|
28
28
|
border-right: 2px solid transparent;
|
|
29
29
|
border-bottom: 2px solid transparent;
|
|
30
30
|
border-radius: var(--nuraly-menu-border-radius);
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
border-color var(--nuraly-menu-transition-duration) var(--nuraly-menu-transition-timing);
|
|
31
|
+
margin-bottom: 4px;
|
|
32
|
+
gap: 8px;
|
|
34
33
|
}
|
|
35
34
|
|
|
36
35
|
.menu-link.disabled {
|
|
@@ -116,12 +115,22 @@ import{css as e,LitElement as n,html as t,nothing as r}from"lit";import{property
|
|
|
116
115
|
.menu-link nr-icon {
|
|
117
116
|
display: flex;
|
|
118
117
|
align-items: center;
|
|
119
|
-
--nuraly-icon
|
|
118
|
+
--nuraly-color-icon: var(--nuraly-menu-link-icon-color);
|
|
119
|
+
--nuraly-icon-size: var(--nuraly-menu-icon-size, 20px);
|
|
120
|
+
flex-shrink: 0;
|
|
120
121
|
}
|
|
121
122
|
|
|
122
123
|
.menu-link nr-icon:first-child {
|
|
123
|
-
padding-right:
|
|
124
|
-
padding-left:
|
|
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);
|
|
125
134
|
}
|
|
126
135
|
|
|
127
136
|
/* Sub Menu Styles */
|
|
@@ -131,6 +140,7 @@ import{css as e,LitElement as n,html as t,nothing as r}from"lit";import{property
|
|
|
131
140
|
padding-left: 0;
|
|
132
141
|
list-style: none;
|
|
133
142
|
color: var(--nuraly-sub-menu-color);
|
|
143
|
+
margin-bottom: 4px;
|
|
134
144
|
}
|
|
135
145
|
|
|
136
146
|
.sub-menu.disabled .sub-menu-header {
|
|
@@ -149,38 +159,38 @@ import{css as e,LitElement as n,html as t,nothing as r}from"lit";import{property
|
|
|
149
159
|
justify-content: space-between;
|
|
150
160
|
align-items: center;
|
|
151
161
|
cursor: pointer;
|
|
152
|
-
padding: var(--nuraly-sub-menu-padding
|
|
162
|
+
padding: var(--nuraly-sub-menu-header-padding, 1px);
|
|
153
163
|
border-left: 4px solid transparent;
|
|
154
164
|
border-top: 2px solid transparent;
|
|
155
165
|
border-right: 2px solid transparent;
|
|
156
166
|
border-bottom: 2px solid transparent;
|
|
157
167
|
border-radius: var(--nuraly-menu-border-radius);
|
|
158
|
-
|
|
159
|
-
color var(--nuraly-menu-transition-duration) var(--nuraly-menu-transition-timing),
|
|
160
|
-
border-color var(--nuraly-menu-transition-duration) var(--nuraly-menu-transition-timing);
|
|
168
|
+
gap: 8px;
|
|
161
169
|
}
|
|
162
170
|
|
|
163
171
|
.sub-menu .sub-menu-header span {
|
|
164
172
|
flex: 1;
|
|
165
173
|
min-width: 0;
|
|
166
|
-
padding-left:
|
|
174
|
+
padding-left: 0;
|
|
167
175
|
}
|
|
168
176
|
|
|
169
177
|
.sub-menu .text-icon {
|
|
170
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);
|
|
171
181
|
}
|
|
172
182
|
|
|
173
183
|
.sub-menu .icons-container {
|
|
174
184
|
display: flex;
|
|
175
185
|
align-items: center;
|
|
176
|
-
gap:
|
|
186
|
+
gap: 8px;
|
|
177
187
|
position: relative;
|
|
178
188
|
flex-shrink: 0;
|
|
179
189
|
/* Reserve space for dropdown to prevent layout shift */
|
|
180
190
|
min-width: fit-content;
|
|
181
191
|
/* Fixed height to prevent vertical shifting */
|
|
182
192
|
height: 100%;
|
|
183
|
-
min-height:
|
|
193
|
+
min-height: 20px;
|
|
184
194
|
}
|
|
185
195
|
|
|
186
196
|
.menu-link .icon-container {
|
|
@@ -190,7 +200,7 @@ import{css as e,LitElement as n,html as t,nothing as r}from"lit";import{property
|
|
|
190
200
|
flex-shrink: 0;
|
|
191
201
|
/* Fixed height to prevent vertical shifting */
|
|
192
202
|
height: 100%;
|
|
193
|
-
min-height:
|
|
203
|
+
min-height: 20px;
|
|
194
204
|
}
|
|
195
205
|
|
|
196
206
|
.sub-menu nr-dropdown,
|
|
@@ -210,19 +220,23 @@ import{css as e,LitElement as n,html as t,nothing as r}from"lit";import{property
|
|
|
210
220
|
}
|
|
211
221
|
|
|
212
222
|
.sub-menu .action-icon {
|
|
213
|
-
--nuraly-icon
|
|
223
|
+
--nuraly-color-icon: var(--nuraly-sub-menu-action-icon-color);
|
|
224
|
+
--nuraly-icon-size: var(--nuraly-menu-icon-size, 16px);
|
|
214
225
|
}
|
|
215
226
|
|
|
216
227
|
.sub-menu .status-icon {
|
|
217
|
-
--nuraly-icon
|
|
228
|
+
--nuraly-color-icon: var(--nuraly-sub-menu-status-icon-color);
|
|
229
|
+
--nuraly-icon-size: var(--nuraly-menu-icon-size, 16px);
|
|
218
230
|
}
|
|
219
231
|
|
|
220
232
|
.sub-menu .text-icon {
|
|
221
|
-
--nuraly-icon
|
|
233
|
+
--nuraly-color-icon: var(--nuraly-sub-menu-text-icon-color);
|
|
234
|
+
--nuraly-icon-size: var(--nuraly-menu-icon-size, 20px);
|
|
222
235
|
}
|
|
223
236
|
|
|
224
237
|
.sub-menu #toggle-icon {
|
|
225
|
-
--nuraly-icon
|
|
238
|
+
--nuraly-color-icon: var(--nuraly-sub-menu-toggle-icon-color);
|
|
239
|
+
--nuraly-icon-size: var(--nuraly-menu-icon-size, 16px);
|
|
226
240
|
}
|
|
227
241
|
|
|
228
242
|
.sub-menu:not(.disabled):not(.selected) .sub-menu-header:focus {
|
|
@@ -293,29 +307,49 @@ import{css as e,LitElement as n,html as t,nothing as r}from"lit";import{property
|
|
|
293
307
|
padding-left: var(--nuraly-sub-menu-nested-padding-left);
|
|
294
308
|
}
|
|
295
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
|
+
|
|
296
330
|
/* Size Variants */
|
|
297
331
|
.menu--small .menu-link {
|
|
298
|
-
padding: var(--nuraly-menu-link-padding-
|
|
332
|
+
padding: var(--nuraly-menu-link-padding-small, 1px);
|
|
299
333
|
}
|
|
300
334
|
|
|
301
335
|
.menu--small .sub-menu .sub-menu-header {
|
|
302
|
-
padding: var(--nuraly-sub-menu-padding-
|
|
336
|
+
padding: var(--nuraly-sub-menu-header-padding-small, 1px);
|
|
303
337
|
}
|
|
304
338
|
|
|
305
339
|
.menu--medium .menu-link {
|
|
306
|
-
padding: var(--nuraly-menu-link-padding-
|
|
340
|
+
padding: var(--nuraly-menu-link-padding-medium, 1px);
|
|
307
341
|
}
|
|
308
342
|
|
|
309
343
|
.menu--medium .sub-menu .sub-menu-header {
|
|
310
|
-
padding: var(--nuraly-sub-menu-padding-
|
|
344
|
+
padding: var(--nuraly-sub-menu-header-padding-medium, 1px);
|
|
311
345
|
}
|
|
312
346
|
|
|
313
347
|
.menu--large .menu-link {
|
|
314
|
-
padding: var(--nuraly-menu-link-padding-
|
|
348
|
+
padding: var(--nuraly-menu-link-padding-large, 1px);
|
|
315
349
|
}
|
|
316
350
|
|
|
317
351
|
.menu--large .sub-menu .sub-menu-header {
|
|
318
|
-
padding: var(--nuraly-sub-menu-padding-
|
|
352
|
+
padding: var(--nuraly-sub-menu-header-padding-large, 1px);
|
|
319
353
|
}
|
|
320
354
|
`];
|
|
321
355
|
/**
|
|
@@ -323,37 +357,37 @@ import{css as e,LitElement as n,html as t,nothing as r}from"lit";import{property
|
|
|
323
357
|
* Copyright 2023 Nuraly, Laabidi Aymen
|
|
324
358
|
* SPDX-License-Identifier: MIT
|
|
325
359
|
*/
|
|
326
|
-
class
|
|
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}}
|
|
327
361
|
/**
|
|
328
362
|
* @license
|
|
329
363
|
* Copyright 2023 Nuraly, Laabidi Aymen
|
|
330
364
|
* SPDX-License-Identifier: MIT
|
|
331
|
-
*/class
|
|
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")}}}
|
|
332
366
|
/**
|
|
333
367
|
* @license
|
|
334
368
|
* Copyright 2023 Nuraly, Laabidi Aymen
|
|
335
369
|
* SPDX-License-Identifier: MIT
|
|
336
|
-
*/class d extends
|
|
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)}}
|
|
337
371
|
/**
|
|
338
372
|
* @license
|
|
339
373
|
* Copyright 2023 Nuraly, Laabidi Aymen
|
|
340
374
|
* SPDX-License-Identifier: MIT
|
|
341
|
-
*/class c extends
|
|
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)}}
|
|
342
376
|
/**
|
|
343
377
|
* @license
|
|
344
378
|
* Copyright 2023 Nuraly, Laabidi Aymen
|
|
345
379
|
* SPDX-License-Identifier: MIT
|
|
346
|
-
*/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
|
|
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`
|
|
347
381
|
<li
|
|
348
382
|
class="menu-link ${a?"selected":""} ${e.disabled?"disabled":""}"
|
|
349
383
|
data-path=${s}
|
|
350
|
-
data-index=${
|
|
384
|
+
data-index=${l}
|
|
351
385
|
tabindex="0"
|
|
352
386
|
@mousedown=${e.disabled?r:t=>this._handleLinkClick(n,e.text,t)}
|
|
353
387
|
@click=${e.disabled?r:t=>this._handleLinkClick(n,e.text,t)}>
|
|
354
388
|
<div class="icon-container">
|
|
355
389
|
${e.icon?t`
|
|
356
|
-
${e.text?t`<nr-icon name="${e.icon}"></nr-icon>`:t`<div class="icon-only"><nr-icon name="${e.icon}"></nr-icon></div>`}
|
|
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>`}
|
|
357
391
|
`:r}
|
|
358
392
|
</div>
|
|
359
393
|
${e.text?t`
|
|
@@ -363,24 +397,24 @@ class u{constructor(e){this.host=e,e.addController(this)}hostConnected(){}hostDi
|
|
|
363
397
|
</div>
|
|
364
398
|
<div class="icon-container">
|
|
365
399
|
${(null===(i=e.status)||void 0===i?void 0:i.icon)?t`
|
|
366
|
-
<nr-icon name=${e.status.icon} class="status-icon"></nr-icon>
|
|
400
|
+
<nr-icon name=${e.status.icon} class="status-icon" size="small"></nr-icon>
|
|
367
401
|
`:r}
|
|
368
402
|
${(null===(o=e.menu)||void 0===o?void 0:o.actions)?t`
|
|
369
|
-
<nr-dropdown
|
|
370
|
-
.items=${this._convertActionsToDropdownItems(e.menu.actions)}
|
|
371
|
-
trigger="click"
|
|
403
|
+
<nr-dropdown
|
|
404
|
+
.items=${this._convertActionsToDropdownItems(e.menu.actions)}
|
|
405
|
+
trigger="click"
|
|
372
406
|
placement="bottom-end"
|
|
373
407
|
@nr-dropdown-item-click=${e=>this._handleActionClick(n,e)}>
|
|
374
|
-
<nr-icon name="${e.menu.icon}" class="action-icon" slot="trigger"></nr-icon>
|
|
408
|
+
<nr-icon name="${e.menu.icon}" class="action-icon" slot="trigger" size="small"></nr-icon>
|
|
375
409
|
</nr-dropdown>
|
|
376
410
|
`:r}
|
|
377
411
|
</div>
|
|
378
412
|
</div>
|
|
379
413
|
`:r}
|
|
380
414
|
</li>
|
|
381
|
-
`}_renderSubMenu(e,n){var i,o;const s=n.join("-"),a=this.stateController.isSubMenuOpen(n)||e.opened,
|
|
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`
|
|
382
416
|
<ul
|
|
383
|
-
class="sub-menu ${
|
|
417
|
+
class="sub-menu ${u?"highlighted":""} ${e.disabled?"disabled":""} ${d?"selected":""} ${h?"arrow-left":"arrow-right"}"
|
|
384
418
|
data-path=${s}
|
|
385
419
|
tabindex="0"
|
|
386
420
|
@mouseenter=${()=>this._handleSubMenuMouseEnter(n)}
|
|
@@ -390,26 +424,35 @@ class u{constructor(e){this.host=e,e.addController(this)}hostConnected(){}hostDi
|
|
|
390
424
|
class="sub-menu-header"
|
|
391
425
|
@mousedown=${e.disabled?r:t=>this._handleSubMenuClick(n,e.text,t)}
|
|
392
426
|
@click=${e.disabled?r:t=>this._handleSubMenuClick(n,e.text,t)}>
|
|
393
|
-
${e.
|
|
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}
|
|
394
436
|
<span>${e.text}</span>
|
|
395
437
|
<div class="icons-container">
|
|
396
438
|
${(null===(i=e.status)||void 0===i?void 0:i.icon)?t`
|
|
397
|
-
<nr-icon name=${e.status.icon} class="status-icon"></nr-icon>
|
|
439
|
+
<nr-icon name=${e.status.icon} class="status-icon" size="small"></nr-icon>
|
|
398
440
|
`:r}
|
|
399
|
-
${(l
|
|
400
|
-
<nr-dropdown
|
|
401
|
-
.items=${this._convertActionsToDropdownItems(e.menu.actions)}
|
|
402
|
-
trigger="click"
|
|
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"
|
|
403
445
|
placement="bottom-end"
|
|
404
446
|
@nr-dropdown-item-click=${e=>this._handleActionClick(n,e)}>
|
|
405
|
-
<nr-icon name="${e.menu.icon}" class="action-icon" slot="trigger"></nr-icon>
|
|
447
|
+
<nr-icon name="${e.menu.icon}" class="action-icon" slot="trigger" size="small"></nr-icon>
|
|
406
448
|
</nr-dropdown>
|
|
407
449
|
`:r}
|
|
408
|
-
${e.children&&e.children.length?t`
|
|
450
|
+
${!h&&e.children&&e.children.length?t`
|
|
409
451
|
<nr-icon
|
|
410
452
|
id="toggle-icon"
|
|
411
|
-
name="${a?"
|
|
412
|
-
@mousedown=${e.disabled?r:e=>this._toggleSubMenu(n,e)}
|
|
453
|
+
name="${a?"ChevronDown":"ChevronRight"}"
|
|
454
|
+
@mousedown=${e.disabled?r:e=>this._toggleSubMenu(n,e)}
|
|
455
|
+
size="small">
|
|
413
456
|
</nr-icon>
|
|
414
457
|
`:r}
|
|
415
458
|
</div>
|
|
@@ -418,8 +461,8 @@ class u{constructor(e){this.host=e,e.addController(this)}hostConnected(){}hostDi
|
|
|
418
461
|
${e.children?this._renderMenuItems(e.children,n):r}
|
|
419
462
|
</div>
|
|
420
463
|
</ul>
|
|
421
|
-
`}_renderMenuItems(e,n=[]){return e.map((
|
|
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`
|
|
422
465
|
<ul class="menu-root menu--${this.size}">
|
|
423
466
|
${this._renderMenuItems(this.items)}
|
|
424
467
|
</ul>
|
|
425
|
-
`}};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};
|
|
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":["
|
|
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"]}
|
package/menu.component.d.ts
CHANGED
|
@@ -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
|
-
|
|
83
|
+
private _renderContextMenu;
|
|
84
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
50
85
|
}
|
|
51
86
|
export {};
|
|
52
87
|
//# sourceMappingURL=menu.component.d.ts.map
|