Files
Genarrative/src/components/common/PlatformModalCloseButton.tsx
kdletters 94122583ac 收口前端平台组件能力
新增 PlatformAsyncStatePanel 统一 profile 异步状态骨架
扩展 PlatformSegmentedTabs 支持滚动 tab 并接入创作入口与发现页
统一 PixelCloseButton 复用 PlatformModalCloseButton 像素关闭能力
抽取平台入口泥点前置提示弹层并收紧阻断语义
补充组件收口文档与共享决策记录
2026-06-11 01:06:31 +08:00

105 lines
3.0 KiB
TypeScript

import { X } from 'lucide-react';
import type {
ButtonHTMLAttributes,
MouseEvent as ReactMouseEvent,
ReactNode,
} from 'react';
type PlatformModalCloseButtonVariant =
| 'profile'
| 'profileCompact'
| 'floating'
| 'floatingPlain'
| 'platformIcon'
| 'pixel'
| 'editorDark';
type PlatformModalCloseButtonPlacement = 'absolute' | 'inline';
type PlatformModalCloseButtonProps = Omit<
ButtonHTMLAttributes<HTMLButtonElement>,
'children'
> & {
label: string;
variant?: PlatformModalCloseButtonVariant;
icon?: ReactNode;
placement?: PlatformModalCloseButtonPlacement;
stopPropagation?: boolean;
};
const PLATFORM_MODAL_CLOSE_BUTTON_CLASS_BY_VARIANT: Record<
PlatformModalCloseButtonVariant,
string
> = {
profile:
'platform-modal-close flex h-9 w-9 items-center justify-center rounded-full',
profileCompact:
'platform-profile-icon-button flex h-8 w-8 items-center justify-center rounded-full',
floating:
'absolute right-3 top-3 z-10 flex h-8 w-8 items-center justify-center rounded-full bg-white/80 text-[#ff4056] shadow-sm',
floatingPlain:
'absolute right-3 top-2 z-10 flex h-8 w-8 items-center justify-center rounded-full text-[#ff4056]',
platformIcon: 'platform-icon-button disabled:cursor-not-allowed disabled:opacity-45',
pixel:
'flex h-9 w-9 items-center justify-center rounded-full border border-white/10 bg-black/30 p-0 text-zinc-400 shadow-[0_8px_18px_rgba(0,0,0,0.28)] transition-colors hover:text-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-amber-200/70 disabled:cursor-not-allowed disabled:opacity-45',
editorDark:
'platform-modal-close-button--editor-dark rounded-full border border-white/10 bg-white/5 p-2 text-zinc-300 transition hover:bg-white/10 hover:text-white',
};
const PLATFORM_MODAL_CLOSE_BUTTON_PIXEL_PLACEMENT_CLASS_BY_PLACEMENT: Record<
PlatformModalCloseButtonPlacement,
string
> = {
absolute: 'absolute right-4 top-3 sm:right-5 sm:top-4',
inline: 'relative shrink-0',
};
/**
* 平台弹窗关闭按钮。
* 收口个人中心和平台浮层里重复的关闭 aria、尺寸和视觉样式。
*/
export function PlatformModalCloseButton({
label,
variant = 'profile',
icon = <X className="h-4 w-4" />,
className,
type = 'button',
placement = 'absolute',
stopPropagation = false,
onClick,
title,
...buttonProps
}: PlatformModalCloseButtonProps) {
const handleClick = (event: ReactMouseEvent<HTMLButtonElement>) => {
if (stopPropagation) {
event.preventDefault();
event.stopPropagation();
}
onClick?.(event);
};
return (
<button
{...buttonProps}
type={type}
aria-label={label}
title={title ?? label}
onClick={handleClick}
className={[
PLATFORM_MODAL_CLOSE_BUTTON_CLASS_BY_VARIANT[variant],
variant === 'pixel'
? PLATFORM_MODAL_CLOSE_BUTTON_PIXEL_PLACEMENT_CLASS_BY_PLACEMENT[
placement
]
: null,
className,
]
.filter(Boolean)
.join(' ')}
>
{icon}
</button>
);
}