Skip to content

Commit 1ed4469

Browse files
committed
Merge remote-tracking branch 'origin/v1/contrib' into release/1.2.0
2 parents 7472484 + e11c8c1 commit 1ed4469

File tree

3 files changed

+98
-51
lines changed

3 files changed

+98
-51
lines changed

packages/uui-radio/lib/uui-radio-group.element.ts

+61-51
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,7 @@ export class UUIRadioGroupElement extends FormControlMixin(LitElement) {
5959
if (newValue === null || newValue === '') {
6060
this._makeFirstEnabledFocusable();
6161
}
62-
this._radioElements.forEach((el, index) => {
63-
if (el.value === newValue) {
64-
el.checked = true;
65-
this._selected = index;
66-
} else {
67-
el.checked = false;
68-
}
69-
});
62+
this._updateRadioElementsCheckedState(newValue);
7063
}
7164

7265
private _selected: number | null = null;
@@ -75,6 +68,16 @@ export class UUIRadioGroupElement extends FormControlMixin(LitElement) {
7568
super();
7669
this.addEventListener('keydown', this._onKeydown);
7770
this.addEventListener('keypress', this._onKeypress);
71+
72+
// Wait for the radio elements to be added to the dom before updating the checked state.
73+
this.updateComplete.then(() => {
74+
this._updateRadioElementsCheckedState(this.value);
75+
});
76+
}
77+
78+
connectedCallback() {
79+
super.connectedCallback();
80+
if (!this.hasAttribute('role')) this.setAttribute('role', 'radiogroup');
7881
}
7982

