From 2d24e22c64b471fde871687d121e695c73818630 Mon Sep 17 00:00:00 2001 From: SunayKulkarni Date: Tue, 19 May 2026 19:21:24 +0530 Subject: [PATCH 1/7] Fix incomplete homepage localization (chip labels + translations) --- apps/web/src/components/HomeHero.tsx | 5 +++-- apps/web/src/components/home-hero/chips.ts | 22 +++++++++++----------- apps/web/src/i18n/locales/zh-CN.ts | 2 +- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/apps/web/src/components/HomeHero.tsx b/apps/web/src/components/HomeHero.tsx index 8023d67b68..db5f265f7e 100644 --- a/apps/web/src/components/HomeHero.tsx +++ b/apps/web/src/components/HomeHero.tsx @@ -1511,6 +1511,7 @@ function TypeTabBar({ onPickChip, }: TypeTabBarProps) { const chips = useMemo(() => chipsForGroup('create'), []); + const t = useT(); return (
{chips.map((chip) => { @@ -1530,9 +1531,9 @@ function TypeTabBar({ onClick={() => onPickChip(chip)} disabled={pluginsLoading || isPending || pendingPluginId !== null} aria-selected={isActive} - title={chip.hint ?? chip.label} + title={chip.hint ?? t(chip.labelKey as any)} > - {chip.label} + {t(chip.labelKey as any)} ); })} diff --git a/apps/web/src/components/home-hero/chips.ts b/apps/web/src/components/home-hero/chips.ts index f847ab18bc..c4067c34b8 100644 --- a/apps/web/src/components/home-hero/chips.ts +++ b/apps/web/src/components/home-hero/chips.ts @@ -61,7 +61,7 @@ export type ChipGroup = 'create' | 'migrate'; export interface HomeHeroChip { id: string; - label: string; + labelKey: string; icon: IconName; group: ChipGroup; hint?: string; @@ -71,7 +71,7 @@ export interface HomeHeroChip { export const HOME_HERO_CHIPS: ReadonlyArray = [ { id: 'prototype', - label: 'Prototype', + labelKey: 'homeHero.chip.prototype', icon: 'palette', group: 'create', // Prototype now binds to the bundled `example-web-prototype` plugin, @@ -91,7 +91,7 @@ export const HOME_HERO_CHIPS: ReadonlyArray = [ }, { 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 @@ -112,7 +112,7 @@ export const HOME_HERO_CHIPS: ReadonlyArray = [ }, { id: 'image', - label: 'Image', + labelKey: 'homeHero.chip.image', icon: 'image', group: 'create', action: { @@ -129,7 +129,7 @@ export const HOME_HERO_CHIPS: ReadonlyArray = [ }, { id: 'video', - label: 'Video', + labelKey: 'homeHero.chip.video', icon: 'play', group: 'create', action: { @@ -146,7 +146,7 @@ export const HOME_HERO_CHIPS: ReadonlyArray = [ }, { id: 'hyperframes', - label: 'HyperFrames', + labelKey: 'homeHero.chip.hyperframes', icon: 'orbit', group: 'create', hint: 'Author HTML-based motion: captions, audio-reactive visuals, scene transitions.', @@ -158,7 +158,7 @@ export const HOME_HERO_CHIPS: ReadonlyArray = [ }, { id: 'audio', - label: 'Audio', + labelKey: 'homeHero.chip.audio', icon: 'mic', group: 'create', action: { @@ -175,7 +175,7 @@ export const HOME_HERO_CHIPS: ReadonlyArray = [ }, { id: 'create-plugin', - label: 'Create plugin', + labelKey: 'homeHero.chip.create-plugin', icon: 'edit', group: 'migrate', hint: 'Author a reusable Open Design plugin and add it to My plugins.', @@ -183,7 +183,7 @@ export const HOME_HERO_CHIPS: ReadonlyArray = [ }, { id: 'figma', - label: 'From Figma', + labelKey: 'homeHero.chip.figma', icon: 'import', group: 'migrate', hint: 'Migrate a Figma frame into the active design system.', @@ -199,7 +199,7 @@ export const HOME_HERO_CHIPS: ReadonlyArray = [ }, { id: 'folder', - label: 'From folder', + labelKey: 'homeHero.chip.folder', icon: 'folder', group: 'migrate', hint: 'Import an existing local folder and continue editing.', @@ -207,7 +207,7 @@ export const HOME_HERO_CHIPS: ReadonlyArray = [ }, { id: 'template', - label: 'From template', + labelKey: 'homeHero.chip.template', icon: 'file-code', group: 'migrate', hint: 'Start from a bundled template.', diff --git a/apps/web/src/i18n/locales/zh-CN.ts b/apps/web/src/i18n/locales/zh-CN.ts index b668eed3ae..9e2d29d68e 100644 --- a/apps/web/src/i18n/locales/zh-CN.ts +++ b/apps/web/src/i18n/locales/zh-CN.ts @@ -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}', From d25005cd5544f3b53cbad32708672c71e06c884b Mon Sep 17 00:00:00 2001 From: SunayKulkarni Date: Tue, 19 May 2026 20:02:55 +0530 Subject: [PATCH 2/7] Fix i18n key mismatch and remove unsafe cast; localize tooltips --- apps/web/src/components/HomeHero.tsx | 4 ++-- apps/web/src/components/home-hero/chips.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/web/src/components/HomeHero.tsx b/apps/web/src/components/HomeHero.tsx index db5f265f7e..0fe2519081 100644 --- a/apps/web/src/components/HomeHero.tsx +++ b/apps/web/src/components/HomeHero.tsx @@ -1531,9 +1531,9 @@ function TypeTabBar({ onClick={() => onPickChip(chip)} disabled={pluginsLoading || isPending || pendingPluginId !== null} aria-selected={isActive} - title={chip.hint ?? t(chip.labelKey as any)} + title={homeHeroChipTitle(chip, t)} > - {t(chip.labelKey as any)} + {t(chip.labelKey)} ); })} diff --git a/apps/web/src/components/home-hero/chips.ts b/apps/web/src/components/home-hero/chips.ts index c4067c34b8..3eada5ec5f 100644 --- a/apps/web/src/components/home-hero/chips.ts +++ b/apps/web/src/components/home-hero/chips.ts @@ -175,7 +175,7 @@ export const HOME_HERO_CHIPS: ReadonlyArray = [ }, { id: 'create-plugin', - labelKey: 'homeHero.chip.create-plugin', + labelKey: 'homeHero.chip.createPlugin', icon: 'edit', group: 'migrate', hint: 'Author a reusable Open Design plugin and add it to My plugins.', From 8ac09d31e3ebb9f3340828c45daa048394289161 Mon Sep 17 00:00:00 2001 From: SunayKulkarni Date: Tue, 19 May 2026 20:46:42 +0530 Subject: [PATCH 3/7] Enforce type-safe i18n keys for HomeHero chips --- apps/web/src/components/home-hero/chips.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/web/src/components/home-hero/chips.ts b/apps/web/src/components/home-hero/chips.ts index 3eada5ec5f..576520a277 100644 --- a/apps/web/src/components/home-hero/chips.ts +++ b/apps/web/src/components/home-hero/chips.ts @@ -22,6 +22,7 @@ import type { ProjectKind } from '@open-design/contracts'; import type { DefaultScenarioPluginId } from '@open-design/contracts'; import type { IconName } from '../Icon'; +import type { Dict } from '../../i18n/types'; // Plugin ids the chip rail can dispatch to. Most chips route to a // `DefaultScenarioPluginId` so the same fallback table the daemon @@ -61,7 +62,7 @@ export type ChipGroup = 'create' | 'migrate'; export interface HomeHeroChip { id: string; - labelKey: string; + labelKey: keyof Dict; icon: IconName; group: ChipGroup; hint?: string; From fa2f11dddaf8aeebb14004f36da5dc987be4cd07 Mon Sep 17 00:00:00 2001 From: SunayKulkarni Date: Tue, 19 May 2026 21:29:40 +0530 Subject: [PATCH 4/7] Remove unused labelKey for migrate chips to avoid duplicate i18n sources --- apps/web/src/components/home-hero/chips.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/apps/web/src/components/home-hero/chips.ts b/apps/web/src/components/home-hero/chips.ts index 576520a277..0cd206cacc 100644 --- a/apps/web/src/components/home-hero/chips.ts +++ b/apps/web/src/components/home-hero/chips.ts @@ -176,7 +176,6 @@ export const HOME_HERO_CHIPS: ReadonlyArray = [ }, { id: 'create-plugin', - labelKey: 'homeHero.chip.createPlugin', icon: 'edit', group: 'migrate', hint: 'Author a reusable Open Design plugin and add it to My plugins.', @@ -184,7 +183,6 @@ export const HOME_HERO_CHIPS: ReadonlyArray = [ }, { id: 'figma', - labelKey: 'homeHero.chip.figma', icon: 'import', group: 'migrate', hint: 'Migrate a Figma frame into the active design system.', @@ -200,7 +198,6 @@ export const HOME_HERO_CHIPS: ReadonlyArray = [ }, { id: 'folder', - labelKey: 'homeHero.chip.folder', icon: 'folder', group: 'migrate', hint: 'Import an existing local folder and continue editing.', @@ -208,7 +205,6 @@ export const HOME_HERO_CHIPS: ReadonlyArray = [ }, { id: 'template', - labelKey: 'homeHero.chip.template', icon: 'file-code', group: 'migrate', hint: 'Start from a bundled template.', From 7cb77c452f520fed00c60d3ee1252d1d45e986c7 Mon Sep 17 00:00:00 2001 From: SunayKulkarni Date: Tue, 19 May 2026 22:39:24 +0530 Subject: [PATCH 5/7] Restore labelKey for migrate chips to satisfy HomeHeroChip type --- apps/web/src/components/home-hero/chips.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/web/src/components/home-hero/chips.ts b/apps/web/src/components/home-hero/chips.ts index 0cd206cacc..576520a277 100644 --- a/apps/web/src/components/home-hero/chips.ts +++ b/apps/web/src/components/home-hero/chips.ts @@ -176,6 +176,7 @@ export const HOME_HERO_CHIPS: ReadonlyArray = [ }, { id: 'create-plugin', + labelKey: 'homeHero.chip.createPlugin', icon: 'edit', group: 'migrate', hint: 'Author a reusable Open Design plugin and add it to My plugins.', @@ -183,6 +184,7 @@ export const HOME_HERO_CHIPS: ReadonlyArray = [ }, { id: 'figma', + labelKey: 'homeHero.chip.figma', icon: 'import', group: 'migrate', hint: 'Migrate a Figma frame into the active design system.', @@ -198,6 +200,7 @@ export const HOME_HERO_CHIPS: ReadonlyArray = [ }, { id: 'folder', + labelKey: 'homeHero.chip.folder', icon: 'folder', group: 'migrate', hint: 'Import an existing local folder and continue editing.', @@ -205,6 +208,7 @@ export const HOME_HERO_CHIPS: ReadonlyArray = [ }, { id: 'template', + labelKey: 'homeHero.chip.template', icon: 'file-code', group: 'migrate', hint: 'Start from a bundled template.', From ca8bf06be796e2df3d0e523492f87bc42a3241be Mon Sep 17 00:00:00 2001 From: SunayKulkarni Date: Tue, 19 May 2026 23:24:24 +0530 Subject: [PATCH 6/7] Add zh-CN localization test for HomeHero rail labels and tooltips --- .../tests/components/HomeHero.rail.test.tsx | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/apps/web/tests/components/HomeHero.rail.test.tsx b/apps/web/tests/components/HomeHero.rail.test.tsx index 9d87c37e03..ed7c6b71e8 100644 --- a/apps/web/tests/components/HomeHero.rail.test.tsx +++ b/apps/web/tests/components/HomeHero.rail.test.tsx @@ -11,6 +11,7 @@ import { cleanup, fireEvent, render, screen } from '@testing-library/react'; import { afterEach, describe, expect, it, vi } from 'vitest'; +import { I18nProvider } from '../../src/i18n'; import { HomeHero } from '../../src/components/HomeHero'; import { HOME_HERO_CHIPS, @@ -135,4 +136,38 @@ describe('HomeHero intent rail', () => { }); expect(findChip('live-artifact')).toBeUndefined(); }); + + it('renders localized chip labels and tooltips in zh-CN', () => { + render( + + undefined} + onSubmit={() => undefined} + activePluginTitle={null} + activeChipId={null} + onClearActivePlugin={() => undefined} + pluginOptions={[]} + pluginsLoading={false} + pendingPluginId={null} + pendingChipId={null} + onPickPlugin={vi.fn()} + onPickChip={vi.fn()} + contextItemCount={0} + error={null} + /> + + ); + + // Prototype chip label should be zh-CN + const prototypeChip = screen.getByTestId('home-hero-rail-prototype'); + expect(prototypeChip.textContent).toContain('原型'); + + // HyperFrames tooltip should be the zh-CN string + const hyperframes = screen.getByTestId('home-hero-rail-hyperframes'); + expect(hyperframes.getAttribute('title')).toBe( + '创作基于 HTML 的动态内容:字幕、音频响应视觉和场景转场。' + ); +}); + }); From a6bfd6fb3850fcd1de617ac837d01fc80f73630f Mon Sep 17 00:00:00 2001 From: SunayKulkarni Date: Wed, 20 May 2026 00:38:10 +0530 Subject: [PATCH 7/7] Refactor HomeHeroChip into create/migrate union and fix type-safe rendering --- apps/web/src/components/HomeHero.tsx | 2 +- apps/web/src/components/home-hero/chips.ts | 19 ++++++++++++------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/apps/web/src/components/HomeHero.tsx b/apps/web/src/components/HomeHero.tsx index 0fe2519081..09a348c4d2 100644 --- a/apps/web/src/components/HomeHero.tsx +++ b/apps/web/src/components/HomeHero.tsx @@ -1533,7 +1533,7 @@ function TypeTabBar({ aria-selected={isActive} title={homeHeroChipTitle(chip, t)} > - {t(chip.labelKey)} + {chip.group === 'create' ? t(chip.labelKey) : homeHeroChipLabel(chip.id, t)} ); })} diff --git a/apps/web/src/components/home-hero/chips.ts b/apps/web/src/components/home-hero/chips.ts index 576520a277..c896cf9193 100644 --- a/apps/web/src/components/home-hero/chips.ts +++ b/apps/web/src/components/home-hero/chips.ts @@ -60,15 +60,24 @@ export type ChipAction = // narrow viewports without horizontal scrolling. export type ChipGroup = 'create' | 'migrate'; -export interface HomeHeroChip { +export interface CreateChip { id: string; labelKey: keyof Dict; icon: IconName; - group: ChipGroup; - hint?: string; + group: 'create'; action: ChipAction; } +export interface MigrateChip { + id: string; + icon: IconName; + group: 'migrate'; + hint: string; + action: ChipAction; +} + +export type HomeHeroChip = CreateChip | MigrateChip; + export const HOME_HERO_CHIPS: ReadonlyArray = [ { id: 'prototype', @@ -176,7 +185,6 @@ export const HOME_HERO_CHIPS: ReadonlyArray = [ }, { id: 'create-plugin', - labelKey: 'homeHero.chip.createPlugin', icon: 'edit', group: 'migrate', hint: 'Author a reusable Open Design plugin and add it to My plugins.', @@ -184,7 +192,6 @@ export const HOME_HERO_CHIPS: ReadonlyArray = [ }, { id: 'figma', - labelKey: 'homeHero.chip.figma', icon: 'import', group: 'migrate', hint: 'Migrate a Figma frame into the active design system.', @@ -200,7 +207,6 @@ export const HOME_HERO_CHIPS: ReadonlyArray = [ }, { id: 'folder', - labelKey: 'homeHero.chip.folder', icon: 'folder', group: 'migrate', hint: 'Import an existing local folder and continue editing.', @@ -208,7 +214,6 @@ export const HOME_HERO_CHIPS: ReadonlyArray = [ }, { id: 'template', - labelKey: 'homeHero.chip.template', icon: 'file-code', group: 'migrate', hint: 'Start from a bundled template.',