Localize folder home shortcut

This commit is contained in:
逸尘 2026-05-23 10:02:10 +08:00
parent b738dc75a1
commit 068aca5574
2 changed files with 43 additions and 46 deletions

View file

@ -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}
>
<span className="home-hero__active-type-chip-icon" aria-hidden>
<Icon name={chip.icon} size={13} />
</span>
<span>{homeHeroChipLabel(chip.id, t)}</span>
<span>{homeHeroChipLabel(chip, t)}</span>
<Icon name="close" size={12} className="home-hero__active-type-chip-close" />
</button>
);
@ -2639,7 +2639,7 @@ function ShortcutsMenu({
onClick={() => onPickChip(chip)}
>
<Icon name={chip.icon} size={14} className="home-hero__shortcut-menu-icon" />
<span>{homeHeroChipLabel(chip.id, t)}</span>
<span>{homeHeroChipLabel(chip, t)}</span>
</button>
);
})}
@ -2649,31 +2649,12 @@ function ShortcutsMenu({
);
}
function homeHeroChipLabel(chipId: string, t: ReturnType<typeof useT>): 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<typeof useT>): string {
return t(chip.labelKey);
}
function homeHeroChipTitle(chip: HomeHeroChip, t: ReturnType<typeof useT>): 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(

View file

@ -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<React.ComponentProps<typeof HomeHero>> = {}) {
function renderHero(
overrides: Partial<React.ComponentProps<typeof HomeHero>> = {},
locale: Locale = 'en',
) {
const onPickChip = vi.fn();
const onPickPlugin = vi.fn();
const onPickExamplePlugin = vi.fn();
const onClearActiveChip = vi.fn();
render(
<HomeHero
prompt=""
onPromptChange={() => 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}
/>,
<I18nProvider initial={locale}>
<HomeHero
prompt=""
onPromptChange={() => 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}
/>
</I18nProvider>,
);
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();