Compare commits
No commits in common. "c2107b14a3bdfbba58738d65f1cc82f45ae8d68e" and "c4b61069fd2f72115b7b98e164b26c41fc5a40aa" have entirely different histories.
c2107b14a3
...
c4b61069fd
|
@ -894,22 +894,6 @@ body {
|
||||||
max-height: 100vh;
|
max-height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
.min-h-40 {
|
|
||||||
min-height: 10rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.min-h-6 {
|
|
||||||
min-height: 1.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.min-h-8 {
|
|
||||||
min-height: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.min-h-10 {
|
|
||||||
min-height: 2.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.w-10 {
|
.w-10 {
|
||||||
width: 2.5rem;
|
width: 2.5rem;
|
||||||
}
|
}
|
||||||
|
@ -1556,22 +1540,6 @@ body {
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.leading-10 {
|
|
||||||
line-height: 2.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.leading-8 {
|
|
||||||
line-height: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.leading-6 {
|
|
||||||
line-height: 1.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.leading-5 {
|
|
||||||
line-height: 1.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tracking-tight {
|
.tracking-tight {
|
||||||
letter-spacing: -0.025em;
|
letter-spacing: -0.025em;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,128 @@
|
||||||
|
"use client"
|
||||||
|
|
||||||
|
import { zodResolver } from "@hookform/resolvers/zod"
|
||||||
|
import { useForm } from "react-hook-form"
|
||||||
|
import { z } from "zod"
|
||||||
|
|
||||||
|
import { Button } from "@/components/ui/button"
|
||||||
|
import { Checkbox } from "@/components/ui/checkbox"
|
||||||
|
import {
|
||||||
|
Form,
|
||||||
|
FormControl,
|
||||||
|
FormDescription,
|
||||||
|
FormField,
|
||||||
|
FormItem,
|
||||||
|
FormLabel,
|
||||||
|
FormMessage,
|
||||||
|
} from "@/components/ui/form"
|
||||||
|
import { toast } from "@/components/ui/use-toast"
|
||||||
|
|
||||||
|
const items = [
|
||||||
|
{
|
||||||
|
id: "recents",
|
||||||
|
label: "Recents",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "home",
|
||||||
|
label: "Home",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "applications",
|
||||||
|
label: "Applications",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "desktop",
|
||||||
|
label: "Desktop",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "downloads",
|
||||||
|
label: "Downloads",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "documents",
|
||||||
|
label: "Documents",
|
||||||
|
},
|
||||||
|
] as const
|
||||||
|
|
||||||
|
const FormSchema = z.object({
|
||||||
|
items: z.array(z.string()).refine((value) => value.some((item) => item), {
|
||||||
|
message: "You have to select at least one item.",
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
|
||||||
|
export function CheckboxReactHookFormMultiple() {
|
||||||
|
const form = useForm<z.infer<typeof FormSchema>>({
|
||||||
|
resolver: zodResolver(FormSchema),
|
||||||
|
defaultValues: {
|
||||||
|
items: ["recents", "home"],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
function onSubmit(data: z.infer<typeof FormSchema>) {
|
||||||
|
toast({
|
||||||
|
title: "You submitted the following values:",
|
||||||
|
description: (
|
||||||
|
<pre className="mt-2 w-[340px] rounded-md bg-slate-950 p-4">
|
||||||
|
<code className="text-white">{JSON.stringify(data, null, 2)}</code>
|
||||||
|
</pre>
|
||||||
|
),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Form {...form}>
|
||||||
|
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="items"
|
||||||
|
render={() => (
|
||||||
|
<FormItem>
|
||||||
|
<div className="mb-4">
|
||||||
|
<FormLabel className="text-base">Sidebar</FormLabel>
|
||||||
|
<FormDescription>
|
||||||
|
Select the items you want to display in the sidebar.
|
||||||
|
</FormDescription>
|
||||||
|
</div>
|
||||||
|
{items.map((item) => (
|
||||||
|
<FormField
|
||||||
|
key={item.id}
|
||||||
|
control={form.control}
|
||||||
|
name="items"
|
||||||
|
render={({ field }) => {
|
||||||
|
return (
|
||||||
|
<FormItem
|
||||||
|
key={item.id}
|
||||||
|
className="flex flex-row items-start space-x-3 space-y-0"
|
||||||
|
>
|
||||||
|
<FormControl>
|
||||||
|
<Checkbox
|
||||||
|
checked={field.value?.includes(item.id)}
|
||||||
|
onCheckedChange={(checked) => {
|
||||||
|
return checked
|
||||||
|
? field.onChange([...field.value, item.id])
|
||||||
|
: field.onChange(
|
||||||
|
field.value?.filter(
|
||||||
|
(value) => value !== item.id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormLabel className="text-sm font-normal">
|
||||||
|
{item.label}
|
||||||
|
</FormLabel>
|
||||||
|
</FormItem>
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<Button type="submit">Submit</Button>
|
||||||
|
</form>
|
||||||
|
</Form>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
"use client"
|
||||||
|
|
||||||
|
import { zodResolver } from "@hookform/resolvers/zod"
|
||||||
|
import { CalendarIcon } from "@radix-ui/react-icons"
|
||||||
|
import { format } from "date-fns"
|
||||||
|
import { useForm } from "react-hook-form"
|
||||||
|
import { z } from "zod"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
import { Button } from "@/components/ui/button"
|
||||||
|
import { Calendar } from "@/components/ui/calendar"
|
||||||
|
import {
|
||||||
|
Form,
|
||||||
|
FormControl,
|
||||||
|
FormDescription,
|
||||||
|
FormField,
|
||||||
|
FormItem,
|
||||||
|
FormLabel,
|
||||||
|
FormMessage,
|
||||||
|
} from "@/components/ui/form"
|
||||||
|
import {
|
||||||
|
Popover,
|
||||||
|
PopoverContent,
|
||||||
|
PopoverTrigger,
|
||||||
|
} from "@/components/ui/popover"
|
||||||
|
import { toast } from "@/components/ui/use-toast"
|
||||||
|
|
||||||
|
const FormSchema = z.object({
|
||||||
|
dob: z.date({
|
||||||
|
required_error: "A date of birth is required.",
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
|
||||||
|
export function DatePickerForm() {
|
||||||
|
const form = useForm<z.infer<typeof FormSchema>>({
|
||||||
|
resolver: zodResolver(FormSchema),
|
||||||
|
})
|
||||||
|
|
||||||
|
function onSubmit(data: z.infer<typeof FormSchema>) {
|
||||||
|
toast({
|
||||||
|
title: "You submitted the following values:",
|
||||||
|
description: (
|
||||||
|
<pre className="mt-2 w-[340px] rounded-md bg-slate-950 p-4">
|
||||||
|
<code className="text-white">{JSON.stringify(data, null, 2)}</code>
|
||||||
|
</pre>
|
||||||
|
),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Form {...form}>
|
||||||
|
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="dob"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem className="flex flex-col">
|
||||||
|
<FormLabel>Date of birth</FormLabel>
|
||||||
|
<Popover>
|
||||||
|
<PopoverTrigger asChild>
|
||||||
|
<FormControl>
|
||||||
|
<Button
|
||||||
|
variant={"outline"}
|
||||||
|
className={cn(
|
||||||
|
"w-[240px] pl-3 text-left font-normal",
|
||||||
|
!field.value && "text-muted-foreground"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{field.value ? (
|
||||||
|
format(field.value, "PPP")
|
||||||
|
) : (
|
||||||
|
<span>Pick a date</span>
|
||||||
|
)}
|
||||||
|
<CalendarIcon className="ml-auto h-4 w-4 opacity-50" />
|
||||||
|
</Button>
|
||||||
|
</FormControl>
|
||||||
|
</PopoverTrigger>
|
||||||
|
<PopoverContent className="w-auto p-0" align="start">
|
||||||
|
<Calendar
|
||||||
|
mode="single"
|
||||||
|
selected={field.value}
|
||||||
|
onSelect={field.onChange}
|
||||||
|
disabled={(date) =>
|
||||||
|
date > new Date() || date < new Date("1900-01-01")
|
||||||
|
}
|
||||||
|
initialFocus
|
||||||
|
/>
|
||||||
|
</PopoverContent>
|
||||||
|
</Popover>
|
||||||
|
<FormDescription>
|
||||||
|
Your date of birth is used to calculate your age.
|
||||||
|
</FormDescription>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Button type="submit">Submit</Button>
|
||||||
|
</form>
|
||||||
|
</Form>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
import { forwardRef } from "react";
|
||||||
|
import { FormField, FormItem, FormMessage } from "@/components/ui/form";
|
||||||
|
import { Popover, PopoverContent, PopoverPortal, PopoverTrigger } from "@radix-ui/react-popover";
|
||||||
|
import GenresTrigger from "./genresTrigger";
|
||||||
|
import GenreCheckbox from "./genreCheckbox";
|
||||||
|
|
||||||
|
export const GenrePicker = forwardRef(
|
||||||
|
({ form, genres }, ref) => (
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="genres"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem className="flex flex-col">
|
||||||
|
<Popover>
|
||||||
|
<GenresTrigger value={field.value} genres={genres} />
|
||||||
|
<PopoverContent ref={ref}>
|
||||||
|
{genres.map((item) => (
|
||||||
|
<FormField
|
||||||
|
key={item.id}
|
||||||
|
control={form.control}
|
||||||
|
name="genres"
|
||||||
|
render={({ field }) => {
|
||||||
|
return (
|
||||||
|
<GenreCheckbox field={field} item={item} />
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</PopoverContent>
|
||||||
|
</Popover>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
)
|
|
@ -11,7 +11,7 @@ export default function GenresTrigger({ value, genres }) {
|
||||||
<Button
|
<Button
|
||||||
variant={"outline"}
|
variant={"outline"}
|
||||||
className={cn(
|
className={cn(
|
||||||
"min-w-fit max-w-full w-fit pl-3 text-left font-normal flex-wrap gap-y-1 h-fit min-h-10",
|
"min-w-fit max-w-full w-fit pl-3 text-left font-normal flex-wrap gap-y-1 h-fit",
|
||||||
!value && "text-muted-foreground"
|
!value && "text-muted-foreground"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
|
|
@ -127,7 +127,6 @@ export default function PubForm({ genres, createPub }) {
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
<Button variant="link" className="p-0" onClick={() => form.setValue("genres", [])}>Clear</Button>
|
|
||||||
</PopoverContent>
|
</PopoverContent>
|
||||||
</Popover>
|
</Popover>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
"use client"
|
||||||
|
|
||||||
|
import Link from "next/link"
|
||||||
|
import { zodResolver } from "@hookform/resolvers/zod"
|
||||||
|
import { useForm } from "react-hook-form"
|
||||||
|
import { z } from "zod"
|
||||||
|
|
||||||
|
import { Button } from "@/components/ui/button"
|
||||||
|
import {
|
||||||
|
Form,
|
||||||
|
FormControl,
|
||||||
|
FormDescription,
|
||||||
|
FormField,
|
||||||
|
FormItem,
|
||||||
|
FormLabel,
|
||||||
|
FormMessage,
|
||||||
|
} from "@/components/ui/form"
|
||||||
|
import {
|
||||||
|
Select,
|
||||||
|
SelectContent,
|
||||||
|
SelectItem,
|
||||||
|
SelectTrigger,
|
||||||
|
SelectValue,
|
||||||
|
} from "@/components/ui/select"
|
||||||
|
import { toast } from "@/components/ui/use-toast"
|
||||||
|
|
||||||
|
const FormSchema = z.object({
|
||||||
|
email: z
|
||||||
|
.string({
|
||||||
|
required_error: "Please select an email to display.",
|
||||||
|
})
|
||||||
|
.email(),
|
||||||
|
})
|
||||||
|
|
||||||
|
export function SelectForm() {
|
||||||
|
const form = useForm<z.infer<typeof FormSchema>>({
|
||||||
|
resolver: zodResolver(FormSchema),
|
||||||
|
})
|
||||||
|
|
||||||
|
function onSubmit(data: z.infer<typeof FormSchema>) {
|
||||||
|
toast({
|
||||||
|
title: "You submitted the following values:",
|
||||||
|
description: (
|
||||||
|
<pre className="mt-2 w-[340px] rounded-md bg-slate-950 p-4">
|
||||||
|
<code className="text-white">{JSON.stringify(data, null, 2)}</code>
|
||||||
|
</pre>
|
||||||
|
),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Form {...form}>
|
||||||
|
<form onSubmit={form.handleSubmit(onSubmit)} className="w-2/3 space-y-6">
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="email"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Email</FormLabel>
|
||||||
|
<Select onValueChange={field.onChange} defaultValue={field.value}>
|
||||||
|
<FormControl>
|
||||||
|
<SelectTrigger>
|
||||||
|
<SelectValue placeholder="Select a verified email to display" />
|
||||||
|
</SelectTrigger>
|
||||||
|
</FormControl>
|
||||||
|
<SelectContent>
|
||||||
|
<SelectItem value="m@example.com">m@example.com</SelectItem>
|
||||||
|
<SelectItem value="m@google.com">m@google.com</SelectItem>
|
||||||
|
<SelectItem value="m@support.com">m@support.com</SelectItem>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
<FormDescription>
|
||||||
|
You can manage email addresses in your{" "}
|
||||||
|
<Link href="/examples/forms">email settings</Link>.
|
||||||
|
</FormDescription>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<Button type="submit">Submit</Button>
|
||||||
|
</form>
|
||||||
|
</Form>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -118,7 +118,6 @@ export default function StoryForm({ genres, createStory, className }: ComponentP
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
<Button variant="link" className="p-0" onClick={() => form.setValue("genres", [])}>Clear</Button>
|
|
||||||
</PopoverContent>
|
</PopoverContent>
|
||||||
</Popover>
|
</Popover>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
|
@ -141,7 +140,6 @@ export default function StoryForm({ genres, createStory, className }: ComponentP
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Button type="submit" className="">Submit</Button>
|
<Button type="submit" className="">Submit</Button>
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue