Skip to content

Commit

Permalink
feat(PhoneNumber): add filter for showing e.g. only Scandinavia count…
Browse files Browse the repository at this point in the history
…ries
  • Loading branch information
tujoworker committed Dec 1, 2023
1 parent 56e2f08 commit d67c654
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,17 @@ export const ValidationRequired = () => {
</ComponentBox>
)
}

export const WithFilter = () => {
return (
<ComponentBox>
<Field.PhoneNumber
label="Label text"
onChange={(...args) => console.log('onChange', ...args)}
filterCountries={({ regions }) =>
regions && regions.includes('Scandinavia')
}
/>
</ComponentBox>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ import * as Examples from './Examples'

<Examples.LabelAndValue />

### Show only Scandinavia countries

<Examples.WithFilter />

### With help

<Examples.WithHelp />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,34 @@ The default country code is set to `+47`.
Creating a list of all possible phone numbers would be impractical due to the vast number of combinations, especially considering the various country codes, area codes, and local numbers. Additionally, new numbers are constantly being allocated, and existing numbers may be reassigned over time.

Therefore, the structure and format is only used when `+47` is selected.

## Filter countries

You can filter out the countries based on many possibilities:

- by continent, such as `Europe`.
- by regions, such as `Scandinavia` or `Nordic` countries.
- by iso etc.

Here is the object for Norway:

```json
{
"i18n": {
"en": "Norway",
"nb": "Norge"
},
"cdc": "47",
"iso": "NO",
"continent": "Europe",
"regions": "Scandinavia, Nordic-Northern"
}
```

Here is how you would filter countries:

```jsx
<PhoneNumber
filterCountries={({ regions }) => regions?.includes('Scandinavia')}
/>
```
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ import DataValueReadwriteProperties from '../../data-value-readwrite-properties.

| Property | Type | Description |
| --------------------------------------- | ------------------- | ----------------------------------------------------------------------------------------------------------- |
| `help` | `object` | _(optional)_ Provide a help button. Object consisting of `title` and `contents` |
| `help` | `object` | _(optional)_ Provide a help button. Object consisting of `title` and `contents`. |
| `filterCountries` | `function` | _(optional)_ Show only some countries based your your custom filter. See info section for more details. |
| `countryCodeFieldClassName` | `string` | _(optional)_ Class name for the country code component. |
| `numberFieldClassName` | `string` | _(optional)_ Class name for the number component. |
| `countryCodePlaceholder` | `string` | _(optional)_ Placeholder for the country code field. |
| `countryCodeLabel` | `string` | _(optional)_ Label to show above / before the country code field |
| `countryCodeLabel` | `string` | _(optional)_ Label to show above / before the country code field. |
| `numberMask` | Various | _(optional)_ See property `mask` of the [InputMasked](/uilib/components/input-masked/properties) component. |
| `width` | `string` or `false` | _(optional)_ `large` for predefined standard width, `stretch` for fill available width. |
| [Space](/uilib/layout/space/properties) | Various | _(optional)_ Spacing properties like `top` or `bottom` are supported. |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useMemo, useContext, useCallback, useEffect } from 'react'
import { Autocomplete, Flex } from '../../../../components'
import { InputMaskedProps } from '../../../../components/InputMasked'
import classnames from 'classnames'
import countries from '../../constants/countries'
import countries, { CountryType } from '../../constants/countries'
import StringComponent from '../String'
import { useDataValue } from '../../hooks'
import FieldBlock from '../../FieldBlock'
Expand All @@ -20,7 +20,8 @@ export type Props = FieldHelpProps &
width?: 'large' | 'stretch'
onCountryCodeChange?: (value: string | undefined) => void
onNumberChange?: (value: string | undefined) => void
} & {
filterCountries?: (country: CountryType) => boolean

/**
* For internal testing purposes
*/
Expand Down Expand Up @@ -92,6 +93,7 @@ function PhoneNumber(props: Props) {
updateValue,
onCountryCodeChange,
onNumberChange,
filterCountries,
} = useDataValue(preparedProps)

const countryCodeRef = React.useRef(null)
Expand Down Expand Up @@ -127,9 +129,10 @@ function PhoneNumber(props: Props) {
langRef.current = lang
dataRef.current = getCountryData({
lang,
filter: filterCountries,
})
}
}, [props.value, lang])
}, [props.value, lang, filterCountries])

