Skip to content

fix(astro-kbve): make ArgoCD dashboard rows tappable on mobile - #11578

Merged
h0lybyte merged 1 commit into
devfrom
trunk/argo-mobile-fix-1780356441
Jun 1, 2026
Merged

fix(astro-kbve): make ArgoCD dashboard rows tappable on mobile#11578
h0lybyte merged 1 commit into
devfrom
trunk/argo-mobile-fix-1780356441

Conversation

@h0lybyte

@h0lybyte h0lybyte commented Jun 1, 2026

Copy link
Copy Markdown
Member

Summary

The ArgoCD dashboard rendered clickable rows as `

` with a fixed `24px 1fr 100px 120px 120px 180px` grid (~544 px min). Combined, the row failed on phones for three reasons:

  1. iOS Safari + `
    ` — treats unstyled divs as non-interactive for tap purposes more often than a real ``, and bakes in the legacy ~300 ms tap delay.
  2. Grid overflows phone viewports — the row scrolls horizontally, so the chevron + click hit-area drift off the visible page and taps land on sibling rows or empty space.
  3. `client:only="react"` re-hydration race — re-mounts on every ClientRouter swap. On a slower mobile CPU there's a brief window where the DOM is painted but handlers aren't attached yet. Desktop is fast enough that it's invisible.

Changes

  • App row header + resource-tree row → real `<button type="button">` with `aria-expanded` + `touch-action: manipulation` + `-webkit-tap-highlight-color: transparent`. Tap is treated as a click immediately, no 300 ms delay, no grey flash.
  • Grid moved from inline style into a single injected `<style>` block. Class `.kbve-argo-row` carries the desktop 6-column grid and a mobile 4-column collapse (chevron + name + sync + health) under `@media (max-width: 768px)`. The Project + Last Sync columns are hidden on phones — there isn't room for them, and they're available again as soon as the row expands.
  • Ellipsis + `min-width: 0` on the name cell so long app names don't push the row wider than the viewport.

Expand behaviour, resource tree, and the desktop look are unchanged.

`nx run astro-kbve:build` → 7682 pages, 0 errors.

Test plan

  • Desktop `/dashboard/argo/` → rows still 6 columns, click expand/collapse works
  • Phone (or DevTools mobile emulation) → row collapses to 4 columns, no horizontal scroll, tap on the row expands cleanly
  • Long app names → name ellipses cleanly without spilling the grid
  • Tap on a resource inside an expanded app → opens the detail panel, no double-tap needed
  • Keyboard `Tab` lands on each row, `Enter` / `Space` toggles expand (free with the `` swap)

The ArgoCD dashboard rendered clickable rows as `<div onClick>` with
a fixed 24px / 1fr / 100px / 120px / 120px / 180px grid (≈544px min).
That combination failed for phones on three separate axes:

1. iOS Safari treats unstyled `<div onClick>` as non-interactive for
   tap purposes more often than a real `<button>`, plus it bakes in
   the legacy ~300ms tap delay.
2. The fixed grid overflowed phone viewports — the row scrolled
   horizontally so the chevron and click hit-area drifted off the
   visible page, and taps landed on sibling rows or empty space.
3. `client:only="react"` re-hydrates after every ClientRouter swap.
   On a slower mobile CPU there's a brief window where the DOM is
   painted but handlers aren't attached yet, which is invisible on
   desktop.

This PR keeps the desktop layout identical and lands three small
mobile fixes:

- Convert the expandable application row header + the resource-tree
  row from `<div onClick>` to a real `<button type="button">` with
  `aria-expanded` on the app row. Adds `touch-action: manipulation`
  + `-webkit-tap-highlight-color: transparent` so iOS treats the tap
  as a click immediately and doesn't paint the grey flash.
- Move the grid definition off the inline style and into a single
  injected `<style>` block. The same class `.kbve-argo-row` carries
  the full 6-column desktop grid AND a 4-column mobile collapse
  (24px chevron + name + sync + health) under `@media (max-width:
  768px)`, hiding the project + last-sync columns where there's no
  room.
- Add ellipsis + `min-width: 0` on the name cell so long app names
  don't push the row wider than the viewport.

The expand behaviour, the resource tree, and the desktop look are
unchanged. `nx run astro-kbve:build` → 7682 pages, 0 errors.
@github-actions

