Skip to content

Commit 14cd6d3

Browse files
committed
rewrite auto-check events to be classes
1 parent c82bbaf commit 14cd6d3

File tree

2 files changed

+238
-53
lines changed

2 files changed

+238
-53
lines changed

custom-elements.json

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,138 @@
66
"kind": "javascript-module",
77
"path": "src/auto-check-element.ts",
88
"declarations": [
9+
{
10+
"kind": "class",
11+
"description": "",
12+
"name": "AutoCheckCompleteEvent",
13+
"superclass": {
14+
"name": "AutoCheckEvent",
15+
"module": "src/auto-check-element.ts"
16+
},
17+
"members": [
18+
{
19+
"kind": "field",
20+
"name": "detail",
21+
"readonly": true,
22+
"inheritedFrom": {
23+
"name": "AutoCheckEvent",
24+
"module": "src/auto-check-element.ts"
25+
}
26+
}
27+
]
28+
},
29+
{
30+
"kind": "class",
31+
"description": "",
32+
"name": "AutoCheckSuccessEvent",
33+
"superclass": {
34+
"name": "AutoCheckEvent",
35+
"module": "src/auto-check-element.ts"
36+
},
37+
"members": [
38+
{
39+
"kind": "field",
40+
"name": "detail",
41+
"readonly": true,
42+
"inheritedFrom": {
43+
"name": "AutoCheckEvent",
44+
"module": "src/auto-check-element.ts"
45+
}
46+
}
47+
]
48+
},
49+
{
50+
"kind": "class",
51+
"description": "",
52+
"name": "AutoCheckStartEvent",
53+
"superclass": {
54+
"name": "AutoCheckValidationEvent",
55+
"module": "src/auto-check-element.ts"
56+
},
57+
"members": [
58+
{
59+
"kind": "method",
60+
"name": "setValidity",
61+
"parameters": [
62+
{
63+
"name": "message",
64+
"type": {
65+
"text": "string"
66+
}
67+
}
68+
],
69+
"inheritedFrom": {
70+
"name": "AutoCheckValidationEvent",
71+
"module": "src/auto-check-element.ts"
72+
}
73+
},
74+
{
75+
"kind": "field",
76+
"name": "detail",
77+
"readonly": true,
78+
"inheritedFrom": {
79+
"name": "AutoCheckEvent",
80+
"module": "src/auto-check-element.ts"
81+
}
82+
}
83+
]
84+
},
85+
{
86+
"kind": "class",
87+
"description": "",
88+
"name": "AutoCheckErrorEvent",
89+
"superclass": {
90+
"name": "AutoCheckValidationEvent",
91+
"module": "src/auto-check-element.ts"
92+
},
93+
"members": [
94+
{
95+
"kind": "method",
96+
"name": "setValidity",
97+
"parameters": [
98+
{
99+
"name": "message",
100+
"type": {
101+
"text": "string"
102+
}
103+
}
104+
],
105+
"inheritedFrom": {
106+
"name": "AutoCheckValidationEvent",
107+
"module": "src/auto-check-element.ts"
108+
}
109+
},
110+
{
111+
"kind": "field",
112+
"name": "detail",
113+
"readonly": true,
114+
"inheritedFrom": {
115+
"name": "AutoCheckEvent",
116+
"module": "src/auto-check-element.ts"
117+
}
118+
}
119+
]
120+
},
121+
{
122+
"kind": "class",
123+
"description": "",
124+
"name": "AutoCheckSendEvent",
125+
"superclass": {
126+
"name": "AutoCheckEvent",
127+
"module": "src/auto-check-element.ts"
128+
},
129+
"members": [
130+
{
131+
"kind": "field",
132+
"name": "detail",
133+
"readonly": true,
134+
"inheritedFrom": {
135+
"name": "AutoCheckEvent",
136+
"module": "src/auto-check-element.ts"
137+
}
138+
}
139+
]
140+
},
9141
{
10142
"kind": "class",
11143
"description": "",
@@ -75,6 +207,46 @@
75207
}
76208
],
77209
"exports": [
210+
{
211+
"kind": "js",
212+
"name": "AutoCheckCompleteEvent",
213+
"declaration": {
214+
"name": "AutoCheckCompleteEvent",
215+
"module": "src/auto-check-element.ts"
216+
}
217+
},
218+
{
219+
"kind": "js",
220+
"name": "AutoCheckSuccessEvent",
221+
"declaration": {
222+
"name": "AutoCheckSuccessEvent",
223+
"module": "src/auto-check-element.ts"
224+
}
225+
},
226+
{
227+
"kind": "js",
228+
"name": "AutoCheckStartEvent",
229+
"declaration": {
230+
"name": "AutoCheckStartEvent",
231+
"module": "src/auto-check-element.ts"
232+
}
233+
},
234+
{
235+
"kind": "js",
236+
"name": "AutoCheckErrorEvent",
237+
"declaration": {
238+
"name": "AutoCheckErrorEvent",
239+
"module": "src/auto-check-element.ts"
240+
}
241+
},
242+
{
243+
"kind": "js",
244+
"name": "AutoCheckSendEvent",
245+
"declaration": {
246+
"name": "AutoCheckSendEvent",
247+
"module": "src/auto-check-element.ts"
248+
}
249+
},
78250
{
79251
"kind": "js",
80252
"name": "AutoCheckElement",

src/auto-check-element.ts

Lines changed: 66 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,60 @@ type State = {
1414

1515
const states = new WeakMap<AutoCheckElement, State>()
1616

17-
export class AutoCheckCompleteEvent extends Event {
17+
class AutoCheckEvent extends Event {
18+
constructor(public readonly phase: string) {
19+
super(`auto-check-${phase}`, {bubbles: true})
20+
}
21+
22+
// Backwards compatibiltiy with `CustomEvent`
23+
get detail() {
24+
return this
25+
}
26+
}
27+
28+
class AutoCheckValidationEvent extends AutoCheckEvent {
29+
constructor(public readonly phase: string, public message = '') {
30+
super(phase)
31+
}
32+
33+
setValidity(message: string) {
34+
this.message = message
35+
}
36+
}
37+
38+
// eslint-disable-next-line custom-elements/no-exports-with-element
39+
export class AutoCheckCompleteEvent extends AutoCheckEvent {
40+
constructor() {
41+
super('complete')
42+
}
43+
}
44+
45+
// eslint-disable-next-line custom-elements/no-exports-with-element
46+
export class AutoCheckSuccessEvent extends AutoCheckEvent {
47+
constructor(public readonly response: Response) {
48+
super('success')
49+
}
50+
}
51+
52+
// eslint-disable-next-line custom-elements/no-exports-with-element
53+
export class AutoCheckStartEvent extends AutoCheckValidationEvent {
1854
constructor() {
19-
super('auto-check-complete', {bubbles: true})
55+
super('start', 'Verifying…')
56+
}
57+
}
58+
59+
// eslint-disable-next-line custom-elements/no-exports-with-element
60+
export class AutoCheckErrorEvent extends AutoCheckValidationEvent {
61+
constructor(public readonly response: Response) {
62+
// eslint-disable-next-line i18n-text/no-en
63+
super('error', 'Validation failed')
64+
}
65+
}
66+
67+
// eslint-disable-next-line custom-elements/no-exports-with-element
68+
export class AutoCheckSendEvent extends AutoCheckEvent {
69+
constructor(public readonly body: FormData) {
70+
super('send')
2071
}
2172
}
2273

@@ -128,17 +179,10 @@ function setLoadingState(event: Event) {
128179
return
129180
}
130181

131-
let message = 'Verifying…'
132-
const setValidity = (text: string) => (message = text)
133-
input.dispatchEvent(
134-
new CustomEvent('auto-check-start', {
135-
bubbles: true,
136-
detail: {setValidity},
137-
}),
138-
)
139-
182+
const startEvent = new AutoCheckStartEvent()
183+
input.dispatchEvent(startEvent)
140184
if (autoCheckElement.required) {
141-
input.setCustomValidity(message)
185+
input.setCustomValidity(startEvent.message)
142186
}
143187
}
144188

@@ -199,12 +243,7 @@ async function check(autoCheckElement: AutoCheckElement) {
199243
body.append(csrfField, csrf)
200244
body.append('value', input.value)
201245

202-
input.dispatchEvent(
203-
new CustomEvent('auto-check-send', {
204-
bubbles: true,
205-
detail: {body},
206-
}),
207-
)
246+
input.dispatchEvent(new AutoCheckSendEvent(body))
208247

209248
if (state.controller) {
210249
state.controller.abort()
@@ -222,9 +261,16 @@ async function check(autoCheckElement: AutoCheckElement) {
222261
body,
223262
})
224263
if (response.ok) {
225-
processSuccess(response, input, autoCheckElement.required)
264+
if (autoCheckElement.required) {
265+
input.setCustomValidity('')
266+
}
267+
input.dispatchEvent(new AutoCheckSuccessEvent(response.clone()))
226268
} else {
227-
processFailure(response, input, autoCheckElement.required)
269+
const event = new AutoCheckErrorEvent(response.clone())
270+
input.dispatchEvent(event)
271+
if (autoCheckElement.required) {
272+
input.setCustomValidity(event.message)
273+
}
228274
}
229275
state.controller = null
230276
input.dispatchEvent(new AutoCheckCompleteEvent())
@@ -236,37 +282,4 @@ async function check(autoCheckElement: AutoCheckElement) {
236282
}
237283
}
238284

239-
function processSuccess(response: Response, input: HTMLInputElement, required: boolean) {
240-
if (required) {
241-
input.setCustomValidity('')
242-
}
243-
input.dispatchEvent(
244-
new CustomEvent('auto-check-success', {
245-
bubbles: true,
246-
detail: {
247-
response: response.clone(),
248-
},
249-
}),
250-
)
251-
}
252-
253-
function processFailure(response: Response, input: HTMLInputElement, required: boolean) {
254-
// eslint-disable-next-line i18n-text/no-en
255-
let message = 'Validation failed'
256-
const setValidity = (text: string) => (message = text)
257-
input.dispatchEvent(
258-
new CustomEvent('auto-check-error', {
259-
bubbles: true,
260-
detail: {
261-
response: response.clone(),
262-
setValidity,
263-
},
264-
}),
265-
)
266-
267-
if (required) {
268-
input.setCustomValidity(message)
269-
}
270-
}
271-
272285
export default AutoCheckElement

0 commit comments

Comments
 (0)