@superdispatch/phones 0.21.13 → 0.21.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/LICENSE +21 -0
  2. package/{pkg/dist-types → dist-types}/index.d.ts +2 -2
  3. package/package.json +14 -40
  4. package/.babelrc.js +0 -5
  5. package/.turbo/turbo-version.log +0 -26
  6. package/pkg/README.md +0 -10
  7. package/pkg/package.json +0 -34
  8. package/playroom.ts +0 -3
  9. package/src/__tests__/index.spec.ts +0 -23
  10. package/src/apn/APN.ts +0 -40
  11. package/src/country-code-metadata/CountryCodeMetadata.spec.ts +0 -1291
  12. package/src/country-code-metadata/CountryCodeMetadata.ts +0 -281
  13. package/src/formatted-phone-number/FormattedPhoneNumber.ts +0 -20
  14. package/src/index.ts +0 -6
  15. package/src/phone-field/PhoneField.playroom.tsx +0 -28
  16. package/src/phone-field/PhoneField.spec.tsx +0 -171
  17. package/src/phone-field/PhoneField.stories.tsx +0 -6
  18. package/src/phone-field/PhoneField.tsx +0 -200
  19. package/src/phone-field/PhoneFieldFlag.tsx +0 -54
  20. package/src/phone-field/PhoneFieldMenu.tsx +0 -53
  21. package/src/phone-field/PhoneFieldMenuItem.spec.tsx +0 -12
  22. package/src/phone-field/PhoneFieldMenuItem.tsx +0 -61
  23. package/src/phone-field/PhoneFieldStartAdornment.tsx +0 -68
  24. package/src/phone-link/PhoneLink.spec.tsx +0 -60
  25. package/src/phone-link/PhoneLink.stories.tsx +0 -9
  26. package/src/phone-link/PhoneLink.tsx +0 -59
  27. package/src/phone-service/PhoneService.spec.ts +0 -277
  28. package/src/phone-service/PhoneService.ts +0 -287
  29. package/src/phone-text/PhoneText.spec.tsx +0 -65
  30. package/src/phone-text/PhoneText.stories.tsx +0 -9
  31. package/src/phone-text/PhoneText.tsx +0 -38
  32. package/tsconfig.json +0 -19
  33. /package/{pkg/dist-node → dist-node}/index.js +0 -0
  34. /package/{pkg/dist-node → dist-node}/index.js.map +0 -0
  35. /package/{pkg/dist-src → dist-src}/apn/APN.js +0 -0
  36. /package/{pkg/dist-src → dist-src}/country-code-metadata/CountryCodeMetadata.js +0 -0
  37. /package/{pkg/dist-src → dist-src}/formatted-phone-number/FormattedPhoneNumber.js +0 -0
  38. /package/{pkg/dist-src → dist-src}/index.js +0 -0
  39. /package/{pkg/dist-src → dist-src}/phone-field/PhoneField.js +0 -0
  40. /package/{pkg/dist-src → dist-src}/phone-field/PhoneFieldFlag.js +0 -0
  41. /package/{pkg/dist-src → dist-src}/phone-field/PhoneFieldMenu.js +0 -0
  42. /package/{pkg/dist-src → dist-src}/phone-field/PhoneFieldMenuItem.js +0 -0
  43. /package/{pkg/dist-src → dist-src}/phone-field/PhoneFieldStartAdornment.js +0 -0
  44. /package/{pkg/dist-src → dist-src}/phone-link/PhoneLink.js +0 -0
  45. /package/{pkg/dist-src → dist-src}/phone-service/PhoneService.js +0 -0
  46. /package/{pkg/dist-src → dist-src}/phone-text/PhoneText.js +0 -0
  47. /package/{pkg/dist-web → dist-web}/index.js +0 -0
  48. /package/{pkg/dist-web → dist-web}/index.js.map +0 -0
