mdx-editor / editor

A rich text editor React component for markdown
https://mdxeditor.dev
MIT License
1.91k stars 145 forks source link

i18n support #371

Closed pukmajster closed 7 months ago

pukmajster commented 7 months ago

Example usage

The editor can be localised by passing the i18n prop to the editor like so:

const slovenianLocale: MDXEditorI18n = {
  toolbar: {
    blockTypeSelect: {
      selectBlockTypeTooltip: 'Izberi vrsto bloka',
      placeholder: 'Vrsta bloka'
    },

    blockTypes: {
      paragraph: 'Odstavek',
      heading: 'Naslov',
      quote: 'Citat'
    }
  }
}

function LocalizedEditor() {
  return <MDXEditor i18n={slovenianLocale} />
}

This code above will change the strings for the block type select element and its labels:

image

How it's done internally

i18n is handled via a React context. More specifically, the useI18n hook. A plugin can access this hook and it will have all the necessary translations available to it

export default function ExampleElement() {
  const i18n = useI18n()
  return <button title={i18n.toolbar.bold}>{i18n.toolbar.bold}</button>
}

I may have missed a translation or two, and some additional work may be required for custom plugins, but I think this is a decent starting point. I will happily provide additional development on the subject, so please, let me know what you think.

petyosi commented 7 months ago

Thank you very much for that contribution. This is indeed a great addition. I pushed a change that does the following:

With the changes above, any plugin should be able to access the hook or the i18n$ cell (if they need it outside of React).

To extend further on the topic of external plugins needing more translations: I think it makes sense to take advantage of TypeScript's capability to merge interface declarations.

For that purpose, I think we should use interfaces rather than types (a small example in the docs on how to declare the interface from the outside would be great - here's one example where I do that for an external interface: https://github.com/mdx-editor/editor/blob/main/src/mdastUtilHtmlComment.ts#L9-L15). Let me know if this makes sense.

pukmajster commented 7 months ago

Yeah agreed, interfaces are better for this. I've gone ahead and converted the types. Is this then, in theory, enough for external plugins to fully utilise i18n?

petyosi commented 7 months ago

That looks good to me. I will give it another thorough read and merge next week.

petyosi commented 7 months ago

I've given this some more thought. I will work on distributing the translation pieces into each plugin to see how this could work. In that way, each plugin should be able to include its own parts conveniently. Of course, the final translation override should happen at the root component prop.

petyosi commented 7 months ago

@pukmajster Thank you very much for your contribution. I adapted it to an i18next-compatible implementation - the API they have is actually solving issues like interpolation for example. The new translation prop is available in v2.10.0; here are the docs: https://mdxeditor.dev/editor/docs/i18n.