/**
* On external value change, update the internal,
Expand Down Expand Up @@ -192,12 +195,13 @@ function PhoneNumber(props: Props) {
if (dataRef.current.length < 10) {
dataRef.current = getCountryData({
lang,
filter: filterCountries,
})
updateData(dataRef.current)
}
handleFocus()
},
[handleFocus, lang]
[handleFocus, lang, filterCountries]
)

const isNorway = countryCodeRef.current.includes('47')
Expand Down Expand Up @@ -271,14 +275,6 @@ function PhoneNumber(props: Props) {
)
}

type CountryType = {
cdc: string
iso: string
i18n: {
en: string
}
}

function makeObject(country: CountryType, lang: string) {
return {
selectedKey: `+${country.cdc}`,
Expand All @@ -287,9 +283,22 @@ function makeObject(country: CountryType, lang: string) {
}
}

function getCountryData({ lang = 'en', filter = null } = {}) {
type GetCountryData = {
lang?: string
filter?: Props['filterCountries']
}
function getCountryData({
lang = 'en',
filter = null,
}: GetCountryData = {}) {
return countries
.filter(({ cdc }) => !filter || `+${cdc}` === filter)
.filter((country) => {
if (typeof filter === 'function') {
return filter(country)
}

return !filter || `+${country.cdc}` === filter
})
.sort(({ i18n: a }, { i18n: b }) => (a[lang] > b[lang] ? 1 : -1))
.map((country) => makeObject(country, lang))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -455,4 +455,34 @@ describe('Field.PhoneNumber', () => {
document.querySelector('[role="alert"]')
).not.toBeInTheDocument()
})

it('should filter countries list with given filterCountries', () => {
render(
<PhoneNumber
filterCountries={({ regions }) => regions?.includes('Scandinavia')}
/>
)

const codeElement: HTMLInputElement = document.querySelector(
'.dnb-forms-field-phone-number__country-code input'
)

// open
fireEvent.focus(codeElement)
fireEvent.keyDown(codeElement, {
key: 'Enter',
keyCode: 13,
})

const liElements = document.querySelectorAll('li:not([aria-hidden])')
expect(liElements).toHaveLength(3)
expect(liElements[0].textContent).toBe('+45 Danmark')
expect(liElements[1].textContent).toBe('+47 Norge')
expect(liElements[2].textContent).toBe('+46 Sverige')

expect(
document.querySelector('li.dnb-drawer-list__option--selected')
.textContent
).toBe('+47 Norge')
})
})
21 changes: 20 additions & 1 deletion packages/dnb-eufemia/src/extensions/forms/constants/countries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,18 @@
*
* cdc: Country Dialing Code
*/

export type CountryType = {
cdc: string
iso: string
i18n: {
en: string
nb: string
}
continent: string
regions?: string
}

export default [
{
i18n: {
Expand Down Expand Up @@ -516,6 +528,7 @@ export default [
cdc: '45',
iso: 'DK',
continent: 'Europe',
regions: 'Scandinavia, NorthernNordic',
},
{
i18n: {
Expand Down Expand Up @@ -642,6 +655,7 @@ export default [
cdc: '298',
iso: 'FO',
continent: 'Europe',
regions: 'AutonomousNordic',
},
{
i18n: {
Expand All @@ -660,6 +674,7 @@ export default [
cdc: '358',
iso: 'FI',
continent: 'Europe',
regions: 'NorthernNordic',
},
{
i18n: {
Expand Down Expand Up @@ -759,6 +774,7 @@ export default [
cdc: '299',
iso: 'GL',
continent: 'North America',
regions: 'AutonomousNordic',
},
{
i18n: {
Expand Down Expand Up @@ -876,6 +892,7 @@ export default [
cdc: '354',
iso: 'IS',
continent: 'Europe',
regions: 'NorthernNordic',
},
{
i18n: {
Expand Down Expand Up @@ -1452,6 +1469,7 @@ export default [
cdc: '47',
iso: 'NO',
continent: 'Europe',
regions: 'Scandinavia, NorthernNordic',
},
{
i18n: {
Expand Down Expand Up @@ -1902,6 +1920,7 @@ export default [
cdc: '46',
iso: 'SE',
continent: 'Europe',
regions: 'Scandinavia, NorthernNordic',
},
{
i18n: {
Expand Down Expand Up @@ -2191,4 +2210,4 @@ export default [
iso: 'ZW',
continent: 'Africa',
},
]
] as Array<CountryType>

0 comments on commit d67c654

Please sign in to comment.