tldraw 5.2.0-next.ee0fa4d6244f → 5.2.0

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 (474) hide show
  1. package/DOCS.md +20294 -0
  2. package/README.md +13 -1
  3. package/RELEASE_NOTES.md +2908 -0
  4. package/dist-cjs/index.d.ts +110 -25
  5. package/dist-cjs/index.js +3 -3
  6. package/dist-cjs/index.js.map +2 -2
  7. package/dist-cjs/lib/TldrawImage.js +0 -1
  8. package/dist-cjs/lib/TldrawImage.js.map +2 -2
  9. package/dist-cjs/lib/bindings/arrow/ArrowBindingUtil.js +2 -1
  10. package/dist-cjs/lib/bindings/arrow/ArrowBindingUtil.js.map +2 -2
  11. package/dist-cjs/lib/defaultEmbedDefinitions.js +3 -2
  12. package/dist-cjs/lib/defaultEmbedDefinitions.js.map +2 -2
  13. package/dist-cjs/lib/defaultOverlayUtils.js +11 -11
  14. package/dist-cjs/lib/defaultOverlayUtils.js.map +2 -2
  15. package/dist-cjs/lib/overlays/SelectionForegroundOverlayUtil.js +76 -64
  16. package/dist-cjs/lib/overlays/SelectionForegroundOverlayUtil.js.map +2 -2
  17. package/dist-cjs/lib/overlays/ShapeHandleOverlayUtil.js +1 -1
  18. package/dist-cjs/lib/overlays/ShapeHandleOverlayUtil.js.map +2 -2
  19. package/dist-cjs/lib/overlays/ShapeIndicatorOverlayUtil.js +107 -0
  20. package/dist-cjs/lib/overlays/ShapeIndicatorOverlayUtil.js.map +7 -0
  21. package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js +3 -0
  22. package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js.map +2 -2
  23. package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js +12 -3
  24. package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js.map +2 -2
  25. package/dist-cjs/lib/shapes/bookmark/bookmarks.js +54 -6
  26. package/dist-cjs/lib/shapes/bookmark/bookmarks.js.map +2 -2
  27. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js +2 -1
  28. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js.map +2 -2
  29. package/dist-cjs/lib/shapes/draw/getPath.js +1 -1
  30. package/dist-cjs/lib/shapes/draw/getPath.js.map +2 -2
  31. package/dist-cjs/lib/shapes/draw/toolStates/Drawing.js +45 -47
  32. package/dist-cjs/lib/shapes/draw/toolStates/Drawing.js.map +2 -2
  33. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js +2 -1
  34. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js.map +2 -2
  35. package/dist-cjs/lib/shapes/frame/FrameShapeTool.js +23 -18
  36. package/dist-cjs/lib/shapes/frame/FrameShapeTool.js.map +2 -2
  37. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js +1 -1
  38. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js.map +2 -2
  39. package/dist-cjs/lib/shapes/geo/toolStates/Pointing.js +3 -0
  40. package/dist-cjs/lib/shapes/geo/toolStates/Pointing.js.map +2 -2
  41. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js +11 -7
  42. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js.map +2 -2
  43. package/dist-cjs/lib/shapes/image/ImageShapeUtil.js +3 -11
  44. package/dist-cjs/lib/shapes/image/ImageShapeUtil.js.map +2 -2
  45. package/dist-cjs/lib/shapes/line/toolStates/Pointing.js +5 -1
  46. package/dist-cjs/lib/shapes/line/toolStates/Pointing.js.map +2 -2
  47. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js +31 -41
  48. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js.map +2 -2
  49. package/dist-cjs/lib/shapes/note/noteHelpers.js +1 -1
  50. package/dist-cjs/lib/shapes/note/noteHelpers.js.map +2 -2
  51. package/dist-cjs/lib/shapes/note/toolStates/Pointing.js +28 -6
  52. package/dist-cjs/lib/shapes/note/toolStates/Pointing.js.map +2 -2
  53. package/dist-cjs/lib/shapes/shared/PlainTextLabel.js +3 -2
  54. package/dist-cjs/lib/shapes/shared/PlainTextLabel.js.map +2 -2
  55. package/dist-cjs/lib/shapes/shared/RichTextLabel.js +3 -3
  56. package/dist-cjs/lib/shapes/shared/RichTextLabel.js.map +2 -2
  57. package/dist-cjs/lib/shapes/shared/defaultStyleDefs.js +17 -3
  58. package/dist-cjs/lib/shapes/shared/defaultStyleDefs.js.map +2 -2
  59. package/dist-cjs/lib/shapes/shared/freehand/core.js +424 -0
  60. package/dist-cjs/lib/shapes/shared/freehand/core.js.map +7 -0
  61. package/dist-cjs/lib/shapes/shared/freehand/fmt.js +106 -0
  62. package/dist-cjs/lib/shapes/shared/freehand/fmt.js.map +7 -0
  63. package/dist-cjs/lib/shapes/shared/freehand/getStroke.js +6 -6
  64. package/dist-cjs/lib/shapes/shared/freehand/getStroke.js.map +2 -2
  65. package/dist-cjs/lib/shapes/shared/freehand/getStrokeOutlinePoints.js +320 -86
  66. package/dist-cjs/lib/shapes/shared/freehand/getStrokeOutlinePoints.js.map +3 -3
  67. package/dist-cjs/lib/shapes/shared/freehand/getStrokePoints.js +20 -96
  68. package/dist-cjs/lib/shapes/shared/freehand/getStrokePoints.js.map +3 -3
  69. package/dist-cjs/lib/shapes/shared/freehand/svg.js +55 -19
  70. package/dist-cjs/lib/shapes/shared/freehand/svg.js.map +2 -2
  71. package/dist-cjs/lib/shapes/shared/freehand/svgInk.js +189 -97
  72. package/dist-cjs/lib/shapes/shared/freehand/svgInk.js.map +3 -3
  73. package/dist-cjs/lib/shapes/shared/freehand/types.js.map +1 -1
  74. package/dist-cjs/lib/shapes/shared/interpolate-props.js +6 -2
  75. package/dist-cjs/lib/shapes/shared/interpolate-props.js.map +2 -2
  76. package/dist-cjs/lib/shapes/text/toolStates/Pointing.js +3 -0
  77. package/dist-cjs/lib/shapes/text/toolStates/Pointing.js.map +2 -2
  78. package/dist-cjs/lib/tools/HandTool/HandTool.js +14 -25
  79. package/dist-cjs/lib/tools/HandTool/HandTool.js.map +2 -2
  80. package/dist-cjs/lib/tools/HandTool/childStates/Dragging.js +10 -1
  81. package/dist-cjs/lib/tools/HandTool/childStates/Dragging.js.map +2 -2
  82. package/dist-cjs/lib/tools/HandTool/childStates/OneFingerZooming.js +84 -0
  83. package/dist-cjs/lib/tools/HandTool/childStates/OneFingerZooming.js.map +7 -0
  84. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/Crop.js +3 -1
  85. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/Crop.js.map +2 -2
  86. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Idle.js +1 -1
  87. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Idle.js.map +2 -2
  88. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/PointingCrop.js +7 -0
  89. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/PointingCrop.js.map +2 -2
  90. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.js +7 -0
  91. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.js.map +2 -2
  92. package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js +13 -1
  93. package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js.map +2 -2
  94. package/dist-cjs/lib/tools/SelectTool/childStates/PointingCanvas.js +7 -0
  95. package/dist-cjs/lib/tools/SelectTool/childStates/PointingCanvas.js.map +2 -2
  96. package/dist-cjs/lib/tools/SelectTool/childStates/PointingHandle.js +7 -0
  97. package/dist-cjs/lib/tools/SelectTool/childStates/PointingHandle.js.map +2 -2
  98. package/dist-cjs/lib/tools/SelectTool/childStates/PointingResizeHandle.js +7 -0
  99. package/dist-cjs/lib/tools/SelectTool/childStates/PointingResizeHandle.js.map +2 -2
  100. package/dist-cjs/lib/tools/SelectTool/childStates/PointingRotateHandle.js +7 -0
  101. package/dist-cjs/lib/tools/SelectTool/childStates/PointingRotateHandle.js.map +2 -2
  102. package/dist-cjs/lib/tools/SelectTool/childStates/PointingSelection.js +4 -1
  103. package/dist-cjs/lib/tools/SelectTool/childStates/PointingSelection.js.map +2 -2
  104. package/dist-cjs/lib/tools/SelectTool/childStates/PointingShape.js +14 -1
  105. package/dist-cjs/lib/tools/SelectTool/childStates/PointingShape.js.map +2 -2
  106. package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js +107 -46
  107. package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js.map +2 -2
  108. package/dist-cjs/lib/ui/TldrawUi.js +4 -3
  109. package/dist-cjs/lib/ui/TldrawUi.js.map +2 -2
  110. package/dist-cjs/lib/ui/components/A11y.js +2 -0
  111. package/dist-cjs/lib/ui/components/A11y.js.map +2 -2
  112. package/dist-cjs/lib/ui/components/ContextMenu/DefaultContextMenu.js +14 -1
  113. package/dist-cjs/lib/ui/components/ContextMenu/DefaultContextMenu.js.map +2 -2
  114. package/dist-cjs/lib/ui/components/ContextMenu/DefaultContextMenuContent.js +0 -6
  115. package/dist-cjs/lib/ui/components/ContextMenu/DefaultContextMenuContent.js.map +2 -2
  116. package/dist-cjs/lib/ui/components/DefaultFollowingIndicator.js.map +2 -2
  117. package/dist-cjs/lib/ui/components/Dialogs.js +17 -37
  118. package/dist-cjs/lib/ui/components/Dialogs.js.map +2 -2
  119. package/dist-cjs/lib/ui/components/HelperButtons/BackToContent.js +19 -4
  120. package/dist-cjs/lib/ui/components/HelperButtons/BackToContent.js.map +2 -2
  121. package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js +12 -2
  122. package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js.map +2 -2
  123. package/dist-cjs/lib/ui/components/Minimap/DefaultMinimap.js +47 -70
  124. package/dist-cjs/lib/ui/components/Minimap/DefaultMinimap.js.map +2 -2
  125. package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js +25 -46
  126. package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js.map +2 -2
  127. package/dist-cjs/lib/ui/components/SharePanel/DefaultPeopleMenuAvatar.js.map +2 -2
  128. package/dist-cjs/lib/ui/components/SharePanel/DefaultPeopleMenuContent.js.map +2 -2
  129. package/dist-cjs/lib/ui/components/SharePanel/DefaultPeopleMenuFacePile.js.map +2 -2
  130. package/dist-cjs/lib/ui/components/SharePanel/DefaultPeopleMenuItem.js +1 -1
  131. package/dist-cjs/lib/ui/components/SharePanel/DefaultPeopleMenuItem.js.map +2 -2
  132. package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js +1 -0
  133. package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js.map +2 -2
  134. package/dist-cjs/lib/ui/components/StylePanel/StylePanelDropdownPicker.js +2 -1
  135. package/dist-cjs/lib/ui/components/StylePanel/StylePanelDropdownPicker.js.map +2 -2
  136. package/dist-cjs/lib/ui/components/menu-items.js +7 -0
  137. package/dist-cjs/lib/ui/components/menu-items.js.map +2 -2
  138. package/dist-cjs/lib/ui/components/primitives/TldrawUiDropdownMenu.js +2 -1
  139. package/dist-cjs/lib/ui/components/primitives/TldrawUiDropdownMenu.js.map +2 -2
  140. package/dist-cjs/lib/ui/components/primitives/TldrawUiIcon.js +14 -3
  141. package/dist-cjs/lib/ui/components/primitives/TldrawUiIcon.js.map +2 -2
  142. package/dist-cjs/lib/ui/components/primitives/TldrawUiInput.js +2 -0
  143. package/dist-cjs/lib/ui/components/primitives/TldrawUiInput.js.map +2 -2
  144. package/dist-cjs/lib/ui/components/primitives/TldrawUiPopover.js +2 -0
  145. package/dist-cjs/lib/ui/components/primitives/TldrawUiPopover.js.map +2 -2
  146. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.js +0 -2
  147. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.js.map +2 -2
  148. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuSubmenu.js +1 -2
  149. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuSubmenu.js.map +2 -2
  150. package/dist-cjs/lib/ui/context/actions.js +70 -1
  151. package/dist-cjs/lib/ui/context/actions.js.map +2 -2
  152. package/dist-cjs/lib/ui/context/asset-urls.js +5 -8
  153. package/dist-cjs/lib/ui/context/asset-urls.js.map +2 -2
  154. package/dist-cjs/lib/ui/context/events.js.map +2 -2
  155. package/dist-cjs/lib/ui/hooks/useKeyboardShortcuts.js +13 -0
  156. package/dist-cjs/lib/ui/hooks/useKeyboardShortcuts.js.map +2 -2
  157. package/dist-cjs/lib/ui/hooks/useTools.js +1 -1
  158. package/dist-cjs/lib/ui/hooks/useTools.js.map +2 -2
  159. package/dist-cjs/lib/ui/hooks/useTranslation/TLUiTranslationKey.js.map +1 -1
  160. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js +2 -0
  161. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js.map +2 -2
  162. package/dist-cjs/lib/ui/version.js +3 -3
  163. package/dist-cjs/lib/ui/version.js.map +1 -1
  164. package/dist-cjs/lib/utils/embeds/embeds.js +4 -4
  165. package/dist-cjs/lib/utils/embeds/embeds.js.map +2 -2
  166. package/dist-cjs/lib/utils/test-helpers.js +2 -2
  167. package/dist-cjs/lib/utils/test-helpers.js.map +2 -2
  168. package/dist-cjs/lib/utils/text/richText.js +3 -1
  169. package/dist-cjs/lib/utils/text/richText.js.map +2 -2
  170. package/dist-esm/index.d.mts +110 -25
  171. package/dist-esm/index.mjs +5 -3
  172. package/dist-esm/index.mjs.map +2 -2
  173. package/dist-esm/lib/TldrawImage.mjs +0 -1
  174. package/dist-esm/lib/TldrawImage.mjs.map +2 -2
  175. package/dist-esm/lib/bindings/arrow/ArrowBindingUtil.mjs +2 -1
  176. package/dist-esm/lib/bindings/arrow/ArrowBindingUtil.mjs.map +2 -2
  177. package/dist-esm/lib/defaultEmbedDefinitions.mjs +3 -2
  178. package/dist-esm/lib/defaultEmbedDefinitions.mjs.map +2 -2
  179. package/dist-esm/lib/defaultOverlayUtils.mjs +11 -11
  180. package/dist-esm/lib/defaultOverlayUtils.mjs.map +2 -2
  181. package/dist-esm/lib/overlays/SelectionForegroundOverlayUtil.mjs +77 -65
  182. package/dist-esm/lib/overlays/SelectionForegroundOverlayUtil.mjs.map +2 -2
  183. package/dist-esm/lib/overlays/ShapeHandleOverlayUtil.mjs +1 -1
  184. package/dist-esm/lib/overlays/ShapeHandleOverlayUtil.mjs.map +2 -2
  185. package/dist-esm/lib/overlays/ShapeIndicatorOverlayUtil.mjs +87 -0
  186. package/dist-esm/lib/overlays/ShapeIndicatorOverlayUtil.mjs.map +7 -0
  187. package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs +9 -1
  188. package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs.map +2 -2
  189. package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs +15 -3
  190. package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs.map +2 -2
  191. package/dist-esm/lib/shapes/bookmark/bookmarks.mjs +54 -6
  192. package/dist-esm/lib/shapes/bookmark/bookmarks.mjs.map +2 -2
  193. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs +3 -1
  194. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs.map +2 -2
  195. package/dist-esm/lib/shapes/draw/getPath.mjs +1 -1
  196. package/dist-esm/lib/shapes/draw/getPath.mjs.map +2 -2
  197. package/dist-esm/lib/shapes/draw/toolStates/Drawing.mjs +46 -47
  198. package/dist-esm/lib/shapes/draw/toolStates/Drawing.mjs.map +2 -2
  199. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs +2 -1
  200. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs.map +2 -2
  201. package/dist-esm/lib/shapes/frame/FrameShapeTool.mjs +23 -18
  202. package/dist-esm/lib/shapes/frame/FrameShapeTool.mjs.map +2 -2
  203. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs +2 -1
  204. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs.map +2 -2
  205. package/dist-esm/lib/shapes/geo/toolStates/Pointing.mjs +4 -0
  206. package/dist-esm/lib/shapes/geo/toolStates/Pointing.mjs.map +2 -2
  207. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs +12 -7
  208. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs.map +2 -2
  209. package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs +3 -11
  210. package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs.map +2 -2
  211. package/dist-esm/lib/shapes/line/toolStates/Pointing.mjs +6 -1
  212. package/dist-esm/lib/shapes/line/toolStates/Pointing.mjs.map +2 -2
  213. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs +32 -42
  214. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs.map +2 -2
  215. package/dist-esm/lib/shapes/note/noteHelpers.mjs +1 -1
  216. package/dist-esm/lib/shapes/note/noteHelpers.mjs.map +2 -2
  217. package/dist-esm/lib/shapes/note/toolStates/Pointing.mjs +29 -6
  218. package/dist-esm/lib/shapes/note/toolStates/Pointing.mjs.map +2 -2
  219. package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs +3 -2
  220. package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs.map +2 -2
  221. package/dist-esm/lib/shapes/shared/RichTextLabel.mjs +4 -3
  222. package/dist-esm/lib/shapes/shared/RichTextLabel.mjs.map +2 -2
  223. package/dist-esm/lib/shapes/shared/defaultStyleDefs.mjs +17 -3
  224. package/dist-esm/lib/shapes/shared/defaultStyleDefs.mjs.map +2 -2
  225. package/dist-esm/lib/shapes/shared/freehand/core.mjs +404 -0
  226. package/dist-esm/lib/shapes/shared/freehand/core.mjs.map +7 -0
  227. package/dist-esm/lib/shapes/shared/freehand/fmt.mjs +86 -0
  228. package/dist-esm/lib/shapes/shared/freehand/fmt.mjs.map +7 -0
  229. package/dist-esm/lib/shapes/shared/freehand/getStroke.mjs +7 -7
  230. package/dist-esm/lib/shapes/shared/freehand/getStroke.mjs.map +2 -2
  231. package/dist-esm/lib/shapes/shared/freehand/getStrokeOutlinePoints.mjs +332 -86
  232. package/dist-esm/lib/shapes/shared/freehand/getStrokeOutlinePoints.mjs.map +3 -3
  233. package/dist-esm/lib/shapes/shared/freehand/getStrokePoints.mjs +31 -96
  234. package/dist-esm/lib/shapes/shared/freehand/getStrokePoints.mjs.map +3 -3
  235. package/dist-esm/lib/shapes/shared/freehand/svg.mjs +55 -19
  236. package/dist-esm/lib/shapes/shared/freehand/svg.mjs.map +2 -2
  237. package/dist-esm/lib/shapes/shared/freehand/svgInk.mjs +214 -99
  238. package/dist-esm/lib/shapes/shared/freehand/svgInk.mjs.map +3 -3
  239. package/dist-esm/lib/shapes/shared/interpolate-props.mjs +6 -2
  240. package/dist-esm/lib/shapes/shared/interpolate-props.mjs.map +2 -2
  241. package/dist-esm/lib/shapes/text/toolStates/Pointing.mjs +4 -0
  242. package/dist-esm/lib/shapes/text/toolStates/Pointing.mjs.map +2 -2
  243. package/dist-esm/lib/tools/HandTool/HandTool.mjs +14 -25
  244. package/dist-esm/lib/tools/HandTool/HandTool.mjs.map +2 -2
  245. package/dist-esm/lib/tools/HandTool/childStates/Dragging.mjs +10 -1
  246. package/dist-esm/lib/tools/HandTool/childStates/Dragging.mjs.map +2 -2
  247. package/dist-esm/lib/tools/HandTool/childStates/OneFingerZooming.mjs +64 -0
  248. package/dist-esm/lib/tools/HandTool/childStates/OneFingerZooming.mjs.map +7 -0
  249. package/dist-esm/lib/tools/SelectTool/childStates/Crop/Crop.mjs +3 -1
  250. package/dist-esm/lib/tools/SelectTool/childStates/Crop/Crop.mjs.map +2 -2
  251. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Idle.mjs +1 -1
  252. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Idle.mjs.map +2 -2
  253. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/PointingCrop.mjs +7 -0
  254. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/PointingCrop.mjs.map +2 -2
  255. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.mjs +7 -0
  256. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.mjs.map +2 -2
  257. package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs +13 -1
  258. package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs.map +2 -2
  259. package/dist-esm/lib/tools/SelectTool/childStates/PointingCanvas.mjs +7 -0
  260. package/dist-esm/lib/tools/SelectTool/childStates/PointingCanvas.mjs.map +2 -2
  261. package/dist-esm/lib/tools/SelectTool/childStates/PointingHandle.mjs +11 -1
  262. package/dist-esm/lib/tools/SelectTool/childStates/PointingHandle.mjs.map +2 -2
  263. package/dist-esm/lib/tools/SelectTool/childStates/PointingResizeHandle.mjs +10 -1
  264. package/dist-esm/lib/tools/SelectTool/childStates/PointingResizeHandle.mjs.map +2 -2
  265. package/dist-esm/lib/tools/SelectTool/childStates/PointingRotateHandle.mjs +7 -0
  266. package/dist-esm/lib/tools/SelectTool/childStates/PointingRotateHandle.mjs.map +2 -2
  267. package/dist-esm/lib/tools/SelectTool/childStates/PointingSelection.mjs +4 -1
  268. package/dist-esm/lib/tools/SelectTool/childStates/PointingSelection.mjs.map +2 -2
  269. package/dist-esm/lib/tools/SelectTool/childStates/PointingShape.mjs +14 -1
  270. package/dist-esm/lib/tools/SelectTool/childStates/PointingShape.mjs.map +2 -2
  271. package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs +108 -46
  272. package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs.map +2 -2
  273. package/dist-esm/lib/ui/TldrawUi.mjs +4 -3
  274. package/dist-esm/lib/ui/TldrawUi.mjs.map +2 -2
  275. package/dist-esm/lib/ui/components/A11y.mjs +2 -0
  276. package/dist-esm/lib/ui/components/A11y.mjs.map +2 -2
  277. package/dist-esm/lib/ui/components/ContextMenu/DefaultContextMenu.mjs +21 -2
  278. package/dist-esm/lib/ui/components/ContextMenu/DefaultContextMenu.mjs.map +2 -2
  279. package/dist-esm/lib/ui/components/ContextMenu/DefaultContextMenuContent.mjs +0 -6
  280. package/dist-esm/lib/ui/components/ContextMenu/DefaultContextMenuContent.mjs.map +2 -2
  281. package/dist-esm/lib/ui/components/DefaultFollowingIndicator.mjs.map +2 -2
  282. package/dist-esm/lib/ui/components/Dialogs.mjs +19 -39
  283. package/dist-esm/lib/ui/components/Dialogs.mjs.map +2 -2
  284. package/dist-esm/lib/ui/components/HelperButtons/BackToContent.mjs +20 -5
  285. package/dist-esm/lib/ui/components/HelperButtons/BackToContent.mjs.map +2 -2
  286. package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs +12 -2
  287. package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs.map +2 -2
  288. package/dist-esm/lib/ui/components/Minimap/DefaultMinimap.mjs +47 -70
  289. package/dist-esm/lib/ui/components/Minimap/DefaultMinimap.mjs.map +2 -2
  290. package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs +25 -46
  291. package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs.map +2 -2
  292. package/dist-esm/lib/ui/components/SharePanel/DefaultPeopleMenuAvatar.mjs.map +2 -2
  293. package/dist-esm/lib/ui/components/SharePanel/DefaultPeopleMenuContent.mjs.map +2 -2
  294. package/dist-esm/lib/ui/components/SharePanel/DefaultPeopleMenuFacePile.mjs.map +2 -2
  295. package/dist-esm/lib/ui/components/SharePanel/DefaultPeopleMenuItem.mjs +1 -1
  296. package/dist-esm/lib/ui/components/SharePanel/DefaultPeopleMenuItem.mjs.map +2 -2
  297. package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs +1 -0
  298. package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs.map +2 -2
  299. package/dist-esm/lib/ui/components/StylePanel/StylePanelDropdownPicker.mjs +2 -1
  300. package/dist-esm/lib/ui/components/StylePanel/StylePanelDropdownPicker.mjs.map +2 -2
  301. package/dist-esm/lib/ui/components/menu-items.mjs +7 -0
  302. package/dist-esm/lib/ui/components/menu-items.mjs.map +2 -2
  303. package/dist-esm/lib/ui/components/primitives/TldrawUiDropdownMenu.mjs +2 -1
  304. package/dist-esm/lib/ui/components/primitives/TldrawUiDropdownMenu.mjs.map +2 -2
  305. package/dist-esm/lib/ui/components/primitives/TldrawUiIcon.mjs +14 -3
  306. package/dist-esm/lib/ui/components/primitives/TldrawUiIcon.mjs.map +2 -2
  307. package/dist-esm/lib/ui/components/primitives/TldrawUiInput.mjs +2 -0
  308. package/dist-esm/lib/ui/components/primitives/TldrawUiInput.mjs.map +2 -2
  309. package/dist-esm/lib/ui/components/primitives/TldrawUiPopover.mjs +2 -0
  310. package/dist-esm/lib/ui/components/primitives/TldrawUiPopover.mjs.map +2 -2
  311. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.mjs +0 -2
  312. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.mjs.map +2 -2
  313. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuSubmenu.mjs +1 -2
  314. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuSubmenu.mjs.map +2 -2
  315. package/dist-esm/lib/ui/context/actions.mjs +71 -1
  316. package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
  317. package/dist-esm/lib/ui/context/asset-urls.mjs +5 -8
  318. package/dist-esm/lib/ui/context/asset-urls.mjs.map +2 -2
  319. package/dist-esm/lib/ui/context/events.mjs.map +2 -2
  320. package/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs +13 -0
  321. package/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs.map +2 -2
  322. package/dist-esm/lib/ui/hooks/useTools.mjs +1 -1
  323. package/dist-esm/lib/ui/hooks/useTools.mjs.map +2 -2
  324. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs +2 -0
  325. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs.map +2 -2
  326. package/dist-esm/lib/ui/version.mjs +3 -3
  327. package/dist-esm/lib/ui/version.mjs.map +1 -1
  328. package/dist-esm/lib/utils/embeds/embeds.mjs +4 -4
  329. package/dist-esm/lib/utils/embeds/embeds.mjs.map +2 -2
  330. package/dist-esm/lib/utils/test-helpers.mjs +2 -2
  331. package/dist-esm/lib/utils/test-helpers.mjs.map +2 -2
  332. package/dist-esm/lib/utils/text/richText.mjs +3 -1
  333. package/dist-esm/lib/utils/text/richText.mjs.map +2 -2
  334. package/package.json +11 -6
  335. package/src/index.ts +6 -1
  336. package/src/lib/TldrawImage.tsx +2 -2
  337. package/src/lib/bindings/arrow/ArrowBindingUtil.ts +5 -1
  338. package/src/lib/defaultEmbedDefinitions.ts +28 -6
  339. package/src/lib/defaultOverlayUtils.ts +11 -11
  340. package/src/lib/overlays/SelectionForegroundOverlayUtil.ts +91 -72
  341. package/src/lib/overlays/ShapeHandleOverlayUtil.ts +3 -1
  342. package/src/lib/overlays/ShapeIndicatorOverlayUtil.ts +133 -0
  343. package/src/lib/shapes/arrow/toolStates/Pointing.tsx +11 -1
  344. package/src/lib/shapes/bookmark/BookmarkShapeUtil.tsx +16 -3
  345. package/src/lib/shapes/bookmark/bookmarks.ts +105 -15
  346. package/src/lib/shapes/draw/DrawShapeUtil.tsx +7 -5
  347. package/src/lib/shapes/draw/getPath.ts +1 -1
  348. package/src/lib/shapes/draw/toolStates/Drawing.ts +55 -48
  349. package/src/lib/shapes/embed/EmbedShapeUtil.tsx +14 -4
  350. package/src/lib/shapes/frame/FrameShapeTool.ts +35 -24
  351. package/src/lib/shapes/geo/GeoShapeUtil.test.tsx +46 -0
  352. package/src/lib/shapes/geo/GeoShapeUtil.tsx +2 -1
  353. package/src/lib/shapes/geo/toolStates/Pointing.ts +5 -0
  354. package/src/lib/shapes/highlight/HighlightShapeUtil.tsx +14 -11
  355. package/src/lib/shapes/image/ImageShapeUtil.tsx +7 -11
  356. package/src/lib/shapes/line/LineShapeTool.test.ts +41 -0
  357. package/src/lib/shapes/line/toolStates/Pointing.ts +12 -2
  358. package/src/lib/shapes/note/NoteShapeUtil.tsx +36 -51
  359. package/src/lib/shapes/note/noteCloning.test.ts +5 -5
  360. package/src/lib/shapes/note/noteHelpers.ts +1 -1
  361. package/src/lib/shapes/note/toolStates/Pointing.ts +40 -7
  362. package/src/lib/shapes/shared/PlainTextLabel.tsx +3 -3
  363. package/src/lib/shapes/shared/RichTextLabel.tsx +4 -3
  364. package/src/lib/shapes/shared/defaultStyleDefs.tsx +25 -3
  365. package/src/lib/shapes/shared/freehand/core.ts +547 -0
  366. package/src/lib/shapes/shared/freehand/fmt.ts +106 -0
  367. package/src/lib/shapes/shared/freehand/getStroke.ts +7 -7
  368. package/src/lib/shapes/shared/freehand/getStrokeOutlinePoints.ts +451 -139
  369. package/src/lib/shapes/shared/freehand/getStrokePoints.ts +33 -153
  370. package/src/lib/shapes/shared/freehand/svg.ts +72 -23
  371. package/src/lib/shapes/shared/freehand/svgInk.ts +281 -136
  372. package/src/lib/shapes/shared/freehand/types.ts +0 -1
  373. package/src/lib/shapes/shared/interpolate-props.ts +6 -2
  374. package/src/lib/shapes/text/toolStates/Pointing.ts +5 -0
  375. package/src/lib/tools/HandTool/HandTool.ts +17 -28
  376. package/src/lib/tools/HandTool/childStates/Dragging.ts +17 -1
  377. package/src/lib/tools/HandTool/childStates/OneFingerZooming.ts +79 -0
  378. package/src/lib/tools/SelectTool/childStates/Crop/Crop.ts +3 -1
  379. package/src/lib/tools/SelectTool/childStates/Crop/children/Idle.ts +2 -2
  380. package/src/lib/tools/SelectTool/childStates/Crop/children/PointingCrop.ts +15 -1
  381. package/src/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.ts +15 -1
  382. package/src/lib/tools/SelectTool/childStates/Idle.ts +17 -3
  383. package/src/lib/tools/SelectTool/childStates/PointingCanvas.ts +15 -1
  384. package/src/lib/tools/SelectTool/childStates/PointingHandle.ts +23 -1
  385. package/src/lib/tools/SelectTool/childStates/PointingResizeHandle.ts +21 -1
  386. package/src/lib/tools/SelectTool/childStates/PointingRotateHandle.ts +15 -1
  387. package/src/lib/tools/SelectTool/childStates/PointingSelection.ts +11 -2
  388. package/src/lib/tools/SelectTool/childStates/PointingShape.ts +26 -2
  389. package/src/lib/tools/SelectTool/childStates/Resizing.ts +137 -49
  390. package/src/lib/ui/TldrawUi.tsx +3 -3
  391. package/src/lib/ui/components/A11y.tsx +2 -0
  392. package/src/lib/ui/components/ContextMenu/DefaultContextMenu.tsx +32 -2
  393. package/src/lib/ui/components/ContextMenu/DefaultContextMenuContent.tsx +5 -6
  394. package/src/lib/ui/components/DefaultFollowingIndicator.tsx +2 -2
  395. package/src/lib/ui/components/Dialogs.tsx +20 -23
  396. package/src/lib/ui/components/HelperButtons/BackToContent.tsx +32 -4
  397. package/src/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.tsx +10 -0
  398. package/src/lib/ui/components/Minimap/DefaultMinimap.tsx +60 -74
  399. package/src/lib/ui/components/Minimap/MinimapManager.ts +35 -57
  400. package/src/lib/ui/components/SharePanel/DefaultPeopleMenuAvatar.tsx +2 -2
  401. package/src/lib/ui/components/SharePanel/DefaultPeopleMenuContent.tsx +2 -1
  402. package/src/lib/ui/components/SharePanel/DefaultPeopleMenuFacePile.tsx +2 -1
  403. package/src/lib/ui/components/SharePanel/DefaultPeopleMenuItem.tsx +3 -3
  404. package/src/lib/ui/components/StylePanel/StylePanelButtonPicker.tsx +5 -0
  405. package/src/lib/ui/components/StylePanel/StylePanelDropdownPicker.tsx +8 -1
  406. package/src/lib/ui/components/menu-items.tsx +9 -0
  407. package/src/lib/ui/components/primitives/TldrawUiDropdownMenu.tsx +3 -1
  408. package/src/lib/ui/components/primitives/TldrawUiIcon.tsx +15 -3
  409. package/src/lib/ui/components/primitives/TldrawUiInput.tsx +4 -0
  410. package/src/lib/ui/components/primitives/TldrawUiPopover.tsx +7 -0
  411. package/src/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.tsx +0 -2
  412. package/src/lib/ui/components/primitives/menus/TldrawUiMenuSubmenu.tsx +0 -1
  413. package/src/lib/ui/context/actions.tsx +88 -1
  414. package/src/lib/ui/context/asset-urls.tsx +9 -8
  415. package/src/lib/ui/context/events.tsx +2 -0
  416. package/src/lib/ui/hooks/useKeyboardShortcuts.ts +45 -7
  417. package/src/lib/ui/hooks/useTools.tsx +7 -1
  418. package/src/lib/ui/hooks/useTranslation/TLUiTranslationKey.ts +2 -0
  419. package/src/lib/ui/hooks/useTranslation/defaultTranslation.ts +2 -0
  420. package/src/lib/ui/version.ts +3 -3
  421. package/src/lib/ui.css +20 -9
  422. package/src/lib/utils/embeds/embeds.test.ts +14 -12
  423. package/src/lib/utils/embeds/embeds.ts +10 -4
  424. package/src/lib/utils/test-helpers.ts +3 -3
  425. package/src/lib/utils/text/richText.test.ts +36 -0
  426. package/src/lib/utils/text/richText.ts +9 -1
  427. package/src/test/ClickManager.test.ts +33 -28
  428. package/src/test/HandTool.test.ts +98 -34
  429. package/src/test/ImageShapeUtil.test.ts +88 -0
  430. package/src/test/SelectTool.test.ts +102 -1
  431. package/src/test/__snapshots__/drawing.test.ts.snap +2 -1
  432. package/src/test/attribution.test.ts +40 -29
  433. package/src/test/bookmark-shapes.test.ts +256 -28
  434. package/src/test/commands/__snapshots__/getSvgString.test.ts.snap +4 -6
  435. package/src/test/commands/clipboardCallbacks.test.ts +3 -1
  436. package/src/test/commands/getSvgString.test.ts +30 -0
  437. package/src/test/commands/penmode.test.ts +97 -1
  438. package/src/test/commands/setCamera.test.ts +109 -1
  439. package/src/test/cropping.test.ts +7 -0
  440. package/src/test/dragFromToolbar.test.ts +67 -0
  441. package/src/test/drawing.test.ts +48 -7
  442. package/src/test/frames.test.ts +72 -0
  443. package/src/test/freehand/corpus/presets.ts +71 -0
  444. package/src/test/freehand/corpus/real.ts +370 -0
  445. package/src/test/freehand/corpus/strokes.ts +50 -0
  446. package/src/test/freehand/svg.test.ts +20 -0
  447. package/src/test/freehand/wellformed.test.ts +30 -0
  448. package/src/test/long-press-create.test.ts +102 -0
  449. package/src/test/overlays/CollaboratorBrushOverlayUtil.test.ts +4 -4
  450. package/src/test/overlays/CollaboratorCursorOverlayUtil.test.ts +18 -18
  451. package/src/test/overlays/CollaboratorHintOverlayUtil.test.ts +7 -7
  452. package/src/test/overlays/CollaboratorScribbleOverlayUtil.test.ts +3 -3
  453. package/src/test/overlays/OverlayManager.test.ts +1 -1
  454. package/src/test/overlays/SelectionForegroundOverlayUtil.test.ts +58 -0
  455. package/src/test/overlays/ShapeHandleOverlayUtil.test.ts +2 -2
  456. package/src/test/overlays/ShapeIndicatorOverlayUtil.test.ts +36 -0
  457. package/src/test/pinch-dom.test.tsx +170 -0
  458. package/src/test/pinch.test.ts +139 -0
  459. package/src/test/resizing.test.ts +250 -0
  460. package/src/test/right-click-context-menu.test.ts +90 -0
  461. package/src/test/rightClickPanning.test.ts +11 -0
  462. package/src/test/selection-omnibus.test.ts +19 -6
  463. package/src/test/spatialIndex.test.ts +132 -0
  464. package/src/test/translating.test.ts +0 -6
  465. package/src/test/ui/ContextMenu.test.tsx +146 -3
  466. package/src/test/ui/Dialogs.test.tsx +256 -0
  467. package/src/test/ui/copyHoveredStyles.test.tsx +154 -0
  468. package/src/test/ui/keyboardShortcuts.test.tsx +266 -0
  469. package/tldraw.css +35 -12
  470. package/dist-cjs/lib/shapes/shared/freehand/setStrokePointRadii.js +0 -100
  471. package/dist-cjs/lib/shapes/shared/freehand/setStrokePointRadii.js.map +0 -7
  472. package/dist-esm/lib/shapes/shared/freehand/setStrokePointRadii.mjs +0 -80
  473. package/dist-esm/lib/shapes/shared/freehand/setStrokePointRadii.mjs.map +0 -7
  474. package/src/lib/shapes/shared/freehand/setStrokePointRadii.ts +0 -127
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/shapes/note/noteHelpers.ts"],
4
- "sourcesContent": ["import {\n\tEditor,\n\tIndexKey,\n\tTLNoteShape,\n\tTLShape,\n\tVec,\n\tcompact,\n\tcreateShapeId,\n\ttoRichText,\n} from '@tldraw/editor'\n\n/** @internal */\nexport const CLONE_HANDLE_MARGIN = 0\n/** @internal */\nexport const NOTE_ADJACENT_POSITION_SNAP_RADIUS = 10\n\nconst BASE_NOTE_POSITIONS = (editor: Editor, noteWidth: number, noteHeight: number) =>\n\t[\n\t\t[\n\t\t\t['a1' as IndexKey],\n\t\t\tnew Vec(noteWidth * 0.5, noteHeight * -0.5 - editor.options.adjacentShapeMargin),\n\t\t], // t\n\t\t[\n\t\t\t['a2' as IndexKey],\n\t\t\tnew Vec(noteWidth * 1.5 + editor.options.adjacentShapeMargin, noteHeight * 0.5),\n\t\t], // r\n\t\t[\n\t\t\t['a3' as IndexKey],\n\t\t\tnew Vec(noteWidth * 0.5, noteHeight * 1.5 + editor.options.adjacentShapeMargin),\n\t\t], // b\n\t\t[\n\t\t\t['a4' as IndexKey],\n\t\t\tnew Vec(noteWidth * -0.5 - editor.options.adjacentShapeMargin, noteHeight * 0.5),\n\t\t], // l\n\t] as const\n\nfunction getBaseAdjacentNotePositions(\n\teditor: Editor,\n\tscale: number,\n\tnoteWidth: number,\n\tnoteHeight: number\n) {\n\tif (scale === 1) return BASE_NOTE_POSITIONS(editor, noteWidth, noteHeight)\n\tconst w = noteWidth * scale\n\tconst h = noteHeight * scale\n\tconst m = editor.options.adjacentShapeMargin * scale\n\treturn [\n\t\t[['a1' as IndexKey], new Vec(w * 0.5, h * -0.5 - m)], // t\n\t\t[['a2' as IndexKey], new Vec(w * 1.5 + m, h * 0.5)], // r\n\t\t[['a3' as IndexKey], new Vec(w * 0.5, h * 1.5 + m)], // b\n\t\t[['a4' as IndexKey], new Vec(w * -0.5 - m, h * 0.5)], // l\n\t] as const\n}\n\n/** @internal */\nexport interface NoteAdjacentPositionsOpts {\n\tpagePoint: Vec\n\tpageRotation: number\n\tgrowY: number\n\textraHeight: number\n\tscale: number\n\tnoteWidth: number\n\tnoteHeight: number\n}\n\n/**\n * Get the adjacent positions for a particular note shape.\n *\n * @internal */\nexport function getNoteAdjacentPositions(\n\teditor: Editor,\n\topts: NoteAdjacentPositionsOpts\n): Record<IndexKey, Vec> {\n\tconst { pagePoint, pageRotation, growY, extraHeight, scale, noteWidth, noteHeight } = opts\n\treturn Object.fromEntries(\n\t\tgetBaseAdjacentNotePositions(editor, scale, noteWidth, noteHeight).map(([id, v], i) => {\n\t\t\tconst point = v.clone()\n\t\t\tif (i === 0 && extraHeight) {\n\t\t\t\t// apply top margin (the growY of the moving note shape)\n\t\t\t\tpoint.y -= extraHeight\n\t\t\t} else if (i === 2 && growY) {\n\t\t\t\t// apply bottom margin (the growY of this note shape)\n\t\t\t\tpoint.y += growY\n\t\t\t}\n\t\t\treturn [id, point.rot(pageRotation).add(pagePoint)]\n\t\t})\n\t)\n}\n\n/** @internal */\nexport interface AvailableNoteAdjacentPositionsOpts {\n\trotation: number\n\tscale: number\n\textraHeight: number\n\tnoteWidth: number\n\tnoteHeight: number\n}\n\n/**\n * Get all of the available note adjacent positions, excluding the selected shapes.\n *\n * @internal */\nexport function getAvailableNoteAdjacentPositions(\n\teditor: Editor,\n\topts: AvailableNoteAdjacentPositionsOpts\n) {\n\tconst { rotation, scale, extraHeight, noteWidth, noteHeight } = opts\n\tconst selectedShapeIds = new Set(editor.getSelectedShapeIds())\n\tconst minSize =\n\t\t(Math.max(noteWidth, noteHeight) + editor.options.adjacentShapeMargin + extraHeight) ** 2\n\tconst allCenters = new Map<TLNoteShape, Vec>()\n\tconst positions: (Vec | undefined)[] = []\n\n\t// Get all the positions that are adjacent to the selected note shapes\n\tfor (const shape of editor.getCurrentPageShapes()) {\n\t\tif (\n\t\t\t!editor.isShapeOfType(shape, 'note') ||\n\t\t\tscale !== shape.props.scale ||\n\t\t\tselectedShapeIds.has(shape.id)\n\t\t) {\n\t\t\tcontinue\n\t\t}\n\n\t\tconst transform = editor.getShapePageTransform(shape.id)!\n\n\t\t// If the note has a different rotation, we can't use its adjacent positions\n\t\tif (rotation !== transform.rotation()) continue\n\n\t\t// Save the unselected note shape's center\n\t\tallCenters.set(shape, editor.getShapePageBounds(shape)!.center)\n\n\t\t// And push its position to the positions array\n\t\tpositions.push(\n\t\t\t...Object.values(\n\t\t\t\tgetNoteAdjacentPositions(editor, {\n\t\t\t\t\tpagePoint: transform.point(),\n\t\t\t\t\tpageRotation: rotation,\n\t\t\t\t\tgrowY: shape.props.growY,\n\t\t\t\t\textraHeight,\n\t\t\t\t\tscale,\n\t\t\t\t\tnoteWidth,\n\t\t\t\t\tnoteHeight,\n\t\t\t\t})\n\t\t\t)\n\t\t)\n\t}\n\n\t// Remove positions that are inside of another note shape\n\tconst len = positions.length\n\tlet position: Vec | undefined\n\tfor (const [shape, center] of allCenters) {\n\t\tfor (let i = 0; i < len; i++) {\n\t\t\tposition = positions[i]\n\t\t\tif (!position) continue\n\t\t\tif (Vec.Dist2(center, position) > minSize) continue\n\t\t\tif (editor.isPointInShape(shape, position)) {\n\t\t\t\tpositions[i] = undefined\n\t\t\t}\n\t\t}\n\t}\n\n\treturn compact(positions)\n}\n\n/** @internal */\nexport interface NoteShapeForAdjacentPositionOpts {\n\tshape: TLNoteShape\n\tcenter: Vec\n\tpageRotation: number\n\tnoteWidth: number\n\tnoteHeight: number\n\tforceNew?: boolean\n}\n\n/**\n * For a particular adjacent note position, get the shape in that position or create a new one.\n *\n * @internal */\nexport function getNoteShapeForAdjacentPosition(\n\teditor: Editor,\n\topts: NoteShapeForAdjacentPositionOpts\n) {\n\tconst { shape, center, pageRotation, noteWidth, noteHeight, forceNew = false } = opts\n\t// There might already be a note in that position! If there is, we'll\n\t// select the next note and switch focus to it. If there's not, then\n\t// we'll create a new note in that position.\n\n\tlet nextNote: TLShape | undefined\n\n\t// Check the center of where a new note would be\n\t// Start from the top of the stack, and work our way down\n\tconst allShapesOnPage = editor.getCurrentPageShapesSorted()\n\n\tconst minDistance =\n\t\t(Math.max(noteWidth, noteHeight) + editor.options.adjacentShapeMargin ** 2) ** shape.props.scale\n\n\tfor (let i = allShapesOnPage.length - 1; i >= 0; i--) {\n\t\tconst otherNote = allShapesOnPage[i]\n\t\tif (otherNote.type === 'note' && otherNote.id !== shape.id) {\n\t\t\tconst otherBounds = editor.getShapePageBounds(otherNote)\n\t\t\tif (\n\t\t\t\totherBounds &&\n\t\t\t\tVec.Dist2(otherBounds.center, center) < minDistance &&\n\t\t\t\teditor.isPointInShape(otherNote, center)\n\t\t\t) {\n\t\t\t\tnextNote = otherNote\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\teditor.complete()\n\n\t// If we didn't find any in that position, then create a new one\n\tif (!nextNote || forceNew) {\n\t\teditor.markHistoryStoppingPoint('creating note shape')\n\t\tconst id = createShapeId()\n\n\t\t// We create it at the center first, so that it becomes\n\t\t// the child of whatever parent was at that center\n\t\teditor.createShape({\n\t\t\tid,\n\t\t\ttype: 'note',\n\t\t\tx: center.x,\n\t\t\ty: center.y,\n\t\t\trotation: pageRotation,\n\t\t\topacity: shape.opacity,\n\t\t\tprops: {\n\t\t\t\t// Use the props of the shape we're cloning\n\t\t\t\t...shape.props,\n\t\t\t\trichText: toRichText(''),\n\t\t\t\tgrowY: 0,\n\t\t\t\tfontSizeAdjustment: 1,\n\t\t\t\turl: '',\n\t\t\t\ttextFirstEditedBy: null,\n\t\t\t},\n\t\t})\n\n\t\t// Now we need to correct its location within its new parent\n\n\t\tconst createdShape = editor.getShape<TLNoteShape>(id)!\n\t\tif (!createdShape) return // may have hit max shapes\n\n\t\t// We need to put the page point in the same coordinate space as the newly created shape (i.e its parent's space)\n\t\tconst topLeft = editor.getPointInParentSpace(\n\t\t\tcreatedShape,\n\t\t\tVec.Sub(\n\t\t\t\tcenter,\n\t\t\t\tVec.Rot(new Vec(noteWidth / 2, noteHeight / 2).mul(createdShape.props.scale), pageRotation)\n\t\t\t)\n\t\t)\n\n\t\teditor.updateShape({\n\t\t\tid,\n\t\t\ttype: 'note',\n\t\t\tx: topLeft.x,\n\t\t\ty: topLeft.y,\n\t\t})\n\n\t\tnextNote = editor.getShape(id)!\n\t}\n\n\teditor.zoomToSelectionIfOffscreen(16, {\n\t\tanimation: {\n\t\t\tduration: editor.options.animationMediumMs,\n\t\t},\n\t\tinset: 0,\n\t})\n\treturn nextNote\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n\tEditor,\n\tIndexKey,\n\tTLNoteShape,\n\tTLShape,\n\tVec,\n\tcompact,\n\tcreateShapeId,\n\ttoRichText,\n} from '@tldraw/editor'\n\n/** @internal */\nexport const CLONE_HANDLE_MARGIN = 0\n/** @internal */\nexport const NOTE_ADJACENT_POSITION_SNAP_RADIUS = 10\n\nconst BASE_NOTE_POSITIONS = (editor: Editor, noteWidth: number, noteHeight: number) =>\n\t[\n\t\t[\n\t\t\t['a1' as IndexKey],\n\t\t\tnew Vec(noteWidth * 0.5, noteHeight * -0.5 - editor.options.adjacentShapeMargin),\n\t\t], // t\n\t\t[\n\t\t\t['a2' as IndexKey],\n\t\t\tnew Vec(noteWidth * 1.5 + editor.options.adjacentShapeMargin, noteHeight * 0.5),\n\t\t], // r\n\t\t[\n\t\t\t['a3' as IndexKey],\n\t\t\tnew Vec(noteWidth * 0.5, noteHeight * 1.5 + editor.options.adjacentShapeMargin),\n\t\t], // b\n\t\t[\n\t\t\t['a4' as IndexKey],\n\t\t\tnew Vec(noteWidth * -0.5 - editor.options.adjacentShapeMargin, noteHeight * 0.5),\n\t\t], // l\n\t] as const\n\nfunction getBaseAdjacentNotePositions(\n\teditor: Editor,\n\tscale: number,\n\tnoteWidth: number,\n\tnoteHeight: number\n) {\n\tif (scale === 1) return BASE_NOTE_POSITIONS(editor, noteWidth, noteHeight)\n\tconst w = noteWidth * scale\n\tconst h = noteHeight * scale\n\tconst m = editor.options.adjacentShapeMargin * scale\n\treturn [\n\t\t[['a1' as IndexKey], new Vec(w * 0.5, h * -0.5 - m)], // t\n\t\t[['a2' as IndexKey], new Vec(w * 1.5 + m, h * 0.5)], // r\n\t\t[['a3' as IndexKey], new Vec(w * 0.5, h * 1.5 + m)], // b\n\t\t[['a4' as IndexKey], new Vec(w * -0.5 - m, h * 0.5)], // l\n\t] as const\n}\n\n/** @internal */\nexport interface NoteAdjacentPositionsOpts {\n\tpagePoint: Vec\n\tpageRotation: number\n\tgrowY: number\n\textraHeight: number\n\tscale: number\n\tnoteWidth: number\n\tnoteHeight: number\n}\n\n/**\n * Get the adjacent positions for a particular note shape.\n *\n * @internal */\nexport function getNoteAdjacentPositions(\n\teditor: Editor,\n\topts: NoteAdjacentPositionsOpts\n): Record<IndexKey, Vec> {\n\tconst { pagePoint, pageRotation, growY, extraHeight, scale, noteWidth, noteHeight } = opts\n\treturn Object.fromEntries(\n\t\tgetBaseAdjacentNotePositions(editor, scale, noteWidth, noteHeight).map(([id, v], i) => {\n\t\t\tconst point = v.clone()\n\t\t\tif (i === 0 && extraHeight) {\n\t\t\t\t// apply top margin (the growY of the moving note shape)\n\t\t\t\tpoint.y -= extraHeight\n\t\t\t} else if (i === 2 && growY) {\n\t\t\t\t// apply bottom margin (the growY of this note shape)\n\t\t\t\tpoint.y += growY\n\t\t\t}\n\t\t\treturn [id, point.rot(pageRotation).add(pagePoint)]\n\t\t})\n\t)\n}\n\n/** @internal */\nexport interface AvailableNoteAdjacentPositionsOpts {\n\trotation: number\n\tscale: number\n\textraHeight: number\n\tnoteWidth: number\n\tnoteHeight: number\n}\n\n/**\n * Get all of the available note adjacent positions, excluding the selected shapes.\n *\n * @internal */\nexport function getAvailableNoteAdjacentPositions(\n\teditor: Editor,\n\topts: AvailableNoteAdjacentPositionsOpts\n) {\n\tconst { rotation, scale, extraHeight, noteWidth, noteHeight } = opts\n\tconst selectedShapeIds = new Set(editor.getSelectedShapeIds())\n\tconst minSize =\n\t\t(Math.max(noteWidth, noteHeight) + editor.options.adjacentShapeMargin + extraHeight) ** 2\n\tconst allCenters = new Map<TLNoteShape, Vec>()\n\tconst positions: (Vec | undefined)[] = []\n\n\t// Get all the positions that are adjacent to the selected note shapes\n\tfor (const shape of editor.getCurrentPageShapes()) {\n\t\tif (\n\t\t\t!editor.isShapeOfType(shape, 'note') ||\n\t\t\tscale !== shape.props.scale ||\n\t\t\tselectedShapeIds.has(shape.id)\n\t\t) {\n\t\t\tcontinue\n\t\t}\n\n\t\tconst transform = editor.getShapePageTransform(shape.id)!\n\n\t\t// If the note has a different rotation, we can't use its adjacent positions\n\t\tif (rotation !== transform.rotation()) continue\n\n\t\t// Save the unselected note shape's center\n\t\tallCenters.set(shape, editor.getShapePageBounds(shape)!.center)\n\n\t\t// And push its position to the positions array\n\t\tpositions.push(\n\t\t\t...Object.values(\n\t\t\t\tgetNoteAdjacentPositions(editor, {\n\t\t\t\t\tpagePoint: transform.point(),\n\t\t\t\t\tpageRotation: rotation,\n\t\t\t\t\tgrowY: shape.props.growY,\n\t\t\t\t\textraHeight,\n\t\t\t\t\tscale,\n\t\t\t\t\tnoteWidth,\n\t\t\t\t\tnoteHeight,\n\t\t\t\t})\n\t\t\t)\n\t\t)\n\t}\n\n\t// Remove positions that are inside of another note shape\n\tconst len = positions.length\n\tlet position: Vec | undefined\n\tfor (const [shape, center] of allCenters) {\n\t\tfor (let i = 0; i < len; i++) {\n\t\t\tposition = positions[i]\n\t\t\tif (!position) continue\n\t\t\tif (Vec.Dist2(center, position) > minSize) continue\n\t\t\tif (editor.isPointInShape(shape, position)) {\n\t\t\t\tpositions[i] = undefined\n\t\t\t}\n\t\t}\n\t}\n\n\treturn compact(positions)\n}\n\n/** @internal */\nexport interface NoteShapeForAdjacentPositionOpts {\n\tshape: TLNoteShape\n\tcenter: Vec\n\tpageRotation: number\n\tnoteWidth: number\n\tnoteHeight: number\n\tforceNew?: boolean\n}\n\n/**\n * For a particular adjacent note position, get the shape in that position or create a new one.\n *\n * @internal */\nexport function getNoteShapeForAdjacentPosition(\n\teditor: Editor,\n\topts: NoteShapeForAdjacentPositionOpts\n) {\n\tconst { shape, center, pageRotation, noteWidth, noteHeight, forceNew = false } = opts\n\t// There might already be a note in that position! If there is, we'll\n\t// select the next note and switch focus to it. If there's not, then\n\t// we'll create a new note in that position.\n\n\tlet nextNote: TLShape | undefined\n\n\t// Check the center of where a new note would be\n\t// Start from the top of the stack, and work our way down\n\tconst allShapesOnPage = editor.getCurrentPageShapesSorted()\n\n\tconst minDistance =\n\t\t(Math.max(noteWidth, noteHeight) + editor.options.adjacentShapeMargin ** 2) ** shape.props.scale\n\n\tfor (let i = allShapesOnPage.length - 1; i >= 0; i--) {\n\t\tconst otherNote = allShapesOnPage[i]\n\t\tif (otherNote.type === 'note' && otherNote.id !== shape.id) {\n\t\t\tconst otherBounds = editor.getShapePageBounds(otherNote)\n\t\t\tif (\n\t\t\t\totherBounds &&\n\t\t\t\tVec.Dist2(otherBounds.center, center) < minDistance &&\n\t\t\t\teditor.isPointInShape(otherNote, center)\n\t\t\t) {\n\t\t\t\tnextNote = otherNote\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\teditor.complete()\n\n\t// If we didn't find any in that position, then create a new one\n\tif (!nextNote || forceNew) {\n\t\teditor.markHistoryStoppingPoint('creating note shape')\n\t\tconst id = createShapeId()\n\n\t\t// We create it at the center first, so that it becomes\n\t\t// the child of whatever parent was at that center\n\t\teditor.createShape({\n\t\t\tid,\n\t\t\ttype: 'note',\n\t\t\tx: center.x,\n\t\t\ty: center.y,\n\t\t\trotation: pageRotation,\n\t\t\topacity: shape.opacity,\n\t\t\tprops: {\n\t\t\t\t// Use the props of the shape we're cloning\n\t\t\t\t...shape.props,\n\t\t\t\trichText: toRichText(''),\n\t\t\t\tgrowY: 0,\n\t\t\t\tfontSizeAdjustment: 1,\n\t\t\t\turl: '',\n\t\t\t\ttextLastEditedBy: null,\n\t\t\t},\n\t\t})\n\n\t\t// Now we need to correct its location within its new parent\n\n\t\tconst createdShape = editor.getShape<TLNoteShape>(id)!\n\t\tif (!createdShape) return // may have hit max shapes\n\n\t\t// We need to put the page point in the same coordinate space as the newly created shape (i.e its parent's space)\n\t\tconst topLeft = editor.getPointInParentSpace(\n\t\t\tcreatedShape,\n\t\t\tVec.Sub(\n\t\t\t\tcenter,\n\t\t\t\tVec.Rot(new Vec(noteWidth / 2, noteHeight / 2).mul(createdShape.props.scale), pageRotation)\n\t\t\t)\n\t\t)\n\n\t\teditor.updateShape({\n\t\t\tid,\n\t\t\ttype: 'note',\n\t\t\tx: topLeft.x,\n\t\t\ty: topLeft.y,\n\t\t})\n\n\t\tnextNote = editor.getShape(id)!\n\t}\n\n\teditor.zoomToSelectionIfOffscreen(16, {\n\t\tanimation: {\n\t\t\tduration: editor.options.animationMediumMs,\n\t\t},\n\t\tinset: 0,\n\t})\n\treturn nextNote\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -2,6 +2,7 @@ import {
2
2
  StateNode,
3
3
  Vec,
4
4
  createShapeId,
5
+ cancelShapeCreationOnLongPress,
5
6
  maybeSnapToGrid
6
7
  } from "@tldraw/editor";
