Commit graph

798 commits

Author SHA1 Message Date
Danila Poyarkov e0d8efb2a4
Merge pull request #411 from open-pencil/figma-paste-images
fix(clipboard): fetch pasted Figma images on desktop
2026-07-18 05:04:49 +03:00
Sadko 665e28cbaa
Merge branch 'master' into master 2026-07-17 22:03:09 -04:00
Danila Poyarkov c2812ba136 fix(tauri): preserve request and abort semantics
- Serialize bodies from the normalized Request, including Request inputs\n- Consume late transport failures after an already-aborted signal\n- Handle pre-aborted clipboard test requests
2026-07-18 05:02:51 +03:00
Danila Poyarkov d7a27a894c fix(app): preserve compact paint field sizing
- Keep embedded number fields from crowding color values\n- Cover paint-row geometry in property-panel E2E tests\n- Refresh the reviewed typography panel snapshot for visible variable actions
2026-07-18 04:57:48 +03:00
Danila Poyarkov 45d8cd51f5 Merge branch 'master' into review-pr-410-current 2026-07-18 04:40:38 +03:00
Danila Poyarkov a3127e716b refactor(tauri): share HTTP abort handling
- Make the desktop HTTP adapter honor standard AbortSignal cancellation
- Use AbortSignal.timeout directly for Figma batch and image requests
- Cover resolved, pre-aborted, and in-flight abort behavior
2026-07-18 04:40:15 +03:00
Danila Poyarkov 585b80d023 Merge remote-tracking branch 'origin/master' into review-pr-411-current 2026-07-18 04:36:06 +03:00
Danila Poyarkov fc5cc2d4b8 fix(app): align variable-enabled panel fields
- Keep Apply variable actions visible with restrained hover treatment
- Preserve the shared 26px NumberField height in column layouts
- Anchor variable pickers to their trigger instead of the zero-size contents wrapper
- Cover control dimensions, action visibility, and popover placement end to end
2026-07-18 04:35:52 +03:00
Danila Poyarkov 798a3c2b2c fix(editor): harden opacity shortcuts
- Match numeric keypad input by generated key so NumLock-off navigation remains available
- Coalesce buffered opacity updates into one undo interaction
- Add end-to-end coverage for digit composition, modifiers, and undo
2026-07-18 04:22:38 +03:00
Danila Poyarkov b08e199c85 fix(clipboard): finalize paste before image fetch
- Complete placement and undo registration before awaiting image hydration
- Bound Figma image requests with timeouts and use shared Tauri detection
- Localize missing-image notifications and cover stalled requests
2026-07-18 04:22:38 +03:00
Danila Poyarkov c8bbdbbb46 Merge branch 'master' into review-pr-411-current 2026-07-18 04:00:57 +03:00
Sadko d78f4bb64e
Merge branch 'open-pencil:master' into master 2026-07-17 17:28:32 -04:00
Danila Poyarkov 0abbb839cb refactor(app): finish visual state theming
- Theme Variables, collaboration, presence, and provider status states\n- Expose semantic default, resizing, following, connection, and tone attributes\n- Remove the final dynamic-state allowlist and document enforced Vue template rules
2026-07-18 00:23:38 +03:00
Danila Poyarkov 69e39cc59e refactor(app): theme toolbar editing states
- Share typed toolbar slots across desktop, mobile, flyout, and action controls\n- Theme alignment cells, fill tabs, and gradient stop states\n- Expose semantic active and disabled state and retire migrated allowlist entries
2026-07-18 00:07:49 +03:00
Sadko 0809f26c8e
Merge branch 'master' into master 2026-07-17 16:56:39 -04:00
Danila Poyarkov 3e750383c0 test(app): add panel UI guardrails
- Lock representative property and Layer Tree states with visual snapshots\n- Cover keyboard tab order and keyboard activation for panel controls\n- Reject template-time UI hooks and raw SVG app icons through parsed Vue ASTs
2026-07-17 23:53:06 +03:00
Sadko 1a82f84ba5
Merge branch 'open-pencil:master' into master 2026-07-17 15:44:35 -04:00
Danila Poyarkov 0bf74a418f feat(text): deepen typography controls
- Add case, justification, vertical alignment, truncation, max-lines, and OpenType controls

