Skip to content

BbCheckboxGroup

Manages multiple checkbox options as a group.

import { BbCheckboxGroup } from 'bitboss-ui';

On this page

Props

NameDescription
autofocus Type: Booleanish

Focuses the field when it mounts (a dialog already open included), unless the user is typing in another field.

compact Type: booleanDefaultfalse

Compact density. Swaps --bb-label-spacing-y for --bb-label-spacing-y-compact, so tune a compact group's label gap with the -compact token, not the base one.

See example
dependencies Type: unknown[]

Defines an array of dependencies that will trigger actions in the component upon change.

Only meaningful when items is a provider function: it names what makes the group call it again. A dependency that is a text field wants deps-debounce-time with it; one that is another group does not.

See example
depsDebounceTime Type: number

Timeout used to debounce response to changes to dependencies.

See example
description Type: string

Text between the label and the input. Unlike the hint it is always visible; it joins the input's aria-describedby after any errors / warnings, before the hint.

One description for the whole set; there is no per-option equivalent. When each option needs its own line, the options are not uniform and a BbCheckbox per row is the honest answer.

See example
disabled Type: booleanDefaultfalse

Disables the component.

Locks every option, ticked ones included, and keeps the values out of a native post. To freeze a selection that must still be submitted, use readonly.

See example
emptyText Type: string

String displayed when there are no items to display.

See example
enforceCoherence Type: booleanDefaultfalse

After every applied, successful load (an empty one included), drops the model values the options no longer contain (a single value resets to null). A failed load never prunes.

Drops model entries the current options no longer contain. Worth it when the options depend on another field, and not otherwise: a selection can vanish without the user doing anything.

See example
errors Type: string | string[]

Error messages under the field, a string or array, in an aria-live="polite" region and first in the control's aria-describedby, so they are re-read when it regains focus.

One channel for the whole fieldset, which is the concrete payoff over a hand-stacked row of BbCheckbox, where the message has to be pinned to one arbitrary box.

See example
failedText Type: stringDefaultthe localized common.failedText ("Couldn't load items")

String displayed in the empty state while the latest load FAILED (the items provider threw): the twin of emptyText for that case.

formless Type: booleanDefaultfalse

Keep this control out of the enclosing BbForm entirely: not submitted, not dirty, not reset, not validated. For a control that is not form data (a filter, a "show advanced" switch).

hasErrors Type: booleanDefaultfalse

Define if the component should be in an error state. It usually attaches a CSS class for styling purposes.

hasWarnings Type: booleanDefaultfalse

Define if the component should be in a warning state. Same chrome as errors with --bb-warn; errors take priority.

hideLabel Type: booleanDefaultfalse

Visually hides each option's label text (the text rendered next to every input) while keeping it accessible to screen readers. Does not affect the fieldset legend — use hideLegend for that.

Hides each option's text, not the legend. For a group whose options are drawn entirely by the icon slot, and nothing else.

hideLegend Type: booleanDefaultfalse

Visually hides the legend of the fieldset while maintaining accessibility.

Hides the group's name while keeping it for assistive technology. For when a visible heading right above already says the same words, never as a way to avoid writing one.

See example
hint Type: string

Text box to be displayed near the input, usually to indicate instructions.

See example
id Type: string

Prefix for the ids of each option's input and of the label, description and message. Generated when omitted.

inputAlign Type: FieldCrossAlign

Vertical position of the control in a side-by-side row; not inputPosition, the horizontal one. Omitted, the control's first line meets the label's.

inputPosition Type: "left" | "center" | "right"Default"left"

Sets the alignment of the input. Since inputs are inline block they can be aligned just as text can.

See example
itemInputAlign Type: FieldCrossAlign

Vertical position of each option's control in its row; 'center' is the middle of the label plus its description. Omitted, it sits on the label's first line.

itemLabelAlign Type: FieldCrossAlign

Vertical position of each option's label in its row. Omitted, it stays as it is.

itemLayout Type: FieldLayoutDefault'auto'