7
8
  import { startEditingShapeWithRichText } from "../../../tools/SelectTool/selectHelpers.mjs";
@@ -16,32 +17,49 @@ class Pointing extends StateNode {
16
17
  info = {};
17
18
  markId = "";
18
19
  shape = {};
20
+ shapeId;
21
+ shapeCenter = new Vec();
22
+ hasCreatedShape = false;
19
23
  onEnter() {
20
24
  const { editor } = this;
21
- const id = createShapeId();
22
- this.markId = editor.markHistoryStoppingPoint(`creating_note:${id}`);
25
+ this.hasCreatedShape = false;
26
+ this.shapeId = createShapeId();
27
+ this.markId = editor.markHistoryStoppingPoint(`creating_note:${this.shapeId}`);
23
28
  const noteUtil = editor.getShapeUtil("note");
24
29
  const dv = getDisplayValues(noteUtil, { props: noteUtil.getDefaultProps() });
25
- const center = this.editor.inputs.getOriginPagePoint().clone();
30
+ const center = editor.inputs.getOriginPagePoint().clone();
26
31
  const offset = getNoteShapeAdjacentPositionOffset(
27
- this.editor,
32
+ editor,
28
33
  center,
29
- this.editor.getResizeScaleFactor(),
34
+ editor.getResizeScaleFactor(),
30
35
  dv.noteWidth,
31
36
  dv.noteHeight
32
37
  );
33
38
  if (offset) {
34
39
  center.sub(offset);
35
40
  }
36
- const shape = createNoteShape(this.editor, id, center);
41
+ this.shapeCenter = center;
42
+ if (!editor.getInstanceState().isCoarsePointer) {
43
+ this.ensureShapeCreated();
44
+ }
45
+ }
46
+ // Create the note now if it hasn't been created yet (idempotent). The deferred
47
+ // drag and release paths route through here; a max-shapes failure cancels the
48
+ // gesture, matching the original onEnter behaviour.
49
+ ensureShapeCreated() {
50
+ if (this.hasCreatedShape) return;
51
+ const shape = createNoteShape(this.editor, this.shapeId, this.shapeCenter);
37
52
  if (shape) {
38
53
  this.shape = shape;
54
+ this.hasCreatedShape = true;
39
55
  } else {
40
56
  this.cancel();
41
57
  }
42
58
  }
43
59
  onPointerMove(info) {
44
60
  if (this.editor.inputs.getIsDragging()) {
61
+ this.ensureShapeCreated();
62
+ if (!this.hasCreatedShape) return;
45
63
  this.editor.setCurrentTool("select.translating", {
46
64
  ...info,
47
65
  target: "shape",
@@ -58,6 +76,9 @@ class Pointing extends StateNode {
58
76
  onPointerUp() {
59
77
  this.complete();
60
78
  }
79
+ onLongPress() {
80
+ cancelShapeCreationOnLongPress(this.editor, () => this.cancel());
81
+ }
61
82
  onInterrupt() {
62
83
  this.cancel();
63
84
  }
@@ -68,6 +89,8 @@ class Pointing extends StateNode {
68
89
  this.cancel();
69
90
  }
70
91
  complete() {
92
+ this.ensureShapeCreated();
93
+ if (!this.hasCreatedShape) return;
71
94
  if (this.editor.getInstanceState().isToolLocked) {
72
95
  this.parent.transition("idle");
73
96
  } else {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/lib/shapes/note/toolStates/Pointing.ts"],
4
- "sourcesContent": ["import {\n\tEditor,\n\tStateNode,\n\tTLNoteShape,\n\tTLPointerEventInfo,\n\tTLShapeId,\n\tVec,\n\tcreateShapeId,\n\tmaybeSnapToGrid,\n} from '@tldraw/editor'\nimport { startEditingShapeWithRichText } from '../../../tools/SelectTool/selectHelpers'\nimport { getDisplayValues } from '../../shared/getDisplayValues'\nimport {\n\tNOTE_ADJACENT_POSITION_SNAP_RADIUS,\n\tgetAvailableNoteAdjacentPositions,\n} from '../noteHelpers'\nimport type { NoteShapeUtil } from '../NoteShapeUtil'\n\nexport class Pointing extends StateNode {\n\tstatic override id = 'pointing'\n\n\tdragged = false\n\n\tinfo = {} as TLPointerEventInfo\n\n\tmarkId = ''\n\n\tshape = {} as TLNoteShape\n\n\toverride onEnter() {\n\t\tconst { editor } = this\n\n\t\tconst id = createShapeId()\n\t\tthis.markId = editor.markHistoryStoppingPoint(`creating_note:${id}`)\n\n\t\t// Resolve note dimensions from the util's defaults\n\t\tconst noteUtil = editor.getShapeUtil('note') as NoteShapeUtil\n\t\tconst dv = getDisplayValues(noteUtil, { props: noteUtil.getDefaultProps() } as TLNoteShape)\n\n\t\t// Check for note pits; if the pointer is close to one, place the note centered on the pit\n\t\tconst center = this.editor.inputs.getOriginPagePoint().clone()\n\t\tconst offset = getNoteShapeAdjacentPositionOffset(\n\t\t\tthis.editor,\n\t\t\tcenter,\n\t\t\tthis.editor.getResizeScaleFactor(),\n\t\t\tdv.noteWidth,\n\t\t\tdv.noteHeight\n\t\t)\n\t\tif (offset) {\n\t\t\tcenter.sub(offset)\n\t\t}\n\n\t\t// Allow this to trigger the max shapes reached alert\n\t\tconst shape = createNoteShape(this.editor, id, center)\n\t\tif (shape) {\n\t\t\tthis.shape = shape\n\t\t} else {\n\t\t\tthis.cancel()\n\t\t}\n\t}\n\n\toverride onPointerMove(info: TLPointerEventInfo) {\n\t\tif (this.editor.inputs.getIsDragging()) {\n\t\t\tthis.editor.setCurrentTool('select.translating', {\n\t\t\t\t...info,\n\t\t\t\ttarget: 'shape',\n\t\t\t\tshape: this.shape,\n\t\t\t\tonInteractionEnd: 'note',\n\t\t\t\tisCreating: true,\n\t\t\t\tcreatingMarkId: this.markId,\n\t\t\t\tonCreate: () => {\n\t\t\t\t\tstartEditingShapeWithRichText(this.editor, this.shape.id)\n\t\t\t\t},\n\t\t\t})\n\t\t}\n\t}\n\n\toverride onPointerUp() {\n\t\tthis.complete()\n\t}\n\n\toverride onInterrupt() {\n\t\tthis.cancel()\n\t}\n\n\toverride onComplete() {\n\t\tthis.complete()\n\t}\n\n\toverride onCancel() {\n\t\tthis.cancel()\n\t}\n\n\tprivate complete() {\n\t\tif (this.editor.getInstanceState().isToolLocked) {\n\t\t\tthis.parent.transition('idle')\n\t\t} else {\n\t\t\tstartEditingShapeWithRichText(this.editor, this.shape.id, { info: this.info })\n\t\t}\n\t}\n\n\tprivate cancel() {\n\t\tthis.editor.bailToMark(this.markId)\n\t\tthis.parent.transition('idle', this.info)\n\t}\n}\n\nexport function getNoteShapeAdjacentPositionOffset(\n\teditor: Editor,\n\tcenter: Vec,\n\tscale: number,\n\tnoteWidth: number,\n\tnoteHeight: number\n) {\n\tlet min = NOTE_ADJACENT_POSITION_SNAP_RADIUS / editor.getZoomLevel() // in screen space\n\tlet offset: Vec | undefined\n\tfor (const pit of getAvailableNoteAdjacentPositions(editor, {\n\t\trotation: 0,\n\t\tscale,\n\t\textraHeight: 0,\n\t\tnoteWidth,\n\t\tnoteHeight,\n\t})) {\n\t\t// only check page rotations of zero\n\t\tconst deltaToPit = Vec.Sub(center, pit)\n\t\tconst dist = deltaToPit.len()\n\t\tif (dist < min) {\n\t\t\tmin = dist\n\t\t\toffset = deltaToPit\n\t\t}\n\t}\n\treturn offset\n}\n\nexport function createNoteShape(editor: Editor, id: TLShapeId, center: Vec) {\n\teditor.createShape({\n\t\tid,\n\t\ttype: 'note',\n\t\tx: center.x,\n\t\ty: center.y,\n\t\tprops: {\n\t\t\tscale: editor.getResizeScaleFactor(),\n\t\t},\n\t})\n\n\tconst shape = editor.getShape<TLNoteShape>(id)\n\t// Should never happen since we just checked, but just in case\n\tif (!shape) return\n\n\teditor.select(id)\n\tconst bounds = editor.getShapeGeometry(shape).bounds\n\tconst newPoint = maybeSnapToGrid(\n\t\tnew Vec(shape.x - bounds.width / 2, shape.y - bounds.height / 2),\n\t\teditor\n\t)\n\n\t// Center the text around the created point\n\teditor.updateShapes([\n\t\t{\n\t\t\tid,\n\t\t\ttype: 'note',\n\t\t\tx: newPoint.x,\n\t\t\ty: newPoint.y,\n\t\t},\n\t])\n\n\treturn editor.getShape<TLNoteShape>(id)\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n\tEditor,\n\tStateNode,\n\tTLNoteShape,\n\tTLPointerEventInfo,\n\tTLShapeId,\n\tVec,\n\tcreateShapeId,\n\tcancelShapeCreationOnLongPress,\n\tmaybeSnapToGrid,\n} from '@tldraw/editor'\nimport { startEditingShapeWithRichText } from '../../../tools/SelectTool/selectHelpers'\nimport { getDisplayValues } from '../../shared/getDisplayValues'\nimport {\n\tNOTE_ADJACENT_POSITION_SNAP_RADIUS,\n\tgetAvailableNoteAdjacentPositions,\n} from '../noteHelpers'\nimport type { NoteShapeUtil } from '../NoteShapeUtil'\n\nexport class Pointing extends StateNode {\n\tstatic override id = 'pointing'\n\n\tdragged = false\n\n\tinfo = {} as TLPointerEventInfo\n\n\tmarkId = ''\n\n\tshape = {} as TLNoteShape\n\n\tprivate shapeId!: TLShapeId\n\n\tprivate shapeCenter = new Vec()\n\n\tprivate hasCreatedShape = false\n\n\toverride onEnter() {\n\t\tconst { editor } = this\n\n\t\tthis.hasCreatedShape = false\n\t\tthis.shapeId = createShapeId()\n\t\tthis.markId = editor.markHistoryStoppingPoint(`creating_note:${this.shapeId}`)\n\n\t\t// Resolve note dimensions from the util's defaults\n\t\tconst noteUtil = editor.getShapeUtil('note') as NoteShapeUtil\n\t\tconst dv = getDisplayValues(noteUtil, { props: noteUtil.getDefaultProps() } as TLNoteShape)\n\n\t\t// Check for note pits; if the pointer is close to one, place the note centered on the pit\n\t\tconst center = editor.inputs.getOriginPagePoint().clone()\n\t\tconst offset = getNoteShapeAdjacentPositionOffset(\n\t\t\teditor,\n\t\t\tcenter,\n\t\t\teditor.getResizeScaleFactor(),\n\t\t\tdv.noteWidth,\n\t\t\tdv.noteHeight\n\t\t)\n\t\tif (offset) {\n\t\t\tcenter.sub(offset)\n\t\t}\n\t\tthis.shapeCenter = center\n\n\t\t// On a coarse pointer, defer creating the note until the gesture commits (a\n\t\t// drag or a release). The note is created on press, and a long-press cancels\n\t\t// the pending creation, so without deferral the note appears on press and\n\t\t// vanishes at the long-press mark \u2014 a visible flash. On a fine pointer there\n\t\t// is no long-press cancel, so create immediately to keep the press-and-drag feel.\n\t\tif (!editor.getInstanceState().isCoarsePointer) {\n\t\t\tthis.ensureShapeCreated()\n\t\t}\n\t}\n\n\t// Create the note now if it hasn't been created yet (idempotent). The deferred\n\t// drag and release paths route through here; a max-shapes failure cancels the\n\t// gesture, matching the original onEnter behaviour.\n\tprivate ensureShapeCreated() {\n\t\tif (this.hasCreatedShape) return\n\n\t\tconst shape = createNoteShape(this.editor, this.shapeId, this.shapeCenter)\n\t\tif (shape) {\n\t\t\tthis.shape = shape\n\t\t\tthis.hasCreatedShape = true\n\t\t} else {\n\t\t\tthis.cancel()\n\t\t}\n\t}\n\n\toverride onPointerMove(info: TLPointerEventInfo) {\n\t\tif (this.editor.inputs.getIsDragging()) {\n\t\t\tthis.ensureShapeCreated()\n\t\t\tif (!this.hasCreatedShape) return\n\t\t\tthis.editor.setCurrentTool('select.translating', {\n\t\t\t\t...info,\n\t\t\t\ttarget: 'shape',\n\t\t\t\tshape: this.shape,\n\t\t\t\tonInteractionEnd: 'note',\n\t\t\t\tisCreating: true,\n\t\t\t\tcreatingMarkId: this.markId,\n\t\t\t\tonCreate: () => {\n\t\t\t\t\tstartEditingShapeWithRichText(this.editor, this.shape.id)\n\t\t\t\t},\n\t\t\t})\n\t\t}\n\t}\n\n\toverride onPointerUp() {\n\t\tthis.complete()\n\t}\n\n\toverride onLongPress() {\n\t\tcancelShapeCreationOnLongPress(this.editor, () => this.cancel())\n\t}\n\n\toverride onInterrupt() {\n\t\tthis.cancel()\n\t}\n\n\toverride onComplete() {\n\t\tthis.complete()\n\t}\n\n\toverride onCancel() {\n\t\tthis.cancel()\n\t}\n\n\tprivate complete() {\n\t\tthis.ensureShapeCreated()\n\t\tif (!this.hasCreatedShape) return\n\t\tif (this.editor.getInstanceState().isToolLocked) {\n\t\t\tthis.parent.transition('idle')\n\t\t} else {\n\t\t\tstartEditingShapeWithRichText(this.editor, this.shape.id, { info: this.info })\n\t\t}\n\t}\n\n\tprivate cancel() {\n\t\tthis.editor.bailToMark(this.markId)\n\t\tthis.parent.transition('idle', this.info)\n\t}\n}\n\nexport function getNoteShapeAdjacentPositionOffset(\n\teditor: Editor,\n\tcenter: Vec,\n\tscale: number,\n\tnoteWidth: number,\n\tnoteHeight: number\n) {\n\tlet min = NOTE_ADJACENT_POSITION_SNAP_RADIUS / editor.getZoomLevel() // in screen space\n\tlet offset: Vec | undefined\n\tfor (const pit of getAvailableNoteAdjacentPositions(editor, {\n\t\trotation: 0,\n\t\tscale,\n\t\textraHeight: 0,\n\t\tnoteWidth,\n\t\tnoteHeight,\n\t})) {\n\t\t// only check page rotations of zero\n\t\tconst deltaToPit = Vec.Sub(center, pit)\n\t\tconst dist = deltaToPit.len()\n\t\tif (dist < min) {\n\t\t\tmin = dist\n\t\t\toffset = deltaToPit\n\t\t}\n\t}\n\treturn offset\n}\n\nexport function createNoteShape(editor: Editor, id: TLShapeId, center: Vec) {\n\teditor.createShape({\n\t\tid,\n\t\ttype: 'note',\n\t\tx: center.x,\n\t\ty: center.y,\n\t\tprops: {\n\t\t\tscale: editor.getResizeScaleFactor(),\n\t\t},\n\t})\n\n\tconst shape = editor.getShape<TLNoteShape>(id)\n\t// Should never happen since we just checked, but just in case\n\tif (!shape) return\n\n\teditor.select(id)\n\tconst bounds = editor.getShapeGeometry(shape).bounds\n\tconst newPoint = maybeSnapToGrid(\n\t\tnew Vec(shape.x - bounds.width / 2, shape.y - bounds.height / 2),\n\t\teditor\n\t)\n\n\t// Center the text around the created point\n\teditor.updateShapes([\n\t\t{\n\t\t\tid,\n\t\t\ttype: 'note',\n\t\t\tx: newPoint.x,\n\t\t\ty: newPoint.y,\n\t\t},\n\t])\n\n\treturn editor.getShape<TLNoteShape>(id)\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,4 +1,5 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { resolveLineHeightPx } from "@tldraw/editor";
2
3
  import classNames from "classnames";
3
4
  import React from "react";
4
5
  import { PlainTextArea } from "../text/PlainTextArea.mjs";
@@ -57,8 +58,8 @@ const PlainTextLabel = React.memo(function PlainTextLabel2({
57
58
  className: `${cssPrefix}-label__inner tl-text-content__wrapper`,
58
59
  style: {
59
60
  fontSize,
60
- lineHeight: lineHeight.toString(),
61
- minHeight: Math.floor(fontSize * lineHeight) + "px",
61
+ lineHeight: `${resolveLineHeightPx(fontSize, lineHeight)}px`,
62
+ minHeight: `${resolveLineHeightPx(fontSize, lineHeight)}px`,
62
63
  minWidth: Math.ceil(textWidth || 0),
63
64
  color: labelColor,
64
65
  width: textWidth ? Math.ceil(textWidth) : void 0,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/shapes/shared/PlainTextLabel.tsx"],
4
- "sourcesContent": ["import { Box, ExtractShapeByProps, TLShapeId } from '@tldraw/editor'\nimport classNames from 'classnames'\nimport React from 'react'\nimport { PlainTextArea } from '../text/PlainTextArea'\nimport { isLegacyAlign } from './legacyProps'\nimport { TextHelpers } from './TextHelpers'\nimport { useEditablePlainText } from './useEditablePlainText'\n\n/** @public */\nexport interface PlainTextLabelProps {\n\tshapeId: TLShapeId\n\ttype: ExtractShapeByProps<{ text: string }>['type']\n\tfontFamily: string\n\tfontSize: number\n\tlineHeight: number\n\ttextAlign: 'start' | 'center' | 'end'\n\tverticalAlign: 'start' | 'middle' | 'end'\n\twrap?: boolean\n\ttext?: string\n\tlabelColor: string\n\tbounds?: Box\n\tisSelected: boolean\n\tonKeyDown?(e: KeyboardEvent): void\n\tclassNamePrefix?: string\n\tstyle?: React.CSSProperties\n\ttextWidth?: number\n\ttextHeight?: number\n\tpadding?: number\n\tshowTextOutline?: boolean\n}\n\n/**\n * Renders a text label that can be used inside of shapes.\n * The component has the ability to be edited in place and furthermore\n * supports rich text editing.\n *\n * @public @react\n */\nexport const PlainTextLabel = React.memo(function PlainTextLabel({\n\tshapeId,\n\ttype,\n\ttext: plaintext,\n\tlabelColor,\n\tfontFamily,\n\tfontSize,\n\tlineHeight,\n\ttextAlign,\n\tverticalAlign,\n\twrap,\n\tisSelected,\n\tpadding = 0,\n\tonKeyDown: handleKeyDownCustom,\n\tclassNamePrefix,\n\tstyle,\n\ttextWidth,\n\ttextHeight,\n\tshowTextOutline = true,\n}: PlainTextLabelProps) {\n\tconst { rInput, isEmpty, isEditing, isReadyForEditing, ...editableTextRest } =\n\t\tuseEditablePlainText(shapeId, type, plaintext)\n\n\tconst finalPlainText = TextHelpers.normalizeTextForDom(plaintext || '')\n\tconst hasText = finalPlainText.length > 0\n\n\tconst legacyAlign = isLegacyAlign(textAlign)\n\n\tif (!isEditing && !hasText) {\n\t\treturn null\n\t}\n\n\t// TODO: probably combine tl-text and tl-arrow eventually\n\t// In case you're grepping for this, it breaks down as follows:\n\t// tl-text-label, tl-text-label__inner, tl-text-shape-label, tl-text\n\t// tl-arrow-label, tl-arrow-label__inner, tl-arrow\n\tconst cssPrefix = classNamePrefix || 'tl-text'\n\treturn (\n\t\t<div\n\t\t\tclassName={`${cssPrefix}-label tl-text-wrapper tl-plain-text-wrapper`}\n\t\t\taria-hidden={!isEditing}\n\t\t\tdata-hastext={!isEmpty}\n\t\t\tdata-isediting={isEditing}\n\t\t\tdata-is-ready-for-editing={isReadyForEditing}\n\t\t\tdata-textwrap={!!wrap}\n\t\t\tdata-isselected={isSelected}\n\t\t\tstyle={{\n\t\t\t\tfontFamily,\n\t\t\t\ttextAlign,\n\t\t\t\tjustifyContent:\n\t\t\t\t\ttextAlign === 'center' || legacyAlign\n\t\t\t\t\t\t? 'center'\n\t\t\t\t\t\t: textAlign === 'end'\n\t\t\t\t\t\t\t? 'flex-end'\n\t\t\t\t\t\t\t: 'flex-start',\n\t\t\t\talignItems:\n\t\t\t\t\tverticalAlign === 'middle'\n\t\t\t\t\t\t? 'center'\n\t\t\t\t\t\t: verticalAlign === 'end'\n\t\t\t\t\t\t\t? 'flex-end'\n\t\t\t\t\t\t\t: 'flex-start',\n\t\t\t\tpadding,\n\t\t\t\t...style,\n\t\t\t}}\n\t\t>\n\t\t\t<div\n\t\t\t\tclassName={`${cssPrefix}-label__inner tl-text-content__wrapper`}\n\t\t\t\tstyle={{\n\t\t\t\t\tfontSize,\n\t\t\t\t\tlineHeight: lineHeight.toString(),\n\t\t\t\t\tminHeight: Math.floor(fontSize * lineHeight) + 'px',\n\t\t\t\t\tminWidth: Math.ceil(textWidth || 0),\n\t\t\t\t\tcolor: labelColor,\n\t\t\t\t\twidth: textWidth ? Math.ceil(textWidth) : undefined,\n\t\t\t\t\theight: textHeight ? Math.ceil(textHeight) : undefined,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<div\n\t\t\t\t\tclassName={classNames(\n\t\t\t\t\t\t`${cssPrefix} tl-text tl-text-content`,\n\t\t\t\t\t\tshowTextOutline ? 'tl-text__outline' : 'tl-text__no-outline'\n\t\t\t\t\t)}\n\t\t\t\t\tdir=\"auto\"\n\t\t\t\t>\n\t\t\t\t\t{finalPlainText.split('\\n').map((lineOfText, index) => (\n\t\t\t\t\t\t<div key={index} dir=\"auto\">\n\t\t\t\t\t\t\t{lineOfText}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t))}\n\t\t\t\t</div>\n\t\t\t\t{(isReadyForEditing || isSelected) && (\n\t\t\t\t\t<PlainTextArea\n\t\t\t\t\t\t// Fudge the ref type because we're using forwardRef and it's not typed correctly.\n\t\t\t\t\t\tref={rInput as any}\n\t\t\t\t\t\ttext={plaintext}\n\t\t\t\t\t\tisEditing={isEditing}\n\t\t\t\t\t\tshapeId={shapeId}\n\t\t\t\t\t\t{...editableTextRest}\n\t\t\t\t\t\thandleKeyDown={handleKeyDownCustom ?? editableTextRest.handleKeyDown}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</div>\n\t)\n})\n"],
5
- "mappings": "AAuGG,SAoBG,KApBH;AAtGH,OAAO,gBAAgB;AACvB,OAAO,WAAW;AAClB,SAAS,qBAAqB;AAC9B,SAAS,qBAAqB;AAC9B,SAAS,mBAAmB;AAC5B,SAAS,4BAA4B;AAgC9B,MAAM,iBAAiB,MAAM,KAAK,SAASA,gBAAe;AAAA,EAChE;AAAA,EACA;AAAA,EACA,MAAM;AAAA,EACN;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,kBAAkB;AACnB,GAAwB;AACvB,QAAM,EAAE,QAAQ,SAAS,WAAW,mBAAmB,GAAG,iBAAiB,IAC1E,qBAAqB,SAAS,MAAM,SAAS;AAE9C,QAAM,iBAAiB,YAAY,oBAAoB,aAAa,EAAE;AACtE,QAAM,UAAU,eAAe,SAAS;AAExC,QAAM,cAAc,cAAc,SAAS;AAE3C,MAAI,CAAC,aAAa,CAAC,SAAS;AAC3B,WAAO;AAAA,EACR;AAMA,QAAM,YAAY,mBAAmB;AACrC,SACC;AAAA,IAAC;AAAA;AAAA,MACA,WAAW,GAAG,SAAS;AAAA,MACvB,eAAa,CAAC;AAAA,MACd,gBAAc,CAAC;AAAA,MACf,kBAAgB;AAAA,MAChB,6BAA2B;AAAA,MAC3B,iBAAe,CAAC,CAAC;AAAA,MACjB,mBAAiB;AAAA,MACjB,OAAO;AAAA,QACN;AAAA,QACA;AAAA,QACA,gBACC,cAAc,YAAY,cACvB,WACA,cAAc,QACb,aACA;AAAA,QACL,YACC,kBAAkB,WACf,WACA,kBAAkB,QACjB,aACA;AAAA,QACL;AAAA,QACA,GAAG;AAAA,MACJ;AAAA,MAEA;AAAA,QAAC;AAAA;AAAA,UACA,WAAW,GAAG,SAAS;AAAA,UACvB,OAAO;AAAA,YACN;AAAA,YACA,YAAY,WAAW,SAAS;AAAA,YAChC,WAAW,KAAK,MAAM,WAAW,UAAU,IAAI;AAAA,YAC/C,UAAU,KAAK,KAAK,aAAa,CAAC;AAAA,YAClC,OAAO;AAAA,YACP,OAAO,YAAY,KAAK,KAAK,SAAS,IAAI;AAAA,YAC1C,QAAQ,aAAa,KAAK,KAAK,UAAU,IAAI;AAAA,UAC9C;AAAA,UAEA;AAAA;AAAA,cAAC;AAAA;AAAA,gBACA,WAAW;AAAA,kBACV,GAAG,SAAS;AAAA,kBACZ,kBAAkB,qBAAqB;AAAA,gBACxC;AAAA,gBACA,KAAI;AAAA,gBAEH,yBAAe,MAAM,IAAI,EAAE,IAAI,CAAC,YAAY,UAC5C,oBAAC,SAAgB,KAAI,QACnB,wBADQ,KAEV,CACA;AAAA;AAAA,YACF;AAAA,aACE,qBAAqB,eACtB;AAAA,cAAC;AAAA;AAAA,gBAEA,KAAK;AAAA,gBACL,MAAM;AAAA,gBACN;AAAA,gBACA;AAAA,gBACC,GAAG;AAAA,gBACJ,eAAe,uBAAuB,iBAAiB;AAAA;AAAA,YACxD;AAAA;AAAA;AAAA,MAEF;AAAA;AAAA,EACD;AAEF,CAAC;",
4
+ "sourcesContent": ["import { Box, ExtractShapeByProps, TLShapeId, resolveLineHeightPx } from '@tldraw/editor'\nimport classNames from 'classnames'\nimport React from 'react'\nimport { PlainTextArea } from '../text/PlainTextArea'\nimport { isLegacyAlign } from './legacyProps'\nimport { TextHelpers } from './TextHelpers'\nimport { useEditablePlainText } from './useEditablePlainText'\n\n/** @public */\nexport interface PlainTextLabelProps {\n\tshapeId: TLShapeId\n\ttype: ExtractShapeByProps<{ text: string }>['type']\n\tfontFamily: string\n\tfontSize: number\n\tlineHeight: number\n\ttextAlign: 'start' | 'center' | 'end'\n\tverticalAlign: 'start' | 'middle' | 'end'\n\twrap?: boolean\n\ttext?: string\n\tlabelColor: string\n\tbounds?: Box\n\tisSelected: boolean\n\tonKeyDown?(e: KeyboardEvent): void\n\tclassNamePrefix?: string\n\tstyle?: React.CSSProperties\n\ttextWidth?: number\n\ttextHeight?: number\n\tpadding?: number\n\tshowTextOutline?: boolean\n}\n\n/**\n * Renders a text label that can be used inside of shapes.\n * The component has the ability to be edited in place and furthermore\n * supports rich text editing.\n *\n * @public @react\n */\nexport const PlainTextLabel = React.memo(function PlainTextLabel({\n\tshapeId,\n\ttype,\n\ttext: plaintext,\n\tlabelColor,\n\tfontFamily,\n\tfontSize,\n\tlineHeight,\n\ttextAlign,\n\tverticalAlign,\n\twrap,\n\tisSelected,\n\tpadding = 0,\n\tonKeyDown: handleKeyDownCustom,\n\tclassNamePrefix,\n\tstyle,\n\ttextWidth,\n\ttextHeight,\n\tshowTextOutline = true,\n}: PlainTextLabelProps) {\n\tconst { rInput, isEmpty, isEditing, isReadyForEditing, ...editableTextRest } =\n\t\tuseEditablePlainText(shapeId, type, plaintext)\n\n\tconst finalPlainText = TextHelpers.normalizeTextForDom(plaintext || '')\n\tconst hasText = finalPlainText.length > 0\n\n\tconst legacyAlign = isLegacyAlign(textAlign)\n\n\tif (!isEditing && !hasText) {\n\t\treturn null\n\t}\n\n\t// TODO: probably combine tl-text and tl-arrow eventually\n\t// In case you're grepping for this, it breaks down as follows:\n\t// tl-text-label, tl-text-label__inner, tl-text-shape-label, tl-text\n\t// tl-arrow-label, tl-arrow-label__inner, tl-arrow\n\tconst cssPrefix = classNamePrefix || 'tl-text'\n\treturn (\n\t\t<div\n\t\t\tclassName={`${cssPrefix}-label tl-text-wrapper tl-plain-text-wrapper`}\n\t\t\taria-hidden={!isEditing}\n\t\t\tdata-hastext={!isEmpty}\n\t\t\tdata-isediting={isEditing}\n\t\t\tdata-is-ready-for-editing={isReadyForEditing}\n\t\t\tdata-textwrap={!!wrap}\n\t\t\tdata-isselected={isSelected}\n\t\t\tstyle={{\n\t\t\t\tfontFamily,\n\t\t\t\ttextAlign,\n\t\t\t\tjustifyContent:\n\t\t\t\t\ttextAlign === 'center' || legacyAlign\n\t\t\t\t\t\t? 'center'\n\t\t\t\t\t\t: textAlign === 'end'\n\t\t\t\t\t\t\t? 'flex-end'\n\t\t\t\t\t\t\t: 'flex-start',\n\t\t\t\talignItems:\n\t\t\t\t\tverticalAlign === 'middle'\n\t\t\t\t\t\t? 'center'\n\t\t\t\t\t\t: verticalAlign === 'end'\n\t\t\t\t\t\t\t? 'flex-end'\n\t\t\t\t\t\t\t: 'flex-start',\n\t\t\t\tpadding,\n\t\t\t\t...style,\n\t\t\t}}\n\t\t>\n\t\t\t<div\n\t\t\t\tclassName={`${cssPrefix}-label__inner tl-text-content__wrapper`}\n\t\t\t\tstyle={{\n\t\t\t\t\tfontSize,\n\t\t\t\t\tlineHeight: `${resolveLineHeightPx(fontSize, lineHeight)}px`,\n\t\t\t\t\tminHeight: `${resolveLineHeightPx(fontSize, lineHeight)}px`,\n\t\t\t\t\tminWidth: Math.ceil(textWidth || 0),\n\t\t\t\t\tcolor: labelColor,\n\t\t\t\t\twidth: textWidth ? Math.ceil(textWidth) : undefined,\n\t\t\t\t\theight: textHeight ? Math.ceil(textHeight) : undefined,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<div\n\t\t\t\t\tclassName={classNames(\n\t\t\t\t\t\t`${cssPrefix} tl-text tl-text-content`,\n\t\t\t\t\t\tshowTextOutline ? 'tl-text__outline' : 'tl-text__no-outline'\n\t\t\t\t\t)}\n\t\t\t\t\tdir=\"auto\"\n\t\t\t\t>\n\t\t\t\t\t{finalPlainText.split('\\n').map((lineOfText, index) => (\n\t\t\t\t\t\t<div key={index} dir=\"auto\">\n\t\t\t\t\t\t\t{lineOfText}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t))}\n\t\t\t\t</div>\n\t\t\t\t{(isReadyForEditing || isSelected) && (\n\t\t\t\t\t<PlainTextArea\n\t\t\t\t\t\t// Fudge the ref type because we're using forwardRef and it's not typed correctly.\n\t\t\t\t\t\tref={rInput as any}\n\t\t\t\t\t\ttext={plaintext}\n\t\t\t\t\t\tisEditing={isEditing}\n\t\t\t\t\t\tshapeId={shapeId}\n\t\t\t\t\t\t{...editableTextRest}\n\t\t\t\t\t\thandleKeyDown={handleKeyDownCustom ?? editableTextRest.handleKeyDown}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</div>\n\t)\n})\n"],
5
+ "mappings": "AAuGG,SAoBG,KApBH;AAvGH,SAA8C,2BAA2B;AACzE,OAAO,gBAAgB;AACvB,OAAO,WAAW;AAClB,SAAS,qBAAqB;AAC9B,SAAS,qBAAqB;AAC9B,SAAS,mBAAmB;AAC5B,SAAS,4BAA4B;AAgC9B,MAAM,iBAAiB,MAAM,KAAK,SAASA,gBAAe;AAAA,EAChE;AAAA,EACA;AAAA,EACA,MAAM;AAAA,EACN;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,kBAAkB;AACnB,GAAwB;AACvB,QAAM,EAAE,QAAQ,SAAS,WAAW,mBAAmB,GAAG,iBAAiB,IAC1E,qBAAqB,SAAS,MAAM,SAAS;AAE9C,QAAM,iBAAiB,YAAY,oBAAoB,aAAa,EAAE;AACtE,QAAM,UAAU,eAAe,SAAS;AAExC,QAAM,cAAc,cAAc,SAAS;AAE3C,MAAI,CAAC,aAAa,CAAC,SAAS;AAC3B,WAAO;AAAA,EACR;AAMA,QAAM,YAAY,mBAAmB;AACrC,SACC;AAAA,IAAC;AAAA;AAAA,MACA,WAAW,GAAG,SAAS;AAAA,MACvB,eAAa,CAAC;AAAA,MACd,gBAAc,CAAC;AAAA,MACf,kBAAgB;AAAA,MAChB,6BAA2B;AAAA,MAC3B,iBAAe,CAAC,CAAC;AAAA,MACjB,mBAAiB;AAAA,MACjB,OAAO;AAAA,QACN;AAAA,QACA;AAAA,QACA,gBACC,cAAc,YAAY,cACvB,WACA,cAAc,QACb,aACA;AAAA,QACL,YACC,kBAAkB,WACf,WACA,kBAAkB,QACjB,aACA;AAAA,QACL;AAAA,QACA,GAAG;AAAA,MACJ;AAAA,MAEA;AAAA,QAAC;AAAA;AAAA,UACA,WAAW,GAAG,SAAS;AAAA,UACvB,OAAO;AAAA,YACN;AAAA,YACA,YAAY,GAAG,oBAAoB,UAAU,UAAU,CAAC;AAAA,YACxD,WAAW,GAAG,oBAAoB,UAAU,UAAU,CAAC;AAAA,YACvD,UAAU,KAAK,KAAK,aAAa,CAAC;AAAA,YAClC,OAAO;AAAA,YACP,OAAO,YAAY,KAAK,KAAK,SAAS,IAAI;AAAA,YAC1C,QAAQ,aAAa,KAAK,KAAK,UAAU,IAAI;AAAA,UAC9C;AAAA,UAEA;AAAA;AAAA,cAAC;AAAA;AAAA,gBACA,WAAW;AAAA,kBACV,GAAG,SAAS;AAAA,kBACZ,kBAAkB,qBAAqB;AAAA,gBACxC;AAAA,gBACA,KAAI;AAAA,gBAEH,yBAAe,MAAM,IAAI,EAAE,IAAI,CAAC,YAAY,UAC5C,oBAAC,SAAgB,KAAI,QACnB,wBADQ,KAEV,CACA;AAAA;AAAA,YACF;AAAA,aACE,qBAAqB,eACtB;AAAA,cAAC;AAAA;AAAA,gBAEA,KAAK;AAAA,gBACL,MAAM;AAAA,gBACN;AAAA,gBACA;AAAA,gBACC,GAAG;AAAA,gBACJ,eAAe,uBAAuB,iBAAiB;AAAA;AAAA,YACxD;AAAA;AAAA;AAAA,MAEF;AAAA;AAAA,EACD;AAEF,CAAC;",
6
6
  "names": ["PlainTextLabel"]
7
7
  }
@@ -2,6 +2,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import {
3
3
  openWindow,
4
4
  preventDefault,
5
+ resolveLineHeightPx,
5
6
  useEditor,
6
7
  useReactor,
7
8
  useValue
@@ -100,8 +101,8 @@ const RichTextLabel = React.memo(function RichTextLabel2({
100
101
  className: `${cssPrefix}-label__inner tl-text-content__wrapper`,
101
102
  style: {
102
103
  fontSize,
103
- lineHeight: lineHeight.toString(),
104
- minHeight: Math.floor(fontSize * lineHeight) + "px",
104
+ lineHeight: `${resolveLineHeightPx(fontSize, lineHeight)}px`,
105
+ minHeight: `${resolveLineHeightPx(fontSize, lineHeight)}px`,
105
106
  minWidth: Math.ceil(textWidth || 0),
106
107
  color: labelColor,
107
108
  width: textWidth ? Math.ceil(textWidth) : void 0,
@@ -166,7 +167,7 @@ function RichTextSVG({
166
167
  fontSize: `${fontSize}px`,
167
168
  wrap: wrap ? "wrap" : "nowrap",
168
169
  color: labelColor,
169
- lineHeight,
170
+ lineHeight: `${resolveLineHeightPx(fontSize, lineHeight)}px`,
170
171
  textAlign,
171
172
  width: "100%",
172
173
  wordWrap: "break-word",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/shapes/shared/RichTextLabel.tsx"],
4
- "sourcesContent": ["import {\n\tBox,\n\tExtractShapeByProps,\n\tTLEventInfo,\n\tTLRichText,\n\tTLShapeId,\n\topenWindow,\n\tpreventDefault,\n\tuseEditor,\n\tuseReactor,\n\tuseValue,\n} from '@tldraw/editor'\nimport classNames from 'classnames'\nimport React, { useMemo } from 'react'\nimport { renderHtmlFromRichText } from '../../utils/text/richText'\nimport { RichTextArea } from '../text/RichTextArea'\nimport { isLegacyAlign } from './legacyProps'\nimport { useEditableRichText } from './useEditableRichText'\n\n/** @public */\nexport interface RichTextLabelProps {\n\tshapeId: TLShapeId\n\ttype: ExtractShapeByProps<{ richText: TLRichText }>['type']\n\tfontFamily: string\n\tfontSize: number\n\tlineHeight: number\n\ttextAlign: 'start' | 'center' | 'end'\n\tverticalAlign: 'start' | 'middle' | 'end'\n\twrap?: boolean\n\trichText?: TLRichText\n\tlabelColor: string\n\tbounds?: Box\n\tisSelected: boolean\n\tonKeyDown?(e: KeyboardEvent): void\n\tclassNamePrefix?: string\n\tstyle?: React.CSSProperties\n\ttextWidth?: number\n\ttextHeight?: number\n\tpadding?: number\n\thasCustomTabBehavior?: boolean\n\tshowTextOutline?: boolean\n}\n\n/**\n * Renders a text label that can be used inside of shapes.\n * The component has the ability to be edited in place and furthermore\n * supports rich text editing.\n *\n * @public @react\n */\nexport const RichTextLabel = React.memo(function RichTextLabel({\n\tshapeId,\n\ttype,\n\trichText,\n\tlabelColor,\n\tfontFamily,\n\tfontSize,\n\tlineHeight,\n\ttextAlign,\n\tverticalAlign,\n\twrap,\n\tisSelected,\n\tpadding = 0,\n\tonKeyDown: handleKeyDownCustom,\n\tclassNamePrefix,\n\tstyle,\n\ttextWidth,\n\ttextHeight,\n\thasCustomTabBehavior,\n\tshowTextOutline = true,\n}: RichTextLabelProps) {\n\tconst editor = useEditor()\n\tconst isDragging = React.useRef(false)\n\tconst legacyAlign = isLegacyAlign(textAlign)\n\tconst { rInput, isEmpty, isEditing, isReadyForEditing, ...editableTextRest } =\n\t\tuseEditableRichText(shapeId, type, richText)\n\n\tconst html = useMemo(() => {\n\t\tif (richText) {\n\t\t\treturn renderHtmlFromRichText(editor, richText)\n\t\t}\n\t\treturn undefined\n\t}, [editor, richText])\n\n\tconst selectToolActive = useValue(\n\t\t'isSelectToolActive',\n\t\t() => editor.getCurrentToolId() === 'select',\n\t\t[editor]\n\t)\n\n\tuseReactor(\n\t\t'isDragging',\n\t\t() => {\n\t\t\teditor.getInstanceState()\n\t\t\tisDragging.current = editor.inputs.getIsDragging()\n\t\t},\n\t\t[editor]\n\t)\n\n\tconst handlePointerDown = (e: React.MouseEvent<HTMLDivElement>) => {\n\t\tconst HTMLElementCtor = editor.getContainerWindow().HTMLElement\n\t\tif (\n\t\t\te.target instanceof HTMLElementCtor &&\n\t\t\t(e.target.tagName === 'A' || e.target.closest('a'))\n\t\t) {\n\t\t\t// This mousedown prevent default is to let dragging when over a link work.\n\t\t\tpreventDefault(e)\n\n\t\t\tif (!selectToolActive) return\n\t\t\tconst link = e.target.closest('a')?.getAttribute('href') ?? ''\n\t\t\t// We don't get the mouseup event later because we preventDefault\n\t\t\t// so we have to do it manually.\n\t\t\tconst handlePointerUp = (e: TLEventInfo) => {\n\t\t\t\tif (e.name !== 'pointer_up' || !link) return\n\n\t\t\t\tif (!isDragging.current) {\n\t\t\t\t\topenWindow(link, '_blank', false)\n\t\t\t\t}\n\t\t\t\teditor.off('event', handlePointerUp)\n\t\t\t}\n\t\t\teditor.on('event', handlePointerUp)\n\t\t}\n\t}\n\n\t// Should be guarded higher up so that this doesn't render... but repeated here. This should never be true.\n\tif (!isEditing && isEmpty) return null\n\n\t// TODO: probably combine tl-text and tl-arrow eventually\n\tconst cssPrefix = classNamePrefix || 'tl-text'\n\treturn (\n\t\t<div\n\t\t\tclassName={classNames(\n\t\t\t\t`${cssPrefix}-label tl-text-wrapper tl-rich-text-wrapper`,\n\t\t\t\tshowTextOutline ? 'tl-text__outline' : 'tl-text__no-outline'\n\t\t\t)}\n\t\t\taria-hidden={!isEditing}\n\t\t\tdata-hastext={!isEmpty}\n\t\t\tdata-isediting={isEditing}\n\t\t\tdata-textwrap={!!wrap}\n\t\t\tdata-isselected={isSelected}\n\t\t\tstyle={{\n\t\t\t\tfontFamily,\n\t\t\t\ttextAlign,\n\t\t\t\tjustifyContent:\n\t\t\t\t\ttextAlign === 'center' || legacyAlign\n\t\t\t\t\t\t? 'center'\n\t\t\t\t\t\t: textAlign === 'end'\n\t\t\t\t\t\t\t? 'flex-end'\n\t\t\t\t\t\t\t: 'flex-start',\n\t\t\t\talignItems:\n\t\t\t\t\tverticalAlign === 'middle'\n\t\t\t\t\t\t? 'center'\n\t\t\t\t\t\t: verticalAlign === 'end'\n\t\t\t\t\t\t\t? 'flex-end'\n\t\t\t\t\t\t\t: 'flex-start',\n\t\t\t\tpadding,\n\t\t\t\t...style,\n\t\t\t}}\n\t\t>\n\t\t\t<div\n\t\t\t\tclassName={`${cssPrefix}-label__inner tl-text-content__wrapper`}\n\t\t\t\tstyle={{\n\t\t\t\t\tfontSize,\n\t\t\t\t\tlineHeight: lineHeight.toString(),\n\t\t\t\t\tminHeight: Math.floor(fontSize * lineHeight) + 'px',\n\t\t\t\t\tminWidth: Math.ceil(textWidth || 0),\n\t\t\t\t\tcolor: labelColor,\n\t\t\t\t\twidth: textWidth ? Math.ceil(textWidth) : undefined,\n\t\t\t\t\theight: textHeight ? Math.ceil(textHeight) : undefined,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<div className={`${cssPrefix} tl-text tl-text-content`} dir=\"auto\">\n\t\t\t\t\t{richText && (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclassName=\"tl-rich-text\"\n\t\t\t\t\t\t\tdata-is-select-tool-active={selectToolActive}\n\t\t\t\t\t\t\t// todo: see if I can abuse this\n\t\t\t\t\t\t\tdangerouslySetInnerHTML={{ __html: html || '' }}\n\t\t\t\t\t\t\tonPointerDown={handlePointerDown}\n\t\t\t\t\t\t\tdata-is-ready-for-editing={isReadyForEditing}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t\t{(isReadyForEditing || isSelected) && (\n\t\t\t\t\t<RichTextArea\n\t\t\t\t\t\t// Fudge the ref type because we're using forwardRef and it's not typed correctly.\n\t\t\t\t\t\tref={rInput as any}\n\t\t\t\t\t\trichText={richText}\n\t\t\t\t\t\tisEditing={isEditing}\n\t\t\t\t\t\tshapeId={shapeId}\n\t\t\t\t\t\t{...editableTextRest}\n\t\t\t\t\t\thasCustomTabBehavior={hasCustomTabBehavior}\n\t\t\t\t\t\thandleKeyDown={handleKeyDownCustom ?? editableTextRest.handleKeyDown}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</div>\n\t)\n})\n\n/** @public */\nexport interface RichTextSVGProps {\n\tbounds: Box\n\trichText: TLRichText\n\tfontSize: number\n\tfontFamily: string\n\tlineHeight: number\n\ttextAlign: 'start' | 'center' | 'end'\n\tverticalAlign: 'start' | 'middle' | 'end'\n\twrap?: boolean\n\tlabelColor: string\n\tpadding: number\n\tshowTextOutline?: boolean\n}\n\n/**\n * Renders a rich text string as SVG given bounds and text properties.\n *\n * @public @react\n */\nexport function RichTextSVG({\n\tbounds,\n\trichText,\n\tfontSize,\n\tfontFamily,\n\tlineHeight,\n\ttextAlign,\n\tverticalAlign,\n\twrap,\n\tlabelColor,\n\tpadding,\n\tshowTextOutline = true,\n}: RichTextSVGProps) {\n\tconst editor = useEditor()\n\tconst html = renderHtmlFromRichText(editor, richText)\n\tconst legacyAlign = isLegacyAlign(textAlign)\n\tconst justifyContent =\n\t\ttextAlign === 'center' || legacyAlign\n\t\t\t? ('center' as const)\n\t\t\t: textAlign === 'start'\n\t\t\t\t? ('flex-start' as const)\n\t\t\t\t: ('flex-end' as const)\n\tconst alignItems =\n\t\tverticalAlign === 'middle' ? 'center' : verticalAlign === 'start' ? 'flex-start' : 'flex-end'\n\tconst wrapperStyle = {\n\t\tdisplay: 'flex',\n\t\tfontFamily,\n\t\theight: `100%`,\n\t\tjustifyContent,\n\t\talignItems,\n\t\tpadding: `${padding}px`,\n\t}\n\tconst style = {\n\t\tfontSize: `${fontSize}px`,\n\t\twrap: wrap ? 'wrap' : 'nowrap',\n\t\tcolor: labelColor,\n\t\tlineHeight,\n\t\ttextAlign,\n\t\twidth: '100%',\n\t\twordWrap: 'break-word' as const,\n\t\toverflowWrap: 'break-word' as const,\n\t\twhiteSpace: 'pre-wrap',\n\t\ttextShadow: showTextOutline ? 'var(--tl-text-outline)' : 'none',\n\t\ttabSize: 'var(--tl-tab-size, 2)',\n\t}\n\n\treturn (\n\t\t<foreignObject\n\t\t\tx={bounds.minX}\n\t\t\ty={bounds.minY}\n\t\t\twidth={bounds.w}\n\t\t\theight={bounds.h}\n\t\t\tclassName={classNames(\n\t\t\t\t'tl-export-embed-styles tl-rich-text tl-rich-text-svg',\n\t\t\t\tshowTextOutline ? 'tl-text__outline' : 'tl-text__no-outline'\n\t\t\t)}\n\t\t>\n\t\t\t<div style={wrapperStyle}>\n\t\t\t\t<div dangerouslySetInnerHTML={{ __html: html }} style={style} />\n\t\t\t</div>\n\t\t</foreignObject>\n\t)\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n\tBox,\n\tExtractShapeByProps,\n\tTLEventInfo,\n\tTLRichText,\n\tTLShapeId,\n\topenWindow,\n\tpreventDefault,\n\tresolveLineHeightPx,\n\tuseEditor,\n\tuseReactor,\n\tuseValue,\n} from '@tldraw/editor'\nimport classNames from 'classnames'\nimport React, { useMemo } from 'react'\nimport { renderHtmlFromRichText } from '../../utils/text/richText'\nimport { RichTextArea } from '../text/RichTextArea'\nimport { isLegacyAlign } from './legacyProps'\nimport { useEditableRichText } from './useEditableRichText'\n\n/** @public */\nexport interface RichTextLabelProps {\n\tshapeId: TLShapeId\n\ttype: ExtractShapeByProps<{ richText: TLRichText }>['type']\n\tfontFamily: string\n\tfontSize: number\n\tlineHeight: number\n\ttextAlign: 'start' | 'center' | 'end'\n\tverticalAlign: 'start' | 'middle' | 'end'\n\twrap?: boolean\n\trichText?: TLRichText\n\tlabelColor: string\n\tbounds?: Box\n\tisSelected: boolean\n\tonKeyDown?(e: KeyboardEvent): void\n\tclassNamePrefix?: string\n\tstyle?: React.CSSProperties\n\ttextWidth?: number\n\ttextHeight?: number\n\tpadding?: number\n\thasCustomTabBehavior?: boolean\n\tshowTextOutline?: boolean\n}\n\n/**\n * Renders a text label that can be used inside of shapes.\n * The component has the ability to be edited in place and furthermore\n * supports rich text editing.\n *\n * @public @react\n */\nexport const RichTextLabel = React.memo(function RichTextLabel({\n\tshapeId,\n\ttype,\n\trichText,\n\tlabelColor,\n\tfontFamily,\n\tfontSize,\n\tlineHeight,\n\ttextAlign,\n\tverticalAlign,\n\twrap,\n\tisSelected,\n\tpadding = 0,\n\tonKeyDown: handleKeyDownCustom,\n\tclassNamePrefix,\n\tstyle,\n\ttextWidth,\n\ttextHeight,\n\thasCustomTabBehavior,\n\tshowTextOutline = true,\n}: RichTextLabelProps) {\n\tconst editor = useEditor()\n\tconst isDragging = React.useRef(false)\n\tconst legacyAlign = isLegacyAlign(textAlign)\n\tconst { rInput, isEmpty, isEditing, isReadyForEditing, ...editableTextRest } =\n\t\tuseEditableRichText(shapeId, type, richText)\n\n\tconst html = useMemo(() => {\n\t\tif (richText) {\n\t\t\treturn renderHtmlFromRichText(editor, richText)\n\t\t}\n\t\treturn undefined\n\t}, [editor, richText])\n\n\tconst selectToolActive = useValue(\n\t\t'isSelectToolActive',\n\t\t() => editor.getCurrentToolId() === 'select',\n\t\t[editor]\n\t)\n\n\tuseReactor(\n\t\t'isDragging',\n\t\t() => {\n\t\t\teditor.getInstanceState()\n\t\t\tisDragging.current = editor.inputs.getIsDragging()\n\t\t},\n\t\t[editor]\n\t)\n\n\tconst handlePointerDown = (e: React.MouseEvent<HTMLDivElement>) => {\n\t\tconst HTMLElementCtor = editor.getContainerWindow().HTMLElement\n\t\tif (\n\t\t\te.target instanceof HTMLElementCtor &&\n\t\t\t(e.target.tagName === 'A' || e.target.closest('a'))\n\t\t) {\n\t\t\t// This mousedown prevent default is to let dragging when over a link work.\n\t\t\tpreventDefault(e)\n\n\t\t\tif (!selectToolActive) return\n\t\t\tconst link = e.target.closest('a')?.getAttribute('href') ?? ''\n\t\t\t// We don't get the mouseup event later because we preventDefault\n\t\t\t// so we have to do it manually.\n\t\t\tconst handlePointerUp = (e: TLEventInfo) => {\n\t\t\t\tif (e.name !== 'pointer_up' || !link) return\n\n\t\t\t\tif (!isDragging.current) {\n\t\t\t\t\topenWindow(link, '_blank', false)\n\t\t\t\t}\n\t\t\t\teditor.off('event', handlePointerUp)\n\t\t\t}\n\t\t\teditor.on('event', handlePointerUp)\n\t\t}\n\t}\n\n\t// Should be guarded higher up so that this doesn't render... but repeated here. This should never be true.\n\tif (!isEditing && isEmpty) return null\n\n\t// TODO: probably combine tl-text and tl-arrow eventually\n\tconst cssPrefix = classNamePrefix || 'tl-text'\n\treturn (\n\t\t<div\n\t\t\tclassName={classNames(\n\t\t\t\t`${cssPrefix}-label tl-text-wrapper tl-rich-text-wrapper`,\n\t\t\t\tshowTextOutline ? 'tl-text__outline' : 'tl-text__no-outline'\n\t\t\t)}\n\t\t\taria-hidden={!isEditing}\n\t\t\tdata-hastext={!isEmpty}\n\t\t\tdata-isediting={isEditing}\n\t\t\tdata-textwrap={!!wrap}\n\t\t\tdata-isselected={isSelected}\n\t\t\tstyle={{\n\t\t\t\tfontFamily,\n\t\t\t\ttextAlign,\n\t\t\t\tjustifyContent:\n\t\t\t\t\ttextAlign === 'center' || legacyAlign\n\t\t\t\t\t\t? 'center'\n\t\t\t\t\t\t: textAlign === 'end'\n\t\t\t\t\t\t\t? 'flex-end'\n\t\t\t\t\t\t\t: 'flex-start',\n\t\t\t\talignItems:\n\t\t\t\t\tverticalAlign === 'middle'\n\t\t\t\t\t\t? 'center'\n\t\t\t\t\t\t: verticalAlign === 'end'\n\t\t\t\t\t\t\t? 'flex-end'\n\t\t\t\t\t\t\t: 'flex-start',\n\t\t\t\tpadding,\n\t\t\t\t...style,\n\t\t\t}}\n\t\t>\n\t\t\t<div\n\t\t\t\tclassName={`${cssPrefix}-label__inner tl-text-content__wrapper`}\n\t\t\t\tstyle={{\n\t\t\t\t\tfontSize,\n\t\t\t\t\tlineHeight: `${resolveLineHeightPx(fontSize, lineHeight)}px`,\n\t\t\t\t\tminHeight: `${resolveLineHeightPx(fontSize, lineHeight)}px`,\n\t\t\t\t\tminWidth: Math.ceil(textWidth || 0),\n\t\t\t\t\tcolor: labelColor,\n\t\t\t\t\twidth: textWidth ? Math.ceil(textWidth) : undefined,\n\t\t\t\t\theight: textHeight ? Math.ceil(textHeight) : undefined,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<div className={`${cssPrefix} tl-text tl-text-content`} dir=\"auto\">\n\t\t\t\t\t{richText && (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclassName=\"tl-rich-text\"\n\t\t\t\t\t\t\tdata-is-select-tool-active={selectToolActive}\n\t\t\t\t\t\t\t// todo: see if I can abuse this\n\t\t\t\t\t\t\tdangerouslySetInnerHTML={{ __html: html || '' }}\n\t\t\t\t\t\t\tonPointerDown={handlePointerDown}\n\t\t\t\t\t\t\tdata-is-ready-for-editing={isReadyForEditing}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t\t{(isReadyForEditing || isSelected) && (\n\t\t\t\t\t<RichTextArea\n\t\t\t\t\t\t// Fudge the ref type because we're using forwardRef and it's not typed correctly.\n\t\t\t\t\t\tref={rInput as any}\n\t\t\t\t\t\trichText={richText}\n\t\t\t\t\t\tisEditing={isEditing}\n\t\t\t\t\t\tshapeId={shapeId}\n\t\t\t\t\t\t{...editableTextRest}\n\t\t\t\t\t\thasCustomTabBehavior={hasCustomTabBehavior}\n\t\t\t\t\t\thandleKeyDown={handleKeyDownCustom ?? editableTextRest.handleKeyDown}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</div>\n\t)\n})\n\n/** @public */\nexport interface RichTextSVGProps {\n\tbounds: Box\n\trichText: TLRichText\n\tfontSize: number\n\tfontFamily: string\n\tlineHeight: number\n\ttextAlign: 'start' | 'center' | 'end'\n\tverticalAlign: 'start' | 'middle' | 'end'\n\twrap?: boolean\n\tlabelColor: string\n\tpadding: number\n\tshowTextOutline?: boolean\n}\n\n/**\n * Renders a rich text string as SVG given bounds and text properties.\n *\n * @public @react\n */\nexport function RichTextSVG({\n\tbounds,\n\trichText,\n\tfontSize,\n\tfontFamily,\n\tlineHeight,\n\ttextAlign,\n\tverticalAlign,\n\twrap,\n\tlabelColor,\n\tpadding,\n\tshowTextOutline = true,\n}: RichTextSVGProps) {\n\tconst editor = useEditor()\n\tconst html = renderHtmlFromRichText(editor, richText)\n\tconst legacyAlign = isLegacyAlign(textAlign)\n\tconst justifyContent =\n\t\ttextAlign === 'center' || legacyAlign\n\t\t\t? ('center' as const)\n\t\t\t: textAlign === 'start'\n\t\t\t\t? ('flex-start' as const)\n\t\t\t\t: ('flex-end' as const)\n\tconst alignItems =\n\t\tverticalAlign === 'middle' ? 'center' : verticalAlign === 'start' ? 'flex-start' : 'flex-end'\n\tconst wrapperStyle = {\n\t\tdisplay: 'flex',\n\t\tfontFamily,\n\t\theight: `100%`,\n\t\tjustifyContent,\n\t\talignItems,\n\t\tpadding: `${padding}px`,\n\t}\n\tconst style = {\n\t\tfontSize: `${fontSize}px`,\n\t\twrap: wrap ? 'wrap' : 'nowrap',\n\t\tcolor: labelColor,\n\t\tlineHeight: `${resolveLineHeightPx(fontSize, lineHeight)}px`,\n\t\ttextAlign,\n\t\twidth: '100%',\n\t\twordWrap: 'break-word' as const,\n\t\toverflowWrap: 'break-word' as const,\n\t\twhiteSpace: 'pre-wrap',\n\t\ttextShadow: showTextOutline ? 'var(--tl-text-outline)' : 'none',\n\t\ttabSize: 'var(--tl-tab-size, 2)',\n\t}\n\n\treturn (\n\t\t<foreignObject\n\t\t\tx={bounds.minX}\n\t\t\ty={bounds.minY}\n\t\t\twidth={bounds.w}\n\t\t\theight={bounds.h}\n\t\t\tclassName={classNames(\n\t\t\t\t'tl-export-embed-styles tl-rich-text tl-rich-text-svg',\n\t\t\t\tshowTextOutline ? 'tl-text__outline' : 'tl-text__no-outline'\n\t\t\t)}\n\t\t>\n\t\t\t<div style={wrapperStyle}>\n\t\t\t\t<div dangerouslySetInnerHTML={{ __html: html }} style={style} />\n\t\t\t</div>\n\t\t</foreignObject>\n\t)\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["RichTextLabel", "e"]
7
7
  }
@@ -64,7 +64,10 @@ const generateImage = (dpr, currentZoom, solid) => {
64
64
  canvasEl.width = size;
65
65
  canvasEl.height = size;
66
66
  const ctx = canvasEl.getContext("2d");
67
- if (!ctx) return;
67
+ if (!ctx) {
68
+ reject();
69
+ return;
70
+ }
68
71
  ctx.fillStyle = solid;
69
72
  ctx.fillRect(0, 0, size, size);
70
73
  ctx.globalCompositeOperation = "destination-out";
@@ -89,6 +92,17 @@ const generateImage = (dpr, currentZoom, solid) => {
89
92
  });
90
93
  });
91
94
  };
95
+ const patternImageBlobCache = /* @__PURE__ */ new Map();
96
+ function getPatternImageBlob(dpr, zoom, solid) {
97
+ const key = `${dpr}_${zoom}_${solid}`;
98
+ let blob = patternImageBlobCache.get(key);
99
+ if (!blob) {
100
+ blob = generateImage(dpr, zoom, solid);
101
+ blob.catch(() => patternImageBlobCache.delete(key));
102
+ patternImageBlobCache.set(key, blob);
103
+ }
104
+ return blob;
105
+ }
92
106
  const canvasBlob = (size, fn) => {
93
107
  const canvas = getGlobalDocument().createElement("canvas");
94
108
  canvas.width = size[0];
@@ -171,12 +185,12 @@ function usePattern() {
171
185
  const darkSolid = definition.colors.dark.solid;
172
186
  const promise = Promise.all(
173
187
  getPatternLodsToGenerate(maxEffectiveZoom).flatMap((zoom) => [
174
- generateImage(dpr, zoom, lightSolid).then((blob) => ({
188
+ getPatternImageBlob(dpr, zoom, lightSolid).then((blob) => ({
175
189
  zoom,
176
190
  theme: "light",
177
191
  url: URL.createObjectURL(blob)
178
192
  })),
179
- generateImage(dpr, zoom, darkSolid).then((blob) => ({
193
+ getPatternImageBlob(dpr, zoom, darkSolid).then((blob) => ({
180
194
  zoom,
181
195
  theme: "dark",
182
196
  url: URL.createObjectURL(blob)
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/shapes/shared/defaultStyleDefs.tsx"],
4
- "sourcesContent": ["import {\n\tDefaultFontStyle,\n\tSvgExportDef,\n\tTLDefaultFillStyle,\n\tTLShapeUtilCanvasSvgDef,\n\tdebugFlags,\n\tgetGlobalDocument,\n\tlast,\n\tsuffixSafeId,\n\ttlenv,\n\tuseColorMode,\n\tuseEditor,\n\tuseSharedSafeId,\n\tuseUniqueSafeId,\n\tuseValue,\n} from '@tldraw/editor'\nimport { useCallback, useEffect, useRef, useState } from 'react'\n\n/** @public */\nexport function getFillDefForExport(fill: TLDefaultFillStyle): SvgExportDef {\n\treturn {\n\t\tkey: `${DefaultFontStyle.id}:${fill}`,\n\t\tasync getElement() {\n\t\t\tif (fill !== 'pattern') return null\n\n\t\t\treturn <HashPatternForExport />\n\t\t},\n\t}\n}\n\nfunction HashPatternForExport() {\n\tconst getHashPatternZoomName = useGetHashPatternZoomName()\n\tconst maskId = useUniqueSafeId()\n\tconst editor = useEditor()\n\tconst colorMode = useColorMode()\n\tconst colors = editor.getCurrentTheme().colors[colorMode]\n\tconst t = 8 / 12\n\treturn (\n\t\t<>\n\t\t\t<mask id={maskId}>\n\t\t\t\t<rect x=\"0\" y=\"0\" width=\"8\" height=\"8\" fill=\"white\" />\n\t\t\t\t<g strokeLinecap=\"round\" stroke=\"black\">\n\t\t\t\t\t<line x1={t * 1} y1={t * 3} x2={t * 3} y2={t * 1} />\n\t\t\t\t\t<line x1={t * 5} y1={t * 7} x2={t * 7} y2={t * 5} />\n\t\t\t\t\t<line x1={t * 9} y1={t * 11} x2={t * 11} y2={t * 9} />\n\t\t\t\t</g>\n\t\t\t</mask>\n\t\t\t<pattern\n\t\t\t\tid={getHashPatternZoomName(1, colorMode)}\n\t\t\t\twidth=\"8\"\n\t\t\t\theight=\"8\"\n\t\t\t\tpatternUnits=\"userSpaceOnUse\"\n\t\t\t>\n\t\t\t\t<rect x=\"0\" y=\"0\" width=\"8\" height=\"8\" fill={colors.solid} mask={`url(#${maskId})`} />\n\t\t\t</pattern>\n\t\t</>\n\t)\n}\n\nexport function getFillDefForCanvas(): TLShapeUtilCanvasSvgDef {\n\treturn {\n\t\tkey: `${DefaultFontStyle.id}:pattern`,\n\t\tcomponent: PatternFillDefForCanvas,\n\t}\n}\nconst TILE_PATTERN_SIZE = 8\n\nconst generateImage = (dpr: number, currentZoom: number, solid: string) => {\n\treturn new Promise<Blob>((resolve, reject) => {\n\t\tconst size = TILE_PATTERN_SIZE * currentZoom * dpr\n\n\t\tconst canvasEl = getGlobalDocument().createElement('canvas')\n\t\tcanvasEl.width = size\n\t\tcanvasEl.height = size\n\n\t\tconst ctx = canvasEl.getContext('2d')\n\t\tif (!ctx) return\n\n\t\tctx.fillStyle = solid\n\t\tctx.fillRect(0, 0, size, size)\n\n\t\t// This essentially generates an inverse of the pattern we're drawing.\n\t\tctx.globalCompositeOperation = 'destination-out'\n\n\t\tctx.lineCap = 'round'\n\t\tctx.lineWidth = 1.25 * currentZoom * dpr\n\n\t\tconst t = 8 / 12\n\t\tconst s = (v: number) => v * currentZoom * dpr\n\n\t\tctx.beginPath()\n\t\tctx.moveTo(s(t * 1), s(t * 3))\n\t\tctx.lineTo(s(t * 3), s(t * 1))\n\n\t\tctx.moveTo(s(t * 5), s(t * 7))\n\t\tctx.lineTo(s(t * 7), s(t * 5))\n\n\t\tctx.moveTo(s(t * 9), s(t * 11))\n\t\tctx.lineTo(s(t * 11), s(t * 9))\n\t\tctx.stroke()\n\n\t\tcanvasEl.toBlob((blob) => {\n\t\t\tif (!blob || debugFlags.throwToBlob.get()) {\n\t\t\t\treject()\n\t\t\t} else {\n\t\t\t\tresolve(blob)\n\t\t\t}\n\t\t})\n\t})\n}\n\nconst canvasBlob = (size: [number, number], fn: (ctx: CanvasRenderingContext2D) => void) => {\n\tconst canvas = getGlobalDocument().createElement('canvas')\n\tcanvas.width = size[0]\n\tcanvas.height = size[1]\n\tconst ctx = canvas.getContext('2d')\n\tif (!ctx) return ''\n\tfn(ctx)\n\treturn canvas.toDataURL()\n}\ninterface PatternDef {\n\tzoom: number\n\turl: string\n\ttheme: string\n}\n\nlet defaultPixels: { white: string; black: string } | null = null\nfunction getDefaultPixels() {\n\tif (!defaultPixels) {\n\t\tdefaultPixels = {\n\t\t\twhite: canvasBlob([1, 1], (ctx) => {\n\t\t\t\tctx.fillStyle = '#f8f9fa'\n\t\t\t\tctx.fillRect(0, 0, 1, 1)\n\t\t\t}),\n\t\t\tblack: canvasBlob([1, 1], (ctx) => {\n\t\t\t\tctx.fillStyle = '#212529'\n\t\t\t\tctx.fillRect(0, 0, 1, 1)\n\t\t\t}),\n\t\t}\n\t}\n\treturn defaultPixels\n}\n\nfunction getPatternLodForZoomLevel(zoom: number) {\n\treturn Math.ceil(Math.log2(Math.max(1, zoom)))\n}\n\nexport function useGetHashPatternZoomName() {\n\tconst id = useSharedSafeId('hash_pattern')\n\treturn useCallback(\n\t\t(zoom: number, theme: string) => {\n\t\t\tconst lod = getPatternLodForZoomLevel(zoom)\n\t\t\treturn suffixSafeId(id, `${theme}_${lod}`)\n\t\t},\n\t\t[id]\n\t)\n}\n\nfunction getPatternLodsToGenerate(maxZoom: number) {\n\tconst levels = []\n\tconst minLod = 0\n\tconst maxLod = getPatternLodForZoomLevel(maxZoom)\n\tfor (let i = minLod; i <= maxLod; i++) {\n\t\tlevels.push(Math.pow(2, i))\n\t}\n\treturn levels\n}\n\nfunction getDefaultPatterns(maxZoom: number): PatternDef[] {\n\tconst defaultPixels = getDefaultPixels()\n\treturn getPatternLodsToGenerate(maxZoom).flatMap((zoom) => [\n\t\t{ zoom, url: defaultPixels.white, theme: 'light' },\n\t\t{ zoom, url: defaultPixels.black, theme: 'dark' },\n\t])\n}\n\nfunction usePattern() {\n\tconst editor = useEditor()\n\tconst dpr = useValue('devicePixelRatio', () => editor.getInstanceState().devicePixelRatio, [\n\t\teditor,\n\t])\n\t// In dynamic size mode, new shapes are created with scale = 1 / zoomLevel.\n\t// For pattern LOD generation, we use the worst-case effective zoom:\n\t// a shape created at min zoom and later viewed at max zoom (maxZoom / minZoom)\n\tconst maxEffectiveZoom = useValue(\n\t\t'maxEffectiveZoom',\n\t\t() => {\n\t\t\tconst steps = editor.getCameraOptions().zoomSteps\n\t\t\treturn last(steps)! / steps[0]\n\t\t},\n\t\t[editor]\n\t)\n\tconst [isReady, setIsReady] = useState(false)\n\tconst [backgroundUrls, setBackgroundUrls] = useState<PatternDef[]>(() =>\n\t\tgetDefaultPatterns(maxEffectiveZoom)\n\t)\n\tconst getHashPatternZoomName = useGetHashPatternZoomName()\n\n\tuseEffect(() => {\n\t\tif (process.env.NODE_ENV === 'test') {\n\t\t\tsetIsReady(true)\n\t\t\treturn\n\t\t}\n\n\t\tconst definition = editor.getCurrentTheme()\n\t\tconst lightSolid = definition.colors.light.solid\n\t\tconst darkSolid = definition.colors.dark.solid\n\n\t\tconst promise = Promise.all(\n\t\t\tgetPatternLodsToGenerate(maxEffectiveZoom).flatMap<Promise<PatternDef>>((zoom) => [\n\t\t\t\tgenerateImage(dpr, zoom, lightSolid).then((blob) => ({\n\t\t\t\t\tzoom,\n\t\t\t\t\ttheme: 'light',\n\t\t\t\t\turl: URL.createObjectURL(blob),\n\t\t\t\t})),\n\t\t\t\tgenerateImage(dpr, zoom, darkSolid).then((blob) => ({\n\t\t\t\t\tzoom,\n\t\t\t\t\ttheme: 'dark',\n\t\t\t\t\turl: URL.createObjectURL(blob),\n\t\t\t\t})),\n\t\t\t])\n\t\t)\n\n\t\tlet isCancelled = false\n\t\tpromise.then((urls) => {\n\t\t\tif (isCancelled) return\n\t\t\tsetBackgroundUrls(urls)\n\t\t\tsetIsReady(true)\n\t\t})\n\t\treturn () => {\n\t\t\tisCancelled = true\n\t\t\tsetIsReady(false)\n\t\t\tpromise.then((patterns) => {\n\t\t\t\tfor (const { url } of patterns) {\n\t\t\t\t\tURL.revokeObjectURL(url)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t}, [dpr, maxEffectiveZoom, editor])\n\n\tconst defs = (\n\t\t<>\n\t\t\t{backgroundUrls.map((item) => {\n\t\t\t\tconst id = getHashPatternZoomName(item.zoom, item.theme)\n\t\t\t\treturn (\n\t\t\t\t\t<pattern\n\t\t\t\t\t\tkey={id}\n\t\t\t\t\t\tid={id}\n\t\t\t\t\t\twidth={TILE_PATTERN_SIZE}\n\t\t\t\t\t\theight={TILE_PATTERN_SIZE}\n\t\t\t\t\t\tpatternUnits=\"userSpaceOnUse\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<image href={item.url} width={TILE_PATTERN_SIZE} height={TILE_PATTERN_SIZE} />\n\t\t\t\t\t</pattern>\n\t\t\t\t)\n\t\t\t})}\n\t\t</>\n\t)\n\n\treturn { defs, isReady }\n}\n\nfunction PatternFillDefForCanvas() {\n\tconst editor = useEditor()\n\tconst containerRef = useRef<SVGGElement>(null)\n\tconst { defs, isReady } = usePattern()\n\n\tuseEffect(() => {\n\t\tif (isReady && tlenv.isSafari) {\n\t\t\tconst htmlLayer = findHtmlLayerParent(containerRef.current!)\n\t\t\tif (htmlLayer) {\n\t\t\t\t// Wait for `patternContext` to be picked up\n\t\t\t\teditor.timers.requestAnimationFrame(() => {\n\t\t\t\t\thtmlLayer.style.display = 'none'\n\n\t\t\t\t\t// Wait for 'display = \"none\"' to take effect\n\t\t\t\t\teditor.timers.requestAnimationFrame(() => {\n\t\t\t\t\t\thtmlLayer.style.display = ''\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t}, [editor, isReady])\n\n\treturn (\n\t\t<g ref={containerRef} data-testid={isReady ? 'ready-pattern-fill-defs' : undefined}>\n\t\t\t{defs}\n\t\t</g>\n\t)\n}\n\nfunction findHtmlLayerParent(element: Element): HTMLElement | null {\n\tif (element.classList.contains('tl-html-layer')) return element as HTMLElement\n\tif (element.parentElement) return findHtmlLayerParent(element.parentElement)\n\treturn null\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n\tDefaultFontStyle,\n\tSvgExportDef,\n\tTLDefaultFillStyle,\n\tTLShapeUtilCanvasSvgDef,\n\tdebugFlags,\n\tgetGlobalDocument,\n\tlast,\n\tsuffixSafeId,\n\ttlenv,\n\tuseColorMode,\n\tuseEditor,\n\tuseSharedSafeId,\n\tuseUniqueSafeId,\n\tuseValue,\n} from '@tldraw/editor'\nimport { useCallback, useEffect, useRef, useState } from 'react'\n\n/** @public */\nexport function getFillDefForExport(fill: TLDefaultFillStyle): SvgExportDef {\n\treturn {\n\t\tkey: `${DefaultFontStyle.id}:${fill}`,\n\t\tasync getElement() {\n\t\t\tif (fill !== 'pattern') return null\n\n\t\t\treturn <HashPatternForExport />\n\t\t},\n\t}\n}\n\nfunction HashPatternForExport() {\n\tconst getHashPatternZoomName = useGetHashPatternZoomName()\n\tconst maskId = useUniqueSafeId()\n\tconst editor = useEditor()\n\tconst colorMode = useColorMode()\n\tconst colors = editor.getCurrentTheme().colors[colorMode]\n\tconst t = 8 / 12\n\treturn (\n\t\t<>\n\t\t\t<mask id={maskId}>\n\t\t\t\t<rect x=\"0\" y=\"0\" width=\"8\" height=\"8\" fill=\"white\" />\n\t\t\t\t<g strokeLinecap=\"round\" stroke=\"black\">\n\t\t\t\t\t<line x1={t * 1} y1={t * 3} x2={t * 3} y2={t * 1} />\n\t\t\t\t\t<line x1={t * 5} y1={t * 7} x2={t * 7} y2={t * 5} />\n\t\t\t\t\t<line x1={t * 9} y1={t * 11} x2={t * 11} y2={t * 9} />\n\t\t\t\t</g>\n\t\t\t</mask>\n\t\t\t<pattern\n\t\t\t\tid={getHashPatternZoomName(1, colorMode)}\n\t\t\t\twidth=\"8\"\n\t\t\t\theight=\"8\"\n\t\t\t\tpatternUnits=\"userSpaceOnUse\"\n\t\t\t>\n\t\t\t\t<rect x=\"0\" y=\"0\" width=\"8\" height=\"8\" fill={colors.solid} mask={`url(#${maskId})`} />\n\t\t\t</pattern>\n\t\t</>\n\t)\n}\n\nexport function getFillDefForCanvas(): TLShapeUtilCanvasSvgDef {\n\treturn {\n\t\tkey: `${DefaultFontStyle.id}:pattern`,\n\t\tcomponent: PatternFillDefForCanvas,\n\t}\n}\nconst TILE_PATTERN_SIZE = 8\n\nconst generateImage = (dpr: number, currentZoom: number, solid: string) => {\n\treturn new Promise<Blob>((resolve, reject) => {\n\t\tconst size = TILE_PATTERN_SIZE * currentZoom * dpr\n\n\t\tconst canvasEl = getGlobalDocument().createElement('canvas')\n\t\tcanvasEl.width = size\n\t\tcanvasEl.height = size\n\n\t\tconst ctx = canvasEl.getContext('2d')\n\t\tif (!ctx) {\n\t\t\treject()\n\t\t\treturn\n\t\t}\n\n\t\tctx.fillStyle = solid\n\t\tctx.fillRect(0, 0, size, size)\n\n\t\t// This essentially generates an inverse of the pattern we're drawing.\n\t\tctx.globalCompositeOperation = 'destination-out'\n\n\t\tctx.lineCap = 'round'\n\t\tctx.lineWidth = 1.25 * currentZoom * dpr\n\n\t\tconst t = 8 / 12\n\t\tconst s = (v: number) => v * currentZoom * dpr\n\n\t\tctx.beginPath()\n\t\tctx.moveTo(s(t * 1), s(t * 3))\n\t\tctx.lineTo(s(t * 3), s(t * 1))\n\n\t\tctx.moveTo(s(t * 5), s(t * 7))\n\t\tctx.lineTo(s(t * 7), s(t * 5))\n\n\t\tctx.moveTo(s(t * 9), s(t * 11))\n\t\tctx.lineTo(s(t * 11), s(t * 9))\n\t\tctx.stroke()\n\n\t\tcanvasEl.toBlob((blob) => {\n\t\t\tif (!blob || debugFlags.throwToBlob.get()) {\n\t\t\t\treject()\n\t\t\t} else {\n\t\t\t\tresolve(blob)\n\t\t\t}\n\t\t})\n\t})\n}\n\n// Generating the pattern images is expensive (canvas draw + encode), but the result only depends\n// on the device pixel ratio, zoom level, and solid color. Cache the blobs at the module level so\n// the work is done once and reused across editor mounts and instances. Object URLs are still\n// created and revoked per-instance; only the underlying blobs are shared.\nconst patternImageBlobCache = new Map<string, Promise<Blob>>()\n\nfunction getPatternImageBlob(dpr: number, zoom: number, solid: string): Promise<Blob> {\n\tconst key = `${dpr}_${zoom}_${solid}`\n\tlet blob = patternImageBlobCache.get(key)\n\tif (!blob) {\n\t\tblob = generateImage(dpr, zoom, solid)\n\t\t// Don't keep a rejected promise around (e.g. the throwToBlob debug flag), so a later call\n\t\t// can retry once the failure condition is gone.\n\t\tblob.catch(() => patternImageBlobCache.delete(key))\n\t\tpatternImageBlobCache.set(key, blob)\n\t}\n\treturn blob\n}\n\nconst canvasBlob = (size: [number, number], fn: (ctx: CanvasRenderingContext2D) => void) => {\n\tconst canvas = getGlobalDocument().createElement('canvas')\n\tcanvas.width = size[0]\n\tcanvas.height = size[1]\n\tconst ctx = canvas.getContext('2d')\n\tif (!ctx) return ''\n\tfn(ctx)\n\treturn canvas.toDataURL()\n}\ninterface PatternDef {\n\tzoom: number\n\turl: string\n\ttheme: string\n}\n\nlet defaultPixels: { white: string; black: string } | null = null\nfunction getDefaultPixels() {\n\tif (!defaultPixels) {\n\t\tdefaultPixels = {\n\t\t\twhite: canvasBlob([1, 1], (ctx) => {\n\t\t\t\tctx.fillStyle = '#f8f9fa'\n\t\t\t\tctx.fillRect(0, 0, 1, 1)\n\t\t\t}),\n\t\t\tblack: canvasBlob([1, 1], (ctx) => {\n\t\t\t\tctx.fillStyle = '#212529'\n\t\t\t\tctx.fillRect(0, 0, 1, 1)\n\t\t\t}),\n\t\t}\n\t}\n\treturn defaultPixels\n}\n\nfunction getPatternLodForZoomLevel(zoom: number) {\n\treturn Math.ceil(Math.log2(Math.max(1, zoom)))\n}\n\nexport function useGetHashPatternZoomName() {\n\tconst id = useSharedSafeId('hash_pattern')\n\treturn useCallback(\n\t\t(zoom: number, theme: string) => {\n\t\t\tconst lod = getPatternLodForZoomLevel(zoom)\n\t\t\treturn suffixSafeId(id, `${theme}_${lod}`)\n\t\t},\n\t\t[id]\n\t)\n}\n\nfunction getPatternLodsToGenerate(maxZoom: number) {\n\tconst levels = []\n\tconst minLod = 0\n\tconst maxLod = getPatternLodForZoomLevel(maxZoom)\n\tfor (let i = minLod; i <= maxLod; i++) {\n\t\tlevels.push(Math.pow(2, i))\n\t}\n\treturn levels\n}\n\nfunction getDefaultPatterns(maxZoom: number): PatternDef[] {\n\tconst defaultPixels = getDefaultPixels()\n\treturn getPatternLodsToGenerate(maxZoom).flatMap((zoom) => [\n\t\t{ zoom, url: defaultPixels.white, theme: 'light' },\n\t\t{ zoom, url: defaultPixels.black, theme: 'dark' },\n\t])\n}\n\nfunction usePattern() {\n\tconst editor = useEditor()\n\tconst dpr = useValue('devicePixelRatio', () => editor.getInstanceState().devicePixelRatio, [\n\t\teditor,\n\t])\n\t// In dynamic size mode, new shapes are created with scale = 1 / zoomLevel.\n\t// For pattern LOD generation, we use the worst-case effective zoom:\n\t// a shape created at min zoom and later viewed at max zoom (maxZoom / minZoom)\n\tconst maxEffectiveZoom = useValue(\n\t\t'maxEffectiveZoom',\n\t\t() => {\n\t\t\tconst steps = editor.getCameraOptions().zoomSteps\n\t\t\treturn last(steps)! / steps[0]\n\t\t},\n\t\t[editor]\n\t)\n\tconst [isReady, setIsReady] = useState(false)\n\tconst [backgroundUrls, setBackgroundUrls] = useState<PatternDef[]>(() =>\n\t\tgetDefaultPatterns(maxEffectiveZoom)\n\t)\n\tconst getHashPatternZoomName = useGetHashPatternZoomName()\n\n\tuseEffect(() => {\n\t\tif (process.env.NODE_ENV === 'test') {\n\t\t\tsetIsReady(true)\n\t\t\treturn\n\t\t}\n\n\t\tconst definition = editor.getCurrentTheme()\n\t\tconst lightSolid = definition.colors.light.solid\n\t\tconst darkSolid = definition.colors.dark.solid\n\n\t\tconst promise = Promise.all(\n\t\t\tgetPatternLodsToGenerate(maxEffectiveZoom).flatMap<Promise<PatternDef>>((zoom) => [\n\t\t\t\tgetPatternImageBlob(dpr, zoom, lightSolid).then((blob) => ({\n\t\t\t\t\tzoom,\n\t\t\t\t\ttheme: 'light',\n\t\t\t\t\turl: URL.createObjectURL(blob),\n\t\t\t\t})),\n\t\t\t\tgetPatternImageBlob(dpr, zoom, darkSolid).then((blob) => ({\n\t\t\t\t\tzoom,\n\t\t\t\t\ttheme: 'dark',\n\t\t\t\t\turl: URL.createObjectURL(blob),\n\t\t\t\t})),\n\t\t\t])\n\t\t)\n\n\t\tlet isCancelled = false\n\t\tpromise.then((urls) => {\n\t\t\tif (isCancelled) return\n\t\t\tsetBackgroundUrls(urls)\n\t\t\tsetIsReady(true)\n\t\t})\n\t\treturn () => {\n\t\t\tisCancelled = true\n\t\t\tsetIsReady(false)\n\t\t\tpromise.then((patterns) => {\n\t\t\t\tfor (const { url } of patterns) {\n\t\t\t\t\tURL.revokeObjectURL(url)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t}, [dpr, maxEffectiveZoom, editor])\n\n\tconst defs = (\n\t\t<>\n\t\t\t{backgroundUrls.map((item) => {\n\t\t\t\tconst id = getHashPatternZoomName(item.zoom, item.theme)\n\t\t\t\treturn (\n\t\t\t\t\t<pattern\n\t\t\t\t\t\tkey={id}\n\t\t\t\t\t\tid={id}\n\t\t\t\t\t\twidth={TILE_PATTERN_SIZE}\n\t\t\t\t\t\theight={TILE_PATTERN_SIZE}\n\t\t\t\t\t\tpatternUnits=\"userSpaceOnUse\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<image href={item.url} width={TILE_PATTERN_SIZE} height={TILE_PATTERN_SIZE} />\n\t\t\t\t\t</pattern>\n\t\t\t\t)\n\t\t\t})}\n\t\t</>\n\t)\n\n\treturn { defs, isReady }\n}\n\nfunction PatternFillDefForCanvas() {\n\tconst editor = useEditor()\n\tconst containerRef = useRef<SVGGElement>(null)\n\tconst { defs, isReady } = usePattern()\n\n\tuseEffect(() => {\n\t\tif (isReady && tlenv.isSafari) {\n\t\t\tconst htmlLayer = findHtmlLayerParent(containerRef.current!)\n\t\t\tif (htmlLayer) {\n\t\t\t\t// Wait for `patternContext` to be picked up\n\t\t\t\teditor.timers.requestAnimationFrame(() => {\n\t\t\t\t\thtmlLayer.style.display = 'none'\n\n\t\t\t\t\t// Wait for 'display = \"none\"' to take effect\n\t\t\t\t\teditor.timers.requestAnimationFrame(() => {\n\t\t\t\t\t\thtmlLayer.style.display = ''\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t}, [editor, isReady])\n\n\treturn (\n\t\t<g ref={containerRef} data-testid={isReady ? 'ready-pattern-fill-defs' : undefined}>\n\t\t\t{defs}\n\t\t</g>\n\t)\n}\n\nfunction findHtmlLayerParent(element: Element): HTMLElement | null {\n\tif (element.classList.contains('tl-html-layer')) return element as HTMLElement\n\tif (element.parentElement) return findHtmlLayerParent(element.parentElement)\n\treturn null\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["defaultPixels"]
7
7
  }