]> Untitled Git - lemmy-ui.git/blob - src/shared/components/common/language-select.tsx
Hide create community (#787)
[lemmy-ui.git] / src / shared / components / common / language-select.tsx
1 import { Option } from "@sniptt/monads";
2 import classNames from "classnames";
3 import { Component, linkEvent } from "inferno";
4 import { Language } from "lemmy-js-client";
5 import { i18n } from "../../i18next";
6 import { randomStr } from "../../utils";
7 import { Icon } from "./icon";
8
9 interface LanguageSelectProps {
10   allLanguages: Language[];
11   selectedLanguageIds: Option<number[]>;
12   multiple: boolean;
13   onChange(val: number[]): any;
14 }
15
16 export class LanguageSelect extends Component<LanguageSelectProps, any> {
17   private id = `language-select-${randomStr()}`;
18
19   constructor(props: any, context: any) {
20     super(props, context);
21   }
22
23   componentDidMount() {
24     this.setSelectedValues();
25   }
26
27   // Necessary because there is no HTML way to set selected for multiple in value=
28   setSelectedValues() {
29     this.props.selectedLanguageIds.map(toString).match({
30       some: ids => {
31         var select = (document.getElementById(this.id) as HTMLSelectElement)
32           .options;
33         for (let i = 0; i < select.length; i++) {
34           let o = select[i];
35           if (ids.includes(o.value)) {
36             o.selected = true;
37           }
38         }
39       },
40       none: void 0,
41     });
42   }
43
44   render() {
45     let selectedLangs = this.props.selectedLanguageIds;
46
47     return (
48       <div className="form-group row">
49         <label
50           className={classNames("col-form-label", {
51             "col-sm-3": this.props.multiple,
52             "col-sm-2": !this.props.multiple,
53           })}
54           htmlFor={this.id}
55         >
56           {i18n.t(this.props.multiple ? "language_plural" : "language")}
57         </label>
58         <div
59           className={classNames("input-group", {
60             "col-sm-9": this.props.multiple,
61             "col-sm-10": !this.props.multiple,
62           })}
63         >
64           <select
65             className="form-control custom-select"
66             id={this.id}
67             onChange={linkEvent(this, this.handleLanguageChange)}
68             aria-label="action"
69             multiple={this.props.multiple}
70           >
71             {this.props.allLanguages.map(l => (
72               <option
73                 key={l.id}
74                 value={l.id}
75                 selected={selectedLangs.unwrapOr([]).includes(l.id)}
76               >
77                 {l.name}
78               </option>
79             ))}
80           </select>
81           {this.props.multiple && (
82             <div className="input-group-append">
83               <button
84                 className="input-group-text"
85                 onClick={linkEvent(this, this.handleDeselectAll)}
86               >
87                 <Icon icon="x" />
88               </button>
89             </div>
90           )}
91         </div>
92       </div>
93     );
94   }
95
96   handleLanguageChange(i: LanguageSelect, event: any) {
97     let options: HTMLOptionElement[] = Array.from(event.target.options);
98     let selected: number[] = options
99       .filter(o => o.selected)
100       .map(o => Number(o.value));
101
102     i.props.onChange(selected);
103   }
104
105   handleDeselectAll(i: LanguageSelect, event: any) {
106     event.preventDefault();
107     i.props.onChange([]);
108   }
109 }