Commit Graph
1368 Commits
Author SHA1 Message Date
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
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
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
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 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 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 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
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 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 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 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 Sonnet 5.5 e415a3a0fb M2: pin the leading-edge drag reorder at its boundaries, zero delta and several layers (#2142 review)
Tests for the -129 leftward boundary, the vertical boundaries both ways, a drag with no move along the flow, and several moving layers using their combined box. Doc comments say whose edge is "leading" and what the caller passes; the parity row names the unchanged cases and the web-app measurement source.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Model-Effort: Opus 5.5 triaged and briefed; Sonnet 5.5 verified and wrote at medium
2026-11-09 15:16:36 -05:00
skylar taylor-barrick a2e87433d8 Naming: Developer Mode follow-ups (#2165)
* Naming: record Developer Mode in the feature-names doc and the stage paragraph

docs/feature-names.md gains the entry for the rename: the old label, the new one, Figma's
US registration for DEV MODE (7574348) as the reason with its TSDR record, the identifiers
that keep their names, and the translations that moved from a generic "dev mode" to the
developer mode. The stage paragraph in ROADMAP.md listed the mode as Dev Mode.

* Actions palette: put each search doc comment back on its function

search_text had grown a second doc line under matches's, so the sentence about the query sat
above a function that takes none. search_text now says what it reads and matches keeps its own.
2026-11-09 15:44:02 +01:00
Trevor BrownandClaude Opus 5.5 ff3e4e6010 M12: sticky growth checked with a measured font; the normalize note drops sticky size (#2164 review)
The growth test scans the system fonts, as the other text-measuring engine tests do (#333), and
asserts the note grows taller unconditionally instead of only when text happened to measure.
docs/boards-parity.md no longer lists a sticky's text size among what the normalize pass derives.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Model-Effort: Opus 5.5 checked the findings and wrote
2026-11-09 09:38:56 -05:00
Trevor BrownandClaude Sonnet 5.5 1ee3087bc9 M12: a sticky's text keeps its size and the note grows taller (#2157)
FigJam's sticky text is 18 (Small) and never changes as the note fills; the note keeps its width and grows taller (measured in the web app, 2026-11-09). A new sticky's text is STICKY_TEXT_SIZE (18) and the normalize pass no longer resets a sticky's text size by its length, so saved stickies keep the size they have. No size menu yet.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Model-Effort: Opus 5.5 drove and briefed; Sonnet 5.5 measured in Figma and wrote at medium
2026-11-09 08:46:12 -05:00
Ragulsundaram 50a76d0914 i18n: Tamil (ta) interface catalog (#2159)
Adds ta.toml with every UI string, command label and menu wording, marked draft.
Desktop draws Tamil with an installed face (#2018); the web picker leaves Tamil out
until craft-fonts has Noto Sans Tamil, like Georgian and Arabic, with a test.
docs/translating.md gains Tamil's entry, typography notes and a Tamil draft section.
2026-11-09 18:45:27 +05:30
Trevor BrownandClaude Opus 5.5 6856437479 M8: the Scale panel keeps FigCraft's origin; the centre default is a follow-up (#2146)
The panel set the origin to the centre once per app. The origin is the Scale tool's drag pivot
too (scale_factor), so that also changed handle drags, unmeasured against Figma, while the
engine and its tests keep top-left. This PR keeps to the focus and the Enter and Escape
endings the issue asks for.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Model-Effort: Opus 5.5 drove and wrote
2026-11-09 03:03:26 -05:00
Trevor BrownandClaude Sonnet 5.5 92145e6f8d M8: K focuses the Scale field, so K, 2, Enter scales by two (#2146)
The Scale tool now opens its factor field focused with its text selected (once per activation), the origin starts at the centre, and Enter or Escape in the field returns the tool to Move with the selection kept. Measured in Figma web, 2026-11-09. Docs: ui-parity Scale tool row and revision.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Model-Effort: Opus 5.5 drove and briefed; Sonnet 5.5 measured and wrote at medium
2026-11-09 02:59:53 -05:00
Trevor BrownandClaude Sonnet 5.5 cf567c3f63 M2: a child dragged in auto layout passes a sibling when its leading edge reaches the sibling's middle
Within its own row or column, a dragged child's slot follows the box it would fill under the pointer (start bounds plus the unsnapped drag), by the edge facing the drag, not the pointer. Measured in Figma's web app, 2026-11-09. Dragging in from outside, wrapping layouts and grids keep their rules. Several moving layers use their combined box.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Model-Effort: Opus 5.5 drove and briefed; Sonnet 5.5 measured and wrote at medium
2026-11-09 00:51:03 -05:00
skylar taylor-barrick 3839fe4a0c Naming: use Developer Mode instead of Figma's Dev Mode (#2135)
Figma holds a US registration for DEV MODE (US 7574348). Display text only: the view.devMode label, Inspect tab, shortcut row, refusal messages, CLI help, docs and all locale catalogs now say Developer Mode. Command ids, preference keys and saved fields are unchanged; "Dev Mode" stays a search alias in the Actions palette. Adds a naming guard test.
2026-11-09 06:24:44 +01:00
FredApps 72cfe7be30 fix(naming): use direct FigCraft feature descriptions (#2131)
Drops the "Figma-class" self-description from the MCP instructions and the "Accessibility at Figma" aside from pref.uiScaleUp help. Help text only; ids and preference keys unchanged. Adds a display-name guard over mcp/src and engine/src/cmd string literals.
2026-11-09 06:22:48 +01:00
Trevor BrownandClaude Opus 5.5 8c24cbf691 Merge upstream/main into fix/loaded-font-wins-2092
Co-Authored-By: Claude Opus 5.5
2026-11-08 12:32:40 -05:00
FredApps d54439be8b M6: scale imported vector point radii with their instance row (#2097) 2026-11-08 16:10:54 +01:00
FredApps a07a21b697 M6: bound exported instance factors to the supported range (#2097) 2026-11-08 16:08:34 +01:00
FredApps 23ed778562 M6: preserve scaled instance export overrides (#2097) 2026-11-08 15:23:36 +01:00
Trevor BrownandClaude Opus 5.5 bceb5476e0 Docs: the new history row below the table's separator (#2107 review)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Model-Effort: Opus 5.5 drove and wrote
2026-11-08 00:31:58 -05:00
Trevor BrownandClaude Sonnet 5.5 a285fd293b Selection: Escape clears the selection instead of stepping out to the parent, as in Figma
Measured in Figma: with a layer inside a group inside a frame selected (from the canvas, from the Layers panel, or after Tab), one Escape selects nothing; FigCraft selected the parent first. Escape still leaves text and vector editing, ends gestures and the pen first. Three tests updated to the measured rule (selection_behaviour, devfocus, proto_editor); the rest of the suites pass.

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 low
2026-11-08 00:11:49 -05:00
Trevor BrownandClaude Sonnet 5.5 34c44e6063 Text: a font loaded with text.loadFont wins over the built-in and installed faces of the same family and style (#2092)
FigCraft chose the first face added for a family and style, so the embedded Inter 4.x kept Regular, SemiBold and Bold after Inter 3.19 was loaded and only Medium refitted. A loaded font is the counterpart of a font uploaded to the organization, which Figma's help center ranks first ("Manage conflicting fonts"). The test builds its faces from any embedded or installed font (skipped when there is none) and checks a loaded face beats a built-in one, the latest load beats earlier ones, and other styles resolve as before.

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-07 22:15:22 -05:00
Trevor BrownandClaude Sonnet 5.5 62d761a7bc M6: .fig import draws a scaled instance's layers at its scale factor (#2091)
An instance scaled with the Scale tool in Figma stores `symbolData.uniformScaleFactor`; the importer never read it, so the layers of a 128 px instance of a 256 px component came in at 256 px with the main's radii, strokes and spacing. Layers of an instance now take the main's lengths times the factor (composed through nested instances), the same values the Scale tool scales, unless an override or derived row gives the value, which is already at the instance's scale. Eight tests: the reproducer, the round trip, a derived size row not scaled twice, override rows, auto layout gap/padding/text, nested composition, factor 1 or none, and junk factors ignored.

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 high
2026-11-07 22:06:35 -05:00
Trevor BrownandClaude Sonnet 5.5 524ad8b1dd Components: Create component set in the component button's menu (#2088)
The third entry of the menu several selected layers get: each layer becomes a component and they are wrapped in a component set in place, 20 px around, named as Figma names them (measured): "Property 1=<layer name>" in left-to-right order, prop=value names kept, and layers that all share a name give a set of that name with "Default" variants. Engine tests cover the three measured cases, geometry, selection, one undo and the refusal of instances; the UI test checks the three menu entries in order and that the third makes one set.

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-07 21:38:30 -05:00
Trevor BrownandClaude Sonnet 5.5 f5a52ea528 Components: several layers selected, the component button offers Create multiple components (#2088)
With two or more layers selected, the Design panel header's component button opens a menu with Create component and Create multiple components, as Figma's does; one layer keeps the plain button. Headless UI tests cover both cases (three frames: menu order, names kept, all selected, one undo; one frame: plain click), and an engine test pins createMultiple's names, positions and single undo step.

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-07 21:20:56 -05:00
bflatastic 2c09046a27 Merge main into #1729 2026-11-07 12:47:51 +07:00
bflatastic 4106c26e8c Merge main into #1729 2026-11-07 12:30:05 +07:00
bflatastic 70821e3645 Merge main into #1879 2026-11-07 12:29:18 +07:00
bflatastic 3f6aa299ea Merge main into #1873 2026-11-07 12:15:09 +07:00
bflatastic 9278ee5451 Merge main into #1729 2026-11-07 12:14:41 +07:00
bflatastic 12293e2e55 Merge main into #1879; shortcut counts with #1858's row 2026-11-07 12:14:30 +07:00
BFlat 9bec55c05a Merge pull request #1911 from TrevorBrown-dev/fix/layers-component-contrast
Layers panel: component rows in the theme's component tint, at AA contrast (#1903)
2026-11-07 13:12:56 +08:00
BFlat 808e60eeae Merge pull request #1772 from SoldierPePe/i18n/rtl-window-mirror
M10: a right-to-left UI language mirrors the window
2026-11-07 13:11:40 +08:00
bflatastic 1546d29a66 Merge main into #1729 2026-11-07 12:07:03 +07:00
BFlat 5cbc8207fd Merge pull request #2065 from helenkwok/web/page-api
figcraft-web: window.figcraft takes its request functions from craft-web-api
2026-11-07 13:03:10 +08:00
bflatastic 6304904317 Merge main into #1911 2026-11-07 11:58:09 +07:00
bflatastic 651a7743c1 Merge main into #1873 2026-11-07 11:57:34 +07:00
bflatastic e056dc7608 Merge main into #1879 2026-11-07 11:56:47 +07:00