From 30f1b6e6dbd77c541b5cdd571d02f72d732e6763 Mon Sep 17 00:00:00 2001 From: Developer Date: Fri, 26 Jun 2026 14:37:40 +0000 Subject: [PATCH] Touch-target audit: 44px minimum on mobile interactive elements (Slice 9) Apply the mobile-touch-target CSS class to 40 interactive elements across 12 files. The class applies min-height/min-width:44px only below md (max-width:767px), satisfying WCAG 2.5.5 / Apple HIG on touch devices. Desktop behavior is unchanged. Audit log (before -> after hit-area): - App.tsx: hamburger/dark-mode/sign-out (32/32/28 -> 44) - Dashboard.tsx: shortcut open/edit/delete (28 -> 44), enabled switch (18 -> 44) - Media.tsx: mobile pagination prev/next (28 -> 44) - FileBrowser.impl.tsx: 'Open Settings' alert button (28 -> 44) - UsersPage.impl.tsx: compose toolbar bold/italic/link/list (32 -> 44), attachment remove button (16 -> 44) - Settings.tsx: machine switch (18 -> 44), clear/add-machine buttons (28 -> 44), reset-db checkboxes x3 (16 -> 44) - Actions.tsx: 'Add action' button (28 -> 44) - ServicePage.tsx: service enabled switch (18 -> 44) - ServicesPage.tsx: service switch/open-link/delete-icon (18/28/32 -> 44) - ObservabilityPage.tsx: retry + 4 asChild link buttons (28 -> 44) - WidgetConfigDialog.tsx: 4 icon buttons (32 -> 44), 2 switches (18 -> 44), 2 add-widget buttons (28 -> 44) - SessionActivityPanel.tsx: 'Open in Users' button (28 -> 44) Deliberately skipped: default-size text buttons (32px, borderline), desktop-only sidebar toggle, DataTable internals (desktop-only below md), Select triggers. Dashboard anchor pills and HoverEditButton already had the class from Slices 1/2. No new tests (the class applies via @media which jsdom doesn't honor). 116 tests pass; lint/build green. Refs openspec/changes/mobile-responsive-parity/ (spec R6, tasks slice 9). --- frontend/src/App.tsx | 6 +++--- frontend/src/components/ObservabilityPage.tsx | 10 +++++----- frontend/src/components/SessionActivityPanel.tsx | 1 + frontend/src/components/WidgetConfigDialog.tsx | 14 +++++++++----- frontend/src/pages/Actions.tsx | 2 +- frontend/src/pages/Dashboard.tsx | 6 ++++-- frontend/src/pages/FileBrowser.impl.tsx | 1 + frontend/src/pages/Media.tsx | 2 ++ frontend/src/pages/ServicePage.tsx | 1 + frontend/src/pages/ServicesPage.tsx | 4 +++- frontend/src/pages/Settings.tsx | 8 ++++++-- frontend/src/pages/UsersPage.impl.tsx | 14 +++++++++----- 12 files changed, 45 insertions(+), 24 deletions(-) diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 5745104..316690b 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -194,7 +194,7 @@ function MobileDrawer() { return ( - @@ -281,7 +281,7 @@ function TopBar({ variant="ghost" size="icon" onClick={onToggleDarkMode} - className="h-8 w-8" + className="mobile-touch-target h-8 w-8" > {darkMode ? ( @@ -294,7 +294,7 @@ function TopBar({ variant="ghost" size="sm" onClick={onSignOut} - className="gap-2" + className="mobile-touch-target gap-2" > Logout diff --git a/frontend/src/components/ObservabilityPage.tsx b/frontend/src/components/ObservabilityPage.tsx index e5b34f8..8ca7019 100644 --- a/frontend/src/components/ObservabilityPage.tsx +++ b/frontend/src/components/ObservabilityPage.tsx @@ -141,7 +141,7 @@ function QueryError({ {label} failed {error.message} - @@ -255,7 +255,7 @@ function GrafanaLinkCard({
{title}
{description}
- } @@ -641,7 +641,7 @@ export function ObservabilityPage() { title="No Grafana service configured" description="Add a Grafana service instance to enable deep-links to dashboards and logs." action={ - } @@ -653,7 +653,7 @@ export function ObservabilityPage() { title="No machine selected" description="Add monitoring machines in Settings to see Grafana drill-down links." action={ - } diff --git a/frontend/src/components/SessionActivityPanel.tsx b/frontend/src/components/SessionActivityPanel.tsx index 6eeb6ae..8180552 100644 --- a/frontend/src/components/SessionActivityPanel.tsx +++ b/frontend/src/components/SessionActivityPanel.tsx @@ -168,6 +168,7 @@ export function SessionActivityPanel({ toggleEnabled(instance)} aria-label={`Toggle ${instance.title}`} /> - - diff --git a/frontend/src/pages/FileBrowser.impl.tsx b/frontend/src/pages/FileBrowser.impl.tsx index 7fb2434..fa84977 100644 --- a/frontend/src/pages/FileBrowser.impl.tsx +++ b/frontend/src/pages/FileBrowser.impl.tsx @@ -879,6 +879,7 @@ export function FileBrowser() { variant="outline" size="sm" onClick={() => navigateToSettings("/settings")} + className="mobile-touch-target" > Open Settings diff --git a/frontend/src/pages/Media.tsx b/frontend/src/pages/Media.tsx index 3bbf835..cf3cef2 100644 --- a/frontend/src/pages/Media.tsx +++ b/frontend/src/pages/Media.tsx @@ -167,6 +167,7 @@ function MediaMobilePagination({ } disabled={pageIndex <= 0} aria-label="Previous page" + className="mobile-touch-target" > Previous @@ -180,6 +181,7 @@ function MediaMobilePagination({ })) } disabled={pageIndex >= pageCount - 1} + className="mobile-touch-target" aria-label="Next page" > Next diff --git a/frontend/src/pages/ServicePage.tsx b/frontend/src/pages/ServicePage.tsx index 453a534..7f2603a 100644 --- a/frontend/src/pages/ServicePage.tsx +++ b/frontend/src/pages/ServicePage.tsx @@ -238,6 +238,7 @@ export function ServicePage() {
diff --git a/frontend/src/pages/ServicesPage.tsx b/frontend/src/pages/ServicesPage.tsx index 057e5c3..a9ff467 100644 --- a/frontend/src/pages/ServicesPage.tsx +++ b/frontend/src/pages/ServicesPage.tsx @@ -234,6 +234,7 @@ function CreateServiceDialog({
setDraft({ ...draft, enabled: checked }) @@ -328,6 +329,7 @@ export function ServicesPage() {