@tldraw/editor 4.4.0 → 4.5.0-canary.a4eece45e3d0

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.
Files changed (224) hide show
  1. package/dist-cjs/index.d.ts +29 -11
  2. package/dist-cjs/index.js +4 -7
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/TldrawEditor.js +4 -3
  5. package/dist-cjs/lib/TldrawEditor.js.map +2 -2
  6. package/dist-cjs/lib/components/ErrorBoundary.js.map +1 -1
  7. package/dist-cjs/lib/components/LiveCollaborators.js +2 -2
  8. package/dist-cjs/lib/components/LiveCollaborators.js.map +2 -2
  9. package/dist-cjs/lib/components/Shape.js +2 -2
  10. package/dist-cjs/lib/components/Shape.js.map +2 -2
  11. package/dist-cjs/lib/components/default-components/DefaultCanvas.js +15 -15
  12. package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
  13. package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js +5 -6
  14. package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js.map +2 -2
  15. package/dist-cjs/lib/components/default-components/DefaultLoadingScreen.js +3 -4
  16. package/dist-cjs/lib/components/default-components/DefaultLoadingScreen.js.map +2 -2
  17. package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js +2 -2
  18. package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js.map +2 -2
  19. package/dist-cjs/lib/components/default-components/DefaultShapeIndicators.js +2 -2
  20. package/dist-cjs/lib/components/default-components/DefaultShapeIndicators.js.map +2 -2
  21. package/dist-cjs/lib/config/TLSessionStateSnapshot.js +3 -2
  22. package/dist-cjs/lib/config/TLSessionStateSnapshot.js.map +2 -2
  23. package/dist-cjs/lib/editor/Editor.js +12 -0
  24. package/dist-cjs/lib/editor/Editor.js.map +2 -2
  25. package/dist-cjs/lib/editor/bindings/BindingUtil.js.map +1 -1
  26. package/dist-cjs/lib/editor/derivations/bindingsIndex.js.map +1 -1
  27. package/dist-cjs/lib/editor/derivations/notVisibleShapes.js.map +1 -1
  28. package/dist-cjs/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.js.map +1 -1
  29. package/dist-cjs/lib/editor/managers/FontManager/FontManager.js.map +1 -1
  30. package/dist-cjs/lib/editor/managers/InputsManager/InputsManager.js.map +1 -1
  31. package/dist-cjs/lib/editor/managers/ScribbleManager/ScribbleManager.js.map +1 -1
  32. package/dist-cjs/lib/editor/managers/SnapManager/BoundsSnaps.js.map +1 -1
  33. package/dist-cjs/lib/editor/managers/SnapManager/HandleSnaps.js.map +1 -1
  34. package/dist-cjs/lib/editor/managers/TextManager/TextManager.js.map +1 -1
  35. package/dist-cjs/lib/editor/managers/TickManager/TickManager.js.map +1 -1
  36. package/dist-cjs/lib/editor/shapes/shared/resizeBox.js.map +1 -1
  37. package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/children/Pointing.js.map +1 -1
  38. package/dist-cjs/lib/editor/types/SvgExportContext.js.map +1 -1
  39. package/dist-cjs/lib/exports/exportToSvg.js.map +1 -1
  40. package/dist-cjs/lib/exports/getSvgJsx.js.map +1 -1
  41. package/dist-cjs/lib/{utils/hardResetEditor.js → hooks/EditorComponentsContext.js} +14 -8
  42. package/dist-cjs/lib/hooks/EditorComponentsContext.js.map +7 -0
  43. package/dist-cjs/lib/hooks/useCanvasEvents.js +10 -2
  44. package/dist-cjs/lib/hooks/useCanvasEvents.js.map +2 -2
  45. package/dist-cjs/lib/hooks/useEditor.js.map +1 -1
  46. package/dist-cjs/lib/hooks/useEditorComponents.js +4 -10
  47. package/dist-cjs/lib/hooks/useEditorComponents.js.map +3 -3
  48. package/dist-cjs/lib/options.js +2 -1
  49. package/dist-cjs/lib/options.js.map +2 -2
  50. package/dist-cjs/lib/primitives/Vec.js +10 -5
  51. package/dist-cjs/lib/primitives/Vec.js.map +2 -2
  52. package/dist-cjs/lib/utils/areShapesContentEqual.js +3 -1
  53. package/dist-cjs/lib/utils/areShapesContentEqual.js.map +2 -2
  54. package/dist-cjs/lib/utils/assets.js +4 -6
  55. package/dist-cjs/lib/utils/assets.js.map +2 -2
  56. package/dist-cjs/lib/utils/browserCanvasMaxSize.js +1 -2
  57. package/dist-cjs/lib/utils/browserCanvasMaxSize.js.map +2 -2
  58. package/dist-cjs/lib/utils/debug-flags.js.map +2 -2
  59. package/dist-cjs/lib/utils/deepLinks.js.map +1 -1
  60. package/dist-cjs/lib/utils/dom.js +3 -3
  61. package/dist-cjs/lib/utils/dom.js.map +2 -2
  62. package/dist-cjs/lib/utils/getIncrementedName.js +1 -1
  63. package/dist-cjs/lib/utils/getIncrementedName.js.map +2 -2
  64. package/dist-cjs/lib/utils/getPointerInfo.js.map +2 -2
  65. package/dist-cjs/lib/utils/getSvgPathFromPoints.js.map +1 -1
  66. package/dist-cjs/lib/utils/keyboard.js +2 -2
  67. package/dist-cjs/lib/utils/keyboard.js.map +2 -2
  68. package/dist-cjs/lib/utils/normalizeWheel.js +2 -5
  69. package/dist-cjs/lib/utils/normalizeWheel.js.map +2 -2
  70. package/dist-cjs/lib/utils/reorderShapes.js +6 -6
  71. package/dist-cjs/lib/utils/reorderShapes.js.map +2 -2
  72. package/dist-cjs/lib/utils/reparenting.js +3 -4
  73. package/dist-cjs/lib/utils/reparenting.js.map +2 -2
  74. package/dist-cjs/lib/utils/richText.js.map +1 -1
  75. package/dist-cjs/lib/utils/rotation.js.map +1 -1
  76. package/dist-cjs/lib/utils/runtime.js +12 -0
  77. package/dist-cjs/lib/utils/runtime.js.map +2 -2
  78. package/dist-cjs/version.js +3 -3
  79. package/dist-cjs/version.js.map +1 -1
  80. package/dist-esm/index.d.mts +29 -11
  81. package/dist-esm/index.mjs +8 -5
  82. package/dist-esm/index.mjs.map +2 -2
  83. package/dist-esm/lib/TldrawEditor.mjs +2 -4
  84. package/dist-esm/lib/TldrawEditor.mjs.map +2 -2
  85. package/dist-esm/lib/components/ErrorBoundary.mjs.map +1 -1
  86. package/dist-esm/lib/components/LiveCollaborators.mjs +1 -1
  87. package/dist-esm/lib/components/LiveCollaborators.mjs.map +2 -2
  88. package/dist-esm/lib/components/Shape.mjs +1 -1
  89. package/dist-esm/lib/components/Shape.mjs.map +2 -2
  90. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +1 -1
  91. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
  92. package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs +2 -3
  93. package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs.map +2 -2
  94. package/dist-esm/lib/components/default-components/DefaultLoadingScreen.mjs +2 -3
  95. package/dist-esm/lib/components/default-components/DefaultLoadingScreen.mjs.map +2 -2
  96. package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs +1 -1
  97. package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs.map +2 -2
  98. package/dist-esm/lib/components/default-components/DefaultShapeIndicators.mjs +1 -1
  99. package/dist-esm/lib/components/default-components/DefaultShapeIndicators.mjs.map +2 -2
  100. package/dist-esm/lib/config/TLSessionStateSnapshot.mjs +3 -2
  101. package/dist-esm/lib/config/TLSessionStateSnapshot.mjs.map +2 -2
  102. package/dist-esm/lib/editor/Editor.mjs +12 -0
  103. package/dist-esm/lib/editor/Editor.mjs.map +2 -2
  104. package/dist-esm/lib/editor/bindings/BindingUtil.mjs.map +1 -1
  105. package/dist-esm/lib/editor/derivations/bindingsIndex.mjs.map +1 -1
  106. package/dist-esm/lib/editor/derivations/notVisibleShapes.mjs.map +1 -1
  107. package/dist-esm/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.mjs.map +1 -1
  108. package/dist-esm/lib/editor/managers/FontManager/FontManager.mjs.map +1 -1
  109. package/dist-esm/lib/editor/managers/InputsManager/InputsManager.mjs.map +1 -1
  110. package/dist-esm/lib/editor/managers/ScribbleManager/ScribbleManager.mjs.map +1 -1
  111. package/dist-esm/lib/editor/managers/SnapManager/BoundsSnaps.mjs.map +1 -1
  112. package/dist-esm/lib/editor/managers/SnapManager/HandleSnaps.mjs.map +1 -1
  113. package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs.map +1 -1
  114. package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs.map +1 -1
  115. package/dist-esm/lib/editor/shapes/shared/resizeBox.mjs.map +1 -1
  116. package/dist-esm/lib/editor/tools/BaseBoxShapeTool/children/Pointing.mjs.map +1 -1
  117. package/dist-esm/lib/editor/types/SvgExportContext.mjs.map +1 -1
  118. package/dist-esm/lib/exports/exportToSvg.mjs.map +1 -1
  119. package/dist-esm/lib/exports/getSvgJsx.mjs.map +1 -1
  120. package/dist-esm/lib/hooks/EditorComponentsContext.mjs +14 -0
  121. package/dist-esm/lib/hooks/EditorComponentsContext.mjs.map +7 -0
  122. package/dist-esm/lib/hooks/useCanvasEvents.mjs +10 -2
  123. package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +2 -2
  124. package/dist-esm/lib/hooks/useEditor.mjs.map +1 -1
  125. package/dist-esm/lib/hooks/useEditorComponents.mjs +12 -36
  126. package/dist-esm/lib/hooks/useEditorComponents.mjs.map +2 -2
  127. package/dist-esm/lib/options.mjs +2 -1
  128. package/dist-esm/lib/options.mjs.map +2 -2
  129. package/dist-esm/lib/primitives/Vec.mjs +6 -1
  130. package/dist-esm/lib/primitives/Vec.mjs.map +2 -2
  131. package/dist-esm/lib/utils/areShapesContentEqual.mjs +3 -1
  132. package/dist-esm/lib/utils/areShapesContentEqual.mjs.map +2 -2
  133. package/dist-esm/lib/utils/assets.mjs +4 -6
  134. package/dist-esm/lib/utils/assets.mjs.map +2 -2
  135. package/dist-esm/lib/utils/browserCanvasMaxSize.mjs +1 -2
  136. package/dist-esm/lib/utils/browserCanvasMaxSize.mjs.map +2 -2
  137. package/dist-esm/lib/utils/debug-flags.mjs.map +2 -2
  138. package/dist-esm/lib/utils/deepLinks.mjs.map +1 -1
  139. package/dist-esm/lib/utils/dom.mjs +3 -3
  140. package/dist-esm/lib/utils/dom.mjs.map +2 -2
  141. package/dist-esm/lib/utils/getIncrementedName.mjs +1 -1
  142. package/dist-esm/lib/utils/getIncrementedName.mjs.map +2 -2
  143. package/dist-esm/lib/utils/getPointerInfo.mjs.map +2 -2
  144. package/dist-esm/lib/utils/getSvgPathFromPoints.mjs.map +1 -1
  145. package/dist-esm/lib/utils/keyboard.mjs +2 -2
  146. package/dist-esm/lib/utils/keyboard.mjs.map +2 -2
  147. package/dist-esm/lib/utils/normalizeWheel.mjs +2 -5
  148. package/dist-esm/lib/utils/normalizeWheel.mjs.map +2 -2
  149. package/dist-esm/lib/utils/reorderShapes.mjs +6 -6
  150. package/dist-esm/lib/utils/reorderShapes.mjs.map +2 -2
  151. package/dist-esm/lib/utils/reparenting.mjs +3 -4
  152. package/dist-esm/lib/utils/reparenting.mjs.map +2 -2
  153. package/dist-esm/lib/utils/richText.mjs.map +1 -1
  154. package/dist-esm/lib/utils/rotation.mjs.map +1 -1
  155. package/dist-esm/lib/utils/runtime.mjs +12 -0
  156. package/dist-esm/lib/utils/runtime.mjs.map +2 -2
  157. package/dist-esm/version.mjs +3 -3
  158. package/dist-esm/version.mjs.map +1 -1
  159. package/package.json +7 -7
  160. package/src/index.ts +7 -4
  161. package/src/lib/TldrawEditor.tsx +3 -5
  162. package/src/lib/components/ErrorBoundary.tsx +1 -1
  163. package/src/lib/components/LiveCollaborators.tsx +1 -1
  164. package/src/lib/components/Shape.tsx +1 -1
  165. package/src/lib/components/default-components/DefaultCanvas.tsx +1 -1
  166. package/src/lib/components/default-components/DefaultErrorFallback.tsx +2 -3
  167. package/src/lib/components/default-components/DefaultLoadingScreen.tsx +6 -3
  168. package/src/lib/components/default-components/DefaultShapeIndicator.tsx +1 -1
  169. package/src/lib/components/default-components/DefaultShapeIndicators.tsx +1 -1
  170. package/src/lib/config/TLSessionStateSnapshot.ts +3 -2
  171. package/src/lib/editor/Editor.ts +16 -0
  172. package/src/lib/editor/bindings/BindingUtil.ts +1 -1
  173. package/src/lib/editor/derivations/bindingsIndex.ts +1 -1
  174. package/src/lib/editor/derivations/notVisibleShapes.ts +1 -1
  175. package/src/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.ts +1 -1
  176. package/src/lib/editor/managers/FontManager/FontManager.ts +1 -1
  177. package/src/lib/editor/managers/InputsManager/InputsManager.ts +1 -1
  178. package/src/lib/editor/managers/ScribbleManager/ScribbleManager.ts +1 -1
  179. package/src/lib/editor/managers/SnapManager/BoundsSnaps.ts +2 -2
  180. package/src/lib/editor/managers/SnapManager/HandleSnaps.ts +2 -2
  181. package/src/lib/editor/managers/TextManager/TextManager.ts +1 -1
  182. package/src/lib/editor/managers/TickManager/TickManager.ts +1 -1
  183. package/src/lib/editor/shapes/shared/resizeBox.ts +1 -1
  184. package/src/lib/editor/tools/BaseBoxShapeTool/children/Pointing.ts +2 -2
  185. package/src/lib/editor/types/SvgExportContext.tsx +1 -1
  186. package/src/lib/exports/exportToSvg.tsx +1 -1
  187. package/src/lib/exports/getSvgJsx.tsx +1 -1
  188. package/src/lib/hooks/EditorComponentsContext.tsx +63 -0
  189. package/src/lib/hooks/useCanvasEvents.ts +13 -2
  190. package/src/lib/hooks/useEditor.tsx +1 -1
  191. package/src/lib/hooks/useEditorComponents.tsx +20 -89
  192. package/src/lib/options.ts +11 -0
  193. package/src/lib/primitives/Vec.ts +7 -1
  194. package/src/lib/utils/areShapesContentEqual.ts +9 -2
  195. package/src/lib/utils/assets.ts +15 -10
  196. package/src/lib/utils/browserCanvasMaxSize.ts +4 -2
  197. package/src/lib/utils/debug-flags.ts +0 -20
  198. package/src/lib/utils/deepLinks.ts +1 -1
  199. package/src/lib/utils/dom.ts +6 -7
  200. package/src/lib/utils/getIncrementedName.ts +1 -1
  201. package/src/lib/utils/getPointerInfo.ts +1 -0
  202. package/src/lib/utils/getSvgPathFromPoints.ts +1 -1
  203. package/src/lib/utils/keyboard.ts +6 -4
  204. package/src/lib/utils/normalizeWheel.ts +8 -8
  205. package/src/lib/utils/reorderShapes.ts +17 -8
  206. package/src/lib/utils/reparenting.ts +5 -10
  207. package/src/lib/utils/richText.ts +1 -1
  208. package/src/lib/utils/rotation.ts +1 -1
  209. package/src/lib/utils/runtime.ts +26 -1
  210. package/src/version.ts +3 -3
  211. package/dist-cjs/lib/utils/hardResetEditor.js.map +0 -7
  212. package/dist-cjs/lib/utils/refreshPage.js +0 -28
  213. package/dist-cjs/lib/utils/refreshPage.js.map +0 -7
  214. package/dist-cjs/lib/utils/window-open.js +0 -28
  215. package/dist-cjs/lib/utils/window-open.js.map +0 -7
  216. package/dist-esm/lib/utils/hardResetEditor.mjs +0 -8
  217. package/dist-esm/lib/utils/hardResetEditor.mjs.map +0 -7
  218. package/dist-esm/lib/utils/refreshPage.mjs +0 -8
  219. package/dist-esm/lib/utils/refreshPage.mjs.map +0 -7
  220. package/dist-esm/lib/utils/window-open.mjs +0 -8
  221. package/dist-esm/lib/utils/window-open.mjs.map +0 -7
  222. package/src/lib/utils/hardResetEditor.ts +0 -6
  223. package/src/lib/utils/refreshPage.ts +0 -6
  224. package/src/lib/utils/window-open.ts +0 -16
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/utils/richText.ts"],
4
- "sourcesContent": ["import { getSchema, JSONContent, Editor as TTEditor } from '@tiptap/core'\nimport { Node, Schema } from '@tiptap/pm/model'\nimport { EditorProviderProps } from '@tiptap/react'\nimport { TLRichText } from '@tldraw/tlschema'\nimport { assert, WeakCache } from '@tldraw/utils'\nimport { Editor } from '../editor/Editor'\nimport { TLFontFace } from '../editor/managers/FontManager/FontManager'\n\n/**\n * This is the TipTap editor! Docs are {@link https://tiptap.dev/docs}.\n *\n * @public\n */\nexport type TiptapEditor = TTEditor\n\n/**\n * A TipTap node. See {@link https://tiptap.dev/docs}.\n * @public\n */\nexport type TiptapNode = Node\n\n/** @public */\nexport interface TLTextOptions {\n\ttipTapConfig?: EditorProviderProps\n\taddFontsFromNode?: RichTextFontVisitor\n}\n\n/** @public */\nexport interface RichTextFontVisitorState {\n\treadonly family: string\n\treadonly weight: string\n\treadonly style: string\n}\n\n/** @public */\nexport type RichTextFontVisitor = (\n\tnode: TiptapNode,\n\tstate: RichTextFontVisitorState,\n\taddFont: (font: TLFontFace) => void\n) => RichTextFontVisitorState\n\nconst schemaCache = new WeakCache<EditorProviderProps, Schema>()\nexport function getTipTapSchema(tipTapConfig: EditorProviderProps) {\n\treturn schemaCache.get(tipTapConfig, () => getSchema(tipTapConfig.extensions ?? []))\n}\n\n/** @public */\nexport function getFontsFromRichText(\n\teditor: Editor,\n\trichText: TLRichText,\n\tinitialState: RichTextFontVisitorState\n) {\n\tconst { tipTapConfig, addFontsFromNode } = editor.getTextOptions()\n\tassert(tipTapConfig, 'textOptions.tipTapConfig must be set to use rich text')\n\tassert(addFontsFromNode, 'textOptions.addFontsFromNode must be set to use rich text')\n\n\tconst schema = getTipTapSchema(tipTapConfig)\n\n\tconst rootNode = Node.fromJSON(schema, richText as JSONContent)\n\n\tconst fonts = new Set<TLFontFace>()\n\n\tfunction addFont(font: TLFontFace) {\n\t\tfonts.add(font)\n\t}\n\n\tfunction visit(node: TiptapNode, state: RichTextFontVisitorState) {\n\t\tstate = addFontsFromNode!(node, state, addFont)\n\n\t\tfor (const child of node.children) {\n\t\t\tvisit(child, state)\n\t\t}\n\t}\n\n\tvisit(rootNode, initialState)\n\n\treturn Array.from(fonts)\n}\n"],
4
+ "sourcesContent": ["import { getSchema, JSONContent, Editor as TTEditor } from '@tiptap/core'\nimport { Node, Schema } from '@tiptap/pm/model'\nimport { EditorProviderProps } from '@tiptap/react'\nimport { TLRichText } from '@tldraw/tlschema'\nimport { assert, WeakCache } from '@tldraw/utils'\nimport type { Editor } from '../editor/Editor'\nimport { TLFontFace } from '../editor/managers/FontManager/FontManager'\n\n/**\n * This is the TipTap editor! Docs are {@link https://tiptap.dev/docs}.\n *\n * @public\n */\nexport type TiptapEditor = TTEditor\n\n/**\n * A TipTap node. See {@link https://tiptap.dev/docs}.\n * @public\n */\nexport type TiptapNode = Node\n\n/** @public */\nexport interface TLTextOptions {\n\ttipTapConfig?: EditorProviderProps\n\taddFontsFromNode?: RichTextFontVisitor\n}\n\n/** @public */\nexport interface RichTextFontVisitorState {\n\treadonly family: string\n\treadonly weight: string\n\treadonly style: string\n}\n\n/** @public */\nexport type RichTextFontVisitor = (\n\tnode: TiptapNode,\n\tstate: RichTextFontVisitorState,\n\taddFont: (font: TLFontFace) => void\n) => RichTextFontVisitorState\n\nconst schemaCache = new WeakCache<EditorProviderProps, Schema>()\nexport function getTipTapSchema(tipTapConfig: EditorProviderProps) {\n\treturn schemaCache.get(tipTapConfig, () => getSchema(tipTapConfig.extensions ?? []))\n}\n\n/** @public */\nexport function getFontsFromRichText(\n\teditor: Editor,\n\trichText: TLRichText,\n\tinitialState: RichTextFontVisitorState\n) {\n\tconst { tipTapConfig, addFontsFromNode } = editor.getTextOptions()\n\tassert(tipTapConfig, 'textOptions.tipTapConfig must be set to use rich text')\n\tassert(addFontsFromNode, 'textOptions.addFontsFromNode must be set to use rich text')\n\n\tconst schema = getTipTapSchema(tipTapConfig)\n\n\tconst rootNode = Node.fromJSON(schema, richText as JSONContent)\n\n\tconst fonts = new Set<TLFontFace>()\n\n\tfunction addFont(font: TLFontFace) {\n\t\tfonts.add(font)\n\t}\n\n\tfunction visit(node: TiptapNode, state: RichTextFontVisitorState) {\n\t\tstate = addFontsFromNode!(node, state, addFont)\n\n\t\tfor (const child of node.children) {\n\t\t\tvisit(child, state)\n\t\t}\n\t}\n\n\tvisit(rootNode, initialState)\n\n\treturn Array.from(fonts)\n}\n"],
5
5
  "mappings": "AAAA,SAAS,iBAAkD;AAC3D,SAAS,YAAoB;AAG7B,SAAS,QAAQ,iBAAiB;AAqClC,MAAM,cAAc,IAAI,UAAuC;AACxD,SAAS,gBAAgB,cAAmC;AAClE,SAAO,YAAY,IAAI,cAAc,MAAM,UAAU,aAAa,cAAc,CAAC,CAAC,CAAC;AACpF;AAGO,SAAS,qBACf,QACA,UACA,cACC;AACD,QAAM,EAAE,cAAc,iBAAiB,IAAI,OAAO,eAAe;AACjE,SAAO,cAAc,uDAAuD;AAC5E,SAAO,kBAAkB,2DAA2D;AAEpF,QAAM,SAAS,gBAAgB,YAAY;AAE3C,QAAM,WAAW,KAAK,SAAS,QAAQ,QAAuB;AAE9D,QAAM,QAAQ,oBAAI,IAAgB;AAElC,WAAS,QAAQ,MAAkB;AAClC,UAAM,IAAI,IAAI;AAAA,EACf;AAEA,WAAS,MAAM,MAAkB,OAAiC;AACjE,YAAQ,iBAAkB,MAAM,OAAO,OAAO;AAE9C,eAAW,SAAS,KAAK,UAAU;AAClC,YAAM,OAAO,KAAK;AAAA,IACnB;AAAA,EACD;AAEA,QAAM,UAAU,YAAY;AAE5B,SAAO,MAAM,KAAK,KAAK;AACxB;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/utils/rotation.ts"],
