Skip to content

Commit 2484c2c

Browse files
authored
refactor: FormValue type inference (#1737)
Exposed an utility type for FormValue so it does not have to be initialized in the constructor.
1 parent c01572b commit 2484c2c

File tree

15 files changed

+96
-129
lines changed

15 files changed

+96
-129
lines changed

src/components/checkbox/checkbox-base.ts

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import type { Constructor } from '../common/mixins/constructor.js';
77
import { EventEmitterMixin } from '../common/mixins/event-emitter.js';
88
import { FormAssociatedCheckboxRequiredMixin } from '../common/mixins/forms/associated-required.js';
99
import {
10-
type FormValue,
10+
type FormValueOf,
1111
createFormValueState,
1212
defaultBooleanTransformers,
1313
} from '../common/mixins/forms/form-value.js';
@@ -40,7 +40,11 @@ export class IgcCheckboxBaseComponent extends FormAssociatedCheckboxRequiredMixi
4040
}
4141

4242
protected readonly _focusRingManager = addKeyboardFocusRing(this);
43-
protected override _formValue: FormValue<boolean>;
43+
protected override readonly _formValue: FormValueOf<boolean> =
44+
createFormValueState(this, {
45+
initialValue: false,
46+
transformers: defaultBooleanTransformers,
47+
});
4448
protected _value!: string;
4549

4650
@query('input', true)
@@ -90,15 +94,6 @@ export class IgcCheckboxBaseComponent extends FormAssociatedCheckboxRequiredMixi
9094
@property({ reflect: true, attribute: 'label-position' })
9195
public labelPosition: ToggleLabelPosition = 'after';
9296

93-
constructor() {
94-
super();
95-
96-
this._formValue = createFormValueState(this, {
97-
initialValue: false,
98-
transformers: defaultBooleanTransformers,
99-
});
100-
}
101-
10297
protected override createRenderRoot(): HTMLElement | DocumentFragment {
10398
const root = super.createRenderRoot();
10499
this._hideLabel = isEmpty(this._label);

src/components/combo/combo.ts

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import type { Constructor } from '../common/mixins/constructor.js';
1818
import { EventEmitterMixin } from '../common/mixins/event-emitter.js';
1919
import { FormAssociatedRequiredMixin } from '../common/mixins/forms/associated-required.js';
2020
import {
21-
type FormValue,
21+
type FormValueOf,
2222
createFormValueState,
2323
} from '../common/mixins/forms/form-value.js';
2424
import { partMap } from '../common/part-map.js';
@@ -136,7 +136,14 @@ export default class IgcComboComponent<
136136
return comboValidators;
137137
}
138138

139-
protected override _formValue: FormValue<ComboValue<T>[]>;
139+
protected override readonly _formValue: FormValueOf<ComboValue<T>[]> =
140+
createFormValueState<ComboValue<T>[]>(this, {
141+
initialValue: [],
142+
transformers: {
143+
setValue: asArray,
144+
setDefaultValue: asArray,
145+
},
146+
});
140147
private _data: T[] = [];
141148

