mirror of
https://github.com/nexu-io/open-design.git
synced 2026-05-31 19:04:39 +07:00
Localize folder home shortcut
This commit is contained in:
parent
b738dc75a1
commit
068aca5574
2 changed files with 43 additions and 46 deletions
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue