@tldraw/editor 3.14.0-canary.f8af44c4d1e2 → 3.14.0-canary.faba3f64c07f
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 +150 -76
- package/dist-cjs/index.js +11 -10
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/config/TLSessionStateSnapshot.js +1 -12
- package/dist-cjs/lib/config/TLSessionStateSnapshot.js.map +3 -3
- package/dist-cjs/lib/editor/Editor.js +109 -94
- package/dist-cjs/lib/editor/Editor.js.map +2 -2
- package/dist-cjs/lib/editor/bindings/BindingUtil.js.map +2 -2
- package/dist-cjs/lib/editor/derivations/bindingsIndex.js +22 -22
- package/dist-cjs/lib/editor/derivations/bindingsIndex.js.map +2 -2
- package/dist-cjs/lib/editor/derivations/parentsToChildren.js +16 -16
- package/dist-cjs/lib/editor/derivations/parentsToChildren.js.map +2 -2
- package/dist-cjs/lib/editor/managers/{ClickManager.js → ClickManager/ClickManager.js} +1 -1
- package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js.map +7 -0
- package/dist-cjs/lib/editor/managers/{EdgeScrollManager.js → EdgeScrollManager/EdgeScrollManager.js} +2 -2
- package/dist-cjs/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.js.map +7 -0
- package/dist-cjs/lib/editor/managers/FocusManager/FocusManager.js.map +7 -0
- package/dist-cjs/lib/editor/managers/{FontManager.js → FontManager/FontManager.js} +1 -2
- package/dist-cjs/lib/editor/managers/FontManager/FontManager.js.map +7 -0
- package/dist-cjs/lib/editor/managers/{HistoryManager.js → HistoryManager/HistoryManager.js} +64 -6
- package/dist-cjs/lib/editor/managers/HistoryManager/HistoryManager.js.map +7 -0
- package/dist-cjs/lib/editor/managers/{ScribbleManager.js → ScribbleManager/ScribbleManager.js} +1 -1
- package/dist-cjs/lib/editor/managers/ScribbleManager/ScribbleManager.js.map +7 -0
- package/dist-cjs/lib/editor/managers/{TextManager.js → TextManager/TextManager.js} +73 -42
- package/dist-cjs/lib/editor/managers/TextManager/TextManager.js.map +7 -0
- package/dist-cjs/lib/editor/managers/{TickManager.js → TickManager/TickManager.js} +1 -1
- package/dist-cjs/lib/editor/managers/TickManager/TickManager.js.map +7 -0
- package/dist-cjs/lib/editor/managers/{UserPreferencesManager.js → UserPreferencesManager/UserPreferencesManager.js} +1 -1
- package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js.map +7 -0
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js +0 -10
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js +1 -1
- package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js.map +1 -1
- package/dist-cjs/lib/editor/tools/StateNode.js +3 -3
- package/dist-cjs/lib/editor/tools/StateNode.js.map +2 -2
- 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/getSvgJsx.js.map +1 -1
- package/dist-cjs/lib/hooks/useCanvasEvents.js +1 -2
- package/dist-cjs/lib/hooks/useCanvasEvents.js.map +2 -2
- package/dist-cjs/lib/primitives/Box.js +0 -6
- package/dist-cjs/lib/primitives/Box.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Geometry2d.js +6 -2
- package/dist-cjs/lib/primitives/geometry/Geometry2d.js.map +2 -2
- package/dist-cjs/lib/utils/areShapesContentEqual.js +1 -1
- package/dist-cjs/lib/utils/areShapesContentEqual.js.map +2 -2
- package/dist-cjs/lib/utils/reorderShapes.js +11 -10
- package/dist-cjs/lib/utils/reorderShapes.js.map +2 -2
- package/dist-cjs/lib/utils/reparenting.js +232 -0
- package/dist-cjs/lib/utils/reparenting.js.map +7 -0
- package/dist-cjs/lib/utils/richText.js +7 -2
- package/dist-cjs/lib/utils/richText.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 +150 -76
- package/dist-esm/index.mjs +15 -10
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/config/TLSessionStateSnapshot.mjs +1 -1
- package/dist-esm/lib/config/TLSessionStateSnapshot.mjs.map +2 -2
- package/dist-esm/lib/editor/Editor.mjs +109 -94
- package/dist-esm/lib/editor/Editor.mjs.map +2 -2
- package/dist-esm/lib/editor/bindings/BindingUtil.mjs.map +2 -2
- package/dist-esm/lib/editor/derivations/bindingsIndex.mjs +22 -22
- package/dist-esm/lib/editor/derivations/bindingsIndex.mjs.map +2 -2
- package/dist-esm/lib/editor/derivations/parentsToChildren.mjs +16 -16
- package/dist-esm/lib/editor/derivations/parentsToChildren.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/{ClickManager.mjs → ClickManager/ClickManager.mjs} +1 -1
- package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/{EdgeScrollManager.mjs → EdgeScrollManager/EdgeScrollManager.mjs} +2 -2
- package/dist-esm/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/FocusManager/FocusManager.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/{FontManager.mjs → FontManager/FontManager.mjs} +1 -2
- package/dist-esm/lib/editor/managers/FontManager/FontManager.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/{HistoryManager.mjs → HistoryManager/HistoryManager.mjs} +60 -2
- package/dist-esm/lib/editor/managers/HistoryManager/HistoryManager.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/{ScribbleManager.mjs → ScribbleManager/ScribbleManager.mjs} +1 -1
- package/dist-esm/lib/editor/managers/ScribbleManager/ScribbleManager.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/{TextManager.mjs → TextManager/TextManager.mjs} +73 -42
- package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/{TickManager.mjs → TickManager/TickManager.mjs} +1 -1
- package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/{UserPreferencesManager.mjs → UserPreferencesManager/UserPreferencesManager.mjs} +1 -1
- package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs.map +7 -0
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs +0 -10
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs +1 -1
- package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs.map +1 -1
- package/dist-esm/lib/editor/tools/StateNode.mjs +3 -3
- package/dist-esm/lib/editor/tools/StateNode.mjs.map +2 -2
- package/dist-esm/lib/exports/getSvgJsx.mjs.map +1 -1
- package/dist-esm/lib/hooks/useCanvasEvents.mjs +1 -2
- package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +2 -2
- package/dist-esm/lib/primitives/Box.mjs +0 -6
- package/dist-esm/lib/primitives/Box.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Geometry2d.mjs +6 -2
- package/dist-esm/lib/primitives/geometry/Geometry2d.mjs.map +2 -2
- package/dist-esm/lib/utils/areShapesContentEqual.mjs +1 -1
- package/dist-esm/lib/utils/areShapesContentEqual.mjs.map +2 -2
- package/dist-esm/lib/utils/reorderShapes.mjs +11 -10
- package/dist-esm/lib/utils/reorderShapes.mjs.map +2 -2
- package/dist-esm/lib/utils/reparenting.mjs +216 -0
- package/dist-esm/lib/utils/reparenting.mjs.map +7 -0
- package/dist-esm/lib/utils/richText.mjs +8 -3
- package/dist-esm/lib/utils/richText.mjs.map +2 -2
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/editor.css +442 -492
- package/package.json +8 -9
- package/src/index.ts +20 -8
- package/src/lib/config/TLSessionStateSnapshot.ts +1 -1
- package/src/lib/editor/Editor.test.ts +252 -3
- package/src/lib/editor/Editor.ts +120 -101
- package/src/lib/editor/bindings/BindingUtil.ts +6 -0
- package/src/lib/editor/derivations/bindingsIndex.ts +27 -26
- package/src/lib/editor/derivations/parentsToChildren.ts +28 -25
- package/src/lib/editor/managers/ClickManager/ClickManager.test.ts +442 -0
- package/src/lib/editor/managers/{ClickManager.ts → ClickManager/ClickManager.ts} +3 -3
- package/src/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.test.ts +374 -0
- package/src/lib/editor/managers/{EdgeScrollManager.ts → EdgeScrollManager/EdgeScrollManager.ts} +3 -3
- package/src/lib/editor/managers/FocusManager/FocusManager.test.ts +455 -0
- package/src/lib/editor/managers/{FocusManager.ts → FocusManager/FocusManager.ts} +1 -1
- package/src/lib/editor/managers/FontManager/FontManager.test.ts +263 -0
- package/src/lib/editor/managers/{FontManager.ts → FontManager/FontManager.ts} +2 -3
- package/src/lib/editor/managers/{HistoryManager.test.ts → HistoryManager/HistoryManager.test.ts} +388 -1
- package/src/lib/editor/managers/{HistoryManager.ts → HistoryManager/HistoryManager.ts} +73 -2
- package/src/lib/editor/managers/ScribbleManager/ScribbleManager.test.ts +624 -0
- package/src/lib/editor/managers/{ScribbleManager.ts → ScribbleManager/ScribbleManager.ts} +2 -2
- package/src/lib/editor/managers/SnapManager/SnapManager.test.ts +485 -0
- package/src/lib/editor/managers/TextManager/TextManager.test.ts +407 -0
- package/src/lib/editor/managers/{TextManager.ts → TextManager/TextManager.ts} +119 -87
- package/src/lib/editor/managers/TickManager/TickManager.test.ts +314 -0
- package/src/lib/editor/managers/{TickManager.ts → TickManager/TickManager.ts} +2 -2
- package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.test.ts +591 -0
- package/src/lib/editor/managers/{UserPreferencesManager.ts → UserPreferencesManager/UserPreferencesManager.ts} +2 -2
- package/src/lib/editor/shapes/ShapeUtil.ts +48 -16
- package/src/lib/editor/shapes/group/GroupShapeUtil.tsx +1 -1
- package/src/lib/editor/tools/StateNode.ts +3 -3
- package/src/lib/editor/types/emit-types.ts +4 -0
- package/src/lib/editor/types/external-content.ts +11 -2
- package/src/lib/exports/getSvgJsx.tsx +1 -1
- package/src/lib/hooks/useCanvasEvents.ts +0 -1
- package/src/lib/primitives/Box.ts +0 -8
- package/src/lib/primitives/geometry/Geometry2d.ts +7 -2
- package/src/lib/utils/areShapesContentEqual.ts +1 -2
- package/src/lib/utils/reorderShapes.ts +10 -13
- package/src/lib/utils/reparenting.ts +383 -0
- package/src/lib/utils/richText.ts +10 -4
- package/src/version.ts +3 -3
- package/dist-cjs/lib/editor/managers/ClickManager.js.map +0 -7
- package/dist-cjs/lib/editor/managers/EdgeScrollManager.js.map +0 -7
- package/dist-cjs/lib/editor/managers/FocusManager.js.map +0 -7
- package/dist-cjs/lib/editor/managers/FontManager.js.map +0 -7
- package/dist-cjs/lib/editor/managers/HistoryManager.js.map +0 -7
- package/dist-cjs/lib/editor/managers/ScribbleManager.js.map +0 -7
- package/dist-cjs/lib/editor/managers/Stack.js +0 -82
- package/dist-cjs/lib/editor/managers/Stack.js.map +0 -7
- package/dist-cjs/lib/editor/managers/TextManager.js.map +0 -7
- package/dist-cjs/lib/editor/managers/TickManager.js.map +0 -7
- package/dist-cjs/lib/editor/managers/UserPreferencesManager.js.map +0 -7
- package/dist-esm/lib/editor/managers/ClickManager.mjs.map +0 -7
- package/dist-esm/lib/editor/managers/EdgeScrollManager.mjs.map +0 -7
- package/dist-esm/lib/editor/managers/FocusManager.mjs.map +0 -7
- package/dist-esm/lib/editor/managers/FontManager.mjs.map +0 -7
- package/dist-esm/lib/editor/managers/HistoryManager.mjs.map +0 -7
- package/dist-esm/lib/editor/managers/ScribbleManager.mjs.map +0 -7
- package/dist-esm/lib/editor/managers/Stack.mjs +0 -62
- package/dist-esm/lib/editor/managers/Stack.mjs.map +0 -7
- package/dist-esm/lib/editor/managers/TextManager.mjs.map +0 -7
- package/dist-esm/lib/editor/managers/TickManager.mjs.map +0 -7
- package/dist-esm/lib/editor/managers/UserPreferencesManager.mjs.map +0 -7
- package/src/lib/editor/managers/ScribbleManager.test.ts +0 -32
- package/src/lib/editor/managers/Stack.ts +0 -71
- /package/dist-cjs/lib/editor/managers/{FocusManager.js → FocusManager/FocusManager.js} +0 -0
- /package/dist-esm/lib/editor/managers/{FocusManager.mjs → FocusManager/FocusManager.mjs} +0 -0
package/src/lib/editor/Editor.ts
CHANGED
|
@@ -148,16 +148,16 @@ import { bindingsIndex } from './derivations/bindingsIndex'
|
|
|
148
148
|
import { notVisibleShapes } from './derivations/notVisibleShapes'
|
|
149
149
|
import { parentsToChildren } from './derivations/parentsToChildren'
|
|
150
150
|
import { deriveShapeIdsInCurrentPage } from './derivations/shapeIdsInCurrentPage'
|
|
151
|
-
import { ClickManager } from './managers/ClickManager'
|
|
152
|
-
import { EdgeScrollManager } from './managers/EdgeScrollManager'
|
|
153
|
-
import { FocusManager } from './managers/FocusManager'
|
|
154
|
-
import { FontManager } from './managers/FontManager'
|
|
155
|
-
import { HistoryManager } from './managers/HistoryManager'
|
|
156
|
-
import { ScribbleManager } from './managers/ScribbleManager'
|
|
151
|
+
import { ClickManager } from './managers/ClickManager/ClickManager'
|
|
152
|
+
import { EdgeScrollManager } from './managers/EdgeScrollManager/EdgeScrollManager'
|
|
153
|
+
import { FocusManager } from './managers/FocusManager/FocusManager'
|
|
154
|
+
import { FontManager } from './managers/FontManager/FontManager'
|
|
155
|
+
import { HistoryManager } from './managers/HistoryManager/HistoryManager'
|
|
156
|
+
import { ScribbleManager } from './managers/ScribbleManager/ScribbleManager'
|
|
157
157
|
import { SnapManager } from './managers/SnapManager/SnapManager'
|
|
158
|
-
import { TextManager } from './managers/TextManager'
|
|
159
|
-
import { TickManager } from './managers/TickManager'
|
|
160
|
-
import { UserPreferencesManager } from './managers/UserPreferencesManager'
|
|
158
|
+
import { TextManager } from './managers/TextManager/TextManager'
|
|
159
|
+
import { TickManager } from './managers/TickManager/TickManager'
|
|
160
|
+
import { UserPreferencesManager } from './managers/UserPreferencesManager/UserPreferencesManager'
|
|
161
161
|
import { ShapeUtil, TLGeometryOpts, TLResizeMode } from './shapes/ShapeUtil'
|
|
162
162
|
import { RootState } from './tools/RootState'
|
|
163
163
|
import { StateNode, TLStateNodeConstructor } from './tools/StateNode'
|
|
@@ -328,7 +328,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
328
328
|
this.store = store
|
|
329
329
|
this.history = new HistoryManager<TLRecord>({
|
|
330
330
|
store,
|
|
331
|
-
annotateError: (error) => {
|
|
331
|
+
annotateError: (error: any) => {
|
|
332
332
|
this.annotateError(error, { origin: 'history.batch', willCrashApp: true })
|
|
333
333
|
this.crash(error)
|
|
334
334
|
},
|
|
@@ -348,6 +348,8 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
348
348
|
this.getContainer = getContainer
|
|
349
349
|
|
|
350
350
|
this.textMeasure = new TextManager(this)
|
|
351
|
+
this.disposables.add(() => this.textMeasure.dispose())
|
|
352
|
+
|
|
351
353
|
this.fonts = new FontManager(this, fontAssetUrls)
|
|
352
354
|
|
|
353
355
|
this._tickManager = new TickManager(this)
|
|
@@ -506,14 +508,13 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
506
508
|
shape: {
|
|
507
509
|
afterChange: (shapeBefore, shapeAfter) => {
|
|
508
510
|
for (const binding of this.getBindingsInvolvingShape(shapeAfter)) {
|
|
509
|
-
if (areShapesContentEqual(shapeBefore, shapeAfter)) continue
|
|
510
|
-
|
|
511
511
|
invalidBindingTypes.add(binding.type)
|
|
512
512
|
if (binding.fromId === shapeAfter.id) {
|
|
513
513
|
this.getBindingUtil(binding).onAfterChangeFromShape?.({
|
|
514
514
|
binding,
|
|
515
515
|
shapeBefore,
|
|
516
516
|
shapeAfter,
|
|
517
|
+
reason: 'self',
|
|
517
518
|
})
|
|
518
519
|
}
|
|
519
520
|
if (binding.toId === shapeAfter.id) {
|
|
@@ -521,6 +522,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
521
522
|
binding,
|
|
522
523
|
shapeBefore,
|
|
523
524
|
shapeAfter,
|
|
525
|
+
reason: 'self',
|
|
524
526
|
})
|
|
525
527
|
}
|
|
526
528
|
}
|
|
@@ -539,6 +541,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
539
541
|
binding,
|
|
540
542
|
shapeBefore: descendantShape,
|
|
541
543
|
shapeAfter: descendantShape,
|
|
544
|
+
reason: 'ancestry',
|
|
542
545
|
})
|
|
543
546
|
}
|
|
544
547
|
if (binding.toId === descendantShape.id) {
|
|
@@ -546,6 +549,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
546
549
|
binding,
|
|
547
550
|
shapeBefore: descendantShape,
|
|
548
551
|
shapeAfter: descendantShape,
|
|
552
|
+
reason: 'ancestry',
|
|
549
553
|
})
|
|
550
554
|
}
|
|
551
555
|
}
|
|
@@ -2118,6 +2122,20 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
2118
2122
|
return this.getShapesPageBounds(this.getSelectedShapeIds())
|
|
2119
2123
|
}
|
|
2120
2124
|
|
|
2125
|
+
/**
|
|
2126
|
+
* The bounds of the selection bounding box in the current page space.
|
|
2127
|
+
*
|
|
2128
|
+
* @readonly
|
|
2129
|
+
* @public
|
|
2130
|
+
*/
|
|
2131
|
+
getSelectionScreenBounds(): Box | undefined {
|
|
2132
|
+
const bounds = this.getSelectionPageBounds()
|
|
2133
|
+
if (!bounds) return undefined
|
|
2134
|
+
const { x, y } = this.pageToScreen(bounds.point)
|
|
2135
|
+
const zoom = this.getZoomLevel()
|
|
2136
|
+
return new Box(x, y, bounds.width * zoom, bounds.height * zoom)
|
|
2137
|
+
}
|
|
2138
|
+
|
|
2121
2139
|
/**
|
|
2122
2140
|
* @internal
|
|
2123
2141
|
*/
|
|
@@ -4643,44 +4661,6 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
4643
4661
|
)! as T
|
|
4644
4662
|
}
|
|
4645
4663
|
|
|
4646
|
-
private _shapePageGeometryCaches: Record<string, ComputedCache<Geometry2d, TLShape>> = {}
|
|
4647
|
-
|
|
4648
|
-
/**
|
|
4649
|
-
* Get the geometry of a shape in page-space.
|
|
4650
|
-
*
|
|
4651
|
-
* @example
|
|
4652
|
-
* ```ts
|
|
4653
|
-
* editor.getShapePageGeometry(myShape)
|
|
4654
|
-
* editor.getShapePageGeometry(myShapeId)
|
|
4655
|
-
* editor.getShapePageGeometry(myShapeId, { context: "arrow" })
|
|
4656
|
-
* ```
|
|
4657
|
-
*
|
|
4658
|
-
* @param shape - The shape (or shape id) to get the geometry for.
|
|
4659
|
-
* @param opts - Additional options about the request for geometry. Passed to {@link ShapeUtil.getGeometry}.
|
|
4660
|
-
*
|
|
4661
|
-
* @public
|
|
4662
|
-
*/
|
|
4663
|
-
getShapePageGeometry<T extends Geometry2d>(shape: TLShape | TLShapeId, opts?: TLGeometryOpts): T {
|
|
4664
|
-
const context = opts?.context ?? 'none'
|
|
4665
|
-
if (!this._shapePageGeometryCaches[context]) {
|
|
4666
|
-
this._shapePageGeometryCaches[context] = this.store.createComputedCache(
|
|
4667
|
-
'bounds',
|
|
4668
|
-
(shape) => {
|
|
4669
|
-
const geometry = this.getShapeGeometry(shape.id, opts)
|
|
4670
|
-
const pageTransform = this.getShapePageTransform(shape.id)
|
|
4671
|
-
return geometry.transform(pageTransform)
|
|
4672
|
-
},
|
|
4673
|
-
{
|
|
4674
|
-
// we only depend directly on the shape id, and changing geometry/transform will update us anyway
|
|
4675
|
-
areRecordsEqual: () => true,
|
|
4676
|
-
}
|
|
4677
|
-
)
|
|
4678
|
-
}
|
|
4679
|
-
return this._shapePageGeometryCaches[context].get(
|
|
4680
|
-
typeof shape === 'string' ? shape : shape.id
|
|
4681
|
-
)! as T
|
|
4682
|
-
}
|
|
4683
|
-
|
|
4684
4664
|
/** @internal */
|
|
4685
4665
|
@computed private _getShapeHandlesCache(): ComputedCache<TLHandle[] | undefined, TLShape> {
|
|
4686
4666
|
return this.store.createComputedCache(
|
|
@@ -4793,7 +4773,10 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
4793
4773
|
/** @internal */
|
|
4794
4774
|
@computed private _getShapePageBoundsCache(): ComputedCache<Box, TLShape> {
|
|
4795
4775
|
return this.store.createComputedCache<Box, TLShape>('pageBoundsCache', (shape) => {
|
|
4796
|
-
|
|
4776
|
+
const pageTransform = this.getShapePageTransform(shape)
|
|
4777
|
+
if (!pageTransform) return undefined
|
|
4778
|
+
const geometry = this.getShapeGeometry(shape)
|
|
4779
|
+
return Box.FromPoints(pageTransform.applyToPoints(geometry.vertices))
|
|
4797
4780
|
})
|
|
4798
4781
|
}
|
|
4799
4782
|
|
|
@@ -4867,11 +4850,12 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
4867
4850
|
if (frameAncestors.length === 0) return undefined
|
|
4868
4851
|
|
|
4869
4852
|
const pageMask = frameAncestors
|
|
4870
|
-
.map<Vec[] | undefined>(
|
|
4871
|
-
|
|
4872
|
-
|
|
4873
|
-
|
|
4874
|
-
|
|
4853
|
+
.map<Vec[] | undefined>((s) => {
|
|
4854
|
+
// Apply the frame transform to the frame outline to get the frame outline in the current page space
|
|
4855
|
+
const geometry = this.getShapeGeometry(s.id)
|
|
4856
|
+
const pageTransform = this.getShapePageTransform(s.id)
|
|
4857
|
+
return pageTransform.applyToPoints(geometry.vertices)
|
|
4858
|
+
})
|
|
4875
4859
|
.reduce((acc, b) => {
|
|
4876
4860
|
if (!(b && acc)) return undefined
|
|
4877
4861
|
const intersection = intersectPolygonPolygon(acc, b)
|
|
@@ -5069,28 +5053,33 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5069
5053
|
*
|
|
5070
5054
|
* @public
|
|
5071
5055
|
*/
|
|
5072
|
-
isShapeOrAncestorLocked(shape?: TLShape): boolean
|
|
5073
|
-
|
|
5074
|
-
|
|
5075
|
-
|
|
5076
|
-
|
|
5077
|
-
if (shape.isLocked) return true
|
|
5078
|
-
return this.isShapeOrAncestorLocked(this.getShapeParent(shape))
|
|
5056
|
+
isShapeOrAncestorLocked(shape?: TLShape | TLShapeId): boolean {
|
|
5057
|
+
const _shape = shape && this.getShape(shape)
|
|
5058
|
+
if (_shape === undefined) return false
|
|
5059
|
+
if (_shape.isLocked) return true
|
|
5060
|
+
return this.isShapeOrAncestorLocked(this.getShapeParent(_shape))
|
|
5079
5061
|
}
|
|
5080
5062
|
|
|
5063
|
+
/**
|
|
5064
|
+
* Get shapes that are outside of the viewport.
|
|
5065
|
+
*
|
|
5066
|
+
* @public
|
|
5067
|
+
*/
|
|
5081
5068
|
@computed
|
|
5082
|
-
|
|
5083
|
-
return
|
|
5069
|
+
getNotVisibleShapes() {
|
|
5070
|
+
return this._notVisibleShapes.get()
|
|
5084
5071
|
}
|
|
5085
5072
|
|
|
5073
|
+
private _notVisibleShapes = notVisibleShapes(this)
|
|
5074
|
+
|
|
5086
5075
|
/**
|
|
5087
|
-
* Get culled shapes.
|
|
5076
|
+
* Get culled shapes (those that should not render), taking into account which shapes are selected or editing.
|
|
5088
5077
|
*
|
|
5089
5078
|
* @public
|
|
5090
5079
|
*/
|
|
5091
5080
|
@computed
|
|
5092
5081
|
getCulledShapes() {
|
|
5093
|
-
const notVisibleShapes = this.
|
|
5082
|
+
const notVisibleShapes = this.getNotVisibleShapes()
|
|
5094
5083
|
const selectedShapeIds = this.getSelectedShapeIds()
|
|
5095
5084
|
const editingId = this.getEditingShapeId()
|
|
5096
5085
|
const culledShapes = new Set<TLShapeId>(notVisibleShapes)
|
|
@@ -5339,21 +5328,23 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5339
5328
|
* @example
|
|
5340
5329
|
* ```ts
|
|
5341
5330
|
* editor.getShapesAtPoint({ x: 100, y: 100 })
|
|
5342
|
-
* editor.getShapesAtPoint({ x: 100, y: 100 }, { hitInside: true,
|
|
5331
|
+
* editor.getShapesAtPoint({ x: 100, y: 100 }, { hitInside: true, margin: 8 })
|
|
5343
5332
|
* ```
|
|
5344
5333
|
*
|
|
5345
5334
|
* @param point - The page point to test.
|
|
5346
5335
|
* @param opts - The options for the hit point testing.
|
|
5347
5336
|
*
|
|
5337
|
+
* @returns An array of shapes at the given point, sorted in reverse order of their absolute z-index (top-most shape first).
|
|
5338
|
+
*
|
|
5348
5339
|
* @public
|
|
5349
5340
|
*/
|
|
5350
5341
|
getShapesAtPoint(
|
|
5351
5342
|
point: VecLike,
|
|
5352
5343
|
opts = {} as { margin?: number; hitInside?: boolean }
|
|
5353
5344
|
): TLShape[] {
|
|
5354
|
-
return this.
|
|
5355
|
-
(shape) => !this.isShapeHidden(shape) && this.isPointInShape(shape, point, opts)
|
|
5356
|
-
|
|
5345
|
+
return this.getCurrentPageShapesSorted()
|
|
5346
|
+
.filter((shape) => !this.isShapeHidden(shape) && this.isPointInShape(shape, point, opts))
|
|
5347
|
+
.reverse()
|
|
5357
5348
|
}
|
|
5358
5349
|
|
|
5359
5350
|
/**
|
|
@@ -5537,7 +5528,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5537
5528
|
if (!id) return undefined
|
|
5538
5529
|
const freshShape = this.getShape(id)
|
|
5539
5530
|
if (freshShape === undefined || !isShapeId(freshShape.parentId)) return undefined
|
|
5540
|
-
return this.
|
|
5531
|
+
return this.getShape(freshShape.parentId)
|
|
5541
5532
|
}
|
|
5542
5533
|
|
|
5543
5534
|
/**
|
|
@@ -5720,6 +5711,10 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5720
5711
|
const newPoint = invertedParentTransform.applyToPoint(pagePoint)
|
|
5721
5712
|
const newRotation = pageTransform.rotation() - parentPageRotation
|
|
5722
5713
|
|
|
5714
|
+
if (shape.id === parentId) {
|
|
5715
|
+
throw Error('Attempted to reparent a shape to itself!')
|
|
5716
|
+
}
|
|
5717
|
+
|
|
5723
5718
|
changes.push({
|
|
5724
5719
|
id: shape.id,
|
|
5725
5720
|
type: shape.type,
|
|
@@ -5823,6 +5818,11 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5823
5818
|
return shapeIds
|
|
5824
5819
|
}
|
|
5825
5820
|
|
|
5821
|
+
/** @deprecated Use {@link Editor.getDraggingOverShape} instead */
|
|
5822
|
+
getDroppingOverShape(point: Vec, droppingShapes: TLShape[]): TLShape | undefined {
|
|
5823
|
+
return this.getDraggingOverShape(point, droppingShapes)
|
|
5824
|
+
}
|
|
5825
|
+
|
|
5826
5826
|
/**
|
|
5827
5827
|
* Get the shape that some shapes should be dropped on at a given point.
|
|
5828
5828
|
*
|
|
@@ -5833,35 +5833,33 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5833
5833
|
*
|
|
5834
5834
|
* @public
|
|
5835
5835
|
*/
|
|
5836
|
-
|
|
5837
|
-
//
|
|
5838
|
-
const
|
|
5839
|
-
|
|
5840
|
-
|
|
5841
|
-
|
|
5842
|
-
if (
|
|
5843
|
-
// ignore hidden shapes
|
|
5844
|
-
this.isShapeHidden(shape) ||
|
|
5845
|
-
// don't allow dropping on selected shapes
|
|
5846
|
-
this.getSelectedShapeIds().includes(shape.id) ||
|
|
5847
|
-
// only allow shapes that can receive children
|
|
5848
|
-
!this.getShapeUtil(shape).canDropShapes(shape, droppingShapes) ||
|
|
5849
|
-
// don't allow dropping a shape on itself or one of it's children
|
|
5850
|
-
droppingShapes.find((s) => s.id === shape.id || this.hasAncestor(shape, s.id))
|
|
5851
|
-
) {
|
|
5852
|
-
continue
|
|
5853
|
-
}
|
|
5836
|
+
getDraggingOverShape(point: Vec, droppingShapes: TLShape[]): TLShape | undefined {
|
|
5837
|
+
// get fresh moving shapes
|
|
5838
|
+
const draggingShapes = compact(droppingShapes.map((s) => this.getShape(s))).filter(
|
|
5839
|
+
(s) => !s.isLocked && !this.isShapeHidden(s)
|
|
5840
|
+
)
|
|
5854
5841
|
|
|
5855
|
-
|
|
5856
|
-
|
|
5857
|
-
|
|
5842
|
+
const maybeDraggingOverShapes = this.getShapesAtPoint(point, {
|
|
5843
|
+
hitInside: true,
|
|
5844
|
+
margin: 0,
|
|
5845
|
+
}).filter(
|
|
5846
|
+
(s) =>
|
|
5847
|
+
!droppingShapes.includes(s) &&
|
|
5848
|
+
!s.isLocked &&
|
|
5849
|
+
!this.isShapeHidden(s) &&
|
|
5850
|
+
!draggingShapes.includes(s)
|
|
5851
|
+
)
|
|
5858
5852
|
|
|
5853
|
+
for (const maybeDraggingOverShape of maybeDraggingOverShapes) {
|
|
5854
|
+
const shapeUtil = this.getShapeUtil(maybeDraggingOverShape)
|
|
5855
|
+
// Any shape that can handle any dragging interactions is a valid target
|
|
5859
5856
|
if (
|
|
5860
|
-
|
|
5861
|
-
|
|
5862
|
-
|
|
5857
|
+
shapeUtil.onDragShapesOver ||
|
|
5858
|
+
shapeUtil.onDragShapesIn ||
|
|
5859
|
+
shapeUtil.onDragShapesOut ||
|
|
5860
|
+
shapeUtil.onDropShapesOver
|
|
5863
5861
|
) {
|
|
5864
|
-
return
|
|
5862
|
+
return maybeDraggingOverShape
|
|
5865
5863
|
}
|
|
5866
5864
|
}
|
|
5867
5865
|
}
|
|
@@ -6220,11 +6218,12 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
6220
6218
|
*/
|
|
6221
6219
|
duplicateShapes(shapes: TLShapeId[] | TLShape[], offset?: VecLike): this {
|
|
6222
6220
|
this.run(() => {
|
|
6223
|
-
const
|
|
6221
|
+
const _ids =
|
|
6224
6222
|
typeof shapes[0] === 'string'
|
|
6225
6223
|
? (shapes as TLShapeId[])
|
|
6226
6224
|
: (shapes as TLShape[]).map((s) => s.id)
|
|
6227
6225
|
|
|
6226
|
+
const ids = this._shouldIgnoreShapeLock ? _ids : this._getUnlockedShapeIds(_ids)
|
|
6228
6227
|
if (ids.length <= 0) return this
|
|
6229
6228
|
|
|
6230
6229
|
const initialIds = new Set(ids)
|
|
@@ -7814,9 +7813,10 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
7814
7813
|
|
|
7815
7814
|
for (let i = currentPageShapesSorted.length - 1; i >= 0; i--) {
|
|
7816
7815
|
const parent = currentPageShapesSorted[i]
|
|
7816
|
+
const util = this.getShapeUtil(parent)
|
|
7817
7817
|
if (
|
|
7818
|
+
util.canReceiveNewChildrenOfType(parent, partial.type) &&
|
|
7818
7819
|
!this.isShapeHidden(parent) &&
|
|
7819
|
-
this.getShapeUtil(parent).canReceiveNewChildrenOfType(parent, partial.type) &&
|
|
7820
7820
|
this.isPointInShape(
|
|
7821
7821
|
parent,
|
|
7822
7822
|
// If no parent is provided, then we can treat the
|
|
@@ -7945,6 +7945,8 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
7945
7945
|
}
|
|
7946
7946
|
})
|
|
7947
7947
|
|
|
7948
|
+
this.emit('created-shapes', shapeRecordsToCreate)
|
|
7949
|
+
this.emit('edit')
|
|
7948
7950
|
this.store.put(shapeRecordsToCreate)
|
|
7949
7951
|
})
|
|
7950
7952
|
|
|
@@ -8339,6 +8341,8 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
8339
8341
|
updates.push(updated)
|
|
8340
8342
|
}
|
|
8341
8343
|
|
|
8344
|
+
this.emit('edited-shapes', updates)
|
|
8345
|
+
this.emit('edit')
|
|
8342
8346
|
this.store.put(updates)
|
|
8343
8347
|
})
|
|
8344
8348
|
}
|
|
@@ -8388,6 +8392,8 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
8388
8392
|
})
|
|
8389
8393
|
}
|
|
8390
8394
|
|
|
8395
|
+
this.emit('deleted-shapes', [...allShapeIdsToDelete])
|
|
8396
|
+
this.emit('edit')
|
|
8391
8397
|
return this.run(() => this.store.remove([...allShapeIdsToDelete]))
|
|
8392
8398
|
}
|
|
8393
8399
|
|
|
@@ -8836,6 +8842,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
8836
8842
|
} = {
|
|
8837
8843
|
text: null,
|
|
8838
8844
|
files: null,
|
|
8845
|
+
'file-replace': null,
|
|
8839
8846
|
embed: null,
|
|
8840
8847
|
'svg-text': null,
|
|
8841
8848
|
url: null,
|
|
@@ -8885,6 +8892,15 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
8885
8892
|
return this.externalContentHandlers[info.type]?.(info as any)
|
|
8886
8893
|
}
|
|
8887
8894
|
|
|
8895
|
+
/**
|
|
8896
|
+
* Handle replacing external content.
|
|
8897
|
+
*
|
|
8898
|
+
* @param info - Info about the external content.
|
|
8899
|
+
*/
|
|
8900
|
+
async replaceExternalContent<E>(info: TLExternalContent<E>): Promise<void> {
|
|
8901
|
+
return this.externalContentHandlers[info.type]?.(info as any)
|
|
8902
|
+
}
|
|
8903
|
+
|
|
8888
8904
|
/**
|
|
8889
8905
|
* Get content that can be exported for the given shape ids.
|
|
8890
8906
|
*
|
|
@@ -9302,6 +9318,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
9302
9318
|
if (rootShapes.length === 1) {
|
|
9303
9319
|
const onlyRoot = rootShapes[0] as TLFrameShape
|
|
9304
9320
|
// If the old bounds are in the viewport...
|
|
9321
|
+
// todo: replace frame references with shapes that can accept children
|
|
9305
9322
|
if (this.isShapeOfType<TLFrameShape>(onlyRoot, 'frame')) {
|
|
9306
9323
|
while (
|
|
9307
9324
|
this.getShapesAtPoint(point).some(
|
|
@@ -9503,6 +9520,8 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
9503
9520
|
previousPagePoint,
|
|
9504
9521
|
currentScreenPoint,
|
|
9505
9522
|
currentPagePoint,
|
|
9523
|
+
originScreenPoint,
|
|
9524
|
+
originPagePoint,
|
|
9506
9525
|
} = this.inputs
|
|
9507
9526
|
|
|
9508
9527
|
const { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!
|
|
@@ -9531,8 +9550,8 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
9531
9550
|
// Reset velocity on pointer down, or when a pinch starts or ends
|
|
9532
9551
|
if (info.name === 'pointer_down' || this.inputs.isPinching) {
|
|
9533
9552
|
pointerVelocity.set(0, 0)
|
|
9534
|
-
|
|
9535
|
-
|
|
9553
|
+
originScreenPoint.setTo(currentScreenPoint)
|
|
9554
|
+
originPagePoint.setTo(currentPagePoint)
|
|
9536
9555
|
}
|
|
9537
9556
|
|
|
9538
9557
|
// todo: We only have to do this if there are multiple users in the document
|
|
@@ -62,6 +62,12 @@ export interface BindingOnShapeChangeOptions<Binding extends TLUnknownBinding> {
|
|
|
62
62
|
shapeBefore: TLShape
|
|
63
63
|
/** The shape record after the change is made. */
|
|
64
64
|
shapeAfter: TLShape
|
|
65
|
+
/**
|
|
66
|
+
* Why did this shape change?
|
|
67
|
+
* - 'self': the shape itself changed
|
|
68
|
+
* - 'ancestry': the ancestry of the shape changed, but the shape itself may not have done
|
|
69
|
+
*/
|
|
70
|
+
reason: 'self' | 'ancestry'
|
|
65
71
|
}
|
|
66
72
|
|
|
67
73
|
/**
|
|
@@ -1,41 +1,42 @@
|
|
|
1
1
|
import { Computed, RESET_VALUE, computed, isUninitialized } from '@tldraw/state'
|
|
2
|
-
import { TLBinding, TLShapeId } from '@tldraw/tlschema'
|
|
2
|
+
import { TLArrowBinding, TLBinding, TLShapeId, TLUnknownBinding } from '@tldraw/tlschema'
|
|
3
3
|
import { objectMapValues } from '@tldraw/utils'
|
|
4
4
|
import { Editor } from '../Editor'
|
|
5
5
|
|
|
6
6
|
type TLBindingsIndex = Map<TLShapeId, TLBinding[]>
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
const bindingsHistory = store.query.filterHistory('binding')
|
|
11
|
-
const bindingsQuery = store.query.records('binding')
|
|
12
|
-
function fromScratch() {
|
|
13
|
-
const allBindings = bindingsQuery.get() as TLBinding[]
|
|
8
|
+
function fromScratch(bindingsQuery: Computed<(TLArrowBinding | TLUnknownBinding)[], unknown>) {
|
|
9
|
+
const allBindings = bindingsQuery.get() as TLBinding[]
|
|
14
10
|
|
|
15
|
-
|
|
11
|
+
const shapesToBindings: TLBindingsIndex = new Map()
|
|
16
12
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
13
|
+
for (const binding of allBindings) {
|
|
14
|
+
const { fromId, toId } = binding
|
|
15
|
+
const bindingsForFromShape = shapesToBindings.get(fromId)
|
|
16
|
+
if (!bindingsForFromShape) {
|
|
17
|
+
shapesToBindings.set(fromId, [binding])
|
|
18
|
+
} else {
|
|
19
|
+
bindingsForFromShape.push(binding)
|
|
20
|
+
}
|
|
21
|
+
const bindingsForToShape = shapesToBindings.get(toId)
|
|
22
|
+
if (!bindingsForToShape) {
|
|
23
|
+
shapesToBindings.set(toId, [binding])
|
|
24
|
+
} else {
|
|
25
|
+
bindingsForToShape.push(binding)
|
|
31
26
|
}
|
|
32
|
-
|
|
33
|
-
return shape2Binding
|
|
34
27
|
}
|
|
35
28
|
|
|
29
|
+
return shapesToBindings
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export const bindingsIndex = (editor: Editor): Computed<TLBindingsIndex> => {
|
|
33
|
+
const { store } = editor
|
|
34
|
+
const bindingsHistory = store.query.filterHistory('binding')
|
|
35
|
+
const bindingsQuery = store.query.records('binding')
|
|
36
|
+
|
|
36
37
|
return computed<TLBindingsIndex>('arrowBindingsIndex', (_lastValue, lastComputedEpoch) => {
|
|
37
38
|
if (isUninitialized(_lastValue)) {
|
|
38
|
-
return fromScratch()
|
|
39
|
+
return fromScratch(bindingsQuery)
|
|
39
40
|
}
|
|
40
41
|
|
|
41
42
|
const lastValue = _lastValue
|
|
@@ -43,7 +44,7 @@ export const bindingsIndex = (editor: Editor): Computed<TLBindingsIndex> => {
|
|
|
43
44
|
const diff = bindingsHistory.getDiffSince(lastComputedEpoch)
|
|
44
45
|
|
|
45
46
|
if (diff === RESET_VALUE) {
|
|
46
|
-
return fromScratch()
|
|
47
|
+
return fromScratch(bindingsQuery)
|
|
47
48
|
}
|
|
48
49
|
|
|
49
50
|
let nextValue: TLBindingsIndex | undefined = undefined
|
|
@@ -1,45 +1,48 @@
|
|
|
1
|
-
import { computed, isUninitialized, RESET_VALUE } from '@tldraw/state'
|
|
2
|
-
import { RecordsDiff } from '@tldraw/store'
|
|
1
|
+
import { Computed, computed, isUninitialized, RESET_VALUE } from '@tldraw/state'
|
|
2
|
+
import { CollectionDiff, RecordsDiff } from '@tldraw/store'
|
|
3
3
|
import { isShape, TLParentId, TLRecord, TLShape, TLShapeId, TLStore } from '@tldraw/tlschema'
|
|
4
4
|
import { compact, sortByIndex } from '@tldraw/utils'
|
|
5
5
|
|
|
6
|
-
type
|
|
6
|
+
type ParentShapeIdsToChildShapeIds = Record<TLParentId, TLShapeId[]>
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
function fromScratch(
|
|
9
|
+
shapeIdsQuery: Computed<Set<TLShapeId>, CollectionDiff<TLShapeId>>,
|
|
10
|
+
store: TLStore
|
|
11
|
+
) {
|
|
12
|
+
const result: ParentShapeIdsToChildShapeIds = {}
|
|
13
|
+
const shapeIds = shapeIdsQuery.get()
|
|
14
|
+
const shapes = Array(shapeIds.size) as TLShape[]
|
|
15
|
+
shapeIds.forEach((id) => shapes.push(store.get(id)!))
|
|
11
16
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const shapeIds = shapeIdsQuery.get()
|
|
15
|
-
const shapes = Array(shapeIds.size) as TLShape[]
|
|
16
|
-
shapeIds.forEach((id) => shapes.push(store.get(id)!))
|
|
17
|
+
// Sort the shapes by index
|
|
18
|
+
shapes.sort(sortByIndex)
|
|
17
19
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
+
// Populate the result object with an array for each parent.
|
|
21
|
+
shapes.forEach((shape) => {
|
|
22
|
+
if (!result[shape.parentId]) {
|
|
23
|
+
result[shape.parentId] = []
|
|
24
|
+
}
|
|
25
|
+
result[shape.parentId].push(shape.id)
|
|
26
|
+
})
|
|
20
27
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
if (!result[shape.parentId]) {
|
|
24
|
-
result[shape.parentId] = []
|
|
25
|
-
}
|
|
26
|
-
result[shape.parentId].push(shape.id)
|
|
27
|
-
})
|
|
28
|
+
return result
|
|
29
|
+
}
|
|
28
30
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
export const parentsToChildren = (store: TLStore) => {
|
|
32
|
+
const shapeIdsQuery = store.query.ids<'shape'>('shape')
|
|
33
|
+
const shapeHistory = store.query.filterHistory('shape')
|
|
31
34
|
|
|
32
|
-
return computed<
|
|
35
|
+
return computed<ParentShapeIdsToChildShapeIds>(
|
|
33
36
|
'parentsToChildrenWithIndexes',
|
|
34
37
|
(lastValue, lastComputedEpoch) => {
|
|
35
38
|
if (isUninitialized(lastValue)) {
|
|
36
|
-
return fromScratch()
|
|
39
|
+
return fromScratch(shapeIdsQuery, store)
|
|
37
40
|
}
|
|
38
41
|
|
|
39
42
|
const diff = shapeHistory.getDiffSince(lastComputedEpoch)
|
|
40
43
|
|
|
41
44
|
if (diff === RESET_VALUE) {
|
|
42
|
-
return fromScratch()
|
|
45
|
+
return fromScratch(shapeIdsQuery, store)
|
|
43
46
|
}
|
|
44
47
|
|
|
45
48
|
if (diff.length === 0) return lastValue
|