Skip to content

Commit 8181aa7

Browse files
Merge pull request #10 from adsign/dev
dev to main
2 parents c902195 + 88b8083 commit 8181aa7

File tree

9 files changed

+55
-22
lines changed

9 files changed

+55
-22
lines changed

README.md

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
# Payload CMS Phone Number Plugin
22

33
[![Payload CMS](https://img.shields.io/badge/Payload%20CMS-v3-blue)](https://github.com/payloadcms/payload)
4+
[![NPM Version](https://img.shields.io/npm/v/payload-phone-number-plugin)](https://www.npmjs.com/package/payload-phone-number-plugin)
45

56
This Payload CMS plugin uses [google-libphonenumber](https://github.com/ruimarinho/google-libphonenumber) to format and validate phone numbers.
67

78
![Preview](./src/assets/preview.png)
89

9-
> Admin Panel screenshot of the Phone Number field
10-
1110
## Features
12-
13-
- Built with Payload UI components so it feels native to the Admin UI
14-
- As-you-type formatting
15-
- Validates server-side and client-side
16-
- Support for limiting to only some countries
11+
- Format phone numbers to multiple formats (E.164, national, international)
12+
- As-you-type formatting based on selected country
13+
- Validates phone numbers based on selected country
14+
- Support for limiting selection to only some countries
1715
- Support for setting a default country
18-
- Automatic formatting and region detection when pasting phone numbers
16+
- Automatic formatting and region detection when pasting international phone numbers
17+
- Full TypeScript support with generated phone number types
18+
- Built with Payload UI components so it feels native to the Admin Panel
1919
- i18n support for validation messages (PRs for new languages are welcome)
2020

2121
## Installation
@@ -89,7 +89,7 @@ phoneNumberField({
8989
```ts
9090
phoneNumberField({
9191
name: 'phoneNumber',
92-
label: 'Phone Phone',
92+
label: 'Phone Number',
9393
defaultCountry: 'NO', // Norway will be pre-selected
9494
allowedCountries: ['NO', 'US', 'SE'], // Only these countries will be selectable
9595
})
@@ -107,9 +107,9 @@ phoneNumberField({
107107
})
108108
```
109109

110-
## Creating Records Programmatically
110+
## Creating Documents Programmatically
111111

112-
When creating or updating records, pass the phone number as an E.164 string directly.
112+
When creating or updating documents, pass the phone number as an E.164 string directly. Phone numbers are stored in E.164 format in the database.
113113

114114
The field will handle parsing and validation so it won't save unless it's a valid phone number for that field.
115115

@@ -139,11 +139,11 @@ await fetch('http://localhost:3000/api/employees', {
139139
> [!NOTE]
140140
> You cannot pass a phone number object, only E.164 strings are accepted.
141141
142-
## Querying Phone Numbers by Where
142+
## Querying by Phone Number
143143

144-
When using `payload.find` or database queries, use the E.164 format since phone numbers are stored as E.164 strings:
144+
When using `payload.find` or database queries, use the E.164 format:
145145

146-
```typescript
146+
```ts
147147
const employees = await payload.find({
148148
collection: 'employees',
149149
where: {
@@ -158,7 +158,7 @@ The same applies when using the REST API.
158158

159159
## TypeScript Types
160160

161-
The plugin uses a union type pattern similar to Payload's relationship fields with depth. The field is typed as `string | PhoneNumber`.
161+
The field is typed as `string | PhoneNumber`, similar to Payload's relationship fields with depth.
162162

163163
This is because phone numbers are stored as strings in the database but are transformed into objects when you read them using libphonenumber.
164164

@@ -192,6 +192,6 @@ Example response:
192192

193193
## Additional Information
194194

195-
A region code is a ISO 3166-1 alpha-2 code.
195+
A region code is an ISO 3166-1 alpha-2 code.
196196

197197
List of all valid region codes can be found here: https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements

src/defaults.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ import type { Defaults } from './types.js';
22

33
export const defaults: Defaults = {
44
defaultCountry: 'US',
5+
cellDisplayFormat: 'international',
56
};

src/translations/da.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import type { GenericTranslationsObject } from '@payloadcms/translations';
2+
3+
export const da: GenericTranslationsObject = {
4+
$schema: './translation-schema.json',
5+
'payload-phone-number-plugin': {
6+
phoneNumberRequired: 'Telefonnummer er påkrævet',
7+
invalidPhoneNumber: 'Ugyldigt telefonnummer',
8+
invalidPhoneNumberFormat: 'Ugyldigt telefonnummerformat for landet',
9+
phoneNumberMustBeString: 'Telefonnummer skal være en tekststreng',
10+
phoneNumberCountryNotAllowed: 'Telefonnummer skal være fra et af de tilladte lande',
11+
},
12+
};

src/translations/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,14 @@ import type { GenericTranslationsObject, NestedKeysStripped } from '@payloadcms/
22

33
import { en } from './en.js';
44
import { nb } from './nb.js';
5+
import { sv } from './sv.js';
6+
import { da } from './da.js';
57

68
export const translations = {
79
en,
810
nb,
11+
sv,
12+
da,
913
};
1014

1115
export type PayloadPhoneNumberPluginTranslations = GenericTranslationsObject;

src/translations/sv.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import type { GenericTranslationsObject } from '@payloadcms/translations';
2+
3+
export const sv: GenericTranslationsObject = {
4+
$schema: './translation-schema.json',
5+
'payload-phone-number-plugin': {
6+
phoneNumberRequired: 'Telefonnummer krävs',
7+
invalidPhoneNumber: 'Ogiltigt telefonnummer',
8+
invalidPhoneNumberFormat: 'Ogiltigt telefonnummerformat för landet',
9+
phoneNumberMustBeString: 'Telefonnummer måste vara en textsträng',
10+
phoneNumberCountryNotAllowed: 'Telefonnummer måste vara från ett av de tillåtna länderna',
11+
},
12+
};

src/types.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,14 @@ export type Country = {
2424
};
2525

2626
export type Defaults = {
27+
/**
28+
* @default 'US'
29+
*/
2730
defaultCountry: RegionCode;
31+
/**
32+
* @default 'international'
33+
*/
34+
cellDisplayFormat: CellDisplayFormat;
2835
};
2936

3037
export type { RegionCode };

src/ui/Cell/index.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@ import { useTranslation } from '@payloadcms/ui';
77
import type { FC } from 'react';
88

99
import type { PhoneNumberValue, CellDisplayFormat } from '../../types.js';
10+
import { defaults } from '../../defaults.js';
1011

1112
type PhoneNumberCellProps = DefaultCellComponentProps<TextFieldClient, PhoneNumberValue> & {
1213
cellDisplayFormat?: CellDisplayFormat;
1314
};
1415

15-
export const PhoneNumberCellComponent: FC<PhoneNumberCellProps> = ({ cellData, cellDisplayFormat = 'international', field }) => {
16+
export const PhoneNumberCellComponent: FC<PhoneNumberCellProps> = ({ cellData, cellDisplayFormat = defaults.cellDisplayFormat, field }) => {
1617
const { i18n } = useTranslation();
1718

1819
if (cellData && typeof cellData === 'object' && 'international' in cellData) {

src/ui/Field/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ type PhoneNumberFieldProps = {
2222
} & TextFieldClientProps;
2323

2424
const countryOptions: OptionObject[] = countries.map((country) => ({
25-
label: `${country.emoji} ${country.callingCode} (${country.name.international})`,
25+
label: `${country.name.international} (${country.callingCode})`,
2626
value: country.regionCode,
2727
}));
2828

src/utilities/countries.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1964,9 +1964,5 @@ const allCountries: Record<RegionCode, Country> = {
19641964
};
19651965

19661966
export const countries = Object.values(allCountries).sort((a, b) => {
1967-
const numA = Number(String(a.callingCode).replace('+', ''));
1968-
const numB = Number(String(b.callingCode).replace('+', ''));
1969-
if (numA !== numB) return numA - numB;
1970-
19711967
return a.name.international.localeCompare(b.name.international);
19721968
});

0 commit comments

Comments
 (0)