收口前端平台组件能力
新增 PlatformAsyncStatePanel 统一 profile 异步状态骨架 扩展 PlatformSegmentedTabs 支持滚动 tab 并接入创作入口与发现页 统一 PixelCloseButton 复用 PlatformModalCloseButton 像素关闭能力 抽取平台入口泥点前置提示弹层并收紧阻断语义 补充组件收口文档与共享决策记录
This commit is contained in:
@@ -5,6 +5,7 @@ import type {
|
||||
CreationEntryConfig,
|
||||
CreationEntryEventBannerConfig,
|
||||
} from '../../services/creationEntryConfigService';
|
||||
import { PlatformSegmentedTabs } from '../common/PlatformSegmentedTabs';
|
||||
import {
|
||||
groupVisiblePlatformCreationTypes,
|
||||
type PlatformCreationTypeCard,
|
||||
@@ -111,6 +112,23 @@ export function CustomWorldCreationStartCard({
|
||||
const visibleCreationTypes = isRecentTabActive
|
||||
? recentCreationTypes
|
||||
: (activeGroup?.items ?? []);
|
||||
const categoryTabs = useMemo(
|
||||
() => [
|
||||
...(hasRecentCreationTypes
|
||||
? [
|
||||
{
|
||||
id: CREATION_ENTRY_RECENT_TAB_ID,
|
||||
label: '最近创作',
|
||||
},
|
||||
]
|
||||
: []),
|
||||
...creationTypeGroups.map((group) => ({
|
||||
id: group.id,
|
||||
label: group.label,
|
||||
})),
|
||||
],
|
||||
[creationTypeGroups, hasRecentCreationTypes],
|
||||
);
|
||||
const eventBanners = useMemo(
|
||||
() => resolveCreationEntryEventBanners(entryConfig),
|
||||
[entryConfig],
|
||||
@@ -262,52 +280,28 @@ export function CustomWorldCreationStartCard({
|
||||
</section>
|
||||
|
||||
<section className="creation-template-list -mx-1 px-1 sm:-mx-2 sm:px-2">
|
||||
<div
|
||||
className="-mx-0.5 flex snap-x items-center gap-2 overflow-x-auto px-0.5 pb-1 scrollbar-hide scroll-px-2 sm:gap-3"
|
||||
role="tablist"
|
||||
aria-label="创作入口页签"
|
||||
>
|
||||
{hasRecentCreationTypes ? (
|
||||
<button
|
||||
type="button"
|
||||
role="tab"
|
||||
aria-selected={isRecentTabActive}
|
||||
onClick={() => setActiveCategoryId(CREATION_ENTRY_RECENT_TAB_ID)}
|
||||
className={`relative min-h-8 shrink-0 rounded-full px-2.5 text-xs font-black transition sm:min-h-9 sm:px-3.5 sm:text-sm ${
|
||||
isRecentTabActive
|
||||
? 'text-[#6f2f21]'
|
||||
: 'text-[#7a6558] hover:text-[#6f2f21]'
|
||||
}`}
|
||||
>
|
||||
<span>最近创作</span>
|
||||
{isRecentTabActive ? (
|
||||
<span className="absolute bottom-0 left-3 right-3 h-1 rounded-full bg-[#d9793f]" />
|
||||
) : null}
|
||||
</button>
|
||||
) : null}
|
||||
{creationTypeGroups.map((group) => {
|
||||
const selected = group.id === activeGroup?.id;
|
||||
return (
|
||||
<button
|
||||
key={group.id}
|
||||
type="button"
|
||||
role="tab"
|
||||
aria-selected={selected}
|
||||
onClick={() => setActiveCategoryId(group.id)}
|
||||
className={`relative min-h-8 shrink-0 rounded-full px-2.5 text-xs font-black transition sm:min-h-9 sm:px-3.5 sm:text-sm ${
|
||||
selected
|
||||
? 'text-[#6f2f21]'
|
||||
: 'text-[#7a6558] hover:text-[#6f2f21]'
|
||||
}`}
|
||||
>
|
||||
<span>{group.label}</span>
|
||||
{selected ? (
|
||||
<span className="absolute bottom-0 left-3 right-3 h-1 rounded-full bg-[#d9793f]" />
|
||||
) : null}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<PlatformSegmentedTabs
|
||||
items={categoryTabs}
|
||||
activeId={activeTabId ?? ''}
|
||||
onChange={setActiveCategoryId}
|
||||
layout="scroll"
|
||||
gap="md"
|
||||
frame="bare"
|
||||
surface="transparent"
|
||||
size="sm"
|
||||
tone="neutral"
|
||||
semantics="tabs"
|
||||
ariaLabel="创作入口页签"
|
||||
className="-mx-0.5 snap-x px-0.5 pb-1 scroll-px-2 sm:!gap-3"
|
||||
itemClassName={(_, active) =>
|
||||
[
|
||||
"relative shrink-0 snap-start !min-h-8 !rounded-full !border-0 !bg-transparent !px-2.5 !text-xs !font-black !shadow-none sm:!min-h-9 sm:!px-3.5 sm:!text-sm",
|
||||
active
|
||||
? "!text-[#6f2f21] after:absolute after:bottom-0 after:left-3 after:right-3 after:h-1 after:rounded-full after:bg-[#d9793f] after:content-['']"
|
||||
: '!text-[#7a6558] hover:!bg-transparent hover:!text-[#6f2f21]',
|
||||
].join(' ')
|
||||
}
|
||||
/>
|
||||
|
||||
{isRecentTabActive ? (
|
||||
<div className="creation-template-list__recent-window mt-2 text-[11px] font-bold leading-4 text-[#8b6654] sm:text-xs">
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { PlatformSegmentedTabs } from '../common/PlatformSegmentedTabs';
|
||||
|
||||
export type CustomWorldWorkFilter = 'all' | 'draft' | 'published';
|
||||
|
||||
const FILTER_OPTIONS: Array<{
|
||||
@@ -22,33 +24,42 @@ export function CustomWorldWorkTabs({
|
||||
publishedCount,
|
||||
onChange,
|
||||
}: CustomWorldWorkTabsProps) {
|
||||
return (
|
||||
<div
|
||||
className="flex min-w-0 items-center gap-4 overflow-x-auto pb-1 scrollbar-hide xl:pb-0"
|
||||
role="tablist"
|
||||
aria-label="作品筛选"
|
||||
>
|
||||
{FILTER_OPTIONS.map((option) => {
|
||||
const count =
|
||||
option.id === 'draft'
|
||||
? draftCount
|
||||
: option.id === 'published'
|
||||
? publishedCount
|
||||
: draftCount + publishedCount;
|
||||
const filterTabs = FILTER_OPTIONS.map((option) => {
|
||||
const count =
|
||||
option.id === 'draft'
|
||||
? draftCount
|
||||
: option.id === 'published'
|
||||
? publishedCount
|
||||
: draftCount + publishedCount;
|
||||
|
||||
return (
|
||||
<button
|
||||
key={option.id}
|
||||
type="button"
|
||||
role="tab"
|
||||
aria-selected={activeFilter === option.id}
|
||||
onClick={() => onChange(option.id)}
|
||||
className={`platform-mobile-home-channel shrink-0 ${activeFilter === option.id ? 'platform-mobile-home-channel--active' : ''}`}
|
||||
>
|
||||
{option.label} {count}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
return {
|
||||
id: option.id,
|
||||
label: `${option.label} ${count}`,
|
||||
};
|
||||
});
|
||||
|
||||
return (
|
||||
<PlatformSegmentedTabs
|
||||
items={filterTabs}
|
||||
activeId={activeFilter}
|
||||
onChange={onChange}
|
||||
layout="scroll"
|
||||
gap="md"
|
||||
frame="bare"
|
||||
surface="transparent"
|
||||
size="sm"
|
||||
tone="neutral"
|
||||
semantics="tabs"
|
||||
ariaLabel="作品筛选"
|
||||
className="pb-1 !gap-4 xl:pb-0"
|
||||
itemClassName={(_, active) =>
|
||||
[
|
||||
'platform-mobile-home-channel shrink-0 !min-h-8 !rounded-none !border-0 !bg-transparent !px-0 !shadow-none hover:!bg-transparent',
|
||||
active ? 'platform-mobile-home-channel--active' : null,
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(' ')
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user