Tenon-UI Documentation

Code on GitHub

Create your own CheckboxGroup or RadioGroup view

Here you will see how to create your own CheckboxGroup and RadioGroup view. When creating your own view inline, you will use the children render prop of either the CheckboxGroupController or the RadioGroupController.

Creating these views are so similar they will be discussed on this one page with the small differences highlighted.

Checkbox and radiobutton groups

Making these groups accessible is surprisingly tricky, despite their prolific use. Please reconsider using the CheckboxGroup and RadioGroup components provided.

If you still want to build your own view, please take into account the following:

  1. Groups of elements should go inside a <fieldset> element and be described by a <legend>.
  2. In order for most screen readers out there to recognise the <legend>, it HAS to be the very next element after the <fieldset> opens. Please do not put any other HTML between the opening tag of the <fieldset> and the <legend>.
  3. Unlike controls such as the <input>, there is no reliable way to connect error messages or content hints to a <fieldset>. These messages must therefore be rendered into the <legend> element. Should this text not need be visible, it can be hidden with a style that visually hides content.
  4. When setting focus to this group, focus should land on the first <input type="checkbox"> or <input type="radio"> of the group.

The CheckboxGroupController and RadioGroupController does a lot to support you in this, but if your view does not support the points mentioned above, your resulting group of elements will be almost certainly inaccessible.

The visually hidden style mentioned above can be created like this:

Therefore we will once again urge you to use the CheckboxGroup and RadioGroup components provided by Tenon-UI and change it with styling.

Still not convinced? Then keep these points in mind in the following sections.

Available prop getters from CheckboxGroupController

The CheckboxGroupController gives you access to the following prop getter functions:


This prop getter generates the required props for each checkbox's <label> element.


This prop getter generates the required props for the <input> elements of each checkbox.

Available prop getters from RadioGroupController

The RadioGroupController gives you access to the following prop getter functions:


This prop getter generates the required props for each checkbox's <label> element.


This prop getter generates the required props for the <input> elements of each radiobutton.

Other props

A number of other props are also exposed by the CheckboxGroupController and `RadioGroupController. Refer to the smart controllers page to see how validators work:


This boolean value will indicate to the view whether an error should be shown. Normally, errors will only be shown after the first submit attempt unless overridden by the alwaysShowErrors prop of the Form component.

Use this to easily hide and show your error containers.


This value contains the current actual error message text. For valid or non-validated fields this will be empty. Otherwise if will contain the text from the first failing validator as specified on the controller.


This boolean value indicates if the controller has been marked as required. This can be handy to decide when to render required indicators.

Basic non-validated checkbox and radiobutton group

If you only need a group of checkboxes without validation you can write view code resembling this:

Similarly, if you want a group of radiobuttons the code becomes:

Here you will notice something strange going on. As you will see in the documentation for the ErrorBlock component, we sometimes need to link to our form controls when they are in error.

For single elements, this is easy, but for a group of checkboxes or radiobuttons we want to link to and set focus on the element of the set.

The controllers do not reliably know which of the child elements in their render props are the first. And neither should they try to figure this out as this would lead to more tightly coupled code. So we need to do some further configuration in our views.

Firstly we need to tell the controllers which element is intended to receive focus in an error condition. We do this with the focusElement configuration setting.

For checkbox groups we do this by passing focusElement: true into the config object of the getCheckboxProps prop getter for the first checkbox:

Also note that for each checkbox I need to pass in the name, which will be the returned value in the array of selected checkboxes should this checkbox be selected.

For radiobutton groups we do this by passing focusElement: true into the config object of the getRadiobuttonProps prop getter for the first radiobutton:

And for each radiobutton you need to pass in the value. The selected radiobutton will assign its value as the value of the entire control.

Tenon-ui also automatically generates element id attributes for you. For checkbox groups, the CheckboxGroupController will use the name values to keep the different checkbox id values unique. Similarly the RadioGroupController will use the value values.

Have a look at this HTML snippet of a checkbox group rendered with Tenon-UI to illustrate the effect of this (due to the similarity of the radiobuttons group only the checkbox group will be shown):

Have a look at the id attributes. The first checkbox, which was marked as the focusElement, receives the unique id value generated for the group element.

For every other checkbox, the name is appended to the group id value to keep the values unique.

But we want our labels' for attributes to still point to the correct checkboxes or radiobuttons. So here we have some more work to do. For every label, aside from the label for the focusElement, we need to pass in an autoIdPostfix configuration object value to the getLabelProps prop getter:

This can, of course, also be automated in a map, as we see in the source code for the CheckboxGroup component:

You may also notice that in our examples, the checkboxes are rendered inside a <ul> element. We also do that for the radiobutton.

This is done to give further assistance to screen reader users as they will then get to hear how many elements are inside the current group. Decide for yourself if you also want to add this extra bit of assistance.

We realise that this is not very intuitive, but we have spent a lot of time to come up with a re-usable control pattern that functioned reliably when tested in a large number of screen readers out there. We also want the usage and interface of this control to fit in the pattern of the single elements in Tenon-UI.

In this case we are limited by how these elements are interpreted by assistive technologies.

Required validated checkbox and radiobutton group

Render your error messages directly into the <legend> element. You can move these containers with styling.

Or you can hide it with a visually-hidden style and render the visible message further down and hide that from screen readers with aria-hidden="true".

Note that the required text is also rendered into the <legend>.

For checkboxes:

Similarly, for radiobuttons:

Checkbox and radiobutton group with a content hint

We add a content hint in the same way, although for these elements we do not get any assistance from the controllers.

Similarly, for radiobuttons: