Commit Graph
24 Commits
Author SHA1 Message Date
Dylan M. Taylor 5f022aa8a9 perf(engine): index variables once when following a library's alias chains (#1968)
* perf(engine): index variables once when following a library's alias chains

* address review: return before indexing variables for an empty seed set
2026-11-03 23:00:54 -05:00
Dylan M. Taylor 3265cbca40 perf(engine): look up a component's asset root once per usage report, and skip mode migration without instances (#1966) 2026-11-03 17:58:39 -05:00
0e86f3597a M4: wrap style on a text layer: Auto, Balance and Pretty decide where its lines break (#1827) (#1871)
* M4: wrap style on a text layer: Auto, Balance and Pretty decide where its lines break (#1827)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Docs: no table pipe inside the wrap-style row's code span

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Wrap styles: no new emergency breaks, hanging punctuation in Pretty's width, wrap style as an override

Balance and Pretty reject a re-break with more mid-word breaks than the greedy lines; Pretty narrows a line by its text less its hanging marks; wrapStyle joins the textStyle override group; docs wording. Tests.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-11-03 00:13:48 -05:00
Trevor BrownandClaude Fable 5.1 65bd00f739 M3: Delete on a layer inside an instance hides it instead of being refused (#1834)
* M3: Delete on a layer inside an instance hides it instead of being refused

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* The components structure test: Delete inside an instance hides

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-01 23:49:58 -05:00
BFlat 87254913af M3: library analytics list how each style and variable is used (#1730)
* M3: library analytics list how each style and variable is used

A file reports how many of its layers use each of a team library's styles and
variables, and Show usage lists them by a Type choice with their layers and
files. Layers in instances count for their component. Also ignores plugins/target.

* M3: the style analytics test waits for the instance report too
2026-10-31 09:13:08 +07:00
BFlat 2d784c363d M3: library analytics count insertions and show them over time (#1704)
Gap 10: a file counts the library instances it places, creates, pastes or duplicates and reports them like its detaches. The server counts what a file's totals grow past their highest in the current week and keeps a year of weeks (actions.json). library.usage {days} and Show usage give insertions and detachments over the past 30 days, 90 days or year. New variants are appended; an older server refuses them and Show usage says so.
2026-10-31 04:13:14 +07:00
saimskywalker e6059b3543 M8: confined library checks say they were refused (#1095)
library.check refused nothing while automation roots confined it: it
counted libraries it never asked about and remembered them as yours. It
now refuses before remembering any. library.updates and library.list
answered a refused check with the team library cached earlier, as if the
server had nothing newer; the refusal now reaches them instead of
falling back like an offline server. The MCP and control protocol docs
say that a root on a network share still reaches that file server.
2026-10-31 02:43:50 +08:00
saimskywalker ef4c0aacfd M8: commands confined to automation roots reach no server (#1095)
The roots confined files only: a confined agent could still publish the
open document to any server, host it on the network or join a session.
The engine reaches the network only through the live link, which now
refuses a call made while the roots confine it (hosting, joining,
publishing, sharing, team libraries, plugin directories), and skips the
background team library checks. The MCP and control protocol docs say so.
2026-10-31 02:05:29 +08:00
BFlat be6a7af25f M3: team library analytics count detached instances (#1668)
* M3: team library analytics count detached instances

Detaching an instance of a library component counts it in the file (libraries.detached, saved with it, capped). The background library check reports the counts after its fetch (ReportDetached); the server keeps them per file beside the file's usage report in usage.json (same caps) and answers Detached with them. Show usage and library.usage list detaches per component and per file (detached, detachesKnown). The new request and reply variants are appended, so every older library message keeps its bytes; an older server refuses the new requests, which the app ignores. Gap 10.

* M3: the detach test waits for the instance count too (the two arrive in separate reports)
2026-10-30 23:29:18 +07:00
Christopher Linnett bc76665c65 M3: colour variables can be calculated from others, faded or mixed per mode (#1280)
A colour variable's value in a mode can now be {"alpha": {"variable", "opacity"}} - that
variable's colour with its alpha replaced - or {"mix": {"from", "to", "t"}}, a per-channel blend
of two colour variables or literals over the stored values (in the document's colour profile),
alpha included. Calculations resolve lazily like aliases, so bound layers, mode switches,
instances and undo follow their sources; they compose, and a loop, or a calculation that reads
more than 32 variables in its collection's modes (other collections in their default modes), is
refused when it is set. Operands are stored by id and read by exact id, as stored references
are. Files keep them; REST, CSS, Penpot and .fig exports write the colour they show in each mode;
deleting a source leaves its readers on the colour they showed; library import and swap
re-point their operands. The Variables panel shows them with their formula and can swap one for
an alias or detach it to its colour.
2026-10-30 16:25:26 +08:00
bflatastic b157a38e99 Merge main into #1618 2026-10-30 13:05:24 +07:00
BFlat 7b886404c3 M8: Opening a file contacts no team library server it names until you check it (#1621)
* M8: opening a file contacts no team library server it names until you check it (#1097)

* M8: translate the team library check strings (#1097)

* M8: the Assets panel library test checks what allows a library, without its own fake link (Sonar duplication and coverage)
2026-10-30 13:03:31 +07:00
2f47014917 M3: stored variable and collection references keep their identity (#1613)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
Co-Authored-By: GPT-6 Astra <noreply@openai.com>
Co-Authored-By: GPT-6.1 Terra <noreply@openai.com>
2026-10-30 06:49:06 +03:00
BFlat 7d76b0c673 M3: component properties keep their order on rename; Make slot asks for the name (#1536, #1537) (#1565)
Properties were listed by name, so a rename moved one. Components now keep prop_order (the names as they were made; a rename keeps the place) and every listing follows it. Make slot opens a name field under the frame's Slot row; Enter makes the slot, Escape cancels, a taken name keeps the field open.
2026-10-30 04:49:00 +07:00
BFlat 0d9c2c3f73 M3: components that would contain themselves are refused, and loops in files are repaired (#1084) (#1540)
* M2: components can't contain their own instances (#1084)

Edits that would make a component hold an instance of itself, directly, through other components or through another variant of its set, are refused with the loop named. Files holding such a loop open with one instance per loop detached and a note; a rebuild never expands an instance inside a copy of itself, so a loop merged in a live session stops growing.

* M2: a variant may hold a sibling variant's instance; only true loops are refused (#1084)

Each variant counts as its own component: refusals and open-time repairs apply only to a component leading back to itself through instances (an instance-swap value included), so files with nested sibling variants open unchanged. sync_instance_depth is split into match_layers and copy_layers.
2026-10-29 21:05:32 +07:00
bflatastic a81efe5466 Merge main into #669 2026-10-29 11:52:03 +07:00
Dylan M. Taylor d87f9effe1 refactor(engine): simplify asset and code generation helpers 2026-10-28 16:00:36 +00:00
叶林橦 27d5d99e56 M7: land Flutter code generation on main's code targets
main split `codegen.rs` into `dev/codegen.rs` (the shell: `CodeLang`,
`code_for`, `Ctx`, the shared helpers) and one module per native target
(`css`, `html`, `swift`, `compose`, `arkui`), and added Vue and ArkUI from
other PRs. Flutter arrives as the tenth target, in its own module:
`dev/codegen/flutter.rs`, wired from `codegen.rs` (`CodeLang::Flutter`, `dart`
as an alias, rem left to the web targets), with `flutter_definition` /
`flutter_type` / `flutter_default` beside main's `arkui_definition`.

Every language list in the tree is a union of the two sides now: the
`inspect.code` and `inspect.componentCode` specs, `codeConnect` (parse, import
line, expression, template, path checks, messages), the playground CSS/HTML
assets, the 21 UI catalogues (main added eight after this branch: bn, fi, it,
ka, nl, pl, th, vi, each with Flutter in its own conjunction) and the docs.
Flutter is an extra code target; nothing main gained is dropped.

The reviewer's absolute-child bug (#1382-1403: a child that ignores its auto
layout parent fell through to `Place::Flow`) is fixed in `flutter_children`:
flow and absolute children are split, the absolute ones go in a `Stack` around
the Row/Column at the parent's own box (so their offsets stay the parent's and
the padding moves onto the line instead of insetting them), the line fills that
Stack (`Positioned.fill`, so `Expanded` still has a bounded width), and only
flow children now decide `CrossAxisAlignment.stretch` and `Expanded` — the
absolute child no longer joins the line's spacing or loses its offsets.

`flutter_lifts_a_child_that_ignores_its_auto_layout_parent_out_of_the_line`
covers both kinds of child in one auto-layout frame: a 50×20 flow child and a
30×30 absolute one asking for `fill` on both axes, in a parent with 4 pt
padding. It checks the offset, that the absolute child is out of the Row, that
no `Expanded`/stretch comes from it, and that the padding insets the line only.

ROADMAP and dev-mode-parity keep main's header (2026-10-26) and take this
branch's history row in date order (2026-10-16).

`cargo test`: engine 1391 pass, ui-egui 814 + 8 + 1 pass; fmt and clippy clean.
The one engine failure, `board_tables_tests::a_double_click…`, fails the same
way on a pristine `origin/main` here: this sandbox has no `craft-fonts`
checkout, so its text doesn't wrap and the row can't grow.
2026-10-27 11:30:27 +08:00
aiongg 0330a7cc85 refactor(engine): move assets/components test files to assets/components/ 2026-10-26 20:36:51 +00:00
aiongg 7d70e0bfe5 refactor(engine): move assets/library test files to assets/library/ 2026-10-26 20:36:51 +00:00
aiongg 9c97cb6e17 refactor(engine): move assets/library_server test files to assets/library_server/ 2026-10-26 20:36:51 +00:00
aiongg f664a82093 refactor(engine): move assets/library_swap test files to assets/library_swap/ 2026-10-26 20:36:50 +00:00
aiongg 0bc49705bd refactor(engine): split assets/components.rs into components/ 2026-10-26 20:17:48 +00:00
aiongg e466f4a03a refactor(engine): move components, library, library_server, library_swap, style_vars, playground, token_roles to assets/ 2026-10-26 20:17:48 +00:00