-
-
Notifications
You must be signed in to change notification settings - Fork 835
Expand file tree
/
Copy pathradio-group-cmp.tsx
More file actions
113 lines (101 loc) · 3.41 KB
/
radio-group-cmp.tsx
File metadata and controls
113 lines (101 loc) · 3.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import { Component, h, ReactiveControllerHost, State, Element, Event, EventEmitter } from '@stencil/core';
import { ValidationController } from './validation-controller.js';
import { FocusController } from './focus-controller.js';
@Component({
tag: 'composition-radio-group',
})
export class RadioGroupCmp extends ReactiveControllerHost {
@Element() el!: HTMLElement;
@State() value: string | undefined = undefined;
@State() helperText: string = 'Select an option';
@Event() valueChange!: EventEmitter<string>;
// Controllers via composition
private validation = new ValidationController(this);
private focusController = new FocusController(this);
private inputId = `radio-group-${Math.random().toString(36).substr(2, 9)}`;
private helperTextId = `${this.inputId}-helper-text`;
private errorTextId = `${this.inputId}-error-text`;
componentWillLoad() {
super.componentWillLoad(); // Call base class to trigger controllers
// Set up validation callback
this.validation.setValidationCallback((val: string | undefined) => {
if (!val) {
return 'Please select an option';
}
return undefined;
});
}
componentDidLoad() {
super.componentDidLoad(); // Call base class to trigger controllers
}
disconnectedCallback() {
super.disconnectedCallback(); // Call base class to trigger controllers
}
private handleChange = (e: Event) => {
const radio = e.target as HTMLInputElement;
if (radio.checked) {
this.value = radio.value;
this.valueChange.emit(this.value);
this.validation.validate(this.value);
}
};
private handleFocus = () => {
this.focusController.handleFocus();
};
private handleBlur = () => {
this.focusController.handleBlur();
this.validation.handleBlur(this.value);
};
render() {
const focusState = this.focusController.getFocusState();
const validationData = this.validation.getValidationMessageData(this.helperTextId, this.errorTextId);
return (
<div class="radio-group-container">
<label>Select Option</label>
<div class="radio-group" tabindex="0" onFocus={this.handleFocus} onBlur={this.handleBlur}>
<label>
<input
type="radio"
name={this.inputId}
value="option1"
checked={this.value === 'option1'}
onChange={this.handleChange}
/>
Option 1
</label>
<label>
<input
type="radio"
name={this.inputId}
value="option2"
checked={this.value === 'option2'}
onChange={this.handleChange}
/>
Option 2
</label>
<label>
<input
type="radio"
name={this.inputId}
value="option3"
checked={this.value === 'option3'}
onChange={this.handleChange}
/>
Option 3
</label>
</div>
{validationData.hasError && (
<div class="validation-message">
<div id={validationData.errorTextId} class="error-text">
{validationData.errorMessage}
</div>
</div>
)}
<div class="focus-info">
Focused: {focusState.isFocused ? 'Yes' : 'No'} | Focus Count: {focusState.focusCount} | Blur Count:{' '}
{focusState.blurCount}
</div>
</div>
);
}
}