58 lines
1.5 KiB
TypeScript
58 lines
1.5 KiB
TypeScript
import { forwardRef } from "react";
|
|
|
|
import { cn } from "../lib/cn";
|
|
import { cva, type VariantProps } from "../lib/cva";
|
|
import { createDataAttributes, createSlot } from "../lib/contracts";
|
|
|
|
const skeletonVariants = cva(
|
|
[
|
|
"relative overflow-hidden rounded-[var(--ui-skeleton-radius)] bg-[var(--ui-skeleton-bg)]",
|
|
"before:absolute before:inset-0 before:bg-[var(--ui-skeleton-gradient)] before:opacity-70 before:content-[''] before:animate-[aiui-skeleton-shimmer_1.8s_var(--ease-standard)_infinite]"
|
|
],
|
|
{
|
|
variants: {
|
|
shape: {
|
|
line: "h-4 w-full",
|
|
block: "h-24 w-full rounded-[var(--ui-skeleton-block-radius)]",
|
|
pill: "h-10 w-32 rounded-[var(--ui-skeleton-pill-radius)]",
|
|
avatar: "size-12 rounded-[var(--ui-skeleton-avatar-radius)]"
|
|
},
|
|
tone: {
|
|
default: "bg-[var(--ui-skeleton-bg)]",
|
|
muted: "bg-[var(--ui-skeleton-muted-bg)]"
|
|
}
|
|
},
|
|
defaultVariants: {
|
|
shape: "line",
|
|
tone: "default"
|
|
}
|
|
}
|
|
);
|
|
|
|
export type SkeletonProps = React.ComponentPropsWithoutRef<"div"> &
|
|
VariantProps<typeof skeletonVariants>;
|
|
|
|
export const Skeleton = forwardRef<HTMLDivElement, SkeletonProps>(function Skeleton(
|
|
{
|
|
className,
|
|
shape = "line",
|
|
tone = "default",
|
|
...props
|
|
},
|
|
ref
|
|
) {
|
|
return (
|
|
<div
|
|
{...props}
|
|
{...createSlot("root")}
|
|
{...createDataAttributes({
|
|
shape,
|
|
tone
|
|
})}
|
|
aria-hidden="true"
|
|
className={cn(skeletonVariants({ shape, tone }), className)}
|
|
ref={ref}
|
|
/>
|
|
);
|
|
});
|