@tldraw/editor 5.5.0-canary.b384e8c068e2 → 5.5.0-canary.d64d005dcf06
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.js +1 -1
- package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js +14 -6
- package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js.map +3 -3
- package/dist-cjs/version.js +3 -3
- package/dist-cjs/version.js.map +1 -1
- package/dist-esm/index.mjs +1 -1
- package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs +14 -6
- package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs.map +3 -3
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/package.json +7 -7
- package/src/lib/editor/shapes/group/GroupShapeUtil.tsx +23 -8
- package/src/version.ts +3 -3
package/dist-cjs/index.js
CHANGED
|
@@ -392,7 +392,7 @@ var import_uniq = require("./lib/utils/uniq");
|
|
|
392
392
|
var import_defaultThemes2 = require("./lib/editor/managers/ThemeManager/defaultThemes");
|
|
393
393
|
(0, import_utils.registerTldrawLibraryVersion)(
|
|
394
394
|
"@tldraw/editor",
|
|
395
|
-
"5.5.0-canary.
|
|
395
|
+
"5.5.0-canary.d64d005dcf06",
|
|
396
396
|
"cjs"
|
|
397
397
|
);
|
|
398
398
|
//# sourceMappingURL=index.js.map
|
|
@@ -53,12 +53,20 @@ class GroupShapeUtil extends import_ShapeUtil.ShapeUtil {
|
|
|
53
53
|
if (children.length === 0) {
|
|
54
54
|
return new import_Rectangle2d.Rectangle2d({ width: 1, height: 1, isFilled: false });
|
|
55
55
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
56
|
+
const geometries = [];
|
|
57
|
+
for (const childId of children) {
|
|
58
|
+
const child = this.editor.getShape(childId);
|
|
59
|
+
if (!child) continue;
|
|
60
|
+
const geometry = this.editor.getShapeGeometry(childId);
|
|
61
|
+
if (!geometry) continue;
|
|
62
|
+
const transform = this.editor.getShapeLocalTransform(child);
|
|
63
|
+
if (!transform) continue;
|
|
64
|
+
geometries.push(geometry.transform(transform, { isLabel: false }));
|
|
65
|
+
}
|
|
66
|
+
if (geometries.length === 0) {
|
|
67
|
+
return new import_Rectangle2d.Rectangle2d({ width: 1, height: 1, isFilled: false });
|
|
68
|
+
}
|
|
69
|
+
return new import_Group2d.Group2d({ children: geometries });
|
|
62
70
|
}
|
|
63
71
|
component(shape) {
|
|
64
72
|
const isErasing = this.editor.getErasingShapeIds().includes(shape.id);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/editor/shapes/group/GroupShapeUtil.tsx"],
|
|
4
|
-
"sourcesContent": ["import { TLGroupShape, groupShapeMigrations, groupShapeProps } from '@tldraw/tlschema'\nimport { SVGContainer } from '../../../components/SVGContainer'\nimport { Geometry2d } from '../../../primitives/geometry/Geometry2d'\nimport { Group2d } from '../../../primitives/geometry/Group2d'\nimport { Rectangle2d } from '../../../primitives/geometry/Rectangle2d'\nimport { ShapeUtil } from '../ShapeUtil'\nimport { getPerfectDashProps } from '../shared/getPerfectDashProps'\nimport { DashedOutlineBox } from './DashedOutlineBox'\n\n/** @public */\nexport class GroupShapeUtil extends ShapeUtil<TLGroupShape> {\n\tstatic override type = 'group' as const\n\tstatic override props = groupShapeProps\n\tstatic override migrations = groupShapeMigrations\n\n\toverride hideSelectionBoundsFg(shape: TLGroupShape) {\n\t\treturn true\n\t}\n\n\toverride canBind() {\n\t\treturn false\n\t}\n\n\tcanResize() {\n\t\treturn true\n\t}\n\n\tcanResizeChildren() {\n\t\treturn true\n\t}\n\n\tgetDefaultProps(): TLGroupShape['props'] {\n\t\treturn {}\n\t}\n\n\tgetGeometry(shape: TLGroupShape): Geometry2d {\n\t\tconst children = this.editor.getSortedChildIdsForParent(shape.id)\n\t\tif (children.length === 0) {\n\t\t\treturn new Rectangle2d({ width: 1, height: 1, isFilled: false })\n\t\t}\n\n\t\
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
6
|
-
"names": [
|
|
4
|
+
"sourcesContent": ["import { TLGroupShape, groupShapeMigrations, groupShapeProps } from '@tldraw/tlschema'\nimport { SVGContainer } from '../../../components/SVGContainer'\nimport { Geometry2d } from '../../../primitives/geometry/Geometry2d'\nimport { Group2d } from '../../../primitives/geometry/Group2d'\nimport { Rectangle2d } from '../../../primitives/geometry/Rectangle2d'\nimport { ShapeUtil } from '../ShapeUtil'\nimport { getPerfectDashProps } from '../shared/getPerfectDashProps'\nimport { DashedOutlineBox } from './DashedOutlineBox'\n\n/** @public */\nexport class GroupShapeUtil extends ShapeUtil<TLGroupShape> {\n\tstatic override type = 'group' as const\n\tstatic override props = groupShapeProps\n\tstatic override migrations = groupShapeMigrations\n\n\toverride hideSelectionBoundsFg(shape: TLGroupShape) {\n\t\treturn true\n\t}\n\n\toverride canBind() {\n\t\treturn false\n\t}\n\n\tcanResize() {\n\t\treturn true\n\t}\n\n\tcanResizeChildren() {\n\t\treturn true\n\t}\n\n\tgetDefaultProps(): TLGroupShape['props'] {\n\t\treturn {}\n\t}\n\n\tgetGeometry(shape: TLGroupShape): Geometry2d {\n\t\tconst children = this.editor.getSortedChildIdsForParent(shape.id)\n\t\tif (children.length === 0) {\n\t\t\treturn new Rectangle2d({ width: 1, height: 1, isFilled: false })\n\t\t}\n\n\t\t// A child id can outlive its record. The children index and the geometry cache are separate\n\t\t// derivations, so inside a transaction that removes a child the index can still name it while\n\t\t// `getShapeGeometry` already answers nothing \u2014 its `!` hides that it returns `undefined` for a\n\t\t// record the store no longer holds. Asserting instead of checking threw a `TypeError` out of a\n\t\t// reactive recompute, where no caller could catch it.\n\t\tconst geometries: Geometry2d[] = []\n\t\tfor (const childId of children) {\n\t\t\tconst child = this.editor.getShape(childId)\n\t\t\tif (!child) continue\n\t\t\tconst geometry = this.editor.getShapeGeometry(childId)\n\t\t\tif (!geometry) continue\n\t\t\tconst transform = this.editor.getShapeLocalTransform(child)\n\t\t\tif (!transform) continue\n\t\t\tgeometries.push(geometry.transform(transform, { isLabel: false }))\n\t\t}\n\n\t\t// Every child resolved to nothing, so there is no meaningful extent to report. Matches the\n\t\t// no-children case above rather than building an empty `Group2d`, whose bounds are `NaN`.\n\t\tif (geometries.length === 0) {\n\t\t\treturn new Rectangle2d({ width: 1, height: 1, isFilled: false })\n\t\t}\n\n\t\treturn new Group2d({ children: geometries })\n\t}\n\n\tcomponent(shape: TLGroupShape) {\n\t\tconst isErasing = this.editor.getErasingShapeIds().includes(shape.id)\n\n\t\tconst { hintingShapeIds } = this.editor.getCurrentPageState()\n\t\tconst isHintingOtherGroup =\n\t\t\thintingShapeIds.length > 0 &&\n\t\t\thintingShapeIds.some(\n\t\t\t\t(id) => id !== shape.id && this.editor.isShapeOfType(this.editor.getShape(id)!, 'group')\n\t\t\t)\n\n\t\tconst isFocused = this.editor.getCurrentPageState().focusedGroupId !== shape.id\n\n\t\tif (\n\t\t\t!isErasing && // always show the outline while we're erasing the group\n\t\t\t// show the outline while the group is focused unless something outside of the group is being hinted\n\t\t\t// this happens dropping shapes from a group onto some outside group\n\t\t\t(isFocused || isHintingOtherGroup)\n\t\t) {\n\t\t\treturn null\n\t\t}\n\n\t\tconst bounds = this.editor.getShapeGeometry(shape).bounds\n\n\t\treturn (\n\t\t\t<SVGContainer>\n\t\t\t\t<DashedOutlineBox className=\"tl-group\" bounds={bounds} />\n\t\t\t</SVGContainer>\n\t\t)\n\t}\n\n\toverride getIndicatorPath(shape: TLGroupShape): Path2D {\n\t\tconst bounds = this.editor.getShapeGeometry(shape).bounds\n\t\tconst zoomLevel = this.editor.getEfficientZoomLevel()\n\t\tconst path = new Path2D()\n\n\t\tfor (const side of bounds.sides) {\n\t\t\tconst [start, end] = side\n\t\t\tconst length = start.dist(end)\n\t\t\tif (length <= 0) continue\n\n\t\t\tconst { strokeDasharray, strokeDashoffset } = getPerfectDashProps(length, 1 / zoomLevel, {\n\t\t\t\tstyle: 'dashed',\n\t\t\t\tlengthRatio: 4,\n\t\t\t})\n\n\t\t\tif (strokeDasharray === 'none') {\n\t\t\t\tpath.moveTo(start.x, start.y)\n\t\t\t\tpath.lineTo(end.x, end.y)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tconst [dashLength, gapLength] = strokeDasharray.split(' ').map(Number)\n\t\t\tconst dashOffset = Number(strokeDashoffset)\n\t\t\tconst period = dashLength + gapLength\n\t\t\tif (!Number.isFinite(period) || period <= 0) continue\n\n\t\t\tconst dx = (end.x - start.x) / length\n\t\t\tconst dy = (end.y - start.y) / length\n\n\t\t\tfor (let dashStart = -dashOffset; dashStart < length; dashStart += period) {\n\t\t\t\tconst dashEnd = Math.min(length, dashStart + dashLength)\n\t\t\t\tconst clippedDashStart = Math.max(0, dashStart)\n\t\t\t\tif (dashEnd <= clippedDashStart) continue\n\n\t\t\t\tpath.moveTo(start.x + dx * clippedDashStart, start.y + dy * clippedDashStart)\n\t\t\t\tpath.lineTo(start.x + dx * dashEnd, start.y + dy * dashEnd)\n\t\t\t}\n\t\t}\n\n\t\treturn path\n\t}\n\n\toverride onChildrenChange(group: TLGroupShape) {\n\t\tconst children = this.editor.getSortedChildIdsForParent(group.id)\n\t\tif (children.length === 0) {\n\t\t\tif (this.editor.getCurrentPageState().focusedGroupId === group.id) {\n\t\t\t\tthis.editor.popFocusedGroupId()\n\t\t\t}\n\t\t\tthis.editor.deleteShapes([group.id])\n\t\t\treturn\n\t\t} else if (children.length === 1) {\n\t\t\tif (this.editor.getCurrentPageState().focusedGroupId === group.id) {\n\t\t\t\tthis.editor.popFocusedGroupId()\n\t\t\t}\n\t\t\tthis.editor.reparentShapes(children, group.parentId, group.index)\n\t\t\tthis.editor.deleteShapes([group.id])\n\t\t\treturn\n\t\t}\n\t}\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
7
|
}
|
package/dist-cjs/version.js
CHANGED
|
@@ -22,10 +22,10 @@ __export(version_exports, {
|
|
|
22
22
|
version: () => version
|
|
23
23
|
});
|
|
24
24
|
module.exports = __toCommonJS(version_exports);
|
|
25
|
-
const version = "5.5.0-canary.
|
|
25
|
+
const version = "5.5.0-canary.d64d005dcf06";
|
|
26
26
|
const publishDates = {
|
|
27
27
|
major: "2026-05-06T16:28:18.473Z",
|
|
28
|
-
minor: "2026-09-
|
|
29
|
-
patch: "2026-09-
|
|
28
|
+
minor: "2026-09-04T14:23:32.649Z",
|
|
29
|
+
patch: "2026-09-04T14:23:32.649Z"
|
|
30
30
|
};
|
|
31
31
|
//# sourceMappingURL=version.js.map
|
package/dist-cjs/version.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/version.ts"],
|
|
4
|
-
"sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '5.5.0-canary.
|
|
4
|
+
"sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '5.5.0-canary.d64d005dcf06'\nexport const publishDates = {\n\tmajor: '2026-05-06T16:28:18.473Z',\n\tminor: '2026-09-04T14:23:32.649Z',\n\tpatch: '2026-09-04T14:23:32.649Z',\n}\n"],
|
|
5
5
|
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGO,MAAM,UAAU;AAChB,MAAM,eAAe;AAAA,EAC3B,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AACR;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist-esm/index.mjs
CHANGED
|
@@ -310,7 +310,7 @@ import { LocalIndexedDb, Table } from "./lib/utils/sync/LocalIndexedDb.mjs";
|
|
|
310
310
|
import { uniq } from "./lib/utils/uniq.mjs";
|
|
311
311
|
registerTldrawLibraryVersion(
|
|
312
312
|
"@tldraw/editor",
|
|
313
|
-
"5.5.0-canary.
|
|
313
|
+
"5.5.0-canary.d64d005dcf06",
|
|
314
314
|
"esm"
|
|
315
315
|
);
|
|
316
316
|
import { getColorValue } from "./lib/editor/managers/ThemeManager/defaultThemes.mjs";
|
|
@@ -30,12 +30,20 @@ class GroupShapeUtil extends ShapeUtil {
|
|
|
30
30
|
if (children.length === 0) {
|
|
31
31
|
return new Rectangle2d({ width: 1, height: 1, isFilled: false });
|
|
32
32
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
33
|
+
const geometries = [];
|
|
34
|
+
for (const childId of children) {
|
|
35
|
+
const child = this.editor.getShape(childId);
|
|
36
|
+
if (!child) continue;
|
|
37
|
+
const geometry = this.editor.getShapeGeometry(childId);
|
|
38
|
+
if (!geometry) continue;
|
|
39
|
+
const transform = this.editor.getShapeLocalTransform(child);
|
|
40
|
+
if (!transform) continue;
|
|
41
|
+
geometries.push(geometry.transform(transform, { isLabel: false }));
|
|
42
|
+
}
|
|
43
|
+
if (geometries.length === 0) {
|
|
44
|
+
return new Rectangle2d({ width: 1, height: 1, isFilled: false });
|
|
45
|
+
}
|
|
46
|
+
return new Group2d({ children: geometries });
|
|
39
47
|
}
|
|
40
48
|
component(shape) {
|
|
41
49
|
const isErasing = this.editor.getErasingShapeIds().includes(shape.id);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/editor/shapes/group/GroupShapeUtil.tsx"],
|
|
4
|
-
"sourcesContent": ["import { TLGroupShape, groupShapeMigrations, groupShapeProps } from '@tldraw/tlschema'\nimport { SVGContainer } from '../../../components/SVGContainer'\nimport { Geometry2d } from '../../../primitives/geometry/Geometry2d'\nimport { Group2d } from '../../../primitives/geometry/Group2d'\nimport { Rectangle2d } from '../../../primitives/geometry/Rectangle2d'\nimport { ShapeUtil } from '../ShapeUtil'\nimport { getPerfectDashProps } from '../shared/getPerfectDashProps'\nimport { DashedOutlineBox } from './DashedOutlineBox'\n\n/** @public */\nexport class GroupShapeUtil extends ShapeUtil<TLGroupShape> {\n\tstatic override type = 'group' as const\n\tstatic override props = groupShapeProps\n\tstatic override migrations = groupShapeMigrations\n\n\toverride hideSelectionBoundsFg(shape: TLGroupShape) {\n\t\treturn true\n\t}\n\n\toverride canBind() {\n\t\treturn false\n\t}\n\n\tcanResize() {\n\t\treturn true\n\t}\n\n\tcanResizeChildren() {\n\t\treturn true\n\t}\n\n\tgetDefaultProps(): TLGroupShape['props'] {\n\t\treturn {}\n\t}\n\n\tgetGeometry(shape: TLGroupShape): Geometry2d {\n\t\tconst children = this.editor.getSortedChildIdsForParent(shape.id)\n\t\tif (children.length === 0) {\n\t\t\treturn new Rectangle2d({ width: 1, height: 1, isFilled: false })\n\t\t}\n\n\t\
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": [
|
|
4
|
+
"sourcesContent": ["import { TLGroupShape, groupShapeMigrations, groupShapeProps } from '@tldraw/tlschema'\nimport { SVGContainer } from '../../../components/SVGContainer'\nimport { Geometry2d } from '../../../primitives/geometry/Geometry2d'\nimport { Group2d } from '../../../primitives/geometry/Group2d'\nimport { Rectangle2d } from '../../../primitives/geometry/Rectangle2d'\nimport { ShapeUtil } from '../ShapeUtil'\nimport { getPerfectDashProps } from '../shared/getPerfectDashProps'\nimport { DashedOutlineBox } from './DashedOutlineBox'\n\n/** @public */\nexport class GroupShapeUtil extends ShapeUtil<TLGroupShape> {\n\tstatic override type = 'group' as const\n\tstatic override props = groupShapeProps\n\tstatic override migrations = groupShapeMigrations\n\n\toverride hideSelectionBoundsFg(shape: TLGroupShape) {\n\t\treturn true\n\t}\n\n\toverride canBind() {\n\t\treturn false\n\t}\n\n\tcanResize() {\n\t\treturn true\n\t}\n\n\tcanResizeChildren() {\n\t\treturn true\n\t}\n\n\tgetDefaultProps(): TLGroupShape['props'] {\n\t\treturn {}\n\t}\n\n\tgetGeometry(shape: TLGroupShape): Geometry2d {\n\t\tconst children = this.editor.getSortedChildIdsForParent(shape.id)\n\t\tif (children.length === 0) {\n\t\t\treturn new Rectangle2d({ width: 1, height: 1, isFilled: false })\n\t\t}\n\n\t\t// A child id can outlive its record. The children index and the geometry cache are separate\n\t\t// derivations, so inside a transaction that removes a child the index can still name it while\n\t\t// `getShapeGeometry` already answers nothing \u2014 its `!` hides that it returns `undefined` for a\n\t\t// record the store no longer holds. Asserting instead of checking threw a `TypeError` out of a\n\t\t// reactive recompute, where no caller could catch it.\n\t\tconst geometries: Geometry2d[] = []\n\t\tfor (const childId of children) {\n\t\t\tconst child = this.editor.getShape(childId)\n\t\t\tif (!child) continue\n\t\t\tconst geometry = this.editor.getShapeGeometry(childId)\n\t\t\tif (!geometry) continue\n\t\t\tconst transform = this.editor.getShapeLocalTransform(child)\n\t\t\tif (!transform) continue\n\t\t\tgeometries.push(geometry.transform(transform, { isLabel: false }))\n\t\t}\n\n\t\t// Every child resolved to nothing, so there is no meaningful extent to report. Matches the\n\t\t// no-children case above rather than building an empty `Group2d`, whose bounds are `NaN`.\n\t\tif (geometries.length === 0) {\n\t\t\treturn new Rectangle2d({ width: 1, height: 1, isFilled: false })\n\t\t}\n\n\t\treturn new Group2d({ children: geometries })\n\t}\n\n\tcomponent(shape: TLGroupShape) {\n\t\tconst isErasing = this.editor.getErasingShapeIds().includes(shape.id)\n\n\t\tconst { hintingShapeIds } = this.editor.getCurrentPageState()\n\t\tconst isHintingOtherGroup =\n\t\t\thintingShapeIds.length > 0 &&\n\t\t\thintingShapeIds.some(\n\t\t\t\t(id) => id !== shape.id && this.editor.isShapeOfType(this.editor.getShape(id)!, 'group')\n\t\t\t)\n\n\t\tconst isFocused = this.editor.getCurrentPageState().focusedGroupId !== shape.id\n\n\t\tif (\n\t\t\t!isErasing && // always show the outline while we're erasing the group\n\t\t\t// show the outline while the group is focused unless something outside of the group is being hinted\n\t\t\t// this happens dropping shapes from a group onto some outside group\n\t\t\t(isFocused || isHintingOtherGroup)\n\t\t) {\n\t\t\treturn null\n\t\t}\n\n\t\tconst bounds = this.editor.getShapeGeometry(shape).bounds\n\n\t\treturn (\n\t\t\t<SVGContainer>\n\t\t\t\t<DashedOutlineBox className=\"tl-group\" bounds={bounds} />\n\t\t\t</SVGContainer>\n\t\t)\n\t}\n\n\toverride getIndicatorPath(shape: TLGroupShape): Path2D {\n\t\tconst bounds = this.editor.getShapeGeometry(shape).bounds\n\t\tconst zoomLevel = this.editor.getEfficientZoomLevel()\n\t\tconst path = new Path2D()\n\n\t\tfor (const side of bounds.sides) {\n\t\t\tconst [start, end] = side\n\t\t\tconst length = start.dist(end)\n\t\t\tif (length <= 0) continue\n\n\t\t\tconst { strokeDasharray, strokeDashoffset } = getPerfectDashProps(length, 1 / zoomLevel, {\n\t\t\t\tstyle: 'dashed',\n\t\t\t\tlengthRatio: 4,\n\t\t\t})\n\n\t\t\tif (strokeDasharray === 'none') {\n\t\t\t\tpath.moveTo(start.x, start.y)\n\t\t\t\tpath.lineTo(end.x, end.y)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tconst [dashLength, gapLength] = strokeDasharray.split(' ').map(Number)\n\t\t\tconst dashOffset = Number(strokeDashoffset)\n\t\t\tconst period = dashLength + gapLength\n\t\t\tif (!Number.isFinite(period) || period <= 0) continue\n\n\t\t\tconst dx = (end.x - start.x) / length\n\t\t\tconst dy = (end.y - start.y) / length\n\n\t\t\tfor (let dashStart = -dashOffset; dashStart < length; dashStart += period) {\n\t\t\t\tconst dashEnd = Math.min(length, dashStart + dashLength)\n\t\t\t\tconst clippedDashStart = Math.max(0, dashStart)\n\t\t\t\tif (dashEnd <= clippedDashStart) continue\n\n\t\t\t\tpath.moveTo(start.x + dx * clippedDashStart, start.y + dy * clippedDashStart)\n\t\t\t\tpath.lineTo(start.x + dx * dashEnd, start.y + dy * dashEnd)\n\t\t\t}\n\t\t}\n\n\t\treturn path\n\t}\n\n\toverride onChildrenChange(group: TLGroupShape) {\n\t\tconst children = this.editor.getSortedChildIdsForParent(group.id)\n\t\tif (children.length === 0) {\n\t\t\tif (this.editor.getCurrentPageState().focusedGroupId === group.id) {\n\t\t\t\tthis.editor.popFocusedGroupId()\n\t\t\t}\n\t\t\tthis.editor.deleteShapes([group.id])\n\t\t\treturn\n\t\t} else if (children.length === 1) {\n\t\t\tif (this.editor.getCurrentPageState().focusedGroupId === group.id) {\n\t\t\t\tthis.editor.popFocusedGroupId()\n\t\t\t}\n\t\t\tthis.editor.reparentShapes(children, group.parentId, group.index)\n\t\t\tthis.editor.deleteShapes([group.id])\n\t\t\treturn\n\t\t}\n\t}\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
7
|
}
|
package/dist-esm/version.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
const version = "5.5.0-canary.
|
|
1
|
+
const version = "5.5.0-canary.d64d005dcf06";
|
|
2
2
|
const publishDates = {
|
|
3
3
|
major: "2026-05-06T16:28:18.473Z",
|
|
4
|
-
minor: "2026-09-
|
|
5
|
-
patch: "2026-09-
|
|
4
|
+
minor: "2026-09-04T14:23:32.649Z",
|
|
5
|
+
patch: "2026-09-04T14:23:32.649Z"
|
|
6
6
|
};
|
|
7
7
|
export {
|
|
8
8
|
publishDates,
|
package/dist-esm/version.mjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/version.ts"],
|
|
4
|
-
"sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '5.5.0-canary.
|
|
4
|
+
"sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '5.5.0-canary.d64d005dcf06'\nexport const publishDates = {\n\tmajor: '2026-05-06T16:28:18.473Z',\n\tminor: '2026-09-04T14:23:32.649Z',\n\tpatch: '2026-09-04T14:23:32.649Z',\n}\n"],
|
|
5
5
|
"mappings": "AAGO,MAAM,UAAU;AAChB,MAAM,eAAe;AAAA,EAC3B,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AACR;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tldraw/editor",
|
|
3
3
|
"description": "tldraw infinite canvas SDK (editor).",
|
|
4
|
-
"version": "5.5.0-canary.
|
|
4
|
+
"version": "5.5.0-canary.d64d005dcf06",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "tldraw Inc.",
|
|
7
7
|
"email": "hello@tldraw.com"
|
|
@@ -55,12 +55,12 @@
|
|
|
55
55
|
"@tiptap/core": "^3.12.1",
|
|
56
56
|
"@tiptap/pm": "^3.12.1",
|
|
57
57
|
"@tiptap/react": "^3.12.1",
|
|
58
|
-
"@tldraw/state": "5.5.0-canary.
|
|
59
|
-
"@tldraw/state-react": "5.5.0-canary.
|
|
60
|
-
"@tldraw/store": "5.5.0-canary.
|
|
61
|
-
"@tldraw/tlschema": "5.5.0-canary.
|
|
62
|
-
"@tldraw/utils": "5.5.0-canary.
|
|
63
|
-
"@tldraw/validate": "5.5.0-canary.
|
|
58
|
+
"@tldraw/state": "5.5.0-canary.d64d005dcf06",
|
|
59
|
+
"@tldraw/state-react": "5.5.0-canary.d64d005dcf06",
|
|
60
|
+
"@tldraw/store": "5.5.0-canary.d64d005dcf06",
|
|
61
|
+
"@tldraw/tlschema": "5.5.0-canary.d64d005dcf06",
|
|
62
|
+
"@tldraw/utils": "5.5.0-canary.d64d005dcf06",
|
|
63
|
+
"@tldraw/validate": "5.5.0-canary.d64d005dcf06",
|
|
64
64
|
"classnames": "^2.5.1",
|
|
65
65
|
"eventemitter3": "^4.0.7",
|
|
66
66
|
"idb": "^7.1.1",
|
|
@@ -39,14 +39,29 @@ export class GroupShapeUtil extends ShapeUtil<TLGroupShape> {
|
|
|
39
39
|
return new Rectangle2d({ width: 1, height: 1, isFilled: false })
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
42
|
+
// A child id can outlive its record. The children index and the geometry cache are separate
|
|
43
|
+
// derivations, so inside a transaction that removes a child the index can still name it while
|
|
44
|
+
// `getShapeGeometry` already answers nothing — its `!` hides that it returns `undefined` for a
|
|
45
|
+
// record the store no longer holds. Asserting instead of checking threw a `TypeError` out of a
|
|
46
|
+
// reactive recompute, where no caller could catch it.
|
|
47
|
+
const geometries: Geometry2d[] = []
|
|
48
|
+
for (const childId of children) {
|
|
49
|
+
const child = this.editor.getShape(childId)
|
|
50
|
+
if (!child) continue
|
|
51
|
+
const geometry = this.editor.getShapeGeometry(childId)
|
|
52
|
+
if (!geometry) continue
|
|
53
|
+
const transform = this.editor.getShapeLocalTransform(child)
|
|
54
|
+
if (!transform) continue
|
|
55
|
+
geometries.push(geometry.transform(transform, { isLabel: false }))
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Every child resolved to nothing, so there is no meaningful extent to report. Matches the
|
|
59
|
+
// no-children case above rather than building an empty `Group2d`, whose bounds are `NaN`.
|
|
60
|
+
if (geometries.length === 0) {
|
|
61
|
+
return new Rectangle2d({ width: 1, height: 1, isFilled: false })
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return new Group2d({ children: geometries })
|
|
50
65
|
}
|
|
51
66
|
|
|
52
67
|
component(shape: TLGroupShape) {
|
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 = '5.5.0-canary.
|
|
4
|
+
export const version = '5.5.0-canary.d64d005dcf06'
|
|
5
5
|
export const publishDates = {
|
|
6
6
|
major: '2026-05-06T16:28:18.473Z',
|
|
7
|
-
minor: '2026-09-
|
|
8
|
-
patch: '2026-09-
|
|
7
|
+
minor: '2026-09-04T14:23:32.649Z',
|
|
8
|
+
patch: '2026-09-04T14:23:32.649Z',
|
|
9
9
|
}
|