github-actions Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@h0lybyte
h0lybyte merged commit 9bc51b1 into dev Jun 1, 2026
4 checks passed
@h0lybyte
h0lybyte deleted the trunk/argo-mobile-fix-1780356441 branch June 1, 2026 23:37
h0lybyte added a commit that referenced this pull request Jun 2, 2026
… projects (#11584) (#11633)

Adds three project profiles to playwright.config.ts so dashboard e2e and
visual-regression suites cover the UA matrix that PR #11578's mobile-only
Argo bug slipped through.

- chromium (existing)
- webkit (Desktop Safari)
- mobile-chrome (Pixel 7)
- mobile-safari (iPhone 14)
h0lybyte added a commit that referenced this pull request Jun 2, 2026
…ls (#11585) (#11637)

apps/kbve/astro-kbve/e2e/argo.spec.ts covers the regression class that
slipped past CI in PR #11578:

- unauth load renders the Sign In Required gate
- mocked-session load renders app rows as <button aria-expanded="false">
- tap → aria-expanded flips to true
- Project + Last Sync columns hide under 768px (asserted on mobile projects)

Depends on #11584 (mobile/webkit Playwright projects) and #11586
(mockSupaSession + mockArgoApi fixture).
h0lybyte added a commit that referenced this pull request Jun 2, 2026
#11663)

- @axe-core/playwright added to root dev deps (4.10.2)
- e2e/fixtures/axe.ts exposes runAxe(page) with these defaults:
  - WCAG 2.0/2.1 A + AA tags + best-practice
  - Fails only on impact === 'serious' || 'critical' (warnings stay noisy)
  - Allow-list of selector patterns for known out-of-scope violations
    (Starlight built-ins via /starlight-/i prefix); per-call override
    extends the list
- e2e/axe.spec.ts covers:
  - Argo dashboard authenticated (mocked session + API)
  - Argo dashboard sign-in gate
  - Homepage

The <div onClick> regression from PR #11578 would have failed runAxe
on the kbve-argo-row scope (no role=button + no keyboard handler).
h0lybyte added a commit that referenced this pull request Jun 3, 2026
…11736)

User report: tapping rows in /osrs/ on iPhone Safari did nothing. The
list is a react-window 2 virtualized container (migrated 1.8.11 →
2.2.7 in #11616). Inside an iOS Safari momentum-scrolling container,
the browser queues taps on positioned <a> elements as possible scroll
starts; without an explicit touch-action hint the click never fires.

Same failure mode as PR #11578 (Argo row tap), different surface.

Fix in OSRSItemBrowser.tsx:
- Row link gets touchAction: 'manipulation' (kills 300ms tap delay +
  resolves scroll-vs-tap ambiguity), cursor: 'pointer', and
  WebkitTapHighlightColor for visible feedback on iOS.
- Inner <img> + content <div> get pointer-events-none so taps that
  land on a child element bubble cleanly to the <a> for navigation.
- data-osrs-row + data-osrs-slug attributes for e2e selectors.
- active: bg state added so users see touch feedback.

New e2e at apps/kbve/astro-kbve/e2e/osrs.spec.ts covers:
- Virtualized list renders rows after mount.
- Search input filters the list ('whip' narrows down).
- Tapping a row navigates to its detail page — exact regression the
  user reported. Runs across chromium / webkit / mobile-chrome /
  mobile-safari (added in #11584) so the Safari-only failure mode is
  now CI-visible.
- Row has touchAction=manipulation + cursor=pointer — fast canary
  that surfaces a future style regression at the property level.
- Anchor tag has a non-empty href + is an <A> (defends against a
  future refactor to <div onClick> that would re-introduce the
  same a11y / touch break).
- Tag filter dropdown changes the rendered set.

Build artifact verified: dist/apps/astro-kbve/osrs/index.html present,
OSRSItemBrowser island marker emitted.
h0lybyte added a commit that referenced this pull request Jun 3, 2026
…11739)

Same failure class as #11736 (osrs) and #11578 (argo). MC browser
cards are <a href> grid tiles with a transform-driven hover. iOS
Safari:
  1. Sticky-hovers the card on first tap because :hover is unqualified
     (first tap = hover paint, click only fires on second tap).
  2. Swallows the tap entirely under momentum-scroll when no
     touch-action hint is set on the anchor.
  3. Auto-zooms on the search input because its font-size is 0.9rem
     (~14.4px) — Safari zooms anything < 16px on focus.

src/styles/global.css (.mcdb-browse__card):
  - Add cursor: pointer + touch-action: manipulation +
    -webkit-tap-highlight-color.
  - Gate the :hover transform behind @media (hover: hover) so iOS
    never enters sticky-hover.
  - Add :active state with reduced transform so touch users still get
    visual feedback on tap.
  - Children get pointer-events: none so taps that land on the icon
    or label bubble to the <a>.

src/styles/global.css (.mcdb-browse__page-btn, .mcdb-browse__reset):
  - touch-action: manipulation + tap-highlight, matching the cards.

src/styles/global.css (.mcdb-browse__input):
  - @media (max-width: 768px) bumps font-size to 16px so iOS Safari
    no longer zooms in when the user focuses the search field.

src/components/mcdb/MC{Blocks,Items,Enchants}Browser.tsx:
  - Anchor adds data-mc-card={kind} + data-mc-slug={slug} so the e2e
    can select cards by kind without coupling to the MC slug shape.

apps/kbve/astro-kbve/e2e/mc.spec.ts (new):
  Parameterised across blocks / items / enchants. Runs on all four
  projects (chromium, webkit, mobile-chrome, mobile-safari).
  Each section asserts:
    1. grid renders cards
    2. computed touch-action=manipulation + cursor=pointer canary
    3. card is <a> with valid href (defends against a future
       <div onClick> refactor)
    4. tapping a card navigates to its detail page (the exact
       regression)
    5. search input font-size >= 16px on mobile projects (no iOS
       auto-zoom)
    6. typing in the search input changes the rendered set

Build: 7689 pages, green.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant