refactor: unify guided workspace empty states

This commit is contained in:
lingniu
2026-07-19 12:49:22 +08:00
parent 4e4f383988
commit dffe559160
7 changed files with 367 additions and 14 deletions

View File

@@ -1,5 +1,5 @@
import { IconAlertTriangle, IconRefresh } from '@douyinfe/semi-icons';
import { Button, Empty, Spin, Typography } from '@douyinfe/semi-ui';
import { Button, Card, CardGroup, Empty, Spin, Typography } from '@douyinfe/semi-ui';
import type { ReactNode } from 'react';
type StateScope = 'page' | 'panel' | 'inline';
@@ -75,6 +75,51 @@ export function PanelEmpty({
return <StateSurface className={className} kind="empty" scope="panel" title={title} description={description} action={action} />;
}
export type WorkspaceEmptyGuideStep = {
title: string;
description: string;
icon?: ReactNode;
};
export function WorkspaceEmptyGuide({
title,
description,
steps,
icon,
eyebrow,
action,
secondaryAction,
className = ''
}: {
title: string;
description: string;
steps: WorkspaceEmptyGuideStep[];
icon?: ReactNode;
eyebrow?: string;
action?: ReactNode;
secondaryAction?: ReactNode;
className?: string;
}) {
const classes = ['v2-state-surface', 'is-empty', 'is-panel', 'v2-workspace-empty-guide', className].filter(Boolean).join(' ');
return <section className={classes} role="status" aria-live="polite">
{eyebrow ? <Typography.Text className="v2-workspace-empty-guide-eyebrow" type="tertiary">{eyebrow}</Typography.Text> : null}
<Empty
className="v2-workspace-empty-guide-message"
image={icon ? <span className="v2-workspace-empty-guide-icon">{icon}</span> : undefined}
title={title}
description={description}
/>
<CardGroup className="v2-workspace-empty-guide-steps" type="grid" spacing={0}>
{steps.map((step, index) => <Card key={`${step.title}-${index}`} className="v2-workspace-empty-guide-step" bodyStyle={{ padding: 0 }}>
<span className="v2-workspace-empty-guide-step-index">{step.icon ?? index + 1}</span>
<span><Typography.Text strong>{step.title}</Typography.Text><Typography.Text type="tertiary" size="small">{step.description}</Typography.Text></span>
</Card>)}
</CardGroup>
{action || secondaryAction ? <div className="v2-workspace-empty-guide-actions">{action}{secondaryAction}</div> : null}
</section>;
}
export function InlineError({ message, onRetry }: { message: string; onRetry?: () => void }) {
return <StateSurface
className="v2-inline-state"