Fully customize options, badges, and selected items using render callbacks with HTML or DOM elements
🌐 client — runs in the browser (element JS API) 🖥️ server — LiveView round-trip
.options and render callbacks assigned via a small
page script after the custom element upgrades.
JS callback (no attribute): set el.renderOptionContentCallback · size rows with option_height={75} · overflow badges with badges_threshold={2}
These examples demonstrate renderOptionContentCallback
for customizing how options appear in the dropdown.
getBadgeClassCallback
for dynamic price-based badge colors (Budget: green, Mid-Range: blue, Premium: pink).
Price badges in dropdown options also color-coded based on price ranges.
JS callback (no attribute): set el.renderBadgeContentCallback — return compact vs detailed markup via context.isInPopover
These examples demonstrate renderBadgeContentCallback
for customizing selected item badges.
JS callbacks (no attribute): el.renderBadgeContentCallback · el.getBadgeClassCallback · el.customStylesCallback
Own the whole pill's look without a special hook — three callbacks working
together. The wrapper (.ms__badge) and the remove × stay
component-owned so removal keeps working; you own the content and the styling.
.ms__badge-text
(--ms-badge-text-bg) and .ms__badge-remove
(--ms-badge-remove-bg). For a continuous gradient, paint it
on the wrapper .ms__badge and make those two transparent (the wrapper has
overflow: hidden, so it clips into one clean pill).
// 1) Own the badge CONTENT (rendered inside .ms__badge-text)
el.renderBadgeContentCallback = (item) =>
`<img class="ava" src="${item.avatar}" alt=""><span>${item.name}</span>`;
// 2) Tag special items so their pill can be styled
el.getBadgeClassCallback = (item) => item.vip ? 'badge--vip' : '';
// 3) Inject CSS into the shadow DOM (page CSS can't reach the pill)
el.customStylesCallback = () => `
.ms__badge { border-radius: 999px; } /* pill shape */
.ms__badge-text { gap: .4rem; padding-inline-start: .35rem; }
.ms__badge .ava { width: 20px; height: 20px; border-radius: 50%; object-fit: cover; }
/* VIP: one continuous gradient across the whole pill */
.ms__badge.badge--vip { background: linear-gradient(135deg, #7c3aed, #ec4899); }
.ms__badge.badge--vip .ms__badge-text,
.ms__badge.badge--vip .ms__badge-remove {
background: transparent; color: #fff; border-color: transparent;
}
`;
JS callback: el.renderBadgeCallback = (item) => … · returns the entire badge markup, not just its content
renderBadgeCallback returns the whole badge, so a selection can be a
full card rather than a pill. The component wraps your markup in
.ms__badge.ms__badge--custom and delegates removal to any element inside with
data-action="remove".
enable_selected_popover={false} · badges_display_mode="count" · show_counter={true}
With the badges collapsed to a [N] counter, the built-in popover that opens on
clicking the counter is redundant when you render your own selection list. Setting
enable_selected_popover={false} makes every popover trigger inert and drops
the pointer cursor — the counter here no longer opens anything.
multiple={false} · JS callback (no attribute): set el.renderSelectedContentCallback for the closed-input text and el.getDisplayValueCallback for the dropdown label
These examples demonstrate renderSelectedContentCallback
for customizing the selected value text in single-select mode.
badges_threshold={3} · badges_threshold_mode="partial" · enable_badge_tooltips={true} — plus JS el.renderOptionContentCallback / el.renderBadgeContentCallback / el.getBadgeDisplayCallback
Examples demonstrating how to combine multiple rendering callbacks for sophisticated customization.
These examples show how renderOptionContentCallback
and renderBadgeContentCallback
work together to create different displays for the same data in different contexts (dropdown vs badges vs popover).
renderOptionContentCallback
(rich dropdown with status, priority, tags),
renderBadgeContentCallback
(compact "▶️ Name" in main area, detailed "▶️ Name [priority]" in popover using context.isInPopover),
and getBadgeDisplayCallback
(plain text "Name - status (priority)" for tooltips).
renderBadgeContentCallback
for compact badge display and renderSelectedItemContentCallback
for detailed popover display.
Uses getBadgeClassCallback
to add priority-based CSS classes (badge-urgent, badge-important, badge-normal, badge-low).
Uses customStylesCallback
to inject CSS into Shadow DOM for styling those classes.
Demonstrates separate callbacks for badges vs. selected items popover and solving Shadow DOM CSS isolation.
checkbox_align="center | top" · option_height={90} — CSS-grid/flex markup comes from JS el.renderOptionContentCallback
Examples demonstrating flex/grid layouts with checkbox alignment control.
(pick an option anywhere on this page)