- Apply visual text case and measured vertical offsets in CanvasKit rendering

- Preserve nullable preview values, shared text styles, font demand, and .fig metadata

- Add panel, engine, and canvas visual coverage
2026-07-17 22:40:52 +03:00
Sadko 80b103f408
Merge branch 'master' into master 2026-07-17 15:11:00 -04:00
Danila Poyarkov 0bd5afe784 feat(editor): add paint blend mode controls
- Expose localized blend mode selects for fills and expanded effects

- Reuse PropertyList batching for shared-style detachment and mixed-selection undo

- Share Appearance, Fill, and Effects blend mode options

- Add focused E2E and panel visual coverage
2026-07-17 22:10:27 +03:00
Sadko 1151383de0
Merge branch 'open-pencil:master' into master 2026-07-17 15:09:35 -04:00
sadkodev d58cf0b9e9
test(keyboard): add unit tests for opacity buffer logic
Extract opacityFromBuffer as a pure function in core/editor and test
it directly. Covers Figma semantics: 0→100%, 5→50%, 28→28%, 00→0%,
100→100%, clamp at 100%, NaN guard. Refactor the keyboard handler to
reuse the shared function instead of inlining the buffer math.
2026-07-17 15:00:10 -04:00
Danila Poyarkov 23645d5a2d feat(editor): add component property controls
- Model typed component definitions, references, assignments, and preferred swap values

- Add SDK-owned variant, text, boolean, and nested instance-swap controls with mixed-selection undo

- Preserve assignments across variant changes and component synchronization

- Round-trip component property metadata through .fig import and export
2026-07-17 21:59:49 +03:00
sadkodev 1ca1cbc896
refactor(keyboard): deduplicate opacity binding handler
Collapse the duplicated Digit/Numpad opacity bindings into a single
OPACITY_CODES array with one shared run handler. Digit value is
extracted via code.slice(-1), which works for both Digit0-9 and
Numpad0-9.
2026-07-17 14:49:00 -04:00
sadkodev b5de980632
fix(keyboard): treat single 0 as 100% opacity
Figma treats pressing 0 alone as 100% opacity, not 0%. The single-digit
decena rule (n * 10) would produce 0 * 10 = 0% for 0, which is wrong.
Add an explicit check: buffer '0' applies 100%, all other single
digits apply n * 10, and multi-digit buffers apply the literal value.
2026-07-17 14:41:36 -04:00
sadkodev 9d88c4f045
fix(keyboard): apply opacity immediately on each keypress
Replace the 400ms apply-timeout with immediate application on every
digit press. A separate 800ms reset timer clears the buffer between
sequences so digits typed in quick succession still compose (28→28%,
00→0%, 100→100%) but single digits no longer have a perceptible delay.
2026-07-17 14:26:45 -04:00
sadkodev 0300cb521b
refactor(keyboard): address review feedback on opacity shortcuts
- Move setOpacity to core editor action (packages/core/src/editor/nodes.ts)
  so it is testable directly without duplicating logic in tests
- Replace external window listener with tinykeys bindings in
  registerKeyboardShortcuts, reusing shared input/focus guards
- Add 20 bindings for Digit0-9 and Numpad0-9 with modifier guards
- Implement Figma-style multi-digit buffer: 2→20%, 28→28%, 00→0%, 100→100%
  with 400ms timeout and auto-apply at 3 digits
- Simplify selection.setOpacity command to delegate to editor.setOpacity
- Rewrite unit tests to call editor.setOpacity directly
- Add ofetch to dependencies (was imported but missing from package.json)
- Update CHANGELOG
2026-07-17 14:09:46 -04:00
Sadko bec41bd0d4
Merge branch 'open-pencil:master' into master 2026-07-17 14:08:31 -04:00
Danila Poyarkov 51fccb74d3 refactor(app): theme editor navigation states
- Move Pages and TabBar state styling into typed Tailwind Variants themes

