Files
wr.do/components/shared/empty-placeholder.tsx
T
2024-07-28 14:30:25 +08:00

87 lines
1.9 KiB
TypeScript

import * as React from "react";
import { cn } from "@/lib/utils";
import { Icons } from "@/components/shared/icons";
interface EmptyPlaceholderProps extends React.HTMLAttributes<HTMLDivElement> {}
export function EmptyPlaceholder({
className,
children,
...props
}: EmptyPlaceholderProps) {
return (
<div
className={cn(
"flex max-h-[300px] flex-1 items-center justify-center rounded-lg p-8 text-center shadow-sm animate-in fade-in-50",
className,
)}
{...props}
>
<div className="flex max-w-[420px] flex-col items-center text-center">
{children}
</div>
</div>
);
}
interface EmptyPlaceholderIconProps
extends Partial<React.SVGProps<SVGSVGElement>> {
name: keyof typeof Icons;
ref?:
| ((instance: SVGSVGElement | null) => void)
| React.RefObject<SVGSVGElement>
| null;
}
EmptyPlaceholder.Icon = function EmptyPlaceholderIcon({
name,
className,
...props
}: EmptyPlaceholderIconProps) {
const Icon = Icons[name];
if (!Icon) {
return null;
}
return (
<div className="flex size-20 items-center justify-center rounded-full bg-muted">
<Icon className={cn("size-10", className)} {...props} />
</div>
);
};
interface EmptyPlaceholderTitleProps
extends React.HTMLAttributes<HTMLHeadingElement> {}
EmptyPlaceholder.Title = function EmptyPlaceholderTitle({
className,
...props
}: EmptyPlaceholderTitleProps) {
return (
<h3
className={cn("mt-5 font-heading text-2xl font-bold", className)}
{...props}
/>
);
};
interface EmptyPlaceholderDescriptionProps
extends React.HTMLAttributes<HTMLParagraphElement> {}
EmptyPlaceholder.Description = function EmptyPlaceholderDescription({
className,
...props
}: EmptyPlaceholderDescriptionProps) {
return (
<p
className={cn(
"mb-5 mt-1.5 text-center text-sm font-normal leading-6 text-muted-foreground",
className,
)}
{...props}
/>
);
};