Commit Graph
1417 Commits
Author SHA1 Message Date
BFlat 0ac9399a53 Merge pull request #2223 from TrevorBrown-dev/feat/text-style-font-weight-2174
M7: Text styles: bind a number variable to the weight (#2174)
2026-11-12 11:05:41 +07:00
BFlat 6b2bfaf992 Merge pull request #2218 from TrevorBrown-dev/feat/jam-native-board-items-1808
M9: .jam import: stickies come in as native board stickies (#1808)
2026-11-12 11:05:38 +07:00
BFlat cd6c14e231 Merge pull request #2229 from TrevorBrown-dev/fix/header-icon-size-2227
M10: Design panel: section header icons draw at the panel's icon size (#2227)
2026-11-12 11:04:07 +07:00
BFlat 3740806656 Merge pull request #2221 from TrevorBrown-dev/fix/export-backdrop-blur-2213
M10: Export: a background blur or glass exported on its own keeps the content behind it (#2213)
2026-11-12 11:01:42 +07:00
bflatastic 2161c92f5d Merge main into #2229 2026-11-12 10:48:56 +07:00
bflatastic 8081fe7f6f Merge main into #2218 2026-11-12 10:47:16 +07:00
bflatastic cf28715c18 Merge main into #2221 2026-11-12 10:47:13 +07:00
bflatastic 15d07d049d Merge remote-tracking branch 'origin/main' into landb/2143 2026-11-12 10:45:42 +07:00
bflatastic a5b98d9612 Merge main into #2223 2026-11-12 10:11:57 +07:00
BFlat d3f68c9f77 Merge pull request #2269 from TrevorBrown-dev/fix/instance-lists-its-variant-props-2022
M3: an instance lists the properties its variant uses; long property names stay on one line (#2022)
2026-11-12 10:07:37 +07:00
bflatastic 4565ed9686 Merge main into #2143 2026-11-12 10:06:02 +07:00
BFlat dc5cdb971e Merge pull request #2276 from TrevorBrown-dev/fix/marquee-rules-as-measured
M5: marquee selection follows Figma's measured rules (gap 4)
2026-11-12 10:05:23 +07:00
BFlat cc03f7216d Merge pull request #2236 from TrevorBrown-dev/fix/windows-frame-offset-1343
M10: Windows: the window no longer draws below a hidden caption (#1343)
2026-11-12 10:03:50 +07:00
BFlat 4531e99e5c Merge pull request #2070 from dotCooCoo/fix/export-color-docs
Export: color profile text states which formats are tagged and that CMYK PDF is DeviceCMYK
2026-11-12 09:56:27 +07:00
BFlat ed83ff3f26 Merge pull request #2161 from TrevorBrown-dev/fix/variant-connection-2158
M7: a connection dropped on a sibling variant creates Change to (#2158)
2026-11-12 09:53:51 +07:00
bflatastic 17104743b4 Merge main into #2143 2026-11-12 09:52:05 +07:00
bflatastic fb58711ea6 Merge main into #2276 2026-11-12 09:49:19 +07:00
BFlat 7006141600 Merge pull request #2105 from TrevorBrown-dev/feat/vector-edit-clipboard-1875
M8: copy, cut and paste in vector edit mode act on the selected points and segments (#1875)
2026-11-12 09:47:24 +07:00
BFlat c2d61d36bb Merge pull request #2164 from TrevorBrown-dev/fix/sticky-text-size-2157
M12: a sticky's text keeps its size and the note grows taller (#2157)
2026-11-12 09:37:23 +07:00
bflatastic d1e7a299b0 Merge main into #2269 2026-11-12 09:33:25 +07:00
BFlat af600507d7 Merge pull request #2101 from TrevorBrown-dev/fix/loaded-font-wins-2092
Text: a font loaded with text.loadFont wins over the built-in and installed faces of its family and style (#2092)
2026-11-12 09:32:02 +07:00
bflatastic c1bd18f1f9 Merge main into #2276 2026-11-12 09:31:46 +07:00
BFlat d0c4aca65b Merge pull request #2095 from TrevorBrown-dev/feat/create-multiple-components-dropdown-2088
Components: several layers selected, the component button offers Create multiple components (#2088)
2026-11-12 09:28:25 +07:00
BFlat f9c8a623dd Merge pull request #2248 from TrevorBrown-dev/feat/typed-number-starts-list
M4: a typed number and full stop start a numbered list at that number, as measured in Figma
2026-11-12 09:27:46 +07:00
BFlat 37af80ed89 Merge pull request #2160 from Ragulsundaram/tamil-ui
i18n: Tamil (ta) interface catalog
2026-11-12 09:26:49 +07:00
BFlat 0839958f54 Merge pull request #2142 from TrevorBrown-dev/feat/al-drag-reorder-edge
Auto layout: a dragged child passes a sibling when its leading edge reaches the sibling's middle
2026-11-12 09:23:43 +07:00
bflatastic 1a4824e9e9 Merge main into #2143 2026-11-12 09:23:31 +07:00
bflatastic eddddb6e3c Merge main into #2105 2026-11-12 09:20:27 +07:00
BFlat 0fd45a2eb2 Merge pull request #2107 from TrevorBrown-dev/fix/escape-deselects-measured
Selection: Escape clears the selection instead of stepping out to the parent, as in Figma
2026-11-12 09:18:27 +07:00
BFlat 736a1efe1a Merge pull request #2148 from TrevorBrown-dev/feat/scale-tool-focus-2146
Scale tool: K focuses the Scale field, so K, 2, Enter scales by two (#2146)
2026-11-12 09:15:53 +07:00
Trevor BrownandClaude Sonnet 5.5 c47479bd7f Merge upstream/main into fix/sticky-text-size-2157
boards/board.rs: kept this branch's STICKY_TEXT_SIZE export (sticky_font_size is gone) and main's settle_mind_maps export. Docs: main's status line with ours in front, both revision rows.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Model-Effort: Opus 5.5 drove; Opus 5.5 briefed; Sonnet 5.5 wrote at medium
2026-11-11 20:40:08 -05:00
Trevor BrownandClaude Opus 5.5 55e2b85fd0 Merge upstream/main into feat/jam-native-board-items-1808
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 20:39:08 -05:00
Trevor BrownandClaude Opus 5.5 71723cd428 Merge upstream/main into feat/text-style-font-weight-2174
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 20:38:54 -05:00
Trevor BrownandClaude Opus 5.5 20f02bb7c1 M12: Boards: mind maps in the document and engine (#2226, step 1) (#2228)
* M9: Boards: mind maps in the document and engine (#2226)

Part of #2226, step 1 of 4. A mind map node is a board object of its own (BoardItem::MindNode: a frame hugging its text, no box) and a branch is a connector marked `branch`; the tree is read from the branches alone. `board.mindMap` places a first node with three children and `board.mindMapAdd` adds a child or a sibling, each one undo step. The normalize pass (`board::settle_mind_maps`, `figcraft_doc::mind_layout`) lays a touched map out again from its first node: 88 between columns, 48 between siblings, each stack centred on its parent; a branch that no longer joins two layers of its page is removed. Branches are curved, stroke 4, #757575, round caps. Numbers are from a FigJam map saved and decoded. No toolbar entry, shortcuts or import yet.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Model-Effort: Opus 5.5 drove; Fable 5.1 designed; Sonnet 5.5 wrote at medium

* M12: Mind maps: a map around its own container stays put; a moved branch re-flows its old map (#2226)

A map holding a layer and something inside it is skipped by the settle pass (it never settled). Every touched branch now stirs its old ends, so re-attaching a branch's start re-flows the map it left. Boards without branches return early, a map over MIND_MAX_NODES is left whole, shift skips non-finite moves, and the doc tests share one six-node helper.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Model-Effort: Opus 5.5 drove; Fable 5.1 reviewed; Sonnet 5.5 wrote at medium

* M12: Mind maps: FigCraft's own starter texts (#2226)

A new map's starter children read "Idea 1", "Idea 2" and "Idea 3", as the design specified,
instead of the incumbent's wording, which the first commit had copied from the measurement.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Model-Effort: Opus 5.5 drove and wrote

* M12: Docs: the mind-map revision rows go in the revision history (#2226)

The 2026-11-10 rows sat in ROADMAP.md's Headline numbers table and docs/roadmap.md's Alpha gate
table; each now opens its file's revision history.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Model-Effort: Opus 5.5 drove and wrote

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-12 00:47:05 +01:00
Trevor BrownandClaude Opus 5.5 7d6274d6be Merge upstream/main into feat/vector-edit-clipboard-1875
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 17:55:32 -05:00
Trevor BrownandClaude Opus 5.5 0da027292e Merge upstream/main into fix/escape-deselects-measured
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 17:55:27 -05:00
Trevor BrownandClaude Opus 5.5 d5eec3ec6e Merge upstream/main into feat/annotation-tool-1840
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 17:49:22 -05:00
Trevor BrownandClaude Opus 5.5 3a4b6f0e1f Merge upstream/main into feat/scale-tool-focus-2146
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 17:49:15 -05:00
Trevor BrownandClaude Sonnet 5.5 604c78466c M5: marquee: a drag from inside a frame takes it whole when it takes another top-level frame, as re-measured
In top-level mode the frame the drag started in is now selected whole (re-measure 2: [F1, F2], R1 not selected); with no other frame taken only the touched shapes are. Test 9 uses the re-measure's literal marquees; docs reworded and docs/mcp.md rewrapped.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Model-Effort: Opus 5.5 drove; Fable 5.1 briefed; Sonnet 5.5 wrote at medium
2026-11-11 17:40:52 -05:00
Trevor BrownandClaude Sonnet 5.5 cb52621414 M5: marquee selection follows Figma's measured rules (gap 4)
A plain marquee now selects each top-level layer it touches: a partly covered frame or section gives the layers in it the marquee touches, an enclosed one is selected itself, an empty frame on touch, a rotated shape by its outline. A drag from inside a frame never selects that frame and also takes the top-level layers it touches outside it. Once the marquee selects a frame whole, no frame opens and a partly covered frame comes whole. Measured in Figma's web app, 2026-11-11.

Flipped existing assertions: marquee_selects_what_it_touches, cmd_marquee_selects_nested_layers, a_box_selects_like_a_marquee. Tests: marquee_behaviour_tests.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Model-Effort: Opus 5.5 drove; Fable 5.1 briefed; Sonnet 5.5 wrote at medium
2026-11-11 17:13:26 -05:00
24cf70329b M5: Locked layers follow Figma's rules: no nudge, a locked parent's children stay locked (#1560) (#2219)
* M5: Locked layers follow Figma's rules: no nudge, a locked parent's children stay locked (#1560)

Pins Figma's locked-layer behaviour (measured in Figma's web app, 2026-11-10; help center "Lock and unlock layers") in a new lock_behaviour_tests suite. Fixes the divergences: transform.nudge and transform.nudgeSize skip locked layers, object.toggleLock without a value counts a child of a locked parent as locked (so it never locks the child on its own), and the Layers panel padlock on such a child is inert.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Model-Effort: Opus 5.5 drove; Fable 5.1 briefed; Sonnet 5.5 wrote at medium

* Layers panel: a padlock sweep skips the children of a locked layer (#1560)

A padlock drag sweep no longer collects rows with `locked_above`, so
dragging across a locked frame's children leaves their own flags alone
and draws no swept value on them. An eye sweep is unchanged.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Model-Effort: Opus 5.5 drove; Opus 5.5 briefed; Sonnet 5.5 wrote at medium

* M5: Lock/Unlock leaves a locked layer's child alone in a mixed selection (#1560)

With a locked frame's child and an unlocked layer selected, Lock/Unlock set both own flags, so
the child stayed locked once the frame was unlocked. With no explicit `locked` value, the command
now skips a layer whose parent is locked, as its padlock does; an explicit value (scripts) still
sets it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Model-Effort: Opus 5.5 drove and wrote

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: FredApps <FredApps@users.noreply.github.com>
2026-11-11 21:06:56 +01:00
Trevor BrownandClaude Sonnet 5.5 14670b99d4 M3: an instance lists the properties its variant uses; long property names stay on one line (#2022)
In Figma's data a component set holds one text property per variant (plus leftovers of deleted variants), and an instance lists only the ones its current variant's layers read (measured in Figma's web app). FigCraft listed every definition on every instance, and wrapped a long property name inside an 84 x 20 box so its lines painted over the rows around it.

- components::instance_prop_list: prop_list keeping slots and the properties a layer of the component references (a nested instance counts, its layers and slot content are not entered). component.properties and the Properties panel use it for instances; sets, components and variants still list every definition.
- prop_label cuts the name to one line with an ellipsis and shows the full name on hover.
- Tests: an_instance_lists_only_the_properties_its_variant_uses, a_long_property_name_stays_on_one_line, and the pin a_set_keeps_each_named_text_definition_and_layers_read_their_own. Two tests and one setup that listed an unbound boolean on an instance now bind it to a layer.
- docs/components-parity.md: the properties row, header and revision history.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Model-Effort: Opus 5.5 drove; Fable 5.1 briefed; Sonnet 5.5 wrote at medium
2026-11-11 14:42:37 -05:00
Trevor BrownandClaude Opus 5.5 607a196e35 Merge upstream/main into feat/annotation-tool-1840
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 11:39:56 -05:00
Trevor BrownandClaude Opus 5.5 cf17c66a13 Merge upstream/main into feat/scale-tool-focus-2146
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 11:39:49 -05:00
Trevor BrownandClaude Opus 5.5 a1cb5309f4 Merge upstream/main into feat/vector-edit-clipboard-1875
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 11:39:44 -05:00
Trevor BrownandClaude Opus 5.5 e829590fdf Merge upstream/main into fix/escape-deselects-measured
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 11:39:38 -05:00
Trevor BrownandClaude Opus 5.5 986f6d0a4c Merge upstream/main into fix/header-icon-size-2227
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 11:39:30 -05:00
Trevor BrownandClaude Sonnet 5.5 b8f05d1948 M4: a typed number and full stop start a numbered list at that number, as measured in Figma
Typing `5. ` at the start of a plain paragraph starts a numbered list whose first item reads 5 (Figma has no start-number field); the next item goes on with 6. Digits only, 1 to 9999; `0. `, `12a. ` and `2)` stay text (not measured), `1)` works as before. The measured restart rows (plain paragraph, bullet item) are no longer marked silent.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Model-Effort: Opus 5.5 drove; Opus 5.5 briefed; Sonnet 5.5 wrote at medium
2026-11-11 09:58:57 -05:00
Trevor BrownandClaude Sonnet 5.5 2dd1b5a53a Menus: the main menu and its submenus stay inside the window and scroll when taller (#2217) (#2220)
Submenus of the main menu were not constrained to the window (constrain: false, so they sit
beside their row), so the Object submenu ran past the bottom edge with its lowest commands out of
reach. Menus and submenus are now held within the window's height (moved up, never above the top,
8 pt margins, still beside their row so menu-aim is unchanged), and a panel taller than that
scrolls with the wheel; the keyboard's focus scrolls into view.


Model-Effort: Opus 5.5 drove; Opus 5.5 briefed; Sonnet 5.5 wrote at medium

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-11 15:32:21 +01:00
Trevor BrownandClaude Opus 5.5 985231858c M10: Design panel: Swap orientation and the quick actions use the shared icon size (#2227)
The frame's Swap orientation button and the selection's quick-action buttons (24 pt) still
painted their glyphs at the old 14 pt inset beside Fit to contents' 16 pt; they use
`icon_glyph_rect` now.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Model-Effort: Opus 5.5 drove and wrote
2026-11-11 00:38:03 -05:00