Commit graph

18 commits

Author SHA1 Message Date
Danila Poyarkov 18609e00c3 Fix all lint, typecheck, and formatting issues
- 0 lint warnings (was 66), 0 type errors (was 30+)
- Add typed interfaces for Paint.stops/transform, Effect.blendMode,
  NodeChange.strokeCap/strokeJoin/dashPattern in kiwi codec
- Add CompiledSchema.encodePaint/encodeNodeChange methods
- Remove all no-explicit-any: use Window declaration merging for
  queryLocalFonts, showOpenFilePicker, showSaveFilePicker
- Remove all non-null assertions: add guards, use ?. operator,
  ?? fallbacks throughout
- Add SceneGraph.copyProp typed helper for instance sync
- Suppress kiwi-schema lint warnings via oxlint override
- Remove unused imports, variables, parameters
- Use proper CanvasKit StrokeCap/StrokeJoin enums in renderer
- Run oxfmt with import sorting
2026-02-28 22:57:33 +03:00
Danila Poyarkov 046f23b138 Format codebase with oxfmt 2026-02-28 22:41:34 +03:00
Danila Poyarkov b220fe13e6 Show effect controls inline instead of floating popover
The properties panel has overflow-y: auto which clips absolute
positioned popovers. Expand controls inline below the effect
row instead — simpler and always visible.
2026-02-28 20:49:23 +03:00
Danila Poyarkov c4f6f1caaa Redesign Effects section to match Figma's layout
- Compact row: color swatch + type dropdown + eye toggle + minus
- Expanded controls in a floating popover anchored to the left
- Labeled rows: Position (X/Y), Blur, Spread, Color with hex + opacity
- Type dropdown in popover header with X close button
- Eye/minus icons hidden until row hover (matches fill/stroke rows)
2026-02-28 20:40:03 +03:00
Danila Poyarkov daa949e9e3 Add Effects section to properties panel
Support adding, removing, and editing drop shadows, inner shadows,
layer blurs, background blurs, and foreground blurs. Each effect row
has visibility toggle, type dropdown, and remove button. Expanded
view shows offset, blur, spread, and color controls for shadows,
or just blur radius for blur effects.
2026-02-28 20:12:37 +03:00
Danila Poyarkov b7242a78c2 Fix context menu not showing: scoped slot pattern + icon fix
- CanvasContextMenu now exposes onContextMenu via scoped slot instead
  of wrapping in a <div> (which broke flex layout — the div had no
  flex-1, so it collapsed and never received contextmenu events)
- EditorCanvas binds the handler directly on its own flex-1 div
- Fix lucide/diamonds icon not found — use lucide/component for
  COMPONENT_SET (the actual 4-diamond component icon)
2026-02-28 18:10:26 +03:00
Danila Poyarkov cf454a855e Fill type picker with solid/gradient/image tabs and gradient stop editing
- FillPicker component: 3 category tabs (Solid, Gradient, Image), gradient
  subtype dropdown (Linear/Radial/Angular/Diamond), draggable gradient stop
  bar, per-stop color/position/opacity editing with ScrubInput
- FillSection uses FillPicker instead of ColorPicker for full Fill editing
- Default gradient transforms for each subtype so renderer picks them up
- colorToRgba255/rgba255ToColor helpers in color.ts
- Custom SVG icons for fill type tabs (solid square, gradient fade)
2026-02-28 17:26:50 +03:00
Danila Poyarkov e2e0e75173 Tier 1 rendering parity: gradients, images, effects, strokes, arcs
Data model:
- Gradient fills (LINEAR, RADIAL, ANGULAR, DIAMOND) with stops + transform
- Image fills with hash reference, scale mode, transform
- Blend modes on fills, nodes, effects
- Stroke cap, join, dash pattern, independent border weights
- Arc data for partial ellipses/donuts
- Text: vertical align, auto-resize, case, decoration, max lines
- Constraints: horizontal/vertical
- New node types: ROUNDED_RECTANGLE, COMPONENT, COMPONENT_SET,
  INSTANCE, CONNECTOR, SHAPE_WITH_TEXT

Import:
- All paint types imported (not just SOLID)
- Image hashes extracted from .fig ZIP images/ directory
- Font weight mapping (Thin→100 through Black→900)
- Arc data, stroke options, constraints, text properties

Renderer:
- Gradient shaders via CanvasKit (linear, radial, sweep)
- Image fills with FILL/FIT scale modes and shader matrix
- Drop shadow and inner shadow effects
- Arc/donut rendering for ellipses with arcData
- Stroke cap/join/dash pattern support
- Image cache with cleanup on destroy

Export:
- Gradient/image fills round-trip through Kiwi
- New node types mapped to Figma equivalents

UI:
- Fill section shows gradient/image type labels for non-SOLID fills
2026-02-28 16:40:34 +03:00
Danila Poyarkov 803b69eee6 Split PagesPanel into separate component, inline page rename
- PagesPanel.vue: pages list with click to switch, double-click
  for inline rename (input field, Enter/Escape/blur commits)
- LayersPanel.vue: removed pages logic, composes PagesPanel
- Layer drag-drop uses currentPageId instead of rootId
2026-02-28 13:14:03 +03:00
Danila Poyarkov 1d79473bc6 Pages support: multi-page documents like Figma
Document structure: Document (root) → Pages (CANVAS) → Nodes.
Each page has its own viewport (pan/zoom) and background color.

- CANVAS node type for pages
- SceneGraph: addPage(), getPages(), getAbsolutePosition stops at CANVAS
- Store: currentPageId, switchPage(), addPage(), deletePage(), renamePage()
- All operations (create, select, paste, hit test, render) scoped to current page
- Per-page viewport state saved/restored on page switch
- Pages list in LayersPanel with add/switch/double-click rename
- .fig import creates proper pages from DOCUMENT→CANVAS hierarchy
- Renderer takes pageId to render correct page's children
- Unit test for pages, updated E2E tests for page-scoped graph
2026-02-28 13:12:27 +03:00
Danila Poyarkov ffd305c125 Page properties panel with canvas background color picker
When nothing is selected, the right panel shows Page section with
a color picker for the canvas background (like Figma). The page
color is stored in reactive state and passed to the renderer.
2026-02-28 11:42:13 +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 2af2a280c6 Appearance section: opacity + corner radius + visibility toggle
- Opacity with blend icon, corner radius with radius icon
- Eye/eye-off toggle in section header
- Layers panel: hidden layers dimmed (opacity-50) with permanent
  eye-off indicator
- Removed duplicate corner radius from LayoutSection
2026-02-28 09:20:31 +03:00
Danila Poyarkov babeecc76e Polish fill/stroke sections: editable hex, opacity %, eye toggle, minus
- Hex input is now editable (was read-only label)
- Per-fill/stroke opacity percentage input
- Eye/eye-off icon for visibility toggle (on hover)
- Minus button for removal (replaces ×)
- Stroke weight shown below stroke list
2026-02-28 09:06:04 +03:00
Danila Poyarkov 7b0f6c10f7 Fix text alignment icons: use direct template tags for auto-import 2026-02-28 09:01:54 +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
Danila Poyarkov bcd8bf6bca Add IconsResolver for auto-import, explicit imports only for dynamic maps 2026-02-28 08:29:39 +03:00