File tree Expand file tree Collapse file tree 7 files changed +87
-10
lines changed
frontend/packages/pydantic-forms/src/components Expand file tree Collapse file tree 7 files changed +87
-10
lines changed Original file line number Diff line number Diff line change @@ -19,4 +19,5 @@ __pycache__/
1919test
2020.idea
2121todo.md
22- venv
22+ venv /
23+ .venv /
Original file line number Diff line number Diff line change @@ -31,6 +31,8 @@ $ npm run dev
3131
3232Visit [ http://127.0.0.1:3000 ] [ 5 ] to view the generated form
3333
34+ to also regenerate the pydantic forms ui package, also perform those steps in ` pydantic-forms-ui/frontend/packages/pydantic-forms/ `
35+
3436## Contributing
3537
3638When setting up this repo to contribute initialize the pre-commit hooks using [ pre-commit] [ 6 ] (eq. ` brew install pre-commit ` ).
Original file line number Diff line number Diff line change @@ -102,15 +102,25 @@ class MultiCheckBoxChoices(Choice):
102102 _4 = ("4" , "Option 4" )
103103
104104
105+ class ListChoices (Choice ):
106+ _0 = ("0" , "Option 0" )
107+ _1 = ("1" , "Option 1" )
108+ _2 = ("2" , "Option 2" )
109+ _3 = ("3" , "Option 3" )
110+ _4 = ("4" , "Option 4" )
111+ _5 = ("5" , "Option 5" )
112+ _6 = ("6" , "Option 6" )
113+
114+
105115@app .post ("/form" )
106116async def form (form_data : list [dict ] = []):
107117 def form_generator (state : State ):
108118 class TestForm (FormPage ):
109119 model_config = ConfigDict (title = "Form Title" )
110120
111- number : NumberExample
121+ number : NumberExample = 3
112122 text : Annotated [str , Field (min_length = 3 , max_length = 12 )] = "Default text"
113- textArea : LongText
123+ textArea : LongText = "Default text area"
114124 divider : Divider
115125 label : Label = "Label"
116126 hidden : Hidden = "Hidden"
@@ -119,7 +129,9 @@ class TestForm(FormPage):
119129 # When there are <= 3 choices a radio group will be rendered
120130 radio : RadioChoices = "3"
121131 checkbox : bool = True
122- multicheckbox : choice_list (MultiCheckBoxChoices , min_items = 3 )
132+ # When there are <= 5 choices in a list a set of checkboxes are rendered
133+ multicheckbox : choice_list (MultiCheckBoxChoices ) = ["1" , "2" ]
134+ list : choice_list (ListChoices ) = [0 , 1 ]
123135
124136 form_data_1 = yield TestForm
125137
Original file line number Diff line number Diff line change @@ -10,6 +10,7 @@ import {
1010 HiddenField ,
1111 IntegerField ,
1212 LabelField ,
13+ ListField ,
1314 MultiCheckboxField ,
1415 RadioField ,
1516 TextAreaField ,
@@ -133,15 +134,25 @@ const defaultComponentMatchers: PydanticComponentMatcher[] = [
133134 isControlledElement : true ,
134135 } ,
135136 matcher ( field ) {
136- // Use this component when we have multiple boolean options (5 or more)
137137 return (
138138 field . type === PydanticFormFieldType . ARRAY &&
139139 field . options . length <= 5
140140 ) ;
141141 } ,
142142 validator : zodValidationPresets . array ,
143143 } ,
144+ {
145+ id : 'list' ,
146+ ElementMatch : {
147+ Element : ListField ,
148+ isControlledElement : true ,
149+ } ,
150+ matcher ( field ) {
151+ return field . type === PydanticFormFieldType . ARRAY ;
152+ } ,
153+ validator : zodValidationPresets . array ,
154+ } ,
144155] ;
145156
146- // If nothing matches, it defaults to Text field in the mapToComponent function
157+ // If nothing matches, it defaults to Text field in the mapToComponent function
147158export default defaultComponentMatchers ;
Original file line number Diff line number Diff line change 1+ /**
2+ * Pydantic Forms
3+ *
4+ * List component for multiple choice items
5+ */
6+ import React , { useState } from 'react' ;
7+
8+ import {
9+ PydanticFormControlledElementProps ,
10+ PydanticFormFieldOption ,
11+ } from '@/types' ;
12+
13+ export const ListField = ( {
14+ value,
15+ onChange,
16+ onBlur,
17+ disabled,
18+ pydanticFormField,
19+ } : PydanticFormControlledElementProps & {
20+ options ?: Array < { value : string ; label : string } > ;
21+ } ) => {
22+ const [ listItems , setListItems ] = useState ( value || [ ] ) ;
23+
24+ return (
25+ < div >
26+ < select
27+ onBlur = { onBlur }
28+ disabled = { disabled }
29+ value = { listItems }
30+ onChange = { ( e ) => {
31+ const selectedValues = Array . from (
32+ e . currentTarget . selectedOptions ,
33+ ( option ) => option . value ,
34+ ) ;
35+ setListItems ( selectedValues ) ;
36+ onChange ( selectedValues ) ;
37+ } }
38+ multiple
39+ >
40+ { pydanticFormField . options . map (
41+ ( option : PydanticFormFieldOption ) => (
42+ < option key = { option . value } value = { option . value } >
43+ { option . label }
44+ </ option >
45+ ) ,
46+ ) }
47+ </ select >
48+ </ div >
49+ ) ;
50+ } ;
Original file line number Diff line number Diff line change @@ -10,3 +10,4 @@ export * from './HiddenField';
1010export * from './DropdownField' ;
1111export * from './RadioField' ;
1212export * from './MultiCheckboxField' ;
13+ export * from './ListField' ;
Original file line number Diff line number Diff line change @@ -113,22 +113,22 @@ export const zodValidationPresets: PydanticFormZodValidationPresets = {
113113 array : ( field ) => {
114114 const { minimum, maximum } = field ?. validation ?? { } ;
115115
116- let arraySchema = z . array ( z . boolean ( ) ) ;
116+ let validationRule = z . array ( z . boolean ( ) ) ;
117117
118118 if ( minimum ) {
119- arraySchema = arraySchema . min (
119+ validationRule = validationRule . min (
120120 minimum ,
121121 `Dit veld heeft een minimum waarde van ${ minimum } ` ,
122122 ) ;
123123 }
124124
125125 if ( maximum ) {
126- arraySchema = arraySchema . max (
126+ validationRule = validationRule . max (
127127 maximum ,
128128 `Dit veld heeft een maximum waarde van ${ maximum } ` ,
129129 ) ;
130130 }
131131
132- return arraySchema ;
132+ return validationRule ;
133133 } ,
134134} ;
You can’t perform that action at this time.
0 commit comments