@fluid-topics/ft-radio 1.1.74 → 1.1.76

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.
@@ -6,14 +6,20 @@ export declare class FtRadioGroup extends FtLitElement implements FtRadioGroupPr
6
6
  static elementDefinitions: {};
7
7
  name: string;
8
8
  role: string;
9
+ tabIndex: number;
9
10
  ariaLabelledBy: string;
10
11
  radioButtons: Array<FtRadio>;
12
+ currentSelectedIndex: number;
11
13
  static styles: import("lit").CSSResult;
12
14
  protected render(): import("lit").TemplateResult<1>;
15
+ connectedCallback(): void;
16
+ disconnectedCallback(): void;
13
17
  private onSlotChange;
14
18
  protected contentAvailableCallback(props: PropertyValues): void;
19
+ private onFocus;
20
+ private onFocusOut;
15
21
  private onChange;
16
22
  private onKeyDown;
17
- private findFtRadio;
18
- private focusCurrentValue;
23
+ private resolveCurrentSelectedIndex;
24
+ private focusCurrentChecked;
19
25
  }
@@ -5,7 +5,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
7
  import { FtLitElement } from "@fluid-topics/ft-wc-utils";
8
- import { property, queryAssignedElements } from "lit/decorators.js";
8
+ import { property, queryAssignedElements, state } from "lit/decorators.js";
9
9
  import { html } from "lit";
10
10
  import { groupStyles } from "./ft-radio-group.styles";
