@radix-ng/primitives 1.0.0-beta.2 → 1.0.0-beta.4
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/LICENSE +1 -1
- package/README.md +76 -6
- package/fesm2022/radix-ng-primitives-accordion.mjs +5 -3
- package/fesm2022/radix-ng-primitives-accordion.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-alert-dialog.mjs +31 -24
- package/fesm2022/radix-ng-primitives-alert-dialog.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-autocomplete.mjs +1744 -0
- package/fesm2022/radix-ng-primitives-autocomplete.mjs.map +1 -0
- package/fesm2022/radix-ng-primitives-calendar.mjs +5 -3
- package/fesm2022/radix-ng-primitives-calendar.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-combobox.mjs +1399 -606
- package/fesm2022/radix-ng-primitives-combobox.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-config.mjs +13 -4
- package/fesm2022/radix-ng-primitives-config.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-context-menu.mjs +51 -10
- package/fesm2022/radix-ng-primitives-context-menu.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-core.mjs +1345 -64
- package/fesm2022/radix-ng-primitives-core.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-date-field.mjs +5 -3
- package/fesm2022/radix-ng-primitives-date-field.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-dialog.mjs +271 -145
- package/fesm2022/radix-ng-primitives-dialog.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-direction-provider.mjs +70 -0
- package/fesm2022/radix-ng-primitives-direction-provider.mjs.map +1 -0
- package/fesm2022/radix-ng-primitives-dismissable-layer.mjs +519 -184
- package/fesm2022/radix-ng-primitives-dismissable-layer.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-drawer.mjs +154 -64
- package/fesm2022/radix-ng-primitives-drawer.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-field.mjs +3 -2
- package/fesm2022/radix-ng-primitives-field.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-floating-focus-manager.mjs +517 -0
- package/fesm2022/radix-ng-primitives-floating-focus-manager.mjs.map +1 -0
- package/fesm2022/radix-ng-primitives-focus-scope.mjs +296 -70
- package/fesm2022/radix-ng-primitives-focus-scope.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-menu.mjs +894 -299
- package/fesm2022/radix-ng-primitives-menu.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-menubar.mjs +32 -4
- package/fesm2022/radix-ng-primitives-menubar.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-navigation-menu.mjs +176 -207
- package/fesm2022/radix-ng-primitives-navigation-menu.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-popover.mjs +250 -250
- package/fesm2022/radix-ng-primitives-popover.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-popper.mjs +94 -45
- package/fesm2022/radix-ng-primitives-popper.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-portal.mjs +107 -17
- package/fesm2022/radix-ng-primitives-portal.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-presence.mjs +262 -79
- package/fesm2022/radix-ng-primitives-presence.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-preview-card.mjs +172 -218
- package/fesm2022/radix-ng-primitives-preview-card.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-roving-focus.mjs +4 -2
- package/fesm2022/radix-ng-primitives-roving-focus.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-scroll-area.mjs +5 -4
- package/fesm2022/radix-ng-primitives-scroll-area.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-select.mjs +303 -234
- package/fesm2022/radix-ng-primitives-select.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-slider.mjs +5 -3
- package/fesm2022/radix-ng-primitives-slider.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-stepper.mjs +5 -3
- package/fesm2022/radix-ng-primitives-stepper.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-time-field.mjs +5 -3
- package/fesm2022/radix-ng-primitives-time-field.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-toast.mjs +15 -36
- package/fesm2022/radix-ng-primitives-toast.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-toggle-group.mjs +5 -3
- package/fesm2022/radix-ng-primitives-toggle-group.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-toolbar.mjs +5 -3
- package/fesm2022/radix-ng-primitives-toolbar.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-tooltip.mjs +105 -145
- package/fesm2022/radix-ng-primitives-tooltip.mjs.map +1 -1
- package/package.json +14 -1
- package/types/radix-ng-primitives-accordion.d.ts +4 -3
- package/types/radix-ng-primitives-alert-dialog.d.ts +17 -11
- package/types/radix-ng-primitives-autocomplete.d.ts +661 -0
- package/types/radix-ng-primitives-calendar.d.ts +5 -3
- package/types/radix-ng-primitives-combobox.d.ts +727 -293
- package/types/radix-ng-primitives-config.d.ts +1 -1
- package/types/radix-ng-primitives-context-menu.d.ts +15 -5
- package/types/radix-ng-primitives-core.d.ts +762 -14
- package/types/radix-ng-primitives-date-field.d.ts +3 -2
- package/types/radix-ng-primitives-dialog.d.ts +107 -55
- package/types/radix-ng-primitives-direction-provider.d.ts +41 -0
- package/types/radix-ng-primitives-dismissable-layer.d.ts +147 -99
- package/types/radix-ng-primitives-drawer.d.ts +49 -22
- package/types/radix-ng-primitives-field.d.ts +1 -0
- package/types/radix-ng-primitives-floating-focus-manager.d.ts +175 -0
- package/types/radix-ng-primitives-focus-scope.d.ts +132 -1
- package/types/radix-ng-primitives-menu.d.ts +204 -112
- package/types/radix-ng-primitives-navigation-menu.d.ts +61 -101
- package/types/radix-ng-primitives-popover.d.ts +82 -115
- package/types/radix-ng-primitives-popper.d.ts +46 -10
- package/types/radix-ng-primitives-portal.d.ts +53 -8
- package/types/radix-ng-primitives-presence.d.ts +98 -17
- package/types/radix-ng-primitives-preview-card.d.ts +63 -95
- package/types/radix-ng-primitives-roving-focus.d.ts +7 -6
- package/types/radix-ng-primitives-scroll-area.d.ts +2 -2
- package/types/radix-ng-primitives-select.d.ts +192 -158
- package/types/radix-ng-primitives-slider.d.ts +5 -4
- package/types/radix-ng-primitives-stepper.d.ts +4 -3
- package/types/radix-ng-primitives-time-field.d.ts +3 -2
- package/types/radix-ng-primitives-toast.d.ts +7 -7
- package/types/radix-ng-primitives-toggle-group.d.ts +5 -4
- package/types/radix-ng-primitives-toolbar.d.ts +3 -2
- package/types/radix-ng-primitives-tooltip.d.ts +48 -84
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, computed, Directive, input, signal, TemplateRef, booleanAttribute, effect, untracked, ElementRef, output, DestroyRef,
|
|
2
|
+
import { inject, computed, Directive, input, signal, TemplateRef, booleanAttribute, effect, untracked, ElementRef, output, DestroyRef, isDevMode, model, numberAttribute, ViewContainerRef, Renderer2, NgModule } from '@angular/core';
|
|
3
3
|
import * as i1 from '@radix-ng/primitives/popper';
|
|
4
|
-
import { RdxPopperContentWrapper, RdxPopperArrow, RdxPopperContent, provideRdxPopperContentConfig, RdxPopper } from '@radix-ng/primitives/popper';
|
|
5
|
-
import
|
|
4
|
+
import { RdxPopperContentWrapper, RdxPopperArrow, RdxPopperContent, provideRdxPopperContentWrapper, provideRdxPopperContentConfig, RdxPopper } from '@radix-ng/primitives/popper';
|
|
5
|
+
import * as i2 from '@radix-ng/primitives/core';
|
|
6
|
+
import { createContext, ENTER, SPACE, RDX_FLOATING_ROOT_CONTEXT, RDX_FLOATING_REGISTRATION, ARROW_DOWN, ARROW_UP, HOME, END, rdxDevError, useGraceArea, createFloatingRootContext, useTransitionStatus, provideFloatingTree, provideFloatingRootContext, RdxFloatingNodeRegistration, createCancelableChangeEventDetails, injectDocument, ARROW_LEFT, ARROW_RIGHT, getMaxTransitionDuration } from '@radix-ng/primitives/core';
|
|
6
7
|
import * as i1$1 from '@radix-ng/primitives/roving-focus';
|
|
7
8
|
import { RdxRovingFocusGroupDirective, RdxRovingFocusItemDirective } from '@radix-ng/primitives/roving-focus';
|
|
8
|
-
import {
|
|
9
|
-
import * as i2 from '@radix-ng/primitives/dismissable-layer';
|
|
10
|
-
import { RdxDismissableLayer, RdxDismissableLayersContextToken } from '@radix-ng/primitives/dismissable-layer';
|
|
9
|
+
import { RdxDismiss } from '@radix-ng/primitives/dismissable-layer';
|
|
11
10
|
import * as i1$2 from '@radix-ng/primitives/portal';
|
|
12
|
-
import {
|
|
13
|
-
import
|
|
14
|
-
import {
|
|
11
|
+
import { RdxPortalPresence } from '@radix-ng/primitives/portal';
|
|
12
|
+
import { provideRdxPresenceContext } from '@radix-ng/primitives/presence';
|
|
13
|
+
import { injectDirection } from '@radix-ng/primitives/direction-provider';
|
|
15
14
|
|
|
16
15
|
const [injectNavigationMenuRootContext, provideNavigationMenuRootContext] = createContext('RdxNavigationMenuRootContext', 'components/navigation-menu');
|
|
17
16
|
|
|
@@ -318,7 +317,7 @@ class RdxNavigationMenuList {
|
|
|
318
317
|
if (event.pointerType === 'touch') {
|
|
319
318
|
return;
|
|
320
319
|
}
|
|
321
|
-
this.rootContext.closeOnHover();
|
|
320
|
+
this.rootContext.closeOnHover(event);
|
|
322
321
|
}
|
|
323
322
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxNavigationMenuList, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
324
323
|
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxNavigationMenuList, isStandalone: true, selector: "[rdxNavigationMenuList]", host: { attributes: { "role": "menubar" }, listeners: { "pointerleave": "onPointerLeave($event)" }, properties: { "attr.data-orientation": "rootContext.orientation()" } }, hostDirectives: [{ directive: i1$1.RdxRovingFocusGroupDirective }], ngImport: i0 }); }
|
|
@@ -342,9 +341,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
342
341
|
class RdxNavigationMenuPopup {
|
|
343
342
|
constructor() {
|
|
344
343
|
this.rootContext = injectNavigationMenuRootContext();
|
|
345
|
-
this.
|
|
344
|
+
this.floatingContext = inject(RDX_FLOATING_ROOT_CONTEXT);
|
|
345
|
+
this.registration = inject(RDX_FLOATING_REGISTRATION, { optional: true });
|
|
346
346
|
this.wrapper = inject(RdxPopperContentWrapper, { optional: true });
|
|
347
|
-
this.layersContext = inject(RdxDismissableLayersContextToken);
|
|
348
347
|
this.elementRef = inject(ElementRef);
|
|
349
348
|
this.side = computed(() => this.wrapper?.placedSide(), ...(ngDevMode ? [{ debugName: "side" }] : /* istanbul ignore next */ []));
|
|
350
349
|
this.align = computed(() => this.wrapper?.placedAlign(), ...(ngDevMode ? [{ debugName: "align" }] : /* istanbul ignore next */ []));
|
|
@@ -353,59 +352,46 @@ class RdxNavigationMenuPopup {
|
|
|
353
352
|
const value = this.rootContext.value() ?? this.rootContext.previousValue();
|
|
354
353
|
return value ? this.rootContext.triggerId(value) : undefined;
|
|
355
354
|
}, ...(ngDevMode ? [{ debugName: "labelledBy" }] : /* istanbul ignore next */ []));
|
|
356
|
-
this.dismissReason = 'none';
|
|
357
|
-
this.dismissEvent = new Event('navigation-menu.dismiss');
|
|
358
355
|
/**
|
|
359
356
|
* Event handler called when the escape key is down. Can be prevented.
|
|
360
357
|
*/
|
|
361
|
-
this.escapeKeyDown =
|
|
358
|
+
this.escapeKeyDown = output();
|
|
362
359
|
/**
|
|
363
360
|
* Event handler called when a pointerdown event happens outside the popup. Can be prevented.
|
|
364
361
|
*/
|
|
365
|
-
this.pointerDownOutside =
|
|
362
|
+
this.pointerDownOutside = output();
|
|
366
363
|
/**
|
|
367
364
|
* Event handler called when focus moves outside the popup. Can be prevented.
|
|
368
365
|
*/
|
|
369
|
-
this.focusOutside =
|
|
366
|
+
this.focusOutside = output();
|
|
370
367
|
const destroyRef = inject(DestroyRef);
|
|
371
368
|
const unregisterTransitionElement = this.rootContext.registerTransitionElement(this.elementRef.nativeElement);
|
|
372
369
|
destroyRef.onDestroy(unregisterTransitionElement);
|
|
373
|
-
//
|
|
374
|
-
//
|
|
375
|
-
//
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
this.
|
|
390
|
-
this.
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
this.dismissEvent = event;
|
|
399
|
-
});
|
|
400
|
-
this.dismissableLayer.dismiss.subscribe(() => {
|
|
401
|
-
const reason = this.dismissReason;
|
|
402
|
-
const event = this.dismissEvent;
|
|
403
|
-
this.dismissReason = 'none';
|
|
404
|
-
this.dismissEvent = new Event('navigation-menu.dismiss');
|
|
405
|
-
this.rootContext.close(reason, event);
|
|
406
|
-
// Return focus to the trigger after an Escape dismissal.
|
|
407
|
-
if (reason === 'escape-key') {
|
|
408
|
-
this.rootContext.trigger()?.focus();
|
|
370
|
+
// The popup is this layer's floating element (the inside surface for containment checks). The
|
|
371
|
+
// triggers are registered as "inside" on the shared root context (in `registerTrigger`), so a
|
|
372
|
+
// press / focus on a sibling trigger to switch items — or back on the active trigger — never
|
|
373
|
+
// counts as an outside dismissal. This replaces the legacy dismissable-layer `branches` registry.
|
|
374
|
+
this.floatingContext.setFloatingElement(this.elementRef.nativeElement);
|
|
375
|
+
// Dismissal (ADR 0015): Escape, an outside press, or focus moving outside closes the menu.
|
|
376
|
+
// Navigation Menu registers its FloatingNode on the root, matching Base UI's
|
|
377
|
+
// NavigationMenuRoot → FloatingNode wiring. This lets nested roots participate in parent/child
|
|
378
|
+
// ownership even though each root has one shared popup.
|
|
379
|
+
// It does not trap focus, so it closes on focus-out like a non-modal menu.
|
|
380
|
+
new RdxDismiss(this.floatingContext, () => this.registration?.node() ?? null, {
|
|
381
|
+
escapeKey: () => true,
|
|
382
|
+
outsidePress: () => true,
|
|
383
|
+
outsidePressEvent: () => 'intentional',
|
|
384
|
+
focusOutside: () => true,
|
|
385
|
+
onEscapeKeyDown: (event) => this.escapeKeyDown.emit(event),
|
|
386
|
+
onPointerDownOutside: (event) => this.pointerDownOutside.emit(event),
|
|
387
|
+
onFocusOutside: (event) => this.focusOutside.emit(event),
|
|
388
|
+
onDismiss: (reason, event) => {
|
|
389
|
+
const navReason = reason === 'escape-key' ? 'escape-key' : reason === 'focus-outside' ? 'focus-out' : 'outside-press';
|
|
390
|
+
this.rootContext.close(navReason, event);
|
|
391
|
+
// Return focus to the trigger after an Escape dismissal.
|
|
392
|
+
if (reason === 'escape-key') {
|
|
393
|
+
this.rootContext.trigger()?.focus();
|
|
394
|
+
}
|
|
409
395
|
}
|
|
410
396
|
});
|
|
411
397
|
}
|
|
@@ -413,12 +399,12 @@ class RdxNavigationMenuPopup {
|
|
|
413
399
|
if (event.pointerType === 'touch') {
|
|
414
400
|
return;
|
|
415
401
|
}
|
|
416
|
-
this.rootContext.closeOnHover();
|
|
402
|
+
this.rootContext.closeOnHover(event);
|
|
417
403
|
}
|
|
418
404
|
/**
|
|
419
405
|
* Keyboard navigation inside the open panel: Down/Up move between the panel's focusable items in
|
|
420
406
|
* DOM order, Home/End jump to the first/last, and Up from the first item returns focus to the
|
|
421
|
-
* trigger. (Tab keeps working natively; Escape is handled by the
|
|
407
|
+
* trigger. (Tab keeps working natively; Escape is handled by the dismissal capability.)
|
|
422
408
|
*/
|
|
423
409
|
onKeydown(event) {
|
|
424
410
|
if (event.key !== ARROW_DOWN && event.key !== ARROW_UP && event.key !== HOME && event.key !== END) {
|
|
@@ -458,13 +444,13 @@ class RdxNavigationMenuPopup {
|
|
|
458
444
|
}
|
|
459
445
|
}
|
|
460
446
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxNavigationMenuPopup, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
461
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxNavigationMenuPopup, isStandalone: true, selector: "[rdxNavigationMenuPopup]", outputs: { escapeKeyDown: "escapeKeyDown", pointerDownOutside: "pointerDownOutside", focusOutside: "focusOutside" }, host: { attributes: { "role": "menu", "tabindex": "-1" }, listeners: { "pointerenter": "rootContext.cancelHoverClose()", "pointerleave": "onPointerLeave($event)", "keydown": "onKeydown($event)" }, properties: { "attr.aria-labelledby": "labelledBy()", "attr.data-open": "rootContext.isOpen() ? \"\" : undefined", "attr.data-closed": "rootContext.isOpen() ? undefined : \"\"", "attr.data-starting-style": "rootContext.transitionStatus() === \"starting\" ? \"\" : undefined", "attr.data-ending-style": "rootContext.transitionStatus() === \"ending\" ? \"\" : undefined", "attr.data-instant": "rootContext.instant() ? \"\" : undefined", "attr.data-state": "rootContext.isOpen() ? \"open\" : \"closed\"", "attr.data-side": "side()", "attr.data-align": "align()" } }, hostDirectives: [{ directive: i1.RdxPopperContent }
|
|
447
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxNavigationMenuPopup, isStandalone: true, selector: "[rdxNavigationMenuPopup]", outputs: { escapeKeyDown: "escapeKeyDown", pointerDownOutside: "pointerDownOutside", focusOutside: "focusOutside" }, host: { attributes: { "role": "menu", "tabindex": "-1" }, listeners: { "pointerenter": "rootContext.cancelHoverClose()", "pointerleave": "onPointerLeave($event)", "keydown": "onKeydown($event)" }, properties: { "attr.aria-labelledby": "labelledBy()", "attr.data-open": "rootContext.isOpen() ? \"\" : undefined", "attr.data-closed": "rootContext.isOpen() ? undefined : \"\"", "attr.data-starting-style": "rootContext.transitionStatus() === \"starting\" ? \"\" : undefined", "attr.data-ending-style": "rootContext.transitionStatus() === \"ending\" ? \"\" : undefined", "attr.data-instant": "rootContext.instant() ? \"\" : undefined", "attr.data-state": "rootContext.isOpen() ? \"open\" : \"closed\"", "attr.data-side": "side()", "attr.data-align": "align()" } }, hostDirectives: [{ directive: i1.RdxPopperContent }], ngImport: i0 }); }
|
|
462
448
|
}
|
|
463
449
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxNavigationMenuPopup, decorators: [{
|
|
464
450
|
type: Directive,
|
|
465
451
|
args: [{
|
|
466
452
|
selector: '[rdxNavigationMenuPopup]',
|
|
467
|
-
hostDirectives: [RdxPopperContent
|
|
453
|
+
hostDirectives: [RdxPopperContent],
|
|
468
454
|
host: {
|
|
469
455
|
role: 'menu',
|
|
470
456
|
tabindex: '-1',
|
|
@@ -485,186 +471,93 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
485
471
|
}], ctorParameters: () => [], propDecorators: { escapeKeyDown: [{ type: i0.Output, args: ["escapeKeyDown"] }], pointerDownOutside: [{ type: i0.Output, args: ["pointerDownOutside"] }], focusOutside: [{ type: i0.Output, args: ["focusOutside"] }] } });
|
|
486
472
|
|
|
487
473
|
/**
|
|
488
|
-
*
|
|
474
|
+
* Structural directive that teleports the navigation menu popup into a container (default
|
|
475
|
+
* `document.body`) while the menu is open, and keeps it mounted until any CSS exit `@keyframes`
|
|
476
|
+
* finishes.
|
|
477
|
+
*
|
|
478
|
+
* Apply it with the `*` microsyntax on the positioner —
|
|
479
|
+
* `<div *rdxNavigationMenuPortal rdxNavigationMenuPositioner>` — or as an explicit
|
|
480
|
+
* `<ng-template rdxNavigationMenuPortal>`. For a custom container use the explicit form with
|
|
481
|
+
* `[container]`.
|
|
489
482
|
*/
|
|
490
483
|
class RdxNavigationMenuPortal {
|
|
491
|
-
constructor() {
|
|
492
|
-
this.rootContext = injectNavigationMenuRootContext();
|
|
493
|
-
/**
|
|
494
|
-
* Optional container to portal the popup into. Defaults to `document.body`.
|
|
495
|
-
*/
|
|
496
|
-
this.container = input(...(ngDevMode ? [undefined, { debugName: "container" }] : /* istanbul ignore next */ []));
|
|
497
|
-
}
|
|
498
484
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxNavigationMenuPortal, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
499
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "
|
|
485
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxNavigationMenuPortal, isStandalone: true, selector: "ng-template[rdxNavigationMenuPortal]", providers: [provideRdxPresenceContext(() => ({ present: injectNavigationMenuRootContext().present }))], exportAs: ["rdxNavigationMenuPortal"], hostDirectives: [{ directive: i1$2.RdxPortalPresence, inputs: ["container", "container"] }], ngImport: i0 }); }
|
|
500
486
|
}
|
|
501
487
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxNavigationMenuPortal, decorators: [{
|
|
502
488
|
type: Directive,
|
|
503
489
|
args: [{
|
|
504
|
-
selector: '[rdxNavigationMenuPortal]',
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
inputs: ['container']
|
|
509
|
-
}
|
|
510
|
-
],
|
|
511
|
-
host: {
|
|
512
|
-
'[attr.data-open]': 'rootContext.isOpen() ? "" : undefined',
|
|
513
|
-
'[attr.data-closed]': 'rootContext.isOpen() ? undefined : ""',
|
|
514
|
-
'[attr.data-state]': 'rootContext.isOpen() ? "open" : "closed"'
|
|
515
|
-
}
|
|
490
|
+
selector: 'ng-template[rdxNavigationMenuPortal]',
|
|
491
|
+
exportAs: 'rdxNavigationMenuPortal',
|
|
492
|
+
hostDirectives: [{ directive: RdxPortalPresence, inputs: ['container'] }],
|
|
493
|
+
providers: [provideRdxPresenceContext(() => ({ present: injectNavigationMenuRootContext().present }))]
|
|
516
494
|
}]
|
|
517
|
-
}]
|
|
518
|
-
|
|
495
|
+
}] });
|
|
519
496
|
/**
|
|
520
|
-
*
|
|
521
|
-
*
|
|
522
|
-
*
|
|
523
|
-
* <ng-template rdxNavigationMenuPortalPresence>…</ng-template>
|
|
524
|
-
* ```
|
|
497
|
+
* Dev-mode guard: `rdxNavigationMenuPortal` used to be an attribute directive on a `<div>`. It is now
|
|
498
|
+
* structural, so the old `<div rdxNavigationMenuPortal>` markup would silently stop portaling — fail
|
|
499
|
+
* loudly instead.
|
|
525
500
|
*/
|
|
526
|
-
class
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
501
|
+
class RdxNavigationMenuPortalMisuseGuard {
|
|
502
|
+
constructor() {
|
|
503
|
+
if (isDevMode()) {
|
|
504
|
+
rdxDevError('navigation-menu/portal-on-element', '`rdxNavigationMenuPortal` is now a structural directive. ' +
|
|
505
|
+
'Use `*rdxNavigationMenuPortal` on the positioner element or ' +
|
|
506
|
+
'`<ng-template rdxNavigationMenuPortal>`. rdxNavigationMenuPortalPresence has been removed.', 'components/navigation-menu');
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxNavigationMenuPortalMisuseGuard, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
510
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxNavigationMenuPortalMisuseGuard, isStandalone: true, selector: "[rdxNavigationMenuPortal]:not(ng-template)", ngImport: i0 }); }
|
|
534
511
|
}
|
|
535
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type:
|
|
512
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxNavigationMenuPortalMisuseGuard, decorators: [{
|
|
536
513
|
type: Directive,
|
|
537
514
|
args: [{
|
|
538
|
-
selector: 'ng-template
|
|
539
|
-
hostDirectives: [RdxPresenceDirective],
|
|
540
|
-
providers: [
|
|
541
|
-
provideRdxPresenceContext(() => {
|
|
542
|
-
const context = injectNavigationMenuRootContext();
|
|
543
|
-
return { present: context.isOpen };
|
|
544
|
-
})
|
|
545
|
-
]
|
|
515
|
+
selector: '[rdxNavigationMenuPortal]:not(ng-template)'
|
|
546
516
|
}]
|
|
547
|
-
}] });
|
|
517
|
+
}], ctorParameters: () => [] });
|
|
548
518
|
|
|
549
519
|
/**
|
|
550
520
|
* Positions the shared popup against the active trigger.
|
|
521
|
+
*
|
|
522
|
+
* A "thin" positioner (ADR 0012): it inherits the popper positioning surface (inputs, `placed`
|
|
523
|
+
* output, unified vars + placement attrs) from {@link RdxPopperContentWrapper} and adds the
|
|
524
|
+
* navigation-menu defaults, the open/closed/instant state attributes, and the grace-area hover
|
|
525
|
+
* bridge. It exposes no legacy `--radix-*` aliases.
|
|
551
526
|
*/
|
|
552
|
-
class RdxNavigationMenuPositioner {
|
|
527
|
+
class RdxNavigationMenuPositioner extends RdxPopperContentWrapper {
|
|
553
528
|
constructor() {
|
|
529
|
+
super();
|
|
554
530
|
this.rootContext = injectNavigationMenuRootContext();
|
|
555
|
-
this.
|
|
556
|
-
this.elementRef = inject(ElementRef);
|
|
531
|
+
this.containerRef = inject(ElementRef);
|
|
557
532
|
this.triggerEl = signal(null, ...(ngDevMode ? [{ debugName: "triggerEl" }] : /* istanbul ignore next */ []));
|
|
558
|
-
this.containerEl = signal(this.
|
|
533
|
+
this.containerEl = signal(this.containerRef.nativeElement, ...(ngDevMode ? [{ debugName: "containerEl" }] : /* istanbul ignore next */ []));
|
|
559
534
|
this.graceArea = useGraceArea(this.triggerEl, this.containerEl);
|
|
560
|
-
/**
|
|
561
|
-
* An element to position the popup against. Defaults to the active trigger.
|
|
562
|
-
*/
|
|
563
|
-
this.anchor = input(...(ngDevMode ? [undefined, { debugName: "anchor" }] : /* istanbul ignore next */ []));
|
|
564
|
-
/**
|
|
565
|
-
* The preferred side of the trigger to render against when open.
|
|
566
|
-
*/
|
|
567
|
-
this.side = input('bottom', ...(ngDevMode ? [{ debugName: "side" }] : /* istanbul ignore next */ []));
|
|
568
|
-
/**
|
|
569
|
-
* Distance between the trigger and the popup in pixels.
|
|
570
|
-
*/
|
|
571
|
-
this.sideOffset = input(0, { ...(ngDevMode ? { debugName: "sideOffset" } : /* istanbul ignore next */ {}), transform: numberAttribute });
|
|
572
|
-
/**
|
|
573
|
-
* How to align the popup relative to the specified side.
|
|
574
|
-
*/
|
|
575
|
-
this.align = input('center', ...(ngDevMode ? [{ debugName: "align" }] : /* istanbul ignore next */ []));
|
|
576
|
-
/**
|
|
577
|
-
* An offset in pixels from the `start` or `end` alignment options.
|
|
578
|
-
*/
|
|
579
|
-
this.alignOffset = input(0, { ...(ngDevMode ? { debugName: "alignOffset" } : /* istanbul ignore next */ {}), transform: numberAttribute });
|
|
580
|
-
/**
|
|
581
|
-
* Minimum distance to maintain between the arrow and the edges of the popup.
|
|
582
|
-
*/
|
|
583
|
-
this.arrowPadding = input(5, { ...(ngDevMode ? { debugName: "arrowPadding" } : /* istanbul ignore next */ {}), transform: numberAttribute });
|
|
584
|
-
/**
|
|
585
|
-
* Whether to override side and alignment preferences to prevent collisions.
|
|
586
|
-
*/
|
|
587
|
-
this.avoidCollisions = input(true, { ...(ngDevMode ? { debugName: "avoidCollisions" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
588
|
-
/**
|
|
589
|
-
* The element used as the collision boundary.
|
|
590
|
-
*/
|
|
591
|
-
this.collisionBoundary = input(...(ngDevMode ? [undefined, { debugName: "collisionBoundary" }] : /* istanbul ignore next */ []));
|
|
592
|
-
/**
|
|
593
|
-
* Distance in pixels from the boundary edges where collision detection should occur.
|
|
594
|
-
*/
|
|
595
|
-
this.collisionPadding = input(5, ...(ngDevMode ? [{ debugName: "collisionPadding" }] : /* istanbul ignore next */ []));
|
|
596
|
-
/**
|
|
597
|
-
* The sticky behavior on the alignment axis.
|
|
598
|
-
*/
|
|
599
|
-
this.sticky = input('partial', ...(ngDevMode ? [{ debugName: "sticky" }] : /* istanbul ignore next */ []));
|
|
600
|
-
/**
|
|
601
|
-
* Whether to hide the popup when the trigger becomes fully occluded.
|
|
602
|
-
*/
|
|
603
|
-
this.hideWhenDetached = input(false, { ...(ngDevMode ? { debugName: "hideWhenDetached" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
604
|
-
/**
|
|
605
|
-
* The CSS position strategy used by Floating UI.
|
|
606
|
-
*/
|
|
607
|
-
this.positionStrategy = input('fixed', ...(ngDevMode ? [{ debugName: "positionStrategy" }] : /* istanbul ignore next */ []));
|
|
608
|
-
/**
|
|
609
|
-
* Whether to update position on every animation frame.
|
|
610
|
-
*/
|
|
611
|
-
this.updatePositionStrategy = input('always', ...(ngDevMode ? [{ debugName: "updatePositionStrategy" }] : /* istanbul ignore next */ []));
|
|
612
535
|
effect(() => this.triggerEl.set(this.rootContext.trigger() ?? null));
|
|
613
536
|
// Keep the menu open while the pointer travels from the trigger to the popup; close once it
|
|
614
537
|
// leaves the grace area between them.
|
|
615
538
|
this.graceArea.onPointerExit(() => this.rootContext.closeOnHover());
|
|
616
539
|
}
|
|
617
540
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxNavigationMenuPositioner, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
618
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "
|
|
541
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxNavigationMenuPositioner, isStandalone: true, selector: "[rdxNavigationMenuPositioner]", host: { properties: { "attr.data-open": "rootContext.isOpen() ? \"\" : undefined", "attr.data-closed": "rootContext.isOpen() ? undefined : \"\"", "attr.data-instant": "rootContext.instant() ? \"\" : undefined" } }, providers: [
|
|
542
|
+
...provideRdxPopperContentWrapper(RdxNavigationMenuPositioner),
|
|
619
543
|
provideRdxPopperContentConfig({ arrowPadding: 5, collisionPadding: 5, updatePositionStrategy: 'always' })
|
|
620
|
-
],
|
|
544
|
+
], usesInheritance: true, ngImport: i0 }); }
|
|
621
545
|
}
|
|
622
546
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxNavigationMenuPositioner, decorators: [{
|
|
623
547
|
type: Directive,
|
|
624
548
|
args: [{
|
|
625
549
|
selector: '[rdxNavigationMenuPositioner]',
|
|
626
550
|
providers: [
|
|
551
|
+
...provideRdxPopperContentWrapper(RdxNavigationMenuPositioner),
|
|
627
552
|
provideRdxPopperContentConfig({ arrowPadding: 5, collisionPadding: 5, updatePositionStrategy: 'always' })
|
|
628
553
|
],
|
|
629
|
-
hostDirectives: [
|
|
630
|
-
{
|
|
631
|
-
directive: RdxPopperContentWrapper,
|
|
632
|
-
inputs: [
|
|
633
|
-
'anchor',
|
|
634
|
-
'side',
|
|
635
|
-
'sideOffset',
|
|
636
|
-
'align',
|
|
637
|
-
'alignOffset',
|
|
638
|
-
'arrowPadding',
|
|
639
|
-
'avoidCollisions',
|
|
640
|
-
'collisionBoundary',
|
|
641
|
-
'collisionPadding',
|
|
642
|
-
'sticky',
|
|
643
|
-
'hideWhenDetached',
|
|
644
|
-
'positionStrategy',
|
|
645
|
-
'updatePositionStrategy'
|
|
646
|
-
]
|
|
647
|
-
}
|
|
648
|
-
],
|
|
649
554
|
host: {
|
|
650
555
|
'[attr.data-open]': 'rootContext.isOpen() ? "" : undefined',
|
|
651
556
|
'[attr.data-closed]': 'rootContext.isOpen() ? undefined : ""',
|
|
652
|
-
'[attr.data-
|
|
653
|
-
'[attr.data-align]': 'wrapper.placedAlign()',
|
|
654
|
-
'[attr.data-side]': 'wrapper.placedSide()',
|
|
655
|
-
'[attr.data-instant]': 'rootContext.instant() ? "" : undefined',
|
|
656
|
-
'[style]': `{
|
|
657
|
-
'--anchor-width': 'var(--radix-popper-anchor-width)',
|
|
658
|
-
'--anchor-height': 'var(--radix-popper-anchor-height)',
|
|
659
|
-
'--available-width': 'var(--radix-popper-available-width)',
|
|
660
|
-
'--available-height': 'var(--radix-popper-available-height)',
|
|
661
|
-
'--positioner-width': 'var(--radix-popper-content-wrapper-width)',
|
|
662
|
-
'--positioner-height': 'var(--radix-popper-content-wrapper-height)',
|
|
663
|
-
'--transform-origin': 'var(--radix-popper-transform-origin)'
|
|
664
|
-
}`
|
|
557
|
+
'[attr.data-instant]': 'rootContext.instant() ? "" : undefined'
|
|
665
558
|
}
|
|
666
559
|
}]
|
|
667
|
-
}], ctorParameters: () => []
|
|
560
|
+
}], ctorParameters: () => [] });
|
|
668
561
|
|
|
669
562
|
const context = () => contextFor(inject(RdxNavigationMenuRoot));
|
|
670
563
|
/**
|
|
@@ -679,6 +572,12 @@ class RdxNavigationMenuRoot {
|
|
|
679
572
|
this.popper = inject(RdxPopper);
|
|
680
573
|
this.destroyRef = inject(DestroyRef);
|
|
681
574
|
this.parentRoot = inject(RdxNavigationMenuRoot, { optional: true, skipSelf: true });
|
|
575
|
+
this.registration = inject(RDX_FLOATING_REGISTRATION, { optional: true });
|
|
576
|
+
/** Per-popup floating root context (ADR 0015) — `open` / `triggers` / reference for the dismissal engine. */
|
|
577
|
+
this.floatingContext = createFloatingRootContext({
|
|
578
|
+
ownerDocument: inject(ElementRef).nativeElement.ownerDocument,
|
|
579
|
+
open: () => this.isOpen()
|
|
580
|
+
});
|
|
682
581
|
/** Whether this root is nested inside another navigation menu's content. */
|
|
683
582
|
this.nested = !!this.parentRoot;
|
|
684
583
|
this.baseId = `rdx-nav-menu-${generateId()}`;
|
|
@@ -697,7 +596,8 @@ class RdxNavigationMenuRoot {
|
|
|
697
596
|
/**
|
|
698
597
|
* The reading direction of the navigation menu.
|
|
699
598
|
*/
|
|
700
|
-
this.
|
|
599
|
+
this.dirInput = input(undefined, { ...(ngDevMode ? { debugName: "dirInput" } : /* istanbul ignore next */ {}), alias: 'dir' });
|
|
600
|
+
this.dir = injectDirection(this.dirInput);
|
|
701
601
|
/**
|
|
702
602
|
* Whether keyboard navigation loops from the last item back to the first and vice versa.
|
|
703
603
|
*/
|
|
@@ -731,6 +631,8 @@ class RdxNavigationMenuRoot {
|
|
|
731
631
|
this.transitionStatus = this.transition.status;
|
|
732
632
|
this.previousValue = signal(null, ...(ngDevMode ? [{ debugName: "previousValue" }] : /* istanbul ignore next */ []));
|
|
733
633
|
this.isOpen = computed(() => this.value() !== null, ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
|
|
634
|
+
this.preventUnmountOnClose = signal(false, ...(ngDevMode ? [{ debugName: "preventUnmountOnClose" }] : /* istanbul ignore next */ []));
|
|
635
|
+
this.present = computed(() => this.isOpen() || this.preventUnmountOnClose(), ...(ngDevMode ? [{ debugName: "present" }] : /* istanbul ignore next */ []));
|
|
734
636
|
this.trigger = signal(undefined, ...(ngDevMode ? [{ debugName: "trigger" }] : /* istanbul ignore next */ []));
|
|
735
637
|
this.triggers = signal([], ...(ngDevMode ? [{ debugName: "triggers" }] : /* istanbul ignore next */ []));
|
|
736
638
|
this.contents = signal(new Map(), ...(ngDevMode ? [{ debugName: "contents" }] : /* istanbul ignore next */ []));
|
|
@@ -757,6 +659,9 @@ class RdxNavigationMenuRoot {
|
|
|
757
659
|
});
|
|
758
660
|
// Anchor the shared popper to the active trigger.
|
|
759
661
|
effect(() => this.popper.anchorOverride.set(this.trigger()));
|
|
662
|
+
// Keep the dismissal reference in sync with the active trigger (the anchor) so a press / focus on
|
|
663
|
+
// it counts as "inside" (ADR 0015). The full trigger registry is maintained in `registerTrigger`.
|
|
664
|
+
effect(() => this.floatingContext.setReferenceElement(this.trigger() ?? null));
|
|
760
665
|
this.destroyRef.onDestroy(() => {
|
|
761
666
|
this.clearHoverTimers();
|
|
762
667
|
if (this.instantFrame !== undefined) {
|
|
@@ -778,6 +683,11 @@ class RdxNavigationMenuRoot {
|
|
|
778
683
|
const previousTrigger = this.trigger();
|
|
779
684
|
const nextTrigger = value ? this.registeredTriggers.get(value) : undefined;
|
|
780
685
|
const changedTriggerWhileOpen = previous !== null && value !== null && previousTrigger !== nextTrigger;
|
|
686
|
+
const change = this.createOpenChangeEvent(value, reason, event, nextTrigger ?? previousTrigger);
|
|
687
|
+
this.onOpenChange.emit(change.payload);
|
|
688
|
+
if (change.eventDetails.isCanceled()) {
|
|
689
|
+
return;
|
|
690
|
+
}
|
|
781
691
|
this.instant.set(changedTriggerWhileOpen || reason === 'trigger-focus');
|
|
782
692
|
if (changedTriggerWhileOpen) {
|
|
783
693
|
this.scheduleInstantReset();
|
|
@@ -789,9 +699,9 @@ class RdxNavigationMenuRoot {
|
|
|
789
699
|
this.trigger.set(nextTrigger);
|
|
790
700
|
}
|
|
791
701
|
this.previousValue.set(previous);
|
|
702
|
+
this.preventUnmountOnClose.set(value === null ? change.shouldPreventUnmountOnClose() : false);
|
|
792
703
|
this.value.set(value);
|
|
793
704
|
this.onValueChange.emit(value);
|
|
794
|
-
this.onOpenChange.emit({ value, open: value !== null, reason, event });
|
|
795
705
|
}
|
|
796
706
|
open(value, trigger, reason = 'none', event) {
|
|
797
707
|
this.clearHoverTimers();
|
|
@@ -828,7 +738,11 @@ class RdxNavigationMenuRoot {
|
|
|
828
738
|
}
|
|
829
739
|
this.openTimer = setTimeout(() => this.open(value, trigger, 'trigger-hover', event), this.delay());
|
|
830
740
|
}
|
|
831
|
-
closeOnHover() {
|
|
741
|
+
closeOnHover(event) {
|
|
742
|
+
if (event && this.isInsideOpenChild(event.relatedTarget)) {
|
|
743
|
+
this.cancelHoverClose();
|
|
744
|
+
return;
|
|
745
|
+
}
|
|
832
746
|
this.clearOpenTimer();
|
|
833
747
|
this.clearCloseTimer();
|
|
834
748
|
this.closeTimer = setTimeout(() => this.close('list-leave', new Event('navigation-menu.hover-close')), this.closeDelay());
|
|
@@ -842,6 +756,9 @@ class RdxNavigationMenuRoot {
|
|
|
842
756
|
registerTrigger(value, trigger) {
|
|
843
757
|
this.registeredTriggers.set(value, trigger);
|
|
844
758
|
this.triggers.update((triggers) => (triggers.includes(trigger) ? triggers : [...triggers, trigger]));
|
|
759
|
+
// Mark every trigger as "inside" the floating layer (ADR 0015): a press / focus on a sibling
|
|
760
|
+
// trigger (to switch items) or back on the active trigger must not count as an outside dismissal.
|
|
761
|
+
this.floatingContext.triggers.add(trigger);
|
|
845
762
|
if (this.value() === value) {
|
|
846
763
|
this.trigger.set(trigger);
|
|
847
764
|
}
|
|
@@ -850,6 +767,7 @@ class RdxNavigationMenuRoot {
|
|
|
850
767
|
this.registeredTriggers.delete(value);
|
|
851
768
|
}
|
|
852
769
|
this.triggers.update((triggers) => triggers.filter((candidate) => candidate !== trigger));
|
|
770
|
+
this.floatingContext.triggers.delete(trigger);
|
|
853
771
|
if (this.destroyRef.destroyed || this.value() !== value) {
|
|
854
772
|
return;
|
|
855
773
|
}
|
|
@@ -888,6 +806,9 @@ class RdxNavigationMenuRoot {
|
|
|
888
806
|
this.viewportTriggerChange.add(onTriggerChange);
|
|
889
807
|
return () => this.viewportTriggerChange.delete(onTriggerChange);
|
|
890
808
|
}
|
|
809
|
+
createOpenChangeEvent(value, reason, event, trigger) {
|
|
810
|
+
return createNavigationMenuOpenChangeEvent(value, reason, event, trigger);
|
|
811
|
+
}
|
|
891
812
|
scheduleInstantReset() {
|
|
892
813
|
if (this.instantFrame !== undefined) {
|
|
893
814
|
cancelAnimationFrame(this.instantFrame);
|
|
@@ -915,16 +836,48 @@ class RdxNavigationMenuRoot {
|
|
|
915
836
|
this.closeTimer = undefined;
|
|
916
837
|
}
|
|
917
838
|
}
|
|
839
|
+
isInsideOpenChild(target) {
|
|
840
|
+
if (!(target instanceof Node)) {
|
|
841
|
+
return false;
|
|
842
|
+
}
|
|
843
|
+
const node = this.registration?.node();
|
|
844
|
+
if (!node) {
|
|
845
|
+
return false;
|
|
846
|
+
}
|
|
847
|
+
return node.tree.children(node, { onlyOpen: true }).some((child) => {
|
|
848
|
+
const context = child.context;
|
|
849
|
+
const floating = context?.floatingElement;
|
|
850
|
+
return !!floating && floating.contains(target);
|
|
851
|
+
});
|
|
852
|
+
}
|
|
918
853
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxNavigationMenuRoot, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
919
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxNavigationMenuRoot, isStandalone: true, selector: "[rdxNavigationMenuRoot]", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, defaultValue: { classPropertyName: "defaultValue", publicName: "defaultValue", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null },
|
|
854
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxNavigationMenuRoot, isStandalone: true, selector: "[rdxNavigationMenuRoot]", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, defaultValue: { classPropertyName: "defaultValue", publicName: "defaultValue", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, dirInput: { classPropertyName: "dirInput", publicName: "dir", isSignal: true, isRequired: false, transformFunction: null }, loop: { classPropertyName: "loop", publicName: "loop", isSignal: true, isRequired: false, transformFunction: null }, delay: { classPropertyName: "delay", publicName: "delay", isSignal: true, isRequired: false, transformFunction: null }, closeDelay: { classPropertyName: "closeDelay", publicName: "closeDelay", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", onValueChange: "onValueChange", onOpenChange: "onOpenChange", onOpenChangeComplete: "onOpenChangeComplete" }, host: { attributes: { "role": "navigation", "aria-label": "Main" }, properties: { "attr.data-orientation": "orientation()", "attr.dir": "dir()" } }, providers: [
|
|
855
|
+
provideNavigationMenuRootContext(context),
|
|
856
|
+
// Base UI wraps every NavigationMenu.Root in a FloatingNode and only creates FloatingTree at the
|
|
857
|
+
// top boundary. `provideFloatingTree()` is inherit-or-create, so nested navigation menus join the
|
|
858
|
+
// parent's tree while the top-level menu starts the coordination store.
|
|
859
|
+
provideFloatingTree(),
|
|
860
|
+
// New floating foundation (ADR 0015/0017) — dismissal reads this shared root context, while the
|
|
861
|
+
// root-level node above gives nested navigation menus real parent/child ownership.
|
|
862
|
+
provideFloatingRootContext(() => inject(RdxNavigationMenuRoot).floatingContext)
|
|
863
|
+
], exportAs: ["rdxNavigationMenuRoot"], hostDirectives: [{ directive: i1.RdxPopper }, { directive: i2.RdxFloatingNodeRegistration }], ngImport: i0 }); }
|
|
920
864
|
}
|
|
921
865
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxNavigationMenuRoot, decorators: [{
|
|
922
866
|
type: Directive,
|
|
923
867
|
args: [{
|
|
924
868
|
selector: '[rdxNavigationMenuRoot]',
|
|
925
869
|
exportAs: 'rdxNavigationMenuRoot',
|
|
926
|
-
providers: [
|
|
927
|
-
|
|
870
|
+
providers: [
|
|
871
|
+
provideNavigationMenuRootContext(context),
|
|
872
|
+
// Base UI wraps every NavigationMenu.Root in a FloatingNode and only creates FloatingTree at the
|
|
873
|
+
// top boundary. `provideFloatingTree()` is inherit-or-create, so nested navigation menus join the
|
|
874
|
+
// parent's tree while the top-level menu starts the coordination store.
|
|
875
|
+
provideFloatingTree(),
|
|
876
|
+
// New floating foundation (ADR 0015/0017) — dismissal reads this shared root context, while the
|
|
877
|
+
// root-level node above gives nested navigation menus real parent/child ownership.
|
|
878
|
+
provideFloatingRootContext(() => inject(RdxNavigationMenuRoot).floatingContext)
|
|
879
|
+
],
|
|
880
|
+
hostDirectives: [RdxPopper, RdxFloatingNodeRegistration],
|
|
928
881
|
host: {
|
|
929
882
|
role: 'navigation',
|
|
930
883
|
'aria-label': 'Main',
|
|
@@ -932,7 +885,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
932
885
|
'[attr.dir]': 'dir()'
|
|
933
886
|
}
|
|
934
887
|
}]
|
|
935
|
-
}], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], defaultValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValue", required: false }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }],
|
|
888
|
+
}], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], defaultValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValue", required: false }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], dirInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "dir", required: false }] }], loop: [{ type: i0.Input, args: [{ isSignal: true, alias: "loop", required: false }] }], delay: [{ type: i0.Input, args: [{ isSignal: true, alias: "delay", required: false }] }], closeDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeDelay", required: false }] }], onValueChange: [{ type: i0.Output, args: ["onValueChange"] }], onOpenChange: [{ type: i0.Output, args: ["onOpenChange"] }], onOpenChangeComplete: [{ type: i0.Output, args: ["onOpenChangeComplete"] }] } });
|
|
936
889
|
function contextFor(root) {
|
|
937
890
|
return {
|
|
938
891
|
nested: root.nested,
|
|
@@ -943,6 +896,7 @@ function contextFor(root) {
|
|
|
943
896
|
value: root.value,
|
|
944
897
|
previousValue: root.previousValue.asReadonly(),
|
|
945
898
|
isOpen: root.isOpen,
|
|
899
|
+
present: root.present,
|
|
946
900
|
instant: root.instant.asReadonly(),
|
|
947
901
|
transitionStatus: root.transitionStatus,
|
|
948
902
|
trigger: root.trigger.asReadonly(),
|
|
@@ -955,7 +909,7 @@ function contextFor(root) {
|
|
|
955
909
|
close: (reason, event) => root.close(reason, event),
|
|
956
910
|
toggle: (value, trigger, event) => root.toggle(value, trigger, event),
|
|
957
911
|
openOnHover: (value, trigger, event) => root.openOnHover(value, trigger, event),
|
|
958
|
-
closeOnHover: () => root.closeOnHover(),
|
|
912
|
+
closeOnHover: (event) => root.closeOnHover(event),
|
|
959
913
|
cancelHoverOpen: () => root.cancelHoverOpen(),
|
|
960
914
|
cancelHoverClose: () => root.cancelHoverClose(),
|
|
961
915
|
registerTrigger: (value, trigger) => root.registerTrigger(value, trigger),
|
|
@@ -964,6 +918,21 @@ function contextFor(root) {
|
|
|
964
918
|
registerViewport: (onTriggerChange) => root.registerViewport(onTriggerChange)
|
|
965
919
|
};
|
|
966
920
|
}
|
|
921
|
+
function createNavigationMenuOpenChangeEvent(value, reason, event, trigger) {
|
|
922
|
+
const change = createCancelableChangeEventDetails(reason, event, trigger);
|
|
923
|
+
return {
|
|
924
|
+
payload: {
|
|
925
|
+
value,
|
|
926
|
+
open: value !== null,
|
|
927
|
+
reason,
|
|
928
|
+
event: change.eventDetails.event,
|
|
929
|
+
trigger,
|
|
930
|
+
eventDetails: change.eventDetails
|
|
931
|
+
},
|
|
932
|
+
eventDetails: change.eventDetails,
|
|
933
|
+
shouldPreventUnmountOnClose: change.shouldPreventUnmountOnClose
|
|
934
|
+
};
|
|
935
|
+
}
|
|
967
936
|
|
|
968
937
|
/**
|
|
969
938
|
* A button that opens its item's content in the shared popup.
|
|
@@ -1248,7 +1217,7 @@ const navigationMenuImports = [
|
|
|
1248
1217
|
RdxNavigationMenuContent,
|
|
1249
1218
|
RdxNavigationMenuLink,
|
|
1250
1219
|
RdxNavigationMenuPortal,
|
|
1251
|
-
|
|
1220
|
+
RdxNavigationMenuPortalMisuseGuard,
|
|
1252
1221
|
RdxNavigationMenuBackdrop,
|
|
1253
1222
|
RdxNavigationMenuPositioner,
|
|
1254
1223
|
RdxNavigationMenuPopup,
|
|
@@ -1265,7 +1234,7 @@ class RdxNavigationMenuModule {
|
|
|
1265
1234
|
RdxNavigationMenuContent,
|
|
1266
1235
|
RdxNavigationMenuLink,
|
|
1267
1236
|
RdxNavigationMenuPortal,
|
|
1268
|
-
|
|
1237
|
+
RdxNavigationMenuPortalMisuseGuard,
|
|
1269
1238
|
RdxNavigationMenuBackdrop,
|
|
1270
1239
|
RdxNavigationMenuPositioner,
|
|
1271
1240
|
RdxNavigationMenuPopup,
|
|
@@ -1278,7 +1247,7 @@ class RdxNavigationMenuModule {
|
|
|
1278
1247
|
RdxNavigationMenuContent,
|
|
1279
1248
|
RdxNavigationMenuLink,
|
|
1280
1249
|
RdxNavigationMenuPortal,
|
|
1281
|
-
|
|
1250
|
+
RdxNavigationMenuPortalMisuseGuard,
|
|
1282
1251
|
RdxNavigationMenuBackdrop,
|
|
1283
1252
|
RdxNavigationMenuPositioner,
|
|
1284
1253
|
RdxNavigationMenuPopup,
|
|
@@ -1298,5 +1267,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
1298
1267
|
* Generated bundle index. Do not edit.
|
|
1299
1268
|
*/
|
|
1300
1269
|
|
|
1301
|
-
export { RdxNavigationMenuArrow, RdxNavigationMenuBackdrop, RdxNavigationMenuContent, RdxNavigationMenuIcon, RdxNavigationMenuItem, RdxNavigationMenuLink, RdxNavigationMenuList, RdxNavigationMenuModule, RdxNavigationMenuPopup, RdxNavigationMenuPortal,
|
|
1270
|
+
export { RdxNavigationMenuArrow, RdxNavigationMenuBackdrop, RdxNavigationMenuContent, RdxNavigationMenuIcon, RdxNavigationMenuItem, RdxNavigationMenuLink, RdxNavigationMenuList, RdxNavigationMenuModule, RdxNavigationMenuPopup, RdxNavigationMenuPortal, RdxNavigationMenuPortalMisuseGuard, RdxNavigationMenuPositioner, RdxNavigationMenuRoot, RdxNavigationMenuTrigger, RdxNavigationMenuViewport, injectNavigationMenuRootContext, navigationMenuImports, provideNavigationMenuRootContext };
|
|
1302
1271
|
//# sourceMappingURL=radix-ng-primitives-navigation-menu.mjs.map
|