- Accordion
- Action Bar
- Alert
- Alert Dialog
- Angle Slider
- Aspect Ratio
- Attachment
- Avatar
- Avatar Group
- Badge
- Badge Overflow
- Banner
- Breadcrumb
- Bubble
- Button
- Button Group
- Calendar
- Card
- Carousel
- Chart
- Checkbox
- Checkbox Group
- Chip
- Circular Progress
- Client Only
- Collapsible
- Color Picker
- Color Swatch
- Combobox
- Combobox Advanced
- Command
- Compare Slider
- Composition
- Context Menu
- Cropper
- Data Grid
- Data Table
- Data Table Advanced
- Date Picker
- Dialog
- Direction Provider
- Drawer
- Dropdown Menu
- Editable
- Empty
- Field
- File Upload
- Form
- FPS
- Gauge
- Hitbox
- Hover Card
- Input
- Input Group
- Input OTP
- Item
- Kanban
- Kbd
- Kbd Advanced
- Key Value
- Label
- List
- Listbox
- Map
- Marker
- Marquee
- Mask Input
- Masonry
- Media Player
- Mention
- Menubar
- Message
- Message Scroller
- Native Select
- Navigation Menu
- Number Field
- Pagination
- Pending
- Phone Input
- Pin Input
- Popover
- Portal
- Presence
- Progress
- QR Code
- Questionnaire
- Radio Group
- Range Calendar
- Rating
- Relative Time Card
- Resizable
- Responsive Dialog
- Scroll Area
- Scroll Spy
- Scroller
- Segmented Input
- Select
- Selection Toolbar
- Separator
- Sheet
- Sidebar
- Skeleton
- Slider
- Software Purchase Card
- Sonner
- Sortable
- Speed Dial
- Spinner
- Stack
- Stat
- Status
- Stepper
- Stepper Advanced
- Swap
- Switch
- Table
- Tabs
- Tags Input
- Tags Input Advanced
- Textarea
- Time Picker
- Timeline
- Toast
- Toggle
- Toggle Group
- Tooltip
- Tour
- Typography
- Visually Hidden
- Visually Hidden Input
We are not actively developing this component anymore.
Komponen Form adalah lapisan abstraksi di atas library vee-validate. Ke depannya, kami menyarankan Anda memakai komponen <Field /> untuk membangun form. Keterangan lengkapnya ada di dokumentasi Form.
Form itu rumit. Ia salah satu hal yang paling sering Anda bangun di aplikasi web, sekaligus salah satu yang paling ruwet.
Form HTML yang dirancang dengan baik punya ciri-ciri berikut:
- Terstruktur rapi dan bermakna secara semantik.
- Mudah dipakai dan dinavigasi, termasuk lewat keyboard.
- Mudah diakses lewat atribut ARIA dan label yang benar.
- Mendukung validasi di sisi klien maupun server.
- Tampilannya rapi dan selaras dengan sisa aplikasi.
Di panduan ini kita akan membangun form memakai vee-validate dan zod. Komponen <FormField> akan kita pakai untuk menyusun form yang mudah diakses dari komponen Reka UI.
Features
Komponen <Form /> adalah pembungkus library vee-validate. Ia menyediakan beberapa hal:
- Komponen yang bisa dikomposisikan untuk membangun form.
- Komponen
<FormField />untuk membangun field yang nilainya dikendalikan. - Validasi form memakai
zod. - Menerapkan atribut
ariayang tepat pada tiap field sesuai keadaannya, sekaligus mengurus ID yang unik. - Dirancang agar bekerja dengan semua komponen Reka UI.
- Bebas memilih library skema. Kami memakai
zod, tapi Anda bisa memakai library validasi lain yang didukung, sepertiyupatauvalibot. - Markup dan style-nya sepenuhnya di tangan Anda.
vee-validate menyediakan dua gaya penulisan untuk menambahkan validasi ke form Anda.
- Composition API
- Higher-order component (HOC)
Anatomy
<template>
<Form>
<FormField>
<FormItem>
<FormLabel />
<FormControl>
<!-- any Form Input component or native input elements -->
</FormControl>
<FormDescription />
<FormMessage />
</FormItem>
</FormField>
</Form>
</template>Examples
Komponen Input
<template>
<FormField v-slot="{ componentField }">
<FormItem>
<FormLabel>Username</FormLabel>
<FormControl>
<Input placeholder="shadcn" v-bind="componentField" />
</FormControl>
<FormDescription />
<FormMessage />
</FormItem>
</FormField>
</template>2
3
4
5
6
7
8
9
10
11
12
Elemen input bawaan
<template>
<FormField v-slot="{ field }">
<FormItem>
<FormLabel>Username</FormLabel>
<FormControl>
<input placeholder="shadcn" v-bind="field">
</FormControl>
<FormDescription />
<FormMessage />
</FormItem>
</FormField>
</template>2
3
4
5
6
7
8
9
10
11
12
Installation
pnpm dlx shadcn-vue@latest add formPasang dependensi berikut:
pnpm add reka-ui vee-validate @vee-validate/zod zodSalin dan tempel kode sumber di GitHub ke project Anda.
Sesuaikan path import dengan struktur project Anda.
Usage
<script setup lang="ts">
import {
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from '@/components/ui/form'
</script>
<template>
<FormField v-slot="{ componentField }" name="username">
<FormItem>
<FormLabel>Username</FormLabel>
<FormControl>
<Input placeholder="shadcn" v-bind="componentField" />
</FormControl>
<FormDescription>
This is your public display name.
</FormDescription>
<FormMessage />
</FormItem>
</FormField>
</template>2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Buat skema form
Tentukan bentuk form Anda memakai skema Zod. Penjelasan lengkap soal Zod ada di dokumentasi Zod.
Pakai @vee-validate/zod untuk menyambungkan validasi skema Zod dengan vee-validate.
toTypedSchema sekaligus membuat nilai form dan nilai yang dikirim bertipe otomatis, mencakup tipe masukan maupun keluaran skema tersebut.
<script setup lang="ts">
import { toTypedSchema } from '@vee-validate/zod'
import * as z from 'zod'
const formSchema = toTypedSchema(z.object({
username: z.string().min(2).max(50),
}))
</script>2
3
4
5
6
7
8
Definisikan form
Buat form memakai composable useForm dari vee-validate, atau memakai komponen <Form />.
<script setup lang="ts">
import { useForm } from 'vee-validate'
import { toTypedSchema } from '@vee-validate/zod'
import * as z from 'zod'
import {
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage
} from '@/components/ui/form'
const formSchema = toTypedSchema(z.object({
username: z.string().min(2).max(50),
}))
const form = useForm({
validationSchema: formSchema,
})
const onSubmit = form.handleSubmit((values) => {
console.log('Form submitted!', values)
})
</script>
<template>
<form @submit="onSubmit">
...
</form>
</template>2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<script setup lang="ts">
import { toTypedSchema } from '@vee-validate/zod'
import * as z from 'zod'
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage
} from '@/components/ui/form'
const formSchema = toTypedSchema(z.object({
username: z.string().min(2).max(50),
}))
function onSubmit(values) {
console.log('Form submitted!', values)
}
</script>
<template>
<Form :validation-schema="formSchema" @submit="onSubmit">
...
</Form>
</template>2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Susun form Anda
Melanjutkan langkah sebelumnya, Anda bisa memakai komponen <Form /> atau composable useForm. useForm lebih disarankan karena nilainya otomatis bertipe.
<script setup lang="ts">
import { toTypedSchema } from '@vee-validate/zod'
import { useForm } from 'vee-validate'
import * as z from 'zod'
import { Button } from '@/components/ui/button'
import {
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from '@/components/ui/form'
import { Input } from '@/components/ui/input'
const formSchema = toTypedSchema(z.object({
username: z.string().min(2).max(50),
}))
const form = useForm({
validationSchema: formSchema,
})
const onSubmit = form.handleSubmit((values) => {
console.log('Form submitted!', values)
})
</script>
<template>
<form @submit="onSubmit">
<FormField v-slot="{ componentField }" name="username">
<FormItem>
<FormLabel>Username</FormLabel>
<FormControl>
<Input type="text" placeholder="shadcn" v-bind="componentField" />
</FormControl>
<FormDescription>
This is your public display name.
</FormDescription>
<FormMessage />
</FormItem>
</FormField>
<Button type="submit">
Submit
</Button>
</form>
</template>2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
Selesai
Selesai. Sekarang Anda punya form yang mudah diakses, aman secara tipe, dan tervalidasi di sisi klien.