Skip to content

starproject: mobile compatibility - #51

Open
roshantaneja wants to merge 29 commits into
mainfrom
roshan/mobile
Open

starproject: mobile compatibility#51
roshantaneja wants to merge 29 commits into
mainfrom
roshan/mobile

Conversation

@roshantaneja

Copy link
Copy Markdown
Contributor

Makes the entire starproject app mobile compatible. Consolidates the 10 unit PRs (#38, #40#48) into one branch; those PRs show as merged into this branch and their branches were deleted.

What's included

  • Header & nav: explicit viewport export, responsive header, hamburger menu below sm with proper a11y (focus return, aria-expanded/aria-controls, pointerdown dismiss, rotation reset); UserMenu touch-sized with accessible name on mobile
  • Field select popovers (FieldSelect/AssigneeSelect): viewport-clamped positioning, height capped to available space, visualViewport-aware, 44px touch rows
  • Task table: responsive column visibility (mobile: Task/Status/Due; md: +Priority/Assignees; lg: all), touch-sized rows, overflow-x-auto fallback
  • Board: horizontal snap-scroll columns below lg, long-press TouchSensor (250ms) so page scroll still works, middle-click drag blocked, presentational DragOverlay card, post-drag click suppression
  • Gantt: touch panning with momentum inside its own scroll container, Month default + denser bars on small screens, 44px mode buttons
  • Task modal: full-screen sheet below sm with internal scroll, stacked detail grids, wrapping breadcrumb/blockers/history, touch-sized RichTextEditor toolbar
  • Tasks workspace: stacked toolbar, full-width search, horizontally scrollable filter-chip rows
  • List pages: shared PAGE_CONTAINER (px-4 sm:px-6 py-6 sm:py-8), dashboard grid md:grid-cols-2 lg:grid-cols-4, EntityRow stacking + 44px targets, long-name overflow guards
  • Settings / workspace admin / health / activity: stacked forms, 44px toggles and buttons, wrapping feed rows, dialogs capped at 85dvh with internal scroll

Conventions: mobile-first Tailwind (v4 defaults), all dark: pairings preserved, ≥44px touch targets, no new dependencies, no page-level horizontal scroll at 375px.

Verification

typecheck, lint (zero warnings), vitest (34/34), and next build all pass on the integrated branch (including the merge of main with #39's assignee-chips work — one conflict in BlockerEditor.tsx resolved by combining the mobile sizing with the blocker-bleed fix). Each unit also went through a code-review pass during the batch, with findings fixed before landing. No browser e2e was run (per earlier decision) — recommend a quick visual pass at ~375px before merging, especially board drag and gantt.

Follow-ups (deliberately deferred)

https://claude.ai/code/session_01Y4bjpQZMSDyrkga1zptvRT

roshantaneja and others added 22 commits September 4, 2026 13:14
- Clamp the portal popup horizontally to the viewport with an 8px margin,
  re-measuring the popup's real width once mounted
- Cap popup height to the space actually available above/below the trigger
  (visual-viewport aware, so the iOS keyboard shrinks it too) and anchor
  with `bottom` when flipping above so the menu hugs the trigger
- Reposition on window.visualViewport resize (mobile keyboard)
- Touch-friendly option rows: min-h-11 with larger padding on mobile,
  shrinking back at sm:; search inputs use text-base on mobile to avoid
  iOS focus zoom
- FieldSelect hover highlight now only follows mouse pointers, so taps
  select directly without a stale active state

Claude-Session: https://claude.ai/code/session_01Y4bjpQZMSDyrkga1zptvRT
- TasksWorkspace toolbar stacks on mobile: full-width view tabs, w-full
  search, wrapping action row; touch targets >=44px via min-h-11
- Project/subteam filter chip rows scroll horizontally on mobile
  (overflow-x-auto, flex-nowrap) and wrap as before on sm+
- /tasks page container uses px-4 sm:px-6 py-6 sm:py-8
- NewTaskForm stacks full-width fields on mobile (w-full sm:min-w-56),
  touch-sized inputs and submit button

Claude-Session: https://claude.ai/code/session_01Y4bjpQZMSDyrkga1zptvRT
- layout.tsx: explicit viewport export (device-width, initialScale 1)
- AppHeader: px-4 sm:px-6 container, h-8 sm:h-10 logo, hide Project
  wordmark below 420px, relative header to anchor the mobile nav panel
- HeaderNav: collapse tabs into a 44px hamburger below sm with a
  full-width panel (closes on navigation, outside click, and Esc);
  inline tabs with active underline unchanged at sm+
- UserMenu: avatar-only trigger below sm, 44px touch targets on mobile,
  dropdown capped at calc(100vw-2rem) so it stays on-screen at 375px

Claude-Session: https://claude.ai/code/session_01Y4bjpQZMSDyrkga1zptvRT
- Containers: px-4 sm:px-6 / py-6 sm:py-8 on settings, workspace, health
- DigestSettings: grid-cols-1 sm:grid-cols-2 for include-kinds; touch-sized chips and checkbox rows
- AdminConfig: add-admin row stacks full-width on mobile (w-full sm:min-w-56), 44px targets
- Workspace subteam form: input takes full row on mobile (basis-full sm:min-w-48), larger color/create controls
- Email/theme switches: 44px rows with expanded invisible hit area (after:-inset-2.5)

Claude-Session: https://claude.ai/code/session_01Y4bjpQZMSDyrkga1zptvRT
- Activity page: tighter mobile padding, feed rows stack sentence over
  timestamp with wrapping, touch-sized wrapping pagination controls
- ActivityFilters: filters stack full-width and touch-sized on mobile
- ConfirmButton/EditEntityButton dialogs: max-h-[85dvh] with internal
  scroll, 44px action buttons, full-width color input on mobile
- NewProjectForm: fields stack full-width on mobile, 44px controls

Claude-Session: https://claude.ai/code/session_01Y4bjpQZMSDyrkga1zptvRT
- TaskModalProvider: panel is full-screen (h-dvh, no radius) below sm,
  sm keeps centered max-w-3xl / max-h-[85dvh]; content scrolls internally;
  close button is 44px with a solid bg + ring so content scrolling under
  it stays legible; Esc / backdrop / deep-link behavior unchanged
- TaskDetail: inner Status/Priority/Assignees/Due grid stacks to one
  column on mobile; breadcrumb wraps and truncates long project names;
  blocker/blocking/history rows wrap; 44px touch targets on interactive
  rows and archive buttons (shared btn const)
- RichTextEditor: 44px wrapping toolbar buttons on mobile; read view has
  a visible border on mobile instead of hover-only affordance
- BlockerEditor: note input goes full-width on mobile (sm keeps
  flex-1 min-w-40); 44px Add button
- CopyLinkButton / EditableTitle: 44px touch targets, title wraps
- DueDateInput sizing scoped to the modal via a TaskDetail wrapper so
  the shared component is unchanged for TaskTable

Claude-Session: https://claude.ai/code/session_01Y4bjpQZMSDyrkga1zptvRT
- HeaderNav: return focus to the hamburger on Escape; aria-controls +
  panel id instead of aria-haspopup on a non-menu; close via pointerdown
  (iOS taps don't synthesize mousedown); close when the viewport crosses
  to sm+ so the panel can't reappear open after rotating back; panel
  z-50 to match the app's dropdown layer; dedupe the two LINKS maps into
  a local NavItem; align panel link text with the header content (16px);
  type="button" on the toggle
- UserMenu: aria-label={name} so the trigger keeps an accessible name
  when the name span is hidden on mobile; gate the dismiss listener on
  open, use pointerdown, and add Escape-to-close with focus return;
  clamp the dropdown with a margin that accounts for scrollbar-gutter;
  type="button" on the trigger
- AppHeader: comment that `relative` anchors HeaderNav's full-width
  mobile panel

Claude-Session: https://claude.ai/code/session_01Y4bjpQZMSDyrkga1zptvRT
- Board columns below lg get a fixed width (75vw clamped 16-20rem) inside a
  horizontal overflow-x-auto container with scroll-snap; lg+ keeps the
  all-columns-visible flex-1 layout. Snap classes are dropped while a drag is
  active so mandatory snapping cannot fight dnd-kit's auto-scroller.
- Replace PointerSensor with a primary-button-only MouseSensor (middle-click
  no longer starts a drag) plus a TouchSensor (delay 250ms, tolerance 5px) so
  quick touches scroll the page and a long-press drags.
- TaskCard: touch-none -> touch-manipulation + select-none so scrolling over
  cards works and iOS long-press does not select text; slightly larger padding
  below sm; suppress the post-drag click so a long-press release does not open
  the task modal; fix dark hover border class.
- DragOverlay now renders a presentational TaskCardOverlay instead of a second
  interactive useSortable card with a duplicate id.

Claude-Session: https://claude.ai/code/session_01Y4bjpQZMSDyrkga1zptvRT
- Shared PAGE_CONTAINER const (px-4 py-6, sm:px-6 sm:py-8) used by home,
  projects, subteams list pages and DetailView
- Home dashboard grid stacks on mobile, 2 cols at md, 4 at lg; touch-sized
  row links and "All" links
- EntityRow stacks name/count/buttons on narrow screens with 44px delete
  target lifted above the stretched link
- DetailView tabs are touch-sized and horizontally scrollable on mobile
- ProjectView and subteam headers stack title/actions on mobile; long
  names can no longer force horizontal scroll

Claude-Session: https://claude.ai/code/session_01Y4bjpQZMSDyrkga1zptvRT
- ActivityFilters/NewProjectForm: items-start on mobile column so
  FieldSelect triggers stay content-width instead of stretching with a
  left-glued chevron
- Activity pagination: ml-auto keeps Prev/Next right-aligned when the
  footer wraps

Claude-Session: https://claude.ai/code/session_01Y4bjpQZMSDyrkga1zptvRT
* starproject mobile: responsive task table columns

Hide lower-priority TaskTable columns below breakpoints (mobile shows
Task/Status/Due; md: adds Priority + Assignees; lg: adds Subproject/
Project/Subteam) via a CSS-only per-column visibility map applied to
both th and td. Bump mobile row/header padding for >=44px touch
targets and let the title cell wrap. Row-click modal, inline editors,
and the overflow-x-auto fallback are unchanged.

Claude-Session: https://claude.ai/code/session_01Y4bjpQZMSDyrkga1zptvRT

* Address review: rename visibility map, document admin delete column

Rename columnVisibility -> columnClasses to avoid colliding with
TanStack Table's built-in columnVisibility state, and fix the comment
to note the admin delete column stays visible at every width.

Claude-Session: https://claude.ai/code/session_01Y4bjpQZMSDyrkga1zptvRT
- Timeline pans inside frappe's .gantt-container scroller with touch
  momentum and overscroll-x containment; page body never widens at 375px.
- Day/Week/Month buttons are 44px tap targets on mobile, compact from sm:.
- Default to the denser Month view on small screens (matchMedia on mount,
  post-hydration to avoid SSR mismatch).
- Taller bars/rows (~44px) on small screens via frappe-gantt bar_height/
  padding options; larger SVG label text under 640px in globals.css.
- Touch drag cannot accidentally reschedule: frappe-gantt 0.6.1 binds
  dragging to mouse events only (documented in-code); today-marker math is
  unaffected since per-mode step/column_width are unchanged.

Claude-Session: https://claude.ai/code/session_01Y4bjpQZMSDyrkga1zptvRT
# Conflicts:
#	starproject/src/components/BlockerEditor.tsx
… bottom-sheet dialog

On phones the inline create form (title, project, priority, assignees,
subteam, due date) stacked into a tall card on /tasks, project, and
subteam pages. Below sm it now renders as a single Add task button that
opens a bottom-sheet dialog with the same fields; Esc/backdrop/✕ close
it and it closes itself after a successful create. Desktop inline form
unchanged.

Claude-Session: https://claude.ai/code/session_01Y4bjpQZMSDyrkga1zptvRT
@roshantaneja

Copy link
Copy Markdown
Contributor Author
Screenshot 2026-09-08 at 12 25 42 Screenshot 2026-09-08 at 12 25 52 Screenshot 2026-09-08 at 12 26 00 Screenshot 2026-09-08 at 12 27 22 Screenshot 2026-09-08 at 12 27 33

Screenshot 2026-09-08 at 12 27 44

a-e397-4eb2-aa6a-367a1af1e363" /> Screenshot 2026-09-08 at 12 28 26

…der, softer type scale

- New ViewDock: mobile-only bottom dock (List/Board/Timeline) used by both
  DetailView (link mode) and TasksWorkspace (state mode); the old tab rows
  are now desktop-only and pages add bottom padding to scroll clear of it
- NewTaskForm's mobile trigger is now a floating + button pinned above the
  dock at bottom right, opening the same bottom-sheet form
- AppHeader is sticky top-0 z-40 so the nav stays docked while scrolling
- Type scale reduced ~1pt per step via @theme (text-xs through text-2xl);
  spacing and touch targets unchanged

Claude-Session: https://claude.ai/code/session_01Y4bjpQZMSDyrkga1zptvRT
@swissskimmilk

Copy link
Copy Markdown
Contributor

I feel like for activity those selection dropdowns could fit in the same row. Also how does it handle when there are hella projects in task view? I imagine this would get really messed up on mobile, maybe we just show some of the options and popup to see the rest idk
image

@swissskimmilk

Copy link
Copy Markdown
Contributor

Also how does the board and the timeline views look?

The X sat 4px from the corner of a 12px-radius card, crowding the curve.
Now right-3/top-3 (12px, matching rounded-xl), with TaskDetail's
compensating right padding bumped pr-8 -> pr-10 so the breadcrumb and
title rows still clear the button.

Claude-Session: https://claude.ai/code/session_01Y4bjpQZMSDyrkga1zptvRT
@roshantaneja

Copy link
Copy Markdown
Contributor Author

here i revamped the board view and timeline buttons to the bottom to minimize scrolling, with some other cosmetic fixes to the task popout card on mobile

Screenshot 2026-09-08 at 16 25 36 Screenshot 2026-09-08 at 16 25 51 Screenshot 2026-09-08 at 16 26 05

and on ipad/horizontal it looks good too

@roshantaneja

Copy link
Copy Markdown
Contributor Author

the plus button on the bottom right is the add task button, which opens a popup where we can add tasks. also helps reduce vertical scrolling

…ilters

The tasks-view project/subteam chip rows become a wall with many entries.
Each row now shows the first 8 chips (plus any selected beyond the cap so
active filters stay visible) with a +N more / Show less toggle; collapsed
rows stay a single scrollable line on mobile, expanded rows wrap.
Activity's filter dropdowns now share a wrapping row on mobile instead of
stacking one per line.

Claude-Session: https://claude.ai/code/session_01Y4bjpQZMSDyrkga1zptvRT
Projects/Subteams labels moved outside the horizontal scroll container so
they stay fixed on the left while the chips carousel beside them; when
expanded the label top-aligns with the first wrapped row.

Claude-Session: https://claude.ai/code/session_01Y4bjpQZMSDyrkga1zptvRT
@roshantaneja

Copy link
Copy Markdown
Contributor Author

OK, I made the subteam and project chips scrollable on mobile and much larger and easier to tap on the mobile site. It should have a better experience now. I'm pretty against having like 5 dropdowns at the top of the screen, between the nav, the statuses, the search bar, etc., so this makes it a bit easier, at least for now, with our subprojects and teams.

Screenshot 2026-09-08 at 16 33 01

order-first puts the My tasks tile at the top of the single-column mobile
stack; md:order-none restores source order once the grid kicks in.

Claude-Session: https://claude.ai/code/session_01Y4bjpQZMSDyrkga1zptvRT
The bottom sheet was covered by the on-screen keyboard when typing; the
dialog is now a top sheet (safe-area-aware) so fields stay visible.

Claude-Session: https://claude.ai/code/session_01Y4bjpQZMSDyrkga1zptvRT
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.

2 participants