[{"data":1,"prerenderedAt":1538},["ShallowReactive",2],{"navigation":3,"$fd9cvft0wf4ga":460,"\u002Fdocs\u002Fforms\u002Fformisch":473,"surround-\u002Fdocs\u002Fforms\u002Fformisch":1532},[4],{"title":5,"path":6,"stem":7,"children":8,"page":18},"Docs","\u002Fdocs","docs",[9,294,320,338,344,361,387,400],{"title":10,"path":11,"stem":12,"children":13,"new":18,"type":293},"Components","\u002Fdocs\u002Fcomponents","docs\u002F02.components",[14,20,24,28,32,37,41,45,49,53,57,61,65,69,73,77,81,85,89,93,97,101,105,109,113,117,121,125,129,133,137,141,145,149,153,157,161,165,169,173,177,181,185,189,193,197,201,205,209,213,217,221,225,229,233,237,241,245,249,253,257,261,265,269,273,277,281,285,289],{"title":15,"path":16,"stem":17,"new":18,"type":19,"children":-1},"Accordion","\u002Fdocs\u002Fcomponents\u002Faccordion","docs\u002Fcomponents\u002Faccordion",false,"component",{"title":21,"path":22,"stem":23,"new":18,"type":19,"children":-1},"Alert","\u002Fdocs\u002Fcomponents\u002Falert","docs\u002Fcomponents\u002Falert",{"title":25,"path":26,"stem":27,"new":18,"type":19,"children":-1},"Alert Dialog","\u002Fdocs\u002Fcomponents\u002Falert-dialog","docs\u002Fcomponents\u002Falert-dialog",{"title":29,"path":30,"stem":31,"new":18,"type":19,"children":-1},"Aspect Ratio","\u002Fdocs\u002Fcomponents\u002Faspect-ratio","docs\u002Fcomponents\u002Faspect-ratio",{"title":33,"path":34,"stem":35,"new":36,"type":19,"children":-1},"Attachment","\u002Fdocs\u002Fcomponents\u002Fattachment","docs\u002Fcomponents\u002Fattachment",true,{"title":38,"path":39,"stem":40,"new":18,"type":19,"children":-1},"Avatar","\u002Fdocs\u002Fcomponents\u002Favatar","docs\u002Fcomponents\u002Favatar",{"title":42,"path":43,"stem":44,"new":18,"type":19,"children":-1},"Badge","\u002Fdocs\u002Fcomponents\u002Fbadge","docs\u002Fcomponents\u002Fbadge",{"title":46,"path":47,"stem":48,"new":18,"type":19,"children":-1},"Breadcrumb","\u002Fdocs\u002Fcomponents\u002Fbreadcrumb","docs\u002Fcomponents\u002Fbreadcrumb",{"title":50,"path":51,"stem":52,"new":36,"type":19,"children":-1},"Bubble","\u002Fdocs\u002Fcomponents\u002Fbubble","docs\u002Fcomponents\u002Fbubble",{"title":54,"path":55,"stem":56,"new":18,"type":19,"children":-1},"Button","\u002Fdocs\u002Fcomponents\u002Fbutton","docs\u002Fcomponents\u002Fbutton",{"title":58,"path":59,"stem":60,"new":18,"type":19,"children":-1},"Button Group","\u002Fdocs\u002Fcomponents\u002Fbutton-group","docs\u002Fcomponents\u002Fbutton-group",{"title":62,"path":63,"stem":64,"new":18,"type":19,"children":-1},"Calendar","\u002Fdocs\u002Fcomponents\u002Fcalendar","docs\u002Fcomponents\u002Fcalendar",{"title":66,"path":67,"stem":68,"new":18,"type":19,"children":-1},"Card","\u002Fdocs\u002Fcomponents\u002Fcard","docs\u002Fcomponents\u002Fcard",{"title":70,"path":71,"stem":72,"new":18,"type":19,"children":-1},"Carousel","\u002Fdocs\u002Fcomponents\u002Fcarousel","docs\u002Fcomponents\u002Fcarousel",{"title":74,"path":75,"stem":76,"new":18,"type":19,"children":-1},"Chart","\u002Fdocs\u002Fcomponents\u002Fchart","docs\u002Fcomponents\u002Fchart",{"title":78,"path":79,"stem":80,"new":18,"type":19,"children":-1},"Checkbox","\u002Fdocs\u002Fcomponents\u002Fcheckbox","docs\u002Fcomponents\u002Fcheckbox",{"title":82,"path":83,"stem":84,"new":18,"type":19,"children":-1},"Collapsible","\u002Fdocs\u002Fcomponents\u002Fcollapsible","docs\u002Fcomponents\u002Fcollapsible",{"title":86,"path":87,"stem":88,"new":18,"type":19,"children":-1},"Combobox","\u002Fdocs\u002Fcomponents\u002Fcombobox","docs\u002Fcomponents\u002Fcombobox",{"title":90,"path":91,"stem":92,"new":18,"type":19,"children":-1},"Command","\u002Fdocs\u002Fcomponents\u002Fcommand","docs\u002Fcomponents\u002Fcommand",{"title":94,"path":95,"stem":96,"new":18,"type":19,"children":-1},"Context Menu","\u002Fdocs\u002Fcomponents\u002Fcontext-menu","docs\u002Fcomponents\u002Fcontext-menu",{"title":98,"path":99,"stem":100,"new":18,"type":19,"children":-1},"Data Table","\u002Fdocs\u002Fcomponents\u002Fdata-table","docs\u002Fcomponents\u002Fdata-table",{"title":102,"path":103,"stem":104,"new":18,"type":19,"children":-1},"Date Picker","\u002Fdocs\u002Fcomponents\u002Fdate-picker","docs\u002Fcomponents\u002Fdate-picker",{"title":106,"path":107,"stem":108,"new":18,"type":19,"children":-1},"Dialog","\u002Fdocs\u002Fcomponents\u002Fdialog","docs\u002Fcomponents\u002Fdialog",{"title":110,"path":111,"stem":112,"new":18,"type":19,"children":-1},"Drawer","\u002Fdocs\u002Fcomponents\u002Fdrawer","docs\u002Fcomponents\u002Fdrawer",{"title":114,"path":115,"stem":116,"new":18,"type":19,"children":-1},"Dropdown Menu","\u002Fdocs\u002Fcomponents\u002Fdropdown-menu","docs\u002Fcomponents\u002Fdropdown-menu",{"title":118,"path":119,"stem":120,"new":18,"type":19,"children":-1},"Empty","\u002Fdocs\u002Fcomponents\u002Fempty","docs\u002Fcomponents\u002Fempty",{"title":122,"path":123,"stem":124,"new":18,"type":19,"children":-1},"Field","\u002Fdocs\u002Fcomponents\u002Ffield","docs\u002Fcomponents\u002Ffield",{"title":126,"path":127,"stem":128,"new":18,"type":19,"children":-1},"Form","\u002Fdocs\u002Fcomponents\u002Fform","docs\u002Fcomponents\u002Fform",{"title":130,"path":131,"stem":132,"new":18,"type":19,"children":-1},"Hover Card","\u002Fdocs\u002Fcomponents\u002Fhover-card","docs\u002Fcomponents\u002Fhover-card",{"title":134,"path":135,"stem":136,"new":18,"type":19,"children":-1},"Input","\u002Fdocs\u002Fcomponents\u002Finput","docs\u002Fcomponents\u002Finput",{"title":138,"path":139,"stem":140,"new":18,"type":19,"children":-1},"Input Group","\u002Fdocs\u002Fcomponents\u002Finput-group","docs\u002Fcomponents\u002Finput-group",{"title":142,"path":143,"stem":144,"new":18,"type":19,"children":-1},"Input OTP","\u002Fdocs\u002Fcomponents\u002Finput-otp","docs\u002Fcomponents\u002Finput-otp",{"title":146,"path":147,"stem":148,"new":18,"type":19,"children":-1},"Item","\u002Fdocs\u002Fcomponents\u002Fitem","docs\u002Fcomponents\u002Fitem",{"title":150,"path":151,"stem":152,"new":18,"type":19,"children":-1},"Kbd","\u002Fdocs\u002Fcomponents\u002Fkbd","docs\u002Fcomponents\u002Fkbd",{"title":154,"path":155,"stem":156,"new":18,"type":19,"children":-1},"Label","\u002Fdocs\u002Fcomponents\u002Flabel","docs\u002Fcomponents\u002Flabel",{"title":158,"path":159,"stem":160,"new":36,"type":19,"children":-1},"Marker","\u002Fdocs\u002Fcomponents\u002Fmarker","docs\u002Fcomponents\u002Fmarker",{"title":162,"path":163,"stem":164,"new":18,"type":19,"children":-1},"Menubar","\u002Fdocs\u002Fcomponents\u002Fmenubar","docs\u002Fcomponents\u002Fmenubar",{"title":166,"path":167,"stem":168,"new":36,"type":19,"children":-1},"Message","\u002Fdocs\u002Fcomponents\u002Fmessage","docs\u002Fcomponents\u002Fmessage",{"title":170,"path":171,"stem":172,"new":36,"type":19,"children":-1},"Message Scroller","\u002Fdocs\u002Fcomponents\u002Fmessage-scroller","docs\u002Fcomponents\u002Fmessage-scroller",{"title":174,"path":175,"stem":176,"new":18,"type":19,"children":-1},"Native Select","\u002Fdocs\u002Fcomponents\u002Fnative-select","docs\u002Fcomponents\u002Fnative-select",{"title":178,"path":179,"stem":180,"new":18,"type":19,"children":-1},"Navigation Menu","\u002Fdocs\u002Fcomponents\u002Fnavigation-menu","docs\u002Fcomponents\u002Fnavigation-menu",{"title":182,"path":183,"stem":184,"new":18,"type":19,"children":-1},"Number Field","\u002Fdocs\u002Fcomponents\u002Fnumber-field","docs\u002Fcomponents\u002Fnumber-field",{"title":186,"path":187,"stem":188,"new":18,"type":19,"children":-1},"Pagination","\u002Fdocs\u002Fcomponents\u002Fpagination","docs\u002Fcomponents\u002Fpagination",{"title":190,"path":191,"stem":192,"new":18,"type":19,"children":-1},"Pin Input","\u002Fdocs\u002Fcomponents\u002Fpin-input","docs\u002Fcomponents\u002Fpin-input",{"title":194,"path":195,"stem":196,"new":18,"type":19,"children":-1},"Popover","\u002Fdocs\u002Fcomponents\u002Fpopover","docs\u002Fcomponents\u002Fpopover",{"title":198,"path":199,"stem":200,"new":18,"type":19,"children":-1},"Progress","\u002Fdocs\u002Fcomponents\u002Fprogress","docs\u002Fcomponents\u002Fprogress",{"title":202,"path":203,"stem":204,"new":18,"type":19,"children":-1},"Radio Group","\u002Fdocs\u002Fcomponents\u002Fradio-group","docs\u002Fcomponents\u002Fradio-group",{"title":206,"path":207,"stem":208,"new":18,"type":19,"children":-1},"Range Calendar","\u002Fdocs\u002Fcomponents\u002Frange-calendar","docs\u002Fcomponents\u002Frange-calendar",{"title":210,"path":211,"stem":212,"new":18,"type":19,"children":-1},"Resizable","\u002Fdocs\u002Fcomponents\u002Fresizable","docs\u002Fcomponents\u002Fresizable",{"title":214,"path":215,"stem":216,"new":18,"type":19,"children":-1},"Scroll Area","\u002Fdocs\u002Fcomponents\u002Fscroll-area","docs\u002Fcomponents\u002Fscroll-area",{"title":218,"path":219,"stem":220,"new":18,"type":19,"children":-1},"Select","\u002Fdocs\u002Fcomponents\u002Fselect","docs\u002Fcomponents\u002Fselect",{"title":222,"path":223,"stem":224,"new":18,"type":19,"children":-1},"Separator","\u002Fdocs\u002Fcomponents\u002Fseparator","docs\u002Fcomponents\u002Fseparator",{"title":226,"path":227,"stem":228,"new":18,"type":19,"children":-1},"Sheet","\u002Fdocs\u002Fcomponents\u002Fsheet","docs\u002Fcomponents\u002Fsheet",{"title":230,"path":231,"stem":232,"new":18,"type":19,"children":-1},"Sidebar","\u002Fdocs\u002Fcomponents\u002Fsidebar","docs\u002Fcomponents\u002Fsidebar",{"title":234,"path":235,"stem":236,"new":18,"type":19,"children":-1},"Skeleton","\u002Fdocs\u002Fcomponents\u002Fskeleton","docs\u002Fcomponents\u002Fskeleton",{"title":238,"path":239,"stem":240,"new":18,"type":19,"children":-1},"Slider","\u002Fdocs\u002Fcomponents\u002Fslider","docs\u002Fcomponents\u002Fslider",{"title":242,"path":243,"stem":244,"new":18,"type":19,"children":-1},"Sonner","\u002Fdocs\u002Fcomponents\u002Fsonner","docs\u002Fcomponents\u002Fsonner",{"title":246,"path":247,"stem":248,"new":18,"type":19,"children":-1},"Spinner","\u002Fdocs\u002Fcomponents\u002Fspinner","docs\u002Fcomponents\u002Fspinner",{"title":250,"path":251,"stem":252,"new":18,"type":19,"children":-1},"Stepper","\u002Fdocs\u002Fcomponents\u002Fstepper","docs\u002Fcomponents\u002Fstepper",{"title":254,"path":255,"stem":256,"new":18,"type":19,"children":-1},"Switch","\u002Fdocs\u002Fcomponents\u002Fswitch","docs\u002Fcomponents\u002Fswitch",{"title":258,"path":259,"stem":260,"new":18,"type":19,"children":-1},"Table","\u002Fdocs\u002Fcomponents\u002Ftable","docs\u002Fcomponents\u002Ftable",{"title":262,"path":263,"stem":264,"new":18,"type":19,"children":-1},"Tabs","\u002Fdocs\u002Fcomponents\u002Ftabs","docs\u002Fcomponents\u002Ftabs",{"title":266,"path":267,"stem":268,"new":18,"type":19,"children":-1},"Tags Input","\u002Fdocs\u002Fcomponents\u002Ftags-input","docs\u002Fcomponents\u002Ftags-input",{"title":270,"path":271,"stem":272,"new":18,"type":19,"children":-1},"Textarea","\u002Fdocs\u002Fcomponents\u002Ftextarea","docs\u002Fcomponents\u002Ftextarea",{"title":274,"path":275,"stem":276,"new":18,"type":19,"children":-1},"Toast","\u002Fdocs\u002Fcomponents\u002Ftoast","docs\u002Fcomponents\u002Ftoast",{"title":278,"path":279,"stem":280,"new":18,"type":19,"children":-1},"Toggle","\u002Fdocs\u002Fcomponents\u002Ftoggle","docs\u002Fcomponents\u002Ftoggle",{"title":282,"path":283,"stem":284,"new":18,"type":19,"children":-1},"Toggle Group","\u002Fdocs\u002Fcomponents\u002Ftoggle-group","docs\u002Fcomponents\u002Ftoggle-group",{"title":286,"path":287,"stem":288,"new":18,"type":19,"children":-1},"Tooltip","\u002Fdocs\u002Fcomponents\u002Ftooltip","docs\u002Fcomponents\u002Ftooltip",{"title":290,"path":291,"stem":292,"new":18,"type":19,"children":-1},"Typography","\u002Fdocs\u002Fcomponents\u002Ftypography","docs\u002Fcomponents\u002Ftypography","group",{"title":295,"path":296,"stem":297,"children":298,"new":18,"type":293},"Installation","\u002Fdocs\u002Finstallation","docs\u002F02.installation",[299,304,308,312,316],{"title":300,"path":301,"stem":302,"new":18,"type":303,"children":-1},"Vite","\u002Fdocs\u002Finstallation\u002Fvite","docs\u002Finstallation\u002F01.vite","page",{"title":305,"path":306,"stem":307,"new":18,"type":303,"children":-1},"Nuxt","\u002Fdocs\u002Finstallation\u002Fnuxt","docs\u002Finstallation\u002F02.nuxt",{"title":309,"path":310,"stem":311,"new":18,"type":303,"children":-1},"Astro","\u002Fdocs\u002Finstallation\u002Fastro","docs\u002Finstallation\u002F03.astro",{"title":313,"path":314,"stem":315,"new":18,"type":303,"children":-1},"Laravel","\u002Fdocs\u002Finstallation\u002Flaravel","docs\u002Finstallation\u002F04.laravel",{"title":317,"path":318,"stem":319,"new":18,"type":303,"children":-1},"Manual Installation","\u002Fdocs\u002Finstallation\u002Fmanual","docs\u002Finstallation\u002F05.manual",{"title":321,"path":322,"stem":323,"children":324,"new":18,"type":293},"Dark Mode","\u002Fdocs\u002Fdark-mode","docs\u002F05.dark-mode",[325,328,331,335],{"title":300,"path":326,"stem":327,"new":18,"type":303,"children":-1},"\u002Fdocs\u002Fdark-mode\u002Fvite","docs\u002Fdark-mode\u002F01.vite",{"title":305,"path":329,"stem":330,"new":18,"type":303,"children":-1},"\u002Fdocs\u002Fdark-mode\u002Fnuxt","docs\u002Fdark-mode\u002F02.nuxt",{"title":332,"path":333,"stem":334,"new":18,"type":303,"children":-1},"Vitepress","\u002Fdocs\u002Fdark-mode\u002Fvitepress","docs\u002Fdark-mode\u002F03.vitepress",{"title":309,"path":336,"stem":337,"new":18,"type":303,"children":-1},"\u002Fdocs\u002Fdark-mode\u002Fastro","docs\u002Fdark-mode\u002F04.astro",{"title":339,"path":340,"stem":341,"children":342,"new":18,"type":293},"Directory","\u002Fdocs\u002Fdirectory","docs\u002Fdirectory\u002Findex",[343],{"title":339,"path":340,"stem":341,"new":18,"type":303,"children":-1},{"title":345,"path":346,"stem":347,"children":348,"new":18,"type":293},"Forms","\u002Fdocs\u002Fforms","docs\u002Fforms",[349,353,357],{"title":350,"path":351,"stem":352,"new":18,"type":303,"children":-1},"VeeValidate","\u002Fdocs\u002Fforms\u002Fvee-validate","docs\u002Fforms\u002F01.vee-validate",{"title":354,"path":355,"stem":356,"new":18,"type":303,"children":-1},"TanStack Form","\u002Fdocs\u002Fforms\u002Ftanstack-form","docs\u002Fforms\u002F02.tanstack-form",{"title":358,"path":359,"stem":360,"new":18,"type":303,"children":-1},"Formisch","\u002Fdocs\u002Fforms\u002Fformisch","docs\u002Fforms\u002F03.formisch",{"title":362,"path":363,"stem":364,"children":365,"new":18,"type":293},"Registry","\u002Fdocs\u002Fregistry","docs\u002Fregistry\u002Findex",[366,367,371,375,379,383],{"title":362,"path":363,"stem":364,"new":18,"type":303,"children":-1},{"title":368,"path":369,"stem":370,"new":18,"type":303,"children":-1},"Examples","\u002Fdocs\u002Fregistry\u002Fexamples","docs\u002Fregistry\u002Fexamples",{"title":372,"path":373,"stem":374,"new":18,"type":303,"children":-1},"FAQ","\u002Fdocs\u002Fregistry\u002Ffaq","docs\u002Fregistry\u002Ffaq",{"title":376,"path":377,"stem":378,"new":18,"type":303,"children":-1},"Getting Started","\u002Fdocs\u002Fregistry\u002Fgetting-started","docs\u002Fregistry\u002Fgetting-started",{"title":380,"path":381,"stem":382,"new":18,"type":303,"children":-1},"registry-item.json","\u002Fdocs\u002Fregistry\u002Fregistry-item-json","docs\u002Fregistry\u002Fregistry-item-json",{"title":384,"path":385,"stem":386,"new":18,"type":303,"children":-1},"registry.json","\u002Fdocs\u002Fregistry\u002Fregistry-json","docs\u002Fregistry\u002Fregistry-json",{"title":388,"path":389,"stem":390,"children":391,"page":18,"type":293},"Utilities","\u002Fdocs\u002Futilities","docs\u002Futilities",[392,396],{"title":393,"path":394,"stem":395,"new":36,"type":303,"children":-1},"scroll-fade","\u002Fdocs\u002Futilities\u002Fscroll-fade","docs\u002Futilities\u002Fscroll-fade",{"title":397,"path":398,"stem":399,"new":36,"type":303,"children":-1},"shimmer","\u002Fdocs\u002Futilities\u002Fshimmer","docs\u002Futilities\u002Fshimmer",{"path":6,"stem":7,"title":401,"type":293,"children":402},"Get Started",[403,407,414,418,422,428,432,436,440,444,448,452,456],{"title":404,"path":405,"stem":406,"new":18,"type":303,"children":-1},"Introduction","\u002Fdocs\u002Fintroduction","docs\u002F01.introduction",{"title":295,"path":296,"stem":297,"children":408,"new":18,"type":293},[409,410,411,412,413],{"title":300,"path":301,"stem":302,"new":18,"type":303,"children":-1},{"title":305,"path":306,"stem":307,"new":18,"type":303,"children":-1},{"title":309,"path":310,"stem":311,"new":18,"type":303,"children":-1},{"title":313,"path":314,"stem":315,"new":18,"type":303,"children":-1},{"title":317,"path":318,"stem":319,"new":18,"type":303,"children":-1},{"title":415,"path":416,"stem":417,"new":18,"type":303,"children":-1},"components.json","\u002Fdocs\u002Fcomponents-json","docs\u002F03.components-json",{"title":419,"path":420,"stem":421,"new":18,"type":303,"children":-1},"Theming","\u002Fdocs\u002Ftheming","docs\u002F04.theming",{"title":321,"path":322,"stem":323,"children":423,"new":18,"type":293},[424,425,426,427],{"title":300,"path":326,"stem":327,"new":18,"type":303,"children":-1},{"title":305,"path":329,"stem":330,"new":18,"type":303,"children":-1},{"title":332,"path":333,"stem":334,"new":18,"type":303,"children":-1},{"title":309,"path":336,"stem":337,"new":18,"type":303,"children":-1},{"title":429,"path":430,"stem":431,"new":18,"type":303,"children":-1},"CLI","\u002Fdocs\u002Fcli","docs\u002F06.cli",{"title":433,"path":434,"stem":435,"new":18,"type":303,"children":-1},"JavaScript","\u002Fdocs\u002Fjavascript","docs\u002F07.javascript",{"title":437,"path":438,"stem":439,"new":18,"type":303,"children":-1},"RTL","\u002Fdocs\u002Frtl","docs\u002F08.rtl",{"title":441,"path":442,"stem":443,"new":18,"type":303,"children":-1},"Figma","\u002Fdocs\u002Ffigma","docs\u002F09.figma",{"title":445,"path":446,"stem":447,"new":18,"type":303,"children":-1},"Changelog","\u002Fdocs\u002Fchangelog","docs\u002F10.changelog",{"title":449,"path":450,"stem":451,"new":18,"type":303,"children":-1},"Legacy Docs","\u002Fdocs\u002Flegacy","docs\u002F11.legacy",{"title":453,"path":454,"stem":455,"new":18,"type":303,"children":-1},"Skills","\u002Fdocs\u002Fskills","docs\u002Fskills",{"title":388,"path":389,"stem":390,"children":457,"page":18,"type":293},[458,459],{"title":393,"path":394,"stem":395,"new":36,"type":303,"children":-1},{"title":397,"path":398,"stem":399,"new":36,"type":303,"children":-1},{"repo":461},{"id":462,"name":463,"repo":464,"description":465,"createdAt":466,"updatedAt":467,"pushedAt":468,"stars":469,"watchers":470,"forks":471,"defaultBranch":472},658791894,"shadcn-vue","unovue\u002Fshadcn-vue","Vue port of shadcn-ui","2023-06-26T13:53:23Z","2026-08-02T05:32:15Z","2026-08-02T05:32:07Z",10375,36,669,"dev",{"id":474,"title":358,"body":475,"description":1525,"extension":1526,"links":1527,"meta":1528,"navigation":36,"new":18,"path":359,"rawbody":1529,"seo":1530,"stem":360,"__hash__":1531},"content\u002Fdocs\u002Fforms\u002F03.formisch.md",{"type":476,"value":477,"toc":1491},"minimark",[478,493,498,501,512,519,523,533,569,573,580,590,600,606,660,664,673,702,722,724,729,732,738,742,751,757,774,778,787,791,795,798,809,813,817,823,829,833,853,860,978,982,992,1017,1024,1028,1031,1093,1096,1118,1122,1129,1132,1151,1155,1162,1165,1187,1193,1200,1203,1234,1238,1246,1249,1271,1275,1282,1285,1306,1310,1317,1321,1324,1330,1334,1341,1347,1350,1356,1360,1367,1371,1375,1391,1399,1403,1416,1422,1426,1436,1442,1446,1454,1460,1474,1478,1485],[479,480,481,482,488,489,492],"p",{},"This guide covers building forms with ",[483,484,358],"a",{"href":485,"rel":486},"https:\u002F\u002Fformisch.dev",[487],"nofollow",", the lightweight, schema-first, and fully type-safe form library for Vue. We'll create forms with the ",[490,491,122],"code",{}," component, validate them with Valibot schemas, handle errors, and ensure accessibility.",[494,495,497],"h2",{"id":496},"demo","Demo",[479,499,500],{},"We'll build the following form. It has a simple text input and a textarea. On submit, we'll validate the form data and display any errors.",[502,503,505],"callout",{":icon":504},"true",[479,506,507,511],{},[508,509,510],"strong",{},"Note:"," For the purpose of this demo, we have intentionally disabled browser validation to show how schema validation and form errors work in Formisch. It is recommended to add basic browser validation in your production code.",[513,514],"component-preview",{":chromeLessOnMobile":504,"className":515,"name":518},[516,517],"sm:[&_.preview]:h-[700px]","sm:[&_pre]:!h-[700px]","FormischDemo",[494,520,522],{"id":521},"approach","Approach",[479,524,525,526,528,529,532],{},"This form leverages Formisch for headless, schema-first form handling. We'll build our form using the ",[490,527,122],{}," component, which gives you ",[508,530,531],{},"complete flexibility over the markup and styling",".",[534,535,536,544,553,558,566],"ul",{},[537,538,539,540,543],"li",{},"Uses Formisch's ",[490,541,542],{},"useForm"," composable for form state management.",[537,545,546,548,549,552],{},[490,547,126],{}," component to wrap the native ",[490,550,551],{},"form"," element with submit handling.",[537,554,555,557],{},[490,556,122],{}," component with a slot prop for controlled inputs.",[537,559,560,561,532],{},"Schema validation using ",[483,562,565],{"href":563,"rel":564},"https:\u002F\u002Fvalibot.dev",[487],"Valibot",[537,567,568],{},"Type-safe field paths inferred from the schema.",[494,570,572],{"id":571},"form-methods","Form Methods",[479,574,575,576,579],{},"Formisch exposes form operations as ",[508,577,578],{},"top-level functions"," rather than methods on a form object. Import only what you need:",[581,582,588],"pre",{"className":583,"code":585,"language":586,"meta":587},[584],"language-ts","import { getInput, insert, reset, submit } from '@formisch\u002Fvue'\n","ts","",[490,589,585],{"__ignoreMap":587},[479,591,592,593,596,597,532],{},"Every method follows the same signature: the ",[508,594,595],{},"first parameter is always the form store",", and the ",[508,598,599],{},"second parameter (if necessary) is always a config object",[581,601,604],{"className":602,"code":603,"language":586,"meta":587},[584],"\u002F\u002F Read a field value\nconst email = getInput(form, { path: ['email'] })\n\n\u002F\u002F Reset the form with new initial values\nreset(form, { initialInput: { email: '', password: '' } })\n\n\u002F\u002F Move an item in a field array\nmove(form, { path: ['items'], from: 0, to: 3 })\n",[490,605,603],{"__ignoreMap":587},[479,607,608,609,612,613,616,617,620,621,616,624,627,628,616,631,616,634,637,638,616,641,616,644,616,647,616,650,653,654,659],{},"This design keeps the API flexible and consistent across all methods. You'll see the same ",[490,610,611],{},"(form, config)"," shape used throughout this guide for reading state (",[490,614,615],{},"getInput",", ",[490,618,619],{},"getErrors","), writing state (",[490,622,623],{},"setInput",[490,625,626],{},"setErrors","), form control (",[490,629,630],{},"submit",[490,632,633],{},"validate",[490,635,636],{},"focus","), and array operations (",[490,639,640],{},"insert",[490,642,643],{},"remove",[490,645,646],{},"move",[490,648,649],{},"swap",[490,651,652],{},"replace","). See the ",[483,655,658],{"href":656,"rel":657},"https:\u002F\u002Fformisch.dev\u002Fvue\u002Fguides\u002Fform-methods",[487],"full methods reference"," for details.",[494,661,663],{"id":662},"anatomy","Anatomy",[479,665,666,667,669,670,672],{},"Here's a basic example of a form using the ",[490,668,122],{}," component from Formisch and the shadcn-vue ",[490,671,122],{}," component.",[581,674,700],{"className":675,"code":677,"highlights":678,"language":698,"meta":699},[676],"language-vue","\u003Ctemplate>\n  \u003CForm :of=\"form\" @submit=\"handleSubmit\">\n    \u003CFieldGroup>\n      \u003CFormischField :of=\"form\" :path=\"['title']\" v-slot=\"field\">\n        \u003CField :data-invalid=\"field.errors !== null\">\n          \u003CFieldLabel for=\"form-title\">Bug Title\u003C\u002FFieldLabel>\n          \u003CInput\n            v-model=\"field.input\"\n            v-bind=\"field.props\"\n            id=\"form-title\"\n            :aria-invalid=\"field.errors !== null\"\n            placeholder=\"Login button not working on mobile\"\n            autocomplete=\"off\"\n          \u002F>\n          \u003CFieldDescription>\n            Provide a concise title for your bug report.\n          \u003C\u002FFieldDescription>\n          \u003CFieldError\n            v-if=\"field.errors\"\n            :errors=\"field.errors.map((message) => ({ message }))\"\n          \u002F>\n        \u003C\u002FField>\n      \u003C\u002FFormischField>\n    \u003C\u002FFieldGroup>\n  \u003C\u002FForm>\n\u003C\u002Ftemplate>\n",[679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697],3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,"vue","showLineNumbers",[490,701,677],{"__ignoreMap":587},[502,703,704],{":icon":504},[479,705,706,708,709,711,712,714,715,718,719,721],{},[508,707,510],{}," Formisch ships its own ",[490,710,122],{}," component. To avoid a name clash with the shadcn-vue ",[490,713,122],{},", the examples below import the Formisch one as ",[490,716,717],{},"FormischField"," and keep the shadcn-vue ",[490,720,122],{}," under its original name. In your own code you can alias either side — just be consistent.",[494,723,126],{"id":551},[725,726,728],"h3",{"id":727},"create-a-form-schema","Create a form schema",[479,730,731],{},"We'll start by defining the shape of our form using a Valibot schema. Formisch infers all input and output types directly from this schema.",[581,733,736],{"className":734,"code":735,"language":698,"meta":699},[676],"\u003Cscript setup lang=\"ts\">\nimport * as v from 'valibot'\n\nconst FormSchema = v.object({\n  title: v.pipe(\n    v.string(),\n    v.minLength(5, 'Bug title must be at least 5 characters.'),\n    v.maxLength(32, 'Bug title must be at most 32 characters.'),\n  ),\n  description: v.pipe(\n    v.string(),\n    v.minLength(20, 'Description must be at least 20 characters.'),\n    v.maxLength(100, 'Description must be at most 100 characters.'),\n  ),\n})\n\u003C\u002Fscript>\n",[490,737,735],{"__ignoreMap":587},[725,739,741],{"id":740},"setup-the-form","Setup the form",[479,743,744,745,747,748,750],{},"Next, we'll use the ",[490,746,542],{}," composable from Formisch to create our form instance. The schema is passed directly to ",[490,749,542],{}," — there is no resolver step.",[581,752,755],{"className":753,"code":754,"language":698,"meta":699},[676],"\u003Cscript setup lang=\"ts\">\nimport { Field as FormischField, Form, useForm } from '@formisch\u002Fvue'\nimport type { SubmitHandler } from '@formisch\u002Fvue'\nimport * as v from 'valibot'\n\nconst FormSchema = v.object({\n  \u002F\u002F ...\n})\n\nconst form = useForm({\n  schema: FormSchema,\n  initialInput: {\n    title: '',\n    description: '',\n  },\n})\n\nconst handleSubmit: SubmitHandler\u003Ctypeof FormSchema> = (output) => {\n  \u002F\u002F Do something with the validated form values.\n  console.log(output)\n}\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003CForm :of=\"form\" @submit=\"handleSubmit\">\n    \u003C!-- ... -->\n  \u003C\u002FForm>\n\u003C\u002Ftemplate>\n",[490,756,754],{"__ignoreMap":587},[479,758,759,760,762,763,765,766,769,770,773],{},"The ",[490,761,126],{}," component wraps a native ",[490,764,551],{}," element. It calls ",[490,767,768],{},"event.preventDefault()",", runs validation, and only invokes the submit handler when the data is valid. The ",[490,771,772],{},"output"," you receive is fully typed from the schema.",[725,775,777],{"id":776},"build-the-form","Build the form",[479,779,780,781,783,784,786],{},"We can now build the form using the ",[490,782,717],{}," component from Formisch and the ",[490,785,122],{}," components.",[788,789],"component-source",{"name":518,"title":790},"Form.vue",[725,792,794],{"id":793},"done","Done",[479,796,797],{},"That's it. You now have a fully accessible form with client-side validation.",[479,799,800,801,804,805,808],{},"When you submit the form, the ",[490,802,803],{},"handleSubmit"," function will be called with the validated form data. If the form data is invalid, Formisch will populate ",[490,806,807],{},"field.errors"," for each invalid field and the UI will display them.",[494,810,812],{"id":811},"validation","Validation",[725,814,816],{"id":815},"client-side-validation","Client-side Validation",[479,818,819,820,822],{},"Formisch validates your form data using the Valibot schema you pass to ",[490,821,542],{},". There is no resolver — the schema is the single source of truth for both runtime validation and static types.",[581,824,827],{"className":825,"code":826,"language":698,"meta":699},[676],"\u003Cscript setup lang=\"ts\">\nimport { useForm } from '@formisch\u002Fvue'\nimport * as v from 'valibot'\n\nconst FormSchema = v.object({\n  title: v.string(),\n  description: v.optional(v.string()),\n})\n\nconst form = useForm({\n  schema: FormSchema,\n  initialInput: {\n    title: '',\n    description: '',\n  },\n})\n\u003C\u002Fscript>\n",[490,828,826],{"__ignoreMap":587},[725,830,832],{"id":831},"validation-modes","Validation Modes",[479,834,835,836,839,840,843,844,846,847,850,851,532],{},"Formisch separates the ",[508,837,838],{},"first"," validation from ",[508,841,842],{},"subsequent"," validations. You configure them with the ",[490,845,633],{}," and ",[490,848,849],{},"revalidate"," options on ",[490,852,542],{},[581,854,858],{"className":855,"code":856,"highlights":857,"language":698,"meta":699},[676],"\u003Cscript setup lang=\"ts\">\nconst form = useForm({\n  schema: FormSchema,\n  validate: 'blur',\n  revalidate: 'input',\n})\n\u003C\u002Fscript>\n",[681,682],[490,859,856],{"__ignoreMap":587},[861,862,863,879],"table",{},[864,865,866],"thead",{},[867,868,869,873,876],"tr",{},[870,871,872],"th",{},"Option",[870,874,875],{},"Value",[870,877,878],{},"Description",[880,881,882,897,911,925,939,952,965],"tbody",{},[867,883,884,889,894],{},[885,886,887],"td",{},[490,888,633],{},[885,890,891],{},[490,892,893],{},"'submit'",[885,895,896],{},"Validate on form submission (default).",[867,898,899,903,908],{},[885,900,901],{},[490,902,633],{},[885,904,905],{},[490,906,907],{},"'blur'",[885,909,910],{},"Validate when a field loses focus.",[867,912,913,917,922],{},[885,914,915],{},[490,916,633],{},[885,918,919],{},[490,920,921],{},"'input'",[885,923,924],{},"Validate on every input change.",[867,926,927,931,936],{},[885,928,929],{},[490,930,633],{},[885,932,933],{},[490,934,935],{},"'initial'",[885,937,938],{},"Validate immediately on form creation.",[867,940,941,945,949],{},[885,942,943],{},[490,944,849],{},[885,946,947],{},[490,948,921],{},[885,950,951],{},"Revalidate on every input change after the first run (default).",[867,953,954,958,962],{},[885,955,956],{},[490,957,849],{},[885,959,960],{},[490,961,907],{},[885,963,964],{},"Revalidate on blur after the first run.",[867,966,967,971,975],{},[885,968,969],{},[490,970,849],{},[885,972,973],{},[490,974,893],{},[885,976,977],{},"Revalidate only on form submission.",[494,979,981],{"id":980},"displaying-errors","Displaying Errors",[479,983,984,985,988,989,991],{},"Display errors next to the field using ",[490,986,987],{},"FieldError",". Formisch returns errors as an array of strings, so map them to the shape ",[490,990,987],{}," expects. For styling and accessibility:",[534,993,994,1003],{},[537,995,996,997,1000,1001,672],{},"Add the ",[490,998,999],{},":data-invalid"," prop to the ",[490,1002,122],{},[537,1004,996,1005,1008,1009,616,1011,616,1014,1016],{},[490,1006,1007],{},":aria-invalid"," prop to the form control such as ",[490,1010,134],{},[490,1012,1013],{},"SelectTrigger",[490,1015,78],{},", etc.",[581,1018,1022],{"className":1019,"code":1020,"highlights":1021,"language":698,"meta":699},[676],"\u003Ctemplate>\n  \u003CFormischField :of=\"form\" :path=\"['email']\" v-slot=\"field\">\n    \u003CField :data-invalid=\"field.errors !== null\">\n      \u003CFieldLabel for=\"form-email\">Email\u003C\u002FFieldLabel>\n      \u003CInput\n        v-model=\"field.input\"\n        v-bind=\"field.props\"\n        id=\"form-email\"\n        type=\"email\"\n        :aria-invalid=\"field.errors !== null\"\n      \u002F>\n      \u003CFieldError\n        v-if=\"field.errors\"\n        :errors=\"field.errors.map((message) => ({ message }))\"\n      \u002F>\n    \u003C\u002FField>\n  \u003C\u002FFormischField>\n\u003C\u002Ftemplate>\n",[679,683,689,690,691,692],[490,1023,1020],{"__ignoreMap":587},[494,1025,1027],{"id":1026},"working-with-different-field-types","Working with Different Field Types",[479,1029,1030],{},"Formisch exposes two ways to bind a field to an element:",[534,1032,1033,1063],{},[537,1034,1035,1038,1039,846,1041,1043,1044,1047,1048,1051,1052,1055,1056,616,1059,1062],{},[508,1036,1037],{},"Native HTML elements"," (like ",[490,1040,134],{},[490,1042,270],{},") — use ",[490,1045,1046],{},"v-model=\"field.input\""," and spread ",[490,1049,1050],{},"field.props"," with ",[490,1053,1054],{},"v-bind",". Formisch wires up ",[490,1057,1058],{},"name",[490,1060,1061],{},"ref",", and the focus and blur events for you.",[537,1064,1065,1068,1069,616,1071,616,1073,616,1076,1078,1079,1082,1083,1086,1087,846,1090,532],{},[508,1066,1067],{},"Component-library inputs"," (like reka-ui based ",[490,1070,218],{},[490,1072,78],{},[490,1074,1075],{},"RadioGroup",[490,1077,254],{},") — bind ",[490,1080,1081],{},"field.input"," directly with ",[490,1084,1085],{},"v-model"," or ",[490,1088,1089],{},":model-value",[490,1091,1092],{},"@update:model-value",[725,1094,134],{"id":1095},"input",[534,1097,1098,1106],{},[537,1099,1100,1101,846,1103,532],{},"For input fields, use ",[490,1102,1046],{},[490,1104,1105],{},"v-bind=\"field.props\"",[537,1107,1108,1109,1000,1111,1113,1114,1000,1116,672],{},"To show errors, add the ",[490,1110,1007],{},[490,1112,134],{}," component and the ",[490,1115,999],{},[490,1117,122],{},[513,1119],{":chromeLessOnMobile":504,"className":1120,"name":1121},[516,517],"FormischInput",[581,1123,1127],{"className":1124,"code":1125,"highlights":1126,"language":698,"meta":699},[676],"\u003Ctemplate>\n  \u003CFormischField :of=\"form\" :path=\"['username']\" v-slot=\"field\">\n    \u003CField :data-invalid=\"field.errors !== null\">\n      \u003CFieldLabel for=\"form-username\">Username\u003C\u002FFieldLabel>\n      \u003CInput\n        v-model=\"field.input\"\n        v-bind=\"field.props\"\n        id=\"form-username\"\n        :aria-invalid=\"field.errors !== null\"\n      \u002F>\n      \u003CFieldError\n        v-if=\"field.errors\"\n        :errors=\"field.errors.map((message) => ({ message }))\"\n      \u002F>\n    \u003C\u002FField>\n  \u003C\u002FFormischField>\n\u003C\u002Ftemplate>\n",[681,682,683,684,685,686],[490,1128,1125],{"__ignoreMap":587},[725,1130,270],{"id":1131},"textarea",[534,1133,1134,1141],{},[537,1135,1136,1137,846,1139,532],{},"For textarea fields, use ",[490,1138,1046],{},[490,1140,1105],{},[537,1142,1108,1143,1000,1145,1113,1147,1000,1149,672],{},[490,1144,1007],{},[490,1146,270],{},[490,1148,999],{},[490,1150,122],{},[513,1152],{":chromeLessOnMobile":504,"className":1153,"name":1154},[516,517],"FormischTextarea",[581,1156,1160],{"className":1157,"code":1158,"highlights":1159,"language":698,"meta":699},[676],"\u003Ctemplate>\n  \u003CFormischField :of=\"form\" :path=\"['about']\" v-slot=\"field\">\n    \u003CField :data-invalid=\"field.errors !== null\">\n      \u003CFieldLabel for=\"form-about\">More about you\u003C\u002FFieldLabel>\n      \u003CTextarea\n        v-model=\"field.input\"\n        v-bind=\"field.props\"\n        id=\"form-about\"\n        :aria-invalid=\"field.errors !== null\"\n        placeholder=\"I'm a software engineer...\"\n        class=\"min-h-[120px]\"\n      \u002F>\n      \u003CFieldDescription>\n        Tell us more about yourself. This will be used to help us personalize\n        your experience.\n      \u003C\u002FFieldDescription>\n      \u003CFieldError\n        v-if=\"field.errors\"\n        :errors=\"field.errors.map((message) => ({ message }))\"\n      \u002F>\n    \u003C\u002FField>\n  \u003C\u002FFormischField>\n\u003C\u002Ftemplate>\n",[681,682,683,684,685,686,687,688],[490,1161,1158],{"__ignoreMap":587},[725,1163,218],{"id":1164},"select",[534,1166,1167,1177],{},[537,1168,1169,1170,1051,1172,1174,1175,672],{},"For select components, bind ",[490,1171,1081],{},[490,1173,1085],{}," on the ",[490,1176,218],{},[537,1178,1108,1179,1000,1181,1113,1183,1000,1185,672],{},[490,1180,1007],{},[490,1182,1013],{},[490,1184,999],{},[490,1186,122],{},[513,1188],{":chromeLessOnMobile":504,"className":1189,"name":1192},[1190,1191],"sm:[&_.preview]:h-[500px]","sm:[&_pre]:!h-[500px]","FormischSelect",[581,1194,1198],{"className":1195,"code":1196,"highlights":1197,"language":698,"meta":699},[676],"\u003Ctemplate>\n  \u003CFormischField :of=\"form\" :path=\"['language']\" v-slot=\"field\">\n    \u003CField orientation=\"responsive\" :data-invalid=\"field.errors !== null\">\n      \u003CFieldContent>\n        \u003CFieldLabel for=\"form-language\">Spoken Language\u003C\u002FFieldLabel>\n        \u003CFieldDescription>\n          For best results, select the language you speak.\n        \u003C\u002FFieldDescription>\n        \u003CFieldError\n          v-if=\"field.errors\"\n          :errors=\"field.errors.map((message) => ({ message }))\"\n        \u002F>\n      \u003C\u002FFieldContent>\n      \u003CSelect v-model=\"field.input\">\n        \u003CSelectTrigger\n          id=\"form-language\"\n          :aria-invalid=\"field.errors !== null\"\n          class=\"min-w-[120px]\"\n        >\n          \u003CSelectValue placeholder=\"Select\" \u002F>\n        \u003C\u002FSelectTrigger>\n        \u003CSelectContent position=\"item-aligned\">\n          \u003CSelectItem value=\"auto\">Auto\u003C\u002FSelectItem>\n          \u003CSelectItem value=\"en\">English\u003C\u002FSelectItem>\n        \u003C\u002FSelectContent>\n      \u003C\u002FSelect>\n    \u003C\u002FField>\n  \u003C\u002FFormischField>\n\u003C\u002Ftemplate>\n",[690],[490,1199,1196],{"__ignoreMap":587},[725,1201,78],{"id":1202},"checkbox",[534,1204,1205,1213,1223],{},[537,1206,1207,1208,1210,1211,532],{},"For checkbox arrays, read ",[490,1209,1081],{}," and write the updated array back to it from ",[490,1212,1092],{},[537,1214,1108,1215,1000,1217,1113,1219,1000,1221,672],{},[490,1216,1007],{},[490,1218,78],{},[490,1220,999],{},[490,1222,122],{},[537,1224,1225,1226,1229,1230,1233],{},"Remember to add ",[490,1227,1228],{},"data-slot=\"checkbox-group\""," to the ",[490,1231,1232],{},"FieldGroup"," component for proper styling and spacing.",[513,1235],{":chromeLessOnMobile":504,"className":1236,"name":1237},[516,517],"FormischCheckbox",[581,1239,1244],{"className":1240,"code":1241,"highlights":1242,"language":698,"meta":699},[676],"\u003Ctemplate>\n  \u003CFormischField :of=\"form\" :path=\"['tasks']\" v-slot=\"field\">\n    \u003CFieldSet>\n      \u003CFieldLegend variant=\"label\">Tasks\u003C\u002FFieldLegend>\n      \u003CFieldDescription>\n        Get notified when tasks you've created have updates.\n      \u003C\u002FFieldDescription>\n      \u003CFieldGroup data-slot=\"checkbox-group\">\n        \u003CField\n          v-for=\"task in tasks\"\n          :key=\"task.id\"\n          orientation=\"horizontal\"\n          :data-invalid=\"field.errors !== null\"\n        >\n          \u003CCheckbox\n            :id=\"`form-checkbox-${task.id}`\"\n            :aria-invalid=\"field.errors !== null\"\n            :model-value=\"field.input?.includes(task.id) ?? false\"\n            @update:model-value=\"\n              (checked) =>\n                (field.input = checked\n                  ? [...(field.input ?? []), task.id]\n                  : (field.input ?? []).filter((value) => value !== task.id))\n            \"\n          \u002F>\n          \u003CFieldLabel :for=\"`form-checkbox-${task.id}`\" class=\"font-normal\">\n            {{ task.label }}\n          \u003C\u002FFieldLabel>\n        \u003C\u002FField>\n      \u003C\u002FFieldGroup>\n      \u003CFieldError\n        v-if=\"field.errors\"\n        :errors=\"field.errors.map((message) => ({ message }))\"\n      \u002F>\n    \u003C\u002FFieldSet>\n  \u003C\u002FFormischField>\n\u003C\u002Ftemplate>\n",[691,692,693,694,695,696,697,1243],22,[490,1245,1241],{"__ignoreMap":587},[725,1247,202],{"id":1248},"radio-group",[534,1250,1251,1260],{},[537,1252,1253,1254,1051,1256,1174,1258,672],{},"For radio groups, bind ",[490,1255,1081],{},[490,1257,1085],{},[490,1259,1075],{},[537,1261,1108,1262,1000,1264,1113,1267,1000,1269,672],{},[490,1263,1007],{},[490,1265,1266],{},"RadioGroupItem",[490,1268,999],{},[490,1270,122],{},[513,1272],{":chromeLessOnMobile":504,"className":1273,"name":1274},[516,517],"FormischRadioGroup",[581,1276,1280],{"className":1277,"code":1278,"highlights":1279,"language":698,"meta":699},[676],"\u003Ctemplate>\n  \u003CFormischField :of=\"form\" :path=\"['plan']\" v-slot=\"field\">\n    \u003CFieldSet>\n      \u003CFieldLegend>Plan\u003C\u002FFieldLegend>\n      \u003CFieldDescription>\n        You can upgrade or downgrade your plan at any time.\n      \u003C\u002FFieldDescription>\n      \u003CRadioGroup v-model=\"field.input\">\n        \u003CFieldLabel\n          v-for=\"plan in plans\"\n          :key=\"plan.id\"\n          :for=\"`form-radiogroup-${plan.id}`\"\n        >\n          \u003CField orientation=\"horizontal\" :data-invalid=\"field.errors !== null\">\n            \u003CFieldContent>\n              \u003CFieldTitle>{{ plan.title }}\u003C\u002FFieldTitle>\n              \u003CFieldDescription>{{ plan.description }}\u003C\u002FFieldDescription>\n            \u003C\u002FFieldContent>\n            \u003CRadioGroupItem\n              :value=\"plan.id\"\n              :id=\"`form-radiogroup-${plan.id}`\"\n              :aria-invalid=\"field.errors !== null\"\n            \u002F>\n          \u003C\u002FField>\n        \u003C\u002FFieldLabel>\n      \u003C\u002FRadioGroup>\n      \u003CFieldError\n        v-if=\"field.errors\"\n        :errors=\"field.errors.map((message) => ({ message }))\"\n      \u002F>\n    \u003C\u002FFieldSet>\n  \u003C\u002FFormischField>\n\u003C\u002Ftemplate>\n",[684],[490,1281,1278],{"__ignoreMap":587},[725,1283,254],{"id":1284},"switch",[534,1286,1287,1296],{},[537,1288,1289,1290,1051,1292,1174,1294,672],{},"For switches, bind ",[490,1291,1081],{},[490,1293,1085],{},[490,1295,254],{},[537,1297,1108,1298,1000,1300,1113,1302,1000,1304,672],{},[490,1299,1007],{},[490,1301,254],{},[490,1303,999],{},[490,1305,122],{},[513,1307],{":chromeLessOnMobile":504,"className":1308,"name":1309},[1190,1191],"FormischSwitch",[581,1311,1315],{"className":1312,"code":1313,"highlights":1314,"language":698,"meta":699},[676],"\u003Ctemplate>\n  \u003CFormischField :of=\"form\" :path=\"['twoFactor']\" v-slot=\"field\">\n    \u003CField orientation=\"horizontal\" :data-invalid=\"field.errors !== null\">\n      \u003CFieldContent>\n        \u003CFieldLabel for=\"form-twoFactor\">\n          Multi-factor authentication\n        \u003C\u002FFieldLabel>\n        \u003CFieldDescription>\n          Enable multi-factor authentication to secure your account.\n        \u003C\u002FFieldDescription>\n        \u003CFieldError\n          v-if=\"field.errors\"\n          :errors=\"field.errors.map((message) => ({ message }))\"\n        \u002F>\n      \u003C\u002FFieldContent>\n      \u003CSwitch\n        id=\"form-twoFactor\"\n        v-model=\"field.input\"\n        :aria-invalid=\"field.errors !== null\"\n      \u002F>\n    \u003C\u002FField>\n  \u003C\u002FFormischField>\n\u003C\u002Ftemplate>\n",[691,692,693,694,695],[490,1316,1313],{"__ignoreMap":587},[725,1318,1320],{"id":1319},"complex-forms","Complex Forms",[479,1322,1323],{},"Here is an example of a more complex form with multiple fields and validation.",[513,1325],{":chromeLessOnMobile":504,"className":1326,"name":1329},[1327,1328],"sm:[&_.preview]:h-[1300px]","sm:[&_pre]:!h-[1300px]","FormischComplex",[494,1331,1333],{"id":1332},"resetting-the-form","Resetting the Form",[479,1335,1336,1337,1340],{},"Formisch exposes a top-level ",[490,1338,1339],{},"reset"," function. Pass the form store to reset it to its initial input.",[581,1342,1345],{"className":1343,"code":1344,"language":698,"meta":699},[676],"\u003Ctemplate>\n  \u003CButton type=\"button\" variant=\"outline\" @click=\"reset(form)\">\n    Reset\n  \u003C\u002FButton>\n\u003C\u002Ftemplate>\n",[490,1346,1344],{"__ignoreMap":587},[479,1348,1349],{},"You can also reset to new initial values, or reset while keeping the user's current input:",[581,1351,1354],{"className":1352,"code":1353,"language":586,"meta":699},[584],"\u002F\u002F Reset to a fresh set of initial values\nreset(form, { initialInput: { title: '', description: '' } })\n\n\u002F\u002F Sync the baseline to new server data, but keep the user's edits\nreset(form, { initialInput: serverData, keepInput: true })\n",[490,1355,1353],{"__ignoreMap":587},[494,1357,1359],{"id":1358},"array-fields","Array Fields",[479,1361,1362,1363,1366],{},"Formisch provides a ",[490,1364,1365],{},"FieldArray"," component and a set of helper functions for managing dynamic array fields. Use it whenever you need to add, remove, or reorder items.",[513,1368],{":chromeLessOnMobile":504,"className":1369,"name":1370},[516,517],"FormischArray",[725,1372,1374],{"id":1373},"using-fieldarray","Using FieldArray",[479,1376,1377,1379,1380,1382,1383,1386,1387,1390],{},[490,1378,1365],{}," follows the same slot pattern as ",[490,1381,122],{},". Its ",[490,1384,1385],{},"items"," array contains a stable key per item that you should use as the ",[490,1388,1389],{},"v-for"," key.",[581,1392,1397],{"className":1393,"code":1394,"highlights":1395,"language":698,"meta":699},[676],"\u003Cscript setup lang=\"ts\">\nimport { Field as FormischField, FieldArray, insert, remove } from '@formisch\u002Fvue'\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003CFieldArray :of=\"form\" :path=\"['emails']\" v-slot=\"fieldArray\">\n    \u003CFieldGroup class=\"gap-4\">\n      \u003CFormischField\n        v-for=\"(item, index) in fieldArray.items\"\n        :key=\"item\"\n        :of=\"form\"\n        :path=\"['emails', index, 'address']\"\n        v-slot=\"field\"\n      >\n        \u003C!-- ... -->\n      \u003C\u002FFormischField>\n    \u003C\u002FFieldGroup>\n  \u003C\u002FFieldArray>\n\u003C\u002Ftemplate>\n",[1396,684,685,686,687,688,689,690],2,[490,1398,1394],{"__ignoreMap":587},[725,1400,1402],{"id":1401},"array-field-structure","Array Field Structure",[479,1404,1405,1406,1409,1410,846,1413,532],{},"Wrap your array fields in a ",[490,1407,1408],{},"FieldSet"," with a ",[490,1411,1412],{},"FieldLegend",[490,1414,1415],{},"FieldDescription",[581,1417,1420],{"className":1418,"code":1419,"language":698,"meta":699},[676],"\u003Ctemplate>\n  \u003CFieldSet class=\"gap-4\">\n    \u003CFieldLegend variant=\"label\">Email Addresses\u003C\u002FFieldLegend>\n    \u003CFieldDescription>\n      Add up to 5 email addresses where we can contact you.\n    \u003C\u002FFieldDescription>\n    \u003CFieldGroup class=\"gap-4\">\n      \u003C!-- Array items go here -->\n    \u003C\u002FFieldGroup>\n  \u003C\u002FFieldSet>\n\u003C\u002Ftemplate>\n",[490,1421,1419],{"__ignoreMap":587},[725,1423,1425],{"id":1424},"adding-items","Adding Items",[479,1427,1428,1429,1431,1432,1435],{},"Use the ",[490,1430,640],{}," function to add new items to the array. By default new items are appended to the end. You can also pass an ",[490,1433,1434],{},"at"," index to insert at a specific position.",[581,1437,1440],{"className":1438,"code":1439,"language":698,"meta":699},[676],"\u003Ctemplate>\n  \u003CButton\n    type=\"button\"\n    variant=\"outline\"\n    size=\"sm\"\n    @click=\"insert(form, { path: ['emails'], initialInput: { address: '' } })\"\n    :disabled=\"fieldArray.items.length >= 5\"\n  >\n    Add Email Address\n  \u003C\u002FButton>\n\u003C\u002Ftemplate>\n",[490,1441,1439],{"__ignoreMap":587},[725,1443,1445],{"id":1444},"removing-items","Removing Items",[479,1447,1428,1448,1450,1451,1453],{},[490,1449,643],{}," function with an ",[490,1452,1434],{}," index to remove items from the array.",[581,1455,1458],{"className":1456,"code":1457,"language":698,"meta":699},[676],"\u003Ctemplate>\n  \u003CInputGroupAddon v-if=\"fieldArray.items.length > 1\" align=\"inline-end\">\n    \u003CInputGroupButton\n      type=\"button\"\n      variant=\"ghost\"\n      size=\"icon-xs\"\n      @click=\"remove(form, { path: ['emails'], at: index })\"\n      :aria-label=\"`Remove email ${index + 1}`\"\n    >\n      \u003CXIcon \u002F>\n    \u003C\u002FInputGroupButton>\n  \u003C\u002FInputGroupAddon>\n\u003C\u002Ftemplate>\n",[490,1459,1457],{"__ignoreMap":587},[479,1461,1462,1463,616,1465,1467,1468,1470,1471,1473],{},"Formisch also exposes ",[490,1464,646],{},[490,1466,649],{},", and ",[490,1469,652],{}," for reordering and replacing items. They follow the same ",[490,1472,611],{}," signature.",[725,1475,1477],{"id":1476},"array-validation","Array Validation",[479,1479,1480,1481,1484],{},"Use Valibot's ",[490,1482,1483],{},"array"," and pipeline validators to constrain array fields.",[581,1486,1489],{"className":1487,"code":1488,"language":698,"meta":699},[676],"\u003Cscript setup lang=\"ts\">\nconst FormSchema = v.object({\n  emails: v.pipe(\n    v.array(\n      v.object({\n        address: v.pipe(\n          v.string(),\n          v.nonEmpty('Enter an email address.'),\n          v.email('Enter a valid email address.'),\n        ),\n      }),\n    ),\n    v.minLength(1, 'Add at least one email address.'),\n    v.maxLength(5, 'You can add up to 5 email addresses.'),\n  ),\n})\n\u003C\u002Fscript>\n",[490,1490,1488],{"__ignoreMap":587},{"title":587,"searchDepth":1396,"depth":1396,"links":1492},[1493,1494,1495,1496,1497,1503,1507,1508,1517,1518],{"id":496,"depth":1396,"text":497},{"id":521,"depth":1396,"text":522},{"id":571,"depth":1396,"text":572},{"id":662,"depth":1396,"text":663},{"id":551,"depth":1396,"text":126,"children":1498},[1499,1500,1501,1502],{"id":727,"depth":679,"text":728},{"id":740,"depth":679,"text":741},{"id":776,"depth":679,"text":777},{"id":793,"depth":679,"text":794},{"id":811,"depth":1396,"text":812,"children":1504},[1505,1506],{"id":815,"depth":679,"text":816},{"id":831,"depth":679,"text":832},{"id":980,"depth":1396,"text":981},{"id":1026,"depth":1396,"text":1027,"children":1509},[1510,1511,1512,1513,1514,1515,1516],{"id":1095,"depth":679,"text":134},{"id":1131,"depth":679,"text":270},{"id":1164,"depth":679,"text":218},{"id":1202,"depth":679,"text":78},{"id":1248,"depth":679,"text":202},{"id":1284,"depth":679,"text":254},{"id":1319,"depth":679,"text":1320},{"id":1332,"depth":1396,"text":1333},{"id":1358,"depth":1396,"text":1359,"children":1519},[1520,1521,1522,1523,1524],{"id":1373,"depth":679,"text":1374},{"id":1401,"depth":679,"text":1402},{"id":1424,"depth":679,"text":1425},{"id":1444,"depth":679,"text":1445},{"id":1476,"depth":679,"text":1477},"Build forms in Vue using Formisch and Valibot.","md",{"doc":485},{},"---\ntitle: Formisch\ndescription: Build forms in Vue using Formisch and Valibot.\nlinks:\n  doc: https:\u002F\u002Fformisch.dev\n---\n\nThis guide covers building forms with [Formisch](https:\u002F\u002Fformisch.dev), the lightweight, schema-first, and fully type-safe form library for Vue. We'll create forms with the `Field` component, validate them with Valibot schemas, handle errors, and ensure accessibility.\n\n## Demo\n\nWe'll build the following form. It has a simple text input and a textarea. On submit, we'll validate the form data and display any errors.\n\n::callout\n---\nicon: true\n---\n**Note:** For the purpose of this demo, we have intentionally disabled browser validation to show how schema validation and form errors work in Formisch. It is recommended to add basic browser validation in your production code.\n::\n\n::component-preview\n---\nname: FormischDemo\nclass: sm:[&_.preview]:h-[700px] sm:[&_pre]:!h-[700px]\nchromeLessOnMobile: true\n---\n::\n\n## Approach\n\nThis form leverages Formisch for headless, schema-first form handling. We'll build our form using the `Field` component, which gives you **complete flexibility over the markup and styling**.\n\n- Uses Formisch's `useForm` composable for form state management.\n- `Form` component to wrap the native `form` element with submit handling.\n- `Field` component with a slot prop for controlled inputs.\n- Schema validation using [Valibot](https:\u002F\u002Fvalibot.dev).\n- Type-safe field paths inferred from the schema.\n\n## Form Methods\n\nFormisch exposes form operations as **top-level functions** rather than methods on a form object. Import only what you need:\n\n```ts\nimport { getInput, insert, reset, submit } from '@formisch\u002Fvue'\n```\n\nEvery method follows the same signature: the **first parameter is always the form store**, and the **second parameter (if necessary) is always a config object**.\n\n```ts\n\u002F\u002F Read a field value\nconst email = getInput(form, { path: ['email'] })\n\n\u002F\u002F Reset the form with new initial values\nreset(form, { initialInput: { email: '', password: '' } })\n\n\u002F\u002F Move an item in a field array\nmove(form, { path: ['items'], from: 0, to: 3 })\n```\n\nThis design keeps the API flexible and consistent across all methods. You'll see the same `(form, config)` shape used throughout this guide for reading state (`getInput`, `getErrors`), writing state (`setInput`, `setErrors`), form control (`submit`, `validate`, `focus`), and array operations (`insert`, `remove`, `move`, `swap`, `replace`). See the [full methods reference](https:\u002F\u002Fformisch.dev\u002Fvue\u002Fguides\u002Fform-methods) for details.\n\n## Anatomy\n\nHere's a basic example of a form using the `Field` component from Formisch and the shadcn-vue `Field` component.\n\n```vue showLineNumbers {3-21}\n\u003Ctemplate>\n  \u003CForm :of=\"form\" @submit=\"handleSubmit\">\n    \u003CFieldGroup>\n      \u003CFormischField :of=\"form\" :path=\"['title']\" v-slot=\"field\">\n        \u003CField :data-invalid=\"field.errors !== null\">\n          \u003CFieldLabel for=\"form-title\">Bug Title\u003C\u002FFieldLabel>\n          \u003CInput\n            v-model=\"field.input\"\n            v-bind=\"field.props\"\n            id=\"form-title\"\n            :aria-invalid=\"field.errors !== null\"\n            placeholder=\"Login button not working on mobile\"\n            autocomplete=\"off\"\n          \u002F>\n          \u003CFieldDescription>\n            Provide a concise title for your bug report.\n          \u003C\u002FFieldDescription>\n          \u003CFieldError\n            v-if=\"field.errors\"\n            :errors=\"field.errors.map((message) => ({ message }))\"\n          \u002F>\n        \u003C\u002FField>\n      \u003C\u002FFormischField>\n    \u003C\u002FFieldGroup>\n  \u003C\u002FForm>\n\u003C\u002Ftemplate>\n```\n\n::callout\n---\nicon: true\n---\n**Note:** Formisch ships its own `Field` component. To avoid a name clash with the shadcn-vue `Field`, the examples below import the Formisch one as `FormischField` and keep the shadcn-vue `Field` under its original name. In your own code you can alias either side — just be consistent.\n::\n\n## Form\n\n### Create a form schema\n\nWe'll start by defining the shape of our form using a Valibot schema. Formisch infers all input and output types directly from this schema.\n\n```vue showLineNumbers\n\u003Cscript setup lang=\"ts\">\nimport * as v from 'valibot'\n\nconst FormSchema = v.object({\n  title: v.pipe(\n    v.string(),\n    v.minLength(5, 'Bug title must be at least 5 characters.'),\n    v.maxLength(32, 'Bug title must be at most 32 characters.'),\n  ),\n  description: v.pipe(\n    v.string(),\n    v.minLength(20, 'Description must be at least 20 characters.'),\n    v.maxLength(100, 'Description must be at most 100 characters.'),\n  ),\n})\n\u003C\u002Fscript>\n```\n\n### Setup the form\n\nNext, we'll use the `useForm` composable from Formisch to create our form instance. The schema is passed directly to `useForm` — there is no resolver step.\n\n```vue showLineNumbers\n\u003Cscript setup lang=\"ts\">\nimport { Field as FormischField, Form, useForm } from '@formisch\u002Fvue'\nimport type { SubmitHandler } from '@formisch\u002Fvue'\nimport * as v from 'valibot'\n\nconst FormSchema = v.object({\n  \u002F\u002F ...\n})\n\nconst form = useForm({\n  schema: FormSchema,\n  initialInput: {\n    title: '',\n    description: '',\n  },\n})\n\nconst handleSubmit: SubmitHandler\u003Ctypeof FormSchema> = (output) => {\n  \u002F\u002F Do something with the validated form values.\n  console.log(output)\n}\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003CForm :of=\"form\" @submit=\"handleSubmit\">\n    \u003C!-- ... -->\n  \u003C\u002FForm>\n\u003C\u002Ftemplate>\n```\n\nThe `Form` component wraps a native `form` element. It calls `event.preventDefault()`, runs validation, and only invokes the submit handler when the data is valid. The `output` you receive is fully typed from the schema.\n\n### Build the form\n\nWe can now build the form using the `FormischField` component from Formisch and the `Field` components.\n\n::component-source\n---\nname: FormischDemo\ntitle: Form.vue\n---\n::\n\n### Done\n\nThat's it. You now have a fully accessible form with client-side validation.\n\nWhen you submit the form, the `handleSubmit` function will be called with the validated form data. If the form data is invalid, Formisch will populate `field.errors` for each invalid field and the UI will display them.\n\n## Validation\n\n### Client-side Validation\n\nFormisch validates your form data using the Valibot schema you pass to `useForm`. There is no resolver — the schema is the single source of truth for both runtime validation and static types.\n\n```vue showLineNumbers\n\u003Cscript setup lang=\"ts\">\nimport { useForm } from '@formisch\u002Fvue'\nimport * as v from 'valibot'\n\nconst FormSchema = v.object({\n  title: v.string(),\n  description: v.optional(v.string()),\n})\n\nconst form = useForm({\n  schema: FormSchema,\n  initialInput: {\n    title: '',\n    description: '',\n  },\n})\n\u003C\u002Fscript>\n```\n\n### Validation Modes\n\nFormisch separates the **first** validation from **subsequent** validations. You configure them with the `validate` and `revalidate` options on `useForm`.\n\n```vue showLineNumbers {5-6}\n\u003Cscript setup lang=\"ts\">\nconst form = useForm({\n  schema: FormSchema,\n  validate: 'blur',\n  revalidate: 'input',\n})\n\u003C\u002Fscript>\n```\n\n| Option       | Value       | Description                                                     |\n| ------------ | ----------- | --------------------------------------------------------------- |\n| `validate`   | `'submit'`  | Validate on form submission (default).                          |\n| `validate`   | `'blur'`    | Validate when a field loses focus.                              |\n| `validate`   | `'input'`   | Validate on every input change.                                 |\n| `validate`   | `'initial'` | Validate immediately on form creation.                          |\n| `revalidate` | `'input'`   | Revalidate on every input change after the first run (default). |\n| `revalidate` | `'blur'`    | Revalidate on blur after the first run.                         |\n| `revalidate` | `'submit'`  | Revalidate only on form submission.                             |\n\n## Displaying Errors\n\nDisplay errors next to the field using `FieldError`. Formisch returns errors as an array of strings, so map them to the shape `FieldError` expects. For styling and accessibility:\n\n- Add the `:data-invalid` prop to the `Field` component.\n- Add the `:aria-invalid` prop to the form control such as `Input`, `SelectTrigger`, `Checkbox`, etc.\n\n```vue showLineNumbers {3,7,13-16}\n\u003Ctemplate>\n  \u003CFormischField :of=\"form\" :path=\"['email']\" v-slot=\"field\">\n    \u003CField :data-invalid=\"field.errors !== null\">\n      \u003CFieldLabel for=\"form-email\">Email\u003C\u002FFieldLabel>\n      \u003CInput\n        v-model=\"field.input\"\n        v-bind=\"field.props\"\n        id=\"form-email\"\n        type=\"email\"\n        :aria-invalid=\"field.errors !== null\"\n      \u002F>\n      \u003CFieldError\n        v-if=\"field.errors\"\n        :errors=\"field.errors.map((message) => ({ message }))\"\n      \u002F>\n    \u003C\u002FField>\n  \u003C\u002FFormischField>\n\u003C\u002Ftemplate>\n```\n\n## Working with Different Field Types\n\nFormisch exposes two ways to bind a field to an element:\n\n- **Native HTML elements** (like `Input` and `Textarea`) — use `v-model=\"field.input\"` and spread `field.props` with `v-bind`. Formisch wires up `name`, `ref`, and the focus and blur events for you.\n- **Component-library inputs** (like reka-ui based `Select`, `Checkbox`, `RadioGroup`, `Switch`) — bind `field.input` directly with `v-model` or `:model-value` and `@update:model-value`.\n\n### Input\n\n- For input fields, use `v-model=\"field.input\"` and `v-bind=\"field.props\"`.\n- To show errors, add the `:aria-invalid` prop to the `Input` component and the `:data-invalid` prop to the `Field` component.\n\n::component-preview\n---\nname: FormischInput\nclass: sm:[&_.preview]:h-[700px] sm:[&_pre]:!h-[700px]\nchromeLessOnMobile: true\n---\n::\n\n```vue showLineNumbers {5-10}\n\u003Ctemplate>\n  \u003CFormischField :of=\"form\" :path=\"['username']\" v-slot=\"field\">\n    \u003CField :data-invalid=\"field.errors !== null\">\n      \u003CFieldLabel for=\"form-username\">Username\u003C\u002FFieldLabel>\n      \u003CInput\n        v-model=\"field.input\"\n        v-bind=\"field.props\"\n        id=\"form-username\"\n        :aria-invalid=\"field.errors !== null\"\n      \u002F>\n      \u003CFieldError\n        v-if=\"field.errors\"\n        :errors=\"field.errors.map((message) => ({ message }))\"\n      \u002F>\n    \u003C\u002FField>\n  \u003C\u002FFormischField>\n\u003C\u002Ftemplate>\n```\n\n### Textarea\n\n- For textarea fields, use `v-model=\"field.input\"` and `v-bind=\"field.props\"`.\n- To show errors, add the `:aria-invalid` prop to the `Textarea` component and the `:data-invalid` prop to the `Field` component.\n\n::component-preview\n---\nname: FormischTextarea\nclass: sm:[&_.preview]:h-[700px] sm:[&_pre]:!h-[700px]\nchromeLessOnMobile: true\n---\n::\n\n```vue showLineNumbers {5-12}\n\u003Ctemplate>\n  \u003CFormischField :of=\"form\" :path=\"['about']\" v-slot=\"field\">\n    \u003CField :data-invalid=\"field.errors !== null\">\n      \u003CFieldLabel for=\"form-about\">More about you\u003C\u002FFieldLabel>\n      \u003CTextarea\n        v-model=\"field.input\"\n        v-bind=\"field.props\"\n        id=\"form-about\"\n        :aria-invalid=\"field.errors !== null\"\n        placeholder=\"I'm a software engineer...\"\n        class=\"min-h-[120px]\"\n      \u002F>\n      \u003CFieldDescription>\n        Tell us more about yourself. This will be used to help us personalize\n        your experience.\n      \u003C\u002FFieldDescription>\n      \u003CFieldError\n        v-if=\"field.errors\"\n        :errors=\"field.errors.map((message) => ({ message }))\"\n      \u002F>\n    \u003C\u002FField>\n  \u003C\u002FFormischField>\n\u003C\u002Ftemplate>\n```\n\n### Select\n\n- For select components, bind `field.input` with `v-model` on the `Select` component.\n- To show errors, add the `:aria-invalid` prop to the `SelectTrigger` component and the `:data-invalid` prop to the `Field` component.\n\n::component-preview\n---\nname: FormischSelect\nclass: sm:[&_.preview]:h-[500px] sm:[&_pre]:!h-[500px]\nchromeLessOnMobile: true\n---\n::\n\n```vue showLineNumbers {14}\n\u003Ctemplate>\n  \u003CFormischField :of=\"form\" :path=\"['language']\" v-slot=\"field\">\n    \u003CField orientation=\"responsive\" :data-invalid=\"field.errors !== null\">\n      \u003CFieldContent>\n        \u003CFieldLabel for=\"form-language\">Spoken Language\u003C\u002FFieldLabel>\n        \u003CFieldDescription>\n          For best results, select the language you speak.\n        \u003C\u002FFieldDescription>\n        \u003CFieldError\n          v-if=\"field.errors\"\n          :errors=\"field.errors.map((message) => ({ message }))\"\n        \u002F>\n      \u003C\u002FFieldContent>\n      \u003CSelect v-model=\"field.input\">\n        \u003CSelectTrigger\n          id=\"form-language\"\n          :aria-invalid=\"field.errors !== null\"\n          class=\"min-w-[120px]\"\n        >\n          \u003CSelectValue placeholder=\"Select\" \u002F>\n        \u003C\u002FSelectTrigger>\n        \u003CSelectContent position=\"item-aligned\">\n          \u003CSelectItem value=\"auto\">Auto\u003C\u002FSelectItem>\n          \u003CSelectItem value=\"en\">English\u003C\u002FSelectItem>\n        \u003C\u002FSelectContent>\n      \u003C\u002FSelect>\n    \u003C\u002FField>\n  \u003C\u002FFormischField>\n\u003C\u002Ftemplate>\n```\n\n### Checkbox\n\n- For checkbox arrays, read `field.input` and write the updated array back to it from `@update:model-value`.\n- To show errors, add the `:aria-invalid` prop to the `Checkbox` component and the `:data-invalid` prop to the `Field` component.\n- Remember to add `data-slot=\"checkbox-group\"` to the `FieldGroup` component for proper styling and spacing.\n\n::component-preview\n---\nname: FormischCheckbox\nclass: sm:[&_.preview]:h-[700px] sm:[&_pre]:!h-[700px]\nchromeLessOnMobile: true\n---\n::\n\n```vue showLineNumbers {15-22}\n\u003Ctemplate>\n  \u003CFormischField :of=\"form\" :path=\"['tasks']\" v-slot=\"field\">\n    \u003CFieldSet>\n      \u003CFieldLegend variant=\"label\">Tasks\u003C\u002FFieldLegend>\n      \u003CFieldDescription>\n        Get notified when tasks you've created have updates.\n      \u003C\u002FFieldDescription>\n      \u003CFieldGroup data-slot=\"checkbox-group\">\n        \u003CField\n          v-for=\"task in tasks\"\n          :key=\"task.id\"\n          orientation=\"horizontal\"\n          :data-invalid=\"field.errors !== null\"\n        >\n          \u003CCheckbox\n            :id=\"`form-checkbox-${task.id}`\"\n            :aria-invalid=\"field.errors !== null\"\n            :model-value=\"field.input?.includes(task.id) ?? false\"\n            @update:model-value=\"\n              (checked) =>\n                (field.input = checked\n                  ? [...(field.input ?? []), task.id]\n                  : (field.input ?? []).filter((value) => value !== task.id))\n            \"\n          \u002F>\n          \u003CFieldLabel :for=\"`form-checkbox-${task.id}`\" class=\"font-normal\">\n            {{ task.label }}\n          \u003C\u002FFieldLabel>\n        \u003C\u002FField>\n      \u003C\u002FFieldGroup>\n      \u003CFieldError\n        v-if=\"field.errors\"\n        :errors=\"field.errors.map((message) => ({ message }))\"\n      \u002F>\n    \u003C\u002FFieldSet>\n  \u003C\u002FFormischField>\n\u003C\u002Ftemplate>\n```\n\n### Radio Group\n\n- For radio groups, bind `field.input` with `v-model` on the `RadioGroup` component.\n- To show errors, add the `:aria-invalid` prop to the `RadioGroupItem` component and the `:data-invalid` prop to the `Field` component.\n\n::component-preview\n---\nname: FormischRadioGroup\nclass: sm:[&_.preview]:h-[700px] sm:[&_pre]:!h-[700px]\nchromeLessOnMobile: true\n---\n::\n\n```vue showLineNumbers {8}\n\u003Ctemplate>\n  \u003CFormischField :of=\"form\" :path=\"['plan']\" v-slot=\"field\">\n    \u003CFieldSet>\n      \u003CFieldLegend>Plan\u003C\u002FFieldLegend>\n      \u003CFieldDescription>\n        You can upgrade or downgrade your plan at any time.\n      \u003C\u002FFieldDescription>\n      \u003CRadioGroup v-model=\"field.input\">\n        \u003CFieldLabel\n          v-for=\"plan in plans\"\n          :key=\"plan.id\"\n          :for=\"`form-radiogroup-${plan.id}`\"\n        >\n          \u003CField orientation=\"horizontal\" :data-invalid=\"field.errors !== null\">\n            \u003CFieldContent>\n              \u003CFieldTitle>{{ plan.title }}\u003C\u002FFieldTitle>\n              \u003CFieldDescription>{{ plan.description }}\u003C\u002FFieldDescription>\n            \u003C\u002FFieldContent>\n            \u003CRadioGroupItem\n              :value=\"plan.id\"\n              :id=\"`form-radiogroup-${plan.id}`\"\n              :aria-invalid=\"field.errors !== null\"\n            \u002F>\n          \u003C\u002FField>\n        \u003C\u002FFieldLabel>\n      \u003C\u002FRadioGroup>\n      \u003CFieldError\n        v-if=\"field.errors\"\n        :errors=\"field.errors.map((message) => ({ message }))\"\n      \u002F>\n    \u003C\u002FFieldSet>\n  \u003C\u002FFormischField>\n\u003C\u002Ftemplate>\n```\n\n### Switch\n\n- For switches, bind `field.input` with `v-model` on the `Switch` component.\n- To show errors, add the `:aria-invalid` prop to the `Switch` component and the `:data-invalid` prop to the `Field` component.\n\n::component-preview\n---\nname: FormischSwitch\nclass: sm:[&_.preview]:h-[500px] sm:[&_pre]:!h-[500px]\nchromeLessOnMobile: true\n---\n::\n\n```vue showLineNumbers {15-19}\n\u003Ctemplate>\n  \u003CFormischField :of=\"form\" :path=\"['twoFactor']\" v-slot=\"field\">\n    \u003CField orientation=\"horizontal\" :data-invalid=\"field.errors !== null\">\n      \u003CFieldContent>\n        \u003CFieldLabel for=\"form-twoFactor\">\n          Multi-factor authentication\n        \u003C\u002FFieldLabel>\n        \u003CFieldDescription>\n          Enable multi-factor authentication to secure your account.\n        \u003C\u002FFieldDescription>\n        \u003CFieldError\n          v-if=\"field.errors\"\n          :errors=\"field.errors.map((message) => ({ message }))\"\n        \u002F>\n      \u003C\u002FFieldContent>\n      \u003CSwitch\n        id=\"form-twoFactor\"\n        v-model=\"field.input\"\n        :aria-invalid=\"field.errors !== null\"\n      \u002F>\n    \u003C\u002FField>\n  \u003C\u002FFormischField>\n\u003C\u002Ftemplate>\n```\n\n### Complex Forms\n\nHere is an example of a more complex form with multiple fields and validation.\n\n::component-preview\n---\nname: FormischComplex\nclass: sm:[&_.preview]:h-[1300px] sm:[&_pre]:!h-[1300px]\nchromeLessOnMobile: true\n---\n::\n\n## Resetting the Form\n\nFormisch exposes a top-level `reset` function. Pass the form store to reset it to its initial input.\n\n```vue showLineNumbers\n\u003Ctemplate>\n  \u003CButton type=\"button\" variant=\"outline\" @click=\"reset(form)\">\n    Reset\n  \u003C\u002FButton>\n\u003C\u002Ftemplate>\n```\n\nYou can also reset to new initial values, or reset while keeping the user's current input:\n\n```ts showLineNumbers\n\u002F\u002F Reset to a fresh set of initial values\nreset(form, { initialInput: { title: '', description: '' } })\n\n\u002F\u002F Sync the baseline to new server data, but keep the user's edits\nreset(form, { initialInput: serverData, keepInput: true })\n```\n\n## Array Fields\n\nFormisch provides a `FieldArray` component and a set of helper functions for managing dynamic array fields. Use it whenever you need to add, remove, or reorder items.\n\n::component-preview\n---\nname: FormischArray\nclass: sm:[&_.preview]:h-[700px] sm:[&_pre]:!h-[700px]\nchromeLessOnMobile: true\n---\n::\n\n### Using FieldArray\n\n`FieldArray` follows the same slot pattern as `Field`. Its `items` array contains a stable key per item that you should use as the `v-for` key.\n\n```vue showLineNumbers {2,8-14}\n\u003Cscript setup lang=\"ts\">\nimport { Field as FormischField, FieldArray, insert, remove } from '@formisch\u002Fvue'\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003CFieldArray :of=\"form\" :path=\"['emails']\" v-slot=\"fieldArray\">\n    \u003CFieldGroup class=\"gap-4\">\n      \u003CFormischField\n        v-for=\"(item, index) in fieldArray.items\"\n        :key=\"item\"\n        :of=\"form\"\n        :path=\"['emails', index, 'address']\"\n        v-slot=\"field\"\n      >\n        \u003C!-- ... -->\n      \u003C\u002FFormischField>\n    \u003C\u002FFieldGroup>\n  \u003C\u002FFieldArray>\n\u003C\u002Ftemplate>\n```\n\n### Array Field Structure\n\nWrap your array fields in a `FieldSet` with a `FieldLegend` and `FieldDescription`.\n\n```vue showLineNumbers\n\u003Ctemplate>\n  \u003CFieldSet class=\"gap-4\">\n    \u003CFieldLegend variant=\"label\">Email Addresses\u003C\u002FFieldLegend>\n    \u003CFieldDescription>\n      Add up to 5 email addresses where we can contact you.\n    \u003C\u002FFieldDescription>\n    \u003CFieldGroup class=\"gap-4\">\n      \u003C!-- Array items go here -->\n    \u003C\u002FFieldGroup>\n  \u003C\u002FFieldSet>\n\u003C\u002Ftemplate>\n```\n\n### Adding Items\n\nUse the `insert` function to add new items to the array. By default new items are appended to the end. You can also pass an `at` index to insert at a specific position.\n\n```vue showLineNumbers\n\u003Ctemplate>\n  \u003CButton\n    type=\"button\"\n    variant=\"outline\"\n    size=\"sm\"\n    @click=\"insert(form, { path: ['emails'], initialInput: { address: '' } })\"\n    :disabled=\"fieldArray.items.length >= 5\"\n  >\n    Add Email Address\n  \u003C\u002FButton>\n\u003C\u002Ftemplate>\n```\n\n### Removing Items\n\nUse the `remove` function with an `at` index to remove items from the array.\n\n```vue showLineNumbers\n\u003Ctemplate>\n  \u003CInputGroupAddon v-if=\"fieldArray.items.length > 1\" align=\"inline-end\">\n    \u003CInputGroupButton\n      type=\"button\"\n      variant=\"ghost\"\n      size=\"icon-xs\"\n      @click=\"remove(form, { path: ['emails'], at: index })\"\n      :aria-label=\"`Remove email ${index + 1}`\"\n    >\n      \u003CXIcon \u002F>\n    \u003C\u002FInputGroupButton>\n  \u003C\u002FInputGroupAddon>\n\u003C\u002Ftemplate>\n```\n\nFormisch also exposes `move`, `swap`, and `replace` for reordering and replacing items. They follow the same `(form, config)` signature.\n\n### Array Validation\n\nUse Valibot's `array` and pipeline validators to constrain array fields.\n\n```vue showLineNumbers\n\u003Cscript setup lang=\"ts\">\nconst FormSchema = v.object({\n  emails: v.pipe(\n    v.array(\n      v.object({\n        address: v.pipe(\n          v.string(),\n          v.nonEmpty('Enter an email address.'),\n          v.email('Enter a valid email address.'),\n        ),\n      }),\n    ),\n    v.minLength(1, 'Add at least one email address.'),\n    v.maxLength(5, 'You can add up to 5 email addresses.'),\n  ),\n})\n\u003C\u002Fscript>\n```\n",{"title":358,"description":1525},"SZM_08sNCSjjGUom3E6YcFdDR9kUka-IiRObRQDtIAE",[1533,1534],{"title":354,"path":355,"stem":356,"children":-1},{"title":1535,"path":1536,"stem":1537,"children":-1},"MCP Server","\u002Fdocs\u002Fmcp","docs\u002Fmcp",1785648929282]