feat(web): add preview badge to empty hero
This commit is contained in:
@@ -20,7 +20,7 @@
|
||||
- button "Settings":
|
||||
- img
|
||||
- text: Settings
|
||||
- text: Let's start building
|
||||
- text: Let's start building Preview
|
||||
- button "Choose workspace":
|
||||
- img
|
||||
- text: workspace
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
- button "Settings":
|
||||
- img
|
||||
- text: Settings
|
||||
- text: Let's start building
|
||||
- text: Let's start building Preview
|
||||
- button "Choose workspace":
|
||||
- img
|
||||
- text: workspace
|
||||
|
||||
@@ -33,6 +33,7 @@ export const zh = {
|
||||
'access.confirm.cancel': '取消',
|
||||
'access.confirm.enable': '启用 Full access',
|
||||
'hero.headline': '开始构建吧',
|
||||
'hero.preview': '预览版',
|
||||
'hero.chooseWorkspace': '选择工作区',
|
||||
'session.hierarchy': '会话层级',
|
||||
'details.title': '详情',
|
||||
@@ -144,6 +145,7 @@ export const en = {
|
||||
'access.confirm.cancel': 'Cancel',
|
||||
'access.confirm.enable': 'Enable Full access',
|
||||
'hero.headline': 'Let\'s start building',
|
||||
'hero.preview': 'Preview',
|
||||
'hero.chooseWorkspace': 'Choose workspace',
|
||||
'session.hierarchy': 'Session hierarchy',
|
||||
'details.title': 'Details',
|
||||
|
||||
@@ -119,7 +119,8 @@ export function HeroShell({ t, children }: HeroShellProps) {
|
||||
<div className={css.headline}>
|
||||
{/* figma 34:10412: fish 34×25 leading the headline, gap 10. */}
|
||||
<FishLogo size={34} className={css.fish} />
|
||||
{t('hero.headline')}
|
||||
<span className={css.headlineText}>{t('hero.headline')}</span>
|
||||
<span className={css.previewBadge}>{t('hero.preview')}</span>
|
||||
</div>
|
||||
<div className={css.body}>
|
||||
{/* The resident composer (ConversationRoot wrapActiveBody seat; the
|
||||
|
||||
@@ -23,21 +23,44 @@
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
/* figma 34:10411: fish + title, gap 10, centered; 26/32 wt500. */
|
||||
/* Fish + title stay centered as one unit; the preview badge aligns with the
|
||||
title's leading edge on the second row. */
|
||||
.headline {
|
||||
display: flex;
|
||||
display: grid;
|
||||
grid-template-columns: 34px auto;
|
||||
column-gap: 10px;
|
||||
row-gap: 4px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
font-size: 26px;
|
||||
line-height: 32px;
|
||||
font-weight: 500;
|
||||
color: var(--dsw-alias-label-primary);
|
||||
}
|
||||
|
||||
.headlineText {
|
||||
grid-row: 1;
|
||||
grid-column: 2;
|
||||
}
|
||||
|
||||
.previewBadge {
|
||||
grid-row: 2;
|
||||
grid-column: 2;
|
||||
justify-self: start;
|
||||
padding: 0 4px;
|
||||
border-radius: 4px;
|
||||
background: var(--dsw-alias-state-business-tertiary);
|
||||
color: var(--dsw-alias-state-business-primary);
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* figma fish fill rides business blue. */
|
||||
.fish {
|
||||
flex: none;
|
||||
grid-row: 1;
|
||||
grid-column: 1;
|
||||
color: var(--dsw-alias-state-business-primary);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,12 +12,14 @@ import type {
|
||||
import type { ConversationRootProps } from '../src/client/skeleton/ConversationRoot.tsx'
|
||||
import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'
|
||||
import { makeTranslate } from '@deepseek-ai/dsh-client-test-runtime'
|
||||
import { en as commonEn } from '@deepseek-ai/dsh-client-locale/src/locales/en.ts'
|
||||
import { zh as commonZh } from '@deepseek-ai/dsh-client-locale/src/locales/zh.ts'
|
||||
import { createChatStore } from '../src/client/stores.ts'
|
||||
import { SessionInputShell } from '../src/client/input/facade.ts'
|
||||
import { zh } from '../src/client/locales.ts'
|
||||
import { en, zh } from '../src/client/locales.ts'
|
||||
import { ConversationRoot } from '../src/client/skeleton/ConversationRoot.tsx'
|
||||
import { ConversationSession } from '../src/client/skeleton/ConversationSession.tsx'
|
||||
import { HeroShell } from '../src/client/skeleton/EmptyHero.tsx'
|
||||
import { InputBar } from '../src/client/skeleton/InputBar.tsx'
|
||||
import type { InputBarProps } from '../src/client/skeleton/InputBar.tsx'
|
||||
import type {
|
||||
@@ -214,6 +216,12 @@ function mount(
|
||||
}
|
||||
|
||||
describe('ConversationRoot resident composer', () => {
|
||||
it('renders the English preview badge through the hero locale seat', () => {
|
||||
const view = render(<HeroShell t={makeTranslate(en, commonEn)} />)
|
||||
expect(view.getByText('Let\'s start building')).toBeTruthy()
|
||||
expect(view.getByText('Preview')).toBeTruthy()
|
||||
})
|
||||
|
||||
it('keeps composer text in the machine, mirrors to the chat store, and submits through the sink', () => {
|
||||
const b = mount(conversationSnapshot())
|
||||
const box = b.view.getByRole('textbox')
|
||||
@@ -273,6 +281,7 @@ describe('ConversationRoot resident composer', () => {
|
||||
expect(host).not.toBeNull()
|
||||
expect(header?.getAttribute('aria-hidden')).toBe('true')
|
||||
expect(b.view.getByText('开始构建吧')).toBeTruthy()
|
||||
expect(b.view.getByText('预览版')).toBeTruthy()
|
||||
expect(b.view.queryByTestId('view-chat')).toBeNull()
|
||||
// The same machine-backed textarea is live in the hero, and the
|
||||
// persistence mirror stays bound (ConversationSession mounts chrome-hidden
|
||||
|
||||
Reference in New Issue
Block a user