@digital-realty/ix-radio 1.0.1

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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 ix-radio
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,75 @@
1
+ # \<ix-radio>
2
+
3
+ This webcomponent follows the [open-wc](https://github.com/open-wc/open-wc) recommendation.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm i @digital-realty/ix-radio
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```html
14
+ <script type="module">
15
+ import '@digital-realty/ix-radio/ix-radio.js';
16
+ </script>
17
+
18
+ <ix-radio></ix-radio>
19
+ ```
20
+
21
+ ## Linting and formatting
22
+
23
+ To scan the project for linting and formatting errors, run
24
+
25
+ ```bash
26
+ npm run lint
27
+ ```
28
+
29
+ To automatically fix linting and formatting errors, run
30
+
31
+ ```bash
32
+ npm run format
33
+ ```
34
+
35
+ ## Testing with Web Test Runner
36
+
37
+ To execute a single test run:
38
+
39
+ ```bash
40
+ npm run test
41
+ ```
42
+
43
+ To run the tests in interactive watch mode run:
44
+
45
+ ```bash
46
+ npm run test:watch
47
+ ```
48
+
49
+ ## Demoing with Storybook
50
+
51
+ To run a local instance of Storybook for your component, run
52
+
53
+ ```bash
54
+ npm run storybook
55
+ ```
56
+
57
+ To build a production version of Storybook, run
58
+
59
+ ```bash
60
+ npm run storybook:build
61
+ ```
62
+
63
+ ## Tooling configs
64
+
65
+ For most of the tools, the configuration is in the `package.json` to reduce the amount of files in your project.
66
+
67
+ If you customize the configuration a lot, you can consider moving them to individual files.
68
+
69
+ ## Local Demo with `web-dev-server`
70
+
71
+ ```bash
72
+ npm start
73
+ ```
74
+
75
+ To run a local development server that serves the basic demo located in `demo/index.html`
@@ -0,0 +1,41 @@
1
+ <!doctype html>
2
+ <html lang="en-GB">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <style>
6
+ body {
7
+ background: #fafafa;
8
+ }
9
+ </style>
10
+ </head>
11
+ <body>
12
+ <div id="demo"></div>
13
+
14
+ <script type="module">
15
+ import { html, render } from 'lit';
16
+ import '../dist/src/ix-radio.js';
17
+
18
+ const handleSubmit = (e) => {
19
+ e.preventDefault();
20
+ const form = e.target;
21
+ const formData = new FormData(form);
22
+ formData.forEach((value, key) => console.log(`${key}: ${value}`));
23
+ }
24
+
25
+ render(
26
+ html`
27
+ <form @submit=${handleSubmit}>
28
+ <fieldset id="radiogroup">
29
+ <ix-radio label="Red" name="aName" value="red"></ix-radio><br/><br/>
30
+ <ix-radio label="Green" name="aName" value="green"></ix-radio><br/><br/>
31
+ <ix-radio label="Blue" name="aName" value="blue"></ix-radio><br/><br/>
32
+ <ix-radio label="Black" name="aName" value="black"></ix-radio>
33
+ </fieldset>
34
+ <button type="submit">Submit</button>
35
+ </form>
36
+ `,
37
+ document.querySelector('#demo')
38
+ );
39
+ </script>
40
+ </body>
41
+ </html>
@@ -0,0 +1,71 @@
1
+ <!doctype html>
2
+ <html lang="en-GB">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <style>
6
+ body {
7
+ background: #fafafa;
8
+ }
9
+ </style>
10
+ </head>
11
+ <body>
12
+ <div id="demo"></div>
13
+
14
+ <script type="module">
15
+ import { html, render } from 'lit';
16
+ import '@material/web/radio/radio.js';
17
+
18
+ const handleSubmit = (e) => {
19
+ e.preventDefault();
20
+ const form = e.target;
21
+ const formData = new FormData(form);
22
+ formData.forEach((value, key) => console.log(`${key}: ${value}`));
23
+ }
24
+
25
+ render(
26
+ html`
27
+ <form @submit=${handleSubmit}>
28
+ <div class="column" role="radiogroup" aria-label="Animals">
29
+ <div class="radio-label">
30
+ <md-radio
31
+ aria-label="Birds"
32
+ id="birds-radio"
33
+ name="with-labels"
34
+ touch-target="wrapper"
35
+ value="birds"
36
+ >
37
+ </md-radio>
38
+ <label for="birds-radio">Birds</label>
39
+ </div>
40
+ <div class="radio-label">
41
+ <md-radio
42
+ aria-label="Cats"
43
+ id="cats-radio"
44
+ name="with-labels"
45
+ touch-target="wrapper"
46
+ value="cats"
47
+ >
48
+ </md-radio>
49
+ <label for="cats-radio">Cats</label>
50
+ </div>
51
+ <div class="radio-label">
52
+ <md-radio
53
+ aria-label="Dogs"
54
+ id="dogs-radio"
55
+ name="with-labels"
56
+ touch-target="wrapper"
57
+ value="dogs"
58
+ ?disabled=${true}
59
+ >
60
+ </md-radio>
61
+ <label for="dogs-radio">Dogs</label>
62
+ </div>
63
+ </div>
64
+ <button type="submit">Submit</button>
65
+ </form>
66
+ `,
67
+ document.querySelector('#demo')
68
+ );
69
+ </script>
70
+ </body>
71
+ </html>
@@ -0,0 +1,45 @@
1
+ import { LitElement } from 'lit';
2
+ import '@material/web/radio/radio.js';
3
+ declare const CHECKED: unique symbol;
4
+ export declare class IxRadio extends LitElement {
5
+ static get styles(): import("lit").CSSResult[];
6
+ /** @nocollapse */
7
+ static readonly formAssociated = true;
8
+ /**
9
+ * Whether or not the radio is selected.
10
+ */
11
+ get checked(): boolean;
12
+ set checked(checked: boolean);
13
+ [CHECKED]: boolean;
14
+ disabled: boolean;
15
+ label: string;
16
+ /**
17
+ * The element value to use in form submission when checked.
18
+ */
19
+ value: string;
20
+ ariaLabel: string;
21
+ target: 'wrapper' | '';
22
+ htmlId: string | undefined;
23
+ /**
24
+ * The HTML name to use in form submission.
25
+ */
26
+ get name(): string;
27
+ set name(name: string);
28
+ /**
29
+ * The associated form element with which this element's value will submit.
30
+ */
31
+ get form(): HTMLFormElement | null;
32
+ /**
33
+ * The labels this element is associated with.
34
+ */
35
+ get labels(): NodeList;
36
+ private readonly selectionController;
37
+ private readonly internals;
38
+ private handleClick;
39
+ private handleKeydown;
40
+ constructor();
41
+ protected updated(): void;
42
+ get renderRadio(): import("lit-html").TemplateResult<1>;
43
+ render(): import("lit-html").TemplateResult<1>;
44
+ }
45
+ export {};
@@ -0,0 +1,147 @@
1
+ var _a;
2
+ import { __decorate } from "tslib";
3
+ import { html, LitElement, isServer } from 'lit';
4
+ import { ifDefined } from 'lit/directives/if-defined.js';
5
+ import { property } from 'lit/decorators.js';
6
+ import '@material/web/radio/radio.js';
7
+ import { isActivationClick } from '@material/web/internal/controller/events.js';
8
+ import { IxRadioStyles } from './ix-radio-styles.js';
9
+ import { SingleSelectionController } from './single-selection-controller.js';
10
+ import { polyfillElementInternalsAria } from '@material/web/internal/aria/aria.js';
11
+ const CHECKED = Symbol('checked');
12
+ export class IxRadio extends LitElement {
13
+ static get styles() {
14
+ return [IxRadioStyles];
15
+ }
16
+ /**
17
+ * Whether or not the radio is selected.
18
+ */
19
+ get checked() {
20
+ return this[CHECKED];
21
+ }
22
+ set checked(checked) {
23
+ const wasChecked = this.checked;
24
+ if (wasChecked === checked) {
25
+ return;
26
+ }
27
+ this[CHECKED] = checked;
28
+ const state = String(checked);
29
+ this.internals.setFormValue(this.checked ? this.value : null, state);
30
+ this.requestUpdate('checked', wasChecked);
31
+ this.selectionController.handleCheckedChange();
32
+ }
33
+ /**
34
+ * The HTML name to use in form submission.
35
+ */
36
+ get name() {
37
+ var _b;
38
+ return (_b = this.getAttribute('name')) !== null && _b !== void 0 ? _b : '';
39
+ }
40
+ set name(name) {
41
+ this.setAttribute('name', name);
42
+ }
43
+ /**
44
+ * The associated form element with which this element's value will submit.
45
+ */
46
+ get form() {
47
+ return this.internals.form;
48
+ }
49
+ /**
50
+ * The labels this element is associated with.
51
+ */
52
+ get labels() {
53
+ return this.internals.labels;
54
+ }
55
+ async handleClick(event) {
56
+ if (this.disabled) {
57
+ return;
58
+ }
59
+ // allow event to propagate to user code after a microtask.
60
+ await 0;
61
+ if (event.defaultPrevented) {
62
+ return;
63
+ }
64
+ if (isActivationClick(event)) {
65
+ this.focus();
66
+ }
67
+ // Per spec, clicking on a radio input always selects it.
68
+ this.checked = true;
69
+ this.dispatchEvent(new Event('change', { bubbles: true }));
70
+ this.dispatchEvent(new InputEvent('input', { bubbles: true, composed: true }));
71
+ }
72
+ async handleKeydown(event) {
73
+ // allow event to propagate to user code after a microtask.
74
+ await 0;
75
+ if (event.key !== ' ' || event.defaultPrevented) {
76
+ return;
77
+ }
78
+ this.click();
79
+ }
80
+ constructor() {
81
+ super();
82
+ this[_a] = false;
83
+ this.disabled = false;
84
+ this.label = '';
85
+ /**
86
+ * The element value to use in form submission when checked.
87
+ */
88
+ this.value = 'on';
89
+ this.ariaLabel = '';
90
+ this.target = '';
91
+ this.selectionController = new SingleSelectionController(this);
92
+ this.internals = polyfillElementInternalsAria(this, this /* needed for closure */.attachInternals());
93
+ this.addController(this.selectionController);
94
+ if (!isServer) {
95
+ this.internals.role = 'radio';
96
+ this.addEventListener('click', this.handleClick.bind(this));
97
+ this.addEventListener('keydown', this.handleKeydown.bind(this));
98
+ }
99
+ }
100
+ updated() {
101
+ this.internals.ariaChecked = String(this.checked);
102
+ }
103
+ get renderRadio() {
104
+ return html `
105
+ <md-radio
106
+ aria-label=${this.ariaLabel || this.label}
107
+ name=${this.name}
108
+ value=${this.value}
109
+ ?checked=${this.checked}
110
+ ?disabled=${this.disabled}
111
+ id=${ifDefined(this.htmlId)}
112
+ touch-target=${this.target}
113
+ ></md-radio>
114
+ `;
115
+ }
116
+ render() {
117
+ if (this.label)
118
+ return html `<label>${this.renderRadio}
119
+ <span> ${this.label}</span> </label>`;
120
+ return this.renderRadio;
121
+ }
122
+ }
123
+ _a = CHECKED;
124
+ /** @nocollapse */
125
+ IxRadio.formAssociated = true;
126
+ __decorate([
127
+ property({ type: Boolean })
128
+ ], IxRadio.prototype, "checked", null);
129
+ __decorate([
130
+ property({ type: Boolean, reflect: true })
131
+ ], IxRadio.prototype, "disabled", void 0);
132
+ __decorate([
133
+ property()
134
+ ], IxRadio.prototype, "label", void 0);
135
+ __decorate([
136
+ property()
137
+ ], IxRadio.prototype, "value", void 0);
138
+ __decorate([
139
+ property()
140
+ ], IxRadio.prototype, "ariaLabel", void 0);
141
+ __decorate([
142
+ property()
143
+ ], IxRadio.prototype, "target", void 0);
144
+ __decorate([
145
+ property()
146
+ ], IxRadio.prototype, "htmlId", void 0);
147
+ //# sourceMappingURL=IxRadio.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IxRadio.js","sourceRoot":"","sources":["../../src/IxRadio.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, LitElement, isServer } from 'lit';\nimport {ifDefined} from 'lit/directives/if-defined.js';\nimport { property } from 'lit/decorators.js';\nimport '@material/web/radio/radio.js';\nimport {isActivationClick} from '@material/web/internal/controller/events.js';\nimport { IxRadioStyles } from './ix-radio-styles.js';\nimport {SingleSelectionController} from './single-selection-controller.js';\nimport {polyfillElementInternalsAria, setupHostAria} from '@material/web/internal/aria/aria.js';\n\nconst CHECKED = Symbol('checked');\n\nexport class IxRadio extends LitElement {\n static get styles() {\n return [IxRadioStyles];\n }\n\n /** @nocollapse */\n static readonly formAssociated = true;\n\n /**\n * Whether or not the radio is selected.\n */\n @property({type: Boolean})\n get checked() {\n return this[CHECKED];\n }\n set checked(checked: boolean) {\n const wasChecked = this.checked;\n if (wasChecked === checked) {\n return;\n }\n\n this[CHECKED] = checked;\n const state = String(checked);\n this.internals.setFormValue(this.checked ? this.value : null, state);\n this.requestUpdate('checked', wasChecked);\n this.selectionController.handleCheckedChange();\n }\n\n [CHECKED] = false;\n\n @property({type: Boolean, reflect: true}) disabled = false;\n\n @property() label: string = '';\n\n /**\n * The element value to use in form submission when checked.\n */\n @property() value = 'on';\n\n @property() ariaLabel: string = '';\n\n @property() target: 'wrapper' | '' = '';\n\n @property() htmlId: string | undefined;\n\n /**\n * The HTML name to use in form submission.\n */\n get name() {\n return this.getAttribute('name') ?? '';\n }\n set name(name: string) {\n this.setAttribute('name', name);\n }\n\n /**\n * The associated form element with which this element's value will submit.\n */\n get form() {\n return this.internals.form;\n }\n\n /**\n * The labels this element is associated with.\n */\n get labels() {\n return this.internals.labels;\n }\n\n private readonly selectionController = new SingleSelectionController(this);\n\n private readonly internals = polyfillElementInternalsAria(\n this, (this as HTMLElement /* needed for closure */).attachInternals());\n\n private async handleClick(event: Event) {\n if (this.disabled) {\n return;\n }\n\n // allow event to propagate to user code after a microtask.\n await 0;\n if (event.defaultPrevented) {\n return;\n }\n\n if (isActivationClick(event)) {\n this.focus();\n }\n\n // Per spec, clicking on a radio input always selects it.\n this.checked = true;\n this.dispatchEvent(new Event('change', {bubbles: true}));\n this.dispatchEvent(\n new InputEvent('input', {bubbles: true, composed: true}));\n }\n\n private async handleKeydown(event: KeyboardEvent) {\n // allow event to propagate to user code after a microtask.\n await 0;\n if (event.key !== ' ' || event.defaultPrevented) {\n return;\n }\n\n this.click();\n }\n\n constructor() {\n super();\n this.addController(this.selectionController);\n if (!isServer) {\n this.internals.role = 'radio';\n this.addEventListener('click', this.handleClick.bind(this));\n this.addEventListener('keydown', this.handleKeydown.bind(this));\n }\n }\n\n protected override updated() {\n this.internals.ariaChecked = String(this.checked);\n }\n\n get renderRadio() {\n return html`\n <md-radio\n aria-label=${this.ariaLabel || this.label }\n name=${this.name}\n value=${this.value}\n ?checked=${this.checked}\n ?disabled=${this.disabled}\n id=${ifDefined(this.htmlId)}\n touch-target=${this.target}\n ></md-radio>\n `;\n }\n\n render() {\n if (this.label)\n return html`<label>${this.renderRadio}\n <span> ${this.label}</span> </label>`;\n\n return this.renderRadio;\n }\n}\n"]}
@@ -0,0 +1 @@
1
+ export { IxRadio } from './IxRadio.js';
@@ -0,0 +1,2 @@
1
+ export { IxRadio } from './IxRadio.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC","sourcesContent":["export { IxRadio } from './IxRadio.js';\n"]}
@@ -0,0 +1 @@
1
+ export declare const IxRadioStyles: import("lit").CSSResult;
@@ -0,0 +1,3 @@
1
+ import { css } from 'lit';
2
+ export const IxRadioStyles = css ``;
3
+ //# sourceMappingURL=ix-radio-styles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ix-radio-styles.js","sourceRoot":"","sources":["../../src/ix-radio-styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,CAAA,EAAE,CAAC","sourcesContent":["import { css } from 'lit';\n\nexport const IxRadioStyles = css``;\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ import { IxRadio } from './IxRadio.js';
2
+ window.customElements.define('ix-radio', IxRadio);
3
+ //# sourceMappingURL=ix-radio.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ix-radio.js","sourceRoot":"","sources":["../../src/ix-radio.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC","sourcesContent":["import { IxRadio } from './IxRadio.js';\n\nwindow.customElements.define('ix-radio', IxRadio);\n"]}
@@ -0,0 +1,5 @@
1
+ import { IxRadio as IxRadioLit } from '../IxRadio.js';
2
+ export declare const IxButton: import("@lit-labs/react").ReactWebComponent<IxRadioLit, {
3
+ onclick: string;
4
+ onkeydown: string;
5
+ }>;
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ import { createComponent } from '@lit-labs/react';
3
+ import { IxRadio as IxRadioLit } from '../IxRadio.js';
4
+ window.customElements.define('ix-button', IxRadioLit);
5
+ export const IxButton = createComponent({
6
+ tagName: 'ix-radio',
7
+ elementClass: IxRadioLit,
8
+ react: React,
9
+ events: {
10
+ onclick: 'onClick',
11
+ onkeydown: 'keydown'
12
+ },
13
+ });
14
+ //# sourceMappingURL=IxRadio.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IxRadio.js","sourceRoot":"","sources":["../../../src/react/IxRadio.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,eAAe,CAAC;AAEtD,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;AAEtD,MAAM,CAAC,MAAM,QAAQ,GAAG,eAAe,CAAC;IACtC,OAAO,EAAE,UAAU;IACnB,YAAY,EAAE,UAAU;IACxB,KAAK,EAAE,KAAK;IACZ,MAAM,EAAE;QACN,OAAO,EAAE,SAAS;QAClB,SAAS,EAAE,SAAS;KACrB;CACF,CAAC,CAAC","sourcesContent":["import React from 'react';\nimport { createComponent } from '@lit-labs/react';\nimport { IxRadio as IxRadioLit } from '../IxRadio.js';\n\nwindow.customElements.define('ix-button', IxRadioLit);\n\nexport const IxButton = createComponent({\n tagName: 'ix-radio',\n elementClass: IxRadioLit,\n react: React,\n events: {\n onclick: 'onClick',\n onkeydown: 'keydown'\n },\n});\n"]}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { ReactiveController } from 'lit';
7
+ /**
8
+ * An element that supports single-selection with `SingleSelectionController`.
9
+ */
10
+ export interface SingleSelectionElement extends HTMLElement {
11
+ /**
12
+ * Whether or not the element is selected.
13
+ */
14
+ checked: boolean;
15
+ }
16
+ /**
17
+ * A `ReactiveController` that provides root node-scoped single selection for
18
+ * elements, similar to native `<input type="radio">` selection.
19
+ *
20
+ * To use, elements should add the controller and call
21
+ * `selectionController.handleCheckedChange()` in a getter/setter. This must
22
+ * be synchronous to match native behavior.
23
+ *
24
+ * @example
25
+ * const CHECKED = Symbol('checked');
26
+ *
27
+ * class MyToggle extends LitElement {
28
+ * get checked() { return this[CHECKED]; }
29
+ * set checked(checked: boolean) {
30
+ * const oldValue = this.checked;
31
+ * if (oldValue === checked) {
32
+ * return;
33
+ * }
34
+ *
35
+ * this[CHECKED] = checked;
36
+ * this.selectionController.handleCheckedChange();
37
+ * this.requestUpdate('checked', oldValue);
38
+ * }
39
+ *
40
+ * [CHECKED] = false;
41
+ *
42
+ * private selectionController = new SingleSelectionController(this);
43
+ *
44
+ * constructor() {
45
+ * super();
46
+ * this.addController(this.selectionController);
47
+ * }
48
+ * }
49
+ */
50
+ export declare class SingleSelectionController implements ReactiveController {
51
+ private readonly host;
52
+ private focused;
53
+ private root;
54
+ constructor(host: SingleSelectionElement);
55
+ hostConnected(): void;
56
+ hostDisconnected(): void;
57
+ /**
58
+ * Should be called whenever the host's `checked` property changes
59
+ * synchronously.
60
+ */
61
+ handleCheckedChange(): void;
62
+ private readonly handleFocusIn;
63
+ private readonly handleFocusOut;
64
+ private uncheckSiblings;
65
+ /**
66
+ * Updates the `tabindex` of the host and its siblings.
67
+ */
68
+ private updateTabIndices;
69
+ /**
70
+ * Retrieves all siblings in the host element's root with the same `name`
71
+ * attribute.
72
+ */
73
+ private getNamedSiblings;
74
+ /**
75
+ * Handles arrow key events from the host. Using the arrow keys will
76
+ * select and check the next or previous sibling with the host's
77
+ * `name` attribute.
78
+ */
79
+ private readonly handleKeyDown;
80
+ }