@angular/aria 0.0.1 → 21.0.0-next.10
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 +21 -0
- package/README.md +6 -0
- package/fesm2022/_widget-chunk.mjs +990 -0
- package/fesm2022/_widget-chunk.mjs.map +1 -0
- package/fesm2022/accordion.mjs +192 -0
- package/fesm2022/accordion.mjs.map +1 -0
- package/fesm2022/aria.mjs +7 -0
- package/fesm2022/aria.mjs.map +1 -0
- package/fesm2022/combobox.mjs +145 -0
- package/fesm2022/combobox.mjs.map +1 -0
- package/fesm2022/deferred-content.mjs +60 -0
- package/fesm2022/deferred-content.mjs.map +1 -0
- package/fesm2022/grid.mjs +213 -0
- package/fesm2022/grid.mjs.map +1 -0
- package/fesm2022/listbox.mjs +200 -0
- package/fesm2022/listbox.mjs.map +1 -0
- package/fesm2022/menu.mjs +302 -0
- package/fesm2022/menu.mjs.map +1 -0
- package/fesm2022/radio-group.mjs +197 -0
- package/fesm2022/radio-group.mjs.map +1 -0
- package/fesm2022/tabs.mjs +299 -0
- package/fesm2022/tabs.mjs.map +1 -0
- package/fesm2022/toolbar.mjs +218 -0
- package/fesm2022/toolbar.mjs.map +1 -0
- package/fesm2022/tree.mjs +288 -0
- package/fesm2022/tree.mjs.map +1 -0
- package/fesm2022/ui-patterns.mjs +2951 -0
- package/fesm2022/ui-patterns.mjs.map +1 -0
- package/package.json +86 -3
- package/types/_grid-chunk.d.ts +546 -0
- package/types/accordion.d.ts +92 -0
- package/types/aria.d.ts +6 -0
- package/types/combobox.d.ts +60 -0
- package/types/deferred-content.d.ts +38 -0
- package/types/grid.d.ts +111 -0
- package/types/listbox.d.ts +95 -0
- package/types/menu.d.ts +158 -0
- package/types/radio-group.d.ts +82 -0
- package/types/tabs.d.ts +156 -0
- package/types/toolbar.d.ts +113 -0
- package/types/tree.d.ts +135 -0
- package/types/ui-patterns.d.ts +1604 -0
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { inject, ElementRef, input, output, computed, Directive, contentChildren, signal, afterRenderEffect, untracked, model } from '@angular/core';
|
|
3
|
+
import { MenuTriggerPattern, MenuPattern, MenuBarPattern, MenuItemPattern } from '@angular/aria/ui-patterns';
|
|
4
|
+
import { toSignal } from '@angular/core/rxjs-interop';
|
|
5
|
+
import { Directionality } from '@angular/cdk/bidi';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* A trigger for a menu.
|
|
9
|
+
*
|
|
10
|
+
* The menu trigger is used to open and close menus, and can be placed on menu items to connect
|
|
11
|
+
* sub-menus.
|
|
12
|
+
*/
|
|
13
|
+
class MenuTrigger {
|
|
14
|
+
/** A reference to the menu trigger element. */
|
|
15
|
+
_elementRef = inject(ElementRef);
|
|
16
|
+
/** A reference to the menu element. */
|
|
17
|
+
element = this._elementRef.nativeElement;
|
|
18
|
+
// TODO(wagnermaciel): See we can remove the need to pass in a submenu.
|
|
19
|
+
/** The submenu associated with the menu trigger. */
|
|
20
|
+
submenu = input(undefined, ...(ngDevMode ? [{ debugName: "submenu" }] : []));
|
|
21
|
+
/** A callback function triggered when a menu item is selected. */
|
|
22
|
+
onSubmit = output();
|
|
23
|
+
/** The menu trigger ui pattern instance. */
|
|
24
|
+
uiPattern = new MenuTriggerPattern({
|
|
25
|
+
onSubmit: (value) => this.onSubmit.emit(value),
|
|
26
|
+
element: computed(() => this._elementRef.nativeElement),
|
|
27
|
+
submenu: computed(() => this.submenu()?.uiPattern),
|
|
28
|
+
});
|
|
29
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.0-next.2", ngImport: i0, type: MenuTrigger, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
30
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.2.0-next.2", type: MenuTrigger, isStandalone: true, selector: "button[ngMenuTrigger]", inputs: { submenu: { classPropertyName: "submenu", publicName: "submenu", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onSubmit: "onSubmit" }, host: { listeners: { "click": "uiPattern.onClick()", "keydown": "uiPattern.onKeydown($event)", "focusout": "uiPattern.onFocusOut($event)" }, properties: { "attr.tabindex": "uiPattern.tabindex()", "attr.aria-haspopup": "uiPattern.hasPopup()", "attr.aria-expanded": "uiPattern.expanded()", "attr.aria-controls": "uiPattern.submenu()?.id()" }, classAttribute: "ng-menu-trigger" }, exportAs: ["ngMenuTrigger"], ngImport: i0 });
|
|
31
|
+
}
|
|
32
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.0-next.2", ngImport: i0, type: MenuTrigger, decorators: [{
|
|
33
|
+
type: Directive,
|
|
34
|
+
args: [{
|
|
35
|
+
selector: 'button[ngMenuTrigger]',
|
|
36
|
+
exportAs: 'ngMenuTrigger',
|
|
37
|
+
host: {
|
|
38
|
+
'class': 'ng-menu-trigger',
|
|
39
|
+
'[attr.tabindex]': 'uiPattern.tabindex()',
|
|
40
|
+
'[attr.aria-haspopup]': 'uiPattern.hasPopup()',
|
|
41
|
+
'[attr.aria-expanded]': 'uiPattern.expanded()',
|
|
42
|
+
'[attr.aria-controls]': 'uiPattern.submenu()?.id()',
|
|
43
|
+
'(click)': 'uiPattern.onClick()',
|
|
44
|
+
'(keydown)': 'uiPattern.onKeydown($event)',
|
|
45
|
+
'(focusout)': 'uiPattern.onFocusOut($event)',
|
|
46
|
+
},
|
|
47
|
+
}]
|
|
48
|
+
}] });
|
|
49
|
+
/**
|
|
50
|
+
* A list of menu items.
|
|
51
|
+
*
|
|
52
|
+
* A menu is used to offer a list of menu item choices to users. Menus can be nested within other
|
|
53
|
+
* menus to create sub-menus.
|
|
54
|
+
*
|
|
55
|
+
* ```html
|
|
56
|
+
* <button ngMenuTrigger menu="menu">Options</button>
|
|
57
|
+
*
|
|
58
|
+
* <div ngMenu #menu="ngMenu">
|
|
59
|
+
* <div ngMenuItem>Star</div>
|
|
60
|
+
* <div ngMenuItem>Edit</div>
|
|
61
|
+
* <div ngMenuItem>Delete</div>
|
|
62
|
+
* </div>
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
class Menu {
|
|
66
|
+
/** The menu items contained in the menu. */
|
|
67
|
+
_allItems = contentChildren(MenuItem, ...(ngDevMode ? [{ debugName: "_allItems", descendants: true }] : [{ descendants: true }]));
|
|
68
|
+
/** The menu items that are direct children of this menu. */
|
|
69
|
+
_items = computed(() => this._allItems().filter(i => i.parent === this), ...(ngDevMode ? [{ debugName: "_items" }] : []));
|
|
70
|
+
/** A reference to the menu element. */
|
|
71
|
+
_elementRef = inject(ElementRef);
|
|
72
|
+
/** A reference to the menu element. */
|
|
73
|
+
element = this._elementRef.nativeElement;
|
|
74
|
+
/** The directionality (LTR / RTL) context for the application (or a subtree of it). */
|
|
75
|
+
_directionality = inject(Directionality);
|
|
76
|
+
/** A signal wrapper for directionality. */
|
|
77
|
+
textDirection = toSignal(this._directionality.change, {
|
|
78
|
+
initialValue: this._directionality.value,
|
|
79
|
+
});
|
|
80
|
+
/** The submenu associated with the menu. */
|
|
81
|
+
submenu = input(undefined, ...(ngDevMode ? [{ debugName: "submenu" }] : []));
|
|
82
|
+
/** The unique ID of the menu. */
|
|
83
|
+
id = input(Math.random().toString(36).substring(2, 10), ...(ngDevMode ? [{ debugName: "id" }] : []));
|
|
84
|
+
/** Whether the menu should wrap its items. */
|
|
85
|
+
wrap = input(true, ...(ngDevMode ? [{ debugName: "wrap" }] : []));
|
|
86
|
+
/** The delay in seconds before the typeahead buffer is cleared. */
|
|
87
|
+
typeaheadDelay = input(0.5, ...(ngDevMode ? [{ debugName: "typeaheadDelay" }] : [])); // Picked arbitrarily.
|
|
88
|
+
/** A reference to the parent menu item or menu trigger. */
|
|
89
|
+
parent = input(...(ngDevMode ? [undefined, { debugName: "parent" }] : []));
|
|
90
|
+
/** The menu ui pattern instance. */
|
|
91
|
+
uiPattern;
|
|
92
|
+
/**
|
|
93
|
+
* The menu items as a writable signal.
|
|
94
|
+
*
|
|
95
|
+
* TODO(wagnermaciel): This would normally be a computed, but using a computed causes a bug where
|
|
96
|
+
* sometimes the items array is empty. The bug can be reproduced by switching this to use a
|
|
97
|
+
* computed and then quickly opening and closing menus in the dev app.
|
|
98
|
+
*/
|
|
99
|
+
items = () => this._items().map(i => i.uiPattern);
|
|
100
|
+
/** Whether the menu is visible. */
|
|
101
|
+
isVisible = computed(() => this.uiPattern.isVisible(), ...(ngDevMode ? [{ debugName: "isVisible" }] : []));
|
|
102
|
+
/** A callback function triggered when a menu item is selected. */
|
|
103
|
+
onSubmit = output();
|
|
104
|
+
constructor() {
|
|
105
|
+
this.uiPattern = new MenuPattern({
|
|
106
|
+
...this,
|
|
107
|
+
parent: computed(() => this.parent()?.uiPattern),
|
|
108
|
+
multi: () => false,
|
|
109
|
+
skipDisabled: () => false,
|
|
110
|
+
focusMode: () => 'roving',
|
|
111
|
+
orientation: () => 'vertical',
|
|
112
|
+
selectionMode: () => 'explicit',
|
|
113
|
+
activeItem: signal(undefined),
|
|
114
|
+
element: computed(() => this._elementRef.nativeElement),
|
|
115
|
+
onSubmit: (value) => this.onSubmit.emit(value),
|
|
116
|
+
});
|
|
117
|
+
// TODO(wagnermaciel): This is a redundancy needed for if the user uses display: none to hide
|
|
118
|
+
// submenus. In those cases, the ui pattern is calling focus() before the ui has a chance to
|
|
119
|
+
// update the display property. The result is focus() being called on an element that is not
|
|
120
|
+
// focusable. This simply retries focusing the element after render.
|
|
121
|
+
afterRenderEffect(() => {
|
|
122
|
+
if (this.uiPattern.isVisible()) {
|
|
123
|
+
const activeItem = untracked(() => this.uiPattern.inputs.activeItem());
|
|
124
|
+
this.uiPattern.listBehavior.goto(activeItem);
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
afterRenderEffect(() => {
|
|
128
|
+
if (!this.uiPattern.hasBeenFocused()) {
|
|
129
|
+
this.uiPattern.setDefaultState();
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
// TODO(wagnermaciel): Author close, closeAll, and open methods for each directive.
|
|
134
|
+
/** Closes the menu. */
|
|
135
|
+
close(opts) {
|
|
136
|
+
this.uiPattern.inputs.parent()?.close(opts);
|
|
137
|
+
}
|
|
138
|
+
/** Closes all parent menus. */
|
|
139
|
+
closeAll(opts) {
|
|
140
|
+
const root = this.uiPattern.root();
|
|
141
|
+
if (root instanceof MenuTriggerPattern) {
|
|
142
|
+
root.close(opts);
|
|
143
|
+
}
|
|
144
|
+
if (root instanceof MenuPattern || root instanceof MenuBarPattern) {
|
|
145
|
+
root.inputs.activeItem()?.close(opts);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.0-next.2", ngImport: i0, type: Menu, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
149
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "20.2.0-next.2", type: Menu, isStandalone: true, selector: "[ngMenu]", inputs: { submenu: { classPropertyName: "submenu", publicName: "submenu", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, wrap: { classPropertyName: "wrap", publicName: "wrap", isSignal: true, isRequired: false, transformFunction: null }, typeaheadDelay: { classPropertyName: "typeaheadDelay", publicName: "typeaheadDelay", isSignal: true, isRequired: false, transformFunction: null }, parent: { classPropertyName: "parent", publicName: "parent", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onSubmit: "onSubmit" }, host: { attributes: { "role": "menu" }, listeners: { "keydown": "uiPattern.onKeydown($event)", "mouseover": "uiPattern.onMouseOver($event)", "mouseout": "uiPattern.onMouseOut($event)", "focusout": "uiPattern.onFocusOut($event)", "focusin": "uiPattern.onFocusIn()", "click": "uiPattern.onClick($event)" }, properties: { "attr.id": "uiPattern.id()", "attr.data-visible": "uiPattern.isVisible()" }, classAttribute: "ng-menu" }, queries: [{ propertyName: "_allItems", predicate: MenuItem, descendants: true, isSignal: true }], exportAs: ["ngMenu"], ngImport: i0 });
|
|
150
|
+
}
|
|
151
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.0-next.2", ngImport: i0, type: Menu, decorators: [{
|
|
152
|
+
type: Directive,
|
|
153
|
+
args: [{
|
|
154
|
+
selector: '[ngMenu]',
|
|
155
|
+
exportAs: 'ngMenu',
|
|
156
|
+
host: {
|
|
157
|
+
'role': 'menu',
|
|
158
|
+
'class': 'ng-menu',
|
|
159
|
+
'[attr.id]': 'uiPattern.id()',
|
|
160
|
+
'[attr.data-visible]': 'uiPattern.isVisible()',
|
|
161
|
+
'(keydown)': 'uiPattern.onKeydown($event)',
|
|
162
|
+
'(mouseover)': 'uiPattern.onMouseOver($event)',
|
|
163
|
+
'(mouseout)': 'uiPattern.onMouseOut($event)',
|
|
164
|
+
'(focusout)': 'uiPattern.onFocusOut($event)',
|
|
165
|
+
'(focusin)': 'uiPattern.onFocusIn()',
|
|
166
|
+
'(click)': 'uiPattern.onClick($event)',
|
|
167
|
+
},
|
|
168
|
+
}]
|
|
169
|
+
}], ctorParameters: () => [] });
|
|
170
|
+
/**
|
|
171
|
+
* A menu bar of menu items.
|
|
172
|
+
*
|
|
173
|
+
* Like the menu, a menubar is used to offer a list of menu item choices to users. However, a
|
|
174
|
+
* menubar is used to display a persistent, top-level,
|
|
175
|
+
* always-visible set of menu item choices.
|
|
176
|
+
*/
|
|
177
|
+
class MenuBar {
|
|
178
|
+
/** The menu items contained in the menubar. */
|
|
179
|
+
_allItems = contentChildren(MenuItem, ...(ngDevMode ? [{ debugName: "_allItems", descendants: true }] : [{ descendants: true }]));
|
|
180
|
+
_items = () => this._allItems().filter(i => i.parent === this);
|
|
181
|
+
/** A reference to the menu element. */
|
|
182
|
+
_elementRef = inject(ElementRef);
|
|
183
|
+
/** A reference to the menubar element. */
|
|
184
|
+
element = this._elementRef.nativeElement;
|
|
185
|
+
/** The directionality (LTR / RTL) context for the application (or a subtree of it). */
|
|
186
|
+
_directionality = inject(Directionality);
|
|
187
|
+
/** A signal wrapper for directionality. */
|
|
188
|
+
textDirection = toSignal(this._directionality.change, {
|
|
189
|
+
initialValue: this._directionality.value,
|
|
190
|
+
});
|
|
191
|
+
/** The value of the menu. */
|
|
192
|
+
value = model([], ...(ngDevMode ? [{ debugName: "value" }] : []));
|
|
193
|
+
/** Whether the menu should wrap its items. */
|
|
194
|
+
wrap = input(true, ...(ngDevMode ? [{ debugName: "wrap" }] : []));
|
|
195
|
+
/** The delay in seconds before the typeahead buffer is cleared. */
|
|
196
|
+
typeaheadDelay = input(0.5, ...(ngDevMode ? [{ debugName: "typeaheadDelay" }] : []));
|
|
197
|
+
/** The menu ui pattern instance. */
|
|
198
|
+
uiPattern;
|
|
199
|
+
/** The menu items as a writable signal. */
|
|
200
|
+
items = signal([], ...(ngDevMode ? [{ debugName: "items" }] : []));
|
|
201
|
+
/** A callback function triggered when a menu item is selected. */
|
|
202
|
+
onSubmit = output();
|
|
203
|
+
constructor() {
|
|
204
|
+
this.uiPattern = new MenuBarPattern({
|
|
205
|
+
...this,
|
|
206
|
+
multi: () => false,
|
|
207
|
+
skipDisabled: () => false,
|
|
208
|
+
focusMode: () => 'roving',
|
|
209
|
+
orientation: () => 'horizontal',
|
|
210
|
+
selectionMode: () => 'explicit',
|
|
211
|
+
onSubmit: (value) => this.onSubmit.emit(value),
|
|
212
|
+
activeItem: signal(undefined),
|
|
213
|
+
element: computed(() => this._elementRef.nativeElement),
|
|
214
|
+
});
|
|
215
|
+
afterRenderEffect(() => {
|
|
216
|
+
this.items.set(this._items().map(i => i.uiPattern));
|
|
217
|
+
});
|
|
218
|
+
afterRenderEffect(() => {
|
|
219
|
+
if (!this.uiPattern.hasBeenFocused()) {
|
|
220
|
+
this.uiPattern.setDefaultState();
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.0-next.2", ngImport: i0, type: MenuBar, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
225
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "20.2.0-next.2", type: MenuBar, isStandalone: true, selector: "[ngMenuBar]", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, wrap: { classPropertyName: "wrap", publicName: "wrap", isSignal: true, isRequired: false, transformFunction: null }, typeaheadDelay: { classPropertyName: "typeaheadDelay", publicName: "typeaheadDelay", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", onSubmit: "onSubmit" }, host: { attributes: { "role": "menubar" }, listeners: { "keydown": "uiPattern.onKeydown($event)", "mouseover": "uiPattern.onMouseOver($event)", "click": "uiPattern.onClick($event)", "focusin": "uiPattern.onFocusIn()", "focusout": "uiPattern.onFocusOut($event)" }, classAttribute: "ng-menu-bar" }, queries: [{ propertyName: "_allItems", predicate: MenuItem, descendants: true, isSignal: true }], exportAs: ["ngMenuBar"], ngImport: i0 });
|
|
226
|
+
}
|
|
227
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.0-next.2", ngImport: i0, type: MenuBar, decorators: [{
|
|
228
|
+
type: Directive,
|
|
229
|
+
args: [{
|
|
230
|
+
selector: '[ngMenuBar]',
|
|
231
|
+
exportAs: 'ngMenuBar',
|
|
232
|
+
host: {
|
|
233
|
+
'role': 'menubar',
|
|
234
|
+
'class': 'ng-menu-bar',
|
|
235
|
+
'(keydown)': 'uiPattern.onKeydown($event)',
|
|
236
|
+
'(mouseover)': 'uiPattern.onMouseOver($event)',
|
|
237
|
+
'(click)': 'uiPattern.onClick($event)',
|
|
238
|
+
'(focusin)': 'uiPattern.onFocusIn()',
|
|
239
|
+
'(focusout)': 'uiPattern.onFocusOut($event)',
|
|
240
|
+
},
|
|
241
|
+
}]
|
|
242
|
+
}], ctorParameters: () => [] });
|
|
243
|
+
/**
|
|
244
|
+
* An item in a Menu.
|
|
245
|
+
*
|
|
246
|
+
* Menu items can be used in menus and menubars to represent a choice or action a user can take.
|
|
247
|
+
*/
|
|
248
|
+
class MenuItem {
|
|
249
|
+
/** A reference to the menu item element. */
|
|
250
|
+
_elementRef = inject(ElementRef);
|
|
251
|
+
/** A reference to the menu element. */
|
|
252
|
+
element = this._elementRef.nativeElement;
|
|
253
|
+
/** The unique ID of the menu item. */
|
|
254
|
+
id = input(Math.random().toString(36).substring(2, 10), ...(ngDevMode ? [{ debugName: "id" }] : []));
|
|
255
|
+
/** The value of the menu item. */
|
|
256
|
+
value = input.required(...(ngDevMode ? [{ debugName: "value" }] : []));
|
|
257
|
+
/** Whether the menu item is disabled. */
|
|
258
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
|
|
259
|
+
// TODO(wagnermaciel): Discuss whether all inputs should be models.
|
|
260
|
+
/** The search term associated with the menu item. */
|
|
261
|
+
searchTerm = model('', ...(ngDevMode ? [{ debugName: "searchTerm" }] : []));
|
|
262
|
+
/** A reference to the parent menu. */
|
|
263
|
+
_menu = inject(Menu, { optional: true });
|
|
264
|
+
/** A reference to the parent menu bar. */
|
|
265
|
+
_menuBar = inject(MenuBar, { optional: true });
|
|
266
|
+
/** A reference to the parent menu or menubar. */
|
|
267
|
+
parent = this._menu ?? this._menuBar;
|
|
268
|
+
/** The submenu associated with the menu item. */
|
|
269
|
+
submenu = input(undefined, ...(ngDevMode ? [{ debugName: "submenu" }] : []));
|
|
270
|
+
/** The menu item ui pattern instance. */
|
|
271
|
+
uiPattern = new MenuItemPattern({
|
|
272
|
+
id: this.id,
|
|
273
|
+
value: this.value,
|
|
274
|
+
element: computed(() => this._elementRef.nativeElement),
|
|
275
|
+
disabled: this.disabled,
|
|
276
|
+
searchTerm: this.searchTerm,
|
|
277
|
+
parent: computed(() => this.parent?.uiPattern),
|
|
278
|
+
submenu: computed(() => this.submenu()?.uiPattern),
|
|
279
|
+
});
|
|
280
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.0-next.2", ngImport: i0, type: MenuItem, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
281
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.2.0-next.2", type: MenuItem, isStandalone: true, selector: "[ngMenuItem]", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, searchTerm: { classPropertyName: "searchTerm", publicName: "searchTerm", isSignal: true, isRequired: false, transformFunction: null }, submenu: { classPropertyName: "submenu", publicName: "submenu", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { searchTerm: "searchTermChange" }, host: { attributes: { "role": "menuitem" }, properties: { "attr.tabindex": "uiPattern.tabindex()", "attr.data-active": "uiPattern.isActive()", "attr.aria-haspopup": "uiPattern.hasPopup()", "attr.aria-expanded": "uiPattern.expanded()", "attr.aria-disabled": "uiPattern.disabled()", "attr.aria-controls": "uiPattern.submenu()?.id()" }, classAttribute: "ng-menu-item" }, exportAs: ["ngMenuItem"], ngImport: i0 });
|
|
282
|
+
}
|
|
283
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.0-next.2", ngImport: i0, type: MenuItem, decorators: [{
|
|
284
|
+
type: Directive,
|
|
285
|
+
args: [{
|
|
286
|
+
selector: '[ngMenuItem]',
|
|
287
|
+
exportAs: 'ngMenuItem',
|
|
288
|
+
host: {
|
|
289
|
+
'role': 'menuitem',
|
|
290
|
+
'class': 'ng-menu-item',
|
|
291
|
+
'[attr.tabindex]': 'uiPattern.tabindex()',
|
|
292
|
+
'[attr.data-active]': 'uiPattern.isActive()',
|
|
293
|
+
'[attr.aria-haspopup]': 'uiPattern.hasPopup()',
|
|
294
|
+
'[attr.aria-expanded]': 'uiPattern.expanded()',
|
|
295
|
+
'[attr.aria-disabled]': 'uiPattern.disabled()',
|
|
296
|
+
'[attr.aria-controls]': 'uiPattern.submenu()?.id()',
|
|
297
|
+
},
|
|
298
|
+
}]
|
|
299
|
+
}] });
|
|
300
|
+
|
|
301
|
+
export { Menu, MenuBar, MenuItem, MenuTrigger };
|
|
302
|
+
//# sourceMappingURL=menu.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"menu.mjs","sources":["../../../../../darwin_arm64-fastbuild-ST-199a4f3c4e20/bin/src/aria/menu/menu.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport {\n afterRenderEffect,\n computed,\n contentChildren,\n Directive,\n ElementRef,\n inject,\n input,\n model,\n output,\n Signal,\n signal,\n untracked,\n} from '@angular/core';\nimport {\n SignalLike,\n MenuBarPattern,\n MenuItemPattern,\n MenuPattern,\n MenuTriggerPattern,\n} from '@angular/aria/ui-patterns';\nimport {toSignal} from '@angular/core/rxjs-interop';\nimport {Directionality} from '@angular/cdk/bidi';\n\n/**\n * A trigger for a menu.\n *\n * The menu trigger is used to open and close menus, and can be placed on menu items to connect\n * sub-menus.\n */\n@Directive({\n selector: 'button[ngMenuTrigger]',\n exportAs: 'ngMenuTrigger',\n host: {\n 'class': 'ng-menu-trigger',\n '[attr.tabindex]': 'uiPattern.tabindex()',\n '[attr.aria-haspopup]': 'uiPattern.hasPopup()',\n '[attr.aria-expanded]': 'uiPattern.expanded()',\n '[attr.aria-controls]': 'uiPattern.submenu()?.id()',\n '(click)': 'uiPattern.onClick()',\n '(keydown)': 'uiPattern.onKeydown($event)',\n '(focusout)': 'uiPattern.onFocusOut($event)',\n },\n})\nexport class MenuTrigger<V> {\n /** A reference to the menu trigger element. */\n private readonly _elementRef = inject(ElementRef);\n\n /** A reference to the menu element. */\n readonly element: HTMLButtonElement = this._elementRef.nativeElement;\n\n // TODO(wagnermaciel): See we can remove the need to pass in a submenu.\n\n /** The submenu associated with the menu trigger. */\n submenu = input<Menu<V> | undefined>(undefined);\n\n /** A callback function triggered when a menu item is selected. */\n onSubmit = output<V>();\n\n /** The menu trigger ui pattern instance. */\n uiPattern: MenuTriggerPattern<V> = new MenuTriggerPattern({\n onSubmit: (value: V) => this.onSubmit.emit(value),\n element: computed(() => this._elementRef.nativeElement),\n submenu: computed(() => this.submenu()?.uiPattern),\n });\n}\n\n/**\n * A list of menu items.\n *\n * A menu is used to offer a list of menu item choices to users. Menus can be nested within other\n * menus to create sub-menus.\n *\n * ```html\n * <button ngMenuTrigger menu=\"menu\">Options</button>\n *\n * <div ngMenu #menu=\"ngMenu\">\n * <div ngMenuItem>Star</div>\n * <div ngMenuItem>Edit</div>\n * <div ngMenuItem>Delete</div>\n * </div>\n * ```\n */\n@Directive({\n selector: '[ngMenu]',\n exportAs: 'ngMenu',\n host: {\n 'role': 'menu',\n 'class': 'ng-menu',\n '[attr.id]': 'uiPattern.id()',\n '[attr.data-visible]': 'uiPattern.isVisible()',\n '(keydown)': 'uiPattern.onKeydown($event)',\n '(mouseover)': 'uiPattern.onMouseOver($event)',\n '(mouseout)': 'uiPattern.onMouseOut($event)',\n '(focusout)': 'uiPattern.onFocusOut($event)',\n '(focusin)': 'uiPattern.onFocusIn()',\n '(click)': 'uiPattern.onClick($event)',\n },\n})\nexport class Menu<V> {\n /** The menu items contained in the menu. */\n readonly _allItems = contentChildren<MenuItem<V>>(MenuItem, {descendants: true});\n\n /** The menu items that are direct children of this menu. */\n readonly _items: Signal<MenuItem<V>[]> = computed(() =>\n this._allItems().filter(i => i.parent === this),\n );\n\n /** A reference to the menu element. */\n private readonly _elementRef = inject(ElementRef);\n\n /** A reference to the menu element. */\n readonly element: HTMLElement = this._elementRef.nativeElement;\n\n /** The directionality (LTR / RTL) context for the application (or a subtree of it). */\n private readonly _directionality = inject(Directionality);\n\n /** A signal wrapper for directionality. */\n readonly textDirection = toSignal(this._directionality.change, {\n initialValue: this._directionality.value,\n });\n\n /** The submenu associated with the menu. */\n readonly submenu = input<Menu<V> | undefined>(undefined);\n\n /** The unique ID of the menu. */\n readonly id = input<string>(Math.random().toString(36).substring(2, 10));\n\n /** Whether the menu should wrap its items. */\n readonly wrap = input<boolean>(true);\n\n /** The delay in seconds before the typeahead buffer is cleared. */\n readonly typeaheadDelay = input<number>(0.5); // Picked arbitrarily.\n\n /** A reference to the parent menu item or menu trigger. */\n readonly parent = input<MenuTrigger<V> | MenuItem<V>>();\n\n /** The menu ui pattern instance. */\n readonly uiPattern: MenuPattern<V>;\n\n /**\n * The menu items as a writable signal.\n *\n * TODO(wagnermaciel): This would normally be a computed, but using a computed causes a bug where\n * sometimes the items array is empty. The bug can be reproduced by switching this to use a\n * computed and then quickly opening and closing menus in the dev app.\n */\n readonly items = () => this._items().map(i => i.uiPattern);\n\n /** Whether the menu is visible. */\n isVisible = computed(() => this.uiPattern.isVisible());\n\n /** A callback function triggered when a menu item is selected. */\n onSubmit = output<V>();\n\n constructor() {\n this.uiPattern = new MenuPattern({\n ...this,\n parent: computed(() => this.parent()?.uiPattern),\n multi: () => false,\n skipDisabled: () => false,\n focusMode: () => 'roving',\n orientation: () => 'vertical',\n selectionMode: () => 'explicit',\n activeItem: signal(undefined),\n element: computed(() => this._elementRef.nativeElement),\n onSubmit: (value: V) => this.onSubmit.emit(value),\n });\n\n // TODO(wagnermaciel): This is a redundancy needed for if the user uses display: none to hide\n // submenus. In those cases, the ui pattern is calling focus() before the ui has a chance to\n // update the display property. The result is focus() being called on an element that is not\n // focusable. This simply retries focusing the element after render.\n afterRenderEffect(() => {\n if (this.uiPattern.isVisible()) {\n const activeItem = untracked(() => this.uiPattern.inputs.activeItem());\n this.uiPattern.listBehavior.goto(activeItem!);\n }\n });\n\n afterRenderEffect(() => {\n if (!this.uiPattern.hasBeenFocused()) {\n this.uiPattern.setDefaultState();\n }\n });\n }\n\n // TODO(wagnermaciel): Author close, closeAll, and open methods for each directive.\n\n /** Closes the menu. */\n close(opts?: {refocus?: boolean}) {\n this.uiPattern.inputs.parent()?.close(opts);\n }\n\n /** Closes all parent menus. */\n closeAll(opts?: {refocus?: boolean}) {\n const root = this.uiPattern.root();\n\n if (root instanceof MenuTriggerPattern) {\n root.close(opts);\n }\n\n if (root instanceof MenuPattern || root instanceof MenuBarPattern) {\n root.inputs.activeItem()?.close(opts);\n }\n }\n}\n\n/**\n * A menu bar of menu items.\n *\n * Like the menu, a menubar is used to offer a list of menu item choices to users. However, a\n * menubar is used to display a persistent, top-level,\n * always-visible set of menu item choices.\n */\n@Directive({\n selector: '[ngMenuBar]',\n exportAs: 'ngMenuBar',\n host: {\n 'role': 'menubar',\n 'class': 'ng-menu-bar',\n '(keydown)': 'uiPattern.onKeydown($event)',\n '(mouseover)': 'uiPattern.onMouseOver($event)',\n '(click)': 'uiPattern.onClick($event)',\n '(focusin)': 'uiPattern.onFocusIn()',\n '(focusout)': 'uiPattern.onFocusOut($event)',\n },\n})\nexport class MenuBar<V> {\n /** The menu items contained in the menubar. */\n readonly _allItems = contentChildren<MenuItem<V>>(MenuItem, {descendants: true});\n\n readonly _items: SignalLike<MenuItem<V>[]> = () =>\n this._allItems().filter(i => i.parent === this);\n\n /** A reference to the menu element. */\n private readonly _elementRef = inject(ElementRef);\n\n /** A reference to the menubar element. */\n readonly element: HTMLElement = this._elementRef.nativeElement;\n\n /** The directionality (LTR / RTL) context for the application (or a subtree of it). */\n private readonly _directionality = inject(Directionality);\n\n /** A signal wrapper for directionality. */\n readonly textDirection = toSignal(this._directionality.change, {\n initialValue: this._directionality.value,\n });\n\n /** The value of the menu. */\n readonly value = model<V[]>([]);\n\n /** Whether the menu should wrap its items. */\n readonly wrap = input<boolean>(true);\n\n /** The delay in seconds before the typeahead buffer is cleared. */\n readonly typeaheadDelay = input<number>(0.5);\n\n /** The menu ui pattern instance. */\n readonly uiPattern: MenuBarPattern<V>;\n\n /** The menu items as a writable signal. */\n readonly items = signal<MenuItemPattern<V>[]>([]);\n\n /** A callback function triggered when a menu item is selected. */\n onSubmit = output<V>();\n\n constructor() {\n this.uiPattern = new MenuBarPattern({\n ...this,\n multi: () => false,\n skipDisabled: () => false,\n focusMode: () => 'roving',\n orientation: () => 'horizontal',\n selectionMode: () => 'explicit',\n onSubmit: (value: V) => this.onSubmit.emit(value),\n activeItem: signal(undefined),\n element: computed(() => this._elementRef.nativeElement),\n });\n\n afterRenderEffect(() => {\n this.items.set(this._items().map(i => i.uiPattern));\n });\n\n afterRenderEffect(() => {\n if (!this.uiPattern.hasBeenFocused()) {\n this.uiPattern.setDefaultState();\n }\n });\n }\n}\n\n/**\n * An item in a Menu.\n *\n * Menu items can be used in menus and menubars to represent a choice or action a user can take.\n */\n@Directive({\n selector: '[ngMenuItem]',\n exportAs: 'ngMenuItem',\n host: {\n 'role': 'menuitem',\n 'class': 'ng-menu-item',\n '[attr.tabindex]': 'uiPattern.tabindex()',\n '[attr.data-active]': 'uiPattern.isActive()',\n '[attr.aria-haspopup]': 'uiPattern.hasPopup()',\n '[attr.aria-expanded]': 'uiPattern.expanded()',\n '[attr.aria-disabled]': 'uiPattern.disabled()',\n '[attr.aria-controls]': 'uiPattern.submenu()?.id()',\n },\n})\nexport class MenuItem<V> {\n /** A reference to the menu item element. */\n private readonly _elementRef = inject(ElementRef);\n\n /** A reference to the menu element. */\n readonly element: HTMLElement = this._elementRef.nativeElement;\n\n /** The unique ID of the menu item. */\n readonly id = input<string>(Math.random().toString(36).substring(2, 10));\n\n /** The value of the menu item. */\n readonly value = input.required<V>();\n\n /** Whether the menu item is disabled. */\n readonly disabled = input<boolean>(false);\n\n // TODO(wagnermaciel): Discuss whether all inputs should be models.\n\n /** The search term associated with the menu item. */\n readonly searchTerm = model<string>('');\n\n /** A reference to the parent menu. */\n private readonly _menu = inject<Menu<V>>(Menu, {optional: true});\n\n /** A reference to the parent menu bar. */\n private readonly _menuBar = inject<MenuBar<V>>(MenuBar, {optional: true});\n\n /** A reference to the parent menu or menubar. */\n readonly parent = this._menu ?? this._menuBar;\n\n /** The submenu associated with the menu item. */\n readonly submenu = input<Menu<V> | undefined>(undefined);\n\n /** The menu item ui pattern instance. */\n readonly uiPattern: MenuItemPattern<V> = new MenuItemPattern<V>({\n id: this.id,\n value: this.value,\n element: computed(() => this._elementRef.nativeElement),\n disabled: this.disabled,\n searchTerm: this.searchTerm,\n parent: computed(() => this.parent?.uiPattern),\n submenu: computed(() => this.submenu()?.uiPattern),\n });\n}\n"],"names":[],"mappings":";;;;;;AAgCA;;;;;AAKG;MAeU,WAAW,CAAA;;AAEL,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC;;AAGxC,IAAA,OAAO,GAAsB,IAAI,CAAC,WAAW,CAAC,aAAa;;;AAKpE,IAAA,OAAO,GAAG,KAAK,CAAsB,SAAS,mDAAC;;IAG/C,QAAQ,GAAG,MAAM,EAAK;;IAGtB,SAAS,GAA0B,IAAI,kBAAkB,CAAC;AACxD,QAAA,QAAQ,EAAE,CAAC,KAAQ,KAAK,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;QACjD,OAAO,EAAE,QAAQ,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC;AACvD,QAAA,OAAO,EAAE,QAAQ,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC;AACnD,KAAA,CAAC;8GApBS,WAAW,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;kGAAX,WAAW,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,uBAAA,EAAA,MAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,QAAA,EAAA,UAAA,EAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,OAAA,EAAA,qBAAA,EAAA,SAAA,EAAA,6BAAA,EAAA,UAAA,EAAA,8BAAA,EAAA,EAAA,UAAA,EAAA,EAAA,eAAA,EAAA,sBAAA,EAAA,oBAAA,EAAA,sBAAA,EAAA,oBAAA,EAAA,sBAAA,EAAA,oBAAA,EAAA,2BAAA,EAAA,EAAA,cAAA,EAAA,iBAAA,EAAA,EAAA,QAAA,EAAA,CAAA,eAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;kGAAX,WAAW,EAAA,UAAA,EAAA,CAAA;kBAdvB,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,uBAAuB;AACjC,oBAAA,QAAQ,EAAE,eAAe;AACzB,oBAAA,IAAI,EAAE;AACJ,wBAAA,OAAO,EAAE,iBAAiB;AAC1B,wBAAA,iBAAiB,EAAE,sBAAsB;AACzC,wBAAA,sBAAsB,EAAE,sBAAsB;AAC9C,wBAAA,sBAAsB,EAAE,sBAAsB;AAC9C,wBAAA,sBAAsB,EAAE,2BAA2B;AACnD,wBAAA,SAAS,EAAE,qBAAqB;AAChC,wBAAA,WAAW,EAAE,6BAA6B;AAC1C,wBAAA,YAAY,EAAE,8BAA8B;AAC7C,qBAAA;AACF,iBAAA;;AAwBD;;;;;;;;;;;;;;;AAeG;MAiBU,IAAI,CAAA;;AAEN,IAAA,SAAS,GAAG,eAAe,CAAc,QAAQ,6CAAG,WAAW,EAAE,IAAI,EAAA,CAAA,GAAA,CAAlB,EAAC,WAAW,EAAE,IAAI,EAAC,GAAC;;IAGvE,MAAM,GAA0B,QAAQ,CAAC,MAChD,IAAI,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,EAAA,IAAA,SAAA,GAAA,CAAA,EAAA,SAAA,EAAA,QAAA,EAAA,CAAA,GAAA,EAAA,CAAA,CAChD;;AAGgB,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC;;AAGxC,IAAA,OAAO,GAAgB,IAAI,CAAC,WAAW,CAAC,aAAa;;AAG7C,IAAA,eAAe,GAAG,MAAM,CAAC,cAAc,CAAC;;IAGhD,aAAa,GAAG,QAAQ,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE;AAC7D,QAAA,YAAY,EAAE,IAAI,CAAC,eAAe,CAAC,KAAK;AACzC,KAAA,CAAC;;AAGO,IAAA,OAAO,GAAG,KAAK,CAAsB,SAAS,mDAAC;;IAG/C,EAAE,GAAG,KAAK,CAAS,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,8CAAC;;AAG/D,IAAA,IAAI,GAAG,KAAK,CAAU,IAAI,gDAAC;;AAG3B,IAAA,cAAc,GAAG,KAAK,CAAS,GAAG,EAAC,IAAA,SAAA,GAAA,CAAA,EAAA,SAAA,EAAA,gBAAA,EAAA,CAAA,GAAA,EAAA,CAAA,CAAA,CAAC;;IAGpC,MAAM,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,QAAA,EAAA,CAAA,GAAA,EAAA,CAAA,CAAgC;;AAG9C,IAAA,SAAS;AAElB;;;;;;AAMG;AACM,IAAA,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC;;AAG1D,IAAA,SAAS,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,qDAAC;;IAGtD,QAAQ,GAAG,MAAM,EAAK;AAEtB,IAAA,WAAA,GAAA;AACE,QAAA,IAAI,CAAC,SAAS,GAAG,IAAI,WAAW,CAAC;AAC/B,YAAA,GAAG,IAAI;AACP,YAAA,MAAM,EAAE,QAAQ,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,EAAE,SAAS,CAAC;AAChD,YAAA,KAAK,EAAE,MAAM,KAAK;AAClB,YAAA,YAAY,EAAE,MAAM,KAAK;AACzB,YAAA,SAAS,EAAE,MAAM,QAAQ;AACzB,YAAA,WAAW,EAAE,MAAM,UAAU;AAC7B,YAAA,aAAa,EAAE,MAAM,UAAU;AAC/B,YAAA,UAAU,EAAE,MAAM,CAAC,SAAS,CAAC;YAC7B,OAAO,EAAE,QAAQ,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC;AACvD,YAAA,QAAQ,EAAE,CAAC,KAAQ,KAAK,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;AAClD,SAAA,CAAC;;;;;QAMF,iBAAiB,CAAC,MAAK;AACrB,YAAA,IAAI,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE;AAC9B,gBAAA,MAAM,UAAU,GAAG,SAAS,CAAC,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;gBACtE,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,UAAW,CAAC;;AAEjD,SAAC,CAAC;QAEF,iBAAiB,CAAC,MAAK;YACrB,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,EAAE;AACpC,gBAAA,IAAI,CAAC,SAAS,CAAC,eAAe,EAAE;;AAEpC,SAAC,CAAC;;;;AAMJ,IAAA,KAAK,CAAC,IAA0B,EAAA;AAC9B,QAAA,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC;;;AAI7C,IAAA,QAAQ,CAAC,IAA0B,EAAA;QACjC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE;AAElC,QAAA,IAAI,IAAI,YAAY,kBAAkB,EAAE;AACtC,YAAA,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;;QAGlB,IAAI,IAAI,YAAY,WAAW,IAAI,IAAI,YAAY,cAAc,EAAE;YACjE,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC;;;8GAxG9B,IAAI,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAJ,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,eAAA,EAAA,IAAA,EAAA,IAAI,sqCAEmC,QAAQ,EAAA,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;kGAF/C,IAAI,EAAA,UAAA,EAAA,CAAA;kBAhBhB,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,UAAU;AACpB,oBAAA,QAAQ,EAAE,QAAQ;AAClB,oBAAA,IAAI,EAAE;AACJ,wBAAA,MAAM,EAAE,MAAM;AACd,wBAAA,OAAO,EAAE,SAAS;AAClB,wBAAA,WAAW,EAAE,gBAAgB;AAC7B,wBAAA,qBAAqB,EAAE,uBAAuB;AAC9C,wBAAA,WAAW,EAAE,6BAA6B;AAC1C,wBAAA,aAAa,EAAE,+BAA+B;AAC9C,wBAAA,YAAY,EAAE,8BAA8B;AAC5C,wBAAA,YAAY,EAAE,8BAA8B;AAC5C,wBAAA,WAAW,EAAE,uBAAuB;AACpC,wBAAA,SAAS,EAAE,2BAA2B;AACvC,qBAAA;AACF,iBAAA;;AA8GD;;;;;;AAMG;MAcU,OAAO,CAAA;;AAET,IAAA,SAAS,GAAG,eAAe,CAAc,QAAQ,6CAAG,WAAW,EAAE,IAAI,EAAA,CAAA,GAAA,CAAlB,EAAC,WAAW,EAAE,IAAI,EAAC,GAAC;IAEvE,MAAM,GAA8B,MAC3C,IAAI,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC;;AAGhC,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC;;AAGxC,IAAA,OAAO,GAAgB,IAAI,CAAC,WAAW,CAAC,aAAa;;AAG7C,IAAA,eAAe,GAAG,MAAM,CAAC,cAAc,CAAC;;IAGhD,aAAa,GAAG,QAAQ,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE;AAC7D,QAAA,YAAY,EAAE,IAAI,CAAC,eAAe,CAAC,KAAK;AACzC,KAAA,CAAC;;AAGO,IAAA,KAAK,GAAG,KAAK,CAAM,EAAE,iDAAC;;AAGtB,IAAA,IAAI,GAAG,KAAK,CAAU,IAAI,gDAAC;;AAG3B,IAAA,cAAc,GAAG,KAAK,CAAS,GAAG,0DAAC;;AAGnC,IAAA,SAAS;;AAGT,IAAA,KAAK,GAAG,MAAM,CAAuB,EAAE,iDAAC;;IAGjD,QAAQ,GAAG,MAAM,EAAK;AAEtB,IAAA,WAAA,GAAA;AACE,QAAA,IAAI,CAAC,SAAS,GAAG,IAAI,cAAc,CAAC;AAClC,YAAA,GAAG,IAAI;AACP,YAAA,KAAK,EAAE,MAAM,KAAK;AAClB,YAAA,YAAY,EAAE,MAAM,KAAK;AACzB,YAAA,SAAS,EAAE,MAAM,QAAQ;AACzB,YAAA,WAAW,EAAE,MAAM,YAAY;AAC/B,YAAA,aAAa,EAAE,MAAM,UAAU;AAC/B,YAAA,QAAQ,EAAE,CAAC,KAAQ,KAAK,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;AACjD,YAAA,UAAU,EAAE,MAAM,CAAC,SAAS,CAAC;YAC7B,OAAO,EAAE,QAAQ,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC;AACxD,SAAA,CAAC;QAEF,iBAAiB,CAAC,MAAK;YACrB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC;AACrD,SAAC,CAAC;QAEF,iBAAiB,CAAC,MAAK;YACrB,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,EAAE;AACpC,gBAAA,IAAI,CAAC,SAAS,CAAC,eAAe,EAAE;;AAEpC,SAAC,CAAC;;8GA5DO,OAAO,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAP,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,eAAA,EAAA,IAAA,EAAA,OAAO,+0BAEgC,QAAQ,EAAA,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,CAAA,WAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;kGAF/C,OAAO,EAAA,UAAA,EAAA,CAAA;kBAbnB,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,aAAa;AACvB,oBAAA,QAAQ,EAAE,WAAW;AACrB,oBAAA,IAAI,EAAE;AACJ,wBAAA,MAAM,EAAE,SAAS;AACjB,wBAAA,OAAO,EAAE,aAAa;AACtB,wBAAA,WAAW,EAAE,6BAA6B;AAC1C,wBAAA,aAAa,EAAE,+BAA+B;AAC9C,wBAAA,SAAS,EAAE,2BAA2B;AACtC,wBAAA,WAAW,EAAE,uBAAuB;AACpC,wBAAA,YAAY,EAAE,8BAA8B;AAC7C,qBAAA;AACF,iBAAA;;AAiED;;;;AAIG;MAeU,QAAQ,CAAA;;AAEF,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC;;AAGxC,IAAA,OAAO,GAAgB,IAAI,CAAC,WAAW,CAAC,aAAa;;IAGrD,EAAE,GAAG,KAAK,CAAS,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,8CAAC;;AAG/D,IAAA,KAAK,GAAG,KAAK,CAAC,QAAQ,gDAAK;;AAG3B,IAAA,QAAQ,GAAG,KAAK,CAAU,KAAK,oDAAC;;;AAKhC,IAAA,UAAU,GAAG,KAAK,CAAS,EAAE,sDAAC;;IAGtB,KAAK,GAAG,MAAM,CAAU,IAAI,EAAE,EAAC,QAAQ,EAAE,IAAI,EAAC,CAAC;;IAG/C,QAAQ,GAAG,MAAM,CAAa,OAAO,EAAE,EAAC,QAAQ,EAAE,IAAI,EAAC,CAAC;;IAGhE,MAAM,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,QAAQ;;AAGpC,IAAA,OAAO,GAAG,KAAK,CAAsB,SAAS,mDAAC;;IAG/C,SAAS,GAAuB,IAAI,eAAe,CAAI;QAC9D,EAAE,EAAE,IAAI,CAAC,EAAE;QACX,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,OAAO,EAAE,QAAQ,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC;QACvD,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,MAAM,EAAE,QAAQ,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC;AAC9C,QAAA,OAAO,EAAE,QAAQ,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC;AACnD,KAAA,CAAC;8GA1CS,QAAQ,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;kGAAR,QAAQ,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,EAAA,EAAA,EAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,UAAA,EAAA,kBAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,MAAA,EAAA,UAAA,EAAA,EAAA,UAAA,EAAA,EAAA,eAAA,EAAA,sBAAA,EAAA,kBAAA,EAAA,sBAAA,EAAA,oBAAA,EAAA,sBAAA,EAAA,oBAAA,EAAA,sBAAA,EAAA,oBAAA,EAAA,sBAAA,EAAA,oBAAA,EAAA,2BAAA,EAAA,EAAA,cAAA,EAAA,cAAA,EAAA,EAAA,QAAA,EAAA,CAAA,YAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;kGAAR,QAAQ,EAAA,UAAA,EAAA,CAAA;kBAdpB,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,cAAc;AACxB,oBAAA,QAAQ,EAAE,YAAY;AACtB,oBAAA,IAAI,EAAE;AACJ,wBAAA,MAAM,EAAE,UAAU;AAClB,wBAAA,OAAO,EAAE,cAAc;AACvB,wBAAA,iBAAiB,EAAE,sBAAsB;AACzC,wBAAA,oBAAoB,EAAE,sBAAsB;AAC5C,wBAAA,sBAAsB,EAAE,sBAAsB;AAC9C,wBAAA,sBAAsB,EAAE,sBAAsB;AAC9C,wBAAA,sBAAsB,EAAE,sBAAsB;AAC9C,wBAAA,sBAAsB,EAAE,2BAA2B;AACpD,qBAAA;AACF,iBAAA;;;;;"}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { inject, ElementRef, computed, contentChildren, input, booleanAttribute, model, signal, afterRenderEffect, Directive, linkedSignal } from '@angular/core';
|
|
3
|
+
import { ToolbarRadioGroupPattern, RadioGroupPattern, RadioButtonPattern } from '@angular/aria/ui-patterns';
|
|
4
|
+
import { Directionality } from '@angular/cdk/bidi';
|
|
5
|
+
import { _IdGenerator } from '@angular/cdk/a11y';
|
|
6
|
+
import * as i1 from '@angular/aria/toolbar';
|
|
7
|
+
import { ToolbarWidgetGroup } from '@angular/aria/toolbar';
|
|
8
|
+
|
|
9
|
+
// TODO: Move mapSignal to it's own file so it can be reused across components.
|
|
10
|
+
/**
|
|
11
|
+
* Creates a new writable signal (signal V) whose value is connected to the given original
|
|
12
|
+
* writable signal (signal T) such that updating signal V updates signal T and vice-versa.
|
|
13
|
+
*
|
|
14
|
+
* This function establishes a two-way synchronization between the source signal and the new mapped
|
|
15
|
+
* signal. When the source signal changes, the mapped signal updates by applying the `transform`
|
|
16
|
+
* function. When the mapped signal is explicitly set or updated, the change is propagated back to
|
|
17
|
+
* the source signal by applying the `reverse` function.
|
|
18
|
+
*/
|
|
19
|
+
function mapSignal(originalSignal, operations) {
|
|
20
|
+
const mappedSignal = linkedSignal(() => operations.transform(originalSignal()));
|
|
21
|
+
const updateMappedSignal = mappedSignal.update;
|
|
22
|
+
const setMappedSignal = mappedSignal.set;
|
|
23
|
+
mappedSignal.set = (newValue) => {
|
|
24
|
+
setMappedSignal(newValue);
|
|
25
|
+
originalSignal.set(operations.reverse(newValue));
|
|
26
|
+
};
|
|
27
|
+
mappedSignal.update = (updateFn) => {
|
|
28
|
+
updateMappedSignal(oldValue => updateFn(oldValue));
|
|
29
|
+
originalSignal.update(oldValue => operations.reverse(updateFn(operations.transform(oldValue))));
|
|
30
|
+
};
|
|
31
|
+
return mappedSignal;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* A radio button group container.
|
|
35
|
+
*
|
|
36
|
+
* Radio groups are used to group multiple radio buttons or radio group labels so they function as
|
|
37
|
+
* a single form control. The RadioGroup is meant to be used in conjunction with RadioButton
|
|
38
|
+
* as follows:
|
|
39
|
+
*
|
|
40
|
+
* ```html
|
|
41
|
+
* <div ngRadioGroup>
|
|
42
|
+
* <div ngRadioButton value="1">Option 1</div>
|
|
43
|
+
* <div ngRadioButton value="2">Option 2</div>
|
|
44
|
+
* <div ngRadioButton value="3">Option 3</div>
|
|
45
|
+
* </div>
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
class RadioGroup {
|
|
49
|
+
/** A reference to the radio group element. */
|
|
50
|
+
_elementRef = inject(ElementRef);
|
|
51
|
+
/** A reference to the ToolbarWidgetGroup, if the radio group is in a toolbar. */
|
|
52
|
+
_toolbarWidgetGroup = inject(ToolbarWidgetGroup);
|
|
53
|
+
/** Whether the radio group is inside of a Toolbar. */
|
|
54
|
+
_hasToolbar = computed(() => !!this._toolbarWidgetGroup.toolbar(), ...(ngDevMode ? [{ debugName: "_hasToolbar" }] : []));
|
|
55
|
+
/** The RadioButtons nested inside of the RadioGroup. */
|
|
56
|
+
_radioButtons = contentChildren(RadioButton, ...(ngDevMode ? [{ debugName: "_radioButtons", descendants: true }] : [{ descendants: true }]));
|
|
57
|
+
/** A signal wrapper for directionality. */
|
|
58
|
+
textDirection = inject(Directionality).valueSignal;
|
|
59
|
+
/** The RadioButton UIPatterns of the child RadioButtons. */
|
|
60
|
+
items = computed(() => this._radioButtons().map(radio => radio.pattern), ...(ngDevMode ? [{ debugName: "items" }] : []));
|
|
61
|
+
/** Whether the radio group is vertically or horizontally oriented. */
|
|
62
|
+
orientation = input('vertical', ...(ngDevMode ? [{ debugName: "orientation" }] : []));
|
|
63
|
+
/** Whether disabled items in the group should be skipped when navigating. */
|
|
64
|
+
skipDisabled = input(true, ...(ngDevMode ? [{ debugName: "skipDisabled", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
65
|
+
/** The focus strategy used by the radio group. */
|
|
66
|
+
focusMode = input('roving', ...(ngDevMode ? [{ debugName: "focusMode" }] : []));
|
|
67
|
+
/** Whether the radio group is disabled. */
|
|
68
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
69
|
+
/** Whether the radio group is readonly. */
|
|
70
|
+
readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
71
|
+
/** The value of the currently selected radio button. */
|
|
72
|
+
value = model(null, ...(ngDevMode ? [{ debugName: "value" }] : []));
|
|
73
|
+
/** The internal selection state for the radio group. */
|
|
74
|
+
_value = mapSignal(this.value, {
|
|
75
|
+
transform: value => (value !== null ? [value] : []),
|
|
76
|
+
reverse: values => (values.length === 0 ? null : values[0]),
|
|
77
|
+
});
|
|
78
|
+
/** The RadioGroup UIPattern. */
|
|
79
|
+
pattern;
|
|
80
|
+
/** Whether the radio group has received focus yet. */
|
|
81
|
+
_hasFocused = signal(false, ...(ngDevMode ? [{ debugName: "_hasFocused" }] : []));
|
|
82
|
+
constructor() {
|
|
83
|
+
const inputs = {
|
|
84
|
+
...this,
|
|
85
|
+
items: this.items,
|
|
86
|
+
value: this._value,
|
|
87
|
+
activeItem: signal(undefined),
|
|
88
|
+
textDirection: this.textDirection,
|
|
89
|
+
element: () => this._elementRef.nativeElement,
|
|
90
|
+
getItem: e => {
|
|
91
|
+
if (!(e.target instanceof HTMLElement)) {
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
94
|
+
const element = e.target.closest('[role="radio"]');
|
|
95
|
+
return this.items().find(i => i.element() === element);
|
|
96
|
+
},
|
|
97
|
+
toolbar: this._toolbarWidgetGroup.toolbar,
|
|
98
|
+
};
|
|
99
|
+
this.pattern = this._hasToolbar()
|
|
100
|
+
? new ToolbarRadioGroupPattern(inputs)
|
|
101
|
+
: new RadioGroupPattern(inputs);
|
|
102
|
+
if (this._hasToolbar()) {
|
|
103
|
+
this._toolbarWidgetGroup.controls.set(this.pattern);
|
|
104
|
+
}
|
|
105
|
+
afterRenderEffect(() => {
|
|
106
|
+
if (typeof ngDevMode === 'undefined' || ngDevMode) {
|
|
107
|
+
const violations = this.pattern.validate();
|
|
108
|
+
for (const violation of violations) {
|
|
109
|
+
console.error(violation);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
afterRenderEffect(() => {
|
|
114
|
+
if (!this._hasFocused() && !this._hasToolbar()) {
|
|
115
|
+
this.pattern.setDefaultState();
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
onFocus() {
|
|
120
|
+
this._hasFocused.set(true);
|
|
121
|
+
}
|
|
122
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.0-next.2", ngImport: i0, type: RadioGroup, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
123
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "20.2.0-next.2", type: RadioGroup, isStandalone: true, selector: "[ngRadioGroup]", inputs: { orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, skipDisabled: { classPropertyName: "skipDisabled", publicName: "skipDisabled", isSignal: true, isRequired: false, transformFunction: null }, focusMode: { classPropertyName: "focusMode", publicName: "focusMode", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, host: { attributes: { "role": "radiogroup" }, listeners: { "keydown": "pattern.onKeydown($event)", "pointerdown": "pattern.onPointerdown($event)", "focusin": "onFocus()" }, properties: { "attr.tabindex": "pattern.tabindex()", "attr.aria-readonly": "pattern.readonly()", "attr.aria-disabled": "pattern.disabled()", "attr.aria-orientation": "pattern.orientation()", "attr.aria-activedescendant": "pattern.activedescendant()" }, classAttribute: "ng-radio-group" }, queries: [{ propertyName: "_radioButtons", predicate: RadioButton, descendants: true, isSignal: true }], exportAs: ["ngRadioGroup"], hostDirectives: [{ directive: i1.ToolbarWidgetGroup, inputs: ["disabled", "disabled"] }], ngImport: i0 });
|
|
124
|
+
}
|
|
125
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.0-next.2", ngImport: i0, type: RadioGroup, decorators: [{
|
|
126
|
+
type: Directive,
|
|
127
|
+
args: [{
|
|
128
|
+
selector: '[ngRadioGroup]',
|
|
129
|
+
exportAs: 'ngRadioGroup',
|
|
130
|
+
host: {
|
|
131
|
+
'role': 'radiogroup',
|
|
132
|
+
'class': 'ng-radio-group',
|
|
133
|
+
'[attr.tabindex]': 'pattern.tabindex()',
|
|
134
|
+
'[attr.aria-readonly]': 'pattern.readonly()',
|
|
135
|
+
'[attr.aria-disabled]': 'pattern.disabled()',
|
|
136
|
+
'[attr.aria-orientation]': 'pattern.orientation()',
|
|
137
|
+
'[attr.aria-activedescendant]': 'pattern.activedescendant()',
|
|
138
|
+
'(keydown)': 'pattern.onKeydown($event)',
|
|
139
|
+
'(pointerdown)': 'pattern.onPointerdown($event)',
|
|
140
|
+
'(focusin)': 'onFocus()',
|
|
141
|
+
},
|
|
142
|
+
hostDirectives: [
|
|
143
|
+
{
|
|
144
|
+
directive: ToolbarWidgetGroup,
|
|
145
|
+
inputs: ['disabled'],
|
|
146
|
+
},
|
|
147
|
+
],
|
|
148
|
+
}]
|
|
149
|
+
}], ctorParameters: () => [] });
|
|
150
|
+
/** A selectable radio button in a RadioGroup. */
|
|
151
|
+
class RadioButton {
|
|
152
|
+
/** A reference to the radio button element. */
|
|
153
|
+
_elementRef = inject(ElementRef);
|
|
154
|
+
/** The parent RadioGroup. */
|
|
155
|
+
_radioGroup = inject(RadioGroup);
|
|
156
|
+
/** A unique identifier for the radio button. */
|
|
157
|
+
_generatedId = inject(_IdGenerator).getId('ng-radio-button-');
|
|
158
|
+
/** A unique identifier for the radio button. */
|
|
159
|
+
id = computed(() => this._generatedId, ...(ngDevMode ? [{ debugName: "id" }] : []));
|
|
160
|
+
/** The value associated with the radio button. */
|
|
161
|
+
value = input.required(...(ngDevMode ? [{ debugName: "value" }] : []));
|
|
162
|
+
/** The parent RadioGroup UIPattern. */
|
|
163
|
+
group = computed(() => this._radioGroup.pattern, ...(ngDevMode ? [{ debugName: "group" }] : []));
|
|
164
|
+
/** A reference to the radio button element to be focused on navigation. */
|
|
165
|
+
element = computed(() => this._elementRef.nativeElement, ...(ngDevMode ? [{ debugName: "element" }] : []));
|
|
166
|
+
/** Whether the radio button is disabled. */
|
|
167
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
168
|
+
/** The RadioButton UIPattern. */
|
|
169
|
+
pattern = new RadioButtonPattern({
|
|
170
|
+
...this,
|
|
171
|
+
id: this.id,
|
|
172
|
+
value: this.value,
|
|
173
|
+
group: this.group,
|
|
174
|
+
element: this.element,
|
|
175
|
+
});
|
|
176
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.0-next.2", ngImport: i0, type: RadioButton, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
177
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.2.0-next.2", type: RadioButton, isStandalone: true, selector: "[ngRadioButton]", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "radio" }, properties: { "attr.data-active": "pattern.active()", "attr.tabindex": "pattern.tabindex()", "attr.aria-checked": "pattern.selected()", "attr.aria-disabled": "pattern.disabled()", "id": "pattern.id()" }, classAttribute: "ng-radio-button" }, exportAs: ["ngRadioButton"], ngImport: i0 });
|
|
178
|
+
}
|
|
179
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.0-next.2", ngImport: i0, type: RadioButton, decorators: [{
|
|
180
|
+
type: Directive,
|
|
181
|
+
args: [{
|
|
182
|
+
selector: '[ngRadioButton]',
|
|
183
|
+
exportAs: 'ngRadioButton',
|
|
184
|
+
host: {
|
|
185
|
+
'role': 'radio',
|
|
186
|
+
'class': 'ng-radio-button',
|
|
187
|
+
'[attr.data-active]': 'pattern.active()',
|
|
188
|
+
'[attr.tabindex]': 'pattern.tabindex()',
|
|
189
|
+
'[attr.aria-checked]': 'pattern.selected()',
|
|
190
|
+
'[attr.aria-disabled]': 'pattern.disabled()',
|
|
191
|
+
'[id]': 'pattern.id()',
|
|
192
|
+
},
|
|
193
|
+
}]
|
|
194
|
+
}] });
|
|
195
|
+
|
|
196
|
+
export { RadioButton, RadioGroup };
|
|
197
|
+
//# sourceMappingURL=radio-group.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"radio-group.mjs","sources":["../../../../../darwin_arm64-fastbuild-ST-199a4f3c4e20/bin/src/aria/radio-group/radio-group.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport {\n afterRenderEffect,\n booleanAttribute,\n computed,\n contentChildren,\n Directive,\n ElementRef,\n inject,\n input,\n linkedSignal,\n model,\n signal,\n WritableSignal,\n} from '@angular/core';\nimport {\n RadioButtonPattern,\n RadioGroupInputs,\n RadioGroupPattern,\n ToolbarRadioGroupInputs,\n ToolbarRadioGroupPattern,\n} from '@angular/aria/ui-patterns';\nimport {Directionality} from '@angular/cdk/bidi';\nimport {_IdGenerator} from '@angular/cdk/a11y';\nimport {ToolbarWidgetGroup} from '@angular/aria/toolbar';\n\n// TODO: Move mapSignal to it's own file so it can be reused across components.\n\n/**\n * Creates a new writable signal (signal V) whose value is connected to the given original\n * writable signal (signal T) such that updating signal V updates signal T and vice-versa.\n *\n * This function establishes a two-way synchronization between the source signal and the new mapped\n * signal. When the source signal changes, the mapped signal updates by applying the `transform`\n * function. When the mapped signal is explicitly set or updated, the change is propagated back to\n * the source signal by applying the `reverse` function.\n */\nexport function mapSignal<T, V>(\n originalSignal: WritableSignal<T>,\n operations: {\n transform: (value: T) => V;\n reverse: (value: V) => T;\n },\n) {\n const mappedSignal = linkedSignal(() => operations.transform(originalSignal()));\n const updateMappedSignal = mappedSignal.update;\n const setMappedSignal = mappedSignal.set;\n\n mappedSignal.set = (newValue: V) => {\n setMappedSignal(newValue);\n originalSignal.set(operations.reverse(newValue));\n };\n\n mappedSignal.update = (updateFn: (value: V) => V) => {\n updateMappedSignal(oldValue => updateFn(oldValue));\n originalSignal.update(oldValue => operations.reverse(updateFn(operations.transform(oldValue))));\n };\n\n return mappedSignal;\n}\n\n/**\n * A radio button group container.\n *\n * Radio groups are used to group multiple radio buttons or radio group labels so they function as\n * a single form control. The RadioGroup is meant to be used in conjunction with RadioButton\n * as follows:\n *\n * ```html\n * <div ngRadioGroup>\n * <div ngRadioButton value=\"1\">Option 1</div>\n * <div ngRadioButton value=\"2\">Option 2</div>\n * <div ngRadioButton value=\"3\">Option 3</div>\n * </div>\n * ```\n */\n@Directive({\n selector: '[ngRadioGroup]',\n exportAs: 'ngRadioGroup',\n host: {\n 'role': 'radiogroup',\n 'class': 'ng-radio-group',\n '[attr.tabindex]': 'pattern.tabindex()',\n '[attr.aria-readonly]': 'pattern.readonly()',\n '[attr.aria-disabled]': 'pattern.disabled()',\n '[attr.aria-orientation]': 'pattern.orientation()',\n '[attr.aria-activedescendant]': 'pattern.activedescendant()',\n '(keydown)': 'pattern.onKeydown($event)',\n '(pointerdown)': 'pattern.onPointerdown($event)',\n '(focusin)': 'onFocus()',\n },\n hostDirectives: [\n {\n directive: ToolbarWidgetGroup,\n inputs: ['disabled'],\n },\n ],\n})\nexport class RadioGroup<V> {\n /** A reference to the radio group element. */\n private readonly _elementRef = inject(ElementRef);\n\n /** A reference to the ToolbarWidgetGroup, if the radio group is in a toolbar. */\n private readonly _toolbarWidgetGroup = inject(ToolbarWidgetGroup);\n\n /** Whether the radio group is inside of a Toolbar. */\n private readonly _hasToolbar = computed(() => !!this._toolbarWidgetGroup.toolbar());\n\n /** The RadioButtons nested inside of the RadioGroup. */\n private readonly _radioButtons = contentChildren(RadioButton, {descendants: true});\n\n /** A signal wrapper for directionality. */\n protected textDirection = inject(Directionality).valueSignal;\n\n /** The RadioButton UIPatterns of the child RadioButtons. */\n protected items = computed(() => this._radioButtons().map(radio => radio.pattern));\n\n /** Whether the radio group is vertically or horizontally oriented. */\n readonly orientation = input<'vertical' | 'horizontal'>('vertical');\n\n /** Whether disabled items in the group should be skipped when navigating. */\n readonly skipDisabled = input(true, {transform: booleanAttribute});\n\n /** The focus strategy used by the radio group. */\n readonly focusMode = input<'roving' | 'activedescendant'>('roving');\n\n /** Whether the radio group is disabled. */\n readonly disabled = input(false, {transform: booleanAttribute});\n\n /** Whether the radio group is readonly. */\n readonly readonly = input(false, {transform: booleanAttribute});\n\n /** The value of the currently selected radio button. */\n readonly value = model<V | null>(null);\n\n /** The internal selection state for the radio group. */\n private readonly _value = mapSignal<V | null, V[]>(this.value, {\n transform: value => (value !== null ? [value] : []),\n reverse: values => (values.length === 0 ? null : values[0]),\n });\n\n /** The RadioGroup UIPattern. */\n readonly pattern: RadioGroupPattern<V>;\n\n /** Whether the radio group has received focus yet. */\n private _hasFocused = signal(false);\n\n constructor() {\n const inputs: RadioGroupInputs<V> | ToolbarRadioGroupInputs<V> = {\n ...this,\n items: this.items,\n value: this._value,\n activeItem: signal(undefined),\n textDirection: this.textDirection,\n element: () => this._elementRef.nativeElement,\n getItem: e => {\n if (!(e.target instanceof HTMLElement)) {\n return undefined;\n }\n const element = e.target.closest('[role=\"radio\"]');\n return this.items().find(i => i.element() === element);\n },\n toolbar: this._toolbarWidgetGroup.toolbar,\n };\n\n this.pattern = this._hasToolbar()\n ? new ToolbarRadioGroupPattern<V>(inputs as ToolbarRadioGroupInputs<V>)\n : new RadioGroupPattern<V>(inputs as RadioGroupInputs<V>);\n\n if (this._hasToolbar()) {\n this._toolbarWidgetGroup.controls.set(this.pattern as ToolbarRadioGroupPattern<V>);\n }\n\n afterRenderEffect(() => {\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\n const violations = this.pattern.validate();\n for (const violation of violations) {\n console.error(violation);\n }\n }\n });\n\n afterRenderEffect(() => {\n if (!this._hasFocused() && !this._hasToolbar()) {\n this.pattern.setDefaultState();\n }\n });\n }\n\n onFocus() {\n this._hasFocused.set(true);\n }\n}\n\n/** A selectable radio button in a RadioGroup. */\n@Directive({\n selector: '[ngRadioButton]',\n exportAs: 'ngRadioButton',\n host: {\n 'role': 'radio',\n 'class': 'ng-radio-button',\n '[attr.data-active]': 'pattern.active()',\n '[attr.tabindex]': 'pattern.tabindex()',\n '[attr.aria-checked]': 'pattern.selected()',\n '[attr.aria-disabled]': 'pattern.disabled()',\n '[id]': 'pattern.id()',\n },\n})\nexport class RadioButton<V> {\n /** A reference to the radio button element. */\n private readonly _elementRef = inject(ElementRef);\n\n /** The parent RadioGroup. */\n private readonly _radioGroup = inject(RadioGroup);\n\n /** A unique identifier for the radio button. */\n private readonly _generatedId = inject(_IdGenerator).getId('ng-radio-button-');\n\n /** A unique identifier for the radio button. */\n readonly id = computed(() => this._generatedId);\n\n /** The value associated with the radio button. */\n readonly value = input.required<V>();\n\n /** The parent RadioGroup UIPattern. */\n readonly group = computed(() => this._radioGroup.pattern);\n\n /** A reference to the radio button element to be focused on navigation. */\n element = computed(() => this._elementRef.nativeElement);\n\n /** Whether the radio button is disabled. */\n disabled = input(false, {transform: booleanAttribute});\n\n /** The RadioButton UIPattern. */\n pattern = new RadioButtonPattern<V>({\n ...this,\n id: this.id,\n value: this.value,\n group: this.group,\n element: this.element,\n });\n}\n"],"names":[],"mappings":"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"}
|