Danila Poyarkov
29d7ae4817
refactor(vue): centralize canvas menu groups
2026-05-17 14:09:52 +03:00
Danila Poyarkov
5634e0ecb4
refactor(vue): centralize editor command metadata
2026-05-17 13:56:56 +03:00
Danila Poyarkov
2ef07b7049
refactor(text): use explicit font weight aliases
2026-05-17 13:44:58 +03:00
Danila Poyarkov
0f58b3eb37
chore(text): align font face module naming
2026-05-17 13:42:51 +03:00
Danila Poyarkov
3534a4a919
fix(canvas): render exact font faces
2026-05-17 13:40:56 +03:00
Danila Poyarkov
f9034d4492
perf(kiwi): avoid shifting import propagation queues
2026-05-17 13:19:07 +03:00
Danila Poyarkov
123a5ceddb
Merge pull request #256 from guimaurer/fix/image-fill-hash-encoding
...
fix: image fills lost after save . hex hash corrupted in Kiwi byte[] encoding
2026-05-17 13:03:22 +03:00
Danila Poyarkov
bb6c537b8e
Merge master into image fill hash fix
2026-05-17 13:02:00 +03:00
Danila Poyarkov
3b323a8740
test: cover fig image fill hash roundtrip
2026-05-17 12:58:43 +03:00
Danila Poyarkov
cf0df391c5
docs: document private security reporting
2026-05-17 12:52:10 +03:00
Danila Poyarkov
c044d26431
perf(canvas): cache label hit tests and trace scene renderer
2026-05-17 03:27:19 +03:00
Danila Poyarkov
faaa741911
feat(profiler): expose scene picture and flush timings
2026-05-17 03:09:16 +03:00
Danila Poyarkov
1326aac68d
Revert "perf(canvas): preview mouse panning with CSS transforms"
...
This reverts commit 30191ad11b .
2026-05-17 03:03:51 +03:00
Danila Poyarkov
30191ad11b
perf(canvas): preview mouse panning with CSS transforms
2026-05-17 02:57:35 +03:00
Danila Poyarkov
05b3a870c2
perf(canvas): avoid duplicate scene picture draw on record
2026-05-17 02:50:01 +03:00
Danila Poyarkov
f5bcf92ce4
test(canvas): cover scene cache recovery after drag preview
2026-05-17 02:41:13 +03:00
Danila Poyarkov
957d822af1
perf(canvas): restore scene cache after position previews
2026-05-17 02:38:23 +03:00
Danila Poyarkov
7f784ef1ec
perf(canvas): fast-path solid render colors
2026-05-17 02:34:41 +03:00
Danila Poyarkov
617f3864ac
perf(canvas): keep scene picture cache warm after edits
2026-05-17 02:27:58 +03:00
Danila Poyarkov
0b3b620b54
perf(canvas): cache vector stroke paths
2026-05-17 02:21:53 +03:00
Danila Poyarkov
197e19b6f4
test(e2e): cover live move repaint and component labels
2026-05-17 02:11:04 +03:00
Danila Poyarkov
6e413ccfa1
fix(canvas): repaint scene during live transforms
2026-05-17 01:59:17 +03:00
Danila Poyarkov
446ab8bc59
fix(canvas): align live text baseline with exports
2026-05-17 01:48:58 +03:00
Danila Poyarkov
aee208b34a
fix(demo): align app preview header button
2026-05-17 01:34:40 +03:00
Danila Poyarkov
6954ff3ce7
refactor(jsx): replace hand-rolled Tailwind mapping with twirlwind
...
- Use twirlwind for CSS-to-Tailwind class conversion instead of
450 lines of manual lookup tables and formatting functions
- Build a CSS style object from scene node properties, pass to twirl()
- Remove design-jsx/tailwind.ts (pxToSpacing, colorToTwClass, etc.)
- Remove unused Tailwind-specific helpers from jsx/helpers.ts
- Update tests for twirlwind's v4-native output format
2026-05-17 00:54:53 +03:00
Danila Poyarkov
6f4e8274d6
fix(canvas): use screen-space handles for multi-selection bounds
...
Single-node selection draws handles inside withNodeBounds() which
applies canvas.scale(zoom), so handle size / zoom is correct there.
Multi-selection drawGroupBounds() computes screen-space coordinates
directly (x * zoom + pan) without a canvas zoom transform, so handles
need fixed screen-space sizes. Added drawHandleScreenSpace() and
drawBoundsHandlesScreenSpace() for the multi-select path.
2026-05-17 00:21:34 +03:00
Danila Poyarkov
241cd4442e
fix(demo): use auto-layout header in app preview
2026-05-16 20:58:05 +03:00
Danila Poyarkov
8d21d05f25
fix(clipboard): convert quadratic beziers to cubic instead of flattening to lines
2026-05-16 18:43:24 +03:00
Danila Poyarkov
ea323c33f0
fix(clipboard): match shaped glyphs by character index, not array position
2026-05-16 18:38:58 +03:00
Danila Poyarkov
578b93e189
fix(clipboard): use CanvasKit shaping + pretext word wrap for Figma text
...
- shapeTextForClipboard() now processes all lines, not just the first
- buildFigmaClipboardHTML() passes CanvasKit-shaped positions to
derivedTextData when available (browser with CanvasKit loaded)
- Add @chenglou/pretext for proper Unicode-aware word wrapping as
fallback when CanvasKit isn't available (CLI, headless, .fig export)
- Falls back to basic word-boundary wrapping if pretext fails
2026-05-16 18:26:24 +03:00
Danila Poyarkov
7cfa08aec5
fix(clipboard): normalize glyph advance by fontSize
...
Figma expects derivedTextData glyph advance values normalized to
font-size units (advance / fontSize), not absolute pixel values.
This caused pasted text to appear horizontally mirrored because
Figma multiplied the already-absolute advances by fontSize again.
2026-05-16 18:02:10 +03:00
Danila Poyarkov
680350cdcb
test(e2e): extract shared editor setup and store helpers
...
- useEditorSetup() / useEditorSetupWithClear() in tests/e2e/fixtures.ts
- Migrated 15 simple specs to shared fixture
- Moved getSelectedNode/getSelectedNodes to tests/helpers/store.ts
- Replaced inline getSelectedNode in 4 specs
- Reverted 8 specs with custom beforeAll setup (not fixture-compatible)
- Test duplication in tests/: 329 → 307 clones (10.12% → 8.95%)
2026-05-16 16:55:34 +03:00
Danila Poyarkov
11e38b626a
test(e2e): extract shared editor setup fixture
...
- useEditorSetup() / useEditorSetupWithClear() in tests/e2e/fixtures.ts
- Migrated 17 specs to shared fixture, removing ~300 lines of boilerplate
- Moved getSelectedNode/getSelectedNodes to shared store helpers
- Replaced inline getSelectedNode in 4 specs with shared import
- Test duplication: 329 → 308 clones (10.12% → 9.08%)
2026-05-16 16:19:03 +03:00
Danila Poyarkov
e7b610b228
docs: restore dropped user-facing changelog entries
2026-05-16 15:42:52 +03:00
Danila Poyarkov
a33100b076
docs: tighten changelog for end users
2026-05-16 15:42:18 +03:00
Danila Poyarkov
9c5db24cf5
docs: update changelog for test and quality improvements
2026-05-16 15:40:06 +03:00
Danila Poyarkov
23583525f5
test(e2e): hide rulers in visual regression snapshots
...
- Add &no-rulers to all E2E test URLs that use &no-chrome
- Regenerate snapshots without ruler ticks/selection badges
- Remove stale snapshot dirs from old test paths
2026-05-16 15:36:37 +03:00
Danila Poyarkov
f7445c88e8
chore: include dupe detection in check gate
2026-05-16 15:12:35 +03:00
Danila Poyarkov
41b314b5ef
chore(test): require zero duplicate clones
2026-05-16 14:49:06 +03:00
Danila Poyarkov
e94323ee29
refactor: remove duplicated implementation blocks
2026-05-16 14:45:32 +03:00
Danila Poyarkov
b460d194e7
chore(test): trim stale path redirects
2026-05-16 14:28:40 +03:00
Danila Poyarkov
41fccdfcc6
chore(test): flag broad engine basic tests
2026-05-16 14:26:44 +03:00
Danila Poyarkov
46bf5a2bd2
test(engine): split profiler coverage by module
2026-05-16 14:15:04 +03:00
Danila Poyarkov
cb51fc73fc
test(tauri): clean up font cache mocks
2026-05-16 13:55:09 +03:00
Danila Poyarkov
bf636155cf
test(engine): stabilize render and heavy fig tests
2026-05-16 13:39:45 +03:00
Danila Poyarkov
e6a6926f39
test(engine): split geometry coverage by domain
2026-05-16 13:30:25 +03:00
Danila Poyarkov
ab700fd8be
test(engine): stabilize full engine smoke
2026-05-16 13:27:46 +03:00
Danila Poyarkov
21b649e540
test(engine): organize clipboard and vector coverage
2026-05-16 13:18:38 +03:00
Danila Poyarkov
2fc90769b1
fix(kiwi): export variant prop defs as text
2026-05-16 13:09:48 +03:00
Danila Poyarkov
535d243a14
test(engine): split mutation coverage by domain
2026-05-16 12:51:43 +03:00