@fluid-topics/ft-radio 1.1.75 → 1.1.77

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,21 @@ 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
+ if (this.tabIndex == 0) {
21
+ this.tabIndex = -1;
22
+ this.focusCurrentChecked();
23
+ }
24
+ };
25
+ this.onFocusOut = (e) => {
26
+ let nextFocusOutsideOfGroup = !this.contains(e.relatedTarget);
27
+ if (nextFocusOutsideOfGroup) {
28
+ this.tabIndex = 0;
29
+ }
30
+ };
17
31
  }
18
32
  render() {
19
33
  return html `
@@ -23,19 +37,29 @@ class FtRadioGroup extends FtLitElement {
23
37
  ></slot>
24
38
  `;
25
39
  }
40
+ connectedCallback() {
41
+ super.connectedCallback();
42
+ this.addEventListener("focus", this.onFocus);
43
+ this.addEventListener("focusout", this.onFocusOut);
44
+ }
45
+ disconnectedCallback() {
46
+ super.disconnectedCallback();
47
+ this.removeEventListener("focus", this.onFocus);
48
+ this.removeEventListener("focusout", this.onFocusOut);
49
+ }
26
50
  onSlotChange() {
27
51
  this.radioButtons.forEach(rb => rb.name = this.name);
28
52
  }
29
53
  contentAvailableCallback(props) {
30
54
  super.contentAvailableCallback(props);
31
- //make the first radio button focusable
32
- this.radioButtons[0].setAttribute("tabindex", "0");
55
+ this.radioButtons.forEach(rb => rb.setInputTabIndex(-1)); // RadioButton is no more selectable alone
56
+ this.resolveCurrentSelectedIndex();
33
57
  }
34
58
  onChange(event) {
35
59
  event.stopPropagation();
36
60
  this.radioButtons.forEach(rb => rb.checked = event.detail.value === rb.value);
37
61
  this.dispatchEvent(new CustomEvent("change", { detail: event.detail.value }));
38
- this.focusCurrentValue();
62
+ this.resolveCurrentSelectedIndex();
39
63
  }
