1
1
import { IElementInternals } from 'element-internals-polyfill' ;
2
2
import { Constructor , FormControlInterface , FormValue , IControlHost , Validator } from './types' ;
3
3
4
- export function FormControlMixin < T extends Constructor < HTMLElement & IControlHost > > ( SuperClass : T ) {
4
+ export function FormControlMixin <
5
+ TBase extends Constructor < HTMLElement & IControlHost > & { observedAttributes : string [ ] }
6
+ > ( SuperClass : TBase ) {
5
7
class FormControl extends SuperClass {
6
8
7
9
/** Wires up control instances to be form associated */
@@ -17,6 +19,7 @@ export function FormControlMixin<T extends Constructor<HTMLElement & IControlHos
17
19
* be set to an invalid state.
18
20
*/
19
21
declare static formControlValidators : Validator [ ] ;
22
+
20
23
private static get validators ( ) : Validator [ ] {
21
24
return this . formControlValidators || [ ] ;
22
25
}
@@ -30,12 +33,11 @@ export function FormControlMixin<T extends Constructor<HTMLElement & IControlHos
30
33
static get observedAttributes ( ) : string [ ] {
31
34
const validatorAttributes = this . validators . map ( ( validator ) => validator . attribute ) ;
32
35
33
- /** @ts -ignore This exits */
34
36
const observedAttributes = super . observedAttributes || [ ] ;
35
37
36
38
/** Make sure there are no duplicates inside the attributes list */
37
39
const attributeSet = new Set ( [ ...observedAttributes , ...validatorAttributes ] ) ;
38
- return [ ...attributeSet ] ;
40
+ return [ ...attributeSet ] as string [ ] ;
39
41
}
40
42
41
43
/**
@@ -130,6 +132,7 @@ export function FormControlMixin<T extends Constructor<HTMLElement & IControlHos
130
132
return this . internals . validity ;
131
133
}
132
134
135
+ /* eslint-disable @typescript-eslint/no-explicit-any */
133
136
constructor ( ...args : any [ ] ) {
134
137
super ( ...args ) ;
135
138
this . addEventListener ( 'focus' , this . #onFocus) ;
@@ -159,7 +162,9 @@ export function FormControlMixin<T extends Constructor<HTMLElement & IControlHos
159
162
/** Initialize the form control and perform initial validation */
160
163
this . #initFormControl( ) ;
161
164
this . #validate( this . value ) ;
162
- this . validationMessageCallback ( '' ) ;
165
+ if ( this . validationMessageCallback ) {
166
+ this . validationMessageCallback ( '' ) ;
167
+ }
163
168
}
164
169
165
170
disconnectedCallback ( ) {
@@ -181,12 +186,6 @@ export function FormControlMixin<T extends Constructor<HTMLElement & IControlHos
181
186
/** Closed over variable to track value changes */
182
187
let value : FormValue = this . value || '' ;
183
188
184
- /** Value getter reference within the closure */
185
- let set : ( ( v : FormValue ) => void ) | undefined ;
186
-
187
- /** Value setter reference within the closure */
188
- let get : ( ( v : FormValue ) => void ) | undefined ;
189
-
190
189
/** Look to see if '`checked'` is on the control's prototype */
191
190
const hasChecked = this . #isCheckedElement;
192
191
@@ -210,15 +209,15 @@ export function FormControlMixin<T extends Constructor<HTMLElement & IControlHos
210
209
}
211
210
212
211
/** Make sure to defer to the parent */
213
- set = descriptor && descriptor . set ;
214
- get = descriptor && descriptor . get ;
212
+ const set = descriptor && descriptor . set ;
213
+ const get = descriptor && descriptor . get ;
215
214
216
215
/** Define the FormControl's value property */
217
216
Object . defineProperty ( this , 'value' , {
218
217
get ( ) {
219
218
/** If a getter already exists, make sure to call it */
220
219
if ( get ) {
221
- return get . call ( this , null ) ;
220
+ return get . call ( this ) ;
222
221
}
223
222
return value ;
224
223
} ,
@@ -263,8 +262,8 @@ export function FormControlMixin<T extends Constructor<HTMLElement & IControlHos
263
262
if ( this . constructor . prototype . hasOwnProperty ( 'checked' ) ) {
264
263
descriptor = Object . getOwnPropertyDescriptor ( this . constructor . prototype , 'checked' ) ;
265
264
}
266
- let get = descriptor && descriptor . get ;
267
- let set = descriptor && descriptor . set ;
265
+ const get = descriptor && descriptor . get ;
266
+ const set = descriptor && descriptor . set ;
268
267
269
268
/** Close over the initial value to use in the new getter/setter */
270
269
let checked = this . checked ;
@@ -312,7 +311,7 @@ export function FormControlMixin<T extends Constructor<HTMLElement & IControlHos
312
311
* in cases where `checked` is present upon initialization, this will be
313
312
* effectively `this.checked && this.value`.
314
313
*/
315
- valueChangedCallback ( value : FormValue ) : void { }
314
+ declare valueChangedCallback : ( value : FormValue ) => void ;
316
315
317
316
/**
318
317
* Resets a form control to its initial state
@@ -375,7 +374,9 @@ export function FormControlMixin<T extends Constructor<HTMLElement & IControlHos
375
374
this . #forceError = true ;
376
375
}
377
376
const showError = this . #shouldShowError( ) ;
378
- this . validationMessageCallback ( showError ? this . validationMessage : '' ) ;
377
+ if ( this . validationMessageCallback ) {
378
+ this . validationMessageCallback ( showError ? this . validationMessage : '' ) ;
379
+ }
379
380
} ;
380
381
381
382
/**
@@ -400,7 +401,9 @@ export function FormControlMixin<T extends Constructor<HTMLElement & IControlHos
400
401
}
401
402
this . #validate( value ) ;
402
403
const showError = this . #shouldShowError( ) ;
403
- this . validationMessageCallback ( showError ? this . validationMessage : '' ) ;
404
+ if ( this . validationMessageCallback ) {
405
+ this . validationMessageCallback ( showError ? this . validationMessage : '' ) ;
406
+ }
404
407
}
405
408
406
409
/**
@@ -443,7 +446,7 @@ export function FormControlMixin<T extends Constructor<HTMLElement & IControlHos
443
446
* if a control has a ValidityCallback, it can override the error
444
447
* message for a given validity key.
445
448
*/
446
- if ( this . validityCallback ( key ) ) {
449
+ if ( this . validityCallback && this . validityCallback ( key ) ) {
447
450
messageResult = this . validityCallback ( key ) as string ;
448
451
} else if ( message instanceof Function ) {
449
452
messageResult = message ( this , value ) ;
@@ -508,14 +511,14 @@ export function FormControlMixin<T extends Constructor<HTMLElement & IControlHos
508
511
* The returned value will be used as the validationMessage for the given key.
509
512
* @param validationKey {string} - The key that has returned invalid
510
513
*/
511
- validityCallback ( validationKey : string ) : string | void { }
514
+ declare validityCallback : ( validationKey : string ) => string | void ;
512
515
513
516
/**
514
517
* Called when the control's validationMessage should be changed
515
518
* @param message { string } - The new validation message
516
519
*/
517
- validationMessageCallback ( message : string ) : void { }
520
+ declare validationMessageCallback : ( message : string ) => void ;
518
521
}
519
522
520
- return FormControl as Constructor < FormControlInterface > & T ;
523
+ return FormControl as Constructor < FormControlInterface > & TBase ;
521
524
}
0 commit comments