carconnect-gatherleads-ui-lib 2.2.5 → 2.4.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 +150 -0
- package/dist/carconnect-gatherleads-ui-lib.d.ts +108 -12
- package/dist/carconnect-gatherleads-ui-lib.js +4925 -4823
- package/dist/carconnect-gatherleads-ui-lib.umd.cjs +38 -38
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1315,6 +1315,145 @@ interface GatherFormBuilderProps {
|
|
|
1315
1315
|
onSubmit={(data) => console.log(data)}
|
|
1316
1316
|
/>
|
|
1317
1317
|
|
|
1318
|
+
// EJEMPLOS CON ONCHANGE
|
|
1319
|
+
|
|
1320
|
+
// Ejemplo 1:
|
|
1321
|
+
<GatherFormBuilder
|
|
1322
|
+
config={{
|
|
1323
|
+
fields: [
|
|
1324
|
+
{ name: 'user.firstName', label: 'Nombre', type: 'text' },
|
|
1325
|
+
{ name: 'user.email', label: 'Email', type: 'email' },
|
|
1326
|
+
{ name: 'phone', label: 'Telefono', type: 'tel' },
|
|
1327
|
+
{ name: 'address.country', label: 'País', type: 'select' },
|
|
1328
|
+
]
|
|
1329
|
+
}}
|
|
1330
|
+
watchFields={['user.email','phone']}
|
|
1331
|
+
onChange={(data, changedField, formMethods) => {
|
|
1332
|
+
// ✅ Funciona con datos anidados
|
|
1333
|
+
if (changedField.name === 'address.country') {
|
|
1334
|
+
formMethods.setValue('address.city', '');
|
|
1335
|
+
}
|
|
1336
|
+
}}
|
|
1337
|
+
defaultValues={{
|
|
1338
|
+
user: { firstName: '', email: '' },
|
|
1339
|
+
address: { country: '', city: '' }
|
|
1340
|
+
}}
|
|
1341
|
+
onSubmit={(data) => console.log(data)}
|
|
1342
|
+
/>
|
|
1343
|
+
|
|
1344
|
+
|
|
1345
|
+
|
|
1346
|
+
// Ejemplo 2:
|
|
1347
|
+
const nestedFormConfig = {
|
|
1348
|
+
fields: [
|
|
1349
|
+
{ name: 'user.firstName', label: 'Nombre', type: 'text' },
|
|
1350
|
+
{ name: 'user.lastName', label: 'Apellido', type: 'text' },
|
|
1351
|
+
{ name: 'user.email', label: 'Email', type: 'email' },
|
|
1352
|
+
{ name: 'address.country', label: 'País', type: 'select' },
|
|
1353
|
+
{ name: 'address.city', label: 'Ciudad', type: 'select' },
|
|
1354
|
+
{ name: 'address.street', label: 'Calle', type: 'text' },
|
|
1355
|
+
{ name: 'preferences.notifications', label: 'Notificaciones', type: 'switch' },
|
|
1356
|
+
]
|
|
1357
|
+
};
|
|
1358
|
+
|
|
1359
|
+
<GatherFormBuilder
|
|
1360
|
+
config={nestedFormConfig}
|
|
1361
|
+
watchFields={['address.country','preferences.notifications']}
|
|
1362
|
+
onChange={(data, changedField, formMethods) => {
|
|
1363
|
+
console.log('Campo que cambió:', changedField.name); // ej: 'user.firstName'
|
|
1364
|
+
console.log('Nuevo valor:', changedField.value);
|
|
1365
|
+
console.log('Datos completos:', data); // { user: { firstName: '...', lastName: '...' }, address: { ... } }
|
|
1366
|
+
|
|
1367
|
+
// Validación condicional con campos anidados
|
|
1368
|
+
if (changedField.name === 'address.country') {
|
|
1369
|
+
// Limpiar ciudad cuando cambia país
|
|
1370
|
+
formMethods.setValue('address.city', '');
|
|
1371
|
+
formMethods.clearErrors('address.city');
|
|
1372
|
+
}
|
|
1373
|
+
|
|
1374
|
+
// Lógica basada en preferencias anidadas
|
|
1375
|
+
if (changedField.name === 'preferences.notifications' && !changedField.value) {
|
|
1376
|
+
// Si deshabilita notificaciones, limpiar campos relacionados
|
|
1377
|
+
formMethods.setValue('preferences.emailFrequency', 'never');
|
|
1378
|
+
}
|
|
1379
|
+
}}
|
|
1380
|
+
defaultValues={{
|
|
1381
|
+
user: {
|
|
1382
|
+
firstName: '',
|
|
1383
|
+
lastName: '',
|
|
1384
|
+
email: ''
|
|
1385
|
+
},
|
|
1386
|
+
address: {
|
|
1387
|
+
country: '',
|
|
1388
|
+
city: '',
|
|
1389
|
+
street: ''
|
|
1390
|
+
},
|
|
1391
|
+
preferences: {
|
|
1392
|
+
notifications: true
|
|
1393
|
+
}
|
|
1394
|
+
}}
|
|
1395
|
+
onSubmit={(data) => console.log('Submit:', data)}
|
|
1396
|
+
/>
|
|
1397
|
+
|
|
1398
|
+
// Ejemplo 3:
|
|
1399
|
+
<GatherFormBuilder
|
|
1400
|
+
config={nestedFormConfig}
|
|
1401
|
+
onChange={(data, changedField, formMethods) => {
|
|
1402
|
+
if (changedField.name === 'user.email') {
|
|
1403
|
+
// Validar email en tiempo real
|
|
1404
|
+
validateEmail(changedField.value).then(isValid => {
|
|
1405
|
+
if (!isValid) {
|
|
1406
|
+
formMethods.setError('user.email', { message: 'Email inválido' });
|
|
1407
|
+
}
|
|
1408
|
+
});
|
|
1409
|
+
}
|
|
1410
|
+
}}
|
|
1411
|
+
watchFields={['user.email', 'address.country']} // Solo observa estos campos anidados
|
|
1412
|
+
debounceMs={300}
|
|
1413
|
+
onSubmit={(data) => submitForm(data)}
|
|
1414
|
+
/>
|
|
1415
|
+
|
|
1416
|
+
// Ejemplo 3:
|
|
1417
|
+
const calculatorFormConfig = {
|
|
1418
|
+
fields: [
|
|
1419
|
+
{ name: 'invoice.items[0].quantity', label: 'Cantidad Item 1', type: 'number' },
|
|
1420
|
+
{ name: 'invoice.items[0].price', label: 'Precio Item 1', type: 'number' },
|
|
1421
|
+
{ name: 'invoice.items[1].quantity', label: 'Cantidad Item 2', type: 'number' },
|
|
1422
|
+
{ name: 'invoice.items[1].price', label: 'Precio Item 2', type: 'number' },
|
|
1423
|
+
{ name: 'invoice.discount', label: 'Descuento %', type: 'number' },
|
|
1424
|
+
{ name: 'invoice.total', label: 'Total', type: 'number', disabled: true },
|
|
1425
|
+
]
|
|
1426
|
+
};
|
|
1427
|
+
|
|
1428
|
+
<GatherFormBuilder
|
|
1429
|
+
config={calculatorFormConfig}
|
|
1430
|
+
onChange={(data, changedField, formMethods) => {
|
|
1431
|
+
// Recalcular total cuando cambien items o descuento
|
|
1432
|
+
if (changedField.name.startsWith('invoice.items') || changedField.name === 'invoice.discount') {
|
|
1433
|
+
const items = data.invoice?.items || [];
|
|
1434
|
+
const subtotal = items.reduce((sum: number, item: any) => {
|
|
1435
|
+
return sum + ((item?.quantity || 0) * (item?.price || 0));
|
|
1436
|
+
}, 0);
|
|
1437
|
+
|
|
1438
|
+
const discount = (data.invoice?.discount || 0) / 100;
|
|
1439
|
+
const total = subtotal * (1 - discount);
|
|
1440
|
+
|
|
1441
|
+
formMethods.setValue('invoice.total', total.toFixed(2));
|
|
1442
|
+
}
|
|
1443
|
+
}}
|
|
1444
|
+
defaultValues={{
|
|
1445
|
+
invoice: {
|
|
1446
|
+
items: [
|
|
1447
|
+
{ quantity: 0, price: 0 },
|
|
1448
|
+
{ quantity: 0, price: 0 }
|
|
1449
|
+
],
|
|
1450
|
+
discount: 0,
|
|
1451
|
+
total: 0
|
|
1452
|
+
}
|
|
1453
|
+
}}
|
|
1454
|
+
onSubmit={(data) => console.log('Invoice:', data)}
|
|
1455
|
+
/>
|
|
1456
|
+
|
|
1318
1457
|
// EJEMPLO CON TODAS LAS PROPS
|
|
1319
1458
|
<GatherFormBuilder
|
|
1320
1459
|
// CONFIG: Configuración del formulario (requerida)
|
|
@@ -1361,6 +1500,17 @@ interface GatherFormBuilderProps {
|
|
|
1361
1500
|
// VALIDATIONMODE: Cuándo validar (opcional)
|
|
1362
1501
|
validationMode="onChange" // Valida en cada cambio
|
|
1363
1502
|
|
|
1503
|
+
// DEBOUCEMS: tiempo de respuesta para cualquier cambio en el form
|
|
1504
|
+
debouceMs={100}
|
|
1505
|
+
|
|
1506
|
+
// WATCHFIELDS: campos del form que se vizualizaran en tiempo real
|
|
1507
|
+
watchFields={['nombre', 'pais']}
|
|
1508
|
+
|
|
1509
|
+
// ONCHANGE: cambios en tiempo real del form
|
|
1510
|
+
onChange={(data,changedField, formMethods )=> {
|
|
1511
|
+
console.log({data,changedField,formMethods})
|
|
1512
|
+
}}
|
|
1513
|
+
|
|
1364
1514
|
// LOADINGCOMPONENT: Componente de carga (opcional)
|
|
1365
1515
|
loadingComponent={<CustomSpinner />}
|
|
1366
1516
|
/>
|
|
@@ -203,6 +203,21 @@ export declare const createColumns: <T>(columns: GatherTableColumn<T>[]) => Gath
|
|
|
203
203
|
*/
|
|
204
204
|
export declare const createFlexibleColumns: (columns: BaseGatherTableColumn[]) => BaseGatherTableColumn[];
|
|
205
205
|
|
|
206
|
+
/**
|
|
207
|
+
* Función debounce para limitar la frecuencia de ejecución
|
|
208
|
+
*/
|
|
209
|
+
export declare const debounce: <T extends (...args: any[]) => void>(func: T, wait: number) => ((...args: Parameters<T>) => void);
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Clona un objeto de forma profunda
|
|
213
|
+
*/
|
|
214
|
+
export declare const deepClone: (obj: any) => any;
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Compara dos valores de forma profunda, incluyendo objetos y arrays anidados
|
|
218
|
+
*/
|
|
219
|
+
export declare const deepEqual: (obj1: any, obj2: any) => boolean;
|
|
220
|
+
|
|
206
221
|
/**
|
|
207
222
|
* Tipo unión de todas las configuraciones de campo posibles
|
|
208
223
|
*/
|
|
@@ -525,18 +540,28 @@ export declare interface GatherDateFieldConfig extends BaseFieldConfig {
|
|
|
525
540
|
}
|
|
526
541
|
|
|
527
542
|
/**
|
|
528
|
-
* Componente que construye un formulario dinámico
|
|
543
|
+
* Componente que construye un formulario dinámico a partir de una configuración declarativa.
|
|
544
|
+
*
|
|
545
|
+
* Se apoya en **React Hook Form** para la gestión del estado, validaciones
|
|
546
|
+
* y envío del formulario. Permite definir campos, layout, validaciones,
|
|
547
|
+
* botones y callbacks personalizados para diferentes acciones.
|
|
529
548
|
*
|
|
530
549
|
* @component
|
|
531
|
-
* @param {GatherFormBuilderProps} props - Propiedades
|
|
532
|
-
*
|
|
533
|
-
* @property {Object} config - Configuración del formulario (campos,
|
|
534
|
-
* @property {Function} onSubmit - Función asíncrona
|
|
535
|
-
* @property {Function} [onAction] -
|
|
536
|
-
* @property {
|
|
537
|
-
*
|
|
538
|
-
*
|
|
539
|
-
* @property {string} [
|
|
550
|
+
* @param {GatherFormBuilderProps} props - Propiedades del componente.
|
|
551
|
+
*
|
|
552
|
+
* @property {Object} config - Configuración principal del formulario (campos, layout, título, botones, etc).
|
|
553
|
+
* @property {Function} onSubmit - Función asíncrona ejecutada al enviar el formulario.
|
|
554
|
+
* @property {Function} [onAction] - Callback para el botón de acción secundaria (ej: limpiar).
|
|
555
|
+
* @property {Function} [onChange] - Callback ejecutado cuando cambia el valor de un campo observado.
|
|
556
|
+
* Recibe `(data, changedField, formMethods)`, donde `changedField` incluye `{ name, value, previousValue }`
|
|
557
|
+
* y `formMethods` expone utilidades de React Hook Form (`setValue`, `getValues`, `reset`, `clearErrors`, `setError`, `watch`).
|
|
558
|
+
* @property {string[]} [watchFields=[]] - Lista de nombres de campos que deben ser observados por `onChange`.
|
|
559
|
+
* @property {number} [debounceMs=0] - Tiempo en milisegundos para aplicar `debounce` al callback `onChange`.
|
|
560
|
+
* @property {boolean} [resetData=true] - Si es `true`, el formulario se resetea tras un submit exitoso.
|
|
561
|
+
* @property {Object} [defaultValues={}] - Valores iniciales de los campos.
|
|
562
|
+
* @property {boolean} [isLoading=false] - Indica si el formulario está en estado de carga (bloquea inputs y botones).
|
|
563
|
+
* @property {boolean} [disabled=false] - Deshabilita todos los campos independientemente del estado de carga.
|
|
564
|
+
* @property {string} [className=""] - Clases CSS adicionales para el contenedor principal.
|
|
540
565
|
* @property {'onBlur' | 'onChange' | 'onSubmit' | 'onTouched' | 'all'} [validationMode='onChange'] - Modo de validación usado por React Hook Form.
|
|
541
566
|
*
|
|
542
567
|
* @example
|
|
@@ -561,6 +586,9 @@ export declare interface GatherDateFieldConfig extends BaseFieldConfig {
|
|
|
561
586
|
* }
|
|
562
587
|
* }}
|
|
563
588
|
* onSubmit={(data) => console.log("Datos enviados:", data)}
|
|
589
|
+
* onChange={(data, changedField, formMethods ) => console.log("Cambio:", changedField)}
|
|
590
|
+
* watchFields={["nombre", "email"]}
|
|
591
|
+
* debounceMs={500}
|
|
564
592
|
* />
|
|
565
593
|
* ```
|
|
566
594
|
*/
|
|
@@ -600,6 +628,55 @@ export declare interface GatherFormBuilderProps {
|
|
|
600
628
|
* @example onAction={() => navigate('/home')}
|
|
601
629
|
*/
|
|
602
630
|
onAction?: () => void;
|
|
631
|
+
/**
|
|
632
|
+
* Función que se ejecuta cada vez que cambia algún campo del formulario.
|
|
633
|
+
* Útil para validaciones en tiempo real, cálculos dinámicos, o sincronización con estado externo.
|
|
634
|
+
*
|
|
635
|
+
* @param data - Valores actuales de todos los campos del formulario
|
|
636
|
+
* @param changedField - Información sobre el campo que cambió
|
|
637
|
+
* @param formMethods - Métodos de React Hook Form para manipular el formulario
|
|
638
|
+
*
|
|
639
|
+
* @example
|
|
640
|
+
* onChange={(data, changedField, formMethods) => {
|
|
641
|
+
* if (changedField.name === 'country') {
|
|
642
|
+
* // Limpiar campo ciudad cuando cambia país
|
|
643
|
+
* formMethods.setValue('city', '');
|
|
644
|
+
* }
|
|
645
|
+
*
|
|
646
|
+
* // Auto-guardar borrador
|
|
647
|
+
* saveDraft(data);
|
|
648
|
+
* }}
|
|
649
|
+
*/
|
|
650
|
+
onChange?: (data: Record<string, any>, changedField: {
|
|
651
|
+
name: string;
|
|
652
|
+
value: any;
|
|
653
|
+
previousValue?: any;
|
|
654
|
+
}, formMethods: {
|
|
655
|
+
setValue: (name: string, value: any) => void;
|
|
656
|
+
getValues: (name?: string) => any;
|
|
657
|
+
reset: (values?: any) => void;
|
|
658
|
+
clearErrors: (name?: string) => void;
|
|
659
|
+
setError: (name: string, error: {
|
|
660
|
+
message: string;
|
|
661
|
+
}) => void;
|
|
662
|
+
watch: (name?: string) => any;
|
|
663
|
+
}) => void;
|
|
664
|
+
/**
|
|
665
|
+
* Lista de campos específicos a observar para el onChange.
|
|
666
|
+
* Si no se especifica, observa todos los campos.
|
|
667
|
+
* Útil para optimizar performance en formularios grandes.
|
|
668
|
+
*
|
|
669
|
+
* @example watchFields: ['country', 'state'] // Solo observa estos campos
|
|
670
|
+
*/
|
|
671
|
+
watchFields?: string[];
|
|
672
|
+
/**
|
|
673
|
+
* Debounce en milisegundos para el onChange.
|
|
674
|
+
* Útil para evitar muchas llamadas en campos de texto.
|
|
675
|
+
*
|
|
676
|
+
* @default 0 (sin debounce)
|
|
677
|
+
* @example debounceMs: 300 // Espera 300ms después del último cambio
|
|
678
|
+
*/
|
|
679
|
+
debounceMs?: number;
|
|
603
680
|
/**
|
|
604
681
|
* Valores iniciales para los campos del formulario.
|
|
605
682
|
* Se asignan según la propiedad `name` de cada campo.
|
|
@@ -697,8 +774,10 @@ export declare interface GatherInputFieldConfig extends BaseFieldConfig {
|
|
|
697
774
|
maxLength?: number;
|
|
698
775
|
/** Expresión regular para validar el formato del valor */
|
|
699
776
|
pattern?: string;
|
|
777
|
+
/** Funcion para validar el formato del valor */
|
|
778
|
+
validateFn?: (value: string) => boolean | string;
|
|
700
779
|
/** Mensaje que se muestra cuando el patrón no es válido */
|
|
701
|
-
|
|
780
|
+
errorMessage?: string;
|
|
702
781
|
/** Valor numérico mínimo permitido (para inputs number) */
|
|
703
782
|
min?: number;
|
|
704
783
|
/** Valor numérico máximo permitido (para inputs number) */
|
|
@@ -1781,6 +1860,23 @@ export declare interface GatherTextareaFieldConfig extends BaseFieldConfig {
|
|
|
1781
1860
|
*/
|
|
1782
1861
|
export declare const generateValidationRules: (field: FieldConfig) => ValidationRule;
|
|
1783
1862
|
|
|
1863
|
+
export declare const getAllPaths: (obj: any, prefix?: string) => string[];
|
|
1864
|
+
|
|
1865
|
+
/**
|
|
1866
|
+
* Determina las clases de layout dinámicamente en base al tipo (`grid`, `horizontal`, `stack`, etc).
|
|
1867
|
+
*/
|
|
1868
|
+
export declare const getLayoutClasses: (config: FormConfig) => string;
|
|
1869
|
+
|
|
1870
|
+
/**
|
|
1871
|
+
* Busca campos anidados en estructuras complejas de objetos (ej: direcciones.calle).
|
|
1872
|
+
*/
|
|
1873
|
+
export declare const getNestedField: (obj: any, path: string) => any;
|
|
1874
|
+
|
|
1875
|
+
/**
|
|
1876
|
+
* Ordena los campos en base al array `orderFields` definido en la config.
|
|
1877
|
+
*/
|
|
1878
|
+
export declare const getOrderedFields: (fields: FieldConfig[], orderFields?: string[]) => FieldConfig[];
|
|
1879
|
+
|
|
1784
1880
|
/**
|
|
1785
1881
|
* Tipo de opción para el componente MultiSelect
|
|
1786
1882
|
* @interface OptionType
|
|
@@ -1819,7 +1915,7 @@ export declare interface SelectInputOption {
|
|
|
1819
1915
|
value: string;
|
|
1820
1916
|
/** Patrón de expresión regular para validar el input asociado */
|
|
1821
1917
|
validationPattern?: RegExp;
|
|
1822
|
-
validateFn?: (value: string) => boolean;
|
|
1918
|
+
validateFn?: (value: string) => boolean | string;
|
|
1823
1919
|
/** Mensaje de error personalizado cuando la validación falla */
|
|
1824
1920
|
errorMessage?: string;
|
|
1825
1921
|
/** Texto placeholder específico para esta opción */
|