Chooser
The Chooser component renders a set of options as visually rich, click-to-select tiles. A single component covers four combinations driven by blueprint parameters: cards or chips, single or multi-select. Each option supports icons, descriptions, tooltips, badges, and "recommended" / "disabled" states.
Key Features
- Two visual variants — cards (rich tiles) or chips (compact pills)
- Single or multi-select — radio or checkbox semantics from one option
- Density control — comfortable (with description) or compact (label only)
- Per-option metadata — icon, description, tooltip, badge, recommended, disabled
- Theme-aware — uses Domma CSS variables; retints automatically across all themes
- Full keyboard support — arrows for radio, tab+space for checkbox; disabled options skipped
- Native form integration — hidden inputs degrade gracefully when JS is unavailable
- Blueprint-driven — drop into
F.create()withtype: 'chooser'
When to Use
- Pricing-plan pickers with descriptions and "POPULAR" badges
- Feature-toggle multi-select with icons
- Tag pickers (chip variant) for categorisation
- Theme/skin pickers with compact density
- Anywhere a native radio/checkbox feels visually weak for the choice at hand
Basic Usage
// Standalone
Domma.elements.chooser('#host', {
variant: 'card',
options: [
{ value: 'a', label: 'Alpha', icon: 'rocket' },
{ value: 'b', label: 'Beta', icon: 'zap' }
],
onChange: (v) => console.log('Picked:', v)
});
// Inside a form blueprint
Domma.forms.create({
plan: {
type: 'chooser',
variant: 'card',
label: 'Choose your plan',
options: […]
}
}).renderTo('#my-form');
The four matrix combinations
All four variant × multiple combinations share the same component and parameter surface. Click to select.
Card · single-select
{ variant: 'card', multiple: false }
Card · multi-select
{ variant: 'card', multiple: true }
Chip · single-select
{ variant: 'chip', multiple: false }
Chip · multi-select
{ variant: 'chip', multiple: true }
Density
Comfortable shows the description; compact strips it for dense layouts.
Comfortable
Compact
{ variant: 'card', density: 'compact', columns: 4 }
Columns
The card variant accepts columns: 1–6. Chips wrap freely.
1 column
2 columns
3 columns
4 columns
6 columns
Per-option flags
Each option supports rich metadata. Flags are independent — combine freely.
icon
{ value: 'a', label: 'Alpha', icon: 'rocket' }description
{ value: 'a', label: 'Alpha', description: 'Sub-text under the label' }tooltip
Hover any option to see its tooltip.
{ value: 'a', label: 'Alpha', tooltip: 'Helpful hover hint' }badge — five types
primary
success
info
warning
danger
{ value: 'a', label: 'Alpha', badge: { text: 'NEW', type: 'success' } }recommended
{ value: 'b', label: 'Beta', recommended: true } // success-coloured ringdisabled
{ value: 'c', label: 'Gamma', disabled: true } // muted, non-interactiveVisual options — accent, accent-style, glow, shadow
Six new options polish the look of every chooser. All accept semantic colour names (primary, success, info, warning, danger) or any custom hex/rgb value.
accent — selected/recommended highlight colour
Five semantic colours and a custom hex example.
primary (default)
success
info
warning
danger
custom hex (#9333ea)
{ accent: 'success' } // semantic
{ accent: '#9333ea' } // custom hexaccentStyle — five visual treatments for the selected state
border (default) — coloured border + tinted bg
solid — fully filled tile
glow — transparent border + glowing ring
overlay — heavier translucent fill
underline — minimal: thick coloured bottom border
{ accentStyle: 'solid' } // 'border' | 'solid' | 'glow' | 'overlay' | 'underline'glow — soft outer glow on the selected option
glow only (uses accent colour)
glow with custom glowColour: 'info'
glow with custom hex glowColour: '#ff66cc'
{ glow: true } // glow uses accent colour
{ glow: true, glowColour: 'info' } // override with semantic name
{ glow: true, glowColour: '#ff66cc' } // or any hex/rgbshadow — depth on every option
sm
md
lg
xl
xl with custom shadow colour
{ shadow: 'md' }
{ shadow: 'xl', shadowColour: 'rgba(99, 102, 241, 0.35)' }All together
Combine glow + shadow + custom accent + a non-default style for a full look.
{
accent: '#ec4899',
accentStyle: 'glow',
glow: true,
glowColour: '#ec4899',
shadow: 'lg'
}Theme awareness
The chooser uses Domma's CSS variables. Switch theme + variant below — the chooser retints live with no JavaScript redraw.
Accessibility & keyboard
- Single-select uses
role="radiogroup"; arrow keys move and select; Enter/Space confirm - Multi-select uses
role="group"; Tab between options; Space toggles - Disabled options are skipped by arrow navigation and cannot be toggled by keyboard
aria-checkedreflects each option's selection state for screen readers- Hidden native
<input type="radio|checkbox">elements are emitted whennameis set so the value is captured byFormDataeven with JS disabled
Try it: focus the picker, then use ArrowRight / ArrowLeft
Inside a form (F.create)
Use type: 'chooser' in your blueprint and the rest works automatically — validation, model binding, submission.
const form = Domma.forms.create({
plan: {
type: 'chooser',
variant: 'card',
label: 'Choose your plan',
required: true,
options: [
{ value: 'starter', label: 'Starter', icon: 'rocket', description: 'For solo builders.' },
{ value: 'pro', label: 'Pro', icon: 'zap', description: 'Teams up to 10.', recommended: true,
badge: { text: 'POPULAR', type: 'success' } },
{ value: 'ent', label: 'Enterprise', icon: 'briefcase', description: 'Custom limits + SSO.' }
]
},
addons: {
type: 'chooser',
variant: 'chip',
multiple: true,
label: 'Optional add-ons',
options: [
{ value: 'sso', label: 'SSO', icon: 'lock' },
{ value: 'audit', label: 'Audit log', icon: 'file-text' },
{ value: 'sla', label: '24/7 SLA', icon: 'phone' }
]
}
});
form.renderTo('#my-form');
Standalone usage (E.chooser)
Outside of a form, instantiate the chooser directly. The control object exposes getValue(), setValue(), disable(), enable(), destroy().
Tutorial
When to reach for a chooser
Use a chooser instead of a native <input type="radio"> or <input type="checkbox"> when the choice itself deserves visual weight — pricing plans, feature toggles, theme selection, tag pickers. Native controls are perfect for terse forms; the chooser is for surfaces where the option's identity (icon + label + description) is part of the experience.
Blueprint shape
Inside a form blueprint:
fieldName: {
type: 'chooser', // required — selects this control
variant: 'card' | 'chip', // visual style (default: 'card')
multiple: false | true, // single (radio) vs multi (checkbox); default false
density: 'comfortable' | 'compact', // default 'comfortable'
columns: 1..6, // grid columns for cards (chips wrap); default 3
required: false | true, // standard form flag
label: 'Field label', // standard form flag
default: 'value' | ['v1', 'v2'], // initial selection (string for single, array for multi)
options: [
{
value: 'unique-id', // required
label: 'Visible label', // required
icon: 'icon-name', // optional — Domma icon
description: 'Sub-text', // optional — card+comfortable only
tooltip: 'Hover hint', // optional
badge: { // optional — corner badge
text: 'POPULAR',
type: 'success' // primary | success | info | warning | danger
},
recommended: true, // optional — success-coloured ring
disabled: true // optional — muted, non-interactive
}
]
}Common patterns
1. Pricing-plan picker
plan: {
type: 'chooser', variant: 'card', columns: 3, required: true,
options: [
{ value: 'starter', label: 'Starter', icon: 'rocket',
description: 'For solo builders.' },
{ value: 'pro', label: 'Pro', icon: 'zap',
description: 'Teams up to 10.',
recommended: true,
badge: { text: 'POPULAR', type: 'success' } },
{ value: 'ent', label: 'Enterprise', icon: 'briefcase',
description: 'Custom limits + SSO.' }
]
}2. Tag picker (multi-select chips)
tags: {
type: 'chooser', variant: 'chip', multiple: true,
options: [
{ value: 'js', label: 'JavaScript', icon: 'code' },
{ value: 'css', label: 'CSS', icon: 'palette' },
{ value: 'a11y', label: 'A11y', icon: 'eye' },
{ value: 'wasm', label: 'WASM', icon: 'cpu', disabled: true }
]
}3. Compact theme picker
theme: {
type: 'chooser', variant: 'card', density: 'compact', columns: 4,
options: [
{ value: 'charcoal', label: 'Charcoal', icon: 'moon' },
{ value: 'ocean', label: 'Ocean', icon: 'droplet' },
{ value: 'forest', label: 'Forest', icon: 'leaf' },
{ value: 'sunset', label: 'Sunset', icon: 'sun' }
]
}Gotchas
- Description only renders when
variant: 'card'anddensity: 'comfortable'. Chips ignore it; compact strips it. - Columns is a card-only prop. Chips wrap freely on a flex row.
- Value type follows
multiple. Single-select stores a string; multi-select stores an array of strings. The form pipeline handles both. - Required for multi-select means at least one option must be selected (empty array is invalid).
- Disabled options are non-interactive end to end — click ignored, keyboard skipped, hidden native input also disabled.
- Tooltip uses
data-tooltip; combine withE.tooltip()if you want full Domma tooltip styling on hover.