Adding i18next integration
This commit is contained in:
@@ -56,6 +56,9 @@ ShallowWrapper {
|
||||
Privacy Policy
|
||||
</mockConstructor>
|
||||
</li>
|
||||
<li>
|
||||
<LoadNamespace(LocaleSwitcherImpl) />
|
||||
</li>
|
||||
</ul>,
|
||||
],
|
||||
"className": "header",
|
||||
@@ -115,6 +118,9 @@ ShallowWrapper {
|
||||
Privacy Policy
|
||||
</mockConstructor>
|
||||
</li>,
|
||||
<li>
|
||||
<LoadNamespace(LocaleSwitcherImpl) />
|
||||
</li>,
|
||||
],
|
||||
"className": "list",
|
||||
},
|
||||
@@ -200,6 +206,25 @@ ShallowWrapper {
|
||||
},
|
||||
"type": "li",
|
||||
},
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"children": <LoadNamespace(LocaleSwitcherImpl) />,
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "class",
|
||||
"props": Object {},
|
||||
"ref": null,
|
||||
"rendered": null,
|
||||
"type": [Function],
|
||||
},
|
||||
"type": "li",
|
||||
},
|
||||
],
|
||||
"type": "ul",
|
||||
},
|
||||
@@ -243,6 +268,9 @@ ShallowWrapper {
|
||||
Privacy Policy
|
||||
</mockConstructor>
|
||||
</li>
|
||||
<li>
|
||||
<LoadNamespace(LocaleSwitcherImpl) />
|
||||
</li>
|
||||
</ul>,
|
||||
],
|
||||
"className": "header",
|
||||
@@ -302,6 +330,9 @@ ShallowWrapper {
|
||||
Privacy Policy
|
||||
</mockConstructor>
|
||||
</li>,
|
||||
<li>
|
||||
<LoadNamespace(LocaleSwitcherImpl) />
|
||||
</li>,
|
||||
],
|
||||
"className": "list",
|
||||
},
|
||||
@@ -387,6 +418,25 @@ ShallowWrapper {
|
||||
},
|
||||
"type": "li",
|
||||
},
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"children": <LoadNamespace(LocaleSwitcherImpl) />,
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "class",
|
||||
"props": Object {},
|
||||
"ref": null,
|
||||
"rendered": null,
|
||||
"type": [Function],
|
||||
},
|
||||
"type": "li",
|
||||
},
|
||||
],
|
||||
"type": "ul",
|
||||
},
|
||||
@@ -470,6 +520,9 @@ ShallowWrapper {
|
||||
Privacy Policy
|
||||
</mockConstructor>
|
||||
</li>
|
||||
<li>
|
||||
<LoadNamespace(LocaleSwitcherImpl) />
|
||||
</li>
|
||||
</ul>,
|
||||
],
|
||||
"className": "header",
|
||||
@@ -529,6 +582,9 @@ ShallowWrapper {
|
||||
Privacy Policy
|
||||
</mockConstructor>
|
||||
</li>,
|
||||
<li>
|
||||
<LoadNamespace(LocaleSwitcherImpl) />
|
||||
</li>,
|
||||
],
|
||||
"className": "list",
|
||||
},
|
||||
@@ -614,6 +670,25 @@ ShallowWrapper {
|
||||
},
|
||||
"type": "li",
|
||||
},
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"children": <LoadNamespace(LocaleSwitcherImpl) />,
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "class",
|
||||
"props": Object {},
|
||||
"ref": null,
|
||||
"rendered": null,
|
||||
"type": [Function],
|
||||
},
|
||||
"type": "li",
|
||||
},
|
||||
],
|
||||
"type": "ul",
|
||||
},
|
||||
@@ -657,6 +732,9 @@ ShallowWrapper {
|
||||
Privacy Policy
|
||||
</mockConstructor>
|
||||
</li>
|
||||
<li>
|
||||
<LoadNamespace(LocaleSwitcherImpl) />
|
||||
</li>
|
||||
</ul>,
|
||||
],
|
||||
"className": "header",
|
||||
@@ -716,6 +794,9 @@ ShallowWrapper {
|
||||
Privacy Policy
|
||||
</mockConstructor>
|
||||
</li>,
|
||||
<li>
|
||||
<LoadNamespace(LocaleSwitcherImpl) />
|
||||
</li>,
|
||||
],
|
||||
"className": "list",
|
||||
},
|
||||
@@ -801,6 +882,25 @@ ShallowWrapper {
|
||||
},
|
||||
"type": "li",
|
||||
},
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"children": <LoadNamespace(LocaleSwitcherImpl) />,
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "class",
|
||||
"props": Object {},
|
||||
"ref": null,
|
||||
"rendered": null,
|
||||
"type": [Function],
|
||||
},
|
||||
"type": "li",
|
||||
},
|
||||
],
|
||||
"type": "ul",
|
||||
},
|
||||
|
||||
@@ -4,6 +4,8 @@ import { Link, StaticQuery, graphql } from 'gatsby';
|
||||
|
||||
import GitlabIcon from 'react-feather/dist/icons/gitlab';
|
||||
|
||||
import LocaleSwitcher from 'components/LocaleSwitcher';
|
||||
|
||||
import style from './style.module.css';
|
||||
|
||||
const query = graphql`
|
||||
@@ -36,6 +38,9 @@ export const HeaderImpl = ({ site: { siteMetadata } }) => (
|
||||
<li>
|
||||
<Link to="/privacy">Privacy Policy</Link>
|
||||
</li>
|
||||
<li>
|
||||
<LocaleSwitcher />
|
||||
</li>
|
||||
</ul>
|
||||
</header>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,323 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`LocaleSwitcher rendering 1`] = `
|
||||
ShallowWrapper {
|
||||
Symbol(enzyme.__root__): [Circular],
|
||||
Symbol(enzyme.__unrendered__): <LocaleSwitcherImpl />,
|
||||
Symbol(enzyme.__renderer__): Object {
|
||||
"batchedUpdates": [Function],
|
||||
"getNode": [Function],
|
||||
"render": [Function],
|
||||
"simulateError": [Function],
|
||||
"simulateEvent": [Function],
|
||||
"unmount": [Function],
|
||||
},
|
||||
Symbol(enzyme.__node__): Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"children": Array [
|
||||
<WithMergedOptions(TransComponent)>
|
||||
Language
|
||||
</WithMergedOptions(TransComponent)>,
|
||||
<div
|
||||
className="switcher"
|
||||
>
|
||||
<select
|
||||
onChange={[Function]}
|
||||
value="en"
|
||||
>
|
||||
<option
|
||||
value="en"
|
||||
>
|
||||
English
|
||||
</option>
|
||||
<option
|
||||
value="other"
|
||||
>
|
||||
Other
|
||||
</option>
|
||||
</select>
|
||||
<ChevronsDown
|
||||
color="currentColor"
|
||||
size="24"
|
||||
/>
|
||||
</div>,
|
||||
],
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": Array [
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "class",
|
||||
"props": Object {
|
||||
"children": "Language",
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": "Language",
|
||||
"type": [Function],
|
||||
},
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"children": Array [
|
||||
<select
|
||||
onChange={[Function]}
|
||||
value="en"
|
||||
>
|
||||
<option
|
||||
value="en"
|
||||
>
|
||||
English
|
||||
</option>
|
||||
<option
|
||||
value="other"
|
||||
>
|
||||
Other
|
||||
</option>
|
||||
</select>,
|
||||
<ChevronsDown
|
||||
color="currentColor"
|
||||
size="24"
|
||||
/>,
|
||||
],
|
||||
"className": "switcher",
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": Array [
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"children": Array [
|
||||
<option
|
||||
value="en"
|
||||
>
|
||||
English
|
||||
</option>,
|
||||
<option
|
||||
value="other"
|
||||
>
|
||||
Other
|
||||
</option>,
|
||||
],
|
||||
"onChange": [Function],
|
||||
"value": "en",
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": Array [
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": "en",
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"children": "English",
|
||||
"value": "en",
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": "English",
|
||||
"type": "option",
|
||||
},
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": "other",
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"children": "Other",
|
||||
"value": "other",
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": "Other",
|
||||
"type": "option",
|
||||
},
|
||||
],
|
||||
"type": "select",
|
||||
},
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "function",
|
||||
"props": Object {
|
||||
"color": "currentColor",
|
||||
"size": "24",
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": null,
|
||||
"type": [Function],
|
||||
},
|
||||
],
|
||||
"type": "div",
|
||||
},
|
||||
],
|
||||
"type": "label",
|
||||
},
|
||||
Symbol(enzyme.__nodes__): Array [
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"children": Array [
|
||||
<WithMergedOptions(TransComponent)>
|
||||
Language
|
||||
</WithMergedOptions(TransComponent)>,
|
||||
<div
|
||||
className="switcher"
|
||||
>
|
||||
<select
|
||||
onChange={[Function]}
|
||||
value="en"
|
||||
>
|
||||
<option
|
||||
value="en"
|
||||
>
|
||||
English
|
||||
</option>
|
||||
<option
|
||||
value="other"
|
||||
>
|
||||
Other
|
||||
</option>
|
||||
</select>
|
||||
<ChevronsDown
|
||||
color="currentColor"
|
||||
size="24"
|
||||
/>
|
||||
</div>,
|
||||
],
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": Array [
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "class",
|
||||
"props": Object {
|
||||
"children": "Language",
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": "Language",
|
||||
"type": [Function],
|
||||
},
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"children": Array [
|
||||
<select
|
||||
onChange={[Function]}
|
||||
value="en"
|
||||
>
|
||||
<option
|
||||
value="en"
|
||||
>
|
||||
English
|
||||
</option>
|
||||
<option
|
||||
value="other"
|
||||
>
|
||||
Other
|
||||
</option>
|
||||
</select>,
|
||||
<ChevronsDown
|
||||
color="currentColor"
|
||||
size="24"
|
||||
/>,
|
||||
],
|
||||
"className": "switcher",
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": Array [
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"children": Array [
|
||||
<option
|
||||
value="en"
|
||||
>
|
||||
English
|
||||
</option>,
|
||||
<option
|
||||
value="other"
|
||||
>
|
||||
Other
|
||||
</option>,
|
||||
],
|
||||
"onChange": [Function],
|
||||
"value": "en",
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": Array [
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": "en",
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"children": "English",
|
||||
"value": "en",
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": "English",
|
||||
"type": "option",
|
||||
},
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": "other",
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"children": "Other",
|
||||
"value": "other",
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": "Other",
|
||||
"type": "option",
|
||||
},
|
||||
],
|
||||
"type": "select",
|
||||
},
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "function",
|
||||
"props": Object {
|
||||
"color": "currentColor",
|
||||
"size": "24",
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": null,
|
||||
"type": [Function],
|
||||
},
|
||||
],
|
||||
"type": "div",
|
||||
},
|
||||
],
|
||||
"type": "label",
|
||||
},
|
||||
],
|
||||
Symbol(enzyme.__options__): Object {
|
||||
"adapter": ReactSixteenAdapter {
|
||||
"options": Object {
|
||||
"enableComponentDidUpdateOnSetState": true,
|
||||
"lifecycles": Object {
|
||||
"componentDidUpdate": Object {
|
||||
"onSetState": true,
|
||||
},
|
||||
"getDerivedStateFromProps": true,
|
||||
"getSnapshotBeforeUpdate": true,
|
||||
"setState": Object {
|
||||
"skipsComponentDidUpdateOnNullish": true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
`;
|
||||
@@ -0,0 +1,67 @@
|
||||
import React from 'react';
|
||||
import { withNamespaces, Trans } from 'react-i18next';
|
||||
|
||||
import ExpandIcon from 'react-feather/dist/icons/chevrons-down';
|
||||
|
||||
import i18n, { locales } from 'i18n';
|
||||
|
||||
import style from './style.module.css';
|
||||
|
||||
const localeToAvailable = (locale, available, defaultLocale) => {
|
||||
if (available.includes(locale)) {
|
||||
return locale;
|
||||
}
|
||||
|
||||
const parts = locale.split('-');
|
||||
|
||||
if (parts.length > 0 && available.includes(parts[0])) {
|
||||
return parts[0];
|
||||
}
|
||||
|
||||
return defaultLocale;
|
||||
};
|
||||
|
||||
export class LocaleSwitcherImpl extends React.PureComponent {
|
||||
state = {
|
||||
current: localeToAvailable(
|
||||
i18n.language || '',
|
||||
locales.map(l => l.code),
|
||||
'en')
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
i18n.on('languageChanged', this.handleLanguageChange);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
i18n.off('languageChanged', this.handleLanguageChange);
|
||||
}
|
||||
|
||||
handleSelectChange = ({ target }) => {
|
||||
i18n.changeLanguage(target.value);
|
||||
}
|
||||
|
||||
handleLanguageChange = lang => {
|
||||
this.setState({ current: lang });
|
||||
}
|
||||
|
||||
render() {
|
||||
const { current } = this.state;
|
||||
|
||||
return <label>
|
||||
<Trans>Language</Trans>
|
||||
<div className={ style.switcher }>
|
||||
<select value={ current } onChange={ this.handleSelectChange }>
|
||||
{ locales.map(locale => (
|
||||
<option value={ locale.code } key={ locale.code }>
|
||||
{ locale.name }
|
||||
</option>
|
||||
)) }
|
||||
</select>
|
||||
<ExpandIcon />
|
||||
</div>
|
||||
</label>;
|
||||
}
|
||||
}
|
||||
|
||||
export default withNamespaces()(LocaleSwitcherImpl);
|
||||
@@ -0,0 +1,11 @@
|
||||
@import url('../../globals.module.css');
|
||||
|
||||
:root {
|
||||
--control-gradient: var(--color-tan) var(--gradient-tan);
|
||||
--select-height: 2.4rem;
|
||||
--select-width: 10rem;
|
||||
}
|
||||
|
||||
.switcher {
|
||||
composes: fancy-select;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
import i18n from 'i18n';
|
||||
import { LocaleSwitcherImpl } from 'components/LocaleSwitcher';
|
||||
|
||||
describe('LocaleSwitcher', () => {
|
||||
test('rendering', () => {
|
||||
const component = shallow(
|
||||
<LocaleSwitcherImpl />
|
||||
);
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('changing language', () => {
|
||||
jest.spyOn(i18n, 'changeLanguage');
|
||||
|
||||
const component = shallow(
|
||||
<LocaleSwitcherImpl />
|
||||
);
|
||||
const selectInput = component.find('select');
|
||||
selectInput.value = 'other';
|
||||
selectInput.simulate('change', { target: { value: 'other' } });
|
||||
|
||||
expect(i18n.changeLanguage).toHaveBeenCalledWith('other');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user