Selection Set
Selection Set provides a set of options (selections) to the user and allows them to make a selection(s).
Functionally, a Selection Set is either a series of radio buttons (single select) or of checkboxes (multi-select), though they may have the look of other elements. For instance, a mutually exclusive set of Standard Tiles would be a Selection Set.
Playground
Single Select
A single select Section Set acts as a set of radio buttons, and only one value may be selected at a time. In React, single select is the default behavior.
<SelectionSet variant="single-select" defaultSelectedValue="B"><SelectionSetInput value="A"><SelectionSetLabel>A</SelectionSetLabel></SelectionSetInput><SelectionSetInput value="B"><SelectionSetLabel>B</SelectionSetLabel></SelectionSetInput><SelectionSetInput value="C"><SelectionSetLabel>C</SelectionSetLabel></SelectionSetInput></SelectionSet>
<div class="selection-set" role="radiogroup"><inputtype="radio"class="stylized-radio selection-set-input"value="A"id="exampleId1"/><label class="selection-set-label" for="exampleId1">A</label><inputtype="radio"class="stylized-radio selection-set-input"value="B"checked="checked"id="exampleId2"/><label class="selection-set-label" for="exampleId2">B</label><inputtype="radio"class="stylized-radio selection-set-input"value="C"id="exampleId3"/><label class="selection-set-label" for="exampleId3">C</label></div>
Multi-Select
This behavior allows multiple options to be selected at the same time — the component acting as a set of checkboxes.
<SelectionSetvariant="multi-select"defaultSelectedValues={{ A: true, B: false, C: true }}><SelectionSetInput value="A"><SelectionSetLabel>A</SelectionSetLabel></SelectionSetInput><SelectionSetInput value="B"><SelectionSetLabel>B</SelectionSetLabel></SelectionSetInput><SelectionSetInput value="C"><SelectionSetLabel>C</SelectionSetLabel></SelectionSetInput></SelectionSet>
<div class="selection-set" role="group"><inputtype="checkbox"class="stylized-checkbox selection-set-input"value="A"checked="checked"id="exampleId1"/><label class="selection-set-label" for="exampleId1">A</label><inputtype="checkbox"class="stylized-checkbox selection-set-input"value="B"id="exampleId2"/><label class="selection-set-label" for="exampleId2">B</label><inputtype="checkbox"class="stylized-checkbox selection-set-input"value="C"checked="checked"id="exampleId3"/><label class="selection-set-label" for="exampleId3">C</label></div>
Setting Defaults
You can set a Selection Set to have default values:
In React, you can optionally pass a
defaultSelectedValues
prop on theSelectionSet
to specify an initial state.In vanilla JS, set the
checked
property on the appropriateselection-set-input
elements.
<SelectionSet defaultSelectedValue="B" />
<inputtype="radio"class="selection-set-input"name="exampleRadio"value="B"checked/>
using Standard Tiles
By default, the Selection Set's labels are neutral containers, so you can render just about anything inside of them. That includes entire Standard Tiles!
<SelectionSet variant="single-select" defaultSelectedValue="B"><GridContainer><Row><Column span={4}><SelectionSetInput value="A"><SelectionSetLabel><StandardTile><StandardTileImage><BasicResponsiveImageaspectRatio={1}src="https://picsum.photos/400/400"/></StandardTileImage><StandardTileContents><StandardTileName>Name</StandardTileName><StandardTileDescription>Description</StandardTileDescription></StandardTileContents></StandardTile></SelectionSetLabel></SelectionSetInput></Column><Column span={4}><SelectionSetInput value="B"><SelectionSetLabel><StandardTile><StandardTileImage><BasicResponsiveImageaspectRatio={1}src="https://picsum.photos/400/400?q=1"/></StandardTileImage><StandardTileContents><StandardTileName>Name</StandardTileName><StandardTileDescription>Description</StandardTileDescription></StandardTileContents></StandardTile></SelectionSetLabel></SelectionSetInput></Column><Column span={4}><SelectionSetInput value="C"><SelectionSetLabel><StandardTile><StandardTileImage><BasicResponsiveImageaspectRatio={1}src="https://picsum.photos/400/400?q=2"/></StandardTileImage><StandardTileContents><StandardTileName>Name</StandardTileName><StandardTileDescription>Description</StandardTileDescription></StandardTileContents></StandardTile></SelectionSetLabel></SelectionSetInput></Column></Row></GridContainer></SelectionSet>
Using horizontal tiles:
<SelectionSet defaultSelectedValue="B"><SelectionSetInput value="A"><SelectionSetLabel><SecondaryTile layout="horizontal"><SecondaryTileImage><BasicResponsiveImageaspectRatio={1}src="https://picsum.photos/400/200"/></SecondaryTileImage><SecondaryTileContents><SecondaryTileName>A</SecondaryTileName><SecondaryTileDescription>Description</SecondaryTileDescription><SecondaryTilePrice>$1.00</SecondaryTilePrice></SecondaryTileContents></SecondaryTile></SelectionSetLabel></SelectionSetInput><SelectionSetInput value="B"><SelectionSetLabel><SecondaryTile layout="horizontal"><SecondaryTileImage><BasicResponsiveImageaspectRatio={1}src="https://picsum.photos/400/200?q=1"/></SecondaryTileImage><SecondaryTileContents><SecondaryTileName>B</SecondaryTileName><SecondaryTileDescription>Description</SecondaryTileDescription><SecondaryTilePrice>$1.00</SecondaryTilePrice></SecondaryTileContents></SecondaryTile></SelectionSetLabel></SelectionSetInput></SelectionSet>
Skins
"Buttons" skin
The "buttons" skin uses text-only labels, and puts some standard padding around the text, to give the selections a button-like appearance.
<SelectionSet variant="single-select" skin="buttons" defaultSelectedValue="B"><SelectionSetInput value="A"><SelectionSetLabel>A</SelectionSetLabel></SelectionSetInput><SelectionSetInput value="B"><SelectionSetLabel>B</SelectionSetLabel></SelectionSetInput><SelectionSetInput value="C"><SelectionSetLabel>C</SelectionSetLabel></SelectionSetInput></SelectionSet>
<SelectionSet skin="buttons" />
<div class="selection-set selection-set-skin-buttons" role="radiogroup"></div>
"Buttons with Images" skin
The "buttons with images" skin works like the above, but includes a small image or icon above the text.
<SelectionSetvariant="single-select"skin="buttons-with-images"defaultSelectedValue="B"><SelectionSetInput value="A"><SelectionSetLabel><BasicResponsiveImageaspectRatio={0.3}src="https://picsum.photos/400/200"/>A</SelectionSetLabel></SelectionSetInput><SelectionSetInput value="B"><SelectionSetLabel><BasicResponsiveImageaspectRatio={0.3}src="https://picsum.photos/400/200?q=1"/>B</SelectionSetLabel></SelectionSetInput><SelectionSetInput value="C"><SelectionSetLabel><BasicResponsiveImageaspectRatio={0.3}src="https://picsum.photos/400/200?q=2"/>C</SelectionSetLabel></SelectionSetInput></SelectionSet>
<SelectionSet skin="buttons-with-images" />
<divclass="selection-set selection-set-skin-buttons-with-images"role="radiogroup"></div>
"Simple Column" skin
Sometimes you just want a single checkbox or radio button with a label next to it. You can do that with the "simple column" option, which gives a standard radio-button/checkbox look.
<SelectionSetvariant="single-select"skin="simple-column"defaultSelectedValue="B"><SelectionSetInput value="A"><SelectionSetLabel>A</SelectionSetLabel></SelectionSetInput><SelectionSetInput value="B"><SelectionSetLabel>B</SelectionSetLabel></SelectionSetInput><SelectionSetInput value="C"><SelectionSetLabel>C</SelectionSetLabel></SelectionSetInput></SelectionSet>
You can use this for checkboxes, too :
<SelectionSet skin="simple-column" />
<divclass="selection-set selection-set-skin-simple-column selection-set-show-inputs"role="radiogroup"></div>
"Tiles" skins
The "tiles-horizontal", "tiles-vertical", and "tiles-mini" skins present the selections as simple tiles, arranging the contents of each tile either horizontally or vertically.
Note that the images in these skins are wrapped in a <SelectionSetTileImageContainer>
element, and the image must be a <FluidImage>
component.
The "mini" skin is designed to be visually compact. Tiles using this skin must feature the product name; price and image are optional. No other information (e.g. a description) should go on these tiles.
<SelectionSet skin="tiles-horizontal" variant="multi-select"><SelectionSetInput value="A"><SelectionSetLabel><SelectionSetTileImageContainer><FluidImagesrc="https://picsum.photos/100/100?ssm=1"alt="placeholder"/></SelectionSetTileImageContainer><SelectionSetTileContents><SelectionSetTileName>Name A</SelectionSetTileName><SelectionSetTileDescription>some description</SelectionSetTileDescription><SelectionSetTilePrice>$price</SelectionSetTilePrice></SelectionSetTileContents></SelectionSetLabel></SelectionSetInput><SelectionSetInput value="B"><SelectionSetLabel><SelectionSetTileImageContainer><FluidImagesrc="https://picsum.photos/100/100?ssm=2"alt="placeholder"/></SelectionSetTileImageContainer><SelectionSetTileContents><SelectionSetTileName>Name B</SelectionSetTileName><SelectionSetTileDescription>some description</SelectionSetTileDescription><SelectionSetTilePrice>$price</SelectionSetTilePrice></SelectionSetTileContents></SelectionSetLabel></SelectionSetInput><SelectionSetInput value="C" disabled><SelectionSetLabel><SelectionSetTileImageContainer><FluidImagesrc="https://picsum.photos/100/100?ssm=3"alt="placeholder"/></SelectionSetTileImageContainer><Callout variant="overlay" skin="error">Out of stock</Callout><SelectionSetTileContents><SelectionSetTileName>Name C</SelectionSetTileName><SelectionSetTileDescription>disabled selection</SelectionSetTileDescription><SelectionSetTilePrice>$price</SelectionSetTilePrice></SelectionSetTileContents></SelectionSetLabel></SelectionSetInput></SelectionSet>
<div class="selection-set selection-set-skin-tiles-horizontal" role="group"><inputtype="checkbox"class="stylized-checkbox selection-set-input"value="A"id="exampleId1"/><label class="selection-set-label" for="exampleId1"><div class="selection-set-tile-image-container"><img src="someurl" alt="My example image" class="fluid-image" /></div><div class="selection-set-tile-contents"><p class="selection-set-tile-name">Name A</p><p class="selection-set-tile-description">some description</p><div class="selection-set-tile-price">$price</div></div></label><inputtype="checkbox"class="stylized-checkbox selection-set-input"value="B"id="exampleId2"/><label class="selection-set-label" for="exampleId2"><div class="selection-set-tile-image-container"><img src="someurl" alt="My example image" class="fluid-image" /></div><div class="selection-set-tile-contents"><p class="selection-set-tile-name">Name B</p><p class="selection-set-tile-description">some description</p><div class="selection-set-tile-price">$price</div></div></label><inputdisabled=""type="checkbox"class="stylized-checkbox selection-set-input"value="C"id="exampleId3"/><label class="selection-set-label" for="exampleId3"><div class="selection-set-tile-image-container"><img src="someurl" alt="My example image" class="fluid-image" /></div><span class="callout callout-skin-error callout-overlay">Out of stock</span><div class="selection-set-tile-contents"><p class="selection-set-tile-name">Name C</p><p class="selection-set-tile-description">disabled selection</p><div class="selection-set-tile-price">$price</div></div></label></div>
<SelectionSet skin="tiles-vertical" variant="multi-select"><SelectionSetInput value="A"><SelectionSetLabel><SelectionSetTileImageContainer><FluidImagesrc="https://picsum.photos/100/100?ssm=1"alt="placeholder"/></SelectionSetTileImageContainer><SelectionSetTileContents><SelectionSetTileName>Name A</SelectionSetTileName><SelectionSetTileDescription>some description</SelectionSetTileDescription><SelectionSetTilePrice>$price</SelectionSetTilePrice></SelectionSetTileContents></SelectionSetLabel></SelectionSetInput><SelectionSetInput value="B"><SelectionSetLabel><SelectionSetTileImageContainer><FluidImagesrc="https://picsum.photos/100/100?ssm=2"alt="placeholder"/></SelectionSetTileImageContainer><SelectionSetTileContents><SelectionSetTileName>Name B</SelectionSetTileName><SelectionSetTileDescription>some description</SelectionSetTileDescription><SelectionSetTilePrice>$price</SelectionSetTilePrice></SelectionSetTileContents></SelectionSetLabel></SelectionSetInput><SelectionSetInput value="C" disabled><SelectionSetLabel><SelectionSetTileImageContainer><FluidImagesrc="https://picsum.photos/100/100?ssm=3"alt="placeholder"/></SelectionSetTileImageContainer><SelectionSetTileContents><SelectionSetTileName>Name C</SelectionSetTileName><SelectionSetTileDescription>disabled selection</SelectionSetTileDescription><SelectionSetTilePrice>$price</SelectionSetTilePrice></SelectionSetTileContents></SelectionSetLabel></SelectionSetInput></SelectionSet>
<div class="selection-set selection-set-skin-tiles-vertical" role="group">etc, as above</div>
<SelectionSet skin="tiles-mini"><SelectionSetInput value="A"><SelectionSetLabel><SelectionSetTileImageContainer><FluidImagesrc="https://picsum.photos/100/100?ssm=1"alt="placeholder"/></SelectionSetTileImageContainer><SelectionSetTileContents><SelectionSetTileName>Name A</SelectionSetTileName><SelectionSetTilePrice>$price</SelectionSetTilePrice></SelectionSetTileContents></SelectionSetLabel></SelectionSetInput><SelectionSetInput value="B"><SelectionSetLabel><SelectionSetTileImageContainer><FluidImagesrc="https://picsum.photos/100/100?ssm=2"alt="placeholder"/></SelectionSetTileImageContainer><SelectionSetTileContents><SelectionSetTileName>Name B</SelectionSetTileName><SelectionSetTilePrice>$price</SelectionSetTilePrice></SelectionSetTileContents></SelectionSetLabel></SelectionSetInput><SelectionSetInput value="C" disabled><SelectionSetLabel><SelectionSetTileImageContainer><FluidImagesrc="https://picsum.photos/100/100?ssm=3"alt="placeholder"/></SelectionSetTileImageContainer><SelectionSetTileContents><SelectionSetTileName>Name C</SelectionSetTileName><SelectionSetTilePrice>$price</SelectionSetTilePrice></SelectionSetTileContents></SelectionSetLabel></SelectionSetInput><SelectionSetInput value="D"><SelectionSetLabel><SelectionSetTileContents><SelectionSetTileName>No image D</SelectionSetTileName><SelectionSetTilePrice>$price</SelectionSetTilePrice></SelectionSetTileContents></SelectionSetLabel></SelectionSetInput></SelectionSet>
<div class="selection-set selection-set-skin-tiles-mini" role="radiogroup">etc, as above</div>
Error Messaging
To provide error messaging about a Selection Set, place a "Selection Set Error" component right after the Set. (Don't forget to add the necessary ARIA attributes to the inputs!)
Please make a selection.
<Box><SelectionSetvariant="multi-select"skin="simple-column"defaultSelectedValue="B"><SelectionSetInputvalue="A"aria-describedby="myExampleSelectionSetError"aria-errormessage="myExampleSelectionSetError"><SelectionSetLabel>A</SelectionSetLabel></SelectionSetInput><SelectionSetInputvalue="B"aria-describedby="myExampleSelectionSetError"aria-errormessage="myExampleSelectionSetError"><SelectionSetLabel>B</SelectionSetLabel></SelectionSetInput><SelectionSetInputvalue="C"aria-describedby="myExampleSelectionSetError"aria-errormessage="myExampleSelectionSetError"><SelectionSetLabel>C</SelectionSetLabel></SelectionSetInput></SelectionSet><SelectionSetError id="myExampleSelectionSetError">Please make a selection.</SelectionSetError></Box>
<divclass="selection-set selection-set-skin-simple-column selection-set-show-inputs"role="group"><inputaria-describedby="myExampleSelectionSetError"aria-errormessage="myExampleSelectionSetError"type="checkbox"class="stylized-checkbox selection-set-input"value="A"id="exampleId1"/><label class="selection-set-label" for="exampleId1">A</label><inputaria-describedby="myExampleSelectionSetError"aria-errormessage="myExampleSelectionSetError"type="checkbox"class="stylized-checkbox selection-set-input"value="B"id="exampleId2"/><label class="selection-set-label" for="exampleId2">B</label><inputaria-describedby="myExampleSelectionSetError"aria-errormessage="myExampleSelectionSetError"type="checkbox"class="stylized-checkbox selection-set-input"value="C"id="exampleId3"/><label class="selection-set-label" for="exampleId3">C</label></div><p id="myExampleSelectionSetError" class="selection-set-error">Please make a selection.</p>
Managing State in React
If you want to control the state of SelectionSet
you can make use of the selectedValue
/selectedValues
and onSelectedValueChange
/onSelectedValuesChange
props.
Single Select
A single-select
SelectionSet
should use the selectedValue
and onSelectedValueChange
props in order to control the state.
onSelectedValueChange
will be invoked with the new value as the first arg and the actual <input>
event as the second arg in case you need it.
() => {const [selectedValue, setSelectedValue] = React.useState('B')return (<SelectionSetvariant="single-select"selectedValue={selectedValue}onSelectedValueChange={newSelectedValue =>setSelectedValue(newSelectedValue)}><SelectionSetInput value="A"><SelectionSetLabel>A</SelectionSetLabel></SelectionSetInput><SelectionSetInput value="B"><SelectionSetLabel>B</SelectionSetLabel></SelectionSetInput><SelectionSetInput value="C"><SelectionSetLabel>C</SelectionSetLabel></SelectionSetInput></SelectionSet>)}
Multi Select
A multi-select
SelectionSet
should use the selectedValues
and onSelectedValuesChange
props in order to control the state.
selectedValues
is an object { [value: string]: boolean }
which represents which values are selected and which are not. If a value is omitted from the object, it will be considered unselected.
onSelectedValuesChange
will be invoked with an updated object representing the selected values as the first arg and the actual <input>
event as the second arg in case you need it.
() => {const [selectedValues, setSelectedValues] = React.useState({B: true,C: true,})return (<SelectionSetvariant="multi-select"selectedValues={selectedValues}onSelectedValuesChange={newSelectedValues =>setSelectedValues(newSelectedValues)}><SelectionSetInput value="A"><SelectionSetLabel>A</SelectionSetLabel></SelectionSetInput><SelectionSetInput value="B"><SelectionSetLabel>B</SelectionSetLabel></SelectionSetInput><SelectionSetInput value="C"><SelectionSetLabel>C</SelectionSetLabel></SelectionSetInput></SelectionSet>)}
Components
SelectionSet
Prop | Type | Default | Description |
---|---|---|---|
skin | "standard" | "buttons" | "buttons-with-images" | "simple-column" | "tiles-horizontal" | "tiles-vertical" | "tiles-mini" | "standard" | The visual style of the SelectionSet |
variant | "single-select" | "multi-select" |
| |
selectedValue | string | ||
defaultSelectedValue | string | ||
onSelectedValueChange | (selectedValue: string, event: ChangeEvent<HTMLInputElement>) => void | ||
selectedValues | SelectedValues | ||
defaultSelectedValues | SelectedValues | ||
onSelectedValuesChange | (newSelectedValues: SelectedValues, event: ChangeEvent<HTMLInputElement>) => void | Callback fired when one of the selections' value changes It is passed the updated set of selectedValue |
All other props are forwarded to the element specified in thecomponent
prop(default: <div/>
)
SelectionSetInput
SelectionSetInput
has no props of its own
All props are forwarded to the element specified in thecomponent
prop(default: <input/>
)
SelectionSetLabel
SelectionSetLabel
has no props of its own
All props are forwarded to the element specified in thecomponent
prop(default: <label/>
)
Guidelines
Designer Guidelines
When using the "buttons with images" skin, the images should be no taller than 30 pixels.
Developer Guidelines
You cannot place another form element (such as an
<input>
tag) inside aSelectionSetLabel
orselection-set-label
.The outermost Selection Set element can be combined with a grid row element, if the selections that the user is choosing from are spread out among the columns inside that row. For instance, if you are presenting a row of Standard Tiles to choose from, the grid row can also act as the Selection Set.
Accessibility Guidelines
The outermost element (
SelectionSet
in React, or classselection-set
in vanilla JS) must have an accessible label, such as anaria-labelledby
attribute whose value is the id of the element that acts as a title for the Selection Set. (Typically, that labelling element is a heading that sits right above the Selection Set.) If the Selection Set does not have a visible title, then the outermost element instead needs anaria-label
attribute whose value is a descriptive title of the Selection Set; this text must be localized, as some browsers will read it to the user.If there is more than one input in the Selection Set, that outermost element must also have a
role
attribute; the React component will take care of this for you. For the vanilla JS API, if the Selection Set is a set of radio buttons, it should haverole="radiogroup"
; if it is an Selection Set of checkboxes, it should haverole="group"
.If a checkbox or radio button is a required field before the user can submit the form, add the attribute
aria-required="true"
to the input element.When a Selection Set has an error, each input should have
aria-describedby
andaria-errormessage
attributes whose value is the id of the error message. The error message should not be a label tag with afor
attribute pointing to the input.