Commit graph

368 commits

Author SHA1 Message Date
Danila Poyarkov 1d8f4bf8c4 refactor(app): align canvas menu file layout 2026-05-17 15:29:14 +03:00
Danila Poyarkov f37a263279 refactor(app): centralize canvas menu actions 2026-05-17 15:27:10 +03:00
Danila Poyarkov b790a044e4 refactor(app): model canvas copy submenu 2026-05-17 15:14:55 +03:00
Danila Poyarkov 38d30e25e0 refactor(app): derive menu shortcut formats 2026-05-17 14:50:43 +03:00
Danila Poyarkov 1a03c0e8e8 refactor(app): reuse menu shortcut metadata 2026-05-17 14:44:37 +03:00
Danila Poyarkov 883601f548 fix(ui): format shortcut tooltips by platform 2026-05-17 14:31:29 +03:00
Danila Poyarkov c922e1d9a4 fix(i18n): localize provider settings 2026-05-17 14:24:24 +03:00
Danila Poyarkov 52149e5771 fix(vue): localize static canvas menu labels 2026-05-17 14:20:33 +03:00
Danila Poyarkov 433d812b9d refactor(vue): format command shortcuts by platform 2026-05-17 14:19:37 +03:00
Danila Poyarkov 5634e0ecb4 refactor(vue): centralize editor command metadata 2026-05-17 13:56:56 +03:00
Danila Poyarkov 692ddf9a3f refactor(toolbar): reuse test id helpers 2026-05-15 13:13:24 +03:00
Danila Poyarkov 698bcde00b refactor(vue): share generated test id helpers 2026-05-15 13:10:44 +03:00
Danila Poyarkov 744f0a0f42 refactor(vue): use test id directive 2026-05-15 12:37:00 +03:00
Danila Poyarkov 50a4e1bf93 refactor(vue): use test id helper for dynamic attrs 2026-05-15 12:28:50 +03:00
Danila Poyarkov 711c7cf5a9 refactor(vue): use shared test id prop types 2026-05-15 12:18:50 +03:00
Danila Poyarkov 0749bfa755 chore(vue): standardize test id helpers 2026-05-15 12:07:58 +03:00
Danila Poyarkov e2eaf85cff chore(vue): enable stricter prop linting 2026-05-15 11:57:38 +03:00
Danila Poyarkov b46295a7bb fix(editor): close padding editor on canvas click 2026-05-15 11:49:18 +03:00
Danila Poyarkov 031897c73a test(editor): cover auto-layout padding editor 2026-05-14 22:37:16 +03:00
Danila Poyarkov 686ca5326f chore: enforce Vue style and state boundaries 2026-05-14 22:05:43 +03:00
Danila Poyarkov 5acb8ffb6c chore: guard shared UI boundaries 2026-05-14 19:00:51 +03:00
Danila Poyarkov d2c3b1bce8 test(editor): cover auto-layout hover targets 2026-05-14 18:28:04 +03:00
Danila Poyarkov c3fd32a516 feat(editor): add auto-layout hover controls 2026-05-14 18:15:53 +03:00
Danila Poyarkov 9ab6bfa3bf fix(app): restore left panel scrolling 2026-05-13 05:47:32 +03:00
Danila Poyarkov 49620ef26b fix(vue): distinguish layer child drops 2026-05-13 05:10:29 +03:00
Danila Poyarkov c38778094d fix(vue): restore layer tree reordering 2026-05-13 04:47:23 +03:00
Danila Poyarkov ccc2b0a52c chore(release): polish asset labels and loaders 2026-05-13 03:44:11 +03:00
Danila Poyarkov 9daf260471 feat(components): render asset detail previews
- Generate PNG previews for the selected component/default variant in the details dialog
- Revoke stale preview URLs and refresh on scene changes
- Assert the rendered preview image in assets e2e coverage
2026-05-12 22:24:16 +03:00
Danila Poyarkov 0a53c91a46 feat(components): add asset details dialog
- Add a Figma-style component details dialog from local Assets
- Show preview, description, library key, documentation link, variant properties, and insert action
- Cover details metadata in the Assets panel e2e test
2026-05-12 22:16:07 +03:00
Danila Poyarkov 880fcf3d5b feat(components): surface library metadata in assets
- Show imported library badges in the local Assets panel
- Display component descriptions and documentation links from Figma metadata
- Cover library metadata rendering in the Assets panel test
2026-05-12 21:56:07 +03:00
Danila Poyarkov 4bf161b983 fix(components): sync instances when switching variants
- Swap instance contents when changing variants instead of only updating componentId
- Recreate instance redo state without stale child IDs
- Insert assets into entered containers using local coordinates
- Fall back to Windows paths when URL parsing fails
2026-05-12 18:43:11 +03:00
Danila Poyarkov 24d3ea748f fix(components): respect default variants in assets
- Insert component set assets using explicit default variant values
- Report duplicate variant value combinations in the assets panel
- Cover default insertion and conflict warnings in Playwright
2026-05-12 18:16:51 +03:00
Danila Poyarkov 1ceabf7938 feat(components): add local assets panel
- Add a left-sidebar Assets tab for local components and component sets
- Insert component set assets as instances of the default variant
- Showcase local component set insertion in the demo
- Cover search, empty state, standalone insert, and variant switching with Playwright
2026-05-12 17:30:35 +03:00
Danila Poyarkov c79c9106fb feat(components): add variant inspector UI
Show variant property dropdowns in the design panel when an instance
of a component set is selected. Switching a dropdown value finds the
matching variant component and updates the instance's componentId.

