@fluid-topics/ft-radio 1.3.14 → 1.3.16
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/build/ft-base-radio-group.d.ts +30 -0
- package/build/ft-base-radio-group.js +130 -0
- package/build/ft-base-radio.d.ts +37 -0
- package/build/ft-base-radio.js +135 -0
- package/build/ft-radio-group.d.ts +3 -24
- package/build/ft-radio-group.js +3 -126
- package/build/ft-radio.d.ts +4 -27
- package/build/ft-radio.js +8 -132
- package/build/ft-radio.light.js +240 -120
- package/build/ft-radio.min.js +248 -128
- package/build/ft-radio.styles.d.ts +1 -1
- package/build/ft-radio.styles.js +1 -1
- package/build/ftds-radio-group.d.ts +8 -0
- package/build/ftds-radio-group.js +15 -0
- package/build/ftds-radio-group.styles.d.ts +1 -0
- package/build/ftds-radio-group.styles.js +13 -0
- package/build/ftds-radio.d.ts +11 -0
- package/build/ftds-radio.js +25 -0
- package/build/ftds-radio.styles.d.ts +3 -0
- package/build/ftds-radio.styles.js +113 -0
- package/build/index.d.ts +4 -2
- package/build/index.js +8 -2
- package/package.json +5 -5
- package/build/ft-radio-group.properties.d.ts +0 -3
- package/build/ft-radio-group.properties.js +0 -1
- package/build/ft-radio.properties.d.ts +0 -6
- package/build/ft-radio.properties.js +0 -1
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { FtLitElement } from "@fluid-topics/ft-wc-utils";
|
|
2
|
+
import { PropertyValues } from "lit";
|
|
3
|
+
import { FtBaseRadio } from "./ft-radio";
|
|
4
|
+
export interface FtBaseRadioGroupProperties {
|
|
5
|
+
name?: string;
|
|
6
|
+
role?: string;
|
|
7
|
+
tabIndex?: number;
|
|
8
|
+
ariaLabelledBy?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare class FtBaseRadioGroup extends FtLitElement implements FtBaseRadioGroupProperties {
|
|
11
|
+
static elementDefinitions: {};
|
|
12
|
+
name: string;
|
|
13
|
+
role: string;
|
|
14
|
+
tabIndex: number;
|
|
15
|
+
ariaLabelledBy: string;
|
|
16
|
+
assignedElements?: Array<Element>;
|
|
17
|
+
get radioButtons(): Array<FtBaseRadio>;
|
|
18
|
+
currentSelectedIndex: number;
|
|
19
|
+
protected render(): import("lit-html").TemplateResult<1>;
|
|
20
|
+
connectedCallback(): void;
|
|
21
|
+
disconnectedCallback(): void;
|
|
22
|
+
private onSlotChange;
|
|
23
|
+
protected contentAvailableCallback(props: PropertyValues): void;
|
|
24
|
+
private onFocus;
|
|
25
|
+
private onFocusOut;
|
|
26
|
+
private onChange;
|
|
27
|
+
private onKeyDown;
|
|
28
|
+
private resolveCurrentSelectedIndex;
|
|
29
|
+
private focusCurrentChecked;
|
|
30
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { FtLitElement } from "@fluid-topics/ft-wc-utils";
|
|
8
|
+
import { property, queryAssignedElements, state } from "lit/decorators.js";
|
|
9
|
+
import { html } from "lit";
|
|
10
|
+
class FtBaseRadioGroup extends FtLitElement {
|
|
11
|
+
constructor() {
|
|
12
|
+
super(...arguments);
|
|
13
|
+
this.name = "";
|
|
14
|
+
this.role = "radiogroup";
|
|
15
|
+
this.tabIndex = 0;
|
|
16
|
+
this.ariaLabelledBy = "";
|
|
17
|
+
this.currentSelectedIndex = 0;
|
|
18
|
+
this.onFocus = () => {
|
|
19
|
+
if (this.tabIndex == 0) {
|
|
20
|
+
this.tabIndex = -1;
|
|
21
|
+
setTimeout(() => this.focusCurrentChecked(), 100);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
this.onFocusOut = (e) => {
|
|
25
|
+
const nextFocusOutsideOfGroup = !this.contains(e.relatedTarget);
|
|
26
|
+
if (nextFocusOutsideOfGroup) {
|
|
27
|
+
this.tabIndex = 0;
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
get radioButtons() {
|
|
32
|
+
var _a, _b;
|
|
33
|
+
return (_b = (_a = this.assignedElements) === null || _a === void 0 ? void 0 : _a.flatMap((e) => e.matches("ft-radio,ftds-radio")
|
|
34
|
+
? [e]
|
|
35
|
+
: [...e.querySelectorAll("ft-radio,ftds-radio")])) !== null && _b !== void 0 ? _b : [];
|
|
36
|
+
}
|
|
37
|
+
render() {
|
|
38
|
+
return html `
|
|
39
|
+
<slot @slotchange=${this.onSlotChange}
|
|
40
|
+
@change=${this.onChange}
|
|
41
|
+
@keydown=${this.onKeyDown}
|
|
42
|
+
></slot>
|
|
43
|
+
`;
|
|
44
|
+
}
|
|
45
|
+
connectedCallback() {
|
|
46
|
+
super.connectedCallback();
|
|
47
|
+
this.addEventListener("focus", this.onFocus);
|
|
48
|
+
this.addEventListener("focusout", this.onFocusOut);
|
|
49
|
+
}
|
|
50
|
+
disconnectedCallback() {
|
|
51
|
+
super.disconnectedCallback();
|
|
52
|
+
this.removeEventListener("focus", this.onFocus);
|
|
53
|
+
this.removeEventListener("focusout", this.onFocusOut);
|
|
54
|
+
}
|
|
55
|
+
onSlotChange() {
|
|
56
|
+
this.radioButtons.forEach((rb) => rb.name = this.name);
|
|
57
|
+
}
|
|
58
|
+
contentAvailableCallback(props) {
|
|
59
|
+
super.contentAvailableCallback(props);
|
|
60
|
+
this.radioButtons.forEach((rb) => rb.setInputTabIndex(-1)); // RadioButton is no more selectable alone
|
|
61
|
+
this.resolveCurrentSelectedIndex();
|
|
62
|
+
}
|
|
63
|
+
onChange(event) {
|
|
64
|
+
event.stopPropagation();
|
|
65
|
+
this.radioButtons.forEach((rb) => rb.checked = event.detail.value === rb.value);
|
|
66
|
+
this.dispatchEvent(new CustomEvent("change", { detail: event.detail.value }));
|
|
67
|
+
this.resolveCurrentSelectedIndex();
|
|
68
|
+
}
|
|
69
|
+
onKeyDown(event) {
|
|
70
|
+
let blockUnwhishedReaction = false;
|
|
71
|
+
switch (event.key) {
|
|
72
|
+
case "ArrowUp":
|
|
73
|
+
case "ArrowLeft": {
|
|
74
|
+
blockUnwhishedReaction = true;
|
|
75
|
+
const indexToFocus = this.currentSelectedIndex - 1;
|
|
76
|
+
this.radioButtons[indexToFocus < 0 ? this.radioButtons.length - 1 : indexToFocus].select();
|
|
77
|
+
this.radioButtons[indexToFocus < 0 ? this.radioButtons.length - 1 : indexToFocus].focus();
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
case "ArrowDown":
|
|
81
|
+
case "ArrowRight": {
|
|
82
|
+
blockUnwhishedReaction = true;
|
|
83
|
+
const indexToFocus = this.currentSelectedIndex + 1;
|
|
84
|
+
this.radioButtons[indexToFocus > this.radioButtons.length - 1 ? 0 : indexToFocus].select();
|
|
85
|
+
this.radioButtons[indexToFocus > this.radioButtons.length - 1 ? 0 : indexToFocus].focus();
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
case "Enter": {
|
|
89
|
+
this.radioButtons[this.currentSelectedIndex].select();
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (blockUnwhishedReaction) {
|
|
93
|
+
event.stopPropagation();
|
|
94
|
+
event.preventDefault();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
resolveCurrentSelectedIndex() {
|
|
98
|
+
const checkedButtonIndex = this.radioButtons.findIndex((rb) => rb.checked);
|
|
99
|
+
if (checkedButtonIndex == -1) {
|
|
100
|
+
this.currentSelectedIndex = 0;
|
|
101
|
+
this.radioButtons[0].select();
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
this.currentSelectedIndex = checkedButtonIndex;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
focusCurrentChecked() {
|
|
108
|
+
this.radioButtons[this.currentSelectedIndex].focus();
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
FtBaseRadioGroup.elementDefinitions = {};
|
|
112
|
+
__decorate([
|
|
113
|
+
property()
|
|
114
|
+
], FtBaseRadioGroup.prototype, "name", void 0);
|
|
115
|
+
__decorate([
|
|
116
|
+
property({ reflect: true, attribute: "role" })
|
|
117
|
+
], FtBaseRadioGroup.prototype, "role", void 0);
|
|
118
|
+
__decorate([
|
|
119
|
+
property({ reflect: true })
|
|
120
|
+
], FtBaseRadioGroup.prototype, "tabIndex", void 0);
|
|
121
|
+
__decorate([
|
|
122
|
+
property({ reflect: true, attribute: "aria-labelledby" })
|
|
123
|
+
], FtBaseRadioGroup.prototype, "ariaLabelledBy", void 0);
|
|
124
|
+
__decorate([
|
|
125
|
+
queryAssignedElements()
|
|
126
|
+
], FtBaseRadioGroup.prototype, "assignedElements", void 0);
|
|
127
|
+
__decorate([
|
|
128
|
+
state()
|
|
129
|
+
], FtBaseRadioGroup.prototype, "currentSelectedIndex", void 0);
|
|
130
|
+
export { FtBaseRadioGroup };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { PropertyValues } from "lit";
|
|
2
|
+
import { ElementDefinitionsMap, FtLitElement } from "@fluid-topics/ft-wc-utils";
|
|
3
|
+
import { ClassInfo } from "lit/directives/class-map.js";
|
|
4
|
+
export declare class FtRadioChangeEvent extends CustomEvent<{
|
|
5
|
+
value: string;
|
|
6
|
+
checked: boolean;
|
|
7
|
+
}> {
|
|
8
|
+
constructor(value: string, checked: boolean);
|
|
9
|
+
}
|
|
10
|
+
export interface FtBaseRadioProperties {
|
|
11
|
+
value?: string;
|
|
12
|
+
name?: string;
|
|
13
|
+
checked?: boolean;
|
|
14
|
+
ariaChecked?: string;
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
}
|
|
17
|
+
export declare class FtBaseRadio extends FtLitElement implements FtBaseRadioProperties {
|
|
18
|
+
static elementDefinitions: ElementDefinitionsMap;
|
|
19
|
+
value: string;
|
|
20
|
+
name: string;
|
|
21
|
+
checked: boolean;
|
|
22
|
+
ariaChecked: string;
|
|
23
|
+
disabled: boolean;
|
|
24
|
+
private container?;
|
|
25
|
+
private ripple?;
|
|
26
|
+
private input?;
|
|
27
|
+
get radioClasses(): ClassInfo;
|
|
28
|
+
get typographyVariant(): string;
|
|
29
|
+
protected render(): import("lit-html").TemplateResult<1>;
|
|
30
|
+
protected willUpdate(changedProperties: PropertyValues): void;
|
|
31
|
+
private onChange;
|
|
32
|
+
protected contentAvailableCallback(props: PropertyValues): void;
|
|
33
|
+
select(): void;
|
|
34
|
+
setInputTabIndex(index: number): void;
|
|
35
|
+
focus(): void;
|
|
36
|
+
onClick(e: Event): void;
|
|
37
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { html } from "lit";
|
|
8
|
+
import { property, query } from "lit/decorators.js";
|
|
9
|
+
import { FtLitElement } from "@fluid-topics/ft-wc-utils";
|
|
10
|
+
import { classMap } from "lit/directives/class-map.js";
|
|
11
|
+
import { FtRipple } from "@fluid-topics/ft-ripple";
|
|
12
|
+
import { FtTypography } from "@fluid-topics/ft-typography";
|
|
13
|
+
export class FtRadioChangeEvent extends CustomEvent {
|
|
14
|
+
constructor(value, checked) {
|
|
15
|
+
super("change", { detail: { value: value, checked: checked }, bubbles: true, composed: true });
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
class FtBaseRadio extends FtLitElement {
|
|
19
|
+
constructor() {
|
|
20
|
+
super(...arguments);
|
|
21
|
+
this.value = "";
|
|
22
|
+
this.name = "";
|
|
23
|
+
this.checked = false;
|
|
24
|
+
this.ariaChecked = "false";
|
|
25
|
+
this.disabled = false;
|
|
26
|
+
}
|
|
27
|
+
get radioClasses() {
|
|
28
|
+
return {
|
|
29
|
+
"ft-radio": true,
|
|
30
|
+
"ft-radio--checked": this.checked,
|
|
31
|
+
"ft-radio--disabled": this.disabled,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
get typographyVariant() {
|
|
35
|
+
return "";
|
|
36
|
+
}
|
|
37
|
+
render() {
|
|
38
|
+
// We use aria-hidden on the input to prevent the "radio" role to be present twice in the aria tree
|
|
39
|
+
return html `
|
|
40
|
+
<div class="${classMap(this.radioClasses)}"
|
|
41
|
+
@click=${this.onClick}>
|
|
42
|
+
<div class="ft-radio--box-container">
|
|
43
|
+
<ft-ripple
|
|
44
|
+
?disabled=${this.disabled}
|
|
45
|
+
?primary=${this.checked}
|
|
46
|
+
unbounded>
|
|
47
|
+
</ft-ripple>
|
|
48
|
+
<div class="ft-radio--box">
|
|
49
|
+
</div>
|
|
50
|
+
<input id="radio-button"
|
|
51
|
+
type="radio"
|
|
52
|
+
name="${this.name}"
|
|
53
|
+
value="${this.value}"
|
|
54
|
+
.checked=${this.checked}
|
|
55
|
+
.disabled=${this.disabled}
|
|
56
|
+
@change=${this.onChange}
|
|
57
|
+
aria-hidden="true">
|
|
58
|
+
</div>
|
|
59
|
+
<label for="radio-button">
|
|
60
|
+
<ft-typography variant="${this.typographyVariant}">
|
|
61
|
+
<slot></slot>
|
|
62
|
+
</ft-typography>
|
|
63
|
+
</label>
|
|
64
|
+
</div>
|
|
65
|
+
`;
|
|
66
|
+
}
|
|
67
|
+
willUpdate(changedProperties) {
|
|
68
|
+
super.willUpdate(changedProperties);
|
|
69
|
+
if (changedProperties.has("checked")) {
|
|
70
|
+
this.ariaChecked = this.checked ? "true" : "false";
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
onChange(event) {
|
|
74
|
+
event.stopPropagation();
|
|
75
|
+
this.checked = event.target.checked;
|
|
76
|
+
this.dispatchEvent(new FtRadioChangeEvent(this.value, this.checked));
|
|
77
|
+
}
|
|
78
|
+
contentAvailableCallback(props) {
|
|
79
|
+
var _a;
|
|
80
|
+
super.contentAvailableCallback(props);
|
|
81
|
+
(_a = this.ripple) === null || _a === void 0 ? void 0 : _a.setupFor(this.container);
|
|
82
|
+
}
|
|
83
|
+
select() {
|
|
84
|
+
this.checked = true;
|
|
85
|
+
this.dispatchEvent(new FtRadioChangeEvent(this.value, this.checked));
|
|
86
|
+
}
|
|
87
|
+
setInputTabIndex(index) {
|
|
88
|
+
if (this.input) {
|
|
89
|
+
this.input.tabIndex = index;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
focus() {
|
|
93
|
+
var _a;
|
|
94
|
+
(_a = this.input) === null || _a === void 0 ? void 0 : _a.focus();
|
|
95
|
+
setTimeout(() => { var _a; return (_a = this.ripple) === null || _a === void 0 ? void 0 : _a.forceFocusUpdate(); }, 0);
|
|
96
|
+
}
|
|
97
|
+
onClick(e) {
|
|
98
|
+
var _a;
|
|
99
|
+
if (e.target === this.input) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
e.stopPropagation();
|
|
103
|
+
e.preventDefault();
|
|
104
|
+
(_a = this.input) === null || _a === void 0 ? void 0 : _a.click();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
FtBaseRadio.elementDefinitions = {
|
|
108
|
+
"ft-ripple": FtRipple,
|
|
109
|
+
"ft-typography": FtTypography,
|
|
110
|
+
};
|
|
111
|
+
__decorate([
|
|
112
|
+
property()
|
|
113
|
+
], FtBaseRadio.prototype, "value", void 0);
|
|
114
|
+
__decorate([
|
|
115
|
+
property()
|
|
116
|
+
], FtBaseRadio.prototype, "name", void 0);
|
|
117
|
+
__decorate([
|
|
118
|
+
property({ type: Boolean, reflect: true })
|
|
119
|
+
], FtBaseRadio.prototype, "checked", void 0);
|
|
120
|
+
__decorate([
|
|
121
|
+
property({ attribute: "aria-checked", reflect: true })
|
|
122
|
+
], FtBaseRadio.prototype, "ariaChecked", void 0);
|
|
123
|
+
__decorate([
|
|
124
|
+
property({ type: Boolean })
|
|
125
|
+
], FtBaseRadio.prototype, "disabled", void 0);
|
|
126
|
+
__decorate([
|
|
127
|
+
query(".ft-radio")
|
|
128
|
+
], FtBaseRadio.prototype, "container", void 0);
|
|
129
|
+
__decorate([
|
|
130
|
+
query("ft-ripple")
|
|
131
|
+
], FtBaseRadio.prototype, "ripple", void 0);
|
|
132
|
+
__decorate([
|
|
133
|
+
query("input")
|
|
134
|
+
], FtBaseRadio.prototype, "input", void 0);
|
|
135
|
+
export { FtBaseRadio };
|
|
@@ -1,26 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import { FtRadioGroupProperties } from "./ft-radio-group.properties";
|
|
5
|
-
export declare class FtRadioGroup extends FtLitElement implements FtRadioGroupProperties {
|
|
6
|
-
static elementDefinitions: {};
|
|
7
|
-
name: string;
|
|
8
|
-
role: string;
|
|
9
|
-
tabIndex: number;
|
|
10
|
-
ariaLabelledBy: string;
|
|
11
|
-
assignedElements?: Array<Element>;
|
|
12
|
-
get radioButtons(): Array<FtRadio>;
|
|
13
|
-
currentSelectedIndex: number;
|
|
1
|
+
import { FtBaseRadioGroup, FtBaseRadioGroupProperties } from "./ft-base-radio-group";
|
|
2
|
+
export * from "./ft-base-radio-group";
|
|
3
|
+
export declare class FtRadioGroup extends FtBaseRadioGroup implements FtBaseRadioGroupProperties {
|
|
14
4
|
static styles: import("lit").CSSResult;
|
|
15
|
-
protected render(): import("lit-html").TemplateResult<1>;
|
|
16
|
-
connectedCallback(): void;
|
|
17
|
-
disconnectedCallback(): void;
|
|
18
|
-
private onSlotChange;
|
|
19
|
-
protected contentAvailableCallback(props: PropertyValues): void;
|
|
20
|
-
private onFocus;
|
|
21
|
-
private onFocusOut;
|
|
22
|
-
private onChange;
|
|
23
|
-
private onKeyDown;
|
|
24
|
-
private resolveCurrentSelectedIndex;
|
|
25
|
-
private focusCurrentChecked;
|
|
26
5
|
}
|
package/build/ft-radio-group.js
CHANGED
|
@@ -1,130 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
-
};
|
|
7
|
-
import { FtLitElement } from "@fluid-topics/ft-wc-utils";
|
|
8
|
-
import { property, queryAssignedElements, state } from "lit/decorators.js";
|
|
9
|
-
import { html } from "lit";
|
|
1
|
+
import { FtBaseRadioGroup } from "./ft-base-radio-group";
|
|
10
2
|
import { groupStyles } from "./ft-radio-group.styles";
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
super(...arguments);
|
|
14
|
-
this.name = "";
|
|
15
|
-
this.role = "radiogroup";
|
|
16
|
-
this.tabIndex = 0;
|
|
17
|
-
this.ariaLabelledBy = "";
|
|
18
|
-
this.currentSelectedIndex = 0;
|
|
19
|
-
this.onFocus = () => {
|
|
20
|
-
if (this.tabIndex == 0) {
|
|
21
|
-
this.tabIndex = -1;
|
|
22
|
-
setTimeout(() => this.focusCurrentChecked(), 100);
|
|
23
|
-
}
|
|
24
|
-
};
|
|
25
|
-
this.onFocusOut = (e) => {
|
|
26
|
-
let nextFocusOutsideOfGroup = !this.contains(e.relatedTarget);
|
|
27
|
-
if (nextFocusOutsideOfGroup) {
|
|
28
|
-
this.tabIndex = 0;
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
get radioButtons() {
|
|
33
|
-
var _a, _b;
|
|
34
|
-
return (_b = (_a = this.assignedElements) === null || _a === void 0 ? void 0 : _a.flatMap(e => e.matches("ft-radio") ? [e] : [...e.querySelectorAll("ft-radio")])) !== null && _b !== void 0 ? _b : [];
|
|
35
|
-
}
|
|
36
|
-
render() {
|
|
37
|
-
return html `
|
|
38
|
-
<slot @slotchange=${this.onSlotChange}
|
|
39
|
-
@change=${this.onChange}
|
|
40
|
-
@keydown=${this.onKeyDown}
|
|
41
|
-
></slot>
|
|
42
|
-
`;
|
|
43
|
-
}
|
|
44
|
-
connectedCallback() {
|
|
45
|
-
super.connectedCallback();
|
|
46
|
-
this.addEventListener("focus", this.onFocus);
|
|
47
|
-
this.addEventListener("focusout", this.onFocusOut);
|
|
48
|
-
}
|
|
49
|
-
disconnectedCallback() {
|
|
50
|
-
super.disconnectedCallback();
|
|
51
|
-
this.removeEventListener("focus", this.onFocus);
|
|
52
|
-
this.removeEventListener("focusout", this.onFocusOut);
|
|
53
|
-
}
|
|
54
|
-
onSlotChange() {
|
|
55
|
-
this.radioButtons.forEach(rb => rb.name = this.name);
|
|
56
|
-
}
|
|
57
|
-
contentAvailableCallback(props) {
|
|
58
|
-
super.contentAvailableCallback(props);
|
|
59
|
-
this.radioButtons.forEach(rb => rb.setInputTabIndex(-1)); // RadioButton is no more selectable alone
|
|
60
|
-
this.resolveCurrentSelectedIndex();
|
|
61
|
-
}
|
|
62
|
-
onChange(event) {
|
|
63
|
-
event.stopPropagation();
|
|
64
|
-
this.radioButtons.forEach(rb => rb.checked = event.detail.value === rb.value);
|
|
65
|
-
this.dispatchEvent(new CustomEvent("change", { detail: event.detail.value }));
|
|
66
|
-
this.resolveCurrentSelectedIndex();
|
|
67
|
-
}
|
|
68
|
-
onKeyDown(event) {
|
|
69
|
-
let blockUnwhishedReaction = false;
|
|
70
|
-
switch (event.key) {
|
|
71
|
-
case "ArrowUp":
|
|
72
|
-
case "ArrowLeft": {
|
|
73
|
-
blockUnwhishedReaction = true;
|
|
74
|
-
let indexToFocus = this.currentSelectedIndex - 1;
|
|
75
|
-
this.radioButtons[indexToFocus < 0 ? this.radioButtons.length - 1 : indexToFocus].select();
|
|
76
|
-
this.radioButtons[indexToFocus < 0 ? this.radioButtons.length - 1 : indexToFocus].focus();
|
|
77
|
-
break;
|
|
78
|
-
}
|
|
79
|
-
case "ArrowDown":
|
|
80
|
-
case "ArrowRight": {
|
|
81
|
-
blockUnwhishedReaction = true;
|
|
82
|
-
let indexToFocus = this.currentSelectedIndex + 1;
|
|
83
|
-
this.radioButtons[indexToFocus > this.radioButtons.length - 1 ? 0 : indexToFocus].select();
|
|
84
|
-
this.radioButtons[indexToFocus > this.radioButtons.length - 1 ? 0 : indexToFocus].focus();
|
|
85
|
-
break;
|
|
86
|
-
}
|
|
87
|
-
case "Enter": {
|
|
88
|
-
this.radioButtons[this.currentSelectedIndex].select();
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
if (blockUnwhishedReaction) {
|
|
92
|
-
event.stopPropagation();
|
|
93
|
-
event.preventDefault();
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
resolveCurrentSelectedIndex() {
|
|
97
|
-
let checkedButtonIndex = this.radioButtons.findIndex(rb => rb.checked);
|
|
98
|
-
if (checkedButtonIndex == -1) {
|
|
99
|
-
this.currentSelectedIndex = 0;
|
|
100
|
-
this.radioButtons[0].select();
|
|
101
|
-
}
|
|
102
|
-
else {
|
|
103
|
-
this.currentSelectedIndex = checkedButtonIndex;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
focusCurrentChecked() {
|
|
107
|
-
this.radioButtons[this.currentSelectedIndex].focus();
|
|
108
|
-
}
|
|
3
|
+
export * from "./ft-base-radio-group";
|
|
4
|
+
class FtRadioGroup extends FtBaseRadioGroup {
|
|
109
5
|
}
|
|
110
|
-
FtRadioGroup.elementDefinitions = {};
|
|
111
6
|
FtRadioGroup.styles = groupStyles;
|
|
112
|
-
__decorate([
|
|
113
|
-
property()
|
|
114
|
-
], FtRadioGroup.prototype, "name", void 0);
|
|
115
|
-
__decorate([
|
|
116
|
-
property({ reflect: true, attribute: "role" })
|
|
117
|
-
], FtRadioGroup.prototype, "role", void 0);
|
|
118
|
-
__decorate([
|
|
119
|
-
property({ reflect: true })
|
|
120
|
-
], FtRadioGroup.prototype, "tabIndex", void 0);
|
|
121
|
-
__decorate([
|
|
122
|
-
property({ reflect: true, attribute: "aria-labelledby" })
|
|
123
|
-
], FtRadioGroup.prototype, "ariaLabelledBy", void 0);
|
|
124
|
-
__decorate([
|
|
125
|
-
queryAssignedElements()
|
|
126
|
-
], FtRadioGroup.prototype, "assignedElements", void 0);
|
|
127
|
-
__decorate([
|
|
128
|
-
state()
|
|
129
|
-
], FtRadioGroup.prototype, "currentSelectedIndex", void 0);
|
|
130
7
|
export { FtRadioGroup };
|
package/build/ft-radio.d.ts
CHANGED
|
@@ -1,29 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export declare class FtRadioChangeEvent extends CustomEvent<{
|
|
5
|
-
value: string;
|
|
6
|
-
checked: boolean;
|
|
7
|
-
}> {
|
|
8
|
-
constructor(value: string, checked: boolean);
|
|
9
|
-
}
|
|
10
|
-
export declare class FtRadio extends FtLitElement implements FtRadioProperties {
|
|
11
|
-
static elementDefinitions: ElementDefinitionsMap;
|
|
1
|
+
import { FtBaseRadio, FtBaseRadioProperties } from "./ft-base-radio";
|
|
2
|
+
export * from "./ft-base-radio";
|
|
3
|
+
export declare class FtRadio extends FtBaseRadio implements FtBaseRadioProperties {
|
|
12
4
|
static styles: import("lit").CSSResult;
|
|
13
|
-
|
|
14
|
-
name: string;
|
|
15
|
-
checked: boolean;
|
|
16
|
-
ariaChecked: string;
|
|
17
|
-
disabled: boolean;
|
|
18
|
-
role: string;
|
|
19
|
-
private container?;
|
|
20
|
-
private ripple?;
|
|
21
|
-
private input?;
|
|
22
|
-
protected render(): import("lit-html").TemplateResult<1>;
|
|
23
|
-
protected update(changedProperties: PropertyValues): void;
|
|
24
|
-
private onChange;
|
|
25
|
-
protected contentAvailableCallback(props: PropertyValues): void;
|
|
26
|
-
select(): void;
|
|
27
|
-
setInputTabIndex(index: number): void;
|
|
28
|
-
focus(): void;
|
|
5
|
+
get typographyVariant(): string;
|
|
29
6
|
}
|
package/build/ft-radio.js
CHANGED
|
@@ -1,135 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
import { property, query } from "lit/decorators.js";
|
|
9
|
-
import { FtLitElement } from "@fluid-topics/ft-wc-utils";
|
|
10
|
-
import { classMap } from "lit/directives/class-map.js";
|
|
11
|
-
import { FtRipple } from "@fluid-topics/ft-ripple";
|
|
12
|
-
import { FtTypography } from "@fluid-topics/ft-typography";
|
|
13
|
-
import { styles } from "./ft-radio.styles";
|
|
14
|
-
export class FtRadioChangeEvent extends CustomEvent {
|
|
15
|
-
constructor(value, checked) {
|
|
16
|
-
super("change", { detail: { value: value, checked: checked }, bubbles: true, composed: true });
|
|
1
|
+
import { FtBaseRadio } from "./ft-base-radio";
|
|
2
|
+
import { classicStyles } from "./ft-radio.styles";
|
|
3
|
+
import { FtTypographyVariants } from "@fluid-topics/ft-typography/build/ft-typography.properties";
|
|
4
|
+
export * from "./ft-base-radio";
|
|
5
|
+
class FtRadio extends FtBaseRadio {
|
|
6
|
+
get typographyVariant() {
|
|
7
|
+
return FtTypographyVariants.body2;
|
|
17
8
|
}
|
|
18
9
|
}
|
|
19
|
-
|
|
20
|
-
constructor() {
|
|
21
|
-
super(...arguments);
|
|
22
|
-
this.value = "";
|
|
23
|
-
this.name = "";
|
|
24
|
-
this.checked = false;
|
|
25
|
-
this.ariaChecked = "false";
|
|
26
|
-
this.disabled = false;
|
|
27
|
-
this.role = "radio";
|
|
28
|
-
}
|
|
29
|
-
render() {
|
|
30
|
-
const classes = {
|
|
31
|
-
"ft-radio": true,
|
|
32
|
-
"ft-radio--checked": this.checked,
|
|
33
|
-
"ft-radio--disabled": this.disabled,
|
|
34
|
-
};
|
|
35
|
-
return html `
|
|
36
|
-
<div class="${classMap(classes)}">
|
|
37
|
-
<div class="ft-radio--box-container">
|
|
38
|
-
<ft-ripple
|
|
39
|
-
?disabled=${this.disabled}
|
|
40
|
-
?primary=${this.checked}
|
|
41
|
-
unbounded>
|
|
42
|
-
</ft-ripple>
|
|
43
|
-
<div class="ft-radio--box">
|
|
44
|
-
</div>
|
|
45
|
-
<input id="radio-button"
|
|
46
|
-
type="radio"
|
|
47
|
-
name="${this.name}"
|
|
48
|
-
value="${this.value}"
|
|
49
|
-
.checked=${this.checked}
|
|
50
|
-
.disabled=${this.disabled}
|
|
51
|
-
@change=${this.onChange}
|
|
52
|
-
>
|
|
53
|
-
</div>
|
|
54
|
-
<label for="radio-button" @click=${(e) => {
|
|
55
|
-
var _a;
|
|
56
|
-
e.stopPropagation();
|
|
57
|
-
e.preventDefault();
|
|
58
|
-
(_a = this.input) === null || _a === void 0 ? void 0 : _a.click();
|
|
59
|
-
// This should be the normal behaviour, but chrome have an issue with click transmission in shadowRoot
|
|
60
|
-
// https://issues.chromium.org/issues/325161644
|
|
61
|
-
}}>
|
|
62
|
-
<ft-typography variant="body2">
|
|
63
|
-
<slot></slot>
|
|
64
|
-
</ft-typography>
|
|
65
|
-
</label>
|
|
66
|
-
</div>
|
|
67
|
-
`;
|
|
68
|
-
}
|
|
69
|
-
update(changedProperties) {
|
|
70
|
-
super.update(changedProperties);
|
|
71
|
-
if (changedProperties.has("checked")) {
|
|
72
|
-
this.ariaChecked = this.checked ? "true" : "false";
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
onChange(event) {
|
|
76
|
-
event.stopPropagation();
|
|
77
|
-
this.checked = event.target.checked;
|
|
78
|
-
this.dispatchEvent(new FtRadioChangeEvent(this.value, this.checked));
|
|
79
|
-
}
|
|
80
|
-
contentAvailableCallback(props) {
|
|
81
|
-
var _a;
|
|
82
|
-
super.contentAvailableCallback(props);
|
|
83
|
-
(_a = this.ripple) === null || _a === void 0 ? void 0 : _a.setupFor(this.container);
|
|
84
|
-
}
|
|
85
|
-
select() {
|
|
86
|
-
this.checked = true;
|
|
87
|
-
this.dispatchEvent(new FtRadioChangeEvent(this.value, this.checked));
|
|
88
|
-
}
|
|
89
|
-
setInputTabIndex(index) {
|
|
90
|
-
if (this.input) {
|
|
91
|
-
this.input.tabIndex = index;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
focus() {
|
|
95
|
-
var _a;
|
|
96
|
-
(_a = this.input) === null || _a === void 0 ? void 0 : _a.focus();
|
|
97
|
-
setTimeout(() => {
|
|
98
|
-
var _a;
|
|
99
|
-
(_a = this.ripple) === null || _a === void 0 ? void 0 : _a.forceFocusUpdate();
|
|
100
|
-
}, 0);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
FtRadio.elementDefinitions = {
|
|
104
|
-
"ft-ripple": FtRipple,
|
|
105
|
-
"ft-typography": FtTypography
|
|
106
|
-
};
|
|
107
|
-
FtRadio.styles = styles;
|
|
108
|
-
__decorate([
|
|
109
|
-
property()
|
|
110
|
-
], FtRadio.prototype, "value", void 0);
|
|
111
|
-
__decorate([
|
|
112
|
-
property()
|
|
113
|
-
], FtRadio.prototype, "name", void 0);
|
|
114
|
-
__decorate([
|
|
115
|
-
property({ type: Boolean, reflect: true })
|
|
116
|
-
], FtRadio.prototype, "checked", void 0);
|
|
117
|
-
__decorate([
|
|
118
|
-
property({ attribute: "aria-checked", reflect: true })
|
|
119
|
-
], FtRadio.prototype, "ariaChecked", void 0);
|
|
120
|
-
__decorate([
|
|
121
|
-
property({ type: Boolean })
|
|
122
|
-
], FtRadio.prototype, "disabled", void 0);
|
|
123
|
-
__decorate([
|
|
124
|
-
property({ reflect: true, attribute: "role" })
|
|
125
|
-
], FtRadio.prototype, "role", void 0);
|
|
126
|
-
__decorate([
|
|
127
|
-
query(".ft-radio")
|
|
128
|
-
], FtRadio.prototype, "container", void 0);
|
|
129
|
-
__decorate([
|
|
130
|
-
query("ft-ripple")
|
|
131
|
-
], FtRadio.prototype, "ripple", void 0);
|
|
132
|
-
__decorate([
|
|
133
|
-
query("input")
|
|
134
|
-
], FtRadio.prototype, "input", void 0);
|
|
10
|
+
FtRadio.styles = classicStyles;
|
|
135
11
|
export { FtRadio };
|