@@ -1,277 +0,0 @@
1
- import AwesomePhoneNumber from 'awesome-phonenumber';
2
- import { CountryISO } from '../country-code-metadata/CountryCodeMetadata';
3
- import {
4
- PhoneNumberFormat,
5
- PhoneService,
6
- PhoneValidationRules,
7
- } from '../phone-service/PhoneService';
8
-
9
- test.each([
10
- ['', 'US', ''],
11
- ['5', 'US', '5'],
12
- ['50', 'US', '50'],
13
- ['506', 'US', '506'],
14
- ['506', 'US', '506'],
15
- ['506', 'US', '506'],
16
- ['5062', 'US', '5062'],
17
- ['50623', 'US', '50623'],
18
- ['506234', 'US', '506234'],
19
- ['5062345', 'US', '5062345'],
20
- ['50623456', 'US', '50623456'],
21
- ['506234567', 'US', '506234567'],
22
- ['5062345678', 'US', '506-234-5678'],
23
- ['50623456789', 'US', '50623456789'],
24
- ['506234567890', 'US', '506234567890'],
25
-
26
- ['1', 'US', '1'],
27
- ['15', 'US', '15'],
28
- ['150', 'US', '150'],
29
- ['1506', 'US', '1506'],
30
- ['15062', 'US', '15062'],
31
- ['150623', 'US', '150623'],
32
- ['1506234', 'US', '1506234'],
33
- ['15062345', 'US', '15062345'],
34
- ['150623456', 'US', '150623456'],
35
- ['1506234567', 'US', '1506234567'],
36
- ['15062345678', 'US', '506-234-5678'],
37
- ['150623456789', 'US', '50623456789'],
38
- ['1506234567890', 'US', '506234567890'],
39
-
40
- ['+', 'US', ''],
41
- ['+1', 'US', ''],
42
- ['+15', 'US', '5'],
43
- ['+150', 'US', '50'],
44
- ['+1506', 'US', '506'],
45
- ['+15062', 'US', '5062'],
46
- ['+150623', 'US', '50623'],
47
- ['+1506234', 'US', '506234'],
48
- ['+15062345', 'US', '5062345'],
49
- ['+150623456', 'US', '50623456'],
50
- ['+1506234567', 'US', '506234567'],
51
- ['+15062345678', 'CA', '506-234-5678'],
52
- ['+150623456789', 'US', '50623456789'],
53
- ['+1506234567890', 'US', '506234567890'],
54
- ['+15062345678,+15062345679,+15062345680', 'CA', '506-234-5678'],
55
- ])(
56
- '#getInfo(%p): { country: %p, nationalNumber: %p }',
57
- (input, country, nationalNumber) => {
58
- expect(new PhoneService(AwesomePhoneNumber).getInfo(input)).toEqual({
59
- country,
60
- nationalNumber,
61
- });
62
- },
63
- );
64
-
65
- test.each<
66
- [
67
- input: string,
68
- format: undefined | PhoneNumberFormat,
69
- country: undefined | CountryISO,
70
- expected: string,
71
- ]
72
- >([
73
- // Normalizes national number
74
- ['!+@1#1$', undefined, undefined, '+11'],
75
- ['!+@6#4$1', undefined, undefined, '+641'],
76
-
77
- // Uses `e164` by default
78
- ['', undefined, undefined, ''],
79
- ['5', undefined, undefined, '+15'],
80
- ['50', undefined, undefined, '+150'],
81
- ['506', undefined, undefined, '+1506'],
82
- ['506', undefined, undefined, '+1506'],
83
- ['5062', undefined, undefined, '+15062'],
84
- ['50623', undefined, undefined, '+150623'],
85
- ['506234', undefined, undefined, '+1506234'],
86
- ['5062345', undefined, undefined, '+15062345'],
87
- ['50623456', undefined, undefined, '+150623456'],
88
- ['506234567', undefined, undefined, '+1506234567'],
89
- ['5062345678', undefined, undefined, '+15062345678'],
90
- ['50623456789', undefined, undefined, '+150623456789'],
91
- ['506234567890', undefined, undefined, '+1506234567890'],
92
-
93
- // Formats national with default country
94
- ['', undefined, undefined, ''],
95
- ['5', undefined, undefined, '+15'],
96
- ['50', undefined, undefined, '+150'],
97
- ['506', undefined, undefined, '+1506'],
98
- ['5062', undefined, undefined, '+15062'],
99
- ['50623', undefined, undefined, '+150623'],
100
- ['506234', undefined, undefined, '+1506234'],
101
- ['5062345', undefined, undefined, '+15062345'],
102
- ['50623456', undefined, undefined, '+150623456'],
103
- ['506234567', undefined, undefined, '+1506234567'],
104
- ['5062345678', undefined, undefined, '+15062345678'],
105
- ['50623456789', undefined, undefined, '+150623456789'],
106
- ['506234567890', undefined, undefined, '+1506234567890'],
107
-
108
- // Formats national with provided country
109
- ['', undefined, 'NZ', ''],
110
- ['5', undefined, 'NZ', '+645'],
111
- ['50', undefined, 'NZ', '+6450'],
112
- ['506', undefined, 'NZ', '+64506'],
113
- ['5062', undefined, 'NZ', '+645062'],
114
- ['50623', undefined, 'NZ', '+6450623'],
115
- ['506234', undefined, 'NZ', '+64506234'],
116
- ['5062345', undefined, 'NZ', '+645062345'],
117
- ['50623456', undefined, 'NZ', '+6450623456'],
118
- ['506234567', undefined, 'NZ', '+64506234567'],
119
- ['5062345678', undefined, 'NZ', '+645062345678'],
120
- ['50623456789', undefined, 'NZ', '+6450623456789'],
121
- ['506234567890', undefined, 'NZ', '+64506234567890'],
122
-
123
- ['', 'e164', undefined, ''],
124
- ['+', 'e164', undefined, ''],
125
- ['+1', 'e164', undefined, '+1'],
126
- ['+15', 'e164', undefined, '+15'],
127
- ['+150', 'e164', undefined, '+150'],
128
- ['+1506', 'e164', undefined, '+1506'],
129
- ['+1506', 'e164', undefined, '+1506'],
130
- ['+15062', 'e164', undefined, '+15062'],
131
- ['+150623', 'e164', undefined, '+150623'],
132
- ['+1506234', 'e164', undefined, '+1506234'],
133
- ['+15062345', 'e164', undefined, '+15062345'],
134
- ['+150623456', 'e164', undefined, '+150623456'],
135
- ['+1506234567', 'e164', undefined, '+1506234567'],
136
- ['+15062345678', 'e164', undefined, '+15062345678'],
137
- ['+150623456789', 'e164', undefined, '+150623456789'],
138
- ['+1506234567890', 'e164', undefined, '+1506234567890'],
139
-
140
- ['', 'rfc3966', undefined, ''],
141
- ['+', 'rfc3966', undefined, ''],
142
- ['+1', 'rfc3966', undefined, 'tel:+1'],
143
- ['+15', 'rfc3966', undefined, 'tel:+1-5'],
144
- ['+150', 'rfc3966', undefined, 'tel:+1-50'],
145
- ['+1506', 'rfc3966', undefined, 'tel:+1-506'],
146
- ['+1506', 'rfc3966', undefined, 'tel:+1-506'],
147
- ['+15062', 'rfc3966', undefined, 'tel:+1-5062'],
148
- ['+150623', 'rfc3966', undefined, 'tel:+1-50623'],
149
- ['+1506234', 'rfc3966', undefined, 'tel:+1-506234'],
150
- ['+15062345', 'rfc3966', undefined, 'tel:+1-5062345'],
151
- ['+150623456', 'rfc3966', undefined, 'tel:+1-50623456'],
152
- ['+1506234567', 'rfc3966', undefined, 'tel:+1-506234567'],
153
- ['+15062345678', 'rfc3966', undefined, 'tel:+1-506-234-5678'],
154
- ['+150623456789', 'rfc3966', undefined, 'tel:+1-50623456789'],
155
- ['+1506234567890', 'rfc3966', undefined, 'tel:+1-506234567890'],
156
-
157
- ['', 'national', undefined, ''],
158
- ['+', 'national', undefined, ''],
159
- ['+1', 'national', undefined, ''],
160
- ['+15', 'national', undefined, '5'],
161
- ['+150', 'national', undefined, '50'],
162
- ['+1506', 'national', undefined, '506'],
163
- ['+15062', 'national', undefined, '5062'],
164
- ['+150623', 'national', undefined, '50623'],
165
- ['+1506234', 'national', undefined, '506234'],
166
- ['+15062345', 'national', undefined, '5062345'],
167
- ['+150623456', 'national', undefined, '50623456'],
168
- ['+1506234567', 'national', undefined, '506234567'],
169
- ['+15062345678', 'national', undefined, '506-234-5678'],
170
- ['+150623456789', 'national', undefined, '50623456789'],
171
- ['+1506234567890', 'national', undefined, '506234567890'],
172
-
173
- ['', 'international', undefined, ''],
174
- ['+', 'international', undefined, ''],
175
- ['+1', 'international', undefined, '+1'],
176
- ['+15', 'international', undefined, '+1 5'],
177
- ['+150', 'international', undefined, '+1 50'],
178
- ['+1506', 'international', undefined, '+1 506'],
179
- ['+15062', 'international', undefined, '+1 5062'],
180
- ['+150623', 'international', undefined, '+1 50623'],
181
- ['+1506234', 'international', undefined, '+1 506234'],
182
- ['+15062345', 'international', undefined, '+1 5062345'],
183
- ['+150623456', 'international', undefined, '+1 50623456'],
184
- ['+1506234567', 'international', undefined, '+1 506234567'],
185
- ['+15062345678', 'international', undefined, '+1 506-234-5678'],
186
- ['+150623456789', 'international', undefined, '+1 50623456789'],
187
- ['+1506234567890', 'international', undefined, '+1 506234567890'],
188
- ])('formatPhoneNumber(%p, %p): %p', (input, format, country, phone) => {
189
- expect(
190
- new PhoneService(AwesomePhoneNumber).format(
191
- input,
192
- !format && !country ? undefined : { format, country },
193
- ),
194
- ).toBe(phone);
195
- });
196
-
197
- test.each([
198
- ['', 'unknown'],
199
- ['6', 'unknown'],
200
- ['61', 'too-short'],
201
- ['615-9', 'too-short'],
202
- ['615-99', 'too-short'],
203
- ['615-994', 'too-short'],
204
- ['615-994-3', 'invalid-number'],
205
- ['615-994-33', 'too-short'],
206
- ['615-994-330', 'too-short'],
207
- ['615-994-3300', 'is-possible'],
208
- ['615-994-33001', 'too-long'],
209
- ['1 6', 'unknown'],
210
- ['1 61', 'too-short'],
211
- ['1 615-9', 'too-short'],
212
- ['1 615-99', 'too-short'],
213
- ['1 615-994', 'invalid-number'],
214
- ['1 615-994-3', 'too-short'],
215
- ['1 615-994-33', 'too-short'],
216
- ['1 615-994-330', 'invalid-number'],
217
- ['1 615-994-3300', 'is-possible'],
218
- ['1 615-994-33001', 'too-long'],
219
- ['+1 6', 'unknown'],
220
- ['+1 61', 'too-short'],
221
- ['+1 615-9', 'too-short'],
222
- ['+1 615-99', 'too-short'],
223
- ['+1 615-994', 'too-short'],
224
- ['+1 615-994-3', 'invalid-number'],
225
- ['+1 615-994-33', 'too-short'],
226
- ['+1 615-994-330', 'too-short'],
227
- ['+1 615-994-3300', 'is-possible'],
228
- ['+1 615-994-33001', 'too-long'],
229
-
230
- ['3242225555', 'invalid-number'],
231
- ])('#checkPossibility(%p): %p', (input, expected) => {
232
- expect(new PhoneService(AwesomePhoneNumber).checkPossibility(input)).toBe(
233
- expected,
234
- );
235
- });
236
-
237
- test.each<
238
- [
239
- input: unknown,
240
- rules: undefined | PhoneValidationRules,
241
- expectedMessage: string | undefined,
242
- ]
243
- >([
244
- [' ', undefined, undefined],
245
- [null, undefined, undefined],
246
- [undefined, undefined, undefined],
247
-
248
- ['615-994-3300', undefined, undefined],
249
- ['+1 615-994-3300', undefined, undefined],
250
-
251
- [' ', { required: true }, 'This field is required'],
252
- [null, { required: true }, 'This field is required'],
253
- [undefined, { required: true }, 'This field is required'],
254
- [undefined, { required: true, requiredMessage: 'Required.' }, 'Required.'],
255
-
256
- [
257
- 'Phone: (585) 617-5555 (Home) | (585) 489-6666 (Cell)',
258
- undefined,
259
- 'Invalid phone number',
260
- ],
261
- ['+1', undefined, 'Invalid phone number'],
262
- ['+1', { invalidMessage: 'Invalid.' }, 'Invalid.'],
263
-
264
- ['615', undefined, 'Phone number is too short'],
265
- ['+1 615', undefined, 'Phone number is too short'],
266
- ['+1 615', { tooShortMessage: 'Too short.' }, 'Too short.'],
267
-
268
- ['615-994-3300 00', undefined, 'Phone number is too long'],
269
- ['+1 615-994-3300 00', undefined, 'Phone number is too long'],
270
- ['+1 615-994-3300 00', { tooLongMessage: 'Too long.' }, 'Too long.'],
271
-
272
- ['3242225555', undefined, 'Invalid phone number'],
273
- ])('#validate(%p, %j): %p', (input, rules, expected) => {
274
- expect(new PhoneService(AwesomePhoneNumber).validate(input, rules)).toBe(
275
- expected,
276
- );
277
- });
@@ -1,287 +0,0 @@
1
- import { useMemo } from 'react';
2
- import { APNStatic, APNType, getAPN, loadAPN } from '../apn/APN';
3
- import {
4
- CountryISO,
5
- DEFAULT_COUNTRY,
6
- getCountryCode,
7
- toCountryISO,
8
- } from '../country-code-metadata/CountryCodeMetadata';
9
-
10
- const PLUS_SIGN = '+';
11
- const NON_PHONE_SYMBOLS_PATTERN = /[^+\d]/g;
12
- const PHONE_PATTERN = /^\+?\d+/g;
13
-
14
- function getPrefix(country: CountryISO): string {
15
- return PLUS_SIGN + String(getCountryCode(toCountryISO(country)));
16
- }
17
-
18
- function trim(input: unknown): string | undefined {
19
- return typeof input == 'string' ? input.trim() : undefined;
20
- }
21
-
22
- function normalize(input: unknown): string {
23
- if (typeof input == 'string') {
24
- const matches = input
25
- .replace(NON_PHONE_SYMBOLS_PATTERN, '')
26
- .match(PHONE_PATTERN);
27
- if (matches?.[0]) return matches[0];
28
- }
29
-
30
- return '';
31
- }
32
-
33
- function normalizeNationalNumber(country: CountryISO, input: unknown): string {
34
- const phone = normalize(input);
35
- const prefix = getPrefix(country);
36
-
37
- if (phone.startsWith(PLUS_SIGN)) {
38
- return phone.slice(prefix.length);
39
- }
40
-
41
- return phone;
42
- }
43
-
44
- export type PhoneNumberPossibility =
45
- | 'is-possible'
46
- | 'invalid-country-code'
47
- | 'invalid-number'
48
- | 'too-long'
49
- | 'too-short'
50
- | 'unknown';
51
-
52
- interface PhoneNumberJSON {
53
- valid: boolean;
54
- possible: boolean;
55
- possibility: PhoneNumberPossibility;
56
-
57
- regionCode: CountryISO;
58
- number: {
59
- input: string;
60
- international?: string;
61
- };
62
- }
63
-
64
- export interface PhoneNumberInfo {
65
- country: CountryISO;
66
- nationalNumber: string;
67
- }
68
-
69
- export type PhoneNumberFormat =
70
- | 'e164'
71
- | 'international'
72
- | 'national'
73
- | 'rfc3966';
74
-
75
- export interface PhoneValidationRules {
76
- required?: boolean;
77
- requiredMessage?: string;
78
- tooShortMessage?: string;
79
- tooLongMessage?: string;
80
- invalidMessage?: string;
81
- }
82
-
83
- export interface PhoneFormatOptions {
84
- fallback?: string;
85
- country?: CountryISO;
86
- format?: PhoneNumberFormat;
87
- }
88
-
89
- export class PhoneService {
90
- static load(): Promise<PhoneService> {
91
- return loadAPN().then((APN) => new PhoneService(APN));
92
- }
93
-
94
- static checkPossibility(input: unknown): Promise<PhoneNumberPossibility> {
95
- return this.load().then((phoneService) =>
96
- phoneService.checkPossibility(input),
97
- );
98
- }
99
-
100
- static validate(
101
- input: unknown,
102
- rules?: PhoneValidationRules,
103
- ): Promise<string | undefined> {
104
- return this.load().then((phoneService) =>
105
- phoneService.validate(input, rules),
106
- );
107
- }
108
-
109
- readonly APN;
110
-
111
- constructor(APN: APNStatic) {
112
- this.APN = APN;
113
- }
114
-
115
- createAPN(phone: string, country?: CountryISO): APNType {
116
- const asYouType = this.APN.getAsYouType(toCountryISO(country));
117
-
118
- asYouType.reset(normalize(phone));
119
-
120
- return asYouType.getPhoneNumber();
121
- }
122
-
123
- getJSON(phone: string, country?: CountryISO): PhoneNumberJSON {
124
- return this.createAPN(phone, country).toJSON() as PhoneNumberJSON;
125
- }
126
-
127
- checkPossibility(input: unknown): PhoneNumberPossibility {
128
- const phone = trim(input);
129
-
130
- if (!phone) {
131
- return 'unknown';
132
- }
133
-
134
- const apn = phone.startsWith(PLUS_SIGN)
135
- ? new this.APN(phone)
136
- : new this.APN(phone, DEFAULT_COUNTRY);
137
- const { valid, possible, possibility } = apn.toJSON() as PhoneNumberJSON;
138
-
139
- // Avoid false positive short phone numbers.
140
- if (!valid && possible) {
141
- return 'invalid-number';
142
- }
143
-
144
- return possibility;
145
- }
146
-
147
- validate(
148
- input: unknown,
149
- {
150
- required,
151
- requiredMessage = 'This field is required',
152
- invalidMessage = 'Invalid phone number',
153
- tooLongMessage = 'Phone number is too long',
154
- tooShortMessage = 'Phone number is too short',
155
- }: PhoneValidationRules = {},
156
- ): string | undefined {
157
- const phone = trim(input);
158
-
159
- if (!phone) {
160
- if (required) {
161
- return requiredMessage;
162
- }
163
-
164
- return undefined;
165
- }
166
-
167
- switch (this.checkPossibility(phone)) {
168
- case 'is-possible':
169
- return undefined;
170
- case 'too-long':
171
- return tooLongMessage;
172
- case 'too-short':
173
- return tooShortMessage;
174
- }
175
-
176
- return invalidMessage;
177
- }
178
-
179
- deletePrefix(phone: string, country: CountryISO): string {
180
- const prefix = getPrefix(country);
181
-
182
- if (phone.startsWith(PLUS_SIGN)) {
183
- const subNumber = phone.slice(prefix.length);
184
- return trim(subNumber) as string;
185
- }
186
-
187
- return phone;
188
- }
189
-
190
- getInfo(phone: string): PhoneNumberInfo {
191
- let {
192
- regionCode,
193
- number: { input, international: internationalNumber },
194
- } = this.getJSON(phone);
195
-
196
- let nationalNumber = '';
197
- const country = toCountryISO(regionCode);
198
-
199
- if (!internationalNumber) {
200
- nationalNumber = normalizeNationalNumber(country, input);
201
- } else {
202
- nationalNumber = this.deletePrefix(internationalNumber, country);
203
- }
204
-
205
- return { country, nationalNumber };
206
- }
207
-
208
- format(
209
- input: unknown,
210
- {
211
- fallback = '',
212
- format = 'e164',
213
- country: countryOption,
214
- }: PhoneFormatOptions = {},
215
- ): string {
216
- const phone = normalize(input);
217
-
218
- if (!phone) {
219
- return fallback;
220
- }
221
-
222
- const apn = this.createAPN(phone, countryOption);
223
- const country = countryOption || toCountryISO(apn.getRegionCode());
224
-
225
- const formatted =
226
- format === 'national'
227
- ? this.formatNationalNumber(apn, country)
228
- : apn.getNumber(format);
229
-
230
- if (!formatted) {
231
- return this.customFormat(apn, phone, format);
232
- }
233
-
234
- return formatted;
235
- }
236
-
237
- formatNationalNumber(apn: APNType, country: CountryISO): string | undefined {
238
- const internationalNumber = apn.getNumber('international');
239
-
240
- if (!internationalNumber) {
241
- return undefined;
242
- }
243
-
244
- return this.deletePrefix(internationalNumber, country);
245
- }
246
-
247
- private customFormat(
248
- apn: APNType,
249
- phone: string,
250
- format: PhoneNumberFormat,
251
- ): string {
252
- let formatted = '';
253
- const country = toCountryISO(apn.getRegionCode());
254
-
255
- const nationalNumber = normalizeNationalNumber(country, phone);
256
-
257
- if (format === 'national') {
258
- return nationalNumber;
259
- }
260
-
261
- let prefix = '';
262
- let separator = '';
263
-
264
- if (format === 'rfc3966') {
265
- prefix = 'tel:';
266
- separator = '-';
267
- }
268
-
269
- if (format === 'international') {
270
- separator = ' ';
271
- }
272
-
273
- formatted = prefix + getPrefix(country);
274
-
275
- if (nationalNumber) {
276
- formatted += separator + nationalNumber;
277
- }
278
-
279
- return formatted;
280
- }
281
- }
282
-
283
- export function usePhoneService(): PhoneService {
284
- const APN = getAPN();
285
-
286
- return useMemo(() => new PhoneService(APN), [APN]);
287
- }
@@ -1,65 +0,0 @@
1
- import { renderComponent } from '@superdispatch/ui-testutils';
2
- import { screen, waitFor } from '@testing-library/react';
3
- import { PhoneText } from './PhoneText';
4
-
5
- test('basic', async () => {
6
- const view = renderComponent(<PhoneText phone="+12015550123" />);
7
-
8
- await screen.findByText(/201/);
9
-
10
- expect(view.container).toMatchInlineSnapshot(`
11
- <div>
12
- +1 201-555-0123
13
- </div>
14
- `);
15
- });
16
-
17
- test('format', async () => {
18
- const view = renderComponent(
19
- <PhoneText phone="+12015550123" format="national" />,
20
- );
21
-
22
- await screen.findByText(/201/);
23
-
24
- expect(view.container).toMatchInlineSnapshot(`
25
- <div>
26
- 201-555-0123
27
- </div>
28
- `);
29
- });
30
-
31
- test('country', async () => {
32
- const view = renderComponent(<PhoneText phone="2015550123" country="NZ" />);
33
-
34
- await screen.findByText(/64/);
35
-
36
- expect(view.container).toMatchInlineSnapshot(`
37
- <div>
38
- +64 20 1555 0123
39
- </div>
40
- `);
41
- });
42
-
43
- test('invalid', async () => {
44
- const view = renderComponent(<PhoneText phone="noop" />);
45
-
46
- await waitFor(() => {
47
- expect(screen.queryByText('Suspended…')).toBeNull();
48
- });
49
-
50
- expect(view.container).toMatchInlineSnapshot(`<div />`);
51
- });
52
-
53
- test('fallback', async () => {
54
- const view = renderComponent(<PhoneText phone="noop" fallback="Invalid." />);
55
-
56
- await waitFor(() => {
57
- expect(screen.queryByText('Suspended…')).toBeNull();
58
- });
59
-
60
- expect(view.container).toMatchInlineSnapshot(`
61
- <div>
62
- Invalid.
63
- </div>
64
- `);
65
- });
@@ -1,9 +0,0 @@
1
- import { Meta } from '@storybook/react';
2
- import { PhoneText } from './PhoneText';
3
-
4
- export default { title: 'Phones/PhoneText', component: PhoneText } as Meta;
5
-
6
- export const basic = () => <PhoneText phone="+12015550123" />;
7
- export const fallback = () => (
8
- <PhoneText phone="noop" fallback="Invalid Phone Number" />
9
- );
@@ -1,38 +0,0 @@
1
- import { renderChildren } from '@superdispatch/ui';
2
- import { ReactElement, ReactNode, Suspense } from 'react';
3
- import { CountryISO } from '../country-code-metadata/CountryCodeMetadata';
4
- import { useFormattedPhoneNumber } from '../formatted-phone-number/FormattedPhoneNumber';
5
- import { PhoneNumberFormat } from '../phone-service/PhoneService';
6
-
7
- export interface PhoneTextProps {
8
- phone: unknown;
9
- fallback?: ReactNode;
10
- country?: CountryISO;
11
- format?: PhoneNumberFormat;
12
- }
13
-
14
- export function PhoneText({
15
- phone,
16
- country,
17
- fallback,
18
- format = 'international',
19
- }: PhoneTextProps): null | ReactElement {
20
- const children = useFormattedPhoneNumber(phone, { format, country });
21
-
22
- return renderChildren(children || fallback);
23
- }
24
-
25
- export interface SuspendedPhoneTextProps extends PhoneTextProps {
26
- suspenseFallback?: ReactNode;
27
- }
28
-
29
- export function SuspendedPhoneText({
30
- suspenseFallback = null,
31
- ...props
32
- }: SuspendedPhoneTextProps): ReactElement {
33
- return (
34
- <Suspense fallback={suspenseFallback}>
35
- <PhoneText {...props} />
36
- </Suspense>
37
- );
38
- }
package/tsconfig.json DELETED
@@ -1,19 +0,0 @@
1
- {
2
- "extends": "../../tsconfig.build",
3
- "exclude": [
4
- "pkg",
5
- "playroom.ts",
6
- "**/*.spec.*",
7
- "**/*.stories.*",
8
- "**/*.playroom.*",
9
- "**/__tests__/**",
10
- "**/__testutils__/**"
11
- ],
12
- "references": [{ "path": "../ui" }, { "path": "../__testutils__" }],
13
- "compilerOptions": {
14
- "composite": true,
15
- "rootDir": "src",
16
- "outDir": "pkg/dist-types",
17
- "tsBuildInfoFile": "pkg/dist-types/.tsbuildinfo"
18
- }
19
- }
File without changes