diff --git a/Documentation/CommandForm/radio-button-field.md b/Documentation/CommandForm/radio-button-field.md new file mode 100644 index 0000000..8957e8f --- /dev/null +++ b/Documentation/CommandForm/radio-button-field.md @@ -0,0 +1,30 @@ +# RadioButtonField + +`RadioButtonField` renders a single PrimeReact `RadioButton` that sets the bound command property to a specific value when selected. Use multiple `RadioButtonField` components bound to the same property to form a radio group. + +## Usage + +```tsx +import { CommandDialog } from '@cratis/components'; +import { RadioButtonField } from '@cratis/components/CommandForm'; + + setVisible(false)}> + value={c => c.size} buttonValue="small" label="Small" /> + value={c => c.size} buttonValue="medium" label="Medium" /> + value={c => c.size} buttonValue="large" label="Large" /> + +``` + +## Props + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `value` | `(instance: TCommand) => unknown` | — | **Required.** Accessor function that returns the bound property from the command instance. Pass the command type as the generic parameter for full type safety. | +| `buttonValue` | `string \| number` | — | **Required.** The value this radio button represents. When selected, the command property is set to this value. | +| `label` | `string` | — | Text displayed inline next to the radio button. | + +## Behavior + +- Default value is an empty string. +- The radio button is checked when the current field value equals `buttonValue`. +- Validation state is reflected via the PrimeReact `invalid` flag on the radio button. diff --git a/Documentation/CommandForm/radio-group-field.md b/Documentation/CommandForm/radio-group-field.md new file mode 100644 index 0000000..0a07200 --- /dev/null +++ b/Documentation/CommandForm/radio-group-field.md @@ -0,0 +1,55 @@ +# RadioGroupField + +`RadioGroupField` renders a group of PrimeReact `RadioButton` components from an options array, allowing the user to select a single value. + +## Usage + +```tsx +import { CommandDialog } from '@cratis/components'; +import { RadioGroupField } from '@cratis/components/CommandForm'; + +const sizeOptions = [ + { id: 'small', label: 'Small' }, + { id: 'medium', label: 'Medium' }, + { id: 'large', label: 'Large' }, +]; + + setVisible(false)}> + + value={c => c.size} + options={sizeOptions} + optionLabel="label" + optionValue="id" + title="Size" + /> + +``` + +With horizontal layout: + +```tsx + + value={c => c.priority} + options={priorityOptions} + optionLabel="label" + optionValue="id" + title="Priority" + layout="horizontal" +/> +``` + +## Props + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `value` | `(instance: TCommand) => unknown` | — | **Required.** Accessor function that returns the bound property from the command instance. Pass the command type as the generic parameter for full type safety. | +| `options` | `Array>` | — | **Required.** Array of option objects. | +| `optionLabel` | `string` | — | **Required.** Key in each option object to use as the display label. | +| `optionValue` | `string` | — | **Required.** Key in each option object to use as the submitted value. | +| `layout` | `'horizontal' \| 'vertical'` | `'vertical'` | Controls whether the radio buttons are stacked vertically or laid out in a horizontal row. | + +## Behavior + +- Default value is an empty string. +- A radio button is checked when the current field value equals its `optionValue`. +- Validation state is reflected via the PrimeReact `invalid` flag on all radio buttons. diff --git a/Documentation/CommandForm/toc.yml b/Documentation/CommandForm/toc.yml index 8584119..5e7cefb 100644 --- a/Documentation/CommandForm/toc.yml +++ b/Documentation/CommandForm/toc.yml @@ -16,6 +16,10 @@ href: multi-select-field.md - name: NumberField href: number-field.md +- name: RadioButtonField + href: radio-button-field.md +- name: RadioGroupField + href: radio-group-field.md - name: SliderField href: slider-field.md - name: TextAreaField diff --git a/Source/CommandForm/fields/Fields.stories.tsx b/Source/CommandForm/fields/Fields.stories.tsx index 55fa4bc..5b2943f 100644 --- a/Source/CommandForm/fields/Fields.stories.tsx +++ b/Source/CommandForm/fields/Fields.stories.tsx @@ -18,7 +18,9 @@ import { CalendarField, ColorPickerField, MultiSelectField, - ChipsField + ChipsField, + RadioButtonField, + RadioGroupField } from './index'; const meta: Meta = { @@ -48,6 +50,8 @@ class FormFieldsCommand extends Command { new PropertyDescriptor('color', String), new PropertyDescriptor('multiSelect', Array), new PropertyDescriptor('chips', Array), + new PropertyDescriptor('radioButton', String), + new PropertyDescriptor('radioGroup', String), ]; textInput = ''; @@ -62,6 +66,8 @@ class FormFieldsCommand extends Command { color = ''; multiSelect: Array = []; chips: string[] = []; + radioButton = ''; + radioGroup = ''; constructor() { super(Object, false); @@ -84,7 +90,9 @@ class FormFieldsCommand extends Command { 'calendarDate', 'color', 'multiSelect', - 'chips' + 'chips', + 'radioButton', + 'radioGroup' ]; } } @@ -145,6 +153,8 @@ export const AllFields: Story = { color: '10b981', multiSelect: ['feature1', 'feature3'], chips: ['alpha', 'beta'], + radioButton: '', + radioGroup: '', }} onFieldChange={async (command, fieldName) => { // Validate on field change @@ -358,6 +368,43 @@ export const AllFields: Story = { + +

Radio Button

+ + + value={c => c.radioButton} + buttonValue="option1" + label="Option 1" + /> + + value={c => c.radioButton} + buttonValue="option2" + label="Option 2" + /> + + value={c => c.radioButton} + buttonValue="option3" + label="Option 3" + /> +
+ + + + +

Radio Group

+ + + value={c => c.radioGroup} + title="Radio Group Field" + description="Radio buttons from an options array" + options={dropdownOptions} + optionValue="id" + optionLabel="name" + /> +
+ + +