新增 PlatformNavigableListItem 统一 desktop flat row 的交互骨架 接入首页搜索结果与桌面最近作品最近浏览入口 补充组件测试首页回归测试并更新收口计划和共享决策记录
89 lines
2.0 KiB
TypeScript
89 lines
2.0 KiB
TypeScript
import type { ComponentPropsWithoutRef, ReactNode } from 'react';
|
||
|
||
type PlatformNavigableListItemAlign = 'center' | 'start';
|
||
|
||
type PlatformNavigableListItemProps = Omit<
|
||
ComponentPropsWithoutRef<'button'>,
|
||
'children' | 'type'
|
||
> & {
|
||
children: ReactNode;
|
||
leading?: ReactNode;
|
||
trailing?: ReactNode;
|
||
align?: PlatformNavigableListItemAlign;
|
||
leadingClassName?: string;
|
||
trailingClassName?: string;
|
||
bodyClassName?: string;
|
||
};
|
||
|
||
const ALIGN_CLASS: Record<PlatformNavigableListItemAlign, string> = {
|
||
center: 'items-center gap-3',
|
||
start: 'items-start gap-4',
|
||
};
|
||
|
||
/**
|
||
* 轻量可导航列表行骨架。
|
||
* 只统一 button 语义与 left-content/right-affordance 结构,不持有业务文案、badge 或封面规则。
|
||
*/
|
||
export function PlatformNavigableListItem({
|
||
children,
|
||
leading = null,
|
||
trailing = null,
|
||
align = 'center',
|
||
className,
|
||
leadingClassName,
|
||
trailingClassName,
|
||
bodyClassName,
|
||
...props
|
||
}: PlatformNavigableListItemProps) {
|
||
return (
|
||
<button
|
||
type="button"
|
||
className={[
|
||
'platform-navigable-list-item flex w-full min-w-0 text-left',
|
||
ALIGN_CLASS[align],
|
||
className ?? null,
|
||
]
|
||
.filter(Boolean)
|
||
.join(' ')}
|
||
{...props}
|
||
>
|
||
{leading ? (
|
||
<div
|
||
className={[
|
||
'platform-navigable-list-item__leading shrink-0',
|
||
leadingClassName ?? null,
|
||
]
|
||
.filter(Boolean)
|
||
.join(' ')}
|
||
>
|
||
{leading}
|
||
</div>
|
||
) : null}
|
||
|
||
<div
|
||
className={[
|
||
'platform-navigable-list-item__body min-w-0 flex-1',
|
||
bodyClassName ?? null,
|
||
]
|
||
.filter(Boolean)
|
||
.join(' ')}
|
||
>
|
||
{children}
|
||
</div>
|
||
|
||
{trailing ? (
|
||
<div
|
||
className={[
|
||
'platform-navigable-list-item__trailing shrink-0',
|
||
trailingClassName ?? null,
|
||
]
|
||
.filter(Boolean)
|
||
.join(' ')}
|
||
>
|
||
{trailing}
|
||
</div>
|
||
) : null}
|
||
</button>
|
||
);
|
||
}
|