diff --git a/apps/web/src/components/HomeHero.tsx b/apps/web/src/components/HomeHero.tsx index 4159a5b5d..d08cfe844 100644 --- a/apps/web/src/components/HomeHero.tsx +++ b/apps/web/src/components/HomeHero.tsx @@ -2507,7 +2507,7 @@ function RailGroup({ const cls = isTabs ? ['home-hero__type-tab', `home-hero__type-tab--${group}`] : ['home-hero__rail-chip', `home-hero__rail-chip--${group}`]; - const label = homeHeroChipLabel(chip.id, t); + const label = homeHeroChipLabel(chip, t); if (isActive) cls.push('is-active'); if (isPending) cls.push('is-pending'); return ( @@ -2549,13 +2549,13 @@ function ActiveTypeChip({ chip, onClear }: { chip: HomeHeroChip; onClear: () => data-testid="home-hero-active-type-chip" data-chip-id={chip.id} title={homeHeroChipTitle(chip, t)} - aria-label={`${homeHeroChipLabel(chip.id, t)} ${t('common.delete')}`} + aria-label={`${homeHeroChipLabel(chip, t)} ${t('common.delete')}`} onClick={onClear} > - {homeHeroChipLabel(chip.id, t)} + {homeHeroChipLabel(chip, t)} ); @@ -2639,7 +2639,7 @@ function ShortcutsMenu({ onClick={() => onPickChip(chip)} > - {homeHeroChipLabel(chip.id, t)} + {homeHeroChipLabel(chip, t)} ); })} @@ -2649,31 +2649,12 @@ function ShortcutsMenu({ ); } -function homeHeroChipLabel(chipId: string, t: ReturnType): string { - switch (chipId) { - case 'prototype': return t('homeHero.chip.prototype'); - case 'live-artifact': return t('homeHero.chip.liveArtifact'); - case 'deck': return t('homeHero.chip.deck'); - case 'image': return t('homeHero.chip.image'); - case 'video': return t('homeHero.chip.video'); - case 'hyperframes': return t('homeHero.chip.hyperframes'); - case 'audio': return t('homeHero.chip.audio'); - case 'create-plugin': return t('homeHero.chip.createPlugin'); - case 'figma': return t('homeHero.chip.figma'); - case 'template': return t('homeHero.chip.template'); - default: return chipId; - } +function homeHeroChipLabel(chip: HomeHeroChip, t: ReturnType): string { + return t(chip.labelKey); } function homeHeroChipTitle(chip: HomeHeroChip, t: ReturnType): string { - switch (chip.id) { - case 'live-artifact': return t('homeHero.chip.liveArtifactHint'); - case 'hyperframes': return t('homeHero.chip.hyperframesHint'); - case 'create-plugin': return t('homeHero.chip.createPluginHint'); - case 'figma': return t('homeHero.chip.figmaHint'); - case 'template': return t('homeHero.chip.templateHint'); - default: return homeHeroChipLabel(chip.id, t); - } + return chip.hintKey ? t(chip.hintKey) : homeHeroChipLabel(chip, t); } function homeHeroExamplePluginsForChip( diff --git a/apps/web/tests/components/HomeHero.rail.test.tsx b/apps/web/tests/components/HomeHero.rail.test.tsx index 266c1ef4b..ec63c1122 100644 --- a/apps/web/tests/components/HomeHero.rail.test.tsx +++ b/apps/web/tests/components/HomeHero.rail.test.tsx @@ -18,6 +18,7 @@ import { HOME_HERO_CHIPS, findChip, } from '../../src/components/home-hero/chips'; +import { I18nProvider, type Locale } from '../../src/i18n'; afterEach(() => { cleanup(); @@ -68,31 +69,36 @@ function makePlugin( }; } -function renderHero(overrides: Partial> = {}) { +function renderHero( + overrides: Partial> = {}, + locale: Locale = 'en', +) { const onPickChip = vi.fn(); const onPickPlugin = vi.fn(); const onPickExamplePlugin = vi.fn(); const onClearActiveChip = vi.fn(); render( - undefined} - onSubmit={() => undefined} - activePluginTitle={null} - activeChipId={null} - onClearActivePlugin={() => undefined} - pluginOptions={[]} - pluginsLoading={false} - pendingPluginId={null} - pendingChipId={null} - onPickPlugin={onPickPlugin} - onPickExamplePlugin={onPickExamplePlugin} - onPickChip={onPickChip} - onClearActiveChip={onClearActiveChip} - contextItemCount={0} - error={null} - {...overrides} - />, + + undefined} + onSubmit={() => undefined} + activePluginTitle={null} + activeChipId={null} + onClearActivePlugin={() => undefined} + pluginOptions={[]} + pluginsLoading={false} + pendingPluginId={null} + pendingChipId={null} + onPickPlugin={onPickPlugin} + onPickExamplePlugin={onPickExamplePlugin} + onPickChip={onPickChip} + onClearActiveChip={onClearActiveChip} + contextItemCount={0} + error={null} + {...overrides} + /> + , ); return { onPickChip, onPickPlugin, onPickExamplePlugin, onClearActiveChip }; } @@ -406,6 +412,16 @@ describe('HomeHero intent rail', () => { } }); + it('localizes the folder shortcut label and hint in Simplified Chinese', () => { + renderHero({ activeChipId: 'folder' }, 'zh-CN'); + fireEvent.click(screen.getByTestId('home-hero-shortcuts-trigger')); + + const folder = screen.getByTestId('home-hero-rail-folder'); + expect(folder.textContent).toContain('来自文件夹'); + expect(folder.getAttribute('title')).toBe('导入本地文件夹并继续编辑。'); + expect(folder.className).toContain('is-active'); + }); + it('keeps the generic fallback in the free-form prompt instead of an Other chip', () => { renderHero();