Skip to content

Commit

Permalink
Merge pull request #40 from dsnjunior/feat/generate-min-and-max
Browse files Browse the repository at this point in the history
`min` and `max` number input props
  • Loading branch information
bholmesdev authored Jan 23, 2024
2 parents 8e993bb + 23cb93c commit 4243727
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 6 deletions.
5 changes: 5 additions & 0 deletions .changeset/unlucky-gorillas-learn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"simple-stack-form": patch
---

Add `min` and `max` input props to number input if present on schema
5 changes: 5 additions & 0 deletions examples/playground/src/components/react/Signup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export const signup = createForm({
return s !== "admin";
}),
email: z.string().email().optional(),
coffees: z.number().lt(10).min(2),
optIn: z.boolean().optional(),
});

Expand All @@ -35,6 +36,10 @@ export default function Signup({
<label htmlFor={scope("email")}>Email</label>
<Input id={scope("email")} {...signup.inputProps.email} />
</FormGroup>
<FormGroup>
<label htmlFor={scope("coffees")}>Coffees taken</label>
<Input id={scope("coffees")} {...signup.inputProps.coffees} />
</FormGroup>
<FormGroup>
<label htmlFor={scope("optIn")}>Opt in</label>
<Input id={scope("optIn")} {...signup.inputProps.optIn} />
Expand Down
31 changes: 25 additions & 6 deletions packages/form/src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,13 @@ import {
ZodArray,
ZodBoolean,
type ZodError,
ZodLiteral,
ZodNullable,
ZodNumber,
ZodObject,
ZodOptional,
type ZodRawShape,
ZodString,
type ZodType,
ZodUnion,
z,
} from "zod";

Expand All @@ -23,8 +21,10 @@ export type FieldErrors<
export type InputProp = {
"aria-required": boolean;
name: string;
type: "text" | "number" | "checkbox" | "email";
};
} & (
| { type: "text" | "checkbox" | "email" }
| { type: "number"; min?: number; max?: number }
);

export const formNameInputProps = {
type: "hidden",
Expand Down Expand Up @@ -207,11 +207,15 @@ function getInputProp<T extends ZodType>(
fieldValidator: T,
name: string | number | symbol,
) {
const inputInfo = getInputInfo<T>(fieldValidator);

const inputProp: InputProp = {
name: String(name),
"aria-required":
!fieldValidator.isOptional() && !fieldValidator.isNullable(),
type: getInputInfo<T>(fieldValidator).type,
type: inputInfo.type,
min: inputInfo.min,
max: inputInfo.max,
};

return inputProp;
Expand Down Expand Up @@ -240,6 +244,8 @@ function getInputInfo<T extends ZodType>(fieldValidator: T): {
type: InputProp["type"];
isArray: boolean;
isOptional: boolean;
min?: number;
max?: number;
} {
let resolvedType = fieldValidator;
let isArray = false;
Expand All @@ -261,7 +267,20 @@ function getInputInfo<T extends ZodType>(fieldValidator: T): {

const type = getInputType(resolvedType);

return { type, isArray, isOptional };
const result: ReturnType<typeof getInputInfo> = { type, isArray, isOptional };

if (type === "number" && resolvedType instanceof ZodNumber) {
for (const check of resolvedType._def.checks) {
if (check.kind === "min") {
result.min = check.value + (check.inclusive ? 0 : 1);
}
if (check.kind === "max") {
result.max = check.value - (check.inclusive ? 0 : 1);
}
}
}

return result;
}

export async function validateForm<T extends ZodRawShape>({
Expand Down

0 comments on commit 4243727

Please sign in to comment.