src/views/shared/Select.js
// @flow
const React = require("react");
import type {Context} from "../types.js";
const {childContextTypes} = require("../Wrapper.js");
type Props = {
name: string,
options: Array<{
value: string,
label: string,
}>,
value?: string | Array<string>,
multi?: boolean,
create?: boolean,
clearable?: boolean,
placeholder?: string,
cache?: boolean,
loadOptions?: (input: string) => Promise<*>,
onChange?: (value: string | Array<string>) => void,
};
class SimpleSelect extends React.Component<Props> {
handleChange(e: SyntheticInputEvent<HTMLSelectElement>) {
if (!(e.target instanceof HTMLSelectElement)) {
return;
}
const {multi, onChange} = this.props;
let {value} = e.target;
const {options} = e.target;
if (multi) {
value = Array.prototype.slice
.call(options)
.filter(option => option.selected)
.map(option => option.value);
}
if (onChange) {
onChange(value);
}
}
render() {
const {
name,
multi,
options,
value,
clearable,
placeholder,
} = this.props;
return (
<select
name={name}
multiple={multi}
value={value}
onChange={e => this.handleChange(e)}
className="form-control"
>
{clearable && !multi && <option value="">{placeholder}</option>}
{options.map(({value, label}) => (
<option key={value} value={value}>
{label}
</option>
))}
</select>
);
}
}
class MultiSelect extends React.Component<
Props,
{
searchValue?: string,
loading: boolean,
options?: Array<{
value: string,
label: string,
}>,
error?: Error,
},
> {
constructor(props) {
super(props);
this.state = {
loading: false,
};
this.labelCache = {};
if (props.cache) {
this.queryCache = {};
}
}
componentDidMount() {
this.boundHandleBlur = (e: Event) => this.handleBlur(e);
document.addEventListener("focusin", this.boundHandleBlur);
document.addEventListener("click", this.boundHandleBlur);
}
componentWillUnmount() {
document.removeEventListener("focusin", this.boundHandleBlur);
document.removeEventListener("click", this.boundHandleBlur);
}
context: Context;
control: ?HTMLElement;
input: ?HTMLInputElement;
boundHandleBlur: (e: Event) => void;
labelCache: {
[value: string]: string,
};
queryCache: {
[query: string]: Array<{
value: string,
label: string,
}>,
};
handleBlur(e: Event) {
const {target} = e;
const {searchValue} = this.state;
if (
searchValue !== undefined &&
(!target ||
(target instanceof Node &&
this.control &&
!this.control.contains(target) &&
document.documentElement &&
document.documentElement.contains(target)))
) {
this.closeMenu();
}
}
getNameByValue(value: string): string {
if (this.labelCache[value]) {
return this.labelCache[value];
}
const {options} = this.props;
const result = options.find(option => option.value === value);
if (result) {
return result.label;
}
return value;
}
addValue(addedValue: string, addedLabel: string) {
const {onChange, value} = this.props;
if ((!value || Array.isArray(value)) && onChange) {
this.labelCache[addedValue] = addedLabel;
onChange(
value
? value.includes(addedValue)
? value
: value.concat(addedValue)
: [addedValue],
);
this.clear();
if (this.input) {
this.input.focus();
}
this.handleInput("");
}
}
removeValue(removedValue: string) {
const {onChange, value} = this.props;
if (value && Array.isArray(value) && onChange) {
onChange(value.filter(value => value !== removedValue));
}
}
clear() {
if (this.input) {
this.input.value = "";
}
this.setState({searchValue: ""});
}
getFilteredOptions() {
const {value} = this.props;
const {options} = this.state;
if (!options) {
return [];
}
return options.filter(
option => !value || !value.includes(option.value),
);
}
handleKey(e: SyntheticKeyboardEvent<HTMLInputElement>) {
if (
e.target instanceof HTMLInputElement &&
(e.key === "Enter" || e.key === "Tab")
) {
const {create} = this.props;
const {searchValue} = this.state;
const {value} = e.target;
if (value) {
const options = this.getFilteredOptions();
if (options.length > 0) {
this.addValue(options[0].value, options[0].label);
} else if (create && searchValue) {
this.addValue(searchValue, searchValue);
}
e.preventDefault();
}
}
}
handleInput(searchValue: string) {
const {loadOptions, options} = this.props;
this.setState({
searchValue,
error: undefined,
options: undefined,
loading: false,
});
if (searchValue === undefined) {
return;
}
if (loadOptions) {
if (this.queryCache && this.queryCache[searchValue]) {
return this.setState({
options: this.queryCache[searchValue],
});
}
this.setState({loading: true});
loadOptions(searchValue)
.then(options => {
if (this.state.searchValue === searchValue) {
this.queryCache[searchValue] = options;
this.setState({options, loading: false});
}
})
.catch(error => {
if (this.state.searchValue === searchValue) {
this.setState({error, loading: false});
}
});
} else {
const search = new RegExp(
latinize(searchValue)
.split("")
.map(char => (/\W/.test(char) ? `\\${char}` : char))
.join(".*"),
"i",
);
this.setState({
options: options.filter(option =>
search.test(latinize(option.label)),
),
});
}
}
closeMenu() {
this.setState({searchValue: undefined});
}
renderMenu() {
const {create} = this.props;
const {searchValue, options, error} = this.state;
const {gettext, format} = this.context;
if (searchValue === undefined) {
return null;
}
if (error) {
return (
<div style={{marginTop: "8px"}}>
<span className="label label-danger">
{gettext("Error loading options.")}
</span>
</div>
);
}
if (!options) {
return (
<div style={{marginTop: "8px"}}>
<span className="label label-default">
{gettext("Loading...")}
</span>
</div>
);
}
const filteredOptions = this.getFilteredOptions();
if (filteredOptions.length === 0 && !create) {
return (
<div style={{marginTop: "8px"}}>
<span className="label label-default">
{gettext("No results found.")}
</span>
</div>
);
}
return (
<ul
className="dropdown-menu"
style={{
display: "block",
position: "static",
width: "100%",
height: "150px",
overflow: "auto",
boxShadow: "none",
marginTop: "8px",
}}
>
{filteredOptions.map((option, i) => (
<li
key={option.value}
className={i === 0 && searchValue ? "active" : ""}
>
<a
href="javascript: void(0)"
onClick={e => {
e.preventDefault();
this.addValue(option.value, option.label);
}}
>
{option.label}
</a>
</li>
))}
{create &&
searchValue && (
<li
className={
filteredOptions.length === 0 ? "active" : ""
}
>
<a
href="javascript: void(0)"
onClick={e => {
e.preventDefault();
this.addValue(searchValue, searchValue);
}}
>
{format(gettext("Add %(value)s..."), {
value: searchValue,
})}
</a>
</li>
)}
</ul>
);
}
renderValue() {
const {name, value} = this.props;
if (!value || !Array.isArray(value) || value.length === 0) {
return null;
}
return (
<div>
{value.map(value => (
<span key={value}>
<input type="hidden" name={name} value={value} />
<button
type="button"
className="btn btn-default btn-xs"
onClick={() => this.removeValue(value)}
style={{marginTop: "8px"}}
>
<span
className="glyphicon glyphicon-remove"
aria-hidden="true"
/>{" "}
{this.getNameByValue(value)}
</button>{" "}
</span>
))}
</div>
);
}
render() {
const {placeholder} = this.props;
return (
<div
ref={r => {
this.control = r;
}}
>
<div>
<input
ref={r => {
this.input = r;
}}
type="text"
placeholder={placeholder}
className="form-control"
onKeyDown={e => this.handleKey(e)}
onInput={e => this.handleInput(e.target.value)}
onFocus={e => this.handleInput(e.target.value)}
/>
</div>
{this.renderMenu()}
{this.renderValue()}
</div>
);
}
}
MultiSelect.contextTypes = childContextTypes;
class Select extends React.Component<
Props,
{
value?: string | Array<string>,
},
> {
constructor(props: Props) {
super(props);
this.state = {
value:
props.multi && !Array.isArray(props.value)
? props.value
? [props.value]
: []
: props.value,
};
}
context: Context;
handleChange(value: string | Array<string>) {
this.setState({value});
if (this.props.onChange) {
this.props.onChange(value);
}
}
render() {
const {multi, create, loadOptions, placeholder} = this.props;
const {gettext} = this.context;
let Selector = SimpleSelect;
if (multi || create || loadOptions) {
Selector = MultiSelect;
}
return (
<Selector
{...this.props}
value={this.state.value}
onChange={value => this.handleChange(value)}
placeholder={placeholder || gettext("Select...")}
/>
);
}
}
Select.contextTypes = childContextTypes;
const latinize = str => str.replace(/[^A-Za-z0-9[\] ]/g, a => latinMap[a] || a);
// prettier-ignore
const latinMap = {
"Á": "A",
"Ă": "A",
"Ắ": "A",
"Ặ": "A",
"Ằ": "A",
"Ẳ": "A",
"Ẵ": "A",
"Ǎ": "A",
"Â": "A",
"Ấ": "A",
"Ậ": "A",
"Ầ": "A",
"Ẩ": "A",
"Ẫ": "A",
"Ä": "A",
"Ǟ": "A",
"Ȧ": "A",
"Ǡ": "A",
"Ạ": "A",
"Ȁ": "A",
"À": "A",
"Ả": "A",
"Ȃ": "A",
"Ā": "A",
"Ą": "A",
"Å": "A",
"Ǻ": "A",
"Ḁ": "A",
"Ⱥ": "A",
"Ã": "A",
"Ꜳ": "AA",
"Æ": "AE",
"Ǽ": "AE",
"Ǣ": "AE",
"Ꜵ": "AO",
"Ꜷ": "AU",
"Ꜹ": "AV",
"Ꜻ": "AV",
"Ꜽ": "AY",
"Ḃ": "B",
"Ḅ": "B",
"Ɓ": "B",
"Ḇ": "B",
"Ƀ": "B",
"Ƃ": "B",
"Ć": "C",
"Č": "C",
"Ç": "C",
"Ḉ": "C",
"Ĉ": "C",
"Ċ": "C",
"Ƈ": "C",
"Ȼ": "C",
"Ď": "D",
"Ḑ": "D",
"Ḓ": "D",
"Ḋ": "D",
"Ḍ": "D",
"Ɗ": "D",
"Ḏ": "D",
"Dz": "D",
"Dž": "D",
"Đ": "D",
"Ƌ": "D",
"DZ": "DZ",
"DŽ": "DZ",
"É": "E",
"Ĕ": "E",
"Ě": "E",
"Ȩ": "E",
"Ḝ": "E",
"Ê": "E",
"Ế": "E",
"Ệ": "E",
"Ề": "E",
"Ể": "E",
"Ễ": "E",
"Ḙ": "E",
"Ë": "E",
"Ė": "E",
"Ẹ": "E",
"Ȅ": "E",
"È": "E",
"Ẻ": "E",
"Ȇ": "E",
"Ē": "E",
"Ḗ": "E",
"Ḕ": "E",
"Ę": "E",
"Ɇ": "E",
"Ẽ": "E",
"Ḛ": "E",
"Ꝫ": "ET",
"Ḟ": "F",
"Ƒ": "F",
"Ǵ": "G",
"Ğ": "G",
"Ǧ": "G",
"Ģ": "G",
"Ĝ": "G",
"Ġ": "G",
"Ɠ": "G",
"Ḡ": "G",
"Ǥ": "G",
"Ḫ": "H",
"Ȟ": "H",
"Ḩ": "H",
"Ĥ": "H",
"Ⱨ": "H",
"Ḧ": "H",
"Ḣ": "H",
"Ḥ": "H",
"Ħ": "H",
"Í": "I",
"Ĭ": "I",
"Ǐ": "I",
"Î": "I",
"Ï": "I",
"Ḯ": "I",
"İ": "I",
"Ị": "I",
"Ȉ": "I",
"Ì": "I",
"Ỉ": "I",
"Ȋ": "I",
"Ī": "I",
"Į": "I",
"Ɨ": "I",
"Ĩ": "I",
"Ḭ": "I",
"Ꝺ": "D",
"Ꝼ": "F",
"Ᵹ": "G",
"Ꞃ": "R",
"Ꞅ": "S",
"Ꞇ": "T",
"Ꝭ": "IS",
"Ĵ": "J",
"Ɉ": "J",
"Ḱ": "K",
"Ǩ": "K",
"Ķ": "K",
"Ⱪ": "K",
"Ꝃ": "K",
"Ḳ": "K",
"Ƙ": "K",
"Ḵ": "K",
"Ꝁ": "K",
"Ꝅ": "K",
"Ĺ": "L",
"Ƚ": "L",
"Ľ": "L",
"Ļ": "L",
"Ḽ": "L",
"Ḷ": "L",
"Ḹ": "L",
"Ⱡ": "L",
"Ꝉ": "L",
"Ḻ": "L",
"Ŀ": "L",
"Ɫ": "L",
"Lj": "L",
"Ł": "L",
"LJ": "LJ",
"Ḿ": "M",
"Ṁ": "M",
"Ṃ": "M",
"Ɱ": "M",
"Ń": "N",
"Ň": "N",
"Ņ": "N",
"Ṋ": "N",
"Ṅ": "N",
"Ṇ": "N",
"Ǹ": "N",
"Ɲ": "N",
"Ṉ": "N",
"Ƞ": "N",
"Nj": "N",
"Ñ": "N",
"NJ": "NJ",
"Ó": "O",
"Ŏ": "O",
"Ǒ": "O",
"Ô": "O",
"Ố": "O",
"Ộ": "O",
"Ồ": "O",
"Ổ": "O",
"Ỗ": "O",
"Ö": "O",
"Ȫ": "O",
"Ȯ": "O",
"Ȱ": "O",
"Ọ": "O",
"Ő": "O",
"Ȍ": "O",
"Ò": "O",
"Ỏ": "O",
"Ơ": "O",
"Ớ": "O",
"Ợ": "O",
"Ờ": "O",
"Ở": "O",
"Ỡ": "O",
"Ȏ": "O",
"Ꝋ": "O",
"Ꝍ": "O",
"Ō": "O",
"Ṓ": "O",
"Ṑ": "O",
"Ɵ": "O",
"Ǫ": "O",
"Ǭ": "O",
"Ø": "O",
"Ǿ": "O",
"Õ": "O",
"Ṍ": "O",
"Ṏ": "O",
"Ȭ": "O",
"Ƣ": "OI",
"Ꝏ": "OO",
"Ɛ": "E",
"Ɔ": "O",
"Ȣ": "OU",
"Ṕ": "P",
"Ṗ": "P",
"Ꝓ": "P",
"Ƥ": "P",
"Ꝕ": "P",
"Ᵽ": "P",
"Ꝑ": "P",
"Ꝙ": "Q",
"Ꝗ": "Q",
"Ŕ": "R",
"Ř": "R",
"Ŗ": "R",
"Ṙ": "R",
"Ṛ": "R",
"Ṝ": "R",
"Ȑ": "R",
"Ȓ": "R",
"Ṟ": "R",
"Ɍ": "R",
"Ɽ": "R",
"Ꜿ": "C",
"Ǝ": "E",
"Ś": "S",
"Ṥ": "S",
"Š": "S",
"Ṧ": "S",
"Ş": "S",
"Ŝ": "S",
"Ș": "S",
"Ṡ": "S",
"Ṣ": "S",
"Ṩ": "S",
"Ť": "T",
"Ţ": "T",
"Ṱ": "T",
"Ț": "T",
"Ⱦ": "T",
"Ṫ": "T",
"Ṭ": "T",
"Ƭ": "T",
"Ṯ": "T",
"Ʈ": "T",
"Ŧ": "T",
"Ɐ": "A",
"Ꞁ": "L",
"Ɯ": "M",
"Ʌ": "V",
"Ꜩ": "TZ",
"Ú": "U",
"Ŭ": "U",
"Ǔ": "U",
"Û": "U",
"Ṷ": "U",
"Ü": "U",
"Ǘ": "U",
"Ǚ": "U",
"Ǜ": "U",
"Ǖ": "U",
"Ṳ": "U",
"Ụ": "U",
"Ű": "U",
"Ȕ": "U",
"Ù": "U",
"Ủ": "U",
"Ư": "U",
"Ứ": "U",
"Ự": "U",
"Ừ": "U",
"Ử": "U",
"Ữ": "U",
"Ȗ": "U",
"Ū": "U",
"Ṻ": "U",
"Ų": "U",
"Ů": "U",
"Ũ": "U",
"Ṹ": "U",
"Ṵ": "U",
"Ꝟ": "V",
"Ṿ": "V",
"Ʋ": "V",
"Ṽ": "V",
"Ꝡ": "VY",
"Ẃ": "W",
"Ŵ": "W",
"Ẅ": "W",
"Ẇ": "W",
"Ẉ": "W",
"Ẁ": "W",
"Ⱳ": "W",
"Ẍ": "X",
"Ẋ": "X",
"Ý": "Y",
"Ŷ": "Y",
"Ÿ": "Y",
"Ẏ": "Y",
"Ỵ": "Y",
"Ỳ": "Y",
"Ƴ": "Y",
"Ỷ": "Y",
"Ỿ": "Y",
"Ȳ": "Y",
"Ɏ": "Y",
"Ỹ": "Y",
"Ź": "Z",
"Ž": "Z",
"Ẑ": "Z",
"Ⱬ": "Z",
"Ż": "Z",
"Ẓ": "Z",
"Ȥ": "Z",
"Ẕ": "Z",
"Ƶ": "Z",
"IJ": "IJ",
"Œ": "OE",
"ᴀ": "A",
"ᴁ": "AE",
"ʙ": "B",
"ᴃ": "B",
"ᴄ": "C",
"ᴅ": "D",
"ᴇ": "E",
"ꜰ": "F",
"ɢ": "G",
"ʛ": "G",
"ʜ": "H",
"ɪ": "I",
"ʁ": "R",
"ᴊ": "J",
"ᴋ": "K",
"ʟ": "L",
"ᴌ": "L",
"ᴍ": "M",
"ɴ": "N",
"ᴏ": "O",
"ɶ": "OE",
"ᴐ": "O",
"ᴕ": "OU",
"ᴘ": "P",
"ʀ": "R",
"ᴎ": "N",
"ᴙ": "R",
"ꜱ": "S",
"ᴛ": "T",
"ⱻ": "E",
"ᴚ": "R",
"ᴜ": "U",
"ᴠ": "V",
"ᴡ": "W",
"ʏ": "Y",
"ᴢ": "Z",
"á": "a",
"ă": "a",
"ắ": "a",
"ặ": "a",
"ằ": "a",
"ẳ": "a",
"ẵ": "a",
"ǎ": "a",
"â": "a",
"ấ": "a",
"ậ": "a",
"ầ": "a",
"ẩ": "a",
"ẫ": "a",
"ä": "a",
"ǟ": "a",
"ȧ": "a",
"ǡ": "a",
"ạ": "a",
"ȁ": "a",
"à": "a",
"ả": "a",
"ȃ": "a",
"ā": "a",
"ą": "a",
"ᶏ": "a",
"ẚ": "a",
"å": "a",
"ǻ": "a",
"ḁ": "a",
"ⱥ": "a",
"ã": "a",
"ꜳ": "aa",
"æ": "ae",
"ǽ": "ae",
"ǣ": "ae",
"ꜵ": "ao",
"ꜷ": "au",
"ꜹ": "av",
"ꜻ": "av",
"ꜽ": "ay",
"ḃ": "b",
"ḅ": "b",
"ɓ": "b",
"ḇ": "b",
"ᵬ": "b",
"ᶀ": "b",
"ƀ": "b",
"ƃ": "b",
"ɵ": "o",
"ć": "c",
"č": "c",
"ç": "c",
"ḉ": "c",
"ĉ": "c",
"ɕ": "c",
"ċ": "c",
"ƈ": "c",
"ȼ": "c",
"ď": "d",
"ḑ": "d",
"ḓ": "d",
"ȡ": "d",
"ḋ": "d",
"ḍ": "d",
"ɗ": "d",
"ᶑ": "d",
"ḏ": "d",
"ᵭ": "d",
"ᶁ": "d",
"đ": "d",
"ɖ": "d",
"ƌ": "d",
"ı": "i",
"ȷ": "j",
"ɟ": "j",
"ʄ": "j",
"dz": "dz",
"dž": "dz",
"é": "e",
"ĕ": "e",
"ě": "e",
"ȩ": "e",
"ḝ": "e",
"ê": "e",
"ế": "e",
"ệ": "e",
"ề": "e",
"ể": "e",
"ễ": "e",
"ḙ": "e",
"ë": "e",
"ė": "e",
"ẹ": "e",
"ȅ": "e",
"è": "e",
"ẻ": "e",
"ȇ": "e",
"ē": "e",
"ḗ": "e",
"ḕ": "e",
"ⱸ": "e",
"ę": "e",
"ᶒ": "e",
"ɇ": "e",
"ẽ": "e",
"ḛ": "e",
"ꝫ": "et",
"ḟ": "f",
"ƒ": "f",
"ᵮ": "f",
"ᶂ": "f",
"ǵ": "g",
"ğ": "g",
"ǧ": "g",
"ģ": "g",
"ĝ": "g",
"ġ": "g",
"ɠ": "g",
"ḡ": "g",
"ᶃ": "g",
"ǥ": "g",
"ḫ": "h",
"ȟ": "h",
"ḩ": "h",
"ĥ": "h",
"ⱨ": "h",
"ḧ": "h",
"ḣ": "h",
"ḥ": "h",
"ɦ": "h",
"ẖ": "h",
"ħ": "h",
"ƕ": "hv",
"í": "i",
"ĭ": "i",
"ǐ": "i",
"î": "i",
"ï": "i",
"ḯ": "i",
"ị": "i",
"ȉ": "i",
"ì": "i",
"ỉ": "i",
"ȋ": "i",
"ī": "i",
"į": "i",
"ᶖ": "i",
"ɨ": "i",
"ĩ": "i",
"ḭ": "i",
"ꝺ": "d",
"ꝼ": "f",
"ᵹ": "g",
"ꞃ": "r",
"ꞅ": "s",
"ꞇ": "t",
"ꝭ": "is",
"ǰ": "j",
"ĵ": "j",
"ʝ": "j",
"ɉ": "j",
"ḱ": "k",
"ǩ": "k",
"ķ": "k",
"ⱪ": "k",
"ꝃ": "k",
"ḳ": "k",
"ƙ": "k",
"ḵ": "k",
"ᶄ": "k",
"ꝁ": "k",
"ꝅ": "k",
"ĺ": "l",
"ƚ": "l",
"ɬ": "l",
"ľ": "l",
"ļ": "l",
"ḽ": "l",
"ȴ": "l",
"ḷ": "l",
"ḹ": "l",
"ⱡ": "l",
"ꝉ": "l",
"ḻ": "l",
"ŀ": "l",
"ɫ": "l",
"ᶅ": "l",
"ɭ": "l",
"ł": "l",
"lj": "lj",
"ſ": "s",
"ẜ": "s",
"ẛ": "s",
"ẝ": "s",
"ḿ": "m",
"ṁ": "m",
"ṃ": "m",
"ɱ": "m",
"ᵯ": "m",
"ᶆ": "m",
"ń": "n",
"ň": "n",
"ņ": "n",
"ṋ": "n",
"ȵ": "n",
"ṅ": "n",
"ṇ": "n",
"ǹ": "n",
"ɲ": "n",
"ṉ": "n",
"ƞ": "n",
"ᵰ": "n",
"ᶇ": "n",
"ɳ": "n",
"ñ": "n",
"nj": "nj",
"ó": "o",
"ŏ": "o",
"ǒ": "o",
"ô": "o",
"ố": "o",
"ộ": "o",
"ồ": "o",
"ổ": "o",
"ỗ": "o",
"ö": "o",
"ȫ": "o",
"ȯ": "o",
"ȱ": "o",
"ọ": "o",
"ő": "o",
"ȍ": "o",
"ò": "o",
"ỏ": "o",
"ơ": "o",
"ớ": "o",
"ợ": "o",
"ờ": "o",
"ở": "o",
"ỡ": "o",
"ȏ": "o",
"ꝋ": "o",
"ꝍ": "o",
"ⱺ": "o",
"ō": "o",
"ṓ": "o",
"ṑ": "o",
"ǫ": "o",
"ǭ": "o",
"ø": "o",
"ǿ": "o",
"õ": "o",
"ṍ": "o",
"ṏ": "o",
"ȭ": "o",
"ƣ": "oi",
"ꝏ": "oo",
"ɛ": "e",
"ᶓ": "e",
"ɔ": "o",
"ᶗ": "o",
"ȣ": "ou",
"ṕ": "p",
"ṗ": "p",
"ꝓ": "p",
"ƥ": "p",
"ᵱ": "p",
"ᶈ": "p",
"ꝕ": "p",
"ᵽ": "p",
"ꝑ": "p",
"ꝙ": "q",
"ʠ": "q",
"ɋ": "q",
"ꝗ": "q",
"ŕ": "r",
"ř": "r",
"ŗ": "r",
"ṙ": "r",
"ṛ": "r",
"ṝ": "r",
"ȑ": "r",
"ɾ": "r",
"ᵳ": "r",
"ȓ": "r",
"ṟ": "r",
"ɼ": "r",
"ᵲ": "r",
"ᶉ": "r",
"ɍ": "r",
"ɽ": "r",
"ↄ": "c",
"ꜿ": "c",
"ɘ": "e",
"ɿ": "r",
"ś": "s",
"ṥ": "s",
"š": "s",
"ṧ": "s",
"ş": "s",
"ŝ": "s",
"ș": "s",
"ṡ": "s",
"ṣ": "s",
"ṩ": "s",
"ʂ": "s",
"ᵴ": "s",
"ᶊ": "s",
"ȿ": "s",
"ɡ": "g",
"ᴑ": "o",
"ᴓ": "o",
"ᴝ": "u",
"ť": "t",
"ţ": "t",
"ṱ": "t",
"ț": "t",
"ȶ": "t",
"ẗ": "t",
"ⱦ": "t",
"ṫ": "t",
"ṭ": "t",
"ƭ": "t",
"ṯ": "t",
"ᵵ": "t",
"ƫ": "t",
"ʈ": "t",
"ŧ": "t",
"ᵺ": "th",
"ɐ": "a",
"ᴂ": "ae",
"ǝ": "e",
"ᵷ": "g",
"ɥ": "h",
"ʮ": "h",
"ʯ": "h",
"ᴉ": "i",
"ʞ": "k",
"ꞁ": "l",
"ɯ": "m",
"ɰ": "m",
"ᴔ": "oe",
"ɹ": "r",
"ɻ": "r",
"ɺ": "r",
"ⱹ": "r",
"ʇ": "t",
"ʌ": "v",
"ʍ": "w",
"ʎ": "y",
"ꜩ": "tz",
"ú": "u",
"ŭ": "u",
"ǔ": "u",
"û": "u",
"ṷ": "u",
"ü": "u",
"ǘ": "u",
"ǚ": "u",
"ǜ": "u",
"ǖ": "u",
"ṳ": "u",
"ụ": "u",
"ű": "u",
"ȕ": "u",
"ù": "u",
"ủ": "u",
"ư": "u",
"ứ": "u",
"ự": "u",
"ừ": "u",
"ử": "u",
"ữ": "u",
"ȗ": "u",
"ū": "u",
"ṻ": "u",
"ų": "u",
"ᶙ": "u",
"ů": "u",
"ũ": "u",
"ṹ": "u",
"ṵ": "u",
"ᵫ": "ue",
"ꝸ": "um",
"ⱴ": "v",
"ꝟ": "v",
"ṿ": "v",
"ʋ": "v",
"ᶌ": "v",
"ⱱ": "v",
"ṽ": "v",
"ꝡ": "vy",
"ẃ": "w",
"ŵ": "w",
"ẅ": "w",
"ẇ": "w",
"ẉ": "w",
"ẁ": "w",
"ⱳ": "w",
"ẘ": "w",
"ẍ": "x",
"ẋ": "x",
"ᶍ": "x",
"ý": "y",
"ŷ": "y",
"ÿ": "y",
"ẏ": "y",
"ỵ": "y",
"ỳ": "y",
"ƴ": "y",
"ỷ": "y",
"ỿ": "y",
"ȳ": "y",
"ẙ": "y",
"ɏ": "y",
"ỹ": "y",
"ź": "z",
"ž": "z",
"ẑ": "z",
"ʑ": "z",
"ⱬ": "z",
"ż": "z",
"ẓ": "z",
"ȥ": "z",
"ẕ": "z",
"ᵶ": "z",
"ᶎ": "z",
"ʐ": "z",
"ƶ": "z",
"ɀ": "z",
"ff": "ff",
"ffi": "ffi",
"ffl": "ffl",
"fi": "fi",
"fl": "fl",
"ij": "ij",
"œ": "oe",
"st": "st",
"ₐ": "a",
"ₑ": "e",
"ᵢ": "i",
"ⱼ": "j",
"ₒ": "o",
"ᵣ": "r",
"ᵤ": "u",
"ᵥ": "v",
"ₓ": "x",
};
module.exports = Select;