Skip to content

Commit

Permalink
feat: allow null as a valid Form prop type closes #4483
Browse files Browse the repository at this point in the history
  • Loading branch information
logaretm committed Sep 29, 2023
1 parent a0d34ce commit 78c4668
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 8 deletions.
5 changes: 5 additions & 0 deletions .changeset/green-wolves-reply.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'vee-validate': patch
---

feat: allow null as a valid Form prop type closes #4483
8 changes: 4 additions & 4 deletions packages/vee-validate/src/Form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const FormImpl = /** #__PURE__ */ defineComponent({
inheritAttrs: false,
props: {
as: {
type: String,
type: null as unknown as PropType<string | null>,
default: 'form',
},
validationSchema: {
Expand Down Expand Up @@ -196,16 +196,16 @@ const FormImpl = /** #__PURE__ */ defineComponent({

return function renderForm() {
// avoid resolving the form component as itself
const tag = props.as === 'form' ? props.as : (resolveDynamicComponent(props.as) as string);
const tag = props.as === 'form' ? props.as : !props.as ? null : (resolveDynamicComponent(props.as) as string);
const children = normalizeChildren(tag, ctx, slotProps as any);

if (!props.as) {
if (!tag) {
return children;
}

// Attributes to add on a native `form` tag
const formAttrs =
props.as === 'form'
tag === 'form'
? {
// Disables native validation as vee-validate will handle it.
novalidate: true,
Expand Down
8 changes: 4 additions & 4 deletions packages/vee-validate/src/utils/vnode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import { SetupContext } from 'vue';
type HTMLElementWithValueBinding = HTMLElement & { _value: unknown };

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const normalizeChildren = (
tag: string | Record<string, unknown> | undefined,
export function normalizeChildren(
tag: string | null,
context: SetupContext<any>,
slotProps: () => Record<string, unknown>,
) => {
) {
if (!context.slots.default) {
return context.slots.default;
}
Expand All @@ -19,7 +19,7 @@ export const normalizeChildren = (
return {
default: () => context.slots.default?.(slotProps()),
};
};
}

/**
* Vue adds a `_value` prop at the moment on the input elements to store the REAL value on them, real values are different than the `value` attribute
Expand Down
33 changes: 33 additions & 0 deletions packages/vee-validate/tests/Form.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,39 @@ describe('<Form />', () => {
expect(submitMock).toHaveBeenCalledTimes(1);
});

test('can be renderless with null', async () => {
const submitMock = vi.fn();
const wrapper = mountWithHoc({
template: `
<div>
<VForm :as="null" v-slot="{ errors, submitForm }">
<form @submit="submitForm">
<Field name="field" rules="required" />
<span id="error">{{ errors.field }}</span>
<button>Validate</button>
</form>
</VForm>
</div>
`,
});

const form = wrapper.$el.querySelector('form');
form.submit = submitMock;
const input = wrapper.$el.querySelector('input');
await flushPromises();

wrapper.$el.querySelector('button').click();
await flushPromises();
expect(submitMock).toHaveBeenCalledTimes(0);

setValue(input, '12');
wrapper.$el.querySelector('button').click();
await flushPromises();

expect(submitMock).toHaveBeenCalledTimes(1);
});

test('validation schema with yup', async () => {
const wrapper = mountWithHoc({
setup() {
Expand Down

0 comments on commit 78c4668

Please sign in to comment.