File size: 1,090 Bytes
05e5873
 
 
28faefd
 
 
 
 
 
 
 
05e5873
 
 
 
 
28faefd
 
 
 
 
 
 
 
 
05e5873
 
 
 
 
 
 
28faefd
05e5873
28faefd
 
 
 
 
 
76beec4
 
 
 
28faefd
 
 
05e5873
 
 
 
28faefd
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import { createAttachmentKey } from "svelte/attachments";
import type { HTMLInputAttributes } from "svelte/elements";

export type CreateFieldValidationArgs = {
	validate: (v: string) => string | void | undefined;
};

export function createFieldValidation(args: CreateFieldValidationArgs) {
	let valid = $state(true);
	let msg = $state<string>();

	const key = createAttachmentKey();
	let node: HTMLInputElement;

	const onblur = (_e: Event & { currentTarget: HTMLInputElement }) => {
		validate();
	};

	const oninput = (e: Event & { currentTarget: HTMLInputElement }) => {
		if (valid) return;
		const v = e.currentTarget.value;
		const m = args.validate(v);
		msg = m ? m : undefined;
	};

	const validate = () => {
		const v = node.value;
		const m = args.validate(v);
		valid = !m;
		msg = m ? m : undefined;
	};

	return {
		validate,
		get valid() {
			return valid;
		},
		get msg() {
			return msg;
		},
		reset() {
			valid = true;
			msg = undefined;
		},
		attrs: {
			onblur,
			oninput,
			[key]: el => {
				node = el;
			},
		} as const satisfies HTMLInputAttributes,
	};
}