From 8ef9c3dfebc1b9c79d2a543e167d77568b34a75e Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Thu, 15 Jul 2021 15:42:11 +0200 Subject: [PATCH] Migrate CountryDropdown to TypeScript --- ...CountryDropdown.js => CountryDropdown.tsx} | 59 +++++++++++-------- src/phonenumber.ts | 8 ++- 2 files changed, 42 insertions(+), 25 deletions(-) rename src/components/views/auth/{CountryDropdown.js => CountryDropdown.tsx} (78%) diff --git a/src/components/views/auth/CountryDropdown.js b/src/components/views/auth/CountryDropdown.tsx similarity index 78% rename from src/components/views/auth/CountryDropdown.js rename to src/components/views/auth/CountryDropdown.tsx index cbc19e0f8d..2e85356e38 100644 --- a/src/components/views/auth/CountryDropdown.js +++ b/src/components/views/auth/CountryDropdown.tsx @@ -19,7 +19,7 @@ import PropTypes from 'prop-types'; import * as sdk from '../../../index'; -import { COUNTRIES, getEmojiFlag } from '../../../phonenumber'; +import { COUNTRIES, getEmojiFlag, PhoneNumberCountryDefinition } from '../../../phonenumber'; import SdkConfig from "../../../SdkConfig"; import { _t } from "../../../languageHandler"; import { replaceableComponent } from "../../../utils/replaceableComponent"; @@ -29,7 +29,7 @@ for (const c of COUNTRIES) { COUNTRIES_BY_ISO2[c.iso2] = c; } -function countryMatchesSearchQuery(query, country) { +function countryMatchesSearchQuery(query: string, country: PhoneNumberCountryDefinition): boolean { // Remove '+' if present (when searching for a prefix) if (query[0] === '+') { query = query.slice(1); @@ -41,15 +41,26 @@ function countryMatchesSearchQuery(query, country) { return false; } -@replaceableComponent("views.auth.CountryDropdown") -export default class CountryDropdown extends React.Component { - constructor(props) { - super(props); - this._onSearchChange = this._onSearchChange.bind(this); - this._onOptionChange = this._onOptionChange.bind(this); - this._getShortOption = this._getShortOption.bind(this); +interface IProps { + value?: string; + onOptionChange: (country: PhoneNumberCountryDefinition) => void; + isSmall: boolean; + showPrefix: boolean; + className?: string; + disabled?: boolean; +} - let defaultCountry = COUNTRIES[0]; +interface IState { + searchQuery: string; + defaultCountry: PhoneNumberCountryDefinition; +} + +@replaceableComponent("views.auth.CountryDropdown") +export default class CountryDropdown extends React.Component { + constructor(props: IProps) { + super(props); + + let defaultCountry: PhoneNumberCountryDefinition = COUNTRIES[0]; const defaultCountryCode = SdkConfig.get()["defaultCountryCode"]; if (defaultCountryCode) { const country = COUNTRIES.find(c => c.iso2 === defaultCountryCode.toUpperCase()); @@ -62,7 +73,7 @@ export default class CountryDropdown extends React.Component { }; } - componentDidMount() { + public componentDidMount(): void { if (!this.props.value) { // If no value is given, we start with the default // country selected, but our parent component @@ -71,21 +82,21 @@ export default class CountryDropdown extends React.Component { } } - _onSearchChange(search) { + private onSearchChange = (search: string): void => { this.setState({ searchQuery: search, }); - } + }; - _onOptionChange(iso2) { + private onOptionChange = (iso2: string): void => { this.props.onOptionChange(COUNTRIES_BY_ISO2[iso2]); - } + }; - _flagImgForIso2(iso2) { + private flagImgForIso2(iso2: string): React.ReactNode { return
{ getEmojiFlag(iso2) }
; } - _getShortOption(iso2) { + private getShortOption = (iso2: string): React.ReactNode => { if (!this.props.isSmall) { return undefined; } @@ -94,12 +105,12 @@ export default class CountryDropdown extends React.Component { countryPrefix = '+' + COUNTRIES_BY_ISO2[iso2].prefix; } return - { this._flagImgForIso2(iso2) } + { this.flagImgForIso2(iso2) } { countryPrefix } ; - } + }; - render() { + public render(): React.ReactNode { const Dropdown = sdk.getComponent('elements.Dropdown'); let displayedCountries; @@ -124,7 +135,7 @@ export default class CountryDropdown extends React.Component { const options = displayedCountries.map((country) => { return
- { this._flagImgForIso2(country.iso2) } + { this.flagImgForIso2(country.iso2) } { _t(country.name) } (+{ country.prefix })
; }); @@ -136,10 +147,10 @@ export default class CountryDropdown extends React.Component { return { return String.fromCodePoint(...countryCode.split('').map(l => UNICODE_BASE + l.charCodeAt(0))); }; -export const COUNTRIES = [ +export interface PhoneNumberCountryDefinition { + iso2: string; + name: string; + prefix: string; +} + +export const COUNTRIES: PhoneNumberCountryDefinition[] = [ { "iso2": "GB", "name": _td("United Kingdom"),