@tldraw/editor 5.3.0 → 5.4.0-next.ef99ab47e5ce

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.
@@ -299,13 +299,17 @@ class TextManager extends import_EditorManager.EditorManager {
299
299
  });
300
300
  if (opts.overflow === "truncate-ellipsis" && didTruncate) {
301
301
  elm.textContent = "\u2026";
302
- const ellipsisWidth = Math.ceil(this.measureElementTextNodeSpans(elm).spans[0].box.w);
302
+ const ellipsisSpan = this.measureElementTextNodeSpans(elm).spans[0];
303
+ const ellipsisWidth = ellipsisSpan ? Math.ceil(ellipsisSpan.box.w) : 0;
303
304
  elm.style.setProperty("width", `${elementWidth - ellipsisWidth}px`);
304
305
  elm.textContent = normalizedText;
305
306
  const truncatedSpans = this.measureElementTextNodeSpans(elm, {
306
307
  shouldTruncateToFirstLine: true
307
308
  }).spans;
308
309
  const lastSpan = truncatedSpans[truncatedSpans.length - 1];
310
+ if (!lastSpan) {
311
+ return truncatedSpans;
312
+ }
309
313
  truncatedSpans.push({
310
314
  text: "\u2026",
311
315
  box: {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/lib/editor/managers/TextManager/TextManager.ts"],
4
- "sourcesContent": ["import { BoxModel, TLDefaultHorizontalAlignStyle } from '@tldraw/tlschema'\nimport { objectMapKeys } from '@tldraw/utils'\nimport type { Editor } from '../../Editor'\nimport { EditorManager } from '../EditorManager'\n\n/**\n * The whole-pixel line-height for a given font size and tldraw's unitless line-height\n * multiplier. tldraw's theme stores line-height as a multiplier (e.g. 1.35); resolving it\n * to a whole pixel keeps line spacing identical across rendering engines, which otherwise\n * disagree on fractional line boxes (WebKit snaps them to whole pixels, Blink keeps the\n * fraction) and let multi-line text drift apart. Apply it everywhere line-height is used \u2014\n * measurement, on-canvas render, and export \u2014 so geometry and rendering agree.\n * See https://github.com/tldraw/tldraw/issues/8970.\n *\n * @public\n */\nexport function resolveLineHeightPx(fontSize: number, lineHeight: number): number {\n\treturn Math.round(fontSize * lineHeight)\n}\n\nconst fixNewLines = /\\r?\\n|\\r/g\n\nfunction normalizeTextForDom(text: string) {\n\treturn text\n\t\t.replace(fixNewLines, '\\n')\n\t\t.split('\\n')\n\t\t.map((x) => x || ' ')\n\t\t.join('\\n')\n}\n\nconst textAlignmentsForLtr = {\n\tstart: 'left',\n\t'start-legacy': 'left',\n\tmiddle: 'center',\n\t'middle-legacy': 'center',\n\tend: 'right',\n\t'end-legacy': 'right',\n}\n\ninterface PoolItem {\n\tel: HTMLDivElement\n\thtml: string\n\tappliedStyleKeys: string[]\n}\n\n/** @public */\nexport interface BatchMeasurementRequest {\n\thtml: string\n\topts: TLMeasureTextOpts\n}\n\n/** @public */\nexport type TLMeasuredTextSize = BoxModel & {\n\tscrollWidth: number\n}\n\n/** @public */\nexport interface TLMeasureTextOpts {\n\tfontStyle: string\n\tfontWeight: string\n\tfontFamily: string\n\tfontSize: number\n\t/** This must be a number, e.g. 1.35, not a pixel value. */\n\tlineHeight: number\n\t/**\n\t * When maxWidth is a number, the text will be wrapped to that maxWidth. When maxWidth\n\t * is null, the text will be measured without wrapping, but explicit line breaks and\n\t * space are preserved.\n\t */\n\tmaxWidth: null | number\n\tminWidth?: null | number\n\t// todo: make this a number so that it is consistent with other TLMeasureTextSpanOpts\n\tpadding: string\n\totherStyles?: Record<string, string>\n\tdisableOverflowWrapBreaking?: boolean\n\tmeasureScrollWidth?: boolean\n}\n\n/** @public */\nexport interface TLMeasureTextSpanOpts {\n\toverflow: 'wrap' | 'truncate-ellipsis' | 'truncate-clip'\n\twidth: number\n\theight: number\n\tpadding: number\n\tfontSize: number\n\tfontWeight: string\n\tfontFamily: string\n\tfontStyle: string\n\tlineHeight: number\n\ttextAlign: TLDefaultHorizontalAlignStyle\n\totherStyles?: Record<string, string>\n\tmeasureScrollWidth?: boolean\n}\n\nconst spaceCharacterRegex = /\\s/\n\n// Iterate by grapheme cluster (e.g. emoji sequences, flags, accented letters)\n// rather than by code point, so a single glyph is measured as one unit.\nconst graphemeSegmenter = new Intl.Segmenter(undefined, { granularity: 'grapheme' })\n\nconst initialDefaultStyles = Object.freeze({\n\t'overflow-wrap': 'break-word',\n\t'word-break': 'auto',\n\twidth: null,\n\theight: null,\n\t'max-width': null,\n\t'min-width': null,\n})\n\n/** @public */\nexport class TextManager extends EditorManager {\n\tprivate elm: HTMLDivElement\n\tprivate poolElms: PoolItem[] = []\n\n\tconstructor(editor: Editor) {\n\t\tsuper(editor)\n\t\tthis.elm = this.createMeasurementEl()\n\t\tthis.editor.getContainer().appendChild(this.elm)\n\t\tthis.register(() => {\n\t\t\tthis.elm.remove()\n\t\t\tfor (const { el } of this.poolElms) {\n\t\t\t\tel.remove()\n\t\t\t}\n\t\t\tthis.poolElms.length = 0\n\t\t})\n\t}\n\n\tprivate createMeasurementEl(): HTMLDivElement {\n\t\tconst elm = this.editor.getContainerDocument().createElement('div')\n\t\telm.classList.add('tl-text')\n\t\telm.classList.add('tl-text-measure')\n\t\telm.setAttribute('dir', 'auto')\n\t\telm.tabIndex = -1\n\t\tfor (const key of objectMapKeys(initialDefaultStyles)) {\n\t\t\telm.style.setProperty(key, initialDefaultStyles[key])\n\t\t}\n\n\t\treturn elm\n\t}\n\n\tprivate resetElementStyles(el: HTMLElement, appliedStyleKeys: string[]) {\n\t\tfor (const key of appliedStyleKeys) {\n\t\t\tif (key in initialDefaultStyles) {\n\t\t\t\tel.style.setProperty(key, initialDefaultStyles[key as keyof typeof initialDefaultStyles])\n\t\t\t} else {\n\t\t\t\tel.style.removeProperty(key)\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate setElementStyles(el: HTMLElement, styles: Record<string, string | undefined | null>) {\n\t\ttype StyleValue = string | null\n\t\ttype RestoreEntry = [prop: string, value: StyleValue]\n\n\t\tconst restore: RestoreEntry[] = []\n\n\t\tfor (const [key, nextValue] of Object.entries(styles)) {\n\t\t\tconst oldValue = el.style.getPropertyValue(key)\n\n\t\t\tif (typeof nextValue === 'string') {\n\t\t\t\tif (oldValue === nextValue) continue\n\t\t\t\trestore.push([key, oldValue || null])\n\t\t\t\tel.style.setProperty(key, nextValue)\n\t\t\t} else {\n\t\t\t\tif (!oldValue) continue\n\t\t\t\trestore.push([key, oldValue])\n\t\t\t\tel.style.removeProperty(key)\n\t\t\t}\n\t\t}\n\n\t\treturn () => {\n\t\t\tfor (const [key, value] of restore) {\n\t\t\t\tif (value === null || value === '') el.style.removeProperty(key)\n\t\t\t\telse el.style.setProperty(key, value)\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate getMeasureStyles(opts: TLMeasureTextOpts): Record<string, string | undefined> {\n\t\treturn {\n\t\t\t'font-family': opts.fontFamily,\n\t\t\t'font-style': opts.fontStyle,\n\t\t\t'font-weight': opts.fontWeight,\n\t\t\t'font-size': opts.fontSize + 'px',\n\t\t\t'line-height': `${resolveLineHeightPx(opts.fontSize, opts.lineHeight)}px`,\n\t\t\t// Unitless multiplier consumed by the .tl-rich-text h1\u2013h6 rule (see editor.css),\n\t\t\t// so heading measurement matches on-canvas rendering.\n\t\t\t'--tl-rich-text-heading-line-height': `${opts.lineHeight}`,\n\t\t\tpadding: opts.padding,\n\t\t\t'max-width': opts.maxWidth ? opts.maxWidth + 'px' : undefined,\n\t\t\t'min-width': opts.minWidth ? opts.minWidth + 'px' : undefined,\n\t\t\t'overflow-wrap': opts.disableOverflowWrapBreaking ? 'normal' : 'break-word',\n\t\t\t...opts.otherStyles,\n\t\t}\n\t}\n\n\tprivate ensurePoolSize(size: number) {\n\t\tif (this.poolElms.length >= size) return\n\n\t\tconst fragment = this.editor.getContainerDocument().createDocumentFragment()\n\t\twhile (this.poolElms.length < size) {\n\t\t\tconst el = this.createMeasurementEl()\n\t\t\tthis.poolElms.push({ el, html: '', appliedStyleKeys: [] })\n\t\t\tfragment.appendChild(el)\n\t\t}\n\t\tthis.editor.getContainer().appendChild(fragment)\n\t}\n\n\tprivate getPoolItem(index: number): PoolItem {\n\t\tthis.ensurePoolSize(index + 1)\n\t\treturn this.poolElms[index]\n\t}\n\n\tmeasureHtmlBatch(requests: BatchMeasurementRequest[]): TLMeasuredTextSize[] {\n\t\tif (requests.length === 0) return []\n\n\t\twhile (this.poolElms.length > requests.length) {\n\t\t\tconst { el } = this.poolElms.pop()!\n\t\t\tel.remove()\n\t\t}\n\n\t\tfor (let i = 0; i < requests.length; i++) {\n\t\t\tconst { html, opts } = requests[i]\n\t\t\tconst poolItem = this.getPoolItem(i)\n\n\t\t\tconst { el } = poolItem\n\t\t\tthis.resetElementStyles(el, poolItem.appliedStyleKeys)\n\t\t\tconst styles = this.getMeasureStyles(opts)\n\t\t\tthis.setElementStyles(el, styles)\n\t\t\tpoolItem.appliedStyleKeys = Object.keys(styles)\n\t\t\t// Skip innerHTML parsing if the content hasn't changed\n\t\t\tif (poolItem.html !== html) {\n\t\t\t\tel.innerHTML = html\n\t\t\t\tpoolItem.html = html\n\t\t\t}\n\t\t}\n\n\t\tconst results: TLMeasuredTextSize[] = []\n\t\tfor (let i = 0; i < requests.length; i++) {\n\t\t\tconst el = this.getPoolItem(i).el\n\t\t\tconst scrollWidth = requests[i].opts.measureScrollWidth ? el.scrollWidth : 0\n\t\t\tconst rect = el.getBoundingClientRect()\n\t\t\tresults.push({\n\t\t\t\tx: 0,\n\t\t\t\ty: 0,\n\t\t\t\tw: rect.width,\n\t\t\t\th: rect.height,\n\t\t\t\tscrollWidth,\n\t\t\t})\n\t\t}\n\n\t\treturn results\n\t}\n\n\tmeasureText(textToMeasure: string, opts: TLMeasureTextOpts): TLMeasuredTextSize {\n\t\tconst div = this.editor.getContainerDocument().createElement('div')\n\t\tdiv.textContent = normalizeTextForDom(textToMeasure)\n\t\treturn this.measureHtml(div.innerHTML, opts)\n\t}\n\n\tmeasureHtml(html: string, opts: TLMeasureTextOpts): TLMeasuredTextSize {\n\t\tconst { elm } = this\n\n\t\tconst restoreStyles = this.setElementStyles(elm, this.getMeasureStyles(opts))\n\n\t\ttry {\n\t\t\telm.innerHTML = html\n\n\t\t\tconst scrollWidth = opts.measureScrollWidth ? elm.scrollWidth : 0\n\t\t\tconst rect = elm.getBoundingClientRect()\n\n\t\t\treturn {\n\t\t\t\tx: 0,\n\t\t\t\ty: 0,\n\t\t\t\tw: rect.width,\n\t\t\t\th: rect.height,\n\t\t\t\tscrollWidth,\n\t\t\t}\n\t\t} finally {\n\t\t\trestoreStyles()\n\t\t}\n\t}\n\n\t/**\n\t * Given an html element, measure the position of each span of unbroken\n\t * word/white-space characters within any text nodes it contains.\n\t */\n\tmeasureElementTextNodeSpans(\n\t\telement: HTMLElement,\n\t\t{ shouldTruncateToFirstLine = false }: { shouldTruncateToFirstLine?: boolean } = {}\n\t): { spans: { box: BoxModel; text: string }[]; didTruncate: boolean } {\n\t\tconst spans = []\n\n\t\t// Measurements of individual spans are relative to the containing element\n\t\tconst elmBounds = element.getBoundingClientRect()\n\t\tconst offsetX = -elmBounds.left\n\t\tconst offsetY = -elmBounds.top\n\n\t\t// we measure by creating a range that spans each character in the elements text node\n\t\tconst range = new Range()\n\t\tconst textNode = element.childNodes[0]\n\t\tlet idx = 0\n\n\t\tlet currentSpan = null\n\t\tlet prevCharWasSpaceCharacter = null\n\t\tlet prevCharTop = 0\n\t\tlet prevCharLeftForRTLTest = 0\n\t\tlet didTruncate = false\n\t\tfor (const childNode of element.childNodes) {\n\t\t\tif (childNode.nodeType !== Node.TEXT_NODE) continue\n\n\t\t\tfor (const { segment } of graphemeSegmenter.segment(childNode.textContent ?? '')) {\n\t\t\t\t// place the range around the grapheme we're interested in\n\t\t\t\trange.setStart(textNode, idx)\n\t\t\t\trange.setEnd(textNode, idx + segment.length)\n\t\t\t\t// measure the range. some browsers return multiple rects for the\n\t\t\t\t// first char in a new line - one for the line break, and one for\n\t\t\t\t// the character itself. we're only interested in the character.\n\t\t\t\tconst rects = range.getClientRects()\n\t\t\t\tconst rect = rects[rects.length - 1]\n\n\t\t\t\t// some graphemes produce no layout rectangle (e.g. zero-width\n\t\t\t\t// spaces or newlines). skip them rather than crashing, but keep\n\t\t\t\t// advancing the index so later graphemes stay aligned.\n\t\t\t\t// See https://github.com/tldraw/tldraw/issues/9112.\n\t\t\t\tif (!rect) {\n\t\t\t\t\tidx += segment.length\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t// calculate the position of the character relative to the element\n\t\t\t\tconst top = rect.top + offsetY\n\t\t\t\tconst left = rect.left + offsetX\n\t\t\t\tconst right = rect.right + offsetX\n\t\t\t\tconst isRTL = left < prevCharLeftForRTLTest\n\n\t\t\t\tconst isSpaceCharacter = spaceCharacterRegex.test(segment)\n\t\t\t\tif (\n\t\t\t\t\t// If we're at a word boundary...\n\t\t\t\t\tisSpaceCharacter !== prevCharWasSpaceCharacter ||\n\t\t\t\t\t// ...or we're on a different line...\n\t\t\t\t\ttop !== prevCharTop ||\n\t\t\t\t\t// ...or we're at the start of the text and haven't created a span yet...\n\t\t\t\t\t!currentSpan\n\t\t\t\t) {\n\t\t\t\t\t// ...then we're at a span boundary!\n\n\t\t\t\t\tif (currentSpan) {\n\t\t\t\t\t\t// if we're truncating to a single line & we just finished the first line, stop there\n\t\t\t\t\t\tif (shouldTruncateToFirstLine && top !== prevCharTop) {\n\t\t\t\t\t\t\tdidTruncate = true\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// otherwise add the span to the list ready to start a new one\n\t\t\t\t\t\tspans.push(currentSpan)\n\t\t\t\t\t}\n\n\t\t\t\t\t// start a new span\n\t\t\t\t\tcurrentSpan = {\n\t\t\t\t\t\tbox: { x: left, y: top, w: rect.width, h: rect.height },\n\t\t\t\t\t\ttext: segment,\n\t\t\t\t\t}\n\t\t\t\t\tprevCharLeftForRTLTest = left\n\t\t\t\t} else {\n\t\t\t\t\t// Looks like we're in RTL mode, so we need to adjust the left position.\n\t\t\t\t\tif (isRTL) {\n\t\t\t\t\t\tcurrentSpan.box.x = left\n\t\t\t\t\t}\n\n\t\t\t\t\t// otherwise we just need to extend the current span with the next character\n\t\t\t\t\tcurrentSpan.box.w = isRTL ? currentSpan.box.w + rect.width : right - currentSpan.box.x\n\t\t\t\t\tcurrentSpan.text += segment\n\t\t\t\t}\n\n\t\t\t\tif (segment === '\\n') {\n\t\t\t\t\tprevCharLeftForRTLTest = 0\n\t\t\t\t}\n\n\t\t\t\tprevCharWasSpaceCharacter = isSpaceCharacter\n\t\t\t\tprevCharTop = top\n\t\t\t\tidx += segment.length\n\t\t\t}\n\t\t}\n\n\t\t// Add the last span\n\t\tif (currentSpan) {\n\t\t\tspans.push(currentSpan)\n\t\t}\n\n\t\treturn { spans, didTruncate }\n\t}\n\n\t/**\n\t * Measure text into individual spans. Spans are created by rendering the\n\t * text, then dividing it up according to line breaks and word boundaries.\n\t *\n\t * It works by having the browser render the text, then measuring the\n\t * position of each character. You can use this to replicate the text-layout\n\t * algorithm of the current browser in e.g. an SVG export.\n\t */\n\tmeasureTextSpans(\n\t\ttextToMeasure: string,\n\t\topts: TLMeasureTextSpanOpts\n\t): { text: string; box: BoxModel }[] {\n\t\tif (textToMeasure === '') return []\n\n\t\tconst { elm } = this\n\n\t\tconst shouldTruncateToFirstLine =\n\t\t\topts.overflow === 'truncate-ellipsis' || opts.overflow === 'truncate-clip'\n\t\tconst elementWidth = Math.ceil(opts.width - opts.padding * 2)\n\t\tconst newStyles = {\n\t\t\t'font-family': opts.fontFamily,\n\t\t\t'font-style': opts.fontStyle,\n\t\t\t'font-weight': opts.fontWeight,\n\t\t\t'font-size': opts.fontSize + 'px',\n\t\t\t'line-height': `${resolveLineHeightPx(opts.fontSize, opts.lineHeight)}px`,\n\t\t\twidth: `${elementWidth}px`,\n\t\t\theight: 'min-content',\n\t\t\t'text-align': textAlignmentsForLtr[opts.textAlign],\n\t\t\t'overflow-wrap': shouldTruncateToFirstLine ? 'anywhere' : 'break-word',\n\t\t\t'word-break': shouldTruncateToFirstLine ? 'break-all' : 'normal',\n\t\t\t...opts.otherStyles,\n\t\t}\n\t\tconst restoreStyles = this.setElementStyles(elm, newStyles)\n\n\t\ttry {\n\t\t\tconst normalizedText = normalizeTextForDom(textToMeasure)\n\n\t\t\t// Render the text into the measurement element:\n\t\t\telm.textContent = normalizedText\n\n\t\t\t// actually measure the text:\n\t\t\tconst { spans, didTruncate } = this.measureElementTextNodeSpans(elm, {\n\t\t\t\tshouldTruncateToFirstLine,\n\t\t\t})\n\n\t\t\tif (opts.overflow === 'truncate-ellipsis' && didTruncate) {\n\t\t\t\t// we need to measure the ellipsis to know how much space it takes up\n\t\t\t\telm.textContent = '\u2026'\n\t\t\t\tconst ellipsisWidth = Math.ceil(this.measureElementTextNodeSpans(elm).spans[0].box.w)\n\n\t\t\t\t// then, we need to subtract that space from the width we have and measure again:\n\t\t\t\telm.style.setProperty('width', `${elementWidth - ellipsisWidth}px`)\n\t\t\t\telm.textContent = normalizedText\n\t\t\t\tconst truncatedSpans = this.measureElementTextNodeSpans(elm, {\n\t\t\t\t\tshouldTruncateToFirstLine: true,\n\t\t\t\t}).spans\n\n\t\t\t\t// Finally, we add in our ellipsis at the end of the last span. We\n\t\t\t\t// have to do this after measuring, not before, because adding the\n\t\t\t\t// ellipsis changes how whitespace might be getting collapsed by the\n\t\t\t\t// browser.\n\t\t\t\tconst lastSpan = truncatedSpans[truncatedSpans.length - 1]!\n\t\t\t\ttruncatedSpans.push({\n\t\t\t\t\ttext: '\u2026',\n\t\t\t\t\tbox: {\n\t\t\t\t\t\tx: Math.min(lastSpan.box.x + lastSpan.box.w, opts.width - opts.padding - ellipsisWidth),\n\t\t\t\t\t\ty: lastSpan.box.y,\n\t\t\t\t\t\tw: ellipsisWidth,\n\t\t\t\t\t\th: lastSpan.box.h,\n\t\t\t\t\t},\n\t\t\t\t})\n\n\t\t\t\treturn truncatedSpans\n\t\t\t}\n\n\t\t\treturn spans\n\t\t} finally {\n\t\t\trestoreStyles()\n\t\t}\n\t}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { BoxModel, TLDefaultHorizontalAlignStyle } from '@tldraw/tlschema'\nimport { objectMapKeys } from '@tldraw/utils'\nimport type { Editor } from '../../Editor'\nimport { EditorManager } from '../EditorManager'\n\n/**\n * The whole-pixel line-height for a given font size and tldraw's unitless line-height\n * multiplier. tldraw's theme stores line-height as a multiplier (e.g. 1.35); resolving it\n * to a whole pixel keeps line spacing identical across rendering engines, which otherwise\n * disagree on fractional line boxes (WebKit snaps them to whole pixels, Blink keeps the\n * fraction) and let multi-line text drift apart. Apply it everywhere line-height is used \u2014\n * measurement, on-canvas render, and export \u2014 so geometry and rendering agree.\n * See https://github.com/tldraw/tldraw/issues/8970.\n *\n * @public\n */\nexport function resolveLineHeightPx(fontSize: number, lineHeight: number): number {\n\treturn Math.round(fontSize * lineHeight)\n}\n\nconst fixNewLines = /\\r?\\n|\\r/g\n\nfunction normalizeTextForDom(text: string) {\n\treturn text\n\t\t.replace(fixNewLines, '\\n')\n\t\t.split('\\n')\n\t\t.map((x) => x || ' ')\n\t\t.join('\\n')\n}\n\nconst textAlignmentsForLtr = {\n\tstart: 'left',\n\t'start-legacy': 'left',\n\tmiddle: 'center',\n\t'middle-legacy': 'center',\n\tend: 'right',\n\t'end-legacy': 'right',\n}\n\ninterface PoolItem {\n\tel: HTMLDivElement\n\thtml: string\n\tappliedStyleKeys: string[]\n}\n\n/** @public */\nexport interface BatchMeasurementRequest {\n\thtml: string\n\topts: TLMeasureTextOpts\n}\n\n/** @public */\nexport type TLMeasuredTextSize = BoxModel & {\n\tscrollWidth: number\n}\n\n/** @public */\nexport interface TLMeasureTextOpts {\n\tfontStyle: string\n\tfontWeight: string\n\tfontFamily: string\n\tfontSize: number\n\t/** This must be a number, e.g. 1.35, not a pixel value. */\n\tlineHeight: number\n\t/**\n\t * When maxWidth is a number, the text will be wrapped to that maxWidth. When maxWidth\n\t * is null, the text will be measured without wrapping, but explicit line breaks and\n\t * space are preserved.\n\t */\n\tmaxWidth: null | number\n\tminWidth?: null | number\n\t// todo: make this a number so that it is consistent with other TLMeasureTextSpanOpts\n\tpadding: string\n\totherStyles?: Record<string, string>\n\tdisableOverflowWrapBreaking?: boolean\n\tmeasureScrollWidth?: boolean\n}\n\n/** @public */\nexport interface TLMeasureTextSpanOpts {\n\toverflow: 'wrap' | 'truncate-ellipsis' | 'truncate-clip'\n\twidth: number\n\theight: number\n\tpadding: number\n\tfontSize: number\n\tfontWeight: string\n\tfontFamily: string\n\tfontStyle: string\n\tlineHeight: number\n\ttextAlign: TLDefaultHorizontalAlignStyle\n\totherStyles?: Record<string, string>\n\tmeasureScrollWidth?: boolean\n}\n\nconst spaceCharacterRegex = /\\s/\n\n// Iterate by grapheme cluster (e.g. emoji sequences, flags, accented letters)\n// rather than by code point, so a single glyph is measured as one unit.\nconst graphemeSegmenter = new Intl.Segmenter(undefined, { granularity: 'grapheme' })\n\nconst initialDefaultStyles = Object.freeze({\n\t'overflow-wrap': 'break-word',\n\t'word-break': 'auto',\n\twidth: null,\n\theight: null,\n\t'max-width': null,\n\t'min-width': null,\n})\n\n/** @public */\nexport class TextManager extends EditorManager {\n\tprivate elm: HTMLDivElement\n\tprivate poolElms: PoolItem[] = []\n\n\tconstructor(editor: Editor) {\n\t\tsuper(editor)\n\t\tthis.elm = this.createMeasurementEl()\n\t\tthis.editor.getContainer().appendChild(this.elm)\n\t\tthis.register(() => {\n\t\t\tthis.elm.remove()\n\t\t\tfor (const { el } of this.poolElms) {\n\t\t\t\tel.remove()\n\t\t\t}\n\t\t\tthis.poolElms.length = 0\n\t\t})\n\t}\n\n\tprivate createMeasurementEl(): HTMLDivElement {\n\t\tconst elm = this.editor.getContainerDocument().createElement('div')\n\t\telm.classList.add('tl-text')\n\t\telm.classList.add('tl-text-measure')\n\t\telm.setAttribute('dir', 'auto')\n\t\telm.tabIndex = -1\n\t\tfor (const key of objectMapKeys(initialDefaultStyles)) {\n\t\t\telm.style.setProperty(key, initialDefaultStyles[key])\n\t\t}\n\n\t\treturn elm\n\t}\n\n\tprivate resetElementStyles(el: HTMLElement, appliedStyleKeys: string[]) {\n\t\tfor (const key of appliedStyleKeys) {\n\t\t\tif (key in initialDefaultStyles) {\n\t\t\t\tel.style.setProperty(key, initialDefaultStyles[key as keyof typeof initialDefaultStyles])\n\t\t\t} else {\n\t\t\t\tel.style.removeProperty(key)\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate setElementStyles(el: HTMLElement, styles: Record<string, string | undefined | null>) {\n\t\ttype StyleValue = string | null\n\t\ttype RestoreEntry = [prop: string, value: StyleValue]\n\n\t\tconst restore: RestoreEntry[] = []\n\n\t\tfor (const [key, nextValue] of Object.entries(styles)) {\n\t\t\tconst oldValue = el.style.getPropertyValue(key)\n\n\t\t\tif (typeof nextValue === 'string') {\n\t\t\t\tif (oldValue === nextValue) continue\n\t\t\t\trestore.push([key, oldValue || null])\n\t\t\t\tel.style.setProperty(key, nextValue)\n\t\t\t} else {\n\t\t\t\tif (!oldValue) continue\n\t\t\t\trestore.push([key, oldValue])\n\t\t\t\tel.style.removeProperty(key)\n\t\t\t}\n\t\t}\n\n\t\treturn () => {\n\t\t\tfor (const [key, value] of restore) {\n\t\t\t\tif (value === null || value === '') el.style.removeProperty(key)\n\t\t\t\telse el.style.setProperty(key, value)\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate getMeasureStyles(opts: TLMeasureTextOpts): Record<string, string | undefined> {\n\t\treturn {\n\t\t\t'font-family': opts.fontFamily,\n\t\t\t'font-style': opts.fontStyle,\n\t\t\t'font-weight': opts.fontWeight,\n\t\t\t'font-size': opts.fontSize + 'px',\n\t\t\t'line-height': `${resolveLineHeightPx(opts.fontSize, opts.lineHeight)}px`,\n\t\t\t// Unitless multiplier consumed by the .tl-rich-text h1\u2013h6 rule (see editor.css),\n\t\t\t// so heading measurement matches on-canvas rendering.\n\t\t\t'--tl-rich-text-heading-line-height': `${opts.lineHeight}`,\n\t\t\tpadding: opts.padding,\n\t\t\t'max-width': opts.maxWidth ? opts.maxWidth + 'px' : undefined,\n\t\t\t'min-width': opts.minWidth ? opts.minWidth + 'px' : undefined,\n\t\t\t'overflow-wrap': opts.disableOverflowWrapBreaking ? 'normal' : 'break-word',\n\t\t\t...opts.otherStyles,\n\t\t}\n\t}\n\n\tprivate ensurePoolSize(size: number) {\n\t\tif (this.poolElms.length >= size) return\n\n\t\tconst fragment = this.editor.getContainerDocument().createDocumentFragment()\n\t\twhile (this.poolElms.length < size) {\n\t\t\tconst el = this.createMeasurementEl()\n\t\t\tthis.poolElms.push({ el, html: '', appliedStyleKeys: [] })\n\t\t\tfragment.appendChild(el)\n\t\t}\n\t\tthis.editor.getContainer().appendChild(fragment)\n\t}\n\n\tprivate getPoolItem(index: number): PoolItem {\n\t\tthis.ensurePoolSize(index + 1)\n\t\treturn this.poolElms[index]\n\t}\n\n\tmeasureHtmlBatch(requests: BatchMeasurementRequest[]): TLMeasuredTextSize[] {\n\t\tif (requests.length === 0) return []\n\n\t\twhile (this.poolElms.length > requests.length) {\n\t\t\tconst { el } = this.poolElms.pop()!\n\t\t\tel.remove()\n\t\t}\n\n\t\tfor (let i = 0; i < requests.length; i++) {\n\t\t\tconst { html, opts } = requests[i]\n\t\t\tconst poolItem = this.getPoolItem(i)\n\n\t\t\tconst { el } = poolItem\n\t\t\tthis.resetElementStyles(el, poolItem.appliedStyleKeys)\n\t\t\tconst styles = this.getMeasureStyles(opts)\n\t\t\tthis.setElementStyles(el, styles)\n\t\t\tpoolItem.appliedStyleKeys = Object.keys(styles)\n\t\t\t// Skip innerHTML parsing if the content hasn't changed\n\t\t\tif (poolItem.html !== html) {\n\t\t\t\tel.innerHTML = html\n\t\t\t\tpoolItem.html = html\n\t\t\t}\n\t\t}\n\n\t\tconst results: TLMeasuredTextSize[] = []\n\t\tfor (let i = 0; i < requests.length; i++) {\n\t\t\tconst el = this.getPoolItem(i).el\n\t\t\tconst scrollWidth = requests[i].opts.measureScrollWidth ? el.scrollWidth : 0\n\t\t\tconst rect = el.getBoundingClientRect()\n\t\t\tresults.push({\n\t\t\t\tx: 0,\n\t\t\t\ty: 0,\n\t\t\t\tw: rect.width,\n\t\t\t\th: rect.height,\n\t\t\t\tscrollWidth,\n\t\t\t})\n\t\t}\n\n\t\treturn results\n\t}\n\n\tmeasureText(textToMeasure: string, opts: TLMeasureTextOpts): TLMeasuredTextSize {\n\t\tconst div = this.editor.getContainerDocument().createElement('div')\n\t\tdiv.textContent = normalizeTextForDom(textToMeasure)\n\t\treturn this.measureHtml(div.innerHTML, opts)\n\t}\n\n\tmeasureHtml(html: string, opts: TLMeasureTextOpts): TLMeasuredTextSize {\n\t\tconst { elm } = this\n\n\t\tconst restoreStyles = this.setElementStyles(elm, this.getMeasureStyles(opts))\n\n\t\ttry {\n\t\t\telm.innerHTML = html\n\n\t\t\tconst scrollWidth = opts.measureScrollWidth ? elm.scrollWidth : 0\n\t\t\tconst rect = elm.getBoundingClientRect()\n\n\t\t\treturn {\n\t\t\t\tx: 0,\n\t\t\t\ty: 0,\n\t\t\t\tw: rect.width,\n\t\t\t\th: rect.height,\n\t\t\t\tscrollWidth,\n\t\t\t}\n\t\t} finally {\n\t\t\trestoreStyles()\n\t\t}\n\t}\n\n\t/**\n\t * Given an html element, measure the position of each span of unbroken\n\t * word/white-space characters within any text nodes it contains.\n\t */\n\tmeasureElementTextNodeSpans(\n\t\telement: HTMLElement,\n\t\t{ shouldTruncateToFirstLine = false }: { shouldTruncateToFirstLine?: boolean } = {}\n\t): { spans: { box: BoxModel; text: string }[]; didTruncate: boolean } {\n\t\tconst spans = []\n\n\t\t// Measurements of individual spans are relative to the containing element\n\t\tconst elmBounds = element.getBoundingClientRect()\n\t\tconst offsetX = -elmBounds.left\n\t\tconst offsetY = -elmBounds.top\n\n\t\t// we measure by creating a range that spans each character in the elements text node\n\t\tconst range = new Range()\n\t\tconst textNode = element.childNodes[0]\n\t\tlet idx = 0\n\n\t\tlet currentSpan = null\n\t\tlet prevCharWasSpaceCharacter = null\n\t\tlet prevCharTop = 0\n\t\tlet prevCharLeftForRTLTest = 0\n\t\tlet didTruncate = false\n\t\tfor (const childNode of element.childNodes) {\n\t\t\tif (childNode.nodeType !== Node.TEXT_NODE) continue\n\n\t\t\tfor (const { segment } of graphemeSegmenter.segment(childNode.textContent ?? '')) {\n\t\t\t\t// place the range around the grapheme we're interested in\n\t\t\t\trange.setStart(textNode, idx)\n\t\t\t\trange.setEnd(textNode, idx + segment.length)\n\t\t\t\t// measure the range. some browsers return multiple rects for the\n\t\t\t\t// first char in a new line - one for the line break, and one for\n\t\t\t\t// the character itself. we're only interested in the character.\n\t\t\t\tconst rects = range.getClientRects()\n\t\t\t\tconst rect = rects[rects.length - 1]\n\n\t\t\t\t// some graphemes produce no layout rectangle (e.g. zero-width\n\t\t\t\t// spaces or newlines). skip them rather than crashing, but keep\n\t\t\t\t// advancing the index so later graphemes stay aligned.\n\t\t\t\t// See https://github.com/tldraw/tldraw/issues/9112.\n\t\t\t\tif (!rect) {\n\t\t\t\t\tidx += segment.length\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t// calculate the position of the character relative to the element\n\t\t\t\tconst top = rect.top + offsetY\n\t\t\t\tconst left = rect.left + offsetX\n\t\t\t\tconst right = rect.right + offsetX\n\t\t\t\tconst isRTL = left < prevCharLeftForRTLTest\n\n\t\t\t\tconst isSpaceCharacter = spaceCharacterRegex.test(segment)\n\t\t\t\tif (\n\t\t\t\t\t// If we're at a word boundary...\n\t\t\t\t\tisSpaceCharacter !== prevCharWasSpaceCharacter ||\n\t\t\t\t\t// ...or we're on a different line...\n\t\t\t\t\ttop !== prevCharTop ||\n\t\t\t\t\t// ...or we're at the start of the text and haven't created a span yet...\n\t\t\t\t\t!currentSpan\n\t\t\t\t) {\n\t\t\t\t\t// ...then we're at a span boundary!\n\n\t\t\t\t\tif (currentSpan) {\n\t\t\t\t\t\t// if we're truncating to a single line & we just finished the first line, stop there\n\t\t\t\t\t\tif (shouldTruncateToFirstLine && top !== prevCharTop) {\n\t\t\t\t\t\t\tdidTruncate = true\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// otherwise add the span to the list ready to start a new one\n\t\t\t\t\t\tspans.push(currentSpan)\n\t\t\t\t\t}\n\n\t\t\t\t\t// start a new span\n\t\t\t\t\tcurrentSpan = {\n\t\t\t\t\t\tbox: { x: left, y: top, w: rect.width, h: rect.height },\n\t\t\t\t\t\ttext: segment,\n\t\t\t\t\t}\n\t\t\t\t\tprevCharLeftForRTLTest = left\n\t\t\t\t} else {\n\t\t\t\t\t// Looks like we're in RTL mode, so we need to adjust the left position.\n\t\t\t\t\tif (isRTL) {\n\t\t\t\t\t\tcurrentSpan.box.x = left\n\t\t\t\t\t}\n\n\t\t\t\t\t// otherwise we just need to extend the current span with the next character\n\t\t\t\t\tcurrentSpan.box.w = isRTL ? currentSpan.box.w + rect.width : right - currentSpan.box.x\n\t\t\t\t\tcurrentSpan.text += segment\n\t\t\t\t}\n\n\t\t\t\tif (segment === '\\n') {\n\t\t\t\t\tprevCharLeftForRTLTest = 0\n\t\t\t\t}\n\n\t\t\t\tprevCharWasSpaceCharacter = isSpaceCharacter\n\t\t\t\tprevCharTop = top\n\t\t\t\tidx += segment.length\n\t\t\t}\n\t\t}\n\n\t\t// Add the last span\n\t\tif (currentSpan) {\n\t\t\tspans.push(currentSpan)\n\t\t}\n\n\t\treturn { spans, didTruncate }\n\t}\n\n\t/**\n\t * Measure text into individual spans. Spans are created by rendering the\n\t * text, then dividing it up according to line breaks and word boundaries.\n\t *\n\t * It works by having the browser render the text, then measuring the\n\t * position of each character. You can use this to replicate the text-layout\n\t * algorithm of the current browser in e.g. an SVG export.\n\t */\n\tmeasureTextSpans(\n\t\ttextToMeasure: string,\n\t\topts: TLMeasureTextSpanOpts\n\t): { text: string; box: BoxModel }[] {\n\t\tif (textToMeasure === '') return []\n\n\t\tconst { elm } = this\n\n\t\tconst shouldTruncateToFirstLine =\n\t\t\topts.overflow === 'truncate-ellipsis' || opts.overflow === 'truncate-clip'\n\t\tconst elementWidth = Math.ceil(opts.width - opts.padding * 2)\n\t\tconst newStyles = {\n\t\t\t'font-family': opts.fontFamily,\n\t\t\t'font-style': opts.fontStyle,\n\t\t\t'font-weight': opts.fontWeight,\n\t\t\t'font-size': opts.fontSize + 'px',\n\t\t\t'line-height': `${resolveLineHeightPx(opts.fontSize, opts.lineHeight)}px`,\n\t\t\twidth: `${elementWidth}px`,\n\t\t\theight: 'min-content',\n\t\t\t'text-align': textAlignmentsForLtr[opts.textAlign],\n\t\t\t'overflow-wrap': shouldTruncateToFirstLine ? 'anywhere' : 'break-word',\n\t\t\t'word-break': shouldTruncateToFirstLine ? 'break-all' : 'normal',\n\t\t\t...opts.otherStyles,\n\t\t}\n\t\tconst restoreStyles = this.setElementStyles(elm, newStyles)\n\n\t\ttry {\n\t\t\tconst normalizedText = normalizeTextForDom(textToMeasure)\n\n\t\t\t// Render the text into the measurement element:\n\t\t\telm.textContent = normalizedText\n\n\t\t\t// actually measure the text:\n\t\t\tconst { spans, didTruncate } = this.measureElementTextNodeSpans(elm, {\n\t\t\t\tshouldTruncateToFirstLine,\n\t\t\t})\n\n\t\t\tif (opts.overflow === 'truncate-ellipsis' && didTruncate) {\n\t\t\t\t// we need to measure the ellipsis to know how much space it takes up\n\t\t\t\telm.textContent = '\u2026'\n\t\t\t\tconst ellipsisSpan = this.measureElementTextNodeSpans(elm).spans[0]\n\t\t\t\tconst ellipsisWidth = ellipsisSpan ? Math.ceil(ellipsisSpan.box.w) : 0\n\n\t\t\t\t// then, we need to subtract that space from the width we have and measure again:\n\t\t\t\telm.style.setProperty('width', `${elementWidth - ellipsisWidth}px`)\n\t\t\t\telm.textContent = normalizedText\n\t\t\t\tconst truncatedSpans = this.measureElementTextNodeSpans(elm, {\n\t\t\t\t\tshouldTruncateToFirstLine: true,\n\t\t\t\t}).spans\n\n\t\t\t\t// Finally, we add in our ellipsis at the end of the last span. We\n\t\t\t\t// have to do this after measuring, not before, because adding the\n\t\t\t\t// ellipsis changes how whitespace might be getting collapsed by the\n\t\t\t\t// browser.\n\t\t\t\tconst lastSpan = truncatedSpans[truncatedSpans.length - 1]\n\t\t\t\t// If nothing measurable remained, return the (possibly empty)\n\t\t\t\t// spans as-is rather than dereferencing a missing last span.\n\t\t\t\tif (!lastSpan) {\n\t\t\t\t\treturn truncatedSpans\n\t\t\t\t}\n\t\t\t\ttruncatedSpans.push({\n\t\t\t\t\ttext: '\u2026',\n\t\t\t\t\tbox: {\n\t\t\t\t\t\tx: Math.min(lastSpan.box.x + lastSpan.box.w, opts.width - opts.padding - ellipsisWidth),\n\t\t\t\t\t\ty: lastSpan.box.y,\n\t\t\t\t\t\tw: ellipsisWidth,\n\t\t\t\t\t\th: lastSpan.box.h,\n\t\t\t\t\t},\n\t\t\t\t})\n\n\t\t\t\treturn truncatedSpans\n\t\t\t}\n\n\t\t\treturn spans\n\t\t} finally {\n\t\t\trestoreStyles()\n\t\t}\n\t}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/hooks/useViewportHeight.ts"],
4
- "sourcesContent": ["import { useLayoutEffect, useState } from 'react'\nimport { useMaybeEditor } from './useEditor'\n\n/*!\n * BSD License: https://github.com/outline/rich-markdown-editor/blob/main/LICENSE\n * Copyright (c) 2020 General Outline, Inc (https://www.getoutline.com/) and individual contributors.\n *\n * Returns the height of the viewport.\n * This is mainly to account for virtual keyboards on mobile devices.\n *\n * N.B. On iOS, you have to take into account the offsetTop as well so that you get an accurate position\n * while using the virtual keyboard.\n */\n/** @public */\nexport function useViewportHeight(): number {\n\tconst editor = useMaybeEditor()\n\tconst win = editor?.getContainerWindow() ?? window\n\tconst vv = win.visualViewport\n\tconst [height, setHeight] = useState<number>(() =>\n\t\tvv ? vv.height + vv.offsetTop : win.innerHeight\n\t)\n\n\tuseLayoutEffect(() => {\n\t\tconst win = editor?.getContainerWindow() ?? window\n\t\tconst handleResize = () => {\n\t\t\tconst vv = win.visualViewport\n\t\t\tsetHeight(() => (vv ? vv.height + vv.offsetTop : win.innerHeight))\n\t\t}\n\n\t\twin.visualViewport?.addEventListener('resize', handleResize)\n\t\twin.visualViewport?.addEventListener('scroll', handleResize)\n\n\t\treturn () => {\n\t\t\twin.visualViewport?.removeEventListener('resize', handleResize)\n\t\t\twin.visualViewport?.removeEventListener('scroll', handleResize)\n\t\t}\n\t}, [editor])\n\treturn height\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA0C;AAC1C,uBAA+B;AAE/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWO,SAAS,oBAA4B;AAC3C,QAAM,aAAS,iCAAe;AAC9B,QAAM,MAAM,QAAQ,mBAAmB,KAAK;AAC5C,QAAM,KAAK,IAAI;AACf,QAAM,CAAC,QAAQ,SAAS,QAAI;AAAA,IAAiB,MAC5C,KAAK,GAAG,SAAS,GAAG,YAAY,IAAI;AAAA,EACrC;AAEA,oCAAgB,MAAM;AACrB,UAAMA,OAAM,QAAQ,mBAAmB,KAAK;AAC5C,UAAM,eAAe,MAAM;AAC1B,YAAMC,MAAKD,KAAI;AACf,gBAAU,MAAOC,MAAKA,IAAG,SAASA,IAAG,YAAYD,KAAI,WAAY;AAAA,IAClE;AAEA,IAAAA,KAAI,gBAAgB,iBAAiB,UAAU,YAAY;AAC3D,IAAAA,KAAI,gBAAgB,iBAAiB,UAAU,YAAY;AAE3D,WAAO,MAAM;AACZ,MAAAA,KAAI,gBAAgB,oBAAoB,UAAU,YAAY;AAC9D,MAAAA,KAAI,gBAAgB,oBAAoB,UAAU,YAAY;AAAA,IAC/D;AAAA,EACD,GAAG,CAAC,MAAM,CAAC;AACX,SAAO;AACR;",
4
+ "sourcesContent": ["import { useLayoutEffect, useState } from 'react'\nimport { useMaybeEditor } from './useEditor'\n\n/*!\n * BSD License: https://github.com/outline/rich-markdown-editor/blob/main/LICENSE\n * Copyright (c) 2020 General Outline, Inc (https://www.getoutline.com/) and individual contributors.\n *\n * Returns the height of the viewport.\n * This is mainly to account for virtual keyboards on mobile devices.\n *\n * N.B. On iOS, you have to take into account the offsetTop as well so that you get an accurate position\n * while using the virtual keyboard.\n */\n/**\n * The height of the visible viewport, including the visual viewport's own offset.\n *\n * @deprecated Read `window.visualViewport` directly: this flattens the visible rectangle to a\n * single scalar, and keeping UI clear of the software keyboard usually needs the other edges too.\n * Unused since v3.14; will be removed in a future release.\n *\n * @public\n */\nexport function useViewportHeight(): number {\n\tconst editor = useMaybeEditor()\n\tconst win = editor?.getContainerWindow() ?? window\n\tconst vv = win.visualViewport\n\tconst [height, setHeight] = useState<number>(() =>\n\t\tvv ? vv.height + vv.offsetTop : win.innerHeight\n\t)\n\n\tuseLayoutEffect(() => {\n\t\tconst win = editor?.getContainerWindow() ?? window\n\t\tconst handleResize = () => {\n\t\t\tconst vv = win.visualViewport\n\t\t\tsetHeight(() => (vv ? vv.height + vv.offsetTop : win.innerHeight))\n\t\t}\n\n\t\twin.visualViewport?.addEventListener('resize', handleResize)\n\t\twin.visualViewport?.addEventListener('scroll', handleResize)\n\n\t\treturn () => {\n\t\t\twin.visualViewport?.removeEventListener('resize', handleResize)\n\t\t\twin.visualViewport?.removeEventListener('scroll', handleResize)\n\t\t}\n\t}, [editor])\n\treturn height\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA0C;AAC1C,uBAA+B;AAE/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmBO,SAAS,oBAA4B;AAC3C,QAAM,aAAS,iCAAe;AAC9B,QAAM,MAAM,QAAQ,mBAAmB,KAAK;AAC5C,QAAM,KAAK,IAAI;AACf,QAAM,CAAC,QAAQ,SAAS,QAAI;AAAA,IAAiB,MAC5C,KAAK,GAAG,SAAS,GAAG,YAAY,IAAI;AAAA,EACrC;AAEA,oCAAgB,MAAM;AACrB,UAAMA,OAAM,QAAQ,mBAAmB,KAAK;AAC5C,UAAM,eAAe,MAAM;AAC1B,YAAMC,MAAKD,KAAI;AACf,gBAAU,MAAOC,MAAKA,IAAG,SAASA,IAAG,YAAYD,KAAI,WAAY;AAAA,IAClE;AAEA,IAAAA,KAAI,gBAAgB,iBAAiB,UAAU,YAAY;AAC3D,IAAAA,KAAI,gBAAgB,iBAAiB,UAAU,YAAY;AAE3D,WAAO,MAAM;AACZ,MAAAA,KAAI,gBAAgB,oBAAoB,UAAU,YAAY;AAC9D,MAAAA,KAAI,gBAAgB,oBAAoB,UAAU,YAAY;AAAA,IAC/D;AAAA,EACD,GAAG,CAAC,MAAM,CAAC;AACX,SAAO;AACR;",
6
6
  "names": ["win", "vv"]
7
7
  }
@@ -22,10 +22,10 @@ __export(version_exports, {
22
22
  version: () => version
23
23
  });
24
24
  module.exports = __toCommonJS(version_exports);
25
- const version = "5.3.0";
25
+ const version = "5.4.0-next.ef99ab47e5ce";
26
26
  const publishDates = {
27
27
  major: "2026-05-06T16:28:18.473Z",
28
- minor: "2026-08-05T11:39:54.978Z",
29
- patch: "2026-08-05T11:39:54.978Z"
28
+ minor: "2026-08-05T11:52:36.664Z",
29
+ patch: "2026-08-05T11:52:36.664Z"
30
30
  };
31
31
  //# sourceMappingURL=version.js.map
@@ -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 = '5.3.0'\nexport const publishDates = {\n\tmajor: '2026-05-06T16:28:18.473Z',\n\tminor: '2026-08-05T11:39:54.978Z',\n\tpatch: '2026-08-05T11:39:54.978Z',\n}\n"],
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 = '5.4.0-next.ef99ab47e5ce'\nexport const publishDates = {\n\tmajor: '2026-05-06T16:28:18.473Z',\n\tminor: '2026-08-05T11:52:36.664Z',\n\tpatch: '2026-08-05T11:52:36.664Z',\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
  }
@@ -3700,7 +3700,7 @@ export declare class Editor extends EventEmitter<TLEventMap> {
3700
3700
  *
3701
3701
  * @public
3702
3702
  */
3703
- alignShapes(shapes: TLShape[] | TLShapeId[], operation: 'bottom' | 'center-horizontal' | 'center-vertical' | 'left' | 'right' | 'top'): this;
3703
+ alignShapes(shapes: TLShape[] | TLShapeId[], operation: 'bottom' | 'center-horizontal' | 'center-vertical' | 'center' | 'left' | 'right' | 'top'): this;
3704
3704
  /**
3705
3705
  * Distribute shape positions.
3706
3706
  *
@@ -4473,13 +4473,14 @@ export declare class Editor extends EventEmitter<TLEventMap> {
4473
4473
  cancelDoubleClick(): void;
4474
4474
  /* Excluded from this release type: _prevCursor */
4475
4475
  /* Excluded from this release type: _shiftKeyTimeout */
4476
- /* Excluded from this release type: _setShiftKeyTimeout */
4476
+ /* Excluded from this release type: _releaseShiftKey */
4477
4477
  /* Excluded from this release type: _altKeyTimeout */
4478
- /* Excluded from this release type: _setAltKeyTimeout */
4478
+ /* Excluded from this release type: _releaseAltKey */
4479
4479
  /* Excluded from this release type: _ctrlKeyTimeout */
4480
- /* Excluded from this release type: _setCtrlKeyTimeout */
4480
+ /* Excluded from this release type: _releaseCtrlKey */
4481
4481
  /* Excluded from this release type: _metaKeyTimeout */
4482
- /* Excluded from this release type: _setMetaKeyTimeout */
4482
+ /* Excluded from this release type: _releaseMetaKey */
4483
+ /* Excluded from this release type: _releaseDebouncedModifiers */
4483
4484
  /* Excluded from this release type: _restoreToolId */
4484
4485
  /* Excluded from this release type: _didPinch */
4485
4486
  /* Excluded from this release type: _selectedShapeIdsAtPointerDown */
@@ -10018,7 +10019,15 @@ export declare function useTransform(ref: React.RefObject<HTMLElement | null | S
10018
10019
  */
10019
10020
  export declare function useUniqueSafeId(suffix?: string): SafeId;
10020
10021
 
10021
- /** @public */
10022
+ /**
10023
+ * The height of the visible viewport, including the visual viewport's own offset.
10024
+ *
10025
+ * @deprecated Read `window.visualViewport` directly: this flattens the visible rectangle to a
10026
+ * single scalar, and keeping UI clear of the software keyboard usually needs the other edges too.
10027
+ * Unused since v3.14; will be removed in a future release.
10028
+ *
10029
+ * @public
10030
+ */
10022
10031
  export declare function useViewportHeight(): number;
10023
10032
 
10024
10033
  /* Excluded from this release type: ValidLicenseKeyResult */
@@ -305,7 +305,7 @@ import { LocalIndexedDb, Table } from "./lib/utils/sync/LocalIndexedDb.mjs";
305
305
  import { uniq } from "./lib/utils/uniq.mjs";
306
306
  registerTldrawLibraryVersion(
307
307
  "@tldraw/editor",
308
- "5.3.0",
308
+ "5.4.0-next.ef99ab47e5ce",
309
309
  "esm"
310
310
  );
311
311
  import { getColorValue } from "./lib/editor/managers/ThemeManager/defaultThemes.mjs";
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts"],
4
- "sourcesContent": ["import { registerTldrawLibraryVersion } from '@tldraw/utils'\n\n// eslint-disable-next-line tldraw/no-export-star\nexport * from '@tldraw/state'\n// eslint-disable-next-line tldraw/no-export-star\nexport * from '@tldraw/state-react'\n// eslint-disable-next-line tldraw/no-export-star\nexport * from '@tldraw/store'\n// eslint-disable-next-line tldraw/no-export-star\nexport * from '@tldraw/tlschema'\n// eslint-disable-next-line tldraw/no-export-star\nexport * from '@tldraw/utils'\n// eslint-disable-next-line tldraw/no-export-star\nexport * from '@tldraw/validate'\n\nexport { DefaultBackground } from './lib/components/default-components/DefaultBackground'\nexport {\n\tDefaultCanvas,\n\ttype TLCanvasComponentProps,\n} from './lib/components/default-components/DefaultCanvas'\nexport {\n\tDefaultCursor,\n\ttype TLCursorProps,\n} from './lib/components/default-components/DefaultCursor'\nexport {\n\tDefaultErrorFallback,\n\ttype TLErrorFallbackComponent,\n} from './lib/components/default-components/DefaultErrorFallback'\nexport { DefaultGrid, type TLGridProps } from './lib/components/default-components/DefaultGrid'\nexport { type TLShapeErrorFallbackComponent } from './lib/components/default-components/DefaultShapeErrorFallback'\nexport {\n\tDefaultShapeWrapper,\n\ttype TLShapeWrapperProps,\n} from './lib/components/default-components/DefaultShapeWrapper'\nexport { DefaultSpinner } from './lib/components/default-components/DefaultSpinner'\nexport { DefaultSvgDefs } from './lib/components/default-components/DefaultSvgDefs'\nexport {\n\tEditorPortal,\n\tuseEditorPortalHost,\n\ttype EditorPortalProps,\n} from './lib/components/EditorPortal'\nexport {\n\tErrorBoundary,\n\tOptionalErrorBoundary,\n\ttype TLErrorBoundaryProps,\n} from './lib/components/ErrorBoundary'\nexport { HTMLContainer, type HTMLContainerProps } from './lib/components/HTMLContainer'\nexport { MenuClickCapture } from './lib/components/MenuClickCapture'\nexport { SVGContainer, type SVGContainerProps } from './lib/components/SVGContainer'\nexport {\n\tcreateTLCurrentUser,\n\tuseTldrawCurrentUser,\n\ttype TLCurrentUser,\n} from './lib/config/createTLCurrentUser'\nexport {\n\tcreateTLSchemaFromUtils,\n\tcreateTLStore,\n\tdefaultUserStore,\n\tinlineBase64AssetStore,\n\ttype TLStoreBaseOptions,\n\ttype TLStoreEventInfo,\n\ttype TLStoreOptions,\n\ttype TLStoreSchemaOptions,\n} from './lib/config/createTLStore'\nexport { type TLAnyAssetUtilConstructor } from './lib/config/defaultAssets'\nexport { type TLAnyBindingUtilConstructor } from './lib/config/defaultBindings'\nexport { coreShapes, type TLAnyShapeUtilConstructor } from './lib/config/defaultShapes'\nexport {\n\tgetSnapshot,\n\tloadSnapshot,\n\ttype TLEditorSnapshot,\n\ttype TLLoadSnapshotOptions,\n} from './lib/config/TLEditorSnapshot'\nexport {\n\tcreateSessionStateSnapshotSignal,\n\textractSessionStateFromLegacySnapshot,\n\tloadSessionStateSnapshotIntoStore,\n\tTAB_ID,\n\ttype TLLoadSessionStateSnapshotOptions,\n\ttype TLSessionStateSnapshot,\n} from './lib/config/TLSessionStateSnapshot'\nexport {\n\tdefaultUserPreferences,\n\tgetFreshUserPreferences,\n\tgetUserPreferences,\n\tsetUserPreferences,\n\tUSER_COLORS,\n\tuserTypeValidator,\n\ttype TLUserPreferences,\n} from './lib/config/TLUserPreferences'\nexport { DEFAULT_ANIMATION_OPTIONS, DEFAULT_CAMERA_OPTIONS, SIDES } from './lib/constants'\nexport { AssetUtil, type TLAssetUtilConstructor } from './lib/editor/assets/AssetUtil'\nexport {\n\tBindingUtil,\n\ttype BindingOnChangeOptions,\n\ttype BindingOnCreateOptions,\n\ttype BindingOnDeleteOptions,\n\ttype BindingOnShapeChangeOptions,\n\ttype BindingOnShapeDeleteOptions,\n\ttype BindingOnShapeIsolateOptions,\n\ttype TLBindingUtilConstructor,\n} from './lib/editor/bindings/BindingUtil'\nexport {\n\tEditor,\n\ttype TLEditorOptions,\n\ttype TLEditorRunOptions,\n\ttype TLRenderingShape,\n\ttype TLResizeShapeOptions,\n} from './lib/editor/Editor'\nexport { ClickManager, type TLClickState } from './lib/editor/managers/ClickManager/ClickManager'\nexport { EdgeScrollManager } from './lib/editor/managers/EdgeScrollManager/EdgeScrollManager'\nexport { FontManager } from './lib/editor/managers/FontManager/FontManager'\nexport { HistoryManager } from './lib/editor/managers/HistoryManager/HistoryManager'\nexport { EditorManager } from './lib/editor/managers/EditorManager'\nexport { InputsManager } from './lib/editor/managers/InputsManager/InputsManager'\nexport {\n\tScribbleManager,\n\ttype ScribbleItem,\n\ttype ScribbleSessionOptions,\n} from './lib/editor/managers/ScribbleManager/ScribbleManager'\nexport {\n\tBoundsSnaps,\n\ttype BoundsSnapGeometry,\n\ttype BoundsSnapPoint,\n} from './lib/editor/managers/SnapManager/BoundsSnaps'\nexport { HandleSnaps, type HandleSnapGeometry } from './lib/editor/managers/SnapManager/HandleSnaps'\nexport {\n\tSnapManager,\n\ttype GapsSnapIndicator,\n\ttype PointsSnapIndicator,\n\ttype SnapData,\n\ttype SnapIndicator,\n} from './lib/editor/managers/SnapManager/SnapManager'\nexport { SpatialIndexManager } from './lib/editor/managers/SpatialIndexManager/SpatialIndexManager'\nexport {\n\tTextManager,\n\tresolveLineHeightPx,\n\ttype BatchMeasurementRequest,\n\ttype TLMeasuredTextSize,\n\ttype TLMeasureTextOpts,\n\ttype TLMeasureTextSpanOpts,\n} from './lib/editor/managers/TextManager/TextManager'\nexport { DEFAULT_THEME } from './lib/editor/managers/ThemeManager/defaultThemes'\nexport { ThemeManager, resolveThemes } from './lib/editor/managers/ThemeManager/ThemeManager'\nexport { TickManager } from './lib/editor/managers/TickManager/TickManager'\nexport { CollaboratorsManager } from './lib/editor/managers/CollaboratorsManager/CollaboratorsManager'\nexport { PerformanceApiAdapter } from './lib/editor/managers/PerformanceManager/PerformanceApiAdapter'\nexport { PerformanceManager } from './lib/editor/managers/PerformanceManager/PerformanceManager'\nexport {\n\ttype TLCameraEndPerfEvent,\n\ttype TLCameraStartPerfEvent,\n\ttype TLFramePerfEvent,\n\ttype TLInteractionEndPerfEvent,\n\ttype TLInteractionStartPerfEvent,\n\ttype TLPerfEventMap,\n\ttype TLPerfFrameTimeStats,\n\ttype TLPerfLongAnimationFrame,\n\ttype TLPerfLongAnimationFrameScript,\n\ttype TLShapeOperationPerfEvent,\n\ttype TLUndoRedoPerfEvent,\n} from './lib/editor/managers/PerformanceManager/perf-types'\nexport { UserPreferencesManager } from './lib/editor/managers/UserPreferencesManager/UserPreferencesManager'\nexport { BaseBoxShapeUtil, type TLBaseBoxShape } from './lib/editor/shapes/BaseBoxShapeUtil'\nexport { BaseFrameLikeShapeUtil } from './lib/editor/shapes/BaseFrameLikeShapeUtil'\nexport { GroupShapeUtil } from './lib/editor/shapes/group/GroupShapeUtil'\nexport {\n\tShapeUtil,\n\ttype TLCropInfo,\n\ttype TLDragShapesInInfo,\n\ttype TLDragShapesOutInfo,\n\ttype TLDragShapesOverInfo,\n\ttype TLDropShapesOverInfo,\n\ttype TLEditStartInfo,\n\ttype TLGeometryOpts,\n\ttype TLHandleDragInfo,\n\ttype TLIndicatorPath,\n\ttype TLResizeInfo,\n\ttype TLResizeMode,\n\ttype TLShapeUtilCanBeLaidOutOpts,\n\ttype TLShapeUtilCanBindOpts,\n\ttype TLShapeUtilCanvasSvgDef,\n\ttype TLShapeUtilConstructor,\n} from './lib/editor/shapes/ShapeUtil'\nexport {\n\tgetOverlayDisplayValues,\n\ttype OverlayOptionsWithDisplayValues,\n} from './lib/editor/overlays/getOverlayDisplayValues'\nexport { OverlayManager, type TLOverlayEntry } from './lib/editor/overlays/OverlayManager'\nexport {\n\tOverlayUtil,\n\ttype TLAnyOverlayUtilConstructor,\n\ttype TLOverlay,\n\ttype TLOverlayUtilConstructor,\n} from './lib/editor/overlays/OverlayUtil'\nexport { strokeShapeIndicators } from './lib/editor/overlays/strokeShapeIndicators'\nexport {\n\tgetPerfectDashProps,\n\ttype PerfectDashTerminal,\n} from './lib/editor/shapes/shared/getPerfectDashProps'\nexport { resizeBox, type ResizeBoxOptions } from './lib/editor/shapes/shared/resizeBox'\nexport { resizeScaled } from './lib/editor/shapes/shared/resizeScaled'\nexport { BaseBoxShapeTool } from './lib/editor/tools/BaseBoxShapeTool/BaseBoxShapeTool'\nexport { maybeSnapToGrid } from './lib/editor/tools/BaseBoxShapeTool/children/Pointing'\nexport { StateNode, type TLStateNodeConstructor } from './lib/editor/tools/StateNode'\nexport { type TLContent } from './lib/editor/types/clipboard-types'\nexport { type TLEventMap, type TLEventMapHandler } from './lib/editor/types/emit-types'\nexport {\n\tEVENT_NAME_MAP,\n\ttype TLBaseEventInfo,\n\ttype TLCancelEvent,\n\ttype TLCancelEventInfo,\n\ttype TLClickEvent,\n\ttype TLClickEventInfo,\n\ttype TLCLickEventName,\n\ttype TLCompleteEvent,\n\ttype TLCompleteEventInfo,\n\ttype TLEnterEventHandler,\n\ttype TLEventHandlers,\n\ttype TLEventInfo,\n\ttype TLEventName,\n\ttype TLExitEventHandler,\n\ttype TLInterruptEvent,\n\ttype TLInterruptEventInfo,\n\ttype TLKeyboardEvent,\n\ttype TLKeyboardEventInfo,\n\ttype TLKeyboardEventName,\n\ttype TLPinchEvent,\n\ttype TLPinchEventInfo,\n\ttype TLPinchEventName,\n\ttype TLPointerEvent,\n\ttype TLPointerEventInfo,\n\ttype TLPointerEventName,\n\ttype TLPointerEventTarget,\n\ttype TLTickEvent,\n\ttype TLTickEventInfo,\n\ttype TLWheelEvent,\n\ttype TLWheelEventInfo,\n\ttype UiEvent,\n\ttype UiEventType,\n} from './lib/editor/types/event-types'\nexport {\n\ttype TLBaseExternalContent,\n\ttype TLEmbedExternalContent,\n\ttype TLErrorExternalContentSource,\n\ttype TLExcalidrawExternalContent,\n\ttype TLExcalidrawExternalContentSource,\n\ttype TLExternalAsset,\n\ttype TLExternalContent,\n\ttype TLExternalContentSource,\n\ttype TLFileExternalAsset,\n\ttype TLFileReplaceExternalContent,\n\ttype TLFilesExternalContent,\n\ttype TLSvgTextExternalContent,\n\ttype TLTextExternalContent,\n\ttype TLTextExternalContentSource,\n\ttype TLTldrawExternalContent,\n\ttype TLTldrawExternalContentSource,\n\ttype TLUrlExternalAsset,\n\ttype TLUrlExternalContent,\n} from './lib/editor/types/external-content'\nexport {\n\ttype TLHistoryBatchOptions,\n\ttype TLHistoryDiff,\n\ttype TLHistoryEntry,\n\ttype TLHistoryMark,\n} from './lib/editor/types/history-types'\nexport {\n\ttype OptionalKeys,\n\ttype RequiredKeys,\n\ttype TLCameraConstraints,\n\ttype TLCameraMoveOptions,\n\ttype TLCameraOptions,\n\ttype TLExportType,\n\ttype TLGetShapeAtPointOptions,\n\ttype TLImageExportOptions,\n\ttype TLSvgExportOptions,\n\ttype TLUpdatePointerOptions,\n} from './lib/editor/types/misc-types'\nexport {\n\ttype TLAdjacentDirection,\n\ttype TLResizeHandle,\n\ttype TLSelectionHandle,\n} from './lib/editor/types/selection-types'\nexport {\n\tuseDelaySvgExport,\n\tuseSvgExportContext,\n\ttype SvgExportContext,\n\ttype SvgExportDef,\n} from './lib/editor/types/SvgExportContext'\nexport { getOwnerDocument, getOwnerWindow } from './lib/exports/domUtils'\nexport { getSvgAsImage } from './lib/exports/getSvgAsImage'\nexport { tlenv, tlenvReactive } from './lib/globals/environment'\nexport { tlmenus } from './lib/globals/menus'\nexport { tltime } from './lib/globals/time'\nexport {\n\tContainerProvider,\n\tuseContainer,\n\tuseContainerIfExists,\n\ttype ContainerProviderProps,\n} from './lib/hooks/useContainer'\nexport { useColorMode } from './lib/hooks/useColorMode'\nexport { getCursor } from './lib/hooks/useCursor'\nexport {\n\tEditorContext,\n\tEditorProvider,\n\tuseEditor,\n\tuseMaybeEditor,\n\ttype EditorProviderProps,\n} from './lib/hooks/useEditor'\nexport { useEditorComponents } from './lib/hooks/useEditorComponents'\nexport type { TLEditorComponents } from './lib/hooks/useEditorComponents'\nexport { useEvent, useReactiveEvent } from './lib/hooks/useEvent'\nexport { useGlobalMenuIsOpen } from './lib/hooks/useGlobalMenuIsOpen'\nexport { useShallowArrayIdentity, useShallowObjectIdentity } from './lib/hooks/useIdentity'\nexport { useIsCropping } from './lib/hooks/useIsCropping'\nexport { useIsEditing } from './lib/hooks/useIsEditing'\nexport { useLocalStore } from './lib/hooks/useLocalStore'\nexport { usePassThroughWheelEvents } from './lib/hooks/usePassThroughWheelEvents'\nexport { usePeerIds } from './lib/hooks/usePeerIds'\nexport { usePresence } from './lib/hooks/usePresence'\nexport { useRefState } from './lib/hooks/useRefState'\nexport {\n\tsanitizeId,\n\tsuffixSafeId,\n\tuseSharedSafeId,\n\tuseUniqueSafeId,\n\ttype SafeId,\n} from './lib/hooks/useSafeId'\nexport { useTransform } from './lib/hooks/useTransform'\nexport { isCursorInViewport } from './lib/utils/collaborators'\nexport { useTLSchemaFromUtils, useTLStore } from './lib/hooks/useTLStore'\nexport { useViewportHeight } from './lib/hooks/useViewportHeight'\nexport {\n\tLicenseManager,\n\ttype InvalidLicenseKeyResult,\n\ttype InvalidLicenseReason,\n\ttype LicenseFeatureName,\n\ttype LicenseFromKeyResult,\n\ttype LicenseInfo,\n\ttype LicenseState,\n\ttype ValidLicenseKeyResult,\n} from './lib/license/LicenseManager'\nexport { LICENSE_TIMEOUT, useLicenseContext } from './lib/license/LicenseProvider'\nexport { useLicenseFeatureFlag } from './lib/license/useLicenseManagerState'\nexport {\n\tdefaultTldrawOptions,\n\ttype TLClipboardPasteRawInfo,\n\ttype TLClipboardWriteInfo,\n\ttype TldrawOptions,\n} from './lib/options'\nexport {\n\tBox,\n\tROTATE_CORNER_TO_SELECTION_CORNER,\n\trotateSelectionHandle,\n\ttype BoxLike,\n\ttype RotateCorner,\n\ttype SelectionCorner,\n\ttype SelectionEdge,\n\ttype SelectionHandle,\n} from './lib/primitives/Box'\nexport { EASINGS } from './lib/primitives/easings'\nexport { Arc2d } from './lib/primitives/geometry/Arc2d'\nexport { Circle2d } from './lib/primitives/geometry/Circle2d'\nexport { CubicBezier2d } from './lib/primitives/geometry/CubicBezier2d'\nexport { CubicSpline2d } from './lib/primitives/geometry/CubicSpline2d'\nexport { Edge2d } from './lib/primitives/geometry/Edge2d'\nexport { Ellipse2d } from './lib/primitives/geometry/Ellipse2d'\nexport { getVerticesCountForArcLength } from './lib/primitives/geometry/geometry-constants'\nexport {\n\tGeometry2d,\n\tGeometry2dFilters,\n\tTransformedGeometry2d,\n\ttype Geometry2dOptions,\n\ttype TransformedGeometry2dOptions,\n} from './lib/primitives/geometry/Geometry2d'\nexport { Group2d } from './lib/primitives/geometry/Group2d'\nexport { Point2d } from './lib/primitives/geometry/Point2d'\nexport { Polygon2d } from './lib/primitives/geometry/Polygon2d'\nexport { Polyline2d } from './lib/primitives/geometry/Polyline2d'\nexport { Rectangle2d } from './lib/primitives/geometry/Rectangle2d'\nexport { Stadium2d } from './lib/primitives/geometry/Stadium2d'\nexport {\n\tintersectCircleCircle,\n\tintersectCirclePolygon,\n\tintersectCirclePolyline,\n\tintersectLineSegmentCircle,\n\tintersectLineSegmentLineSegment,\n\tintersectLineSegmentPolygon,\n\tintersectLineSegmentPolyline,\n\tintersectPolygonBounds,\n\tintersectPolygonPolygon,\n\tlinesIntersect,\n\tpolygonIntersectsPolyline,\n\tpolygonsIntersect,\n} from './lib/primitives/intersect'\nexport { Mat, type MatLike, type MatModel } from './lib/primitives/Mat'\nexport {\n\tangleDistance,\n\tapproximately,\n\tareAnglesCompatible,\n\taverage,\n\tcanonicalizeRotation,\n\tcenterOfCircleFromThreePoints,\n\tclamp,\n\tclampRadians,\n\tclockwiseAngleDist,\n\tcounterClockwiseAngleDist,\n\tdegreesToRadians,\n\tgetArcMeasure,\n\tgetPointInArcT,\n\tgetPointOnCircle,\n\tgetPointsOnArc,\n\tgetPolygonVertices,\n\tHALF_PI,\n\tisSafeFloat,\n\tperimeterOfEllipse,\n\tPI,\n\tPI2,\n\tpointInPolygon,\n\tprecise,\n\tradiansToDegrees,\n\trangeIntersection,\n\tshortAngleDist,\n\tSIN,\n\tsnapAngle,\n\ttoDomPrecision,\n\ttoFixed,\n\ttoPrecision,\n} from './lib/primitives/utils'\nexport { Vec, type VecLike } from './lib/primitives/Vec'\nexport {\n\tErrorScreen,\n\tLoadingScreen,\n\tTldrawEditor,\n\tuseOnMount,\n\ttype LoadingScreenProps,\n\ttype TldrawEditorBaseProps,\n\ttype TldrawEditorProps,\n\ttype TldrawEditorStoreProps,\n\ttype TldrawEditorWithoutStoreProps,\n\ttype TldrawEditorWithStoreProps,\n\ttype TLOnMountHandler,\n} from './lib/TldrawEditor'\nexport { dataUrlToFile, getDefaultCdnBaseUrl } from './lib/utils/assets'\nexport { clampToBrowserMaxCanvasSize, type CanvasMaxSize } from './lib/utils/browserCanvasMaxSize'\nexport {\n\tcreateDebugValue,\n\tdebugFlags,\n\tfeatureFlags,\n\ttype DebugFlag,\n\ttype DebugFlagDef,\n\ttype DebugFlagDefaults,\n} from './lib/utils/debug-flags'\nexport {\n\tcreateDeepLinkString,\n\tparseDeepLinkString,\n\ttype TLDeepLink,\n\ttype TLDeepLinkOptions,\n} from './lib/utils/deepLinks'\nexport {\n\tactiveElementShouldCaptureKeys,\n\telementShouldCaptureKeys,\n\tgetGlobalDocument,\n\tgetGlobalWindow,\n\tloopToHtmlElement,\n\tmoveElementInto,\n\tpreventDefault,\n\treleasePointerCapture,\n\tsetPointerCapture,\n\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\tstopEventPropagation,\n} from './lib/utils/dom'\nexport { EditorAtom } from './lib/utils/EditorAtom'\nexport { getIncrementedName } from './lib/utils/getIncrementedName'\nexport { getPointerInfo } from './lib/utils/getPointerInfo'\nexport { getSvgPathFromPoints } from './lib/utils/getSvgPathFromPoints'\nexport { isAccelKey } from './lib/utils/keyboard'\nexport { normalizeWheel } from './lib/utils/normalizeWheel'\nexport { getDroppedShapesToNewParents, kickoutOccludedShapes } from './lib/utils/reparenting'\nexport {\n\tgetFontsFromRichText,\n\ttype RichTextFontVisitor,\n\ttype RichTextFontVisitorState,\n\ttype TiptapEditor,\n\ttype TiptapNode,\n\ttype TLTextOptions,\n} from './lib/utils/richText'\nexport {\n\tapplyRotationToSnapshotShapes,\n\tgetRotationSnapshot,\n\ttype TLRotationSnapshot,\n} from './lib/utils/rotation'\nexport {\n\thardResetEditor,\n\topenWindow,\n\trefreshPage,\n\truntime,\n\tsetRuntimeOverrides,\n} from './lib/utils/runtime'\nexport {\n\tReadonlySharedStyleMap,\n\tSharedStyleMap,\n\ttype SharedStyle,\n} from './lib/utils/SharedStylesMap'\nexport { hardReset } from './lib/utils/sync/hardReset'\nexport { LocalIndexedDb, Table, type StoreName } from './lib/utils/sync/LocalIndexedDb'\nexport { type TLStoreWithStatus } from './lib/utils/sync/StoreWithStatus'\nexport { uniq } from './lib/utils/uniq'\n\nregisterTldrawLibraryVersion(\n\t(globalThis as any).TLDRAW_LIBRARY_NAME,\n\t(globalThis as any).TLDRAW_LIBRARY_VERSION,\n\t(globalThis as any).TLDRAW_LIBRARY_MODULES\n)\n\nexport { getColorValue } from './lib/editor/managers/ThemeManager/defaultThemes'\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { registerTldrawLibraryVersion } from '@tldraw/utils'\n\n// eslint-disable-next-line tldraw/no-export-star\nexport * from '@tldraw/state'\n// eslint-disable-next-line tldraw/no-export-star\nexport * from '@tldraw/state-react'\n// eslint-disable-next-line tldraw/no-export-star\nexport * from '@tldraw/store'\n// eslint-disable-next-line tldraw/no-export-star\nexport * from '@tldraw/tlschema'\n// eslint-disable-next-line tldraw/no-export-star\nexport * from '@tldraw/utils'\n// eslint-disable-next-line tldraw/no-export-star\nexport * from '@tldraw/validate'\n\nexport { DefaultBackground } from './lib/components/default-components/DefaultBackground'\nexport {\n\tDefaultCanvas,\n\ttype TLCanvasComponentProps,\n} from './lib/components/default-components/DefaultCanvas'\nexport {\n\tDefaultCursor,\n\ttype TLCursorProps,\n} from './lib/components/default-components/DefaultCursor'\nexport {\n\tDefaultErrorFallback,\n\ttype TLErrorFallbackComponent,\n} from './lib/components/default-components/DefaultErrorFallback'\nexport { DefaultGrid, type TLGridProps } from './lib/components/default-components/DefaultGrid'\nexport { type TLShapeErrorFallbackComponent } from './lib/components/default-components/DefaultShapeErrorFallback'\nexport {\n\tDefaultShapeWrapper,\n\ttype TLShapeWrapperProps,\n} from './lib/components/default-components/DefaultShapeWrapper'\nexport { DefaultSpinner } from './lib/components/default-components/DefaultSpinner'\nexport { DefaultSvgDefs } from './lib/components/default-components/DefaultSvgDefs'\nexport {\n\tEditorPortal,\n\tuseEditorPortalHost,\n\ttype EditorPortalProps,\n} from './lib/components/EditorPortal'\nexport {\n\tErrorBoundary,\n\tOptionalErrorBoundary,\n\ttype TLErrorBoundaryProps,\n} from './lib/components/ErrorBoundary'\nexport { HTMLContainer, type HTMLContainerProps } from './lib/components/HTMLContainer'\nexport { MenuClickCapture } from './lib/components/MenuClickCapture'\nexport { SVGContainer, type SVGContainerProps } from './lib/components/SVGContainer'\nexport {\n\tcreateTLCurrentUser,\n\tuseTldrawCurrentUser,\n\ttype TLCurrentUser,\n} from './lib/config/createTLCurrentUser'\nexport {\n\tcreateTLSchemaFromUtils,\n\tcreateTLStore,\n\tdefaultUserStore,\n\tinlineBase64AssetStore,\n\ttype TLStoreBaseOptions,\n\ttype TLStoreEventInfo,\n\ttype TLStoreOptions,\n\ttype TLStoreSchemaOptions,\n} from './lib/config/createTLStore'\nexport { type TLAnyAssetUtilConstructor } from './lib/config/defaultAssets'\nexport { type TLAnyBindingUtilConstructor } from './lib/config/defaultBindings'\nexport { coreShapes, type TLAnyShapeUtilConstructor } from './lib/config/defaultShapes'\nexport {\n\tgetSnapshot,\n\tloadSnapshot,\n\ttype TLEditorSnapshot,\n\ttype TLLoadSnapshotOptions,\n} from './lib/config/TLEditorSnapshot'\nexport {\n\tcreateSessionStateSnapshotSignal,\n\textractSessionStateFromLegacySnapshot,\n\tloadSessionStateSnapshotIntoStore,\n\tTAB_ID,\n\ttype TLLoadSessionStateSnapshotOptions,\n\ttype TLSessionStateSnapshot,\n} from './lib/config/TLSessionStateSnapshot'\nexport {\n\tdefaultUserPreferences,\n\tgetFreshUserPreferences,\n\tgetUserPreferences,\n\tsetUserPreferences,\n\tUSER_COLORS,\n\tuserTypeValidator,\n\ttype TLUserPreferences,\n} from './lib/config/TLUserPreferences'\nexport { DEFAULT_ANIMATION_OPTIONS, DEFAULT_CAMERA_OPTIONS, SIDES } from './lib/constants'\nexport { AssetUtil, type TLAssetUtilConstructor } from './lib/editor/assets/AssetUtil'\nexport {\n\tBindingUtil,\n\ttype BindingOnChangeOptions,\n\ttype BindingOnCreateOptions,\n\ttype BindingOnDeleteOptions,\n\ttype BindingOnShapeChangeOptions,\n\ttype BindingOnShapeDeleteOptions,\n\ttype BindingOnShapeIsolateOptions,\n\ttype TLBindingUtilConstructor,\n} from './lib/editor/bindings/BindingUtil'\nexport {\n\tEditor,\n\ttype TLEditorOptions,\n\ttype TLEditorRunOptions,\n\ttype TLRenderingShape,\n\ttype TLResizeShapeOptions,\n} from './lib/editor/Editor'\nexport { ClickManager, type TLClickState } from './lib/editor/managers/ClickManager/ClickManager'\nexport { EdgeScrollManager } from './lib/editor/managers/EdgeScrollManager/EdgeScrollManager'\nexport { FontManager } from './lib/editor/managers/FontManager/FontManager'\nexport { HistoryManager } from './lib/editor/managers/HistoryManager/HistoryManager'\nexport { EditorManager } from './lib/editor/managers/EditorManager'\nexport { InputsManager } from './lib/editor/managers/InputsManager/InputsManager'\nexport {\n\tScribbleManager,\n\ttype ScribbleItem,\n\ttype ScribbleSessionOptions,\n} from './lib/editor/managers/ScribbleManager/ScribbleManager'\nexport {\n\tBoundsSnaps,\n\ttype BoundsSnapGeometry,\n\ttype BoundsSnapPoint,\n} from './lib/editor/managers/SnapManager/BoundsSnaps'\nexport { HandleSnaps, type HandleSnapGeometry } from './lib/editor/managers/SnapManager/HandleSnaps'\nexport {\n\tSnapManager,\n\ttype GapsSnapIndicator,\n\ttype PointsSnapIndicator,\n\ttype SnapData,\n\ttype SnapIndicator,\n} from './lib/editor/managers/SnapManager/SnapManager'\nexport { SpatialIndexManager } from './lib/editor/managers/SpatialIndexManager/SpatialIndexManager'\nexport {\n\tTextManager,\n\tresolveLineHeightPx,\n\ttype BatchMeasurementRequest,\n\ttype TLMeasuredTextSize,\n\ttype TLMeasureTextOpts,\n\ttype TLMeasureTextSpanOpts,\n} from './lib/editor/managers/TextManager/TextManager'\nexport { DEFAULT_THEME } from './lib/editor/managers/ThemeManager/defaultThemes'\nexport { ThemeManager, resolveThemes } from './lib/editor/managers/ThemeManager/ThemeManager'\nexport { TickManager } from './lib/editor/managers/TickManager/TickManager'\nexport { CollaboratorsManager } from './lib/editor/managers/CollaboratorsManager/CollaboratorsManager'\nexport { PerformanceApiAdapter } from './lib/editor/managers/PerformanceManager/PerformanceApiAdapter'\nexport { PerformanceManager } from './lib/editor/managers/PerformanceManager/PerformanceManager'\nexport {\n\ttype TLCameraEndPerfEvent,\n\ttype TLCameraStartPerfEvent,\n\ttype TLFramePerfEvent,\n\ttype TLInteractionEndPerfEvent,\n\ttype TLInteractionStartPerfEvent,\n\ttype TLPerfEventMap,\n\ttype TLPerfFrameTimeStats,\n\ttype TLPerfLongAnimationFrame,\n\ttype TLPerfLongAnimationFrameScript,\n\ttype TLShapeOperationPerfEvent,\n\ttype TLUndoRedoPerfEvent,\n} from './lib/editor/managers/PerformanceManager/perf-types'\nexport { UserPreferencesManager } from './lib/editor/managers/UserPreferencesManager/UserPreferencesManager'\nexport { BaseBoxShapeUtil, type TLBaseBoxShape } from './lib/editor/shapes/BaseBoxShapeUtil'\nexport { BaseFrameLikeShapeUtil } from './lib/editor/shapes/BaseFrameLikeShapeUtil'\nexport { GroupShapeUtil } from './lib/editor/shapes/group/GroupShapeUtil'\nexport {\n\tShapeUtil,\n\ttype TLCropInfo,\n\ttype TLDragShapesInInfo,\n\ttype TLDragShapesOutInfo,\n\ttype TLDragShapesOverInfo,\n\ttype TLDropShapesOverInfo,\n\ttype TLEditStartInfo,\n\ttype TLGeometryOpts,\n\ttype TLHandleDragInfo,\n\ttype TLIndicatorPath,\n\ttype TLResizeInfo,\n\ttype TLResizeMode,\n\ttype TLShapeUtilCanBeLaidOutOpts,\n\ttype TLShapeUtilCanBindOpts,\n\ttype TLShapeUtilCanvasSvgDef,\n\ttype TLShapeUtilConstructor,\n} from './lib/editor/shapes/ShapeUtil'\nexport {\n\tgetOverlayDisplayValues,\n\ttype OverlayOptionsWithDisplayValues,\n} from './lib/editor/overlays/getOverlayDisplayValues'\nexport { OverlayManager, type TLOverlayEntry } from './lib/editor/overlays/OverlayManager'\nexport {\n\tOverlayUtil,\n\ttype TLAnyOverlayUtilConstructor,\n\ttype TLOverlay,\n\ttype TLOverlayUtilConstructor,\n} from './lib/editor/overlays/OverlayUtil'\nexport { strokeShapeIndicators } from './lib/editor/overlays/strokeShapeIndicators'\nexport {\n\tgetPerfectDashProps,\n\ttype PerfectDashTerminal,\n} from './lib/editor/shapes/shared/getPerfectDashProps'\nexport { resizeBox, type ResizeBoxOptions } from './lib/editor/shapes/shared/resizeBox'\nexport { resizeScaled } from './lib/editor/shapes/shared/resizeScaled'\nexport { BaseBoxShapeTool } from './lib/editor/tools/BaseBoxShapeTool/BaseBoxShapeTool'\nexport { maybeSnapToGrid } from './lib/editor/tools/BaseBoxShapeTool/children/Pointing'\nexport { StateNode, type TLStateNodeConstructor } from './lib/editor/tools/StateNode'\nexport { type TLContent } from './lib/editor/types/clipboard-types'\nexport { type TLEventMap, type TLEventMapHandler } from './lib/editor/types/emit-types'\nexport {\n\tEVENT_NAME_MAP,\n\ttype TLBaseEventInfo,\n\ttype TLCancelEvent,\n\ttype TLCancelEventInfo,\n\ttype TLClickEvent,\n\ttype TLClickEventInfo,\n\ttype TLCLickEventName,\n\ttype TLCompleteEvent,\n\ttype TLCompleteEventInfo,\n\ttype TLEnterEventHandler,\n\ttype TLEventHandlers,\n\ttype TLEventInfo,\n\ttype TLEventName,\n\ttype TLExitEventHandler,\n\ttype TLInterruptEvent,\n\ttype TLInterruptEventInfo,\n\ttype TLKeyboardEvent,\n\ttype TLKeyboardEventInfo,\n\ttype TLKeyboardEventName,\n\ttype TLPinchEvent,\n\ttype TLPinchEventInfo,\n\ttype TLPinchEventName,\n\ttype TLPointerEvent,\n\ttype TLPointerEventInfo,\n\ttype TLPointerEventName,\n\ttype TLPointerEventTarget,\n\ttype TLTickEvent,\n\ttype TLTickEventInfo,\n\ttype TLWheelEvent,\n\ttype TLWheelEventInfo,\n\ttype UiEvent,\n\ttype UiEventType,\n} from './lib/editor/types/event-types'\nexport {\n\ttype TLBaseExternalContent,\n\ttype TLEmbedExternalContent,\n\ttype TLErrorExternalContentSource,\n\ttype TLExcalidrawExternalContent,\n\ttype TLExcalidrawExternalContentSource,\n\ttype TLExternalAsset,\n\ttype TLExternalContent,\n\ttype TLExternalContentSource,\n\ttype TLFileExternalAsset,\n\ttype TLFileReplaceExternalContent,\n\ttype TLFilesExternalContent,\n\ttype TLSvgTextExternalContent,\n\ttype TLTextExternalContent,\n\ttype TLTextExternalContentSource,\n\ttype TLTldrawExternalContent,\n\ttype TLTldrawExternalContentSource,\n\ttype TLUrlExternalAsset,\n\ttype TLUrlExternalContent,\n} from './lib/editor/types/external-content'\nexport {\n\ttype TLHistoryBatchOptions,\n\ttype TLHistoryDiff,\n\ttype TLHistoryEntry,\n\ttype TLHistoryMark,\n} from './lib/editor/types/history-types'\nexport {\n\ttype OptionalKeys,\n\ttype RequiredKeys,\n\ttype TLCameraConstraints,\n\ttype TLCameraMoveOptions,\n\ttype TLCameraOptions,\n\ttype TLExportType,\n\ttype TLGetShapeAtPointOptions,\n\ttype TLImageExportOptions,\n\ttype TLSvgExportOptions,\n\ttype TLUpdatePointerOptions,\n} from './lib/editor/types/misc-types'\nexport {\n\ttype TLAdjacentDirection,\n\ttype TLResizeHandle,\n\ttype TLSelectionHandle,\n} from './lib/editor/types/selection-types'\nexport {\n\tuseDelaySvgExport,\n\tuseSvgExportContext,\n\ttype SvgExportContext,\n\ttype SvgExportDef,\n} from './lib/editor/types/SvgExportContext'\nexport { getOwnerDocument, getOwnerWindow } from './lib/exports/domUtils'\nexport { getSvgAsImage } from './lib/exports/getSvgAsImage'\nexport { tlenv, tlenvReactive } from './lib/globals/environment'\nexport { tlmenus } from './lib/globals/menus'\nexport { tltime } from './lib/globals/time'\nexport {\n\tContainerProvider,\n\tuseContainer,\n\tuseContainerIfExists,\n\ttype ContainerProviderProps,\n} from './lib/hooks/useContainer'\nexport { useColorMode } from './lib/hooks/useColorMode'\nexport { getCursor } from './lib/hooks/useCursor'\nexport {\n\tEditorContext,\n\tEditorProvider,\n\tuseEditor,\n\tuseMaybeEditor,\n\ttype EditorProviderProps,\n} from './lib/hooks/useEditor'\nexport { useEditorComponents } from './lib/hooks/useEditorComponents'\nexport type { TLEditorComponents } from './lib/hooks/useEditorComponents'\nexport { useEvent, useReactiveEvent } from './lib/hooks/useEvent'\nexport { useGlobalMenuIsOpen } from './lib/hooks/useGlobalMenuIsOpen'\nexport { useShallowArrayIdentity, useShallowObjectIdentity } from './lib/hooks/useIdentity'\nexport { useIsCropping } from './lib/hooks/useIsCropping'\nexport { useIsEditing } from './lib/hooks/useIsEditing'\nexport { useLocalStore } from './lib/hooks/useLocalStore'\nexport { usePassThroughWheelEvents } from './lib/hooks/usePassThroughWheelEvents'\nexport { usePeerIds } from './lib/hooks/usePeerIds'\nexport { usePresence } from './lib/hooks/usePresence'\nexport { useRefState } from './lib/hooks/useRefState'\nexport {\n\tsanitizeId,\n\tsuffixSafeId,\n\tuseSharedSafeId,\n\tuseUniqueSafeId,\n\ttype SafeId,\n} from './lib/hooks/useSafeId'\nexport { useTransform } from './lib/hooks/useTransform'\nexport { isCursorInViewport } from './lib/utils/collaborators'\nexport { useTLSchemaFromUtils, useTLStore } from './lib/hooks/useTLStore'\n// oxlint-disable-next-line typescript/no-deprecated\nexport { useViewportHeight } from './lib/hooks/useViewportHeight'\nexport {\n\tLicenseManager,\n\ttype InvalidLicenseKeyResult,\n\ttype InvalidLicenseReason,\n\ttype LicenseFeatureName,\n\ttype LicenseFromKeyResult,\n\ttype LicenseInfo,\n\ttype LicenseState,\n\ttype ValidLicenseKeyResult,\n} from './lib/license/LicenseManager'\nexport { LICENSE_TIMEOUT, useLicenseContext } from './lib/license/LicenseProvider'\nexport { useLicenseFeatureFlag } from './lib/license/useLicenseManagerState'\nexport {\n\tdefaultTldrawOptions,\n\ttype TLClipboardPasteRawInfo,\n\ttype TLClipboardWriteInfo,\n\ttype TldrawOptions,\n} from './lib/options'\nexport {\n\tBox,\n\tROTATE_CORNER_TO_SELECTION_CORNER,\n\trotateSelectionHandle,\n\ttype BoxLike,\n\ttype RotateCorner,\n\ttype SelectionCorner,\n\ttype SelectionEdge,\n\ttype SelectionHandle,\n} from './lib/primitives/Box'\nexport { EASINGS } from './lib/primitives/easings'\nexport { Arc2d } from './lib/primitives/geometry/Arc2d'\nexport { Circle2d } from './lib/primitives/geometry/Circle2d'\nexport { CubicBezier2d } from './lib/primitives/geometry/CubicBezier2d'\nexport { CubicSpline2d } from './lib/primitives/geometry/CubicSpline2d'\nexport { Edge2d } from './lib/primitives/geometry/Edge2d'\nexport { Ellipse2d } from './lib/primitives/geometry/Ellipse2d'\nexport { getVerticesCountForArcLength } from './lib/primitives/geometry/geometry-constants'\nexport {\n\tGeometry2d,\n\tGeometry2dFilters,\n\tTransformedGeometry2d,\n\ttype Geometry2dOptions,\n\ttype TransformedGeometry2dOptions,\n} from './lib/primitives/geometry/Geometry2d'\nexport { Group2d } from './lib/primitives/geometry/Group2d'\nexport { Point2d } from './lib/primitives/geometry/Point2d'\nexport { Polygon2d } from './lib/primitives/geometry/Polygon2d'\nexport { Polyline2d } from './lib/primitives/geometry/Polyline2d'\nexport { Rectangle2d } from './lib/primitives/geometry/Rectangle2d'\nexport { Stadium2d } from './lib/primitives/geometry/Stadium2d'\nexport {\n\tintersectCircleCircle,\n\tintersectCirclePolygon,\n\tintersectCirclePolyline,\n\tintersectLineSegmentCircle,\n\tintersectLineSegmentLineSegment,\n\tintersectLineSegmentPolygon,\n\tintersectLineSegmentPolyline,\n\tintersectPolygonBounds,\n\tintersectPolygonPolygon,\n\tlinesIntersect,\n\tpolygonIntersectsPolyline,\n\tpolygonsIntersect,\n} from './lib/primitives/intersect'\nexport { Mat, type MatLike, type MatModel } from './lib/primitives/Mat'\nexport {\n\tangleDistance,\n\tapproximately,\n\tareAnglesCompatible,\n\taverage,\n\tcanonicalizeRotation,\n\tcenterOfCircleFromThreePoints,\n\tclamp,\n\tclampRadians,\n\tclockwiseAngleDist,\n\tcounterClockwiseAngleDist,\n\tdegreesToRadians,\n\tgetArcMeasure,\n\tgetPointInArcT,\n\tgetPointOnCircle,\n\tgetPointsOnArc,\n\tgetPolygonVertices,\n\tHALF_PI,\n\tisSafeFloat,\n\tperimeterOfEllipse,\n\tPI,\n\tPI2,\n\tpointInPolygon,\n\tprecise,\n\tradiansToDegrees,\n\trangeIntersection,\n\tshortAngleDist,\n\tSIN,\n\tsnapAngle,\n\ttoDomPrecision,\n\ttoFixed,\n\ttoPrecision,\n} from './lib/primitives/utils'\nexport { Vec, type VecLike } from './lib/primitives/Vec'\nexport {\n\tErrorScreen,\n\tLoadingScreen,\n\tTldrawEditor,\n\tuseOnMount,\n\ttype LoadingScreenProps,\n\ttype TldrawEditorBaseProps,\n\ttype TldrawEditorProps,\n\ttype TldrawEditorStoreProps,\n\ttype TldrawEditorWithoutStoreProps,\n\ttype TldrawEditorWithStoreProps,\n\ttype TLOnMountHandler,\n} from './lib/TldrawEditor'\nexport { dataUrlToFile, getDefaultCdnBaseUrl } from './lib/utils/assets'\nexport { clampToBrowserMaxCanvasSize, type CanvasMaxSize } from './lib/utils/browserCanvasMaxSize'\nexport {\n\tcreateDebugValue,\n\tdebugFlags,\n\tfeatureFlags,\n\ttype DebugFlag,\n\ttype DebugFlagDef,\n\ttype DebugFlagDefaults,\n} from './lib/utils/debug-flags'\nexport {\n\tcreateDeepLinkString,\n\tparseDeepLinkString,\n\ttype TLDeepLink,\n\ttype TLDeepLinkOptions,\n} from './lib/utils/deepLinks'\nexport {\n\tactiveElementShouldCaptureKeys,\n\telementShouldCaptureKeys,\n\tgetGlobalDocument,\n\tgetGlobalWindow,\n\tloopToHtmlElement,\n\tmoveElementInto,\n\tpreventDefault,\n\treleasePointerCapture,\n\tsetPointerCapture,\n\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\tstopEventPropagation,\n} from './lib/utils/dom'\nexport { EditorAtom } from './lib/utils/EditorAtom'\nexport { getIncrementedName } from './lib/utils/getIncrementedName'\nexport { getPointerInfo } from './lib/utils/getPointerInfo'\nexport { getSvgPathFromPoints } from './lib/utils/getSvgPathFromPoints'\nexport { isAccelKey } from './lib/utils/keyboard'\nexport { normalizeWheel } from './lib/utils/normalizeWheel'\nexport { getDroppedShapesToNewParents, kickoutOccludedShapes } from './lib/utils/reparenting'\nexport {\n\tgetFontsFromRichText,\n\ttype RichTextFontVisitor,\n\ttype RichTextFontVisitorState,\n\ttype TiptapEditor,\n\ttype TiptapNode,\n\ttype TLTextOptions,\n} from './lib/utils/richText'\nexport {\n\tapplyRotationToSnapshotShapes,\n\tgetRotationSnapshot,\n\ttype TLRotationSnapshot,\n} from './lib/utils/rotation'\nexport {\n\thardResetEditor,\n\topenWindow,\n\trefreshPage,\n\truntime,\n\tsetRuntimeOverrides,\n} from './lib/utils/runtime'\nexport {\n\tReadonlySharedStyleMap,\n\tSharedStyleMap,\n\ttype SharedStyle,\n} from './lib/utils/SharedStylesMap'\nexport { hardReset } from './lib/utils/sync/hardReset'\nexport { LocalIndexedDb, Table, type StoreName } from './lib/utils/sync/LocalIndexedDb'\nexport { type TLStoreWithStatus } from './lib/utils/sync/StoreWithStatus'\nexport { uniq } from './lib/utils/uniq'\n\nregisterTldrawLibraryVersion(\n\t(globalThis as any).TLDRAW_LIBRARY_NAME,\n\t(globalThis as any).TLDRAW_LIBRARY_VERSION,\n\t(globalThis as any).TLDRAW_LIBRARY_MODULES\n)\n\nexport { getColorValue } from './lib/editor/managers/ThemeManager/defaultThemes'\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -5746,6 +5746,9 @@ class Editor extends EventEmitter {
5746
5746
  */
5747
5747
  alignShapes(shapes, operation) {
5748
5748
  if (this.getIsReadonly()) return this;
5749
+ if (operation === "center") {
5750
+ return this.alignShapes(shapes, "center-horizontal").alignShapes(shapes, "center-vertical");
5751
+ }
5749
5752
  const { clusters: shapeClustersToAlign, allBounds } = this.getShapeClusters(shapes, "align");
5750
5753
  if (shapeClustersToAlign.length < 2) return this;
5751
5754
  const commonBounds = Box.Common(allBounds);
@@ -7891,7 +7894,8 @@ class Editor extends EventEmitter {
7891
7894
  _prevCursor = "default";
7892
7895
  /** @internal */
7893
7896
  _shiftKeyTimeout = -1;
7894
- _setShiftKeyTimeout() {
7897
+ _releaseShiftKey() {
7898
+ this._shiftKeyTimeout = -1;
7895
7899
  this.inputs.setShiftKey(false);
7896
7900
  this.dispatch({
7897
7901
  type: "keyboard",
@@ -7907,7 +7911,8 @@ class Editor extends EventEmitter {
7907
7911
  }
7908
7912
  /** @internal */
7909
7913
  _altKeyTimeout = -1;
7910
- _setAltKeyTimeout() {
7914
+ _releaseAltKey() {
7915
+ this._altKeyTimeout = -1;
7911
7916
  this.inputs.setAltKey(false);
7912
7917
  this.dispatch({
7913
7918
  type: "keyboard",
@@ -7923,7 +7928,8 @@ class Editor extends EventEmitter {
7923
7928
  }
7924
7929
  /** @internal */
7925
7930
  _ctrlKeyTimeout = -1;
7926
- _setCtrlKeyTimeout() {
7931
+ _releaseCtrlKey() {
7932
+ this._ctrlKeyTimeout = -1;
7927
7933
  this.inputs.setCtrlKey(false);
7928
7934
  this.dispatch({
7929
7935
  type: "keyboard",
@@ -7939,7 +7945,8 @@ class Editor extends EventEmitter {
7939
7945
  }
7940
7946
  /** @internal */
7941
7947
  _metaKeyTimeout = -1;
7942
- _setMetaKeyTimeout() {
7948
+ _releaseMetaKey() {
7949
+ this._metaKeyTimeout = -1;
7943
7950
  this.inputs.setMetaKey(false);
7944
7951
  this.dispatch({
7945
7952
  type: "keyboard",
@@ -7953,6 +7960,51 @@ class Editor extends EventEmitter {
7953
7960
  code: "MetaLeft"
7954
7961
  });
7955
7962
  }
7963
+ /**
7964
+ * Flush any modifier still sitting in its 150ms release-debounce window, so a new
7965
+ * interaction (a pointer down) starts with correct modifier state instead of a
7966
+ * just-released key still being counted as held. A pending timer is exactly
7967
+ * "released but still counted as held"; a genuinely-held modifier has no timer
7968
+ * (-1) and is left alone.
7969
+ *
7970
+ * Each modifier is released through the same path its timer would have taken
7971
+ * (`_releaseShiftKey` and friends), which dispatches the synthetic `key_up` so
7972
+ * stale codes (e.g. `ShiftLeft`) leave `inputs.keys` and tool `onKeyUp` handlers run.
7973
+ * We clear every pending modifier atom and timer *first*, then dispatch: a synthetic
7974
+ * `key_up` reports all currently-held modifiers, so releasing them one at a time
7975
+ * would make each event re-confirm the not-yet-released ones and cancel their flush.
7976
+ * @internal
7977
+ */
7978
+ _releaseDebouncedModifiers() {
7979
+ const releaseShift = this._shiftKeyTimeout !== -1;
7980
+ const releaseAlt = this._altKeyTimeout !== -1;
7981
+ const releaseCtrl = this._ctrlKeyTimeout !== -1;
7982
+ const releaseMeta = this._metaKeyTimeout !== -1;
7983
+ if (releaseShift) {
7984
+ clearTimeout(this._shiftKeyTimeout);
7985
+ this._shiftKeyTimeout = -1;
7986
+ this.inputs.setShiftKey(false);
7987
+ }
7988
+ if (releaseAlt) {
7989
+ clearTimeout(this._altKeyTimeout);
7990
+ this._altKeyTimeout = -1;
7991
+ this.inputs.setAltKey(false);
7992
+ }
7993
+ if (releaseCtrl) {
7994
+ clearTimeout(this._ctrlKeyTimeout);
7995
+ this._ctrlKeyTimeout = -1;
7996
+ this.inputs.setCtrlKey(false);
7997
+ }
7998
+ if (releaseMeta) {
7999
+ clearTimeout(this._metaKeyTimeout);
8000
+ this._metaKeyTimeout = -1;
8001
+ this.inputs.setMetaKey(false);
8002
+ }
8003
+ if (releaseShift) this._releaseShiftKey();
8004
+ if (releaseAlt) this._releaseAltKey();
8005
+ if (releaseCtrl) this._releaseCtrlKey();
8006
+ if (releaseMeta) this._releaseMetaKey();
8007
+ }
7956
8008
  /** @internal */
7957
8009
  _restoreToolId = "select";
7958
8010
  /** @internal */
@@ -8062,28 +8114,28 @@ class Editor extends EventEmitter {
8062
8114
  this._shiftKeyTimeout = -1;
8063
8115
  inputs.setShiftKey(true);
8064
8116
  } else if (!info.shiftKey && inputs.getShiftKey() && this._shiftKeyTimeout === -1) {
8065
- this._shiftKeyTimeout = this.timers.setTimeout(this._setShiftKeyTimeout, 150);
8117
+ this._shiftKeyTimeout = this.timers.setTimeout(this._releaseShiftKey, 150);
8066
8118
  }
8067
8119
  if (info.altKey) {
8068
8120
  clearTimeout(this._altKeyTimeout);
8069
8121
  this._altKeyTimeout = -1;
8070
8122
  inputs.setAltKey(true);
8071
8123
  } else if (!info.altKey && inputs.getAltKey() && this._altKeyTimeout === -1) {
8072
- this._altKeyTimeout = this.timers.setTimeout(this._setAltKeyTimeout, 150);
8124
+ this._altKeyTimeout = this.timers.setTimeout(this._releaseAltKey, 150);
8073
8125
  }
8074
8126
  if (info.ctrlKey) {
8075
8127
  clearTimeout(this._ctrlKeyTimeout);
8076
8128
  this._ctrlKeyTimeout = -1;
8077
8129
  inputs.setCtrlKey(true);
8078
8130
  } else if (!info.ctrlKey && inputs.getCtrlKey() && this._ctrlKeyTimeout === -1) {
8079
- this._ctrlKeyTimeout = this.timers.setTimeout(this._setCtrlKeyTimeout, 150);
8131
+ this._ctrlKeyTimeout = this.timers.setTimeout(this._releaseCtrlKey, 150);
8080
8132
  }
8081
8133
  if (info.metaKey && info.name !== "key_up") {
8082
8134
  clearTimeout(this._metaKeyTimeout);
8083
8135
  this._metaKeyTimeout = -1;
8084
8136
  inputs.setMetaKey(true);
8085
8137
  } else if (!info.metaKey && inputs.getMetaKey() && this._metaKeyTimeout === -1) {
8086
- this._metaKeyTimeout = this.timers.setTimeout(this._setMetaKeyTimeout, 150);
8138
+ this._metaKeyTimeout = this.timers.setTimeout(this._releaseMetaKey, 150);
8087
8139
  }
8088
8140
  if (!inputs.getIsPointing()) {
8089
8141
  inputs.setIsDragging(false);
@@ -8228,6 +8280,7 @@ class Editor extends EventEmitter {
8228
8280
  switch (info.name) {
8229
8281
  case "pointer_down": {
8230
8282
  if (isPenMode && !isPen) return;
8283
+ this._releaseDebouncedModifiers();
8231
8284
  if (!this.inputs.getIsPanning()) {
8232
8285
  this._longPressTimeout = this.timers.setTimeout(() => {
8233
8286
  const vsb = this.getViewportScreenBounds();
@@ -8710,16 +8763,16 @@ __decorateClass([
8710
8763
  ], Editor.prototype, "getIsReadonly", 1);
8711
8764
  __decorateClass([
8712
8765
  bind
8713
- ], Editor.prototype, "_setShiftKeyTimeout", 1);
8766
+ ], Editor.prototype, "_releaseShiftKey", 1);
8714
8767
  __decorateClass([
8715
8768
  bind
8716
- ], Editor.prototype, "_setAltKeyTimeout", 1);
8769
+ ], Editor.prototype, "_releaseAltKey", 1);
8717
8770
  __decorateClass([
8718
8771
  bind
8719
- ], Editor.prototype, "_setCtrlKeyTimeout", 1);
8772
+ ], Editor.prototype, "_releaseCtrlKey", 1);
8720
8773
  __decorateClass([
8721
8774
  bind
8722
- ], Editor.prototype, "_setMetaKeyTimeout", 1);
8775
+ ], Editor.prototype, "_releaseMetaKey", 1);
8723
8776
  function alertMaxShapes(editor, pageId = editor.getCurrentPageId()) {
8724
8777
  const name = editor.getPage(pageId).name;
8725
8778
  editor.emit("max-shapes", { name, pageId, count: editor.options.maxShapesPerPage });