tldraw 3.16.0-canary.f56a36d13420 → 3.16.0-canary.f5bf2b535ea7

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 (274) hide show
  1. package/dist-cjs/index.d.ts +223 -109
  2. package/dist-cjs/index.js +29 -14
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/defaultExternalContentHandlers.js +10 -0
  5. package/dist-cjs/lib/defaultExternalContentHandlers.js.map +2 -2
  6. package/dist-cjs/lib/shapes/arrow/arrow-types.js.map +1 -1
  7. package/dist-cjs/lib/shapes/arrow/arrowLabel.js +6 -0
  8. package/dist-cjs/lib/shapes/arrow/arrowLabel.js.map +3 -3
  9. package/dist-cjs/lib/shapes/arrow/arrowTargetState.js +3 -2
  10. package/dist-cjs/lib/shapes/arrow/arrowTargetState.js.map +2 -2
  11. package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js +1 -1
  12. package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js.map +2 -2
  13. package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js +4 -4
  14. package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js.map +2 -2
  15. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js +2 -1
  16. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js.map +2 -2
  17. package/dist-cjs/lib/shapes/frame/components/FrameLabelInput.js +8 -2
  18. package/dist-cjs/lib/shapes/frame/components/FrameLabelInput.js.map +2 -2
  19. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js +1 -0
  20. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js.map +2 -2
  21. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js +2 -1
  22. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js.map +2 -2
  23. package/dist-cjs/lib/shapes/shared/HyperlinkButton.js +4 -4
  24. package/dist-cjs/lib/shapes/shared/HyperlinkButton.js.map +2 -2
  25. package/dist-cjs/lib/shapes/shared/PlainTextLabel.js +1 -3
  26. package/dist-cjs/lib/shapes/shared/PlainTextLabel.js.map +2 -2
  27. package/dist-cjs/lib/shapes/shared/useEditablePlainText.js +3 -5
  28. package/dist-cjs/lib/shapes/shared/useEditablePlainText.js.map +2 -2
  29. package/dist-cjs/lib/shapes/shared/useImageOrVideoAsset.js +0 -2
  30. package/dist-cjs/lib/shapes/shared/useImageOrVideoAsset.js.map +2 -2
  31. package/dist-cjs/lib/shapes/text/PlainTextArea.js +3 -2
  32. package/dist-cjs/lib/shapes/text/PlainTextArea.js.map +2 -2
  33. package/dist-cjs/lib/shapes/text/RichTextArea.js +3 -3
  34. package/dist-cjs/lib/shapes/text/RichTextArea.js.map +2 -2
  35. package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js +3 -1
  36. package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js.map +2 -2
  37. package/dist-cjs/lib/ui/components/A11y.js +1 -1
  38. package/dist-cjs/lib/ui/components/A11y.js.map +2 -2
  39. package/dist-cjs/lib/ui/components/LanguageMenu.js +1 -0
  40. package/dist-cjs/lib/ui/components/LanguageMenu.js.map +2 -2
  41. package/dist-cjs/lib/ui/components/Minimap/DefaultMinimap.js +2 -1
  42. package/dist-cjs/lib/ui/components/Minimap/DefaultMinimap.js.map +2 -2
  43. package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js +1 -1
  44. package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js.map +2 -2
  45. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js +9 -4
  46. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js.map +2 -2
  47. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js +255 -316
  48. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js.map +2 -2
  49. package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js +147 -0
  50. package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js.map +7 -0
  51. package/dist-cjs/lib/ui/components/StylePanel/StylePanelContext.js +68 -0
  52. package/dist-cjs/lib/ui/components/StylePanel/StylePanelContext.js.map +7 -0
  53. package/dist-cjs/lib/ui/components/StylePanel/{DoubleDropdownPicker.js → StylePanelDoubleDropdownPicker.js} +23 -22
  54. package/dist-cjs/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.js.map +7 -0
  55. package/dist-cjs/lib/ui/components/StylePanel/{DropdownPicker.js → StylePanelDropdownPicker.js} +23 -20
  56. package/dist-cjs/lib/ui/components/StylePanel/StylePanelDropdownPicker.js.map +7 -0
  57. package/dist-cjs/lib/ui/components/StylePanel/StylePanelSubheading.js +28 -0
  58. package/dist-cjs/lib/ui/components/StylePanel/StylePanelSubheading.js.map +7 -0
  59. package/dist-cjs/lib/ui/components/Toolbar/AltTextEditor.js +2 -0
  60. package/dist-cjs/lib/ui/components/Toolbar/AltTextEditor.js.map +2 -2
  61. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js +38 -9
  62. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js.map +2 -2
  63. package/dist-cjs/lib/ui/components/Toolbar/DefaultVideoToolbarContent.js +15 -3
  64. package/dist-cjs/lib/ui/components/Toolbar/DefaultVideoToolbarContent.js.map +2 -2
  65. package/dist-cjs/lib/ui/components/Toolbar/LinkEditor.js +2 -1
  66. package/dist-cjs/lib/ui/components/Toolbar/LinkEditor.js.map +2 -2
  67. package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js +1 -1
  68. package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js.map +2 -2
  69. package/dist-cjs/lib/ui/components/Toolbar/ToggleToolLockedButton.js +6 -2
  70. package/dist-cjs/lib/ui/components/Toolbar/ToggleToolLockedButton.js.map +2 -2
  71. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js +11 -2
  72. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js.map +2 -2
  73. package/dist-cjs/lib/ui/components/primitives/TldrawUiInput.js +5 -3
  74. package/dist-cjs/lib/ui/components/primitives/TldrawUiInput.js.map +2 -2
  75. package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js +18 -5
  76. package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js.map +2 -2
  77. package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js +3 -0
  78. package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js.map +2 -2
  79. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js +47 -3
  80. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js.map +2 -2
  81. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.js +3 -0
  82. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.js.map +2 -2
  83. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js +8 -8
  84. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js.map +2 -2
  85. package/dist-cjs/lib/ui/context/actions.js +13 -8
  86. package/dist-cjs/lib/ui/context/actions.js.map +2 -2
  87. package/dist-cjs/lib/ui/hooks/useClipboardEvents.js +1 -1
  88. package/dist-cjs/lib/ui/hooks/useClipboardEvents.js.map +2 -2
  89. package/dist-cjs/lib/ui/hooks/useExportAs.js +3 -2
  90. package/dist-cjs/lib/ui/hooks/useExportAs.js.map +2 -2
  91. package/dist-cjs/lib/ui/hooks/useTools.js +1 -1
  92. package/dist-cjs/lib/ui/hooks/useTools.js.map +2 -2
  93. package/dist-cjs/lib/ui/hooks/useTranslation/TLUiTranslationKey.js.map +1 -1
  94. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js +5 -2
  95. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js.map +2 -2
  96. package/dist-cjs/lib/ui/version.js +3 -3
  97. package/dist-cjs/lib/ui/version.js.map +1 -1
  98. package/dist-cjs/lib/utils/export/copyAs.js +1 -2
  99. package/dist-cjs/lib/utils/export/copyAs.js.map +2 -2
  100. package/dist-cjs/lib/utils/export/export.js +0 -20
  101. package/dist-cjs/lib/utils/export/export.js.map +2 -2
  102. package/dist-cjs/lib/utils/export/exportAs.js +1 -2
  103. package/dist-cjs/lib/utils/export/exportAs.js.map +2 -2
  104. package/dist-esm/index.d.mts +223 -109
  105. package/dist-esm/index.mjs +59 -28
  106. package/dist-esm/index.mjs.map +2 -2
  107. package/dist-esm/lib/defaultExternalContentHandlers.mjs +10 -0
  108. package/dist-esm/lib/defaultExternalContentHandlers.mjs.map +2 -2
  109. package/dist-esm/lib/shapes/arrow/arrowLabel.mjs +6 -0
  110. package/dist-esm/lib/shapes/arrow/arrowLabel.mjs.map +3 -3
  111. package/dist-esm/lib/shapes/arrow/arrowTargetState.mjs +3 -2
  112. package/dist-esm/lib/shapes/arrow/arrowTargetState.mjs.map +2 -2
  113. package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs +1 -1
  114. package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs.map +2 -2
  115. package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs +4 -5
  116. package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs.map +2 -2
  117. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs +2 -1
  118. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs.map +2 -2
  119. package/dist-esm/lib/shapes/frame/components/FrameLabelInput.mjs +9 -3
  120. package/dist-esm/lib/shapes/frame/components/FrameLabelInput.mjs.map +2 -2
  121. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs +1 -0
  122. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs.map +2 -2
  123. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs +2 -1
  124. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs.map +2 -2
  125. package/dist-esm/lib/shapes/shared/HyperlinkButton.mjs +5 -5
  126. package/dist-esm/lib/shapes/shared/HyperlinkButton.mjs.map +2 -2
  127. package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs +1 -3
  128. package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs.map +2 -2
  129. package/dist-esm/lib/shapes/shared/useEditablePlainText.mjs +3 -6
  130. package/dist-esm/lib/shapes/shared/useEditablePlainText.mjs.map +2 -2
  131. package/dist-esm/lib/shapes/shared/useImageOrVideoAsset.mjs +0 -2
  132. package/dist-esm/lib/shapes/shared/useImageOrVideoAsset.mjs.map +2 -2
  133. package/dist-esm/lib/shapes/text/PlainTextArea.mjs +4 -3
  134. package/dist-esm/lib/shapes/text/PlainTextArea.mjs.map +2 -2
  135. package/dist-esm/lib/shapes/text/RichTextArea.mjs +3 -4
  136. package/dist-esm/lib/shapes/text/RichTextArea.mjs.map +2 -2
  137. package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs +3 -1
  138. package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs.map +2 -2
  139. package/dist-esm/lib/ui/components/A11y.mjs +1 -2
  140. package/dist-esm/lib/ui/components/A11y.mjs.map +2 -2
  141. package/dist-esm/lib/ui/components/LanguageMenu.mjs +1 -0
  142. package/dist-esm/lib/ui/components/LanguageMenu.mjs.map +2 -2
  143. package/dist-esm/lib/ui/components/Minimap/DefaultMinimap.mjs +2 -1
  144. package/dist-esm/lib/ui/components/Minimap/DefaultMinimap.mjs.map +2 -2
  145. package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs +1 -2
  146. package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs.map +2 -2
  147. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs +14 -5
  148. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs.map +2 -2
  149. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs +257 -320
  150. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs.map +2 -2
  151. package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs +135 -0
  152. package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs.map +7 -0
  153. package/dist-esm/lib/ui/components/StylePanel/StylePanelContext.mjs +48 -0
  154. package/dist-esm/lib/ui/components/StylePanel/StylePanelContext.mjs.map +7 -0
  155. package/dist-esm/lib/ui/components/StylePanel/{DoubleDropdownPicker.mjs → StylePanelDoubleDropdownPicker.mjs} +20 -19
  156. package/dist-esm/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.mjs.map +7 -0
  157. package/dist-esm/lib/ui/components/StylePanel/{DropdownPicker.mjs → StylePanelDropdownPicker.mjs} +20 -17
  158. package/dist-esm/lib/ui/components/StylePanel/StylePanelDropdownPicker.mjs.map +7 -0
  159. package/dist-esm/lib/ui/components/StylePanel/StylePanelSubheading.mjs +8 -0
  160. package/dist-esm/lib/ui/components/StylePanel/StylePanelSubheading.mjs.map +7 -0
  161. package/dist-esm/lib/ui/components/Toolbar/AltTextEditor.mjs +2 -0
  162. package/dist-esm/lib/ui/components/Toolbar/AltTextEditor.mjs.map +2 -2
  163. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs +38 -9
  164. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs.map +2 -2
  165. package/dist-esm/lib/ui/components/Toolbar/DefaultVideoToolbarContent.mjs +15 -3
  166. package/dist-esm/lib/ui/components/Toolbar/DefaultVideoToolbarContent.mjs.map +2 -2
  167. package/dist-esm/lib/ui/components/Toolbar/LinkEditor.mjs +2 -1
  168. package/dist-esm/lib/ui/components/Toolbar/LinkEditor.mjs.map +2 -2
  169. package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs +1 -1
  170. package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs.map +2 -2
  171. package/dist-esm/lib/ui/components/Toolbar/ToggleToolLockedButton.mjs +6 -2
  172. package/dist-esm/lib/ui/components/Toolbar/ToggleToolLockedButton.mjs.map +2 -2
  173. package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs +11 -3
  174. package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs.map +2 -2
  175. package/dist-esm/lib/ui/components/primitives/TldrawUiInput.mjs +6 -4
  176. package/dist-esm/lib/ui/components/primitives/TldrawUiInput.mjs.map +2 -2
  177. package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs +18 -5
  178. package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs.map +2 -2
  179. package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs +3 -0
  180. package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs.map +2 -2
  181. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs +48 -3
  182. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs.map +2 -2
  183. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.mjs +3 -0
  184. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.mjs.map +2 -2
  185. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs +8 -8
  186. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs.map +2 -2
  187. package/dist-esm/lib/ui/context/actions.mjs +13 -8
  188. package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
  189. package/dist-esm/lib/ui/hooks/useClipboardEvents.mjs +1 -2
  190. package/dist-esm/lib/ui/hooks/useClipboardEvents.mjs.map +2 -2
  191. package/dist-esm/lib/ui/hooks/useExportAs.mjs +3 -2
  192. package/dist-esm/lib/ui/hooks/useExportAs.mjs.map +2 -2
  193. package/dist-esm/lib/ui/hooks/useTools.mjs +1 -1
  194. package/dist-esm/lib/ui/hooks/useTools.mjs.map +2 -2
  195. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs +5 -2
  196. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs.map +2 -2
  197. package/dist-esm/lib/ui/version.mjs +3 -3
  198. package/dist-esm/lib/ui/version.mjs.map +1 -1
  199. package/dist-esm/lib/utils/export/copyAs.mjs +1 -2
  200. package/dist-esm/lib/utils/export/copyAs.mjs.map +2 -2
  201. package/dist-esm/lib/utils/export/export.mjs +0 -20
  202. package/dist-esm/lib/utils/export/export.mjs.map +2 -2
  203. package/dist-esm/lib/utils/export/exportAs.mjs +1 -2
  204. package/dist-esm/lib/utils/export/exportAs.mjs.map +2 -2
  205. package/package.json +3 -3
  206. package/src/index.ts +45 -21
  207. package/src/lib/defaultExternalContentHandlers.ts +14 -0
  208. package/src/lib/shapes/arrow/ArrowShapeOptions.test.ts +83 -13
  209. package/src/lib/shapes/arrow/ArrowShapeTool.test.ts +99 -5
  210. package/src/lib/shapes/arrow/ArrowShapeUtil.test.ts +41 -0
  211. package/src/lib/shapes/arrow/arrow-types.ts +3 -5
  212. package/src/lib/shapes/arrow/arrowLabel.ts +8 -0
  213. package/src/lib/shapes/arrow/arrowTargetState.ts +34 -3
  214. package/src/lib/shapes/arrow/toolStates/Pointing.tsx +1 -1
  215. package/src/lib/shapes/bookmark/BookmarkShapeUtil.tsx +4 -5
  216. package/src/lib/shapes/frame/FrameShapeUtil.tsx +1 -0
  217. package/src/lib/shapes/frame/components/FrameLabelInput.tsx +10 -3
  218. package/src/lib/shapes/geo/GeoShapeUtil.tsx +1 -0
  219. package/src/lib/shapes/note/NoteShapeUtil.tsx +1 -0
  220. package/src/lib/shapes/shared/HyperlinkButton.tsx +5 -5
  221. package/src/lib/shapes/shared/PlainTextLabel.tsx +0 -6
  222. package/src/lib/shapes/shared/useEditablePlainText.ts +3 -10
  223. package/src/lib/shapes/shared/useImageOrVideoAsset.ts +0 -7
  224. package/src/lib/shapes/text/PlainTextArea.tsx +4 -3
  225. package/src/lib/shapes/text/RichTextArea.tsx +3 -4
  226. package/src/lib/tools/SelectTool/childStates/DraggingHandle.tsx +6 -2
  227. package/src/lib/ui/components/A11y.tsx +1 -2
  228. package/src/lib/ui/components/LanguageMenu.tsx +1 -0
  229. package/src/lib/ui/components/Minimap/DefaultMinimap.tsx +2 -1
  230. package/src/lib/ui/components/PageMenu/DefaultPageMenu.tsx +1 -2
  231. package/src/lib/ui/components/StylePanel/DefaultStylePanel.tsx +27 -13
  232. package/src/lib/ui/components/StylePanel/DefaultStylePanelContent.tsx +260 -381
  233. package/src/lib/ui/components/{primitives/TldrawUiButtonPicker.tsx → StylePanel/StylePanelButtonPicker.tsx} +70 -50
  234. package/src/lib/ui/components/StylePanel/StylePanelContext.tsx +63 -0
  235. package/src/lib/ui/components/StylePanel/{DoubleDropdownPicker.tsx → StylePanelDoubleDropdownPicker.tsx} +28 -19
  236. package/src/lib/ui/components/StylePanel/StylePanelDropdownPicker.tsx +119 -0
  237. package/src/lib/ui/components/StylePanel/StylePanelSubheading.tsx +9 -0
  238. package/src/lib/ui/components/Toolbar/AltTextEditor.tsx +2 -0
  239. package/src/lib/ui/components/Toolbar/DefaultImageToolbarContent.tsx +32 -15
  240. package/src/lib/ui/components/Toolbar/DefaultVideoToolbarContent.tsx +12 -4
  241. package/src/lib/ui/components/Toolbar/LinkEditor.tsx +1 -0
  242. package/src/lib/ui/components/Toolbar/OverflowingToolbar.tsx +1 -1
  243. package/src/lib/ui/components/Toolbar/ToggleToolLockedButton.tsx +9 -2
  244. package/src/lib/ui/components/primitives/TldrawUiContextualToolbar.tsx +7 -3
  245. package/src/lib/ui/components/primitives/TldrawUiInput.tsx +6 -3
  246. package/src/lib/ui/components/primitives/TldrawUiSlider.tsx +52 -32
  247. package/src/lib/ui/components/primitives/TldrawUiToolbar.tsx +5 -1
  248. package/src/lib/ui/components/primitives/TldrawUiTooltip.tsx +67 -13
  249. package/src/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.tsx +4 -0
  250. package/src/lib/ui/components/primitives/menus/TldrawUiMenuItem.tsx +9 -9
  251. package/src/lib/ui/context/actions.tsx +20 -8
  252. package/src/lib/ui/hooks/useClipboardEvents.ts +1 -2
  253. package/src/lib/ui/hooks/useExportAs.ts +3 -2
  254. package/src/lib/ui/hooks/useTools.tsx +1 -1
  255. package/src/lib/ui/hooks/useTranslation/TLUiTranslationKey.ts +3 -0
  256. package/src/lib/ui/hooks/useTranslation/defaultTranslation.ts +5 -2
  257. package/src/lib/ui/version.ts +3 -3
  258. package/src/lib/ui.css +40 -3
  259. package/src/lib/utils/export/copyAs.ts +1 -24
  260. package/src/lib/utils/export/export.ts +0 -36
  261. package/src/lib/utils/export/exportAs.ts +1 -32
  262. package/src/test/TestEditor.ts +8 -2
  263. package/src/test/frames.test.ts +15 -0
  264. package/src/test/getCulledShapes.test.tsx +71 -2
  265. package/tldraw.css +48 -6
  266. package/dist-cjs/lib/ui/components/StylePanel/DoubleDropdownPicker.js.map +0 -7
  267. package/dist-cjs/lib/ui/components/StylePanel/DropdownPicker.js.map +0 -7
  268. package/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js +0 -131
  269. package/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js.map +0 -7
  270. package/dist-esm/lib/ui/components/StylePanel/DoubleDropdownPicker.mjs.map +0 -7
  271. package/dist-esm/lib/ui/components/StylePanel/DropdownPicker.mjs.map +0 -7
  272. package/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs +0 -115
  273. package/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs.map +0 -7
  274. package/src/lib/ui/components/StylePanel/DropdownPicker.tsx +0 -110
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/shapes/text/RichTextArea.tsx"],
4
- "sourcesContent": ["import { EditorView } from '@tiptap/pm/view'\nimport {\n\tEditorEvents,\n\tJSONContent,\n\tEditor as TextEditor,\n\ttype Editor as TTEditor,\n} from '@tiptap/react'\nimport {\n\tEditor,\n\tTLRichText,\n\tTLShapeId,\n\tpreventDefault,\n\tstopEventPropagation,\n\tuseEditor,\n\tuseEvent,\n\tuseUniqueSafeId,\n} from '@tldraw/editor'\nimport React, { useLayoutEffect, useRef } from 'react'\n\n/** @public */\nexport interface TextAreaProps {\n\tisEditing: boolean\n\ttext?: string\n\tshapeId: TLShapeId\n\trichText?: TLRichText\n\thandleFocus(): void\n\thandleBlur(): void\n\thandleKeyDown(e: KeyboardEvent): void\n\thandleChange(changeInfo: { plaintext?: string; richText?: TLRichText }): void\n\thandleInputPointerDown(e: React.PointerEvent<HTMLElement>): void\n\thandleDoubleClick(e: any): any\n\thandlePaste(e: ClipboardEvent | React.ClipboardEvent<HTMLTextAreaElement>): void\n\thasCustomTabBehavior?: boolean\n}\n\n/**\n * N.B. In Development mode you need to ensure you're testing this without StrictMode on.\n * Otherwise it's not gonna work as expected on iOS.\n * Specifically, it means that the virtual keyboard won't pop open sometimes\n * (iOS starts flipping out when you render multiple times when trying to focus something) .\n */\n\n/**\n * A rich text area that can be used for editing text with rich text formatting.\n * This component uses the TipTap editor under the hood.\n *\n * @public @react\n */\nexport const RichTextArea = React.forwardRef<HTMLDivElement, TextAreaProps>(function RichTextArea(\n\t{\n\t\tshapeId,\n\t\tisEditing,\n\t\trichText,\n\t\thandleFocus,\n\t\thandleChange,\n\t\thandleBlur,\n\t\thandleKeyDown,\n\t\thandleDoubleClick,\n\t\thasCustomTabBehavior,\n\t\thandlePaste,\n\t},\n\tref\n) {\n\tconst editor = useEditor()\n\tconst tipTapId = useUniqueSafeId('tip-tap-editor')\n\tconst tipTapConfig = editor.getTextOptions().tipTapConfig\n\n\tconst rInitialRichText = useRef(richText)\n\tconst rTextEditor = useRef<TTEditor | null>(null)\n\tconst rTextEditorEl = useRef<HTMLDivElement>(null)\n\n\tuseLayoutEffect(() => {\n\t\tif (!rTextEditor.current) {\n\t\t\trInitialRichText.current = richText\n\t\t} else if (rInitialRichText.current !== richText) {\n\t\t\trTextEditor.current.commands.setContent(richText as JSONContent)\n\t\t}\n\t}, [richText])\n\n\t// The order of events is:\n\t// - editor begins editing any shape\n\t// - we set listeners for select all / place caret events\n\t// - if the user is editing this shape, this component is rendered\n\t// - editor emits the select all event / place caret event\n\t// - the text editor is onCreate callback is called\n\tconst rCreateInfo = useRef({\n\t\tselectAll: false,\n\t\tcaretPosition: null as { x: number; y: number } | null,\n\t})\n\n\tuseLayoutEffect(() => {\n\t\tfunction selectAllIfEditing(event: { shapeId: TLShapeId }) {\n\t\t\tif (event.shapeId === editor.getEditingShapeId()) {\n\t\t\t\trCreateInfo.current.selectAll = true\n\t\t\t}\n\t\t}\n\n\t\tfunction placeCaret(event: { shapeId: TLShapeId; point: { x: number; y: number } }) {\n\t\t\tif (event.shapeId === editor.getEditingShapeId()) {\n\t\t\t\trCreateInfo.current.caretPosition = event.point\n\t\t\t}\n\t\t}\n\n\t\teditor.on('select-all-text', selectAllIfEditing)\n\t\teditor.on('place-caret', placeCaret)\n\t\treturn () => {\n\t\t\teditor.off('select-all-text', selectAllIfEditing)\n\t\t\teditor.off('place-caret', placeCaret)\n\t\t}\n\t}, [editor, isEditing])\n\n\tconst onChange = useEvent(handleChange)\n\tconst onKeyDown = useEvent(handleKeyDown)\n\tconst onFocus = useEvent(handleFocus)\n\tconst onBlur = useEvent(handleBlur)\n\tconst onDoubleClick = useEvent(handleDoubleClick)\n\tconst onPaste = useEvent(handlePaste)\n\tuseLayoutEffect(() => {\n\t\tif (!isEditing || !tipTapConfig || !rTextEditorEl.current) return\n\n\t\tconst { editorProps, ...restOfTipTapConfig } = tipTapConfig\n\n\t\t// Because React can double-render in Strict Mode, we need to make sure we're not setting\n\t\t// the text editor twice. This became more much more prevalent in React 19, but also it\n\t\t// started manifesting in some cases in Next 14.2 (which maybe patches React 18.3 in weird\n\t\t// ways). So we used to use EditorProvider but we into weird rendering issues.\n\t\tconst textEditorInstance = new TextEditor({\n\t\t\telement: rTextEditorEl.current,\n\t\t\tautofocus: true,\n\t\t\teditable: isEditing,\n\t\t\tonUpdate: (props: EditorEvents['update']) => {\n\t\t\t\tconst content: TLRichText = props.editor.state.doc.toJSON()\n\t\t\t\trInitialRichText.current = content\n\t\t\t\tonChange({ richText: content })\n\t\t\t},\n\t\t\tonFocus,\n\t\t\tonBlur,\n\t\t\t// onCreate is called after a `setTimeout(0)`\n\t\t\tonCreate: (props) => {\n\t\t\t\t// If we're not still editing the original shape, then don't do anything.\n\t\t\t\tif (editor.getEditingShapeId() !== shapeId) return\n\n\t\t\t\tconst textEditor = props.editor\n\t\t\t\teditor.setRichTextEditor(textEditor)\n\n\t\t\t\tconst { selectAll, caretPosition } = rCreateInfo.current\n\n\t\t\t\tif (selectAll) {\n\t\t\t\t\t// Select all of the text\n\t\t\t\t\ttextEditor.chain().focus().selectAll().run()\n\t\t\t\t} else if (caretPosition) {\n\t\t\t\t\t// Set the initial caret screen position\n\t\t\t\t\tconst pos = textEditor.view.posAtCoords({\n\t\t\t\t\t\tleft: caretPosition.x,\n\t\t\t\t\t\ttop: caretPosition.y,\n\t\t\t\t\t})?.pos\n\n\t\t\t\t\tif (pos) {\n\t\t\t\t\t\t// Focus to that position.\n\t\t\t\t\t\ttextEditor.chain().focus().setTextSelection(pos).run()\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// If no position, default to select all.\n\t\t\t\t\t\ttextEditor.chain().focus().selectAll().run()\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\teditorProps: {\n\t\t\t\thandleKeyDown: (view: EditorView, event: KeyboardEvent) => {\n\t\t\t\t\tif (!hasCustomTabBehavior && event.key === 'Tab') {\n\t\t\t\t\t\thandleTab(editor, view, event)\n\t\t\t\t\t}\n\n\t\t\t\t\tonKeyDown(event)\n\t\t\t\t},\n\t\t\t\thandlePaste: (view: EditorView, event: ClipboardEvent) => {\n\t\t\t\t\tonPaste(event)\n\t\t\t\t\tif (event.defaultPrevented) return true\n\t\t\t\t},\n\t\t\t\thandleDoubleClick: (_view, _pos, event) => onDoubleClick(event),\n\t\t\t\t...editorProps,\n\t\t\t},\n\t\t\tcoreExtensionOptions: {\n\t\t\t\tclipboardTextSerializer: {\n\t\t\t\t\tblockSeparator: '\\n',\n\t\t\t\t},\n\t\t\t},\n\t\t\t...restOfTipTapConfig,\n\t\t\tcontent: rInitialRichText.current as JSONContent,\n\t\t})\n\n\t\t// XXX: When creating a brand new shape and double-clicking into it quickly to edit it,\n\t\t// there's some kind of race condition happening where the editor doesn't focus properly.\n\t\tconst timeout = editor.timers.setTimeout(() => {\n\t\t\tif (rCreateInfo.current.caretPosition || rCreateInfo.current.selectAll) {\n\t\t\t\ttextEditorInstance.commands.focus()\n\t\t\t} else {\n\t\t\t\ttextEditorInstance.commands.focus('end')\n\t\t\t}\n\n\t\t\trCreateInfo.current.selectAll = false\n\t\t\trCreateInfo.current.caretPosition = null\n\t\t}, 100)\n\n\t\trTextEditor.current = textEditorInstance\n\n\t\treturn () => {\n\t\t\trTextEditor.current = null\n\t\t\tclearTimeout(timeout)\n\t\t\ttextEditorInstance.destroy()\n\t\t}\n\t}, [\n\t\tisEditing,\n\t\ttipTapConfig,\n\t\tonFocus,\n\t\tonBlur,\n\t\tonDoubleClick,\n\t\tonChange,\n\t\tonPaste,\n\t\tonKeyDown,\n\t\teditor,\n\t\tshapeId,\n\t\thasCustomTabBehavior,\n\t])\n\n\tif (!isEditing || !tipTapConfig) {\n\t\treturn null\n\t}\n\n\treturn (\n\t\t<div\n\t\t\tid={tipTapId}\n\t\t\tref={ref}\n\t\t\ttabIndex={-1}\n\t\t\tdata-testid=\"rich-text-area\"\n\t\t\tclassName=\"tl-rich-text tl-text tl-text-input\"\n\t\t\tonContextMenu={isEditing ? stopEventPropagation : undefined}\n\t\t\t// N.B. When PointerStateExtension was introduced, this was moved there.\n\t\t\t// However, that caused selecting over list items to break.\n\t\t\t// The handleDOMEvents in TipTap don't seem to support the pointerDownCapture event.\n\t\t\tonPointerDownCapture={stopEventPropagation}\n\t\t\t// This onTouchEnd is important for Android to be able to change selection on text.\n\t\t\tonTouchEnd={stopEventPropagation}\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\t\t<div className=\"tl-rich-text\" ref={rTextEditorEl} />\n\t\t</div>\n\t)\n})\n\n// Prevent exiting the editor when hitting Tab.\n// Also, insert a tab character at the front of the line if the shift key isn't pressed,\n// otherwise if shift is pressed, remove a tab character from the front of the line.\nfunction handleTab(editor: Editor, view: EditorView, event: KeyboardEvent) {\n\t// Don't exit the editor.\n\tevent.preventDefault()\n\n\tconst textEditor = editor.getRichTextEditor()\n\tif (textEditor?.isActive('bulletList') || textEditor?.isActive('orderedList')) return\n\n\tconst { state, dispatch } = view\n\tconst { $from, $to } = state.selection\n\tconst isShift = event.shiftKey\n\n\t// Create a new transaction\n\tlet tr = state.tr\n\n\t// Iterate over each line in the selection in reverse so that the positions\n\t// are stable as we modify the document.\n\tlet pos = $to.end()\n\twhile (pos >= $from.start()) {\n\t\tconst line = state.doc.resolve(pos).blockRange()\n\t\tif (!line) break\n\n\t\tconst lineStart = line.start\n\t\tconst lineEnd = line.end\n\t\tconst lineText = state.doc.textBetween(lineStart, lineEnd, '\\n')\n\n\t\t// Check if the current line or any of its parent nodes are part of a list\n\t\tlet isInList = false\n\t\tstate.doc.nodesBetween(lineStart, lineEnd, (node) => {\n\t\t\tif (node.type.name === 'bulletList' || node.type.name === 'orderedList') {\n\t\t\t\tisInList = true\n\t\t\t\treturn false // Stop iteration\n\t\t\t}\n\t\t})\n\n\t\t// TODO: for now skip over lists. Later, we might consider handling them using\n\t\t// sinkListItem and liftListItem from @tiptap/pm/schema-list\n\t\tif (!isInList) {\n\t\t\tif (!isShift) {\n\t\t\t\t// Insert a tab character at the start of the line\n\t\t\t\ttr = tr.insertText('\\t', lineStart + 1)\n\t\t\t} else {\n\t\t\t\t// Remove a tab character from the start of the line\n\t\t\t\tif (lineText.startsWith('\\t')) {\n\t\t\t\t\ttr = tr.delete(lineStart + 1, lineStart + 2)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpos = lineStart - 1\n\t}\n\n\tconst mappedSelection = state.selection.map(tr.doc, tr.mapping)\n\ttr.setSelection(mappedSelection)\n\n\tif (tr.docChanged) {\n\t\tdispatch(tr)\n\t}\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAwPG;AAvPH,mBAKO;AACP,oBASO;AACP,IAAAA,gBAA+C;AA+BxC,MAAM,eAAe,cAAAC,QAAM,WAA0C,SAASC,cACpF;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,GACA,KACC;AACD,QAAM,aAAS,yBAAU;AACzB,QAAM,eAAW,+BAAgB,gBAAgB;AACjD,QAAM,eAAe,OAAO,eAAe,EAAE;AAE7C,QAAM,uBAAmB,sBAAO,QAAQ;AACxC,QAAM,kBAAc,sBAAwB,IAAI;AAChD,QAAM,oBAAgB,sBAAuB,IAAI;AAEjD,qCAAgB,MAAM;AACrB,QAAI,CAAC,YAAY,SAAS;AACzB,uBAAiB,UAAU;AAAA,IAC5B,WAAW,iBAAiB,YAAY,UAAU;AACjD,kBAAY,QAAQ,SAAS,WAAW,QAAuB;AAAA,IAChE;AAAA,EACD,GAAG,CAAC,QAAQ,CAAC;AAQb,QAAM,kBAAc,sBAAO;AAAA,IAC1B,WAAW;AAAA,IACX,eAAe;AAAA,EAChB,CAAC;AAED,qCAAgB,MAAM;AACrB,aAAS,mBAAmB,OAA+B;AAC1D,UAAI,MAAM,YAAY,OAAO,kBAAkB,GAAG;AACjD,oBAAY,QAAQ,YAAY;AAAA,MACjC;AAAA,IACD;AAEA,aAAS,WAAW,OAAgE;AACnF,UAAI,MAAM,YAAY,OAAO,kBAAkB,GAAG;AACjD,oBAAY,QAAQ,gBAAgB,MAAM;AAAA,MAC3C;AAAA,IACD;AAEA,WAAO,GAAG,mBAAmB,kBAAkB;AAC/C,WAAO,GAAG,eAAe,UAAU;AACnC,WAAO,MAAM;AACZ,aAAO,IAAI,mBAAmB,kBAAkB;AAChD,aAAO,IAAI,eAAe,UAAU;AAAA,IACrC;AAAA,EACD,GAAG,CAAC,QAAQ,SAAS,CAAC;AAEtB,QAAM,eAAW,wBAAS,YAAY;AACtC,QAAM,gBAAY,wBAAS,aAAa;AACxC,QAAM,cAAU,wBAAS,WAAW;AACpC,QAAM,aAAS,wBAAS,UAAU;AAClC,QAAM,oBAAgB,wBAAS,iBAAiB;AAChD,QAAM,cAAU,wBAAS,WAAW;AACpC,qCAAgB,MAAM;AACrB,QAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,cAAc,QAAS;AAE3D,UAAM,EAAE,aAAa,GAAG,mBAAmB,IAAI;AAM/C,UAAM,qBAAqB,IAAI,aAAAC,OAAW;AAAA,MACzC,SAAS,cAAc;AAAA,MACvB,WAAW;AAAA,MACX,UAAU;AAAA,MACV,UAAU,CAAC,UAAkC;AAC5C,cAAM,UAAsB,MAAM,OAAO,MAAM,IAAI,OAAO;AAC1D,yBAAiB,UAAU;AAC3B,iBAAS,EAAE,UAAU,QAAQ,CAAC;AAAA,MAC/B;AAAA,MACA;AAAA,MACA;AAAA;AAAA,MAEA,UAAU,CAAC,UAAU;AAEpB,YAAI,OAAO,kBAAkB,MAAM,QAAS;AAE5C,cAAM,aAAa,MAAM;AACzB,eAAO,kBAAkB,UAAU;AAEnC,cAAM,EAAE,WAAW,cAAc,IAAI,YAAY;AAEjD,YAAI,WAAW;AAEd,qBAAW,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI;AAAA,QAC5C,WAAW,eAAe;AAEzB,gBAAM,MAAM,WAAW,KAAK,YAAY;AAAA,YACvC,MAAM,cAAc;AAAA,YACpB,KAAK,cAAc;AAAA,UACpB,CAAC,GAAG;AAEJ,cAAI,KAAK;AAER,uBAAW,MAAM,EAAE,MAAM,EAAE,iBAAiB,GAAG,EAAE,IAAI;AAAA,UACtD,OAAO;AAEN,uBAAW,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI;AAAA,UAC5C;AAAA,QACD;AAAA,MACD;AAAA,MACA,aAAa;AAAA,QACZ,eAAe,CAAC,MAAkB,UAAyB;AAC1D,cAAI,CAAC,wBAAwB,MAAM,QAAQ,OAAO;AACjD,sBAAU,QAAQ,MAAM,KAAK;AAAA,UAC9B;AAEA,oBAAU,KAAK;AAAA,QAChB;AAAA,QACA,aAAa,CAAC,MAAkB,UAA0B;AACzD,kBAAQ,KAAK;AACb,cAAI,MAAM,iBAAkB,QAAO;AAAA,QACpC;AAAA,QACA,mBAAmB,CAAC,OAAO,MAAM,UAAU,cAAc,KAAK;AAAA,QAC9D,GAAG;AAAA,MACJ;AAAA,MACA,sBAAsB;AAAA,QACrB,yBAAyB;AAAA,UACxB,gBAAgB;AAAA,QACjB;AAAA,MACD;AAAA,MACA,GAAG;AAAA,MACH,SAAS,iBAAiB;AAAA,IAC3B,CAAC;AAID,UAAM,UAAU,OAAO,OAAO,WAAW,MAAM;AAC9C,UAAI,YAAY,QAAQ,iBAAiB,YAAY,QAAQ,WAAW;AACvE,2BAAmB,SAAS,MAAM;AAAA,MACnC,OAAO;AACN,2BAAmB,SAAS,MAAM,KAAK;AAAA,MACxC;AAEA,kBAAY,QAAQ,YAAY;AAChC,kBAAY,QAAQ,gBAAgB;AAAA,IACrC,GAAG,GAAG;AAEN,gBAAY,UAAU;AAEtB,WAAO,MAAM;AACZ,kBAAY,UAAU;AACtB,mBAAa,OAAO;AACpB,yBAAmB,QAAQ;AAAA,IAC5B;AAAA,EACD,GAAG;AAAA,IACF;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD,CAAC;AAED,MAAI,CAAC,aAAa,CAAC,cAAc;AAChC,WAAO;AAAA,EACR;AAEA,SACC;AAAA,IAAC;AAAA;AAAA,MACA,IAAI;AAAA,MACJ;AAAA,MACA,UAAU;AAAA,MACV,eAAY;AAAA,MACZ,WAAU;AAAA,MACV,eAAe,YAAY,qCAAuB;AAAA,MAIlD,sBAAsB;AAAA,MAEtB,YAAY;AAAA,MAKZ,aAAa;AAAA,MAEb,sDAAC,SAAI,WAAU,gBAAe,KAAK,eAAe;AAAA;AAAA,EACnD;AAEF,CAAC;AAKD,SAAS,UAAU,QAAgB,MAAkB,OAAsB;AAE1E,QAAM,eAAe;AAErB,QAAM,aAAa,OAAO,kBAAkB;AAC5C,MAAI,YAAY,SAAS,YAAY,KAAK,YAAY,SAAS,aAAa,EAAG;AAE/E,QAAM,EAAE,OAAO,SAAS,IAAI;AAC5B,QAAM,EAAE,OAAO,IAAI,IAAI,MAAM;AAC7B,QAAM,UAAU,MAAM;AAGtB,MAAI,KAAK,MAAM;AAIf,MAAI,MAAM,IAAI,IAAI;AAClB,SAAO,OAAO,MAAM,MAAM,GAAG;AAC5B,UAAM,OAAO,MAAM,IAAI,QAAQ,GAAG,EAAE,WAAW;AAC/C,QAAI,CAAC,KAAM;AAEX,UAAM,YAAY,KAAK;AACvB,UAAM,UAAU,KAAK;AACrB,UAAM,WAAW,MAAM,IAAI,YAAY,WAAW,SAAS,IAAI;AAG/D,QAAI,WAAW;AACf,UAAM,IAAI,aAAa,WAAW,SAAS,CAAC,SAAS;AACpD,UAAI,KAAK,KAAK,SAAS,gBAAgB,KAAK,KAAK,SAAS,eAAe;AACxE,mBAAW;AACX,eAAO;AAAA,MACR;AAAA,IACD,CAAC;AAID,QAAI,CAAC,UAAU;AACd,UAAI,CAAC,SAAS;AAEb,aAAK,GAAG,WAAW,KAAM,YAAY,CAAC;AAAA,MACvC,OAAO;AAEN,YAAI,SAAS,WAAW,GAAI,GAAG;AAC9B,eAAK,GAAG,OAAO,YAAY,GAAG,YAAY,CAAC;AAAA,QAC5C;AAAA,MACD;AAAA,IACD;AAEA,UAAM,YAAY;AAAA,EACnB;AAEA,QAAM,kBAAkB,MAAM,UAAU,IAAI,GAAG,KAAK,GAAG,OAAO;AAC9D,KAAG,aAAa,eAAe;AAE/B,MAAI,GAAG,YAAY;AAClB,aAAS,EAAE;AAAA,EACZ;AACD;",
4
+ "sourcesContent": ["import { EditorView } from '@tiptap/pm/view'\nimport {\n\tEditorEvents,\n\tJSONContent,\n\tEditor as TextEditor,\n\ttype Editor as TTEditor,\n} from '@tiptap/react'\nimport {\n\tEditor,\n\tTLRichText,\n\tTLShapeId,\n\tpreventDefault,\n\tuseEditor,\n\tuseEvent,\n\tuseUniqueSafeId,\n} from '@tldraw/editor'\nimport React, { useLayoutEffect, useRef } from 'react'\n\n/** @public */\nexport interface TextAreaProps {\n\tisEditing: boolean\n\ttext?: string\n\tshapeId: TLShapeId\n\trichText?: TLRichText\n\thandleFocus(): void\n\thandleBlur(): void\n\thandleKeyDown(e: KeyboardEvent): void\n\thandleChange(changeInfo: { plaintext?: string; richText?: TLRichText }): void\n\thandleInputPointerDown(e: React.PointerEvent<HTMLElement>): void\n\thandleDoubleClick(e: any): any\n\thandlePaste(e: ClipboardEvent | React.ClipboardEvent<HTMLTextAreaElement>): void\n\thasCustomTabBehavior?: boolean\n}\n\n/**\n * N.B. In Development mode you need to ensure you're testing this without StrictMode on.\n * Otherwise it's not gonna work as expected on iOS.\n * Specifically, it means that the virtual keyboard won't pop open sometimes\n * (iOS starts flipping out when you render multiple times when trying to focus something) .\n */\n\n/**\n * A rich text area that can be used for editing text with rich text formatting.\n * This component uses the TipTap editor under the hood.\n *\n * @public @react\n */\nexport const RichTextArea = React.forwardRef<HTMLDivElement, TextAreaProps>(function RichTextArea(\n\t{\n\t\tshapeId,\n\t\tisEditing,\n\t\trichText,\n\t\thandleFocus,\n\t\thandleChange,\n\t\thandleBlur,\n\t\thandleKeyDown,\n\t\thandleDoubleClick,\n\t\thasCustomTabBehavior,\n\t\thandlePaste,\n\t},\n\tref\n) {\n\tconst editor = useEditor()\n\tconst tipTapId = useUniqueSafeId('tip-tap-editor')\n\tconst tipTapConfig = editor.getTextOptions().tipTapConfig\n\n\tconst rInitialRichText = useRef(richText)\n\tconst rTextEditor = useRef<TTEditor | null>(null)\n\tconst rTextEditorEl = useRef<HTMLDivElement>(null)\n\n\tuseLayoutEffect(() => {\n\t\tif (!rTextEditor.current) {\n\t\t\trInitialRichText.current = richText\n\t\t} else if (rInitialRichText.current !== richText) {\n\t\t\trTextEditor.current.commands.setContent(richText as JSONContent)\n\t\t}\n\t}, [richText])\n\n\t// The order of events is:\n\t// - editor begins editing any shape\n\t// - we set listeners for select all / place caret events\n\t// - if the user is editing this shape, this component is rendered\n\t// - editor emits the select all event / place caret event\n\t// - the text editor is onCreate callback is called\n\tconst rCreateInfo = useRef({\n\t\tselectAll: false,\n\t\tcaretPosition: null as { x: number; y: number } | null,\n\t})\n\n\tuseLayoutEffect(() => {\n\t\tfunction selectAllIfEditing(event: { shapeId: TLShapeId }) {\n\t\t\tif (event.shapeId === editor.getEditingShapeId()) {\n\t\t\t\trCreateInfo.current.selectAll = true\n\t\t\t}\n\t\t}\n\n\t\tfunction placeCaret(event: { shapeId: TLShapeId; point: { x: number; y: number } }) {\n\t\t\tif (event.shapeId === editor.getEditingShapeId()) {\n\t\t\t\trCreateInfo.current.caretPosition = event.point\n\t\t\t}\n\t\t}\n\n\t\teditor.on('select-all-text', selectAllIfEditing)\n\t\teditor.on('place-caret', placeCaret)\n\t\treturn () => {\n\t\t\teditor.off('select-all-text', selectAllIfEditing)\n\t\t\teditor.off('place-caret', placeCaret)\n\t\t}\n\t}, [editor, isEditing])\n\n\tconst onChange = useEvent(handleChange)\n\tconst onKeyDown = useEvent(handleKeyDown)\n\tconst onFocus = useEvent(handleFocus)\n\tconst onBlur = useEvent(handleBlur)\n\tconst onDoubleClick = useEvent(handleDoubleClick)\n\tconst onPaste = useEvent(handlePaste)\n\tuseLayoutEffect(() => {\n\t\tif (!isEditing || !tipTapConfig || !rTextEditorEl.current) return\n\n\t\tconst { editorProps, ...restOfTipTapConfig } = tipTapConfig\n\n\t\t// Because React can double-render in Strict Mode, we need to make sure we're not setting\n\t\t// the text editor twice. This became more much more prevalent in React 19, but also it\n\t\t// started manifesting in some cases in Next 14.2 (which maybe patches React 18.3 in weird\n\t\t// ways). So we used to use EditorProvider but we into weird rendering issues.\n\t\tconst textEditorInstance = new TextEditor({\n\t\t\telement: rTextEditorEl.current,\n\t\t\tautofocus: true,\n\t\t\teditable: isEditing,\n\t\t\tonUpdate: (props: EditorEvents['update']) => {\n\t\t\t\tconst content: TLRichText = props.editor.state.doc.toJSON()\n\t\t\t\trInitialRichText.current = content\n\t\t\t\tonChange({ richText: content })\n\t\t\t},\n\t\t\tonFocus,\n\t\t\tonBlur,\n\t\t\t// onCreate is called after a `setTimeout(0)`\n\t\t\tonCreate: (props) => {\n\t\t\t\t// If we're not still editing the original shape, then don't do anything.\n\t\t\t\tif (editor.getEditingShapeId() !== shapeId) return\n\n\t\t\t\tconst textEditor = props.editor\n\t\t\t\teditor.setRichTextEditor(textEditor)\n\n\t\t\t\tconst { selectAll, caretPosition } = rCreateInfo.current\n\n\t\t\t\tif (selectAll) {\n\t\t\t\t\t// Select all of the text\n\t\t\t\t\ttextEditor.chain().focus().selectAll().run()\n\t\t\t\t} else if (caretPosition) {\n\t\t\t\t\t// Set the initial caret screen position\n\t\t\t\t\tconst pos = textEditor.view.posAtCoords({\n\t\t\t\t\t\tleft: caretPosition.x,\n\t\t\t\t\t\ttop: caretPosition.y,\n\t\t\t\t\t})?.pos\n\n\t\t\t\t\tif (pos) {\n\t\t\t\t\t\t// Focus to that position.\n\t\t\t\t\t\ttextEditor.chain().focus().setTextSelection(pos).run()\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// If no position, default to select all.\n\t\t\t\t\t\ttextEditor.chain().focus().selectAll().run()\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\teditorProps: {\n\t\t\t\thandleKeyDown: (view: EditorView, event: KeyboardEvent) => {\n\t\t\t\t\tif (!hasCustomTabBehavior && event.key === 'Tab') {\n\t\t\t\t\t\thandleTab(editor, view, event)\n\t\t\t\t\t}\n\n\t\t\t\t\tonKeyDown(event)\n\t\t\t\t},\n\t\t\t\thandlePaste: (view: EditorView, event: ClipboardEvent) => {\n\t\t\t\t\tonPaste(event)\n\t\t\t\t\tif (event.defaultPrevented) return true\n\t\t\t\t},\n\t\t\t\thandleDoubleClick: (_view, _pos, event) => onDoubleClick(event),\n\t\t\t\t...editorProps,\n\t\t\t},\n\t\t\tcoreExtensionOptions: {\n\t\t\t\tclipboardTextSerializer: {\n\t\t\t\t\tblockSeparator: '\\n',\n\t\t\t\t},\n\t\t\t},\n\t\t\t...restOfTipTapConfig,\n\t\t\tcontent: rInitialRichText.current as JSONContent,\n\t\t})\n\n\t\t// XXX: When creating a brand new shape and double-clicking into it quickly to edit it,\n\t\t// there's some kind of race condition happening where the editor doesn't focus properly.\n\t\tconst timeout = editor.timers.setTimeout(() => {\n\t\t\tif (rCreateInfo.current.caretPosition || rCreateInfo.current.selectAll) {\n\t\t\t\ttextEditorInstance.commands.focus()\n\t\t\t} else {\n\t\t\t\ttextEditorInstance.commands.focus('end')\n\t\t\t}\n\n\t\t\trCreateInfo.current.selectAll = false\n\t\t\trCreateInfo.current.caretPosition = null\n\t\t}, 100)\n\n\t\trTextEditor.current = textEditorInstance\n\n\t\treturn () => {\n\t\t\trTextEditor.current = null\n\t\t\tclearTimeout(timeout)\n\t\t\ttextEditorInstance.destroy()\n\t\t}\n\t}, [\n\t\tisEditing,\n\t\ttipTapConfig,\n\t\tonFocus,\n\t\tonBlur,\n\t\tonDoubleClick,\n\t\tonChange,\n\t\tonPaste,\n\t\tonKeyDown,\n\t\teditor,\n\t\tshapeId,\n\t\thasCustomTabBehavior,\n\t])\n\n\tif (!isEditing || !tipTapConfig) {\n\t\treturn null\n\t}\n\n\treturn (\n\t\t<div\n\t\t\tid={tipTapId}\n\t\t\tref={ref}\n\t\t\ttabIndex={-1}\n\t\t\tdata-testid=\"rich-text-area\"\n\t\t\tclassName=\"tl-rich-text tl-text tl-text-input\"\n\t\t\tonContextMenu={isEditing ? (e) => e.stopPropagation() : undefined}\n\t\t\t// N.B. When PointerStateExtension was introduced, this was moved there.\n\t\t\t// However, that caused selecting over list items to break.\n\t\t\t// The handleDOMEvents in TipTap don't seem to support the pointerDownCapture event.\n\t\t\tonPointerDownCapture={(e) => e.stopPropagation()}\n\t\t\t// This onTouchEnd is important for Android to be able to change selection on text.\n\t\t\tonTouchEnd={(e) => e.stopPropagation()}\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\t\t<div className=\"tl-rich-text\" ref={rTextEditorEl} />\n\t\t</div>\n\t)\n})\n\n// Prevent exiting the editor when hitting Tab.\n// Also, insert a tab character at the front of the line if the shift key isn't pressed,\n// otherwise if shift is pressed, remove a tab character from the front of the line.\nfunction handleTab(editor: Editor, view: EditorView, event: KeyboardEvent) {\n\t// Don't exit the editor.\n\tevent.preventDefault()\n\n\tconst textEditor = editor.getRichTextEditor()\n\tif (textEditor?.isActive('bulletList') || textEditor?.isActive('orderedList')) return\n\n\tconst { state, dispatch } = view\n\tconst { $from, $to } = state.selection\n\tconst isShift = event.shiftKey\n\n\t// Create a new transaction\n\tlet tr = state.tr\n\n\t// Iterate over each line in the selection in reverse so that the positions\n\t// are stable as we modify the document.\n\tlet pos = $to.end()\n\twhile (pos >= $from.start()) {\n\t\tconst line = state.doc.resolve(pos).blockRange()\n\t\tif (!line) break\n\n\t\tconst lineStart = line.start\n\t\tconst lineEnd = line.end\n\t\tconst lineText = state.doc.textBetween(lineStart, lineEnd, '\\n')\n\n\t\t// Check if the current line or any of its parent nodes are part of a list\n\t\tlet isInList = false\n\t\tstate.doc.nodesBetween(lineStart, lineEnd, (node) => {\n\t\t\tif (node.type.name === 'bulletList' || node.type.name === 'orderedList') {\n\t\t\t\tisInList = true\n\t\t\t\treturn false // Stop iteration\n\t\t\t}\n\t\t})\n\n\t\t// TODO: for now skip over lists. Later, we might consider handling them using\n\t\t// sinkListItem and liftListItem from @tiptap/pm/schema-list\n\t\tif (!isInList) {\n\t\t\tif (!isShift) {\n\t\t\t\t// Insert a tab character at the start of the line\n\t\t\t\ttr = tr.insertText('\\t', lineStart + 1)\n\t\t\t} else {\n\t\t\t\t// Remove a tab character from the start of the line\n\t\t\t\tif (lineText.startsWith('\\t')) {\n\t\t\t\t\ttr = tr.delete(lineStart + 1, lineStart + 2)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpos = lineStart - 1\n\t}\n\n\tconst mappedSelection = state.selection.map(tr.doc, tr.mapping)\n\ttr.setSelection(mappedSelection)\n\n\tif (tr.docChanged) {\n\t\tdispatch(tr)\n\t}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["import_react", "React", "RichTextArea", "TextEditor"]
7
7
  }
@@ -111,6 +111,8 @@ class DraggingHandle extends import_editor.StateNode {
111
111
  exactTimeout = -1;
112
112
  // Only relevant to arrows
113
113
  resetExactTimeout() {
114
+ const arrowUtil = this.editor.getShapeUtil("arrow");
115
+ const timeoutValue = arrowUtil.options.pointingPreciseTimeout;
114
116
  if (this.exactTimeout !== -1) {
115
117
  this.clearExactTimeout();
116
118
  }
@@ -121,7 +123,7 @@ class DraggingHandle extends import_editor.StateNode {
121
123
  this.update();
122
124
  }
123
125
  this.exactTimeout = -1;
124
- }, 750);
126
+ }, timeoutValue);
125
127
  }
