Commit graph

5 commits

Author SHA1 Message Date
Danila Poyarkov 38e7fdd4ac Fix hit-testing: scope hover to current page, click-through empty containers
- Scope hover hit-test to current page (was searching all pages including
  internal component page, causing ghost hover outlines)
- Frames/sections without visible fills or strokes are click-through
- Groups are always click-through (only children are hittable)
- Clipping parents reject hits outside their bounds
- Instances/components check children before falling back to fill check
- Switch test fixtures from material3.fig (55MB) / nuxtui.fig (82MB) to
  gold-preview.fig (537KB) for fast dev runs, gate heavy fixtures behind
  BUN_HEAVY_TESTS env var (enabled in CI)
2026-03-05 08:56:35 +03:00
Danila Poyarkov d30ab4c5d5 Add variables support: collections, modes, bindings, UI panel
Core:
- Variable, VariableCollection types on SceneGraph
- resolveVariable with alias chain resolution + cycle detection
- Mode switching (activeMode per collection)
- Bind/unbind variables to node properties (fills/strokes colors)
- Renderer resolves variable bindings before painting

Import:
- Parse VARIABLE type NodeChanges from .fig files
- Extract paint variable bindings (fills/strokes)

UI:
- VariablesPanel with reka-ui Tabs (collections) + Editable (names/values)
- FillSection: variable picker (reka-ui Popover + Combobox)
- Bound fills show purple variable name badge with detach button
- Toggle variables panel from bottom of layers sidebar

7 new unit tests (83 total)
2026-03-01 01:47:52 +03:00
Danila Poyarkov f77ad708b8 Live component-instance sync with override support
Editing a main component now propagates to all instances:
- Instance children are mapped to component children via componentId
- syncInstances() copies properties from component to instances,
  skipping any property marked in the overrides record
- New children added to a component appear in existing instances
- Store calls syncIfInsideComponent after updateNode, commitMove,
  commitResize — changes propagate automatically
- Demo creates real instances (Button, Badge) in the App Preview

Tests added: instance creation with child mapping, sync propagation,
override preservation, new child addition, detach.
2026-02-28 19:57:52 +03:00
Danila Poyarkov 1d79473bc6 Pages support: multi-page documents like Figma
Document structure: Document (root) → Pages (CANVAS) → Nodes.
Each page has its own viewport (pan/zoom) and background color.

- CANVAS node type for pages
- SceneGraph: addPage(), getPages(), getAbsolutePosition stops at CANVAS
- Store: currentPageId, switchPage(), addPage(), deletePage(), renamePage()
- All operations (create, select, paste, hit test, render) scoped to current page
- Per-page viewport state saved/restored on page switch
- Pages list in LayersPanel with add/switch/double-click rename
- .fig import creates proper pages from DOCUMENT→CANVAS hierarchy
- Renderer takes pageId to render correct page's children
- Unit test for pages, updated E2E tests for page-scoped graph
2026-02-28 13:12:27 +03:00
Danila Poyarkov e03a01dbe3 Add bun:test unit tests for SceneGraph (15ms) 2026-02-28 07:45:50 +03:00