@tldraw/editor 3.14.0-canary.fdbfe5bf2604 → 3.14.0-canary.fea5990646e1

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.
Files changed (61) hide show
  1. package/dist-cjs/index.d.ts +13 -98
  2. package/dist-cjs/index.js +1 -4
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/editor/Editor.js +24 -57
  5. package/dist-cjs/lib/editor/Editor.js.map +2 -2
  6. package/dist-cjs/lib/editor/managers/HistoryManager/HistoryManager.js +1 -3
  7. package/dist-cjs/lib/editor/managers/HistoryManager/HistoryManager.js.map +2 -2
  8. package/dist-cjs/lib/editor/managers/TextManager/TextManager.js +2 -2
  9. package/dist-cjs/lib/editor/managers/TextManager/TextManager.js.map +2 -2
  10. package/dist-cjs/lib/editor/shapes/ShapeUtil.js +10 -0
  11. package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
  12. package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/children/Pointing.js +6 -10
  13. package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/children/Pointing.js.map +3 -3
  14. package/dist-cjs/lib/editor/types/emit-types.js.map +1 -1
  15. package/dist-cjs/lib/primitives/geometry/Geometry2d.js +2 -6
  16. package/dist-cjs/lib/primitives/geometry/Geometry2d.js.map +2 -2
  17. package/dist-cjs/lib/primitives/geometry/Group2d.js +6 -11
  18. package/dist-cjs/lib/primitives/geometry/Group2d.js.map +2 -2
  19. package/dist-cjs/lib/utils/dom.js +1 -1
  20. package/dist-cjs/lib/utils/dom.js.map +2 -2
  21. package/dist-cjs/version.js +3 -3
  22. package/dist-cjs/version.js.map +1 -1
  23. package/dist-esm/index.d.mts +13 -98
  24. package/dist-esm/index.mjs +1 -4
  25. package/dist-esm/index.mjs.map +2 -2
  26. package/dist-esm/lib/editor/Editor.mjs +24 -57
  27. package/dist-esm/lib/editor/Editor.mjs.map +2 -2
  28. package/dist-esm/lib/editor/managers/HistoryManager/HistoryManager.mjs +1 -3
  29. package/dist-esm/lib/editor/managers/HistoryManager/HistoryManager.mjs.map +2 -2
  30. package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs +2 -2
  31. package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs.map +2 -2
  32. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs +10 -0
  33. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
  34. package/dist-esm/lib/editor/tools/BaseBoxShapeTool/children/Pointing.mjs +6 -10
  35. package/dist-esm/lib/editor/tools/BaseBoxShapeTool/children/Pointing.mjs.map +3 -3
  36. package/dist-esm/lib/primitives/geometry/Geometry2d.mjs +2 -6
  37. package/dist-esm/lib/primitives/geometry/Geometry2d.mjs.map +2 -2
  38. package/dist-esm/lib/primitives/geometry/Group2d.mjs +6 -11
  39. package/dist-esm/lib/primitives/geometry/Group2d.mjs.map +2 -2
  40. package/dist-esm/lib/utils/dom.mjs +1 -1
  41. package/dist-esm/lib/utils/dom.mjs.map +2 -2
  42. package/dist-esm/version.mjs +3 -3
  43. package/dist-esm/version.mjs.map +1 -1
  44. package/editor.css +11 -17
  45. package/package.json +7 -7
  46. package/src/index.ts +0 -5
  47. package/src/lib/editor/Editor.ts +35 -75
  48. package/src/lib/editor/managers/HistoryManager/HistoryManager.ts +1 -3
  49. package/src/lib/editor/managers/TextManager/TextManager.ts +2 -3
  50. package/src/lib/editor/shapes/ShapeUtil.ts +15 -47
  51. package/src/lib/editor/tools/BaseBoxShapeTool/children/Pointing.ts +17 -22
  52. package/src/lib/editor/types/emit-types.ts +0 -4
  53. package/src/lib/primitives/geometry/Geometry2d.ts +2 -7
  54. package/src/lib/primitives/geometry/Group2d.ts +5 -11
  55. package/src/lib/utils/dom.ts +1 -1
  56. package/src/version.ts +3 -3
  57. package/dist-cjs/lib/utils/reparenting.js +0 -232
  58. package/dist-cjs/lib/utils/reparenting.js.map +0 -7
  59. package/dist-esm/lib/utils/reparenting.mjs +0 -216
  60. package/dist-esm/lib/utils/reparenting.mjs.map +0 -7
  61. package/src/lib/utils/reparenting.ts +0 -383
@@ -4,15 +4,12 @@ import { LegacyMigrations, MigrationSequence } from '@tldraw/store'
4
4
  import {
5
5
  RecordProps,
6
6
  TLHandle,
7
- TLParentId,
8
7
  TLPropsMigrations,
9
8
  TLShape,
10
9
  TLShapeCrop,
11
- TLShapeId,
12
10
  TLShapePartial,
13
11
  TLUnknownShape,
14
12
  } from '@tldraw/tlschema'
15
- import { IndexKey } from '@tldraw/utils'
16
13
  import { ReactElement } from 'react'
17
14
  import { Box, SelectionHandle } from '../../primitives/Box'
18
15
  import { Vec } from '../../primitives/Vec'
@@ -390,6 +387,17 @@ export abstract class ShapeUtil<Shape extends TLUnknownShape = TLUnknownShape> {
390
387
  return false
391
388
  }
392
389
 