126
128
  // Only relevant to arrows
127
129
  clearExactTimeout() {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/lib/tools/SelectTool/childStates/DraggingHandle.tsx"],
4
- "sourcesContent": ["import {\n\tMat,\n\tStateNode,\n\tTLArrowShape,\n\tTLHandle,\n\tTLLineShape,\n\tTLPointerEventInfo,\n\tTLShapeId,\n\tTLShapePartial,\n\tVec,\n\tkickoutOccludedShapes,\n\tsnapAngle,\n\tsortByIndex,\n\tstructuredClone,\n} from '@tldraw/editor'\nimport { clearArrowTargetState } from '../../../shapes/arrow/arrowTargetState'\nimport { getArrowBindings } from '../../../shapes/arrow/shared'\n\nexport type DraggingHandleInfo = TLPointerEventInfo & {\n\tshape: TLArrowShape | TLLineShape\n\ttarget: 'handle'\n\tonInteractionEnd?: string\n\tisCreating?: boolean\n\tcreatingMarkId?: string\n}\n\nexport class DraggingHandle extends StateNode {\n\tstatic override id = 'dragging_handle'\n\n\tshapeId!: TLShapeId\n\tinitialHandle!: TLHandle\n\tinitialAdjacentHandle!: TLHandle | null\n\tinitialPagePoint!: Vec\n\n\tmarkId!: string\n\tinitialPageTransform!: Mat\n\tinitialPageRotation!: number\n\n\tinfo!: DraggingHandleInfo\n\n\tisPrecise = false\n\tisPreciseId: TLShapeId | null = null\n\tpointingId: TLShapeId | null = null\n\n\toverride onEnter(info: DraggingHandleInfo) {\n\t\tconst { shape, isCreating, creatingMarkId, handle } = info\n\t\tthis.info = info\n\t\tthis.parent.setCurrentToolIdMask(info.onInteractionEnd)\n\t\tthis.shapeId = shape.id\n\t\tthis.markId = ''\n\n\t\tif (isCreating) {\n\t\t\tif (creatingMarkId) {\n\t\t\t\tthis.markId = creatingMarkId\n\t\t\t} else {\n\t\t\t\t// handle legacy implicit `creating:{shapeId}` marks\n\t\t\t\tconst markId = this.editor.getMarkIdMatching(\n\t\t\t\t\t`creating:${this.editor.getOnlySelectedShapeId()}`\n\t\t\t\t)\n\t\t\t\tif (markId) {\n\t\t\t\t\tthis.markId = markId\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthis.markId = this.editor.markHistoryStoppingPoint('dragging handle')\n\t\t}\n\n\t\tthis.initialHandle = structuredClone(handle)\n\n\t\tthis.initialPageTransform = this.editor.getShapePageTransform(shape)!\n\t\tthis.initialPageRotation = this.initialPageTransform.rotation()\n\t\tthis.initialPagePoint = this.editor.inputs.originPagePoint.clone()\n\n\t\tthis.editor.setCursor({ type: isCreating ? 'cross' : 'grabbing', rotation: 0 })\n\n\t\tconst handles = this.editor.getShapeHandles(shape)!.sort(sortByIndex)\n\t\tconst index = handles.findIndex((h) => h.id === info.handle.id)\n\n\t\t// Find the adjacent handle\n\t\tthis.initialAdjacentHandle = null\n\n\t\t// Start from the handle and work forward\n\t\tfor (let i = index + 1; i < handles.length; i++) {\n\t\t\tconst handle = handles[i]\n\t\t\tif (handle.type === 'vertex' && handle.id !== 'middle' && handle.id !== info.handle.id) {\n\t\t\t\tthis.initialAdjacentHandle = handle\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\t// If still no handle, start from the end and work backward\n\t\tif (!this.initialAdjacentHandle) {\n\t\t\tfor (let i = handles.length - 1; i >= 0; i--) {\n\t\t\t\tconst handle = handles[i]\n\t\t\t\tif (handle.type === 'vertex' && handle.id !== 'middle' && handle.id !== info.handle.id) {\n\t\t\t\t\tthis.initialAdjacentHandle = handle\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// <!-- Only relevant to arrows\n\t\tif (this.editor.isShapeOfType<TLArrowShape>(shape, 'arrow')) {\n\t\t\tconst initialBinding = getArrowBindings(this.editor, shape)[info.handle.id as 'start' | 'end']\n\n\t\t\tthis.isPrecise = false\n\n\t\t\tif (initialBinding) {\n\t\t\t\tthis.isPrecise = initialBinding.props.isPrecise\n\t\t\t\tif (this.isPrecise) {\n\t\t\t\t\tthis.isPreciseId = initialBinding.toId\n\t\t\t\t} else {\n\t\t\t\t\tthis.resetExactTimeout()\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// -->\n\n\t\t// Call onHandleDragStart callback\n\t\tconst handleDragInfo = {\n\t\t\thandle: this.initialHandle,\n\t\t\tisPrecise: this.isPrecise,\n\t\t\tisCreatingShape: !!this.info.isCreating,\n\t\t\tinitial: shape,\n\t\t}\n\t\tconst util = this.editor.getShapeUtil(shape)\n\t\tconst startChanges = util.onHandleDragStart?.(shape, handleDragInfo)\n\t\tif (startChanges) {\n\t\t\tthis.editor.updateShapes([{ ...startChanges, id: shape.id, type: shape.type }])\n\t\t}\n\n\t\tthis.update()\n\n\t\tthis.editor.select(this.shapeId)\n\t}\n\n\t// Only relevant to arrows\n\tprivate exactTimeout = -1 as any\n\n\t// Only relevant to arrows\n\tprivate resetExactTimeout() {\n\t\tif (this.exactTimeout !== -1) {\n\t\t\tthis.clearExactTimeout()\n\t\t}\n\n\t\tthis.exactTimeout = this.editor.timers.setTimeout(() => {\n\t\t\tif (this.getIsActive() && !this.isPrecise) {\n\t\t\t\tthis.isPrecise = true\n\t\t\t\tthis.isPreciseId = this.pointingId\n\t\t\t\tthis.update()\n\t\t\t}\n\t\t\tthis.exactTimeout = -1\n\t\t}, 750)\n\t}\n\n\t// Only relevant to arrows\n\tprivate clearExactTimeout() {\n\t\tif (this.exactTimeout !== -1) {\n\t\t\tclearTimeout(this.exactTimeout)\n\t\t\tthis.exactTimeout = -1\n\t\t}\n\t}\n\n\toverride onPointerMove() {\n\t\tthis.update()\n\t}\n\n\toverride onKeyDown() {\n\t\tthis.update()\n\t}\n\n\toverride onKeyUp() {\n\t\tthis.update()\n\t}\n\n\toverride onPointerUp() {\n\t\tthis.complete()\n\t}\n\n\toverride onComplete() {\n\t\tthis.update()\n\t\tthis.complete()\n\t}\n\n\toverride onCancel() {\n\t\tthis.cancel()\n\t}\n\n\toverride onExit() {\n\t\tthis.parent.setCurrentToolIdMask(undefined)\n\t\tclearArrowTargetState(this.editor)\n\t\tthis.editor.snaps.clearIndicators()\n\n\t\tthis.editor.setCursor({ type: 'default', rotation: 0 })\n\t}\n\n\tprivate complete() {\n\t\tthis.editor.snaps.clearIndicators()\n\t\tkickoutOccludedShapes(this.editor, [this.shapeId])\n\n\t\t// Call onHandleDragEnd callback before state transitions\n\t\tconst shape = this.editor.getShape(this.shapeId)\n\t\tif (shape) {\n\t\t\tconst util = this.editor.getShapeUtil(shape)\n\t\t\tconst handleDragInfo = {\n\t\t\t\thandle: this.initialHandle,\n\t\t\t\tisPrecise: this.isPrecise,\n\t\t\t\tisCreatingShape: !!this.info.isCreating,\n\t\t\t\tinitial: this.info.shape,\n\t\t\t}\n\t\t\tconst endChanges = util.onHandleDragEnd?.(shape, handleDragInfo)\n\t\t\tif (endChanges) {\n\t\t\t\tthis.editor.updateShapes([{ ...endChanges, id: shape.id, type: shape.type }])\n\t\t\t}\n\t\t}\n\n\t\tconst { onInteractionEnd } = this.info\n\t\tif (this.editor.getInstanceState().isToolLocked && onInteractionEnd) {\n\t\t\t// Return to the tool that was active before this one,\n\t\t\t// but only if tool lock is turned on!\n\t\t\tthis.editor.setCurrentTool(onInteractionEnd, { shapeId: this.shapeId })\n\t\t\treturn\n\t\t}\n\n\t\tthis.parent.transition('idle')\n\t}\n\n\tprivate cancel() {\n\t\t// Call onHandleDragCancel callback before bailing to mark\n\t\tconst shape = this.editor.getShape(this.shapeId)\n\t\tif (shape) {\n\t\t\tconst util = this.editor.getShapeUtil(shape)\n\t\t\tconst handleDragInfo = {\n\t\t\t\thandle: this.initialHandle,\n\t\t\t\tisPrecise: this.isPrecise,\n\t\t\t\tisCreatingShape: !!this.info.isCreating,\n\t\t\t\tinitial: this.info.shape,\n\t\t\t}\n\t\t\tutil.onHandleDragCancel?.(shape, handleDragInfo)\n\t\t}\n\n\t\tthis.editor.bailToMark(this.markId)\n\t\tthis.editor.snaps.clearIndicators()\n\n\t\tconst { onInteractionEnd } = this.info\n\t\tif (onInteractionEnd) {\n\t\t\t// Return to the tool that was active before this one,\n\t\t\t// whether tool lock is turned on or not!\n\t\t\tthis.editor.setCurrentTool(onInteractionEnd, { shapeId: this.shapeId })\n\t\t\treturn\n\t\t}\n\n\t\tthis.parent.transition('idle')\n\t}\n\n\tprivate update() {\n\t\tconst { editor, shapeId, initialPagePoint } = this\n\t\tconst { initialHandle, initialPageRotation, initialAdjacentHandle } = this\n\t\tconst isSnapMode = this.editor.user.getIsSnapMode()\n\t\tconst {\n\t\t\tsnaps,\n\t\t\tinputs: { currentPagePoint, shiftKey, ctrlKey, altKey, pointerVelocity },\n\t\t} = editor\n\n\t\tconst initial = this.info.shape\n\n\t\tconst shape = editor.getShape(shapeId)\n\t\tif (!shape) return\n\t\tconst util = editor.getShapeUtil(shape)\n\n\t\tconst initialBinding = editor.isShapeOfType<TLArrowShape>(shape, 'arrow')\n\t\t\t? getArrowBindings(editor, shape)[initialHandle.id as 'start' | 'end']\n\t\t\t: undefined\n\n\t\tlet point = currentPagePoint\n\t\t\t.clone()\n\t\t\t.sub(initialPagePoint)\n\t\t\t.rot(-initialPageRotation)\n\t\t\t.add(initialHandle)\n\n\t\tif (shiftKey && initialAdjacentHandle && initialHandle.id !== 'middle') {\n\t\t\tconst angle = Vec.Angle(initialAdjacentHandle, point)\n\t\t\tconst snappedAngle = snapAngle(angle, 24)\n\t\t\tconst angleDifference = snappedAngle - angle\n\t\t\tpoint = Vec.RotWith(point, initialAdjacentHandle, angleDifference)\n\t\t}\n\n\t\t// Clear any existing snaps\n\t\teditor.snaps.clearIndicators()\n\n\t\tlet nextHandle = { ...initialHandle, x: point.x, y: point.y }\n\n\t\tif (initialHandle.canSnap && (isSnapMode ? !ctrlKey : ctrlKey)) {\n\t\t\t// We're snapping\n\t\t\tconst pageTransform = editor.getShapePageTransform(shape.id)\n\t\t\tif (!pageTransform) throw Error('Expected a page transform')\n\n\t\t\tconst snap = snaps.handles.snapHandle({ currentShapeId: shapeId, handle: nextHandle })\n\n\t\t\tif (snap) {\n\t\t\t\tsnap.nudge.rot(-editor.getShapeParentTransform(shape)!.rotation())\n\t\t\t\tpoint.add(snap.nudge)\n\t\t\t\tnextHandle = { ...initialHandle, x: point.x, y: point.y }\n\t\t\t}\n\t\t}\n\n\t\tconst changes = util.onHandleDrag?.(shape, {\n\t\t\thandle: nextHandle,\n\t\t\tisPrecise: this.isPrecise || altKey,\n\t\t\tisCreatingShape: !!this.info.isCreating,\n\t\t\tinitial: initial,\n\t\t})\n\n\t\tconst next: TLShapePartial<any> = { id: shape.id, type: shape.type, ...changes }\n\n\t\t// Arrows\n\t\tif (\n\t\t\tinitialHandle.type === 'vertex' &&\n\t\t\tthis.editor.isShapeOfType<TLArrowShape>(shape, 'arrow')\n\t\t) {\n\t\t\tconst bindingAfter = getArrowBindings(editor, shape)[initialHandle.id as 'start' | 'end']\n\n\t\t\tif (bindingAfter) {\n\t\t\t\tif (initialBinding?.toId !== bindingAfter.toId) {\n\t\t\t\t\tthis.pointingId = bindingAfter.toId\n\t\t\t\t\tthis.isPrecise = pointerVelocity.len() < 0.5 || altKey\n\t\t\t\t\tthis.isPreciseId = this.isPrecise ? bindingAfter.toId : null\n\t\t\t\t\tthis.resetExactTimeout()\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (initialBinding) {\n\t\t\t\t\tthis.pointingId = null\n\t\t\t\t\tthis.isPrecise = false\n\t\t\t\t\tthis.isPreciseId = null\n\t\t\t\t\tthis.resetExactTimeout()\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (changes) {\n\t\t\teditor.updateShapes([next])\n\t\t}\n\t}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n\tMat,\n\tStateNode,\n\tTLArrowShape,\n\tTLHandle,\n\tTLLineShape,\n\tTLPointerEventInfo,\n\tTLShapeId,\n\tTLShapePartial,\n\tVec,\n\tkickoutOccludedShapes,\n\tsnapAngle,\n\tsortByIndex,\n\tstructuredClone,\n} from '@tldraw/editor'\nimport { ArrowShapeUtil } from '../../../shapes/arrow/ArrowShapeUtil'\nimport { clearArrowTargetState } from '../../../shapes/arrow/arrowTargetState'\nimport { getArrowBindings } from '../../../shapes/arrow/shared'\n\nexport type DraggingHandleInfo = TLPointerEventInfo & {\n\tshape: TLArrowShape | TLLineShape\n\ttarget: 'handle'\n\tonInteractionEnd?: string\n\tisCreating?: boolean\n\tcreatingMarkId?: string\n}\n\nexport class DraggingHandle extends StateNode {\n\tstatic override id = 'dragging_handle'\n\n\tshapeId!: TLShapeId\n\tinitialHandle!: TLHandle\n\tinitialAdjacentHandle!: TLHandle | null\n\tinitialPagePoint!: Vec\n\n\tmarkId!: string\n\tinitialPageTransform!: Mat\n\tinitialPageRotation!: number\n\n\tinfo!: DraggingHandleInfo\n\n\tisPrecise = false\n\tisPreciseId: TLShapeId | null = null\n\tpointingId: TLShapeId | null = null\n\n\toverride onEnter(info: DraggingHandleInfo) {\n\t\tconst { shape, isCreating, creatingMarkId, handle } = info\n\t\tthis.info = info\n\t\tthis.parent.setCurrentToolIdMask(info.onInteractionEnd)\n\t\tthis.shapeId = shape.id\n\t\tthis.markId = ''\n\n\t\tif (isCreating) {\n\t\t\tif (creatingMarkId) {\n\t\t\t\tthis.markId = creatingMarkId\n\t\t\t} else {\n\t\t\t\t// handle legacy implicit `creating:{shapeId}` marks\n\t\t\t\tconst markId = this.editor.getMarkIdMatching(\n\t\t\t\t\t`creating:${this.editor.getOnlySelectedShapeId()}`\n\t\t\t\t)\n\t\t\t\tif (markId) {\n\t\t\t\t\tthis.markId = markId\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthis.markId = this.editor.markHistoryStoppingPoint('dragging handle')\n\t\t}\n\n\t\tthis.initialHandle = structuredClone(handle)\n\n\t\tthis.initialPageTransform = this.editor.getShapePageTransform(shape)!\n\t\tthis.initialPageRotation = this.initialPageTransform.rotation()\n\t\tthis.initialPagePoint = this.editor.inputs.originPagePoint.clone()\n\n\t\tthis.editor.setCursor({ type: isCreating ? 'cross' : 'grabbing', rotation: 0 })\n\n\t\tconst handles = this.editor.getShapeHandles(shape)!.sort(sortByIndex)\n\t\tconst index = handles.findIndex((h) => h.id === info.handle.id)\n\n\t\t// Find the adjacent handle\n\t\tthis.initialAdjacentHandle = null\n\n\t\t// Start from the handle and work forward\n\t\tfor (let i = index + 1; i < handles.length; i++) {\n\t\t\tconst handle = handles[i]\n\t\t\tif (handle.type === 'vertex' && handle.id !== 'middle' && handle.id !== info.handle.id) {\n\t\t\t\tthis.initialAdjacentHandle = handle\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\t// If still no handle, start from the end and work backward\n\t\tif (!this.initialAdjacentHandle) {\n\t\t\tfor (let i = handles.length - 1; i >= 0; i--) {\n\t\t\t\tconst handle = handles[i]\n\t\t\t\tif (handle.type === 'vertex' && handle.id !== 'middle' && handle.id !== info.handle.id) {\n\t\t\t\t\tthis.initialAdjacentHandle = handle\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// <!-- Only relevant to arrows\n\t\tif (this.editor.isShapeOfType<TLArrowShape>(shape, 'arrow')) {\n\t\t\tconst initialBinding = getArrowBindings(this.editor, shape)[info.handle.id as 'start' | 'end']\n\n\t\t\tthis.isPrecise = false\n\n\t\t\tif (initialBinding) {\n\t\t\t\tthis.isPrecise = initialBinding.props.isPrecise\n\t\t\t\tif (this.isPrecise) {\n\t\t\t\t\tthis.isPreciseId = initialBinding.toId\n\t\t\t\t} else {\n\t\t\t\t\tthis.resetExactTimeout()\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// -->\n\n\t\t// Call onHandleDragStart callback\n\t\tconst handleDragInfo = {\n\t\t\thandle: this.initialHandle,\n\t\t\tisPrecise: this.isPrecise,\n\t\t\tisCreatingShape: !!this.info.isCreating,\n\t\t\tinitial: shape,\n\t\t}\n\t\tconst util = this.editor.getShapeUtil(shape)\n\t\tconst startChanges = util.onHandleDragStart?.(shape, handleDragInfo)\n\t\tif (startChanges) {\n\t\t\tthis.editor.updateShapes([{ ...startChanges, id: shape.id, type: shape.type }])\n\t\t}\n\n\t\tthis.update()\n\n\t\tthis.editor.select(this.shapeId)\n\t}\n\n\t// Only relevant to arrows\n\tprivate exactTimeout = -1\n\n\t// Only relevant to arrows\n\tprivate resetExactTimeout() {\n\t\tconst arrowUtil = this.editor.getShapeUtil<ArrowShapeUtil>('arrow')\n\t\tconst timeoutValue = arrowUtil.options.pointingPreciseTimeout\n\n\t\tif (this.exactTimeout !== -1) {\n\t\t\tthis.clearExactTimeout()\n\t\t}\n\n\t\tthis.exactTimeout = this.editor.timers.setTimeout(() => {\n\t\t\tif (this.getIsActive() && !this.isPrecise) {\n\t\t\t\tthis.isPrecise = true\n\t\t\t\tthis.isPreciseId = this.pointingId\n\t\t\t\tthis.update()\n\t\t\t}\n\t\t\tthis.exactTimeout = -1\n\t\t}, timeoutValue)\n\t}\n\n\t// Only relevant to arrows\n\tprivate clearExactTimeout() {\n\t\tif (this.exactTimeout !== -1) {\n\t\t\tclearTimeout(this.exactTimeout)\n\t\t\tthis.exactTimeout = -1\n\t\t}\n\t}\n\n\toverride onPointerMove() {\n\t\tthis.update()\n\t}\n\n\toverride onKeyDown() {\n\t\tthis.update()\n\t}\n\n\toverride onKeyUp() {\n\t\tthis.update()\n\t}\n\n\toverride onPointerUp() {\n\t\tthis.complete()\n\t}\n\n\toverride onComplete() {\n\t\tthis.update()\n\t\tthis.complete()\n\t}\n\n\toverride onCancel() {\n\t\tthis.cancel()\n\t}\n\n\toverride onExit() {\n\t\tthis.parent.setCurrentToolIdMask(undefined)\n\t\tclearArrowTargetState(this.editor)\n\t\tthis.editor.snaps.clearIndicators()\n\n\t\tthis.editor.setCursor({ type: 'default', rotation: 0 })\n\t}\n\n\tprivate complete() {\n\t\tthis.editor.snaps.clearIndicators()\n\t\tkickoutOccludedShapes(this.editor, [this.shapeId])\n\n\t\t// Call onHandleDragEnd callback before state transitions\n\t\tconst shape = this.editor.getShape(this.shapeId)\n\t\tif (shape) {\n\t\t\tconst util = this.editor.getShapeUtil(shape)\n\t\t\tconst handleDragInfo = {\n\t\t\t\thandle: this.initialHandle,\n\t\t\t\tisPrecise: this.isPrecise,\n\t\t\t\tisCreatingShape: !!this.info.isCreating,\n\t\t\t\tinitial: this.info.shape,\n\t\t\t}\n\t\t\tconst endChanges = util.onHandleDragEnd?.(shape, handleDragInfo)\n\t\t\tif (endChanges) {\n\t\t\t\tthis.editor.updateShapes([{ ...endChanges, id: shape.id, type: shape.type }])\n\t\t\t}\n\t\t}\n\n\t\tconst { onInteractionEnd } = this.info\n\t\tif (this.editor.getInstanceState().isToolLocked && onInteractionEnd) {\n\t\t\t// Return to the tool that was active before this one,\n\t\t\t// but only if tool lock is turned on!\n\t\t\tthis.editor.setCurrentTool(onInteractionEnd, { shapeId: this.shapeId })\n\t\t\treturn\n\t\t}\n\n\t\tthis.parent.transition('idle')\n\t}\n\n\tprivate cancel() {\n\t\t// Call onHandleDragCancel callback before bailing to mark\n\t\tconst shape = this.editor.getShape(this.shapeId)\n\t\tif (shape) {\n\t\t\tconst util = this.editor.getShapeUtil(shape)\n\t\t\tconst handleDragInfo = {\n\t\t\t\thandle: this.initialHandle,\n\t\t\t\tisPrecise: this.isPrecise,\n\t\t\t\tisCreatingShape: !!this.info.isCreating,\n\t\t\t\tinitial: this.info.shape,\n\t\t\t}\n\t\t\tutil.onHandleDragCancel?.(shape, handleDragInfo)\n\t\t}\n\n\t\tthis.editor.bailToMark(this.markId)\n\t\tthis.editor.snaps.clearIndicators()\n\n\t\tconst { onInteractionEnd } = this.info\n\t\tif (onInteractionEnd) {\n\t\t\t// Return to the tool that was active before this one,\n\t\t\t// whether tool lock is turned on or not!\n\t\t\tthis.editor.setCurrentTool(onInteractionEnd, { shapeId: this.shapeId })\n\t\t\treturn\n\t\t}\n\n\t\tthis.parent.transition('idle')\n\t}\n\n\tprivate update() {\n\t\tconst { editor, shapeId, initialPagePoint } = this\n\t\tconst { initialHandle, initialPageRotation, initialAdjacentHandle } = this\n\t\tconst isSnapMode = this.editor.user.getIsSnapMode()\n\t\tconst {\n\t\t\tsnaps,\n\t\t\tinputs: { currentPagePoint, shiftKey, ctrlKey, altKey, pointerVelocity },\n\t\t} = editor\n\n\t\tconst initial = this.info.shape\n\n\t\tconst shape = editor.getShape(shapeId)\n\t\tif (!shape) return\n\t\tconst util = editor.getShapeUtil(shape)\n\n\t\tconst initialBinding = editor.isShapeOfType<TLArrowShape>(shape, 'arrow')\n\t\t\t? getArrowBindings(editor, shape)[initialHandle.id as 'start' | 'end']\n\t\t\t: undefined\n\n\t\tlet point = currentPagePoint\n\t\t\t.clone()\n\t\t\t.sub(initialPagePoint)\n\t\t\t.rot(-initialPageRotation)\n\t\t\t.add(initialHandle)\n\n\t\tif (shiftKey && initialAdjacentHandle && initialHandle.id !== 'middle') {\n\t\t\tconst angle = Vec.Angle(initialAdjacentHandle, point)\n\t\t\tconst snappedAngle = snapAngle(angle, 24)\n\t\t\tconst angleDifference = snappedAngle - angle\n\t\t\tpoint = Vec.RotWith(point, initialAdjacentHandle, angleDifference)\n\t\t}\n\n\t\t// Clear any existing snaps\n\t\teditor.snaps.clearIndicators()\n\n\t\tlet nextHandle = { ...initialHandle, x: point.x, y: point.y }\n\n\t\tif (initialHandle.canSnap && (isSnapMode ? !ctrlKey : ctrlKey)) {\n\t\t\t// We're snapping\n\t\t\tconst pageTransform = editor.getShapePageTransform(shape.id)\n\t\t\tif (!pageTransform) throw Error('Expected a page transform')\n\n\t\t\tconst snap = snaps.handles.snapHandle({ currentShapeId: shapeId, handle: nextHandle })\n\n\t\t\tif (snap) {\n\t\t\t\tsnap.nudge.rot(-editor.getShapeParentTransform(shape)!.rotation())\n\t\t\t\tpoint.add(snap.nudge)\n\t\t\t\tnextHandle = { ...initialHandle, x: point.x, y: point.y }\n\t\t\t}\n\t\t}\n\n\t\tconst changes = util.onHandleDrag?.(shape, {\n\t\t\thandle: nextHandle,\n\t\t\tisPrecise: this.isPrecise || altKey,\n\t\t\tisCreatingShape: !!this.info.isCreating,\n\t\t\tinitial: initial,\n\t\t})\n\n\t\tconst next: TLShapePartial<any> = { id: shape.id, type: shape.type, ...changes }\n\n\t\t// Arrows\n\t\tif (\n\t\t\tinitialHandle.type === 'vertex' &&\n\t\t\tthis.editor.isShapeOfType<TLArrowShape>(shape, 'arrow')\n\t\t) {\n\t\t\tconst bindingAfter = getArrowBindings(editor, shape)[initialHandle.id as 'start' | 'end']\n\n\t\t\tif (bindingAfter) {\n\t\t\t\tif (initialBinding?.toId !== bindingAfter.toId) {\n\t\t\t\t\tthis.pointingId = bindingAfter.toId\n\t\t\t\t\tthis.isPrecise = pointerVelocity.len() < 0.5 || altKey\n\t\t\t\t\tthis.isPreciseId = this.isPrecise ? bindingAfter.toId : null\n\t\t\t\t\tthis.resetExactTimeout()\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (initialBinding) {\n\t\t\t\t\tthis.pointingId = null\n\t\t\t\t\tthis.isPrecise = false\n\t\t\t\t\tthis.isPreciseId = null\n\t\t\t\t\tthis.resetExactTimeout()\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (changes) {\n\t\t\teditor.updateShapes([next])\n\t\t}\n\t}\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAcO;AAEP,8BAAsC;AACtC,oBAAiC;AAU1B,MAAM,uBAAuB,wBAAU;AAAA,EAC7C,OAAgB,KAAK;AAAA,EAErB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EAEA,YAAY;AAAA,EACZ,cAAgC;AAAA,EAChC,aAA+B;AAAA,EAEtB,QAAQ,MAA0B;AAC1C,UAAM,EAAE,OAAO,YAAY,gBAAgB,OAAO,IAAI;AACtD,SAAK,OAAO;AACZ,SAAK,OAAO,qBAAqB,KAAK,gBAAgB;AACtD,SAAK,UAAU,MAAM;AACrB,SAAK,SAAS;AAEd,QAAI,YAAY;AACf,UAAI,gBAAgB;AACnB,aAAK,SAAS;AAAA,MACf,OAAO;AAEN,cAAM,SAAS,KAAK,OAAO;AAAA,UAC1B,YAAY,KAAK,OAAO,uBAAuB,CAAC;AAAA,QACjD;AACA,YAAI,QAAQ;AACX,eAAK,SAAS;AAAA,QACf;AAAA,MACD;AAAA,IACD,OAAO;AACN,WAAK,SAAS,KAAK,OAAO,yBAAyB,iBAAiB;AAAA,IACrE;AAEA,SAAK,oBAAgB,+BAAgB,MAAM;AAE3C,SAAK,uBAAuB,KAAK,OAAO,sBAAsB,KAAK;AACnE,SAAK,sBAAsB,KAAK,qBAAqB,SAAS;AAC9D,SAAK,mBAAmB,KAAK,OAAO,OAAO,gBAAgB,MAAM;AAEjE,SAAK,OAAO,UAAU,EAAE,MAAM,aAAa,UAAU,YAAY,UAAU,EAAE,CAAC;AAE9E,UAAM,UAAU,KAAK,OAAO,gBAAgB,KAAK,EAAG,KAAK,yBAAW;AACpE,UAAM,QAAQ,QAAQ,UAAU,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,EAAE;AAG9D,SAAK,wBAAwB;AAG7B,aAAS,IAAI,QAAQ,GAAG,IAAI,QAAQ,QAAQ,KAAK;AAChD,YAAMA,UAAS,QAAQ,CAAC;AACxB,UAAIA,QAAO,SAAS,YAAYA,QAAO,OAAO,YAAYA,QAAO,OAAO,KAAK,OAAO,IAAI;AACvF,aAAK,wBAAwBA;AAC7B;AAAA,MACD;AAAA,IACD;AAGA,QAAI,CAAC,KAAK,uBAAuB;AAChC,eAAS,IAAI,QAAQ,SAAS,GAAG,KAAK,GAAG,KAAK;AAC7C,cAAMA,UAAS,QAAQ,CAAC;AACxB,YAAIA,QAAO,SAAS,YAAYA,QAAO,OAAO,YAAYA,QAAO,OAAO,KAAK,OAAO,IAAI;AACvF,eAAK,wBAAwBA;AAC7B;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAGA,QAAI,KAAK,OAAO,cAA4B,OAAO,OAAO,GAAG;AAC5D,YAAM,qBAAiB,gCAAiB,KAAK,QAAQ,KAAK,EAAE,KAAK,OAAO,EAAqB;AAE7F,WAAK,YAAY;AAEjB,UAAI,gBAAgB;AACnB,aAAK,YAAY,eAAe,MAAM;AACtC,YAAI,KAAK,WAAW;AACnB,eAAK,cAAc,eAAe;AAAA,QACnC,OAAO;AACN,eAAK,kBAAkB;AAAA,QACxB;AAAA,MACD;AAAA,IACD;AAIA,UAAM,iBAAiB;AAAA,MACtB,QAAQ,KAAK;AAAA,MACb,WAAW,KAAK;AAAA,MAChB,iBAAiB,CAAC,CAAC,KAAK,KAAK;AAAA,MAC7B,SAAS;AAAA,IACV;AACA,UAAM,OAAO,KAAK,OAAO,aAAa,KAAK;AAC3C,UAAM,eAAe,KAAK,oBAAoB,OAAO,cAAc;AACnE,QAAI,cAAc;AACjB,WAAK,OAAO,aAAa,CAAC,EAAE,GAAG,cAAc,IAAI,MAAM,IAAI,MAAM,MAAM,KAAK,CAAC,CAAC;AAAA,IAC/E;AAEA,SAAK,OAAO;AAEZ,SAAK,OAAO,OAAO,KAAK,OAAO;AAAA,EAChC;AAAA;AAAA,EAGQ,eAAe;AAAA;AAAA,EAGf,oBAAoB;AAC3B,UAAM,YAAY,KAAK,OAAO,aAA6B,OAAO;AAClE,UAAM,eAAe,UAAU,QAAQ;AAEvC,QAAI,KAAK,iBAAiB,IAAI;AAC7B,WAAK,kBAAkB;AAAA,IACxB;AAEA,SAAK,eAAe,KAAK,OAAO,OAAO,WAAW,MAAM;AACvD,UAAI,KAAK,YAAY,KAAK,CAAC,KAAK,WAAW;AAC1C,aAAK,YAAY;AACjB,aAAK,cAAc,KAAK;AACxB,aAAK,OAAO;AAAA,MACb;AACA,WAAK,eAAe;AAAA,IACrB,GAAG,YAAY;AAAA,EAChB;AAAA;AAAA,EAGQ,oBAAoB;AAC3B,QAAI,KAAK,iBAAiB,IAAI;AAC7B,mBAAa,KAAK,YAAY;AAC9B,WAAK,eAAe;AAAA,IACrB;AAAA,EACD;AAAA,EAES,gBAAgB;AACxB,SAAK,OAAO;AAAA,EACb;AAAA,EAES,YAAY;AACpB,SAAK,OAAO;AAAA,EACb;AAAA,EAES,UAAU;AAClB,SAAK,OAAO;AAAA,EACb;AAAA,EAES,cAAc;AACtB,SAAK,SAAS;AAAA,EACf;AAAA,EAES,aAAa;AACrB,SAAK,OAAO;AACZ,SAAK,SAAS;AAAA,EACf;AAAA,EAES,WAAW;AACnB,SAAK,OAAO;AAAA,EACb;AAAA,EAES,SAAS;AACjB,SAAK,OAAO,qBAAqB,MAAS;AAC1C,uDAAsB,KAAK,MAAM;AACjC,SAAK,OAAO,MAAM,gBAAgB;AAElC,SAAK,OAAO,UAAU,EAAE,MAAM,WAAW,UAAU,EAAE,CAAC;AAAA,EACvD;AAAA,EAEQ,WAAW;AAClB,SAAK,OAAO,MAAM,gBAAgB;AAClC,6CAAsB,KAAK,QAAQ,CAAC,KAAK,OAAO,CAAC;AAGjD,UAAM,QAAQ,KAAK,OAAO,SAAS,KAAK,OAAO;AAC/C,QAAI,OAAO;AACV,YAAM,OAAO,KAAK,OAAO,aAAa,KAAK;AAC3C,YAAM,iBAAiB;AAAA,QACtB,QAAQ,KAAK;AAAA,QACb,WAAW,KAAK;AAAA,QAChB,iBAAiB,CAAC,CAAC,KAAK,KAAK;AAAA,QAC7B,SAAS,KAAK,KAAK;AAAA,MACpB;AACA,YAAM,aAAa,KAAK,kBAAkB,OAAO,cAAc;AAC/D,UAAI,YAAY;AACf,aAAK,OAAO,aAAa,CAAC,EAAE,GAAG,YAAY,IAAI,MAAM,IAAI,MAAM,MAAM,KAAK,CAAC,CAAC;AAAA,MAC7E;AAAA,IACD;AAEA,UAAM,EAAE,iBAAiB,IAAI,KAAK;AAClC,QAAI,KAAK,OAAO,iBAAiB,EAAE,gBAAgB,kBAAkB;AAGpE,WAAK,OAAO,eAAe,kBAAkB,EAAE,SAAS,KAAK,QAAQ,CAAC;AACtE;AAAA,IACD;AAEA,SAAK,OAAO,WAAW,MAAM;AAAA,EAC9B;AAAA,EAEQ,SAAS;AAEhB,UAAM,QAAQ,KAAK,OAAO,SAAS,KAAK,OAAO;AAC/C,QAAI,OAAO;AACV,YAAM,OAAO,KAAK,OAAO,aAAa,KAAK;AAC3C,YAAM,iBAAiB;AAAA,QACtB,QAAQ,KAAK;AAAA,QACb,WAAW,KAAK;AAAA,QAChB,iBAAiB,CAAC,CAAC,KAAK,KAAK;AAAA,QAC7B,SAAS,KAAK,KAAK;AAAA,MACpB;AACA,WAAK,qBAAqB,OAAO,cAAc;AAAA,IAChD;AAEA,SAAK,OAAO,WAAW,KAAK,MAAM;AAClC,SAAK,OAAO,MAAM,gBAAgB;AAElC,UAAM,EAAE,iBAAiB,IAAI,KAAK;AAClC,QAAI,kBAAkB;AAGrB,WAAK,OAAO,eAAe,kBAAkB,EAAE,SAAS,KAAK,QAAQ,CAAC;AACtE;AAAA,IACD;AAEA,SAAK,OAAO,WAAW,MAAM;AAAA,EAC9B;AAAA,EAEQ,SAAS;AAChB,UAAM,EAAE,QAAQ,SAAS,iBAAiB,IAAI;AAC9C,UAAM,EAAE,eAAe,qBAAqB,sBAAsB,IAAI;AACtE,UAAM,aAAa,KAAK,OAAO,KAAK,cAAc;AAClD,UAAM;AAAA,MACL;AAAA,MACA,QAAQ,EAAE,kBAAkB,UAAU,SAAS,QAAQ,gBAAgB;AAAA,IACxE,IAAI;AAEJ,UAAM,UAAU,KAAK,KAAK;AAE1B,UAAM,QAAQ,OAAO,SAAS,OAAO;AACrC,QAAI,CAAC,MAAO;AACZ,UAAM,OAAO,OAAO,aAAa,KAAK;AAEtC,UAAM,iBAAiB,OAAO,cAA4B,OAAO,OAAO,QACrE,gCAAiB,QAAQ,KAAK,EAAE,cAAc,EAAqB,IACnE;AAEH,QAAI,QAAQ,iBACV,MAAM,EACN,IAAI,gBAAgB,EACpB,IAAI,CAAC,mBAAmB,EACxB,IAAI,aAAa;AAEnB,QAAI,YAAY,yBAAyB,cAAc,OAAO,UAAU;AACvE,YAAM,QAAQ,kBAAI,MAAM,uBAAuB,KAAK;AACpD,YAAM,mBAAe,yBAAU,OAAO,EAAE;AACxC,YAAM,kBAAkB,eAAe;AACvC,cAAQ,kBAAI,QAAQ,OAAO,uBAAuB,eAAe;AAAA,IAClE;AAGA,WAAO,MAAM,gBAAgB;AAE7B,QAAI,aAAa,EAAE,GAAG,eAAe,GAAG,MAAM,GAAG,GAAG,MAAM,EAAE;AAE5D,QAAI,cAAc,YAAY,aAAa,CAAC,UAAU,UAAU;AAE/D,YAAM,gBAAgB,OAAO,sBAAsB,MAAM,EAAE;AAC3D,UAAI,CAAC,cAAe,OAAM,MAAM,2BAA2B;AAE3D,YAAM,OAAO,MAAM,QAAQ,WAAW,EAAE,gBAAgB,SAAS,QAAQ,WAAW,CAAC;AAErF,UAAI,MAAM;AACT,aAAK,MAAM,IAAI,CAAC,OAAO,wBAAwB,KAAK,EAAG,SAAS,CAAC;AACjE,cAAM,IAAI,KAAK,KAAK;AACpB,qBAAa,EAAE,GAAG,eAAe,GAAG,MAAM,GAAG,GAAG,MAAM,EAAE;AAAA,MACzD;AAAA,IACD;AAEA,UAAM,UAAU,KAAK,eAAe,OAAO;AAAA,MAC1C,QAAQ;AAAA,MACR,WAAW,KAAK,aAAa;AAAA,MAC7B,iBAAiB,CAAC,CAAC,KAAK,KAAK;AAAA,MAC7B;AAAA,IACD,CAAC;AAED,UAAM,OAA4B,EAAE,IAAI,MAAM,IAAI,MAAM,MAAM,MAAM,GAAG,QAAQ;AAG/E,QACC,cAAc,SAAS,YACvB,KAAK,OAAO,cAA4B,OAAO,OAAO,GACrD;AACD,YAAM,mBAAe,gCAAiB,QAAQ,KAAK,EAAE,cAAc,EAAqB;AAExF,UAAI,cAAc;AACjB,YAAI,gBAAgB,SAAS,aAAa,MAAM;AAC/C,eAAK,aAAa,aAAa;AAC/B,eAAK,YAAY,gBAAgB,IAAI,IAAI,OAAO;AAChD,eAAK,cAAc,KAAK,YAAY,aAAa,OAAO;AACxD,eAAK,kBAAkB;AAAA,QACxB;AAAA,MACD,OAAO;AACN,YAAI,gBAAgB;AACnB,eAAK,aAAa;AAClB,eAAK,YAAY;AACjB,eAAK,cAAc;AACnB,eAAK,kBAAkB;AAAA,QACxB;AAAA,MACD;AAAA,IACD;AAEA,QAAI,SAAS;AACZ,aAAO,aAAa,CAAC,IAAI,CAAC;AAAA,IAC3B;AAAA,EACD;AACD;",
6
6
  "names": ["handle"]
7
7
  }
@@ -36,7 +36,7 @@ function SkipToMainContent() {
36
36
  const button = (0, import_react.useRef)(null);
37
37
  const handleNavigateToFirstShape = (0, import_react.useCallback)(
38
38
  (e) => {
39
- (0, import_editor.stopEventPropagation)(e);
39
+ editor.markEventAsHandled(e);
40
40
  button.current?.blur();
41
41
  const shapes = editor.getCurrentPageShapesInReadingOrder();
42
42
  if (!shapes.length) return;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/ui/components/A11y.tsx"],
4
- "sourcesContent": ["import {\n\tdebugFlags,\n\tEditor,\n\tstopEventPropagation,\n\tTLGeoShape,\n\tTLShapeId,\n\tunsafe__withoutCapture,\n\tuseContainer,\n\tuseEditor,\n\tuseMaybeEditor,\n\tuseReactor,\n\tuseValue,\n} from '@tldraw/editor'\nimport { memo, MouseEvent, useCallback, useEffect, useRef } from 'react'\nimport { useA11y } from '../context/a11y'\nimport { useTranslation } from '../hooks/useTranslation/useTranslation'\nimport { TldrawUiButton } from './primitives/Button/TldrawUiButton'\n\nexport function SkipToMainContent() {\n\tconst editor = useEditor()\n\tconst msg = useTranslation()\n\tconst button = useRef<HTMLButtonElement>(null)\n\n\tconst handleNavigateToFirstShape = useCallback(\n\t\t(e: MouseEvent | KeyboardEvent) => {\n\t\t\tstopEventPropagation(e)\n\t\t\tbutton.current?.blur()\n\t\t\tconst shapes = editor.getCurrentPageShapesInReadingOrder()\n\t\t\tif (!shapes.length) return\n\t\t\teditor.setSelectedShapes([shapes[0].id])\n\t\t\teditor.zoomToSelectionIfOffscreen(256, {\n\t\t\t\tanimation: {\n\t\t\t\t\tduration: editor.options.animationMediumMs,\n\t\t\t\t},\n\t\t\t\tinset: 0,\n\t\t\t})\n\n\t\t\t// N.B. If we don't do this, then we go into editing mode for some reason...\n\t\t\t// Not sure of a better solution at the moment...\n\t\t\teditor.timers.setTimeout(() => editor.getContainer().focus(), 100)\n\t\t},\n\t\t[editor]\n\t)\n\n\treturn (\n\t\t<TldrawUiButton\n\t\t\tref={button}\n\t\t\ttype=\"low\"\n\t\t\ttabIndex={0}\n\t\t\tclassName=\"tl-skip-to-main-content\"\n\t\t\tonClick={handleNavigateToFirstShape}\n\t\t>\n\t\t\t{msg('a11y.skip-to-main-content')}\n\t\t</TldrawUiButton>\n\t)\n}\n\n/** @public @react */\nexport const DefaultA11yAnnouncer = memo(function TldrawUiA11yAnnouncer() {\n\tconst a11y = useA11y()\n\tconst translation = useTranslation()\n\tconst msg = useValue('a11y-msg', () => a11y.currentMsg.get(), [])\n\tuseA11yDebug(msg.msg)\n\n\tuseSelectedShapesAnnouncer()\n\n\treturn (\n\t\tmsg.msg && (\n\t\t\t<div\n\t\t\t\taria-label={translation('a11y.status')}\n\t\t\t\taria-live={msg.priority || 'assertive'}\n\t\t\t\trole=\"status\"\n\t\t\t\taria-hidden=\"false\"\n\t\t\t\tstyle={{\n\t\t\t\t\tposition: 'absolute',\n\t\t\t\t\ttop: '-10000px',\n\t\t\t\t\tleft: '-10000px',\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{msg.msg}\n\t\t\t</div>\n\t\t)\n\t)\n})\n\n/**\n * Core function to generate accessibility announcements for selected shapes\n * @public\n */\nexport function generateShapeAnnouncementMessage(args: {\n\teditor: Editor\n\tselectedShapeIds: TLShapeId[]\n\tmsg(id: string, values?: Record<string, any>): string\n}) {\n\tconst { editor, selectedShapeIds, msg } = args\n\tlet a11yLive = ''\n\tconst numShapes = selectedShapeIds.length\n\n\tif (numShapes > 1) {\n\t\ta11yLive = msg('a11y.multiple-shapes').replace('{num}', numShapes.toString())\n\t} else if (numShapes === 1) {\n\t\tconst shapeId = selectedShapeIds[0]\n\t\tconst shape = editor.getShape(shapeId)\n\t\tif (!shape) return ''\n\n\t\tconst shapeUtil = editor.getShapeUtil(shape.type)\n\n\t\tconst isMedia = ['image', 'video'].includes(shape.type)\n\t\t// Yeah, yeah this is a bit of a hack, we should get better translations.\n\t\tlet shapeType = ''\n\t\tif (shape.type === 'geo') {\n\t\t\tshapeType = msg(`geo-style.${(shape as TLGeoShape).props.geo}`)\n\t\t} else if (isMedia) {\n\t\t\tshapeType = msg(`a11y.shape-${shape.type}`)\n\t\t} else {\n\t\t\tshapeType = msg(`tool.${shape.type}`)\n\t\t}\n\n\t\t// Get shape index in reading order\n\t\tconst readingOrderShapes = editor.getCurrentPageShapesInReadingOrder()\n\t\tconst currentShapeIndex = (readingOrderShapes.findIndex((s) => s.id === shapeId) + 1).toString()\n\t\tconst totalShapes = readingOrderShapes.length.toString()\n\t\tconst shapeIndex = msg('a11y.shape-index')\n\t\t\t.replace('{num}', currentShapeIndex)\n\t\t\t.replace('{total}', totalShapes)\n\n\t\t// Get describing text (alt text or shape text)\n\t\tconst describingText = shapeUtil.getAriaDescriptor(shape) || shapeUtil.getText(shape) || ''\n\n\t\t// Build the full announcement\n\t\ta11yLive = (describingText ? `${describingText}, ` : '') + `${shapeType}. ${shapeIndex}`\n\t}\n\n\treturn a11yLive\n}\n\n/** @public */\nexport const useSelectedShapesAnnouncer = () => {\n\tconst editor = useMaybeEditor()\n\tconst a11y = useA11y()\n\tconst msg = useTranslation()\n\n\tconst rPrevSelectedShapeIds = useRef<string[]>([])\n\n\tuseReactor(\n\t\t'announce selection',\n\t\t() => {\n\t\t\tif (!editor) return\n\n\t\t\tconst isInSelecting = editor.isIn('select.idle')\n\t\t\tif (isInSelecting) {\n\t\t\t\tconst selectedShapeIds = editor.getSelectedShapeIds()\n\t\t\t\tif (selectedShapeIds !== rPrevSelectedShapeIds.current) {\n\t\t\t\t\trPrevSelectedShapeIds.current = selectedShapeIds\n\t\t\t\t\tunsafe__withoutCapture(() => {\n\t\t\t\t\t\tconst a11yLive = generateShapeAnnouncementMessage({\n\t\t\t\t\t\t\teditor,\n\t\t\t\t\t\t\tselectedShapeIds,\n\t\t\t\t\t\t\tmsg,\n\t\t\t\t\t\t})\n\n\t\t\t\t\t\tif (a11yLive) {\n\t\t\t\t\t\t\ta11y.announce({ msg: a11yLive })\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[editor, a11y, msg]\n\t)\n}\n\nconst useA11yDebug = (msg: string | undefined) => {\n\tconst container = useContainer()\n\n\tuseEffect(() => {\n\t\tif (debugFlags.a11y.get()) {\n\t\t\tconst log = (msg: string) => {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.debug(\n\t\t\t\t\t`%ca11y%c: ${msg}`,\n\t\t\t\t\t`color: white; background: #40C057; padding: 2px;border-radius: 3px;`,\n\t\t\t\t\t'font-weight: normal'\n\t\t\t\t)\n\t\t\t}\n\t\t\tconst handleKeyUp = (e: KeyboardEvent) => {\n\t\t\t\tconst el = document.activeElement\n\t\t\t\tif (\n\t\t\t\t\te.key === 'Tab' &&\n\t\t\t\t\tel &&\n\t\t\t\t\tel !== document.body &&\n\t\t\t\t\t!el.classList.contains('tl-container')\n\t\t\t\t) {\n\t\t\t\t\tconst label = el.getAttribute('aria-label') || el.getAttribute('title') || el.textContent\n\t\t\t\t\tif (label) {\n\t\t\t\t\t\tlog(label)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (msg) {\n\t\t\t\tlog(msg)\n\t\t\t}\n\n\t\t\tdocument.addEventListener('keyup', handleKeyUp)\n\t\t\treturn () => document.removeEventListener('keyup', handleKeyUp)\n\t\t}\n\t}, [container, msg])\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n\tdebugFlags,\n\tEditor,\n\tTLGeoShape,\n\tTLShapeId,\n\tunsafe__withoutCapture,\n\tuseContainer,\n\tuseEditor,\n\tuseMaybeEditor,\n\tuseReactor,\n\tuseValue,\n} from '@tldraw/editor'\nimport { memo, MouseEvent, useCallback, useEffect, useRef } from 'react'\nimport { useA11y } from '../context/a11y'\nimport { useTranslation } from '../hooks/useTranslation/useTranslation'\nimport { TldrawUiButton } from './primitives/Button/TldrawUiButton'\n\nexport function SkipToMainContent() {\n\tconst editor = useEditor()\n\tconst msg = useTranslation()\n\tconst button = useRef<HTMLButtonElement>(null)\n\n\tconst handleNavigateToFirstShape = useCallback(\n\t\t(e: MouseEvent | KeyboardEvent) => {\n\t\t\teditor.markEventAsHandled(e)\n\t\t\tbutton.current?.blur()\n\t\t\tconst shapes = editor.getCurrentPageShapesInReadingOrder()\n\t\t\tif (!shapes.length) return\n\t\t\teditor.setSelectedShapes([shapes[0].id])\n\t\t\teditor.zoomToSelectionIfOffscreen(256, {\n\t\t\t\tanimation: {\n\t\t\t\t\tduration: editor.options.animationMediumMs,\n\t\t\t\t},\n\t\t\t\tinset: 0,\n\t\t\t})\n\n\t\t\t// N.B. If we don't do this, then we go into editing mode for some reason...\n\t\t\t// Not sure of a better solution at the moment...\n\t\t\teditor.timers.setTimeout(() => editor.getContainer().focus(), 100)\n\t\t},\n\t\t[editor]\n\t)\n\n\treturn (\n\t\t<TldrawUiButton\n\t\t\tref={button}\n\t\t\ttype=\"low\"\n\t\t\ttabIndex={0}\n\t\t\tclassName=\"tl-skip-to-main-content\"\n\t\t\tonClick={handleNavigateToFirstShape}\n\t\t>\n\t\t\t{msg('a11y.skip-to-main-content')}\n\t\t</TldrawUiButton>\n\t)\n}\n\n/** @public @react */\nexport const DefaultA11yAnnouncer = memo(function TldrawUiA11yAnnouncer() {\n\tconst a11y = useA11y()\n\tconst translation = useTranslation()\n\tconst msg = useValue('a11y-msg', () => a11y.currentMsg.get(), [])\n\tuseA11yDebug(msg.msg)\n\n\tuseSelectedShapesAnnouncer()\n\n\treturn (\n\t\tmsg.msg && (\n\t\t\t<div\n\t\t\t\taria-label={translation('a11y.status')}\n\t\t\t\taria-live={msg.priority || 'assertive'}\n\t\t\t\trole=\"status\"\n\t\t\t\taria-hidden=\"false\"\n\t\t\t\tstyle={{\n\t\t\t\t\tposition: 'absolute',\n\t\t\t\t\ttop: '-10000px',\n\t\t\t\t\tleft: '-10000px',\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{msg.msg}\n\t\t\t</div>\n\t\t)\n\t)\n})\n\n/**\n * Core function to generate accessibility announcements for selected shapes\n * @public\n */\nexport function generateShapeAnnouncementMessage(args: {\n\teditor: Editor\n\tselectedShapeIds: TLShapeId[]\n\tmsg(id: string, values?: Record<string, any>): string\n}) {\n\tconst { editor, selectedShapeIds, msg } = args\n\tlet a11yLive = ''\n\tconst numShapes = selectedShapeIds.length\n\n\tif (numShapes > 1) {\n\t\ta11yLive = msg('a11y.multiple-shapes').replace('{num}', numShapes.toString())\n\t} else if (numShapes === 1) {\n\t\tconst shapeId = selectedShapeIds[0]\n\t\tconst shape = editor.getShape(shapeId)\n\t\tif (!shape) return ''\n\n\t\tconst shapeUtil = editor.getShapeUtil(shape.type)\n\n\t\tconst isMedia = ['image', 'video'].includes(shape.type)\n\t\t// Yeah, yeah this is a bit of a hack, we should get better translations.\n\t\tlet shapeType = ''\n\t\tif (shape.type === 'geo') {\n\t\t\tshapeType = msg(`geo-style.${(shape as TLGeoShape).props.geo}`)\n\t\t} else if (isMedia) {\n\t\t\tshapeType = msg(`a11y.shape-${shape.type}`)\n\t\t} else {\n\t\t\tshapeType = msg(`tool.${shape.type}`)\n\t\t}\n\n\t\t// Get shape index in reading order\n\t\tconst readingOrderShapes = editor.getCurrentPageShapesInReadingOrder()\n\t\tconst currentShapeIndex = (readingOrderShapes.findIndex((s) => s.id === shapeId) + 1).toString()\n\t\tconst totalShapes = readingOrderShapes.length.toString()\n\t\tconst shapeIndex = msg('a11y.shape-index')\n\t\t\t.replace('{num}', currentShapeIndex)\n\t\t\t.replace('{total}', totalShapes)\n\n\t\t// Get describing text (alt text or shape text)\n\t\tconst describingText = shapeUtil.getAriaDescriptor(shape) || shapeUtil.getText(shape) || ''\n\n\t\t// Build the full announcement\n\t\ta11yLive = (describingText ? `${describingText}, ` : '') + `${shapeType}. ${shapeIndex}`\n\t}\n\n\treturn a11yLive\n}\n\n/** @public */\nexport const useSelectedShapesAnnouncer = () => {\n\tconst editor = useMaybeEditor()\n\tconst a11y = useA11y()\n\tconst msg = useTranslation()\n\n\tconst rPrevSelectedShapeIds = useRef<string[]>([])\n\n\tuseReactor(\n\t\t'announce selection',\n\t\t() => {\n\t\t\tif (!editor) return\n\n\t\t\tconst isInSelecting = editor.isIn('select.idle')\n\t\t\tif (isInSelecting) {\n\t\t\t\tconst selectedShapeIds = editor.getSelectedShapeIds()\n\t\t\t\tif (selectedShapeIds !== rPrevSelectedShapeIds.current) {\n\t\t\t\t\trPrevSelectedShapeIds.current = selectedShapeIds\n\t\t\t\t\tunsafe__withoutCapture(() => {\n\t\t\t\t\t\tconst a11yLive = generateShapeAnnouncementMessage({\n\t\t\t\t\t\t\teditor,\n\t\t\t\t\t\t\tselectedShapeIds,\n\t\t\t\t\t\t\tmsg,\n\t\t\t\t\t\t})\n\n\t\t\t\t\t\tif (a11yLive) {\n\t\t\t\t\t\t\ta11y.announce({ msg: a11yLive })\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[editor, a11y, msg]\n\t)\n}\n\nconst useA11yDebug = (msg: string | undefined) => {\n\tconst container = useContainer()\n\n\tuseEffect(() => {\n\t\tif (debugFlags.a11y.get()) {\n\t\t\tconst log = (msg: string) => {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.debug(\n\t\t\t\t\t`%ca11y%c: ${msg}`,\n\t\t\t\t\t`color: white; background: #40C057; padding: 2px;border-radius: 3px;`,\n\t\t\t\t\t'font-weight: normal'\n\t\t\t\t)\n\t\t\t}\n\t\t\tconst handleKeyUp = (e: KeyboardEvent) => {\n\t\t\t\tconst el = document.activeElement\n\t\t\t\tif (\n\t\t\t\t\te.key === 'Tab' &&\n\t\t\t\t\tel &&\n\t\t\t\t\tel !== document.body &&\n\t\t\t\t\t!el.classList.contains('tl-container')\n\t\t\t\t) {\n\t\t\t\t\tconst label = el.getAttribute('aria-label') || el.getAttribute('title') || el.textContent\n\t\t\t\t\tif (label) {\n\t\t\t\t\t\tlog(label)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (msg) {\n\t\t\t\tlog(msg)\n\t\t\t}\n\n\t\t\tdocument.addEventListener('keyup', handleKeyUp)\n\t\t\treturn () => document.removeEventListener('keyup', handleKeyUp)\n\t\t}\n\t}, [container, msg])\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["msg"]
7
7
  }
@@ -36,6 +36,7 @@ function LanguageMenu() {
36
36
  import_TldrawUiMenuCheckboxItem.TldrawUiMenuCheckboxItem,
37
37
  {
38
38
  id: `language-${locale}`,
39
+ lang: locale,
39
40
  title: locale,
40
41
  label,
41
42
  checked: locale === currentLanguage,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/ui/components/LanguageMenu.tsx"],
4
- "sourcesContent": ["import { LANGUAGES, useMaybeEditor, useValue } from '@tldraw/editor'\nimport { useUiEvents } from '../context/events'\nimport { TldrawUiMenuCheckboxItem } from './primitives/menus/TldrawUiMenuCheckboxItem'\nimport { TldrawUiMenuGroup } from './primitives/menus/TldrawUiMenuGroup'\nimport { TldrawUiMenuSubmenu } from './primitives/menus/TldrawUiMenuSubmenu'\n\n/** @public @react */\nexport function LanguageMenu() {\n\tconst editor = useMaybeEditor()\n\tconst trackEvent = useUiEvents()\n\tconst currentLanguage = useValue('locale', () => editor?.user.getLocale(), [editor])\n\n\tif (!editor) return null\n\n\treturn (\n\t\t<TldrawUiMenuSubmenu id=\"help menu language\" label=\"menu.language\">\n\t\t\t<TldrawUiMenuGroup id=\"languages\" className=\"tlui-language-menu\">\n\t\t\t\t{LANGUAGES.map(({ locale, label }) => (\n\t\t\t\t\t<TldrawUiMenuCheckboxItem\n\t\t\t\t\t\tid={`language-${locale}`}\n\t\t\t\t\t\tkey={locale}\n\t\t\t\t\t\ttitle={locale}\n\t\t\t\t\t\tlabel={label}\n\t\t\t\t\t\tchecked={locale === currentLanguage}\n\t\t\t\t\t\treadonlyOk\n\t\t\t\t\t\tonSelect={() => {\n\t\t\t\t\t\t\teditor.user.updateUserPreferences({ locale })\n\t\t\t\t\t\t\ttrackEvent('change-language', { source: 'menu', locale })\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t))}\n\t\t\t</TldrawUiMenuGroup>\n\t\t</TldrawUiMenuSubmenu>\n\t)\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBK;AAlBL,oBAAoD;AACpD,oBAA4B;AAC5B,sCAAyC;AACzC,+BAAkC;AAClC,iCAAoC;AAG7B,SAAS,eAAe;AAC9B,QAAM,aAAS,8BAAe;AAC9B,QAAM,iBAAa,2BAAY;AAC/B,QAAM,sBAAkB,wBAAS,UAAU,MAAM,QAAQ,KAAK,UAAU,GAAG,CAAC,MAAM,CAAC;AAEnF,MAAI,CAAC,OAAQ,QAAO;AAEpB,SACC,4CAAC,kDAAoB,IAAG,sBAAqB,OAAM,iBAClD,sDAAC,8CAAkB,IAAG,aAAY,WAAU,sBAC1C,kCAAU,IAAI,CAAC,EAAE,QAAQ,MAAM,MAC/B;AAAA,IAAC;AAAA;AAAA,MACA,IAAI,YAAY,MAAM;AAAA,MAEtB,OAAO;AAAA,MACP;AAAA,MACA,SAAS,WAAW;AAAA,MACpB,YAAU;AAAA,MACV,UAAU,MAAM;AACf,eAAO,KAAK,sBAAsB,EAAE,OAAO,CAAC;AAC5C,mBAAW,mBAAmB,EAAE,QAAQ,QAAQ,OAAO,CAAC;AAAA,MACzD;AAAA;AAAA,IARK;AAAA,EASN,CACA,GACF,GACD;AAEF;",
4
+ "sourcesContent": ["import { LANGUAGES, useMaybeEditor, useValue } from '@tldraw/editor'\nimport { useUiEvents } from '../context/events'\nimport { TldrawUiMenuCheckboxItem } from './primitives/menus/TldrawUiMenuCheckboxItem'\nimport { TldrawUiMenuGroup } from './primitives/menus/TldrawUiMenuGroup'\nimport { TldrawUiMenuSubmenu } from './primitives/menus/TldrawUiMenuSubmenu'\n\n/** @public @react */\nexport function LanguageMenu() {\n\tconst editor = useMaybeEditor()\n\tconst trackEvent = useUiEvents()\n\tconst currentLanguage = useValue('locale', () => editor?.user.getLocale(), [editor])\n\n\tif (!editor) return null\n\n\treturn (\n\t\t<TldrawUiMenuSubmenu id=\"help menu language\" label=\"menu.language\">\n\t\t\t<TldrawUiMenuGroup id=\"languages\" className=\"tlui-language-menu\">\n\t\t\t\t{LANGUAGES.map(({ locale, label }) => (\n\t\t\t\t\t<TldrawUiMenuCheckboxItem\n\t\t\t\t\t\tid={`language-${locale}`}\n\t\t\t\t\t\tlang={locale}\n\t\t\t\t\t\tkey={locale}\n\t\t\t\t\t\ttitle={locale}\n\t\t\t\t\t\tlabel={label}\n\t\t\t\t\t\tchecked={locale === currentLanguage}\n\t\t\t\t\t\treadonlyOk\n\t\t\t\t\t\tonSelect={() => {\n\t\t\t\t\t\t\teditor.user.updateUserPreferences({ locale })\n\t\t\t\t\t\t\ttrackEvent('change-language', { source: 'menu', locale })\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t))}\n\t\t\t</TldrawUiMenuGroup>\n\t\t</TldrawUiMenuSubmenu>\n\t)\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBK;AAlBL,oBAAoD;AACpD,oBAA4B;AAC5B,sCAAyC;AACzC,+BAAkC;AAClC,iCAAoC;AAG7B,SAAS,eAAe;AAC9B,QAAM,aAAS,8BAAe;AAC9B,QAAM,iBAAa,2BAAY;AAC/B,QAAM,sBAAkB,wBAAS,UAAU,MAAM,QAAQ,KAAK,UAAU,GAAG,CAAC,MAAM,CAAC;AAEnF,MAAI,CAAC,OAAQ,QAAO;AAEpB,SACC,4CAAC,kDAAoB,IAAG,sBAAqB,OAAM,iBAClD,sDAAC,8CAAkB,IAAG,aAAY,WAAU,sBAC1C,kCAAU,IAAI,CAAC,EAAE,QAAQ,MAAM,MAC/B;AAAA,IAAC;AAAA;AAAA,MACA,IAAI,YAAY,MAAM;AAAA,MACtB,MAAM;AAAA,MAEN,OAAO;AAAA,MACP;AAAA,MACA,SAAS,WAAW;AAAA,MACpB,YAAU;AAAA,MACV,UAAU,MAAM;AACf,eAAO,KAAK,sBAAsB,EAAE,OAAO,CAAC;AAC5C,mBAAW,mBAAmB,EAAE,QAAQ,QAAQ,OAAO,CAAC;AAAA,MACzD;AAAA;AAAA,IARK;AAAA,EASN,CACA,GACF,GACD;AAEF;",
6
6
  "names": []
7
7
  }
@@ -154,7 +154,7 @@ function DefaultMinimap() {
154
154
  type: "pointer",
155
155
  target: "canvas",
156
156
  name: "pointer_move",
157
- ...(0, import_editor.getPointerInfo)(e),
157
+ ...(0, import_editor.getPointerInfo)(editor, e),
158
158
  point: screenPoint,
159
159
  isPen: editor.getInstanceState().isPenMode
160
160
  };
@@ -191,6 +191,7 @@ function DefaultMinimap() {
191
191
  {
192
192
  role: "img",
193
193
  "aria-label": msg("navigation-zone.minimap"),
194
+ "data-testid": "minimap.canvas",
194
195
  ref: rCanvas,
195
196
  className: "tlui-minimap__canvas",
196
197
  onDoubleClick,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/lib/ui/components/Minimap/DefaultMinimap.tsx"],
4
- "sourcesContent": ["import {\n\tBox,\n\tTLPointerEventInfo,\n\tVec,\n\tgetPointerInfo,\n\tisAccelKey,\n\tnormalizeWheel,\n\treleasePointerCapture,\n\tsetPointerCapture,\n\tuseContainer,\n\tuseEditor,\n\tuseIsDarkMode,\n} from '@tldraw/editor'\nimport * as React from 'react'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { MinimapManager } from './MinimapManager'\n\n/** @public @react */\nexport function DefaultMinimap() {\n\tconst editor = useEditor()\n\tconst container = useContainer()\n\tconst msg = useTranslation()\n\n\tconst rCanvas = React.useRef<HTMLCanvasElement>(null!)\n\tconst rPointing = React.useRef(false)\n\n\tconst minimapRef = React.useRef<MinimapManager>()\n\n\tReact.useEffect(() => {\n\t\ttry {\n\t\t\tconst minimap = new MinimapManager(editor, rCanvas.current, container)\n\t\t\tminimapRef.current = minimap\n\t\t\treturn minimapRef.current.close\n\t\t} catch (e) {\n\t\t\teditor.annotateError(e, {\n\t\t\t\torigin: 'minimap',\n\t\t\t\twillCrashApp: false,\n\t\t\t})\n\t\t\teditor.timers.setTimeout(() => {\n\t\t\t\tthrow e\n\t\t\t})\n\t\t}\n\t}, [editor, container])\n\n\tconst onDoubleClick = React.useCallback(\n\t\t(e: React.MouseEvent<HTMLCanvasElement>) => {\n\t\t\tif (!editor.getCurrentPageShapeIds().size) return\n\t\t\tif (!minimapRef.current) return\n\n\t\t\tconst point = minimapRef.current.minimapScreenPointToPagePoint(\n\t\t\t\te.clientX,\n\t\t\t\te.clientY,\n\t\t\t\tfalse,\n\t\t\t\tfalse\n\t\t\t)\n\n\t\t\tconst clampedPoint = minimapRef.current.minimapScreenPointToPagePoint(\n\t\t\t\te.clientX,\n\t\t\t\te.clientY,\n\t\t\t\tfalse,\n\t\t\t\ttrue\n\t\t\t)\n\n\t\t\tminimapRef.current.originPagePoint.setTo(clampedPoint)\n\t\t\tminimapRef.current.originPageCenter.setTo(editor.getViewportPageBounds().center)\n\n\t\t\teditor.centerOnPoint(point, { animation: { duration: editor.options.animationMediumMs } })\n\t\t},\n\t\t[editor]\n\t)\n\n\tconst onPointerDown = React.useCallback(\n\t\t(e: React.PointerEvent<HTMLCanvasElement>) => {\n\t\t\tif (!minimapRef.current) return\n\t\t\tconst elm = e.currentTarget\n\t\t\tsetPointerCapture(elm, e)\n\t\t\tif (!editor.getCurrentPageShapeIds().size) return\n\n\t\t\trPointing.current = true\n\n\t\t\tminimapRef.current.isInViewport = false\n\n\t\t\tconst point = minimapRef.current.minimapScreenPointToPagePoint(\n\t\t\t\te.clientX,\n\t\t\t\te.clientY,\n\t\t\t\tfalse,\n\t\t\t\tfalse\n\t\t\t)\n\n\t\t\tconst _vpPageBounds = editor.getViewportPageBounds()\n\t\t\tconst commonBounds = minimapRef.current.getContentPageBounds()\n\t\t\tconst allowedBounds = new Box(\n\t\t\t\tcommonBounds.x - _vpPageBounds.width / 2,\n\t\t\t\tcommonBounds.y - _vpPageBounds.height / 2,\n\t\t\t\tcommonBounds.width + _vpPageBounds.width,\n\t\t\t\tcommonBounds.height + _vpPageBounds.height\n\t\t\t)\n\n\t\t\t// If we clicked inside of the allowed area, but outside of the viewport\n\t\t\tif (allowedBounds.containsPoint(point) && !_vpPageBounds.containsPoint(point)) {\n\t\t\t\tminimapRef.current.isInViewport = _vpPageBounds.containsPoint(point)\n\t\t\t\tconst delta = Vec.Sub(_vpPageBounds.center, _vpPageBounds.point)\n\t\t\t\tconst pagePoint = Vec.Add(point, delta)\n\t\t\t\tminimapRef.current.originPagePoint.setTo(pagePoint)\n\t\t\t\tminimapRef.current.originPageCenter.setTo(point)\n\t\t\t\teditor.centerOnPoint(point, { animation: { duration: editor.options.animationMediumMs } })\n\t\t\t} else {\n\t\t\t\tconst clampedPoint = minimapRef.current.minimapScreenPointToPagePoint(\n\t\t\t\t\te.clientX,\n\t\t\t\t\te.clientY,\n\t\t\t\t\tfalse,\n\t\t\t\t\ttrue\n\t\t\t\t)\n\t\t\t\tminimapRef.current.isInViewport = _vpPageBounds.containsPoint(clampedPoint)\n\t\t\t\tminimapRef.current.originPagePoint.setTo(clampedPoint)\n\t\t\t\tminimapRef.current.originPageCenter.setTo(_vpPageBounds.center)\n\t\t\t}\n\n\t\t\tfunction release(e: PointerEvent) {\n\t\t\t\tif (elm) {\n\t\t\t\t\treleasePointerCapture(elm, e)\n\t\t\t\t}\n\t\t\t\trPointing.current = false\n\t\t\t\tdocument.body.removeEventListener('pointerup', release)\n\t\t\t}\n\n\t\t\tdocument.body.addEventListener('pointerup', release)\n\t\t},\n\t\t[editor]\n\t)\n\n\tconst onPointerMove = React.useCallback(\n\t\t(e: React.PointerEvent<HTMLCanvasElement>) => {\n\t\t\tif (!minimapRef.current) return\n\t\t\tconst point = minimapRef.current.minimapScreenPointToPagePoint(\n\t\t\t\te.clientX,\n\t\t\t\te.clientY,\n\t\t\t\te.shiftKey,\n\t\t\t\ttrue\n\t\t\t)\n\n\t\t\tif (rPointing.current) {\n\t\t\t\tif (minimapRef.current.isInViewport) {\n\t\t\t\t\tconst delta = minimapRef.current.originPagePoint\n\t\t\t\t\t\t.clone()\n\t\t\t\t\t\t.sub(minimapRef.current.originPageCenter)\n\t\t\t\t\teditor.centerOnPoint(Vec.Sub(point, delta))\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\teditor.centerOnPoint(point)\n\t\t\t}\n\n\t\t\tconst pagePoint = minimapRef.current.getMinimapPagePoint(e.clientX, e.clientY)\n\n\t\t\tconst screenPoint = editor.pageToScreen(pagePoint)\n\n\t\t\tconst info: TLPointerEventInfo = {\n\t\t\t\ttype: 'pointer',\n\t\t\t\ttarget: 'canvas',\n\t\t\t\tname: 'pointer_move',\n\t\t\t\t...getPointerInfo(e),\n\t\t\t\tpoint: screenPoint,\n\t\t\t\tisPen: editor.getInstanceState().isPenMode,\n\t\t\t}\n\n\t\t\teditor.dispatch(info)\n\t\t},\n\t\t[editor]\n\t)\n\n\tconst onWheel = React.useCallback(\n\t\t(e: React.WheelEvent<HTMLCanvasElement>) => {\n\t\t\tconst offset = normalizeWheel(e)\n\n\t\t\teditor.dispatch({\n\t\t\t\ttype: 'wheel',\n\t\t\t\tname: 'wheel',\n\t\t\t\tdelta: offset,\n\t\t\t\tpoint: new Vec(e.clientX, e.clientY),\n\t\t\t\tshiftKey: e.shiftKey,\n\t\t\t\taltKey: e.altKey,\n\t\t\t\tctrlKey: e.metaKey || e.ctrlKey,\n\t\t\t\tmetaKey: e.metaKey,\n\t\t\t\taccelKey: isAccelKey(e),\n\t\t\t})\n\t\t},\n\t\t[editor]\n\t)\n\n\tconst isDarkMode = useIsDarkMode()\n\n\tReact.useEffect(() => {\n\t\t// need to wait a tick for next theme css to be applied\n\t\t// otherwise the minimap will render with the wrong colors\n\t\teditor.timers.setTimeout(() => {\n\t\t\tminimapRef.current?.updateColors()\n\t\t\tminimapRef.current?.render()\n\t\t})\n\t}, [isDarkMode, editor])\n\n\treturn (\n\t\t<div className=\"tlui-minimap\">\n\t\t\t<canvas\n\t\t\t\trole=\"img\"\n\t\t\t\taria-label={msg('navigation-zone.minimap')}\n\t\t\t\tref={rCanvas}\n\t\t\t\tclassName=\"tlui-minimap__canvas\"\n\t\t\t\tonDoubleClick={onDoubleClick}\n\t\t\t\tonPointerMove={onPointerMove}\n\t\t\t\tonPointerDown={onPointerDown}\n\t\t\t\tonWheelCapture={onWheel}\n\t\t\t/>\n\t\t</div>\n\t)\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA2MG;AA3MH,oBAYO;AACP,YAAuB;AACvB,4BAA+B;AAC/B,4BAA+B;AAGxB,SAAS,iBAAiB;AAChC,QAAM,aAAS,yBAAU;AACzB,QAAM,gBAAY,4BAAa;AAC/B,QAAM,UAAM,sCAAe;AAE3B,QAAM,UAAU,MAAM,OAA0B,IAAK;AACrD,QAAM,YAAY,MAAM,OAAO,KAAK;AAEpC,QAAM,aAAa,MAAM,OAAuB;AAEhD,QAAM,UAAU,MAAM;AACrB,QAAI;AACH,YAAM,UAAU,IAAI,qCAAe,QAAQ,QAAQ,SAAS,SAAS;AACrE,iBAAW,UAAU;AACrB,aAAO,WAAW,QAAQ;AAAA,IAC3B,SAAS,GAAG;AACX,aAAO,cAAc,GAAG;AAAA,QACvB,QAAQ;AAAA,QACR,cAAc;AAAA,MACf,CAAC;AACD,aAAO,OAAO,WAAW,MAAM;AAC9B,cAAM;AAAA,MACP,CAAC;AAAA,IACF;AAAA,EACD,GAAG,CAAC,QAAQ,SAAS,CAAC;AAEtB,QAAM,gBAAgB,MAAM;AAAA,IAC3B,CAAC,MAA2C;AAC3C,UAAI,CAAC,OAAO,uBAAuB,EAAE,KAAM;AAC3C,UAAI,CAAC,WAAW,QAAS;AAEzB,YAAM,QAAQ,WAAW,QAAQ;AAAA,QAChC,EAAE;AAAA,QACF,EAAE;AAAA,QACF;AAAA,QACA;AAAA,MACD;AAEA,YAAM,eAAe,WAAW,QAAQ;AAAA,QACvC,EAAE;AAAA,QACF,EAAE;AAAA,QACF;AAAA,QACA;AAAA,MACD;AAEA,iBAAW,QAAQ,gBAAgB,MAAM,YAAY;AACrD,iBAAW,QAAQ,iBAAiB,MAAM,OAAO,sBAAsB,EAAE,MAAM;AAE/E,aAAO,cAAc,OAAO,EAAE,WAAW,EAAE,UAAU,OAAO,QAAQ,kBAAkB,EAAE,CAAC;AAAA,IAC1F;AAAA,IACA,CAAC,MAAM;AAAA,EACR;AAEA,QAAM,gBAAgB,MAAM;AAAA,IAC3B,CAAC,MAA6C;AAC7C,UAAI,CAAC,WAAW,QAAS;AACzB,YAAM,MAAM,EAAE;AACd,2CAAkB,KAAK,CAAC;AACxB,UAAI,CAAC,OAAO,uBAAuB,EAAE,KAAM;AAE3C,gBAAU,UAAU;AAEpB,iBAAW,QAAQ,eAAe;AAElC,YAAM,QAAQ,WAAW,QAAQ;AAAA,QAChC,EAAE;AAAA,QACF,EAAE;AAAA,QACF;AAAA,QACA;AAAA,MACD;AAEA,YAAM,gBAAgB,OAAO,sBAAsB;AACnD,YAAM,eAAe,WAAW,QAAQ,qBAAqB;AAC7D,YAAM,gBAAgB,IAAI;AAAA,QACzB,aAAa,IAAI,cAAc,QAAQ;AAAA,QACvC,aAAa,IAAI,cAAc,SAAS;AAAA,QACxC,aAAa,QAAQ,cAAc;AAAA,QACnC,aAAa,SAAS,cAAc;AAAA,MACrC;AAGA,UAAI,cAAc,cAAc,KAAK,KAAK,CAAC,cAAc,cAAc,KAAK,GAAG;AAC9E,mBAAW,QAAQ,eAAe,cAAc,cAAc,KAAK;AACnE,cAAM,QAAQ,kBAAI,IAAI,cAAc,QAAQ,cAAc,KAAK;AAC/D,cAAM,YAAY,kBAAI,IAAI,OAAO,KAAK;AACtC,mBAAW,QAAQ,gBAAgB,MAAM,SAAS;AAClD,mBAAW,QAAQ,iBAAiB,MAAM,KAAK;AAC/C,eAAO,cAAc,OAAO,EAAE,WAAW,EAAE,UAAU,OAAO,QAAQ,kBAAkB,EAAE,CAAC;AAAA,MAC1F,OAAO;AACN,cAAM,eAAe,WAAW,QAAQ;AAAA,UACvC,EAAE;AAAA,UACF,EAAE;AAAA,UACF;AAAA,UACA;AAAA,QACD;AACA,mBAAW,QAAQ,eAAe,cAAc,cAAc,YAAY;AAC1E,mBAAW,QAAQ,gBAAgB,MAAM,YAAY;AACrD,mBAAW,QAAQ,iBAAiB,MAAM,cAAc,MAAM;AAAA,MAC/D;AAEA,eAAS,QAAQA,IAAiB;AACjC,YAAI,KAAK;AACR,mDAAsB,KAAKA,EAAC;AAAA,QAC7B;AACA,kBAAU,UAAU;AACpB,iBAAS,KAAK,oBAAoB,aAAa,OAAO;AAAA,MACvD;AAEA,eAAS,KAAK,iBAAiB,aAAa,OAAO;AAAA,IACpD;AAAA,IACA,CAAC,MAAM;AAAA,EACR;AAEA,QAAM,gBAAgB,MAAM;AAAA,IAC3B,CAAC,MAA6C;AAC7C,UAAI,CAAC,WAAW,QAAS;AACzB,YAAM,QAAQ,WAAW,QAAQ;AAAA,QAChC,EAAE;AAAA,QACF,EAAE;AAAA,QACF,EAAE;AAAA,QACF;AAAA,MACD;AAEA,UAAI,UAAU,SAAS;AACtB,YAAI,WAAW,QAAQ,cAAc;AACpC,gBAAM,QAAQ,WAAW,QAAQ,gBAC/B,MAAM,EACN,IAAI,WAAW,QAAQ,gBAAgB;AACzC,iBAAO,cAAc,kBAAI,IAAI,OAAO,KAAK,CAAC;AAC1C;AAAA,QACD;AAEA,eAAO,cAAc,KAAK;AAAA,MAC3B;AAEA,YAAM,YAAY,WAAW,QAAQ,oBAAoB,EAAE,SAAS,EAAE,OAAO;AAE7E,YAAM,cAAc,OAAO,aAAa,SAAS;AAEjD,YAAM,OAA2B;AAAA,QAChC,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,OAAG,8BAAe,CAAC;AAAA,QACnB,OAAO;AAAA,QACP,OAAO,OAAO,iBAAiB,EAAE;AAAA,MAClC;AAEA,aAAO,SAAS,IAAI;AAAA,IACrB;AAAA,IACA,CAAC,MAAM;AAAA,EACR;AAEA,QAAM,UAAU,MAAM;AAAA,IACrB,CAAC,MAA2C;AAC3C,YAAM,aAAS,8BAAe,CAAC;AAE/B,aAAO,SAAS;AAAA,QACf,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,QACP,OAAO,IAAI,kBAAI,EAAE,SAAS,EAAE,OAAO;AAAA,QACnC,UAAU,EAAE;AAAA,QACZ,QAAQ,EAAE;AAAA,QACV,SAAS,EAAE,WAAW,EAAE;AAAA,QACxB,SAAS,EAAE;AAAA,QACX,cAAU,0BAAW,CAAC;AAAA,MACvB,CAAC;AAAA,IACF;AAAA,IACA,CAAC,MAAM;AAAA,EACR;AAEA,QAAM,iBAAa,6BAAc;AAEjC,QAAM,UAAU,MAAM;AAGrB,WAAO,OAAO,WAAW,MAAM;AAC9B,iBAAW,SAAS,aAAa;AACjC,iBAAW,SAAS,OAAO;AAAA,IAC5B,CAAC;AAAA,EACF,GAAG,CAAC,YAAY,MAAM,CAAC;AAEvB,SACC,4CAAC,SAAI,WAAU,gBACd;AAAA,IAAC;AAAA;AAAA,MACA,MAAK;AAAA,MACL,cAAY,IAAI,yBAAyB;AAAA,MACzC,KAAK;AAAA,MACL,WAAU;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA,gBAAgB;AAAA;AAAA,EACjB,GACD;AAEF;",
4
+ "sourcesContent": ["import {\n\tBox,\n\tTLPointerEventInfo,\n\tVec,\n\tgetPointerInfo,\n\tisAccelKey,\n\tnormalizeWheel,\n\treleasePointerCapture,\n\tsetPointerCapture,\n\tuseContainer,\n\tuseEditor,\n\tuseIsDarkMode,\n} from '@tldraw/editor'\nimport * as React from 'react'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { MinimapManager } from './MinimapManager'\n\n/** @public @react */\nexport function DefaultMinimap() {\n\tconst editor = useEditor()\n\tconst container = useContainer()\n\tconst msg = useTranslation()\n\n\tconst rCanvas = React.useRef<HTMLCanvasElement>(null!)\n\tconst rPointing = React.useRef(false)\n\n\tconst minimapRef = React.useRef<MinimapManager>()\n\n\tReact.useEffect(() => {\n\t\ttry {\n\t\t\tconst minimap = new MinimapManager(editor, rCanvas.current, container)\n\t\t\tminimapRef.current = minimap\n\t\t\treturn minimapRef.current.close\n\t\t} catch (e) {\n\t\t\teditor.annotateError(e, {\n\t\t\t\torigin: 'minimap',\n\t\t\t\twillCrashApp: false,\n\t\t\t})\n\t\t\teditor.timers.setTimeout(() => {\n\t\t\t\tthrow e\n\t\t\t})\n\t\t}\n\t}, [editor, container])\n\n\tconst onDoubleClick = React.useCallback(\n\t\t(e: React.MouseEvent<HTMLCanvasElement>) => {\n\t\t\tif (!editor.getCurrentPageShapeIds().size) return\n\t\t\tif (!minimapRef.current) return\n\n\t\t\tconst point = minimapRef.current.minimapScreenPointToPagePoint(\n\t\t\t\te.clientX,\n\t\t\t\te.clientY,\n\t\t\t\tfalse,\n\t\t\t\tfalse\n\t\t\t)\n\n\t\t\tconst clampedPoint = minimapRef.current.minimapScreenPointToPagePoint(\n\t\t\t\te.clientX,\n\t\t\t\te.clientY,\n\t\t\t\tfalse,\n\t\t\t\ttrue\n\t\t\t)\n\n\t\t\tminimapRef.current.originPagePoint.setTo(clampedPoint)\n\t\t\tminimapRef.current.originPageCenter.setTo(editor.getViewportPageBounds().center)\n\n\t\t\teditor.centerOnPoint(point, { animation: { duration: editor.options.animationMediumMs } })\n\t\t},\n\t\t[editor]\n\t)\n\n\tconst onPointerDown = React.useCallback(\n\t\t(e: React.PointerEvent<HTMLCanvasElement>) => {\n\t\t\tif (!minimapRef.current) return\n\t\t\tconst elm = e.currentTarget\n\t\t\tsetPointerCapture(elm, e)\n\t\t\tif (!editor.getCurrentPageShapeIds().size) return\n\n\t\t\trPointing.current = true\n\n\t\t\tminimapRef.current.isInViewport = false\n\n\t\t\tconst point = minimapRef.current.minimapScreenPointToPagePoint(\n\t\t\t\te.clientX,\n\t\t\t\te.clientY,\n\t\t\t\tfalse,\n\t\t\t\tfalse\n\t\t\t)\n\n\t\t\tconst _vpPageBounds = editor.getViewportPageBounds()\n\t\t\tconst commonBounds = minimapRef.current.getContentPageBounds()\n\t\t\tconst allowedBounds = new Box(\n\t\t\t\tcommonBounds.x - _vpPageBounds.width / 2,\n\t\t\t\tcommonBounds.y - _vpPageBounds.height / 2,\n\t\t\t\tcommonBounds.width + _vpPageBounds.width,\n\t\t\t\tcommonBounds.height + _vpPageBounds.height\n\t\t\t)\n\n\t\t\t// If we clicked inside of the allowed area, but outside of the viewport\n\t\t\tif (allowedBounds.containsPoint(point) && !_vpPageBounds.containsPoint(point)) {\n\t\t\t\tminimapRef.current.isInViewport = _vpPageBounds.containsPoint(point)\n\t\t\t\tconst delta = Vec.Sub(_vpPageBounds.center, _vpPageBounds.point)\n\t\t\t\tconst pagePoint = Vec.Add(point, delta)\n\t\t\t\tminimapRef.current.originPagePoint.setTo(pagePoint)\n\t\t\t\tminimapRef.current.originPageCenter.setTo(point)\n\t\t\t\teditor.centerOnPoint(point, { animation: { duration: editor.options.animationMediumMs } })\n\t\t\t} else {\n\t\t\t\tconst clampedPoint = minimapRef.current.minimapScreenPointToPagePoint(\n\t\t\t\t\te.clientX,\n\t\t\t\t\te.clientY,\n\t\t\t\t\tfalse,\n\t\t\t\t\ttrue\n\t\t\t\t)\n\t\t\t\tminimapRef.current.isInViewport = _vpPageBounds.containsPoint(clampedPoint)\n\t\t\t\tminimapRef.current.originPagePoint.setTo(clampedPoint)\n\t\t\t\tminimapRef.current.originPageCenter.setTo(_vpPageBounds.center)\n\t\t\t}\n\n\t\t\tfunction release(e: PointerEvent) {\n\t\t\t\tif (elm) {\n\t\t\t\t\treleasePointerCapture(elm, e)\n\t\t\t\t}\n\t\t\t\trPointing.current = false\n\t\t\t\tdocument.body.removeEventListener('pointerup', release)\n\t\t\t}\n\n\t\t\tdocument.body.addEventListener('pointerup', release)\n\t\t},\n\t\t[editor]\n\t)\n\n\tconst onPointerMove = React.useCallback(\n\t\t(e: React.PointerEvent<HTMLCanvasElement>) => {\n\t\t\tif (!minimapRef.current) return\n\t\t\tconst point = minimapRef.current.minimapScreenPointToPagePoint(\n\t\t\t\te.clientX,\n\t\t\t\te.clientY,\n\t\t\t\te.shiftKey,\n\t\t\t\ttrue\n\t\t\t)\n\n\t\t\tif (rPointing.current) {\n\t\t\t\tif (minimapRef.current.isInViewport) {\n\t\t\t\t\tconst delta = minimapRef.current.originPagePoint\n\t\t\t\t\t\t.clone()\n\t\t\t\t\t\t.sub(minimapRef.current.originPageCenter)\n\t\t\t\t\teditor.centerOnPoint(Vec.Sub(point, delta))\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\teditor.centerOnPoint(point)\n\t\t\t}\n\n\t\t\tconst pagePoint = minimapRef.current.getMinimapPagePoint(e.clientX, e.clientY)\n\n\t\t\tconst screenPoint = editor.pageToScreen(pagePoint)\n\n\t\t\tconst info: TLPointerEventInfo = {\n\t\t\t\ttype: 'pointer',\n\t\t\t\ttarget: 'canvas',\n\t\t\t\tname: 'pointer_move',\n\t\t\t\t...getPointerInfo(editor, e),\n\t\t\t\tpoint: screenPoint,\n\t\t\t\tisPen: editor.getInstanceState().isPenMode,\n\t\t\t}\n\n\t\t\teditor.dispatch(info)\n\t\t},\n\t\t[editor]\n\t)\n\n\tconst onWheel = React.useCallback(\n\t\t(e: React.WheelEvent<HTMLCanvasElement>) => {\n\t\t\tconst offset = normalizeWheel(e)\n\n\t\t\teditor.dispatch({\n\t\t\t\ttype: 'wheel',\n\t\t\t\tname: 'wheel',\n\t\t\t\tdelta: offset,\n\t\t\t\tpoint: new Vec(e.clientX, e.clientY),\n\t\t\t\tshiftKey: e.shiftKey,\n\t\t\t\taltKey: e.altKey,\n\t\t\t\tctrlKey: e.metaKey || e.ctrlKey,\n\t\t\t\tmetaKey: e.metaKey,\n\t\t\t\taccelKey: isAccelKey(e),\n\t\t\t})\n\t\t},\n\t\t[editor]\n\t)\n\n\tconst isDarkMode = useIsDarkMode()\n\n\tReact.useEffect(() => {\n\t\t// need to wait a tick for next theme css to be applied\n\t\t// otherwise the minimap will render with the wrong colors\n\t\teditor.timers.setTimeout(() => {\n\t\t\tminimapRef.current?.updateColors()\n\t\t\tminimapRef.current?.render()\n\t\t})\n\t}, [isDarkMode, editor])\n\n\treturn (\n\t\t<div className=\"tlui-minimap\">\n\t\t\t<canvas\n\t\t\t\trole=\"img\"\n\t\t\t\taria-label={msg('navigation-zone.minimap')}\n\t\t\t\tdata-testid=\"minimap.canvas\"\n\t\t\t\tref={rCanvas}\n\t\t\t\tclassName=\"tlui-minimap__canvas\"\n\t\t\t\tonDoubleClick={onDoubleClick}\n\t\t\t\tonPointerMove={onPointerMove}\n\t\t\t\tonPointerDown={onPointerDown}\n\t\t\t\tonWheelCapture={onWheel}\n\t\t\t/>\n\t\t</div>\n\t)\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["e"]
7
7
  }
@@ -414,7 +414,7 @@ const DefaultPageMenu = (0, import_react.memo)(function DefaultPageMenu2() {
414
414
  if (e.key === "Enter") {
415
415
  if (page.id === currentPage.id) {
416
416
  toggleEditing();
417
- (0, import_editor.stopEventPropagation)(e);
417
+ editor.markEventAsHandled(e);
418
418
  }
419
419
  }
420
420
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/lib/ui/components/PageMenu/DefaultPageMenu.tsx"],
4
- "sourcesContent": ["import {\n\tPageRecordType,\n\tTLPageId,\n\treleasePointerCapture,\n\tsetPointerCapture,\n\tstopEventPropagation,\n\ttlenv,\n\tuseEditor,\n\tuseValue,\n} from '@tldraw/editor'\nimport { memo, useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react'\nimport { PORTRAIT_BREAKPOINT } from '../../constants'\nimport { useBreakpoint } from '../../context/breakpoints'\nimport { useUiEvents } from '../../context/events'\nimport { useMenuIsOpen } from '../../hooks/useMenuIsOpen'\nimport { useReadonly } from '../../hooks/useReadonly'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiButton } from '../primitives/Button/TldrawUiButton'\nimport { TldrawUiButtonCheck } from '../primitives/Button/TldrawUiButtonCheck'\nimport { TldrawUiButtonIcon } from '../primitives/Button/TldrawUiButtonIcon'\nimport { TldrawUiButtonLabel } from '../primitives/Button/TldrawUiButtonLabel'\nimport {\n\tTldrawUiPopover,\n\tTldrawUiPopoverContent,\n\tTldrawUiPopoverTrigger,\n} from '../primitives/TldrawUiPopover'\nimport { TldrawUiRow } from '../primitives/layout'\nimport { PageItemInput } from './PageItemInput'\nimport { PageItemSubmenu } from './PageItemSubmenu'\nimport { onMovePage } from './edit-pages-shared'\n\n/** @public @react */\nexport const DefaultPageMenu = memo(function DefaultPageMenu() {\n\tconst editor = useEditor()\n\tconst trackEvent = useUiEvents()\n\tconst msg = useTranslation()\n\tconst breakpoint = useBreakpoint()\n\n\tconst handleOpenChange = useCallback(() => setIsEditing(false), [])\n\n\tconst [isOpen, onOpenChange] = useMenuIsOpen('page-menu', handleOpenChange)\n\n\tconst ITEM_HEIGHT = 36\n\n\tconst rSortableContainer = useRef<HTMLDivElement>(null)\n\n\tconst pages = useValue('pages', () => editor.getPages(), [editor])\n\tconst currentPage = useValue('currentPage', () => editor.getCurrentPage(), [editor])\n\tconst currentPageId = useValue('currentPageId', () => editor.getCurrentPageId(), [editor])\n\n\t// When in readonly mode, we don't allow a user to edit the pages\n\tconst isReadonlyMode = useReadonly()\n\n\t// If the user has reached the max page count, we disable the \"add page\" button\n\tconst maxPageCountReached = useValue(\n\t\t'maxPageCountReached',\n\t\t() => editor.getPages().length >= editor.options.maxPages,\n\t\t[editor]\n\t)\n\n\tconst isCoarsePointer = useValue(\n\t\t'isCoarsePointer',\n\t\t() => editor.getInstanceState().isCoarsePointer,\n\t\t[editor]\n\t)\n\n\t// The component has an \"editing state\" that may be toggled to expose additional controls\n\tconst [isEditing, setIsEditing] = useState(false)\n\n\tuseEffect(\n\t\tfunction closePageMenuOnEnterPressAfterPressingEnterToConfirmRename() {\n\t\t\tfunction handleKeyDown() {\n\t\t\t\tif (isEditing) return\n\t\t\t\tif (document.activeElement === document.body) {\n\t\t\t\t\teditor.menus.clearOpenMenus()\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tdocument.addEventListener('keydown', handleKeyDown, { passive: true })\n\t\t\treturn () => {\n\t\t\t\tdocument.removeEventListener('keydown', handleKeyDown)\n\t\t\t}\n\t\t},\n\t\t[editor, isEditing]\n\t)\n\n\tconst toggleEditing = useCallback(() => {\n\t\tif (isReadonlyMode) return\n\t\tsetIsEditing((s) => !s)\n\t}, [isReadonlyMode])\n\n\tconst rMutables = useRef({\n\t\tisPointing: false,\n\t\tstatus: 'idle' as 'idle' | 'pointing' | 'dragging',\n\t\tpointing: null as { id: string; index: number } | null,\n\t\tstartY: 0,\n\t\tstartIndex: 0,\n\t\tdragIndex: 0,\n\t})\n\n\tconst [sortablePositionItems, setSortablePositionItems] = useState(\n\t\tObject.fromEntries(\n\t\t\tpages.map((page, i) => [page.id, { y: i * ITEM_HEIGHT, offsetY: 0, isSelected: false }])\n\t\t)\n\t)\n\n\t// Update the sortable position items when the pages change\n\tuseLayoutEffect(() => {\n\t\tsetSortablePositionItems(\n\t\t\tObject.fromEntries(\n\t\t\t\tpages.map((page, i) => [page.id, { y: i * ITEM_HEIGHT, offsetY: 0, isSelected: false }])\n\t\t\t)\n\t\t)\n\t}, [ITEM_HEIGHT, pages])\n\n\t// Scroll the current page into view when the menu opens / when current page changes\n\tuseEffect(() => {\n\t\tif (!isOpen) return\n\t\teditor.timers.requestAnimationFrame(() => {\n\t\t\tconst elm = document.querySelector(`[data-pageid=\"${currentPageId}\"]`) as HTMLDivElement\n\n\t\t\tif (elm) {\n\t\t\t\telm.querySelector('button')?.focus()\n\n\t\t\t\tconst container = rSortableContainer.current\n\t\t\t\tif (!container) return\n\t\t\t\t// Scroll into view is slightly borked on iOS Safari\n\n\t\t\t\t// if top of less than top cuttoff, scroll into view at top\n\t\t\t\tconst elmTopPosition = elm.offsetTop\n\t\t\t\tconst containerScrollTopPosition = container.scrollTop\n\t\t\t\tif (elmTopPosition < containerScrollTopPosition) {\n\t\t\t\t\tcontainer.scrollTo({ top: elmTopPosition })\n\t\t\t\t}\n\t\t\t\t// if bottom position is greater than bottom cutoff, scroll into view at bottom\n\t\t\t\tconst elmBottomPosition = elmTopPosition + ITEM_HEIGHT\n\t\t\t\tconst containerScrollBottomPosition = container.scrollTop + container.offsetHeight\n\t\t\t\tif (elmBottomPosition > containerScrollBottomPosition) {\n\t\t\t\t\tcontainer.scrollTo({ top: elmBottomPosition - container.offsetHeight })\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t}, [ITEM_HEIGHT, currentPageId, isOpen, editor])\n\n\tconst handlePointerDown = useCallback(\n\t\t(e: React.PointerEvent<HTMLButtonElement>) => {\n\t\t\tconst { clientY, currentTarget } = e\n\t\t\tconst {\n\t\t\t\tdataset: { id, index },\n\t\t\t} = currentTarget\n\n\t\t\tif (!id || !index) return\n\n\t\t\tconst mut = rMutables.current\n\n\t\t\tsetPointerCapture(e.currentTarget, e)\n\n\t\t\tmut.status = 'pointing'\n\t\t\tmut.pointing = { id, index: +index! }\n\t\t\tconst current = sortablePositionItems[id]\n\t\t\tconst dragY = current.y\n\n\t\t\tmut.startY = clientY\n\t\t\tmut.startIndex = Math.max(0, Math.min(Math.round(dragY / ITEM_HEIGHT), pages.length - 1))\n\t\t},\n\t\t[ITEM_HEIGHT, pages.length, sortablePositionItems]\n\t)\n\n\tconst handlePointerMove = useCallback(\n\t\t(e: React.PointerEvent<HTMLButtonElement>) => {\n\t\t\tconst mut = rMutables.current\n\t\t\tif (mut.status === 'pointing') {\n\t\t\t\tconst { clientY } = e\n\t\t\t\tconst offset = clientY - mut.startY\n\t\t\t\tif (Math.abs(offset) > 5) {\n\t\t\t\t\tmut.status = 'dragging'\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (mut.status === 'dragging') {\n\t\t\t\tconst { clientY } = e\n\t\t\t\tconst offsetY = clientY - mut.startY\n\t\t\t\tconst current = sortablePositionItems[mut.pointing!.id]\n\n\t\t\t\tconst { startIndex, pointing } = mut\n\t\t\t\tconst dragY = current.y + offsetY\n\t\t\t\tconst dragIndex = Math.max(0, Math.min(Math.round(dragY / ITEM_HEIGHT), pages.length - 1))\n\n\t\t\t\tconst next = { ...sortablePositionItems }\n\t\t\t\tnext[pointing!.id] = {\n\t\t\t\t\ty: current.y,\n\t\t\t\t\toffsetY,\n\t\t\t\t\tisSelected: true,\n\t\t\t\t}\n\n\t\t\t\tif (dragIndex !== mut.dragIndex) {\n\t\t\t\t\tmut.dragIndex = dragIndex\n\n\t\t\t\t\tfor (let i = 0; i < pages.length; i++) {\n\t\t\t\t\t\tconst item = pages[i]\n\t\t\t\t\t\tif (item.id === mut.pointing!.id) {\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tlet { y } = next[item.id]\n\n\t\t\t\t\t\tif (dragIndex === startIndex) {\n\t\t\t\t\t\t\ty = i * ITEM_HEIGHT\n\t\t\t\t\t\t} else if (dragIndex < startIndex) {\n\t\t\t\t\t\t\tif (dragIndex <= i && i < startIndex) {\n\t\t\t\t\t\t\t\ty = (i + 1) * ITEM_HEIGHT\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\ty = i * ITEM_HEIGHT\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (dragIndex > startIndex) {\n\t\t\t\t\t\t\tif (dragIndex >= i && i > startIndex) {\n\t\t\t\t\t\t\t\ty = (i - 1) * ITEM_HEIGHT\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\ty = i * ITEM_HEIGHT\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (y !== next[item.id].y) {\n\t\t\t\t\t\t\tnext[item.id] = { y, offsetY: 0, isSelected: true }\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tsetSortablePositionItems(next)\n\t\t\t}\n\t\t},\n\t\t[ITEM_HEIGHT, pages, sortablePositionItems]\n\t)\n\n\tconst handlePointerUp = useCallback(\n\t\t(e: React.PointerEvent<HTMLButtonElement>) => {\n\t\t\tconst mut = rMutables.current\n\n\t\t\tif (mut.status === 'dragging') {\n\t\t\t\tconst { id, index } = mut.pointing!\n\t\t\t\tonMovePage(editor, id as TLPageId, index, mut.dragIndex, trackEvent)\n\t\t\t}\n\n\t\t\treleasePointerCapture(e.currentTarget, e)\n\t\t\tmut.status = 'idle'\n\t\t},\n\t\t[editor, trackEvent]\n\t)\n\n\tconst handleKeyDown = useCallback(\n\t\t(e: React.KeyboardEvent<HTMLButtonElement>) => {\n\t\t\tconst mut = rMutables.current\n\t\t\t// bail on escape\n\t\t\tif (e.key === 'Escape') {\n\t\t\t\tif (mut.status === 'dragging') {\n\t\t\t\t\tsetSortablePositionItems(\n\t\t\t\t\t\tObject.fromEntries(\n\t\t\t\t\t\t\tpages.map((page, i) => [\n\t\t\t\t\t\t\t\tpage.id,\n\t\t\t\t\t\t\t\t{ y: i * ITEM_HEIGHT, offsetY: 0, isSelected: false },\n\t\t\t\t\t\t\t])\n\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\t}\n\n\t\t\t\tmut.status = 'idle'\n\t\t\t}\n\t\t},\n\t\t[ITEM_HEIGHT, pages]\n\t)\n\n\tconst handleCreatePageClick = useCallback(() => {\n\t\tif (isReadonlyMode) return\n\n\t\teditor.run(() => {\n\t\t\teditor.markHistoryStoppingPoint('creating page')\n\t\t\tconst newPageId = PageRecordType.createId()\n\t\t\teditor.createPage({ name: msg('page-menu.new-page-initial-name'), id: newPageId })\n\t\t\teditor.setCurrentPage(newPageId)\n\n\t\t\tsetIsEditing(true)\n\n\t\t\teditor.timers.requestAnimationFrame(() => {\n\t\t\t\tconst elm = document.querySelector(`[data-pageid=\"${newPageId}\"]`) as HTMLDivElement\n\n\t\t\t\tif (elm) {\n\t\t\t\t\telm.querySelector('button')?.focus()\n\t\t\t\t}\n\t\t\t})\n\t\t})\n\t\ttrackEvent('new-page', { source: 'page-menu' })\n\t}, [editor, msg, isReadonlyMode, trackEvent])\n\n\tconst changePage = useCallback(\n\t\t(id: TLPageId) => {\n\t\t\teditor.setCurrentPage(id)\n\t\t\ttrackEvent('change-page', { source: 'page-menu' })\n\t\t},\n\t\t[editor, trackEvent]\n\t)\n\n\tconst renamePage = useCallback(\n\t\t(id: TLPageId, name: string) => {\n\t\t\teditor.renamePage(id, name)\n\t\t\ttrackEvent('rename-page', { source: 'page-menu' })\n\t\t},\n\t\t[editor, trackEvent]\n\t)\n\n\treturn (\n\t\t<TldrawUiPopover id=\"pages\" onOpenChange={onOpenChange} open={isOpen}>\n\t\t\t<TldrawUiPopoverTrigger data-testid=\"main.page-menu\">\n\t\t\t\t<TldrawUiButton\n\t\t\t\t\ttype=\"menu\"\n\t\t\t\t\ttitle={currentPage.name}\n\t\t\t\t\tdata-testid=\"page-menu.button\"\n\t\t\t\t\tclassName=\"tlui-page-menu__trigger\"\n\t\t\t\t>\n\t\t\t\t\t<div className=\"tlui-page-menu__name\">{currentPage.name}</div>\n\t\t\t\t\t<TldrawUiButtonIcon icon=\"chevron-down\" small />\n\t\t\t\t</TldrawUiButton>\n\t\t\t</TldrawUiPopoverTrigger>\n\t\t\t<TldrawUiPopoverContent\n\t\t\t\tside=\"bottom\"\n\t\t\t\talign=\"start\"\n\t\t\t\tsideOffset={0}\n\t\t\t\tdisableEscapeKeyDown={isEditing}\n\t\t\t>\n\t\t\t\t<div className=\"tlui-page-menu__wrapper\">\n\t\t\t\t\t<div className=\"tlui-page-menu__header\">\n\t\t\t\t\t\t<div className=\"tlui-page-menu__header__title\">{msg('page-menu.title')}</div>\n\t\t\t\t\t\t{!isReadonlyMode && (\n\t\t\t\t\t\t\t<TldrawUiRow>\n\t\t\t\t\t\t\t\t<TldrawUiButton\n\t\t\t\t\t\t\t\t\ttype=\"icon\"\n\t\t\t\t\t\t\t\t\tdata-testid=\"page-menu.edit\"\n\t\t\t\t\t\t\t\t\ttitle={msg(isEditing ? 'page-menu.edit-done' : 'page-menu.edit-start')}\n\t\t\t\t\t\t\t\t\tonClick={toggleEditing}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<TldrawUiButtonIcon icon={isEditing ? 'check' : 'edit'} />\n\t\t\t\t\t\t\t\t</TldrawUiButton>\n\t\t\t\t\t\t\t\t<TldrawUiButton\n\t\t\t\t\t\t\t\t\ttype=\"icon\"\n\t\t\t\t\t\t\t\t\tdata-testid=\"page-menu.create\"\n\t\t\t\t\t\t\t\t\ttitle={msg(\n\t\t\t\t\t\t\t\t\t\tmaxPageCountReached\n\t\t\t\t\t\t\t\t\t\t\t? 'page-menu.max-page-count-reached'\n\t\t\t\t\t\t\t\t\t\t\t: 'page-menu.create-new-page'\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\tdisabled={maxPageCountReached}\n\t\t\t\t\t\t\t\t\tonClick={handleCreatePageClick}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<TldrawUiButtonIcon icon=\"plus\" />\n\t\t\t\t\t\t\t\t</TldrawUiButton>\n\t\t\t\t\t\t\t</TldrawUiRow>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div\n\t\t\t\t\t\tdata-testid=\"page-menu.list\"\n\t\t\t\t\t\tclassName=\"tlui-page-menu__list tlui-menu__group\"\n\t\t\t\t\t\tstyle={{ height: ITEM_HEIGHT * pages.length + 4 }}\n\t\t\t\t\t\tref={rSortableContainer}\n\t\t\t\t\t>\n\t\t\t\t\t\t{pages.map((page, index) => {\n\t\t\t\t\t\t\tconst position = sortablePositionItems[page.id] ?? {\n\t\t\t\t\t\t\t\tposition: index * 40,\n\t\t\t\t\t\t\t\toffsetY: 0,\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\treturn isEditing ? (\n\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\tkey={page.id + '_editing'}\n\t\t\t\t\t\t\t\t\tdata-testid=\"page-menu.item\"\n\t\t\t\t\t\t\t\t\tdata-pageid={page.id}\n\t\t\t\t\t\t\t\t\tclassName=\"tlui-page_menu__item__sortable\"\n\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\tzIndex: page.id === currentPage.id ? 888 : index,\n\t\t\t\t\t\t\t\t\t\ttransform: `translate(0px, ${position.y + position.offsetY}px)`,\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<TldrawUiButton\n\t\t\t\t\t\t\t\t\t\ttype=\"icon\"\n\t\t\t\t\t\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\t\t\t\t\t\tclassName=\"tlui-page_menu__item__sortable__handle\"\n\t\t\t\t\t\t\t\t\t\tonPointerDown={handlePointerDown}\n\t\t\t\t\t\t\t\t\t\tonPointerUp={handlePointerUp}\n\t\t\t\t\t\t\t\t\t\tonPointerMove={handlePointerMove}\n\t\t\t\t\t\t\t\t\t\tonKeyDown={handleKeyDown}\n\t\t\t\t\t\t\t\t\t\tdata-id={page.id}\n\t\t\t\t\t\t\t\t\t\tdata-index={index}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<TldrawUiButtonIcon icon=\"drag-handle-dots\" />\n\t\t\t\t\t\t\t\t\t</TldrawUiButton>\n\t\t\t\t\t\t\t\t\t{breakpoint < PORTRAIT_BREAKPOINT.TABLET_SM && isCoarsePointer ? (\n\t\t\t\t\t\t\t\t\t\t// sigh, this is a workaround for iOS Safari\n\t\t\t\t\t\t\t\t\t\t// because the device and the radix popover seem\n\t\t\t\t\t\t\t\t\t\t// to be fighting over scroll position. Nothing\n\t\t\t\t\t\t\t\t\t\t// else seems to work!\n\t\t\t\t\t\t\t\t\t\t<TldrawUiButton\n\t\t\t\t\t\t\t\t\t\t\ttype=\"normal\"\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"tlui-page-menu__item__button\"\n\t\t\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\t\t\tconst name = window.prompt('Rename page', page.name)\n\t\t\t\t\t\t\t\t\t\t\t\tif (name && name !== page.name) {\n\t\t\t\t\t\t\t\t\t\t\t\t\trenamePage(page.id, name)\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\tonDoubleClick={toggleEditing}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<TldrawUiButtonCheck checked={page.id === currentPage.id} />\n\t\t\t\t\t\t\t\t\t\t\t<TldrawUiButtonLabel>{page.name}</TldrawUiButtonLabel>\n\t\t\t\t\t\t\t\t\t\t</TldrawUiButton>\n\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"tlui-page_menu__item__sortable__title\"\n\t\t\t\t\t\t\t\t\t\t\tstyle={{ height: ITEM_HEIGHT }}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<PageItemInput\n\t\t\t\t\t\t\t\t\t\t\t\tid={page.id}\n\t\t\t\t\t\t\t\t\t\t\t\tname={page.name}\n\t\t\t\t\t\t\t\t\t\t\t\tisCurrentPage={page.id === currentPage.id}\n\t\t\t\t\t\t\t\t\t\t\t\tonComplete={() => {\n\t\t\t\t\t\t\t\t\t\t\t\t\tsetIsEditing(false)\n\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\tonCancel={() => {\n\t\t\t\t\t\t\t\t\t\t\t\t\tsetIsEditing(false)\n\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t{!isReadonlyMode && (\n\t\t\t\t\t\t\t\t\t\t<div className=\"tlui-page_menu__item__submenu\" data-isediting={isEditing}>\n\t\t\t\t\t\t\t\t\t\t\t<PageItemSubmenu index={index} item={page} listSize={pages.length} />\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\tkey={page.id}\n\t\t\t\t\t\t\t\t\tdata-pageid={page.id}\n\t\t\t\t\t\t\t\t\tdata-testid=\"page-menu.item\"\n\t\t\t\t\t\t\t\t\tclassName=\"tlui-page-menu__item\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<TldrawUiButton\n\t\t\t\t\t\t\t\t\t\ttype=\"normal\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"tlui-page-menu__item__button\"\n\t\t\t\t\t\t\t\t\t\tonClick={() => changePage(page.id)}\n\t\t\t\t\t\t\t\t\t\tonDoubleClick={toggleEditing}\n\t\t\t\t\t\t\t\t\t\ttitle={msg('page-menu.go-to-page')}\n\t\t\t\t\t\t\t\t\t\tonKeyDown={(e) => {\n\t\t\t\t\t\t\t\t\t\t\tif (e.key === 'Enter') {\n\t\t\t\t\t\t\t\t\t\t\t\tif (page.id === currentPage.id) {\n\t\t\t\t\t\t\t\t\t\t\t\t\ttoggleEditing()\n\t\t\t\t\t\t\t\t\t\t\t\t\tstopEventPropagation(e)\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<TldrawUiButtonCheck checked={page.id === currentPage.id} />\n\t\t\t\t\t\t\t\t\t\t<TldrawUiButtonLabel>{page.name}</TldrawUiButtonLabel>\n\t\t\t\t\t\t\t\t\t</TldrawUiButton>\n\t\t\t\t\t\t\t\t\t{!isReadonlyMode && (\n\t\t\t\t\t\t\t\t\t\t<div className=\"tlui-page_menu__item__submenu\">\n\t\t\t\t\t\t\t\t\t\t\t<PageItemSubmenu\n\t\t\t\t\t\t\t\t\t\t\t\tindex={index}\n\t\t\t\t\t\t\t\t\t\t\t\titem={page}\n\t\t\t\t\t\t\t\t\t\t\t\tlistSize={pages.length}\n\t\t\t\t\t\t\t\t\t\t\t\tonRename={() => {\n\t\t\t\t\t\t\t\t\t\t\t\t\tif (tlenv.isIos) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tconst name = window.prompt('Rename page', page.name)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (name && name !== page.name) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\trenamePage(page.id, name)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetIsEditing(true)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (currentPageId !== page.id) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tchangePage(page.id)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t})}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</TldrawUiPopoverContent>\n\t\t</TldrawUiPopover>\n\t)\n})\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n\tPageRecordType,\n\tTLPageId,\n\treleasePointerCapture,\n\tsetPointerCapture,\n\ttlenv,\n\tuseEditor,\n\tuseValue,\n} from '@tldraw/editor'\nimport { memo, useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react'\nimport { PORTRAIT_BREAKPOINT } from '../../constants'\nimport { useBreakpoint } from '../../context/breakpoints'\nimport { useUiEvents } from '../../context/events'\nimport { useMenuIsOpen } from '../../hooks/useMenuIsOpen'\nimport { useReadonly } from '../../hooks/useReadonly'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiButton } from '../primitives/Button/TldrawUiButton'\nimport { TldrawUiButtonCheck } from '../primitives/Button/TldrawUiButtonCheck'\nimport { TldrawUiButtonIcon } from '../primitives/Button/TldrawUiButtonIcon'\nimport { TldrawUiButtonLabel } from '../primitives/Button/TldrawUiButtonLabel'\nimport {\n\tTldrawUiPopover,\n\tTldrawUiPopoverContent,\n\tTldrawUiPopoverTrigger,\n} from '../primitives/TldrawUiPopover'\nimport { TldrawUiRow } from '../primitives/layout'\nimport { PageItemInput } from './PageItemInput'\nimport { PageItemSubmenu } from './PageItemSubmenu'\nimport { onMovePage } from './edit-pages-shared'\n\n/** @public @react */\nexport const DefaultPageMenu = memo(function DefaultPageMenu() {\n\tconst editor = useEditor()\n\tconst trackEvent = useUiEvents()\n\tconst msg = useTranslation()\n\tconst breakpoint = useBreakpoint()\n\n\tconst handleOpenChange = useCallback(() => setIsEditing(false), [])\n\n\tconst [isOpen, onOpenChange] = useMenuIsOpen('page-menu', handleOpenChange)\n\n\tconst ITEM_HEIGHT = 36\n\n\tconst rSortableContainer = useRef<HTMLDivElement>(null)\n\n\tconst pages = useValue('pages', () => editor.getPages(), [editor])\n\tconst currentPage = useValue('currentPage', () => editor.getCurrentPage(), [editor])\n\tconst currentPageId = useValue('currentPageId', () => editor.getCurrentPageId(), [editor])\n\n\t// When in readonly mode, we don't allow a user to edit the pages\n\tconst isReadonlyMode = useReadonly()\n\n\t// If the user has reached the max page count, we disable the \"add page\" button\n\tconst maxPageCountReached = useValue(\n\t\t'maxPageCountReached',\n\t\t() => editor.getPages().length >= editor.options.maxPages,\n\t\t[editor]\n\t)\n\n\tconst isCoarsePointer = useValue(\n\t\t'isCoarsePointer',\n\t\t() => editor.getInstanceState().isCoarsePointer,\n\t\t[editor]\n\t)\n\n\t// The component has an \"editing state\" that may be toggled to expose additional controls\n\tconst [isEditing, setIsEditing] = useState(false)\n\n\tuseEffect(\n\t\tfunction closePageMenuOnEnterPressAfterPressingEnterToConfirmRename() {\n\t\t\tfunction handleKeyDown() {\n\t\t\t\tif (isEditing) return\n\t\t\t\tif (document.activeElement === document.body) {\n\t\t\t\t\teditor.menus.clearOpenMenus()\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tdocument.addEventListener('keydown', handleKeyDown, { passive: true })\n\t\t\treturn () => {\n\t\t\t\tdocument.removeEventListener('keydown', handleKeyDown)\n\t\t\t}\n\t\t},\n\t\t[editor, isEditing]\n\t)\n\n\tconst toggleEditing = useCallback(() => {\n\t\tif (isReadonlyMode) return\n\t\tsetIsEditing((s) => !s)\n\t}, [isReadonlyMode])\n\n\tconst rMutables = useRef({\n\t\tisPointing: false,\n\t\tstatus: 'idle' as 'idle' | 'pointing' | 'dragging',\n\t\tpointing: null as { id: string; index: number } | null,\n\t\tstartY: 0,\n\t\tstartIndex: 0,\n\t\tdragIndex: 0,\n\t})\n\n\tconst [sortablePositionItems, setSortablePositionItems] = useState(\n\t\tObject.fromEntries(\n\t\t\tpages.map((page, i) => [page.id, { y: i * ITEM_HEIGHT, offsetY: 0, isSelected: false }])\n\t\t)\n\t)\n\n\t// Update the sortable position items when the pages change\n\tuseLayoutEffect(() => {\n\t\tsetSortablePositionItems(\n\t\t\tObject.fromEntries(\n\t\t\t\tpages.map((page, i) => [page.id, { y: i * ITEM_HEIGHT, offsetY: 0, isSelected: false }])\n\t\t\t)\n\t\t)\n\t}, [ITEM_HEIGHT, pages])\n\n\t// Scroll the current page into view when the menu opens / when current page changes\n\tuseEffect(() => {\n\t\tif (!isOpen) return\n\t\teditor.timers.requestAnimationFrame(() => {\n\t\t\tconst elm = document.querySelector(`[data-pageid=\"${currentPageId}\"]`) as HTMLDivElement\n\n\t\t\tif (elm) {\n\t\t\t\telm.querySelector('button')?.focus()\n\n\t\t\t\tconst container = rSortableContainer.current\n\t\t\t\tif (!container) return\n\t\t\t\t// Scroll into view is slightly borked on iOS Safari\n\n\t\t\t\t// if top of less than top cuttoff, scroll into view at top\n\t\t\t\tconst elmTopPosition = elm.offsetTop\n\t\t\t\tconst containerScrollTopPosition = container.scrollTop\n\t\t\t\tif (elmTopPosition < containerScrollTopPosition) {\n\t\t\t\t\tcontainer.scrollTo({ top: elmTopPosition })\n\t\t\t\t}\n\t\t\t\t// if bottom position is greater than bottom cutoff, scroll into view at bottom\n\t\t\t\tconst elmBottomPosition = elmTopPosition + ITEM_HEIGHT\n\t\t\t\tconst containerScrollBottomPosition = container.scrollTop + container.offsetHeight\n\t\t\t\tif (elmBottomPosition > containerScrollBottomPosition) {\n\t\t\t\t\tcontainer.scrollTo({ top: elmBottomPosition - container.offsetHeight })\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t}, [ITEM_HEIGHT, currentPageId, isOpen, editor])\n\n\tconst handlePointerDown = useCallback(\n\t\t(e: React.PointerEvent<HTMLButtonElement>) => {\n\t\t\tconst { clientY, currentTarget } = e\n\t\t\tconst {\n\t\t\t\tdataset: { id, index },\n\t\t\t} = currentTarget\n\n\t\t\tif (!id || !index) return\n\n\t\t\tconst mut = rMutables.current\n\n\t\t\tsetPointerCapture(e.currentTarget, e)\n\n\t\t\tmut.status = 'pointing'\n\t\t\tmut.pointing = { id, index: +index! }\n\t\t\tconst current = sortablePositionItems[id]\n\t\t\tconst dragY = current.y\n\n\t\t\tmut.startY = clientY\n\t\t\tmut.startIndex = Math.max(0, Math.min(Math.round(dragY / ITEM_HEIGHT), pages.length - 1))\n\t\t},\n\t\t[ITEM_HEIGHT, pages.length, sortablePositionItems]\n\t)\n\n\tconst handlePointerMove = useCallback(\n\t\t(e: React.PointerEvent<HTMLButtonElement>) => {\n\t\t\tconst mut = rMutables.current\n\t\t\tif (mut.status === 'pointing') {\n\t\t\t\tconst { clientY } = e\n\t\t\t\tconst offset = clientY - mut.startY\n\t\t\t\tif (Math.abs(offset) > 5) {\n\t\t\t\t\tmut.status = 'dragging'\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (mut.status === 'dragging') {\n\t\t\t\tconst { clientY } = e\n\t\t\t\tconst offsetY = clientY - mut.startY\n\t\t\t\tconst current = sortablePositionItems[mut.pointing!.id]\n\n\t\t\t\tconst { startIndex, pointing } = mut\n\t\t\t\tconst dragY = current.y + offsetY\n\t\t\t\tconst dragIndex = Math.max(0, Math.min(Math.round(dragY / ITEM_HEIGHT), pages.length - 1))\n\n\t\t\t\tconst next = { ...sortablePositionItems }\n\t\t\t\tnext[pointing!.id] = {\n\t\t\t\t\ty: current.y,\n\t\t\t\t\toffsetY,\n\t\t\t\t\tisSelected: true,\n\t\t\t\t}\n\n\t\t\t\tif (dragIndex !== mut.dragIndex) {\n\t\t\t\t\tmut.dragIndex = dragIndex\n\n\t\t\t\t\tfor (let i = 0; i < pages.length; i++) {\n\t\t\t\t\t\tconst item = pages[i]\n\t\t\t\t\t\tif (item.id === mut.pointing!.id) {\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tlet { y } = next[item.id]\n\n\t\t\t\t\t\tif (dragIndex === startIndex) {\n\t\t\t\t\t\t\ty = i * ITEM_HEIGHT\n\t\t\t\t\t\t} else if (dragIndex < startIndex) {\n\t\t\t\t\t\t\tif (dragIndex <= i && i < startIndex) {\n\t\t\t\t\t\t\t\ty = (i + 1) * ITEM_HEIGHT\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\ty = i * ITEM_HEIGHT\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (dragIndex > startIndex) {\n\t\t\t\t\t\t\tif (dragIndex >= i && i > startIndex) {\n\t\t\t\t\t\t\t\ty = (i - 1) * ITEM_HEIGHT\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\ty = i * ITEM_HEIGHT\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (y !== next[item.id].y) {\n\t\t\t\t\t\t\tnext[item.id] = { y, offsetY: 0, isSelected: true }\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tsetSortablePositionItems(next)\n\t\t\t}\n\t\t},\n\t\t[ITEM_HEIGHT, pages, sortablePositionItems]\n\t)\n\n\tconst handlePointerUp = useCallback(\n\t\t(e: React.PointerEvent<HTMLButtonElement>) => {\n\t\t\tconst mut = rMutables.current\n\n\t\t\tif (mut.status === 'dragging') {\n\t\t\t\tconst { id, index } = mut.pointing!\n\t\t\t\tonMovePage(editor, id as TLPageId, index, mut.dragIndex, trackEvent)\n\t\t\t}\n\n\t\t\treleasePointerCapture(e.currentTarget, e)\n\t\t\tmut.status = 'idle'\n\t\t},\n\t\t[editor, trackEvent]\n\t)\n\n\tconst handleKeyDown = useCallback(\n\t\t(e: React.KeyboardEvent<HTMLButtonElement>) => {\n\t\t\tconst mut = rMutables.current\n\t\t\t// bail on escape\n\t\t\tif (e.key === 'Escape') {\n\t\t\t\tif (mut.status === 'dragging') {\n\t\t\t\t\tsetSortablePositionItems(\n\t\t\t\t\t\tObject.fromEntries(\n\t\t\t\t\t\t\tpages.map((page, i) => [\n\t\t\t\t\t\t\t\tpage.id,\n\t\t\t\t\t\t\t\t{ y: i * ITEM_HEIGHT, offsetY: 0, isSelected: false },\n\t\t\t\t\t\t\t])\n\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\t}\n\n\t\t\t\tmut.status = 'idle'\n\t\t\t}\n\t\t},\n\t\t[ITEM_HEIGHT, pages]\n\t)\n\n\tconst handleCreatePageClick = useCallback(() => {\n\t\tif (isReadonlyMode) return\n\n\t\teditor.run(() => {\n\t\t\teditor.markHistoryStoppingPoint('creating page')\n\t\t\tconst newPageId = PageRecordType.createId()\n\t\t\teditor.createPage({ name: msg('page-menu.new-page-initial-name'), id: newPageId })\n\t\t\teditor.setCurrentPage(newPageId)\n\n\t\t\tsetIsEditing(true)\n\n\t\t\teditor.timers.requestAnimationFrame(() => {\n\t\t\t\tconst elm = document.querySelector(`[data-pageid=\"${newPageId}\"]`) as HTMLDivElement\n\n\t\t\t\tif (elm) {\n\t\t\t\t\telm.querySelector('button')?.focus()\n\t\t\t\t}\n\t\t\t})\n\t\t})\n\t\ttrackEvent('new-page', { source: 'page-menu' })\n\t}, [editor, msg, isReadonlyMode, trackEvent])\n\n\tconst changePage = useCallback(\n\t\t(id: TLPageId) => {\n\t\t\teditor.setCurrentPage(id)\n\t\t\ttrackEvent('change-page', { source: 'page-menu' })\n\t\t},\n\t\t[editor, trackEvent]\n\t)\n\n\tconst renamePage = useCallback(\n\t\t(id: TLPageId, name: string) => {\n\t\t\teditor.renamePage(id, name)\n\t\t\ttrackEvent('rename-page', { source: 'page-menu' })\n\t\t},\n\t\t[editor, trackEvent]\n\t)\n\n\treturn (\n\t\t<TldrawUiPopover id=\"pages\" onOpenChange={onOpenChange} open={isOpen}>\n\t\t\t<TldrawUiPopoverTrigger data-testid=\"main.page-menu\">\n\t\t\t\t<TldrawUiButton\n\t\t\t\t\ttype=\"menu\"\n\t\t\t\t\ttitle={currentPage.name}\n\t\t\t\t\tdata-testid=\"page-menu.button\"\n\t\t\t\t\tclassName=\"tlui-page-menu__trigger\"\n\t\t\t\t>\n\t\t\t\t\t<div className=\"tlui-page-menu__name\">{currentPage.name}</div>\n\t\t\t\t\t<TldrawUiButtonIcon icon=\"chevron-down\" small />\n\t\t\t\t</TldrawUiButton>\n\t\t\t</TldrawUiPopoverTrigger>\n\t\t\t<TldrawUiPopoverContent\n\t\t\t\tside=\"bottom\"\n\t\t\t\talign=\"start\"\n\t\t\t\tsideOffset={0}\n\t\t\t\tdisableEscapeKeyDown={isEditing}\n\t\t\t>\n\t\t\t\t<div className=\"tlui-page-menu__wrapper\">\n\t\t\t\t\t<div className=\"tlui-page-menu__header\">\n\t\t\t\t\t\t<div className=\"tlui-page-menu__header__title\">{msg('page-menu.title')}</div>\n\t\t\t\t\t\t{!isReadonlyMode && (\n\t\t\t\t\t\t\t<TldrawUiRow>\n\t\t\t\t\t\t\t\t<TldrawUiButton\n\t\t\t\t\t\t\t\t\ttype=\"icon\"\n\t\t\t\t\t\t\t\t\tdata-testid=\"page-menu.edit\"\n\t\t\t\t\t\t\t\t\ttitle={msg(isEditing ? 'page-menu.edit-done' : 'page-menu.edit-start')}\n\t\t\t\t\t\t\t\t\tonClick={toggleEditing}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<TldrawUiButtonIcon icon={isEditing ? 'check' : 'edit'} />\n\t\t\t\t\t\t\t\t</TldrawUiButton>\n\t\t\t\t\t\t\t\t<TldrawUiButton\n\t\t\t\t\t\t\t\t\ttype=\"icon\"\n\t\t\t\t\t\t\t\t\tdata-testid=\"page-menu.create\"\n\t\t\t\t\t\t\t\t\ttitle={msg(\n\t\t\t\t\t\t\t\t\t\tmaxPageCountReached\n\t\t\t\t\t\t\t\t\t\t\t? 'page-menu.max-page-count-reached'\n\t\t\t\t\t\t\t\t\t\t\t: 'page-menu.create-new-page'\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\tdisabled={maxPageCountReached}\n\t\t\t\t\t\t\t\t\tonClick={handleCreatePageClick}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<TldrawUiButtonIcon icon=\"plus\" />\n\t\t\t\t\t\t\t\t</TldrawUiButton>\n\t\t\t\t\t\t\t</TldrawUiRow>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div\n\t\t\t\t\t\tdata-testid=\"page-menu.list\"\n\t\t\t\t\t\tclassName=\"tlui-page-menu__list tlui-menu__group\"\n\t\t\t\t\t\tstyle={{ height: ITEM_HEIGHT * pages.length + 4 }}\n\t\t\t\t\t\tref={rSortableContainer}\n\t\t\t\t\t>\n\t\t\t\t\t\t{pages.map((page, index) => {\n\t\t\t\t\t\t\tconst position = sortablePositionItems[page.id] ?? {\n\t\t\t\t\t\t\t\tposition: index * 40,\n\t\t\t\t\t\t\t\toffsetY: 0,\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\treturn isEditing ? (\n\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\tkey={page.id + '_editing'}\n\t\t\t\t\t\t\t\t\tdata-testid=\"page-menu.item\"\n\t\t\t\t\t\t\t\t\tdata-pageid={page.id}\n\t\t\t\t\t\t\t\t\tclassName=\"tlui-page_menu__item__sortable\"\n\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\tzIndex: page.id === currentPage.id ? 888 : index,\n\t\t\t\t\t\t\t\t\t\ttransform: `translate(0px, ${position.y + position.offsetY}px)`,\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<TldrawUiButton\n\t\t\t\t\t\t\t\t\t\ttype=\"icon\"\n\t\t\t\t\t\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\t\t\t\t\t\tclassName=\"tlui-page_menu__item__sortable__handle\"\n\t\t\t\t\t\t\t\t\t\tonPointerDown={handlePointerDown}\n\t\t\t\t\t\t\t\t\t\tonPointerUp={handlePointerUp}\n\t\t\t\t\t\t\t\t\t\tonPointerMove={handlePointerMove}\n\t\t\t\t\t\t\t\t\t\tonKeyDown={handleKeyDown}\n\t\t\t\t\t\t\t\t\t\tdata-id={page.id}\n\t\t\t\t\t\t\t\t\t\tdata-index={index}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<TldrawUiButtonIcon icon=\"drag-handle-dots\" />\n\t\t\t\t\t\t\t\t\t</TldrawUiButton>\n\t\t\t\t\t\t\t\t\t{breakpoint < PORTRAIT_BREAKPOINT.TABLET_SM && isCoarsePointer ? (\n\t\t\t\t\t\t\t\t\t\t// sigh, this is a workaround for iOS Safari\n\t\t\t\t\t\t\t\t\t\t// because the device and the radix popover seem\n\t\t\t\t\t\t\t\t\t\t// to be fighting over scroll position. Nothing\n\t\t\t\t\t\t\t\t\t\t// else seems to work!\n\t\t\t\t\t\t\t\t\t\t<TldrawUiButton\n\t\t\t\t\t\t\t\t\t\t\ttype=\"normal\"\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"tlui-page-menu__item__button\"\n\t\t\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\t\t\tconst name = window.prompt('Rename page', page.name)\n\t\t\t\t\t\t\t\t\t\t\t\tif (name && name !== page.name) {\n\t\t\t\t\t\t\t\t\t\t\t\t\trenamePage(page.id, name)\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\tonDoubleClick={toggleEditing}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<TldrawUiButtonCheck checked={page.id === currentPage.id} />\n\t\t\t\t\t\t\t\t\t\t\t<TldrawUiButtonLabel>{page.name}</TldrawUiButtonLabel>\n\t\t\t\t\t\t\t\t\t\t</TldrawUiButton>\n\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"tlui-page_menu__item__sortable__title\"\n\t\t\t\t\t\t\t\t\t\t\tstyle={{ height: ITEM_HEIGHT }}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<PageItemInput\n\t\t\t\t\t\t\t\t\t\t\t\tid={page.id}\n\t\t\t\t\t\t\t\t\t\t\t\tname={page.name}\n\t\t\t\t\t\t\t\t\t\t\t\tisCurrentPage={page.id === currentPage.id}\n\t\t\t\t\t\t\t\t\t\t\t\tonComplete={() => {\n\t\t\t\t\t\t\t\t\t\t\t\t\tsetIsEditing(false)\n\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\tonCancel={() => {\n\t\t\t\t\t\t\t\t\t\t\t\t\tsetIsEditing(false)\n\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t{!isReadonlyMode && (\n\t\t\t\t\t\t\t\t\t\t<div className=\"tlui-page_menu__item__submenu\" data-isediting={isEditing}>\n\t\t\t\t\t\t\t\t\t\t\t<PageItemSubmenu index={index} item={page} listSize={pages.length} />\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\tkey={page.id}\n\t\t\t\t\t\t\t\t\tdata-pageid={page.id}\n\t\t\t\t\t\t\t\t\tdata-testid=\"page-menu.item\"\n\t\t\t\t\t\t\t\t\tclassName=\"tlui-page-menu__item\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<TldrawUiButton\n\t\t\t\t\t\t\t\t\t\ttype=\"normal\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"tlui-page-menu__item__button\"\n\t\t\t\t\t\t\t\t\t\tonClick={() => changePage(page.id)}\n\t\t\t\t\t\t\t\t\t\tonDoubleClick={toggleEditing}\n\t\t\t\t\t\t\t\t\t\ttitle={msg('page-menu.go-to-page')}\n\t\t\t\t\t\t\t\t\t\tonKeyDown={(e) => {\n\t\t\t\t\t\t\t\t\t\t\tif (e.key === 'Enter') {\n\t\t\t\t\t\t\t\t\t\t\t\tif (page.id === currentPage.id) {\n\t\t\t\t\t\t\t\t\t\t\t\t\ttoggleEditing()\n\t\t\t\t\t\t\t\t\t\t\t\t\teditor.markEventAsHandled(e)\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<TldrawUiButtonCheck checked={page.id === currentPage.id} />\n\t\t\t\t\t\t\t\t\t\t<TldrawUiButtonLabel>{page.name}</TldrawUiButtonLabel>\n\t\t\t\t\t\t\t\t\t</TldrawUiButton>\n\t\t\t\t\t\t\t\t\t{!isReadonlyMode && (\n\t\t\t\t\t\t\t\t\t\t<div className=\"tlui-page_menu__item__submenu\">\n\t\t\t\t\t\t\t\t\t\t\t<PageItemSubmenu\n\t\t\t\t\t\t\t\t\t\t\t\tindex={index}\n\t\t\t\t\t\t\t\t\t\t\t\titem={page}\n\t\t\t\t\t\t\t\t\t\t\t\tlistSize={pages.length}\n\t\t\t\t\t\t\t\t\t\t\t\tonRename={() => {\n\t\t\t\t\t\t\t\t\t\t\t\t\tif (tlenv.isIos) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tconst name = window.prompt('Rename page', page.name)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (name && name !== page.name) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\trenamePage(page.id, name)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetIsEditing(true)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (currentPageId !== page.id) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tchangePage(page.id)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t})}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</TldrawUiPopoverContent>\n\t\t</TldrawUiPopover>\n\t)\n})\n"],
5
+ "mappings": "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",
6
6
  "names": ["DefaultPageMenu", "handleKeyDown"]
7
7
  }
@@ -37,21 +37,25 @@ var import_classnames = __toESM(require("classnames"));
37
37
  var import_react = require("react");
38
38
  var import_useRelevantStyles = require("../../hooks/useRelevantStyles");
39
39
  var import_DefaultStylePanelContent = require("./DefaultStylePanelContent");
40
+ var import_StylePanelContext = require("./StylePanelContext");
40
41
  const DefaultStylePanel = (0, import_react.memo)(function DefaultStylePanel2({
41
42
  isMobile,
43
+ styles,
42
44
  children
43
45
  }) {
44
46
  const editor = (0, import_editor.useEditor)();
45
47
  const showUiLabels = (0, import_editor.useValue)("showUiLabels", () => editor.user.getShowUiLabels(), [editor]);
46
48
  const ref = (0, import_react.useRef)(null);
47
49
  (0, import_editor.usePassThroughWheelEvents)(ref);
48
- const styles = (0, import_useRelevantStyles.useRelevantStyles)();
49
50
  const handlePointerOut = (0, import_react.useCallback)(() => {
50
51
  if (!isMobile) {
51
52
  editor.updateInstanceState({ isChangingStyle: false });
52
53
  }
53
54
  }, [editor, isMobile]);
54
- const content = children ?? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_DefaultStylePanelContent.DefaultStylePanelContent, { styles });
55
+ const defaultStyles = (0, import_useRelevantStyles.useRelevantStyles)();
56
+ if (styles === void 0) {
57
+ styles = defaultStyles;
58
+ }
55
59
  (0, import_react.useEffect)(() => {
56
60
  function handleKeyDown(event) {
57
61
  if (event.key === "Escape" && ref.current?.contains(document.activeElement)) {
@@ -65,15 +69,16 @@ const DefaultStylePanel = (0, import_react.memo)(function DefaultStylePanel2({
65
69
  stylePanelContainerEl?.removeEventListener("keydown", handleKeyDown, { capture: true });
66
70
  };
67
71
  }, [editor]);
68
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
72
+ return styles && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
69
73
  "div",
70
74
  {
71
75
  ref,
76
+ "data-testid": "style.panel",
72
77
  className: (0, import_classnames.default)("tlui-style-panel", { "tlui-style-panel__wrapper": !isMobile }),
73
78
  "data-ismobile": isMobile,
74
79
  "data-show-ui-labels": showUiLabels,
75
80
  onPointerLeave: handlePointerOut,
76
- children: content
81
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_StylePanelContext.StylePanelContextProvider, { styles, children: children ?? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_DefaultStylePanelContent.DefaultStylePanelContent, {}) })
77
82
  }
78
83
  );
79
84
  });
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/lib/ui/components/StylePanel/DefaultStylePanel.tsx"],
4
- "sourcesContent": ["import { useEditor, usePassThroughWheelEvents, useValue } from '@tldraw/editor'\nimport classNames from 'classnames'\nimport { ReactNode, memo, useCallback, useEffect, useRef } from 'react'\nimport { useRelevantStyles } from '../../hooks/useRelevantStyles'\nimport { DefaultStylePanelContent } from './DefaultStylePanelContent'\n\n/** @public */\nexport interface TLUiStylePanelProps {\n\tisMobile?: boolean\n\tchildren?: ReactNode\n}\n\n/** @public @react */\nexport const DefaultStylePanel = memo(function DefaultStylePanel({\n\tisMobile,\n\tchildren,\n}: TLUiStylePanelProps) {\n\tconst editor = useEditor()\n\tconst showUiLabels = useValue('showUiLabels', () => editor.user.getShowUiLabels(), [editor])\n\n\tconst ref = useRef<HTMLDivElement>(null)\n\tusePassThroughWheelEvents(ref)\n\n\tconst styles = useRelevantStyles()\n\n\tconst handlePointerOut = useCallback(() => {\n\t\tif (!isMobile) {\n\t\t\teditor.updateInstanceState({ isChangingStyle: false })\n\t\t}\n\t}, [editor, isMobile])\n\n\tconst content = children ?? <DefaultStylePanelContent styles={styles} />\n\n\tuseEffect(() => {\n\t\tfunction handleKeyDown(event: KeyboardEvent) {\n\t\t\tif (event.key === 'Escape' && ref.current?.contains(document.activeElement)) {\n\t\t\t\tevent.stopPropagation()\n\t\t\t\teditor.getContainer().focus()\n\t\t\t}\n\t\t}\n\n\t\tconst stylePanelContainerEl = ref.current\n\t\tstylePanelContainerEl?.addEventListener('keydown', handleKeyDown, { capture: true })\n\t\treturn () => {\n\t\t\tstylePanelContainerEl?.removeEventListener('keydown', handleKeyDown, { capture: true })\n\t\t}\n\t}, [editor])\n\n\treturn (\n\t\t<div\n\t\t\tref={ref}\n\t\t\tclassName={classNames('tlui-style-panel', { 'tlui-style-panel__wrapper': !isMobile })}\n\t\t\tdata-ismobile={isMobile}\n\t\t\tdata-show-ui-labels={showUiLabels}\n\t\t\tonPointerLeave={handlePointerOut}\n\t\t>\n\t\t\t{content}\n\t\t</div>\n\t)\n})\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA+B6B;AA/B7B,oBAA+D;AAC/D,wBAAuB;AACvB,mBAAgE;AAChE,+BAAkC;AAClC,sCAAyC;AASlC,MAAM,wBAAoB,mBAAK,SAASA,mBAAkB;AAAA,EAChE;AAAA,EACA;AACD,GAAwB;AACvB,QAAM,aAAS,yBAAU;AACzB,QAAM,mBAAe,wBAAS,gBAAgB,MAAM,OAAO,KAAK,gBAAgB,GAAG,CAAC,MAAM,CAAC;AAE3F,QAAM,UAAM,qBAAuB,IAAI;AACvC,+CAA0B,GAAG;AAE7B,QAAM,aAAS,4CAAkB;AAEjC,QAAM,uBAAmB,0BAAY,MAAM;AAC1C,QAAI,CAAC,UAAU;AACd,aAAO,oBAAoB,EAAE,iBAAiB,MAAM,CAAC;AAAA,IACtD;AAAA,EACD,GAAG,CAAC,QAAQ,QAAQ,CAAC;AAErB,QAAM,UAAU,YAAY,4CAAC,4DAAyB,QAAgB;AAEtE,8BAAU,MAAM;AACf,aAAS,cAAc,OAAsB;AAC5C,UAAI,MAAM,QAAQ,YAAY,IAAI,SAAS,SAAS,SAAS,aAAa,GAAG;AAC5E,cAAM,gBAAgB;AACtB,eAAO,aAAa,EAAE,MAAM;AAAA,MAC7B;AAAA,IACD;AAEA,UAAM,wBAAwB,IAAI;AAClC,2BAAuB,iBAAiB,WAAW,eAAe,EAAE,SAAS,KAAK,CAAC;AACnF,WAAO,MAAM;AACZ,6BAAuB,oBAAoB,WAAW,eAAe,EAAE,SAAS,KAAK,CAAC;AAAA,IACvF;AAAA,EACD,GAAG,CAAC,MAAM,CAAC;AAEX,SACC;AAAA,IAAC;AAAA;AAAA,MACA;AAAA,MACA,eAAW,kBAAAC,SAAW,oBAAoB,EAAE,6BAA6B,CAAC,SAAS,CAAC;AAAA,MACpF,iBAAe;AAAA,MACf,uBAAqB;AAAA,MACrB,gBAAgB;AAAA,MAEf;AAAA;AAAA,EACF;AAEF,CAAC;",
4
+ "sourcesContent": ["import {\n\tReadonlySharedStyleMap,\n\tuseEditor,\n\tusePassThroughWheelEvents,\n\tuseValue,\n} from '@tldraw/editor'\nimport classNames from 'classnames'\nimport { ReactNode, memo, useCallback, useEffect, useRef } from 'react'\nimport { useRelevantStyles } from '../../hooks/useRelevantStyles'\nimport { DefaultStylePanelContent } from './DefaultStylePanelContent'\nimport { StylePanelContextProvider } from './StylePanelContext'\n\n/** @public */\nexport interface TLUiStylePanelProps {\n\tisMobile?: boolean\n\tstyles?: ReadonlySharedStyleMap | null\n\tchildren?: ReactNode\n}\n\n/** @public @react */\nexport const DefaultStylePanel = memo(function DefaultStylePanel({\n\tisMobile,\n\tstyles,\n\tchildren,\n}: TLUiStylePanelProps) {\n\tconst editor = useEditor()\n\tconst showUiLabels = useValue('showUiLabels', () => editor.user.getShowUiLabels(), [editor])\n\n\tconst ref = useRef<HTMLDivElement>(null)\n\tusePassThroughWheelEvents(ref)\n\n\tconst handlePointerOut = useCallback(() => {\n\t\tif (!isMobile) {\n\t\t\teditor.updateInstanceState({ isChangingStyle: false })\n\t\t}\n\t}, [editor, isMobile])\n\n\tconst defaultStyles = useRelevantStyles()\n\tif (styles === undefined) {\n\t\tstyles = defaultStyles\n\t}\n\n\tuseEffect(() => {\n\t\tfunction handleKeyDown(event: KeyboardEvent) {\n\t\t\tif (event.key === 'Escape' && ref.current?.contains(document.activeElement)) {\n\t\t\t\tevent.stopPropagation()\n\t\t\t\teditor.getContainer().focus()\n\t\t\t}\n\t\t}\n\n\t\tconst stylePanelContainerEl = ref.current\n\t\tstylePanelContainerEl?.addEventListener('keydown', handleKeyDown, { capture: true })\n\t\treturn () => {\n\t\t\tstylePanelContainerEl?.removeEventListener('keydown', handleKeyDown, { capture: true })\n\t\t}\n\t}, [editor])\n\n\treturn (\n\t\tstyles && (\n\t\t\t<div\n\t\t\t\tref={ref}\n\t\t\t\tdata-testid=\"style.panel\"\n\t\t\t\tclassName={classNames('tlui-style-panel', { 'tlui-style-panel__wrapper': !isMobile })}\n\t\t\t\tdata-ismobile={isMobile}\n\t\t\t\tdata-show-ui-labels={showUiLabels}\n\t\t\t\tonPointerLeave={handlePointerOut}\n\t\t\t>\n\t\t\t\t<StylePanelContextProvider styles={styles}>\n\t\t\t\t\t{children ?? <DefaultStylePanelContent />}\n\t\t\t\t</StylePanelContextProvider>\n\t\t\t</div>\n\t\t)\n\t)\n})\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAoEkB;AApElB,oBAKO;AACP,wBAAuB;AACvB,mBAAgE;AAChE,+BAAkC;AAClC,sCAAyC;AACzC,+BAA0C;AAUnC,MAAM,wBAAoB,mBAAK,SAASA,mBAAkB;AAAA,EAChE;AAAA,EACA;AAAA,EACA;AACD,GAAwB;AACvB,QAAM,aAAS,yBAAU;AACzB,QAAM,mBAAe,wBAAS,gBAAgB,MAAM,OAAO,KAAK,gBAAgB,GAAG,CAAC,MAAM,CAAC;AAE3F,QAAM,UAAM,qBAAuB,IAAI;AACvC,+CAA0B,GAAG;AAE7B,QAAM,uBAAmB,0BAAY,MAAM;AAC1C,QAAI,CAAC,UAAU;AACd,aAAO,oBAAoB,EAAE,iBAAiB,MAAM,CAAC;AAAA,IACtD;AAAA,EACD,GAAG,CAAC,QAAQ,QAAQ,CAAC;AAErB,QAAM,oBAAgB,4CAAkB;AACxC,MAAI,WAAW,QAAW;AACzB,aAAS;AAAA,EACV;AAEA,8BAAU,MAAM;AACf,aAAS,cAAc,OAAsB;AAC5C,UAAI,MAAM,QAAQ,YAAY,IAAI,SAAS,SAAS,SAAS,aAAa,GAAG;AAC5E,cAAM,gBAAgB;AACtB,eAAO,aAAa,EAAE,MAAM;AAAA,MAC7B;AAAA,IACD;AAEA,UAAM,wBAAwB,IAAI;AAClC,2BAAuB,iBAAiB,WAAW,eAAe,EAAE,SAAS,KAAK,CAAC;AACnF,WAAO,MAAM;AACZ,6BAAuB,oBAAoB,WAAW,eAAe,EAAE,SAAS,KAAK,CAAC;AAAA,IACvF;AAAA,EACD,GAAG,CAAC,MAAM,CAAC;AAEX,SACC,UACC;AAAA,IAAC;AAAA;AAAA,MACA;AAAA,MACA,eAAY;AAAA,MACZ,eAAW,kBAAAC,SAAW,oBAAoB,EAAE,6BAA6B,CAAC,SAAS,CAAC;AAAA,MACpF,iBAAe;AAAA,MACf,uBAAqB;AAAA,MACrB,gBAAgB;AAAA,MAEhB,sDAAC,sDAA0B,QACzB,sBAAY,4CAAC,4DAAyB,GACxC;AAAA;AAAA,EACD;AAGH,CAAC;",
6
6
  "names": ["DefaultStylePanel", "classNames"]
7
7
  }