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.
Usage
import {
Frame,
FrameDescription,
FrameFooter,
FrameHeader,
FramePanel,
FrameTitle,
} from "@/components/ui/frame";<Frame className="w-full max-w-md">
<FrameHeader>
<FrameTitle>Section header</FrameTitle>
<FrameDescription>Brief description about the section</FrameDescription>
</FrameHeader>
<FramePanel>
<h2 className="font-semibold text-sm">Section title</h2>
<p className="text-muted-foreground text-sm">Section description</p>
</FramePanel>
<FrameFooter>
<p className="text-muted-foreground text-sm">Footer</p>
</FrameFooter>
</Frame>Demos
Separated Panels
API Reference
Frame
div
PropType
AttributeType
FramePanel
div
PropType
AttributeType
FrameHeader
header
PropType
AttributeType
FrameTitle
div
PropType
AttributeType
FrameDescription
div
PropType
AttributeType
FrameFooter
footer
PropType
AttributeType