feat(client): nav shell — icons, collapse, switchers, native drawer (#210) #211
No reviewers
Labels
No labels
area:auth
area:ci
area:db
area:infra
area:native
area:pwa
area:service
epic
feature
foundation
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
james/carol!211
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "210-nav-shell-features"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Brings the universal client's nav shell up to parity with the design package's spec. Closes / addresses #210.
lucide-react-native@1.21.0(pure-JS, no lavamoat allowlist work) + its peerreact-native-svg@15.15.4(the version paired with Expo SDK 56 inbundledNativeModules.json).lib/sidebarCollapsed.tshelper — SecureStore on native, localStorage on web. Collapsed width 64px, expanded 240px.useSetThemePreference→useUpdateSettings. Locale cycles throughSUPPORTED_LOCALESand persists locally vialib/i18n/persistence.ts(locale isn't on theSettingsDtotoday). Both controls collapse to icon-only buttons.Drawerlayout (which bundles react-navigation drawer +react-native-drawer-layoutinside SDK 56 — no extra workspace dep). Web ≥720px usesdrawerType: "permanent"+defaultStatus: "open". Native + narrow web usesdrawerType: "front"with a thinMobileHeadercontaining a Lucide hamburger that callsnavigation.openDrawer().GestureHandlerRootViewmounted at the root.tokens.accentplus the softaccentSubtlefill on active rows; brand wordmark usestokens.accentTextso the brand row reads as brand, not nav.Icon mapping (for review)
StickyNoteUserSparklesBriefcaseUsersFolderKanbanInboxMessageSquareSettingsSidebar chrome:
ChevronLeft/ChevronRightMonitor/Sun/MoonGlobeLogOutMenuCommits
chore(client): add lucide-react-native + nav icons (#210)feat(client): collapse + expand sidebar with persistence (#210)feat(client): theme + locale switchers in the sidebar footer (#210)feat(client): native drawer + mobile hamburger (#210)feat(client): tighter active-route + brand styling (#210)Test plan
pnpm install --frozen-lockfilepnpm -F @carol/api typecheck/lint/test(555 passed, 107 skipped)pnpm -F @carol/api openapi:checkpnpm -F @carol/api-client typecheck/lint/test/checkpnpm -F @carol/client typecheck/lint/testpnpm -F @carol/client export:webproduces a cleandist/Tradeoffs / notes
useWindowDimensions()re-renders the layout on viewport changes and we passdrawerTypeanddefaultStatusreactively.react-native-drawer-layouthandles thedrawerTypeswap idempotently (it treatspermanentasopen: trueregardless of the open prop), so resizing a desktop browser past the breakpoint swaps modes live without remount loops.SIDEBAR_WIDTHS.collapsedvsexpanded) are the load-bearing change; a Reanimated transition would be polish, not parity. Filed as a follow-up.expo-secure-store/localStoragehelper rather than expanding the API contract. Theme keeps usinguseSettings/useUpdateSettingsbecause it already exists inSettingsDto.expo-router/drawer(which inlinesreact-navigation/drawer+react-native-drawer-layoutin the SDK 56 build), so no extra workspace dep. MountedGestureHandlerRootViewat the root layout for swipe-to-open on native.Sidebar.tsxandFooterControls.tsxto use pre-flattened plain-object styles (vs[a, b]arrays). Carried over from PR #209's RNW interop fix; the drawer's inline-style merging exposed the same edge.Follow-ups worth filing
sidebarCollapsedandlocalecould graduate to the APISettingsDtoif cross-device sync is desired later; the current local-only persistence is intentional for the v1 scope.🤖 Generated with Claude Code
📊 Test coverage
Patch coverage: no testable lines changed.
Overall (
app/,lib/,db/, excluding UI per ADR-0019):Soft thresholds per ADR-0019. Coverage is informational and does not block merge.
Trivy (container image)
Threshold:
high· Total findings: 121 · At/above threshold: 16.27.0, 7.28.0, 8.5.0