Skip to main content
Bubble Choice displays multiple choices in a pannable arena. Bubbles near the center stay large; those near the edge shrink. Choose plain labels, descriptions, photo backgrounds or small image icons. Selected bubbles can stay circular, grow, or morph into a scalloped shape.

First field

The stored value might be ['walk', 'read']. Numeric option keys are saved as strings; 0 is a supported key. Selection order is preserved. The component works with an ordinary JSON column and an Eloquent array cast:

Rich choices

Labels and descriptions are plain text. Image URLs are configured on the server; they are not uploaded by this field.

Colors and appearance

Light mode uses a pale gray arena; dark mode uses charcoal. Built-in bubble colors follow the panel’s primary palette. Explicit field/option colors remain the configured colors in both themes. Hex and RGB custom colors receive a calculated foreground; image backgrounds use white text. Choose adequate contrast for other CSS color formats.

Layout

Numbers must be finite and nonnegative. Bubble diameter must be at least 1px; minimum diameter cannot exceed it. Numeric layout values are bounded at 10,000 and column count at 4,096. Boolean options accept actual booleans. Unknown keys and inconsistent values raise a configuration error. A later individual setter overrides the corresponding layoutOptions() value; a later layoutOptions() call replaces the previous layout overrides. The arena starts centered. It supports touch panning and two-axis trackpad scrolling. Resizing adjusts the layout without creating another set of bubbles. Labels hide when the displayed bubble is 50px or smaller; the accessible button name remains available.

Selection limits and validation

Limits can be null to remove them or integers from 0 to 4,096. maxItems(0) prevents all additions; exactItems(0) accepts only an empty list. Combining required() with an exact zero cannot produce a valid selection. Contradictory minimum/maximum/exact limits raise a configuration error. Validation rejects unknown or disabled keys, duplicates, nested values, associative arrays, booleans, floats and malformed/oversized keys. Submitted values are not silently filtered to make them valid. Use the normal validated Filament form state when saving.
normalizeState() is a presentation helper that removes unknown, disabled and repeated keys. It is not a replacement for submission validation. readOnly() is an interaction setting, not record authorization: enforce permissions and immutable-value policies on the server.

Dynamic options

Option, disabled-option and layout closures support the normal Filament utility injection. Option closures are resolved against current server state rather than a stale field cache. Use live() on the controlling field to refresh dependent choices, and reset their state when the parent changes.
Collections are bounded at 4,096 configured options. Keys must be nonempty valid UTF-8 strings up to 512 bytes, without control characters. Labels and other configured option strings are bounded at 8,192 bytes. This is an interactive visual picker, not a paginated remote search field; use SelectField for that workflow.

Keyboard and motion

  • Tab focuses an available bubble. Enter or Space selects it.
  • Arrow keys move to a neighboring available choice; left/right respect RTL direction.
  • Home and End move to the first or last available choice.
  • Keyboard movement brings the target to the center without changing the selected value.
  • After initialization, the centered bubbles fade in with a subtle scale transition. The arena keeps its reserved height throughout.
  • Reduced-motion preferences disable the entrance animation, shape tweening and decorative transitions.
Component CSS and JS use FLEX’s per-instance asset loading. Inactive tabs and closed modal content initialize on activation. Removing a field disposes its listeners, observer, pending animation frame and state subscriptions.

Choice checkbox cards

Structured choices in a card grid.

Image choice cards

A fixed image-forward selection grid.
Last modified on October 16, 2026