Skip to content

plugin-timeline gantt axis and row-label default are hardcoded English strings, so a zh session reads "Week 1" / "Q3 2026" / "Items" #4520

Description

@yinlianghui

Found while fixing #4513 (the four 'en-US' literals plus the bare toLocaleDateString() in packages/plugin-timeline/src/renderer.tsx). Out of that card's scope — #4513's ruling scopes it to the five Intl date sites, and these are a translation concern rather than a locale-resolver one, so they are recorded here rather than fixed on a rider.

What was measured

#4513's fix threads useDisplayLocale() through every Intl call, so on a zh session the gantt axis now reads 2026年8月 and item dates read 2026年8月11日. Three sibling strings in the same renderer never went through Intl at all, so they stay English on that same Chinese axis:

  • renderer.tsx:84headers.push(Week ${week++}) for the week scale. A zh gantt axis reads Week 1, Week 2, ….
  • renderer.tsx:92headers.push(Q${...} ${current.getFullYear()}) for the quarter scale, i.e. Q3 2026. (Q is arguably a recognized abbreviation in some locales; zh writes 第三季度 / 2026年第3季度.)
  • renderer.tsx:364{schema.rowLabel || 'Items'} — the gantt row-label column header. Only the default is hardcoded; an author who sets rowLabel supplies their own string.

The year scale (String(current.getFullYear())) is genuinely locale-free and needs nothing.

Why it matters

Same user-visible surface as #4513 and the same session: a fully Chinese console renders a Chinese date axis with English bucket labels beside it. It is narrower than #4513 — only the week and quarter scales and the unset-rowLabel case are affected — but it is live, not dormant.

What this needs (and why it is not a rider on #4513)

The package already owns a translation channel: useTimelineTranslation / TIMELINE_DEFAULT_TRANSLATIONS in src/useTimelineTranslation.ts, the createSafeTranslation pattern that keeps the widget working with no I18nProvider mounted. Adding timeline.scale.week / timeline.scale.quarter / timeline.gantt.rowLabel there is the shape.

Two reasons it was not folded into #4513:

  1. generateTimeScaleHeaders is a pure exported function, not a component. plugin-timeline hardcodes 'en-US' at four date sites, so timeline headers stay English on every non-English session #4513 threads a resolved locale string into it, which is a value; a translate fn is a different kind of dependency, and pushing one through the same seam is a design choice (thread t as well, vs. return structured buckets and let the component render them) rather than a mechanical extension.
  2. It is vocabulary growth — three new translation keys plus their locale-pack entries — which under the startup-focus principle deserves its own triage rather than arriving inside a bug fix.

No Intl call is involved in any of the three, so nothing here is affected by #4513's change; the two are disjoint edits to the same file.


Generated by Claude Code

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions