tldraw 4.2.0-canary.64d1b321cd5b → 4.2.0-canary.6e26a8c97509
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.js +1 -1
- package/dist-cjs/lib/ui/components/Toolbar/DefaultRichTextToolbarContent.js +2 -1
- package/dist-cjs/lib/ui/components/Toolbar/DefaultRichTextToolbarContent.js.map +2 -2
- package/dist-cjs/lib/ui/version.js +3 -3
- package/dist-cjs/lib/ui/version.js.map +1 -1
- package/dist-esm/index.mjs +1 -1
- package/dist-esm/lib/ui/components/Toolbar/DefaultRichTextToolbarContent.mjs +2 -1
- package/dist-esm/lib/ui/components/Toolbar/DefaultRichTextToolbarContent.mjs.map +2 -2
- package/dist-esm/lib/ui/version.mjs +3 -3
- package/dist-esm/lib/ui/version.mjs.map +1 -1
- package/package.json +3 -3
- package/src/lib/ui/components/Toolbar/DefaultRichTextToolbarContent.tsx +4 -1
- package/src/lib/ui/version.ts +3 -3
package/dist-cjs/index.js
CHANGED
|
@@ -584,7 +584,7 @@ var import_buildFromV1Document = require("./lib/utils/tldr/buildFromV1Document")
|
|
|
584
584
|
var import_file = require("./lib/utils/tldr/file");
|
|
585
585
|
(0, import_editor.registerTldrawLibraryVersion)(
|
|
586
586
|
"tldraw",
|
|
587
|
-
"4.2.0-canary.
|
|
587
|
+
"4.2.0-canary.6e26a8c97509",
|
|
588
588
|
"cjs"
|
|
589
589
|
);
|
|
590
590
|
//# sourceMappingURL=index.js.map
|
|
@@ -60,6 +60,7 @@ function DefaultRichTextToolbarContent({
|
|
|
60
60
|
}, [onEditLinkStart]);
|
|
61
61
|
const actions = (0, import_react.useMemo)(() => {
|
|
62
62
|
function handleOp(name, op) {
|
|
63
|
+
if (!textEditor.view) return;
|
|
63
64
|
trackEvent("rich-text", { operation: name, source });
|
|
64
65
|
textEditor.chain().focus()[op]().run();
|
|
65
66
|
}
|
|
@@ -107,7 +108,7 @@ function DefaultRichTextToolbarContent({
|
|
|
107
108
|
].filter(Boolean);
|
|
108
109
|
}, [textEditor, trackEvent, onEditLinkStart]);
|
|
109
110
|
return actions.map(({ name, attrs, onSelect }) => {
|
|
110
|
-
const isActive = textEditor.isActive(name, attrs);
|
|
111
|
+
const isActive = textEditor.view ? textEditor.isActive(name, attrs) : false;
|
|
111
112
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
112
113
|
import_TldrawUiToolbar.TldrawUiToolbarButton,
|
|
113
114
|
{
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/ui/components/Toolbar/DefaultRichTextToolbarContent.tsx"],
|
|
4
|
-
"sourcesContent": ["import { isAccelKey, preventDefault, TiptapEditor } from '@tldraw/editor'\nimport { useEffect, useMemo, useState } from 'react'\nimport { useUiEvents } from '../../context/events'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiButtonIcon } from '../primitives/Button/TldrawUiButtonIcon'\nimport { TldrawUiToolbarButton } from '../primitives/TldrawUiToolbar'\n\n/** @public */\nexport interface DefaultRichTextToolbarContentProps {\n\tonEditLinkStart?(): void\n\ttextEditor: TiptapEditor\n}\n\n/**\n * Rich text toolbar items that have the basics.\n *\n * @public @react\n */\nexport function DefaultRichTextToolbarContent({\n\ttextEditor,\n\tonEditLinkStart,\n}: DefaultRichTextToolbarContentProps) {\n\tconst trackEvent = useUiEvents()\n\tconst msg = useTranslation()\n\tconst source = 'rich-text-menu'\n\n\t// We need to force this one to update when the editor updates or when selection changes\n\tconst [_, set] = useState(0)\n\tuseEffect(\n\t\tfunction forceUpdateWhenContentChanges() {\n\t\t\tfunction forceUpdate() {\n\t\t\t\tset((t) => t + 1)\n\t\t\t}\n\t\t\ttextEditor.on('update', forceUpdate)\n\t\t\ttextEditor.on('selectionUpdate', forceUpdate)\n\t\t},\n\t\t[textEditor]\n\t)\n\n\tuseEffect(() => {\n\t\tfunction handleKeyDown(event: KeyboardEvent) {\n\t\t\tif (onEditLinkStart && isAccelKey(event) && event.shiftKey && event.key === 'k') {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tonEditLinkStart()\n\t\t\t}\n\t\t}\n\n\t\tdocument.addEventListener('keydown', handleKeyDown)\n\t\treturn () => {\n\t\t\tdocument.removeEventListener('keydown', handleKeyDown)\n\t\t}\n\t}, [onEditLinkStart])\n\n\t// todo: we could make this a prop\n\tconst actions = useMemo(() => {\n\t\tfunction handleOp(name: string, op: string) {\n\t\t\ttrackEvent('rich-text', { operation: name as any, source })\n\t\t\t// @ts-expect-error typing this is annoying at the moment.\n\t\t\ttextEditor.chain().focus()[op]().run()\n\t\t}\n\n\t\treturn [\n\t\t\t// { name: 'heading', attrs: { level: 3 }, onSelect() { textEditor.chain().focus().toggleHeading({ level: 3}).run() }},\n\t\t\t{\n\t\t\t\tname: 'bold',\n\t\t\t\tonSelect() {\n\t\t\t\t\thandleOp('bold', 'toggleBold')\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'italic',\n\t\t\t\tonSelect() {\n\t\t\t\t\thandleOp('bold', 'toggleItalic')\n\t\t\t\t},\n\t\t\t},\n\t\t\t// { name: 'underline', onSelect() { handleOp('underline', 'toggleUnderline') }},\n\t\t\t// { name: 'strike', onSelect() { handleOp('strike', 'toggleStrike') }},\n\t\t\t{\n\t\t\t\tname: 'code',\n\t\t\t\tonSelect() {\n\t\t\t\t\thandleOp('bold', 'toggleCode')\n\t\t\t\t},\n\t\t\t},\n\t\t\tonEditLinkStart\n\t\t\t\t? {\n\t\t\t\t\t\tname: 'link',\n\t\t\t\t\t\tonSelect() {\n\t\t\t\t\t\t\tonEditLinkStart()\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t: undefined, // ? is this really optional?\n\t\t\t{\n\t\t\t\tname: 'bulletList',\n\t\t\t\tonSelect() {\n\t\t\t\t\thandleOp('bulletList', 'toggleBulletList')\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'highlight',\n\t\t\t\tonSelect() {\n\t\t\t\t\thandleOp('bulletList', 'toggleHighlight')\n\t\t\t\t},\n\t\t\t},\n\t\t].filter(Boolean) as {\n\t\t\tname: string\n\t\t\tattrs?: string\n\t\t\tonSelect(): void\n\t\t}[]\n\t}, [textEditor, trackEvent, onEditLinkStart])\n\n\treturn actions.map(({ name, attrs, onSelect }) => {\n\t\tconst isActive = textEditor.isActive(name, attrs)\n\t\treturn (\n\t\t\t<TldrawUiToolbarButton\n\t\t\t\tkey={name}\n\t\t\t\ttitle={msg(`tool.rich-text-${name}`)}\n\t\t\t\tdata-testid={`rich-text.${name}`}\n\t\t\t\ttype=\"icon\"\n\t\t\t\tisActive={isActive} // todo: we need to update this only when the text editor \"settles\", ie not during a change of selection\n\t\t\t\tonPointerDown={preventDefault}\n\t\t\t\tonClick={onSelect}\n\t\t\t\trole=\"option\"\n\t\t\t\taria-pressed={isActive}\n\t\t\t>\n\t\t\t\t<TldrawUiButtonIcon small icon={name} />\n\t\t\t</TldrawUiToolbarButton>\n\t\t)\n\t})\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
4
|
+
"sourcesContent": ["import { isAccelKey, preventDefault, TiptapEditor } from '@tldraw/editor'\nimport { useEffect, useMemo, useState } from 'react'\nimport { useUiEvents } from '../../context/events'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiButtonIcon } from '../primitives/Button/TldrawUiButtonIcon'\nimport { TldrawUiToolbarButton } from '../primitives/TldrawUiToolbar'\n\n/** @public */\nexport interface DefaultRichTextToolbarContentProps {\n\tonEditLinkStart?(): void\n\ttextEditor: TiptapEditor\n}\n\n/**\n * Rich text toolbar items that have the basics.\n *\n * @public @react\n */\nexport function DefaultRichTextToolbarContent({\n\ttextEditor,\n\tonEditLinkStart,\n}: DefaultRichTextToolbarContentProps) {\n\tconst trackEvent = useUiEvents()\n\tconst msg = useTranslation()\n\tconst source = 'rich-text-menu'\n\n\t// We need to force this one to update when the editor updates or when selection changes\n\tconst [_, set] = useState(0)\n\tuseEffect(\n\t\tfunction forceUpdateWhenContentChanges() {\n\t\t\tfunction forceUpdate() {\n\t\t\t\tset((t) => t + 1)\n\t\t\t}\n\t\t\ttextEditor.on('update', forceUpdate)\n\t\t\ttextEditor.on('selectionUpdate', forceUpdate)\n\t\t},\n\t\t[textEditor]\n\t)\n\n\tuseEffect(() => {\n\t\tfunction handleKeyDown(event: KeyboardEvent) {\n\t\t\tif (onEditLinkStart && isAccelKey(event) && event.shiftKey && event.key === 'k') {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tonEditLinkStart()\n\t\t\t}\n\t\t}\n\n\t\tdocument.addEventListener('keydown', handleKeyDown)\n\t\treturn () => {\n\t\t\tdocument.removeEventListener('keydown', handleKeyDown)\n\t\t}\n\t}, [onEditLinkStart])\n\n\t// todo: we could make this a prop\n\tconst actions = useMemo(() => {\n\t\tfunction handleOp(name: string, op: string) {\n\t\t\t// Check if the editor view is available before calling operations\n\t\t\tif (!textEditor.view) return\n\n\t\t\ttrackEvent('rich-text', { operation: name as any, source })\n\t\t\t// @ts-expect-error typing this is annoying at the moment.\n\t\t\ttextEditor.chain().focus()[op]().run()\n\t\t}\n\n\t\treturn [\n\t\t\t// { name: 'heading', attrs: { level: 3 }, onSelect() { textEditor.chain().focus().toggleHeading({ level: 3}).run() }},\n\t\t\t{\n\t\t\t\tname: 'bold',\n\t\t\t\tonSelect() {\n\t\t\t\t\thandleOp('bold', 'toggleBold')\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'italic',\n\t\t\t\tonSelect() {\n\t\t\t\t\thandleOp('bold', 'toggleItalic')\n\t\t\t\t},\n\t\t\t},\n\t\t\t// { name: 'underline', onSelect() { handleOp('underline', 'toggleUnderline') }},\n\t\t\t// { name: 'strike', onSelect() { handleOp('strike', 'toggleStrike') }},\n\t\t\t{\n\t\t\t\tname: 'code',\n\t\t\t\tonSelect() {\n\t\t\t\t\thandleOp('bold', 'toggleCode')\n\t\t\t\t},\n\t\t\t},\n\t\t\tonEditLinkStart\n\t\t\t\t? {\n\t\t\t\t\t\tname: 'link',\n\t\t\t\t\t\tonSelect() {\n\t\t\t\t\t\t\tonEditLinkStart()\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t: undefined, // ? is this really optional?\n\t\t\t{\n\t\t\t\tname: 'bulletList',\n\t\t\t\tonSelect() {\n\t\t\t\t\thandleOp('bulletList', 'toggleBulletList')\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'highlight',\n\t\t\t\tonSelect() {\n\t\t\t\t\thandleOp('bulletList', 'toggleHighlight')\n\t\t\t\t},\n\t\t\t},\n\t\t].filter(Boolean) as {\n\t\t\tname: string\n\t\t\tattrs?: string\n\t\t\tonSelect(): void\n\t\t}[]\n\t}, [textEditor, trackEvent, onEditLinkStart])\n\n\treturn actions.map(({ name, attrs, onSelect }) => {\n\t\tconst isActive = textEditor.view ? textEditor.isActive(name, attrs) : false\n\t\treturn (\n\t\t\t<TldrawUiToolbarButton\n\t\t\t\tkey={name}\n\t\t\t\ttitle={msg(`tool.rich-text-${name}`)}\n\t\t\t\tdata-testid={`rich-text.${name}`}\n\t\t\t\ttype=\"icon\"\n\t\t\t\tisActive={isActive} // todo: we need to update this only when the text editor \"settles\", ie not during a change of selection\n\t\t\t\tonPointerDown={preventDefault}\n\t\t\t\tonClick={onSelect}\n\t\t\t\trole=\"option\"\n\t\t\t\taria-pressed={isActive}\n\t\t\t>\n\t\t\t\t<TldrawUiButtonIcon small icon={name} />\n\t\t\t</TldrawUiToolbarButton>\n\t\t)\n\t})\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA+HI;AA/HJ,oBAAyD;AACzD,mBAA6C;AAC7C,oBAA4B;AAC5B,4BAA+B;AAC/B,gCAAmC;AACnC,6BAAsC;AAa/B,SAAS,8BAA8B;AAAA,EAC7C;AAAA,EACA;AACD,GAAuC;AACtC,QAAM,iBAAa,2BAAY;AAC/B,QAAM,UAAM,sCAAe;AAC3B,QAAM,SAAS;AAGf,QAAM,CAAC,GAAG,GAAG,QAAI,uBAAS,CAAC;AAC3B;AAAA,IACC,SAAS,gCAAgC;AACxC,eAAS,cAAc;AACtB,YAAI,CAAC,MAAM,IAAI,CAAC;AAAA,MACjB;AACA,iBAAW,GAAG,UAAU,WAAW;AACnC,iBAAW,GAAG,mBAAmB,WAAW;AAAA,IAC7C;AAAA,IACA,CAAC,UAAU;AAAA,EACZ;AAEA,8BAAU,MAAM;AACf,aAAS,cAAc,OAAsB;AAC5C,UAAI,uBAAmB,0BAAW,KAAK,KAAK,MAAM,YAAY,MAAM,QAAQ,KAAK;AAChF,cAAM,eAAe;AACrB,wBAAgB;AAAA,MACjB;AAAA,IACD;AAEA,aAAS,iBAAiB,WAAW,aAAa;AAClD,WAAO,MAAM;AACZ,eAAS,oBAAoB,WAAW,aAAa;AAAA,IACtD;AAAA,EACD,GAAG,CAAC,eAAe,CAAC;AAGpB,QAAM,cAAU,sBAAQ,MAAM;AAC7B,aAAS,SAAS,MAAc,IAAY;AAE3C,UAAI,CAAC,WAAW,KAAM;AAEtB,iBAAW,aAAa,EAAE,WAAW,MAAa,OAAO,CAAC;AAE1D,iBAAW,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI;AAAA,IACtC;AAEA,WAAO;AAAA;AAAA,MAEN;AAAA,QACC,MAAM;AAAA,QACN,WAAW;AACV,mBAAS,QAAQ,YAAY;AAAA,QAC9B;AAAA,MACD;AAAA,MACA;AAAA,QACC,MAAM;AAAA,QACN,WAAW;AACV,mBAAS,QAAQ,cAAc;AAAA,QAChC;AAAA,MACD;AAAA;AAAA;AAAA,MAGA;AAAA,QACC,MAAM;AAAA,QACN,WAAW;AACV,mBAAS,QAAQ,YAAY;AAAA,QAC9B;AAAA,MACD;AAAA,MACA,kBACG;AAAA,QACA,MAAM;AAAA,QACN,WAAW;AACV,0BAAgB;AAAA,QACjB;AAAA,MACD,IACC;AAAA;AAAA,MACH;AAAA,QACC,MAAM;AAAA,QACN,WAAW;AACV,mBAAS,cAAc,kBAAkB;AAAA,QAC1C;AAAA,MACD;AAAA,MACA;AAAA,QACC,MAAM;AAAA,QACN,WAAW;AACV,mBAAS,cAAc,iBAAiB;AAAA,QACzC;AAAA,MACD;AAAA,IACD,EAAE,OAAO,OAAO;AAAA,EAKjB,GAAG,CAAC,YAAY,YAAY,eAAe,CAAC;AAE5C,SAAO,QAAQ,IAAI,CAAC,EAAE,MAAM,OAAO,SAAS,MAAM;AACjD,UAAM,WAAW,WAAW,OAAO,WAAW,SAAS,MAAM,KAAK,IAAI;AACtE,WACC;AAAA,MAAC;AAAA;AAAA,QAEA,OAAO,IAAI,kBAAkB,IAAI,EAAE;AAAA,QACnC,eAAa,aAAa,IAAI;AAAA,QAC9B,MAAK;AAAA,QACL;AAAA,QACA,eAAe;AAAA,QACf,SAAS;AAAA,QACT,MAAK;AAAA,QACL,gBAAc;AAAA,QAEd,sDAAC,gDAAmB,OAAK,MAAC,MAAM,MAAM;AAAA;AAAA,MAVjC;AAAA,IAWN;AAAA,EAEF,CAAC;AACF;",
|
|
6
6
|
"names": []
|
|
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 = "4.2.0-canary.
|
|
25
|
+
const version = "4.2.0-canary.6e26a8c97509";
|
|
26
26
|
const publishDates = {
|
|
27
27
|
major: "2025-09-18T14:39:22.803Z",
|
|
28
|
-
minor: "2025-
|
|
29
|
-
patch: "2025-
|
|
28
|
+
minor: "2025-11-04T11:36:50.406Z",
|
|
29
|
+
patch: "2025-11-04T11:36:50.406Z"
|
|
30
30
|
};
|
|
31
31
|
//# sourceMappingURL=version.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/ui/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 = '4.2.0-canary.
|
|
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 = '4.2.0-canary.6e26a8c97509'\nexport const publishDates = {\n\tmajor: '2025-09-18T14:39:22.803Z',\n\tminor: '2025-11-04T11:36:50.406Z',\n\tpatch: '2025-11-04T11:36:50.406Z',\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.mjs
CHANGED
|
@@ -37,6 +37,7 @@ function DefaultRichTextToolbarContent({
|
|
|
37
37
|
}, [onEditLinkStart]);
|
|
38
38
|
const actions = useMemo(() => {
|
|
39
39
|
function handleOp(name, op) {
|
|
40
|
+
if (!textEditor.view) return;
|
|
40
41
|
trackEvent("rich-text", { operation: name, source });
|
|
41
42
|
textEditor.chain().focus()[op]().run();
|
|
42
43
|
}
|
|
@@ -84,7 +85,7 @@ function DefaultRichTextToolbarContent({
|
|
|
84
85
|
].filter(Boolean);
|
|
85
86
|
}, [textEditor, trackEvent, onEditLinkStart]);
|
|
86
87
|
return actions.map(({ name, attrs, onSelect }) => {
|
|
87
|
-
const isActive = textEditor.isActive(name, attrs);
|
|
88
|
+
const isActive = textEditor.view ? textEditor.isActive(name, attrs) : false;
|
|
88
89
|
return /* @__PURE__ */ jsx(
|
|
89
90
|
TldrawUiToolbarButton,
|
|
90
91
|
{
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/ui/components/Toolbar/DefaultRichTextToolbarContent.tsx"],
|
|
4
|
-
"sourcesContent": ["import { isAccelKey, preventDefault, TiptapEditor } from '@tldraw/editor'\nimport { useEffect, useMemo, useState } from 'react'\nimport { useUiEvents } from '../../context/events'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiButtonIcon } from '../primitives/Button/TldrawUiButtonIcon'\nimport { TldrawUiToolbarButton } from '../primitives/TldrawUiToolbar'\n\n/** @public */\nexport interface DefaultRichTextToolbarContentProps {\n\tonEditLinkStart?(): void\n\ttextEditor: TiptapEditor\n}\n\n/**\n * Rich text toolbar items that have the basics.\n *\n * @public @react\n */\nexport function DefaultRichTextToolbarContent({\n\ttextEditor,\n\tonEditLinkStart,\n}: DefaultRichTextToolbarContentProps) {\n\tconst trackEvent = useUiEvents()\n\tconst msg = useTranslation()\n\tconst source = 'rich-text-menu'\n\n\t// We need to force this one to update when the editor updates or when selection changes\n\tconst [_, set] = useState(0)\n\tuseEffect(\n\t\tfunction forceUpdateWhenContentChanges() {\n\t\t\tfunction forceUpdate() {\n\t\t\t\tset((t) => t + 1)\n\t\t\t}\n\t\t\ttextEditor.on('update', forceUpdate)\n\t\t\ttextEditor.on('selectionUpdate', forceUpdate)\n\t\t},\n\t\t[textEditor]\n\t)\n\n\tuseEffect(() => {\n\t\tfunction handleKeyDown(event: KeyboardEvent) {\n\t\t\tif (onEditLinkStart && isAccelKey(event) && event.shiftKey && event.key === 'k') {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tonEditLinkStart()\n\t\t\t}\n\t\t}\n\n\t\tdocument.addEventListener('keydown', handleKeyDown)\n\t\treturn () => {\n\t\t\tdocument.removeEventListener('keydown', handleKeyDown)\n\t\t}\n\t}, [onEditLinkStart])\n\n\t// todo: we could make this a prop\n\tconst actions = useMemo(() => {\n\t\tfunction handleOp(name: string, op: string) {\n\t\t\ttrackEvent('rich-text', { operation: name as any, source })\n\t\t\t// @ts-expect-error typing this is annoying at the moment.\n\t\t\ttextEditor.chain().focus()[op]().run()\n\t\t}\n\n\t\treturn [\n\t\t\t// { name: 'heading', attrs: { level: 3 }, onSelect() { textEditor.chain().focus().toggleHeading({ level: 3}).run() }},\n\t\t\t{\n\t\t\t\tname: 'bold',\n\t\t\t\tonSelect() {\n\t\t\t\t\thandleOp('bold', 'toggleBold')\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'italic',\n\t\t\t\tonSelect() {\n\t\t\t\t\thandleOp('bold', 'toggleItalic')\n\t\t\t\t},\n\t\t\t},\n\t\t\t// { name: 'underline', onSelect() { handleOp('underline', 'toggleUnderline') }},\n\t\t\t// { name: 'strike', onSelect() { handleOp('strike', 'toggleStrike') }},\n\t\t\t{\n\t\t\t\tname: 'code',\n\t\t\t\tonSelect() {\n\t\t\t\t\thandleOp('bold', 'toggleCode')\n\t\t\t\t},\n\t\t\t},\n\t\t\tonEditLinkStart\n\t\t\t\t? {\n\t\t\t\t\t\tname: 'link',\n\t\t\t\t\t\tonSelect() {\n\t\t\t\t\t\t\tonEditLinkStart()\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t: undefined, // ? is this really optional?\n\t\t\t{\n\t\t\t\tname: 'bulletList',\n\t\t\t\tonSelect() {\n\t\t\t\t\thandleOp('bulletList', 'toggleBulletList')\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'highlight',\n\t\t\t\tonSelect() {\n\t\t\t\t\thandleOp('bulletList', 'toggleHighlight')\n\t\t\t\t},\n\t\t\t},\n\t\t].filter(Boolean) as {\n\t\t\tname: string\n\t\t\tattrs?: string\n\t\t\tonSelect(): void\n\t\t}[]\n\t}, [textEditor, trackEvent, onEditLinkStart])\n\n\treturn actions.map(({ name, attrs, onSelect }) => {\n\t\tconst isActive = textEditor.isActive(name, attrs)\n\t\treturn (\n\t\t\t<TldrawUiToolbarButton\n\t\t\t\tkey={name}\n\t\t\t\ttitle={msg(`tool.rich-text-${name}`)}\n\t\t\t\tdata-testid={`rich-text.${name}`}\n\t\t\t\ttype=\"icon\"\n\t\t\t\tisActive={isActive} // todo: we need to update this only when the text editor \"settles\", ie not during a change of selection\n\t\t\t\tonPointerDown={preventDefault}\n\t\t\t\tonClick={onSelect}\n\t\t\t\trole=\"option\"\n\t\t\t\taria-pressed={isActive}\n\t\t\t>\n\t\t\t\t<TldrawUiButtonIcon small icon={name} />\n\t\t\t</TldrawUiToolbarButton>\n\t\t)\n\t})\n}\n"],
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["import { isAccelKey, preventDefault, TiptapEditor } from '@tldraw/editor'\nimport { useEffect, useMemo, useState } from 'react'\nimport { useUiEvents } from '../../context/events'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiButtonIcon } from '../primitives/Button/TldrawUiButtonIcon'\nimport { TldrawUiToolbarButton } from '../primitives/TldrawUiToolbar'\n\n/** @public */\nexport interface DefaultRichTextToolbarContentProps {\n\tonEditLinkStart?(): void\n\ttextEditor: TiptapEditor\n}\n\n/**\n * Rich text toolbar items that have the basics.\n *\n * @public @react\n */\nexport function DefaultRichTextToolbarContent({\n\ttextEditor,\n\tonEditLinkStart,\n}: DefaultRichTextToolbarContentProps) {\n\tconst trackEvent = useUiEvents()\n\tconst msg = useTranslation()\n\tconst source = 'rich-text-menu'\n\n\t// We need to force this one to update when the editor updates or when selection changes\n\tconst [_, set] = useState(0)\n\tuseEffect(\n\t\tfunction forceUpdateWhenContentChanges() {\n\t\t\tfunction forceUpdate() {\n\t\t\t\tset((t) => t + 1)\n\t\t\t}\n\t\t\ttextEditor.on('update', forceUpdate)\n\t\t\ttextEditor.on('selectionUpdate', forceUpdate)\n\t\t},\n\t\t[textEditor]\n\t)\n\n\tuseEffect(() => {\n\t\tfunction handleKeyDown(event: KeyboardEvent) {\n\t\t\tif (onEditLinkStart && isAccelKey(event) && event.shiftKey && event.key === 'k') {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tonEditLinkStart()\n\t\t\t}\n\t\t}\n\n\t\tdocument.addEventListener('keydown', handleKeyDown)\n\t\treturn () => {\n\t\t\tdocument.removeEventListener('keydown', handleKeyDown)\n\t\t}\n\t}, [onEditLinkStart])\n\n\t// todo: we could make this a prop\n\tconst actions = useMemo(() => {\n\t\tfunction handleOp(name: string, op: string) {\n\t\t\t// Check if the editor view is available before calling operations\n\t\t\tif (!textEditor.view) return\n\n\t\t\ttrackEvent('rich-text', { operation: name as any, source })\n\t\t\t// @ts-expect-error typing this is annoying at the moment.\n\t\t\ttextEditor.chain().focus()[op]().run()\n\t\t}\n\n\t\treturn [\n\t\t\t// { name: 'heading', attrs: { level: 3 }, onSelect() { textEditor.chain().focus().toggleHeading({ level: 3}).run() }},\n\t\t\t{\n\t\t\t\tname: 'bold',\n\t\t\t\tonSelect() {\n\t\t\t\t\thandleOp('bold', 'toggleBold')\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'italic',\n\t\t\t\tonSelect() {\n\t\t\t\t\thandleOp('bold', 'toggleItalic')\n\t\t\t\t},\n\t\t\t},\n\t\t\t// { name: 'underline', onSelect() { handleOp('underline', 'toggleUnderline') }},\n\t\t\t// { name: 'strike', onSelect() { handleOp('strike', 'toggleStrike') }},\n\t\t\t{\n\t\t\t\tname: 'code',\n\t\t\t\tonSelect() {\n\t\t\t\t\thandleOp('bold', 'toggleCode')\n\t\t\t\t},\n\t\t\t},\n\t\t\tonEditLinkStart\n\t\t\t\t? {\n\t\t\t\t\t\tname: 'link',\n\t\t\t\t\t\tonSelect() {\n\t\t\t\t\t\t\tonEditLinkStart()\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t: undefined, // ? is this really optional?\n\t\t\t{\n\t\t\t\tname: 'bulletList',\n\t\t\t\tonSelect() {\n\t\t\t\t\thandleOp('bulletList', 'toggleBulletList')\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'highlight',\n\t\t\t\tonSelect() {\n\t\t\t\t\thandleOp('bulletList', 'toggleHighlight')\n\t\t\t\t},\n\t\t\t},\n\t\t].filter(Boolean) as {\n\t\t\tname: string\n\t\t\tattrs?: string\n\t\t\tonSelect(): void\n\t\t}[]\n\t}, [textEditor, trackEvent, onEditLinkStart])\n\n\treturn actions.map(({ name, attrs, onSelect }) => {\n\t\tconst isActive = textEditor.view ? textEditor.isActive(name, attrs) : false\n\t\treturn (\n\t\t\t<TldrawUiToolbarButton\n\t\t\t\tkey={name}\n\t\t\t\ttitle={msg(`tool.rich-text-${name}`)}\n\t\t\t\tdata-testid={`rich-text.${name}`}\n\t\t\t\ttype=\"icon\"\n\t\t\t\tisActive={isActive} // todo: we need to update this only when the text editor \"settles\", ie not during a change of selection\n\t\t\t\tonPointerDown={preventDefault}\n\t\t\t\tonClick={onSelect}\n\t\t\t\trole=\"option\"\n\t\t\t\taria-pressed={isActive}\n\t\t\t>\n\t\t\t\t<TldrawUiButtonIcon small icon={name} />\n\t\t\t</TldrawUiToolbarButton>\n\t\t)\n\t})\n}\n"],
|
|
5
|
+
"mappings": "AA+HI;AA/HJ,SAAS,YAAY,sBAAoC;AACzD,SAAS,WAAW,SAAS,gBAAgB;AAC7C,SAAS,mBAAmB;AAC5B,SAAS,sBAAsB;AAC/B,SAAS,0BAA0B;AACnC,SAAS,6BAA6B;AAa/B,SAAS,8BAA8B;AAAA,EAC7C;AAAA,EACA;AACD,GAAuC;AACtC,QAAM,aAAa,YAAY;AAC/B,QAAM,MAAM,eAAe;AAC3B,QAAM,SAAS;AAGf,QAAM,CAAC,GAAG,GAAG,IAAI,SAAS,CAAC;AAC3B;AAAA,IACC,SAAS,gCAAgC;AACxC,eAAS,cAAc;AACtB,YAAI,CAAC,MAAM,IAAI,CAAC;AAAA,MACjB;AACA,iBAAW,GAAG,UAAU,WAAW;AACnC,iBAAW,GAAG,mBAAmB,WAAW;AAAA,IAC7C;AAAA,IACA,CAAC,UAAU;AAAA,EACZ;AAEA,YAAU,MAAM;AACf,aAAS,cAAc,OAAsB;AAC5C,UAAI,mBAAmB,WAAW,KAAK,KAAK,MAAM,YAAY,MAAM,QAAQ,KAAK;AAChF,cAAM,eAAe;AACrB,wBAAgB;AAAA,MACjB;AAAA,IACD;AAEA,aAAS,iBAAiB,WAAW,aAAa;AAClD,WAAO,MAAM;AACZ,eAAS,oBAAoB,WAAW,aAAa;AAAA,IACtD;AAAA,EACD,GAAG,CAAC,eAAe,CAAC;AAGpB,QAAM,UAAU,QAAQ,MAAM;AAC7B,aAAS,SAAS,MAAc,IAAY;AAE3C,UAAI,CAAC,WAAW,KAAM;AAEtB,iBAAW,aAAa,EAAE,WAAW,MAAa,OAAO,CAAC;AAE1D,iBAAW,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI;AAAA,IACtC;AAEA,WAAO;AAAA;AAAA,MAEN;AAAA,QACC,MAAM;AAAA,QACN,WAAW;AACV,mBAAS,QAAQ,YAAY;AAAA,QAC9B;AAAA,MACD;AAAA,MACA;AAAA,QACC,MAAM;AAAA,QACN,WAAW;AACV,mBAAS,QAAQ,cAAc;AAAA,QAChC;AAAA,MACD;AAAA;AAAA;AAAA,MAGA;AAAA,QACC,MAAM;AAAA,QACN,WAAW;AACV,mBAAS,QAAQ,YAAY;AAAA,QAC9B;AAAA,MACD;AAAA,MACA,kBACG;AAAA,QACA,MAAM;AAAA,QACN,WAAW;AACV,0BAAgB;AAAA,QACjB;AAAA,MACD,IACC;AAAA;AAAA,MACH;AAAA,QACC,MAAM;AAAA,QACN,WAAW;AACV,mBAAS,cAAc,kBAAkB;AAAA,QAC1C;AAAA,MACD;AAAA,MACA;AAAA,QACC,MAAM;AAAA,QACN,WAAW;AACV,mBAAS,cAAc,iBAAiB;AAAA,QACzC;AAAA,MACD;AAAA,IACD,EAAE,OAAO,OAAO;AAAA,EAKjB,GAAG,CAAC,YAAY,YAAY,eAAe,CAAC;AAE5C,SAAO,QAAQ,IAAI,CAAC,EAAE,MAAM,OAAO,SAAS,MAAM;AACjD,UAAM,WAAW,WAAW,OAAO,WAAW,SAAS,MAAM,KAAK,IAAI;AACtE,WACC;AAAA,MAAC;AAAA;AAAA,QAEA,OAAO,IAAI,kBAAkB,IAAI,EAAE;AAAA,QACnC,eAAa,aAAa,IAAI;AAAA,QAC9B,MAAK;AAAA,QACL;AAAA,QACA,eAAe;AAAA,QACf,SAAS;AAAA,QACT,MAAK;AAAA,QACL,gBAAc;AAAA,QAEd,8BAAC,sBAAmB,OAAK,MAAC,MAAM,MAAM;AAAA;AAAA,MAVjC;AAAA,IAWN;AAAA,EAEF,CAAC;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
const version = "4.2.0-canary.
|
|
1
|
+
const version = "4.2.0-canary.6e26a8c97509";
|
|
2
2
|
const publishDates = {
|
|
3
3
|
major: "2025-09-18T14:39:22.803Z",
|
|
4
|
-
minor: "2025-
|
|
5
|
-
patch: "2025-
|
|
4
|
+
minor: "2025-11-04T11:36:50.406Z",
|
|
5
|
+
patch: "2025-11-04T11:36:50.406Z"
|
|
6
6
|
};
|
|
7
7
|
export {
|
|
8
8
|
publishDates,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/ui/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 = '4.2.0-canary.
|
|
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 = '4.2.0-canary.6e26a8c97509'\nexport const publishDates = {\n\tmajor: '2025-09-18T14:39:22.803Z',\n\tminor: '2025-11-04T11:36:50.406Z',\n\tpatch: '2025-11-04T11:36:50.406Z',\n}\n"],
|
|
5
5
|
"mappings": "AAGO,MAAM,UAAU;AAChB,MAAM,eAAe;AAAA,EAC3B,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AACR;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tldraw",
|
|
3
3
|
"description": "A tiny little drawing editor.",
|
|
4
|
-
"version": "4.2.0-canary.
|
|
4
|
+
"version": "4.2.0-canary.6e26a8c97509",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "tldraw Inc.",
|
|
7
7
|
"email": "hello@tldraw.com"
|
|
@@ -62,8 +62,8 @@
|
|
|
62
62
|
"@tiptap/pm": "3.6.2",
|
|
63
63
|
"@tiptap/react": "3.6.2",
|
|
64
64
|
"@tiptap/starter-kit": "3.6.2",
|
|
65
|
-
"@tldraw/editor": "4.2.0-canary.
|
|
66
|
-
"@tldraw/store": "4.2.0-canary.
|
|
65
|
+
"@tldraw/editor": "4.2.0-canary.6e26a8c97509",
|
|
66
|
+
"@tldraw/store": "4.2.0-canary.6e26a8c97509",
|
|
67
67
|
"classnames": "^2.5.1",
|
|
68
68
|
"hotkeys-js": "^3.13.9",
|
|
69
69
|
"idb": "^7.1.1",
|
|
@@ -54,6 +54,9 @@ export function DefaultRichTextToolbarContent({
|
|
|
54
54
|
// todo: we could make this a prop
|
|
55
55
|
const actions = useMemo(() => {
|
|
56
56
|
function handleOp(name: string, op: string) {
|
|
57
|
+
// Check if the editor view is available before calling operations
|
|
58
|
+
if (!textEditor.view) return
|
|
59
|
+
|
|
57
60
|
trackEvent('rich-text', { operation: name as any, source })
|
|
58
61
|
// @ts-expect-error typing this is annoying at the moment.
|
|
59
62
|
textEditor.chain().focus()[op]().run()
|
|
@@ -109,7 +112,7 @@ export function DefaultRichTextToolbarContent({
|
|
|
109
112
|
}, [textEditor, trackEvent, onEditLinkStart])
|
|
110
113
|
|
|
111
114
|
return actions.map(({ name, attrs, onSelect }) => {
|
|
112
|
-
const isActive = textEditor.isActive(name, attrs)
|
|
115
|
+
const isActive = textEditor.view ? textEditor.isActive(name, attrs) : false
|
|
113
116
|
return (
|
|
114
117
|
<TldrawUiToolbarButton
|
|
115
118
|
key={name}
|
package/src/lib/ui/version.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// This file is automatically generated by internal/scripts/refresh-assets.ts.
|
|
2
2
|
// Do not edit manually. Or do, I'm a comment, not a cop.
|
|
3
3
|
|
|
4
|
-
export const version = '4.2.0-canary.
|
|
4
|
+
export const version = '4.2.0-canary.6e26a8c97509'
|
|
5
5
|
export const publishDates = {
|
|
6
6
|
major: '2025-09-18T14:39:22.803Z',
|
|
7
|
-
minor: '2025-
|
|
8
|
-
patch: '2025-
|
|
7
|
+
minor: '2025-11-04T11:36:50.406Z',
|
|
8
|
+
patch: '2025-11-04T11:36:50.406Z',
|
|
9
9
|
}
|