Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | 1x 1x 36x 1x 33x 1x 1x 1x 1x 1x 1x 2x 1x 1x 1x 1x 1x 1x 1x 3x 3x 3x 33x 1x 1x | import React from 'react';
import PropTypes from 'prop-types';
// Add new flag emoji here
const flags = {
en: '🇬🇧',
fr: '🇫🇷',
de: '🇩🇪',
es: '🇪🇸',
hi: '🇮🇳',
id: '🇮🇩',
it: '🇮🇹',
ja: '🇯🇵',
mr: '🇮🇳',
my: '🇲🇲',
pt: '🇵🇹',
};
/**
* Renders the flag emoji and display name for a given language
*
* @param object props
* @param string name language display name
* @param string flag flag emoji
*
* @returns component stateless
*/
const LanguageNode = ({ name, flag }) => (
<>
<span className='flag'>{flag}</span>
{name}
</>
);
/**
* Renders a selectable language option in the languages dropdown
*
* @param object props
* @param object language language object
* @param string value language value
* @param string selectedLanguage selected language value
* @param function onClick click handler from LanguageSelect instance
*
* @returns component stateless
*/
const LanguageOption = ({ language, value, selectedLanguage, onClick }) => (
<li className={selectedLanguage === value ? 'selected' : null}>
<a onClick={onClick} data-language={value}>
<LanguageNode name={language.inLocal} flag={language.flag} />
</a>
</li>
);
/**
* Presentational component
* A dropdown to select a language. Clicking/tapping the dropdown trigger
* opens a dropdown list of languages that render flag icons and the language
* name written in its native language.
*
* @param object languages - object map of language values
* input object example:
* { 'en': { inEnglish: 'English', inLocal: 'English', flag: '🇬🇧' } }
* @param function onSelect - event handler
* @param string selectedLanguage - language that is selected
*
* @returns component
*/
class LanguageSelect extends React.Component {
constructor(props) {
const { languages, selectedLanguage, onSelect } = props;
super(props);
this.languages = languages;
this.state = {
selectedLanguage,
dropdownOpen: false,
};
this.onSelect = onSelect;
['toggleDropdown', 'selectLanguage'].forEach((method) => {
this[method] = this[method].bind(this);
});
}
toggleDropdown(e) {
e.preventDefault();
const isOpened = !this.state.dropdownOpen;
this.setState({ dropdownOpen: isOpened });
}
selectLanguage(e) {
e.preventDefault();
const selectedLanguage = e.target.dataset.language;
this.setState({
dropdownOpen: false,
selectedLanguage,
});
this.onSelect(selectedLanguage);
}
render() {
const { selectedLanguage, dropdownOpen } = this.state;
const selectedOption = this.languages[selectedLanguage] || this.languages[Object.keys(this.languages)[0]];
return (
<div className='language_select'>
<a onClick={this.toggleDropdown}>
<LanguageNode name={selectedOption.inLocal} flag={selectedOption.flag} />
</a>
<ul className={dropdownOpen ? 'visible' : null}>
{Object.keys(this.languages).map((language) => (
<LanguageOption
key={`language_${language}`}
language={this.languages[language]}
value={language}
selectedLanguage={selectedLanguage}
onClick={this.selectLanguage} />))}
</ul>
</div>
);
}
}
LanguageSelect.defaultProps = {
selectedLanguage: '',
};
LanguageSelect.propTypes = {
languages: PropTypes.objectOf(PropTypes.shape({
inEnglish: PropTypes.string,
inLocal: PropTypes.string,
flag: PropTypes.string,
})).isRequired,
selectedLanguage: PropTypes.string,
onSelect: PropTypes.func,
};
export default LanguageSelect;
|