@@ -135,12 +135,63 @@ export class Picker implements ComponentInterface {
135135 * function that has been set in onPointerDown
136136 * so that we enter/exit input mode correctly.
137137 */
138- private onClick = ( ) => {
138+ private onClick = ( ev : PointerEvent ) => {
139139 const { actionOnClick } = this ;
140140 if ( actionOnClick ) {
141141 actionOnClick ( ) ;
142142 this . actionOnClick = undefined ;
143143 }
144+
145+ /**
146+ * In order to avoid a11y issues we must manage focus
147+ * on the picker columns and picker itself.
148+ * This is because once picker is clicked we got an issue/warning because
149+ * picker input is being focused, and once it has tabindex -1 it can't be focused,
150+ * which ends on focusing the picker itself.
151+ * During the process above we fall into issues since there is an element
152+ * with tabindex -1 and aria-hidden='true' that is focused, which is not allowed.
153+ * That said and since onClick is being propagated to the picker itself, we need to
154+ * manage focus on the picker columns and picker itself to avoid the issue.
155+ */
156+ const clickedTarget = ev . target as HTMLElement ;
157+ let elementToFocus : HTMLElement | null = null ;
158+
159+ switch ( clickedTarget . tagName ) {
160+ case 'ION-PICKER' :
161+ /**
162+ * If the user clicked the picker itself
163+ * then we should focus the first picker options
164+ * so that users can scroll through them.
165+ */
166+ const ionPickerColumn = this . el . querySelector ( 'ion-picker-column' ) ;
167+ elementToFocus = ionPickerColumn ?. shadowRoot ?. querySelector ( '.picker-opts' ) as HTMLElement | null ;
168+ break ;
169+
170+ case 'ION-PICKER-COLUMN' :
171+ /**
172+ * If the user clicked a picker column
173+ * then we should focus its own picker options
174+ * so that users can scroll through them.
175+ */
176+ elementToFocus = clickedTarget . shadowRoot ?. querySelector ( '.picker-opts' ) as HTMLElement | null ;
177+ break ;
178+
179+ case 'ION-PICKER-COLUMN-OPTION' :
180+ /**
181+ * If the user clicked a picker column option
182+ * then we should focus its picker options parent so that
183+ * users can scroll through them.
184+ */
185+ const ionPickerColumnOption = clickedTarget . closest ( 'ion-picker-column' ) ;
186+ if ( ionPickerColumnOption ) {
187+ elementToFocus = ionPickerColumnOption . shadowRoot ?. querySelector ( '.picker-opts' ) as HTMLElement | null ;
188+ }
189+ break ;
190+ }
191+
192+ if ( elementToFocus ) {
193+ elementToFocus . focus ( ) ;
194+ }
144195 } ;
145196
146197 /**
@@ -537,7 +588,10 @@ export class Picker implements ComponentInterface {
537588
538589 render ( ) {
539590 return (
540- < Host onPointerDown = { ( ev : PointerEvent ) => this . onPointerDown ( ev ) } onClick = { ( ) => this . onClick ( ) } >
591+ < Host
592+ onPointerDown = { ( ev : PointerEvent ) => this . onPointerDown ( ev ) }
593+ onClick = { ( ev : PointerEvent ) => this . onClick ( ev ) }
594+ >
541595 < input
542596 aria-hidden = "true"
543597 tabindex = { - 1 }
0 commit comments