Skip to content

Commit 427a5f1

Browse files
feat(plugin-form-builder): radio field (#11716)
### What? A field for input radio Demo: <img width="1320" alt="Screenshot 2025-03-15 at 6 54 51 AM" src="https://github.com/user-attachments/assets/47744e3f-e1ca-4596-bc7c-09f7b2d42c5b" /> --- UI code example, using shadcn/ui: ```tsx import type { SelectField } from '@payloadcms/plugin-form-builder/types' import type { Control, FieldErrorsImpl } from 'react-hook-form' import { Label } from '@/components/ui/label' import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group' import React from 'react' import { Controller } from 'react-hook-form' import { Error } from '../Error' import { Width } from '../Width' export const Radio: React.FC< SelectField & { control: Control errors: Partial<FieldErrorsImpl> } > = ({ name, control, errors, label, options, required, width, defaultValue }) => { return ( <Width width={width}> <Label htmlFor={name}>{label}</Label> <Controller control={control} defaultValue={defaultValue} name={name} render={({ field: { onChange, value } }) => { return ( <RadioGroup onValueChange={(val) => onChange(val)} value={value} className="space-y-2"> {options.map(({ label, value }) => { const id = `${name}-${value}` return ( <div key={value} className="flex items-center space-x-2"> <RadioGroupItem value={value} id={id} /> <Label htmlFor={id}>{label}</Label> </div> ) })} </RadioGroup> ) }} rules={{ required }} /> {required && errors[name] && <Error />} </Width> ) } ``` UI demo: <img width="651" alt="Screenshot 2025-03-15 at 7 04 37 AM" src="https://github.com/user-attachments/assets/f3922489-8e62-4464-b48c-8425735421f5" /> Co-authored-by: Pan <kpkong@hk01.com>
1 parent 9f9db3f commit 427a5f1

File tree

2 files changed

+112
-0
lines changed

2 files changed

+112
-0
lines changed

packages/plugin-form-builder/src/collections/Forms/fields.ts

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,95 @@ const width: Field = {
2828
label: 'Field Width (percentage)',
2929
}
3030

31+
const placeholder: Field = {
32+
name: 'placeholder',
33+
type: 'text',
34+
label: 'Placeholder',
35+
}
36+
37+
const Radio: Block = {
38+
slug: 'radio',
39+
fields: [
40+
{
41+
type: 'row',
42+
fields: [
43+
{
44+
...name,
45+
admin: {
46+
width: '50%',
47+
},
48+
},
49+
{
50+
...label,
51+
admin: {
52+
width: '50%',
53+
},
54+
},
55+
],
56+
},
57+
{
58+
type: 'row',
59+
fields: [
60+
{
61+
...width,
62+
admin: {
63+
width: '50%',
64+
},
65+
},
66+
{
67+
name: 'defaultValue',
68+
type: 'text',
69+
admin: {
70+
width: '50%',
71+
},
72+
label: 'Default Value',
73+
localized: true,
74+
},
75+
],
76+
},
77+
{
78+
name: 'options',
79+
type: 'array',
80+
fields: [
81+
{
82+
type: 'row',
83+
fields: [
84+
{
85+
name: 'label',
86+
type: 'text',
87+
admin: {
88+
width: '50%',
89+
},
90+
label: 'Label',
91+
localized: true,
92+
required: true,
93+
},
94+
{
95+
name: 'value',
96+
type: 'text',
97+
admin: {
98+
width: '50%',
99+
},
100+
label: 'Value',
101+
required: true,
102+
},
103+
],
104+
},
105+
],
106+
label: 'Radio Attribute Options',
107+
labels: {
108+
plural: 'Options',
109+
singular: 'Option',
110+
},
111+
},
112+
required,
113+
],
114+
labels: {
115+
plural: 'Radio Fields',
116+
singular: 'Radio',
117+
},
118+
}
119+
31120
const Select: Block = {
32121
slug: 'select',
33122
fields: [
@@ -68,6 +157,14 @@ const Select: Block = {
68157
},
69158
],
70159
},
160+
{
161+
type: 'row',
162+
fields: [
163+
{
164+
...placeholder,
165+
},
166+
],
167+
},
71168
{
72169
name: 'options',
73170
type: 'array',
@@ -576,6 +673,7 @@ export const fields = {
576673
message: Message,
577674
number: Number,
578675
payment: Payment,
676+
radio: Radio,
579677
select: Select,
580678
state: State,
581679
text: Text,

packages/plugin-form-builder/src/types.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,19 @@ export interface SelectField {
9797
label?: string
9898
name: string
9999
options: SelectFieldOption[]
100+
placeholder?: string
101+
required?: boolean
102+
width?: number
103+
}
104+
105+
export interface RadioField {
106+
blockName?: string
107+
blockType: 'radio'
108+
defaultValue?: string
109+
label?: string
110+
name: string
111+
options: SelectFieldOption[]
112+
placeholder?: string
100113
required?: boolean
101114
width?: number
102115
}
@@ -175,6 +188,7 @@ export type FormFieldBlock =
175188
| EmailField
176189
| MessageField
177190
| PaymentField
191+
| RadioField
178192
| SelectField
179193
| StateField
180194
| TextAreaField

0 commit comments

Comments
 (0)