frutjam 0.0.1 → 0.0.3

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.
@@ -0,0 +1,114 @@
1
+ import allCountries from "./data";
2
+ import { CountryInfo } from "./types";
3
+ import { TelephoneInputSettings } from "./interfaces";
4
+
5
+ function countryCodeToEmoji(countryCode: string): string {
6
+ const codePoints = countryCode
7
+ .toUpperCase()
8
+ .split('')
9
+ .map((char) => 127397 + char.charCodeAt(0));
10
+ return String.fromCodePoint(...codePoints);
11
+ }
12
+
13
+ export default class TelephoneInput {
14
+ private inputElement: HTMLInputElement | null = null;
15
+ private selectElement: HTMLSelectElement;
16
+ private countries: Record<string, CountryInfo> = {};
17
+ private showFlag: boolean;
18
+
19
+ constructor(elementId: string, settings: TelephoneInputSettings) {
20
+ this.inputElement = document.getElementById(elementId) as HTMLInputElement | null;
21
+ this.selectElement = document.createElement('select');
22
+ this.showFlag = settings.showFlag ?? false; // Default to false if not provided
23
+ this.init();
24
+
25
+ if (this.inputElement) {
26
+ const countryCodes = Array.isArray(settings.countries)
27
+ ? settings.countries.map((country) => (typeof country === 'string' ? country : country.code))
28
+ : Object.keys(allCountries);
29
+
30
+ this.convertCountries(countryCodes).then((convertedCountries) => {
31
+ this.countries = convertedCountries;
32
+ this.createCountryDropdown(); // Call createCountryDropdown after countries are loaded
33
+ });
34
+ } else {
35
+ console.error(`Element with ID '${elementId}' not found.`);
36
+ }
37
+ }
38
+
39
+ private async convertCountries(countries: string[]): Promise<Record<string, CountryInfo>> {
40
+ const countryObjects = await Promise.all(
41
+ countries.map(async (code) => {
42
+ return allCountries[code] ? {
43
+ code,
44
+ name: allCountries[code].name,
45
+ flag: this.showFlag ? countryCodeToEmoji(allCountries[code].code) : '', // Conditionally include emoji flag
46
+ exampleNumber: allCountries[code].exampleNumber
47
+ } : null;
48
+ })
49
+ );
50
+ return countryObjects.filter((country) => country !== null).reduce((acc, country) => {
51
+ if (country) acc[country.code] = country;
52
+ return acc;
53
+ }, {} as Record<string, CountryInfo>);
54
+ }
55
+
56
+ private init() {
57
+ if (this.inputElement) {
58
+ // Check if the input element is already inside a div with data-fj="telephoneInput"
59
+ if (!this.inputElement.closest('[data-fj="telephoneInput"]')) {
60
+ // Create a div with data-fj="telephoneInput" attribute
61
+ const telephoneInputDiv = document.createElement('div');
62
+ telephoneInputDiv.setAttribute('data-fj', 'telephoneInput');
63
+
64
+ // Append the input element to the div
65
+ const parent = this.inputElement.parentNode;
66
+ if (parent) {
67
+ parent.insertBefore(telephoneInputDiv, this.inputElement);
68
+ telephoneInputDiv.appendChild(this.inputElement);
69
+ } else {
70
+ console.error('Input element has no parent node.');
71
+ }
72
+ } else {
73
+ console.error('Input element is already inside a div with data-fj="telephoneInput".');
74
+ }
75
+ } else {
76
+ console.error('Input element is not initialized.');
77
+ }
78
+ }
79
+
80
+
81
+ private createCountryDropdown() {
82
+ // Clear the existing content of selectElement
83
+ this.selectElement.innerHTML = '';
84
+
85
+ // Populate selectElement with options
86
+ Object.values(this.countries).forEach((country) => {
87
+ const option = document.createElement('option');
88
+ option.value = country.code;
89
+ const emojiFlag = countryCodeToEmoji(country.code);
90
+ option.text = this.showFlag ? `${emojiFlag} ${country.name} (${country.code})` : `${country.name} (${country.code})`;
91
+
92
+ // Append the option to the selectElement
93
+ this.selectElement.appendChild(option);
94
+ });
95
+
96
+ // Check if selectElement is not already part of the DOM
97
+ if (!this.selectElement.parentNode && this.inputElement && this.inputElement.parentNode) {
98
+ // Prepend selectElement before the input element
99
+ this.inputElement.parentNode.insertBefore(this.selectElement, this.inputElement);
100
+ }
101
+ }
102
+
103
+
104
+
105
+ private updatePlaceholder() {
106
+ const selectedCountryCode = this.selectElement.value;
107
+ const selectedCountry = this.countries[selectedCountryCode];
108
+ if (selectedCountry) {
109
+ this.inputElement?.setAttribute('placeholder', `E.g., ${selectedCountry.exampleNumber}`);
110
+ } else {
111
+ this.inputElement?.removeAttribute('placeholder');
112
+ }
113
+ }
114
+ }
@@ -0,0 +1,6 @@
1
+ import { CountryInfo } from "./types";
2
+ // Updated interface for TelephoneInputSettings to accept CountryInfo[]
3
+ export interface TelephoneInputSettings {
4
+ countries?: CountryInfo[] | string[];
5
+ showFlag?:boolean;
6
+ }
@@ -0,0 +1,7 @@
1
+ type CountryInfo = {
2
+ code: string;
3
+ name: string;
4
+ exampleNumber: string; // Example phone number
5
+ };
6
+
7
+ export type { CountryInfo }