Add react-i18next for multi-language support (#917)

This is a rough start on adding react-i18next. I'll be working on adding
more translatable strings and translations in the coming days. I'm going
to need to wrap class components in HOCs, so let me know if there's
something I should be fixing before doing that. I'm thinking now to keep
the exported class names exactly the same, and rename the existing
classes by prefixing an `I` (for internal). For example:

```
export default class AppToolbar ...
```

becomes

```
class IAppToolbar ...
const AppToolbar = withTranslation()(IAppToolbar);
export default AppToolbar;
```

I'll be able to contribute Japanese strings (I've talked to a couple
people on my team and they'll be happy to help as well), so that's the
language I decided to go with in this PR.

Closes #746

---------

Co-authored-by: Ko Nagase <nagase@georepublic.co.jp>
Co-authored-by: Harel M <harel.mazor@gmail.com>
This commit is contained in:
Keitaroh Kobayashi
2024-08-19 18:43:04 +09:00
committed by GitHub
parent 35840409b8
commit 58edd262b0
55 changed files with 2333 additions and 501 deletions
+12 -8
View File
@@ -1,6 +1,7 @@
import React from 'react'
import {MdDelete, MdUndo} from 'react-icons/md'
import stringifyPretty from 'json-stringify-pretty-compact'
import { WithTranslation, withTranslation } from 'react-i18next';
import Block from './Block'
import InputButton from './InputButton'
@@ -8,7 +9,7 @@ import labelFromFieldName from '../libs/label-from-field-name'
import FieldJson from './FieldJson'
type ExpressionPropertyProps = {
type ExpressionPropertyInternalProps = {
onDelete?(...args: unknown[]): unknown
fieldName: string
fieldType?: string
@@ -20,20 +21,20 @@ type ExpressionPropertyProps = {
canUndo?(...args: unknown[]): unknown
onFocus?(...args: unknown[]): unknown
onBlur?(...args: unknown[]): unknown
};
} & WithTranslation;
type ExpressionPropertyState = {
jsonError: boolean
};
export default class ExpressionProperty extends React.Component<ExpressionPropertyProps, ExpressionPropertyState> {
class ExpressionPropertyInternal extends React.Component<ExpressionPropertyInternalProps, ExpressionPropertyState> {
static defaultProps = {
errors: {},
onFocus: () => {},
onBlur: () => {},
}
constructor (props:ExpressionPropertyProps) {
constructor(props: ExpressionPropertyInternalProps) {
super(props);
this.state = {
jsonError: false,
@@ -53,7 +54,7 @@ export default class ExpressionProperty extends React.Component<ExpressionProper
}
render() {
const {errors, fieldName, fieldType, value, canUndo} = this.props;
const {t, errors, fieldName, fieldType, value, canUndo} = this.props;
const {jsonError} = this.state;
const undoDisabled = canUndo ? !canUndo() : true;
@@ -65,7 +66,7 @@ export default class ExpressionProperty extends React.Component<ExpressionProper
onClick={this.props.onUndo}
disabled={undoDisabled}
className="maputnik-delete-stop"
title="Revert from expression"
title={t("Revert from expression")}
>
<MdUndo />
</InputButton>
@@ -74,7 +75,7 @@ export default class ExpressionProperty extends React.Component<ExpressionProper
key="delete_action"
onClick={this.props.onDelete}
className="maputnik-delete-stop"
title="Delete expression"
title={t("Delete expression")}
>
<MdDelete />
</InputButton>
@@ -112,7 +113,7 @@ export default class ExpressionProperty extends React.Component<ExpressionProper
// this feels like an incorrect type...? `foundErrors` is an array of objects, not a single object
error={foundErrors as any}
fieldSpec={this.props.fieldSpec}
label={labelFromFieldName(this.props.fieldName)}
label={t(labelFromFieldName(this.props.fieldName))}
action={deleteStopBtn}
wideMode={true}
>
@@ -137,3 +138,6 @@ export default class ExpressionProperty extends React.Component<ExpressionProper
</Block>
}
}
const ExpressionProperty = withTranslation()(ExpressionPropertyInternal);
export default ExpressionProperty;