@jacksonavila/phone-lib 2.0.0 → 2.0.2

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 (2) hide show
  1. package/README.md +652 -230
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,275 +1,572 @@
1
1
  # PhoneLib 📱
2
2
 
3
- Librería JavaScript 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**.
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
4
 
5
- ## Características
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**.
6
6
 
7
- - ✅ Dropdown con países mostrando nombre, código ISO2, código de marcación y bandera
8
- - ✅ Input de tipo "tel" con formato automático según el país seleccionado
9
- - ✅ Validación de números telefónicos usando `libphonenumber-js`
10
- - ✅ API pública completa con métodos para obtener información del número
11
- - ✅ Opciones de configuración flexibles
12
- - ✅ Estilos CSS modernos y responsivos
13
- - ✅ **Soporte para Vanilla JavaScript y React**
14
- - ✅ Eventos y callbacks personalizables
15
- - ✅ Control programático completo
16
- - ✅ Detección automática de país
17
- - ✅ Filtrado de países
18
- - ✅ Modo readonly/disabled
7
+ [![npm version](https://img.shields.io/npm/v/@jacksonavila/phone-lib.svg)](https://www.npmjs.com/package/@jacksonavila/phone-lib)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
19
9
 
20
- ## Instalación
10
+ ---
21
11
 
22
- ### Desde npm (Después de publicar)
12
+ ## Features / Características
23
13
 
24
- ```bash
25
- npm install @jacksonavila/phone-lib
26
- ```
27
-
28
- ### Desarrollo Local
29
-
30
- ```bash
31
- npm install
32
- ```
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)
33
27
 
34
- ## 🚀 Cómo Probar la Librería
28
+ ---
35
29
 
36
- ### Opción Rápida (Recomendada)
30
+ ## 📦 Installation / Instalación
37
31
 
38
32
  ```bash
39
- # 1. Instalar dependencias
40
- npm install
41
-
42
- # 2. Iniciar servidor de desarrollo
43
- npm run serve
33
+ npm install @jacksonavila/phone-lib
44
34
  ```
45
35
 
46
- Esto abrirá automáticamente tu navegador en `http://localhost:3004` con todos los demos disponibles.
47
-
48
- ### Archivos de Demo Disponibles
49
-
50
- Una vez que el servidor esté corriendo, puedes probar:
51
-
52
- - **`demo.html`** - Ejemplo básico con layout integrado
53
- - **`demo-separated.html`** - Layout separado
54
- - **`demo-all-layouts.html`** - Comparación de todos los layouts
55
- - **`demo-features.html`** - Todas las nuevas características (eventos, control programático, etc.)
56
- - **`demo-react.html`** - Ejemplo con React
57
-
58
- ### Otras Opciones de Servidor
36
+ ### Dependencies / Dependencias
59
37
 
60
38
  ```bash
61
- # Python 3
62
- python -m http.server 8000
63
-
64
- # Node.js http-server
65
- npx http-server . -p 8080 -o
39
+ # For React projects / Para proyectos React
40
+ npm install react react-dom
66
41
 
67
- # PHP
68
- php -S localhost:8000
42
+ # libphonenumber-js is installed automatically
43
+ # libphonenumber-js se instala automáticamente
69
44
  ```
70
45
 
71
- **⚠️ Importante:** No abras los archivos directamente con `file://` - necesitas un servidor HTTP debido a los módulos ES6.
46
+ ---
72
47
 
73
- 📖 **Para más detalles sobre cómo probar**, consulta [`TESTING.md`](./TESTING.md)
48
+ ## 🚀 Quick Start / Inicio Rápido
74
49
 
75
- ## Uso Básico
76
-
77
- ### HTML
50
+ ### Vanilla JavaScript
78
51
 
79
52
  ```html
80
53
  <!DOCTYPE html>
81
54
  <html>
82
55
  <head>
83
- <link rel="stylesheet" href="phone-lib.css">
56
+ <link rel="stylesheet" href="node_modules/@jacksonavila/phone-lib/phone-lib.css">
84
57
  </head>
85
58
  <body>
86
59
  <div id="phone-container"></div>
87
-
60
+
88
61
  <script type="module">
89
- import PhoneLib from './phone-lib.js';
90
-
62
+ import PhoneLib from '@jacksonavila/phone-lib';
63
+
91
64
  const phoneLib = new PhoneLib('#phone-container', {
92
65
  initialCountry: 'CO',
93
- preferredCountries: ['CO', 'US', 'ES'],
94
- showHint: true
66
+ layout: 'integrated',
67
+ showDialCode: true
95
68
  });
69
+
70
+ // Get number information / Obtener información del número
71
+ const info = phoneLib.getInfo();
72
+ console.log(info);
96
73
  </script>
97
74
  </body>
98
75
  </html>
99
76
  ```
100
77
 
101
- ### Opciones de Configuración
78
+ ### React
79
+
80
+ ```jsx
81
+ import React from 'react';
82
+ import PhoneLibReact from '@jacksonavila/phone-lib/react';
83
+ import '@jacksonavila/phone-lib/css';
84
+
85
+ function App() {
86
+ return (
87
+ <PhoneLibReact
88
+ initialCountry="CO"
89
+ layout="integrated"
90
+ showDialCode={true}
91
+ />
92
+ );
93
+ }
94
+
95
+ export default App;
96
+ ```
97
+
98
+ ---
99
+
100
+ ## 📖 Complete Usage Guide / Guía de Uso Completa
101
+
102
+ ### Vanilla JavaScript
103
+
104
+ #### Basic Example / Ejemplo Básico
102
105
 
103
106
  ```javascript
104
- const phoneLib = new PhoneLib(container, {
105
- initialCountry: 'CO', // País inicial (código ISO2)
106
- preferredCountries: ['CO', 'US'], // Países que aparecen primero en la lista
107
- showHint: true, // Mostrar hint de validación
108
- layout: 'integrated', // 'integrated' o 'separated'
109
- showDialCode: true // Mostrar código de marcación (true/false)
107
+ import PhoneLib from '@jacksonavila/phone-lib';
108
+ import '@jacksonavila/phone-lib/css';
109
+
110
+ const phoneLib = new PhoneLib('#phone-container', {
111
+ initialCountry: 'CO',
112
+ preferredCountries: ['CO', 'US', 'ES'],
113
+ showHint: true,
114
+ layout: 'integrated',
115
+ showDialCode: true
110
116
  });
111
117
  ```
112
118
 
113
- ### Ejemplos de Layouts
119
+ #### With Events and Callbacks / Con Eventos y Callbacks
114
120
 
115
- **Layout Integrado con código:**
116
121
  ```javascript
122
+ import PhoneLib from '@jacksonavila/phone-lib';
123
+ import '@jacksonavila/phone-lib/css';
124
+
117
125
  const phoneLib = new PhoneLib('#phone-container', {
126
+ initialCountry: 'CO',
127
+
128
+ // Callbacks
129
+ onCountryChange: (country, dialCode, countryName) => {
130
+ console.log('Country changed / País cambiado:', country, dialCode, countryName);
131
+ },
132
+
133
+ onPhoneChange: (phoneNumber, isValid, country) => {
134
+ console.log('Number / Número:', phoneNumber, 'Valid / Válido:', isValid);
135
+ if (isValid) {
136
+ const info = phoneLib.getInfo();
137
+ console.log('Complete info / Información completa:', info);
138
+ }
139
+ },
140
+
141
+ onValidationChange: (isValid, phoneNumber) => {
142
+ console.log('Validation / Validación:', isValid ? 'Valid / Válido' : 'Invalid / Inválido');
143
+ },
144
+
145
+ onFocus: () => console.log('Input focused / Input enfocado'),
146
+ onBlur: () => console.log('Input blurred / Input perdió foco')
147
+ });
148
+
149
+ // Listen to custom DOM events / Escuchar eventos DOM personalizados
150
+ document.getElementById('phone-container').addEventListener('phoneLib:countryChange', (e) => {
151
+ console.log('DOM event / Evento DOM:', e.detail);
152
+ });
153
+ ```
154
+
155
+ #### Programmatic Control / Control Programático
156
+
157
+ ```javascript
158
+ // Set values / Establecer valores
159
+ phoneLib.setCountry('ES');
160
+ phoneLib.setPhoneNumber('+34600123456');
161
+ phoneLib.setValue('US', '5551234567');
162
+
163
+ // Control state / Controlar estado
164
+ phoneLib.enable();
165
+ phoneLib.disable();
166
+ phoneLib.reset();
167
+
168
+ // Get information / Obtener información
169
+ const country = phoneLib.getCountry(); // 'CO'
170
+ const dialCode = phoneLib.getDialCode(); // '+57'
171
+ const raw = phoneLib.getRaw(); // '3001234567'
172
+ const e164 = phoneLib.getE164(); // '+573001234567'
173
+ const isValid = phoneLib.isValid(); // true/false
174
+ const info = phoneLib.getInfo(); // Complete object / Objeto completo
175
+ ```
176
+
177
+ #### Form Integration / Integración con Formularios
178
+
179
+ ```html
180
+ <form id="contact-form">
181
+ <div id="phone-container"></div>
182
+ <button type="submit">Submit / Enviar</button>
183
+ </form>
184
+
185
+ <script type="module">
186
+ import PhoneLib from '@jacksonavila/phone-lib';
187
+ import '@jacksonavila/phone-lib/css';
188
+
189
+ const phoneLib = new PhoneLib('#phone-container', {
190
+ initialCountry: 'CO',
191
+ validateOnInput: true
192
+ });
193
+
194
+ document.getElementById('contact-form').addEventListener('submit', (e) => {
195
+ e.preventDefault();
196
+
197
+ const phoneInfo = phoneLib.getInfo();
198
+
199
+ if (!phoneInfo.isValid) {
200
+ alert('Please enter a valid number / Por favor ingrese un número válido');
201
+ return;
202
+ }
203
+
204
+ // Send data / Enviar datos
205
+ const formData = {
206
+ phone: phoneInfo.e164,
207
+ country: phoneInfo.country,
208
+ // ... other fields / otros campos
209
+ };
210
+
211
+ console.log('Sending / Enviando:', formData);
212
+ });
213
+ </script>
214
+ ```
215
+
216
+ ### React
217
+
218
+ #### Basic Example / Ejemplo Básico
219
+
220
+ ```jsx
221
+ import React from 'react';
222
+ import PhoneLibReact from '@jacksonavila/phone-lib/react';
223
+ import '@jacksonavila/phone-lib/css';
224
+
225
+ function App() {
226
+ return (
227
+ <PhoneLibReact
228
+ initialCountry="CO"
229
+ layout="integrated"
230
+ showDialCode={true}
231
+ />
232
+ );
233
+ }
234
+
235
+ export default App;
236
+ ```
237
+
238
+ #### With Ref and Methods / Con Ref y Métodos
239
+
240
+ ```jsx
241
+ import React, { useRef } from 'react';
242
+ import PhoneLibReact from '@jacksonavila/phone-lib/react';
243
+ import '@jacksonavila/phone-lib/css';
244
+
245
+ function App() {
246
+ const phoneLibRef = useRef(null);
247
+
248
+ const handleSubmit = () => {
249
+ const info = phoneLibRef.current.getInfo();
250
+
251
+ if (!info.isValid) {
252
+ alert('Invalid number / Número inválido');
253
+ return;
254
+ }
255
+
256
+ console.log('Send / Enviar:', info.e164);
257
+ };
258
+
259
+ return (
260
+ <div>
261
+ <PhoneLibReact
262
+ ref={phoneLibRef}
263
+ initialCountry="CO"
264
+ layout="integrated"
265
+ onPhoneChange={(phone, isValid) => {
266
+ console.log('Number / Número:', phone, 'Valid / Válido:', isValid);
267
+ }}
268
+ />
269
+ <button onClick={handleSubmit}>Submit / Enviar</button>
270
+ </div>
271
+ );
272
+ }
273
+ ```
274
+
275
+ #### With React State / Con Estado de React
276
+
277
+ ```jsx
278
+ import React, { useState, useRef } from 'react';
279
+ import PhoneLibReact from '@jacksonavila/phone-lib/react';
280
+ import '@jacksonavila/phone-lib/css';
281
+
282
+ function PhoneForm() {
283
+ const phoneLibRef = useRef(null);
284
+ const [phoneData, setPhoneData] = useState(null);
285
+
286
+ const handleGetData = () => {
287
+ const info = phoneLibRef.current.getInfo();
288
+ setPhoneData(info);
289
+ };
290
+
291
+ return (
292
+ <div>
293
+ <PhoneLibReact
294
+ ref={phoneLibRef}
295
+ initialCountry="CO"
296
+ onPhoneChange={(phone, isValid) => {
297
+ if (isValid) {
298
+ const info = phoneLibRef.current.getInfo();
299
+ setPhoneData(info);
300
+ }
301
+ }}
302
+ />
303
+
304
+ {phoneData && (
305
+ <div>
306
+ <p>Country / País: {phoneData.country}</p>
307
+ <p>Number / Número: {phoneData.e164}</p>
308
+ <p>Valid / Válido: {phoneData.isValid ? 'Yes / Sí' : 'No'}</p>
309
+ </div>
310
+ )}
311
+ </div>
312
+ );
313
+ }
314
+ ```
315
+
316
+ #### React Form Integration / Integración con Formularios React
317
+
318
+ ```jsx
319
+ import React, { useRef } from 'react';
320
+ import PhoneLibReact from '@jacksonavila/phone-lib/react';
321
+ import '@jacksonavila/phone-lib/css';
322
+
323
+ function ContactForm() {
324
+ const phoneLibRef = useRef(null);
325
+ const formRef = useRef(null);
326
+
327
+ const handleSubmit = (e) => {
328
+ e.preventDefault();
329
+
330
+ const phoneInfo = phoneLibRef.current.getInfo();
331
+
332
+ if (!phoneInfo.isValid) {
333
+ alert('Please enter a valid number / Por favor ingrese un número válido');
334
+ return;
335
+ }
336
+
337
+ const formData = {
338
+ name: formRef.current.name.value,
339
+ email: formRef.current.email.value,
340
+ phone: phoneInfo.e164,
341
+ country: phoneInfo.country
342
+ };
343
+
344
+ // Send data / Enviar datos
345
+ fetch('/api/contact', {
346
+ method: 'POST',
347
+ headers: { 'Content-Type': 'application/json' },
348
+ body: JSON.stringify(formData)
349
+ });
350
+ };
351
+
352
+ return (
353
+ <form ref={formRef} onSubmit={handleSubmit}>
354
+ <input name="name" placeholder="Name / Nombre" required />
355
+ <input name="email" type="email" placeholder="Email" required />
356
+
357
+ <PhoneLibReact
358
+ ref={phoneLibRef}
359
+ initialCountry="CO"
360
+ validateOnInput={true}
361
+ />
362
+
363
+ <button type="submit">Submit / Enviar</button>
364
+ </form>
365
+ );
366
+ }
367
+ ```
368
+
369
+ ---
370
+
371
+ ## 🎨 Available Layouts / Layouts Disponibles
372
+
373
+ ### Integrated Layout / Layout Integrado (Default)
374
+
375
+ 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:
376
+
377
+ ```javascript
378
+ const phoneLib = new PhoneLib('#container', {
118
379
  layout: 'integrated',
119
- showDialCode: true // Muestra +57 en el botón
380
+ showDialCode: true // Shows +57 in button / Muestra +57 en el botón
120
381
  });
121
382
  ```
122
383
 
123
- **Layout Integrado sin código:**
384
+ **With code visible / Con código visible:**
385
+ - Shows / Muestra: `[🇨🇴 +57 ▼] [300 123 4567]`
386
+
387
+ **Without code visible / Sin código visible:**
124
388
  ```javascript
125
- const phoneLib = new PhoneLib('#phone-container', {
389
+ const phoneLib = new PhoneLib('#container', {
126
390
  layout: 'integrated',
127
- showDialCode: false // Solo muestra la bandera
391
+ showDialCode: false // Only shows flag / Solo muestra la bandera
128
392
  });
129
393
  ```
394
+ - Shows / Muestra: `[🇨🇴 ▼] [300 123 4567]`
395
+
396
+ ### Separated Layout / Layout Separado
397
+
398
+ Fields are separated in a row / Los campos están separados en una fila:
130
399
 
131
- **Layout Separado con código:**
132
400
  ```javascript
133
- const phoneLib = new PhoneLib('#phone-container', {
401
+ const phoneLib = new PhoneLib('#container', {
134
402
  layout: 'separated',
135
- showDialCode: true // Muestra campo "Código" separado
403
+ showDialCode: true // Shows separate "Code" field / Muestra campo "Código" separado
136
404
  });
137
405
  ```
138
406
 
139
- **Layout Separado sin código:**
407
+ **With code visible / Con código visible:**
408
+ - Shows / Muestra: `[Country / País: 🇨🇴 Colombia ▼] [Code / Código: +57] [Number / Número: 300 123 4567]`
409
+
410
+ **Without code visible / Sin código visible:**
140
411
  ```javascript
141
- const phoneLib = new PhoneLib('#phone-container', {
412
+ const phoneLib = new PhoneLib('#container', {
142
413
  layout: 'separated',
143
- showDialCode: false // Solo muestra País y Número
414
+ showDialCode: false // Only shows Country and Number / Solo muestra País y Número
144
415
  });
145
416
  ```
417
+ - Shows / Muestra: `[Country / País: 🇨🇴 Colombia ▼] [Number / Número: 300 123 4567]`
146
418
 
147
- ### Estilos Personalizados
419
+ ---
148
420
 
149
- Puedes personalizar los estilos usando clases CSS o estilos inline:
421
+ ## ⚙️ Configuration Options / Opciones de Configuración
422
+
423
+ ### Basic Options / Opciones Básicas
150
424
 
151
- **Con clases CSS personalizadas:**
152
425
  ```javascript
153
- const phoneLib = new PhoneLib('#phone-container', {
154
- layout: 'integrated',
155
- customClasses: {
156
- wrapper: 'mi-clase-personalizada',
157
- dropdownButton: 'mi-boton-personalizado',
158
- input: 'mi-input-personalizado'
159
- }
160
- });
426
+ {
427
+ initialCountry: 'CO', // Initial country / País inicial (ISO2)
428
+ preferredCountries: ['CO', 'US'], // Countries that appear first / Países que aparecen primero
429
+ showHint: true, // Show validation hint / Mostrar hint de validación
430
+ layout: 'integrated', // 'integrated' or 'separated' / 'integrated' o 'separated'
431
+ showDialCode: true // Show dial code / Mostrar código de marcación
432
+ }
161
433
  ```
162
434
 
163
- **Con estilos inline:**
435
+ ### Advanced Options / Opciones Avanzadas
436
+
164
437
  ```javascript
165
- const phoneLib = new PhoneLib('#phone-container', {
166
- layout: 'integrated',
438
+ {
439
+ // Detection and validation / Detección y validación
440
+ autoDetectCountry: true, // Auto-detect country / Detectar país automáticamente
441
+ validateOnInput: false, // Validate while typing / Validar mientras se escribe
442
+
443
+ // Country filtering / Filtrado de países
444
+ onlyCountries: ['CO', 'US', 'ES'], // Only these countries / Solo estos países
445
+ disabledCountries: ['CU', 'KP'], // Disable these / Deshabilitar estos
446
+ excludeCountries: ['XX'], // Exclude these / Excluir estos
447
+
448
+ // States / Estados
449
+ readonly: false, // Read-only mode / Modo solo lectura
450
+ disabled: false, // Disabled component / Componente deshabilitado
451
+
452
+ // Customization / Personalización
453
+ placeholder: 'Enter your number', // Custom placeholder / Placeholder personalizado
454
+ countryLabel: 'Country', // Label for selector / Label para selector
455
+ dialCodeLabel: 'Code', // Label for code / Label para código
456
+ phoneLabel: 'Phone number', // Label for number / Label para número
457
+
458
+ // Messages / Mensajes
459
+ messages: {
460
+ invalid: 'Invalid number',
461
+ valid: '✓ Valid number'
462
+ },
463
+
464
+ // Styles / Estilos
465
+ customClasses: {
466
+ wrapper: 'my-class',
467
+ input: 'my-input'
468
+ },
167
469
  customStyles: {
168
- dropdownButton: {
169
- backgroundColor: '#4a90e2',
170
- borderRadius: '20px',
171
- color: 'white'
172
- },
173
470
  input: {
174
- borderColor: '#4a90e2',
175
- fontSize: '18px'
471
+ borderColor: '#4a90e2'
176
472
  }
177
473
  }
178
- });
474
+ }
179
475
  ```
180
476
 
181
- **Combinando ambos métodos:**
477
+ ### Callbacks and Events / Callbacks y Eventos
478
+
182
479
  ```javascript
183
- const phoneLib = new PhoneLib('#phone-container', {
184
- layout: 'separated',
185
- customClasses: {
186
- wrapper: 'mi-tema-personalizado'
480
+ {
481
+ onCountryChange: (country, dialCode, countryName) => {
482
+ // Country changed / País cambiado
187
483
  },
188
- customStyles: {
189
- row: {
190
- gap: '20px'
191
- },
192
- input: {
193
- borderColor: '#27ae60'
194
- }
484
+ onPhoneChange: (phoneNumber, isValid, country) => {
485
+ // Number changed / Número cambiado
486
+ },
487
+ onValidationChange: (isValid, phoneNumber) => {
488
+ // Validation changed / Validación cambiada
489
+ },
490
+ onFocus: () => {
491
+ // Input focused / Input enfocado
492
+ },
493
+ onBlur: () => {
494
+ // Input blurred / Input perdió foco
195
495
  }
196
- });
496
+ }
197
497
  ```
198
498
 
199
- **Elementos personalizables:**
200
- - `wrapper` - Contenedor principal
201
- - `dropdownButton` - Botón del selector de país
202
- - `input` - Campo de entrada de teléfono
203
- - `dialCodeInput` - Campo de código (solo layout separado)
204
- - `row` - Fila del grid (solo layout separado)
499
+ ---
205
500
 
206
- ## API Pública
501
+ ## 📚 Public API
207
502
 
208
- ### `getCountry()`
209
- Devuelve el código ISO2 del país seleccionado.
503
+ ### Reading Methods / Métodos de Lectura
504
+
505
+ #### `getCountry()`
506
+ Returns the ISO2 code of the selected country / Devuelve el código ISO2 del país seleccionado.
210
507
 
211
508
  ```javascript
212
509
  const country = phoneLib.getCountry(); // 'CO'
213
510
  ```
214
511
 
215
- ### `getDialCode()`
216
- Devuelve el código de marcación del país seleccionado.
512
+ #### `getDialCode()`
513
+ Returns the dial code of the selected country / Devuelve el código de marcación del país seleccionado.
217
514
 
218
515
  ```javascript
219
516
  const dialCode = phoneLib.getDialCode(); // '+57'
220
517
  ```
221
518
 
222
- ### `getRaw()`
223
- Devuelve el número ingresado sin formato.
519
+ #### `getRaw()`
520
+ Returns the entered number without formatting (digits only) / Devuelve el número ingresado sin formato (solo dígitos).
224
521
 
225
522
  ```javascript
226
523
  const raw = phoneLib.getRaw(); // '3001234567'
227
524
  ```
228
525
 
229
- ### `getE164()`
230
- Devuelve el número en formato E.164.
526
+ #### `getE164()`
527
+ Returns the number in E.164 format / Devuelve el número en formato E.164.
231
528
 
232
529
  ```javascript
233
530
  const e164 = phoneLib.getE164(); // '+573001234567'
234
531
  ```
235
532
 
236
- ### `isValid()`
237
- Devuelve `true` si el número es válido, `false` en caso contrario.
533
+ #### `isValid()`
534
+ Returns `true` if the number is valid, `false` otherwise / Devuelve `true` si el número es válido, `false` en caso contrario.
238
535
 
239
536
  ```javascript
240
537
  const isValid = phoneLib.isValid(); // true o false
241
538
  ```
242
539
 
243
- ### `formatInternational()`
244
- Devuelve el número en formato internacional.
540
+ #### `formatInternational()`
541
+ Returns the number in international format / Devuelve el número en formato internacional.
245
542
 
246
543
  ```javascript
247
544
  const international = phoneLib.formatInternational(); // '+57 300 123 4567'
248
545
  ```
249
546
 
250
- ### `formatNational()`
251
- Devuelve el número en formato nacional.
547
+ #### `formatNational()`
548
+ Returns the number in national format / Devuelve el número en formato nacional.
252
549
 
253
550
  ```javascript
254
551
  const national = phoneLib.formatNational(); // '300 123 4567'
255
552
  ```
256
553
 
257
- ### `formatRFC3966()`
258
- Devuelve el número en formato RFC3966.
554
+ #### `formatRFC3966()`
555
+ Returns the number in RFC3966 format / Devuelve el número en formato RFC3966.
259
556
 
260
557
  ```javascript
261
558
  const rfc3966 = phoneLib.formatRFC3966(); // 'tel:+57-300-123-4567'
262
559
  ```
263
560
 
264
- ### `getNumberType()`
265
- Devuelve el tipo de número (MOBILE, FIXED_LINE, etc.).
561
+ #### `getNumberType()`
562
+ Returns the number type (MOBILE, FIXED_LINE, etc.) / Devuelve el tipo de número (MOBILE, FIXED_LINE, etc.).
266
563
 
267
564
  ```javascript
268
565
  const type = phoneLib.getNumberType(); // 'MOBILE' o null
269
566
  ```
270
567
 
271
- ### `getInfo()`
272
- Devuelve un objeto con toda la información del número.
568
+ #### `getInfo()`
569
+ Returns an object with all number information / Devuelve un objeto con toda la información del número.
273
570
 
274
571
  ```javascript
275
572
  const info = phoneLib.getInfo();
@@ -287,8 +584,8 @@ const info = phoneLib.getInfo();
287
584
  // }
288
585
  ```
289
586
 
290
- ### `getCountryMetadata()`
291
- Devuelve información completa del país seleccionado.
587
+ #### `getCountryMetadata()`
588
+ Returns complete information about the selected country / Devuelve información completa del país seleccionado.
292
589
 
293
590
  ```javascript
294
591
  const metadata = phoneLib.getCountryMetadata();
@@ -300,51 +597,53 @@ const metadata = phoneLib.getCountryMetadata();
300
597
  // }
301
598
  ```
302
599
 
303
- ### `setCountry(iso2)`
304
- Establece el país programáticamente.
600
+ ### Control Methods / Métodos de Control
601
+
602
+ #### `setCountry(iso2)`
603
+ Sets the country programmatically / Establece el país programáticamente.
305
604
 
306
605
  ```javascript
307
606
  phoneLib.setCountry('ES');
308
607
  ```
309
608
 
310
- ### `setPhoneNumber(number)`
311
- Establece el número telefónico programáticamente.
609
+ #### `setPhoneNumber(number)`
610
+ Sets the phone number programmatically / Establece el número telefónico programáticamente.
312
611
 
313
612
  ```javascript
314
613
  phoneLib.setPhoneNumber('+34600123456');
315
614
  ```
316
615
 
317
- ### `setValue(country, number)`
318
- Establece país y número juntos.
616
+ #### `setValue(country, number)`
617
+ Sets both country and number / Establece país y número juntos.
319
618
 
320
619
  ```javascript
321
620
  phoneLib.setValue('ES', '600123456');
322
621
  ```
323
622
 
324
- ### `enable()` / `disable()`
325
- Habilita o deshabilita el componente.
623
+ #### `enable()` / `disable()`
624
+ Enables or disables the component / Habilita o deshabilita el componente.
326
625
 
327
626
  ```javascript
328
627
  phoneLib.enable();
329
628
  phoneLib.disable();
330
629
  ```
331
630
 
332
- ### `reset()`
333
- Resetea el componente a valores iniciales.
631
+ #### `reset()`
632
+ Resets the component to initial values / Resetea el componente a valores iniciales.
334
633
 
335
634
  ```javascript
336
635
  phoneLib.reset();
337
636
  ```
338
637
 
339
- ### `destroy()`
340
- Destruye la instancia y limpia recursos.
638
+ #### `destroy()`
639
+ Destroys the instance and cleans up resources / Destruye la instancia y limpia recursos.
341
640
 
342
641
  ```javascript
343
642
  phoneLib.destroy();
344
643
  ```
345
644
 
346
- ### `updateOptions(newOptions)`
347
- Actualiza opciones dinámicamente.
645
+ #### `updateOptions(newOptions)`
646
+ Updates options dynamically / Actualiza opciones dinámicamente.
348
647
 
349
648
  ```javascript
350
649
  phoneLib.updateOptions({
@@ -352,104 +651,227 @@ phoneLib.updateOptions({
352
651
  });
353
652
  ```
354
653
 
355
- ## Ejemplos Completos
654
+ ---
356
655
 
357
- ### Vanilla JavaScript
358
- - `demo.html` - Layout integrado con código
359
- - `demo-separated.html` - Layout separado con código
360
- - `demo-all-layouts.html` - Comparación de todos los layouts disponibles
361
- - `demo-features.html` - Demostración de todas las nuevas características
362
-
363
- ### React
364
- - `demo-react.html` - Ejemplo básico con React (usando Babel Standalone para demo)
365
- - `phone-lib-react.jsx` - Componente React completo para usar en tu proyecto
366
-
367
- Ver estos archivos para ejemplos completos de integración con actualización en tiempo real de la información del número.
656
+ ## 🎨 Custom Styling / Estilos Personalizados
368
657
 
369
- ## Estructura de Archivos
658
+ ### With CSS Classes / Con Clases CSS
370
659
 
371
- ```
372
- phone-lib/
373
- ├── phone-lib.js # Código principal de la librería (Vanilla JS)
374
- ├── phone-lib.css # Estilos CSS
375
- ├── phone-lib-react.jsx # Componente React wrapper
376
- ├── phone-lib-react.js # Versión CommonJS/ESM del wrapper React
377
- ├── demo.html # Ejemplo básico Vanilla JS
378
- ├── demo-separated.html # Ejemplo layout separado
379
- ├── demo-all-layouts.html # Comparación de layouts
380
- ├── demo-features.html # Nuevas características
381
- ├── demo-react.html # Ejemplo React (demo)
382
- ├── package.json # Dependencias
383
- └── README.md # Documentación
660
+ ```javascript
661
+ const phoneLib = new PhoneLib('#container', {
662
+ customClasses: {
663
+ wrapper: 'my-custom-class',
664
+ dropdownButton: 'my-custom-button',
665
+ input: 'my-custom-input'
666
+ }
667
+ });
384
668
  ```
385
669
 
386
- ## Nuevas Características (v2.0)
670
+ ### With Inline Styles / Con Estilos Inline
387
671
 
388
- ### Eventos y Callbacks
389
672
  ```javascript
390
- const phoneLib = new PhoneLib('#phone-container', {
391
- onCountryChange: (country, dialCode, countryName) => {
392
- console.log('País cambiado:', country, dialCode);
393
- },
394
- onPhoneChange: (phoneNumber, isValid, country) => {
395
- console.log('Número cambiado:', phoneNumber);
396
- },
397
- onValidationChange: (isValid, phoneNumber) => {
398
- console.log('Validación:', isValid);
399
- },
400
- onFocus: () => console.log('Input enfocado'),
401
- onBlur: () => console.log('Input perdió foco')
673
+ const phoneLib = new PhoneLib('#container', {
674
+ customStyles: {
675
+ dropdownButton: {
676
+ backgroundColor: '#4a90e2',
677
+ borderRadius: '20px',
678
+ color: 'white'
679
+ },
680
+ input: {
681
+ borderColor: '#4a90e2',
682
+ fontSize: '18px'
683
+ }
684
+ }
402
685
  });
403
686
  ```
404
687
 
405
- ### Métodos de Control Programático
688
+ ### Customizable Elements / Elementos Personalizables
689
+
690
+ - `wrapper` - Main container / Contenedor principal
691
+ - `dropdownButton` - Country selector button / Botón del selector de país
692
+ - `input` - Phone input field / Campo de entrada de teléfono
693
+ - `dialCodeInput` - Dial code field (separated layout only) / Campo de código (solo layout separado)
694
+ - `row` - Grid row (separated layout only) / Fila del grid (solo layout separado)
695
+
696
+ ---
697
+
698
+ ## 🔧 Advanced Examples / Ejemplos Avanzados
699
+
700
+ ### Automatic Country Detection / Detección Automática de País
701
+
406
702
  ```javascript
407
- phoneLib.setCountry('ES'); // Establecer país
408
- phoneLib.setPhoneNumber('600123456'); // Establecer número
409
- phoneLib.setValue('ES', '600123456'); // Establecer ambos
410
- phoneLib.enable(); // Habilitar
411
- phoneLib.disable(); // Deshabilitar
412
- phoneLib.reset(); // Resetear
413
- phoneLib.destroy(); // Destruir instancia
703
+ const phoneLib = new PhoneLib('#container', {
704
+ autoDetectCountry: true // Detects country when entering +34... / Detecta país al ingresar +34...
705
+ });
706
+
707
+ // User types / Usuario escribe: +34 600 123 456
708
+ // Automatically changes to Spain / Automáticamente cambia a España
414
709
  ```
415
710
 
416
- ### Detección Automática de País
711
+ ### Country Filtering / Filtrado de Países
712
+
417
713
  ```javascript
418
- const phoneLib = new PhoneLib('#phone-container', {
419
- autoDetectCountry: true // Detecta país automáticamente al ingresar +34...
714
+ const phoneLib = new PhoneLib('#container', {
715
+ // Only show these countries / Solo mostrar estos países
716
+ onlyCountries: ['CO', 'US', 'ES', 'MX'],
717
+
718
+ // Disable these countries (appear but can't be selected) / Deshabilitar estos países
719
+ disabledCountries: ['CU', 'KP'],
720
+
721
+ // Exclude these countries (don't appear in list) / Excluir estos países
722
+ excludeCountries: ['XX']
420
723
  });
421
724
  ```
422
725
 
423
- ### Filtrado de Países
726
+ ### Real-time Validation / Validación en Tiempo Real
727
+
424
728
  ```javascript
425
- const phoneLib = new PhoneLib('#phone-container', {
426
- onlyCountries: ['CO', 'US', 'ES'], // Solo estos países
427
- disabledCountries: ['CU', 'KP'], // Deshabilitar estos
428
- excludeCountries: ['XX'] // Excluir estos
729
+ const phoneLib = new PhoneLib('#container', {
730
+ validateOnInput: true, // Validate while user types / Valida mientras el usuario escribe
731
+
732
+ onValidationChange: (isValid) => {
733
+ if (isValid) {
734
+ console.log('Valid number! / ¡Número válido!');
735
+ }
736
+ }
429
737
  });
430
738
  ```
431
739
 
432
- ### Modo Readonly/Disabled
740
+ ### Readonly/Disabled Mode / Modo Readonly/Disabled
741
+
433
742
  ```javascript
434
- const phoneLib = new PhoneLib('#phone-container', {
435
- readonly: true, // Solo lectura
436
- disabled: false // Deshabilitado
743
+ // Read-only / Solo lectura
744
+ const phoneLib = new PhoneLib('#container', {
745
+ readonly: true
746
+ });
747
+
748
+ // Disabled / Deshabilitado
749
+ const phoneLib = new PhoneLib('#container', {
750
+ disabled: true
437
751
  });
438
752
  ```
439
753
 
440
- ### Métodos Adicionales
754
+ ---
755
+
756
+ ## 📱 React Component Props
757
+
758
+ | Prop | Type | Default | Description / Descripción |
759
+ |------|------|---------|--------------------------|
760
+ | `initialCountry` | string | `'US'` | Initial country (ISO2) / País inicial (ISO2) |
761
+ | `preferredCountries` | array | `[]` | Preferred countries / Países preferidos |
762
+ | `showHint` | boolean | `true` | Show validation hint / Mostrar hint de validación |
763
+ | `layout` | string | `'integrated'` | `'integrated'` or `'separated'` / `'integrated'` o `'separated'` |
764
+ | `showDialCode` | boolean | `true` | Show dial code / Mostrar código de marcación |
765
+ | `autoDetectCountry` | boolean | `false` | Auto-detect country / Detectar país automáticamente |
766
+ | `validateOnInput` | boolean | `false` | Validate while typing / Validar mientras se escribe |
767
+ | `disabledCountries` | array | `[]` | Disabled countries / Países deshabilitados |
768
+ | `onlyCountries` | array | `[]` | Only these countries / Solo estos países |
769
+ | `excludeCountries` | array | `[]` | Exclude these countries / Excluir estos países |
770
+ | `readonly` | boolean | `false` | Read-only mode / Modo solo lectura |
771
+ | `disabled` | boolean | `false` | Disabled component / Componente deshabilitado |
772
+ | `placeholder` | string | `null` | Custom placeholder / Placeholder personalizado |
773
+ | `countryLabel` | string | `'Country'` / `'País'` | Label for selector / Label para selector |
774
+ | `dialCodeLabel` | string | `'Code'` / `'Código'` | Label for code / Label para código |
775
+ | `phoneLabel` | string | `'Phone number'` / `'Número de teléfono'` | Label for number / Label para número |
776
+ | `customClasses` | object | `{}` | Custom CSS classes / Clases CSS personalizadas |
777
+ | `customStyles` | object | `{}` | Inline styles / Estilos inline personalizados |
778
+ | `messages` | object | `{}` | Custom messages / Mensajes personalizables |
779
+ | `ariaLabels` | object | `{}` | ARIA labels / Labels ARIA personalizables |
780
+ | `onCountryChange` | function | `null` | Callback when country changes / Callback cuando cambia el país |
781
+ | `onPhoneChange` | function | `null` | Callback when number changes / Callback cuando cambia el número |
782
+ | `onValidationChange` | function | `null` | Callback when validation changes / Callback cuando cambia la validación |
783
+ | `onFocus` | function | `null` | Callback when focused / Callback cuando se enfoca |
784
+ | `onBlur` | function | `null` | Callback when blurred / Callback cuando pierde foco |
785
+
786
+ ---
787
+
788
+ ## 🧪 Development and Testing / Desarrollo y Pruebas
789
+
790
+ ### Run Demos Locally / Ejecutar Demos Localmente
791
+
792
+ ```bash
793
+ # Install dependencies / Instalar dependencias
794
+ npm install
795
+
796
+ # Start development server / Iniciar servidor de desarrollo
797
+ npm run serve
798
+ ```
799
+
800
+ This will open `http://localhost:3004` with all available demos / Esto abrirá `http://localhost:3004` con todos los demos disponibles.
801
+
802
+ ### Demo Files / Archivos de Demo
803
+
804
+ - `demo.html` - Basic integrated layout / Layout integrado básico
805
+ - `demo-separated.html` - Separated layout / Layout separado
806
+ - `demo-all-layouts.html` - All layouts comparison / Comparación de todos los layouts
807
+ - `demo-features.html` - All features / Todas las características
808
+ - `demo-react.html` - React example / Ejemplo con React
809
+
810
+ ---
811
+
812
+ ## 📦 Package Structure / Estructura del Paquete
813
+
814
+ ```
815
+ @jacksonavila/phone-lib/
816
+ ├── phone-lib.js # Main code (Vanilla JS) / Código principal (Vanilla JS)
817
+ ├── phone-lib.css # CSS styles / Estilos CSS
818
+ ├── phone-lib-react.jsx # React component / Componente React
819
+ ├── phone-lib-react.js # CommonJS/ESM React version / Versión CommonJS/ESM React
820
+ └── README.md # Documentation / Documentación
821
+ ```
822
+
823
+ ### Import Paths / Rutas de Importación
824
+
441
825
  ```javascript
442
- phoneLib.formatNational(); // Formato nacional
443
- phoneLib.formatRFC3966(); // Formato RFC3966
444
- phoneLib.getNumberType(); // Tipo (MOBILE, FIXED_LINE, etc.)
445
- phoneLib.getInfo(); // Objeto completo con toda la info
446
- phoneLib.getCountryMetadata(); // Metadata del país
826
+ // Main library (Vanilla JS) / Librería principal (Vanilla JS)
827
+ import PhoneLib from '@jacksonavila/phone-lib';
828
+
829
+ // React component / Componente React
830
+ import PhoneLibReact from '@jacksonavila/phone-lib/react';
831
+
832
+ // CSS styles / Estilos CSS
833
+ import '@jacksonavila/phone-lib/css';
834
+
835
+ // Or with full paths / O con rutas completas
836
+ import PhoneLib from '@jacksonavila/phone-lib/phone-lib.js';
837
+ import PhoneLibReact from '@jacksonavila/phone-lib/phone-lib-react.jsx';
838
+ import '@jacksonavila/phone-lib/phone-lib.css';
447
839
  ```
448
840
 
449
- ## Dependencias
841
+ ---
842
+
843
+ ## 🤝 Contributing / Contribuir
844
+
845
+ Contributions are welcome / Las contribuciones son bienvenidas. Please / Por favor:
846
+
847
+ 1. Fork the project / Haz fork del proyecto
848
+ 2. Create a feature branch / Crea una rama para tu feature (`git checkout -b feature/AmazingFeature`)
849
+ 3. Commit your changes / Commit tus cambios (`git commit -m 'Add some AmazingFeature'`)
850
+ 4. Push to the branch / Push a la rama (`git push origin feature/AmazingFeature`)
851
+ 5. Open a Pull Request / Abre un Pull Request
852
+
853
+ ---
854
+
855
+ ## 📄 License / Licencia
856
+
857
+ 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.
858
+
859
+ ---
860
+
861
+ ## 🙏 Acknowledgments / Agradecimientos
862
+
863
+ - [libphonenumber-js](https://github.com/catamphetamine/libphonenumber-js) - For phone number validation and formatting / Para validación y formato de números telefónicos
864
+
865
+ ---
866
+
867
+ ## 📞 Support / Soporte
868
+
869
+ If you have questions or find any issues / Si tienes preguntas o encuentras algún problema:
450
870
 
451
- - `libphonenumber-js`: Para validación y formato de números telefónicos
871
+ - Open an [issue](https://github.com/tu-usuario/phone-lib/issues) on GitHub
872
+ - Check the [complete documentation](./USAGE.md) / Consulta la [documentación completa](./USAGE.md)
873
+ - Review the [examples](./demo.html) / Revisa los [ejemplos](./demo.html)
452
874
 
453
- ## Licencia
875
+ ---
454
876
 
455
- MIT
877
+ **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.0",
3
+ "version": "2.0.2",
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",