All docs/Hello

docs/architecture/hello-component-architecture.md

Last verified: 2026-03-03 Target: apps/hello Companion: packages/app-hello

Hello App Component Architecture

Overview

The Hello app uses a composable component architecture where layout concerns are separated from functionality. This document covers the core wrapper components and their composition patterns.

Component Hierarchy

Visual Diagram (Desktop)

┌─────────────────────────────────────────────────────────────────────────────┐
│                              PAGE STRUCTURE                                  │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│  SHARED INNER COMPONENT                                                      │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │ OnboardingPanel (header + content + background, flexible height)     │    │
│  │  [← Back]                                           [HeaderSlot]     │    │
│  │  ─────────────────────────────────────────────────────────────────   │    │
│  │                            {children}                                │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
│                                                                              │
│                                                                              │
│  NON-PREVIEW PAGES (Company, Objective, etc.)                               │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │ OnboardingScreen (min-h-screen wrapper)                              │    │
│  │  └── OnboardingPanel                                                 │    │
│  │       [← Back]                                      [HeaderSlot]     │    │
│  │       ─────────────────────────────────────────────────────────────  │    │
│  │                         <StepComponent />                            │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
│                                                                              │
│                                                                              │
│  PREVIEW PAGES (Studio, Configure)                                          │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │ WithFlowPreview                                                       │    │
│  │  ┌─────────────────────────────┬───────────────────────────────┐    │    │
│  │  │ LEFT PANEL (50%)            │ RIGHT PANEL (50%)             │    │    │
│  │  │ ┌─────────────────────────┐ │ ┌───────────────────────────┐ │    │    │
│  │  │ │ OnboardingPanel         │ │ │                           │ │    │    │
│  │  │ │ [← Back]    [HeaderSlot]│ │ │ ContextualFlowPreview     │ │    │    │
│  │  │ │ ─────────────────────── │ │ │                           │ │    │    │
│  │  │ │      {children}         │ │ │ (clean, no chrome)        │ │    │    │
│  │  │ └─────────────────────────┘ │ │        [Fullscreen btn]   │ │    │    │
│  │  │                             │ └───────────────────────────┘ │    │    │
│  │  └─────────────────────────────┴───────────────────────────────┘    │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

Mobile Layouts

Non-Preview Page:

┌────────────────────────┐
│ OnboardingScreen       │
│ ┌──────────────────┐   │
│ │ OnboardingPanel  │   │
│ │ [←]        [Auth]│   │  ← Header
│ │ ──────────────── │   │
│ │                  │   │
│ │   <StepContent>  │   │
│ │                  │   │
│ └──────────────────┘   │
└────────────────────────┘

Preview Page:

┌────────────────────────┐
│ WithFlowPreview        │
│ ┌──────────────────┐   │
│ │ OnboardingPanel  │   │
│ │ [←]        [Auth]│   │  ← Header (from OnboardingPanel)
│ └──────────────────┘   │
│ ┌──────┬───────────┐   │
│ │Config│Preview    │   │  ← Tab navigation
│ └──────┴───────────┘   │
│ ┌──────────────────┐   │
│ │                  │   │
│ │   Tab Content    │   │
│ │                  │   │
│ └──────────────────┘   │
└────────────────────────┘

Component Module Overview

Integration Map

Core Components

OnboardingPanel (shared inner component)

Location: packages/app-hello/src/web/components/OnboardingPanel.tsx

Reusable header + content layout with background. Flexible height to fill parent.

PropTypeDescription
childrenReactNodePanel content
variant"grey" | "gradient"Background style
onBack() => voidBack button handler
backDisabledbooleanDisable back button
headerSlotReactNodeRight side of header
maxWidthstringContent max-width
centeredbooleanVertically center content

OnboardingScreen (full-page wrapper)

Location: packages/app-hello/src/web/components/OnboardingScreen.tsx

Wraps OnboardingPanel with min-h-screen. Used for pages WITHOUT preview.

Same props as OnboardingPanel (pass-through).

WithFlowPreview (split layout wrapper)

Location: packages/app-hello/src/web/components/WithFlowPreview.tsx

Split-screen layout. Takes OnboardingPanel as children for left panel.

PropTypeDescription
childrenReactNodeShould be OnboardingPanel

Features:

  • 50/50 split layout (desktop)
  • Children (OnboardingPanel) renders in left panel
  • ContextualFlowPreview renders in right panel (clean, no chrome)
  • Tab navigation (mobile)
  • Fullscreen preview mode with device simulator
  • Reset preview button

ContextualFlowPreview

Location: packages/app-hello/src/web/components/ContextualFlowPreview.tsx

Live preview of the VideoFlow based on DraftStore state.

Imperative API:

interface ContextualFlowPreviewController {
  resetPreview: () => void;
}

const previewRef = useRef<ContextualFlowPreviewController>(null);
<ContextualFlowPreview ref={previewRef} />

Primary Data Flow: Server → Store → Preview

The Studio page flow shows how data moves from the server through the component tree to the live preview:

Composition Patterns

Non-Preview Step (use OnboardingScreen)

// CompanyStepForm.tsx
export function CompanyStepForm({ ... }) {
  return (
    <OnboardingScreen
      variant="grey"
      onBack={handleGoBack}
      headerSlot={<OnboardingHeaderSlot />}
    >
      <PlanInterviewStep ... />
    </OnboardingScreen>
  );
}

Preview Step (use WithFlowPreview + OnboardingPanel)

// StudioStepForm.tsx
export function StudioStepForm({ ... }) {
  return (
    <WithFlowPreview>
      <OnboardingPanel
        variant="grey"
        onBack={handleGoBack}
        backDisabled={isPending}
        headerSlot={<OnboardingHeaderSlot />}
      >
        <StudioStep ... />
      </OnboardingPanel>
    </WithFlowPreview>
  );
}

Consistent Header Pattern

Both patterns use OnboardingPanel internally for header:

  • OnboardingScreen = min-h-screen + OnboardingPanel
  • WithFlowPreview takes OnboardingPanel as children

Step Components

Step components are "pure" UI - they receive data and handlers as props:

ComponentPackageUsed In
PlanInterviewStep@repo/app-helloCompanyStepForm
StudioStep@repo/app-helloStudioStepForm
ConfigureInterviewStep@repo/app-helloConfigureStepForm
ObjectiveStep@repo/app-helloObjectiveStepForm

Form Components (apps/hello)

Form components connect step components to:

  • Server actions
  • DraftStore (Zustand)
  • Navigation (router)
  • Error handling (toast)
FormWrapperHas Preview
CompanyStepFormOnboardingScreenNo
StudioStepFormWithFlowPreview + OnboardingPanelYes
ConfigureStepFormWithFlowPreview + OnboardingPanelYes
ObjectiveStepFormOnboardingScreenNo
ExtractionFailedPageOnboardingScreenNo
AuthGateFormOnboardingScreenNo

Related Documentation