收口前端平台组件库能力

新增 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

@@ -0,0 +1,90 @@
import type { CSSProperties, ReactNode } from 'react';
type PlatformProgressBarSize = 'xs' | 'sm' | 'md' | 'lg';
type PlatformProgressBarProps = {
value: number;
minVisibleValue?: number;
size?: PlatformProgressBarSize;
ariaLabel?: string;
labelledBy?: string;
indeterminate?: boolean;
className?: string;
fillClassName?: string;
fillStyle?: CSSProperties;
trackStyle?: CSSProperties;
children?: ReactNode;
};
const PLATFORM_PROGRESS_BAR_SIZE_CLASS: Record<
PlatformProgressBarSize,
string
> = {
xs: 'h-2',
sm: 'h-2.5',
md: 'h-3',
lg: 'h-12',
};
function clampProgressValue(value: number) {
if (!Number.isFinite(value)) {
return 0;
}
return Math.min(100, Math.max(0, Math.round(value)));
}
/**
* 平台通用进度条。
* 统一承接 progressbar 语义、platform-progress-track 壳和填充宽度计算。
*/
export function PlatformProgressBar({
value,
minVisibleValue = 0,
size = 'xs',
ariaLabel,
labelledBy,
indeterminate = false,
className,
fillClassName,
fillStyle,
trackStyle,
children,
}: PlatformProgressBarProps) {
const progress = clampProgressValue(value);
const visibleProgress =
progress <= 0 ? 0 : Math.max(minVisibleValue, progress);
return (
<div
role="progressbar"
aria-valuemin={0}
aria-valuemax={100}
aria-valuenow={indeterminate ? undefined : progress}
aria-label={ariaLabel}
aria-labelledby={labelledBy}
className={[
'platform-progress-track relative overflow-hidden rounded-full',
PLATFORM_PROGRESS_BAR_SIZE_CLASS[size],
className,
]
.filter(Boolean)
.join(' ')}
style={trackStyle}
>
<div
className={[
'h-full rounded-full transition-[width] duration-300',
fillClassName,
]
.filter(Boolean)
.join(' ')}
style={{
width: `${visibleProgress}%`,
...fillStyle,
}}
/>
{children}
</div>
);
}