Merge main into the Bosnian catalog follow-up

Main merged #1652 (the Bosnian catalog) and added more strings; ROADMAP keeps main's rows with the count updated, and bs.toml translates the two new strings (a pasted table's size limit, connector labels without a snapshot), so it covers all 1,906 UI strings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013Tayw8nmxoLLmKv13jK93z
This commit is contained in:
Claude
2026-10-30 16:18:27 +00:00
80 changed files with 1716 additions and 220 deletions
+5 -3
View File
@@ -1,6 +1,6 @@
# Boards parity
> **Last reviewed:** 2026-10-24 · **Last updated:** 2026-10-30 · **Change:** minor (Shift+Cmd/Ctrl+Enter on a selected board shape adds the next shape already joined to it, and goes on typing (#1597); "+" handles beside a selected sticky or shape make the next one, joined by a connector (#1597); a FigJam `.jam` file opens as a board (#1342); board grid settings: dots, lines, graph paper or none, spacing, size and contrast; the connector tool shows the connector it will make while dragging, ends snapping to attach points (#1387); templates and tables; facilitation: a shared timer and voting sessions; the dot grid, dragging a connector's end to re-attach it, curved connectors, elbows that go around what they join) · **Target:** the incumbent's whiteboard product (behaviour from its public help centre)
> **Last reviewed:** 2026-10-24 · **Last updated:** 2026-10-30 · **Change:** minor (a connector's bar sets its start and end points, dashes, weight and any colour (#1596); cells copied from a spreadsheet paste onto a board as a table; Shift+Cmd/Ctrl+Enter on a selected board shape adds the next shape already joined to it, and goes on typing (#1597); "+" handles beside a selected sticky or shape make the next one, joined by a connector (#1597); a FigJam `.jam` file opens as a board (#1342); board grid settings: dots, lines, graph paper or none, spacing, size and contrast; the connector tool shows the connector it will make while dragging, ends snapping to attach points (#1387); templates and tables; facilitation: a shared timer and voting sessions; the dot grid, dragging a connector's end to re-attach it, curved connectors, elbows that go around what they join) · **Target:** the incumbent's whiteboard product (behaviour from its public help centre)
**Breadth ~47%, ready ~29% (estimated, erring low).** A board is a FigCraft file of its own kind
(`file.newBoard`) with a dot grid on the page, sticky notes, shapes with text, connectors that
@@ -28,7 +28,7 @@ all end with the same geometry.
|---|---|---|
| Board files: File ▸ New board, the home screen's New board card, a light page | done | `file.newBoard`; the kind shows in `inspect_document`, tabs and file rows (a note mark; design files a pen nib) |
| Board toolbar at the bottom | done | Move/Hand, Marker/Highlighter/Eraser, Sticky (colour flyout), Shapes (flyout), Connector, Text, Section, Stamp (flyout), Comment, Actions, then the templates and the Design panel's buttons — on the same 32 pt grid as a design file's (no Resources button, as there) |
| Design panel hidden by default; a contextual bar above the selection | done | colour, shape, text size (S/M/L/XL), connector straight/elbow/curved and its arrow; the Design panel opens with its button or View ▸ Design panel |
| Design panel hidden by default; a contextual bar above the selection | done | colour, shape, text size (S/M/L/XL); for connectors straight/elbow/curved, the start and end points (none, round, square, line arrow, triangle arrow, reversed triangle, circle, diamond), solid or dashed, the weight, and any colour in the colour picker beside the board colours (#1596); each control says what it is on hover; the Design panel opens with its button or View ▸ Design panel |
| Prototyping and Dev Mode refuse on boards | done | `proto.*`, `dev.*`, `view.prototype`, `view.devMode` say why |
| Sticky notes | done | a square frame (200 wide, growing taller through auto layout), 8 soft colours, a soft shadow, the note's text size shrinking as it grows (24 → 11, by characters and lines), the author's name at the bottom; a click places one and starts typing; Enter or a double-click edits; Shift+Cmd/Ctrl+Enter adds the next one beside it |
| Sticky options: hide the author, change size presets, sticky stacks | partial | `board.sticky {author: false}`; no size presets or stacks |
@@ -52,7 +52,7 @@ all end with the same geometry.
| Voting: only the facilitator ends or clears it, who voted for what | missing | anyone who can edit the board can end or clear a vote; results are counts only |
| Board widgets | missing | design-file widgets exist (`crates/engine/src/extensions/widgets.rs`), not wired to boards |
| Templates (retrospective, brainstorm, flow chart…) | partial | five built-in templates drawn up for FigCraft (retrospective, brainstorm, weekly planner, flow chart, kanban board), placed from the toolbar's templates picker (each with a picture of itself) or `board.template {name, x?, y?}` as ordinary sections, stickies, shapes, connectors and text in one undo step; `board.templates` lists them. No community templates, no saving your own |
| Tables | partial | `board.table {rows, columns, cells?, x?, y?}` (at most 50 × 20): an auto layout frame of rows of cells with text, a tinted header row and lines between rows and columns; a cell's row grows with its text; a double-click types in the cell under the pointer; add or remove a row or column from the bar over the selection or `board.tableEdit {id, action, index?}`; undoable and synced in live sessions. No column resizing by dragging, no cell colours, no Tab between cells, no CSV paste |
| Tables | partial | `board.table {rows, columns, cells?, x?, y?}` (at most 50 × 20): an auto layout frame of rows of cells with text, a tinted header row and lines between rows and columns; a cell's row grows with its text; a double-click types in the cell under the pointer; add or remove a row or column from the bar over the selection or `board.tableEdit {id, action, index?}`; cells copied from a spreadsheet (tab-separated text, quoted cells kept whole) paste as a table, up to 50 × 20 with a note when there was more; undoable and synced in live sessions. No column resizing by dragging, no cell colours, no Tab between cells; comma-separated text pastes as text |
| Mind maps | missing | |
| Washi tape, code blocks, image cropping on boards | missing | images can be placed as in design files |
| Audio and huddles | missing | |
@@ -64,6 +64,8 @@ all end with the same geometry.
| Date | Change | Summary |
|---|---|---|
| 2026-10-30 | minor | The contextual bar row: a selected connector's bar sets its start and end points, solid or dashed, its weight and any colour, beside the line type and the board colours (#1596). Numbers unchanged |
| 2026-10-30 | minor | M12, gap 24: cells copied from a spreadsheet paste onto a board as a table. The clipboard carries them as text: a row per line, a tab between cells, and a cell holding a tab, a line break or a quote in quotes. `board_table::spreadsheet_cells` reads that into `board.table`'s `cells`. The table is centred in the view, or with Paste here its top-left goes at the point. Up to 50 × 20 cells are kept, with a note when there were more. Text without tabs, comma-separated text and any paste into a design file stay a text layer, as before. Tests: `board_table_paste_tests`, `table_paste_tests`. |
| 2026-10-30 | minor | #1597: Shift+Cmd/Ctrl+Enter on a selected shape adds the next shape joined by a connector and starts typing in it; on a sticky it still adds a sticky beside it. Numbers unchanged. |
| 2026-10-30 | minor | A row for creating the next shape already connected: "+" handles on a selected sticky's or shape's sides make the next one joined by a connector, ready for typing (#1597). Numbers unchanged |
| 2026-10-30 | minor | M12, #1342: a FigJam `.jam` file opens as a board, our whiteboard file kind, instead of a design file: the `.fig` reader marks a canvas with FigJam's `fig-jam.` header as `FileKind::Board`, so the file opens with the board toolbar, the dot grid and the board panels, and saves as a board. A `.fig` stays a design file, and `file.import` of a `.jam` adds its pages to the open file without changing its kind. Its stickies and shapes with text are still frames with their generated layers and its connectors vectors, not native board objects. Tests: `board_import_tests.rs` (the kind, `.jam` against `.fig`), `jam_open_tests.rs` (open as a board, import into a design file). |
File diff suppressed because one or more lines are too long
+10 -5
View File
@@ -100,8 +100,8 @@ No alpha blockers: the alpha gate in [`roadmap.md`](roadmap.md#alpha-gate) passe
so the differences come from the fonts' advances. Evidence:
`crates/text/src/saved_breaks_tests.rs`, `crates/format/src/fig/text_wrap_tests.rs`; not
checked on real files.
- **Missing:** labels of
connectors without a saved snapshot, table cells beyond their own layers, live region
- **Missing:** the background of connector labels without a saved snapshot (the label is kept,
centred on its line), table cells beyond their own layers, live region
style/variable links, variables
bound to fields the editor can't bind and video fills aren't read; text lays out again with
local fonts (an unedited text keeps the file's line breaks, but glyph positions, line widths
@@ -261,7 +261,12 @@ No alpha blockers: the alpha gate in [`roadmap.md`](roadmap.md#alpha-gate) passe
Sliders (2026-10-30): a panel control or command parameter of type `slider` (a number between
its `min` and `max`) is drawn as a slider with its value beside it; the plugin is called back
once, when the drag ends.
Panel images (2026-10-30): an `image` control shows a picture the plugin carries (base64, at most
256 KB and 4,096 pixels on a side), as wide as a field at most, named by its label.
- **Missing:** a public catalogue and Community files, publisher accounts and signatures, ratings
and install counts, background update checks, the directory in the browser build; widgets have no hover or
timers, can't open a panel and draw only frames, text, shapes and images.
Figma's own plugins are JavaScript against Figma's plugin API and
and install counts, background update checks, the directory in the browser build; widgets have no
timers, can't open a panel and draw only frames, text, shapes and images;
no images in panels. Figma's own plugins are JavaScript against Figma's plugin API and
@@ -411,9 +416,6 @@ No alpha blockers: the alpha gate in [`roadmap.md`](roadmap.md#alpha-gate) passe
importer warns and skips them, `crates/format/src/rest/proto.rs`); controllers on macOS, Linux
and FreeBSD (the usual Rust controller library links libudev on Linux; a pure-Rust reader per
platform, or an owner decision on that dependency); PlayStation and Switch button labels.
`proto.linkNotice` from the Actions palette or the control channel changes the preference in
memory only; it reaches the preferences file with the next preferences save (the notice's own
"Don't show this again" saves at once).
- **Estimate:** 2–5 h, the media part after video fills (gap 12).
### 16. Dev Mode: the tail after dev resources
@@ -571,6 +573,9 @@ No alpha blockers: the alpha gate in [`roadmap.md`](roadmap.md#alpha-gate) passe
| Date | Change | Summary |
|---|---|---|
| 2026-10-30 | patch | Gap 15: `proto.linkNotice` (the Actions palette, the control channel, MCP) is saved with the preferences at once, as the notice's own "Don't show this again" is, instead of only when the app quits; that note leaves the missing list. Estimate unchanged. Test: `present_links_tests::skipping_the_notice_by_command_is_saved_at_once` |
| 2026-10-30 | minor | Gap 6: plugin panels show pictures: an `image` control (`data` base64, at most 256 KB and 4,096 px a side; panel specs up to 1 MB) drawn at its size up to a field's width, named by its label, which shows instead when the picture can't be decoded. "Images" leaves the missing list; estimate unchanged. Tests: `v2_tests::panels_are_validated_and_keep_entered_values`, `plugin_panel_tests::panel_images_show_named_or_fall_back_to_their_label` |
| 2026-10-30 | minor | Gap 1: labels of connectors without a saved snapshot are kept, centred on their line (without their background), instead of skipped. Not checked on real files; estimate unchanged. Test: `fig::tests::tail::a_labelled_connector_without_a_snapshot_keeps_its_label` |
| 2026-10-30 | minor | Gap 6: widget hover styles landed (a layer's `hover` fill, stroke, opacity or text colour shown while the pointer is over it, as a live preview; `widget.hover`); the entry no longer lists hover. Estimate unchanged. |
| 2026-10-30 | minor | Gap 1: elbowed and curved connectors without a saved path no longer import as straight lines; they are routed as board connectors are (the shared `figcraft_doc::route_points`). Not checked on real files; estimate unchanged. Tests: `fig::tests::tail::connectors_without_a_saved_path_follow_their_line_style` |
| 2026-10-30 | minor | Gap 6: plugin panels and command forms take a `slider` control (a number between a required `min` and `max`), drawn as a slider with its value field beside it; the plugin is called back once when a drag ends, one undo step. "Sliders" leaves the missing list; estimate unchanged. Tests: `v2_tests::panels_are_validated_and_keep_entered_values`, `plugin_panel_tests::a_slider_calls_the_plugin_back_once_when_let_go` |
+2 -2
View File
@@ -105,7 +105,7 @@ Other languages (measured 2026-10-22): Russian (`ru`) 2,352 / 2,352 (100%), revi
by VanTan, one/few/many integer plurals; Swedish (`sv`) 2,314 / 2,352 (98.4%), its command labels and menu
wordings added 2026-10-17 (#599), native review welcome; Turkish (`tr`) 2,291 / 2,352 (97.4%), whose header
says it was machine-drafted and reviewed by a native speaker; Czech (`cs`) 2,292 / 2,352 (97.4%), a draft
with one/few/other plurals; Bosnian (`bs`, Bosanski, added 2026-10-30) 2,565 / 2,565 (100%: 1,905 UI
with one/few/other plurals; Bosnian (`bs`, Bosanski, added 2026-10-30) 2,566 / 2,566 (100%: 1,906 UI
strings, 629 command labels, 31 menu wordings), a machine draft awaiting native review, with
one/few/other plurals (21 takes one). Figma ships none beyond the eight above.
@@ -125,7 +125,7 @@ Hindi and Arabic. Traditional Chinese is not planned (no catalog; its users see
| Date | Change | Summary |
|---|---|---|
| 2026-10-30 | minor | Bosnian (`bs`, Bosanski) draft catalog: every UI string (1,905), command label (629) and menu wording (31), machine-drafted in Latin script with ijekavian forms and marked as a draft awaiting native review. Bosnian plurals: one for 1, 21, 31… (not 11), few for 2–4, 22–24… (not 12–14), other for the rest. Grade and hours unchanged (Bosnian is not one of the twelve key languages) |
| 2026-10-30 | minor | Bosnian (`bs`, Bosanski) draft catalog: every UI string (1,906), command label (629) and menu wording (31), machine-drafted in Latin script with ijekavian forms and marked as a draft awaiting native review. Bosnian plurals: one for 1, 21, 31… (not 11), few for 2–4, 22–24… (not 12–14), other for the rest. Grade and hours unchanged (Bosnian is not one of the twelve key languages) |
| 2026-10-29 | minor | German terminology corrections (M10): gradient stops, OpenType stylistic sets and the Home-screen preference; partial review, catalog remains a draft. Nine existing translations corrected; keys, placeholders, coverage, grade and estimates unchanged |
| 2026-10-28 | minor | Arabic draft: 1,857 UI entries, 620 command labels and 31 menu wordings, with count-neutral plurals. AI-assisted, native review pending. Desktop uses the existing Arabic fallback and bidi; web requires an embedded Arabic face. No panel mirroring or parity-grade increase claimed |
| 2026-10-24 | minor | Thai (`th`) draft catalog: `th.toml` translates every UI string (1,791), 589 command labels and the 31 menu wordings, machine-drafted and marked as a draft awaiting native review (9 newer command labels read English, as in the other drafts). The desktop UI now adds an installed Thai face (Noto Sans Thai, Leelawadee UI, Tahoma, Sukhumvit Set, Thonburi, Ayuthaya, Sarabun, Loma, Garuda or Waree) when a layer or page name or the UI language needs it, so Thai names no longer show as tofu squares. No plural forms for Thai. Grade and hours unchanged |
+7 -5
View File
@@ -72,7 +72,7 @@ A message the plugin shows (`notify`) appears as a toast; so does a text result.
**Plugin panels.** A plugin written for API 2 can show a panel while it runs: a floating window,
first placed beside the properties panel (drag its title bar to move it), with the plugin's notes,
fields (text, number, slider, checkbox, menu, list, colour) and buttons, drawn with FigCraft's own widgets
pictures, fields (text, number, slider, checkbox, menu, list, colour) and buttons, drawn with FigCraft's own widgets
and named for screen readers. A colour field's swatch opens FigCraft's colour picker (the plugin hears
of the colour when a drag in the picker ends); its hex can also be typed. Pressing a button or
changing a field calls the plugin back with every field's value; what that callback does is one
@@ -277,7 +277,7 @@ it can handle):
Limits per run, and again per panel callback: 1,000,000,000 fuel (about a second or two of plain
WebAssembly in a debug build, far less in a release build), 64 MB of memory, 100,000 host calls
(each also costs 10,000 fuel, including `reply_len`, `reply_read` and `set_output`), 16 MB per string either way, 1,000 log lines, and modules up to
16 MB. A panel spec is at most 64 KB with 64 controls; settings are at most 64 KB per plugin (keys
16 MB. A panel spec is at most 1 MB with 64 controls, each image at most 256 KB; settings are at most 64 KB per plugin (keys
and JSON values), keys 1–128 characters. A widget callback gets the same limits; its description is
at most 4 MB with 256 layers nested 16 deep, its state at most 16 KB (keys 1–128 characters), and
its images 1 MB each, 2 MB together and 4096 pixels on a side. A property menu has at most 8
@@ -372,8 +372,10 @@ plugin is removed.
```
`title` defaults to the plugin's name. Controls are the manifest's parameter types (`text`,
`number`, `boolean`, `select`, `list`, `slider`, `color`) plus `button` and `note` (text in `label`, up to
1,000 characters, no `name` needed), in order, each `name` unique. A field shows its `value`; a
`number`, `boolean`, `select`, `list`, `slider`, `color`) plus `button`, `note` (text in `label`, up to
1,000 characters, no `name` needed) and `image` (`data`: a PNG, JPEG, WebP, GIF, BMP or TIFF file as
base64, at most 256 KB and 4,096 pixels on a side; `label` is what screen readers say, and what
shows if the picture can't be; no `name` needed), in order, each `name` unique. A field shows its `value`; a
field without one keeps what the user entered before the panel was updated, so a plugin can update
a note without resetting the other fields. Buttons next to each other share a row; the first button
is the primary one. FigCraft checks the whole spec (sizes, kinds, options, bounds) and drops values
@@ -523,7 +525,7 @@ import what you need from `figcraft`.
- Widgets: clicks, field edits and menu items are their only events (no hover or timers), a field
is plain text (no placeholder, length or single-line setting), they can't open a panel, and their layers are frames, text, rectangles, ellipses and images only (no
vectors, components or variables).
- Panels: no images or free layout inside a panel.
- Panels: no free layout inside a panel; images can't be clicked.
- Data in the document: plugins keep data on layers (pages included) with `node.set {props:
{pluginData: {key: value}}}` (a `null` value removes a key) and read it back with `node.get`, which
reports `pluginData: {key: value}` (values as strings) when a layer has any; there is no separate
+10 -2
View File
File diff suppressed because one or more lines are too long