2.3 KiB
2.3 KiB
Badge Component Design Notes (WCAG)
Design rationale for the central <.badge> core component
(MvWeb.CoreComponents) and the WCAG-driven theme overrides in
assets/css/app.css. Before it, badges were raw <span class="badge ...">
markup with no central component.
<.badge> API contract
attr :variant—:neutral | :primary | :info | :success | :warning | :errorattr :style—:soft | :solid | :outline(default::soft)attr :size—:sm | :md(default::md)attr :sr_label— optional screen-reader label for icon-only badgesslot :icon— optionalslot :inner_block— badge text
Design rules
:softand:soliduse a visible background;:softis the default. No transparent ghost as a default.:outlinealways sets a background (e.g.bg-base-100) so the border stays visible on grey (base-200/base-300) surfaces.- Ghost only as an explicit opt-in, and then with
bg-base-100for visibility (plain DaisyUIbadge-ghostisbase-200onbase-200— nearly invisible). - Clickable chips keep
<.badge>as a plain container with a button in theinner_block.
WCAG contrast overrides (app.css)
DaisyUI defaults do not reach the WCAG 2.2 AA 4.5:1 text-contrast ratio for
badges, so app.css adds per-theme overrides on top of the custom light /
dark themes:
- Light theme: darker
--badge-fgfor all solid variants; darker text onbadge-soft's tinted background; uniform dark text forbadge-outlineonbase-100. - Dark theme: slightly darkened solid-badge backgrounds so the light
*-contentcolors reach 4.5:1; lighter, readable variant tints forbadge-soft; light--badge-fgforbadge-outlineonbase-100.
Related: contrast overrides for the member-filter join buttons
(.member-filter-dropdown .join .btn) under the same 4.5:1 rule.
Variant helpers
MembershipFeeHelpers.status_variant/1→:success | :error | :warning.status_variant(:suspended) -> :warning(yellow) deliberately matches the Edit button (btn-warning), keeping the "suspended" badge the same color as its action.RoleLive.Helpers.permission_set_badge_variant/1→:neutral | :info | :success | :error.MembershipFeeStatus.format_cycle_status_badge/1additionally returns a:variantfor<.badge>.