feat(e10): finish the mappable Button migration, including the ui/ layer itself
Third sweep, 20 more sites: the rest of AdminUsers (the access-request and invite clusters), Scheduler, SettingsPanel, SetupWizard, About, Feed, KeyGate, OnboardingWizard -- and, importantly, four platform components that were still hand-rolling their own buttons: Modal's close, Banner's dismiss, SidePanel's two toggles and QueryState's retry. A platform layer that bypasses its own primitive is the same defect one level up. Hand-rolled buttons with their own geometry: 110 -> 39; Button call sites 37 -> 106. What is left is deliberate, and it is the list Button's own docstring excludes plus two families this pass refused to force: video overlay controls painted on white/N, drag handles, chip removers, accent-solid pills, the bg-card family on the signed-out screen, and sites whose paint is conditional (`suspended ? warn : neutral`) or otherwise has no variant yet. Forcing those through a className override would be unsafe without tailwind-merge, which is exactly the hazard this sprint documented. 3x tsc, eslint, knip, prettier, 689 vitest green; UAT on Settings and the About dialog (its close button and full-width CTA are both migrated), clean console.
This commit is contained in:
@@ -828,14 +828,15 @@ function AdminDemo() {
|
||||
)}
|
||||
</div>
|
||||
<Tooltip hint={t("settings.demo.removeHint")}>
|
||||
<button
|
||||
<Button
|
||||
variant="outline-danger"
|
||||
size="icon-sm"
|
||||
className="shrink-0"
|
||||
onClick={() => onRemove(r)}
|
||||
disabled={remove.isPending}
|
||||
className="shrink-0 p-1.5 rounded-lg border border-border text-muted hover:text-danger disabled:opacity-50 transition"
|
||||
aria-label={t("settings.demo.remove")}
|
||||
>
|
||||
<Trash2 className="w-4 h-4" />
|
||||
</button>
|
||||
icon={<Trash2 className="w-4 h-4" />}
|
||||
/>
|
||||
</Tooltip>
|
||||
</div>
|
||||
))}
|
||||
@@ -856,12 +857,9 @@ function AdminDemo() {
|
||||
placeholder={t("settings.demo.addPlaceholder")}
|
||||
className="flex-1 min-w-0 bg-surface border border-border rounded-xl px-3 py-2 text-sm focus:outline-hidden focus:ring-2 focus:ring-accent/40"
|
||||
/>
|
||||
<button
|
||||
type="submit"
|
||||
className="shrink-0 glass-card glass-hover flex items-center gap-1.5 px-3 py-2 rounded-xl text-sm transition"
|
||||
>
|
||||
<Button variant="glass" size="md" className="shrink-0" type="submit">
|
||||
<UserPlus className="w-4 h-4" /> {t("settings.demo.add")}
|
||||
</button>
|
||||
</Button>
|
||||
</form>
|
||||
|
||||
<div className="mt-4 pt-3 border-t border-border">
|
||||
@@ -917,24 +915,26 @@ function InviteRow({
|
||||
)}
|
||||
</div>
|
||||
<Tooltip hint={t("settings.invites.approveHint")}>
|
||||
<button
|
||||
<Button
|
||||
variant="outline-accent"
|
||||
size="icon-sm"
|
||||
className="shrink-0"
|
||||
onClick={onApprove}
|
||||
disabled={busy}
|
||||
className="shrink-0 p-1.5 rounded-lg border border-accent/40 text-accent hover:bg-accent/10 disabled:opacity-50 transition"
|
||||
aria-label={t("settings.invites.approve")}
|
||||
>
|
||||
<Check className="w-4 h-4" />
|
||||
</button>
|
||||
icon={<Check className="w-4 h-4" />}
|
||||
/>
|
||||
</Tooltip>
|
||||
<Tooltip hint={t("settings.invites.denyHint")}>
|
||||
<button
|
||||
<Button
|
||||
variant="outline-danger"
|
||||
size="icon-sm"
|
||||
className="shrink-0"
|
||||
onClick={onDeny}
|
||||
disabled={busy}
|
||||
className="shrink-0 p-1.5 rounded-lg border border-border text-muted hover:text-danger disabled:opacity-50 transition"
|
||||
aria-label={t("settings.invites.deny")}
|
||||
>
|
||||
<X className="w-4 h-4" />
|
||||
</button>
|
||||
icon={<X className="w-4 h-4" />}
|
||||
/>
|
||||
</Tooltip>
|
||||
{/* Deny records a decision and keeps the row; delete forgets the address. Once an account
|
||||
exists for it the row is that account's approval gate, so it is managed from Users & roles
|
||||
@@ -954,14 +954,15 @@ function InviteRow({
|
||||
</button>
|
||||
) : (
|
||||
<Tooltip hint={t("settings.invites.deleteHint")}>
|
||||
<button
|
||||
<Button
|
||||
variant="outline-danger"
|
||||
size="icon-sm"
|
||||
className="shrink-0"
|
||||
onClick={onDelete}
|
||||
disabled={busy}
|
||||
className="shrink-0 p-1.5 rounded-lg border border-border text-muted hover:text-danger disabled:opacity-50 transition"
|
||||
aria-label={t("settings.invites.deleteLabel", { email: inv.email })}
|
||||
>
|
||||
<Trash2 className="w-4 h-4" />
|
||||
</button>
|
||||
icon={<Trash2 className="w-4 h-4" />}
|
||||
/>
|
||||
</Tooltip>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user