fix(radio): updates the tabindex when a radio is added or removed (#30976)

Issue number: resolves internal

---------

## What is the current behavior?
When radio buttons are added after the radio group has already been
initialised (e.g., as a result of a fetch), the `tabindex` of the radio
buttons is not updated.

## What is the new behavior?
When a radio button is added or removed, the radio group updates the
`tabindex` of its radio buttons in accordance with the existing logic.

## Does this introduce a breaking change?

- [ ] Yes
- [ ] No

## Other information

[Current Behavior
Example](https://stackblitz.com/edit/mjr76e54?file=src%2FApp.tsx,src%2Fmain.tsx)
This commit is contained in:
David Lourenço
2026-03-02 09:47:53 +00:00
committed by GitHub
parent 5cc8adb1d5
commit 55c506dbd6
3 changed files with 13 additions and 1 deletions

View File

@@ -3098,6 +3098,7 @@ export namespace Components {
* The theme determines the visual appearance of the component.
*/
"theme"?: "ios" | "md" | "ionic";
"updateRadiosTabindex": () => Promise<void>;
/**
* the value of the radio group.
*/

View File

@@ -1,7 +1,7 @@
import type { ComponentInterface, EventEmitter } from '@stencil/core';
import { Build, Component, Element, Event, Host, Listen, Method, Prop, State, Watch, h } from '@stencil/core';
import { checkInvalidState } from '@utils/forms';
import { renderHiddenInput } from '@utils/helpers';
import { debounce, renderHiddenInput } from '@utils/helpers';
import { hostContext } from '@utils/theme';
import { getIonTheme } from '../../global/ionic-global';
@@ -110,6 +110,15 @@ export class RadioGroup implements ComponentInterface {
this.valueChanged(this.value);
}
/** @internal - Recompute which radio has tabindex 0. Call when radios are added/removed. */
@Method()
async updateRadiosTabindex() {
this.scheduleTabindexUpdate();
}
/** Ensures that the tabindex update is debounced and only called once. */
private scheduleTabindexUpdate = debounce(() => this.setRadioTabindex(this.value), 0);
private setRadioTabindex = (value: any | undefined) => {
const radios = this.getRadios();

View File

@@ -151,6 +151,7 @@ export class Radio implements ComponentInterface {
if (radioGroup) {
this.updateState();
addEventListener(radioGroup, 'ionValueChange', this.updateState);
radioGroup.updateRadiosTabindex();
}
}
@@ -158,6 +159,7 @@ export class Radio implements ComponentInterface {
const radioGroup = this.radioGroup;
if (radioGroup) {
removeEventListener(radioGroup, 'ionValueChange', this.updateState);
radioGroup.updateRadiosTabindex();
this.radioGroup = null;
}
}