Commit graph

987 commits

Author SHA1 Message Date
Danila Poyarkov decee0216e Move format-specific code under io/formats 2026-03-28 14:30:02 +03:00
Danila Poyarkov e396df3224 Add .pen document import
Co-authored-by: Anton Soldatov <eddclyde@yandex.ru>
2026-03-28 13:57:32 +03:00
Danila Poyarkov 0001802dda Add shared IO format registry 2026-03-28 01:58:05 +03:00
Danila Poyarkov d52d38cb3b Remove WebGPU backend 2026-03-27 22:03:19 +03:00
Danila Poyarkov 25788dae36 Remove OpenSpec workflow files 2026-03-27 22:01:38 +03:00
Danila Poyarkov 4f47cf7ac6 Quote vector edit docs descriptions 2026-03-27 21:54:54 +03:00
Danila Poyarkov 49bc46d2e1
Merge pull request #158 from ilyavred/feat/vector-editor
feat(vector): add vector curve editor with enhanced pen tool
2026-03-27 21:47:20 +03:00
Ilya Nikitin b917711451 Merge remote-tracking branch 'origin/feat/vector-editor' into feat/vector-editor 2026-03-27 21:45:25 +05:00
Ilya Nikitin cbae1eaccf lint:
- Add parentheses in bezier-math.ts ternary conditions
- Add parentheses in editor.ts align calculation expression
2026-03-27 21:44:59 +05:00
Ilya Nikitin 98c682641b lint:
- Add parentheses in bezier-math.ts ternary conditions
- Add parentheses in editor.ts align calculation expression
2026-03-27 21:38:27 +05:00
Ilya Nikitin 0ff5a87ccb update pen tool space drag spec
Adds a new scenario to the pen tool specifications defining the behavior for relocating the active vertex with spacebar during a curve drag, including asserting that the cursor remains a crosshair instead of switching to the hand tool.

Made-with: Cursor
2026-03-27 21:27:45 +05:00
Ilya Nikitin 455f04d6f1 Merge branch 'up_master' into feat/vector-editor
# Conflicts:
#	src/composables/use-keyboard.ts
2026-03-27 19:33:07 +05:00
Ilya Nikitin cedd88813b Use KeyboardEvent.code instead of KeyboardEvent.key across editor and input handling. 2026-03-27 17:13:35 +03:00
Ilya Nikitin ae2fbccf01 fix(components): update Lucide icon names in properties sections
Ensure proper semantic alignment between icon names and their visual representation
2026-03-27 17:09:34 +03:00
Ilya Nikitin e393ca7a07 fix(properties): update Lucide icon names for alignment and flip controls
Ensure proper semantic alignment between icon names and their visual representation
2026-03-27 17:09:02 +03:00
Danila Poyarkov c1d7fc80b0 Fix property panel visibility toggles, independent corners/stroke sides, extract shared ColorStyleRow
- Fix fill/stroke/effect/appearance visibility eye toggle (stale clone reads)
- Fix independent corner radii toggle not showing 4 inputs
- Fix stroke sides toggle: replace dropdown with direct toggle like corners
- Copy uniform weight to all sides when expanding stroke sides
- Batch multi-selection visibility toggles into single undo entry
- Extract ColorStyleRow shared by FillSection and StrokeSection
- Replace useFillVariableBinding/useStrokeVariableBinding with useColorVariableBinding(kind)
- AppearanceSection uses useAppearance() directly instead of slot wrapper
- Add sceneVersion dependency to useNodeProps and PropertyListRoot computeds
- Add E2E tests for visibility toggles and corner/stroke side toggles
2026-03-27 17:06:33 +03:00
Ilya Nikitin 2b92916881 feat(vector): add anchor point alignment for selected vertices
Align selected anchor points relative to each other in vector edit mode. The standard alignment buttons in the position panel now operate on selected vertices when 2 or more are selected, enabling precise vector path editing workflows.
2026-03-26 11:55:56 +05:00
Ilya Nikitin 6ad25297df Merge branch 'up_master' into feat/vector-editor
# Conflicts:
#	CHANGELOG.md
#	src/composables/use-keyboard.ts
2026-03-26 02:45:30 +05:00
Ilya Nikitin b1997e413f feat(vector): add vector curve editor with enhanced pen tool
- Add bezier math utilities for VectorNetwork manipulation
- Enable resuming pen drawing from existing open path endpoints
- Allow closing open paths by dragging endpoints together
- Add comprehensive vector editing capabilities for curves and paths
2026-03-26 02:28:55 +05:00
Danila Poyarkov ae13bb1cbd Sync locale files with latest i18n keys 2026-03-25 21:54:12 +03:00
Danila Poyarkov e03038f4bf Translate collaboration share popover 2026-03-25 21:48:38 +03:00
Danila Poyarkov 3d9d559451 Update changelog for recent SDK and i18n work 2026-03-25 21:45:52 +03:00
Danila Poyarkov 4b9cd54983 Translate more editor UI surfaces 2026-03-25 18:47:23 +03:00
Danila Poyarkov 9f296b7357 Translate chat setup and code panel strings 2026-03-25 18:40:17 +03:00
Danila Poyarkov 2f646ffcaf Translate more visible UI strings 2026-03-25 18:26:03 +03:00
Danila Poyarkov 77032ab092 Translate visible panel chrome for Russian locale 2026-03-25 18:12:09 +03:00
Danila Poyarkov 9220ef399b Handle checkbox submenu items in app menu 2026-03-25 18:07:24 +03:00
Danila Poyarkov cf16857a76 Add locale picker to app menu 2026-03-25 18:05:58 +03:00
Danila Poyarkov e52fcf1b8f Fix Vue package declaration build 2026-03-25 17:43:16 +03:00
Danila Poyarkov 6bfc5c2189 Rename toggleUI i18n key 2026-03-25 17:40:26 +03:00
Danila Poyarkov ea4676d991 Finish i18n pass for menus and tool labels
Localize remaining menu state labels like Hide/Show and Lock/Unlock,
wire toolbar tool/action labels through the i18n stores, and localize
the app menu UI toggle tooltip.

