UNPKG

tldraw

Version:

A tiny little drawing editor.

56 lines (46 loc) 1.72 kB
import { BaseBoxShapeTool, TLShape, TLShapeId } from '@tldraw/editor' /** @public */ export class FrameShapeTool extends BaseBoxShapeTool { static override id = 'frame' static override initial = 'idle' override shapeType = 'frame' as const override onCreate(shape: TLShape | null): void { if (!shape) return const bounds = this.editor.getShapePageBounds(shape)! const shapesToAddToFrame: TLShapeId[] = [] const ancestorIds = this.editor.getShapeAncestors(shape).map((shape) => shape.id) this.editor.getSortedChildIdsForParent(shape.parentId).map((siblingShapeId) => { const siblingShape = this.editor.getShape(siblingShapeId) if (!siblingShape) return // We don't want to frame the frame itself if (siblingShape.id === shape.id) return if (siblingShape.isLocked) return const pageShapeBounds = this.editor.getShapePageBounds(siblingShape) if (!pageShapeBounds) return // Frame shape encloses page shape if (bounds.contains(pageShapeBounds)) { if (canEnclose(siblingShape, ancestorIds, shape)) { shapesToAddToFrame.push(siblingShape.id) } } }) this.editor.reparentShapes(shapesToAddToFrame, shape.id) if (this.editor.getInstanceState().isToolLocked) { this.editor.setCurrentTool('frame') } else { this.editor.setCurrentTool('select.idle') } } } /** @internal */ function canEnclose(shape: TLShape, ancestorIds: TLShapeId[], frame: TLShape): boolean { // We don't want to pull in shapes that are ancestors of the frame (can create a cycle) if (ancestorIds.includes(shape.id)) { return false } // We only want to pull in shapes that are siblings of the frame if (shape.parentId === frame.parentId) { return true } return false }