tldraw
Version:
A tiny little drawing editor.
8 lines (7 loc) • 3.99 kB
Source Map (JSON)
{
"version": 3,
"sources": ["../../../../src/lib/shapes/shared/createTextJsxFromSpans.tsx"],
"sourcesContent": ["import {\n\tBox,\n\tBoxModel,\n\tEditor,\n\tTLDefaultVerticalAlignStyle,\n\tTLMeasureTextSpanOpts,\n} from '@tldraw/editor'\n\nfunction correctSpacesToNbsp(input: string) {\n\treturn input.replace(/\\s/g, '\\xa0')\n}\n\nexport interface TLCreateTextJsxFromSpansOpts extends TLMeasureTextSpanOpts {\n\tverticalTextAlign: TLDefaultVerticalAlignStyle\n\toffsetX: number\n\toffsetY: number\n\tstroke?: string\n\tstrokeWidth?: number\n\tfill?: string\n}\n\n/** Get an SVG element for a text shape. */\nexport function createTextJsxFromSpans(\n\teditor: Editor,\n\tspans: { text: string; box: BoxModel }[],\n\topts: TLCreateTextJsxFromSpansOpts\n) {\n\tconst { padding = 0 } = opts\n\tif (spans.length === 0) return null\n\n\tconst bounds = Box.From(spans[0].box)\n\tfor (const { box } of spans) {\n\t\tbounds.union(box)\n\t}\n\n\tconst offsetX = padding + (opts.offsetX ?? 0)\n\tconst offsetY =\n\t\t(opts.offsetY ?? 0) +\n\t\topts.fontSize / 2 +\n\t\t(opts.verticalTextAlign === 'start'\n\t\t\t? padding\n\t\t\t: opts.verticalTextAlign === 'end'\n\t\t\t\t? opts.height - padding - bounds.height\n\t\t\t\t: (Math.ceil(opts.height) - bounds.height) / 2)\n\n\t// Create text span elements for each word\n\tlet currentLineTop = null\n\tconst children = []\n\tfor (const { text, box } of spans) {\n\t\t// if we broke a line, add a line break span. This helps tools like\n\t\t// figma import our exported svg correctly\n\t\tconst didBreakLine = currentLineTop !== null && box.y > currentLineTop\n\t\tif (didBreakLine) {\n\t\t\tchildren.push(\n\t\t\t\t<tspan\n\t\t\t\t\tkey={children.length}\n\t\t\t\t\talignmentBaseline=\"mathematical\"\n\t\t\t\t\tx={offsetX}\n\t\t\t\t\ty={box.y + offsetY}\n\t\t\t\t>\n\t\t\t\t\t{'\\n'}\n\t\t\t\t</tspan>\n\t\t\t)\n\t\t}\n\n\t\tchildren.push(\n\t\t\t<tspan\n\t\t\t\tkey={children.length}\n\t\t\t\talignmentBaseline=\"mathematical\"\n\t\t\t\tx={box.x + offsetX}\n\t\t\t\ty={box.y + offsetY}\n\t\t\t\t// N.B. This property, while discouraged (\"intended for Document Type Definition (DTD) designers\")\n\t\t\t\t// is necessary for ensuring correct mixed RTL/LTR behavior when exporting SVGs.\n\t\t\t\tunicodeBidi=\"plaintext\"\n\t\t\t>\n\t\t\t\t{correctSpacesToNbsp(text)}\n\t\t\t</tspan>\n\t\t)\n\n\t\tcurrentLineTop = box.y\n\t}\n\n\treturn (\n\t\t<text\n\t\t\tfontSize={opts.fontSize}\n\t\t\tfontFamily={opts.fontFamily}\n\t\t\tfontStyle={opts.fontStyle}\n\t\t\tfontWeight={opts.fontWeight}\n\t\t\tdominantBaseline=\"mathematical\"\n\t\t\talignmentBaseline=\"mathematical\"\n\t\t\tstroke={opts.stroke}\n\t\t\tstrokeWidth={opts.strokeWidth}\n\t\t\tfill={opts.fill}\n\t\t>\n\t\t\t{children}\n\t\t</text>\n\t)\n}\n"],
"mappings": "AAsDI;AAtDJ;AAAA,EACC;AAAA,OAKM;AAEP,SAAS,oBAAoB,OAAe;AAC3C,SAAO,MAAM,QAAQ,OAAO,MAAM;AACnC;AAYO,SAAS,uBACf,QACA,OACA,MACC;AACD,QAAM,EAAE,UAAU,EAAE,IAAI;AACxB,MAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,QAAM,SAAS,IAAI,KAAK,MAAM,CAAC,EAAE,GAAG;AACpC,aAAW,EAAE,IAAI,KAAK,OAAO;AAC5B,WAAO,MAAM,GAAG;AAAA,EACjB;AAEA,QAAM,UAAU,WAAW,KAAK,WAAW;AAC3C,QAAM,WACJ,KAAK,WAAW,KACjB,KAAK,WAAW,KACf,KAAK,sBAAsB,UACzB,UACA,KAAK,sBAAsB,QAC1B,KAAK,SAAS,UAAU,OAAO,UAC9B,KAAK,KAAK,KAAK,MAAM,IAAI,OAAO,UAAU;AAGhD,MAAI,iBAAiB;AACrB,QAAM,WAAW,CAAC;AAClB,aAAW,EAAE,MAAM,IAAI,KAAK,OAAO;AAGlC,UAAM,eAAe,mBAAmB,QAAQ,IAAI,IAAI;AACxD,QAAI,cAAc;AACjB,eAAS;AAAA,QACR;AAAA,UAAC;AAAA;AAAA,YAEA,mBAAkB;AAAA,YAClB,GAAG;AAAA,YACH,GAAG,IAAI,IAAI;AAAA,YAEV;AAAA;AAAA,UALI,SAAS;AAAA,QAMf;AAAA,MACD;AAAA,IACD;AAEA,aAAS;AAAA,MACR;AAAA,QAAC;AAAA;AAAA,UAEA,mBAAkB;AAAA,UAClB,GAAG,IAAI,IAAI;AAAA,UACX,GAAG,IAAI,IAAI;AAAA,UAGX,aAAY;AAAA,UAEX,8BAAoB,IAAI;AAAA;AAAA,QARpB,SAAS;AAAA,MASf;AAAA,IACD;AAEA,qBAAiB,IAAI;AAAA,EACtB;AAEA,SACC;AAAA,IAAC;AAAA;AAAA,MACA,UAAU,KAAK;AAAA,MACf,YAAY,KAAK;AAAA,MACjB,WAAW,KAAK;AAAA,MAChB,YAAY,KAAK;AAAA,MACjB,kBAAiB;AAAA,MACjB,mBAAkB;AAAA,MAClB,QAAQ,KAAK;AAAA,MACb,aAAa,KAAK;AAAA,MAClB,MAAM,KAAK;AAAA,MAEV;AAAA;AAAA,EACF;AAEF;",
"names": []
}