Components API Overview
This section is the authoritative reference for the React components that make up Apollo Map Studio's UI. Every component has its own page covering:
- Purpose & UX role
- Props interface table (name / type / default / description)
- Internal state (
useState, Zustand selectors, XState selectors) - Side effects (event subscriptions, MapLibre layer registration, FSM event sends)
- Render anatomy (DOM / layer structure)
- Performance notes (
memo,RAF, effect deps) - Source map (file:line)
- Cross-links to guide pages, architecture pages, and sibling components
Component layering
Per ARCHITECTURE.md, components/ sits at the top of the import hierarchy. It freely consumes hooks/, store/, lib/, core/, and types/, but downward references are forbidden. Each component page lists which lower-tier modules it directly consumes.
Component index
| Component | Tier | Primary role | Source |
|---|---|---|---|
| WorkspaceLayout | Shell (root) | Full-screen grid: MenuBar / LicenseBanner / ToolStrip / Dockview / StatusBar; injects EditorProvider + SidebarProvider | src/components/layout/WorkspaceLayout.tsx |
| MapCanvas | Map (core) | MapLibre GL container; hosts cold/hot/grid/Apollo layers + event router | src/components/map/MapCanvas.tsx |
| MenuBar | Shell | Top-level menu (File / Edit / View / Tools / Help) + mode toggle | src/components/layout/MenuBar.tsx |
| ToolStrip | Shell | Tool strip: default/connect + 11 element icons + tool variants + view toggles | src/components/layout/ToolStrip.tsx |
| ActivityBar | Shell | VS Code-style left activity rail: Explorer / Layers / Search / Timeline / Settings | src/components/layout/ActivityBar.tsx |
| MapOutline | Sidebar Panel | Read-only structural overview: per-type counts, health checks, Apollo header metadata | src/components/layout/panels/MapOutline.tsx |
| LayerTree | Sidebar Panel | react-arborist drag-and-drop tree: Road / Junction / Lane parenthood | src/components/layout/panels/LayerTree.tsx + LayerTree/ |
| SearchPanel | Sidebar Panel | Flat substring search across id / entityType (200-result safety cap) | src/components/layout/panels/SearchPanel.tsx |
| InspectorForms | Inspector Panel | Entity-form dispatcher (Lane / Road / Signal / PNCJunction / Overlap / 17 Apollo entities) | src/components/layout/panels/InspectorForms.tsx + InspectorForms/ + SchemaForm.tsx |
| LaneRefList | Inspector Helper | Clickable lane-id pill row that routes SELECT_ENTITY FSM events | src/components/layout/panels/LaneRefList.tsx |
| SettingsPanel | Modal | Undo limit / viewport center / lane half-width / arrow spacing etc. user prefs | src/components/layout/panels/SettingsPanel.tsx + MapMetadataForm.tsx |
| StatusBar | Shell | Bottom status bar: mode / entity count / cursor / zoom / Apollo info | src/components/layout/StatusBar.tsx |
| TimelinePanel | Bottom Panel | Scene-mode timeline: tracks + keyframes + playhead (PoC, not yet wired to a store) | src/components/layout/panels/TimelinePanel.tsx |
| CommandPalette | Overlay | cmdk palette, ⌘K to open, bound to Action Registry | src/components/layout/panels/CommandPalette.tsx |
| TaskProgressOverlay | Overlay | Full-screen long-running task progress (import/export, spatial worker tasks) | src/components/layout/TaskProgressOverlay.tsx |
| ProjPickerDialog | Modal | Opens when an Apollo map is imported without a PROJ string, three input modes | src/components/dialogs/ProjPickerDialog.tsx |
| LicenseBanner | Shell | Trial countdown / expiry warning banner, opens the activation dialog | src/components/license/LicenseBanner.tsx |
| ActivationDialog | Modal | Surfaces machine code + accepts an activation token → Ed25519 verification | src/components/license/ActivationDialog.tsx |
Suggested reading order
- WorkspaceLayout — start with the skeleton, then drill down.
- MapCanvas — see how cold/hot layers, the worker bridge, and the event router are assembled in one component.
- InspectorForms — schema-driven forms are where the R2 anti-corruption layer surfaces in the UI.
- LayerTree + ToolStrip — drag-and-drop semantics and the Action Registry single source.
Cross-references
- Architecture overview →
/en/architecture/ - Action Registry →
src/core/actions/registry.ts(/en/api/core/actions/) - FSM state machine →
src/core/fsm/editorMachine.ts(/en/api/core/fsm/) - Zustand stores →
mapStore/uiStore - Hooks overview →
/en/api/hooks
Reading conventions
- Notes tagged R1 refer to the R1 risk in the architecture audit (undo + drawing-FSM sync); R2 refers to the Apollo proto anti-corruption layer.
- All
file:linereferences are pinned to v1 HEAD; re-verify when migrating to v2.
Entity ↔ component matrix
The following table maps each of the 17 Apollo HD-Map entity types and the 6 drawing primitives to the components that render or edit them. Use this as a fast lookup when locating "the file that lets me edit X":
| entityType | LayerTree group | Inspector form | Outline count key | Action category |
|---|---|---|---|---|
lane | Lanes / Junction / Section | LaneForm (SchemaForm) | lane | lane |
road | Roads / Junction | RoadForm | road | road |
junction | Junctions | JunctionForm | junction | junction |
signal | Signals | SignalForm | signal | signal |
crosswalk | Crosswalks | CrosswalkForm (RO) | crosswalk | crosswalk |
stopSign | Stop Signs | StopSignForm | stopSign | stopSign |
yieldSign | Yield Signs | YieldSignForm (RO) | yieldSign | yieldSign |
speedBump | Speed Bumps | SpeedBumpForm (RO) | speedBump | speedBump |
clearArea | Clear Areas | ClearAreaForm (RO) | clearArea | clearArea |
parkingSpace | Parking Spaces | ParkingSpaceForm | parkingSpace | parkingSpace |
parkingLot | Parking Lots | (DrawingForm fallback) | parkingLot | parkingLot |
pncJunction | PNC Junctions | PNCJunctionForm | pncJunction | pncJunction |
rsu | RSUs / Junction | RSUForm (RO) | rsu | rsu |
area | Areas | AreaForm | area | area |
barrierGate | Barrier Gates | BarrierGateForm | barrierGate | barrierGate |
overlap | Overlaps | OverlapForm | overlap | overlap |
speedControl | Speed Controls | (DrawingForm fallback) | speedControl | speedControl |
polyline | Polylines | DrawingForm | (drawingCount) | drawing |
bezier | Beziers | DrawingForm | (drawingCount) | drawing |
arc | Arcs | DrawingForm | (drawingCount) | drawing |
rect | Rectangles | DrawingForm | (drawingCount) | drawing |
polygon | Polygons | DrawingForm | (drawingCount) | drawing |
catmullRom | CatmullRom | DrawingForm | (drawingCount) | drawing |
RO = read-only (renders <Section><Value /></Section> only).
Wiring overview
This compact graph shows who calls whom and which stores each component subscribes to. Legend: white = component, blue = store, yellow = hook, green = registry.
Test coverage
Test file locations per component (see contributing guide):
| Component | Tests |
|---|---|
| WorkspaceLayout | (integration; covered via e2e/ Playwright) |
| MapCanvas | src/components/map/__tests__/MapCanvas.test.tsx |
| InspectorForms.lane | src/components/layout/panels/__tests__/lane-form.test.tsx |
| LayerTree.treeBuilder | src/components/layout/panels/__tests__/treeBuilder.test.ts |
| SearchPanel | src/components/layout/panels/__tests__/search.test.tsx |
| SchemaForm | src/components/layout/panels/__tests__/SchemaForm.test.tsx |
| Overlap inspector | src/components/layout/panels/__tests__/overlap-form.test.tsx |
| Action Registry | src/core/actions/__tests__/registry.test.ts |
Maintenance contract
- When adding a new component, decide which tier it belongs to (Shell / Sidebar / Inspector / Overlay) and update the corresponding row in the index table.
- Adding a new prop requires updating the component page's Props table.
- When changing a
file:linecited in a Source map —git grepfor the coordinate across docs and update every reference together. - Do not paste long code blocks in the docs — keep API signatures and line references; readers can click through.
Naming conventions
Every component file, directory, and test follows these conventions:
| Category | Pattern | Example |
|---|---|---|
| Main component file | PascalCase.tsx | WorkspaceLayout.tsx |
| Sibling directory (split-out submodules) | PascalCase/ | WorkspaceLayout/dockviewLayout.ts |
| Submodule helper | camelCase.ts | dockviewLayout.ts, treeBuilder.ts |
| Test directory | __tests__/ | panels/__tests__/ |
| Test file | {component}.test.tsx / {module}.test.ts | lane-form.test.tsx |
| Hook file | use{Name}.ts | useColdLayer.ts |
| Store file | {name}Store.ts | mapStore.ts |
Any deviation from these patterns must be justified in the PR.
Risk map (cross-reference with the architecture audit)
The table below ties project-level risk items to component directories, so reviewers can quickly identify "which PRs might affect R-x":
| Risk ID | Description | Affected components |
|---|---|---|
| R1 | Undo + FSM sync | WorkspaceLayout (dispatcher) + InspectorForms (drift sync) |
| R2 | Apollo proto anti-corruption layer | InspectorForms, LayerTree, MapOutline |
| R4 | Cold-layer performance | MapCanvas, TaskProgressOverlay |
| R5 | Action Registry single source | MenuBar, ToolStrip, CommandPalette |
| Labels | Hardcoded component labels | Components that render user-facing text |
| (a11y) | Not yet WCAG AA | All components |
Adding a new component checklist
When adding a new component page, follow this order:
- Decide the tier: Shell / Sidebar / Inspector / Modal / Overlay / License. Then add a row to the "Component index" table on this page.
- Create the source file: follow the naming conventions above; place it under the right directory (
layout//layout/panels//dialogs// etc.). - Write tests:
__tests__/{name}.test.tsx, covering at minimum render + basic interaction. - Write the component page with sections in this order: Purpose / Props / Internal state / Side effects / Render anatomy / Performance / Source map / Cross-references.
- Update this index page: add a row to the "Component index" table.
- Update the diagrams: if the new component changes the mermaid composition tree or wiring diagram, update the relevant diagram on this page.
- Attach a docs preview to the PR: let reviewers read the markdown directly so inconsistencies are caught before merge.
Documentation readability guide
- Prefer tables over prose — readers scan tables faster.
- Add a caption sentence next to every mermaid diagram.
- Use
file:linelinks instead of pasting source code — avoids the maintenance burden of duplication. - Keep VitePress containers (
::: tip/::: warning/::: info). - Keep component pages compact: explain behavior once, then link to source for implementation details.