@angular/aria 0.0.1 → 21.0.0-next.9
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/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 +130 -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/listbox.mjs +200 -0
- package/fesm2022/listbox.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 +285 -0
- package/fesm2022/tree.mjs.map +1 -0
- package/fesm2022/ui-patterns.mjs +2504 -0
- package/fesm2022/ui-patterns.mjs.map +1 -0
- package/package.json +78 -3
- package/types/accordion.d.ts +92 -0
- package/types/aria.d.ts +6 -0
- package/types/combobox.d.ts +51 -0
- package/types/deferred-content.d.ts +38 -0
- package/types/listbox.d.ts +95 -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 +133 -0
- package/types/ui-patterns.d.ts +1404 -0
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { inject, computed, ElementRef, contentChildren, input, booleanAttribute, model, signal, afterRenderEffect, untracked, Directive } from '@angular/core';
|
|
3
|
+
import { ComboboxListboxPattern, ListboxPattern, OptionPattern } from '@angular/aria/ui-patterns';
|
|
4
|
+
import { Directionality } from '@angular/cdk/bidi';
|
|
5
|
+
import { toSignal } from '@angular/core/rxjs-interop';
|
|
6
|
+
import { _IdGenerator } from '@angular/cdk/a11y';
|
|
7
|
+
import { ComboboxPopup } from './combobox.mjs';
|
|
8
|
+
import '@angular/aria/deferred-content';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* A listbox container.
|
|
12
|
+
*
|
|
13
|
+
* Listboxes are used to display a list of items for a user to select from. The Listbox is meant
|
|
14
|
+
* to be used in conjunction with Option as follows:
|
|
15
|
+
*
|
|
16
|
+
* ```html
|
|
17
|
+
* <ul ngListbox>
|
|
18
|
+
* <li [value]="1" ngOption>Item 1</li>
|
|
19
|
+
* <li [value]="2" ngOption>Item 2</li>
|
|
20
|
+
* <li [value]="3" ngOption>Item 3</li>
|
|
21
|
+
* </ul>
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
class Listbox {
|
|
25
|
+
/** A unique identifier for the listbox. */
|
|
26
|
+
_generatedId = inject(_IdGenerator).getId('ng-listbox-');
|
|
27
|
+
// TODO(wagnermaciel): https://github.com/angular/components/pull/30495#discussion_r1972601144.
|
|
28
|
+
/** A unique identifier for the listbox. */
|
|
29
|
+
id = computed(() => this._generatedId, ...(ngDevMode ? [{ debugName: "id" }] : []));
|
|
30
|
+
/** A reference to the parent combobox popup, if one exists. */
|
|
31
|
+
_popup = inject(ComboboxPopup, {
|
|
32
|
+
optional: true,
|
|
33
|
+
});
|
|
34
|
+
/** A reference to the listbox element. */
|
|
35
|
+
_elementRef = inject(ElementRef);
|
|
36
|
+
/** The directionality (LTR / RTL) context for the application (or a subtree of it). */
|
|
37
|
+
_directionality = inject(Directionality);
|
|
38
|
+
/** The Options nested inside of the Listbox. */
|
|
39
|
+
_options = contentChildren(Option, ...(ngDevMode ? [{ debugName: "_options", descendants: true }] : [{ descendants: true }]));
|
|
40
|
+
/** A signal wrapper for directionality. */
|
|
41
|
+
textDirection = toSignal(this._directionality.change, {
|
|
42
|
+
initialValue: this._directionality.value,
|
|
43
|
+
});
|
|
44
|
+
/** The Option UIPatterns of the child Options. */
|
|
45
|
+
items = computed(() => this._options().map(option => option.pattern), ...(ngDevMode ? [{ debugName: "items" }] : []));
|
|
46
|
+
/** Whether the list is vertically or horizontally oriented. */
|
|
47
|
+
orientation = input('vertical', ...(ngDevMode ? [{ debugName: "orientation" }] : []));
|
|
48
|
+
/** Whether multiple items in the list can be selected at once. */
|
|
49
|
+
multi = input(false, ...(ngDevMode ? [{ debugName: "multi", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
50
|
+
/** Whether focus should wrap when navigating. */
|
|
51
|
+
wrap = input(true, ...(ngDevMode ? [{ debugName: "wrap", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
52
|
+
/** Whether disabled items in the list should be skipped when navigating. */
|
|
53
|
+
skipDisabled = input(true, ...(ngDevMode ? [{ debugName: "skipDisabled", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
54
|
+
/** The focus strategy used by the list. */
|
|
55
|
+
focusMode = input('roving', ...(ngDevMode ? [{ debugName: "focusMode" }] : []));
|
|
56
|
+
/** The selection strategy used by the list. */
|
|
57
|
+
selectionMode = input('follow', ...(ngDevMode ? [{ debugName: "selectionMode" }] : []));
|
|
58
|
+
/** The amount of time before the typeahead search is reset. */
|
|
59
|
+
typeaheadDelay = input(0.5, ...(ngDevMode ? [{ debugName: "typeaheadDelay" }] : [])); // Picked arbitrarily.
|
|
60
|
+
/** Whether the listbox is disabled. */
|
|
61
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
62
|
+
/** Whether the listbox is readonly. */
|
|
63
|
+
readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
64
|
+
/** The values of the current selected items. */
|
|
65
|
+
value = model([], ...(ngDevMode ? [{ debugName: "value" }] : []));
|
|
66
|
+
/** The Listbox UIPattern. */
|
|
67
|
+
pattern;
|
|
68
|
+
/** Whether the listbox has received focus yet. */
|
|
69
|
+
_hasFocused = signal(false, ...(ngDevMode ? [{ debugName: "_hasFocused" }] : []));
|
|
70
|
+
constructor() {
|
|
71
|
+
const inputs = {
|
|
72
|
+
...this,
|
|
73
|
+
id: this.id,
|
|
74
|
+
items: this.items,
|
|
75
|
+
activeItem: signal(undefined),
|
|
76
|
+
textDirection: this.textDirection,
|
|
77
|
+
element: () => this._elementRef.nativeElement,
|
|
78
|
+
combobox: () => this._popup?.combobox?.pattern,
|
|
79
|
+
};
|
|
80
|
+
this.pattern = this._popup?.combobox
|
|
81
|
+
? new ComboboxListboxPattern(inputs)
|
|
82
|
+
: new ListboxPattern(inputs);
|
|
83
|
+
if (this._popup) {
|
|
84
|
+
this._popup.controls.set(this.pattern);
|
|
85
|
+
}
|
|
86
|
+
afterRenderEffect(() => {
|
|
87
|
+
if (typeof ngDevMode === 'undefined' || ngDevMode) {
|
|
88
|
+
const violations = this.pattern.validate();
|
|
89
|
+
for (const violation of violations) {
|
|
90
|
+
console.error(violation);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
afterRenderEffect(() => {
|
|
95
|
+
if (!this._hasFocused()) {
|
|
96
|
+
this.pattern.setDefaultState();
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
// Ensure that if the active item is removed from
|
|
100
|
+
// the list, the listbox updates it's focus state.
|
|
101
|
+
afterRenderEffect(() => {
|
|
102
|
+
const items = inputs.items();
|
|
103
|
+
const activeItem = untracked(() => inputs.activeItem());
|
|
104
|
+
if (!items.some(i => i === activeItem) && activeItem) {
|
|
105
|
+
this.pattern.listBehavior.unfocus();
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
// Ensure that the value is always in sync with the available options.
|
|
109
|
+
afterRenderEffect(() => {
|
|
110
|
+
const items = inputs.items();
|
|
111
|
+
const value = untracked(() => this.value());
|
|
112
|
+
if (items && value.some(v => !items.some(i => i.value() === v))) {
|
|
113
|
+
this.value.set(value.filter(v => items.some(i => i.value() === v)));
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
onFocus() {
|
|
118
|
+
this._hasFocused.set(true);
|
|
119
|
+
}
|
|
120
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.0-next.2", ngImport: i0, type: Listbox, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
121
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "20.2.0-next.2", type: Listbox, isStandalone: true, selector: "[ngListbox]", inputs: { orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, multi: { classPropertyName: "multi", publicName: "multi", isSignal: true, isRequired: false, transformFunction: null }, wrap: { classPropertyName: "wrap", publicName: "wrap", 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 }, selectionMode: { classPropertyName: "selectionMode", publicName: "selectionMode", isSignal: true, isRequired: false, transformFunction: null }, typeaheadDelay: { classPropertyName: "typeaheadDelay", publicName: "typeaheadDelay", 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": "listbox" }, listeners: { "keydown": "pattern.onKeydown($event)", "pointerdown": "pattern.onPointerdown($event)", "focusin": "onFocus()" }, properties: { "attr.id": "id()", "attr.tabindex": "pattern.tabindex()", "attr.aria-readonly": "pattern.readonly()", "attr.aria-disabled": "pattern.disabled()", "attr.aria-orientation": "pattern.orientation()", "attr.aria-multiselectable": "pattern.multi()", "attr.aria-activedescendant": "pattern.activedescendant()" }, classAttribute: "ng-listbox" }, queries: [{ propertyName: "_options", predicate: Option, descendants: true, isSignal: true }], exportAs: ["ngListbox"], hostDirectives: [{ directive: ComboboxPopup }], ngImport: i0 });
|
|
122
|
+
}
|
|
123
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.0-next.2", ngImport: i0, type: Listbox, decorators: [{
|
|
124
|
+
type: Directive,
|
|
125
|
+
args: [{
|
|
126
|
+
selector: '[ngListbox]',
|
|
127
|
+
exportAs: 'ngListbox',
|
|
128
|
+
host: {
|
|
129
|
+
'role': 'listbox',
|
|
130
|
+
'class': 'ng-listbox',
|
|
131
|
+
'[attr.id]': 'id()',
|
|
132
|
+
'[attr.tabindex]': 'pattern.tabindex()',
|
|
133
|
+
'[attr.aria-readonly]': 'pattern.readonly()',
|
|
134
|
+
'[attr.aria-disabled]': 'pattern.disabled()',
|
|
135
|
+
'[attr.aria-orientation]': 'pattern.orientation()',
|
|
136
|
+
'[attr.aria-multiselectable]': 'pattern.multi()',
|
|
137
|
+
'[attr.aria-activedescendant]': 'pattern.activedescendant()',
|
|
138
|
+
'(keydown)': 'pattern.onKeydown($event)',
|
|
139
|
+
'(pointerdown)': 'pattern.onPointerdown($event)',
|
|
140
|
+
'(focusin)': 'onFocus()',
|
|
141
|
+
},
|
|
142
|
+
hostDirectives: [{ directive: ComboboxPopup }],
|
|
143
|
+
}]
|
|
144
|
+
}], ctorParameters: () => [] });
|
|
145
|
+
/** A selectable option in a Listbox. */
|
|
146
|
+
class Option {
|
|
147
|
+
/** A reference to the option element. */
|
|
148
|
+
_elementRef = inject(ElementRef);
|
|
149
|
+
/** The parent Listbox. */
|
|
150
|
+
_listbox = inject(Listbox);
|
|
151
|
+
/** A unique identifier for the option. */
|
|
152
|
+
_generatedId = inject(_IdGenerator).getId('ng-option-');
|
|
153
|
+
// TODO(wagnermaciel): https://github.com/angular/components/pull/30495#discussion_r1972601144.
|
|
154
|
+
/** A unique identifier for the option. */
|
|
155
|
+
id = computed(() => this._generatedId, ...(ngDevMode ? [{ debugName: "id" }] : []));
|
|
156
|
+
// TODO(wagnermaciel): See if we want to change how we handle this since textContent is not
|
|
157
|
+
// reactive. See https://github.com/angular/components/pull/30495#discussion_r1961260216.
|
|
158
|
+
/** The text used by the typeahead search. */
|
|
159
|
+
searchTerm = computed(() => this.label() ?? this.element().textContent, ...(ngDevMode ? [{ debugName: "searchTerm" }] : []));
|
|
160
|
+
/** The parent Listbox UIPattern. */
|
|
161
|
+
listbox = computed(() => this._listbox.pattern, ...(ngDevMode ? [{ debugName: "listbox" }] : []));
|
|
162
|
+
/** A reference to the option element to be focused on navigation. */
|
|
163
|
+
element = computed(() => this._elementRef.nativeElement, ...(ngDevMode ? [{ debugName: "element" }] : []));
|
|
164
|
+
/** The value of the option. */
|
|
165
|
+
value = input.required(...(ngDevMode ? [{ debugName: "value" }] : []));
|
|
166
|
+
/** Whether an item is disabled. */
|
|
167
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
|
|
168
|
+
/** The text used by the typeahead search. */
|
|
169
|
+
label = input(...(ngDevMode ? [undefined, { debugName: "label" }] : []));
|
|
170
|
+
/** The Option UIPattern. */
|
|
171
|
+
pattern = new OptionPattern({
|
|
172
|
+
...this,
|
|
173
|
+
id: this.id,
|
|
174
|
+
value: this.value,
|
|
175
|
+
listbox: this.listbox,
|
|
176
|
+
element: this.element,
|
|
177
|
+
searchTerm: this.searchTerm,
|
|
178
|
+
});
|
|
179
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.0-next.2", ngImport: i0, type: Option, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
180
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.2.0-next.2", type: Option, isStandalone: true, selector: "[ngOption]", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "option" }, properties: { "attr.data-active": "pattern.active()", "attr.id": "pattern.id()", "attr.tabindex": "pattern.tabindex()", "attr.aria-selected": "pattern.selected()", "attr.aria-disabled": "pattern.disabled()" }, classAttribute: "ng-option" }, exportAs: ["ngOption"], ngImport: i0 });
|
|
181
|
+
}
|
|
182
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.0-next.2", ngImport: i0, type: Option, decorators: [{
|
|
183
|
+
type: Directive,
|
|
184
|
+
args: [{
|
|
185
|
+
selector: '[ngOption]',
|
|
186
|
+
exportAs: 'ngOption',
|
|
187
|
+
host: {
|
|
188
|
+
'role': 'option',
|
|
189
|
+
'class': 'ng-option',
|
|
190
|
+
'[attr.data-active]': 'pattern.active()',
|
|
191
|
+
'[attr.id]': 'pattern.id()',
|
|
192
|
+
'[attr.tabindex]': 'pattern.tabindex()',
|
|
193
|
+
'[attr.aria-selected]': 'pattern.selected()',
|
|
194
|
+
'[attr.aria-disabled]': 'pattern.disabled()',
|
|
195
|
+
},
|
|
196
|
+
}]
|
|
197
|
+
}] });
|
|
198
|
+
|
|
199
|
+
export { Listbox, Option };
|
|
200
|
+
//# sourceMappingURL=listbox.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"listbox.mjs","sources":["../../../../../darwin_arm64-fastbuild-ST-199a4f3c4e20/bin/src/aria/listbox/listbox.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 model,\n signal,\n untracked,\n} from '@angular/core';\nimport {ComboboxListboxPattern, ListboxPattern, OptionPattern} from '@angular/aria/ui-patterns';\nimport {Directionality} from '@angular/cdk/bidi';\nimport {toSignal} from '@angular/core/rxjs-interop';\nimport {_IdGenerator} from '@angular/cdk/a11y';\nimport {ComboboxPopup} from '../combobox';\n\n/**\n * A listbox container.\n *\n * Listboxes are used to display a list of items for a user to select from. The Listbox is meant\n * to be used in conjunction with Option as follows:\n *\n * ```html\n * <ul ngListbox>\n * <li [value]=\"1\" ngOption>Item 1</li>\n * <li [value]=\"2\" ngOption>Item 2</li>\n * <li [value]=\"3\" ngOption>Item 3</li>\n * </ul>\n * ```\n */\n@Directive({\n selector: '[ngListbox]',\n exportAs: 'ngListbox',\n host: {\n 'role': 'listbox',\n 'class': 'ng-listbox',\n '[attr.id]': 'id()',\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-multiselectable]': 'pattern.multi()',\n '[attr.aria-activedescendant]': 'pattern.activedescendant()',\n '(keydown)': 'pattern.onKeydown($event)',\n '(pointerdown)': 'pattern.onPointerdown($event)',\n '(focusin)': 'onFocus()',\n },\n hostDirectives: [{directive: ComboboxPopup}],\n})\nexport class Listbox<V> {\n /** A unique identifier for the listbox. */\n private readonly _generatedId = inject(_IdGenerator).getId('ng-listbox-');\n\n // TODO(wagnermaciel): https://github.com/angular/components/pull/30495#discussion_r1972601144.\n /** A unique identifier for the listbox. */\n protected id = computed(() => this._generatedId);\n\n /** A reference to the parent combobox popup, if one exists. */\n private readonly _popup = inject<ComboboxPopup<V>>(ComboboxPopup, {\n optional: true,\n });\n\n /** A reference to the listbox element. */\n private readonly _elementRef = inject(ElementRef);\n\n /** The directionality (LTR / RTL) context for the application (or a subtree of it). */\n private readonly _directionality = inject(Directionality);\n\n /** The Options nested inside of the Listbox. */\n private readonly _options = contentChildren(Option, {descendants: true});\n\n /** A signal wrapper for directionality. */\n protected textDirection = toSignal(this._directionality.change, {\n initialValue: this._directionality.value,\n });\n\n /** The Option UIPatterns of the child Options. */\n protected items = computed(() => this._options().map(option => option.pattern));\n\n /** Whether the list is vertically or horizontally oriented. */\n orientation = input<'vertical' | 'horizontal'>('vertical');\n\n /** Whether multiple items in the list can be selected at once. */\n multi = input(false, {transform: booleanAttribute});\n\n /** Whether focus should wrap when navigating. */\n wrap = input(true, {transform: booleanAttribute});\n\n /** Whether disabled items in the list should be skipped when navigating. */\n skipDisabled = input(true, {transform: booleanAttribute});\n\n /** The focus strategy used by the list. */\n focusMode = input<'roving' | 'activedescendant'>('roving');\n\n /** The selection strategy used by the list. */\n selectionMode = input<'follow' | 'explicit'>('follow');\n\n /** The amount of time before the typeahead search is reset. */\n typeaheadDelay = input<number>(0.5); // Picked arbitrarily.\n\n /** Whether the listbox is disabled. */\n disabled = input(false, {transform: booleanAttribute});\n\n /** Whether the listbox is readonly. */\n readonly = input(false, {transform: booleanAttribute});\n\n /** The values of the current selected items. */\n value = model<V[]>([]);\n\n /** The Listbox UIPattern. */\n pattern: ListboxPattern<V>;\n\n /** Whether the listbox has received focus yet. */\n private _hasFocused = signal(false);\n\n constructor() {\n const inputs = {\n ...this,\n id: this.id,\n items: this.items,\n activeItem: signal(undefined),\n textDirection: this.textDirection,\n element: () => this._elementRef.nativeElement,\n combobox: () => this._popup?.combobox?.pattern,\n };\n\n this.pattern = this._popup?.combobox\n ? new ComboboxListboxPattern<V>(inputs)\n : new ListboxPattern<V>(inputs);\n\n if (this._popup) {\n this._popup.controls.set(this.pattern as ComboboxListboxPattern<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()) {\n this.pattern.setDefaultState();\n }\n });\n\n // Ensure that if the active item is removed from\n // the list, the listbox updates it's focus state.\n afterRenderEffect(() => {\n const items = inputs.items();\n const activeItem = untracked(() => inputs.activeItem());\n\n if (!items.some(i => i === activeItem) && activeItem) {\n this.pattern.listBehavior.unfocus();\n }\n });\n\n // Ensure that the value is always in sync with the available options.\n afterRenderEffect(() => {\n const items = inputs.items();\n const value = untracked(() => this.value());\n\n if (items && value.some(v => !items.some(i => i.value() === v))) {\n this.value.set(value.filter(v => items.some(i => i.value() === v)));\n }\n });\n }\n\n onFocus() {\n this._hasFocused.set(true);\n }\n}\n\n/** A selectable option in a Listbox. */\n@Directive({\n selector: '[ngOption]',\n exportAs: 'ngOption',\n host: {\n 'role': 'option',\n 'class': 'ng-option',\n '[attr.data-active]': 'pattern.active()',\n '[attr.id]': 'pattern.id()',\n '[attr.tabindex]': 'pattern.tabindex()',\n '[attr.aria-selected]': 'pattern.selected()',\n '[attr.aria-disabled]': 'pattern.disabled()',\n },\n})\nexport class Option<V> {\n /** A reference to the option element. */\n private readonly _elementRef = inject(ElementRef);\n\n /** The parent Listbox. */\n private readonly _listbox = inject(Listbox);\n\n /** A unique identifier for the option. */\n private readonly _generatedId = inject(_IdGenerator).getId('ng-option-');\n\n // TODO(wagnermaciel): https://github.com/angular/components/pull/30495#discussion_r1972601144.\n /** A unique identifier for the option. */\n protected id = computed(() => this._generatedId);\n\n // TODO(wagnermaciel): See if we want to change how we handle this since textContent is not\n // reactive. See https://github.com/angular/components/pull/30495#discussion_r1961260216.\n /** The text used by the typeahead search. */\n protected searchTerm = computed(() => this.label() ?? this.element().textContent);\n\n /** The parent Listbox UIPattern. */\n protected listbox = computed(() => this._listbox.pattern);\n\n /** A reference to the option element to be focused on navigation. */\n protected element = computed(() => this._elementRef.nativeElement);\n\n /** The value of the option. */\n value = input.required<V>();\n\n /** Whether an item is disabled. */\n disabled = input(false, {transform: booleanAttribute});\n\n /** The text used by the typeahead search. */\n label = input<string>();\n\n /** The Option UIPattern. */\n pattern = new OptionPattern<V>({\n ...this,\n id: this.id,\n value: this.value,\n listbox: this.listbox,\n element: this.element,\n searchTerm: this.searchTerm,\n });\n}\n"],"names":["i1.ComboboxPopup"],"mappings":"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"}
|
|
@@ -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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"}
|