@scrawl-board/board 0.1.0-beta.10 → 0.1.0-beta.11

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/dist/browser.d.ts CHANGED
@@ -1369,6 +1369,13 @@ interface BoardSnapshot {
1369
1369
  readonly readOnly: boolean;
1370
1370
  readonly selection: readonly string[];
1371
1371
  readonly focusedItem: FocusedItem | null;
1372
+ /**
1373
+ * What an inline editor currently covers, as last set through
1374
+ * `view.setInlineEditing` — a text block (`{ id }`) or a table cell
1375
+ * (`{ id, row, col }`), else null. Chrome uses it to stay out of an open
1376
+ * editor's way.
1377
+ */
1378
+ readonly inlineEditing: InlineEditingTarget | null;
1372
1379
  readonly strokeCount: number;
1373
1380
  readonly objectCount: number;
1374
1381
  readonly canUndo: boolean;
@@ -1392,6 +1399,18 @@ interface BoardSnapshot {
1392
1399
  * shape doesn't carry a holder name, so it always reports `locked: false`
1393
1400
  * here, matching the engine's own internal selection-badge behavior.
1394
1401
  */
1402
+ /** Axis-aligned bounds in board space (y up). */
1403
+ interface BoardBounds {
1404
+ readonly minX: number;
1405
+ readonly minY: number;
1406
+ readonly maxX: number;
1407
+ readonly maxY: number;
1408
+ }
1409
+ interface InlineEditingTarget {
1410
+ readonly id: string;
1411
+ readonly row?: number;
1412
+ readonly col?: number;
1413
+ }
1395
1414
  interface FocusedItem {
1396
1415
  readonly type: "stroke" | "note" | "text" | "table" | "image" | "timer" | "rectangle" | "ellipse" | "group" | "line" | "arrow" | "polygon" | "star" | "heart" | "custom";
1397
1416
  readonly id: string;
@@ -2184,10 +2203,14 @@ interface BoardController {
2184
2203
  get(id: string): DeepReadonly<BoardObject> | undefined;
2185
2204
  all(): readonly DeepReadonly<BoardObject>[];
2186
2205
  search(query: string): readonly SearchHit[];
2206
+ /** An object's axis-aligned board-space bounds (y up), or undefined for an unknown id. */
2207
+ bounds(id: string): BoardBounds | undefined;
2187
2208
  };
2188
2209
  /** Host-owned comments, synced in for search and marker rendering only — see CommentMarker. */
2189
2210
  readonly comments: {
2190
2211
  sync(comments: readonly CommentMarker[]): void;
2212
+ /** The markers last passed to `sync`, in the order given. */
2213
+ list(): readonly CommentMarker[];
2191
2214
  open(id: string): void;
2192
2215
  setActive(id: string | null): void;
2193
2216
  };
@@ -2294,4 +2317,4 @@ interface CreateMemoryPersistenceOptions {
2294
2317
  declare function createMemoryPersistence(options?: CreateMemoryPersistenceOptions): PersistenceAdapter;
2295
2318
 
2296
2319
  export { AssetResolutionError, EMOJI_LIBRARY, ICON_LIBRARY, STAMPS, SUPPORTED_ASSET_MEDIA_TYPES, assetRef, clampAssetCacheBytes, cloneCustomObject, createBoardController, createLocalBoard, createMemoryPersistence, emojiDataUrl, iconCategories, iconDataUrl, isAssetRef, isEmojiName, isIconName, isStampKind, isStickerKind, stampDataUrl, stickerLabel };
2297
- export type { ApplyOpsResult, AssetDiagnostic, AssetExportFailure, AssetIngestRequest, AssetIngestResult, AssetIngestor, AssetKind, AssetPurpose, AssetRef, AssetResolutionErrorCode, AssetResolveRequest, AssetResolveResult, AssetResolver, BoardController, BoardControllerError, BoardEventMap, BoardKeyInput, BoardNotebook, BoardObject, BoardObjectInput, BoardObjectPatch, BoardPage, BoardPointerInput, BoardScene, BoardSection, BoardSnapshot, BoardStyle, BoardThemeOptions, BoardView, BuiltInTool, CollaborationAckDiagnostic, CollaborationAdapter, CollaborationReceiver, CollaborationSession, CollaborationSnapshot, CollaborationSyncResult, CollaboratorIdentity, CommentMarker, ControllerOp, CreateBoardControllerOptions, CreateMemoryPersistenceOptions, CustomBoardObject, CustomObjectAddInput, CustomObjectDefinition, CustomTool, CustomToolDefinition, DeepReadonly, DocumentContext, EmojiDefinition, EmojiName, ExportDocumentSVGOptions, ExportDocumentSVGResult, ExtensionCommand, ExtensionDiagnostic, ExtensionHitResult, ExtensionId, ExtensionRequirement, FocusedItem, IconDefinition, IconName, InputModifiers, JsonObject, JsonValue, LoadResult, LocalBoard, LocalBoardOptions, LocalBoardSnapshot, LocalPresence, Mat2x3, ObjectDescribeContext, ObjectIntent, ObjectType, PersistenceAdapter, PersistenceDiagnostic, PersistenceSnapshot, PresenceCursor, PresenceUser, PresenceView, QueryableBoardObject, ReadonlyBoardDocument, ReadonlyCustomObject, ReadonlyDocumentChange, ReplaceResult, SceneEllipse, SceneGroup, SceneImage, ScenePath, SceneRect, SceneText, ScrawlExtension, ScreenPoint, ScreenRect, SearchHit, SearchHitKind, SearchableComment, StampKind, StickerKind, SupportedAssetMediaType, ToolCancelReason, ToolCapabilities, ToolCursor, ToolId };
2320
+ export type { ApplyOpsResult, AssetDiagnostic, AssetExportFailure, AssetIngestRequest, AssetIngestResult, AssetIngestor, AssetKind, AssetPurpose, AssetRef, AssetResolutionErrorCode, AssetResolveRequest, AssetResolveResult, AssetResolver, BoardBounds, BoardController, BoardControllerError, BoardEventMap, BoardKeyInput, BoardNotebook, BoardObject, BoardObjectInput, BoardObjectPatch, BoardPage, BoardPoint, BoardPointerInput, BoardScene, BoardSection, BoardSnapshot, BoardStyle, BoardThemeOptions, BoardView, BuiltInTool, CollaborationAckDiagnostic, CollaborationAdapter, CollaborationReceiver, CollaborationSession, CollaborationSnapshot, CollaborationSyncResult, CollaboratorIdentity, CommentMarker, ControllerOp, CreateBoardControllerOptions, CreateMemoryPersistenceOptions, CustomBoardObject, CustomObjectAddInput, CustomObjectDefinition, CustomTool, CustomToolDefinition, DeepReadonly, DocumentContext, EmojiDefinition, EmojiName, ExportDocumentSVGOptions, ExportDocumentSVGResult, ExtensionCommand, ExtensionDiagnostic, ExtensionHitResult, ExtensionId, ExtensionRequirement, FocusedItem, IconDefinition, IconName, InlineEditingTarget, InputModifiers, JsonObject, JsonValue, LoadResult, LocalBoard, LocalBoardOptions, LocalBoardSnapshot, LocalPresence, Mat2x3, ObjectDescribeContext, ObjectIntent, ObjectType, PersistenceAdapter, PersistenceDiagnostic, PersistenceSnapshot, PresenceCursor, PresenceUser, PresenceView, QueryableBoardObject, ReadonlyBoardDocument, ReadonlyCustomObject, ReadonlyDocumentChange, ReplaceResult, SceneEllipse, SceneGroup, SceneImage, ScenePath, SceneRect, SceneText, ScrawlExtension, ScreenPoint, ScreenRect, SearchHit, SearchHitKind, SearchableComment, StampKind, StickerKind, SupportedAssetMediaType, ToolCancelReason, ToolCapabilities, ToolCursor, ToolId };
package/dist/browser.js CHANGED
@@ -5778,12 +5778,35 @@ function toDataUri(bytes, mediaType) {
5778
5778
  return `data:${mediaType};base64,${btoa(binary)}`;
5779
5779
  }
5780
5780
  //#endregion
5781
+ //#region src/persistence/adapters/imageDecode.ts
5782
+ var ORIENTED = { imageOrientation: "from-image" };
5783
+ /**
5784
+ * Decodes image bytes the way a browser displays them: EXIF orientation
5785
+ * applied, so a phone photo comes out upright and its width/height are the
5786
+ * displayed ones.
5787
+ *
5788
+ * `"from-image"` is already the default in every browser this SDK supports
5789
+ * (Chrome/Edge 112+, Firefox 111+, Safari 16+); passing it just makes that
5790
+ * explicit. Engines from before `"none"` was renamed to `"from-image"` reject
5791
+ * the value with a TypeError — they get their own default decode instead of
5792
+ * no image at all.
5793
+ */
5794
+ async function decodeImageBitmap(blob) {
5795
+ try {
5796
+ return await createImageBitmap(blob, ORIENTED);
5797
+ } catch (error) {
5798
+ if (error instanceof TypeError) return createImageBitmap(blob);
5799
+ throw error;
5800
+ }
5801
+ }
5802
+ //#endregion
5781
5803
  //#region src/persistence/adapters/assetIngestion.ts
5804
+ /** Displayed dimensions — EXIF orientation applied, so a portrait phone photo measures as portrait. */
5782
5805
  async function decodeDimensionsWithImageBitmap(bytes, mediaType) {
5783
5806
  const blob = new Blob([bytes], { type: mediaType });
5784
5807
  let bitmap;
5785
5808
  try {
5786
- bitmap = await createImageBitmap(blob);
5809
+ bitmap = await decodeImageBitmap(blob);
5787
5810
  } catch (cause) {
5788
5811
  throw new AssetResolutionError("decode-failed", false, cause instanceof Error ? cause.message : String(cause));
5789
5812
  }
@@ -5973,10 +5996,7 @@ var AssetTextureCache = class {
5973
5996
  }
5974
5997
  let texture;
5975
5998
  try {
5976
- const bitmap = await createImageBitmap(new Blob([outcome.bytes], { type: outcome.mediaType }));
5977
- texture = new THREE.Texture(bitmap);
5978
- texture.colorSpace = THREE.SRGBColorSpace;
5979
- texture.needsUpdate = true;
5999
+ texture = uprightBitmapTexture(await decodeImageBitmap(new Blob([outcome.bytes], { type: outcome.mediaType })));
5980
6000
  } catch (cause) {
5981
6001
  onError(toDecodeError(cause, ref));
5982
6002
  return;
@@ -6031,6 +6051,23 @@ var AssetTextureCache = class {
6031
6051
  function toDecodeError(cause, ref) {
6032
6052
  return new AssetResolutionError("decode-failed", false, cause instanceof Error ? cause.message : String(cause), ref);
6033
6053
  }
6054
+ /**
6055
+ * A texture that shows `bitmap` the right way up. Three.js normally flips an
6056
+ * image vertically on upload (`flipY`) to match WebGL's bottom-up texture
6057
+ * rows, but WebGL ignores that flag for ImageBitmap sources — so every
6058
+ * bitmap-backed image drew upside-down. The flip happens in the texture's UV
6059
+ * transform instead, which every material using this shared texture (built-in
6060
+ * images and Custom SceneImages alike) picks up.
6061
+ */
6062
+ function uprightBitmapTexture(bitmap) {
6063
+ const texture = new THREE.Texture(bitmap);
6064
+ texture.colorSpace = THREE.SRGBColorSpace;
6065
+ texture.flipY = false;
6066
+ texture.repeat.set(1, -1);
6067
+ texture.offset.set(0, 1);
6068
+ texture.needsUpdate = true;
6069
+ return texture;
6070
+ }
6034
6071
  //#endregion
6035
6072
  //#region src/renderer/canvas/raycast.ts
6036
6073
  var origin$1 = new THREE.Vector3();
@@ -19308,7 +19345,7 @@ var ScrawlEngine = class {
19308
19345
  this.eraserRadius = 2;
19309
19346
  this.tableRows = 3;
19310
19347
  this.tableCols = 3;
19311
- this.tool = "marker";
19348
+ this.tool = "select";
19312
19349
  this.voter = null;
19313
19350
  this.stampKind = "emoji:grinning";
19314
19351
  this.timerDurationMs = TIMER_DEFAULT_DURATION_MS;
@@ -21141,7 +21178,8 @@ function createBoardControllerWithEngine(options, existingEngine) {
21141
21178
  const storeListeners = /* @__PURE__ */ new Set();
21142
21179
  const eventListeners = /* @__PURE__ */ new Map();
21143
21180
  const documentListeners = /* @__PURE__ */ new Set();
21144
- let tool = "marker";
21181
+ let tool = "select";
21182
+ let inlineEditing = null;
21145
21183
  let style = Object.freeze({
21146
21184
  inkColor: "#1C1C1E",
21147
21185
  highlightColor: HIGHLIGHT_COLORS.yellow,
@@ -21716,6 +21754,7 @@ function createBoardControllerWithEngine(options, existingEngine) {
21716
21754
  readOnly,
21717
21755
  selection: Object.freeze([...selection]),
21718
21756
  focusedItem: computeFocusedItem(),
21757
+ inlineEditing,
21719
21758
  strokeCount: [...document.all()].length,
21720
21759
  objectCount: allObjects().length,
21721
21760
  canUndo: history.canUndo,
@@ -22342,6 +22381,8 @@ function createBoardControllerWithEngine(options, existingEngine) {
22342
22381
  setInlineEditing(target) {
22343
22382
  assertActive();
22344
22383
  engine?.setInlineEditing(target);
22384
+ inlineEditing = target ? { ...target } : null;
22385
+ changed();
22345
22386
  },
22346
22387
  centerOn(point) {
22347
22388
  assertActive();
@@ -22787,6 +22828,15 @@ function createBoardControllerWithEngine(options, existingEngine) {
22787
22828
  query: {
22788
22829
  get: readObject,
22789
22830
  all: () => allObjects(),
22831
+ bounds: (id) => {
22832
+ const box = document.bbox(id);
22833
+ return box ? {
22834
+ minX: box.minX,
22835
+ minY: box.minY,
22836
+ maxX: box.maxX,
22837
+ maxY: box.maxY
22838
+ } : void 0;
22839
+ },
22790
22840
  search: (query) => searchBoard(query, {
22791
22841
  notes: document.allNotes(),
22792
22842
  texts: document.allTexts(),
@@ -22797,6 +22847,7 @@ function createBoardControllerWithEngine(options, existingEngine) {
22797
22847
  })
22798
22848
  },
22799
22849
  comments: {
22850
+ list: () => comments,
22800
22851
  sync(next) {
22801
22852
  comments = Object.freeze([...next]);
22802
22853
  if (engine) engine.setComments(comments);
package/dist/index.d.ts CHANGED
@@ -2539,6 +2539,13 @@ interface BoardSnapshot {
2539
2539
  readonly readOnly: boolean;
2540
2540
  readonly selection: readonly string[];
2541
2541
  readonly focusedItem: FocusedItem | null;
2542
+ /**
2543
+ * What an inline editor currently covers, as last set through
2544
+ * `view.setInlineEditing` — a text block (`{ id }`) or a table cell
2545
+ * (`{ id, row, col }`), else null. Chrome uses it to stay out of an open
2546
+ * editor's way.
2547
+ */
2548
+ readonly inlineEditing: InlineEditingTarget | null;
2542
2549
  readonly strokeCount: number;
2543
2550
  readonly objectCount: number;
2544
2551
  readonly canUndo: boolean;
@@ -2562,6 +2569,18 @@ interface BoardSnapshot {
2562
2569
  * shape doesn't carry a holder name, so it always reports `locked: false`
2563
2570
  * here, matching the engine's own internal selection-badge behavior.
2564
2571
  */
2572
+ /** Axis-aligned bounds in board space (y up). */
2573
+ interface BoardBounds {
2574
+ readonly minX: number;
2575
+ readonly minY: number;
2576
+ readonly maxX: number;
2577
+ readonly maxY: number;
2578
+ }
2579
+ interface InlineEditingTarget {
2580
+ readonly id: string;
2581
+ readonly row?: number;
2582
+ readonly col?: number;
2583
+ }
2565
2584
  interface FocusedItem {
2566
2585
  readonly type: "stroke" | "note" | "text" | "table" | "image" | "timer" | "rectangle" | "ellipse" | "group" | "line" | "arrow" | "polygon" | "star" | "heart" | "custom";
2567
2586
  readonly id: string;
@@ -3354,10 +3373,14 @@ interface BoardController {
3354
3373
  get(id: string): DeepReadonly<BoardObject> | undefined;
3355
3374
  all(): readonly DeepReadonly<BoardObject>[];
3356
3375
  search(query: string): readonly SearchHit[];
3376
+ /** An object's axis-aligned board-space bounds (y up), or undefined for an unknown id. */
3377
+ bounds(id: string): BoardBounds | undefined;
3357
3378
  };
3358
3379
  /** Host-owned comments, synced in for search and marker rendering only — see CommentMarker. */
3359
3380
  readonly comments: {
3360
3381
  sync(comments: readonly CommentMarker[]): void;
3382
+ /** The markers last passed to `sync`, in the order given. */
3383
+ list(): readonly CommentMarker[];
3361
3384
  open(id: string): void;
3362
3385
  setActive(id: string | null): void;
3363
3386
  };
@@ -3558,6 +3581,62 @@ declare const scrawlThemePresets: Readonly<Record<ScrawlThemePreset, Readonly<Re
3558
3581
  declare function validateScrawlTheme(theme: ScrawlTheme | Record<string, unknown>): ScrawlThemeDiagnostic[];
3559
3582
  declare function resolveScrawlTheme(preset?: ScrawlThemePreset, theme?: ScrawlTheme | Record<string, unknown>): ScrawlResolvedTheme;
3560
3583
 
3584
+ /** Access levels, shown as View / Edit / Admin. Map your backend's roles onto these. */
3585
+ type BoardRole = "viewer" | "editor" | "admin";
3586
+ interface BoardMember {
3587
+ id: string;
3588
+ name: string;
3589
+ email?: string;
3590
+ avatarUrl?: string;
3591
+ online?: boolean;
3592
+ role: BoardRole;
3593
+ }
3594
+ interface BoardRoleChange {
3595
+ memberId: string;
3596
+ role: BoardRole;
3597
+ }
3598
+ interface BoardPermissions {
3599
+ members: readonly BoardMember[];
3600
+ /** Marks "(you)" and keeps your own access level from being changed here. */
3601
+ currentUserId?: string;
3602
+ /** Whether "Manage permissions" is offered at all — your rule, from your backend. */
3603
+ canManage: boolean;
3604
+ /**
3605
+ * Called with every pending change when Save is pressed. Resolve once your
3606
+ * backend accepted them; reject to show the error and keep them pending.
3607
+ * Nothing changes until your backend says so — update `members` afterwards.
3608
+ */
3609
+ onSave(changes: readonly BoardRoleChange[]): Promise<void>;
3610
+ }
3611
+ type BoardActivityKind = "added" | "removed" | "updated" | "commented" | "shared" | "exported";
3612
+ interface BoardActivityEntry {
3613
+ id: string;
3614
+ kind: BoardActivityKind;
3615
+ /** e.g. "Added a sticky note". */
3616
+ title: string;
3617
+ actorName?: string;
3618
+ /** When it happened (ms since epoch or ISO string). */
3619
+ at: number | string;
3620
+ /** Board point to jump to, if the action has a place on the board. */
3621
+ location?: BoardPoint;
3622
+ }
3623
+ interface BoardActivityFeed {
3624
+ /** Newest first. Omit to show this session's own actions instead. */
3625
+ entries?: readonly BoardActivityEntry[];
3626
+ unreadCount?: number;
3627
+ onMarkAllRead?(): void;
3628
+ }
3629
+ interface BoardCommentFeed {
3630
+ unreadCount?: number;
3631
+ onMarkAllRead?(): void;
3632
+ }
3633
+ interface BoardMenuItem {
3634
+ id: string;
3635
+ label: string;
3636
+ icon?: ReactNode;
3637
+ onSelect(): void;
3638
+ }
3639
+
3561
3640
  interface CommentAuthor {
3562
3641
  name: string;
3563
3642
  color?: string;
@@ -3578,6 +3657,26 @@ interface DefaultBoardChromeProps {
3578
3657
  icons?: Partial<Record<BuiltInTool, ReactNode>>;
3579
3658
  /** Name (and pin colour) shown on comments left through the default comment UI. Defaults to "You". */
3580
3659
  commentAuthor?: CommentAuthor;
3660
+ /**
3661
+ * Sharing is the Host's own (links, permissions, backends), so the board
3662
+ * actions only offer a Share button when this is supplied.
3663
+ */
3664
+ onShare?(): void;
3665
+ /**
3666
+ * Your backend's activity feed for the Recent Activity drawer. Without
3667
+ * `entries`, the drawer lists this session's own board actions.
3668
+ */
3669
+ activity?: BoardActivityFeed;
3670
+ /** Unread state for the Comments drawer's badge and "Mark all as read". */
3671
+ commentFeed?: BoardCommentFeed;
3672
+ /**
3673
+ * Members and access levels from your backend, for the permissions drawer
3674
+ * (offered in the More menu when `canManage`). The SDK never changes a role
3675
+ * itself: Save calls `onSave`, and your backend decides.
3676
+ */
3677
+ permissions?: BoardPermissions;
3678
+ /** Extra More-menu actions your app provides (board settings, version history, duplicate…). */
3679
+ menuItems?: readonly BoardMenuItem[];
3581
3680
  }
3582
3681
 
3583
3682
  /**
@@ -3586,7 +3685,7 @@ interface DefaultBoardChromeProps {
3586
3685
  * Turn either off when the Host handles `comment-draft-request`/
3587
3686
  * `comment-open-request` or `import-request` itself.
3588
3687
  */
3589
- type DefaultUIRegion = "tools" | "history" | "view" | "style" | "search" | "import" | "export" | "inlineEditing" | "styleShelf" | "focusedItemToolbar" | "emptyState" | "pages" | "comments" | "images";
3688
+ type DefaultUIRegion = "tools" | "history" | "view" | "style" | "search" | "import" | "export" | "inlineEditing" | "styleShelf" | "focusedItemToolbar" | "emptyState" | "pages" | "comments" | "images" | "activity";
3590
3689
  /** Props for the toolbar/topBar/stylePanel/contextMenu slots. */
3591
3690
  interface BoardSlotProps {
3592
3691
  controller: BoardController;
@@ -3614,7 +3713,7 @@ interface DefaultUISlots {
3614
3713
  */
3615
3714
  contextMenu?: ComponentType<BoardSlotProps> | null;
3616
3715
  }
3617
- declare function DefaultBoardChrome({ controller, snapshot, renderPortal, className, style, regions, slots, icons, commentAuthor }: DefaultBoardChromeProps): react.JSX.Element;
3716
+ declare function DefaultBoardChrome({ controller, snapshot, renderPortal, className, style, regions, slots, icons, commentAuthor, onShare, activity, commentFeed, permissions, menuItems }: DefaultBoardChromeProps): react.JSX.Element;
3618
3717
 
3619
3718
  interface InlineEditorsProps {
3620
3719
  controller: BoardController;
@@ -3647,9 +3746,11 @@ interface FocusedItemToolbarProps {
3647
3746
  * Floating toolbar above the focused note, shape, text block, or semantic
3648
3747
  * Rectangle/Ellipse — Colour, Size (note/text) or Width (shape), Fill/Stroke
3649
3748
  * (Rectangle/Ellipse), Lock/Unlock, Duplicate, Delete. Images (photos and
3650
- * placed emoji/icons) get Lock/Duplicate/Delete only — the native gizmo
3651
- * already resizes them. Table/timer/custom objects and plain (non-shape) ink
3652
- * strokes never get a toolbar here — out of scope for this destination.
3749
+ * placed emoji/icons) and tables get Lock/Duplicate/Delete only — each
3750
+ * already has its own resize affordance (the native gizmo for images, edge
3751
+ * handles for tables), and a table's row/column actions live in its cell
3752
+ * editor. Timer/custom objects and plain (non-shape) ink strokes never get a
3753
+ * toolbar here — out of scope for this destination.
3653
3754
  *
3654
3755
  * Rectangle/Ellipse (Phase 2) are a second, parallel "shape" concept from
3655
3756
  * the legacy ink-stroke shape below: both draw from the same toolbar
@@ -3743,6 +3844,16 @@ interface ScrawlProps extends Omit<CreateBoardControllerOptions, "canvas"> {
3743
3844
  * SDK's default UI). See DefaultBoardChromeProps.icons.
3744
3845
  */
3745
3846
  icons?: Partial<Record<BuiltInTool, ReactNode>>;
3847
+ /** Offer a Share button in the default UI's board actions — see DefaultBoardChromeProps.onShare. */
3848
+ onShare?(): void;
3849
+ /** Your backend's activity feed — see DefaultBoardChromeProps.activity. */
3850
+ activity?: BoardActivityFeed;
3851
+ /** Unread state for the Comments drawer — see DefaultBoardChromeProps.commentFeed. */
3852
+ commentFeed?: BoardCommentFeed;
3853
+ /** Members and access levels from your backend — see DefaultBoardChromeProps.permissions. */
3854
+ permissions?: BoardPermissions;
3855
+ /** Extra More-menu actions — see DefaultBoardChromeProps.menuItems. */
3856
+ menuItems?: readonly BoardMenuItem[];
3746
3857
  }
3747
3858
  /**
3748
3859
  * The fastest path to an embedded Board: creates and owns a
@@ -3755,7 +3866,7 @@ interface ScrawlProps extends Omit<CreateBoardControllerOptions, "canvas"> {
3755
3866
  * field except `canvas` (pass `canvas={null}` for a headless board, or an
3756
3867
  * existing `<canvas>` element to control its identity yourself).
3757
3868
  */
3758
- declare function Scrawl({ children, preset, theme, portalContainer, className, style, onReady, onError, onThemeDiagnostic, canvas: suppliedCanvas, icons, ...options }: ScrawlProps): react.JSX.Element;
3869
+ declare function Scrawl({ children, preset, theme, portalContainer, className, style, onReady, onError, onThemeDiagnostic, canvas: suppliedCanvas, icons, onShare, activity, commentFeed, permissions, menuItems, ...options }: ScrawlProps): react.JSX.Element;
3759
3870
  interface ScrawlCanvasProps {
3760
3871
  element?: HTMLCanvasElement;
3761
3872
  className?: string;
@@ -3774,8 +3885,18 @@ interface ScrawlDefaultUIProps {
3774
3885
  icons?: Partial<Record<BuiltInTool, ReactNode>>;
3775
3886
  /** Author shown on comments left through the default comment UI — see DefaultBoardChromeProps.commentAuthor. */
3776
3887
  commentAuthor?: CommentAuthor;
3777
- }
3778
- declare function ScrawlDefaultUI({ className, style, regions, slots, icons, commentAuthor }: ScrawlDefaultUIProps): react.JSX.Element;
3888
+ /** Supply to offer a Share button in the board actions — see DefaultBoardChromeProps.onShare. */
3889
+ onShare?(): void;
3890
+ /** Your backend's activity feed — see DefaultBoardChromeProps.activity. */
3891
+ activity?: BoardActivityFeed;
3892
+ /** Unread state for the Comments drawer — see DefaultBoardChromeProps.commentFeed. */
3893
+ commentFeed?: BoardCommentFeed;
3894
+ /** Members and access levels from your backend — see DefaultBoardChromeProps.permissions. */
3895
+ permissions?: BoardPermissions;
3896
+ /** Extra More-menu actions — see DefaultBoardChromeProps.menuItems. */
3897
+ menuItems?: readonly BoardMenuItem[];
3898
+ }
3899
+ declare function ScrawlDefaultUI({ className, style, regions, slots, icons, commentAuthor, onShare, activity, commentFeed, permissions, menuItems }: ScrawlDefaultUIProps): react.JSX.Element;
3779
3900
  declare function ScrawlPortal({ children }: {
3780
3901
  children: ReactNode;
3781
3902
  }): react.ReactPortal | null;
@@ -3825,4 +3946,4 @@ type ScrawlBoardProps = {
3825
3946
  declare function ScrawlBoard({ documentId, initialDocument, onReady, className, style }: ScrawlBoardProps): react.JSX.Element;
3826
3947
 
3827
3948
  export { ASSET_CACHE_BYTES_DEFAULT, ASSET_CACHE_BYTES_MAX, ASSET_CACHE_BYTES_MIN, ASSET_EXPORT_MAX_DECODED_MEGAPIXELS, ASSET_EXPORT_MAX_ENCODED_BYTES, ASSET_MAX_CONCURRENT_RESOLUTIONS, ASSET_MAX_DECODED_MEGAPIXELS, ASSET_MAX_DIMENSION_PX, ASSET_MAX_ENCODED_BYTES, ASSET_REF_MAX_BYTES, ASSET_REF_PATTERN, AddArrowCommand, AddEllipseCommand, AddGroupCommand, AddHeartCommand, AddImageCommand, AddLineCommand, AddNoteCommand, AddPolygonCommand, AddRectangleCommand, AddStarCommand, AddStrokesCommand, AddTableCommand, AddTextCommand, AddTimerCommand, AssetResolutionError, BEACON_INSET, BoardDocument, CURRENT_DOCUMENT_SCHEMA_VERSION, ClusterStore, CommandBatch, DefaultBoardChrome, DeleteArrowCommand, DeleteEllipseCommand, DeleteGroupCommand, DeleteHeartCommand, DeleteImageCommand, DeleteLineCommand, DeleteNoteCommand, DeletePolygonCommand, DeleteRectangleCommand, DeleteStarCommand, DeleteStrokesCommand, DeleteTableCommand, DeleteTextCommand, DeleteTimerCommand, DocumentRecoveryError, EMOJI_LIBRARY, END_TAPER, ERASE_THRESHOLD, EraseCommand, FOG_COLOR, FocusedItemToolbar, HIGHLIGHT_COLORS, History, ICON_LIBRARY, IDENTITY, INK_COLORS, InlineEditors, LockItemsCommand, MIN_WIDTH_FACTOR, MultiplayerCursors, NOTE_COLORS, NOTE_DEFAULT_SIZE, NOTE_DEFAULT_Z, NOTE_MAX_Z, NOTE_MIN_Z, NOTE_PEEL_STEP, ReorderObjectCommand, SDK_DEVELOPMENT_VERSION, SDK_PACKAGE_NAME, SHAPE_DEFAULT_STROKE, SHAPE_DEFAULT_STROKE_WIDTH, SHAPE_MIN_SIZE, SHAPE_STYLE_DEFAULTS, STAMPS, STAMP_SIZE, SUPPORTED_ASSET_MEDIA_TYPES, Scrawl, ScrawlBoard, ScrawlCanvas, ScrawlDefaultUI, ScrawlPortal, ScrawlProvider, SpatialIndex, StyleShelf, TABLE_DEFAULT_CELL_HEIGHT, TABLE_DEFAULT_CELL_WIDTH, TABLE_DEFAULT_FONT_SIZE, TEXT_DEFAULT_SIZE, TIMER_DEFAULT_DURATION_MS, TIMER_DEFAULT_SIZE, TIMER_PRESETS_MS, TransformCommand, TransformObjectsCommand, UpdateArrowCommand, UpdateEllipseCommand, UpdateGroupCommand, UpdateHeartCommand, UpdateImageCommand, UpdateLineCommand, UpdateNoteCommand, UpdatePolygonCommand, UpdateRectangleCommand, UpdateStarCommand, UpdateTableCommand, UpdateTextCommand, UpdateTimerCommand, apply, applyItemLock, assetRef, avgScale, canUnlockItem, changeToOps, clampAssetCacheBytes, cloneArrow, cloneCustomObject, cloneEllipse, cloneGroup, cloneHeart, cloneImage, cloneLine, cloneNote, clonePolygon, cloneRectangle, cloneStar, cloneStroke, cloneTable, cloneText, cloneTimer, createBoardController, createLocalBoard, createMemoryPersistence, documentId, documentSize, documentToSVG, emojiDataUrl, emojiDefinition, formatTimer, iconCategories, iconDataUrl, iconDefinition, invert, isAssetRef, isEmojiName, isIconName, isIdentity, isStampKind, isStickerKind, loadDocumentBytes, measureTable, measureTextBlock, migrateDocument, mul, pauseTimer, placePresenceBeacon, resolveScrawlTheme, ribbonEdges, rotationAbout, scalingAbout, scrawlThemePresets, searchBoard, serializeDocument, serializeLock, serializeStroke, setTimerDuration, stampDataUrl, startTimer, stickerDataUrl, stickerLabel, strokeId, timerExpired, timerRemaining, toggleTimer, translation, useCollaborationStatus, usePersistenceStatus, usePresence, useScrawlController, useScrawlSnapshot, useScrawlTheme, validateScrawlTheme };
3828
- export type { ApplyOpsResult, ArrowHeadStyle, ArrowObject, AssetDiagnostic, AssetExportFailure, AssetIngestRequest, AssetIngestResult, AssetIngestor, AssetKind, AssetPurpose, AssetRef, AssetResolutionErrorCode, AssetResolveRequest, AssetResolveResult, AssetResolver, BBox, BoardController, BoardControllerError, BoardEventMap, BoardKeyInput, BoardNotebook, BoardObject, BoardObjectInput, BoardObjectPatch, BoardPage, BoardPoint, BoardPointerInput, BoardScene, BoardSection, BoardSlotProps, BoardSnapshot, BoardStroke, BoardStyle, BoardThemeOptions, BoardView, BuiltInTool, ClusterIdFactory, CollaborationAckDiagnostic, CollaborationAdapter, CollaborationReceiver, CollaborationSession, CollaborationSnapshot, CollaborationSyncResult, CollaboratorIdentity, Command, CommandKind, CommentAuthor, CommentMarker, ConnectorBinding, ConnectorBox, ConnectorTarget, ControllerOp, CreateBoardControllerOptions, CreateMemoryPersistenceOptions, CurrentSerializedDocument, CurrentSerializedStroke, CustomBoardObject, CustomObjectAddInput, CustomObjectDefinition, CustomTool, CustomToolDefinition, DeepReadonly, DefaultBoardChromeProps, DefaultUIRegion, DefaultUISlot, DefaultUISlots, DialogSlotProps, DocumentChange, DocumentContext, DocumentId, DocumentLoadResult, DocumentRecoveryCode, EllipseObject, EmojiDefinition, EmojiName, ExportDocumentSVGOptions, ExportDocumentSVGResult, ExtensionCommand, ExtensionDiagnostic, ExtensionHitResult, ExtensionId, ExtensionRequirement, FocusedItem, FocusedItemToolbarProps, GroupObject, HeartObject, IconDefinition, IconName, ImageBlock, InlineEditorsProps, InputModifiers, JsonObject, JsonValue, KitchenTimer, LineObject, LoadResult, LocalBoard, LocalBoardOptions, LocalBoardSnapshot, LocalPresence, LockHolder, LockTarget, Lockable, Mat2x3, MultiplayerCursorsProps, NoteVote, ObjectDescribeContext, ObjectIntent, ObjectType, Op, OpCollection, PersistenceAdapter, PersistenceDiagnostic, PersistenceSnapshot, PolygonObject, PresenceCursor, PresencePlacement, PresenceUser, PresenceView, QueryableBoardObject, ReadonlyBoardDocument, ReadonlyCustomObject, ReadonlyDocumentChange, RectangleObject, ReorderDirection, ReplaceResult, RibbonEdgePoint, SceneEllipse, SceneGroup, SceneImage, ScenePath, SceneRect, SceneText, ScrawlBoardProps, ScrawlCanvasProps, ScrawlDefaultUIProps, ScrawlDensity, ScrawlExtension, ScrawlGridMode, ScrawlProps, ScrawlProviderProps, ScrawlResolvedTheme, ScrawlSurfaceTexture, ScrawlTheme, ScrawlThemeDiagnostic, ScrawlThemePreset, ScreenPoint, ScreenRect, SearchHit, SearchHitKind, SearchableBoard, SearchableComment, SerializedBoardDocument, SerializedBoardPage, SerializedBoardStroke, SerializedPoint, SerializedStroke, StampKind, StarObject, StickerKind, StickyNote, Stroke, StrokeId, StrokePoint, StrokeTool, StyleShelfProps, SupportedAssetMediaType, TableBlock, TextBlock, ToolCancelReason, ToolCapabilities, ToolCursor, ToolId, ViewportInset };
3949
+ export type { ApplyOpsResult, ArrowHeadStyle, ArrowObject, AssetDiagnostic, AssetExportFailure, AssetIngestRequest, AssetIngestResult, AssetIngestor, AssetKind, AssetPurpose, AssetRef, AssetResolutionErrorCode, AssetResolveRequest, AssetResolveResult, AssetResolver, BBox, BoardActivityEntry, BoardActivityFeed, BoardActivityKind, BoardBounds, BoardCommentFeed, BoardController, BoardControllerError, BoardEventMap, BoardKeyInput, BoardMember, BoardMenuItem, BoardNotebook, BoardObject, BoardObjectInput, BoardObjectPatch, BoardPage, BoardPermissions, BoardPoint, BoardPointerInput, BoardRole, BoardRoleChange, BoardScene, BoardSection, BoardSlotProps, BoardSnapshot, BoardStroke, BoardStyle, BoardThemeOptions, BoardView, BuiltInTool, ClusterIdFactory, CollaborationAckDiagnostic, CollaborationAdapter, CollaborationReceiver, CollaborationSession, CollaborationSnapshot, CollaborationSyncResult, CollaboratorIdentity, Command, CommandKind, CommentAuthor, CommentMarker, ConnectorBinding, ConnectorBox, ConnectorTarget, ControllerOp, CreateBoardControllerOptions, CreateMemoryPersistenceOptions, CurrentSerializedDocument, CurrentSerializedStroke, CustomBoardObject, CustomObjectAddInput, CustomObjectDefinition, CustomTool, CustomToolDefinition, DeepReadonly, DefaultBoardChromeProps, DefaultUIRegion, DefaultUISlot, DefaultUISlots, DialogSlotProps, DocumentChange, DocumentContext, DocumentId, DocumentLoadResult, DocumentRecoveryCode, EllipseObject, EmojiDefinition, EmojiName, ExportDocumentSVGOptions, ExportDocumentSVGResult, ExtensionCommand, ExtensionDiagnostic, ExtensionHitResult, ExtensionId, ExtensionRequirement, FocusedItem, FocusedItemToolbarProps, GroupObject, HeartObject, IconDefinition, IconName, ImageBlock, InlineEditingTarget, InlineEditorsProps, InputModifiers, JsonObject, JsonValue, KitchenTimer, LineObject, LoadResult, LocalBoard, LocalBoardOptions, LocalBoardSnapshot, LocalPresence, LockHolder, LockTarget, Lockable, Mat2x3, MultiplayerCursorsProps, NoteVote, ObjectDescribeContext, ObjectIntent, ObjectType, Op, OpCollection, PersistenceAdapter, PersistenceDiagnostic, PersistenceSnapshot, PolygonObject, PresenceCursor, PresencePlacement, PresenceUser, PresenceView, QueryableBoardObject, ReadonlyBoardDocument, ReadonlyCustomObject, ReadonlyDocumentChange, RectangleObject, ReorderDirection, ReplaceResult, RibbonEdgePoint, SceneEllipse, SceneGroup, SceneImage, ScenePath, SceneRect, SceneText, ScrawlBoardProps, ScrawlCanvasProps, ScrawlDefaultUIProps, ScrawlDensity, ScrawlExtension, ScrawlGridMode, ScrawlProps, ScrawlProviderProps, ScrawlResolvedTheme, ScrawlSurfaceTexture, ScrawlTheme, ScrawlThemeDiagnostic, ScrawlThemePreset, ScreenPoint, ScreenRect, SearchHit, SearchHitKind, SearchableBoard, SearchableComment, SerializedBoardDocument, SerializedBoardPage, SerializedBoardStroke, SerializedPoint, SerializedStroke, StampKind, StarObject, StickerKind, StickyNote, Stroke, StrokeId, StrokePoint, StrokeTool, StyleShelfProps, SupportedAssetMediaType, TableBlock, TextBlock, ToolCancelReason, ToolCapabilities, ToolCursor, ToolId, ViewportInset };