Touch-target pass: 44px min on default-size buttons (WCAG 2.5.5)

Applies .mobile-touch-target to 32 default-size <Button> elements (32px
tall, below the mobile minimum) across 9 files for strict WCAG 2.5.5
compliance: Save, Cancel, Delete, Validate SSH, Run job, Build index,
Update connection, Add service, etc. Plus the shared DialogFooter Cancel
+ Confirm buttons (used by every ConfirmDialog).

The class applies min-height/min-width: 44px only below md
(max-width: 767px); no-op at md+, so desktop sizing is unchanged.

Completes the touch-target audit started in Slice 9 (which covered icon
buttons, size=sm buttons, checkboxes, switches). 122 tests pass; lint/
build green. No new tests (@media queries aren't honored by jsdom).

Refs openspec/changes/mobile-responsive-parity/verify-report.md residual
risk #2.
This commit is contained in:
Developer
2026-06-26 15:45:34 +00:00
parent 09b9c45665
commit d05de0aacd
9 changed files with 78 additions and 25 deletions
+18 -2
View File
@@ -466,6 +466,7 @@ function MachineEditor({
</Alert>
<div className="flex flex-row flex-wrap items-center gap-2">
<Button
className="mobile-touch-target"
variant="outline"
onClick={onValidateSSH}
disabled={
@@ -678,6 +679,7 @@ function SSHKeyManager({
</div>
<div className="flex flex-row flex-wrap items-center gap-2">
<Button
className="mobile-touch-target"
disabled={saveKey.isPending}
onClick={async () => {
await saveKey.mutateAsync(draft);
@@ -687,6 +689,7 @@ function SSHKeyManager({
{editing ? "Update key" : "Save key"}
</Button>
<Button
className="mobile-touch-target"
variant="outline"
disabled={generateKey.isPending}
onClick={async () => {
@@ -710,11 +713,16 @@ function SSHKeyManager({
>
{generateKey.isPending ? "Generating..." : "Generate key"}
</Button>
<Button variant="outline" onClick={clear}>
<Button
variant="outline"
onClick={clear}
className="mobile-touch-target"
>
Clear
</Button>
{selectedKey && (
<Button
className="mobile-touch-target"
variant="destructive"
onClick={() => deleteKey.mutate(selectedKey.id)}
>
@@ -780,7 +788,11 @@ function ResetLocalDatabaseCard() {
Reset the local SQLite settings/media index databases after
acknowledging the data loss.
</p>
<Button variant="destructive" onClick={() => setOpen(true)}>
<Button
variant="destructive"
onClick={() => setOpen(true)}
className="mobile-touch-target"
>
Reset local database
</Button>
{resetDatabase.error && (
@@ -1117,6 +1129,7 @@ export function Settings() {
</div>
<div className="flex flex-row flex-wrap items-center gap-2">
<Button
className="mobile-touch-target"
variant="outline"
onClick={() =>
openEditMachine(
@@ -1144,6 +1157,7 @@ export function Settings() {
Edit
</Button>
<Button
className="mobile-touch-target"
variant="destructive"
onClick={() => setDeleteMachineId(selectedMachine.id)}
>
@@ -1207,6 +1221,7 @@ export function Settings() {
/>
{machineDraft.id ? (
<Button
className="mobile-touch-target"
variant="destructive"
onClick={() => setDeleteMachineId(machineDraft.id as string)}
>
@@ -1266,6 +1281,7 @@ export function Settings() {
secondaryAction={
machineDraft.id ? (
<Button
className="mobile-touch-target"
variant="destructive"
onClick={() => {
setDeleteMachineId(machineDraft.id as string);