svelte-tel-input 3.2.2 → 3.3.1

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.
package/README.md CHANGED
@@ -26,16 +26,17 @@ npm install --save svelte-tel-input
26
26
  - Prevent non-digits typing into the input, except the leading `+` sign (and `space` optionally).
27
27
  - Handle copy-pasted phone numbers, it's sanitize non-digit characters except the leading `+` sign (and `space` optionally).
28
28
  - Automatic placeholder generation for the selected country.
29
+ - International or National formatted phone numbers.
29
30
 
30
31
  ## Usage
31
32
 
32
33
  ### Advanced
33
34
 
34
- _Snippet would be too long_ - [REPL](https://stackblitz.com/edit/svelte-tel-input-repl-1jfaar?file=README.md) (StackBlitz)
35
+ _Snippet would be too long_ - [Example](https://github.com/gyurielf/svelte-tel-input/blob/main/apps/site/src/lib/components/examples/AdvancedPhoneInput.svelte) - [REPL](https://stackblitz.com/edit/svelte-tel-input-repl-1jfaar?file=README.md) (StackBlitz)
35
36
 
36
37
  ### Basic
37
38
 
38
- [REPL](https://stackblitz.com/edit/svelte-tel-input-repl?file=README.md) (StackBlitz)
39
+ [Example](https://github.com/gyurielf/svelte-tel-input/blob/main/apps/site/src/lib/components/examples/BasicPhoneInput.svelte) - [REPL](https://stackblitz.com/edit/svelte-tel-input-repl?file=README.md) (StackBlitz)
39
40
 
40
41
  ```html
41
42
  <script lang="ts">
@@ -127,7 +128,9 @@ Config options:
127
128
  // Allow or disallow spaces in the input field
128
129
  spaces: true,
129
130
  // If you have a parsed phone number and you change country manually from outside, then it's set the `valid` prop to false.
130
- invalidateOnCountryChange: false
131
+ invalidateOnCountryChange: false,
132
+ // Formatted output `national` | `international`
133
+ format: 'national'
131
134
  }
132
135
  ```
133
136
 
@@ -11,7 +11,8 @@ const dispatch = createEventDispatcher();
11
11
  const defaultOptions = {
12
12
  autoPlaceholder: true,
13
13
  spaces: true,
14
- invalidateOnCountryChange: false
14
+ invalidateOnCountryChange: false,
15
+ format: "national"
15
16
  };
16
17
  export let country;
17
18
  export let value;
@@ -33,9 +34,10 @@ const handleInputAction = (value2) => {
33
34
  handleParsePhoneNumber(value2, country);
34
35
  };
35
36
  const updateCountry = (countryCode) => {
36
- country = countryCode;
37
- prevCountry = countryCode;
38
- dispatch("updateCountry", country);
37
+ if (countryCode !== country) {
38
+ country = prevCountry = countryCode;
39
+ dispatch("updateCountry", country);
40
+ }
39
41
  return country;
40
42
  };
41
43
  const handleParsePhoneNumber = (input, currCountry = null) => {
@@ -59,16 +61,14 @@ const handleParsePhoneNumber = (input, currCountry = null) => {
59
61
  throw err;
60
62
  }
61
63
  }
62
- if (detailedValue?.isValid && combinedOptions.spaces && detailedValue?.formatOriginal) {
63
- if (inputValue === detailedValue?.formatOriginal) {
64
- inputValue = null;
65
- }
66
- inputValue = detailedValue?.formatOriginal;
67
- } else if (detailedValue?.isValid && detailedValue?.nationalNumber) {
68
- if (inputValue === detailedValue?.nationalNumber) {
69
- inputValue = null;
64
+ if (detailedValue?.isValid) {
65
+ const formatOption = combinedOptions.format === "national" ? "nationalNumber" : "e164";
66
+ const formattedValue = combinedOptions.format === "national" ? "formatOriginal" : "formatInternational";
67
+ if (combinedOptions.spaces && detailedValue?.[formattedValue]) {
68
+ inputValue = inputValue === detailedValue[formattedValue] ? null : detailedValue[formattedValue] ?? null;
69
+ } else if (detailedValue?.[formatOption]) {
70
+ inputValue = inputValue === detailedValue[formatOption] ? null : detailedValue[formatOption] ?? null;
70
71
  }
71
- inputValue = detailedValue?.nationalNumber;
72
72
  }
73
73
  value = detailedValue?.e164 ?? input ?? null;
74
74
  valid = detailedValue?.isValid ?? false;
@@ -80,9 +80,7 @@ const handleParsePhoneNumber = (input, currCountry = null) => {
80
80
  prevCountry = currCountry;
81
81
  valid = !options.invalidateOnCountryChange;
82
82
  value = null;
83
- if (inputValue !== null || inputValue !== "") {
84
- inputValue = null;
85
- }
83
+ inputValue = null;
86
84
  detailedValue = null;
87
85
  dispatch("updateValid", valid);
88
86
  dispatch("updateValue", value);
@@ -109,7 +107,10 @@ const countryChangeWatch = watcher(null, countryChangeWatchFunction);
109
107
  $:
110
108
  $countryChangeWatch = country;
111
109
  $:
112
- getPlaceholder = combinedOptions.autoPlaceholder ? country ? generatePlaceholder(country) : null : placeholder;
110
+ getPlaceholder = combinedOptions.autoPlaceholder ? country ? generatePlaceholder(country, {
111
+ format: combinedOptions.format,
112
+ spaces: combinedOptions.spaces
113
+ }) : null : placeholder;
113
114
  $:
114
115
  if (value === null && inputValue !== null && detailedValue !== null) {
115
116
  inputValue = null;
@@ -117,15 +118,8 @@ $:
117
118
  dispatch("updateDetailedValue", detailedValue);
118
119
  }
119
120
  const initialize = () => {
120
- if (value && country) {
121
- handleParsePhoneNumber(value, country);
122
- } else if (value) {
123
- const numberHasCountry = getCountryForPartialE164Number(value);
124
- if (numberHasCountry) {
125
- handleParsePhoneNumber(value, numberHasCountry);
126
- } else {
127
- handleParsePhoneNumber(value, null);
128
- }
121
+ if (value) {
122
+ handleParsePhoneNumber(value, getCountryForPartialE164Number(value) || country);
129
123
  }
130
124
  };
131
125
  onMount(() => {
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { default as TelInput } from './components/Input/TelInput.svelte';
1
+ export { default as TelInput } from './components/input/TelInput.svelte';
2
2
  export { getCurrentCountry, inputParser, inspectAllowedChars, normalizeTelInput, getCountryForPartialE164Number, clickOutsideAction, isSelected } from './utils/index.js';
3
3
  export { parsePhoneNumberWithError, ParseError } from 'libphonenumber-js/max';
4
4
  export { normalizedCountries } from './assets/index.js';
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export { default as TelInput } from './components/Input/TelInput.svelte';
1
+ export { default as TelInput } from './components/input/TelInput.svelte';
2
2
  export { getCurrentCountry, inputParser, inspectAllowedChars, normalizeTelInput, getCountryForPartialE164Number, clickOutsideAction, isSelected } from './utils/index.js';
3
3
  export { parsePhoneNumberWithError, ParseError } from 'libphonenumber-js/max';
4
4
  export { normalizedCountries } from './assets/index.js';
@@ -76,12 +76,11 @@ export interface TelInputOptions {
76
76
  */
77
77
  invalidateOnCountryChange?: boolean;
78
78
  /**
79
- * "formatInternational": "+36 20 123 4567",
80
- * "formatOriginal": "20 123 4567",
81
- * "formatNational": "06 20 123 4567",
82
- * @default 'original'
79
+ * "international": `+36 20 123 4567`,
80
+ * "default": `20 123 4567`
81
+ * @default national
83
82
  */
84
- // format: 'original' | 'national' | 'international';
83
+ format?: 'national' | 'international';
85
84
  }
86
85
 
87
86
  export type {
@@ -5,7 +5,10 @@ export declare const isNumber: (value: number) => boolean;
5
5
  export declare const normalizeTelInput: (input?: PhoneNumber) => {
6
6
  [k: string]: string | boolean | E164Number | import("libphonenumber-js/types").CountryCallingCode | import("libphonenumber-js/types").NationalNumber | null | undefined;
7
7
  };
8
- export declare const generatePlaceholder: (country: CountryCode, format?: 'international' | 'national' | 'default') => string;
8
+ export declare const generatePlaceholder: (country: CountryCode, { format, spaces }?: {
9
+ format: 'international' | 'national';
10
+ spaces: boolean;
11
+ }) => string;
9
12
  export declare const isSelected: <T extends {
10
13
  id: string;
11
14
  }>(itemToSelect: string | T, selectedItem: string | T | null | undefined) => boolean;
@@ -68,6 +71,6 @@ export declare const allowedCharacters: (character: string, { spaces }?: {
68
71
  }) => string;
69
72
  export declare const inputParser: (text: string, { allowSpaces, parseCharacter }: {
70
73
  allowSpaces: boolean;
71
- parseCharacter: (characted: string, val: string, allowSpaces?: boolean) => string;
74
+ parseCharacter: (char: string, val: string, allowSpaces?: boolean) => string | undefined;
72
75
  }) => string;
73
76
  export declare const inspectAllowedChars: (character: string, value: string, allowSpaces?: boolean) => string;
@@ -1,7 +1,9 @@
1
1
  import { AsYouType, Metadata, getCountryCallingCode, getExampleNumber } from 'libphonenumber-js/max';
2
2
  import examples from 'libphonenumber-js/mobile/examples';
3
3
  export const capitalize = (str) => {
4
- return (str && str[0].toUpperCase() + str.slice(1).toLowerCase()) || '';
4
+ if (!str)
5
+ return '';
6
+ return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
5
7
  };
6
8
  // Use carefully, it can be rate limited.
7
9
  export const getCurrentCountry = async () => {
@@ -44,20 +46,24 @@ export const normalizeTelInput = (input) => {
44
46
  }).filter(([, value]) => value !== null));
45
47
  return filteredResult;
46
48
  };
47
- export const generatePlaceholder = (country, format = 'default') => {
49
+ export const generatePlaceholder = (country, { format, spaces } = {
50
+ format: 'national',
51
+ spaces: true
52
+ }) => {
48
53
  const examplePhoneNumber = getExampleNumber(country, examples);
49
54
  if (examplePhoneNumber) {
50
- const countryCallingCode = examplePhoneNumber.countryCallingCode;
51
55
  switch (format) {
52
56
  case 'international':
53
- return examplePhoneNumber.formatInternational();
54
- case 'national':
55
- return examplePhoneNumber.formatNational();
57
+ return spaces
58
+ ? examplePhoneNumber.formatInternational()
59
+ : examplePhoneNumber.number;
56
60
  default:
57
- return examplePhoneNumber
58
- .formatInternational()
59
- .slice(countryCallingCode.length + 1)
60
- .trim();
61
+ return spaces
62
+ ? examplePhoneNumber
63
+ .formatInternational()
64
+ .slice(examplePhoneNumber.countryCallingCode.length + 1)
65
+ .trim()
66
+ : examplePhoneNumber.nationalNumber;
61
67
  }
62
68
  }
63
69
  else {
@@ -65,28 +71,13 @@ export const generatePlaceholder = (country, format = 'default') => {
65
71
  }
66
72
  };
67
73
  export const isSelected = (itemToSelect, selectedItem) => {
68
- if (!selectedItem || selectedItem === null) {
74
+ if (!selectedItem) {
69
75
  return false;
70
76
  }
71
- if (typeof selectedItem === 'object' &&
72
- typeof itemToSelect === 'object' &&
73
- selectedItem !== null &&
74
- itemToSelect !== null) {
75
- if (typeof selectedItem === 'object' &&
76
- typeof itemToSelect === 'object' &&
77
- selectedItem.id === itemToSelect.id) {
78
- return true;
79
- }
80
- else {
81
- return false;
82
- }
83
- }
84
- else if (itemToSelect === selectedItem) {
85
- return true;
86
- }
87
- else {
88
- return false;
77
+ if (typeof selectedItem === 'object' && typeof itemToSelect === 'object') {
78
+ return selectedItem.id === itemToSelect.id;
89
79
  }
80
+ return itemToSelect === selectedItem;
90
81
  };
91
82
  export const getInternationalPhoneNumberPrefix = (country) => {
92
83
  const ONLY_DIGITS_REGEXP = /^\d+$/;
@@ -276,13 +267,11 @@ export const allowedCharacters = (character, { spaces } = {
276
267
  };
277
268
  export const inputParser = (text, { allowSpaces, parseCharacter }) => {
278
269
  let value = '';
279
- let index = 0;
280
- while (index < text.length) {
270
+ for (let index = 0; index < text.length; index++) {
281
271
  const character = parseCharacter(text[index], value, allowSpaces);
282
272
  if (character !== undefined) {
283
273
  value += character;
284
274
  }
285
- index++;
286
275
  }
287
276
  return value;
288
277
  };
@@ -1,4 +1,3 @@
1
1
  export * from './helpers.js';
2
- export * from './typeCheck.js';
3
2
  export * from './directives/clickOutsideAction.js';
4
3
  export * from './directives/telInputAction.js';
@@ -1,4 +1,3 @@
1
1
  export * from './helpers.js';
2
- export * from './typeCheck.js';
3
2
  export * from './directives/clickOutsideAction.js';
4
3
  export * from './directives/telInputAction.js';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "svelte-tel-input",
3
3
  "description": "svelte-tel-input",
4
- "version": "3.2.2",
4
+ "version": "3.3.1",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/gyurielf/svelte-tel-input.git"
@@ -30,45 +30,47 @@
30
30
  "svelte": "^3.58.0 || ^4.0.0"
31
31
  },
32
32
  "dependencies": {
33
- "libphonenumber-js": "^1.10.37"
33
+ "libphonenumber-js": "^1.10.39"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@sveltejs/adapter-auto": "2.1.0",
37
- "@sveltejs/kit": "^1.22.3",
37
+ "@sveltejs/kit": "^1.22.4",
38
38
  "@sveltejs/package": "^2.2.0",
39
39
  "@testing-library/svelte": "^4.0.3",
40
40
  "@testing-library/user-event": "^14.4.3",
41
41
  "@types/micromatch": "^4.0.2",
42
- "@typescript-eslint/eslint-plugin": "^6.1.0",
43
- "@typescript-eslint/parser": "^6.1.0",
42
+ "@typescript-eslint/eslint-plugin": "^6.2.1",
43
+ "@typescript-eslint/parser": "^6.2.1",
44
44
  "autoprefixer": "^10.4.14",
45
45
  "cssnano": "^6.0.1",
46
46
  "dotenv": "^16.3.1",
47
47
  "eslint": "^8.45.0",
48
48
  "eslint-config-prettier": "^8.8.0",
49
- "eslint-plugin-import": "^2.27.5",
49
+ "eslint-plugin-import": "^2.28.0",
50
50
  "eslint-plugin-svelte": "^2.32.4",
51
51
  "jsdom": "^22.1.0",
52
52
  "micromatch": "^4.0.5",
53
53
  "postcss": "^8.4.27",
54
54
  "prettier": "^2.8.8",
55
55
  "prettier-plugin-svelte": "^2.10.1",
56
- "publint": "^0.1.16",
56
+ "publint": "^0.2.0",
57
57
  "svelte": "^3.58.0",
58
58
  "svelte-check": "^3.4.6",
59
59
  "svelte2tsx": "^0.6.19",
60
60
  "tailwindcss": "^3.3.3",
61
- "tslib": "^2.6.0",
61
+ "tslib": "^2.6.1",
62
62
  "typescript": "^5.1.6",
63
- "vite": "^4.4.6",
64
- "vitest": "^0.33.0"
63
+ "vite": "^4.4.8",
64
+ "vitest": "^0.34.1"
65
65
  },
66
66
  "type": "module",
67
67
  "license": "MIT",
68
68
  "files": [
69
69
  "dist"
70
70
  ],
71
+ "main": "./dist/index.js",
71
72
  "types": "./dist/index.d.ts",
73
+ "svelte": "./dist/index.js",
72
74
  "typesVersions": {
73
75
  "*": {
74
76
  "types": [
@@ -1 +0,0 @@
1
- export declare const rawRegions: (string | number | string[])[][];
@@ -1,43 +0,0 @@
1
- // Country model:
2
- // [
3
- // Country name,
4
- // Regions,
5
- // iso2 code,
6
- // International dial code,
7
- // Format (if available),
8
- // Order priority (if >1 country with same dial code),
9
- // Area codes (if >1 country with same dial code)
10
- // ]
11
- //
12
- // Regions:
13
- // ['america', 'europe', 'asia', 'oceania', 'africa']
14
- //
15
- // Sub-regions:
16
- // ['north-america', 'south-america', 'central-america', 'carribean',
17
- // 'eu-union', 'ex-ussr', 'ex-yugos', 'baltic', 'middle-east', 'north-africa']
18
- export const rawRegions = [
19
- ['American Samoa', ['oceania'], 'as', '1684'],
20
- ['Anguilla', ['america', 'carribean'], 'ai', '1264'],
21
- ['Bermuda', ['america', 'north-america'], 'bm', '1441'],
22
- ['British Virgin Islands', ['america', 'carribean'], 'vg', '1284'],
23
- ['Cayman Islands', ['america', 'carribean'], 'ky', '1345'],
24
- ['Cook Islands', ['oceania'], 'ck', '682'],
25
- ['Falkland Islands', ['america', 'south-america'], 'fk', '500'],
26
- ['Faroe Islands', ['europe'], 'fo', '298'],
27
- ['Gibraltar', ['europe'], 'gi', '350'],
28
- ['Greenland', ['america'], 'gl', '299'],
29
- ['Jersey', ['europe', 'eu-union'], 'je', '44', '.... ......'],
30
- ['Montserrat', ['america', 'carribean'], 'ms', '1664'],
31
- ['Niue', ['asia'], 'nu', '683'],
32
- ['Norfolk Island', ['oceania'], 'nf', '672'],
33
- ['Northern Mariana Islands', ['oceania'], 'mp', '1670'],
34
- ['Saint Barthélemy', ['america', 'carribean'], 'bl', '590', '', 1],
35
- ['Saint Helena', ['africa'], 'sh', '290'],
36
- ['Saint Martin', ['america', 'carribean'], 'mf', '590', '', 2],
37
- ['Saint Pierre and Miquelon', ['america', 'north-america'], 'pm', '508'],
38
- ['Sint Maarten', ['america', 'carribean'], 'sx', '1721'],
39
- ['Tokelau', ['oceania'], 'tk', '690'],
40
- ['Turks and Caicos Islands', ['america', 'carribean'], 'tc', '1649'],
41
- ['U.S. Virgin Islands', ['america', 'carribean'], 'vi', '1340'],
42
- ['Wallis and Futuna', ['oceania'], 'wf', '681']
43
- ];
@@ -1,5 +0,0 @@
1
- export declare const telTypes: {
2
- id: string;
3
- value: string;
4
- label: string;
5
- }[];
@@ -1,16 +0,0 @@
1
- import { capitalize } from '../utils/index.js';
2
- export const telTypes = [
3
- 'PREMIUM_RATE',
4
- 'TOLL_FREE',
5
- 'SHARED_COST',
6
- 'VOIP',
7
- 'PERSONAL_NUMBER',
8
- 'PAGER',
9
- 'UAN',
10
- 'VOICEMAIL',
11
- 'FIXED_LINE_OR_MOBILE',
12
- 'FIXED_LINE',
13
- 'MOBILE'
14
- ].map((el) => {
15
- return { id: el, value: el, label: capitalize(el.split('_').join(' ')) };
16
- });
@@ -1 +0,0 @@
1
- export declare const isStringArray: (items: unknown) => items is string[];
@@ -1,3 +0,0 @@
1
- export const isStringArray = (items) => {
2
- return Array.isArray(items) && items.length > 0 && typeof items[0] === 'string';
3
- };