Installation
Complete project setup first. Your configuration
must select vue/reka and include your Design System ID.
pnpm exec frontfriend download form -f vue --primitive rekaReview dependencies reported by the downloader and keep your source changes in version control.
Usage
<script setup lang="ts">
import { Form } from "@/components/ui/form";
import { FormField } from "@/components/ui/form";
import { FormItem } from "@/components/ui/form";
import { FormLabel } from "@/components/ui/form";
import { FormControl } from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { FormMessage } from "@/components/ui/form";
import { Button } from "@/components/ui/button";
import * as UI from "@/components/ui/form";
const Component = UI.Form;
const args = {
"orientation": "vertical",
} satisfies Partial<
InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
Record<string, unknown> & { orientation?: "horizontal" | "vertical" };
</script>
<template>
<Form @submit="() => undefined"
><FormField v-slot="{ componentField }" name="email"
><FormItem :orientation="args.orientation"
><FormLabel>Email</FormLabel
><FormControl
><Input v-bind="componentField" type="email" /></FormControl
><FormMessage /></FormItem></FormField
><Button type="submit">Submit</Button></Form
>
</template> Examples
Default
<script setup lang="ts">
import { toTypedSchema } from "@vee-validate/zod";
import { z } from "zod";
import { useForm } from "vee-validate";
import { Form } from "@/components/ui/form";
import { FormField } from "@/components/ui/form";
import { FormItem } from "@/components/ui/form";
import { FormLabel } from "@/components/ui/form";
import { FormControl } from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { FormMessage } from "@/components/ui/form";
import { Button } from "@/components/ui/button";
import * as UI from "@/components/ui/form";
function useDemoForm() {
const formSchema = toTypedSchema(
z.object({
login: z
.string()
.min(2, { message: "Login must be at least 2 characters" }),
password: z
.string()
.min(2, { message: "Password must be at least 2 characters" }),
}),
);
useForm({ validationSchema: formSchema });
const onSubmit = (values: Record<string, unknown>) => console.log(values);
return { onSubmit };
}
const Component = UI.Form;
const args = {
} satisfies Partial<
InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
Record<string, unknown>;
const { onSubmit } = useDemoForm();
</script>
<template>
<Form @submit="onSubmit" class="flex w-full flex-col items-start gap-8"
><FormField v-slot="{ componentField }" name="login"
><FormItem orientation="vertical" class="w-full"
><FormLabel>Login</FormLabel
><FormControl
><Input class="w-full" v-bind="componentField" /></FormControl
><FormMessage /></FormItem></FormField
><FormField v-slot="{ componentField }" name="password"
><FormItem orientation="vertical" class="w-full"
><FormLabel>Password</FormLabel
><FormControl
><Input
class="w-full"
type="password"
v-bind="componentField" /></FormControl
><FormMessage /></FormItem></FormField
><Button type="submit" class="w-full" variant="main">Submit</Button></Form
>
</template> Horizontal
<script setup lang="ts">
import { toTypedSchema } from "@vee-validate/zod";
import { z } from "zod";
import { useForm } from "vee-validate";
import { Form } from "@/components/ui/form";
import { FormField } from "@/components/ui/form";
import { FormItem } from "@/components/ui/form";
import { FormLabel } from "@/components/ui/form";
import { FormControl } from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { FormMessage } from "@/components/ui/form";
import { Button } from "@/components/ui/button";
import * as UI from "@/components/ui/form";
function useDemoForm() {
const formSchema = toTypedSchema(
z.object({
login: z
.string()
.min(2, { message: "Login must be at least 2 characters" }),
password: z
.string()
.min(2, { message: "Password must be at least 2 characters" }),
}),
);
useForm({ validationSchema: formSchema });
const onSubmit = (values: Record<string, unknown>) => console.log(values);
return { onSubmit };
}
const Component = UI.Form;
const args = {
} satisfies Partial<
InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
Record<string, unknown>;
const { onSubmit } = useDemoForm();
</script>
<template>
<Form @submit="onSubmit" class="flex w-full flex-row items-start gap-8"
><FormField v-slot="{ componentField }" name="login"
><FormItem orientation="horizontal" class="w-full"
><FormLabel>Login</FormLabel
><FormControl
><Input class="w-full" v-bind="componentField" /></FormControl
><FormMessage /></FormItem></FormField
><FormField v-slot="{ componentField }" name="password"
><FormItem orientation="horizontal" class="w-full"
><FormLabel>Password</FormLabel
><FormControl
><Input
class="w-full"
type="password"
v-bind="componentField" /></FormControl
><FormMessage /></FormItem></FormField
><Button type="submit" class="w-fit" variant="main">Submit</Button></Form
>
</template> API reference
Frontfriend-owned props. Native HTML and inherited primitive props remain documented by Reka UI.
FormDescription
| Prop | Type | Default | Description |
|---|---|---|---|
class | HTMLAttributes["class"] | — |
FormItem
| Prop | Type | Default | Description |
|---|---|---|---|
class | HTMLAttributes["class"] | — | |
orientation | "vertical" | "horizontal" | — |
FormLabel
| Prop | Type | Default | Description |
|---|---|---|---|
class | HTMLAttributes["class"] | — | |
variant | "main" | "secondary" | — |
FormMessage
| Prop | Type | Default | Description |
|---|---|---|---|
class | HTMLAttributes["class"] | — |
Configuration determines the actual classes and available styling hooks. See Theming & component configuration before introducing a repeated local override.