Skip to content
This repository has been archived by the owner on Feb 28, 2024. It is now read-only.

i18n Banner #46

Merged
merged 12 commits into from
Dec 29, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"private": true,
"dependencies": {
"axios": "^0.17.1",
"browser-locale": "^1.0.3",
"flexboxgrid-sass": "https://github.com/hugeinc/flexboxgrid-sass.git",
"lodash": "^4.17.4",
"node-sass-chokidar": "^0.0.3",
Expand Down
2 changes: 2 additions & 0 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {

// components
import Banner from "components/layout/Banner"
import I18nBanner from "components/I18nBanner"
import Header from "components/layout/Header"
import Footer from "components/layout/Footer"

Expand All @@ -22,6 +23,7 @@ class App extends Component {
<Router>
<div>
<Banner />
<I18nBanner />
<section className="coa-main">
<Route exact path="/" component={HomePage} />
<Route exact path="/services" component={ServicesIndex} />
Expand Down
137 changes: 137 additions & 0 deletions src/components/I18nBanner.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import React, { Component } from 'react';
import locale from 'browser-locale';

import CaretDownSVG from 'svg/CaretDown';

const languages = [
{
title: 'English',
abbr: 'en',
}, {
title: 'Español',
abbr: 'es',
}, {
title: 'Tiếng Việt',
abbr: 'vn',
}, {
title: '中文',
abbr: 'zh',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are there supposed to be two languages abbreviated with zh (中文, Chinese Traditional)?
Since we're using the abbr prop to indicate active state, two languages will be shown as active.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this is a good point. I didn't get all the way to the end of my research about the form of Chinese we'll be using.

This is the best list of language codes I've found: http://www.iana.org/assignments/language-subtag-registry/language-subtag-registry

And its seems like Simplified and Traditional Chinese share the zh language code, but have subtags to distinguish them. Not sure what that means for us in practice, if we're really going to translate for both, or how we would deal with language codes that aren't just two characters.

Thus, I just kept their abbreviation the same.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created an issue: #53 For now, I think I'll just comment out Traditional Chinese for simplicity.

}, {
title: 'عربى',
abbr: 'ar',
}, {
title: '한국어',
abbr: 'ko',
}, {
title: 'اردو',
abbr: 'ur',
}, {
title: 'မြန်မာ',
abbr: 'my',
},
]

class I18nBanner extends Component {
constructor(props) {
super(props);
this.state = {
activeLanguage: locale().substring(0,2) || 'en',
};
this.displayedLanguageAmount = 4;
this.visibleLanguageOptions = languages.slice(0, this.displayedLanguageAmount);
this.secondaryLanguageOptions = languages.slice(this.displayedLanguageAmount, languages.length);
}

getLanguageMenuClassName = (language) => {
const classNameBase = `coa-I18nBanner__language`;
return language.abbr === this.state.activeLanguage
? `${classNameBase}--active`
: ''
}

getSecondaryLanguageMenuClassName = () => {
const base = `coa-I18nBanner__other-language-options`;
return this.state.isOpen ? `${base}--open` : `${base}--closed`;
}

handleSetLanguage = (e) => {
e.stopPropagation();
e.nativeEvent.stopImmediatePropagation();
const languageAbbr = e.target.lang;
console.log(languageAbbr)
this.setState({
activeLanguage: languageAbbr,
isOpen: false,
})
}

handleExpandMenu = () => {
this.setState({
isOpen: !this.state.isOpen
})
}

render() {
return (
<div className="coa-I18nBanner">
<div className="wrapper">
<div className="row">
<div className="col-md-4 col-xs">
<div className="coa-I18nBanner__prompt">
Choose your preferred language
</div>
</div>
<div className="col-md-8 col-xs-12">
<ul className="coa-I18nBanner__language-list">
{ this.visibleLanguageOptions.map((language, i) => {
return (
<li className={`coa-I18nBanner__language ${this.getLanguageMenuClassName(language)}`}
onClick={this.handleSetLanguage}
key={i}
>
<span className="hidden--sm visible--md"
lang={language.abbr}
>
{language.title}
</span>
<span className="hidden--md visible--sm"
lang={language.abbr}
>
{language.abbr.toUpperCase()}
</span>
</li>
)
})}
{ this.secondaryLanguageOptions.length > 0 &&
<li className="coa-I18nBanner__language--other"
onClick={this.handleExpandMenu}
>
<span className="hidden--sm">Other Language </span>
<CaretDownSVG size="20"/>
<ul className={this.getSecondaryLanguageMenuClassName()}>
{ this.secondaryLanguageOptions.map((language) => {
return (
<li onClick={this.handleSetLanguage}
className={this.getLanguageMenuClassName(language)}
>
<span lang={language.abbr}>
{language.title}
</span>
</li>
)
})
}
</ul>
</li>
}
</ul>
</div>
</div>
</div>
</div>
);
}

}

export default I18nBanner;
3 changes: 0 additions & 3 deletions src/css/base/_helpers.scss

This file was deleted.

6 changes: 4 additions & 2 deletions src/css/coa.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@

// base
@import 'css/base/base';
@import 'css/base/helpers';

// helpers
@import 'css/helpers/helpers';

// modules
@import 'css/modules/form';
Expand All @@ -22,4 +24,4 @@
// layout
@import 'css/layout/main';
@import "css/layout/Footer";

@import "css/layout/I18nBanner";
32 changes: 32 additions & 0 deletions src/css/helpers/_helpers.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
.nowrap {
white-space: nowrap;
}

.hidden--sm {
// --> display none for small width screens and higher
display: none;
@include media($medium-screen) {
display: inline;
}
}

.hidden--md {
// --> display none for medium width screens and higher
display: inline;
@include media($medium-screen) {
display: none !important;
}
}

.visible--sm {
// --> display none by default, display initial for small screens and higher
display: inline;
}

.visible--md {
// --> display none by default, display initial for medium screens and higher
display: none;
@include media($medium-screen) {
display: inline;
}
}
62 changes: 62 additions & 0 deletions src/css/layout/_I18nBanner.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
.coa-I18nBanner {
width: 100%;
background-color: $color-gray-light;
padding: $coa-space-level1;
}

.coa-I18nBanner__language-list {
text-align: right;
font-size: $small-font-size;
}

.coa-I18nBanner__prompt {
display: none;
font-size: $small-font-size;
position: absolute;
left: -999em;
@include media($medium-screen) {
position: relative;
left: auto;
display: block;
};
}

@mixin coa-I18nBanner__language {
display: inline;
padding: 0 $coa-space-level2;
cursor: pointer;
}

.coa-I18nBanner__language {
@include coa-I18nBanner__language;
}

.coa-I18nBanner__language--active {
background-color: $color-gray-lighter;
}

.coa-I18nBanner__language--other {
@include coa-I18nBanner__language;
position: relative;
svg {
vertical-align: middle;
}
}

@mixin coa-I18nBanner__other-language-options {
position: absolute;
background-color: $color-gray-light;
list-style: none;
top: $coa-space-level5;
right: $coa-space-level2;
padding: $coa-space-level3;
}

.coa-I18nBanner__other-language-options--open {
@include coa-I18nBanner__other-language-options;
}

.coa-I18nBanner__other-language-options--closed {
@include coa-I18nBanner__other-language-options;
display: none;
}
13 changes: 13 additions & 0 deletions src/svg/CaretDown.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react';

function CaretDown(props) {
const { size } = props

return (
<svg width={size} height={size} viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg" aria-labelledby="title">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SHOW ME HOW TO MAKE SVG PEEEEEAS!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remind me when we are both back in the office. no magic here.

<title id="title">Caret Arrow Down</title>
<path d="M1408 704q0 26-19 45l-448 448q-19 19-45 19t-45-19l-448-448q-19-19-19-45t19-45 45-19h896q26 0 45 19t19 45z"/>
</svg>
)
}
export default CaretDown;
4 changes: 4 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1109,6 +1109,10 @@ brorand@^1.0.1:
version "1.1.0"
resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"

browser-locale@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/browser-locale/-/browser-locale-1.0.3.tgz#3c6646e6dd5f7a3c62ff51d4ae618a5dd3126911"

browser-pack@^6.0.1:
version "6.0.2"
resolved "https://registry.yarnpkg.com/browser-pack/-/browser-pack-6.0.2.tgz#f86cd6cef4f5300c8e63e07a4d512f65fbff4531"
Expand Down