@fastlabai/design-editor 1.0.0-beta.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,384 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import React from 'react';
3
+
4
+ /** A single media library item — image, video, or other asset. */
5
+ interface MediaItem {
6
+ /** Stable unique identifier for this item. */
7
+ id: string;
8
+ /** Absolute or app-relative URL to the asset. */
9
+ url: string;
10
+ /** Optional thumbnail URL — falls back to `url` if omitted. */
11
+ thumbnailUrl?: string;
12
+ width?: number;
13
+ height?: number;
14
+ name?: string;
15
+ /** MIME type, e.g. `image/png` or `video/mp4`. */
16
+ mimeType?: string;
17
+ }
18
+ /** Paginated result returned by {@link MediaProvider.list}. */
19
+ interface MediaListResult {
20
+ items: MediaItem[];
21
+ /** Opaque cursor for the next page, or undefined if no more pages. */
22
+ nextCursor?: string;
23
+ }
24
+ /**
25
+ * Plug in your own media library backend. The editor calls `list` to populate
26
+ * the Library panel and `upload` when the user drops a file into the Upload panel.
27
+ */
28
+ interface MediaProvider {
29
+ /** List media items, optionally paginated and filtered by search. */
30
+ list(opts: {
31
+ cursor?: string;
32
+ search?: string;
33
+ signal?: AbortSignal;
34
+ }): Promise<MediaListResult>;
35
+ /** Upload a file and return the resulting media item. */
36
+ upload(file: File, opts?: {
37
+ signal?: AbortSignal;
38
+ onProgress?: (pct: number) => void;
39
+ }): Promise<MediaItem>;
40
+ }
41
+
42
+ /** Describes a font family available to the editor. */
43
+ interface FontDescriptor {
44
+ family: string;
45
+ weights?: number[];
46
+ styles?: ('normal' | 'italic')[];
47
+ category?: 'serif' | 'sans-serif' | 'display' | 'handwriting' | 'monospace';
48
+ previewUrl?: string;
49
+ }
50
+ /**
51
+ * Plug in your own font source. The editor calls `list` to populate the Fonts
52
+ * panel and `load` when the user selects a font (the provider is responsible
53
+ * for injecting the @font-face declaration or stylesheet).
54
+ */
55
+ interface FontProvider {
56
+ /** Return the list of available fonts, optionally filtered by search. */
57
+ list(opts?: {
58
+ search?: string;
59
+ signal?: AbortSignal;
60
+ }): Promise<FontDescriptor[]>;
61
+ /** Load a font family (and optional weight/style) so it can be rendered on canvas. */
62
+ load(family: string, opts?: {
63
+ weight?: number;
64
+ style?: string;
65
+ }): Promise<void>;
66
+ }
67
+
68
+ /**
69
+ * Plug in a background-removal backend. The default provider uses the
70
+ * optional `@imgly/background-removal` peer dep to run in-browser; you can
71
+ * supply a server-side provider here instead.
72
+ */
73
+ interface BackgroundRemovalProvider {
74
+ /** Remove the background from the given image and return a transparent-PNG Blob. */
75
+ remove(input: string | Blob, opts?: {
76
+ signal?: AbortSignal;
77
+ onProgress?: (pct: number) => void;
78
+ }): Promise<Blob>;
79
+ }
80
+
81
+ interface TimeRange {
82
+ from?: number;
83
+ to?: number;
84
+ }
85
+
86
+ type ILayerType = "StaticVector" | "StaticGroup" | "DynamicGroup" | "StaticPath" | "DynamicPath" | "StaticImage" | "BackgroundImage" | "StaticVideo" | "StaticAudio" | "DynamicImage" | "StaticText" | "DynamicText" | "Background" | "Frame" | "Group" | "activeSelection";
87
+ interface IKeyValue {
88
+ key: string;
89
+ value: string;
90
+ }
91
+ interface IShadow {
92
+ blur: number;
93
+ color: string;
94
+ offsetX: number;
95
+ offsetY: number;
96
+ affectStroke?: boolean;
97
+ nonScaling?: boolean;
98
+ }
99
+ interface Param {
100
+ key: string;
101
+ name: string;
102
+ }
103
+ interface LayerBaseOptions {
104
+ id: string;
105
+ name?: string;
106
+ type: ILayerType | string;
107
+ top?: number;
108
+ left?: number;
109
+ angle?: number;
110
+ width?: number;
111
+ height?: number;
112
+ originX?: string;
113
+ originY?: string;
114
+ scaleX?: number;
115
+ scaleY?: number;
116
+ opacity?: number;
117
+ flipX?: boolean;
118
+ flipY?: boolean;
119
+ skewX?: number;
120
+ skewY?: number;
121
+ stroke?: string;
122
+ strokeWidth?: number;
123
+ watermark?: string;
124
+ visible?: boolean;
125
+ shadow?: IShadow;
126
+ metadata?: Record<string, string | number | boolean>;
127
+ animation?: Animation;
128
+ clipPath?: ILayer;
129
+ strokeDashArray?: number[] | undefined;
130
+ strokeLineCap?: string | undefined;
131
+ strokeLineJoin?: string | undefined;
132
+ strokeUniform?: boolean;
133
+ strokeMiterLimit?: number | undefined;
134
+ strokeDashOffset?: number;
135
+ clipToFrame?: boolean;
136
+ preview?: string;
137
+ duration?: number;
138
+ display?: TimeRange;
139
+ cut?: TimeRange;
140
+ params?: Param[];
141
+ }
142
+ interface Animation {
143
+ type: string;
144
+ }
145
+ interface IStaticText extends LayerBaseOptions {
146
+ fontURL?: string;
147
+ textAlign?: string;
148
+ fontFamily?: string;
149
+ fontSize?: number;
150
+ charSpacing?: number;
151
+ lineHeight?: number;
152
+ underline?: boolean;
153
+ text: string;
154
+ fill?: string;
155
+ }
156
+ interface IDynamicText extends IStaticText {
157
+ keyValues: IKeyValue[];
158
+ }
159
+ interface IStaticImage extends LayerBaseOptions {
160
+ src: string;
161
+ cropX?: number;
162
+ cropY?: number;
163
+ }
164
+ interface IBackgroundImage extends IStaticImage {
165
+ }
166
+ interface IDynamicImage extends LayerBaseOptions {
167
+ key: string;
168
+ }
169
+ interface IGroup extends LayerBaseOptions {
170
+ objects: ILayer[];
171
+ }
172
+ interface IStaticPath extends LayerBaseOptions {
173
+ path: number[][];
174
+ fill: string;
175
+ }
176
+ interface IStaticVector extends LayerBaseOptions {
177
+ src: string;
178
+ colorMap: Record<string, string>;
179
+ }
180
+ interface IStaticVideo extends LayerBaseOptions {
181
+ src: string;
182
+ speedFactor: number;
183
+ }
184
+ interface IStaticAudio extends LayerBaseOptions {
185
+ src: string;
186
+ speedFactor: number;
187
+ }
188
+ interface IBackground extends LayerBaseOptions {
189
+ fill: string;
190
+ }
191
+ type ILayer = IStaticText | IDynamicText | IStaticImage | IDynamicImage | IStaticPath | IBackground | IStaticAudio | IStaticVideo | IStaticVector | IGroup | IBackgroundImage;
192
+
193
+ interface IFrame {
194
+ width: number;
195
+ height: number;
196
+ }
197
+ interface IScene {
198
+ id: string;
199
+ frame: IFrame;
200
+ name?: string;
201
+ description?: string;
202
+ layers: Partial<ILayer>[];
203
+ metadata: Record<string, any>;
204
+ preview?: string;
205
+ duration?: number;
206
+ display?: TimeRange;
207
+ }
208
+
209
+ declare module "fabric" {
210
+ namespace fabric {
211
+ interface Frame {
212
+ }
213
+ }
214
+ }
215
+
216
+ declare module "fabric" {
217
+ namespace fabric {
218
+ interface StaticText {
219
+ }
220
+ }
221
+ }
222
+
223
+ declare module "fabric" {
224
+ namespace fabric {
225
+ interface StaticImage {
226
+ }
227
+ }
228
+ }
229
+
230
+ declare module "fabric" {
231
+ namespace fabric {
232
+ interface StaticVector {
233
+ }
234
+ }
235
+ }
236
+
237
+ declare module "fabric" {
238
+ namespace fabric {
239
+ interface StaticPath {
240
+ }
241
+ }
242
+ }
243
+
244
+ declare module "fabric" {
245
+ namespace fabric {
246
+ interface Background {
247
+ }
248
+ }
249
+ }
250
+
251
+ declare module "fabric" {
252
+ namespace fabric {
253
+ interface BackgroundImage {
254
+ }
255
+ interface IUtil {
256
+ isTouchEvent(event: Event): boolean;
257
+ getPointer(event: Event, a?: any): Point;
258
+ }
259
+ }
260
+ }
261
+
262
+ declare module "fabric" {
263
+ namespace fabric {
264
+ interface StaticVideo {
265
+ }
266
+ }
267
+ }
268
+
269
+ declare module "fabric" {
270
+ namespace fabric {
271
+ interface StaticAudio {
272
+ }
273
+ }
274
+ }
275
+
276
+ declare module "fabric" {
277
+ namespace fabric {
278
+ interface Canvas {
279
+ __fire: any;
280
+ enableEvents: () => void;
281
+ disableEvents: () => void;
282
+ }
283
+ interface Object {
284
+ id: string;
285
+ name: string;
286
+ locked: boolean;
287
+ duration?: {
288
+ start?: number;
289
+ stop?: number;
290
+ };
291
+ _objects?: fabric.Object[];
292
+ metadata?: Record<string, any>;
293
+ clipPath?: undefined | null | fabric.Object;
294
+ }
295
+ }
296
+ }
297
+
298
+ /**
299
+ * Plug in a persistence backend for autosave/load. The default provider stores
300
+ * scenes in `localStorage`; you can supply a server-side adapter here.
301
+ */
302
+ interface PersistenceProvider {
303
+ /** Persist the given scene under the provided key. */
304
+ save(sceneKey: string, scene: IScene): Promise<void>;
305
+ /** Load a previously saved scene, or null if none exists. */
306
+ load(sceneKey: string): Promise<IScene | null>;
307
+ /** Optional: enumerate stored scenes (used by host-app scene pickers). */
308
+ list?(): Promise<{
309
+ sceneKey: string;
310
+ updatedAt: number;
311
+ thumbnailUrl?: string;
312
+ }[]>;
313
+ }
314
+
315
+ declare function createLocalStoragePersistence(opts?: {
316
+ prefix?: string;
317
+ }): PersistenceProvider;
318
+
319
+ declare function createGoogleFontsProvider(opts?: {
320
+ apiKey?: string;
321
+ }): FontProvider;
322
+
323
+ declare function createImglyBackgroundRemoval(): BackgroundRemovalProvider;
324
+
325
+ declare function createNullMediaProvider(): MediaProvider;
326
+
327
+ type LibraryPanelRenderProp = React.ReactNode | ((props: {
328
+ onAddMedia: (url: string) => void;
329
+ }) => React.ReactNode);
330
+ /** Props for the top-level {@link DesignEditor} component. */
331
+ interface DesignEditorProps {
332
+ /** A serialized scene to load on mount, or any scene-shaped object with optional `canvasBg`/`workspaceBg`. */
333
+ initialScene?: IScene | any;
334
+ /** Stable key identifying the scene for persistence; passed to the persistence provider. */
335
+ sceneKey?: string;
336
+ /** Called when the user clicks the back button in the toolbar. */
337
+ onBack?: () => void;
338
+ /** Called when the user exports the design. Receives the rendered Blob and the output format. */
339
+ onExport?: (blob: Blob, format: 'png' | 'jpg' | 'svg') => void | Promise<void>;
340
+ /** Media library provider. Defaults to a null provider (empty Library panel). */
341
+ mediaProvider?: MediaProvider;
342
+ /** Font provider. Defaults to a Google Fonts provider. */
343
+ fontProvider?: FontProvider;
344
+ /** Background removal provider. Defaults to `@imgly/background-removal` if installed. */
345
+ backgroundRemovalProvider?: BackgroundRemovalProvider;
346
+ /** Autosave/scene persistence provider. Defaults to a `localStorage` provider. */
347
+ persistenceProvider?: PersistenceProvider;
348
+ /** Optional className applied to the editor root for outer styling. */
349
+ className?: string;
350
+ /** Custom render override for the Library panel — useful to inject host-app media UI. */
351
+ libraryPanel?: LibraryPanelRenderProp;
352
+ }
353
+ /**
354
+ * The top-level image design editor. Renders a full-screen canvas-based editor
355
+ * with toolbar, side panels, layer panel, and object properties bar.
356
+ *
357
+ * Configure host integration via the provider props
358
+ * (`mediaProvider`, `fontProvider`, `backgroundRemovalProvider`, `persistenceProvider`).
359
+ *
360
+ * @example
361
+ * ```tsx
362
+ * import { DesignEditor } from '@fastlabai/design-editor'
363
+ * import '@fastlabai/design-editor/theme.css'
364
+ *
365
+ * export default function App() {
366
+ * return <DesignEditor />
367
+ * }
368
+ * ```
369
+ */
370
+ declare function DesignEditor({ initialScene, sceneKey, onBack, onExport, mediaProvider, fontProvider, backgroundRemovalProvider, persistenceProvider, className, libraryPanel, }: DesignEditorProps): react_jsx_runtime.JSX.Element;
371
+
372
+ /**
373
+ * @fastlabai/design-editor
374
+ *
375
+ * An open-source image design editor for React and Next.js.
376
+ * Plug into your own media library, fonts, and storage backend via simple
377
+ * provider interfaces.
378
+ *
379
+ * @packageDocumentation
380
+ */
381
+ /** Current package version. */
382
+ declare const VERSION = "0.0.0";
383
+
384
+ export { type BackgroundRemovalProvider, DesignEditor, type DesignEditorProps, type FontDescriptor, type FontProvider, type ILayer, type IScene, type MediaItem, type MediaListResult, type MediaProvider, type PersistenceProvider, VERSION, createGoogleFontsProvider, createImglyBackgroundRemoval, createLocalStoragePersistence, createNullMediaProvider };