Commit graph

21 commits

Author SHA1 Message Date
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 4b9cd54983 Translate more editor UI surfaces 2026-03-25 18:47:23 +03:00
Danila Poyarkov 1da5483fec Format remaining SDK refactor files 2026-03-24 17:02:01 +03:00
Danila Poyarkov 74bb119579 Extract Vue SDK editor controls and pickers 2026-03-24 09:50:28 +03:00
Danila Poyarkov 329dd301bd Align app UI primitives with shared ui overrides 2026-03-24 09:50:20 +03:00
Danila Poyarkov d3aa511056 Self-review fixes: VueUse adoption, tailwind-variants recipes
VueUse:
- useClipboard({ copiedDuring }) in CodePanel, CollabPanel \u2014 replaces
  manual copied ref + setTimeout pattern
- useDebounceFn in stores/editor.ts \u2014 replaces manual clearTimeout +
  setTimeout for autosave
- onScopeDispose in ExportSection \u2014 replaces onUnmounted for URL cleanup

Tailwind-variants:
- New iconButton() recipe (sm/md) \u2014 replaces 15+ repeated button class strings
- New sectionWrapper() + sectionLabel() \u2014 replaces 12 repeated section classes
- Applied across all 10 property section components
2026-03-17 16:48:12 +03:00
Danila Poyarkov 0fbaf1c24e Adopt Reka UI Tooltip/ToggleGroup, VueUse useClipboard
Reka UI:
- Tip.vue — reusable tooltip wrapping Reka UI Tooltip primitives
- TooltipProvider in EditorView.vue with 400ms delay
- PositionSection: 9 title= attrs → <Tip> wrappers
- TypographySection: alignment → ToggleGroup (single),
  formatting (bold/italic/underline/strikethrough) → ToggleGroup
  (multiple). Keyboard nav + ARIA for free.

VueUse:
- useClipboard replaces navigator.clipboard.writeText in
  CodePanel, CollabPanel, MobileHud, CanvasMenu
2026-03-17 11:30:25 +03:00
Danila Poyarkov 51bbf67f1f Remove re-export shims, import directly from @open-pencil/vue
Delete 9 shim files from src/composables/ that just re-exported
SDK composables. All 18 consumers now import from '@open-pencil/vue'.

Merge dual useNodeProps()/useMultiProps() calls into single
useNodeProps() in 5 property section components.

src/composables/ now has only 4 app-specific files:
use-chat, use-collab, use-keyboard, use-menu.
2026-03-17 08:10:05 +03:00
Danila Poyarkov 30f8a3fda6 Wire editor actions, move kiwi-serialize, clean dead code
- VariablesDialog: replace 7 manual undo.push + graph mutation + requestRender
  patterns with editor.renameCollection/addVariable/removeVariable etc.
- PositionSection: replace inline alignment/flip/rotate geometry with
  editor.alignNodes/flipNodes/rotateNodes
- Move kiwi-serialize.ts into kiwi/ where it belongs
- Remove dead createPropertyChange export from undo.ts
- Un-export internal queryFonts/FontInfo from fonts.ts
- Deduplicate font weight maps: single FONT_WEIGHT_NAMES in fonts.ts,
  figma-api-proxy.ts imports from there
2026-03-16 22:30:56 +03:00
Danila Poyarkov f44f06f721 Refactor: extract business logic from components, clean composables
Tier 1 — Core API fixes:
- updateNodeWithUndo now calls requestRender internally, eliminating
  15+ redundant requestRender() calls across 6 property panel components
- New editor/variables.ts: 7 undo-able variable CRUD operations
  (renameCollection, addCollection, removeCollection, addVariable,
  removeVariable, renameVariable, updateVariableValue)
- New editor/alignment.ts: alignNodes, flipNodes, rotateNodes —
  moves bounding box geometry out of PositionSection.vue

Tier 2 — Composable cleanup:
- Merged use-node-props + use-multi-props into single useNodeProps()
  with MIXED sentinel, eliminating duplicate computed refs