11
11
  class FtRadioGroup extends FtLitElement {
@@ -13,7 +13,19 @@ class FtRadioGroup extends FtLitElement {
13
13
  super(...arguments);
14
14
  this.name = "";
15
15
  this.role = "radiogroup";
16
+ this.tabIndex = 0;
16
17
  this.ariaLabelledBy = "";
18
+ this.currentSelectedIndex = 0;
19
+ this.onFocus = () => {
20
+ this.tabIndex = -1;
21
+ this.focusCurrentChecked();
22
+ };
23
+ this.onFocusOut = (e) => {
24
+ let nextFocusOutsideOfGroup = !this.contains(e.relatedTarget);
25
+ if (nextFocusOutsideOfGroup) {
26
+ this.tabIndex = 0;
27
+ }
28
+ };
17
29
  }
18
30
  render() {
19
31
  return html `
@@ -23,19 +35,29 @@ class FtRadioGroup extends FtLitElement {
23
35
  ></slot>
24
36
  `;
25
37
  }
38
+ connectedCallback() {
39
+ super.connectedCallback();
40
+ this.addEventListener("focus", this.onFocus);
41
+ this.addEventListener("focusout", this.onFocusOut);
42
+ }
43
+ disconnectedCallback() {
44
+ super.disconnectedCallback();
45
+ this.removeEventListener("focus", this.onFocus);
46
+ this.removeEventListener("focusout", this.onFocusOut);
47
+ }
26
48
  onSlotChange() {
27
49
  this.radioButtons.forEach(rb => rb.name = this.name);
28
50
  }
29
51
  contentAvailableCallback(props) {
30
52
  super.contentAvailableCallback(props);
31
- //make the first radio button focusable
32
- this.radioButtons[0].setAttribute("tabindex", "0");
53
+ this.radioButtons.forEach(rb => rb.setInputTabIndex(-1)); // RadioButton is no more selectable alone
54
+ this.resolveCurrentSelectedIndex();
33
55
  }
34
56
  onChange(event) {
35
57
  event.stopPropagation();
36
58
  this.radioButtons.forEach(rb => rb.checked = event.detail.value === rb.value);
37
59
  this.dispatchEvent(new CustomEvent("change", { detail: event.detail.value }));
38
- this.focusCurrentValue();
60
+ this.resolveCurrentSelectedIndex();
39
61
  }
40
62
  onKeyDown(event) {
41
63
  let blockUnwhishedReaction = false;
@@ -43,8 +65,7 @@ class FtRadioGroup extends FtLitElement {
43
65
  case "ArrowUp":
44
66
  case "ArrowLeft": {
45
67
  blockUnwhishedReaction = true;
46
- let searchElement = this.findFtRadio(event);
47
- let indexToFocus = this.radioButtons.indexOf(searchElement) - 1;
68
+ let indexToFocus = this.currentSelectedIndex - 1;
48
69
  this.radioButtons[indexToFocus < 0 ? this.radioButtons.length - 1 : indexToFocus].select();
49
70
  this.radioButtons[indexToFocus < 0 ? this.radioButtons.length - 1 : indexToFocus].focus();
50
71
  break;
@@ -52,14 +73,13 @@ class FtRadioGroup extends FtLitElement {
52
73
  case "ArrowDown":
53
74
  case "ArrowRight": {
54
75
  blockUnwhishedReaction = true;
55
- let indexToFocus = this.radioButtons.indexOf(this.findFtRadio(event)) + 1;
76
+ let indexToFocus = this.currentSelectedIndex + 1;
56
77
  this.radioButtons[indexToFocus > this.radioButtons.length - 1 ? 0 : indexToFocus].select();
57
78
  this.radioButtons[indexToFocus > this.radioButtons.length - 1 ? 0 : indexToFocus].focus();
58
79
  break;
59
80
  }
60
81
  case "Enter": {
61
- let indexToSelect = this.radioButtons.indexOf(this.findFtRadio(event));
62
- this.radioButtons[indexToSelect].select();
82
+ this.radioButtons[this.currentSelectedIndex].select();
63
83
  }
64
84
  }
65
85
  if (blockUnwhishedReaction) {
@@ -67,11 +87,18 @@ class FtRadioGroup extends FtLitElement {
67
87
  event.preventDefault();
68
88
  }
69
89
  }
70
- findFtRadio(event) {
71
- return event.composedPath().find(element => element.tagName === "FT-RADIO");
90
+ resolveCurrentSelectedIndex() {
91
+ let checkedButtonIndex = this.radioButtons.findIndex(rb => rb.checked);
92
+ if (checkedButtonIndex == -1) {
93
+ this.currentSelectedIndex = 0;
94
+ this.radioButtons[0].select();
95
+ }
96
+ else {
97
+ this.currentSelectedIndex = checkedButtonIndex;
98
+ }
72
99
  }
73
- focusCurrentValue() {
74
- setTimeout(() => { var _a; return (_a = this.radioButtons.find(rb => rb.checked)) === null || _a === void 0 ? void 0 : _a.focus(); }, 10);
100
+ focusCurrentChecked() {
101
+ this.radioButtons[this.currentSelectedIndex].focus();
75
102
  }
76
103
  }
77
104
  FtRadioGroup.elementDefinitions = {};
@@ -82,10 +109,16 @@ __decorate([
82
109
  __decorate([
83
110
  property({ reflect: true, attribute: "role" })
84
111
  ], FtRadioGroup.prototype, "role", void 0);
112
+ __decorate([
113
+ property({ reflect: true })
114
+ ], FtRadioGroup.prototype, "tabIndex", void 0);
85
115
  __decorate([
86
116
  property({ reflect: true, attribute: "aria-labelledby" })
87
117
  ], FtRadioGroup.prototype, "ariaLabelledBy", void 0);
88
118
  __decorate([
89
119
  queryAssignedElements()
90
120
  ], FtRadioGroup.prototype, "radioButtons", void 0);
121
+ __decorate([
122
+ state()
123
+ ], FtRadioGroup.prototype, "currentSelectedIndex", void 0);
91
124
  export { FtRadioGroup };
@@ -3,6 +3,6 @@ export const FtRadioGroupCssVariables = {};
3
3
  // language=CSS
4
4
  export const groupStyles = css `
5
5
  :host {
6
- display: contents;
6
+ display: block;
7
7
  }
8
8
  `;
@@ -13,8 +13,8 @@ export declare class FtRadio extends FtLitElement implements FtRadioProperties {
13
13
  value: string;
14
14
  name: string;
15
15
  checked: boolean;
16
+ ariaChecked: string;
16
17
  disabled: boolean;
17
- tabIndex: number;
18
18
  role: string;
19
19
  private container?;
20
20
  private ripple?;
@@ -23,7 +23,7 @@ export declare class FtRadio extends FtLitElement implements FtRadioProperties {
23
23
  protected update(changedProperties: PropertyValues): void;
24
24
  private onChange;
25
25
  protected contentAvailableCallback(props: PropertyValues): void;
26
- disconnectedCallback(): void;
27
- private onFocus;
28
26
  select(): void;
27
+ setInputTabIndex(index: number): void;
28
+ focus(): void;
29
29
  }
package/build/ft-radio.js CHANGED
@@ -22,8 +22,8 @@ class FtRadio extends FtLitElement {
22
22
  this.value = "";
23
23
  this.name = "";
24
24
  this.checked = false;
25
+ this.ariaChecked = "false";
25
26
  this.disabled = false;
26
- this.tabIndex = -1;
27
27
  this.role = "radio";
28
28
  }
29
29
  render() {
@@ -61,15 +61,8 @@ class FtRadio extends FtLitElement {
61
61
  }
62
62
  update(changedProperties) {
63
63
  super.update(changedProperties);
64
- if (changedProperties.has("checked") && !changedProperties.has("aria-checked")) {
65
- if (this.checked) {
66
- this.setAttribute("aria-checked", "true");
67
- this.tabIndex = 0;
68
- }
69
- else {
70
- this.setAttribute("aria-checked", "false");
71
- this.tabIndex = -1;
72
- }
64
+ if (changedProperties.has("checked")) {
65
+ this.ariaChecked = this.checked ? "true" : "false";
73
66
  }
74
67
  }
75
68
  onChange(event) {
@@ -81,19 +74,20 @@ class FtRadio extends FtLitElement {
81
74
  var _a;
82
75
  super.contentAvailableCallback(props);
83
76
  (_a = this.ripple) === null || _a === void 0 ? void 0 : _a.setupFor(this.container);
84
- this.addEventListener("focus", this.onFocus);
85
- }
86
- disconnectedCallback() {
87
- this.removeEventListener("focus", this.onFocus);
88
- super.disconnectedCallback();
89
- }
90
- onFocus(e) {
91
- this.dispatchEvent(new FtRadioChangeEvent(this.name, this.checked));
92
77
  }
93
78
  select() {
94
79
  this.checked = true;
95
80
  this.dispatchEvent(new FtRadioChangeEvent(this.value, this.checked));
96
81
  }
82
+ setInputTabIndex(index) {
83
+ if (this.input) {
84
+ this.input.tabIndex = index;
85
+ }
86
+ }
87
+ focus() {
88
+ var _a;
89
+ (_a = this.input) === null || _a === void 0 ? void 0 : _a.focus();
90
+ }
97
91
  }
98
92
  FtRadio.elementDefinitions = {
99
93
  "ft-ripple": FtRipple,
@@ -109,12 +103,12 @@ __decorate([
109
103
  __decorate([
110
104
  property({ type: Boolean, reflect: true })
111
105
  ], FtRadio.prototype, "checked", void 0);
106
+ __decorate([
107
+ property({ attribute: "aria-checked", reflect: true })
108
+ ], FtRadio.prototype, "ariaChecked", void 0);
112
109
  __decorate([
113
110
  property({ type: Boolean })
114
111
  ], FtRadio.prototype, "disabled", void 0);
115
- __decorate([
116
- property({ reflect: true })
117
- ], FtRadio.prototype, "tabIndex", void 0);
118
112
  __decorate([
119
113
  property({ reflect: true, attribute: "role" })
120
114
  ], FtRadio.prototype, "role", void 0);