@fluentui/web-components 3.0.0-rc.12 → 3.0.0-rc.13
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/CHANGELOG.md +11 -2
- package/custom-elements.json +964 -161
- package/dist/esm/index.d.ts +2 -2
- package/dist/esm/index.js +2 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/menu-list/index.d.ts +1 -0
- package/dist/esm/menu-list/index.js +1 -0
- package/dist/esm/menu-list/index.js.map +1 -1
- package/dist/esm/menu-list/menu-list.base.d.ts +76 -0
- package/dist/esm/menu-list/menu-list.base.js +251 -0
- package/dist/esm/menu-list/menu-list.base.js.map +1 -0
- package/dist/esm/menu-list/menu-list.d.ts +3 -70
- package/dist/esm/menu-list/menu-list.js +3 -244
- package/dist/esm/menu-list/menu-list.js.map +1 -1
- package/dist/esm/radio-group/index.d.ts +1 -0
- package/dist/esm/radio-group/index.js +1 -0
- package/dist/esm/radio-group/index.js.map +1 -1
- package/dist/esm/radio-group/radio-group.base.d.ts +285 -0
- package/dist/esm/radio-group/radio-group.base.js +497 -0
- package/dist/esm/radio-group/radio-group.base.js.map +1 -0
- package/dist/esm/radio-group/radio-group.d.ts +4 -280
- package/dist/esm/radio-group/radio-group.js +4 -491
- package/dist/esm/radio-group/radio-group.js.map +1 -1
- package/dist/web-components.d.ts +1845 -1827
- package/dist/web-components.js +20 -16
- package/dist/web-components.min.js +34 -34
- package/package.json +1 -1
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { FASTElement, Observable, observable, Updates } from '@microsoft/fast-element';
|
|
3
|
-
import { isHTMLElement, keyArrowDown, keyArrowUp, keyEnd, keyHome } from '@microsoft/fast-web-utilities';
|
|
4
|
-
import { isMenuItem, MenuItemRole } from '../menu-item/menu-item.options.js';
|
|
1
|
+
import { BaseMenuList } from './menu-list.base.js';
|
|
5
2
|
/**
|
|
6
|
-
* A Menu Custom HTML Element.
|
|
3
|
+
* A Menu List Custom HTML Element.
|
|
7
4
|
* Implements the {@link https://www.w3.org/TR/wai-aria-1.1/#menu | ARIA menu }.
|
|
8
5
|
*
|
|
9
6
|
* @tag fluent-menu-list
|
|
@@ -12,244 +9,6 @@ import { isMenuItem, MenuItemRole } from '../menu-item/menu-item.options.js';
|
|
|
12
9
|
*
|
|
13
10
|
* @public
|
|
14
11
|
*/
|
|
15
|
-
export class MenuList extends
|
|
16
|
-
itemsChanged(oldValue, newValue) {
|
|
17
|
-
// only update children after the component is connected and
|
|
18
|
-
// the setItems has run on connectedCallback
|
|
19
|
-
// (menuItems is undefined until then)
|
|
20
|
-
if (this.$fastController.isConnected && this.menuItems !== undefined) {
|
|
21
|
-
this.setItems();
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
static { this.focusableElementRoles = MenuItemRole; }
|
|
25
|
-
constructor() {
|
|
26
|
-
super();
|
|
27
|
-
/**
|
|
28
|
-
* The internal {@link https://developer.mozilla.org/docs/Web/API/ElementInternals | `ElementInternals`} instance for the component.
|
|
29
|
-
*
|
|
30
|
-
* @internal
|
|
31
|
-
*/
|
|
32
|
-
this.elementInternals = this.attachInternals();
|
|
33
|
-
/**
|
|
34
|
-
* The index of the focusable element in the items array
|
|
35
|
-
* defaults to -1
|
|
36
|
-
*/
|
|
37
|
-
this.focusIndex = -1;
|
|
38
|
-
/**
|
|
39
|
-
* @internal
|
|
40
|
-
*/
|
|
41
|
-
this.isNestedMenu = () => {
|
|
42
|
-
return (this.parentElement !== null &&
|
|
43
|
-
isHTMLElement(this.parentElement) &&
|
|
44
|
-
this.parentElement.getAttribute('role') === 'menuitem');
|
|
45
|
-
};
|
|
46
|
-
/**
|
|
47
|
-
* if focus is moving out of the menu, reset to a stable initial state
|
|
48
|
-
* @internal
|
|
49
|
-
*/
|
|
50
|
-
this.handleFocusOut = (e) => {
|
|
51
|
-
if (!this.contains(e.relatedTarget) && this.menuItems !== undefined) {
|
|
52
|
-
// find our first focusable element
|
|
53
|
-
const focusIndex = this.menuItems.findIndex(this.isFocusableElement);
|
|
54
|
-
// set the current focus index's tabindex to -1
|
|
55
|
-
this.menuItems[this.focusIndex].setAttribute('tabindex', '-1');
|
|
56
|
-
// set the first focusable element tabindex to 0
|
|
57
|
-
this.menuItems[focusIndex].setAttribute('tabindex', '0');
|
|
58
|
-
// set the focus index
|
|
59
|
-
this.focusIndex = focusIndex;
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
this.handleItemFocus = (e) => {
|
|
63
|
-
const targetItem = e.target;
|
|
64
|
-
if (this.menuItems !== undefined && targetItem !== this.menuItems[this.focusIndex]) {
|
|
65
|
-
this.menuItems[this.focusIndex].setAttribute('tabindex', '-1');
|
|
66
|
-
this.focusIndex = this.menuItems.indexOf(targetItem);
|
|
67
|
-
targetItem.setAttribute('tabindex', '0');
|
|
68
|
-
}
|
|
69
|
-
};
|
|
70
|
-
/**
|
|
71
|
-
* Handle change from child MenuItem element and set radio group behavior
|
|
72
|
-
*/
|
|
73
|
-
this.changedMenuItemHandler = (e) => {
|
|
74
|
-
if (this.menuItems === undefined) {
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
const changedMenuItem = e.target;
|
|
78
|
-
const changeItemIndex = this.menuItems.indexOf(changedMenuItem);
|
|
79
|
-
if (changeItemIndex === -1) {
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
if (changedMenuItem.role === 'menuitemradio' && changedMenuItem.checked === true) {
|
|
83
|
-
for (let i = changeItemIndex - 1; i >= 0; --i) {
|
|
84
|
-
const item = this.menuItems[i];
|
|
85
|
-
const role = item.role;
|
|
86
|
-
if (role === MenuItemRole.menuitemradio) {
|
|
87
|
-
item.checked = false;
|
|
88
|
-
}
|
|
89
|
-
if (role === 'separator') {
|
|
90
|
-
break;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
const maxIndex = this.menuItems.length - 1;
|
|
94
|
-
for (let i = changeItemIndex + 1; i <= maxIndex; ++i) {
|
|
95
|
-
const item = this.menuItems[i];
|
|
96
|
-
const role = item.role;
|
|
97
|
-
if (role === MenuItemRole.menuitemradio) {
|
|
98
|
-
item.checked = false;
|
|
99
|
-
}
|
|
100
|
-
if (role === 'separator') {
|
|
101
|
-
break;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
};
|
|
106
|
-
/**
|
|
107
|
-
* check if the item is a menu item
|
|
108
|
-
*/
|
|
109
|
-
this.isMenuItemElement = (el) => {
|
|
110
|
-
return isMenuItem(el) || (isHTMLElement(el) && !!el.role && el.role in MenuList.focusableElementRoles);
|
|
111
|
-
};
|
|
112
|
-
/**
|
|
113
|
-
* check if the item is focusable
|
|
114
|
-
*/
|
|
115
|
-
this.isFocusableElement = (el) => {
|
|
116
|
-
return this.isMenuItemElement(el);
|
|
117
|
-
};
|
|
118
|
-
this.elementInternals.role = 'menu';
|
|
119
|
-
}
|
|
120
|
-
/**
|
|
121
|
-
* @internal
|
|
122
|
-
*/
|
|
123
|
-
connectedCallback() {
|
|
124
|
-
super.connectedCallback();
|
|
125
|
-
Updates.enqueue(() => {
|
|
126
|
-
// wait until children have had a chance to
|
|
127
|
-
// connect before setting/checking their props/attributes
|
|
128
|
-
this.setItems();
|
|
129
|
-
});
|
|
130
|
-
this.addEventListener('change', this.changedMenuItemHandler);
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* @internal
|
|
134
|
-
*/
|
|
135
|
-
disconnectedCallback() {
|
|
136
|
-
super.disconnectedCallback();
|
|
137
|
-
this.removeItemListeners();
|
|
138
|
-
this.menuItems = undefined;
|
|
139
|
-
this.removeEventListener('change', this.changedMenuItemHandler);
|
|
140
|
-
}
|
|
141
|
-
/**
|
|
142
|
-
* Focuses the first item in the menu.
|
|
143
|
-
*
|
|
144
|
-
* @public
|
|
145
|
-
*/
|
|
146
|
-
focus() {
|
|
147
|
-
this.setFocus(0, 1);
|
|
148
|
-
}
|
|
149
|
-
/**
|
|
150
|
-
* @internal
|
|
151
|
-
*/
|
|
152
|
-
handleMenuKeyDown(e) {
|
|
153
|
-
if (e.defaultPrevented || this.menuItems === undefined) {
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
|
-
switch (e.key) {
|
|
157
|
-
case keyArrowDown:
|
|
158
|
-
// go forward one index
|
|
159
|
-
this.setFocus(this.focusIndex + 1, 1);
|
|
160
|
-
return;
|
|
161
|
-
case keyArrowUp:
|
|
162
|
-
// go back one index
|
|
163
|
-
this.setFocus(this.focusIndex - 1, -1);
|
|
164
|
-
return;
|
|
165
|
-
case keyEnd:
|
|
166
|
-
// set focus on last item
|
|
167
|
-
this.setFocus(this.menuItems.length - 1, -1);
|
|
168
|
-
return;
|
|
169
|
-
case keyHome:
|
|
170
|
-
// set focus on first item
|
|
171
|
-
this.setFocus(0, 1);
|
|
172
|
-
return;
|
|
173
|
-
default:
|
|
174
|
-
// if we are not handling the event, do not prevent default
|
|
175
|
-
return true;
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
removeItemListeners(items = this.items) {
|
|
179
|
-
items.forEach(item => {
|
|
180
|
-
item.removeEventListener('focus', this.handleItemFocus);
|
|
181
|
-
Observable.getNotifier(item).unsubscribe(this, 'hidden');
|
|
182
|
-
});
|
|
183
|
-
}
|
|
184
|
-
static elementIndent(el) {
|
|
185
|
-
const role = el.role;
|
|
186
|
-
const startSlot = el.querySelector('[slot=start]');
|
|
187
|
-
if (role && role !== MenuItemRole.menuitem) {
|
|
188
|
-
return startSlot ? 2 : 1;
|
|
189
|
-
}
|
|
190
|
-
return startSlot ? 1 : 0;
|
|
191
|
-
}
|
|
192
|
-
setItems() {
|
|
193
|
-
const children = Array.from(this.children);
|
|
194
|
-
this.removeItemListeners(children);
|
|
195
|
-
children.forEach((child) => Observable.getNotifier(child).subscribe(this, 'hidden'));
|
|
196
|
-
const newItems = children.filter(child => !child.hasAttribute('hidden'));
|
|
197
|
-
this.menuItems = newItems;
|
|
198
|
-
const menuItems = this.menuItems.filter(this.isMenuItemElement);
|
|
199
|
-
// if our focus index is not -1 we have items
|
|
200
|
-
if (menuItems.length) {
|
|
201
|
-
this.focusIndex = 0;
|
|
202
|
-
}
|
|
203
|
-
menuItems.forEach((item, index) => {
|
|
204
|
-
item.setAttribute('tabindex', index === 0 ? '0' : '-1');
|
|
205
|
-
item.addEventListener('focus', this.handleItemFocus);
|
|
206
|
-
});
|
|
207
|
-
/**
|
|
208
|
-
* Set the indent attribute on MenuItem elements based on their
|
|
209
|
-
* position in the MenuList. Each MenuItem element has a data-indent attribute that is
|
|
210
|
-
* used to set the indent of the element's start slot content.
|
|
211
|
-
*/
|
|
212
|
-
const filteredMenuListItems = this.menuItems?.filter(this.isMenuItemElement);
|
|
213
|
-
const indent = filteredMenuListItems?.reduce((accum, current) => {
|
|
214
|
-
const elementValue = MenuList.elementIndent(current);
|
|
215
|
-
return Math.max(accum, elementValue);
|
|
216
|
-
}, 0);
|
|
217
|
-
filteredMenuListItems?.forEach((item) => {
|
|
218
|
-
item.dataset.indent = `${indent}`;
|
|
219
|
-
});
|
|
220
|
-
}
|
|
221
|
-
/**
|
|
222
|
-
* Method for Observable changes to the hidden attribute of child elements
|
|
223
|
-
*/
|
|
224
|
-
handleChange(source, propertyName) {
|
|
225
|
-
if (propertyName === 'hidden') {
|
|
226
|
-
this.setItems();
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
setFocus(focusIndex, adjustment) {
|
|
230
|
-
if (this.menuItems === undefined) {
|
|
231
|
-
return;
|
|
232
|
-
}
|
|
233
|
-
while (focusIndex >= 0 && focusIndex < this.menuItems.length) {
|
|
234
|
-
const child = this.menuItems[focusIndex];
|
|
235
|
-
if (this.isFocusableElement(child)) {
|
|
236
|
-
// change the previous index to -1
|
|
237
|
-
if (this.focusIndex > -1 && this.menuItems.length >= this.focusIndex - 1) {
|
|
238
|
-
this.menuItems[this.focusIndex].setAttribute('tabindex', '-1');
|
|
239
|
-
}
|
|
240
|
-
// update the focus index
|
|
241
|
-
this.focusIndex = focusIndex;
|
|
242
|
-
// update the tabindex of next focusable element
|
|
243
|
-
child.setAttribute('tabindex', '0');
|
|
244
|
-
// focus the element
|
|
245
|
-
child.focus();
|
|
246
|
-
break;
|
|
247
|
-
}
|
|
248
|
-
focusIndex += adjustment;
|
|
249
|
-
}
|
|
250
|
-
}
|
|
12
|
+
export class MenuList extends BaseMenuList {
|
|
251
13
|
}
|
|
252
|
-
__decorate([
|
|
253
|
-
observable
|
|
254
|
-
], MenuList.prototype, "items", void 0);
|
|
255
14
|
//# sourceMappingURL=menu-list.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menu-list.js","sourceRoot":"","sources":["../../../src/menu-list/menu-list.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"menu-list.js","sourceRoot":"","sources":["../../../src/menu-list/menu-list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD;;;;;;;;;GASG;AACH,MAAM,OAAO,QAAS,SAAQ,YAAY;CAAG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/radio-group/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,UAAU,IAAI,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACjF,OAAO,EAAE,MAAM,IAAI,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAE,QAAQ,IAAI,kBAAkB,EAAE,MAAM,2BAA2B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/radio-group/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,UAAU,IAAI,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACjF,OAAO,EAAE,MAAM,IAAI,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAE,QAAQ,IAAI,kBAAkB,EAAE,MAAM,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import { FASTElement } from '@microsoft/fast-element';
|
|
2
|
+
import { Radio } from '../radio/radio.js';
|
|
3
|
+
import { RadioGroupOrientation } from './radio-group.options.js';
|
|
4
|
+
/**
|
|
5
|
+
* A Base Radio Group Custom HTML Element.
|
|
6
|
+
* Implements the {@link https://w3c.github.io/aria/#radiogroup | ARIA `radiogroup` role}.
|
|
7
|
+
*
|
|
8
|
+
* @public
|
|
9
|
+
*/
|
|
10
|
+
export declare class BaseRadioGroup extends FASTElement {
|
|
11
|
+
/**
|
|
12
|
+
* The index of the checked radio, scoped to the enabled radios.
|
|
13
|
+
*
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
protected checkedIndex: number;
|
|
17
|
+
/**
|
|
18
|
+
* Sets the checked state of the nearest enabled radio when the `checkedIndex` changes.
|
|
19
|
+
*
|
|
20
|
+
* @param prev - the previous index
|
|
21
|
+
* @param next - the current index
|
|
22
|
+
* @internal
|
|
23
|
+
*/
|
|
24
|
+
protected checkedIndexChanged(prev: number | undefined, next: number): void;
|
|
25
|
+
/**
|
|
26
|
+
* Indicates that the value has been changed by the user.
|
|
27
|
+
*/
|
|
28
|
+
private dirtyState;
|
|
29
|
+
/**
|
|
30
|
+
* Disables the radio group and child radios.
|
|
31
|
+
*
|
|
32
|
+
* @public
|
|
33
|
+
* @remarks
|
|
34
|
+
* HTML Attribute: `disabled`
|
|
35
|
+
*/
|
|
36
|
+
disabled: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Sets the `disabled` attribute on all child radios when the `disabled` property changes.
|
|
39
|
+
*
|
|
40
|
+
* @param prev - the previous disabled value
|
|
41
|
+
* @param next - the current disabled value
|
|
42
|
+
* @internal
|
|
43
|
+
*/
|
|
44
|
+
protected disabledChanged(prev?: boolean, next?: boolean): void;
|
|
45
|
+
/**
|
|
46
|
+
* The value of the checked radio.
|
|
47
|
+
*
|
|
48
|
+
* @public
|
|
49
|
+
* @remarks
|
|
50
|
+
* HTML Attribute: `value`
|
|
51
|
+
*/
|
|
52
|
+
initialValue?: string;
|
|
53
|
+
/**
|
|
54
|
+
* Sets the matching radio to checked when the value changes. If no radio matches the value, no radio will be checked.
|
|
55
|
+
*
|
|
56
|
+
* @param prev - the previous value
|
|
57
|
+
* @param next - the current value
|
|
58
|
+
*/
|
|
59
|
+
initialValueChanged(prev: string | undefined, next: string | undefined): void;
|
|
60
|
+
/**
|
|
61
|
+
* The name of the radio group.
|
|
62
|
+
*
|
|
63
|
+
* @public
|
|
64
|
+
* @remarks
|
|
65
|
+
* HTML Attribute: `name`
|
|
66
|
+
*/
|
|
67
|
+
name: string;
|
|
68
|
+
/**
|
|
69
|
+
* Sets the `name` attribute on all child radios when the `name` property changes.
|
|
70
|
+
*
|
|
71
|
+
* @internal
|
|
72
|
+
*/
|
|
73
|
+
protected nameChanged(prev: string | undefined, next: string | undefined): void;
|
|
74
|
+
/**
|
|
75
|
+
* The orientation of the group.
|
|
76
|
+
*
|
|
77
|
+
* @public
|
|
78
|
+
* @remarks
|
|
79
|
+
* HTML Attribute: `orientation`
|
|
80
|
+
*/
|
|
81
|
+
orientation?: RadioGroupOrientation;
|
|
82
|
+
/**
|
|
83
|
+
* Sets the ariaOrientation attribute when the orientation changes.
|
|
84
|
+
*
|
|
85
|
+
* @param prev - the previous orientation
|
|
86
|
+
* @param next - the current orientation
|
|
87
|
+
* @internal
|
|
88
|
+
*/
|
|
89
|
+
orientationChanged(prev: RadioGroupOrientation | undefined, next: RadioGroupOrientation | undefined): void;
|
|
90
|
+
/**
|
|
91
|
+
* The collection of all child radios.
|
|
92
|
+
*
|
|
93
|
+
* @public
|
|
94
|
+
*/
|
|
95
|
+
radios: Radio[];
|
|
96
|
+
/**
|
|
97
|
+
* Updates the enabled radios collection when properties on the child radios change.
|
|
98
|
+
*
|
|
99
|
+
* @param prev - the previous radios
|
|
100
|
+
* @param next - the current radios
|
|
101
|
+
*/
|
|
102
|
+
radiosChanged(prev: Radio[] | undefined, next: Radio[] | undefined): void;
|
|
103
|
+
/**
|
|
104
|
+
* Indicates whether the radio group is required.
|
|
105
|
+
*
|
|
106
|
+
* @public
|
|
107
|
+
* @remarks
|
|
108
|
+
* HTML Attribute: `required`
|
|
109
|
+
*/
|
|
110
|
+
required: boolean;
|
|
111
|
+
/**
|
|
112
|
+
*
|
|
113
|
+
* @param prev - the previous required value
|
|
114
|
+
* @param next - the current required value
|
|
115
|
+
*/
|
|
116
|
+
requiredChanged(prev: boolean, next: boolean): void;
|
|
117
|
+
/**
|
|
118
|
+
* The collection of radios that are slotted into the default slot.
|
|
119
|
+
*
|
|
120
|
+
* @internal
|
|
121
|
+
*/
|
|
122
|
+
slottedRadios: Radio[];
|
|
123
|
+
/**
|
|
124
|
+
* Updates the radios collection when the slotted radios change.
|
|
125
|
+
*
|
|
126
|
+
* @param prev - the previous slotted radios
|
|
127
|
+
* @param next - the current slotted radios
|
|
128
|
+
*/
|
|
129
|
+
slottedRadiosChanged(prev: Radio[] | undefined, next: Radio[]): void;
|
|
130
|
+
/**
|
|
131
|
+
* The internal {@link https://developer.mozilla.org/docs/Web/API/ElementInternals | `ElementInternals`} instance for the component.
|
|
132
|
+
*
|
|
133
|
+
* @internal
|
|
134
|
+
*/
|
|
135
|
+
elementInternals: ElementInternals;
|
|
136
|
+
/**
|
|
137
|
+
* A collection of child radios that are not disabled.
|
|
138
|
+
*
|
|
139
|
+
* @internal
|
|
140
|
+
*/
|
|
141
|
+
get enabledRadios(): Radio[];
|
|
142
|
+
/**
|
|
143
|
+
* The form-associated flag.
|
|
144
|
+
* @see {@link https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements-face-example | Form-associated custom elements}
|
|
145
|
+
*
|
|
146
|
+
* @public
|
|
147
|
+
*/
|
|
148
|
+
static formAssociated: boolean;
|
|
149
|
+
/**
|
|
150
|
+
* The fallback validation message, taken from a native checkbox `<input>` element.
|
|
151
|
+
*
|
|
152
|
+
* @internal
|
|
153
|
+
*/
|
|
154
|
+
private _validationFallbackMessage;
|
|
155
|
+
/**
|
|
156
|
+
* The validation message. Uses the browser's default validation message for native checkboxes if not otherwise
|
|
157
|
+
* specified (e.g., via `setCustomValidity`).
|
|
158
|
+
*
|
|
159
|
+
* @internal
|
|
160
|
+
*/
|
|
161
|
+
get validationMessage(): string;
|
|
162
|
+
/**
|
|
163
|
+
* The element's validity state.
|
|
164
|
+
*
|
|
165
|
+
* @public
|
|
166
|
+
* @remarks
|
|
167
|
+
* Reflects the {@link https://developer.mozilla.org/docs/Web/API/ElementInternals/validity | `ElementInternals.validity`} property.
|
|
168
|
+
*/
|
|
169
|
+
get validity(): ValidityState;
|
|
170
|
+
/**
|
|
171
|
+
* The current value of the checked radio.
|
|
172
|
+
*
|
|
173
|
+
* @public
|
|
174
|
+
*/
|
|
175
|
+
get value(): string | null;
|
|
176
|
+
set value(next: string | null);
|
|
177
|
+
/**
|
|
178
|
+
* Sets the checked state of all radios when any radio emits a `change` event.
|
|
179
|
+
*
|
|
180
|
+
* @param e - the change event
|
|
181
|
+
*/
|
|
182
|
+
changeHandler(e: Event): boolean | void;
|
|
183
|
+
/**
|
|
184
|
+
* Checks the radio at the specified index.
|
|
185
|
+
*
|
|
186
|
+
* @param index - the index of the radio to check
|
|
187
|
+
* @internal
|
|
188
|
+
*/
|
|
189
|
+
checkRadio(index?: number, shouldEmit?: boolean): void;
|
|
190
|
+
/**
|
|
191
|
+
* Checks the validity of the element and returns the result.
|
|
192
|
+
*
|
|
193
|
+
* @public
|
|
194
|
+
* @remarks
|
|
195
|
+
* Reflects the {@link https://developer.mozilla.org/docs/Web/API/ElementInternals/checkValidity | `HTMLInputElement.checkValidity()`} method.
|
|
196
|
+
*/
|
|
197
|
+
checkValidity(): boolean;
|
|
198
|
+
/**
|
|
199
|
+
* Handles click events for the radio group.
|
|
200
|
+
*
|
|
201
|
+
* @param e - the click event
|
|
202
|
+
* @internal
|
|
203
|
+
*/
|
|
204
|
+
clickHandler(e: MouseEvent): boolean | void;
|
|
205
|
+
constructor();
|
|
206
|
+
/**
|
|
207
|
+
* Focuses the checked radio or the first enabled radio.
|
|
208
|
+
*
|
|
209
|
+
* @internal
|
|
210
|
+
*/
|
|
211
|
+
focus(): void;
|
|
212
|
+
/**
|
|
213
|
+
* Enables tabbing through the radio group when the group receives focus.
|
|
214
|
+
*
|
|
215
|
+
* @param e - the focus event
|
|
216
|
+
* @internal
|
|
217
|
+
*/
|
|
218
|
+
focusinHandler(e: FocusEvent): boolean | void;
|
|
219
|
+
/**
|
|
220
|
+
* Sets the tabindex of the radios based on the checked state when the radio group loses focus.
|
|
221
|
+
*
|
|
222
|
+
* @param e - the focusout event
|
|
223
|
+
* @internal
|
|
224
|
+
*/
|
|
225
|
+
focusoutHandler(e: FocusEvent): boolean | void;
|
|
226
|
+
formResetCallback(): void;
|
|
227
|
+
private getEnabledIndexInBounds;
|
|
228
|
+
/**
|
|
229
|
+
* Handles keydown events for the radio group.
|
|
230
|
+
*
|
|
231
|
+
* @param e - the keyboard event
|
|
232
|
+
* @internal
|
|
233
|
+
*/
|
|
234
|
+
keydownHandler(e: KeyboardEvent): boolean | void;
|
|
235
|
+
/**
|
|
236
|
+
*
|
|
237
|
+
* @param e - the disabled event
|
|
238
|
+
*/
|
|
239
|
+
disabledRadioHandler(e: CustomEvent): void;
|
|
240
|
+
/**
|
|
241
|
+
* Reports the validity of the element.
|
|
242
|
+
*
|
|
243
|
+
* @public
|
|
244
|
+
* @remarks
|
|
245
|
+
* Reflects the {@link https://developer.mozilla.org/docs/Web/API/ElementInternals/reportValidity | `HTMLInputElement.reportValidity()`} method.
|
|
246
|
+
*/
|
|
247
|
+
reportValidity(): boolean;
|
|
248
|
+
/**
|
|
249
|
+
* Resets the `tabIndex` for all child radios when the radio group loses focus.
|
|
250
|
+
*
|
|
251
|
+
* @internal
|
|
252
|
+
*/
|
|
253
|
+
private restrictFocus;
|
|
254
|
+
/**
|
|
255
|
+
* Reflects the {@link https://developer.mozilla.org/docs/Web/API/ElementInternals/setFormValue | `ElementInternals.setFormValue()`} method.
|
|
256
|
+
*
|
|
257
|
+
* @internal
|
|
258
|
+
*/
|
|
259
|
+
setFormValue(value: File | string | FormData | null, state?: File | string | FormData | null): void;
|
|
260
|
+
/**
|
|
261
|
+
* Sets the validity of the element.
|
|
262
|
+
*
|
|
263
|
+
* @param flags - Validity flags to set.
|
|
264
|
+
* @param message - Optional message to supply. If not provided, the element's `validationMessage` will be used.
|
|
265
|
+
* @param anchor - Optional anchor to use for the validation message.
|
|
266
|
+
*
|
|
267
|
+
* @internal
|
|
268
|
+
* @remarks
|
|
269
|
+
* RadioGroup validation is reported through the individual Radio elements rather than the RadioGroup itself.
|
|
270
|
+
* This is necessary because:
|
|
271
|
+
* 1. Each Radio is form-associated (extends BaseCheckbox which has `formAssociated = true`)
|
|
272
|
+
* 2. Browser validation UIs and screen readers announce validation against individual form controls
|
|
273
|
+
* 3. For groups like RadioGroup, the browser needs to report the error on a specific member of the group
|
|
274
|
+
* 4. We anchor the error to the first Radio so it receives focus and announcement
|
|
275
|
+
*
|
|
276
|
+
* When the group is invalid (required but no selection):
|
|
277
|
+
* - Only the first Radio gets the invalid state with the validation message
|
|
278
|
+
* - Other Radios are kept valid since selecting any of them would satisfy the requirement
|
|
279
|
+
*
|
|
280
|
+
* When the group becomes valid (user selects any Radio):
|
|
281
|
+
* - All Radios are cleared back to valid state
|
|
282
|
+
* - This allows form submission to proceed
|
|
283
|
+
*/
|
|
284
|
+
setValidity(flags?: Partial<ValidityState>, message?: string, anchor?: HTMLElement): void;
|
|
285
|
+
}
|