The card component supports a size prop that defaults to "default" for standard spacing and sizing.
The card component supports a size prop that can be set to "sm" for a more compact appearance.
These terms govern your use of the workspace, including access to shared documents, project files, and collaboration tools.
You are responsible for the content you upload and for ensuring that your team has the appropriate permissions to view or edit it.
We may update features or limits as the service evolves. When those changes materially affect your workflow, we will notify your workspace administrators.
By continuing, you agree to keep your account credentials secure and to follow your organization's acceptable use policies.
The header has a border-b class applied, creating a visual separation between the header and content sections.
The footer has a border-t class applied, creating a visual separation between the content and footer sections.
The header has a border-b class applied, creating a visual separation between the header and content sections.
The footer has a border-t class applied, creating a visual separation between the content and footer sections.
Client requested dashboard redesign with focus on mobile responsiveness.
- New analytics widgets for daily/weekly metrics
- Simplified navigation menu
- Dark mode support
- Timeline: 6 weeks
- Follow-up meeting scheduled for next Tuesday
<script lang="ts">
import { Avatar, AvatarFallback, AvatarGroup, AvatarGroupCount, AvatarImage } from '@sveltery/components/avatar';
import { Button } from '@sveltery/components/button';
import { Example, ExampleWrapper } from '@sveltery/components/example';
import { Card, CardAction, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from '@sveltery/components/card';
import { Field, FieldGroup, FieldLabel } from '@sveltery/components/field';
import { IconPlaceholder } from '@sveltery/components/icons';
import { Input } from '@sveltery/components/input';
import { ToggleGroup, ToggleGroupItem } from '@sveltery/components/toggle-group';
const spacingOptions = [
{ class: '[--card-spacing:--spacing(4)]', label: '16px', value: '4' },
{ class: '[--card-spacing:--spacing(5)]', label: '20px', value: '5' },
{ class: '[--card-spacing:--spacing(6)]', label: '24px', value: '6' },
{ class: '[--card-spacing:--spacing(8)]', label: '32px', value: '8' },
];
let spacing = $state('4');
const selectedSpacing = $derived(spacingOptions.find((option) => option.value === spacing));
</script>
<ExampleWrapper>
<Example title="Default Size">
<Card size="default" class="mx-auto w-full max-w-sm">
<CardHeader>
<CardTitle>Default Card</CardTitle>
<CardDescription>
This card uses the default size variant.
</CardDescription>
</CardHeader>
<CardContent>
<p>
The card component supports a size prop that defaults to
"default" for standard spacing and sizing.
</p>
</CardContent>
<CardFooter>
<Button variant="outline" class="w-full">
Action
</Button>
</CardFooter>
</Card>
</Example>
<Example title="Small Size">
<Card size="sm" class="mx-auto w-full max-w-sm">
<CardHeader>
<CardTitle>Small Card</CardTitle>
<CardDescription>
This card uses the small size variant.
</CardDescription>
</CardHeader>
<CardContent>
<p>
The card component supports a size prop that can be set to
"sm" for a more compact appearance.
</p>
</CardContent>
<CardFooter>
<Button variant="outline" size="sm" class="w-full">
Action
</Button>
</CardFooter>
</Card>
</Example>
<Example title="Content Edge to Edge">
<Card class="mx-auto w-full max-w-sm">
<CardHeader>
<CardTitle>Terms of Service</CardTitle>
<CardDescription>
Review the terms before accepting the agreement.
</CardDescription>
</CardHeader>
<CardContent class="-mb-(--card-spacing) px-0">
<div class="max-h-48 space-y-4 overflow-y-scroll border-t bg-muted/50 px-(--card-spacing) py-4 text-sm leading-relaxed">
<p>
These terms govern your use of the workspace, including access to
shared documents, project files, and collaboration tools.
</p>
<p>
You are responsible for the content you upload and for ensuring
that your team has the appropriate permissions to view or edit it.
</p>
<p>
We may update features or limits as the service evolves. When
those changes materially affect your workflow, we will notify your
workspace administrators.
</p>
<p>
By continuing, you agree to keep your account credentials secure
and to follow your organization's acceptable use policies.
</p>
</div>
</CardContent>
<CardFooter class="justify-end gap-2">
<Button variant="outline">Decline</Button>
<Button>Accept</Button>
</CardFooter>
</Card>
</Example>
<Example title="Custom Spacing">
<div class="mx-auto grid w-full max-w-sm gap-4">
<ToggleGroup
value={[spacing]}
onValueChange={(value) => {
if (value[0]) spacing = value[0];
}}
variant="outline"
size="sm"
class="justify-center"
>
{#each spacingOptions as option (option.value)}
<ToggleGroupItem value={option.value}>{option.label}</ToggleGroupItem>
{/each}
</ToggleGroup>
<Card class={selectedSpacing?.class}>
<CardHeader>
<CardTitle>Release Health</CardTitle>
<CardDescription>Track readiness across launch signals.</CardDescription>
</CardHeader>
<CardContent>
<div class="grid gap-2 rounded-lg bg-muted/50 p-3 text-sm style-lyra:rounded-none style-sera:rounded-none">
<div class="flex items-center justify-between gap-2">
<span class="text-muted-foreground">Checks passed</span>
<span class="font-medium">24 / 26</span>
</div>
<div class="flex items-center justify-between gap-2">
<span class="text-muted-foreground">Open blockers</span>
<span class="font-medium">2</span>
</div>
</div>
</CardContent>
</Card>
</div>
</Example>
<Example title="Header with Border">
<Card class="mx-auto w-full max-w-sm">
<CardHeader class="border-b">
<CardTitle>Header with Border</CardTitle>
<CardDescription>
This is a card with a header that has a bottom border.
</CardDescription>
</CardHeader>
<CardContent>
<p>
The header has a border-b class applied, creating a visual
separation between the header and content sections.
</p>
</CardContent>
</Card>
</Example>
<Example title="Footer with Border">
<Card class="mx-auto w-full max-w-sm">
<CardContent>
<p>
The footer has a border-t class applied, creating a visual
separation between the content and footer sections.
</p>
</CardContent>
<CardFooter class="border-t">
<Button variant="outline" class="w-full">
Footer with Border
</Button>
</CardFooter>
</Card>
</Example>
<Example title="Header with Border (Small)">
<Card size="sm" class="mx-auto w-full max-w-sm">
<CardHeader class="border-b">
<CardTitle>Header with Border</CardTitle>
<CardDescription>
This is a small card with a header that has a bottom border.
</CardDescription>
</CardHeader>
<CardContent>
<p>
The header has a border-b class applied, creating a visual
separation between the header and content sections.
</p>
</CardContent>
</Card>
</Example>
<Example title="Footer with Border (Small)">
<Card size="sm" class="mx-auto w-full max-w-sm">
<CardContent>
<p>
The footer has a border-t class applied, creating a visual
separation between the content and footer sections.
</p>
</CardContent>
<CardFooter class="border-t">
<Button variant="outline" size="sm" class="w-full">
Footer with Border
</Button>
</CardFooter>
</Card>
</Example>
<Example title="With Image">
<Card size="default" class="relative mx-auto w-full max-w-sm pt-0">
<div class="absolute inset-0 z-30 aspect-video bg-primary opacity-50 mix-blend-color"></div>
<div class="relative z-20 aspect-video w-full bg-muted"></div>
<CardHeader>
<CardTitle>Beautiful Landscape</CardTitle>
<CardDescription>A stunning view that captures the essence of natural beauty.</CardDescription>
</CardHeader>
<CardFooter>
<Button class="w-full">
<IconPlaceholder
lucide="PlusIcon"
tabler="IconPlus"
hugeicons="Add01Icon"
phosphor="PlusIcon"
remixicon="RiAddLine"
data-icon="inline-start"
/>
Button
</Button>
</CardFooter>
</Card>
</Example>
<Example title="With Image (Small)">
<Card size="sm" class="relative mx-auto w-full max-w-sm pt-0">
<div class="absolute inset-0 z-30 aspect-video bg-primary opacity-50 mix-blend-color"></div>
<div class="relative z-20 aspect-video w-full bg-muted"></div>
<CardHeader>
<CardTitle>Beautiful Landscape</CardTitle>
<CardDescription>A stunning view that captures the essence of natural beauty.</CardDescription>
</CardHeader>
<CardFooter>
<Button size="sm" class="w-full">
<IconPlaceholder
lucide="PlusIcon"
tabler="IconPlus"
hugeicons="Add01Icon"
phosphor="PlusIcon"
remixicon="RiAddLine"
data-icon="inline-start"
/>
Button
</Button>
</CardFooter>
</Card>
</Example>
<Example title="Login">
<Card class="mx-auto w-full max-w-sm">
<CardHeader>
<CardTitle>Login to your account</CardTitle>
<CardDescription>Enter your email below to login to your account</CardDescription>
</CardHeader>
<CardContent>
<form>
<FieldGroup>
<Field>
<FieldLabel for="email">Email</FieldLabel>
<Input id="email" type="email" placeholder="m@example.com" required />
</Field>
<Field>
<div class="flex items-center">
<FieldLabel for="password">Password</FieldLabel>
<!-- svelte-ignore a11y_invalid_attribute -->
<a href="#" class="ml-auto inline-block underline-offset-4 hover:underline">Forgot your password?</a>
</div>
<Input id="password" type="password" required />
</Field>
</FieldGroup>
</form>
</CardContent>
<CardFooter class="flex-col gap-2">
<Button type="submit" class="w-full">Login</Button>
<Button variant="outline" class="w-full">Login with Google</Button>
<div class="mt-4 text-center">
Don't have an account?
<!-- svelte-ignore a11y_invalid_attribute -->
<a href="#" class="underline underline-offset-4">Sign up</a>
</div>
</CardFooter>
</Card>
</Example>
<Example title="Meeting Notes">
<Card class="mx-auto w-full max-w-sm">
<CardHeader>
<CardTitle>Meeting Notes</CardTitle>
<CardDescription>Transcript from the meeting with the client.</CardDescription>
<CardAction>
<Button variant="outline" size="sm">
<IconPlaceholder
lucide="CaptionsIcon"
tabler="IconTextCaption"
hugeicons="TextCheckIcon"
phosphor="TextTIcon"
remixicon="RiTextWrap"
data-icon="inline-start"
/>
Transcribe
</Button>
</CardAction>
</CardHeader>
<CardContent>
<p>Client requested dashboard redesign with focus on mobile responsiveness.</p>
<ol class="mt-4 flex list-decimal flex-col gap-2 pl-6">
<li>New analytics widgets for daily/weekly metrics</li>
<li>Simplified navigation menu</li>
<li>Dark mode support</li>
<li>Timeline: 6 weeks</li>
<li>Follow-up meeting scheduled for next Tuesday</li>
</ol>
</CardContent>
<CardFooter>
<AvatarGroup>
<Avatar>
<AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
<AvatarFallback>CN</AvatarFallback>
</Avatar>
<Avatar>
<AvatarImage src="https://github.com/maxleiter.png" alt="@maxleiter" />
<AvatarFallback>LR</AvatarFallback>
</Avatar>
<Avatar>
<AvatarImage src="https://github.com/evilrabbit.png" alt="@evilrabbit" />
<AvatarFallback>ER</AvatarFallback>
</Avatar>
<AvatarGroupCount>+8</AvatarGroupCount>
</AvatarGroup>
</CardFooter>
</Card>
</Example>
</ExampleWrapper>Installation
Install the dependencies
pnpm add cn class-variance-authorityCopy the component
Copy the following files into src/lib/components/ui/card.
<script lang="ts">
import type { CardProps } from './types.js';
import { cn } from 'cn';
let { children, class: classProp, size = 'default', ...props }: CardProps = $props();
</script>
<div data-slot="card" data-size={size} {...props} class={cn('ring-foreground/10 bg-card text-card-foreground gap-(--card-spacing) overflow-hidden rounded-xl py-(--card-spacing) text-sm ring-1 [--card-spacing:--spacing(4)] has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:[--card-spacing:--spacing(3)] data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl group/card flex flex-col', classProp)}>
{@render children?.()}
</div><script lang="ts">
import type { CardActionProps } from './types.js';
import { cn } from 'cn';
let { children, class: classProp, ...props }: CardActionProps = $props();
</script>
<div data-slot="card-action" {...props} class={cn('col-start-2 row-span-2 row-start-1 self-start justify-self-end', classProp)}>
{@render children?.()}
</div><script lang="ts">
import type { CardContentProps } from './types.js';
import { cn } from 'cn';
let { children, class: classProp, ...props }: CardContentProps = $props();
</script>
<div data-slot="card-content" {...props} class={cn('px-(--card-spacing)', classProp)}>
{@render children?.()}
</div><script lang="ts">
import type { CardDescriptionProps } from './types.js';
import { cn } from 'cn';
let { children, class: classProp, ...props }: CardDescriptionProps = $props();
</script>
<div data-slot="card-description" {...props} class={cn('text-muted-foreground text-sm', classProp)}>
{@render children?.()}
</div><script lang="ts">
import type { CardFooterProps } from './types.js';
import { cn } from 'cn';
let { children, class: classProp, ...props }: CardFooterProps = $props();
</script>
<div data-slot="card-footer" {...props} class={cn('bg-muted/50 rounded-b-xl border-t p-(--card-spacing) flex items-center', classProp)}>
{@render children?.()}
</div><script lang="ts">
import type { CardHeaderProps } from './types.js';
import { cn } from 'cn';
let { children, class: classProp, ...props }: CardHeaderProps = $props();
</script>
<div data-slot="card-header" {...props} class={cn('gap-1 rounded-t-xl px-(--card-spacing) [.border-b]:pb-(--card-spacing) group/card-header @container/card-header grid auto-rows-min items-start has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto]', classProp)}>
{@render children?.()}
</div><script lang="ts">
import type { CardTitleProps } from './types.js';
import { cn } from 'cn';
let { children, class: classProp, ...props }: CardTitleProps = $props();
</script>
<div data-slot="card-title" {...props} class={cn('text-base leading-snug font-medium group-data-[size=sm]/card:text-sm', classProp)}>
{@render children?.()}
</div>import type { HTMLAttributes } from 'svelte/elements';
type NativeCardProps = HTMLAttributes<HTMLDivElement>;
export type CardProps = NativeCardProps & { size?: 'default' | 'sm' };
export type CardHeaderProps = NativeCardProps;
export type CardTitleProps = NativeCardProps;
export type CardDescriptionProps = NativeCardProps;
export type CardActionProps = NativeCardProps;
export type CardContentProps = NativeCardProps;
export type CardFooterProps = NativeCardProps;export { default as Card } from './Card.svelte';
export { default as CardHeader } from './CardHeader.svelte';
export { default as CardTitle } from './CardTitle.svelte';
export { default as CardDescription } from './CardDescription.svelte';
export { default as CardAction } from './CardAction.svelte';
export { default as CardContent } from './CardContent.svelte';
export { default as CardFooter } from './CardFooter.svelte';
export type { CardProps, CardHeaderProps, CardTitleProps, CardDescriptionProps, CardActionProps, CardContentProps, CardFooterProps } from './types.js';Update the import paths
Change the imports to match your project setup.
Usage
<script lang="ts">
import { Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '$lib/components/ui/card';
</script><Card>
<CardHeader>
<CardTitle>Card Title</CardTitle>
<CardDescription>Card Description</CardDescription>
<CardAction>Card Action</CardAction>
</CardHeader>
<CardContent>
<p>Card Content</p>
</CardContent>
<CardFooter>
<p>Card Footer</p>
</CardFooter>
</Card>Image card
Place an image above CardHeader and drop the top padding with pt-0. Put a Badge or an action next to the footer content with ml-auto. Here the footer opens an AlertDialog.
<script lang="ts">
import { Example, ExampleWrapper } from '@sveltery/components/example';
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogMedia,
AlertDialogTitle,
AlertDialogTrigger,
} from '@sveltery/components/alert-dialog';
import { Badge } from '@sveltery/components/badge';
import { Button } from '@sveltery/components/button';
import { Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@sveltery/components/card';
import { Combobox, ComboboxCollection, ComboboxContent, ComboboxEmpty, ComboboxInput, ComboboxItem, ComboboxList } from '@sveltery/components/combobox';
import {
DropdownMenu,
DropdownMenuCheckboxItem,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuPortal,
DropdownMenuRadioGroup,
DropdownMenuRadioItem,
DropdownMenuSeparator,
DropdownMenuShortcut,
DropdownMenuSub,
DropdownMenuSubContent,
DropdownMenuSubTrigger,
DropdownMenuTrigger,
} from '@sveltery/components/dropdown-menu';
import { Field, FieldGroup, FieldLabel } from '@sveltery/components/field';
import { IconPlaceholder } from '@sveltery/components/icons';
import { Input } from '@sveltery/components/input';
import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from '@sveltery/components/select';
import { Textarea } from '@sveltery/components/textarea';
const frameworks = ['Next.js', 'SvelteKit', 'Nuxt.js', 'Remix', 'Astro'] as const;
const roleItems = [
{ label: 'Developer', value: 'developer' },
{ label: 'Designer', value: 'designer' },
{ label: 'Manager', value: 'manager' },
{ label: 'Other', value: 'other' },
];
let notifications = $state({ email: true, sms: false, push: true });
let theme = $state('light');
</script>
<ExampleWrapper>
<Example title="Card" class="items-center justify-center" containerClass="md:col-span-2">
<Card class="relative w-full max-w-sm overflow-hidden pt-0">
<div class="absolute inset-0 z-30 aspect-video bg-primary opacity-50 mix-blend-color"></div>
<img
src="https://images.unsplash.com/photo-1604076850742-4c7221f3101b?q=80&w=1887&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
alt="Photo by mymind on Unsplash"
title="Photo by mymind on Unsplash"
class="relative z-20 aspect-video w-full object-cover brightness-60 grayscale"
/>
<CardHeader>
<CardTitle>Observability Plus is replacing Monitoring</CardTitle>
<CardDescription>
Switch to the improved way to explore your data, with natural language. Monitoring will no longer be available
on the Pro plan in November, 2025
</CardDescription>
</CardHeader>
<CardFooter>
<AlertDialog>
<AlertDialogTrigger>
{#snippet render(props, _state, content)}<Button {...props}>{@render content?.()}</Button>{/snippet}
<IconPlaceholder
lucide="PlusIcon"
tabler="IconPlus"
hugeicons="PlusSignIcon"
phosphor="PlusIcon"
remixicon="RiAddLine"
data-icon="inline-start"
/>
Show Dialog
</AlertDialogTrigger>
<AlertDialogContent size="sm">
<AlertDialogHeader>
<AlertDialogMedia>
<IconPlaceholder
lucide="BluetoothIcon"
tabler="IconBluetooth"
hugeicons="BluetoothIcon"
phosphor="BluetoothIcon"
remixicon="RiBluetoothLine"
/>
</AlertDialogMedia>
<AlertDialogTitle>Allow accessory to connect?</AlertDialogTitle>
<AlertDialogDescription>
Do you want to allow the USB accessory to connect to this device?
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Don't allow</AlertDialogCancel>
<AlertDialogAction>Allow</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
<Badge variant="secondary" class="ml-auto">Warning</Badge>
</CardFooter>
</Card>
</Example>
<Example title="Form">
<Card class="w-full max-w-md">
<CardHeader>
<CardTitle>User Information</CardTitle>
<CardDescription>Please fill in your details below</CardDescription>
<CardAction>
<DropdownMenu>
<DropdownMenuTrigger>
{#snippet render(props, _state, content)}
<Button {...(props as Record<string, unknown>)} variant="ghost" size="icon">{@render content?.()}</Button>
{/snippet}
<IconPlaceholder lucide="MoreVerticalIcon" tabler="IconDotsVertical" hugeicons="MoreVerticalCircle01Icon" phosphor="DotsThreeVerticalIcon" remixicon="RiMore2Line" />
<span class="sr-only">More options</span>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" class="w-56">
<DropdownMenuGroup>
<DropdownMenuLabel>File</DropdownMenuLabel>
<DropdownMenuItem>
<IconPlaceholder lucide="FileIcon" tabler="IconFile" hugeicons="FileIcon" phosphor="FileIcon" remixicon="RiFileLine" />New File
<DropdownMenuShortcut>⌘N</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
<IconPlaceholder lucide="FolderIcon" tabler="IconFolder" hugeicons="FolderIcon" phosphor="FolderIcon" remixicon="RiFolderLine" />New Folder
<DropdownMenuShortcut>⇧⌘N</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuSub>
<DropdownMenuSubTrigger>
<IconPlaceholder lucide="FolderOpenIcon" tabler="IconFolderOpen" hugeicons="FolderOpenIcon" phosphor="FolderOpenIcon" remixicon="RiFolderOpenLine" />Open Recent
</DropdownMenuSubTrigger>
<DropdownMenuPortal>
<DropdownMenuSubContent>
<DropdownMenuGroup>
<DropdownMenuLabel>Recent Projects</DropdownMenuLabel>
<DropdownMenuItem>
<IconPlaceholder lucide="FileCodeIcon" tabler="IconFileCode" hugeicons="CodeIcon" phosphor="CodeIcon" remixicon="RiCodeLine" />Project Alpha
</DropdownMenuItem>
<DropdownMenuItem>
<IconPlaceholder lucide="FileCodeIcon" tabler="IconFileCode" hugeicons="CodeIcon" phosphor="CodeIcon" remixicon="RiCodeLine" />Project Beta
</DropdownMenuItem>
<DropdownMenuSub>
<DropdownMenuSubTrigger>
<IconPlaceholder lucide="MoreHorizontalIcon" tabler="IconDots" hugeicons="MoreHorizontalCircle01Icon" phosphor="DotsThreeOutlineIcon" remixicon="RiMoreLine" />More Projects
</DropdownMenuSubTrigger>
<DropdownMenuPortal>
<DropdownMenuSubContent>
<DropdownMenuItem>
<IconPlaceholder lucide="FileCodeIcon" tabler="IconFileCode" hugeicons="CodeIcon" phosphor="CodeIcon" remixicon="RiCodeLine" />Project Gamma
</DropdownMenuItem>
<DropdownMenuItem>
<IconPlaceholder lucide="FileCodeIcon" tabler="IconFileCode" hugeicons="CodeIcon" phosphor="CodeIcon" remixicon="RiCodeLine" />Project Delta
</DropdownMenuItem>
</DropdownMenuSubContent>
</DropdownMenuPortal>
</DropdownMenuSub>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem>
<IconPlaceholder lucide="FolderSearchIcon" tabler="IconFolderSearch" hugeicons="SearchIcon" phosphor="MagnifyingGlassIcon" remixicon="RiSearchLine" />Browse...
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuSubContent>
</DropdownMenuPortal>
</DropdownMenuSub>
<DropdownMenuSeparator />
<DropdownMenuItem>
<IconPlaceholder lucide="SaveIcon" tabler="IconDeviceFloppy" hugeicons="FloppyDiskIcon" phosphor="FloppyDiskIcon" remixicon="RiSaveLine" />Save
<DropdownMenuShortcut>⌘S</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
<IconPlaceholder lucide="DownloadIcon" tabler="IconDownload" hugeicons="DownloadIcon" phosphor="DownloadIcon" remixicon="RiDownloadLine" />Export
<DropdownMenuShortcut>⇧⌘E</DropdownMenuShortcut>
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuLabel>View</DropdownMenuLabel>
<DropdownMenuCheckboxItem
bind:checked={notifications.email}
>
<IconPlaceholder lucide="EyeIcon" tabler="IconEye" hugeicons="EyeIcon" phosphor="EyeIcon" remixicon="RiEyeLine" />Show Sidebar
</DropdownMenuCheckboxItem>
<DropdownMenuCheckboxItem
bind:checked={notifications.sms}
>
<IconPlaceholder lucide="LayoutIcon" tabler="IconLayout" hugeicons="LayoutIcon" phosphor="LayoutIcon" remixicon="RiLayoutLine" />Show Status Bar
</DropdownMenuCheckboxItem>
<DropdownMenuSub>
<DropdownMenuSubTrigger>
<IconPlaceholder lucide="PaletteIcon" tabler="IconPalette" hugeicons="PaintBoardIcon" phosphor="PaletteIcon" remixicon="RiPaletteLine" />Theme
</DropdownMenuSubTrigger>
<DropdownMenuPortal>
<DropdownMenuSubContent>
<DropdownMenuGroup>
<DropdownMenuLabel>Appearance</DropdownMenuLabel>
<DropdownMenuRadioGroup bind:value={theme}>
<DropdownMenuRadioItem value="light">
<IconPlaceholder lucide="SunIcon" tabler="IconSun" hugeicons="SunIcon" phosphor="SunIcon" remixicon="RiSunLine" />Light
</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="dark">
<IconPlaceholder lucide="MoonIcon" tabler="IconMoon" hugeicons="MoonIcon" phosphor="MoonIcon" remixicon="RiMoonLine" />Dark
</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="system">
<IconPlaceholder lucide="MonitorIcon" tabler="IconDeviceDesktop" hugeicons="ComputerIcon" phosphor="MonitorIcon" remixicon="RiComputerLine" />System
</DropdownMenuRadioItem>
</DropdownMenuRadioGroup>
</DropdownMenuGroup>
</DropdownMenuSubContent>
</DropdownMenuPortal>
</DropdownMenuSub>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuLabel>Account</DropdownMenuLabel>
<DropdownMenuItem>
<IconPlaceholder lucide="UserIcon" tabler="IconUser" hugeicons="UserIcon" phosphor="UserIcon" remixicon="RiUserLine" />Profile
<DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
<IconPlaceholder lucide="CreditCardIcon" tabler="IconCreditCard" hugeicons="CreditCardIcon" phosphor="CreditCardIcon" remixicon="RiBankCardLine" />Billing
</DropdownMenuItem>
<DropdownMenuSub>
<DropdownMenuSubTrigger>
<IconPlaceholder lucide="SettingsIcon" tabler="IconSettings" hugeicons="SettingsIcon" phosphor="GearIcon" remixicon="RiSettingsLine" />Settings
</DropdownMenuSubTrigger>
<DropdownMenuPortal>
<DropdownMenuSubContent>
<DropdownMenuGroup>
<DropdownMenuLabel>Preferences</DropdownMenuLabel>
<DropdownMenuItem>
<IconPlaceholder lucide="KeyboardIcon" tabler="IconKeyboard" hugeicons="KeyboardIcon" phosphor="KeyboardIcon" remixicon="RiKeyboardLine" />Keyboard Shortcuts
</DropdownMenuItem>
<DropdownMenuItem>
<IconPlaceholder lucide="LanguagesIcon" tabler="IconLanguage" hugeicons="LanguageCircleIcon" phosphor="TranslateIcon" remixicon="RiTranslate" />Language
</DropdownMenuItem>
<DropdownMenuSub>
<DropdownMenuSubTrigger>
<IconPlaceholder lucide="BellIcon" tabler="IconBell" hugeicons="NotificationIcon" phosphor="BellIcon" remixicon="RiNotificationLine" />Notifications
</DropdownMenuSubTrigger>
<DropdownMenuPortal>
<DropdownMenuSubContent>
<DropdownMenuGroup>
<DropdownMenuLabel>Notification Types</DropdownMenuLabel>
<DropdownMenuCheckboxItem
bind:checked={notifications.push}
>
<IconPlaceholder lucide="BellIcon" tabler="IconBell" hugeicons="NotificationIcon" phosphor="BellIcon" remixicon="RiNotificationLine" />Push Notifications
</DropdownMenuCheckboxItem>
<DropdownMenuCheckboxItem
bind:checked={notifications.email}
>
<IconPlaceholder lucide="MailIcon" tabler="IconMail" hugeicons="MailIcon" phosphor="EnvelopeIcon" remixicon="RiMailLine" />Email Notifications
</DropdownMenuCheckboxItem>
</DropdownMenuGroup>
</DropdownMenuSubContent>
</DropdownMenuPortal>
</DropdownMenuSub>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem>
<IconPlaceholder lucide="ShieldIcon" tabler="IconShield" hugeicons="ShieldIcon" phosphor="ShieldIcon" remixicon="RiShieldLine" />Privacy & Security
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuSubContent>
</DropdownMenuPortal>
</DropdownMenuSub>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem>
<IconPlaceholder lucide="HelpCircleIcon" tabler="IconHelpCircle" hugeicons="HelpCircleIcon" phosphor="QuestionIcon" remixicon="RiQuestionLine" />Help & Support
</DropdownMenuItem>
<DropdownMenuItem>
<IconPlaceholder lucide="FileTextIcon" tabler="IconFileText" hugeicons="File01Icon" phosphor="FileTextIcon" remixicon="RiFileTextLine" />Documentation
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem variant="destructive">
<IconPlaceholder lucide="LogOutIcon" tabler="IconLogout" hugeicons="LogoutIcon" phosphor="SignOutIcon" remixicon="RiLogoutBoxLine" />Sign Out
<DropdownMenuShortcut>⇧⌘Q</DropdownMenuShortcut>
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
</CardAction>
</CardHeader>
<CardContent>
<form>
<FieldGroup>
<div class="grid grid-cols-2 gap-4">
<Field>
<FieldLabel for="small-form-name">Name</FieldLabel>
<Input id="small-form-name" placeholder="Enter your name" required />
</Field>
<Field>
<FieldLabel for="small-form-role">Role</FieldLabel>
<Select items={roleItems} defaultValue={null}>
<SelectTrigger id="small-form-role">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectGroup>
{#each roleItems as item (item.value)}
<SelectItem value={item.value}>{item.label}</SelectItem>
{/each}
</SelectGroup>
</SelectContent>
</Select>
</Field>
</div>
<Field>
<FieldLabel for="small-form-framework">Framework</FieldLabel>
<Combobox items={frameworks}>
<ComboboxInput id="small-form-framework" placeholder="Select a framework" required />
<ComboboxContent>
<ComboboxEmpty>No frameworks found.</ComboboxEmpty>
<ComboboxList>
<ComboboxCollection>
{#snippet children(item)}
<ComboboxItem value={item}>{item}</ComboboxItem>
{/snippet}
</ComboboxCollection>
</ComboboxList>
</ComboboxContent>
</Combobox>
</Field>
<Field>
<FieldLabel for="small-form-comments">Comments</FieldLabel>
<Textarea id="small-form-comments" placeholder="Add any additional comments" />
</Field>
<Field orientation="horizontal">
<Button type="submit">Submit</Button>
<Button variant="outline" type="button">Cancel</Button>
</Field>
</FieldGroup>
</form>
</CardContent>
</Card>
</Example>
</ExampleWrapper>