Sidebar Controls

Visual editing is great, but sometimes you want to delegate editors the ability to change the styles of a component using external controls (for example, to choose a background color or the padding of a block).

Editors can change these props via the right sidebar controls that you define in the schema's sideEditProps property. Let's see an example!

Simple sideEditProps

Let's make the thumbnail's shadow optional, using a hasShadow boolean prop which will show a checkbox control.

Thumbnail.tsx
import { types, Text, RichText, Image } from 'react-bricks/rsc'

interface ThumbnailProps {
  title: types.TextValue
  description: types.TextValue
  image: types.IImageSource
  hasShadow: boolean
}

const Thumbnail: types.Brick<ThumbnailProps> = ({ title, description, image, hasShadow }) => {
  return (
    <div
      className={`my-6 mx-6 p-6 text-center w-1/3 border rounded-lg ${
        hasShadow ? 'shadow-xl' : ''
      }`}
    >
      <Image
        propName="image"
        source={image}
        alt="Fallback alt tag"
        maxWidth={200}
        imageClassName="mb-6"
      />
      <Text
        propName="title"
        value={title}
        renderBlock={({ children }) => (
          <h1 className="text-2xl font-bold">{children}</h1>
        )}
        placeholder="Type a title..."
      />
      <RichText
        propName="description"
        value={description}
        renderBlock={({ children }) => (
          <p className="text-lg text-gray-500">{children}</p>
        )}
        placeholder="Type a description"
        allowedFeatures={[
          types.RichTextFeatures.Bold,
          types.RichTextFeatures.Highlight,
        ]}
        renderHighlight={({ children }) => (
          <span className="px-1 rounded bg-blue-200 text-blue-900">
            {children}
          </span>
        )}
      />
    </div>
  )
}

Thumbnail.schema = {
  name: 'thumbnail',
  label: 'Thumbnail',
  getDefaultProps: () => ({
    title: 'Hello, world!',
    description: 'Lorem ipsum dolor sit amet.',
    hasShadow: true
  }),

  sideEditProps: [
    {
      name: 'hasShadow',
      label: 'Shadow',
      type: types.SideEditPropType.Boolean,
    },
  ],
}

export default Thumbnail

Now, if you add a Thumbnail block, you should see something like this:

Side edit props

Control types

React Bricks natively supports the following side edit props' types on types.SideEditPropType:

  • Autocomplete
  • Boolean
  • Custom
  • Date
  • Image
  • Number
  • Range
  • Relationship
  • Select
  • Text
  • TextArea

The Text, TextArea, Number, Date, Boolean and Range types render the expected HTML5 input control.

The Select type, based on the display property, can be rendered as a Select, a Radio button or a Color selection interface.

The Autocomplete type, renders an async autocomplete to fetch data from an external source based on a search field.

The Image type renders an image upload interface to manage properties such as the background image.

The Relationship type is used to reference other pages or entities.

The Custom type lets you provide your own component to edit a sidebar prop (component property).

Docs reference
» Side edit props

Work with color values 🎨

As you can see from the documentation, the Select type requires a selectOptions object with the display property and options with the array of available options. These options are objects which need a value (the value passed to your component) and label (shown in the select/radio).

When you use a color display for a select prop, the value should be an object with a required color property which must have a string value representing a color (hex, hsla, rgba...) so that React Bricks can display the correct color bullet for the color selection. You can put any other property you need to receive back on the value object (for example a class name to be used with Tailwind CSS).

Let's change the thumbnail's background using a sideEditProp:

Thumbnail.tsx
import { types, Text, RichText, Image } from 'react-bricks/rsc'

interface ThumbnailProps {
  title: types.TextValue
  description: types.TextValue
  image: types.IImageSource
  hasShadow: boolean
  bgColor: types.IColor & { className: string } 
}

const Thumbnail: types.Brick<ThumbnailProps> = ({ title, description, image, hasShadow, bgColor }) => {
  return (
    <div
      className={`my-6 mx-6 p-6 text-center w-1/3 border rounded-lg ${
        hasShadow ? 'shadow-xl' : ''
      } ${bgColor?.className}`}
    >
      <Image
        //...
      />
      <Text
        //...
      />
      <RichText
       //...
      />
    </div>
  )
}

Thumbnail.schema = {
  name: 'thumbnail',
  label: 'Thumbnail',
  getDefaultProps: () => ({
    title: 'Hello, world!',
    description: 'Lorem ipsum dolor sit amet.',
    hasShadow: true,
    bgColor: { color: '#ffffff', className: 'bg-white' } 
  }),
  sideEditProps: [
    {
      name: 'hasShadow',
      label: 'Shadow',
      type: types.SideEditPropType.Boolean,
    },
    {
      name: 'bgColor',
      label: 'Background',
      type: types.SideEditPropType.Select,
      selectOptions: {
        display: types.OptionsDisplay.Color,
        options: [
          {
            label: 'White',
            value: { color: '#ffffff', className: 'bg-white' },
          },
          {
            label: 'Light blue',
            value: { color: '#eff6ff', className: 'bg-blue-50' },
          },
        ],
      },
    },
  ],
}

export default Thumbnail

And the result is...

Great! Now you know how to let your users edit props via sidebar controls: well done!

In the next lesson we'll see advanced sideEditProps usage (validation, conditional rendering of controls, collapsible groups and more).

Pay attention to the question below: it will give you many points!

# Time to get points

An option for a color selection control should be: