@umituz/react-native-photo-editor 2.0.24 → 2.0.26

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.
Files changed (55) hide show
  1. package/package.json +1 -1
  2. package/src/PhotoEditor.tsx +43 -137
  3. package/src/application/hooks/useEditor.ts +4 -6
  4. package/src/application/hooks/useEditorUI.ts +8 -5
  5. package/src/application/stores/EditorStore.ts +42 -17
  6. package/src/domain/entities/Layer.entity.ts +138 -0
  7. package/src/domain/entities/{Layer.ts → Layer.legacy.ts} +3 -3
  8. package/src/domain/entities/StickerLayer.entity.ts +37 -0
  9. package/src/domain/entities/TextLayer.entity.ts +58 -0
  10. package/src/domain/entities/index.ts +9 -0
  11. package/src/domain/services/History.service.ts +69 -0
  12. package/src/domain/services/LayerFactory.service.ts +81 -0
  13. package/src/domain/services/LayerRepository.service.ts +90 -0
  14. package/src/domain/services/LayerService.ts +21 -23
  15. package/src/domain/types.ts +39 -0
  16. package/src/domain/value-objects/FilterSettings.vo.ts +89 -0
  17. package/src/domain/value-objects/LayerDefaults.vo.ts +56 -0
  18. package/src/domain/value-objects/Transform.vo.ts +61 -0
  19. package/src/domain/value-objects/index.ts +13 -0
  20. package/src/index.ts +6 -4
  21. package/src/infrastructure/gesture/createTransformGesture.ts +127 -0
  22. package/src/infrastructure/gesture/useTransformGesture.ts +7 -13
  23. package/src/presentation/components/DraggableLayer.tsx +13 -13
  24. package/src/presentation/components/EditorCanvas.tsx +5 -5
  25. package/src/presentation/components/EditorContent.tsx +72 -0
  26. package/src/presentation/components/EditorHeader.tsx +48 -0
  27. package/src/presentation/components/EditorSheets.tsx +85 -0
  28. package/src/presentation/components/FontControls.tsx +2 -2
  29. package/src/presentation/components/sheets/AdjustmentsSheet.tsx +4 -4
  30. package/src/presentation/components/sheets/FilterSheet.tsx +1 -1
  31. package/src/presentation/components/sheets/LayerManager.tsx +3 -4
  32. package/src/presentation/components/sheets/TextEditorSheet.tsx +1 -1
  33. package/src/types.ts +9 -18
  34. package/src/utils/constants.ts +84 -0
  35. package/src/utils/formatters.ts +29 -0
  36. package/src/utils/helpers.ts +51 -0
  37. package/src/utils/index.ts +9 -0
  38. package/src/utils/validators.ts +38 -0
  39. package/src/components/AIMagicSheet.tsx +0 -107
  40. package/src/components/AdjustmentsSheet.tsx +0 -108
  41. package/src/components/ColorPicker.tsx +0 -77
  42. package/src/components/DraggableSticker.tsx +0 -161
  43. package/src/components/DraggableText.tsx +0 -181
  44. package/src/components/EditorCanvas.tsx +0 -106
  45. package/src/components/EditorToolbar.tsx +0 -155
  46. package/src/components/FilterPicker.tsx +0 -73
  47. package/src/components/FontControls.tsx +0 -132
  48. package/src/components/LayerManager.tsx +0 -164
  49. package/src/components/Slider.tsx +0 -112
  50. package/src/components/StickerPicker.tsx +0 -47
  51. package/src/components/TextEditorSheet.tsx +0 -160
  52. package/src/core/HistoryManager.ts +0 -53
  53. package/src/hooks/usePhotoEditor.ts +0 -172
  54. package/src/hooks/usePhotoEditorUI.ts +0 -162
  55. package/src/infrastructure/history/HistoryManager.ts +0 -38
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Domain Entities Export
3
+ * Clean exports for all domain entities
4
+ */
5
+
6
+ export { Layer } from "./Layer.entity";
7
+ export { TextLayer } from "./TextLayer.entity";
8
+ export { StickerLayer } from "./StickerLayer.entity";
9
+
@@ -0,0 +1,69 @@
1
+ /**
2
+ * History Service
3
+ * Undo/redo functionality for any state type
4
+ */
5
+
6
+ export interface HistoryState<T> {
7
+ past: T[][];
8
+ present: T[];
9
+ future: T[][];
10
+ }
11
+
12
+ export class HistoryService<T> {
13
+ constructor(private readonly maxSize: number = 20) {}
14
+
15
+ createInitialState(initialValue: T[]): HistoryState<T> {
16
+ return {
17
+ past: [],
18
+ present: initialValue,
19
+ future: [],
20
+ };
21
+ }
22
+
23
+ push(history: HistoryState<T>, newValue: T[]): HistoryState<T> {
24
+ const past = [...history.past, history.present];
25
+ const trimmedPast = past.slice(-this.maxSize);
26
+
27
+ return {
28
+ past: trimmedPast,
29
+ present: newValue,
30
+ future: [],
31
+ };
32
+ }
33
+
34
+ undo(history: HistoryState<T>): HistoryState<T> {
35
+ if (history.past.length === 0) return history;
36
+
37
+ const previous = history.past[history.past.length - 1];
38
+ const newPast = history.past.slice(0, -1);
39
+ const newFuture = [history.present, ...history.future];
40
+
41
+ return {
42
+ past: newPast,
43
+ present: previous,
44
+ future: newFuture,
45
+ };
46
+ }
47
+
48
+ redo(history: HistoryState<T>): HistoryState<T> {
49
+ if (history.future.length === 0) return history;
50
+
51
+ const next = history.future[0];
52
+ const newPast = [...history.past, history.present];
53
+ const newFuture = history.future.slice(1);
54
+
55
+ return {
56
+ past: newPast,
57
+ present: next,
58
+ future: newFuture,
59
+ };
60
+ }
61
+
62
+ canUndo(history: HistoryState<T>): boolean {
63
+ return history.past.length > 0;
64
+ }
65
+
66
+ canRedo(history: HistoryState<T>): boolean {
67
+ return history.future.length > 0;
68
+ }
69
+ }
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Layer Factory Service
3
+ * Centralized layer creation with defaults and validation
4
+ */
5
+
6
+ import { TextLayer } from "../entities/TextLayer.entity";
7
+ import { StickerLayer } from "../entities/StickerLayer.entity";
8
+ import { LayerDefaults } from "../value-objects/LayerDefaults.vo";
9
+ import type { Position, Appearance, TextContent } from "../types";
10
+
11
+ export class LayerFactory {
12
+ createTextLayer(overrides?: Partial<Position & Appearance & TextContent>): TextLayer {
13
+ const id = LayerDefaults.createId("text");
14
+
15
+ return new TextLayer({
16
+ id,
17
+ position: { ...LayerDefaults.position, ...overrides },
18
+ rotation: LayerDefaults.transform.rotation,
19
+ scale: LayerDefaults.transform.scale,
20
+ appearance: { ...LayerDefaults.appearance, ...overrides },
21
+ content: {
22
+ ...LayerDefaults.text,
23
+ ...overrides,
24
+ },
25
+ });
26
+ }
27
+
28
+ createStickerLayer(uri: string, overrides?: Partial<Position & Appearance>): StickerLayer {
29
+ const id = LayerDefaults.createId("sticker");
30
+
31
+ return new StickerLayer({
32
+ id,
33
+ position: { ...LayerDefaults.position, ...overrides },
34
+ rotation: LayerDefaults.transform.rotation,
35
+ scale: LayerDefaults.transform.scale,
36
+ appearance: { ...LayerDefaults.appearance, ...overrides },
37
+ content: {
38
+ uri,
39
+ },
40
+ });
41
+ }
42
+
43
+ duplicateLayer<T extends TextLayer | StickerLayer>(
44
+ layer: T,
45
+ currentLayers: { zIndex: number }[]
46
+ ): T {
47
+ const nextZIndex = LayerDefaults.getNextZIndex(currentLayers);
48
+ const offset = { x: 20, y: 20 };
49
+
50
+ if (layer instanceof TextLayer) {
51
+ return new TextLayer({
52
+ ...layer,
53
+ id: LayerDefaults.createId("text"),
54
+ position: {
55
+ x: layer.position.x + offset.x,
56
+ y: layer.position.y + offset.y,
57
+ },
58
+ appearance: {
59
+ ...layer.appearance,
60
+ zIndex: nextZIndex,
61
+ },
62
+ }) as T;
63
+ }
64
+
65
+ return new StickerLayer({
66
+ ...layer,
67
+ id: LayerDefaults.createId("sticker"),
68
+ position: {
69
+ x: layer.position.x + offset.x,
70
+ y: layer.position.y + offset.y,
71
+ },
72
+ appearance: {
73
+ ...layer.appearance,
74
+ zIndex: nextZIndex,
75
+ },
76
+ }) as T;
77
+ }
78
+ }
79
+
80
+ // Singleton instance
81
+ export const layerFactory = new LayerFactory();
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Layer Repository Service
3
+ * CRUD operations for layers with history support
4
+ */
5
+
6
+ import type { Layer } from "../entities/Layer.entity";
7
+ import { LayerFactory } from "./LayerFactory.service";
8
+
9
+ export class LayerRepository {
10
+ constructor(private factory: LayerFactory) {}
11
+
12
+ createLayer(
13
+ type: "text" | "sticker",
14
+ content: string,
15
+ currentLayers: Layer[]
16
+ ): Layer {
17
+ if (type === "text") {
18
+ return this.factory.createTextLayer({
19
+ zIndex: this.getNextZIndex(currentLayers),
20
+ });
21
+ }
22
+
23
+ return this.factory.createStickerLayer(content || "", {
24
+ zIndex: this.getNextZIndex(currentLayers),
25
+ });
26
+ }
27
+
28
+ updateLayer(
29
+ layers: Layer[],
30
+ layerId: string,
31
+ updates: Partial<{ position: { x: number; y: number }; rotation: number; scale: number }>
32
+ ): Layer[] {
33
+ return layers.map((layer) =>
34
+ layer.id === layerId
35
+ ? layer.withPosition(updates.position || {}).withTransform({
36
+ rotation: updates.rotation,
37
+ scale: updates.scale,
38
+ })
39
+ : layer
40
+ );
41
+ }
42
+
43
+ deleteLayer(layers: Layer[], layerId: string): Layer[] {
44
+ return layers.filter((layer) => layer.id !== layerId);
45
+ }
46
+
47
+ duplicateLayer(layers: Layer[], layerId: string): Layer[] {
48
+ const layer = layers.find((l) => l.id === layerId);
49
+ if (!layer) return layers;
50
+
51
+ // Type narrowing - only TextLayer and StickerLayer can be duplicated
52
+ if (!layer.isText() && !layer.isSticker()) {
53
+ return layers;
54
+ }
55
+
56
+ const duplicate = this.factory.duplicateLayer(layer, layers);
57
+ return [...layers, duplicate];
58
+ }
59
+
60
+ reorderLayers(layers: Layer[], layerId: string, direction: "up" | "down"): Layer[] {
61
+ const sorted = this.sortByZIndex(layers);
62
+ const idx = sorted.findIndex((l) => l.id === layerId);
63
+
64
+ if (idx === -1) return layers;
65
+ if (direction === "up" && idx >= sorted.length - 1) return layers;
66
+ if (direction === "down" && idx <= 0) return layers;
67
+
68
+ const reordered = [...sorted];
69
+ const targetIdx = direction === "up" ? idx + 1 : idx - 1;
70
+ [reordered[idx], reordered[targetIdx]] = [reordered[targetIdx], reordered[idx]];
71
+
72
+ return this.reassignZIndex(reordered);
73
+ }
74
+
75
+ sortByZIndex(layers: Layer[]): Layer[] {
76
+ return [...layers].sort((a, b) => a.appearance.zIndex - b.appearance.zIndex);
77
+ }
78
+
79
+ private getNextZIndex(layers: Layer[]): number {
80
+ return layers.length > 0 ? Math.max(...layers.map((l) => l.appearance.zIndex)) + 1 : 0;
81
+ }
82
+
83
+ private reassignZIndex(layers: Layer[]): Layer[] {
84
+ return layers.map((layer, i) => layer.withAppearance({ zIndex: i }));
85
+ }
86
+ }
87
+
88
+ // Singleton instance
89
+ import { layerFactory } from "./LayerFactory.service";
90
+ export const layerRepository = new LayerRepository(layerFactory);
@@ -3,7 +3,10 @@
3
3
  * Business logic for layer operations
