@tldraw/editor 4.4.0-canary.afdcafe834b3 → 4.4.0-canary.b80d167101d1
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-cjs/index.d.ts +3 -3
- package/dist-cjs/index.js +1 -1
- package/dist-cjs/lib/editor/Editor.js +9 -8
- package/dist-cjs/lib/editor/Editor.js.map +2 -2
- package/dist-cjs/lib/options.js.map +1 -1
- package/dist-cjs/version.js +3 -3
- package/dist-cjs/version.js.map +1 -1
- package/dist-esm/index.d.mts +3 -3
- package/dist-esm/index.mjs +1 -1
- package/dist-esm/lib/editor/Editor.mjs +9 -8
- package/dist-esm/lib/editor/Editor.mjs.map +2 -2
- package/dist-esm/lib/options.mjs.map +1 -1
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/editor.css +5 -0
- package/package.json +8 -9
- package/src/lib/editor/Editor.ts +17 -8
- package/src/lib/options.ts +2 -2
- package/src/version.ts +3 -3
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/lib/options.ts"],
|
|
4
|
-
"sourcesContent": ["import { ComponentType, Fragment } from 'react'\n\n/**\n * Options for configuring tldraw. For defaults, see {@link defaultTldrawOptions}.\n *\n * @example\n * ```tsx\n * const options: Partial<TldrawOptions> = {\n * maxPages: 3,\n * maxShapesPerPage: 1000,\n * }\n *\n * function MyTldrawComponent() {\n * return <Tldraw options={options} />\n * }\n * ```\n *\n * @public\n */\nexport interface TldrawOptions {\n\treadonly maxShapesPerPage: number\n\treadonly maxFilesAtOnce: number\n\treadonly maxPages: number\n\treadonly animationMediumMs: number\n\treadonly followChaseViewportSnap: number\n\treadonly doubleClickDurationMs: number\n\treadonly multiClickDurationMs: number\n\treadonly coarseDragDistanceSquared: number\n\treadonly dragDistanceSquared: number\n\treadonly uiDragDistanceSquared: number\n\treadonly uiCoarseDragDistanceSquared: number\n\treadonly defaultSvgPadding: number\n\treadonly cameraSlideFriction: number\n\treadonly gridSteps: readonly {\n\t\treadonly min: number\n\t\treadonly mid: number\n\t\treadonly step: number\n\t}[]\n\treadonly collaboratorInactiveTimeoutMs: number\n\treadonly collaboratorIdleTimeoutMs: number\n\treadonly collaboratorCheckIntervalMs: number\n\treadonly cameraMovingTimeoutMs: number\n\treadonly hitTestMargin: number\n\treadonly edgeScrollDelay: number\n\treadonly edgeScrollEaseDuration: number\n\treadonly edgeScrollSpeed: number\n\treadonly edgeScrollDistance: number\n\treadonly coarsePointerWidth: number\n\treadonly coarseHandleRadius: number\n\treadonly handleRadius: number\n\treadonly longPressDurationMs: number\n\treadonly textShadowLod: number\n\treadonly adjacentShapeMargin: number\n\treadonly flattenImageBoundsExpand: number\n\treadonly flattenImageBoundsPadding: number\n\treadonly laserDelayMs: number\n\t/**\n\t * How long (in milliseconds) to fade all laser scribbles after the session ends.\n\t * The total points across all scribbles will be removed proportionally over this duration.\n\t * Defaults to 500ms (0.5 seconds).\n\t */\n\treadonly laserFadeoutMs: number\n\treadonly maxExportDelayMs: number\n\treadonly tooltipDelayMs: number\n\t/**\n\t * How long should previews created by {@link Editor.createTemporaryAssetPreview} last before\n\t * they expire? Defaults to 3 minutes.\n\t */\n\treadonly temporaryAssetPreviewLifetimeMs: number\n\treadonly actionShortcutsLocation: 'menu' | 'toolbar' | 'swap'\n\treadonly createTextOnCanvasDoubleClick: boolean\n\t/**\n\t * The react provider to use when exporting an image. This is useful if your shapes depend on\n\t * external context providers. By default, this is `React.Fragment`.\n\t */\n\treadonly exportProvider: ComponentType<{ children: React.ReactNode }>\n\t/**\n\t * By default, the toolbar items are accessible via number shortcuts according to their order. To disable this, set this option to false.\n\t */\n\treadonly enableToolbarKeyboardShortcuts: boolean\n\t/**\n\t * The maximum number of fonts that will be loaded while blocking the main rendering of the\n\t * canvas. If there are more than this number of fonts needed, we'll just show the canvas right\n\t * away and let the fonts load in in the background.\n\t */\n\treadonly maxFontsToLoadBeforeRender: number\n\t/**\n\t * If you have a CSP policy that blocks inline styles, you can use this prop to provide a\n\t * nonce to use in the editor's styles.\n\t */\n\treadonly nonce: string | undefined\n\t/**\n\t * Branding name of the app, currently only used for adding aria-label for the application.\n\t */\n\treadonly branding?: string\n\t/**\n\t * Whether to use debounced zoom level for certain rendering optimizations. When true,\n\t * `editor.
|
|
4
|
+
"sourcesContent": ["import { ComponentType, Fragment } from 'react'\n\n/**\n * Options for configuring tldraw. For defaults, see {@link defaultTldrawOptions}.\n *\n * @example\n * ```tsx\n * const options: Partial<TldrawOptions> = {\n * maxPages: 3,\n * maxShapesPerPage: 1000,\n * }\n *\n * function MyTldrawComponent() {\n * return <Tldraw options={options} />\n * }\n * ```\n *\n * @public\n */\nexport interface TldrawOptions {\n\treadonly maxShapesPerPage: number\n\treadonly maxFilesAtOnce: number\n\treadonly maxPages: number\n\treadonly animationMediumMs: number\n\treadonly followChaseViewportSnap: number\n\treadonly doubleClickDurationMs: number\n\treadonly multiClickDurationMs: number\n\treadonly coarseDragDistanceSquared: number\n\treadonly dragDistanceSquared: number\n\treadonly uiDragDistanceSquared: number\n\treadonly uiCoarseDragDistanceSquared: number\n\treadonly defaultSvgPadding: number\n\treadonly cameraSlideFriction: number\n\treadonly gridSteps: readonly {\n\t\treadonly min: number\n\t\treadonly mid: number\n\t\treadonly step: number\n\t}[]\n\treadonly collaboratorInactiveTimeoutMs: number\n\treadonly collaboratorIdleTimeoutMs: number\n\treadonly collaboratorCheckIntervalMs: number\n\treadonly cameraMovingTimeoutMs: number\n\treadonly hitTestMargin: number\n\treadonly edgeScrollDelay: number\n\treadonly edgeScrollEaseDuration: number\n\treadonly edgeScrollSpeed: number\n\treadonly edgeScrollDistance: number\n\treadonly coarsePointerWidth: number\n\treadonly coarseHandleRadius: number\n\treadonly handleRadius: number\n\treadonly longPressDurationMs: number\n\treadonly textShadowLod: number\n\treadonly adjacentShapeMargin: number\n\treadonly flattenImageBoundsExpand: number\n\treadonly flattenImageBoundsPadding: number\n\treadonly laserDelayMs: number\n\t/**\n\t * How long (in milliseconds) to fade all laser scribbles after the session ends.\n\t * The total points across all scribbles will be removed proportionally over this duration.\n\t * Defaults to 500ms (0.5 seconds).\n\t */\n\treadonly laserFadeoutMs: number\n\treadonly maxExportDelayMs: number\n\treadonly tooltipDelayMs: number\n\t/**\n\t * How long should previews created by {@link Editor.createTemporaryAssetPreview} last before\n\t * they expire? Defaults to 3 minutes.\n\t */\n\treadonly temporaryAssetPreviewLifetimeMs: number\n\treadonly actionShortcutsLocation: 'menu' | 'toolbar' | 'swap'\n\treadonly createTextOnCanvasDoubleClick: boolean\n\t/**\n\t * The react provider to use when exporting an image. This is useful if your shapes depend on\n\t * external context providers. By default, this is `React.Fragment`.\n\t */\n\treadonly exportProvider: ComponentType<{ children: React.ReactNode }>\n\t/**\n\t * By default, the toolbar items are accessible via number shortcuts according to their order. To disable this, set this option to false.\n\t */\n\treadonly enableToolbarKeyboardShortcuts: boolean\n\t/**\n\t * The maximum number of fonts that will be loaded while blocking the main rendering of the\n\t * canvas. If there are more than this number of fonts needed, we'll just show the canvas right\n\t * away and let the fonts load in in the background.\n\t */\n\treadonly maxFontsToLoadBeforeRender: number\n\t/**\n\t * If you have a CSP policy that blocks inline styles, you can use this prop to provide a\n\t * nonce to use in the editor's styles.\n\t */\n\treadonly nonce: string | undefined\n\t/**\n\t * Branding name of the app, currently only used for adding aria-label for the application.\n\t */\n\treadonly branding?: string\n\t/**\n\t * Whether to use debounced zoom level for certain rendering optimizations. When true,\n\t * `editor.getEfficientZoomLevel()` returns a cached zoom value while the camera is moving,\n\t * reducing re-renders. When false, it always returns the current zoom level.\n\t */\n\treadonly debouncedZoom: boolean\n\t/**\n\t * The number of shapes that must be on the page for the debounced zoom level to be used.\n\t * Defaults to 500 shapes.\n\t */\n\treadonly debouncedZoomThreshold: number\n\t/**\n\t * Whether to allow spacebar panning. When true, the spacebar will pan the camera when held down.\n\t * When false, the spacebar will not pan the camera.\n\t */\n\treadonly spacebarPanning: boolean\n\t/**\n\t * The default padding (in pixels) used when zooming to fit content in the viewport.\n\t * This affects methods like `zoomToFit()`, `zoomToSelection()`, and `zoomToBounds()`.\n\t * The actual padding used is the minimum of this value and 28% of the viewport width.\n\t * Defaults to 128 pixels.\n\t */\n\treadonly zoomToFitPadding: number\n\t/**\n\t * The distance (in screen pixels) at which shapes snap to guides and other shapes.\n\t */\n\treadonly snapThreshold: number\n}\n\n/** @public */\nexport const defaultTldrawOptions = {\n\tmaxShapesPerPage: 4000,\n\tmaxFilesAtOnce: 100,\n\tmaxPages: 40,\n\tanimationMediumMs: 320,\n\tfollowChaseViewportSnap: 2,\n\tdoubleClickDurationMs: 450,\n\tmultiClickDurationMs: 200,\n\tcoarseDragDistanceSquared: 36, // 6 squared\n\tdragDistanceSquared: 16, // 4 squared\n\tuiDragDistanceSquared: 16, // 4 squared\n\t// it's really easy to accidentally drag from the toolbar on mobile, so we use a much larger\n\t// threshold than usual here to try and prevent accidental drags.\n\tuiCoarseDragDistanceSquared: 625, // 25 squared\n\tdefaultSvgPadding: 32,\n\tcameraSlideFriction: 0.09,\n\tgridSteps: [\n\t\t{ min: -1, mid: 0.15, step: 64 },\n\t\t{ min: 0.05, mid: 0.375, step: 16 },\n\t\t{ min: 0.15, mid: 1, step: 4 },\n\t\t{ min: 0.7, mid: 2.5, step: 1 },\n\t],\n\tcollaboratorInactiveTimeoutMs: 60000,\n\tcollaboratorIdleTimeoutMs: 3000,\n\tcollaboratorCheckIntervalMs: 1200,\n\tcameraMovingTimeoutMs: 64,\n\thitTestMargin: 8,\n\tedgeScrollDelay: 200,\n\tedgeScrollEaseDuration: 200,\n\tedgeScrollSpeed: 25,\n\tedgeScrollDistance: 8,\n\tcoarsePointerWidth: 12,\n\tcoarseHandleRadius: 20,\n\thandleRadius: 12,\n\tlongPressDurationMs: 500,\n\ttextShadowLod: 0.35,\n\tadjacentShapeMargin: 10,\n\tflattenImageBoundsExpand: 64,\n\tflattenImageBoundsPadding: 16,\n\tlaserDelayMs: 1200,\n\tlaserFadeoutMs: 500,\n\tmaxExportDelayMs: 5000,\n\ttooltipDelayMs: 700,\n\ttemporaryAssetPreviewLifetimeMs: 180000,\n\tactionShortcutsLocation: 'swap',\n\tcreateTextOnCanvasDoubleClick: true,\n\texportProvider: Fragment,\n\tenableToolbarKeyboardShortcuts: true,\n\tmaxFontsToLoadBeforeRender: Infinity,\n\tnonce: undefined,\n\tdebouncedZoom: true,\n\tdebouncedZoomThreshold: 500,\n\tspacebarPanning: true,\n\tzoomToFitPadding: 128,\n\tsnapThreshold: 8,\n} as const satisfies TldrawOptions\n"],
|
|
5
5
|
"mappings": "AAAA,SAAwB,gBAAgB;AA6HjC,MAAM,uBAAuB;AAAA,EACnC,kBAAkB;AAAA,EAClB,gBAAgB;AAAA,EAChB,UAAU;AAAA,EACV,mBAAmB;AAAA,EACnB,yBAAyB;AAAA,EACzB,uBAAuB;AAAA,EACvB,sBAAsB;AAAA,EACtB,2BAA2B;AAAA;AAAA,EAC3B,qBAAqB;AAAA;AAAA,EACrB,uBAAuB;AAAA;AAAA;AAAA;AAAA,EAGvB,6BAA6B;AAAA;AAAA,EAC7B,mBAAmB;AAAA,EACnB,qBAAqB;AAAA,EACrB,WAAW;AAAA,IACV,EAAE,KAAK,IAAI,KAAK,MAAM,MAAM,GAAG;AAAA,IAC/B,EAAE,KAAK,MAAM,KAAK,OAAO,MAAM,GAAG;AAAA,IAClC,EAAE,KAAK,MAAM,KAAK,GAAG,MAAM,EAAE;AAAA,IAC7B,EAAE,KAAK,KAAK,KAAK,KAAK,MAAM,EAAE;AAAA,EAC/B;AAAA,EACA,+BAA+B;AAAA,EAC/B,2BAA2B;AAAA,EAC3B,6BAA6B;AAAA,EAC7B,uBAAuB;AAAA,EACvB,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,wBAAwB;AAAA,EACxB,iBAAiB;AAAA,EACjB,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,cAAc;AAAA,EACd,qBAAqB;AAAA,EACrB,eAAe;AAAA,EACf,qBAAqB;AAAA,EACrB,0BAA0B;AAAA,EAC1B,2BAA2B;AAAA,EAC3B,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,kBAAkB;AAAA,EAClB,gBAAgB;AAAA,EAChB,iCAAiC;AAAA,EACjC,yBAAyB;AAAA,EACzB,+BAA+B;AAAA,EAC/B,gBAAgB;AAAA,EAChB,gCAAgC;AAAA,EAChC,4BAA4B;AAAA,EAC5B,OAAO;AAAA,EACP,eAAe;AAAA,EACf,wBAAwB;AAAA,EACxB,iBAAiB;AAAA,EACjB,kBAAkB;AAAA,EAClB,eAAe;AAChB;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist-esm/version.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
const version = "4.4.0-canary.
|
|
1
|
+
const version = "4.4.0-canary.b80d167101d1";
|
|
2
2
|
const publishDates = {
|
|
3
3
|
major: "2025-09-18T14:39:22.803Z",
|
|
4
|
-
minor: "2026-02-
|
|
5
|
-
patch: "2026-02-
|
|
4
|
+
minor: "2026-02-09T12:49:21.563Z",
|
|
5
|
+
patch: "2026-02-09T12:49:21.563Z"
|
|
6
6
|
};
|
|
7
7
|
export {
|
|
8
8
|
publishDates,
|
package/dist-esm/version.mjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/version.ts"],
|
|
4
|
-
"sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '4.4.0-canary.
|
|
4
|
+
"sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '4.4.0-canary.b80d167101d1'\nexport const publishDates = {\n\tmajor: '2025-09-18T14:39:22.803Z',\n\tminor: '2026-02-09T12:49:21.563Z',\n\tpatch: '2026-02-09T12:49:21.563Z',\n}\n"],
|
|
5
5
|
"mappings": "AAGO,MAAM,UAAU;AAChB,MAAM,eAAe;AAAA,EAC3B,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AACR;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/editor.css
CHANGED
|
@@ -60,6 +60,7 @@
|
|
|
60
60
|
|
|
61
61
|
/* Misc */
|
|
62
62
|
--tl-zoom: 1;
|
|
63
|
+
--tl-tab-size: 2;
|
|
63
64
|
|
|
64
65
|
/* Cursor SVGs */
|
|
65
66
|
--tl-cursor-none: none;
|
|
@@ -895,6 +896,10 @@ input,
|
|
|
895
896
|
/* white-space: break-spaces; */
|
|
896
897
|
}
|
|
897
898
|
|
|
899
|
+
.tl-rich-text {
|
|
900
|
+
tab-size: var(--tl-tab-size, 2);
|
|
901
|
+
}
|
|
902
|
+
|
|
898
903
|
.tl-rich-text p {
|
|
899
904
|
margin: 0;
|
|
900
905
|
/* Depending on the extensions, <p> tags can be empty, without a <br />. */
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tldraw/editor",
|
|
3
3
|
"description": "tldraw infinite canvas SDK (editor).",
|
|
4
|
-
"version": "4.4.0-canary.
|
|
4
|
+
"version": "4.4.0-canary.b80d167101d1",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "tldraw Inc.",
|
|
7
7
|
"email": "hello@tldraw.com"
|
|
@@ -43,19 +43,18 @@
|
|
|
43
43
|
"prepack": "yarn run -T tsx ../../internal/scripts/prepack.ts",
|
|
44
44
|
"postpack": "../../internal/scripts/postpack.sh",
|
|
45
45
|
"pack-tarball": "yarn pack",
|
|
46
|
-
"lint": "yarn run -T tsx ../../internal/scripts/lint.ts"
|
|
47
|
-
"context": "yarn run -T tsx ../../internal/scripts/context.ts"
|
|
46
|
+
"lint": "yarn run -T tsx ../../internal/scripts/lint.ts"
|
|
48
47
|
},
|
|
49
48
|
"dependencies": {
|
|
50
49
|
"@tiptap/core": "^3.12.1",
|
|
51
50
|
"@tiptap/pm": "^3.12.1",
|
|
52
51
|
"@tiptap/react": "^3.12.1",
|
|
53
|
-
"@tldraw/state": "4.4.0-canary.
|
|
54
|
-
"@tldraw/state-react": "4.4.0-canary.
|
|
55
|
-
"@tldraw/store": "4.4.0-canary.
|
|
56
|
-
"@tldraw/tlschema": "4.4.0-canary.
|
|
57
|
-
"@tldraw/utils": "4.4.0-canary.
|
|
58
|
-
"@tldraw/validate": "4.4.0-canary.
|
|
52
|
+
"@tldraw/state": "4.4.0-canary.b80d167101d1",
|
|
53
|
+
"@tldraw/state-react": "4.4.0-canary.b80d167101d1",
|
|
54
|
+
"@tldraw/store": "4.4.0-canary.b80d167101d1",
|
|
55
|
+
"@tldraw/tlschema": "4.4.0-canary.b80d167101d1",
|
|
56
|
+
"@tldraw/utils": "4.4.0-canary.b80d167101d1",
|
|
57
|
+
"@tldraw/validate": "4.4.0-canary.b80d167101d1",
|
|
59
58
|
"@use-gesture/react": "^10.3.1",
|
|
60
59
|
"classnames": "^2.5.1",
|
|
61
60
|
"eventemitter3": "^4.0.7",
|
package/src/lib/editor/Editor.ts
CHANGED
|
@@ -443,6 +443,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
443
443
|
const deletedShapeIds = new Set<TLShapeId>()
|
|
444
444
|
const invalidParents = new Set<TLShapeId>()
|
|
445
445
|
let invalidBindingTypes = new Set<TLBinding['type']>()
|
|
446
|
+
|
|
446
447
|
this.disposables.add(
|
|
447
448
|
this.sideEffects.registerOperationCompleteHandler(() => {
|
|
448
449
|
// this needs to be cleared here because further effects may delete more shapes
|
|
@@ -4180,23 +4181,25 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
4180
4181
|
// unmount / remount in the DOM, which is expensive; and computing visibility is
|
|
4181
4182
|
// also expensive in large projects. For this reason, we use a second bounding
|
|
4182
4183
|
// box just for rendering, and we only update after the camera stops moving.
|
|
4183
|
-
private _cameraState = atom('camera state', 'idle' as 'idle' | 'moving')
|
|
4184
4184
|
private _cameraStateTimeoutRemaining = 0
|
|
4185
4185
|
private _decayCameraStateTimeout(elapsed: number) {
|
|
4186
4186
|
this._cameraStateTimeoutRemaining -= elapsed
|
|
4187
4187
|
if (this._cameraStateTimeoutRemaining > 0) return
|
|
4188
4188
|
this.off('tick', this._decayCameraStateTimeout)
|
|
4189
|
-
this.
|
|
4189
|
+
this._setCameraState('idle')
|
|
4190
4190
|
}
|
|
4191
4191
|
private _tickCameraState() {
|
|
4192
4192
|
// always reset the timeout
|
|
4193
4193
|
this._cameraStateTimeoutRemaining = this.options.cameraMovingTimeoutMs
|
|
4194
4194
|
// If the state is idle, then start the tick
|
|
4195
|
-
if (this.
|
|
4196
|
-
this.
|
|
4195
|
+
if (this.getInstanceState().cameraState !== 'idle') return
|
|
4196
|
+
this._setCameraState('moving')
|
|
4197
4197
|
this._debouncedZoomLevel.set(unsafe__withoutCapture(() => this.getCamera().z))
|
|
4198
4198
|
this.on('tick', this._decayCameraStateTimeout)
|
|
4199
4199
|
}
|
|
4200
|
+
private _setCameraState(cameraState: 'idle' | 'moving') {
|
|
4201
|
+
this.updateInstanceState({ cameraState }, { history: 'ignore' })
|
|
4202
|
+
}
|
|
4200
4203
|
|
|
4201
4204
|
/**
|
|
4202
4205
|
* Whether the camera is moving or idle.
|
|
@@ -4209,7 +4212,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
4209
4212
|
* @public
|
|
4210
4213
|
*/
|
|
4211
4214
|
getCameraState() {
|
|
4212
|
-
return this.
|
|
4215
|
+
return this.getInstanceState().cameraState
|
|
4213
4216
|
}
|
|
4214
4217
|
|
|
4215
4218
|
/**
|
|
@@ -10421,9 +10424,10 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
10421
10424
|
if (inputs.getIsPinching()) return
|
|
10422
10425
|
|
|
10423
10426
|
if (!inputs.getIsEditing()) {
|
|
10424
|
-
|
|
10425
|
-
|
|
10426
|
-
|
|
10427
|
+
// Always capture the current selection when pinch starts.
|
|
10428
|
+
// This ensures Safari (which uses gesture events instead of wheel)
|
|
10429
|
+
// doesn't restore a stale selection from an earlier pointer_down.
|
|
10430
|
+
this._selectedShapeIdsAtPointerDown = [...pageState.selectedShapeIds]
|
|
10427
10431
|
|
|
10428
10432
|
this._didPinch = true
|
|
10429
10433
|
|
|
@@ -10734,6 +10738,11 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
10734
10738
|
this.setCurrentTool(this._restoreToolId)
|
|
10735
10739
|
}
|
|
10736
10740
|
}
|
|
10741
|
+
|
|
10742
|
+
// Clear the stashed selection so the next pinch captures fresh state.
|
|
10743
|
+
// This fixes Safari pinch zoom restoring outdated selections.
|
|
10744
|
+
this._selectedShapeIdsAtPointerDown = []
|
|
10745
|
+
|
|
10737
10746
|
break
|
|
10738
10747
|
}
|
|
10739
10748
|
}
|
package/src/lib/options.ts
CHANGED
|
@@ -95,13 +95,13 @@ export interface TldrawOptions {
|
|
|
95
95
|
readonly branding?: string
|
|
96
96
|
/**
|
|
97
97
|
* Whether to use debounced zoom level for certain rendering optimizations. When true,
|
|
98
|
-
* `editor.
|
|
98
|
+
* `editor.getEfficientZoomLevel()` returns a cached zoom value while the camera is moving,
|
|
99
99
|
* reducing re-renders. When false, it always returns the current zoom level.
|
|
100
100
|
*/
|
|
101
101
|
readonly debouncedZoom: boolean
|
|
102
102
|
/**
|
|
103
103
|
* The number of shapes that must be on the page for the debounced zoom level to be used.
|
|
104
|
-
* Defaults to
|
|
104
|
+
* Defaults to 500 shapes.
|
|
105
105
|
*/
|
|
106
106
|
readonly debouncedZoomThreshold: number
|
|
107
107
|
/**
|
package/src/version.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// This file is automatically generated by internal/scripts/refresh-assets.ts.
|
|
2
2
|
// Do not edit manually. Or do, I'm a comment, not a cop.
|
|
3
3
|
|
|
4
|
-
export const version = '4.4.0-canary.
|
|
4
|
+
export const version = '4.4.0-canary.b80d167101d1'
|
|
5
5
|
export const publishDates = {
|
|
6
6
|
major: '2025-09-18T14:39:22.803Z',
|
|
7
|
-
minor: '2026-02-
|
|
8
|
-
patch: '2026-02-
|
|
7
|
+
minor: '2026-02-09T12:49:21.563Z',
|
|
8
|
+
patch: '2026-02-09T12:49:21.563Z',
|
|
9
9
|
}
|