@@ -52,12 +52,14 @@ export const SelectableMixin = <T extends Constructor<LitElement>>(
5252 }
5353 set selectable ( newVal ) {
5454 const oldVal = this . _selectable ;
55+ if ( oldVal === newVal ) return ;
5556 this . _selectable = newVal ;
57+
5658 // Potentially problematic as a component might need focus for another feature when not selectable:
57- if ( this . selectableTarget === this ) {
58- // If the selectable target, then make it self selectable. (A different selectable target should be made focusable by the component itself)
59- this . setAttribute ( 'tabindex' , `${ newVal ? '0' : '-1' } ` ) ;
60- }
59+ // if (this.# selectableTarget === this) {
60+ // If the selectable target, then make it self selectable. (A different selectable target should be made focusable by the component itself)
61+ this . #selectableTarget . setAttribute ( 'tabindex' , `${ newVal ? '0' : '-1' } ` ) ;
62+ // }
6163 this . requestUpdate ( 'selectable' , oldVal ) ;
6264 }
6365
@@ -71,7 +73,28 @@ export const SelectableMixin = <T extends Constructor<LitElement>>(
7173 @property ( { type : Boolean , reflect : true } )
7274 public selected = false ;
7375
74- protected selectableTarget : EventTarget = this ;
76+ #selectableTarget: Element = this ;
77+ protected get selectableTarget ( ) : EventTarget {
78+ return this . #selectableTarget;
79+ }
80+ protected set selectableTarget ( target : EventTarget ) {
81+ const oldTarget = this . #selectableTarget;
82+
83+ oldTarget . removeAttribute ( 'tabindex' ) ;
84+ oldTarget . removeEventListener ( 'click' , this . #onClick) ;
85+ oldTarget . removeEventListener (
86+ 'keydown' ,
87+ this . #onKeydown as EventListener ,
88+ ) ;
89+
90+ this . #selectableTarget = target as Element ;
91+ this . #selectableTarget. setAttribute (
92+ 'tabindex' ,
93+ this . _selectable ? '0' : '-1' ,
94+ ) ;
95+ target . addEventListener ( 'click' , this . #onClick) ;
96+ target . addEventListener ( 'keydown' , this . #onKeydown as EventListener ) ;
97+ }
7598
7699 constructor ( ...args : any [ ] ) {
77100 super ( ...args ) ;
@@ -80,17 +103,8 @@ export const SelectableMixin = <T extends Constructor<LitElement>>(
80103 }
81104
82105 readonly #onKeydown = ( e : KeyboardEvent ) => {
83- const composePath = e . composedPath ( ) ;
84- if (
85- ( this . _selectable || ( this . deselectable && this . selected ) ) &&
86- composePath . indexOf ( this . selectableTarget ) === 0
87- ) {
88- if ( this . selectableTarget === this ) {
89- if ( e . code !== 'Space' && e . code !== 'Enter' ) return ;
90- this . #toggleSelect( ) ;
91- e . preventDefault ( ) ;
92- }
93- }
106+ if ( e . code !== 'Space' && e . code !== 'Enter' ) return ;
107+ this . #onClick( e ) ;
94108 } ;
95109
96110 readonly #onClick = ( e : Event ) => {
@@ -99,12 +113,18 @@ export const SelectableMixin = <T extends Constructor<LitElement>>(
99113
100114 if ( isSelectable === false ) return ;
101115
102- if ( this . selectableTarget === this ) {
116+ if ( this . # selectableTarget === this ) {
103117 // If target is this, then only allow selection if the click is on the element itself.
104- if ( e . composedPath ( ) . indexOf ( this . selectableTarget ) === 0 ) {
118+ if ( e . composedPath ( ) . indexOf ( this . #selectableTarget) === 0 ) {
119+ if ( e . type === 'keydown' ) {
120+ e . preventDefault ( ) ; // Do not want the space key to trigger a page scroll.
121+ }
105122 this . #toggleSelect( ) ;
106123 }
107- } else if ( e . composedPath ( ) . indexOf ( this . selectableTarget ) !== - 1 ) {
124+ } else if ( e . composedPath ( ) . indexOf ( this . #selectableTarget) !== - 1 ) {
125+ if ( e . type === 'keydown' ) {
126+ e . preventDefault ( ) ; // Do not want the space key to trigger a page scroll.
127+ }
108128 this . #toggleSelect( ) ;
109129 }
110130 } ;
0 commit comments