Skip to main content

Window State-First Content Renderers (March 2026)

· One min read

@wonderlandlabs-pixi-ux/window now documents a clear state-first pattern for runtime content updates in windows and titlebars.

For dynamic content (toolbar actions, async updates, external events), use this flow:

  1. Mutate window/titlebar state (including custom fields).
  2. Mark the relevant store dirty (markDirty() / isDirty).
  3. Upsert display objects from windowContentRenderer and/or titlebarContentRenderer.

Why this matters

  • Avoids Pixi artifacts from direct display-list mutation outside the refresh/ticker path.
  • Coalesces multiple state changes between ticks into one final render snapshot.
  • Prevents unnecessary add/remove churn when intermediate states cancel out before render.

Refresh-cycle timing

  • windowContentRenderer runs during WindowStore.resolve() via content refresh.
  • titlebarContentRenderer runs during TitlebarStore.resolve().

This keeps content generation deterministic and aligned with the rest of the monorepo rendering model.

TickerForest Scale Tracking and Counter-Scale Helpers (March 2026)

· 2 min read

@wonderlandlabs-pixi-ux/ticker-forest now has first-class support for scale-aware dirty tracking and counter-scale helpers.

What changed

  • Added dirtyOnScale to TickerForest config.
  • Added getScale(): { x, y } and getInverseScale(): { x, y }.
  • Standardized dirty triggering via makeDirty(data?: unknown) so the base class can request dirty state without assuming store-specific dirty fields.
  • Scale observer now only triggers dirtying when isDirty() is currently false, and uses axis-aware distinctUntilChanged.

dirtyOnScale options

dirtyOnScale: true enables defaults:

  • watchX: true
  • watchY: true
  • epsilon: 0.0001
  • relativeToRootParent: true

You can also pass an object with:

  • enabled
  • watchX
  • watchY
  • epsilon
  • relativeToRootParent

Why this matters

This removes repeated per-package scale observer logic and centralizes it in TickerForest. Packages like window, grid, and resizer can now share one pattern:

  1. Track container scale.
  2. Mark dirty on meaningful scale deltas.
  3. Re-render once on the next ticker frame.

For UI elements that should appear visually constant under zoom (for example titlebar content or handles), use getInverseScale() in resolve().

Titlebar pattern

For titlebar rendering under zoom:

  • width should follow the window width directly
  • height should be multiplied by inverse y scale
  • content can live in a sub-container scaled by inverse y
  • mask height should use the same inverse-scaled titlebar height

This keeps the titlebar's perceived height stable while preserving alignment with the parent window.

Resizer Updates (March 2026)

· One min read

Recent updates landed for @wonderlandlabs-pixi-ux/resizer:

  • Resize handles now remain visually consistent under parent/super-container scaling by counter-scaling against world transform.
  • Added optional rectTransform support for coordinate transforms like snapping, with a single-argument object:
    • rectTransform({ rect, phase, handle })
  • Added optional transformed-rectangle preview callback:
    • onTransformedRect(rawRect, transformedRect, phase)
  • On drag release, transformed coordinates are committed before onRelease runs.

Validation demos in package-validator were also expanded:

  • /resizer/* remains the basic always-visible handles demo.
  • /resizer-snap/* demonstrates snapping + transformed preview with a gray marching-ants overlay.

Window Drag/Resize + Validator Source Fixes (March 2026)

· One min read

Today we addressed a group of related issues across drag, resizer, window, and the package-validator app:

  • Fixed zoom/scaling delta mismatches for drag + resize interactions by moving pointer-delta math into the correct local coordinate space.
  • Updated resizer drag flow so drag-phase transforms/snapping are committed to current rect state during drag, which keeps handles aligned with snapped geometry before release.
  • Updated window-to-resizer syncing so handle positions follow full window rect changes (x, y, width, height) and use the current window rect for external repositioning.
  • Added validator heartbeat coverage for:
    • scaled drag behavior
    • drag-phase snapping behavior
    • window handle updates during snap drag and external window movement
  • Fixed validator source separation so published mode does not accidentally resolve nested imports back to workspace packages.

Result: published and workspace routes now show meaningful behavioral differences when package versions differ, and interaction fidelity under zoom/scale is consistent.

Docs Site Created

· One min read

Initial Docusaurus app scaffolded in apps/docs for monorepo package documentation.