Skip to content

Support localizable command palette copy#46

Open
shekharnwagh wants to merge 1 commit into
trunkfrom
add/i18n-support
Open

Support localizable command palette copy#46
shekharnwagh wants to merge 1 commit into
trunkfrom
add/i18n-support

Conversation

@shekharnwagh
Copy link
Copy Markdown
Contributor

Summary

Adds a dependency-free messages API so consumers can localize package-owned command palette copy while keeping their existing i18n framework.

Closes RSM-2861

What changed

  • Added CommandsMessages and ResultItemType exports.
  • Added messages?: Partial<CommandsMessages> to <Commands />.
  • Replaced package-owned hardcoded UI, ARIA, empty-state, loading, and result-count strings with configurable messages.
  • Kept placeholder and emptyState precedence for backward compatibility.
  • Documented the API and the consumer-owned command config localization boundary.

Testing

  • pnpm format:check
  • pnpm lint
  • pnpm test -- src/commands.test.tsx

Expose a messages prop so consumers can localize package-owned
palette copy without adding an i18n dependency to the library.
@shekharnwagh shekharnwagh self-assigned this May 11, 2026
@shekharnwagh shekharnwagh requested a review from aswasif007 May 11, 2026 18:45
@aswasif007
Copy link
Copy Markdown
Contributor

aswasif007 commented May 12, 2026

I think this approach of i18n adds maintenance overhead: the clients have to pass every string-label. Can we just have the client pass the translate function instead?

Or just directly use the i18n-calypso library if i18n=true is set in the prop?

@shekharnwagh
Copy link
Copy Markdown
Contributor Author

shekharnwagh commented May 12, 2026

I think this approach of i18n adds maintenance overhead: the clients have to pass every string-label. Can we just have the client pass the translate function instead?

Or just directly use the i18n-calypso library if i18n=true is set in the prop?

@aswasif007 The boilerplate concern is fair and even considered it, but both alternatives run into practical issues:

Passing the translate function: The main problem is string extraction. Tools like wp-i18n and Calypso's babel plugin work by statically analysing source code for translate('...') calls. If the English strings live inside @automattic/commands but the translate function comes from the consumer, the consumer's extraction pipeline won't find them. There's also a signature mismatch: i18n-calypso uses translate(single, plural, { count }), @wordpress/i18n uses separate __() / _n() / _x(), and react-i18next uses t(key, { count }). Pluralization especially doesn't generalise across these.

Using i18n-calypso directly: This couples a reusable package to the Calypso ecosystem. VIP Dashboard already had to fork i18n-calypso locally just for React 18 compat. Future consumers may use entirely different i18n runtimes.

Since it's Partial<CommandsMessages>, English-only consumers pass nothing. For translated consumers, it's a one-time hook wired at the single mount point. This is the same pattern MUI uses with their localeText prop for DataGrid/DatePicker — a partial object of translated strings with built-in defaults.

That said, this felt like a straightforward fix without needing to add translation parsers or i18n dependencies to the package. But if you think a different approach would be worth the added complexity, happy to explore it further.

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.

2 participants