ng-primitives 0.122.0 → 0.123.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/fesm2022/ng-primitives-combobox.mjs +10 -1
- package/fesm2022/ng-primitives-combobox.mjs.map +1 -1
- package/fesm2022/ng-primitives-context-menu.mjs +10 -2
- package/fesm2022/ng-primitives-context-menu.mjs.map +1 -1
- package/fesm2022/ng-primitives-date-picker.mjs +1 -1
- package/fesm2022/ng-primitives-date-picker.mjs.map +1 -1
- package/fesm2022/ng-primitives-internal.mjs +184 -3
- package/fesm2022/ng-primitives-internal.mjs.map +1 -1
- package/fesm2022/ng-primitives-menu.mjs +141 -21
- package/fesm2022/ng-primitives-menu.mjs.map +1 -1
- package/fesm2022/ng-primitives-portal.mjs +74 -12
- package/fesm2022/ng-primitives-portal.mjs.map +1 -1
- package/fesm2022/ng-primitives-select.mjs +10 -1
- package/fesm2022/ng-primitives-select.mjs.map +1 -1
- package/fesm2022/ng-primitives-tooltip.mjs +19 -118
- package/fesm2022/ng-primitives-tooltip.mjs.map +1 -1
- package/fesm2022/ng-primitives-utils.mjs +40 -23
- package/fesm2022/ng-primitives-utils.mjs.map +1 -1
- package/package.json +1 -1
- package/schematics/ng-generate/templates/toggle-group/toggle-group.__fileSuffix@dasherize__.ts.template +2 -2
- package/types/ng-primitives-internal.d.ts +95 -3
- package/types/ng-primitives-menu.d.ts +42 -10
- package/types/ng-primitives-portal.d.ts +31 -1
- package/types/ng-primitives-tooltip.d.ts +6 -9
- package/types/ng-primitives-utils.d.ts +12 -9
|
@@ -4,13 +4,13 @@ import * as i0 from '@angular/core';
|
|
|
4
4
|
import { InjectionToken, inject, Injector, ViewContainerRef, signal, computed, effect, input, booleanAttribute, Directive, output, numberAttribute } from '@angular/core';
|
|
5
5
|
import { ngpRovingFocusItem, provideRovingFocusItemState, ngpRovingFocusGroup, provideRovingFocusGroupState } from 'ng-primitives/roving-focus';
|
|
6
6
|
import { ngpButton } from 'ng-primitives/button';
|
|
7
|
-
import { injectElementRef } from 'ng-primitives/internal';
|
|
7
|
+
import { injectElementRef, createHoverBridge } from 'ng-primitives/internal';
|
|
8
8
|
import { createPrimitive, controlled, attrBinding, dataBinding, listener, deprecatedSetter, styleBinding, emitter } from 'ng-primitives/state';
|
|
9
9
|
import { Directionality } from '@angular/cdk/bidi';
|
|
10
10
|
import { ngpFocusTrap, provideFocusTrapState } from 'ng-primitives/focus-trap';
|
|
11
11
|
import { Subject } from 'rxjs';
|
|
12
|
+
import { injectDisposables, safeTakeUntilDestroyed } from 'ng-primitives/utils';
|
|
12
13
|
import { FocusMonitor } from '@angular/cdk/a11y';
|
|
13
|
-
import { safeTakeUntilDestroyed } from 'ng-primitives/utils';
|
|
14
14
|
|
|
15
15
|
const defaultMenuConfig = {
|
|
16
16
|
offset: 4,
|
|
@@ -52,6 +52,7 @@ const [NgpMenuTriggerStateToken, ngpMenuTrigger, _injectMenuTriggerState, provid
|
|
|
52
52
|
const injector = inject(Injector);
|
|
53
53
|
const viewContainerRef = inject(ViewContainerRef);
|
|
54
54
|
const directionality = inject(Directionality);
|
|
55
|
+
const disposables = injectDisposables();
|
|
55
56
|
// Controlled properties
|
|
56
57
|
const menu = controlled(_menu);
|
|
57
58
|
const disabled = controlled(_disabled);
|
|
@@ -70,11 +71,21 @@ const [NgpMenuTriggerStateToken, ngpMenuTrigger, _injectMenuTriggerState, provid
|
|
|
70
71
|
const pointerOverTrigger = signal(false, ...(ngDevMode ? [{ debugName: "pointerOverTrigger" }] : /* istanbul ignore next */ []));
|
|
71
72
|
const pointerOverContent = signal(false, ...(ngDevMode ? [{ debugName: "pointerOverContent" }] : /* istanbul ignore next */ []));
|
|
72
73
|
const isPointerOverMenuArea = computed(() => pointerOverTrigger() || pointerOverContent(), ...(ngDevMode ? [{ debugName: "isPointerOverMenuArea" }] : /* istanbul ignore next */ []));
|
|
74
|
+
// Safe-polygon hover intent: while the pointer travels inside a corridor from
|
|
75
|
+
// the trigger exit point toward the open menu, the menu stays open. Reversing
|
|
76
|
+
// away closes it (requireForwardMovement).
|
|
77
|
+
const hoverBridge = createHoverBridge({
|
|
78
|
+
isPointerInAnchor: isPointerOverMenuArea,
|
|
79
|
+
close: () => hide(),
|
|
80
|
+
requireForwardMovement: true,
|
|
81
|
+
});
|
|
73
82
|
// Reset pointer tracking when menu closes
|
|
74
83
|
effect(() => {
|
|
75
84
|
const isOpen = open();
|
|
76
|
-
// When menu closes, reset pointer tracking state
|
|
85
|
+
// When menu closes, reset pointer tracking state and tear down any
|
|
86
|
+
// in-progress hover bridge (and its global listener).
|
|
77
87
|
if (!isOpen) {
|
|
88
|
+
hoverBridge.clear();
|
|
78
89
|
pointerOverTrigger.set(false);
|
|
79
90
|
pointerOverContent.set(false);
|
|
80
91
|
}
|
|
@@ -110,8 +121,10 @@ const [NgpMenuTriggerStateToken, ngpMenuTrigger, _injectMenuTriggerState, provid
|
|
|
110
121
|
return;
|
|
111
122
|
}
|
|
112
123
|
pointerOverTrigger.set(true);
|
|
113
|
-
// If already open, cancel any pending hide
|
|
124
|
+
// If already open, cancel any pending hide - the pointer is back on the
|
|
125
|
+
// trigger, so any in-progress hover bridge is no longer needed.
|
|
114
126
|
if (open()) {
|
|
127
|
+
hoverBridge.clear();
|
|
115
128
|
overlay()?.cancelPendingClose();
|
|
116
129
|
return;
|
|
117
130
|
}
|
|
@@ -126,17 +139,31 @@ const [NgpMenuTriggerStateToken, ngpMenuTrigger, _injectMenuTriggerState, provid
|
|
|
126
139
|
return;
|
|
127
140
|
}
|
|
128
141
|
pointerOverTrigger.set(false);
|
|
142
|
+
const currentOverlay = overlay();
|
|
129
143
|
// If the overlay hasn't been created, there's nothing to cancel
|
|
130
|
-
if (!
|
|
144
|
+
if (!currentOverlay) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
// Build a safe-polygon corridor from the pointer exit point toward the
|
|
148
|
+
// open menu. While the pointer stays inside it the menu stays open, so
|
|
149
|
+
// diagonal travel across the offset gap doesn't collapse the menu.
|
|
150
|
+
const menuElement = open() ? currentOverlay.getElements()[0] : undefined;
|
|
151
|
+
const started = !!menuElement &&
|
|
152
|
+
hoverBridge.track({
|
|
153
|
+
triggerRect: element.nativeElement.getBoundingClientRect(),
|
|
154
|
+
targetRect: menuElement.getBoundingClientRect(),
|
|
155
|
+
exitPoint: { x: event.clientX, y: event.clientY },
|
|
156
|
+
});
|
|
157
|
+
if (started) {
|
|
158
|
+
currentOverlay.cancelPendingClose();
|
|
131
159
|
return;
|
|
132
160
|
}
|
|
133
|
-
//
|
|
134
|
-
setTimeout(() => {
|
|
135
|
-
// Only hide if pointer is not over trigger or content
|
|
161
|
+
// Fall back to a small grace period when we can't build the corridor.
|
|
162
|
+
disposables.setTimeout(() => {
|
|
136
163
|
if (!isPointerOverMenuArea()) {
|
|
137
164
|
hide();
|
|
138
165
|
}
|
|
139
|
-
}, 50);
|
|
166
|
+
}, 50);
|
|
140
167
|
}
|
|
141
168
|
function onFocus() {
|
|
142
169
|
if (disabled?.() || !triggers().includes('focus')) {
|
|
@@ -309,9 +336,14 @@ const [NgpMenuTriggerStateToken, ngpMenuTrigger, _injectMenuTriggerState, provid
|
|
|
309
336
|
*/
|
|
310
337
|
function setPointerOverContent(isOver) {
|
|
311
338
|
pointerOverContent.set(isOver);
|
|
312
|
-
if (
|
|
339
|
+
if (isOver) {
|
|
340
|
+
// The pointer reached the menu - the hover bridge has served its purpose.
|
|
341
|
+
hoverBridge.clear();
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
if (open() && triggers().includes('hover')) {
|
|
313
345
|
// Use a small delay to allow pointer to move back to trigger
|
|
314
|
-
setTimeout(() => {
|
|
346
|
+
disposables.setTimeout(() => {
|
|
315
347
|
// Only hide if pointer is not over trigger or content
|
|
316
348
|
if (!isPointerOverMenuArea()) {
|
|
317
349
|
hide();
|
|
@@ -432,21 +464,48 @@ const [NgpMenuStateToken, ngpMenu, injectMenuState, provideMenuState] = createPr
|
|
|
432
464
|
};
|
|
433
465
|
});
|
|
434
466
|
|
|
435
|
-
const [NgpSubmenuTriggerStateToken, ngpSubmenuTrigger, injectSubmenuTriggerState, provideSubmenuTriggerState,] = createPrimitive('NgpSubmenuTrigger', ({ disabled: _disabled = signal(false), menu: _menu = signal(undefined), placement: _placement = signal('right-start'), offset: _offset = signal(0), flip: _flip = signal(true), }) => {
|
|
467
|
+
const [NgpSubmenuTriggerStateToken, ngpSubmenuTrigger, injectSubmenuTriggerState, provideSubmenuTriggerState,] = createPrimitive('NgpSubmenuTrigger', ({ disabled: _disabled = signal(false), menu: _menu = signal(undefined), placement: _placement = signal('right-start'), offset: _offset = signal(0), flip: _flip = signal(true), container: _container, }) => {
|
|
436
468
|
const element = injectElementRef();
|
|
437
469
|
const injector = inject(Injector);
|
|
438
470
|
const viewContainerRef = inject(ViewContainerRef);
|
|
439
471
|
const parentMenu = injectMenuState({ optional: true });
|
|
440
472
|
const focusMonitor = inject(FocusMonitor);
|
|
473
|
+
const disposables = injectDisposables();
|
|
441
474
|
// Controlled properties
|
|
442
475
|
const menu = controlled(_menu);
|
|
443
476
|
const disabled = controlled(_disabled);
|
|
444
477
|
const placement = controlled(_placement);
|
|
445
478
|
const flip = controlled(_flip);
|
|
446
479
|
const offset = controlled(_offset);
|
|
480
|
+
const container = controlled(_container, 'body');
|
|
447
481
|
const overlay = signal(null, ...(ngDevMode ? [{ debugName: "overlay" }] : /* istanbul ignore next */ []));
|
|
448
482
|
const open = computed(() => overlay()?.isOpen() ?? false, ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
|
|
449
483
|
const openOrigin = signal('program', ...(ngDevMode ? [{ debugName: "openOrigin" }] : /* istanbul ignore next */ []));
|
|
484
|
+
// Track pointer presence for the safe-polygon hover bridge.
|
|
485
|
+
const pointerOverTrigger = signal(false, ...(ngDevMode ? [{ debugName: "pointerOverTrigger" }] : /* istanbul ignore next */ []));
|
|
486
|
+
const pointerOverContent = signal(false, ...(ngDevMode ? [{ debugName: "pointerOverContent" }] : /* istanbul ignore next */ []));
|
|
487
|
+
const isPointerOverSubmenu = computed(() => pointerOverTrigger() || pointerOverContent(), ...(ngDevMode ? [{ debugName: "isPointerOverSubmenu" }] : /* istanbul ignore next */ []));
|
|
488
|
+
// Safe-polygon hover intent: while the pointer travels inside a corridor from
|
|
489
|
+
// the submenu trigger toward the open submenu, sibling hover events are
|
|
490
|
+
// ignored so the submenu doesn't collapse mid-traversal.
|
|
491
|
+
const hoverBridge = createHoverBridge({
|
|
492
|
+
isPointerInAnchor: isPointerOverSubmenu,
|
|
493
|
+
close: () => hide('mouse'),
|
|
494
|
+
requireForwardMovement: true,
|
|
495
|
+
});
|
|
496
|
+
// Tear down any hover bridge whenever the submenu closes - including close
|
|
497
|
+
// paths that bypass hide() (e.g. an outside click on the overlay), so a
|
|
498
|
+
// stale corridor can't linger or wrongly suppress the next sibling hover.
|
|
499
|
+
// Also reset the pointer flags: destroying the panel under the pointer never
|
|
500
|
+
// fires its pointerleave, and a stuck pointerOverContent would make every
|
|
501
|
+
// future corridor treat the pointer as anchored and never close.
|
|
502
|
+
effect(() => {
|
|
503
|
+
if (!open()) {
|
|
504
|
+
hoverBridge.clear();
|
|
505
|
+
pointerOverTrigger.set(false);
|
|
506
|
+
pointerOverContent.set(false);
|
|
507
|
+
}
|
|
508
|
+
});
|
|
450
509
|
// Subscribe to parent menu's closeSubmenus
|
|
451
510
|
parentMenu()
|
|
452
511
|
?.closeSubmenus.pipe(safeTakeUntilDestroyed())
|
|
@@ -455,6 +514,12 @@ const [NgpSubmenuTriggerStateToken, ngpSubmenuTrigger, injectSubmenuTriggerState
|
|
|
455
514
|
if (submenuElement === element.nativeElement) {
|
|
456
515
|
return;
|
|
457
516
|
}
|
|
517
|
+
// While the pointer is still inside the safe-polygon corridor toward this
|
|
518
|
+
// submenu, ignore sibling hover-driven closes. The pointer-move listener
|
|
519
|
+
// closes the submenu itself once the pointer actually leaves the corridor.
|
|
520
|
+
if (hoverBridge.isActive()) {
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
458
523
|
hide('mouse');
|
|
459
524
|
});
|
|
460
525
|
// Host bindings
|
|
@@ -465,6 +530,7 @@ const [NgpSubmenuTriggerStateToken, ngpSubmenuTrigger, injectSubmenuTriggerState
|
|
|
465
530
|
listener(element, 'click', onClick);
|
|
466
531
|
listener(element, 'keydown', handleArrowKey);
|
|
467
532
|
listener(element, 'pointerenter', showSubmenuOnHover);
|
|
533
|
+
listener(element, 'pointerleave', onPointerLeave);
|
|
468
534
|
// Methods
|
|
469
535
|
function onClick(event) {
|
|
470
536
|
if (disabled?.()) {
|
|
@@ -502,6 +568,8 @@ const [NgpSubmenuTriggerStateToken, ngpSubmenuTrigger, injectSubmenuTriggerState
|
|
|
502
568
|
if (disabled?.() || !open()) {
|
|
503
569
|
return;
|
|
504
570
|
}
|
|
571
|
+
// The submenu is closing - any active hover bridge is no longer relevant.
|
|
572
|
+
hoverBridge.clear();
|
|
505
573
|
// Hide the overlay
|
|
506
574
|
overlay()?.hide({ origin });
|
|
507
575
|
}
|
|
@@ -520,6 +588,7 @@ const [NgpSubmenuTriggerStateToken, ngpSubmenuTrigger, injectSubmenuTriggerState
|
|
|
520
588
|
content: menuContent,
|
|
521
589
|
triggerElement: element.nativeElement,
|
|
522
590
|
injector,
|
|
591
|
+
container: container(),
|
|
523
592
|
placement,
|
|
524
593
|
offset: offset(),
|
|
525
594
|
flip: flip(),
|
|
@@ -552,8 +621,38 @@ const [NgpSubmenuTriggerStateToken, ngpSubmenuTrigger, injectSubmenuTriggerState
|
|
|
552
621
|
if (event.pointerType === 'touch') {
|
|
553
622
|
return;
|
|
554
623
|
}
|
|
624
|
+
pointerOverTrigger.set(true);
|
|
625
|
+
// The pointer is back on the trigger - drop any in-progress hover bridge.
|
|
626
|
+
hoverBridge.clear();
|
|
555
627
|
show('mouse');
|
|
556
628
|
}
|
|
629
|
+
function onPointerLeave(event) {
|
|
630
|
+
if (event instanceof PointerEvent === false || event.pointerType === 'touch') {
|
|
631
|
+
return;
|
|
632
|
+
}
|
|
633
|
+
pointerOverTrigger.set(false);
|
|
634
|
+
const currentOverlay = overlay();
|
|
635
|
+
// Only build a corridor while the submenu is actually open.
|
|
636
|
+
if (!open() || !currentOverlay) {
|
|
637
|
+
return;
|
|
638
|
+
}
|
|
639
|
+
const submenuElement = currentOverlay.getElements()[0];
|
|
640
|
+
const started = !!submenuElement &&
|
|
641
|
+
hoverBridge.track({
|
|
642
|
+
triggerRect: element.nativeElement.getBoundingClientRect(),
|
|
643
|
+
targetRect: submenuElement.getBoundingClientRect(),
|
|
644
|
+
exitPoint: { x: event.clientX, y: event.clientY },
|
|
645
|
+
});
|
|
646
|
+
if (!started) {
|
|
647
|
+
// Defensive fallback: if the corridor can't be built, close after a short
|
|
648
|
+
// grace period rather than leaving the submenu stuck open.
|
|
649
|
+
disposables.setTimeout(() => {
|
|
650
|
+
if (!isPointerOverSubmenu()) {
|
|
651
|
+
hide('mouse');
|
|
652
|
+
}
|
|
653
|
+
}, 50);
|
|
654
|
+
}
|
|
655
|
+
}
|
|
557
656
|
function setDisabled(isDisabled) {
|
|
558
657
|
disabled.set(isDisabled);
|
|
559
658
|
if (isDisabled && open()) {
|
|
@@ -572,14 +671,19 @@ const [NgpSubmenuTriggerStateToken, ngpSubmenuTrigger, injectSubmenuTriggerState
|
|
|
572
671
|
function setFlip(shouldFlip) {
|
|
573
672
|
flip.set(shouldFlip);
|
|
574
673
|
}
|
|
674
|
+
function setContainer(newContainer) {
|
|
675
|
+
container.set(newContainer);
|
|
676
|
+
}
|
|
575
677
|
function focus(origin) {
|
|
576
678
|
focusMonitor.focusVia(element.nativeElement, origin, { preventScroll: true });
|
|
577
679
|
}
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
//
|
|
581
|
-
//
|
|
582
|
-
|
|
680
|
+
function setPointerOverContent(isOver) {
|
|
681
|
+
pointerOverContent.set(isOver);
|
|
682
|
+
// Reaching the submenu content means the pointer arrived safely, so the
|
|
683
|
+
// hover bridge corridor is no longer needed.
|
|
684
|
+
if (isOver) {
|
|
685
|
+
hoverBridge.clear();
|
|
686
|
+
}
|
|
583
687
|
}
|
|
584
688
|
return {
|
|
585
689
|
placement: deprecatedSetter(placement, 'setPlacement'),
|
|
@@ -597,8 +701,10 @@ const [NgpSubmenuTriggerStateToken, ngpSubmenuTrigger, injectSubmenuTriggerState
|
|
|
597
701
|
setFlip,
|
|
598
702
|
setPlacement,
|
|
599
703
|
setOffset,
|
|
704
|
+
setContainer,
|
|
600
705
|
focus,
|
|
601
706
|
setPointerOverContent,
|
|
707
|
+
container: deprecatedSetter(container, 'setContainer', setContainer),
|
|
602
708
|
};
|
|
603
709
|
});
|
|
604
710
|
|
|
@@ -633,6 +739,11 @@ class NgpSubmenuTrigger {
|
|
|
633
739
|
*/
|
|
634
740
|
this.flip = input(true, { ...(ngDevMode ? { debugName: "flip" } : /* istanbul ignore next */ {}), alias: 'ngpSubmenuTriggerFlip',
|
|
635
741
|
transform: coerceFlip });
|
|
742
|
+
/**
|
|
743
|
+
* Define the container in which the menu should be attached.
|
|
744
|
+
* @default document.body
|
|
745
|
+
*/
|
|
746
|
+
this.container = input(null, { ...(ngDevMode ? { debugName: "container" } : /* istanbul ignore next */ {}), alias: 'ngpSubmenuTriggerContainer' });
|
|
636
747
|
/**
|
|
637
748
|
* Access the menu trigger state.
|
|
638
749
|
*/
|
|
@@ -642,6 +753,7 @@ class NgpSubmenuTrigger {
|
|
|
642
753
|
placement: this.placement,
|
|
643
754
|
offset: this.offset,
|
|
644
755
|
flip: this.flip,
|
|
756
|
+
container: this.container,
|
|
645
757
|
});
|
|
646
758
|
}
|
|
647
759
|
/**
|
|
@@ -671,8 +783,12 @@ class NgpSubmenuTrigger {
|
|
|
671
783
|
this.state.focus(origin);
|
|
672
784
|
}
|
|
673
785
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NgpSubmenuTrigger, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
674
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.14", type: NgpSubmenuTrigger, isStandalone: true, selector: "[ngpSubmenuTrigger]", inputs: { menu: { classPropertyName: "menu", publicName: "ngpSubmenuTrigger", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "ngpSubmenuTriggerDisabled", isSignal: true, isRequired: false, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "ngpSubmenuTriggerPlacement", isSignal: true, isRequired: false, transformFunction: null }, offset: { classPropertyName: "offset", publicName: "ngpSubmenuTriggerOffset", isSignal: true, isRequired: false, transformFunction: null }, flip: { classPropertyName: "flip", publicName: "ngpSubmenuTriggerFlip", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
|
|
675
|
-
|
|
786
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.14", type: NgpSubmenuTrigger, isStandalone: true, selector: "[ngpSubmenuTrigger]", inputs: { menu: { classPropertyName: "menu", publicName: "ngpSubmenuTrigger", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "ngpSubmenuTriggerDisabled", isSignal: true, isRequired: false, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "ngpSubmenuTriggerPlacement", isSignal: true, isRequired: false, transformFunction: null }, offset: { classPropertyName: "offset", publicName: "ngpSubmenuTriggerOffset", isSignal: true, isRequired: false, transformFunction: null }, flip: { classPropertyName: "flip", publicName: "ngpSubmenuTriggerFlip", isSignal: true, isRequired: false, transformFunction: null }, container: { classPropertyName: "container", publicName: "ngpSubmenuTriggerContainer", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
|
|
787
|
+
// inherit: false - a nested submenu trigger lives inside the DI scope of its
|
|
788
|
+
// parent submenu trigger (via the overlay's injector). Inheriting would reuse
|
|
789
|
+
// the parent trigger's state signal and overwrite it with this trigger's
|
|
790
|
+
// state, so the parent's menu would start talking to the wrong trigger.
|
|
791
|
+
provideSubmenuTriggerState({ inherit: false }),
|
|
676
792
|
// Also provide as NgpMenuTriggerStateToken so the submenu's menu-state
|
|
677
793
|
// can find this trigger's openOrigin for :focus-visible styling
|
|
678
794
|
{ provide: NgpMenuTriggerStateToken, useExisting: NgpSubmenuTriggerStateToken },
|
|
@@ -684,13 +800,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
684
800
|
selector: '[ngpSubmenuTrigger]',
|
|
685
801
|
exportAs: 'ngpSubmenuTrigger',
|
|
686
802
|
providers: [
|
|
687
|
-
|
|
803
|
+
// inherit: false - a nested submenu trigger lives inside the DI scope of its
|
|
804
|
+
// parent submenu trigger (via the overlay's injector). Inheriting would reuse
|
|
805
|
+
// the parent trigger's state signal and overwrite it with this trigger's
|
|
806
|
+
// state, so the parent's menu would start talking to the wrong trigger.
|
|
807
|
+
provideSubmenuTriggerState({ inherit: false }),
|
|
688
808
|
// Also provide as NgpMenuTriggerStateToken so the submenu's menu-state
|
|
689
809
|
// can find this trigger's openOrigin for :focus-visible styling
|
|
690
810
|
{ provide: NgpMenuTriggerStateToken, useExisting: NgpSubmenuTriggerStateToken },
|
|
691
811
|
],
|
|
692
812
|
}]
|
|
693
|
-
}], propDecorators: { menu: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngpSubmenuTrigger", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngpSubmenuTriggerDisabled", required: false }] }], placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngpSubmenuTriggerPlacement", required: false }] }], offset: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngpSubmenuTriggerOffset", required: false }] }], flip: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngpSubmenuTriggerFlip", required: false }] }] } });
|
|
813
|
+
}], propDecorators: { menu: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngpSubmenuTrigger", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngpSubmenuTriggerDisabled", required: false }] }], placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngpSubmenuTriggerPlacement", required: false }] }], offset: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngpSubmenuTriggerOffset", required: false }] }], flip: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngpSubmenuTriggerFlip", required: false }] }], container: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngpSubmenuTriggerContainer", required: false }] }] } });
|
|
694
814
|
|
|
695
815
|
const [NgpMenuItemStateToken, ngpMenuItem, injectMenuItemState, provideMenuItemState] = createPrimitive('NgpMenuItem', ({ disabled = signal(false), closeOnSelect = signal(true), role = 'menuitem', }) => {
|
|
696
816
|
const element = injectElementRef();
|