@tldraw/editor 3.16.0-next.6611943ca24a → 3.16.0-next.8eb6d5c2d8f4
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 +117 -109
- package/dist-cjs/index.js +3 -5
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/TldrawEditor.js +6 -8
- package/dist-cjs/lib/TldrawEditor.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultCanvas.js +12 -2
- package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
- package/dist-cjs/lib/config/TLUserPreferences.js +15 -4
- package/dist-cjs/lib/config/TLUserPreferences.js.map +2 -2
- package/dist-cjs/lib/editor/Editor.js +75 -114
- package/dist-cjs/lib/editor/Editor.js.map +2 -2
- package/dist-cjs/lib/editor/derivations/notVisibleShapes.js +4 -0
- package/dist-cjs/lib/editor/derivations/notVisibleShapes.js.map +2 -2
- package/dist-cjs/lib/editor/managers/FocusManager/FocusManager.js +4 -2
- package/dist-cjs/lib/editor/managers/FocusManager/FocusManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js +11 -6
- package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js +23 -0
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
- package/dist-cjs/lib/editor/types/misc-types.js.map +1 -1
- package/dist-cjs/lib/exports/getSvgJsx.js +34 -14
- package/dist-cjs/lib/exports/getSvgJsx.js.map +2 -2
- package/dist-cjs/lib/hooks/useCanvasEvents.js +26 -21
- package/dist-cjs/lib/hooks/useCanvasEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/useDocumentEvents.js +5 -5
- package/dist-cjs/lib/hooks/useDocumentEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.js +1 -2
- package/dist-cjs/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/useGestureEvents.js +1 -1
- package/dist-cjs/lib/hooks/useGestureEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/useHandleEvents.js +6 -6
- package/dist-cjs/lib/hooks/useHandleEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/usePassThroughMouseOverEvents.js +4 -1
- package/dist-cjs/lib/hooks/usePassThroughMouseOverEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/usePassThroughWheelEvents.js +4 -1
- package/dist-cjs/lib/hooks/usePassThroughWheelEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/useSelectionEvents.js +8 -8
- package/dist-cjs/lib/hooks/useSelectionEvents.js.map +2 -2
- package/dist-cjs/lib/license/LicenseManager.js +143 -53
- package/dist-cjs/lib/license/LicenseManager.js.map +2 -2
- package/dist-cjs/lib/license/LicenseProvider.js +39 -1
- package/dist-cjs/lib/license/LicenseProvider.js.map +2 -2
- package/dist-cjs/lib/license/Watermark.js +144 -75
- package/dist-cjs/lib/license/Watermark.js.map +3 -3
- package/dist-cjs/lib/license/useLicenseManagerState.js.map +2 -2
- package/dist-cjs/lib/primitives/Box.js +3 -0
- package/dist-cjs/lib/primitives/Box.js.map +2 -2
- package/dist-cjs/lib/primitives/Vec.js +0 -4
- package/dist-cjs/lib/primitives/Vec.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Geometry2d.js +50 -20
- package/dist-cjs/lib/primitives/geometry/Geometry2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Group2d.js +8 -1
- package/dist-cjs/lib/primitives/geometry/Group2d.js.map +2 -2
- package/dist-cjs/lib/utils/dom.js.map +2 -2
- package/dist-cjs/lib/utils/getPointerInfo.js +2 -3
- package/dist-cjs/lib/utils/getPointerInfo.js.map +2 -2
- package/dist-cjs/lib/utils/reparenting.js +7 -36
- package/dist-cjs/lib/utils/reparenting.js.map +3 -3
- package/dist-cjs/version.js +3 -3
- package/dist-cjs/version.js.map +1 -1
- package/dist-esm/index.d.mts +117 -109
- package/dist-esm/index.mjs +3 -5
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/TldrawEditor.mjs +6 -8
- package/dist-esm/lib/TldrawEditor.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +12 -2
- package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
- package/dist-esm/lib/config/TLUserPreferences.mjs +15 -4
- package/dist-esm/lib/config/TLUserPreferences.mjs.map +2 -2
- package/dist-esm/lib/editor/Editor.mjs +75 -114
- package/dist-esm/lib/editor/Editor.mjs.map +2 -2
- package/dist-esm/lib/editor/derivations/notVisibleShapes.mjs +4 -0
- package/dist-esm/lib/editor/derivations/notVisibleShapes.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/FocusManager/FocusManager.mjs +4 -2
- package/dist-esm/lib/editor/managers/FocusManager/FocusManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs +11 -6
- package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs +23 -0
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/exports/getSvgJsx.mjs +34 -14
- package/dist-esm/lib/exports/getSvgJsx.mjs.map +2 -2
- package/dist-esm/lib/hooks/useCanvasEvents.mjs +27 -27
- package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useDocumentEvents.mjs +6 -6
- package/dist-esm/lib/hooks/useDocumentEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.mjs +1 -2
- package/dist-esm/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useGestureEvents.mjs +2 -2
- package/dist-esm/lib/hooks/useGestureEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useHandleEvents.mjs +6 -6
- package/dist-esm/lib/hooks/useHandleEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/usePassThroughMouseOverEvents.mjs +4 -1
- package/dist-esm/lib/hooks/usePassThroughMouseOverEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/usePassThroughWheelEvents.mjs +4 -1
- package/dist-esm/lib/hooks/usePassThroughWheelEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useSelectionEvents.mjs +9 -14
- package/dist-esm/lib/hooks/useSelectionEvents.mjs.map +2 -2
- package/dist-esm/lib/license/LicenseManager.mjs +144 -54
- package/dist-esm/lib/license/LicenseManager.mjs.map +2 -2
- package/dist-esm/lib/license/LicenseProvider.mjs +39 -2
- package/dist-esm/lib/license/LicenseProvider.mjs.map +2 -2
- package/dist-esm/lib/license/Watermark.mjs +145 -76
- package/dist-esm/lib/license/Watermark.mjs.map +3 -3
- package/dist-esm/lib/license/useLicenseManagerState.mjs.map +2 -2
- package/dist-esm/lib/primitives/Box.mjs +4 -1
- package/dist-esm/lib/primitives/Box.mjs.map +2 -2
- package/dist-esm/lib/primitives/Vec.mjs +0 -4
- package/dist-esm/lib/primitives/Vec.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Geometry2d.mjs +53 -21
- package/dist-esm/lib/primitives/geometry/Geometry2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Group2d.mjs +8 -1
- package/dist-esm/lib/primitives/geometry/Group2d.mjs.map +2 -2
- package/dist-esm/lib/utils/dom.mjs.map +2 -2
- package/dist-esm/lib/utils/getPointerInfo.mjs +2 -3
- package/dist-esm/lib/utils/getPointerInfo.mjs.map +2 -2
- package/dist-esm/lib/utils/reparenting.mjs +8 -41
- package/dist-esm/lib/utils/reparenting.mjs.map +2 -2
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/editor.css +16 -3
- package/package.json +7 -7
- package/src/index.ts +2 -9
- package/src/lib/TldrawEditor.tsx +7 -16
- package/src/lib/components/default-components/DefaultCanvas.tsx +9 -1
- package/src/lib/config/TLUserPreferences.ts +16 -3
- package/src/lib/editor/Editor.test.ts +90 -0
- package/src/lib/editor/Editor.ts +95 -151
- package/src/lib/editor/derivations/notVisibleShapes.ts +6 -0
- package/src/lib/editor/managers/FocusManager/FocusManager.ts +6 -2
- package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.test.ts +30 -8
- package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.ts +10 -3
- package/src/lib/editor/shapes/ShapeUtil.ts +46 -0
- package/src/lib/editor/types/misc-types.ts +0 -6
- package/src/lib/exports/getSvgJsx.test.ts +868 -0
- package/src/lib/exports/getSvgJsx.tsx +76 -19
- package/src/lib/hooks/useCanvasEvents.ts +26 -26
- package/src/lib/hooks/useDocumentEvents.ts +6 -6
- package/src/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.ts +1 -1
- package/src/lib/hooks/useGestureEvents.ts +2 -2
- package/src/lib/hooks/useHandleEvents.ts +6 -6
- package/src/lib/hooks/usePassThroughMouseOverEvents.ts +4 -1
- package/src/lib/hooks/usePassThroughWheelEvents.ts +6 -1
- package/src/lib/hooks/useSelectionEvents.ts +9 -14
- package/src/lib/license/LicenseManager.test.ts +721 -382
- package/src/lib/license/LicenseManager.ts +204 -58
- package/src/lib/license/LicenseProvider.tsx +74 -2
- package/src/lib/license/Watermark.tsx +152 -77
- package/src/lib/license/useLicenseManagerState.ts +2 -2
- package/src/lib/primitives/Box.test.ts +126 -0
- package/src/lib/primitives/Box.ts +10 -1
- package/src/lib/primitives/Vec.ts +0 -5
- package/src/lib/primitives/geometry/Geometry2d.test.ts +420 -0
- package/src/lib/primitives/geometry/Geometry2d.ts +78 -21
- package/src/lib/primitives/geometry/Group2d.ts +10 -1
- package/src/lib/test/InFrontOfTheCanvas.test.tsx +187 -0
- package/src/lib/utils/dom.test.ts +103 -0
- package/src/lib/utils/dom.ts +8 -1
- package/src/lib/utils/getPointerInfo.ts +3 -2
- package/src/lib/utils/reparenting.ts +10 -70
- package/src/version.ts +3 -3
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
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": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA
|
|
6
|
-
"names": ["
|
|
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 { intersectPolygonPolygon } from '../primitives/intersect'\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 _shape = editor.getShape(shape)\n\tif (!_shape) return EMPTY_ARRAY\n\n\tconst pageTransform = editor.getShapePageTransform(shape)\n\tconst clipPath = editor.getShapeUtil(_shape.type).getClipPath?.(_shape)\n\n\tconst parentPageMaskVertices = clipPath ? pageTransform.applyToPoints(clipPath) : undefined\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 geometry.overlapsPolygon(parentPolygonInShapeShape)\n\t})\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 (editor.getShapeGeometry(shape).overlapsPolygon(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": ["shapeIds"]
|
|
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 = "3.16.0-next.
|
|
25
|
+
const version = "3.16.0-next.8eb6d5c2d8f4";
|
|
26
26
|
const publishDates = {
|
|
27
27
|
major: "2024-09-13T14:36:29.063Z",
|
|
28
|
-
minor: "2025-
|
|
29
|
-
patch: "2025-
|
|
28
|
+
minor: "2025-09-18T14:19:10.006Z",
|
|
29
|
+
patch: "2025-09-18T14:19:10.006Z"
|
|
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 = '3.16.0-next.
|
|
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 = '3.16.0-next.8eb6d5c2d8f4'\nexport const publishDates = {\n\tmajor: '2024-09-13T14:36:29.063Z',\n\tminor: '2025-09-18T14:19:10.006Z',\n\tpatch: '2025-09-18T14:19:10.006Z',\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.d.mts
CHANGED
|
@@ -510,6 +510,7 @@ export declare class Box {
|
|
|
510
510
|
static ExpandBy(A: Box, n: number): Box;
|
|
511
511
|
static Collides(A: Box, B: Box): boolean;
|
|
512
512
|
static Contains(A: Box, B: Box): boolean;
|
|
513
|
+
static ContainsApproximately(A: Box, B: Box, precision?: number): boolean;
|
|
513
514
|
static Includes(A: Box, B: Box): boolean;
|
|
514
515
|
static ContainsPoint(A: Box, B: VecLike, margin?: number): boolean;
|
|
515
516
|
static Common(boxes: Box[]): Box;
|
|
@@ -760,11 +761,6 @@ export declare class CubicSpline2d extends Geometry2d {
|
|
|
760
761
|
/** @public */
|
|
761
762
|
export declare function dataUrlToFile(url: string, filename: string, mimeType: string): Promise<File>;
|
|
762
763
|
|
|
763
|
-
/**
|
|
764
|
-
* @deprecated Licensing is now enabled in the tldraw SDK.
|
|
765
|
-
* @public */
|
|
766
|
-
export declare function debugEnableLicensing(): void;
|
|
767
|
-
|
|
768
764
|
/* Excluded from this release type: DebugFlag */
|
|
769
765
|
|
|
770
766
|
/* Excluded from this release type: DebugFlagDef */
|
|
@@ -901,13 +897,14 @@ export declare const defaultUserPreferences: Readonly<{
|
|
|
901
897
|
color: "#02B1CC" | "#11B3A3" | "#39B178" | "#55B467" | "#7B66DC" | "#9D5BD2" | "#BD54C6" | "#E34BA9" | "#EC5E41" | "#F04F88" | "#F2555A" | "#FF802B";
|
|
902
898
|
colorScheme: "light";
|
|
903
899
|
edgeScrollSpeed: 1;
|
|
900
|
+
enhancedA11yMode: false;
|
|
901
|
+
inputMode: null;
|
|
904
902
|
isDynamicSizeMode: false;
|
|
905
903
|
isPasteAtCursorMode: false;
|
|
906
904
|
isSnapMode: false;
|
|
907
905
|
isWrapMode: false;
|
|
908
906
|
locale: "ar" | "bn" | "ca" | "cs" | "da" | "de" | "el" | "en" | "es" | "fa" | "fi" | "fr" | "gl" | "gu-in" | "he" | "hi-in" | "hr" | "hu" | "id" | "it" | "ja" | "km-kh" | "kn" | "ko-kr" | "ml" | "mr" | "ms" | "ne" | "nl" | "no" | "pa" | "pl" | "pt-br" | "pt-pt" | "ro" | "ru" | "sl" | "so" | "sv" | "ta" | "te" | "th" | "tl" | "tr" | "uk" | "ur" | "vi" | "zh-cn" | "zh-tw";
|
|
909
907
|
name: "";
|
|
910
|
-
showUiLabels: false;
|
|
911
908
|
}>;
|
|
912
909
|
|
|
913
910
|
/**
|
|
@@ -983,7 +980,7 @@ export declare class EdgeScrollManager {
|
|
|
983
980
|
/** @public */
|
|
984
981
|
export declare class Editor extends EventEmitter<TLEventMap> {
|
|
985
982
|
readonly id: string;
|
|
986
|
-
constructor({ store, user, shapeUtils, bindingUtils, tools, getContainer, cameraOptions, textOptions, initialState, autoFocus, inferDarkMode, options,
|
|
983
|
+
constructor({ store, user, shapeUtils, bindingUtils, tools, getContainer, cameraOptions, textOptions, initialState, autoFocus, inferDarkMode, options, getShapeVisibility, fontAssetUrls, }: TLEditorOptions);
|
|
987
984
|
private readonly _getShapeVisibility?;
|
|
988
985
|
private getIsShapeHiddenCache;
|
|
989
986
|
isShapeHidden(shapeOrId: TLShape | TLShapeId): boolean;
|
|
@@ -1050,22 +1047,6 @@ export declare class Editor extends EventEmitter<TLEventMap> {
|
|
|
1050
1047
|
* @public
|
|
1051
1048
|
*/
|
|
1052
1049
|
readonly fonts: FontManager;
|
|
1053
|
-
/**
|
|
1054
|
-
* A manager for the editor's environment.
|
|
1055
|
-
*
|
|
1056
|
-
* @deprecated This is deprecated and will be removed in a future version. Use the `tlenv` global export instead.
|
|
1057
|
-
* @public
|
|
1058
|
-
*/
|
|
1059
|
-
readonly environment: {
|
|
1060
|
-
hasCanvasSupport: boolean;
|
|
1061
|
-
isAndroid: boolean;
|
|
1062
|
-
isChromeForIos: boolean;
|
|
1063
|
-
isDarwin: boolean;
|
|
1064
|
-
isFirefox: boolean;
|
|
1065
|
-
isIos: boolean;
|
|
1066
|
-
isSafari: boolean;
|
|
1067
|
-
isWebview: boolean;
|
|
1068
|
-
};
|
|
1069
1050
|
/**
|
|
1070
1051
|
* A manager for the editor's scribbles.
|
|
1071
1052
|
*
|
|
@@ -1208,22 +1189,6 @@ export declare class Editor extends EventEmitter<TLEventMap> {
|
|
|
1208
1189
|
* @public
|
|
1209
1190
|
*/
|
|
1210
1191
|
getCanRedo(): boolean;
|
|
1211
|
-
/**
|
|
1212
|
-
* Create a new "mark", or stopping point, in the undo redo history. Creating a mark will clear
|
|
1213
|
-
* any redos.
|
|
1214
|
-
*
|
|
1215
|
-
* @example
|
|
1216
|
-
* ```ts
|
|
1217
|
-
* editor.mark()
|
|
1218
|
-
* editor.mark('flip shapes')
|
|
1219
|
-
* ```
|
|
1220
|
-
*
|
|
1221
|
-
* @param markId - The mark's id, usually the reason for adding the mark.
|
|
1222
|
-
*
|
|
1223
|
-
* @public
|
|
1224
|
-
* @deprecated use {@link Editor.markHistoryStoppingPoint} instead
|
|
1225
|
-
*/
|
|
1226
|
-
mark(markId?: string): this;
|
|
1227
1192
|
/**
|
|
1228
1193
|
* Create a new "mark", or stopping point, in the undo redo history. Creating a mark will clear
|
|
1229
1194
|
* any redos. You typically want to do this just before a user interaction begins or is handled.
|
|
@@ -1313,10 +1278,6 @@ export declare class Editor extends EventEmitter<TLEventMap> {
|
|
|
1313
1278
|
* @public
|
|
1314
1279
|
*/
|
|
1315
1280
|
run(fn: () => void, opts?: TLEditorRunOptions): this;
|
|
1316
|
-
/**
|
|
1317
|
-
* @deprecated Use `Editor.run` instead.
|
|
1318
|
-
*/
|
|
1319
|
-
batch(fn: () => void, opts?: TLEditorRunOptions): this;
|
|
1320
1281
|
/* Excluded from this release type: annotateError */
|
|
1321
1282
|
/* Excluded from this release type: createErrorAnnotations */
|
|
1322
1283
|
/* Excluded from this release type: _crashingError */
|
|
@@ -1438,36 +1399,6 @@ export declare class Editor extends EventEmitter<TLEventMap> {
|
|
|
1438
1399
|
hasOpenMenus: () => boolean;
|
|
1439
1400
|
isMenuOpen: (id: string) => boolean;
|
|
1440
1401
|
};
|
|
1441
|
-
/**
|
|
1442
|
-
* @deprecated Use `editor.menus.getOpenMenus` instead.
|
|
1443
|
-
*
|
|
1444
|
-
* @public
|
|
1445
|
-
*/
|
|
1446
|
-
getOpenMenus(): string[];
|
|
1447
|
-
/**
|
|
1448
|
-
* @deprecated Use `editor.menus.addOpenMenu` instead.
|
|
1449
|
-
*
|
|
1450
|
-
* @public
|
|
1451
|
-
*/
|
|
1452
|
-
addOpenMenu(id: string): this;
|
|
1453
|
-
/**
|
|
1454
|
-
* @deprecated Use `editor.menus.deleteOpenMenu` instead.
|
|
1455
|
-
*
|
|
1456
|
-
* @public
|
|
1457
|
-
*/
|
|
1458
|
-
deleteOpenMenu(id: string): this;
|
|
1459
|
-
/**
|
|
1460
|
-
* @deprecated Use `editor.menus.clearOpenMenus` instead.
|
|
1461
|
-
*
|
|
1462
|
-
* @public
|
|
1463
|
-
*/
|
|
1464
|
-
clearOpenMenus(): this;
|
|
1465
|
-
/**
|
|
1466
|
-
* @deprecated Use `editor.menus.hasAnyOpenMenus` instead.
|
|
1467
|
-
*
|
|
1468
|
-
* @public
|
|
1469
|
-
*/
|
|
1470
|
-
getIsMenuOpen(): boolean;
|
|
1471
1402
|
/**
|
|
1472
1403
|
* Set the cursor.
|
|
1473
1404
|
*
|
|
@@ -2916,8 +2847,6 @@ export declare class Editor extends EventEmitter<TLEventMap> {
|
|
|
2916
2847
|
* @public
|
|
2917
2848
|
*/
|
|
2918
2849
|
getShapeAndDescendantIds(ids: TLShapeId[]): Set<TLShapeId>;
|
|
2919
|
-
/** @deprecated Use {@link Editor.getDraggingOverShape} instead */
|
|
2920
|
-
getDroppingOverShape(point: Vec, droppingShapes: TLShape[]): TLShape | undefined;
|
|
2921
2850
|
/**
|
|
2922
2851
|
* Get the shape that some shapes should be dropped on at a given point.
|
|
2923
2852
|
*
|
|
@@ -3629,14 +3558,20 @@ export declare class Editor extends EventEmitter<TLEventMap> {
|
|
|
3629
3558
|
* Handle external content, such as files, urls, embeds, or plain text which has been put into the app, for example by pasting external text or dropping external images onto canvas.
|
|
3630
3559
|
*
|
|
3631
3560
|
* @param info - Info about the external content.
|
|
3561
|
+
* @param opts - Options for handling external content, including force flag to bypass readonly checks.
|
|
3632
3562
|
*/
|
|
3633
|
-
putExternalContent<E>(info: TLExternalContent<E
|
|
3563
|
+
putExternalContent<E>(info: TLExternalContent<E>, opts?: {
|
|
3564
|
+
force?: boolean;
|
|
3565
|
+
}): Promise<void>;
|
|
3634
3566
|
/**
|
|
3635
3567
|
* Handle replacing external content.
|
|
3636
3568
|
*
|
|
3637
3569
|
* @param info - Info about the external content.
|
|
3570
|
+
* @param opts - Options for handling external content, including force flag to bypass readonly checks.
|
|
3638
3571
|
*/
|
|
3639
|
-
replaceExternalContent<E>(info: TLExternalContent<E
|
|
3572
|
+
replaceExternalContent<E>(info: TLExternalContent<E>, opts?: {
|
|
3573
|
+
force?: boolean;
|
|
3574
|
+
}): Promise<void>;
|
|
3640
3575
|
/**
|
|
3641
3576
|
* Get content that can be exported for the given shape ids.
|
|
3642
3577
|
*
|
|
@@ -3692,8 +3627,6 @@ export declare class Editor extends EventEmitter<TLEventMap> {
|
|
|
3692
3627
|
svg: string;
|
|
3693
3628
|
width: number;
|
|
3694
3629
|
} | undefined>;
|
|
3695
|
-
/** @deprecated Use {@link Editor.getSvgString} or {@link Editor.getSvgElement} instead. */
|
|
3696
|
-
getSvg(shapes: TLShape[] | TLShapeId[], opts?: TLSvgExportOptions): Promise<SVGSVGElement | undefined>;
|
|
3697
3630
|
/**
|
|
3698
3631
|
* Get an exported image of the given shapes.
|
|
3699
3632
|
*
|
|
@@ -3708,6 +3641,20 @@ export declare class Editor extends EventEmitter<TLEventMap> {
|
|
|
3708
3641
|
height: number;
|
|
3709
3642
|
width: number;
|
|
3710
3643
|
}>;
|
|
3644
|
+
/**
|
|
3645
|
+
* Get an exported image of the given shapes as a data URL.
|
|
3646
|
+
*
|
|
3647
|
+
* @param shapes - The shapes (or shape ids) to export.
|
|
3648
|
+
* @param opts - Options for the export.
|
|
3649
|
+
*
|
|
3650
|
+
* @returns A data URL of the image.
|
|
3651
|
+
* @public
|
|
3652
|
+
*/
|
|
3653
|
+
toImageDataUrl(shapes: TLShape[] | TLShapeId[], opts?: TLImageExportOptions): Promise<{
|
|
3654
|
+
height: number;
|
|
3655
|
+
url: string;
|
|
3656
|
+
width: number;
|
|
3657
|
+
}>;
|
|
3711
3658
|
/**
|
|
3712
3659
|
* The app's current input state.
|
|
3713
3660
|
*
|
|
@@ -4013,6 +3960,31 @@ export declare class Editor extends EventEmitter<TLEventMap> {
|
|
|
4013
3960
|
/* Excluded from this release type: capturedPointerId */
|
|
4014
3961
|
/* Excluded from this release type: performanceTracker */
|
|
4015
3962
|
/* Excluded from this release type: performanceTrackerTimeout */
|
|
3963
|
+
/* Excluded from this release type: handledEvents */
|
|
3964
|
+
/**
|
|
3965
|
+
* In tldraw, events are sometimes handled by multiple components. For example, the shapes might
|
|
3966
|
+
* have events, but the canvas handles events too. The way that the canvas handles events can
|
|
3967
|
+
* interfere with the with the shapes event handlers - for example, it calls `.preventDefault()`
|
|
3968
|
+
* on `pointerDown`, which also prevents `click` events from firing on the shapes.
|
|
3969
|
+
*
|
|
3970
|
+
* You can use `.stopPropagation()` to prevent the event from propagating to the rest of the
|
|
3971
|
+
* DOM, but that can impact non-tldraw event handlers set up elsewhere. By using
|
|
3972
|
+
* `markEventAsHandled`, you'll stop other parts of tldraw from handling the event without
|
|
3973
|
+
* impacting other, non-tldraw event handlers. See also {@link Editor.wasEventAlreadyHandled}.
|
|
3974
|
+
*
|
|
3975
|
+
* @public
|
|
3976
|
+
*/
|
|
3977
|
+
markEventAsHandled(e: {
|
|
3978
|
+
nativeEvent: Event;
|
|
3979
|
+
} | Event): void;
|
|
3980
|
+
/**
|
|
3981
|
+
* Checks if an event has already been handled. See {@link Editor.markEventAsHandled}.
|
|
3982
|
+
*
|
|
3983
|
+
* @public
|
|
3984
|
+
*/
|
|
3985
|
+
wasEventAlreadyHandled(e: {
|
|
3986
|
+
nativeEvent: Event;
|
|
3987
|
+
} | Event): boolean;
|
|
4016
3988
|
/**
|
|
4017
3989
|
* Dispatch an event to the editor.
|
|
4018
3990
|
*
|
|
@@ -4149,6 +4121,7 @@ export declare abstract class Geometry2d {
|
|
|
4149
4121
|
isLabel: boolean;
|
|
4150
4122
|
isEmptyLabel: boolean;
|
|
4151
4123
|
isInternal: boolean;
|
|
4124
|
+
excludeFromShapeBounds: boolean;
|
|
4152
4125
|
debugColor?: string;
|
|
4153
4126
|
ignore?: boolean;
|
|
4154
4127
|
constructor(opts: Geometry2dOptions);
|
|
@@ -4172,12 +4145,14 @@ export declare abstract class Geometry2d {
|
|
|
4172
4145
|
* along the edge it is as a fraction of the total length.
|
|
4173
4146
|
*/
|
|
4174
4147
|
uninterpolateAlongEdge(point: VecLike, _filters?: Geometry2dFilters): number;
|
|
4175
|
-
/** @deprecated Iterate the vertices instead. */
|
|
4176
|
-
nearestPointOnLineSegment(A: VecLike, B: VecLike): Vec;
|
|
4177
4148
|
isPointInBounds(point: VecLike, margin?: number): boolean;
|
|
4149
|
+
overlapsPolygon(_polygon: VecLike[]): boolean;
|
|
4178
4150
|
transform(transform: MatModel, opts?: TransformedGeometry2dOptions): Geometry2d;
|
|
4179
4151
|
private _vertices;
|
|
4180
4152
|
get vertices(): Vec[];
|
|
4153
|
+
getBoundsVertices(): Vec[];
|
|
4154
|
+
private _boundsVertices;
|
|
4155
|
+
get boundsVertices(): Vec[];
|
|
4181
4156
|
getBounds(): Box;
|
|
4182
4157
|
private _bounds;
|
|
4183
4158
|
get bounds(): Box;
|
|
@@ -4285,7 +4260,7 @@ export declare function getPerfectDashProps(totalLength: number, strokeWidth: nu
|
|
|
4285
4260
|
};
|
|
4286
4261
|
|
|
4287
4262
|
/** @public */
|
|
4288
|
-
export declare function getPointerInfo(e: PointerEvent | React.PointerEvent): {
|
|
4263
|
+
export declare function getPointerInfo(editor: Editor, e: PointerEvent | React.PointerEvent): {
|
|
4289
4264
|
accelKey: boolean;
|
|
4290
4265
|
altKey: boolean;
|
|
4291
4266
|
button: number;
|
|
@@ -4374,6 +4349,7 @@ export declare class Group2d extends Geometry2d {
|
|
|
4374
4349
|
hitTestLineSegment(A: VecLike, B: VecLike, zoom: number, filters?: Geometry2dFilters): boolean;
|
|
4375
4350
|
intersectLineSegment(A: VecLike, B: VecLike, filters?: Geometry2dFilters): VecLike[];
|
|
4376
4351
|
intersectCircle(center: VecLike, radius: number, filters?: Geometry2dFilters): VecLike[];
|
|
4352
|
+
getBoundsVertices(): Vec[];
|
|
4377
4353
|
intersectPolygon(polygon: VecLike[], filters?: Geometry2dFilters): VecLike[];
|
|
4378
4354
|
intersectPolyline(polyline: VecLike[], filters?: Geometry2dFilters): VecLike[];
|
|
4379
4355
|
interpolateAlongEdge(t: number, filters?: Geometry2dFilters): Vec;
|
|
@@ -4383,6 +4359,7 @@ export declare class Group2d extends Geometry2d {
|
|
|
4383
4359
|
toSimpleSvgPath(): string;
|
|
4384
4360
|
getLength(filters?: Geometry2dFilters): number;
|
|
4385
4361
|
getSvgPathData(): string;
|
|
4362
|
+
overlapsPolygon(polygon: VecLike[]): boolean;
|
|
4386
4363
|
}
|
|
4387
4364
|
|
|
4388
4365
|
/** @public */
|
|
@@ -4623,12 +4600,16 @@ export declare function kickoutOccludedShapes(editor: Editor, shapeIds: TLShapeI
|
|
|
4623
4600
|
filter?(parent: TLShape): boolean;
|
|
4624
4601
|
}): void;
|
|
4625
4602
|
|
|
4603
|
+
/* Excluded from this release type: LICENSE_TIMEOUT */
|
|
4604
|
+
|
|
4626
4605
|
/* Excluded from this release type: LicenseFromKeyResult */
|
|
4627
4606
|
|
|
4628
4607
|
/* Excluded from this release type: LicenseInfo */
|
|
4629
4608
|
|
|
4630
4609
|
/* Excluded from this release type: LicenseManager */
|
|
4631
4610
|
|
|
4611
|
+
/* Excluded from this release type: LicenseState */
|
|
4612
|
+
|
|
4632
4613
|
/** @public */
|
|
4633
4614
|
export declare function linesIntersect(A: VecLike, B: VecLike, C: VecLike, D: VecLike): boolean;
|
|
4634
4615
|
|
|
@@ -5234,7 +5215,34 @@ export declare abstract class ShapeUtil<Shape extends TLUnknownShape = TLUnknown
|
|
|
5234
5215
|
* @public
|
|
5235
5216
|
*/
|
|
5236
5217
|
canBeLaidOut(_shape: Shape, _info: TLShapeUtilCanBeLaidOutOpts): boolean;
|
|
5218
|
+
/**
|
|
5219
|
+
* Whether this shape can be culled. By default, shapes are culled for
|
|
5220
|
+
* performance reasons when they are outside of the viewport. Culled shapes are still rendered
|
|
5221
|
+
* to the DOM, but have their `display` property set to `none`.
|
|
5222
|
+
*
|
|
5223
|
+
* @param shape - The shape.
|
|
5224
|
+
*/
|
|
5225
|
+
canCull(_shape: Shape): boolean;
|
|
5237
5226
|
/* Excluded from this release type: providesBackgroundForChildren */
|
|
5227
|
+
/**
|
|
5228
|
+
* Get the clip path to apply to this shape's children.
|
|
5229
|
+
*
|
|
5230
|
+
* @param shape - The shape to get the clip path for
|
|
5231
|
+
* @returns Array of points defining the clipping polygon in local coordinates, or undefined if no clipping
|
|
5232
|
+
* @public
|
|
5233
|
+
*/
|
|
5234
|
+
getClipPath?(shape: Shape): undefined | Vec[];
|
|
5235
|
+
/**
|
|
5236
|
+
* Whether a specific child shape should be clipped by this shape.
|
|
5237
|
+
* Only called if getClipPath returns a valid polygon.
|
|
5238
|
+
*
|
|
5239
|
+
* If not defined, the default behavior is to clip all children.
|
|
5240
|
+
*
|
|
5241
|
+
* @param child - The child shape to check
|
|
5242
|
+
* @returns boolean indicating if this child should be clipped
|
|
5243
|
+
* @public
|
|
5244
|
+
*/
|
|
5245
|
+
shouldClipChild?(child: TLShape): boolean;
|
|
5238
5246
|
/**
|
|
5239
5247
|
* Whether the shape should hide its resize handles when selected.
|
|
5240
5248
|
*
|
|
@@ -5265,6 +5273,17 @@ export declare abstract class ShapeUtil<Shape extends TLUnknownShape = TLUnknown
|
|
|
5265
5273
|
* @public
|
|
5266
5274
|
*/
|
|
5267
5275
|
isAspectRatioLocked(_shape: Shape): boolean;
|
|
5276
|
+
/**
|
|
5277
|
+
* By default, the bounds of an image export are the bounds of all the shapes it contains, plus
|
|
5278
|
+
* some padding. If an export includes a shape where `isExportBoundsContainer` is true, then the
|
|
5279
|
+
* padding is skipped _if the bounds of that shape contains all the other shapes_. This is
|
|
5280
|
+
* useful in cases like annotating on top of an image, where you usually want to avoid extra
|
|
5281
|
+
* padding around the image if you don't need it.
|
|
5282
|
+
*
|
|
5283
|
+
* @param _shape - The shape to check
|
|
5284
|
+
* @returns True if this shape should be treated as an export bounds container
|
|
5285
|
+
*/
|
|
5286
|
+
isExportBoundsContainer(_shape: Shape): boolean;
|
|
5268
5287
|
/* Excluded from this release type: backgroundComponent */
|
|
5269
5288
|
/**
|
|
5270
5289
|
* Get the interpolated props for an animating shape. This is an optional method.
|
|
@@ -5820,7 +5839,14 @@ export declare abstract class StateNode implements Partial<TLEventHandlers> {
|
|
|
5820
5839
|
onExit?(info: any, to: string): void;
|
|
5821
5840
|
}
|
|
5822
5841
|
|
|
5823
|
-
/**
|
|
5842
|
+
/**
|
|
5843
|
+
* Calls `event.stopPropagation()`.
|
|
5844
|
+
*
|
|
5845
|
+
* @deprecated Use {@link Editor.markEventAsHandled} instead, or manually call `event.stopPropagation()` if
|
|
5846
|
+
* that's what you really want.
|
|
5847
|
+
*
|
|
5848
|
+
* @public
|
|
5849
|
+
*/
|
|
5824
5850
|
export declare const stopEventPropagation: (e: any) => any;
|
|
5825
5851
|
|
|
5826
5852
|
/* Excluded from this release type: StoreName */
|
|
@@ -6311,12 +6337,6 @@ export declare interface TldrawEditorBaseProps {
|
|
|
6311
6337
|
* Options for syncing the editor's camera state with the URL.
|
|
6312
6338
|
*/
|
|
6313
6339
|
deepLinks?: TLDeepLinkOptions | true;
|
|
6314
|
-
/**
|
|
6315
|
-
* Predicate for whether or not a shape should be hidden.
|
|
6316
|
-
*
|
|
6317
|
-
* @deprecated Use {@link TldrawEditorBaseProps#getShapeVisibility} instead.
|
|
6318
|
-
*/
|
|
6319
|
-
isShapeHidden?(shape: TLShape, editor: Editor): boolean;
|
|
6320
6340
|
/**
|
|
6321
6341
|
* Provides a way to hide shapes.
|
|
6322
6342
|
*
|
|
@@ -6578,15 +6598,6 @@ export declare interface TLEditorOptions {
|
|
|
6578
6598
|
fontAssetUrls?: {
|
|
6579
6599
|
[key: string]: string | undefined;
|
|
6580
6600
|
};
|
|
6581
|
-
/**
|
|
6582
|
-
* A predicate that should return true if the given shape should be hidden.
|
|
6583
|
-
*
|
|
6584
|
-
* @deprecated Use {@link Editor#getShapeVisibility} instead.
|
|
6585
|
-
*
|
|
6586
|
-
* @param shape - The shape to check.
|
|
6587
|
-
* @param editor - The editor instance.
|
|
6588
|
-
*/
|
|
6589
|
-
isShapeHidden?(shape: TLShape, editor: Editor): boolean;
|
|
6590
6601
|
/**
|
|
6591
6602
|
* Provides a way to hide shapes.
|
|
6592
6603
|
*
|
|
@@ -7577,12 +7588,6 @@ export declare interface TLSvgExportOptions {
|
|
|
7577
7588
|
preserveAspectRatio?: React.SVGAttributes<SVGSVGElement>['preserveAspectRatio'];
|
|
7578
7589
|
}
|
|
7579
7590
|
|
|
7580
|
-
/**
|
|
7581
|
-
* @public
|
|
7582
|
-
* @deprecated use {@link TLImageExportOptions} instead
|
|
7583
|
-
*/
|
|
7584
|
-
export declare type TLSvgOptions = TLImageExportOptions;
|
|
7585
|
-
|
|
7586
7591
|
/** @public */
|
|
7587
7592
|
export declare interface TLSvgTextExternalContent extends TLBaseExternalContent {
|
|
7588
7593
|
type: 'svg-text';
|
|
@@ -7693,7 +7698,8 @@ export declare interface TLUserPreferences {
|
|
|
7693
7698
|
isWrapMode?: boolean | null;
|
|
7694
7699
|
isDynamicSizeMode?: boolean | null;
|
|
7695
7700
|
isPasteAtCursorMode?: boolean | null;
|
|
7696
|
-
|
|
7701
|
+
enhancedA11yMode?: boolean | null;
|
|
7702
|
+
inputMode?: 'mouse' | 'trackpad' | null;
|
|
7697
7703
|
}
|
|
7698
7704
|
|
|
7699
7705
|
/** @public */
|
|
@@ -7736,6 +7742,7 @@ export declare class TransformedGeometry2d extends Geometry2d {
|
|
|
7736
7742
|
private readonly decomposed;
|
|
7737
7743
|
constructor(geometry: Geometry2d, matrix: MatModel, opts?: TransformedGeometry2dOptions);
|
|
7738
7744
|
getVertices(filters: Geometry2dFilters): Vec[];
|
|
7745
|
+
getBoundsVertices(): Vec[];
|
|
7739
7746
|
nearestPoint(point: VecLike, filters?: Geometry2dFilters): Vec;
|
|
7740
7747
|
hitTestPoint(point: VecLike, margin?: number, hitInside?: boolean, filters?: Geometry2dFilters): boolean;
|
|
7741
7748
|
distanceToPoint(point: VecLike, hitInside?: boolean, filters?: Geometry2dFilters): number;
|
|
@@ -7756,6 +7763,7 @@ export declare interface TransformedGeometry2dOptions {
|
|
|
7756
7763
|
isInternal?: boolean;
|
|
7757
7764
|
debugColor?: string;
|
|
7758
7765
|
ignore?: boolean;
|
|
7766
|
+
excludeFromShapeBounds?: boolean;
|
|
7759
7767
|
}
|
|
7760
7768
|
|
|
7761
7769
|
/** @public */
|
|
@@ -7859,14 +7867,15 @@ export declare class UserPreferencesManager {
|
|
|
7859
7867
|
areKeyboardShortcutsEnabled: boolean;
|
|
7860
7868
|
color: string;
|
|
7861
7869
|
colorScheme: "dark" | "light" | "system" | undefined;
|
|
7870
|
+
enhancedA11yMode: boolean;
|
|
7862
7871
|
id: string;
|
|
7872
|
+
inputMode: "mouse" | "trackpad" | null;
|
|
7863
7873
|
isDarkMode: boolean;
|
|
7864
7874
|
isDynamicResizeMode: boolean;
|
|
7865
7875
|
isSnapMode: boolean;
|
|
7866
7876
|
isWrapMode: boolean;
|
|
7867
7877
|
locale: string;
|
|
7868
7878
|
name: string;
|
|
7869
|
-
showUiLabels: boolean;
|
|
7870
7879
|
};
|
|
7871
7880
|
getIsDarkMode(): boolean;
|
|
7872
7881
|
/**
|
|
@@ -7883,7 +7892,8 @@ export declare class UserPreferencesManager {
|
|
|
7883
7892
|
getIsWrapMode(): boolean;
|
|
7884
7893
|
getIsDynamicResizeMode(): boolean;
|
|
7885
7894
|
getIsPasteAtCursorMode(): boolean;
|
|
7886
|
-
|
|
7895
|
+
getEnhancedA11yMode(): boolean;
|
|
7896
|
+
getInputMode(): "mouse" | "trackpad" | null;
|
|
7887
7897
|
}
|
|
7888
7898
|
|
|
7889
7899
|
/** @public */
|
|
@@ -7990,8 +8000,6 @@ export declare class Vec {
|
|
|
7990
8000
|
lrp(B: VecLike, t: number): Vec;
|
|
7991
8001
|
equals(B: VecLike): boolean;
|
|
7992
8002
|
equalsXY(x: number, y: number): boolean;
|
|
7993
|
-
/** @deprecated use `uni` instead */
|
|
7994
|
-
norm(): this;
|
|
7995
8003
|
toFixed(): this;
|
|
7996
8004
|
toString(): string;
|
|
7997
8005
|
toJson(): VecModel;
|
package/dist-esm/index.mjs
CHANGED
|
@@ -175,6 +175,7 @@ import { useViewportHeight } from "./lib/hooks/useViewportHeight.mjs";
|
|
|
175
175
|
import {
|
|
176
176
|
LicenseManager
|
|
177
177
|
} from "./lib/license/LicenseManager.mjs";
|
|
178
|
+
import { LICENSE_TIMEOUT } from "./lib/license/LicenseProvider.mjs";
|
|
178
179
|
import { defaultTldrawOptions } from "./lib/options.mjs";
|
|
179
180
|
import {
|
|
180
181
|
Box,
|
|
@@ -298,12 +299,9 @@ import { hardReset } from "./lib/utils/sync/hardReset.mjs";
|
|
|
298
299
|
import { LocalIndexedDb, Table } from "./lib/utils/sync/LocalIndexedDb.mjs";
|
|
299
300
|
import { uniq } from "./lib/utils/uniq.mjs";
|
|
300
301
|
import { openWindow } from "./lib/utils/window-open.mjs";
|
|
301
|
-
function debugEnableLicensing() {
|
|
302
|
-
return;
|
|
303
|
-
}
|
|
304
302
|
registerTldrawLibraryVersion(
|
|
305
303
|
"@tldraw/editor",
|
|
306
|
-
"3.16.0-next.
|
|
304
|
+
"3.16.0-next.8eb6d5c2d8f4",
|
|
307
305
|
"esm"
|
|
308
306
|
);
|
|
309
307
|
export {
|
|
@@ -358,6 +356,7 @@ export {
|
|
|
358
356
|
HTMLContainer,
|
|
359
357
|
HandleSnaps,
|
|
360
358
|
HistoryManager,
|
|
359
|
+
LICENSE_TIMEOUT,
|
|
361
360
|
LicenseManager,
|
|
362
361
|
LoadingScreen,
|
|
363
362
|
LocalIndexedDb,
|
|
@@ -409,7 +408,6 @@ export {
|
|
|
409
408
|
createTLStore,
|
|
410
409
|
createTLUser,
|
|
411
410
|
dataUrlToFile,
|
|
412
|
-
debugEnableLicensing,
|
|
413
411
|
debugFlags,
|
|
414
412
|
defaultTldrawOptions,
|
|
415
413
|
defaultUserPreferences,
|