tldraw 3.16.0-canary.ffdf566dd0a8 → 3.16.0-internal.71f83a8a571b

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 (515) hide show
  1. package/dist-cjs/index.d.ts +348 -113
  2. package/dist-cjs/index.js +40 -14
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/Tldraw.js +12 -2
  5. package/dist-cjs/lib/Tldraw.js.map +2 -2
  6. package/dist-cjs/lib/canvas/TldrawScribble.js +1 -1
  7. package/dist-cjs/lib/canvas/TldrawScribble.js.map +2 -2
  8. package/dist-cjs/lib/defaultExternalContentHandlers.js +5 -4
  9. package/dist-cjs/lib/defaultExternalContentHandlers.js.map +2 -2
  10. package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js +3 -3
  11. package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js.map +2 -2
  12. package/dist-cjs/lib/shapes/arrow/arrowLabel.js +6 -0
  13. package/dist-cjs/lib/shapes/arrow/arrowLabel.js.map +3 -3
  14. package/dist-cjs/lib/shapes/arrow/arrowTargetState.js.map +2 -2
  15. package/dist-cjs/lib/shapes/arrow/elbow/ElbowArrowDebug.js +3 -3
  16. package/dist-cjs/lib/shapes/arrow/elbow/ElbowArrowDebug.js.map +1 -1
  17. package/dist-cjs/lib/shapes/arrow/elbow/elbowArrowSnapLines.js.map +1 -1
  18. package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js +4 -4
  19. package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js.map +2 -2
  20. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js +3 -3
  21. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js.map +2 -2
  22. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js +1 -1
  23. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js.map +1 -1
  24. package/dist-cjs/lib/shapes/frame/FrameShapeTool.js.map +1 -1
  25. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js +20 -13
  26. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js.map +2 -2
  27. package/dist-cjs/lib/shapes/frame/components/FrameHeading.js +1 -1
  28. package/dist-cjs/lib/shapes/frame/components/FrameHeading.js.map +2 -2
  29. package/dist-cjs/lib/shapes/frame/components/FrameLabelInput.js +2 -2
  30. package/dist-cjs/lib/shapes/frame/components/FrameLabelInput.js.map +2 -2
  31. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js +3 -2
  32. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js.map +2 -2
  33. package/dist-cjs/lib/shapes/geo/components/GeoShapeBody.js +2 -1
  34. package/dist-cjs/lib/shapes/geo/components/GeoShapeBody.js.map +2 -2
  35. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js +5 -1
  36. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js.map +2 -2
  37. package/dist-cjs/lib/shapes/image/ImageShapeUtil.js +6 -3
  38. package/dist-cjs/lib/shapes/image/ImageShapeUtil.js.map +2 -2
  39. package/dist-cjs/lib/shapes/line/LineShapeUtil.js +5 -1
  40. package/dist-cjs/lib/shapes/line/LineShapeUtil.js.map +2 -2
  41. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js +6 -5
  42. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js.map +2 -2
  43. package/dist-cjs/lib/shapes/shared/HyperlinkButton.js +4 -4
  44. package/dist-cjs/lib/shapes/shared/HyperlinkButton.js.map +2 -2
  45. package/dist-cjs/lib/shapes/shared/PlainTextLabel.js +1 -3
  46. package/dist-cjs/lib/shapes/shared/PlainTextLabel.js.map +2 -2
  47. package/dist-cjs/lib/shapes/shared/RichTextLabel.js.map +2 -2
  48. package/dist-cjs/lib/shapes/shared/ShapeFill.js +4 -4
  49. package/dist-cjs/lib/shapes/shared/ShapeFill.js.map +2 -2
  50. package/dist-cjs/lib/shapes/shared/crop.js +1 -0
  51. package/dist-cjs/lib/shapes/shared/crop.js.map +2 -2
  52. package/dist-cjs/lib/shapes/shared/freehand/svg.js.map +2 -2
  53. package/dist-cjs/lib/shapes/shared/useEditablePlainText.js +3 -4
  54. package/dist-cjs/lib/shapes/shared/useEditablePlainText.js.map +2 -2
  55. package/dist-cjs/lib/shapes/shared/useEditableRichText.js.map +2 -2
  56. package/dist-cjs/lib/shapes/shared/useImageOrVideoAsset.js +0 -2
  57. package/dist-cjs/lib/shapes/shared/useImageOrVideoAsset.js.map +2 -2
  58. package/dist-cjs/lib/shapes/text/PlainTextArea.js +2 -2
  59. package/dist-cjs/lib/shapes/text/PlainTextArea.js.map +2 -2
  60. package/dist-cjs/lib/shapes/text/RichTextArea.js +3 -3
  61. package/dist-cjs/lib/shapes/text/RichTextArea.js.map +2 -2
  62. package/dist-cjs/lib/shapes/text/TextShapeUtil.js +2 -2
  63. package/dist-cjs/lib/shapes/text/TextShapeUtil.js.map +2 -2
  64. package/dist-cjs/lib/shapes/video/VideoShapeUtil.js +3 -3
  65. package/dist-cjs/lib/shapes/video/VideoShapeUtil.js.map +1 -1
  66. package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js +25 -1
  67. package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js.map +2 -2
  68. package/dist-cjs/lib/tools/EraserTool/childStates/Pointing.js +12 -0
  69. package/dist-cjs/lib/tools/EraserTool/childStates/Pointing.js.map +2 -2
  70. package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js +1 -1
  71. package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js.map +2 -2
  72. package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js.map +2 -2
  73. package/dist-cjs/lib/ui/TldrawUi.js +27 -12
  74. package/dist-cjs/lib/ui/TldrawUi.js.map +3 -3
  75. package/dist-cjs/lib/ui/assetUrls.js +13 -10
  76. package/dist-cjs/lib/ui/assetUrls.js.map +2 -2
  77. package/dist-cjs/lib/ui/components/A11y.js +1 -1
  78. package/dist-cjs/lib/ui/components/A11y.js.map +2 -2
  79. package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenu.js +12 -3
  80. package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenu.js.map +2 -2
  81. package/dist-cjs/lib/ui/components/{FollowingIndicator.js → DefaultFollowingIndicator.js} +6 -6
  82. package/dist-cjs/lib/ui/components/DefaultFollowingIndicator.js.map +7 -0
  83. package/dist-cjs/lib/ui/components/DefaultMenuPanel.js +3 -2
  84. package/dist-cjs/lib/ui/components/DefaultMenuPanel.js.map +2 -2
  85. package/dist-cjs/lib/ui/components/EditLinkDialog.js +11 -1
  86. package/dist-cjs/lib/ui/components/EditLinkDialog.js.map +2 -2
  87. package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js +6 -6
  88. package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js.map +1 -1
  89. package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js +4 -4
  90. package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js.map +2 -2
  91. package/dist-cjs/lib/ui/components/MobileStylePanel.js +5 -3
  92. package/dist-cjs/lib/ui/components/MobileStylePanel.js.map +2 -2
  93. package/dist-cjs/lib/ui/components/NavigationPanel/DefaultNavigationPanel.js +1 -1
  94. package/dist-cjs/lib/ui/components/NavigationPanel/DefaultNavigationPanel.js.map +2 -2
  95. package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js +3 -2
  96. package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js.map +2 -2
  97. package/dist-cjs/lib/ui/components/SharePanel/PeopleMenuItem.js +3 -2
  98. package/dist-cjs/lib/ui/components/SharePanel/PeopleMenuItem.js.map +2 -2
  99. package/dist-cjs/lib/ui/components/SharePanel/UserPresenceColorPicker.js +2 -2
  100. package/dist-cjs/lib/ui/components/SharePanel/UserPresenceColorPicker.js.map +2 -2
  101. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js +9 -4
  102. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js.map +2 -2
  103. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js +255 -316
  104. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js.map +2 -2
  105. package/dist-cjs/lib/ui/components/{primitives/TldrawUiButtonPicker.js → StylePanel/StylePanelButtonPicker.js} +52 -56
  106. package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js.map +7 -0
  107. package/dist-cjs/lib/ui/components/StylePanel/StylePanelContext.js +68 -0
  108. package/dist-cjs/lib/ui/components/StylePanel/StylePanelContext.js.map +7 -0
  109. package/dist-cjs/lib/ui/components/StylePanel/{DoubleDropdownPicker.js → StylePanelDoubleDropdownPicker.js} +26 -25
  110. package/dist-cjs/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.js.map +7 -0
  111. package/dist-cjs/lib/ui/components/StylePanel/{DropdownPicker.js → StylePanelDropdownPicker.js} +47 -43
  112. package/dist-cjs/lib/ui/components/StylePanel/StylePanelDropdownPicker.js.map +7 -0
  113. package/dist-cjs/lib/ui/components/StylePanel/StylePanelSubheading.js +28 -0
  114. package/dist-cjs/lib/ui/components/StylePanel/StylePanelSubheading.js.map +7 -0
  115. package/dist-cjs/lib/ui/components/Toolbar/AltTextEditor.js +3 -2
  116. package/dist-cjs/lib/ui/components/Toolbar/AltTextEditor.js.map +2 -2
  117. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js +39 -10
  118. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js.map +2 -2
  119. package/dist-cjs/lib/ui/components/Toolbar/DefaultToolbar.js +66 -21
  120. package/dist-cjs/lib/ui/components/Toolbar/DefaultToolbar.js.map +3 -3
  121. package/dist-cjs/lib/ui/components/Toolbar/DefaultVideoToolbarContent.js +15 -3
  122. package/dist-cjs/lib/ui/components/Toolbar/DefaultVideoToolbarContent.js.map +2 -2
  123. package/dist-cjs/lib/ui/components/Toolbar/LinkEditor.js +3 -3
  124. package/dist-cjs/lib/ui/components/Toolbar/LinkEditor.js.map +2 -2
  125. package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js +189 -80
  126. package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js.map +3 -3
  127. package/dist-cjs/lib/ui/components/Toolbar/ToggleToolLockedButton.js +2 -2
  128. package/dist-cjs/lib/ui/components/Toolbar/ToggleToolLockedButton.js.map +2 -2
  129. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js +11 -2
  130. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js.map +2 -2
  131. package/dist-cjs/lib/ui/components/primitives/TldrawUiInput.js +2 -2
  132. package/dist-cjs/lib/ui/components/primitives/TldrawUiInput.js.map +2 -2
  133. package/dist-cjs/lib/ui/components/primitives/TldrawUiPopover.js +3 -2
  134. package/dist-cjs/lib/ui/components/primitives/TldrawUiPopover.js.map +3 -3
  135. package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js +18 -5
  136. package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js.map +2 -2
  137. package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js +21 -4
  138. package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js.map +2 -2
  139. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js +185 -158
  140. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js.map +2 -2
  141. package/dist-cjs/lib/ui/components/primitives/layout.js +76 -0
  142. package/dist-cjs/lib/ui/components/primitives/layout.js.map +7 -0
  143. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuContext.js.map +2 -2
  144. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuGroup.js +25 -12
  145. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuGroup.js.map +2 -2
  146. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js +154 -20
  147. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js.map +2 -2
  148. package/dist-cjs/lib/ui/context/actions.js +23 -10
  149. package/dist-cjs/lib/ui/context/actions.js.map +2 -2
  150. package/dist-cjs/lib/ui/context/components.js +2 -0
  151. package/dist-cjs/lib/ui/context/components.js.map +2 -2
  152. package/dist-cjs/lib/ui/context/events.js.map +2 -2
  153. package/dist-cjs/lib/ui/hooks/useClipboardEvents.js +1 -1
  154. package/dist-cjs/lib/ui/hooks/useClipboardEvents.js.map +2 -2
  155. package/dist-cjs/lib/ui/hooks/useExportAs.js +3 -2
  156. package/dist-cjs/lib/ui/hooks/useExportAs.js.map +2 -2
  157. package/dist-cjs/lib/ui/hooks/useTools.js +94 -9
  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 +4 -2
  161. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js.map +2 -2
  162. package/dist-cjs/lib/ui/kbd-utils.js +9 -3
  163. package/dist-cjs/lib/ui/kbd-utils.js.map +2 -2
  164. package/dist-cjs/lib/ui/version.js +3 -3
  165. package/dist-cjs/lib/ui/version.js.map +1 -1
  166. package/dist-cjs/lib/utils/excalidraw/putExcalidrawContent.js.map +1 -1
  167. package/dist-cjs/lib/utils/export/copyAs.js +1 -2
  168. package/dist-cjs/lib/utils/export/copyAs.js.map +2 -2
  169. package/dist-cjs/lib/utils/export/export.js +0 -20
  170. package/dist-cjs/lib/utils/export/export.js.map +2 -2
  171. package/dist-cjs/lib/utils/export/exportAs.js +1 -2
  172. package/dist-cjs/lib/utils/export/exportAs.js.map +2 -2
  173. package/dist-esm/index.d.mts +348 -113
  174. package/dist-esm/index.mjs +75 -29
  175. package/dist-esm/index.mjs.map +2 -2
  176. package/dist-esm/lib/Tldraw.mjs +14 -4
  177. package/dist-esm/lib/Tldraw.mjs.map +2 -2
  178. package/dist-esm/lib/canvas/TldrawScribble.mjs +1 -1
  179. package/dist-esm/lib/canvas/TldrawScribble.mjs.map +2 -2
  180. package/dist-esm/lib/defaultExternalContentHandlers.mjs +5 -4
  181. package/dist-esm/lib/defaultExternalContentHandlers.mjs.map +2 -2
  182. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs +4 -3
  183. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs.map +2 -2
  184. package/dist-esm/lib/shapes/arrow/arrowLabel.mjs +6 -0
  185. package/dist-esm/lib/shapes/arrow/arrowLabel.mjs.map +3 -3
  186. package/dist-esm/lib/shapes/arrow/arrowTargetState.mjs.map +2 -2
  187. package/dist-esm/lib/shapes/arrow/elbow/ElbowArrowDebug.mjs +3 -3
  188. package/dist-esm/lib/shapes/arrow/elbow/ElbowArrowDebug.mjs.map +1 -1
  189. package/dist-esm/lib/shapes/arrow/elbow/elbowArrowSnapLines.mjs.map +1 -1
  190. package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs +5 -5
  191. package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs.map +2 -2
  192. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs +4 -3
  193. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs.map +2 -2
  194. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs +1 -1
  195. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs.map +1 -1
  196. package/dist-esm/lib/shapes/frame/FrameShapeTool.mjs.map +1 -1
  197. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs +21 -13
  198. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs.map +2 -2
  199. package/dist-esm/lib/shapes/frame/components/FrameHeading.mjs +1 -1
  200. package/dist-esm/lib/shapes/frame/components/FrameHeading.mjs.map +2 -2
  201. package/dist-esm/lib/shapes/frame/components/FrameLabelInput.mjs +3 -3
  202. package/dist-esm/lib/shapes/frame/components/FrameLabelInput.mjs.map +2 -2
  203. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs +4 -2
  204. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs.map +2 -2
  205. package/dist-esm/lib/shapes/geo/components/GeoShapeBody.mjs +2 -1
  206. package/dist-esm/lib/shapes/geo/components/GeoShapeBody.mjs.map +2 -2
  207. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs +6 -1
  208. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs.map +2 -2
  209. package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs +6 -3
  210. package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs.map +2 -2
  211. package/dist-esm/lib/shapes/line/LineShapeUtil.mjs +6 -1
  212. package/dist-esm/lib/shapes/line/LineShapeUtil.mjs.map +2 -2
  213. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs +7 -5
  214. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs.map +2 -2
  215. package/dist-esm/lib/shapes/shared/HyperlinkButton.mjs +5 -5
  216. package/dist-esm/lib/shapes/shared/HyperlinkButton.mjs.map +2 -2
  217. package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs +1 -3
  218. package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs.map +2 -2
  219. package/dist-esm/lib/shapes/shared/RichTextLabel.mjs.map +2 -2
  220. package/dist-esm/lib/shapes/shared/ShapeFill.mjs +5 -4
  221. package/dist-esm/lib/shapes/shared/ShapeFill.mjs.map +2 -2
  222. package/dist-esm/lib/shapes/shared/crop.mjs +1 -0
  223. package/dist-esm/lib/shapes/shared/crop.mjs.map +2 -2
  224. package/dist-esm/lib/shapes/shared/freehand/svg.mjs.map +2 -2
  225. package/dist-esm/lib/shapes/shared/useEditablePlainText.mjs +4 -5
  226. package/dist-esm/lib/shapes/shared/useEditablePlainText.mjs.map +2 -2
  227. package/dist-esm/lib/shapes/shared/useEditableRichText.mjs.map +2 -2
  228. package/dist-esm/lib/shapes/shared/useImageOrVideoAsset.mjs +0 -2
  229. package/dist-esm/lib/shapes/shared/useImageOrVideoAsset.mjs.map +2 -2
  230. package/dist-esm/lib/shapes/text/PlainTextArea.mjs +3 -3
  231. package/dist-esm/lib/shapes/text/PlainTextArea.mjs.map +2 -2
  232. package/dist-esm/lib/shapes/text/RichTextArea.mjs +3 -4
  233. package/dist-esm/lib/shapes/text/RichTextArea.mjs.map +2 -2
  234. package/dist-esm/lib/shapes/text/TextShapeUtil.mjs +3 -2
  235. package/dist-esm/lib/shapes/text/TextShapeUtil.mjs.map +2 -2
  236. package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs +3 -3
  237. package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs.map +1 -1
  238. package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs +26 -1
  239. package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs.map +2 -2
  240. package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs +13 -0
  241. package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs.map +2 -2
  242. package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs +1 -1
  243. package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs.map +2 -2
  244. package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs.map +2 -2
  245. package/dist-esm/lib/ui/TldrawUi.mjs +29 -14
  246. package/dist-esm/lib/ui/TldrawUi.mjs.map +3 -3
  247. package/dist-esm/lib/ui/assetUrls.mjs +13 -10
  248. package/dist-esm/lib/ui/assetUrls.mjs.map +2 -2
  249. package/dist-esm/lib/ui/components/A11y.mjs +2 -2
  250. package/dist-esm/lib/ui/components/A11y.mjs.map +2 -2
  251. package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenu.mjs +12 -3
  252. package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenu.mjs.map +2 -2
  253. package/dist-esm/lib/ui/components/{FollowingIndicator.mjs → DefaultFollowingIndicator.mjs} +3 -3
  254. package/dist-esm/lib/ui/components/DefaultFollowingIndicator.mjs.map +7 -0
  255. package/dist-esm/lib/ui/components/DefaultMenuPanel.mjs +3 -2
  256. package/dist-esm/lib/ui/components/DefaultMenuPanel.mjs.map +2 -2
  257. package/dist-esm/lib/ui/components/EditLinkDialog.mjs +11 -1
  258. package/dist-esm/lib/ui/components/EditLinkDialog.mjs.map +2 -2
  259. package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs +6 -6
  260. package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs.map +1 -1
  261. package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs +4 -4
  262. package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs.map +2 -2
  263. package/dist-esm/lib/ui/components/MobileStylePanel.mjs +6 -3
  264. package/dist-esm/lib/ui/components/MobileStylePanel.mjs.map +2 -2
  265. package/dist-esm/lib/ui/components/NavigationPanel/DefaultNavigationPanel.mjs +1 -1
  266. package/dist-esm/lib/ui/components/NavigationPanel/DefaultNavigationPanel.mjs.map +2 -2
  267. package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs +4 -3
  268. package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs.map +2 -2
  269. package/dist-esm/lib/ui/components/SharePanel/PeopleMenuItem.mjs +3 -2
  270. package/dist-esm/lib/ui/components/SharePanel/PeopleMenuItem.mjs.map +2 -2
  271. package/dist-esm/lib/ui/components/SharePanel/UserPresenceColorPicker.mjs +2 -2
  272. package/dist-esm/lib/ui/components/SharePanel/UserPresenceColorPicker.mjs.map +2 -2
  273. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs +14 -5
  274. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs.map +2 -2
  275. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs +257 -320
  276. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs.map +2 -2
  277. package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs +126 -0
  278. package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs.map +7 -0
  279. package/dist-esm/lib/ui/components/StylePanel/StylePanelContext.mjs +48 -0
  280. package/dist-esm/lib/ui/components/StylePanel/StylePanelContext.mjs.map +7 -0
  281. package/dist-esm/lib/ui/components/StylePanel/{DoubleDropdownPicker.mjs → StylePanelDoubleDropdownPicker.mjs} +23 -22
  282. package/dist-esm/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.mjs.map +7 -0
  283. package/dist-esm/lib/ui/components/StylePanel/{DropdownPicker.mjs → StylePanelDropdownPicker.mjs} +44 -40
  284. package/dist-esm/lib/ui/components/StylePanel/StylePanelDropdownPicker.mjs.map +7 -0
  285. package/dist-esm/lib/ui/components/StylePanel/StylePanelSubheading.mjs +8 -0
  286. package/dist-esm/lib/ui/components/StylePanel/StylePanelSubheading.mjs.map +7 -0
  287. package/dist-esm/lib/ui/components/Toolbar/AltTextEditor.mjs +3 -2
  288. package/dist-esm/lib/ui/components/Toolbar/AltTextEditor.mjs.map +2 -2
  289. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs +39 -10
  290. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs.map +2 -2
  291. package/dist-esm/lib/ui/components/Toolbar/DefaultToolbar.mjs +56 -21
  292. package/dist-esm/lib/ui/components/Toolbar/DefaultToolbar.mjs.map +2 -2
  293. package/dist-esm/lib/ui/components/Toolbar/DefaultVideoToolbarContent.mjs +15 -3
  294. package/dist-esm/lib/ui/components/Toolbar/DefaultVideoToolbarContent.mjs.map +2 -2
  295. package/dist-esm/lib/ui/components/Toolbar/LinkEditor.mjs +3 -3
  296. package/dist-esm/lib/ui/components/Toolbar/LinkEditor.mjs.map +2 -2
  297. package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs +192 -81
  298. package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs.map +3 -3
  299. package/dist-esm/lib/ui/components/Toolbar/ToggleToolLockedButton.mjs +2 -2
  300. package/dist-esm/lib/ui/components/Toolbar/ToggleToolLockedButton.mjs.map +2 -2
  301. package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs +12 -3
  302. package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs.map +2 -2
  303. package/dist-esm/lib/ui/components/primitives/TldrawUiInput.mjs +3 -3
  304. package/dist-esm/lib/ui/components/primitives/TldrawUiInput.mjs.map +2 -2
  305. package/dist-esm/lib/ui/components/primitives/TldrawUiPopover.mjs +3 -2
  306. package/dist-esm/lib/ui/components/primitives/TldrawUiPopover.mjs.map +2 -2
  307. package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs +18 -5
  308. package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs.map +2 -2
  309. package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs +21 -4
  310. package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs.map +2 -2
  311. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs +195 -160
  312. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs.map +2 -2
  313. package/dist-esm/lib/ui/components/primitives/layout.mjs +46 -0
  314. package/dist-esm/lib/ui/components/primitives/layout.mjs.map +7 -0
  315. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuContext.mjs.map +2 -2
  316. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuGroup.mjs +25 -12
  317. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuGroup.mjs.map +2 -2
  318. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs +162 -22
  319. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs.map +2 -2
  320. package/dist-esm/lib/ui/context/actions.mjs +23 -10
  321. package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
  322. package/dist-esm/lib/ui/context/components.mjs +2 -0
  323. package/dist-esm/lib/ui/context/components.mjs.map +2 -2
  324. package/dist-esm/lib/ui/context/events.mjs.map +2 -2
  325. package/dist-esm/lib/ui/hooks/useClipboardEvents.mjs +2 -2
  326. package/dist-esm/lib/ui/hooks/useClipboardEvents.mjs.map +2 -2
  327. package/dist-esm/lib/ui/hooks/useExportAs.mjs +3 -2
  328. package/dist-esm/lib/ui/hooks/useExportAs.mjs.map +2 -2
  329. package/dist-esm/lib/ui/hooks/useTools.mjs +102 -10
  330. package/dist-esm/lib/ui/hooks/useTools.mjs.map +2 -2
  331. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs +4 -2
  332. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs.map +2 -2
  333. package/dist-esm/lib/ui/kbd-utils.mjs +9 -3
  334. package/dist-esm/lib/ui/kbd-utils.mjs.map +2 -2
  335. package/dist-esm/lib/ui/version.mjs +3 -3
  336. package/dist-esm/lib/ui/version.mjs.map +1 -1
  337. package/dist-esm/lib/utils/excalidraw/putExcalidrawContent.mjs.map +1 -1
  338. package/dist-esm/lib/utils/export/copyAs.mjs +1 -2
  339. package/dist-esm/lib/utils/export/copyAs.mjs.map +2 -2
  340. package/dist-esm/lib/utils/export/export.mjs +0 -20
  341. package/dist-esm/lib/utils/export/export.mjs.map +2 -2
  342. package/dist-esm/lib/utils/export/exportAs.mjs +1 -2
  343. package/dist-esm/lib/utils/export/exportAs.mjs.map +2 -2
  344. package/package.json +11 -34
  345. package/src/index.ts +56 -22
  346. package/src/lib/Tldraw.tsx +15 -2
  347. package/src/lib/canvas/TldrawScribble.tsx +1 -1
  348. package/src/lib/defaultExternalContentHandlers.ts +12 -4
  349. package/src/lib/shapes/arrow/ArrowShapeOptions.test.ts +2 -1
  350. package/src/lib/shapes/arrow/ArrowShapeTool.test.ts +6 -5
  351. package/src/lib/shapes/arrow/ArrowShapeUtil.test.ts +48 -6
  352. package/src/lib/shapes/arrow/ArrowShapeUtil.tsx +4 -3
  353. package/src/lib/shapes/arrow/arrowLabel.ts +8 -0
  354. package/src/lib/shapes/arrow/arrowTargetState.ts +1 -1
  355. package/src/lib/shapes/arrow/elbow/ElbowArrowDebug.tsx +3 -3
  356. package/src/lib/shapes/arrow/elbow/elbowArrowSnapLines.tsx +2 -2
  357. package/src/lib/shapes/bookmark/BookmarkShapeUtil.tsx +5 -5
  358. package/src/lib/shapes/draw/DrawShapeTool.test.ts +0 -5
  359. package/src/lib/shapes/draw/DrawShapeUtil.tsx +4 -3
  360. package/src/lib/shapes/embed/EmbedShapeUtil.tsx +1 -1
  361. package/src/lib/shapes/frame/FrameShapeTool.ts +1 -1
  362. package/src/lib/shapes/frame/FrameShapeUtil.tsx +30 -14
  363. package/src/lib/shapes/frame/components/FrameHeading.tsx +1 -1
  364. package/src/lib/shapes/frame/components/FrameLabelInput.tsx +3 -3
  365. package/src/lib/shapes/geo/GeoShapeUtil.tsx +4 -2
  366. package/src/lib/shapes/geo/components/GeoShapeBody.tsx +2 -2
  367. package/src/lib/shapes/highlight/HighlightShapeUtil.tsx +7 -1
  368. package/src/lib/shapes/image/ImageShapeUtil.tsx +6 -3
  369. package/src/lib/shapes/line/LineShapeUtil.test.tsx +8 -7
  370. package/src/lib/shapes/line/LineShapeUtil.tsx +6 -1
  371. package/src/lib/shapes/line/__snapshots__/LineShapeUtil.test.tsx.snap +2 -2
  372. package/src/lib/shapes/note/NoteShapeTool.test.ts +2 -1
  373. package/src/lib/shapes/note/NoteShapeUtil.tsx +10 -4
  374. package/src/lib/shapes/shared/HyperlinkButton.tsx +5 -5
  375. package/src/lib/shapes/shared/PlainTextLabel.tsx +2 -7
  376. package/src/lib/shapes/shared/RichTextLabel.tsx +2 -1
  377. package/src/lib/shapes/shared/ShapeFill.tsx +5 -4
  378. package/src/lib/shapes/shared/crop.ts +1 -0
  379. package/src/lib/shapes/shared/freehand/svg.ts +2 -0
  380. package/src/lib/shapes/shared/useEditablePlainText.ts +12 -12
  381. package/src/lib/shapes/shared/useEditableRichText.ts +7 -3
  382. package/src/lib/shapes/shared/useImageOrVideoAsset.ts +0 -7
  383. package/src/lib/shapes/text/PlainTextArea.tsx +3 -3
  384. package/src/lib/shapes/text/RichTextArea.tsx +3 -4
  385. package/src/lib/shapes/text/TextShapeTool.test.ts +6 -5
  386. package/src/lib/shapes/text/TextShapeUtil.tsx +3 -2
  387. package/src/lib/shapes/video/VideoShapeUtil.tsx +3 -3
  388. package/src/lib/tools/EraserTool/childStates/Erasing.ts +34 -1
  389. package/src/lib/tools/EraserTool/childStates/Pointing.ts +20 -0
  390. package/src/lib/tools/SelectTool/childStates/DraggingHandle.tsx +1 -1
  391. package/src/lib/tools/SelectTool/childStates/Translating.ts +0 -1
  392. package/src/lib/ui/TldrawUi.tsx +33 -12
  393. package/src/lib/ui/assetUrls.ts +13 -10
  394. package/src/lib/ui/components/A11y.tsx +2 -2
  395. package/src/lib/ui/components/ActionsMenu/DefaultActionsMenu.tsx +15 -3
  396. package/src/lib/ui/components/{FollowingIndicator.tsx → DefaultFollowingIndicator.tsx} +2 -1
  397. package/src/lib/ui/components/DefaultMenuPanel.tsx +4 -3
  398. package/src/lib/ui/components/EditLinkDialog.tsx +16 -6
  399. package/src/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.tsx +6 -6
  400. package/src/lib/ui/components/Minimap/MinimapManager.ts +4 -4
  401. package/src/lib/ui/components/MobileStylePanel.tsx +9 -6
  402. package/src/lib/ui/components/NavigationPanel/DefaultNavigationPanel.tsx +1 -1
  403. package/src/lib/ui/components/PageMenu/DefaultPageMenu.tsx +5 -4
  404. package/src/lib/ui/components/SharePanel/PeopleMenuItem.tsx +4 -3
  405. package/src/lib/ui/components/SharePanel/UserPresenceColorPicker.tsx +3 -3
  406. package/src/lib/ui/components/StylePanel/DefaultStylePanel.tsx +27 -13
  407. package/src/lib/ui/components/StylePanel/DefaultStylePanelContent.tsx +260 -385
  408. package/src/lib/ui/components/{primitives/TldrawUiButtonPicker.tsx → StylePanel/StylePanelButtonPicker.tsx} +66 -50
  409. package/src/lib/ui/components/StylePanel/StylePanelContext.tsx +63 -0
  410. package/src/lib/ui/components/StylePanel/{DoubleDropdownPicker.tsx → StylePanelDoubleDropdownPicker.tsx} +31 -22
  411. package/src/lib/ui/components/StylePanel/StylePanelDropdownPicker.tsx +119 -0
  412. package/src/lib/ui/components/StylePanel/StylePanelSubheading.tsx +9 -0
  413. package/src/lib/ui/components/Toolbar/AltTextEditor.tsx +5 -4
  414. package/src/lib/ui/components/Toolbar/DefaultImageToolbarContent.tsx +33 -16
  415. package/src/lib/ui/components/Toolbar/DefaultToolbar.tsx +55 -23
  416. package/src/lib/ui/components/Toolbar/DefaultVideoToolbarContent.tsx +12 -4
  417. package/src/lib/ui/components/Toolbar/LinkEditor.tsx +5 -5
  418. package/src/lib/ui/components/Toolbar/OverflowingToolbar.tsx +212 -61
  419. package/src/lib/ui/components/Toolbar/ToggleToolLockedButton.tsx +2 -2
  420. package/src/lib/ui/components/primitives/TldrawUiContextualToolbar.tsx +8 -3
  421. package/src/lib/ui/components/primitives/TldrawUiInput.tsx +3 -3
  422. package/src/lib/ui/components/primitives/TldrawUiPopover.tsx +4 -2
  423. package/src/lib/ui/components/primitives/TldrawUiSlider.tsx +52 -32
  424. package/src/lib/ui/components/primitives/TldrawUiToolbar.tsx +35 -9
  425. package/src/lib/ui/components/primitives/TldrawUiTooltip.tsx +232 -180
  426. package/src/lib/ui/components/primitives/layout.tsx +107 -0
  427. package/src/lib/ui/components/primitives/menus/TldrawUiMenuContext.tsx +0 -1
  428. package/src/lib/ui/components/primitives/menus/TldrawUiMenuGroup.tsx +29 -16
  429. package/src/lib/ui/components/primitives/menus/TldrawUiMenuItem.tsx +221 -19
  430. package/src/lib/ui/context/actions.tsx +23 -10
  431. package/src/lib/ui/context/components.tsx +3 -0
  432. package/src/lib/ui/context/events.tsx +2 -1
  433. package/src/lib/ui/hooks/useClipboardEvents.ts +2 -2
  434. package/src/lib/ui/hooks/useExportAs.ts +3 -2
  435. package/src/lib/ui/hooks/useTools.tsx +140 -10
  436. package/src/lib/ui/hooks/useTranslation/TLUiTranslationKey.ts +2 -0
  437. package/src/lib/ui/hooks/useTranslation/defaultTranslation.ts +4 -2
  438. package/src/lib/ui/kbd-utils.ts +10 -3
  439. package/src/lib/ui/version.ts +3 -3
  440. package/src/lib/ui.css +381 -306
  441. package/src/lib/utils/excalidraw/__snapshots__/putExcalidrawContent.test.tsx.snap +5 -5
  442. package/src/lib/utils/excalidraw/putExcalidrawContent.ts +6 -6
  443. package/src/lib/utils/export/copyAs.ts +1 -24
  444. package/src/lib/utils/export/export.ts +0 -36
  445. package/src/lib/utils/export/exportAs.ts +1 -32
  446. package/src/lib/utils/tldr/__snapshots__/buildFromV1Document.test.ts.snap +4 -4
  447. package/src/test/A11y.test.tsx +3 -2
  448. package/src/test/ClickManager.test.ts +7 -6
  449. package/src/test/Editor.test.tsx +55 -27
  450. package/src/test/EraserTool.test.ts +184 -13
  451. package/src/test/HandTool.test.ts +10 -9
  452. package/src/test/HighlightShape.test.ts +2 -1
  453. package/src/test/SelectTool.test.ts +3 -2
  454. package/src/test/TLUserPreferences.test.ts +4 -3
  455. package/src/test/TestEditor.ts +13 -15
  456. package/src/test/TldrawEditor.test.tsx +26 -19
  457. package/src/test/ZoomTool.test.ts +7 -6
  458. package/src/test/__snapshots__/drawing.test.ts.snap +2 -2
  459. package/src/test/__snapshots__/groups.test.tsx.snap +6 -6
  460. package/src/test/__snapshots__/resizing.test.ts.snap +2 -2
  461. package/src/test/arrows-megabus.test.tsx +5 -4
  462. package/src/test/bindings.test.tsx +24 -37
  463. package/src/test/bookmark-shapes.test.ts +1 -8
  464. package/src/test/commands/__snapshots__/getSvgString.test.ts.snap +23 -7
  465. package/src/test/commands/__snapshots__/packShapes.test.ts.snap +8 -8
  466. package/src/test/commands/__snapshots__/zoomToFit.test.ts.snap +2 -2
  467. package/src/test/commands/alignShapes.test.tsx +25 -24
  468. package/src/test/commands/animationSpeed.test.ts +2 -1
  469. package/src/test/commands/centerOnPoint.test.ts +3 -2
  470. package/src/test/commands/clipboard.test.ts +3 -2
  471. package/src/test/commands/createShapes.test.ts +2 -1
  472. package/src/test/commands/deleteShapes.test.ts +2 -1
  473. package/src/test/commands/distributeShapes.test.tsx +11 -10
  474. package/src/test/commands/getSvgString.test.ts +2 -1
  475. package/src/test/commands/packShapes.test.ts +5 -4
  476. package/src/test/commands/putContent.test.ts +1 -0
  477. package/src/test/commands/resizeShape.test.ts +2 -1
  478. package/src/test/commands/rotateShapes.test.ts +7 -6
  479. package/src/test/commands/setCamera.test.ts +4 -3
  480. package/src/test/commands/setCurrentPage.test.ts +3 -2
  481. package/src/test/commands/stackShapes.test.ts +11 -10
  482. package/src/test/commands/stretch.test.tsx +13 -12
  483. package/src/test/commands/updateShapes.test.ts +9 -5
  484. package/src/test/createDeepLink.test.tsx +2 -1
  485. package/src/test/cropping.test.ts +3 -2
  486. package/src/test/custom-clipping.test.ts +442 -0
  487. package/src/test/customSnapping.test.tsx +55 -41
  488. package/src/test/drawing.test.ts +2 -1
  489. package/src/test/flipShapes.test.ts +4 -3
  490. package/src/test/frames.test.ts +25 -24
  491. package/src/test/getCulledShapes.test.tsx +80 -4
  492. package/src/test/groups.test.tsx +5 -3
  493. package/src/test/handleDeepLink.test.tsx +2 -1
  494. package/src/test/maxShapes.test.ts +3 -2
  495. package/src/test/modifiers.test.ts +5 -4
  496. package/src/test/navigation.test.ts +12 -11
  497. package/src/test/panning.test.ts +2 -1
  498. package/src/test/perf/perf.test.ts +2 -1
  499. package/src/test/registerDeepLinkListener.test.tsx +10 -9
  500. package/src/test/resizing.test.ts +39 -38
  501. package/src/test/select.test.tsx +4 -3
  502. package/src/test/selection-omnibus.test.ts +11 -10
  503. package/src/test/shapeutils.test.ts +4 -3
  504. package/src/test/translating.test.ts +11 -10
  505. package/tldraw.css +689 -598
  506. package/dist-cjs/lib/ui/components/FollowingIndicator.js.map +0 -7
  507. package/dist-cjs/lib/ui/components/StylePanel/DoubleDropdownPicker.js.map +0 -7
  508. package/dist-cjs/lib/ui/components/StylePanel/DropdownPicker.js.map +0 -7
  509. package/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js.map +0 -7
  510. package/dist-esm/lib/ui/components/FollowingIndicator.mjs.map +0 -7
  511. package/dist-esm/lib/ui/components/StylePanel/DoubleDropdownPicker.mjs.map +0 -7
  512. package/dist-esm/lib/ui/components/StylePanel/DropdownPicker.mjs.map +0 -7
  513. package/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs +0 -115
  514. package/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs.map +0 -7
  515. package/src/lib/ui/components/StylePanel/DropdownPicker.tsx +0 -109
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/shapes/shared/PlainTextLabel.tsx"],
4
- "sourcesContent": ["import {\n\tBox,\n\tTLDefaultFillStyle,\n\tTLDefaultFontStyle,\n\tTLDefaultHorizontalAlignStyle,\n\tTLDefaultVerticalAlignStyle,\n\tTLShapeId,\n} from '@tldraw/editor'\nimport React from 'react'\nimport { PlainTextArea } from '../text/PlainTextArea'\nimport { TextHelpers } from './TextHelpers'\nimport { isLegacyAlign } from './legacyProps'\nimport { useEditablePlainText } from './useEditablePlainText'\n\n/** @public */\nexport interface PlainTextLabelProps {\n\tshapeId: TLShapeId\n\ttype: string\n\tfont: TLDefaultFontStyle\n\tfontSize: number\n\tlineHeight: number\n\tfill?: TLDefaultFillStyle\n\talign: TLDefaultHorizontalAlignStyle\n\tverticalAlign: TLDefaultVerticalAlignStyle\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}\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\tfont,\n\tfontSize,\n\tlineHeight,\n\talign,\n\tverticalAlign,\n\twrap,\n\tisSelected,\n\tpadding = 0,\n\tonKeyDown: handleKeyDownCustom,\n\tclassNamePrefix,\n\tstyle,\n\ttextWidth,\n\ttextHeight,\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(align)\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-font={font}\n\t\t\tdata-align={align}\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\tjustifyContent: align === 'middle' || legacyAlign ? 'center' : align,\n\t\t\t\talignItems: verticalAlign === 'middle' ? 'center' : verticalAlign,\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{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\n/**\n * @deprecated Use `PlainTextLabel` instead.\n * @public\n */\nexport const TextLabel = PlainTextLabel\n"],
5
- "mappings": "AAkGG,SAcG,KAdH;AA1FH,OAAO,WAAW;AAClB,SAAS,qBAAqB;AAC9B,SAAS,mBAAmB;AAC5B,SAAS,qBAAqB;AAC9B,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;AACD,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,KAAK;AAEvC,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,aAAW;AAAA,MACX,cAAY;AAAA,MACZ,gBAAc,CAAC;AAAA,MACf,kBAAgB;AAAA,MAChB,6BAA2B;AAAA,MAC3B,iBAAe,CAAC,CAAC;AAAA,MACjB,mBAAiB;AAAA,MACjB,OAAO;AAAA,QACN,gBAAgB,UAAU,YAAY,cAAc,WAAW;AAAA,QAC/D,YAAY,kBAAkB,WAAW,WAAW;AAAA,QACpD;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,gCAAC,SAAI,WAAW,GAAG,SAAS,4BAA4B,KAAI,QAC1D,yBAAe,MAAM,IAAI,EAAE,IAAI,CAAC,YAAY,UAC5C,oBAAC,SAAgB,KAAI,QACnB,wBADQ,KAEV,CACA,GACF;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;AAMM,MAAM,YAAY;",
4
+ "sourcesContent": ["import {\n\tBox,\n\tTLDefaultFillStyle,\n\tTLDefaultFontStyle,\n\tTLDefaultHorizontalAlignStyle,\n\tTLDefaultVerticalAlignStyle,\n\tTLShape,\n\tTLShapeId,\n} from '@tldraw/editor'\nimport React from 'react'\nimport { PlainTextArea } from '../text/PlainTextArea'\nimport { TextHelpers } from './TextHelpers'\nimport { isLegacyAlign } from './legacyProps'\nimport { useEditablePlainText } from './useEditablePlainText'\n\n/** @public */\nexport interface PlainTextLabelProps {\n\tshapeId: TLShapeId\n\ttype: Extract<TLShape, { props: { text: string } }>['type']\n\tfont: TLDefaultFontStyle\n\tfontSize: number\n\tlineHeight: number\n\tfill?: TLDefaultFillStyle\n\talign: TLDefaultHorizontalAlignStyle\n\tverticalAlign: TLDefaultVerticalAlignStyle\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}\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\tfont,\n\tfontSize,\n\tlineHeight,\n\talign,\n\tverticalAlign,\n\twrap,\n\tisSelected,\n\tpadding = 0,\n\tonKeyDown: handleKeyDownCustom,\n\tclassNamePrefix,\n\tstyle,\n\ttextWidth,\n\ttextHeight,\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(align)\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-font={font}\n\t\t\tdata-align={align}\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\tjustifyContent: align === 'middle' || legacyAlign ? 'center' : align,\n\t\t\t\talignItems: verticalAlign === 'middle' ? 'center' : verticalAlign,\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{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": "AAmGG,SAcG,KAdH;AA1FH,OAAO,WAAW;AAClB,SAAS,qBAAqB;AAC9B,SAAS,mBAAmB;AAC5B,SAAS,qBAAqB;AAC9B,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;AACD,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,KAAK;AAEvC,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,aAAW;AAAA,MACX,cAAY;AAAA,MACZ,gBAAc,CAAC;AAAA,MACf,kBAAgB;AAAA,MAChB,6BAA2B;AAAA,MAC3B,iBAAe,CAAC,CAAC;AAAA,MACjB,mBAAiB;AAAA,MACjB,OAAO;AAAA,QACN,gBAAgB,UAAU,YAAY,cAAc,WAAW;AAAA,QAC/D,YAAY,kBAAkB,WAAW,WAAW;AAAA,QACpD;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,gCAAC,SAAI,WAAW,GAAG,SAAS,4BAA4B,KAAI,QAC1D,yBAAe,MAAM,IAAI,EAAE,IAAI,CAAC,YAAY,UAC5C,oBAAC,SAAgB,KAAI,QACnB,wBADQ,KAEV,CACA,GACF;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
  }
