[{"data":1,"prerenderedAt":477},["ShallowReactive",2],{"content-\u002Fdocs\u002Fgetting-started\u002Fyour-first-schema":3},{"id":4,"title":5,"body":6,"description":462,"extension":463,"meta":464,"metaRows":465,"navigation":119,"path":472,"seo":473,"source":474,"stem":475,"__hash__":476},"docs\u002Fdocs\u002Fgetting-started\u002Fyour-first-schema.md","Your first schema",{"type":7,"value":8,"toc":457},"minimark",[9,13,20,23,58,63,67,72,256,266,269,331,335,363,420,423,427,453],[10,11,5],"h1",{"id":12},"your-first-schema",[14,15,16],"blockquote",{},[17,18,19],"p",{},"Any Zod schema becomes a typed, reactive Attaform.",[21,22],"docs-meta-table",{},[17,24,25,26,30,31,30,34,30,37,40,41,44,45,47,48,51,52,57],{},"Type into any of the demo's four inputs (",[27,28,29],"code",{},"email",", ",[27,32,33],{},"password",[27,35,36],{},"displayName",[27,38,39],{},"age",") and watch the live ",[27,42,43],{},"form.values"," JSON below the form update in real time. ",[27,46,43],{}," is the reactive view of the form data that ",[27,49,50],{},"useForm"," returns, paths and types straight from the schema you handed in. The ",[53,54,56],"a",{"href":55},"#what-attaform-reads","What Attaform reads"," section below traces each Zod construct in the demo to its form behavior.",[59,60],"docs-demo",{"label":61,"slug":62},"Signup Demo","first-schema",[64,65,56],"h2",{"id":66},"what-attaform-reads",[17,68,69,71],{},[27,70,50],{}," is Attaform's entry point. Hand it a Zod schema and it returns a reactive form carrying every helper a template needs: a per-input binding factory, a per-field state map, and the live parsed values. Save the return value and reach for the pieces by name:",[73,74,79],"pre",{"className":75,"code":76,"language":77,"meta":78,"style":78},"language-ts shiki shiki-themes github-light github-dark","import { useForm } from 'attaform\u002Fzod'\nimport { z } from 'zod'\n\nconst schema = z.object({\n  email: z.email(),\n  password: z.string().min(8),\n  displayName: z.string().min(2).optional(),\n  age: z.number().int().min(13),\n})\n\nconst form = useForm({ schema })\n","ts","",[27,80,81,101,114,121,144,155,179,204,229,235,240],{"__ignoreMap":78},[82,83,86,90,94,97],"span",{"class":84,"line":85},"line",1,[82,87,89],{"class":88},"szBVR","import",[82,91,93],{"class":92},"sVt8B"," { useForm } ",[82,95,96],{"class":88},"from",[82,98,100],{"class":99},"sZZnC"," 'attaform\u002Fzod'\n",[82,102,104,106,109,111],{"class":84,"line":103},2,[82,105,89],{"class":88},[82,107,108],{"class":92}," { z } ",[82,110,96],{"class":88},[82,112,113],{"class":99}," 'zod'\n",[82,115,117],{"class":84,"line":116},3,[82,118,120],{"emptyLinePlaceholder":119},true,"\n",[82,122,124,127,131,134,137,141],{"class":84,"line":123},4,[82,125,126],{"class":88},"const",[82,128,130],{"class":129},"sj4cs"," schema",[82,132,133],{"class":88}," =",[82,135,136],{"class":92}," z.",[82,138,140],{"class":139},"sScJk","object",[82,142,143],{"class":92},"({\n",[82,145,147,150,152],{"class":84,"line":146},5,[82,148,149],{"class":92},"  email: z.",[82,151,29],{"class":139},[82,153,154],{"class":92},"(),\n",[82,156,158,161,164,167,170,173,176],{"class":84,"line":157},6,[82,159,160],{"class":92},"  password: z.",[82,162,163],{"class":139},"string",[82,165,166],{"class":92},"().",[82,168,169],{"class":139},"min",[82,171,172],{"class":92},"(",[82,174,175],{"class":129},"8",[82,177,178],{"class":92},"),\n",[82,180,182,185,187,189,191,193,196,199,202],{"class":84,"line":181},7,[82,183,184],{"class":92},"  displayName: z.",[82,186,163],{"class":139},[82,188,166],{"class":92},[82,190,169],{"class":139},[82,192,172],{"class":92},[82,194,195],{"class":129},"2",[82,197,198],{"class":92},").",[82,200,201],{"class":139},"optional",[82,203,154],{"class":92},[82,205,207,210,213,215,218,220,222,224,227],{"class":84,"line":206},8,[82,208,209],{"class":92},"  age: z.",[82,211,212],{"class":139},"number",[82,214,166],{"class":92},[82,216,217],{"class":139},"int",[82,219,166],{"class":92},[82,221,169],{"class":139},[82,223,172],{"class":92},[82,225,226],{"class":129},"13",[82,228,178],{"class":92},[82,230,232],{"class":84,"line":231},9,[82,233,234],{"class":92},"})\n",[82,236,238],{"class":84,"line":237},10,[82,239,120],{"emptyLinePlaceholder":119},[82,241,243,245,248,250,253],{"class":84,"line":242},11,[82,244,126],{"class":88},[82,246,247],{"class":129}," form",[82,249,133],{"class":88},[82,251,252],{"class":139}," useForm",[82,254,255],{"class":92},"({ schema })\n",[17,257,258,259,261,262,265],{},"Object fields become reactive paths on ",[27,260,43],{},"; nested objects become nested paths; refinements become per-field validators surfaced through ",[27,263,264],{},"form.fields",".",[17,267,268],{},"The schema above covers most of what a real signup form needs:",[270,271,272,297,312],"ul",{},[273,274,275,277,278,280,281,285,286,289,290,293,294,296],"li",{},[27,276,29],{}," and ",[27,279,33],{}," are ",[282,283,284],"strong",{},"required strings",". Attaform stores ",[27,287,288],{},"''"," as the default, so ",[27,291,292],{},"form.values.email"," starts as ",[27,295,288],{}," and updates as the user types.",[273,298,299,301,302,304,305,307,308,311],{},[27,300,36],{}," is ",[282,303,201],{},". Storage still starts at ",[27,306,288],{},"; the ",[27,309,310],{},".optional()"," flag lets the field's empty string pass schema parsing at submit time.",[273,313,314,316,317,320,321,307,324,327,328,265],{},[27,315,39],{}," is a ",[282,318,319],{},"required number",". Storage starts at ",[27,322,323],{},"0",[27,325,326],{},"min(13)"," refinement runs every time the field validates and shows up on ",[27,329,330],{},"form.fields.age.errors",[64,332,334],{"id":333},"defaults-from-the-schema","Defaults from the schema",[17,336,337,338,340,341,343,344,346,347,350,351,354,355,358,359,362],{},"You don't redeclare defaults when you call ",[27,339,50],{},". Attaform reads them from the schema: ",[27,342,288],{}," for strings, ",[27,345,323],{}," for numbers, ",[27,348,349],{},"false"," for booleans, ",[27,352,353],{},"[]"," for arrays, ",[27,356,357],{},"{}"," for objects. Override per field with ",[27,360,361],{},"defaultValues",":",[73,364,366],{"className":75,"code":365,"language":77,"meta":78,"style":78},"const form = useForm({\n  schema,\n  defaultValues: {\n    age: 18,\n    displayName: 'Anonymous',\n  },\n})\n",[27,367,368,380,385,390,401,411,416],{"__ignoreMap":78},[82,369,370,372,374,376,378],{"class":84,"line":85},[82,371,126],{"class":88},[82,373,247],{"class":129},[82,375,133],{"class":88},[82,377,252],{"class":139},[82,379,143],{"class":92},[82,381,382],{"class":84,"line":103},[82,383,384],{"class":92},"  schema,\n",[82,386,387],{"class":84,"line":116},[82,388,389],{"class":92},"  defaultValues: {\n",[82,391,392,395,398],{"class":84,"line":123},[82,393,394],{"class":92},"    age: ",[82,396,397],{"class":129},"18",[82,399,400],{"class":92},",\n",[82,402,403,406,409],{"class":84,"line":146},[82,404,405],{"class":92},"    displayName: ",[82,407,408],{"class":99},"'Anonymous'",[82,410,400],{"class":92},[82,412,413],{"class":84,"line":157},[82,414,415],{"class":92},"  },\n",[82,417,418],{"class":84,"line":181},[82,419,234],{"class":92},[17,421,422],{},"Overrides are partial. Fields you don't mention pick up the schema's own default.",[64,424,426],{"id":425},"where-to-next","Where to next",[270,428,429,443],{},[273,430,431,435,436,439,440,265],{},[53,432,434],{"href":433},"\u002Fdocs\u002Fgetting-started\u002Ffrom-schema-to-inputs","From schema to inputs",": bind the schema to native inputs with ",[27,437,438],{},"register"," + ",[27,441,442],{},"v-register",[273,444,445,449,450,452],{},[53,446,448],{"href":447},"\u002Fdocs\u002Freading-the-form\u002Fthe-form","The form",": every property ",[27,451,50],{}," returns.",[454,455,456],"style",{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":78,"searchDepth":103,"depth":103,"links":458},[459,460,461],{"id":66,"depth":103,"text":56},{"id":333,"depth":103,"text":334},{"id":425,"depth":103,"text":426},"Attaform reads any Zod schema (required strings, optional fields, refinements, defaults) and turns it into a typed, reactive Attaform with no extra mapping.","md",{},[466,469],{"label":467,"value":468},"Read time","~5 minutes",{"label":470,"value":471},"Builds on","Quick start","\u002Fdocs\u002Fgetting-started\u002Fyour-first-schema",{"title":5,"description":462},null,"docs\u002Fgetting-started\u002Fyour-first-schema","ATZICl256OsfYm1UIAQLW_7dv7pqwKx6z4lHJESYwjo",1780949757353]