Skip to content

Commit b8f428f

Browse files
- guarantee focusVisibleElement is called on all interfaces;
- change test page so all select have scroll;
1 parent cd5c27a commit b8f428f

File tree

2 files changed

+194
-48
lines changed

2 files changed

+194
-48
lines changed

core/src/components/select/select.tsx

Lines changed: 44 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -319,58 +319,54 @@ export class Select implements ComponentInterface {
319319

320320
await overlay.present();
321321

322-
// focus selected option for popovers and modals
323-
if (this.interface === 'popover' || this.interface === 'modal') {
324-
const indexOfSelected = this.childOpts.findIndex((o) => o.value === this.value);
325-
326-
if (indexOfSelected > -1) {
327-
const selectedItem = overlay.querySelector<HTMLElement>(
328-
`.select-interface-option:nth-child(${indexOfSelected + 1})`
329-
);
330-
331-
if (selectedItem) {
332-
/**
333-
* Browsers such as Firefox do not
334-
* correctly delegate focus when manually
335-
* focusing an element with delegatesFocus.
336-
* We work around this by manually focusing
337-
* the interactive element.
338-
* ion-radio and ion-checkbox are the only
339-
* elements that ion-select-popover uses, so
340-
* we only need to worry about those two components
341-
* when focusing.
342-
*/
343-
const interactiveEl = selectedItem.querySelector<HTMLElement>('ion-radio, ion-checkbox') as
344-
| HTMLIonRadioElement
345-
| HTMLIonCheckboxElement
346-
| null;
347-
if (interactiveEl) {
348-
// Needs to be called before `focusVisibleElement` to prevent issue with focus event bubbling
349-
// and removing `ion-focused` style
350-
interactiveEl.setFocus();
351-
}
322+
const indexOfSelected = this.childOpts.findIndex((o) => o.value === this.value);
323+
if (indexOfSelected > -1) {
324+
const selectedItem = overlay.querySelector<HTMLElement>(
325+
`.select-interface-option:nth-child(${indexOfSelected + 1})`
326+
);
352327

353-
focusVisibleElement(selectedItem);
354-
}
355-
} else {
328+
if (selectedItem) {
356329
/**
357-
* If no value is set then focus the first enabled option.
330+
* Browsers such as Firefox do not
331+
* correctly delegate focus when manually
332+
* focusing an element with delegatesFocus.
333+
* We work around this by manually focusing
334+
* the interactive element.
335+
* ion-radio and ion-checkbox are the only
336+
* elements that ion-select-popover uses, so
337+
* we only need to worry about those two components
338+
* when focusing.
358339
*/
359-
const firstEnabledOption = overlay.querySelector<HTMLElement>(
360-
'ion-radio:not(.radio-disabled), ion-checkbox:not(.checkbox-disabled)'
361-
) as HTMLIonRadioElement | HTMLIonCheckboxElement | null;
362-
363-
if (firstEnabledOption) {
364-
/**
365-
* Focus the option for the same reason as we do above.
366-
*
367-
* Needs to be called before `focusVisibleElement` to prevent issue with focus event bubbling
368-
* and removing `ion-focused` style
369-
*/
370-
firstEnabledOption.setFocus();
371-
372-
focusVisibleElement(firstEnabledOption.closest('ion-item')!);
340+
const interactiveEl = selectedItem.querySelector<HTMLElement>('ion-radio, ion-checkbox') as
341+
| HTMLIonRadioElement
342+
| HTMLIonCheckboxElement
343+
| null;
344+
if (interactiveEl) {
345+
// Needs to be called before `focusVisibleElement` to prevent issue with focus event bubbling
346+
// and removing `ion-focused` style
347+
interactiveEl.setFocus();
373348
}
349+
350+
focusVisibleElement(selectedItem);
351+
}
352+
} else {
353+
/**
354+
* If no value is set then focus the first enabled option.
355+
*/
356+
const firstEnabledOption = overlay.querySelector<HTMLElement>(
357+
'ion-radio:not(.radio-disabled), ion-checkbox:not(.checkbox-disabled)'
358+
) as HTMLIonRadioElement | HTMLIonCheckboxElement | null;
359+
360+
if (firstEnabledOption) {
361+
/**
362+
* Focus the option for the same reason as we do above.
363+
*
364+
* Needs to be called before `focusVisibleElement` to prevent issue with focus event bubbling
365+
* and removing `ion-focused` style
366+
*/
367+
firstEnabledOption.setFocus();
368+
369+
focusVisibleElement(firstEnabledOption.closest('ion-item')!);
374370
}
375371
}
376372

core/src/components/select/test/basic/index.html

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,156 @@
6161
</ion-item>
6262
</ion-list>
6363

64+
<ion-list>
65+
<ion-list-header>
66+
<ion-label>Single Value - Overflowing Options</ion-label>
67+
</ion-list-header>
68+
69+
<ion-item>
70+
<ion-select id="alert-select2" label="Alert" placeholder="Select one" interface="alert" value="dragonfruit">
71+
<ion-select-option value="apples">Apples</ion-select-option>
72+
<ion-select-option value="oranges">Oranges</ion-select-option>
73+
<ion-select-option value="pears">Pears</ion-select-option>
74+
<ion-select-option value="pineaple">Pineaple</ion-select-option>
75+
<ion-select-option value="peach">Peach</ion-select-option>
76+
<ion-select-option value="melon">Melon</ion-select-option>
77+
<ion-select-option value="watermelon">Watermelon</ion-select-option>
78+
<ion-select-option value="strawberry">Strawberry</ion-select-option>
79+
<ion-select-option value="grapes">Grapes</ion-select-option>
80+
<ion-select-option value="banana">Banana</ion-select-option>
81+
<ion-select-option value="mango">Mango</ion-select-option>
82+
<ion-select-option value="dragonfruit">Dragonfruit</ion-select-option>
83+
<ion-select-option value="kiwi">Kiwi</ion-select-option>
84+
<ion-select-option value="blackberry">Blackberry</ion-select-option>
85+
<ion-select-option value="blueberry">Blueberry</ion-select-option>
86+
</ion-select>
87+
</ion-item>
88+
89+
<ion-item>
90+
<ion-select label="Popover" placeholder="Select one" interface="popover" value="2watermelon">
91+
<ion-select-option value="apples">Apples</ion-select-option>
92+
<ion-select-option value="oranges">Oranges</ion-select-option>
93+
<ion-select-option value="pears">Pears</ion-select-option>
94+
<ion-select-option value="pineaple">Pineaple</ion-select-option>
95+
<ion-select-option value="peach">Peach</ion-select-option>
96+
<ion-select-option value="melon">Melon</ion-select-option>
97+
<ion-select-option value="watermelon">Watermelon</ion-select-option>
98+
<ion-select-option value="strawberry">Strawberry</ion-select-option>
99+
<ion-select-option value="grapes">Grapes</ion-select-option>
100+
<ion-select-option value="banana">Banana</ion-select-option>
101+
<ion-select-option value="mango">Mango</ion-select-option>
102+
<ion-select-option value="dragonfruit">Dragonfruit</ion-select-option>
103+
<ion-select-option value="kiwi">Kiwi</ion-select-option>
104+
<ion-select-option value="blackberry">Blackberry</ion-select-option>
105+
<ion-select-option value="blueberry">Blueberry</ion-select-option>
106+
107+
<ion-select-option value="1apples">Apples</ion-select-option>
108+
<ion-select-option value="1oranges">Oranges</ion-select-option>
109+
<ion-select-option value="1pears">Pears</ion-select-option>
110+
<ion-select-option value="1pineaple">Pineaple</ion-select-option>
111+
<ion-select-option value="1peach">Peach</ion-select-option>
112+
<ion-select-option value="1melon">Melon</ion-select-option>
113+
<ion-select-option value="1watermelon">Watermelon</ion-select-option>
114+
<ion-select-option value="1strawberry">Strawberry</ion-select-option>
115+
<ion-select-option value="1grapes">Grapes</ion-select-option>
116+
<ion-select-option value="1banana">Banana</ion-select-option>
117+
<ion-select-option value="1mango">Mango</ion-select-option>
118+
<ion-select-option value="1dragonfruit">Dragonfruit</ion-select-option>
119+
<ion-select-option value="1kiwi">Kiwi</ion-select-option>
120+
<ion-select-option value="1blackberry">Blackberry</ion-select-option>
121+
<ion-select-option value="1blueberry">Blueberry</ion-select-option>
122+
123+
<ion-select-option value="2apples">Apples</ion-select-option>
124+
<ion-select-option value="2oranges">Oranges</ion-select-option>
125+
<ion-select-option value="2pears">Pears</ion-select-option>
126+
<ion-select-option value="2pineaple">Pineaple</ion-select-option>
127+
<ion-select-option value="2peach">Peach</ion-select-option>
128+
<ion-select-option value="2melon">Melon</ion-select-option>
129+
<ion-select-option value="2watermelon">Watermelon</ion-select-option>
130+
<ion-select-option value="2strawberry">Strawberry</ion-select-option>
131+
<ion-select-option value="2grapes">Grapes</ion-select-option>
132+
<ion-select-option value="2banana">Banana</ion-select-option>
133+
<ion-select-option value="2mango">Mango</ion-select-option>
134+
<ion-select-option value="2dragonfruit">Dragonfruit</ion-select-option>
135+
<ion-select-option value="2kiwi">Kiwi</ion-select-option>
136+
<ion-select-option value="2blackberry">Blackberry</ion-select-option>
137+
<ion-select-option value="2blueberry">Blueberry</ion-select-option>
138+
</ion-select>
139+
</ion-item>
140+
141+
<ion-item>
142+
<ion-select label="Action Sheet" placeholder="Select one" interface="action-sheet" value="2watermelon">
143+
<ion-select-option value="apples">Apples</ion-select-option>
144+
<ion-select-option value="oranges">Oranges</ion-select-option>
145+
<ion-select-option value="pears">Pears</ion-select-option>
146+
<ion-select-option value="pineaple">Pineaple</ion-select-option>
147+
<ion-select-option value="peach">Peach</ion-select-option>
148+
<ion-select-option value="melon">Melon</ion-select-option>
149+
<ion-select-option value="watermelon">Watermelon</ion-select-option>
150+
<ion-select-option value="strawberry">Strawberry</ion-select-option>
151+
<ion-select-option value="grapes">Grapes</ion-select-option>
152+
<ion-select-option value="banana">Banana</ion-select-option>
153+
<ion-select-option value="mango">Mango</ion-select-option>
154+
<ion-select-option value="dragonfruit">Dragonfruit</ion-select-option>
155+
<ion-select-option value="kiwi">Kiwi</ion-select-option>
156+
<ion-select-option value="blackberry">Blackberry</ion-select-option>
157+
<ion-select-option value="blueberry">Blueberry</ion-select-option>
158+
159+
<ion-select-option value="1apples">Apples</ion-select-option>
160+
<ion-select-option value="1oranges">Oranges</ion-select-option>
161+
<ion-select-option value="1pears">Pears</ion-select-option>
162+
<ion-select-option value="1pineaple">Pineaple</ion-select-option>
163+
<ion-select-option value="1peach">Peach</ion-select-option>
164+
<ion-select-option value="1melon">Melon</ion-select-option>
165+
<ion-select-option value="1watermelon">Watermelon</ion-select-option>
166+
<ion-select-option value="1strawberry">Strawberry</ion-select-option>
167+
<ion-select-option value="1grapes">Grapes</ion-select-option>
168+
<ion-select-option value="1banana">Banana</ion-select-option>
169+
<ion-select-option value="1mango">Mango</ion-select-option>
170+
<ion-select-option value="1dragonfruit">Dragonfruit</ion-select-option>
171+
<ion-select-option value="1kiwi">Kiwi</ion-select-option>
172+
<ion-select-option value="1blackberry">Blackberry</ion-select-option>
173+
<ion-select-option value="1blueberry">Blueberry</ion-select-option>
174+
175+
<ion-select-option value="2apples">Apples</ion-select-option>
176+
<ion-select-option value="2oranges">Oranges</ion-select-option>
177+
<ion-select-option value="2pears">Pears</ion-select-option>
178+
<ion-select-option value="2pineaple">Pineaple</ion-select-option>
179+
<ion-select-option value="2peach">Peach</ion-select-option>
180+
<ion-select-option value="2melon">Melon</ion-select-option>
181+
<ion-select-option value="2watermelon">Watermelon</ion-select-option>
182+
<ion-select-option value="2strawberry">Strawberry</ion-select-option>
183+
<ion-select-option value="2grapes">Grapes</ion-select-option>
184+
<ion-select-option value="2banana">Banana</ion-select-option>
185+
<ion-select-option value="2mango">Mango</ion-select-option>
186+
<ion-select-option value="2dragonfruit">Dragonfruit</ion-select-option>
187+
<ion-select-option value="2kiwi">Kiwi</ion-select-option>
188+
<ion-select-option value="2blackberry">Blackberry</ion-select-option>
189+
<ion-select-option value="2blueberry">Blueberry</ion-select-option>
190+
</ion-select>
191+
</ion-item>
192+
193+
<ion-item>
194+
<ion-select label="Modal" placeholder="Select one" interface="modal" value="kiwi">
195+
<ion-select-option value="apples">Apples</ion-select-option>
196+
<ion-select-option value="oranges">Oranges</ion-select-option>
197+
<ion-select-option value="pears">Pears</ion-select-option>
198+
<ion-select-option value="pineaple">Pineaple</ion-select-option>
199+
<ion-select-option value="peach">Peach</ion-select-option>
200+
<ion-select-option value="melon">Melon</ion-select-option>
201+
<ion-select-option value="watermelon">Watermelon</ion-select-option>
202+
<ion-select-option value="strawberry">Strawberry</ion-select-option>
203+
<ion-select-option value="grapes">Grapes</ion-select-option>
204+
<ion-select-option value="banana">Banana</ion-select-option>
205+
<ion-select-option value="mango">Mango</ion-select-option>
206+
<ion-select-option value="dragonfruit">Dragonfruit</ion-select-option>
207+
<ion-select-option value="kiwi">Kiwi</ion-select-option>
208+
<ion-select-option value="blackberry">Blackberry</ion-select-option>
209+
<ion-select-option value="blueberry">Blueberry</ion-select-option>
210+
</ion-select>
211+
</ion-item>
212+
</ion-list>
213+
64214
<ion-list>
65215
<ion-list-header>
66216
<ion-label>Multiple Value Select</ion-label>

0 commit comments

Comments
 (0)