Files
bface/src/ui/components
Amer Agovic 94a9f32969 Initial commit: bface library, build fixes, and refreshed docs
- Externalize all @tamagui/* and tamagui subpaths so dist no longer vendors Tamagui.
- Emit TypeScript declarations with vite-plugin-dts; fix package exports types for ui/*.
- Align initEnv with profiles: displayName, brandLogo, api.baseURL, themeColor, uiShell.
- Stabilize tests with Node localStorage file; env tests pass.
- Update README and component docs for services, menus, API client, and development.
2026-04-18 10:43:52 -05:00
..

Shell components

When consuming @reliancy/bface from npm, import shells and helpers from @reliancy/bface/ui/components (for example import { EmptyShell, useShell } from '@reliancy/bface/ui/components'). This repository uses @ui/* TypeScript path aliases in source; published paths follow package.json exports.

Shell components provide a flexible, responsive, sectioned layout system for the application. All components are built with Tamagui for cross-platform compatibility (web + React Native).

Architecture

Responsive Layout Structure

Desktop Layout (gtSm, > 801px)

┌─────────────────────────────────────┐
│  LeftSide │ MiddleSide │ RightSide │
│           │ ┌────────┐ │           │
│           │ │ Header │ │           │
│           │ ├────────┤ │           │
│           │ │  Main  │ │           │
│           │ │Content │ │           │
│           │ ├────────┤ │           │
│           │ │ Footer │ │           │
│           │ └────────┘ │           │
└─────────────────────────────────────┘

Mobile Layout (sm and below, ≤ 801px)

┌─────────────────────┐
│      Header         │
├─────────────────────┤
│   LeftSide (TopBar) │  ← Hamburger menu bar
├─────────────────────┤
│    MainContent      │
├─────────────────────┤
│     RightSide       │
├─────────────────────┤
│      Footer         │
└─────────────────────┘

Default Dimensions

  • LeftSide: 0px width (collapsed on desktop), full width on mobile
  • RightSide: 0px width (collapsed on desktop), full width on mobile
  • MiddleSide: 100% width (takes remaining space on desktop)
  • Header: 0px height (collapsed)
  • Footer: 0px height (collapsed)
  • MainContent: 100% height (flex: 1)

Usage

Basic Usage

import { EmptyShell } from '@ui/components';

function App() {
  return (
    <EmptyShell>
      <div>This goes to MainContent by default</div>
    </EmptyShell>
  );
}

Placing Children in Specific Sections

Method 1: Using ShellPlacement Component

import { EmptyShell, ShellPlacement } from '@ui/components';

function App() {
  return (
    <EmptyShell>
      <ShellPlacement placement="leftSide">
        <Sidebar />
      </ShellPlacement>
      
      <ShellPlacement placement="header">
        <Header />
      </ShellPlacement>
      
      <div>Main content (default placement)</div>
      
      <ShellPlacement placement="footer">
        <Footer />
      </ShellPlacement>
    </EmptyShell>
  );
}

Method 2: Using placement prop directly

import { EmptyShell } from '@ui/components';

function App() {
  return (
    <EmptyShell>
      <Sidebar placement="leftSide" />
      <Header placement="header" />
      <MainContent /> {/* Defaults to mainContent */}
      <Footer placement="footer" />
    </EmptyShell>
  );
}

Programmatic Control

Use the useShell hook to control section dimensions:

import { EmptyShell, useShell } from '@ui/components';

function SidebarToggle() {
  const { toggleLeftSide, leftSideWidth } = useShell();
  
  return (
    <button onClick={() => toggleLeftSide(250)}>
      {leftSideWidth === 0 ? 'Show' : 'Hide'} Sidebar
    </button>
  );
}

function Dashboard() {
  return (
    <EmptyShell>
      <Sidebar placement="leftSide" />
      <SidebarToggle />
      <MainContent />
    </EmptyShell>
  );
}

Available Control Functions

const {
  // Current dimensions
  leftSideWidth,
  rightSideWidth,
  headerHeight,
  footerHeight,
  
  // Setter functions
  setLeftSideWidth,
  setRightSideWidth,
  setHeaderHeight,
  setFooterHeight,
  
  // Convenience toggles
  toggleLeftSide,  // (targetWidth = 250) => void
  toggleRightSide  // (targetWidth = 250) => void
} = useShell();

Example: DashboardShell with Toggleable Sidebar

import { EmptyShell, useShell } from '@ui/components';

function DashboardShell({ children }) {
  return (
    <EmptyShell initialLeftWidth={250}>
      <Sidebar placement="leftSide" />
      <DashboardHeader placement="header" />
      {children}
      <DashboardFooter placement="footer" />
    </EmptyShell>
  );
}

function Sidebar() {
  const { toggleLeftSide, leftSideWidth } = useShell();
  
  return (
    <div>
      <button onClick={() => toggleLeftSide(250)}>
        {leftSideWidth === 0 ? '☰' : '✕'}
      </button>
      {/* Sidebar content */}
    </div>
  );
}

Placement Values

  • 'leftSide' or 'left' - Left sidebar
  • 'rightSide' or 'right' - Right sidebar
  • 'header' - Top header section
  • 'footer' - Bottom footer section
  • 'mainContent' or 'main' - Main content area (default)

Responsive Design

All shell components are responsive and automatically adapt to screen size using Tamagui's useMedia() hook:

  • Breakpoint: Switches at sm (801px) using Tamagui's default breakpoints
  • Desktop (> 801px): Horizontal layout with sidebars
  • Mobile (≤ 801px): Vertical stack layout

TopBar Component

The TopBar component automatically switches between wide and narrow layouts:

  • Desktop: Full horizontal navigation bar with all menu items visible
  • Mobile: Hamburger menu button + Sheet drawer for menu items

Subcomponents:

  • TopBar.Wide - Desktop layout (horizontal menu items)
  • TopBar.Narrow - Mobile layout (hamburger + Sheet)

Usage:

import { TopBar } from '@ui/components';

// Automatically responsive
<TopBar>
  {/* Custom content with placement */}
</TopBar>

SideBar Component

The SideBar component automatically switches between wide and narrow layouts:

  • Desktop: Fixed vertical sidebar with all menu items visible
  • Mobile: Hamburger menu button + Sheet drawer for menu items

Subcomponents:

  • SideBar.Wide - Desktop layout (vertical sidebar)
  • SideBar.Narrow - Mobile layout (hamburger + Sheet)

Usage:

import { SideBar } from '@ui/components';

// Automatically responsive
<SideBar>
  {/* Custom content with placement */}
</SideBar>

EmptyShell Responsive Behavior

EmptyShell automatically adapts its layout:

  • Desktop: Horizontal XStack with LeftSide, MiddleSide, RightSide side-by-side
  • Mobile: Vertical YStack with sections stacked: Header → LeftSide → MainContent → RightSide → Footer

On mobile, LeftSide becomes a full-width top bar (perfect for hamburger menus), and RightSide stacks below main content.

Platform-Agnostic

All shell components use Tamagui components (XStack, YStack, View, Sheet, useMedia) making them work on:

  • Web (React)
  • iOS (React Native)
  • Android (React Native)
  • Other platforms supported by Tamagui

The responsive design uses Tamagui's built-in breakpoints and media queries, ensuring consistent behavior across platforms.