{ "version": 3, "sources": ["../../../../src/lib/shapes/frame/FrameShapeUtil.tsx"], "sourcesContent": ["import {\n\tBaseBoxShapeUtil,\n\tGeometry2d,\n\tRectangle2d,\n\tSVGContainer,\n\tSelectionEdge,\n\tTLFrameShape,\n\tTLGroupShape,\n\tTLOnResizeEndHandler,\n\tTLShape,\n\tTLShapeId,\n\tcanonicalizeRotation,\n\tframeShapeMigrations,\n\tframeShapeProps,\n\tgetDefaultColorTheme,\n\tlast,\n\ttoDomPrecision,\n} from '@tldraw/editor'\nimport { useDefaultColorTheme } from '../shared/ShapeFill'\nimport { createTextSvgElementFromSpans } from '../shared/createTextSvgElementFromSpans'\nimport { FrameHeading } from './components/FrameHeading'\n\nexport function defaultEmptyAs(str: string, dflt: string) {\n\tif (str.match(/^\\s*$/)) {\n\t\treturn dflt\n\t}\n\treturn str\n}\n\n/** @public */\nexport class FrameShapeUtil extends BaseBoxShapeUtil {\n\tstatic override type = 'frame' as const\n\tstatic override props = frameShapeProps\n\tstatic override migrations = frameShapeMigrations\n\n\toverride canBind = () => true\n\n\toverride canEdit = () => true\n\n\toverride getDefaultProps(): TLFrameShape['props'] {\n\t\treturn { w: 160 * 2, h: 90 * 2, name: '' }\n\t}\n\n\toverride getGeometry(shape: TLFrameShape): Geometry2d {\n\t\treturn new Rectangle2d({\n\t\t\twidth: shape.props.w,\n\t\t\theight: shape.props.h,\n\t\t\tisFilled: false,\n\t\t})\n\t}\n\n\toverride component(shape: TLFrameShape) {\n\t\tconst bounds = this.editor.getShapeGeometry(shape).bounds\n\t\t// eslint-disable-next-line react-hooks/rules-of-hooks\n\t\tconst theme = useDefaultColorTheme()\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t)\n\t}\n\n\toverride toSvg(shape: TLFrameShape): SVGElement | Promise {\n\t\tconst theme = getDefaultColorTheme({ isDarkMode: this.editor.user.isDarkMode })\n\t\tconst g = document.createElementNS('http://www.w3.org/2000/svg', 'g')\n\n\t\tconst rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect')\n\t\trect.setAttribute('width', shape.props.w.toString())\n\t\trect.setAttribute('height', shape.props.h.toString())\n\t\trect.setAttribute('fill', theme.solid)\n\t\trect.setAttribute('stroke', theme.black.solid)\n\t\trect.setAttribute('stroke-width', '1')\n\t\trect.setAttribute('rx', '1')\n\t\trect.setAttribute('ry', '1')\n\t\tg.appendChild(rect)\n\n\t\t// Text label\n\t\tconst pageRotation = canonicalizeRotation(\n\t\t\tthis.editor.getShapePageTransform(shape.id)!.rotation()\n\t\t)\n\t\t// rotate right 45 deg\n\t\tconst offsetRotation = pageRotation + Math.PI / 4\n\t\tconst scaledRotation = (offsetRotation * (2 / Math.PI) + 4) % 4\n\t\tconst labelSide: SelectionEdge = (['top', 'left', 'bottom', 'right'] as const)[\n\t\t\tMath.floor(scaledRotation)\n\t\t]\n\n\t\tlet labelTranslate: string\n\t\tswitch (labelSide) {\n\t\t\tcase 'top':\n\t\t\t\tlabelTranslate = ``\n\t\t\t\tbreak\n\t\t\tcase 'right':\n\t\t\t\tlabelTranslate = `translate(${toDomPrecision(shape.props.w)}px, 0px) rotate(90deg)`\n\t\t\t\tbreak\n\t\t\tcase 'bottom':\n\t\t\t\tlabelTranslate = `translate(${toDomPrecision(shape.props.w)}px, ${toDomPrecision(\n\t\t\t\t\tshape.props.h\n\t\t\t\t)}px) rotate(180deg)`\n\t\t\t\tbreak\n\t\t\tcase 'left':\n\t\t\t\tlabelTranslate = `translate(0px, ${toDomPrecision(shape.props.h)}px) rotate(270deg)`\n\t\t\t\tbreak\n\t\t\tdefault:\n\t\t\t\tlabelTranslate = ``\n\t\t}\n\n\t\t// Truncate with ellipsis\n\t\tconst opts = {\n\t\t\tfontSize: 12,\n\t\t\tfontFamily: 'Inter, sans-serif',\n\t\t\ttextAlign: 'start' as const,\n\t\t\twidth: shape.props.w,\n\t\t\theight: 32,\n\t\t\tpadding: 0,\n\t\t\tlineHeight: 1,\n\t\t\tfontStyle: 'normal',\n\t\t\tfontWeight: 'normal',\n\t\t\toverflow: 'truncate-ellipsis' as const,\n\t\t\tverticalTextAlign: 'middle' as const,\n\t\t}\n\n\t\tconst spans = this.editor.textMeasure.measureTextSpans(\n\t\t\tdefaultEmptyAs(shape.props.name, 'Frame') + String.fromCharCode(8203),\n\t\t\topts\n\t\t)\n\n\t\tconst firstSpan = spans[0]\n\t\tconst lastSpan = last(spans)!\n\t\tconst labelTextWidth = lastSpan.box.w + lastSpan.box.x - firstSpan.box.x\n\t\tconst text = createTextSvgElementFromSpans(this.editor, spans, {\n\t\t\toffsetY: -opts.height - 2,\n\t\t\t...opts,\n\t\t})\n\t\ttext.style.setProperty('transform', labelTranslate)\n\n\t\tconst textBg = document.createElementNS('http://www.w3.org/2000/svg', 'rect')\n\t\ttextBg.setAttribute('x', '-8px')\n\t\ttextBg.setAttribute('y', -opts.height - 4 + 'px')\n\t\ttextBg.setAttribute('width', labelTextWidth + 16 + 'px')\n\t\ttextBg.setAttribute('height', `${opts.height}px`)\n\t\ttextBg.setAttribute('rx', 4 + 'px')\n\t\ttextBg.setAttribute('ry', 4 + 'px')\n\t\ttextBg.setAttribute('fill', theme.background)\n\n\t\tg.appendChild(textBg)\n\t\tg.appendChild(text)\n\n\t\treturn g\n\t}\n\n\tindicator(shape: TLFrameShape) {\n\t\tconst bounds = this.editor.getShapeGeometry(shape).bounds\n\n\t\treturn (\n\t\t\t\n\t\t)\n\t}\n\n\toverride canReceiveNewChildrenOfType = (shape: TLShape, _type: TLShape['type']) => {\n\t\treturn !shape.isLocked\n\t}\n\n\toverride providesBackgroundForChildren(): boolean {\n\t\treturn true\n\t}\n\n\toverride canDropShapes = (shape: TLFrameShape, _shapes: TLShape[]): boolean => {\n\t\treturn !shape.isLocked\n\t}\n\n\toverride onDragShapesOver = (frame: TLFrameShape, shapes: TLShape[]): { shouldHint: boolean } => {\n\t\tif (!shapes.every((child) => child.parentId === frame.id)) {\n\t\t\tthis.editor.reparentShapes(\n\t\t\t\tshapes.map((shape) => shape.id),\n\t\t\t\tframe.id\n\t\t\t)\n\t\t\treturn { shouldHint: true }\n\t\t}\n\t\treturn { shouldHint: false }\n\t}\n\n\toverride onDragShapesOut = (_shape: TLFrameShape, shapes: TLShape[]): void => {\n\t\tconst parent = this.editor.getShape(_shape.parentId)\n\t\tconst isInGroup = parent && this.editor.isShapeOfType(parent, 'group')\n\n\t\t// If frame is in a group, keep the shape\n\t\t// moved out in that group\n\n\t\tif (isInGroup) {\n\t\t\tthis.editor.reparentShapes(shapes, parent.id)\n\t\t} else {\n\t\t\tthis.editor.reparentShapes(shapes, this.editor.currentPageId)\n\t\t}\n\t}\n\n\toverride onResizeEnd: TLOnResizeEndHandler = (shape) => {\n\t\tconst bounds = this.editor.getShapePageBounds(shape)!\n\t\tconst children = this.editor.getSortedChildIdsForParent(shape.id)\n\n\t\tconst shapesToReparent: TLShapeId[] = []\n\n\t\tfor (const childId of children) {\n\t\t\tconst childBounds = this.editor.getShapePageBounds(childId)!\n\t\t\tif (!bounds.includes(childBounds)) {\n\t\t\t\tshapesToReparent.push(childId)\n\t\t\t}\n\t\t}\n\n\t\tif (shapesToReparent.length > 0) {\n\t\t\tthis.editor.reparentShapes(shapesToReparent, this.editor.currentPageId)\n\t\t}\n\t}\n}\n"], "mappings": "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", "names": [] }