Refine settings, archive, and check-in styling

This commit is contained in:
syntaxbullet
2026-09-04 18:56:05 +02:00
parent 1208e93953
commit 865bdd1328
9 changed files with 184 additions and 72 deletions

View File

@@ -0,0 +1,29 @@
import { useId, type ReactNode } from "react";
import { X } from "lucide-react";
import { Button } from "./primitives";
/** Shared flat panel for secondary workspace flows. */
export function WorkspacePanel({ id, eyebrow, title, description, children, onClose, closeLabel = "Close panel" }: {
id: string; eyebrow: string; title: string; description?: string; children: ReactNode; onClose?: () => void; closeLabel?: string;
}) {
return <section id={id} className="ds-workspace-panel" aria-label={title}>
<header className="ds-panel-heading">
<div><p className="ds-eyebrow">{eyebrow}</p><h2>{title}</h2>{description && <p className="ds-panel-description">{description}</p>}</div>
{onClose && <Button variant="text" className="ds-panel-close" onClick={onClose} aria-label={closeLabel} title={closeLabel}><X size={20} aria-hidden="true" /></Button>}
</header>
{children}
</section>;
}
/** Consistent label, explanation and control columns for preference forms. */
export function SettingRow({ title, description, children }: { title: string; description: ReactNode; children: ReactNode }) {
const id = useId();
return <section className="ds-setting-row" aria-labelledby={id}>
<header className="ds-setting-heading"><h3 id={id}>{title}</h3><div>{description}</div></header>
<div className="ds-setting-controls">{children}</div>
</section>;
}
export function FormMessage({ children, error = false }: { children: ReactNode; error?: boolean }) {
return <p className={`ds-form-message${error ? " ds-form-message--error" : ""}`} role={error ? "alert" : "status"}>{children}</p>;
}