@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.js
CHANGED
|
@@ -35,7 +35,7 @@ var NextUIError = class {
|
|
|
35
35
|
};
|
|
36
36
|
|
|
37
37
|
// src/hooks/useForm.tsx
|
|
38
|
-
var
|
|
38
|
+
var import_react2 = require("react");
|
|
39
39
|
|
|
40
40
|
// src/utils/utils.ts
|
|
41
41
|
function handleNestedChange({
|
|
@@ -45,11 +45,15 @@ function handleNestedChange({
|
|
|
45
45
|
hasNestedValues = false
|
|
46
46
|
}) {
|
|
47
47
|
if (!hasNestedValues) return { ...state, [id]: value };
|
|
48
|
-
const propertyDepth = String(id).split("."), newValues = state;
|
|
48
|
+
const propertyDepth = String(id).split("."), newValues = { ...state };
|
|
49
49
|
let current = newValues;
|
|
50
50
|
for (let i = 0; i < propertyDepth.length - 1; i++) {
|
|
51
51
|
const key = propertyDepth[i];
|
|
52
|
-
current[key]
|
|
52
|
+
if (Array.isArray(current[key])) {
|
|
53
|
+
current[key] = [...current[key]];
|
|
54
|
+
} else {
|
|
55
|
+
current[key] = { ...current[key] };
|
|
56
|
+
}
|
|
53
57
|
current = current[key];
|
|
54
58
|
}
|
|
55
59
|
current[propertyDepth[propertyDepth.length - 1]] = value;
|
|
@@ -70,7 +74,11 @@ function handleArrayItemChange({
|
|
|
70
74
|
} else {
|
|
71
75
|
let current = item;
|
|
72
76
|
for (let i = 0; i < fieldDepth.length - 1; i++) {
|
|
73
|
-
current[fieldDepth[i]]
|
|
77
|
+
if (Array.isArray(current[fieldDepth[i]])) {
|
|
78
|
+
current[fieldDepth[i]] = [...current[fieldDepth[i]]];
|
|
79
|
+
} else {
|
|
80
|
+
current[fieldDepth[i]] = { ...current[fieldDepth[i]] };
|
|
81
|
+
}
|
|
74
82
|
current = current[fieldDepth[i]];
|
|
75
83
|
}
|
|
76
84
|
current[fieldDepth[fieldDepth.length - 1]] = value;
|
|
@@ -81,141 +89,134 @@ function handleArrayItemChange({
|
|
|
81
89
|
function getNestedValue(obj, path) {
|
|
82
90
|
return path.split(".").reduce((acc, key) => acc?.[key], obj);
|
|
83
91
|
}
|
|
84
|
-
function removeCompositeKeysByPrefix(
|
|
85
|
-
const result = new Map(
|
|
86
|
-
for (const key of
|
|
92
|
+
function removeCompositeKeysByPrefix(map, prefix) {
|
|
93
|
+
const result = new Map(map);
|
|
94
|
+
for (const key of map.keys()) {
|
|
87
95
|
if (key.startsWith(prefix)) {
|
|
88
96
|
result.delete(key);
|
|
89
97
|
}
|
|
90
98
|
}
|
|
91
99
|
return result;
|
|
92
100
|
}
|
|
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
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
msg: "INVALID_EMAIL"
|
|
150
|
-
},
|
|
151
|
-
password: {
|
|
152
|
-
validate: (val) => new RegExp(regex.password).test(val),
|
|
153
|
-
msg: "INVALID_PASSWORD"
|
|
101
|
+
|
|
102
|
+
// src/hooks/useForm.tsx
|
|
103
|
+
var import_react3 = require("@heroui/react");
|
|
104
|
+
|
|
105
|
+
// src/hooks/useComponentLang.tsx
|
|
106
|
+
var import_yup = require("yup");
|
|
107
|
+
var import_react = require("react");
|
|
108
|
+
|
|
109
|
+
// src/assets/translations.ts
|
|
110
|
+
var translations = {
|
|
111
|
+
en: {
|
|
112
|
+
mixed: {
|
|
113
|
+
default: "Invalid value",
|
|
114
|
+
required: "This field is required",
|
|
115
|
+
oneOf: "Must be one of: ${values}",
|
|
116
|
+
notOneOf: "Cannot be any of: ${values}",
|
|
117
|
+
notType: "Incorrect data format",
|
|
118
|
+
defined: "Must be defined"
|
|
119
|
+
},
|
|
120
|
+
string: {
|
|
121
|
+
length: "Must be exactly ${length} characters",
|
|
122
|
+
min: "Must be at least ${min} characters",
|
|
123
|
+
max: "Must be at most ${max} characters",
|
|
124
|
+
matches: 'Must match: "${regex}"',
|
|
125
|
+
email: "Enter a valid email address",
|
|
126
|
+
url: "Enter a valid URL",
|
|
127
|
+
uuid: "Enter a valid UUID",
|
|
128
|
+
trim: "Remove leading/trailing spaces",
|
|
129
|
+
lowercase: "Must be in lowercase",
|
|
130
|
+
uppercase: "Must be in uppercase",
|
|
131
|
+
password: "Your password doesn't meet the security criteria."
|
|
132
|
+
},
|
|
133
|
+
number: {
|
|
134
|
+
min: "Value must be ${min} or greater",
|
|
135
|
+
max: "Value must be ${max} or less",
|
|
136
|
+
lessThan: "Must be less than ${less}",
|
|
137
|
+
moreThan: "Must be greater than ${more}",
|
|
138
|
+
positive: "Must be a positive number",
|
|
139
|
+
negative: "Must be a negative number",
|
|
140
|
+
integer: "Must be a whole number"
|
|
141
|
+
},
|
|
142
|
+
date: {
|
|
143
|
+
min: "Date must be after ${min}",
|
|
144
|
+
max: "Date must be before ${max}"
|
|
145
|
+
},
|
|
146
|
+
boolean: {
|
|
147
|
+
isValue: "Must be ${value}"
|
|
148
|
+
},
|
|
149
|
+
object: {
|
|
150
|
+
noUnknown: "Contains unknown properties"
|
|
151
|
+
},
|
|
152
|
+
array: {
|
|
153
|
+
min: "Must have at least ${min} items",
|
|
154
|
+
max: "Must have ${max} items or fewer",
|
|
155
|
+
length: "Must have exactly ${length} items"
|
|
156
|
+
}
|
|
154
157
|
},
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
+
es: {
|
|
159
|
+
mixed: {
|
|
160
|
+
default: "Valor no v\xE1lido",
|
|
161
|
+
required: "Este campo es obligatorio",
|
|
162
|
+
oneOf: "Debe ser uno de: ${values}",
|
|
163
|
+
notOneOf: "No puede ser ninguno de: ${values}",
|
|
164
|
+
defined: "Debe estar definido",
|
|
165
|
+
notType: "Formato de dato incorrecto"
|
|
166
|
+
},
|
|
167
|
+
string: {
|
|
168
|
+
length: "Debe tener exactamente ${length} caracteres",
|
|
169
|
+
min: "Debe tener al menos ${min} caracteres",
|
|
170
|
+
max: "Debe tener como m\xE1ximo ${max} caracteres",
|
|
171
|
+
matches: 'Debe coincidir con: "${regex}"',
|
|
172
|
+
email: "Ingresa un correo electr\xF3nico v\xE1lido",
|
|
173
|
+
url: "Ingresa una URL v\xE1lida",
|
|
174
|
+
uuid: "Ingresa un UUID v\xE1lido",
|
|
175
|
+
trim: "No debe contener espacios al inicio o final",
|
|
176
|
+
lowercase: "Debe estar en min\xFAsculas",
|
|
177
|
+
uppercase: "Debe estar en may\xFAsculas",
|
|
178
|
+
password: "Tu contrase\xF1a no cumple con los requisitos de seguridad."
|
|
179
|
+
},
|
|
180
|
+
number: {
|
|
181
|
+
min: "Debe ser mayor o igual a ${min}",
|
|
182
|
+
max: "Debe ser menor o igual a ${max}",
|
|
183
|
+
lessThan: "Debe ser menor a ${less}",
|
|
184
|
+
moreThan: "Debe ser mayor a ${more}",
|
|
185
|
+
positive: "Debe ser un n\xFAmero positivo",
|
|
186
|
+
negative: "Debe ser un n\xFAmero negativo",
|
|
187
|
+
integer: "Debe ser un n\xFAmero entero"
|
|
188
|
+
},
|
|
189
|
+
date: {
|
|
190
|
+
min: "La fecha debe ser posterior a ${min}",
|
|
191
|
+
max: "La fecha debe ser anterior a ${max}"
|
|
192
|
+
},
|
|
193
|
+
boolean: {
|
|
194
|
+
isValue: "Debe ser ${value}"
|
|
195
|
+
},
|
|
196
|
+
object: {
|
|
197
|
+
noUnknown: "Contiene propiedades no permitidas"
|
|
198
|
+
},
|
|
199
|
+
array: {
|
|
200
|
+
min: "Debe tener al menos ${min} elementos",
|
|
201
|
+
max: "Debe tener como m\xE1ximo ${max} elementos",
|
|
202
|
+
length: "Debe tener ${length} elementos"
|
|
203
|
+
}
|
|
158
204
|
}
|
|
159
205
|
};
|
|
160
206
|
|
|
161
|
-
// lang/en.json
|
|
162
|
-
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" };
|
|
163
|
-
|
|
164
|
-
// lang/es.json
|
|
165
|
-
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" };
|
|
166
|
-
|
|
167
207
|
// src/hooks/useComponentLang.tsx
|
|
168
208
|
var cookieName = "LOCALE";
|
|
169
|
-
var langMap = {
|
|
170
|
-
en: en_default,
|
|
171
|
-
es: es_default
|
|
172
|
-
};
|
|
173
209
|
var getClientCookie = () => {
|
|
174
210
|
const value = "; " + document.cookie, decodedValue = decodeURIComponent(value), parts = decodedValue.split("; " + cookieName + "=");
|
|
175
211
|
if (parts.length === 2) return parts.pop()?.split(";").shift();
|
|
176
212
|
};
|
|
177
|
-
var getServerCookie = () => {
|
|
178
|
-
try {
|
|
179
|
-
const { cookies } = require("next/headers");
|
|
180
|
-
return cookies().get(cookieName)?.value;
|
|
181
|
-
} catch {
|
|
182
|
-
return "es";
|
|
183
|
-
}
|
|
184
|
-
};
|
|
185
213
|
function useComponentLanguage() {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
locale
|
|
189
|
-
|
|
190
|
-
};
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
// src/hooks/useValidate.tsx
|
|
194
|
-
var validProps = {
|
|
195
|
-
isInvalid: false,
|
|
196
|
-
errorMessage: ""
|
|
197
|
-
};
|
|
198
|
-
function useValidate() {
|
|
199
|
-
const { lang } = useComponentLanguage();
|
|
200
|
-
const performValidations = (value, validationTypes, errorMessages) => {
|
|
201
|
-
if (!validationTypes) return validProps;
|
|
202
|
-
const items = Object.entries(validationTypes), requiredExist = validationTypes?.required !== void 0, isRequired = requiredExist ? validationTypes.required : false;
|
|
203
|
-
if (value === "" && !isRequired) return validProps;
|
|
204
|
-
let errorFound = validProps;
|
|
205
|
-
for (const [key, opts] of items) {
|
|
206
|
-
if (opts === null) continue;
|
|
207
|
-
const { validate, msg } = errors[key], isInvalid = !validate(value, opts);
|
|
208
|
-
if (isInvalid) {
|
|
209
|
-
errorFound = {
|
|
210
|
-
isInvalid,
|
|
211
|
-
errorMessage: errorMessages?.[key] || lang[msg]
|
|
212
|
-
};
|
|
213
|
-
break;
|
|
214
|
-
}
|
|
214
|
+
(0, import_react.useEffect)(() => {
|
|
215
|
+
const locale = getClientCookie() || "en";
|
|
216
|
+
if (translations[locale]) {
|
|
217
|
+
(0, import_yup.setLocale)(translations[locale]);
|
|
215
218
|
}
|
|
216
|
-
|
|
217
|
-
};
|
|
218
|
-
return { performValidations };
|
|
219
|
+
}, []);
|
|
219
220
|
}
|
|
220
221
|
|
|
221
222
|
// src/hooks/useForm.utils.ts
|
|
@@ -259,7 +260,7 @@ function resolveFieldData(args, state, getIndex, getNestedValue2) {
|
|
|
259
260
|
}
|
|
260
261
|
const arrayKey = arg0;
|
|
261
262
|
const index = arg1;
|
|
262
|
-
const arr = state
|
|
263
|
+
const arr = getNestedValue2(state, arrayKey);
|
|
263
264
|
return {
|
|
264
265
|
type: "primitiveArray" /* PrimitiveArray */,
|
|
265
266
|
compositeKey: `${arrayKey}.@${index}`,
|
|
@@ -313,19 +314,42 @@ function resolveFieldData(args, state, getIndex, getNestedValue2) {
|
|
|
313
314
|
}
|
|
314
315
|
|
|
315
316
|
// src/hooks/useForm.tsx
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
317
|
+
var import_yup2 = require("yup");
|
|
318
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
319
|
+
var DEFAULT_OPTIONS = {};
|
|
320
|
+
function useForm(schema, {
|
|
321
|
+
arrayIdentifiers,
|
|
322
|
+
onFormSubmit: onFormSubmitProp,
|
|
323
|
+
resetOnSubmit = false,
|
|
324
|
+
keepValues: keepValuesProp
|
|
325
|
+
} = DEFAULT_OPTIONS) {
|
|
326
|
+
const { initialState, validationSchema } = (0, import_react2.useMemo)(() => {
|
|
327
|
+
const state2 = {};
|
|
328
|
+
const extractedRules = {};
|
|
329
|
+
Object.entries(schema).forEach(([key, value]) => {
|
|
330
|
+
if ((0, import_yup2.isSchema)(value)) {
|
|
331
|
+
try {
|
|
332
|
+
state2[key] = value.cast(void 0);
|
|
333
|
+
} catch {
|
|
334
|
+
state2[key] = void 0;
|
|
335
|
+
}
|
|
336
|
+
extractedRules[key] = value;
|
|
337
|
+
} else {
|
|
338
|
+
state2[key] = value;
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
return {
|
|
342
|
+
initialState: state2,
|
|
343
|
+
validationSchema: (0, import_yup2.object)().shape(extractedRules)
|
|
344
|
+
};
|
|
345
|
+
}, [schema]);
|
|
346
|
+
const [state, setState] = (0, import_react2.useState)(initialState), [metadata, setMetadata] = (0, import_react2.useState)(/* @__PURE__ */ new Map());
|
|
347
|
+
useComponentLanguage();
|
|
348
|
+
const stateRef = (0, import_react2.useRef)(state), metadataRef = (0, import_react2.useRef)(metadata);
|
|
324
349
|
stateRef.current = state;
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
const map2 = /* @__PURE__ */ new Map();
|
|
350
|
+
metadataRef.current = metadata;
|
|
351
|
+
const indexMap = (0, import_react2.useMemo)(() => {
|
|
352
|
+
const map = /* @__PURE__ */ new Map();
|
|
329
353
|
const traverse = (current, path) => {
|
|
330
354
|
if (!current || typeof current !== "object") return;
|
|
331
355
|
if (Array.isArray(current)) {
|
|
@@ -341,7 +365,7 @@ function useForm(initialState, { rules, messages, arrayIdentifiers } = {}) {
|
|
|
341
365
|
traverse(item, `${path}.${index}`);
|
|
342
366
|
}
|
|
343
367
|
});
|
|
344
|
-
|
|
368
|
+
map.set(path, itemMap);
|
|
345
369
|
} else {
|
|
346
370
|
Object.keys(current).forEach((key) => {
|
|
347
371
|
const nextPath = path ? `${path}.${key}` : key;
|
|
@@ -350,106 +374,140 @@ function useForm(initialState, { rules, messages, arrayIdentifiers } = {}) {
|
|
|
350
374
|
}
|
|
351
375
|
};
|
|
352
376
|
traverse(state, "");
|
|
353
|
-
return
|
|
377
|
+
return map;
|
|
354
378
|
}, [state, arrayIdentifiers]);
|
|
355
|
-
const indexMapRef = (0,
|
|
379
|
+
const indexMapRef = (0, import_react2.useRef)(indexMap);
|
|
356
380
|
indexMapRef.current = indexMap;
|
|
357
|
-
const getIndex = (0,
|
|
381
|
+
const getIndex = (0, import_react2.useCallback)((arrayKey, itemId) => {
|
|
358
382
|
return indexMapRef.current.get(arrayKey)?.get(itemId);
|
|
359
383
|
}, []);
|
|
360
|
-
const
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
384
|
+
const ruleCache = (0, import_react2.useRef)(/* @__PURE__ */ new Map());
|
|
385
|
+
(0, import_react2.useMemo)(() => {
|
|
386
|
+
ruleCache.current.clear();
|
|
387
|
+
}, [validationSchema]);
|
|
388
|
+
const getRule = (0, import_react2.useCallback)((path, schema2) => {
|
|
389
|
+
if (ruleCache.current.has(path)) {
|
|
390
|
+
return ruleCache.current.get(path);
|
|
391
|
+
}
|
|
392
|
+
let rule;
|
|
393
|
+
try {
|
|
394
|
+
rule = (0, import_yup2.reach)(schema2, path);
|
|
395
|
+
} catch {
|
|
371
396
|
const genericPath = path.replace(/\.\d+\./g, ".").replace(/\.\d+$/, "");
|
|
372
|
-
|
|
397
|
+
try {
|
|
398
|
+
rule = (0, import_yup2.reach)(schema2, genericPath);
|
|
399
|
+
} catch {
|
|
400
|
+
rule = void 0;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
ruleCache.current.set(path, rule);
|
|
404
|
+
return rule;
|
|
405
|
+
}, []);
|
|
406
|
+
const runValidation = (0, import_react2.useCallback)(
|
|
407
|
+
(ruleDef, value, compositeKey) => {
|
|
408
|
+
if ((0, import_yup2.isSchema)(ruleDef)) {
|
|
409
|
+
try {
|
|
410
|
+
ruleDef.validateSync(value);
|
|
411
|
+
return false;
|
|
412
|
+
} catch (err) {
|
|
413
|
+
const error = {
|
|
414
|
+
isInvalid: true,
|
|
415
|
+
errorMessage: err.message || "Invalid"
|
|
416
|
+
};
|
|
417
|
+
setMetadata((prev) => {
|
|
418
|
+
const newMap = new Map(prev);
|
|
419
|
+
const currentMeta = newMap.get(compositeKey) || {
|
|
420
|
+
isTouched: false,
|
|
421
|
+
isInvalid: false,
|
|
422
|
+
errorMessage: ""
|
|
423
|
+
};
|
|
424
|
+
newMap.set(compositeKey, { ...currentMeta, ...error });
|
|
425
|
+
return newMap;
|
|
426
|
+
});
|
|
427
|
+
return true;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
return false;
|
|
373
431
|
},
|
|
374
|
-
[
|
|
432
|
+
[]
|
|
375
433
|
);
|
|
376
|
-
const validateField = (0,
|
|
377
|
-
(compositeKey, fieldPath, value
|
|
378
|
-
let
|
|
379
|
-
if (
|
|
380
|
-
|
|
381
|
-
if (stripped !== fieldPath) ruleDef = getRule(stripped);
|
|
382
|
-
}
|
|
383
|
-
const rule = typeof ruleDef === "function" ? ruleDef(
|
|
384
|
-
value,
|
|
385
|
-
stateRef.current,
|
|
386
|
-
extraContext?.item,
|
|
387
|
-
extraContext?.index
|
|
388
|
-
) : ruleDef;
|
|
389
|
-
let message = getMessage(fieldPath);
|
|
390
|
-
if (!message && fieldPath !== fieldPath.replace(/\.@\d+/, "")) {
|
|
391
|
-
message = getMessage(fieldPath.replace(/\.@\d+/, ""));
|
|
434
|
+
const validateField = (0, import_react2.useCallback)(
|
|
435
|
+
(compositeKey, fieldPath, value) => {
|
|
436
|
+
let schemaRule = getRule(fieldPath, validationSchema);
|
|
437
|
+
if (schemaRule) {
|
|
438
|
+
if (runValidation(schemaRule, value, compositeKey)) return true;
|
|
392
439
|
}
|
|
393
|
-
|
|
394
|
-
setErrors((prev) => {
|
|
440
|
+
setMetadata((prev) => {
|
|
395
441
|
const newMap = new Map(prev);
|
|
396
|
-
newMap.
|
|
442
|
+
const currentMeta = newMap.get(compositeKey) || {
|
|
443
|
+
isTouched: false,
|
|
444
|
+
isInvalid: false,
|
|
445
|
+
errorMessage: ""
|
|
446
|
+
};
|
|
447
|
+
newMap.set(compositeKey, {
|
|
448
|
+
...currentMeta,
|
|
449
|
+
isInvalid: false,
|
|
450
|
+
errorMessage: ""
|
|
451
|
+
});
|
|
397
452
|
return newMap;
|
|
398
453
|
});
|
|
399
|
-
return
|
|
454
|
+
return false;
|
|
400
455
|
},
|
|
401
|
-
[getRule,
|
|
456
|
+
[getRule, runValidation, validationSchema]
|
|
402
457
|
);
|
|
403
|
-
const validateAll = (0,
|
|
404
|
-
if (!
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
458
|
+
const validateAll = (0, import_react2.useCallback)(() => {
|
|
459
|
+
if (!validationSchema) return false;
|
|
460
|
+
let hasError = false;
|
|
461
|
+
const newMetadata = new Map(metadataRef.current);
|
|
462
|
+
try {
|
|
463
|
+
validationSchema.validateSync(state, { abortEarly: false });
|
|
464
|
+
} catch (err) {
|
|
465
|
+
hasError = true;
|
|
466
|
+
if (err.inner) {
|
|
467
|
+
err.inner.forEach((validationError) => {
|
|
468
|
+
const yupPath = validationError.path;
|
|
469
|
+
const dotPath = yupPath.replace(/\[(\d+)\]/g, ".$1");
|
|
470
|
+
const parts = dotPath.split(".");
|
|
471
|
+
let current = state;
|
|
472
|
+
const compositeParts = [];
|
|
473
|
+
for (let i = 0; i < parts.length; i++) {
|
|
474
|
+
const part = parts[i];
|
|
475
|
+
if (Array.isArray(current)) {
|
|
476
|
+
const index = parseInt(part, 10);
|
|
477
|
+
const item = current[index];
|
|
478
|
+
if (item && typeof item === "object") {
|
|
479
|
+
const genericPath = compositeParts.join(".").replace(/\.\d+/g, "");
|
|
480
|
+
const idKey = arrayIdentifiers?.[genericPath] || "id";
|
|
481
|
+
const id = item[idKey];
|
|
482
|
+
compositeParts.push(String(id !== void 0 ? id : index));
|
|
483
|
+
} else {
|
|
484
|
+
compositeParts.push(part);
|
|
485
|
+
}
|
|
486
|
+
current = item;
|
|
487
|
+
} else {
|
|
488
|
+
compositeParts.push(part);
|
|
489
|
+
current = current?.[part];
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
const compositeKey = compositeParts.join(".");
|
|
493
|
+
const currentMeta = newMetadata.get(compositeKey) || {
|
|
494
|
+
isTouched: false,
|
|
495
|
+
isInvalid: false,
|
|
496
|
+
errorMessage: ""
|
|
497
|
+
};
|
|
498
|
+
newMetadata.set(compositeKey, {
|
|
499
|
+
...currentMeta,
|
|
500
|
+
isTouched: true,
|
|
501
|
+
isInvalid: true,
|
|
502
|
+
errorMessage: validationError.message
|
|
432
503
|
});
|
|
433
|
-
}
|
|
434
|
-
} else {
|
|
435
|
-
const val = getNestedValue(stateRef.current, ruleKey);
|
|
436
|
-
const rule = typeof ruleVal === "function" ? ruleVal(val, stateRef.current) : ruleVal;
|
|
437
|
-
const msg = getMessage(ruleKey);
|
|
438
|
-
const err = performValidations(val, rule, msg);
|
|
439
|
-
nextErrors.set(ruleKey, err);
|
|
440
|
-
if (err.isInvalid) hasInvalid = true;
|
|
504
|
+
});
|
|
441
505
|
}
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
nextErrors.forEach((_, k) => next.set(k, true));
|
|
448
|
-
return next;
|
|
449
|
-
});
|
|
450
|
-
return hasInvalid;
|
|
451
|
-
}, [rules, getMessage, performValidations]);
|
|
452
|
-
const handleFieldChange = (0, import_react.useCallback)(
|
|
506
|
+
}
|
|
507
|
+
setMetadata(newMetadata);
|
|
508
|
+
return hasError;
|
|
509
|
+
}, [validationSchema, state, arrayIdentifiers]);
|
|
510
|
+
const handleFieldChange = (0, import_react2.useCallback)(
|
|
453
511
|
(resolution, newValue) => {
|
|
454
512
|
if (!resolution) return;
|
|
455
513
|
const {
|
|
@@ -462,18 +520,33 @@ function useForm(initialState, { rules, messages, arrayIdentifiers } = {}) {
|
|
|
462
520
|
parentId,
|
|
463
521
|
nestedField
|
|
464
522
|
} = resolution;
|
|
523
|
+
let finalValue = newValue;
|
|
524
|
+
let rule = getRule(fieldPath, validationSchema);
|
|
525
|
+
if (rule && rule.type === "array" && type === "primitiveArray" /* PrimitiveArray */ && rule.innerType) {
|
|
526
|
+
rule = rule.innerType;
|
|
527
|
+
}
|
|
528
|
+
if (rule && rule.type === "string") {
|
|
529
|
+
try {
|
|
530
|
+
finalValue = rule.cast(newValue);
|
|
531
|
+
} catch {
|
|
532
|
+
}
|
|
533
|
+
}
|
|
465
534
|
setState((prev) => {
|
|
466
535
|
if (type === "scalar" /* Scalar */) {
|
|
467
536
|
return handleNestedChange({
|
|
468
537
|
state: prev,
|
|
469
538
|
id: compositeKey,
|
|
470
|
-
value:
|
|
539
|
+
value: finalValue,
|
|
540
|
+
hasNestedValues: compositeKey.includes(".")
|
|
471
541
|
});
|
|
472
542
|
}
|
|
473
543
|
if (type === "primitiveArray" /* PrimitiveArray */) {
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
544
|
+
return handleNestedChange({
|
|
545
|
+
state: prev,
|
|
546
|
+
id: `${arrayKey}.${index}`,
|
|
547
|
+
value: finalValue,
|
|
548
|
+
hasNestedValues: true
|
|
549
|
+
});
|
|
477
550
|
}
|
|
478
551
|
if (type === "objectArray" /* ObjectArray */) {
|
|
479
552
|
return handleArrayItemChange({
|
|
@@ -481,7 +554,7 @@ function useForm(initialState, { rules, messages, arrayIdentifiers } = {}) {
|
|
|
481
554
|
arrayKey,
|
|
482
555
|
index,
|
|
483
556
|
field: resolution.field,
|
|
484
|
-
value:
|
|
557
|
+
value: finalValue
|
|
485
558
|
});
|
|
486
559
|
}
|
|
487
560
|
if (type === "nestedPrimitiveArray" /* NestedPrimitiveArray */) {
|
|
@@ -490,47 +563,46 @@ function useForm(initialState, { rules, messages, arrayIdentifiers } = {}) {
|
|
|
490
563
|
const parentArr = [...prev[parentKey]];
|
|
491
564
|
const pItem = { ...parentArr[pIndex] };
|
|
492
565
|
const nestedArr = [...getNestedValue(pItem, nestedField) || []];
|
|
493
|
-
nestedArr[index] =
|
|
566
|
+
nestedArr[index] = finalValue;
|
|
494
567
|
pItem[nestedField] = nestedArr;
|
|
495
|
-
|
|
496
|
-
parentArr[pIndex] = updatedItem;
|
|
568
|
+
parentArr[pIndex] = pItem;
|
|
497
569
|
return { ...prev, [parentKey]: parentArr };
|
|
498
570
|
}
|
|
499
571
|
return prev;
|
|
500
572
|
});
|
|
501
|
-
|
|
502
|
-
if (type === "objectArray" /* ObjectArray */ || type === "nestedPrimitiveArray" /* NestedPrimitiveArray */) {
|
|
503
|
-
const idx = index;
|
|
504
|
-
const arrKey = arrayKey || parentKey;
|
|
505
|
-
extraContext = {
|
|
506
|
-
index: idx,
|
|
507
|
-
item: stateRef.current[arrKey]?.[idx]
|
|
508
|
-
};
|
|
509
|
-
}
|
|
510
|
-
validateField(compositeKey, fieldPath, newValue, extraContext);
|
|
573
|
+
validateField(compositeKey, fieldPath, finalValue);
|
|
511
574
|
},
|
|
512
|
-
[getIndex, validateField]
|
|
575
|
+
[getIndex, validateField, getRule, validationSchema]
|
|
513
576
|
);
|
|
514
|
-
const createHandlers = (0,
|
|
577
|
+
const createHandlers = (0, import_react2.useCallback)(
|
|
515
578
|
(resolution) => {
|
|
516
579
|
if (!resolution) return {};
|
|
517
580
|
const { compositeKey, fieldPath, value } = resolution;
|
|
518
|
-
const
|
|
519
|
-
const isTouched =
|
|
581
|
+
const meta = metadataRef.current.get(compositeKey);
|
|
582
|
+
const isTouched = meta?.isTouched;
|
|
520
583
|
return {
|
|
521
584
|
id: compositeKey,
|
|
522
|
-
isInvalid: Boolean(isTouched &&
|
|
523
|
-
errorMessage: isTouched ?
|
|
585
|
+
isInvalid: Boolean(isTouched && meta?.isInvalid),
|
|
586
|
+
errorMessage: isTouched ? meta?.errorMessage || "" : "",
|
|
524
587
|
onBlur: () => {
|
|
525
|
-
if (
|
|
588
|
+
if (metadataRef.current.get(compositeKey)?.isTouched) return;
|
|
526
589
|
validateField(compositeKey, fieldPath, value);
|
|
527
|
-
|
|
590
|
+
setMetadata((prev) => {
|
|
591
|
+
const newMap = new Map(prev);
|
|
592
|
+
const current = newMap.get(compositeKey) || {
|
|
593
|
+
isTouched: false,
|
|
594
|
+
isInvalid: false,
|
|
595
|
+
errorMessage: ""
|
|
596
|
+
};
|
|
597
|
+
newMap.set(compositeKey, { ...current, isTouched: true });
|
|
598
|
+
return newMap;
|
|
599
|
+
});
|
|
528
600
|
}
|
|
529
601
|
};
|
|
530
602
|
},
|
|
531
603
|
[validateField]
|
|
532
604
|
);
|
|
533
|
-
const on = (0,
|
|
605
|
+
const on = (0, import_react2.useMemo)(
|
|
534
606
|
() => ({
|
|
535
607
|
input: (...args) => {
|
|
536
608
|
const data = resolveFieldData(
|
|
@@ -584,58 +656,81 @@ function useForm(initialState, { rules, messages, arrayIdentifiers } = {}) {
|
|
|
584
656
|
}),
|
|
585
657
|
[createHandlers, getIndex, handleFieldChange]
|
|
586
658
|
);
|
|
587
|
-
const helpers = (0,
|
|
659
|
+
const helpers = (0, import_react2.useMemo)(
|
|
588
660
|
() => ({
|
|
589
661
|
addItem: (arrayKey, item, index) => {
|
|
590
662
|
setState((prev) => {
|
|
591
|
-
const arr = [...prev[
|
|
663
|
+
const arr = [...getNestedValue(prev, arrayKey) || []];
|
|
592
664
|
if (index === void 0) arr.push(item);
|
|
593
665
|
else arr.splice(index, 0, item);
|
|
594
|
-
return {
|
|
666
|
+
return handleNestedChange({
|
|
667
|
+
state: prev,
|
|
668
|
+
id: arrayKey,
|
|
669
|
+
value: arr,
|
|
670
|
+
hasNestedValues: String(arrayKey).includes(".")
|
|
671
|
+
});
|
|
595
672
|
});
|
|
596
673
|
},
|
|
597
674
|
removeItem: (arrayKey, index) => {
|
|
598
|
-
const currentArr = stateRef.current[
|
|
675
|
+
const currentArr = getNestedValue(stateRef.current, arrayKey) || [];
|
|
599
676
|
const item = currentArr[index];
|
|
600
677
|
const idKey = arrayIdentifiers?.[arrayKey] || "id";
|
|
601
678
|
const itemId = item?.[idKey];
|
|
602
679
|
setState((prev) => {
|
|
603
|
-
const arr = [...prev[
|
|
680
|
+
const arr = [...getNestedValue(prev, arrayKey) || []];
|
|
604
681
|
arr.splice(index, 1);
|
|
605
|
-
return {
|
|
682
|
+
return handleNestedChange({
|
|
683
|
+
state: prev,
|
|
684
|
+
id: arrayKey,
|
|
685
|
+
value: arr,
|
|
686
|
+
hasNestedValues: String(arrayKey).includes(".")
|
|
687
|
+
});
|
|
606
688
|
});
|
|
607
689
|
if (itemId !== void 0) {
|
|
608
690
|
const prefix = `${String(arrayKey)}.${itemId}.`;
|
|
609
|
-
|
|
610
|
-
setErrors((prev) => removeCompositeKeysByPrefix(prev, prefix));
|
|
691
|
+
setMetadata((prev) => removeCompositeKeysByPrefix(prev, prefix));
|
|
611
692
|
}
|
|
612
693
|
},
|
|
613
694
|
removeById: (arrayKey, itemId) => {
|
|
614
695
|
const index = getIndex(arrayKey, itemId);
|
|
615
696
|
if (index !== void 0) {
|
|
616
697
|
setState((prev) => {
|
|
617
|
-
const arr = [...prev[
|
|
698
|
+
const arr = [...getNestedValue(prev, arrayKey) || []];
|
|
618
699
|
arr.splice(index, 1);
|
|
619
|
-
return {
|
|
700
|
+
return handleNestedChange({
|
|
701
|
+
state: prev,
|
|
702
|
+
id: arrayKey,
|
|
703
|
+
value: arr,
|
|
704
|
+
hasNestedValues: String(arrayKey).includes(".")
|
|
705
|
+
});
|
|
620
706
|
});
|
|
621
707
|
const prefix = `${String(arrayKey)}.${itemId}.`;
|
|
622
|
-
|
|
623
|
-
setErrors((prev) => removeCompositeKeysByPrefix(prev, prefix));
|
|
708
|
+
setMetadata((prev) => removeCompositeKeysByPrefix(prev, prefix));
|
|
624
709
|
}
|
|
625
710
|
},
|
|
626
711
|
updateItem: (arrayKey, index, value) => {
|
|
627
712
|
setState((prev) => {
|
|
628
|
-
const arr = [...prev[
|
|
713
|
+
const arr = [...getNestedValue(prev, arrayKey) || []];
|
|
629
714
|
arr[index] = value;
|
|
630
|
-
return {
|
|
715
|
+
return handleNestedChange({
|
|
716
|
+
state: prev,
|
|
717
|
+
id: arrayKey,
|
|
718
|
+
value: arr,
|
|
719
|
+
hasNestedValues: String(arrayKey).includes(".")
|
|
720
|
+
});
|
|
631
721
|
});
|
|
632
722
|
},
|
|
633
723
|
moveItem: (arrayKey, from, to) => {
|
|
634
724
|
setState((prev) => {
|
|
635
|
-
const arr = [...prev[
|
|
725
|
+
const arr = [...getNestedValue(prev, arrayKey) || []];
|
|
636
726
|
const [item] = arr.splice(from, 1);
|
|
637
727
|
arr.splice(to, 0, item);
|
|
638
|
-
return {
|
|
728
|
+
return handleNestedChange({
|
|
729
|
+
state: prev,
|
|
730
|
+
id: arrayKey,
|
|
731
|
+
value: arr,
|
|
732
|
+
hasNestedValues: String(arrayKey).includes(".")
|
|
733
|
+
});
|
|
639
734
|
});
|
|
640
735
|
},
|
|
641
736
|
moveById: (arrayKey, fromId, toId) => {
|
|
@@ -643,26 +738,43 @@ function useForm(initialState, { rules, messages, arrayIdentifiers } = {}) {
|
|
|
643
738
|
const toIndex = getIndex(arrayKey, toId);
|
|
644
739
|
if (fromIndex !== void 0 && toIndex !== void 0) {
|
|
645
740
|
setState((prev) => {
|
|
646
|
-
const arr = [...prev[
|
|
741
|
+
const arr = [...getNestedValue(prev, arrayKey) || []];
|
|
647
742
|
const [item] = arr.splice(fromIndex, 1);
|
|
648
743
|
arr.splice(toIndex, 0, item);
|
|
649
|
-
return {
|
|
744
|
+
return handleNestedChange({
|
|
745
|
+
state: prev,
|
|
746
|
+
id: arrayKey,
|
|
747
|
+
value: arr,
|
|
748
|
+
hasNestedValues: String(arrayKey).includes(".")
|
|
749
|
+
});
|
|
650
750
|
});
|
|
651
751
|
}
|
|
652
752
|
},
|
|
653
753
|
getItem: (arrayKey, itemId) => {
|
|
654
754
|
const index = getIndex(arrayKey, itemId);
|
|
655
755
|
if (index === void 0) return void 0;
|
|
656
|
-
return stateRef.current
|
|
756
|
+
return getNestedValue(stateRef.current, arrayKey)[index];
|
|
657
757
|
}
|
|
658
758
|
}),
|
|
659
759
|
[getIndex, arrayIdentifiers]
|
|
660
760
|
);
|
|
661
|
-
const onBlur = (
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
761
|
+
const onBlur = (0, import_react2.useCallback)(
|
|
762
|
+
(id) => {
|
|
763
|
+
validateField(String(id), String(id), stateRef.current[id]);
|
|
764
|
+
setMetadata((prev) => {
|
|
765
|
+
const newMap = new Map(prev);
|
|
766
|
+
const current = newMap.get(String(id)) || {
|
|
767
|
+
isTouched: false,
|
|
768
|
+
isInvalid: false,
|
|
769
|
+
errorMessage: ""
|
|
770
|
+
};
|
|
771
|
+
newMap.set(String(id), { ...current, isTouched: true });
|
|
772
|
+
return newMap;
|
|
773
|
+
});
|
|
774
|
+
},
|
|
775
|
+
[validateField]
|
|
776
|
+
);
|
|
777
|
+
const polymorphicOnValueChange = (0, import_react2.useCallback)(
|
|
666
778
|
(...args) => {
|
|
667
779
|
const value = args[args.length - 1];
|
|
668
780
|
const idArgs = args.slice(0, args.length - 1);
|
|
@@ -676,7 +788,7 @@ function useForm(initialState, { rules, messages, arrayIdentifiers } = {}) {
|
|
|
676
788
|
},
|
|
677
789
|
[getIndex, handleFieldChange]
|
|
678
790
|
);
|
|
679
|
-
const polymorphicOnSelectionChange = (0,
|
|
791
|
+
const polymorphicOnSelectionChange = (0, import_react2.useCallback)(
|
|
680
792
|
(id, val) => {
|
|
681
793
|
const fixed = typeof val === "string" || val === null ? val : Array.from(val);
|
|
682
794
|
setState((prev) => handleNestedChange({ state: prev, id, value: fixed }));
|
|
@@ -684,22 +796,26 @@ function useForm(initialState, { rules, messages, arrayIdentifiers } = {}) {
|
|
|
684
796
|
},
|
|
685
797
|
[validateField]
|
|
686
798
|
);
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
799
|
+
const onFormSubmit = (0, import_react2.useCallback)(
|
|
800
|
+
(fn) => (e) => {
|
|
801
|
+
e.preventDefault();
|
|
802
|
+
if (validateAll()) return;
|
|
803
|
+
fn(stateRef.current, e);
|
|
804
|
+
},
|
|
805
|
+
[validateAll]
|
|
806
|
+
);
|
|
807
|
+
const onFormSubmitPropRef = (0, import_react2.useRef)(onFormSubmitProp);
|
|
808
|
+
onFormSubmitPropRef.current = onFormSubmitProp;
|
|
809
|
+
const resetOnSubmitRef = (0, import_react2.useRef)(resetOnSubmit);
|
|
810
|
+
resetOnSubmitRef.current = resetOnSubmit;
|
|
811
|
+
const keepValuesPropRef = (0, import_react2.useRef)(keepValuesProp);
|
|
812
|
+
keepValuesPropRef.current = keepValuesProp;
|
|
813
|
+
const handleReset = (0, import_react2.useCallback)(
|
|
814
|
+
(options) => {
|
|
815
|
+
const { keepValues } = options || {};
|
|
816
|
+
if (keepValues && keepValues.length > 0) {
|
|
701
817
|
const nextState = { ...initialState };
|
|
702
|
-
|
|
818
|
+
keepValues.forEach((k) => {
|
|
703
819
|
if (stateRef.current[k] !== void 0)
|
|
704
820
|
nextState[k] = stateRef.current[k];
|
|
705
821
|
});
|
|
@@ -707,25 +823,59 @@ function useForm(initialState, { rules, messages, arrayIdentifiers } = {}) {
|
|
|
707
823
|
} else {
|
|
708
824
|
setState(initialState);
|
|
709
825
|
}
|
|
710
|
-
|
|
711
|
-
setErrors(/* @__PURE__ */ new Map());
|
|
826
|
+
setMetadata(/* @__PURE__ */ new Map());
|
|
712
827
|
},
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
828
|
+
[initialState]
|
|
829
|
+
);
|
|
830
|
+
const validateAllRef = (0, import_react2.useRef)(validateAll);
|
|
831
|
+
validateAllRef.current = validateAll;
|
|
832
|
+
const ControlledForm = (0, import_react2.useMemo)(() => {
|
|
833
|
+
return (props) => {
|
|
834
|
+
const { onSubmit, ...rest } = props;
|
|
835
|
+
const handleSubmit = (e) => {
|
|
836
|
+
e.preventDefault();
|
|
837
|
+
if (validateAllRef.current()) {
|
|
838
|
+
return;
|
|
839
|
+
}
|
|
840
|
+
onFormSubmitPropRef.current?.(stateRef.current, e);
|
|
841
|
+
if (resetOnSubmitRef.current) {
|
|
842
|
+
handleReset({ keepValues: keepValuesPropRef.current });
|
|
843
|
+
}
|
|
844
|
+
onSubmit?.(stateRef.current, e);
|
|
845
|
+
};
|
|
846
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react3.Form, { onSubmit: handleSubmit, ...rest });
|
|
847
|
+
};
|
|
848
|
+
}, []);
|
|
849
|
+
return (0, import_react2.useMemo)(
|
|
850
|
+
() => ({
|
|
851
|
+
state,
|
|
852
|
+
setState,
|
|
853
|
+
metadata,
|
|
854
|
+
on,
|
|
855
|
+
helpers,
|
|
856
|
+
onFieldChange: polymorphicOnValueChange,
|
|
857
|
+
onFieldBlur: onBlur,
|
|
858
|
+
onSelectionChange: polymorphicOnSelectionChange,
|
|
859
|
+
isDirty: Array.from(metadata.values()).some((m) => m.isTouched),
|
|
860
|
+
onFormReset: handleReset,
|
|
861
|
+
onFormSubmit,
|
|
862
|
+
ControlledForm
|
|
863
|
+
}),
|
|
864
|
+
[
|
|
865
|
+
state,
|
|
866
|
+
setState,
|
|
867
|
+
metadata,
|
|
868
|
+
on,
|
|
869
|
+
helpers,
|
|
870
|
+
onBlur,
|
|
871
|
+
polymorphicOnValueChange,
|
|
872
|
+
polymorphicOnSelectionChange,
|
|
873
|
+
validateAll,
|
|
874
|
+
onFormSubmit,
|
|
875
|
+
ControlledForm,
|
|
876
|
+
initialState
|
|
877
|
+
]
|
|
878
|
+
);
|
|
729
879
|
}
|
|
730
880
|
// Annotate the CommonJS export names for ESM import in node:
|
|
731
881
|
0 && (module.exports = {
|