Skip to content

React Composition showcase w/ simple Shopping List app

Notifications You must be signed in to change notification settings

xde013/react-composition

Repository files navigation

React Composition

A simple example to show React Composition in practice. It’s a minimal shopping list UI.

Shopping list app: header, add item form, active items (Milk, Eggs, Bread), done section (Apples), footer with Slots / Compound Components / Hooks

Tech stack

  • React 19 + TypeScript
  • Vite 7 (dev, build, lazy loading)
  • Tailwind CSS 4

Scripts

Command Description
npm run dev Start dev server
npm run build Type-check + build
npm run preview Preview production build
npm run lint Run ESLint

Composition overview

The UI is built from compound components that share state via context and hooks:

  • ShoppingApp — Root layout with Provider, Container, and slots (Header, Form, List, DoneList, Footer). List sections are lazy-loaded.
  • ListList + List.Item; each row is wrapped in ItemProvider so item-specific controls read from ItemContext.
  • ListSection — Section container with optional ListSection.Title; renders a list of items, each in an ItemProvider.
  • ItemControls — Per-row controls composed of ItemControlsStepper (quantity) and ItemControlsUnitSelect (unit); both use ItemContext and ShoppingListContext.

Global list state lives in ShoppingListContext (add, update, remove, toggle). Per-item state is provided by ItemContext (current item) so ListItem and ItemControls stay decoupled from parent data.

Below is a diagram of the component and context flow.

Architecture

flowchart TB
  subgraph App["App"]
    Root["ShoppingApp.Root"]
  end

  subgraph ShoppingApp["ShoppingApp (compound)"]
    Provider["Provider\n(ShoppingListContext)"]
    Container["Container"]
    Header["Header"]
    Form["Form"]
    List["List (lazy)"]
    DoneList["DoneList (lazy)"]
    Footer["Footer"]
  end

  subgraph ListSection["ListSection (compound)"]
    SectionRoot["ListSection"]
    SectionTitle["ListSection.Title"]
    SectionRoot --> SectionTitle
    SectionRoot --> ItemLoop["items → ItemProvider → List.Item"]
  end

  subgraph List["List (compound)"]
    ListRoot["List"]
    ListItem["List.Item\n(ListItem)"]
    ListRoot --> ListItem
  end

  subgraph ListItemInternals["ListItem internals"]
    Checkbox["Checkbox"]
    Slot["children / slot"]
    ItemControls["ItemControls"]
    RemoveBtn["IconButton (remove)"]
  end

  subgraph ItemControlsCompound["ItemControls (compound)"]
    Stepper["ItemControlsStepper"]
    UnitSelect["ItemControlsUnitSelect"]
  end

  subgraph Context["Context"]
    ShoppingListCtx["ShoppingListContext\n(items, add, update, remove, toggle)"]
    ItemCtx["ItemContext\n(current item)"]
  end

  Root --> Provider
  Provider --> Container
  Container --> Header
  Container --> Form
  Container --> List
  Container --> DoneList
  Container --> Footer

  List --> ListSection
  DoneList --> ListSection

  ItemLoop --> ListRoot
  ListItem --> Checkbox
  ListItem --> Slot
  ListItem --> ItemControls
  ListItem --> RemoveBtn

  ItemControls --> Stepper
  ItemControls --> UnitSelect

  ShoppingListCtx -.-> Provider
  ShoppingListCtx -.-> Form
  ShoppingListCtx -.-> ListSection
  ShoppingListCtx -.-> ListItem
  ShoppingListCtx -.-> Stepper
  ShoppingListCtx -.-> UnitSelect

  ItemCtx -.-> ItemProvider["ItemProvider\n(per row)"]
  ItemProvider -.-> ListItem
  ItemCtx -.-> Stepper
  ItemCtx -.-> UnitSelect
Loading

About

React Composition showcase w/ simple Shopping List app

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published