68 lines
1.7 KiB
TypeScript
68 lines
1.7 KiB
TypeScript
import type { ReactNode } from "react";
|
|
import { Info, Lightbulb, TriangleAlert, CircleAlert } from "lucide-react";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
/**
|
|
* 提示块:可在 MDX 正文中直接使用。
|
|
*
|
|
* 颜色取自 DESIGN.md 的语义色:
|
|
* - info → brand-tag(信息蓝)
|
|
* - tip → brand-green(品牌绿)
|
|
* - warning → brand-warn(警告橙)
|
|
* - danger → brand-error(错误红)
|
|
*/
|
|
const CALLOUT_VARIANTS = {
|
|
info: {
|
|
icon: Info,
|
|
label: "说明",
|
|
className: "border-brand-tag/30 bg-brand-tag/[0.06] text-brand-tag",
|
|
},
|
|
tip: {
|
|
icon: Lightbulb,
|
|
label: "提示",
|
|
className:
|
|
"border-brand-green/40 bg-brand-green/[0.07] text-brand-green-deep",
|
|
},
|
|
warning: {
|
|
icon: TriangleAlert,
|
|
label: "注意",
|
|
className: "border-brand-warn/30 bg-brand-warn/[0.07] text-brand-warn",
|
|
},
|
|
danger: {
|
|
icon: CircleAlert,
|
|
label: "警告",
|
|
className: "border-brand-error/30 bg-brand-error/[0.06] text-brand-error",
|
|
},
|
|
} as const;
|
|
|
|
export type CalloutType = keyof typeof CALLOUT_VARIANTS;
|
|
|
|
export interface CalloutProps {
|
|
type?: CalloutType;
|
|
title?: string;
|
|
children: ReactNode;
|
|
}
|
|
|
|
export function Callout({ type = "info", title, children }: CalloutProps) {
|
|
const variant = CALLOUT_VARIANTS[type] ?? CALLOUT_VARIANTS.info;
|
|
const Icon = variant.icon;
|
|
|
|
return (
|
|
<aside
|
|
className={cn(
|
|
"my-xl flex gap-sm rounded-md border p-md",
|
|
variant.className,
|
|
)}
|
|
>
|
|
<Icon className="mt-[2px] size-4 shrink-0" aria-hidden="true" />
|
|
|
|
<div className="flex-1 text-body-sm">
|
|
<p className="mb-xxs font-semibold">
|
|
{title ?? variant.label}
|
|
</p>
|
|
<div className="text-slate [&>p]:text-slate [&>p+p]:mt-xs">{children}</div>
|
|
</div>
|
|
</aside>
|
|
);
|
|
}
|