From 60785f53bc4886950cc22866e7088d1706564c9a Mon Sep 17 00:00:00 2001 From: Harel M Date: Mon, 2 Sep 2024 12:44:44 +0300 Subject: [PATCH] Add translation process and small fixes (#930) ## Launch Checklist This adds information about how to translate Maputnik and how to get in touch with people who have translated in the past. @keichan34, @jieme, @lhapaipai - I need your approval for this so that people in the future will know to contact you in case text is being added and they need help translating it. CC: @ianthetechie I've also changed the word "Language" in the upper part of the screen so that it won't be translated in case you accidentally switch language, and you need to switch back. I've also fixed some RTL issues in the CSS and updated the maplibre components labels when the language changes. --- README.md | 2 ++ src/components/AppToolbar.tsx | 8 ++++---- src/components/MapMaplibreGl.tsx | 24 +++++++++++++++++++----- src/libs/zoomcontrol.ts | 16 ++++++++++------ src/locales/README.md | 25 +++++++++++++++++++++++++ src/styles/_export.scss | 2 +- src/styles/_filtereditor.scss | 4 ++-- src/styles/_input.scss | 3 +++ src/styles/_layer.scss | 2 +- src/styles/_popup.scss | 4 +++- src/styles/_toolbar.scss | 8 ++++---- src/styles/index.scss | 3 +-- 12 files changed, 75 insertions(+), 26 deletions(-) create mode 100644 src/locales/README.md diff --git a/README.md b/README.md index 9970de51..99ea2e2b 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,8 @@ Maputnik is written in typescript and is using [React](https://github.com/facebo We ensure building and developing Maputnik works with the [current active LTS Node.js version and above](https://github.com/nodejs/Release#release-schedule). +Check out our [Internationalization guide](./src/locales/README.md) for UI text related changes. + ### Getting Involved Join the #maplibre or #maputnik slack channel at OSMUS: get an invite at https://slack.openstreetmap.us/ Read the the below guide in order to get familiar with how we do things around here. diff --git a/src/components/AppToolbar.tsx b/src/components/AppToolbar.tsx index 30eb4497..6765be44 100644 --- a/src/components/AppToolbar.tsx +++ b/src/components/AppToolbar.tsx @@ -230,7 +230,7 @@ class AppToolbarInternal extends React.Component { - + - + diff --git a/src/components/MapMaplibreGl.tsx b/src/components/MapMaplibreGl.tsx index c98d742a..87a2ad23 100644 --- a/src/components/MapMaplibreGl.tsx +++ b/src/components/MapMaplibreGl.tsx @@ -14,6 +14,7 @@ import '../libs/maplibre-rtl' import MaplibreGeocoder, { MaplibreGeocoderApi, MaplibreGeocoderApiConfig } from '@maplibre/maplibre-gl-geocoder'; import '@maplibre/maplibre-gl-geocoder/dist/maplibre-gl-geocoder.css'; import { withTranslation, WithTranslation } from 'react-i18next' +import i18next from 'i18next' function renderPopup(popup: JSX.Element, mountNode: ReactDOM.Container): HTMLElement { ReactDOM.render(popup, mountNode); @@ -67,9 +68,11 @@ type MapMaplibreGlInternalProps = { } & WithTranslation; type MapMaplibreGlState = { - map: Map | null - inspect: MaplibreInspect | null - zoom?: number + map: Map | null; + inspect: MaplibreInspect | null; + geocoder: MaplibreGeocoder | null; + zoomControl: ZoomControl | null; + zoom?: number; }; class MapMaplibreGlInternal extends React.Component { @@ -87,7 +90,12 @@ class MapMaplibreGlInternal extends React.Component { + this.forceUpdate(); + }) } @@ -125,6 +133,7 @@ class MapMaplibreGlInternal extends React.Component - `; - this._textEl = this._container.querySelector("span"); - + this.setLabel("Zoom:"); this.addEventListeners(); return this._container; @@ -25,6 +21,14 @@ export default class ZoomControl { updateZoomLevel() { this._textEl!.innerHTML = this._map!.getZoom().toFixed(2); } + + setLabel(label: string) { + this._container!.innerHTML = ` + ${label} + `; + this._textEl = this._container!.querySelector("span"); + this.updateZoomLevel(); + } addEventListeners (){ this._map!.on('render', () => this.updateZoomLevel()); diff --git a/src/locales/README.md b/src/locales/README.md new file mode 100644 index 00000000..5535f79b --- /dev/null +++ b/src/locales/README.md @@ -0,0 +1,25 @@ +## Internationalization + +The process of internationlization is pretty straight forward for Maputnik. + +In order to add a new translation you'll need to create a new folder and a json file with the relevant language code and make sure all the keys are translated. +The following users can help you with the relevant languages: + +- English - @HarelM +- Japanese - @keichan34 +- Simplified Chinese - @jieme +- Hebrew - @HarelM +- French - @lhapaipai + +If you happen to add a feature which needs some text to be translated, update the translation files. +After running, check your working copy for files and add/correct as needed. + +``` +npm run i18n:refresh +``` + +You can test the UI in different languages using the dropdown in the top menu +Note that Maputnik automatically localize based on browser language settings and stores this language in local storage. +You can use incognito mode to check a first time usage. + + diff --git a/src/styles/_export.scss b/src/styles/_export.scss index ce000ec0..d14e0f3c 100644 --- a/src/styles/_export.scss +++ b/src/styles/_export.scss @@ -10,7 +10,7 @@ } input.maputnik-string { - margin-left: 5px; + margin: 0 5px; width: 60%; display: inline-block; } diff --git a/src/styles/_filtereditor.scss b/src/styles/_filtereditor.scss index f2219ded..b8d4fd7d 100644 --- a/src/styles/_filtereditor.scss +++ b/src/styles/_filtereditor.scss @@ -18,7 +18,7 @@ } .maputnik-filter-editor-operator { - margin-left: 2%; + margin: 0 2%; display: inline-block; width: 17%; @@ -30,7 +30,7 @@ .maputnik-filter-editor-args { display: inline-block; width: 54%; - margin-left: 2%; + margin: 0 2%; .maputnik-string, .maputnik-number { diff --git a/src/styles/_input.scss b/src/styles/_input.scss index 5af49891..e6e5b890 100644 --- a/src/styles/_input.scss +++ b/src/styles/_input.scss @@ -107,6 +107,9 @@ height: 24px; } +[dir="rtl"] .maputnik-select { + background: $color-gray url("#{$icon-down-arrow}") left center no-repeat; +} // MULTIBUTTON .maputnik-multibutton { diff --git a/src/styles/_layer.scss b/src/styles/_layer.scss index 5dc9bf36..bba1b881 100644 --- a/src/styles/_layer.scss +++ b/src/styles/_layer.scss @@ -178,7 +178,7 @@ } &-group-content { - margin-left: $margin-3; + margin: 0 $margin-3; } } diff --git a/src/styles/_popup.scss b/src/styles/_popup.scss index a500efb5..91f104fa 100644 --- a/src/styles/_popup.scss +++ b/src/styles/_popup.scss @@ -22,7 +22,7 @@ .maputnik-popup-layer-id { padding-left: $margin-2; - padding-right: 1.6em; + padding-right: $margin-2; background-color: $color-midgray; color: $color-white; } @@ -33,6 +33,7 @@ .maputnik-input-block { margin: 0; margin-left: $margin-2; + margin-right: $margin-2; margin-top: $margin-2; } } @@ -44,4 +45,5 @@ .maputnik-popup-table-cell { color: $color-lowgray; padding-left: $margin-2; + padding-right: $margin-2; } diff --git a/src/styles/_toolbar.scss b/src/styles/_toolbar.scss index 7d515f96..7ca45914 100644 --- a/src/styles/_toolbar.scss +++ b/src/styles/_toolbar.scss @@ -87,7 +87,7 @@ .maputnik-toolbar-version { font-size: 10px; - margin-left: 4px; + margin: 0 4px; white-space: nowrap; } @@ -103,7 +103,7 @@ @extend .maputnik-toolbar-link; /* stylelint-disable-line */ select { - margin-left: 6px; + margin: 0 6px; border-width: 0; display: inline; width: auto; @@ -114,12 +114,12 @@ } .maputnik-icon-text { - padding-left: $margin-1; + padding: 0 $margin-1; } .maputnik-icon-action { display: inline; - margin-left: $margin-1; + margin: 0 $margin-1; } .maputnik-toolbar__inner { diff --git a/src/styles/index.scss b/src/styles/index.scss index 865cf994..29dad048 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -102,8 +102,7 @@ &:not(:first-child) { - padding-top: $margin-1; - padding-left: $margin-2; + padding: $margin-1; } &:nth-child(1) {