@tldraw/editor 3.14.2 → 3.15.0-canary.0183e172b2bf
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.
- package/dist-cjs/index.d.ts +49 -38
- package/dist-cjs/index.js +17 -16
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/editor/Editor.js.map +1 -1
- package/dist-cjs/lib/editor/managers/TextManager/TextManager.js +101 -96
- package/dist-cjs/lib/editor/managers/TextManager/TextManager.js.map +2 -2
- package/dist-cjs/lib/hooks/useEditor.js +1 -4
- package/dist-cjs/lib/hooks/useEditor.js.map +2 -2
- package/dist-cjs/version.js +3 -3
- package/dist-cjs/version.js.map +1 -1
- package/dist-esm/index.d.mts +49 -38
- package/dist-esm/index.mjs +48 -42
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/editor/Editor.mjs.map +1 -1
- package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs +101 -96
- package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs.map +2 -2
- package/dist-esm/lib/hooks/useEditor.mjs +1 -4
- package/dist-esm/lib/hooks/useEditor.mjs.map +2 -2
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/package.json +7 -7
- package/src/index.ts +69 -63
- package/src/lib/editor/Editor.ts +1 -1
- package/src/lib/editor/managers/TextManager/TextManager.ts +128 -108
- package/src/lib/hooks/useEditor.tsx +6 -5
- package/src/lib/license/LicenseManager.test.ts +1 -1
- package/src/version.ts +3 -3
|
@@ -21,7 +21,6 @@ __export(TextManager_exports, {
|
|
|
21
21
|
TextManager: () => TextManager
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(TextManager_exports);
|
|
24
|
-
var import_utils = require("@tldraw/utils");
|
|
25
24
|
const fixNewLines = /\r?\n|\r/g;
|
|
26
25
|
function normalizeTextForDom(text) {
|
|
27
26
|
return text.replace(fixNewLines, "\n").split("\n").map((x) => x || " ").join("\n");
|
|
@@ -35,14 +34,6 @@ const textAlignmentsForLtr = {
|
|
|
35
34
|
"end-legacy": "right"
|
|
36
35
|
};
|
|
37
36
|
const spaceCharacterRegex = /\s/;
|
|
38
|
-
const initialDefaultStyles = Object.freeze({
|
|
39
|
-
"overflow-wrap": "break-word",
|
|
40
|
-
"word-break": "auto",
|
|
41
|
-
width: null,
|
|
42
|
-
height: null,
|
|
43
|
-
"max-width": null,
|
|
44
|
-
"min-width": null
|
|
45
|
-
});
|
|
46
37
|
class TextManager {
|
|
47
38
|
constructor(editor) {
|
|
48
39
|
this.editor = editor;
|
|
@@ -52,31 +43,27 @@ class TextManager {
|
|
|
52
43
|
elm.setAttribute("dir", "auto");
|
|
53
44
|
elm.tabIndex = -1;
|
|
54
45
|
this.editor.getContainer().appendChild(elm);
|
|
46
|
+
this.defaultStyles = {
|
|
47
|
+
"overflow-wrap": "break-word",
|
|
48
|
+
"word-break": "auto",
|
|
49
|
+
width: null,
|
|
50
|
+
height: null,
|
|
51
|
+
"max-width": null,
|
|
52
|
+
"min-width": null
|
|
53
|
+
};
|
|
55
54
|
this.elm = elm;
|
|
56
|
-
for (const key of (0, import_utils.objectMapKeys)(initialDefaultStyles)) {
|
|
57
|
-
elm.style.setProperty(key, initialDefaultStyles[key]);
|
|
58
|
-
}
|
|
59
55
|
}
|
|
60
56
|
elm;
|
|
61
|
-
|
|
62
|
-
const stylesToReinstate = {};
|
|
63
|
-
for (const key of (0, import_utils.objectMapKeys)(styles)) {
|
|
64
|
-
if (typeof styles[key] === "string") {
|
|
65
|
-
const oldValue = this.elm.style.getPropertyValue(key);
|
|
66
|
-
if (oldValue === styles[key]) continue;
|
|
67
|
-
stylesToReinstate[key] = oldValue;
|
|
68
|
-
this.elm.style.setProperty(key, styles[key]);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
return () => {
|
|
72
|
-
for (const key of (0, import_utils.objectMapKeys)(stylesToReinstate)) {
|
|
73
|
-
this.elm.style.setProperty(key, stylesToReinstate[key]);
|
|
74
|
-
}
|
|
75
|
-
};
|
|
76
|
-
}
|
|
57
|
+
defaultStyles;
|
|
77
58
|
dispose() {
|
|
78
59
|
return this.elm.remove();
|
|
79
60
|
}
|
|
61
|
+
resetElmStyles() {
|
|
62
|
+
const { elm, defaultStyles } = this;
|
|
63
|
+
for (const key in defaultStyles) {
|
|
64
|
+
elm.style.setProperty(key, defaultStyles[key]);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
80
67
|
measureText(textToMeasure, opts) {
|
|
81
68
|
const div = document.createElement("div");
|
|
82
69
|
div.textContent = normalizeTextForDom(textToMeasure);
|
|
@@ -84,33 +71,44 @@ class TextManager {
|
|
|
84
71
|
}
|
|
85
72
|
measureHtml(html, opts) {
|
|
86
73
|
const { elm } = this;
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
};
|
|
111
|
-
} finally {
|
|
112
|
-
restoreStyles();
|
|
74
|
+
if (opts.otherStyles) {
|
|
75
|
+
for (const key in opts.otherStyles) {
|
|
76
|
+
if (!this.defaultStyles[key]) {
|
|
77
|
+
this.defaultStyles[key] = elm.style.getPropertyValue(key);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
elm.innerHTML = html;
|
|
82
|
+
this.resetElmStyles();
|
|
83
|
+
elm.style.setProperty("font-family", opts.fontFamily);
|
|
84
|
+
elm.style.setProperty("font-style", opts.fontStyle);
|
|
85
|
+
elm.style.setProperty("font-weight", opts.fontWeight);
|
|
86
|
+
elm.style.setProperty("font-size", opts.fontSize + "px");
|
|
87
|
+
elm.style.setProperty("line-height", opts.lineHeight.toString());
|
|
88
|
+
elm.style.setProperty("padding", opts.padding);
|
|
89
|
+
if (opts.maxWidth) {
|
|
90
|
+
elm.style.setProperty("max-width", opts.maxWidth + "px");
|
|
91
|
+
}
|
|
92
|
+
if (opts.minWidth) {
|
|
93
|
+
elm.style.setProperty("min-width", opts.minWidth + "px");
|
|
94
|
+
}
|
|
95
|
+
if (opts.disableOverflowWrapBreaking) {
|
|
96
|
+
elm.style.setProperty("overflow-wrap", "normal");
|
|
113
97
|
}
|
|
98
|
+
if (opts.otherStyles) {
|
|
99
|
+
for (const [key, value] of Object.entries(opts.otherStyles)) {
|
|
100
|
+
elm.style.setProperty(key, value);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const scrollWidth = opts.measureScrollWidth ? elm.scrollWidth : 0;
|
|
104
|
+
const rect = elm.getBoundingClientRect();
|
|
105
|
+
return {
|
|
106
|
+
x: 0,
|
|
107
|
+
y: 0,
|
|
108
|
+
w: rect.width,
|
|
109
|
+
h: rect.height,
|
|
110
|
+
scrollWidth
|
|
111
|
+
};
|
|
114
112
|
}
|
|
115
113
|
/**
|
|
116
114
|
* Given an html element, measure the position of each span of unbroken
|
|
@@ -190,52 +188,59 @@ class TextManager {
|
|
|
190
188
|
measureTextSpans(textToMeasure, opts) {
|
|
191
189
|
if (textToMeasure === "") return [];
|
|
192
190
|
const { elm } = this;
|
|
193
|
-
|
|
191
|
+
if (opts.otherStyles) {
|
|
192
|
+
for (const key in opts.otherStyles) {
|
|
193
|
+
if (!this.defaultStyles[key]) {
|
|
194
|
+
this.defaultStyles[key] = elm.style.getPropertyValue(key);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
this.resetElmStyles();
|
|
199
|
+
elm.style.setProperty("font-family", opts.fontFamily);
|
|
200
|
+
elm.style.setProperty("font-style", opts.fontStyle);
|
|
201
|
+
elm.style.setProperty("font-weight", opts.fontWeight);
|
|
202
|
+
elm.style.setProperty("font-size", opts.fontSize + "px");
|
|
203
|
+
elm.style.setProperty("line-height", opts.lineHeight.toString());
|
|
194
204
|
const elementWidth = Math.ceil(opts.width - opts.padding * 2);
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
"
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
}
|
|
208
|
-
const
|
|
209
|
-
|
|
210
|
-
|
|
205
|
+
elm.style.setProperty("width", `${elementWidth}px`);
|
|
206
|
+
elm.style.setProperty("height", "min-content");
|
|
207
|
+
elm.style.setProperty("text-align", textAlignmentsForLtr[opts.textAlign]);
|
|
208
|
+
const shouldTruncateToFirstLine = opts.overflow === "truncate-ellipsis" || opts.overflow === "truncate-clip";
|
|
209
|
+
if (shouldTruncateToFirstLine) {
|
|
210
|
+
elm.style.setProperty("overflow-wrap", "anywhere");
|
|
211
|
+
elm.style.setProperty("word-break", "break-all");
|
|
212
|
+
}
|
|
213
|
+
if (opts.otherStyles) {
|
|
214
|
+
for (const [key, value] of Object.entries(opts.otherStyles)) {
|
|
215
|
+
elm.style.setProperty(key, value);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
const normalizedText = normalizeTextForDom(textToMeasure);
|
|
219
|
+
elm.textContent = normalizedText;
|
|
220
|
+
const { spans, didTruncate } = this.measureElementTextNodeSpans(elm, {
|
|
221
|
+
shouldTruncateToFirstLine
|
|
222
|
+
});
|
|
223
|
+
if (opts.overflow === "truncate-ellipsis" && didTruncate) {
|
|
224
|
+
elm.textContent = "\u2026";
|
|
225
|
+
const ellipsisWidth = Math.ceil(this.measureElementTextNodeSpans(elm).spans[0].box.w);
|
|
226
|
+
elm.style.setProperty("width", `${elementWidth - ellipsisWidth}px`);
|
|
211
227
|
elm.textContent = normalizedText;
|
|
212
|
-
const
|
|
213
|
-
shouldTruncateToFirstLine
|
|
228
|
+
const truncatedSpans = this.measureElementTextNodeSpans(elm, {
|
|
229
|
+
shouldTruncateToFirstLine: true
|
|
230
|
+
}).spans;
|
|
231
|
+
const lastSpan = truncatedSpans[truncatedSpans.length - 1];
|
|
232
|
+
truncatedSpans.push({
|
|
233
|
+
text: "\u2026",
|
|
234
|
+
box: {
|
|
235
|
+
x: Math.min(lastSpan.box.x + lastSpan.box.w, opts.width - opts.padding - ellipsisWidth),
|
|
236
|
+
y: lastSpan.box.y,
|
|
237
|
+
w: ellipsisWidth,
|
|
238
|
+
h: lastSpan.box.h
|
|
239
|
+
}
|
|
214
240
|
});
|
|
215
|
-
|
|
216
|
-
elm.textContent = "\u2026";
|
|
217
|
-
const ellipsisWidth = Math.ceil(this.measureElementTextNodeSpans(elm).spans[0].box.w);
|
|
218
|
-
elm.style.setProperty("width", `${elementWidth - ellipsisWidth}px`);
|
|
219
|
-
elm.textContent = normalizedText;
|
|
220
|
-
const truncatedSpans = this.measureElementTextNodeSpans(elm, {
|
|
221
|
-
shouldTruncateToFirstLine: true
|
|
222
|
-
}).spans;
|
|
223
|
-
const lastSpan = truncatedSpans[truncatedSpans.length - 1];
|
|
224
|
-
truncatedSpans.push({
|
|
225
|
-
text: "\u2026",
|
|
226
|
-
box: {
|
|
227
|
-
x: Math.min(lastSpan.box.x + lastSpan.box.w, opts.width - opts.padding - ellipsisWidth),
|
|
228
|
-
y: lastSpan.box.y,
|
|
229
|
-
w: ellipsisWidth,
|
|
230
|
-
h: lastSpan.box.h
|
|
231
|
-
}
|
|
232
|
-
});
|
|
233
|
-
return truncatedSpans;
|
|
234
|
-
}
|
|
235
|
-
return spans;
|
|
236
|
-
} finally {
|
|
237
|
-
restoreStyles();
|
|
241
|
+
return truncatedSpans;
|
|
238
242
|
}
|
|
243
|
+
return spans;
|
|
239
244
|
}
|
|
240
245
|
}
|
|
241
246
|
//# sourceMappingURL=TextManager.js.map
|
|
@@ -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 { Editor } from '../../Editor'\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\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\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 {\n\tprivate elm: HTMLDivElement\n\n\tconstructor(public editor: Editor) {\n\t\tconst elm = document.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\tthis.editor.getContainer().appendChild(elm)\n\n\t\tthis.elm = elm\n\n\t\tfor (const key of objectMapKeys(initialDefaultStyles)) {\n\t\t\telm.style.setProperty(key, initialDefaultStyles[key])\n\t\t}\n\t}\n\n\tprivate setElementStyles(styles: Record<string, string | undefined>) {\n\t\tconst stylesToReinstate = {} as any\n\t\tfor (const key of objectMapKeys(styles)) {\n\t\t\tif (typeof styles[key] === 'string') {\n\t\t\t\tconst oldValue = this.elm.style.getPropertyValue(key)\n\t\t\t\tif (oldValue === styles[key]) continue\n\t\t\t\tstylesToReinstate[key] = oldValue\n\t\t\t\tthis.elm.style.setProperty(key, styles[key])\n\t\t\t}\n\t\t}\n\t\treturn () => {\n\t\t\tfor (const key of objectMapKeys(stylesToReinstate)) {\n\t\t\t\tthis.elm.style.setProperty(key, stylesToReinstate[key])\n\t\t\t}\n\t\t}\n\t}\n\n\tdispose() {\n\t\treturn this.elm.remove()\n\t}\n\n\tmeasureText(textToMeasure: string, opts: TLMeasureTextOpts): BoxModel & { scrollWidth: number } {\n\t\tconst div = document.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): BoxModel & { scrollWidth: number } {\n\t\tconst { elm } = this\n\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': opts.lineHeight.toString(),\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' : undefined,\n\t\t\t...opts.otherStyles,\n\t\t}\n\n\t\tconst restoreStyles = this.setElementStyles(newStyles)\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 char of childNode.textContent ?? '') {\n\t\t\t\t// place the range around the characters we're interested in\n\t\t\t\trange.setStart(textNode, idx)\n\t\t\t\trange.setEnd(textNode, idx + char.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// 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(char)\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: char,\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 += char\n\t\t\t\t}\n\n\t\t\t\tif (char === '\\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 += char.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': opts.lineHeight.toString(),\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' : undefined,\n\t\t\t'word-break': shouldTruncateToFirstLine ? 'break-all' : undefined,\n\t\t\t...opts.otherStyles,\n\t\t}\n\t\tconst restoreStyles = this.setElementStyles(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": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
4
|
+
"sourcesContent": ["import { BoxModel, TLDefaultHorizontalAlignStyle } from '@tldraw/tlschema'\nimport { Editor } from '../../Editor'\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\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/** @public */\nexport class TextManager {\n\tprivate elm: HTMLDivElement\n\tprivate defaultStyles: Record<string, string | null>\n\n\tconstructor(public editor: Editor) {\n\t\tconst elm = document.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\tthis.editor.getContainer().appendChild(elm)\n\n\t\t// we need to save the default styles so that we can restore them when we're done\n\t\t// these must be the css names, not the js names for the styles\n\t\tthis.defaultStyles = {\n\t\t\t'overflow-wrap': 'break-word',\n\t\t\t'word-break': 'auto',\n\t\t\twidth: null,\n\t\t\theight: null,\n\t\t\t'max-width': null,\n\t\t\t'min-width': null,\n\t\t}\n\n\t\tthis.elm = elm\n\t}\n\n\tdispose() {\n\t\treturn this.elm.remove()\n\t}\n\n\tprivate resetElmStyles() {\n\t\tconst { elm, defaultStyles } = this\n\t\tfor (const key in defaultStyles) {\n\t\t\telm.style.setProperty(key, defaultStyles[key])\n\t\t}\n\t}\n\n\tmeasureText(textToMeasure: string, opts: TLMeasureTextOpts): BoxModel & { scrollWidth: number } {\n\t\tconst div = document.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): BoxModel & { scrollWidth: number } {\n\t\tconst { elm } = this\n\n\t\tif (opts.otherStyles) {\n\t\t\tfor (const key in opts.otherStyles) {\n\t\t\t\tif (!this.defaultStyles[key]) {\n\t\t\t\t\t// we need to save the original style so that we can restore it when we're done\n\t\t\t\t\tthis.defaultStyles[key] = elm.style.getPropertyValue(key)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\telm.innerHTML = html\n\n\t\t// Apply the default styles to the element (for all styles here or that were ever seen in opts.otherStyles)\n\t\tthis.resetElmStyles()\n\n\t\telm.style.setProperty('font-family', opts.fontFamily)\n\t\telm.style.setProperty('font-style', opts.fontStyle)\n\t\telm.style.setProperty('font-weight', opts.fontWeight)\n\t\telm.style.setProperty('font-size', opts.fontSize + 'px')\n\t\telm.style.setProperty('line-height', opts.lineHeight.toString())\n\t\telm.style.setProperty('padding', opts.padding)\n\n\t\tif (opts.maxWidth) {\n\t\t\telm.style.setProperty('max-width', opts.maxWidth + 'px')\n\t\t}\n\n\t\tif (opts.minWidth) {\n\t\t\telm.style.setProperty('min-width', opts.minWidth + 'px')\n\t\t}\n\n\t\tif (opts.disableOverflowWrapBreaking) {\n\t\t\telm.style.setProperty('overflow-wrap', 'normal')\n\t\t}\n\n\t\tif (opts.otherStyles) {\n\t\t\tfor (const [key, value] of Object.entries(opts.otherStyles)) {\n\t\t\t\telm.style.setProperty(key, value)\n\t\t\t}\n\t\t}\n\n\t\tconst scrollWidth = opts.measureScrollWidth ? elm.scrollWidth : 0\n\t\tconst rect = elm.getBoundingClientRect()\n\n\t\treturn {\n\t\t\tx: 0,\n\t\t\ty: 0,\n\t\t\tw: rect.width,\n\t\t\th: rect.height,\n\t\t\tscrollWidth,\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 char of childNode.textContent ?? '') {\n\t\t\t\t// place the range around the characters we're interested in\n\t\t\t\trange.setStart(textNode, idx)\n\t\t\t\trange.setEnd(textNode, idx + char.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// 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(char)\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: char,\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 += char\n\t\t\t\t}\n\n\t\t\t\tif (char === '\\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 += char.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\tif (opts.otherStyles) {\n\t\t\tfor (const key in opts.otherStyles) {\n\t\t\t\tif (!this.defaultStyles[key]) {\n\t\t\t\t\t// we need to save the original style so that we can restore it when we're done\n\t\t\t\t\tthis.defaultStyles[key] = elm.style.getPropertyValue(key)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.resetElmStyles()\n\n\t\telm.style.setProperty('font-family', opts.fontFamily)\n\t\telm.style.setProperty('font-style', opts.fontStyle)\n\t\telm.style.setProperty('font-weight', opts.fontWeight)\n\t\telm.style.setProperty('font-size', opts.fontSize + 'px')\n\t\telm.style.setProperty('line-height', opts.lineHeight.toString())\n\n\t\tconst elementWidth = Math.ceil(opts.width - opts.padding * 2)\n\t\telm.style.setProperty('width', `${elementWidth}px`)\n\t\telm.style.setProperty('height', 'min-content')\n\t\telm.style.setProperty('text-align', textAlignmentsForLtr[opts.textAlign])\n\n\t\tconst shouldTruncateToFirstLine =\n\t\t\topts.overflow === 'truncate-ellipsis' || opts.overflow === 'truncate-clip'\n\n\t\tif (shouldTruncateToFirstLine) {\n\t\t\telm.style.setProperty('overflow-wrap', 'anywhere')\n\t\t\telm.style.setProperty('word-break', 'break-all')\n\t\t}\n\n\t\tif (opts.otherStyles) {\n\t\t\tfor (const [key, value] of Object.entries(opts.otherStyles)) {\n\t\t\t\telm.style.setProperty(key, value)\n\t\t\t}\n\t\t}\n\n\t\tconst normalizedText = normalizeTextForDom(textToMeasure)\n\n\t\t// Render the text into the measurement element:\n\t\telm.textContent = normalizedText\n\n\t\t// actually measure the text:\n\t\tconst { spans, didTruncate } = this.measureElementTextNodeSpans(elm, {\n\t\t\tshouldTruncateToFirstLine,\n\t\t})\n\n\t\tif (opts.overflow === 'truncate-ellipsis' && didTruncate) {\n\t\t\t// we need to measure the ellipsis to know how much space it takes up\n\t\t\telm.textContent = '\u2026'\n\t\t\tconst ellipsisWidth = Math.ceil(this.measureElementTextNodeSpans(elm).spans[0].box.w)\n\n\t\t\t// then, we need to subtract that space from the width we have and measure again:\n\t\t\telm.style.setProperty('width', `${elementWidth - ellipsisWidth}px`)\n\t\t\telm.textContent = normalizedText\n\t\t\tconst truncatedSpans = this.measureElementTextNodeSpans(elm, {\n\t\t\t\tshouldTruncateToFirstLine: true,\n\t\t\t}).spans\n\n\t\t\t// Finally, we add in our ellipsis at the end of the last span. We\n\t\t\t// have to do this after measuring, not before, because adding the\n\t\t\t// ellipsis changes how whitespace might be getting collapsed by the\n\t\t\t// browser.\n\t\t\tconst lastSpan = truncatedSpans[truncatedSpans.length - 1]!\n\t\t\ttruncatedSpans.push({\n\t\t\t\ttext: '\u2026',\n\t\t\t\tbox: {\n\t\t\t\t\tx: Math.min(lastSpan.box.x + lastSpan.box.w, opts.width - opts.padding - ellipsisWidth),\n\t\t\t\t\ty: lastSpan.box.y,\n\t\t\t\t\tw: ellipsisWidth,\n\t\t\t\t\th: lastSpan.box.h,\n\t\t\t\t},\n\t\t\t})\n\n\t\t\treturn truncatedSpans\n\t\t}\n\n\t\treturn spans\n\t}\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -50,10 +50,7 @@ function useEditor() {
|
|
|
50
50
|
function useMaybeEditor() {
|
|
51
51
|
return import_react.default.useContext(EditorContext);
|
|
52
52
|
}
|
|
53
|
-
function EditorProvider({
|
|
54
|
-
editor,
|
|
55
|
-
children
|
|
56
|
-
}) {
|
|
53
|
+
function EditorProvider({ editor, children }) {
|
|
57
54
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EditorContext.Provider, { value: editor, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_useSafeId.IdProvider, { children }) });
|
|
58
55
|
}
|
|
59
56
|
//# sourceMappingURL=useEditor.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/hooks/useEditor.tsx"],
|
|
4
|
-
"sourcesContent": ["import React, { createContext } from 'react'\nimport { Editor } from '../editor/Editor'\nimport { IdProvider } from './useSafeId'\n\n/** @public */\nexport const EditorContext = createContext<Editor | null>(null)\n\n/** @public */\nexport function useEditor(): Editor {\n\tconst editor = React.useContext(EditorContext)\n\tif (!editor) {\n\t\tthrow new Error(\n\t\t\t'useEditor must be used inside of the <Tldraw /> or <TldrawEditor /> components'\n\t\t)\n\t}\n\treturn editor\n}\n\n/** @public */\nexport function useMaybeEditor(): Editor | null {\n\treturn React.useContext(EditorContext)\n}\n\nexport
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
4
|
+
"sourcesContent": ["import React, { createContext } from 'react'\nimport { Editor } from '../editor/Editor'\nimport { IdProvider } from './useSafeId'\n\n/** @public */\nexport const EditorContext = createContext<Editor | null>(null)\n\n/** @public */\nexport function useEditor(): Editor {\n\tconst editor = React.useContext(EditorContext)\n\tif (!editor) {\n\t\tthrow new Error(\n\t\t\t'useEditor must be used inside of the <Tldraw /> or <TldrawEditor /> components'\n\t\t)\n\t}\n\treturn editor\n}\n\n/** @public */\nexport function useMaybeEditor(): Editor | null {\n\treturn React.useContext(EditorContext)\n}\n\n/** @public */\nexport interface EditorProviderProps {\n\teditor: Editor\n\tchildren: React.ReactNode\n}\n\n/** @public @react */\nexport function EditorProvider({ editor, children }: EditorProviderProps) {\n\treturn (\n\t\t<EditorContext.Provider value={editor}>\n\t\t\t<IdProvider>{children}</IdProvider>\n\t\t</EditorContext.Provider>\n\t)\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiCG;AAjCH,mBAAqC;AAErC,uBAA2B;AAGpB,MAAM,oBAAgB,4BAA6B,IAAI;AAGvD,SAAS,YAAoB;AACnC,QAAM,SAAS,aAAAA,QAAM,WAAW,aAAa;AAC7C,MAAI,CAAC,QAAQ;AACZ,UAAM,IAAI;AAAA,MACT;AAAA,IACD;AAAA,EACD;AACA,SAAO;AACR;AAGO,SAAS,iBAAgC;AAC/C,SAAO,aAAAA,QAAM,WAAW,aAAa;AACtC;AASO,SAAS,eAAe,EAAE,QAAQ,SAAS,GAAwB;AACzE,SACC,4CAAC,cAAc,UAAd,EAAuB,OAAO,QAC9B,sDAAC,+BAAY,UAAS,GACvB;AAEF;",
|
|
6
6
|
"names": ["React"]
|
|
7
7
|
}
|
package/dist-cjs/version.js
CHANGED
|
@@ -22,10 +22,10 @@ __export(version_exports, {
|
|
|
22
22
|
version: () => version
|
|
23
23
|
});
|
|
24
24
|
module.exports = __toCommonJS(version_exports);
|
|
25
|
-
const version = "3.
|
|
25
|
+
const version = "3.15.0-canary.0183e172b2bf";
|
|
26
26
|
const publishDates = {
|
|
27
27
|
major: "2024-09-13T14:36:29.063Z",
|
|
28
|
-
minor: "2025-07-
|
|
29
|
-
patch: "2025-07-
|
|
28
|
+
minor: "2025-07-03T13:14:18.791Z",
|
|
29
|
+
patch: "2025-07-03T13:14:18.791Z"
|
|
30
30
|
};
|
|
31
31
|
//# sourceMappingURL=version.js.map
|
package/dist-cjs/version.js.map
CHANGED
|
@@ -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 = '3.
|
|
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 = '3.15.0-canary.0183e172b2bf'\nexport const publishDates = {\n\tmajor: '2024-09-13T14:36:29.063Z',\n\tminor: '2025-07-03T13:14:18.791Z',\n\tpatch: '2025-07-03T13:14:18.791Z',\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
|
}
|
package/dist-esm/index.d.mts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
|
|
1
3
|
import { Atom } from '@tldraw/state';
|
|
2
4
|
import { BoxModel } from '@tldraw/tlschema';
|
|
3
5
|
import { ComponentType } from 'react';
|
|
4
6
|
import { Computed } from '@tldraw/state';
|
|
5
7
|
import { Dispatch } from 'react';
|
|
6
8
|
import { Editor as Editor_2 } from '@tiptap/core';
|
|
7
|
-
import { EditorProviderProps } from '@tiptap/react';
|
|
9
|
+
import { EditorProviderProps as EditorProviderProps_2 } from '@tiptap/react';
|
|
8
10
|
import EventEmitter from 'eventemitter3';
|
|
9
11
|
import { ExoticComponent } from 'react';
|
|
10
12
|
import { HistoryEntry } from '@tldraw/store';
|
|
@@ -17,8 +19,8 @@ import { NamedExoticComponent } from 'react';
|
|
|
17
19
|
import { Node as Node_2 } from '@tiptap/pm/model';
|
|
18
20
|
import { PerformanceTracker } from '@tldraw/utils';
|
|
19
21
|
import { PointerEventHandler } from 'react';
|
|
20
|
-
import
|
|
21
|
-
import
|
|
22
|
+
import { default as React_2 } from 'react';
|
|
23
|
+
import * as React_3 from 'react';
|
|
22
24
|
import { ReactElement } from 'react';
|
|
23
25
|
import { ReactNode } from 'react';
|
|
24
26
|
import { RecordProps } from '@tldraw/tlschema';
|
|
@@ -57,7 +59,6 @@ import { TLImageAsset } from '@tldraw/tlschema';
|
|
|
57
59
|
import { TLInstance } from '@tldraw/tlschema';
|
|
58
60
|
import { TLInstancePageState } from '@tldraw/tlschema';
|
|
59
61
|
import { TLInstancePresence } from '@tldraw/tlschema';
|
|
60
|
-
import { TLOpacityType } from '@tldraw/tlschema';
|
|
61
62
|
import { TLPage } from '@tldraw/tlschema';
|
|
62
63
|
import { TLPageId } from '@tldraw/tlschema';
|
|
63
64
|
import { TLParentId } from '@tldraw/tlschema';
|
|
@@ -715,8 +716,8 @@ export declare function createTLStore({ initialData, defaultName, id, assets, on
|
|
|
715
716
|
|
|
716
717
|
/** @public */
|
|
717
718
|
export declare function createTLUser(opts?: {
|
|
718
|
-
setUserPreferences?: (userPreferences: TLUserPreferences) => void;
|
|
719
|
-
userPreferences?: Signal<TLUserPreferences
|
|
719
|
+
setUserPreferences?: ((userPreferences: TLUserPreferences) => void) | undefined;
|
|
720
|
+
userPreferences?: Signal<TLUserPreferences, unknown> | undefined;
|
|
720
721
|
}): TLUser;
|
|
721
722
|
|
|
722
723
|
/** @public */
|
|
@@ -847,7 +848,7 @@ export declare const defaultTldrawOptions: {
|
|
|
847
848
|
readonly edgeScrollSpeed: 25;
|
|
848
849
|
readonly enableToolbarKeyboardShortcuts: true;
|
|
849
850
|
readonly exportProvider: ExoticComponent< {
|
|
850
|
-
children?: ReactNode
|
|
851
|
+
children?: ReactNode;
|
|
851
852
|
}>;
|
|
852
853
|
readonly flattenImageBoundsExpand: 64;
|
|
853
854
|
readonly flattenImageBoundsPadding: 16;
|
|
@@ -1017,8 +1018,8 @@ export declare class Editor extends EventEmitter<TLEventMap> {
|
|
|
1017
1018
|
readonly timers: {
|
|
1018
1019
|
dispose: () => void;
|
|
1019
1020
|
requestAnimationFrame: (callback: FrameRequestCallback) => number;
|
|
1020
|
-
setInterval: (handler: TimerHandler, timeout?: number, ...args: any[]) => number;
|
|
1021
|
-
setTimeout: (handler: TimerHandler, timeout?: number, ...args: any[]) => number;
|
|
1021
|
+
setInterval: (handler: TimerHandler, timeout?: number | undefined, ...args: any[]) => number;
|
|
1022
|
+
setTimeout: (handler: TimerHandler, timeout?: number | undefined, ...args: any[]) => number;
|
|
1022
1023
|
};
|
|
1023
1024
|
/**
|
|
1024
1025
|
* A manager for the user and their preferences.
|
|
@@ -2067,10 +2068,10 @@ export declare class Editor extends EventEmitter<TLEventMap> {
|
|
|
2067
2068
|
*/
|
|
2068
2069
|
slideCamera(opts?: {
|
|
2069
2070
|
direction: VecLike;
|
|
2070
|
-
force?: boolean;
|
|
2071
|
-
friction?: number;
|
|
2071
|
+
force?: boolean | undefined;
|
|
2072
|
+
friction?: number | undefined;
|
|
2072
2073
|
speed: number;
|
|
2073
|
-
speedThreshold?: number;
|
|
2074
|
+
speedThreshold?: number | undefined;
|
|
2074
2075
|
}): this;
|
|
2075
2076
|
/**
|
|
2076
2077
|
* Animate the camera to a user's cursor position. This also briefly show the user's cursor if it's not currently visible.
|
|
@@ -2682,12 +2683,12 @@ export declare class Editor extends EventEmitter<TLEventMap> {
|
|
|
2682
2683
|
*/
|
|
2683
2684
|
getShapeAtPoint(point: VecLike, opts?: {
|
|
2684
2685
|
filter?(shape: TLShape): boolean;
|
|
2685
|
-
hitFrameInside?: boolean;
|
|
2686
|
-
hitInside?: boolean;
|
|
2687
|
-
hitLabels?: boolean;
|
|
2688
|
-
hitLocked?: boolean;
|
|
2689
|
-
margin?: number;
|
|
2690
|
-
renderingOnly?: boolean;
|
|
2686
|
+
hitFrameInside?: boolean | undefined;
|
|
2687
|
+
hitInside?: boolean | undefined;
|
|
2688
|
+
hitLabels?: boolean | undefined;
|
|
2689
|
+
hitLocked?: boolean | undefined;
|
|
2690
|
+
margin?: number | undefined;
|
|
2691
|
+
renderingOnly?: boolean | undefined;
|
|
2691
2692
|
}): TLShape | undefined;
|
|
2692
2693
|
/**
|
|
2693
2694
|
* Get the shapes, if any, at a given page point.
|
|
@@ -2706,8 +2707,8 @@ export declare class Editor extends EventEmitter<TLEventMap> {
|
|
|
2706
2707
|
* @public
|
|
2707
2708
|
*/
|
|
2708
2709
|
getShapesAtPoint(point: VecLike, opts?: {
|
|
2709
|
-
hitInside?: boolean;
|
|
2710
|
-
margin?: number;
|
|
2710
|
+
hitInside?: boolean | undefined;
|
|
2711
|
+
margin?: number | undefined;
|
|
2711
2712
|
}): TLShape[];
|
|
2712
2713
|
/**
|
|
2713
2714
|
* Test whether a point (in the current page space) will will a shape. This method takes into account masks,
|
|
@@ -2725,8 +2726,8 @@ export declare class Editor extends EventEmitter<TLEventMap> {
|
|
|
2725
2726
|
* @public
|
|
2726
2727
|
*/
|
|
2727
2728
|
isPointInShape(shape: TLShape | TLShapeId, point: VecLike, opts?: {
|
|
2728
|
-
hitInside?: boolean;
|
|
2729
|
-
margin?: number;
|
|
2729
|
+
hitInside?: boolean | undefined;
|
|
2730
|
+
margin?: number | undefined;
|
|
2730
2731
|
}): boolean;
|
|
2731
2732
|
/**
|
|
2732
2733
|
* Convert a point in the current page space to a point in the local space of a shape. For example, if a
|
|
@@ -4012,7 +4013,16 @@ export declare class Editor extends EventEmitter<TLEventMap> {
|
|
|
4012
4013
|
}
|
|
4013
4014
|
|
|
4014
4015
|
/** @public */
|
|
4015
|
-
export declare const EditorContext:
|
|
4016
|
+
export declare const EditorContext: React_2.Context<Editor | null>;
|
|
4017
|
+
|
|
4018
|
+
/** @public @react */
|
|
4019
|
+
export declare function EditorProvider({ editor, children }: EditorProviderProps): JSX_2.Element;
|
|
4020
|
+
|
|
4021
|
+
/** @public */
|
|
4022
|
+
export declare interface EditorProviderProps {
|
|
4023
|
+
editor: Editor;
|
|
4024
|
+
children: React_2.ReactNode;
|
|
4025
|
+
}
|
|
4016
4026
|
|
|
4017
4027
|
/** @public */
|
|
4018
4028
|
export declare class Ellipse2d extends Geometry2d {
|
|
@@ -4037,7 +4047,7 @@ export declare class Ellipse2d extends Geometry2d {
|
|
|
4037
4047
|
}
|
|
4038
4048
|
|
|
4039
4049
|
/** @public */
|
|
4040
|
-
export declare class ErrorBoundary extends
|
|
4050
|
+
export declare class ErrorBoundary extends React_3.Component<React_3.PropsWithRef<React_3.PropsWithChildren<TLErrorBoundaryProps>>, {
|
|
4041
4051
|
error: Error | null;
|
|
4042
4052
|
}> {
|
|
4043
4053
|
static getDerivedStateFromError(error: Error): {
|
|
@@ -4047,7 +4057,7 @@ export declare class ErrorBoundary extends React_2.Component<React_2.PropsWithRe
|
|
|
4047
4057
|
error: null;
|
|
4048
4058
|
};
|
|
4049
4059
|
componentDidCatch(error: unknown): void;
|
|
4050
|
-
render(): boolean | JSX_2.Element | Iterable<
|
|
4060
|
+
render(): boolean | JSX_2.Element | Iterable<React_3.ReactNode> | null | number | string | undefined;
|
|
4051
4061
|
}
|
|
4052
4062
|
|
|
4053
4063
|
/** @public @react */
|
|
@@ -4451,7 +4461,7 @@ export declare class HistoryManager<R extends UnknownRecord> {
|
|
|
4451
4461
|
export declare function HTMLContainer({ children, className, ...rest }: HTMLContainerProps): JSX_2.Element;
|
|
4452
4462
|
|
|
4453
4463
|
/** @public */
|
|
4454
|
-
export declare type HTMLContainerProps =
|
|
4464
|
+
export declare type HTMLContainerProps = React_3.HTMLAttributes<HTMLDivElement>;
|
|
4455
4465
|
|
|
4456
4466
|
/** @public */
|
|
4457
4467
|
export declare const inlineBase64AssetStore: TLAssetStore;
|
|
@@ -4813,7 +4823,7 @@ export declare function precise(A: VecLike): string;
|
|
|
4813
4823
|
* @param event - To prevent default on
|
|
4814
4824
|
* @public
|
|
4815
4825
|
*/
|
|
4816
|
-
export declare function preventDefault(event: Event |
|
|
4826
|
+
export declare function preventDefault(event: Event | React_2.BaseSyntheticEvent): void;
|
|
4817
4827
|
|
|
4818
4828
|
/**
|
|
4819
4829
|
* Convert radians to degrees.
|
|
@@ -4848,10 +4858,10 @@ export declare class ReadonlySharedStyleMap {
|
|
|
4848
4858
|
getAsKnownValue<T>(prop: StyleProp<T>): T | undefined;
|
|
4849
4859
|
get size(): number;
|
|
4850
4860
|
equals(other: ReadonlySharedStyleMap): boolean;
|
|
4851
|
-
keys():
|
|
4852
|
-
values():
|
|
4853
|
-
entries():
|
|
4854
|
-
[Symbol.iterator]():
|
|
4861
|
+
keys(): IterableIterator<StyleProp<any>>;
|
|
4862
|
+
values(): IterableIterator<SharedStyle<unknown>>;
|
|
4863
|
+
entries(): IterableIterator<[StyleProp<any>, SharedStyle<unknown>]>;
|
|
4864
|
+
[Symbol.iterator](): IterableIterator<[StyleProp<any>, SharedStyle<unknown>]>;
|
|
4855
4865
|
}
|
|
4856
4866
|
|
|
4857
4867
|
/** @public */
|
|
@@ -4875,7 +4885,7 @@ export declare class Rectangle2d extends Polygon2d {
|
|
|
4875
4885
|
export declare function refreshPage(): void;
|
|
4876
4886
|
|
|
4877
4887
|
/** @public */
|
|
4878
|
-
export declare function releasePointerCapture(element: Element, event: PointerEvent |
|
|
4888
|
+
export declare function releasePointerCapture(element: Element, event: PointerEvent | React_2.PointerEvent<Element>): void;
|
|
4879
4889
|
|
|
4880
4890
|
/** @public */
|
|
4881
4891
|
export declare type RequiredKeys<T, K extends keyof T> = Required<Pick<T, K>> & Omit<T, K>;
|
|
@@ -5018,7 +5028,7 @@ export declare type SelectionEdge = 'bottom' | 'left' | 'right' | 'top';
|
|
|
5018
5028
|
export declare type SelectionHandle = SelectionCorner | SelectionEdge;
|
|
5019
5029
|
|
|
5020
5030
|
/** @public */
|
|
5021
|
-
export declare function setPointerCapture(element: Element, event: PointerEvent |
|
|
5031
|
+
export declare function setPointerCapture(element: Element, event: PointerEvent | React_2.PointerEvent<Element>): void;
|
|
5022
5032
|
|
|
5023
5033
|
/** @public */
|
|
5024
5034
|
export declare function setRuntimeOverrides(input: Partial<typeof runtime>): void;
|
|
@@ -5724,7 +5734,7 @@ export declare function suffixSafeId(id: SafeId, suffix: string): SafeId;
|
|
|
5724
5734
|
export declare function SVGContainer({ children, className, ...rest }: SVGContainerProps): JSX_2.Element;
|
|
5725
5735
|
|
|
5726
5736
|
/** @public */
|
|
5727
|
-
export declare type SVGContainerProps =
|
|
5737
|
+
export declare type SVGContainerProps = React_3.ComponentProps<'svg'>;
|
|
5728
5738
|
|
|
5729
5739
|
/** @public */
|
|
5730
5740
|
export declare interface SvgExportContext {
|
|
@@ -5785,9 +5795,10 @@ export declare const TAB_ID: string;
|
|
|
5785
5795
|
export declare class TextManager {
|
|
5786
5796
|
editor: Editor;
|
|
5787
5797
|
private elm;
|
|
5798
|
+
private defaultStyles;
|
|
5788
5799
|
constructor(editor: Editor);
|
|
5789
|
-
private setElementStyles;
|
|
5790
5800
|
dispose(): void;
|
|
5801
|
+
private resetElmStyles;
|
|
5791
5802
|
measureText(textToMeasure: string, opts: TLMeasureTextOpts): BoxModel & {
|
|
5792
5803
|
scrollWidth: number;
|
|
5793
5804
|
};
|
|
@@ -6131,7 +6142,7 @@ export declare interface TLDragShapesOverInfo {
|
|
|
6131
6142
|
}
|
|
6132
6143
|
|
|
6133
6144
|
/** @public @react */
|
|
6134
|
-
export declare const TldrawEditor:
|
|
6145
|
+
export declare const TldrawEditor: React_2.NamedExoticComponent<TldrawEditorProps>;
|
|
6135
6146
|
|
|
6136
6147
|
/**
|
|
6137
6148
|
* Base props for the {@link tldraw#Tldraw} and {@link TldrawEditor} components.
|
|
@@ -6535,7 +6546,7 @@ export declare const tlenv: {
|
|
|
6535
6546
|
|
|
6536
6547
|
/** @public */
|
|
6537
6548
|
export declare interface TLErrorBoundaryProps {
|
|
6538
|
-
children:
|
|
6549
|
+
children: React_3.ReactNode;
|
|
6539
6550
|
onError?: ((error: unknown) => void) | null;
|
|
6540
6551
|
fallback: TLErrorFallbackComponent;
|
|
6541
6552
|
}
|
|
@@ -7429,7 +7440,7 @@ export declare interface TLTextExternalContentSource {
|
|
|
7429
7440
|
|
|
7430
7441
|
/** @public */
|
|
7431
7442
|
export declare interface TLTextOptions {
|
|
7432
|
-
tipTapConfig?:
|
|
7443
|
+
tipTapConfig?: EditorProviderProps_2;
|
|
7433
7444
|
addFontsFromNode?: RichTextFontVisitor;
|
|
7434
7445
|
}
|
|
7435
7446
|
|