收口前端平台组件库能力

新增 PlatformUiKit 通用弹窗、按钮、状态、空态、媒体、表单和标签等公共组件
迁移结果页、创作工作台、认证入口、RPG 暗色面板和运行态弹窗的重复 UI chrome
补充组件测试、页面回归测试、技术文档和 Hermes 共享决策记录
This commit is contained in:
2026-06-10 10:24:18 +08:00
parent a4ee6ff698
commit 1ad25e30f8
226 changed files with 23364 additions and 7825 deletions

View File

@@ -1,13 +1,14 @@
import { Check, Copy } from 'lucide-react';
import { useEffect, useMemo, useRef, useState } from 'react';
import { useEffect, useMemo } from 'react';
import { copyTextToClipboard } from '../../services/clipboard';
import { useAuthUi } from '../auth/AuthUiContext';
import { CopyFeedbackButton } from './CopyFeedbackButton';
import { PlatformInfoBlock } from './PlatformInfoBlock';
import {
buildPublishShareText,
type PublishShareModalPayload,
} from './publishShareModalModel';
import { UnifiedModal } from './UnifiedModal';
import { useCopyFeedback } from './useCopyFeedback';
type PublishShareModalProps = {
open: boolean;
@@ -94,43 +95,22 @@ export function PublishShareModal({
onClose,
}: PublishShareModalProps) {
const platformTheme = useAuthUi()?.platformTheme ?? 'light';
const [copyState, setCopyState] = useState<'idle' | 'copied' | 'failed'>(
'idle',
);
const resetTimerRef = useRef<number | null>(null);
const { copyState, copyText, resetCopyState } = useCopyFeedback();
const shareText = useMemo(
() => (payload ? buildPublishShareText(payload) : ''),
[payload],
);
useEffect(
() => () => {
if (resetTimerRef.current !== null) {
window.clearTimeout(resetTimerRef.current);
}
},
[],
);
useEffect(() => {
setCopyState('idle');
}, [payload?.publicWorkCode]);
resetCopyState();
}, [payload?.publicWorkCode, resetCopyState]);
const copyShareText = () => {
if (!shareText) {
return;
}
void copyTextToClipboard(shareText).then((copied) => {
setCopyState(copied ? 'copied' : 'failed');
if (resetTimerRef.current !== null) {
window.clearTimeout(resetTimerRef.current);
}
resetTimerRef.current = window.setTimeout(() => {
resetTimerRef.current = null;
setCopyState('idle');
}, 1400);
});
void copyText(shareText);
};
return (
@@ -167,28 +147,22 @@ export function PublishShareModal({
</div>
}
>
<div className="rounded-[1.25rem] border border-[var(--platform-subpanel-border)] bg-white/72 p-4">
<div className="whitespace-pre-wrap break-words text-sm leading-6 text-[var(--platform-text-strong)]">
{shareText}
</div>
</div>
<button
type="button"
<PlatformInfoBlock
multiline
className="rounded-[1.25rem] p-4"
valueClassName="mt-0"
>
{shareText}
</PlatformInfoBlock>
<CopyFeedbackButton
state={copyState}
onClick={copyShareText}
disabled={!shareText}
className="platform-button platform-button--primary w-full justify-center gap-2 disabled:cursor-not-allowed disabled:opacity-55"
>
{copyState === 'copied' ? (
<Check className="h-4 w-4" />
) : (
<Copy className="h-4 w-4" />
)}
{copyState === 'copied'
? '已复制'
: copyState === 'failed'
? '复制失败'
: '分享'}
</button>
idleLabel="分享"
actionSurface="platform"
actionFullWidth
className="disabled:opacity-55"
/>
</UnifiedModal>
);
}