@@ -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\tDefaultFontFamilies,\n\tTLDefaultFillStyle,\n\tTLDefaultFontStyle,\n\tTLDefaultHorizontalAlignStyle,\n\tTLDefaultVerticalAlignStyle,\n\tTLEventInfo,\n\tTLRichText,\n\tTLShapeId,\n\tpreventDefault,\n\tuseEditor,\n\tuseReactor,\n\tuseValue,\n} from '@tldraw/editor'\nimport React, { useMemo } from 'react'\nimport { renderHtmlFromRichText } from '../../utils/text/richText'\nimport { RichTextArea } from '../text/RichTextArea'\nimport { TEXT_PROPS } from './default-shape-constants'\nimport { isLegacyAlign } from './legacyProps'\nimport { useEditableRichText } from './useEditableRichText'\n\n/** @public */\nexport interface RichTextLabelProps {\n\tshapeId: TLShapeId\n\ttype: string\n\tfont: TLDefaultFontStyle\n\tfontSize: number\n\tlineHeight: number\n\tfill?: TLDefaultFillStyle\n\talign: TLDefaultHorizontalAlignStyle\n\tverticalAlign: TLDefaultVerticalAlignStyle\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}\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\tfont,\n\tfontSize,\n\tlineHeight,\n\talign,\n\tverticalAlign,\n\twrap,\n\tisSelected,\n\tpadding = 0,\n\tonKeyDown: handleKeyDownCustom,\n\tclassNamePrefix,\n\tstyle,\n\ttextWidth,\n\ttextHeight,\n\thasCustomTabBehavior,\n}: RichTextLabelProps) {\n\tconst editor = useEditor()\n\tconst isDragging = React.useRef(false)\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}, [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.isDragging\n\t\t},\n\t\t[editor]\n\t)\n\n\tconst legacyAlign = isLegacyAlign(align)\n\n\tconst handlePointerDown = (e: React.MouseEvent<HTMLDivElement>) => {\n\t\tif (e.target instanceof HTMLElement && (e.target.tagName === 'A' || e.target.closest('a'))) {\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') return\n\n\t\t\t\tif (!isDragging.current) {\n\t\t\t\t\twindow.open(link, '_blank', 'noopener, noreferrer')\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={`${cssPrefix}-label tl-text-wrapper tl-rich-text-wrapper`}\n\t\t\taria-hidden={!isEditing}\n\t\t\tdata-font={font}\n\t\t\tdata-align={align}\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\tjustifyContent: align === 'middle' || legacyAlign ? 'center' : align,\n\t\t\t\talignItems: verticalAlign === 'middle' ? 'center' : verticalAlign,\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\tfont: TLDefaultFontStyle\n\talign: TLDefaultHorizontalAlignStyle\n\tverticalAlign: TLDefaultVerticalAlignStyle\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\tfont,\n\talign,\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 textAlign =\n\t\talign === 'middle'\n\t\t\t? ('center' as const)\n\t\t\t: align === 'start'\n\t\t\t\t? ('start' as const)\n\t\t\t\t: ('end' as const)\n\tconst justifyContent =\n\t\talign === 'middle'\n\t\t\t? ('center' as const)\n\t\t\t: align === '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: DefaultFontFamilies[font],\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: TEXT_PROPS.lineHeight,\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}\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=\"tl-export-embed-styles tl-rich-text tl-rich-text-svg\"\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\tDefaultFontFamilies,\n\tTLDefaultFillStyle,\n\tTLDefaultFontStyle,\n\tTLDefaultHorizontalAlignStyle,\n\tTLDefaultVerticalAlignStyle,\n\tTLEventInfo,\n\tTLRichText,\n\tTLShape,\n\tTLShapeId,\n\tpreventDefault,\n\tuseEditor,\n\tuseReactor,\n\tuseValue,\n} from '@tldraw/editor'\nimport React, { useMemo } from 'react'\nimport { renderHtmlFromRichText } from '../../utils/text/richText'\nimport { RichTextArea } from '../text/RichTextArea'\nimport { TEXT_PROPS } from './default-shape-constants'\nimport { isLegacyAlign } from './legacyProps'\nimport { useEditableRichText } from './useEditableRichText'\n\n/** @public */\nexport interface RichTextLabelProps {\n\tshapeId: TLShapeId\n\ttype: Extract<TLShape, { props: { richText: TLRichText } }>['type']\n\tfont: TLDefaultFontStyle\n\tfontSize: number\n\tlineHeight: number\n\tfill?: TLDefaultFillStyle\n\talign: TLDefaultHorizontalAlignStyle\n\tverticalAlign: TLDefaultVerticalAlignStyle\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}\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\tfont,\n\tfontSize,\n\tlineHeight,\n\talign,\n\tverticalAlign,\n\twrap,\n\tisSelected,\n\tpadding = 0,\n\tonKeyDown: handleKeyDownCustom,\n\tclassNamePrefix,\n\tstyle,\n\ttextWidth,\n\ttextHeight,\n\thasCustomTabBehavior,\n}: RichTextLabelProps) {\n\tconst editor = useEditor()\n\tconst isDragging = React.useRef(false)\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}, [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.isDragging\n\t\t},\n\t\t[editor]\n\t)\n\n\tconst legacyAlign = isLegacyAlign(align)\n\n\tconst handlePointerDown = (e: React.MouseEvent<HTMLDivElement>) => {\n\t\tif (e.target instanceof HTMLElement && (e.target.tagName === 'A' || e.target.closest('a'))) {\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') return\n\n\t\t\t\tif (!isDragging.current) {\n\t\t\t\t\twindow.open(link, '_blank', 'noopener, noreferrer')\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={`${cssPrefix}-label tl-text-wrapper tl-rich-text-wrapper`}\n\t\t\taria-hidden={!isEditing}\n\t\t\tdata-font={font}\n\t\t\tdata-align={align}\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\tjustifyContent: align === 'middle' || legacyAlign ? 'center' : align,\n\t\t\t\talignItems: verticalAlign === 'middle' ? 'center' : verticalAlign,\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\tfont: TLDefaultFontStyle\n\talign: TLDefaultHorizontalAlignStyle\n\tverticalAlign: TLDefaultVerticalAlignStyle\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\tfont,\n\talign,\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 textAlign =\n\t\talign === 'middle'\n\t\t\t? ('center' as const)\n\t\t\t: align === 'start'\n\t\t\t\t? ('start' as const)\n\t\t\t\t: ('end' as const)\n\tconst justifyContent =\n\t\talign === 'middle'\n\t\t\t? ('center' as const)\n\t\t\t: align === '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: DefaultFontFamilies[font],\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: TEXT_PROPS.lineHeight,\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}\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=\"tl-export-embed-styles tl-rich-text tl-rich-text-svg\"\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
  }
