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:
@@ -6,7 +6,7 @@ import {
|
||||
useQuery,
|
||||
useQueryClient,
|
||||
} from "@tanstack/react-query";
|
||||
import { Copy, Radio, Search, X } from "lucide-react";
|
||||
import { Copy, Radio, Search } from "lucide-react";
|
||||
|
||||
import { api, type LogFacet, type LogQuery, type ServerLogRow } from "../lib/api";
|
||||
import { copyText } from "../lib/clipboard";
|
||||
@@ -33,6 +33,7 @@ import FilterChipGroup from "./ui/FilterChipGroup";
|
||||
import FilterSelect from "./ui/FilterSelect";
|
||||
import { Section } from "./ui/form";
|
||||
import { LoadingState, StateMessage } from "./ui/QueryState";
|
||||
import { DismissibleChip } from "./ui/Chip";
|
||||
|
||||
// Admin → Szervernapló: the server's stored log (`log_events`, E22.6). One list, newest first; a line
|
||||
// opens in place to its full record, and its request id / job id narrow the list to that request or
|
||||
@@ -421,18 +422,9 @@ function PivotChip({
|
||||
onClear: () => void;
|
||||
}) {
|
||||
return (
|
||||
<span className="chip py-0.5 pl-2.5 pr-1">
|
||||
<span className="font-mono">{label}</span>
|
||||
<button
|
||||
type="button"
|
||||
onClick={onClear}
|
||||
aria-label={clearLabel}
|
||||
title={clearLabel}
|
||||
className="rounded-full p-0.5 hover:bg-accent/20"
|
||||
>
|
||||
<X className="h-3 w-3" aria-hidden />
|
||||
</button>
|
||||
</span>
|
||||
<DismissibleChip onDismiss={onClear} dismissLabel={clearLabel} className="font-mono">
|
||||
{label}
|
||||
</DismissibleChip>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -449,7 +441,7 @@ function RowDetail({
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const pivotCls =
|
||||
"font-mono text-accent underline decoration-dotted underline-offset-2 hover:decoration-solid";
|
||||
"font-mono underline decoration-dotted underline-offset-2 hover:decoration-solid";
|
||||
return (
|
||||
<div className="flex flex-col gap-2">
|
||||
<dl className="grid grid-cols-[max-content_minmax(0,1fr)] gap-x-3 gap-y-0.5 font-sans text-xs">
|
||||
@@ -465,14 +457,14 @@ function RowDetail({
|
||||
<>
|
||||
<dt>{t("adminLogs.fields.request")}</dt>
|
||||
<dd>
|
||||
<button
|
||||
type="button"
|
||||
<Button
|
||||
variant="link"
|
||||
className={pivotCls}
|
||||
title={t("adminLogs.showRequest")}
|
||||
onClick={() => onRequest(row.request_id!)}
|
||||
>
|
||||
{row.request_id}
|
||||
</button>
|
||||
</Button>
|
||||
</dd>
|
||||
</>
|
||||
)}
|
||||
@@ -480,14 +472,14 @@ function RowDetail({
|
||||
<>
|
||||
<dt>{t("adminLogs.fields.job")}</dt>
|
||||
<dd>
|
||||
<button
|
||||
type="button"
|
||||
<Button
|
||||
variant="link"
|
||||
className={pivotCls}
|
||||
title={t("adminLogs.showJob")}
|
||||
onClick={() => onJob(row.job_id!)}
|
||||
>
|
||||
{row.job_id}
|
||||
</button>
|
||||
</Button>
|
||||
</dd>
|
||||
</>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user