Skip to content

Commit 92069f9

Browse files
committed
Serializer code in seperate file
1 parent 8ed26e4 commit 92069f9

File tree

3 files changed

+114
-114
lines changed

3 files changed

+114
-114
lines changed

src/elements/FormInput.tsx

Lines changed: 1 addition & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React from "react";
22
import { InputHTMLAttributes } from "react";
33
import { DefaultError, DefaultState, FormState } from "../form";
44
import { useListener } from "../hooks";
5+
import { SerializeProps, defaultSerializer, defaultDeserializer, Serializer, Deserializer } from "./serializer";
56

67
export const DEFAULT_DIRTY_CLASS = "typed-form-dirty";
78
export const DEFAULT_ERROR_CLASS = "typed-form-error";
@@ -10,122 +11,8 @@ export function getClassName(...args: any) {
1011
return [...args].filter((e) => !!e).join(" ");
1112
}
1213

13-
export type SerializeType =
14-
| "number"
15-
| "text"
16-
| "password"
17-
| "date"
18-
| "datetime-local"
19-
| "radio"
20-
| "checkbox"
21-
| "color"
22-
| "email"
23-
| "text"
24-
| "month"
25-
| "url"
26-
| "week"
27-
| "time"
28-
| "tel"
29-
| "range";
30-
31-
export type Serializer<T> = (currentValue: T, props: SerializeProps<T>) => boolean | string;
32-
33-
export type Deserializer<T> = (inputValue: string, inputChecked: boolean, currentValue: T, props: SerializeProps<T>) => T;
34-
35-
export type SerializeProps<V = any> = {
36-
dateAsNumber?: boolean;
37-
setUndefinedOnUncheck?: boolean;
38-
setNullOnUncheck?: boolean;
39-
type?: SerializeType;
40-
value?: V;
41-
};
42-
4314
export type FormInputValue<T extends object, K extends keyof T> = T[K] extends any[] ? T[K][keyof T[K]] : T[K];
4415

45-
export function defaultSerializer<T>(currentValue: T, props: SerializeProps<T>): boolean | string {
46-
switch (props.type) {
47-
case "datetime-local":
48-
case "date": {
49-
let dateValue = currentValue as any;
50-
if (typeof dateValue === "string") {
51-
let ni = parseInt(dateValue);
52-
if (!isNaN(ni)) dateValue = ni;
53-
}
54-
let date = new Date(dateValue);
55-
if (!isNaN(date.getTime())) {
56-
return date?.toISOString().split("T")[0] ?? "";
57-
} else {
58-
return "";
59-
}
60-
break;
61-
}
62-
case "radio": {
63-
return currentValue === props.value;
64-
}
65-
case "checkbox": {
66-
if (props.setNullOnUncheck) {
67-
return currentValue !== null;
68-
} else if (props.setUndefinedOnUncheck) {
69-
return currentValue !== undefined;
70-
} else if (props.value !== undefined) {
71-
return (Array.isArray(currentValue) ? currentValue : []).includes(props.value as never);
72-
} else {
73-
return !!currentValue;
74-
}
75-
}
76-
default: {
77-
return (currentValue ?? "") + "";
78-
}
79-
}
80-
}
81-
82-
export function defaultDeserializer<T>(inputValue: string, inputChecked: boolean, currentValue: T, props: SerializeProps<T>) {
83-
switch (props.type) {
84-
case "number": {
85-
return parseFloat(inputValue) as any;
86-
}
87-
case "datetime-local":
88-
case "date": {
89-
if (inputValue) {
90-
let d = new Date(inputValue);
91-
return (props.dateAsNumber ? d.getTime() : d) as any;
92-
} else {
93-
return null as any;
94-
}
95-
}
96-
case "radio": {
97-
// Enum field
98-
if (inputChecked) {
99-
return props.value as any;
100-
}
101-
return currentValue;
102-
}
103-
case "checkbox": {
104-
if (props.setNullOnUncheck || props.setUndefinedOnUncheck) {
105-
if (inputChecked && props.value === undefined && process.env.NODE_ENV === "development") {
106-
console.error(
107-
"Checkbox using setNullOnUncheck got checked but a value to set was not found, please provide a value to the value prop."
108-
);
109-
}
110-
return inputChecked ? props.value : ((props.setNullOnUncheck ? null : undefined) as any);
111-
} else if (props.value !== undefined) {
112-
// Primitive array field
113-
let arr = Array.isArray(currentValue) ? [...currentValue] : [];
114-
if (inputChecked) arr.push(props.value);
115-
else arr.splice(arr.indexOf(props.value), 1);
116-
return arr as any;
117-
} else {
118-
// Boolean field
119-
return inputChecked as any;
120-
}
121-
}
122-
default: {
123-
// String field
124-
return inputValue as any;
125-
}
126-
}
127-
}
128-
12916
export type InputProps = Omit<InputHTMLAttributes<HTMLInputElement>, "name" | "form" | "value" | "type">;
13017

