refactor(ui): R10 S4 — unify selected-paint into .pill/.is-current/.chip recipes
The ~14 hand-rolled "this is the selected/current/active one" idioms each repeated the same `sel ? "bg-accent text-accent-fg border-accent" : "…"` inline ternary, which had drifted. Three attribute-driven recipes in @layer components now own that paint, keyed on the ARIA the control already carries: .pill (aria-pressed segments/toggles), .is-current (aria-current nav/list items), and .chip / .chip-solid (tag & filter tokens). The JSX just toggles the ARIA; the CSS paints, so one control's selected look can't diverge from the next's. No focus-visible in the recipes — the @layer base rule already rings every button/a. Migrated 15 sites (Feed show/content, Channels tag filter, Sidebar or-and + scope, PlexSidebar match, Tabs, SettingsPanel tab-rail, PlexPlaylistView layout [soft], NavSidebar nav + settings, ActiveFilterChips, PlexSidebar RemovableChip, ChannelTags, ChannelPicker). Deliberately left: PlexSidebar facet Chip and PlexPlaylistView already covered; SavedViews row (paint split across two elements), the scheme swatch (border-only on a coloured swatch), and ChannelPicker's option rows (text-only selection) — noted for a follow-up.
This commit is contained in:
@@ -418,6 +418,70 @@ body {
|
||||
outline: 2px solid color-mix(in srgb, var(--accent) 60%, transparent);
|
||||
outline-offset: -2px;
|
||||
}
|
||||
|
||||
/* ===== R10 S4 · Selection-paint recipes =====
|
||||
The ~14 hand-rolled "this is the selected / current / active one" idioms all painted the SAME
|
||||
bg-accent fill via an inline ternary (`sel ? "bg-accent text-accent-fg border-accent" : "…"`),
|
||||
which drifted over time. These recipes OWN that paint, keyed on the semantic ARIA the control
|
||||
already carries — the JSX just toggles `aria-pressed` (a segment/toggle) or `aria-current` (the
|
||||
single current item) and the CSS paints, so one control's selected look can never diverge from
|
||||
the next's. Geometry (padding / radius / border-width / font) stays a per-site utility since it
|
||||
legitimately varies. NO focus-visible here on purpose: the `@layer base` rule above already rings
|
||||
every button/a/[role]; re-adding it would duplicate that (an R9 review finding). Because these sit
|
||||
in @layer components, a site's own utility still wins — so a MIGRATED site must DROP its bg/text/
|
||||
border-color utilities (else a utility-layer `bg-*` beats the recipe's pressed fill). Add
|
||||
data-soft="true" for the subtle tint some surfaces use instead of the solid fill. */
|
||||
.pill,
|
||||
.is-current {
|
||||
color: var(--muted);
|
||||
border-color: var(--border); /* inert unless the site also adds a border-width utility */
|
||||
transition:
|
||||
color 0.15s ease,
|
||||
background-color 0.15s ease,
|
||||
border-color 0.15s ease;
|
||||
}
|
||||
.pill:hover,
|
||||
.is-current:hover {
|
||||
color: var(--fg);
|
||||
}
|
||||
.pill:hover {
|
||||
border-color: color-mix(in srgb, var(--accent) 55%, transparent);
|
||||
}
|
||||
.is-current:hover {
|
||||
background-color: var(--card);
|
||||
}
|
||||
/* selected / current — SOLID accent fill (the dominant idiom) */
|
||||
.pill[aria-pressed="true"],
|
||||
.is-current[aria-current] {
|
||||
background-color: var(--accent);
|
||||
color: var(--accent-fg);
|
||||
border-color: var(--accent);
|
||||
}
|
||||
/* selected — SOFT tint variant (the plex layout toggle keeps a glass-card resting look, so its
|
||||
"on" state is a subtle accent tint rather than the solid fill). */
|
||||
.pill[aria-pressed="true"][data-soft="true"] {
|
||||
background-color: color-mix(in srgb, var(--accent) 14%, transparent);
|
||||
color: var(--accent);
|
||||
border-color: color-mix(in srgb, var(--accent) 40%, transparent);
|
||||
}
|
||||
|
||||
/* .chip — an applied tag / filter token (rounded, tinted). The tint is the resting look (a filter
|
||||
is "on" whenever the chip exists); removable variants add their own × button as a child.
|
||||
.chip-solid = the strong-fill token (an applied tag colour, a picked channel). */
|
||||
.chip {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.25rem;
|
||||
border-radius: 9999px;
|
||||
border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent);
|
||||
background-color: color-mix(in srgb, var(--accent) 10%, transparent);
|
||||
color: var(--accent);
|
||||
}
|
||||
.chip-solid {
|
||||
background-color: var(--accent);
|
||||
color: var(--accent-fg);
|
||||
border-color: var(--accent);
|
||||
}
|
||||
}
|
||||
.glass-hover:hover {
|
||||
border-color: color-mix(in srgb, var(--accent) 55%, transparent);
|
||||
|
||||
Reference in New Issue
Block a user