@retouchjs/core 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/constants.ts","../src/event-emitter.ts","../src/state-machine.ts","../src/styles.ts","../src/ui/h.ts","../src/ui/drop-zone.ts","../src/ui/editor/adjust-tool.ts","../src/ui/editor/canvas-renderer.ts","../src/utils/math.ts","../src/ui/editor/crop-tool.ts","../src/ui/editor/properties-panel.ts","../src/ui/editor/toolbar.ts","../src/ui/editor/editor.ts","../src/ui/gallery.ts","../src/utils/image.ts","../src/retouch.ts"],"names":[],"mappings":"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;AAAA,EAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA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","file":"index.cjs","sourcesContent":["import type { Adjustments, CropRect, ImageEdits } from \"./types\";\n\nexport const VERSION = \"0.0.1\";\n\nexport const ACCEPTED_TYPES = [\"image/jpeg\", \"image/png\", \"image/webp\"];\n\nexport const DEFAULT_CROP: CropRect = { x: 0, y: 0, width: 1, height: 1 };\n\nexport const DEFAULT_ADJUSTMENTS: Adjustments = {\n brightness: 100,\n contrast: 100,\n saturation: 100,\n};\n\nexport const DEFAULT_EDITS: ImageEdits = {\n crop: { ...DEFAULT_CROP },\n rotation: 0,\n adjustments: { ...DEFAULT_ADJUSTMENTS },\n};\n\nexport const ASPECT_RATIOS: Record<string, number | null> = {\n free: null,\n \"16:9\": 16 / 9,\n \"4:3\": 4 / 3,\n \"1:1\": 1,\n \"3:2\": 3 / 2,\n \"9:16\": 9 / 16,\n};\n","// biome-ignore lint/suspicious/noExplicitAny: internal event data variance\nexport class EventEmitter<T extends Record<string, any>> {\n private listeners = new Map<keyof T, Set<(data: never) => void>>();\n\n on<K extends keyof T>(event: K, fn: (data: T[K]) => void): () => void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n const set = this.listeners.get(event);\n if (set) {\n set.add(fn as (data: never) => void);\n }\n return () => this.listeners.get(event)?.delete(fn as (data: never) => void);\n }\n\n off<K extends keyof T>(event: K, fn: (data: T[K]) => void): void {\n this.listeners.get(event)?.delete(fn as (data: never) => void);\n }\n\n emit<K extends keyof T>(event: K, data: T[K]): void {\n for (const fn of this.listeners.get(event) ?? []) {\n (fn as (data: T[K]) => void)(data);\n }\n }\n\n removeAll(): void {\n this.listeners.clear();\n }\n}\n","import { EventEmitter } from \"./event-emitter\";\n\nexport interface StateChangeEvent<S extends string> {\n from: S;\n to: S;\n}\n\nexport class StateMachine<S extends string> {\n private current: S;\n private readonly transitions: Record<S, S[]>;\n private readonly emitter = new EventEmitter<{ change: StateChangeEvent<S> }>();\n\n constructor(initial: S, transitions: Record<S, S[]>) {\n this.current = initial;\n this.transitions = transitions;\n }\n\n get state(): S {\n return this.current;\n }\n\n canTransition(to: S): boolean {\n return (this.transitions[this.current] ?? []).includes(to);\n }\n\n transition(to: S): void {\n if (!this.canTransition(to)) {\n throw new Error(`[Retouch] Invalid state transition: ${this.current} → ${to}`);\n }\n const from = this.current;\n this.current = to;\n this.emitter.emit(\"change\", { from, to });\n }\n\n onChange(fn: (data: StateChangeEvent<S>) => void): () => void {\n return this.emitter.on(\"change\", fn);\n }\n\n destroy(): void {\n this.emitter.removeAll();\n }\n}\n","const STYLE_ID = \"rt-styles\";\n\nconst CSS = /* css */ `\n.rt-root {\n --rt-bg: #F7F5F2;\n --rt-bg-elevated: #FFFFFF;\n --rt-bg-subtle: #EEEAE5;\n --rt-border: #DDD8D0;\n --rt-border-strong: #C5BFB5;\n --rt-text: #1A1815;\n --rt-text-secondary: #6B6560;\n --rt-text-tertiary: #9E9890;\n --rt-accent: #D4572A;\n --rt-accent-hover: #BF4D24;\n --rt-accent-soft: rgba(212, 87, 42, 0.08);\n --rt-accent-glow: rgba(212, 87, 42, 0.15);\n --rt-shadow-sm: 0 1px 3px rgba(26,24,21,0.06);\n --rt-shadow-md: 0 4px 16px rgba(26,24,21,0.08);\n --rt-shadow-lg: 0 12px 48px rgba(26,24,21,0.12);\n --rt-radius-sm: 6px;\n --rt-radius-md: 10px;\n --rt-radius-lg: 16px;\n --rt-radius-xl: 24px;\n --rt-transition: 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n\n font-family: system-ui, -apple-system, 'Segoe UI', sans-serif;\n color: var(--rt-text);\n line-height: 1.5;\n -webkit-font-smoothing: antialiased;\n position: relative;\n width: 100%;\n}\n\n.rt-root *, .rt-root *::before, .rt-root *::after {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n}\n\n/* ── Drop Zone ─────────────────────────────── */\n\n.rt-dropzone-wrapper {\n background: var(--rt-bg-elevated);\n border-radius: var(--rt-radius-xl);\n padding: 48px;\n box-shadow: var(--rt-shadow-md);\n}\n\n.rt-dropzone {\n border: 2px dashed var(--rt-border-strong);\n border-radius: var(--rt-radius-lg);\n padding: 80px 40px;\n text-align: center;\n cursor: pointer;\n transition: var(--rt-transition);\n position: relative;\n overflow: hidden;\n}\n\n.rt-dropzone::before {\n content: '';\n position: absolute;\n inset: 0;\n background: var(--rt-accent-soft);\n opacity: 0;\n transition: var(--rt-transition);\n}\n\n.rt-dropzone:hover {\n border-color: var(--rt-accent);\n}\n\n.rt-dropzone:hover::before {\n opacity: 1;\n}\n\n.rt-dropzone--active {\n border-color: var(--rt-accent);\n border-style: solid;\n background: var(--rt-accent-soft);\n}\n\n.rt-dropzone--active .rt-dropzone__icon {\n background: var(--rt-accent);\n transform: scale(1.1);\n}\n\n.rt-dropzone--active .rt-dropzone__icon svg {\n color: white;\n}\n\n.rt-dropzone__icon {\n width: 56px;\n height: 56px;\n border-radius: 50%;\n background: var(--rt-bg-subtle);\n display: flex;\n align-items: center;\n justify-content: center;\n margin: 0 auto 20px;\n transition: var(--rt-transition);\n}\n\n.rt-dropzone:hover .rt-dropzone__icon {\n background: var(--rt-accent-glow);\n transform: scale(1.05);\n}\n\n.rt-dropzone__icon svg {\n width: 24px;\n height: 24px;\n color: var(--rt-text-secondary);\n transition: var(--rt-transition);\n}\n\n.rt-dropzone:hover .rt-dropzone__icon svg {\n color: var(--rt-accent);\n}\n\n.rt-dropzone__text {\n font-size: 16px;\n color: var(--rt-text-secondary);\n margin-bottom: 4px;\n position: relative;\n}\n\n.rt-dropzone__text strong {\n color: var(--rt-accent);\n font-weight: 500;\n}\n\n.rt-dropzone__hint {\n font-size: 13px;\n color: var(--rt-text-tertiary);\n position: relative;\n}\n\n/* ── Gallery ───────────────────────────────── */\n\n.rt-gallery {\n background: var(--rt-bg-elevated);\n border-radius: var(--rt-radius-xl);\n padding: 32px;\n box-shadow: var(--rt-shadow-md);\n}\n\n.rt-gallery__toolbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 24px;\n padding-bottom: 20px;\n border-bottom: 1px solid var(--rt-border);\n}\n\n.rt-gallery__count {\n font-size: 14px;\n color: var(--rt-text-secondary);\n}\n\n.rt-gallery__count strong {\n color: var(--rt-text);\n font-weight: 600;\n}\n\n.rt-gallery__actions {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.rt-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border: 1px solid var(--rt-border);\n border-radius: var(--rt-radius-sm);\n background: var(--rt-bg-elevated);\n font-size: 13px;\n font-weight: 500;\n color: var(--rt-text-secondary);\n cursor: pointer;\n transition: var(--rt-transition);\n font-family: inherit;\n line-height: 1;\n}\n\n.rt-btn:hover {\n border-color: var(--rt-border-strong);\n color: var(--rt-text);\n}\n\n.rt-btn svg {\n width: 14px;\n height: 14px;\n}\n\n.rt-btn--accent {\n background: var(--rt-accent);\n border-color: var(--rt-accent);\n color: white;\n}\n\n.rt-btn--accent:hover {\n background: var(--rt-accent-hover);\n border-color: var(--rt-accent-hover);\n color: white;\n}\n\n.rt-gallery__grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));\n gap: 16px;\n}\n\n.rt-gallery__item {\n position: relative;\n aspect-ratio: 1;\n border-radius: var(--rt-radius-md);\n overflow: hidden;\n cursor: pointer;\n}\n\n.rt-gallery__item img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.rt-gallery__item:hover img {\n transform: scale(1.04);\n}\n\n.rt-gallery__item-overlay {\n position: absolute;\n inset: 0;\n background: linear-gradient(to top, rgba(26,24,21,0.7) 0%, transparent 50%);\n opacity: 0;\n transition: var(--rt-transition);\n display: flex;\n align-items: flex-end;\n padding: 12px;\n}\n\n.rt-gallery__item:hover .rt-gallery__item-overlay {\n opacity: 1;\n}\n\n.rt-gallery__item-info {\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n}\n\n.rt-gallery__item-name {\n font-size: 12px;\n color: rgba(255,255,255,0.85);\n font-weight: 500;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 55%;\n}\n\n.rt-gallery__item-edit {\n display: flex;\n align-items: center;\n gap: 5px;\n padding: 6px 12px;\n background: var(--rt-accent);\n color: white;\n border: none;\n border-radius: var(--rt-radius-sm);\n font-size: 11px;\n font-weight: 600;\n letter-spacing: 0.3px;\n cursor: pointer;\n transition: var(--rt-transition);\n font-family: inherit;\n text-transform: uppercase;\n}\n\n.rt-gallery__item-edit:hover {\n background: var(--rt-accent-hover);\n transform: translateY(-1px);\n}\n\n.rt-gallery__item-edit svg {\n width: 12px;\n height: 12px;\n}\n\n.rt-gallery__item-status {\n position: absolute;\n top: 8px;\n right: 8px;\n width: 8px;\n height: 8px;\n border-radius: 50%;\n border: 2px solid var(--rt-bg-elevated);\n}\n\n.rt-gallery__item-status--edited {\n background: #22C55E;\n}\n\n.rt-gallery__item-status--pending {\n background: var(--rt-text-tertiary);\n}\n\n.rt-gallery__item-remove {\n position: absolute;\n top: 8px;\n left: 8px;\n width: 24px;\n height: 24px;\n border-radius: 50%;\n background: rgba(0,0,0,0.5);\n border: none;\n color: white;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n transition: var(--rt-transition);\n backdrop-filter: blur(4px);\n}\n\n.rt-gallery__item:hover .rt-gallery__item-remove {\n opacity: 1;\n}\n\n.rt-gallery__item-remove:hover {\n background: rgba(220, 50, 50, 0.8);\n}\n\n.rt-gallery__item-remove svg {\n width: 12px;\n height: 12px;\n}\n\n.rt-gallery__footer {\n display: flex;\n justify-content: flex-end;\n margin-top: 24px;\n padding-top: 20px;\n border-top: 1px solid var(--rt-border);\n}\n\n/* ── Editor ────────────────────────────────── */\n\n.rt-editor-overlay {\n position: fixed;\n inset: 0;\n z-index: 9999;\n background: #1A1815;\n display: flex;\n flex-direction: column;\n}\n\n.rt-editor__topbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 20px;\n background: #222019;\n border-bottom: 1px solid rgba(255,255,255,0.06);\n flex-shrink: 0;\n}\n\n.rt-editor__topbar-left {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.rt-editor__filename {\n font-size: 13px;\n color: rgba(255,255,255,0.6);\n font-weight: 400;\n}\n\n.rt-editor__dimensions {\n font-size: 11px;\n color: rgba(255,255,255,0.3);\n padding: 3px 8px;\n background: rgba(255,255,255,0.06);\n border-radius: 4px;\n}\n\n.rt-editor__topbar-right {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.rt-editor__btn-cancel {\n padding: 7px 16px;\n border: 1px solid rgba(255,255,255,0.12);\n border-radius: var(--rt-radius-sm);\n background: transparent;\n color: rgba(255,255,255,0.6);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--rt-transition);\n font-family: inherit;\n}\n\n.rt-editor__btn-cancel:hover {\n border-color: rgba(255,255,255,0.25);\n color: rgba(255,255,255,0.85);\n}\n\n.rt-editor__btn-done {\n padding: 7px 20px;\n border: none;\n border-radius: var(--rt-radius-sm);\n background: var(--rt-accent);\n color: white;\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n transition: var(--rt-transition);\n font-family: inherit;\n}\n\n.rt-editor__btn-done:hover {\n background: var(--rt-accent-hover);\n}\n\n.rt-editor__body {\n display: flex;\n flex: 1;\n min-height: 0;\n}\n\n/* ── Toolbar (left sidebar) ────────────────── */\n\n.rt-toolbar {\n width: 64px;\n background: #1E1C18;\n border-right: 1px solid rgba(255,255,255,0.06);\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 16px 0;\n gap: 4px;\n flex-shrink: 0;\n}\n\n.rt-toolbar__btn {\n width: 44px;\n height: 44px;\n border: none;\n background: transparent;\n border-radius: var(--rt-radius-sm);\n color: rgba(255,255,255,0.4);\n cursor: pointer;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 3px;\n transition: var(--rt-transition);\n position: relative;\n}\n\n.rt-toolbar__btn:hover {\n background: rgba(255,255,255,0.06);\n color: rgba(255,255,255,0.7);\n}\n\n.rt-toolbar__btn--active {\n background: rgba(212, 87, 42, 0.15);\n color: var(--rt-accent);\n}\n\n.rt-toolbar__btn--active::before {\n content: '';\n position: absolute;\n left: 0;\n top: 50%;\n transform: translateY(-50%);\n width: 3px;\n height: 20px;\n background: var(--rt-accent);\n border-radius: 0 2px 2px 0;\n}\n\n.rt-toolbar__btn svg {\n width: 20px;\n height: 20px;\n}\n\n.rt-toolbar__btn span {\n font-size: 9px;\n font-weight: 500;\n letter-spacing: 0.3px;\n}\n\n/* ── Canvas area ───────────────────────────── */\n\n.rt-editor__canvas-area {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n overflow: hidden;\n background:\n repeating-conic-gradient(\n rgba(255,255,255,0.03) 0% 25%,\n transparent 0% 50%\n )\n 0 0 / 24px 24px;\n}\n\n.rt-editor__canvas-container {\n position: relative;\n max-width: 90%;\n max-height: 90%;\n}\n\n.rt-editor__canvas-container canvas {\n display: block;\n border-radius: var(--rt-radius-sm);\n box-shadow: 0 8px 40px rgba(0,0,0,0.3);\n}\n\n/* ── Crop overlay ──────────────────────────── */\n\n.rt-crop {\n position: absolute;\n inset: 0;\n pointer-events: none;\n}\n\n.rt-crop__mask {\n position: absolute;\n background: rgba(0,0,0,0.45);\n pointer-events: none;\n}\n\n.rt-crop__selection {\n position: absolute;\n border: 2px solid white;\n pointer-events: auto;\n cursor: move;\n}\n\n.rt-crop__grid {\n position: absolute;\n inset: 0;\n display: grid;\n grid-template-columns: 1fr 1fr 1fr;\n grid-template-rows: 1fr 1fr 1fr;\n pointer-events: none;\n}\n\n.rt-crop__grid-cell {\n border-right: 1px solid rgba(255,255,255,0.2);\n border-bottom: 1px solid rgba(255,255,255,0.2);\n}\n\n.rt-crop__grid-cell:nth-child(3n) { border-right: none; }\n.rt-crop__grid-cell:nth-child(n+7) { border-bottom: none; }\n\n.rt-crop__handle {\n position: absolute;\n width: 12px;\n height: 12px;\n background: white;\n border-radius: 2px;\n box-shadow: 0 1px 4px rgba(0,0,0,0.3);\n pointer-events: auto;\n}\n\n.rt-crop__handle--nw { top: -6px; left: -6px; cursor: nw-resize; }\n.rt-crop__handle--ne { top: -6px; right: -6px; cursor: ne-resize; }\n.rt-crop__handle--sw { bottom: -6px; left: -6px; cursor: sw-resize; }\n.rt-crop__handle--se { bottom: -6px; right: -6px; cursor: se-resize; }\n.rt-crop__handle--n { top: -6px; left: 50%; transform: translateX(-50%); cursor: n-resize; }\n.rt-crop__handle--s { bottom: -6px; left: 50%; transform: translateX(-50%); cursor: s-resize; }\n.rt-crop__handle--w { top: 50%; left: -6px; transform: translateY(-50%); cursor: w-resize; }\n.rt-crop__handle--e { top: 50%; right: -6px; transform: translateY(-50%); cursor: e-resize; }\n\n/* ── Properties panel (right) ──────────────── */\n\n.rt-props {\n width: 260px;\n background: #1E1C18;\n border-left: 1px solid rgba(255,255,255,0.06);\n padding: 20px 16px;\n overflow-y: auto;\n flex-shrink: 0;\n}\n\n.rt-props__title {\n font-size: 11px;\n font-weight: 600;\n letter-spacing: 1.5px;\n text-transform: uppercase;\n color: rgba(255,255,255,0.35);\n margin-bottom: 16px;\n}\n\n.rt-props__row {\n margin-bottom: 16px;\n}\n\n.rt-props__label {\n font-size: 12px;\n color: rgba(255,255,255,0.5);\n margin-bottom: 6px;\n}\n\n.rt-props__slider {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.rt-props__slider input[type=\"range\"] {\n flex: 1;\n height: 4px;\n -webkit-appearance: none;\n appearance: none;\n background: rgba(255,255,255,0.1);\n border-radius: 2px;\n outline: none;\n}\n\n.rt-props__slider input[type=\"range\"]::-webkit-slider-thumb {\n -webkit-appearance: none;\n width: 14px;\n height: 14px;\n background: white;\n border-radius: 50%;\n box-shadow: 0 1px 4px rgba(0,0,0,0.3);\n cursor: pointer;\n}\n\n.rt-props__slider-value {\n font-size: 12px;\n color: rgba(255,255,255,0.5);\n width: 36px;\n text-align: right;\n font-variant-numeric: tabular-nums;\n}\n\n.rt-props__aspect-grid {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 6px;\n}\n\n.rt-props__aspect-btn {\n padding: 8px 4px;\n border: 1px solid rgba(255,255,255,0.1);\n border-radius: var(--rt-radius-sm);\n background: transparent;\n color: rgba(255,255,255,0.5);\n font-size: 11px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--rt-transition);\n text-align: center;\n font-family: inherit;\n}\n\n.rt-props__aspect-btn:hover {\n border-color: rgba(255,255,255,0.2);\n color: rgba(255,255,255,0.8);\n}\n\n.rt-props__aspect-btn--active {\n border-color: var(--rt-accent);\n background: rgba(212, 87, 42, 0.12);\n color: var(--rt-accent);\n}\n\n.rt-props__divider {\n height: 1px;\n background: rgba(255,255,255,0.06);\n margin: 20px 0;\n}\n`;\n\nlet injected = false;\n\nexport function injectStyles(): void {\n if (injected || document.getElementById(STYLE_ID)) {\n injected = true;\n return;\n }\n const style = document.createElement(\"style\");\n style.id = STYLE_ID;\n style.textContent = CSS;\n document.head.appendChild(style);\n injected = true;\n}\n","type Attrs = Record<string, string | number | boolean | EventListener>;\ntype Child = Node | string;\n\nexport function h<K extends keyof HTMLElementTagNameMap>(\n tag: K,\n attrs?: Attrs | null,\n ...children: Child[]\n): HTMLElementTagNameMap[K] {\n const el = document.createElement(tag);\n\n if (attrs) {\n for (const [key, value] of Object.entries(attrs)) {\n if (key.startsWith(\"on\") && typeof value === \"function\") {\n el.addEventListener(key.slice(2).toLowerCase(), value as EventListener);\n } else if (typeof value === \"boolean\") {\n if (value) el.setAttribute(key, \"\");\n } else {\n el.setAttribute(key, String(value));\n }\n }\n }\n\n for (const child of children) {\n el.appendChild(typeof child === \"string\" ? document.createTextNode(child) : child);\n }\n\n return el;\n}\n","import type { ViewHandle } from \"../types\";\nimport { h } from \"./h\";\n\nexport interface DropZoneOptions {\n onFiles: (files: File[]) => void;\n}\n\nexport function createDropZone(options: DropZoneOptions): ViewHandle {\n const input = h(\"input\", {\n type: \"file\",\n accept: \"image/*\",\n multiple: true,\n style: \"display:none\",\n }) as HTMLInputElement;\n\n const zone = h(\n \"div\",\n { class: \"rt-dropzone\" },\n h(\"div\", { class: \"rt-dropzone__icon\" }, createUploadIcon()),\n h(\"div\", { class: \"rt-dropzone__text\" }, \"Drop images here or \", h(\"strong\", null, \"browse\")),\n h(\"div\", { class: \"rt-dropzone__hint\" }, \"PNG, JPG, WebP\"),\n input,\n );\n\n const root = h(\"div\", { class: \"rt-dropzone-wrapper\" }, zone);\n\n const abort = new AbortController();\n const signal = abort.signal;\n\n // Click to browse\n zone.addEventListener(\"click\", () => input.click(), { signal });\n\n // File input change\n input.addEventListener(\n \"change\",\n () => {\n if (input.files && input.files.length > 0) {\n options.onFiles(Array.from(input.files));\n input.value = \"\";\n }\n },\n { signal },\n );\n\n // Drag & drop\n let dragCounter = 0;\n\n zone.addEventListener(\n \"dragenter\",\n (e) => {\n e.preventDefault();\n dragCounter++;\n zone.classList.add(\"rt-dropzone--active\");\n },\n { signal },\n );\n\n zone.addEventListener(\n \"dragover\",\n (e) => {\n e.preventDefault();\n },\n { signal },\n );\n\n zone.addEventListener(\n \"dragleave\",\n (e) => {\n e.preventDefault();\n dragCounter--;\n if (dragCounter <= 0) {\n dragCounter = 0;\n zone.classList.remove(\"rt-dropzone--active\");\n }\n },\n { signal },\n );\n\n zone.addEventListener(\n \"drop\",\n (e) => {\n e.preventDefault();\n dragCounter = 0;\n zone.classList.remove(\"rt-dropzone--active\");\n if (e.dataTransfer?.files && e.dataTransfer.files.length > 0) {\n options.onFiles(Array.from(e.dataTransfer.files));\n }\n },\n { signal },\n );\n\n return {\n root,\n destroy() {\n abort.abort();\n root.remove();\n },\n };\n}\n\nfunction createUploadIcon(): SVGElement {\n const svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\n svg.setAttribute(\"viewBox\", \"0 0 24 24\");\n svg.setAttribute(\"fill\", \"none\");\n svg.setAttribute(\"stroke\", \"currentColor\");\n svg.setAttribute(\"stroke-width\", \"1.5\");\n\n const p1 = document.createElementNS(\"http://www.w3.org/2000/svg\", \"path\");\n p1.setAttribute(\"d\", \"M4 14.899A7 7 0 1115.71 8h1.79a4.5 4.5 0 012.5 8.242\");\n\n const p2 = document.createElementNS(\"http://www.w3.org/2000/svg\", \"path\");\n p2.setAttribute(\"d\", \"M12 12v9m0-9l-3 3m3-3 3 3\");\n\n svg.appendChild(p1);\n svg.appendChild(p2);\n return svg;\n}\n","import type { Adjustments } from \"../../types\";\nimport { h } from \"../h\";\n\nexport interface AdjustToolOptions {\n adjustments: Adjustments;\n onChange: (adjustments: Adjustments) => void;\n}\n\nexport interface AdjustToolHandle {\n root: HTMLElement;\n getAdjustments(): Adjustments;\n destroy(): void;\n}\n\nexport function createAdjustTool(options: AdjustToolOptions): AdjustToolHandle {\n const adj: Adjustments = { ...options.adjustments };\n const abort = new AbortController();\n const signal = abort.signal;\n\n function createSlider(\n label: string,\n key: keyof Adjustments,\n min: number,\n max: number,\n ): HTMLElement {\n const valueEl = h(\"span\", { class: \"rt-props__slider-value\" }, formatValue(adj[key], key));\n const input = h(\"input\", {\n type: \"range\",\n min,\n max,\n step: 1,\n value: adj[key],\n }) as HTMLInputElement;\n\n input.addEventListener(\n \"input\",\n () => {\n adj[key] = Number(input.value);\n valueEl.textContent = formatValue(adj[key], key);\n options.onChange({ ...adj });\n },\n { signal },\n );\n\n return h(\n \"div\",\n { class: \"rt-props__row\" },\n h(\"div\", { class: \"rt-props__label\" }, label),\n h(\"div\", { class: \"rt-props__slider\" }, input, valueEl),\n );\n }\n\n const root = h(\n \"div\",\n null,\n h(\"div\", { class: \"rt-props__title\" }, \"Adjustments\"),\n createSlider(\"Brightness\", \"brightness\", 0, 200),\n createSlider(\"Contrast\", \"contrast\", 0, 200),\n createSlider(\"Saturation\", \"saturation\", 0, 200),\n );\n\n return {\n root,\n getAdjustments: () => ({ ...adj }),\n destroy() {\n abort.abort();\n },\n };\n}\n\nfunction formatValue(value: number, _key: keyof Adjustments): string {\n const diff = value - 100;\n if (diff === 0) return \"0\";\n return diff > 0 ? `+${diff}` : `${diff}`;\n}\n","import type { Adjustments, ImageEdits } from \"../../types\";\n\nexport interface ImageRect {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nexport class CanvasRenderer {\n private readonly canvas: HTMLCanvasElement;\n private readonly ctx: CanvasRenderingContext2D;\n private readonly container: HTMLElement;\n private readonly image: HTMLImageElement;\n private adjustments: Adjustments;\n private rotation = 0;\n private imageRect: ImageRect = { x: 0, y: 0, width: 0, height: 0 };\n\n constructor(container: HTMLElement, image: HTMLImageElement, edits: ImageEdits) {\n this.container = container;\n this.image = image;\n this.adjustments = { ...edits.adjustments };\n this.rotation = edits.rotation;\n\n this.canvas = document.createElement(\"canvas\");\n this.canvas.style.display = \"block\";\n this.container.appendChild(this.canvas);\n\n const ctx = this.canvas.getContext(\"2d\");\n if (!ctx) throw new Error(\"[Retouch] Failed to get 2D context\");\n this.ctx = ctx;\n }\n\n setAdjustments(adj: Adjustments): void {\n this.adjustments = { ...adj };\n }\n\n setRotation(deg: number): void {\n this.rotation = deg;\n }\n\n getImageRect(): ImageRect {\n return { ...this.imageRect };\n }\n\n getCanvasElement(): HTMLCanvasElement {\n return this.canvas;\n }\n\n render(): void {\n const containerWidth = this.container.clientWidth || 800;\n const containerHeight = this.container.clientHeight || 600;\n\n const imgW = this.image.naturalWidth;\n const imgH = this.image.naturalHeight;\n if (imgW === 0 || imgH === 0) return;\n\n // Fit image to container\n const scale = Math.min((containerWidth * 0.9) / imgW, (containerHeight * 0.9) / imgH, 1);\n\n const drawW = Math.round(imgW * scale);\n const drawH = Math.round(imgH * scale);\n\n // Size canvas to the image display size\n this.canvas.width = drawW;\n this.canvas.height = drawH;\n this.canvas.style.width = `${drawW}px`;\n this.canvas.style.height = `${drawH}px`;\n\n this.imageRect = { x: 0, y: 0, width: drawW, height: drawH };\n\n const ctx = this.ctx;\n ctx.clearRect(0, 0, drawW, drawH);\n\n // Apply adjustments\n const { brightness, contrast, saturation } = this.adjustments;\n ctx.filter = `brightness(${brightness / 100}) contrast(${contrast / 100}) saturate(${saturation / 100})`;\n\n // Apply rotation\n if (this.rotation !== 0) {\n const radians = (this.rotation * Math.PI) / 180;\n ctx.save();\n ctx.translate(drawW / 2, drawH / 2);\n ctx.rotate(radians);\n ctx.drawImage(this.image, -drawW / 2, -drawH / 2, drawW, drawH);\n ctx.restore();\n } else {\n ctx.drawImage(this.image, 0, 0, drawW, drawH);\n }\n\n ctx.filter = \"none\";\n }\n\n /** Convert screen coordinates (relative to canvas) to normalized image coords (0–1). */\n screenToImage(sx: number, sy: number): { x: number; y: number } {\n const r = this.imageRect;\n return {\n x: r.width > 0 ? (sx - r.x) / r.width : 0,\n y: r.height > 0 ? (sy - r.y) / r.height : 0,\n };\n }\n\n /** Convert normalized image coords (0–1) to screen coordinates relative to canvas. */\n imageToScreen(ix: number, iy: number): { x: number; y: number } {\n const r = this.imageRect;\n return {\n x: r.x + ix * r.width,\n y: r.y + iy * r.height,\n };\n }\n\n destroy(): void {\n this.canvas.remove();\n }\n}\n","export function clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\nexport function constrainToAspectRatio(\n width: number,\n height: number,\n ratio: number,\n anchor: \"width\" | \"height\" = \"width\",\n): { width: number; height: number } {\n if (anchor === \"width\") {\n return { width, height: width / ratio };\n }\n return { width: height * ratio, height };\n}\n","import { ASPECT_RATIOS } from \"../../constants\";\nimport type { AspectRatioPreset, CropRect } from \"../../types\";\nimport { clamp } from \"../../utils/math\";\nimport type { CanvasRenderer } from \"./canvas-renderer\";\n\nexport interface CropToolOptions {\n container: HTMLElement;\n renderer: CanvasRenderer;\n edits: { crop: CropRect };\n onChange: (crop: CropRect) => void;\n}\n\nexport interface CropToolHandle {\n root: HTMLElement;\n getCrop(): CropRect;\n setAspectRatio(preset: AspectRatioPreset): void;\n getAspectRatio(): AspectRatioPreset;\n setVisible(visible: boolean): void;\n destroy(): void;\n}\n\ntype HandlePosition = \"nw\" | \"ne\" | \"sw\" | \"se\" | \"n\" | \"s\" | \"w\" | \"e\";\n\nconst MIN_SIZE = 0.05; // Minimum crop size in normalized coords\n\nexport function createCropTool(options: CropToolOptions): CropToolHandle {\n const { container, renderer, onChange } = options;\n const crop: CropRect = { ...options.edits.crop };\n let aspectRatio: AspectRatioPreset = \"free\";\n const abort = new AbortController();\n const signal = abort.signal;\n\n // Root overlay\n const root = document.createElement(\"div\");\n root.className = \"rt-crop\";\n\n // 4 mask regions\n const maskTop = createMask();\n const maskRight = createMask();\n const maskBottom = createMask();\n const maskLeft = createMask();\n\n // Selection box\n const selection = document.createElement(\"div\");\n selection.className = \"rt-crop__selection\";\n\n // Rule of thirds grid\n const grid = document.createElement(\"div\");\n grid.className = \"rt-crop__grid\";\n for (let i = 0; i < 9; i++) {\n const cell = document.createElement(\"div\");\n cell.className = \"rt-crop__grid-cell\";\n grid.appendChild(cell);\n }\n selection.appendChild(grid);\n\n // 8 handles\n const handles: Record<HandlePosition, HTMLElement> = {} as Record<HandlePosition, HTMLElement>;\n for (const pos of [\"nw\", \"ne\", \"sw\", \"se\", \"n\", \"s\", \"w\", \"e\"] as HandlePosition[]) {\n const handle = document.createElement(\"div\");\n handle.className = `rt-crop__handle rt-crop__handle--${pos}`;\n handle.dataset.handle = pos;\n selection.appendChild(handle);\n handles[pos] = handle;\n }\n\n root.appendChild(maskTop);\n root.appendChild(maskRight);\n root.appendChild(maskBottom);\n root.appendChild(maskLeft);\n root.appendChild(selection);\n container.appendChild(root);\n\n // ── Layout ──\n\n function updateLayout(): void {\n const imgRect = renderer.getImageRect();\n\n // Crop selection position in pixels (relative to container)\n const sx = imgRect.x + crop.x * imgRect.width;\n const sy = imgRect.y + crop.y * imgRect.height;\n const sw = crop.width * imgRect.width;\n const sh = crop.height * imgRect.height;\n\n // Selection\n selection.style.left = `${sx}px`;\n selection.style.top = `${sy}px`;\n selection.style.width = `${sw}px`;\n selection.style.height = `${sh}px`;\n\n // Container dimensions\n const cw = container.clientWidth || imgRect.width;\n const ch = container.clientHeight || imgRect.height;\n\n // Masks\n maskTop.style.left = \"0\";\n maskTop.style.top = \"0\";\n maskTop.style.width = `${cw}px`;\n maskTop.style.height = `${sy}px`;\n\n maskBottom.style.left = \"0\";\n maskBottom.style.top = `${sy + sh}px`;\n maskBottom.style.width = `${cw}px`;\n maskBottom.style.height = `${ch - sy - sh}px`;\n\n maskLeft.style.left = \"0\";\n maskLeft.style.top = `${sy}px`;\n maskLeft.style.width = `${sx}px`;\n maskLeft.style.height = `${sh}px`;\n\n maskRight.style.left = `${sx + sw}px`;\n maskRight.style.top = `${sy}px`;\n maskRight.style.width = `${cw - sx - sw}px`;\n maskRight.style.height = `${sh}px`;\n }\n\n // ── Drag interaction ──\n\n let dragging: {\n type: \"move\" | HandlePosition;\n startX: number;\n startY: number;\n startCrop: CropRect;\n } | null = null;\n\n selection.addEventListener(\n \"pointerdown\",\n (e) => {\n if ((e.target as HTMLElement).dataset.handle) return;\n e.preventDefault();\n dragging = { type: \"move\", startX: e.clientX, startY: e.clientY, startCrop: { ...crop } };\n },\n { signal },\n );\n\n for (const [pos, handle] of Object.entries(handles)) {\n handle.addEventListener(\n \"pointerdown\",\n (e) => {\n e.preventDefault();\n e.stopPropagation();\n dragging = {\n type: pos as HandlePosition,\n startX: e.clientX,\n startY: e.clientY,\n startCrop: { ...crop },\n };\n },\n { signal },\n );\n }\n\n document.addEventListener(\n \"pointermove\",\n (e) => {\n if (!dragging) return;\n e.preventDefault();\n\n const imgRect = renderer.getImageRect();\n if (imgRect.width === 0 || imgRect.height === 0) return;\n\n const dx = (e.clientX - dragging.startX) / imgRect.width;\n const dy = (e.clientY - dragging.startY) / imgRect.height;\n const sc = dragging.startCrop;\n\n if (dragging.type === \"move\") {\n crop.x = clamp(sc.x + dx, 0, 1 - sc.width);\n crop.y = clamp(sc.y + dy, 0, 1 - sc.height);\n } else {\n handleResize(dragging.type, sc, dx, dy);\n }\n\n updateLayout();\n onChange(crop);\n },\n { signal },\n );\n\n document.addEventListener(\n \"pointerup\",\n () => {\n dragging = null;\n },\n { signal },\n );\n\n function handleResize(pos: HandlePosition, sc: CropRect, dx: number, dy: number): void {\n const ratio = ASPECT_RATIOS[aspectRatio];\n let newX = sc.x;\n let newY = sc.y;\n let newW = sc.width;\n let newH = sc.height;\n\n // Horizontal edges\n if (pos.includes(\"w\")) {\n const maxDx = sc.width - MIN_SIZE;\n const clampedDx = clamp(dx, -sc.x, maxDx);\n newX = sc.x + clampedDx;\n newW = sc.width - clampedDx;\n }\n if (pos.includes(\"e\")) {\n newW = clamp(sc.width + dx, MIN_SIZE, 1 - sc.x);\n }\n\n // Vertical edges\n if (pos.includes(\"n\")) {\n const maxDy = sc.height - MIN_SIZE;\n const clampedDy = clamp(dy, -sc.y, maxDy);\n newY = sc.y + clampedDy;\n newH = sc.height - clampedDy;\n }\n if (pos.includes(\"s\")) {\n newH = clamp(sc.height + dy, MIN_SIZE, 1 - sc.y);\n }\n\n // Enforce aspect ratio\n if (ratio !== null && ratio !== undefined) {\n const imgRect = renderer.getImageRect();\n const pixelRatio = imgRect.width / imgRect.height;\n const normalizedRatio = ratio / pixelRatio;\n\n if (pos === \"n\" || pos === \"s\") {\n newW = newH * normalizedRatio;\n if (newX + newW > 1) newW = 1 - newX;\n newH = newW / normalizedRatio;\n } else {\n newH = newW / normalizedRatio;\n if (newY + newH > 1) newH = 1 - newY;\n newW = newH * normalizedRatio;\n }\n }\n\n // Clamp to bounds\n newW = clamp(newW, MIN_SIZE, 1 - newX);\n newH = clamp(newH, MIN_SIZE, 1 - newY);\n\n crop.x = newX;\n crop.y = newY;\n crop.width = newW;\n crop.height = newH;\n }\n\n // Initial layout\n updateLayout();\n\n return {\n root,\n getCrop: () => ({ ...crop }),\n setAspectRatio(preset) {\n aspectRatio = preset;\n const ratio = ASPECT_RATIOS[preset];\n if (ratio !== null && ratio !== undefined) {\n // Adjust current crop to match ratio\n const imgRect = renderer.getImageRect();\n const pixelRatio = imgRect.width / imgRect.height;\n const normalizedRatio = ratio / pixelRatio;\n let newW = crop.width;\n let newH = newW / normalizedRatio;\n if (newH > 1) {\n newH = 1;\n newW = newH * normalizedRatio;\n }\n if (crop.x + newW > 1) crop.x = Math.max(0, 1 - newW);\n if (crop.y + newH > 1) crop.y = Math.max(0, 1 - newH);\n crop.width = newW;\n crop.height = newH;\n updateLayout();\n onChange(crop);\n }\n },\n getAspectRatio: () => aspectRatio,\n setVisible(visible) {\n root.style.display = visible ? \"\" : \"none\";\n },\n destroy() {\n abort.abort();\n root.remove();\n },\n };\n}\n\nfunction createMask(): HTMLElement {\n const div = document.createElement(\"div\");\n div.className = \"rt-crop__mask\";\n return div;\n}\n","import type { AspectRatioPreset, EditorTool, ImageEdits, ViewHandle } from \"../../types\";\nimport { h } from \"../h\";\nimport type { AdjustToolHandle } from \"./adjust-tool\";\nimport type { CropToolHandle } from \"./crop-tool\";\n\nexport interface PropertiesPanelOptions {\n cropTool: CropToolHandle;\n adjustTool: AdjustToolHandle;\n edits: ImageEdits;\n onRotationChange: (degrees: number) => void;\n}\n\nexport interface PropertiesPanelHandle extends ViewHandle {\n setActiveTool(tool: EditorTool): void;\n}\n\nconst ASPECT_PRESETS: { id: AspectRatioPreset; label: string }[] = [\n { id: \"free\", label: \"Free\" },\n { id: \"16:9\", label: \"16:9\" },\n { id: \"4:3\", label: \"4:3\" },\n { id: \"1:1\", label: \"1:1\" },\n { id: \"3:2\", label: \"3:2\" },\n { id: \"9:16\", label: \"9:16\" },\n];\n\nexport function createPropertiesPanel(options: PropertiesPanelOptions): PropertiesPanelHandle {\n const { cropTool, adjustTool, edits, onRotationChange } = options;\n const abort = new AbortController();\n const signal = abort.signal;\n\n // ── Crop properties ──\n\n const aspectBtns = new Map<AspectRatioPreset, HTMLElement>();\n const aspectGrid = h(\"div\", { class: \"rt-props__aspect-grid\" });\n\n for (const preset of ASPECT_PRESETS) {\n const isActive = cropTool.getAspectRatio() === preset.id;\n const btn = h(\n \"button\",\n {\n class: `rt-props__aspect-btn${isActive ? \" rt-props__aspect-btn--active\" : \"\"}`,\n },\n preset.label,\n );\n\n btn.addEventListener(\n \"click\",\n () => {\n for (const b of aspectBtns.values()) {\n b.classList.remove(\"rt-props__aspect-btn--active\");\n }\n btn.classList.add(\"rt-props__aspect-btn--active\");\n cropTool.setAspectRatio(preset.id);\n },\n { signal },\n );\n\n aspectBtns.set(preset.id, btn);\n aspectGrid.appendChild(btn);\n }\n\n const rotationValue = h(\"span\", { class: \"rt-props__slider-value\" }, `${edits.rotation}\\u00b0`);\n const rotationInput = h(\"input\", {\n type: \"range\",\n min: -45,\n max: 45,\n step: 1,\n value: edits.rotation,\n }) as HTMLInputElement;\n\n rotationInput.addEventListener(\n \"input\",\n () => {\n const deg = Number(rotationInput.value);\n rotationValue.textContent = `${deg}\\u00b0`;\n onRotationChange(deg);\n },\n { signal },\n );\n\n const cropProps = h(\n \"div\",\n null,\n h(\"div\", { class: \"rt-props__title\" }, \"Crop\"),\n h(\n \"div\",\n { class: \"rt-props__row\" },\n h(\"div\", { class: \"rt-props__label\" }, \"Aspect Ratio\"),\n aspectGrid,\n ),\n h(\n \"div\",\n { class: \"rt-props__row\" },\n h(\"div\", { class: \"rt-props__label\" }, \"Rotation\"),\n h(\"div\", { class: \"rt-props__slider\" }, rotationInput, rotationValue),\n ),\n h(\"div\", { class: \"rt-props__divider\" }),\n );\n\n // ── Adjust properties ──\n const adjustProps = adjustTool.root;\n\n // ── Panel ──\n const content = h(\"div\");\n content.appendChild(cropProps);\n content.appendChild(adjustProps);\n\n // Initially show crop\n adjustProps.style.display = \"none\";\n\n const root = h(\"div\", { class: \"rt-props\" }, content);\n\n return {\n root,\n setActiveTool(tool) {\n cropProps.style.display = tool === \"crop\" ? \"\" : \"none\";\n adjustProps.style.display = tool === \"adjust\" ? \"\" : \"none\";\n },\n destroy() {\n abort.abort();\n root.remove();\n },\n };\n}\n","import type { EditorTool, ViewHandle } from \"../../types\";\nimport { h } from \"../h\";\n\nexport interface ToolbarOptions {\n activeTool: EditorTool;\n onToolChange: (tool: EditorTool) => void;\n}\n\nexport interface ToolbarHandle extends ViewHandle {\n setActiveTool(tool: EditorTool): void;\n}\n\nconst TOOLS: { id: EditorTool; label: string; icon: string }[] = [\n {\n id: \"crop\",\n label: \"Crop\",\n icon: '<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><path d=\"M6 2L3 6v14a2 2 0 002 2h14a2 2 0 002-2V6l-3-4zM3 6h18\"/></svg>',\n },\n {\n id: \"adjust\",\n label: \"Adjust\",\n icon: '<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><circle cx=\"12\" cy=\"12\" r=\"9\"/><path d=\"M12 3v18M3 12h18\"/></svg>',\n },\n];\n\nexport function createToolbar(options: ToolbarOptions): ToolbarHandle {\n const abort = new AbortController();\n const signal = abort.signal;\n let active = options.activeTool;\n\n const buttons = new Map<EditorTool, HTMLElement>();\n\n const root = h(\"div\", { class: \"rt-toolbar\" });\n\n for (const tool of TOOLS) {\n const btn = h(\"button\", {\n class: `rt-toolbar__btn${tool.id === active ? \" rt-toolbar__btn--active\" : \"\"}`,\n title: tool.label,\n });\n btn.innerHTML = `${tool.icon}<span>${tool.label}</span>`;\n\n btn.addEventListener(\n \"click\",\n () => {\n if (active === tool.id) return;\n buttons.get(active)?.classList.remove(\"rt-toolbar__btn--active\");\n btn.classList.add(\"rt-toolbar__btn--active\");\n active = tool.id;\n options.onToolChange(tool.id);\n },\n { signal },\n );\n\n buttons.set(tool.id, btn);\n root.appendChild(btn);\n }\n\n return {\n root,\n setActiveTool(tool) {\n buttons.get(active)?.classList.remove(\"rt-toolbar__btn--active\");\n buttons.get(tool)?.classList.add(\"rt-toolbar__btn--active\");\n active = tool;\n },\n destroy() {\n abort.abort();\n root.remove();\n },\n };\n}\n","import type { EditorTool, ImageEdits, ImageEntry, ViewHandle } from \"../../types\";\nimport { h } from \"../h\";\nimport { createAdjustTool } from \"./adjust-tool\";\nimport { CanvasRenderer } from \"./canvas-renderer\";\nimport { createCropTool } from \"./crop-tool\";\nimport { createPropertiesPanel } from \"./properties-panel\";\nimport { createToolbar } from \"./toolbar\";\n\nexport interface EditorOptions {\n entry: ImageEntry;\n onDone: () => void;\n onCancel: () => void;\n}\n\nexport function createEditor(options: EditorOptions): ViewHandle {\n const { entry, onDone, onCancel } = options;\n const abort = new AbortController();\n const signal = abort.signal;\n\n // Snapshot edits so cancel can restore them\n const editSnapshot: ImageEdits = structuredClone(entry.edits);\n let activeTool: EditorTool = \"crop\";\n\n // Top bar\n const filenameEl = h(\"span\", { class: \"rt-editor__filename\" }, entry.file.name);\n const dimsEl = h(\n \"span\",\n { class: \"rt-editor__dimensions\" },\n `${entry.image.naturalWidth} \\u00d7 ${entry.image.naturalHeight}`,\n );\n const cancelBtn = h(\"button\", { class: \"rt-editor__btn-cancel\" }, \"Cancel\");\n const doneBtn = h(\"button\", { class: \"rt-editor__btn-done\" }, \"Done\");\n\n const topbar = h(\n \"div\",\n { class: \"rt-editor__topbar\" },\n h(\"div\", { class: \"rt-editor__topbar-left\" }, filenameEl, dimsEl),\n h(\"div\", { class: \"rt-editor__topbar-right\" }, cancelBtn, doneBtn),\n );\n\n // Canvas\n const canvasContainer = h(\"div\", { class: \"rt-editor__canvas-container\" });\n const canvasArea = h(\"div\", { class: \"rt-editor__canvas-area\" }, canvasContainer);\n const renderer = new CanvasRenderer(canvasContainer, entry.image, entry.edits);\n\n // Crop tool (DOM overlay, sits inside canvasContainer)\n const cropTool = createCropTool({\n container: canvasContainer,\n renderer,\n edits: entry.edits,\n onChange: (crop) => {\n entry.edits.crop = crop;\n renderer.render();\n },\n });\n\n // Adjust tool\n const adjustTool = createAdjustTool({\n adjustments: entry.edits.adjustments,\n onChange: (adj) => {\n entry.edits.adjustments = adj;\n renderer.setAdjustments(adj);\n renderer.render();\n },\n });\n\n // Properties panel (right side)\n const propsPanel = createPropertiesPanel({\n cropTool,\n adjustTool,\n edits: entry.edits,\n onRotationChange: (deg) => {\n entry.edits.rotation = deg;\n renderer.setRotation(deg);\n renderer.render();\n },\n });\n\n // Toolbar (left side)\n const toolbar = createToolbar({\n activeTool,\n onToolChange: (tool) => {\n activeTool = tool;\n cropTool.setVisible(tool === \"crop\");\n propsPanel.setActiveTool(tool);\n },\n });\n\n // Body\n const body = h(\"div\", { class: \"rt-editor__body\" }, toolbar.root, canvasArea, propsPanel.root);\n\n // Root overlay\n const root = h(\"div\", { class: \"rt-editor-overlay\" }, topbar, body);\n\n // Button handlers\n cancelBtn.addEventListener(\n \"click\",\n () => {\n // Restore snapshot\n Object.assign(entry.edits, editSnapshot);\n onCancel();\n },\n { signal },\n );\n\n doneBtn.addEventListener(\n \"click\",\n () => {\n onDone();\n },\n { signal },\n );\n\n // Initial render\n renderer.render();\n\n return {\n root,\n destroy() {\n abort.abort();\n cropTool.destroy();\n adjustTool.destroy();\n propsPanel.destroy();\n toolbar.destroy();\n renderer.destroy();\n root.remove();\n },\n };\n}\n","import type { ImageEntry, ViewHandle } from \"../types\";\nimport { h } from \"./h\";\n\nexport interface GalleryOptions {\n images: ImageEntry[];\n onEdit: (id: string) => void;\n onRemove: (id: string) => void;\n onAddMore: (files: File[]) => void;\n onDone: () => void;\n}\n\nexport function createGallery(options: GalleryOptions): ViewHandle {\n const abort = new AbortController();\n const signal = abort.signal;\n\n // Hidden file input for \"Add more\"\n const input = h(\"input\", {\n type: \"file\",\n accept: \"image/*\",\n multiple: true,\n style: \"display:none\",\n }) as HTMLInputElement;\n\n input.addEventListener(\n \"change\",\n () => {\n if (input.files && input.files.length > 0) {\n options.onAddMore(Array.from(input.files));\n input.value = \"\";\n }\n },\n { signal },\n );\n\n // Count display\n const countEl = h(\"div\", { class: \"rt-gallery__count\" });\n const updateCount = () => {\n const n = grid.children.length;\n countEl.innerHTML = `<strong>${n}</strong> image${n !== 1 ? \"s\" : \"\"}`;\n };\n\n // Add more button\n const addMoreBtn = h(\n \"button\",\n {\n class: \"rt-btn\",\n onClick: () => input.click(),\n },\n createPlusIcon(),\n \"Add more\",\n );\n\n // Done button\n const doneBtn = h(\n \"button\",\n {\n class: \"rt-btn rt-btn--accent\",\n onClick: () => options.onDone(),\n },\n \"Done\",\n );\n\n // Grid\n const grid = h(\"div\", { class: \"rt-gallery__grid\" });\n\n // Add initial images\n for (const entry of options.images) {\n grid.appendChild(createGridItem(entry, options, signal));\n }\n\n // Toolbar\n const toolbar = h(\n \"div\",\n { class: \"rt-gallery__toolbar\" },\n countEl,\n h(\"div\", { class: \"rt-gallery__actions\" }, addMoreBtn, input),\n );\n\n // Footer\n const footer = h(\"div\", { class: \"rt-gallery__footer\" }, doneBtn);\n\n const root = h(\"div\", { class: \"rt-gallery\" }, toolbar, grid, footer);\n\n updateCount();\n\n return {\n root,\n destroy() {\n abort.abort();\n root.remove();\n },\n };\n}\n\nfunction createGridItem(\n entry: ImageEntry,\n options: GalleryOptions,\n signal: AbortSignal,\n): HTMLElement {\n const img = h(\"img\", { src: entry.thumbnailUrl, alt: entry.file.name });\n\n const statusClass = entry.edited\n ? \"rt-gallery__item-status--edited\"\n : \"rt-gallery__item-status--pending\";\n const status = h(\"div\", { class: `rt-gallery__item-status ${statusClass}` });\n\n const removeBtn = h(\"button\", { class: \"rt-gallery__item-remove\" });\n removeBtn.innerHTML =\n '<svg viewBox=\"0 0 12 12\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><path d=\"M2 2l8 8M10 2l-8 8\"/></svg>';\n\n const editBtn = h(\"button\", { class: \"rt-gallery__item-edit\" });\n editBtn.innerHTML =\n '<svg viewBox=\"0 0 12 12\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"><path d=\"M8.5 1.5a1.414 1.414 0 012 2L4 10l-2.5.5L2 8l6.5-6.5z\"/></svg> Edit';\n\n const overlay = h(\n \"div\",\n { class: \"rt-gallery__item-overlay\" },\n h(\n \"div\",\n { class: \"rt-gallery__item-info\" },\n h(\"span\", { class: \"rt-gallery__item-name\" }, entry.file.name),\n editBtn,\n ),\n );\n\n const item = h(\n \"div\",\n { class: \"rt-gallery__item\", \"data-id\": entry.id },\n img,\n status,\n removeBtn,\n overlay,\n );\n\n editBtn.addEventListener(\n \"click\",\n (e) => {\n e.stopPropagation();\n options.onEdit(entry.id);\n },\n { signal },\n );\n\n removeBtn.addEventListener(\n \"click\",\n (e) => {\n e.stopPropagation();\n item.remove();\n options.onRemove(entry.id);\n },\n { signal },\n );\n\n return item;\n}\n\nfunction createPlusIcon(): SVGElement {\n const svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\n svg.setAttribute(\"viewBox\", \"0 0 16 16\");\n svg.setAttribute(\"fill\", \"none\");\n svg.setAttribute(\"stroke\", \"currentColor\");\n svg.setAttribute(\"stroke-width\", \"1.5\");\n const p = document.createElementNS(\"http://www.w3.org/2000/svg\", \"path\");\n p.setAttribute(\"d\", \"M8 3v10M3 8h10\");\n svg.appendChild(p);\n return svg;\n}\n","import { DEFAULT_EDITS } from \"../constants\";\nimport type { ImageEdits, ImageEntry } from \"../types\";\n\nexport function generateId(): string {\n return crypto.randomUUID();\n}\n\nexport function isAcceptedType(file: File, accepted: string[]): boolean {\n return accepted.some((type) => {\n if (type.endsWith(\"/*\")) {\n return file.type.startsWith(type.slice(0, -1));\n }\n return file.type === type;\n });\n}\n\nexport function createThumbnailUrl(file: File): string {\n return URL.createObjectURL(file);\n}\n\nexport function revokeThumbnailUrl(url: string): void {\n URL.revokeObjectURL(url);\n}\n\nexport function loadImage(file: File): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n const url = URL.createObjectURL(file);\n img.onload = () => {\n URL.revokeObjectURL(url);\n resolve(img);\n };\n img.onerror = () => {\n URL.revokeObjectURL(url);\n reject(new Error(`[Retouch] Failed to load image: ${file.name}`));\n };\n img.src = url;\n });\n}\n\nexport async function processFiles(\n files: FileList | File[],\n acceptedTypes: string[],\n): Promise<ImageEntry[]> {\n const entries: ImageEntry[] = [];\n const fileArray = Array.from(files);\n\n for (const file of fileArray) {\n if (!isAcceptedType(file, acceptedTypes)) continue;\n\n const image = await loadImage(file);\n entries.push({\n id: generateId(),\n file,\n image,\n thumbnailUrl: createThumbnailUrl(file),\n edits: structuredClone(DEFAULT_EDITS),\n edited: false,\n });\n }\n\n return entries;\n}\n\nfunction buildFilterString(adj: ImageEdits[\"adjustments\"]): string {\n return `brightness(${adj.brightness / 100}) contrast(${adj.contrast / 100}) saturate(${adj.saturation / 100})`;\n}\n\nexport function exportImage(image: HTMLImageElement, edits: ImageEdits): Promise<Blob> {\n return new Promise((resolve, reject) => {\n const { crop, rotation, adjustments } = edits;\n\n // Source region in original image coordinates\n const sx = crop.x * image.naturalWidth;\n const sy = crop.y * image.naturalHeight;\n const sw = crop.width * image.naturalWidth;\n const sh = crop.height * image.naturalHeight;\n\n // Calculate output dimensions accounting for rotation\n const radians = (rotation * Math.PI) / 180;\n const cos = Math.abs(Math.cos(radians));\n const sin = Math.abs(Math.sin(radians));\n const outWidth = Math.round(sw * cos + sh * sin);\n const outHeight = Math.round(sh * cos + sw * sin);\n\n const canvas = document.createElement(\"canvas\");\n canvas.width = outWidth;\n canvas.height = outHeight;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) {\n reject(new Error(\"[Retouch] Failed to create export canvas context\"));\n return;\n }\n\n ctx.filter = buildFilterString(adjustments);\n ctx.translate(outWidth / 2, outHeight / 2);\n ctx.rotate(radians);\n ctx.drawImage(image, sx, sy, sw, sh, -sw / 2, -sh / 2, sw, sh);\n\n canvas.toBlob((blob) => {\n if (blob) {\n resolve(blob);\n } else {\n reject(new Error(\"[Retouch] Failed to export image as blob\"));\n }\n }, \"image/png\");\n });\n}\n","import { ACCEPTED_TYPES } from \"./constants\";\nimport { EventEmitter } from \"./event-emitter\";\nimport { StateMachine } from \"./state-machine\";\nimport { injectStyles } from \"./styles\";\nimport type { AppState, ImageEntry, RetouchEventMap, RetouchOptions, ViewHandle } from \"./types\";\nimport { createDropZone } from \"./ui/drop-zone\";\nimport { createEditor } from \"./ui/editor/editor\";\nimport { createGallery } from \"./ui/gallery\";\nimport { h } from \"./ui/h\";\nimport { exportImage, processFiles, revokeThumbnailUrl } from \"./utils/image\";\n\nconst STATE_TRANSITIONS: Record<AppState, AppState[]> = {\n idle: [\"dropzone\"],\n dropzone: [\"gallery\", \"destroyed\"],\n gallery: [\"editor\", \"dropzone\", \"destroyed\"],\n editor: [\"gallery\", \"destroyed\"],\n destroyed: [],\n};\n\nexport class Retouch {\n private readonly root: HTMLElement;\n private readonly container: HTMLElement;\n private readonly images = new Map<string, ImageEntry>();\n private readonly sm: StateMachine<AppState>;\n private readonly emitter = new EventEmitter<RetouchEventMap>();\n private readonly options: Required<Pick<RetouchOptions, \"maxFiles\" | \"acceptedTypes\">> & {\n onDone?: RetouchOptions[\"onDone\"];\n };\n\n private currentView: ViewHandle | null = null;\n private editingImageId: string | null = null;\n\n constructor(options: RetouchOptions) {\n if (typeof options.target === \"string\") {\n const el = document.querySelector<HTMLElement>(options.target);\n if (!el) {\n throw new Error(`[Retouch] Target element not found: ${options.target}`);\n }\n this.container = el;\n } else {\n this.container = options.target;\n }\n\n this.options = {\n maxFiles: options.maxFiles ?? Number.POSITIVE_INFINITY,\n acceptedTypes: options.acceptedTypes ?? ACCEPTED_TYPES,\n onDone: options.onDone,\n };\n\n injectStyles();\n\n this.root = h(\"div\", { class: \"rt-root\" });\n this.container.appendChild(this.root);\n\n this.sm = new StateMachine<AppState>(\"idle\", STATE_TRANSITIONS);\n this.sm.onChange(({ to }) => {\n this.handleStateChange(to);\n });\n\n this.sm.transition(\"dropzone\");\n }\n\n get state(): AppState {\n return this.sm.state;\n }\n\n on<K extends keyof RetouchEventMap>(\n event: K,\n fn: (data: RetouchEventMap[K]) => void,\n ): () => void {\n return this.emitter.on(event, fn);\n }\n\n async addFiles(files: File[]): Promise<void> {\n const remaining = this.options.maxFiles - this.images.size;\n if (remaining <= 0) return;\n\n const sliced = files.slice(0, remaining);\n const entries = await processFiles(sliced, this.options.acceptedTypes);\n if (entries.length === 0) return;\n\n for (const entry of entries) {\n this.images.set(entry.id, entry);\n }\n\n this.emitter.emit(\"images:add\", { entries });\n\n if (this.sm.state === \"dropzone\") {\n this.sm.transition(\"gallery\");\n }\n }\n\n removeImage(id: string): void {\n const entry = this.images.get(id);\n if (!entry) return;\n revokeThumbnailUrl(entry.thumbnailUrl);\n this.images.delete(id);\n this.emitter.emit(\"images:remove\", { id });\n\n if (this.images.size === 0 && this.sm.state === \"gallery\") {\n this.sm.transition(\"dropzone\");\n }\n }\n\n openEditor(id: string): void {\n if (!this.images.has(id)) return;\n this.editingImageId = id;\n this.emitter.emit(\"editor:open\", { id });\n this.sm.transition(\"editor\");\n }\n\n closeEditor(commit: boolean): void {\n if (this.sm.state !== \"editor\" || !this.editingImageId) return;\n const id = this.editingImageId;\n const entry = this.images.get(id);\n\n if (commit && entry) {\n entry.edited = true;\n this.emitter.emit(\"editor:done\", { id, edits: entry.edits });\n } else {\n this.emitter.emit(\"editor:cancel\", { id });\n }\n\n this.editingImageId = null;\n this.sm.transition(\"gallery\");\n }\n\n getEditingEntry(): ImageEntry | null {\n if (!this.editingImageId) return null;\n return this.images.get(this.editingImageId) ?? null;\n }\n\n getImages(): ImageEntry[] {\n return Array.from(this.images.values());\n }\n\n async exportAll(): Promise<Blob[]> {\n const blobs: Blob[] = [];\n for (const entry of this.images.values()) {\n const blob = await exportImage(entry.image, entry.edits);\n blobs.push(blob);\n }\n return blobs;\n }\n\n async done(): Promise<void> {\n const blobs = await this.exportAll();\n this.emitter.emit(\"done\", { blobs });\n this.options.onDone?.(blobs);\n }\n\n destroy(): void {\n if (this.sm.state === \"destroyed\") return;\n this.unmountCurrentView();\n\n for (const entry of this.images.values()) {\n revokeThumbnailUrl(entry.thumbnailUrl);\n }\n this.images.clear();\n\n this.root.remove();\n this.sm.transition(\"destroyed\");\n this.sm.destroy();\n this.emitter.removeAll();\n }\n\n // ── View lifecycle ────────────────────────\n\n private handleStateChange(to: AppState): void {\n this.unmountCurrentView();\n\n switch (to) {\n case \"dropzone\":\n this.mountDropZone();\n break;\n case \"gallery\":\n this.mountGallery();\n break;\n case \"editor\":\n this.mountEditor();\n break;\n }\n }\n\n private unmountCurrentView(): void {\n if (this.currentView) {\n this.currentView.destroy();\n this.currentView = null;\n }\n }\n\n private mountDropZone(): void {\n const view = createDropZone({\n onFiles: (files) => this.addFiles(files),\n });\n this.root.appendChild(view.root);\n this.currentView = view;\n }\n\n private mountGallery(): void {\n const view = createGallery({\n images: this.getImages(),\n onEdit: (id) => this.openEditor(id),\n onRemove: (id) => this.removeImage(id),\n onAddMore: (files) => this.addFiles(files),\n onDone: () => this.done(),\n });\n this.root.appendChild(view.root);\n this.currentView = view;\n }\n\n private mountEditor(): void {\n const entry = this.getEditingEntry();\n if (!entry) return;\n const view = createEditor({\n entry,\n onDone: () => this.closeEditor(true),\n onCancel: () => this.closeEditor(false),\n });\n this.root.appendChild(view.root);\n this.currentView = view;\n }\n}\n"]}
@@ -0,0 +1,102 @@
1
+ type AppState = "idle" | "dropzone" | "gallery" | "editor" | "destroyed";
2
+ type EditorTool = "crop" | "adjust";
3
+ type AspectRatioPreset = "free" | "16:9" | "4:3" | "1:1" | "3:2" | "9:16";
4
+ interface RetouchOptions {
5
+ /** Target DOM element or CSS selector to mount into. */
6
+ target: string | HTMLElement;
7
+ /** Maximum number of files. Defaults to Infinity. */
8
+ maxFiles?: number;
9
+ /** Accepted MIME types. Defaults to common image types. */
10
+ acceptedTypes?: string[];
11
+ /** Called when the user clicks Done in the gallery with all exported blobs. */
12
+ onDone?: (blobs: Blob[]) => void;
13
+ }
14
+ interface CropRect {
15
+ /** Normalized left (0–1). */
16
+ x: number;
17
+ /** Normalized top (0–1). */
18
+ y: number;
19
+ /** Normalized width (0–1). */
20
+ width: number;
21
+ /** Normalized height (0–1). */
22
+ height: number;
23
+ }
24
+ interface Adjustments {
25
+ /** 0–200, default 100. */
26
+ brightness: number;
27
+ /** 0–200, default 100. */
28
+ contrast: number;
29
+ /** 0–200, default 100. */
30
+ saturation: number;
31
+ }
32
+ interface ImageEdits {
33
+ crop: CropRect;
34
+ /** Degrees, -45 to 45. */
35
+ rotation: number;
36
+ adjustments: Adjustments;
37
+ }
38
+ interface ImageEntry {
39
+ id: string;
40
+ file: File;
41
+ image: HTMLImageElement;
42
+ thumbnailUrl: string;
43
+ edits: ImageEdits;
44
+ edited: boolean;
45
+ }
46
+ interface RetouchEventMap {
47
+ "state:change": {
48
+ from: AppState;
49
+ to: AppState;
50
+ };
51
+ "images:add": {
52
+ entries: ImageEntry[];
53
+ };
54
+ "images:remove": {
55
+ id: string;
56
+ };
57
+ "editor:open": {
58
+ id: string;
59
+ };
60
+ "editor:done": {
61
+ id: string;
62
+ edits: ImageEdits;
63
+ };
64
+ "editor:cancel": {
65
+ id: string;
66
+ };
67
+ done: {
68
+ blobs: Blob[];
69
+ };
70
+ }
71
+
72
+ declare const VERSION = "0.0.1";
73
+
74
+ declare class Retouch {
75
+ private readonly root;
76
+ private readonly container;
77
+ private readonly images;
78
+ private readonly sm;
79
+ private readonly emitter;
80
+ private readonly options;
81
+ private currentView;
82
+ private editingImageId;
83
+ constructor(options: RetouchOptions);
84
+ get state(): AppState;
85
+ on<K extends keyof RetouchEventMap>(event: K, fn: (data: RetouchEventMap[K]) => void): () => void;
86
+ addFiles(files: File[]): Promise<void>;
87
+ removeImage(id: string): void;
88
+ openEditor(id: string): void;
89
+ closeEditor(commit: boolean): void;
90
+ getEditingEntry(): ImageEntry | null;
91
+ getImages(): ImageEntry[];
92
+ exportAll(): Promise<Blob[]>;
93
+ done(): Promise<void>;
94
+ destroy(): void;
95
+ private handleStateChange;
96
+ private unmountCurrentView;
97
+ private mountDropZone;
98
+ private mountGallery;
99
+ private mountEditor;
100
+ }
101
+
102
+ export { type Adjustments, type AppState, type AspectRatioPreset, type CropRect, type EditorTool, type ImageEdits, type ImageEntry, Retouch, type RetouchEventMap, type RetouchOptions, VERSION };
@@ -0,0 +1,102 @@
1
+ type AppState = "idle" | "dropzone" | "gallery" | "editor" | "destroyed";
2
+ type EditorTool = "crop" | "adjust";
3
+ type AspectRatioPreset = "free" | "16:9" | "4:3" | "1:1" | "3:2" | "9:16";
4
+ interface RetouchOptions {
5
+ /** Target DOM element or CSS selector to mount into. */
6
+ target: string | HTMLElement;
7
+ /** Maximum number of files. Defaults to Infinity. */
8
+ maxFiles?: number;
9
+ /** Accepted MIME types. Defaults to common image types. */
10
+ acceptedTypes?: string[];
11
+ /** Called when the user clicks Done in the gallery with all exported blobs. */
12
+ onDone?: (blobs: Blob[]) => void;
13
+ }
14
+ interface CropRect {
15
+ /** Normalized left (0–1). */
16
+ x: number;
17
+ /** Normalized top (0–1). */
18
+ y: number;
19
+ /** Normalized width (0–1). */
20
+ width: number;
21
+ /** Normalized height (0–1). */
22
+ height: number;
23
+ }
24
+ interface Adjustments {
25
+ /** 0–200, default 100. */
26
+ brightness: number;
27
+ /** 0–200, default 100. */
28
+ contrast: number;
29
+ /** 0–200, default 100. */
30
+ saturation: number;
31
+ }
32
+ interface ImageEdits {
33
+ crop: CropRect;
34
+ /** Degrees, -45 to 45. */
35
+ rotation: number;
36
+ adjustments: Adjustments;
37
+ }
38
+ interface ImageEntry {
39
+ id: string;
40
+ file: File;
41
+ image: HTMLImageElement;
42
+ thumbnailUrl: string;
43
+ edits: ImageEdits;
44
+ edited: boolean;
45
+ }
46
+ interface RetouchEventMap {
47
+ "state:change": {
48
+ from: AppState;
49
+ to: AppState;
50
+ };
51
+ "images:add": {
52
+ entries: ImageEntry[];
53
+ };
54
+ "images:remove": {
55
+ id: string;
56
+ };
57
+ "editor:open": {
58
+ id: string;
59
+ };
60
+ "editor:done": {
61
+ id: string;
62
+ edits: ImageEdits;
63
+ };
64
+ "editor:cancel": {
65
+ id: string;
66
+ };
67
+ done: {
68
+ blobs: Blob[];
69
+ };
70
+ }
71
+
72
+ declare const VERSION = "0.0.1";
73
+
74
+ declare class Retouch {
75
+ private readonly root;
76
+ private readonly container;
77
+ private readonly images;
78
+ private readonly sm;
79
+ private readonly emitter;
80
+ private readonly options;
81
+ private currentView;
82
+ private editingImageId;
83
+ constructor(options: RetouchOptions);
84
+ get state(): AppState;
85
+ on<K extends keyof RetouchEventMap>(event: K, fn: (data: RetouchEventMap[K]) => void): () => void;
86
+ addFiles(files: File[]): Promise<void>;
87
+ removeImage(id: string): void;
88
+ openEditor(id: string): void;
89
+ closeEditor(commit: boolean): void;
90
+ getEditingEntry(): ImageEntry | null;
91
+ getImages(): ImageEntry[];
92
+ exportAll(): Promise<Blob[]>;
93
+ done(): Promise<void>;
94
+ destroy(): void;
95
+ private handleStateChange;
96
+ private unmountCurrentView;
97
+ private mountDropZone;
98
+ private mountGallery;
99
+ private mountEditor;
100
+ }
101
+
102
+ export { type Adjustments, type AppState, type AspectRatioPreset, type CropRect, type EditorTool, type ImageEdits, type ImageEntry, Retouch, type RetouchEventMap, type RetouchOptions, VERSION };