@@ -1,5 +1,6 @@
1
1
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
2
  import {
3
+ getColorValue,
3
4
  useEditor,
4
5
  useSvgExportContext,
5
6
  useValue
@@ -18,13 +19,13 @@ const ShapeFill = React.memo(function ShapeFill2({
18
19
  return null;
19
20
  }
20
21
  case "solid": {
21
- return /* @__PURE__ */ jsx("path", { fill: theme[color].semi, d });
22
+ return /* @__PURE__ */ jsx("path", { fill: getColorValue(theme, color, "semi"), d });
22
23
  }
23
24
  case "semi": {
24
25
  return /* @__PURE__ */ jsx("path", { fill: theme.solid, d });
25
26
  }
26
27
  case "fill": {
27
- return /* @__PURE__ */ jsx("path", { fill: theme[color].fill, d });
28
+ return /* @__PURE__ */ jsx("path", { fill: getColorValue(theme, color, "fill"), d });
28
29
  }
29
30
  case "pattern": {
30
31
  return /* @__PURE__ */ jsx(PatternFill, { theme, color, fill, d, scale });
@@ -38,11 +39,11 @@ function PatternFill({ d, color, theme }) {
38
39
  const getHashPatternZoomName = useGetHashPatternZoomName();
39
40
  const teenyTiny = editor.getZoomLevel() <= 0.18;
40
41
  return /* @__PURE__ */ jsxs(Fragment, { children: [
41
- /* @__PURE__ */ jsx("path", { fill: theme[color].pattern, d }),
42
+ /* @__PURE__ */ jsx("path", { fill: getColorValue(theme, color, "pattern"), d }),
42
43
  /* @__PURE__ */ jsx(
43
44
  "path",
44
45
  {
45
- fill: svgExport ? `url(#${getHashPatternZoomName(1, theme.id)})` : teenyTiny ? theme[color].semi : `url(#${getHashPatternZoomName(zoomLevel, theme.id)})`,
46
+ fill: svgExport ? `url(#${getHashPatternZoomName(1, theme.id)})` : teenyTiny ? getColorValue(theme, color, "semi") : `url(#${getHashPatternZoomName(zoomLevel, theme.id)})`,
46
47
  d
47
48
  }
48
49
  )
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/shapes/shared/ShapeFill.tsx"],
4
- "sourcesContent": ["import {\n\tTLDefaultColorStyle,\n\tTLDefaultColorTheme,\n\tTLDefaultFillStyle,\n\tuseEditor,\n\tuseSvgExportContext,\n\tuseValue,\n} from '@tldraw/editor'\nimport React from 'react'\nimport { useGetHashPatternZoomName } from './defaultStyleDefs'\n\ninterface ShapeFillProps {\n\td: string\n\tfill: TLDefaultFillStyle\n\tcolor: TLDefaultColorStyle\n\ttheme: TLDefaultColorTheme\n\tscale: number\n}\n\nexport const ShapeFill = React.memo(function ShapeFill({\n\ttheme,\n\td,\n\tcolor,\n\tfill,\n\tscale,\n}: ShapeFillProps) {\n\tswitch (fill) {\n\t\tcase 'none': {\n\t\t\treturn null\n\t\t}\n\t\tcase 'solid': {\n\t\t\treturn <path fill={theme[color].semi} d={d} />\n\t\t}\n\t\tcase 'semi': {\n\t\t\treturn <path fill={theme.solid} d={d} />\n\t\t}\n\t\tcase 'fill': {\n\t\t\treturn <path fill={theme[color].fill} d={d} />\n\t\t}\n\t\tcase 'pattern': {\n\t\t\treturn <PatternFill theme={theme} color={color} fill={fill} d={d} scale={scale} />\n\t\t}\n\t}\n})\n\nexport function PatternFill({ d, color, theme }: ShapeFillProps) {\n\tconst editor = useEditor()\n\tconst svgExport = useSvgExportContext()\n\tconst zoomLevel = useValue('zoomLevel', () => editor.getZoomLevel(), [editor])\n\tconst getHashPatternZoomName = useGetHashPatternZoomName()\n\n\tconst teenyTiny = editor.getZoomLevel() <= 0.18\n\n\treturn (\n\t\t<>\n\t\t\t<path fill={theme[color].pattern} d={d} />\n\t\t\t<path\n\t\t\t\tfill={\n\t\t\t\t\tsvgExport\n\t\t\t\t\t\t? `url(#${getHashPatternZoomName(1, theme.id)})`\n\t\t\t\t\t\t: teenyTiny\n\t\t\t\t\t\t\t? theme[color].semi\n\t\t\t\t\t\t\t: `url(#${getHashPatternZoomName(zoomLevel, theme.id)})`\n\t\t\t\t}\n\t\t\t\td={d}\n\t\t\t/>\n\t\t</>\n\t)\n}\n"],
5
- "mappings": "AA+BU,SAuBR,UAvBQ,KAuBR,YAvBQ;AA/BV;AAAA,EAIC;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,OAAO,WAAW;AAClB,SAAS,iCAAiC;AAUnC,MAAM,YAAY,MAAM,KAAK,SAASA,WAAU;AAAA,EACtD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,GAAmB;AAClB,UAAQ,MAAM;AAAA,IACb,KAAK,QAAQ;AACZ,aAAO;AAAA,IACR;AAAA,IACA,KAAK,SAAS;AACb,aAAO,oBAAC,UAAK,MAAM,MAAM,KAAK,EAAE,MAAM,GAAM;AAAA,IAC7C;AAAA,IACA,KAAK,QAAQ;AACZ,aAAO,oBAAC,UAAK,MAAM,MAAM,OAAO,GAAM;AAAA,IACvC;AAAA,IACA,KAAK,QAAQ;AACZ,aAAO,oBAAC,UAAK,MAAM,MAAM,KAAK,EAAE,MAAM,GAAM;AAAA,IAC7C;AAAA,IACA,KAAK,WAAW;AACf,aAAO,oBAAC,eAAY,OAAc,OAAc,MAAY,GAAM,OAAc;AAAA,IACjF;AAAA,EACD;AACD,CAAC;AAEM,SAAS,YAAY,EAAE,GAAG,OAAO,MAAM,GAAmB;AAChE,QAAM,SAAS,UAAU;AACzB,QAAM,YAAY,oBAAoB;AACtC,QAAM,YAAY,SAAS,aAAa,MAAM,OAAO,aAAa,GAAG,CAAC,MAAM,CAAC;AAC7E,QAAM,yBAAyB,0BAA0B;AAEzD,QAAM,YAAY,OAAO,aAAa,KAAK;AAE3C,SACC,iCACC;AAAA,wBAAC,UAAK,MAAM,MAAM,KAAK,EAAE,SAAS,GAAM;AAAA,IACxC;AAAA,MAAC;AAAA;AAAA,QACA,MACC,YACG,QAAQ,uBAAuB,GAAG,MAAM,EAAE,CAAC,MAC3C,YACC,MAAM,KAAK,EAAE,OACb,QAAQ,uBAAuB,WAAW,MAAM,EAAE,CAAC;AAAA,QAExD;AAAA;AAAA,IACD;AAAA,KACD;AAEF;",
4
+ "sourcesContent": ["import {\n\tgetColorValue,\n\tTLDefaultColorStyle,\n\tTLDefaultColorTheme,\n\tTLDefaultFillStyle,\n\tuseEditor,\n\tuseSvgExportContext,\n\tuseValue,\n} from '@tldraw/editor'\nimport React from 'react'\nimport { useGetHashPatternZoomName } from './defaultStyleDefs'\n\ninterface ShapeFillProps {\n\td: string\n\tfill: TLDefaultFillStyle\n\tcolor: TLDefaultColorStyle\n\ttheme: TLDefaultColorTheme\n\tscale: number\n}\n\nexport const ShapeFill = React.memo(function ShapeFill({\n\ttheme,\n\td,\n\tcolor,\n\tfill,\n\tscale,\n}: ShapeFillProps) {\n\tswitch (fill) {\n\t\tcase 'none': {\n\t\t\treturn null\n\t\t}\n\t\tcase 'solid': {\n\t\t\treturn <path fill={getColorValue(theme, color, 'semi')} d={d} />\n\t\t}\n\t\tcase 'semi': {\n\t\t\treturn <path fill={theme.solid} d={d} />\n\t\t}\n\t\tcase 'fill': {\n\t\t\treturn <path fill={getColorValue(theme, color, 'fill')} d={d} />\n\t\t}\n\t\tcase 'pattern': {\n\t\t\treturn <PatternFill theme={theme} color={color} fill={fill} d={d} scale={scale} />\n\t\t}\n\t}\n})\n\nexport function PatternFill({ d, color, theme }: ShapeFillProps) {\n\tconst editor = useEditor()\n\tconst svgExport = useSvgExportContext()\n\tconst zoomLevel = useValue('zoomLevel', () => editor.getZoomLevel(), [editor])\n\tconst getHashPatternZoomName = useGetHashPatternZoomName()\n\n\tconst teenyTiny = editor.getZoomLevel() <= 0.18\n\n\treturn (\n\t\t<>\n\t\t\t<path fill={getColorValue(theme, color, 'pattern')} d={d} />\n\t\t\t<path\n\t\t\t\tfill={\n\t\t\t\t\tsvgExport\n\t\t\t\t\t\t? `url(#${getHashPatternZoomName(1, theme.id)})`\n\t\t\t\t\t\t: teenyTiny\n\t\t\t\t\t\t\t? getColorValue(theme, color, 'semi')\n\t\t\t\t\t\t\t: `url(#${getHashPatternZoomName(zoomLevel, theme.id)})`\n\t\t\t\t}\n\t\t\t\td={d}\n\t\t\t/>\n\t\t</>\n\t)\n}\n"],
5
+ "mappings": "AAgCU,SAuBR,UAvBQ,KAuBR,YAvBQ;AAhCV;AAAA,EACC;AAAA,EAIA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,OAAO,WAAW;AAClB,SAAS,iCAAiC;AAUnC,MAAM,YAAY,MAAM,KAAK,SAASA,WAAU;AAAA,EACtD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,GAAmB;AAClB,UAAQ,MAAM;AAAA,IACb,KAAK,QAAQ;AACZ,aAAO;AAAA,IACR;AAAA,IACA,KAAK,SAAS;AACb,aAAO,oBAAC,UAAK,MAAM,cAAc,OAAO,OAAO,MAAM,GAAG,GAAM;AAAA,IAC/D;AAAA,IACA,KAAK,QAAQ;AACZ,aAAO,oBAAC,UAAK,MAAM,MAAM,OAAO,GAAM;AAAA,IACvC;AAAA,IACA,KAAK,QAAQ;AACZ,aAAO,oBAAC,UAAK,MAAM,cAAc,OAAO,OAAO,MAAM,GAAG,GAAM;AAAA,IAC/D;AAAA,IACA,KAAK,WAAW;AACf,aAAO,oBAAC,eAAY,OAAc,OAAc,MAAY,GAAM,OAAc;AAAA,IACjF;AAAA,EACD;AACD,CAAC;AAEM,SAAS,YAAY,EAAE,GAAG,OAAO,MAAM,GAAmB;AAChE,QAAM,SAAS,UAAU;AACzB,QAAM,YAAY,oBAAoB;AACtC,QAAM,YAAY,SAAS,aAAa,MAAM,OAAO,aAAa,GAAG,CAAC,MAAM,CAAC;AAC7E,QAAM,yBAAyB,0BAA0B;AAEzD,QAAM,YAAY,OAAO,aAAa,KAAK;AAE3C,SACC,iCACC;AAAA,wBAAC,UAAK,MAAM,cAAc,OAAO,OAAO,SAAS,GAAG,GAAM;AAAA,IAC1D;AAAA,MAAC;AAAA;AAAA,QACA,MACC,YACG,QAAQ,uBAAuB,GAAG,MAAM,EAAE,CAAC,MAC3C,YACC,cAAc,OAAO,OAAO,MAAM,IAClC,QAAQ,uBAAuB,WAAW,MAAM,EAAE,CAAC;AAAA,QAExD;AAAA;AAAA,IACD;AAAA,KACD;AAEF;",
6
6
  "names": ["ShapeFill"]
7
7
  }
@@ -243,6 +243,7 @@ function getCropBox(shape, info, opts = {}) {
243
243
  x: newPoint.x,
244
244
  y: newPoint.y,
245
245
  props: {
246
+ ...shape.props,
246
247
  w: tempBox.w,
247
248
  h: tempBox.h,
248
249
  crop: newCrop
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/shapes/shared/crop.ts"],
4
- "sourcesContent": ["import {\n\tBox,\n\tShapeWithCrop,\n\tTLCropInfo,\n\tTLImageShape,\n\tTLShapeCrop,\n\tTLShapeId,\n\tVec,\n\tclamp,\n\tisEqual,\n} from '@tldraw/editor'\n\n/** @internal */\nexport const MIN_CROP_SIZE = 8\n\n/** @public */\nexport interface CropBoxOptions {\n\tminWidth?: number\n\tminHeight?: number\n}\n\n/** @public */\nexport function getDefaultCrop(): TLShapeCrop {\n\treturn {\n\t\ttopLeft: { x: 0, y: 0 },\n\t\tbottomRight: { x: 1, y: 1 },\n\t}\n}\n\n/** @public */\nexport type ASPECT_RATIO_OPTION =\n\t| 'original'\n\t| 'square'\n\t| 'circle'\n\t| 'landscape'\n\t| 'portrait'\n\t| 'wide'\n\n/** @public */\nexport const ASPECT_RATIO_OPTIONS: ASPECT_RATIO_OPTION[] = [\n\t'original',\n\t'square',\n\t'circle',\n\t'landscape',\n\t'portrait',\n\t'wide',\n]\n\n/** @public */\nexport const ASPECT_RATIO_TO_VALUE: Record<ASPECT_RATIO_OPTION, number> = {\n\toriginal: 0,\n\tsquare: 1,\n\tcircle: 1,\n\tlandscape: 4 / 3,\n\tportrait: 3 / 4,\n\twide: 16 / 9,\n}\n\n/**\n * Original (uncropped) width and height of shape.\n *\n * @public\n */\nexport function getUncroppedSize(\n\tshapeSize: { w: number; h: number },\n\tcrop: TLShapeCrop | null\n): { w: number; h: number } {\n\tif (!crop) return { w: shapeSize.w, h: shapeSize.h }\n\tconst w = shapeSize.w / (crop.bottomRight.x - crop.topLeft.x)\n\tconst h = shapeSize.h / (crop.bottomRight.y - crop.topLeft.y)\n\treturn { w, h }\n}\n\n// Utility function to get crop dimensions\nfunction getCropDimensions(crop: TLShapeCrop) {\n\treturn {\n\t\twidth: crop.bottomRight.x - crop.topLeft.x,\n\t\theight: crop.bottomRight.y - crop.topLeft.y,\n\t}\n}\n\n// Utility function to get crop center\nfunction getCropCenter(crop: TLShapeCrop) {\n\tconst { width, height } = getCropDimensions(crop)\n\treturn {\n\t\tx: crop.topLeft.x + width / 2,\n\t\ty: crop.topLeft.y + height / 2,\n\t}\n}\n\n// Utility function to create crop with specified dimensions centered on given point\nfunction createCropAroundCenter(\n\tcenterX: number,\n\tcenterY: number,\n\twidth: number,\n\theight: number,\n\tisCircle?: boolean\n) {\n\tconst topLeftX = Math.max(0, Math.min(1 - width, centerX - width / 2))\n\tconst topLeftY = Math.max(0, Math.min(1 - height, centerY - height / 2))\n\n\treturn {\n\t\ttopLeft: { x: topLeftX, y: topLeftY },\n\t\tbottomRight: { x: topLeftX + width, y: topLeftY + height },\n\t\tisCircle,\n\t}\n}\n\n/** @public */\nexport function getCropBox<T extends ShapeWithCrop>(\n\tshape: T,\n\tinfo: TLCropInfo<T>,\n\topts = {} as CropBoxOptions\n):\n\t| {\n\t\t\tid: TLShapeId\n\t\t\ttype: T['type']\n\t\t\tx: number\n\t\t\ty: number\n\t\t\tprops: ShapeWithCrop['props']\n\t }\n\t| undefined {\n\tconst { handle, change, crop, aspectRatioLocked } = info\n\tconst { w, h } = info.uncroppedSize\n\tconst { minWidth = MIN_CROP_SIZE, minHeight = MIN_CROP_SIZE } = opts\n\n\tif (w < minWidth || h < minHeight || (change.x === 0 && change.y === 0)) {\n\t\treturn\n\t}\n\n\t// Lets get a box here in pixel space. For simplicity, we'll do all the math in\n\t// pixel space, then convert to normalized space at the end.\n\tconst prevCropBox = new Box(\n\t\tcrop.topLeft.x * w,\n\t\tcrop.topLeft.y * h,\n\t\t(crop.bottomRight.x - crop.topLeft.x) * w,\n\t\t(crop.bottomRight.y - crop.topLeft.y) * h\n\t)\n\n\tconst targetRatio = prevCropBox.aspectRatio\n\tconst tempBox = prevCropBox.clone()\n\n\t// Basic resizing logic based on the handles\n\n\tif (handle === 'top_left' || handle === 'bottom_left' || handle === 'left') {\n\t\ttempBox.x = clamp(tempBox.x + change.x, 0, prevCropBox.maxX - minWidth)\n\t\ttempBox.w = prevCropBox.maxX - tempBox.x\n\t} else if (handle === 'top_right' || handle === 'bottom_right' || handle === 'right') {\n\t\tconst tempRight = clamp(tempBox.maxX + change.x, prevCropBox.x + minWidth, w)\n\t\ttempBox.w = tempRight - tempBox.x\n\t}\n\n\tif (handle === 'top_left' || handle === 'top_right' || handle === 'top') {\n\t\ttempBox.y = clamp(tempBox.y + change.y, 0, prevCropBox.maxY - minHeight)\n\t\ttempBox.h = prevCropBox.maxY - tempBox.y\n\t} else if (handle === 'bottom_left' || handle === 'bottom_right' || handle === 'bottom') {\n\t\tconst tempBottom = clamp(tempBox.maxY + change.y, prevCropBox.y + minHeight, h)\n\t\ttempBox.h = tempBottom - tempBox.y\n\t}\n\n\t// Aspect ratio locked resizing logic\n\n\tif (aspectRatioLocked) {\n\t\tconst isXLimiting = tempBox.aspectRatio > targetRatio\n\n\t\tif (isXLimiting) {\n\t\t\ttempBox.h = tempBox.w / targetRatio\n\t\t} else {\n\t\t\ttempBox.w = tempBox.h * targetRatio\n\t\t}\n\n\t\tswitch (handle) {\n\t\t\tcase 'top_left': {\n\t\t\t\t// preserve the bottom right corner\n\t\t\t\ttempBox.x = prevCropBox.maxX - tempBox.w\n\t\t\t\ttempBox.y = prevCropBox.maxY - tempBox.h\n\n\t\t\t\tif (tempBox.x <= 0) {\n\t\t\t\t\ttempBox.x = 0\n\t\t\t\t\ttempBox.w = prevCropBox.maxX - tempBox.x\n\t\t\t\t\ttempBox.h = tempBox.w / targetRatio\n\t\t\t\t\ttempBox.y = prevCropBox.maxY - tempBox.h\n\t\t\t\t}\n\n\t\t\t\tif (tempBox.y <= 0) {\n\t\t\t\t\ttempBox.y = 0\n\t\t\t\t\ttempBox.h = prevCropBox.maxY - tempBox.y\n\t\t\t\t\ttempBox.w = tempBox.h * targetRatio\n\t\t\t\t\ttempBox.x = prevCropBox.maxX - tempBox.w\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'top_right': {\n\t\t\t\t// preserve the bottom left corner\n\t\t\t\ttempBox.x = prevCropBox.x\n\t\t\t\ttempBox.y = prevCropBox.maxY - tempBox.h\n\n\t\t\t\tif (tempBox.maxX >= w) {\n\t\t\t\t\ttempBox.w = w - prevCropBox.x\n\t\t\t\t\ttempBox.h = tempBox.w / targetRatio\n\t\t\t\t\ttempBox.y = prevCropBox.maxY - tempBox.h\n\t\t\t\t}\n\n\t\t\t\tif (tempBox.y <= 0) {\n\t\t\t\t\ttempBox.y = 0\n\t\t\t\t\ttempBox.h = prevCropBox.maxY - tempBox.y\n\t\t\t\t\ttempBox.w = tempBox.h * targetRatio\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'bottom_left': {\n\t\t\t\t// preserve the top right corner\n\t\t\t\ttempBox.x = prevCropBox.maxX - tempBox.w\n\t\t\t\ttempBox.y = prevCropBox.y\n\n\t\t\t\tif (tempBox.x <= 0) {\n\t\t\t\t\ttempBox.x = 0\n\t\t\t\t\ttempBox.w = prevCropBox.maxX - tempBox.x\n\t\t\t\t\ttempBox.h = tempBox.w / targetRatio\n\t\t\t\t}\n\n\t\t\t\tif (tempBox.maxY >= h) {\n\t\t\t\t\ttempBox.h = h - prevCropBox.y\n\t\t\t\t\ttempBox.w = tempBox.h * targetRatio\n\t\t\t\t\ttempBox.x = prevCropBox.maxX - tempBox.w\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'bottom_right': {\n\t\t\t\t// preserve the top left corner\n\t\t\t\ttempBox.x = prevCropBox.x\n\t\t\t\ttempBox.y = prevCropBox.y\n\n\t\t\t\tif (tempBox.maxX >= w) {\n\t\t\t\t\ttempBox.w = w - prevCropBox.x\n\t\t\t\t\ttempBox.h = tempBox.w / targetRatio\n\t\t\t\t}\n\n\t\t\t\tif (tempBox.maxY >= h) {\n\t\t\t\t\ttempBox.h = h - prevCropBox.y\n\t\t\t\t\ttempBox.w = tempBox.h * targetRatio\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'top': {\n\t\t\t\t// preserve the bottom edge center\n\t\t\t\ttempBox.h = prevCropBox.maxY - tempBox.y\n\t\t\t\ttempBox.w = tempBox.h * targetRatio\n\t\t\t\ttempBox.x -= (tempBox.w - prevCropBox.w) / 2\n\n\t\t\t\tif (tempBox.x <= 0) {\n\t\t\t\t\tconst leftSide = prevCropBox.midX\n\t\t\t\t\ttempBox.w = leftSide * 2\n\t\t\t\t\ttempBox.h = tempBox.w / targetRatio\n\t\t\t\t\ttempBox.x = 0\n\t\t\t\t}\n\n\t\t\t\tif (tempBox.maxX >= w) {\n\t\t\t\t\tconst rightSide = w - prevCropBox.midX\n\t\t\t\t\ttempBox.w = rightSide * 2\n\t\t\t\t\ttempBox.h = tempBox.w / targetRatio\n\t\t\t\t\ttempBox.x = w - tempBox.w\n\t\t\t\t}\n\n\t\t\t\ttempBox.y = prevCropBox.maxY - tempBox.h\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'right': {\n\t\t\t\t// preserve the left edge center\n\t\t\t\ttempBox.w = tempBox.maxX - prevCropBox.x\n\t\t\t\ttempBox.h = tempBox.w / targetRatio\n\t\t\t\ttempBox.y -= (tempBox.h - prevCropBox.h) / 2\n\n\t\t\t\tif (tempBox.y <= 0) {\n\t\t\t\t\tconst topSide = prevCropBox.midY\n\t\t\t\t\ttempBox.h = topSide * 2\n\t\t\t\t\ttempBox.w = tempBox.h * targetRatio\n\t\t\t\t\ttempBox.y = 0\n\t\t\t\t}\n\n\t\t\t\tif (tempBox.maxY >= h) {\n\t\t\t\t\tconst bottomSide = h - prevCropBox.midY\n\t\t\t\t\ttempBox.h = bottomSide * 2\n\t\t\t\t\ttempBox.w = tempBox.h * targetRatio\n\t\t\t\t\ttempBox.y = h - tempBox.h\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'bottom': {\n\t\t\t\t// preserve the top edge center\n\t\t\t\ttempBox.h = tempBox.maxY - prevCropBox.y\n\t\t\t\ttempBox.w = tempBox.h * targetRatio\n\t\t\t\ttempBox.x -= (tempBox.w - prevCropBox.w) / 2\n\n\t\t\t\tif (tempBox.x <= 0) {\n\t\t\t\t\tconst leftSide = prevCropBox.midX\n\t\t\t\t\ttempBox.w = leftSide * 2\n\t\t\t\t\ttempBox.h = tempBox.w / targetRatio\n\t\t\t\t\ttempBox.x = 0\n\t\t\t\t}\n\n\t\t\t\tif (tempBox.maxX >= w) {\n\t\t\t\t\tconst rightSide = w - prevCropBox.midX\n\t\t\t\t\ttempBox.w = rightSide * 2\n\t\t\t\t\ttempBox.h = tempBox.w / targetRatio\n\t\t\t\t\ttempBox.x = w - tempBox.w\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'left': {\n\t\t\t\t// preserve the right edge center\n\t\t\t\ttempBox.w = prevCropBox.maxX - tempBox.x\n\t\t\t\ttempBox.h = tempBox.w / targetRatio\n\t\t\t\ttempBox.y -= (tempBox.h - prevCropBox.h) / 2\n\n\t\t\t\tif (tempBox.y <= 0) {\n\t\t\t\t\tconst topSide = prevCropBox.midY\n\t\t\t\t\ttempBox.h = topSide * 2\n\t\t\t\t\ttempBox.w = tempBox.h * targetRatio\n\t\t\t\t\ttempBox.y = 0\n\t\t\t\t}\n\n\t\t\t\tif (tempBox.maxY >= h) {\n\t\t\t\t\tconst bottomSide = h - prevCropBox.midY\n\t\t\t\t\ttempBox.h = bottomSide * 2\n\t\t\t\t\ttempBox.w = tempBox.h * targetRatio\n\t\t\t\t\ttempBox.y = h - tempBox.h\n\t\t\t\t}\n\n\t\t\t\ttempBox.x = prevCropBox.maxX - tempBox.w\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\t// Convert the box back to normalized space\n\tconst newCrop: TLShapeCrop = {\n\t\ttopLeft: { x: tempBox.x / w, y: tempBox.y / h },\n\t\tbottomRight: { x: tempBox.maxX / w, y: tempBox.maxY / h },\n\t\tisCircle: crop.isCircle,\n\t}\n\n\t// If the crop hasn't changed, we can return early\n\tif (\n\t\tnewCrop.topLeft.x === crop.topLeft.x &&\n\t\tnewCrop.topLeft.y === crop.topLeft.y &&\n\t\tnewCrop.bottomRight.x === crop.bottomRight.x &&\n\t\tnewCrop.bottomRight.y === crop.bottomRight.y\n\t) {\n\t\treturn\n\t}\n\n\t// Adjust the shape's position to keep the crop's absolute coordinates correct\n\tconst newPoint = new Vec(tempBox.x - crop.topLeft.x * w, tempBox.y - crop.topLeft.y * h)\n\t\t.rot(shape.rotation)\n\t\t.add(shape)\n\n\treturn {\n\t\tid: shape.id,\n\t\ttype: shape.type,\n\t\tx: newPoint.x,\n\t\ty: newPoint.y,\n\t\tprops: {\n\t\t\tw: tempBox.w,\n\t\t\th: tempBox.h,\n\t\t\tcrop: newCrop,\n\t\t},\n\t}\n}\n\ninterface CropChange {\n\tcrop: {\n\t\ttopLeft: { x: number; y: number }\n\t\tbottomRight: { x: number; y: number }\n\t\tisCircle?: boolean\n\t}\n\tw: number\n\th: number\n\tx: number\n\ty: number\n}\n\n// Base function for calculating crop changes\nfunction calculateCropChange(\n\timageShape: TLImageShape,\n\tnewCropWidth: number,\n\tnewCropHeight: number,\n\tcenterOnCurrentCrop: boolean = true,\n\tisCircle: boolean = false\n): CropChange {\n\tconst { w, h } = getUncroppedSize(imageShape.props, imageShape.props.crop ?? getDefaultCrop())\n\tconst currentCrop = imageShape.props.crop || getDefaultCrop()\n\n\t// Calculate image and crop centers\n\tconst imageCenterX = imageShape.x + imageShape.props.w / 2\n\tconst imageCenterY = imageShape.y + imageShape.props.h / 2\n\n\tlet cropCenterX, cropCenterY\n\tif (centerOnCurrentCrop) {\n\t\tconst { x, y } = getCropCenter(currentCrop)\n\t\tcropCenterX = x\n\t\tcropCenterY = y\n\t} else {\n\t\tcropCenterX = 0.5\n\t\tcropCenterY = 0.5\n\t}\n\n\t// Create new crop\n\tconst newCrop = createCropAroundCenter(\n\t\tcropCenterX,\n\t\tcropCenterY,\n\t\tnewCropWidth,\n\t\tnewCropHeight,\n\t\tisCircle\n\t)\n\n\t// Calculate new dimensions\n\tconst croppedW = newCropWidth * w\n\tconst croppedH = newCropHeight * h\n\n\treturn {\n\t\tcrop: newCrop,\n\t\tw: croppedW,\n\t\th: croppedH,\n\t\tx: imageCenterX - croppedW / 2,\n\t\ty: imageCenterY - croppedH / 2,\n\t}\n}\n\n/** @internal */\nexport const MAX_ZOOM = 3\n\n/**\n * Calculate new crop dimensions and position when zooming\n */\nexport function getCroppedImageDataWhenZooming(\n\tzoom: number,\n\timageShape: TLImageShape,\n\tmaxZoom?: number\n): CropChange {\n\tconst oldCrop = imageShape.props.crop || getDefaultCrop()\n\tconst { width: oldWidth, height: oldHeight } = getCropDimensions(oldCrop)\n\tconst aspectRatio = oldWidth / oldHeight\n\n\t// Calculate new crop size with zoom scale\n\tconst derivedMaxZoom = maxZoom ? 1 / (1 - maxZoom) : MAX_ZOOM\n\tconst zoomScale = 1 + zoom * (derivedMaxZoom - 1)\n\tlet newWidth, newHeight\n\n\tif (aspectRatio > 1) {\n\t\tnewWidth = Math.min(1, 1 / zoomScale)\n\t\tnewHeight = newWidth / aspectRatio\n\t} else {\n\t\tnewHeight = Math.min(1, 1 / zoomScale)\n\t\tnewWidth = newHeight * aspectRatio\n\t}\n\n\t// Calculate result with base function\n\tconst result = calculateCropChange(imageShape, newWidth, newHeight, true, oldCrop.isCircle)\n\n\t// Apply zoom factor to display dimensions\n\tconst scaleFactor = Math.min(MAX_ZOOM, oldWidth / newWidth)\n\tresult.w *= scaleFactor\n\tresult.h *= scaleFactor\n\n\t// Recenter\n\tconst imageCenterX = imageShape.x + imageShape.props.w / 2\n\tconst imageCenterY = imageShape.y + imageShape.props.h / 2\n\tresult.x = imageCenterX - result.w / 2\n\tresult.y = imageCenterY - result.h / 2\n\n\treturn result\n}\n\n/**\n * Calculate new crop dimensions and position when replacing an image\n */\nexport function getCroppedImageDataForReplacedImage(\n\timageShape: TLImageShape,\n\tnewImageWidth: number,\n\tnewImageHeight: number\n): CropChange {\n\tconst defaultCrop = getDefaultCrop()\n\tconst currentCrop = imageShape.props.crop || defaultCrop\n\tconst origDisplayW = imageShape.props.w\n\tconst origDisplayH = imageShape.props.h\n\tconst newImageAspectRatio = newImageWidth / newImageHeight\n\n\tlet crop = defaultCrop\n\tlet newDisplayW = origDisplayW\n\tlet newDisplayH = origDisplayH\n\tconst isOriginalCrop = isEqual(imageShape.props.crop, defaultCrop)\n\n\tif (isOriginalCrop) {\n\t\tnewDisplayW = origDisplayW\n\t\tnewDisplayH = (origDisplayW * newImageHeight) / newImageWidth\n\t} else {\n\t\tconst { w: uncroppedW, h: uncroppedH } = getUncroppedSize(\n\t\t\timageShape.props,\n\t\t\timageShape.props.crop || getDefaultCrop() // Use the ACTUAL current crop to correctly infer uncropped size\n\t\t)\n\t\tconst { width: cropW, height: cropH } = getCropDimensions(currentCrop)\n\t\tconst targetRatio = cropW / cropH\n\t\tconst oldImageAspectRatio = uncroppedW / uncroppedH\n\t\tlet newRelativeWidth: number\n\t\tlet newRelativeHeight: number\n\n\t\tconst currentCropCenter = getCropCenter(currentCrop)\n\n\t\t// Adjust the new crop dimensions to match the current crop zoom\n\t\tnewRelativeWidth = cropW\n\t\tconst ratioConversion = newImageAspectRatio / oldImageAspectRatio / targetRatio\n\t\tnewRelativeHeight = newRelativeWidth * ratioConversion\n\n\t\t// Check that our new crop dimensions are within the MAX_ZOOM bounds\n\t\tconst maxRatioConversion = MAX_ZOOM / (MAX_ZOOM - 1)\n\t\tif (ratioConversion > maxRatioConversion) {\n\t\t\tconst minDimension = 1 / MAX_ZOOM\n\t\t\tif (1 / newRelativeHeight < 1 / newRelativeWidth) {\n\t\t\t\tconst scale = newRelativeHeight / minDimension\n\t\t\t\tnewRelativeHeight = newRelativeHeight / scale\n\t\t\t\tnewRelativeWidth = newRelativeWidth / scale\n\t\t\t} else {\n\t\t\t\tconst scale = newRelativeWidth / minDimension\n\t\t\t\tnewRelativeWidth = newRelativeWidth / scale\n\t\t\t\tnewRelativeHeight = newRelativeHeight / scale\n\t\t\t}\n\t\t}\n\n\t\t// Ensure dimensions are within [0, 1] bounds after adjustment\n\t\tnewRelativeWidth = Math.max(0, Math.min(1, newRelativeWidth))\n\t\tnewRelativeHeight = Math.max(0, Math.min(1, newRelativeHeight))\n\n\t\t// Create the new crop object, centered around the CURRENT crop's center\n\t\tcrop = createCropAroundCenter(\n\t\t\tcurrentCropCenter.x,\n\t\t\tcurrentCropCenter.y,\n\t\t\tnewRelativeWidth,\n\t\t\tnewRelativeHeight,\n\t\t\tcurrentCrop.isCircle\n\t\t)\n\t}\n\n\t// Position so visual center stays put\n\tconst pageCenterX = imageShape.x + origDisplayW / 2\n\tconst pageCenterY = imageShape.y + origDisplayH / 2\n\n\tconst newX = pageCenterX - newDisplayW / 2\n\tconst newY = pageCenterY - newDisplayH / 2\n\n\treturn {\n\t\tcrop,\n\t\tw: newDisplayW,\n\t\th: newDisplayH,\n\t\tx: newX,\n\t\ty: newY,\n\t}\n}\n\n/**\n * Calculate new crop dimensions and position when changing aspect ratio\n */\nexport function getCroppedImageDataForAspectRatio(\n\taspectRatioOption: ASPECT_RATIO_OPTION,\n\timageShape: TLImageShape\n): CropChange {\n\t// If original aspect ratio is requested, use default crop\n\tif (aspectRatioOption === 'original') {\n\t\tconst { w, h } = getUncroppedSize(imageShape.props, imageShape.props.crop ?? getDefaultCrop())\n\t\tconst imageCenterX = imageShape.x + imageShape.props.w / 2\n\t\tconst imageCenterY = imageShape.y + imageShape.props.h / 2\n\n\t\treturn {\n\t\t\tcrop: getDefaultCrop(),\n\t\t\tw,\n\t\t\th,\n\t\t\tx: imageCenterX - w / 2,\n\t\t\ty: imageCenterY - h / 2,\n\t\t}\n\t}\n\n\t// Get target ratio and uncropped image properties\n\tconst targetRatio = ASPECT_RATIO_TO_VALUE[aspectRatioOption] // Assume valid option\n\tconst isCircle = aspectRatioOption === 'circle'\n\t// Use default crop to get uncropped size relative to the *original* image bounds\n\tconst { w: uncroppedW, h: uncroppedH } = getUncroppedSize(\n\t\timageShape.props,\n\t\timageShape.props.crop || getDefaultCrop() // Use the ACTUAL current crop to correctly infer uncropped size\n\t)\n\t// Calculate the original image aspect ratio\n\tconst imageAspectRatio = uncroppedW / uncroppedH\n\n\t// Get the current crop and its relative dimensions\n\tconst currentCrop = imageShape.props.crop || getDefaultCrop()\n\tconst { width: cropW, height: cropH } = getCropDimensions(currentCrop)\n\tconst currentCropCenter = getCropCenter(currentCrop)\n\n\t// Calculate the current crop zoom level\n\tconst currentCropZoom = Math.min(1 / cropW, 1 / cropH)\n\n\t// Calculate the relative width and height of the crop rectangle (0-1 scale)\n\t// Try to preserve the longest dimension of the current crop when changing aspect ratios\n\tlet newRelativeWidth: number\n\tlet newRelativeHeight: number\n\n\tif (imageAspectRatio === 0 || !Number.isFinite(imageAspectRatio) || targetRatio === 0) {\n\t\t// Avoid division by zero or NaN issues if image dimensions are invalid or target ratio is 0\n\t\tnewRelativeWidth = 1\n\t\tnewRelativeHeight = 1\n\t} else {\n\t\t// Get current crop dimensions in absolute units\n\t\tconst currentAbsoluteWidth = cropW * uncroppedW\n\t\tconst currentAbsoluteHeight = cropH * uncroppedH\n\n\t\t// Find the longest current dimension to preserve\n\t\tconst longestCurrentDimension = Math.max(currentAbsoluteWidth, currentAbsoluteHeight)\n\t\tconst isWidthLongest = currentAbsoluteWidth >= currentAbsoluteHeight\n\n\t\t// Calculate new dimensions preserving the longest dimension\n\t\tlet newAbsoluteWidth: number\n\t\tlet newAbsoluteHeight: number\n\n\t\tif (isWidthLongest) {\n\t\t\t// Preserve width, calculate height based on target ratio\n\t\t\tnewAbsoluteWidth = longestCurrentDimension\n\t\t\tnewAbsoluteHeight = newAbsoluteWidth / targetRatio\n\t\t} else {\n\t\t\t// Preserve height, calculate width based on target ratio\n\t\t\tnewAbsoluteHeight = longestCurrentDimension\n\t\t\tnewAbsoluteWidth = newAbsoluteHeight * targetRatio\n\t\t}\n\n\t\t// Convert back to relative coordinates\n\t\tnewRelativeWidth = newAbsoluteWidth / uncroppedW\n\t\tnewRelativeHeight = newAbsoluteHeight / uncroppedH\n\n\t\t// Clamp to image bounds and adjust if necessary\n\t\tif (newRelativeWidth > 1) {\n\t\t\t// Width exceeds bounds, clamp and recalculate height\n\t\t\tnewRelativeWidth = 1\n\t\t\tnewRelativeHeight = imageAspectRatio / targetRatio\n\t\t}\n\t\tif (newRelativeHeight > 1) {\n\t\t\t// Height exceeds bounds, clamp and recalculate width\n\t\t\tnewRelativeHeight = 1\n\t\t\tnewRelativeWidth = targetRatio / imageAspectRatio\n\t\t}\n\n\t\t// Final clamp to ensure we stay within bounds\n\t\tnewRelativeWidth = Math.max(0, Math.min(1, newRelativeWidth))\n\t\tnewRelativeHeight = Math.max(0, Math.min(1, newRelativeHeight))\n\t}\n\n\tconst newCropZoom = Math.min(1 / newRelativeWidth, 1 / newRelativeHeight)\n\t// Adjust the new crop dimensions to match the current crop zoom\n\tnewRelativeWidth *= newCropZoom / currentCropZoom\n\tnewRelativeHeight *= newCropZoom / currentCropZoom\n\n\t// Ensure dimensions are within [0, 1] bounds after adjustment\n\tnewRelativeWidth = Math.max(0, Math.min(1, newRelativeWidth))\n\tnewRelativeHeight = Math.max(0, Math.min(1, newRelativeHeight))\n\n\t// Create the new crop object, centered around the CURRENT crop's center\n\tconst newCrop = createCropAroundCenter(\n\t\tcurrentCropCenter.x,\n\t\tcurrentCropCenter.y,\n\t\tnewRelativeWidth,\n\t\tnewRelativeHeight,\n\t\tisCircle\n\t)\n\n\t// Get the actual relative dimensions from the new crop (after potential clamping)\n\tconst finalRelativeWidth = newCrop.bottomRight.x - newCrop.topLeft.x\n\tconst finalRelativeHeight = newCrop.bottomRight.y - newCrop.topLeft.y\n\n\t// Calculate the base dimensions (as if applying the new crop to the uncropped image at scale 1)\n\tconst baseW = finalRelativeWidth * uncroppedW\n\tconst baseH = finalRelativeHeight * uncroppedH\n\n\t// Determine the current effective scale of the shape\n\t// This preserves the visual size when the crop changes\n\tlet currentScale = 1.0\n\tif (cropW > 0) {\n\t\tcurrentScale = imageShape.props.w / (cropW * uncroppedW)\n\t} else if (cropH > 0) {\n\t\t// Fallback to height if width relative dimension is zero\n\t\tcurrentScale = imageShape.props.h / (cropH * uncroppedH)\n\t}\n\n\t// Apply the current scale to the base dimensions to get the final dimensions\n\tconst newW = baseW * currentScale\n\tconst newH = baseH * currentScale\n\n\t// Calculate the new top-left position (x, y) for the shape\n\t// to keep the visual center of the cropped area fixed on the page.\n\tconst currentCenterXPage = imageShape.x + imageShape.props.w / 2\n\tconst currentCenterYPage = imageShape.y + imageShape.props.h / 2\n\tconst newX = currentCenterXPage - newW / 2\n\tconst newY = currentCenterYPage - newH / 2\n\n\treturn {\n\t\tcrop: newCrop,\n\t\tw: newW,\n\t\th: newH,\n\t\tx: newX,\n\t\ty: newY,\n\t}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n\tBox,\n\tShapeWithCrop,\n\tTLCropInfo,\n\tTLImageShape,\n\tTLShapeCrop,\n\tTLShapeId,\n\tVec,\n\tclamp,\n\tisEqual,\n} from '@tldraw/editor'\n\n/** @internal */\nexport const MIN_CROP_SIZE = 8\n\n/** @public */\nexport interface CropBoxOptions {\n\tminWidth?: number\n\tminHeight?: number\n}\n\n/** @public */\nexport function getDefaultCrop(): TLShapeCrop {\n\treturn {\n\t\ttopLeft: { x: 0, y: 0 },\n\t\tbottomRight: { x: 1, y: 1 },\n\t}\n}\n\n/** @public */\nexport type ASPECT_RATIO_OPTION =\n\t| 'original'\n\t| 'square'\n\t| 'circle'\n\t| 'landscape'\n\t| 'portrait'\n\t| 'wide'\n\n/** @public */\nexport const ASPECT_RATIO_OPTIONS: ASPECT_RATIO_OPTION[] = [\n\t'original',\n\t'square',\n\t'circle',\n\t'landscape',\n\t'portrait',\n\t'wide',\n]\n\n/** @public */\nexport const ASPECT_RATIO_TO_VALUE: Record<ASPECT_RATIO_OPTION, number> = {\n\toriginal: 0,\n\tsquare: 1,\n\tcircle: 1,\n\tlandscape: 4 / 3,\n\tportrait: 3 / 4,\n\twide: 16 / 9,\n}\n\n/**\n * Original (uncropped) width and height of shape.\n *\n * @public\n */\nexport function getUncroppedSize(\n\tshapeSize: { w: number; h: number },\n\tcrop: TLShapeCrop | null\n): { w: number; h: number } {\n\tif (!crop) return { w: shapeSize.w, h: shapeSize.h }\n\tconst w = shapeSize.w / (crop.bottomRight.x - crop.topLeft.x)\n\tconst h = shapeSize.h / (crop.bottomRight.y - crop.topLeft.y)\n\treturn { w, h }\n}\n\n// Utility function to get crop dimensions\nfunction getCropDimensions(crop: TLShapeCrop) {\n\treturn {\n\t\twidth: crop.bottomRight.x - crop.topLeft.x,\n\t\theight: crop.bottomRight.y - crop.topLeft.y,\n\t}\n}\n\n// Utility function to get crop center\nfunction getCropCenter(crop: TLShapeCrop) {\n\tconst { width, height } = getCropDimensions(crop)\n\treturn {\n\t\tx: crop.topLeft.x + width / 2,\n\t\ty: crop.topLeft.y + height / 2,\n\t}\n}\n\n// Utility function to create crop with specified dimensions centered on given point\nfunction createCropAroundCenter(\n\tcenterX: number,\n\tcenterY: number,\n\twidth: number,\n\theight: number,\n\tisCircle?: boolean\n) {\n\tconst topLeftX = Math.max(0, Math.min(1 - width, centerX - width / 2))\n\tconst topLeftY = Math.max(0, Math.min(1 - height, centerY - height / 2))\n\n\treturn {\n\t\ttopLeft: { x: topLeftX, y: topLeftY },\n\t\tbottomRight: { x: topLeftX + width, y: topLeftY + height },\n\t\tisCircle,\n\t}\n}\n\n/** @public */\nexport function getCropBox<T extends ShapeWithCrop>(\n\tshape: T,\n\tinfo: TLCropInfo<T>,\n\topts = {} as CropBoxOptions\n):\n\t| {\n\t\t\tid: TLShapeId\n\t\t\ttype: T['type']\n\t\t\tx: number\n\t\t\ty: number\n\t\t\tprops: ShapeWithCrop['props']\n\t }\n\t| undefined {\n\tconst { handle, change, crop, aspectRatioLocked } = info\n\tconst { w, h } = info.uncroppedSize\n\tconst { minWidth = MIN_CROP_SIZE, minHeight = MIN_CROP_SIZE } = opts\n\n\tif (w < minWidth || h < minHeight || (change.x === 0 && change.y === 0)) {\n\t\treturn\n\t}\n\n\t// Lets get a box here in pixel space. For simplicity, we'll do all the math in\n\t// pixel space, then convert to normalized space at the end.\n\tconst prevCropBox = new Box(\n\t\tcrop.topLeft.x * w,\n\t\tcrop.topLeft.y * h,\n\t\t(crop.bottomRight.x - crop.topLeft.x) * w,\n\t\t(crop.bottomRight.y - crop.topLeft.y) * h\n\t)\n\n\tconst targetRatio = prevCropBox.aspectRatio\n\tconst tempBox = prevCropBox.clone()\n\n\t// Basic resizing logic based on the handles\n\n\tif (handle === 'top_left' || handle === 'bottom_left' || handle === 'left') {\n\t\ttempBox.x = clamp(tempBox.x + change.x, 0, prevCropBox.maxX - minWidth)\n\t\ttempBox.w = prevCropBox.maxX - tempBox.x\n\t} else if (handle === 'top_right' || handle === 'bottom_right' || handle === 'right') {\n\t\tconst tempRight = clamp(tempBox.maxX + change.x, prevCropBox.x + minWidth, w)\n\t\ttempBox.w = tempRight - tempBox.x\n\t}\n\n\tif (handle === 'top_left' || handle === 'top_right' || handle === 'top') {\n\t\ttempBox.y = clamp(tempBox.y + change.y, 0, prevCropBox.maxY - minHeight)\n\t\ttempBox.h = prevCropBox.maxY - tempBox.y\n\t} else if (handle === 'bottom_left' || handle === 'bottom_right' || handle === 'bottom') {\n\t\tconst tempBottom = clamp(tempBox.maxY + change.y, prevCropBox.y + minHeight, h)\n\t\ttempBox.h = tempBottom - tempBox.y\n\t}\n\n\t// Aspect ratio locked resizing logic\n\n\tif (aspectRatioLocked) {\n\t\tconst isXLimiting = tempBox.aspectRatio > targetRatio\n\n\t\tif (isXLimiting) {\n\t\t\ttempBox.h = tempBox.w / targetRatio\n\t\t} else {\n\t\t\ttempBox.w = tempBox.h * targetRatio\n\t\t}\n\n\t\tswitch (handle) {\n\t\t\tcase 'top_left': {\n\t\t\t\t// preserve the bottom right corner\n\t\t\t\ttempBox.x = prevCropBox.maxX - tempBox.w\n\t\t\t\ttempBox.y = prevCropBox.maxY - tempBox.h\n\n\t\t\t\tif (tempBox.x <= 0) {\n\t\t\t\t\ttempBox.x = 0\n\t\t\t\t\ttempBox.w = prevCropBox.maxX - tempBox.x\n\t\t\t\t\ttempBox.h = tempBox.w / targetRatio\n\t\t\t\t\ttempBox.y = prevCropBox.maxY - tempBox.h\n\t\t\t\t}\n\n\t\t\t\tif (tempBox.y <= 0) {\n\t\t\t\t\ttempBox.y = 0\n\t\t\t\t\ttempBox.h = prevCropBox.maxY - tempBox.y\n\t\t\t\t\ttempBox.w = tempBox.h * targetRatio\n\t\t\t\t\ttempBox.x = prevCropBox.maxX - tempBox.w\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'top_right': {\n\t\t\t\t// preserve the bottom left corner\n\t\t\t\ttempBox.x = prevCropBox.x\n\t\t\t\ttempBox.y = prevCropBox.maxY - tempBox.h\n\n\t\t\t\tif (tempBox.maxX >= w) {\n\t\t\t\t\ttempBox.w = w - prevCropBox.x\n\t\t\t\t\ttempBox.h = tempBox.w / targetRatio\n\t\t\t\t\ttempBox.y = prevCropBox.maxY - tempBox.h\n\t\t\t\t}\n\n\t\t\t\tif (tempBox.y <= 0) {\n\t\t\t\t\ttempBox.y = 0\n\t\t\t\t\ttempBox.h = prevCropBox.maxY - tempBox.y\n\t\t\t\t\ttempBox.w = tempBox.h * targetRatio\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'bottom_left': {\n\t\t\t\t// preserve the top right corner\n\t\t\t\ttempBox.x = prevCropBox.maxX - tempBox.w\n\t\t\t\ttempBox.y = prevCropBox.y\n\n\t\t\t\tif (tempBox.x <= 0) {\n\t\t\t\t\ttempBox.x = 0\n\t\t\t\t\ttempBox.w = prevCropBox.maxX - tempBox.x\n\t\t\t\t\ttempBox.h = tempBox.w / targetRatio\n\t\t\t\t}\n\n\t\t\t\tif (tempBox.maxY >= h) {\n\t\t\t\t\ttempBox.h = h - prevCropBox.y\n\t\t\t\t\ttempBox.w = tempBox.h * targetRatio\n\t\t\t\t\ttempBox.x = prevCropBox.maxX - tempBox.w\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'bottom_right': {\n\t\t\t\t// preserve the top left corner\n\t\t\t\ttempBox.x = prevCropBox.x\n\t\t\t\ttempBox.y = prevCropBox.y\n\n\t\t\t\tif (tempBox.maxX >= w) {\n\t\t\t\t\ttempBox.w = w - prevCropBox.x\n\t\t\t\t\ttempBox.h = tempBox.w / targetRatio\n\t\t\t\t}\n\n\t\t\t\tif (tempBox.maxY >= h) {\n\t\t\t\t\ttempBox.h = h - prevCropBox.y\n\t\t\t\t\ttempBox.w = tempBox.h * targetRatio\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'top': {\n\t\t\t\t// preserve the bottom edge center\n\t\t\t\ttempBox.h = prevCropBox.maxY - tempBox.y\n\t\t\t\ttempBox.w = tempBox.h * targetRatio\n\t\t\t\ttempBox.x -= (tempBox.w - prevCropBox.w) / 2\n\n\t\t\t\tif (tempBox.x <= 0) {\n\t\t\t\t\tconst leftSide = prevCropBox.midX\n\t\t\t\t\ttempBox.w = leftSide * 2\n\t\t\t\t\ttempBox.h = tempBox.w / targetRatio\n\t\t\t\t\ttempBox.x = 0\n\t\t\t\t}\n\n\t\t\t\tif (tempBox.maxX >= w) {\n\t\t\t\t\tconst rightSide = w - prevCropBox.midX\n\t\t\t\t\ttempBox.w = rightSide * 2\n\t\t\t\t\ttempBox.h = tempBox.w / targetRatio\n\t\t\t\t\ttempBox.x = w - tempBox.w\n\t\t\t\t}\n\n\t\t\t\ttempBox.y = prevCropBox.maxY - tempBox.h\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'right': {\n\t\t\t\t// preserve the left edge center\n\t\t\t\ttempBox.w = tempBox.maxX - prevCropBox.x\n\t\t\t\ttempBox.h = tempBox.w / targetRatio\n\t\t\t\ttempBox.y -= (tempBox.h - prevCropBox.h) / 2\n\n\t\t\t\tif (tempBox.y <= 0) {\n\t\t\t\t\tconst topSide = prevCropBox.midY\n\t\t\t\t\ttempBox.h = topSide * 2\n\t\t\t\t\ttempBox.w = tempBox.h * targetRatio\n\t\t\t\t\ttempBox.y = 0\n\t\t\t\t}\n\n\t\t\t\tif (tempBox.maxY >= h) {\n\t\t\t\t\tconst bottomSide = h - prevCropBox.midY\n\t\t\t\t\ttempBox.h = bottomSide * 2\n\t\t\t\t\ttempBox.w = tempBox.h * targetRatio\n\t\t\t\t\ttempBox.y = h - tempBox.h\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'bottom': {\n\t\t\t\t// preserve the top edge center\n\t\t\t\ttempBox.h = tempBox.maxY - prevCropBox.y\n\t\t\t\ttempBox.w = tempBox.h * targetRatio\n\t\t\t\ttempBox.x -= (tempBox.w - prevCropBox.w) / 2\n\n\t\t\t\tif (tempBox.x <= 0) {\n\t\t\t\t\tconst leftSide = prevCropBox.midX\n\t\t\t\t\ttempBox.w = leftSide * 2\n\t\t\t\t\ttempBox.h = tempBox.w / targetRatio\n\t\t\t\t\ttempBox.x = 0\n\t\t\t\t}\n\n\t\t\t\tif (tempBox.maxX >= w) {\n\t\t\t\t\tconst rightSide = w - prevCropBox.midX\n\t\t\t\t\ttempBox.w = rightSide * 2\n\t\t\t\t\ttempBox.h = tempBox.w / targetRatio\n\t\t\t\t\ttempBox.x = w - tempBox.w\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'left': {\n\t\t\t\t// preserve the right edge center\n\t\t\t\ttempBox.w = prevCropBox.maxX - tempBox.x\n\t\t\t\ttempBox.h = tempBox.w / targetRatio\n\t\t\t\ttempBox.y -= (tempBox.h - prevCropBox.h) / 2\n\n\t\t\t\tif (tempBox.y <= 0) {\n\t\t\t\t\tconst topSide = prevCropBox.midY\n\t\t\t\t\ttempBox.h = topSide * 2\n\t\t\t\t\ttempBox.w = tempBox.h * targetRatio\n\t\t\t\t\ttempBox.y = 0\n\t\t\t\t}\n\n\t\t\t\tif (tempBox.maxY >= h) {\n\t\t\t\t\tconst bottomSide = h - prevCropBox.midY\n\t\t\t\t\ttempBox.h = bottomSide * 2\n\t\t\t\t\ttempBox.w = tempBox.h * targetRatio\n\t\t\t\t\ttempBox.y = h - tempBox.h\n\t\t\t\t}\n\n\t\t\t\ttempBox.x = prevCropBox.maxX - tempBox.w\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\t// Convert the box back to normalized space\n\tconst newCrop: TLShapeCrop = {\n\t\ttopLeft: { x: tempBox.x / w, y: tempBox.y / h },\n\t\tbottomRight: { x: tempBox.maxX / w, y: tempBox.maxY / h },\n\t\tisCircle: crop.isCircle,\n\t}\n\n\t// If the crop hasn't changed, we can return early\n\tif (\n\t\tnewCrop.topLeft.x === crop.topLeft.x &&\n\t\tnewCrop.topLeft.y === crop.topLeft.y &&\n\t\tnewCrop.bottomRight.x === crop.bottomRight.x &&\n\t\tnewCrop.bottomRight.y === crop.bottomRight.y\n\t) {\n\t\treturn\n\t}\n\n\t// Adjust the shape's position to keep the crop's absolute coordinates correct\n\tconst newPoint = new Vec(tempBox.x - crop.topLeft.x * w, tempBox.y - crop.topLeft.y * h)\n\t\t.rot(shape.rotation)\n\t\t.add(shape)\n\n\treturn {\n\t\tid: shape.id,\n\t\ttype: shape.type,\n\t\tx: newPoint.x,\n\t\ty: newPoint.y,\n\t\tprops: {\n\t\t\t...shape.props,\n\t\t\tw: tempBox.w,\n\t\t\th: tempBox.h,\n\t\t\tcrop: newCrop,\n\t\t},\n\t}\n}\n\ninterface CropChange {\n\tcrop: {\n\t\ttopLeft: { x: number; y: number }\n\t\tbottomRight: { x: number; y: number }\n\t\tisCircle?: boolean\n\t}\n\tw: number\n\th: number\n\tx: number\n\ty: number\n}\n\n// Base function for calculating crop changes\nfunction calculateCropChange(\n\timageShape: TLImageShape,\n\tnewCropWidth: number,\n\tnewCropHeight: number,\n\tcenterOnCurrentCrop: boolean = true,\n\tisCircle: boolean = false\n): CropChange {\n\tconst { w, h } = getUncroppedSize(imageShape.props, imageShape.props.crop ?? getDefaultCrop())\n\tconst currentCrop = imageShape.props.crop || getDefaultCrop()\n\n\t// Calculate image and crop centers\n\tconst imageCenterX = imageShape.x + imageShape.props.w / 2\n\tconst imageCenterY = imageShape.y + imageShape.props.h / 2\n\n\tlet cropCenterX, cropCenterY\n\tif (centerOnCurrentCrop) {\n\t\tconst { x, y } = getCropCenter(currentCrop)\n\t\tcropCenterX = x\n\t\tcropCenterY = y\n\t} else {\n\t\tcropCenterX = 0.5\n\t\tcropCenterY = 0.5\n\t}\n\n\t// Create new crop\n\tconst newCrop = createCropAroundCenter(\n\t\tcropCenterX,\n\t\tcropCenterY,\n\t\tnewCropWidth,\n\t\tnewCropHeight,\n\t\tisCircle\n\t)\n\n\t// Calculate new dimensions\n\tconst croppedW = newCropWidth * w\n\tconst croppedH = newCropHeight * h\n\n\treturn {\n\t\tcrop: newCrop,\n\t\tw: croppedW,\n\t\th: croppedH,\n\t\tx: imageCenterX - croppedW / 2,\n\t\ty: imageCenterY - croppedH / 2,\n\t}\n}\n\n/** @internal */\nexport const MAX_ZOOM = 3\n\n/**\n * Calculate new crop dimensions and position when zooming\n */\nexport function getCroppedImageDataWhenZooming(\n\tzoom: number,\n\timageShape: TLImageShape,\n\tmaxZoom?: number\n): CropChange {\n\tconst oldCrop = imageShape.props.crop || getDefaultCrop()\n\tconst { width: oldWidth, height: oldHeight } = getCropDimensions(oldCrop)\n\tconst aspectRatio = oldWidth / oldHeight\n\n\t// Calculate new crop size with zoom scale\n\tconst derivedMaxZoom = maxZoom ? 1 / (1 - maxZoom) : MAX_ZOOM\n\tconst zoomScale = 1 + zoom * (derivedMaxZoom - 1)\n\tlet newWidth, newHeight\n\n\tif (aspectRatio > 1) {\n\t\tnewWidth = Math.min(1, 1 / zoomScale)\n\t\tnewHeight = newWidth / aspectRatio\n\t} else {\n\t\tnewHeight = Math.min(1, 1 / zoomScale)\n\t\tnewWidth = newHeight * aspectRatio\n\t}\n\n\t// Calculate result with base function\n\tconst result = calculateCropChange(imageShape, newWidth, newHeight, true, oldCrop.isCircle)\n\n\t// Apply zoom factor to display dimensions\n\tconst scaleFactor = Math.min(MAX_ZOOM, oldWidth / newWidth)\n\tresult.w *= scaleFactor\n\tresult.h *= scaleFactor\n\n\t// Recenter\n\tconst imageCenterX = imageShape.x + imageShape.props.w / 2\n\tconst imageCenterY = imageShape.y + imageShape.props.h / 2\n\tresult.x = imageCenterX - result.w / 2\n\tresult.y = imageCenterY - result.h / 2\n\n\treturn result\n}\n\n/**\n * Calculate new crop dimensions and position when replacing an image\n */\nexport function getCroppedImageDataForReplacedImage(\n\timageShape: TLImageShape,\n\tnewImageWidth: number,\n\tnewImageHeight: number\n): CropChange {\n\tconst defaultCrop = getDefaultCrop()\n\tconst currentCrop = imageShape.props.crop || defaultCrop\n\tconst origDisplayW = imageShape.props.w\n\tconst origDisplayH = imageShape.props.h\n\tconst newImageAspectRatio = newImageWidth / newImageHeight\n\n\tlet crop = defaultCrop\n\tlet newDisplayW = origDisplayW\n\tlet newDisplayH = origDisplayH\n\tconst isOriginalCrop = isEqual(imageShape.props.crop, defaultCrop)\n\n\tif (isOriginalCrop) {\n\t\tnewDisplayW = origDisplayW\n\t\tnewDisplayH = (origDisplayW * newImageHeight) / newImageWidth\n\t} else {\n\t\tconst { w: uncroppedW, h: uncroppedH } = getUncroppedSize(\n\t\t\timageShape.props,\n\t\t\timageShape.props.crop || getDefaultCrop() // Use the ACTUAL current crop to correctly infer uncropped size\n\t\t)\n\t\tconst { width: cropW, height: cropH } = getCropDimensions(currentCrop)\n\t\tconst targetRatio = cropW / cropH\n\t\tconst oldImageAspectRatio = uncroppedW / uncroppedH\n\t\tlet newRelativeWidth: number\n\t\tlet newRelativeHeight: number\n\n\t\tconst currentCropCenter = getCropCenter(currentCrop)\n\n\t\t// Adjust the new crop dimensions to match the current crop zoom\n\t\tnewRelativeWidth = cropW\n\t\tconst ratioConversion = newImageAspectRatio / oldImageAspectRatio / targetRatio\n\t\tnewRelativeHeight = newRelativeWidth * ratioConversion\n\n\t\t// Check that our new crop dimensions are within the MAX_ZOOM bounds\n\t\tconst maxRatioConversion = MAX_ZOOM / (MAX_ZOOM - 1)\n\t\tif (ratioConversion > maxRatioConversion) {\n\t\t\tconst minDimension = 1 / MAX_ZOOM\n\t\t\tif (1 / newRelativeHeight < 1 / newRelativeWidth) {\n\t\t\t\tconst scale = newRelativeHeight / minDimension\n\t\t\t\tnewRelativeHeight = newRelativeHeight / scale\n\t\t\t\tnewRelativeWidth = newRelativeWidth / scale\n\t\t\t} else {\n\t\t\t\tconst scale = newRelativeWidth / minDimension\n\t\t\t\tnewRelativeWidth = newRelativeWidth / scale\n\t\t\t\tnewRelativeHeight = newRelativeHeight / scale\n\t\t\t}\n\t\t}\n\n\t\t// Ensure dimensions are within [0, 1] bounds after adjustment\n\t\tnewRelativeWidth = Math.max(0, Math.min(1, newRelativeWidth))\n\t\tnewRelativeHeight = Math.max(0, Math.min(1, newRelativeHeight))\n\n\t\t// Create the new crop object, centered around the CURRENT crop's center\n\t\tcrop = createCropAroundCenter(\n\t\t\tcurrentCropCenter.x,\n\t\t\tcurrentCropCenter.y,\n\t\t\tnewRelativeWidth,\n\t\t\tnewRelativeHeight,\n\t\t\tcurrentCrop.isCircle\n\t\t)\n\t}\n\n\t// Position so visual center stays put\n\tconst pageCenterX = imageShape.x + origDisplayW / 2\n\tconst pageCenterY = imageShape.y + origDisplayH / 2\n\n\tconst newX = pageCenterX - newDisplayW / 2\n\tconst newY = pageCenterY - newDisplayH / 2\n\n\treturn {\n\t\tcrop,\n\t\tw: newDisplayW,\n\t\th: newDisplayH,\n\t\tx: newX,\n\t\ty: newY,\n\t}\n}\n\n/**\n * Calculate new crop dimensions and position when changing aspect ratio\n */\nexport function getCroppedImageDataForAspectRatio(\n\taspectRatioOption: ASPECT_RATIO_OPTION,\n\timageShape: TLImageShape\n): CropChange {\n\t// If original aspect ratio is requested, use default crop\n\tif (aspectRatioOption === 'original') {\n\t\tconst { w, h } = getUncroppedSize(imageShape.props, imageShape.props.crop ?? getDefaultCrop())\n\t\tconst imageCenterX = imageShape.x + imageShape.props.w / 2\n\t\tconst imageCenterY = imageShape.y + imageShape.props.h / 2\n\n\t\treturn {\n\t\t\tcrop: getDefaultCrop(),\n\t\t\tw,\n\t\t\th,\n\t\t\tx: imageCenterX - w / 2,\n\t\t\ty: imageCenterY - h / 2,\n\t\t}\n\t}\n\n\t// Get target ratio and uncropped image properties\n\tconst targetRatio = ASPECT_RATIO_TO_VALUE[aspectRatioOption] // Assume valid option\n\tconst isCircle = aspectRatioOption === 'circle'\n\t// Use default crop to get uncropped size relative to the *original* image bounds\n\tconst { w: uncroppedW, h: uncroppedH } = getUncroppedSize(\n\t\timageShape.props,\n\t\timageShape.props.crop || getDefaultCrop() // Use the ACTUAL current crop to correctly infer uncropped size\n\t)\n\t// Calculate the original image aspect ratio\n\tconst imageAspectRatio = uncroppedW / uncroppedH\n\n\t// Get the current crop and its relative dimensions\n\tconst currentCrop = imageShape.props.crop || getDefaultCrop()\n\tconst { width: cropW, height: cropH } = getCropDimensions(currentCrop)\n\tconst currentCropCenter = getCropCenter(currentCrop)\n\n\t// Calculate the current crop zoom level\n\tconst currentCropZoom = Math.min(1 / cropW, 1 / cropH)\n\n\t// Calculate the relative width and height of the crop rectangle (0-1 scale)\n\t// Try to preserve the longest dimension of the current crop when changing aspect ratios\n\tlet newRelativeWidth: number\n\tlet newRelativeHeight: number\n\n\tif (imageAspectRatio === 0 || !Number.isFinite(imageAspectRatio) || targetRatio === 0) {\n\t\t// Avoid division by zero or NaN issues if image dimensions are invalid or target ratio is 0\n\t\tnewRelativeWidth = 1\n\t\tnewRelativeHeight = 1\n\t} else {\n\t\t// Get current crop dimensions in absolute units\n\t\tconst currentAbsoluteWidth = cropW * uncroppedW\n\t\tconst currentAbsoluteHeight = cropH * uncroppedH\n\n\t\t// Find the longest current dimension to preserve\n\t\tconst longestCurrentDimension = Math.max(currentAbsoluteWidth, currentAbsoluteHeight)\n\t\tconst isWidthLongest = currentAbsoluteWidth >= currentAbsoluteHeight\n\n\t\t// Calculate new dimensions preserving the longest dimension\n\t\tlet newAbsoluteWidth: number\n\t\tlet newAbsoluteHeight: number\n\n\t\tif (isWidthLongest) {\n\t\t\t// Preserve width, calculate height based on target ratio\n\t\t\tnewAbsoluteWidth = longestCurrentDimension\n\t\t\tnewAbsoluteHeight = newAbsoluteWidth / targetRatio\n\t\t} else {\n\t\t\t// Preserve height, calculate width based on target ratio\n\t\t\tnewAbsoluteHeight = longestCurrentDimension\n\t\t\tnewAbsoluteWidth = newAbsoluteHeight * targetRatio\n\t\t}\n\n\t\t// Convert back to relative coordinates\n\t\tnewRelativeWidth = newAbsoluteWidth / uncroppedW\n\t\tnewRelativeHeight = newAbsoluteHeight / uncroppedH\n\n\t\t// Clamp to image bounds and adjust if necessary\n\t\tif (newRelativeWidth > 1) {\n\t\t\t// Width exceeds bounds, clamp and recalculate height\n\t\t\tnewRelativeWidth = 1\n\t\t\tnewRelativeHeight = imageAspectRatio / targetRatio\n\t\t}\n\t\tif (newRelativeHeight > 1) {\n\t\t\t// Height exceeds bounds, clamp and recalculate width\n\t\t\tnewRelativeHeight = 1\n\t\t\tnewRelativeWidth = targetRatio / imageAspectRatio\n\t\t}\n\n\t\t// Final clamp to ensure we stay within bounds\n\t\tnewRelativeWidth = Math.max(0, Math.min(1, newRelativeWidth))\n\t\tnewRelativeHeight = Math.max(0, Math.min(1, newRelativeHeight))\n\t}\n\n\tconst newCropZoom = Math.min(1 / newRelativeWidth, 1 / newRelativeHeight)\n\t// Adjust the new crop dimensions to match the current crop zoom\n\tnewRelativeWidth *= newCropZoom / currentCropZoom\n\tnewRelativeHeight *= newCropZoom / currentCropZoom\n\n\t// Ensure dimensions are within [0, 1] bounds after adjustment\n\tnewRelativeWidth = Math.max(0, Math.min(1, newRelativeWidth))\n\tnewRelativeHeight = Math.max(0, Math.min(1, newRelativeHeight))\n\n\t// Create the new crop object, centered around the CURRENT crop's center\n\tconst newCrop = createCropAroundCenter(\n\t\tcurrentCropCenter.x,\n\t\tcurrentCropCenter.y,\n\t\tnewRelativeWidth,\n\t\tnewRelativeHeight,\n\t\tisCircle\n\t)\n\n\t// Get the actual relative dimensions from the new crop (after potential clamping)\n\tconst finalRelativeWidth = newCrop.bottomRight.x - newCrop.topLeft.x\n\tconst finalRelativeHeight = newCrop.bottomRight.y - newCrop.topLeft.y\n\n\t// Calculate the base dimensions (as if applying the new crop to the uncropped image at scale 1)\n\tconst baseW = finalRelativeWidth * uncroppedW\n\tconst baseH = finalRelativeHeight * uncroppedH\n\n\t// Determine the current effective scale of the shape\n\t// This preserves the visual size when the crop changes\n\tlet currentScale = 1.0\n\tif (cropW > 0) {\n\t\tcurrentScale = imageShape.props.w / (cropW * uncroppedW)\n\t} else if (cropH > 0) {\n\t\t// Fallback to height if width relative dimension is zero\n\t\tcurrentScale = imageShape.props.h / (cropH * uncroppedH)\n\t}\n\n\t// Apply the current scale to the base dimensions to get the final dimensions\n\tconst newW = baseW * currentScale\n\tconst newH = baseH * currentScale\n\n\t// Calculate the new top-left position (x, y) for the shape\n\t// to keep the visual center of the cropped area fixed on the page.\n\tconst currentCenterXPage = imageShape.x + imageShape.props.w / 2\n\tconst currentCenterYPage = imageShape.y + imageShape.props.h / 2\n\tconst newX = currentCenterXPage - newW / 2\n\tconst newY = currentCenterYPage - newH / 2\n\n\treturn {\n\t\tcrop: newCrop,\n\t\tw: newW,\n\t\th: newH,\n\t\tx: newX,\n\t\ty: newY,\n\t}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/lib/shapes/shared/freehand/svg.ts"],
4
- "sourcesContent": ["import { average, precise } from '@tldraw/editor'\nimport { StrokePoint } from './types'\n\n/**\n * Turn an array of stroke points into a path of quadradic curves.\n *\n * @param points - The stroke points returned from perfect-freehand\n * @param closed - Whether the shape is closed\n */\nexport function getSvgPathFromStrokePoints(points: StrokePoint[], closed = false): string {\n\tconst len = points.length\n\n\tif (len < 2) {\n\t\treturn ''\n\t}\n\n\tlet a = points[0].point\n\tlet b = points[1].point\n\n\tif (len === 2) {\n\t\treturn `M${precise(a)}L${precise(b)}`\n\t}\n\n\tlet result = ''\n\n\tfor (let i = 2, max = len - 1; i < max; i++) {\n\t\ta = points[i].point\n\t\tb = points[i + 1].point\n\t\tresult += average(a, b)\n\t}\n\n\tif (closed) {\n\t\t// If closed, draw a curve from the last point to the first\n\t\treturn `M${average(points[0].point, points[1].point)}Q${precise(points[1].point)}${average(\n\t\t\tpoints[1].point,\n\t\t\tpoints[2].point\n\t\t)}T${result}${average(points[len - 1].point, points[0].point)}${average(\n\t\t\tpoints[0].point,\n\t\t\tpoints[1].point\n\t\t)}Z`\n\t} else {\n\t\t// If not closed, draw a curve starting at the first point and\n\t\t// ending at the midpoint of the last and second-last point, then\n\t\t// complete the curve with a line segment to the last point.\n\t\treturn `M${precise(points[0].point)}Q${precise(points[1].point)}${average(\n\t\t\tpoints[1].point,\n\t\t\tpoints[2].point\n\t\t)}${points.length > 3 ? 'T' : ''}${result}L${precise(points[len - 1].point)}`\n\t}\n}\n"],
5
- "mappings": "AAAA,SAAS,SAAS,eAAe;AAS1B,SAAS,2BAA2B,QAAuB,SAAS,OAAe;AACzF,QAAM,MAAM,OAAO;AAEnB,MAAI,MAAM,GAAG;AACZ,WAAO;AAAA,EACR;AAEA,MAAI,IAAI,OAAO,CAAC,EAAE;AAClB,MAAI,IAAI,OAAO,CAAC,EAAE;AAElB,MAAI,QAAQ,GAAG;AACd,WAAO,IAAI,QAAQ,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC;AAAA,EACpC;AAEA,MAAI,SAAS;AAEb,WAAS,IAAI,GAAG,MAAM,MAAM,GAAG,IAAI,KAAK,KAAK;AAC5C,QAAI,OAAO,CAAC,EAAE;AACd,QAAI,OAAO,IAAI,CAAC,EAAE;AAClB,cAAU,QAAQ,GAAG,CAAC;AAAA,EACvB;AAEA,MAAI,QAAQ;AAEX,WAAO,IAAI,QAAQ,OAAO,CAAC,EAAE,OAAO,OAAO,CAAC,EAAE,KAAK,CAAC,IAAI,QAAQ,OAAO,CAAC,EAAE,KAAK,CAAC,GAAG;AAAA,MAClF,OAAO,CAAC,EAAE;AAAA,MACV,OAAO,CAAC,EAAE;AAAA,IACX,CAAC,IAAI,MAAM,GAAG,QAAQ,OAAO,MAAM,CAAC,EAAE,OAAO,OAAO,CAAC,EAAE,KAAK,CAAC,GAAG;AAAA,MAC/D,OAAO,CAAC,EAAE;AAAA,MACV,OAAO,CAAC,EAAE;AAAA,IACX,CAAC;AAAA,EACF,OAAO;AAIN,WAAO,IAAI,QAAQ,OAAO,CAAC,EAAE,KAAK,CAAC,IAAI,QAAQ,OAAO,CAAC,EAAE,KAAK,CAAC,GAAG;AAAA,MACjE,OAAO,CAAC,EAAE;AAAA,MACV,OAAO,CAAC,EAAE;AAAA,IACX,CAAC,GAAG,OAAO,SAAS,IAAI,MAAM,EAAE,GAAG,MAAM,IAAI,QAAQ,OAAO,MAAM,CAAC,EAAE,KAAK,CAAC;AAAA,EAC5E;AACD;",
4
+ "sourcesContent": ["import { average, precise } from '@tldraw/editor'\nimport { StrokePoint } from './types'\n\n/**\n * Turn an array of stroke points into a path of quadradic curves.\n *\n * @param points - The stroke points returned from perfect-freehand\n * @param closed - Whether the shape is closed\n *\n * @public\n */\nexport function getSvgPathFromStrokePoints(points: StrokePoint[], closed = false): string {\n\tconst len = points.length\n\n\tif (len < 2) {\n\t\treturn ''\n\t}\n\n\tlet a = points[0].point\n\tlet b = points[1].point\n\n\tif (len === 2) {\n\t\treturn `M${precise(a)}L${precise(b)}`\n\t}\n\n\tlet result = ''\n\n\tfor (let i = 2, max = len - 1; i < max; i++) {\n\t\ta = points[i].point\n\t\tb = points[i + 1].point\n\t\tresult += average(a, b)\n\t}\n\n\tif (closed) {\n\t\t// If closed, draw a curve from the last point to the first\n\t\treturn `M${average(points[0].point, points[1].point)}Q${precise(points[1].point)}${average(\n\t\t\tpoints[1].point,\n\t\t\tpoints[2].point\n\t\t)}T${result}${average(points[len - 1].point, points[0].point)}${average(\n\t\t\tpoints[0].point,\n\t\t\tpoints[1].point\n\t\t)}Z`\n\t} else {\n\t\t// If not closed, draw a curve starting at the first point and\n\t\t// ending at the midpoint of the last and second-last point, then\n\t\t// complete the curve with a line segment to the last point.\n\t\treturn `M${precise(points[0].point)}Q${precise(points[1].point)}${average(\n\t\t\tpoints[1].point,\n\t\t\tpoints[2].point\n\t\t)}${points.length > 3 ? 'T' : ''}${result}L${precise(points[len - 1].point)}`\n\t}\n}\n"],
5
+ "mappings": "AAAA,SAAS,SAAS,eAAe;AAW1B,SAAS,2BAA2B,QAAuB,SAAS,OAAe;AACzF,QAAM,MAAM,OAAO;AAEnB,MAAI,MAAM,GAAG;AACZ,WAAO;AAAA,EACR;AAEA,MAAI,IAAI,OAAO,CAAC,EAAE;AAClB,MAAI,IAAI,OAAO,CAAC,EAAE;AAElB,MAAI,QAAQ,GAAG;AACd,WAAO,IAAI,QAAQ,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC;AAAA,EACpC;AAEA,MAAI,SAAS;AAEb,WAAS,IAAI,GAAG,MAAM,MAAM,GAAG,IAAI,KAAK,KAAK;AAC5C,QAAI,OAAO,CAAC,EAAE;AACd,QAAI,OAAO,IAAI,CAAC,EAAE;AAClB,cAAU,QAAQ,GAAG,CAAC;AAAA,EACvB;AAEA,MAAI,QAAQ;AAEX,WAAO,IAAI,QAAQ,OAAO,CAAC,EAAE,OAAO,OAAO,CAAC,EAAE,KAAK,CAAC,IAAI,QAAQ,OAAO,CAAC,EAAE,KAAK,CAAC,GAAG;AAAA,MAClF,OAAO,CAAC,EAAE;AAAA,MACV,OAAO,CAAC,EAAE;AAAA,IACX,CAAC,IAAI,MAAM,GAAG,QAAQ,OAAO,MAAM,CAAC,EAAE,OAAO,OAAO,CAAC,EAAE,KAAK,CAAC,GAAG;AAAA,MAC/D,OAAO,CAAC,EAAE;AAAA,MACV,OAAO,CAAC,EAAE;AAAA,IACX,CAAC;AAAA,EACF,OAAO;AAIN,WAAO,IAAI,QAAQ,OAAO,CAAC,EAAE,KAAK,CAAC,IAAI,QAAQ,OAAO,CAAC,EAAE,KAAK,CAAC,GAAG;AAAA,MACjE,OAAO,CAAC,EAAE;AAAA,MACV,OAAO,CAAC,EAAE;AAAA,IACX,CAAC,GAAG,OAAO,SAAS,IAAI,MAAM,EAAE,GAAG,MAAM,IAAI,QAAQ,OAAO,MAAM,CAAC,EAAE,KAAK,CAAC;AAAA,EAC5E;AACD;",
6
6
  "names": []
7
7
  }
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  getPointerInfo,
3
+ markEventAsHandled,
3
4
  noop,
4
5
  preventDefault,
5
- stopEventPropagation,
6
6
  tlenv,
7
7
  useEditor,
8
8
  useValue
@@ -99,7 +99,7 @@ function useEditableTextCommon(shapeId) {
99
99
  target: "shape",
100
100
  shape: editor.getShape(shapeId)
101
101
  });
102
- stopEventPropagation(e);
102
+ e.stopPropagation();
103
103
  },
104
104
  [editor, shapeId]
105
105
  );
@@ -117,20 +117,19 @@ function useEditableTextCommon(shapeId) {
117
117
  },
118
118
  [editor, shapeId]
119
119
  );
120
+ const handleDoubleClick = markEventAsHandled;
120
121
  return {
121
122
  handleFocus: noop,
122
123
  handleBlur: noop,
123
124
  handleInputPointerDown,
124
- handleDoubleClick: stopEventPropagation,
125
+ handleDoubleClick,
125
126
  handlePaste,
126
127
  isEditing,
127
128
  isReadyForEditing
128
129
  };
129
130
  }
130
- const useEditableText = useEditablePlainText;
131
131
  export {
132
132
  useEditablePlainText,
133
- useEditableText,
134
133
  useEditableTextCommon,
135
134
  useIsReadyForEditing
136
135
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/shapes/shared/useEditablePlainText.ts"],
4
- "sourcesContent": ["import {\n\tEditor,\n\tTLShapeId,\n\tTLUnknownShape,\n\tgetPointerInfo,\n\tnoop,\n\tpreventDefault,\n\tstopEventPropagation,\n\ttlenv,\n\tuseEditor,\n\tuseValue,\n} from '@tldraw/editor'\nimport React, { useCallback, useEffect, useRef } from 'react'\nimport { TextHelpers } from './TextHelpers'\n\n/** @public */\nexport function useEditablePlainText(shapeId: TLShapeId, type: string, text?: string) {\n\tconst commonUseEditableTextHandlers = useEditableTextCommon(shapeId)\n\tconst isEditing = commonUseEditableTextHandlers.isEditing\n\tconst editor = useEditor()\n\tconst rInput = useRef<HTMLTextAreaElement>(null)\n\tconst isEmpty = (text || '').trim().length === 0\n\n\tuseEffect(() => {\n\t\tfunction selectAllIfEditing(event: { shapeId: TLShapeId }) {\n\t\t\tif (event.shapeId === shapeId) {\n\t\t\t\trInput.current?.select?.()\n\t\t\t}\n\t\t}\n\n\t\teditor.on('select-all-text', selectAllIfEditing)\n\t\treturn () => {\n\t\t\teditor.off('select-all-text', selectAllIfEditing)\n\t\t}\n\t}, [editor, shapeId, isEditing])\n\n\tuseEffect(() => {\n\t\tif (!isEditing) return\n\n\t\tif (document.activeElement !== rInput.current) {\n\t\t\trInput.current?.focus()\n\t\t}\n\n\t\tif (editor.getInstanceState().isCoarsePointer) {\n\t\t\trInput.current?.select()\n\t\t}\n\n\t\t// XXX(mime): This fixes iOS not showing the caret sometimes.\n\t\t// This \"shakes\" the caret awake.\n\t\tif (tlenv.isSafari) {\n\t\t\trInput.current?.blur()\n\t\t\trInput.current?.focus()\n\t\t}\n\t}, [editor, isEditing])\n\n\t// When the user presses ctrl / meta enter, complete the editing state.\n\tconst handleKeyDown = useCallback(\n\t\t(e: KeyboardEvent) => {\n\t\t\tif (editor.getEditingShapeId() !== shapeId) return\n\n\t\t\tswitch (e.key) {\n\t\t\t\tcase 'Enter': {\n\t\t\t\t\tif (e.ctrlKey || e.metaKey) {\n\t\t\t\t\t\teditor.complete()\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[editor, shapeId]\n\t)\n\n\t// When the text changes, update the text value.\n\tconst handleChange = useCallback(\n\t\t({ plaintext }: { plaintext: string }) => {\n\t\t\tif (editor.getEditingShapeId() !== shapeId) return\n\n\t\t\tconst normalizedPlaintext = TextHelpers.normalizeText(plaintext || '')\n\t\t\teditor.updateShape<TLUnknownShape & { props: { text: string } }>({\n\t\t\t\tid: shapeId,\n\t\t\t\ttype,\n\t\t\t\tprops: { text: normalizedPlaintext },\n\t\t\t})\n\t\t},\n\t\t[editor, shapeId, type]\n\t)\n\n\treturn {\n\t\trInput,\n\t\thandleKeyDown,\n\t\thandleChange,\n\t\tisEmpty,\n\t\t...commonUseEditableTextHandlers,\n\t}\n}\n\n/** @internal */\nexport function useIsReadyForEditing(editor: Editor, shapeId: TLShapeId) {\n\treturn useValue(\n\t\t'isReadyForEditing',\n\t\t() => {\n\t\t\tconst editingShapeId = editor.getEditingShapeId()\n\t\t\treturn (\n\t\t\t\t// something's being editing... and either it's this shape OR this shape is hovered\n\t\t\t\teditingShapeId !== null &&\n\t\t\t\t(editingShapeId === shapeId || editor.getHoveredShapeId() === shapeId)\n\t\t\t)\n\t\t},\n\t\t[editor, shapeId]\n\t)\n}\n\n/** @internal */\nexport function useEditableTextCommon(shapeId: TLShapeId) {\n\tconst editor = useEditor()\n\tconst isEditing = useValue('isEditing', () => editor.getEditingShapeId() === shapeId, [editor])\n\tconst isReadyForEditing = useIsReadyForEditing(editor, shapeId)\n\n\tconst handleInputPointerDown = useCallback(\n\t\t(e: React.PointerEvent) => {\n\t\t\t// N.B. We used to only do this only when isEditing to help\n\t\t\t// prevent an issue where you could drag a selected shape\n\t\t\t// behind another shape. That is addressed now by the CSS logic\n\t\t\t// looking at data-isselectinganything.\n\t\t\t//\n\t\t\t// We still need to follow this logic even if not isEditing\n\t\t\t// because otherwise there is some flakiness in selection.\n\t\t\t// When selecting text, it would sometimes select some text\n\t\t\t// partially if we didn't dispatch/stop below.\n\n\t\t\teditor.dispatch({\n\t\t\t\t...getPointerInfo(e),\n\t\t\t\ttype: 'pointer',\n\t\t\t\tname: 'pointer_down',\n\t\t\t\ttarget: 'shape',\n\t\t\t\tshape: editor.getShape(shapeId)!,\n\t\t\t})\n\n\t\t\tstopEventPropagation(e) // we need to prevent blurring the input\n\t\t},\n\t\t[editor, shapeId]\n\t)\n\n\tconst handlePaste = useCallback(\n\t\t(e: ClipboardEvent | React.ClipboardEvent<HTMLTextAreaElement>) => {\n\t\t\tif (editor.getEditingShapeId() !== shapeId) return\n\t\t\tif (e.clipboardData) {\n\t\t\t\t// find html in the clipboard and look for the tldraw data\n\t\t\t\tconst html = e.clipboardData.getData('text/html')\n\t\t\t\tif (html) {\n\t\t\t\t\tif (html.includes('<div data-tldraw')) {\n\t\t\t\t\t\tpreventDefault(e)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[editor, shapeId]\n\t)\n\n\treturn {\n\t\thandleFocus: noop,\n\t\thandleBlur: noop,\n\t\thandleInputPointerDown,\n\t\thandleDoubleClick: stopEventPropagation,\n\t\thandlePaste,\n\t\tisEditing,\n\t\tisReadyForEditing,\n\t}\n}\n\n/**\n * @deprecated Use `useEditablePlainText` instead.\n * @public\n */\nexport const useEditableText = useEditablePlainText\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n\tEditor,\n\tTLShape,\n\tTLShapeId,\n\tgetPointerInfo,\n\tmarkEventAsHandled,\n\tnoop,\n\tpreventDefault,\n\ttlenv,\n\tuseEditor,\n\tuseValue,\n} from '@tldraw/editor'\nimport React, { useCallback, useEffect, useRef } from 'react'\nimport { TextHelpers } from './TextHelpers'\n\n/** @public */\nexport function useEditablePlainText(\n\tshapeId: TLShapeId,\n\ttype: Extract<TLShape, { props: { text: string } }>['type'],\n\ttext?: string\n) {\n\tconst commonUseEditableTextHandlers = useEditableTextCommon(shapeId)\n\tconst isEditing = commonUseEditableTextHandlers.isEditing\n\tconst editor = useEditor()\n\tconst rInput = useRef<HTMLTextAreaElement>(null)\n\tconst isEmpty = (text || '').trim().length === 0\n\n\tuseEffect(() => {\n\t\tfunction selectAllIfEditing(event: { shapeId: TLShapeId }) {\n\t\t\tif (event.shapeId === shapeId) {\n\t\t\t\trInput.current?.select?.()\n\t\t\t}\n\t\t}\n\n\t\teditor.on('select-all-text', selectAllIfEditing)\n\t\treturn () => {\n\t\t\teditor.off('select-all-text', selectAllIfEditing)\n\t\t}\n\t}, [editor, shapeId, isEditing])\n\n\tuseEffect(() => {\n\t\tif (!isEditing) return\n\n\t\tif (document.activeElement !== rInput.current) {\n\t\t\trInput.current?.focus()\n\t\t}\n\n\t\tif (editor.getInstanceState().isCoarsePointer) {\n\t\t\trInput.current?.select()\n\t\t}\n\n\t\t// XXX(mime): This fixes iOS not showing the caret sometimes.\n\t\t// This \"shakes\" the caret awake.\n\t\tif (tlenv.isSafari) {\n\t\t\trInput.current?.blur()\n\t\t\trInput.current?.focus()\n\t\t}\n\t}, [editor, isEditing])\n\n\t// When the user presses ctrl / meta enter, complete the editing state.\n\tconst handleKeyDown = useCallback(\n\t\t(e: KeyboardEvent) => {\n\t\t\tif (editor.getEditingShapeId() !== shapeId) return\n\n\t\t\tswitch (e.key) {\n\t\t\t\tcase 'Enter': {\n\t\t\t\t\tif (e.ctrlKey || e.metaKey) {\n\t\t\t\t\t\teditor.complete()\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[editor, shapeId]\n\t)\n\n\t// When the text changes, update the text value.\n\tconst handleChange = useCallback(\n\t\t({ plaintext }: { plaintext: string }) => {\n\t\t\tif (editor.getEditingShapeId() !== shapeId) return\n\n\t\t\tconst normalizedPlaintext = TextHelpers.normalizeText(plaintext || '')\n\t\t\teditor.updateShape({\n\t\t\t\tid: shapeId,\n\t\t\t\ttype,\n\t\t\t\tprops: { text: normalizedPlaintext },\n\t\t\t})\n\t\t},\n\t\t[editor, shapeId, type]\n\t)\n\n\treturn {\n\t\trInput,\n\t\thandleKeyDown,\n\t\thandleChange,\n\t\tisEmpty,\n\t\t...commonUseEditableTextHandlers,\n\t}\n}\n\n/** @internal */\nexport function useIsReadyForEditing(editor: Editor, shapeId: TLShapeId) {\n\treturn useValue(\n\t\t'isReadyForEditing',\n\t\t() => {\n\t\t\tconst editingShapeId = editor.getEditingShapeId()\n\t\t\treturn (\n\t\t\t\t// something's being editing... and either it's this shape OR this shape is hovered\n\t\t\t\teditingShapeId !== null &&\n\t\t\t\t(editingShapeId === shapeId || editor.getHoveredShapeId() === shapeId)\n\t\t\t)\n\t\t},\n\t\t[editor, shapeId]\n\t)\n}\n\n/** @internal */\nexport function useEditableTextCommon(shapeId: TLShapeId) {\n\tconst editor = useEditor()\n\tconst isEditing = useValue('isEditing', () => editor.getEditingShapeId() === shapeId, [editor])\n\tconst isReadyForEditing = useIsReadyForEditing(editor, shapeId)\n\n\tconst handleInputPointerDown = useCallback(\n\t\t(e: React.PointerEvent) => {\n\t\t\t// N.B. We used to only do this only when isEditing to help\n\t\t\t// prevent an issue where you could drag a selected shape\n\t\t\t// behind another shape. That is addressed now by the CSS logic\n\t\t\t// looking at data-isselectinganything.\n\t\t\t//\n\t\t\t// We still need to follow this logic even if not isEditing\n\t\t\t// because otherwise there is some flakiness in selection.\n\t\t\t// When selecting text, it would sometimes select some text\n\t\t\t// partially if we didn't dispatch/stop below.\n\n\t\t\teditor.dispatch({\n\t\t\t\t...getPointerInfo(e),\n\t\t\t\ttype: 'pointer',\n\t\t\t\tname: 'pointer_down',\n\t\t\t\ttarget: 'shape',\n\t\t\t\tshape: editor.getShape(shapeId)!,\n\t\t\t})\n\n\t\t\te.stopPropagation() // we need to prevent blurring the input\n\t\t},\n\t\t[editor, shapeId]\n\t)\n\n\tconst handlePaste = useCallback(\n\t\t(e: ClipboardEvent | React.ClipboardEvent<HTMLTextAreaElement>) => {\n\t\t\tif (editor.getEditingShapeId() !== shapeId) return\n\t\t\tif (e.clipboardData) {\n\t\t\t\t// find html in the clipboard and look for the tldraw data\n\t\t\t\tconst html = e.clipboardData.getData('text/html')\n\t\t\t\tif (html) {\n\t\t\t\t\tif (html.includes('<div data-tldraw')) {\n\t\t\t\t\t\tpreventDefault(e)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[editor, shapeId]\n\t)\n\n\tconst handleDoubleClick: (e: React.MouseEvent) => void = markEventAsHandled\n\n\treturn {\n\t\thandleFocus: noop,\n\t\thandleBlur: noop,\n\t\thandleInputPointerDown,\n\t\thandleDoubleClick,\n\t\thandlePaste,\n\t\tisEditing,\n\t\tisReadyForEditing,\n\t}\n}\n"],
5
+ "mappings": "AAAA;AAAA,EAIC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,SAAgB,aAAa,WAAW,cAAc;AACtD,SAAS,mBAAmB;AAGrB,SAAS,qBACf,SACA,MACA,MACC;AACD,QAAM,gCAAgC,sBAAsB,OAAO;AACnE,QAAM,YAAY,8BAA8B;AAChD,QAAM,SAAS,UAAU;AACzB,QAAM,SAAS,OAA4B,IAAI;AAC/C,QAAM,WAAW,QAAQ,IAAI,KAAK,EAAE,WAAW;AAE/C,YAAU,MAAM;AACf,aAAS,mBAAmB,OAA+B;AAC1D,UAAI,MAAM,YAAY,SAAS;AAC9B,eAAO,SAAS,SAAS;AAAA,MAC1B;AAAA,IACD;AAEA,WAAO,GAAG,mBAAmB,kBAAkB;AAC/C,WAAO,MAAM;AACZ,aAAO,IAAI,mBAAmB,kBAAkB;AAAA,IACjD;AAAA,EACD,GAAG,CAAC,QAAQ,SAAS,SAAS,CAAC;AAE/B,YAAU,MAAM;AACf,QAAI,CAAC,UAAW;AAEhB,QAAI,SAAS,kBAAkB,OAAO,SAAS;AAC9C,aAAO,SAAS,MAAM;AAAA,IACvB;AAEA,QAAI,OAAO,iBAAiB,EAAE,iBAAiB;AAC9C,aAAO,SAAS,OAAO;AAAA,IACxB;AAIA,QAAI,MAAM,UAAU;AACnB,aAAO,SAAS,KAAK;AACrB,aAAO,SAAS,MAAM;AAAA,IACvB;AAAA,EACD,GAAG,CAAC,QAAQ,SAAS,CAAC;AAGtB,QAAM,gBAAgB;AAAA,IACrB,CAAC,MAAqB;AACrB,UAAI,OAAO,kBAAkB,MAAM,QAAS;AAE5C,cAAQ,EAAE,KAAK;AAAA,QACd,KAAK,SAAS;AACb,cAAI,EAAE,WAAW,EAAE,SAAS;AAC3B,mBAAO,SAAS;AAAA,UACjB;AACA;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA,IACA,CAAC,QAAQ,OAAO;AAAA,EACjB;AAGA,QAAM,eAAe;AAAA,IACpB,CAAC,EAAE,UAAU,MAA6B;AACzC,UAAI,OAAO,kBAAkB,MAAM,QAAS;AAE5C,YAAM,sBAAsB,YAAY,cAAc,aAAa,EAAE;AACrE,aAAO,YAAY;AAAA,QAClB,IAAI;AAAA,QACJ;AAAA,QACA,OAAO,EAAE,MAAM,oBAAoB;AAAA,MACpC,CAAC;AAAA,IACF;AAAA,IACA,CAAC,QAAQ,SAAS,IAAI;AAAA,EACvB;AAEA,SAAO;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACJ;AACD;AAGO,SAAS,qBAAqB,QAAgB,SAAoB;AACxE,SAAO;AAAA,IACN;AAAA,IACA,MAAM;AACL,YAAM,iBAAiB,OAAO,kBAAkB;AAChD;AAAA;AAAA,QAEC,mBAAmB,SAClB,mBAAmB,WAAW,OAAO,kBAAkB,MAAM;AAAA;AAAA,IAEhE;AAAA,IACA,CAAC,QAAQ,OAAO;AAAA,EACjB;AACD;AAGO,SAAS,sBAAsB,SAAoB;AACzD,QAAM,SAAS,UAAU;AACzB,QAAM,YAAY,SAAS,aAAa,MAAM,OAAO,kBAAkB,MAAM,SAAS,CAAC,MAAM,CAAC;AAC9F,QAAM,oBAAoB,qBAAqB,QAAQ,OAAO;AAE9D,QAAM,yBAAyB;AAAA,IAC9B,CAAC,MAA0B;AAW1B,aAAO,SAAS;AAAA,QACf,GAAG,eAAe,CAAC;AAAA,QACnB,MAAM;AAAA,QACN,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,OAAO,OAAO,SAAS,OAAO;AAAA,MAC/B,CAAC;AAED,QAAE,gBAAgB;AAAA,IACnB;AAAA,IACA,CAAC,QAAQ,OAAO;AAAA,EACjB;AAEA,QAAM,cAAc;AAAA,IACnB,CAAC,MAAkE;AAClE,UAAI,OAAO,kBAAkB,MAAM,QAAS;AAC5C,UAAI,EAAE,eAAe;AAEpB,cAAM,OAAO,EAAE,cAAc,QAAQ,WAAW;AAChD,YAAI,MAAM;AACT,cAAI,KAAK,SAAS,kBAAkB,GAAG;AACtC,2BAAe,CAAC;AAAA,UACjB;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA,IACA,CAAC,QAAQ,OAAO;AAAA,EACjB;AAEA,QAAM,oBAAmD;AAEzD,SAAO;AAAA,IACN,aAAa;AAAA,IACb,YAAY;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD;AACD;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/shapes/shared/useEditableRichText.ts"],
4
- "sourcesContent": ["import { TLRichText, TLShapeId, TLUnknownShape, isAccelKey, useEditor } from '@tldraw/editor'\nimport { useCallback, useEffect, useRef } from 'react'\nimport { isEmptyRichText } from '../../utils/text/richText'\nimport { useEditableTextCommon } from './useEditablePlainText'\n\n/** @public */\nexport function useEditableRichText(shapeId: TLShapeId, type: string, richText?: TLRichText) {\n\tconst commonUseEditableTextHandlers = useEditableTextCommon(shapeId)\n\tconst isEditing = commonUseEditableTextHandlers.isEditing\n\tconst editor = useEditor()\n\tconst rInput = useRef<HTMLDivElement>(null)\n\tconst isEmpty = richText && isEmptyRichText(richText)\n\n\tuseEffect(() => {\n\t\tif (!isEditing) return\n\n\t\t// N.B. In Development mode you need to ensure you're testing this without StrictMode on.\n\t\t// Otherwise it's not gonna work as expected on iOS.\n\t\tconst contentEditable = rInput.current?.querySelector('[contenteditable]')\n\t\tif (contentEditable && document.activeElement !== rInput.current) {\n\t\t\t// This is a crucial difference with useEditablePlainText, that we need to select the\n\t\t\t// child contentEditable <div> not rInput.current directly.\n\t\t\t// Specifically, this is to ensure iOS works. Otherwise, we could just use rInput.current.\n\t\t\t;(contentEditable as HTMLElement).focus()\n\t\t}\n\t}, [editor, isEditing])\n\n\t// When the user presses ctrl / meta enter, complete the editing state.\n\tconst handleKeyDown = useCallback(\n\t\t(e: KeyboardEvent) => {\n\t\t\tif (editor.getEditingShapeId() !== shapeId) return\n\t\t\tif (e.key === 'Enter' && isAccelKey(e)) editor.complete()\n\t\t},\n\t\t[editor, shapeId]\n\t)\n\n\t// When the text changes, update the text value.\n\tconst handleChange = useCallback(\n\t\t({ richText }: { richText: TLRichText }) => {\n\t\t\tif (editor.getEditingShapeId() !== shapeId) return\n\n\t\t\teditor.updateShape<TLUnknownShape & { props: { richText: TLRichText } }>({\n\t\t\t\tid: shapeId,\n\t\t\t\ttype,\n\t\t\t\tprops: { richText },\n\t\t\t})\n\t\t},\n\t\t[editor, shapeId, type]\n\t)\n\n\treturn {\n\t\trInput,\n\t\thandleKeyDown,\n\t\thandleChange,\n\t\tisEmpty,\n\t\t...commonUseEditableTextHandlers,\n\t}\n}\n"],
5
- "mappings": "AAAA,SAAgD,YAAY,iBAAiB;AAC7E,SAAS,aAAa,WAAW,cAAc;AAC/C,SAAS,uBAAuB;AAChC,SAAS,6BAA6B;AAG/B,SAAS,oBAAoB,SAAoB,MAAc,UAAuB;AAC5F,QAAM,gCAAgC,sBAAsB,OAAO;AACnE,QAAM,YAAY,8BAA8B;AAChD,QAAM,SAAS,UAAU;AACzB,QAAM,SAAS,OAAuB,IAAI;AAC1C,QAAM,UAAU,YAAY,gBAAgB,QAAQ;AAEpD,YAAU,MAAM;AACf,QAAI,CAAC,UAAW;AAIhB,UAAM,kBAAkB,OAAO,SAAS,cAAc,mBAAmB;AACzE,QAAI,mBAAmB,SAAS,kBAAkB,OAAO,SAAS;AAIjE;AAAC,MAAC,gBAAgC,MAAM;AAAA,IACzC;AAAA,EACD,GAAG,CAAC,QAAQ,SAAS,CAAC;AAGtB,QAAM,gBAAgB;AAAA,IACrB,CAAC,MAAqB;AACrB,UAAI,OAAO,kBAAkB,MAAM,QAAS;AAC5C,UAAI,EAAE,QAAQ,WAAW,WAAW,CAAC,EAAG,QAAO,SAAS;AAAA,IACzD;AAAA,IACA,CAAC,QAAQ,OAAO;AAAA,EACjB;AAGA,QAAM,eAAe;AAAA,IACpB,CAAC,EAAE,UAAAA,UAAS,MAAgC;AAC3C,UAAI,OAAO,kBAAkB,MAAM,QAAS;AAE5C,aAAO,YAAkE;AAAA,QACxE,IAAI;AAAA,QACJ;AAAA,QACA,OAAO,EAAE,UAAAA,UAAS;AAAA,MACnB,CAAC;AAAA,IACF;AAAA,IACA,CAAC,QAAQ,SAAS,IAAI;AAAA,EACvB;AAEA,SAAO;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACJ;AACD;",
4
+ "sourcesContent": ["import { TLRichText, TLShape, TLShapeId, isAccelKey, useEditor } from '@tldraw/editor'\nimport { useCallback, useEffect, useRef } from 'react'\nimport { isEmptyRichText } from '../../utils/text/richText'\nimport { useEditableTextCommon } from './useEditablePlainText'\n\n/** @public */\nexport function useEditableRichText(\n\tshapeId: TLShapeId,\n\ttype: Extract<TLShape, { props: { richText: TLRichText } }>['type'],\n\trichText?: TLRichText\n) {\n\tconst commonUseEditableTextHandlers = useEditableTextCommon(shapeId)\n\tconst isEditing = commonUseEditableTextHandlers.isEditing\n\tconst editor = useEditor()\n\tconst rInput = useRef<HTMLDivElement>(null)\n\tconst isEmpty = richText && isEmptyRichText(richText)\n\n\tuseEffect(() => {\n\t\tif (!isEditing) return\n\n\t\t// N.B. In Development mode you need to ensure you're testing this without StrictMode on.\n\t\t// Otherwise it's not gonna work as expected on iOS.\n\t\tconst contentEditable = rInput.current?.querySelector('[contenteditable]')\n\t\tif (contentEditable && document.activeElement !== rInput.current) {\n\t\t\t// This is a crucial difference with useEditablePlainText, that we need to select the\n\t\t\t// child contentEditable <div> not rInput.current directly.\n\t\t\t// Specifically, this is to ensure iOS works. Otherwise, we could just use rInput.current.\n\t\t\t;(contentEditable as HTMLElement).focus()\n\t\t}\n\t}, [editor, isEditing])\n\n\t// When the user presses ctrl / meta enter, complete the editing state.\n\tconst handleKeyDown = useCallback(\n\t\t(e: KeyboardEvent) => {\n\t\t\tif (editor.getEditingShapeId() !== shapeId) return\n\t\t\tif (e.key === 'Enter' && isAccelKey(e)) editor.complete()\n\t\t},\n\t\t[editor, shapeId]\n\t)\n\n\t// When the text changes, update the text value.\n\tconst handleChange = useCallback(\n\t\t({ richText }: { richText: TLRichText }) => {\n\t\t\tif (editor.getEditingShapeId() !== shapeId) return\n\n\t\t\teditor.updateShape({\n\t\t\t\tid: shapeId,\n\t\t\t\ttype,\n\t\t\t\tprops: { richText },\n\t\t\t})\n\t\t},\n\t\t[editor, shapeId, type]\n\t)\n\n\treturn {\n\t\trInput,\n\t\thandleKeyDown,\n\t\thandleChange,\n\t\tisEmpty,\n\t\t...commonUseEditableTextHandlers,\n\t}\n}\n"],
5
+ "mappings": "AAAA,SAAyC,YAAY,iBAAiB;AACtE,SAAS,aAAa,WAAW,cAAc;AAC/C,SAAS,uBAAuB;AAChC,SAAS,6BAA6B;AAG/B,SAAS,oBACf,SACA,MACA,UACC;AACD,QAAM,gCAAgC,sBAAsB,OAAO;AACnE,QAAM,YAAY,8BAA8B;AAChD,QAAM,SAAS,UAAU;AACzB,QAAM,SAAS,OAAuB,IAAI;AAC1C,QAAM,UAAU,YAAY,gBAAgB,QAAQ;AAEpD,YAAU,MAAM;AACf,QAAI,CAAC,UAAW;AAIhB,UAAM,kBAAkB,OAAO,SAAS,cAAc,mBAAmB;AACzE,QAAI,mBAAmB,SAAS,kBAAkB,OAAO,SAAS;AAIjE;AAAC,MAAC,gBAAgC,MAAM;AAAA,IACzC;AAAA,EACD,GAAG,CAAC,QAAQ,SAAS,CAAC;AAGtB,QAAM,gBAAgB;AAAA,IACrB,CAAC,MAAqB;AACrB,UAAI,OAAO,kBAAkB,MAAM,QAAS;AAC5C,UAAI,EAAE,QAAQ,WAAW,WAAW,CAAC,EAAG,QAAO,SAAS;AAAA,IACzD;AAAA,IACA,CAAC,QAAQ,OAAO;AAAA,EACjB;AAGA,QAAM,eAAe;AAAA,IACpB,CAAC,EAAE,UAAAA,UAAS,MAAgC;AAC3C,UAAI,OAAO,kBAAkB,MAAM,QAAS;AAE5C,aAAO,YAAY;AAAA,QAClB,IAAI;AAAA,QACJ;AAAA,QACA,OAAO,EAAE,UAAAA,UAAS;AAAA,MACnB,CAAC;AAAA,IACF;AAAA,IACA,CAAC,QAAQ,SAAS,IAAI;AAAA,EACvB;AAEA,SAAO;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACJ;AACD;",
6
6
  "names": ["richText"]
7
7
  }
@@ -79,9 +79,7 @@ function resolveAssetUrl(editor, assetId, screenScale, exportInfo, callback) {
79
79
  callback(url);
80
80
  });
81
81
  }
