ng-primitives 0.44.0 → 0.45.1
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/combobox/combobox/combobox-state.d.ts +3 -2
- package/combobox/combobox/combobox.d.ts +9 -3
- package/combobox/combobox-button/combobox-button.d.ts +3 -2
- package/combobox/combobox-dropdown/combobox-dropdown.d.ts +52 -2
- package/combobox/combobox-input/combobox-input.d.ts +3 -2
- package/combobox/combobox-option/combobox-option.d.ts +3 -2
- package/combobox/combobox-portal/combobox-portal.d.ts +10 -21
- package/example-theme/index.css +1 -0
- package/fesm2022/ng-primitives-combobox.mjs +66 -87
- package/fesm2022/ng-primitives-combobox.mjs.map +1 -1
- package/fesm2022/ng-primitives-focus-trap.mjs +9 -1
- package/fesm2022/ng-primitives-focus-trap.mjs.map +1 -1
- package/fesm2022/ng-primitives-listbox.mjs +1 -1
- package/fesm2022/ng-primitives-listbox.mjs.map +1 -1
- package/fesm2022/ng-primitives-menu.mjs +382 -63
- package/fesm2022/ng-primitives-menu.mjs.map +1 -1
- package/fesm2022/ng-primitives-popover.mjs +66 -331
- package/fesm2022/ng-primitives-popover.mjs.map +1 -1
- package/fesm2022/ng-primitives-portal.mjs +360 -2
- package/fesm2022/ng-primitives-portal.mjs.map +1 -1
- package/fesm2022/ng-primitives-tooltip.mjs +56 -176
- package/fesm2022/ng-primitives-tooltip.mjs.map +1 -1
- package/focus-trap/focus-trap/focus-trap-state.d.ts +1 -0
- package/focus-trap/focus-trap/focus-trap.d.ts +5 -0
- package/menu/config/menu-config.d.ts +42 -0
- package/menu/index.d.ts +5 -1
- package/menu/menu/menu.d.ts +6 -2
- package/menu/menu-trigger/menu-trigger-state.d.ts +38 -0
- package/menu/menu-trigger/menu-trigger.d.ts +91 -13
- package/menu/submenu-trigger/submenu-trigger-state.d.ts +58 -0
- package/menu/submenu-trigger/submenu-trigger.d.ts +66 -10
- package/package.json +12 -12
- package/popover/index.d.ts +1 -2
- package/popover/popover/popover.d.ts +2 -43
- package/popover/popover-trigger/popover-trigger.d.ts +16 -106
- package/portal/index.d.ts +2 -0
- package/portal/overlay-token.d.ts +12 -0
- package/portal/overlay.d.ts +172 -0
- package/schematics/ng-generate/templates/combobox/combobox.__fileSuffix@dasherize__.ts.template +31 -0
- package/tooltip/index.d.ts +1 -1
- package/tooltip/tooltip/tooltip.d.ts +3 -25
- package/tooltip/tooltip-trigger/tooltip-trigger.d.ts +16 -63
- package/popover/popover/popover-token.d.ts +0 -10
- package/popover/utils/transform-origin.d.ts +0 -2
- package/tooltip/tooltip/tooltip-token.d.ts +0 -10
|
@@ -1,15 +1,47 @@
|
|
|
1
|
+
import { createOverlay, injectOverlay } from 'ng-primitives/portal';
|
|
2
|
+
export { injectOverlayContext as injectMenuContext } from 'ng-primitives/portal';
|
|
1
3
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, inject, HostListener, Directive
|
|
3
|
-
import * as i1
|
|
4
|
+
import { InjectionToken, inject, Injector, ViewContainerRef, input, booleanAttribute, numberAttribute, signal, computed, HostListener, Directive } from '@angular/core';
|
|
5
|
+
import * as i1 from 'ng-primitives/button';
|
|
4
6
|
import { NgpButton } from 'ng-primitives/button';
|
|
5
|
-
import { injectElementRef } from 'ng-primitives/internal';
|
|
7
|
+
import { injectElementRef, provideExitAnimationManager } from 'ng-primitives/internal';
|
|
6
8
|
import * as i2 from 'ng-primitives/roving-focus';
|
|
7
9
|
import { NgpRovingFocusItem, provideRovingFocusGroup, NgpRovingFocusGroup } from 'ng-primitives/roving-focus';
|
|
8
10
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
+
import { createStateToken, createStateProvider, createStateInjector, createState } from 'ng-primitives/state';
|
|
12
|
+
import * as i1$1 from 'ng-primitives/popover';
|
|
13
|
+
import { NgpPopover } from 'ng-primitives/popover';
|
|
11
14
|
import { Subject } from 'rxjs';
|
|
12
15
|
|
|
16
|
+
const defaultMenuConfig = {
|
|
17
|
+
offset: 4,
|
|
18
|
+
placement: 'bottom-start',
|
|
19
|
+
flip: true,
|
|
20
|
+
container: null,
|
|
21
|
+
scrollBehavior: 'block',
|
|
22
|
+
};
|
|
23
|
+
const NgpMenuConfigToken = new InjectionToken('NgpMenuConfigToken');
|
|
24
|
+
/**
|
|
25
|
+
* Provide the default Menu configuration
|
|
26
|
+
* @param config The Menu configuration
|
|
27
|
+
* @returns The provider
|
|
28
|
+
*/
|
|
29
|
+
function provideMenuConfig(config) {
|
|
30
|
+
return [
|
|
31
|
+
{
|
|
32
|
+
provide: NgpMenuConfigToken,
|
|
33
|
+
useValue: { ...defaultMenuConfig, ...config },
|
|
34
|
+
},
|
|
35
|
+
];
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Inject the Menu configuration
|
|
39
|
+
* @returns The global Menu configuration
|
|
40
|
+
*/
|
|
41
|
+
function injectMenuConfig() {
|
|
42
|
+
return inject(NgpMenuConfigToken, { optional: true }) ?? defaultMenuConfig;
|
|
43
|
+
}
|
|
44
|
+
|
|
13
45
|
const NgpMenuToken = new InjectionToken('NgpMenuToken');
|
|
14
46
|
/**
|
|
15
47
|
* Inject the Menu directive instance
|
|
@@ -24,41 +56,185 @@ function provideMenu(type) {
|
|
|
24
56
|
return { provide: NgpMenuToken, useExisting: type };
|
|
25
57
|
}
|
|
26
58
|
|
|
59
|
+
/**
|
|
60
|
+
* The state token for the MenuTrigger primitive.
|
|
61
|
+
*/
|
|
62
|
+
const NgpMenuTriggerStateToken = createStateToken('MenuTrigger');
|
|
63
|
+
/**
|
|
64
|
+
* Provides the MenuTrigger state.
|
|
65
|
+
*/
|
|
66
|
+
const provideMenuTriggerState = createStateProvider(NgpMenuTriggerStateToken);
|
|
67
|
+
/**
|
|
68
|
+
* Injects the MenuTrigger state.
|
|
69
|
+
*/
|
|
70
|
+
const injectMenuTriggerState = createStateInjector(NgpMenuTriggerStateToken);
|
|
71
|
+
/**
|
|
72
|
+
* The MenuTrigger state registration function.
|
|
73
|
+
*/
|
|
74
|
+
const menuTriggerState = createState(NgpMenuTriggerStateToken);
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* The state token for the SubmenuTrigger primitive.
|
|
78
|
+
*/
|
|
79
|
+
const NgpSubmenuTriggerStateToken = createStateToken('SubmenuTrigger');
|
|
80
|
+
/**
|
|
81
|
+
* Provides the SubmenuTrigger state.
|
|
82
|
+
*/
|
|
83
|
+
const provideSubmenuTriggerState = createStateProvider(NgpSubmenuTriggerStateToken);
|
|
84
|
+
/**
|
|
85
|
+
* Injects the SubmenuTrigger state.
|
|
86
|
+
*/
|
|
87
|
+
const injectSubmenuTriggerState = createStateInjector(NgpSubmenuTriggerStateToken);
|
|
88
|
+
/**
|
|
89
|
+
* The SubmenuTrigger state registration function.
|
|
90
|
+
*/
|
|
91
|
+
const submenuTriggerState = createState(NgpSubmenuTriggerStateToken);
|
|
92
|
+
|
|
27
93
|
class NgpSubmenuTrigger {
|
|
28
94
|
constructor() {
|
|
29
|
-
/**
|
|
95
|
+
/**
|
|
96
|
+
* Access the menu trigger element.
|
|
97
|
+
*/
|
|
30
98
|
this.trigger = injectElementRef();
|
|
31
|
-
/**
|
|
32
|
-
|
|
99
|
+
/**
|
|
100
|
+
* Access the injector.
|
|
101
|
+
*/
|
|
102
|
+
this.injector = inject(Injector);
|
|
103
|
+
/**
|
|
104
|
+
* Access the view container reference.
|
|
105
|
+
*/
|
|
106
|
+
this.viewContainerRef = inject(ViewContainerRef);
|
|
107
|
+
/** Access the menu trigger state */
|
|
108
|
+
this.menuTrigger = injectMenuTriggerState();
|
|
33
109
|
/** Access the parent menu */
|
|
34
110
|
this.parentMenu = inject(NgpMenuToken, { optional: true });
|
|
35
|
-
|
|
111
|
+
/**
|
|
112
|
+
* Access the submenu template ref.
|
|
113
|
+
*/
|
|
114
|
+
this.menu = input(undefined, {
|
|
115
|
+
alias: 'ngpSubmenuTrigger',
|
|
116
|
+
});
|
|
117
|
+
/**
|
|
118
|
+
* Define if the trigger should be disabled.
|
|
119
|
+
* @default false
|
|
120
|
+
*/
|
|
121
|
+
this.disabled = input(false, {
|
|
122
|
+
alias: 'ngpMenuTriggerDisabled',
|
|
123
|
+
transform: booleanAttribute,
|
|
124
|
+
});
|
|
125
|
+
/**
|
|
126
|
+
* Define the placement of the menu relative to the trigger.
|
|
127
|
+
* @default 'right-start'
|
|
128
|
+
*/
|
|
129
|
+
this.placement = input('right-start', {
|
|
130
|
+
alias: 'ngpMenuTriggerPlacement',
|
|
131
|
+
});
|
|
132
|
+
/**
|
|
133
|
+
* Define the offset of the menu relative to the trigger.
|
|
134
|
+
* @default 0
|
|
135
|
+
*/
|
|
136
|
+
this.offset = input(0, {
|
|
137
|
+
alias: 'ngpMenuTriggerOffset',
|
|
138
|
+
transform: numberAttribute,
|
|
139
|
+
});
|
|
140
|
+
/**
|
|
141
|
+
* Define whether the menu should flip when there is not enough space for the menu.
|
|
142
|
+
* @default true
|
|
143
|
+
*/
|
|
144
|
+
this.flip = input(true, {
|
|
145
|
+
alias: 'ngpMenuTriggerFlip',
|
|
146
|
+
transform: booleanAttribute,
|
|
147
|
+
});
|
|
148
|
+
/**
|
|
149
|
+
* The overlay that manages the menu
|
|
150
|
+
* @internal
|
|
151
|
+
*/
|
|
152
|
+
this.overlay = signal(null);
|
|
153
|
+
/**
|
|
154
|
+
* The open state of the menu.
|
|
155
|
+
* @internal
|
|
156
|
+
*/
|
|
157
|
+
this.open = computed(() => this.overlay()?.isOpen() ?? false);
|
|
158
|
+
/**
|
|
159
|
+
* Access the menu trigger state.
|
|
160
|
+
*/
|
|
161
|
+
this.state = submenuTriggerState(this);
|
|
162
|
+
// by default the menu opens below and to the center of the trigger,
|
|
36
163
|
// but as this is a submenu we want to default to opening to the right
|
|
37
164
|
// and to the start
|
|
38
|
-
this.
|
|
165
|
+
this.menuTrigger().placement.set('right-start');
|
|
39
166
|
this.parentMenu?.closeSubmenus.pipe(takeUntilDestroyed()).subscribe(element => {
|
|
40
167
|
// if the element is not the trigger, we want to close the menu
|
|
41
168
|
if (element === this.trigger.nativeElement) {
|
|
42
169
|
return;
|
|
43
170
|
}
|
|
44
|
-
this.
|
|
171
|
+
this.hide('mouse');
|
|
45
172
|
});
|
|
46
173
|
}
|
|
174
|
+
toggle(event) {
|
|
175
|
+
// if the trigger is disabled then do not toggle the menu
|
|
176
|
+
if (this.state.disabled()) {
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
// determine the origin of the event, 0 is keyboard, 1 is mouse
|
|
180
|
+
const origin = event.detail === 0 ? 'keyboard' : 'mouse';
|
|
181
|
+
// if the menu is open then hide it
|
|
182
|
+
if (this.open()) {
|
|
183
|
+
this.hide(origin);
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
this.show();
|
|
187
|
+
}
|
|
188
|
+
}
|
|
47
189
|
/**
|
|
48
|
-
*
|
|
190
|
+
* Show the menu.
|
|
49
191
|
*/
|
|
50
|
-
|
|
51
|
-
//
|
|
52
|
-
if (this.
|
|
192
|
+
show() {
|
|
193
|
+
// If the trigger is disabled, don't show the menu
|
|
194
|
+
if (this.state.disabled()) {
|
|
53
195
|
return;
|
|
54
196
|
}
|
|
55
|
-
|
|
197
|
+
// Create the overlay if it doesn't exist yet
|
|
198
|
+
if (!this.overlay()) {
|
|
199
|
+
this.createOverlay();
|
|
200
|
+
}
|
|
201
|
+
// Show the overlay
|
|
202
|
+
this.overlay()?.show();
|
|
56
203
|
}
|
|
57
204
|
/**
|
|
58
205
|
* @internal
|
|
206
|
+
* Hide the menu.
|
|
207
|
+
*/
|
|
208
|
+
hide(origin = 'program') {
|
|
209
|
+
// If the trigger is disabled or the menu is not open, do nothing
|
|
210
|
+
if (this.state.disabled() || !this.open()) {
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
// Hide the overlay
|
|
214
|
+
this.overlay()?.hide({ origin });
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Create the overlay that will contain the menu
|
|
59
218
|
*/
|
|
60
|
-
|
|
61
|
-
this.
|
|
219
|
+
createOverlay() {
|
|
220
|
+
const menu = this.state.menu();
|
|
221
|
+
if (!menu) {
|
|
222
|
+
throw new Error('Menu must be either a TemplateRef or a ComponentType');
|
|
223
|
+
}
|
|
224
|
+
// Create config for the overlay
|
|
225
|
+
const config = {
|
|
226
|
+
content: menu,
|
|
227
|
+
triggerElement: this.trigger.nativeElement,
|
|
228
|
+
injector: this.injector,
|
|
229
|
+
placement: this.state.placement(),
|
|
230
|
+
offset: this.state.offset(),
|
|
231
|
+
flip: this.state.flip(),
|
|
232
|
+
closeOnOutsideClick: true,
|
|
233
|
+
closeOnEscape: true,
|
|
234
|
+
restoreFocus: true,
|
|
235
|
+
viewContainerRef: this.viewContainerRef,
|
|
236
|
+
};
|
|
237
|
+
this.overlay.set(createOverlay(config));
|
|
62
238
|
}
|
|
63
239
|
/**
|
|
64
240
|
* If the user presses the right arrow key, we want to open the submenu
|
|
@@ -73,28 +249,29 @@ class NgpSubmenuTrigger {
|
|
|
73
249
|
const isLeftArrow = event.key === 'ArrowLeft';
|
|
74
250
|
if ((isRightArrow && !isRtl) || (isLeftArrow && isRtl)) {
|
|
75
251
|
event.preventDefault();
|
|
76
|
-
this.
|
|
252
|
+
this.show();
|
|
77
253
|
}
|
|
78
254
|
}
|
|
79
255
|
/**
|
|
80
256
|
* If the user hovers over the trigger, we want to open the submenu
|
|
81
257
|
*/
|
|
82
258
|
showSubmenuOnHover() {
|
|
83
|
-
this.
|
|
259
|
+
this.show();
|
|
84
260
|
}
|
|
85
261
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: NgpSubmenuTrigger, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
86
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "
|
|
262
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.11", type: NgpSubmenuTrigger, isStandalone: true, selector: "[ngpSubmenuTrigger]", inputs: { menu: { classPropertyName: "menu", publicName: "ngpSubmenuTrigger", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "ngpMenuTriggerDisabled", isSignal: true, isRequired: false, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "ngpMenuTriggerPlacement", isSignal: true, isRequired: false, transformFunction: null }, offset: { classPropertyName: "offset", publicName: "ngpMenuTriggerOffset", isSignal: true, isRequired: false, transformFunction: null }, flip: { classPropertyName: "flip", publicName: "ngpMenuTriggerFlip", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "aria-haspopup": "true" }, listeners: { "click": "toggle($event)", "keydown.ArrowRight": "showSubmenuOnArrow($event)", "keydown.ArrowLeft": "showSubmenuOnArrow($event)", "mouseenter": "showSubmenuOnHover()" }, properties: { "attr.aria-expanded": "open() ? \"true\" : \"false\"", "attr.data-open": "open() ? \"\" : null" } }, providers: [provideSubmenuTriggerState({ inherit: false }), provideExitAnimationManager()], exportAs: ["ngpSubmenuTrigger"], ngImport: i0 }); }
|
|
87
263
|
}
|
|
88
264
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: NgpSubmenuTrigger, decorators: [{
|
|
89
265
|
type: Directive,
|
|
90
266
|
args: [{
|
|
91
267
|
selector: '[ngpSubmenuTrigger]',
|
|
92
268
|
exportAs: 'ngpSubmenuTrigger',
|
|
93
|
-
|
|
94
|
-
{ directive: NgpPopoverTrigger, inputs: ['ngpPopoverTrigger:ngpSubmenuTrigger'] },
|
|
95
|
-
],
|
|
269
|
+
providers: [provideSubmenuTriggerState({ inherit: false }), provideExitAnimationManager()],
|
|
96
270
|
host: {
|
|
97
271
|
'aria-haspopup': 'true',
|
|
272
|
+
'[attr.aria-expanded]': 'open() ? "true" : "false"',
|
|
273
|
+
'[attr.data-open]': 'open() ? "" : null',
|
|
274
|
+
'(click)': 'toggle($event)',
|
|
98
275
|
},
|
|
99
276
|
}]
|
|
100
277
|
}], ctorParameters: () => [], propDecorators: { showSubmenuOnArrow: [{
|
|
@@ -147,7 +324,7 @@ class NgpMenuItem {
|
|
|
147
324
|
if ((isLeftArrow && !isRtl) || (isRightArrow && isRtl)) {
|
|
148
325
|
event.preventDefault();
|
|
149
326
|
if (trigger) {
|
|
150
|
-
trigger.
|
|
327
|
+
trigger.hide('keyboard');
|
|
151
328
|
}
|
|
152
329
|
}
|
|
153
330
|
}
|
|
@@ -158,7 +335,7 @@ class NgpMenuItem {
|
|
|
158
335
|
this.parentMenu?.closeSubmenus.next(this.elementRef.nativeElement);
|
|
159
336
|
}
|
|
160
337
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: NgpMenuItem, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
161
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.11", type: NgpMenuItem, isStandalone: true, selector: "[ngpMenuItem]", host: { attributes: { "role": "menuitem" }, listeners: { "click": "onClick($event)", "keydown.ArrowLeft": "handleArrowKey($event)", "keydown.ArrowRight": "handleArrowKey($event)", "mouseenter": "showSubmenuOnHover()" } }, exportAs: ["ngpMenuItem"], hostDirectives: [{ directive: i1
|
|
338
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.11", type: NgpMenuItem, isStandalone: true, selector: "[ngpMenuItem]", host: { attributes: { "role": "menuitem" }, listeners: { "click": "onClick($event)", "keydown.ArrowLeft": "handleArrowKey($event)", "keydown.ArrowRight": "handleArrowKey($event)", "mouseenter": "showSubmenuOnHover()" } }, exportAs: ["ngpMenuItem"], hostDirectives: [{ directive: i1.NgpButton, inputs: ["disabled", "ngpMenuItemDisabled"] }, { directive: i2.NgpRovingFocusItem }], ngImport: i0 }); }
|
|
162
339
|
}
|
|
163
340
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: NgpMenuItem, decorators: [{
|
|
164
341
|
type: Directive,
|
|
@@ -186,60 +363,195 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImpo
|
|
|
186
363
|
*/
|
|
187
364
|
class NgpMenuTrigger {
|
|
188
365
|
constructor() {
|
|
189
|
-
/**
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
this.
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
366
|
+
/**
|
|
367
|
+
* Access the trigger element
|
|
368
|
+
*/
|
|
369
|
+
this.trigger = injectElementRef();
|
|
370
|
+
/**
|
|
371
|
+
* Access the injector.
|
|
372
|
+
*/
|
|
373
|
+
this.injector = inject(Injector);
|
|
374
|
+
/**
|
|
375
|
+
* Access the view container reference.
|
|
376
|
+
*/
|
|
377
|
+
this.viewContainerRef = inject(ViewContainerRef);
|
|
378
|
+
/**
|
|
379
|
+
* Access the global menu configuration.
|
|
380
|
+
*/
|
|
381
|
+
this.config = injectMenuConfig();
|
|
382
|
+
/**
|
|
383
|
+
* Access the menu template ref.
|
|
384
|
+
*/
|
|
385
|
+
this.menu = input(undefined, {
|
|
386
|
+
alias: 'ngpMenuTrigger',
|
|
387
|
+
});
|
|
388
|
+
/**
|
|
389
|
+
* Define if the trigger should be disabled.
|
|
390
|
+
* @default false
|
|
391
|
+
*/
|
|
392
|
+
this.disabled = input(false, {
|
|
393
|
+
alias: 'ngpMenuTriggerDisabled',
|
|
394
|
+
transform: booleanAttribute,
|
|
395
|
+
});
|
|
396
|
+
/**
|
|
397
|
+
* Define the placement of the menu relative to the trigger.
|
|
398
|
+
* @default 'bottom-start'
|
|
399
|
+
*/
|
|
400
|
+
this.placement = input(this.config.placement, {
|
|
401
|
+
alias: 'ngpMenuTriggerPlacement',
|
|
402
|
+
});
|
|
403
|
+
/**
|
|
404
|
+
* Define the offset of the menu relative to the trigger.
|
|
405
|
+
* @default 0
|
|
406
|
+
*/
|
|
407
|
+
this.offset = input(this.config.offset, {
|
|
408
|
+
alias: 'ngpMenuTriggerOffset',
|
|
409
|
+
transform: numberAttribute,
|
|
410
|
+
});
|
|
411
|
+
/**
|
|
412
|
+
* Define whether the menu should flip when there is not enough space for the menu.
|
|
413
|
+
* @default true
|
|
414
|
+
*/
|
|
415
|
+
this.flip = input(this.config.flip, {
|
|
416
|
+
alias: 'ngpMenuTriggerFlip',
|
|
417
|
+
transform: booleanAttribute,
|
|
418
|
+
});
|
|
419
|
+
/**
|
|
420
|
+
* Define the container in which the menu should be attached.
|
|
421
|
+
* @default document.body
|
|
422
|
+
*/
|
|
423
|
+
this.container = input(this.config.container, {
|
|
424
|
+
alias: 'ngpMenuTriggerContainer',
|
|
425
|
+
});
|
|
426
|
+
/**
|
|
427
|
+
* Defines how the menu behaves when the window is scrolled.
|
|
428
|
+
* @default 'block'
|
|
429
|
+
*/
|
|
430
|
+
this.scrollBehavior = input(this.config.scrollBehavior, {
|
|
431
|
+
alias: 'ngpMenuTriggerScrollBehavior',
|
|
432
|
+
});
|
|
433
|
+
/**
|
|
434
|
+
* Provide context to the menu. This can be used to pass data to the menu content.
|
|
435
|
+
*/
|
|
436
|
+
this.context = input(undefined, {
|
|
437
|
+
alias: 'ngpMenuTriggerContext',
|
|
438
|
+
});
|
|
439
|
+
/**
|
|
440
|
+
* The overlay that manages the menu
|
|
441
|
+
* @internal
|
|
442
|
+
*/
|
|
443
|
+
this.overlay = signal(null);
|
|
444
|
+
/**
|
|
445
|
+
* The open state of the menu.
|
|
446
|
+
* @internal
|
|
447
|
+
*/
|
|
448
|
+
this.open = computed(() => this.overlay()?.isOpen() ?? false);
|
|
449
|
+
/**
|
|
450
|
+
* The menu trigger state.
|
|
451
|
+
*/
|
|
452
|
+
this.state = menuTriggerState(this);
|
|
453
|
+
}
|
|
454
|
+
ngOnDestroy() {
|
|
455
|
+
this.overlay()?.destroy();
|
|
456
|
+
}
|
|
457
|
+
toggle(event) {
|
|
458
|
+
// if the trigger is disabled then do not toggle the menu
|
|
459
|
+
if (this.state.disabled()) {
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
// determine the origin of the event, 0 is keyboard, 1 is mouse
|
|
463
|
+
const origin = event.detail === 0 ? 'keyboard' : 'mouse';
|
|
464
|
+
// if the menu is open then hide it
|
|
465
|
+
if (this.open()) {
|
|
466
|
+
this.hide(origin);
|
|
467
|
+
}
|
|
468
|
+
else {
|
|
469
|
+
this.show();
|
|
470
|
+
}
|
|
198
471
|
}
|
|
199
472
|
/**
|
|
200
|
-
*
|
|
473
|
+
* Show the menu.
|
|
201
474
|
*/
|
|
202
|
-
|
|
203
|
-
|
|
475
|
+
show() {
|
|
476
|
+
// If the trigger is disabled, don't show the menu
|
|
477
|
+
if (this.state.disabled()) {
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
480
|
+
// Create the overlay if it doesn't exist yet
|
|
481
|
+
if (!this.overlay()) {
|
|
482
|
+
this.createOverlay();
|
|
483
|
+
}
|
|
484
|
+
// Show the overlay
|
|
485
|
+
this.overlay()?.show();
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* @internal
|
|
489
|
+
* Hide the menu.
|
|
490
|
+
*/
|
|
491
|
+
hide(origin = 'program') {
|
|
492
|
+
// If the trigger is disabled or the menu is not open, do nothing
|
|
493
|
+
if (this.state.disabled() || !this.open()) {
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
// Hide the overlay
|
|
497
|
+
this.overlay()?.hide({ origin });
|
|
498
|
+
}
|
|
499
|
+
/**
|
|
500
|
+
* Create the overlay that will contain the menu
|
|
501
|
+
*/
|
|
502
|
+
createOverlay() {
|
|
503
|
+
const menu = this.state.menu();
|
|
504
|
+
if (!menu) {
|
|
505
|
+
throw new Error('Menu must be either a TemplateRef or a ComponentType');
|
|
506
|
+
}
|
|
507
|
+
// Create config for the overlay
|
|
508
|
+
const config = {
|
|
509
|
+
content: menu,
|
|
510
|
+
triggerElement: this.trigger.nativeElement,
|
|
511
|
+
viewContainerRef: this.viewContainerRef,
|
|
512
|
+
injector: this.injector,
|
|
513
|
+
context: this.state.context(),
|
|
514
|
+
container: this.state.container(),
|
|
515
|
+
placement: this.state.placement(),
|
|
516
|
+
offset: this.state.offset(),
|
|
517
|
+
flip: this.state.flip(),
|
|
518
|
+
closeOnOutsideClick: true,
|
|
519
|
+
closeOnEscape: true,
|
|
520
|
+
restoreFocus: true,
|
|
521
|
+
scrollBehaviour: this.state.scrollBehavior(),
|
|
522
|
+
};
|
|
523
|
+
this.overlay.set(createOverlay(config));
|
|
204
524
|
}
|
|
205
525
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: NgpMenuTrigger, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
206
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "
|
|
526
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.11", type: NgpMenuTrigger, isStandalone: true, selector: "[ngpMenuTrigger]", inputs: { menu: { classPropertyName: "menu", publicName: "ngpMenuTrigger", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "ngpMenuTriggerDisabled", isSignal: true, isRequired: false, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "ngpMenuTriggerPlacement", isSignal: true, isRequired: false, transformFunction: null }, offset: { classPropertyName: "offset", publicName: "ngpMenuTriggerOffset", isSignal: true, isRequired: false, transformFunction: null }, flip: { classPropertyName: "flip", publicName: "ngpMenuTriggerFlip", isSignal: true, isRequired: false, transformFunction: null }, container: { classPropertyName: "container", publicName: "ngpMenuTriggerContainer", isSignal: true, isRequired: false, transformFunction: null }, scrollBehavior: { classPropertyName: "scrollBehavior", publicName: "ngpMenuTriggerScrollBehavior", isSignal: true, isRequired: false, transformFunction: null }, context: { classPropertyName: "context", publicName: "ngpMenuTriggerContext", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "aria-haspopup": "true" }, listeners: { "click": "toggle($event)" }, properties: { "attr.aria-expanded": "open() ? \"true\" : \"false\"", "attr.data-open": "open() ? \"\" : null", "attr.data-placement": "state.placement()" } }, providers: [provideMenuTriggerState({ inherit: false }), provideExitAnimationManager()], exportAs: ["ngpMenuTrigger"], ngImport: i0 }); }
|
|
207
527
|
}
|
|
208
528
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: NgpMenuTrigger, decorators: [{
|
|
209
529
|
type: Directive,
|
|
210
530
|
args: [{
|
|
211
531
|
selector: '[ngpMenuTrigger]',
|
|
212
532
|
exportAs: 'ngpMenuTrigger',
|
|
213
|
-
|
|
214
|
-
{
|
|
215
|
-
directive: NgpPopoverTrigger,
|
|
216
|
-
inputs: [
|
|
217
|
-
'ngpPopoverTrigger:ngpMenuTrigger',
|
|
218
|
-
'ngpPopoverTriggerDisabled:ngpMenuTriggerDisabled',
|
|
219
|
-
'ngpPopoverTriggerPlacement:ngpMenuTriggerPlacement',
|
|
220
|
-
'ngpPopoverTriggerOffset:ngpMenuTriggerOffset',
|
|
221
|
-
'ngpPopoverTriggerShowDelay:ngpMenuTriggerShowDelay',
|
|
222
|
-
'ngpPopoverTriggerHideDelay:ngpMenuTriggerHideDelay',
|
|
223
|
-
'ngpPopoverTriggerFlip:ngpMenuTriggerFlip',
|
|
224
|
-
'ngpPopoverTriggerContainer:ngpMenuTriggerContainer',
|
|
225
|
-
'ngpPopoverTriggerScrollBehavior:ngpMenuTriggerScrollBehavior',
|
|
226
|
-
],
|
|
227
|
-
},
|
|
228
|
-
],
|
|
533
|
+
providers: [provideMenuTriggerState({ inherit: false }), provideExitAnimationManager()],
|
|
229
534
|
host: {
|
|
230
535
|
'aria-haspopup': 'true',
|
|
231
|
-
'
|
|
536
|
+
'[attr.aria-expanded]': 'open() ? "true" : "false"',
|
|
537
|
+
'[attr.data-open]': 'open() ? "" : null',
|
|
538
|
+
'[attr.data-placement]': 'state.placement()',
|
|
539
|
+
'(click)': 'toggle($event)',
|
|
232
540
|
},
|
|
233
541
|
}]
|
|
234
|
-
}]
|
|
542
|
+
}] });
|
|
235
543
|
|
|
236
544
|
/**
|
|
237
545
|
* The `NgpMenu` is a container for menu items.
|
|
238
546
|
*/
|
|
239
547
|
class NgpMenu {
|
|
240
548
|
constructor() {
|
|
241
|
-
/**
|
|
242
|
-
|
|
549
|
+
/**
|
|
550
|
+
* Access the overlay.
|
|
551
|
+
*/
|
|
552
|
+
this.overlay = injectOverlay();
|
|
553
|
+
/** Access the menu trigger state */
|
|
554
|
+
this.menuTrigger = injectMenuTriggerState();
|
|
243
555
|
/** Access any parent menus */
|
|
244
556
|
this.parentMenu = inject(NgpMenuToken, { optional: true, skipSelf: true });
|
|
245
557
|
/** @internal Whether we should close submenus */
|
|
@@ -247,15 +559,15 @@ class NgpMenu {
|
|
|
247
559
|
}
|
|
248
560
|
/** Close the menu and any parent menus */
|
|
249
561
|
closeAllMenus(origin) {
|
|
250
|
-
this.
|
|
562
|
+
this.menuTrigger().hide(origin);
|
|
251
563
|
this.parentMenu?.closeAllMenus(origin);
|
|
252
564
|
}
|
|
253
565
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: NgpMenu, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
254
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.11", type: NgpMenu, isStandalone: true, selector: "[ngpMenu]", providers: [
|
|
566
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.11", type: NgpMenu, isStandalone: true, selector: "[ngpMenu]", host: { attributes: { "role": "menu" }, properties: { "style.left.px": "overlay.position().x", "style.top.px": "overlay.position().y", "style.--ngp-menu-trigger-width.px": "overlay.triggerWidth()", "style.--ngp-menu-transform-origin": "overlay.transformOrigin()" } }, providers: [
|
|
255
567
|
// ensure we don't inherit the focus group from the parent menu if there is one
|
|
256
568
|
provideRovingFocusGroup(NgpRovingFocusGroup, { inherit: false }),
|
|
257
569
|
provideMenu(NgpMenu),
|
|
258
|
-
], exportAs: ["ngpMenu"], hostDirectives: [{ directive: i1.NgpPopover }, { directive: i2.NgpRovingFocusGroup }], ngImport: i0 }); }
|
|
570
|
+
], exportAs: ["ngpMenu"], hostDirectives: [{ directive: i1$1.NgpPopover }, { directive: i2.NgpRovingFocusGroup }], ngImport: i0 }); }
|
|
259
571
|
}
|
|
260
572
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: NgpMenu, decorators: [{
|
|
261
573
|
type: Directive,
|
|
@@ -268,6 +580,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImpo
|
|
|
268
580
|
provideRovingFocusGroup(NgpRovingFocusGroup, { inherit: false }),
|
|
269
581
|
provideMenu(NgpMenu),
|
|
270
582
|
],
|
|
583
|
+
host: {
|
|
584
|
+
role: 'menu',
|
|
585
|
+
'[style.left.px]': 'overlay.position().x',
|
|
586
|
+
'[style.top.px]': 'overlay.position().y',
|
|
587
|
+
'[style.--ngp-menu-trigger-width.px]': 'overlay.triggerWidth()',
|
|
588
|
+
'[style.--ngp-menu-transform-origin]': 'overlay.transformOrigin()',
|
|
589
|
+
},
|
|
271
590
|
}]
|
|
272
591
|
}] });
|
|
273
592
|
|
|
@@ -275,5 +594,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImpo
|
|
|
275
594
|
* Generated bundle index. Do not edit.
|
|
276
595
|
*/
|
|
277
596
|
|
|
278
|
-
export { NgpMenu, NgpMenuItem, NgpMenuToken, NgpMenuTrigger, NgpSubmenuTrigger, injectMenu };
|
|
597
|
+
export { NgpMenu, NgpMenuItem, NgpMenuToken, NgpMenuTrigger, NgpSubmenuTrigger, injectMenu, injectMenuTriggerState, injectSubmenuTriggerState, provideMenuConfig, provideMenuTriggerState, provideSubmenuTriggerState };
|
|
279
598
|
//# sourceMappingURL=ng-primitives-menu.mjs.map
|