Skip to content
5 changes: 3 additions & 2 deletions apps/web/src/components/HomeHero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1511,6 +1511,7 @@ function TypeTabBar({
onPickChip,
}: TypeTabBarProps) {
const chips = useMemo(() => chipsForGroup('create'), []);
const t = useT();
return (
<div className="home-hero__type-tabs" role="tablist" aria-label="Output type">
{chips.map((chip) => {
Expand All @@ -1530,9 +1531,9 @@ function TypeTabBar({
onClick={() => onPickChip(chip)}
disabled={pluginsLoading || isPending || pendingPluginId !== null}
aria-selected={isActive}
title={chip.hint ?? chip.label}
title={homeHeroChipTitle(chip, t)}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

apps/web/src/components/HomeHero.tsx:1534-1536 adds the localized label/title path, but there still is no regression test covering that zh-CN behavior. apps/web/tests/components/HomeHero.rail.test.tsx currently only checks that each chip renders, routes clicks, and toggles state; it never asserts translated text or tooltips, so the earlier labelKey typo and English HyperFrames tooltip both would have passed the suite. Because this PR's goal is to eliminate mixed-language homepage UI, please extend that rail test to render under zh-CN and assert at least one translated create-chip label plus the localized HyperFrames tooltip.

🔁 Powered by Looper · runner=reviewer · agent=opencode · An autonomous AI dev team for your GitHub repos.

>
<span>{chip.label}</span>
<span>{t(chip.labelKey)}</span>
</button>
);
})}
Expand Down
22 changes: 11 additions & 11 deletions apps/web/src/components/home-hero/chips.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export type ChipGroup = 'create' | 'migrate';

export interface HomeHeroChip {
id: string;
label: string;
labelKey: string;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

labelKey is still widened to plain string, so this follow-up does not actually restore compile-time protection for chip translation keys. useT() only accepts keyof Dict in apps/web/src/i18n/index.tsx, but this metadata shape now allows any arbitrary string, which is how the earlier homeHero.chip.create-plugin typo slipped in unnoticed until runtime. That matters because future chip additions can reintroduce missing-translation regressions even though this PR moved the UI over to labelKey. Please type this field as a real i18n key (for example keyof Dict, or a narrower HomeHeroChipLabelKey union derived from Dict) and import that type here so bad keys fail during development instead of shipping to users.

🔁 Powered by Looper · runner=reviewer · agent=opencode · An autonomous AI dev team for your GitHub repos.

icon: IconName;
group: ChipGroup;
hint?: string;
Expand All @@ -71,7 +71,7 @@ export interface HomeHeroChip {
export const HOME_HERO_CHIPS: ReadonlyArray<HomeHeroChip> = [
{
id: 'prototype',
label: 'Prototype',
labelKey: 'homeHero.chip.prototype',
icon: 'palette',
group: 'create',
// Prototype now binds to the bundled `example-web-prototype` plugin,
Expand All @@ -91,7 +91,7 @@ export const HOME_HERO_CHIPS: ReadonlyArray<HomeHeroChip> = [
},
{
id: 'deck',
label: 'Slide deck',
labelKey: 'homeHero.chip.deck',
icon: 'present',
group: 'create',
// Slide deck binds to `example-simple-deck`, which ships a 353-line
Expand All @@ -112,7 +112,7 @@ export const HOME_HERO_CHIPS: ReadonlyArray<HomeHeroChip> = [
},
{
id: 'image',
label: 'Image',
labelKey: 'homeHero.chip.image',
icon: 'image',
group: 'create',
action: {
Expand All @@ -129,7 +129,7 @@ export const HOME_HERO_CHIPS: ReadonlyArray<HomeHeroChip> = [
},
{
id: 'video',
label: 'Video',
labelKey: 'homeHero.chip.video',
icon: 'play',
group: 'create',
action: {
Expand All @@ -146,7 +146,7 @@ export const HOME_HERO_CHIPS: ReadonlyArray<HomeHeroChip> = [
},
{
id: 'hyperframes',
label: 'HyperFrames',
labelKey: 'homeHero.chip.hyperframes',
icon: 'orbit',
group: 'create',
hint: 'Author HTML-based motion: captions, audio-reactive visuals, scene transitions.',
Expand All @@ -158,7 +158,7 @@ export const HOME_HERO_CHIPS: ReadonlyArray<HomeHeroChip> = [
},
{
id: 'audio',
label: 'Audio',
labelKey: 'homeHero.chip.audio',
icon: 'mic',
group: 'create',
action: {
Expand All @@ -175,15 +175,15 @@ export const HOME_HERO_CHIPS: ReadonlyArray<HomeHeroChip> = [
},
{
id: 'create-plugin',
label: 'Create plugin',
labelKey: 'homeHero.chip.createPlugin',
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

labelKey is type-safe now, but the migrate-chip metadata you changed here still is not the source of truth for what the homepage renders. RailGroup still reads homeHeroChipLabel(chip.id, t) in apps/web/src/components/HomeHero.tsx:1587, and homeHeroChipTitle() still switches on chip.id for these same create-plugin / figma / folder / template entries at apps/web/src/components/HomeHero.tsx:1616-1619. That matters because a future homepage i18n edit can update HOME_HERO_CHIPS and assume the UI changed, while the rendered label/tooltip keeps coming from the separate switch tables. Please either derive both label and tooltip from the chip metadata (for example labelKey plus a typed hintKey) or split the chip model so migrate chips do not carry localized fields that the renderer ignores.

🔁 Powered by Looper · runner=reviewer · agent=opencode · An autonomous AI dev team for your GitHub repos.

icon: 'edit',
group: 'migrate',
hint: 'Author a reusable Open Design plugin and add it to My plugins.',
action: { kind: 'create-plugin' },
},
{
id: 'figma',
label: 'From Figma',
labelKey: 'homeHero.chip.figma',
icon: 'import',
group: 'migrate',
hint: 'Migrate a Figma frame into the active design system.',
Expand All @@ -199,15 +199,15 @@ export const HOME_HERO_CHIPS: ReadonlyArray<HomeHeroChip> = [
},
{
id: 'folder',
label: 'From folder',
labelKey: 'homeHero.chip.folder',
icon: 'folder',
group: 'migrate',
hint: 'Import an existing local folder and continue editing.',
action: { kind: 'import-folder' },
},
{
id: 'template',
label: 'From template',
labelKey: 'homeHero.chip.template',
icon: 'file-code',
group: 'migrate',
hint: 'Start from a bundled template.',
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/i18n/locales/zh-CN.ts
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ export const zhCN: Dict = {
'recentProjects.title': '最近项目',
'recentProjects.viewAll': '查看全部',
'recentProjects.empty': '还没有项目 — 输入 Prompt 即可开始。',
'pluginsHome.title': '官方 starter',
'pluginsHome.title': '官方入门',
'pluginsHome.subtitle': '当前运行环境内置的 Open Design 工作流。选择一个加载 starter prompt,或浏览插件市场查看更多。',
'pluginsHome.browseRegistry': '浏览插件市场',
'pluginsHome.count': '{filtered} / {total}',
Expand Down