@stackcraftmx/calcita 0.51.0 → 0.53.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 +73 -6
- package/cli/calcita.js +4 -2
- package/cli/checkTexts.js +66 -9
- package/dist/appShell/BarActionButton.js.map +1 -1
- package/dist/datePickers/DateInput.js +5 -3
- package/dist/datePickers/DateInput.js.map +1 -1
- package/dist/datePickers/DateTimeInput.js +6 -4
- package/dist/datePickers/DateTimeInput.js.map +1 -1
- package/dist/datePickers/FormDateField.js +1 -1
- package/dist/datePickers/FormDateField.js.map +1 -1
- package/dist/datePickers/FormDateTimeField.js +1 -1
- package/dist/datePickers/FormDateTimeField.js.map +1 -1
- package/dist/datePickers/FormMonthField.js +1 -1
- package/dist/datePickers/FormMonthField.js.map +1 -1
- package/dist/datePickers/FormTimeField.js +1 -1
- package/dist/datePickers/FormTimeField.js.map +1 -1
- package/dist/datePickers/MonthInput.js +5 -3
- package/dist/datePickers/MonthInput.js.map +1 -1
- package/dist/datePickers/PickerFrame.js +2 -2
- package/dist/datePickers/PickerFrame.js.map +1 -1
- package/dist/datePickers/TimeInput.js +6 -4
- package/dist/datePickers/TimeInput.js.map +1 -1
- package/dist/feedback/Toaster.js +11 -2
- package/dist/feedback/Toaster.js.map +1 -1
- package/dist/forms/CalcitaFormik.js +11 -0
- package/dist/forms/CalcitaFormik.js.map +1 -0
- package/dist/forms/FormAttachmentsField.js +1 -1
- package/dist/forms/FormAttachmentsField.js.map +1 -1
- package/dist/forms/FormCatalogField.js +1 -1
- package/dist/forms/FormCatalogField.js.map +1 -1
- package/dist/forms/FormCheckboxGroupField.js +1 -1
- package/dist/forms/FormCheckboxGroupField.js.map +1 -1
- package/dist/forms/FormColorField.js +1 -1
- package/dist/forms/FormColorField.js.map +1 -1
- package/dist/forms/FormFileField.js +1 -1
- package/dist/forms/FormFileField.js.map +1 -1
- package/dist/forms/FormFileUploadField.js +1 -1
- package/dist/forms/FormFileUploadField.js.map +1 -1
- package/dist/forms/FormImageField.js +1 -1
- package/dist/forms/FormImageField.js.map +1 -1
- package/dist/forms/FormMaskedField.js +1 -1
- package/dist/forms/FormMaskedField.js.map +1 -1
- package/dist/forms/FormNumberField.js +1 -1
- package/dist/forms/FormNumberField.js.map +1 -1
- package/dist/forms/FormSchemaProvider.js +17 -0
- package/dist/forms/FormSchemaProvider.js.map +1 -0
- package/dist/forms/FormSelectField.js +1 -1
- package/dist/forms/FormSelectField.js.map +1 -1
- package/dist/forms/FormTextField.js +1 -1
- package/dist/forms/FormTextField.js.map +1 -1
- package/dist/forms/FormTransferListField.js +1 -1
- package/dist/forms/FormTransferListField.js.map +1 -1
- package/dist/forms/FormWizard.js +23 -6
- package/dist/forms/FormWizard.js.map +1 -1
- package/dist/forms/schemaRequired.js +33 -0
- package/dist/forms/schemaRequired.js.map +1 -0
- package/dist/forms/useFormikField.js +18 -5
- package/dist/forms/useFormikField.js.map +1 -1
- package/dist/forms.js +52 -46
- package/dist/forms.js.map +1 -1
- package/dist/hookForm/FormAttachmentsField.js +1 -1
- package/dist/hookForm/FormAttachmentsField.js.map +1 -1
- package/dist/hookForm/FormCatalogField.js +1 -1
- package/dist/hookForm/FormCatalogField.js.map +1 -1
- package/dist/hookForm/FormCheckboxGroupField.js +1 -1
- package/dist/hookForm/FormCheckboxGroupField.js.map +1 -1
- package/dist/hookForm/FormColorField.js +1 -1
- package/dist/hookForm/FormColorField.js.map +1 -1
- package/dist/hookForm/FormFileField.js +1 -1
- package/dist/hookForm/FormFileField.js.map +1 -1
- package/dist/hookForm/FormFileUploadField.js +1 -1
- package/dist/hookForm/FormFileUploadField.js.map +1 -1
- package/dist/hookForm/FormImageField.js +1 -1
- package/dist/hookForm/FormImageField.js.map +1 -1
- package/dist/hookForm/FormMaskedField.js +1 -1
- package/dist/hookForm/FormMaskedField.js.map +1 -1
- package/dist/hookForm/FormNumberField.js +1 -1
- package/dist/hookForm/FormNumberField.js.map +1 -1
- package/dist/hookForm/FormSelectField.js +1 -1
- package/dist/hookForm/FormSelectField.js.map +1 -1
- package/dist/hookForm/FormTextField.js +1 -1
- package/dist/hookForm/FormTextField.js.map +1 -1
- package/dist/hookForm/FormTransferListField.js +1 -1
- package/dist/hookForm/FormTransferListField.js.map +1 -1
- package/dist/hookForm/FormWizard.js +21 -5
- package/dist/hookForm/FormWizard.js.map +1 -1
- package/dist/hookForm/useHookFormField.js +9 -3
- package/dist/hookForm/useHookFormField.js.map +1 -1
- package/dist/index.js +12 -3
- package/dist/index.js.map +1 -1
- package/dist/inputs/CatalogInput.js +3 -2
- package/dist/inputs/CatalogInput.js.map +1 -1
- package/dist/inputs/CheckboxGroupInput.js +2 -1
- package/dist/inputs/CheckboxGroupInput.js.map +1 -1
- package/dist/inputs/ColorInput.js +3 -1
- package/dist/inputs/ColorInput.js.map +1 -1
- package/dist/inputs/FieldFrame.js +18 -3
- package/dist/inputs/FieldFrame.js.map +1 -1
- package/dist/inputs/FormSection.js +42 -11
- package/dist/inputs/FormSection.js.map +1 -1
- package/dist/inputs/NumberInput.js +3 -1
- package/dist/inputs/NumberInput.js.map +1 -1
- package/dist/inputs/SelectInput.js +3 -1
- package/dist/inputs/SelectInput.js.map +1 -1
- package/dist/inputs/TextInput.js +1 -1
- package/dist/inputs/TextInput.js.map +1 -1
- package/dist/inputs/TransferListInput.js +2 -1
- package/dist/inputs/TransferListInput.js.map +1 -1
- package/dist/inputs/WizardLayout.js +51 -17
- package/dist/inputs/WizardLayout.js.map +1 -1
- package/dist/inputs/formLayoutContext.js +7 -2
- package/dist/inputs/formLayoutContext.js.map +1 -1
- package/dist/inputs/requiredMark.js +17 -0
- package/dist/inputs/requiredMark.js.map +1 -0
- package/dist/inputs/useWizardSteps.js +36 -0
- package/dist/inputs/useWizardSteps.js.map +1 -0
- package/dist/inputs/wizardSteps.js +32 -0
- package/dist/inputs/wizardSteps.js.map +1 -0
- package/dist/locales/en.js +1 -0
- package/dist/locales/en.js.map +1 -1
- package/dist/locales/es.js +1 -0
- package/dist/locales/es.js.map +1 -1
- package/dist/richText/FormRichTextField.js +1 -1
- package/dist/richText/FormRichTextField.js.map +1 -1
- package/dist/richText/RichTextEditor.js +4 -3
- package/dist/richText/RichTextEditor.js.map +1 -1
- package/dist/toolkit/ToolkitProvider.js +3 -0
- package/dist/toolkit/ToolkitProvider.js.map +1 -1
- package/dist/toolkit/toolkitContext.js.map +1 -1
- package/dist/types/appShell/BarActionButton.d.ts +1 -0
- package/dist/types/datePickers/DateInput.d.ts +2 -0
- package/dist/types/datePickers/DateTimeInput.d.ts +2 -0
- package/dist/types/datePickers/FormDateField.d.ts +3 -3
- package/dist/types/datePickers/FormDateTimeField.d.ts +3 -3
- package/dist/types/datePickers/FormMonthField.d.ts +3 -3
- package/dist/types/datePickers/FormTimeField.d.ts +3 -3
- package/dist/types/datePickers/MonthInput.d.ts +2 -0
- package/dist/types/datePickers/PickerFrame.d.ts +3 -1
- package/dist/types/datePickers/TimeInput.d.ts +2 -0
- package/dist/types/feedback/Toaster.d.ts +15 -1
- package/dist/types/feedback/index.d.ts +1 -1
- package/dist/types/forms/CalcitaFormik.d.ts +6 -0
- package/dist/types/forms/FormAttachmentsField.d.ts +3 -3
- package/dist/types/forms/FormCatalogField.d.ts +2 -2
- package/dist/types/forms/FormCheckboxGroupField.d.ts +3 -3
- package/dist/types/forms/FormColorField.d.ts +2 -2
- package/dist/types/forms/FormFileField.d.ts +3 -3
- package/dist/types/forms/FormFileUploadField.d.ts +3 -3
- package/dist/types/forms/FormImageField.d.ts +3 -3
- package/dist/types/forms/FormMaskedField.d.ts +2 -2
- package/dist/types/forms/FormNumberField.d.ts +2 -2
- package/dist/types/forms/FormSchemaProvider.d.ts +13 -0
- package/dist/types/forms/FormSelectField.d.ts +2 -2
- package/dist/types/forms/FormTextField.d.ts +2 -2
- package/dist/types/forms/FormTransferListField.d.ts +3 -3
- package/dist/types/forms/FormWizard.d.ts +14 -1
- package/dist/types/forms/index.d.ts +1 -0
- package/dist/types/forms/schemaRequired.d.ts +14 -0
- package/dist/types/forms/useFormikField.d.ts +10 -4
- package/dist/types/forms.d.ts +4 -2
- package/dist/types/hookForm/FormAttachmentsField.d.ts +3 -3
- package/dist/types/hookForm/FormCatalogField.d.ts +3 -3
- package/dist/types/hookForm/FormCheckboxGroupField.d.ts +3 -3
- package/dist/types/hookForm/FormColorField.d.ts +3 -3
- package/dist/types/hookForm/FormFileField.d.ts +3 -3
- package/dist/types/hookForm/FormFileUploadField.d.ts +3 -3
- package/dist/types/hookForm/FormImageField.d.ts +3 -3
- package/dist/types/hookForm/FormMaskedField.d.ts +3 -3
- package/dist/types/hookForm/FormNumberField.d.ts +3 -3
- package/dist/types/hookForm/FormSelectField.d.ts +3 -3
- package/dist/types/hookForm/FormTextField.d.ts +3 -3
- package/dist/types/hookForm/FormTransferListField.d.ts +3 -3
- package/dist/types/hookForm/FormWizard.d.ts +14 -1
- package/dist/types/hookForm/useHookFormField.d.ts +8 -4
- package/dist/types/index.d.ts +4 -3
- package/dist/types/inputs/CatalogInput.d.ts +1 -0
- package/dist/types/inputs/CheckboxGroupInput.d.ts +1 -0
- package/dist/types/inputs/ColorInput.d.ts +1 -0
- package/dist/types/inputs/FieldFrame.d.ts +1 -0
- package/dist/types/inputs/FormSection.d.ts +13 -0
- package/dist/types/inputs/NumberInput.d.ts +1 -0
- package/dist/types/inputs/SelectInput.d.ts +1 -0
- package/dist/types/inputs/TextInput.d.ts +1 -1
- package/dist/types/inputs/TransferListInput.d.ts +1 -0
- package/dist/types/inputs/WizardLayout.d.ts +6 -2
- package/dist/types/inputs/formLayoutContext.d.ts +8 -1
- package/dist/types/inputs/requiredMark.d.ts +9 -0
- package/dist/types/inputs/useWizardSteps.d.ts +23 -0
- package/dist/types/inputs/wizardSteps.d.ts +65 -0
- package/dist/types/locales/en.d.ts +1 -0
- package/dist/types/locales/es.d.ts +1 -0
- package/dist/types/richText/FormRichTextField.d.ts +3 -3
- package/dist/types/richText/RichTextEditor.d.ts +1 -0
- package/dist/types/toolkit/ToolkitProvider.d.ts +5 -1
- package/dist/types/toolkit/toolkitContext.d.ts +2 -1
- package/dist/types/ui/cards/RecordCard.d.ts +12 -0
- package/dist/types/ui/index.d.ts +1 -1
- package/dist/types/ui/navigation/BackButton.d.ts +1 -0
- package/dist/types/upload/AttachmentsInput.d.ts +2 -0
- package/dist/types/upload/FileInput.d.ts +1 -0
- package/dist/types/upload/FileUploadInput.d.ts +1 -0
- package/dist/types/upload/ImageInput.d.ts +1 -0
- package/dist/ui/cards/RecordCard.js +6 -2
- package/dist/ui/cards/RecordCard.js.map +1 -1
- package/dist/ui/navigation/BackButton.js.map +1 -1
- package/dist/upload/AttachmentsInput.js +2 -1
- package/dist/upload/AttachmentsInput.js.map +1 -1
- package/dist/upload/FileInput.js +2 -1
- package/dist/upload/FileInput.js.map +1 -1
- package/dist/upload/FileUploadInput.js +2 -1
- package/dist/upload/FileUploadInput.js.map +1 -1
- package/dist/upload/ImageInput.js +2 -1
- package/dist/upload/ImageInput.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
function fieldPathOf(name) {
|
|
2
|
+
return name.replace(/\[(\d+)]/g, ".$1").split(".").filter(Boolean);
|
|
3
|
+
}
|
|
4
|
+
function describesRequired(description) {
|
|
5
|
+
if (description.optional === false) {
|
|
6
|
+
return true;
|
|
7
|
+
}
|
|
8
|
+
return description.type === "array" && (description.tests ?? []).some((test) => test.name === "min" && Number(test.params?.min) >= 1);
|
|
9
|
+
}
|
|
10
|
+
function isRequiredInSchema(schema, name, values) {
|
|
11
|
+
let current = typeof schema === "function" ? schema() : schema;
|
|
12
|
+
if (!current || typeof current.describe !== "function") {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
let value = values;
|
|
16
|
+
let parent;
|
|
17
|
+
for (const part of fieldPathOf(name)) {
|
|
18
|
+
const resolved = typeof current.resolve === "function" ? current.resolve({ value, parent }) : current;
|
|
19
|
+
const next = resolved.fields ? resolved.fields[part] : resolved.innerType;
|
|
20
|
+
if (!next) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
current = next;
|
|
24
|
+
parent = value;
|
|
25
|
+
value = value?.[part];
|
|
26
|
+
}
|
|
27
|
+
return describesRequired(current.describe({ value, parent }));
|
|
28
|
+
}
|
|
29
|
+
export {
|
|
30
|
+
fieldPathOf,
|
|
31
|
+
isRequiredInSchema
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=schemaRequired.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemaRequired.js","sources":["../../src/forms/schemaRequired.js"],"sourcesContent":["// Si el esquema de yup del formulario pide un campo: lo lee el campo de formik para ponerle su asterisco cuando el proyecto\n// lo prende (ToolkitProvider requiredFromSchema). Así el esquema manda y la pantalla no repite a mano cuáles son\n// obligatorios (un paso de 33 campos tenía 23).\n//\n// Cuenta como obligatorio lo que yup describe como no opcional: .required() y .defined(); y una lista con .min(1) o más,\n// porque pide al menos uno. Las condiciones (.when) se resuelven con los valores de ese momento: un RFC que solo se pide a\n// una empresa lleva su asterisco solo cuando se elige empresa.\n//\n// Sin importar yup: camina el esquema por lo que todos los de yup traen (fields de un objeto, innerType de una lista,\n// resolve y describe). Así /date-pickers y /rich-text no le piden yup al proyecto que no lo usa.\n//\n// Funciones puras, sin React.\n\n/**\n * Las partes de un nombre de campo de formik: 'contacts.2.email' y 'contacts[2].email' dan ['contacts', '2', 'email'].\n *\n * @param {string} name\n * @returns {string[]}\n */\nexport function fieldPathOf(name) {\n return name.replace(/\\[(\\d+)]/g, '.$1').split('.').filter(Boolean);\n}\n\n/**\n * @param {object} description lo que da describe() de un esquema de yup\n * @returns {boolean}\n */\nfunction describesRequired(description) {\n if (description.optional === false) {\n return true;\n }\n // una lista con .min(1) pide al menos uno aunque yup la llame opcional\n return description.type === 'array' && (description.tests ?? []).some((test) => test.name === 'min' && Number(test.params?.min) >= 1);\n}\n\n/**\n * @param {unknown} schema el validationSchema del formulario (un esquema de yup o una función que lo da, como en formik)\n * @param {string} name el campo, con la forma de formik ('contacts.2.email')\n * @param {object} [values] los valores del formulario, para las condiciones (.when)\n * @returns {boolean} false si no hay esquema, si no es de yup o si el campo no está en él\n */\nexport function isRequiredInSchema(schema, name, values) {\n let current = typeof schema === 'function' ? schema() : schema;\n if (!current || typeof current.describe !== 'function') {\n return false;\n }\n let value = values;\n let parent;\n for (const part of fieldPathOf(name)) {\n // con sus condiciones ya resueltas: un campo puede existir o pedirse según otro\n const resolved = typeof current.resolve === 'function' ? current.resolve({value, parent}) : current;\n const next = resolved.fields ? resolved.fields[part] : resolved.innerType;\n if (!next) {\n return false;\n }\n current = next;\n parent = value;\n value = value?.[part];\n }\n return describesRequired(current.describe({value, parent}));\n}\n"],"names":[],"mappings":"AAmBO,SAAS,YAAY,MAAM;AAC9B,SAAO,KAAK,QAAQ,aAAa,KAAK,EAAE,MAAM,GAAG,EAAE,OAAO,OAAO;AACrE;AAMA,SAAS,kBAAkB,aAAa;AACpC,MAAI,YAAY,aAAa,OAAO;AAChC,WAAO;AAAA,EACX;AAEA,SAAO,YAAY,SAAS,YAAY,YAAY,SAAS,CAAA,GAAI,KAAK,CAAC,SAAS,KAAK,SAAS,SAAS,OAAO,KAAK,QAAQ,GAAG,KAAK,CAAC;AACxI;AAQO,SAAS,mBAAmB,QAAQ,MAAM,QAAQ;AACrD,MAAI,UAAU,OAAO,WAAW,aAAa,OAAM,IAAK;AACxD,MAAI,CAAC,WAAW,OAAO,QAAQ,aAAa,YAAY;AACpD,WAAO;AAAA,EACX;AACA,MAAI,QAAQ;AACZ,MAAI;AACJ,aAAW,QAAQ,YAAY,IAAI,GAAG;AAElC,UAAM,WAAW,OAAO,QAAQ,YAAY,aAAa,QAAQ,QAAQ,EAAC,OAAO,OAAM,CAAC,IAAI;AAC5F,UAAM,OAAO,SAAS,SAAS,SAAS,OAAO,IAAI,IAAI,SAAS;AAChE,QAAI,CAAC,MAAM;AACP,aAAO;AAAA,IACX;AACA,cAAU;AACV,aAAS;AACT,YAAQ,QAAQ,IAAI;AAAA,EACxB;AACA,SAAO,kBAAkB,QAAQ,SAAS,EAAC,OAAO,OAAM,CAAC,CAAC;AAC9D;"}
|
|
@@ -1,13 +1,26 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { useField } from "formik";
|
|
3
|
-
|
|
2
|
+
import { useField, useFormikContext } from "formik";
|
|
3
|
+
import { useFormSchema } from "./FormSchemaProvider.js";
|
|
4
|
+
import { isRequiredInSchema } from "./schemaRequired.js";
|
|
5
|
+
import { useToolkitSettings } from "../toolkit/toolkitContext.js";
|
|
6
|
+
function useFormikField(name, screen = {}) {
|
|
4
7
|
const [field, meta, helpers] = useField(name);
|
|
8
|
+
const { values } = useFormikContext();
|
|
9
|
+
const schema = useFormSchema();
|
|
10
|
+
const { requiredFromSchema } = useToolkitSettings();
|
|
5
11
|
return {
|
|
6
12
|
name,
|
|
7
13
|
value: field.value,
|
|
8
|
-
onChange: (value) =>
|
|
9
|
-
|
|
10
|
-
|
|
14
|
+
onChange: (value, ...rest) => {
|
|
15
|
+
helpers.setValue(value);
|
|
16
|
+
screen.onChange?.(value, ...rest);
|
|
17
|
+
},
|
|
18
|
+
onBlur: (...args) => {
|
|
19
|
+
helpers.setTouched(true);
|
|
20
|
+
screen.onBlur?.(...args);
|
|
21
|
+
},
|
|
22
|
+
error: meta.touched ? meta.error : void 0,
|
|
23
|
+
required: screen.required ?? (requiredFromSchema === true && isRequiredInSchema(schema, name, values))
|
|
11
24
|
};
|
|
12
25
|
}
|
|
13
26
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFormikField.js","sources":["../../src/forms/useFormikField.js"],"sourcesContent":["// La conexión de un campo suelto (inputs/) con formik: lo que la vista necesita, sacado del campo de formik.\n//\n// Una
|
|
1
|
+
{"version":3,"file":"useFormikField.js","sources":["../../src/forms/useFormikField.js"],"sourcesContent":["// La conexión de un campo suelto (inputs/) con formik: lo que la vista necesita, sacado del campo de formik.\n//\n// Una regla vive aquí: el error se enseña cuando el campo ya se tocó (o ya se intentó enviar, que formik marca como\n// tocados todos). Marcar en rojo lo que nadie ha llenado regaña a alguien por no adivinar.\n//\n// Lo que la pantalla le pase al campo en onChange y onBlur también corre, después del de formik y con el valor nuevo. OJO:\n// antes el de formik iba después y lo pisaba sin avisar (la pantalla tenía que observar el valor para enterarse).\n//\n// Y lo obligatorio: lo que diga la pantalla con required; si no dice nada y el proyecto lo prendió\n// (ToolkitProvider requiredFromSchema), lo que pida el esquema de yup del formulario (schemaRequired.js). El esquema llega\n// por FormSchemaProvider (el Formik de Calcita lo pone solo): formik no lo comparte con sus campos.\n//\n// Hook genérico del paquete: function (regla de la casa).\nimport {useField, useFormikContext} from 'formik';\n\nimport {useFormSchema} from '@/forms/FormSchemaProvider.jsx';\nimport {isRequiredInSchema} from '@/forms/schemaRequired.js';\nimport {useToolkitSettings} from '@/toolkit/toolkitContext.js';\n\n/**\n * @param {string} name el campo del formulario\n * @param {{required?: boolean, onChange?: Function, onBlur?: Function}} [screen] lo que la pantalla le dijo al campo\n * @returns {{name: string, value: unknown, onChange: (value: unknown, ...rest: unknown[]) => void, onBlur: (...args: unknown[]) => void, error: unknown, required: boolean}}\n */\nexport function useFormikField(name, screen = {}) {\n const [field, meta, helpers] = useField(name);\n const {values} = useFormikContext();\n const schema = useFormSchema();\n const {requiredFromSchema} = useToolkitSettings();\n\n return {\n name,\n value: field.value,\n onChange: (value, ...rest) => {\n helpers.setValue(value);\n screen.onChange?.(value, ...rest);\n },\n onBlur: (...args) => {\n helpers.setTouched(true);\n screen.onBlur?.(...args);\n },\n error: meta.touched ? meta.error : undefined,\n required: screen.required ?? (requiredFromSchema === true && isRequiredInSchema(schema, name, values)),\n };\n}\n"],"names":[],"mappings":";;;;;AAwBO,SAAS,eAAe,MAAM,SAAS,IAAI;AAC9C,QAAM,CAAC,OAAO,MAAM,OAAO,IAAI,SAAS,IAAI;AAC5C,QAAM,EAAC,OAAM,IAAI,iBAAgB;AACjC,QAAM,SAAS,cAAa;AAC5B,QAAM,EAAC,mBAAkB,IAAI,mBAAkB;AAE/C,SAAO;AAAA,IACH;AAAA,IACA,OAAO,MAAM;AAAA,IACb,UAAU,CAAC,UAAU,SAAS;AAC1B,cAAQ,SAAS,KAAK;AACtB,aAAO,WAAW,OAAO,GAAG,IAAI;AAAA,IACpC;AAAA,IACA,QAAQ,IAAI,SAAS;AACjB,cAAQ,WAAW,IAAI;AACvB,aAAO,SAAS,GAAG,IAAI;AAAA,IAC3B;AAAA,IACA,OAAO,KAAK,UAAU,KAAK,QAAQ;AAAA,IACnC,UAAU,OAAO,aAAa,uBAAuB,QAAQ,mBAAmB,QAAQ,MAAM,MAAM;AAAA,EAC5G;AACA;"}
|
package/dist/forms.js
CHANGED
|
@@ -1,69 +1,74 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { FieldArray, Form,
|
|
3
|
-
import { default as default2 } from "./forms/
|
|
4
|
-
import {
|
|
5
|
-
import { default as
|
|
6
|
-
import { default as
|
|
7
|
-
import { default as
|
|
8
|
-
import { default as
|
|
9
|
-
import { default as
|
|
10
|
-
import { default as
|
|
11
|
-
import { default as
|
|
12
|
-
import { default as
|
|
13
|
-
import { default as
|
|
14
|
-
import { default as
|
|
2
|
+
import { FieldArray, Form, useField, useFormikContext } from "formik";
|
|
3
|
+
import { default as default2 } from "./forms/CalcitaFormik.js";
|
|
4
|
+
import { FormSchemaProvider, useFormSchema } from "./forms/FormSchemaProvider.js";
|
|
5
|
+
import { default as default3 } from "./forms/FormAttachmentsField.js";
|
|
6
|
+
import { default as default4 } from "./forms/FormCatalogField.js";
|
|
7
|
+
import { default as default5 } from "./forms/FormCheckboxGroupField.js";
|
|
8
|
+
import { default as default6 } from "./forms/FormColorField.js";
|
|
9
|
+
import { default as default7 } from "./forms/FormFileField.js";
|
|
10
|
+
import { default as default8 } from "./forms/FormFileUploadField.js";
|
|
11
|
+
import { default as default9 } from "./forms/FormImageField.js";
|
|
12
|
+
import { default as default10 } from "./forms/FormMaskedField.js";
|
|
13
|
+
import { default as default11 } from "./forms/FormNumberField.js";
|
|
14
|
+
import { default as default12 } from "./forms/FormProblemAlert.js";
|
|
15
|
+
import { default as default13 } from "./forms/FormRepeatingFields.js";
|
|
16
|
+
import { default as default14 } from "./forms/FormTransferListField.js";
|
|
15
17
|
import { listTotalAtMostRule, listTotalOf, orderedInListRule, uniqueInListRule } from "./forms/listRules.js";
|
|
16
18
|
import { percentRule, sameAsFieldRule } from "./forms/fieldRules.js";
|
|
17
|
-
import { default as
|
|
18
|
-
import { default as
|
|
19
|
-
import { default as
|
|
20
|
-
import { default as
|
|
21
|
-
import { default as
|
|
22
|
-
import { default as
|
|
23
|
-
import { default as
|
|
24
|
-
import { SECOND_STEP_METHOD, default as
|
|
25
|
-
import { default as
|
|
19
|
+
import { default as default15 } from "./forms/FormSelectField.js";
|
|
20
|
+
import { default as default16 } from "./forms/FormServerProblem.js";
|
|
21
|
+
import { default as default17 } from "./forms/FormTextField.js";
|
|
22
|
+
import { default as default18 } from "./forms/FormWizard.js";
|
|
23
|
+
import { default as default19 } from "./forms/auth/ChangePasswordForm.js";
|
|
24
|
+
import { default as default20 } from "./forms/auth/ForgotPasswordForm.js";
|
|
25
|
+
import { default as default21 } from "./forms/auth/SignInForm.js";
|
|
26
|
+
import { SECOND_STEP_METHOD, default as default22 } from "./forms/security/SecondStepForm.js";
|
|
27
|
+
import { default as default23 } from "./forms/security/TwoStepVerificationCard.js";
|
|
26
28
|
import { RECOVERY_CODE_PATTERN, TOTP_CODE_PATTERN, normalizeRecoveryCode, normalizeTotpCode } from "./forms/security/securityRules.js";
|
|
27
|
-
import { default as
|
|
29
|
+
import { default as default24 } from "./forms/SubmitButton.js";
|
|
28
30
|
import { applyServerProblem } from "./forms/applyServerProblem.js";
|
|
29
31
|
import { formLevelMessageOf, splitRowFieldErrors, splitServerFieldErrors } from "./forms/serverProblemFields.js";
|
|
32
|
+
import { isRequiredInSchema } from "./forms/schemaRequired.js";
|
|
30
33
|
import { useFormikField } from "./forms/useFormikField.js";
|
|
31
34
|
import { buildYupLocale } from "./forms/validation.js";
|
|
32
35
|
import * as Yup from "yup";
|
|
33
36
|
import { translateValidationMessage } from "./forms/validationMessages.js";
|
|
34
37
|
export {
|
|
35
|
-
|
|
38
|
+
default19 as ChangePasswordForm,
|
|
36
39
|
FieldArray,
|
|
37
|
-
|
|
40
|
+
default20 as ForgotPasswordForm,
|
|
38
41
|
Form,
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
default15 as
|
|
52
|
-
default16 as
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
42
|
+
default3 as FormAttachmentsField,
|
|
43
|
+
default4 as FormCatalogField,
|
|
44
|
+
default5 as FormCheckboxGroupField,
|
|
45
|
+
default6 as FormColorField,
|
|
46
|
+
default7 as FormFileField,
|
|
47
|
+
default8 as FormFileUploadField,
|
|
48
|
+
default9 as FormImageField,
|
|
49
|
+
default10 as FormMaskedField,
|
|
50
|
+
default11 as FormNumberField,
|
|
51
|
+
default12 as FormProblemAlert,
|
|
52
|
+
default13 as FormRepeatingFields,
|
|
53
|
+
FormSchemaProvider,
|
|
54
|
+
default15 as FormSelectField,
|
|
55
|
+
default16 as FormServerProblem,
|
|
56
|
+
default17 as FormTextField,
|
|
57
|
+
default14 as FormTransferListField,
|
|
58
|
+
default18 as FormWizard,
|
|
59
|
+
default2 as Formik,
|
|
56
60
|
RECOVERY_CODE_PATTERN,
|
|
57
61
|
SECOND_STEP_METHOD,
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
62
|
+
default22 as SecondStepForm,
|
|
63
|
+
default21 as SignInForm,
|
|
64
|
+
default24 as SubmitButton,
|
|
61
65
|
TOTP_CODE_PATTERN,
|
|
62
|
-
|
|
66
|
+
default23 as TwoStepVerificationCard,
|
|
63
67
|
Yup,
|
|
64
68
|
applyServerProblem,
|
|
65
69
|
buildYupLocale,
|
|
66
70
|
formLevelMessageOf,
|
|
71
|
+
isRequiredInSchema,
|
|
67
72
|
listTotalAtMostRule,
|
|
68
73
|
listTotalOf,
|
|
69
74
|
normalizeRecoveryCode,
|
|
@@ -76,6 +81,7 @@ export {
|
|
|
76
81
|
translateValidationMessage,
|
|
77
82
|
uniqueInListRule,
|
|
78
83
|
useField,
|
|
84
|
+
useFormSchema,
|
|
79
85
|
useFormikContext,
|
|
80
86
|
useFormikField
|
|
81
87
|
};
|
package/dist/forms.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"forms.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"forms.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -3,7 +3,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import { useHookFormField } from "./useHookFormField.js";
|
|
4
4
|
import AttachmentsInput from "../upload/AttachmentsInput.js";
|
|
5
5
|
function FormAttachmentsField({ name, control, ...inputProps }) {
|
|
6
|
-
const fieldProps = useHookFormField(name, control);
|
|
6
|
+
const fieldProps = useHookFormField(name, control, inputProps);
|
|
7
7
|
return /* @__PURE__ */ jsx(AttachmentsInput, { ...inputProps, ...fieldProps });
|
|
8
8
|
}
|
|
9
9
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormAttachmentsField.js","sources":["../../src/hookForm/FormAttachmentsField.jsx"],"sourcesContent":["// Campo de varios archivos de react-hook-form: AttachmentsInput (upload/) conectado a su campo con useController. Se ve y\n// se porta igual que el FormAttachmentsField de formik (@stackcraftmx/calcita/forms).\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useHookFormField} from '@/hookForm/useHookFormField.js';\nimport AttachmentsInput from '@/upload/AttachmentsInput.jsx';\n\n/**\n * @param {{name: string, control?: object} & Omit<Parameters<typeof import('@/upload/AttachmentsInput.jsx').default>[0], 'name'|'value'|'onChange'|'onBlur'|'error'>} props las del campo de la casa, sin\n * value
|
|
1
|
+
{"version":3,"file":"FormAttachmentsField.js","sources":["../../src/hookForm/FormAttachmentsField.jsx"],"sourcesContent":["// Campo de varios archivos de react-hook-form: AttachmentsInput (upload/) conectado a su campo con useController. Se ve y\n// se porta igual que el FormAttachmentsField de formik (@stackcraftmx/calcita/forms).\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useHookFormField} from '@/hookForm/useHookFormField.js';\nimport AttachmentsInput from '@/upload/AttachmentsInput.jsx';\n\n/**\n * @param {{name: string, control?: object} & Omit<Parameters<typeof import('@/upload/AttachmentsInput.jsx').default>[0], 'name'|'value'|'onChange'|'onBlur'|'error'> & Partial<Pick<Parameters<typeof import('@/upload/AttachmentsInput.jsx').default>[0], 'onChange'|'onBlur'>>} props las del campo de la casa, sin\n * value ni error (su onChange y su onBlur corren después de los del formulario); control: el de useForm, si la pantalla no usa FormProvider\n */\nexport default function FormAttachmentsField({name, control, ...inputProps}) {\n const fieldProps = useHookFormField(name, control, inputProps);\n return <AttachmentsInput {...inputProps} {...fieldProps} />;\n}\n"],"names":[],"mappings":";;;;AAWA,SAAwB,qBAAqB,EAAC,MAAM,SAAS,GAAG,cAAa;AACzE,QAAM,aAAa,iBAAiB,MAAM,SAAS,UAAU;AAC7D,SAAO,oBAAC,kBAAA,EAAkB,GAAG,YAAa,GAAG,WAAA,CAAY;AAC7D;"}
|
|
@@ -3,7 +3,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import CatalogInput from "../inputs/CatalogInput.js";
|
|
4
4
|
import { useHookFormField } from "./useHookFormField.js";
|
|
5
5
|
function FormCatalogField({ name, control, ...inputProps }) {
|
|
6
|
-
const fieldProps = useHookFormField(name, control);
|
|
6
|
+
const fieldProps = useHookFormField(name, control, inputProps);
|
|
7
7
|
return /* @__PURE__ */ jsx(CatalogInput, { ...inputProps, ...fieldProps });
|
|
8
8
|
}
|
|
9
9
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormCatalogField.js","sources":["../../src/hookForm/FormCatalogField.jsx"],"sourcesContent":["// Campo de catálogo de react-hook-form: CatalogInput (inputs/) conectado a su campo con useController. Se ve y se porta igual que\n// el FormCatalogField de formik (@stackcraftmx/calcita/forms).\n//\n// Genérico del paquete: function (regla de la casa).\nimport CatalogInput from '@/inputs/CatalogInput.jsx';\nimport {useHookFormField} from '@/hookForm/useHookFormField.js';\n\n/**\n * @param {{name: string, control?: object} & Omit<Parameters<typeof import('@/inputs/CatalogInput.jsx').default>[0], 'name'|'value'|'onChange'|'onBlur'|'error'>} props las del campo de la casa, sin\n * value
|
|
1
|
+
{"version":3,"file":"FormCatalogField.js","sources":["../../src/hookForm/FormCatalogField.jsx"],"sourcesContent":["// Campo de catálogo de react-hook-form: CatalogInput (inputs/) conectado a su campo con useController. Se ve y se porta igual que\n// el FormCatalogField de formik (@stackcraftmx/calcita/forms).\n//\n// Genérico del paquete: function (regla de la casa).\nimport CatalogInput from '@/inputs/CatalogInput.jsx';\nimport {useHookFormField} from '@/hookForm/useHookFormField.js';\n\n/**\n * @param {{name: string, control?: object} & Omit<Parameters<typeof import('@/inputs/CatalogInput.jsx').default>[0], 'name'|'value'|'onChange'|'onBlur'|'error'> & Partial<Pick<Parameters<typeof import('@/inputs/CatalogInput.jsx').default>[0], 'onChange'|'onBlur'>>} props las del campo de la casa, sin\n * value ni error (su onChange y su onBlur corren después de los del formulario); control: el de useForm, si la pantalla no usa FormProvider\n */\nexport default function FormCatalogField({name, control, ...inputProps}) {\n const fieldProps = useHookFormField(name, control, inputProps);\n return <CatalogInput {...inputProps} {...fieldProps} />;\n}\n"],"names":[],"mappings":";;;;AAWA,SAAwB,iBAAiB,EAAC,MAAM,SAAS,GAAG,cAAa;AACrE,QAAM,aAAa,iBAAiB,MAAM,SAAS,UAAU;AAC7D,SAAO,oBAAC,cAAA,EAAc,GAAG,YAAa,GAAG,WAAA,CAAY;AACzD;"}
|
|
@@ -3,7 +3,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import { useHookFormField } from "./useHookFormField.js";
|
|
4
4
|
import CheckboxGroupInput from "../inputs/CheckboxGroupInput.js";
|
|
5
5
|
function FormCheckboxGroupField({ name, control, ...inputProps }) {
|
|
6
|
-
const fieldProps = useHookFormField(name, control);
|
|
6
|
+
const fieldProps = useHookFormField(name, control, inputProps);
|
|
7
7
|
return /* @__PURE__ */ jsx(CheckboxGroupInput, { ...inputProps, ...fieldProps });
|
|
8
8
|
}
|
|
9
9
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormCheckboxGroupField.js","sources":["../../src/hookForm/FormCheckboxGroupField.jsx"],"sourcesContent":["// El grupo de casillas de react-hook-form: CheckboxGroupInput (inputs/) conectado con useController. Se ve y se porta\n// igual que el de formik (@stackcraftmx/calcita/forms).\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useHookFormField} from '@/hookForm/useHookFormField.js';\nimport CheckboxGroupInput from '@/inputs/CheckboxGroupInput.jsx';\n\n/**\n * @param {{name: string, control?: object} & Omit<Parameters<typeof import('@/inputs/CheckboxGroupInput.jsx').default>[0], 'name'|'value'|'onChange'|'onBlur'|'error'>} props las del campo de la casa, sin\n * value
|
|
1
|
+
{"version":3,"file":"FormCheckboxGroupField.js","sources":["../../src/hookForm/FormCheckboxGroupField.jsx"],"sourcesContent":["// El grupo de casillas de react-hook-form: CheckboxGroupInput (inputs/) conectado con useController. Se ve y se porta\n// igual que el de formik (@stackcraftmx/calcita/forms).\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useHookFormField} from '@/hookForm/useHookFormField.js';\nimport CheckboxGroupInput from '@/inputs/CheckboxGroupInput.jsx';\n\n/**\n * @param {{name: string, control?: object} & Omit<Parameters<typeof import('@/inputs/CheckboxGroupInput.jsx').default>[0], 'name'|'value'|'onChange'|'onBlur'|'error'> & Partial<Pick<Parameters<typeof import('@/inputs/CheckboxGroupInput.jsx').default>[0], 'onChange'|'onBlur'>>} props las del campo de la casa, sin\n * value ni error (su onChange y su onBlur corren después de los del formulario); control: el de useForm, si la pantalla no usa FormProvider\n */\nexport default function FormCheckboxGroupField({name, control, ...inputProps}) {\n const fieldProps = useHookFormField(name, control, inputProps);\n return <CheckboxGroupInput {...inputProps} {...fieldProps} />;\n}\n"],"names":[],"mappings":";;;;AAWA,SAAwB,uBAAuB,EAAC,MAAM,SAAS,GAAG,cAAa;AAC3E,QAAM,aAAa,iBAAiB,MAAM,SAAS,UAAU;AAC7D,SAAO,oBAAC,oBAAA,EAAoB,GAAG,YAAa,GAAG,WAAA,CAAY;AAC/D;"}
|
|
@@ -3,7 +3,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import ColorInput from "../inputs/ColorInput.js";
|
|
4
4
|
import { useHookFormField } from "./useHookFormField.js";
|
|
5
5
|
function FormColorField({ name, control, ...inputProps }) {
|
|
6
|
-
const fieldProps = useHookFormField(name, control);
|
|
6
|
+
const fieldProps = useHookFormField(name, control, inputProps);
|
|
7
7
|
return /* @__PURE__ */ jsx(ColorInput, { ...inputProps, ...fieldProps });
|
|
8
8
|
}
|
|
9
9
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormColorField.js","sources":["../../src/hookForm/FormColorField.jsx"],"sourcesContent":["// Campo de color de react-hook-form: ColorInput (inputs/) conectado a su campo con useController. Se ve y se porta igual que\n// el FormColorField de formik (@stackcraftmx/calcita/forms).\n//\n// Genérico del paquete: function (regla de la casa).\nimport ColorInput from '@/inputs/ColorInput.jsx';\nimport {useHookFormField} from '@/hookForm/useHookFormField.js';\n\n/**\n * @param {{name: string, control?: object} & Omit<Parameters<typeof import('@/inputs/ColorInput.jsx').default>[0], 'name'|'value'|'onChange'|'onBlur'|'error'>} props las del campo de la casa, sin\n * value
|
|
1
|
+
{"version":3,"file":"FormColorField.js","sources":["../../src/hookForm/FormColorField.jsx"],"sourcesContent":["// Campo de color de react-hook-form: ColorInput (inputs/) conectado a su campo con useController. Se ve y se porta igual que\n// el FormColorField de formik (@stackcraftmx/calcita/forms).\n//\n// Genérico del paquete: function (regla de la casa).\nimport ColorInput from '@/inputs/ColorInput.jsx';\nimport {useHookFormField} from '@/hookForm/useHookFormField.js';\n\n/**\n * @param {{name: string, control?: object} & Omit<Parameters<typeof import('@/inputs/ColorInput.jsx').default>[0], 'name'|'value'|'onChange'|'onBlur'|'error'> & Partial<Pick<Parameters<typeof import('@/inputs/ColorInput.jsx').default>[0], 'onChange'|'onBlur'>>} props las del campo de la casa, sin\n * value ni error (su onChange y su onBlur corren después de los del formulario); control: el de useForm, si la pantalla no usa FormProvider\n */\nexport default function FormColorField({name, control, ...inputProps}) {\n const fieldProps = useHookFormField(name, control, inputProps);\n return <ColorInput {...inputProps} {...fieldProps} />;\n}\n"],"names":[],"mappings":";;;;AAWA,SAAwB,eAAe,EAAC,MAAM,SAAS,GAAG,cAAa;AACnE,QAAM,aAAa,iBAAiB,MAAM,SAAS,UAAU;AAC7D,SAAO,oBAAC,YAAA,EAAY,GAAG,YAAa,GAAG,WAAA,CAAY;AACvD;"}
|
|
@@ -3,7 +3,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import { useHookFormField } from "./useHookFormField.js";
|
|
4
4
|
import FileInput from "../upload/FileInput.js";
|
|
5
5
|
function FormFileField({ name, control, ...inputProps }) {
|
|
6
|
-
const fieldProps = useHookFormField(name, control);
|
|
6
|
+
const fieldProps = useHookFormField(name, control, inputProps);
|
|
7
7
|
return /* @__PURE__ */ jsx(FileInput, { ...inputProps, ...fieldProps });
|
|
8
8
|
}
|
|
9
9
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormFileField.js","sources":["../../src/hookForm/FormFileField.jsx"],"sourcesContent":["// Campo de un archivo de react-hook-form: FileInput (upload/) conectado a su campo con useController. Se ve y se porta igual\n// que el FormFileField de formik (@stackcraftmx/calcita/forms).\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useHookFormField} from '@/hookForm/useHookFormField.js';\nimport FileInput from '@/upload/FileInput.jsx';\n\n/**\n * @param {{name: string, control?: object} & Omit<Parameters<typeof import('@/upload/FileInput.jsx').default>[0], 'name'|'value'|'onChange'|'onBlur'|'error'>} props las del campo de la casa, sin\n * value
|
|
1
|
+
{"version":3,"file":"FormFileField.js","sources":["../../src/hookForm/FormFileField.jsx"],"sourcesContent":["// Campo de un archivo de react-hook-form: FileInput (upload/) conectado a su campo con useController. Se ve y se porta igual\n// que el FormFileField de formik (@stackcraftmx/calcita/forms).\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useHookFormField} from '@/hookForm/useHookFormField.js';\nimport FileInput from '@/upload/FileInput.jsx';\n\n/**\n * @param {{name: string, control?: object} & Omit<Parameters<typeof import('@/upload/FileInput.jsx').default>[0], 'name'|'value'|'onChange'|'onBlur'|'error'> & Partial<Pick<Parameters<typeof import('@/upload/FileInput.jsx').default>[0], 'onChange'|'onBlur'>>} props las del campo de la casa, sin\n * value ni error (su onChange y su onBlur corren después de los del formulario); control: el de useForm, si la pantalla no usa FormProvider\n */\nexport default function FormFileField({name, control, ...inputProps}) {\n const fieldProps = useHookFormField(name, control, inputProps);\n return <FileInput {...inputProps} {...fieldProps} />;\n}\n"],"names":[],"mappings":";;;;AAWA,SAAwB,cAAc,EAAC,MAAM,SAAS,GAAG,cAAa;AAClE,QAAM,aAAa,iBAAiB,MAAM,SAAS,UAAU;AAC7D,SAAO,oBAAC,WAAA,EAAW,GAAG,YAAa,GAAG,WAAA,CAAY;AACtD;"}
|
|
@@ -3,7 +3,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import { useHookFormField } from "./useHookFormField.js";
|
|
4
4
|
import FileUploadInput from "../upload/FileUploadInput.js";
|
|
5
5
|
function FormFileUploadField({ name, control, ...inputProps }) {
|
|
6
|
-
const fieldProps = useHookFormField(name, control);
|
|
6
|
+
const fieldProps = useHookFormField(name, control, inputProps);
|
|
7
7
|
return /* @__PURE__ */ jsx(FileUploadInput, { ...inputProps, ...fieldProps });
|
|
8
8
|
}
|
|
9
9
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormFileUploadField.js","sources":["../../src/hookForm/FormFileUploadField.jsx"],"sourcesContent":["// El cargador mini de react-hook-form: FileUploadInput (upload/) conectado a su campo con useController. Se ve y se porta\n// igual que el FormFileUploadField de formik (@stackcraftmx/calcita/forms).\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useHookFormField} from '@/hookForm/useHookFormField.js';\nimport FileUploadInput from '@/upload/FileUploadInput.jsx';\n\n/**\n * @param {{name: string, control?: object} & Omit<Parameters<typeof import('@/upload/FileUploadInput.jsx').default>[0], 'name'|'value'|'onChange'|'onBlur'|'error'>} props las del campo de la casa, sin\n * value
|
|
1
|
+
{"version":3,"file":"FormFileUploadField.js","sources":["../../src/hookForm/FormFileUploadField.jsx"],"sourcesContent":["// El cargador mini de react-hook-form: FileUploadInput (upload/) conectado a su campo con useController. Se ve y se porta\n// igual que el FormFileUploadField de formik (@stackcraftmx/calcita/forms).\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useHookFormField} from '@/hookForm/useHookFormField.js';\nimport FileUploadInput from '@/upload/FileUploadInput.jsx';\n\n/**\n * @param {{name: string, control?: object} & Omit<Parameters<typeof import('@/upload/FileUploadInput.jsx').default>[0], 'name'|'value'|'onChange'|'onBlur'|'error'> & Partial<Pick<Parameters<typeof import('@/upload/FileUploadInput.jsx').default>[0], 'onChange'|'onBlur'>>} props las del campo de la casa, sin\n * value ni error (su onChange y su onBlur corren después de los del formulario); control: el de useForm, si la pantalla no usa FormProvider\n */\nexport default function FormFileUploadField({name, control, ...inputProps}) {\n const fieldProps = useHookFormField(name, control, inputProps);\n return <FileUploadInput {...inputProps} {...fieldProps} />;\n}\n"],"names":[],"mappings":";;;;AAWA,SAAwB,oBAAoB,EAAC,MAAM,SAAS,GAAG,cAAa;AACxE,QAAM,aAAa,iBAAiB,MAAM,SAAS,UAAU;AAC7D,SAAO,oBAAC,iBAAA,EAAiB,GAAG,YAAa,GAAG,WAAA,CAAY;AAC5D;"}
|
|
@@ -3,7 +3,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import { useHookFormField } from "./useHookFormField.js";
|
|
4
4
|
import ImageInput from "../upload/ImageInput.js";
|
|
5
5
|
function FormImageField({ name, control, ...inputProps }) {
|
|
6
|
-
const fieldProps = useHookFormField(name, control);
|
|
6
|
+
const fieldProps = useHookFormField(name, control, inputProps);
|
|
7
7
|
return /* @__PURE__ */ jsx(ImageInput, { ...inputProps, ...fieldProps });
|
|
8
8
|
}
|
|
9
9
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormImageField.js","sources":["../../src/hookForm/FormImageField.jsx"],"sourcesContent":["// Campo de una imagen de react-hook-form: ImageInput (upload/) conectado a su campo con useController. Se ve y se porta igual\n// que el FormImageField de formik (@stackcraftmx/calcita/forms).\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useHookFormField} from '@/hookForm/useHookFormField.js';\nimport ImageInput from '@/upload/ImageInput.jsx';\n\n/**\n * @param {{name: string, control?: object} & Omit<Parameters<typeof import('@/upload/ImageInput.jsx').default>[0], 'name'|'value'|'onChange'|'onBlur'|'error'>} props las del campo de la casa, sin\n * value
|
|
1
|
+
{"version":3,"file":"FormImageField.js","sources":["../../src/hookForm/FormImageField.jsx"],"sourcesContent":["// Campo de una imagen de react-hook-form: ImageInput (upload/) conectado a su campo con useController. Se ve y se porta igual\n// que el FormImageField de formik (@stackcraftmx/calcita/forms).\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useHookFormField} from '@/hookForm/useHookFormField.js';\nimport ImageInput from '@/upload/ImageInput.jsx';\n\n/**\n * @param {{name: string, control?: object} & Omit<Parameters<typeof import('@/upload/ImageInput.jsx').default>[0], 'name'|'value'|'onChange'|'onBlur'|'error'> & Partial<Pick<Parameters<typeof import('@/upload/ImageInput.jsx').default>[0], 'onChange'|'onBlur'>>} props las del campo de la casa, sin\n * value ni error (su onChange y su onBlur corren después de los del formulario); control: el de useForm, si la pantalla no usa FormProvider\n */\nexport default function FormImageField({name, control, ...inputProps}) {\n const fieldProps = useHookFormField(name, control, inputProps);\n return <ImageInput {...inputProps} {...fieldProps} />;\n}\n"],"names":[],"mappings":";;;;AAWA,SAAwB,eAAe,EAAC,MAAM,SAAS,GAAG,cAAa;AACnE,QAAM,aAAa,iBAAiB,MAAM,SAAS,UAAU;AAC7D,SAAO,oBAAC,YAAA,EAAY,GAAG,YAAa,GAAG,WAAA,CAAY;AACvD;"}
|
|
@@ -3,7 +3,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import { useHookFormField } from "./useHookFormField.js";
|
|
4
4
|
import MaskedInput from "../inputs/MaskedInput.js";
|
|
5
5
|
function FormMaskedField({ name, control, ...inputProps }) {
|
|
6
|
-
const fieldProps = useHookFormField(name, control);
|
|
6
|
+
const fieldProps = useHookFormField(name, control, inputProps);
|
|
7
7
|
return /* @__PURE__ */ jsx(MaskedInput, { ...inputProps, ...fieldProps });
|
|
8
8
|
}
|
|
9
9
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormMaskedField.js","sources":["../../src/hookForm/FormMaskedField.jsx"],"sourcesContent":["// Campo con máscara de react-hook-form: MaskedInput (inputs/) conectado a su campo. Al formulario llega el valor LIMPIO (sin\n// separadores, en mayúsculas): «5551234567», no «555 123 4567».\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useHookFormField} from '@/hookForm/useHookFormField.js';\nimport MaskedInput from '@/inputs/MaskedInput.jsx';\n\n/**\n * @param {{name: string, control?: object} & Omit<Parameters<typeof import('@/inputs/MaskedInput.jsx').default>[0], 'name'|'value'|'onChange'|'onBlur'|'error'>} props\n * las de MaskedInput (mask, label, helperText, placeholder…), sin value
|
|
1
|
+
{"version":3,"file":"FormMaskedField.js","sources":["../../src/hookForm/FormMaskedField.jsx"],"sourcesContent":["// Campo con máscara de react-hook-form: MaskedInput (inputs/) conectado a su campo. Al formulario llega el valor LIMPIO (sin\n// separadores, en mayúsculas): «5551234567», no «555 123 4567».\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useHookFormField} from '@/hookForm/useHookFormField.js';\nimport MaskedInput from '@/inputs/MaskedInput.jsx';\n\n/**\n * @param {{name: string, control?: object} & Omit<Parameters<typeof import('@/inputs/MaskedInput.jsx').default>[0], 'name'|'value'|'onChange'|'onBlur'|'error'> & Partial<Pick<Parameters<typeof import('@/inputs/MaskedInput.jsx').default>[0], 'onChange'|'onBlur'>>} props\n * las de MaskedInput (mask, label, helperText, placeholder…), sin value ni error (su onChange y su onBlur corren después de los del formulario); control: el de useForm,\n * si la pantalla no usa FormProvider\n */\nexport default function FormMaskedField({name, control, ...inputProps}) {\n const fieldProps = useHookFormField(name, control, inputProps);\n return <MaskedInput {...inputProps} {...fieldProps} />;\n}\n"],"names":[],"mappings":";;;;AAYA,SAAwB,gBAAgB,EAAC,MAAM,SAAS,GAAG,cAAa;AACpE,QAAM,aAAa,iBAAiB,MAAM,SAAS,UAAU;AAC7D,SAAO,oBAAC,aAAA,EAAa,GAAG,YAAa,GAAG,WAAA,CAAY;AACxD;"}
|
|
@@ -3,7 +3,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import NumberInput from "../inputs/NumberInput.js";
|
|
4
4
|
import { useHookFormField } from "./useHookFormField.js";
|
|
5
5
|
function FormNumberField({ name, control, ...inputProps }) {
|
|
6
|
-
const fieldProps = useHookFormField(name, control);
|
|
6
|
+
const fieldProps = useHookFormField(name, control, inputProps);
|
|
7
7
|
return /* @__PURE__ */ jsx(NumberInput, { ...inputProps, ...fieldProps });
|
|
8
8
|
}
|
|
9
9
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormNumberField.js","sources":["../../src/hookForm/FormNumberField.jsx"],"sourcesContent":["// Campo de número de react-hook-form: NumberInput (inputs/) conectado a su campo con useController. Se ve y se porta igual que\n// el FormNumberField de formik (@stackcraftmx/calcita/forms).\n//\n// Genérico del paquete: function (regla de la casa).\nimport NumberInput from '@/inputs/NumberInput.jsx';\nimport {useHookFormField} from '@/hookForm/useHookFormField.js';\n\n/**\n * @param {{name: string, control?: object} & Omit<Parameters<typeof import('@/inputs/NumberInput.jsx').default>[0], 'name'|'value'|'onChange'|'onBlur'|'error'>} props las del campo de la casa, sin\n * value
|
|
1
|
+
{"version":3,"file":"FormNumberField.js","sources":["../../src/hookForm/FormNumberField.jsx"],"sourcesContent":["// Campo de número de react-hook-form: NumberInput (inputs/) conectado a su campo con useController. Se ve y se porta igual que\n// el FormNumberField de formik (@stackcraftmx/calcita/forms).\n//\n// Genérico del paquete: function (regla de la casa).\nimport NumberInput from '@/inputs/NumberInput.jsx';\nimport {useHookFormField} from '@/hookForm/useHookFormField.js';\n\n/**\n * @param {{name: string, control?: object} & Omit<Parameters<typeof import('@/inputs/NumberInput.jsx').default>[0], 'name'|'value'|'onChange'|'onBlur'|'error'> & Partial<Pick<Parameters<typeof import('@/inputs/NumberInput.jsx').default>[0], 'onChange'|'onBlur'>>} props las del campo de la casa, sin\n * value ni error (su onChange y su onBlur corren después de los del formulario); control: el de useForm, si la pantalla no usa FormProvider\n */\nexport default function FormNumberField({name, control, ...inputProps}) {\n const fieldProps = useHookFormField(name, control, inputProps);\n return <NumberInput {...inputProps} {...fieldProps} />;\n}\n"],"names":[],"mappings":";;;;AAWA,SAAwB,gBAAgB,EAAC,MAAM,SAAS,GAAG,cAAa;AACpE,QAAM,aAAa,iBAAiB,MAAM,SAAS,UAAU;AAC7D,SAAO,oBAAC,aAAA,EAAa,GAAG,YAAa,GAAG,WAAA,CAAY;AACxD;"}
|
|
@@ -3,7 +3,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import SelectInput from "../inputs/SelectInput.js";
|
|
4
4
|
import { useHookFormField } from "./useHookFormField.js";
|
|
5
5
|
function FormSelectField({ name, control, ...inputProps }) {
|
|
6
|
-
const fieldProps = useHookFormField(name, control);
|
|
6
|
+
const fieldProps = useHookFormField(name, control, inputProps);
|
|
7
7
|
return /* @__PURE__ */ jsx(SelectInput, { ...inputProps, ...fieldProps });
|
|
8
8
|
}
|
|
9
9
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormSelectField.js","sources":["../../src/hookForm/FormSelectField.jsx"],"sourcesContent":["// Campo de lista desplegable de react-hook-form: SelectInput (inputs/) conectado a su campo con useController. Se ve y se porta igual que\n// el FormSelectField de formik (@stackcraftmx/calcita/forms).\n//\n// Genérico del paquete: function (regla de la casa).\nimport SelectInput from '@/inputs/SelectInput.jsx';\nimport {useHookFormField} from '@/hookForm/useHookFormField.js';\n\n/**\n * @param {{name: string, control?: object} & Omit<Parameters<typeof import('@/inputs/SelectInput.jsx').default>[0], 'name'|'value'|'onChange'|'onBlur'|'error'>} props las del campo de la casa, sin\n * value
|
|
1
|
+
{"version":3,"file":"FormSelectField.js","sources":["../../src/hookForm/FormSelectField.jsx"],"sourcesContent":["// Campo de lista desplegable de react-hook-form: SelectInput (inputs/) conectado a su campo con useController. Se ve y se porta igual que\n// el FormSelectField de formik (@stackcraftmx/calcita/forms).\n//\n// Genérico del paquete: function (regla de la casa).\nimport SelectInput from '@/inputs/SelectInput.jsx';\nimport {useHookFormField} from '@/hookForm/useHookFormField.js';\n\n/**\n * @param {{name: string, control?: object} & Omit<Parameters<typeof import('@/inputs/SelectInput.jsx').default>[0], 'name'|'value'|'onChange'|'onBlur'|'error'> & Partial<Pick<Parameters<typeof import('@/inputs/SelectInput.jsx').default>[0], 'onChange'|'onBlur'>>} props las del campo de la casa, sin\n * value ni error (su onChange y su onBlur corren después de los del formulario); control: el de useForm, si la pantalla no usa FormProvider\n */\nexport default function FormSelectField({name, control, ...inputProps}) {\n const fieldProps = useHookFormField(name, control, inputProps);\n return <SelectInput {...inputProps} {...fieldProps} />;\n}\n"],"names":[],"mappings":";;;;AAWA,SAAwB,gBAAgB,EAAC,MAAM,SAAS,GAAG,cAAa;AACpE,QAAM,aAAa,iBAAiB,MAAM,SAAS,UAAU;AAC7D,SAAO,oBAAC,aAAA,EAAa,GAAG,YAAa,GAAG,WAAA,CAAY;AACxD;"}
|
|
@@ -3,7 +3,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import TextInput from "../inputs/TextInput.js";
|
|
4
4
|
import { useHookFormField } from "./useHookFormField.js";
|
|
5
5
|
function FormTextField({ name, control, ...inputProps }) {
|
|
6
|
-
const fieldProps = useHookFormField(name, control);
|
|
6
|
+
const fieldProps = useHookFormField(name, control, inputProps);
|
|
7
7
|
return /* @__PURE__ */ jsx(TextInput, { ...inputProps, ...fieldProps });
|
|
8
8
|
}
|
|
9
9
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormTextField.js","sources":["../../src/hookForm/FormTextField.jsx"],"sourcesContent":["// Campo de texto de react-hook-form: TextInput (inputs/) conectado a su campo con useController. Se ve y se porta igual que\n// el FormTextField de formik (@stackcraftmx/calcita/forms).\n//\n// Genérico del paquete: function (regla de la casa).\nimport TextInput from '@/inputs/TextInput.jsx';\nimport {useHookFormField} from '@/hookForm/useHookFormField.js';\n\n/**\n * @param {{name: string, control?: object} & Omit<Parameters<typeof import('@/inputs/TextInput.jsx').default>[0], 'name'|'value'|'onChange'|'onBlur'|'error'>} props las del campo de la casa, sin\n * value
|
|
1
|
+
{"version":3,"file":"FormTextField.js","sources":["../../src/hookForm/FormTextField.jsx"],"sourcesContent":["// Campo de texto de react-hook-form: TextInput (inputs/) conectado a su campo con useController. Se ve y se porta igual que\n// el FormTextField de formik (@stackcraftmx/calcita/forms).\n//\n// Genérico del paquete: function (regla de la casa).\nimport TextInput from '@/inputs/TextInput.jsx';\nimport {useHookFormField} from '@/hookForm/useHookFormField.js';\n\n/**\n * @param {{name: string, control?: object} & Omit<Parameters<typeof import('@/inputs/TextInput.jsx').default>[0], 'name'|'value'|'onChange'|'onBlur'|'error'> & Partial<Pick<Parameters<typeof import('@/inputs/TextInput.jsx').default>[0], 'onChange'|'onBlur'>>} props las del campo de la casa, sin\n * value ni error (su onChange y su onBlur corren después de los del formulario); control: el de useForm, si la pantalla no usa FormProvider\n */\nexport default function FormTextField({name, control, ...inputProps}) {\n const fieldProps = useHookFormField(name, control, inputProps);\n return <TextInput {...inputProps} {...fieldProps} />;\n}\n"],"names":[],"mappings":";;;;AAWA,SAAwB,cAAc,EAAC,MAAM,SAAS,GAAG,cAAa;AAClE,QAAM,aAAa,iBAAiB,MAAM,SAAS,UAAU;AAC7D,SAAO,oBAAC,WAAA,EAAW,GAAG,YAAa,GAAG,WAAA,CAAY;AACtD;"}
|
|
@@ -3,7 +3,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import { useHookFormField } from "./useHookFormField.js";
|
|
4
4
|
import TransferListInput from "../inputs/TransferListInput.js";
|
|
5
5
|
function FormTransferListField({ name, control, ...inputProps }) {
|
|
6
|
-
const fieldProps = useHookFormField(name, control);
|
|
6
|
+
const fieldProps = useHookFormField(name, control, inputProps);
|
|
7
7
|
return /* @__PURE__ */ jsx(TransferListInput, { ...inputProps, ...fieldProps });
|
|
8
8
|
}
|
|
9
9
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormTransferListField.js","sources":["../../src/hookForm/FormTransferListField.jsx"],"sourcesContent":["// La lista de transferencia de react-hook-form: TransferListInput (inputs/) conectada con useController. Se ve y se porta\n// igual que la de formik (@stackcraftmx/calcita/forms).\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useHookFormField} from '@/hookForm/useHookFormField.js';\nimport TransferListInput from '@/inputs/TransferListInput.jsx';\n\n/**\n * @param {{name: string, control?: object} & Omit<Parameters<typeof import('@/inputs/TransferListInput.jsx').default>[0], 'name'|'value'|'onChange'|'onBlur'|'error'>} props las del campo de la casa, sin\n * value
|
|
1
|
+
{"version":3,"file":"FormTransferListField.js","sources":["../../src/hookForm/FormTransferListField.jsx"],"sourcesContent":["// La lista de transferencia de react-hook-form: TransferListInput (inputs/) conectada con useController. Se ve y se porta\n// igual que la de formik (@stackcraftmx/calcita/forms).\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useHookFormField} from '@/hookForm/useHookFormField.js';\nimport TransferListInput from '@/inputs/TransferListInput.jsx';\n\n/**\n * @param {{name: string, control?: object} & Omit<Parameters<typeof import('@/inputs/TransferListInput.jsx').default>[0], 'name'|'value'|'onChange'|'onBlur'|'error'> & Partial<Pick<Parameters<typeof import('@/inputs/TransferListInput.jsx').default>[0], 'onChange'|'onBlur'>>} props las del campo de la casa, sin\n * value ni error (su onChange y su onBlur corren después de los del formulario); control: el de useForm, si la pantalla no usa FormProvider\n */\nexport default function FormTransferListField({name, control, ...inputProps}) {\n const fieldProps = useHookFormField(name, control, inputProps);\n return <TransferListInput {...inputProps} {...fieldProps} />;\n}\n"],"names":[],"mappings":";;;;AAWA,SAAwB,sBAAsB,EAAC,MAAM,SAAS,GAAG,cAAa;AAC1E,QAAM,aAAa,iBAAiB,MAAM,SAAS,UAAU;AAC7D,SAAO,oBAAC,mBAAA,EAAmB,GAAG,YAAa,GAAG,WAAA,CAAY;AAC9D;"}
|
|
@@ -4,15 +4,30 @@ import { useState, useRef, useEffect } from "react";
|
|
|
4
4
|
import { useFormContext } from "react-hook-form";
|
|
5
5
|
import FormProblemAlert from "./FormProblemAlert.js";
|
|
6
6
|
import SubmitButton from "./SubmitButton.js";
|
|
7
|
+
import { useWizardSteps } from "../inputs/useWizardSteps.js";
|
|
7
8
|
import WizardLayout from "../inputs/WizardLayout.js";
|
|
8
9
|
import { warnUnknownProps } from "../toolkit/unknownProps.js";
|
|
9
|
-
function FormWizard({
|
|
10
|
+
function FormWizard({
|
|
11
|
+
steps,
|
|
12
|
+
submitLabel,
|
|
13
|
+
orientation,
|
|
14
|
+
hideBackOnFirstStep,
|
|
15
|
+
initialStepKey,
|
|
16
|
+
stepSelection,
|
|
17
|
+
onStepChange,
|
|
18
|
+
texts,
|
|
19
|
+
...unknownProps
|
|
20
|
+
}) {
|
|
10
21
|
warnUnknownProps("FormWizard", unknownProps);
|
|
11
22
|
const { trigger, resetField, getFieldState, formState } = useFormContext();
|
|
12
23
|
const { isSubmitting, submitCount } = formState;
|
|
13
|
-
const [activeIndex, setActiveIndex] = useState(0);
|
|
14
24
|
const [skippedKeys, setSkippedKeys] = useState(() => /* @__PURE__ */ new Set());
|
|
15
25
|
const wasSubmitting = useRef(false);
|
|
26
|
+
const isStepValid = async (index) => {
|
|
27
|
+
const stepFields = steps[index].fields ?? [];
|
|
28
|
+
return stepFields.length === 0 || trigger(stepFields, { shouldFocus: true });
|
|
29
|
+
};
|
|
30
|
+
const { activeIndex, setActiveIndex, selectStep } = useWizardSteps({ steps, initialStepKey, stepSelection, onStepChange, isStepValid });
|
|
16
31
|
const activeStep = steps[activeIndex];
|
|
17
32
|
useEffect(() => {
|
|
18
33
|
if (wasSubmitting.current && !isSubmitting) {
|
|
@@ -24,9 +39,7 @@ function FormWizard({ steps, submitLabel, texts, ...unknownProps }) {
|
|
|
24
39
|
wasSubmitting.current = isSubmitting;
|
|
25
40
|
}, [isSubmitting, submitCount]);
|
|
26
41
|
const goNext = async () => {
|
|
27
|
-
|
|
28
|
-
const isStepValid = stepFields.length === 0 || await trigger(stepFields, { shouldFocus: true });
|
|
29
|
-
if (!isStepValid) {
|
|
42
|
+
if (!await isStepValid(activeIndex)) {
|
|
30
43
|
return;
|
|
31
44
|
}
|
|
32
45
|
setSkippedKeys((currentKeys) => new Set([...currentKeys].filter((key) => key !== activeStep.key)));
|
|
@@ -46,9 +59,12 @@ function FormWizard({ steps, submitLabel, texts, ...unknownProps }) {
|
|
|
46
59
|
activeIndex,
|
|
47
60
|
skippedKeys,
|
|
48
61
|
isSubmitting,
|
|
62
|
+
orientation,
|
|
63
|
+
hideBackOnFirstStep,
|
|
49
64
|
onBack: () => setActiveIndex((currentIndex) => currentIndex - 1),
|
|
50
65
|
onNext: goNext,
|
|
51
66
|
onSkip: skipStep,
|
|
67
|
+
onStepSelect: selectStep,
|
|
52
68
|
submitButton: /* @__PURE__ */ jsx(SubmitButton, { children: submitLabel }),
|
|
53
69
|
problemAlert: /* @__PURE__ */ jsx(FormProblemAlert, {}),
|
|
54
70
|
texts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormWizard.js","sources":["../../src/hookForm/FormWizard.jsx"],"sourcesContent":["// Formulario por pasos (wizard) con react-hook-form: el mismo del de formik (@stackcraftmx/calcita/forms), con las mismas\n// props y el mismo comportamiento:\n// - «Siguiente» revisa SOLO los campos del paso (trigger con sus nombres) y no avanza si alguno tiene error;\n// - «Omitir este paso» (solo en los opcionales) regresa sus campos a su valor de inicio (resetField): omitir es no dar ese\n// dato, no dejar lo que se escribió a medias;\n// - el último paso envía TODO el formulario (el esquema de yup completo vale para todos los pasos);\n// - si el envío falla por un campo de un paso anterior (yup o el 422 del servidor con applyServerProblem), regresa solo a\n// ese paso: un error que no se ve no se puede corregir.\n//\n// Va DENTRO de <FormProvider> y del <form> con su handleSubmit (usa useFormContext):\n// const form = useForm({resolver: yupResolver(schema), defaultValues});\n// <FormProvider {...form}>\n// <form noValidate onSubmit={form.handleSubmit(send)}>\n// <FormWizard submitLabel=\"Enviar solicitud\" steps={[\n// {key: 'datos', label: 'Sus datos', fields: ['name', 'email'], content: <>…campos…</>},\n// {key: 'aval', label: 'Aval', optional: true, fields: ['guarantor'], content: <>…</>},\n// ]} />\n// </form>\n// </FormProvider>\n//\n// Lo que se ve vive en WizardLayout (inputs/). Los textos se cambian con `texts`: {wizard: {next: 'Continuar'}}.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useEffect, useRef, useState} from 'react';\nimport {useFormContext} from 'react-hook-form';\n\nimport FormProblemAlert from '@/hookForm/FormProblemAlert.jsx';\nimport SubmitButton from '@/hookForm/SubmitButton.jsx';\nimport WizardLayout from '@/inputs/WizardLayout.jsx';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\n\n/**\n * @param {object} props\n * @param {Object[]} props.steps en orden\n * @param {string} props.steps[].key\n * @param {string} props.steps[].label ya traducido\n * @param {string[]} [props.steps[].fields] los campos del paso (los que revisa «Siguiente»)\n * @param {boolean} [props.steps[].optional] se puede omitir\n * @param {import('react').ReactNode} props.steps[].content los campos del paso\n * @param {string} props.submitLabel ya traducido: el botón del último paso\n * @param {object} [props.texts] los textos que cambian, con la forma de `common`: {wizard: {next, back, skip, optional, skipped, stepOf}}\n */\nexport default function FormWizard({steps, submitLabel, texts, ...unknownProps}) {\n warnUnknownProps('FormWizard', unknownProps);\n const {trigger, resetField, getFieldState, formState} = useFormContext();\n const {isSubmitting, submitCount} = formState;\n const [
|
|
1
|
+
{"version":3,"file":"FormWizard.js","sources":["../../src/hookForm/FormWizard.jsx"],"sourcesContent":["// Formulario por pasos (wizard) con react-hook-form: el mismo del de formik (@stackcraftmx/calcita/forms), con las mismas\n// props y el mismo comportamiento:\n// - «Siguiente» revisa SOLO los campos del paso (trigger con sus nombres) y no avanza si alguno tiene error;\n// - «Omitir este paso» (solo en los opcionales) regresa sus campos a su valor de inicio (resetField): omitir es no dar ese\n// dato, no dejar lo que se escribió a medias;\n// - el último paso envía TODO el formulario (el esquema de yup completo vale para todos los pasos);\n// - si el envío falla por un campo de un paso anterior (yup o el 422 del servidor con applyServerProblem), regresa solo a\n// ese paso: un error que no se ve no se puede corregir;\n// - para editar un registro (se entra a corregir un dato suelto): initialStepKey abre en el paso que diga el servidor,\n// orientation=\"vertical\" pone los campos dentro de su paso, y stepSelection deja pulsar el título de otro paso para\n// saltar directo (free) o solo si el paso abierto no tiene errores (checked). onStepChange avisa cada cambio de paso.\n//\n// Va DENTRO de <FormProvider> y del <form> con su handleSubmit (usa useFormContext):\n// const form = useForm({resolver: yupResolver(schema), defaultValues});\n// <FormProvider {...form}>\n// <form noValidate onSubmit={form.handleSubmit(send)}>\n// <FormWizard submitLabel=\"Enviar solicitud\" steps={[\n// {key: 'datos', label: 'Sus datos', fields: ['name', 'email'], content: <>…campos…</>},\n// {key: 'aval', label: 'Aval', optional: true, fields: ['guarantor'], content: <>…</>},\n// ]} />\n// </form>\n// </FormProvider>\n//\n// Lo que se ve vive en WizardLayout (inputs/). Los textos se cambian con `texts`: {wizard: {next: 'Continuar'}}.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useEffect, useRef, useState} from 'react';\nimport {useFormContext} from 'react-hook-form';\n\nimport FormProblemAlert from '@/hookForm/FormProblemAlert.jsx';\nimport SubmitButton from '@/hookForm/SubmitButton.jsx';\nimport {useWizardSteps} from '@/inputs/useWizardSteps.js';\nimport WizardLayout from '@/inputs/WizardLayout.jsx';\nimport {warnUnknownProps} from '@/toolkit/unknownProps.js';\n\n/**\n * @param {object} props\n * @param {Object[]} props.steps en orden\n * @param {string} props.steps[].key\n * @param {string} props.steps[].label ya traducido\n * @param {string[]} [props.steps[].fields] los campos del paso (los que revisa «Siguiente»)\n * @param {boolean} [props.steps[].optional] se puede omitir\n * @param {import('react').ReactNode} props.steps[].content los campos del paso\n * @param {boolean} [props.steps[].completed] lleva la palomita (cuando los títulos se pulsan, solo si la pantalla lo dice)\n * @param {string} props.submitLabel ya traducido: el botón del último paso\n * @param {'horizontal'|'vertical'} [props.orientation] uno de WIZARD_ORIENTATION; por omisión horizontal\n * @param {boolean} [props.hideBackOnFirstStep] en el primer paso no se pinta «Anterior»; por omisión sale apagado, como antes\n * @param {string} [props.initialStepKey] la llave del paso en el que se abre (la que diga el servidor); por omisión el primero\n * @param {'none'|'free'|'checked'} [props.stepSelection] uno de WIZARD_STEP_SELECTION: si el título de otro paso se pulsa y qué\n * revisa antes; por omisión none (se avanza con «Siguiente», como siempre)\n * @param {(stepKey: string, index: number) => void} [props.onStepChange] cada vez que cambia el paso abierto\n * @param {object} [props.texts] los textos que cambian, con la forma de `common`: {wizard: {next, back, skip, optional, skipped, stepOf}}\n */\nexport default function FormWizard({\n steps, submitLabel, orientation, hideBackOnFirstStep, initialStepKey, stepSelection, onStepChange, texts, ...unknownProps\n}) {\n warnUnknownProps('FormWizard', unknownProps);\n const {trigger, resetField, getFieldState, formState} = useFormContext();\n const {isSubmitting, submitCount} = formState;\n const [skippedKeys, setSkippedKeys] = useState(() => new Set());\n const wasSubmitting = useRef(false);\n\n // revisa SOLO los campos de un paso (trigger los marca, los pinta y pone el foco en el primero con error)\n const isStepValid = async (index) => {\n const stepFields = steps[index].fields ?? [];\n return stepFields.length === 0 || trigger(stepFields, {shouldFocus: true});\n };\n const {activeIndex, setActiveIndex, selectStep} = useWizardSteps({steps, initialStepKey, stepSelection, onStepChange, isStepValid});\n const activeStep = steps[activeIndex];\n\n // al terminar un envío fallido, regresa al paso con el primer error (solo en ese momento: escribir en otro paso no\n // debe jalar a la persona de regreso). OJO: getFieldState necesita formState para leer los errores de ahora\n useEffect(() => {\n if (wasSubmitting.current && !isSubmitting) {\n const errorStepIndex = steps.findIndex((step) => (step.fields ?? []).some((field) => getFieldState(field, formState).invalid));\n if (errorStepIndex >= 0) {\n setActiveIndex(errorStepIndex);\n }\n }\n wasSubmitting.current = isSubmitting;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isSubmitting, submitCount]);\n\n const goNext = async () => {\n // el paso tiene errores: se queda ahí para que se corrijan\n if (!(await isStepValid(activeIndex))) {\n return;\n }\n setSkippedKeys((currentKeys) => new Set([...currentKeys].filter((key) => key !== activeStep.key)));\n setActiveIndex((currentIndex) => currentIndex + 1);\n };\n\n const skipStep = () => {\n for (const field of activeStep.fields ?? []) {\n resetField(field);\n }\n setSkippedKeys((currentKeys) => new Set([...currentKeys, activeStep.key]));\n setActiveIndex((currentIndex) => currentIndex + 1);\n };\n\n return (\n <WizardLayout steps={steps} activeIndex={activeIndex} skippedKeys={skippedKeys} isSubmitting={isSubmitting} orientation={orientation} hideBackOnFirstStep={hideBackOnFirstStep}\n onBack={() => setActiveIndex((currentIndex) => currentIndex - 1)} onNext={goNext} onSkip={skipStep} onStepSelect={selectStep}\n submitButton={<SubmitButton>{submitLabel}</SubmitButton>} problemAlert={<FormProblemAlert />} texts={texts} />\n );\n}\n"],"names":[],"mappings":";;;;;;;;;AAqDA,SAAwB,WAAW;AAAA,EAC/B;AAAA,EAAO;AAAA,EAAa;AAAA,EAAa;AAAA,EAAqB;AAAA,EAAgB;AAAA,EAAe;AAAA,EAAc;AAAA,EAAO,GAAG;AACjH,GAAG;AACC,mBAAiB,cAAc,YAAY;AAC3C,QAAM,EAAC,SAAS,YAAY,eAAe,UAAA,IAAa,eAAA;AACxD,QAAM,EAAC,cAAc,YAAA,IAAe;AACpC,QAAM,CAAC,aAAa,cAAc,IAAI,SAAS,MAAM,oBAAI,KAAK;AAC9D,QAAM,gBAAgB,OAAO,KAAK;AAGlC,QAAM,cAAc,OAAO,UAAU;AACjC,UAAM,aAAa,MAAM,KAAK,EAAE,UAAU,CAAA;AAC1C,WAAO,WAAW,WAAW,KAAK,QAAQ,YAAY,EAAC,aAAa,MAAK;AAAA,EAC7E;AACA,QAAM,EAAC,aAAa,gBAAgB,WAAA,IAAc,eAAe,EAAC,OAAO,gBAAgB,eAAe,cAAc,YAAA,CAAY;AAClI,QAAM,aAAa,MAAM,WAAW;AAIpC,YAAU,MAAM;AACZ,QAAI,cAAc,WAAW,CAAC,cAAc;AACxC,YAAM,iBAAiB,MAAM,UAAU,CAAC,UAAU,KAAK,UAAU,CAAA,GAAI,KAAK,CAAC,UAAU,cAAc,OAAO,SAAS,EAAE,OAAO,CAAC;AAC7H,UAAI,kBAAkB,GAAG;AACrB,uBAAe,cAAc;AAAA,MACjC;AAAA,IACJ;AACA,kBAAc,UAAU;AAAA,EAE5B,GAAG,CAAC,cAAc,WAAW,CAAC;AAE9B,QAAM,SAAS,YAAY;AAEvB,QAAI,CAAE,MAAM,YAAY,WAAW,GAAI;AACnC;AAAA,IACJ;AACA,mBAAe,CAAC,gBAAgB,IAAI,IAAI,CAAC,GAAG,WAAW,EAAE,OAAO,CAAC,QAAQ,QAAQ,WAAW,GAAG,CAAC,CAAC;AACjG,mBAAe,CAAC,iBAAiB,eAAe,CAAC;AAAA,EACrD;AAEA,QAAM,WAAW,MAAM;AACnB,eAAW,SAAS,WAAW,UAAU,CAAA,GAAI;AACzC,iBAAW,KAAK;AAAA,IACpB;AACA,mBAAe,CAAC,gBAAgB,oBAAI,IAAI,CAAC,GAAG,aAAa,WAAW,GAAG,CAAC,CAAC;AACzE,mBAAe,CAAC,iBAAiB,eAAe,CAAC;AAAA,EACrD;AAEA,SACI;AAAA,IAAC;AAAA,IAAA;AAAA,MAAa;AAAA,MAAc;AAAA,MAA0B;AAAA,MAA0B;AAAA,MAA4B;AAAA,MAA0B;AAAA,MACxH,QAAQ,MAAM,eAAe,CAAC,iBAAiB,eAAe,CAAC;AAAA,MAAG,QAAQ;AAAA,MAAQ,QAAQ;AAAA,MAAU,cAAc;AAAA,MAClH,cAAc,oBAAC,cAAA,EAAc,UAAA,YAAA,CAAY;AAAA,MAAiB,kCAAe,kBAAA,EAAiB;AAAA,MAAI;AAAA,IAAA;AAAA,EAAA;AAEpH;"}
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { useFormContext, useController } from "react-hook-form";
|
|
3
|
-
function useHookFormField(name, control) {
|
|
3
|
+
function useHookFormField(name, control, screen = {}) {
|
|
4
4
|
const formContext = useFormContext();
|
|
5
5
|
const { field, fieldState } = useController({ name, control: control ?? formContext?.control });
|
|
6
6
|
return {
|
|
7
7
|
name,
|
|
8
8
|
value: field.value,
|
|
9
|
-
onChange:
|
|
10
|
-
|
|
9
|
+
onChange: (value, ...rest) => {
|
|
10
|
+
field.onChange(value);
|
|
11
|
+
screen.onChange?.(value, ...rest);
|
|
12
|
+
},
|
|
13
|
+
onBlur: (...args) => {
|
|
14
|
+
field.onBlur();
|
|
15
|
+
screen.onBlur?.(...args);
|
|
16
|
+
},
|
|
11
17
|
// react-hook-form enfoca el primer campo con error al enviar: necesita el input de verdad
|
|
12
18
|
inputRef: field.ref,
|
|
13
19
|
error: fieldState.error?.message
|