Replace template-string JSON imports with an explicit locale loader map
so published package builds have stable locale asset references.
2026-03-25 17:39:47 +03:00
Danila Poyarkov eb2891233a Wire i18n into commands, menus, and add locale files
Commands and menu models now read labels from nanostores i18n
messages instead of hardcoded English strings. App menu rebuilt
to use i18n directly instead of matching on localized labels.

Added locale files: de, es, fr, it, pl (ru was added earlier).
All 6 translations plus English base cover menus, commands, tools,
panels, pages, and dialogs.
2026-03-25 17:05:11 +03:00
Danila Poyarkov 2b3219e106 Add i18n to Vue SDK with nanostores
nanostores + @nanostores/i18n + @nanostores/vue (~6 KB total).

English base translations defined inline in messages.ts, other
locales loaded on demand from JSON. Grouped by domain: menu,
commands, tools, panels, pages, dialogs.

useI18n() composable returns reactive translation objects plus
locale controls. Russian locale included as first translation.

Browser language auto-detected, user preference persisted in
localStorage.
2026-03-25 16:17:03 +03:00
Danila Poyarkov 1f851e29cd Normalize textAutoResize to NONE for auto-layout children on export
Figma expects text inside auto-layout frames to have no textAutoResize
field (NONE). Internally OpenPencil uses WIDTH_AND_HEIGHT so the layout
engine can measure text, but this caused overflow when exported .fig
files were opened in Figma.

Normalize at export time, matching how we already normalize font
families for the binary format.

Fixes #136
2026-03-25 06:41:45 +03:00
Danila Poyarkov 1e35c0d3a8 Preserve fig-kiwi version on roundtrip
Parse the version field from the fig-kiwi header during .fig import
and store it on SceneGraph.figKiwiVersion. Use the original version
when re-exporting. New files default to 101 (current Figma standard).

Previously hardcoded to 106, which Figma rejected on import.

Fixes #153
2026-03-25 06:02:24 +03:00
Danila Poyarkov 29876f0c2b Await font loading before first canvas render
The initial renderNow() fired before loadFonts() completed, causing
text measurement to return null on slower connections (especially
Safari). Layout computed without text dimensions got corrupted.

Move loadFonts() into the async init() flow and only render after
fonts are ready.
2026-03-25 00:32:06 +03:00
TKman c52f88e34c feat: add spacebar hold to temporarily activate Hand (pan) tool
Hold Spacebar to temporarily switch to the Hand tool for panning,
release to return to the previously active tool. This matches the
standard Figma UX pattern.