82
- const useAsset = useImageOrVideoAsset;
83
82
  export {
84
- useAsset,
85
83
  useImageOrVideoAsset
86
84
  };
87
85
  //# sourceMappingURL=useImageOrVideoAsset.mjs.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/shapes/shared/useImageOrVideoAsset.ts"],
4
- "sourcesContent": ["import {\n\tEditor,\n\tSvgExportContext,\n\tTLAssetId,\n\tTLImageAsset,\n\tTLShapeId,\n\tTLVideoAsset,\n\treact,\n\tuseDelaySvgExport,\n\tuseEditor,\n\tuseSvgExportContext,\n} from '@tldraw/editor'\nimport { useEffect, useRef, useState } from 'react'\n\n/**\n * Options for {@link useImageOrVideoAsset}.\n *\n * @public\n */\nexport interface UseImageOrVideoAssetOptions {\n\t/** The asset ID you want a URL for. */\n\tassetId: TLAssetId | null\n\t/**\n\t * The shape the asset is being used for. We won't update the resolved URL while the shape is\n\t * off-screen.\n\t */\n\tshapeId?: TLShapeId\n\t/**\n\t * The width at which the asset will be displayed, in shape-space pixels.\n\t */\n\twidth: number\n}\n\n/**\n * This is a handy helper hook that resolves an asset to an optimized URL for a given shape, or its\n * {@link @tldraw/editor#Editor.createTemporaryAssetPreview | placeholder} if the asset is still\n * uploading. This is used in particular for high-resolution images when you want lower and higher\n * resolution depending on the size of the image on the canvas and the zoom level.\n *\n * For image scaling to work, you need to implement scaled URLs in\n * {@link @tldraw/tlschema#TLAssetStore.resolve}.\n *\n * @public\n */\nexport function useImageOrVideoAsset({ shapeId, assetId, width }: UseImageOrVideoAssetOptions) {\n\tconst editor = useEditor()\n\tconst exportInfo = useSvgExportContext()\n\tconst exportIsReady = useDelaySvgExport()\n\n\t// We use a state to store the result of the asset resolution, and we're going to avoid updating this whenever we can\n\tconst [result, setResult] = useState<{\n\t\tasset: (TLImageAsset | TLVideoAsset) | null\n\t\turl: string | null\n\t}>(() => ({\n\t\tasset: assetId ? (editor.getAsset<TLImageAsset | TLVideoAsset>(assetId) ?? null) : null,\n\t\turl: null as string | null,\n\t}))\n\n\t// A flag for whether we've resolved the asset URL at least once, after which we can debounce\n\tconst didAlreadyResolve = useRef(false)\n\n\t// The last URL that we've seen for the shape\n\tconst previousUrl = useRef<string | null>(null)\n\n\tuseEffect(() => {\n\t\tif (!assetId) return\n\n\t\tlet isCancelled = false\n\t\tlet cancelDebounceFn: (() => void) | undefined\n\n\t\tconst cleanupEffectScheduler = react('update state', () => {\n\t\t\tif (!exportInfo && shapeId && editor.getCulledShapes().has(shapeId)) return\n\n\t\t\t// Get the fresh asset\n\t\t\tconst asset = editor.getAsset<TLImageAsset | TLVideoAsset>(assetId)\n\t\t\tif (!asset) {\n\t\t\t\t// If the asset is deleted, such as when an upload fails, set the URL to null\n\t\t\t\tsetResult((prev) => ({ ...prev, asset: null, url: null }))\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Set initial preview for the shape if it has no source (if it was pasted into a local project as base64)\n\t\t\tif (!asset.props.src) {\n\t\t\t\tconst preview = editor.getTemporaryAssetPreview(asset.id)\n\t\t\t\tif (preview) {\n\t\t\t\t\tif (previousUrl.current !== preview) {\n\t\t\t\t\t\tpreviousUrl.current = preview // just for kicks, let's save the url as the previous URL\n\t\t\t\t\t\tsetResult((prev) => ({ ...prev, isPlaceholder: true, url: preview })) // set the preview as the URL\n\t\t\t\t\t\texportIsReady() // let the SVG export know we're ready for export\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// aside ...we could bail here if the only thing that has changed is the shape has changed from culled to not culled\n\n\t\t\tconst screenScale = exportInfo\n\t\t\t\t? exportInfo.scale * (width / asset.props.w)\n\t\t\t\t: editor.getZoomLevel() * (width / asset.props.w)\n\n\t\t\tfunction resolve(asset: TLImageAsset | TLVideoAsset, url: string | null) {\n\t\t\t\tif (isCancelled) return // don't update if the hook has remounted\n\t\t\t\tif (previousUrl.current === url) return // don't update the state if the url is the same\n\t\t\t\tdidAlreadyResolve.current = true // mark that we've resolved our first image\n\t\t\t\tpreviousUrl.current = url // keep the url around to compare with the next one\n\t\t\t\tsetResult({ asset, url })\n\t\t\t\texportIsReady() // let the SVG export know we're ready for export\n\t\t\t}\n\n\t\t\t// If we already resolved the URL, debounce fetching potentially multiple image variations.\n\t\t\tif (didAlreadyResolve.current) {\n\t\t\t\tlet tick = 0\n\n\t\t\t\tconst resolveAssetAfterAWhile = () => {\n\t\t\t\t\ttick++\n\t\t\t\t\tif (tick > 500 / 16) {\n\t\t\t\t\t\t// debounce for 500ms\n\t\t\t\t\t\tresolveAssetUrl(editor, assetId, screenScale, exportInfo, (url) => resolve(asset, url))\n\t\t\t\t\t\tcancelDebounceFn?.()\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcancelDebounceFn?.()\n\t\t\t\teditor.on('tick', resolveAssetAfterAWhile)\n\t\t\t\tcancelDebounceFn = () => editor.off('tick', resolveAssetAfterAWhile)\n\t\t\t} else {\n\t\t\t\tresolveAssetUrl(editor, assetId, screenScale, exportInfo, (url) => resolve(asset, url))\n\t\t\t}\n\t\t})\n\n\t\treturn () => {\n\t\t\tcleanupEffectScheduler()\n\t\t\tcancelDebounceFn?.()\n\t\t\tisCancelled = true\n\t\t}\n\t}, [editor, assetId, exportInfo, exportIsReady, shapeId, width])\n\n\treturn result\n}\n\nfunction resolveAssetUrl(\n\teditor: Editor,\n\tassetId: TLAssetId,\n\tscreenScale: number,\n\texportInfo: SvgExportContext | null,\n\tcallback: (url: string | null) => void\n) {\n\teditor\n\t\t.resolveAssetUrl(assetId, {\n\t\t\tscreenScale,\n\t\t\tshouldResolveToOriginal: exportInfo ? exportInfo.pixelRatio === null : false,\n\t\t\tdpr: exportInfo?.pixelRatio ?? undefined,\n\t\t})\n\t\t// There's a weird bug with out debounce function that doesn't\n\t\t// make it work right with async functions, so we use a callback\n\t\t// here instead of returning a promise.\n\t\t.then((url) => {\n\t\t\tcallback(url)\n\t\t})\n}\n\n/**\n * @deprecated Use {@link useImageOrVideoAsset} instead.\n *\n * @public\n */\nexport const useAsset = useImageOrVideoAsset\n"],
5
- "mappings": "AAAA;AAAA,EAOC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,SAAS,WAAW,QAAQ,gBAAgB;AAgCrC,SAAS,qBAAqB,EAAE,SAAS,SAAS,MAAM,GAAgC;AAC9F,QAAM,SAAS,UAAU;AACzB,QAAM,aAAa,oBAAoB;AACvC,QAAM,gBAAgB,kBAAkB;AAGxC,QAAM,CAAC,QAAQ,SAAS,IAAI,SAGzB,OAAO;AAAA,IACT,OAAO,UAAW,OAAO,SAAsC,OAAO,KAAK,OAAQ;AAAA,IACnF,KAAK;AAAA,EACN,EAAE;AAGF,QAAM,oBAAoB,OAAO,KAAK;AAGtC,QAAM,cAAc,OAAsB,IAAI;AAE9C,YAAU,MAAM;AACf,QAAI,CAAC,QAAS;AAEd,QAAI,cAAc;AAClB,QAAI;AAEJ,UAAM,yBAAyB,MAAM,gBAAgB,MAAM;AAC1D,UAAI,CAAC,cAAc,WAAW,OAAO,gBAAgB,EAAE,IAAI,OAAO,EAAG;AAGrE,YAAM,QAAQ,OAAO,SAAsC,OAAO;AAClE,UAAI,CAAC,OAAO;AAEX,kBAAU,CAAC,UAAU,EAAE,GAAG,MAAM,OAAO,MAAM,KAAK,KAAK,EAAE;AACzD;AAAA,MACD;AAGA,UAAI,CAAC,MAAM,MAAM,KAAK;AACrB,cAAM,UAAU,OAAO,yBAAyB,MAAM,EAAE;AACxD,YAAI,SAAS;AACZ,cAAI,YAAY,YAAY,SAAS;AACpC,wBAAY,UAAU;AACtB,sBAAU,CAAC,UAAU,EAAE,GAAG,MAAM,eAAe,MAAM,KAAK,QAAQ,EAAE;AACpE,0BAAc;AAAA,UACf;AACA;AAAA,QACD;AAAA,MACD;AAIA,YAAM,cAAc,aACjB,WAAW,SAAS,QAAQ,MAAM,MAAM,KACxC,OAAO,aAAa,KAAK,QAAQ,MAAM,MAAM;AAEhD,eAAS,QAAQA,QAAoC,KAAoB;AACxE,YAAI,YAAa;AACjB,YAAI,YAAY,YAAY,IAAK;AACjC,0BAAkB,UAAU;AAC5B,oBAAY,UAAU;AACtB,kBAAU,EAAE,OAAAA,QAAO,IAAI,CAAC;AACxB,sBAAc;AAAA,MACf;AAGA,UAAI,kBAAkB,SAAS;AAC9B,YAAI,OAAO;AAEX,cAAM,0BAA0B,MAAM;AACrC;AACA,cAAI,OAAO,MAAM,IAAI;AAEpB,4BAAgB,QAAQ,SAAS,aAAa,YAAY,CAAC,QAAQ,QAAQ,OAAO,GAAG,CAAC;AACtF,+BAAmB;AAAA,UACpB;AAAA,QACD;AAEA,2BAAmB;AACnB,eAAO,GAAG,QAAQ,uBAAuB;AACzC,2BAAmB,MAAM,OAAO,IAAI,QAAQ,uBAAuB;AAAA,MACpE,OAAO;AACN,wBAAgB,QAAQ,SAAS,aAAa,YAAY,CAAC,QAAQ,QAAQ,OAAO,GAAG,CAAC;AAAA,MACvF;AAAA,IACD,CAAC;AAED,WAAO,MAAM;AACZ,6BAAuB;AACvB,yBAAmB;AACnB,oBAAc;AAAA,IACf;AAAA,EACD,GAAG,CAAC,QAAQ,SAAS,YAAY,eAAe,SAAS,KAAK,CAAC;AAE/D,SAAO;AACR;AAEA,SAAS,gBACR,QACA,SACA,aACA,YACA,UACC;AACD,SACE,gBAAgB,SAAS;AAAA,IACzB;AAAA,IACA,yBAAyB,aAAa,WAAW,eAAe,OAAO;AAAA,IACvE,KAAK,YAAY,cAAc;AAAA,EAChC,CAAC,EAIA,KAAK,CAAC,QAAQ;AACd,aAAS,GAAG;AAAA,EACb,CAAC;AACH;AAOO,MAAM,WAAW;",
4
+ "sourcesContent": ["import {\n\tEditor,\n\tSvgExportContext,\n\tTLAssetId,\n\tTLImageAsset,\n\tTLShapeId,\n\tTLVideoAsset,\n\treact,\n\tuseDelaySvgExport,\n\tuseEditor,\n\tuseSvgExportContext,\n} from '@tldraw/editor'\nimport { useEffect, useRef, useState } from 'react'\n\n/**\n * Options for {@link useImageOrVideoAsset}.\n *\n * @public\n */\nexport interface UseImageOrVideoAssetOptions {\n\t/** The asset ID you want a URL for. */\n\tassetId: TLAssetId | null\n\t/**\n\t * The shape the asset is being used for. We won't update the resolved URL while the shape is\n\t * off-screen.\n\t */\n\tshapeId?: TLShapeId\n\t/**\n\t * The width at which the asset will be displayed, in shape-space pixels.\n\t */\n\twidth: number\n}\n\n/**\n * This is a handy helper hook that resolves an asset to an optimized URL for a given shape, or its\n * {@link @tldraw/editor#Editor.createTemporaryAssetPreview | placeholder} if the asset is still\n * uploading. This is used in particular for high-resolution images when you want lower and higher\n * resolution depending on the size of the image on the canvas and the zoom level.\n *\n * For image scaling to work, you need to implement scaled URLs in\n * {@link @tldraw/tlschema#TLAssetStore.resolve}.\n *\n * @public\n */\nexport function useImageOrVideoAsset({ shapeId, assetId, width }: UseImageOrVideoAssetOptions) {\n\tconst editor = useEditor()\n\tconst exportInfo = useSvgExportContext()\n\tconst exportIsReady = useDelaySvgExport()\n\n\t// We use a state to store the result of the asset resolution, and we're going to avoid updating this whenever we can\n\tconst [result, setResult] = useState<{\n\t\tasset: (TLImageAsset | TLVideoAsset) | null\n\t\turl: string | null\n\t}>(() => ({\n\t\tasset: assetId ? (editor.getAsset<TLImageAsset | TLVideoAsset>(assetId) ?? null) : null,\n\t\turl: null as string | null,\n\t}))\n\n\t// A flag for whether we've resolved the asset URL at least once, after which we can debounce\n\tconst didAlreadyResolve = useRef(false)\n\n\t// The last URL that we've seen for the shape\n\tconst previousUrl = useRef<string | null>(null)\n\n\tuseEffect(() => {\n\t\tif (!assetId) return\n\n\t\tlet isCancelled = false\n\t\tlet cancelDebounceFn: (() => void) | undefined\n\n\t\tconst cleanupEffectScheduler = react('update state', () => {\n\t\t\tif (!exportInfo && shapeId && editor.getCulledShapes().has(shapeId)) return\n\n\t\t\t// Get the fresh asset\n\t\t\tconst asset = editor.getAsset<TLImageAsset | TLVideoAsset>(assetId)\n\t\t\tif (!asset) {\n\t\t\t\t// If the asset is deleted, such as when an upload fails, set the URL to null\n\t\t\t\tsetResult((prev) => ({ ...prev, asset: null, url: null }))\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Set initial preview for the shape if it has no source (if it was pasted into a local project as base64)\n\t\t\tif (!asset.props.src) {\n\t\t\t\tconst preview = editor.getTemporaryAssetPreview(asset.id)\n\t\t\t\tif (preview) {\n\t\t\t\t\tif (previousUrl.current !== preview) {\n\t\t\t\t\t\tpreviousUrl.current = preview // just for kicks, let's save the url as the previous URL\n\t\t\t\t\t\tsetResult((prev) => ({ ...prev, isPlaceholder: true, url: preview })) // set the preview as the URL\n\t\t\t\t\t\texportIsReady() // let the SVG export know we're ready for export\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// aside ...we could bail here if the only thing that has changed is the shape has changed from culled to not culled\n\n\t\t\tconst screenScale = exportInfo\n\t\t\t\t? exportInfo.scale * (width / asset.props.w)\n\t\t\t\t: editor.getZoomLevel() * (width / asset.props.w)\n\n\t\t\tfunction resolve(asset: TLImageAsset | TLVideoAsset, url: string | null) {\n\t\t\t\tif (isCancelled) return // don't update if the hook has remounted\n\t\t\t\tif (previousUrl.current === url) return // don't update the state if the url is the same\n\t\t\t\tdidAlreadyResolve.current = true // mark that we've resolved our first image\n\t\t\t\tpreviousUrl.current = url // keep the url around to compare with the next one\n\t\t\t\tsetResult({ asset, url })\n\t\t\t\texportIsReady() // let the SVG export know we're ready for export\n\t\t\t}\n\n\t\t\t// If we already resolved the URL, debounce fetching potentially multiple image variations.\n\t\t\tif (didAlreadyResolve.current) {\n\t\t\t\tlet tick = 0\n\n\t\t\t\tconst resolveAssetAfterAWhile = () => {\n\t\t\t\t\ttick++\n\t\t\t\t\tif (tick > 500 / 16) {\n\t\t\t\t\t\t// debounce for 500ms\n\t\t\t\t\t\tresolveAssetUrl(editor, assetId, screenScale, exportInfo, (url) => resolve(asset, url))\n\t\t\t\t\t\tcancelDebounceFn?.()\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcancelDebounceFn?.()\n\t\t\t\teditor.on('tick', resolveAssetAfterAWhile)\n\t\t\t\tcancelDebounceFn = () => editor.off('tick', resolveAssetAfterAWhile)\n\t\t\t} else {\n\t\t\t\tresolveAssetUrl(editor, assetId, screenScale, exportInfo, (url) => resolve(asset, url))\n\t\t\t}\n\t\t})\n\n\t\treturn () => {\n\t\t\tcleanupEffectScheduler()\n\t\t\tcancelDebounceFn?.()\n\t\t\tisCancelled = true\n\t\t}\n\t}, [editor, assetId, exportInfo, exportIsReady, shapeId, width])\n\n\treturn result\n}\n\nfunction resolveAssetUrl(\n\teditor: Editor,\n\tassetId: TLAssetId,\n\tscreenScale: number,\n\texportInfo: SvgExportContext | null,\n\tcallback: (url: string | null) => void\n) {\n\teditor\n\t\t.resolveAssetUrl(assetId, {\n\t\t\tscreenScale,\n\t\t\tshouldResolveToOriginal: exportInfo ? exportInfo.pixelRatio === null : false,\n\t\t\tdpr: exportInfo?.pixelRatio ?? undefined,\n\t\t})\n\t\t// There's a weird bug with out debounce function that doesn't\n\t\t// make it work right with async functions, so we use a callback\n\t\t// here instead of returning a promise.\n\t\t.then((url) => {\n\t\t\tcallback(url)\n\t\t})\n}\n"],
5
+ "mappings": "AAAA;AAAA,EAOC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,SAAS,WAAW,QAAQ,gBAAgB;AAgCrC,SAAS,qBAAqB,EAAE,SAAS,SAAS,MAAM,GAAgC;AAC9F,QAAM,SAAS,UAAU;AACzB,QAAM,aAAa,oBAAoB;AACvC,QAAM,gBAAgB,kBAAkB;AAGxC,QAAM,CAAC,QAAQ,SAAS,IAAI,SAGzB,OAAO;AAAA,IACT,OAAO,UAAW,OAAO,SAAsC,OAAO,KAAK,OAAQ;AAAA,IACnF,KAAK;AAAA,EACN,EAAE;AAGF,QAAM,oBAAoB,OAAO,KAAK;AAGtC,QAAM,cAAc,OAAsB,IAAI;AAE9C,YAAU,MAAM;AACf,QAAI,CAAC,QAAS;AAEd,QAAI,cAAc;AAClB,QAAI;AAEJ,UAAM,yBAAyB,MAAM,gBAAgB,MAAM;AAC1D,UAAI,CAAC,cAAc,WAAW,OAAO,gBAAgB,EAAE,IAAI,OAAO,EAAG;AAGrE,YAAM,QAAQ,OAAO,SAAsC,OAAO;AAClE,UAAI,CAAC,OAAO;AAEX,kBAAU,CAAC,UAAU,EAAE,GAAG,MAAM,OAAO,MAAM,KAAK,KAAK,EAAE;AACzD;AAAA,MACD;AAGA,UAAI,CAAC,MAAM,MAAM,KAAK;AACrB,cAAM,UAAU,OAAO,yBAAyB,MAAM,EAAE;AACxD,YAAI,SAAS;AACZ,cAAI,YAAY,YAAY,SAAS;AACpC,wBAAY,UAAU;AACtB,sBAAU,CAAC,UAAU,EAAE,GAAG,MAAM,eAAe,MAAM,KAAK,QAAQ,EAAE;AACpE,0BAAc;AAAA,UACf;AACA;AAAA,QACD;AAAA,MACD;AAIA,YAAM,cAAc,aACjB,WAAW,SAAS,QAAQ,MAAM,MAAM,KACxC,OAAO,aAAa,KAAK,QAAQ,MAAM,MAAM;AAEhD,eAAS,QAAQA,QAAoC,KAAoB;AACxE,YAAI,YAAa;AACjB,YAAI,YAAY,YAAY,IAAK;AACjC,0BAAkB,UAAU;AAC5B,oBAAY,UAAU;AACtB,kBAAU,EAAE,OAAAA,QAAO,IAAI,CAAC;AACxB,sBAAc;AAAA,MACf;AAGA,UAAI,kBAAkB,SAAS;AAC9B,YAAI,OAAO;AAEX,cAAM,0BAA0B,MAAM;AACrC;AACA,cAAI,OAAO,MAAM,IAAI;AAEpB,4BAAgB,QAAQ,SAAS,aAAa,YAAY,CAAC,QAAQ,QAAQ,OAAO,GAAG,CAAC;AACtF,+BAAmB;AAAA,UACpB;AAAA,QACD;AAEA,2BAAmB;AACnB,eAAO,GAAG,QAAQ,uBAAuB;AACzC,2BAAmB,MAAM,OAAO,IAAI,QAAQ,uBAAuB;AAAA,MACpE,OAAO;AACN,wBAAgB,QAAQ,SAAS,aAAa,YAAY,CAAC,QAAQ,QAAQ,OAAO,GAAG,CAAC;AAAA,MACvF;AAAA,IACD,CAAC;AAED,WAAO,MAAM;AACZ,6BAAuB;AACvB,yBAAmB;AACnB,oBAAc;AAAA,IACf;AAAA,EACD,GAAG,CAAC,QAAQ,SAAS,YAAY,eAAe,SAAS,KAAK,CAAC;AAE/D,SAAO;AACR;AAEA,SAAS,gBACR,QACA,SACA,aACA,YACA,UACC;AACD,SACE,gBAAgB,SAAS;AAAA,IACzB;AAAA,IACA,yBAAyB,aAAa,WAAW,eAAe,OAAO;AAAA,IACvE,KAAK,YAAY,cAAc;AAAA,EAChC,CAAC,EAIA,KAAK,CAAC,QAAQ;AACd,aAAS,GAAG;AAAA,EACb,CAAC;AACH;",
6
6
  "names": ["asset"]
