Translation work done

This commit is contained in:
Federico Kereki
2018-07-11 23:02:27 -03:00
parent 644f77888c
commit 6321d9ad04
15 changed files with 352 additions and 89 deletions
+45
View File
@@ -7571,6 +7571,14 @@
}
}
},
"html-parse-stringify2": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/html-parse-stringify2/-/html-parse-stringify2-2.0.1.tgz",
"integrity": "sha1-3FZwtyksoVi3vJFsmmc1rIhyg0o=",
"requires": {
"void-elements": "^2.0.1"
}
},
"html-tag-names": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/html-tag-names/-/html-tag-names-1.1.3.tgz",
@@ -7665,6 +7673,21 @@
"integrity": "sha1-MRYKNpMK2vH8BMYHT360FGXU7Es=",
"dev": true
},
"i18next": {
"version": "11.3.6",
"resolved": "https://registry.npmjs.org/i18next/-/i18next-11.3.6.tgz",
"integrity": "sha512-gaS/MwVTxOXgYSYPB3J8N3LWgOPJw7U6syjFZd2jef+kWA+0UDxf84Ai6587kTjS622/nOeCzCNPjJNQ5Mzp3Q=="
},
"i18next-browser-languagedetector": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-2.2.0.tgz",
"integrity": "sha512-fKhsaJzXY2anqAPxn9bgxc5NrTcu1GnYiIwGfNFPkpfFneutHnuReb4x4suOVNMf9RTuiCxfR+UAF8aHhv89SQ=="
},
"i18next-xhr-backend": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/i18next-xhr-backend/-/i18next-xhr-backend-1.5.1.tgz",
"integrity": "sha512-9OLdC/9YxDvTFcgsH5t2BHCODHEotHCa6h7Ly0EUlUC7Y2GS09UeoHOGj3gWKQ3HCqXz8NlH4gOrK3NNc9vPuw=="
},
"iconv-lite": {
"version": "0.4.23",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz",
@@ -11611,6 +11634,23 @@
"html-element-attributes": "^1.0.0"
}
},
"react-i18next": {
"version": "7.8.0",
"resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-7.8.0.tgz",
"integrity": "sha512-NidPO6IY//vWIhL36DbFQx0rmjTJ/s4xxdvzRErGclcnka6vjUIzpEQy+NzN8fyMpI0zID3pfsV+jpBLHeAoCw==",
"requires": {
"hoist-non-react-statics": "^2.3.1",
"html-parse-stringify2": "2.0.1",
"prop-types": "^15.6.0"
},
"dependencies": {
"hoist-non-react-statics": {
"version": "2.5.5",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz",
"integrity": "sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw=="
}
}
},
"react-icon-base": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/react-icon-base/-/react-icon-base-2.1.0.tgz",
@@ -14007,6 +14047,11 @@
"indexof": "0.0.1"
}
},
"void-elements": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz",
"integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w="
},
"warning": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz",
+4
View File
@@ -25,8 +25,12 @@
},
"dependencies": {
"color": "^3.0.0",
"i18next": "^11.3.6",
"i18next-browser-languagedetector": "^2.2.0",
"i18next-xhr-backend": "^1.5.1",
"react": "^16.4.1",
"react-dom": "^16.4.1",
"react-i18next": "^7.8.0",
"styled-components": "^3.3.3"
},
"scripts": {
+37
View File
@@ -0,0 +1,37 @@
import i18n from "i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import EN_TEXTS from "./translations.en.json";
import ES_TEXTS from "./translations.es.json";
i18n.use(LanguageDetector).init({
resources: {
en: { translations: EN_TEXTS },
es: { translations: ES_TEXTS }
},
fallbackLng: "en",
ns: ["translations"],
defaultNS: "translations",
debug: true,
interpolation: {
escapeValue: false,
format: function(value, format, lang = i18n.language) {
if (format === "AS_DATE") {
try {
const dd = new Date(value);
return new Intl.DateTimeFormat(lang).format(
new Date(
dd.getTime() + dd.getTimezoneOffset() * 60000
)
);
} catch (e) {
return "???";
}
} else {
return value;
}
}
}
});
export default i18n;
@@ -0,0 +1,87 @@
/* @flow */
import React from "react";
import "./styles.css";
import i18n from "./i18n";
const t = i18n.t.bind(i18n);
export class I18nForm extends React.PureComponent<
{},
{
delivery: String,
howMany: Number,
thingColor: String
}
> {
state = {
delivery: "2018-09-22",
howMany: 1,
thingColor: "NC"
};
componentDidMount() {
i18n.on("languageChanged", () => this.forceUpdate());
}
render() {
return (
<div>
<div>
<h2>{t("details")}</h2>
<button onClick={() => i18n.changeLanguage("es")}>
ES
</button>
<button onClick={() => i18n.changeLanguage("en")}>
EN
</button>
</div>
<br />
<div>{t("please enter details")}</div>
<br />
<div>
{t("send it before")}:
<input
type="date"
value={this.state.delivery}
onChange={e =>
this.setState({ delivery: e.target.value })
}
/>
</div>
<div>
{t("number")}:
<input
type="number"
min="1"
value={this.state.howMany}
onChange={e =>
this.setState({
howMany: Number(e.target.value)
})
}
/>
</div>
<div>
{t("color")}:
<select
onChange={e =>
this.setState({ thingColor: e.target.value })
}
>
<option value="NC">{t("colors.none")}</option>
<option value="ST">{t("colors.steel")}</option>
<option value="SD">{t("colors.sand")}</option>
</select>
</div>
<br />
<div>
{t("summary", {
count: this.state.howMany,
date: this.state.delivery
})}
</div>
</div>
);
}
}
@@ -0,0 +1,8 @@
/* @flow */
import React from "react";
import { storiesOf } from "@storybook/react";
import { I18nForm } from "./";
storiesOf("i18n form", module).add("standard", () => <I18nForm />);
@@ -0,0 +1,4 @@
/* @flow */
import { I18nForm } from "./i18nform.js";
export { I18nForm };
@@ -0,0 +1,2 @@
div {
margin-bottom: 12px; }
@@ -0,0 +1,3 @@
div {
margin-bottom: 12px;
}
@@ -0,0 +1,15 @@
{
"details": "Details",
"number": "How many things?",
"color": "Thing Color",
"send it before": "Send the thing before",
"please enter details": "Please, enter details for your thing:",
"summary": "Your only thing will be there before {{date, AS_DATE}}",
"summary_plural":
"Your {{count}} things will be there before {{date, AS_DATE}}",
"colors": {
"none": "None",
"steel": "Steel",
"sand": "Sand"
}
}
@@ -0,0 +1,15 @@
{
"details": "Detalles",
"number": "¿Cuántas cosas?",
"color": "Color de la cosa",
"send it before": "Enviar antes de",
"please enter details": "Por favor, ingrese detalles para su cosa:",
"summary": "Su única cosa llegará antes de la fecha {{date, AS_DATE}}",
"summary_plural":
"Sus {{count}} cosas llegarán antes del {{date, AS_DATE}}",
"colors": {
"none": "Ninguno",
"steel": "Acero",
"sand": "Arena"
}
}
+2 -28
View File
@@ -1,30 +1,4 @@
/* @flow */
import React from "react";
import PropTypes from "prop-types";
import "./styles.css";
export class SassButton extends React.PureComponent<{
normal: boolean,
buttonText: string,
onSelect: void => void
}> {
static propTypes = {
normal: PropTypes.bool.isRequired,
buttonText: PropTypes.string.isRequired,
onSelect: PropTypes.func.isRequired
};
render() {
return (
<div
className={
this.props.normal ? "normalButton" : "alertButton"
}
onClick={this.props.onSelect}
>
<span>{this.props.buttonText}</span>
</div>
);
}
}
import { SassButton } from "./sassButton";
export { SassButton };
@@ -0,0 +1,30 @@
/* @flow */
import React from "react";
import PropTypes from "prop-types";
import "./styles.css";
export class SassButton extends React.PureComponent<{
normal: boolean,
buttonText: string,
onSelect: void => void
}> {
static propTypes = {
normal: PropTypes.bool.isRequired,
buttonText: PropTypes.string.isRequired,
onSelect: PropTypes.func.isRequired
};
render() {
return (
<div
className={
this.props.normal ? "normalButton" : "alertButton"
}
onClick={this.props.onSelect}
>
<span>{this.props.buttonText}</span>
</div>
);
}
}
+2 -61
View File
@@ -1,63 +1,4 @@
/* @flow */
import React from "react";
import PropTypes from "prop-types";
import styled from "styled-components";
import Color from "color";
import {
NORMAL_TEXT,
NORMAL_COLOR,
ALERT_TEXT,
ALERT_COLOR
} from "./constants";
const makeSpan = props => `
span {
color: ${props.normal ? NORMAL_TEXT : ALERT_TEXT};
font-weight: bold;
}
`;
const BasicStyledDiv = styled.div`
display: inline-block;
text-decoration: none;
padding: 5px 10px;
border-radius: 3px;
`;
const StyledDiv = BasicStyledDiv.extend`
background-color: ${props =>
props.normal ? NORMAL_COLOR : ALERT_COLOR};
&:hover {
background-color: ${props =>
Color(props.normal ? NORMAL_COLOR : ALERT_COLOR)
.darken(0.25)
.string()};
transition: all 0.5s ease;
}
${props => makeSpan(props)};
`;
export class StyledButton extends React.PureComponent<{
normal: boolean,
buttonText: string,
onSelect: void => void
}> {
static propTypes = {
normal: PropTypes.bool.isRequired,
buttonText: PropTypes.string.isRequired,
onSelect: PropTypes.func.isRequired
};
render() {
return (
<StyledDiv
normal={this.props.normal}
onClick={this.props.onSelect}
>
<span>{this.props.buttonText}</span>
</StyledDiv>
);
}
}
import { StyledButton } from "./styledButton";
export { StyledButton };
@@ -0,0 +1,63 @@
/* @flow */
import React from "react";
import PropTypes from "prop-types";
import styled from "styled-components";
import Color from "color";
import {
NORMAL_TEXT,
NORMAL_COLOR,
ALERT_TEXT,
ALERT_COLOR
} from "./constants";
const makeSpan = props => `
span {
color: ${props.normal ? NORMAL_TEXT : ALERT_TEXT};
font-weight: bold;
}
`;
const BasicStyledDiv = styled.div`
display: inline-block;
text-decoration: none;
padding: 5px 10px;
border-radius: 3px;
`;
const StyledDiv = BasicStyledDiv.extend`
background-color: ${props =>
props.normal ? NORMAL_COLOR : ALERT_COLOR};
&:hover {
background-color: ${props =>
Color(props.normal ? NORMAL_COLOR : ALERT_COLOR)
.darken(0.25)
.string()};
transition: all 0.5s ease;
}
${props => makeSpan(props)};
`;
export class StyledButton extends React.PureComponent<{
normal: boolean,
buttonText: string,
onSelect: void => void
}> {
static propTypes = {
normal: PropTypes.bool.isRequired,
buttonText: PropTypes.string.isRequired,
onSelect: PropTypes.func.isRequired
};
render() {
return (
<StyledDiv
normal={this.props.normal}
onClick={this.props.onSelect}
>
<span>{this.props.buttonText}</span>
</StyledDiv>
);
}
}
+35
View File
@@ -0,0 +1,35 @@
/* @flow */
import React from "react";
const getWindowSize = () => ({
resized_w_h: window.innerWidth + "x" + window.innerHeight
});
export const makeResize = Comp => {
// eslint-disable-next-line react/display-name
return class extends React.Component {
state = getWindowSize();
constructor(props) {
super(props);
this.componentIsResizing = this.componentIsResizing.bind(this);
}
componentDidMount() {
window.addEventListener("resize", this.componentIsResizing);
}
componentWillUnmount() {
window.removeEventListener("resize", this.componentIsResizing);
}
componentIsResizing() {
this.setState(getWindowSize());
}
render() {
return <Comp {...this.props} {...this.state} />;
}
};
};