@nuralyui/menu 0.0.10 → 0.0.15

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.
Files changed (57) hide show
  1. package/bundle.js +1305 -0
  2. package/index.d.ts +2 -0
  3. package/index.js.map +1 -1
  4. package/menu.component.d.ts +48 -13
  5. package/menu.component.js +256 -73
  6. package/menu.component.js.map +1 -1
  7. package/menu.style.js +316 -79
  8. package/menu.style.js.map +1 -1
  9. package/menu.types.d.ts +41 -1
  10. package/menu.types.js +6 -1
  11. package/menu.types.js.map +1 -1
  12. package/package.json +40 -5
  13. package/react.d.ts +4 -2
  14. package/react.js +7 -5
  15. package/react.js.map +1 -1
  16. package/demo/menus-demo.d.ts +0 -22
  17. package/demo/menus-demo.d.ts.map +0 -1
  18. package/demo/menus-demo.js +0 -157
  19. package/demo/menus-demo.js.map +0 -1
  20. package/index.d.ts.map +0 -1
  21. package/menu.component.d.ts.map +0 -1
  22. package/menu.constants.d.ts.map +0 -1
  23. package/menu.style.d.ts.map +0 -1
  24. package/menu.types.d.ts.map +0 -1
  25. package/react.d.ts.map +0 -1
  26. package/templates/hy-menu-link.d.ts +0 -29
  27. package/templates/hy-menu-link.d.ts.map +0 -1
  28. package/templates/hy-menu-link.js +0 -122
  29. package/templates/hy-menu-link.js.map +0 -1
  30. package/templates/hy-sub-menu.d.ts +0 -32
  31. package/templates/hy-sub-menu.d.ts.map +0 -1
  32. package/templates/hy-sub-menu.js +0 -121
  33. package/templates/hy-sub-menu.js.map +0 -1
  34. package/templates/menu-link.contants.d.ts +0 -5
  35. package/templates/menu-link.contants.d.ts.map +0 -1
  36. package/templates/menu-link.contants.js +0 -6
  37. package/templates/menu-link.contants.js.map +0 -1
  38. package/templates/menu-link.style.d.ts +0 -2
  39. package/templates/menu-link.style.d.ts.map +0 -1
  40. package/templates/menu-link.style.js +0 -98
  41. package/templates/menu-link.style.js.map +0 -1
  42. package/templates/sub-menu.style.d.ts +0 -2
  43. package/templates/sub-menu.style.d.ts.map +0 -1
  44. package/templates/sub-menu.style.js +0 -88
  45. package/templates/sub-menu.style.js.map +0 -1
  46. package/test/menu-link_test.d.ts +0 -2
  47. package/test/menu-link_test.d.ts.map +0 -1
  48. package/test/menu-link_test.js +0 -85
  49. package/test/menu-link_test.js.map +0 -1
  50. package/test/menu_test.d.ts +0 -2
  51. package/test/menu_test.d.ts.map +0 -1
  52. package/test/menu_test.js +0 -81
  53. package/test/menu_test.js.map +0 -1
  54. package/test/sub-menu_test.d.ts +0 -2
  55. package/test/sub-menu_test.d.ts.map +0 -1
  56. package/test/sub-menu_test.js +0 -72
  57. package/test/sub-menu_test.js.map +0 -1
package/index.d.ts CHANGED
@@ -1,2 +1,4 @@
1
1
  export * from './menu.component.js';
2
+ export { MenuSize, IconPosition } from './menu.types.js';
3
+ export type { IMenu, IAction } from './menu.types.js';
2
4
  //# sourceMappingURL=index.d.ts.map
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';\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"]}
@@ -1,19 +1,54 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2023 Nuraly, Laabidi Aymen
4
+ * SPDX-License-Identifier: MIT
5
+ */
1
6
  import { LitElement } from 'lit';
