feat(design): every button on its family, the chip primitive, the lint rule (E28 S3b2)
The second half of the button sweep: the remaining hand-rolled buttons in
feature components, the design lab and the components/ui composites now
stand on Button, IconButton, Pressable, Chip or DragHandle.
- Chip + DismissibleChip (filter / token / tag / suggest / ghost, 24px
floor, 44 on touch) replace five chip geometries; FilterChipGroup
renders Chips; overflow lanes measure a mirror painted by chipClass.
- The Plex control row is IconButton's player rung (36, 20px glyph,
round, overlay; 44 on touch); the YT modal bar is on the sm rung with
pressed cycle toggles and names that survive a folded label.
- New variants: IconButton ghost-accent, danger-soft; Button warn on a
new state-warn utility. The .btn-{tone} recipes and btnCls are gone.
- Fixed on the way: membership rows (collection editor, Plex playlist
add) announce checked/mixed; a one-letter tag chip was 21px wide;
descriptionLinks moved out of lib/ (it renders components).
- local/button-primitive: a raw <button>/<FocusSafeButton> outside the
control-primitive files is a lint error (contract-tested, seen red).
This commit is contained in:
@@ -21,7 +21,8 @@ import PlexLibraryPicker from "./PlexLibraryPicker";
|
||||
import { toggleWatchState } from "../lib/plexWatch";
|
||||
import { LoadingState, StateMessage } from "./ui/QueryState";
|
||||
import NavGrid from "./ui/NavGrid";
|
||||
import { FocusSafeButton } from "./ui/FocusSafeButton";
|
||||
import { Button } from "./ui/Button";
|
||||
import { IconButton } from "./ui/IconButton";
|
||||
|
||||
// The Collection info page (ask B): a hero (art/title/cert/year-range/count/runtime/summary) + the
|
||||
// ordered member grid, a Play-all / Shuffle over the playable leaves, and — for a NON-external,
|
||||
@@ -312,12 +313,14 @@ export default function PlexCollectionView({
|
||||
>
|
||||
{d.summary}
|
||||
</p>
|
||||
<button
|
||||
<Button
|
||||
variant="link"
|
||||
aria-expanded={expanded}
|
||||
onClick={() => setExpanded((v) => !v)}
|
||||
className="mt-1 text-xs font-medium text-accent hover:underline"
|
||||
className="mt-1 text-xs"
|
||||
>
|
||||
{expanded ? t("plex.collection.less") : t("plex.collection.more")}
|
||||
</button>
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -412,15 +415,15 @@ export default function PlexCollectionView({
|
||||
menuProps={pinMenu.triggerProps}
|
||||
/>
|
||||
{canEdit && (
|
||||
<FocusSafeButton
|
||||
<IconButton
|
||||
variant="media"
|
||||
onClick={() => doRemove(c)}
|
||||
disabled={busy}
|
||||
title={t("plex.collection.removeItem")}
|
||||
aria-label={t("plex.collection.removeItem")}
|
||||
className="glass-card glass-hover absolute right-1.5 top-1.5 z-base grid h-6 w-6 place-items-center rounded-full text-fg disabled:opacity-50"
|
||||
label={t("plex.collection.removeItem")}
|
||||
className="absolute right-1.5 top-1.5 z-base"
|
||||
>
|
||||
<X className="h-3.5 w-3.5" />
|
||||
</FocusSafeButton>
|
||||
<X />
|
||||
</IconButton>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
@@ -475,13 +478,9 @@ function AddItemPanel({
|
||||
aria-label={t("plex.collection.addSearch")}
|
||||
className="glass-card flex-1 rounded-lg px-3 py-1.5 text-sm focus:outline-hidden focus:ring-2 focus:ring-accent/40"
|
||||
/>
|
||||
<button
|
||||
onClick={onClose}
|
||||
aria-label={t("common.close")}
|
||||
className="glass-hover grid h-8 w-8 place-items-center rounded-lg"
|
||||
>
|
||||
<X className="h-4 w-4" />
|
||||
</button>
|
||||
<IconButton size="md" onClick={onClose} label={t("common.close")}>
|
||||
<X />
|
||||
</IconButton>
|
||||
</div>
|
||||
<PlexLibraryPicker
|
||||
scope={scope}
|
||||
@@ -490,14 +489,15 @@ function AddItemPanel({
|
||||
renderAction={(c) => {
|
||||
const inColl = existing.has(c.id) || added.has(c.id);
|
||||
return (
|
||||
<FocusSafeButton
|
||||
<Button
|
||||
variant="glass"
|
||||
size="xs"
|
||||
icon={inColl ? <Check /> : <Plus />}
|
||||
onClick={() => add(c)}
|
||||
disabled={inColl}
|
||||
className="glass-card glass-hover inline-flex items-center gap-1 rounded-lg px-2.5 py-1 text-xs disabled:opacity-50"
|
||||
>
|
||||
{inColl ? <Check className="h-3.5 w-3.5" /> : <Plus className="h-3.5 w-3.5" />}
|
||||
{inColl ? t("plex.collection.added") : t("plex.collection.add")}
|
||||
</FocusSafeButton>
|
||||
</Button>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user