@@ -656,6 +656,184 @@ test('reports required state for schema intersections with nested fields', async
656656 ) ;
657657} ) ;
658658
659+ test ( 'reports required state for variant schemas' , async ( ) => {
660+ const metaSpy = vi . fn ( ) ;
661+ mountWithHoc ( {
662+ setup ( ) {
663+ const ScheduledDateSchema = v . object ( {
664+ dateType : v . literal ( 'schedule' ) ,
665+ date : v . pipe ( v . string ( ) , v . isoDate ( ) ) ,
666+ } ) ;
667+
668+ const ImmediateDateSchema = v . object ( {
669+ dateType : v . literal ( 'immediate' ) ,
670+ } ) ;
671+
672+ const PaymentDetailsFormSchema = v . variant ( 'dateType' , [ ImmediateDateSchema , ScheduledDateSchema ] ) ;
673+
674+ const schema = toTypedSchema ( PaymentDetailsFormSchema ) ;
675+
676+ useForm ( {
677+ validationSchema : schema ,
678+ } ) ;
679+
680+ const { meta : dateType } = useField ( 'dateType' ) ;
681+ const { meta : date } = useField ( 'date' ) ;
682+
683+ metaSpy ( {
684+ dateType : dateType . required ,
685+ date : date . required ,
686+ } ) ;
687+
688+ return {
689+ schema,
690+ } ;
691+ } ,
692+ template : `<div></div>` ,
693+ } ) ;
694+
695+ await flushPromises ( ) ;
696+ await expect ( metaSpy ) . toHaveBeenLastCalledWith (
697+ expect . objectContaining ( {
698+ dateType : true ,
699+ date : true ,
700+ } ) ,
701+ ) ;
702+ } ) ;
703+
704+ test ( 'reports required state for variant schemas with nested fields' , async ( ) => {
705+ const metaSpy = vi . fn ( ) ;
706+ mountWithHoc ( {
707+ setup ( ) {
708+ const ComplexVariantSchema = v . variant ( 'kind' , [
709+ v . variant ( 'type' , [
710+ v . object ( {
711+ kind : v . literal ( 'fruit' ) ,
712+ type : v . literal ( 'apple' ) ,
713+ item : v . object ( {
714+ name : v . string ( ) ,
715+ price : v . number ( ) ,
716+ } ) ,
717+ } ) ,
718+ v . object ( {
719+ kind : v . literal ( 'fruit' ) ,
720+ type : v . literal ( 'banana' ) ,
721+ item : v . object ( {
722+ name : v . string ( ) ,
723+ price : v . number ( ) ,
724+ } ) ,
725+ } ) ,
726+ ] ) ,
727+ v . variant ( 'type' , [
728+ v . object ( {
729+ kind : v . literal ( 'vegetable' ) ,
730+ type : v . literal ( 'carrot' ) ,
731+ item : v . object ( {
732+ name : v . string ( ) ,
733+ price : v . number ( ) ,
734+ } ) ,
735+ } ) ,
736+ v . object ( {
737+ kind : v . literal ( 'vegetable' ) ,
738+ type : v . literal ( 'tomato' ) ,
739+ item : v . object ( {
740+ name : v . string ( ) ,
741+ price : v . number ( ) ,
742+ } ) ,
743+ } ) ,
744+ ] ) ,
745+ ] ) ;
746+
747+ const schema = toTypedSchema ( ComplexVariantSchema ) ;
748+
749+ useForm ( {
750+ validationSchema : schema ,
751+ } ) ;
752+
753+ const { meta : kind } = useField ( 'kind' ) ;
754+ const { meta : type } = useField ( 'type' ) ;
755+ const { meta : item } = useField ( 'item' ) ;
756+
757+ metaSpy ( {
758+ kind : kind . required ,
759+ type : type . required ,
760+ item : item . required ,
761+ } ) ;
762+
763+ return {
764+ schema,
765+ } ;
766+ } ,
767+ template : `<div></div>` ,
768+ } ) ;
769+
770+ await flushPromises ( ) ;
771+ await expect ( metaSpy ) . toHaveBeenLastCalledWith (
772+ expect . objectContaining ( {
773+ kind : true ,
774+ type : true ,
775+ item : true ,
776+ } ) ,
777+ ) ;
778+ } ) ;
779+
780+ test ( 'reports required state for variant schemas when combined with intersections' , async ( ) => {
781+ const metaSpy = vi . fn ( ) ;
782+ mountWithHoc ( {
783+ setup ( ) {
784+ const ScheduledDateSchema = v . object ( {
785+ dateType : v . literal ( 'schedule' ) ,
786+ date : v . pipe ( v . string ( ) , v . isoDate ( ) ) ,
787+ } ) ;
788+
789+ const ImmediateDateSchema = v . object ( {
790+ dateType : v . literal ( 'immediate' ) ,
791+ } ) ;
792+
793+ const PaymentDetailsFormSchema = v . intersect ( [
794+ v . variant ( 'dateType' , [ ImmediateDateSchema , ScheduledDateSchema ] ) ,
795+ v . object ( {
796+ amount : v . pipe ( v . number ( ) , v . minValue ( 1 ) ) ,
797+ note : v . optional ( v . string ( ) ) ,
798+ } ) ,
799+ ] ) ;
800+
801+ const schema = toTypedSchema ( PaymentDetailsFormSchema ) ;
802+
803+ useForm ( {
804+ validationSchema : schema ,
805+ } ) ;
806+
807+ const { meta : dateType } = useField ( 'dateType' ) ;
808+ const { meta : date } = useField ( 'date' ) ;
809+ const { meta : amount } = useField ( 'amount' ) ;
810+ const { meta : note } = useField ( 'note' ) ;
811+
812+ metaSpy ( {
813+ dateType : dateType . required ,
814+ date : date . required ,
815+ amount : amount . required ,
816+ note : note . required ,
817+ } ) ;
818+
819+ return {
820+ schema,
821+ } ;
822+ } ,
823+ template : `<div></div>` ,
824+ } ) ;
825+
826+ await flushPromises ( ) ;
827+ await expect ( metaSpy ) . toHaveBeenLastCalledWith (
828+ expect . objectContaining ( {
829+ dateType : true ,
830+ date : true ,
831+ amount : true ,
832+ note : false ,
833+ } ) ,
834+ ) ;
835+ } ) ;
836+
659837test ( 'allows passing valibot config' , async ( ) => {
660838 let errors ! : Ref < string [ ] > ;
661839 const wrapper = mountWithHoc ( {
0 commit comments