Form Layout
Settings and signup forms laid out in sections.
Fromblocks.so
Form with Workspace Fields
import { Button } from "@/components/ui/button"
import { Field, FieldLabel } from "@/components/ui/field"
import { Input } from "@/components/ui/input"
import { Separator } from "@/components/ui/separator"
export default function FormLayout01() {
return (
<div className="flex items-center justify-center p-10">
<div className="sm:mx-auto sm:max-w-2xl">
<h3 className="text-balance font-semibold text-2xl text-foreground dark:text-foreground">
Register to workspace
</h3>
<p className="mt-1 text-pretty text-muted-foreground text-sm dark:text-muted-foreground">
Take a few moments to register for your company's workspace
</p>
<form action="#" className="mt-8" method="post">
<div className="grid grid-cols-1 gap-x-4 gap-y-6 sm:grid-cols-6">
<div className="col-span-full sm:col-span-3">
<Field className="gap-2">
<FieldLabel htmlFor="first-name">
First name
<span className="text-red-500">*</span>
</FieldLabel>
<Input
autoComplete="first-name"
id="first-name"
name="first-name"
placeholder="First name"
required
type="text"
/>
</Field>
</div>
<div className="col-span-full sm:col-span-3">
<Field className="gap-2">
<FieldLabel htmlFor="last-name">
Last name
<span className="text-red-500">*</span>
</FieldLabel>
<Input
autoComplete="last-name"
id="last-name"
name="last-name"
placeholder="Last name"
required
type="text"
/>
</Field>
</div>
<div className="col-span-full">
<Field className="gap-2">
<FieldLabel htmlFor="email">
Email
<span className="text-red-500">*</span>
</FieldLabel>
<Input
autoComplete="email"
id="email"
name="email"
placeholder="Email"
required
type="email"
/>
</Field>
</div>
<div className="col-span-full">
<Field className="gap-2">
<FieldLabel htmlFor="address">Address</FieldLabel>
<Input
autoComplete="street-address"
id="address"
name="address"
placeholder="Address"
type="text"
/>
</Field>
</div>
<div className="col-span-full sm:col-span-2">
<Field className="gap-2">
<FieldLabel htmlFor="city">City</FieldLabel>
<Input
autoComplete="address-level2"
id="city"
name="city"
placeholder="City"
type="text"
/>
</Field>
</div>
<div className="col-span-full sm:col-span-2">
<Field className="gap-2">
<FieldLabel htmlFor="state">State</FieldLabel>
<Input
autoComplete="address-level1"
id="state"
name="state"
placeholder="State"
type="text"
/>
</Field>
</div>
<div className="col-span-full sm:col-span-2">
<Field className="gap-2">
<FieldLabel htmlFor="postal-code">Postal code</FieldLabel>
<Input
autoComplete="postal-code"
id="postal-code"
name="postal-code"
placeholder="Postal code"
/>
</Field>
</div>
</div>
<Separator className="my-6" />
<div className="flex items-center justify-end space-x-4">
<Button
className="whitespace-nowrap"
type="button"
variant="outline"
>
Cancel
</Button>
<Button className="whitespace-nowrap" type="submit">
Submit
</Button>
</div>
</form>
</div>
</div>
)
}npx shadcn@latest add https://blocks.so/r/form-layout-01.jsonForm with Side Labels
import { Button } from "@/components/ui/button"
import { Field, FieldDescription, FieldLabel } from "@/components/ui/field"
import { Input } from "@/components/ui/input"
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select"
import { Separator } from "@/components/ui/separator"
import { Textarea } from "@/components/ui/textarea"
export default function FormLayout02() {
return (
<div className="flex items-center justify-center p-10">
<form>
<div className="grid grid-cols-1 gap-10 md:grid-cols-3">
<div>
<h2 className="text-balance font-semibold text-foreground dark:text-foreground">
Personal information
</h2>
<p className="mt-1 text-pretty text-muted-foreground text-sm leading-6 dark:text-muted-foreground">
Lorem ipsum dolor sit amet, consetetur sadipscing elitr.
</p>
</div>
<div className="sm:max-w-3xl md:col-span-2">
<div className="grid grid-cols-1 gap-4 sm:grid-cols-6">
<div className="col-span-full sm:col-span-3">
<Field className="gap-2">
<FieldLabel htmlFor="first-name">First name</FieldLabel>
<Input
autoComplete="given-name"
id="first-name"
name="first-name"
placeholder="Emma"
type="text"
/>
</Field>
</div>
<div className="col-span-full sm:col-span-3">
<Field className="gap-2">
<FieldLabel htmlFor="last-name">Last name</FieldLabel>
<Input
autoComplete="family-name"
id="last-name"
name="last-name"
placeholder="Crown"
type="text"
/>
</Field>
</div>
<div className="col-span-full">
<Field className="gap-2">
<FieldLabel htmlFor="email">Email</FieldLabel>
<Input
autoComplete="email"
id="email"
name="email"
placeholder="emma@company.com"
type="email"
/>
</Field>
</div>
<div className="col-span-full sm:col-span-3">
<Field className="gap-2">
<FieldLabel htmlFor="birthyear">Birth year</FieldLabel>
<Input
id="birthyear"
name="year"
placeholder="1990"
type="number"
/>
</Field>
</div>
<div className="col-span-full sm:col-span-3">
<Field className="gap-2">
<FieldLabel htmlFor="role">Role</FieldLabel>
<Input
disabled
id="role"
name="role"
placeholder="Senior Manager"
type="text"
/>
<FieldDescription>
Roles can only be changed by system admin.
</FieldDescription>
</Field>
</div>
</div>
</div>
</div>
<Separator className="my-8" />
<div className="grid grid-cols-1 gap-10 md:grid-cols-3">
<div>
<h2 className="text-balance font-semibold text-foreground dark:text-foreground">
Workspace settings
</h2>
<p className="mt-1 text-pretty text-muted-foreground text-sm leading-6 dark:text-muted-foreground">
Lorem ipsum dolor sit amet, consetetur sadipscing elitr.
</p>
</div>
<div className="sm:max-w-3xl md:col-span-2">
<div className="grid grid-cols-1 gap-4 sm:grid-cols-6">
<div className="col-span-full sm:col-span-3">
<Field className="gap-2">
<FieldLabel htmlFor="workspace-name">
Workspace name
</FieldLabel>
<Input
id="workspace-name"
name="workspace-name"
placeholder="Test workspace"
type="text"
/>
</Field>
</div>
<div className="col-span-full sm:col-span-3">
<Field className="gap-2">
<FieldLabel htmlFor="visibility">Visibility</FieldLabel>
<Select
defaultValue="private"
items={{ private: "Private", public: "Public" }}
name="visibility"
>
<SelectTrigger id="visibility">
<SelectValue placeholder="Select visibility" />
</SelectTrigger>
<SelectContent>
<SelectItem value="public">Public</SelectItem>
<SelectItem value="private">Private</SelectItem>
</SelectContent>
</Select>
</Field>
</div>
<div className="col-span-full">
<Field className="gap-2">
<FieldLabel htmlFor="workspace-description">
Workspace description
</FieldLabel>
<Textarea
id="workspace-description"
name="workspace-description"
rows={4}
/>
<FieldDescription>
Note: description provided will not be displayed externally.
</FieldDescription>
</Field>
</div>
</div>
</div>
</div>
<Separator className="my-8" />
<div className="grid grid-cols-1 gap-10 md:grid-cols-3">
<div>
<h2 className="text-balance font-semibold text-foreground dark:text-foreground">
Notification settings
</h2>
<p className="mt-1 text-pretty text-muted-foreground text-sm leading-6 dark:text-muted-foreground">
Lorem ipsum dolor sit amet, consetetur sadipscing elitr.
</p>
</div>
<div className="sm:max-w-3xl md:col-span-2">
<fieldset>
<legend className="font-medium text-foreground text-sm dark:text-foreground">
Newsletter
</legend>
<FieldDescription
className="mt-2 leading-6"
id="newsletter-description"
>
Change how often you want to receive updates from our
newsletter.
</FieldDescription>
<RadioGroup className="mt-6" defaultValue="never">
<div className="flex items-center gap-x-3">
<RadioGroupItem
aria-describedby="newsletter-description"
id="every-week"
value="every-week"
/>
<FieldLabel className="font-normal" htmlFor="every-week">
Every week
</FieldLabel>
</div>
<div className="flex items-center gap-x-3">
<RadioGroupItem
aria-describedby="newsletter-description"
id="every-month"
value="every-month"
/>
<FieldLabel className="font-normal" htmlFor="every-month">
Every month
</FieldLabel>
</div>
<div className="flex items-center gap-x-3">
<RadioGroupItem
aria-describedby="newsletter-description"
id="never"
value="never"
/>
<FieldLabel className="font-normal" htmlFor="never">
Never
</FieldLabel>
</div>
</RadioGroup>
</fieldset>
</div>
</div>
<Separator className="my-8" />
<div className="flex items-center justify-end space-x-4">
<Button className="whitespace-nowrap" type="button" variant="outline">
Go back
</Button>
<Button className="whitespace-nowrap" type="submit">
Save settings
</Button>
</div>
</form>
</div>
)
}npx shadcn@latest add https://blocks.so/r/form-layout-02.jsonForm with Checkbox Settings
import { Button } from "@/components/ui/button"
import { Checkbox } from "@/components/ui/checkbox"
import { Field, FieldDescription, FieldLabel } from "@/components/ui/field"
import { Input } from "@/components/ui/input"
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select"
import { Separator } from "@/components/ui/separator"
import { Textarea } from "@/components/ui/textarea"
export default function FormLayout03() {
return (
<div className="flex items-center justify-center p-10">
<form>
<div className="grid grid-cols-1 gap-10 md:grid-cols-3">
<div>
<h2 className="text-balance font-semibold text-foreground dark:text-foreground">
Personal information
</h2>
<p className="mt-1 text-pretty text-muted-foreground text-sm leading-6 dark:text-muted-foreground">
Lorem ipsum dolor sit amet, consetetur sadipscing elitr.
</p>
</div>
<div className="sm:max-w-3xl md:col-span-2">
<div className="grid grid-cols-1 gap-4 sm:grid-cols-6">
<div className="col-span-full sm:col-span-3">
<Field className="gap-2">
<FieldLabel htmlFor="first-name">First name</FieldLabel>
<Input
autoComplete="given-name"
id="first-name"
name="first-name"
placeholder="Emma"
type="text"
/>
</Field>
</div>
<div className="col-span-full sm:col-span-3">
<Field className="gap-2">
<FieldLabel htmlFor="last-name">Last name</FieldLabel>
<Input
autoComplete="family-name"
id="last-name"
name="last-name"
placeholder="Crown"
type="text"
/>
</Field>
</div>
<div className="col-span-full">
<Field className="gap-2">
<FieldLabel htmlFor="email">Email</FieldLabel>
<Input
autoComplete="email"
id="email"
name="email"
placeholder="emma@company.com"
type="email"
/>
</Field>
</div>
<div className="col-span-full sm:col-span-3">
<Field className="gap-2">
<FieldLabel htmlFor="birthyear">Birth year</FieldLabel>
<Input
id="birthyear"
name="year"
placeholder="1990"
type="number"
/>
</Field>
</div>
<div className="col-span-full sm:col-span-3">
<Field className="gap-2">
<FieldLabel htmlFor="role">Role</FieldLabel>
<Input
disabled
id="role"
name="role"
placeholder="Senior Manager"
type="text"
/>
<FieldDescription>
Roles can only be changed by system admin.
</FieldDescription>
</Field>
</div>
</div>
</div>
</div>
<Separator className="my-8" />
<div className="grid grid-cols-1 gap-10 md:grid-cols-3">
<div>
<h2 className="text-balance font-semibold text-foreground dark:text-foreground">
Workspace settings
</h2>
<p className="mt-1 text-pretty text-muted-foreground text-sm leading-6 dark:text-muted-foreground">
Lorem ipsum dolor sit amet, consetetur sadipscing elitr.
</p>
</div>
<div className="sm:max-w-3xl md:col-span-2">
<div className="grid grid-cols-1 gap-4 sm:grid-cols-6">
<div className="col-span-full sm:col-span-3">
<Field className="gap-2">
<FieldLabel htmlFor="workspace-name">
Workspace name
</FieldLabel>
<Input
id="workspace-name"
name="workspace-name"
placeholder="Test workspace"
type="text"
/>
</Field>
</div>
<div className="col-span-full sm:col-span-3">
<Field className="gap-2">
<FieldLabel htmlFor="visibility">Visibility</FieldLabel>
<Select
defaultValue="private"
items={{ private: "Private", public: "Public" }}
name="visibility"
>
<SelectTrigger id="visibility">
<SelectValue placeholder="Select visibility" />
</SelectTrigger>
<SelectContent>
<SelectItem value="public">Public</SelectItem>
<SelectItem value="private">Private</SelectItem>
</SelectContent>
</Select>
</Field>
</div>
<div className="col-span-full">
<Field className="gap-2">
<FieldLabel htmlFor="workspace-description">
Workspace description
</FieldLabel>
<Textarea
id="workspace-description"
name="workspace-description"
rows={4}
/>
<FieldDescription>
Note: description provided will not be displayed externally.
</FieldDescription>
</Field>
</div>
</div>
</div>
</div>
<Separator className="my-8" />
<div className="grid grid-cols-1 gap-10 md:grid-cols-3">
<div>
<h2 className="text-balance font-semibold text-foreground dark:text-foreground">
Notification settings
</h2>
<p className="mt-1 text-pretty text-muted-foreground text-sm leading-6 dark:text-muted-foreground">
Lorem ipsum dolor sit amet, consetetur sadipscing elitr.
</p>
</div>
<div className="sm:max-w-3xl md:col-span-2">
<fieldset>
<legend className="font-medium text-foreground text-sm dark:text-foreground">
Team
</legend>
<FieldDescription className="mt-1 leading-6">
Configure the types of team alerts you want to receive.
</FieldDescription>
<div className="mt-2">
<div className="flex items-center gap-x-3 py-1">
<Checkbox
defaultChecked
id="team-requests"
name="team-requests"
/>
<FieldLabel className="font-normal" htmlFor="team-requests">
Team join requests
</FieldLabel>
</div>
<div className="flex items-center gap-x-3 py-1">
<Checkbox
id="team-activity-digest"
name="team-activity-digest"
/>
<FieldLabel
className="font-normal"
htmlFor="team-activity-digest"
>
Weekly team activity digest
</FieldLabel>
</div>
</div>
</fieldset>
<fieldset className="mt-6">
<legend className="font-medium text-foreground text-sm dark:text-foreground">
Usage
</legend>
<FieldDescription className="mt-1 leading-6">
Configure the types of usage alerts you want to receive.
</FieldDescription>
<div className="mt-2">
<div className="flex items-center gap-x-3 py-1">
<Checkbox id="api-requests" name="api-requests" />
<FieldLabel className="font-normal" htmlFor="api-requests">
API requests
</FieldLabel>
</div>
<div className="flex items-center gap-x-3 py-1">
<Checkbox
id="workspace-execution"
name="workspace-execution"
/>
<FieldLabel
className="font-normal"
htmlFor="workspace-execution"
>
Workspace loading times
</FieldLabel>
</div>
<div className="flex items-center gap-x-3 py-1">
<Checkbox
defaultChecked
id="query-caching"
name="query-caching"
/>
<FieldLabel className="font-normal" htmlFor="query-caching">
Query caching
</FieldLabel>
</div>
<div className="flex items-center gap-x-3 py-1">
<Checkbox defaultChecked id="storage" name="storage" />
<FieldLabel className="font-normal" htmlFor="storage">
Storage
</FieldLabel>
</div>
</div>
</fieldset>
</div>
</div>
<Separator className="my-8" />
<div className="flex items-center justify-end space-x-4">
<Button className="whitespace-nowrap" type="button" variant="outline">
Go back
</Button>
<Button className="whitespace-nowrap" type="submit">
Save settings
</Button>
</div>
</form>
</div>
)
}npx shadcn@latest add https://blocks.so/r/form-layout-03.jsonForm with Package Selection
"use client"
import { useState } from "react"
import { Button } from "@/components/ui/button"
import { Field, FieldDescription, FieldLabel } from "@/components/ui/field"
import { Input } from "@/components/ui/input"
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select"
import { Separator } from "@/components/ui/separator"
const workspaces = [
{
id: 1,
title: "Starter",
description: "Up to 10,000 requests per day.",
users: "Free",
},
{
id: 2,
title: "Premium",
description: "500,000 requests per day¹",
users: "$900/month²",
},
{
id: 3,
title: "Enterprise",
description: "Based on your specific needs",
users: "Custom",
},
]
export default function FormLayout04() {
const [selectedWorkspace, setSelectedWorkspace] = useState(workspaces[0])
return (
<div className="flex items-center justify-center p-10">
<div className="sm:mx-auto sm:max-w-2xl">
<h3 className="text-balance font-semibold text-foreground text-lg">
Apply for early access
</h3>
<p className="mt-1 text-pretty text-muted-foreground text-sm leading-6">
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam
nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.
</p>
<form action="#" className="mt-8" method="post">
<div className="grid grid-cols-1 gap-4 sm:grid-cols-6">
<div className="col-span-full sm:col-span-3">
<Field className="gap-2">
<FieldLabel htmlFor="first-name">
First name<span className="text-red-500">*</span>
</FieldLabel>
<Input
autoComplete="given-name"
id="first-name"
name="first-name"
placeholder="Emma"
required
type="text"
/>
</Field>
</div>
<div className="col-span-full sm:col-span-3">
<Field className="gap-2">
<FieldLabel htmlFor="last-name">Last name</FieldLabel>
<Input
autoComplete="family-name"
id="last-name"
name="last-name"
placeholder="Crown"
type="text"
/>
</Field>
</div>
<div className="col-span-full">
<Field className="gap-2">
<FieldLabel htmlFor="email">
Work email<span className="text-red-500">*</span>
</FieldLabel>
<Input
autoComplete="email"
id="email"
name="email"
placeholder="emma@company.com"
required
type="email"
/>
</Field>
</div>
<div className="col-span-full sm:col-span-3">
<Field className="gap-2">
<FieldLabel htmlFor="company">Company</FieldLabel>
<Input
autoComplete="organization"
id="company"
name="company"
placeholder="Company, Inc."
type="text"
/>
</Field>
</div>
<div className="col-span-full sm:col-span-3">
<Field className="gap-2">
<FieldLabel htmlFor="size">Company size (employees)</FieldLabel>
<Select defaultValue="">
<SelectTrigger id="size" name="size">
<SelectValue placeholder="Select company size" />
</SelectTrigger>
<SelectContent>
<SelectItem value="1-9">1-9</SelectItem>
<SelectItem value="10-50">10-50</SelectItem>
<SelectItem value="50-250">50-250</SelectItem>
<SelectItem value="250+">250+</SelectItem>
</SelectContent>
</Select>
</Field>
</div>
<Separator className="col-span-full my-4" />
<div className="col-span-full">
<FieldLabel className="mb-4 block font-semibold text-foreground">
Select a workspace package
</FieldLabel>
<RadioGroup
className="grid grid-cols-1 gap-5 sm:grid-cols-3"
defaultValue={selectedWorkspace.id.toString()}
onValueChange={(value) =>
setSelectedWorkspace(
workspaces.find(
(workspace) => workspace.id.toString() === value
) || workspaces[0]
)
}
>
{workspaces.map((item) => (
<div
className="relative flex flex-col gap-2 rounded-md border border-input p-4 shadow-xs outline-none has-data-checked:border-ring"
key={item.id.toString()}
>
<div className="flex justify-between">
<RadioGroupItem
className="order-1 after:absolute after:inset-0"
id={item.id.toString()}
value={item.id.toString()}
/>
<FieldLabel
className="block font-medium text-foreground text-sm"
htmlFor={item.id.toString()}
>
{item.title}
</FieldLabel>
</div>
<div className="flex h-full flex-col justify-between">
<p className="mt-1 text-pretty text-muted-foreground text-sm">
{item.description}
</p>
<span className="mt-4 block font-medium text-foreground text-sm">
{item.users}
</span>
</div>
</div>
))}
</RadioGroup>
<FieldDescription className="mt-2!">
<sup>1</sup> $0.5/10K requests after limit reach.
</FieldDescription>
<FieldDescription className="mt-1">
<sup>2</sup> No credit card required for registration.
</FieldDescription>
</div>
</div>
<Separator className="my-6" />
<div className="flex items-center justify-end space-x-4">
<Button
className="whitespace-nowrap"
type="button"
variant="outline"
>
Go back
</Button>
<Button className="whitespace-nowrap" type="submit">
Apply
</Button>
</div>
</form>
</div>
</div>
)
}npx shadcn@latest add https://blocks.so/r/form-layout-04.jsonForm with Plan Selection
"use client"
import { Check, CircleCheck, ExternalLink } from "lucide-react"
import { useState } from "react"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { Card, CardContent } from "@/components/ui/card"
import { Field, FieldDescription, FieldLabel } from "@/components/ui/field"
import { Input } from "@/components/ui/input"
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select"
import { Separator } from "@/components/ui/separator"
import { cn } from "@/lib/utils"
const highlights = [
{
id: 1,
feature: "Used by top design teams worldwide",
},
{
id: 2,
feature: "Seamless integration with design tools",
},
{
id: 3,
feature: "Real-time collaboration features",
},
]
const plans = [
{
name: "Creator",
features: [
{ feature: "Up to 3 design projects" },
{ feature: "Basic collaboration tools" },
{ feature: "5GB cloud storage" },
{ feature: "Community forum support" },
],
price: "$15",
href: "#",
isRecommended: false,
},
{
name: "Team",
features: [
{ feature: "Unlimited design projects" },
{ feature: "Advanced collaboration suite" },
{ feature: "50GB cloud storage" },
{ feature: "Priority email support" },
],
price: "$49",
href: "#",
isRecommended: true,
},
{
name: "Agency",
features: [
{ feature: "Unlimited projects and team members" },
{ feature: "Client portal access" },
{ feature: "250GB cloud storage" },
{ feature: "White-labeling options" },
{ feature: "Dedicated account manager" },
],
price: "$99",
href: "#",
isRecommended: false,
},
]
export default function FormLayout05() {
const [selected, setSelected] = useState(plans[0])
return (
<div className="flex items-center justify-center p-10">
<form className="sm:mx-auto sm:max-w-7xl">
<h3 className="text-balance font-semibold text-foreground text-xl">
Create new design workspace
</h3>
<div className="grid grid-cols-1 gap-10 lg:grid-cols-12 lg:gap-12">
<div className="mt-6 lg:col-span-7">
<div className="space-y-4 md:space-y-6">
<div className="md:flex md:items-center md:space-x-4">
<div className="md:w-1/4">
<Field className="gap-2">
<FieldLabel htmlFor="organization">Organization</FieldLabel>
<Select
defaultValue="1"
items={{
"1": "Acme, Inc.",
"2": "Hero Labs",
"3": "Rose Holding",
}}
>
<SelectTrigger
className="w-full"
id="organization"
name="organization"
>
<SelectValue placeholder="Select organization" />
</SelectTrigger>
<SelectContent>
<SelectItem value="1">Acme, Inc.</SelectItem>
<SelectItem value="2">Hero Labs</SelectItem>
<SelectItem value="3">Rose Holding</SelectItem>
</SelectContent>
</Select>
</Field>
</div>
<div className="mt-4 md:mt-0 md:w-3/4">
<Field className="gap-2">
<FieldLabel htmlFor="workspace">Workspace name</FieldLabel>
<Input id="workspace" name="workspace" />
</Field>
</div>
</div>
<div>
<Field className="gap-2">
<FieldLabel htmlFor="region">Region</FieldLabel>
<Select
defaultValue="iad1"
items={{
fra1: "eu-central-1 (Frankfurt, Germany)",
iad1: "us-east-1 (Washington, D.C., USA)",
lhr1: "eu-west-2 (London, United Kingdom)",
sfo1: "us-west-1 (San Francisco, USA)",
sin1: "ap-southeast-1 (Singapore)",
}}
>
<SelectTrigger id="region" name="region">
<SelectValue placeholder="Select region" />
</SelectTrigger>
<SelectContent>
<SelectItem value="fra1">
eu-central-1 (Frankfurt, Germany)
</SelectItem>
<SelectItem value="iad1">
us-east-1 (Washington, D.C., USA)
</SelectItem>
<SelectItem value="lhr1">
eu-west-2 (London, United Kingdom)
</SelectItem>
<SelectItem value="sfo1">
us-west-1 (San Francisco, USA)
</SelectItem>
<SelectItem value="sin1">
ap-southeast-1 (Singapore)
</SelectItem>
</SelectContent>
</Select>
<FieldDescription>
For best performance, choose a region closest to your
operations
</FieldDescription>
</Field>
</div>
</div>
<h4 className="mt-14 text-balance font-medium">
Plan type<span className="text-red-500">*</span>
</h4>
<RadioGroup
className="mt-4 space-y-4"
onValueChange={(value) =>
setSelected(
plans.find((plan) => plan.name === value) || plans[0]
)
}
value={selected.name}
>
{plans.map((plan) => (
<label
className={cn(
"relative block cursor-pointer rounded-md border bg-background transition",
selected.name === plan.name
? "border-primary/20 ring-2 ring-primary/20"
: "border-border"
)}
htmlFor={plan.name}
key={plan.name}
>
<div className="flex items-start space-x-4 px-6 py-4">
<div className="mt-1 flex h-4 w-4 shrink-0 items-center justify-center">
<RadioGroupItem id={plan.name} value={plan.name} />
</div>
<div className="w-full">
<p className="text-pretty leading-6">
<span className="font-semibold text-foreground">
{plan.name}
</span>
{plan.isRecommended && (
<Badge className="ml-2" variant="secondary">
recommended
</Badge>
)}
</p>
<ul className="mt-2 space-y-1">
{plan.features.map((feature, index) => (
<li
className="flex items-center gap-2 text-sm"
key={index}
>
<Check
aria-hidden={true}
className="h-4 w-4 text-muted-foreground"
/>
{feature.feature}
</li>
))}
</ul>
</div>
</div>
<div className="flex items-center justify-between rounded-b-md border-border border-t bg-muted px-6 py-3">
<a
className="inline-flex items-center gap-1 text-primary text-sm hover:underline hover:underline-offset-4"
href={plan.href}
>
Learn more
<ExternalLink aria-hidden={true} className="h-4 w-4" />
</a>
<div>
<span className="font-semibold text-foreground text-lg">
{plan.price}
</span>
<span className="text-muted-foreground text-sm">/mo</span>
</div>
</div>
</label>
))}
</RadioGroup>
</div>
<div className="lg:col-span-5">
<Card className="bg-muted shadow-none">
<CardContent>
<h4 className="text-balance font-semibold text-foreground text-sm">
Choose the right plan for your design team
</h4>
<p className="mt-2 text-pretty text-muted-foreground text-sm leading-6">
Our flexible plans are designed to scale with your team's
needs. All plans include core design collaboration features
with varying levels of storage and support.
</p>
<ul className="mt-4 space-y-1">
{highlights.map((item) => (
<li
className="flex items-center space-x-2 py-1.5 text-foreground"
key={item.id}
>
<CircleCheck className="h-5 w-5 text-primary" />
<span className="truncate text-sm">{item.feature}</span>
</li>
))}
</ul>
<a
className="mt-4 inline-flex items-center gap-1 text-primary text-sm"
href="#"
>
Learn more
<ExternalLink aria-hidden={true} className="h-4 w-4" />
</a>
</CardContent>
</Card>
</div>
</div>
<Separator className="my-10" />
<div className="flex items-center justify-end space-x-4">
<Button type="button" variant="ghost">
Cancel
</Button>
<Button type="submit">Update</Button>
</div>
</form>
</div>
)
}npx shadcn@latest add https://blocks.so/r/form-layout-05.json