Skip to content

Commit

Permalink
feat: add option to prepend the flag to the country name
Browse files Browse the repository at this point in the history
  • Loading branch information
inigomarquinez committed Feb 28, 2024
1 parent 246aa4a commit 72b4413
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 48 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,9 @@ https://user-images.githubusercontent.com/79102959/134897712-95e4391c-cfbb-42cd-
| blacklist | List of ISO 3166-1 alpha-2 codes of the countries not allowed in the list. This is mutually exclusive with `whitelist` and `whitelist`takes precedence. | string[] | [] |
| priorityOptions | List of ISO 3166-1 alpha-2 codes of the countries to be displayed first in the list. Ex: ['GB', 'ES'] | string[] | [] |
| language | ISO 639-1 code of the language to display countries names. [Available laguages](https://github.com/michaelwittig/node-i18n-iso-countries?tab=readme-ov-file#supported-languages-iso-639-1) | string | en |
| search | Allows the user to search typing in the select control | boolean | false |
| flag | Shows the flag of the country before the name | boolean | false |


### Country v2 example:

Expand Down
22 changes: 19 additions & 3 deletions example/src/forms/Countries/form-new.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "Form with new Country question format",
"title": "Form with new Country question format",
"name": "Form with Country v2 question format",
"title": "Form with Country v2 question format",
"questions": [
{
"name": "country_all",
Expand All @@ -18,14 +18,30 @@
"name": "country_all",
"placeholder": "Select your country",
"type": "country_v2",
"label": "List of original countries with search option",
"label": "List of original countries with flags",
"errorMessages": {
"required": "This field is required"
},
"registerConfig": {
"required": true
},
"config": {
"flag": true
}
},
{
"name": "country_all",
"placeholder": "Select your country",
"type": "country_v2",
"label": "List of original countries with flags and search option",
"errorMessages": {
"required": "This field is required"
},
"registerConfig": {
"required": true
},
"config": {
"flag": true,
"search": true
}
},
Expand Down
4 changes: 2 additions & 2 deletions example/src/forms/Countries/form-old.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "Form with old Country question format",
"title": "Form with old Country question format",
"name": "Form with Country question format",
"title": "Form with Country question format",
"questions": [
{
"name": "country_all",
Expand Down
4 changes: 2 additions & 2 deletions example/src/forms/Countries/styles.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
export default {
container: {
padding: '30px 30px',
padding: '10px 10px',
display: 'flex',
},
formContainer: {
padding: '30px 30px',
padding: '10px 10px',
}
}
98 changes: 58 additions & 40 deletions src/Questions/CountryV2/index.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,61 @@
/** @jsxRuntime classic */
/** @jsx jsx */
import { jsx } from 'theme-ui'
import { getCountryDataList } from 'countries-list'
import { getCountryDataList, getEmojiFlag } from 'countries-list'
import countriesTools from 'i18n-iso-countries'

import ErrorMessage from '../../Fields/Error'
import Select from '../../Fields/Select'
import Label from '../../Fields/Label'
import { useState } from 'react'

// TODO: import all languages
countriesTools.registerLocale(require('i18n-iso-countries/langs/en.json'))
countriesTools.registerLocale(require('i18n-iso-countries/langs/es.json'))
countriesTools.registerLocale(require('i18n-iso-countries/langs/fr.json'))

const buildCountryOptions = (config, language) => {
const priorityOptions = config?.priorityOptions || []
const whitelist = config?.whitelist || []
const blacklist = config?.blacklist || []
const flag = config?.flag || false

let finalListOfCountries = getCountryDataList()

// whitelist and blacklist are mutually exclusive
if (whitelist.length > 0) {
finalListOfCountries = finalListOfCountries.filter((country) => whitelist.includes(country.iso2))
} else if (blacklist.length > 0) {
finalListOfCountries = finalListOfCountries.filter((country) => !blacklist.includes(country.iso2))
}

// translate the country names and sort them by translated name
finalListOfCountries = finalListOfCountries.map((country) => ({
value: country.iso2,
label: countriesTools.getName(country.iso2, language) || country.name
})).sort((a, b) => a.label.localeCompare(b.label))

// sort the countries by priority
if (priorityOptions.length > 0) {
priorityOptions.toReversed().forEach((isoCountryCode) => {
const foundIndex = finalListOfCountries.findIndex((country) => country.value.toLowerCase() === isoCountryCode.toLowerCase())
if (foundIndex !== -1) {
const foundCountry = finalListOfCountries[foundIndex]
finalListOfCountries.splice(foundIndex, 1);
finalListOfCountries.unshift(foundCountry)
}
})
}

if (flag) {
finalListOfCountries = finalListOfCountries.map((country) => {
const emoji = getEmojiFlag(country.value)
return {
...country,
label: emoji + ' ' + country.label
}
})
}

return finalListOfCountries
}

const QuestionCountryV2 = ({
component,
Expand All @@ -21,6 +65,15 @@ const QuestionCountryV2 = ({
language,
...props
}) => {
useState(() => {
try {
countriesTools.registerLocale(require(`i18n-iso-countries/langs/${language}.json`))
} catch (e) {
// eslint-disable-next-line no-console
console.error('@onebeyond/react-form-builder: language not supported for country names. Using English.')
}
}, [language])

const {
formState: { errors },
trigger,
Expand All @@ -29,41 +82,6 @@ const QuestionCountryV2 = ({
unregister
} = useForm

const buildCountryOptions = (config) => {
const priorityOptions = config?.priorityOptions || []
const whitelist = config?.whitelist || []
const blacklist = config?.blacklist || []

let finalListOfCountries = getCountryDataList()

// whitelist and blacklist are mutually exclusive
if (whitelist.length > 0) {
finalListOfCountries = finalListOfCountries.filter((country) => whitelist.includes(country.iso2))
} else if (blacklist.length > 0) {
finalListOfCountries = finalListOfCountries.filter((country) => !blacklist.includes(country.iso2))
}

// translate the country names and sort them by translated name
finalListOfCountries = finalListOfCountries.map((country) => ({
value: country.iso2,
label: countriesTools.getName(country.iso2, language) || country.name
})).sort((a, b) => a.label.localeCompare(b.label))

// sort the countries by priority
if (priorityOptions.length > 0) {
priorityOptions.toReversed().forEach((isoCountryCode) => {
const foundIndex = finalListOfCountries.findIndex((country) => country.value.toLowerCase() === isoCountryCode.toLowerCase())
if (foundIndex !== -1) {
const foundCountry = finalListOfCountries[foundIndex]
finalListOfCountries.splice(foundIndex, 1);
finalListOfCountries.unshift(foundCountry)
}
})
}

return finalListOfCountries
}

return (
<div
data-testid='question-country'
Expand All @@ -86,7 +104,7 @@ const QuestionCountryV2 = ({
id={question.name}
key={question.name}
name={question.name}
options={buildCountryOptions(question.config || {})}
options={buildCountryOptions(question.config || {}, language || 'en')}
isSearchable={question.config?.search === true}
registerConfig={question.registerConfig}
placeholder={question.placeholder}
Expand Down
2 changes: 1 addition & 1 deletion src/builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const FormBuilder = ({
formErrors = [],
...props
}) => {
const useFormObj = useForm({ defaultValues: { formatDate: '' } })
const useFormObj = useForm()

useEffect(() => {
if (formErrors && formErrors.length > 0) {
Expand Down

0 comments on commit 72b4413

Please sign in to comment.