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>
This commit is contained in:
@@ -28,6 +28,95 @@ const width: Field = {
|
||||
label: 'Field Width (percentage)',
|
||||
}
|
||||
|
||||
const placeholder: Field = {
|
||||
name: 'placeholder',
|
||||
type: 'text',
|
||||
label: 'Placeholder',
|
||||
}
|
||||
|
||||
const Radio: Block = {
|
||||
slug: 'radio',
|
||||
fields: [
|
||||
{
|
||||
type: 'row',
|
||||
fields: [
|
||||
{
|
||||
...name,
|
||||
admin: {
|
||||
width: '50%',
|
||||
},
|
||||
},
|
||||
{
|
||||
...label,
|
||||
admin: {
|
||||
width: '50%',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'row',
|
||||
fields: [
|
||||
{
|
||||
...width,
|
||||
admin: {
|
||||
width: '50%',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'defaultValue',
|
||||
type: 'text',
|
||||
admin: {
|
||||
width: '50%',
|
||||
},
|
||||
label: 'Default Value',
|
||||
localized: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'options',
|
||||
type: 'array',
|
||||
fields: [
|
||||
{
|
||||
type: 'row',
|
||||
fields: [
|
||||
{
|
||||
name: 'label',
|
||||
type: 'text',
|
||||
admin: {
|
||||
width: '50%',
|
||||
},
|
||||
label: 'Label',
|
||||
localized: true,
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'value',
|
||||
type: 'text',
|
||||
admin: {
|
||||
width: '50%',
|
||||
},
|
||||
label: 'Value',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
label: 'Radio Attribute Options',
|
||||
labels: {
|
||||
plural: 'Options',
|
||||
singular: 'Option',
|
||||
},
|
||||
},
|
||||
required,
|
||||
],
|
||||
labels: {
|
||||
plural: 'Radio Fields',
|
||||
singular: 'Radio',
|
||||
},
|
||||
}
|
||||
|
||||
const Select: Block = {
|
||||
slug: 'select',
|
||||
fields: [
|
||||
@@ -68,6 +157,14 @@ const Select: Block = {
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'row',
|
||||
fields: [
|
||||
{
|
||||
...placeholder,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'options',
|
||||
type: 'array',
|
||||
@@ -576,6 +673,7 @@ export const fields = {
|
||||
message: Message,
|
||||
number: Number,
|
||||
payment: Payment,
|
||||
radio: Radio,
|
||||
select: Select,
|
||||
state: State,
|
||||
text: Text,
|
||||
|
||||
@@ -97,6 +97,19 @@ export interface SelectField {
|
||||
label?: string
|
||||
name: string
|
||||
options: SelectFieldOption[]
|
||||
placeholder?: string
|
||||
required?: boolean
|
||||
width?: number
|
||||
}
|
||||
|
||||
export interface RadioField {
|
||||
blockName?: string
|
||||
blockType: 'radio'
|
||||
defaultValue?: string
|
||||
label?: string
|
||||
name: string
|
||||
options: SelectFieldOption[]
|
||||
placeholder?: string
|
||||
required?: boolean
|
||||
width?: number
|
||||
}
|
||||
@@ -175,6 +188,7 @@ export type FormFieldBlock =
|
||||
| EmailField
|
||||
| MessageField
|
||||
| PaymentField
|
||||
| RadioField
|
||||
| SelectField
|
||||
| StateField
|
||||
| TextAreaField
|
||||
|
||||
Reference in New Issue
Block a user