@tldraw/editor 4.6.0-next.30b99cd52fc8 → 4.6.0-next.35cf541abcf9

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 (284) hide show
  1. package/dist-cjs/index.d.ts +758 -96
  2. package/dist-cjs/index.js +18 -3
  3. package/dist-cjs/index.js.map +3 -3
  4. package/dist-cjs/lib/TldrawEditor.js +55 -12
  5. package/dist-cjs/lib/TldrawEditor.js.map +3 -3
  6. package/dist-cjs/lib/components/LiveCollaborators.js +1 -0
  7. package/dist-cjs/lib/components/LiveCollaborators.js.map +2 -2
  8. package/dist-cjs/lib/components/MenuClickCapture.js +99 -38
  9. package/dist-cjs/lib/components/MenuClickCapture.js.map +2 -2
  10. package/dist-cjs/lib/components/default-components/CanvasShapeIndicators.js +10 -3
  11. package/dist-cjs/lib/components/default-components/CanvasShapeIndicators.js.map +3 -3
  12. package/dist-cjs/lib/components/default-components/DefaultCanvas.js +5 -2
  13. package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
  14. package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js +1 -1
  15. package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js.map +2 -2
  16. package/dist-cjs/lib/components/default-components/DefaultShapeIndicators.js +1 -0
  17. package/dist-cjs/lib/components/default-components/DefaultShapeIndicators.js.map +2 -2
  18. package/dist-cjs/lib/config/createTLStore.js +7 -0
  19. package/dist-cjs/lib/config/createTLStore.js.map +2 -2
  20. package/dist-cjs/lib/config/defaultAssets.js +36 -0
  21. package/dist-cjs/lib/config/defaultAssets.js.map +7 -0
  22. package/dist-cjs/lib/editor/Editor.js +279 -10
  23. package/dist-cjs/lib/editor/Editor.js.map +2 -2
  24. package/dist-cjs/lib/editor/assets/AssetUtil.js +67 -0
  25. package/dist-cjs/lib/editor/assets/AssetUtil.js.map +7 -0
  26. package/dist-cjs/lib/editor/bindings/BindingUtil.js +1 -0
  27. package/dist-cjs/lib/editor/bindings/BindingUtil.js.map +1 -1
  28. package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js +1 -0
  29. package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js.map +1 -1
  30. package/dist-cjs/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.js +1 -0
  31. package/dist-cjs/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.js.map +1 -1
  32. package/dist-cjs/lib/editor/managers/FocusManager/FocusManager.js +1 -0
  33. package/dist-cjs/lib/editor/managers/FocusManager/FocusManager.js.map +1 -1
  34. package/dist-cjs/lib/editor/managers/FontManager/FontManager.js +2 -0
  35. package/dist-cjs/lib/editor/managers/FontManager/FontManager.js.map +2 -2
  36. package/dist-cjs/lib/editor/managers/HistoryManager/HistoryManager.js +2 -0
  37. package/dist-cjs/lib/editor/managers/HistoryManager/HistoryManager.js.map +1 -1
  38. package/dist-cjs/lib/editor/managers/InputsManager/InputsManager.js +12 -0
  39. package/dist-cjs/lib/editor/managers/InputsManager/InputsManager.js.map +2 -2
  40. package/dist-cjs/lib/editor/managers/PerformanceManager/PerformanceApiAdapter.js +80 -0
  41. package/dist-cjs/lib/editor/managers/PerformanceManager/PerformanceApiAdapter.js.map +7 -0
  42. package/dist-cjs/lib/editor/managers/PerformanceManager/PerformanceManager.js +466 -0
  43. package/dist-cjs/lib/editor/managers/PerformanceManager/PerformanceManager.js.map +7 -0
  44. package/dist-cjs/lib/editor/managers/PerformanceManager/perf-types.js +17 -0
  45. package/dist-cjs/lib/editor/managers/PerformanceManager/perf-types.js.map +7 -0
  46. package/dist-cjs/lib/editor/managers/ScribbleManager/ScribbleManager.js +1 -0
  47. package/dist-cjs/lib/editor/managers/ScribbleManager/ScribbleManager.js.map +1 -1
  48. package/dist-cjs/lib/editor/managers/SnapManager/BoundsSnaps.js +1 -0
  49. package/dist-cjs/lib/editor/managers/SnapManager/BoundsSnaps.js.map +1 -1
  50. package/dist-cjs/lib/editor/managers/SnapManager/HandleSnaps.js +1 -0
  51. package/dist-cjs/lib/editor/managers/SnapManager/HandleSnaps.js.map +1 -1
  52. package/dist-cjs/lib/editor/managers/SnapManager/SnapManager.js +2 -1
  53. package/dist-cjs/lib/editor/managers/SnapManager/SnapManager.js.map +2 -2
  54. package/dist-cjs/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.js +1 -0
  55. package/dist-cjs/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.js.map +1 -1
  56. package/dist-cjs/lib/editor/managers/TextManager/TextManager.js +1 -0
  57. package/dist-cjs/lib/editor/managers/TextManager/TextManager.js.map +1 -1
  58. package/dist-cjs/lib/editor/managers/ThemeManager/ThemeManager.js +107 -0
  59. package/dist-cjs/lib/editor/managers/ThemeManager/ThemeManager.js.map +7 -0
  60. package/dist-cjs/lib/editor/managers/ThemeManager/defaultThemes.js +586 -0
  61. package/dist-cjs/lib/editor/managers/ThemeManager/defaultThemes.js.map +7 -0
  62. package/dist-cjs/lib/editor/managers/TickManager/TickManager.js +1 -0
  63. package/dist-cjs/lib/editor/managers/TickManager/TickManager.js.map +1 -1
  64. package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js +8 -4
  65. package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js.map +2 -2
  66. package/dist-cjs/lib/editor/shapes/BaseFrameLikeShapeUtil.js +76 -0
  67. package/dist-cjs/lib/editor/shapes/BaseFrameLikeShapeUtil.js.map +7 -0
  68. package/dist-cjs/lib/editor/shapes/ShapeUtil.js +22 -2
  69. package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
  70. package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js +1 -1
  71. package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js.map +2 -2
  72. package/dist-cjs/lib/editor/shapes/shared/getPerfectDashProps.js +6 -0
  73. package/dist-cjs/lib/editor/shapes/shared/getPerfectDashProps.js.map +2 -2
  74. package/dist-cjs/lib/editor/tools/StateNode.js +15 -17
  75. package/dist-cjs/lib/editor/tools/StateNode.js.map +2 -2
  76. package/dist-cjs/lib/editor/types/SvgExportContext.js.map +2 -2
  77. package/dist-cjs/lib/editor/types/external-content.js.map +1 -1
  78. package/dist-cjs/lib/exports/ExportDelay.js +1 -0
  79. package/dist-cjs/lib/exports/ExportDelay.js.map +1 -1
  80. package/dist-cjs/lib/exports/StyleEmbedder.js +1 -0
  81. package/dist-cjs/lib/exports/StyleEmbedder.js.map +1 -1
  82. package/dist-cjs/lib/exports/getSvgJsx.js +14 -8
  83. package/dist-cjs/lib/exports/getSvgJsx.js.map +2 -2
  84. package/dist-cjs/lib/globals/environment.js +18 -1
  85. package/dist-cjs/lib/globals/environment.js.map +2 -2
  86. package/dist-cjs/lib/hooks/useCanvasEvents.js +25 -4
  87. package/dist-cjs/lib/hooks/useCanvasEvents.js.map +2 -2
  88. package/dist-cjs/lib/hooks/{useIsDarkMode.js → useColorMode.js} +14 -10
  89. package/dist-cjs/lib/hooks/useColorMode.js.map +7 -0
  90. package/dist-cjs/lib/hooks/useCursor.js +3 -7
  91. package/dist-cjs/lib/hooks/useCursor.js.map +2 -2
  92. package/dist-cjs/lib/hooks/useDarkMode.js +4 -4
  93. package/dist-cjs/lib/hooks/useDarkMode.js.map +2 -2
  94. package/dist-cjs/lib/options.js +2 -0
  95. package/dist-cjs/lib/options.js.map +2 -2
  96. package/dist-cjs/lib/primitives/Vec.js +3 -0
  97. package/dist-cjs/lib/primitives/Vec.js.map +1 -1
  98. package/dist-cjs/lib/primitives/geometry/Circle2d.js +1 -0
  99. package/dist-cjs/lib/primitives/geometry/Circle2d.js.map +1 -1
  100. package/dist-cjs/lib/primitives/geometry/Ellipse2d.js +1 -0
  101. package/dist-cjs/lib/primitives/geometry/Ellipse2d.js.map +1 -1
  102. package/dist-cjs/lib/primitives/geometry/Geometry2d.js +2 -0
  103. package/dist-cjs/lib/primitives/geometry/Geometry2d.js.map +1 -1
  104. package/dist-cjs/lib/primitives/geometry/Stadium2d.js +1 -0
  105. package/dist-cjs/lib/primitives/geometry/Stadium2d.js.map +1 -1
  106. package/dist-cjs/lib/utils/EditorAtom.js +2 -0
  107. package/dist-cjs/lib/utils/EditorAtom.js.map +1 -1
  108. package/dist-cjs/lib/utils/reparenting.js +2 -1
  109. package/dist-cjs/lib/utils/reparenting.js.map +2 -2
  110. package/dist-cjs/lib/utils/richText.js.map +2 -2
  111. package/dist-cjs/lib/utils/runtime.js +2 -1
  112. package/dist-cjs/lib/utils/runtime.js.map +2 -2
  113. package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js +2 -0
  114. package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js.map +1 -1
  115. package/dist-cjs/lib/utils/sync/hardReset.js +0 -8
  116. package/dist-cjs/lib/utils/sync/hardReset.js.map +2 -2
  117. package/dist-cjs/version.js +3 -3
  118. package/dist-cjs/version.js.map +1 -1
  119. package/dist-esm/index.d.mts +758 -96
  120. package/dist-esm/index.mjs +19 -6
  121. package/dist-esm/index.mjs.map +2 -2
  122. package/dist-esm/lib/TldrawEditor.mjs +58 -12
  123. package/dist-esm/lib/TldrawEditor.mjs.map +3 -3
  124. package/dist-esm/lib/components/LiveCollaborators.mjs +1 -0
  125. package/dist-esm/lib/components/LiveCollaborators.mjs.map +2 -2
  126. package/dist-esm/lib/components/MenuClickCapture.mjs +100 -39
  127. package/dist-esm/lib/components/MenuClickCapture.mjs.map +2 -2
  128. package/dist-esm/lib/components/default-components/CanvasShapeIndicators.mjs +10 -3
  129. package/dist-esm/lib/components/default-components/CanvasShapeIndicators.mjs.map +3 -3
  130. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +5 -2
  131. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
  132. package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs +1 -1
  133. package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs.map +2 -2
  134. package/dist-esm/lib/components/default-components/DefaultShapeIndicators.mjs +1 -0
  135. package/dist-esm/lib/components/default-components/DefaultShapeIndicators.mjs.map +2 -2
  136. package/dist-esm/lib/config/createTLStore.mjs +10 -1
  137. package/dist-esm/lib/config/createTLStore.mjs.map +2 -2
  138. package/dist-esm/lib/config/defaultAssets.mjs +16 -0
  139. package/dist-esm/lib/config/defaultAssets.mjs.map +7 -0
  140. package/dist-esm/lib/editor/Editor.mjs +279 -10
  141. package/dist-esm/lib/editor/Editor.mjs.map +2 -2
  142. package/dist-esm/lib/editor/assets/AssetUtil.mjs +47 -0
  143. package/dist-esm/lib/editor/assets/AssetUtil.mjs.map +7 -0
  144. package/dist-esm/lib/editor/bindings/BindingUtil.mjs +1 -0
  145. package/dist-esm/lib/editor/bindings/BindingUtil.mjs.map +1 -1
  146. package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs +1 -0
  147. package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs.map +1 -1
  148. package/dist-esm/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.mjs +1 -0
  149. package/dist-esm/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.mjs.map +1 -1
  150. package/dist-esm/lib/editor/managers/FocusManager/FocusManager.mjs +1 -0
  151. package/dist-esm/lib/editor/managers/FocusManager/FocusManager.mjs.map +1 -1
  152. package/dist-esm/lib/editor/managers/FontManager/FontManager.mjs +2 -0
  153. package/dist-esm/lib/editor/managers/FontManager/FontManager.mjs.map +2 -2
  154. package/dist-esm/lib/editor/managers/HistoryManager/HistoryManager.mjs +2 -0
  155. package/dist-esm/lib/editor/managers/HistoryManager/HistoryManager.mjs.map +1 -1
  156. package/dist-esm/lib/editor/managers/InputsManager/InputsManager.mjs +12 -0
  157. package/dist-esm/lib/editor/managers/InputsManager/InputsManager.mjs.map +2 -2
  158. package/dist-esm/lib/editor/managers/PerformanceManager/PerformanceApiAdapter.mjs +60 -0
  159. package/dist-esm/lib/editor/managers/PerformanceManager/PerformanceApiAdapter.mjs.map +7 -0
  160. package/dist-esm/lib/editor/managers/PerformanceManager/PerformanceManager.mjs +438 -0
  161. package/dist-esm/lib/editor/managers/PerformanceManager/PerformanceManager.mjs.map +7 -0
  162. package/dist-esm/lib/editor/managers/PerformanceManager/perf-types.mjs +1 -0
  163. package/dist-esm/lib/editor/managers/PerformanceManager/perf-types.mjs.map +7 -0
  164. package/dist-esm/lib/editor/managers/ScribbleManager/ScribbleManager.mjs +1 -0
  165. package/dist-esm/lib/editor/managers/ScribbleManager/ScribbleManager.mjs.map +1 -1
  166. package/dist-esm/lib/editor/managers/SnapManager/BoundsSnaps.mjs +1 -0
  167. package/dist-esm/lib/editor/managers/SnapManager/BoundsSnaps.mjs.map +1 -1
  168. package/dist-esm/lib/editor/managers/SnapManager/HandleSnaps.mjs +1 -0
  169. package/dist-esm/lib/editor/managers/SnapManager/HandleSnaps.mjs.map +1 -1
  170. package/dist-esm/lib/editor/managers/SnapManager/SnapManager.mjs +2 -1
  171. package/dist-esm/lib/editor/managers/SnapManager/SnapManager.mjs.map +2 -2
  172. package/dist-esm/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.mjs +1 -0
  173. package/dist-esm/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.mjs.map +1 -1
  174. package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs +1 -0
  175. package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs.map +1 -1
  176. package/dist-esm/lib/editor/managers/ThemeManager/ThemeManager.mjs +89 -0
  177. package/dist-esm/lib/editor/managers/ThemeManager/ThemeManager.mjs.map +7 -0
  178. package/dist-esm/lib/editor/managers/ThemeManager/defaultThemes.mjs +568 -0
  179. package/dist-esm/lib/editor/managers/ThemeManager/defaultThemes.mjs.map +7 -0
  180. package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs +1 -0
  181. package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs.map +1 -1
  182. package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs +8 -4
  183. package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs.map +2 -2
  184. package/dist-esm/lib/editor/shapes/BaseFrameLikeShapeUtil.mjs +56 -0
  185. package/dist-esm/lib/editor/shapes/BaseFrameLikeShapeUtil.mjs.map +7 -0
  186. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs +22 -2
  187. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
  188. package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs +1 -1
  189. package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs.map +2 -2
  190. package/dist-esm/lib/editor/shapes/shared/getPerfectDashProps.mjs +6 -0
  191. package/dist-esm/lib/editor/shapes/shared/getPerfectDashProps.mjs.map +2 -2
  192. package/dist-esm/lib/editor/tools/StateNode.mjs +15 -17
  193. package/dist-esm/lib/editor/tools/StateNode.mjs.map +2 -2
  194. package/dist-esm/lib/editor/types/SvgExportContext.mjs.map +2 -2
  195. package/dist-esm/lib/exports/ExportDelay.mjs +1 -0
  196. package/dist-esm/lib/exports/ExportDelay.mjs.map +1 -1
  197. package/dist-esm/lib/exports/StyleEmbedder.mjs +1 -0
  198. package/dist-esm/lib/exports/StyleEmbedder.mjs.map +1 -1
  199. package/dist-esm/lib/exports/getSvgJsx.mjs +14 -11
  200. package/dist-esm/lib/exports/getSvgJsx.mjs.map +2 -2
  201. package/dist-esm/lib/globals/environment.mjs +18 -1
  202. package/dist-esm/lib/globals/environment.mjs.map +2 -2
  203. package/dist-esm/lib/hooks/useCanvasEvents.mjs +25 -4
  204. package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +2 -2
  205. package/dist-esm/lib/hooks/useColorMode.mjs +19 -0
  206. package/dist-esm/lib/hooks/useColorMode.mjs.map +7 -0
  207. package/dist-esm/lib/hooks/useCursor.mjs +3 -7
  208. package/dist-esm/lib/hooks/useCursor.mjs.map +2 -2
  209. package/dist-esm/lib/hooks/useDarkMode.mjs +4 -4
  210. package/dist-esm/lib/hooks/useDarkMode.mjs.map +2 -2
  211. package/dist-esm/lib/options.mjs +2 -0
  212. package/dist-esm/lib/options.mjs.map +2 -2
  213. package/dist-esm/lib/primitives/Vec.mjs +3 -0
  214. package/dist-esm/lib/primitives/Vec.mjs.map +1 -1
  215. package/dist-esm/lib/primitives/geometry/Circle2d.mjs +1 -0
  216. package/dist-esm/lib/primitives/geometry/Circle2d.mjs.map +1 -1
  217. package/dist-esm/lib/primitives/geometry/Ellipse2d.mjs +1 -0
  218. package/dist-esm/lib/primitives/geometry/Ellipse2d.mjs.map +1 -1
  219. package/dist-esm/lib/primitives/geometry/Geometry2d.mjs +2 -0
  220. package/dist-esm/lib/primitives/geometry/Geometry2d.mjs.map +1 -1
  221. package/dist-esm/lib/primitives/geometry/Stadium2d.mjs +1 -0
  222. package/dist-esm/lib/primitives/geometry/Stadium2d.mjs.map +1 -1
  223. package/dist-esm/lib/utils/EditorAtom.mjs +2 -0
  224. package/dist-esm/lib/utils/EditorAtom.mjs.map +1 -1
  225. package/dist-esm/lib/utils/reparenting.mjs +2 -1
  226. package/dist-esm/lib/utils/reparenting.mjs.map +2 -2
  227. package/dist-esm/lib/utils/richText.mjs.map +2 -2
  228. package/dist-esm/lib/utils/runtime.mjs +2 -1
  229. package/dist-esm/lib/utils/runtime.mjs.map +2 -2
  230. package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs +2 -0
  231. package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs.map +1 -1
  232. package/dist-esm/lib/utils/sync/hardReset.mjs +0 -8
  233. package/dist-esm/lib/utils/sync/hardReset.mjs.map +2 -2
  234. package/dist-esm/version.mjs +3 -3
  235. package/dist-esm/version.mjs.map +1 -1
  236. package/editor.css +0 -37
  237. package/package.json +7 -7
  238. package/src/index.ts +24 -6
  239. package/src/lib/TldrawEditor.tsx +90 -13
  240. package/src/lib/components/LiveCollaborators.tsx +8 -2
  241. package/src/lib/components/MenuClickCapture.tsx +129 -49
  242. package/src/lib/components/default-components/CanvasShapeIndicators.tsx +14 -3
  243. package/src/lib/components/default-components/DefaultCanvas.tsx +6 -2
  244. package/src/lib/components/default-components/DefaultShapeIndicator.tsx +2 -2
  245. package/src/lib/components/default-components/DefaultShapeIndicators.tsx +2 -0
  246. package/src/lib/config/createTLStore.ts +22 -1
  247. package/src/lib/config/defaultAssets.ts +19 -0
  248. package/src/lib/editor/Editor.ts +387 -40
  249. package/src/lib/editor/assets/AssetUtil.ts +85 -0
  250. package/src/lib/editor/managers/FontManager/FontManager.test.ts +9 -2
  251. package/src/lib/editor/managers/FontManager/FontManager.ts +1 -67
  252. package/src/lib/editor/managers/InputsManager/InputsManager.ts +12 -0
  253. package/src/lib/editor/managers/PerformanceManager/PerformanceApiAdapter.ts +82 -0
  254. package/src/lib/editor/managers/PerformanceManager/PerformanceManager.test.ts +522 -0
  255. package/src/lib/editor/managers/PerformanceManager/PerformanceManager.ts +583 -0
  256. package/src/lib/editor/managers/PerformanceManager/perf-types.ts +196 -0
  257. package/src/lib/editor/managers/SnapManager/SnapManager.test.ts +13 -2
  258. package/src/lib/editor/managers/SnapManager/SnapManager.ts +1 -1
  259. package/src/lib/editor/managers/ThemeManager/ThemeManager.ts +116 -0
  260. package/src/lib/editor/managers/ThemeManager/defaultThemes.ts +605 -0
  261. package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.test.ts +23 -29
  262. package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.ts +5 -3
  263. package/src/lib/editor/shapes/BaseFrameLikeShapeUtil.tsx +121 -0
  264. package/src/lib/editor/shapes/ShapeUtil.ts +39 -3
  265. package/src/lib/editor/shapes/group/GroupShapeUtil.tsx +1 -1
  266. package/src/lib/editor/shapes/shared/getPerfectDashProps.ts +7 -0
  267. package/src/lib/editor/tools/StateNode.ts +16 -18
  268. package/src/lib/editor/types/SvgExportContext.tsx +5 -0
  269. package/src/lib/editor/types/external-content.ts +1 -0
  270. package/src/lib/exports/getSvgJsx.tsx +23 -16
  271. package/src/lib/globals/environment.ts +18 -0
  272. package/src/lib/hooks/useCanvasEvents.ts +40 -3
  273. package/src/lib/hooks/{useIsDarkMode.ts → useColorMode.ts} +9 -5
  274. package/src/lib/hooks/useCursor.ts +3 -7
  275. package/src/lib/hooks/useDarkMode.ts +4 -4
  276. package/src/lib/options.ts +14 -0
  277. package/src/lib/utils/reparenting.ts +6 -2
  278. package/src/lib/utils/richText.ts +1 -1
  279. package/src/lib/utils/runtime.ts +3 -1
  280. package/src/lib/utils/sync/hardReset.ts +0 -8
  281. package/src/version.ts +3 -3
  282. package/dist-cjs/lib/hooks/useIsDarkMode.js.map +0 -7
  283. package/dist-esm/lib/hooks/useIsDarkMode.mjs +0 -15
  284. package/dist-esm/lib/hooks/useIsDarkMode.mjs.map +0 -7
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/editor/types/SvgExportContext.tsx"],
4
- "sourcesContent": ["import { TLAssetId } from '@tldraw/tlschema'\nimport { promiseWithResolve } from '@tldraw/utils'\nimport { ReactElement, ReactNode, createContext, useContext, useEffect, useState } from 'react'\nimport { ContainerProvider } from '../../hooks/useContainer'\nimport { EditorProvider } from '../../hooks/useEditor'\nimport { useEvent } from '../../hooks/useEvent'\nimport type { Editor } from '../Editor'\n\n/** @public */\nexport interface SvgExportDef {\n\tkey: string\n\tgetElement(): Promise<ReactElement | null> | ReactElement | null\n}\n\n/** @public */\nexport interface SvgExportContext {\n\t/**\n\t * Add contents to the `<defs>` section of the export SVG. Each export def should have a unique\n\t * key. If multiple defs come with the same key, only one will be added.\n\t */\n\taddExportDef(def: SvgExportDef): void\n\n\t/**\n\t * Cause the SVG export to be delayed until the returned promise is resolved. This is useful if\n\t * e.g. your shape loads data dynamically, and you need to prevent the export from happening\n\t * until after the data is loaded.\n\t *\n\t * See also the {@link useDelaySvgExport} hook, which may be a more convenient way to use this\n\t * method depending on your use-case.\n\t */\n\twaitUntil(promise: Promise<void>): void\n\n\t/**\n\t * Resolve an asset URL in the context of this export. Supply the asset ID and the width in\n\t * shape-pixels it'll be displayed at, and this will resolve the asset according to the export\n\t * options.\n\t */\n\tresolveAssetUrl(assetId: TLAssetId, width: number): Promise<string | null>\n\n\t/**\n\t * Whether the export should be in dark mode.\n\t */\n\treadonly isDarkMode: boolean\n\n\t/**\n\t * The scale of the export - how much CSS pixels will be scaled up/down by.\n\t */\n\treadonly scale: number\n\n\t/**\n\t * Use this value to optionally downscale images in the export. If we're exporting directly to\n\t * an SVG, this will usually be null, and you shouldn't downscale images. If the export is to a\n\t * raster format like PNG, this will be the number of raster pixels in the resulting bitmap per\n\t * CSS pixel in the resulting SVG.\n\t */\n\treadonly pixelRatio: number | null\n}\n\nconst Context = createContext<SvgExportContext | null>(null)\nexport function SvgExportContextProvider({\n\tcontext,\n\teditor,\n\tchildren,\n}: {\n\tcontext: SvgExportContext\n\teditor: Editor\n\tchildren: ReactNode\n}) {\n\tconst Provider = editor.options.exportProvider\n\n\treturn (\n\t\t<EditorProvider editor={editor}>\n\t\t\t<ContainerProvider container={editor.getContainer()}>\n\t\t\t\t<Context.Provider value={context}>\n\t\t\t\t\t<Provider>{children}</Provider>\n\t\t\t\t</Context.Provider>\n\t\t\t</ContainerProvider>\n\t\t</EditorProvider>\n\t)\n}\n\n/**\n * Returns the current SVG export context. Returns null if the component isn't being rendered for an\n * SVG export.\n *\n * @public\n */\nexport function useSvgExportContext() {\n\treturn useContext(Context)\n}\n\n/**\n * Delay an SVG export until the returned function is called. This is useful if e.g. your shape\n * loads data dynamically, and you need to prevent the export from happening until after the data is\n * loaded.\n *\n * If used outside of an SVG export, this hook has no effect.\n *\n * @example\n * ```tsx\n * const readyForExport = useDelaySvgExport()\n *\n * return <MyDynamicComponent onDataLoaded={() => readyForExport()} />\n * ```\n *\n * @public\n */\nexport function useDelaySvgExport() {\n\tconst ctx = useContext(Context)\n\tconst [promise] = useState(promiseWithResolve<void>)\n\n\tuseEffect(() => {\n\t\tctx?.waitUntil(promise)\n\t\treturn () => {\n\t\t\tpromise.resolve()\n\t\t}\n\t}, [promise, ctx])\n\n\treturn useEvent(() => {\n\t\tpromise.resolve()\n\t})\n}\n"],
5
- "mappings": "AA0EK;AAzEL,SAAS,0BAA0B;AACnC,SAAkC,eAAe,YAAY,WAAW,gBAAgB;AACxF,SAAS,yBAAyB;AAClC,SAAS,sBAAsB;AAC/B,SAAS,gBAAgB;AAqDzB,MAAM,UAAU,cAAuC,IAAI;AACpD,SAAS,yBAAyB;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AACD,GAIG;AACF,QAAM,WAAW,OAAO,QAAQ;AAEhC,SACC,oBAAC,kBAAe,QACf,8BAAC,qBAAkB,WAAW,OAAO,aAAa,GACjD,8BAAC,QAAQ,UAAR,EAAiB,OAAO,SACxB,8BAAC,YAAU,UAAS,GACrB,GACD,GACD;AAEF;AAQO,SAAS,sBAAsB;AACrC,SAAO,WAAW,OAAO;AAC1B;AAkBO,SAAS,oBAAoB;AACnC,QAAM,MAAM,WAAW,OAAO;AAC9B,QAAM,CAAC,OAAO,IAAI,SAAS,kBAAwB;AAEnD,YAAU,MAAM;AACf,SAAK,UAAU,OAAO;AACtB,WAAO,MAAM;AACZ,cAAQ,QAAQ;AAAA,IACjB;AAAA,EACD,GAAG,CAAC,SAAS,GAAG,CAAC;AAEjB,SAAO,SAAS,MAAM;AACrB,YAAQ,QAAQ;AAAA,EACjB,CAAC;AACF;",
4
+ "sourcesContent": ["import { TLAssetId } from '@tldraw/tlschema'\nimport { promiseWithResolve } from '@tldraw/utils'\nimport { ReactElement, ReactNode, createContext, useContext, useEffect, useState } from 'react'\nimport { ContainerProvider } from '../../hooks/useContainer'\nimport { EditorProvider } from '../../hooks/useEditor'\nimport { useEvent } from '../../hooks/useEvent'\nimport type { Editor } from '../Editor'\n\n/** @public */\nexport interface SvgExportDef {\n\tkey: string\n\tgetElement(): Promise<ReactElement | null> | ReactElement | null\n}\n\n/** @public */\nexport interface SvgExportContext {\n\t/**\n\t * Add contents to the `<defs>` section of the export SVG. Each export def should have a unique\n\t * key. If multiple defs come with the same key, only one will be added.\n\t */\n\taddExportDef(def: SvgExportDef): void\n\n\t/**\n\t * Cause the SVG export to be delayed until the returned promise is resolved. This is useful if\n\t * e.g. your shape loads data dynamically, and you need to prevent the export from happening\n\t * until after the data is loaded.\n\t *\n\t * See also the {@link useDelaySvgExport} hook, which may be a more convenient way to use this\n\t * method depending on your use-case.\n\t */\n\twaitUntil(promise: Promise<void>): void\n\n\t/**\n\t * Resolve an asset URL in the context of this export. Supply the asset ID and the width in\n\t * shape-pixels it'll be displayed at, and this will resolve the asset according to the export\n\t * options.\n\t */\n\tresolveAssetUrl(assetId: TLAssetId, width: number): Promise<string | null>\n\n\t/**\n\t * Whether the export should be in dark mode.\n\t */\n\treadonly isDarkMode: boolean\n\n\t/**\n\t * The color mode to use for this export.\n\t */\n\treadonly colorMode: 'light' | 'dark'\n\n\t/**\n\t * The scale of the export - how much CSS pixels will be scaled up/down by.\n\t */\n\treadonly scale: number\n\n\t/**\n\t * Use this value to optionally downscale images in the export. If we're exporting directly to\n\t * an SVG, this will usually be null, and you shouldn't downscale images. If the export is to a\n\t * raster format like PNG, this will be the number of raster pixels in the resulting bitmap per\n\t * CSS pixel in the resulting SVG.\n\t */\n\treadonly pixelRatio: number | null\n}\n\nconst Context = createContext<SvgExportContext | null>(null)\nexport function SvgExportContextProvider({\n\tcontext,\n\teditor,\n\tchildren,\n}: {\n\tcontext: SvgExportContext\n\teditor: Editor\n\tchildren: ReactNode\n}) {\n\tconst Provider = editor.options.exportProvider\n\n\treturn (\n\t\t<EditorProvider editor={editor}>\n\t\t\t<ContainerProvider container={editor.getContainer()}>\n\t\t\t\t<Context.Provider value={context}>\n\t\t\t\t\t<Provider>{children}</Provider>\n\t\t\t\t</Context.Provider>\n\t\t\t</ContainerProvider>\n\t\t</EditorProvider>\n\t)\n}\n\n/**\n * Returns the current SVG export context. Returns null if the component isn't being rendered for an\n * SVG export.\n *\n * @public\n */\nexport function useSvgExportContext() {\n\treturn useContext(Context)\n}\n\n/**\n * Delay an SVG export until the returned function is called. This is useful if e.g. your shape\n * loads data dynamically, and you need to prevent the export from happening until after the data is\n * loaded.\n *\n * If used outside of an SVG export, this hook has no effect.\n *\n * @example\n * ```tsx\n * const readyForExport = useDelaySvgExport()\n *\n * return <MyDynamicComponent onDataLoaded={() => readyForExport()} />\n * ```\n *\n * @public\n */\nexport function useDelaySvgExport() {\n\tconst ctx = useContext(Context)\n\tconst [promise] = useState(promiseWithResolve<void>)\n\n\tuseEffect(() => {\n\t\tctx?.waitUntil(promise)\n\t\treturn () => {\n\t\t\tpromise.resolve()\n\t\t}\n\t}, [promise, ctx])\n\n\treturn useEvent(() => {\n\t\tpromise.resolve()\n\t})\n}\n"],
5
+ "mappings": "AA+EK;AA9EL,SAAS,0BAA0B;AACnC,SAAkC,eAAe,YAAY,WAAW,gBAAgB;AACxF,SAAS,yBAAyB;AAClC,SAAS,sBAAsB;AAC/B,SAAS,gBAAgB;AA0DzB,MAAM,UAAU,cAAuC,IAAI;AACpD,SAAS,yBAAyB;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AACD,GAIG;AACF,QAAM,WAAW,OAAO,QAAQ;AAEhC,SACC,oBAAC,kBAAe,QACf,8BAAC,qBAAkB,WAAW,OAAO,aAAa,GACjD,8BAAC,QAAQ,UAAR,EAAiB,OAAO,SACxB,8BAAC,YAAU,UAAS,GACrB,GACD,GACD;AAEF;AAQO,SAAS,sBAAsB;AACrC,SAAO,WAAW,OAAO;AAC1B;AAkBO,SAAS,oBAAoB;AACnC,QAAM,MAAM,WAAW,OAAO;AAC9B,QAAM,CAAC,OAAO,IAAI,SAAS,kBAAwB;AAEnD,YAAU,MAAM;AACf,SAAK,UAAU,OAAO;AACtB,WAAO,MAAM;AACZ,cAAQ,QAAQ;AAAA,IACjB;AAAA,EACD,GAAG,CAAC,SAAS,GAAG,CAAC;AAEjB,SAAO,SAAS,MAAM;AACrB,YAAQ,QAAQ;AAAA,EACjB,CAAC;AACF;",
6
6
  "names": []
