收口前端平台组件库能力
新增 PlatformUiKit 通用弹窗、按钮、状态、空态、媒体、表单和标签等公共组件 迁移结果页、创作工作台、认证入口、RPG 暗色面板和运行态弹窗的重复 UI chrome 补充组件测试、页面回归测试、技术文档和 Hermes 共享决策记录
This commit is contained in:
126
src/components/common/PlatformMediaTileGrid.tsx
Normal file
126
src/components/common/PlatformMediaTileGrid.tsx
Normal file
@@ -0,0 +1,126 @@
|
||||
import type { ReactNode } from 'react';
|
||||
|
||||
import { PlatformMediaFrame } from './PlatformMediaFrame';
|
||||
|
||||
type PlatformMediaTileGridColumns = 'five' | 'six';
|
||||
type PlatformMediaTileGridGap = 'xs' | 'sm';
|
||||
type PlatformMediaTileGridAspect = 'auto' | 'square';
|
||||
type PlatformMediaTileSurface = 'white' | 'slate' | 'bare';
|
||||
type PlatformMediaTileGridSurface = 'none' | 'soft';
|
||||
|
||||
export type PlatformMediaTileGridItem = {
|
||||
id: string;
|
||||
src?: string | null;
|
||||
alt?: string;
|
||||
refreshKey?: string | number | null;
|
||||
fallbackLabel?: string;
|
||||
fallbackContent?: ReactNode;
|
||||
testId?: string;
|
||||
className?: string;
|
||||
imageClassName?: string;
|
||||
fallbackClassName?: string;
|
||||
};
|
||||
|
||||
type PlatformMediaTileGridProps = {
|
||||
items: PlatformMediaTileGridItem[];
|
||||
columns?: PlatformMediaTileGridColumns;
|
||||
gap?: PlatformMediaTileGridGap;
|
||||
aspect?: PlatformMediaTileGridAspect;
|
||||
surface?: PlatformMediaTileGridSurface;
|
||||
tileSurface?: PlatformMediaTileSurface;
|
||||
fallbackLabel?: string;
|
||||
imageClassName?: string;
|
||||
fallbackClassName?: string;
|
||||
className?: string;
|
||||
tileClassName?: string;
|
||||
};
|
||||
|
||||
const PLATFORM_MEDIA_TILE_GRID_COLUMNS_CLASS: Record<
|
||||
PlatformMediaTileGridColumns,
|
||||
string
|
||||
> = {
|
||||
five: 'grid-cols-5',
|
||||
six: 'grid-cols-6',
|
||||
};
|
||||
|
||||
const PLATFORM_MEDIA_TILE_GRID_GAP_CLASS: Record<
|
||||
PlatformMediaTileGridGap,
|
||||
string
|
||||
> = {
|
||||
sm: 'gap-1.5',
|
||||
xs: 'gap-1',
|
||||
};
|
||||
|
||||
const PLATFORM_MEDIA_TILE_GRID_SURFACE_CLASS: Record<
|
||||
PlatformMediaTileGridSurface,
|
||||
string
|
||||
> = {
|
||||
none: '',
|
||||
soft: 'bg-white/78 p-2',
|
||||
};
|
||||
|
||||
const PLATFORM_MEDIA_TILE_SURFACE_CLASS: Record<
|
||||
PlatformMediaTileSurface,
|
||||
string
|
||||
> = {
|
||||
bare: 'border border-white/80',
|
||||
slate: 'border border-white/80 bg-slate-50',
|
||||
white: 'border border-white/80 bg-white shadow-sm',
|
||||
};
|
||||
|
||||
/**
|
||||
* 平台媒体缩略格网格。
|
||||
* 统一承接结果页里同尺寸素材 tile 的网格、圆角、边框和图片/fallback 框。
|
||||
*/
|
||||
export function PlatformMediaTileGrid({
|
||||
items,
|
||||
columns = 'six',
|
||||
gap = 'sm',
|
||||
aspect = 'auto',
|
||||
surface = 'none',
|
||||
tileSurface = 'white',
|
||||
fallbackLabel = '素材',
|
||||
imageClassName = 'h-full w-full object-cover',
|
||||
fallbackClassName = 'tracking-normal text-[var(--platform-text-soft)]',
|
||||
className,
|
||||
tileClassName,
|
||||
}: PlatformMediaTileGridProps) {
|
||||
return (
|
||||
<div
|
||||
className={[
|
||||
'platform-media-tile-grid grid',
|
||||
PLATFORM_MEDIA_TILE_GRID_COLUMNS_CLASS[columns],
|
||||
PLATFORM_MEDIA_TILE_GRID_GAP_CLASS[gap],
|
||||
PLATFORM_MEDIA_TILE_GRID_SURFACE_CLASS[surface],
|
||||
aspect === 'square' ? 'aspect-[1/1]' : '',
|
||||
className,
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(' ')}
|
||||
>
|
||||
{items.map((item) => (
|
||||
<PlatformMediaFrame
|
||||
key={item.id}
|
||||
src={item.src}
|
||||
alt={item.alt ?? ''}
|
||||
refreshKey={item.refreshKey}
|
||||
fallbackLabel={item.fallbackLabel ?? fallbackLabel}
|
||||
fallbackContent={item.fallbackContent}
|
||||
aspect="square"
|
||||
surface="none"
|
||||
data-testid={item.testId}
|
||||
imageClassName={item.imageClassName ?? imageClassName}
|
||||
fallbackClassName={item.fallbackClassName ?? fallbackClassName}
|
||||
className={[
|
||||
'platform-media-tile-grid__item min-h-0 rounded-[0.45rem]',
|
||||
PLATFORM_MEDIA_TILE_SURFACE_CLASS[tileSurface],
|
||||
tileClassName,
|
||||
item.className,
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(' ')}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user