feat: 外观支持自定义 CSS/JS,并升级发帖工作台与积分存量看板
后台可注入全站 CSS/JS(SSR 生效,CSS 可热换);发帖/编辑改为锁一屏工作室;经济看板增加存量健康度;主题令牌与弹层误关一并收紧。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -45,14 +45,16 @@ export function AdminChartCard({
|
||||
hint,
|
||||
children,
|
||||
actions,
|
||||
className = "",
|
||||
}: {
|
||||
title: string;
|
||||
hint?: string;
|
||||
children: React.ReactNode;
|
||||
actions?: React.ReactNode;
|
||||
className?: string;
|
||||
}) {
|
||||
return (
|
||||
<div className="panel p-4 sm:p-5 flex flex-col min-h-[260px]">
|
||||
<div className={`panel p-4 sm:p-5 flex flex-col ${className}`.trim()}>
|
||||
<div className="flex items-start justify-between gap-2 mb-3">
|
||||
<div className="min-w-0">
|
||||
<h3 className="text-[14.5px] font-semibold" style={{ color: "var(--ink)" }}>
|
||||
@@ -66,7 +68,7 @@ export function AdminChartCard({
|
||||
</div>
|
||||
{/* 捕获阶段拦截 mousedown:冒泡阶段太晚,浏览器已开始 SVG 多柱选区黑框 */}
|
||||
<div
|
||||
className="flex-1 min-h-[180px] w-full overflow-hidden select-none [&_*]:select-none [&_svg]:outline-none [&_.recharts-surface]:outline-none [&_.recharts-tooltip-cursor]:hidden"
|
||||
className="w-full overflow-hidden select-none [&_*]:select-none [&_svg]:outline-none [&_.recharts-surface]:outline-none [&_.recharts-tooltip-cursor]:hidden"
|
||||
onMouseDownCapture={(e) => e.preventDefault()}
|
||||
>
|
||||
{children}
|
||||
@@ -144,15 +146,17 @@ export function SingleAreaChart({
|
||||
dataKey,
|
||||
name,
|
||||
color = "var(--accent)",
|
||||
height = 200,
|
||||
}: {
|
||||
data: { date: string; [k: string]: string | number }[];
|
||||
dataKey: string;
|
||||
name: string;
|
||||
color?: string;
|
||||
height?: number;
|
||||
}) {
|
||||
const rows = data.map((d) => ({ ...d, label: shortDate(String(d.date)) }));
|
||||
return (
|
||||
<ResponsiveContainer width="100%" height={200}>
|
||||
<ResponsiveContainer width="100%" height={height}>
|
||||
<AreaChart data={rows} margin={{ top: 12, right: 12, left: 0, bottom: 0 }} accessibilityLayer={false}>
|
||||
<CartesianGrid stroke="var(--line)" strokeDasharray="3 3" vertical={false} />
|
||||
<XAxis dataKey="label" tick={{ fill: "var(--ink-3)", fontSize: 11 }} axisLine={false} tickLine={false} />
|
||||
@@ -183,8 +187,10 @@ export function NamedBarChart({
|
||||
layout?: "vertical" | "horizontal";
|
||||
}) {
|
||||
if (layout === "horizontal") {
|
||||
// 固定像素高度,避免 overflow 滚动条 ↔ ResponsiveContainer 互相触发闪烁
|
||||
const chartH = Math.max(180, Math.min(320, data.length * 28));
|
||||
return (
|
||||
<ResponsiveContainer width="100%" height={Math.max(180, data.length * 28)}>
|
||||
<ResponsiveContainer width="100%" height={chartH}>
|
||||
<BarChart data={data} layout="vertical" margin={{ top: 8, right: 12, left: 8, bottom: 4 }} accessibilityLayer={false}>
|
||||
<CartesianGrid stroke="var(--line)" strokeDasharray="3 3" horizontal={false} />
|
||||
<XAxis type="number" tick={{ fill: "var(--ink-3)", fontSize: 11 }} axisLine={false} allowDecimals={false} />
|
||||
|
||||
Reference in New Issue
Block a user