7
7
  }
@@ -1,5 +1,5 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
- import { preventDefault, stopEventPropagation } from "@tldraw/editor";
2
+ import { markEventAsHandled, preventDefault } from "@tldraw/editor";
3
3
  import React from "react";
4
4
  const PlainTextArea = React.forwardRef(function TextArea({
5
5
  isEditing,
@@ -37,8 +37,8 @@ const PlainTextArea = React.forwardRef(function TextArea({
37
37
  onChange,
38
38
  onKeyDown: (e) => handleKeyDown(e.nativeEvent),
39
39
  onBlur: handleBlur,
40
- onTouchEnd: stopEventPropagation,
41
- onContextMenu: isEditing ? stopEventPropagation : void 0,
40
+ onTouchEnd: markEventAsHandled,
41
+ onContextMenu: isEditing ? (e) => e.stopPropagation() : void 0,
42
42
  onPointerDown: handleInputPointerDown,
43
43
  onPaste: handlePaste,
44
44
  onDoubleClick: handleDoubleClick,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/shapes/text/PlainTextArea.tsx"],
4
- "sourcesContent": ["import { preventDefault, stopEventPropagation } from '@tldraw/editor'\nimport React from 'react'\nimport { TextAreaProps } from './RichTextArea'\n\n/**\n * A plain text area that can be used for basic editing text.\n *\n * @public @react\n */\nexport const PlainTextArea = React.forwardRef<HTMLTextAreaElement, TextAreaProps>(function TextArea(\n\t{\n\t\tisEditing,\n\t\ttext,\n\t\thandleFocus,\n\t\thandleChange,\n\t\thandleKeyDown,\n\t\thandlePaste,\n\t\thandleBlur,\n\t\thandleInputPointerDown,\n\t\thandleDoubleClick,\n\t},\n\tref\n) {\n\tconst onChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n\t\thandleChange({ plaintext: e.target.value })\n\t}\n\n\treturn (\n\t\t<textarea\n\t\t\tref={ref}\n\t\t\tclassName=\"tl-text tl-text-input\"\n\t\t\tname=\"text\"\n\t\t\ttabIndex={-1}\n\t\t\tdisabled={!isEditing}\n\t\t\treadOnly={!isEditing}\n\t\t\tautoComplete=\"off\"\n\t\t\tautoCapitalize=\"off\"\n\t\t\tautoCorrect=\"off\"\n\t\t\tautoSave=\"off\"\n\t\t\tplaceholder=\"\"\n\t\t\tspellCheck=\"true\"\n\t\t\twrap=\"off\"\n\t\t\tdir=\"auto\"\n\t\t\tdefaultValue={text}\n\t\t\tonFocus={handleFocus}\n\t\t\tonChange={onChange}\n\t\t\tonKeyDown={(e) => handleKeyDown(e.nativeEvent)}\n\t\t\tonBlur={handleBlur}\n\t\t\tonTouchEnd={stopEventPropagation}\n\t\t\tonContextMenu={isEditing ? stopEventPropagation : undefined}\n\t\t\tonPointerDown={handleInputPointerDown}\n\t\t\tonPaste={handlePaste}\n\t\t\tonDoubleClick={handleDoubleClick}\n\t\t\t// On FF, there's a behavior where dragging a selection will grab that selection into\n\t\t\t// the drag event. However, once the drag is over, and you select away from the textarea,\n\t\t\t// starting a drag over the textarea will restart a selection drag instead of a shape drag.\n\t\t\t// This prevents that default behavior in FF.\n\t\t\tonDragStart={preventDefault}\n\t\t/>\n\t)\n})\n"],
5
- "mappings": "AA4BE;AA5BF,SAAS,gBAAgB,4BAA4B;AACrD,OAAO,WAAW;AAQX,MAAM,gBAAgB,MAAM,WAA+C,SAAS,SAC1F;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,GACA,KACC;AACD,QAAM,WAAW,CAAC,MAA8C;AAC/D,iBAAa,EAAE,WAAW,EAAE,OAAO,MAAM,CAAC;AAAA,EAC3C;AAEA,SACC;AAAA,IAAC;AAAA;AAAA,MACA;AAAA,MACA,WAAU;AAAA,MACV,MAAK;AAAA,MACL,UAAU;AAAA,MACV,UAAU,CAAC;AAAA,MACX,UAAU,CAAC;AAAA,MACX,cAAa;AAAA,MACb,gBAAe;AAAA,MACf,aAAY;AAAA,MACZ,UAAS;AAAA,MACT,aAAY;AAAA,MACZ,YAAW;AAAA,MACX,MAAK;AAAA,MACL,KAAI;AAAA,MACJ,cAAc;AAAA,MACd,SAAS;AAAA,MACT;AAAA,MACA,WAAW,CAAC,MAAM,cAAc,EAAE,WAAW;AAAA,MAC7C,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,eAAe,YAAY,uBAAuB;AAAA,MAClD,eAAe;AAAA,MACf,SAAS;AAAA,MACT,eAAe;AAAA,MAKf,aAAa;AAAA;AAAA,EACd;AAEF,CAAC;",
4
+ "sourcesContent": ["import { markEventAsHandled, preventDefault } from '@tldraw/editor'\nimport React from 'react'\nimport { TextAreaProps } from './RichTextArea'\n\n/**\n * A plain text area that can be used for basic editing text.\n *\n * @public @react\n */\nexport const PlainTextArea = React.forwardRef<HTMLTextAreaElement, TextAreaProps>(function TextArea(\n\t{\n\t\tisEditing,\n\t\ttext,\n\t\thandleFocus,\n\t\thandleChange,\n\t\thandleKeyDown,\n\t\thandlePaste,\n\t\thandleBlur,\n\t\thandleInputPointerDown,\n\t\thandleDoubleClick,\n\t},\n\tref\n) {\n\tconst onChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n\t\thandleChange({ plaintext: e.target.value })\n\t}\n\n\treturn (\n\t\t<textarea\n\t\t\tref={ref}\n\t\t\tclassName=\"tl-text tl-text-input\"\n\t\t\tname=\"text\"\n\t\t\ttabIndex={-1}\n\t\t\tdisabled={!isEditing}\n\t\t\treadOnly={!isEditing}\n\t\t\tautoComplete=\"off\"\n\t\t\tautoCapitalize=\"off\"\n\t\t\tautoCorrect=\"off\"\n\t\t\tautoSave=\"off\"\n\t\t\tplaceholder=\"\"\n\t\t\tspellCheck=\"true\"\n\t\t\twrap=\"off\"\n\t\t\tdir=\"auto\"\n\t\t\tdefaultValue={text}\n\t\t\tonFocus={handleFocus}\n\t\t\tonChange={onChange}\n\t\t\tonKeyDown={(e) => handleKeyDown(e.nativeEvent)}\n\t\t\tonBlur={handleBlur}\n\t\t\tonTouchEnd={markEventAsHandled}\n\t\t\tonContextMenu={isEditing ? (e) => e.stopPropagation() : undefined}\n\t\t\tonPointerDown={handleInputPointerDown}\n\t\t\tonPaste={handlePaste}\n\t\t\tonDoubleClick={handleDoubleClick}\n\t\t\t// On FF, there's a behavior where dragging a selection will grab that selection into\n\t\t\t// the drag event. However, once the drag is over, and you select away from the textarea,\n\t\t\t// starting a drag over the textarea will restart a selection drag instead of a shape drag.\n\t\t\t// This prevents that default behavior in FF.\n\t\t\tonDragStart={preventDefault}\n\t\t/>\n\t)\n})\n"],
5
+ "mappings": "AA4BE;AA5BF,SAAS,oBAAoB,sBAAsB;AACnD,OAAO,WAAW;AAQX,MAAM,gBAAgB,MAAM,WAA+C,SAAS,SAC1F;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,GACA,KACC;AACD,QAAM,WAAW,CAAC,MAA8C;AAC/D,iBAAa,EAAE,WAAW,EAAE,OAAO,MAAM,CAAC;AAAA,EAC3C;AAEA,SACC;AAAA,IAAC;AAAA;AAAA,MACA;AAAA,MACA,WAAU;AAAA,MACV,MAAK;AAAA,MACL,UAAU;AAAA,MACV,UAAU,CAAC;AAAA,MACX,UAAU,CAAC;AAAA,MACX,cAAa;AAAA,MACb,gBAAe;AAAA,MACf,aAAY;AAAA,MACZ,UAAS;AAAA,MACT,aAAY;AAAA,MACZ,YAAW;AAAA,MACX,MAAK;AAAA,MACL,KAAI;AAAA,MACJ,cAAc;AAAA,MACd,SAAS;AAAA,MACT;AAAA,MACA,WAAW,CAAC,MAAM,cAAc,EAAE,WAAW;AAAA,MAC7C,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,eAAe,YAAY,CAAC,MAAM,EAAE,gBAAgB,IAAI;AAAA,MACxD,eAAe;AAAA,MACf,SAAS;AAAA,MACT,eAAe;AAAA,MAKf,aAAa;AAAA;AAAA,EACd;AAEF,CAAC;",
6
6
  "names": []
7
7
  }
@@ -4,7 +4,6 @@ import {
4
4
  } from "@tiptap/react";
5
5
  import {
6
6
  preventDefault,
7
- stopEventPropagation,
8
7
  useEditor,
9
8
  useEvent,
10
9
  useUniqueSafeId
@@ -158,9 +157,9 @@ const RichTextArea = React.forwardRef(function RichTextArea2({
158
157
  tabIndex: -1,
159
158
  "data-testid": "rich-text-area",
160
159
  className: "tl-rich-text tl-text tl-text-input",
161
- onContextMenu: isEditing ? stopEventPropagation : void 0,
162
- onPointerDownCapture: stopEventPropagation,
163
- onTouchEnd: stopEventPropagation,
160
+ onContextMenu: isEditing ? (e) => e.stopPropagation() : void 0,
161
+ onPointerDownCapture: (e) => e.stopPropagation(),
162
+ onTouchEnd: (e) => e.stopPropagation(),
164
163
  onDragStart: preventDefault,
165
164
  children: /* @__PURE__ */ jsx("div", { className: "tl-rich-text", ref: rTextEditorEl })
166
165
  }