8083
/**
@@ -102,16 +105,24 @@ export class UUIRadioGroupElement extends FormControlMixin(LitElement) {
102105
return undefined;
103106
}
104107

105-
connectedCallback() {
106-
super.connectedCallback();
107-
if (!this.hasAttribute('role')) this.setAttribute('role', 'radiogroup');
108-
}
109-
110-
private _radioElements!: UUIRadioElement[];
108+
private _radioElements: UUIRadioElement[] = [];
111109
private _setNameOnRadios(name: string) {
112110
this._radioElements?.forEach(el => (el.name = name));
113111
}
114112

113+
private _updateRadioElementsCheckedState(
114+
newValue: FormData | FormDataEntryValue
115+
) {
116+
this._radioElements.forEach((el, index) => {
117+
if (el.value === newValue) {
118+
el.checked = true;
119+
this._selected = index;
120+
} else {
121+
el.checked = false;
122+
}
123+
});
124+
}
125+
115126
private _setDisableOnRadios(value: boolean) {
116127
this._radioElements?.forEach(el => (el.disabled = value));
117128
}
@@ -134,52 +145,51 @@ export class UUIRadioGroupElement extends FormControlMixin(LitElement) {
134145
.assignedElements({ flatten: true })
135146
.filter(el => el instanceof UUIRadioElement) as UUIRadioElement[];
136147

137-
if (this._radioElements.length > 0) {
138-
this._radioElements.forEach(el => {
139-
el.addEventListener(
140-
UUIRadioEvent.CHANGE,
141-
// @ts-ignore TODO: fix typescript error
142-
this._handleSelectOnClick as EventHandlerNonNull
143-
);
144-
el.addEventListener('blur', this._onChildBlur);
145-
});
148+
// Only continue if there are radio elements
149+
if (this._radioElements.length === 0) return;
146150

147-
this._setNameOnRadios(this.name);
148-
if (this.disabled) {
149-
this._setDisableOnRadios(true);
150-
}
151+
this._radioElements.forEach(el => {
152+
el.addEventListener(
153+
UUIRadioEvent.CHANGE,
154+
// @ts-ignore TODO: fix typescript error
155+
this._handleSelectOnClick as EventHandlerNonNull
156+
);
157+
el.addEventListener('blur', this._onChildBlur);
158+
});
151159

152-
const checkedRadios = this._radioElements.filter(
153-
el => el.checked === true
160+
this._setNameOnRadios(this.name);
161+
if (this.disabled) {
162+
this._setDisableOnRadios(true);
163+
}
164+
165+
const checkedRadios = this._radioElements.filter(el => el.checked === true);
166+
167+
if (checkedRadios.length > 1) {
168+
this._radioElements.forEach(el => {
169+
el.checked = false;
170+
});
171+
this.value = '';
172+
console.error(
173+
'There can only be one checked radio among the <' +
174+
this.nodeName +
175+
'> children',
176+
this
154177
);
178+
}
155179

156-
if (checkedRadios.length > 1) {
180+
if (checkedRadios.length === 1) {
181+
this.value = checkedRadios[0].value;
182+
this._selected = this._radioElements.indexOf(checkedRadios[0]);
183+
if (checkedRadios[0].disabled === false) {
157184
this._radioElements.forEach(el => {
158-
el.checked = false;
185+
el.makeUnfocusable();
159186
});
160-
this.value = '';
161-
console.error(
162-
'There can only be one checked radio among the <' +
163-
this.nodeName +
164-
'> children',
165-
this
166-
);
167-
}
168-
169-
if (checkedRadios.length === 1) {
170-
this.value = checkedRadios[0].value;
171-
this._selected = this._radioElements.indexOf(checkedRadios[0]);
172-
if (checkedRadios[0].disabled === false) {
173-
this._radioElements.forEach(el => {
174-
el.makeUnfocusable();
175-
});
176-
checkedRadios[0].makeFocusable();
177-
} else {
178-
this._makeFirstEnabledFocusable();
179-
}
187+
checkedRadios[0].makeFocusable();
180188
} else {
181189
this._makeFirstEnabledFocusable();
182190
}
191+
} else {
192+
this._makeFirstEnabledFocusable();
183193
}
184194
}
185195

packages/uui-radio/lib/uui-radio-group.test.ts

+22
Original file line numberDiff line numberDiff line change
@@ -252,3 +252,25 @@ describe('UuiRadioGroup when one radio child radio is checked', () => {
252252
expect(formData.get(`${element.name}`)).to.be.equal('Value 2');
253253
});
254254
});
255+
256+
describe('UuiRadioGroup with start value', () => {
257+
let radioGroup: UUIRadioGroupElement;
258+
let radios: Array<UUIRadioElement>;
259+
beforeEach(async () => {
260+
radioGroup = await fixture(
261+
html` <uui-radio-group value="2">
262+
<uui-radio value="1">one</uui-radio>
263+
<uui-radio value="2">two</uui-radio>
264+
<uui-radio value="3">three</uui-radio>
265+
<uui-radio value="4">four</uui-radio>
266+
</uui-radio-group>`
267+
);
268+
radios = Array.from(radioGroup.querySelectorAll('uui-radio'));
269+
});
270+
it('propagates the start value to the correct child radio', async () => {
271+
expect(radios[0]).to.not.have.attribute('checked');
272+
expect(radios[1]).to.have.attribute('checked');
273+
expect(radios[2]).to.not.have.attribute('checked');
274+
expect(radios[3]).to.not.have.attribute('checked');
275+
});
276+
});

packages/uui-radio/lib/uui-radio.story.ts

+15
Original file line numberDiff line numberDiff line change
@@ -181,3 +181,18 @@ export const DisabledGroup: Story = props => html`
181181
DisabledGroup.args = {
182182
disabled: true,
183183
};
184+
185+
export const GroupWithStartValue: Story = props => html`
186+
<uui-radio-group value=${props.value}>
187+
<uui-radio value="1">one</uui-radio>
188+
<uui-radio value="2">two</uui-radio>
189+
<uui-radio value="3">three</uui-radio>
190+
<uui-radio value="4">four</uui-radio>
191+
</uui-radio-group>
192+
`;
193+
GroupWithStartValue.args = {
194+
value: '3',
195+
};
196+
GroupWithStartValue.parameters = {
197+
controls: { exclude: ['label', 'checked', 'disabled', 'name'] },
198+
};

0 commit comments

Comments
 (0)