Skip to content

fix(language-select): hide raw language code from translate selector trigger - #21993

Merged
DeJeune merged 2 commits into
CherryHQ:mainfrom
zzx04-cool:fix/21967-language-select-trigger-label
Oct 19, 2026
Merged

DeJeune merged 2 commits into
CherryHQ:mainfrom
zzx04-cool:fix/21967-language-select-trigger-label

Conversation

@zzx04-cool

Copy link
Copy Markdown
Contributor

What this PR does

Before this PR:

  • The translate target-language selector (LanguageSelect with searchPlacement="trigger") showed the raw language code in front of the flag and localized name while closed, e.g. zh-cn 🇨🇳 简体中文 or ja-jp 🇯🇳 日文.
  • In trigger-search mode the closed combobox renders an <input> whose value is selectedOption.label (packages/ui/src/components/primitives/combobox.tsx), and LanguageSelect built that label from searchText (code + flag + name). The renderValue prop (flag + name only) applies solely to the button trigger, so it never took effect here.

After this PR:

  • Each language option carries a display label of flag + localized name (🇨🇳 简体中文), matching the dropdown options and the renderValue output.
  • The code-bearing string remains in searchText, and filterOption still matches against searchText and the option value, so typing a language code (e.g. zh-cn) still finds the language.

Fixes #21967

Why we need it and why it was done in this way

The following tradeoffs were made:

  • The display label is a plain string (flag + name) because the trigger-search input can only render a string value; the rich JSX rendering (content) continues to be used inside the dropdown and by renderValue.
  • Only language options changed. extraOptionsBefore/After already build their label from the plain display text with no code prefix, so they were left untouched.

The following alternatives were considered:

  • Changing the shared Combobox to use renderValue for the closed trigger input. That would alter a shared primitive used across the app and would also need a string fallback for the input, for a bug that is specific to how LanguageSelect constructs its labels. Keeping the change in LanguageSelect is the smaller, lower-risk fix.

Links to places where the discussion took place: #21967 (root cause and fix direction identified there).

Agent Note / Spec

Agent Note: N/A — one-line, localized UI bug fix on an existing component; the issue already located the exact cause and direction, no Spec needed.

Spec PR: N/A

Acceptance criteria: N/A — direct bug fix; verified by the two regression cases noted below (closed selector shows flag + name only; code search still works).

Verification

  • Environment: Node v24.22.0, pnpm 12.6.0 (corepack), Windows 11 (10.0.26200), AMD64.
  • Baseline before changes: pnpm test:renderer src/renderer/components/__tests__/LanguageSelect.test.tsx → 1 pass, 0 fail.
  • pnpm test:renderer src/renderer/components/__tests__/LanguageSelect.test.tsx src/renderer/windows/quickAssistant/translate/__tests__/TranslateWindow.test.tsx → 2 files, 6 pass, 0 fail.
  • Regression check: with the one-line fix reverted, the new closed-selector test fails (zh-cn 🇨🇳 Chinese received instead of 🇨🇳 Chinese); the code-search test stays green. With the fix in place, all 3 tests pass.
  • pnpm check --group types (selected scope: renderer, tsc --noEmit -p tsconfig.web.json) → passed.
  • pnpm check --group i18n → passed (89062 translation entries verified; 0 unused keys; no hardcoded strings).
  • pnpm exec oxlint --deny-warnings <changed files> → 0 warnings, 0 errors; pnpm exec eslint <changed files> → clean; pnpm exec oxfmt --check <changed files> → correct format.
  • The full local suite was not run per the repository's scoped local-PR validation guidance; CI will run the full gate once a maintainer approves.

Breaking changes

None. The option value and searchText are unchanged; only the closed-trigger display string changes.

Special notes for your reviewer

  • Diff is 1 production line plus 18 test lines (src/renderer/components/LanguageSelect.tsx and its existing test file).
  • Commits include DCO Signed-off-by; GPG/SSH cryptographic signing is not configured on this machine.

Checklist

  • Branch: This PR targets main
  • PR: The PR description is explicit enough and will help future contributors
  • Code: Write code that humans can understand and Keep it simple
  • Refactor: You have left the code cleaner than you found it (Boy Scout Rule)
  • Upgrade: Impact of this change on upgrade flows was considered and addressed if required
  • Documentation: A user-guide update was considered; this fixes a selector display detail and adds no new setting or workflow, so no docs update is required.
  • Self-review: I have reviewed my own code (e.g., via /gh-pr-review, git pr diff, or GitHub UI) before requesting review from others

Release note

Translate: the target-language selector no longer shows the raw language code (e.g. "zh-cn") before the flag and language name when closed.

…trigger

With searchPlacement='trigger', the closed combobox renders an input whose value is selectedOption.label. LanguageSelect built that label from searchText (code + flag + name), so the closed selector showed e.g. 'zh-cn 🇨🇳 简体中文'. Use a display label of flag + localized name; the code-bearing string stays in searchText for filtering.

Refs CherryHQ#21967

Signed-off-by: zzx04-cool <[email protected]>
Assert the closed selector shows flag + localized name without the raw code (fails before the fix), and that typing a language code still finds and selects the language.

Refs CherryHQ#21967

Signed-off-by: zzx04-cool <[email protected]>

@cherry-pr-review cherry-pr-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Technical review supports approval at 39b30b3de92e7efc1819c495cdc8ce7a5b2ff714. No confirmed defects: the selector displays flag plus localized name while preserving code search and selection values. Reviewed the full diff, Combobox contract, and all LanguageSelect consumers.

