@@ -24,7 +24,7 @@ const focusableSelector = [
2424 'input:not([disabled])' ,
2525 'select:not([disabled])' ,
2626 'textarea:not([disabled])' ,
27- ]
27+ ] . join ( ',' )
2828
2929function onKeyDown ( event : KeyboardEvent ) {
3030 if ( event . key !== Tab ) return
@@ -33,7 +33,7 @@ function onKeyDown(event: KeyboardEvent) {
3333 const element = event . target as HTMLElement
3434 if ( ! container . contains ( element ) ) return
3535
36- const focusable = [ ...container . querySelectorAll ( focusableSelector . join ( ',' ) ) ]
36+ const focusable = [ ...container . querySelectorAll ( focusableSelector ) ]
3737 const first = focusable [ 0 ]
3838 const last = focusable [ focusable . length - 1 ]
3939
@@ -50,14 +50,27 @@ function onKeyDown(event: KeyboardEvent) {
5050 }
5151}
5252
53+ const selectableSelector = [ 'textarea' , 'input' ] . join ( ',' )
54+ function isSelectableElement (
55+ element : Element | null ,
56+ ) : element is HTMLInputElement | HTMLTextAreaElement {
57+ return element ?. matches ?.( selectableSelector ) ?? false
58+ }
59+
5360export const trapFocusOnOpen =
5461 ( store : Readable < Expandable > ) : Behavior =>
5562 ( node ) =>
5663 derived ( store , ( $store ) => $store . expanded ) . subscribe ( ( expanded ) => {
5764 if ( expanded ) {
58- const focusable = node . querySelector ( focusableSelector . join ( ',' ) )
65+ const focusable = node . querySelector ( focusableSelector ) as HTMLElement | null
5966 if ( focusable ) {
60- requestAnimationFrame ( ( ) => ( focusable as HTMLElement ) . focus ( ) )
67+ requestAnimationFrame ( ( ) => {
68+ focusable . focus ( )
69+ // if input or textarea, select text as though we'd tabbed to it
70+ if ( isSelectableElement ( focusable ) ) {
71+ focusable . select ( )
72+ }
73+ } )
6174 }
6275 node . addEventListener ( 'keydown' , onKeyDown )
6376 } else {
0 commit comments