M3: components at scale; Alt-drag to swap instances (#91)

* M3: components at scale; Alt-drag to swap instances

- Synthetic design system (engine `synthetic_ds`): ~300 components (icons; button, input,
  card, nav and badge sets of size x state x type x theme variants), boolean/text/instance
  swap/slot properties, instances nested four deep, text and paint styles, light/dark
  variables bound across it, and 2,000 instances with overrides at every level.
- Propagation: value, size and added/removed-layer edits of mains reach their copies
  directly; other edits rebuild each affected instance once, inner mains first; rebuilds keep
  unchanged layers shared; bound variables no longer touch unchanged layers; auto layout
  re-flows only where sizes or places changed.
- Fixes: values from variables (theme switches, bound radii) are no longer recorded as
  overrides; a detached variable on an instance layer is an override that survives main
  edits; exposed nested instances stay exposed; swapped nested instances keep their layer
  names and the ids/overrides of layers their own main adds; renamed nested instances keep
  their name when detached out.
- Instance swap properties have preferred values. `instance.swapAt` / `library.swapAt` and
  Alt-drop from the Assets panel onto an instance swap it (highlighted while dragging).
- Instances pasted into other files follow their mains (library copies shared, published
  components used from their library, other mains left behind as a missing main).
- Assets panel lays out only visible tiles and renders thumbnails lazily with a cache
  invalidated per changed component; instance panel lists components once per revision.
- `figcraft-cli perf --instances`, UI frame bench and tests in components_scale_tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* M3: the swap perf case drops on a glyph the hit test reaches

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Merge origin/main into feat/components-scale; weighted depth 79%

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
BFlat
2026-10-10 21:07:43 +07:00
committed by GitHub
co-authored by Claude Opus 5.5
parent fe550fc14a
commit 3c63e6d7c8
26 changed files with 3014 additions and 286 deletions
+5 -2
View File
@@ -115,8 +115,11 @@ popovers and fields (`ui.pointer` and `ui.key` drive the canvas tools and shortc
`{up: [x, y], button?}`, `{key, shift?, alt?, cmd?}` (pressed and released; egui key names such as
`ArrowLeft`, `Escape`, `A`), `{text}` (typed text), `{scroll: [dx, dy], shift?, alt?, cmd?}` (a
mouse wheel at the pointer: the content moves by that many points, so a negative `dy` scrolls down)
and `{leave: true}` (the pointer left the window); positions are window points. Events of one call arrive in the same frame, so send a press
and its release (or a double-click's two clicks) as separate calls. Returns `{queued}`.
`{leave: true}` (the pointer left the window) and `{hold: {alt?, shift?, cmd?}}` (keep those modifier
keys down for the frames that follow, e.g. Alt while dragging a component from the Assets panel onto
an instance to swap it; all false releases them); positions are window points. Events of one call
arrive in the same frame, so send a press and its release (or a double-click's two clicks) as
separate calls. Returns `{queued}`.
```json
{"id":6,"method":"ui.input","params":{"events":[{"move":[1000,315]}]}}