diff --git a/.changeset/unlucky-gorillas-learn.md b/.changeset/unlucky-gorillas-learn.md
new file mode 100644
index 0000000..c1bdde6
--- /dev/null
+++ b/.changeset/unlucky-gorillas-learn.md
@@ -0,0 +1,5 @@
+---
+"simple-stack-form": patch
+---
+
+Add `min` and `max` input props to number input if present on schema
diff --git a/examples/playground/src/components/react/Signup.tsx b/examples/playground/src/components/react/Signup.tsx
index e0bf8a2..091da02 100644
--- a/examples/playground/src/components/react/Signup.tsx
+++ b/examples/playground/src/components/react/Signup.tsx
@@ -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(),
});
@@ -35,6 +36,10 @@ export default function Signup({
+
+
+
+
diff --git a/packages/form/src/module.ts b/packages/form/src/module.ts
index 2dbf6dc..77b51fe 100644
--- a/packages/form/src/module.ts
+++ b/packages/form/src/module.ts
@@ -3,7 +3,6 @@ import {
ZodArray,
ZodBoolean,
type ZodError,
- ZodLiteral,
ZodNullable,
ZodNumber,
ZodObject,
@@ -11,7 +10,6 @@ import {
type ZodRawShape,
ZodString,
type ZodType,
- ZodUnion,
z,
} from "zod";
@@ -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",
@@ -207,11 +207,15 @@ function getInputProp(
fieldValidator: T,
name: string | number | symbol,
) {
+ const inputInfo = getInputInfo(fieldValidator);
+
const inputProp: InputProp = {
name: String(name),
"aria-required":
!fieldValidator.isOptional() && !fieldValidator.isNullable(),
- type: getInputInfo(fieldValidator).type,
+ type: inputInfo.type,
+ min: inputInfo.min,
+ max: inputInfo.max,
};
return inputProp;
@@ -240,6 +244,8 @@ function getInputInfo(fieldValidator: T): {
type: InputProp["type"];
isArray: boolean;
isOptional: boolean;
+ min?: number;
+ max?: number;
} {
let resolvedType = fieldValidator;
let isArray = false;
@@ -261,7 +267,20 @@ function getInputInfo(fieldValidator: T): {
const type = getInputType(resolvedType);
- return { type, isArray, isOptional };
+ const result: ReturnType = { 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({