Skip to content

Commit 0bc30f5

Browse files
author
Ruben van Leeuwen
committed
1694: Adds radio field
1 parent 7aae301 commit 0bc30f5

File tree

4 files changed

+65
-3
lines changed

4 files changed

+65
-3
lines changed

backend/main.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,12 @@ class DropdownChoices(Choice):
8282
_4 = ("4", "Option 4")
8383

8484

85+
class RadioChoices(Choice):
86+
_1 = ("1", "Option 1")
87+
_2 = ("2", "Option 2")
88+
_3 = ("3", "Option 3")
89+
90+
8591
@app.post("/form")
8692
async def form(form_data: list[dict] = []):
8793
def form_generator(state: State):
@@ -94,7 +100,12 @@ class TestForm(FormPage):
94100
divider: Divider
95101
label: Label = "Label"
96102
hidden: Hidden = "Hidden"
97-
dropdown: DropdownChoices = "2"
103+
dropdown: DropdownChoices = (
104+
"2" # When there are > 3 choices a dropdown will be rendered
105+
)
106+
radio: RadioChoices = (
107+
"3" # When there are <= 3 choices a radio group will be rendered
108+
)
98109

99110
form_data_1 = yield TestForm
100111

frontend/packages/pydantic-forms/src/components/defaultComponentMatchers.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
HiddenField,
1010
IntegerField,
1111
LabelField,
12+
RadioField,
1213
TextAreaField,
1314
} from '@/components/fields';
1415
import {
@@ -84,17 +85,32 @@ const defaultComponentMatchers: PydanticComponentMatcher[] = [
8485
);
8586
},
8687
},
88+
{
89+
id: 'radio',
90+
ElementMatch: {
91+
Element: RadioField,
92+
isControlledElement: true,
93+
},
94+
matcher(field) {
95+
// We are looking for a single value from a set list of options. With less than 4 options, use radio buttons.
96+
return (
97+
field.type === PydanticFormFieldType.STRING &&
98+
field.options.length > 0 &&
99+
field.options.length <= 3
100+
);
101+
},
102+
},
87103
{
88104
id: 'dropdown',
89105
ElementMatch: {
90106
Element: DropdownField,
91107
isControlledElement: true,
92108
},
93109
matcher(field) {
94-
// We are looking for a single value from a set list of options. Use a dropdown.
110+
// We are looking for a single value from a set list of options. With more than 3 options, use a dropdown.
95111
return (
96112
field.type === PydanticFormFieldType.STRING &&
97-
field.options.length > 0
113+
field.options.length >= 4
98114
);
99115
},
100116
},
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/**
2+
* Pydantic Forms
3+
*
4+
* Text component
5+
*/
6+
import React from 'react';
7+
8+
import { PydanticFormControlledElementProps } from '@/types';
9+
10+
export const RadioField = ({
11+
value,
12+
onChange,
13+
pydanticFormField,
14+
}: PydanticFormControlledElementProps) => {
15+
const { options, id } = pydanticFormField;
16+
17+
return (
18+
<div>
19+
{options.map((option, key) => (
20+
<div key={key}>
21+
<input
22+
type="radio"
23+
id={option.value}
24+
name={id}
25+
value={option.value}
26+
checked={value === option.value}
27+
onChange={(e) => onChange(e.target.value)}
28+
/>
29+
 <label htmlFor={option.value}>{option.label}</label>
30+
</div>
31+
))}
32+
</div>
33+
);
34+
};

frontend/packages/pydantic-forms/src/components/fields/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ export * from './LabelField';
77
export * from './DividerField';
88
export * from './HiddenField';
99
export * from './DropdownField';
10+
export * from './RadioField';

0 commit comments

Comments
 (0)