@twick/studio 0.15.18 → 0.15.20

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.
package/README.md CHANGED
@@ -161,6 +161,9 @@ interface StudioConfig {
161
161
  saveProject?: (project: ProjectJSON, fileName: string) => Promise<Result>;
162
162
  loadProject?: () => Promise<ProjectJSON>;
163
163
  exportVideo?: (project: ProjectJSON, videoSettings: VideoSettings) => Promise<Result>;
164
+ // Generative AI (optional; enables generate-media toolbar)
165
+ imageGenerationService?: IImageGenerationService;
166
+ videoGenerationService?: IVideoGenerationService;
164
167
  }
165
168
 
166
169
  interface TimelineTickConfig {
@@ -199,10 +202,32 @@ The studio includes specialized panels for different element types:
199
202
  - **RectPanel**: Rectangle shape creation and editing
200
203
  - **IconPanel**: Icon library with search and customization
201
204
 
205
+ ### Generative AI Services
206
+
207
+ Implement `IImageGenerationService` and/or `IVideoGenerationService` to enable the generate-media tool (toolbar icon Wand2):
208
+
209
+ ```ts
210
+ interface IImageGenerationService {
211
+ generateImage: (params: GenerateImageParams) => Promise<string>; // returns requestId
212
+ getRequestStatus: (reqId: string) => Promise<IGenerationPollingResponse>;
213
+ getAvailableModels?: () => ModelInfo[];
214
+ }
215
+
216
+ interface IVideoGenerationService {
217
+ generateVideo: (params: GenerateVideoParams) => Promise<string>;
218
+ getRequestStatus: (reqId: string) => Promise<IGenerationPollingResponse>;
219
+ getAvailableModels?: () => ModelInfo[];
220
+ }
221
+ ```
222
+
223
+ Types (`GenerateImageParams`, `GenerateVideoParams`, `IGenerationPollingResponse`, `ModelInfo`) come from `@twick/ai-models`. Pass your implementation via `studioConfig.imageGenerationService` and `studioConfig.videoGenerationService`. If neither is provided, the generate-media tool is hidden.
224
+
202
225
  ### Hooks
203
226
 
204
227
  - **useStudioManager**: Hook for managing studio state, selected tools, and element manipulation
205
228
  - **useGenerateCaptions**: Hook for caption generation and polling
229
+ - **useGenerateImage**: Hook for image generation (returns `generateImage`, `addImageToTimeline`, `isGenerating`, `error`)
230
+ - **useGenerateVideo**: Hook for video generation (returns `generateVideo`, `addVideoToTimeline`, `isGenerating`, `error`)
206
231
 
207
232
  ### Re-exported Components
208
233
 
@@ -1,5 +1,6 @@
1
1
  import { default as React } from 'react';
2
2
  import { Size, TrackElement } from '@twick/timeline';
3
+ import { StudioConfig, UploadConfig } from '../../types';
3
4
 
4
5
  /**
5
6
  * Props interface for the ElementPanelContainer component.
@@ -12,6 +13,8 @@ interface ElementPanelContainerProps {
12
13
  setSelectedTool: (tool: string) => void;
13
14
  addElement: (element: TrackElement) => void;
14
15
  updateElement: (element: TrackElement) => void;
16
+ uploadConfig?: UploadConfig;
17
+ studioConfig?: StudioConfig;
15
18
  }
16
19
  /**
17
20
  * ElementPanelContainer component that renders the appropriate element panel
@@ -34,5 +37,5 @@ interface ElementPanelContainerProps {
34
37
  * />
35
38
  * ```
36
39
  */
37
- declare const ElementPanelContainer: ({ selectedTool, videoResolution, selectedElement, addElement, updateElement, }: ElementPanelContainerProps) => React.ReactElement;
40
+ declare const ElementPanelContainer: ({ selectedTool, videoResolution, selectedElement, addElement, updateElement, uploadConfig, studioConfig, }: ElementPanelContainerProps) => React.ReactElement;
38
41
  export default ElementPanelContainer;
@@ -0,0 +1,13 @@
1
+ import { default as React } from 'react';
2
+ import { Size, TrackElement } from '@twick/timeline';
3
+ import { StudioConfig } from '../../types';
4
+
5
+ interface GenerateMediaPanelContainerProps {
6
+ videoResolution: Size;
7
+ selectedElement: TrackElement | null;
8
+ addElement: (element: TrackElement) => void;
9
+ updateElement: (element: TrackElement) => void;
10
+ studioConfig?: StudioConfig;
11
+ }
12
+ export declare function GenerateMediaPanelContainer({ videoResolution, addElement, studioConfig, }: GenerateMediaPanelContainerProps): React.ReactElement;
13
+ export {};
@@ -1,24 +1,7 @@
1
+ import { CAPTION_STYLE, CAPTION_STYLE_OPTIONS } from '@twick/timeline';
1
2
  import { PropertiesPanelProps } from '../../types';
2
3
 
3
- export declare const CAPTION_STYLE: {
4
- WORD_BG_HIGHLIGHT: string;
5
- WORD_BY_WORD: string;
6
- WORD_BY_WORD_WITH_BG: string;
7
- };
8
- export declare const CAPTION_STYLE_OPTIONS: {
9
- [CAPTION_STYLE.WORD_BG_HIGHLIGHT]: {
10
- label: string;
11
- value: string;
12
- };
13
- [CAPTION_STYLE.WORD_BY_WORD]: {
14
- label: string;
15
- value: string;
16
- };
17
- [CAPTION_STYLE.WORD_BY_WORD_WITH_BG]: {
18
- label: string;
19
- value: string;
20
- };
21
- };
4
+ export { CAPTION_STYLE, CAPTION_STYLE_OPTIONS };
22
5
  export declare const CAPTION_FONT: {
23
6
  size: number;
24
7
  family: string;
@@ -27,9 +10,11 @@ export declare const CAPTION_COLOR: {
27
10
  text: string;
28
11
  highlight: string;
29
12
  bgColor: string;
13
+ outlineColor: string;
30
14
  };
31
15
  interface CaptionPropPanelProps {
32
- setApplyPropsToAllCaption: (apply: boolean) => void;
16
+ /** No-op when using fixed config. Kept for API compatibility. */
17
+ setApplyPropsToAllCaption?: (apply: boolean) => void;
33
18
  }
34
- export declare function CaptionPropPanel({ selectedElement, updateElement, setApplyPropsToAllCaption, }: CaptionPropPanelProps & PropertiesPanelProps): import("react/jsx-runtime").JSX.Element | null;
19
+ export declare function CaptionPropPanel({ selectedElement, updateElement, }: CaptionPropPanelProps & PropertiesPanelProps): import("react/jsx-runtime").JSX.Element | null;
35
20
  export default CaptionPropPanel;
@@ -0,0 +1,15 @@
1
+ import { CloudUploadProvider } from '../../hooks/use-cloud-media-upload';
2
+
3
+ export interface CloudMediaUploadProps {
4
+ onSuccess: (url: string, file: File) => void;
5
+ onError?: (error: string) => void;
6
+ accept?: string;
7
+ uploadApiUrl: string;
8
+ provider: CloudUploadProvider;
9
+ buttonText?: string;
10
+ className?: string;
11
+ disabled?: boolean;
12
+ id?: string;
13
+ icon?: React.ReactNode;
14
+ }
15
+ export declare const CloudMediaUpload: ({ onSuccess, onError, accept, uploadApiUrl, provider, buttonText, className, disabled, id: providedId, icon, }: CloudMediaUploadProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,3 +1,4 @@
1
+ export * from './cloud-media-upload';
1
2
  export * from './color-input';
2
3
  export * from './file-input';
3
4
  export * from './media-manager';
@@ -49,4 +49,40 @@ export declare const CAPTION_PROPS: {
49
49
  shadowColor: string;
50
50
  shadowBlur: number;
51
51
  };
52
+ outline_only: {
53
+ font: {
54
+ size: number;
55
+ weight: number;
56
+ family: string;
57
+ };
58
+ colors: {
59
+ text: string;
60
+ highlight: string;
61
+ bgColor: string;
62
+ };
63
+ lineWidth: number;
64
+ stroke: string;
65
+ fontWeight: number;
66
+ shadowOffset: number[];
67
+ shadowColor: string;
68
+ shadowBlur: number;
69
+ };
70
+ soft_box: {
71
+ font: {
72
+ size: number;
73
+ weight: number;
74
+ family: string;
75
+ };
76
+ colors: {
77
+ text: string;
78
+ highlight: string;
79
+ bgColor: string;
80
+ };
81
+ lineWidth: number;
82
+ stroke: string;
83
+ fontWeight: number;
84
+ shadowOffset: number[];
85
+ shadowColor: string;
86
+ shadowBlur: number;
87
+ };
52
88
  };
@@ -0,0 +1,27 @@
1
+ export type CloudUploadProvider = "s3" | "gcs";
2
+ export interface UseCloudMediaUploadConfig {
3
+ uploadApiUrl: string;
4
+ provider: CloudUploadProvider;
5
+ }
6
+ /** Response from S3 presign API (e.g. file-uploader Lambda). */
7
+ export interface S3PresignResponse {
8
+ uploadUrl: string;
9
+ key?: string;
10
+ bucket?: string;
11
+ contentType?: string;
12
+ expiresIn?: number;
13
+ }
14
+ /** Response from GCS upload API (server-side upload). */
15
+ export interface GCSUploadResponse {
16
+ url: string;
17
+ }
18
+ export interface UseCloudMediaUploadReturn {
19
+ uploadFile: (file: File) => Promise<{
20
+ url: string;
21
+ }>;
22
+ isUploading: boolean;
23
+ progress: number;
24
+ error: string | null;
25
+ resetError: () => void;
26
+ }
27
+ export declare const useCloudMediaUpload: (config: UseCloudMediaUploadConfig) => UseCloudMediaUploadReturn;
@@ -0,0 +1,10 @@
1
+ import { Size } from '@twick/timeline';
2
+ import { StudioConfig, GenerateImageParams } from '../types';
3
+
4
+ export declare const useGenerateImage: (studioConfig?: StudioConfig) => {
5
+ generateImage: (params: GenerateImageParams) => Promise<string | null>;
6
+ addImageToTimeline: (url: string, videoResolution: Size, startTime: number, duration: number) => void;
7
+ isGenerating: boolean;
8
+ error: string | null;
9
+ hasService: boolean;
10
+ };
@@ -0,0 +1,10 @@
1
+ import { Size } from '@twick/timeline';
2
+ import { StudioConfig, GenerateVideoParams } from '../types';
3
+
4
+ export declare const useGenerateVideo: (studioConfig?: StudioConfig) => {
5
+ generateVideo: (params: GenerateVideoParams) => Promise<string | null>;
6
+ addVideoToTimeline: (url: string, videoResolution: Size, startTime: number, duration: number) => void;
7
+ isGenerating: boolean;
8
+ error: string | null;
9
+ hasService: boolean;
10
+ };
package/dist/index.d.ts CHANGED
@@ -10,6 +10,8 @@ import { TextPanel } from './components/panel/text-panel';
10
10
  import { CirclePanel } from './components/panel/circle-panel';
11
11
  import { RectPanel } from './components/panel/rect-panel';
12
12
  import { CaptionsPanel } from './components/panel/captions-panel';
13
+ import { CloudMediaUpload } from './components/shared/cloud-media-upload';
14
+ import { useCloudMediaUpload } from './hooks/use-cloud-media-upload';
13
15
 
14
16
  export {
15
17
  /** Main studio editing environment */
@@ -37,10 +39,17 @@ export {
37
39
  /** Hook for managing studio state and selections */
38
40
  useStudioManager,
39
41
  /** Hook for polling-based caption generation */
40
- useGenerateCaptions, };
42
+ useGenerateCaptions,
43
+ /** Hook for S3/GCS cloud media upload */
44
+ useCloudMediaUpload, };
45
+ export {
46
+ /** Cloud media upload (S3 or GCS) for use in media panels */
47
+ CloudMediaUpload, };
41
48
  export * from './helpers/generate-captions.service';
42
49
  export * from './helpers/constant';
43
50
  export * from './types';
51
+ export type { CloudUploadProvider, UseCloudMediaUploadConfig, UseCloudMediaUploadReturn, S3PresignResponse, GCSUploadResponse, } from './hooks/use-cloud-media-upload';
52
+ export type { CloudMediaUploadProps } from './components/shared/cloud-media-upload';
44
53
  /**
45
54
  * ============================================================================
46
55
  * RE-EXPORTS FROM DEPENDENCY PACKAGES