feat: tip component
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
"use client";
|
||||
|
||||
import type { TipBlockPayload } from "@/lib/blog-blocks";
|
||||
import { Info, AlertTriangle, AlertCircle } from "lucide-react";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
interface BlogTipProps {
|
||||
payload: TipBlockPayload;
|
||||
}
|
||||
|
||||
const variantConfig = {
|
||||
info: {
|
||||
icon: Info,
|
||||
className:
|
||||
"border-primary/40 bg-primary/5 text-foreground [&_strong]:text-primary",
|
||||
iconClassName: "text-primary",
|
||||
},
|
||||
warn: {
|
||||
icon: AlertTriangle,
|
||||
className:
|
||||
"border-amber-500/50 bg-amber-500/10 text-foreground [&_strong]:text-amber-600 dark:[&_strong]:text-amber-400",
|
||||
iconClassName: "text-amber-500",
|
||||
},
|
||||
danger: {
|
||||
icon: AlertCircle,
|
||||
className:
|
||||
"border-destructive/50 bg-destructive/10 text-foreground [&_strong]:text-destructive",
|
||||
iconClassName: "text-destructive",
|
||||
},
|
||||
} as const;
|
||||
|
||||
export function BlogTip({ payload }: BlogTipProps) {
|
||||
const { variant, content } = payload;
|
||||
if (!content.trim()) return null;
|
||||
|
||||
const config = variantConfig[variant ?? 'info'];
|
||||
const Icon = config.icon;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"my-6 flex gap-3 rounded-xl border p-4 pr-4 shadow-sm",
|
||||
config.className
|
||||
)}
|
||||
role="note"
|
||||
>
|
||||
<Icon
|
||||
className={cn("mt-0.5 size-8 shrink-0", config.iconClassName)}
|
||||
aria-hidden
|
||||
/>
|
||||
<div
|
||||
className="blog-tip-content min-w-0 text-sm leading-relaxed [&_p]:my-2 [&_p:first-child]:mt-0 [&_p:last-child]:mb-0 [&_a]:text-primary [&_a]:underline hover:[&_a]:no-underline"
|
||||
dangerouslySetInnerHTML={{ __html: content }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user