@orangecatai/element 0.0.2 → 0.0.4

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 (93) hide show
  1. package/dist/dev/index.js +67 -4
  2. package/dist/dev/index.js.map +2 -2
  3. package/dist/prod/index.js +9 -9
  4. package/dist/types/common/src/constants.d.ts +4 -0
  5. package/dist/types/common/src/keys.d.ts +2 -0
  6. package/dist/types/element/src/Scene.d.ts +1 -1
  7. package/dist/types/element/src/frame.d.ts +5 -5
  8. package/dist/types/element/src/newElement.d.ts +10 -1
  9. package/dist/types/element/src/typeChecks.d.ts +2 -1
  10. package/dist/types/element/src/types.d.ts +17 -2
  11. package/dist/types/excalidraw/actions/actionAddToLibrary.d.ts +1 -1
  12. package/dist/types/excalidraw/actions/actionCanvas.d.ts +177 -0
  13. package/dist/types/excalidraw/actions/actionClipboard.d.ts +7 -7
  14. package/dist/types/excalidraw/actions/actionCropEditor.d.ts +2 -2
  15. package/dist/types/excalidraw/actions/actionDuplicateSelection.d.ts +2 -2
  16. package/dist/types/excalidraw/actions/actionElementLink.d.ts +6 -6
  17. package/dist/types/excalidraw/actions/actionEmbeddable.d.ts +1 -1
  18. package/dist/types/excalidraw/actions/actionFrame.d.ts +219 -0
  19. package/dist/types/excalidraw/actions/actionLinearEditor.d.ts +48 -7
  20. package/dist/types/excalidraw/actions/actionLink.d.ts +3 -3
  21. package/dist/types/excalidraw/actions/actionMenu.d.ts +1 -1
  22. package/dist/types/excalidraw/actions/actionSelectAll.d.ts +4 -4
  23. package/dist/types/excalidraw/actions/actionStyles.d.ts +2 -2
  24. package/dist/types/excalidraw/actions/actionToggleObjectsSnapMode.d.ts +4 -4
  25. package/dist/types/excalidraw/actions/actionToggleShapeSwitch.d.ts +3 -3
  26. package/dist/types/excalidraw/actions/actionToggleStats.d.ts +2 -2
  27. package/dist/types/excalidraw/actions/actionToggleViewMode.d.ts +4 -4
  28. package/dist/types/excalidraw/actions/actionToggleZenMode.d.ts +4 -4
  29. package/dist/types/excalidraw/actions/actionZindex.d.ts +8 -8
  30. package/dist/types/excalidraw/actions/index.d.ts +1 -1
  31. package/dist/types/excalidraw/actions/shortcuts.d.ts +1 -1
  32. package/dist/types/excalidraw/actions/types.d.ts +1 -1
  33. package/dist/types/excalidraw/components/AIChatPanel.d.ts +176 -0
  34. package/dist/types/excalidraw/components/Actions.d.ts +3 -0
  35. package/dist/types/excalidraw/components/App.d.ts +10 -0
  36. package/dist/types/excalidraw/components/CanvasBackgroundSwatch.d.ts +7 -0
  37. package/dist/types/excalidraw/components/ColorPicker/AdvancedColorPicker.d.ts +8 -0
  38. package/dist/types/excalidraw/components/ColorPicker/colorConversions.d.ts +27 -0
  39. package/dist/types/excalidraw/components/DarkModeToggle.d.ts +1 -1
  40. package/dist/types/excalidraw/components/DefaultSidebar.d.ts +1 -1
  41. package/dist/types/excalidraw/components/ElementCanvasButtons.d.ts +1 -1
  42. package/dist/types/excalidraw/components/FrameToolbar.d.ts +1 -1
  43. package/dist/types/excalidraw/components/HintViewer.d.ts +1 -1
  44. package/dist/types/excalidraw/components/ImageEditToolbar.d.ts +15 -0
  45. package/dist/types/excalidraw/components/ImageGeneratorPanel.d.ts +59 -13
  46. package/dist/types/excalidraw/components/ImageQuickEditPanel.d.ts +10 -1
  47. package/dist/types/excalidraw/components/Sidebar/Sidebar.d.ts +2 -2
  48. package/dist/types/excalidraw/components/Stats/DragInput.d.ts +1 -1
  49. package/dist/types/excalidraw/components/Stats/index.d.ts +1 -1
  50. package/dist/types/excalidraw/components/StockImagePanel.d.ts +49 -0
  51. package/dist/types/excalidraw/components/TTDDialog/utils/TTDStreamFetch.d.ts +1 -0
  52. package/dist/types/excalidraw/components/ToolButton.d.ts +1 -1
  53. package/dist/types/excalidraw/components/VideoElement.d.ts +9 -0
  54. package/dist/types/excalidraw/components/VideoGeneratorPanel.d.ts +149 -0
  55. package/dist/types/excalidraw/components/ai-chat/AdGenShimmerLayer.d.ts +10 -0
  56. package/dist/types/excalidraw/components/ai-chat/adGenShimmerStore.d.ts +12 -0
  57. package/dist/types/excalidraw/components/ai-chat/agentLoop.d.ts +114 -0
  58. package/dist/types/excalidraw/components/ai-chat/audioUtils.d.ts +5 -0
  59. package/dist/types/excalidraw/components/ai-chat/canvasTools.d.ts +752 -0
  60. package/dist/types/excalidraw/components/ai-chat/htmlToExcalidraw.d.ts +53 -0
  61. package/dist/types/excalidraw/components/ai-chat/openRouterStream.d.ts +50 -0
  62. package/dist/types/excalidraw/components/ai-chat/reviewerAgent.d.ts +74 -0
  63. package/dist/types/excalidraw/components/auto-resize/AutoResizePanel.d.ts +17 -0
  64. package/dist/types/excalidraw/components/auto-resize/AutoResizePanelHost.d.ts +4 -0
  65. package/dist/types/excalidraw/components/auto-resize/AutoResizeShimmerLayer.d.ts +11 -0
  66. package/dist/types/excalidraw/components/auto-resize/autoResizeEngine.d.ts +185 -0
  67. package/dist/types/excalidraw/components/auto-resize/autoResizePanelStore.d.ts +15 -0
  68. package/dist/types/excalidraw/components/auto-resize/autoResizeStore.d.ts +16 -0
  69. package/dist/types/excalidraw/components/hyperlink/Hyperlink.d.ts +1 -1
  70. package/dist/types/excalidraw/components/icons.d.ts +3 -0
  71. package/dist/types/excalidraw/components/main-menu/DefaultItems.d.ts +5 -1
  72. package/dist/types/excalidraw/components/template-builder/TemplateBuilderPanelHost.d.ts +4 -0
  73. package/dist/types/excalidraw/components/template-builder/TemplateBuilderTray.d.ts +4 -0
  74. package/dist/types/excalidraw/components/template-builder/slotTypes.d.ts +43 -0
  75. package/dist/types/excalidraw/components/template-builder/templateBuilderStore.d.ts +19 -0
  76. package/dist/types/excalidraw/components/ui/avatar.d.ts +6 -0
  77. package/dist/types/excalidraw/components/ui/button.d.ts +11 -0
  78. package/dist/types/excalidraw/components/ui/chat-container.d.ts +17 -0
  79. package/dist/types/excalidraw/components/ui/code-block.d.ts +16 -0
  80. package/dist/types/excalidraw/components/ui/markdown.d.ts +10 -0
  81. package/dist/types/excalidraw/components/ui/message.d.ts +35 -0
  82. package/dist/types/excalidraw/components/ui/scroll-button.d.ts +10 -0
  83. package/dist/types/excalidraw/data/blob.d.ts +4 -1
  84. package/dist/types/excalidraw/fonts/Fonts.d.ts +17 -0
  85. package/dist/types/excalidraw/index.d.ts +13 -1
  86. package/dist/types/excalidraw/scene/types.d.ts +1 -0
  87. package/dist/types/excalidraw/types.d.ts +286 -4
  88. package/dist/types/excalidraw/utils/brandContextUtils.d.ts +23 -0
  89. package/dist/types/excalidraw/utils/imageApi.d.ts +19 -0
  90. package/dist/types/excalidraw/utils/videoApi.d.ts +30 -0
  91. package/dist/types/utils/src/shape.d.ts +2 -2
  92. package/package.json +2 -2
  93. package/dist/types/excalidraw/utils/geminiApiKey.d.ts +0 -1