390
+ /**
391
+ * Get whether the shape can receive children of a given type.
392
+ *
393
+ * @param shape - The shape type.
394
+ * @param shapes - The shapes that are being dropped.
395
+ * @public
396
+ */
397
+ canDropShapes(_shape: Shape, _shapes: TLShape[]) {
398
+ return false
399
+ }
400
+
393
401
  /**
394
402
  * Get the shape as an SVG object.
395
403
  *
@@ -509,16 +517,7 @@ export abstract class ShapeUtil<Shape extends TLUnknownShape = TLUnknownShape> {
509
517
  ): Omit<TLShapePartial<Shape>, 'id' | 'type'> | undefined | void
510
518
 
511
519
  /**
512
- * A callback called when some other shapes are dragged into this one. This fires when the shapes are dragged over the shape for the first time.
513
- *
514
- * @param shape - The shape.
515
- * @param shapes - The shapes that are being dragged in.
516
- * @public
517
- */
518
- onDragShapesIn?(shape: Shape, shapes: TLShape[], info: TLDragShapesInInfo): void
519
-
520
- /**
521
- * A callback called when some other shapes are dragged over this one. This fires when the shapes are dragged over the shape for the first time (after the onDragShapesIn callback), and again on every update while the shapes are being dragged.
520
+ * A callback called when some other shapes are dragged over this one.
522
521
  *
523
522
  * @example
524
523
  *
@@ -532,7 +531,7 @@ export abstract class ShapeUtil<Shape extends TLUnknownShape = TLUnknownShape> {
532
531
  * @param shapes - The shapes that are being dragged over this one.
533
532
  * @public
534
533
  */
535
- onDragShapesOver?(shape: Shape, shapes: TLShape[], info: TLDragShapesOverInfo): void
534
+ onDragShapesOver?(shape: Shape, shapes: TLShape[]): void
536
535
 
537
536
  /**
538
537
  * A callback called when some other shapes are dragged out of this one.
@@ -541,7 +540,7 @@ export abstract class ShapeUtil<Shape extends TLUnknownShape = TLUnknownShape> {
541
540
  * @param shapes - The shapes that are being dragged out.
542
541
  * @public
543
542
  */
544
- onDragShapesOut?(shape: Shape, shapes: TLShape[], info: TLDragShapesOutInfo): void
543
+ onDragShapesOut?(shape: Shape, shapes: TLShape[]): void
545
544
 
546
545
  /**
547
546
  * A callback called when some other shapes are dropped over this one.
@@ -550,7 +549,7 @@ export abstract class ShapeUtil<Shape extends TLUnknownShape = TLUnknownShape> {
550
549
  * @param shapes - The shapes that are being dropped over this one.
551
550
  * @public
552
551
  */
553
- onDropShapesOver?(shape: Shape, shapes: TLShape[], info: TLDropShapesOverInfo): void
552
+ onDropShapesOver?(shape: Shape, shapes: TLShape[]): void
554
553
 
555
554
  /**
556
555
  * A callback called when a shape starts being resized.
@@ -746,37 +745,6 @@ export interface TLCropInfo<T extends TLShape> {
746
745
  crop: TLShapeCrop
747
746
  uncroppedSize: { w: number; h: number }
748
747
  initialShape: T
749
- aspectRatioLocked?: boolean
750
- }
751
-
752
- /** @public */
753
- export interface TLDragShapesInInfo {
754
- initialDraggingOverShapeId: TLShapeId | null
755
- prevDraggingOverShapeId: TLShapeId | null
756
- initialParentIds: Map<TLShapeId, TLParentId>
757
- initialIndices: Map<TLShapeId, IndexKey>
758
- }
759
-
760
- /** @public */
761
- export interface TLDragShapesOverInfo {
762
- initialDraggingOverShapeId: TLShapeId | null
763
- initialParentIds: Map<TLShapeId, TLParentId>
764
- initialIndices: Map<TLShapeId, IndexKey>
765
- }
766
-
767
- /** @public */
768
- export interface TLDragShapesOutInfo {
769
- nextDraggingOverShapeId: TLShapeId | null
770
- initialDraggingOverShapeId: TLShapeId | null
771
- initialParentIds: Map<TLShapeId, TLParentId>
772
- initialIndices: Map<TLShapeId, IndexKey>
773
- }
774
-
775
- /** @public */
776
- export interface TLDropShapesOverInfo {
777
- initialDraggingOverShapeId: TLShapeId | null
778
- initialParentIds: Map<TLShapeId, TLParentId>
779
- initialIndices: Map<TLShapeId, IndexKey>
780
748
  }
781
749
 
782
750
  /**
@@ -11,33 +11,29 @@ export class Pointing extends StateNode {
11
11
  static override id = 'pointing'
12
12
 
13
13
  override onPointerMove(info: TLPointerEventInfo) {
14
- const { editor } = this
15
- if (editor.inputs.isDragging) {
16
- const { originPagePoint } = editor.inputs
14
+ if (this.editor.inputs.isDragging) {
15
+ const { originPagePoint } = this.editor.inputs
17
16
 
18
17
  const shapeType = (this.parent as BaseBoxShapeTool)!.shapeType
19
18
 
20
19
  const id = createShapeId()
21
20
 
22
- const creatingMarkId = editor.markHistoryStoppingPoint(`creating_box:${id}`)
23
- const newPoint = maybeSnapToGrid(originPagePoint, editor)
24
-
25
- // Allow this to trigger the max shapes reached alert
26
- this.editor.createShapes<TLBaseBoxShape>([
27
- {
28
- id,
29
- type: shapeType,
30
- x: newPoint.x,
31
- y: newPoint.y,
32
- props: {
33
- w: 1,
34
- h: 1,
21
+ const creatingMarkId = this.editor.markHistoryStoppingPoint(`creating_box:${id}`)
22
+ const newPoint = maybeSnapToGrid(originPagePoint, this.editor)
23
+ this.editor
24
+ .createShapes<TLBaseBoxShape>([
25
+ {
26
+ id,
27
+ type: shapeType,
28
+ x: newPoint.x,
29
+ y: newPoint.y,
30
+ props: {
31
+ w: 1,
32
+ h: 1,
33
+ },
35
34
  },
36
- },
37
- ])
38
- const shape = editor.getShape(id)
39
- if (!shape) this.cancel()
40
- editor.select(id)
35
+ ])
36
+ .select(id)
41
37
 
42
38
  const parent = this.parent as BaseBoxShapeTool
43
39
  this.editor.setCurrentTool(
@@ -83,7 +79,6 @@ export class Pointing extends StateNode {
83
79
 
84
80
  this.editor.markHistoryStoppingPoint(`creating_box:${id}`)
85
81
 
86
- // Allow this to trigger the max shapes reached alert
87
82
  // todo: add scale here when dynamic size is enabled (is this still needed?)
88
83
  this.editor.createShapes<TLBaseBoxShape>([
89
84
  {
@@ -18,10 +18,6 @@ export interface TLEventMap {
18
18
  frame: [number]
19
19
  'select-all-text': [{ shapeId: TLShapeId }]
20
20
  'place-caret': [{ shapeId: TLShapeId; point: { x: number; y: number } }]
21
- 'created-shapes': [TLRecord[]]
22
- 'edited-shapes': [TLRecord[]]
23
- 'deleted-shapes': [TLShapeId[]]
24
- edit: []
25
21
  }
26
22
 
27
23
  /** @public */