4
4
  */
5
5
 
6
- import { Layer, TextLayer, StickerLayer, isTextLayer } from "../entities/Layer";
6
+ import { Layer } from "../entities/Layer.entity";
7
+ import { TextLayer } from "../entities/TextLayer.entity";
8
+ import { StickerLayer } from "../entities/StickerLayer.entity";
9
+ import type { TextContent } from "../types";
7
10
  import type { Transform } from "../entities/Transform";
8
11
 
9
12
  export class LayerService {
@@ -11,18 +14,10 @@ export class LayerService {
11
14
  return `${type}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
12
15
  }
13
16
 
14
- createTextLayer(overrides: Partial<Omit<TextLayerData, "id" | "type">> = {}): TextLayer {
17
+ createTextLayer(overrides: Partial<TextContent> = {}): TextLayer {
15
18
  const id = this.generateId("text");
16
- const defaults: TextLayerData = {
17
- id,
18
- type: "text",
19
+ const contentDefaults: TextContent = {
19
20
  text: "",
20
- x: 50,
21
- y: 50,
22
- rotation: 0,
23
- scale: 1,
24
- opacity: 1,
25
- zIndex: 0,
26
21
  fontSize: 32,
27
22
  fontFamily: "System",
28
23
  color: "#FFFFFF",
@@ -32,24 +27,27 @@ export class LayerService {
32
27
  isItalic: false,
33
28
  };
34
29
 
35
- return new TextLayer({ ...defaults, ...overrides });
30
+ return new TextLayer({
31
+ id,
32
+ position: { x: 50, y: 50 },
33
+ rotation: 0,
34
+ scale: 1,
35
+ appearance: { opacity: 1, zIndex: 0 },
36
+ content: { ...contentDefaults, ...overrides },
37
+ });
36
38
  }
37
39
 
38
- createStickerLayer(uri: string, overrides: Partial<Omit<StickerLayerData, "id" | "type" | "uri">> = {}): StickerLayer {
40
+ createStickerLayer(uri: string, _overrides: Record<string, never> = {}): StickerLayer {
39
41
  const id = this.generateId("sticker");
40
- const defaults: StickerLayerData = {
42
+
43
+ return new StickerLayer({
41
44
  id,
42
- type: "sticker",
43
- uri,
44
- x: 100,
45
- y: 100,
45
+ position: { x: 100, y: 100 },
46
46
  rotation: 0,
47
47
  scale: 1,
48
- opacity: 1,
49
- zIndex: 0,
50
- };
51
-
52
- return new StickerLayer({ ...defaults, ...overrides });
48
+ appearance: { opacity: 1, zIndex: 0 },
49
+ content: { uri },
50
+ });
53
51
  }
54
52
 
55
53
  updateLayer(layers: Layer[], layerId: string, updates: Partial<Transform>): Layer[] {
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Shared Domain Types
3
+ * Central type definitions for the photo editor domain
4
+ */
5
+
6
+ export type LayerType = "text" | "sticker";
7
+ export type TextAlign = "left" | "center" | "right";
8
+
9
+ export interface Position {
10
+ readonly x: number;
11
+ readonly y: number;
12
+ }
13
+
14
+ export interface Dimensions {
15
+ readonly width?: number;
16
+ readonly height?: number;
17
+ }
18
+
19
+ export interface Appearance {
20
+ readonly opacity: number;
21
+ readonly zIndex: number;
22
+ }
23
+
24
+ export interface TextContent {
25
+ readonly text: string;
26
+ readonly fontSize: number;
27
+ readonly fontFamily: string;
28
+ readonly color: string;
29
+ readonly backgroundColor: string;
30
+ readonly textAlign: TextAlign;
31
+ readonly isBold?: boolean;
32
+ readonly isItalic?: boolean;
33
+ }
34
+
35
+ export interface StickerContent {
36
+ readonly uri: string;
37
+ }
38
+
39
+ export type LayerContent = TextContent | StickerContent;
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Filter Settings Value Object
3
+ * Immutable image filter adjustments
4
+ */
5
+
6
+ export interface FilterData {
7
+ readonly brightness: number;
8
+ readonly contrast: number;
9
+ readonly saturation: number;
10
+ readonly sepia: number;
11
+ readonly grayscale: number;
12
+ readonly hueRotate?: number;
13
+ }
14
+
15
+ export class FilterSettings {
16
+ readonly brightness: number;
17
+ readonly contrast: number;
18
+ readonly saturation: number;
19
+ readonly sepia: number;
20
+ readonly grayscale: number;
21
+ readonly hueRotate?: number;
22
+
23
+ constructor(data: FilterData) {
24
+ this.brightness = data.brightness;
25
+ this.contrast = data.contrast;
26
+ this.saturation = data.saturation;
27
+ this.sepia = data.sepia;
28
+ this.grayscale = data.grayscale;
29
+ this.hueRotate = data.hueRotate;
30
+ }
31
+
32
+ static readonly DEFAULT = new FilterSettings({
33
+ brightness: 1,
34
+ contrast: 1,
35
+ saturation: 1,
36
+ sepia: 0,
37
+ grayscale: 0,
38
+ });
39
+
40
+ withBrightness(brightness: number): FilterSettings {
41
+ return new FilterSettings({ ...this, brightness });
42
+ }
43
+
44
+ withContrast(contrast: number): FilterSettings {
45
+ return new FilterSettings({ ...this, contrast });
46
+ }
47
+
48
+ withSaturation(saturation: number): FilterSettings {
49
+ return new FilterSettings({ ...this, saturation });
50
+ }
51
+
52
+ withSepia(sepia: number): FilterSettings {
53
+ return new FilterSettings({ ...this, sepia });
54
+ }
55
+
56
+ withGrayscale(grayscale: number): FilterSettings {
57
+ return new FilterSettings({ ...this, grayscale });
58
+ }
59
+
60
+ withHueRotate(hueRotate: number): FilterSettings {
61
+ return new FilterSettings({ ...this, hueRotate });
62
+ }
63
+
64
+ reset(): FilterSettings {
65
+ return FilterSettings.DEFAULT;
66
+ }
67
+
68
+ toJSON(): FilterData {
69
+ return {
70
+ brightness: this.brightness,
71
+ contrast: this.contrast,
72
+ saturation: this.saturation,
73
+ sepia: this.sepia,
74
+ grayscale: this.grayscale,
75
+ hueRotate: this.hueRotate,
76
+ };
77
+ }
78
+
79
+ toRecord(): Record<string, number> {
80
+ return {
81
+ brightness: this.brightness,
82
+ contrast: this.contrast,
83
+ saturation: this.saturation,
84
+ sepia: this.sepia,
85
+ grayscale: this.grayscale,
86
+ ...(this.hueRotate !== undefined && { hueRotate: this.hueRotate }),
87
+ } as Record<string, number>;
88
+ }
89
+ }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Layer Defaults Value Object
3
+ * Centralized default values for layer creation
4
+ */
5
+
6
+ import type { TextAlign } from "../types";
7
+
8
+ export const LayerDefaults = {
9
+ // Position defaults
10
+ position: {
11
+ x: 50,
12
+ y: 50,
13
+ },
14
+
15
+ // Transform defaults
16
+ transform: {
17
+ rotation: 0,
18
+ scale: 1,
19
+ },
20
+
21
+ // Appearance defaults
22
+ appearance: {
23
+ opacity: 1,
24
+ zIndex: 0,
25
+ },
26
+
27
+ // Text layer defaults
28
+ text: {
29
+ text: "",
30
+ fontSize: 32,
31
+ fontFamily: "System",
32
+ color: "#FFFFFF",
33
+ backgroundColor: "transparent",
34
+ textAlign: "center" as TextAlign,
35
+ isBold: false,
36
+ isItalic: false,
37
+ },
38
+
39
+ // Sticker layer defaults
40
+ sticker: {
41
+ uri: "",
42
+ },
43
+
44
+ // Utility functions
45
+ createId(type: "text" | "sticker"): string {
46
+ return `${type}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
47
+ },
48
+
49
+ getNextZIndex(currentLayers: { zIndex: number }[]): number {
50
+ return currentLayers.length > 0
51
+ ? Math.max(...currentLayers.map((l) => l.zIndex)) + 1
52
+ : 0;
53
+ },
54
+ } as const;
55
+
56
+ export type LayerDefaultsType = typeof LayerDefaults;
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Transform Value Object
3
+ * Immutable position, scale, and rotation state
4
+ */
5
+
6
+ export interface TransformData {
7
+ readonly x: number;
8
+ readonly y: number;
9
+ readonly rotation: number;
10
+ readonly scale: number;
11
+ }
12
+
13
+ export class Transform {
14
+ readonly x: number;
15
+ readonly y: number;
16
+ readonly rotation: number;
17
+ readonly scale: number;
18
+
19
+ constructor(data: TransformData) {
20
+ this.x = data.x;
21
+ this.y = data.y;
22
+ this.rotation = data.rotation;
23
+ this.scale = data.scale;
24
+ }
25
+
26
+ static readonly DEFAULT = new Transform({
27
+ x: 50,
28
+ y: 50,
29
+ rotation: 0,
30
+ scale: 1,
31
+ });
32
+
33
+ withX(x: number): Transform {
34
+ return new Transform({ ...this, x });
35
+ }
36
+
37
+ withY(y: number): Transform {
38
+ return new Transform({ ...this, y });
39
+ }
40
+
41
+ withPosition(position: { x: number; y: number }): Transform {
42
+ return new Transform({ ...this, ...position });
43
+ }
44
+
45
+ withRotation(rotation: number): Transform {
46
+ return new Transform({ ...this, rotation });
47
+ }
48
+
49
+ withScale(scale: number): Transform {
50
+ return new Transform({ ...this, scale });
51
+ }
52
+
53
+ toJSON(): TransformData {
54
+ return {
55
+ x: this.x,
56
+ y: this.y,
57
+ rotation: this.rotation,
58
+ scale: this.scale,
59
+ };
60
+ }
61
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Value Objects Export
3
+ * Immutable value objects for domain modeling
4
+ */
5
+
6
+ export { Transform } from "./Transform.vo";
7
+ export type { TransformData } from "./Transform.vo";
8
+
9
+ export { FilterSettings } from "./FilterSettings.vo";
10
+ export type { FilterData } from "./FilterSettings.vo";
11
+
12
+ export { LayerDefaults } from "./LayerDefaults.vo";
13
+ export type { LayerDefaults as LayerDefaultsType } from "./LayerDefaults.vo";
package/src/index.ts CHANGED
@@ -10,18 +10,20 @@ export { PhotoEditor } from "./PhotoEditor";
10
10
  export type { PhotoEditorProps } from "./PhotoEditor";
11
11
 
12
12
  // Domain entities
13
- export type { Layer, TextLayer, StickerLayer } from "./domain/entities/Layer";
13
+ export type { Layer, TextLayer, StickerLayer } from "./domain/entities/Layer.entity";
14
+ export type { TextContent as TextLayerData, StickerContent as StickerLayerData } from "./domain/types";
15
+ export type { TextAlign } from "./domain/types";
14
16
  export type { Transform } from "./domain/entities/Transform";
15
17
  export type { FilterValues, FiltersVO } from "./domain/entities/Filters";
16
- export { isTextLayer, isStickerLayer } from "./domain/entities/Layer";
18
+ export { isTextLayer, isStickerLayer } from "./domain/entities/Layer.entity";
17
19
 
18
20
  // Application hooks
19
21
  export { useEditor } from "./application/hooks/useEditor";
20
22
  export { useEditorUI } from "./application/hooks/useEditorUI";
21
23
 
22
24
  // Types & constants
23
- export type { LayerTransform } from "./infrastructure/gesture/types";
24
- export { DEFAULT_IMAGE_FILTERS } from "./domain/entities/Filters";
25
+ export type { TransformGestureState, TransformGestureConfig } from "./infrastructure/gesture/types";
26
+ export { DEFAULT_IMAGE_FILTERS } from "./types";
25
27
  export { DEFAULT_FONTS, DEFAULT_TEXT_COLORS, DEFAULT_STICKERS, DEFAULT_AI_STYLES } from "./constants";
26
28
  export type { FilterOption } from "./presentation/components/sheets/FilterSheet";
27
29