Form
basecn/formFreeComponent
Renders a form built with React Hook Form.
Live preview
live · rendered by the registry
Rendered by basecn on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://basecn.dev/r/form.jsonSource
1"use client";23import { useRender } from "@base-ui/react/use-render";4import * as React from "react";5import {6 Controller,7 FormProvider,8 useFormContext,9 useFormState,10 type ControllerProps,11 type FieldPath,12 type FieldValues,13} from "react-hook-form";1415import { cn } from "@/lib/utils";16import { Label } from "@/registry/components/ui/label";1718const Form = FormProvider;1920type FormFieldContextValue<21 TFieldValues extends FieldValues = FieldValues,22 TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>23> = {24 name: TName;25};2627const FormFieldContext = React.createContext<FormFieldContextValue>(28 {} as FormFieldContextValue29);3031const FormField = <32 TFieldValues extends FieldValues = FieldValues,33 TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>34>({35 ...props36}: ControllerProps<TFieldValues, TName>) => {37 return (38 <FormFieldContext.Provider value={{ name: props.name }}>39 <Controller {...props} />40 </FormFieldContext.Provider>41 );42};4344const useFormField = () => {45 const fieldContext = React.useContext(FormFieldContext);46 const itemContext = React.useContext(FormItemContext);47 const { getFieldState } = useFormContext();48 const formState = useFormState({ name: fieldContext.name });49 const fieldState = getFieldState(fieldContext.name, formState);5051 if (!fieldContext) {52 throw new Error("useFormField should be used within <FormField>");53 }5455 const { id } = itemContext;5657 return {58 id,59 name: fieldContext.name,60 formItemId: `${id}-form-item`,61 formDescriptionId: `${id}-form-item-description`,62 formMessageId: `${id}-form-item-message`,63 ...fieldState,64 };65};6667type FormItemContextValue = {68 id: string;69};7071const FormItemContext = React.createContext<FormItemContextValue>(72 {} as FormItemContextValue73);7475function FormItem({ className, ...props }: React.ComponentProps<"div">) {76 const id = React.useId();7778 return (79 <FormItemContext.Provider value={{ id }}>80 <div81 data-slot="form-item"82 className={cn("grid gap-2", className)}83 {...props}84 />85 </FormItemContext.Provider>86 );87}8889function FormLabel({90 className,91 ...props92}: React.ComponentProps<typeof Label>) {93 const { error, formItemId } = useFormField();9495 return (96 <Label97 data-slot="form-label"98 data-error={!!error}99 className={cn("data-[error=true]:text-destructive", className)}100 htmlFor={formItemId}101 {...props}102 />103 );104}105106function FormControl({107// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from basecn
All 56 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Accordionaccordion | basecn | Components | Free | 2 deps | |
| Alertalert | basecn | Components | Free | 1 dep | |
| Alert Dialogalert-dialog | basecn | Components | Free | 1 dep | |
| Aspect Ratioaspect-ratio | basecn | Components | Free | no deps | |
| Autocompleteautocomplete | basecn | Components | Free | 2 deps | |
| Avataravatar | basecn | Components | Free | 1 dep | |
| Badgebadge | basecn | Components | Free | 2 deps | |
| Breadcrumbbreadcrumb | basecn | Components | Free | 2 deps |
