170 lines
3.9 KiB
TypeScript
170 lines
3.9 KiB
TypeScript
"use client";
|
|
|
|
import * as React from "react";
|
|
import { cva, type VariantProps } from "class-variance-authority";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
export type PlatformKey =
|
|
| "wenxin"
|
|
| "kimi"
|
|
| "tongyi"
|
|
| "baidu_ai"
|
|
| "yuanbao"
|
|
| "qingyan"
|
|
| "doubao"
|
|
| "tiangong"
|
|
| "xinghuo"
|
|
| string;
|
|
|
|
interface PlatformConfig {
|
|
label: string;
|
|
short: string;
|
|
colorClass: string;
|
|
bgClass: string;
|
|
textClass: string;
|
|
}
|
|
|
|
const platformConfigs: Record<string, PlatformConfig> = {
|
|
wenxin: {
|
|
label: "文心一言",
|
|
short: "文",
|
|
colorClass: "border-blue-200",
|
|
bgClass: "bg-blue-50",
|
|
textClass: "text-blue-600",
|
|
},
|
|
kimi: {
|
|
label: "Kimi",
|
|
short: "K",
|
|
colorClass: "border-indigo-200",
|
|
bgClass: "bg-indigo-50",
|
|
textClass: "text-indigo-600",
|
|
},
|
|
tongyi: {
|
|
label: "通义千问",
|
|
short: "通",
|
|
colorClass: "border-purple-200",
|
|
bgClass: "bg-purple-50",
|
|
textClass: "text-purple-600",
|
|
},
|
|
baidu_ai: {
|
|
label: "百度AI",
|
|
short: "百",
|
|
colorClass: "border-red-200",
|
|
bgClass: "bg-red-50",
|
|
textClass: "text-red-600",
|
|
},
|
|
yuanbao: {
|
|
label: "腾讯元宝",
|
|
short: "元",
|
|
colorClass: "border-cyan-200",
|
|
bgClass: "bg-cyan-50",
|
|
textClass: "text-cyan-600",
|
|
},
|
|
qingyan: {
|
|
label: "智谱清言",
|
|
short: "智",
|
|
colorClass: "border-violet-200",
|
|
bgClass: "bg-violet-50",
|
|
textClass: "text-violet-600",
|
|
},
|
|
doubao: {
|
|
label: "豆包",
|
|
short: "豆",
|
|
colorClass: "border-amber-200",
|
|
bgClass: "bg-amber-50",
|
|
textClass: "text-amber-600",
|
|
},
|
|
tiangong: {
|
|
label: "天工AI",
|
|
short: "天",
|
|
colorClass: "border-sky-200",
|
|
bgClass: "bg-sky-50",
|
|
textClass: "text-sky-600",
|
|
},
|
|
xinghuo: {
|
|
label: "讯飞星火",
|
|
short: "星",
|
|
colorClass: "border-orange-200",
|
|
bgClass: "bg-orange-50",
|
|
textClass: "text-orange-600",
|
|
},
|
|
};
|
|
|
|
const fallbackConfig: PlatformConfig = {
|
|
label: "未知平台",
|
|
short: "?",
|
|
colorClass: "border-border",
|
|
bgClass: "bg-muted",
|
|
textClass: "text-muted-foreground",
|
|
};
|
|
|
|
const platformBadgeVariants = cva(
|
|
"inline-flex items-center gap-1.5 rounded-md border font-medium transition-colors duration-200",
|
|
{
|
|
variants: {
|
|
size: {
|
|
sm: "px-2 py-0.5 text-xs",
|
|
default: "px-2.5 py-1 text-xs",
|
|
lg: "px-3 py-1.5 text-sm",
|
|
},
|
|
showIcon: {
|
|
true: "",
|
|
false: "",
|
|
},
|
|
},
|
|
defaultVariants: {
|
|
size: "default",
|
|
showIcon: true,
|
|
},
|
|
}
|
|
);
|
|
|
|
export interface PlatformBadgeProps
|
|
extends React.HTMLAttributes<HTMLDivElement>,
|
|
Omit<VariantProps<typeof platformBadgeVariants>, "showIcon"> {
|
|
platform: PlatformKey;
|
|
/** 自定义标签文字(默认用平台名称) */
|
|
label?: string;
|
|
/** 是否显示左侧图标圆点 */
|
|
showIcon?: boolean;
|
|
/** 是否只显示icon不显示文字 */
|
|
iconOnly?: boolean;
|
|
}
|
|
|
|
const PlatformBadge = React.forwardRef<HTMLDivElement, PlatformBadgeProps>(
|
|
({ className, platform, label, showIcon = true, iconOnly = false, size, ...props }, ref) => {
|
|
const config = platformConfigs[platform] ?? { ...fallbackConfig, label: platform, short: platform.slice(0, 1).toUpperCase() };
|
|
const displayLabel = label ?? config.label;
|
|
|
|
return (
|
|
<div
|
|
ref={ref}
|
|
className={cn(
|
|
platformBadgeVariants({ size, showIcon }),
|
|
config.bgClass,
|
|
config.colorClass,
|
|
config.textClass,
|
|
className
|
|
)}
|
|
title={displayLabel}
|
|
{...props}
|
|
>
|
|
{showIcon && (
|
|
<span
|
|
className={cn(
|
|
"flex items-center justify-center rounded font-bold shrink-0",
|
|
size === "lg" ? "h-4.5 w-4.5 text-xs" : "h-4 w-4 text-[10px]"
|
|
)}
|
|
>
|
|
{config.short}
|
|
</span>
|
|
)}
|
|
{!iconOnly && <span>{displayLabel}</span>}
|
|
</div>
|
|
);
|
|
}
|
|
);
|
|
PlatformBadge.displayName = "PlatformBadge";
|
|
|
|
export { PlatformBadge, platformConfigs };
|