A wrapper for OptionCard components.

Importing

In a React app, the component can be imported via:

import { OptionCardGroup } from '@customerio/pluma-components/react';

In an Ember app, the component is named PlumaOptionCardGroup.

Usage

An OptionCardGroup should contain OptionCard components as children. OptionCardGroup will forward the name attribute to any Checkboxes nested within, as well as connect onChange handlers to them, so there's no need to define those props on the OptionCards themselves:

Loading editor

Or, in Ember:

Loading...
Loading editor

Labels

An OptionCardGroup must always have an associated label. The component accepts a label string prop, which renders text above the nested checkboxes.

Alternatively, ariaLabelledby may be used to associate the group with a label elsewhere in the DOM. To make sure the association is set up both ways, it's recommended to also set for on the label, pointing to an id on the checkbox group:

Loading editor

Finally, the ariaLabel prop can be used if no other element is suitable for a label.

Disabled groups

The isDisabled prop on an OptionCardGroup will take precedence over the isDisabled prop on individual OptionCard components.

It is not necessary to set isDisabled on the individual OptionCard components, as the OptionCardGroup provides that state to the cards through its context.

Loading editor

Input type

An inputType can be set o the OptionCardGroup, which will be passed down into the nested OptionCards:

Loading editor

Preventing selection

Just like in the OptionCard component, selection can be prevented with the canSelect prop. Note that deselecting is still allowed.

This is useful in cases where you need to limit a checkbox-based selection to a maximum number of options.

Loading editor

Size

The Option Card Group component accepts a size prop that controls the size of all option cards within the group. This allows you to easily set a consistent size for all cards in the group without having to specify it on each individual card.

Loading editor

The size property accepts either "md" (default) or "sm" as values.

Layout

By default, the cards will render in a flex container, with a gap of 200 and no wrapping. The layout of the card container can be customized through the following properties:

For example:

Loading editor

Grid layout

Wrapping cards in a flex container gives every row as many cards as happen to fit, which leaves ragged rows and cards of differing widths. Set cardsLayout to grid to lay the cards out on a real grid instead. The card container then accepts the same grid configuration the Grid component does, through the cardsColumns, cardsRows, cardsAreas and cardsAutoFlow props:

Loading editor

cardsColumns accepts a number of equal-width columns, or any grid-template-columns value — for example "repeat(auto-fit, minmax(200px, 1fr))" for a responsive grid, or "2fr 1fr" for uneven columns.

Not every container prop applies to both layouts:

table
PropFlexGrid
cardsGapYesYes
cardsColumnGapYesYes
cardsRowGapYesYes
cardsAlignItemsYesYes
cardsJustifyContentYesYes
cardsAlignContentOnly with shouldWrapCardsYes
shouldWrapCardsYesNo — a grid wraps by definition
cardsDirectionYesNo — use cardsAutoFlow
cardsJustifyItemsNo — flex ignores justify-itemsYes
cardsColumnsNoYes
cardsRowsNoYes
cardsAreasNoYes
cardsAutoFlowNoYes

Keep the cards in the order you want them read. cardsAutoFlow values of column and dense, and explicit placement through cardsAreas, position cards in an order that no longer matches the DOM — but tab order and radio arrow-key navigation still follow the DOM, which is a WCAG 1.3.2 / 2.4.3 failure. Reorder the cards themselves rather than using auto-placement to reposition them.

API

The aria-label attribute to be applied on the fieldset

The aria-labelledby attribute to be applied on the fieldset

This option prevents selection of cards. Unlike isDisabled, however, it will not prevent the deselection of currently selected cards.

The align-content style of the card container. In the flex layout this only has an effect when shouldWrapCards is true.

grid-template-areas definitions for the card container. Only applies when cardsLayout is grid.

Default:row

The grid auto-placement algorithm to use for the card container. Only applies when cardsLayout is grid.

Note that column and the dense values place cards in an order that no longer matches the DOM, while tab order and arrow-key navigation still follow the DOM. Prefer reordering the cards themselves over relying on auto-placement to reposition them.

grid-template-columns definitions for the card container, or number of columns. Only applies when cardsLayout is grid.

Default:row

The flex-direction style of the card container. Only applies when cardsLayout is flex.

The justify-items style of the card container. Only applies when cardsLayout is grid — flex containers ignore justify-items.

Default:flex

Whether the card container lays its cards out as a flexbox or as a Grid. In grid mode the container accepts the same grid configuration the Grid component does, through the cardsColumns, cardsRows, cardsAreas and cardsAutoFlow props.

grid-template-rows definitions for the card container. Only applies when cardsLayout is grid.

An optional id attribute to assign to the fieldset

Default:radio

Whether the cards in the group represent radio or checkbox inputs.

Whether the entire group is disabled

The label text to be shown above the option card group

The name shared by option cards in this group. If none is provided, one will be generated

Default:false

Whether the cards should wrap (sets flex-wrap to wrap or nowrap). Only applies when cardsLayout is flex.

Default:md

The size of all option cards in the group

The current value. If the inputType is radio, the value is a string. When the inputType is checkbox, the value is an array of strings.