/* eslint-disable react-hooks/rules-of-hooks */ import { Box2d, toDomPrecision, Vec2d } from '@tldraw/primitives' import { TLTextShape } from '@tldraw/tlschema' import { HTMLContainer } from '../../../components/HTMLContainer' import { FONT_FAMILIES, FONT_SIZES, TEXT_PROPS } from '../../../constants' import { stopEventPropagation } from '../../../utils/dom' import { WeakMapCache } from '../../../utils/WeakMapCache' import { Editor } from '../../Editor' import { ShapeUtil, TLOnEditEndHandler, TLOnResizeHandler, TLShapeUtilFlag } from '../ShapeUtil' import { createTextSvgElementFromSpans } from '../shared/createTextSvgElementFromSpans' import { resizeScaled } from '../shared/resizeScaled' import { TLExportColors } from '../shared/TLExportColors' import { useEditableText } from '../shared/useEditableText' export { INDENT } from './TextHelpers' const sizeCache = new WeakMapCache() /** @public */ export class TextShapeUtil extends ShapeUtil { static override type = 'text' canEdit = () => true isAspectRatioLocked: TLShapeUtilFlag = () => true defaultProps(): TLTextShape['props'] { return { color: 'black', size: 'm', w: 8, text: '', font: 'draw', align: 'middle', autoSize: true, scale: 1, } } // @computed // private get minDimensionsCache() { // return this.editor.store.createSelectedComputedCache< // TLTextShape['props'], // { width: number; height: number }, // TLTextShape // >( // 'text measure cache', // (shape) => { // return shape.props // }, // (props) => getTextSize(this.editor, props) // ) // } getMinDimensions(shape: TLTextShape) { return sizeCache.get(shape.props, (props) => getTextSize(this.editor, props)) } getBounds(shape: TLTextShape) { const { scale } = shape.props const { width, height } = this.getMinDimensions(shape)! return new Box2d(0, 0, width * scale, height * scale) } getOutline(shape: TLTextShape) { const bounds = this.bounds(shape) return [ new Vec2d(0, 0), new Vec2d(bounds.width, 0), new Vec2d(bounds.width, bounds.height), new Vec2d(0, bounds.height), ] } getCenter(shape: TLTextShape): Vec2d { const bounds = this.bounds(shape) return new Vec2d(bounds.width / 2, bounds.height / 2) } render(shape: TLTextShape) { const { id, type, props: { text }, } = shape const { width, height } = this.getMinDimensions(shape) const { rInput, isEmpty, isEditing, isEditableFromHover, handleFocus, handleChange, handleKeyDown, handleBlur, } = useEditableText(id, type, text) return (
{text}
{isEditing || isEditableFromHover ? (