From 72b4413d844d923f1cb003008d9bfb14a26cf9d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=8D=C3=B1igo=20Marqu=C3=ADnez=20Prado?= <25435858+inigomarquinez@users.noreply.github.com> Date: Wed, 28 Feb 2024 20:56:51 +0100 Subject: [PATCH] feat: add option to prepend the flag to the country name --- README.md | 3 + example/src/forms/Countries/form-new.json | 22 ++++- example/src/forms/Countries/form-old.json | 4 +- example/src/forms/Countries/styles.js | 4 +- src/Questions/CountryV2/index.js | 98 ++++++++++++++--------- src/builder.js | 2 +- 6 files changed, 85 insertions(+), 48 deletions(-) diff --git a/README.md b/README.md index acd4bc71..fe96a3e3 100644 --- a/README.md +++ b/README.md @@ -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: diff --git a/example/src/forms/Countries/form-new.json b/example/src/forms/Countries/form-new.json index 5bfe4a2e..4c181a70 100644 --- a/example/src/forms/Countries/form-new.json +++ b/example/src/forms/Countries/form-new.json @@ -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", @@ -18,7 +18,7 @@ "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" }, @@ -26,6 +26,22 @@ "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 } }, diff --git a/example/src/forms/Countries/form-old.json b/example/src/forms/Countries/form-old.json index 995d42b7..2570abe2 100644 --- a/example/src/forms/Countries/form-old.json +++ b/example/src/forms/Countries/form-old.json @@ -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", diff --git a/example/src/forms/Countries/styles.js b/example/src/forms/Countries/styles.js index c92c5231..34941690 100644 --- a/example/src/forms/Countries/styles.js +++ b/example/src/forms/Countries/styles.js @@ -1,9 +1,9 @@ export default { container: { - padding: '30px 30px', + padding: '10px 10px', display: 'flex', }, formContainer: { - padding: '30px 30px', + padding: '10px 10px', } } diff --git a/src/Questions/CountryV2/index.js b/src/Questions/CountryV2/index.js index 9b001650..20ae1393 100644 --- a/src/Questions/CountryV2/index.js +++ b/src/Questions/CountryV2/index.js @@ -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, @@ -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, @@ -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 (