统一详情页操作区模板(05-31-unify-business-detail-ant-design)

这个提交包含在:
2026-05-31 12:21:42 +08:00
父节点 7b5476a70e
当前提交 2bcd9012f7
共修改 11 个文件,包含 513 行新增和 178 行删除
@@ -0,0 +1,117 @@
import { Children, type ReactNode } from "react";
import { cn } from "../../lib/utils";
import { SectionPanel } from "./SectionPanel";
export function BusinessDetailWorkspace({
children,
className,
testId,
}: {
children: ReactNode;
className?: string;
testId?: string;
}) {
return (
<div className={cn("detail-workspace-grid", className)} data-testid={testId}>
{children}
</div>
);
}
export function BusinessDetailMain({
children,
className,
}: {
children: ReactNode;
className?: string;
}) {
return <div className={cn("space-y-5", className)}>{children}</div>;
}
export function BusinessDetailAside({
children,
className,
}: {
children: ReactNode;
className?: string;
}) {
return <div className={cn("space-y-5", className)}>{children}</div>;
}
export function BusinessDetailFactGrid({
children,
className,
testId,
}: {
children: ReactNode;
className?: string;
testId?: string;
}) {
return (
<div className={cn("detail-fact-grid", className)} data-testid={testId}>
{children}
</div>
);
}
export function BusinessDetailFact({
label,
children,
className,
}: {
label: ReactNode;
children: ReactNode;
className?: string;
}) {
return (
<div className={cn("detail-fact-card", className)}>
<div className="detail-fact-card__label">{label}</div>
<div className="detail-fact-card__value">{children}</div>
</div>
);
}
export function BusinessDetailActionPanel({
title = "操作",
status,
primaryAction,
secondaryActions,
moreActions,
summary,
children,
className,
testId,
}: {
title?: string;
status?: ReactNode;
primaryAction?: ReactNode;
secondaryActions?: ReactNode;
moreActions?: ReactNode;
summary?: ReactNode;
children?: ReactNode;
className?: string;
testId?: string;
}) {
const visibleChildren = Children.toArray(children);
const hasActionContent = Boolean(primaryAction || secondaryActions || moreActions);
const hasChildren = visibleChildren.length > 0;
const hasContentBeforeSummary = Boolean(primaryAction || secondaryActions || moreActions || hasChildren);
return (
<SectionPanel title={title} actions={status} className={cn("detail-action-panel xl:sticky xl:top-24", className)}>
<div className="detail-action-stack" data-testid={testId}>
{primaryAction ? <div className="grid gap-2">{primaryAction}</div> : null}
{secondaryActions ? <div className="workflow-action-bar">{secondaryActions}</div> : null}
{moreActions ? <div className="border-t border-zinc-200 pt-3">{moreActions}</div> : null}
{hasChildren ? (
<div className={cn(hasActionContent && "border-t border-zinc-200 pt-3")}>{children}</div>
) : null}
{summary ? (
<div className={cn(hasContentBeforeSummary && "border-t border-zinc-200 pt-3")}>
<div className="space-y-2 text-sm text-zinc-600">{summary}</div>
</div>
) : null}
</div>
</SectionPanel>
);
}