@juantroconisf/lib 7.0.0 → 9.0.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 +227 -46
- package/dist/index.d.mts +84 -80
- package/dist/index.d.ts +84 -80
- package/dist/index.js +455 -305
- package/dist/index.mjs +443 -300
- package/package.json +11 -3
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
-
}) : x)(function(x) {
|
|
4
|
-
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
-
});
|
|
7
|
-
|
|
8
1
|
// src/utils/types.ts
|
|
9
2
|
var NextUIError = class {
|
|
10
3
|
isInvalid;
|
|
@@ -26,11 +19,15 @@ function handleNestedChange({
|
|
|
26
19
|
hasNestedValues = false
|
|
27
20
|
}) {
|
|
28
21
|
if (!hasNestedValues) return { ...state, [id]: value };
|
|
29
|
-
const propertyDepth = String(id).split("."), newValues = state;
|
|
22
|
+
const propertyDepth = String(id).split("."), newValues = { ...state };
|
|
30
23
|
let current = newValues;
|
|
31
24
|
for (let i = 0; i < propertyDepth.length - 1; i++) {
|
|
32
25
|
const key = propertyDepth[i];
|
|
33
|
-
current[key]
|
|
26
|
+
if (Array.isArray(current[key])) {
|
|
27
|
+
current[key] = [...current[key]];
|
|
28
|
+
} else {
|
|
29
|
+
current[key] = { ...current[key] };
|
|
30
|
+
}
|
|
34
31
|
current = current[key];
|
|
35
32
|
}
|
|
36
33
|
current[propertyDepth[propertyDepth.length - 1]] = value;
|
|
@@ -51,7 +48,11 @@ function handleArrayItemChange({
|
|
|
51
48
|
} else {
|
|
52
49
|
let current = item;
|
|
53
50
|
for (let i = 0; i < fieldDepth.length - 1; i++) {
|
|
54
|
-
current[fieldDepth[i]]
|
|
51
|
+
if (Array.isArray(current[fieldDepth[i]])) {
|
|
52
|
+
current[fieldDepth[i]] = [...current[fieldDepth[i]]];
|
|
53
|
+
} else {
|
|
54
|
+
current[fieldDepth[i]] = { ...current[fieldDepth[i]] };
|
|
55
|
+
}
|
|
55
56
|
current = current[fieldDepth[i]];
|
|
56
57
|
}
|
|
57
58
|
current[fieldDepth[fieldDepth.length - 1]] = value;
|
|
@@ -62,141 +63,134 @@ function handleArrayItemChange({
|
|
|
62
63
|
function getNestedValue(obj, path) {
|
|
63
64
|
return path.split(".").reduce((acc, key) => acc?.[key], obj);
|
|
64
65
|
}
|
|
65
|
-
function removeCompositeKeysByPrefix(
|
|
66
|
-
const result = new Map(
|
|
67
|
-
for (const key of
|
|
66
|
+
function removeCompositeKeysByPrefix(map, prefix) {
|
|
67
|
+
const result = new Map(map);
|
|
68
|
+
for (const key of map.keys()) {
|
|
68
69
|
if (key.startsWith(prefix)) {
|
|
69
70
|
result.delete(key);
|
|
70
71
|
}
|
|
71
72
|
}
|
|
72
73
|
return result;
|
|
73
74
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
msg: "INVALID_EMAIL"
|
|
131
|
-
},
|
|
132
|
-
password: {
|
|
133
|
-
validate: (val) => new RegExp(regex.password).test(val),
|
|
134
|
-
msg: "INVALID_PASSWORD"
|
|
75
|
+
|
|
76
|
+
// src/hooks/useForm.tsx
|
|
77
|
+
import { Form } from "@heroui/react";
|
|
78
|
+
|
|
79
|
+
// src/hooks/useComponentLang.tsx
|
|
80
|
+
import { setLocale } from "yup";
|
|
81
|
+
import { useEffect } from "react";
|
|
82
|
+
|
|
83
|
+
// src/assets/translations.ts
|
|
84
|
+
var translations = {
|
|
85
|
+
en: {
|
|
86
|
+
mixed: {
|
|
87
|
+
default: "Invalid value",
|
|
88
|
+
required: "This field is required",
|
|
89
|
+
oneOf: "Must be one of: ${values}",
|
|
90
|
+
notOneOf: "Cannot be any of: ${values}",
|
|
91
|
+
notType: "Incorrect data format",
|
|
92
|
+
defined: "Must be defined"
|
|
93
|
+
},
|
|
94
|
+
string: {
|
|
95
|
+
length: "Must be exactly ${length} characters",
|
|
96
|
+
min: "Must be at least ${min} characters",
|
|
97
|
+
max: "Must be at most ${max} characters",
|
|
98
|
+
matches: 'Must match: "${regex}"',
|
|
99
|
+
email: "Enter a valid email address",
|
|
100
|
+
url: "Enter a valid URL",
|
|
101
|
+
uuid: "Enter a valid UUID",
|
|
102
|
+
trim: "Remove leading/trailing spaces",
|
|
103
|
+
lowercase: "Must be in lowercase",
|
|
104
|
+
uppercase: "Must be in uppercase",
|
|
105
|
+
password: "Your password doesn't meet the security criteria."
|
|
106
|
+
},
|
|
107
|
+
number: {
|
|
108
|
+
min: "Value must be ${min} or greater",
|
|
109
|
+
max: "Value must be ${max} or less",
|
|
110
|
+
lessThan: "Must be less than ${less}",
|
|
111
|
+
moreThan: "Must be greater than ${more}",
|
|
112
|
+
positive: "Must be a positive number",
|
|
113
|
+
negative: "Must be a negative number",
|
|
114
|
+
integer: "Must be a whole number"
|
|
115
|
+
},
|
|
116
|
+
date: {
|
|
117
|
+
min: "Date must be after ${min}",
|
|
118
|
+
max: "Date must be before ${max}"
|
|
119
|
+
},
|
|
120
|
+
boolean: {
|
|
121
|
+
isValue: "Must be ${value}"
|
|
122
|
+
},
|
|
123
|
+
object: {
|
|
124
|
+
noUnknown: "Contains unknown properties"
|
|
125
|
+
},
|
|
126
|
+
array: {
|
|
127
|
+
min: "Must have at least ${min} items",
|
|
128
|
+
max: "Must have ${max} items or fewer",
|
|
129
|
+
length: "Must have exactly ${length} items"
|
|
130
|
+
}
|
|
135
131
|
},
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
132
|
+
es: {
|
|
133
|
+
mixed: {
|
|
134
|
+
default: "Valor no v\xE1lido",
|
|
135
|
+
required: "Este campo es obligatorio",
|
|
136
|
+
oneOf: "Debe ser uno de: ${values}",
|
|
137
|
+
notOneOf: "No puede ser ninguno de: ${values}",
|
|
138
|
+
defined: "Debe estar definido",
|
|
139
|
+
notType: "Formato de dato incorrecto"
|
|
140
|
+
},
|
|
141
|
+
string: {
|
|
142
|
+
length: "Debe tener exactamente ${length} caracteres",
|
|
143
|
+
min: "Debe tener al menos ${min} caracteres",
|
|
144
|
+
max: "Debe tener como m\xE1ximo ${max} caracteres",
|
|
145
|
+
matches: 'Debe coincidir con: "${regex}"',
|
|
146
|
+
email: "Ingresa un correo electr\xF3nico v\xE1lido",
|
|
147
|
+
url: "Ingresa una URL v\xE1lida",
|
|
148
|
+
uuid: "Ingresa un UUID v\xE1lido",
|
|
149
|
+
trim: "No debe contener espacios al inicio o final",
|
|
150
|
+
lowercase: "Debe estar en min\xFAsculas",
|
|
151
|
+
uppercase: "Debe estar en may\xFAsculas",
|
|
152
|
+
password: "Tu contrase\xF1a no cumple con los requisitos de seguridad."
|
|
153
|
+
},
|
|
154
|
+
number: {
|
|
155
|
+
min: "Debe ser mayor o igual a ${min}",
|
|
156
|
+
max: "Debe ser menor o igual a ${max}",
|
|
157
|
+
lessThan: "Debe ser menor a ${less}",
|
|
158
|
+
moreThan: "Debe ser mayor a ${more}",
|
|
159
|
+
positive: "Debe ser un n\xFAmero positivo",
|
|
160
|
+
negative: "Debe ser un n\xFAmero negativo",
|
|
161
|
+
integer: "Debe ser un n\xFAmero entero"
|
|
162
|
+
},
|
|
163
|
+
date: {
|
|
164
|
+
min: "La fecha debe ser posterior a ${min}",
|
|
165
|
+
max: "La fecha debe ser anterior a ${max}"
|
|
166
|
+
},
|
|
167
|
+
boolean: {
|
|
168
|
+
isValue: "Debe ser ${value}"
|
|
169
|
+
},
|
|
170
|
+
object: {
|
|
171
|
+
noUnknown: "Contiene propiedades no permitidas"
|
|
172
|
+
},
|
|
173
|
+
array: {
|
|
174
|
+
min: "Debe tener al menos ${min} elementos",
|
|
175
|
+
max: "Debe tener como m\xE1ximo ${max} elementos",
|
|
176
|
+
length: "Debe tener ${length} elementos"
|
|
177
|
+
}
|
|
139
178
|
}
|
|
140
179
|
};
|
|
141
180
|
|
|
142
|
-
// lang/en.json
|
|
143
|
-
var en_default = { BIRTH_DATE: "Birth date", DAY: "Day", DAY_PLACEHOLDER: "Choose a day", MONTH: "Month", MONTH_PLACEHOLDER: "Choose a month", YEAR: "Year", YEAR_PLACEHOLDER: "Choose a year", PRICING: "Pricing", PRICING_TABLE: "Pricing table", OUR_PRICING_PLAN: "Our pricing plan", PRICING_DESCRIPTION: "Level up your experience. Discover the plan that unlocks the features you need.", VALUE_STORAGE: "{{value}} storage", GOOGLE_CALENDAR_SYNC: "Google Calendar Sync", INTERNAL_REMINDERS: "Internal reminders", WHATSAPP_AUTOMATED_REMINDERS: "WhatsApp Automated Reminders", PROFESSIONAL: "Professional", PROFESSIONAL_PLAN_DESCRIPTION: "For single doctors looking to level up their practice", DIGITAL_PRESCRIPTIONS: "Digital prescriptions", DICOM_VIEWER: "DICOM Viewer", VERIFIED_MEDICAL_CREDENTIALS: "Verified medical credentials", PATIENT_SELF_MANAGEMENT: "Patient self management", BUY_NOW: "Buy now", ORGANIZATION: "Organization", ORGANIZATION_PLAN_DESCRIPTION: "For organizations with multiple users looking to share information", UP_TO_VALUE_STORAGE: "Up to {{value}} storage", CONFIGURABLE_USER_PERMISSIONS: "Configurable user permissions", CALCULATE_PRICING: "Calculate pricing", DOCTORS: "Doctors", ASSISTANTS: "Assistants", BASIC: "Basic", BASIC_PLAN_DESCRIPTION: "For starters in the medical industry", USER: "User", TYPE_A_VALUE: "Type a value", STORAGE: "Storage", PASSWORD: "Password", PASSWORD_PLACEHOLDER: "Enter your password", REQUIRED: "Required", TOO_SHORT: "Too short", TOO_LONG: "Too long", VALUE_LOW: "Value is too low", VALUE_HIGH: "Value is too high", PATTERN_INVALID: "Pattern is not valid", INVALID_EMAIL: "Invalid email", SHOW_PASSWORD: "Show password", HIDE_PASSWORD: "Hide password", GROUP_PRICING_CALCULATOR: "Group Pricing Calculator", VERIFIED_ACCOUNT: "Verified account", VERIFIED_ACCOUNT_TEXT: "This account has been verified by Clinikos, as well as its affiliations with the following institutions", PHONE_NUMBER: "Phone number", PHONE_NUMBER_PLACEHOLDER: "Enter your phone number", SEND_MESSAGE: "Send message", BOOK_MEETING: "Book meeting", SIGN_UP: "Sign up", INVALID_PASSWORD: "Your password doesn't meet the security criteria.", NOT_EQUAL: "Values are not equal", GENDER: "Gender", FEMALE: "Female", MALE: "Male", CLOSE: "Close", MANDATORY_FIELDS_WARNING: "", INVALID_FIELDS_WARNING: "", COUNTRY: "Country", COUNTRY_PLACEHOLDER: "Select a country", STATE: "State", STATE_PLACEHOLDER: "Select a state", CITY: "City", CITY_PLACEHOLDER: "Select a city", TIMEZONE: "Timezone", TIMEZONE_PLACEHOLDER: "Selecte a timezone", NAME: "Name", OK: "Ok", PAGE_NOT_FOUND: "Page not found", PAGE_NOT_FOUND_DESCRIPTION: "The link you clicked may be broken or the page may have been removed or renamed", TODAY: "Today", WEEK: "Week", CALENDAR: "Calendar", EVENT: "Event", NO_INFORMATION: "No information", SYNC_GOOGLE_CALENDAR: "Sync Google Calendar", NO_RESULTS: "No results were found", GOOGLE_MEET: "Google Meet", LONG_TIME_AGO: "Long time ago", TOMORROW: "Tomorrow", CHOOSE_PLAN: "Choose a plan", CHOOSE_PLAN_DESCRIPTION: "Choose a plan that fits your needs!", PRIVACY_POLICY: "", OPTIONAL: "Optional", RESULTS: "Results", LOCATION: "Location", ADDRESS: "Address", ADDRESS_PLACEHOLDER: "Enter your address", COPY_TO_CLIPBOARD: "Copy to clipboard", ACTIONS: "Actions", MIN: "Minimum", MAX: "Maximum", DUE_DATE: "Due date", QUICK_SEARCH: "Quick search", MONTHLY: "Monthly", WEEKLY: "Weekly", GOOGLE_MAPS_LINK: "Google maps link", MINUTE: "Minute", MINUTES: "Minutes", HOUR: "Hour", HOURS: "Hours", VE_ID: "Identity card", ACCOUNT_VERIFIED_BY_CLINIKOS: "This account has been verified by Clinikos, as well as its affiliations with the following institutions", INBOX: "Inbox", ACCEPTED: "Accepted", DECLINED: "Declined", NEEDS_ACTION: "Needs action", OVERDUE: "Overdue", FILTER_BY: "Filter by", REFRESH: "Refresh", LOADING: "Loading", MINUTE_LEFT: "One minute left", VALUE_MINUTES_LEFT: "{{value}} minutes left", PLAY: "Play", PAUSE: "Pause", STOP: "Stop", LOAD_MORE: "Load more", BILLING: "Billing", DOCTOR: "Doctor", ASSISTANT: "Assistant", NUMBER_OF_DOCTORS: "Number of Doctors", NUMBER_OF_ASSISTANTS: "Number of Assistants", EACH_DOCTOR: "Each doctor", EACH_ASSISTANT: "Each assistant", ROLE: "Role", PAYMENT_METHODS: "Payment methods", UPGRADE: "Upgrade", TOTAL: "Total", BUY: "Buy", TYPE: "Type", RECURRENT: "Recurrent", ACCEPT: "Accept", DECLINE: "Decline", PREFERENCES: "Preferences", BOOKING: "Booking", PATTERN_NOT_VALID: "Pattern is not valid" };
|
|
144
|
-
|
|
145
|
-
// lang/es.json
|
|
146
|
-
var es_default = { BIRTH_DATE: "Fecha de nacimiento", DAY: "D\xEDa", DAY_PLACEHOLDER: "Elige un d\xEDa", MONTH: "Mes", MONTH_PLACEHOLDER: "Elige un mes", YEAR: "A\xF1o", YEAR_PLACEHOLDER: "Elige un a\xF1o", PRICING: "Precio", PRICING_TABLE: "Tabla de precios", OUR_PRICING_PLAN: "Nuestros precios", PRICING_DESCRIPTION: "Mejora tu experiencia. Descubre el plan que desbloquea las funciones que necesitas.", VALUE_STORAGE: "{{value}} almacenamiento", GOOGLE_CALENDAR_SYNC: "Google Calenar Sync", INTERNAL_REMINDERS: "Recordatorios internos", WHATSAPP_AUTOMATED_REMINDERS: "Recordatorios automatizados de WhatsApp", PROFESSIONAL: "Profesional", PROFESSIONAL_PLAN_DESCRIPTION: "Para doctores individuales que buscan elevar sus pr\xE1cticas", DIGITAL_PRESCRIPTIONS: "Recipes digitales", DICOM_VIEWER: "Visualizador DICOM", VERIFIED_MEDICAL_CREDENTIALS: "Credenciales m\xE9dicas verificadas", PATIENT_SELF_MANAGEMENT: "Auto gesti\xF3n para pacientes", BUY_NOW: "Comprar ahora", ORGANIZATION: "Organizaci\xF3n", ORGANIZATION_PLAN_DESCRIPTION: "Para organizaciones con m\xFAltiples usuarios que buscan compartir informaci\xF3n", UP_TO_VALUE_STORAGE: "Hasta {{value}} de almacenamiento", CONFIGURABLE_USER_PERMISSIONS: "Permisolog\xEDa configurable para usuarios", CALCULATE_PRICING: "Calcular precio", DOCTORS: "Doctores", ASSISTANTS: "Asistentes", BASIC: "B\xE1sico", BASIC_PLAN_DESCRIPTION: "Para iniciar en la industria m\xE9dica", USER: "Usuario", TYPE_A_VALUE: "Ingresa un valor", STORAGE: "Almacenamiento", PASSWORD: "Contrase\xF1a", PASSWORD_PLACEHOLDER: "Ingresa tu contrase\xF1a", REQUIRED: "Requerido", TOO_SHORT: "Demasiado corto", TOO_LONG: "Demasiado largo", VALUE_LOW: "El valor es muy bajo", VALUE_HIGH: "El valor es muy alto", PATTERN_INVALID: "El patr\xF3n no es v\xE1lido", INVALID_EMAIL: "Correo inv\xE1lido", SHOW_PASSWORD: "Mostrar contrase\xF1a", HIDE_PASSWORD: "Esconder contrase\xF1a", GROUP_PRICING_CALCULATOR: "Calculadora de precios grupal", VERIFIED_ACCOUNT: "Cuenta verificada", VERIFIED_ACCOUNT_TEXT: "Esta cuenta ha sido verificada por Clinikos, as\xED como sus afiliaciones con las siguientes instituciones", PHONE_NUMBER: "N\xFAmero de tel\xE9fono", PHONE_NUMBER_PLACEHOLDER: "Ingrese su n\xFAmero de tel\xE9fono", SEND_MESSAGE: "Enviar mensaje", BOOK_MEETING: "Agendar cita", SIGN_UP: "Reg\xEDstrate", INVALID_PASSWORD: "Tu contrase\xF1a no cumple con los requisitos de seguridad.", NOT_EQUAL: "Los valores no son iguales", GENDER: "G\xE9nero", FEMALE: "Femenino", MALE: "Masculino", CLOSE: "Cerrar", MANDATORY_FIELDS_WARNING: "", INVALID_FIELDS_WARNING: "", COUNTRY: "Pa\xEDs", COUNTRY_PLACEHOLDER: "Selecciona un pa\xEDs", STATE: "Estado", STATE_PLACEHOLDER: "Selecciona un estado", CITY: "Ciudad", CITY_PLACEHOLDER: "Selecciona una ciudad", TIMEZONE: "Zona horaria", TIMEZONE_PLACEHOLDER: "Selecciona una zora horaria", NAME: "Nombre", OK: "Ok", PAGE_NOT_FOUND: "P\xE1gina no encontrada", PAGE_NOT_FOUND_DESCRIPTION: "El enlace en el que hiciste click puede que est\xE9 roto o la p\xE1gina puede haber sido eliminada o renombrada", TODAY: "Hoy", WEEK: "Semana", CALENDAR: "Calendario", EVENT: "Evento", NO_INFORMATION: "Sin informaci\xF3n", SYNC_GOOGLE_CALENDAR: "Vincular Calendario de Google", NO_RESULTS: "No se encontraron resultados", GOOGLE_MEET: "Google Meet", LONG_TIME_AGO: "Hace mucho tiempo", TOMORROW: "Ma\xF1ana", CHOOSE_PLAN: "Elige un plan", CHOOSE_PLAN_DESCRIPTION: "\xA1Elige el plan que se ajuste a tus necesidades!", PRIVACY_POLICY: "", OPTIONAL: "Opcional", RESULTS: "Resultados", LOCATION: "Ubicaci\xF3n", ADDRESS: "Direcci\xF3n", ADDRESS_PLACEHOLDER: "Ingresa tu direcci\xF3n", COPY_TO_CLIPBOARD: "Copiar al portapapeles", ACTIONS: "Acciones", MIN: "M\xEDnimo", MAX: "M\xE1ximo", DUE_DATE: "Fecha l\xEDmite", QUICK_SEARCH: "B\xFAsqueda r\xE1pida", MONTHLY: "Mensual", WEEKLY: "Semanal", GOOGLE_MAPS_LINK: "Link de Google Maps", MINUTE: "Minuto", MINUTES: "Minutos", HOUR: "Hora", HOURS: "Horas", VE_ID: "C\xE9dula de Identidad", ACCOUNT_VERIFIED_BY_CLINIKOS: "Esta cuenta ha sido verificada por Clinikos, as\xED como sus afiliaciones con las siguientes instituciones", INBOX: "Bandeja de entrada", ACCEPTED: "Aceptado", DECLINED: "Declinado", NEEDS_ACTION: "Necesita acci\xF3n", OVERDUE: "Atrasado", FILTER_BY: "Filtrar por", REFRESH: "Refrescar", LOADING: "Cargando", MINUTE_LEFT: "Un minuto restante", VALUE_MINUTES_LEFT: "{{value}} minutos restantes", PLAY: "Reproducir", PAUSE: "Pausar", STOP: "Detener", LOAD_MORE: "Cargar m\xE1s", BILLING: "Facturaci\xF3n", DOCTOR: "Doctor", ASSISTANT: "Asistente", NUMBER_OF_DOCTORS: "N\xFAmero de Doctores", NUMBER_OF_ASSISTANTS: "N\xFAmero de Asistentes", EACH_DOCTOR: "Cada doctor", EACH_ASSISTANT: "Cada asistente", ROLE: "Rol", PAYMENT_METHODS: "M\xE9todos de pago", UPGRADE: "Mejorar", TOTAL: "Total", BUY: "Comprar", TYPE: "Tipo", RECURRENT: "Recurrente", ACCEPT: "Aceptar", DECLINE: "Declinar", PREFERENCES: "Preferencias", BOOKING: "Agendar cita", PATTERN_NOT_VALID: "El patr\xF3n no es v\xE1lido" };
|
|
147
|
-
|
|
148
181
|
// src/hooks/useComponentLang.tsx
|
|
149
182
|
var cookieName = "LOCALE";
|
|
150
|
-
var langMap = {
|
|
151
|
-
en: en_default,
|
|
152
|
-
es: es_default
|
|
153
|
-
};
|
|
154
183
|
var getClientCookie = () => {
|
|
155
184
|
const value = "; " + document.cookie, decodedValue = decodeURIComponent(value), parts = decodedValue.split("; " + cookieName + "=");
|
|
156
185
|
if (parts.length === 2) return parts.pop()?.split(";").shift();
|
|
157
186
|
};
|
|
158
|
-
var getServerCookie = () => {
|
|
159
|
-
try {
|
|
160
|
-
const { cookies } = __require("next/headers");
|
|
161
|
-
return cookies().get(cookieName)?.value;
|
|
162
|
-
} catch {
|
|
163
|
-
return "es";
|
|
164
|
-
}
|
|
165
|
-
};
|
|
166
187
|
function useComponentLanguage() {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
locale
|
|
170
|
-
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// src/hooks/useValidate.tsx
|
|
175
|
-
var validProps = {
|
|
176
|
-
isInvalid: false,
|
|
177
|
-
errorMessage: ""
|
|
178
|
-
};
|
|
179
|
-
function useValidate() {
|
|
180
|
-
const { lang } = useComponentLanguage();
|
|
181
|
-
const performValidations = (value, validationTypes, errorMessages) => {
|
|
182
|
-
if (!validationTypes) return validProps;
|
|
183
|
-
const items = Object.entries(validationTypes), requiredExist = validationTypes?.required !== void 0, isRequired = requiredExist ? validationTypes.required : false;
|
|
184
|
-
if (value === "" && !isRequired) return validProps;
|
|
185
|
-
let errorFound = validProps;
|
|
186
|
-
for (const [key, opts] of items) {
|
|
187
|
-
if (opts === null) continue;
|
|
188
|
-
const { validate, msg } = errors[key], isInvalid = !validate(value, opts);
|
|
189
|
-
if (isInvalid) {
|
|
190
|
-
errorFound = {
|
|
191
|
-
isInvalid,
|
|
192
|
-
errorMessage: errorMessages?.[key] || lang[msg]
|
|
193
|
-
};
|
|
194
|
-
break;
|
|
195
|
-
}
|
|
188
|
+
useEffect(() => {
|
|
189
|
+
const locale = getClientCookie() || "en";
|
|
190
|
+
if (translations[locale]) {
|
|
191
|
+
setLocale(translations[locale]);
|
|
196
192
|
}
|
|
197
|
-
|
|
198
|
-
};
|
|
199
|
-
return { performValidations };
|
|
193
|
+
}, []);
|
|
200
194
|
}
|
|
201
195
|
|
|
202
196
|
// src/hooks/useForm.utils.ts
|
|
@@ -240,7 +234,7 @@ function resolveFieldData(args, state, getIndex, getNestedValue2) {
|
|
|
240
234
|
}
|
|
241
235
|
const arrayKey = arg0;
|
|
242
236
|
const index = arg1;
|
|
243
|
-
const arr = state
|
|
237
|
+
const arr = getNestedValue2(state, arrayKey);
|
|
244
238
|
return {
|
|
245
239
|
type: "primitiveArray" /* PrimitiveArray */,
|
|
246
240
|
compositeKey: `${arrayKey}.@${index}`,
|
|
@@ -294,19 +288,42 @@ function resolveFieldData(args, state, getIndex, getNestedValue2) {
|
|
|
294
288
|
}
|
|
295
289
|
|
|
296
290
|
// src/hooks/useForm.tsx
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
291
|
+
import { isSchema, object, reach } from "yup";
|
|
292
|
+
import { jsx } from "react/jsx-runtime";
|
|
293
|
+
var DEFAULT_OPTIONS = {};
|
|
294
|
+
function useForm(schema, {
|
|
295
|
+
arrayIdentifiers,
|
|
296
|
+
onFormSubmit: onFormSubmitProp,
|
|
297
|
+
resetOnSubmit = false,
|
|
298
|
+
keepValues: keepValuesProp
|
|
299
|
+
} = DEFAULT_OPTIONS) {
|
|
300
|
+
const { initialState, validationSchema } = useMemo(() => {
|
|
301
|
+
const state2 = {};
|
|
302
|
+
const extractedRules = {};
|
|
303
|
+
Object.entries(schema).forEach(([key, value]) => {
|
|
304
|
+
if (isSchema(value)) {
|
|
305
|
+
try {
|
|
306
|
+
state2[key] = value.cast(void 0);
|
|
307
|
+
} catch {
|
|
308
|
+
state2[key] = void 0;
|
|
309
|
+
}
|
|
310
|
+
extractedRules[key] = value;
|
|
311
|
+
} else {
|
|
312
|
+
state2[key] = value;
|
|
313
|
+
}
|
|
314
|
+
});
|
|
315
|
+
return {
|
|
316
|
+
initialState: state2,
|
|
317
|
+
validationSchema: object().shape(extractedRules)
|
|
318
|
+
};
|
|
319
|
+
}, [schema]);
|
|
320
|
+
const [state, setState] = useState(initialState), [metadata, setMetadata] = useState(/* @__PURE__ */ new Map());
|
|
321
|
+
useComponentLanguage();
|
|
322
|
+
const stateRef = useRef(state), metadataRef = useRef(metadata);
|
|
305
323
|
stateRef.current = state;
|
|
306
|
-
|
|
307
|
-
errorsRef.current = errors2;
|
|
324
|
+
metadataRef.current = metadata;
|
|
308
325
|
const indexMap = useMemo(() => {
|
|
309
|
-
const
|
|
326
|
+
const map = /* @__PURE__ */ new Map();
|
|
310
327
|
const traverse = (current, path) => {
|
|
311
328
|
if (!current || typeof current !== "object") return;
|
|
312
329
|
if (Array.isArray(current)) {
|
|
@@ -322,7 +339,7 @@ function useForm(initialState, { rules, messages, arrayIdentifiers } = {}) {
|
|
|
322
339
|
traverse(item, `${path}.${index}`);
|
|
323
340
|
}
|
|
324
341
|
});
|
|
325
|
-
|
|
342
|
+
map.set(path, itemMap);
|
|
326
343
|
} else {
|
|
327
344
|
Object.keys(current).forEach((key) => {
|
|
328
345
|
const nextPath = path ? `${path}.${key}` : key;
|
|
@@ -331,105 +348,139 @@ function useForm(initialState, { rules, messages, arrayIdentifiers } = {}) {
|
|
|
331
348
|
}
|
|
332
349
|
};
|
|
333
350
|
traverse(state, "");
|
|
334
|
-
return
|
|
351
|
+
return map;
|
|
335
352
|
}, [state, arrayIdentifiers]);
|
|
336
353
|
const indexMapRef = useRef(indexMap);
|
|
337
354
|
indexMapRef.current = indexMap;
|
|
338
355
|
const getIndex = useCallback((arrayKey, itemId) => {
|
|
339
356
|
return indexMapRef.current.get(arrayKey)?.get(itemId);
|
|
340
357
|
}, []);
|
|
341
|
-
const
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
358
|
+
const ruleCache = useRef(/* @__PURE__ */ new Map());
|
|
359
|
+
useMemo(() => {
|
|
360
|
+
ruleCache.current.clear();
|
|
361
|
+
}, [validationSchema]);
|
|
362
|
+
const getRule = useCallback((path, schema2) => {
|
|
363
|
+
if (ruleCache.current.has(path)) {
|
|
364
|
+
return ruleCache.current.get(path);
|
|
365
|
+
}
|
|
366
|
+
let rule;
|
|
367
|
+
try {
|
|
368
|
+
rule = reach(schema2, path);
|
|
369
|
+
} catch {
|
|
352
370
|
const genericPath = path.replace(/\.\d+\./g, ".").replace(/\.\d+$/, "");
|
|
353
|
-
|
|
371
|
+
try {
|
|
372
|
+
rule = reach(schema2, genericPath);
|
|
373
|
+
} catch {
|
|
374
|
+
rule = void 0;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
ruleCache.current.set(path, rule);
|
|
378
|
+
return rule;
|
|
379
|
+
}, []);
|
|
380
|
+
const runValidation = useCallback(
|
|
381
|
+
(ruleDef, value, compositeKey) => {
|
|
382
|
+
if (isSchema(ruleDef)) {
|
|
383
|
+
try {
|
|
384
|
+
ruleDef.validateSync(value);
|
|
385
|
+
return false;
|
|
386
|
+
} catch (err) {
|
|
387
|
+
const error = {
|
|
388
|
+
isInvalid: true,
|
|
389
|
+
errorMessage: err.message || "Invalid"
|
|
390
|
+
};
|
|
391
|
+
setMetadata((prev) => {
|
|
392
|
+
const newMap = new Map(prev);
|
|
393
|
+
const currentMeta = newMap.get(compositeKey) || {
|
|
394
|
+
isTouched: false,
|
|
395
|
+
isInvalid: false,
|
|
396
|
+
errorMessage: ""
|
|
397
|
+
};
|
|
398
|
+
newMap.set(compositeKey, { ...currentMeta, ...error });
|
|
399
|
+
return newMap;
|
|
400
|
+
});
|
|
401
|
+
return true;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
return false;
|
|
354
405
|
},
|
|
355
|
-
[
|
|
406
|
+
[]
|
|
356
407
|
);
|
|
357
408
|
const validateField = useCallback(
|
|
358
|
-
(compositeKey, fieldPath, value
|
|
359
|
-
let
|
|
360
|
-
if (
|
|
361
|
-
|
|
362
|
-
if (stripped !== fieldPath) ruleDef = getRule(stripped);
|
|
363
|
-
}
|
|
364
|
-
const rule = typeof ruleDef === "function" ? ruleDef(
|
|
365
|
-
value,
|
|
366
|
-
stateRef.current,
|
|
367
|
-
extraContext?.item,
|
|
368
|
-
extraContext?.index
|
|
369
|
-
) : ruleDef;
|
|
370
|
-
let message = getMessage(fieldPath);
|
|
371
|
-
if (!message && fieldPath !== fieldPath.replace(/\.@\d+/, "")) {
|
|
372
|
-
message = getMessage(fieldPath.replace(/\.@\d+/, ""));
|
|
409
|
+
(compositeKey, fieldPath, value) => {
|
|
410
|
+
let schemaRule = getRule(fieldPath, validationSchema);
|
|
411
|
+
if (schemaRule) {
|
|
412
|
+
if (runValidation(schemaRule, value, compositeKey)) return true;
|
|
373
413
|
}
|
|
374
|
-
|
|
375
|
-
setErrors((prev) => {
|
|
414
|
+
setMetadata((prev) => {
|
|
376
415
|
const newMap = new Map(prev);
|
|
377
|
-
newMap.
|
|
416
|
+
const currentMeta = newMap.get(compositeKey) || {
|
|
417
|
+
isTouched: false,
|
|
418
|
+
isInvalid: false,
|
|
419
|
+
errorMessage: ""
|
|
420
|
+
};
|
|
421
|
+
newMap.set(compositeKey, {
|
|
422
|
+
...currentMeta,
|
|
423
|
+
isInvalid: false,
|
|
424
|
+
errorMessage: ""
|
|
425
|
+
});
|
|
378
426
|
return newMap;
|
|
379
427
|
});
|
|
380
|
-
return
|
|
428
|
+
return false;
|
|
381
429
|
},
|
|
382
|
-
[getRule,
|
|
430
|
+
[getRule, runValidation, validationSchema]
|
|
383
431
|
);
|
|
384
432
|
const validateAll = useCallback(() => {
|
|
385
|
-
if (!
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
433
|
+
if (!validationSchema) return false;
|
|
434
|
+
let hasError = false;
|
|
435
|
+
const newMetadata = new Map(metadataRef.current);
|
|
436
|
+
try {
|
|
437
|
+
validationSchema.validateSync(state, { abortEarly: false });
|
|
438
|
+
} catch (err) {
|
|
439
|
+
hasError = true;
|
|
440
|
+
if (err.inner) {
|
|
441
|
+
err.inner.forEach((validationError) => {
|
|
442
|
+
const yupPath = validationError.path;
|
|
443
|
+
const dotPath = yupPath.replace(/\[(\d+)\]/g, ".$1");
|
|
444
|
+
const parts = dotPath.split(".");
|
|
445
|
+
let current = state;
|
|
446
|
+
const compositeParts = [];
|
|
447
|
+
for (let i = 0; i < parts.length; i++) {
|
|
448
|
+
const part = parts[i];
|
|
449
|
+
if (Array.isArray(current)) {
|
|
450
|
+
const index = parseInt(part, 10);
|
|
451
|
+
const item = current[index];
|
|
452
|
+
if (item && typeof item === "object") {
|
|
453
|
+
const genericPath = compositeParts.join(".").replace(/\.\d+/g, "");
|
|
454
|
+
const idKey = arrayIdentifiers?.[genericPath] || "id";
|
|
455
|
+
const id = item[idKey];
|
|
456
|
+
compositeParts.push(String(id !== void 0 ? id : index));
|
|
457
|
+
} else {
|
|
458
|
+
compositeParts.push(part);
|
|
459
|
+
}
|
|
460
|
+
current = item;
|
|
461
|
+
} else {
|
|
462
|
+
compositeParts.push(part);
|
|
463
|
+
current = current?.[part];
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
const compositeKey = compositeParts.join(".");
|
|
467
|
+
const currentMeta = newMetadata.get(compositeKey) || {
|
|
468
|
+
isTouched: false,
|
|
469
|
+
isInvalid: false,
|
|
470
|
+
errorMessage: ""
|
|
471
|
+
};
|
|
472
|
+
newMetadata.set(compositeKey, {
|
|
473
|
+
...currentMeta,
|
|
474
|
+
isTouched: true,
|
|
475
|
+
isInvalid: true,
|
|
476
|
+
errorMessage: validationError.message
|
|
413
477
|
});
|
|
414
|
-
}
|
|
415
|
-
} else {
|
|
416
|
-
const val = getNestedValue(stateRef.current, ruleKey);
|
|
417
|
-
const rule = typeof ruleVal === "function" ? ruleVal(val, stateRef.current) : ruleVal;
|
|
418
|
-
const msg = getMessage(ruleKey);
|
|
419
|
-
const err = performValidations(val, rule, msg);
|
|
420
|
-
nextErrors.set(ruleKey, err);
|
|
421
|
-
if (err.isInvalid) hasInvalid = true;
|
|
478
|
+
});
|
|
422
479
|
}
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
const next = new Map(prev);
|
|
428
|
-
nextErrors.forEach((_, k) => next.set(k, true));
|
|
429
|
-
return next;
|
|
430
|
-
});
|
|
431
|
-
return hasInvalid;
|
|
432
|
-
}, [rules, getMessage, performValidations]);
|
|
480
|
+
}
|
|
481
|
+
setMetadata(newMetadata);
|
|
482
|
+
return hasError;
|
|
483
|
+
}, [validationSchema, state, arrayIdentifiers]);
|
|
433
484
|
const handleFieldChange = useCallback(
|
|
434
485
|
(resolution, newValue) => {
|
|
435
486
|
if (!resolution) return;
|
|
@@ -443,18 +494,33 @@ function useForm(initialState, { rules, messages, arrayIdentifiers } = {}) {
|
|
|
443
494
|
parentId,
|
|
444
495
|
nestedField
|
|
445
496
|
} = resolution;
|
|
497
|
+
let finalValue = newValue;
|
|
498
|
+
let rule = getRule(fieldPath, validationSchema);
|
|
499
|
+
if (rule && rule.type === "array" && type === "primitiveArray" /* PrimitiveArray */ && rule.innerType) {
|
|
500
|
+
rule = rule.innerType;
|
|
501
|
+
}
|
|
502
|
+
if (rule && rule.type === "string") {
|
|
503
|
+
try {
|
|
504
|
+
finalValue = rule.cast(newValue);
|
|
505
|
+
} catch {
|
|
506
|
+
}
|
|
507
|
+
}
|
|
446
508
|
setState((prev) => {
|
|
447
509
|
if (type === "scalar" /* Scalar */) {
|
|
448
510
|
return handleNestedChange({
|
|
449
511
|
state: prev,
|
|
450
512
|
id: compositeKey,
|
|
451
|
-
value:
|
|
513
|
+
value: finalValue,
|
|
514
|
+
hasNestedValues: compositeKey.includes(".")
|
|
452
515
|
});
|
|
453
516
|
}
|
|
454
517
|
if (type === "primitiveArray" /* PrimitiveArray */) {
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
518
|
+
return handleNestedChange({
|
|
519
|
+
state: prev,
|
|
520
|
+
id: `${arrayKey}.${index}`,
|
|
521
|
+
value: finalValue,
|
|
522
|
+
hasNestedValues: true
|
|
523
|
+
});
|
|
458
524
|
}
|
|
459
525
|
if (type === "objectArray" /* ObjectArray */) {
|
|
460
526
|
return handleArrayItemChange({
|
|
@@ -462,7 +528,7 @@ function useForm(initialState, { rules, messages, arrayIdentifiers } = {}) {
|
|
|
462
528
|
arrayKey,
|
|
463
529
|
index,
|
|
464
530
|
field: resolution.field,
|
|
465
|
-
value:
|
|
531
|
+
value: finalValue
|
|
466
532
|
});
|
|
467
533
|
}
|
|
468
534
|
if (type === "nestedPrimitiveArray" /* NestedPrimitiveArray */) {
|
|
@@ -471,41 +537,40 @@ function useForm(initialState, { rules, messages, arrayIdentifiers } = {}) {
|
|
|
471
537
|
const parentArr = [...prev[parentKey]];
|
|
472
538
|
const pItem = { ...parentArr[pIndex] };
|
|
473
539
|
const nestedArr = [...getNestedValue(pItem, nestedField) || []];
|
|
474
|
-
nestedArr[index] =
|
|
540
|
+
nestedArr[index] = finalValue;
|
|
475
541
|
pItem[nestedField] = nestedArr;
|
|
476
|
-
|
|
477
|
-
parentArr[pIndex] = updatedItem;
|
|
542
|
+
parentArr[pIndex] = pItem;
|
|
478
543
|
return { ...prev, [parentKey]: parentArr };
|
|
479
544
|
}
|
|
480
545
|
return prev;
|
|
481
546
|
});
|
|
482
|
-
|
|
483
|
-
if (type === "objectArray" /* ObjectArray */ || type === "nestedPrimitiveArray" /* NestedPrimitiveArray */) {
|
|
484
|
-
const idx = index;
|
|
485
|
-
const arrKey = arrayKey || parentKey;
|
|
486
|
-
extraContext = {
|
|
487
|
-
index: idx,
|
|
488
|
-
item: stateRef.current[arrKey]?.[idx]
|
|
489
|
-
};
|
|
490
|
-
}
|
|
491
|
-
validateField(compositeKey, fieldPath, newValue, extraContext);
|
|
547
|
+
validateField(compositeKey, fieldPath, finalValue);
|
|
492
548
|
},
|
|
493
|
-
[getIndex, validateField]
|
|
549
|
+
[getIndex, validateField, getRule, validationSchema]
|
|
494
550
|
);
|
|
495
551
|
const createHandlers = useCallback(
|
|
496
552
|
(resolution) => {
|
|
497
553
|
if (!resolution) return {};
|
|
498
554
|
const { compositeKey, fieldPath, value } = resolution;
|
|
499
|
-
const
|
|
500
|
-
const isTouched =
|
|
555
|
+
const meta = metadataRef.current.get(compositeKey);
|
|
556
|
+
const isTouched = meta?.isTouched;
|
|
501
557
|
return {
|
|
502
558
|
id: compositeKey,
|
|
503
|
-
isInvalid: Boolean(isTouched &&
|
|
504
|
-
errorMessage: isTouched ?
|
|
559
|
+
isInvalid: Boolean(isTouched && meta?.isInvalid),
|
|
560
|
+
errorMessage: isTouched ? meta?.errorMessage || "" : "",
|
|
505
561
|
onBlur: () => {
|
|
506
|
-
if (
|
|
562
|
+
if (metadataRef.current.get(compositeKey)?.isTouched) return;
|
|
507
563
|
validateField(compositeKey, fieldPath, value);
|
|
508
|
-
|
|
564
|
+
setMetadata((prev) => {
|
|
565
|
+
const newMap = new Map(prev);
|
|
566
|
+
const current = newMap.get(compositeKey) || {
|
|
567
|
+
isTouched: false,
|
|
568
|
+
isInvalid: false,
|
|
569
|
+
errorMessage: ""
|
|
570
|
+
};
|
|
571
|
+
newMap.set(compositeKey, { ...current, isTouched: true });
|
|
572
|
+
return newMap;
|
|
573
|
+
});
|
|
509
574
|
}
|
|
510
575
|
};
|
|
511
576
|
},
|
|
@@ -569,54 +634,77 @@ function useForm(initialState, { rules, messages, arrayIdentifiers } = {}) {
|
|
|
569
634
|
() => ({
|
|
570
635
|
addItem: (arrayKey, item, index) => {
|
|
571
636
|
setState((prev) => {
|
|
572
|
-
const arr = [...prev[
|
|
637
|
+
const arr = [...getNestedValue(prev, arrayKey) || []];
|
|
573
638
|
if (index === void 0) arr.push(item);
|
|
574
639
|
else arr.splice(index, 0, item);
|
|
575
|
-
return {
|
|
640
|
+
return handleNestedChange({
|
|
641
|
+
state: prev,
|
|
642
|
+
id: arrayKey,
|
|
643
|
+
value: arr,
|
|
644
|
+
hasNestedValues: String(arrayKey).includes(".")
|
|
645
|
+
});
|
|
576
646
|
});
|
|
577
647
|
},
|
|
578
648
|
removeItem: (arrayKey, index) => {
|
|
579
|
-
const currentArr = stateRef.current[
|
|
649
|
+
const currentArr = getNestedValue(stateRef.current, arrayKey) || [];
|
|
580
650
|
const item = currentArr[index];
|
|
581
651
|
const idKey = arrayIdentifiers?.[arrayKey] || "id";
|
|
582
652
|
const itemId = item?.[idKey];
|
|
583
653
|
setState((prev) => {
|
|
584
|
-
const arr = [...prev[
|
|
654
|
+
const arr = [...getNestedValue(prev, arrayKey) || []];
|
|
585
655
|
arr.splice(index, 1);
|
|
586
|
-
return {
|
|
656
|
+
return handleNestedChange({
|
|
657
|
+
state: prev,
|
|
658
|
+
id: arrayKey,
|
|
659
|
+
value: arr,
|
|
660
|
+
hasNestedValues: String(arrayKey).includes(".")
|
|
661
|
+
});
|
|
587
662
|
});
|
|
588
663
|
if (itemId !== void 0) {
|
|
589
664
|
const prefix = `${String(arrayKey)}.${itemId}.`;
|
|
590
|
-
|
|
591
|
-
setErrors((prev) => removeCompositeKeysByPrefix(prev, prefix));
|
|
665
|
+
setMetadata((prev) => removeCompositeKeysByPrefix(prev, prefix));
|
|
592
666
|
}
|
|
593
667
|
},
|
|
594
668
|
removeById: (arrayKey, itemId) => {
|
|
595
669
|
const index = getIndex(arrayKey, itemId);
|
|
596
670
|
if (index !== void 0) {
|
|
597
671
|
setState((prev) => {
|
|
598
|
-
const arr = [...prev[
|
|
672
|
+
const arr = [...getNestedValue(prev, arrayKey) || []];
|
|
599
673
|
arr.splice(index, 1);
|
|
600
|
-
return {
|
|
674
|
+
return handleNestedChange({
|
|
675
|
+
state: prev,
|
|
676
|
+
id: arrayKey,
|
|
677
|
+
value: arr,
|
|
678
|
+
hasNestedValues: String(arrayKey).includes(".")
|
|
679
|
+
});
|
|
601
680
|
});
|
|
602
681
|
const prefix = `${String(arrayKey)}.${itemId}.`;
|
|
603
|
-
|
|
604
|
-
setErrors((prev) => removeCompositeKeysByPrefix(prev, prefix));
|
|
682
|
+
setMetadata((prev) => removeCompositeKeysByPrefix(prev, prefix));
|
|
605
683
|
}
|
|
606
684
|
},
|
|
607
685
|
updateItem: (arrayKey, index, value) => {
|
|
608
686
|
setState((prev) => {
|
|
609
|
-
const arr = [...prev[
|
|
687
|
+
const arr = [...getNestedValue(prev, arrayKey) || []];
|
|
610
688
|
arr[index] = value;
|
|
611
|
-
return {
|
|
689
|
+
return handleNestedChange({
|
|
690
|
+
state: prev,
|
|
691
|
+
id: arrayKey,
|
|
692
|
+
value: arr,
|
|
693
|
+
hasNestedValues: String(arrayKey).includes(".")
|
|
694
|
+
});
|
|
612
695
|
});
|
|
613
696
|
},
|
|
614
697
|
moveItem: (arrayKey, from, to) => {
|
|
615
698
|
setState((prev) => {
|
|
616
|
-
const arr = [...prev[
|
|
699
|
+
const arr = [...getNestedValue(prev, arrayKey) || []];
|
|
617
700
|
const [item] = arr.splice(from, 1);
|
|
618
701
|
arr.splice(to, 0, item);
|
|
619
|
-
return {
|
|
702
|
+
return handleNestedChange({
|
|
703
|
+
state: prev,
|
|
704
|
+
id: arrayKey,
|
|
705
|
+
value: arr,
|
|
706
|
+
hasNestedValues: String(arrayKey).includes(".")
|
|
707
|
+
});
|
|
620
708
|
});
|
|
621
709
|
},
|
|
622
710
|
moveById: (arrayKey, fromId, toId) => {
|
|
@@ -624,25 +712,42 @@ function useForm(initialState, { rules, messages, arrayIdentifiers } = {}) {
|
|
|
624
712
|
const toIndex = getIndex(arrayKey, toId);
|
|
625
713
|
if (fromIndex !== void 0 && toIndex !== void 0) {
|
|
626
714
|
setState((prev) => {
|
|
627
|
-
const arr = [...prev[
|
|
715
|
+
const arr = [...getNestedValue(prev, arrayKey) || []];
|
|
628
716
|
const [item] = arr.splice(fromIndex, 1);
|
|
629
717
|
arr.splice(toIndex, 0, item);
|
|
630
|
-
return {
|
|
718
|
+
return handleNestedChange({
|
|
719
|
+
state: prev,
|
|
720
|
+
id: arrayKey,
|
|
721
|
+
value: arr,
|
|
722
|
+
hasNestedValues: String(arrayKey).includes(".")
|
|
723
|
+
});
|
|
631
724
|
});
|
|
632
725
|
}
|
|
633
726
|
},
|
|
634
727
|
getItem: (arrayKey, itemId) => {
|
|
635
728
|
const index = getIndex(arrayKey, itemId);
|
|
636
729
|
if (index === void 0) return void 0;
|
|
637
|
-
return stateRef.current
|
|
730
|
+
return getNestedValue(stateRef.current, arrayKey)[index];
|
|
638
731
|
}
|
|
639
732
|
}),
|
|
640
733
|
[getIndex, arrayIdentifiers]
|
|
641
734
|
);
|
|
642
|
-
const onBlur = (
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
735
|
+
const onBlur = useCallback(
|
|
736
|
+
(id) => {
|
|
737
|
+
validateField(String(id), String(id), stateRef.current[id]);
|
|
738
|
+
setMetadata((prev) => {
|
|
739
|
+
const newMap = new Map(prev);
|
|
740
|
+
const current = newMap.get(String(id)) || {
|
|
741
|
+
isTouched: false,
|
|
742
|
+
isInvalid: false,
|
|
743
|
+
errorMessage: ""
|
|
744
|
+
};
|
|
745
|
+
newMap.set(String(id), { ...current, isTouched: true });
|
|
746
|
+
return newMap;
|
|
747
|
+
});
|
|
748
|
+
},
|
|
749
|
+
[validateField]
|
|
750
|
+
);
|
|
646
751
|
const polymorphicOnValueChange = useCallback(
|
|
647
752
|
(...args) => {
|
|
648
753
|
const value = args[args.length - 1];
|
|
@@ -665,22 +770,26 @@ function useForm(initialState, { rules, messages, arrayIdentifiers } = {}) {
|
|
|
665
770
|
},
|
|
666
771
|
[validateField]
|
|
667
772
|
);
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
773
|
+
const onFormSubmit = useCallback(
|
|
774
|
+
(fn) => (e) => {
|
|
775
|
+
e.preventDefault();
|
|
776
|
+
if (validateAll()) return;
|
|
777
|
+
fn(stateRef.current, e);
|
|
778
|
+
},
|
|
779
|
+
[validateAll]
|
|
780
|
+
);
|
|
781
|
+
const onFormSubmitPropRef = useRef(onFormSubmitProp);
|
|
782
|
+
onFormSubmitPropRef.current = onFormSubmitProp;
|
|
783
|
+
const resetOnSubmitRef = useRef(resetOnSubmit);
|
|
784
|
+
resetOnSubmitRef.current = resetOnSubmit;
|
|
785
|
+
const keepValuesPropRef = useRef(keepValuesProp);
|
|
786
|
+
keepValuesPropRef.current = keepValuesProp;
|
|
787
|
+
const handleReset = useCallback(
|
|
788
|
+
(options) => {
|
|
789
|
+
const { keepValues } = options || {};
|
|
790
|
+
if (keepValues && keepValues.length > 0) {
|
|
682
791
|
const nextState = { ...initialState };
|
|
683
|
-
|
|
792
|
+
keepValues.forEach((k) => {
|
|
684
793
|
if (stateRef.current[k] !== void 0)
|
|
685
794
|
nextState[k] = stateRef.current[k];
|
|
686
795
|
});
|
|
@@ -688,25 +797,59 @@ function useForm(initialState, { rules, messages, arrayIdentifiers } = {}) {
|
|
|
688
797
|
} else {
|
|
689
798
|
setState(initialState);
|
|
690
799
|
}
|
|
691
|
-
|
|
692
|
-
setErrors(/* @__PURE__ */ new Map());
|
|
800
|
+
setMetadata(/* @__PURE__ */ new Map());
|
|
693
801
|
},
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
802
|
+
[initialState]
|
|
803
|
+
);
|
|
804
|
+
const validateAllRef = useRef(validateAll);
|
|
805
|
+
validateAllRef.current = validateAll;
|
|
806
|
+
const ControlledForm = useMemo(() => {
|
|
807
|
+
return (props) => {
|
|
808
|
+
const { onSubmit, ...rest } = props;
|
|
809
|
+
const handleSubmit = (e) => {
|
|
810
|
+
e.preventDefault();
|
|
811
|
+
if (validateAllRef.current()) {
|
|
812
|
+
return;
|
|
813
|
+
}
|
|
814
|
+
onFormSubmitPropRef.current?.(stateRef.current, e);
|
|
815
|
+
if (resetOnSubmitRef.current) {
|
|
816
|
+
handleReset({ keepValues: keepValuesPropRef.current });
|
|
817
|
+
}
|
|
818
|
+
onSubmit?.(stateRef.current, e);
|
|
819
|
+
};
|
|
820
|
+
return /* @__PURE__ */ jsx(Form, { onSubmit: handleSubmit, ...rest });
|
|
821
|
+
};
|
|
822
|
+
}, []);
|
|
823
|
+
return useMemo(
|
|
824
|
+
() => ({
|
|
825
|
+
state,
|
|
826
|
+
setState,
|
|
827
|
+
metadata,
|
|
828
|
+
on,
|
|
829
|
+
helpers,
|
|
830
|
+
onFieldChange: polymorphicOnValueChange,
|
|
831
|
+
onFieldBlur: onBlur,
|
|
832
|
+
onSelectionChange: polymorphicOnSelectionChange,
|
|
833
|
+
isDirty: Array.from(metadata.values()).some((m) => m.isTouched),
|
|
834
|
+
onFormReset: handleReset,
|
|
835
|
+
onFormSubmit,
|
|
836
|
+
ControlledForm
|
|
837
|
+
}),
|
|
838
|
+
[
|
|
839
|
+
state,
|
|
840
|
+
setState,
|
|
841
|
+
metadata,
|
|
842
|
+
on,
|
|
843
|
+
helpers,
|
|
844
|
+
onBlur,
|
|
845
|
+
polymorphicOnValueChange,
|
|
846
|
+
polymorphicOnSelectionChange,
|
|
847
|
+
validateAll,
|
|
848
|
+
onFormSubmit,
|
|
849
|
+
ControlledForm,
|
|
850
|
+
initialState
|
|
851
|
+
]
|
|
852
|
+
);
|
|
710
853
|
}
|
|
711
854
|
export {
|
|
712
855
|
NextUIError,
|