Skip to content

App Lifecycle

The App class manages the render loop, event routing, and canvas drawing.

Creating an App

Use the graticule() convenience function:

ts
import { graticule } from 'graticule'

const app = graticule(canvas, {
  fontSize: 14,     // font size in px (default: 14)
  font: 'SF Mono',  // monospace font family
  fg: '#c0c0c0',    // foreground color
  bg: '#0a0a0a',    // background color
  lineHeight: 1.2,  // line height multiplier
  hover: true,       // enable hover highlighting (default: true)
  hoverColor: '#ffffff', // hover highlight color
})

Or construct directly:

ts
import { App } from 'graticule'
const app = new App(canvas, config)

Render Function

Assign a render function that receives the terminal dimensions and returns a RenderResult:

ts
app.render = (cols: number, rows: number): RenderResult => {
  const g = grid.create(cols, rows)
  // ... compose your UI ...
  return { grid: g, clicks: [], colors: [] }
}

The render function is called:

  • On app.start() (initial render)
  • On app.update() (manual re-render)
  • On window resize (automatic)
  • On mouse move (for hover updates)

start()

Performs the initial render. Call this once after setting up your render function:

ts
app.render = (cols, rows) => { /* ... */ }
app.start()

update()

Trigger a re-render manually. Call this whenever your state changes:

ts
let count = 0
setInterval(() => {
  count++
  app.update() // re-renders with new count
}, 1000)

onKey()

Listen for keyboard events:

ts
app.onKey((e: KeyboardEvent) => {
  if (e.key === 'q') console.log('quit')
})

Only one handler is active at a time. Calling onKey() again replaces the previous handler.

destroy()

Clean up event listeners when done:

ts
app.destroy()

dump()

Get the last rendered grid as a string (useful for debugging):

ts
console.log(app.dump())

Screen Access

The underlying Screen instance is exposed for low-level access:

ts
app.screen.onClick((col, row) => { /* ... */ })
app.screen.onResize(() => { /* ... */ })
const { cols, rows } = app.screen.getDimensions()