feat/unified-sidebar-ux #188

Merged
haydar merged 7 commits from feat/unified-sidebar-ux into develop 2026-10-30 22:00:42 +00:00
Member
No description provided.
Share one sidebar implementation (useSidebarState + SidebarResizeHandle)
across PortalLayout and AdminLayout:

- Sidebar nav scrolls independently with an invisible scrollbar and
  contained overscroll.
- Right-edge drag handle resizes 220-480px with pointer capture,
  col-resize affordance, no text selection while dragging, double-click
  reset to 232px, and a main-content minimum-width bound that re-clamps
  live on window resize.
- Keyboard resize via role=separator: ArrowLeft/Right step 16px
  (Shift 64px); Escape cancels a live drag or closes the mobile drawer.
- Collapse hides the card and exposes a small expand button below the
  top bar; collapsed and width persist under dwb:portal:sidebar:* keys
  with a graceful no-localStorage fallback.
- Mobile drawer behaviour is unchanged; desktop chrome hides below the
  900px breakpoint and prefers-reduced-motion drops the transitions.
OpenProject already ships sidebar scrolling (#menu-sidebar is the
overflow-y:auto container), drag resize (opce-main-menu-resizer) and
collapse/expand with localStorage persistence via MainMenuToggleService.
The theme keeps all of it and only removes the visible scrollbar on
#menu-sidebar and the nested .dwb-project-groups scroller; no second
resizer or width bound is introduced.

Native width bounds (snap-to-collapse below ~11px, 280px default, no
fixed maximum) live in the compiled frontend service and cannot be
adjusted from a plugin stylesheet, so the cross-app 220-480px range is
documented rather than enforced.

test/sidebar.test.js pins the contract: hidden-scrollbar rules hit the
real scroll container without redeclaring overflow, the theme never
sets a width on #main-menu, and no JS/CSS targets the native resizer
or toggle selectors. browser_acceptance.py now asserts computed
overflowY stays auto, scrollbarWidth is none, exactly one resizer
exists, and the collapse/expand roundtrip works. A request spec checks
the native scaffolding is still rendered.
- Collapsed expand button gets a fixed slot below the 56px header band
  (--dwb-sidebar-open-top = max(navbar bottom, header height)) so it can
  never ride up over the navbar/logo when a static navbar scrolls away.
- Edge drag handle resizes the sidebar live via --dwb-sidebar-w, clamped
  to 220-480px, pointer capture + dbl-click reset; keyboard-accessible
  (role=separator, Arrow/Home/End). Width persists in
  dwb:code:sidebar:width; collapsed state migrates to
  dwb:code:sidebar:collapsed with legacy-key fallback.
- .page-footer is a sibling after .full.height, so it now gets the same
  margin-left offset as content — the fixed sidebar no longer obscures
  footer text. Offsets are gated on dwb-repo-sidebar-present so anonymous
  pages keep the native full-width layout.
- List sections move into .dwb-repo-sidebar-scroll: independent scrolling
  with the visual scrollbar hidden; header stays pinned; the resize
  handle is hidden below 1024px where the drawer overlay runs.
- The whole .dwb-sidebar is now the drawer's scroller: min-height:0 on
  the flex item plus overflow-y:auto/overflow-x:hidden and
  overscroll-behavior:contain bounds it below the header, so My
  Projects no longer bleeds past the drawer. The scrollbar is hidden
  (scrollbar-width:none + zero-size webkit rules) while wheel,
  trackpad and keyboard scrolling stay functional.
- Collapse control in a sticky chrome row at the top of the scroll
  container; collapsing sets the dwb-docs-sidebar-collapsed body class
  which hides .w-drawer--left, folding the grid's auto column to zero
  so the main column reclaims the space. A fixed expand tab on the
  window's left edge restores it. Persisted under
  dwb:docs:sidebar:collapsed.
- Right-edge resize grip (role=separator, focusable, Arrow/Home/End
  keys, double-click reset, pointer capture with document-level
  fallback) clamps the drawer to 220-480px by writing the same
  --w-drawer-width variable Wiki.js binds to its width prop, so the
  layout column and content shift together. Persisted under
  dwb:docs:sidebar:width and re-applied on every reconcile.
- Chrome mounts through the idempotent ensureChrome() pass — rail and
  grip are reconciled once and left alone afterwards, keeping the
  settled page mutation-free. The overlay (mobile) and 56px mini
  drawers keep their native chrome; RTL mirrors the grip and drag
  direction.
Merge remote-tracking branch 'origin/feat/sb-work' into feat/unified-sidebar-ux
All checks were successful
ci / commit-trailers (pull_request) Successful in 11s
ci / secret-scan (pull_request) Successful in 13s
ci / release-tests (pull_request) Successful in 1m34s
ci / portal-frontend (pull_request) Successful in 41s
ci / integrations-js (pull_request) Successful in 38s
ci / openproject-spec (pull_request) Successful in 28s
ci / portal-php (pull_request) Successful in 6m26s
ci / openproject-rspec (pull_request) Successful in 5m1s
f35a1b8df4
haydar scheduled this pull request to auto merge when all checks succeed 2026-10-30 21:54:00 +00:00
haydar merged commit eb0e9a3e90 into develop 2026-10-30 22:00:42 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
developing4all/devworkbase!188
No description provided.