Commit graph

11 commits

Author SHA1 Message Date
Danila Poyarkov c06ed32990 Harden linting: add eqeqeq, prefer-const, radix, no-console, no-typeof-window-check
New built-in rules:
- eqeqeq (null-safe) — prevent loose equality coercions
- prefer-const — catch unused let declarations
- radix — require parseInt radix parameter
- no-console — warn on console.log in app code (CLI/MCP exempted)

New custom rule:
- no-typeof-window-check — flag raw typeof window checks, prefer
  IS_BROWSER/IS_TAURI constants (warn-level, constants.ts + fonts.ts
  exempted)

Fix 4 violations caught by new rules.
2026-03-16 13:54:07 +03:00
Danila Poyarkov e3ab8dab38 AI chat rendering, undo, visual verification, and provider compatibility
Rendering & layout:
- Fix COUNTER_ALIGN_MAP stretch mapping
- Direction-aware fill sizing based on parent flex direction
- Text without explicit width defaults to WIDTH_AND_HEIGHT auto-resize
- Padding auto-enables vertical auto-layout
- clipsContent propagated as Overflow.Hidden to Yoga
- Text height measurement for HEIGHT auto-resize mode
- Export x/y for absolute children, text w/h per textAutoResize
- Export STRETCH as fill on cross axis

Undo system:
- Undo for auto-layout and layer tree reorder
- Atomic undo for drag + reparent
- Page snapshot undo for AI tool operations
- mouseleave no longer terminates active drag

AI tools & vision:
- Add get_jsx, diff_jsx, and describe tools
- export_image returns image via toModelOutput
- Chunked uint8ArrayToBase64 (stack overflow fix)
- computeAllLayouts after AI tool execution
- onBeforeExecute/onAfterExecute receive ToolDef

Provider & UI:
- Add anthropic-compatible provider
- API type toggle for OpenAI-compatible
- Debug toolbar (dev only)
- Preserve chat on UI toggle
- Enhanced system prompt with JSX reference

Co-authored-by: Anton A S <eddclyde@yandex.ru>
2026-03-09 15:49:29 +03:00
Danila Poyarkov 9890b7c1a1 Enable Tailwind CSS class sorting in oxfmt
Sort classes using the same algorithm as prettier-plugin-tailwindcss,
configured for Tailwind v4 (reads src/app.css for theme).

Also sorts class strings inside twMerge() and tv() calls.

Eliminates 2 nested ternaries that conflicted with the formatter
(oxfmt strips parentheses that the lint rule requires).
2026-03-09 15:46:20 +03:00
Danila Poyarkov 7f5a388e2b Code review: svg-export/ folder, restore comments, cleanup
- Move svg-export-{defs,paths}.ts into svg-export/ folder
  (defs.ts, paths.ts, index.ts) instead of prefix-based split
- Remove duplicate getChildren lambda in fig-import.ts importPages
- Remove dead dashPattern local in kiwi-convert.ts nodeChangeToProps
- Restore useful explanatory comments in instance-overrides.ts
  (DSD propagation, direct vs cloned assignments, seed skipping)
- Rename applyEffectOverrides → applyShapeAndEffectOverrides
  (handles polygon props + shadow + blur, not just effects)
- Format src/ with oxfmt
2026-03-09 15:22:14 +03:00
Danila Poyarkov 5549a2f46f Auto-layout icons in layer tree, frame title draggable on canvas
Layer tree shows layout-specific icons for auto-layout frames:
vertical → rows-3, horizontal → columns-3, grid → grid-3x3.
Only applies to FRAME nodes — components/instances keep their
purple diamond icon.

Clicking a selected top-level frame's name label on the canvas
now starts a drag instead of deselecting (hitTestFrameTitle).

Fix toolbar disappearing — TOOLS was incorrectly moved into
import type by consistent-type-imports, erasing it from the
runtime bundle.
2026-03-09 12:36:01 +03:00
Danila Poyarkov 1631d48c40 Reduce cyclomatic complexity below 20 in all functions
Extract dispatch branches into focused helpers:

