Compare commits

...

4 Commits

Author SHA1 Message Date
João Ferreira
53e378a523 - fix double id; 2025-02-20 15:26:19 +00:00
João Ferreira
555505bc7f - fix lint; 2025-02-20 09:25:37 +00:00
João Ferreira
f467b34091 - reorganize basic test page; 2025-02-19 18:42:05 +00:00
João Ferreira
d98a480e28 - guarantee focusVisibleElement is called on all interfaces;
- change test page so all select have scroll;
2025-02-19 17:25:42 +00:00
2 changed files with 194 additions and 48 deletions

View File

@@ -335,58 +335,54 @@ 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')!);
}
}

View File

@@ -61,6 +61,156 @@
</ion-item>
</ion-list>
<ion-list>
<ion-list-header>
<ion-label>Single Value - Overflowing Options</ion-label>
</ion-list-header>
<ion-item>
<ion-select id="alert-select2" label="Alert" placeholder="Select one" interface="alert" value="dragonfruit">
<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-item>
<ion-select label="Popover" placeholder="Select one" interface="popover" value="2watermelon">
<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>
<ion-item>
<ion-select label="Action Sheet" placeholder="Select one" interface="action-sheet" value="2watermelon">
<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>
<ion-item>
<ion-select label="Modal" placeholder="Select one" interface="modal" value="kiwi">
<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>
<ion-list>
<ion-list-header>
<ion-label>Multiple Value Select</ion-label>