File tree Expand file tree Collapse file tree 4 files changed +46
-8
lines changed
Expand file tree Collapse file tree 4 files changed +46
-8
lines changed Original file line number Diff line number Diff line change 1+ ---
2+ ' vee-validate ' : patch
3+ ---
4+
5+ feat: allow null as a valid Form prop type closes #4483
Original file line number Diff line number Diff line change @@ -40,7 +40,7 @@ const FormImpl = /** #__PURE__ */ defineComponent({
4040 inheritAttrs : false ,
4141 props : {
4242 as : {
43- type : String ,
43+ type : null as unknown as PropType < string | null > ,
4444 default : 'form' ,
4545 } ,
4646 validationSchema : {
@@ -196,16 +196,16 @@ const FormImpl = /** #__PURE__ */ defineComponent({
196196
197197 return function renderForm ( ) {
198198 // avoid resolving the form component as itself
199- const tag = props . as === 'form' ? props . as : ( resolveDynamicComponent ( props . as ) as string ) ;
199+ const tag = props . as === 'form' ? props . as : ! props . as ? null : ( resolveDynamicComponent ( props . as ) as string ) ;
200200 const children = normalizeChildren ( tag , ctx , slotProps as any ) ;
201201
202- if ( ! props . as ) {
202+ if ( ! tag ) {
203203 return children ;
204204 }
205205
206206 // Attributes to add on a native `form` tag
207207 const formAttrs =
208- props . as === 'form'
208+ tag === 'form'
209209 ? {
210210 // Disables native validation as vee-validate will handle it.
211211 novalidate : true ,
Original file line number Diff line number Diff line change @@ -3,11 +3,11 @@ import { SetupContext } from 'vue';
33type HTMLElementWithValueBinding = HTMLElement & { _value : unknown } ;
44
55// eslint-disable-next-line @typescript-eslint/no-explicit-any
6- export const normalizeChildren = (
7- tag : string | Record < string , unknown > | undefined ,
6+ export function normalizeChildren (
7+ tag : string | null ,
88 context : SetupContext < any > ,
99 slotProps : ( ) => Record < string , unknown > ,
10- ) => {
10+ ) {
1111 if ( ! context . slots . default ) {
1212 return context . slots . default ;
1313 }
@@ -19,7 +19,7 @@ export const normalizeChildren = (
1919 return {
2020 default : ( ) => context . slots . default ?.( slotProps ( ) ) ,
2121 } ;
22- } ;
22+ }
2323
2424/**
2525 * 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
Original file line number Diff line number Diff line change @@ -351,6 +351,39 @@ describe('<Form />', () => {
351351 expect ( submitMock ) . toHaveBeenCalledTimes ( 1 ) ;
352352 } ) ;
353353
354+ test ( 'can be renderless with null' , async ( ) => {
355+ const submitMock = vi . fn ( ) ;
356+ const wrapper = mountWithHoc ( {
357+ template : `
358+ <div>
359+ <VForm :as="null" v-slot="{ errors, submitForm }">
360+ <form @submit="submitForm">
361+ <Field name="field" rules="required" />
362+ <span id="error">{{ errors.field }}</span>
363+
364+ <button>Validate</button>
365+ </form>
366+ </VForm>
367+ </div>
368+ ` ,
369+ } ) ;
370+
371+ const form = wrapper . $el . querySelector ( 'form' ) ;
372+ form . submit = submitMock ;
373+ const input = wrapper . $el . querySelector ( 'input' ) ;
374+ await flushPromises ( ) ;
375+
376+ wrapper . $el . querySelector ( 'button' ) . click ( ) ;
377+ await flushPromises ( ) ;
378+ expect ( submitMock ) . toHaveBeenCalledTimes ( 0 ) ;
379+
380+ setValue ( input , '12' ) ;
381+ wrapper . $el . querySelector ( 'button' ) . click ( ) ;
382+ await flushPromises ( ) ;
383+
384+ expect ( submitMock ) . toHaveBeenCalledTimes ( 1 ) ;
385+ } ) ;
386+
354387 test ( 'validation schema with yup' , async ( ) => {
355388 const wrapper = mountWithHoc ( {
356389 setup ( ) {
You can’t perform that action at this time.
0 commit comments