use-canvas-input.ts (5 functions, was 21–61):
- onMouseDown → handleSelectDown, startPanDrag, tryStartRotation,
  tryStartResize, handleTextEditClick, duplicateAndDrag
- onMouseMove → dragNodes, updatePan, updateRotation,
  extendTextSelection, updateDrawShape, updateMarquee
- onMouseUp → commitDrag, commitDrawing, reparentOutsideNodes
- applyResize → constrainToAspectRatio
- computeAutoLayoutIndicatorForFrame → computeIndicatorPosition

use-keyboard.ts (was 39):
- onEventFired → shouldPreventDefault + Set-based lookups

server.ts (was 34):
- handleRequest → Partial<Record> command dispatch map

LayerTree.vue (was 22):
- updateDropTarget → classifyDropZone, resolveInsertPosition

use-text-edit.ts (was 27):
- onKeyDown → handleDeletion, handleHorizontalArrow, metaKeyActions map
2026-03-09 11:24:56 +03:00
Danila Poyarkov 17faf4df93 Add strict lint rules to catch AI-generated slop at compile time
New rules:
- typescript/no-unnecessary-condition: catches redundant ?., ??, and
  always-true/false branches (22 violations fixed)
- typescript/consistent-return: mixed return/no-return in functions
- typescript/no-unnecessary-type-parameters: unused generic params
- typescript/prefer-for-of: use for-of instead of indexed loops
- unicorn/no-nested-ternary: forbid nested ternaries
- unicorn/consistent-existence-index-check: !== -1 over >= 0
- no-empty-function: no empty function bodies

Fixed all 32 violations: removed unnecessary optional chaining on
non-nullish values, tightened Record types to Partial<Record> where
index access can return undefined, replaced nested ternary with
lookup table, added exhaustive default cases.
2026-03-09 09:16:07 +03:00
Danila Poyarkov f96fffb83f Harden oxlint: consistent-type-imports, no-duplicates, no-misused-promises, prefer-optional-chain
Add 6 new lint rules: typescript/consistent-type-imports,
typescript/no-unnecessary-type-assertion, typescript/prefer-optional-chain,
typescript/no-misused-promises, import/no-duplicates, import/no-mutable-exports.
Ban @/types shim via no-restricted-imports.

Fix all violations: replace inline import() annotations with proper
type imports, merge duplicate module imports, add void to fire-and-forget
promises, convert && chains to optional chaining.
2026-03-09 09:05:04 +03:00
Danila Poyarkov 5cd7cc12b2 Fix double-click rename in layer tree and pages panel
Prevent reka-ui TreeItem from toggling expand/collapse on click —
expand is handled by the chevron button with @click.stop.

Match page rename input styling to layer tree: show file icon next
to the input, use the same compact border/padding classes.
2026-03-08 22:58:38 +03:00
Danila Poyarkov bc52095138 Add double-click to rename layers, extract useInlineRename composable
- New useInlineRename composable: shared editing state, commit logic,
  and keyboard handling for inline rename across panels
- LayerTree: double-click a layer name to rename inline
- PagesPanel: refactored to use useInlineRename, removing duplicate code

Closes #57
2026-03-06 09:50:35 +03:00
Anton Soldatov 168c25c189
feat: mobile layout, PWA support (#27) (#27)
- Mobile-responsive editor with bottom drawer, ribbon nav, HUD overlay
- Touch support: single-finger tools, two-finger pinch-zoom
- PWA: manifest, service worker, installability
- Extract LayerTree from LayersPanel, shared utils (colorToCSS, initials, toolIcons)
- Constants moved to src/constants.ts, clipboard state to editor store
- reka-ui Popover/DropdownMenu in MobileHud

Co-authored-by: Danila Poyarkov <dev@dannote.net>
2026-03-05 19:51:51 +03:00