2
- import { IMenu } from './menu.types.js';
3
- import './templates/hy-menu-link.js';
4
- import './templates/hy-sub-menu.js';
5
- export declare class HyMenuComponent extends LitElement {
6
- private _currentSelectedLink;
7
- _menuLinks: NodeListOf<HTMLElement>;
8
- _subMenues: NodeListOf<HTMLElement>;
7
+ import { IMenu, MenuSize } from './menu.types.js';
8
+ import '../icon/icon.component.js';
9
+ import '../dropdown/dropdown.component.js';
10
+ declare const NrMenuElement_base: (new (...args: any[]) => import("../../shared/dependency-mixin.js").DependencyAware) & (new (...args: any[]) => import("../../shared/theme-mixin.js").ThemeAware) & (new (...args: any[]) => import("../../shared/event-handler-mixin.js").EventHandlerCapable) & typeof LitElement;
11
+ /**
12
+ * Versatile menu component for hierarchical navigation with support for nested submenus.
13
+ *
14
+ * @example
15
+ * ```html
16
+ * <nr-menu .items=${menuItems}></nr-menu>
17
+ * ```
18
+ *
19
+ * @fires change - Menu item selected
20
+ * @fires action-click - Menu action clicked
21
+ *
22
+ * @slot - Menu items (auto-generated from items property)
23
+ */
24
+ export declare class NrMenuElement extends NrMenuElement_base {
25
+ static styles: import("lit").CSSResult[];
26
+ requiredComponents: string[];
27
+ /** Menu items configuration */
9
28
  items: IMenu[];
29
+ /** Menu size variant (small, medium, large) */
30
+ size: MenuSize | string;
31
+ private stateController;
32
+ private keyboardController;
33
+ private accessibilityController;
34
+ private _linkIndex;
35
+ constructor();
10
36
  firstUpdated(): void;
11
- _getPreSelectedIndex(): void;
12
- _updateSelectedLink(updateSelectedLinkEvent: CustomEvent): void;
13
- _handleInitHighlighted(): void;
14
- _selectMenu(selectMenuEvent: CustomEvent): void;
15
- _display(items: IMenu[], path?: number[]): any;
37
+ updated(): void;
38
+ private _initializeSelectedState;
39
+ private _findSelectedPath;
40
+ private _handleLinkClick;
41
+ private _handleSubMenuClick;
42
+ private _toggleSubMenu;
43
+ private _handleSubMenuMouseEnter;
44
+ private _handleSubMenuMouseLeave;
45
+ private _handleActionClick;
46
+ private _isPathSelected;
47
+ private _convertActionsToDropdownItems;
48
+ private _renderMenuLink;
49
+ private _renderSubMenu;
50
+ private _renderMenuItems;
16
51
  render(): import("lit").TemplateResult<1>;
17
- static styles: import("lit").CSSResult[][];
18
52
  }
53
+ export {};
19
54
  //# sourceMappingURL=menu.component.d.ts.map
package/menu.component.js CHANGED
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2023 Nuraly, Laabidi Aymen
4
+ * SPDX-License-Identifier: MIT
5
+ */
1
6
  var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
7
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
8
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -5,105 +10,283 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
10
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
11
  };
7
12
  /* eslint-disable @typescript-eslint/no-explicit-any */
8
- import { LitElement, html } from 'lit';
9
- import { customElement, property, queryAll } from 'lit/decorators.js';
13
+ /* eslint-disable @typescript-eslint/no-unused-vars */
14
+ import { LitElement, html, nothing } from 'lit';
15
+ import { customElement, property } from 'lit/decorators.js';
10
16
  import { styles } from './menu.style.js';
