From d27c7c8c22b8e1cb4853fc277c9c0b515ca73284 Mon Sep 17 00:00:00 2001 From: Amani Date: Sat, 15 Aug 2026 16:46:15 -0500 Subject: [PATCH] feat(canvas): support in-canvas overlays --- CHANGELOG.md | 7 +++++++ docs/api.md | 3 +++ package-lock.json | 4 ++-- package.json | 2 +- src/InfiniteInkCanvas.tsx | 2 ++ src/infinite-ink-canvas/types.ts | 7 +++++++ 6 files changed, 22 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dd2b956..2465ee2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ All notable changes to `@mathnotes/mobile-ink` will be documented here. +## [0.3.4] - 2026-08-15 + +- Added the optional `overlay` prop to `InfiniteInkCanvas`. Host applications + can render React overlays inside the UI-thread transformed viewport, keeping + inserted images, text boxes, and other page content synchronized with ink + during panning and zooming. + ## [0.3.3] - 2026-08-14 - Prevented software-keyboard viewport resizes from being treated as orientation changes. diff --git a/docs/api.md b/docs/api.md index 618da2e..3fee51b 100644 --- a/docs/api.md +++ b/docs/api.md @@ -27,6 +27,9 @@ High-level continuous notebook component. - `pageWidth` / `pageHeight`: logical page size. - `minScale` / `maxScale`: viewport zoom bounds. - `showPageLabels`: whether the generic example-style page number labels render. +- `overlay`: optional app-owned React content rendered inside the UI-thread + transformed viewport. Use this for images, text boxes, or other overlays + that must stay synchronized with ink during panning and zooming. - `onDrawingChange(pageId)`: called when a page becomes dirty. - `onCurrentPageChange(pageIndex)`: called when the settled/current page changes. - `onPagesChange(pages)`: called when page growth or trimming changes the page array. diff --git a/package-lock.json b/package-lock.json index 8927d97..da88a84 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@mathnotes/mobile-ink", - "version": "0.3.3", + "version": "0.3.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@mathnotes/mobile-ink", - "version": "0.3.3", + "version": "0.3.4", "license": "Apache-2.0", "devDependencies": { "@babel/core": "^7.25.2", diff --git a/package.json b/package.json index 3b9d644..c121e4c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mathnotes/mobile-ink", - "version": "0.3.3", + "version": "0.3.4", "description": "Production-grade React Native ink engine with native Skia drawing and continuous canvas primitives.", "license": "Apache-2.0", "author": "BuilderPro LLC", diff --git a/src/InfiniteInkCanvas.tsx b/src/InfiniteInkCanvas.tsx index 491de8a..69abdbe 100644 --- a/src/InfiniteInkCanvas.tsx +++ b/src/InfiniteInkCanvas.tsx @@ -107,6 +107,7 @@ function InfiniteInkCanvasImpl( maxScale = 5, contentPadding = DEFAULT_CONTENT_PADDING, showPageLabels = true, + overlay, onReady, onDrawingChange, onSelectionChange, @@ -670,6 +671,7 @@ function InfiniteInkCanvasImpl( shouldCaptureBeforeReassign={shouldCaptureBeforeReassign} onSlotCaptureBeforeUnmount={updatePageData} /> + {overlay} diff --git a/src/infinite-ink-canvas/types.ts b/src/infinite-ink-canvas/types.ts index b0a127f..6a01276 100644 --- a/src/infinite-ink-canvas/types.ts +++ b/src/infinite-ink-canvas/types.ts @@ -1,3 +1,4 @@ +import type { ReactNode } from "react"; import type { StyleProp, ViewStyle } from "react-native"; import type { ContinuousEnginePoolToolState } from "../ContinuousEnginePool"; import type { @@ -54,6 +55,12 @@ export type InfiniteInkCanvasProps = { maxScale?: number; contentPadding?: number; showPageLabels?: boolean; + /** + * Optional app-owned content rendered inside the UI-thread transformed + * viewport. Use this for overlays that must stay synchronized with ink + * while the canvas pans or zooms. + */ + overlay?: ReactNode; onReady?: () => void; onDrawingChange?: (pageId: string) => void; onSelectionChange?: (