- Added toolCursor() utility — replaces if/else chain in EditorCanvas
- Renamed use-toast.ts → toast.ts (singleton module, not a composable)

Tier 3 — use-canvas-input.ts split (1497 → 817 lines):
- input/types.ts (88) — DragState variants, HandlePosition, TOOL_TO_NODE
- input/geometry.ts (170) — hit testing, handle positions, rotation cursor
- input/pan-zoom.ts (266) — wheel, touch pinch, Safari gestures
- input/resize.ts (121) — constrainToAspectRatio, applyResize
- input/auto-layout.ts (103) — insert indicator computation

All 955 tests pass, 0 lint errors, 1.48% duplication.
2026-03-16 20:35:17 +03:00
Anton Soldatov 3ac016b806
Add data-test-id attributes to all Vue components (#41) 2026-03-04 17:18:26 +03:00
Danila Poyarkov 7e06969ab5 Multi-selection properties panel with tests
Show position, appearance, fill, stroke, and effects sections
when multiple nodes are selected. Shared values display normally,
differing values show 'Mixed'. Editing applies to all selected.

- Shared composable (use-multi-props) for isMulti, active, activeNode
- ScrubInput supports MIXED symbol as model-value
- Per-node previous values for correct undo on multi-edit
- Fix flip transform encoding (scale first column only)
- Fix npm publish auth for MCP package
- 22 new tests: flip, alignment, multi-node merging, kiwi roundtrip
2026-03-03 20:35:51 +03:00
Danila Poyarkov 5a77f2c1cc Fix flip and single-node alignment
Flip horizontal/vertical now toggles flipX/flipY with scale
transform instead of manipulating rotation. Import detects flip
from negative transform determinant. Single-node alignment uses
parent frame bounds instead of bailing out.
2026-03-03 18:35:30 +03:00
Danila Poyarkov 70c88dd72b Replace relative imports with @/ alias
Add @/ → src/ alias in vite.config.ts and tsconfig.json.
Rewrite all ../ imports across 32 files to use @/ paths.
Same-directory ./ imports kept as-is.
2026-02-28 23:08:45 +03:00
Danila Poyarkov 046f23b138 Format codebase with oxfmt 2026-02-28 22:41:34 +03:00
Danila Poyarkov ce46dea54d Sort nodes by position when wrapping in auto-layout, fix null node crash
Nodes are sorted top-to-bottom (then left-to-right) before
reparenting into auto-layout frame. Positions are snapshotted
as plain IDs before mutation to avoid reactive proxy issues.

Property panel sections guard against null node with v-if,
preventing crashes during selection transitions.
2026-02-28 10:36:43 +03:00
Danila Poyarkov b0a35a4d24 Fix rotation icon to rotate-ccw, add rotate 90° button 2026-02-28 09:57:45 +03:00
Danila Poyarkov c66e466fb2 Position section: alignment buttons, rotation icon, flip H/V
- 6 alignment buttons (left/center/right, top/center/bottom) for
  multi-select alignment
- Rotation input with rotate-cw icon and degree suffix
- Flip horizontal and flip vertical buttons
- Matching Figma's Position panel layout
2026-02-28 09:55:02 +03:00
Danila Poyarkov de83a716cd Remove prop drilling from property sections
All sections now get selected node from useNodeProps() composable
instead of receiving it as a prop from PropertiesPanel.
2026-02-28 09:27:03 +03:00
Danila Poyarkov 7e9cd46e0b Split PropertiesPanel into sections, add Typography panel
- PropertiesPanel.vue: 513 → 67 lines (composition only)
- Extracted: PositionSection, LayoutSection, AppearanceSection,
  FillSection, StrokeSection, TypographySection
- Shared useNodeProps() composable for update/commit logic
- Typography panel: font family picker with search (queryLocalFonts),
  weight select, font size, line height, letter spacing, text alignment
- Font picker shows each family in its own typeface
- Loads selected font into both CanvasKit and browser on pick
2026-02-28 09:00:25 +03:00