- Uses separate keydown/keyup event listeners for reliable handling
- Guards against text editing mode and key repeat
- References state.activeTool for correct tool state

Fixes #147
2026-03-24 23:47:56 +03:00
Shai Rubinstein 2e723caba0 fix: kiwi serialization bugs causing broken auto-layout in Figma import
- Zero transforms for auto-layout children (Figma computes positions)
- Write bordersTakeSpace from strokesIncludedInLayout
- Always write explicit lineHeight, defaulting to ceil(fontSize * 1.2)
- Normalize font family in derivedTextData fontMetaData and fontName
- Extend normalizeFontFamily to strip optical size suffixes (9pt, 18px)
- Extract computeExportTransform() helper for lint compliance
- Add 20 unit tests covering all fixes

Fixes #134
2026-03-24 23:47:56 +03:00
Shai Rubinstein 5139836816 fix: default TEXT nodes to solid black fill
TEXT nodes created via SceneGraph.createNode() defaulted to empty
fills, causing text to be invisible when .fig files are opened in
Figma. Now defaults to a solid black fill matching Figma's behavior.

Closes #133
2026-03-24 23:47:56 +03:00
Shai Rubinstein 2efd63ea09 fix: normalize font family names on .fig export
Strip optical size suffixes (e.g. "DM Sans 9pt" → "DM Sans") and
"Variable" suffixes when writing fontName.family to .fig files.
This ensures Figma recognizes the font instead of showing a
"Missing font" dialog.

Closes #131
2026-03-24 23:47:56 +03:00
myhency 8599750f1d feat(fonts): load multiple CJK Google Fonts for full Han/Japanese/Korean coverage
Previously, the CJK fallback loaded only a single Google Font
(Noto Sans SC) when local system fonts were unavailable. This meant
Korean and Japanese text would not render correctly in browsers that
block the Local Font Access API.

Changes:
- Replace CJK_GOOGLE_FONT (single string) with CJK_GOOGLE_FONTS array
  containing Noto Sans SC, Noto Sans JP, and Noto Sans KR
- Load all three fonts in parallel via Promise.allSettled so each
  script has proper glyph coverage
- Update text renderer to pass all loaded CJK families as fallbacks
- Maintain backward compatibility: getCJKFallbackFamily() still works,
  new getCJKFallbackFamilies() returns the full list
2026-03-24 23:47:55 +03:00
Danila Poyarkov 2956507783 Fix switch_page not persisting across MCP tool calls
Each RPC tool call created a fresh FigmaAPI instance, so switch_page
set currentPageId on a throwaway object. Sync the page change back
to the editor store after tool execution.

Fixes #112
2026-03-24 23:47:55 +03:00
Danila Poyarkov bceddd759f Guard keyboard shortcuts during canvas text editing
Backspace/Delete and tool shortcuts (V, R, F, T, etc.) fired during
canvas text editing because the guard only checked for DOM input/textarea
focus, not the canvas TextEditor state. Add editingTextId check to both
the onEventFired handler and the plain() shortcut helper.
2026-03-24 23:47:55 +03:00
Danila Poyarkov 2ace1d4e49
Merge pull request #137 from open-pencil/refactor/vue-sdk-architecture
Refactor: extract @open-pencil/vue headless SDK, split editor into modules
2026-03-24 23:29:21 +03:00
Danila Poyarkov a743da54b6 Document Vue SDK public APIs 2026-03-24 23:25:06 +03:00
Danila Poyarkov 99e646aaa4 Refine docs structure for SDK and automation 2026-03-24 23:24:08 +03:00
Danila Poyarkov 07fade6abb Use explicit Vue SDK barrel exports 2026-03-24 18:37:08 +03:00
Danila Poyarkov 80a2855bb3 Fix review issues in undo and Vue SDK 2026-03-24 18:15:40 +03:00
Danila Poyarkov bff8895775 Fix CLI tsconfig rootDir mismatch 2026-03-24 17:16:44 +03:00
Danila Poyarkov 936ba6637b Adopt package aliases across Vue SDK 2026-03-24 17:10:43 +03:00