@@ -0,0 +1,10 @@
1
+ import * as React from "react";
2
+ import { type VariantProps } from "class-variance-authority";
3
+ import type { buttonVariants } from "@/components/ui/button";
4
+ export type ScrollButtonProps = {
5
+ className?: string;
6
+ variant?: VariantProps<typeof buttonVariants>["variant"];
7
+ size?: VariantProps<typeof buttonVariants>["size"];
8
+ } & React.ButtonHTMLAttributes<HTMLButtonElement>;
9
+ declare function ScrollButton({ className, variant, size, ...props }: ScrollButtonProps): import("react/jsx-runtime").JSX.Element;
10
+ export { ScrollButton };
@@ -1,4 +1,4 @@
1
- import { IMAGE_MIME_TYPES, MIME_TYPES } from "@orangecatai/common";
1
+ import { IMAGE_MIME_TYPES, VIDEO_MIME_TYPES, MIME_TYPES } from "@orangecatai/common";
2
2
  import type { ExcalidrawElement, FileId } from "@orangecatai/element/types";
3
3
  import type { ValueOf } from "@orangecatai/common/utility-types";
4
4
  import type { AppState, DataURL, LibraryItem } from "../types";
@@ -12,6 +12,9 @@ export declare const isSupportedImageFileType: (type: string | null | undefined)
12
12
  export declare const isSupportedImageFile: (blob: Blob | null | undefined) => blob is Blob & {
13
13
  type: ValueOf<typeof IMAGE_MIME_TYPES>;
14
14
  };