13118
export type FormInputProps<T extends object, K extends keyof T = keyof T, State = DefaultState, Error extends string = string> = InputProps & {

src/elements/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@ export * from "./FormInput";
22
export * from "./FormSelect";
33
export * from "./FormTextArea";
44
export * from "./FormError";
5+
export * from "./serializer";
56

67
export type StyledFix<T, Props = {}> = T | ((props: Props) => JSX.Element);

src/elements/serializer.ts

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
export type SerializeType =
2+
| "number"
3+
| "text"
4+
| "password"
5+
| "date"
6+
| "datetime-local"
7+
| "radio"
8+
| "checkbox"
9+
| "color"
10+
| "email"
11+
| "text"
12+
| "month"
13+
| "url"
14+
| "week"
15+
| "time"
16+
| "tel"
17+
| "range";
18+
19+
export type Serializer<T> = (currentValue: T, props: SerializeProps<T>) => boolean | string;
20+
21+
export type Deserializer<T> = (inputValue: string, inputChecked: boolean, currentValue: T, props: SerializeProps<T>) => T;
22+
23+
export type SerializeProps<V = any> = {
24+
dateAsNumber?: boolean;
25+
setUndefinedOnUncheck?: boolean;
26+
setNullOnUncheck?: boolean;
27+
type?: SerializeType;
28+
value?: V;
29+
};
30+
31+
export function defaultSerializer<T>(currentValue: T, props: SerializeProps<T>): boolean | string {
32+
switch (props.type) {
33+
case "datetime-local":
34+
case "date": {
35+
let dateValue = currentValue as any;
36+
if (typeof dateValue === "string") {
37+
let ni = parseInt(dateValue);
38+
if (!isNaN(ni)) dateValue = ni;
39+
}
40+
let date = new Date(dateValue);
41+
if (!isNaN(date.getTime())) {
42+
return date?.toISOString().split("T")[0] ?? "";
43+
} else {
44+
return "";
45+
}
46+
}
47+
case "radio": {
48+
return currentValue === props.value;
49+
}
50+
case "checkbox": {
51+
if (props.setNullOnUncheck) {
52+
return currentValue !== null;
53+
} else if (props.setUndefinedOnUncheck) {
54+
return currentValue !== undefined;
55+
} else if (props.value !== undefined) {
56+
return (Array.isArray(currentValue) ? currentValue : []).includes(props.value as never);
57+
} else {
58+
return !!currentValue;
59+
}
60+
}
61+
default: {
62+
return (currentValue ?? "") + "";
63+
}
64+
}
65+
}
66+
67+
export function defaultDeserializer<T>(inputValue: string, inputChecked: boolean, currentValue: T, props: SerializeProps<T>) {
68+
switch (props.type) {
69+
case "number": {
70+
return parseFloat(inputValue) as any;
71+
}
72+
case "datetime-local":
73+
case "date": {
74+
if (inputValue) {
75+
let d = new Date(inputValue);
76+
return (props.dateAsNumber ? d.getTime() : d) as any;
77+
} else {
78+
return null as any;
79+
}
80+
}
81+
case "radio": {
82+
// Enum field
83+
if (inputChecked) {
84+
return props.value as any;
85+
}
86+
return currentValue;
87+
}
88+
case "checkbox": {
89+
if (props.setNullOnUncheck || props.setUndefinedOnUncheck) {
90+
if (inputChecked && props.value === undefined && process.env.NODE_ENV === "development") {
91+
console.error(
92+
"Checkbox using setNullOnUncheck got checked but a value to set was not found, please provide a value to the value prop."
93+
);
94+
}
95+
return inputChecked ? props.value : ((props.setNullOnUncheck ? null : undefined) as any);
96+
} else if (props.value !== undefined) {
97+
// Primitive array field
98+
let arr = Array.isArray(currentValue) ? [...currentValue] : [];
99+
if (inputChecked) arr.push(props.value);
100+
else arr.splice(arr.indexOf(props.value), 1);
101+
return arr as any;
102+
} else {
103+
// Boolean field
104+
return inputChecked as any;
105+
}
106+
}
107+
default: {
108+
// String field
109+
return inputValue as any;
110+
}
111+
}
112+
}

0 commit comments

Comments
 (0)