- Reuse the segmented control contract for Layers and Assets navigation

- Add light and dark Storybook state coverage and remove migrated architecture allowlist entries
2026-07-17 21:03:35 +03:00
Sadko cb63d6f0f3
Merge branch 'open-pencil:master' into master 2026-07-17 13:57:33 -04:00
Danila Poyarkov c96f87bf9b feat(editor): add shared style bindings
- Model imported fill, stroke, text, effect, and grid style definitions and references

- Add SDK and app selectors with mixed-selection batching, detach-on-edit, and undo restoration

- Preserve style definitions through .fig export and extracted subgraphs

- Document the shared-style composable and update compatibility coverage
2026-07-17 20:28:22 +03:00
Danila Poyarkov 1d8ddd951a feat(editor): add corner smoothing control
- Expose mixed smoothing percentages through Appearance controls
- Preserve per-node corner preview values in one-step undo
- Cover CanvasKit profiles and .fig import/export with engine and visual tests
2026-07-17 19:28:34 +03:00
Danila Poyarkov 2f8d799a5f feat(editor): add stroke geometry controls
- Add mixed-selection cap, join, and miter-limit controls with one-step undo
- Apply node miter limits across CanvasKit stroke paths and vector outline caches
- Preserve imported and edited stroke geometry through Plugin API and .fig roundtrips
2026-07-17 19:01:42 +03:00
Danila Poyarkov d19c05f48e feat(editor): add resize constraints
- Add SDK-owned mixed constraint state, pin controls, and undo-aware updates
- Apply Figma constraint modes recursively during frame resize previews and commits
- Document and test the control, multi-selection behavior, and resize geometry
2026-07-17 18:32:58 +03:00
Danila Poyarkov fc85589438 fix(clipboard): fetch pasted Figma images on desktop
- Resolve Figma image hashes through the existing Tauri HTTP bridge
- Verify downloaded image bytes and report partial failures through typed editor events
- Warn web users and surface actionable desktop fetch errors
2026-07-17 18:03:00 +03:00
Danila Poyarkov 7bfebce0bf feat(editor): scale and theme Layers panel
- Add indexed visible rows, virtual scroll-to-selection, and range selection

- Move Layer Tree state styling into typed Tailwind Variants slots

- Enforce parsed Vue state-class theming and cover 5,000-node documents
2026-07-17 17:23:16 +03:00
Danila Poyarkov 47fe43c3ec feat(text): harden font resolution lifecycle
- Gate ingest rendering until required faces and script fallbacks resolve
- Key CanvasKit artifacts by font registration generation and invalidate affected nodes
- Load character-aware remote subsets with cumulative coverage and exact render aliases
- Use BCP-47 language hints for shaping and CJK fallback order
- Keep baked .fig glyphs as an exhaustion-only fallback
2026-07-17 14:52:35 +03:00
Danila Poyarkov 4b3d97ce0d feat(text): add demand-driven font resolver
- Resolve exact faces through registered, local, cache, and remote sources with deduplicated state transitions\n- Use CanvasKit notdef glyphs to request script fallbacks and repaint after resolution\n- Make CJK coverage analysis codepoint-safe across supplementary characters and style runs
2026-07-17 13:00:09 +03:00
Sadko 183019fe84
Update src/app/shell/keyboard/opacity.ts
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-07-16 22:37:31 -04:00
sadkodev e91ea4b061
feat(keyboard): add Figma-style opacity shortcuts 1-9/0
Add opacity keyboard shortcuts matching Figma: pressing Digit1-Digit9
sets the selected layers to 10%-90% opacity, and Digit0 sets 100%.

- Add 'selection.setOpacity' EditorCommandId with registry metadata
  (shortcut display '1-9, 0') so it appears in the command cheatsheet
