shadcn.io is not affiliated with official shadcn/ui
Shadcn Frame for React and Tailwind
Bordered box for grouping related content.
Section header
Brief description about the section
Section title
Section description
Installation
bunx --bun shadcn@latest add https://kit.dev/r/frame.jsonpnpm dlx shadcn@latest add https://kit.dev/r/frame.jsonnpx shadcn@latest add https://kit.dev/r/frame.jsonyarn shadcn@latest add https://kit.dev/r/frame.jsonInstall the following dependencies:
bun add @ark-ui/reactpnpm add @ark-ui/reactnpm install @ark-ui/reactyarn add @ark-ui/reactCopy and paste the following code into your project.
"use client";
import { ark } from "@ark-ui/react/factory";
import type * as React from "react";
import { cn } from "@/lib/utils";
export const Frame = (props: React.ComponentProps<typeof ark.div>) => {
const { className, ...rest } = props;
return (
<ark.div
className={cn(
"relative",
"p-1",
"flex flex-col",
"bg-muted/72",
"rounded-2xl",
"*:[[data-slot=frame-panel]+[data-slot=frame-panel]]:mt-1",
className
)}
data-slot="frame"
{...rest}
/>
);
};
export const FramePanel = (props: React.ComponentProps<typeof ark.div>) => {
const { className, ...rest } = props;
return (
<ark.div
className={cn(
"relative",
"p-5",
"bg-background",
"rounded-xl border shadow-xs/5",
className
)}
data-slot="frame-panel"
{...rest}
/>
);
};
interface FrameHeaderProps extends React.ComponentProps<typeof ark.header> {
/**
* The description of the dialog
*/
description?: string;
/**
* The title of the dialog
*/
title?: string;
}
export const FrameHeader = (props: FrameHeaderProps) => {
const { title, description, className, children, ...rest } = props;
return (
<ark.header
className={cn("flex flex-col", "px-5 py-4", className)}
data-slot="frame-panel-header"
{...rest}
>
{!!title && <FrameTitle>{title}</FrameTitle>}
{!!description && <FrameDescription>{description}</FrameDescription>}
{!title && typeof children === "string" ? (
<FrameTitle>{children}</FrameTitle>
) : (
children
)}
</ark.header>
);
};
export const FrameTitle = (props: React.ComponentProps<typeof ark.div>) => {
const { className, ...rest } = props;
return (
<ark.div
className={cn("font-semibold text-sm", className)}
data-slot="frame-panel-title"
{...rest}
/>
);
};
export const FrameDescription = (
props: React.ComponentProps<typeof ark.div>
) => {
const { className, ...rest } = props;
return (
<ark.div
className={cn("text-muted-foreground text-sm", className)}
data-slot="frame-panel-description"
{...rest}
/>
);
};
export const FrameFooter = (props: React.ComponentProps<typeof ark.footer>) => {
const { className, ...rest } = props;
return (
<ark.footer
className={cn("px-5 py-4", className)}
data-slot="frame-panel-footer"
{...rest}
/>
);
};Update the import paths to match your project setup.
Anatomy
Frame
├── FramePanel
└── FrameHeader
├── FrameTitle
├── FrameDescription
└── FrameFooterUsage
import {
Frame,
FrameHeader,
FrameTitle,
FrameDescription,
FramePanel,
FrameFooter,
} from "@/components/ui/frame";<Frame>
<FrameHeader>
<FrameTitle>Title</FrameTitle>
<FrameDescription>Description</FrameDescription>
</FrameHeader>
<FramePanel>Content</FramePanel>
<FrameFooter>Footer</FrameFooter>
</Frame>Title & Description
FrameHeader supports two usage patterns:
Using props
Pass title and description props directly to FrameHeader.
<FrameHeader title="Frame Title" description="Frame description" />This approach does not require
FrameTitleorFrameDescriptioncomponents.
Using components
Use FrameTitle and FrameDescription as children for more control.
<FrameHeader>
<FrameTitle>Frame Title</FrameTitle>
<FrameDescription>Frame description</FrameDescription>
</FrameHeader>Examples
Separated Panels
By default, multiple panels are separated with spacing between them.
API Reference
Frame
Main container for grouping related content into panels.
| Prop | Type | Default |
|---|---|---|
className | string | - |
asChild | boolean | false |
FramePanel
A single panel with optional header and footer.
| Prop | Type | Default |
|---|---|---|
className | string | - |
asChild | boolean | false |
FrameHeader
Header area for the panel. Often contains title and description.
| Prop | Type | Default |
|---|---|---|
className | string | - |
asChild | boolean | false |
FrameTitle
Panel title or heading.
| Prop | Type | Default |
|---|---|---|
className | string | - |
asChild | boolean | false |
FrameDescription
Panel description or subtitle.
| Prop | Type | Default |
|---|---|---|
className | string | - |
asChild | boolean | false |
FrameFooter
Footer area for the panel. Often contains actions.
| Prop | Type | Default |
|---|---|---|
className | string | - |
asChild | boolean | false |