@tldraw/editor 3.8.0-canary.4703b6039d91 → 3.8.0-canary.47b499005887
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 +119 -50
- package/dist-cjs/index.js +11 -8
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultCanvas.js +1 -1
- package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
- package/dist-cjs/lib/config/TLSessionStateSnapshot.js.map +2 -2
- package/dist-cjs/lib/editor/Editor.js +23 -16
- package/dist-cjs/lib/editor/Editor.js.map +2 -2
- package/dist-cjs/lib/editor/managers/SnapManager/BoundsSnaps.js.map +2 -2
- package/dist-cjs/lib/editor/managers/TextManager.js +1 -0
- package/dist-cjs/lib/editor/managers/TextManager.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js +13 -0
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/shared/resizeScaled.js +66 -0
- package/dist-cjs/lib/editor/shapes/shared/resizeScaled.js.map +7 -0
- package/dist-cjs/lib/editor/types/emit-types.js.map +1 -1
- package/dist-cjs/lib/editor/types/external-content.js.map +1 -1
- package/dist-cjs/lib/exports/StyleEmbedder.js.map +2 -2
- package/dist-cjs/lib/hooks/useDocumentEvents.js +1 -3
- package/dist-cjs/lib/hooks/useDocumentEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/usePassThroughWheelEvents.js +4 -0
- package/dist-cjs/lib/hooks/usePassThroughWheelEvents.js.map +3 -3
- package/dist-cjs/lib/options.js +2 -2
- package/dist-cjs/lib/options.js.map +2 -2
- package/dist-cjs/lib/utils/dom.js +6 -0
- package/dist-cjs/lib/utils/dom.js.map +2 -2
- package/dist-cjs/version.js +3 -3
- package/dist-cjs/version.js.map +1 -1
- package/dist-esm/index.d.mts +119 -50
- package/dist-esm/index.mjs +5 -1
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +1 -1
- package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
- package/dist-esm/lib/config/TLSessionStateSnapshot.mjs.map +2 -2
- package/dist-esm/lib/editor/Editor.mjs +23 -16
- package/dist-esm/lib/editor/Editor.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/SnapManager/BoundsSnaps.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/TextManager.mjs +1 -0
- package/dist-esm/lib/editor/managers/TextManager.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs +13 -0
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/shared/resizeScaled.mjs +46 -0
- package/dist-esm/lib/editor/shapes/shared/resizeScaled.mjs.map +7 -0
- package/dist-esm/lib/exports/StyleEmbedder.mjs.map +2 -2
- package/dist-esm/lib/hooks/useDocumentEvents.mjs +2 -4
- package/dist-esm/lib/hooks/useDocumentEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/usePassThroughWheelEvents.mjs +4 -0
- package/dist-esm/lib/hooks/usePassThroughWheelEvents.mjs.map +3 -3
- package/dist-esm/lib/options.mjs +2 -2
- package/dist-esm/lib/options.mjs.map +2 -2
- package/dist-esm/lib/utils/dom.mjs +6 -0
- package/dist-esm/lib/utils/dom.mjs.map +2 -2
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/editor.css +2 -1
- package/package.json +20 -20
- package/src/index.ts +15 -1
- package/src/lib/components/default-components/DefaultCanvas.tsx +1 -1
- package/src/lib/config/TLSessionStateSnapshot.ts +3 -1
- package/src/lib/editor/Editor.ts +44 -32
- package/src/lib/editor/managers/SnapManager/BoundsSnaps.ts +4 -4
- package/src/lib/editor/managers/TextManager.ts +1 -0
- package/src/lib/editor/shapes/ShapeUtil.ts +19 -0
- package/src/lib/editor/shapes/shared/resizeScaled.ts +61 -0
- package/src/lib/editor/types/emit-types.ts +1 -0
- package/src/lib/editor/types/external-content.ts +90 -50
- package/src/lib/exports/StyleEmbedder.ts +1 -1
- package/src/lib/hooks/useDocumentEvents.ts +2 -11
- package/src/lib/hooks/usePassThroughWheelEvents.ts +7 -0
- package/src/lib/options.ts +5 -2
- package/src/lib/utils/dom.ts +12 -0
- package/src/version.ts +3 -3
package/src/lib/editor/Editor.ts
CHANGED
|
@@ -155,7 +155,7 @@ import {
|
|
|
155
155
|
TLPointerEventInfo,
|
|
156
156
|
TLWheelEventInfo,
|
|
157
157
|
} from './types/event-types'
|
|
158
|
-
import {
|
|
158
|
+
import { TLExternalAsset, TLExternalContent } from './types/external-content'
|
|
159
159
|
import { TLHistoryBatchOptions } from './types/history-types'
|
|
160
160
|
import {
|
|
161
161
|
OptionalKeys,
|
|
@@ -1400,8 +1400,8 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
1400
1400
|
*
|
|
1401
1401
|
* @example
|
|
1402
1402
|
* ```ts
|
|
1403
|
-
*
|
|
1404
|
-
*
|
|
1403
|
+
* editor.getStateDescendant('select')
|
|
1404
|
+
* editor.getStateDescendant('select.brushing')
|
|
1405
1405
|
* ```
|
|
1406
1406
|
*
|
|
1407
1407
|
* @param path - The descendant's path of state ids, separated by periods.
|
|
@@ -1681,7 +1681,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
1681
1681
|
* @public
|
|
1682
1682
|
*/
|
|
1683
1683
|
isAncestorSelected(shape: TLShape | TLShapeId): boolean {
|
|
1684
|
-
const id = typeof shape === 'string' ? shape : shape?.id ?? null
|
|
1684
|
+
const id = typeof shape === 'string' ? shape : (shape?.id ?? null)
|
|
1685
1685
|
const _shape = this.getShape(id)
|
|
1686
1686
|
if (!_shape) return false
|
|
1687
1687
|
const selectedShapeIds = this.getSelectedShapeIds()
|
|
@@ -1938,7 +1938,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
1938
1938
|
* @public
|
|
1939
1939
|
*/
|
|
1940
1940
|
setFocusedGroup(shape: TLShapeId | TLGroupShape | null): this {
|
|
1941
|
-
const id = typeof shape === 'string' ? shape : shape?.id ?? null
|
|
1941
|
+
const id = typeof shape === 'string' ? shape : (shape?.id ?? null)
|
|
1942
1942
|
|
|
1943
1943
|
if (id !== null) {
|
|
1944
1944
|
const shape = this.getShape(id)
|
|
@@ -2021,7 +2021,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
2021
2021
|
* @public
|
|
2022
2022
|
*/
|
|
2023
2023
|
setEditingShape(shape: TLShapeId | TLShape | null): this {
|
|
2024
|
-
const id = typeof shape === 'string' ? shape : shape?.id ?? null
|
|
2024
|
+
const id = typeof shape === 'string' ? shape : (shape?.id ?? null)
|
|
2025
2025
|
if (id !== this.getEditingShapeId()) {
|
|
2026
2026
|
if (id) {
|
|
2027
2027
|
const shape = this.getShape(id)
|
|
@@ -2082,7 +2082,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
2082
2082
|
* @public
|
|
2083
2083
|
*/
|
|
2084
2084
|
setHoveredShape(shape: TLShapeId | TLShape | null): this {
|
|
2085
|
-
const id = typeof shape === 'string' ? shape : shape?.id ?? null
|
|
2085
|
+
const id = typeof shape === 'string' ? shape : (shape?.id ?? null)
|
|
2086
2086
|
if (id === this.getHoveredShapeId()) return this
|
|
2087
2087
|
this.run(
|
|
2088
2088
|
() => {
|
|
@@ -2231,7 +2231,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
2231
2231
|
* @public
|
|
2232
2232
|
*/
|
|
2233
2233
|
setCroppingShape(shape: TLShapeId | TLShape | null): this {
|
|
2234
|
-
const id = typeof shape === 'string' ? shape : shape?.id ?? null
|
|
2234
|
+
const id = typeof shape === 'string' ? shape : (shape?.id ?? null)
|
|
2235
2235
|
if (id !== this.getCroppingShapeId()) {
|
|
2236
2236
|
this.run(
|
|
2237
2237
|
() => {
|
|
@@ -6775,6 +6775,8 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
6775
6775
|
}
|
|
6776
6776
|
}
|
|
6777
6777
|
|
|
6778
|
+
let didResize = false
|
|
6779
|
+
|
|
6778
6780
|
if (util.onResize && util.canResize(initialShape)) {
|
|
6779
6781
|
// get the model changes from the shape util
|
|
6780
6782
|
const newPagePoint = this._scalePagePoint(
|
|
@@ -6813,24 +6815,30 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
6813
6815
|
)
|
|
6814
6816
|
}
|
|
6815
6817
|
|
|
6818
|
+
const resizedShape = util.onResize(
|
|
6819
|
+
{ ...initialShape, x, y },
|
|
6820
|
+
{
|
|
6821
|
+
newPoint: newLocalPoint,
|
|
6822
|
+
handle: opts.dragHandle ?? 'bottom_right',
|
|
6823
|
+
// don't set isSingle to true for children
|
|
6824
|
+
mode: opts.mode ?? 'scale_shape',
|
|
6825
|
+
scaleX: myScale.x,
|
|
6826
|
+
scaleY: myScale.y,
|
|
6827
|
+
initialBounds,
|
|
6828
|
+
initialShape,
|
|
6829
|
+
}
|
|
6830
|
+
)
|
|
6831
|
+
|
|
6832
|
+
if (resizedShape) {
|
|
6833
|
+
didResize = true
|
|
6834
|
+
}
|
|
6835
|
+
|
|
6816
6836
|
workingShape = applyPartialToRecordWithProps(workingShape, {
|
|
6817
6837
|
id,
|
|
6818
6838
|
type: initialShape.type as any,
|
|
6819
6839
|
x: newLocalPoint.x,
|
|
6820
6840
|
y: newLocalPoint.y,
|
|
6821
|
-
...
|
|
6822
|
-
{ ...initialShape, x, y },
|
|
6823
|
-
{
|
|
6824
|
-
newPoint: newLocalPoint,
|
|
6825
|
-
handle: opts.dragHandle ?? 'bottom_right',
|
|
6826
|
-
// don't set isSingle to true for children
|
|
6827
|
-
mode: opts.mode ?? 'scale_shape',
|
|
6828
|
-
scaleX: myScale.x,
|
|
6829
|
-
scaleY: myScale.y,
|
|
6830
|
-
initialBounds,
|
|
6831
|
-
initialShape,
|
|
6832
|
-
}
|
|
6833
|
-
),
|
|
6841
|
+
...resizedShape,
|
|
6834
6842
|
})
|
|
6835
6843
|
|
|
6836
6844
|
if (!opts.skipStartAndEndCallbacks) {
|
|
@@ -6841,7 +6849,11 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
6841
6849
|
}
|
|
6842
6850
|
|
|
6843
6851
|
this.updateShapes([workingShape])
|
|
6844
|
-
}
|
|
6852
|
+
}
|
|
6853
|
+
|
|
6854
|
+
if (!didResize) {
|
|
6855
|
+
// reposition shape (rather than resizing it) based on where its resized center would be
|
|
6856
|
+
|
|
6845
6857
|
const initialPageCenter = Mat.applyToPoint(pageTransform, initialBounds.center)
|
|
6846
6858
|
// get the model changes from the shape util
|
|
6847
6859
|
const newPageCenter = this._scalePagePoint(
|
|
@@ -7963,10 +7975,8 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
7963
7975
|
|
|
7964
7976
|
/** @internal */
|
|
7965
7977
|
externalAssetContentHandlers: {
|
|
7966
|
-
[K in
|
|
7967
|
-
[Key in K]:
|
|
7968
|
-
| null
|
|
7969
|
-
| ((info: TLExternalAssetContent & { type: Key }) => Promise<TLAsset | undefined>)
|
|
7978
|
+
[K in TLExternalAsset['type']]: {
|
|
7979
|
+
[Key in K]: null | ((info: TLExternalAsset & { type: Key }) => Promise<TLAsset | undefined>)
|
|
7970
7980
|
}[K]
|
|
7971
7981
|
} = {
|
|
7972
7982
|
file: null,
|
|
@@ -7995,9 +8005,9 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
7995
8005
|
*
|
|
7996
8006
|
* @public
|
|
7997
8007
|
*/
|
|
7998
|
-
registerExternalAssetHandler<T extends
|
|
8008
|
+
registerExternalAssetHandler<T extends TLExternalAsset['type']>(
|
|
7999
8009
|
type: T,
|
|
8000
|
-
handler: null | ((info:
|
|
8010
|
+
handler: null | ((info: TLExternalAsset & { type: T }) => Promise<TLAsset>)
|
|
8001
8011
|
): this {
|
|
8002
8012
|
this.externalAssetContentHandlers[type] = handler as any
|
|
8003
8013
|
return this
|
|
@@ -8065,11 +8075,11 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
8065
8075
|
* @param info - Info about the external content.
|
|
8066
8076
|
* @returns The asset.
|
|
8067
8077
|
*/
|
|
8068
|
-
async getAssetForExternalContent(info:
|
|
8078
|
+
async getAssetForExternalContent(info: TLExternalAsset): Promise<TLAsset | undefined> {
|
|
8069
8079
|
return await this.externalAssetContentHandlers[info.type]?.(info as any)
|
|
8070
8080
|
}
|
|
8071
8081
|
|
|
8072
|
-
hasExternalAssetHandler(type:
|
|
8082
|
+
hasExternalAssetHandler(type: TLExternalAsset['type']): boolean {
|
|
8073
8083
|
return !!this.externalAssetContentHandlers[type]
|
|
8074
8084
|
}
|
|
8075
8085
|
|
|
@@ -8791,8 +8801,8 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
8791
8801
|
// If our pointer moved only because we're following some other user, then don't
|
|
8792
8802
|
// update our last activity timestamp; otherwise, update it to the current timestamp.
|
|
8793
8803
|
info.type === 'pointer' && info.pointerId === INTERNAL_POINTER_IDS.CAMERA_MOVE
|
|
8794
|
-
? this.store.unsafeGetWithoutCapture(TLPOINTER_ID)?.lastActivityTimestamp ??
|
|
8795
|
-
this._tickManager.now
|
|
8804
|
+
? (this.store.unsafeGetWithoutCapture(TLPOINTER_ID)?.lastActivityTimestamp ??
|
|
8805
|
+
this._tickManager.now)
|
|
8796
8806
|
: this._tickManager.now,
|
|
8797
8807
|
meta: {},
|
|
8798
8808
|
},
|
|
@@ -9357,6 +9367,8 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
9357
9367
|
// todo: replace with new readonly mode?
|
|
9358
9368
|
if (this.getCrashingError()) return this
|
|
9359
9369
|
|
|
9370
|
+
this.emit('before-event', info)
|
|
9371
|
+
|
|
9360
9372
|
const { inputs } = this
|
|
9361
9373
|
const { type } = info
|
|
9362
9374
|
|
|
@@ -390,8 +390,8 @@ export class BoundsSnaps {
|
|
|
390
390
|
|
|
391
391
|
// at the same time, calculate how far we need to nudge the shape to 'snap' to the target point(s)
|
|
392
392
|
const nudge = new Vec(
|
|
393
|
-
lockedAxis === 'x' ? 0 : nearestSnapsX[0]?.nudge ?? 0,
|
|
394
|
-
lockedAxis === 'y' ? 0 : nearestSnapsY[0]?.nudge ?? 0
|
|
393
|
+
lockedAxis === 'x' ? 0 : (nearestSnapsX[0]?.nudge ?? 0),
|
|
394
|
+
lockedAxis === 'y' ? 0 : (nearestSnapsY[0]?.nudge ?? 0)
|
|
395
395
|
)
|
|
396
396
|
|
|
397
397
|
// ok we've figured out how much the box should be nudged, now let's find all the snap points
|
|
@@ -504,8 +504,8 @@ export class BoundsSnaps {
|
|
|
504
504
|
|
|
505
505
|
// at the same time, calculate how far we need to nudge the shape to 'snap' to the target point(s)
|
|
506
506
|
const nudge = new Vec(
|
|
507
|
-
isXLocked ? 0 : nearestSnapsX[0]?.nudge ?? 0,
|
|
508
|
-
isYLocked ? 0 : nearestSnapsY[0]?.nudge ?? 0
|
|
507
|
+
isXLocked ? 0 : (nearestSnapsX[0]?.nudge ?? 0),
|
|
508
|
+
isYLocked ? 0 : (nearestSnapsY[0]?.nudge ?? 0)
|
|
509
509
|
)
|
|
510
510
|
|
|
511
511
|
if (isAspectRatioLocked && isSelectionCorner(handle) && nudge.len() !== 0) {
|
|
@@ -230,6 +230,7 @@ export class TextManager {
|
|
|
230
230
|
elm.style.setProperty('font-weight', opts.fontWeight)
|
|
231
231
|
elm.style.setProperty('line-height', `${opts.lineHeight * opts.fontSize}px`)
|
|
232
232
|
elm.style.setProperty('text-align', textAlignmentsForLtr[opts.textAlign])
|
|
233
|
+
elm.style.setProperty('font-style', opts.fontStyle)
|
|
233
234
|
|
|
234
235
|
const shouldTruncateToFirstLine =
|
|
235
236
|
opts.overflow === 'truncate-ellipsis' || opts.overflow === 'truncate-clip'
|
|
@@ -53,8 +53,27 @@ export interface TLShapeUtilCanvasSvgDef {
|
|
|
53
53
|
|
|
54
54
|
/** @public */
|
|
55
55
|
export abstract class ShapeUtil<Shape extends TLUnknownShape = TLUnknownShape> {
|
|
56
|
+
/** Configure this shape utils {@link ShapeUtil.options | `options`}. */
|
|
57
|
+
static configure<T extends TLShapeUtilConstructor<any, any>>(
|
|
58
|
+
this: T,
|
|
59
|
+
options: T extends new (...args: any[]) => { options: infer Options } ? Partial<Options> : never
|
|
60
|
+
): T {
|
|
61
|
+
// @ts-expect-error -- typescript has no idea what's going on here but it's fine
|
|
62
|
+
return class extends this {
|
|
63
|
+
// @ts-expect-error
|
|
64
|
+
options = { ...this.options, ...options }
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
56
68
|
constructor(public editor: Editor) {}
|
|
57
69
|
|
|
70
|
+
/**
|
|
71
|
+
* Options for this shape util. If you're implementing a custom shape util, you can override
|
|
72
|
+
* this to provide customization options for your shape. If using an existing shape util, you
|
|
73
|
+
* can customizing this by calling {@link ShapeUtil.configure}.
|
|
74
|
+
*/
|
|
75
|
+
options = {}
|
|
76
|
+
|
|
58
77
|
/**
|
|
59
78
|
* Props allow you to define the shape's properties in a way that the editor can understand.
|
|
60
79
|
* This has two main uses:
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { TLBaseShape } from '@tldraw/tlschema'
|
|
2
|
+
import { exhaustiveSwitchError } from '@tldraw/utils'
|
|
3
|
+
import { Vec } from '../../../primitives/Vec'
|
|
4
|
+
import { TLResizeInfo } from '../ShapeUtil'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Resize a shape that has a scale prop.
|
|
8
|
+
*
|
|
9
|
+
* @param shape - The shape to resize
|
|
10
|
+
* @param info - The resize info
|
|
11
|
+
*
|
|
12
|
+
* @public */
|
|
13
|
+
export function resizeScaled(
|
|
14
|
+
shape: TLBaseShape<any, { scale: number }>,
|
|
15
|
+
{ initialBounds, scaleX, scaleY, newPoint, handle }: TLResizeInfo<any>
|
|
16
|
+
) {
|
|
17
|
+
let scaleDelta: number
|
|
18
|
+
switch (handle) {
|
|
19
|
+
case 'bottom_left':
|
|
20
|
+
case 'bottom_right':
|
|
21
|
+
case 'top_left':
|
|
22
|
+
case 'top_right': {
|
|
23
|
+
scaleDelta = Math.max(0.01, Math.max(Math.abs(scaleX), Math.abs(scaleY)))
|
|
24
|
+
break
|
|
25
|
+
}
|
|
26
|
+
case 'left':
|
|
27
|
+
case 'right': {
|
|
28
|
+
scaleDelta = Math.max(0.01, Math.abs(scaleX))
|
|
29
|
+
break
|
|
30
|
+
}
|
|
31
|
+
case 'bottom':
|
|
32
|
+
case 'top': {
|
|
33
|
+
scaleDelta = Math.max(0.01, Math.abs(scaleY))
|
|
34
|
+
break
|
|
35
|
+
}
|
|
36
|
+
default: {
|
|
37
|
+
throw exhaustiveSwitchError(handle)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Compute the offset (if flipped X or flipped Y)
|
|
42
|
+
const offset = new Vec(0, 0)
|
|
43
|
+
|
|
44
|
+
if (scaleX < 0) {
|
|
45
|
+
offset.x = -(initialBounds.width * scaleDelta)
|
|
46
|
+
}
|
|
47
|
+
if (scaleY < 0) {
|
|
48
|
+
offset.y = -(initialBounds.height * scaleDelta)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Apply the offset to the new point
|
|
52
|
+
const { x, y } = Vec.Add(newPoint, offset.rot(shape.rotation))
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
x,
|
|
56
|
+
y,
|
|
57
|
+
props: {
|
|
58
|
+
scale: scaleDelta * shape.props.scale,
|
|
59
|
+
},
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -2,57 +2,97 @@ import { TLAssetId } from '@tldraw/tlschema'
|
|
|
2
2
|
import { VecLike } from '../../primitives/Vec'
|
|
3
3
|
import { TLContent } from './clipboard-types'
|
|
4
4
|
|
|
5
|
+
/** @public */
|
|
6
|
+
export interface TLTldrawExternalContentSource {
|
|
7
|
+
type: 'tldraw'
|
|
8
|
+
data: TLContent
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/** @public */
|
|
12
|
+
export interface TLExcalidrawExternalContentSource {
|
|
13
|
+
type: 'excalidraw'
|
|
14
|
+
data: any
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** @public */
|
|
18
|
+
export interface TLTextExternalContentSource {
|
|
19
|
+
type: 'text'
|
|
20
|
+
data: string
|
|
21
|
+
subtype: 'json' | 'html' | 'text' | 'url'
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** @public */
|
|
25
|
+
export interface TLErrorExternalContentSource {
|
|
26
|
+
type: 'error'
|
|
27
|
+
data: string | null
|
|
28
|
+
reason: string
|
|
29
|
+
}
|
|
30
|
+
|
|
5
31
|
/** @public */
|
|
6
32
|
export type TLExternalContentSource =
|
|
7
|
-
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
| {
|
|
16
|
-
type: 'text'
|
|
17
|
-
data: string
|
|
18
|
-
subtype: 'json' | 'html' | 'text' | 'url'
|
|
19
|
-
}
|
|
20
|
-
| {
|
|
21
|
-
type: 'error'
|
|
22
|
-
data: string | null
|
|
23
|
-
reason: string
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/** @public */
|
|
27
|
-
export type TLExternalContent<EmbedDefinition> = {
|
|
33
|
+
| TLTldrawExternalContentSource
|
|
34
|
+
| TLExcalidrawExternalContentSource
|
|
35
|
+
| TLTextExternalContentSource
|
|
36
|
+
| TLErrorExternalContentSource
|
|
37
|
+
|
|
38
|
+
/** @public */
|
|
39
|
+
export interface TLBaseExternalContent {
|
|
28
40
|
sources?: TLExternalContentSource[]
|
|
29
41
|
point?: VecLike
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** @public */
|
|
45
|
+
export interface TLTextExternalContent extends TLBaseExternalContent {
|
|
46
|
+
type: 'text'
|
|
47
|
+
text: string
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** @public */
|
|
51
|
+
export interface TLFilesExternalContent extends TLBaseExternalContent {
|
|
52
|
+
type: 'files'
|
|
53
|
+
files: File[]
|
|
54
|
+
ignoreParent: boolean
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** @public */
|
|
58
|
+
export interface TLUrlExternalContent extends TLBaseExternalContent {
|
|
59
|
+
type: 'url'
|
|
60
|
+
url: string
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** @public */
|
|
64
|
+
export interface TLSvgTextExternalContent extends TLBaseExternalContent {
|
|
65
|
+
type: 'svg-text'
|
|
66
|
+
text: string
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** @public */
|
|
70
|
+
export interface TLEmbedExternalContent<EmbedDefinition> extends TLBaseExternalContent {
|
|
71
|
+
type: 'embed'
|
|
72
|
+
url: string
|
|
73
|
+
embed: EmbedDefinition
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** @public */
|
|
77
|
+
export type TLExternalContent<EmbedDefinition> =
|
|
78
|
+
| TLTextExternalContent
|
|
79
|
+
| TLFilesExternalContent
|
|
80
|
+
| TLUrlExternalContent
|
|
81
|
+
| TLSvgTextExternalContent
|
|
82
|
+
| TLEmbedExternalContent<EmbedDefinition>
|
|
83
|
+
|
|
84
|
+
/** @public */
|
|
85
|
+
export interface TLFileExternalAsset {
|
|
86
|
+
type: 'file'
|
|
87
|
+
file: File
|
|
88
|
+
assetId?: TLAssetId
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** @public */
|
|
92
|
+
export interface TLUrlExternalAsset {
|
|
93
|
+
type: 'url'
|
|
94
|
+
url: string
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** @public */
|
|
98
|
+
export type TLExternalAsset = TLFileExternalAsset | TLUrlExternalAsset
|
|
@@ -54,7 +54,7 @@ export class StyleEmbedder {
|
|
|
54
54
|
: NO_STYLES
|
|
55
55
|
|
|
56
56
|
const parentStyles = shouldSkipInheritedParentStyles
|
|
57
|
-
? this.styles.get(element.parentElement as Element)?.self ?? NO_STYLES
|
|
57
|
+
? (this.styles.get(element.parentElement as Element)?.self ?? NO_STYLES)
|
|
58
58
|
: NO_STYLES
|
|
59
59
|
|
|
60
60
|
const info: ElementStyleInfo = {
|
|
@@ -2,7 +2,7 @@ import { useValue } from '@tldraw/state-react'
|
|
|
2
2
|
import { useEffect } from 'react'
|
|
3
3
|
import { Editor } from '../editor/Editor'
|
|
4
4
|
import { TLKeyboardEventInfo } from '../editor/types/event-types'
|
|
5
|
-
import { preventDefault, stopEventPropagation } from '../utils/dom'
|
|
5
|
+
import { activeElementShouldCaptureKeys, preventDefault, stopEventPropagation } from '../utils/dom'
|
|
6
6
|
import { isAccelKey } from '../utils/keyboard'
|
|
7
7
|
import { useContainer } from './useContainer'
|
|
8
8
|
import { useEditor } from './useEditor'
|
|
@@ -274,15 +274,6 @@ export function useDocumentEvents() {
|
|
|
274
274
|
}, [editor, container, isAppFocused])
|
|
275
275
|
}
|
|
276
276
|
|
|
277
|
-
const INPUTS = ['input', 'select', 'button', 'textarea']
|
|
278
|
-
|
|
279
277
|
function areShortcutsDisabled(editor: Editor) {
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
return (
|
|
283
|
-
editor.menus.hasOpenMenus() ||
|
|
284
|
-
(activeElement &&
|
|
285
|
-
(activeElement.getAttribute('contenteditable') ||
|
|
286
|
-
INPUTS.indexOf(activeElement.tagName.toLowerCase()) > -1))
|
|
287
|
-
)
|
|
278
|
+
return editor.menus.hasOpenMenus() || activeElementShouldCaptureKeys()
|
|
288
279
|
}
|
|
@@ -11,6 +11,13 @@ export function usePassThroughWheelEvents(ref: RefObject<HTMLElement>) {
|
|
|
11
11
|
useEffect(() => {
|
|
12
12
|
function onWheel(e: WheelEvent) {
|
|
13
13
|
if ((e as any).isSpecialRedispatchedEvent) return
|
|
14
|
+
|
|
15
|
+
// if the element is scrollable, don't redispatch the event
|
|
16
|
+
const elm = ref.current
|
|
17
|
+
if (elm && elm.scrollHeight > elm.clientHeight) {
|
|
18
|
+
return
|
|
19
|
+
}
|
|
20
|
+
|
|
14
21
|
preventDefault(e)
|
|
15
22
|
const cvs = container.querySelector('.tl-canvas')
|
|
16
23
|
if (!cvs) return
|
package/src/lib/options.ts
CHANGED
|
@@ -29,7 +29,6 @@ export interface TldrawOptions {
|
|
|
29
29
|
readonly dragDistanceSquared: number
|
|
30
30
|
readonly defaultSvgPadding: number
|
|
31
31
|
readonly cameraSlideFriction: number
|
|
32
|
-
readonly maxPointsPerDrawShape: number
|
|
33
32
|
readonly gridSteps: readonly {
|
|
34
33
|
readonly min: number
|
|
35
34
|
readonly mid: number
|
|
@@ -66,6 +65,10 @@ export interface TldrawOptions {
|
|
|
66
65
|
* external context providers. By default, this is `React.Fragment`.
|
|
67
66
|
*/
|
|
68
67
|
readonly exportProvider: ComponentType<{ children: React.ReactNode }>
|
|
68
|
+
/**
|
|
69
|
+
* By default, the toolbar items are accessible via number shortcuts according to their order. To disable this, set this option to false.
|
|
70
|
+
*/
|
|
71
|
+
readonly enableToolbarKeyboardShortcuts: boolean
|
|
69
72
|
}
|
|
70
73
|
|
|
71
74
|
/** @public */
|
|
@@ -81,7 +84,6 @@ export const defaultTldrawOptions = {
|
|
|
81
84
|
dragDistanceSquared: 16, // 4 squared
|
|
82
85
|
defaultSvgPadding: 32,
|
|
83
86
|
cameraSlideFriction: 0.09,
|
|
84
|
-
maxPointsPerDrawShape: 500,
|
|
85
87
|
gridSteps: [
|
|
86
88
|
{ min: -1, mid: 0.15, step: 64 },
|
|
87
89
|
{ min: 0.05, mid: 0.375, step: 16 },
|
|
@@ -111,4 +113,5 @@ export const defaultTldrawOptions = {
|
|
|
111
113
|
actionShortcutsLocation: 'swap',
|
|
112
114
|
createTextOnCanvasDoubleClick: true,
|
|
113
115
|
exportProvider: Fragment,
|
|
116
|
+
enableToolbarKeyboardShortcuts: true,
|
|
114
117
|
} as const satisfies TldrawOptions
|
package/src/lib/utils/dom.ts
CHANGED
|
@@ -90,3 +90,15 @@ export const setStyleProperty = (
|
|
|
90
90
|
if (!elm) return
|
|
91
91
|
elm.style.setProperty(property, value as string)
|
|
92
92
|
}
|
|
93
|
+
|
|
94
|
+
const INPUTS = ['input', 'select', 'button', 'textarea']
|
|
95
|
+
|
|
96
|
+
/** @internal */
|
|
97
|
+
export function activeElementShouldCaptureKeys() {
|
|
98
|
+
const { activeElement } = document
|
|
99
|
+
return !!(
|
|
100
|
+
activeElement &&
|
|
101
|
+
(activeElement.getAttribute('contenteditable') ||
|
|
102
|
+
INPUTS.indexOf(activeElement.tagName.toLowerCase()) > -1)
|
|
103
|
+
)
|
|
104
|
+
}
|
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 = '3.8.0-canary.
|
|
4
|
+
export const version = '3.8.0-canary.47b499005887'
|
|
5
5
|
export const publishDates = {
|
|
6
6
|
major: '2024-09-13T14:36:29.063Z',
|
|
7
|
-
minor: '2025-
|
|
8
|
-
patch: '2025-
|
|
7
|
+
minor: '2025-02-12T08:39:48.772Z',
|
|
8
|
+
patch: '2025-02-12T08:39:48.772Z',
|
|
9
9
|
}
|