4
- "sourcesContent": ["import { isShapeId, TLShape, TLShapeId, TLShapePartial } from '@tldraw/tlschema'\nimport { compact } from '@tldraw/utils'\nimport { Editor } from '../editor/Editor'\nimport { Mat } from '../primitives/Mat'\nimport { canonicalizeRotation } from '../primitives/utils'\nimport { Vec, VecLike } from '../primitives/Vec'\n\n/** @internal */\nexport function getRotationSnapshot({\n\teditor,\n\tids,\n}: {\n\teditor: Editor\n\tids: TLShapeId[]\n}): TLRotationSnapshot | null {\n\tconst shapes = compact(ids.map((id) => editor.getShape(id)))\n\tconst rotation = editor.getShapesSharedRotation(ids)\n\tconst rotatedPageBounds = editor.getShapesRotatedPageBounds(ids)\n\n\t// todo: this assumes we're rotating the selected shapes\n\t// if we try to rotate shapes that aren't selected, this\n\t// will produce the wrong results\n\n\t// Return null if there are no selected shapes\n\tif (!rotatedPageBounds) {\n\t\treturn null\n\t}\n\n\tconst initialPageCenter = rotatedPageBounds.center\n\t\t.clone()\n\t\t.rotWith(rotatedPageBounds.point, rotation)\n\n\treturn {\n\t\tinitialPageCenter,\n\t\tinitialCursorAngle: initialPageCenter.angle(editor.inputs.getOriginPagePoint()),\n\t\tinitialShapesRotation: rotation,\n\t\tshapeSnapshots: shapes.map((shape) => ({\n\t\t\tshape,\n\t\t\tinitialPagePoint: editor.getShapePageTransform(shape.id)!.point(),\n\t\t})),\n\t}\n}\n\n/**\n * @internal\n **/\nexport interface TLRotationSnapshot {\n\tinitialPageCenter: Vec\n\tinitialCursorAngle: number\n\tinitialShapesRotation: number\n\tshapeSnapshots: {\n\t\tshape: TLShape\n\t\tinitialPagePoint: Vec\n\t}[]\n}\n\n/** @internal */\nexport function applyRotationToSnapshotShapes({\n\tdelta,\n\teditor,\n\tsnapshot,\n\tstage,\n\tcenterOverride,\n}: {\n\tdelta: number\n\tsnapshot: TLRotationSnapshot\n\teditor: Editor\n\tstage: 'start' | 'update' | 'end' | 'one-off'\n\tcenterOverride?: VecLike\n}) {\n\tconst { initialPageCenter, shapeSnapshots } = snapshot\n\n\teditor.updateShapes(\n\t\tshapeSnapshots.map(({ shape, initialPagePoint }) => {\n\t\t\t// We need to both rotate each shape individually and rotate the shapes\n\t\t\t// around the pivot point (the average center of all rotating shapes.)\n\n\t\t\tconst parentTransform = isShapeId(shape.parentId)\n\t\t\t\t? editor.getShapePageTransform(shape.parentId)!\n\t\t\t\t: Mat.Identity()\n\n\t\t\tconst newPagePoint = Vec.RotWith(initialPagePoint, centerOverride ?? initialPageCenter, delta)\n\n\t\t\tconst newLocalPoint = Mat.applyToPoint(\n\t\t\t\t// use the current parent transform in case it has moved/resized since the start\n\t\t\t\t// (e.g. if rotating a shape at the edge of a group)\n\t\t\t\tMat.Inverse(parentTransform),\n\t\t\t\tnewPagePoint\n\t\t\t)\n\t\t\tconst newRotation = canonicalizeRotation(shape.rotation + delta)\n\n\t\t\treturn {\n\t\t\t\tid: shape.id,\n\t\t\t\ttype: shape.type,\n\t\t\t\tx: newLocalPoint.x,\n\t\t\t\ty: newLocalPoint.y,\n\t\t\t\trotation: newRotation,\n\t\t\t}\n\t\t})\n\t)\n\n\t// Handle change\n\n\tconst changes: TLShapePartial[] = []\n\n\tshapeSnapshots.forEach(({ shape }) => {\n\t\tconst current = editor.getShape(shape.id)\n\t\tif (!current) return\n\t\tconst util = editor.getShapeUtil(shape)\n\n\t\tif (stage === 'start' || stage === 'one-off') {\n\t\t\tconst changeStart = util.onRotateStart?.(shape)\n\t\t\tif (changeStart) changes.push(changeStart)\n\t\t}\n\n\t\tconst changeUpdate = util.onRotate?.(shape, current)\n\t\tif (changeUpdate) changes.push(changeUpdate)\n\n\t\tif (stage === 'end' || stage === 'one-off') {\n\t\t\tconst changeEnd = util.onRotateEnd?.(shape, current)\n\t\t\tif (changeEnd) changes.push(changeEnd)\n\t\t}\n\t})\n\n\tif (changes.length > 0) {\n\t\teditor.updateShapes(changes)\n\t}\n}\n"],
4
+ "sourcesContent": ["import { isShapeId, TLShape, TLShapeId, TLShapePartial } from '@tldraw/tlschema'\nimport { compact } from '@tldraw/utils'\nimport type { Editor } from '../editor/Editor'\nimport { Mat } from '../primitives/Mat'\nimport { canonicalizeRotation } from '../primitives/utils'\nimport { Vec, VecLike } from '../primitives/Vec'\n\n/** @internal */\nexport function getRotationSnapshot({\n\teditor,\n\tids,\n}: {\n\teditor: Editor\n\tids: TLShapeId[]\n}): TLRotationSnapshot | null {\n\tconst shapes = compact(ids.map((id) => editor.getShape(id)))\n\tconst rotation = editor.getShapesSharedRotation(ids)\n\tconst rotatedPageBounds = editor.getShapesRotatedPageBounds(ids)\n\n\t// todo: this assumes we're rotating the selected shapes\n\t// if we try to rotate shapes that aren't selected, this\n\t// will produce the wrong results\n\n\t// Return null if there are no selected shapes\n\tif (!rotatedPageBounds) {\n\t\treturn null\n\t}\n\n\tconst initialPageCenter = rotatedPageBounds.center\n\t\t.clone()\n\t\t.rotWith(rotatedPageBounds.point, rotation)\n\n\treturn {\n\t\tinitialPageCenter,\n\t\tinitialCursorAngle: initialPageCenter.angle(editor.inputs.getOriginPagePoint()),\n\t\tinitialShapesRotation: rotation,\n\t\tshapeSnapshots: shapes.map((shape) => ({\n\t\t\tshape,\n\t\t\tinitialPagePoint: editor.getShapePageTransform(shape.id)!.point(),\n\t\t})),\n\t}\n}\n\n/**\n * @internal\n **/\nexport interface TLRotationSnapshot {\n\tinitialPageCenter: Vec\n\tinitialCursorAngle: number\n\tinitialShapesRotation: number\n\tshapeSnapshots: {\n\t\tshape: TLShape\n\t\tinitialPagePoint: Vec\n\t}[]\n}\n\n/** @internal */\nexport function applyRotationToSnapshotShapes({\n\tdelta,\n\teditor,\n\tsnapshot,\n\tstage,\n\tcenterOverride,\n}: {\n\tdelta: number\n\tsnapshot: TLRotationSnapshot\n\teditor: Editor\n\tstage: 'start' | 'update' | 'end' | 'one-off'\n\tcenterOverride?: VecLike\n}) {\n\tconst { initialPageCenter, shapeSnapshots } = snapshot\n\n\teditor.updateShapes(\n\t\tshapeSnapshots.map(({ shape, initialPagePoint }) => {\n\t\t\t// We need to both rotate each shape individually and rotate the shapes\n\t\t\t// around the pivot point (the average center of all rotating shapes.)\n\n\t\t\tconst parentTransform = isShapeId(shape.parentId)\n\t\t\t\t? editor.getShapePageTransform(shape.parentId)!\n\t\t\t\t: Mat.Identity()\n\n\t\t\tconst newPagePoint = Vec.RotWith(initialPagePoint, centerOverride ?? initialPageCenter, delta)\n\n\t\t\tconst newLocalPoint = Mat.applyToPoint(\n\t\t\t\t// use the current parent transform in case it has moved/resized since the start\n\t\t\t\t// (e.g. if rotating a shape at the edge of a group)\n\t\t\t\tMat.Inverse(parentTransform),\n\t\t\t\tnewPagePoint\n\t\t\t)\n\t\t\tconst newRotation = canonicalizeRotation(shape.rotation + delta)\n\n\t\t\treturn {\n\t\t\t\tid: shape.id,\n\t\t\t\ttype: shape.type,\n\t\t\t\tx: newLocalPoint.x,\n\t\t\t\ty: newLocalPoint.y,\n\t\t\t\trotation: newRotation,\n\t\t\t}\n\t\t})\n\t)\n\n\t// Handle change\n\n\tconst changes: TLShapePartial[] = []\n\n\tshapeSnapshots.forEach(({ shape }) => {\n\t\tconst current = editor.getShape(shape.id)\n\t\tif (!current) return\n\t\tconst util = editor.getShapeUtil(shape)\n\n\t\tif (stage === 'start' || stage === 'one-off') {\n\t\t\tconst changeStart = util.onRotateStart?.(shape)\n\t\t\tif (changeStart) changes.push(changeStart)\n\t\t}\n\n\t\tconst changeUpdate = util.onRotate?.(shape, current)\n\t\tif (changeUpdate) changes.push(changeUpdate)\n\n\t\tif (stage === 'end' || stage === 'one-off') {\n\t\t\tconst changeEnd = util.onRotateEnd?.(shape, current)\n\t\t\tif (changeEnd) changes.push(changeEnd)\n\t\t}\n\t})\n\n\tif (changes.length > 0) {\n\t\teditor.updateShapes(changes)\n\t}\n}\n"],
5
5
  "mappings": "AAAA,SAAS,iBAAqD;AAC9D,SAAS,eAAe;AAExB,SAAS,WAAW;AACpB,SAAS,4BAA4B;AACrC,SAAS,WAAoB;AAGtB,SAAS,oBAAoB;AAAA,EACnC;AAAA,EACA;AACD,GAG8B;AAC7B,QAAM,SAAS,QAAQ,IAAI,IAAI,CAAC,OAAO,OAAO,SAAS,EAAE,CAAC,CAAC;AAC3D,QAAM,WAAW,OAAO,wBAAwB,GAAG;AACnD,QAAM,oBAAoB,OAAO,2BAA2B,GAAG;AAO/D,MAAI,CAAC,mBAAmB;AACvB,WAAO;AAAA,EACR;AAEA,QAAM,oBAAoB,kBAAkB,OAC1C,MAAM,EACN,QAAQ,kBAAkB,OAAO,QAAQ;AAE3C,SAAO;AAAA,IACN;AAAA,IACA,oBAAoB,kBAAkB,MAAM,OAAO,OAAO,mBAAmB,CAAC;AAAA,IAC9E,uBAAuB;AAAA,IACvB,gBAAgB,OAAO,IAAI,CAAC,WAAW;AAAA,MACtC;AAAA,MACA,kBAAkB,OAAO,sBAAsB,MAAM,EAAE,EAAG,MAAM;AAAA,IACjE,EAAE;AAAA,EACH;AACD;AAgBO,SAAS,8BAA8B;AAAA,EAC7C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,GAMG;AACF,QAAM,EAAE,mBAAmB,eAAe,IAAI;AAE9C,SAAO;AAAA,IACN,eAAe,IAAI,CAAC,EAAE,OAAO,iBAAiB,MAAM;AAInD,YAAM,kBAAkB,UAAU,MAAM,QAAQ,IAC7C,OAAO,sBAAsB,MAAM,QAAQ,IAC3C,IAAI,SAAS;AAEhB,YAAM,eAAe,IAAI,QAAQ,kBAAkB,kBAAkB,mBAAmB,KAAK;AAE7F,YAAM,gBAAgB,IAAI;AAAA;AAAA;AAAA,QAGzB,IAAI,QAAQ,eAAe;AAAA,QAC3B;AAAA,MACD;AACA,YAAM,cAAc,qBAAqB,MAAM,WAAW,KAAK;AAE/D,aAAO;AAAA,QACN,IAAI,MAAM;AAAA,QACV,MAAM,MAAM;AAAA,QACZ,GAAG,cAAc;AAAA,QACjB,GAAG,cAAc;AAAA,QACjB,UAAU;AAAA,MACX;AAAA,IACD,CAAC;AAAA,EACF;AAIA,QAAM,UAA4B,CAAC;AAEnC,iBAAe,QAAQ,CAAC,EAAE,MAAM,MAAM;AACrC,UAAM,UAAU,OAAO,SAAS,MAAM,EAAE;AACxC,QAAI,CAAC,QAAS;AACd,UAAM,OAAO,OAAO,aAAa,KAAK;AAEtC,QAAI,UAAU,WAAW,UAAU,WAAW;AAC7C,YAAM,cAAc,KAAK,gBAAgB,KAAK;AAC9C,UAAI,YAAa,SAAQ,KAAK,WAAW;AAAA,IAC1C;AAEA,UAAM,eAAe,KAAK,WAAW,OAAO,OAAO;AACnD,QAAI,aAAc,SAAQ,KAAK,YAAY;AAE3C,QAAI,UAAU,SAAS,UAAU,WAAW;AAC3C,YAAM,YAAY,KAAK,cAAc,OAAO,OAAO;AACnD,UAAI,UAAW,SAAQ,KAAK,SAAS;AAAA,IACtC;AAAA,EACD,CAAC;AAED,MAAI,QAAQ,SAAS,GAAG;AACvB,WAAO,aAAa,OAAO;AAAA,EAC5B;AACD;",
