← Back to all how-tos

Sidebar controls in depth

Use the Select control

Use the Select control when editors must choose one value from a controlled list, whether as a dropdown, radio buttons, or color swatches.

Estimated time: 7 minRaw Markdown

In this how-to, you'll learn how to use SideEditPropType.Select.

This is one of the most useful sidebar controls because it lets editors choose from a safe set of predefined options instead of typing arbitrary values.

Docs reference: Sidebar controls

When Select is the right tool

Use Select when editors should choose one value from a fixed list, for example:

  • left or right alignment
  • small, medium, or large spacing
  • a design variant such as primary or secondary
  • a theme color

This is often better than a free text field because it prevents invalid values and keeps the design system consistent.

Example with radio buttons

import clsx from 'clsx'
import { Text, types } from 'react-bricks/rsc'
 
interface CallToActionProps {
  title: types.TextValue
  tone: 'primary' | 'secondary'
}
 
const CallToAction: types.Brick<CallToActionProps> = ({ title, tone }) => {
  return (
    <section
      className={clsx(
        'rounded-2xl p-8',
        tone === 'primary'
          ? 'bg-sky-600 text-white'
          : 'bg-slate-100 text-slate-900'
      )}
    >
      <Text
        propName="title"
        value={title}
        placeholder="Call to action..."
        renderBlock={({ children }) => <h2>{children}</h2>}
      />
    </section>
  )
}
 
CallToAction.schema = {
  name: 'call-to-action',
  label: 'Call To Action',
  getDefaultProps: () => ({
    title: 'Start your free trial',
    tone: 'primary',
  }),
  sideEditProps: [
    {
      name: 'tone',
      label: 'Tone',
      type: types.SideEditPropType.Select,
      selectOptions: {
        display: types.OptionsDisplay.Radio,
        options: [
          { value: 'primary', label: 'Primary' },
          { value: 'secondary', label: 'Secondary' },
        ],
      },
    },
  ],
}

The 3 display modes

selectOptions.display can render the same control in 3 different ways:

  • types.OptionsDisplay.Select: a dropdown
  • types.OptionsDisplay.Radio: radio buttons
  • types.OptionsDisplay.Color: color swatches

As a rule of thumb:

  • use Select for long lists
  • use Radio for short lists where editors should compare options at a glance
  • use Color when editors need to choose a color from a predefined set

Static options vs dynamic options

Most of the time, you will use static options:

selectOptions: {
  display: types.OptionsDisplay.Select,
  options: [
    { value: 'sm', label: 'Small' },
    { value: 'md', label: 'Medium' },
    { value: 'lg', label: 'Large' },
  ],
}

If the list must depend on current brick props or external data, you can use getOptions instead.

That function can return the options directly or return a promise.

Example with dynamic options

{
  name: 'category',
  label: 'Category',
  type: types.SideEditPropType.Select,
  selectOptions: {
    display: types.OptionsDisplay.Select,
    getOptions: async (props) => {
      const response = await fetch(`/api/categories?site=${props.siteKey}`)
      const categories = await response.json()
 
      return categories.map((category: { id: string; name: string }) => ({
        value: category.id,
        label: category.name,
      }))
    },
  },
}

Using color display

For types.OptionsDisplay.Color, the option value should be an object with a required color property.

For example:

{
  value: { color: '#0ea5e9', className: 'bg-sky-500 text-white' },
  label: 'Sky',
}

This is useful when the prop needs to carry both:

  • the visible color swatch
  • an extra value such as a Tailwind class name

There are also 2 useful details that are easy to miss:

  • if color is 'transparent', React Bricks shows a gray checkerboard swatch so editors can recognize transparency
  • if you provide a style property on the option object, React Bricks uses it to style the swatch itself, which is useful for gradients

For example:

{
  value: {
    color: 'transparent',
    className: 'bg-gradient-to-r from-sky-500 to-violet-500 text-white',
  },
  style: {
    background: 'linear-gradient(135deg, #0ea5e9, #8b5cf6)',
  },
  label: 'Gradient',
}

A practical tip

Prefer values that are stable and meaningful in code, such as:

  • 'left'
  • 'primary'
  • 'sm'

instead of labels such as 'Left side' or 'Blue option 1'.

The label is for editors. The value is for your component logic.

Related reading