How each row's input and label sit together, in the layout keywords: 'auto', 'vertical', 'horizontal', 'label-fill', 'input-fill', or a two-word ratio pattern like 'xx xxxxx'.

itemProps Type: BbOptionGroupItemProps<T>

ADDITIONAL row fields, never the text or value: description, a muted line under the label (it may wrap; announced as the option's description). An object of paths or getters, or a function of the item; nothing is read implicitly.

Only additional row fields: today one, description, the muted line under each option. Nothing is read implicitly: an item carrying a description field shows nothing until you map it here.

See example
itemReverse Type: booleanDefaultfalse

Swaps each row's input and label from their natural order (input first), in every item-layout. reverse swaps the legend and the options instead.

items requiredType: T[] | ((context: BbCheckboxGroupItemsContext) => T[] | Promise<T[]>)

The options: an array, or a provider called with a BbCheckboxGroupItemsContext (BbSwitchGroupItemsContext on a switch group) (reason, modelValue, signal), sync or async. A provider fails by THROWING, never by returning []: the rows clear and #empty gets the error.

An array, or a function called on mount and after every dependencies change, returning an array or a promise. Options whose resolved value duplicates an earlier one are dropped silently, first occurrence winning.

See example
itemText Type: ItemAccessor<T, string>Defaultown label, else text, else JSON.stringify(item)

Defines a path that returns a property of the object to use as text or a function that returns a string. Unset: own label, else text ({ label, value } needs no accessor).

A property path ("fullName", "profile.city") or a function. Omit it for primitive items, where the value is its own label, and for objects with a label (or text) key, which is read by default.

See example
itemValue Type: ItemAccessor<T>Defaultown value, else the whole item

Defines a path that returns a property of the object to use as value or a function that returns any value. Unset: own value, even null.

Prefer a stable primitive id. With this unset the model holds the item's own value key when it has one, otherwise the whole item, which works (matching is structural, not by reference), but an id survives a refetch and is readable in a payload.

See example
labelAlign Type: FieldCrossAlign

Vertical position of the label block in a side-by-side row; not labelPosition, the horizontal one. Omitted, the label's first line meets the control's.

layout Type: Responsive<FieldLayout>

How label and input sit together: 'vertical', 'horizontal' (50/50), 'auto', 'label-fill', 'input-fill', a ratio like 'xx xxxxx', or a per-breakpoint map ({ default: 'vertical', md: 'xx xxxxx' }).

Splits the legend from the options, not the options from each other; that is list-layout. Defaults to vertical, which is why the legend sits above.

See example
legend requiredType: string

Text content of the legend.

Required, because it is the fieldset's accessible name: a screen reader announces it on entry, so every box is heard as an answer to a named question. Hide it with hide-legend when a visible heading already carries it.

See example
legendMode Type: "outside" | "inside"

Legend rendering mode. 'outside' renders the legend above the fieldset in the normal flow; 'inside' overlays the legend inside the fieldset border. Floating mode is not supported for option groups (checkbox, radio or switch) — there is no single field for the legend to float against.

No floating mode here: a group has no single input for a label to float into. inside draws the fieldset border and sets the legend on it.

See example
legendPosition Type: "left" | "center" | "right"

Sets the text alignment of the label.

Renamed from v2's labelPosition, with no change in behaviour. The rename is silent: an unknown attribute falls through to the DOM, so the alignment just stops applying.

See example
listLayout Type: ListLayoutDefault'horizontal'

How the rows sit in the list: 'horizontal' (on a line, wrapping), 'vertical' (stacked), 'vertical-stretch' (stacked, as wide as the list) or 'tiles' (equal boxes; --tile-min-width on pt:list sets the narrowest).

Lays the options out inside the fieldset. Defaults to horizontal: a wrapping row, not a stack.

See example
loadingText Type: string

String displayed while items are being loaded.

Worth setting to something specific. "Loading hubs…" tells the reader more than the default.

See example
max Type: number

Maximum number of selected items.

A shape rule, not a validation rule: it prevents the extra choice rather than complaining about it. Once the cap is reached the options that are off render disabled and the ticked ones stay live, so the user swaps rather than getting stuck.

See example
modelValue Type: any

Used by v-model. Can be an array of any serializable type.

modelValueDebounceTime Type: number

Timeout used to debounce response to changes to modelValue.

multiple Type: booleanDefaulttrue

Enables multi-selection behavior. When true, modelValue must be an array. When false, modelValue should be a single value.

True by default, so the model is an array: unbound, it starts empty, and a non-array value such as null throws on mount. Setting it false gives a single-value control that emits a bare value and null; it works, and an exclusive choice drawn as checkboxes is BbRadioGroup.

See example
name Type: string

Defines the name of the input.

persistentHint Type: booleanDefaultfalse

Keeps the hint displayed.

pt Type: ({ root?: PtValue | undefined; "root:loading"?: PtValue | undefined; "icon:loading"?: PtValue | undefined; "root:disabled"?: PtValue | undefined; "root:errors"?: PtValue | undefined; "root:warnings"?: PtValue | undefined; "root:readonly"?: PtValue | undefined; "icon:disabled"?: PtValue | undefined; "item:disabled"?: PtValue | undefined; description?: PtValue | undefined; message?: PtValue | undefined; hint?: PtValue | undefined; "icon:errors"?: PtValue | undefined; "icon:warnings"?: PtValue | undefined; "icon:readonly"?: PtValue | undefined; "icon:checked"?: PtValue | undefined; "icon:focused"?: PtValue | undefined; "icon:focusVisible"?: PtValue | undefined; "label:disabled"?: PtValue | undefined; "label:errors"?: PtValue | undefined; "label:warnings"?: PtValue | undefined; "label:readonly"?: PtValue | undefined; "label:checked"?: PtValue | undefined; "label:focused"?: PtValue | undefined; "label:focusVisible"?: PtValue | undefined; "description:disabled"?: PtValue | undefined; "description:errors"?: PtValue | undefined; "description:warnings"?: PtValue | undefined; "description:readonly"?: PtValue | undefined; "message:disabled"?: PtValue | undefined; "message:errors"?: PtValue | undefined; "message:warnings"?: PtValue | undefined; "message:readonly"?: PtValue | undefined; "hint:disabled"?: PtValue | undefined; "hint:errors"?: PtValue | undefined; "hint:warnings"?: PtValue | undefined; "hint:readonly"?: PtValue | undefined; legend?: PtValue | undefined; list?: PtValue | undefined; indicator?: PtValue | undefined; "root:hasValue"?: PtValue | undefined; "description:loading"?: PtValue | undefined; "description:hasValue"?: PtValue | undefined; "message:loading"?: PtValue | undefined; "message:hasValue"?: PtValue | undefined; "hint:loading"?: PtValue | undefined; "hint:hasValue"?: PtValue | undefined; "legend:loading"?: PtValue | undefined; "legend:disabled"?: PtValue | undefined; "legend:errors"?: PtValue | undefined; "legend:warnings"?: PtValue | undefined; "legend:readonly"?: PtValue | undefined; "legend:hasValue"?: PtValue | undefined; "list:loading"?: PtValue | undefined; "list:disabled"?: PtValue | undefined; "list:errors"?: PtValue | undefined; "list:warnings"?: PtValue | undefined; "list:readonly"?: PtValue | undefined; "list:hasValue"?: PtValue | undefined; "indicator:loading"?: PtValue | undefined; "indicator:disabled"?: PtValue | undefined; "indicator:errors"?: PtValue | undefined; "indicator:warnings"?: PtValue | undefined; "indicator:readonly"?: PtValue | undefined; "indicator:hasValue"?: PtValue | undefined; "icon:hasValue"?: PtValue | undefined; "label:loading"?: PtValue | undefined; "label:hasValue"?: PtValue | undefined; "item:loading"?: PtValue | undefined; "item:errors"?: PtValue | undefined; "item:warnings"?: PtValue | undefined; "item:readonly"?: PtValue | undefined; "item:checked"?: PtValue | undefined; "item:focused"?: PtValue | undefined; "item:focusVisible"?: PtValue | undefined; "item:hasValue"?: PtValue | undefined; "itemDescription:loading"?: PtValue | undefined; "itemDescription:disabled"?: PtValue | undefined; "itemDescription:errors"?: PtValue | undefined; "itemDescription:warnings"?: PtValue | undefined; "itemDescription:readonly"?: PtValue | undefined; "itemDescription:checked"?: PtValue | undefined; "itemDescription:focused"?: PtValue | undefined; "itemDescription:focusVisible"?: PtValue | undefined; "itemDescription:hasValue"?: PtValue | undefined; } & { icon?: PtValue | PtItemFn<T, GroupPtState, never, { readonly item: T; }> | undefined; label?: PtValue | PtItemFn<T, GroupPtState, never, { readonly item: T; }> | undefined; item?: PtValue | PtItemFn<T, GroupPtState, never, { readonly item: T; }> | undefined; itemDescription?: PtValue | PtItemFn<T, GroupPtState, never, { readonly item: T; }> | undefined; } & { "indicator:pill"?: PtValue | undefined; "indicator:line"?: PtValue | undefined; "root:pill"?: PtValue | undefined; "root:line"?: PtValue | undefined; "icon:pill"?: PtValue | undefined; "icon:line"?: PtValue | undefined; "label:pill"?: PtValue | undefined; "label:line"?: PtValue | undefined; "item:pill"?: PtValue | undefined; "item:line"?: PtValue | undefined; "description:pill"?: PtValue | undefined; "description:line"?: PtValue | undefined; "message:pill"?: PtValue | undefined; "message:line"?: PtValue | undefined; "hint:pill"?: PtValue | undefined; "hint:line"?: PtValue | undefined; "legend:pill"?: PtValue | undefined; "legend:line"?: PtValue | undefined; "list:pill"?: PtValue | undefined; "list:line"?: PtValue | undefined; "itemDescription:pill"?: PtValue | undefined; "itemDescription:line"?: PtValue | undefined; })

Passthrough, object form: the same keys as the pt:* attributes without the prefix. See the pt:<part> row.

pt:<part> Type: PtValue | ((ctx: PtItemCtx<T, GroupPtState>) => PtItemResult)

Passthrough, attribute form: one attribute per part, pt:<part>, and per part and state, pt:<part>:<state>. Parts: description, hint, icon, indicator, item, itemDescription, label, legend, list, message, root. States: checked, disabled, errors, focused, focusVisible, hasValue, line, loading, pill, readonly, warnings.

See example
readonly Type: booleanDefaultfalse

Sets the input in a readonly state.

Keeps every box focusable and submitted while swallowing every change. The right lock for a value the user may read and must not alter.

See example
reverse Type: booleanDefaultfalse

Reverses the layout. Applicable in every direction the order of the label and the input is swapped.

See example
rules Type: RuleExpression<any>

vee-validate rules for this field. Only inside a BbForm.

Validates the array as a single field, so required means "at least one". Only inside a BbForm; outside one, compute errors yourself.

See example
selectable Type: boolean | ((item: T) => boolean)Defaulttrue

Defines whether options are selectable. Can be a global boolean that affects all options or a function that accepts an item and returns a boolean that only affects that item. Non-selectable options are rendered disabled.

A boolean for the group or a predicate over the item. This is where v2's per-item disabled field went: that field is inert in v3, silently, so options that used to render locked become tickable.

See example
validationLabel Type: string

The field's name in validation messages ({field}): "Email is not valid". Defaults to the label (or legend), then "This field"; never the name. Set it when the label is hidden or reads badly in a sentence (icon-only, a question). BbForm only.

validationMode Type: ValidationMode

When the field validates: aggressive (each change), balanced (on leave, then live while in error), lazy (on leave), submit-only, submit-live. Unset: the BbForm's validation-mode, then formControls.validationMode ('balanced'). BbForm only.

See example
variant Type: keyof CheckboxVariantRegistry

A tab-strip look (Q76.11 d): 'pill' (a pill per run of adjacent picks) or 'line' (a bar under each pick). list-layout="vertical" stacks it. Register more with checkboxVariants. Unset: the group's own rows.

warnings Type: string | string[]

Warning messages under the field, a string or array: amber, in their own aria-live region and in the control's aria-describedby after the errors. Non-empty turns on the warning state; errors win when both are set.

v-model

Values kept in sync through v-model.

NameDescription
modelValue Type: any

The array of resolved values, re-emitted in full on every change, never the option that moved. Diff it against the previous value when you need to know what changed.

See example

Events

NameDescription
active Type: (): void

Emitted when the group becomes active (focus/click enters it).

blur Type: (event: FocusEvent): void

Emitted when one of the generated checkbox inputs loses focus. Forwards the original DOM FocusEvent.

change Type: (event: Event): void

Emitted when an option is toggled. Forwards the original DOM Event from the checkbox input.

click Type: (event: MouseEvent): void

Emitted when one of the generated checkbox inputs is clicked. Forwards the original DOM MouseEvent.

focus Type: (event: FocusEvent): void

Emitted when one of the generated checkbox inputs receives focus. Forwards the original DOM FocusEvent.

inactive Type: (): void

Emitted when focus/click moves outside the group after it was active. Useful for validation-on-blur flows at group level.

input Type: (event: Event): void

Emitted on native input events from generated checkbox inputs. Forwards the original DOM Event.

keydown Type: (event: KeyboardEvent): void

Emitted for keyboard interaction on generated checkbox inputs. Forwards the original DOM KeyboardEvent.

mousedown Type: (event: MouseEvent): void

Emitted when a pointing device button is pressed over a checkbox input. Forwards the original DOM MouseEvent.

mouseup Type: (event: MouseEvent): void

Emitted when a pointing device button is released over a checkbox input. Forwards the original DOM MouseEvent.

update:modelValue Type: (value: any): void

Emitted with the coherent next selection array whenever selection changes.

Slots

The listed properties are the ones exposed to the slot scope.

NameDescription
append Type: object

Content rendered after the last option, inside the options container.

description Type: BbCheckboxGroupDescriptionSlotProps

Replaces the description text. Provided alone (no description prop) it still renders the description region and wires it into aria-describedby.

empty Type: { error: unknown; }

Content shown when no options are available (replaces the default "no data" text). error is what the latest failed load rejected with, untouched, and null when nothing failed — a failed load clears the rows, so this slot is where it shows.

icon Type: BbCheckboxGroupIconSlotProps<T>

Replaces the default checkmark icon for each checkbox option.

Replaces the box visual per option, and receives item and text alongside the live state.

See example
label Type: BbCheckboxGroupLabelSlotProps<T>

Replaces the default label text for each option.

One template for every option, scoped { item, text, checked, description }. Decorate text rather than dropping it: what renders here is the option's accessible name. This is what replaced v2's removed #option:prepend and #option:append.

See example
legend Type: BbCheckboxGroupLegendSlotProps

Replaces the default fieldset legend text for the group.

Scoped { text, hasErrors, hasWarnings }, plus showAsterisk when the required marker shows.

See example
loading Type: object

Content shown while options are loading (replaces the default loading text).

prepend Type: object

Content rendered before the first option, inside the options container.

Renamed and removed

Names from v2 and from earlier 3.0 betas that no longer work, and what to write instead.

  • colorremovedfails silently
  • directionlayoutfails silently
  • hasWarninghasWarningsfails silently
  • inputDirectionlistLayoutfails silently
  • labelPositionlegendPositionfails silently
  • slotno-dataemptyfails silently
  • noDataTextemptyTextfails silently
  • validateOnvalidationModefails silently

    An array of events became one mode (aggressive | balanced | lazy | submit-only | submit-live). The old defaults (['blur'], ['inactive'], a toggle's ['update:modelValue', 'change', 'blur']) are balanced, the new default: delete the prop. A text field on ['update:modelValue'] is validation-mode="aggressive". Set it once on <BbForm validation-mode> instead of per field.

  • vidremovedfails silently

    A display name (v2: vid="Email address") is now validation-label; a field path (3.0 betas: vid="address.city") is now name (brackets for a native post: address[city]). check --fix picks by the value.