Swatch Group
<x-wirekit:: lets the reader choose a color or a pattern: the color of a product variant on its page, or several colors in a filter. Each option is a native radio button, or a checkbox with multiple, drawn as a swatch and named in words.
Because the options are native form controls, the group needs no script of its own. It posts with a form, binds with wire:model, and the keyboard works the way it does in every other radio group or set of checkboxes.
Choosing One Value
Give each option a value, a label and a color. The label is the option's name, read to a reader who cannot see the color:
With Livewire, bind the choice with wire:model. The chosen name next to the label is yours to show, from the bound value, through the labelAfter slot:
<x-wirekit::swatch-group wire:model.live="color" label="Color" :options="$colors">
<x-slot:label-after>
<x-wirekit::text as="span" size="sm" intent="muted">{{ $colorName }}</x-wirekit::text>
</x-slot:label-after>
</x-wirekit::swatch-group>
Without Livewire, value sets the chosen option and the group posts its name with the form.
Choosing Several: A Filter
multiple makes each option a checkbox, as a filter takes several values at once. The group posts its name as a list, colors[], and a wire:model binds an array:
<x-wirekit::swatch-group wire:model.live="colors" multiple label="Color" size="sm" :options="$colors" />
Names Under the Swatches
Each name is in the page for assistive technology. labels="below" shows it under its swatch as well, which helps where the colors are close to each other:
An option takes an image in place of a color for a pattern, as a swatch does.
Unavailable and Disabled Options
'available' => false draws a line across the option's swatch and reads "unavailable" with its name. The option stays a choice, because a sold-out variant can still be looked at. 'disabled' => true takes an option out of the choice, and disabled on the group takes all of them:
Hints and Errors
The group takes hint, error and help as every field does. The message stands under the swatches and describes the choice, and an error is announced politely:
The color is printed on the front only.
With required the label carries the mark, and one value has to be chosen before the form submits. After a failed validation the group shows the message the error bag holds for its name, as every field does:
Choose a color.
A group of checkboxes, with multiple, has no native way to require one of them: required marks its label, and the rule that at least one is chosen belongs to your validation.
What an Option Checks
An option without a value has nothing to send, and one without a label would leave its color to say what it is. WireKit reports both in development; an option without a label takes its value as its name. A color in a form other than a hex color, rgb(), hsl() or oklch(), and an image with a scheme other than http or https, are rejected as on a swatch and draw nothing.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
label |
string|null |
null |
The group's label, which names it |
options |
array |
[] |
The options, each an array with value, label and color or image, and optionally available (default true) and disabled (default false) |
value |
mixed |
null |
The chosen value, or with multiple a list of them, for a form without wire:model |
multiple |
bool |
false |
Choose several values, as checkboxes. Without it one value, as radio buttons |
labels |
string |
hidden |
hidden keeps each name for assistive technology, below shows it under its swatch |
size |
string |
md |
The swatches' size: sm (24px), md (32px) or lg (40px) |
shape |
string |
circle |
The swatches' shape: circle or square |
disabled |
bool |
false |
Disable every option |
required |
bool |
false |
One value has to be chosen: the label carries the mark, the radio buttons the native constraint, and the group says it is required. With multiple it marks the label only |
hint |
string|null |
null |
Text under the swatches |
error |
string|null |
null |
An error message under the swatches, in place of the hint |
announceError |
bool|null |
null |
Announce the error politely. Falls back to the surrounding form, then to config('wirekit.a11y.announce_error') |
help |
string|null |
null |
An explanation in a tooltip from a question mark beside the label, read as the group's description |
scope |
string|null |
null |
Scoped personalization key |
name, wire:model and x-model reach every option. The defaults for size, shape and labels come from config('wirekit., see Customization.
Slots
| Slot | Description |
|---|---|
labelAfter |
A mark after the label and its help, in the same row: the chosen name, or a badge |
Accessibility
- The group is named by its label, as a
radiogroupfor one value or agroupfor several, and every option is a native radio button or checkbox. - No option rests on its color. Each has its name in words, in the page whether it is shown or not; an unavailable one has a line across it and "unavailable" in its name; the chosen one has an outline in the accent color and is checked.
- The hint or the error describes the choice. For one value it stands on the radiogroup, as the description a screen reader gives when the focus enters the group, and on no single radio, where it would be read once per option. For several values every checkbox carries it, as each is a control of its own. An error is a polite live region and marks the choice invalid.
- The focus ring is the one every field draws, and on a touch surface each option has a 44px hit area. It follows the arrow keys in every browser. Safari, and every browser on iOS, does not count the focus an arrow key moves as keyboard focus, so WireKit's scripts note when an arrow key brings the focus to an option, and the ring follows it there too. Without
@wirekitScriptson the page, Safari draws the ring afterTaband not after an arrow key. - A forced-colors theme keeps the colors of the swatches, which are content, and draws their edges and the outline of the chosen one in its own colors.
Keyboard Interaction
| Key | Action |
|---|---|
Tab |
Into the group: to the chosen option, or the first one, as one stop for radio buttons; to each option in turn for checkboxes |
← → ↑ ↓ |
Choose the previous or next option, with radio buttons |
Space |
Choose the focused option, or check and uncheck it with checkboxes |
Customization
Set the defaults of every swatch group in config/:
'components' => [
'swatch-group' => ['size' => 'lg', 'shape' => 'square', 'labels' => 'below'],
],