Skip to content

Commit fee5973

Browse files
committed
refactor(associated-mixin): Incorporated internals controller
1 parent 771f0f7 commit fee5973

File tree

3 files changed

+63
-10
lines changed

3 files changed

+63
-10
lines changed

src/components/common/controllers/internals.ts

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type {
33
ReactiveController,
44
ReactiveControllerHost,
55
} from 'lit';
6+
import type { FormValueType } from '../mixins/forms/types.js';
67

78
/** Configuration for the ElementInternalsController. */
89
type ElementInternalsConfig<T extends keyof ARIAMixin = keyof ARIAMixin> = {
@@ -29,6 +30,41 @@ class ElementInternalsController {
2930
return this._internals.form;
3031
}
3132

33+
/**
34+
* Returns a `ValidityState` object which represents the different validity states
35+
* the element can be in, with respect to constraint validation.
36+
*
37+
* @remarks
38+
* The host element must be form associated, that is should have
39+
* `static formAssociated = true`.
40+
*/
41+
public get validity(): ValidityState {
42+
return this._internals.validity;
43+
}
44+
45+
/**
46+
* Returns a string containing the validation message of this element.
47+
*
48+
* @remarks
49+
* The host element must be form associated, that is should have
50+
* `static formAssociated = true`.
51+
*/
52+
public get validationMessage(): string {
53+
return this._internals.validationMessage;
54+
}
55+
56+
/**
57+
* Returns a boolean value which returns true if the element is a submittable element
58+
* which is a candidate for constraint validation.
59+
*
60+
* @remarks
61+
* The host element must be form associated, that is should have
62+
* `static formAssociated = true`.
63+
*/
64+
public get willValidate(): boolean {
65+
return this._internals.willValidate;
66+
}
67+
3268
constructor(
3369
host: ReactiveControllerHost & LitElement,
3470
config?: ElementInternalsConfig
@@ -52,13 +88,29 @@ class ElementInternalsController {
5288

5389
/**
5490
* Adds or removes a custom state from the element's internals.
55-
* Custom states can be styled via `:state()` pseudo-class in CSS.
91+
* Custom states can be styled via `:state()` selector in CSS.
5692
*/
5793
public setState(state: string, value: boolean): void {
5894
value
5995
? this._internals.states.add(state)
6096
: this._internals.states.delete(state);
6197
}
98+
99+
public setFormValue(value: FormValueType, state?: FormValueType): void {
100+
this._internals.setFormValue(value, state);
101+
}
102+
103+
public setValidity(flags?: ValidityStateFlags, message?: string): void {
104+
this._internals.setValidity(flags, message);
105+
}
106+
107+
public checkValidity(): boolean {
108+
return this._internals.checkValidity();
109+
}
110+
111+
public reportValidity(): boolean {
112+
return this._internals.reportValidity();
113+
}
62114
}
63115

64116
/** Creates and adds a {@link ElementInternalsController} to a LitElement host. */

src/components/common/mixins/forms/associated.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { LitElement } from 'lit';
22
import { property, state } from 'lit/decorators.js';
3+
import { addInternalsController } from '../../controllers/internals.js';
34
import { addSafeEventListener, isFunction, isString } from '../../util.js';
45
import type { Validator } from '../../validators.js';
56
import type { Constructor } from '../constructor.js';
@@ -13,6 +14,8 @@ import {
1314
InternalResetEvent,
1415
} from './types.js';
1516

17+
const INVALID_STATE = 'ig-invalid';
18+
1619
const eventOptions = {
1720
bubbles: false,
1821
composed: false,
@@ -30,8 +33,8 @@ function BaseFormAssociated<T extends Constructor<LitElement>>(base: T) {
3033
class BaseFormAssociatedElement extends base {
3134
public static readonly formAssociated = true;
3235

33-
private __internals: ElementInternals;
34-
protected _formValue!: FormValue<unknown>;
36+
private readonly __internals = addInternalsController(this);
37+
protected readonly _formValue!: FormValue<unknown>;
3538

3639
protected _disabled = false;
3740
protected _invalid = false;
@@ -122,8 +125,6 @@ function BaseFormAssociated<T extends Constructor<LitElement>>(base: T) {
122125

123126
constructor(...args: any[]) {
124127
super(args);
125-
this.__internals = this.attachInternals();
126-
127128
addSafeEventListener(this, 'invalid', this._handleInvalid);
128129
}
129130

@@ -137,6 +138,7 @@ function BaseFormAssociated<T extends Constructor<LitElement>>(base: T) {
137138
}
138139

139140
private _setInvalidStyles(): void {
141+
this.__internals.setState(INVALID_STATE, this._shouldApplyStyles);
140142
this.toggleAttribute('invalid', this._shouldApplyStyles);
141143
this.requestUpdate();
142144
}
@@ -157,9 +159,7 @@ function BaseFormAssociated<T extends Constructor<LitElement>>(base: T) {
157159
}
158160

159161
protected _handleBlur(): void {
160-
if (!this._touched) {
161-
this._touched = true;
162-
}
162+
this._setTouchedState();
163163
this._validate();
164164
}
165165

src/components/common/mixins/forms/types.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { LitElement } from 'lit';
2+
import type { ElementInternalsController } from '../../controllers/internals.js';
23
import type { Validator } from '../../validators.js';
34

45
export type FormRestoreMode = 'autocomplete' | 'restore';
@@ -9,10 +10,10 @@ export type IgcFormControl = LitElement &
910
declare class BaseFormAssociatedElement {
1011
public static readonly formAssociated: boolean;
1112

12-
private __internals: ElementInternals;
13+
private readonly __internals: ElementInternalsController;
14+
protected readonly _formValue: unknown;
1315

1416
// Properties
15-
protected _formValue: unknown;
1617
protected _pristine: boolean;
1718
protected _disabled: boolean;
1819
protected _invalid: boolean;

0 commit comments

Comments
 (0)