@radix-ng/primitives 1.0.1 → 1.0.3
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/composite/README.md +1 -1
- package/fesm2022/radix-ng-primitives-accordion.mjs +18 -36
- package/fesm2022/radix-ng-primitives-accordion.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-checkbox.mjs +134 -58
- package/fesm2022/radix-ng-primitives-checkbox.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-collapsible.mjs +113 -64
- package/fesm2022/radix-ng-primitives-collapsible.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-composite.mjs +127 -43
- package/fesm2022/radix-ng-primitives-composite.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-menu.mjs +288 -63
- package/fesm2022/radix-ng-primitives-menu.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-menubar.mjs +24 -1
- package/fesm2022/radix-ng-primitives-menubar.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-select.mjs +56 -29
- package/fesm2022/radix-ng-primitives-select.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-slider.mjs +57 -13
- package/fesm2022/radix-ng-primitives-slider.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-tabs.mjs +292 -59
- package/fesm2022/radix-ng-primitives-tabs.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-toolbar.mjs +19 -13
- package/fesm2022/radix-ng-primitives-toolbar.mjs.map +1 -1
- package/package.json +2 -10
- package/types/radix-ng-primitives-accordion.d.ts +7 -15
- package/types/radix-ng-primitives-checkbox.d.ts +98 -70
- package/types/radix-ng-primitives-collapsible.d.ts +44 -24
- package/types/radix-ng-primitives-composite.d.ts +58 -15
- package/types/radix-ng-primitives-menu.d.ts +44 -16
- package/types/radix-ng-primitives-menubar.d.ts +2 -0
- package/types/radix-ng-primitives-select.d.ts +46 -32
- package/types/radix-ng-primitives-slider.d.ts +19 -4
- package/types/radix-ng-primitives-tabs.d.ts +63 -11
- package/types/radix-ng-primitives-toolbar.d.ts +80 -73
- package/collection/README.md +0 -1
- package/fesm2022/radix-ng-primitives-collection.mjs +0 -72
- package/fesm2022/radix-ng-primitives-collection.mjs.map +0 -1
- package/fesm2022/radix-ng-primitives-roving-focus.mjs +0 -420
- package/fesm2022/radix-ng-primitives-roving-focus.mjs.map +0 -1
- package/roving-focus/README.md +0 -3
- package/types/radix-ng-primitives-collection.d.ts +0 -44
- package/types/radix-ng-primitives-roving-focus.d.ts +0 -201
|
@@ -7,33 +7,83 @@ import { createContext, createFloatingRootContext, useTransitionStatus, createCa
|
|
|
7
7
|
import { injectDirection } from '@radix-ng/primitives/direction-provider';
|
|
8
8
|
import * as i3 from '@radix-ng/primitives/floating-focus-manager';
|
|
9
9
|
import { getInteractionTypeFromEvent, RdxFloatingFocusManager, provideFloatingFocusManagerConfig, createRdxTriggerInteraction, useTriggerFocusGuards } from '@radix-ng/primitives/floating-focus-manager';
|
|
10
|
+
import * as i1$1 from '@radix-ng/primitives/composite';
|
|
11
|
+
import { isElementVisible, RdxCompositeListItem, RdxCompositeList } from '@radix-ng/primitives/composite';
|
|
10
12
|
import { outputFromObservable, outputToObservable } from '@angular/core/rxjs-interop';
|
|
11
13
|
import { RdxDismiss } from '@radix-ng/primitives/dismissable-layer';
|
|
12
14
|
import { RdxFocusScope } from '@radix-ng/primitives/focus-scope';
|
|
13
|
-
import * as i1$
|
|
15
|
+
import * as i1$2 from '@radix-ng/primitives/portal';
|
|
14
16
|
import { RdxPortalPresence } from '@radix-ng/primitives/portal';
|
|
15
17
|
import { provideRdxPresenceContext } from '@radix-ng/primitives/presence';
|
|
16
18
|
import { isPlatformBrowser } from '@angular/common';
|
|
17
|
-
import * as i2$1 from '@radix-ng/primitives/composite';
|
|
18
|
-
import { RdxCompositeItem } from '@radix-ng/primitives/composite';
|
|
19
19
|
|
|
20
|
-
/** Selector for
|
|
20
|
+
/** Selector for menu items within a popup. Disabled items stay focusable to match Base UI. */
|
|
21
21
|
const RDX_MENU_ITEM_SELECTOR = [
|
|
22
|
-
'[rdxMenuItem]
|
|
23
|
-
'[rdxMenuCheckboxItem]
|
|
24
|
-
'[rdxMenuRadioItem]
|
|
25
|
-
'[rdxMenuLinkItem]
|
|
26
|
-
'[rdxMenuSubTrigger]
|
|
22
|
+
'[rdxMenuItem]',
|
|
23
|
+
'[rdxMenuCheckboxItem]',
|
|
24
|
+
'[rdxMenuRadioItem]',
|
|
25
|
+
'[rdxMenuLinkItem]',
|
|
26
|
+
'[rdxMenuSubTrigger]'
|
|
27
27
|
].join(',');
|
|
28
28
|
function getFocusableMenuItems(popup) {
|
|
29
29
|
return Array.from(popup.querySelectorAll(RDX_MENU_ITEM_SELECTOR)).filter((item) => item.closest('[rdxMenuPopup]') === popup);
|
|
30
30
|
}
|
|
31
|
+
function getCompositeMenuItems(list) {
|
|
32
|
+
const map = list.itemMap();
|
|
33
|
+
return list
|
|
34
|
+
.items()
|
|
35
|
+
.map(({ element }) => {
|
|
36
|
+
const metadata = map.get(element);
|
|
37
|
+
if (!metadata || !isElementVisible(element)) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
element,
|
|
42
|
+
index: metadata.index,
|
|
43
|
+
label: getMenuItemLabel(element, metadata),
|
|
44
|
+
metadata
|
|
45
|
+
};
|
|
46
|
+
})
|
|
47
|
+
.filter((item) => item !== null);
|
|
48
|
+
}
|
|
49
|
+
function getDomMenuItems(popup) {
|
|
50
|
+
return getFocusableMenuItems(popup).map((element, index) => ({
|
|
51
|
+
element,
|
|
52
|
+
index,
|
|
53
|
+
label: getMenuItemLabel(element),
|
|
54
|
+
metadata: {
|
|
55
|
+
index,
|
|
56
|
+
type: getMenuItemType(element),
|
|
57
|
+
disabled: element.hasAttribute('data-disabled'),
|
|
58
|
+
label: element.dataset['label']
|
|
59
|
+
}
|
|
60
|
+
}));
|
|
61
|
+
}
|
|
62
|
+
function getMenuItemLabel(element, metadata) {
|
|
63
|
+
return (metadata?.label ?? element.dataset['label'] ?? element.textContent?.trim() ?? '').toLowerCase();
|
|
64
|
+
}
|
|
65
|
+
function getMenuItemType(element) {
|
|
66
|
+
if (element.hasAttribute('rdxMenuCheckboxItem')) {
|
|
67
|
+
return 'checkbox-item';
|
|
68
|
+
}
|
|
69
|
+
if (element.hasAttribute('rdxMenuRadioItem')) {
|
|
70
|
+
return 'radio-item';
|
|
71
|
+
}
|
|
72
|
+
if (element.hasAttribute('rdxMenuLinkItem')) {
|
|
73
|
+
return 'link-item';
|
|
74
|
+
}
|
|
75
|
+
if (element.hasAttribute('rdxMenuSubTrigger')) {
|
|
76
|
+
return 'submenu-trigger';
|
|
77
|
+
}
|
|
78
|
+
return 'regular-item';
|
|
79
|
+
}
|
|
31
80
|
|
|
32
81
|
const [injectRdxMenuRootContext, provideRdxMenuRootContext] = createContext('RdxMenuRootContext', 'components/menu');
|
|
33
82
|
function buildContext(instance) {
|
|
34
83
|
return {
|
|
35
84
|
isOpen: instance.open,
|
|
36
85
|
present: instance.present,
|
|
86
|
+
activeIndex: instance.activeIndex.asReadonly(),
|
|
37
87
|
disabled: instance.effectiveDisabled,
|
|
38
88
|
modal: instance.effectiveModal,
|
|
39
89
|
loopFocus: instance.loopFocus,
|
|
@@ -55,6 +105,7 @@ function buildContext(instance) {
|
|
|
55
105
|
beforeContentFocusGuard: instance.beforeContentFocusGuard.asReadonly(),
|
|
56
106
|
transitionStatus: instance.transitionStatus,
|
|
57
107
|
close: (reason, event) => instance.close(reason, event),
|
|
108
|
+
setActiveIndex: (index) => instance.setActiveIndex(index),
|
|
58
109
|
closeEntireMenu: (reason, event) => instance.closeEntireMenu(reason, event),
|
|
59
110
|
toggle: (reason, event) => instance.toggle(reason, event),
|
|
60
111
|
show: (autoFocus, reason, event) => instance.show(autoFocus, reason, event),
|
|
@@ -123,6 +174,7 @@ class RdxMenuRoot {
|
|
|
123
174
|
this.popupElement = signal(undefined, ...(ngDevMode ? [{ debugName: "popupElement" }] : /* istanbul ignore next */ []));
|
|
124
175
|
this.beforeContentFocusGuard = signal(null, ...(ngDevMode ? [{ debugName: "beforeContentFocusGuard" }] : /* istanbul ignore next */ []));
|
|
125
176
|
this.transitionStatus = this.transition.status;
|
|
177
|
+
this.activeIndex = signal(null, ...(ngDevMode ? [{ debugName: "activeIndex" }] : /* istanbul ignore next */ []));
|
|
126
178
|
/** Whether the popup grabs focus when it opens. Set false for menubar hover-switching. */
|
|
127
179
|
this.autoFocus = signal('first', ...(ngDevMode ? [{ debugName: "autoFocus" }] : /* istanbul ignore next */ []));
|
|
128
180
|
this.isSubmenu = signal(false, ...(ngDevMode ? [{ debugName: "isSubmenu" }] : /* istanbul ignore next */ []));
|
|
@@ -178,6 +230,11 @@ class RdxMenuRoot {
|
|
|
178
230
|
this.preventUnmountOnClose.set(false);
|
|
179
231
|
}
|
|
180
232
|
});
|
|
233
|
+
effect(() => {
|
|
234
|
+
if (!this.open()) {
|
|
235
|
+
this.activeIndex.set(null);
|
|
236
|
+
}
|
|
237
|
+
});
|
|
181
238
|
let previousOpen = this.open();
|
|
182
239
|
effect(() => {
|
|
183
240
|
const open = this.open();
|
|
@@ -244,6 +301,14 @@ class RdxMenuRoot {
|
|
|
244
301
|
markAsContextMenu() {
|
|
245
302
|
this.isContextMenu.set(true);
|
|
246
303
|
}
|
|
304
|
+
setActiveIndex(index) {
|
|
305
|
+
if (this.effectiveDisabled() && index !== null) {
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
if (this.activeIndex() !== index) {
|
|
309
|
+
this.activeIndex.set(index);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
247
312
|
setAllowMouseUpTrigger(value) {
|
|
248
313
|
if (this.parentRoot) {
|
|
249
314
|
this.parentRoot.setAllowMouseUpTrigger(value);
|
|
@@ -338,6 +403,7 @@ class RdxMenuRoot {
|
|
|
338
403
|
return;
|
|
339
404
|
}
|
|
340
405
|
if (autoFocus === 'popup') {
|
|
406
|
+
this.setActiveIndex(null);
|
|
341
407
|
popup.focus({ preventScroll: true });
|
|
342
408
|
return;
|
|
343
409
|
}
|
|
@@ -448,6 +514,7 @@ const checkboxItemContextFactory = () => {
|
|
|
448
514
|
class RdxMenuCheckboxItem {
|
|
449
515
|
constructor() {
|
|
450
516
|
this.rootContext = injectRdxMenuRootContext(true);
|
|
517
|
+
this.listItem = inject(RdxCompositeListItem, { self: true });
|
|
451
518
|
this.elementRef = inject(ElementRef);
|
|
452
519
|
this.isFocused = signal(false, ...(ngDevMode ? [{ debugName: "isFocused" }] : /* istanbul ignore next */ []));
|
|
453
520
|
/** Whether this item is disabled. */
|
|
@@ -460,19 +527,28 @@ class RdxMenuCheckboxItem {
|
|
|
460
527
|
this.checked = model(false, ...(ngDevMode ? [{ debugName: "checked" }] : /* istanbul ignore next */ []));
|
|
461
528
|
/** Emits when the checked state changes. */
|
|
462
529
|
this.onCheckedChange = output();
|
|
463
|
-
this.highlighted = computed(() => this.isFocused(), ...(ngDevMode ? [{ debugName: "highlighted" }] : /* istanbul ignore next */ []));
|
|
530
|
+
this.highlighted = computed(() => this.rootContext?.activeIndex() === this.listItem.index() || this.isFocused(), ...(ngDevMode ? [{ debugName: "highlighted" }] : /* istanbul ignore next */ []));
|
|
464
531
|
this.effectiveDisabled = computed(() => this.disabled() || (this.rootContext?.disabled() ?? false), ...(ngDevMode ? [{ debugName: "effectiveDisabled" }] : /* istanbul ignore next */ []));
|
|
465
532
|
// Expose helpers for host bindings
|
|
466
533
|
this.isIndeterminate = isIndeterminate;
|
|
467
534
|
this.getCheckedState = getCheckedState;
|
|
535
|
+
effect(() => {
|
|
536
|
+
this.listItem.setMetadata({
|
|
537
|
+
type: 'checkbox-item',
|
|
538
|
+
disabled: this.effectiveDisabled(),
|
|
539
|
+
label: this.label()
|
|
540
|
+
});
|
|
541
|
+
});
|
|
468
542
|
}
|
|
469
543
|
onFocus() {
|
|
470
|
-
if (!this.
|
|
544
|
+
if (!this.rootContext?.disabled()) {
|
|
471
545
|
this.isFocused.set(true);
|
|
472
546
|
}
|
|
547
|
+
this.setActiveIndex();
|
|
473
548
|
}
|
|
474
549
|
onBlur() {
|
|
475
550
|
this.isFocused.set(false);
|
|
551
|
+
this.clearActiveIndex();
|
|
476
552
|
}
|
|
477
553
|
onPointerMove(event) {
|
|
478
554
|
if (event.defaultPrevented || event.pointerType !== 'mouse' || this.effectiveDisabled()) {
|
|
@@ -481,6 +557,7 @@ class RdxMenuCheckboxItem {
|
|
|
481
557
|
if (this.rootContext && !this.rootContext.highlightItemOnHover()) {
|
|
482
558
|
return;
|
|
483
559
|
}
|
|
560
|
+
this.setActiveIndex();
|
|
484
561
|
if (this.elementRef.nativeElement.ownerDocument.activeElement !== this.elementRef.nativeElement) {
|
|
485
562
|
this.elementRef.nativeElement.focus({ preventScroll: true });
|
|
486
563
|
}
|
|
@@ -490,6 +567,8 @@ class RdxMenuCheckboxItem {
|
|
|
490
567
|
return;
|
|
491
568
|
}
|
|
492
569
|
if (this.elementRef.nativeElement.ownerDocument.activeElement === this.elementRef.nativeElement) {
|
|
570
|
+
this.isFocused.set(false);
|
|
571
|
+
this.clearActiveIndex();
|
|
493
572
|
this.elementRef.nativeElement.closest('[rdxMenuPopup]')?.focus({ preventScroll: true });
|
|
494
573
|
}
|
|
495
574
|
}
|
|
@@ -520,8 +599,22 @@ class RdxMenuCheckboxItem {
|
|
|
520
599
|
this.checked.set(next);
|
|
521
600
|
this.onCheckedChange.emit(next);
|
|
522
601
|
}
|
|
602
|
+
setActiveIndex() {
|
|
603
|
+
if (!this.rootContext || this.rootContext.disabled()) {
|
|
604
|
+
return;
|
|
605
|
+
}
|
|
606
|
+
const index = this.listItem.index();
|
|
607
|
+
if (index !== -1) {
|
|
608
|
+
this.rootContext.setActiveIndex(index);
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
clearActiveIndex() {
|
|
612
|
+
if (this.rootContext?.activeIndex() === this.listItem.index()) {
|
|
613
|
+
this.rootContext.setActiveIndex(null);
|
|
614
|
+
}
|
|
615
|
+
}
|
|
523
616
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxMenuCheckboxItem, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
524
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxMenuCheckboxItem, isStandalone: true, selector: "[rdxMenuCheckboxItem]", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, closeOnClick: { classPropertyName: "closeOnClick", publicName: "closeOnClick", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checked: "checkedChange", onCheckedChange: "onCheckedChange" }, host: { attributes: { "role": "menuitemcheckbox"
|
|
617
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxMenuCheckboxItem, isStandalone: true, selector: "[rdxMenuCheckboxItem]", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, closeOnClick: { classPropertyName: "closeOnClick", publicName: "closeOnClick", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checked: "checkedChange", onCheckedChange: "onCheckedChange" }, host: { attributes: { "role": "menuitemcheckbox" }, listeners: { "focus": "onFocus()", "blur": "onBlur()", "pointermove": "onPointerMove($event)", "pointerleave": "onPointerLeave($event)", "mouseup": "onMouseUp($event)", "click": "onItemClick()", "keydown.enter": "onActivate($event)", "keydown.space": "onActivate($event)" }, properties: { "attr.tabindex": "rootContext?.isOpen() && highlighted() ? 0 : -1", "attr.aria-checked": "isIndeterminate(checked()) ? \"mixed\" : checked()", "attr.data-state": "getCheckedState(checked())", "attr.data-disabled": "effectiveDisabled() ? \"\" : undefined", "attr.aria-disabled": "effectiveDisabled() ? true : undefined", "attr.data-highlighted": "highlighted() ? \"\" : undefined", "attr.data-label": "label() ?? undefined" } }, providers: [provideRdxMenuCheckboxItemContext(checkboxItemContextFactory)], exportAs: ["rdxMenuCheckboxItem"], hostDirectives: [{ directive: i1$1.RdxCompositeListItem }], ngImport: i0 }); }
|
|
525
618
|
}
|
|
526
619
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxMenuCheckboxItem, decorators: [{
|
|
527
620
|
type: Directive,
|
|
@@ -529,9 +622,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
529
622
|
selector: '[rdxMenuCheckboxItem]',
|
|
530
623
|
exportAs: 'rdxMenuCheckboxItem',
|
|
531
624
|
providers: [provideRdxMenuCheckboxItemContext(checkboxItemContextFactory)],
|
|
625
|
+
hostDirectives: [RdxCompositeListItem],
|
|
532
626
|
host: {
|
|
533
627
|
role: 'menuitemcheckbox',
|
|
534
|
-
tabindex: '-1',
|
|
628
|
+
'[attr.tabindex]': 'rootContext?.isOpen() && highlighted() ? 0 : -1',
|
|
535
629
|
'[attr.aria-checked]': 'isIndeterminate(checked()) ? "mixed" : checked()',
|
|
536
630
|
'[attr.data-state]': 'getCheckedState(checked())',
|
|
537
631
|
'[attr.data-disabled]': 'effectiveDisabled() ? "" : undefined',
|
|
@@ -548,7 +642,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
548
642
|
'(keydown.space)': 'onActivate($event)'
|
|
549
643
|
}
|
|
550
644
|
}]
|
|
551
|
-
}], propDecorators: { disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], closeOnClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnClick", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }, { type: i0.Output, args: ["checkedChange"] }], onCheckedChange: [{ type: i0.Output, args: ["onCheckedChange"] }] } });
|
|
645
|
+
}], ctorParameters: () => [], propDecorators: { disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], closeOnClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnClick", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }, { type: i0.Output, args: ["checkedChange"] }], onCheckedChange: [{ type: i0.Output, args: ["onCheckedChange"] }] } });
|
|
552
646
|
|
|
553
647
|
/**
|
|
554
648
|
* Renders when the parent checkbox item is checked or indeterminate.
|
|
@@ -642,6 +736,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
642
736
|
class RdxMenuItem {
|
|
643
737
|
constructor() {
|
|
644
738
|
this.rootContext = injectRdxMenuRootContext(true);
|
|
739
|
+
this.listItem = inject(RdxCompositeListItem, { self: true });
|
|
645
740
|
this.elementRef = inject(ElementRef);
|
|
646
741
|
this.isFocused = signal(false, ...(ngDevMode ? [{ debugName: "isFocused" }] : /* istanbul ignore next */ []));
|
|
647
742
|
/** Whether this item is disabled. */
|
|
@@ -652,16 +747,25 @@ class RdxMenuItem {
|
|
|
652
747
|
this.label = input(undefined, ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
653
748
|
/** Emits when the item is selected. */
|
|
654
749
|
this.onSelect = output();
|
|
655
|
-
this.highlighted = computed(() => this.isFocused(), ...(ngDevMode ? [{ debugName: "highlighted" }] : /* istanbul ignore next */ []));
|
|
750
|
+
this.highlighted = computed(() => this.rootContext?.activeIndex() === this.listItem.index() || this.isFocused(), ...(ngDevMode ? [{ debugName: "highlighted" }] : /* istanbul ignore next */ []));
|
|
656
751
|
this.effectiveDisabled = computed(() => this.disabled() || (this.rootContext?.disabled() ?? false), ...(ngDevMode ? [{ debugName: "effectiveDisabled" }] : /* istanbul ignore next */ []));
|
|
752
|
+
effect(() => {
|
|
753
|
+
this.listItem.setMetadata({
|
|
754
|
+
type: 'regular-item',
|
|
755
|
+
disabled: this.effectiveDisabled(),
|
|
756
|
+
label: this.label()
|
|
757
|
+
});
|
|
758
|
+
});
|
|
657
759
|
}
|
|
658
760
|
onFocus() {
|
|
659
|
-
if (!this.
|
|
761
|
+
if (!this.rootContext?.disabled()) {
|
|
660
762
|
this.isFocused.set(true);
|
|
661
763
|
}
|
|
764
|
+
this.setActiveIndex();
|
|
662
765
|
}
|
|
663
766
|
onBlur() {
|
|
664
767
|
this.isFocused.set(false);
|
|
768
|
+
this.clearActiveIndex();
|
|
665
769
|
}
|
|
666
770
|
onPointerMove(event) {
|
|
667
771
|
if (event.defaultPrevented || event.pointerType !== 'mouse' || this.effectiveDisabled()) {
|
|
@@ -670,6 +774,7 @@ class RdxMenuItem {
|
|
|
670
774
|
if (this.rootContext && !this.rootContext.highlightItemOnHover()) {
|
|
671
775
|
return;
|
|
672
776
|
}
|
|
777
|
+
this.setActiveIndex();
|
|
673
778
|
if (this.elementRef.nativeElement.ownerDocument.activeElement !== this.elementRef.nativeElement) {
|
|
674
779
|
this.elementRef.nativeElement.focus({ preventScroll: true });
|
|
675
780
|
}
|
|
@@ -681,6 +786,8 @@ class RdxMenuItem {
|
|
|
681
786
|
// Clear highlight when the pointer leaves: move focus back to the popup. A subsequent
|
|
682
787
|
// pointermove on a sibling item re-focuses it, so moving between items still works.
|
|
683
788
|
if (this.elementRef.nativeElement.ownerDocument.activeElement === this.elementRef.nativeElement) {
|
|
789
|
+
this.isFocused.set(false);
|
|
790
|
+
this.clearActiveIndex();
|
|
684
791
|
this.elementRef.nativeElement.closest('[rdxMenuPopup]')?.focus({ preventScroll: true });
|
|
685
792
|
}
|
|
686
793
|
}
|
|
@@ -706,17 +813,32 @@ class RdxMenuItem {
|
|
|
706
813
|
if (this.closeOnClick())
|
|
707
814
|
this.rootContext?.closeEntireMenu();
|
|
708
815
|
}
|
|
816
|
+
setActiveIndex() {
|
|
817
|
+
if (!this.rootContext || this.rootContext.disabled()) {
|
|
818
|
+
return;
|
|
819
|
+
}
|
|
820
|
+
const index = this.listItem.index();
|
|
821
|
+
if (index !== -1) {
|
|
822
|
+
this.rootContext.setActiveIndex(index);
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
clearActiveIndex() {
|
|
826
|
+
if (this.rootContext?.activeIndex() === this.listItem.index()) {
|
|
827
|
+
this.rootContext.setActiveIndex(null);
|
|
828
|
+
}
|
|
829
|
+
}
|
|
709
830
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxMenuItem, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
710
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxMenuItem, isStandalone: true, selector: "[rdxMenuItem]", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, closeOnClick: { classPropertyName: "closeOnClick", publicName: "closeOnClick", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onSelect: "onSelect" }, host: { attributes: { "role": "menuitem"
|
|
831
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxMenuItem, isStandalone: true, selector: "[rdxMenuItem]", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, closeOnClick: { classPropertyName: "closeOnClick", publicName: "closeOnClick", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onSelect: "onSelect" }, host: { attributes: { "role": "menuitem" }, listeners: { "focus": "onFocus()", "blur": "onBlur()", "pointermove": "onPointerMove($event)", "pointerleave": "onPointerLeave($event)", "mouseup": "onMouseUp($event)", "click": "onItemClick()", "keydown.enter": "onActivate($event)", "keydown.space": "onActivate($event)" }, properties: { "attr.tabindex": "rootContext?.isOpen() && highlighted() ? 0 : -1", "attr.data-disabled": "effectiveDisabled() ? \"\" : undefined", "attr.aria-disabled": "effectiveDisabled() ? true : undefined", "attr.data-highlighted": "highlighted() ? \"\" : undefined", "attr.data-label": "label() ?? undefined" } }, exportAs: ["rdxMenuItem"], hostDirectives: [{ directive: i1$1.RdxCompositeListItem }], ngImport: i0 }); }
|
|
711
832
|
}
|
|
712
833
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxMenuItem, decorators: [{
|
|
713
834
|
type: Directive,
|
|
714
835
|
args: [{
|
|
715
836
|
selector: '[rdxMenuItem]',
|
|
716
837
|
exportAs: 'rdxMenuItem',
|
|
838
|
+
hostDirectives: [RdxCompositeListItem],
|
|
717
839
|
host: {
|
|
718
840
|
role: 'menuitem',
|
|
719
|
-
tabindex: '-1',
|
|
841
|
+
'[attr.tabindex]': 'rootContext?.isOpen() && highlighted() ? 0 : -1',
|
|
720
842
|
'[attr.data-disabled]': 'effectiveDisabled() ? "" : undefined',
|
|
721
843
|
'[attr.aria-disabled]': 'effectiveDisabled() ? true : undefined',
|
|
722
844
|
'[attr.data-highlighted]': 'highlighted() ? "" : undefined',
|
|
@@ -731,7 +853,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
731
853
|
'(keydown.space)': 'onActivate($event)'
|
|
732
854
|
}
|
|
733
855
|
}]
|
|
734
|
-
}], propDecorators: { disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], closeOnClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnClick", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], onSelect: [{ type: i0.Output, args: ["onSelect"] }] } });
|
|
856
|
+
}], ctorParameters: () => [], propDecorators: { disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], closeOnClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnClick", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], onSelect: [{ type: i0.Output, args: ["onSelect"] }] } });
|
|
735
857
|
|
|
736
858
|
/**
|
|
737
859
|
* A menu item that renders as a link.
|
|
@@ -739,6 +861,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
739
861
|
class RdxMenuLinkItem {
|
|
740
862
|
constructor() {
|
|
741
863
|
this.rootContext = injectRdxMenuRootContext(true);
|
|
864
|
+
this.listItem = inject(RdxCompositeListItem, { self: true });
|
|
742
865
|
this.elementRef = inject(ElementRef);
|
|
743
866
|
this.isFocused = signal(false, ...(ngDevMode ? [{ debugName: "isFocused" }] : /* istanbul ignore next */ []));
|
|
744
867
|
/** Whether this item is disabled. */
|
|
@@ -749,16 +872,25 @@ class RdxMenuLinkItem {
|
|
|
749
872
|
this.label = input(undefined, ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
750
873
|
/** Emits when the item is selected. */
|
|
751
874
|
this.onSelect = output();
|
|
752
|
-
this.highlighted = computed(() => this.isFocused(), ...(ngDevMode ? [{ debugName: "highlighted" }] : /* istanbul ignore next */ []));
|
|
875
|
+
this.highlighted = computed(() => this.rootContext?.activeIndex() === this.listItem.index() || this.isFocused(), ...(ngDevMode ? [{ debugName: "highlighted" }] : /* istanbul ignore next */ []));
|
|
753
876
|
this.effectiveDisabled = computed(() => this.disabled() || (this.rootContext?.disabled() ?? false), ...(ngDevMode ? [{ debugName: "effectiveDisabled" }] : /* istanbul ignore next */ []));
|
|
877
|
+
effect(() => {
|
|
878
|
+
this.listItem.setMetadata({
|
|
879
|
+
type: 'link-item',
|
|
880
|
+
disabled: this.effectiveDisabled(),
|
|
881
|
+
label: this.label()
|
|
882
|
+
});
|
|
883
|
+
});
|
|
754
884
|
}
|
|
755
885
|
onFocus() {
|
|
756
|
-
if (!this.
|
|
886
|
+
if (!this.rootContext?.disabled()) {
|
|
757
887
|
this.isFocused.set(true);
|
|
758
888
|
}
|
|
889
|
+
this.setActiveIndex();
|
|
759
890
|
}
|
|
760
891
|
onBlur() {
|
|
761
892
|
this.isFocused.set(false);
|
|
893
|
+
this.clearActiveIndex();
|
|
762
894
|
}
|
|
763
895
|
onPointerMove(event) {
|
|
764
896
|
if (event.defaultPrevented || event.pointerType !== 'mouse' || this.effectiveDisabled()) {
|
|
@@ -767,6 +899,7 @@ class RdxMenuLinkItem {
|
|
|
767
899
|
if (this.rootContext && !this.rootContext.highlightItemOnHover()) {
|
|
768
900
|
return;
|
|
769
901
|
}
|
|
902
|
+
this.setActiveIndex();
|
|
770
903
|
if (this.elementRef.nativeElement.ownerDocument.activeElement !== this.elementRef.nativeElement) {
|
|
771
904
|
this.elementRef.nativeElement.focus({ preventScroll: true });
|
|
772
905
|
}
|
|
@@ -776,6 +909,8 @@ class RdxMenuLinkItem {
|
|
|
776
909
|
return;
|
|
777
910
|
}
|
|
778
911
|
if (this.elementRef.nativeElement.ownerDocument.activeElement === this.elementRef.nativeElement) {
|
|
912
|
+
this.isFocused.set(false);
|
|
913
|
+
this.clearActiveIndex();
|
|
779
914
|
this.elementRef.nativeElement.closest('[rdxMenuPopup]')?.focus({ preventScroll: true });
|
|
780
915
|
}
|
|
781
916
|
}
|
|
@@ -796,25 +931,38 @@ class RdxMenuLinkItem {
|
|
|
796
931
|
this.elementRef.nativeElement.click();
|
|
797
932
|
}
|
|
798
933
|
onActivate(event) {
|
|
934
|
+
event.preventDefault();
|
|
799
935
|
if (this.effectiveDisabled()) {
|
|
800
|
-
event.preventDefault();
|
|
801
936
|
return;
|
|
802
937
|
}
|
|
803
|
-
this.
|
|
804
|
-
|
|
805
|
-
|
|
938
|
+
this.elementRef.nativeElement.click();
|
|
939
|
+
}
|
|
940
|
+
setActiveIndex() {
|
|
941
|
+
if (!this.rootContext || this.rootContext.disabled()) {
|
|
942
|
+
return;
|
|
943
|
+
}
|
|
944
|
+
const index = this.listItem.index();
|
|
945
|
+
if (index !== -1) {
|
|
946
|
+
this.rootContext.setActiveIndex(index);
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
clearActiveIndex() {
|
|
950
|
+
if (this.rootContext?.activeIndex() === this.listItem.index()) {
|
|
951
|
+
this.rootContext.setActiveIndex(null);
|
|
952
|
+
}
|
|
806
953
|
}
|
|
807
954
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxMenuLinkItem, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
808
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxMenuLinkItem, isStandalone: true, selector: "a[rdxMenuLinkItem]", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, closeOnClick: { classPropertyName: "closeOnClick", publicName: "closeOnClick", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onSelect: "onSelect" }, host: { attributes: { "role": "menuitem"
|
|
955
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxMenuLinkItem, isStandalone: true, selector: "a[rdxMenuLinkItem]", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, closeOnClick: { classPropertyName: "closeOnClick", publicName: "closeOnClick", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onSelect: "onSelect" }, host: { attributes: { "role": "menuitem" }, listeners: { "focus": "onFocus()", "blur": "onBlur()", "pointermove": "onPointerMove($event)", "pointerleave": "onPointerLeave($event)", "mouseup": "onMouseUp($event)", "click": "onItemClick($event)", "keydown.enter": "onActivate($event)", "keydown.space": "onActivate($event)" }, properties: { "attr.tabindex": "rootContext?.isOpen() && highlighted() ? 0 : -1", "attr.data-disabled": "effectiveDisabled() ? \"\" : undefined", "attr.aria-disabled": "effectiveDisabled() ? true : undefined", "attr.data-highlighted": "highlighted() ? \"\" : undefined", "attr.data-label": "label() ?? undefined" } }, exportAs: ["rdxMenuLinkItem"], hostDirectives: [{ directive: i1$1.RdxCompositeListItem }], ngImport: i0 }); }
|
|
809
956
|
}
|
|
810
957
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxMenuLinkItem, decorators: [{
|
|
811
958
|
type: Directive,
|
|
812
959
|
args: [{
|
|
813
960
|
selector: 'a[rdxMenuLinkItem]',
|
|
814
961
|
exportAs: 'rdxMenuLinkItem',
|
|
962
|
+
hostDirectives: [RdxCompositeListItem],
|
|
815
963
|
host: {
|
|
816
964
|
role: 'menuitem',
|
|
817
|
-
tabindex: '-1',
|
|
965
|
+
'[attr.tabindex]': 'rootContext?.isOpen() && highlighted() ? 0 : -1',
|
|
818
966
|
'[attr.data-disabled]': 'effectiveDisabled() ? "" : undefined',
|
|
819
967
|
'[attr.aria-disabled]': 'effectiveDisabled() ? true : undefined',
|
|
820
968
|
'[attr.data-highlighted]': 'highlighted() ? "" : undefined',
|
|
@@ -825,10 +973,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
825
973
|
'(pointerleave)': 'onPointerLeave($event)',
|
|
826
974
|
'(mouseup)': 'onMouseUp($event)',
|
|
827
975
|
'(click)': 'onItemClick($event)',
|
|
828
|
-
'(keydown.enter)': 'onActivate($event)'
|
|
976
|
+
'(keydown.enter)': 'onActivate($event)',
|
|
977
|
+
'(keydown.space)': 'onActivate($event)'
|
|
829
978
|
}
|
|
830
979
|
}]
|
|
831
|
-
}], propDecorators: { disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], closeOnClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnClick", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], onSelect: [{ type: i0.Output, args: ["onSelect"] }] } });
|
|
980
|
+
}], ctorParameters: () => [], propDecorators: { disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], closeOnClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnClick", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], onSelect: [{ type: i0.Output, args: ["onSelect"] }] } });
|
|
832
981
|
|
|
833
982
|
/**
|
|
834
983
|
* A container for the menu contents.
|
|
@@ -840,6 +989,7 @@ class RdxMenuPopup {
|
|
|
840
989
|
this.registration = inject(RDX_FLOATING_REGISTRATION, { optional: true });
|
|
841
990
|
this.focusManager = inject(RdxFloatingFocusManager);
|
|
842
991
|
this.focusScope = inject(RdxFocusScope);
|
|
992
|
+
this.compositeList = inject(RdxCompositeList, { self: true });
|
|
843
993
|
this.wrapper = inject(RdxPopperContentWrapper, { optional: true });
|
|
844
994
|
this.elementRef = inject(ElementRef);
|
|
845
995
|
this.search = '';
|
|
@@ -954,10 +1104,11 @@ class RdxMenuPopup {
|
|
|
954
1104
|
}
|
|
955
1105
|
}
|
|
956
1106
|
handleKeydown(event) {
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
const
|
|
1107
|
+
if (this.rootContext.disabled()) {
|
|
1108
|
+
return;
|
|
1109
|
+
}
|
|
1110
|
+
const items = this.menuItems();
|
|
1111
|
+
const currentIndex = this.currentItemIndex(items);
|
|
961
1112
|
switch (event.key) {
|
|
962
1113
|
case 'ArrowDown': {
|
|
963
1114
|
event.preventDefault();
|
|
@@ -968,7 +1119,7 @@ class RdxMenuPopup {
|
|
|
968
1119
|
? items[0]
|
|
969
1120
|
: items[items.length - 1]
|
|
970
1121
|
: items[currentIndex + 1];
|
|
971
|
-
next
|
|
1122
|
+
this.focusMenuItem(next);
|
|
972
1123
|
break;
|
|
973
1124
|
}
|
|
974
1125
|
case 'ArrowUp': {
|
|
@@ -980,19 +1131,19 @@ class RdxMenuPopup {
|
|
|
980
1131
|
? items[items.length - 1]
|
|
981
1132
|
: items[0]
|
|
982
1133
|
: items[currentIndex - 1];
|
|
983
|
-
prev
|
|
1134
|
+
this.focusMenuItem(prev);
|
|
984
1135
|
break;
|
|
985
1136
|
}
|
|
986
1137
|
case 'Home': {
|
|
987
1138
|
event.preventDefault();
|
|
988
1139
|
event.stopPropagation();
|
|
989
|
-
items[0]
|
|
1140
|
+
this.focusMenuItem(items[0]);
|
|
990
1141
|
break;
|
|
991
1142
|
}
|
|
992
1143
|
case 'End': {
|
|
993
1144
|
event.preventDefault();
|
|
994
1145
|
event.stopPropagation();
|
|
995
|
-
items[items.length - 1]
|
|
1146
|
+
this.focusMenuItem(items[items.length - 1]);
|
|
996
1147
|
break;
|
|
997
1148
|
}
|
|
998
1149
|
case 'ArrowLeft': {
|
|
@@ -1055,11 +1206,8 @@ class RdxMenuPopup {
|
|
|
1055
1206
|
const query = this.search.length > 1 && [...this.search].every((c) => c === char) ? char : this.search;
|
|
1056
1207
|
const startIndex = currentIndex >= 0 ? currentIndex + 1 : 0;
|
|
1057
1208
|
const rotated = [...items.slice(startIndex), ...items.slice(0, startIndex)];
|
|
1058
|
-
const match = rotated.find((item) =>
|
|
1059
|
-
|
|
1060
|
-
return text.startsWith(query);
|
|
1061
|
-
});
|
|
1062
|
-
match?.focus({ preventScroll: true });
|
|
1209
|
+
const match = rotated.find((item) => item.label.startsWith(query));
|
|
1210
|
+
this.focusMenuItem(match);
|
|
1063
1211
|
}
|
|
1064
1212
|
break;
|
|
1065
1213
|
}
|
|
@@ -1079,14 +1227,34 @@ class RdxMenuPopup {
|
|
|
1079
1227
|
if (activeElement && popup.contains(activeElement)) {
|
|
1080
1228
|
return;
|
|
1081
1229
|
}
|
|
1082
|
-
const items =
|
|
1230
|
+
const items = this.menuItems();
|
|
1083
1231
|
if (items.length === 0) {
|
|
1084
1232
|
if (attempt < maxAttempts) {
|
|
1085
1233
|
this.scheduleSubmenuKeyboardFocus(attempt + 1);
|
|
1086
1234
|
}
|
|
1087
1235
|
return;
|
|
1088
1236
|
}
|
|
1089
|
-
items[0]
|
|
1237
|
+
this.focusMenuItem(items[0]);
|
|
1238
|
+
}
|
|
1239
|
+
menuItems() {
|
|
1240
|
+
const compositeItems = getCompositeMenuItems(this.compositeList);
|
|
1241
|
+
return compositeItems.length > 0 ? compositeItems : getDomMenuItems(this.elementRef.nativeElement);
|
|
1242
|
+
}
|
|
1243
|
+
currentItemIndex(items) {
|
|
1244
|
+
const current = this.elementRef.nativeElement.ownerDocument.activeElement;
|
|
1245
|
+
const focusedIndex = items.findIndex((item) => item.element === current);
|
|
1246
|
+
if (focusedIndex !== -1) {
|
|
1247
|
+
return focusedIndex;
|
|
1248
|
+
}
|
|
1249
|
+
const activeIndex = this.rootContext.activeIndex();
|
|
1250
|
+
return items.findIndex((item) => item.index === activeIndex);
|
|
1251
|
+
}
|
|
1252
|
+
focusMenuItem(item) {
|
|
1253
|
+
if (!item) {
|
|
1254
|
+
return;
|
|
1255
|
+
}
|
|
1256
|
+
this.rootContext.setActiveIndex(item.index);
|
|
1257
|
+
item.element.focus({ preventScroll: true });
|
|
1090
1258
|
}
|
|
1091
1259
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxMenuPopup, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1092
1260
|
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxMenuPopup, isStandalone: true, selector: "[rdxMenuPopup]", outputs: { escapeKeyDown: "escapeKeyDown", pointerDownOutside: "pointerDownOutside", focusOutside: "focusOutside", interactOutside: "interactOutside", openAutoFocus: "openAutoFocus", closeAutoFocus: "closeAutoFocus" }, host: { attributes: { "role": "menu", "tabindex": "-1" }, listeners: { "keydown": "handleKeydown($event)", "rdx-menu-close-parent": "handleCloseParent($event)" }, properties: { "attr.aria-orientation": "rootContext.orientation()", "attr.data-closed": "rootContext.isOpen() ? undefined : \"\"", "attr.data-open": "rootContext.isOpen() ? \"\" : undefined", "attr.data-state": "rootContext.isOpen() ? \"open\" : \"closed\"", "attr.data-starting-style": "rootContext.transitionStatus() === \"starting\" ? \"\" : undefined", "attr.data-ending-style": "rootContext.transitionStatus() === \"ending\" ? \"\" : undefined", "attr.data-align": "align()", "attr.data-side": "side()" } }, providers: [
|
|
@@ -1138,14 +1306,14 @@ class RdxMenuPopup {
|
|
|
1138
1306
|
closeInteractionType: () => rootContext.closeInteractionType()
|
|
1139
1307
|
};
|
|
1140
1308
|
})
|
|
1141
|
-
], exportAs: ["rdxMenuPopup"], hostDirectives: [{ directive: i1.RdxPopperContent }, { directive: i2.RdxFloatingNodeRegistration }, { directive: i3.RdxFloatingFocusManager }], ngImport: i0 }); }
|
|
1309
|
+
], exportAs: ["rdxMenuPopup"], hostDirectives: [{ directive: i1.RdxPopperContent }, { directive: i2.RdxFloatingNodeRegistration }, { directive: i3.RdxFloatingFocusManager }, { directive: i1$1.RdxCompositeList }], ngImport: i0 }); }
|
|
1142
1310
|
}
|
|
1143
1311
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxMenuPopup, decorators: [{
|
|
1144
1312
|
type: Directive,
|
|
1145
1313
|
args: [{
|
|
1146
1314
|
selector: '[rdxMenuPopup]',
|
|
1147
1315
|
exportAs: 'rdxMenuPopup',
|
|
1148
|
-
hostDirectives: [RdxPopperContent, RdxFloatingNodeRegistration, RdxFloatingFocusManager],
|
|
1316
|
+
hostDirectives: [RdxPopperContent, RdxFloatingNodeRegistration, RdxFloatingFocusManager, RdxCompositeList],
|
|
1149
1317
|
providers: [
|
|
1150
1318
|
provideFloatingFocusManagerConfig(() => {
|
|
1151
1319
|
const rootContext = injectRdxMenuRootContext();
|
|
@@ -1224,7 +1392,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
1224
1392
|
*/
|
|
1225
1393
|
class RdxMenuPortal {
|
|
1226
1394
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxMenuPortal, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1227
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxMenuPortal, isStandalone: true, selector: "ng-template[rdxMenuPortal]", providers: [provideRdxPresenceContext(() => ({ present: injectRdxMenuRootContext().present }))], exportAs: ["rdxMenuPortal"], hostDirectives: [{ directive: i1$
|
|
1395
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxMenuPortal, isStandalone: true, selector: "ng-template[rdxMenuPortal]", providers: [provideRdxPresenceContext(() => ({ present: injectRdxMenuRootContext().present }))], exportAs: ["rdxMenuPortal"], hostDirectives: [{ directive: i1$2.RdxPortalPresence, inputs: ["container", "container"] }], ngImport: i0 }); }
|
|
1228
1396
|
}
|
|
1229
1397
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxMenuPortal, decorators: [{
|
|
1230
1398
|
type: Directive,
|
|
@@ -1422,6 +1590,7 @@ class RdxMenuRadioItem {
|
|
|
1422
1590
|
constructor() {
|
|
1423
1591
|
this.rootContext = injectRdxMenuRootContext(true);
|
|
1424
1592
|
this.radioGroupContext = injectRdxMenuRadioGroupContext();
|
|
1593
|
+
this.listItem = inject(RdxCompositeListItem, { self: true });
|
|
1425
1594
|
this.elementRef = inject(ElementRef);
|
|
1426
1595
|
this.isFocused = signal(false, ...(ngDevMode ? [{ debugName: "isFocused" }] : /* istanbul ignore next */ []));
|
|
1427
1596
|
/** The value of this radio item. */
|
|
@@ -1435,17 +1604,26 @@ class RdxMenuRadioItem {
|
|
|
1435
1604
|
/** Emits when this item is selected. */
|
|
1436
1605
|
this.onSelect = output();
|
|
1437
1606
|
this.checked = computed(() => this.radioGroupContext.value() === this.value(), ...(ngDevMode ? [{ debugName: "checked" }] : /* istanbul ignore next */ []));
|
|
1438
|
-
this.highlighted = computed(() => this.isFocused(), ...(ngDevMode ? [{ debugName: "highlighted" }] : /* istanbul ignore next */ []));
|
|
1607
|
+
this.highlighted = computed(() => this.rootContext?.activeIndex() === this.listItem.index() || this.isFocused(), ...(ngDevMode ? [{ debugName: "highlighted" }] : /* istanbul ignore next */ []));
|
|
1439
1608
|
this.effectiveDisabled = computed(() => this.disabled() || this.radioGroupContext.disabled() || (this.rootContext?.disabled() ?? false), ...(ngDevMode ? [{ debugName: "effectiveDisabled" }] : /* istanbul ignore next */ []));
|
|
1440
1609
|
this.getCheckedState = getCheckedState;
|
|
1610
|
+
effect(() => {
|
|
1611
|
+
this.listItem.setMetadata({
|
|
1612
|
+
type: 'radio-item',
|
|
1613
|
+
disabled: this.effectiveDisabled(),
|
|
1614
|
+
label: this.label()
|
|
1615
|
+
});
|
|
1616
|
+
});
|
|
1441
1617
|
}
|
|
1442
1618
|
onFocus() {
|
|
1443
|
-
if (!this.
|
|
1619
|
+
if (!this.rootContext?.disabled()) {
|
|
1444
1620
|
this.isFocused.set(true);
|
|
1445
1621
|
}
|
|
1622
|
+
this.setActiveIndex();
|
|
1446
1623
|
}
|
|
1447
1624
|
onBlur() {
|
|
1448
1625
|
this.isFocused.set(false);
|
|
1626
|
+
this.clearActiveIndex();
|
|
1449
1627
|
}
|
|
1450
1628
|
onPointerMove(event) {
|
|
1451
1629
|
if (event.defaultPrevented || event.pointerType !== 'mouse' || this.effectiveDisabled()) {
|
|
@@ -1454,6 +1632,7 @@ class RdxMenuRadioItem {
|
|
|
1454
1632
|
if (this.rootContext && !this.rootContext.highlightItemOnHover()) {
|
|
1455
1633
|
return;
|
|
1456
1634
|
}
|
|
1635
|
+
this.setActiveIndex();
|
|
1457
1636
|
if (this.elementRef.nativeElement.ownerDocument.activeElement !== this.elementRef.nativeElement) {
|
|
1458
1637
|
this.elementRef.nativeElement.focus({ preventScroll: true });
|
|
1459
1638
|
}
|
|
@@ -1463,6 +1642,8 @@ class RdxMenuRadioItem {
|
|
|
1463
1642
|
return;
|
|
1464
1643
|
}
|
|
1465
1644
|
if (this.elementRef.nativeElement.ownerDocument.activeElement === this.elementRef.nativeElement) {
|
|
1645
|
+
this.isFocused.set(false);
|
|
1646
|
+
this.clearActiveIndex();
|
|
1466
1647
|
this.elementRef.nativeElement.closest('[rdxMenuPopup]')?.focus({ preventScroll: true });
|
|
1467
1648
|
}
|
|
1468
1649
|
}
|
|
@@ -1493,8 +1674,22 @@ class RdxMenuRadioItem {
|
|
|
1493
1674
|
if (this.closeOnClick())
|
|
1494
1675
|
this.rootContext?.closeEntireMenu();
|
|
1495
1676
|
}
|
|
1677
|
+
setActiveIndex() {
|
|
1678
|
+
if (!this.rootContext || this.rootContext.disabled()) {
|
|
1679
|
+
return;
|
|
1680
|
+
}
|
|
1681
|
+
const index = this.listItem.index();
|
|
1682
|
+
if (index !== -1) {
|
|
1683
|
+
this.rootContext.setActiveIndex(index);
|
|
1684
|
+
}
|
|
1685
|
+
}
|
|
1686
|
+
clearActiveIndex() {
|
|
1687
|
+
if (this.rootContext?.activeIndex() === this.listItem.index()) {
|
|
1688
|
+
this.rootContext.setActiveIndex(null);
|
|
1689
|
+
}
|
|
1690
|
+
}
|
|
1496
1691
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxMenuRadioItem, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1497
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxMenuRadioItem, isStandalone: true, selector: "[rdxMenuRadioItem]", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, closeOnClick: { classPropertyName: "closeOnClick", publicName: "closeOnClick", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onSelect: "onSelect" }, host: { attributes: { "role": "menuitemradio"
|
|
1692
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxMenuRadioItem, isStandalone: true, selector: "[rdxMenuRadioItem]", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, closeOnClick: { classPropertyName: "closeOnClick", publicName: "closeOnClick", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onSelect: "onSelect" }, host: { attributes: { "role": "menuitemradio" }, listeners: { "focus": "onFocus()", "blur": "onBlur()", "pointermove": "onPointerMove($event)", "pointerleave": "onPointerLeave($event)", "mouseup": "onMouseUp($event)", "click": "onItemClick()", "keydown.enter": "onActivate($event)", "keydown.space": "onActivate($event)" }, properties: { "attr.tabindex": "rootContext?.isOpen() && highlighted() ? 0 : -1", "attr.aria-checked": "checked()", "attr.data-state": "getCheckedState(checked())", "attr.data-disabled": "effectiveDisabled() ? \"\" : undefined", "attr.aria-disabled": "effectiveDisabled() ? true : undefined", "attr.data-highlighted": "highlighted() ? \"\" : undefined", "attr.data-label": "label() ?? undefined" } }, providers: [provideRdxMenuRadioItemContext(radioItemContextFactory)], exportAs: ["rdxMenuRadioItem"], hostDirectives: [{ directive: i1$1.RdxCompositeListItem }], ngImport: i0 }); }
|
|
1498
1693
|
}
|
|
1499
1694
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxMenuRadioItem, decorators: [{
|
|
1500
1695
|
type: Directive,
|
|
@@ -1502,9 +1697,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
1502
1697
|
selector: '[rdxMenuRadioItem]',
|
|
1503
1698
|
exportAs: 'rdxMenuRadioItem',
|
|
1504
1699
|
providers: [provideRdxMenuRadioItemContext(radioItemContextFactory)],
|
|
1700
|
+
hostDirectives: [RdxCompositeListItem],
|
|
1505
1701
|
host: {
|
|
1506
1702
|
role: 'menuitemradio',
|
|
1507
|
-
tabindex: '-1',
|
|
1703
|
+
'[attr.tabindex]': 'rootContext?.isOpen() && highlighted() ? 0 : -1',
|
|
1508
1704
|
'[attr.aria-checked]': 'checked()',
|
|
1509
1705
|
'[attr.data-state]': 'getCheckedState(checked())',
|
|
1510
1706
|
'[attr.data-disabled]': 'effectiveDisabled() ? "" : undefined',
|
|
@@ -1521,7 +1717,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
1521
1717
|
'(keydown.space)': 'onActivate($event)'
|
|
1522
1718
|
}
|
|
1523
1719
|
}]
|
|
1524
|
-
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], closeOnClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnClick", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], onSelect: [{ type: i0.Output, args: ["onSelect"] }] } });
|
|
1720
|
+
}], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], closeOnClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnClick", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], onSelect: [{ type: i0.Output, args: ["onSelect"] }] } });
|
|
1525
1721
|
|
|
1526
1722
|
/**
|
|
1527
1723
|
* Renders when the parent radio item is selected.
|
|
@@ -1915,6 +2111,8 @@ class RdxMenuSubTrigger {
|
|
|
1915
2111
|
constructor() {
|
|
1916
2112
|
this.submenuContext = injectRdxMenuRootContext();
|
|
1917
2113
|
this.submenuRoot = inject(RdxMenuRoot);
|
|
2114
|
+
this.parentMenuRoot = this.submenuRoot.parentRoot;
|
|
2115
|
+
this.listItem = inject(RdxCompositeListItem, { self: true });
|
|
1918
2116
|
this.elementRef = inject(ElementRef);
|
|
1919
2117
|
this.destroyRef = inject(DestroyRef);
|
|
1920
2118
|
this.isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
|
|
@@ -1936,8 +2134,10 @@ class RdxMenuSubTrigger {
|
|
|
1936
2134
|
this.closeDelay = input(0, { ...(ngDevMode ? { debugName: "closeDelay" } : /* istanbul ignore next */ {}), transform: numberOrUndefined$1 });
|
|
1937
2135
|
/** Explicit typeahead label. When set, overrides textContent for character search. */
|
|
1938
2136
|
this.label = input(undefined, ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
1939
|
-
/** Highlighted when
|
|
1940
|
-
this.highlighted = computed(() => this.
|
|
2137
|
+
/** Highlighted when active in the parent menu or while the submenu is open. */
|
|
2138
|
+
this.highlighted = computed(() => this.parentMenuRoot?.activeIndex() === this.listItem.index() ||
|
|
2139
|
+
this.isFocused() ||
|
|
2140
|
+
this.submenuContext.isOpen(), ...(ngDevMode ? [{ debugName: "highlighted" }] : /* istanbul ignore next */ []));
|
|
1941
2141
|
this.effectiveDisabled = computed(() => this.disabled() || this.submenuContext.disabled(), ...(ngDevMode ? [{ debugName: "effectiveDisabled" }] : /* istanbul ignore next */ []));
|
|
1942
2142
|
this.nativeButtonState = computed(() => this.nativeButton() || this.elementRef.nativeElement.tagName === 'BUTTON', ...(ngDevMode ? [{ debugName: "nativeButtonState" }] : /* istanbul ignore next */ []));
|
|
1943
2143
|
this.submenuContext.markAsSubmenu();
|
|
@@ -1950,6 +2150,13 @@ class RdxMenuSubTrigger {
|
|
|
1950
2150
|
submenuRootsByTrigger.delete(el);
|
|
1951
2151
|
});
|
|
1952
2152
|
});
|
|
2153
|
+
effect(() => {
|
|
2154
|
+
this.listItem.setMetadata({
|
|
2155
|
+
type: 'submenu-trigger',
|
|
2156
|
+
disabled: this.effectiveDisabled(),
|
|
2157
|
+
label: this.label()
|
|
2158
|
+
});
|
|
2159
|
+
});
|
|
1953
2160
|
// While this submenu is open by hover, it owns the decision to close itself: a document
|
|
1954
2161
|
// `mousemove` handler keeps it open while the cursor traverses the safe polygon toward the
|
|
1955
2162
|
// popup, and a pointer-events tunnel stops siblings from stealing it mid-traversal.
|
|
@@ -2011,13 +2218,16 @@ class RdxMenuSubTrigger {
|
|
|
2011
2218
|
}
|
|
2012
2219
|
}
|
|
2013
2220
|
onFocus() {
|
|
2014
|
-
if (
|
|
2015
|
-
|
|
2016
|
-
this.isFocused.set(true);
|
|
2221
|
+
if (this.submenuContext.disabled()) {
|
|
2222
|
+
return;
|
|
2017
2223
|
}
|
|
2224
|
+
this.clearSiblingHighlights();
|
|
2225
|
+
this.isFocused.set(true);
|
|
2226
|
+
this.setParentActiveIndex();
|
|
2018
2227
|
}
|
|
2019
2228
|
onBlur() {
|
|
2020
2229
|
this.isFocused.set(false);
|
|
2230
|
+
this.clearParentActiveIndex();
|
|
2021
2231
|
}
|
|
2022
2232
|
onClick(event) {
|
|
2023
2233
|
if (this.effectiveDisabled())
|
|
@@ -2100,6 +2310,7 @@ class RdxMenuSubTrigger {
|
|
|
2100
2310
|
return;
|
|
2101
2311
|
this.lastPointer = { x: event.clientX, y: event.clientY };
|
|
2102
2312
|
this.clearSiblingHighlights();
|
|
2313
|
+
this.setParentActiveIndex();
|
|
2103
2314
|
const el = this.elementRef.nativeElement;
|
|
2104
2315
|
if (this.submenuContext.highlightItemOnHover() && el.ownerDocument.activeElement !== el) {
|
|
2105
2316
|
el.focus({ preventScroll: true });
|
|
@@ -2118,6 +2329,7 @@ class RdxMenuSubTrigger {
|
|
|
2118
2329
|
}
|
|
2119
2330
|
clearHighlight() {
|
|
2120
2331
|
this.isFocused.set(false);
|
|
2332
|
+
this.clearParentActiveIndex();
|
|
2121
2333
|
}
|
|
2122
2334
|
closeSiblingSubmenus() {
|
|
2123
2335
|
const currentTrigger = this.elementRef.nativeElement;
|
|
@@ -2177,23 +2389,34 @@ class RdxMenuSubTrigger {
|
|
|
2177
2389
|
setTimeout(run);
|
|
2178
2390
|
}
|
|
2179
2391
|
}
|
|
2392
|
+
setParentActiveIndex() {
|
|
2393
|
+
const index = this.listItem.index();
|
|
2394
|
+
if (index === -1 || !this.parentMenuRoot || this.parentMenuRoot.effectiveDisabled()) {
|
|
2395
|
+
return;
|
|
2396
|
+
}
|
|
2397
|
+
this.parentMenuRoot.setActiveIndex(index);
|
|
2398
|
+
}
|
|
2399
|
+
clearParentActiveIndex() {
|
|
2400
|
+
if (this.parentMenuRoot?.activeIndex() === this.listItem.index()) {
|
|
2401
|
+
this.parentMenuRoot.setActiveIndex(null);
|
|
2402
|
+
}
|
|
2403
|
+
}
|
|
2180
2404
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxMenuSubTrigger, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
2181
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxMenuSubTrigger, isStandalone: true, selector: "[rdxMenuSubTrigger]", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, nativeButton: { classPropertyName: "nativeButton", publicName: "nativeButton", isSignal: true, isRequired: false, transformFunction: null }, openOnHover: { classPropertyName: "openOnHover", publicName: "openOnHover", 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 }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "menuitem"
|
|
2405
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxMenuSubTrigger, isStandalone: true, selector: "[rdxMenuSubTrigger]", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, nativeButton: { classPropertyName: "nativeButton", publicName: "nativeButton", isSignal: true, isRequired: false, transformFunction: null }, openOnHover: { classPropertyName: "openOnHover", publicName: "openOnHover", 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 }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "menuitem" }, listeners: { "focus": "onFocus()", "blur": "onBlur()", "click": "onClick($event)", "keydown.enter": "onEnter($event)", "keydown.space": "onEnter($event)", "keydown.arrowleft": "onArrowLeft($event)", "keydown.arrowright": "onArrowRight($event)", "pointermove": "onPointerMove($event)", "pointerleave": "onPointerLeave()", "rdx-menu-subtrigger-clear-highlight": "clearHighlight()" }, properties: { "attr.type": "nativeButtonState() ? \"button\" : undefined", "attr.tabindex": "parentMenuRoot?.open() && highlighted() ? 0 : -1", "attr.aria-haspopup": "\"menu\"", "attr.aria-expanded": "submenuContext.isOpen()", "attr.aria-disabled": "effectiveDisabled() ? true : undefined", "attr.data-state": "submenuContext.isOpen() ? \"open\" : \"closed\"", "attr.data-popup-open": "submenuContext.isOpen() ? \"\" : undefined", "attr.data-highlighted": "highlighted() ? \"\" : undefined", "attr.data-disabled": "effectiveDisabled() ? \"\" : undefined", "attr.data-label": "label() ?? undefined" } }, exportAs: ["rdxMenuSubTrigger"], hostDirectives: [{ directive: i1.RdxPopperAnchor }, { directive: i1$1.RdxCompositeListItem }], ngImport: i0 }); }
|
|
2182
2406
|
}
|
|
2183
2407
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxMenuSubTrigger, decorators: [{
|
|
2184
2408
|
type: Directive,
|
|
2185
2409
|
args: [{
|
|
2186
2410
|
selector: '[rdxMenuSubTrigger]',
|
|
2187
2411
|
exportAs: 'rdxMenuSubTrigger',
|
|
2188
|
-
hostDirectives: [RdxPopperAnchor],
|
|
2412
|
+
hostDirectives: [RdxPopperAnchor, RdxCompositeListItem],
|
|
2189
2413
|
host: {
|
|
2190
2414
|
'[attr.type]': 'nativeButtonState() ? "button" : undefined',
|
|
2191
2415
|
role: 'menuitem',
|
|
2192
|
-
tabindex: '-1',
|
|
2416
|
+
'[attr.tabindex]': 'parentMenuRoot?.open() && highlighted() ? 0 : -1',
|
|
2193
2417
|
'[attr.aria-haspopup]': '"menu"',
|
|
2194
2418
|
'[attr.aria-expanded]': 'submenuContext.isOpen()',
|
|
2195
2419
|
'[attr.aria-disabled]': 'effectiveDisabled() ? true : undefined',
|
|
2196
|
-
'[attr.disabled]': 'nativeButtonState() && effectiveDisabled() ? "" : undefined',
|
|
2197
2420
|
'[attr.data-state]': 'submenuContext.isOpen() ? "open" : "closed"',
|
|
2198
2421
|
'[attr.data-popup-open]': 'submenuContext.isOpen() ? "" : undefined',
|
|
2199
2422
|
'[attr.data-highlighted]': 'highlighted() ? "" : undefined',
|
|
@@ -2203,6 +2426,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
2203
2426
|
'(blur)': 'onBlur()',
|
|
2204
2427
|
'(click)': 'onClick($event)',
|
|
2205
2428
|
'(keydown.enter)': 'onEnter($event)',
|
|
2429
|
+
'(keydown.space)': 'onEnter($event)',
|
|
2206
2430
|
'(keydown.arrowleft)': 'onArrowLeft($event)',
|
|
2207
2431
|
'(keydown.arrowright)': 'onArrowRight($event)',
|
|
2208
2432
|
'(pointermove)': 'onPointerMove($event)',
|
|
@@ -2226,6 +2450,7 @@ class RdxMenuTrigger {
|
|
|
2226
2450
|
this.openedByHover = false;
|
|
2227
2451
|
this.ignoreNextClick = null;
|
|
2228
2452
|
this.handleDocumentMouseUp = (event) => {
|
|
2453
|
+
clearTimeout(this.allowMouseUpTriggerTimer);
|
|
2229
2454
|
this.allowMouseUpTriggerTimer = undefined;
|
|
2230
2455
|
this.rootContext.setAllowMouseUpTrigger(false);
|
|
2231
2456
|
const trigger = this.elementRef.nativeElement;
|
|
@@ -2515,14 +2740,14 @@ class RdxMenuTrigger {
|
|
|
2515
2740
|
}
|
|
2516
2741
|
}
|
|
2517
2742
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxMenuTrigger, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
2518
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxMenuTrigger, isStandalone: true, selector: "[rdxMenuTrigger]", inputs: { nativeButton: { classPropertyName: "nativeButton", publicName: "nativeButton", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, openOnHover: { classPropertyName: "openOnHover", publicName: "openOnHover", 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 } }, host: { listeners: { "pointerdown": "handlePointerDown($event)", "mousedown": "handleMouseDown($event)", "click": "handleClick($event)", "pointerenter": "handlePointerEnter($event)", "pointermove": "handlePointerMove($event)", "pointerleave": "handlePointerLeave($event)", "keydown.arrowdown": "handleArrowDown($event)", "keydown.arrowup": "handleArrowUp($event)", "keydown.arrowleft": "handleArrowLeft($event)", "keydown.arrowright": "handleArrowRight($event)", "keydown.home": "handleHome($event)", "keydown.end": "handleEnd($event)", "keydown.escape": "handleEscape($event)", "keydown.enter": "handleKeyboardToggle($event)", "keydown.space": "handleKeyboardToggle($event)" }, properties: { "attr.type": "nativeButtonState() ? \"button\" : undefined", "attr.role": "rootContext.hasTriggerInteractionHandler() ? \"menuitem\" : nativeButtonState() ? undefined : \"button\"", "attr.aria-haspopup": "\"menu\"", "attr.aria-expanded": "triggerInteraction.ariaExpanded()", "attr.aria-disabled": "isDisabled() ? true : undefined", "attr.disabled": "nativeButtonState() && isDisabled() ? \"\" : undefined", "attr.data-state": "triggerInteraction.dataState()", "attr.data-disabled": "isDisabled() ? \"\" : undefined", "attr.data-popup-open": "triggerInteraction.dataPopupOpen()", "style.pointer-events": "rootContext.isOpen() && rootContext.modal() ? \"auto\" : undefined" } }, exportAs: ["rdxMenuTrigger"], hostDirectives: [{ directive: i1.RdxPopperAnchor }
|
|
2743
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxMenuTrigger, isStandalone: true, selector: "[rdxMenuTrigger]", inputs: { nativeButton: { classPropertyName: "nativeButton", publicName: "nativeButton", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, openOnHover: { classPropertyName: "openOnHover", publicName: "openOnHover", 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 } }, host: { listeners: { "pointerdown": "handlePointerDown($event)", "mousedown": "handleMouseDown($event)", "click": "handleClick($event)", "pointerenter": "handlePointerEnter($event)", "pointermove": "handlePointerMove($event)", "pointerleave": "handlePointerLeave($event)", "keydown.arrowdown": "handleArrowDown($event)", "keydown.arrowup": "handleArrowUp($event)", "keydown.arrowleft": "handleArrowLeft($event)", "keydown.arrowright": "handleArrowRight($event)", "keydown.home": "handleHome($event)", "keydown.end": "handleEnd($event)", "keydown.escape": "handleEscape($event)", "keydown.enter": "handleKeyboardToggle($event)", "keydown.space": "handleKeyboardToggle($event)" }, properties: { "attr.type": "nativeButtonState() ? \"button\" : undefined", "attr.role": "rootContext.hasTriggerInteractionHandler() ? \"menuitem\" : nativeButtonState() ? undefined : \"button\"", "attr.aria-haspopup": "\"menu\"", "attr.aria-expanded": "triggerInteraction.ariaExpanded()", "attr.aria-disabled": "isDisabled() ? true : undefined", "attr.disabled": "nativeButtonState() && isDisabled() ? \"\" : undefined", "attr.data-state": "triggerInteraction.dataState()", "attr.data-disabled": "isDisabled() ? \"\" : undefined", "attr.data-popup-open": "triggerInteraction.dataPopupOpen()", "style.pointer-events": "rootContext.isOpen() && rootContext.modal() ? \"auto\" : undefined" } }, exportAs: ["rdxMenuTrigger"], hostDirectives: [{ directive: i1.RdxPopperAnchor }], ngImport: i0 }); }
|
|
2519
2744
|
}
|
|
2520
2745
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxMenuTrigger, decorators: [{
|
|
2521
2746
|
type: Directive,
|
|
2522
2747
|
args: [{
|
|
2523
2748
|
selector: '[rdxMenuTrigger]',
|
|
2524
2749
|
exportAs: 'rdxMenuTrigger',
|
|
2525
|
-
hostDirectives: [RdxPopperAnchor
|
|
2750
|
+
hostDirectives: [RdxPopperAnchor],
|
|
2526
2751
|
host: {
|
|
2527
2752
|
'[attr.type]': 'nativeButtonState() ? "button" : undefined',
|
|
2528
2753
|
'[attr.role]': 'rootContext.hasTriggerInteractionHandler() ? "menuitem" : nativeButtonState() ? undefined : "button"',
|