feat(dashboard): type-safe i18n for UI extensions (#13851)
## Summary
**What**
Exports the type of medusa's i18n keys from the dashboard package, for autocomplete support.
**Why**
Currently i18next is not able to provide proper ts autocomplete support when adding translations to projects or plugins.
For example when adding a data table or form, I have to go back multiple times to the source i18n files in the medusa repo and search for the exact key name(is it "actions.confirm" or "general.confirm"? etc) and I forget it right after every single time.
Even if all medusa components were provided already translated, it's still very convinient to use keys from medusa(if context appropriate) for some custom components, since they are already translated into many languages(eg "yes", "no" and other very basic strings). Hence why ts support for the base keys would be very helpful
**How**
Modified the generateTypes script to also copy the `en.json` file to the dist folder, and export a `Resources` type with the inferred keys in index.d.ts.
This allows users to define their own i18next type definitions including the base "translation" namespace, example below.
**Testing**
Manual testing
---
## Examples
```ts
// In src/admin/i18next.d.ts
import type enTranslation from "./i18n/en.json" // custom keys
import type { Resources } from "@medusajs/dashboard" // medusa keys
declare module "i18next" {
interface CustomTypeOptions {
fallbackNS: "translation"
resources: {
translation: Resources["translation"]
// all custom namespaces need to merge Resources["translation"] as well
// otherwise when falling back to "translation", strings will have type "never"
myCustomNs: typeof enTranslation & Resources["translation"]
}
}
}
```
Then, both `useTranslation()` and `useTranslation("myCustomNs")` will have proper autocomplete support
---
## Checklist
Please ensure the following before requesting a review:
- [x] I have added a **changeset** for this PR
- Every non-breaking change should be marked as a **patch**
- To add a changeset, run `yarn changeset` and follow the prompts
- [x] The changes are covered by relevant **tests**
- [x] I have verified the code works as intended locally
- [x] I have linked the related issue(s) if applicable
This commit is contained in:
5
.changeset/sour-camels-live.md
Normal file
5
.changeset/sour-camels-live.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@medusajs/dashboard": patch
|
||||
---
|
||||
|
||||
feat(dashboard): type-safe i18n for UI extensions
|
||||
@@ -11,12 +11,17 @@ async function generateTypes() {
|
||||
const filePath = path.join(distDir, "index.d.ts")
|
||||
|
||||
const fileContent = `
|
||||
declare function App(props: {
|
||||
plugins?: any[]
|
||||
}): JSX.Element
|
||||
declare function App(props: {
|
||||
plugins?: any[]
|
||||
}): JSX.Element
|
||||
|
||||
export default App
|
||||
`
|
||||
export default App
|
||||
|
||||
import type enTranslation from "./en.json"
|
||||
export type Resources = {
|
||||
translation: typeof enTranslation
|
||||
}
|
||||
`
|
||||
|
||||
// Ensure the dist directory exists
|
||||
if (!fs.existsSync(distDir)) {
|
||||
@@ -26,6 +31,13 @@ async function generateTypes() {
|
||||
// Write the content to the index.d.ts file
|
||||
fs.writeFileSync(filePath, fileContent.trim(), "utf8")
|
||||
|
||||
// Copy the canonical en translation for type inference
|
||||
const enTranslationSrcPath = path.join(
|
||||
__dirname, "../src/i18n/translations/en.json"
|
||||
)
|
||||
const enTranslationDistPath = path.join(distDir, "en.json")
|
||||
fs.copyFileSync(enTranslationSrcPath, enTranslationDistPath)
|
||||
|
||||
console.log(`File created at ${filePath}`)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user