1- // Filepath: /src/DynamicForm.stories.tsx
21import React from 'react' ;
32import { Meta , StoryFn } from '@storybook/react' ;
43import { fn } from '@storybook/test' ;
@@ -36,7 +35,14 @@ BasicInputTypes.args = {
3635 firstName : {
3736 label : 'First Name' ,
3837 type : 'text' ,
39- // defaultValue: 'John',
38+ defaultValue : 'John' ,
39+ inputProps : {
40+ placeholder : 'Enter your first name' ,
41+ } ,
42+ validation : {
43+ required : { value : true , message : 'This field is required' } ,
44+ minLength : { value : 3 , message : 'Minimum length is 3' } ,
45+ } ,
4046 } ,
4147 lastName : {
4248 label : 'Last Name' ,
@@ -52,6 +58,9 @@ BasicInputTypes.args = {
5258 label : 'Age' ,
5359 type : 'number' ,
5460 // defaultValue: 30,
61+ inputProps : {
62+ disabled : true ,
63+ } ,
5564 } ,
5665 subscribe : {
5766 label : 'Subscribe to newsletter?' ,
@@ -75,6 +84,9 @@ AdvancedInputTypes.args = {
7584 label : 'Start Date' ,
7685 type : 'date' ,
7786 defaultValue : '2023-11-20' ,
87+ validation : {
88+ required : { value : true , message : 'Start date is required' } ,
89+ } ,
7890 } ,
7991 startTime : {
8092 label : 'Start Time' ,
@@ -116,16 +128,6 @@ AdvancedInputTypes.args = {
116128 type : 'switch' ,
117129 defaultValue : true ,
118130 } ,
119- favoriteFruit : {
120- label : 'Favorite Fruit' ,
121- type : 'combobox' ,
122- defaultValue : 'Apple' ,
123- options : [
124- { value : 'Apple' , label : 'Apple' } ,
125- { value : 'Banana' , label : 'Banana' } ,
126- { value : 'Orange' , label : 'Orange' } ,
127- ] ,
128- } ,
129131 } ,
130132 onSubmit : ( data ) => {
131133 console . log ( '🚀 ~ file: DynamicForm.stories.tsx ~ data:' , data ) ;
@@ -864,3 +866,69 @@ CustomInput.args = {
864866 onFormReady : fn ( ) ,
865867} ;
866868CustomInput . storyName = 'Custom Input (ColorPicker)' ;
869+
870+ // Story 8: ComboBox Input
871+ // Mock data for ComboBox
872+ const mockComboBoxData = [
873+ { value : 'apple' , label : 'Apple' } ,
874+ { value : 'banana' , label : 'Banana' } ,
875+ { value : 'orange' , label : 'Orange' } ,
876+ { value : 'grape' , label : 'Grape' } ,
877+ { value : 'watermelon' , label : 'Watermelon' } ,
878+ { value : 'pineapple' , label : 'Pineapple' } ,
879+ { value : 'mango' , label : 'Mango' } ,
880+ { value : 'strawberry' , label : 'Strawberry' } ,
881+ { value : 'blueberry' , label : 'Blueberry' } ,
882+ { value : 'raspberry' , label : 'Raspberry' } ,
883+ ] ;
884+
885+ // Mock search API function for ComboBox
886+ const mockSearchApi = async ( params : { query : string } ) => {
887+ return new Promise < { data : { value : string ; label : string } [ ] } > (
888+ ( resolve ) => {
889+ setTimeout ( ( ) => {
890+ const filteredData = mockComboBoxData . filter ( ( item ) =>
891+ item . label . toLowerCase ( ) . includes ( params . query . toLowerCase ( ) )
892+ ) ;
893+ resolve ( { data : filteredData } ) ;
894+ } , 500 ) ; // Simulate 500ms delay
895+ }
896+ ) ;
897+ } ;
898+
899+ export const ComboBoxInput = Template . bind ( { } ) ;
900+ ComboBoxInput . args = {
901+ theme : defaultTheme ,
902+ config : {
903+ favoriteFruit : {
904+ label : 'Favorite Fruit' ,
905+ type : 'combobox' ,
906+ inputProps : {
907+ placeholder : 'Search for a fruit...' ,
908+ searchApi : mockSearchApi ,
909+ noResultsMessage : 'No fruits found.' ,
910+ loadingMessage : 'Loading fruits...' ,
911+ disabled : false ,
912+ required : true ,
913+ } ,
914+ validation : {
915+ validate : ( value ) => {
916+ console . log ( '🚀 ~ file: DynamicForm.stories.tsx ~ value:' , value ) ;
917+ if ( ! value ) {
918+ return 'This field is required' ;
919+ }
920+ if ( value . length < 3 ) {
921+ return 'Please select at least 3 fruits' ;
922+ }
923+ return undefined ;
924+ } ,
925+ } ,
926+ } ,
927+ } ,
928+ onSubmit : ( data ) => {
929+ console . log ( '🚀 ~ file: DynamicForm.stories.tsx ~ data:' , data ) ;
930+ alert ( JSON . stringify ( data ) ) ;
931+ } ,
932+ onFormReady : fn ( ) ,
933+ } ;
934+ ComboBoxInput . storyName = 'ComboBox Input' ;
0 commit comments