Define Screens
The defineScreen function creates a screen definition with metadata about your page/route.
Basic Usage
Section titled “Basic Usage”import { defineScreen } from "screenbook"
export const screen = defineScreen({ id: "billing.invoice.detail", title: "Invoice Detail", route: "/billing/invoices/:id",})All Fields
Section titled “All Fields”Required Fields
Section titled “Required Fields”| Field | Type | Description |
|---|---|---|
id | string | Unique identifier for the screen |
title | string | Human-readable title |
route | string | Route path pattern |
Optional Fields
Section titled “Optional Fields”| Field | Type | Description |
|---|---|---|
owner | string[] | Team(s) that own this screen |
tags | string[] | Tags for categorization |
dependsOn | string[] | APIs/services this screen depends on |
entryPoints | string[] | Screen IDs that can navigate here |
next | string[] | Screen IDs this screen can navigate to |
description | string | Optional description |
links | Link[] | External resource links |
mock | ScreenMock | Wireframe-level UI mock definition |
Complete Example
Section titled “Complete Example”import { defineScreen } from "screenbook"
export const screen = defineScreen({ // Required fields id: "billing.invoice.detail", title: "Invoice Detail", route: "/billing/invoices/:id",
// Ownership owner: ["billing-team", "payments-team"],
// Categorization tags: ["billing", "invoice", "detail"], description: "Displays detailed information about a specific invoice",
// Dependencies dependsOn: [ "InvoiceAPI.getDetail", "PaymentAPI.getStatus", "CustomerAPI.get", ],
// Navigation entryPoints: ["billing.invoice.list", "dashboard"], next: ["billing.invoice.edit", "billing.payment.start"],
// External links links: [ { label: "Figma Design", url: "https://figma.com/..." }, { label: "Storybook", url: "https://storybook.example.com/..." }, ],})ID Naming Conventions
Section titled “ID Naming Conventions”Use dot-separated hierarchical IDs:
domain.feature.actionExamples:
billing.invoice.listbilling.invoice.detailbilling.invoice.createsettings.profileauth.login
This convention helps with:
- Alphabetical sorting groups related screens
- Easy filtering by domain
- Clear ownership boundaries
Route Patterns
Section titled “Route Patterns”Routes can include dynamic segments:
// Static routeroute: "/dashboard"
// Single dynamic segmentroute: "/users/:id"
// Multiple dynamic segmentsroute: "/projects/:projectId/tasks/:taskId"
// Optional segments (depends on your router)route: "/products/:category?/:subcategory?"Dependencies
Section titled “Dependencies”The dependsOn field tracks which APIs or services this screen relies on:
dependsOn: [ "InvoiceAPI.getDetail", // Specific endpoint "PaymentService", // Entire service "UserStore.currentUser", // State dependency]This enables Impact Analysis to identify affected screens when APIs change.
Navigation Relationships
Section titled “Navigation Relationships”entryPoints
Section titled “entryPoints”Screens that link TO this screen:
// On invoice detail pageentryPoints: ["billing.invoice.list"] // User comes from list pageScreens this page links TO:
// On invoice detail pagenext: ["billing.invoice.edit", "billing.payment.start"]These relationships create the Navigation Graph.
Validation
Section titled “Validation”Screen references in entryPoints and next are validated during build:
# Shows warnings for invalid referencesnpx screenbook build
# Fails on invalid referencesnpx screenbook build --strictMock Wireframes
Section titled “Mock Wireframes”The mock field allows you to define wireframe-level UI mockups for screen flow documentation. Navigation targets defined in mocks are automatically extracted and merged into the next array.
Basic Mock Structure
Section titled “Basic Mock Structure”import { defineScreen } from "screenbook"
export const screen = defineScreen({ id: "billing.invoice.detail", title: "Invoice Detail", route: "/billing/invoices/:id", mock: { sections: [ { title: "Header", layout: "horizontal", elements: [ { type: "text", label: "Invoice #123", variant: "heading" }, { type: "button", label: "Edit", navigateTo: "billing.invoice.edit" }, ], }, { title: "Line Items", elements: [ { type: "list", label: "Items", itemCount: 5, itemNavigateTo: "billing.lineitem.detail" }, ], }, ], },})Element Types
Section titled “Element Types”| Type | Properties | Description |
|---|---|---|
button | label, variant?, navigateTo? | Clickable button |
input | label, placeholder?, inputType? | Form input field |
link | label, navigateTo? | Text link |
text | label, variant? | Static text |
image | label, aspectRatio? | Image placeholder |
list | label, itemCount?, itemNavigateTo? | List of items |
table | label, columns?, rowCount?, rowNavigateTo? | Data table |
Button Variants
Section titled “Button Variants”{ type: "button", label: "Submit", variant: "primary" }{ type: "button", label: "Cancel", variant: "secondary" }{ type: "button", label: "Delete", variant: "danger" }Text Variants
Section titled “Text Variants”{ type: "text", label: "Page Title", variant: "heading" }{ type: "text", label: "Section Title", variant: "subheading" }{ type: "text", label: "Normal text", variant: "body" }{ type: "text", label: "Small text", variant: "caption" }Input Types
Section titled “Input Types”{ type: "input", label: "Email", inputType: "email" }{ type: "input", label: "Password", inputType: "password" }{ type: "input", label: "Search", inputType: "search" }{ type: "input", label: "Description", inputType: "textarea" }Section Layouts
Section titled “Section Layouts”// Vertical layout (default){ title: "Form", layout: "vertical", elements: [...] }
// Horizontal layout{ title: "Actions", layout: "horizontal", elements: [...] }Nested Sections
Section titled “Nested Sections”Sections can contain child sections for complex layouts:
{ title: "Parent Section", elements: [{ type: "text", label: "Parent content" }], children: [ { title: "Child Section", elements: [{ type: "button", label: "Child action" }], }, ],}Auto-Generated Navigation
Section titled “Auto-Generated Navigation”Navigation targets from mock elements are automatically merged into next:
// These navigateTo values...{ type: "button", label: "Edit", navigateTo: "billing.invoice.edit" }{ type: "list", label: "Items", itemNavigateTo: "billing.lineitem.detail" }{ type: "table", label: "Invoices", rowNavigateTo: "billing.invoice.detail" }
// ...are automatically added to the screen's `next` arrayThis means you don’t need to manually maintain next when using mocks - navigation is derived from the UI definition.
Best Practices
Section titled “Best Practices”-
Keep metadata close to routes - Place
screen.meta.tsin the same directory as your page component -
Use consistent ID patterns - Establish a naming convention for your team
-
Track real dependencies - Only list APIs actually called by the screen
-
Update on changes - Keep navigation relationships in sync with actual links
-
Use mocks for documentation - Define wireframes to visualize screen structure and auto-generate navigation