40
64
  onKeyDown(event) {
41
65
  let blockUnwhishedReaction = false;
@@ -43,8 +67,7 @@ class FtRadioGroup extends FtLitElement {
43
67
  case "ArrowUp":
44
68
  case "ArrowLeft": {
45
69
  blockUnwhishedReaction = true;
46
- let searchElement = this.findFtRadio(event);
47
- let indexToFocus = this.radioButtons.indexOf(searchElement) - 1;
70
+ let indexToFocus = this.currentSelectedIndex - 1;
48
71
  this.radioButtons[indexToFocus < 0 ? this.radioButtons.length - 1 : indexToFocus].select();
49
72
  this.radioButtons[indexToFocus < 0 ? this.radioButtons.length - 1 : indexToFocus].focus();
50
73
  break;
@@ -52,14 +75,13 @@ class FtRadioGroup extends FtLitElement {
52
75
  case "ArrowDown":
53
76
  case "ArrowRight": {
54
77
  blockUnwhishedReaction = true;
55
- let indexToFocus = this.radioButtons.indexOf(this.findFtRadio(event)) + 1;
78
+ let indexToFocus = this.currentSelectedIndex + 1;
56
79
  this.radioButtons[indexToFocus > this.radioButtons.length - 1 ? 0 : indexToFocus].select();
57
80
  this.radioButtons[indexToFocus > this.radioButtons.length - 1 ? 0 : indexToFocus].focus();
58
81
  break;
59
82
  }
60
83
  case "Enter": {
61
- let indexToSelect = this.radioButtons.indexOf(this.findFtRadio(event));
62
- this.radioButtons[indexToSelect].select();
84
+ this.radioButtons[this.currentSelectedIndex].select();
63
85
  }
64
86
  }
65
87
  if (blockUnwhishedReaction) {
@@ -67,11 +89,18 @@ class FtRadioGroup extends FtLitElement {
67
89
  event.preventDefault();
68
90
  }
69
91
  }
70
- findFtRadio(event) {
71
- return event.composedPath().find(element => element.tagName === "FT-RADIO");
92
+ resolveCurrentSelectedIndex() {
93
+ let checkedButtonIndex = this.radioButtons.findIndex(rb => rb.checked);
94
+ if (checkedButtonIndex == -1) {
95
+ this.currentSelectedIndex = 0;
96
+ this.radioButtons[0].select();
97
+ }
98
+ else {
99
+ this.currentSelectedIndex = checkedButtonIndex;
100
+ }
72
101
  }
73
- focusCurrentValue() {
74
- setTimeout(() => { var _a; return (_a = this.radioButtons.find(rb => rb.checked)) === null || _a === void 0 ? void 0 : _a.focus(); }, 10);
102
+ focusCurrentChecked() {
103
+ this.radioButtons[this.currentSelectedIndex].focus();
75
104
  }
76
105
  }
77
106
  FtRadioGroup.elementDefinitions = {};
@@ -82,10 +111,16 @@ __decorate([
82
111
  __decorate([
83
112
  property({ reflect: true, attribute: "role" })
84
113
  ], FtRadioGroup.prototype, "role", void 0);
114
+ __decorate([
115
+ property({ reflect: true })
116
+ ], FtRadioGroup.prototype, "tabIndex", void 0);
85
117
  __decorate([
86
118
  property({ reflect: true, attribute: "aria-labelledby" })
87
119
  ], FtRadioGroup.prototype, "ariaLabelledBy", void 0);
88
120
  __decorate([
89
121
  queryAssignedElements()
90
122
  ], FtRadioGroup.prototype, "radioButtons", void 0);
123
+ __decorate([
124
+ state()
125
+ ], FtRadioGroup.prototype, "currentSelectedIndex", void 0);
91
126
  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() {
@@ -51,7 +51,14 @@ class FtRadio extends FtLitElement {
51
51
  @change=${this.onChange}
52
52
  >
53
53
  </div>
54
- <label for="radio-button" @click=${(e) => e.stopPropagation()}>
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
+ }}>
55
62
  <ft-typography variant="body2">
56
63
  <slot></slot>
57
64
  </ft-typography>
@@ -61,15 +68,8 @@ class FtRadio extends FtLitElement {
61
68
  }
62
69
  update(changedProperties) {
63
70
  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
- }
71
+ if (changedProperties.has("checked")) {
72
+ this.ariaChecked = this.checked ? "true" : "false";
73
73
  }
74
74
  }
75
75
  onChange(event) {
@@ -81,19 +81,20 @@ class FtRadio extends FtLitElement {
81
81
  var _a;
82
82
  super.contentAvailableCallback(props);
83
83
  (_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
84
  }
93
85
  select() {
94
86
  this.checked = true;
95
87
  this.dispatchEvent(new FtRadioChangeEvent(this.value, this.checked));
96
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
+ }
97
98
  }
98
99
  FtRadio.elementDefinitions = {
99
100
  "ft-ripple": FtRipple,
@@ -109,12 +110,12 @@ __decorate([
109
110
  __decorate([
110
111
  property({ type: Boolean, reflect: true })
111
112
  ], FtRadio.prototype, "checked", void 0);
113
+ __decorate([
114
+ property({ attribute: "aria-checked", reflect: true })
115
+ ], FtRadio.prototype, "ariaChecked", void 0);
112
116
  __decorate([
113
117
  property({ type: Boolean })
114
118
  ], FtRadio.prototype, "disabled", void 0);
115
- __decorate([
116
- property({ reflect: true })
117
- ], FtRadio.prototype, "tabIndex", void 0);
118
119
  __decorate([
119
120
  property({ reflect: true, attribute: "role" })
120
121
  ], FtRadio.prototype, "role", void 0);