15
+ export declare const isSupportedVideoFile: (blob: Blob | null | undefined) => blob is Blob & {
16
+ type: ValueOf<typeof VIDEO_MIME_TYPES>;
17
+ };
15
18
  export declare const loadSceneOrLibraryFromBlob: (blob: Blob | File,
16
19
  /** @see restore.localAppState */
17
20
  localAppState: AppState | null, localElements: readonly ExcalidrawElement[] | null,
@@ -6,6 +6,10 @@ export declare class Fonts {
6
6
  static readonly loadedFontsCache: Set<string>;
7
7
  private static _registered;
8
8
  private static _initialized;
9
+ private static _customFontVersion;
10
+ private static _subscribers;
11
+ static readonly subscribeToCustomFonts: (callback: () => void) => (() => void);
12
+ static readonly getCustomFontVersion: () => number;
9
13
  static get registered(): Map<number, {
10
14
  metadata: FontMetadata;
11
15
  fontFaces: ExcalidrawFontFace[];
@@ -14,6 +18,19 @@ export declare class Fonts {
14
18
  metadata: FontMetadata;
15
19
  fontFaces: ExcalidrawFontFace[];
16
20
  }>;
21
+ /**
22
+ * Register a custom font from a URL into the canvas font system.
23
+ *
24
+ * Use family IDs >= 2000 to avoid collisions with built-in fonts.
25
+ * IDs 1–10 are named fonts, 100 = Xiaolai, 998/999 = generic fallbacks,
26
+ * 1000 = Segoe UI Emoji — all are reserved.
27
+ *
28
+ * Note: custom fonts are registered without a weight/style descriptor
29
+ * because getFontString generates "${size}px ${familyName}" (no weight),
30
+ * so the browser always requests the normal-weight variant. Pass the font
31
+ * file that should render by default for this family ID.
32
+ */
33
+ static registerCustomFont(spec: import("../types").CustomFontSpec): void;
17
34
  private readonly scene;
18
35
  constructor(scene: Scene);
19
36
  /**
@@ -8,16 +8,20 @@ import "./css/styles.scss";
8
8
  import "./fonts/fonts.css";
9
9
  import "./css/tailwind.generated.css";
10
10
  import type { ExcalidrawProps } from "./types";
11
+ export { StockImagePanel } from "./components/StockImagePanel";
12
+ export type { StockImagePanelProps, StockImagePhoto, StockImageSearchResult, LibraryImage, LibraryImageResult, LibraryImageFilter, } from "./components/StockImagePanel";
11
13
  export declare const Excalidraw: React.MemoExoticComponent<(props: ExcalidrawProps) => import("react/jsx-runtime").JSX.Element>;
12
14
  export { getSceneVersion, hashElementsVersion, hashString, getNonDeletedElements, } from "@orangecatai/element";
13
15
  export { getTextFromElements } from "@orangecatai/element";
14
16
  export { isInvisiblySmallElement } from "@orangecatai/element";
17
+ export { newImageElement, newVideoElement, newTextElement, newFrameElement, } from "@orangecatai/element";
18
+ export { isVideoElement } from "@orangecatai/element";
15
19
  export { defaultLang, useI18n, languages } from "./i18n";
16
20
  export { restoreAppState, restoreElement, restoreElements, restoreLibraryItems, } from "./data/restore";
17
21
  export { reconcileElements } from "./data/reconcile";
18
22
  export { exportToCanvas, exportToBlob, exportToSvg, exportToClipboard, } from "@orangecatai/utils/export";
19
23
  export { serializeAsJSON, serializeLibraryAsJSON } from "./data/json";
20
- export { loadFromBlob, loadSceneOrLibraryFromBlob, loadLibraryFromBlob, } from "./data/blob";
24
+ export { loadFromBlob, loadSceneOrLibraryFromBlob, loadLibraryFromBlob, isSupportedVideoFile, } from "./data/blob";
21
25
  export { mergeLibraryItems, getLibraryItemsHash } from "./data/library";
22
26
  export { isLinearElement } from "@orangecatai/element";
23
27
  export { FONT_FAMILY, THEME, MIME_TYPES, ROUNDNESS, DEFAULT_LASER_COLOR, UserIdleState, normalizeLink, sceneCoordsToViewportCoords, viewportCoordsToSceneCoords, getFormFactor, } from "@orangecatai/common";
@@ -46,3 +50,11 @@ export { getDataURL } from "./data/blob";
46
50
  export { isElementLink } from "@orangecatai/element";
47
51
  export { setCustomTextMetricsProvider } from "@orangecatai/element";
48
52
  export { CommandPalette } from "./components/CommandPalette/CommandPalette";
53
+ export { AIChatPanel } from "./components/AIChatPanel";
54
+ export type { AIChatPanelProps, AIChatPanelRef, ChatMessage, ChatSession, } from "./components/AIChatPanel";
55
+ export type { ExcalidrawImperativeAPI } from "./types";
56
+ export type { AppState, BinaryFiles, BinaryFileData, ExcalidrawProps, ExcalidrawInitialDataState, LibraryItem, LibraryItems, SceneData, UnsubscribeCallback, } from "./types";
57
+ export type { ExcalidrawElement, NonDeletedExcalidrawElement, NonDeleted, OrderedExcalidrawElement, ExcalidrawElementType, ExcalidrawVideoElement, } from "@orangecatai/element/types";
58
+ export type { ImageEditToolbarCallbacks } from "./components/ImageEditToolbar";
59
+ export type { CustomFontSpec, BrandContext } from "./types";
60
+ export type { ReviewerFeedback, ReviewIssue, } from "./components/ai-chat/reviewerAgent";
@@ -132,6 +132,7 @@ export type ElementShapes = {
132
132
  line: Drawable[];
133
133
  text: null;
134
134
  image: null;
135
+ video: Drawable;
135
136
  frame: null;
136
137
  magicframe: null;
137
138
  };
@@ -430,6 +430,97 @@ export type OnUserFollowedPayload = {
430
430
  userToFollow: UserToFollow;
431
431
  action: "FOLLOW" | "UNFOLLOW";
432
432
  };
433
+ /**
434
+ * Describes a custom font to register in the canvas font system.
435
+ * Use family IDs >= 2000 to avoid collision with built-in fonts.
436
+ * IDs up to 1000 are reserved (1–10 named fonts, 100 CJK, 998/999 generic, 1000 emoji).
437
+ */
438
+ export type CustomFontSpec = {
439
+ /** Unique numeric family ID. Use 2000+ to avoid collisions with built-ins. */
440
+ familyId: number;
441
+ /** CSS font-family name used in @font-face and canvas rendering. */
442
+ name: string;
443
+ /** Absolute URL or data: URL pointing to the font file. */
444
+ url: string;
445
+ /**
446
+ * Informational font-weight (e.g. "400", "700"). Not applied as a CSS
447
+ * descriptor — getFontString never includes weight, so all custom fonts
448
+ * load as the normal-weight variant for their family ID.
449
+ */
450
+ weight?: string;
451
+ };
452
+ /**
453
+ * Optional brand identity context passed to AIChatPanel.
454
+ * When provided, the AI agent uses these guidelines when creating ads.
455
+ */
456
+ export type BrandContext = {
457
+ /** Brand name — injected as a system-level constraint so the model stays on-brand. */
458
+ name?: string;
459
+ colors?: {
460
+ primary?: string;
461
+ secondary?: string;
462
+ accent?: string;
463
+ background?: string;
464
+ };
465
+ typography?: {
466
+ headline?: {
467
+ family: string;
468
+ weight?: string;
469
+ /** size_scale from brand kit (e.g. "display", "large", "medium", "small") */
470
+ sizeScale?: string;
471
+ /**
472
+ * Font family ID if a matching custom font was registered via
473
+ * the `customFonts` prop on <Excalidraw>. The agent will pass
474
+ * this number to add_text fontFamily calls.
475
+ */
476
+ fontFamilyId?: number;
477
+ /** Original font file name from brand DNA (e.g. "Avenir-Heavy.otf"). Passed to AI for image generation context. */
478
+ fontName?: string;
479
+ };
480
+ body?: {
481
+ family: string;
482
+ weight?: string;
483
+ sizeScale?: string;
484
+ fontFamilyId?: number;
485
+ /** Original font file name from brand DNA. */
486
+ fontName?: string;
487
+ };
488
+ };
489
+ visualStyle?: string;
490
+ layoutPattern?: string;
491
+ toneOfVoice?: {
492
+ register?: string;
493
+ vocabulary?: string;
494
+ ctaStyle?: string;
495
+ sentenceLength?: string;
496
+ person?: string;
497
+ };
498
+ imagery?: {
499
+ type?: string;
500
+ lighting?: string;
501
+ composition?: string;
502
+ subjects?: string;
503
+ grading?: string;
504
+ depthOfField?: string;
505
+ environment?: string;
506
+ negativeSpace?: string;
507
+ };
508
+ /** Data URL of the master brand logo — passed as a visual reference to the image generation model. */
509
+ logoDataUrl?: string;
510
+ /** Data URL of text rendered in the brand headline font — passed as a visual reference to the image generation model. */
511
+ headlineFontPreviewDataUrl?: string;
512
+ /** Data URL of text rendered in the brand body font — passed as a second visual reference alongside the headline preview. */
513
+ bodyFontPreviewDataUrl?: string;
514
+ /**
515
+ * Fetchable URL (e.g. a short-lived presigned S3 URL) of the actual headline
516
+ * font file (.ttf/.otf). Passed to image models that accept a font file as
517
+ * input (Sourceful Riverflow v2+ via OpenRouter `image_config.font_inputs`).
518
+ * Unlike `headlineFontPreviewDataUrl` (a rendered preview image), this is the
519
+ * real font file the provider's servers fetch directly, so it must be a URL
520
+ * reachable without auth cookies — not the private `/api/brand/font` proxy.
521
+ */
522
+ headlineFontUrl?: string;
523
+ };
433
524
  export interface ExcalidrawProps {
434
525
  onChange?: (elements: readonly OrderedExcalidrawElement[], appState: AppState, files: BinaryFiles) => void;
435
526
  onIncrement?: (event: DurableIncrement | EphemeralIncrement) => void;
@@ -492,11 +583,191 @@ export interface ExcalidrawProps {
492
583
  showDeprecatedFonts?: boolean;
493
584
  renderScrollbars?: boolean;
494
585
  /**
495
- * Gemini API key for image generation.
496
- * When provided, takes precedence over the VITE_APP_GEMINI_API_KEY env variable.
497
- * Required for image generation when using this package as an npm dependency.
586
+ * Host proxy URL for OpenRouter image generation (ImageGeneratorPanel,
587
+ * ImageQuickEditPanel). The SDK POSTs the OpenRouter request body here; the
588
+ * host injects the API key and forwards. Keeps the provider key out of the
589
+ * browser.
590
+ */
591
+ imageGenUrl?: string;
592
+ /**
593
+ * Brand context (colors, typography, logo, font preview) passed to every
594
+ * image generation surface (ImageGeneratorPanel, ImageQuickEditPanel, and the
595
+ * AI chat agent). When present, the logo and font preview are sent as visual
596
+ * references to the image model.
498
597
  */
499
- geminiApiKey?: string;
598
+ brandContext?: BrandContext;
599
+ /**
600
+ * Host proxy URL for the auto-resize engine's OpenRouter calls (layout
601
+ * planning, vision tagging, HTML generation, reviewer). Key stays server-side.
602
+ */
603
+ autoResizeUrl?: string;
604
+ /**
605
+ * Host proxy URL for the remove.bg toolbar action. The SDK POSTs
606
+ * `{ imageDataUrl }` and receives `{ imageDataUrl }`. Key stays server-side.
607
+ */
608
+ removeBgUrl?: string;
609
+ /**
610
+ * Called before any image generation (ImageGeneratorPanel, ImageQuickEditPanel,
611
+ * or agent loop generate_image tool). Return `{ allowed: false }` to block.
612
+ * Host apps use this for credit gating.
613
+ */
614
+ onBeforeImageGen?: () => Promise<{
615
+ allowed: boolean;
616
+ error?: string;
617
+ }>;
618
+ /**
619
+ * Called after a successful image generation from any panel or agent tool.
620
+ */
621
+ onAfterImageGen?: () => void;
622
+ /**
623
+ * Host proxy URL for video uploads. The SDK POSTs multipart/form-data with
624
+ * a `file` field; the host stores the video and returns `{ url: string }`.
625
+ * Without this prop, video upload via drag-and-drop is silently ignored.
626
+ */
627
+ videoUploadUrl?: string;
628
+ /**
629
+ * Called before a video upload begins. Return `{ allowed: false }` to block
630
+ * (e.g. quota exceeded). Host uses this for credit gating.
631
+ */
632
+ onBeforeVideoUpload?: () => Promise<{
633
+ allowed: boolean;
634
+ error?: string;
635
+ }>;
636
+ /** Called after a video is successfully uploaded and placed on the canvas. */
637
+ onAfterVideoUpload?: () => void;
638
+ /** Host proxy URL for video generation jobs (POST). */
639
+ videoGenUrl?: string;
640
+ /** Host proxy URL for polling video generation job status (GET {url}/{jobId}). */
641
+ videoGenStatusUrl?: string;
642
+ /** Called before a video generation job is submitted (credit gate). */
643
+ onBeforeVideoGen?: () => Promise<{
644
+ allowed: boolean;
645
+ error?: string;
646
+ }>;
647
+ /** Called after a video is successfully generated and inserted into the canvas. */
648
+ onAfterVideoGen?: () => void;
649
+ /** Host proxy URL for video downloads — works around S3 CORS / presigned-URL expiry. */
650
+ videoDownloadProxyUrl?: string;
651
+ /**
652
+ * Called before a background removal is run (deduct credits, check quota).
653
+ * Return `{ allowed: false, error: "..." }` to block the operation.
654
+ */
655
+ onBeforeRemoveBg?: () => Promise<{
656
+ allowed: boolean;
657
+ error?: string;
658
+ }>;
659
+ /** Called after a successful background removal. */
660
+ onAfterRemoveBg?: () => void;
661
+ /**
662
+ * Called before each auto-resize dimension is generated (deduct credits, check quota).
663
+ * Return `{ allowed: false, error: "..." }` to skip that dimension.
664
+ */
665
+ onBeforeAutoResize?: () => Promise<{
666
+ allowed: boolean;
667
+ error?: string;
668
+ }>;
669
+ /** Called after each successfully generated auto-resize dimension. */
670
+ onAfterAutoResize?: () => void;
671
+ /**
672
+ * OpenRouter model ID used for AI image generation — covers both the auto-resize
673
+ * background regeneration and the agent chat `generate_image` tool.
674
+ * Pass the same value here and to `AIChatPanel.agentImageModel` to keep
675
+ * both surfaces on the same model with a single configuration.
676
+ * @default "google/gemini-3.1-flash-image-preview"
677
+ * @example "google/gemini-2.5-flash-image"
678
+ */
679
+ agentImageModel?: string;
680
+ /**
681
+ * OpenRouter model tag used by the auto-resize engine for HTML layout
682
+ * generation. This is the LLM call that figures out how to reflow the ad
683
+ * content into the target dimensions before Gemini regenerates the background.
684
+ * @default "google/gemini-3.1-flash-lite-preview"
685
+ * @example "openai/gpt-4o"
686
+ */
687
+ chatModel?: string;
688
+ /**
689
+ * Show the Library sidebar trigger button. Defaults to `false`.
690
+ * Set to `true` to show the library icon in the top-right area.
691
+ */
692
+ showLibraryButton?: boolean;
693
+ /**
694
+ * Callbacks for each action in the image edit toolbar
695
+ * (shown when an image element is selected on canvas).
696
+ * When callbacks are omitted, built-in toolbar actions are used.
697
+ */
698
+ imageEditToolbarCallbacks?: import("./components/ImageEditToolbar").ImageEditToolbarCallbacks;
699
+ /**
700
+ * Custom fonts to register in the canvas font system.
701
+ * Each entry maps a numeric family ID (use 2000+) to a font file URL.
702
+ * Registered fonts become available for text elements whose fontFamily
703
+ * matches the given familyId.
704
+ */
705
+ customFonts?: CustomFontSpec[];
706
+ /**
707
+ * Called when the user saves a template from the Template Builder.
708
+ */
709
+ onSaveTemplate?: (template: {
710
+ name: string;
711
+ campaignTag?: string;
712
+ label?: string;
713
+ width?: number;
714
+ height?: number;
715
+ canvasJson?: string;
716
+ thumbnailDataUrl?: string;
717
+ }) => void;
718
+ /**
719
+ * Fetch all available brand assets for the asset picker (in-canvas swap).
720
+ */
721
+ onFetchAllAssets?: () => Promise<Array<{
722
+ id: string;
723
+ name: string;
724
+ tags: string[];
725
+ assetType: string;
726
+ blobUrl: string;
727
+ }>>;
728
+ /**
729
+ * Search brand assets by query and optional type filter.
730
+ */
731
+ onSearchBrandAssets?: (query: string, type?: string) => Promise<Array<{
732
+ id: string;
733
+ name: string;
734
+ tags: string[];
735
+ assetType: string;
736
+ blobUrl: string;
737
+ }>>;
738
+ /**
739
+ * List brand templates, optionally filtered by campaignTag.
740
+ */
741
+ onListBrandTemplates?: (keywords?: string[]) => Promise<Array<{
742
+ id: string;
743
+ name: string;
744
+ campaignTag?: string;
745
+ label?: string;
746
+ width?: number;
747
+ height?: number;
748
+ thumbnailBlobUrl?: string;
749
+ }>>;
750
+ /**
751
+ * Fetch the full canvas JSON for a specific template by ID.
752
+ */
753
+ onGetTemplateVariant?: (templateId: string) => Promise<{
754
+ canvasJson: string;
755
+ }>;
756
+ /**
757
+ * Search brand image assets, ad creatives, or templates by keywords and
758
+ * return top 3 matches with base64 preview images. Used by the agent's
759
+ * `find_brand_asset` tool.
760
+ */
761
+ onFindBrandAssets?: (type: "image-asset" | "ad-creative" | "template", keywords: string[]) => Promise<{
762
+ results: Array<{
763
+ id: string;
764
+ name: string;
765
+ tags?: string[];
766
+ width?: number | null;
767
+ height?: number | null;
768
+ previewDataUrl: string;
769
+ }>;
770
+ }>;
500
771
  }
501
772
  export type SceneData = {
502
773
  elements?: ImportedDataState["elements"];
@@ -517,6 +788,7 @@ export type CanvasActions = Partial<{
517
788
  saveToActiveFile: boolean;
518
789
  toggleTheme: boolean | null;
519
790
  saveAsImage: boolean;
791
+ scrollBackToContent: boolean;
520
792
  }>;
521
793
  export type UIOptions = Partial<{
522
794
  dockedSidebarBreakpoint: number;
@@ -549,6 +821,7 @@ export type AppProps = Merge<ExcalidrawProps, {
549
821
  export type AppClassProperties = {
550
822
  props: AppProps;
551
823
  state: AppState;
824
+ actionManager: App["actionManager"];
552
825
  interactiveCanvas: HTMLCanvasElement | null;
553
826
  /** static canvas */
554
827
  canvas: HTMLCanvasElement;
@@ -578,8 +851,10 @@ export type AppClassProperties = {
578
851
  insertEmbeddableElement: App["insertEmbeddableElement"];
579
852
  onMagicframeToolSelect: App["onMagicframeToolSelect"];
580
853
  onImageGeneratorSelect: App["onImageGeneratorSelect"];
854
+ onVideoGeneratorSelect: App["onVideoGeneratorSelect"];
581
855
  insertGeneratedImageIntoFrame: App["insertGeneratedImageIntoFrame"];
582
856
  insertGeneratedImageNearElement: App["insertGeneratedImageNearElement"];
857
+ insertGeneratedVideoIntoFrame: App["insertGeneratedVideoIntoFrame"];
583
858
  getName: App["getName"];
584
859
  dismissLinearEditor: App["dismissLinearEditor"];
585
860
  flowChartCreator: App["flowChartCreator"];
@@ -590,11 +865,18 @@ export type AppClassProperties = {
590
865
  visibleElements: App["visibleElements"];
591
866
  excalidrawContainerValue: App["excalidrawContainerValue"];
592
867
  getSceneElements: App["getSceneElements"];
868
+ updateScene: App["updateScene"];
593
869
  onPointerUpEmitter: App["onPointerUpEmitter"];
594
870
  updateEditorAtom: App["updateEditorAtom"];
595
871
  onPointerDownEmitter: App["onPointerDownEmitter"];
596
872
  lastPointerMoveCoords: App["lastPointerMoveCoords"];
597
873
  bindModeHandler: App["bindModeHandler"];
874
+ refresh: App["refresh"];
875
+ refreshEditorInterface: App["refreshEditorInterface"];
876
+ lassoTrail: App["lassoTrail"];
877
+ toggleSidebar: App["toggleSidebar"];
878
+ insertVideos: App["insertVideos"];
879
+ onVideoToolbarButtonClick: App["onVideoToolbarButtonClick"];
598
880
  };
599
881
  export type PointerDownState = Readonly<{
600
882
  origin: Readonly<{
@@ -0,0 +1,23 @@
1
+ import type { BrandContext } from "../types";
2
+ /**
3
+ * Converts a BrandContext object to a concise text block describing brand
4
+ * identity guidelines. Used as a system/prompt prefix for both the agent loop
5
+ * and direct image generation panels.
6
+ */
7
+ export declare function buildBrandContextMessage(ctx: BrandContext): string;
8
+ /**
9
+ * Augments a raw user prompt with strong brand asset instructions — identical to
10
+ * the approach used by execGenerateImage in the AI chat agent. Call this in
11
+ * ImageGeneratorPanel and ImageQuickEditPanel before invoking callOpenRouterImageAPI
12
+ * so that direct-generation panels produce the same brand-faithful output as the
13
+ * agent loop.
14
+ *
15
+ * Brand DNA text (colors, visual style, etc.) should be passed separately as
16
+ * `brandImages.brandContextText` in callOpenRouterImageAPI so it's prepended as a
17
+ * block before the prompt. This function only appends the per-asset mandatory
18
+ * instructions that reference the visual attachments by position.
19
+ */
20
+ export declare function buildImageGenSafePrompt(prompt: string, brandContext: BrandContext, dimensions?: {
21
+ width: number;
22
+ height: number;
23
+ }): string;
@@ -0,0 +1,19 @@
1
+ export declare function callOpenRouterImageAPI(prompt: string, modelId: string, aspectRatio: string, imageSize: string | null, textOutput: boolean, imageGenUrl: string, referenceImageDataUrl?: string, signal?: AbortSignal, brandImages?: {
2
+ logo?: string;
3
+ fontPreview?: string;
4
+ /** Optional second font preview (brand body typeface) shown as a reference. */
5
+ fontPreviewBody?: string;
6
+ /**
7
+ * Fetchable URL of the real headline font file (.ttf/.otf). Only Sourceful
8
+ * Riverflow v2+ consumes this — sent via `image_config.font_inputs` so the
9
+ * model renders text in the actual brand typeface (not just a preview img).
10
+ */
11
+ fontUrl?: string;
12
+ /** Text to render with `fontUrl` for the font_inputs entry. */
13
+ fontText?: string;
14
+ /**
15
+ * Full brand identity context text (colors, typography, visual style, etc.)
16
+ * prepended to the prompt so the model applies brand guidelines to the image.
17
+ */
18
+ brandContextText?: string;
19
+ }): Promise<string>;
@@ -0,0 +1,30 @@
1
+ export interface VideoJobParams {
2
+ model: string;
3
+ prompt: string;
4
+ aspectRatio: string;
5
+ duration?: number;
6
+ resolution?: string;
7
+ firstFrameDataUrl?: string;
8
+ lastFrameDataUrl?: string;
9
+ audio?: boolean;
10
+ negativePrompt?: string;
11
+ inputReferences?: string[];
12
+ seed?: number;
13
+ }
14
+ export interface VideoJobResult {
15
+ videoPresignedUrl: string;
16
+ }
17
+ /**
18
+ * Submit a video generation job to the host proxy.
19
+ * Returns { jobId } immediately — the job runs async on OpenRouter.
20
+ */
21
+ export declare function submitVideoJob(params: VideoJobParams, videoGenUrl: string): Promise<{
22
+ jobId: string;
23
+ }>;
24
+ /**
25
+ * Poll the host status endpoint until the job is done or failed.
26
+ * onProgress is called with values 0–1 as they arrive.
27
+ * Resolves with { videoPresignedUrl } on success.
28
+ * Rejects with an Error on failure or abort.
29
+ */
30
+ export declare function pollVideoJob(jobId: string, videoGenStatusUrl: string, onProgress: (progress: number) => void, signal?: AbortSignal): Promise<VideoJobResult>;
@@ -1,5 +1,5 @@
1
1
  import { type GlobalPoint, type LocalPoint } from "@orangecatai/math";
2
- import type { ElementsMap, ExcalidrawBindableElement, ExcalidrawDiamondElement, ExcalidrawElement, ExcalidrawEllipseElement, ExcalidrawEmbeddableElement, ExcalidrawFrameLikeElement, ExcalidrawFreeDrawElement, ExcalidrawIframeElement, ExcalidrawImageElement, ExcalidrawLinearElement, ExcalidrawRectangleElement, ExcalidrawSelectionElement, ExcalidrawTextElement } from "@orangecatai/element/types";
2
+ import type { ElementsMap, ExcalidrawBindableElement, ExcalidrawDiamondElement, ExcalidrawElement, ExcalidrawEllipseElement, ExcalidrawEmbeddableElement, ExcalidrawFrameLikeElement, ExcalidrawFreeDrawElement, ExcalidrawIframeElement, ExcalidrawImageElement, ExcalidrawVideoElement, ExcalidrawLinearElement, ExcalidrawRectangleElement, ExcalidrawSelectionElement, ExcalidrawTextElement } from "@orangecatai/element/types";
3
3
  import type { Curve, LineSegment, Polygon, Radians } from "@orangecatai/math";
4
4
  import type { Drawable, Op } from "roughjs/bin/core";
5
5
  export type Polyline<Point extends GlobalPoint | LocalPoint> = LineSegment<Point>[];
@@ -29,7 +29,7 @@ export type GeometricShape<Point extends GlobalPoint | LocalPoint> = {
29
29
  type: "polycurve";
30
30
  data: Polycurve<Point>;
31
31
  };
32
- type RectangularElement = ExcalidrawRectangleElement | ExcalidrawDiamondElement | ExcalidrawFrameLikeElement | ExcalidrawEmbeddableElement | ExcalidrawImageElement | ExcalidrawIframeElement | ExcalidrawTextElement | ExcalidrawSelectionElement;
32
+ type RectangularElement = ExcalidrawRectangleElement | ExcalidrawDiamondElement | ExcalidrawFrameLikeElement | ExcalidrawEmbeddableElement | ExcalidrawImageElement | ExcalidrawVideoElement | ExcalidrawIframeElement | ExcalidrawTextElement | ExcalidrawSelectionElement;
33
33
  export declare const getPolygonShape: <Point extends GlobalPoint | LocalPoint>(element: RectangularElement) => GeometricShape<Point>;
34
34
  export declare const getSelectionBoxShape: <Point extends GlobalPoint | LocalPoint>(element: ExcalidrawElement, elementsMap: ElementsMap, padding?: number) => GeometricShape<Point>;
35
35
  export declare const getEllipseShape: <Point extends GlobalPoint | LocalPoint>(element: ExcalidrawEllipseElement) => GeometricShape<Point>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orangecatai/element",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "type": "module",
5
5
  "types": "./dist/types/element/src/index.d.ts",
6
6
  "main": "./dist/prod/index.js",
@@ -63,7 +63,7 @@
63
63
  "build:esm": "rimraf dist && node ../../scripts/buildBase.js && yarn gen:types"
64
64
  },
65
65
  "dependencies": {
66
- "@orangecatai/common": "0.0.2",
66
+ "@orangecatai/common": "0.0.4",
67
67
  "@orangecatai/math": "0.0.2"
68
68
  }
69
69
  }
@@ -1 +0,0 @@
1
- export declare function resolveGeminiApiKey(propKey?: string): string;