@nuralyui/dropdown 0.0.10 → 0.0.16
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 +881 -0
- package/dropdown.component.d.ts +118 -0
- package/dropdown.component.js +376 -0
- package/dropdown.component.js.map +1 -0
- package/{hy-dropdown.style.d.ts → dropdown.style.d.ts} +1 -1
- package/dropdown.style.js +451 -0
- package/dropdown.style.js.map +1 -0
- package/dropdown.types.d.ts +83 -1
- package/dropdown.types.js.map +1 -1
- package/index.d.ts +2 -1
- package/index.js +2 -1
- package/index.js.map +1 -1
- package/package.json +17 -6
- package/react.d.ts +6 -2
- package/react.js +9 -5
- package/react.js.map +1 -1
- package/demo/hy-dropdowns-demo.d.ts +0 -19
- package/demo/hy-dropdowns-demo.d.ts.map +0 -1
- package/demo/hy-dropdowns-demo.js +0 -205
- package/demo/hy-dropdowns-demo.js.map +0 -1
- package/dropdown.types.d.ts.map +0 -1
- package/hy-dropdown.component.d.ts +0 -30
- package/hy-dropdown.component.d.ts.map +0 -1
- package/hy-dropdown.component.js +0 -183
- package/hy-dropdown.component.js.map +0 -1
- package/hy-dropdown.style.d.ts.map +0 -1
- package/hy-dropdown.style.js +0 -47
- package/hy-dropdown.style.js.map +0 -1
- package/index.d.ts.map +0 -1
- package/react.d.ts.map +0 -1
- package/templates/hy-dropdown-item.d.ts +0 -12
- package/templates/hy-dropdown-item.d.ts.map +0 -1
- package/templates/hy-dropdown-item.js +0 -55
- package/templates/hy-dropdown-item.js.map +0 -1
- package/templates/hy-dropdown-item.style.d.ts +0 -2
- package/templates/hy-dropdown-item.style.d.ts.map +0 -1
- package/templates/hy-dropdown-item.style.js +0 -34
- package/templates/hy-dropdown-item.style.js.map +0 -1
- package/templates/hy-dropdown-menu.d.ts +0 -18
- package/templates/hy-dropdown-menu.d.ts.map +0 -1
- package/templates/hy-dropdown-menu.js +0 -70
- package/templates/hy-dropdown-menu.js.map +0 -1
- package/templates/hy-dropdown-menu.style.d.ts +0 -2
- package/templates/hy-dropdown-menu.style.d.ts.map +0 -1
- package/templates/hy-dropdown-menu.style.js +0 -49
- package/templates/hy-dropdown-menu.style.js.map +0 -1
- package/test/hy-dropdown_test.d.ts +0 -4
- package/test/hy-dropdown_test.d.ts.map +0 -1
- package/test/hy-dropdown_test.js +0 -132
- package/test/hy-dropdown_test.js.map +0 -1
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2023 Nuraly, Laabidi Aymen
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*/
|
|
6
|
+
import { LitElement } from 'lit';
|
|
7
|
+
import '../icon/index.js';
|
|
8
|
+
import { DropdownPlacement, DropdownTrigger, DropdownSize, DropdownAnimation, DropdownItem } from './dropdown.types.js';
|
|
9
|
+
declare const NrDropdownElement_base: (new (...args: any[]) => import("../../shared").DependencyAware) & (new (...args: any[]) => import("../../shared").ThemeAware) & (new (...args: any[]) => import("../../shared").EventHandlerCapable) & typeof LitElement;
|
|
10
|
+
/**
|
|
11
|
+
* # Dropdown Component
|
|
12
|
+
*
|
|
13
|
+
* A versatile dropdown component that provides floating panel functionality with customizable triggers,
|
|
14
|
+
* content, and positioning. Supports both predefined item lists and custom slot content with
|
|
15
|
+
* cascading submenus and interactive elements.
|
|
16
|
+
*
|
|
17
|
+
* ## Features
|
|
18
|
+
* - Multiple trigger modes (hover, click, focus, manual)
|
|
19
|
+
* - Flexible positioning with auto-placement
|
|
20
|
+
* - Cascading submenus with custom content support
|
|
21
|
+
* - Interactive elements (forms, buttons) within dropdowns
|
|
22
|
+
* - Keyboard navigation and accessibility
|
|
23
|
+
* - Customizable animations and styling
|
|
24
|
+
* - Event delegation and outside click detection
|
|
25
|
+
*
|
|
26
|
+
* ## Usage
|
|
27
|
+
* ```html
|
|
28
|
+
* <!-- Basic dropdown with slot content -->
|
|
29
|
+
* <nr-dropdown trigger="hover">
|
|
30
|
+
* <button slot="trigger">Menu</button>
|
|
31
|
+
* <div slot="content">
|
|
32
|
+
* <p>Custom content here</p>
|
|
33
|
+
* </div>
|
|
34
|
+
* </nr-dropdown>
|
|
35
|
+
*
|
|
36
|
+
* <!-- Dropdown with predefined items -->
|
|
37
|
+
* <nr-dropdown
|
|
38
|
+
* .items="${items}"
|
|
39
|
+
* placement="bottom-start"
|
|
40
|
+
* trigger="click">
|
|
41
|
+
* <button slot="trigger">Menu</button>
|
|
42
|
+
* </nr-dropdown>
|
|
43
|
+
*
|
|
44
|
+
* <!-- Hover dropdown with custom positioning -->
|
|
45
|
+
* <nr-dropdown
|
|
46
|
+
* trigger="hover"
|
|
47
|
+
* placement="top"
|
|
48
|
+
* size="large">
|
|
49
|
+
* <span slot="trigger">Hover me</span>
|
|
50
|
+
* <div slot="content">Tooltip content</div>
|
|
51
|
+
* </nr-dropdown>
|
|
52
|
+
* ```
|
|
53
|
+
*
|
|
54
|
+
* @element nr-dropdown
|
|
55
|
+
* @fires nr-dropdown-open - Fired when dropdown opens
|
|
56
|
+
* @fires nr-dropdown-close - Fired when dropdown closes
|
|
57
|
+
* @fires nr-dropdown-item-click - Fired when dropdown item is clicked
|
|
58
|
+
*
|
|
59
|
+
* @slot trigger - Element that triggers the dropdown
|
|
60
|
+
* @slot content - Custom content for the dropdown panel
|
|
61
|
+
* @slot header - Optional header content
|
|
62
|
+
* @slot footer - Optional footer content
|
|
63
|
+
*
|
|
64
|
+
* @cssproperty --dropdown-background - Background color of dropdown panel
|
|
65
|
+
* @cssproperty --dropdown-border - Border of dropdown panel
|
|
66
|
+
* @cssproperty --dropdown-shadow - Shadow of dropdown panel
|
|
67
|
+
* @cssproperty --dropdown-border-radius - Border radius of dropdown panel
|
|
68
|
+
* @cssproperty --dropdown-max-width - Maximum width of dropdown panel
|
|
69
|
+
* @cssproperty --dropdown-min-width - Minimum width of dropdown panel
|
|
70
|
+
* @cssproperty --dropdown-max-height - Maximum height of dropdown panel
|
|
71
|
+
*/
|
|
72
|
+
export declare class NrDropdownElement extends NrDropdownElement_base {
|
|
73
|
+
static styles: import("lit").CSSResult;
|
|
74
|
+
requiredComponents: string[];
|
|
75
|
+
items: DropdownItem[];
|
|
76
|
+
open: boolean;
|
|
77
|
+
placement: DropdownPlacement;
|
|
78
|
+
trigger: DropdownTrigger;
|
|
79
|
+
size: DropdownSize;
|
|
80
|
+
animation: DropdownAnimation;
|
|
81
|
+
disabled: boolean;
|
|
82
|
+
arrow: boolean;
|
|
83
|
+
autoClose: boolean;
|
|
84
|
+
closeOnOutsideClick: boolean;
|
|
85
|
+
closeOnEscape: boolean;
|
|
86
|
+
offset: number;
|
|
87
|
+
delay: number;
|
|
88
|
+
maxHeight: string;
|
|
89
|
+
minWidth: string;
|
|
90
|
+
cascadeDirection: 'right' | 'left' | 'auto';
|
|
91
|
+
cascadeDelay: number;
|
|
92
|
+
cascadeOnHover: boolean;
|
|
93
|
+
private dropdownController;
|
|
94
|
+
private openSubmenus;
|
|
95
|
+
private submenuTimers;
|
|
96
|
+
connectedCallback(): void;
|
|
97
|
+
updated(changedProperties: Map<string, any>): void;
|
|
98
|
+
disconnectedCallback(): void;
|
|
99
|
+
firstUpdated(): void;
|
|
100
|
+
private updateCascadingAttribute;
|
|
101
|
+
private handleDropdownPanelClick;
|
|
102
|
+
private handleItemClick;
|
|
103
|
+
private handleItemHover;
|
|
104
|
+
private handleItemLeave;
|
|
105
|
+
private handleSubmenuEnter;
|
|
106
|
+
private handleSubmenuLeave;
|
|
107
|
+
private clearSubmenuTimer;
|
|
108
|
+
private toggleSubmenu;
|
|
109
|
+
private showSubmenu;
|
|
110
|
+
private hideSubmenu;
|
|
111
|
+
show(): void;
|
|
112
|
+
hide(): void;
|
|
113
|
+
toggle(): void;
|
|
114
|
+
private renderItems;
|
|
115
|
+
render(): import("lit").TemplateResult<1>;
|
|
116
|
+
}
|
|
117
|
+
export {};
|
|
118
|
+
//# sourceMappingURL=dropdown.component.d.ts.map
|
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2023 Nuraly, Laabidi Aymen
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*/
|
|
6
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
7
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
9
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
10
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
11
|
+
};
|
|
12
|
+
import { html, LitElement, nothing } from 'lit';
|
|
13
|
+
import { customElement, property } from 'lit/decorators.js';
|
|
14
|
+
import { styles } from './dropdown.style';
|
|
15
|
+
import { classMap } from 'lit/directives/class-map.js';
|
|
16
|
+
import { styleMap } from 'lit/directives/style-map.js';
|
|
17
|
+
import { NuralyUIBaseMixin } from '../../shared/base-mixin.js';
|
|
18
|
+
import { NrDropdownController } from './controllers/dropdown.controller.js';
|
|
19
|
+
import '../icon/index.js';
|
|
20
|
+
/**
|
|
21
|
+
* # Dropdown Component
|
|
22
|
+
*
|
|
23
|
+
* A versatile dropdown component that provides floating panel functionality with customizable triggers,
|
|
24
|
+
* content, and positioning. Supports both predefined item lists and custom slot content with
|
|
25
|
+
* cascading submenus and interactive elements.
|
|
26
|
+
*
|
|
27
|
+
* ## Features
|
|
28
|
+
* - Multiple trigger modes (hover, click, focus, manual)
|
|
29
|
+
* - Flexible positioning with auto-placement
|
|
30
|
+
* - Cascading submenus with custom content support
|
|
31
|
+
* - Interactive elements (forms, buttons) within dropdowns
|
|
32
|
+
* - Keyboard navigation and accessibility
|
|
33
|
+
* - Customizable animations and styling
|
|
34
|
+
* - Event delegation and outside click detection
|
|
35
|
+
*
|
|
36
|
+
* ## Usage
|
|
37
|
+
* ```html
|
|
38
|
+
* <!-- Basic dropdown with slot content -->
|
|
39
|
+
* <nr-dropdown trigger="hover">
|
|
40
|
+
* <button slot="trigger">Menu</button>
|
|
41
|
+
* <div slot="content">
|
|
42
|
+
* <p>Custom content here</p>
|
|
43
|
+
* </div>
|
|
44
|
+
* </nr-dropdown>
|
|
45
|
+
*
|
|
46
|
+
* <!-- Dropdown with predefined items -->
|
|
47
|
+
* <nr-dropdown
|
|
48
|
+
* .items="${items}"
|
|
49
|
+
* placement="bottom-start"
|
|
50
|
+
* trigger="click">
|
|
51
|
+
* <button slot="trigger">Menu</button>
|
|
52
|
+
* </nr-dropdown>
|
|
53
|
+
*
|
|
54
|
+
* <!-- Hover dropdown with custom positioning -->
|
|
55
|
+
* <nr-dropdown
|
|
56
|
+
* trigger="hover"
|
|
57
|
+
* placement="top"
|
|
58
|
+
* size="large">
|
|
59
|
+
* <span slot="trigger">Hover me</span>
|
|
60
|
+
* <div slot="content">Tooltip content</div>
|
|
61
|
+
* </nr-dropdown>
|
|
62
|
+
* ```
|
|
63
|
+
*
|
|
64
|
+
* @element nr-dropdown
|
|
65
|
+
* @fires nr-dropdown-open - Fired when dropdown opens
|
|
66
|
+
* @fires nr-dropdown-close - Fired when dropdown closes
|
|
67
|
+
* @fires nr-dropdown-item-click - Fired when dropdown item is clicked
|
|
68
|
+
*
|
|
69
|
+
* @slot trigger - Element that triggers the dropdown
|
|
70
|
+
* @slot content - Custom content for the dropdown panel
|
|
71
|
+
* @slot header - Optional header content
|
|
72
|
+
* @slot footer - Optional footer content
|
|
73
|
+
*
|
|
74
|
+
* @cssproperty --dropdown-background - Background color of dropdown panel
|
|
75
|
+
* @cssproperty --dropdown-border - Border of dropdown panel
|
|
76
|
+
* @cssproperty --dropdown-shadow - Shadow of dropdown panel
|
|
77
|
+
* @cssproperty --dropdown-border-radius - Border radius of dropdown panel
|
|
78
|
+
* @cssproperty --dropdown-max-width - Maximum width of dropdown panel
|
|
79
|
+
* @cssproperty --dropdown-min-width - Minimum width of dropdown panel
|
|
80
|
+
* @cssproperty --dropdown-max-height - Maximum height of dropdown panel
|
|
81
|
+
*/
|
|
82
|
+
let NrDropdownElement = class NrDropdownElement extends NuralyUIBaseMixin(LitElement) {
|
|
83
|
+
constructor() {
|
|
84
|
+
super(...arguments);
|
|
85
|
+
this.requiredComponents = ['nr-icon'];
|
|
86
|
+
this.items = [];
|
|
87
|
+
this.open = false;
|
|
88
|
+
this.placement = "bottom" /* DropdownPlacement.Bottom */;
|
|
89
|
+
this.trigger = "hover" /* DropdownTrigger.Hover */;
|
|
90
|
+
this.size = "medium" /* DropdownSize.Medium */;
|
|
91
|
+
this.animation = "fade" /* DropdownAnimation.Fade */;
|
|
92
|
+
this.disabled = false;
|
|
93
|
+
this.arrow = false;
|
|
94
|
+
this.autoClose = false;
|
|
95
|
+
this.closeOnOutsideClick = true;
|
|
96
|
+
this.closeOnEscape = true;
|
|
97
|
+
this.offset = 4;
|
|
98
|
+
this.delay = 50;
|
|
99
|
+
this.maxHeight = '300px';
|
|
100
|
+
this.minWidth = 'auto';
|
|
101
|
+
this.cascadeDirection = 'auto';
|
|
102
|
+
this.cascadeDelay = 50;
|
|
103
|
+
this.cascadeOnHover = true;
|
|
104
|
+
this.dropdownController = new NrDropdownController(this);
|
|
105
|
+
this.openSubmenus = new Set();
|
|
106
|
+
this.submenuTimers = new Map();
|
|
107
|
+
this.handleDropdownPanelClick = (e) => {
|
|
108
|
+
e.stopPropagation();
|
|
109
|
+
};
|
|
110
|
+
this.handleItemClick = (item) => {
|
|
111
|
+
if (item.disabled)
|
|
112
|
+
return;
|
|
113
|
+
if ((item.options && item.options.length > 0) || item.customContent) {
|
|
114
|
+
this.toggleSubmenu(item.id);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
this.dropdownController.handleItemClick(item);
|
|
118
|
+
};
|
|
119
|
+
this.handleItemHover = (item) => {
|
|
120
|
+
var _a;
|
|
121
|
+
if (!((_a = item.options) === null || _a === void 0 ? void 0 : _a.length) && !item.customContent)
|
|
122
|
+
return;
|
|
123
|
+
this.clearSubmenuTimer(item.id);
|
|
124
|
+
if (this.cascadeOnHover) {
|
|
125
|
+
const timer = window.setTimeout(() => {
|
|
126
|
+
this.showSubmenu(item.id);
|
|
127
|
+
}, this.cascadeDelay);
|
|
128
|
+
this.submenuTimers.set(item.id, timer);
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
this.handleItemLeave = (item) => {
|
|
132
|
+
var _a;
|
|
133
|
+
if (!((_a = item.options) === null || _a === void 0 ? void 0 : _a.length) && !item.customContent)
|
|
134
|
+
return;
|
|
135
|
+
this.clearSubmenuTimer(item.id);
|
|
136
|
+
const timer = window.setTimeout(() => {
|
|
137
|
+
this.hideSubmenu(item.id);
|
|
138
|
+
}, 100);
|
|
139
|
+
this.submenuTimers.set(`hide-${item.id}`, timer);
|
|
140
|
+
};
|
|
141
|
+
this.handleSubmenuEnter = (itemId) => {
|
|
142
|
+
this.clearSubmenuTimer(`hide-${itemId}`);
|
|
143
|
+
};
|
|
144
|
+
this.handleSubmenuLeave = (itemId) => {
|
|
145
|
+
const timer = window.setTimeout(() => {
|
|
146
|
+
this.hideSubmenu(itemId);
|
|
147
|
+
}, 100);
|
|
148
|
+
this.submenuTimers.set(`hide-${itemId}`, timer);
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
connectedCallback() {
|
|
152
|
+
super.connectedCallback();
|
|
153
|
+
this.updateCascadingAttribute();
|
|
154
|
+
}
|
|
155
|
+
updated(changedProperties) {
|
|
156
|
+
super.updated(changedProperties);
|
|
157
|
+
if (changedProperties.has('items')) {
|
|
158
|
+
this.updateCascadingAttribute();
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
disconnectedCallback() {
|
|
162
|
+
super.disconnectedCallback();
|
|
163
|
+
}
|
|
164
|
+
firstUpdated() {
|
|
165
|
+
}
|
|
166
|
+
updateCascadingAttribute() {
|
|
167
|
+
const hasCascading = this.items.some(item => (item.options && item.options.length > 0) || !!item.customContent);
|
|
168
|
+
if (hasCascading) {
|
|
169
|
+
this.setAttribute('has-cascading', '');
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
this.removeAttribute('has-cascading');
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
clearSubmenuTimer(key) {
|
|
176
|
+
const timer = this.submenuTimers.get(key);
|
|
177
|
+
if (timer) {
|
|
178
|
+
clearTimeout(timer);
|
|
179
|
+
this.submenuTimers.delete(key);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
toggleSubmenu(itemId) {
|
|
183
|
+
if (this.openSubmenus.has(itemId)) {
|
|
184
|
+
this.hideSubmenu(itemId);
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
this.showSubmenu(itemId);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
showSubmenu(itemId) {
|
|
191
|
+
this.openSubmenus.add(itemId);
|
|
192
|
+
this.requestUpdate();
|
|
193
|
+
}
|
|
194
|
+
hideSubmenu(itemId) {
|
|
195
|
+
this.openSubmenus.delete(itemId);
|
|
196
|
+
this.requestUpdate();
|
|
197
|
+
}
|
|
198
|
+
show() {
|
|
199
|
+
this.dropdownController.open();
|
|
200
|
+
}
|
|
201
|
+
hide() {
|
|
202
|
+
this.dropdownController.close();
|
|
203
|
+
}
|
|
204
|
+
toggle() {
|
|
205
|
+
this.dropdownController.toggle();
|
|
206
|
+
}
|
|
207
|
+
renderItems() {
|
|
208
|
+
if (!this.items.length)
|
|
209
|
+
return nothing;
|
|
210
|
+
return html `
|
|
211
|
+
<div class="dropdown__items">
|
|
212
|
+
${this.items.map(item => {
|
|
213
|
+
if (item.divider) {
|
|
214
|
+
return html `<div class="dropdown__divider"></div>`;
|
|
215
|
+
}
|
|
216
|
+
const hasSubmenu = !!(item.options && item.options.length > 0) || !!item.customContent;
|
|
217
|
+
const isSubmenuOpen = hasSubmenu && this.openSubmenus.has(item.id);
|
|
218
|
+
return html `
|
|
219
|
+
<div class="dropdown__item-container ${classMap({
|
|
220
|
+
'dropdown__item-container--has-submenu': hasSubmenu
|
|
221
|
+
})}">
|
|
222
|
+
<button
|
|
223
|
+
class="dropdown__item ${classMap({
|
|
224
|
+
'dropdown__item--disabled': !!item.disabled,
|
|
225
|
+
'dropdown__item--has-submenu': hasSubmenu
|
|
226
|
+
})}"
|
|
227
|
+
?disabled="${item.disabled}"
|
|
228
|
+
@click="${() => this.handleItemClick(item)}"
|
|
229
|
+
@mouseenter="${() => hasSubmenu && this.handleItemHover(item)}"
|
|
230
|
+
@mouseleave="${() => hasSubmenu && this.handleItemLeave(item)}"
|
|
231
|
+
>
|
|
232
|
+
${item.icon ? html `<nr-icon name="${item.icon}" class="dropdown__item-icon"></nr-icon>` : nothing}
|
|
233
|
+
<span class="dropdown__item-label">${item.label}</span>
|
|
234
|
+
${hasSubmenu ? html `<nr-icon name="chevron-right" class="dropdown__submenu-arrow"></nr-icon>` : nothing}
|
|
235
|
+
</button>
|
|
236
|
+
|
|
237
|
+
${hasSubmenu && isSubmenuOpen ? html `
|
|
238
|
+
<div class="dropdown__submenu ${classMap({
|
|
239
|
+
'dropdown__submenu--right': this.cascadeDirection === 'right' || this.cascadeDirection === 'auto',
|
|
240
|
+
'dropdown__submenu--left': this.cascadeDirection === 'left'
|
|
241
|
+
})}"
|
|
242
|
+
@mouseenter="${() => this.handleSubmenuEnter(item.id)}"
|
|
243
|
+
@mouseleave="${() => this.handleSubmenuLeave(item.id)}">
|
|
244
|
+
${item.customContent ? html `
|
|
245
|
+
<div class="dropdown__custom-content">
|
|
246
|
+
${typeof item.customContent === 'string'
|
|
247
|
+
? html `<div .innerHTML="${item.customContent}"></div>`
|
|
248
|
+
: item.customContent}
|
|
249
|
+
</div>
|
|
250
|
+
` : html `
|
|
251
|
+
<div class="dropdown__items">
|
|
252
|
+
${item.options.map(subItem => {
|
|
253
|
+
if (subItem.divider) {
|
|
254
|
+
return html `<div class="dropdown__divider"></div>`;
|
|
255
|
+
}
|
|
256
|
+
return html `
|
|
257
|
+
<button
|
|
258
|
+
class="dropdown__item ${classMap({
|
|
259
|
+
'dropdown__item--disabled': !!subItem.disabled
|
|
260
|
+
})}"
|
|
261
|
+
?disabled="${subItem.disabled}"
|
|
262
|
+
@click="${() => this.handleItemClick(subItem)}"
|
|
263
|
+
>
|
|
264
|
+
${subItem.icon ? html `<nr-icon name="${subItem.icon}" class="dropdown__item-icon"></nr-icon>` : nothing}
|
|
265
|
+
<span class="dropdown__item-label">${subItem.label}</span>
|
|
266
|
+
</button>
|
|
267
|
+
`;
|
|
268
|
+
})}
|
|
269
|
+
</div>
|
|
270
|
+
`}
|
|
271
|
+
</div>
|
|
272
|
+
` : nothing}
|
|
273
|
+
</div>
|
|
274
|
+
`;
|
|
275
|
+
})}
|
|
276
|
+
</div>
|
|
277
|
+
`;
|
|
278
|
+
}
|
|
279
|
+
render() {
|
|
280
|
+
const panelClasses = {
|
|
281
|
+
'dropdown__panel': true,
|
|
282
|
+
'dropdown__panel--open': this.open,
|
|
283
|
+
[`dropdown__panel--${this.size}`]: true,
|
|
284
|
+
[`dropdown__panel--${this.animation}`]: true,
|
|
285
|
+
[`dropdown__panel--${this.placement}`]: true,
|
|
286
|
+
'dropdown__panel--with-arrow': this.arrow
|
|
287
|
+
};
|
|
288
|
+
const panelStyles = {
|
|
289
|
+
maxHeight: this.maxHeight,
|
|
290
|
+
minWidth: this.minWidth
|
|
291
|
+
};
|
|
292
|
+
return html `
|
|
293
|
+
<div class="dropdown">
|
|
294
|
+
<div class="dropdown__trigger">
|
|
295
|
+
<slot name="trigger"></slot>
|
|
296
|
+
</div>
|
|
297
|
+
|
|
298
|
+
<div
|
|
299
|
+
class="${classMap(panelClasses)}"
|
|
300
|
+
style="${styleMap(panelStyles)}"
|
|
301
|
+
@click="${this.handleDropdownPanelClick}"
|
|
302
|
+
>
|
|
303
|
+
${this.arrow ? html `<div class="dropdown__arrow"></div>` : nothing}
|
|
304
|
+
|
|
305
|
+
<slot name="header"></slot>
|
|
306
|
+
|
|
307
|
+
<div class="dropdown__content">
|
|
308
|
+
<slot name="content">${this.renderItems()}</slot>
|
|
309
|
+
</div>
|
|
310
|
+
|
|
311
|
+
<slot name="footer"></slot>
|
|
312
|
+
</div>
|
|
313
|
+
</div>
|
|
314
|
+
`;
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
NrDropdownElement.styles = styles;
|
|
318
|
+
__decorate([
|
|
319
|
+
property({ type: Array })
|
|
320
|
+
], NrDropdownElement.prototype, "items", void 0);
|
|
321
|
+
__decorate([
|
|
322
|
+
property({ type: Boolean, reflect: true })
|
|
323
|
+
], NrDropdownElement.prototype, "open", void 0);
|
|
324
|
+
__decorate([
|
|
325
|
+
property({ type: String })
|
|
326
|
+
], NrDropdownElement.prototype, "placement", void 0);
|
|
327
|
+
__decorate([
|
|
328
|
+
property({ type: String })
|
|
329
|
+
], NrDropdownElement.prototype, "trigger", void 0);
|
|
330
|
+
__decorate([
|
|
331
|
+
property({ type: String })
|
|
332
|
+
], NrDropdownElement.prototype, "size", void 0);
|
|
333
|
+
__decorate([
|
|
334
|
+
property({ type: String })
|
|
335
|
+
], NrDropdownElement.prototype, "animation", void 0);
|
|
336
|
+
__decorate([
|
|
337
|
+
property({ type: Boolean })
|
|
338
|
+
], NrDropdownElement.prototype, "disabled", void 0);
|
|
339
|
+
__decorate([
|
|
340
|
+
property({ type: Boolean })
|
|
341
|
+
], NrDropdownElement.prototype, "arrow", void 0);
|
|
342
|
+
__decorate([
|
|
343
|
+
property({ type: Boolean, attribute: 'auto-close' })
|
|
344
|
+
], NrDropdownElement.prototype, "autoClose", void 0);
|
|
345
|
+
__decorate([
|
|
346
|
+
property({ type: Boolean, attribute: 'close-on-outside-click' })
|
|
347
|
+
], NrDropdownElement.prototype, "closeOnOutsideClick", void 0);
|
|
348
|
+
__decorate([
|
|
349
|
+
property({ type: Boolean, attribute: 'close-on-escape' })
|
|
350
|
+
], NrDropdownElement.prototype, "closeOnEscape", void 0);
|
|
351
|
+
__decorate([
|
|
352
|
+
property({ type: Number })
|
|
353
|
+
], NrDropdownElement.prototype, "offset", void 0);
|
|
354
|
+
__decorate([
|
|
355
|
+
property({ type: Number })
|
|
356
|
+
], NrDropdownElement.prototype, "delay", void 0);
|
|
357
|
+
__decorate([
|
|
358
|
+
property({ type: String, attribute: 'max-height' })
|
|
359
|
+
], NrDropdownElement.prototype, "maxHeight", void 0);
|
|
360
|
+
__decorate([
|
|
361
|
+
property({ type: String, attribute: 'min-width' })
|
|
362
|
+
], NrDropdownElement.prototype, "minWidth", void 0);
|
|
363
|
+
__decorate([
|
|
364
|
+
property({ type: String, attribute: 'cascade-direction' })
|
|
365
|
+
], NrDropdownElement.prototype, "cascadeDirection", void 0);
|
|
366
|
+
__decorate([
|
|
367
|
+
property({ type: Number, attribute: 'cascade-delay' })
|
|
368
|
+
], NrDropdownElement.prototype, "cascadeDelay", void 0);
|
|
369
|
+
__decorate([
|
|
370
|
+
property({ type: Boolean, attribute: 'cascade-on-hover' })
|
|
371
|
+
], NrDropdownElement.prototype, "cascadeOnHover", void 0);
|
|
372
|
+
NrDropdownElement = __decorate([
|
|
373
|
+
customElement('nr-dropdown')
|
|
374
|
+
], NrDropdownElement);
|
|
375
|
+
export { NrDropdownElement };
|
|
376
|
+
//# sourceMappingURL=dropdown.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dropdown.component.js","sourceRoot":"","sources":["../../../src/components/dropdown/dropdown.component.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2023 Nuraly, Laabidi Aymen\n * SPDX-License-Identifier: MIT\n */\n\nimport { html, LitElement, nothing } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { styles } from './dropdown.style';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { styleMap } from 'lit/directives/style-map.js';\nimport { NuralyUIBaseMixin } from '../../shared/base-mixin.js';\nimport { NrDropdownController } from './controllers/dropdown.controller.js';\nimport '../icon/index.js';\n\nimport {\n DropdownPlacement,\n DropdownTrigger,\n DropdownSize,\n DropdownAnimation,\n DropdownItem\n} from './dropdown.types.js';\n\n/**\n * # Dropdown Component\n * \n * A versatile dropdown component that provides floating panel functionality with customizable triggers,\n * content, and positioning. Supports both predefined item lists and custom slot content with\n * cascading submenus and interactive elements.\n * \n * ## Features\n * - Multiple trigger modes (hover, click, focus, manual)\n * - Flexible positioning with auto-placement\n * - Cascading submenus with custom content support\n * - Interactive elements (forms, buttons) within dropdowns\n * - Keyboard navigation and accessibility\n * - Customizable animations and styling\n * - Event delegation and outside click detection\n * \n * ## Usage\n * ```html\n * <!-- Basic dropdown with slot content -->\n * <nr-dropdown trigger=\"hover\">\n * <button slot=\"trigger\">Menu</button>\n * <div slot=\"content\">\n * <p>Custom content here</p>\n * </div>\n * </nr-dropdown>\n * \n * <!-- Dropdown with predefined items -->\n * <nr-dropdown \n * .items=\"${items}\" \n * placement=\"bottom-start\"\n * trigger=\"click\">\n * <button slot=\"trigger\">Menu</button>\n * </nr-dropdown>\n * \n * <!-- Hover dropdown with custom positioning -->\n * <nr-dropdown \n * trigger=\"hover\" \n * placement=\"top\"\n * size=\"large\">\n * <span slot=\"trigger\">Hover me</span>\n * <div slot=\"content\">Tooltip content</div>\n * </nr-dropdown>\n * ```\n * \n * @element nr-dropdown\n * @fires nr-dropdown-open - Fired when dropdown opens\n * @fires nr-dropdown-close - Fired when dropdown closes\n * @fires nr-dropdown-item-click - Fired when dropdown item is clicked\n * \n * @slot trigger - Element that triggers the dropdown\n * @slot content - Custom content for the dropdown panel\n * @slot header - Optional header content\n * @slot footer - Optional footer content\n * \n * @cssproperty --dropdown-background - Background color of dropdown panel\n * @cssproperty --dropdown-border - Border of dropdown panel\n * @cssproperty --dropdown-shadow - Shadow of dropdown panel\n * @cssproperty --dropdown-border-radius - Border radius of dropdown panel\n * @cssproperty --dropdown-max-width - Maximum width of dropdown panel\n * @cssproperty --dropdown-min-width - Minimum width of dropdown panel\n * @cssproperty --dropdown-max-height - Maximum height of dropdown panel\n */\n@customElement('nr-dropdown')\nexport class NrDropdownElement extends NuralyUIBaseMixin(LitElement) {\n static override styles = styles;\n\n override requiredComponents = ['nr-icon'];\n\n @property({ type: Array }) items: DropdownItem[] = [];\n @property({ type: Boolean, reflect: true }) open = false;\n @property({ type: String }) placement: DropdownPlacement = DropdownPlacement.Bottom;\n @property({ type: String }) trigger: DropdownTrigger = DropdownTrigger.Hover;\n @property({ type: String }) size: DropdownSize = DropdownSize.Medium;\n @property({ type: String }) animation: DropdownAnimation = DropdownAnimation.Fade;\n @property({ type: Boolean }) disabled = false;\n @property({ type: Boolean }) arrow = false;\n @property({ type: Boolean, attribute: 'auto-close' }) autoClose = false;\n @property({ type: Boolean, attribute: 'close-on-outside-click' }) closeOnOutsideClick = true;\n @property({ type: Boolean, attribute: 'close-on-escape' }) closeOnEscape = true;\n @property({ type: Number }) offset = 4;\n @property({ type: Number }) delay = 50;\n @property({ type: String, attribute: 'max-height' }) maxHeight = '300px';\n @property({ type: String, attribute: 'min-width' }) minWidth = 'auto';\n @property({ type: String, attribute: 'cascade-direction' }) cascadeDirection: 'right' | 'left' | 'auto' = 'auto';\n @property({ type: Number, attribute: 'cascade-delay' }) cascadeDelay = 50;\n @property({ type: Boolean, attribute: 'cascade-on-hover' }) cascadeOnHover = true;\n\n private dropdownController = new NrDropdownController(this);\n private openSubmenus = new Set<string>();\n private submenuTimers = new Map<string, number>();\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.updateCascadingAttribute();\n }\n\n override updated(changedProperties: Map<string, any>): void {\n super.updated(changedProperties);\n if (changedProperties.has('items')) {\n this.updateCascadingAttribute();\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n }\n\n override firstUpdated(): void {\n }\n\n private updateCascadingAttribute(): void {\n const hasCascading = this.items.some(item => \n (item.options && item.options.length > 0) || !!item.customContent\n );\n if (hasCascading) {\n this.setAttribute('has-cascading', '');\n } else {\n this.removeAttribute('has-cascading');\n }\n }\n\n private handleDropdownPanelClick = (e: Event): void => {\n e.stopPropagation();\n };\n\n private handleItemClick = (item: DropdownItem): void => {\n if (item.disabled) return;\n\n if ((item.options && item.options.length > 0) || item.customContent) {\n this.toggleSubmenu(item.id);\n return;\n }\n\n this.dropdownController.handleItemClick(item);\n };\n\n private handleItemHover = (item: DropdownItem): void => {\n if (!item.options?.length && !item.customContent) return;\n\n this.clearSubmenuTimer(item.id);\n\n if (this.cascadeOnHover) {\n const timer = window.setTimeout(() => {\n this.showSubmenu(item.id);\n }, this.cascadeDelay);\n this.submenuTimers.set(item.id, timer);\n }\n };\n\n private handleItemLeave = (item: DropdownItem): void => {\n if (!item.options?.length && !item.customContent) return;\n\n this.clearSubmenuTimer(item.id);\n\n const timer = window.setTimeout(() => {\n this.hideSubmenu(item.id);\n }, 100);\n this.submenuTimers.set(`hide-${item.id}`, timer);\n };\n\n private handleSubmenuEnter = (itemId: string): void => {\n this.clearSubmenuTimer(`hide-${itemId}`);\n };\n\n private handleSubmenuLeave = (itemId: string): void => {\n const timer = window.setTimeout(() => {\n this.hideSubmenu(itemId);\n }, 100);\n this.submenuTimers.set(`hide-${itemId}`, timer);\n };\n\n private clearSubmenuTimer(key: string): void {\n const timer = this.submenuTimers.get(key);\n if (timer) {\n clearTimeout(timer);\n this.submenuTimers.delete(key);\n }\n }\n\n private toggleSubmenu(itemId: string): void {\n if (this.openSubmenus.has(itemId)) {\n this.hideSubmenu(itemId);\n } else {\n this.showSubmenu(itemId);\n }\n }\n\n private showSubmenu(itemId: string): void {\n this.openSubmenus.add(itemId);\n this.requestUpdate();\n }\n\n private hideSubmenu(itemId: string): void {\n this.openSubmenus.delete(itemId);\n this.requestUpdate();\n }\n\n show(): void {\n this.dropdownController.open();\n }\n\n hide(): void {\n this.dropdownController.close();\n }\n\n toggle(): void {\n this.dropdownController.toggle();\n }\n\n private renderItems(): unknown {\n if (!this.items.length) return nothing;\n\n return html`\n <div class=\"dropdown__items\">\n ${this.items.map(item => {\n if (item.divider) {\n return html`<div class=\"dropdown__divider\"></div>`;\n }\n\n const hasSubmenu = !!(item.options && item.options.length > 0) || !!item.customContent;\n const isSubmenuOpen = hasSubmenu && this.openSubmenus.has(item.id);\n\n return html`\n <div class=\"dropdown__item-container ${classMap({\n 'dropdown__item-container--has-submenu': hasSubmenu\n })}\">\n <button\n class=\"dropdown__item ${classMap({\n 'dropdown__item--disabled': !!item.disabled,\n 'dropdown__item--has-submenu': hasSubmenu\n })}\"\n ?disabled=\"${item.disabled}\"\n @click=\"${() => this.handleItemClick(item)}\"\n @mouseenter=\"${() => hasSubmenu && this.handleItemHover(item)}\"\n @mouseleave=\"${() => hasSubmenu && this.handleItemLeave(item)}\"\n >\n ${item.icon ? html`<nr-icon name=\"${item.icon}\" class=\"dropdown__item-icon\"></nr-icon>` : nothing}\n <span class=\"dropdown__item-label\">${item.label}</span>\n ${hasSubmenu ? html`<nr-icon name=\"chevron-right\" class=\"dropdown__submenu-arrow\"></nr-icon>` : nothing}\n </button>\n \n ${hasSubmenu && isSubmenuOpen ? html`\n <div class=\"dropdown__submenu ${classMap({\n 'dropdown__submenu--right': this.cascadeDirection === 'right' || this.cascadeDirection === 'auto',\n 'dropdown__submenu--left': this.cascadeDirection === 'left'\n })}\"\n @mouseenter=\"${() => this.handleSubmenuEnter(item.id)}\"\n @mouseleave=\"${() => this.handleSubmenuLeave(item.id)}\">\n ${item.customContent ? html`\n <div class=\"dropdown__custom-content\">\n ${typeof item.customContent === 'string' \n ? html`<div .innerHTML=\"${item.customContent}\"></div>`\n : item.customContent\n }\n </div>\n ` : html`\n <div class=\"dropdown__items\">\n ${item.options!.map(subItem => {\n if (subItem.divider) {\n return html`<div class=\"dropdown__divider\"></div>`;\n }\n \n return html`\n <button\n class=\"dropdown__item ${classMap({\n 'dropdown__item--disabled': !!subItem.disabled\n })}\"\n ?disabled=\"${subItem.disabled}\"\n @click=\"${() => this.handleItemClick(subItem)}\"\n >\n ${subItem.icon ? html`<nr-icon name=\"${subItem.icon}\" class=\"dropdown__item-icon\"></nr-icon>` : nothing}\n <span class=\"dropdown__item-label\">${subItem.label}</span>\n </button>\n `;\n })}\n </div>\n `}\n </div>\n ` : nothing}\n </div>\n `;\n })}\n </div>\n `;\n }\n\n override render() {\n const panelClasses = {\n 'dropdown__panel': true,\n 'dropdown__panel--open': this.open,\n [`dropdown__panel--${this.size}`]: true,\n [`dropdown__panel--${this.animation}`]: true,\n [`dropdown__panel--${this.placement}`]: true,\n 'dropdown__panel--with-arrow': this.arrow\n };\n\n const panelStyles = {\n maxHeight: this.maxHeight,\n minWidth: this.minWidth\n };\n\n return html`\n <div class=\"dropdown\">\n <div class=\"dropdown__trigger\">\n <slot name=\"trigger\"></slot>\n </div>\n \n <div \n class=\"${classMap(panelClasses)}\"\n style=\"${styleMap(panelStyles)}\"\n @click=\"${this.handleDropdownPanelClick}\"\n >\n ${this.arrow ? html`<div class=\"dropdown__arrow\"></div>` : nothing}\n \n <slot name=\"header\"></slot>\n \n <div class=\"dropdown__content\">\n <slot name=\"content\">${this.renderItems()}</slot>\n </div>\n \n <slot name=\"footer\"></slot>\n </div>\n </div>\n `;\n }\n}"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export declare const styles: import("lit").CSSResult;
|
|
2
|
-
//# sourceMappingURL=
|
|
2
|
+
//# sourceMappingURL=dropdown.style.d.ts.map
|