- VariantSection.vue with property dropdowns using AppSelect
- Bridge variant actions to the editor return object
- i18n for en, ru, zh-CN

Ref #239
2026-05-07 19:48:59 +03:00
Danila Poyarkov ad88364562 feat(variables): bind min/max size constraints to variables
Wire VariableScrubInput for minWidth, maxWidth, minHeight, maxHeight
in the size controls panel. Uses the after-variable slot to preserve
the existing select dropdown suffix alongside the variable binding UI.
2026-05-07 14:32:36 +03:00
Danila Poyarkov a6da185e54 refactor: eliminate HTMLInputElement template casts
- Add shared DOM event helpers to Vue SDK (inputValue, inputNumberValue,
  blurTarget, selectTarget) in packages/vue/src/shared/dom-events.ts
- Export from @open-pencil/vue for app consumption
- Replace all template `as HTMLInputElement` casts with helper calls:
  ColorPickerPanel fields, PickerSlider, GradientEditor, ColorInput,
  CollabPanel, AppMenu, ScrubInputRoot
- Fix useInlineRename to use instanceof guards instead of casts
- Fix document name rename to accept Event directly
2026-05-07 10:24:46 +03:00
Danila Poyarkov 0a268f0a65 feat(variables): add inspector bindings for typography properties
- Add lineHeight, letterSpacing, fontWeight, paragraphSpacing,
  paragraphIndent to NumberBindingPath
- Wire lineHeight and letterSpacing inputs in TypographySection
  to VariableScrubInput with variable binding support
2026-05-07 09:50:52 +03:00
Danila Poyarkov 506b5f81e1 refactor(variables): reuse useInlineRename for dialog renaming
- Reuse useInlineRename composable for collection and mode renaming
- Accept Event in useInlineRename.commit to eliminate template casts
- Remove HTMLInputElement casts from PagesPanel and LayerTree blur handlers
- Remove hand-rolled rename state from dialog composable
2026-05-07 00:02:13 +03:00
Danila Poyarkov 107e9f3d51 feat(variables): add mode management and collection deletion
Core:
- Add addMode, removeMode, renameMode, setDefaultMode to SceneGraph
- Add editor actions with full undo: addMode, removeMode, renameMode,
  setDefaultMode, duplicateMode, setActiveMode

Vue SDK:
- Wire all mode and collection actions through SDK helpers
- Add mode rename state to dialog composable
- Remove HTMLInputElement casts from commit handlers

UI:
- Mode management lives in the table column headers (Figma-style):
  double-click to rename, right-click for context menu (rename,
  duplicate, set as default, delete), + button after last mode column
- Collection ⋯ dropdown menu with rename and delete
- Use shared menu UI styles throughout
- i18n for en, ru, zh-CN
2026-05-06 21:36:04 +03:00
Danila Poyarkov c3f5189f8f style: tighten import grouping
- Configure oxfmt custom import groups for workspace, app, package, and test aliases
- Keep type imports grouped with their matching source category instead of one global tail group
- Expand the format script to cover formatter config, Vite files, and scripts
2026-05-06 02:22:08 +03:00
Danila Poyarkov ddb1db8175 style: format imports 2026-05-06 02:16:37 +03:00
Danila Poyarkov 68d15440b1 feat(app): add variable type creation menu 2026-05-05 23:49:20 +03:00
Danila Poyarkov 020b55a8ae test(app): cover Tauri file actions 2026-05-05 22:24:57 +03:00
Danila Poyarkov cc216c79db test(app): cover font settings UI 2026-05-05 22:12:33 +03:00
Danila Poyarkov 0f9b69d051 test(app): expand Tauri helper coverage 2026-05-05 22:07:02 +03:00
Danila Poyarkov f29da6c5cd refactor(vue): clean up primitive UI APIs
- Replace one-off class props with typed ui objects

- Group renderless slot actions and remove DOM ref callback plumbing

- Make local font access and typography font loading explicit capability objects
2026-05-05 20:57:13 +03:00
Joseph Cumines c69e3884cf
fix(core): critical codec and canvas fixes
- Deduplicate plugin data and relaunch data during .fig parsing/export
- Unify shared plugin data into the pluginData storage path
- Refactor shadow rendering and harden CanvasKit font provider teardown
- Expand engine and renderer coverage
2026-05-05 14:58:02 +03:00
Danila Poyarkov 7252b450cf fix(app): fix variable picker click and layout spacing
- ScrubInput: skip scrub drag when pointerdown target is inside a button
- Size fields: always show chevron icon instead of hover-swap to prevent layout jump
- Variable picker: add right padding when no chevron follows, none when chevron present
2026-05-04 14:39:49 +03:00
Danila Poyarkov 8458334fec fix(app): prevent ScrubInput scrub drag from swallowing button clicks
The outer ScrubInput container captured all pointerdown events and
started a scrub drag, preventing embedded button clicks (like the
variable picker diamond icon) from ever reaching their handlers.

Now checks if the click target is inside a <button> before starting
the scrub.
2026-05-04 14:05:45 +03:00
Danila Poyarkov 6cc8b9d07c feat(app): extend variable binding to more inspector fields
Add VariableScrubInput — reusable wrapper that combines ScrubInput
with variable binding picker and detach button. Wire it into:

- Corner radius (uniform + 4 independent corners)
- Opacity
- Auto-layout gap (primary + cross axis)
- Padding (horizontal/vertical + 4 individual sides)
- Font size

All fields get bind, detach, create, search, and detach-on-edit
behavior automatically through the shared component.
2026-05-04 13:43:33 +03:00