11
- import './templates/hy-menu-link.js';
12
- import './templates/hy-sub-menu.js';
13
- let HyMenuComponent = class HyMenuComponent extends LitElement {
17
+ import { NuralyUIBaseMixin } from '../../shared/base-mixin.js';
18
+ import { StateController, KeyboardController, AccessibilityController } from './controllers/index.js';
19
+ import '../icon/icon.component.js';
20
+ import '../dropdown/dropdown.component.js';
21
+ /**
22
+ * Versatile menu component for hierarchical navigation with support for nested submenus.
23
+ *
24
+ * @example
25
+ * ```html
26
+ * <nr-menu .items=${menuItems}></nr-menu>
27
+ * ```
28
+ *
29
+ * @fires change - Menu item selected
30
+ * @fires action-click - Menu action clicked
31
+ *
32
+ * @slot - Menu items (auto-generated from items property)
33
+ */
34
+ let NrMenuElement = class NrMenuElement extends NuralyUIBaseMixin(LitElement) {
35
+ constructor() {
36
+ super();
37
+ this.requiredComponents = ['nr-icon', 'nr-dropdown'];
38
+ /** Menu items configuration */
39
+ this.items = [];
40
+ /** Menu size variant (small, medium, large) */
41
+ this.size = "medium" /* MenuSize.Medium */;
42
+ this._linkIndex = 0;
43
+ this.stateController = new StateController(this);
44
+ this.keyboardController = new KeyboardController(this, this.stateController);
45
+ this.accessibilityController = new AccessibilityController(this, this.stateController);
46
+ }
14
47
  firstUpdated() {
15
- this._getPreSelectedIndex();
48
+ this._initializeSelectedState();
49
+ this.accessibilityController.updateAriaAttributes();
50
+ }
51
+ updated() {
52
+ this.accessibilityController.updateAriaAttributes();
16
53
  }
17
- _getPreSelectedIndex() {
18
- const listOfLinks = [...this._menuLinks.values()];
19
- this._currentSelectedLink = listOfLinks.findIndex((element) => element.hasAttribute('selected'));
54
+ _initializeSelectedState() {
55
+ this._linkIndex = 0;
56
+ this._findSelectedPath(this.items);
20
57
  }
21
- _updateSelectedLink(updateSelectedLinkEvent) {
58
+ _findSelectedPath(items, path = []) {
59
+ for (let index = 0; index < items.length; index++) {
60
+ const item = items[index];
61
+ const currentPath = [...path, index];
62
+ if (item.children) {
63
+ if (this._findSelectedPath(item.children, currentPath)) {
64
+ return true;
65
+ }
66
+ }
67
+ else {
68
+ if (item.selected) {
69
+ this.stateController.setSelectedPath(currentPath);
70
+ return true;
71
+ }
72
+ }
73
+ }
74
+ return false;
75
+ }
76
+ _handleLinkClick(path, value, event) {
22
77
  var _a;
23
- this._handleInitHighlighted();
24
- const newSelectedIndex = updateSelectedLinkEvent.detail.index;
25
- const value = updateSelectedLinkEvent.detail.value;
26
- if (this._currentSelectedLink >= 0)
27
- this._menuLinks[this._currentSelectedLink].removeAttribute('selected');
28
- this._menuLinks[newSelectedIndex].setAttribute('selected', 'true');
29
- this._currentSelectedLink = newSelectedIndex;
30
- const pathToOption = (_a = this._menuLinks[newSelectedIndex]
31
- .getAttribute('data-path')) === null || _a === void 0 ? void 0 : _a.split('-').map((valueString) => +valueString);
78
+ if ((_a = event === null || event === void 0 ? void 0 : event.target) === null || _a === void 0 ? void 0 : _a.classList.contains('action-icon')) {
79
+ return;
80
+ }
81
+ if ((event === null || event === void 0 ? void 0 : event.type) === 'click') {
82
+ const mouseEvent = event;
83
+ if (mouseEvent.detail > 0) {
84
+ return;
85
+ }
86
+ }
87
+ this.stateController.setSelectedPath(path);
32
88
  this.dispatchEvent(new CustomEvent('change', {
33
89
  bubbles: true,
34
90
  composed: true,
35
- detail: { path: pathToOption, value },
91
+ detail: { path, value },
36
92
  }));
93
+ this.requestUpdate();
37
94
  }
38
- _handleInitHighlighted() {
39
- this._subMenues.forEach((element) => {
40
- if (element.hasAttribute('highlighted')) {
41
- element.removeAttribute('highlighted');
95
+ _handleSubMenuClick(path, value, event) {
96
+ const mouseEvent = event;
97
+ const target = event.target;
98
+ // Don't handle if clicking on toggle icon or its parent container
99
+ if (target.id === 'toggle-icon' || target.closest('#toggle-icon')) {
100
+ return;
101
+ }
102
+ // If it's a click event
103
+ if (event.type === 'click') {
104
+ // Check if it's keyboard activation (Enter/Space) - detail will be 0
105
+ if (mouseEvent.detail === 0) {
106
+ // Keyboard activation - toggle the submenu
107
+ this.stateController.toggleSubMenu(path);
108
+ this.requestUpdate();
109
+ return;
42
110
  }
43
- });
44
- }
45
- _selectMenu(selectMenuEvent) {
46
- if (this._currentSelectedLink >= 0) {
47
- this._menuLinks[this._currentSelectedLink].removeAttribute('selected');
48
- this._currentSelectedLink = -1;
111
+ // Real mouse click - already handled by mousedown, so return
112
+ return;
49
113
  }
50
- this._handleInitHighlighted();
51
- this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true, detail: { path: selectMenuEvent.detail.path, value: selectMenuEvent.detail.value } }));
114
+ // This is a mousedown event - highlight and toggle the submenu
115
+ this.stateController.setSelectedPath([]);
116
+ this.stateController.clearHighlights();
117
+ this.stateController.setHighlighted(path, true);
118
+ // Toggle the submenu when clicking on header
119
+ this.stateController.toggleSubMenu(path);
120
+ this.dispatchEvent(new CustomEvent('change', {
121
+ bubbles: true,
122
+ composed: true,
123
+ detail: { path, value },
124
+ }));
125
+ this.requestUpdate();
126
+ }
127
+ _toggleSubMenu(path, event) {
128
+ event.stopPropagation();
129
+ this.stateController.toggleSubMenu(path);
130
+ this.requestUpdate();
52
131
  }
53
- _display(items, path = []) {
132
+ _handleSubMenuMouseEnter(path) {
133
+ this.stateController.setHovered(path, true);
134
+ this.requestUpdate();
135
+ }
136
+ _handleSubMenuMouseLeave(path) {
137
+ this.stateController.setHovered(path, false);
138
+ this.requestUpdate();
139
+ }
140
+ _handleActionClick(path, event) {
141
+ const item = event.detail.item;
142
+ this.dispatchEvent(new CustomEvent('action-click', {
143
+ detail: { value: item.value, path, item },
144
+ composed: true,
145
+ bubbles: true,
146
+ }));
147
+ }
148
+ _isPathSelected(path) {
149
+ return this.stateController.isPathSelected(path);
150
+ }
151
+ _convertActionsToDropdownItems(actions) {
152
+ return actions.map(action => ({
153
+ id: action.value,
154
+ label: action.label,
155
+ value: action.value
156
+ }));
157
+ }
158
+ _renderMenuLink(menu, path) {
159
+ var _a, _b;
160
+ const pathKey = path.join('-');
161
+ const isSelected = this._isPathSelected(path);
162
+ const linkIndex = this._linkIndex++;
163
+ return html `
164
+ <li
165
+ class="menu-link ${isSelected ? 'selected' : ''} ${menu.disabled ? 'disabled' : ''}"
166
+ data-path=${pathKey}
167
+ data-index=${linkIndex}
168
+ tabindex="0"
169
+ @mousedown=${!menu.disabled ? (e) => this._handleLinkClick(path, menu.text, e) : nothing}
170
+ @click=${!menu.disabled ? (e) => this._handleLinkClick(path, menu.text, e) : nothing}>
171
+ <div class="icon-container">
172
+ ${menu.icon ? html `
173
+ ${!menu.text
174
+ ? html `<div class="icon-only"><nr-icon name="${menu.icon}"></nr-icon></div>`
175
+ : html `<nr-icon name="${menu.icon}"></nr-icon>`}
176
+ ` : nothing}
177
+ </div>
178
+ ${menu.text ? html `
179
+ <div class="action-text-container">
180
+ <div class="text-container">
181
+ <span>${menu.text}</span>
182
+ </div>
183
+ <div class="icon-container">
184
+ ${((_a = menu.status) === null || _a === void 0 ? void 0 : _a.icon) ? html `
185
+ <nr-icon name=${menu.status.icon} class="status-icon"></nr-icon>
186
+ ` : nothing}
187
+ ${((_b = menu.menu) === null || _b === void 0 ? void 0 : _b.actions) ? html `
188
+ <nr-dropdown
189
+ .items=${this._convertActionsToDropdownItems(menu.menu.actions)}
190
+ trigger="click"
191
+ placement="bottom-end"
192
+ @nr-dropdown-item-click=${(e) => this._handleActionClick(path, e)}>
193
+ <nr-icon name="${menu.menu.icon}" class="action-icon" slot="trigger"></nr-icon>
194
+ </nr-dropdown>
195
+ ` : nothing}
196
+ </div>
197
+ </div>
198
+ ` : nothing}
199
+ </li>
200
+ `;
201
+ }
202
+ _renderSubMenu(menu, path) {
203
+ var _a, _b;
204
+ const pathKey = path.join('-');
205
+ const isOpen = this.stateController.isSubMenuOpen(path) || menu.opened;
206
+ const isHovered = this.stateController.isSubMenuHovered(path);
207
+ const isHighlighted = this.stateController.isSubMenuHighlighted(path);
208
+ const isSelected = menu.selected;
209
+ return html `
210
+ <ul
211
+ class="sub-menu ${isHighlighted ? 'highlighted' : ''} ${menu.disabled ? 'disabled' : ''} ${isSelected ? 'selected' : ''}"
212
+ data-path=${pathKey}
213
+ tabindex="0"
214
+ @mouseenter=${() => this._handleSubMenuMouseEnter(path)}
215
+ @mouseleave=${() => this._handleSubMenuMouseLeave(path)}
216
+ @click=${!menu.disabled ? (e) => {
217
+ // Handle keyboard activation on the ul element
218
+ const target = e.target;
219
+ const mouseEvent = e;
220
+ // If click is on the ul itself (not children) and it's keyboard-generated
221
+ if (target.classList.contains('sub-menu') && mouseEvent.detail === 0) {
222
+ e.stopPropagation(); // Prevent bubbling to parent submenus
223
+ this.stateController.toggleSubMenu(path);
224
+ this.requestUpdate();
225
+ }
226
+ } : nothing}>
227
+ <div
228
+ class="sub-menu-header"
229
+ @mousedown=${!menu.disabled ? (e) => this._handleSubMenuClick(path, menu.text, e) : nothing}
230
+ @click=${!menu.disabled ? (e) => this._handleSubMenuClick(path, menu.text, e) : nothing}>
231
+ ${menu.icon ? html `<nr-icon class="text-icon" name="${menu.icon}"></nr-icon>` : nothing}
232
+ <span>${menu.text}</span>
233
+ <div class="icons-container">
234
+ ${((_a = menu.status) === null || _a === void 0 ? void 0 : _a.icon) ? html `
235
+ <nr-icon name=${menu.status.icon} class="status-icon"></nr-icon>
236
+ ` : nothing}
237
+ ${(isHighlighted || isHovered) && ((_b = menu.menu) === null || _b === void 0 ? void 0 : _b.actions) ? html `
238
+ <nr-dropdown
239
+ .items=${this._convertActionsToDropdownItems(menu.menu.actions)}
240
+ trigger="click"
241
+ placement="bottom-end"
242
+ @nr-dropdown-item-click=${(e) => this._handleActionClick(path, e)}>
243
+ <nr-icon name="${menu.menu.icon}" class="action-icon" slot="trigger"></nr-icon>
244
+ </nr-dropdown>
245
+ ` : nothing}
246
+ ${menu.children && menu.children.length ? html `
247
+ <nr-icon
248
+ id="toggle-icon"
249
+ name="${isOpen ? 'angle-up' : 'angle-down'}"
250
+ @mousedown=${!menu.disabled ? (e) => this._toggleSubMenu(path, e) : nothing}>
251
+ </nr-icon>
252
+ ` : nothing}
253
+ </div>
254
+ </div>
255
+ <div class="sub-menu-children" style="display: ${isOpen ? 'block' : 'none'}">
256
+ ${menu.children ? this._renderMenuItems(menu.children, path) : nothing}
257
+ </div>
258
+ </ul>
259
+ `;
260
+ }
261
+ _renderMenuItems(items, parentPath = []) {
54
262
  return items.map((menu, index) => {
55
- const currentPath = [...path, index].join('-');
263
+ const currentPath = [...parentPath, index];
56
264
  if (menu.children) {
57
- return html `
58
- <hy-sub-menu
59
- .menu=${menu}
60
- .text=${menu.text}
61
- .icon=${menu.icon}
62
- .disabled=${menu.disabled}
63
- .status=${menu.status}
64
- ?selected=${menu.selected}
65
- data-path=${currentPath}
66
- @select-menu=${this._selectMenu}>
67
- ${this._display(menu.children, [...path, index])}
68
- </hy-sub-menu>
69
- `;
265
+ return this._renderSubMenu(menu, currentPath);
70
266
  }
71
267
  else {
72
- return html ` <hy-menu-link
73
- data-path=${currentPath}
74
- icon=${menu.icon}
75
- .menu=${menu.menu}
76
- .status=${menu.status}
77
- text=${menu.text}
78
- link=${menu.link}
79
- iconposition=${menu.iconPosition}
80
- ?selected=${menu.selected}
81
- ?disabled=${menu.disabled}
82
- @selected-link=${this._updateSelectedLink}
83
- ></hy-menu-link>`;
268
+ return this._renderMenuLink(menu, currentPath);
84
269
  }
85
270
  });
86
271
  }
87
272
  render() {
273
+ this._linkIndex = 0;
88
274
  return html `
89
- <ul>
90
- ${this._display(this.items)}
275
+ <ul class="menu-root menu--${this.size}">
276
+ ${this._renderMenuItems(this.items)}
91
277
  </ul>
92
278
  `;
93
279
  }
94
280
  };
95
- HyMenuComponent.styles = [styles];
96
- __decorate([
97
- queryAll('hy-menu-link')
98
- ], HyMenuComponent.prototype, "_menuLinks", void 0);
281
+ NrMenuElement.styles = styles;
99
282
  __decorate([
100
- queryAll('hy-sub-menu')
101
- ], HyMenuComponent.prototype, "_subMenues", void 0);
283
+ property({ type: Array })
284
+ ], NrMenuElement.prototype, "items", void 0);
102
285
  __decorate([
103
- property()
104
- ], HyMenuComponent.prototype, "items", void 0);
105
- HyMenuComponent = __decorate([
106
- customElement('hy-menu')
107
- ], HyMenuComponent);
108
- export { HyMenuComponent };
286
+ property({ type: String })
287
+ ], NrMenuElement.prototype, "size", void 0);
288
+ NrMenuElement = __decorate([
289
+ customElement('nr-menu')
290
+ ], NrMenuElement);
291
+ export { NrMenuElement };
109
292
  //# sourceMappingURL=menu.component.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"menu.component.js","sourceRoot":"","sources":["../../../src/components/menu/menu.component.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {LitElement, html} from 'lit';\nimport {customElement, property, queryAll} from 'lit/decorators.js';\nimport {styles} from './menu.style.js';\nimport {IMenu} from './menu.types.js';\nimport './templates/hy-menu-link.js';\nimport './templates/hy-sub-menu.js';\n@customElement('hy-menu')\nexport class HyMenuComponent extends LitElement {\n private _currentSelectedLink!: number;\n @queryAll('hy-menu-link')\n _menuLinks!: NodeListOf<HTMLElement>;\n\n @queryAll('hy-sub-menu')\n _subMenues!: NodeListOf<HTMLElement>;\n\n @property()\n items!: IMenu[];\n\n override firstUpdated(): void {\n this._getPreSelectedIndex();\n }\n\n _getPreSelectedIndex() {\n const listOfLinks = [...this._menuLinks.values()];\n this._currentSelectedLink = listOfLinks.findIndex((element) => element.hasAttribute('selected'));\n }\n\n _updateSelectedLink(updateSelectedLinkEvent: CustomEvent) {\n this._handleInitHighlighted();\n const newSelectedIndex = updateSelectedLinkEvent.detail.index;\n const value = updateSelectedLinkEvent.detail.value;\n if (this._currentSelectedLink >= 0) this._menuLinks[this._currentSelectedLink].removeAttribute('selected');\n this._menuLinks[newSelectedIndex].setAttribute('selected', 'true');\n this._currentSelectedLink = newSelectedIndex;\n const pathToOption = this._menuLinks[newSelectedIndex]\n .getAttribute('data-path')\n ?.split('-')\n .map((valueString) => +valueString);\n this.dispatchEvent(\n new CustomEvent('change', {\n bubbles: true,\n composed: true,\n detail: {path: pathToOption, value},\n })\n );\n }\n\n _handleInitHighlighted() {\n this._subMenues.forEach((element) => {\n if (element.hasAttribute('highlighted')) {\n element.removeAttribute('highlighted');\n }\n });\n }\n _selectMenu(selectMenuEvent:CustomEvent){\n if (this._currentSelectedLink >= 0) \n {\n this._menuLinks[this._currentSelectedLink].removeAttribute('selected');\n this._currentSelectedLink = -1;\n }\n\n this._handleInitHighlighted()\n this.dispatchEvent(new CustomEvent('change',{bubbles:true,composed:true,detail:{path:selectMenuEvent.detail.path,value:selectMenuEvent.detail.value}}));\n }\n\n _display(items: IMenu[], path: number[] = []): any {\n return items.map((menu, index) => {\n const currentPath = [...path, index].join('-');\n if (menu.children) {\n return html`\n <hy-sub-menu \n .menu=${menu} \n .text=${menu.text} \n .icon=${menu.icon} \n .disabled=${menu.disabled} \n .status=${menu.status}\n ?selected=${menu.selected}\n data-path=${currentPath} \n @select-menu=${this._selectMenu}>\n ${this._display(menu.children, [...path, index])}\n </hy-sub-menu>\n `;\n } else {\n return html` <hy-menu-link\n data-path=${currentPath}\n icon=${menu.icon}\n .menu=${menu.menu}\n .status=${menu.status}\n text=${menu.text}\n link=${menu.link}\n iconposition=${menu.iconPosition}\n ?selected=${menu.selected}\n ?disabled=${menu.disabled}\n @selected-link=${this._updateSelectedLink}\n ></hy-menu-link>`;\n }\n });\n }\n\n override render() {\n return html`\n <ul>\n ${this._display(this.items)}\n </ul>\n `;\n }\n\n static override styles = [styles];\n}\n"]}
