收口前端平台组件库能力
新增 PlatformUiKit 通用弹窗、按钮、状态、空态、媒体、表单和标签等公共组件 迁移结果页、创作工作台、认证入口、RPG 暗色面板和运行态弹窗的重复 UI chrome 补充组件测试、页面回归测试、技术文档和 Hermes 共享决策记录
This commit is contained in:
90
src/components/common/PlatformProgressBar.tsx
Normal file
90
src/components/common/PlatformProgressBar.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user