← Back to Examples

📱 Responsive & Mobile

Two independent axes: mobile_presentation (device → floating vs fullscreen overlay) and collapse_badges_below (the element's own box → badge display).

🌐 client — runs in the browser (element JS API) 🖥️ server — LiveView round-trip

Preview the phone UI without a phone
On a real phone-sized touch device these pickers open as a full-screen overlay. The Preview as fullscreen toggles below force mobile_presentation="fullscreen" on the demo so the overlay is inspectable on desktop; unchecking restores mobile_presentation="auto" (floating here).

RS01 · mobile-presentation — floating vs fullscreen

mobile_presentation="auto | floating | fullscreen"

auto keeps the floating panel on desktop/tablet and switches to a full-screen overlay on phone-sized touch devices; floating forces the anchored panel everywhere; fullscreen forces the overlay on any device.

<.web_multiselect mobile_presentation="fullscreen" />

RS02 · fullscreen-autofocus — soft keyboard on phones

fullscreen_autofocus={true}

By default the fullscreen sheet opens with the list visible and the keyboard closed — it appears only when you tap the search field. Set fullscreen_autofocus={true} to focus the search (and pop the keyboard) immediately.

RS03 · filter vs navigate — live switch

search_mode="navigate" · show_search_mode_toggle

In navigate mode the list stays whole and typing jumps focus between matches. show_search_mode_toggle={true} adds a clickable icon in the phone fullscreen search header that flips the mode in place, without closing the overlay.

RS04 · Responsive rendering — rich on desktop, lean on the phone

JS callback: el.renderOptionContentCallback = (item, ctx) => … reads ctx.isFullscreen

The render-callback context now carries the resolved presentation (isFullscreen / isModal), so one callback can draw a rich row on the desktop dropdown and a leaner one in the phone sheet — no matchMedia/resize wiring.

picker.renderOptionContentCallback = (item, ctx) => ctx.isFullscreen ? leanRow(item) : richRow(item);

RS05 · RTL — right-to-left, overlay included

dir="rtl" (on the element or any ancestor)

The whole component mirrors via CSS logical properties — the input, dropdown, checkboxes, badges, and the fullscreen overlay chrome. Runtime dir switching re-mirrors the live picker without a rebuild.

RS06 · Own box vs. the window

collapse_badges_below is a different axis from mobile_presentation. It keys off the element's own border box (via a shared ResizeObserver), not the viewport — so a picker in a narrow column collapses its badges to the count mode ("N selected") even on a wide monitor, where a viewport check would read "desktop". Widening the box past the threshold restores the configured badges mode. The two axes compose.

RS07 · Drag the box — collapse-badges-below="360"

collapse_badges_below={360}

Drag the resize handle at the box's corner: below 360px wide the badges collapse to a count.

RS08 · A picker in a narrow sidebar (window stays wide)

collapse_badges_below={300}

The window is wide, but the sidebar column is narrow — so the sidebar picker collapses while a wide-column one wouldn't.

Main content area — plenty of room here.

RS09 · How it resolves

Axis Keys off Decides
mobile_presentation the device (touch + shorter viewport side < 600px) floating panel vs. full-screen overlay
collapse_badges_below the element's own border box full badges vs. a "N selected" count
🔌 Server round-trip
0
The LiveView server saw 0 event(s) from the wrapper.
(pick an option anywhere on this page)