Frozen-head CI at 2026-10-19 08:58 UTC: 10 successful checks, six skipped, and cherry-review in progress; no failures. Legacy status has zero contexts. Reviewer A reports six focused tests passed across two files; the Lead performed static verification and scope checks without rerunning tests or Electron visual checks.

Cherry Review · Passed

no findings

@DeJeune
DeJeune merged commit dcab4fe into CherryHQ:main Oct 19, 2026
18 checks passed
ShuaiHui pushed a commit to xigaomeicun/cherry-lite that referenced this pull request Oct 20, 2026
…trigger (CherryHQ#21993)

### What this PR does

Before this PR:

- The translate target-language selector (`LanguageSelect` with
`searchPlacement="trigger"`) showed the raw language code in front of
the flag and localized name while closed, e.g. `zh-cn 🇨🇳 简体中文` or `ja-jp
🇯🇳 日文`.
- In trigger-search mode the closed combobox renders an `<input>` whose
value is `selectedOption.label`
(`packages/ui/src/components/primitives/combobox.tsx`), and
`LanguageSelect` built that `label` from `searchText` (code + flag +
name). The `renderValue` prop (flag + name only) applies solely to the
button trigger, so it never took effect here.

After this PR:

- Each language option carries a display `label` of flag + localized
name (`🇨🇳 简体中文`), matching the dropdown options and the `renderValue`
output.
- The code-bearing string remains in `searchText`, and `filterOption`
still matches against `searchText` and the option value, so typing a
language code (e.g. `zh-cn`) still finds the language.

Fixes CherryHQ#21967

### Why we need it and why it was done in this way

The following tradeoffs were made:

- The display label is a plain string (`flag + name`) because the
trigger-search input can only render a string value; the rich JSX
rendering (`content`) continues to be used inside the dropdown and by
`renderValue`.
- Only language options changed. `extraOptionsBefore/After` already
build their label from the plain display text with no code prefix, so
they were left untouched.

The following alternatives were considered:

- Changing the shared `Combobox` to use `renderValue` for the closed
trigger input. That would alter a shared primitive used across the app
and would also need a string fallback for the input, for a bug that is
specific to how `LanguageSelect` constructs its labels. Keeping the
change in `LanguageSelect` is the smaller, lower-risk fix.

Links to places where the discussion took place: CherryHQ#21967 (root cause and
fix direction identified there).

### Agent Note / Spec

Agent Note: N/A — one-line, localized UI bug fix on an existing
component; the issue already located the exact cause and direction, no
Spec needed.

Spec PR: N/A

Acceptance criteria: N/A — direct bug fix; verified by the two
regression cases noted below (closed selector shows flag + name only;
code search still works).

### Verification

- Environment: Node v24.22.0, pnpm 12.6.0 (corepack), Windows 11
(10.0.26200), AMD64.
- Baseline before changes: `pnpm test:renderer
src/renderer/components/__tests__/LanguageSelect.test.tsx` → 1 pass, 0
fail.
- `pnpm test:renderer
src/renderer/components/__tests__/LanguageSelect.test.tsx
src/renderer/windows/quickAssistant/translate/__tests__/TranslateWindow.test.tsx`
→ 2 files, 6 pass, 0 fail.
- Regression check: with the one-line fix reverted, the new
closed-selector test fails (`zh-cn 🇨🇳 Chinese` received instead of `🇨🇳
Chinese`); the code-search test stays green. With the fix in place, all
3 tests pass.
- `pnpm check --group types` (selected scope: renderer, `tsc --noEmit -p
tsconfig.web.json`) → passed.
- `pnpm check --group i18n` → passed (89062 translation entries
verified; 0 unused keys; no hardcoded strings).
- `pnpm exec oxlint --deny-warnings <changed files>` → 0 warnings, 0
errors; `pnpm exec eslint <changed files>` → clean; `pnpm exec oxfmt
--check <changed files>` → correct format.
- The full local suite was not run per the repository's scoped local-PR
validation guidance; CI will run the full gate once a maintainer
approves.

### Breaking changes

None. The option `value` and `searchText` are unchanged; only the
closed-trigger display string changes.

### Special notes for your reviewer

- Diff is 1 production line plus 18 test lines
(`src/renderer/components/LanguageSelect.tsx` and its existing test
file).
- Commits include DCO `Signed-off-by`; GPG/SSH cryptographic signing is
not configured on this machine.

### Checklist

- [x] Branch: This PR targets `main`
- [x] PR: The PR description is explicit enough and will help future
contributors
- [x] Code: Write code that humans can understand and Keep it simple
- [x] Refactor: You have left the code cleaner than you found it (Boy
Scout Rule)
- [x] Upgrade: Impact of this change on upgrade flows was considered and
addressed if required
- [x] Documentation: A user-guide update was considered; this fixes a
selector display detail and adds no new setting or workflow, so no docs
update is required.
- [x] Self-review: I have reviewed my own code (e.g., via
`/gh-pr-review`, `git pr diff`, or GitHub UI) before requesting review
from others

### Release note

```release-note
Translate: the target-language selector no longer shows the raw language code (e.g. "zh-cn") before the flag and language name when closed.
```

---------

Signed-off-by: zzx04-cool <[email protected]>
Co-authored-by: zzx04-cool <[email protected]>
(cherry picked from commit dcab4fe)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Translate language selector shows the raw language code before the language name

2 participants