feat(ux): toast system, accessible modal wrapper, safer dialogs

- Global toast stack (success/error/info) replacing hidden notice/syncError
- Shared Modal: focus trap, Escape, focus restore, scroll lock; all dialogs migrated
- ConfirmDialog tone prop; limit-override now warning-styled
- Single-entry delete now requires confirmation, per-row busy spinner
- Onboarding no longer closes on failed save; inline error + skip option
This commit is contained in:
nh9961
2026-07-19 20:08:14 +00:00
parent f8d06cbafb
commit 733c6cbae8
16 changed files with 857 additions and 520 deletions
+2 -9
View File
@@ -3,12 +3,11 @@ import type { SetupStatus } from "../types";
type StatusRailProps = {
busyAction: string | null;
syncError: string;
setupStatus: SetupStatus;
};
export function StatusRail({ busyAction, syncError, setupStatus }: StatusRailProps) {
if (!busyAction && !syncError && setupStatus.state === "ok") return null;
export function StatusRail({ busyAction, setupStatus }: StatusRailProps) {
if (!busyAction && setupStatus.state === "ok") return null;
return (
<div className="mt-3 grid gap-2">
{busyAction && (
@@ -17,12 +16,6 @@ export function StatusRail({ busyAction, syncError, setupStatus }: StatusRailPro
Working on {actionLabel(busyAction)}...
</div>
)}
{syncError && (
<div className="status-card status-card--error">
<AlertTriangle size={17} aria-hidden="true" />
{syncError}
</div>
)}
{setupStatus.state === "error" && (
<div className="status-card status-card--warning">
<AlertTriangle size={17} aria-hidden="true" />