6
6
  "names": []
7
7
  }
@@ -12,7 +12,19 @@ const runtime = {
12
12
  function setRuntimeOverrides(input) {
13
13
  Object.assign(runtime, input);
14
14
  }
15
+ function openWindow(url, target = "_blank", allowReferrer) {
16
+ return runtime.openWindow(url, target, allowReferrer);
17
+ }
18
+ function refreshPage() {
19
+ runtime.refreshPage();
20
+ }
21
+ function hardResetEditor() {
22
+ runtime.hardReset();
23
+ }
15
24
  export {
25
+ hardResetEditor,
26
+ openWindow,
27
+ refreshPage,
16
28
  runtime,
17
29
  setRuntimeOverrides
18
30
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/utils/runtime.ts"],
4
- "sourcesContent": ["/** @public */\nexport const runtime: {\n\topenWindow(url: string, target: string, allowReferrer?: boolean): void\n\trefreshPage(): void\n\thardReset(): void\n} = {\n\topenWindow(url, target, allowReferrer = false) {\n\t\treturn window.open(url, target, allowReferrer ? 'noopener' : 'noopener noreferrer')\n\t},\n\trefreshPage() {\n\t\twindow.location.reload()\n\t},\n\tasync hardReset() {\n\t\treturn await (window as any).__tldraw__hardReset?.()\n\t},\n}\n\n/** @public */\nexport function setRuntimeOverrides(input: Partial<typeof runtime>) {\n\tObject.assign(runtime, input)\n}\n"],
5
- "mappings": "AACO,MAAM,UAIT;AAAA,EACH,WAAW,KAAK,QAAQ,gBAAgB,OAAO;AAC9C,WAAO,OAAO,KAAK,KAAK,QAAQ,gBAAgB,aAAa,qBAAqB;AAAA,EACnF;AAAA,EACA,cAAc;AACb,WAAO,SAAS,OAAO;AAAA,EACxB;AAAA,EACA,MAAM,YAAY;AACjB,WAAO,MAAO,OAAe,sBAAsB;AAAA,EACpD;AACD;AAGO,SAAS,oBAAoB,OAAgC;AACnE,SAAO,OAAO,SAAS,KAAK;AAC7B;",
4
+ "sourcesContent": ["/** @public */\nexport const runtime: {\n\topenWindow(url: string, target: string, allowReferrer?: boolean): void\n\trefreshPage(): void\n\thardReset(): Promise<void>\n} = {\n\topenWindow(url, target, allowReferrer = false) {\n\t\treturn window.open(url, target, allowReferrer ? 'noopener' : 'noopener noreferrer')\n\t},\n\trefreshPage() {\n\t\twindow.location.reload()\n\t},\n\tasync hardReset() {\n\t\treturn await (window as any).__tldraw__hardReset?.()\n\t},\n}\n\n/** @public */\nexport function setRuntimeOverrides(input: Partial<typeof runtime>) {\n\tObject.assign(runtime, input)\n}\n\n/**\n * Open a new window with the given URL and target. Prefer this to the window.open function, as it\n * will work more reliably in embedded scenarios, such as our VS Code extension. See the runtime\n * object in tldraw/editor for more details.\n *\n * @param url - The URL to open.\n * @param target - The target window to open the URL in.\n * @param allowReferrer - Whether to allow the referrer to be sent to the new window.\n * @returns The new window object.\n * @public\n */\nexport function openWindow(url: string, target = '_blank', allowReferrer?: boolean) {\n\treturn runtime.openWindow(url, target, allowReferrer)\n}\n\n/** @public */\nexport function refreshPage() {\n\truntime.refreshPage()\n}\n\n/** @public */\nexport function hardResetEditor() {\n\truntime.hardReset()\n}\n"],
5
+ "mappings": "AACO,MAAM,UAIT;AAAA,EACH,WAAW,KAAK,QAAQ,gBAAgB,OAAO;AAC9C,WAAO,OAAO,KAAK,KAAK,QAAQ,gBAAgB,aAAa,qBAAqB;AAAA,EACnF;AAAA,EACA,cAAc;AACb,WAAO,SAAS,OAAO;AAAA,EACxB;AAAA,EACA,MAAM,YAAY;AACjB,WAAO,MAAO,OAAe,sBAAsB;AAAA,EACpD;AACD;AAGO,SAAS,oBAAoB,OAAgC;AACnE,SAAO,OAAO,SAAS,KAAK;AAC7B;AAaO,SAAS,WAAW,KAAa,SAAS,UAAU,eAAyB;AACnF,SAAO,QAAQ,WAAW,KAAK,QAAQ,aAAa;AACrD;AAGO,SAAS,cAAc;AAC7B,UAAQ,YAAY;AACrB;AAGO,SAAS,kBAAkB;AACjC,UAAQ,UAAU;AACnB;",
6
6
  "names": []
7
7
  }
@@ -1,8 +1,8 @@
1
- const version = "4.4.0";
1
+ const version = "4.5.0-canary.a4eece45e3d0";
2
2
  const publishDates = {
3
3
  major: "2025-09-18T14:39:22.803Z",
4
- minor: "2026-02-18T12:03:50.380Z",
5
- patch: "2026-02-18T12:03:50.380Z"
4
+ minor: "2026-02-18T16:41:31.064Z",
5
+ patch: "2026-02-18T16:41:31.064Z"
6
6
  };
7
7
  export {
8
8
  publishDates,
@@ -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 = '4.4.0'\nexport const publishDates = {\n\tmajor: '2025-09-18T14:39:22.803Z',\n\tminor: '2026-02-18T12:03:50.380Z',\n\tpatch: '2026-02-18T12:03:50.380Z',\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 = '4.5.0-canary.a4eece45e3d0'\nexport const publishDates = {\n\tmajor: '2025-09-18T14:39:22.803Z',\n\tminor: '2026-02-18T16:41:31.064Z',\n\tpatch: '2026-02-18T16:41:31.064Z',\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/editor",
3
3
  "description": "tldraw infinite canvas SDK (editor).",
4
- "version": "4.4.0",
4
+ "version": "4.5.0-canary.a4eece45e3d0",
5
5
  "author": {
6
6
  "name": "tldraw Inc.",
7
7
  "email": "hello@tldraw.com"
@@ -49,12 +49,12 @@
49
49
  "@tiptap/core": "^3.12.1",
50
50
  "@tiptap/pm": "^3.12.1",
51
51
  "@tiptap/react": "^3.12.1",
52
- "@tldraw/state": "4.4.0",
53
- "@tldraw/state-react": "4.4.0",
54
- "@tldraw/store": "4.4.0",
55
- "@tldraw/tlschema": "4.4.0",
56
- "@tldraw/utils": "4.4.0",
57
- "@tldraw/validate": "4.4.0",
52
+ "@tldraw/state": "4.5.0-canary.a4eece45e3d0",
53
+ "@tldraw/state-react": "4.5.0-canary.a4eece45e3d0",
54
+ "@tldraw/store": "4.5.0-canary.a4eece45e3d0",
55
+ "@tldraw/tlschema": "4.5.0-canary.a4eece45e3d0",
56
+ "@tldraw/utils": "4.5.0-canary.a4eece45e3d0",
57
+ "@tldraw/validate": "4.5.0-canary.a4eece45e3d0",
58
58
  "@use-gesture/react": "^10.3.1",
59
59
  "classnames": "^2.5.1",
60
60
  "eventemitter3": "^4.0.7",
package/src/index.ts CHANGED
@@ -457,10 +457,8 @@ export { EditorAtom } from './lib/utils/EditorAtom'
457
457
  export { getIncrementedName } from './lib/utils/getIncrementedName'
458
458
  export { getPointerInfo } from './lib/utils/getPointerInfo'
459
459
  export { getSvgPathFromPoints } from './lib/utils/getSvgPathFromPoints'
460
- export { hardResetEditor } from './lib/utils/hardResetEditor'
461
460
  export { isAccelKey } from './lib/utils/keyboard'
462
461
  export { normalizeWheel } from './lib/utils/normalizeWheel'
463
- export { refreshPage } from './lib/utils/refreshPage'
464
462
  export { getDroppedShapesToNewParents, kickoutOccludedShapes } from './lib/utils/reparenting'
465
463
  export {
466
464
  getFontsFromRichText,
@@ -475,7 +473,13 @@ export {
475
473
  getRotationSnapshot,
476
474
  type TLRotationSnapshot,
477
475
  } from './lib/utils/rotation'
478
- export { runtime, setRuntimeOverrides } from './lib/utils/runtime'
476
+ export {
477
+ hardResetEditor,
478
+ openWindow,
479
+ refreshPage,
480
+ runtime,
481
+ setRuntimeOverrides,
482
+ } from './lib/utils/runtime'
479
483
  export {
480
484
  ReadonlySharedStyleMap,
481
485
  SharedStyleMap,
@@ -485,7 +489,6 @@ export { hardReset } from './lib/utils/sync/hardReset'
485
489
  export { LocalIndexedDb, Table, type StoreName } from './lib/utils/sync/LocalIndexedDb'
486
490
  export { type TLStoreWithStatus } from './lib/utils/sync/StoreWithStatus'
487
491
  export { uniq } from './lib/utils/uniq'
488
- export { openWindow } from './lib/utils/window-open'
489
492
 
490
493
  registerTldrawLibraryVersion(
491
494
  (globalThis as any).TLDRAW_LIBRARY_NAME,
@@ -24,15 +24,13 @@ import { TLEditorSnapshot } from './config/TLEditorSnapshot'
24
24
  import { Editor } from './editor/Editor'
25
25
  import { TLStateNodeConstructor } from './editor/tools/StateNode'
26
26
  import { TLCameraOptions } from './editor/types/misc-types'
27
+ import type { TLEditorComponents } from './hooks/EditorComponentsContext'
28
+ import { useEditorComponents } from './hooks/EditorComponentsContext'
27
29
  import { ContainerProvider, useContainer } from './hooks/useContainer'
28
30
  import { useCursor } from './hooks/useCursor'
29
31
  import { useDarkMode } from './hooks/useDarkMode'
30
32
  import { EditorProvider, useEditor } from './hooks/useEditor'
31
- import {
32
- EditorComponentsProvider,
33
- TLEditorComponents,
34
- useEditorComponents,
35
- } from './hooks/useEditorComponents'
33
+ import { EditorComponentsProvider } from './hooks/useEditorComponents'
36
34
  import { useEvent } from './hooks/useEvent'
37
35
  import { useForceUpdate } from './hooks/useForceUpdate'
38
36
  import { useShallowObjectIdentity } from './hooks/useIdentity'
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react'
2
- import { TLErrorFallbackComponent } from './default-components/DefaultErrorFallback'
2
+ import type { TLErrorFallbackComponent } from './default-components/DefaultErrorFallback'
3
3
 
4
4
  /** @public */
5
5
  export interface TLErrorBoundaryProps {
@@ -2,8 +2,8 @@ import { track } from '@tldraw/state-react'
2
2
  import { TLInstancePresence } from '@tldraw/tlschema'
3
3
  import { useEffect, useRef, useState } from 'react'
4
4
  import { Editor } from '../editor/Editor'
5
+ import { useEditorComponents } from '../hooks/EditorComponentsContext'
5
6
  import { useEditor } from '../hooks/useEditor'
6
- import { useEditorComponents } from '../hooks/useEditorComponents'
7
7
  import { usePeerIds } from '../hooks/usePeerIds'
8
8
  import { usePresence } from '../hooks/usePresence'
9
9
  import {
@@ -3,8 +3,8 @@ import { useQuickReactor, useStateTracking } from '@tldraw/state-react'
3
3
  import { TLShape, TLShapeId } from '@tldraw/tlschema'
4
4
  import { memo, useCallback, useEffect, useLayoutEffect, useRef } from 'react'
5
5
  import { ShapeUtil } from '../editor/shapes/ShapeUtil'
6
+ import { useEditorComponents } from '../hooks/EditorComponentsContext'
6
7
  import { useEditor } from '../hooks/useEditor'
7
- import { useEditorComponents } from '../hooks/useEditorComponents'
8
8
  import { useShapeCulling } from '../hooks/useShapeCulling'
9
9
  import { Mat } from '../primitives/Mat'
10
10
  import { areShapesContentEqual } from '../utils/areShapesContentEqual'
@@ -5,12 +5,12 @@ import { dedupe, modulate, objectMapValues } from '@tldraw/utils'
5
5
  import classNames from 'classnames'
6
6
  import { Fragment, JSX, useEffect, useRef, useState } from 'react'
7
7
  import { tlenv } from '../../globals/environment'
8
+ import { useEditorComponents } from '../../hooks/EditorComponentsContext'
8
9
  import { useCanvasEvents } from '../../hooks/useCanvasEvents'
9
10
  import { useCoarsePointer } from '../../hooks/useCoarsePointer'
10
11
  import { useContainer } from '../../hooks/useContainer'
11
12
  import { useDocumentEvents } from '../../hooks/useDocumentEvents'
12
13
  import { useEditor } from '../../hooks/useEditor'
13
- import { useEditorComponents } from '../../hooks/useEditorComponents'
14
14
  import { useFixSafariDoubleTapZoomPencilEvents } from '../../hooks/useFixSafariDoubleTapZoomPencilEvents'
15
15
  import { useGestureEvents } from '../../hooks/useGestureEvents'
16
16
  import { useHandleEvents } from '../../hooks/useHandleEvents'
@@ -3,10 +3,9 @@ import { noop } from '@tldraw/utils'
3
3
  import classNames from 'classnames'
4
4
  import { ComponentType, useEffect, useLayoutEffect, useRef, useState } from 'react'
5
5
  import { Editor } from '../../editor/Editor'
6
+ import { useEditorComponents } from '../../hooks/EditorComponentsContext'
6
7
  import { EditorProvider } from '../../hooks/useEditor'
7
- import { useEditorComponents } from '../../hooks/useEditorComponents'
8
- import { hardResetEditor } from '../../utils/hardResetEditor'
9
- import { refreshPage } from '../../utils/refreshPage'
8
+ import { hardResetEditor, refreshPage } from '../../utils/runtime'
10
9
  import { ErrorBoundary } from '../ErrorBoundary'
11
10
 
12
11
  const BASE_ERROR_URL = 'https://github.com/tldraw/tldraw/issues/new'
@@ -1,8 +1,11 @@
1
- import { LoadingScreen } from '../../TldrawEditor'
2
- import { useEditorComponents } from '../../hooks/useEditorComponents'
1
+ import { useEditorComponents } from '../../hooks/EditorComponentsContext'
3
2
 
4
3
  /** @public @react */
5
4
  export const DefaultLoadingScreen = () => {
6
5
  const { Spinner } = useEditorComponents()
7
- return <LoadingScreen>{Spinner ? <Spinner /> : null}</LoadingScreen>
6
+ return (
7
+ <div className="tl-loading" aria-busy="true" tabIndex={0}>
8
+ {Spinner ? <Spinner /> : null}
9
+ </div>
10
+ )
8
11
  }
@@ -4,8 +4,8 @@ import classNames from 'classnames'
4
4
  import { memo, useLayoutEffect, useRef } from 'react'
5
5
  import type { Editor } from '../../editor/Editor'
6
6
  import { ShapeUtil } from '../../editor/shapes/ShapeUtil'
7
+ import { useEditorComponents } from '../../hooks/EditorComponentsContext'
7
8
  import { useEditor } from '../../hooks/useEditor'
8
- import { useEditorComponents } from '../../hooks/useEditorComponents'
9
9
  import { OptionalErrorBoundary } from '../ErrorBoundary'
10
10
 
11
11
  // need an extra layer of indirection here to allow hooks to be used inside the indicator render
@@ -1,8 +1,8 @@
1
1
  import { useValue } from '@tldraw/state-react'
2
2
  import { TLShapeId } from '@tldraw/tlschema'
3
3
  import { memo, useRef } from 'react'
4
+ import { useEditorComponents } from '../../hooks/EditorComponentsContext'
4
5
  import { useEditor } from '../../hooks/useEditor'
5
- import { useEditorComponents } from '../../hooks/useEditorComponents'
6
6
 
7
7
  /** @public */
8
8
  export interface TLShapeIndicatorsProps {
@@ -230,7 +230,8 @@ export function loadSessionStateSnapshotIntoStore(
230
230
  const res = migrateAndValidateSessionStateSnapshot(snapshot)
231
231
  if (!res) return
232
232
 
233
- const preserved = pluckPreservingValues(store.get(TLINSTANCE_ID))
233
+ const existingInstance = store.get(TLINSTANCE_ID)
234
+ const preserved = pluckPreservingValues(existingInstance)
234
235
  const primary = opts?.forceOverwrite ? res : preserved
235
236
  const secondary = opts?.forceOverwrite ? preserved : res
236
237
 
@@ -238,7 +239,7 @@ export function loadSessionStateSnapshotIntoStore(
238
239
  id: TLINSTANCE_ID,
239
240
  ...preserved,
240
241
  // the integrity checker will ensure that the currentPageId is valid
241
- currentPageId: res.currentPageId,
242
+ currentPageId: res.currentPageId ?? existingInstance?.currentPageId,
242
243
  isDebugMode: primary?.isDebugMode ?? secondary?.isDebugMode,
243
244
  isFocusMode: primary?.isFocusMode ?? secondary?.isFocusMode,
244
245
  isToolLocked: primary?.isToolLocked ?? secondary?.isToolLocked,
@@ -134,6 +134,7 @@ import {
134
134
  } from '../utils/deepLinks'
135
135
  import { getIncrementedName } from '../utils/getIncrementedName'
136
136
  import { getReorderingShapesChanges } from '../utils/reorderShapes'
137
+ import { getDroppedShapesToNewParents } from '../utils/reparenting'
137
138
  import { TLTextOptions, TiptapEditor } from '../utils/richText'
138
139
  import { applyRotationToSnapshotShapes, getRotationSnapshot } from '../utils/rotation'
139
140
  import { BindingOnDeleteOptions, BindingUtil } from './bindings/BindingUtil'
@@ -821,6 +822,7 @@ export class Editor extends EventEmitter<TLEventMap> {
821
822
  }
822
823
 
823
824
  private readonly _getShapeVisibility?: TLEditorOptions['getShapeVisibility']
825
+
824
826
  @computed
825
827
  private getIsShapeHiddenCache() {
826
828
  if (!this._getShapeVisibility) return null
@@ -9631,6 +9633,20 @@ export class Editor extends EventEmitter<TLEventMap> {
9631
9633
  return { id: s.id, type: s.type, x: s.x + localDelta.x, y: s.y + localDelta.y }
9632
9634
  })
9633
9635
  )
9636
+
9637
+ // If shapes were pasted onto the page (not into a specific parent),
9638
+ // check whether they landed inside a frame and reparent if so.
9639
+ if (isPageId(pasteParentId)) {
9640
+ const currentRootShapes = compact(rootShapes.map((s) => this.getShape(s.id)))
9641
+ const { reparenting } = getDroppedShapesToNewParents(this, currentRootShapes)
9642
+ reparenting.forEach((childrenToReparent, newParentId) => {
9643
+ if (childrenToReparent.length === 0) return
9644
+ this.reparentShapes(
9645
+ childrenToReparent.map((s) => s.id),
9646
+ newParentId
9647
+ )
9648
+ })
9649
+ }
9634
9650
  })
9635
9651
 
9636
9652
  return this
@@ -5,7 +5,7 @@ import {
5
5
  TLShape,
6
6
  TLUnknownBinding,
7
7
  } from '@tldraw/tlschema'
8
- import { Editor } from '../Editor'
8
+ import type { Editor } from '../Editor'
9
9
 
10
10
  /** @public */
11
11
  export interface TLBindingUtilConstructor<
@@ -1,7 +1,7 @@
1
1
  import { Computed, RESET_VALUE, computed, isUninitialized } from '@tldraw/state'
2
2
  import { TLBinding, TLShapeId } from '@tldraw/tlschema'
3
3
  import { objectMapValues } from '@tldraw/utils'
4
- import { Editor } from '../Editor'
4
+ import type { Editor } from '../Editor'
5
5
 
6
6
  type TLBindingsIndex = Map<TLShapeId, TLBinding[]>
7
7
 
@@ -1,6 +1,6 @@
1
1
  import { computed, isUninitialized } from '@tldraw/state'
2
2
  import { TLShape, TLShapeId } from '@tldraw/tlschema'
3
- import { Editor } from '../Editor'
3
+ import type { Editor } from '../Editor'
4
4
 
5
5
  /**
6
6
  * Non visible shapes are shapes outside of the viewport page bounds.
@@ -1,6 +1,6 @@
1
1
  import { Vec } from '../../../primitives/Vec'
2
2
  import { EASINGS } from '../../../primitives/easings'
3
- import { Editor } from '../../Editor'
3
+ import type { Editor } from '../../Editor'
4
4
 
5
5
  /** @public */
6
6
  export class EdgeScrollManager {
@@ -8,7 +8,7 @@ import {
8
8
  mapObjectMapValues,
9
9
  objectMapEntries,
10
10
  } from '@tldraw/utils'
11
- import { Editor } from '../../Editor'
11
+ import type { Editor } from '../../Editor'
12
12
 
13
13
  /**
14
14
  * Represents the `src` property of a {@link TLFontFace}.
@@ -4,7 +4,7 @@ import { TLINSTANCE_ID, TLPOINTER_ID } from '@tldraw/tlschema'
4
4
  import { INTERNAL_POINTER_IDS } from '../../../constants'
5
5
  import { Vec } from '../../../primitives/Vec'
6
6
  import { isAccelKey } from '../../../utils/keyboard'
7
- import { Editor } from '../../Editor'
7
+ import type { Editor } from '../../Editor'
8
8
  import { TLPinchEventInfo, TLPointerEventInfo, TLWheelEventInfo } from '../../types/event-types'
9
9
 
10
10
  /** @public */
@@ -1,7 +1,7 @@
1
1
  import { TLScribble, VecModel } from '@tldraw/tlschema'
2
2
  import { uniqueId } from '@tldraw/utils'
3
3
  import { Vec } from '../../../primitives/Vec'
4
- import { Editor } from '../../Editor'
4
+ import type { Editor } from '../../Editor'
5
5
 
6
6
  /** @public */
7
7
  export interface ScribbleItem {
@@ -12,8 +12,8 @@ import {
12
12
  import { Mat } from '../../../primitives/Mat'
13
13
  import { Vec } from '../../../primitives/Vec'
14
14
  import { rangeIntersection, rangesOverlap } from '../../../primitives/utils'
15
- import { Editor } from '../../Editor'
16
- import {
15
+ import type { Editor } from '../../Editor'
16
+ import type {
17
17
  GapsSnapIndicator,
18
18
  PointsSnapIndicator,
19
19
  SnapData,
@@ -3,8 +3,8 @@ import { TLHandle, TLShape, TLShapeId, VecModel } from '@tldraw/tlschema'
3
3
  import { assertExists, uniqueId } from '@tldraw/utils'
4
4
  import { Vec } from '../../../primitives/Vec'
5
5
  import { Geometry2d } from '../../../primitives/geometry/Geometry2d'
6
- import { Editor } from '../../Editor'
7
- import { PointsSnapIndicator, SnapData, SnapManager } from './SnapManager'
6
+ import type { Editor } from '../../Editor'
7
+ import type { PointsSnapIndicator, SnapData, SnapManager } from './SnapManager'
8
8
 
9
9
  /**
10
10
  * When dragging a handle, users can snap the handle to key geometry on other nearby shapes.
@@ -1,6 +1,6 @@
1
1
  import { BoxModel, TLDefaultHorizontalAlignStyle } from '@tldraw/tlschema'
2
2
  import { objectMapKeys } from '@tldraw/utils'
3
- import { Editor } from '../../Editor'
3
+ import type { Editor } from '../../Editor'
4
4
 
5
5
  const fixNewLines = /\r?\n|\r/g
6
6
 
@@ -1,5 +1,5 @@
1
1
  import { throttleToNextFrame as _throttleToNextFrame, bind } from '@tldraw/utils'
2
- import { Editor } from '../../Editor'
2
+ import type { Editor } from '../../Editor'
3
3
 
4
4
  const throttleToNextFrame =
5
5
  typeof process !== 'undefined' && process.env.NODE_ENV === 'test'
@@ -2,7 +2,7 @@ import { VecModel } from '@tldraw/tlschema'
2
2
  import { Box } from '../../../primitives/Box'
3
3
  import { Vec } from '../../../primitives/Vec'
4
4
  import { TLResizeHandle } from '../../types/selection-types'
5
- import { TLBaseBoxShape } from '../BaseBoxShapeUtil'
5
+ import type { TLBaseBoxShape } from '../BaseBoxShapeUtil'
6
6
  import { TLResizeMode } from '../ShapeUtil'
7
7
 
8
8
  /** @public */
@@ -1,11 +1,11 @@
1
1
  import { TLShape, createShapeId } from '@tldraw/tlschema'
2
2
  import { structuredClone } from '@tldraw/utils'
3
3
  import { Vec } from '../../../../primitives/Vec'
4
- import { Editor } from '../../../Editor'
4
+ import type { Editor } from '../../../Editor'
5
5
  import { TLBaseBoxShape } from '../../../shapes/BaseBoxShapeUtil'
6
6
  import { TLPointerEventInfo } from '../../../types/event-types'
7
7
  import { StateNode } from '../../StateNode'
8
- import { BaseBoxShapeTool } from '../BaseBoxShapeTool'
8
+ import type { BaseBoxShapeTool } from '../BaseBoxShapeTool'
9
9
 
10
10
  export class Pointing extends StateNode {
11
11
  static override id = 'pointing'
@@ -4,7 +4,7 @@ import { ReactElement, ReactNode, createContext, useContext, useEffect, useState
4
4
  import { ContainerProvider } from '../../hooks/useContainer'
5
5
  import { EditorProvider } from '../../hooks/useEditor'
6
6
  import { useEvent } from '../../hooks/useEvent'
7
- import { Editor } from '../Editor'
7
+ import type { Editor } from '../Editor'
8
8
 
9
9
  /** @public */
10
10
  export interface SvgExportDef {
@@ -2,7 +2,7 @@ import { TLShapeId } from '@tldraw/tlschema'
2
2
  import { assert } from '@tldraw/utils'
3
3
  import { flushSync } from 'react-dom'
4
4
  import { createRoot } from 'react-dom/client'
5
- import { Editor } from '../editor/Editor'
5
+ import type { Editor } from '../editor/Editor'
6
6
  import { TLSvgExportOptions } from '../editor/types/misc-types'
7
7
  import { SVG_EXPORT_CLASSNAME } from './FontEmbedder'
8
8
  import { StyleEmbedder } from './StyleEmbedder'
@@ -20,7 +20,7 @@ import {
20
20
  import { flushSync } from 'react-dom'
21
21
  import { ErrorBoundary } from '../components/ErrorBoundary'
22
22
  import { InnerShape, InnerShapeBackground } from '../components/Shape'
23
- import { Editor, TLRenderingShape } from '../editor/Editor'
23
+ import type { Editor, TLRenderingShape } from '../editor/Editor'
24
24
  import { TLFontFace } from '../editor/managers/FontManager/FontManager'
25
25
  import { ShapeUtil } from '../editor/shapes/ShapeUtil'
26
26
  import {
@@ -0,0 +1,63 @@
1
+ import { ComponentType, RefAttributes, createContext, useContext } from 'react'
2
+ import type { TLBrushProps } from '../components/default-components/DefaultBrush'
3
+ import type { TLCanvasComponentProps } from '../components/default-components/DefaultCanvas'
4
+ import type { TLCollaboratorHintProps } from '../components/default-components/DefaultCollaboratorHint'
5
+ import type { TLCursorProps } from '../components/default-components/DefaultCursor'
6
+ import type { TLErrorFallbackComponent } from '../components/default-components/DefaultErrorFallback'
7
+ import type { TLGridProps } from '../components/default-components/DefaultGrid'
8
+ import type { TLHandleProps } from '../components/default-components/DefaultHandle'
9
+ import type { TLHandlesProps } from '../components/default-components/DefaultHandles'
10
+ import type { TLScribbleProps } from '../components/default-components/DefaultScribble'
11
+ import type { TLSelectionBackgroundProps } from '../components/default-components/DefaultSelectionBackground'
12
+ import type { TLSelectionForegroundProps } from '../components/default-components/DefaultSelectionForeground'
13
+ import type { TLShapeErrorFallbackComponent } from '../components/default-components/DefaultShapeErrorFallback'
14
+ import type { TLShapeIndicatorProps } from '../components/default-components/DefaultShapeIndicator'
15
+ import type { TLShapeIndicatorErrorFallbackComponent } from '../components/default-components/DefaultShapeIndicatorErrorFallback'
16
+ import type { TLShapeWrapperProps } from '../components/default-components/DefaultShapeWrapper'
17
+ import type { TLSnapIndicatorProps } from '../components/default-components/DefaultSnapIndictor'
18
+
19
+ /** @public */
20
+ export interface TLEditorComponents {
21
+ Background?: ComponentType | null
22
+ Brush?: ComponentType<TLBrushProps> | null
23
+ Canvas?: ComponentType<TLCanvasComponentProps> | null
24
+ CollaboratorBrush?: ComponentType<TLBrushProps> | null
25
+ CollaboratorCursor?: ComponentType<TLCursorProps> | null
26
+ CollaboratorHint?: ComponentType<TLCollaboratorHintProps> | null
27
+ CollaboratorScribble?: ComponentType<TLScribbleProps> | null
28
+ CollaboratorShapeIndicator?: ComponentType<TLShapeIndicatorProps> | null
29
+ Cursor?: ComponentType<TLCursorProps> | null
30
+ Grid?: ComponentType<TLGridProps> | null
31
+ Handle?: ComponentType<TLHandleProps> | null
32
+ Handles?: ComponentType<TLHandlesProps> | null
33
+ InFrontOfTheCanvas?: ComponentType | null
34
+ LoadingScreen?: ComponentType | null
35
+ OnTheCanvas?: ComponentType | null
36
+ Overlays?: ComponentType | null
37
+ Scribble?: ComponentType<TLScribbleProps> | null
38
+ SelectionBackground?: ComponentType<TLSelectionBackgroundProps> | null
39
+ SelectionForeground?: ComponentType<TLSelectionForegroundProps> | null
40
+ ShapeIndicator?: ComponentType<TLShapeIndicatorProps> | null
41
+ ShapeIndicators?: ComponentType | null
42
+ ShapeWrapper?: ComponentType<TLShapeWrapperProps & RefAttributes<HTMLDivElement>> | null
43
+ SnapIndicator?: ComponentType<TLSnapIndicatorProps> | null
44
+ Spinner?: ComponentType<React.SVGProps<SVGSVGElement>> | null
45
+ SvgDefs?: ComponentType | null
46
+ ZoomBrush?: ComponentType<TLBrushProps> | null
47
+
48
+ // These will always have defaults
49
+ ErrorFallback?: TLErrorFallbackComponent
50
+ ShapeErrorFallback?: TLShapeErrorFallbackComponent
51
+ ShapeIndicatorErrorFallback?: TLShapeIndicatorErrorFallbackComponent
52
+ }
53
+
54
+ export const EditorComponentsContext = createContext<null | Required<TLEditorComponents>>(null)
55
+
56
+ /** @public */
57
+ export function useEditorComponents() {
58
+ const components = useContext(EditorComponentsContext)
59
+ if (!components) {
60
+ throw new Error('useEditorComponents must be used inside of <EditorComponentsProvider />')
61
+ }
62
+ return components
63
+ }
@@ -102,13 +102,24 @@ export function useCanvasEvents() {
102
102
  preventDefault(e)
103
103
  e.stopPropagation()
104
104
 
105
+ const pagePoint = editor.screenToPage({ x: e.clientX, y: e.clientY })
106
+
107
+ // Call the custom onDropOnCanvas callback if provided
108
+ if (editor.options.experimental__onDropOnCanvas) {
109
+ const handled = editor.options.experimental__onDropOnCanvas({
110
+ point: pagePoint,
111
+ event: e,
112
+ })
113
+ if (handled) return
114
+ }
115
+
105
116
  if (e.dataTransfer?.files?.length) {
106
117
  const files = Array.from(e.dataTransfer.files)
107
118
 
108
119
  await editor.putExternalContent({
109
120
  type: 'files',
110
121
  files,
111
- point: editor.screenToPage({ x: e.clientX, y: e.clientY }),
122
+ point: pagePoint,
112
123
  })
113
124
  return
114
125
  }
@@ -118,7 +129,7 @@ export function useCanvasEvents() {
118
129
  await editor.putExternalContent({
119
130
  type: 'url',
120
131
  url,
121
- point: editor.screenToPage({ x: e.clientX, y: e.clientY }),
132
+ point: pagePoint,
122
133
  })
123
134
  return
124
135
  }