- guarantee focusVisibleElement is called on all interfaces;

- change test page so all select have scroll;
This commit is contained in:
João Ferreira
2025-02-19 17:25:42 +00:00
parent 061712318c
commit d98a480e28
2 changed files with 158 additions and 50 deletions

View File

@@ -335,61 +335,57 @@ export class Select implements ComponentInterface {
await overlay.present();
// focus selected option for popovers and modals
if (this.interface === 'popover' || this.interface === 'modal') {
const indexOfSelected = this.childOpts.findIndex((o) => o.value === this.value);
const indexOfSelected = this.childOpts.findIndex((o) => o.value === this.value);
if (indexOfSelected > -1) {
const selectedItem = overlay.querySelector<HTMLElement>(
`.select-interface-option:nth-child(${indexOfSelected + 1})`
);
if (indexOfSelected > -1) {
const selectedItem = overlay.querySelector<HTMLElement>(
`.select-interface-option:nth-child(${indexOfSelected + 1})`
);
if (selectedItem) {
/**
* Browsers such as Firefox do not
* correctly delegate focus when manually
* focusing an element with delegatesFocus.
* We work around this by manually focusing
* the interactive element.
* ion-radio and ion-checkbox are the only
* elements that ion-select-popover uses, so
* we only need to worry about those two components
* when focusing.
*/
const interactiveEl = selectedItem.querySelector<HTMLElement>('ion-radio, ion-checkbox') as
| HTMLIonRadioElement
| HTMLIonCheckboxElement
| null;
if (interactiveEl) {
// Needs to be called before `focusVisibleElement` to prevent issue with focus event bubbling
// and removing `ion-focused` style
interactiveEl.setFocus();
}
focusVisibleElement(selectedItem);
}
} else {
if (selectedItem) {
/**
* If no value is set then focus the first enabled option.
* Browsers such as Firefox do not
* correctly delegate focus when manually
* focusing an element with delegatesFocus.
* We work around this by manually focusing
* the interactive element.
* ion-radio and ion-checkbox are the only
* elements that ion-select-popover uses, so
* we only need to worry about those two components
* when focusing.
*/
const firstEnabledOption = overlay.querySelector<HTMLElement>(
'ion-radio:not(.radio-disabled), ion-checkbox:not(.checkbox-disabled)'
) as HTMLIonRadioElement | HTMLIonCheckboxElement | null;
if (firstEnabledOption) {
/**
* Focus the option for the same reason as we do above.
*
* Needs to be called before `focusVisibleElement` to prevent issue with focus event bubbling
* and removing `ion-focused` style
*/
firstEnabledOption.setFocus();
focusVisibleElement(firstEnabledOption.closest('ion-item')!);
const interactiveEl = selectedItem.querySelector<HTMLElement>('ion-radio, ion-checkbox') as
| HTMLIonRadioElement
| HTMLIonCheckboxElement
| null;
if (interactiveEl) {
// Needs to be called before `focusVisibleElement` to prevent issue with focus event bubbling
// and removing `ion-focused` style
interactiveEl.setFocus();
}
}
}
focusVisibleElement(selectedItem);
}
} else {
/**
* If no value is set then focus the first enabled option.
*/
const firstEnabledOption = overlay.querySelector<HTMLElement>(
'ion-radio:not(.radio-disabled), ion-checkbox:not(.checkbox-disabled)'
) as HTMLIonRadioElement | HTMLIonCheckboxElement | null;
if (firstEnabledOption) {
/**
* Focus the option for the same reason as we do above.
*
* Needs to be called before `focusVisibleElement` to prevent issue with focus event bubbling
* and removing `ion-focused` style
*/
firstEnabledOption.setFocus();
focusVisibleElement(firstEnabledOption.closest('ion-item')!);
}
}
return overlay;
}

View File

@@ -33,6 +33,18 @@
<ion-select-option value="apples">Apples</ion-select-option>
<ion-select-option value="oranges">Oranges</ion-select-option>
<ion-select-option value="pears">Pears</ion-select-option>
<ion-select-option value="pineaple">Pineaple</ion-select-option>
<ion-select-option value="peach">Peach</ion-select-option>
<ion-select-option value="melon">Melon</ion-select-option>
<ion-select-option value="watermelon">Watermelon</ion-select-option>
<ion-select-option value="strawberry">Strawberry</ion-select-option>
<ion-select-option value="grapes">Grapes</ion-select-option>
<ion-select-option value="banana">Banana</ion-select-option>
<ion-select-option value="mango">Mango</ion-select-option>
<ion-select-option value="dragonfruit">Dragonfruit</ion-select-option>
<ion-select-option value="kiwi">Kiwi</ion-select-option>
<ion-select-option value="blackberry">Blackberry</ion-select-option>
<ion-select-option value="blueberry">Blueberry</ion-select-option>
</ion-select>
</ion-item>
@@ -41,6 +53,50 @@
<ion-select-option value="apples">Apples</ion-select-option>
<ion-select-option value="oranges">Oranges</ion-select-option>
<ion-select-option value="pears">Pears</ion-select-option>
<ion-select-option value="pineaple">Pineaple</ion-select-option>
<ion-select-option value="peach">Peach</ion-select-option>
<ion-select-option value="melon">Melon</ion-select-option>
<ion-select-option value="watermelon">Watermelon</ion-select-option>
<ion-select-option value="strawberry">Strawberry</ion-select-option>
<ion-select-option value="grapes">Grapes</ion-select-option>
<ion-select-option value="banana">Banana</ion-select-option>
<ion-select-option value="mango">Mango</ion-select-option>
<ion-select-option value="dragonfruit">Dragonfruit</ion-select-option>
<ion-select-option value="kiwi">Kiwi</ion-select-option>
<ion-select-option value="blackberry">Blackberry</ion-select-option>
<ion-select-option value="blueberry">Blueberry</ion-select-option>
<ion-select-option value="1apples">Apples</ion-select-option>
<ion-select-option value="1oranges">Oranges</ion-select-option>
<ion-select-option value="1pears">Pears</ion-select-option>
<ion-select-option value="1pineaple">Pineaple</ion-select-option>
<ion-select-option value="1peach">Peach</ion-select-option>
<ion-select-option value="1melon">Melon</ion-select-option>
<ion-select-option value="1watermelon">Watermelon</ion-select-option>
<ion-select-option value="1strawberry">Strawberry</ion-select-option>
<ion-select-option value="1grapes">Grapes</ion-select-option>
<ion-select-option value="1banana">Banana</ion-select-option>
<ion-select-option value="1mango">Mango</ion-select-option>
<ion-select-option value="1dragonfruit">Dragonfruit</ion-select-option>
<ion-select-option value="1kiwi">Kiwi</ion-select-option>
<ion-select-option value="1blackberry">Blackberry</ion-select-option>
<ion-select-option value="1blueberry">Blueberry</ion-select-option>
<ion-select-option value="2apples">Apples</ion-select-option>
<ion-select-option value="2oranges">Oranges</ion-select-option>
<ion-select-option value="2pears">Pears</ion-select-option>
<ion-select-option value="2pineaple">Pineaple</ion-select-option>
<ion-select-option value="2peach">Peach</ion-select-option>
<ion-select-option value="2melon">Melon</ion-select-option>
<ion-select-option value="2watermelon">Watermelon</ion-select-option>
<ion-select-option value="2strawberry">Strawberry</ion-select-option>
<ion-select-option value="2grapes">Grapes</ion-select-option>
<ion-select-option value="2banana">Banana</ion-select-option>
<ion-select-option value="2mango">Mango</ion-select-option>
<ion-select-option value="2dragonfruit">Dragonfruit</ion-select-option>
<ion-select-option value="2kiwi">Kiwi</ion-select-option>
<ion-select-option value="2blackberry">Blackberry</ion-select-option>
<ion-select-option value="2blueberry">Blueberry</ion-select-option>
</ion-select>
</ion-item>
@@ -49,6 +105,50 @@
<ion-select-option value="apples">Apples</ion-select-option>
<ion-select-option value="oranges">Oranges</ion-select-option>
<ion-select-option value="pears">Pears</ion-select-option>
<ion-select-option value="pineaple">Pineaple</ion-select-option>
<ion-select-option value="peach">Peach</ion-select-option>
<ion-select-option value="melon">Melon</ion-select-option>
<ion-select-option value="watermelon">Watermelon</ion-select-option>
<ion-select-option value="strawberry">Strawberry</ion-select-option>
<ion-select-option value="grapes">Grapes</ion-select-option>
<ion-select-option value="banana">Banana</ion-select-option>
<ion-select-option value="mango">Mango</ion-select-option>
<ion-select-option value="dragonfruit">Dragonfruit</ion-select-option>
<ion-select-option value="kiwi">Kiwi</ion-select-option>
<ion-select-option value="blackberry">Blackberry</ion-select-option>
<ion-select-option value="blueberry">Blueberry</ion-select-option>
<ion-select-option value="1apples">Apples</ion-select-option>
<ion-select-option value="1oranges">Oranges</ion-select-option>
<ion-select-option value="1pears">Pears</ion-select-option>
<ion-select-option value="1pineaple">Pineaple</ion-select-option>
<ion-select-option value="1peach">Peach</ion-select-option>
<ion-select-option value="1melon">Melon</ion-select-option>
<ion-select-option value="1watermelon">Watermelon</ion-select-option>
<ion-select-option value="1strawberry">Strawberry</ion-select-option>
<ion-select-option value="1grapes">Grapes</ion-select-option>
<ion-select-option value="1banana">Banana</ion-select-option>
<ion-select-option value="1mango">Mango</ion-select-option>
<ion-select-option value="1dragonfruit">Dragonfruit</ion-select-option>
<ion-select-option value="1kiwi">Kiwi</ion-select-option>
<ion-select-option value="1blackberry">Blackberry</ion-select-option>
<ion-select-option value="1blueberry">Blueberry</ion-select-option>
<ion-select-option value="2apples">Apples</ion-select-option>
<ion-select-option value="2oranges">Oranges</ion-select-option>
<ion-select-option value="2pears">Pears</ion-select-option>
<ion-select-option value="2pineaple">Pineaple</ion-select-option>
<ion-select-option value="2peach">Peach</ion-select-option>
<ion-select-option value="2melon">Melon</ion-select-option>
<ion-select-option value="2watermelon">Watermelon</ion-select-option>
<ion-select-option value="2strawberry">Strawberry</ion-select-option>
<ion-select-option value="2grapes">Grapes</ion-select-option>
<ion-select-option value="2banana">Banana</ion-select-option>
<ion-select-option value="2mango">Mango</ion-select-option>
<ion-select-option value="2dragonfruit">Dragonfruit</ion-select-option>
<ion-select-option value="2kiwi">Kiwi</ion-select-option>
<ion-select-option value="2blackberry">Blackberry</ion-select-option>
<ion-select-option value="2blueberry">Blueberry</ion-select-option>
</ion-select>
</ion-item>
@@ -57,6 +157,18 @@
<ion-select-option value="apples">Apples</ion-select-option>
<ion-select-option value="oranges">Oranges</ion-select-option>
<ion-select-option value="pears">Pears</ion-select-option>
<ion-select-option value="pineaple">Pineaple</ion-select-option>
<ion-select-option value="peach">Peach</ion-select-option>
<ion-select-option value="melon">Melon</ion-select-option>
<ion-select-option value="watermelon">Watermelon</ion-select-option>
<ion-select-option value="strawberry">Strawberry</ion-select-option>
<ion-select-option value="grapes">Grapes</ion-select-option>
<ion-select-option value="banana">Banana</ion-select-option>
<ion-select-option value="mango">Mango</ion-select-option>
<ion-select-option value="dragonfruit">Dragonfruit</ion-select-option>
<ion-select-option value="kiwi">Kiwi</ion-select-option>
<ion-select-option value="blackberry">Blackberry</ion-select-option>
<ion-select-option value="blueberry">Blueberry</ion-select-option>
</ion-select>
</ion-item>
</ion-list>