From 385cbeec6cadc1c351d5e3ce3e5c2df0f5e58f6f Mon Sep 17 00:00:00 2001 From: Romain Hamel Date: Wed, 16 Apr 2025 18:10:54 +0200 Subject: [PATCH] refactor(Form): remove state assignment and opt-in to nested forms --- .../examples/form/FormExampleNested.vue | 2 +- .../examples/form/FormExampleNestedList.vue | 9 ++- .../app/pages/components/form-sandro.vue | 71 +++++++++++++++++++ src/runtime/components/Form.vue | 23 +++--- 4 files changed, 89 insertions(+), 16 deletions(-) create mode 100644 playground/app/pages/components/form-sandro.vue diff --git a/docs/app/components/content/examples/form/FormExampleNested.vue b/docs/app/components/content/examples/form/FormExampleNested.vue index 78e0fea1..a5cb30de 100644 --- a/docs/app/components/content/examples/form/FormExampleNested.vue +++ b/docs/app/components/content/examples/form/FormExampleNested.vue @@ -39,7 +39,7 @@ async function onSubmit(event: FormSubmitEvent) { - + diff --git a/docs/app/components/content/examples/form/FormExampleNestedList.vue b/docs/app/components/content/examples/form/FormExampleNestedList.vue index 195bdfc6..2b002b9d 100644 --- a/docs/app/components/content/examples/form/FormExampleNestedList.vue +++ b/docs/app/components/content/examples/form/FormExampleNestedList.vue @@ -51,7 +51,14 @@ async function onSubmit(event: FormSubmitEvent) { - + diff --git a/playground/app/pages/components/form-sandro.vue b/playground/app/pages/components/form-sandro.vue new file mode 100644 index 00000000..d592f013 --- /dev/null +++ b/playground/app/pages/components/form-sandro.vue @@ -0,0 +1,71 @@ + + + diff --git a/src/runtime/components/Form.vue b/src/runtime/components/Form.vue index f30f6ab0..b17b6c02 100644 --- a/src/runtime/components/Form.vue +++ b/src/runtime/components/Form.vue @@ -19,7 +19,7 @@ export interface FormProps { * @param state - The current state of the form. * @returns A promise that resolves to an array of FormError objects, or an array of FormError objects directly. */ - validate?: (state: Partial | O) => Promise | FormError[] + validate?: (state: Partial) => Promise | FormError[] /** * The list of input events that trigger the form validation. * @defaultValue `['blur', 'change', 'input']` @@ -32,11 +32,11 @@ export interface FormProps { * @defaultValue `300` */ validateOnInputDelay?: number + /** - * If true, schema transformations will be applied to the state on submit. - * @defaultValue `true` + * If true and nested in another form, this form will attach to its parent and validate at the same time. */ - transform?: boolean + nested?: boolean /** * When `true`, all form elements will be disabled on `@submit` event. * This will cause any focused input elements to lose their focus state. @@ -71,7 +71,6 @@ const props = withDefaults(defineProps>(), { return ['input', 'blur', 'change'] as FormInputEvents[] }, validateOnInputDelay: 300, - transform: true, loadingAuto: true }) @@ -127,14 +126,14 @@ onUnmounted(() => { }) onMounted(async () => { - if (parentBus) { + if (props.nested && parentBus) { await nextTick() parentBus.emit({ type: 'attach', validate: _validate, formId }) } }) onUnmounted(() => { - if (parentBus) { + if (props.nested && parentBus) { parentBus.emit({ type: 'detach', formId }) } }) @@ -173,7 +172,7 @@ async function getErrors(): Promise { return resolveErrorIds(errs) } -async function _validate(opts: { name?: keyof I | (keyof I)[], silent?: boolean, nested?: boolean, transform?: boolean } = { silent: false, nested: true, transform: false }): Promise { +async function _validate(opts: { name?: keyof I | (keyof I)[], silent?: boolean, nested?: boolean } = { silent: false, nested: true }): Promise { const names = opts.name && !Array.isArray(opts.name) ? [opts.name] : opts.name as (keyof I)[] const nestedValidatePromises = !names && opts.nested @@ -210,11 +209,7 @@ async function _validate(opts: { name?: keyof I | (keyof I)[], silent?: boolean, throw new FormValidationException(formId, errors.value, childErrors) } - if (opts.transform) { - Object.assign(props.state, transformedState.value) - } - - return props.state as O + return transformedState.value } const loading = ref(false) @@ -226,7 +221,7 @@ async function onSubmitWrapper(payload: Event) { const event = payload as FormSubmitEvent try { - event.data = await _validate({ nested: true, transform: props.transform }) + event.data = await _validate({ nested: true }) await props.onSubmit?.(event) dirtyFields.clear() } catch (error) {