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();