svelte-tel-input 3.2.1 → 3.3.0

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
@@ -20,6 +20,7 @@ npm install --save svelte-tel-input
20
20
 
21
21
  ## Features
22
22
 
23
+ - Support SSR/SSG.
23
24
  - Parse and validate phone number.You can store one exact format (`E164`), no matter how users type their phone numbers.
24
25
  - Format (specified to its country), to make it more readable.
25
26
  - Prevent non-digits typing into the input, except the leading `+` sign (and `space` optionally).
@@ -126,7 +127,9 @@ Config options:
126
127
  // Allow or disallow spaces in the input field
127
128
  spaces: true,
128
129
  // If you have a parsed phone number and you change country manually from outside, then it's set the `valid` prop to false.
129
- invalidateOnCountryChange: false
130
+ invalidateOnCountryChange: false,
131
+ // Formatted output `national` | `international`
132
+ format: 'national'
130
133
  }
131
134
  ```
132
135
 
@@ -190,17 +193,15 @@ The default export of the library is the main TelInput component. It has the fol
190
193
 
191
194
  ## Dependencies
192
195
 
193
- [svelte](https://svelte.dev/)
194
-
195
196
  [libphonenumber-js](https://gitlab.com/catamphetamine/libphonenumber-js)
196
197
 
197
198
  <p align="right">(<a href="#readme-top">back to top</a>)</p>
198
199
 
199
200
  ## Changelog
200
201
 
201
- | Package | Changelog |
202
- | ------------------------------ | ------------------------- |
203
- | [@gyurielf/svelte-tel-input]() | [Changelog](CHANGELOG.md) |
202
+ | Package | Changelog |
203
+ | -------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
204
+ | [@gyurielf/svelte-tel-input](https://github.com/gyurielf/svelte-tel-input/tree/main/packages/svelte-tel-input) | [Changelog](https://github.com/gyurielf/svelte-tel-input/blob/main/packages/svelte-tel-input/CHANGELOG.md) |
204
205
 
205
206
  <p align="right">(<a href="#readme-top">back to top</a>)</p>
206
207
 
@@ -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';
@@ -1,5 +1,4 @@
1
- /// <reference types="svelte" />
2
1
  export declare const watcher: (initialValue: string | null, watchFunction: (oldVal: string | null, newVal: string | null) => void) => {
3
- subscribe: (this: void, run: import("svelte/store").Subscriber<string | null>, invalidate?: import("svelte/store").Invalidator<string | null> | undefined) => import("svelte/store").Unsubscriber;
2
+ subscribe: (this: void, run: import("svelte/store").Subscriber<string | null>, invalidate?: ((value?: string | null | undefined) => void) | undefined) => import("svelte/store").Unsubscriber;
4
3
  set: (value: string | null) => void;
5
4
  };
@@ -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.1",
4
+ "version": "3.3.0",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/gyurielf/svelte-tel-input.git"
@@ -27,12 +27,10 @@
27
27
  "pnpm": ">= 8"
28
28
  },
29
29
  "peerDependencies": {
30
- "libphonenumber-js": "^1.10.30",
31
30
  "svelte": "^3.58.0 || ^4.0.0"
32
31
  },
33
32
  "dependencies": {
34
- "libphonenumber-js": "^1.10.37",
35
- "svelte": "^4.0.5"
33
+ "libphonenumber-js": "^1.10.38"
36
34
  },
37
35
  "devDependencies": {
38
36
  "@sveltejs/adapter-auto": "2.1.0",
@@ -41,27 +39,28 @@
41
39
  "@testing-library/svelte": "^4.0.3",
42
40
  "@testing-library/user-event": "^14.4.3",
43
41
  "@types/micromatch": "^4.0.2",
44
- "@typescript-eslint/eslint-plugin": "^6.0.0",
45
- "@typescript-eslint/parser": "^6.0.0",
42
+ "@typescript-eslint/eslint-plugin": "^6.2.0",
43
+ "@typescript-eslint/parser": "^6.2.0",
46
44
  "autoprefixer": "^10.4.14",
47
45
  "cssnano": "^6.0.1",
48
46
  "dotenv": "^16.3.1",
49
47
  "eslint": "^8.45.0",
50
48
  "eslint-config-prettier": "^8.8.0",
51
49
  "eslint-plugin-import": "^2.27.5",
52
- "eslint-plugin-svelte": "^2.32.2",
50
+ "eslint-plugin-svelte": "^2.32.4",
53
51
  "jsdom": "^22.1.0",
54
52
  "micromatch": "^4.0.5",
55
- "postcss": "^8.4.26",
53
+ "postcss": "^8.4.27",
56
54
  "prettier": "^2.8.8",
57
55
  "prettier-plugin-svelte": "^2.10.1",
58
- "publint": "^0.1.16",
56
+ "publint": "^0.2.0",
57
+ "svelte": "^3.58.0",
59
58
  "svelte-check": "^3.4.6",
60
59
  "svelte2tsx": "^0.6.19",
61
60
  "tailwindcss": "^3.3.3",
62
- "tslib": "^2.6.0",
61
+ "tslib": "^2.6.1",
63
62
  "typescript": "^5.1.6",
64
- "vite": "^4.4.4",
63
+ "vite": "^4.4.7",
65
64
  "vitest": "^0.33.0"
66
65
  },
67
66
  "type": "module",
@@ -69,7 +68,9 @@
69
68
  "files": [
70
69
  "dist"
71
70
  ],
71
+ "main": "./dist/index.js",
72
72
  "types": "./dist/index.d.ts",
73
+ "svelte": "./dist/index.js",
73
74
  "typesVersions": {
74
75
  "*": {
75
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
- };