Image, screenshot, mockup and motion editor for polish social media post.
- React 18 + TypeScript — UI
- Vite — dev server + build
- Konva (
react-konva) — canvas, drag/resize/transform, export - Zustand — in-memory editor state
Design tokens, layout CSS, and visual fidelity are imported verbatim from
src/styles/app.css
npm install
npm run dev # http://127.0.0.1:5173Other commands:
npm run typecheck
npm run build
npm run preview| Spec item | Where |
|---|---|
| Image import (file picker, drag-drop, ⌘V) | Uploads panel, App.tsx |
| Canvas size presets + custom W/H | CanvasSizePicker |
| Background: solid / gradient / image + blur | BackgroundPanel, Background.tsx |
| Device frame overlay (clips screenshot) | MockupPanel, ImageNode.tsx |
| Heading + body text, in-place edit (dbl-click) | HeaderPanel, TextNode.tsx |
| Shapes: rect, rounded-rect, ellipse, arrow, highlight, callout | AnnotationPanel, ShapeNode.tsx |
| Position / scale / rotate / opacity | PositionPanel + Konva Transformer |
| Element shadow + border (incl. corner radius) | ShadowPanel · BorderPanel |
| Watermark (free tier) | WatermarkPanel + composited in CanvasStage.tsx |
| Export PNG / JPG / WebP @ 2× (default) | ExportMenu · exporters.ts |
| Copy to clipboard | exporters.ts:copyCanvasToClipboard |
.laybel save / open |
exporters.ts · importers.ts |
| Social preview modal | SocialPreviewModal |
| Customize sidebar (hide tools) | CustomizeSidebarModal |
| Keyboard: ⌘E export, ⌘C copy, ⌫ delete, esc | App.tsx |
src/
├── App.tsx app shell + hotkeys + drag-drop
├── main.tsx React entry
├── components/
│ ├── TopBar.tsx logo, undo/redo, size picker, export, sign-in
│ ├── LeftRail.tsx 16 tool buttons + customize
│ ├── CanvasSizePicker.tsx platform-grouped size dropdown
│ ├── ExportMenu.tsx export formats + scale + save/open project
│ ├── SocialPreviewModal.tsx LinkedIn-style preview modal
│ ├── CustomizeSidebarModal.tsx hide/show rail tools
│ ├── canvas/
│ │ ├── CanvasStage.tsx Konva Stage + fit-zoom + transformer + paste
│ │ ├── Background.tsx solid / gradient / image+blur
│ │ ├── ImageNode.tsx screenshot + device frame + clip
│ │ ├── TextNode.tsx editable text (overlay textarea on dbl-click)
│ │ └── ShapeNode.tsx rect, ellipse, arrow, callout, highlight
│ ├── panels/ each rail tool's right-panel UI
│ └── icons/ all SVG icons from the design
├── store/editor.ts Zustand store (canvas, elements, selection, IO)
├── lib/
│ ├── constants.ts canvas sizes, device frames, fonts
│ ├── importers.ts image + .laybel project loading
│ └── exporters.ts PNG/JPG/WebP/clipboard/.laybel saving
├── types/index.ts LaybelElement / Project / Background types
└── styles/app.css full design CSS (copied from the design artifact)