@jacksonavila/phone-lib 2.0.1 → 2.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.
Files changed (3) hide show
  1. package/README.md +351 -227
  2. package/package.json +7 -4
  3. package/phone-lib.cdn.js +101 -0
package/README.md CHANGED
@@ -1,42 +1,138 @@
1
1
  # PhoneLib 📱
2
2
 
3
+ Modern JavaScript library to easily integrate a phone input with country selector, flags, and phone number validation. **Compatible with Vanilla JavaScript and React**.
4
+
3
5
  Librería JavaScript moderna para integrar fácilmente un input de teléfono con selector de país, banderas y validación de números telefónicos. **Compatible con Vanilla JavaScript y React**.
4
6
 
5
7
  [![npm version](https://img.shields.io/npm/v/@jacksonavila/phone-lib.svg)](https://www.npmjs.com/package/@jacksonavila/phone-lib)
6
8
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
9
 
8
- ## ✨ Características
10
+ ---
11
+
12
+ ## ✨ Features / Características
13
+
14
+ - ✅ **Country dropdown** / **Dropdown de países** showing name, ISO2 code, dial code, and flag
15
+ - ✅ **Tel input** / **Input tipo tel** with automatic formatting based on selected country
16
+ - ✅ **Phone number validation** / **Validación de números** using `libphonenumber-js`
17
+ - ✅ **Complete public API** / **API pública completa** with methods to get number information
18
+ - ✅ **Vanilla JavaScript and React support** / **Soporte para Vanilla JavaScript y React**
19
+ - ✅ **Two layouts available** / **Dos layouts disponibles**: integrated and separated
20
+ - ✅ **Customizable events and callbacks** / **Eventos y callbacks** personalizables
21
+ - ✅ **Full programmatic control** / **Control programático** completo
22
+ - ✅ **Automatic country detection** / **Detección automática** de país
23
+ - ✅ **Country filtering** / **Filtrado de países** (include/exclude/disable)
24
+ - ✅ **Readonly/disabled mode** / **Modo readonly/disabled**
25
+ - ✅ **Modern responsive CSS** / **Estilos CSS modernos** y responsivos
26
+ - ✅ **Improved accessibility** / **Accesibilidad mejorada** (ARIA labels, keyboard navigation)
9
27
 
10
- - ✅ **Dropdown con países** mostrando nombre, código ISO2, código de marcación y bandera
11
- - ✅ **Input de tipo "tel"** con formato automático según el país seleccionado
12
- - **Validación de números** telefónicos usando `libphonenumber-js`
13
- - ✅ **API pública completa** con métodos para obtener información del número
14
- - ✅ **Soporte para Vanilla JavaScript y React**
15
- - ✅ **Dos layouts disponibles**: integrado y separado
16
- - ✅ **Eventos y callbacks** personalizables
17
- - ✅ **Control programático** completo
18
- - ✅ **Detección automática** de país
19
- - ✅ **Filtrado de países** (incluir/excluir/deshabilitar)
20
- - ✅ **Modo readonly/disabled**
21
- - ✅ **Estilos CSS modernos** y responsivos
22
- - ✅ **Accesibilidad** mejorada (ARIA labels, navegación por teclado)
28
+ ---
29
+
30
+ ## 📦 Installation / Instalación
23
31
 
24
- ## 📦 Instalación
32
+ ### Option 1: npm / Opción 1: npm
25
33
 
26
34
  ```bash
27
35
  npm install @jacksonavila/phone-lib
28
36
  ```
29
37
 
30
- ### Dependencias
38
+ ### Option 2: CDN (No npm required) / Opción 2: CDN (Sin npm)
39
+
40
+ Use directly from CDN / Usar directamente desde CDN - see [Using from CDN / Usar desde CDN](#-using-from-cdn--usar-desde-cdn) section below / ver sección abajo.
41
+
42
+ ### Dependencies / Dependencias
31
43
 
32
44
  ```bash
33
- # Para proyectos React
45
+ # For React projects / Para proyectos React
34
46
  npm install react react-dom
35
47
 
36
- # La dependencia libphonenumber-js se instala automáticamente
48
+ # libphonenumber-js is installed automatically
49
+ # libphonenumber-js se instala automáticamente
50
+ ```
51
+
52
+ ---
53
+
54
+ ## 🌐 Using from CDN / Usar desde CDN
55
+
56
+ You can use PhoneLib directly from CDN without npm / Puedes usar PhoneLib directamente desde CDN sin npm.
57
+
58
+ ### Method 1: Import Maps (Modern Browsers) / Método 1: Import Maps (Navegadores Modernos)
59
+
60
+ ```html
61
+ <!DOCTYPE html>
62
+ <html>
63
+ <head>
64
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jacksonavila/phone-lib@2.0.3/phone-lib.css">
65
+ </head>
66
+ <body>
67
+ <div id="phone-container"></div>
68
+
69
+ <script type="importmap">
70
+ {
71
+ "imports": {
72
+ "@jacksonavila/phone-lib": "https://cdn.jsdelivr.net/npm/@jacksonavila/phone-lib@2.0.3/phone-lib.js",
73
+ "libphonenumber-js": "https://esm.sh/libphonenumber-js@1.11.0"
74
+ }
75
+ }
76
+ </script>
77
+
78
+ <script type="module">
79
+ import PhoneLib from '@jacksonavila/phone-lib';
80
+
81
+ const phoneLib = new PhoneLib('#phone-container', {
82
+ initialCountry: 'CO',
83
+ layout: 'integrated',
84
+ showDialCode: true
85
+ });
86
+ </script>
87
+ </body>
88
+ </html>
37
89
  ```
38
90
 
39
- ## 🚀 Inicio Rápido
91
+ **CDN URLs / URLs de CDN:**
92
+ - **jsDelivr:** `https://cdn.jsdelivr.net/npm/@jacksonavila/phone-lib@2.0.3/`
93
+ - **unpkg:** `https://unpkg.com/@jacksonavila/phone-lib@2.0.3/`
94
+
95
+ ### Method 2: Script Tag (All Browsers) / Método 2: Script Tag (Todos los Navegadores)
96
+
97
+ ```html
98
+ <!DOCTYPE html>
99
+ <html>
100
+ <head>
101
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jacksonavila/phone-lib@2.0.3/phone-lib.css">
102
+ </head>
103
+ <body>
104
+ <div id="phone-container"></div>
105
+
106
+ <script src="https://cdn.jsdelivr.net/npm/@jacksonavila/phone-lib@2.0.3/phone-lib.cdn.js"></script>
107
+
108
+ <script>
109
+ let phoneLib = null;
110
+
111
+ // Wait for PhoneLib to be ready / Esperar a que PhoneLib esté listo
112
+ document.addEventListener('phoneLibReady', () => {
113
+ phoneLib = new PhoneLib('#phone-container', {
114
+ initialCountry: 'CO',
115
+ layout: 'integrated',
116
+ showDialCode: true
117
+ });
118
+ });
119
+
120
+ // Handle errors / Manejar errores
121
+ document.addEventListener('phoneLibError', (e) => {
122
+ console.error('Error loading PhoneLib:', e.detail.error);
123
+ });
124
+ </script>
125
+ </body>
126
+ </html>
127
+ ```
128
+
129
+ **⚠️ Important / Importante:** You need an HTTP server / Necesitas un servidor HTTP (doesn't work with `file://` / no funciona con `file://`)
130
+
131
+ 📖 **Complete CDN guide / Guía completa de CDN:** See [USO-SIN-NPM.md](./USO-SIN-NPM.md) / Ver [USO-SIN-NPM.md](./USO-SIN-NPM.md)
132
+
133
+ ---
134
+
135
+ ## 🚀 Quick Start / Inicio Rápido
40
136
 
41
137
  ### Vanilla JavaScript
42
138
 
@@ -58,7 +154,7 @@ npm install react react-dom
58
154
  showDialCode: true
59
155
  });
60
156
 
61
- // Obtener información del número
157
+ // Get number information / Obtener información del número
62
158
  const info = phoneLib.getInfo();
63
159
  console.log(info);
64
160
  </script>
@@ -86,11 +182,13 @@ function App() {
86
182
  export default App;
87
183
  ```
88
184
 
89
- ## 📖 Guía de Uso Completa
185
+ ---
186
+
187
+ ## 📖 Complete Usage Guide / Guía de Uso Completa
90
188
 
91
189
  ### Vanilla JavaScript
92
190
 
93
- #### Ejemplo Básico
191
+ #### Basic Example / Ejemplo Básico
94
192
 
95
193
  ```javascript
96
194
  import PhoneLib from '@jacksonavila/phone-lib';
@@ -105,7 +203,7 @@ const phoneLib = new PhoneLib('#phone-container', {
105
203
  });
106
204
  ```
107
205
 
108
- #### Con Eventos y Callbacks
206
+ #### With Events and Callbacks / Con Eventos y Callbacks
109
207
 
110
208
  ```javascript
111
209
  import PhoneLib from '@jacksonavila/phone-lib';
@@ -116,59 +214,59 @@ const phoneLib = new PhoneLib('#phone-container', {
116
214
 
117
215
  // Callbacks
118
216
  onCountryChange: (country, dialCode, countryName) => {
119
- console.log('País cambiado:', country, dialCode, countryName);
217
+ console.log('Country changed / País cambiado:', country, dialCode, countryName);
120
218
  },
121
219
 
122
220
  onPhoneChange: (phoneNumber, isValid, country) => {
123
- console.log('Número:', phoneNumber, 'Válido:', isValid);
221
+ console.log('Number / Número:', phoneNumber, 'Valid / Válido:', isValid);
124
222
  if (isValid) {
125
223
  const info = phoneLib.getInfo();
126
- console.log('Información completa:', info);
224
+ console.log('Complete info / Información completa:', info);
127
225
  }
128
226
  },
129
227
 
130
228
  onValidationChange: (isValid, phoneNumber) => {
131
- console.log('Validación:', isValid ? 'Válido' : 'Inválido');
229
+ console.log('Validation / Validación:', isValid ? 'Valid / Válido' : 'Invalid / Inválido');
132
230
  },
133
231
 
134
- onFocus: () => console.log('Input enfocado'),
135
- onBlur: () => console.log('Input perdió foco')
232
+ onFocus: () => console.log('Input focused / Input enfocado'),
233
+ onBlur: () => console.log('Input blurred / Input perdió foco')
136
234
  });
137
235
 
138
- // Escuchar eventos DOM personalizados
236
+ // Listen to custom DOM events / Escuchar eventos DOM personalizados
139
237
  document.getElementById('phone-container').addEventListener('phoneLib:countryChange', (e) => {
140
- console.log('Evento DOM:', e.detail);
238
+ console.log('DOM event / Evento DOM:', e.detail);
141
239
  });
142
240
  ```
143
241
 
144
- #### Control Programático
242
+ #### Programmatic Control / Control Programático
145
243
 
146
244
  ```javascript
147
- // Establecer valores
245
+ // Set values / Establecer valores
148
246
  phoneLib.setCountry('ES');
149
247
  phoneLib.setPhoneNumber('+34600123456');
150
248
  phoneLib.setValue('US', '5551234567');
151
249
 
152
- // Controlar estado
250
+ // Control state / Controlar estado
153
251
  phoneLib.enable();
154
252
  phoneLib.disable();
155
253
  phoneLib.reset();
156
254
 
157
- // Obtener información
255
+ // Get information / Obtener información
158
256
  const country = phoneLib.getCountry(); // 'CO'
159
257
  const dialCode = phoneLib.getDialCode(); // '+57'
160
258
  const raw = phoneLib.getRaw(); // '3001234567'
161
259
  const e164 = phoneLib.getE164(); // '+573001234567'
162
260
  const isValid = phoneLib.isValid(); // true/false
163
- const info = phoneLib.getInfo(); // Objeto completo
261
+ const info = phoneLib.getInfo(); // Complete object / Objeto completo
164
262
  ```
165
263
 
166
- #### Integración con Formularios
264
+ #### Form Integration / Integración con Formularios
167
265
 
168
266
  ```html
169
267
  <form id="contact-form">
170
268
  <div id="phone-container"></div>
171
- <button type="submit">Enviar</button>
269
+ <button type="submit">Submit / Enviar</button>
172
270
  </form>
173
271
 
174
272
  <script type="module">
@@ -186,25 +284,25 @@ const info = phoneLib.getInfo(); // Objeto completo
186
284
  const phoneInfo = phoneLib.getInfo();
187
285
 
188
286
  if (!phoneInfo.isValid) {
189
- alert('Por favor ingrese un número válido');
287
+ alert('Please enter a valid number / Por favor ingrese un número válido');
190
288
  return;
191
289
  }
192
290
 
193
- // Enviar datos
291
+ // Send data / Enviar datos
194
292
  const formData = {
195
293
  phone: phoneInfo.e164,
196
294
  country: phoneInfo.country,
197
- // ... otros campos
295
+ // ... other fields / otros campos
198
296
  };
199
297
 
200
- console.log('Enviando:', formData);
298
+ console.log('Sending / Enviando:', formData);
201
299
  });
202
300
  </script>
203
301
  ```
204
302
 
205
303
  ### React
206
304
 
207
- #### Ejemplo Básico
305
+ #### Basic Example / Ejemplo Básico
208
306
 
209
307
  ```jsx
210
308
  import React from 'react';
@@ -224,7 +322,7 @@ function App() {
224
322
  export default App;
225
323
  ```
226
324
 
227
- #### Con Ref y Métodos
325
+ #### With Ref and Methods / Con Ref y Métodos
228
326
 
229
327
  ```jsx
230
328
  import React, { useRef } from 'react';
@@ -238,11 +336,11 @@ function App() {
238
336
  const info = phoneLibRef.current.getInfo();
239
337
 
240
338
  if (!info.isValid) {
241
- alert('Número inválido');
339
+ alert('Invalid number / Número inválido');
242
340
  return;
243
341
  }
244
342
 
245
- console.log('Enviar:', info.e164);
343
+ console.log('Send / Enviar:', info.e164);
246
344
  };
247
345
 
248
346
  return (
@@ -252,16 +350,16 @@ function App() {
252
350
  initialCountry="CO"
253
351
  layout="integrated"
254
352
  onPhoneChange={(phone, isValid) => {
255
- console.log('Número:', phone, 'Válido:', isValid);
353
+ console.log('Number / Número:', phone, 'Valid / Válido:', isValid);
256
354
  }}
257
355
  />
258
- <button onClick={handleSubmit}>Enviar</button>
356
+ <button onClick={handleSubmit}>Submit / Enviar</button>
259
357
  </div>
260
358
  );
261
359
  }
262
360
  ```
263
361
 
264
- #### Con Estado de React
362
+ #### With React State / Con Estado de React
265
363
 
266
364
  ```jsx
267
365
  import React, { useState, useRef } from 'react';
@@ -292,9 +390,9 @@ function PhoneForm() {
292
390
 
293
391
  {phoneData && (
294
392
  <div>
295
- <p>País: {phoneData.country}</p>
296
- <p>Número: {phoneData.e164}</p>
297
- <p>Válido: {phoneData.isValid ? 'Sí' : 'No'}</p>
393
+ <p>Country / País: {phoneData.country}</p>
394
+ <p>Number / Número: {phoneData.e164}</p>
395
+ <p>Valid / Válido: {phoneData.isValid ? 'Yes / Sí' : 'No'}</p>
298
396
  </div>
299
397
  )}
300
398
  </div>
@@ -302,7 +400,7 @@ function PhoneForm() {
302
400
  }
303
401
  ```
304
402
 
305
- #### Integración con Formularios React
403
+ #### React Form Integration / Integración con Formularios React
306
404
 
307
405
  ```jsx
308
406
  import React, { useRef } from 'react';
@@ -319,7 +417,7 @@ function ContactForm() {
319
417
  const phoneInfo = phoneLibRef.current.getInfo();
320
418
 
321
419
  if (!phoneInfo.isValid) {
322
- alert('Por favor ingrese un número válido');
420
+ alert('Please enter a valid number / Por favor ingrese un número válido');
323
421
  return;
324
422
  }
325
423
 
@@ -330,7 +428,7 @@ function ContactForm() {
330
428
  country: phoneInfo.country
331
429
  };
332
430
 
333
- // Enviar datos
431
+ // Send data / Enviar datos
334
432
  fetch('/api/contact', {
335
433
  method: 'POST',
336
434
  headers: { 'Content-Type': 'application/json' },
@@ -340,7 +438,7 @@ function ContactForm() {
340
438
 
341
439
  return (
342
440
  <form ref={formRef} onSubmit={handleSubmit}>
343
- <input name="name" placeholder="Nombre" required />
441
+ <input name="name" placeholder="Name / Nombre" required />
344
442
  <input name="email" type="email" placeholder="Email" required />
345
443
 
346
444
  <PhoneLibReact
@@ -349,107 +447,111 @@ function ContactForm() {
349
447
  validateOnInput={true}
350
448
  />
351
449
 
352
- <button type="submit">Enviar</button>
450
+ <button type="submit">Submit / Enviar</button>
353
451
  </form>
354
452
  );
355
453
  }
356
454
  ```
357
455
 
358
- ## 🎨 Layouts Disponibles
456
+ ---
457
+
458
+ ## 🎨 Available Layouts / Layouts Disponibles
359
459
 
360
- ### Layout Integrado (Default)
460
+ ### Integrated Layout / Layout Integrado (Default)
361
461
 
362
- El selector de país y el input están en la misma línea:
462
+ The country selector and input are on the same line / El selector de país y el input están en la misma línea:
363
463
 
364
464
  ```javascript
365
465
  const phoneLib = new PhoneLib('#container', {
366
466
  layout: 'integrated',
367
- showDialCode: true // Muestra +57 en el botón
467
+ showDialCode: true // Shows +57 in button / Muestra +57 en el botón
368
468
  });
369
469
  ```
370
470
 
371
- **Con código visible:**
372
- - Muestra: `[🇨🇴 +57 ▼] [300 123 4567]`
471
+ **With code visible / Con código visible:**
472
+ - Shows / Muestra: `[🇨🇴 +57 ▼] [300 123 4567]`
373
473
 
374
- **Sin código visible:**
474
+ **Without code visible / Sin código visible:**
375
475
  ```javascript
376
476
  const phoneLib = new PhoneLib('#container', {
377
477
  layout: 'integrated',
378
- showDialCode: false // Solo muestra la bandera
478
+ showDialCode: false // Only shows flag / Solo muestra la bandera
379
479
  });
380
480
  ```
381
- - Muestra: `[🇨🇴 ▼] [300 123 4567]`
481
+ - Shows / Muestra: `[🇨🇴 ▼] [300 123 4567]`
382
482
 
383
- ### Layout Separado
483
+ ### Separated Layout / Layout Separado
384
484
 
385
- Los campos están separados en una fila:
485
+ Fields are separated in a row / Los campos están separados en una fila:
386
486
 
387
487
  ```javascript
388
488
  const phoneLib = new PhoneLib('#container', {
389
489
  layout: 'separated',
390
- showDialCode: true // Muestra campo "Código" separado
490
+ showDialCode: true // Shows separate "Code" field / Muestra campo "Código" separado
391
491
  });
392
492
  ```
393
493
 
394
- **Con código visible:**
395
- - Muestra: `[País: 🇨🇴 Colombia ▼] [Código: +57] [Número: 300 123 4567]`
494
+ **With code visible / Con código visible:**
495
+ - Shows / Muestra: `[Country / País: 🇨🇴 Colombia ▼] [Code / Código: +57] [Number / Número: 300 123 4567]`
396
496
 
397
- **Sin código visible:**
497
+ **Without code visible / Sin código visible:**
398
498
  ```javascript
399
499
  const phoneLib = new PhoneLib('#container', {
400
500
  layout: 'separated',
401
- showDialCode: false // Solo muestra País y Número
501
+ showDialCode: false // Only shows Country and Number / Solo muestra País y Número
402
502
  });
403
503
  ```
404
- - Muestra: `[País: 🇨🇴 Colombia ▼] [Número: 300 123 4567]`
504
+ - Shows / Muestra: `[Country / País: 🇨🇴 Colombia ▼] [Number / Número: 300 123 4567]`
405
505
 
406
- ## ⚙️ Opciones de Configuración
506
+ ---
407
507
 
408
- ### Opciones Básicas
508
+ ## ⚙️ Configuration Options / Opciones de Configuración
509
+
510
+ ### Basic Options / Opciones Básicas
409
511
 
410
512
  ```javascript
411
513
  {
412
- initialCountry: 'CO', // País inicial (ISO2)
413
- preferredCountries: ['CO', 'US'], // Países que aparecen primero
414
- showHint: true, // Mostrar hint de validación
415
- layout: 'integrated', // 'integrated' o 'separated'
416
- showDialCode: true // Mostrar código de marcación
514
+ initialCountry: 'CO', // Initial country / País inicial (ISO2)
515
+ preferredCountries: ['CO', 'US'], // Countries that appear first / Países que aparecen primero
516
+ showHint: true, // Show validation hint / Mostrar hint de validación
517
+ layout: 'integrated', // 'integrated' or 'separated' / 'integrated' o 'separated'
518
+ showDialCode: true // Show dial code / Mostrar código de marcación
417
519
  }
418
520
  ```
419
521
 
420
- ### Opciones Avanzadas
522
+ ### Advanced Options / Opciones Avanzadas
421
523
 
422
524
  ```javascript
423
525
  {
424
- // Detección y validación
425
- autoDetectCountry: true, // Detectar país automáticamente
426
- validateOnInput: false, // Validar mientras se escribe
526
+ // Detection and validation / Detección y validación
527
+ autoDetectCountry: true, // Auto-detect country / Detectar país automáticamente
528
+ validateOnInput: false, // Validate while typing / Validar mientras se escribe
427
529
 
428
- // Filtrado de países
429
- onlyCountries: ['CO', 'US', 'ES'], // Solo estos países
430
- disabledCountries: ['CU', 'KP'], // Deshabilitar estos
431
- excludeCountries: ['XX'], // Excluir estos
530
+ // Country filtering / Filtrado de países
531
+ onlyCountries: ['CO', 'US', 'ES'], // Only these countries / Solo estos países
532
+ disabledCountries: ['CU', 'KP'], // Disable these / Deshabilitar estos
533
+ excludeCountries: ['XX'], // Exclude these / Excluir estos
432
534
 
433
- // Estados
434
- readonly: false, // Modo solo lectura
435
- disabled: false, // Componente deshabilitado
535
+ // States / Estados
536
+ readonly: false, // Read-only mode / Modo solo lectura
537
+ disabled: false, // Disabled component / Componente deshabilitado
436
538
 
437
- // Personalización
438
- placeholder: 'Ingrese su número', // Placeholder personalizado
439
- countryLabel: 'País', // Label para selector
440
- dialCodeLabel: 'Código', // Label para código
441
- phoneLabel: 'Número de teléfono', // Label para número
539
+ // Customization / Personalización
540
+ placeholder: 'Enter your number', // Custom placeholder / Placeholder personalizado
541
+ countryLabel: 'Country', // Label for selector / Label para selector
542
+ dialCodeLabel: 'Code', // Label for code / Label para código
543
+ phoneLabel: 'Phone number', // Label for number / Label para número
442
544
 
443
- // Mensajes
545
+ // Messages / Mensajes
444
546
  messages: {
445
- invalid: 'Número inválido',
446
- valid: '✓ Número válido'
547
+ invalid: 'Invalid number',
548
+ valid: '✓ Valid number'
447
549
  },
448
550
 
449
- // Estilos
551
+ // Styles / Estilos
450
552
  customClasses: {
451
- wrapper: 'mi-clase',
452
- input: 'mi-input'
553
+ wrapper: 'my-class',
554
+ input: 'my-input'
453
555
  },
454
556
  customStyles: {
455
557
  input: {
@@ -459,97 +561,99 @@ const phoneLib = new PhoneLib('#container', {
459
561
  }
460
562
  ```
461
563
 
462
- ### Callbacks y Eventos
564
+ ### Callbacks and Events / Callbacks y Eventos
463
565
 
464
566
  ```javascript
465
567
  {
466
568
  onCountryChange: (country, dialCode, countryName) => {
467
- // País cambiado
569
+ // Country changed / País cambiado
468
570
  },
469
571
  onPhoneChange: (phoneNumber, isValid, country) => {
470
- // Número cambiado
572
+ // Number changed / Número cambiado
471
573
  },
472
574
  onValidationChange: (isValid, phoneNumber) => {
473
- // Validación cambiada
575
+ // Validation changed / Validación cambiada
474
576
  },
475
577
  onFocus: () => {
476
- // Input enfocado
578
+ // Input focused / Input enfocado
477
579
  },
478
580
  onBlur: () => {
479
- // Input perdió foco
581
+ // Input blurred / Input perdió foco
480
582
  }
481
583
  }
482
584
  ```
483
585
 
484
- ## 📚 API Pública
586
+ ---
485
587
 
486
- ### Métodos de Lectura
588
+ ## 📚 Public API
589
+
590
+ ### Reading Methods / Métodos de Lectura
487
591
 
488
592
  #### `getCountry()`
489
- Devuelve el código ISO2 del país seleccionado.
593
+ Returns the ISO2 code of the selected country / Devuelve el código ISO2 del país seleccionado.
490
594
 
491
595
  ```javascript
492
596
  const country = phoneLib.getCountry(); // 'CO'
493
597
  ```
494
598
 
495
599
  #### `getDialCode()`
496
- Devuelve el código de marcación del país seleccionado.
600
+ Returns the dial code of the selected country / Devuelve el código de marcación del país seleccionado.
497
601
 
498
602
  ```javascript
499
603
  const dialCode = phoneLib.getDialCode(); // '+57'
500
604
  ```
501
605
 
502
606
  #### `getRaw()`
503
- Devuelve el número ingresado sin formato (solo dígitos).
607
+ Returns the entered number without formatting (digits only) / Devuelve el número ingresado sin formato (solo dígitos).
504
608
 
505
609
  ```javascript
506
610
  const raw = phoneLib.getRaw(); // '3001234567'
507
611
  ```
508
612
 
509
613
  #### `getE164()`
510
- Devuelve el número en formato E.164.
614
+ Returns the number in E.164 format / Devuelve el número en formato E.164.
511
615
 
512
616
  ```javascript
513
617
  const e164 = phoneLib.getE164(); // '+573001234567'
514
618
  ```
515
619
 
516
620
  #### `isValid()`
517
- Devuelve `true` si el número es válido, `false` en caso contrario.
621
+ Returns `true` if the number is valid, `false` otherwise / Devuelve `true` si el número es válido, `false` en caso contrario.
518
622
 
519
623
  ```javascript
520
624
  const isValid = phoneLib.isValid(); // true o false
521
625
  ```
522
626
 
523
627
  #### `formatInternational()`
524
- Devuelve el número en formato internacional.
628
+ Returns the number in international format / Devuelve el número en formato internacional.
525
629
 
526
630
  ```javascript
527
631
  const international = phoneLib.formatInternational(); // '+57 300 123 4567'
528
632
  ```
529
633
 
530
634
  #### `formatNational()`
531
- Devuelve el número en formato nacional.
635
+ Returns the number in national format / Devuelve el número en formato nacional.
532
636
 
533
637
  ```javascript
534
638
  const national = phoneLib.formatNational(); // '300 123 4567'
535
639
  ```
536
640
 
537
641
  #### `formatRFC3966()`
538
- Devuelve el número en formato RFC3966.
642
+ Returns the number in RFC3966 format / Devuelve el número en formato RFC3966.
539
643
 
540
644
  ```javascript
541
645
  const rfc3966 = phoneLib.formatRFC3966(); // 'tel:+57-300-123-4567'
542
646
  ```
543
647
 
544
648
  #### `getNumberType()`
545
- Devuelve el tipo de número (MOBILE, FIXED_LINE, etc.).
649
+ Returns the number type (MOBILE, FIXED_LINE, etc.) / Devuelve el tipo de número (MOBILE, FIXED_LINE, etc.).
546
650
 
547
651
  ```javascript
548
652
  const type = phoneLib.getNumberType(); // 'MOBILE' o null
549
653
  ```
550
654
 
551
655
  #### `getInfo()`
552
- Devuelve un objeto con toda la información del número.
656
+ Returns an object with all number information / Devuelve un objeto con toda la información del número.
553
657
 
554
658
  ```javascript
555
659
  const info = phoneLib.getInfo();
@@ -568,7 +672,7 @@ const info = phoneLib.getInfo();
568
672
  ```
569
673
 
570
674
  #### `getCountryMetadata()`
571
- Devuelve información completa del país seleccionado.
675
+ Returns complete information about the selected country / Devuelve información completa del país seleccionado.
572
676
 
573
677
  ```javascript
574
678
  const metadata = phoneLib.getCountryMetadata();
@@ -580,31 +684,31 @@ const metadata = phoneLib.getCountryMetadata();
580
684
  // }
581
685
  ```
582
686
 
583
- ### Métodos de Control
687
+ ### Control Methods / Métodos de Control
584
688
 
585
689
  #### `setCountry(iso2)`
586
- Establece el país programáticamente.
690
+ Sets the country programmatically / Establece el país programáticamente.
587
691
 
588
692
  ```javascript
589
693
  phoneLib.setCountry('ES');
590
694
  ```
591
695
 
592
696
  #### `setPhoneNumber(number)`
593
- Establece el número telefónico programáticamente.
697
+ Sets the phone number programmatically / Establece el número telefónico programáticamente.
594
698
 
595
699
  ```javascript
596
700
  phoneLib.setPhoneNumber('+34600123456');
597
701
  ```
598
702
 
599
703
  #### `setValue(country, number)`
600
- Establece país y número juntos.
704
+ Sets both country and number / Establece país y número juntos.
601
705
 
602
706
  ```javascript
603
707
  phoneLib.setValue('ES', '600123456');
604
708
  ```
605
709
 
606
710
  #### `enable()` / `disable()`
607
- Habilita o deshabilita el componente.
711
+ Enables or disables the component / Habilita o deshabilita el componente.
608
712
 
609
713
  ```javascript
610
714
  phoneLib.enable();
@@ -612,21 +716,21 @@ phoneLib.disable();
612
716
  ```
613
717
 
614
718
  #### `reset()`
615
- Resetea el componente a valores iniciales.
719
+ Resets the component to initial values / Resetea el componente a valores iniciales.
616
720
 
617
721
  ```javascript
618
722
  phoneLib.reset();
619
723
  ```
620
724
 
621
725
  #### `destroy()`
622
- Destruye la instancia y limpia recursos.
726
+ Destroys the instance and cleans up resources / Destruye la instancia y limpia recursos.
623
727
 
624
728
  ```javascript
625
729
  phoneLib.destroy();
626
730
  ```
627
731
 
628
732
  #### `updateOptions(newOptions)`
629
- Actualiza opciones dinámicamente.
733
+ Updates options dynamically / Actualiza opciones dinámicamente.
630
734
 
631
735
  ```javascript
632
736
  phoneLib.updateOptions({
@@ -634,21 +738,23 @@ phoneLib.updateOptions({
634
738
  });
635
739
  ```
636
740
 
637
- ## 🎨 Estilos Personalizados
741
+ ---
742
+
743
+ ## 🎨 Custom Styling / Estilos Personalizados
638
744
 
639
- ### Con Clases CSS
745
+ ### With CSS Classes / Con Clases CSS
640
746
 
641
747
  ```javascript
642
748
  const phoneLib = new PhoneLib('#container', {
643
749
  customClasses: {
644
- wrapper: 'mi-clase-personalizada',
645
- dropdownButton: 'mi-boton-personalizado',
646
- input: 'mi-input-personalizado'
750
+ wrapper: 'my-custom-class',
751
+ dropdownButton: 'my-custom-button',
752
+ input: 'my-custom-input'
647
753
  }
648
754
  });
649
755
  ```
650
756
 
651
- ### Con Estilos Inline
757
+ ### With Inline Styles / Con Estilos Inline
652
758
 
653
759
  ```javascript
654
760
  const phoneLib = new PhoneLib('#container', {
@@ -666,177 +772,195 @@ const phoneLib = new PhoneLib('#container', {
666
772
  });
667
773
  ```
668
774
 
669
- ### Elementos Personalizables
775
+ ### Customizable Elements / Elementos Personalizables
670
776
 
671
- - `wrapper` - Contenedor principal
672
- - `dropdownButton` - Botón del selector de país
673
- - `input` - Campo de entrada de teléfono
674
- - `dialCodeInput` - Campo de código (solo layout separado)
675
- - `row` - Fila del grid (solo layout separado)
777
+ - `wrapper` - Main container / Contenedor principal
778
+ - `dropdownButton` - Country selector button / Botón del selector de país
779
+ - `input` - Phone input field / Campo de entrada de teléfono
780
+ - `dialCodeInput` - Dial code field (separated layout only) / Campo de código (solo layout separado)
781
+ - `row` - Grid row (separated layout only) / Fila del grid (solo layout separado)
676
782
 
677
- ## 🔧 Ejemplos Avanzados
783
+ ---
784
+
785
+ ## 🔧 Advanced Examples / Ejemplos Avanzados
678
786
 
679
- ### Detección Automática de País
787
+ ### Automatic Country Detection / Detección Automática de País
680
788
 
681
789
  ```javascript
682
790
  const phoneLib = new PhoneLib('#container', {
683
- autoDetectCountry: true // Detecta país al ingresar +34...
791
+ autoDetectCountry: true // Detects country when entering +34... / Detecta país al ingresar +34...
684
792
  });
685
793
 
686
- // El usuario escribe: +34 600 123 456
687
- // Automáticamente cambia a España
794
+ // User types / Usuario escribe: +34 600 123 456
795
+ // Automatically changes to Spain / Automáticamente cambia a España
688
796
  ```
689
797
 
690
- ### Filtrado de Países
798
+ ### Country Filtering / Filtrado de Países
691
799
 
692
800
  ```javascript
693
801
  const phoneLib = new PhoneLib('#container', {
694
- // Solo mostrar estos países
802
+ // Only show these countries / Solo mostrar estos países
695
803
  onlyCountries: ['CO', 'US', 'ES', 'MX'],
696
804
 
697
- // Deshabilitar estos países (aparecen pero no se pueden seleccionar)
805
+ // Disable these countries (appear but can't be selected) / Deshabilitar estos países
698
806
  disabledCountries: ['CU', 'KP'],
699
807
 
700
- // Excluir estos países (no aparecen en la lista)
808
+ // Exclude these countries (don't appear in list) / Excluir estos países
701
809
  excludeCountries: ['XX']
702
810
  });
703
811
  ```
704
812
 
705
- ### Validación en Tiempo Real
813
+ ### Real-time Validation / Validación en Tiempo Real
706
814
 
707
815
  ```javascript
708
816
  const phoneLib = new PhoneLib('#container', {
709
- validateOnInput: true, // Valida mientras el usuario escribe
817
+ validateOnInput: true, // Validate while user types / Valida mientras el usuario escribe
710
818
 
711
819
  onValidationChange: (isValid) => {
712
820
  if (isValid) {
713
- console.log('Número válido!');
821
+ console.log('Valid number! / ¡Número válido!');
714
822
  }
715
823
  }
716
824
  });
717
825
  ```
718
826
 
719
- ### Modo Readonly/Disabled
827
+ ### Readonly/Disabled Mode / Modo Readonly/Disabled
720
828
 
721
829
  ```javascript
722
- // Solo lectura
830
+ // Read-only / Solo lectura
723
831
  const phoneLib = new PhoneLib('#container', {
724
832
  readonly: true
725
833
  });
726
834
 
727
- // Deshabilitado
835
+ // Disabled / Deshabilitado
728
836
  const phoneLib = new PhoneLib('#container', {
729
837
  disabled: true
730
838
  });
731
839
  ```
732
840
 
733
- ## 📱 Props del Componente React
734
-
735
- | Prop | Tipo | Default | Descripción |
736
- |------|------|---------|-------------|
737
- | `initialCountry` | string | `'US'` | País inicial (ISO2) |
738
- | `preferredCountries` | array | `[]` | Países preferidos |
739
- | `showHint` | boolean | `true` | Mostrar hint de validación |
740
- | `layout` | string | `'integrated'` | `'integrated'` o `'separated'` |
741
- | `showDialCode` | boolean | `true` | Mostrar código de marcación |
742
- | `autoDetectCountry` | boolean | `false` | Detectar país automáticamente |
743
- | `validateOnInput` | boolean | `false` | Validar mientras se escribe |
744
- | `disabledCountries` | array | `[]` | Países deshabilitados |
745
- | `onlyCountries` | array | `[]` | Solo estos países |
746
- | `excludeCountries` | array | `[]` | Excluir estos países |
747
- | `readonly` | boolean | `false` | Modo solo lectura |
748
- | `disabled` | boolean | `false` | Componente deshabilitado |
749
- | `placeholder` | string | `null` | Placeholder personalizado |
750
- | `countryLabel` | string | `'País'` | Label para selector |
751
- | `dialCodeLabel` | string | `'Código'` | Label para código |
752
- | `phoneLabel` | string | `'Número de teléfono'` | Label para número |
753
- | `customClasses` | object | `{}` | Clases CSS personalizadas |
754
- | `customStyles` | object | `{}` | Estilos inline personalizados |
755
- | `messages` | object | `{}` | Mensajes personalizables |
756
- | `ariaLabels` | object | `{}` | Labels ARIA personalizables |
757
- | `onCountryChange` | function | `null` | Callback cuando cambia el país |
758
- | `onPhoneChange` | function | `null` | Callback cuando cambia el número |
759
- | `onValidationChange` | function | `null` | Callback cuando cambia la validación |
760
- | `onFocus` | function | `null` | Callback cuando se enfoca |
761
- | `onBlur` | function | `null` | Callback cuando pierde foco |
762
-
763
- ## 🧪 Desarrollo y Pruebas
764
-
765
- ### Ejecutar Demos Localmente
841
+ ---
842
+
843
+ ## 📱 React Component Props
844
+
845
+ | Prop | Type | Default | Description / Descripción |
846
+ |------|------|---------|--------------------------|
847
+ | `initialCountry` | string | `'US'` | Initial country (ISO2) / País inicial (ISO2) |
848
+ | `preferredCountries` | array | `[]` | Preferred countries / Países preferidos |
849
+ | `showHint` | boolean | `true` | Show validation hint / Mostrar hint de validación |
850
+ | `layout` | string | `'integrated'` | `'integrated'` or `'separated'` / `'integrated'` o `'separated'` |
851
+ | `showDialCode` | boolean | `true` | Show dial code / Mostrar código de marcación |
852
+ | `autoDetectCountry` | boolean | `false` | Auto-detect country / Detectar país automáticamente |
853
+ | `validateOnInput` | boolean | `false` | Validate while typing / Validar mientras se escribe |
854
+ | `disabledCountries` | array | `[]` | Disabled countries / Países deshabilitados |
855
+ | `onlyCountries` | array | `[]` | Only these countries / Solo estos países |
856
+ | `excludeCountries` | array | `[]` | Exclude these countries / Excluir estos países |
857
+ | `readonly` | boolean | `false` | Read-only mode / Modo solo lectura |
858
+ | `disabled` | boolean | `false` | Disabled component / Componente deshabilitado |
859
+ | `placeholder` | string | `null` | Custom placeholder / Placeholder personalizado |
860
+ | `countryLabel` | string | `'Country'` / `'País'` | Label for selector / Label para selector |
861
+ | `dialCodeLabel` | string | `'Code'` / `'Código'` | Label for code / Label para código |
862
+ | `phoneLabel` | string | `'Phone number'` / `'Número de teléfono'` | Label for number / Label para número |
863
+ | `customClasses` | object | `{}` | Custom CSS classes / Clases CSS personalizadas |
864
+ | `customStyles` | object | `{}` | Inline styles / Estilos inline personalizados |
865
+ | `messages` | object | `{}` | Custom messages / Mensajes personalizables |
866
+ | `ariaLabels` | object | `{}` | ARIA labels / Labels ARIA personalizables |
867
+ | `onCountryChange` | function | `null` | Callback when country changes / Callback cuando cambia el país |
868
+ | `onPhoneChange` | function | `null` | Callback when number changes / Callback cuando cambia el número |
869
+ | `onValidationChange` | function | `null` | Callback when validation changes / Callback cuando cambia la validación |
870
+ | `onFocus` | function | `null` | Callback when focused / Callback cuando se enfoca |
871
+ | `onBlur` | function | `null` | Callback when blurred / Callback cuando pierde foco |
872
+
873
+ ---
874
+
875
+ ## 🧪 Development and Testing / Desarrollo y Pruebas
876
+
877
+ ### Run Demos Locally / Ejecutar Demos Localmente
766
878
 
767
879
  ```bash
768
- # Instalar dependencias
880
+ # Install dependencies / Instalar dependencias
769
881
  npm install
770
882
 
771
- # Iniciar servidor de desarrollo
883
+ # Start development server / Iniciar servidor de desarrollo
772
884
  npm run serve
773
885
  ```
774
886
 
775
- Esto abrirá `http://localhost:3004` con todos los demos disponibles.
887
+ This will open `http://localhost:3004` with all available demos / Esto abrirá `http://localhost:3004` con todos los demos disponibles.
776
888
 
777
- ### Archivos de Demo
889
+ ### Demo Files / Archivos de Demo
778
890
 
779
- - `demo.html` - Layout integrado básico
780
- - `demo-separated.html` - Layout separado
781
- - `demo-all-layouts.html` - Comparación de todos los layouts
782
- - `demo-features.html` - Todas las características
783
- - `demo-react.html` - Ejemplo con React
891
+ - `demo.html` - Basic integrated layout / Layout integrado básico
892
+ - `demo-separated.html` - Separated layout / Layout separado
893
+ - `demo-all-layouts.html` - All layouts comparison / Comparación de todos los layouts
894
+ - `demo-features.html` - All features / Todas las características
895
+ - `demo-react.html` - React example / Ejemplo con React
896
+ - `demo-cdn-importmap.html` - CDN with Import Maps / CDN con Import Maps
897
+ - `demo-cdn-script.html` - CDN with Script Tag / CDN con Script Tag
784
898
 
785
- ## 📦 Estructura del Paquete
899
+ ---
900
+
901
+ ## 📦 Package Structure / Estructura del Paquete
786
902
 
787
903
  ```
788
904
  @jacksonavila/phone-lib/
789
- ├── phone-lib.js # Código principal (Vanilla JS)
790
- ├── phone-lib.css # Estilos CSS
791
- ├── phone-lib-react.jsx # Componente React
792
- ├── phone-lib-react.js # Versión CommonJS/ESM React
793
- └── README.md # Documentación
905
+ ├── phone-lib.js # Main code (Vanilla JS) / Código principal (Vanilla JS)
906
+ ├── phone-lib.css # CSS styles / Estilos CSS
907
+ ├── phone-lib-react.jsx # React component / Componente React
908
+ ├── phone-lib-react.js # CommonJS/ESM React version / Versión CommonJS/ESM React
909
+ └── README.md # Documentation / Documentación
794
910
  ```
795
911
 
796
- ### Rutas de Importación
912
+ ### Import Paths / Rutas de Importación
797
913
 
798
914
  ```javascript
799
- // Librería principal (Vanilla JS)
915
+ // Main library (Vanilla JS) / Librería principal (Vanilla JS)
800
916
  import PhoneLib from '@jacksonavila/phone-lib';
801
917
 
802
- // Componente React
918
+ // React component / Componente React
803
919
  import PhoneLibReact from '@jacksonavila/phone-lib/react';
804
920
 
805
- // Estilos CSS
921
+ // CSS styles / Estilos CSS
806
922
  import '@jacksonavila/phone-lib/css';
807
923
 
808
- // O con rutas completas
924
+ // Or with full paths / O con rutas completas
809
925
  import PhoneLib from '@jacksonavila/phone-lib/phone-lib.js';
810
926
  import PhoneLibReact from '@jacksonavila/phone-lib/phone-lib-react.jsx';
811
927
  import '@jacksonavila/phone-lib/phone-lib.css';
812
928
  ```
813
929
 
814
- ## 🤝 Contribuir
930
+ ---
931
+
932
+ ## 🤝 Contributing / Contribuir
933
+
934
+ Contributions are welcome / Las contribuciones son bienvenidas. Please / Por favor:
815
935
 
816
- Las contribuciones son bienvenidas. Por favor:
936
+ 1. Fork the project / Haz fork del proyecto
937
+ 2. Create a feature branch / Crea una rama para tu feature (`git checkout -b feature/AmazingFeature`)
938
+ 3. Commit your changes / Commit tus cambios (`git commit -m 'Add some AmazingFeature'`)
939
+ 4. Push to the branch / Push a la rama (`git push origin feature/AmazingFeature`)
940
+ 5. Open a Pull Request / Abre un Pull Request
817
941
 
818
- 1. Fork el proyecto
819
- 2. Crea una rama para tu feature (`git checkout -b feature/AmazingFeature`)
820
- 3. Commit tus cambios (`git commit -m 'Add some AmazingFeature'`)
821
- 4. Push a la rama (`git push origin feature/AmazingFeature`)
822
- 5. Abre un Pull Request
942
+ ---
943
+
944
+ ## 📄 License / Licencia
823
945
 
824
- ## 📄 Licencia
946
+ This project is licensed under the MIT License / Este proyecto está bajo la Licencia MIT - see the [LICENSE](LICENSE) file for details / ver el archivo [LICENSE](LICENSE) para más detalles.
825
947
 
826
- Este proyecto está bajo la Licencia MIT - ver el archivo [LICENSE](LICENSE) para más detalles.
948
+ ---
827
949
 
828
- ## 🙏 Agradecimientos
950
+ ## 🙏 Acknowledgments / Agradecimientos
829
951
 
830
- - [libphonenumber-js](https://github.com/catamphetamine/libphonenumber-js) - Para validación y formato de números telefónicos
952
+ - [libphonenumber-js](https://github.com/catamphetamine/libphonenumber-js) - For phone number validation and formatting / Para validación y formato de números telefónicos
953
+
954
+ ---
831
955
 
832
- ## 📞 Soporte
956
+ ## 📞 Support / Soporte
833
957
 
834
- Si tienes preguntas o encuentras algún problema:
958
+ If you have questions or find any issues / Si tienes preguntas o encuentras algún problema:
835
959
 
836
- - Abre un [issue](https://github.com/tu-usuario/phone-lib/issues) en GitHub
837
- - Consulta la [documentación completa](./USAGE.md)
838
- - Revisa los [ejemplos](./demo.html)
960
+ - Open an [issue](https://github.com/tu-usuario/phone-lib/issues) on GitHub
961
+ - Check the [complete documentation](./USAGE.md) / Consulta la [documentación completa](./USAGE.md)
962
+ - Review the [examples](./demo.html) / Revisa los [ejemplos](./demo.html)
839
963
 
840
964
  ---
841
965
 
842
- **Hecho con ❤️ para la comunidad de desarrolladores**
966
+ **Made with ❤️ for the developer community / Hecho con ❤️ para la comunidad de desarrolladores**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jacksonavila/phone-lib",
3
- "version": "2.0.1",
3
+ "version": "2.0.3",
4
4
  "description": "Librería JavaScript para input de teléfono con selector de país y banderas - Compatible con Vanilla JS y React",
5
5
  "main": "phone-lib.js",
6
6
  "module": "phone-lib.js",
@@ -14,11 +14,13 @@
14
14
  "import": "./phone-lib-react.jsx",
15
15
  "require": "./phone-lib-react.js"
16
16
  },
17
- "./css": "./phone-lib.css"
17
+ "./css": "./phone-lib.css",
18
+ "./cdn": "./phone-lib.cdn.js"
18
19
  },
19
20
  "scripts": {
20
21
  "serve": "npx http-server . -p 3004 -o",
21
- "prepublishOnly": "echo 'Verificando archivos antes de publicar...' && node --check phone-lib.js"
22
+ "prepublishOnly": "echo 'Verificando archivos antes de publicar...' && node --check phone-lib.js",
23
+ "update-version": "node update-version.js"
22
24
  },
23
25
  "keywords": [
24
26
  "phone",
@@ -64,6 +66,7 @@
64
66
  "files": [
65
67
  "phone-lib.js",
66
68
  "phone-lib.css",
69
+ "phone-lib.cdn.js",
67
70
  "phone-lib-react.jsx",
68
71
  "phone-lib-react.js",
69
72
  "README.md"
@@ -71,4 +74,4 @@
71
74
  "engines": {
72
75
  "node": ">=14.0.0"
73
76
  }
74
- }
77
+ }
@@ -0,0 +1,101 @@
1
+ /**
2
+ * PhoneLib CDN Version
3
+ * Versión para uso directo desde CDN con script tag
4
+ * Carga libphonenumber-js dinámicamente y expone PhoneLib globalmente
5
+ *
6
+ * Uso:
7
+ * <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jacksonavila/phone-lib@2.0.3/phone-lib.css">
8
+ * <script src="https://cdn.jsdelivr.net/npm/@jacksonavila/phone-lib@2.0.3/phone-lib.cdn.js"></script>
9
+ * <script>
10
+ * document.addEventListener('phoneLibReady', () => {
11
+ * const phoneLib = new PhoneLib('#container', {...});
12
+ * });
13
+ * </script>
14
+ */
15
+
16
+ (function () {
17
+ 'use strict';
18
+
19
+ // Versión del paquete (actualizar cuando se publique nueva versión)
20
+ const PACKAGE_VERSION = '2.0.3';
21
+ const PACKAGE_NAME = '@jacksonavila/phone-lib';
22
+
23
+ // URLs de CDN
24
+ const CDN_BASE = `https://cdn.jsdelivr.net/npm/${PACKAGE_NAME}@${PACKAGE_VERSION}`;
25
+ const LIBPHONENUMBER_CDN = 'https://esm.sh/libphonenumber-js@1.11.0';
26
+
27
+ // Cargar CSS automáticamente
28
+ function loadCSS() {
29
+ const linkId = 'phone-lib-css';
30
+ if (!document.getElementById(linkId)) {
31
+ const link = document.createElement('link');
32
+ link.id = linkId;
33
+ link.rel = 'stylesheet';
34
+ link.href = `${CDN_BASE}/phone-lib.css`;
35
+ document.head.appendChild(link);
36
+ }
37
+ }
38
+
39
+ // Cargar libphonenumber-js y phone-lib.js dinámicamente
40
+ async function loadPhoneLib() {
41
+ try {
42
+ // Cargar libphonenumber-js primero
43
+ const libphonenumber = await import(LIBPHONENUMBER_CDN);
44
+
45
+ // Crear un módulo temporal que exponga libphonenumber-js
46
+ // Esto es necesario porque phone-lib.js importa desde 'libphonenumber-js'
47
+ window.__libphonenumberjs = libphonenumber;
48
+
49
+ // Crear un import map dinámico para que phone-lib.js pueda importar libphonenumber-js
50
+ if (!document.querySelector('script[type="importmap"]')) {
51
+ const importMap = document.createElement('script');
52
+ importMap.type = 'importmap';
53
+ importMap.textContent = JSON.stringify({
54
+ imports: {
55
+ 'libphonenumber-js': LIBPHONENUMBER_CDN
56
+ }
57
+ });
58
+ document.head.appendChild(importMap);
59
+ }
60
+
61
+ // Cargar phone-lib.js desde CDN
62
+ const phoneLibModule = await import(`${CDN_BASE}/phone-lib.js`);
63
+
64
+ // Exponer PhoneLib globalmente
65
+ window.PhoneLib = phoneLibModule.default || phoneLibModule.PhoneLib;
66
+
67
+ // Disparar evento cuando esté listo
68
+ const event = new CustomEvent('phoneLibReady', {
69
+ detail: { PhoneLib: window.PhoneLib }
70
+ });
71
+ document.dispatchEvent(event);
72
+
73
+ return window.PhoneLib;
74
+ } catch (error) {
75
+ console.error('Error loading PhoneLib:', error);
76
+ const event = new CustomEvent('phoneLibError', {
77
+ detail: { error }
78
+ });
79
+ document.dispatchEvent(event);
80
+ throw error;
81
+ }
82
+ }
83
+
84
+ // Inicializar
85
+ function init() {
86
+ // Cargar CSS primero
87
+ loadCSS();
88
+
89
+ // Cargar PhoneLib
90
+ loadPhoneLib().catch(err => {
91
+ console.error('Failed to load PhoneLib:', err);
92
+ });
93
+ }
94
+
95
+ // Inicializar cuando el DOM esté listo
96
+ if (document.readyState === 'loading') {
97
+ document.addEventListener('DOMContentLoaded', init);
98
+ } else {
99
+ init();
100
+ }
101
+ })();