[{"data":1,"prerenderedAt":619},["ShallowReactive",2],{"content-\u002Fdocs\u002Fbinding-inputs\u002Ffile":3},{"id":4,"title":5,"body":6,"description":598,"extension":599,"meta":600,"metaRows":601,"navigation":212,"path":614,"seo":615,"source":616,"stem":617,"__hash__":618},"docs\u002Fdocs\u002Fbinding-inputs\u002Ffile.md","File inputs",{"type":7,"value":8,"toc":591},"minimark",[9,13,33,36,50,55,60,129,224,233,239,280,346,349,353,359,503,525,529,550,554,587],[10,11,5],"h1",{"id":12},"file-inputs",[14,15,16],"blockquote",{},[17,18,19,20,24,25,28,29,32],"p",{},"Single file → ",[21,22,23],"code",{},"File | null",". Multiple → ",[21,26,27],{},"readonly File[]",". Live handles, ready for ",[21,30,31],{},"FormData"," or your upload pipeline.",[34,35],"docs-meta-table",{},[17,37,38,39,42,43,46,47,49],{},"Pick a file in the single input to watch the avatar slot fill in with the file name + size. Pick more in the multi-input below to see them stack; the directive writes a ",[21,40,41],{},"File[]"," in the order the picker returned them. Both surfaces hand you live ",[21,44,45],{},"File"," handles you can append to ",[21,48,31],{}," or stream into an upload.",[51,52],"docs-demo",{"label":53,"slug":54},"File Input Demo","file",[56,57,59],"h2",{"id":58},"single-file-file-null","Single file → File | null",[61,62,67],"pre",{"className":63,"code":64,"language":65,"meta":66,"style":66},"language-vue shiki shiki-themes github-light github-dark","\u003Cinput v-register=\"form.register('avatar')\" type=\"file\" accept=\"image\u002F*\" \u002F>\n","vue","",[21,68,69],{"__ignoreMap":66},[70,71,74,78,82,86,89,93,96,99,102,105,108,110,113,115,118,121,123,126],"span",{"class":72,"line":73},"line",1,[70,75,77],{"class":76},"sVt8B","\u003C",[70,79,81],{"class":80},"s9eBZ","input",[70,83,85],{"class":84},"sScJk"," v-register",[70,87,88],{"class":76},"=",[70,90,92],{"class":91},"sZZnC","\"",[70,94,95],{"class":76},"form.",[70,97,98],{"class":84},"register",[70,100,101],{"class":76},"(",[70,103,104],{"class":91},"'avatar'",[70,106,107],{"class":76},")",[70,109,92],{"class":91},[70,111,112],{"class":84}," type",[70,114,88],{"class":76},[70,116,117],{"class":91},"\"file\"",[70,119,120],{"class":84}," accept",[70,122,88],{"class":76},[70,124,125],{"class":91},"\"image\u002F*\"",[70,127,128],{"class":76}," \u002F>\n",[61,130,134],{"className":131,"code":132,"language":133,"meta":66,"style":66},"language-ts shiki shiki-themes github-light github-dark","const form = useForm({\n  schema: z.object({\n    avatar: z.file().nullable(),\n  }),\n  defaultValues: { avatar: null },\n})\n\nform.values.avatar \u002F\u002F File | null\n","ts",[21,135,136,155,166,183,189,201,207,214],{"__ignoreMap":66},[70,137,138,142,146,149,152],{"class":72,"line":73},[70,139,141],{"class":140},"szBVR","const",[70,143,145],{"class":144},"sj4cs"," form",[70,147,148],{"class":140}," =",[70,150,151],{"class":84}," useForm",[70,153,154],{"class":76},"({\n",[70,156,158,161,164],{"class":72,"line":157},2,[70,159,160],{"class":76},"  schema: z.",[70,162,163],{"class":84},"object",[70,165,154],{"class":76},[70,167,169,172,174,177,180],{"class":72,"line":168},3,[70,170,171],{"class":76},"    avatar: z.",[70,173,54],{"class":84},[70,175,176],{"class":76},"().",[70,178,179],{"class":84},"nullable",[70,181,182],{"class":76},"(),\n",[70,184,186],{"class":72,"line":185},4,[70,187,188],{"class":76},"  }),\n",[70,190,192,195,198],{"class":72,"line":191},5,[70,193,194],{"class":76},"  defaultValues: { avatar: ",[70,196,197],{"class":144},"null",[70,199,200],{"class":76}," },\n",[70,202,204],{"class":72,"line":203},6,[70,205,206],{"class":76},"})\n",[70,208,210],{"class":72,"line":209},7,[70,211,213],{"emptyLinePlaceholder":212},true,"\n",[70,215,217,220],{"class":72,"line":216},8,[70,218,219],{"class":76},"form.values.avatar ",[70,221,223],{"class":222},"sJ8bj","\u002F\u002F File | null\n",[17,225,226,227,229,230,232],{},"Selecting a file writes the ",[21,228,45],{}," handle into storage. Clearing the input (or selecting then cancelling) writes ",[21,231,197],{},".",[56,234,236,237],{"id":235},"multiple-files-file","Multiple files → File",[70,238],{},[61,240,242],{"className":63,"code":241,"language":65,"meta":66,"style":66},"\u003Cinput v-register=\"form.register('attachments')\" type=\"file\" multiple \u002F>\n",[21,243,244],{"__ignoreMap":66},[70,245,246,248,250,252,254,256,258,260,262,265,267,269,271,273,275,278],{"class":72,"line":73},[70,247,77],{"class":76},[70,249,81],{"class":80},[70,251,85],{"class":84},[70,253,88],{"class":76},[70,255,92],{"class":91},[70,257,95],{"class":76},[70,259,98],{"class":84},[70,261,101],{"class":76},[70,263,264],{"class":91},"'attachments'",[70,266,107],{"class":76},[70,268,92],{"class":91},[70,270,112],{"class":84},[70,272,88],{"class":76},[70,274,117],{"class":91},[70,276,277],{"class":84}," multiple",[70,279,128],{"class":76},[61,281,283],{"className":131,"code":282,"language":133,"meta":66,"style":66},"const form = useForm({\n  schema: z.object({\n    attachments: z.array(z.file()),\n  }),\n  defaultValues: { attachments: [] },\n})\n\nform.values.attachments \u002F\u002F readonly File[]\n",[21,284,285,297,305,321,325,330,334,338],{"__ignoreMap":66},[70,286,287,289,291,293,295],{"class":72,"line":73},[70,288,141],{"class":140},[70,290,145],{"class":144},[70,292,148],{"class":140},[70,294,151],{"class":84},[70,296,154],{"class":76},[70,298,299,301,303],{"class":72,"line":157},[70,300,160],{"class":76},[70,302,163],{"class":84},[70,304,154],{"class":76},[70,306,307,310,313,316,318],{"class":72,"line":168},[70,308,309],{"class":76},"    attachments: z.",[70,311,312],{"class":84},"array",[70,314,315],{"class":76},"(z.",[70,317,54],{"class":84},[70,319,320],{"class":76},"()),\n",[70,322,323],{"class":72,"line":185},[70,324,188],{"class":76},[70,326,327],{"class":72,"line":191},[70,328,329],{"class":76},"  defaultValues: { attachments: [] },\n",[70,331,332],{"class":72,"line":203},[70,333,206],{"class":76},[70,335,336],{"class":72,"line":209},[70,337,213],{"emptyLinePlaceholder":212},[70,339,340,343],{"class":72,"line":216},[70,341,342],{"class":76},"form.values.attachments ",[70,344,345],{"class":222},"\u002F\u002F readonly File[]\n",[17,347,348],{},"Every file in the picker selection lands in the array, in picker order. Re-selecting replaces the array; the input never accumulates across picks.",[56,350,352],{"id":351},"uploading-via-formdata","Uploading via FormData",[17,354,355,356,358],{},"Live ",[21,357,45],{}," handles work directly with the upload pipelines you'd reach for anyway:",[61,360,362],{"className":131,"code":361,"language":133,"meta":66,"style":66},"const onSubmit = form.handleSubmit(async (values) => {\n  const body = new FormData()\n  body.append('avatar', values.avatar!)\n  for (const file of values.attachments) {\n    body.append('attachments', file)\n  }\n  await fetch('\u002Fapi\u002Fupload', { method: 'POST', body })\n})\n",[21,363,364,400,419,440,458,472,477,499],{"__ignoreMap":66},[70,365,366,368,371,373,376,379,381,384,387,391,394,397],{"class":72,"line":73},[70,367,141],{"class":140},[70,369,370],{"class":144}," onSubmit",[70,372,148],{"class":140},[70,374,375],{"class":76}," form.",[70,377,378],{"class":84},"handleSubmit",[70,380,101],{"class":76},[70,382,383],{"class":140},"async",[70,385,386],{"class":76}," (",[70,388,390],{"class":389},"s4XuR","values",[70,392,393],{"class":76},") ",[70,395,396],{"class":140},"=>",[70,398,399],{"class":76}," {\n",[70,401,402,405,408,410,413,416],{"class":72,"line":157},[70,403,404],{"class":140},"  const",[70,406,407],{"class":144}," body",[70,409,148],{"class":140},[70,411,412],{"class":140}," new",[70,414,415],{"class":84}," FormData",[70,417,418],{"class":76},"()\n",[70,420,421,424,427,429,431,434,437],{"class":72,"line":168},[70,422,423],{"class":76},"  body.",[70,425,426],{"class":84},"append",[70,428,101],{"class":76},[70,430,104],{"class":91},[70,432,433],{"class":76},", values.avatar",[70,435,436],{"class":140},"!",[70,438,439],{"class":76},")\n",[70,441,442,445,447,449,452,455],{"class":72,"line":185},[70,443,444],{"class":140},"  for",[70,446,386],{"class":76},[70,448,141],{"class":140},[70,450,451],{"class":144}," file",[70,453,454],{"class":140}," of",[70,456,457],{"class":76}," values.attachments) {\n",[70,459,460,463,465,467,469],{"class":72,"line":191},[70,461,462],{"class":76},"    body.",[70,464,426],{"class":84},[70,466,101],{"class":76},[70,468,264],{"class":91},[70,470,471],{"class":76},", file)\n",[70,473,474],{"class":72,"line":203},[70,475,476],{"class":76},"  }\n",[70,478,479,482,485,487,490,493,496],{"class":72,"line":209},[70,480,481],{"class":140},"  await",[70,483,484],{"class":84}," fetch",[70,486,101],{"class":76},[70,488,489],{"class":91},"'\u002Fapi\u002Fupload'",[70,491,492],{"class":76},", { method: ",[70,494,495],{"class":91},"'POST'",[70,497,498],{"class":76},", body })\n",[70,500,501],{"class":72,"line":216},[70,502,206],{"class":76},[17,504,505,506,509,510,513,514,513,517,520,521,524],{},"The schema's ",[21,507,508],{},"z.file()"," leaf type carries the constraint through validation; refinements like ",[21,511,512],{},".min(size)",", ",[21,515,516],{},".max(size)",[21,518,519],{},".mime([...])"," surface in ",[21,522,523],{},"form.errors.\u003Cpath>"," like any other validator.",[56,526,528],{"id":527},"reset-behavior","Reset behavior",[17,530,531,534,535,537,538,541,542,545,546,549],{},[21,532,533],{},"form.reset()"," clears the file input back to ",[21,536,197],{}," \u002F ",[21,539,540],{},"[]",". The directive also resets the underlying ",[21,543,544],{},"\u003Cinput>","'s ",[21,547,548],{},"value"," attribute, so the picker shows \"No file chosen\" after the reset, no stale filename hanging around.",[56,551,553],{"id":552},"where-to-next","Where to next",[555,556,557,572,579],"ul",{},[558,559,560,571],"li",{},[561,562,564,567,568],"a",{"href":563},"\u002Fdocs\u002Fwriting-and-mutating\u002Freset",[21,565,566],{},"reset"," & ",[21,569,570],{},"resetField",": programmatic clearing.",[558,573,574,578],{},[561,575,577],{"href":576},"\u002Fdocs\u002Fbinding-inputs\u002Fcoercion","Schema-driven coercion",": how File leaves move through the directive.",[558,580,581,586],{},[561,582,584],{"href":583},"\u002Fdocs\u002Fsubmitting\u002Fhandle-submit",[21,585,378],{},": wraps your upload callback in the validation gate.",[588,589,590],"style",{},"html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}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);}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":66,"searchDepth":157,"depth":157,"links":592},[593,594,595,596,597],{"id":58,"depth":157,"text":59},{"id":235,"depth":157,"text":236},{"id":351,"depth":157,"text":352},{"id":527,"depth":157,"text":528},{"id":552,"depth":157,"text":553},"\u003Cinput type=\"file\"> binds to a single File (or null when empty); type=\"file\" multiple binds to a File[]. Live File handles, ready for FormData or upload.","md",{},[602,605,608,611],{"label":603,"value":604},"Category","Directive binding",{"label":606,"value":607,"kind":21},"Element","\u003Cinput type=\"file\"> · \u003Cinput type=\"file\" multiple>",{"label":609,"value":610},"Modifiers","none",{"label":612,"value":613,"kind":21},"Leaf types","File | null (single) · readonly File[] (multiple)","\u002Fdocs\u002Fbinding-inputs\u002Ffile",{"title":5,"description":598},null,"docs\u002Fbinding-inputs\u002Ffile","93HXopZMcKDpDDWFmimvff1Fb9s1xHOLg3OdCYIIWQk",1780949759370]