ed2c386603
账号设置弹窗复用认证壳层并保留 direct mode 唯一 dialog 语义 拼图运行态新增本地弹窗壳层收口确认设置退出失败和通关结算 抓大鹅与跳一跳结算弹窗提取本地结算结构并补测试 拼图 onboarding 登录保存覆盖层迁入 UnifiedModal 更新 PlatformUiKit 收口文档和 Hermes 决策记录
94 lines
2.1 KiB
TypeScript
94 lines
2.1 KiB
TypeScript
import type {
|
|
ButtonHTMLAttributes,
|
|
MouseEvent,
|
|
ReactNode,
|
|
} from 'react';
|
|
|
|
type PuzzleRuntimeModalShellProps = {
|
|
titleId: string;
|
|
children: ReactNode;
|
|
overlayClassName?: string;
|
|
dialogClassName?: string;
|
|
onOverlayClick?: () => void;
|
|
};
|
|
|
|
type PuzzleRuntimeDialogFooterProps = {
|
|
children: ReactNode;
|
|
className: string;
|
|
framed?: boolean;
|
|
};
|
|
|
|
type PuzzleRuntimeDialogButtonProps =
|
|
ButtonHTMLAttributes<HTMLButtonElement> & {
|
|
tone: 'primary' | 'secondary';
|
|
};
|
|
|
|
const DEFAULT_OVERLAY_CLASS_NAME =
|
|
'puzzle-runtime-modal-overlay absolute inset-0 z-50 flex items-center justify-center p-4 backdrop-blur-sm';
|
|
|
|
const DEFAULT_DIALOG_CLASS_NAME =
|
|
'puzzle-runtime-dialog w-full max-w-[22rem] overflow-hidden rounded-[1.35rem] shadow-[0_24px_80px_rgba(0,0,0,0.24)]';
|
|
|
|
export function PuzzleRuntimeModalShell({
|
|
titleId,
|
|
children,
|
|
overlayClassName = DEFAULT_OVERLAY_CLASS_NAME,
|
|
dialogClassName = DEFAULT_DIALOG_CLASS_NAME,
|
|
onOverlayClick,
|
|
}: PuzzleRuntimeModalShellProps) {
|
|
const handleDialogClick = (event: MouseEvent<HTMLElement>) => {
|
|
event.stopPropagation();
|
|
};
|
|
|
|
return (
|
|
<div
|
|
className={overlayClassName}
|
|
onClick={onOverlayClick ? () => onOverlayClick() : undefined}
|
|
>
|
|
<section
|
|
role="dialog"
|
|
aria-modal="true"
|
|
aria-labelledby={titleId}
|
|
className={dialogClassName}
|
|
onClick={handleDialogClick}
|
|
>
|
|
{children}
|
|
</section>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function PuzzleRuntimeDialogFooter({
|
|
children,
|
|
className,
|
|
framed = true,
|
|
}: PuzzleRuntimeDialogFooterProps) {
|
|
return (
|
|
<footer
|
|
className={`${framed ? 'puzzle-runtime-dialog__line border-t ' : ''}${className}`}
|
|
>
|
|
{children}
|
|
</footer>
|
|
);
|
|
}
|
|
|
|
export function PuzzleRuntimeDialogButton({
|
|
tone,
|
|
className = '',
|
|
type = 'button',
|
|
...buttonProps
|
|
}: PuzzleRuntimeDialogButtonProps) {
|
|
const toneClassName =
|
|
tone === 'primary'
|
|
? 'puzzle-runtime-primary-button'
|
|
: 'puzzle-runtime-secondary-button';
|
|
|
|
return (
|
|
<button
|
|
{...buttonProps}
|
|
type={type}
|
|
className={`${toneClassName} ${className}`}
|
|
/>
|
|
);
|
|
}
|