fix(radio): radio with modern syntax is keyboard navigable (#27530)

Issue number: resolves #27268 

---------

<!-- Please do not submit updates to dependencies unless it fixes an
issue. -->

<!-- Please try to limit your pull request to one type (bugfix, feature,
etc). Submit multiple pull requests if needed. -->

## What is the current behavior?
<!-- Please describe the current behavior that you are modifying. -->

When tabbing on a radio group (modern syntax), it focuses on the next
radio option inside the radio group. It replicates the behavior of the
up/down keys.

## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->

- When tabbing on a radio group (modern syntax), it focuses on the next
radio option of the next radio group.

A spike ticket has been created to further investigate web accessibility
and browser compatibility.

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

<!-- If this introduces a breaking change, please describe the impact
and migration path for existing applications below. -->


## Other information

<!-- Any other information that is important to this PR such as
screenshots of how the component looks before and after the change. -->

N/A
This commit is contained in:
Maria Hutt
2023-05-31 13:11:30 -07:00
committed by GitHub
parent 7871210e9e
commit d87e692c6c
2 changed files with 20 additions and 5 deletions

View File

@ -135,7 +135,8 @@ export class Radio implements ComponentInterface {
ev.stopPropagation(); ev.stopPropagation();
ev.preventDefault(); ev.preventDefault();
this.el.focus(); const element = this.legacyFormController.hasLegacyControl() ? this.el : this.nativeInput;
element.focus();
} }
/** @internal */ /** @internal */
@ -231,7 +232,18 @@ export class Radio implements ComponentInterface {
} }
private renderRadio() { private renderRadio() {
const { checked, disabled, inputId, color, el, justify, labelPlacement, inheritedAttributes, hasLabel } = this; const {
checked,
disabled,
inputId,
color,
el,
justify,
labelPlacement,
inheritedAttributes,
hasLabel,
buttonTabindex,
} = this;
const mode = getIonMode(this); const mode = getIonMode(this);
const inItem = hostContext('ion-item', el); const inItem = hostContext('ion-item', el);
@ -260,6 +272,7 @@ export class Radio implements ComponentInterface {
checked={checked} checked={checked}
disabled={disabled} disabled={disabled}
id={inputId} id={inputId}
tabindex={buttonTabindex}
ref={(nativeEl) => (this.nativeInput = nativeEl as HTMLInputElement)} ref={(nativeEl) => (this.nativeInput = nativeEl as HTMLInputElement)}
{...inheritedAttributes} {...inheritedAttributes}
/> />

View File

@ -15,9 +15,11 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
}); });
}); });
// TODO: FW-4155 - Enable tests once tab behavior is fixed for modern syntax. test.describe(title('radio: keyboard navigation'), () => {
test.describe.skip(title('radio: keyboard navigation'), () => { test.beforeEach(async ({ page, skip }) => {
test.beforeEach(async ({ page }) => { // TODO (FW-2979)
skip.browser('webkit', 'Safari 16 only allows text fields and pop-up menus to be focused.');
await page.setContent( await page.setContent(
` `
<ion-app> <ion-app>