From c7e71360cb11aa9901781caa30d7a29e6fa0975c Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 19 Apr 2026 04:07:06 +0000 Subject: [PATCH] feat(ui): implement responsive design Phase 0 & Phase 1 Phase 0 - Foundation: - Add ContentContainer: max-width 1440 centered wrapper for large screens - Add ResponsiveStack: XStack that collapses to column at $md breakpoint Phase 1 - Layout Shell: - Sidebar: off-canvas Sheet drawer on mobile/tablet ($md and below), classic inline sidebar on desktop ($gtMd); visibility state lifted to Layout - Sidebar.state: remove isShown (now managed by Layout), fix SSR-unsafe window.location.pathname with typeof window guard - Navbar: add leftActionItem prop, $xs column stacking, numberOfLines+ellipsis on title for overflow safety - Layout: manage sidebar open/close state via useMedia() for viewport-aware defaults (open on desktop, closed on mobile); add hamburger button for mobile; responsive content padding ($3/$4/$5 by breakpoint); wrap children in ContentContainer https://claude.ai/code/session_01R25cNRQMhafRu4VQ7njNFL --- .../components/base/ContentContainer.tsx | 12 + .../presentation/components/base/Layout.tsx | 47 +++- .../components/base/Navbar/Navbar.tsx | 11 +- .../components/base/ResponsiveStack.tsx | 8 + .../components/base/Sidebar/Sidebar.state.tsx | 12 +- .../components/base/Sidebar/Sidebar.tsx | 219 ++++++++++-------- .../presentation/components/base/index.tsx | 2 + 7 files changed, 193 insertions(+), 118 deletions(-) create mode 100644 libs/ui/src/presentation/components/base/ContentContainer.tsx create mode 100644 libs/ui/src/presentation/components/base/ResponsiveStack.tsx diff --git a/libs/ui/src/presentation/components/base/ContentContainer.tsx b/libs/ui/src/presentation/components/base/ContentContainer.tsx new file mode 100644 index 00000000..1ccc2228 --- /dev/null +++ b/libs/ui/src/presentation/components/base/ContentContainer.tsx @@ -0,0 +1,12 @@ +import { YStack } from 'tamagui'; +import { ReactNode } from 'react'; + +type ContentContainerProps = { + children: ReactNode; +}; + +export const ContentContainer = ({ children }: ContentContainerProps) => ( + + {children} + +); diff --git a/libs/ui/src/presentation/components/base/Layout.tsx b/libs/ui/src/presentation/components/base/Layout.tsx index c2e20430..1f72a635 100644 --- a/libs/ui/src/presentation/components/base/Layout.tsx +++ b/libs/ui/src/presentation/components/base/Layout.tsx @@ -1,7 +1,9 @@ -import { PortalProvider, XStack, YStack } from 'tamagui'; +import { Menu } from '@tamagui/lucide-icons'; +import { Button, PortalProvider, XStack, YStack, useMedia } from 'tamagui'; import { Sidebar } from './Sidebar'; import { Navbar } from './Navbar/Navbar'; -import { ReactNode } from 'react'; +import { ContentContainer } from './ContentContainer'; +import { ReactNode, useEffect, useState } from 'react'; export type LayoutProps = { children: React.ReactNode; @@ -18,18 +20,53 @@ export const Layout = ({ rightActionItem, onLogoutPress, }: LayoutProps) => { + const media = useMedia(); + const [isSidebarShown, setIsSidebarShown] = useState(false); + + // Default: open on desktop, closed on mobile/tablet + useEffect(() => { + setIsSidebarShown(!!media.gtMd); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); // Intentionally runs once on mount with initial media value + + const onToggleSidebar = () => setIsSidebarShown((prev) => !prev); + + const hamburgerButton = ( + + + + ); + + // Mobile/tablet (md and below): off-canvas Sheet drawer + if (!media.gtMd) { + return ( + + {sidebarContent} + + ); + } + + // Desktop (gtMd): classic inline sidebar return ( <> - - - -
Gatherloop POS
-
- - - {items.map((item) => ( - - { - if (item.path) { - event.preventDefault(); - router.push(item.path); - } - }} - > - {({ open }: { open: boolean }) => ( - <> - - - {item.title} - - {item.subItems && ( - - - - )} - - )} - - - {item.subItems && ( - - - {item.subItems.map((subItem, index) => ( - - - - {subItem.title} - - - - ))} - - - )} - - ))} - -
- - - - -
+ {sidebarContent}
{!isShown && ( + /> )} ); diff --git a/libs/ui/src/presentation/components/base/index.tsx b/libs/ui/src/presentation/components/base/index.tsx index 4c3b8e72..c43ee292 100644 --- a/libs/ui/src/presentation/components/base/index.tsx +++ b/libs/ui/src/presentation/components/base/index.tsx @@ -14,3 +14,5 @@ export * from './Markdown'; export * from './Tabs'; export * from './ConfirmationAlert'; export * from './SkeletonView'; +export * from './ContentContainer'; +export * from './ResponsiveStack';