Files
Genarrative/src/components/common/PlatformDetailTopbar.tsx
T
kdletters 7c47ad3358 继续收口详情页头部动作组合
沉淀 PlatformDetailTopbar 与 PlatformDetailShareActions 共享骨架
接入 RPG 世界详情与公开作品详情的返回复制分享动作组合
补充测试护栏与文档决策记录
2026-06-11 06:32:20 +08:00

90 lines
2.0 KiB
TypeScript

import { ArrowLeft } from 'lucide-react';
import type { ReactNode } from 'react';
import { PlatformBackActionButton } from './PlatformBackActionButton';
import { PlatformIconButton } from './PlatformIconButton';
type PlatformDetailTopbarProps = {
onBack: () => void;
title?: ReactNode;
trailing?: ReactNode;
backVariant?: 'icon' | 'pill';
backLabel?: string;
className?: string;
backButtonClassName?: string;
titleClassName?: string;
trailingClassName?: string;
};
/**
* 详情页顶部动作骨架。
* 只统一返回、标题和右侧动作槽位的布局,不吸收页面自己的标题文案或业务动作。
*/
export function PlatformDetailTopbar({
onBack,
title,
trailing,
backVariant = 'pill',
backLabel = '返回',
className,
backButtonClassName,
titleClassName,
trailingClassName,
}: PlatformDetailTopbarProps) {
const backAction =
backVariant === 'icon' ? (
<PlatformIconButton
label={backLabel}
title={backLabel}
className={backButtonClassName}
onClick={onBack}
icon={<ArrowLeft className="h-6 w-6" />}
/>
) : (
<PlatformBackActionButton
onClick={onBack}
label={backLabel}
className={backButtonClassName}
/>
);
return (
<div
className={[
'grid min-w-0 grid-cols-[auto,minmax(0,1fr),auto] items-center gap-3',
className,
]
.filter(Boolean)
.join(' ')}
>
<div className="min-w-0 justify-self-start">
{backAction}
</div>
{title ? (
<div
className={[
'min-w-0 text-center',
titleClassName,
]
.filter(Boolean)
.join(' ')}
>
{title}
</div>
) : (
<div aria-hidden="true" />
)}
<div
className={[
'min-w-0 justify-self-end',
trailingClassName,
]
.filter(Boolean)
.join(' ')}
>
{trailing}
</div>
</div>
);
}