@@ -44,7 +44,6 @@ export const Geometry2dFilters: {
44
44
  /** @public */
45
45
  export interface TransformedGeometry2dOptions {
46
46
  isLabel?: boolean
47
- isEmptyLabel?: boolean
48
47
  isInternal?: boolean
49
48
  debugColor?: string
50
49
  ignore?: boolean
@@ -58,24 +57,20 @@ export interface Geometry2dOptions extends TransformedGeometry2dOptions {
58
57
 
59
58
  /** @public */
60
59
  export abstract class Geometry2d {
61
- // todo: consider making accessors for these too, so that they can be overridden in subclasses by geometries with more complex logic
62
60
  isFilled = false
63
61
  isClosed = true
64
62
  isLabel = false
65
- isEmptyLabel = false
66
63
  isInternal = false
67
64
  debugColor?: string
68
65
  ignore?: boolean
69
66
 
70
67
  constructor(opts: Geometry2dOptions) {
71
- const { isLabel = false, isEmptyLabel = false, isInternal = false } = opts
72
68
  this.isFilled = opts.isFilled
73
69
  this.isClosed = opts.isClosed
70
+ this.isLabel = opts.isLabel ?? false
71
+ this.isInternal = opts.isInternal ?? false
74
72
  this.debugColor = opts.debugColor
75
73
  this.ignore = opts.ignore
76
- this.isLabel = isLabel
77
- this.isEmptyLabel = isEmptyLabel
78
- this.isInternal = isInternal
79
74
  }
80
75
 
81
76
  isExcludedByFilter(filters?: Geometry2dFilters) {
@@ -17,20 +17,14 @@ export class Group2d extends Geometry2d {
17
17
  ) {
18
18
  super({ ...config, isClosed: true, isFilled: false })
19
19
 
20
- const addChildren = (children: Geometry2d[]) => {
21
- for (const child of children) {
22
- if (child instanceof Group2d) {
23
- addChildren(child.children)
24
- } else if (child.ignore) {
25
- this.ignoredChildren.push(child)
26
- } else {
27
- this.children.push(child)
28
- }
20
+ for (const child of config.children) {
21
+ if (child.ignore) {
22
+ this.ignoredChildren.push(child)
23
+ } else {
24
+ this.children.push(child)
29
25
  }
30
26
  }
31
27
 
32
- addChildren(config.children)
33
-
34
28
  if (this.children.length === 0) throw Error('Group2d must have at least one child')
35
29
  }
36
30
 
@@ -18,7 +18,7 @@ import { debugFlags, pointerCaptureTrackingObject } from './debug-flags'
18
18
 
19
19
  /** @public */
20
20
  export function loopToHtmlElement(elm: Element): HTMLElement {
21
- if (elm.nodeType === Node.ELEMENT_NODE) return elm as HTMLElement
21
+ if (elm instanceof HTMLElement) return elm
22
22
  if (elm.parentElement) return loopToHtmlElement(elm.parentElement)
23
23
  else throw Error('Could not find a parent element of an HTML type!')
24
24
  }
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.14.0-canary.fdbfe5bf2604'
4
+ export const version = '3.14.0-canary.fea5990646e1'
5
5
  export const publishDates = {
6
6
  major: '2024-09-13T14:36:29.063Z',
7
- minor: '2025-07-01T09:03:39.076Z',
8
- patch: '2025-07-01T09:03:39.076Z',
7
+ minor: '2025-06-23T08:56:17.973Z',
8
+ patch: '2025-06-23T08:56:17.973Z',
9
9
  }
@@ -1,232 +0,0 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
- var reparenting_exports = {};
20
- __export(reparenting_exports, {
21
- doesGeometryOverlapPolygon: () => doesGeometryOverlapPolygon,
22
- getDroppedShapesToNewParents: () => getDroppedShapesToNewParents,
23
- kickoutOccludedShapes: () => kickoutOccludedShapes
24
- });
25
- module.exports = __toCommonJS(reparenting_exports);
26
- var import_state = require("@tldraw/state");
27
- var import_utils = require("@tldraw/utils");
28
- var import_Group2d = require("../primitives/geometry/Group2d");
29
- var import_intersect = require("../primitives/intersect");
30
- var import_utils2 = require("../primitives/utils");
31
- function kickoutOccludedShapes(editor, shapeIds, opts) {
32
- const parentsToCheck = /* @__PURE__ */ new Set();
33
- for (const id of shapeIds) {
34
- const shape = editor.getShape(id);
35
- if (!shape) continue;
36
- parentsToCheck.add(shape);
37
- const parent = editor.getShape(shape.parentId);
38
- if (!parent) continue;
39
- parentsToCheck.add(parent);
40
- }
41
- const parentsToLostChildren = /* @__PURE__ */ new Map();
42
- for (const parent of parentsToCheck) {
43
- const childIds = editor.getSortedChildIdsForParent(parent);
44
- if (opts?.filter && !opts.filter(parent)) {
45
- parentsToLostChildren.set(parent, childIds);
46
- } else {
47
- const overlappingChildren = getOverlappingShapes(editor, parent.id, childIds);
48
- if (overlappingChildren.length < childIds.length) {
49
- parentsToLostChildren.set(
50
- parent,
51
- childIds.filter((id) => !overlappingChildren.includes(id))
52
- );
53
- }
54
- }
55
- }
56
- const sortedShapeIds = editor.getCurrentPageShapesSorted().map((s) => s.id);
57
- const parentsToNewChildren = {};
58
- for (const [prevParent, lostChildrenIds] of parentsToLostChildren) {
59
- const lostChildren = (0, import_utils.compact)(lostChildrenIds.map((id) => editor.getShape(id)));
60
- const { reparenting, remainingShapesToReparent } = getDroppedShapesToNewParents(
61
- editor,
62
- lostChildren,
63
- (shape, maybeNewParent) => {
64
- if (opts?.filter && !opts.filter(maybeNewParent)) return false;
65
- return maybeNewParent.id !== prevParent.id && sortedShapeIds.indexOf(maybeNewParent.id) < sortedShapeIds.indexOf(shape.id);
66
- }
67
- );
68
- reparenting.forEach((childrenToReparent, newParentId) => {
69
- if (childrenToReparent.length === 0) return;
70
- if (!parentsToNewChildren[newParentId]) {
71
- parentsToNewChildren[newParentId] = {
72
- parentId: newParentId,
73
- shapeIds: []
74
- };
75
- }
76
- parentsToNewChildren[newParentId].shapeIds.push(...childrenToReparent.map((s) => s.id));
77
- });
78
- if (remainingShapesToReparent.size > 0) {
79
- const newParentId = editor.findShapeAncestor(prevParent, (s) => editor.isShapeOfType(s, "group"))?.id ?? editor.getCurrentPageId();
80
- remainingShapesToReparent.forEach((shape) => {
81
- if (!parentsToNewChildren[newParentId]) {
82
- let insertIndexKey;
83
- const oldParentSiblingIds = editor.getSortedChildIdsForParent(newParentId);
84
- const oldParentIndex = oldParentSiblingIds.indexOf(prevParent.id);
85
- if (oldParentIndex > -1) {
86
- const siblingsIndexAbove = oldParentSiblingIds[oldParentIndex + 1];
87
- const indexKeyAbove = siblingsIndexAbove ? editor.getShape(siblingsIndexAbove).index : (0, import_utils.getIndexAbove)(prevParent.index);
88
- insertIndexKey = (0, import_utils.getIndexBetween)(prevParent.index, indexKeyAbove);
89
- } else {
90
- }
91
- parentsToNewChildren[newParentId] = {
92
- parentId: newParentId,
93
- shapeIds: [],
94
- index: insertIndexKey
95
- };
96
- }
97
- parentsToNewChildren[newParentId].shapeIds.push(shape.id);
98
- });
99
- }
100
- }
101
- editor.run(() => {
102
- Object.values(parentsToNewChildren).forEach(({ parentId, shapeIds: shapeIds2, index }) => {
103
- if (shapeIds2.length === 0) return;
104
- shapeIds2.sort((a, b) => sortedShapeIds.indexOf(a) < sortedShapeIds.indexOf(b) ? -1 : 1);
105
- editor.reparentShapes(shapeIds2, parentId, index);
106
- });
107
- });
108
- }
109
- function getOverlappingShapes(editor, shape, otherShapes) {
110
- if (otherShapes.length === 0) {
111
- return import_state.EMPTY_ARRAY;
112
- }
113
- const parentPageBounds = editor.getShapePageBounds(shape);
114
- if (!parentPageBounds) return import_state.EMPTY_ARRAY;
115
- const parentGeometry = editor.getShapeGeometry(shape);
116
- const parentPageTransform = editor.getShapePageTransform(shape);
117
- const parentPageCorners = parentPageTransform.applyToPoints(parentGeometry.vertices);
118
- const parentPageMaskVertices = editor.getShapeMask(shape);
119
- const parentPagePolygon = parentPageMaskVertices ? (0, import_intersect.intersectPolygonPolygon)(parentPageMaskVertices, parentPageCorners) : parentPageCorners;
120
- if (!parentPagePolygon) return import_state.EMPTY_ARRAY;
121
- return otherShapes.filter((childId) => {
122
- const shapePageBounds = editor.getShapePageBounds(childId);
123
- if (!shapePageBounds || !parentPageBounds.includes(shapePageBounds)) return false;
124
- const parentPolygonInShapeShape = editor.getShapePageTransform(childId).clone().invert().applyToPoints(parentPagePolygon);
125
- const geometry = editor.getShapeGeometry(childId);
126
- return doesGeometryOverlapPolygon(geometry, parentPolygonInShapeShape);
127
- });
128
- }
129
- function doesGeometryOverlapPolygon(geometry, parentCornersInShapeSpace) {
130
- if (geometry instanceof import_Group2d.Group2d) {
131
- return geometry.children.some(
132
- (childGeometry) => doesGeometryOverlapPolygon(childGeometry, parentCornersInShapeSpace)
133
- );
134
- }
135
- const { vertices, center, isFilled, isEmptyLabel, isClosed } = geometry;
136
- if (isEmptyLabel) return false;
137
- if (vertices.some((v) => (0, import_utils2.pointInPolygon)(v, parentCornersInShapeSpace))) {
138
- return true;
139
- }
140
- if (isClosed) {
141
- if (isFilled) {
142
- if ((0, import_utils2.pointInPolygon)(center, parentCornersInShapeSpace)) {
143
- return true;
144
- }
145
- if (parentCornersInShapeSpace.every((v) => (0, import_utils2.pointInPolygon)(v, vertices))) {
146
- return true;
147
- }
148
- }
149
- if ((0, import_intersect.polygonsIntersect)(parentCornersInShapeSpace, vertices)) {
150
- return true;
151
- }
152
- } else {
153
- if ((0, import_intersect.polygonIntersectsPolyline)(parentCornersInShapeSpace, vertices)) {
154
- return true;
155
- }
156
- }
157
- return false;
158
- }
159
- function getDroppedShapesToNewParents(editor, shapes, cb) {
160
- const shapesToActuallyCheck = new Set(shapes);
161
- const movingGroups = /* @__PURE__ */ new Set();
162
- for (const shape of shapes) {
163
- const parent = editor.getShapeParent(shape);
164
- if (parent && editor.isShapeOfType(parent, "group")) {
165
- if (!movingGroups.has(parent)) {
166
- movingGroups.add(parent);
167
- }
168
- }
169
- }
170
- for (const movingGroup of movingGroups) {
171
- const children = (0, import_utils.compact)(
172
- editor.getSortedChildIdsForParent(movingGroup).map((id) => editor.getShape(id))
173
- );
174
- for (const child of children) {
175
- shapesToActuallyCheck.delete(child);
176
- }
177
- shapesToActuallyCheck.add(movingGroup);
178
- }
179
- const shapeGroupIds = /* @__PURE__ */ new Map();
180
- const reparenting = /* @__PURE__ */ new Map();
181
- const remainingShapesToReparent = new Set(shapesToActuallyCheck);
182
- const potentialParentShapes = editor.getCurrentPageShapesSorted().filter(
183
- (s) => editor.getShapeUtil(s).canReceiveNewChildrenOfType?.(s, s.type) && !remainingShapesToReparent.has(s)
184
- );
185
- parentCheck: for (let i = potentialParentShapes.length - 1; i >= 0; i--) {
186
- const parentShape = potentialParentShapes[i];
187
- const parentShapeContainingGroupId = editor.findShapeAncestor(
188
- parentShape,
189
- (s) => editor.isShapeOfType(s, "group")
190
- )?.id;
191
- const parentGeometry = editor.getShapeGeometry(parentShape);
192
- const parentPageTransform = editor.getShapePageTransform(parentShape);
193
- const parentPageMaskVertices = editor.getShapeMask(parentShape);
194
- const parentPageCorners = parentPageTransform.applyToPoints(parentGeometry.vertices);
195
- const parentPagePolygon = parentPageMaskVertices ? (0, import_intersect.intersectPolygonPolygon)(parentPageMaskVertices, parentPageCorners) : parentPageCorners;
196
- if (!parentPagePolygon) continue parentCheck;
197
- const childrenToReparent = [];
198
- shapeCheck: for (const shape of remainingShapesToReparent) {
199
- if (parentShape.id === shape.id) continue shapeCheck;
200
- if (cb && !cb(shape, parentShape)) continue shapeCheck;
201
- if (!shapeGroupIds.has(shape.id)) {
202
- shapeGroupIds.set(
203
- shape.id,
204
- editor.findShapeAncestor(shape, (s) => editor.isShapeOfType(s, "group"))?.id
205
- );
206
- }
207
- const shapeGroupId = shapeGroupIds.get(shape.id);
208
- if (shapeGroupId !== parentShapeContainingGroupId) continue shapeCheck;
209
- if (editor.findShapeAncestor(parentShape, (s) => shape.id === s.id)) continue shapeCheck;
210
- const parentPolygonInShapeSpace = editor.getShapePageTransform(shape).clone().invert().applyToPoints(parentPagePolygon);
211
- if (doesGeometryOverlapPolygon(editor.getShapeGeometry(shape), parentPolygonInShapeSpace)) {
212
- if (!editor.getShapeUtil(parentShape).canReceiveNewChildrenOfType?.(parentShape, shape.type))
213
- continue shapeCheck;
214
- if (shape.parentId !== parentShape.id) {
215
- childrenToReparent.push(shape);
216
- }
217
- remainingShapesToReparent.delete(shape);
218
- continue shapeCheck;
219
- }
220
- }
221
- if (childrenToReparent.length) {
222
- reparenting.set(parentShape.id, childrenToReparent);
223
- }
224
- }
225
- return {
226
- // these are the shapes that will be reparented to new parents
227
- reparenting,
228
- // these are the shapes that will be reparented to the page or their ancestral group
229
- remainingShapesToReparent
230
- };
231
- }
232
- //# sourceMappingURL=reparenting.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/lib/utils/reparenting.ts"],
4
- "sourcesContent": ["import { EMPTY_ARRAY } from '@tldraw/state'\nimport { TLGroupShape, TLParentId, TLShape, TLShapeId } from '@tldraw/tlschema'\nimport { IndexKey, compact, getIndexAbove, getIndexBetween } from '@tldraw/utils'\nimport { Editor } from '../editor/Editor'\nimport { Vec } from '../primitives/Vec'\nimport { Geometry2d } from '../primitives/geometry/Geometry2d'\nimport { Group2d } from '../primitives/geometry/Group2d'\nimport {\n\tintersectPolygonPolygon,\n\tpolygonIntersectsPolyline,\n\tpolygonsIntersect,\n} from '../primitives/intersect'\nimport { pointInPolygon } from '../primitives/utils'\n\n/**\n * Reparents shapes that are no longer contained within their parent shapes.\n * todo: rename me to something more descriptive, like `reparentOccludedShapes` or `reparentAutoDroppedShapes`\n *\n * @param editor - The editor instance.\n * @param shapeIds - The IDs of the shapes to reparent.\n * @param opts - Optional options, including a callback to filter out certain parents, such as when removing a frame.\n *\n * @public\n */\nexport function kickoutOccludedShapes(\n\teditor: Editor,\n\tshapeIds: TLShapeId[],\n\topts?: { filter?(parent: TLShape): boolean }\n) {\n\tconst parentsToCheck = new Set<TLShape>()\n\n\tfor (const id of shapeIds) {\n\t\tconst shape = editor.getShape(id)\n\n\t\tif (!shape) continue\n\t\tparentsToCheck.add(shape)\n\n\t\tconst parent = editor.getShape(shape.parentId)\n\t\tif (!parent) continue\n\t\tparentsToCheck.add(parent)\n\t}\n\n\t// Check all of the parents and gather up parents who have lost children\n\tconst parentsToLostChildren = new Map<TLShape, TLShapeId[]>()\n\n\tfor (const parent of parentsToCheck) {\n\t\tconst childIds = editor.getSortedChildIdsForParent(parent)\n\t\tif (opts?.filter && !opts.filter(parent)) {\n\t\t\t// If the shape is filtered out, we kick out all of its children\n\t\t\tparentsToLostChildren.set(parent, childIds)\n\t\t} else {\n\t\t\tconst overlappingChildren = getOverlappingShapes(editor, parent.id, childIds)\n\t\t\tif (overlappingChildren.length < childIds.length) {\n\t\t\t\tparentsToLostChildren.set(\n\t\t\t\t\tparent,\n\t\t\t\t\tchildIds.filter((id) => !overlappingChildren.includes(id))\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t}\n\n\t// Get all of the shapes on the current page, sorted by their index\n\tconst sortedShapeIds = editor.getCurrentPageShapesSorted().map((s) => s.id)\n\n\tconst parentsToNewChildren: Record<\n\t\tTLParentId,\n\t\t{ parentId: TLParentId; shapeIds: TLShapeId[]; index?: IndexKey }\n\t> = {}\n\n\tfor (const [prevParent, lostChildrenIds] of parentsToLostChildren) {\n\t\tconst lostChildren = compact(lostChildrenIds.map((id) => editor.getShape(id)))\n\n\t\t// Don't fall \"up\" into frames in front of the shape\n\t\t// if (pageShapes.indexOf(shape) < frameSortPosition) continue shapeCheck\n\n\t\t// Otherwise, we have no next dropping shape under the cursor, so go find\n\t\t// all the frames on the page where the moving shapes will fall into\n\t\tconst { reparenting, remainingShapesToReparent } = getDroppedShapesToNewParents(\n\t\t\teditor,\n\t\t\tlostChildren,\n\t\t\t(shape, maybeNewParent) => {\n\t\t\t\t// If we're filtering out a potential parent, don't reparent shapes to the filtered out shape\n\t\t\t\tif (opts?.filter && !opts.filter(maybeNewParent)) return false\n\t\t\t\treturn (\n\t\t\t\t\tmaybeNewParent.id !== prevParent.id &&\n\t\t\t\t\tsortedShapeIds.indexOf(maybeNewParent.id) < sortedShapeIds.indexOf(shape.id)\n\t\t\t\t)\n\t\t\t}\n\t\t)\n\n\t\treparenting.forEach((childrenToReparent, newParentId) => {\n\t\t\tif (childrenToReparent.length === 0) return\n\t\t\tif (!parentsToNewChildren[newParentId]) {\n\t\t\t\tparentsToNewChildren[newParentId] = {\n\t\t\t\t\tparentId: newParentId,\n\t\t\t\t\tshapeIds: [],\n\t\t\t\t}\n\t\t\t}\n\t\t\tparentsToNewChildren[newParentId].shapeIds.push(...childrenToReparent.map((s) => s.id))\n\t\t})\n\n\t\t// Reparent the rest to the page (or containing group)\n\t\tif (remainingShapesToReparent.size > 0) {\n\t\t\t// The remaining shapes are going to be reparented to the old parent's containing group, if there was one, or else to the page\n\t\t\tconst newParentId =\n\t\t\t\teditor.findShapeAncestor(prevParent, (s) => editor.isShapeOfType<TLGroupShape>(s, 'group'))\n\t\t\t\t\t?.id ?? editor.getCurrentPageId()\n\n\t\t\tremainingShapesToReparent.forEach((shape) => {\n\t\t\t\tif (!parentsToNewChildren[newParentId]) {\n\t\t\t\t\tlet insertIndexKey: IndexKey | undefined\n\n\t\t\t\t\tconst oldParentSiblingIds = editor.getSortedChildIdsForParent(newParentId)\n\t\t\t\t\tconst oldParentIndex = oldParentSiblingIds.indexOf(prevParent.id)\n\t\t\t\t\tif (oldParentIndex > -1) {\n\t\t\t\t\t\t// If the old parent is a direct child of the new parent, then we'll add them above the old parent but below the next sibling.\n\t\t\t\t\t\tconst siblingsIndexAbove = oldParentSiblingIds[oldParentIndex + 1]\n\t\t\t\t\t\tconst indexKeyAbove = siblingsIndexAbove\n\t\t\t\t\t\t\t? editor.getShape(siblingsIndexAbove)!.index\n\t\t\t\t\t\t\t: getIndexAbove(prevParent.index)\n\t\t\t\t\t\tinsertIndexKey = getIndexBetween(prevParent.index, indexKeyAbove)\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// If the old parent is not a direct child of the new parent, then we'll add them to the \"top\" of the new parent's children.\n\t\t\t\t\t\t// This is done automatically if we leave the index undefined, so let's do that.\n\t\t\t\t\t}\n\n\t\t\t\t\tparentsToNewChildren[newParentId] = {\n\t\t\t\t\t\tparentId: newParentId,\n\t\t\t\t\t\tshapeIds: [],\n\t\t\t\t\t\tindex: insertIndexKey,\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tparentsToNewChildren[newParentId].shapeIds.push(shape.id)\n\t\t\t})\n\t\t}\n\t}\n\n\teditor.run(() => {\n\t\tObject.values(parentsToNewChildren).forEach(({ parentId, shapeIds, index }) => {\n\t\t\tif (shapeIds.length === 0) return\n\t\t\t// Before we reparent, sort the new shape ids by their place in the original absolute order on the page\n\t\t\tshapeIds.sort((a, b) => (sortedShapeIds.indexOf(a) < sortedShapeIds.indexOf(b) ? -1 : 1))\n\t\t\teditor.reparentShapes(shapeIds, parentId, index)\n\t\t})\n\t})\n}\n\n/**\n * Get the shapes that overlap with a given shape.\n *\n * @param editor - The editor instance.\n * @param shape - The shapes or shape IDs to check against.\n * @param otherShapes - The shapes or shape IDs to check for overlap.\n * @returns An array of shapes or shape IDs that overlap with the given shape.\n */\nfunction getOverlappingShapes<T extends TLShape[] | TLShapeId[]>(\n\teditor: Editor,\n\tshape: T[number],\n\totherShapes: T\n) {\n\tif (otherShapes.length === 0) {\n\t\treturn EMPTY_ARRAY\n\t}\n\n\tconst parentPageBounds = editor.getShapePageBounds(shape)\n\tif (!parentPageBounds) return EMPTY_ARRAY\n\n\tconst parentGeometry = editor.getShapeGeometry(shape)\n\tconst parentPageTransform = editor.getShapePageTransform(shape)\n\tconst parentPageCorners = parentPageTransform.applyToPoints(parentGeometry.vertices)\n\n\tconst parentPageMaskVertices = editor.getShapeMask(shape)\n\tconst parentPagePolygon = parentPageMaskVertices\n\t\t? intersectPolygonPolygon(parentPageMaskVertices, parentPageCorners)\n\t\t: parentPageCorners\n\n\tif (!parentPagePolygon) return EMPTY_ARRAY\n\n\treturn otherShapes.filter((childId) => {\n\t\tconst shapePageBounds = editor.getShapePageBounds(childId)\n\t\tif (!shapePageBounds || !parentPageBounds.includes(shapePageBounds)) return false\n\n\t\tconst parentPolygonInShapeShape = editor\n\t\t\t.getShapePageTransform(childId)\n\t\t\t.clone()\n\t\t\t.invert()\n\t\t\t.applyToPoints(parentPagePolygon)\n\n\t\tconst geometry = editor.getShapeGeometry(childId)\n\n\t\treturn doesGeometryOverlapPolygon(geometry, parentPolygonInShapeShape)\n\t})\n}\n\n/**\n * @public\n */\nexport function doesGeometryOverlapPolygon(\n\tgeometry: Geometry2d,\n\tparentCornersInShapeSpace: Vec[]\n): boolean {\n\t// If the child is a group, check if any of its children overlap the box\n\tif (geometry instanceof Group2d) {\n\t\treturn geometry.children.some((childGeometry) =>\n\t\t\tdoesGeometryOverlapPolygon(childGeometry, parentCornersInShapeSpace)\n\t\t)\n\t}\n\n\t// Otherwise, check if the geometry overlaps the box\n\tconst { vertices, center, isFilled, isEmptyLabel, isClosed } = geometry\n\n\t// We'll do things in order of cheapest to most expensive checks\n\n\t// Skip empty labels\n\tif (isEmptyLabel) return false\n\n\t// If any of the shape's vertices are inside the occluder, it's inside\n\tif (vertices.some((v) => pointInPolygon(v, parentCornersInShapeSpace))) {\n\t\treturn true\n\t}\n\n\t// If the shape is filled and closed and its center is inside the parent, it's inside\n\tif (isClosed) {\n\t\tif (isFilled) {\n\t\t\t// If closed and filled, check if the center is inside the parent\n\t\t\tif (pointInPolygon(center, parentCornersInShapeSpace)) {\n\t\t\t\treturn true\n\t\t\t}\n\n\t\t\t// ..then, slightly more expensive check, see the shape covers the entire parent but not its center\n\t\t\tif (parentCornersInShapeSpace.every((v) => pointInPolygon(v, vertices))) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\n\t\t// If any the shape's vertices intersect the edge of the occluder, it's inside.\n\t\t// for example when a rotated rectangle is moved over the corner of a parent rectangle\n\t\t// If the child shape is closed, intersect as a polygon\n\t\tif (polygonsIntersect(parentCornersInShapeSpace, vertices)) {\n\t\t\treturn true\n\t\t}\n\t} else {\n\t\t// if the child shape is not closed, intersect as a polyline\n\t\tif (polygonIntersectsPolyline(parentCornersInShapeSpace, vertices)) {\n\t\t\treturn true\n\t\t}\n\t}\n\n\t// If none of the above checks passed, the shape is outside the parent\n\treturn false\n}\n\n/**\n * Get the shapes that will be reparented to new parents when the shapes are dropped.\n *\n * @param editor - The editor instance.\n * @param shapes - The shapes to check.\n * @param cb - A callback to filter out certain shapes.\n * @returns An object with the shapes that will be reparented to new parents and the shapes that will be reparented to the page or their ancestral group.\n *\n * @public\n */\nexport function getDroppedShapesToNewParents(\n\teditor: Editor,\n\tshapes: Set<TLShape> | TLShape[],\n\tcb?: (shape: TLShape, parent: TLShape) => boolean\n) {\n\tconst shapesToActuallyCheck = new Set<TLShape>(shapes)\n\tconst movingGroups = new Set<TLGroupShape>()\n\n\tfor (const shape of shapes) {\n\t\tconst parent = editor.getShapeParent(shape)\n\t\tif (parent && editor.isShapeOfType<TLGroupShape>(parent, 'group')) {\n\t\t\tif (!movingGroups.has(parent)) {\n\t\t\t\tmovingGroups.add(parent)\n\t\t\t}\n\t\t}\n\t}\n\n\t// If all of a group's children are moving, then move the group instead\n\tfor (const movingGroup of movingGroups) {\n\t\tconst children = compact(\n\t\t\teditor.getSortedChildIdsForParent(movingGroup).map((id) => editor.getShape(id))\n\t\t)\n\t\tfor (const child of children) {\n\t\t\tshapesToActuallyCheck.delete(child)\n\t\t}\n\t\tshapesToActuallyCheck.add(movingGroup)\n\t}\n\n\t// this could be cached and passed in\n\tconst shapeGroupIds = new Map<TLShapeId, TLShapeId | undefined>()\n\n\tconst reparenting = new Map<TLShapeId, TLShape[]>()\n\n\tconst remainingShapesToReparent = new Set(shapesToActuallyCheck)\n\n\tconst potentialParentShapes = editor\n\t\t.getCurrentPageShapesSorted()\n\t\t// filter out any shapes that aren't frames or that are included among the provided shapes\n\t\t.filter(\n\t\t\t(s) =>\n\t\t\t\teditor.getShapeUtil(s).canReceiveNewChildrenOfType?.(s, s.type) &&\n\t\t\t\t!remainingShapesToReparent.has(s)\n\t\t)\n\n\tparentCheck: for (let i = potentialParentShapes.length - 1; i >= 0; i--) {\n\t\tconst parentShape = potentialParentShapes[i]\n\t\tconst parentShapeContainingGroupId = editor.findShapeAncestor(parentShape, (s) =>\n\t\t\teditor.isShapeOfType<TLGroupShape>(s, 'group')\n\t\t)?.id\n\n\t\tconst parentGeometry = editor.getShapeGeometry(parentShape)\n\t\tconst parentPageTransform = editor.getShapePageTransform(parentShape)\n\t\tconst parentPageMaskVertices = editor.getShapeMask(parentShape)\n\t\tconst parentPageCorners = parentPageTransform.applyToPoints(parentGeometry.vertices)\n\t\tconst parentPagePolygon = parentPageMaskVertices\n\t\t\t? intersectPolygonPolygon(parentPageMaskVertices, parentPageCorners)\n\t\t\t: parentPageCorners\n\n\t\tif (!parentPagePolygon) continue parentCheck\n\n\t\tconst childrenToReparent = []\n\n\t\t// For each of the dropping shapes...\n\t\tshapeCheck: for (const shape of remainingShapesToReparent) {\n\t\t\t// Don't reparent a frame to itself\n\t\t\tif (parentShape.id === shape.id) continue shapeCheck\n\n\t\t\t// Use the callback to filter out certain shapes\n\t\t\tif (cb && !cb(shape, parentShape)) continue shapeCheck\n\n\t\t\tif (!shapeGroupIds.has(shape.id)) {\n\t\t\t\tshapeGroupIds.set(\n\t\t\t\t\tshape.id,\n\t\t\t\t\teditor.findShapeAncestor(shape, (s) => editor.isShapeOfType<TLGroupShape>(s, 'group'))?.id\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tconst shapeGroupId = shapeGroupIds.get(shape.id)\n\n\t\t\t// Are the shape and the parent part of different groups?\n\t\t\tif (shapeGroupId !== parentShapeContainingGroupId) continue shapeCheck\n\n\t\t\t// Is the shape is actually the ancestor of the parent?\n\t\t\tif (editor.findShapeAncestor(parentShape, (s) => shape.id === s.id)) continue shapeCheck\n\n\t\t\t// Convert the parent polygon to the shape's space\n\t\t\tconst parentPolygonInShapeSpace = editor\n\t\t\t\t.getShapePageTransform(shape)\n\t\t\t\t.clone()\n\t\t\t\t.invert()\n\t\t\t\t.applyToPoints(parentPagePolygon)\n\n\t\t\t// If the shape overlaps the parent polygon, reparent it to that parent\n\t\t\tif (doesGeometryOverlapPolygon(editor.getShapeGeometry(shape), parentPolygonInShapeSpace)) {\n\t\t\t\t// Use the util to check if the shape can be reparented to the parent\n\t\t\t\tif (\n\t\t\t\t\t!editor.getShapeUtil(parentShape).canReceiveNewChildrenOfType?.(parentShape, shape.type)\n\t\t\t\t)\n\t\t\t\t\tcontinue shapeCheck\n\n\t\t\t\tif (shape.parentId !== parentShape.id) {\n\t\t\t\t\tchildrenToReparent.push(shape)\n\t\t\t\t}\n\t\t\t\tremainingShapesToReparent.delete(shape)\n\t\t\t\tcontinue shapeCheck\n\t\t\t}\n\t\t}\n\n\t\tif (childrenToReparent.length) {\n\t\t\treparenting.set(parentShape.id, childrenToReparent)\n\t\t}\n\t}\n\n\treturn {\n\t\t// these are the shapes that will be reparented to new parents\n\t\treparenting,\n\t\t// these are the shapes that will be reparented to the page or their ancestral group\n\t\tremainingShapesToReparent,\n\t}\n}\n"],
5
- "mappings": "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",
6
- "names": ["import_utils", "shapeIds"]
7
- }