For the best experience, please view this on a larger device.

For the best experience, please view this on a larger device.

Radio group

A customizable, accessible radio button group for Framer projects. Create interactive form elements with complete design freedom—use your own components for selected and unselected states, or create unique visuals for each option with advanced mode.

Demo

Form Radio Group Component


Overview

The FormRadioGroup component provides a flexible, accessible, and visually customizable radio button group for your Framer forms. Perfect for creating interactive forms, preference selectors, and option pickers while maintaining proper form semantics and accessibility.

Why Use This Component?

For Designers

  • Design Freedom: Complete visual control while maintaining proper form functionality

  • Accessibility Built-in: Screen reader support without extra work

  • Rapid Prototyping: Configure layouts and styles without coding

  • Interactive Feedback: Real working radio functionality in your prototypes

Benefits Over DIY Approaches

  • Proper Form Semantics: Uses actual radio inputs for correct behavior and keyboard navigation

  • Accessibility Compliance: Maintains screen reader compatibility even with custom styling

  • Fewer Variants Needed: No need to create separate variants for every state

  • Simplified Handoff: Developers receive designs with proper semantic structure

Properties Overview

Basic Configuration

  • native (Boolean): Toggle between custom components or native HTML radio buttons

  • name (String): Unique identifier for the radio group

  • defaultOption (String): Pre-selected option value when the component loads

  • hideLabel (Boolean): Visually hides labels while keeping them accessible to screen readers

Content Options

  • options (Array): List of radio button options

    • label (String): Text label for the option

    • value (String): Unique identifier for the option

Visual Customization

  • label (Object): Styling for option labels

    • fontFamily (String): Font family for labels

    • color (Color): Text color

    • fontSize (Number): Text size

Component Visualization

  • Standard Mode (when isAdvanced is off)

    • checkedComponent (ComponentInstance): Component displayed for any selected option

    • uncheckedComponent (ComponentInstance): Component displayed for any unselected option

  • Advanced Mode (when isAdvanced is on)

    • checkedRadioItems (Array of ComponentInstances): Unique component for each option when selected

    • unCheckedRadioItems (Array of ComponentInstances): Unique component for each option when not selected

Layout Configuration

  • layout (Object): Controls how radio options are arranged

    • direction (Enum): "row" or "column" orientation

    • distribute (Enum): Spacing distribution (start, center, end, space-between, etc.)

    • align (Enum): Alignment of items (start, center, end)

    • wrap (Boolean): Whether options should wrap to next line/column

    • gap (Number): Space between each option

Implementation Examples

Basic Example with Custom Components

<FormRadioGroup
  name="color-selector"
  defaultOption="blue"
  options={[
    { label: "Blue", value: "blue" },
    { label: "Red", value: "red" },
    { label: "Green", value: "green" }
  ]}
  layout={{
    direction: "row",
    distribute: "space-between",
    align: "center",
    wrap: false,
    gap: 16
  }}
  label={{
    fontFamily: "Inter",
    color: "#333333",
    fontSize: 14
  }}
  checkedComponent={<RadioSelected />}
  uncheckedComponent={<RadioDefault />}
  native={false}
/>

Advanced Mode Example

When isAdvanced is enabled, you can assign unique visuals to each radio option:

<FormRadioGroup
  name="payment-method"
  defaultOption="credit"
  isAdvanced={true}
  options={[
    { label: "Credit Card", value: "credit" },
    { label: "PayPal", value: "paypal" },
    { label: "Bank Transfer", value: "bank" }
  ]}
  checkedRadioItems={[
    <CreditCardActive />,
    <PayPalActive />,
    <BankActive />
  ]}
  unCheckedRadioItems={[
    <CreditCardInactive />,
    <PayPalInactive />,
    <BankInactive />
  ]}
  layout={{
    direction: "column",
    distribute: "start",
    align: "start",
    wrap: false,
    gap: 12
  }}
/>

Design Tips

Customizing Visual States

  1. Create two components for each state (selected/unselected)

  2. For simple groups, use standard mode with single checked/unchecked components

  3. For varied designs per option, use advanced mode with separate component arrays

Accessibility Best Practices

  • Maintain clear visual distinction between selected and unselected states

  • Use the hideLabel option only when the custom components clearly communicate purpose

  • Ensure sufficient color contrast for labels

Layout Recommendations

  • For horizontal layouts, use row direction with appropriate gap

  • For vertical layouts, use column direction

  • Enable wrap for responsive designs with many options

  • Adjust distribute property based on available space

Working with Developers

This component generates proper semantic HTML radio inputs, making developer handoff smoother. When exporting designs:

  • Mention that actual form fields are used (not just visual components)

  • Note the structure follows standard HTML radio button groups

  • Highlight that accessibility has been maintained in the design

blak/ui