7
7
  }
@@ -13,6 +13,7 @@ class ExportDelay {
13
13
  constructor(maxDelayTimeMs) {
14
14
  this.maxDelayTimeMs = maxDelayTimeMs;
15
15
  }
16
+ maxDelayTimeMs;
16
17
  isResolved = false;
17
18
  promisesToWaitFor = [];
18
19
  waitUntil(promise) {
@@ -2,6 +2,6 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/exports/ExportDelay.tsx"],
4
4
  "sourcesContent": ["import { bind, sleep } from '@tldraw/utils'\n\n/**\n * Export delay is a helper class that allows you to wait for a set of promises to resolve before\n * proceeding with an export. Over time, promises can be added by calling `waitUntil`.\n *\n * When `resolve` is called, we'll wait for all the promises already added (and any new ones added\n * in the mean time) to resolve before proceeding. The class is designed to be used once: after\n * `resolve` has been called and finished, new promises cannot be added.\n */\nexport class ExportDelay {\n\tprivate isResolved = false\n\tprivate readonly promisesToWaitFor: Promise<void>[] = []\n\n\tconstructor(private readonly maxDelayTimeMs: number) {}\n\n\t@bind waitUntil(promise: Promise<void>): void {\n\t\tif (this.isResolved) {\n\t\t\tthrow new Error(\n\t\t\t\t'Cannot `waitUntil` - the export has already been resolved. Make sure to call `waitUntil` as soon as possible during an export - ie within the first react effect after rendering.'\n\t\t\t)\n\t\t}\n\t\tthis.promisesToWaitFor.push(\n\t\t\tpromise.catch((err) => console.error('Error while waiting for export:', err))\n\t\t)\n\t}\n\n\tprivate async resolvePromises() {\n\t\tlet lastLength = null\n\t\twhile (this.promisesToWaitFor.length !== lastLength) {\n\t\t\tlastLength = this.promisesToWaitFor.length\n\t\t\tawait Promise.allSettled(this.promisesToWaitFor)\n\n\t\t\t// wait for a cycle of the event loop to allow any of those promises to add more if needed.\n\t\t\tawait sleep(0)\n\t\t}\n\t}\n\n\tasync resolve() {\n\t\tconst timeoutPromise = sleep(this.maxDelayTimeMs).then(() => 'timeout' as const)\n\t\tconst resolvePromise = this.resolvePromises().then(() => 'resolved' as const)\n\n\t\tconst result = await Promise.race([timeoutPromise, resolvePromise])\n\t\tif (result === 'timeout') {\n\t\t\tconsole.warn('[tldraw] Export delay timed out after ${this.maxDelayTimeMs}ms')\n\t\t}\n\n\t\tthis.isResolved = true\n\t}\n}\n"],
5
- "mappings": ";;;;;;;;;;AAAA,SAAS,MAAM,aAAa;AAUrB,MAAM,YAAY;AAAA,EAIxB,YAA6B,gBAAwB;AAAxB;AAAA,EAAyB;AAAA,EAH9C,aAAa;AAAA,EACJ,oBAAqC,CAAC;AAAA,EAIjD,UAAU,SAA8B;AAC7C,QAAI,KAAK,YAAY;AACpB,YAAM,IAAI;AAAA,QACT;AAAA,MACD;AAAA,IACD;AACA,SAAK,kBAAkB;AAAA,MACtB,QAAQ,MAAM,CAAC,QAAQ,QAAQ,MAAM,mCAAmC,GAAG,CAAC;AAAA,IAC7E;AAAA,EACD;AAAA,EAEA,MAAc,kBAAkB;AAC/B,QAAI,aAAa;AACjB,WAAO,KAAK,kBAAkB,WAAW,YAAY;AACpD,mBAAa,KAAK,kBAAkB;AACpC,YAAM,QAAQ,WAAW,KAAK,iBAAiB;AAG/C,YAAM,MAAM,CAAC;AAAA,IACd;AAAA,EACD;AAAA,EAEA,MAAM,UAAU;AACf,UAAM,iBAAiB,MAAM,KAAK,cAAc,EAAE,KAAK,MAAM,SAAkB;AAC/E,UAAM,iBAAiB,KAAK,gBAAgB,EAAE,KAAK,MAAM,UAAmB;AAE5E,UAAM,SAAS,MAAM,QAAQ,KAAK,CAAC,gBAAgB,cAAc,CAAC;AAClE,QAAI,WAAW,WAAW;AACzB,cAAQ,KAAK,gEAAgE;AAAA,IAC9E;AAEA,SAAK,aAAa;AAAA,EACnB;AACD;AAjCO;AAAA,EAAL;AAAA,GANW,YAMN;",
5
+ "mappings": ";;;;;;;;;;AAAA,SAAS,MAAM,aAAa;AAUrB,MAAM,YAAY;AAAA,EAIxB,YAA6B,gBAAwB;AAAxB;AAAA,EAAyB;AAAA,EAAzB;AAAA,EAHrB,aAAa;AAAA,EACJ,oBAAqC,CAAC;AAAA,EAIjD,UAAU,SAA8B;AAC7C,QAAI,KAAK,YAAY;AACpB,YAAM,IAAI;AAAA,QACT;AAAA,MACD;AAAA,IACD;AACA,SAAK,kBAAkB;AAAA,MACtB,QAAQ,MAAM,CAAC,QAAQ,QAAQ,MAAM,mCAAmC,GAAG,CAAC;AAAA,IAC7E;AAAA,EACD;AAAA,EAEA,MAAc,kBAAkB;AAC/B,QAAI,aAAa;AACjB,WAAO,KAAK,kBAAkB,WAAW,YAAY;AACpD,mBAAa,KAAK,kBAAkB;AACpC,YAAM,QAAQ,WAAW,KAAK,iBAAiB;AAG/C,YAAM,MAAM,CAAC;AAAA,IACd;AAAA,EACD;AAAA,EAEA,MAAM,UAAU;AACf,UAAM,iBAAiB,MAAM,KAAK,cAAc,EAAE,KAAK,MAAM,SAAkB;AAC/E,UAAM,iBAAiB,KAAK,gBAAgB,EAAE,KAAK,MAAM,UAAmB;AAE5E,UAAM,SAAS,MAAM,QAAQ,KAAK,CAAC,gBAAgB,cAAc,CAAC;AAClE,QAAI,WAAW,WAAW;AACzB,cAAQ,KAAK,gEAAgE;AAAA,IAC9E;AAEA,SAAK,aAAa;AAAA,EACnB;AACD;AAjCO;AAAA,EAAL;AAAA,GANW,YAMN;",
6
6
  "names": []
7
7
  }
@@ -15,6 +15,7 @@ class StyleEmbedder {
15
15
  constructor(root) {
16
16
  this.root = root;
17
17
  }
18
+ root;
18
19
  styles = /* @__PURE__ */ new Map();
19
20
  fonts = new FontEmbedder();
20
21
  readRootElementStyles(rootElement) {
@@ -2,6 +2,6 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/exports/StyleEmbedder.ts"],
4
4
  "sourcesContent": ["import { assertExists, getOwnProperty, objectMapValues, uniqueId } from '@tldraw/utils'\nimport { ReadonlyStyles, Styles, cssRules } from './cssRules'\nimport {\n\telementStyle,\n\tgetComputedStyle,\n\tgetRenderedChildNodes,\n\tgetRenderedChildren,\n\tisElement,\n} from './domUtils'\nimport { resourceToDataUrl } from './fetchCache'\nimport { FontEmbedder } from './FontEmbedder'\nimport { parseCssValueUrls, shouldIncludeCssProperty } from './parseCss'\n\nconst NO_STYLES = {} as const\n\ninterface ElementStyleInfo {\n\tself: Styles\n\tbefore: Styles | undefined\n\tafter: Styles | undefined\n}\n\nexport class StyleEmbedder {\n\tconstructor(private readonly root: Element) {}\n\tprivate readonly styles = new Map<Element, ElementStyleInfo>()\n\treadonly fonts = new FontEmbedder()\n\n\treadRootElementStyles(rootElement: Element) {\n\t\t// when reading a root, we always apply _all_ the styles, even if they match the defaults\n\t\tthis.readElementStyles(rootElement, {\n\t\t\tshouldRespectDefaults: false,\n\t\t\tshouldSkipInheritedParentStyles: false,\n\t\t})\n\n\t\tconst children = Array.from(getRenderedChildren(rootElement))\n\t\twhile (children.length) {\n\t\t\tconst child = children.pop()!\n\t\t\tchildren.push(...getRenderedChildren(child))\n\n\t\t\t// when reading children, we don't apply styles that match the defaults for that\n\t\t\t// element, or that would be inherited from the parent\n\t\t\tthis.readElementStyles(child, {\n\t\t\t\tshouldRespectDefaults: true,\n\t\t\t\tshouldSkipInheritedParentStyles: true,\n\t\t\t})\n\t\t}\n\t}\n\n\tprivate readElementStyles(\n\t\telement: Element,\n\t\t{ shouldRespectDefaults = true, shouldSkipInheritedParentStyles = true }\n\t) {\n\t\tconst defaultStyles = shouldRespectDefaults\n\t\t\t? getDefaultStylesForTagName(element.ownerDocument, element.tagName.toLowerCase())\n\t\t\t: NO_STYLES\n\n\t\tconst parentStyles = Object.assign({}, NO_STYLES) as Styles\n\t\tif (shouldSkipInheritedParentStyles) {\n\t\t\tlet el = element.parentElement\n\t\t\t// Keep going up the tree to find all the relevant styles\n\t\t\twhile (el) {\n\t\t\t\tconst currentStyles = this.styles.get(el)?.self\n\t\t\t\tfor (const style in currentStyles) {\n\t\t\t\t\tif (!parentStyles[style]) {\n\t\t\t\t\t\tparentStyles[style] = currentStyles[style]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tel = el.parentElement\n\t\t\t}\n\t\t}\n\n\t\tconst info: ElementStyleInfo = {\n\t\t\tself: styleFromElement(element, { defaultStyles, parentStyles }),\n\t\t\tbefore: styleFromPseudoElement(element, '::before'),\n\t\t\tafter: styleFromPseudoElement(element, '::after'),\n\t\t}\n\t\tthis.styles.set(element, info)\n\t}\n\n\tfetchResources() {\n\t\tconst promises: Promise<void>[] = []\n\n\t\tfor (const info of this.styles.values()) {\n\t\t\tfor (const styles of objectMapValues(info)) {\n\t\t\t\tif (!styles) continue\n\t\t\t\tfor (const [property, value] of Object.entries(styles)) {\n\t\t\t\t\tif (!value) continue\n\t\t\t\t\tif (property === 'font-family') {\n\t\t\t\t\t\tthis.fonts.onFontFamilyValue(value)\n\t\t\t\t\t}\n\n\t\t\t\t\tconst urlMatches = parseCssValueUrls(value)\n\t\t\t\t\tif (urlMatches.length === 0) continue\n\n\t\t\t\t\tpromises.push(\n\t\t\t\t\t\t...urlMatches.map(async ({ url, original }) => {\n\t\t\t\t\t\t\tconst dataUrl = (await resourceToDataUrl(url)) ?? 'data:'\n\t\t\t\t\t\t\tstyles[property] = value.replace(original, `url(\"${dataUrl}\")`)\n\t\t\t\t\t\t})\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn Promise.all(promises)\n\t}\n\n\t// custom elements are tricky. if we serialize the dom as-is, the custom elements wont have\n\t// their shadow-dom contents serialized. after we've read all the styles, we need to unwrap the\n\t// contents of each custom elements shadow dom directly into the parent element itself.\n\tunwrapCustomElements() {\n\t\tconst visited = new Set<Node>()\n\n\t\tconst visit = (element: Element, clonedParent: Element | null) => {\n\t\t\tif (visited.has(element)) return\n\t\t\tvisited.add(element)\n\n\t\t\tconst shadowRoot = element.shadowRoot\n\n\t\t\tif (shadowRoot) {\n\t\t\t\tconst clonedCustomEl = element.ownerDocument.createElement('div')\n\t\t\t\tthis.styles.set(clonedCustomEl, this.styles.get(element)!)\n\n\t\t\t\tclonedCustomEl.setAttribute('data-tl-custom-element', element.tagName)\n\t\t\t\t;(clonedParent ?? element.parentElement!).appendChild(clonedCustomEl)\n\n\t\t\t\tfor (const child of shadowRoot.childNodes) {\n\t\t\t\t\tif (isElement(child)) {\n\t\t\t\t\t\tvisit(child, clonedCustomEl)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclonedCustomEl.appendChild(child.cloneNode(true))\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\telement.remove()\n\t\t\t} else if (clonedParent) {\n\t\t\t\tif (element.tagName.toLowerCase() === 'style') {\n\t\t\t\t\t// we don't clone style tags at that would break the style scoping. instead we\n\t\t\t\t\t// rely on the computed styles we've already read\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst clonedEl = element.cloneNode(false) as Element\n\t\t\t\tthis.styles.set(clonedEl, this.styles.get(element)!)\n\n\t\t\t\tclonedParent.appendChild(clonedEl)\n\n\t\t\t\tfor (const child of getRenderedChildNodes(element)) {\n\t\t\t\t\tif (isElement(child)) {\n\t\t\t\t\t\tvisit(child, clonedEl)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclonedEl.appendChild(child.cloneNode(true))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (const element of this.styles.keys()) {\n\t\t\tvisit(element, null)\n\t\t}\n\t}\n\n\tembedStyles(): string {\n\t\tlet css = ''\n\n\t\tfor (const [element, info] of this.styles) {\n\t\t\tif (info.after || info.before) {\n\t\t\t\tconst className = `pseudo-${uniqueId()}`\n\t\t\t\telement.classList.add(className)\n\n\t\t\t\tif (info.before) {\n\t\t\t\t\tcss += `.${className}::before {${formatCss(info.before)}}\\n`\n\t\t\t\t}\n\t\t\t\tif (info.after) {\n\t\t\t\t\tcss += `.${className}::after {${formatCss(info.after)}}\\n`\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst style = elementStyle(element)\n\t\t\tfor (const [property, value] of Object.entries(info.self)) {\n\t\t\t\tif (!value) continue\n\t\t\t\tstyle.setProperty(property, value)\n\t\t\t}\n\n\t\t\t// in HTML, font-kerning: auto is equivalent to font-kerning: normal. But in SVG, it's\n\t\t\t// none. We set it to normal here to match the HTML behavior, as otherwise this can\n\t\t\t// cause rendering differences.\n\t\t\tif (style.fontKerning === 'auto') {\n\t\t\t\tstyle.fontKerning = 'normal'\n\t\t\t}\n\t\t}\n\n\t\treturn css\n\t}\n\n\tasync getFontFaceCss() {\n\t\treturn await this.fonts.createCss()\n\t}\n\n\tdispose() {\n\t\tdestroyDefaultStyleFrame()\n\t}\n}\n\ninterface ReadStyleOpts {\n\tdefaultStyles: ReadonlyStyles\n\tparentStyles: ReadonlyStyles\n}\n\nfunction styleFromElement(element: Element, { defaultStyles, parentStyles }: ReadStyleOpts) {\n\t// `computedStyleMap` produces a more accurate representation of the styles, but it's not\n\t// supported in firefox at the time of writing. So we fall back to `getComputedStyle` if it's\n\t// not available.\n\tif (element.computedStyleMap) {\n\t\treturn styleFromComputedStyleMap(element.computedStyleMap(), { defaultStyles, parentStyles })\n\t}\n\treturn styleFromComputedStyle(getComputedStyle(element), { defaultStyles, parentStyles })\n}\n\nfunction styleFromPseudoElement(element: Element, pseudo: string) {\n\t// the equivalent of `computedStyleMap` for pseudo-elements isn't even fully specced out yet, so\n\t// for those we have to use `getComputedStyle` in all browsers.\n\tconst style = getComputedStyle(element, pseudo)\n\n\tconst content = style.getPropertyValue('content')\n\tif (content === '' || content === 'none') {\n\t\treturn undefined\n\t}\n\n\treturn styleFromComputedStyle(style, { defaultStyles: NO_STYLES, parentStyles: NO_STYLES })\n}\n\nfunction styleFromComputedStyleMap(\n\tstyle: StylePropertyMapReadOnly,\n\t{ defaultStyles, parentStyles }: ReadStyleOpts\n) {\n\tconst styles: Record<string, string> = {}\n\tconst currentColor = style.get('color')?.toString() || ''\n\tconst ruleOptions = {\n\t\tcurrentColor,\n\t\tparentStyles,\n\t\tdefaultStyles,\n\t\tgetStyle: (property: string) => style.get(property)?.toString() ?? '',\n\t}\n\tfor (const property of style.keys()) {\n\t\tif (!shouldIncludeCssProperty(property)) continue\n\n\t\tconst value = style.get(property)!.toString()\n\n\t\tif (defaultStyles[property] === value) continue\n\n\t\tconst rule = getOwnProperty(cssRules, property)\n\t\tif (rule && rule(value, property, ruleOptions)) continue\n\n\t\tstyles[property] = value\n\t}\n\n\treturn styles\n}\n\nfunction styleFromComputedStyle(\n\tstyle: CSSStyleDeclaration,\n\t{ defaultStyles, parentStyles }: ReadStyleOpts\n) {\n\tconst styles: Record<string, string> = {}\n\tconst currentColor = style.color\n\tconst ruleOptions = {\n\t\tcurrentColor,\n\t\tparentStyles,\n\t\tdefaultStyles,\n\t\tgetStyle: (property: string) => style.getPropertyValue(property),\n\t}\n\n\tfor (const property in style) {\n\t\tif (!shouldIncludeCssProperty(property)) continue\n\n\t\tconst value = style.getPropertyValue(property)\n\n\t\tif (defaultStyles[property] === value) continue\n\n\t\tconst rule = getOwnProperty(cssRules, property)\n\t\tif (rule && rule(value, property, ruleOptions)) continue\n\n\t\tstyles[property] = value\n\t}\n\treturn styles\n}\n\nfunction formatCss(style: ReadonlyStyles) {\n\tlet cssText = ''\n\tfor (const [property, value] of Object.entries(style)) {\n\t\tcssText += `${property}: ${value};`\n\t}\n\treturn cssText\n}\n\n// when we're figuring out the default values for a tag, we need read them from a separate document\n// so they're not affected by the current document's styles\nlet defaultStyleFrame:\n\t| {\n\t\t\tiframe: HTMLIFrameElement\n\t\t\tforeignObject: SVGForeignObjectElement\n\t\t\tdocument: Document\n\t\t\townerDocument: Document\n\t }\n\t| undefined\nconst defaultStylesByTagName: Record<string, ReadonlyStyles> = {}\nfunction getDefaultStyleFrame(ownerDoc: Document) {\n\tif (!defaultStyleFrame || defaultStyleFrame.ownerDocument !== ownerDoc) {\n\t\tdestroyDefaultStyleFrame()\n\t\tconst frame = ownerDoc.createElement('iframe')\n\t\tframe.style.display = 'none'\n\t\townerDoc.body.appendChild(frame)\n\t\tconst frameDocument = assertExists(frame.contentDocument, 'frame must have a document')\n\t\tconst svg = frameDocument.createElementNS('http://www.w3.org/2000/svg', 'svg')\n\t\tconst foreignObject = frameDocument.createElementNS(\n\t\t\t'http://www.w3.org/2000/svg',\n\t\t\t'foreignObject'\n\t\t)\n\t\tsvg.appendChild(foreignObject)\n\t\tframeDocument.body.appendChild(svg)\n\t\tdefaultStyleFrame = {\n\t\t\tiframe: frame,\n\t\t\tforeignObject,\n\t\t\tdocument: frameDocument,\n\t\t\townerDocument: ownerDoc,\n\t\t}\n\t}\n\treturn defaultStyleFrame\n}\n\nfunction destroyDefaultStyleFrame() {\n\tif (defaultStyleFrame) {\n\t\tdefaultStyleFrame.iframe.remove()\n\t\tdefaultStyleFrame = undefined\n\t}\n\tfor (const tagName in defaultStylesByTagName) {\n\t\tdelete defaultStylesByTagName[tagName]\n\t}\n}\n\nconst defaultStyleReadOptions: ReadStyleOpts = { defaultStyles: NO_STYLES, parentStyles: NO_STYLES }\nfunction getDefaultStylesForTagName(ownerDoc: Document, tagName: string) {\n\tlet existing = defaultStylesByTagName[tagName]\n\tif (!existing) {\n\t\tconst { foreignObject, document } = getDefaultStyleFrame(ownerDoc)\n\t\tconst element = document.createElement(tagName)\n\t\tforeignObject.appendChild(element)\n\t\texisting = element.computedStyleMap\n\t\t\t? styleFromComputedStyleMap(element.computedStyleMap(), defaultStyleReadOptions)\n\t\t\t: styleFromComputedStyle(getComputedStyle(element), defaultStyleReadOptions)\n\t\tforeignObject.removeChild(element)\n\t\tdefaultStylesByTagName[tagName] = existing\n\t}\n\treturn existing\n}\n"],
5
- "mappings": "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",
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,9 +1,5 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { useAtom, useValue } from "@tldraw/state-react";
3
- import {
4
- getColorValue,
5
- getDefaultColorTheme
6
- } from "@tldraw/tlschema";
7
3
  import { hasOwnProperty, promiseWithResolve, uniqueId } from "@tldraw/utils";
8
4
  import {
9
5
  Fragment,
@@ -15,6 +11,7 @@ import {
15
11
  import { flushSync } from "react-dom";
16
12
  import { ErrorBoundary } from "../components/ErrorBoundary.mjs";
17
13
  import { InnerShape, InnerShapeBackground } from "../components/Shape.mjs";
14
+ import { getColorValue } from "../editor/managers/ThemeManager/defaultThemes.mjs";
18
15
  import {
19
16
  SvgExportContextProvider
20
17
  } from "../editor/types/SvgExportContext.mjs";
@@ -35,10 +32,12 @@ function getSvgJsx(editor, ids, opts = {}) {
35
32
  } = opts;
36
33
  const isAutoTrim = typeof opts.padding !== "number";
37
34
  const renderPadding = typeof opts.padding === "number" ? opts.padding : editor.options.defaultSvgPadding;
38
- const isDarkMode = opts.darkMode ?? editor.user.getIsDarkMode();
35
+ const colorMode = opts.darkMode !== void 0 ? opts.darkMode ? "dark" : "light" : editor.getColorMode();
36
+ const isDarkMode = colorMode === "dark";
39
37
  const shapeIdsToInclude = editor.getShapeAndDescendantIds(ids);
40
38
  const renderingShapes = editor.getUnorderedRenderingShapes(false).filter(({ id }) => shapeIdsToInclude.has(id));
41
- const singleFrameShapeId = ids.length === 1 && editor.isShapeOfType(editor.getShape(ids[0]), "frame") ? ids[0] : null;
39
+ const singleFrameShape = ids.length === 1 ? editor.getShape(ids[0]) : null;
40
+ const singleFrameShapeId = singleFrameShape && editor.isShapeFrameLike(singleFrameShape) ? ids[0] : null;
42
41
  let bbox = null;
43
42
  let paddingWasApplied = false;
44
43
  if (opts.bounds) {
@@ -75,6 +74,7 @@ function getSvgJsx(editor, ids, opts = {}) {
75
74
  background,
76
75
  singleFrameShapeId,
77
76
  isDarkMode,
77
+ colorMode,
78
78
  renderingShapes,
79
79
  onMount: initialEffectPromise.resolve,
80
80
  waitUntil: exportDelay.waitUntil
@@ -121,12 +121,13 @@ function SvgExport({
121
121
  background,
122
122
  singleFrameShapeId,
123
123
  isDarkMode,
124
+ colorMode,
124
125
  renderingShapes,
125
126
  onMount,
126
127
  waitUntil
127
128
  }) {
128
129
  const masksId = useUniqueSafeId();
129
- const theme = getDefaultColorTheme({ isDarkMode });
130
+ const theme = editor.getCurrentTheme();
130
131
  const stateAtom = useAtom("export state", { defsById: {}, shapeElements: null });
131
132
  const { defsById, shapeElements } = useValue(stateAtom);
132
133
  const addExportDef = useEvent((def) => {
@@ -150,6 +151,7 @@ function SvgExport({
150
151
  const exportContext = useMemo(
151
152
  () => ({
152
153
  isDarkMode,
154
+ colorMode,
153
155
  waitUntil,
154
156
  addExportDef,
155
157
  scale,
@@ -164,7 +166,7 @@ function SvgExport({
164
166
  });
165
167
  }
166
168
  }),
167
- [isDarkMode, waitUntil, addExportDef, scale, pixelRatio, editor]
169
+ [isDarkMode, colorMode, waitUntil, addExportDef, scale, pixelRatio, editor]
168
170
  );
169
171
  const didRenderRef = useRef(false);
170
172
  useLayoutEffect(() => {
@@ -307,14 +309,15 @@ function SvgExport({
307
309
  if (shapeElements === null) return;
308
310
  onMount();
309
311
  }, [onMount, shapeElements]);
310
- let backgroundColor = background ? theme.background : "transparent";
312
+ const colors = theme.colors[colorMode];
313
+ let backgroundColor = background ? colors.background : "transparent";
311
314
  if (singleFrameShapeId && background) {
312
315
  const frameShapeUtil = editor.getShapeUtil("frame");
313
316
  if (frameShapeUtil?.options.showColors) {
314
317
  const shape = editor.getShape(singleFrameShapeId);
315
- backgroundColor = getColorValue(theme, shape.props.color, "frameFill");
318
+ backgroundColor = getColorValue(colors, shape.props.color, "frameFill");
316
319
  } else {
317
- backgroundColor = theme.solid;
320
+ backgroundColor = colors.solid;
318
321
  }
319
322
  }
320
323
  return /* @__PURE__ */ jsx(SvgExportContextProvider, { editor, context: exportContext, children: /* @__PURE__ */ jsxs(
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/exports/getSvgJsx.tsx"],
4
- "sourcesContent": ["import { useAtom, useValue } from '@tldraw/state-react'\nimport {\n\tTLFrameShape,\n\tTLShape,\n\tTLShapeId,\n\tgetColorValue,\n\tgetDefaultColorTheme,\n} from '@tldraw/tlschema'\nimport { hasOwnProperty, promiseWithResolve, uniqueId } from '@tldraw/utils'\nimport {\n\tComponentType,\n\tFragment,\n\tReactElement,\n\tReactNode,\n\tuseEffect,\n\tuseLayoutEffect,\n\tuseMemo,\n\tuseRef,\n} from 'react'\nimport { flushSync } from 'react-dom'\nimport { ErrorBoundary } from '../components/ErrorBoundary'\nimport { InnerShape, InnerShapeBackground } from '../components/Shape'\nimport type { Editor, TLRenderingShape } from '../editor/Editor'\nimport { TLFontFace } from '../editor/managers/FontManager/FontManager'\nimport { ShapeUtil } from '../editor/shapes/ShapeUtil'\nimport { TLImageExportOptions } from '../editor/types/misc-types'\nimport {\n\tSvgExportContext,\n\tSvgExportContextProvider,\n\tSvgExportDef,\n} from '../editor/types/SvgExportContext'\nimport { useEditor } from '../hooks/useEditor'\nimport { useEvent } from '../hooks/useEvent'\nimport { suffixSafeId, useUniqueSafeId } from '../hooks/useSafeId'\nimport { Box } from '../primitives/Box'\nimport { Mat } from '../primitives/Mat'\nimport { ExportDelay } from './ExportDelay'\n\nexport function getSvgJsx(editor: Editor, ids: TLShapeId[], opts: TLImageExportOptions = {}) {\n\tconst editorDocument = editor.getContainerDocument()\n\tif (!editorDocument) throw Error('No document')\n\n\tconst {\n\t\tscale = 1,\n\t\t// should we include the background in the export? or is it transparent?\n\t\tbackground = editor.getInstanceState().exportBackground,\n\t\tpreserveAspectRatio,\n\t} = opts\n\n\t// Resolve the padding mode:\n\t// - 'auto' (or undefined): render with default padding, then trim to actual visual content\n\t// - number: fixed padding, no trimming\n\tconst isAutoTrim = typeof opts.padding !== 'number'\n\tconst renderPadding =\n\t\ttypeof opts.padding === 'number' ? opts.padding : editor.options.defaultSvgPadding\n\n\tconst isDarkMode = opts.darkMode ?? editor.user.getIsDarkMode()\n\n\t// ---Figure out which shapes we need to include\n\tconst shapeIdsToInclude = editor.getShapeAndDescendantIds(ids)\n\tconst renderingShapes = editor\n\t\t.getUnorderedRenderingShapes(false)\n\t\t.filter(({ id }) => shapeIdsToInclude.has(id))\n\n\t// --- Common bounding box of all shapes\n\tconst singleFrameShapeId =\n\t\tids.length === 1 && editor.isShapeOfType(editor.getShape(ids[0])!, 'frame') ? ids[0] : null\n\n\tlet bbox: null | Box = null\n\tlet paddingWasApplied = false\n\tif (opts.bounds) {\n\t\t// Explicit bounds: use exact bounds when auto, expand by padding when fixed\n\t\tbbox = isAutoTrim ? opts.bounds.clone() : opts.bounds.clone().expandBy(renderPadding)\n\t} else {\n\t\tconst result = getExportDefaultBounds(\n\t\t\teditor,\n\t\t\trenderingShapes,\n\t\t\trenderPadding,\n\t\t\tsingleFrameShapeId\n\t\t)\n\t\tbbox = result.box\n\t\tpaddingWasApplied = result.paddingApplied\n\t}\n\n\t// no unmasked shapes to export\n\tif (!bbox) return\n\n\t// When auto-trim is active and padding was applied by getExportDefaultBounds,\n\t// the padding region is trimmable: exports will scan pixels from each edge inward\n\t// and trim to the actual visual content bounds. This ensures visual overflow\n\t// (strokes, arrowheads) is captured without unnecessary whitespace.\n\tconst trimPadding = isAutoTrim && paddingWasApplied ? renderPadding : 0\n\n\t// We want the svg image to be BIGGER THAN USUAL to account for image quality\n\tconst w = bbox.width * scale\n\tconst h = bbox.height * scale\n\n\ttry {\n\t\teditorDocument.body.focus?.() // weird but necessary\n\t} catch {\n\t\t// not implemented\n\t}\n\n\tconst exportDelay = new ExportDelay(editor.options.maxExportDelayMs)\n\n\tconst initialEffectPromise = promiseWithResolve<void>()\n\texportDelay.waitUntil(initialEffectPromise)\n\n\tconst svg = (\n\t\t<SvgExport\n\t\t\teditor={editor}\n\t\t\tpreserveAspectRatio={preserveAspectRatio}\n\t\t\tscale={scale}\n\t\t\tpixelRatio={opts.pixelRatio ?? null}\n\t\t\tbbox={bbox}\n\t\t\tbackground={background}\n\t\t\tsingleFrameShapeId={singleFrameShapeId}\n\t\t\tisDarkMode={isDarkMode}\n\t\t\trenderingShapes={renderingShapes}\n\t\t\tonMount={initialEffectPromise.resolve}\n\t\t\twaitUntil={exportDelay.waitUntil}\n\t\t>\n\t\t\t{}\n\t\t</SvgExport>\n\t)\n\n\treturn { jsx: svg, width: w, height: h, exportDelay, trimPadding }\n}\n\n/**\n * Calculates the default bounds for an SVG export. This function handles:\n * 1. Computing masked page bounds for each shape\n * 2. Container logic: if a shape is marked as an export bounds container and it\n * contains all other shapes, use its bounds and skip padding\n * 3. Otherwise, create a union of all shape bounds and apply padding\n *\n * The container logic is useful for cases like annotating on an image - if the image\n * contains all annotations, we want to export exactly the image bounds without extra padding.\n *\n * @param editor - The editor instance\n * @param renderingShapes - The shapes to include in the export\n * @param padding - Padding to add around the bounds (only applied if no container bounds)\n * @param singleFrameShapeId - If exporting a single frame, this is its ID (skips padding)\n * @returns The calculated bounds box, or null if no shapes to export\n */\nexport function getExportDefaultBounds(\n\teditor: Editor,\n\trenderingShapes: TLRenderingShape[],\n\tpadding: number,\n\tsingleFrameShapeId: TLShapeId | null\n): { box: Box; paddingApplied: boolean } | { box: null; paddingApplied: false } {\n\tlet isBoundedByContainer = false\n\tlet bbox: null | Box = null\n\n\tfor (const { id } of renderingShapes) {\n\t\tconst maskedPageBounds = editor.getShapeMaskedPageBounds(id)\n\t\tif (!maskedPageBounds) continue\n\n\t\t// Check if this shape is an export bounds container (e.g., an image being annotated)\n\t\tconst shape = editor.getShape(id)!\n\t\tconst isContainer = editor.getShapeUtil(shape).isExportBoundsContainer(shape)\n\n\t\tif (bbox) {\n\t\t\t// Container logic: if this is a container and it contains all shapes processed so far,\n\t\t\t// use the container's bounds instead of the union. This prevents extra padding around\n\t\t\t// things like annotated images.\n\t\t\tif (isContainer && Box.ContainsApproximately(maskedPageBounds, bbox)) {\n\t\t\t\tisBoundedByContainer = true\n\t\t\t\tbbox = maskedPageBounds.clone()\n\t\t\t} else {\n\t\t\t\t// If we were previously bounded by a container but this shape extends outside it,\n\t\t\t\t// we're no longer bounded by a container\n\t\t\t\tif (isBoundedByContainer && !Box.ContainsApproximately(bbox, maskedPageBounds)) {\n\t\t\t\t\tisBoundedByContainer = false\n\t\t\t\t}\n\t\t\t\t// Expand the bounding box to include this shape\n\t\t\t\tbbox.union(maskedPageBounds)\n\t\t\t}\n\t\t} else {\n\t\t\t// First shape sets the initial bounds\n\t\t\tisBoundedByContainer = isContainer\n\t\t\tbbox = maskedPageBounds.clone()\n\t\t}\n\t}\n\n\t// No unmasked shapes to export\n\tif (!bbox) return { box: null, paddingApplied: false }\n\n\t// Only apply padding if:\n\t// - Not exporting a single frame (frames have their own padding rules)\n\t// - Not bounded by a container (containers define their own bounds precisely)\n\tconst paddingApplied = !singleFrameShapeId && !isBoundedByContainer\n\tif (paddingApplied) {\n\t\tbbox.expandBy(padding)\n\t}\n\n\treturn { box: bbox, paddingApplied }\n}\n\nfunction SvgExport({\n\teditor,\n\tpreserveAspectRatio,\n\tscale,\n\tpixelRatio,\n\tbbox,\n\tbackground,\n\tsingleFrameShapeId,\n\tisDarkMode,\n\trenderingShapes,\n\tonMount,\n\twaitUntil,\n}: {\n\teditor: Editor\n\tpreserveAspectRatio?: string\n\tscale: number\n\tpixelRatio: number | null\n\tbbox: Box\n\tbackground: boolean\n\tsingleFrameShapeId: TLShapeId | null\n\tisDarkMode: boolean\n\trenderingShapes: TLRenderingShape[]\n\tonMount(): void\n\twaitUntil(promise: Promise<void>): void\n}) {\n\tconst masksId = useUniqueSafeId()\n\tconst theme = getDefaultColorTheme({ isDarkMode })\n\n\tconst stateAtom = useAtom<{\n\t\tdefsById: Record<\n\t\t\tstring,\n\t\t\t{ pending: false; element: ReactNode } | { pending: true; element: Promise<ReactNode> }\n\t\t>\n\t\tshapeElements: ReactElement[] | null\n\t}>('export state', { defsById: {}, shapeElements: null })\n\tconst { defsById, shapeElements } = useValue(stateAtom)\n\n\tconst addExportDef = useEvent((def: SvgExportDef) => {\n\t\tstateAtom.update((state) => {\n\t\t\tif (hasOwnProperty(state.defsById, def.key)) return state\n\n\t\t\tconst promise = Promise.resolve(def.getElement())\n\t\t\twaitUntil(\n\t\t\t\tpromise.then((result) => {\n\t\t\t\t\tstateAtom.update((state) => ({\n\t\t\t\t\t\t...state,\n\t\t\t\t\t\tdefsById: { ...state.defsById, [def.key]: { pending: false, element: result } },\n\t\t\t\t\t}))\n\t\t\t\t})\n\t\t\t)\n\t\t\treturn {\n\t\t\t\t...state,\n\t\t\t\tdefsById: { ...state.defsById, [def.key]: { pending: true, element: promise } },\n\t\t\t}\n\t\t})\n\t})\n\n\tconst exportContext = useMemo(\n\t\t(): SvgExportContext => ({\n\t\t\tisDarkMode,\n\t\t\twaitUntil,\n\t\t\taddExportDef,\n\t\t\tscale,\n\t\t\tpixelRatio,\n\t\t\tasync resolveAssetUrl(assetId, width) {\n\t\t\t\tconst asset = editor.getAsset(assetId)\n\t\t\t\tif (!asset || (asset.type !== 'image' && asset.type !== 'video')) return null\n\n\t\t\t\treturn await editor.resolveAssetUrl(assetId, {\n\t\t\t\t\tscreenScale: scale * (width / asset.props.w),\n\t\t\t\t\tshouldResolveToOriginal: pixelRatio === null,\n\t\t\t\t\tdpr: pixelRatio ?? undefined,\n\t\t\t\t})\n\t\t\t},\n\t\t}),\n\t\t[isDarkMode, waitUntil, addExportDef, scale, pixelRatio, editor]\n\t)\n\n\tconst didRenderRef = useRef(false)\n\tuseLayoutEffect(() => {\n\t\tif (didRenderRef.current) {\n\t\t\tthrow new Error('SvgExport should only render once - do not use with react strict mode')\n\t\t}\n\t\tdidRenderRef.current = true\n\t\t;(async () => {\n\t\t\tconst shapeDefs: Record<string, { pending: false; element: ReactElement }> = {}\n\n\t\t\t// Then render everything. The shapes with assets should all hit the cache\n\t\t\tconst unorderedShapeElementPromises = renderingShapes.map(\n\t\t\t\tasync ({ id, opacity, index, backgroundIndex }) => {\n\t\t\t\t\t// Don't render the frame if we're only exporting a single frame and it's children\n\t\t\t\t\tif (id === singleFrameShapeId) return []\n\n\t\t\t\t\tconst shape = editor.getShape(id)!\n\n\t\t\t\t\tif (editor.isShapeOfType(shape, 'group')) return []\n\n\t\t\t\t\tconst elements = []\n\t\t\t\t\tconst util = editor.getShapeUtil(shape)\n\n\t\t\t\t\tif (util.toSvg || util.toBackgroundSvg) {\n\t\t\t\t\t\t// If the shape has any sort of custom svg export, let's use that.\n\t\t\t\t\t\tconst [toSvgResult, toBackgroundSvgResult] = await Promise.all([\n\t\t\t\t\t\t\tutil.toSvg?.(shape, exportContext),\n\t\t\t\t\t\t\tutil.toBackgroundSvg?.(shape, exportContext),\n\t\t\t\t\t\t])\n\n\t\t\t\t\t\tconst pageTransform = editor.getShapePageTransform(shape)\n\t\t\t\t\t\tlet pageTransformString = pageTransform!.toCssString()\n\t\t\t\t\t\tlet scale = 1\n\t\t\t\t\t\tif ('scale' in shape.props) {\n\t\t\t\t\t\t\tif (shape.props.scale !== 1) {\n\t\t\t\t\t\t\t\tscale = shape.props.scale\n\t\t\t\t\t\t\t\tpageTransformString = `${pageTransformString} scale(${shape.props.scale}, ${shape.props.scale})`\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Create svg mask if shape has a frame as parent\n\t\t\t\t\t\tconst pageMask = editor.getShapeMask(shape.id)\n\t\t\t\t\t\tconst shapeMask = pageMask\n\t\t\t\t\t\t\t? Mat.From(Mat.Inverse(pageTransform)).applyToPoints(pageMask)\n\t\t\t\t\t\t\t: null\n\t\t\t\t\t\tconst shapeMaskId = suffixSafeId(masksId, shape.id)\n\t\t\t\t\t\tif (shapeMask) {\n\t\t\t\t\t\t\t// Create a clip path and add it to defs\n\t\t\t\t\t\t\tshapeDefs[shapeMaskId] = {\n\t\t\t\t\t\t\t\tpending: false,\n\t\t\t\t\t\t\t\telement: (\n\t\t\t\t\t\t\t\t\t<clipPath id={shapeMaskId}>\n\t\t\t\t\t\t\t\t\t\t{/* Create a polyline mask that does the clipping */}\n\t\t\t\t\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t\t\t\t\td={`M${shapeMask.map(({ x, y }) => `${x / scale},${y / scale}`).join('L')}Z`}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</clipPath>\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (toSvgResult) {\n\t\t\t\t\t\t\telements.push({\n\t\t\t\t\t\t\t\tzIndex: index,\n\t\t\t\t\t\t\t\telement: (\n\t\t\t\t\t\t\t\t\t<g\n\t\t\t\t\t\t\t\t\t\tkey={`fg_${shape.id}`}\n\t\t\t\t\t\t\t\t\t\ttransform={pageTransformString}\n\t\t\t\t\t\t\t\t\t\topacity={opacity}\n\t\t\t\t\t\t\t\t\t\tclipPath={pageMask ? `url(#${shapeMaskId})` : undefined}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{toSvgResult}\n\t\t\t\t\t\t\t\t\t</g>\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (toBackgroundSvgResult) {\n\t\t\t\t\t\t\telements.push({\n\t\t\t\t\t\t\t\tzIndex: backgroundIndex,\n\t\t\t\t\t\t\t\telement: (\n\t\t\t\t\t\t\t\t\t<g\n\t\t\t\t\t\t\t\t\t\tkey={`bg_${shape.id}`}\n\t\t\t\t\t\t\t\t\t\ttransform={pageTransformString}\n\t\t\t\t\t\t\t\t\t\topacity={opacity}\n\t\t\t\t\t\t\t\t\t\tclipPath={pageMask ? `url(#${shapeMaskId})` : undefined}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{toBackgroundSvgResult}\n\t\t\t\t\t\t\t\t\t</g>\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// If the shape doesn't have a custom svg export, we'll use its normal HTML\n\t\t\t\t\t\t// renderer in a foreignObject.\n\t\t\t\t\t\telements.push({\n\t\t\t\t\t\t\tzIndex: index,\n\t\t\t\t\t\t\telement: (\n\t\t\t\t\t\t\t\t<ForeignObjectShape\n\t\t\t\t\t\t\t\t\tkey={`fg_${shape.id}`}\n\t\t\t\t\t\t\t\t\tshape={shape}\n\t\t\t\t\t\t\t\t\tutil={util}\n\t\t\t\t\t\t\t\t\tcomponent={InnerShape}\n\t\t\t\t\t\t\t\t\tclassName=\"tl-shape\"\n\t\t\t\t\t\t\t\t\tbbox={bbox}\n\t\t\t\t\t\t\t\t\topacity={opacity}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t})\n\n\t\t\t\t\t\tif (util.backgroundComponent) {\n\t\t\t\t\t\t\telements.push({\n\t\t\t\t\t\t\t\tzIndex: backgroundIndex,\n\t\t\t\t\t\t\t\telement: (\n\t\t\t\t\t\t\t\t\t<ForeignObjectShape\n\t\t\t\t\t\t\t\t\t\tkey={`bg_${shape.id}`}\n\t\t\t\t\t\t\t\t\t\tshape={shape}\n\t\t\t\t\t\t\t\t\t\tutil={util}\n\t\t\t\t\t\t\t\t\t\tcomponent={InnerShapeBackground}\n\t\t\t\t\t\t\t\t\t\tclassName=\"tl-shape tl-shape-background\"\n\t\t\t\t\t\t\t\t\t\tbbox={bbox}\n\t\t\t\t\t\t\t\t\t\topacity={opacity}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn elements\n\t\t\t\t}\n\t\t\t)\n\n\t\t\tconst unorderedShapeElements = (await Promise.all(unorderedShapeElementPromises)).flat()\n\n\t\t\tflushSync(() => {\n\t\t\t\tstateAtom.update((state) => ({\n\t\t\t\t\t...state,\n\t\t\t\t\tshapeElements: unorderedShapeElements\n\t\t\t\t\t\t.sort((a, b) => a.zIndex - b.zIndex)\n\t\t\t\t\t\t.map(({ element }) => element),\n\t\t\t\t\tdefsById: { ...state.defsById, ...shapeDefs },\n\t\t\t\t}))\n\t\t\t})\n\t\t})()\n\t}, [bbox, editor, exportContext, masksId, renderingShapes, singleFrameShapeId, stateAtom])\n\n\tuseEffect(() => {\n\t\tconst fontsInUse = new Set<TLFontFace>()\n\t\tfor (const { id } of renderingShapes) {\n\t\t\tfor (const font of editor.fonts.getShapeFontFaces(id)) {\n\t\t\t\tfontsInUse.add(font)\n\t\t\t}\n\t\t}\n\n\t\tfor (const font of fontsInUse) {\n\t\t\taddExportDef({\n\t\t\t\tkey: uniqueId(),\n\t\t\t\tgetElement: async () => {\n\t\t\t\t\tconst declaration = await editor.fonts.toEmbeddedCssDeclaration(font)\n\t\t\t\t\treturn <style nonce={editor.options.nonce}>{declaration}</style>\n\t\t\t\t},\n\t\t\t})\n\t\t}\n\t}, [editor, renderingShapes, addExportDef])\n\n\tuseEffect(() => {\n\t\tif (shapeElements === null) return\n\t\tonMount()\n\t}, [onMount, shapeElements])\n\n\tlet backgroundColor = background ? theme.background : 'transparent'\n\n\tif (singleFrameShapeId && background) {\n\t\tconst frameShapeUtil = editor.getShapeUtil('frame') as any as\n\t\t\t| undefined\n\t\t\t| { options: { showColors: boolean } }\n\t\tif (frameShapeUtil?.options.showColors) {\n\t\t\tconst shape = editor.getShape(singleFrameShapeId)! as TLFrameShape\n\t\t\tbackgroundColor = getColorValue(theme, shape.props.color, 'frameFill')\n\t\t} else {\n\t\t\tbackgroundColor = theme.solid\n\t\t}\n\t}\n\n\treturn (\n\t\t<SvgExportContextProvider editor={editor} context={exportContext}>\n\t\t\t<svg\n\t\t\t\tpreserveAspectRatio={preserveAspectRatio}\n\t\t\t\tdirection=\"ltr\"\n\t\t\t\twidth={bbox.width * scale}\n\t\t\t\theight={bbox.height * scale}\n\t\t\t\tviewBox={`${bbox.minX} ${bbox.minY} ${bbox.width} ${bbox.height}`}\n\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\tstrokeLinejoin=\"round\"\n\t\t\t\tstyle={{ backgroundColor }}\n\t\t\t\tdata-color-mode={isDarkMode ? 'dark' : 'light'}\n\t\t\t\tclassName={`tl-container tl-theme__force-sRGB ${isDarkMode ? 'tl-theme__dark' : 'tl-theme__light'}`}\n\t\t\t>\n\t\t\t\t<defs>\n\t\t\t\t\t{Object.entries(defsById).map(([key, def]) =>\n\t\t\t\t\t\tdef.pending ? null : <Fragment key={key}>{def.element}</Fragment>\n\t\t\t\t\t)}\n\t\t\t\t</defs>\n\t\t\t\t{shapeElements}\n\t\t\t</svg>\n\t\t</SvgExportContextProvider>\n\t)\n}\n\nfunction ForeignObjectShape({\n\tshape,\n\tutil,\n\tclassName,\n\tcomponent: Component,\n\tbbox,\n\topacity,\n}: {\n\tshape: TLShape\n\tutil: ShapeUtil\n\tclassName?: string\n\tcomponent: ComponentType<{ shape: TLShape; util: ShapeUtil }>\n\tbbox: Box\n\topacity: number\n}) {\n\tconst editor = useEditor()\n\n\tconst transform = Mat.Translate(-bbox.minX, -bbox.minY).multiply(\n\t\teditor.getShapePageTransform(shape.id)!\n\t)\n\n\tconst bounds = editor.getShapeGeometry(shape.id).bounds\n\tconst width = Math.max(bounds.width, 1)\n\tconst height = Math.max(bounds.height, 1)\n\n\treturn (\n\t\t<ErrorBoundary fallback={() => null}>\n\t\t\t<foreignObject\n\t\t\t\tx={bbox.minX}\n\t\t\t\ty={bbox.minY}\n\t\t\t\twidth={bbox.w}\n\t\t\t\theight={bbox.h}\n\t\t\t\tclassName=\"tl-shape-foreign-object tl-export-embed-styles\"\n\t\t\t>\n\t\t\t\t<div\n\t\t\t\t\tclassName={className}\n\t\t\t\t\tdata-shape-type={shape.type}\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tclipPath: editor.getShapeClipPath(shape.id),\n\t\t\t\t\t\ttransform: transform.toCssString(),\n\t\t\t\t\t\twidth,\n\t\t\t\t\t\theight,\n\t\t\t\t\t\topacity,\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<Component shape={shape} util={util} />\n\t\t\t\t</div>\n\t\t\t</foreignObject>\n\t\t</ErrorBoundary>\n\t)\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { useAtom, useValue } from '@tldraw/state-react'\nimport { TLFrameShape, TLShape, TLShapeId } from '@tldraw/tlschema'\nimport { TLFontFace } from '@tldraw/tlschema'\nimport { hasOwnProperty, promiseWithResolve, uniqueId } from '@tldraw/utils'\nimport {\n\tComponentType,\n\tFragment,\n\tReactElement,\n\tReactNode,\n\tuseEffect,\n\tuseLayoutEffect,\n\tuseMemo,\n\tuseRef,\n} from 'react'\nimport { flushSync } from 'react-dom'\nimport { ErrorBoundary } from '../components/ErrorBoundary'\nimport { InnerShape, InnerShapeBackground } from '../components/Shape'\nimport type { Editor, TLRenderingShape } from '../editor/Editor'\nimport { getColorValue } from '../editor/managers/ThemeManager/defaultThemes'\nimport { ShapeUtil } from '../editor/shapes/ShapeUtil'\nimport { TLImageExportOptions } from '../editor/types/misc-types'\nimport {\n\tSvgExportContext,\n\tSvgExportContextProvider,\n\tSvgExportDef,\n} from '../editor/types/SvgExportContext'\nimport { useEditor } from '../hooks/useEditor'\nimport { useEvent } from '../hooks/useEvent'\nimport { suffixSafeId, useUniqueSafeId } from '../hooks/useSafeId'\nimport { Box } from '../primitives/Box'\nimport { Mat } from '../primitives/Mat'\nimport { ExportDelay } from './ExportDelay'\n\nexport function getSvgJsx(editor: Editor, ids: TLShapeId[], opts: TLImageExportOptions = {}) {\n\tconst editorDocument = editor.getContainerDocument()\n\tif (!editorDocument) throw Error('No document')\n\n\tconst {\n\t\tscale = 1,\n\t\t// should we include the background in the export? or is it transparent?\n\t\tbackground = editor.getInstanceState().exportBackground,\n\t\tpreserveAspectRatio,\n\t} = opts\n\n\t// Resolve the padding mode:\n\t// - 'auto' (or undefined): render with default padding, then trim to actual visual content\n\t// - number: fixed padding, no trimming\n\tconst isAutoTrim = typeof opts.padding !== 'number'\n\tconst renderPadding =\n\t\ttypeof opts.padding === 'number' ? opts.padding : editor.options.defaultSvgPadding\n\n\tconst colorMode: 'light' | 'dark' =\n\t\topts.darkMode !== undefined ? (opts.darkMode ? 'dark' : 'light') : editor.getColorMode()\n\tconst isDarkMode = colorMode === 'dark'\n\n\t// ---Figure out which shapes we need to include\n\tconst shapeIdsToInclude = editor.getShapeAndDescendantIds(ids)\n\tconst renderingShapes = editor\n\t\t.getUnorderedRenderingShapes(false)\n\t\t.filter(({ id }) => shapeIdsToInclude.has(id))\n\n\t// --- Common bounding box of all shapes\n\tconst singleFrameShape = ids.length === 1 ? editor.getShape(ids[0]) : null\n\tconst singleFrameShapeId =\n\t\tsingleFrameShape && editor.isShapeFrameLike(singleFrameShape) ? ids[0] : null\n\n\tlet bbox: null | Box = null\n\tlet paddingWasApplied = false\n\tif (opts.bounds) {\n\t\t// Explicit bounds: use exact bounds when auto, expand by padding when fixed\n\t\tbbox = isAutoTrim ? opts.bounds.clone() : opts.bounds.clone().expandBy(renderPadding)\n\t} else {\n\t\tconst result = getExportDefaultBounds(\n\t\t\teditor,\n\t\t\trenderingShapes,\n\t\t\trenderPadding,\n\t\t\tsingleFrameShapeId\n\t\t)\n\t\tbbox = result.box\n\t\tpaddingWasApplied = result.paddingApplied\n\t}\n\n\t// no unmasked shapes to export\n\tif (!bbox) return\n\n\t// When auto-trim is active and padding was applied by getExportDefaultBounds,\n\t// the padding region is trimmable: exports will scan pixels from each edge inward\n\t// and trim to the actual visual content bounds. This ensures visual overflow\n\t// (strokes, arrowheads) is captured without unnecessary whitespace.\n\tconst trimPadding = isAutoTrim && paddingWasApplied ? renderPadding : 0\n\n\t// We want the svg image to be BIGGER THAN USUAL to account for image quality\n\tconst w = bbox.width * scale\n\tconst h = bbox.height * scale\n\n\ttry {\n\t\teditorDocument.body.focus?.() // weird but necessary\n\t} catch {\n\t\t// not implemented\n\t}\n\n\tconst exportDelay = new ExportDelay(editor.options.maxExportDelayMs)\n\n\tconst initialEffectPromise = promiseWithResolve<void>()\n\texportDelay.waitUntil(initialEffectPromise)\n\n\tconst svg = (\n\t\t<SvgExport\n\t\t\teditor={editor}\n\t\t\tpreserveAspectRatio={preserveAspectRatio}\n\t\t\tscale={scale}\n\t\t\tpixelRatio={opts.pixelRatio ?? null}\n\t\t\tbbox={bbox}\n\t\t\tbackground={background}\n\t\t\tsingleFrameShapeId={singleFrameShapeId}\n\t\t\tisDarkMode={isDarkMode}\n\t\t\tcolorMode={colorMode}\n\t\t\trenderingShapes={renderingShapes}\n\t\t\tonMount={initialEffectPromise.resolve}\n\t\t\twaitUntil={exportDelay.waitUntil}\n\t\t>\n\t\t\t{}\n\t\t</SvgExport>\n\t)\n\n\treturn { jsx: svg, width: w, height: h, exportDelay, trimPadding }\n}\n\n/**\n * Calculates the default bounds for an SVG export. This function handles:\n * 1. Computing masked page bounds for each shape\n * 2. Container logic: if a shape is marked as an export bounds container and it\n * contains all other shapes, use its bounds and skip padding\n * 3. Otherwise, create a union of all shape bounds and apply padding\n *\n * The container logic is useful for cases like annotating on an image - if the image\n * contains all annotations, we want to export exactly the image bounds without extra padding.\n *\n * @param editor - The editor instance\n * @param renderingShapes - The shapes to include in the export\n * @param padding - Padding to add around the bounds (only applied if no container bounds)\n * @param singleFrameShapeId - If exporting a single frame, this is its ID (skips padding)\n * @returns The calculated bounds box, or null if no shapes to export\n */\nexport function getExportDefaultBounds(\n\teditor: Editor,\n\trenderingShapes: TLRenderingShape[],\n\tpadding: number,\n\tsingleFrameShapeId: TLShapeId | null\n): { box: Box; paddingApplied: boolean } | { box: null; paddingApplied: false } {\n\tlet isBoundedByContainer = false\n\tlet bbox: null | Box = null\n\n\tfor (const { id } of renderingShapes) {\n\t\tconst maskedPageBounds = editor.getShapeMaskedPageBounds(id)\n\t\tif (!maskedPageBounds) continue\n\n\t\t// Check if this shape is an export bounds container (e.g., an image being annotated)\n\t\tconst shape = editor.getShape(id)!\n\t\tconst isContainer = editor.getShapeUtil(shape).isExportBoundsContainer(shape)\n\n\t\tif (bbox) {\n\t\t\t// Container logic: if this is a container and it contains all shapes processed so far,\n\t\t\t// use the container's bounds instead of the union. This prevents extra padding around\n\t\t\t// things like annotated images.\n\t\t\tif (isContainer && Box.ContainsApproximately(maskedPageBounds, bbox)) {\n\t\t\t\tisBoundedByContainer = true\n\t\t\t\tbbox = maskedPageBounds.clone()\n\t\t\t} else {\n\t\t\t\t// If we were previously bounded by a container but this shape extends outside it,\n\t\t\t\t// we're no longer bounded by a container\n\t\t\t\tif (isBoundedByContainer && !Box.ContainsApproximately(bbox, maskedPageBounds)) {\n\t\t\t\t\tisBoundedByContainer = false\n\t\t\t\t}\n\t\t\t\t// Expand the bounding box to include this shape\n\t\t\t\tbbox.union(maskedPageBounds)\n\t\t\t}\n\t\t} else {\n\t\t\t// First shape sets the initial bounds\n\t\t\tisBoundedByContainer = isContainer\n\t\t\tbbox = maskedPageBounds.clone()\n\t\t}\n\t}\n\n\t// No unmasked shapes to export\n\tif (!bbox) return { box: null, paddingApplied: false }\n\n\t// Only apply padding if:\n\t// - Not exporting a single frame (frames have their own padding rules)\n\t// - Not bounded by a container (containers define their own bounds precisely)\n\tconst paddingApplied = !singleFrameShapeId && !isBoundedByContainer\n\tif (paddingApplied) {\n\t\tbbox.expandBy(padding)\n\t}\n\n\treturn { box: bbox, paddingApplied }\n}\n\nfunction SvgExport({\n\teditor,\n\tpreserveAspectRatio,\n\tscale,\n\tpixelRatio,\n\tbbox,\n\tbackground,\n\tsingleFrameShapeId,\n\tisDarkMode,\n\tcolorMode,\n\trenderingShapes,\n\tonMount,\n\twaitUntil,\n}: {\n\teditor: Editor\n\tpreserveAspectRatio?: string\n\tscale: number\n\tpixelRatio: number | null\n\tbbox: Box\n\tbackground: boolean\n\tsingleFrameShapeId: TLShapeId | null\n\tisDarkMode: boolean\n\tcolorMode: 'light' | 'dark'\n\trenderingShapes: TLRenderingShape[]\n\tonMount(): void\n\twaitUntil(promise: Promise<void>): void\n}) {\n\tconst masksId = useUniqueSafeId()\n\tconst theme = editor.getCurrentTheme()\n\n\tconst stateAtom = useAtom<{\n\t\tdefsById: Record<\n\t\t\tstring,\n\t\t\t{ pending: false; element: ReactNode } | { pending: true; element: Promise<ReactNode> }\n\t\t>\n\t\tshapeElements: ReactElement[] | null\n\t}>('export state', { defsById: {}, shapeElements: null })\n\tconst { defsById, shapeElements } = useValue(stateAtom)\n\n\tconst addExportDef = useEvent((def: SvgExportDef) => {\n\t\tstateAtom.update((state) => {\n\t\t\tif (hasOwnProperty(state.defsById, def.key)) return state\n\n\t\t\tconst promise = Promise.resolve(def.getElement())\n\t\t\twaitUntil(\n\t\t\t\tpromise.then((result) => {\n\t\t\t\t\tstateAtom.update((state) => ({\n\t\t\t\t\t\t...state,\n\t\t\t\t\t\tdefsById: { ...state.defsById, [def.key]: { pending: false, element: result } },\n\t\t\t\t\t}))\n\t\t\t\t})\n\t\t\t)\n\t\t\treturn {\n\t\t\t\t...state,\n\t\t\t\tdefsById: { ...state.defsById, [def.key]: { pending: true, element: promise } },\n\t\t\t}\n\t\t})\n\t})\n\n\tconst exportContext = useMemo(\n\t\t(): SvgExportContext => ({\n\t\t\tisDarkMode,\n\t\t\tcolorMode,\n\t\t\twaitUntil,\n\t\t\taddExportDef,\n\t\t\tscale,\n\t\t\tpixelRatio,\n\t\t\tasync resolveAssetUrl(assetId, width) {\n\t\t\t\tconst asset = editor.getAsset(assetId)\n\t\t\t\tif (!asset || (asset.type !== 'image' && asset.type !== 'video')) return null\n\n\t\t\t\treturn await editor.resolveAssetUrl(assetId, {\n\t\t\t\t\tscreenScale: scale * (width / asset.props.w),\n\t\t\t\t\tshouldResolveToOriginal: pixelRatio === null,\n\t\t\t\t\tdpr: pixelRatio ?? undefined,\n\t\t\t\t})\n\t\t\t},\n\t\t}),\n\t\t[isDarkMode, colorMode, waitUntil, addExportDef, scale, pixelRatio, editor]\n\t)\n\n\tconst didRenderRef = useRef(false)\n\tuseLayoutEffect(() => {\n\t\tif (didRenderRef.current) {\n\t\t\tthrow new Error('SvgExport should only render once - do not use with react strict mode')\n\t\t}\n\t\tdidRenderRef.current = true\n\t\t;(async () => {\n\t\t\tconst shapeDefs: Record<string, { pending: false; element: ReactElement }> = {}\n\n\t\t\t// Then render everything. The shapes with assets should all hit the cache\n\t\t\tconst unorderedShapeElementPromises = renderingShapes.map(\n\t\t\t\tasync ({ id, opacity, index, backgroundIndex }) => {\n\t\t\t\t\t// Don't render the frame if we're only exporting a single frame and it's children\n\t\t\t\t\tif (id === singleFrameShapeId) return []\n\n\t\t\t\t\tconst shape = editor.getShape(id)!\n\n\t\t\t\t\tif (editor.isShapeOfType(shape, 'group')) return []\n\n\t\t\t\t\tconst elements = []\n\t\t\t\t\tconst util = editor.getShapeUtil(shape)\n\n\t\t\t\t\tif (util.toSvg || util.toBackgroundSvg) {\n\t\t\t\t\t\t// If the shape has any sort of custom svg export, let's use that.\n\t\t\t\t\t\tconst [toSvgResult, toBackgroundSvgResult] = await Promise.all([\n\t\t\t\t\t\t\tutil.toSvg?.(shape, exportContext),\n\t\t\t\t\t\t\tutil.toBackgroundSvg?.(shape, exportContext),\n\t\t\t\t\t\t])\n\n\t\t\t\t\t\tconst pageTransform = editor.getShapePageTransform(shape)\n\t\t\t\t\t\tlet pageTransformString = pageTransform!.toCssString()\n\t\t\t\t\t\tlet scale = 1\n\t\t\t\t\t\tif ('scale' in shape.props) {\n\t\t\t\t\t\t\tif (shape.props.scale !== 1) {\n\t\t\t\t\t\t\t\tscale = shape.props.scale\n\t\t\t\t\t\t\t\tpageTransformString = `${pageTransformString} scale(${shape.props.scale}, ${shape.props.scale})`\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Create svg mask if shape has a frame as parent\n\t\t\t\t\t\tconst pageMask = editor.getShapeMask(shape.id)\n\t\t\t\t\t\tconst shapeMask = pageMask\n\t\t\t\t\t\t\t? Mat.From(Mat.Inverse(pageTransform)).applyToPoints(pageMask)\n\t\t\t\t\t\t\t: null\n\t\t\t\t\t\tconst shapeMaskId = suffixSafeId(masksId, shape.id)\n\t\t\t\t\t\tif (shapeMask) {\n\t\t\t\t\t\t\t// Create a clip path and add it to defs\n\t\t\t\t\t\t\tshapeDefs[shapeMaskId] = {\n\t\t\t\t\t\t\t\tpending: false,\n\t\t\t\t\t\t\t\telement: (\n\t\t\t\t\t\t\t\t\t<clipPath id={shapeMaskId}>\n\t\t\t\t\t\t\t\t\t\t{/* Create a polyline mask that does the clipping */}\n\t\t\t\t\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t\t\t\t\td={`M${shapeMask.map(({ x, y }) => `${x / scale},${y / scale}`).join('L')}Z`}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</clipPath>\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (toSvgResult) {\n\t\t\t\t\t\t\telements.push({\n\t\t\t\t\t\t\t\tzIndex: index,\n\t\t\t\t\t\t\t\telement: (\n\t\t\t\t\t\t\t\t\t<g\n\t\t\t\t\t\t\t\t\t\tkey={`fg_${shape.id}`}\n\t\t\t\t\t\t\t\t\t\ttransform={pageTransformString}\n\t\t\t\t\t\t\t\t\t\topacity={opacity}\n\t\t\t\t\t\t\t\t\t\tclipPath={pageMask ? `url(#${shapeMaskId})` : undefined}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{toSvgResult}\n\t\t\t\t\t\t\t\t\t</g>\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (toBackgroundSvgResult) {\n\t\t\t\t\t\t\telements.push({\n\t\t\t\t\t\t\t\tzIndex: backgroundIndex,\n\t\t\t\t\t\t\t\telement: (\n\t\t\t\t\t\t\t\t\t<g\n\t\t\t\t\t\t\t\t\t\tkey={`bg_${shape.id}`}\n\t\t\t\t\t\t\t\t\t\ttransform={pageTransformString}\n\t\t\t\t\t\t\t\t\t\topacity={opacity}\n\t\t\t\t\t\t\t\t\t\tclipPath={pageMask ? `url(#${shapeMaskId})` : undefined}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{toBackgroundSvgResult}\n\t\t\t\t\t\t\t\t\t</g>\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// If the shape doesn't have a custom svg export, we'll use its normal HTML\n\t\t\t\t\t\t// renderer in a foreignObject.\n\t\t\t\t\t\telements.push({\n\t\t\t\t\t\t\tzIndex: index,\n\t\t\t\t\t\t\telement: (\n\t\t\t\t\t\t\t\t<ForeignObjectShape\n\t\t\t\t\t\t\t\t\tkey={`fg_${shape.id}`}\n\t\t\t\t\t\t\t\t\tshape={shape}\n\t\t\t\t\t\t\t\t\tutil={util}\n\t\t\t\t\t\t\t\t\tcomponent={InnerShape}\n\t\t\t\t\t\t\t\t\tclassName=\"tl-shape\"\n\t\t\t\t\t\t\t\t\tbbox={bbox}\n\t\t\t\t\t\t\t\t\topacity={opacity}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t})\n\n\t\t\t\t\t\tif (util.backgroundComponent) {\n\t\t\t\t\t\t\telements.push({\n\t\t\t\t\t\t\t\tzIndex: backgroundIndex,\n\t\t\t\t\t\t\t\telement: (\n\t\t\t\t\t\t\t\t\t<ForeignObjectShape\n\t\t\t\t\t\t\t\t\t\tkey={`bg_${shape.id}`}\n\t\t\t\t\t\t\t\t\t\tshape={shape}\n\t\t\t\t\t\t\t\t\t\tutil={util}\n\t\t\t\t\t\t\t\t\t\tcomponent={InnerShapeBackground}\n\t\t\t\t\t\t\t\t\t\tclassName=\"tl-shape tl-shape-background\"\n\t\t\t\t\t\t\t\t\t\tbbox={bbox}\n\t\t\t\t\t\t\t\t\t\topacity={opacity}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn elements\n\t\t\t\t}\n\t\t\t)\n\n\t\t\tconst unorderedShapeElements = (await Promise.all(unorderedShapeElementPromises)).flat()\n\n\t\t\tflushSync(() => {\n\t\t\t\tstateAtom.update((state) => ({\n\t\t\t\t\t...state,\n\t\t\t\t\tshapeElements: unorderedShapeElements\n\t\t\t\t\t\t.sort((a, b) => a.zIndex - b.zIndex)\n\t\t\t\t\t\t.map(({ element }) => element),\n\t\t\t\t\tdefsById: { ...state.defsById, ...shapeDefs },\n\t\t\t\t}))\n\t\t\t})\n\t\t})()\n\t}, [bbox, editor, exportContext, masksId, renderingShapes, singleFrameShapeId, stateAtom])\n\n\tuseEffect(() => {\n\t\tconst fontsInUse = new Set<TLFontFace>()\n\t\tfor (const { id } of renderingShapes) {\n\t\t\tfor (const font of editor.fonts.getShapeFontFaces(id)) {\n\t\t\t\tfontsInUse.add(font)\n\t\t\t}\n\t\t}\n\n\t\tfor (const font of fontsInUse) {\n\t\t\taddExportDef({\n\t\t\t\tkey: uniqueId(),\n\t\t\t\tgetElement: async () => {\n\t\t\t\t\tconst declaration = await editor.fonts.toEmbeddedCssDeclaration(font)\n\t\t\t\t\treturn <style nonce={editor.options.nonce}>{declaration}</style>\n\t\t\t\t},\n\t\t\t})\n\t\t}\n\t}, [editor, renderingShapes, addExportDef])\n\n\tuseEffect(() => {\n\t\tif (shapeElements === null) return\n\t\tonMount()\n\t}, [onMount, shapeElements])\n\n\tconst colors = theme.colors[colorMode]\n\tlet backgroundColor = background ? colors.background : 'transparent'\n\n\tif (singleFrameShapeId && background) {\n\t\tconst frameShapeUtil = editor.getShapeUtil('frame') as any as\n\t\t\t| undefined\n\t\t\t| {\n\t\t\t\t\toptions: {\n\t\t\t\t\t\tshowColors: boolean\n\t\t\t\t\t}\n\t\t\t }\n\t\tif (frameShapeUtil?.options.showColors) {\n\t\t\tconst shape = editor.getShape(singleFrameShapeId)! as TLFrameShape\n\t\t\tbackgroundColor = getColorValue(colors, shape.props.color, 'frameFill')\n\t\t} else {\n\t\t\tbackgroundColor = colors.solid\n\t\t}\n\t}\n\n\treturn (\n\t\t<SvgExportContextProvider editor={editor} context={exportContext}>\n\t\t\t<svg\n\t\t\t\tpreserveAspectRatio={preserveAspectRatio}\n\t\t\t\tdirection=\"ltr\"\n\t\t\t\twidth={bbox.width * scale}\n\t\t\t\theight={bbox.height * scale}\n\t\t\t\tviewBox={`${bbox.minX} ${bbox.minY} ${bbox.width} ${bbox.height}`}\n\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\tstrokeLinejoin=\"round\"\n\t\t\t\tstyle={{ backgroundColor }}\n\t\t\t\tdata-color-mode={isDarkMode ? 'dark' : 'light'}\n\t\t\t\tclassName={`tl-container tl-theme__force-sRGB ${isDarkMode ? 'tl-theme__dark' : 'tl-theme__light'}`}\n\t\t\t>\n\t\t\t\t<defs>\n\t\t\t\t\t{Object.entries(defsById).map(([key, def]) =>\n\t\t\t\t\t\tdef.pending ? null : <Fragment key={key}>{def.element}</Fragment>\n\t\t\t\t\t)}\n\t\t\t\t</defs>\n\t\t\t\t{shapeElements}\n\t\t\t</svg>\n\t\t</SvgExportContextProvider>\n\t)\n}\n\nfunction ForeignObjectShape({\n\tshape,\n\tutil,\n\tclassName,\n\tcomponent: Component,\n\tbbox,\n\topacity,\n}: {\n\tshape: TLShape\n\tutil: ShapeUtil\n\tclassName?: string\n\tcomponent: ComponentType<{ shape: TLShape; util: ShapeUtil }>\n\tbbox: Box\n\topacity: number\n}) {\n\tconst editor = useEditor()\n\n\tconst transform = Mat.Translate(-bbox.minX, -bbox.minY).multiply(\n\t\teditor.getShapePageTransform(shape.id)!\n\t)\n\n\tconst bounds = editor.getShapeGeometry(shape.id).bounds\n\tconst width = Math.max(bounds.width, 1)\n\tconst height = Math.max(bounds.height, 1)\n\n\treturn (\n\t\t<ErrorBoundary fallback={() => null}>\n\t\t\t<foreignObject\n\t\t\t\tx={bbox.minX}\n\t\t\t\ty={bbox.minY}\n\t\t\t\twidth={bbox.w}\n\t\t\t\theight={bbox.h}\n\t\t\t\tclassName=\"tl-shape-foreign-object tl-export-embed-styles\"\n\t\t\t>\n\t\t\t\t<div\n\t\t\t\t\tclassName={className}\n\t\t\t\t\tdata-shape-type={shape.type}\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tclipPath: editor.getShapeClipPath(shape.id),\n\t\t\t\t\t\ttransform: transform.toCssString(),\n\t\t\t\t\t\twidth,\n\t\t\t\t\t\theight,\n\t\t\t\t\t\topacity,\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<Component shape={shape} util={util} />\n\t\t\t\t</div>\n\t\t\t</foreignObject>\n\t\t</ErrorBoundary>\n\t)\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["state", "scale"]
7
7
  }
@@ -27,8 +27,25 @@ const tlenvReactive = atom("tlenvReactive", {
27
27
  // Whether the user's device has a coarse pointer. This is dynamic on many systems, especially
28
28
  // on touch-screen laptops, which will become "coarse" if the user touches the screen.
29
29
  // See https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@media/pointer#coarse
30
- isCoarsePointer: false
30
+ isCoarsePointer: false,
31
+ // Whether the user's display supports P3 color space. This is dynamic because a window can
32
+ // move between displays with different color gamut support.
33
+ supportsP3ColorSpace: false
31
34
  });
35
+ if (typeof window !== "undefined") {
36
+ const canRenderP3 = typeof CSS !== "undefined" && CSS.supports("color", "color(display-p3 1 1 1)");
37
+ if (canRenderP3) {
38
+ const p3mql = window.matchMedia("(color-gamut: p3)");
39
+ const updateSupportsP3 = () => {
40
+ const supportsP3 = p3mql.matches;
41
+ if (supportsP3 !== tlenvReactive.__unsafe__getWithoutCapture().supportsP3ColorSpace) {
42
+ tlenvReactive.update((prev) => ({ ...prev, supportsP3ColorSpace: supportsP3 }));
43
+ }
44
+ };
45
+ updateSupportsP3();
46
+ p3mql.addEventListener("change", updateSupportsP3);
47
+ }
48
+ }
32
49
  if (typeof window !== "undefined" && !isForcedFinePointer) {
33
50
  const mql = getGlobalWindow().matchMedia && getGlobalWindow().matchMedia("(any-pointer: coarse)");
34
51
  const isCurrentCoarsePointer = () => tlenvReactive.__unsafe__getWithoutCapture().isCoarsePointer;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/globals/environment.ts"],
4
- "sourcesContent": ["import { atom } from '@tldraw/state'\nimport { getGlobalWindow } from '../utils/dom'\n\n/**\n * An object that contains information about the current device and environment.\n * This object is not reactive and will not update automatically when the environment changes,\n * so only include values that are fixed, such as the user's browser and operating system.\n *\n * @public\n */\nconst tlenv = {\n\tisSafari: false,\n\tisIos: false,\n\tisChromeForIos: false,\n\tisFirefox: false,\n\tisAndroid: false,\n\tisWebview: false,\n\tisDarwin: false,\n\thasCanvasSupport: false,\n}\n\nlet isForcedFinePointer = false\n\nif (typeof window !== 'undefined') {\n\tif ('navigator' in window) {\n\t\ttlenv.isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent)\n\t\ttlenv.isIos = !!navigator.userAgent.match(/iPad/i) || !!navigator.userAgent.match(/iPhone/i)\n\t\ttlenv.isChromeForIos = /crios.*safari/i.test(navigator.userAgent)\n\t\ttlenv.isFirefox = /firefox/i.test(navigator.userAgent)\n\t\ttlenv.isAndroid = /android/i.test(navigator.userAgent)\n\t\ttlenv.isDarwin = getGlobalWindow().navigator.userAgent.toLowerCase().indexOf('mac') > -1\n\t}\n\ttlenv.hasCanvasSupport = 'Promise' in window && 'HTMLCanvasElement' in window\n\tisForcedFinePointer = tlenv.isFirefox && !tlenv.isAndroid && !tlenv.isIos\n}\n\n/**\n * An atom that contains information about the current device and environment.\n * This object is reactive and will update automatically when the environment changes.\n * Use it for values that may change over time, such as the pointer type.\n *\n * @public\n */\nconst tlenvReactive = atom('tlenvReactive', {\n\t// Whether the user's device has a coarse pointer. This is dynamic on many systems, especially\n\t// on touch-screen laptops, which will become \"coarse\" if the user touches the screen.\n\t// See https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@media/pointer#coarse\n\tisCoarsePointer: false,\n})\n\nif (typeof window !== 'undefined' && !isForcedFinePointer) {\n\tconst mql = getGlobalWindow().matchMedia && getGlobalWindow().matchMedia('(any-pointer: coarse)')\n\n\tconst isCurrentCoarsePointer = () => tlenvReactive.__unsafe__getWithoutCapture().isCoarsePointer\n\n\tif (mql) {\n\t\t// 1. Update the coarse pointer automatically when the media query changes\n\t\tconst updateIsCoarsePointer = () => {\n\t\t\tconst isCoarsePointer = mql.matches\n\t\t\tif (isCoarsePointer !== isCurrentCoarsePointer()) {\n\t\t\t\ttlenvReactive.update((prev) => ({ ...prev, isCoarsePointer: isCoarsePointer }))\n\t\t\t}\n\t\t}\n\t\tupdateIsCoarsePointer()\n\t\tmql.addEventListener('change', updateIsCoarsePointer)\n\t}\n\n\t// 2. Also update the coarse pointer state when a pointer down event occurs. We need `capture: true`\n\t// here because the tldraw component itself stops propagation on pointer events it receives.\n\tgetGlobalWindow().addEventListener(\n\t\t'pointerdown',\n\t\t(e: PointerEvent) => {\n\t\t\t// when the user interacts with a mouse, we assume they have a fine pointer.\n\t\t\t// otherwise, we assume they have a coarse pointer.\n\t\t\tconst isCoarseEvent = e.pointerType !== 'mouse'\n\t\t\tif (isCoarseEvent !== isCurrentCoarsePointer()) {\n\t\t\t\ttlenvReactive.update((prev) => ({ ...prev, isCoarsePointer: isCoarseEvent }))\n\t\t\t}\n\t\t},\n\t\t{ capture: true }\n\t)\n}\n\nexport { tlenv, tlenvReactive }\n"],
5
- "mappings": "AAAA,SAAS,YAAY;AACrB,SAAS,uBAAuB;AAShC,MAAM,QAAQ;AAAA,EACb,UAAU;AAAA,EACV,OAAO;AAAA,EACP,gBAAgB;AAAA,EAChB,WAAW;AAAA,EACX,WAAW;AAAA,EACX,WAAW;AAAA,EACX,UAAU;AAAA,EACV,kBAAkB;AACnB;AAEA,IAAI,sBAAsB;AAE1B,IAAI,OAAO,WAAW,aAAa;AAClC,MAAI,eAAe,QAAQ;AAC1B,UAAM,WAAW,iCAAiC,KAAK,UAAU,SAAS;AAC1E,UAAM,QAAQ,CAAC,CAAC,UAAU,UAAU,MAAM,OAAO,KAAK,CAAC,CAAC,UAAU,UAAU,MAAM,SAAS;AAC3F,UAAM,iBAAiB,iBAAiB,KAAK,UAAU,SAAS;AAChE,UAAM,YAAY,WAAW,KAAK,UAAU,SAAS;AACrD,UAAM,YAAY,WAAW,KAAK,UAAU,SAAS;AACrD,UAAM,WAAW,gBAAgB,EAAE,UAAU,UAAU,YAAY,EAAE,QAAQ,KAAK,IAAI;AAAA,EACvF;AACA,QAAM,mBAAmB,aAAa,UAAU,uBAAuB;AACvE,wBAAsB,MAAM,aAAa,CAAC,MAAM,aAAa,CAAC,MAAM;AACrE;AASA,MAAM,gBAAgB,KAAK,iBAAiB;AAAA;AAAA;AAAA;AAAA,EAI3C,iBAAiB;AAClB,CAAC;AAED,IAAI,OAAO,WAAW,eAAe,CAAC,qBAAqB;AAC1D,QAAM,MAAM,gBAAgB,EAAE,cAAc,gBAAgB,EAAE,WAAW,uBAAuB;AAEhG,QAAM,yBAAyB,MAAM,cAAc,4BAA4B,EAAE;AAEjF,MAAI,KAAK;AAER,UAAM,wBAAwB,MAAM;AACnC,YAAM,kBAAkB,IAAI;AAC5B,UAAI,oBAAoB,uBAAuB,GAAG;AACjD,sBAAc,OAAO,CAAC,UAAU,EAAE,GAAG,MAAM,gBAAiC,EAAE;AAAA,MAC/E;AAAA,IACD;AACA,0BAAsB;AACtB,QAAI,iBAAiB,UAAU,qBAAqB;AAAA,EACrD;AAIA,kBAAgB,EAAE;AAAA,IACjB;AAAA,IACA,CAAC,MAAoB;AAGpB,YAAM,gBAAgB,EAAE,gBAAgB;AACxC,UAAI,kBAAkB,uBAAuB,GAAG;AAC/C,sBAAc,OAAO,CAAC,UAAU,EAAE,GAAG,MAAM,iBAAiB,cAAc,EAAE;AAAA,MAC7E;AAAA,IACD;AAAA,IACA,EAAE,SAAS,KAAK;AAAA,EACjB;AACD;",
4
+ "sourcesContent": ["import { atom } from '@tldraw/state'\nimport { getGlobalWindow } from '../utils/dom'\n\n/**\n * An object that contains information about the current device and environment.\n * This object is not reactive and will not update automatically when the environment changes,\n * so only include values that are fixed, such as the user's browser and operating system.\n *\n * @public\n */\nconst tlenv = {\n\tisSafari: false,\n\tisIos: false,\n\tisChromeForIos: false,\n\tisFirefox: false,\n\tisAndroid: false,\n\tisWebview: false,\n\tisDarwin: false,\n\thasCanvasSupport: false,\n}\n\nlet isForcedFinePointer = false\n\nif (typeof window !== 'undefined') {\n\tif ('navigator' in window) {\n\t\ttlenv.isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent)\n\t\ttlenv.isIos = !!navigator.userAgent.match(/iPad/i) || !!navigator.userAgent.match(/iPhone/i)\n\t\ttlenv.isChromeForIos = /crios.*safari/i.test(navigator.userAgent)\n\t\ttlenv.isFirefox = /firefox/i.test(navigator.userAgent)\n\t\ttlenv.isAndroid = /android/i.test(navigator.userAgent)\n\t\ttlenv.isDarwin = getGlobalWindow().navigator.userAgent.toLowerCase().indexOf('mac') > -1\n\t}\n\ttlenv.hasCanvasSupport = 'Promise' in window && 'HTMLCanvasElement' in window\n\tisForcedFinePointer = tlenv.isFirefox && !tlenv.isAndroid && !tlenv.isIos\n}\n\n/**\n * An atom that contains information about the current device and environment.\n * This object is reactive and will update automatically when the environment changes.\n * Use it for values that may change over time, such as the pointer type.\n *\n * @public\n */\nconst tlenvReactive = atom('tlenvReactive', {\n\t// Whether the user's device has a coarse pointer. This is dynamic on many systems, especially\n\t// on touch-screen laptops, which will become \"coarse\" if the user touches the screen.\n\t// See https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@media/pointer#coarse\n\tisCoarsePointer: false,\n\t// Whether the user's display supports P3 color space. This is dynamic because a window can\n\t// move between displays with different color gamut support.\n\tsupportsP3ColorSpace: false,\n})\n\nif (typeof window !== 'undefined') {\n\tconst canRenderP3 = typeof CSS !== 'undefined' && CSS.supports('color', 'color(display-p3 1 1 1)')\n\tif (canRenderP3) {\n\t\tconst p3mql = window.matchMedia('(color-gamut: p3)')\n\t\tconst updateSupportsP3 = () => {\n\t\t\tconst supportsP3 = p3mql.matches\n\t\t\tif (supportsP3 !== tlenvReactive.__unsafe__getWithoutCapture().supportsP3ColorSpace) {\n\t\t\t\ttlenvReactive.update((prev) => ({ ...prev, supportsP3ColorSpace: supportsP3 }))\n\t\t\t}\n\t\t}\n\t\tupdateSupportsP3()\n\t\tp3mql.addEventListener('change', updateSupportsP3)\n\t}\n}\n\nif (typeof window !== 'undefined' && !isForcedFinePointer) {\n\tconst mql = getGlobalWindow().matchMedia && getGlobalWindow().matchMedia('(any-pointer: coarse)')\n\n\tconst isCurrentCoarsePointer = () => tlenvReactive.__unsafe__getWithoutCapture().isCoarsePointer\n\n\tif (mql) {\n\t\t// 1. Update the coarse pointer automatically when the media query changes\n\t\tconst updateIsCoarsePointer = () => {\n\t\t\tconst isCoarsePointer = mql.matches\n\t\t\tif (isCoarsePointer !== isCurrentCoarsePointer()) {\n\t\t\t\ttlenvReactive.update((prev) => ({ ...prev, isCoarsePointer: isCoarsePointer }))\n\t\t\t}\n\t\t}\n\t\tupdateIsCoarsePointer()\n\t\tmql.addEventListener('change', updateIsCoarsePointer)\n\t}\n\n\t// 2. Also update the coarse pointer state when a pointer down event occurs. We need `capture: true`\n\t// here because the tldraw component itself stops propagation on pointer events it receives.\n\tgetGlobalWindow().addEventListener(\n\t\t'pointerdown',\n\t\t(e: PointerEvent) => {\n\t\t\t// when the user interacts with a mouse, we assume they have a fine pointer.\n\t\t\t// otherwise, we assume they have a coarse pointer.\n\t\t\tconst isCoarseEvent = e.pointerType !== 'mouse'\n\t\t\tif (isCoarseEvent !== isCurrentCoarsePointer()) {\n\t\t\t\ttlenvReactive.update((prev) => ({ ...prev, isCoarsePointer: isCoarseEvent }))\n\t\t\t}\n\t\t},\n\t\t{ capture: true }\n\t)\n}\n\nexport { tlenv, tlenvReactive }\n"],
5
+ "mappings": "AAAA,SAAS,YAAY;AACrB,SAAS,uBAAuB;AAShC,MAAM,QAAQ;AAAA,EACb,UAAU;AAAA,EACV,OAAO;AAAA,EACP,gBAAgB;AAAA,EAChB,WAAW;AAAA,EACX,WAAW;AAAA,EACX,WAAW;AAAA,EACX,UAAU;AAAA,EACV,kBAAkB;AACnB;AAEA,IAAI,sBAAsB;AAE1B,IAAI,OAAO,WAAW,aAAa;AAClC,MAAI,eAAe,QAAQ;AAC1B,UAAM,WAAW,iCAAiC,KAAK,UAAU,SAAS;AAC1E,UAAM,QAAQ,CAAC,CAAC,UAAU,UAAU,MAAM,OAAO,KAAK,CAAC,CAAC,UAAU,UAAU,MAAM,SAAS;AAC3F,UAAM,iBAAiB,iBAAiB,KAAK,UAAU,SAAS;AAChE,UAAM,YAAY,WAAW,KAAK,UAAU,SAAS;AACrD,UAAM,YAAY,WAAW,KAAK,UAAU,SAAS;AACrD,UAAM,WAAW,gBAAgB,EAAE,UAAU,UAAU,YAAY,EAAE,QAAQ,KAAK,IAAI;AAAA,EACvF;AACA,QAAM,mBAAmB,aAAa,UAAU,uBAAuB;AACvE,wBAAsB,MAAM,aAAa,CAAC,MAAM,aAAa,CAAC,MAAM;AACrE;AASA,MAAM,gBAAgB,KAAK,iBAAiB;AAAA;AAAA;AAAA;AAAA,EAI3C,iBAAiB;AAAA;AAAA;AAAA,EAGjB,sBAAsB;AACvB,CAAC;AAED,IAAI,OAAO,WAAW,aAAa;AAClC,QAAM,cAAc,OAAO,QAAQ,eAAe,IAAI,SAAS,SAAS,yBAAyB;AACjG,MAAI,aAAa;AAChB,UAAM,QAAQ,OAAO,WAAW,mBAAmB;AACnD,UAAM,mBAAmB,MAAM;AAC9B,YAAM,aAAa,MAAM;AACzB,UAAI,eAAe,cAAc,4BAA4B,EAAE,sBAAsB;AACpF,sBAAc,OAAO,CAAC,UAAU,EAAE,GAAG,MAAM,sBAAsB,WAAW,EAAE;AAAA,MAC/E;AAAA,IACD;AACA,qBAAiB;AACjB,UAAM,iBAAiB,UAAU,gBAAgB;AAAA,EAClD;AACD;AAEA,IAAI,OAAO,WAAW,eAAe,CAAC,qBAAqB;AAC1D,QAAM,MAAM,gBAAgB,EAAE,cAAc,gBAAgB,EAAE,WAAW,uBAAuB;AAEhG,QAAM,yBAAyB,MAAM,cAAc,4BAA4B,EAAE;AAEjF,MAAI,KAAK;AAER,UAAM,wBAAwB,MAAM;AACnC,YAAM,kBAAkB,IAAI;AAC5B,UAAI,oBAAoB,uBAAuB,GAAG;AACjD,sBAAc,OAAO,CAAC,UAAU,EAAE,GAAG,MAAM,gBAAiC,EAAE;AAAA,MAC/E;AAAA,IACD;AACA,0BAAsB;AACtB,QAAI,iBAAiB,UAAU,qBAAqB;AAAA,EACrD;AAIA,kBAAgB,EAAE;AAAA,IACjB;AAAA,IACA,CAAC,MAAoB;AAGpB,YAAM,gBAAgB,EAAE,gBAAgB;AACxC,UAAI,kBAAkB,uBAAuB,GAAG;AAC/C,sBAAc,OAAO,CAAC,UAAU,EAAE,GAAG,MAAM,iBAAiB,cAAc,EAAE;AAAA,MAC7E;AAAA,IACD;AAAA,IACA,EAAE,SAAS,KAAK;AAAA,EACjB;AACD;",
6
6
  "names": []
7
7
  }
@@ -1,6 +1,5 @@
1
1
  import { useValue } from "@tldraw/state-react";
2
2
  import { useEffect, useMemo } from "react";
3
- import { RIGHT_MOUSE_BUTTON } from "../constants.mjs";
4
3
  import { tlenv } from "../globals/environment.mjs";
5
4
  import {
6
5
  elementShouldCaptureKeys,
@@ -18,7 +17,7 @@ function useCanvasEvents() {
18
17
  function canvasEvents() {
19
18
  function onPointerDown(e) {
20
19
  if (editor.wasEventAlreadyHandled(e)) return;
21
- if (e.button === RIGHT_MOUSE_BUTTON) {
20
+ if (e.button === 2 && !editor.options.rightClickPanning) {
22
21
  editor.dispatch({
23
22
  type: "pointer",
24
23
  target: "canvas",
@@ -27,7 +26,7 @@ function useCanvasEvents() {
27
26
  });
28
27
  return;
29
28
  }
30
- if (e.button !== 0 && e.button !== 1 && e.button !== 5) return;
29
+ if (e.button !== 0 && e.button !== 1 && e.button !== 2 && e.button !== 5) return;
31
30
  setPointerCapture(e.currentTarget, e);
32
31
  editor.dispatch({
33
32
  type: "pointer",
@@ -39,6 +38,8 @@ function useCanvasEvents() {
39
38
  function onPointerUp(e) {
40
39
  if (editor.wasEventAlreadyHandled(e)) return;
41
40
  if (e.button !== 0 && e.button !== 1 && e.button !== 2 && e.button !== 5) return;
41
+ const rightClickPanning = editor.options.rightClickPanning;
42
+ const wasRightClickPanning = rightClickPanning && e.button === 2 && editor.inputs.getIsPanning();
42
43
  releasePointerCapture(e.currentTarget, e);
43
44
  editor.dispatch({
44
45
  type: "pointer",
@@ -46,6 +47,19 @@ function useCanvasEvents() {
46
47
  name: "pointer_up",
47
48
  ...getPointerInfo(editor, e)
48
49
  });
50
+ if (rightClickPanning && e.button === 2 && !wasRightClickPanning) {
51
+ const contextMenuEvent = new PointerEvent("contextmenu", {
52
+ bubbles: true,
53
+ clientX: e.clientX,
54
+ clientY: e.clientY,
55
+ button: 2,
56
+ buttons: 0,
57
+ pointerId: e.pointerId,
58
+ pointerType: e.pointerType,
59
+ isPrimary: e.isPrimary
60
+ });
61
+ e.currentTarget.dispatchEvent(contextMenuEvent);
62
+ }
49
63
  }
50
64
  function onPointerEnter(e) {
51
65
  if (editor.wasEventAlreadyHandled(e)) return;
@@ -117,6 +131,12 @@ function useCanvasEvents() {
117
131
  if (editor.wasEventAlreadyHandled(e)) return;
118
132
  e.stopPropagation();
119
133
  }
134
+ function onContextMenu(e) {
135
+ if (!editor.options.rightClickPanning) return;
136
+ if (e.nativeEvent.isTrusted) {
137
+ preventDefault(e);
138
+ }
139
+ }
120
140
  return {
121
141
  onPointerDown,
122
142
  onPointerUp,
@@ -126,7 +146,8 @@ function useCanvasEvents() {
126
146
  onDrop,
127
147
  onTouchStart,
128
148
  onTouchEnd,
129
- onClick
149
+ onClick,
150
+ onContextMenu
130
151
  };
131
152
  },
132
153
  [editor]
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/hooks/useCanvasEvents.ts"],
4
- "sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport React, { useEffect, useMemo } from 'react'\nimport { RIGHT_MOUSE_BUTTON } from '../constants'\nimport { tlenv } from '../globals/environment'\nimport {\n\telementShouldCaptureKeys,\n\tpreventDefault,\n\treleasePointerCapture,\n\tsetPointerCapture,\n} from '../utils/dom'\nimport { getPointerInfo } from '../utils/getPointerInfo'\nimport { useEditor } from './useEditor'\n\nexport function useCanvasEvents() {\n\tconst editor = useEditor()\n\tconst ownerDocument = editor.getContainerDocument()\n\tconst currentTool = useValue('current tool', () => editor.getCurrentTool(), [editor])\n\n\tconst events = useMemo(\n\t\tfunction canvasEvents() {\n\t\t\tfunction onPointerDown(e: React.PointerEvent) {\n\t\t\t\tif (editor.wasEventAlreadyHandled(e)) return\n\n\t\t\t\tif (e.button === RIGHT_MOUSE_BUTTON) {\n\t\t\t\t\teditor.dispatch({\n\t\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\t\tname: 'right_click',\n\t\t\t\t\t\t...getPointerInfo(editor, e),\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tif (e.button !== 0 && e.button !== 1 && e.button !== 5) return\n\n\t\t\t\tsetPointerCapture(e.currentTarget, e)\n\n\t\t\t\teditor.dispatch({\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_down',\n\t\t\t\t\t...getPointerInfo(editor, e),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tfunction onPointerUp(e: React.PointerEvent) {\n\t\t\t\tif (editor.wasEventAlreadyHandled(e)) return\n\t\t\t\tif (e.button !== 0 && e.button !== 1 && e.button !== 2 && e.button !== 5) return\n\n\t\t\t\treleasePointerCapture(e.currentTarget, e)\n\n\t\t\t\teditor.dispatch({\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_up',\n\t\t\t\t\t...getPointerInfo(editor, e),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tfunction onPointerEnter(e: React.PointerEvent) {\n\t\t\t\tif (editor.wasEventAlreadyHandled(e)) return\n\t\t\t\tif (editor.getInstanceState().isPenMode && e.pointerType !== 'pen') return\n\t\t\t\tconst canHover = e.pointerType === 'mouse' || e.pointerType === 'pen'\n\t\t\t\teditor.updateInstanceState({ isHoveringCanvas: canHover ? true : null })\n\t\t\t}\n\n\t\t\tfunction onPointerLeave(e: React.PointerEvent) {\n\t\t\t\tif (editor.wasEventAlreadyHandled(e)) return\n\t\t\t\tif (editor.getInstanceState().isPenMode && e.pointerType !== 'pen') return\n\t\t\t\tconst canHover = e.pointerType === 'mouse' || e.pointerType === 'pen'\n\t\t\t\teditor.updateInstanceState({ isHoveringCanvas: canHover ? false : null })\n\t\t\t}\n\n\t\t\tfunction onTouchStart(e: React.TouchEvent) {\n\t\t\t\tif (editor.wasEventAlreadyHandled(e)) return\n\t\t\t\teditor.markEventAsHandled(e)\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\n\t\t\tfunction onTouchEnd(e: React.TouchEvent) {\n\t\t\t\tif (editor.wasEventAlreadyHandled(e)) return\n\t\t\t\teditor.markEventAsHandled(e)\n\t\t\t\tif (!(e.target instanceof editor.getContainerWindow().HTMLElement)) return\n\n\t\t\t\tconst editingShapeId = editor.getEditingShapeId()\n\t\t\t\tif (\n\t\t\t\t\t// if the target is not inside the editing shape\n\t\t\t\t\t!(editingShapeId && e.target.closest(`[data-shape-id=\"${editingShapeId}\"]`)) &&\n\t\t\t\t\t// and the target is not an clickable element\n\t\t\t\t\te.target.tagName !== 'A' &&\n\t\t\t\t\t// and the target is not an editable element\n\t\t\t\t\t!elementShouldCaptureKeys(e.target, false)\n\t\t\t\t) {\n\t\t\t\t\tpreventDefault(e)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction onDragOver(e: React.DragEvent<Element>) {\n\t\t\t\tif (editor.wasEventAlreadyHandled(e)) return\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\n\t\t\tasync function onDrop(e: React.DragEvent<Element>) {\n\t\t\t\tif (editor.wasEventAlreadyHandled(e)) return\n\t\t\t\tpreventDefault(e)\n\t\t\t\te.stopPropagation()\n\n\t\t\t\tconst pagePoint = editor.screenToPage({ x: e.clientX, y: e.clientY })\n\n\t\t\t\t// Call the custom onDropOnCanvas callback if provided\n\t\t\t\tif (editor.options.experimental__onDropOnCanvas) {\n\t\t\t\t\tconst handled = editor.options.experimental__onDropOnCanvas({\n\t\t\t\t\t\tpoint: pagePoint,\n\t\t\t\t\t\tevent: e,\n\t\t\t\t\t})\n\t\t\t\t\tif (handled) return\n\t\t\t\t}\n\n\t\t\t\tif (e.dataTransfer?.files?.length) {\n\t\t\t\t\tconst files = Array.from(e.dataTransfer.files)\n\n\t\t\t\t\tawait editor.putExternalContent({\n\t\t\t\t\t\ttype: 'files',\n\t\t\t\t\t\tfiles,\n\t\t\t\t\t\tpoint: pagePoint,\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst url = e.dataTransfer.getData('url')\n\t\t\t\tif (url) {\n\t\t\t\t\tawait editor.putExternalContent({\n\t\t\t\t\t\ttype: 'url',\n\t\t\t\t\t\turl,\n\t\t\t\t\t\tpoint: pagePoint,\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction onClick(e: React.MouseEvent) {\n\t\t\t\tif (editor.wasEventAlreadyHandled(e)) return\n\t\t\t\te.stopPropagation()\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tonPointerDown,\n\t\t\t\tonPointerUp,\n\t\t\t\tonPointerEnter,\n\t\t\t\tonPointerLeave,\n\t\t\t\tonDragOver,\n\t\t\t\tonDrop,\n\t\t\t\tonTouchStart,\n\t\t\t\tonTouchEnd,\n\t\t\t\tonClick,\n\t\t\t}\n\t\t},\n\t\t[editor]\n\t)\n\n\t// onPointerMove is special: where we're only interested in the other events when they're\n\t// happening _on_ the canvas (as opposed to outside of it, or on UI floating over it), we want\n\t// the pointer position to be up to date regardless of whether it's over the tldraw canvas or\n\t// not. So instead of returning a listener to be attached to the canvas, we directly attach a\n\t// listener to the whole document instead.\n\tuseEffect(() => {\n\t\tlet lastX: number, lastY: number\n\n\t\tfunction onPointerMove(e: PointerEvent) {\n\t\t\tif (editor.wasEventAlreadyHandled(e)) return\n\t\t\teditor.markEventAsHandled(e)\n\n\t\t\tif (e.clientX === lastX && e.clientY === lastY) return\n\t\t\tlastX = e.clientX\n\t\t\tlastY = e.clientY\n\n\t\t\t// For tools that benefit from a higher fidelity of events,\n\t\t\t// we dispatch the coalesced events.\n\t\t\t// N.B. Sometimes getCoalescedEvents isn't present on iOS, ugh.\n\t\t\t// Specifically, in local mode (non-https) mode, iOS does not `useCoalescedEvents`\n\t\t\t// so it appears like the ink is working locally, when really it's just that `useCoalescedEvents`\n\t\t\t// is disabled. The intent here is to have `useCoalescedEvents` disabled for iOS.\n\t\t\tconst events =\n\t\t\t\t!tlenv.isIos && currentTool.useCoalescedEvents && e.getCoalescedEvents\n\t\t\t\t\t? e.getCoalescedEvents()\n\t\t\t\t\t: [e]\n\n\t\t\tfor (const singleEvent of events) {\n\t\t\t\teditor.dispatch({\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_move',\n\t\t\t\t\t...getPointerInfo(editor, singleEvent),\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\townerDocument.body.addEventListener('pointermove', onPointerMove)\n\t\treturn () => {\n\t\t\townerDocument.body.removeEventListener('pointermove', onPointerMove)\n\t\t}\n\t}, [editor, currentTool, ownerDocument])\n\n\treturn events\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport React, { useEffect, useMemo } from 'react'\nimport { tlenv } from '../globals/environment'\nimport {\n\telementShouldCaptureKeys,\n\tpreventDefault,\n\treleasePointerCapture,\n\tsetPointerCapture,\n} from '../utils/dom'\nimport { getPointerInfo } from '../utils/getPointerInfo'\nimport { useEditor } from './useEditor'\n\nexport function useCanvasEvents() {\n\tconst editor = useEditor()\n\tconst ownerDocument = editor.getContainerDocument()\n\tconst currentTool = useValue('current tool', () => editor.getCurrentTool(), [editor])\n\n\tconst events = useMemo(\n\t\tfunction canvasEvents() {\n\t\t\tfunction onPointerDown(e: React.PointerEvent) {\n\t\t\t\tif (editor.wasEventAlreadyHandled(e)) return\n\n\t\t\t\t// With right-click panning disabled, fire right_click on press and let the\n\t\t\t\t// native contextmenu through so the menu opens at the pointer-down location.\n\t\t\t\tif (e.button === 2 && !editor.options.rightClickPanning) {\n\t\t\t\t\teditor.dispatch({\n\t\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\t\tname: 'right_click',\n\t\t\t\t\t\t...getPointerInfo(editor, e),\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tif (e.button !== 0 && e.button !== 1 && e.button !== 2 && e.button !== 5) return\n\n\t\t\t\tsetPointerCapture(e.currentTarget, e)\n\n\t\t\t\teditor.dispatch({\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_down',\n\t\t\t\t\t...getPointerInfo(editor, e),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tfunction onPointerUp(e: React.PointerEvent) {\n\t\t\t\tif (editor.wasEventAlreadyHandled(e)) return\n\t\t\t\tif (e.button !== 0 && e.button !== 1 && e.button !== 2 && e.button !== 5) return\n\n\t\t\t\tconst rightClickPanning = editor.options.rightClickPanning\n\t\t\t\t// Check before dispatch (which resets isPanning)\n\t\t\t\tconst wasRightClickPanning =\n\t\t\t\t\trightClickPanning && e.button === 2 && editor.inputs.getIsPanning()\n\n\t\t\t\treleasePointerCapture(e.currentTarget, e)\n\n\t\t\t\teditor.dispatch({\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_up',\n\t\t\t\t\t...getPointerInfo(editor, e),\n\t\t\t\t})\n\n\t\t\t\t// Static right-click: fire contextmenu at the pointer-up location\n\t\t\t\tif (rightClickPanning && e.button === 2 && !wasRightClickPanning) {\n\t\t\t\t\tconst contextMenuEvent = new PointerEvent('contextmenu', {\n\t\t\t\t\t\tbubbles: true,\n\t\t\t\t\t\tclientX: e.clientX,\n\t\t\t\t\t\tclientY: e.clientY,\n\t\t\t\t\t\tbutton: 2,\n\t\t\t\t\t\tbuttons: 0,\n\t\t\t\t\t\tpointerId: e.pointerId,\n\t\t\t\t\t\tpointerType: e.pointerType,\n\t\t\t\t\t\tisPrimary: e.isPrimary,\n\t\t\t\t\t})\n\t\t\t\t\te.currentTarget.dispatchEvent(contextMenuEvent)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction onPointerEnter(e: React.PointerEvent) {\n\t\t\t\tif (editor.wasEventAlreadyHandled(e)) return\n\t\t\t\tif (editor.getInstanceState().isPenMode && e.pointerType !== 'pen') return\n\t\t\t\tconst canHover = e.pointerType === 'mouse' || e.pointerType === 'pen'\n\t\t\t\teditor.updateInstanceState({ isHoveringCanvas: canHover ? true : null })\n\t\t\t}\n\n\t\t\tfunction onPointerLeave(e: React.PointerEvent) {\n\t\t\t\tif (editor.wasEventAlreadyHandled(e)) return\n\t\t\t\tif (editor.getInstanceState().isPenMode && e.pointerType !== 'pen') return\n\t\t\t\tconst canHover = e.pointerType === 'mouse' || e.pointerType === 'pen'\n\t\t\t\teditor.updateInstanceState({ isHoveringCanvas: canHover ? false : null })\n\t\t\t}\n\n\t\t\tfunction onTouchStart(e: React.TouchEvent) {\n\t\t\t\tif (editor.wasEventAlreadyHandled(e)) return\n\t\t\t\teditor.markEventAsHandled(e)\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\n\t\t\tfunction onTouchEnd(e: React.TouchEvent) {\n\t\t\t\tif (editor.wasEventAlreadyHandled(e)) return\n\t\t\t\teditor.markEventAsHandled(e)\n\t\t\t\tif (!(e.target instanceof editor.getContainerWindow().HTMLElement)) return\n\n\t\t\t\tconst editingShapeId = editor.getEditingShapeId()\n\t\t\t\tif (\n\t\t\t\t\t// if the target is not inside the editing shape\n\t\t\t\t\t!(editingShapeId && e.target.closest(`[data-shape-id=\"${editingShapeId}\"]`)) &&\n\t\t\t\t\t// and the target is not an clickable element\n\t\t\t\t\te.target.tagName !== 'A' &&\n\t\t\t\t\t// and the target is not an editable element\n\t\t\t\t\t!elementShouldCaptureKeys(e.target, false)\n\t\t\t\t) {\n\t\t\t\t\tpreventDefault(e)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction onDragOver(e: React.DragEvent<Element>) {\n\t\t\t\tif (editor.wasEventAlreadyHandled(e)) return\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\n\t\t\tasync function onDrop(e: React.DragEvent<Element>) {\n\t\t\t\tif (editor.wasEventAlreadyHandled(e)) return\n\t\t\t\tpreventDefault(e)\n\t\t\t\te.stopPropagation()\n\n\t\t\t\tconst pagePoint = editor.screenToPage({ x: e.clientX, y: e.clientY })\n\n\t\t\t\t// Call the custom onDropOnCanvas callback if provided\n\t\t\t\tif (editor.options.experimental__onDropOnCanvas) {\n\t\t\t\t\tconst handled = editor.options.experimental__onDropOnCanvas({\n\t\t\t\t\t\tpoint: pagePoint,\n\t\t\t\t\t\tevent: e,\n\t\t\t\t\t})\n\t\t\t\t\tif (handled) return\n\t\t\t\t}\n\n\t\t\t\tif (e.dataTransfer?.files?.length) {\n\t\t\t\t\tconst files = Array.from(e.dataTransfer.files)\n\n\t\t\t\t\tawait editor.putExternalContent({\n\t\t\t\t\t\ttype: 'files',\n\t\t\t\t\t\tfiles,\n\t\t\t\t\t\tpoint: pagePoint,\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst url = e.dataTransfer.getData('url')\n\t\t\t\tif (url) {\n\t\t\t\t\tawait editor.putExternalContent({\n\t\t\t\t\t\ttype: 'url',\n\t\t\t\t\t\turl,\n\t\t\t\t\t\tpoint: pagePoint,\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction onClick(e: React.MouseEvent) {\n\t\t\t\tif (editor.wasEventAlreadyHandled(e)) return\n\t\t\t\te.stopPropagation()\n\t\t\t}\n\n\t\t\tfunction onContextMenu(e: React.MouseEvent) {\n\t\t\t\t// With right-click panning disabled, let the native contextmenu through so the\n\t\t\t\t// menu opens on press.\n\t\t\t\tif (!editor.options.rightClickPanning) return\n\t\t\t\t// Synthetic events \u2014 our own dispatch from onPointerUp, or tests using\n\t\t\t\t// fireEvent.contextMenu \u2014 pass through so Radix can open the menu. The real\n\t\t\t\t// browser contextmenu is always suppressed: right-click behavior has\n\t\t\t\t// already been decided by our pointer handling (either we dispatched a\n\t\t\t\t// synthetic to open the menu at the release position, or we panned and\n\t\t\t\t// don't want a menu at all).\n\t\t\t\tif (e.nativeEvent.isTrusted) {\n\t\t\t\t\tpreventDefault(e)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tonPointerDown,\n\t\t\t\tonPointerUp,\n\t\t\t\tonPointerEnter,\n\t\t\t\tonPointerLeave,\n\t\t\t\tonDragOver,\n\t\t\t\tonDrop,\n\t\t\t\tonTouchStart,\n\t\t\t\tonTouchEnd,\n\t\t\t\tonClick,\n\t\t\t\tonContextMenu,\n\t\t\t}\n\t\t},\n\t\t[editor]\n\t)\n\n\t// onPointerMove is special: where we're only interested in the other events when they're\n\t// happening _on_ the canvas (as opposed to outside of it, or on UI floating over it), we want\n\t// the pointer position to be up to date regardless of whether it's over the tldraw canvas or\n\t// not. So instead of returning a listener to be attached to the canvas, we directly attach a\n\t// listener to the whole document instead.\n\tuseEffect(() => {\n\t\tlet lastX: number, lastY: number\n\n\t\tfunction onPointerMove(e: PointerEvent) {\n\t\t\tif (editor.wasEventAlreadyHandled(e)) return\n\t\t\teditor.markEventAsHandled(e)\n\n\t\t\tif (e.clientX === lastX && e.clientY === lastY) return\n\t\t\tlastX = e.clientX\n\t\t\tlastY = e.clientY\n\n\t\t\t// For tools that benefit from a higher fidelity of events,\n\t\t\t// we dispatch the coalesced events.\n\t\t\t// N.B. Sometimes getCoalescedEvents isn't present on iOS, ugh.\n\t\t\t// Specifically, in local mode (non-https) mode, iOS does not `useCoalescedEvents`\n\t\t\t// so it appears like the ink is working locally, when really it's just that `useCoalescedEvents`\n\t\t\t// is disabled. The intent here is to have `useCoalescedEvents` disabled for iOS.\n\t\t\tconst events =\n\t\t\t\t!tlenv.isIos && currentTool.useCoalescedEvents && e.getCoalescedEvents\n\t\t\t\t\t? e.getCoalescedEvents()\n\t\t\t\t\t: [e]\n\n\t\t\tfor (const singleEvent of events) {\n\t\t\t\teditor.dispatch({\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_move',\n\t\t\t\t\t...getPointerInfo(editor, singleEvent),\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\townerDocument.body.addEventListener('pointermove', onPointerMove)\n\t\treturn () => {\n\t\t\townerDocument.body.removeEventListener('pointermove', onPointerMove)\n\t\t}\n\t}, [editor, currentTool, ownerDocument])\n\n\treturn events\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["events"]
7
7
  }
@@ -0,0 +1,19 @@
1
+ import { useValue } from "@tldraw/state-react";
2
+ import { useSvgExportContext } from "../editor/types/SvgExportContext.mjs";
3
+ import { useEditor } from "./useEditor.mjs";
4
+ function useColorMode() {
5
+ const editor = useEditor();
6
+ const exportContext = useSvgExportContext();
7
+ return useValue(
8
+ "colorMode",
9
+ () => {
10
+ if (exportContext) return exportContext.colorMode;
11
+ return editor.getColorMode();
12
+ },
13
+ [exportContext, editor]
14
+ );
15
+ }
16
+ export {
17
+ useColorMode
18
+ };
19
+ //# sourceMappingURL=useColorMode.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/lib/hooks/useColorMode.ts"],
4
+ "sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport { useSvgExportContext } from '../editor/types/SvgExportContext'\nimport { useEditor } from './useEditor'\n\n/** @public */\nexport function useColorMode(): 'light' | 'dark' {\n\tconst editor = useEditor()\n\tconst exportContext = useSvgExportContext()\n\treturn useValue(\n\t\t'colorMode',\n\t\t() => {\n\t\t\tif (exportContext) return exportContext.colorMode\n\t\t\treturn editor.getColorMode()\n\t\t},\n\t\t[exportContext, editor]\n\t)\n}\n"],
5
+ "mappings": "AAAA,SAAS,gBAAgB;AACzB,SAAS,2BAA2B;AACpC,SAAS,iBAAiB;AAGnB,SAAS,eAAiC;AAChD,QAAM,SAAS,UAAU;AACzB,QAAM,gBAAgB,oBAAoB;AAC1C,SAAO;AAAA,IACN;AAAA,IACA,MAAM;AACL,UAAI,cAAe,QAAO,cAAc;AACxC,aAAO,OAAO,aAAa;AAAA,IAC5B;AAAA,IACA,CAAC,eAAe,MAAM;AAAA,EACvB;AACD;",
6
+ "names": []
7
+ }