142149
private _valueKey?: Keys<T>;
@@ -468,14 +475,6 @@ export default class IgcComboComponent<
468475
constructor() {
469476
super();
470477

471-
this._formValue = createFormValueState<ComboValue<T>[]>(this, {
472-
initialValue: [],
473-
transformers: {
474-
setValue: asArray,
475-
setDefaultValue: asArray,
476-
},
477-
});
478-
479478
this.addEventListener('blur', this._handleBlur);
480479

481480
this.addEventListener(

src/components/common/mixins/form-associated.spec.ts

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {
1515
requiredValidator,
1616
} from '../validators.js';
1717
import { FormAssociatedRequiredMixin } from './forms/associated-required.js';
18-
import { type FormValue, createFormValueState } from './forms/form-value.js';
18+
import { type FormValueOf, createFormValueState } from './forms/form-value.js';
1919
import type {
2020
FormAssociatedElementInterface,
2121
FormRequiredInterface,
@@ -52,7 +52,8 @@ describe('Form associated mixin tests', () => {
5252
return [requiredValidator, minLengthValidator, maxLengthValidator];
5353
}
5454

55-
protected override _formValue: FormValue<string>;
55+
protected override _formValue: FormValueOf<string> =
56+
createFormValueState(this, { initialValue: '' });
5657

5758
private _minLength!: number;
5859
private _maxLength!: number;
@@ -84,12 +85,6 @@ describe('Form associated mixin tests', () => {
8485
return this._formValue.value;
8586
}
8687

87-
constructor() {
88-
super();
89-
90-
this._formValue = createFormValueState(this, { initialValue: '' });
91-
}
92-
9388
public override connectedCallback() {
9489
super.connectedCallback();
9590
this._updateValidity();

src/components/common/mixins/forms/form-value.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,6 @@ import type { DateRangeValue } from '../../../date-range-picker/date-range-picke
77
import { asNumber } from '../../util.js';
88
import type { FormValueType, IgcFormControl } from './types.js';
99

10-
export function createFormValueState<T>(
11-
host: IgcFormControl,
12-
config: FormValueConfig<T>
13-
): FormValue<T> {
14-
return new FormValue(host, config);
15-
}
16-
1710
type FormValueTransformers<T> = {
1811
setValue: (value: T) => T;
1912
getValue: (value: T) => T;
@@ -171,3 +164,12 @@ export class FormValue<T> {
171164
return this._transformers.getValue(this._value);
172165
}
173166
}
167+
168+
export function createFormValueState<T>(
169+
host: IgcFormControl,
170+
config: FormValueConfig<T>
171+
): FormValue<T> {
172+
return new FormValue(host, config);
173+
}
174+
175+
export type FormValueOf<T> = ReturnType<typeof createFormValueState<T>>;

src/components/date-picker/date-picker.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import type { AbstractConstructor } from '../common/mixins/constructor.js';
3131
import { EventEmitterMixin } from '../common/mixins/event-emitter.js';
3232
import { FormAssociatedRequiredMixin } from '../common/mixins/forms/associated-required.js';
3333
import {
34-
type FormValue,
34+
type FormValueOf,
3535
createFormValueState,
3636
defaultDateTimeTransformers,
3737
} from '../common/mixins/forms/form-value.js';
@@ -194,7 +194,11 @@ export default class IgcDatePickerComponent extends FormAssociatedRequiredMixin(
194194
private _displayFormat?: string;
195195
private _inputFormat?: string;
196196

197-
protected override readonly _formValue: FormValue<Date | null>;
197+
protected override readonly _formValue: FormValueOf<Date | null> =
198+
createFormValueState(this, {
199+
initialValue: null,
200+
transformers: defaultDateTimeTransformers,
201+
});
198202

199203
@query(IgcDateTimeInputComponent.tagName)
200204
private readonly _input!: IgcDateTimeInputComponent;
@@ -457,11 +461,6 @@ export default class IgcDatePickerComponent extends FormAssociatedRequiredMixin(
457461
constructor() {
458462
super();
459463

460-
this._formValue = createFormValueState<Date | null>(this, {
461-
initialValue: null,
462-
transformers: defaultDateTimeTransformers,
463-
});
464-
465464
this.addEventListener('focusin', this._handleFocusIn);
466465
this.addEventListener('focusout', this._handleFocusOut);
467466

src/components/date-range-picker/date-range-picker.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import type { AbstractConstructor } from '../common/mixins/constructor.js';
3333
import { EventEmitterMixin } from '../common/mixins/event-emitter.js';
3434
import { FormAssociatedRequiredMixin } from '../common/mixins/forms/associated-required.js';
3535
import {
36-
type FormValue,
36+
type FormValueOf,
3737
createFormValueState,
3838
defaultDateRangeTransformers,
3939
} from '../common/mixins/forms/form-value.js';
@@ -213,7 +213,14 @@ export default class IgcDateRangePickerComponent extends FormAssociatedRequiredM
213213
private static readonly _increment = createCounter();
214214

215215
protected readonly _inputId = `date-range-picker-${IgcDateRangePickerComponent._increment()}`;
216-
protected override _formValue: FormValue<DateRangeValue | null>;
216+
protected override readonly _formValue: FormValueOf<DateRangeValue | null> =
217+
createFormValueState(this, {
218+
initialValue: {
219+
start: null,
220+
end: null,
221+
},
222+
transformers: defaultDateRangeTransformers,
223+
});
217224

218225
private _activeDate: Date | null = null;
219226
private _min: Date | null = null;
@@ -573,13 +580,6 @@ export default class IgcDateRangePickerComponent extends FormAssociatedRequiredM
573580

574581
constructor() {
575582
super();
576-
this._formValue = createFormValueState<DateRangeValue | null>(this, {
577-
initialValue: {
578-
start: null,
579-
end: null,
580-
},
581-
transformers: defaultDateRangeTransformers,
582-
});
583583

584584
this._rootClickController.update({ hideCallback: this._handleClosing });
585585
this.addEventListener('focusin', this._handleFocusIn);

src/components/date-time-input/date-time-input.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { registerComponent } from '../common/definitions/register.js';
1818
import type { AbstractConstructor } from '../common/mixins/constructor.js';
1919
import { EventEmitterMixin } from '../common/mixins/event-emitter.js';
2020
import {
21-
type FormValue,
21+
type FormValueOf,
2222
createFormValueState,
2323
defaultDateTimeTransformers,
2424
} from '../common/mixins/forms/form-value.js';
@@ -87,7 +87,11 @@ export default class IgcDateTimeInputComponent extends EventEmitterMixin<
8787
return dateTimeInputValidators;
8888
}
8989

90-
protected override _formValue: FormValue<Date | null>;
90+
protected override readonly _formValue: FormValueOf<Date | null> =
91+
createFormValueState(this, {
92+
initialValue: null,
93+
transformers: defaultDateTimeTransformers,
94+
});
9195

9296
protected _defaultMask!: string;
9397
private _oldValue: Date | null = null;
@@ -282,11 +286,6 @@ export default class IgcDateTimeInputComponent extends EventEmitterMixin<
282286
constructor() {
283287
super();
284288

285-
this._formValue = createFormValueState(this, {
286-
initialValue: null,
287-
transformers: defaultDateTimeTransformers,
288-
});
289-
290289
addKeybindings(this, {
291290
skip: () => this.readOnly,
292291
bindingDefaults: { preventDefault: true, triggers: ['keydownRepeat'] },

src/components/file-input/file-input.ts

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { themes } from '../../theming/theming-decorator.js';
66
import IgcButtonComponent from '../button/button.js';
77
import { registerComponent } from '../common/definitions/register.js';
88
import {
9-
type FormValue,
9+
type FormValueOf,
1010
createFormValueState,
1111
defaultFileListTransformer,
1212
} from '../common/mixins/forms/form-value.js';
@@ -62,7 +62,11 @@ export default class IgcFileInputComponent extends IgcInputBaseComponent {
6262
return fileValidators;
6363
}
6464

65-
protected override _formValue: FormValue<FileList | null>;
65+
protected override readonly _formValue: FormValueOf<FileList | null> =
66+
createFormValueState(this, {
67+
initialValue: null,
68+
transformers: defaultFileListTransformer,
69+
});
6670

6771
@state()
6872
private _hasActivation = false;
@@ -129,14 +133,6 @@ export default class IgcFileInputComponent extends IgcInputBaseComponent {
129133
return this.input?.files ?? null;
130134
}
131135

132-
constructor() {
133-
super();
134-
this._formValue = createFormValueState(this, {
135-
initialValue: null,
136-
transformers: defaultFileListTransformer,
137-
});
138-
}
139-
140136
protected override _restoreDefaultValue(): void {
141137
this.input.value = '';
142138
super._restoreDefaultValue();

src/components/input/input.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { live } from 'lit/directives/live.js';
55

66
import { registerComponent } from '../common/definitions/register.js';
77
import {
8-
type FormValue,
8+
type FormValueOf,
99
createFormValueState,
1010
} from '../common/mixins/forms/form-value.js';
1111
import { partMap } from '../common/part-map.js';
@@ -50,7 +50,8 @@ export default class IgcInputComponent extends IgcInputBaseComponent {
5050
registerComponent(IgcInputComponent, IgcValidationContainerComponent);
5151
}
5252

53-
protected override _formValue: FormValue<string>;
53+
protected override readonly _formValue: FormValueOf<string> =
54+
createFormValueState(this, { initialValue: '' });
5455

5556
protected override get __validators() {
5657
return this.type !== 'number' ? stringValidators : numberValidators;
@@ -207,11 +208,6 @@ export default class IgcInputComponent extends IgcInputBaseComponent {
207208
@property({ type: Number })
208209
public override tabIndex = 0;
209210

210-
constructor() {
211-
super();
212-
this._formValue = createFormValueState(this, { initialValue: '' });
213-
}
214-
215211
/* blazorSuppress */
216212
/** Replaces the selected text in the input. */
217213
public override setRangeText(

src/components/mask-input/mask-input.ts

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { live } from 'lit/directives/live.js';
66
import { watch } from '../common/decorators/watch.js';
77
import { registerComponent } from '../common/definitions/register.js';
88
import {
9-
type FormValue,
9+
type FormValueOf,
1010
createFormValueState,
1111
} from '../common/mixins/forms/form-value.js';
1212
import { partMap } from '../common/part-map.js';
@@ -55,7 +55,14 @@ export default class IgcMaskInputComponent extends IgcMaskInputBaseComponent {
5555
return maskValidators;
5656
}
5757

58-
protected override _formValue: FormValue<string>;
58+
protected override readonly _formValue: FormValueOf<string> =
59+
createFormValueState(this, {
60+
initialValue: '',
61+
transformers: {
62+
setFormValue: (value) =>
63+
this._isRawMode ? value || null : this.maskedValue || null,
64+
},
65+
});
5966

6067
protected get _isRawMode() {
6168
return this.valueMode === 'raw';
@@ -114,18 +121,6 @@ export default class IgcMaskInputComponent extends IgcMaskInputBaseComponent {
114121
}
115122
}
116123

117-
constructor() {
118-
super();
119-
120-
this._formValue = createFormValueState(this, {
121-
initialValue: '',
122-
transformers: {
123-
setFormValue: (value) =>
124-
this._isRawMode ? value || null : this.maskedValue || null,
125-
},
126-
});
127-
}
128-
129124
@watch('prompt')
130125
protected promptChange() {
131126
this.parser.prompt = this.prompt;

0 commit comments

Comments
 (0)