收口前端平台组件库能力
新增 PlatformUiKit 通用弹窗、按钮、状态、空态、媒体、表单和标签等公共组件 迁移结果页、创作工作台、认证入口、RPG 暗色面板和运行态弹窗的重复 UI chrome 补充组件测试、页面回归测试、技术文档和 Hermes 共享决策记录
This commit is contained in:
@@ -1,10 +1,18 @@
|
||||
import { X } from 'lucide-react';
|
||||
import type { ReactNode } from 'react';
|
||||
|
||||
import type {
|
||||
CustomWorldCreatorIntent,
|
||||
CustomWorldGenerationMode,
|
||||
} from '../types';
|
||||
import { PlatformActionButton } from './common/PlatformActionButton';
|
||||
import { PlatformModalCloseButton } from './common/PlatformModalCloseButton';
|
||||
import { PlatformProgressBar } from './common/PlatformProgressBar';
|
||||
import { PlatformStatusMessage } from './common/PlatformStatusMessage';
|
||||
import { PlatformSubpanel } from './common/PlatformSubpanel';
|
||||
import {
|
||||
PlatformSelectField,
|
||||
PlatformTextField,
|
||||
} from './common/PlatformTextField';
|
||||
|
||||
type BaseModalProps = {
|
||||
isOpen: boolean;
|
||||
@@ -28,13 +36,11 @@ function SelectionModal({
|
||||
<div className="platform-modal-shell platform-remap-surface flex max-h-[90vh] w-full max-w-2xl flex-col overflow-hidden rounded-3xl shadow-[0_30px_80px_rgba(0,0,0,0.55)]">
|
||||
<div className="flex items-center justify-between border-b border-white/10 px-5 py-4">
|
||||
<div className="text-base font-semibold text-white">{title}</div>
|
||||
<button
|
||||
type="button"
|
||||
<PlatformModalCloseButton
|
||||
label={`关闭${title}`}
|
||||
variant="editorDark"
|
||||
onClick={onClose}
|
||||
className="rounded-full border border-white/10 bg-white/5 p-2 text-zinc-300 transition hover:bg-white/10 hover:text-white"
|
||||
>
|
||||
<X className="h-4 w-4" />
|
||||
</button>
|
||||
/>
|
||||
</div>
|
||||
<div className="min-h-0 flex-1 overflow-y-auto px-5 py-5">
|
||||
{children}
|
||||
@@ -79,50 +85,71 @@ export function CharacterDraftModal(props: {
|
||||
onClose={onClose}
|
||||
footer={(
|
||||
<>
|
||||
<button
|
||||
type="button"
|
||||
<PlatformActionButton
|
||||
surface="editorDark"
|
||||
tone="secondary"
|
||||
size="sm"
|
||||
onClick={onClose}
|
||||
className="rounded-2xl border border-white/10 bg-white/5 px-4 py-2 text-sm text-zinc-300 transition hover:bg-white/10 hover:text-white"
|
||||
>
|
||||
取消
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
</PlatformActionButton>
|
||||
<PlatformActionButton
|
||||
surface="editorDark"
|
||||
tone="success"
|
||||
size="sm"
|
||||
onClick={onConfirm}
|
||||
className="rounded-2xl bg-emerald-400 px-4 py-2 text-sm font-semibold text-slate-950 transition hover:bg-emerald-300"
|
||||
>
|
||||
确认进入
|
||||
</button>
|
||||
</PlatformActionButton>
|
||||
</>
|
||||
)}
|
||||
>
|
||||
<div className="space-y-4">
|
||||
<div className="rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm text-zinc-300">
|
||||
<PlatformSubpanel
|
||||
as="div"
|
||||
surface="dark"
|
||||
radius="md"
|
||||
padding="row"
|
||||
className="text-sm text-zinc-300"
|
||||
>
|
||||
当前角色:{characterLabel}
|
||||
</div>
|
||||
</PlatformSubpanel>
|
||||
<label className="block">
|
||||
<div className="mb-2 text-sm font-medium text-zinc-200">角色名字</div>
|
||||
<input
|
||||
<PlatformTextField
|
||||
value={draftName}
|
||||
onChange={(event) => onNameChange(event.target.value)}
|
||||
placeholder="输入一个更贴合这次旅程的称呼"
|
||||
className="w-full rounded-2xl border border-white/10 bg-black/30 px-4 py-3 text-sm text-white outline-none transition focus:border-emerald-400/40"
|
||||
surface="editorDark"
|
||||
tone="emerald"
|
||||
density="roomy"
|
||||
className="rounded-2xl"
|
||||
/>
|
||||
</label>
|
||||
<label className="block">
|
||||
<div className="mb-2 text-sm font-medium text-zinc-200">背景补充</div>
|
||||
<textarea
|
||||
<PlatformTextField
|
||||
variant="textarea"
|
||||
value={draftBackstory}
|
||||
onChange={(event) => onBackstoryChange(event.target.value)}
|
||||
rows={6}
|
||||
placeholder="可以补充这次开局想强调的身份、经历、执念或禁忌。"
|
||||
className="w-full rounded-2xl border border-white/10 bg-black/30 px-4 py-3 text-sm leading-7 text-white outline-none transition focus:border-emerald-400/40"
|
||||
surface="editorDark"
|
||||
tone="emerald"
|
||||
size="md"
|
||||
density="roomy"
|
||||
className="rounded-2xl leading-7"
|
||||
/>
|
||||
</label>
|
||||
{error ? (
|
||||
<div className="rounded-2xl border border-rose-400/25 bg-rose-500/10 px-4 py-3 text-sm text-rose-100">
|
||||
<PlatformStatusMessage
|
||||
tone="error"
|
||||
surface="editorDark"
|
||||
size="md"
|
||||
className="rounded-2xl"
|
||||
>
|
||||
{error}
|
||||
</div>
|
||||
</PlatformStatusMessage>
|
||||
) : null}
|
||||
</div>
|
||||
</SelectionModal>
|
||||
@@ -199,22 +226,24 @@ export function CustomWorldCreatorModal(props: CustomWorldCreatorModalProps) {
|
||||
onClose={onClose}
|
||||
footer={(
|
||||
<>
|
||||
<button
|
||||
type="button"
|
||||
<PlatformActionButton
|
||||
surface="editorDark"
|
||||
tone="secondary"
|
||||
size="sm"
|
||||
onClick={onClose}
|
||||
disabled={isGenerating}
|
||||
className="rounded-2xl border border-white/10 bg-white/5 px-4 py-2 text-sm text-zinc-300 transition hover:bg-white/10 hover:text-white disabled:cursor-not-allowed disabled:opacity-50"
|
||||
>
|
||||
取消
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
</PlatformActionButton>
|
||||
<PlatformActionButton
|
||||
surface="editorDark"
|
||||
tone="primary"
|
||||
size="sm"
|
||||
onClick={onSubmit}
|
||||
disabled={isGenerating}
|
||||
className="rounded-2xl bg-sky-400 px-4 py-2 text-sm font-semibold text-slate-950 transition hover:bg-sky-300 disabled:cursor-not-allowed disabled:opacity-50"
|
||||
>
|
||||
{isGenerating ? '生成中...' : '开始生成'}
|
||||
</button>
|
||||
</PlatformActionButton>
|
||||
</>
|
||||
)}
|
||||
>
|
||||
@@ -222,18 +251,21 @@ export function CustomWorldCreatorModal(props: CustomWorldCreatorModalProps) {
|
||||
{hasCreatorIntentProps(props) ? (
|
||||
<label className="block">
|
||||
<div className="mb-2 text-sm font-medium text-zinc-200">生成模式</div>
|
||||
<select
|
||||
<PlatformSelectField
|
||||
value={props.generationMode}
|
||||
onChange={(event) =>
|
||||
props.onGenerationModeChange(
|
||||
event.target.value as CustomWorldGenerationMode,
|
||||
)
|
||||
}
|
||||
className="w-full rounded-2xl border border-white/10 bg-black/30 px-4 py-3 text-sm text-white outline-none transition focus:border-sky-400/40"
|
||||
surface="editorDark"
|
||||
tone="sky"
|
||||
density="roomy"
|
||||
className="rounded-2xl"
|
||||
>
|
||||
<option value="fast">快速</option>
|
||||
<option value="full">完整</option>
|
||||
</select>
|
||||
</PlatformSelectField>
|
||||
</label>
|
||||
) : null}
|
||||
|
||||
@@ -241,33 +273,49 @@ export function CustomWorldCreatorModal(props: CustomWorldCreatorModalProps) {
|
||||
用几句话描述世界观、核心矛盾、时代气质和你想体验的叙事方向。系统会据此生成可游玩的自定义世界。
|
||||
</div>
|
||||
|
||||
<textarea
|
||||
<PlatformTextField
|
||||
variant="textarea"
|
||||
value={draftText}
|
||||
onChange={(event) => updateDraftText(event.target.value)}
|
||||
rows={8}
|
||||
placeholder="例:一个被潮雾与失落列岛切碎的边境世界,旧盟约、沉船秘术与灯塔守望者纠缠在一起……"
|
||||
className="w-full rounded-2xl border border-white/10 bg-black/30 px-4 py-3 text-sm leading-7 text-white outline-none transition focus:border-sky-400/40"
|
||||
surface="editorDark"
|
||||
tone="sky"
|
||||
size="md"
|
||||
density="roomy"
|
||||
className="rounded-2xl leading-7"
|
||||
/>
|
||||
|
||||
{isGenerating ? (
|
||||
<div className="rounded-2xl border border-sky-300/15 bg-sky-500/10 px-4 py-3">
|
||||
<PlatformStatusMessage
|
||||
tone="info"
|
||||
surface="editorDark"
|
||||
size="md"
|
||||
className="rounded-2xl"
|
||||
>
|
||||
<div className="mb-2 flex items-center justify-between text-xs tracking-[0.16em] text-sky-100/80">
|
||||
<span>{progressLabel}</span>
|
||||
<span>{Math.max(0, Math.min(100, Math.round(progress)))}%</span>
|
||||
</div>
|
||||
<div className="h-2 overflow-hidden rounded-full bg-white/10">
|
||||
<div
|
||||
className="h-full rounded-full bg-gradient-to-r from-sky-300 to-cyan-200 transition-[width] duration-300"
|
||||
style={{ width: `${Math.max(6, Math.min(100, progress))}%` }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<PlatformProgressBar
|
||||
value={progress}
|
||||
minVisibleValue={6}
|
||||
ariaLabel="自定义世界生成进度"
|
||||
className="bg-white/10"
|
||||
fillClassName="bg-gradient-to-r from-sky-300 to-cyan-200"
|
||||
/>
|
||||
</PlatformStatusMessage>
|
||||
) : null}
|
||||
|
||||
{error ? (
|
||||
<div className="rounded-2xl border border-rose-400/25 bg-rose-500/10 px-4 py-3 text-sm text-rose-100">
|
||||
<PlatformStatusMessage
|
||||
tone="error"
|
||||
surface="editorDark"
|
||||
size="md"
|
||||
className="rounded-2xl"
|
||||
>
|
||||
{error}
|
||||
</div>
|
||||
</PlatformStatusMessage>
|
||||
) : null}
|
||||
</div>
|
||||
</SelectionModal>
|
||||
|
||||
Reference in New Issue
Block a user