- Implement the command in selection.ts using editor.undo.runBatch +
  updateNodeWithUndo, following the toggleVisibility/setBlendMode pattern
- Add setOpacityTarget closure in useEditorCommands so the external
  keyboard handler can inject the digit value before runCommand
- Add canSetOpacity capability (enabled when there is a selection)
- Add bindOpacityKeys handler in src/app/shell/keyboard/opacity.ts,
  following the nudging.ts external-handler pattern since the opacity
  value comes from event.code and cannot be expressed as a fixed
  keybinding in the registry
- Guard against text editing, number field focus, and modifier keys
- Add i18n label 'setOpacity' across all 8 locales
- Add unit tests for single/multi selection, undo batch, and no-op
2026-07-16 22:12:50 -04:00
Danila Poyarkov a62cec00f8 refactor(vue): remove deprecated panel APIs
- Remove FillPickerRoot and useFillPicker from source, exports, and localized docs
- Replace the final PanelRow consumer with accessible auto-layout controls
- Document the canonical panel and fill composition contracts
2026-07-14 18:13:20 +03:00
Danila Poyarkov 27fdef2ea4 feat(app): finish Design panel migration
- Rebuild Typography, Variant, Mask, and Page sections with shared labeled fields
- Expose semantic empty states across list sections
- Replace section test hooks with accessible roles and add focused visual coverage
2026-07-14 17:40:56 +03:00
Danila Poyarkov 5371ed11b8 feat(app): migrate paint effect and export panels
- Share compact item-row and paint-field anatomy across Fill, Stroke, Effects, and Export
- Add COLOR binding transactions with picker rollback and one-step undo
- Replace bespoke panel test hooks with semantic selectors and visual coverage
2026-07-14 17:06:28 +03:00
Danila Poyarkov 29e2172643 Merge branch 'library-opportunities' 2026-07-14 00:38:27 +03:00
Danila Poyarkov 422f83331f feat(vue): promote color and fill primitives
- Add accessible OkHCL channel sliders and use Reka ColorSlider for standard color channels

- Split fill state and binding-aware swatches from application popover composition

- Add keyboard-operable gradient stops, shared demos, generated docs, and focused coverage
2026-07-13 23:41:04 +03:00
Danila Poyarkov bf90a70d05 feat(vue): consolidate color model
- Add a reactive useColorModel API for format state, channel edits, Reka bridges, and slider presentation

- Move the app color panel and ColorInputRoot onto the shared model and remove superseded picker helpers

- Document the public contract and cover precise RGB plus OkHCL intent round trips
2026-07-13 21:48:36 +03:00
Danila Poyarkov fcdf7f1d4c feat(app): migrate layout size controls
- Replace duplicated width and height binding branches with shared semantic fields

- Switch edited Hug and Fill dimensions to Fixed in one reversible transaction

- Add typed LayoutControls actions, documentation, and visual coverage
2026-07-13 15:34:25 +03:00
Danila Poyarkov 12031b76c9 feat(app): migrate position and appearance panels
- Move independent-corner presentation and batched mutations into AppearanceControls

- Rebuild Position and Appearance with aligned panel grids and semantic locators

- Replace type text headers with compact node icons and add visual coverage
2026-07-13 14:47:48 +03:00
Danila Poyarkov 1d60d3a407 feat(ui): add binding field skins
- Show one variable picker affordance with a quiet identity pill and accessible combobox

- Keep bound NumberField focus non-destructive until the first value mutation

- Prefer accessible and semantic test selectors over compound test IDs
2026-07-13 14:04:13 +03:00
Danila Poyarkov 1b7934b98e feat(vue): add property panel primitives
- Add headless PropertySection and accessible SegmentedControl anatomy

- Make PropertyList controlled and exactly typed with an undo-aware editor adapter

- Consolidate SDK metadata loaders and link untranslated docs to canonical pages
2026-07-13 12:36:03 +03:00