- Accordion
- Agent Thinking
- Alert
- Alert Dialog
- Announcement
- Aspect Ratio
- Attachment
- Avatar
- Badge
- Breadcrumb
- Bubble
- Button
- Button Group
- Calendar
- Card
- Carousel
- Checkbox
- Checkbox Card
- Code Block
- Collapsible
- Color Picker
- Combobox
- Command
- Composer
- Composer Loader
- Context Menu
- Data Grid
- Data Table
- Date Picker
- Dialog
- Direction
- Drawer
- Dropdown Menu
- Empty
- Field
- File Upload
- Hover Card
- Input
- Input Group
- Input Otp
- Item
- Kbd
- Label
- Marker
- Menubar
- Message
- Message Scroller
- Meter
- Native Select
- Navigation Menu
- Number Field
- Pagination
- Period Switcher
- Popover
- Progress
- Questionnaire
- Radio Card
- Radio Group
- Resizable
- Reveal
- Scroll Area
- Search Field
- Select
- Separator
- Sheet
- Sidebar
- Skeleton
- Slider
- Social Button
- Sonner
- Spinner
- Status Dot
- Switch
- Switch Card
- Table
- Tabs
- Tag Group
- Textarea
- Theme Toggle
- Time Field
- Toggle
- Toggle Group
- Tooltip
- Trace
- Tree View
- Agent Creator 01
- Agent Limits Card 01
- Agent Progress 01
- AI Chat 01
- AI Image Generation 01
- AI Profile 01
- Alerts Card 01
- Auth Card 01
- Calendar 01
- Composer 01
- Composer Attachments 01
- Composer Panel 01
- Finance Dashboard 01
- Home Dashboard 01
- Marketing Dashboard 01
- Medical Profile 01
- Meeting Scheduler 01
- Multi Agent Chat 01
- Notification Center 01
- Patient Info Card 01
- Project Board 01
- Questionnaire 01
- Settings Modal 01
- Sidebar 01
- Stat Cards 01
- Task List 01
- Web Search 01
- Activity Rings Card 01
- Area Chart Card 01
- Bar List Card 01
- Combo Chart Card 01
- Contributions Card 01
- Earnings Chart Card 01
- Funnel Chart Card 01
- Heatmap Chart Card 01
- Line Chart Card 01
- Most Active Days Card 01
- Orders Chart Card 01
- Radar Chart Card 01
- Radial Chart Card 01
- Revenue Chart Card 01
- Sankey Chart Card 01
- Scatter Chart Card 01
- Sleep Score Card 01
- Stage Bars Card 01
- Steps Card 01
Weekly summaryReady to view. 12 items updated.
Installation
$ pnpm dlx shadcn@latest add @cobalt/skeleton
Source
import { cn } from "cn";
type SkeletonShape = "rect" | "text" | "circle";
type SkeletonProps = React.ComponentProps<"div"> & {
shape?: SkeletonShape;
isLoaded?: boolean;
};
function Skeleton({
className,
shape = "rect",
isLoaded = false,
children,
...props
}: SkeletonProps) {
const block = cn(
"block overflow-hidden isolate bg-[color:color-mix(in_srgb,var(--foreground)_8%,transparent)] after:pointer-events-none after:absolute after:inset-0 after:translate-x-[-100%] after:content-[''] after:[background:linear-gradient(90deg,transparent,var(--skeleton-line,var(--background)))_right/2px_100%_no-repeat,linear-gradient(90deg,transparent,var(--skeleton-glow,var(--background)))_right/72px_100%_no-repeat,linear-gradient(90deg,transparent,var(--skeleton-bloom,var(--background)))_right/240px_100%_no-repeat] after:[animation:skeleton-sheen_2.2s_cubic-bezier(0.4,0,0.2,1)_infinite] rtl:after:scale-x-[-1] rtl:after:[animation-direction:reverse] motion-reduce:after:hidden motion-reduce:[animation:skeleton-pulse_2s_ease-in-out_infinite]",
shape === "rect" && "rounded-[12px]",
shape === "text" && "rounded-[6px]",
shape === "circle" && "rounded-full"
);
if (children === undefined) {
return (
<div
data-slot="skeleton"
aria-hidden
className={cn(block, "relative", className)}
{...props}
/>
);
}
return (
<div
data-slot="skeleton"
className={cn("relative block", className)}
{...props}
>
<div
aria-hidden={!isLoaded || undefined}
inert={!isLoaded}
className={cn(
"transition-[opacity,filter] duration-300 ease-out motion-reduce:transition-none",
isLoaded
? "opacity-100 blur-[0px]"
: "opacity-0 motion-safe:blur-[4px]"
)}
>
{children}
</div>
<div
aria-hidden
className={cn(
block,
"pointer-events-none absolute inset-0 transition-[opacity,filter] duration-300 ease-out motion-reduce:transition-none",
isLoaded && "opacity-0"
)}
/>
</div>
);
}
function SkeletonText({
lines = 3,
lineClassName = "h-3.5",
className,
}: {
lines?: number;
lineClassName?: string;
className?: string;
}) {
return (
<div aria-hidden className={cn("flex w-full flex-col gap-2.5", className)}>
{Array.from({ length: lines }, (_, index) => (
<Skeleton
key={index}
shape="text"
className={cn(
lineClassName,
index === lines - 1 && lines > 1 ? "w-3/5" : "w-full"
)}
/>
))}
</div>
);
}
export { Skeleton, SkeletonText };
export type { SkeletonProps, SkeletonShape }; On this page