Form
basecn/form-tanstackFreeComponent
Renders a form built with Tanstack 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-tanstack.jsonSource
1"use client";23import { useRender } from "@base-ui/react/use-render";4import { createFormHookContexts, createFormHook } from "@tanstack/react-form";5import * as React from "react";67import { cn } from "@/lib/utils";8import { Label } from "@/registry/components/ui/label";910const { fieldContext, formContext, useFieldContext } = createFormHookContexts();1112const { useAppForm } = createFormHook({13 fieldComponents: {14 Label: FieldLabel,15 Control: FieldControl,16 Description: FieldDescription,17 Message: FieldMessage,18 },19 formComponents: {20 Item: FormItem,21 },22 fieldContext,23 formContext,24});2526const useFormField = () => {27 const itemContext = React.useContext(FormItemContext);28 const fieldContext = useFieldContext();2930 if (!fieldContext) {31 throw new Error("useFormField should be used within <field.Container>");32 }3334 const { id } = itemContext;3536 return {37 id,38 name: fieldContext.name,39 formItemId: `${id}-form-item`,40 formDescriptionId: `${id}-form-item-description`,41 formMessageId: `${id}-form-item-message`,42 ...fieldContext.state.meta,43 };44};4546type FormItemContextValue = {47 id: string;48};4950const FormItemContext = React.createContext<FormItemContextValue>(51 {} as FormItemContextValue52);5354function FormItem({ className, ...props }: React.ComponentProps<"div">) {55 const id = React.useId();5657 return (58 <FormItemContext.Provider value={{ id }}>59 <div60 data-slot="form-item"61 className={cn("grid gap-2", className)}62 {...props}63 />64 </FormItemContext.Provider>65 );66}6768function FieldLabel({69 className,70 ...props71}: React.ComponentProps<typeof Label>) {72 const { formItemId, isValid } = useFormField();7374 return (75 <Label76 data-slot="field-label"77 data-error={!isValid}78 className={cn("data-[error=true]:text-destructive", className)}79 htmlFor={formItemId}80 {...props}81 />82 );83}8485function FieldControl({86 children = <div />,87}: {88 children?: useRender.RenderProp;89}) {90 const { formItemId, isValid, formDescriptionId, formMessageId } =91 useFormField();9293 return useRender({94 render: children,95 props: {96 "data-slot": "field-control",97 id: formItemId,98 "aria-describedby": isValid99 ? `${formDescriptionId}`100 : `${formDescriptionId} ${formMessageId}`,101 "aria-invalid": !isValid,102 },103 });104}105106function FieldDescription({ className, ...props }: React.ComponentProps<"p">) {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 |
