FormCard
fable-ui/form-cardFreeComponent
Collect a few structured fields mid-conversation.
Live preview
live · rendered by the registry
Rendered by fable-ui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://fable-ui.shobky.com/r/form-card.jsonSource
1"use client"23import { useMemo, useState } from "react"45import { Button } from "@/components/ui/button"6import {7 Card,8 CardContent,9 CardDescription,10 CardFooter,11 CardHeader,12 CardTitle,13} from "@/components/ui/card"14import { Input } from "@/components/ui/input"15import { Textarea } from "@/components/ui/textarea"16import { cn } from "@/lib/utils"1718export type FormCardField =19 | {20 name: string21 label: string22 type: "text" | "date" | "textarea"23 required?: boolean24 placeholder?: string25 }26 | {27 name: string28 label: string29 type: "number"30 required?: boolean31 placeholder?: string32 min?: number33 max?: number34 }35 | {36 name: string37 label: string38 type: "select"39 required?: boolean40 options: { label: string; value: string }[]41 }42 | { name: string; label: string; type: "toggle"; required?: boolean }4344export type FormCardProps = {45 title: string46 description?: string47 submitLabel?: string48 fields: FormCardField[]49 isLoading?: boolean50 isDisabled?: boolean51 error?: {52 title: string53 description?: string54 }55 onSubmit?: (values: Record<string, string | number | boolean>) => void56}5758export function FormCard({59 title,60 description,61 submitLabel = "Submit",62 fields = [],63 isLoading,64 isDisabled,65 error,66 onSubmit,67}: FormCardProps) {68 const initialValues = useMemo<69 Record<string, string | number | boolean>70 >(() => {71 return Object.fromEntries(72 fields.map((field) => [field.name, field.type === "toggle" ? false : ""])73 )74 }, [fields])75 const [editedValues, setEditedValues] =76 useState<Record<string, string | number | boolean>>(initialValues)77 const values = useMemo(() => {78 const next = { ...initialValues }7980 for (const field of fields) {81 if (field.name in editedValues) {82 next[field.name] = editedValues[field.name]83 }84 }8586 return next87 }, [editedValues, fields, initialValues])88 const formDisabled = Boolean(isDisabled || isLoading || error)8990 function setValue(name: string, value: string | number | boolean) {91 setEditedValues((current) => ({ ...current, [name]: value }))92 }9394 return (95 <Card96 className="w-full max-w-2xl"97 data-fable-ui="form-card"98 aria-busy={isLoading || undefined}99 >100 <CardHeader>101 <CardTitle className="text-base">{title || "Collect input"}</CardTitle>102// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from fable-ui
All 10 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| ConfirmationCardconfirmation-card | fable-ui | Components | Free | 2 deps · 4 files | |
| MetricCardmetric-card | fable-ui | Components | Free | 3 deps · 4 files | |
| SuggestedActionssuggested-actions | fable-ui | Components | Free | 2 deps · 4 files |