1
+ {"version":3,"file":"menu.component.js","sourceRoot":"","sources":["../../../src/components/menu/menu.component.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2023 Nuraly, Laabidi Aymen\n * SPDX-License-Identifier: MIT\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/no-unused-vars */\nimport { LitElement, html, nothing } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { styles } from './menu.style.js';\nimport { IMenu, IAction, MenuSize } from './menu.types.js';\nimport { NuralyUIBaseMixin } from '../../shared/base-mixin.js';\nimport { StateController, KeyboardController, AccessibilityController } from './controllers/index.js';\nimport '../icon/icon.component.js';\nimport '../dropdown/dropdown.component.js';\n\n/**\n * Versatile menu component for hierarchical navigation with support for nested submenus.\n * \n * @example\n * ```html\n * <nr-menu .items=${menuItems}></nr-menu>\n * ```\n * \n * @fires change - Menu item selected\n * @fires action-click - Menu action clicked\n * \n * @slot - Menu items (auto-generated from items property)\n */\n@customElement('nr-menu')\nexport class NrMenuElement extends NuralyUIBaseMixin(LitElement) {\n static override styles = styles;\n \n override requiredComponents = ['nr-icon', 'nr-dropdown'];\n\n /** Menu items configuration */\n @property({ type: Array })\n items: IMenu[] = [];\n\n /** Menu size variant (small, medium, large) */\n @property({ type: String })\n size: MenuSize | string = MenuSize.Medium;\n\n // Controllers\n private stateController: StateController;\n // Keyboard controller is connected via Lit's controller system and listens to events\n // @ts-ignore - Controller is used via Lit's reactive controller system\n private keyboardController: KeyboardController;\n private accessibilityController: AccessibilityController;\n\n private _linkIndex = 0;\n\n constructor() {\n super();\n this.stateController = new StateController(this);\n this.keyboardController = new KeyboardController(this, this.stateController);\n this.accessibilityController = new AccessibilityController(this, this.stateController);\n }\n\n override firstUpdated(): void {\n this._initializeSelectedState();\n this.accessibilityController.updateAriaAttributes();\n }\n\n override updated(): void {\n this.accessibilityController.updateAriaAttributes();\n }\n\n private _initializeSelectedState() {\n this._linkIndex = 0;\n this._findSelectedPath(this.items);\n }\n\n private _findSelectedPath(items: IMenu[], path: number[] = []): boolean {\n for (let index = 0; index < items.length; index++) {\n const item = items[index];\n const currentPath = [...path, index];\n \n if (item.children) {\n if (this._findSelectedPath(item.children, currentPath)) {\n return true;\n }\n } else {\n if (item.selected) {\n this.stateController.setSelectedPath(currentPath);\n return true;\n }\n }\n }\n return false;\n }\n\n private _handleLinkClick(path: number[], value: string, event?: Event) {\n if ((event?.target as HTMLElement)?.classList.contains('action-icon')) {\n return;\n }\n\n if (event?.type === 'click') {\n const mouseEvent = event as MouseEvent;\n if (mouseEvent.detail > 0) {\n return;\n }\n }\n\n this.stateController.setSelectedPath(path);\n \n this.dispatchEvent(\n new CustomEvent('change', {\n bubbles: true,\n composed: true,\n detail: { path, value },\n })\n );\n \n this.requestUpdate();\n }\n\n private _handleSubMenuClick(path: number[], value: string, event: Event) {\n const mouseEvent = event as MouseEvent;\n const target = event.target as HTMLElement;\n \n // Don't handle if clicking on toggle icon or its parent container\n if (target.id === 'toggle-icon' || target.closest('#toggle-icon')) {\n return;\n }\n \n // If it's a click event\n if (event.type === 'click') {\n // Check if it's keyboard activation (Enter/Space) - detail will be 0\n if (mouseEvent.detail === 0) {\n // Keyboard activation - toggle the submenu\n this.stateController.toggleSubMenu(path);\n this.requestUpdate();\n return;\n }\n // Real mouse click - already handled by mousedown, so return\n return;\n }\n\n // This is a mousedown event - highlight and toggle the submenu\n \n this.stateController.setSelectedPath([]);\n this.stateController.clearHighlights();\n this.stateController.setHighlighted(path, true);\n \n // Toggle the submenu when clicking on header\n this.stateController.toggleSubMenu(path);\n\n this.dispatchEvent(\n new CustomEvent('change', {\n bubbles: true,\n composed: true,\n detail: { path, value },\n })\n );\n \n this.requestUpdate();\n }\n\n private _toggleSubMenu(path: number[], event: Event) {\n event.stopPropagation();\n this.stateController.toggleSubMenu(path);\n this.requestUpdate();\n }\n\n private _handleSubMenuMouseEnter(path: number[]) {\n this.stateController.setHovered(path, true);\n this.requestUpdate();\n }\n\n private _handleSubMenuMouseLeave(path: number[]) {\n this.stateController.setHovered(path, false);\n this.requestUpdate();\n }\n\n private _handleActionClick(path: number[], event: CustomEvent) {\n const item = event.detail.item;\n this.dispatchEvent(\n new CustomEvent('action-click', {\n detail: { value: item.value, path, item },\n composed: true,\n bubbles: true,\n })\n );\n }\n\n private _isPathSelected(path: number[]): boolean {\n return this.stateController.isPathSelected(path);\n }\n\n private _convertActionsToDropdownItems(actions: IAction[]): any[] {\n return actions.map(action => ({\n id: action.value,\n label: action.label,\n value: action.value\n }));\n }\n\n private _renderMenuLink(menu: IMenu, path: number[]): any {\n const pathKey = path.join('-');\n const isSelected = this._isPathSelected(path);\n const linkIndex = this._linkIndex++;\n \n return html`\n <li \n class=\"menu-link ${isSelected ? 'selected' : ''} ${menu.disabled ? 'disabled' : ''}\"\n data-path=${pathKey}\n data-index=${linkIndex}\n tabindex=\"0\"\n @mousedown=${!menu.disabled ? (e: Event) => this._handleLinkClick(path, menu.text, e) : nothing}\n @click=${!menu.disabled ? (e: Event) => this._handleLinkClick(path, menu.text, e) : nothing}>\n <div class=\"icon-container\">\n ${menu.icon ? html`\n ${!menu.text \n ? html`<div class=\"icon-only\"><nr-icon name=\"${menu.icon}\"></nr-icon></div>`\n : html`<nr-icon name=\"${menu.icon}\"></nr-icon>`}\n ` : nothing}\n </div>\n ${menu.text ? html`\n <div class=\"action-text-container\">\n <div class=\"text-container\">\n <span>${menu.text}</span>\n </div>\n <div class=\"icon-container\">\n ${menu.status?.icon ? html`\n <nr-icon name=${menu.status.icon} class=\"status-icon\"></nr-icon>\n ` : nothing}\n ${menu.menu?.actions ? html`\n <nr-dropdown \n .items=${this._convertActionsToDropdownItems(menu.menu.actions)} \n trigger=\"click\" \n placement=\"bottom-end\"\n @nr-dropdown-item-click=${(e: CustomEvent) => this._handleActionClick(path, e)}>\n <nr-icon name=\"${menu.menu.icon}\" class=\"action-icon\" slot=\"trigger\"></nr-icon>\n </nr-dropdown>\n ` : nothing}\n </div>\n </div>\n ` : nothing}\n </li>\n `;\n }\n\n private _renderSubMenu(menu: IMenu, path: number[]): any {\n const pathKey = path.join('-');\n const isOpen = this.stateController.isSubMenuOpen(path) || menu.opened;\n const isHovered = this.stateController.isSubMenuHovered(path);\n const isHighlighted = this.stateController.isSubMenuHighlighted(path);\n const isSelected = menu.selected;\n \n return html`\n <ul \n class=\"sub-menu ${isHighlighted ? 'highlighted' : ''} ${menu.disabled ? 'disabled' : ''} ${isSelected ? 'selected' : ''}\"\n data-path=${pathKey}\n tabindex=\"0\"\n @mouseenter=${() => this._handleSubMenuMouseEnter(path)}\n @mouseleave=${() => this._handleSubMenuMouseLeave(path)}\n @click=${!menu.disabled ? (e: Event) => {\n // Handle keyboard activation on the ul element\n const target = e.target as HTMLElement;\n const mouseEvent = e as MouseEvent;\n // If click is on the ul itself (not children) and it's keyboard-generated\n if (target.classList.contains('sub-menu') && mouseEvent.detail === 0) {\n e.stopPropagation(); // Prevent bubbling to parent submenus\n this.stateController.toggleSubMenu(path);\n this.requestUpdate();\n }\n } : nothing}>\n <div \n class=\"sub-menu-header\"\n @mousedown=${!menu.disabled ? (e: Event) => this._handleSubMenuClick(path, menu.text, e) : nothing}\n @click=${!menu.disabled ? (e: Event) => this._handleSubMenuClick(path, menu.text, e) : nothing}>\n ${menu.icon ? html`<nr-icon class=\"text-icon\" name=\"${menu.icon}\"></nr-icon>` : nothing}\n <span>${menu.text}</span>\n <div class=\"icons-container\">\n ${menu.status?.icon ? html`\n <nr-icon name=${menu.status.icon} class=\"status-icon\"></nr-icon>\n ` : nothing}\n ${(isHighlighted || isHovered) && menu.menu?.actions ? html`\n <nr-dropdown \n .items=${this._convertActionsToDropdownItems(menu.menu.actions)} \n trigger=\"click\" \n placement=\"bottom-end\"\n @nr-dropdown-item-click=${(e: CustomEvent) => this._handleActionClick(path, e)}>\n <nr-icon name=\"${menu.menu.icon}\" class=\"action-icon\" slot=\"trigger\"></nr-icon>\n </nr-dropdown>\n ` : nothing}\n ${menu.children && menu.children.length ? html`\n <nr-icon \n id=\"toggle-icon\" \n name=\"${isOpen ? 'angle-up' : 'angle-down'}\" \n @mousedown=${!menu.disabled ? (e: Event) => this._toggleSubMenu(path, e) : nothing}>\n </nr-icon>\n ` : nothing}\n </div>\n </div>\n <div class=\"sub-menu-children\" style=\"display: ${isOpen ? 'block' : 'none'}\">\n ${menu.children ? this._renderMenuItems(menu.children, path) : nothing}\n </div>\n </ul>\n `;\n }\n\n private _renderMenuItems(items: IMenu[], parentPath: number[] = []): any {\n return items.map((menu, index) => {\n const currentPath = [...parentPath, index];\n \n if (menu.children) {\n return this._renderSubMenu(menu, currentPath);\n } else {\n return this._renderMenuLink(menu, currentPath);\n }\n });\n }\n\n override render() {\n this._linkIndex = 0;\n return html`\n <ul class=\"menu-root menu--${this.size}\">\n ${this._renderMenuItems(this.items)}\n </ul>\n `;\n }\n}\n"]}