@dwelle/excalidraw 0.5.0-b2180aef → 0.5.0-bb58eff

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 (367) hide show
  1. package/CHANGELOG.md +21 -2
  2. package/dist/browser/dev/excalidraw-assets-dev/{c4Diagram-9cddb37f-PEY4VZB7.js → c4Diagram-9cddb37f-5K5MMBTZ.js} +4 -4
  3. package/dist/browser/dev/excalidraw-assets-dev/{chunk-BHNA7NJW.js → chunk-2WPXONHI.js} +14 -6
  4. package/dist/browser/dev/excalidraw-assets-dev/chunk-2WPXONHI.js.map +7 -0
  5. package/dist/browser/dev/excalidraw-assets-dev/{chunk-NBYAYPHZ.js → chunk-ABU3Y4P6.js} +5 -5
  6. package/dist/browser/dev/excalidraw-assets-dev/{chunk-WBHNX65T.js → chunk-AQ5OI7FF.js} +3 -3
  7. package/dist/browser/dev/excalidraw-assets-dev/{chunk-Y5HKH6XA.js → chunk-AU5UG6FO.js} +6 -6
  8. package/dist/browser/dev/excalidraw-assets-dev/{chunk-SETFIRY3.js → chunk-FG5PX37Z.js} +44892 -43600
  9. package/dist/browser/dev/excalidraw-assets-dev/chunk-FG5PX37Z.js.map +7 -0
  10. package/dist/browser/dev/excalidraw-assets-dev/{chunk-LZZSOW5G.js → chunk-FSI24XHB.js} +7 -7
  11. package/dist/browser/dev/excalidraw-assets-dev/{chunk-E557S7MQ.js → chunk-HPE2QM6Z.js} +3 -3
  12. package/dist/browser/dev/excalidraw-assets-dev/{chunk-OWSGU75H.js → chunk-JRHEG4KR.js} +3 -3
  13. package/dist/browser/dev/excalidraw-assets-dev/{chunk-VPBFET2I.js → chunk-LARCHXKL.js} +3 -3
  14. package/dist/browser/dev/excalidraw-assets-dev/chunk-OBKV4VWD.js +17 -0
  15. package/dist/browser/dev/excalidraw-assets-dev/chunk-OBKV4VWD.js.map +7 -0
  16. package/dist/browser/dev/excalidraw-assets-dev/{chunk-3EGXR66X.js → chunk-PTRCE3YZ.js} +4 -4
  17. package/dist/browser/dev/excalidraw-assets-dev/{chunk-ZAXKJMAT.js → chunk-RMILGNZX.js} +4 -4
  18. package/dist/browser/dev/excalidraw-assets-dev/{chunk-TCBWJJWV.js → chunk-UN4RKPVH.js} +3 -3
  19. package/dist/browser/dev/excalidraw-assets-dev/{chunk-FODTRPG3.js → chunk-VJWYXZRD.js} +3 -3
  20. package/dist/browser/dev/excalidraw-assets-dev/{chunk-D66SDVP5.js → chunk-VVJS3CBB.js} +3 -3
  21. package/dist/browser/dev/excalidraw-assets-dev/{chunk-N5BBQLFA.js → chunk-YLFK45LY.js} +21 -21
  22. package/dist/browser/dev/excalidraw-assets-dev/{classDiagram-bc733c3b-JSZNPXOZ.js → classDiagram-bc733c3b-NWRL2CDH.js} +7 -7
  23. package/dist/browser/dev/excalidraw-assets-dev/{classDiagram-v2-8931bdaf-XZABE7NO.js → classDiagram-v2-8931bdaf-Y5FPX4CT.js} +10 -10
  24. package/dist/browser/dev/excalidraw-assets-dev/{directory-open-01563666-JBJQLHCB.js → directory-open-01563666-VWSBJ543.js} +2 -2
  25. package/dist/browser/dev/excalidraw-assets-dev/{directory-open-4ed118d0-AVAL3OHL.js → directory-open-4ed118d0-FYNYOZXP.js} +2 -2
  26. package/dist/browser/dev/excalidraw-assets-dev/dist-HOOQ44NM.js +10 -0
  27. package/dist/browser/dev/excalidraw-assets-dev/{en-NZOK7NH7.js → en-OFPNSLTO.js} +4 -2
  28. package/dist/browser/dev/excalidraw-assets-dev/{erDiagram-f6946109-4QSBUSYO.js → erDiagram-f6946109-URHWBVQF.js} +5 -5
  29. package/dist/browser/dev/excalidraw-assets-dev/{file-open-002ab408-OO3RYMPC.js → file-open-002ab408-K7UWK3UX.js} +2 -2
  30. package/dist/browser/dev/excalidraw-assets-dev/{file-open-7c801643-I4T65EE5.js → file-open-7c801643-PUS6AQBV.js} +2 -2
  31. package/dist/browser/dev/excalidraw-assets-dev/{file-save-3189631c-6CIF7VXA.js → file-save-3189631c-AVBJT4K7.js} +2 -2
  32. package/dist/browser/dev/excalidraw-assets-dev/{file-save-745eba88-Y6PZEOQJ.js → file-save-745eba88-FCWOWXVA.js} +2 -2
  33. package/dist/browser/dev/excalidraw-assets-dev/{flowDiagram-93327f21-2Q3YOEXF.js → flowDiagram-93327f21-ARY24FIN.js} +11 -11
  34. package/dist/browser/dev/excalidraw-assets-dev/{flowDiagram-v2-476db779-J5GISDEJ.js → flowDiagram-v2-476db779-Y3LYCDLM.js} +11 -11
  35. package/dist/browser/dev/excalidraw-assets-dev/{flowchart-elk-definition-5082a990-IENP3HGW.js → flowchart-elk-definition-5082a990-DTGYPOS7.js} +8 -8
  36. package/dist/browser/dev/excalidraw-assets-dev/{ganttDiagram-7ce12d6b-REFK6FBK.js → ganttDiagram-7ce12d6b-GWKDCJYX.js} +3 -3
  37. package/dist/browser/dev/excalidraw-assets-dev/{gitGraphDiagram-1e960c50-IQVIPT45.js → gitGraphDiagram-1e960c50-A4SIEE63.js} +3 -3
  38. package/dist/browser/dev/excalidraw-assets-dev/{image-LGX5I4ZO.js → image-J27XZPQC.js} +6 -6
  39. package/dist/browser/dev/excalidraw-assets-dev/{image-5ICVK422.css → image-ZQHNSB7P.css} +1719 -1587
  40. package/dist/browser/dev/excalidraw-assets-dev/image-ZQHNSB7P.css.map +7 -0
  41. package/dist/browser/dev/excalidraw-assets-dev/{image-blob-reduce.esm-YIBCQAZT.js → image-blob-reduce.esm-BDWVJKFQ.js} +2 -2
  42. package/dist/browser/dev/excalidraw-assets-dev/{infoDiagram-264bed3e-F6HNESGL.js → infoDiagram-264bed3e-AUF35UHX.js} +3 -3
  43. package/dist/browser/dev/excalidraw-assets-dev/{journeyDiagram-31be0096-U2VLZYDS.js → journeyDiagram-31be0096-ADAT3O42.js} +4 -4
  44. package/dist/browser/dev/excalidraw-assets-dev/{mindmap-definition-4fc2557c-FPCY5KJG.js → mindmap-definition-4fc2557c-YC2LM75P.js} +4 -4
  45. package/dist/browser/dev/excalidraw-assets-dev/{pica-MVKKFBEE.js → pica-GXUQBC7B.js} +2 -2
  46. package/dist/browser/dev/excalidraw-assets-dev/{pieDiagram-157505fe-WZHX73VN.js → pieDiagram-157505fe-4XR6DLIZ.js} +3 -3
  47. package/dist/browser/dev/excalidraw-assets-dev/{quadrantDiagram-fd70f2d0-LDIC264P.js → quadrantDiagram-fd70f2d0-LIR55Z6M.js} +3 -3
  48. package/dist/browser/dev/excalidraw-assets-dev/{requirementDiagram-19c99588-L7QT6GLS.js → requirementDiagram-19c99588-NKRCRRBM.js} +5 -5
  49. package/dist/browser/dev/excalidraw-assets-dev/{roundRect-DADH6WR7.js → roundRect-ZNZYUVWJ.js} +2 -2
  50. package/dist/browser/dev/excalidraw-assets-dev/{sequenceDiagram-5dfd0049-GHIDHZQT.js → sequenceDiagram-5dfd0049-VUKNRO5G.js} +4 -4
  51. package/dist/browser/dev/excalidraw-assets-dev/{stateDiagram-133e3642-65LI7CZ7.js → stateDiagram-133e3642-3NYPG4IW.js} +6 -6
  52. package/dist/browser/dev/excalidraw-assets-dev/{stateDiagram-v2-6371a76b-XXMHR5TG.js → stateDiagram-v2-6371a76b-YINZI7AG.js} +10 -10
  53. package/dist/browser/dev/excalidraw-assets-dev/{timeline-definition-5ed366f4-OIEEMQSB.js → timeline-definition-5ed366f4-KWC42LPI.js} +3 -3
  54. package/dist/browser/dev/index.css +269 -137
  55. package/dist/browser/dev/index.css.map +3 -3
  56. package/dist/browser/dev/index.js +11 -5
  57. package/dist/browser/prod/excalidraw-assets/{c4Diagram-9cddb37f-TZR3YECX.js → c4Diagram-9cddb37f-UIUBGLLC.js} +1 -1
  58. package/dist/browser/prod/excalidraw-assets/{chunk-NAINBD24.js → chunk-4C6GEPVI.js} +1 -1
  59. package/dist/browser/prod/excalidraw-assets/{chunk-RXNHMEGA.js → chunk-5EY4KGYU.js} +1 -1
  60. package/dist/browser/prod/excalidraw-assets/chunk-7CLKPETF.js +1 -0
  61. package/dist/browser/prod/excalidraw-assets/chunk-D2I3QE7U.js +269 -0
  62. package/dist/browser/prod/excalidraw-assets/{chunk-WXSVWMVD.js → chunk-EQDCUI7P.js} +1 -1
  63. package/dist/browser/prod/excalidraw-assets/{chunk-X5EU7KOJ.js → chunk-FGOIQKRL.js} +1 -1
  64. package/dist/browser/prod/excalidraw-assets/{chunk-5WS52ZFV.js → chunk-FVDUD6XA.js} +1 -1
  65. package/dist/browser/prod/excalidraw-assets/{chunk-F6IMNTBC.js → chunk-I32TF3FD.js} +1 -1
  66. package/dist/browser/prod/excalidraw-assets/{chunk-NWYUEDDS.js → chunk-LOWTGNCV.js} +1 -1
  67. package/dist/browser/prod/excalidraw-assets/{chunk-J6AGEV2X.js → chunk-MJ2YKZ3B.js} +1 -1
  68. package/dist/browser/prod/excalidraw-assets/{chunk-IUV7EN5I.js → chunk-RVQN2TTU.js} +3 -3
  69. package/dist/browser/prod/excalidraw-assets/{chunk-IEF2XJIX.js → chunk-VI6ARPX6.js} +1 -1
  70. package/dist/browser/prod/excalidraw-assets/{chunk-LZ2WFMDL.js → chunk-VZ5ZGWAN.js} +1 -1
  71. package/dist/browser/prod/excalidraw-assets/{chunk-AKC6KRIS.js → chunk-X3V4W6Y3.js} +1 -1
  72. package/dist/browser/prod/excalidraw-assets/{chunk-GOBEXXS4.js → chunk-XXT5RS66.js} +1 -1
  73. package/dist/browser/prod/excalidraw-assets/{chunk-4S63NBQL.js → chunk-YGSQT3TE.js} +4 -4
  74. package/dist/browser/prod/excalidraw-assets/{classDiagram-bc733c3b-SATLP6S3.js → classDiagram-bc733c3b-6BX33ZTH.js} +1 -1
  75. package/dist/browser/prod/excalidraw-assets/{classDiagram-v2-8931bdaf-O7IXKAFS.js → classDiagram-v2-8931bdaf-ACBVEHQO.js} +1 -1
  76. package/dist/browser/prod/excalidraw-assets/{directory-open-01563666-2VFHDWFK.js → directory-open-01563666-C2PFQBKL.js} +1 -1
  77. package/dist/browser/prod/excalidraw-assets/{directory-open-4ed118d0-4ETCHWB2.js → directory-open-4ed118d0-E55HNHTS.js} +1 -1
  78. package/dist/browser/prod/excalidraw-assets/dist-XTBKPFET.js +1 -0
  79. package/dist/browser/prod/excalidraw-assets/en-46OXMRU6.js +1 -0
  80. package/dist/browser/prod/excalidraw-assets/{erDiagram-f6946109-RROH5PKB.js → erDiagram-f6946109-TYWREFGK.js} +1 -1
  81. package/dist/browser/prod/excalidraw-assets/{file-open-002ab408-2I5HJRIT.js → file-open-002ab408-FQU3HANB.js} +1 -1
  82. package/dist/browser/prod/excalidraw-assets/{file-open-7c801643-4MOMJOAD.js → file-open-7c801643-BCD55L36.js} +1 -1
  83. package/dist/browser/prod/excalidraw-assets/{file-save-3189631c-3KVHGHIE.js → file-save-3189631c-TAXV2OAM.js} +1 -1
  84. package/dist/browser/prod/excalidraw-assets/{file-save-745eba88-TJBQ2X5I.js → file-save-745eba88-DPWZ3VE6.js} +1 -1
  85. package/dist/browser/prod/excalidraw-assets/{flowDiagram-93327f21-DMLC54G3.js → flowDiagram-93327f21-4VGGLTSV.js} +1 -1
  86. package/dist/browser/prod/excalidraw-assets/flowDiagram-v2-476db779-KLWICWG3.js +1 -0
  87. package/dist/browser/prod/excalidraw-assets/{flowchart-elk-definition-5082a990-Y2P4GO4N.js → flowchart-elk-definition-5082a990-DWI3JPDY.js} +1 -1
  88. package/dist/browser/prod/excalidraw-assets/{ganttDiagram-7ce12d6b-BPV5NUOC.js → ganttDiagram-7ce12d6b-FGLMWLXT.js} +1 -1
  89. package/dist/browser/prod/excalidraw-assets/{gitGraphDiagram-1e960c50-AYQB5F3W.js → gitGraphDiagram-1e960c50-6PYRBTDK.js} +1 -1
  90. package/dist/browser/prod/excalidraw-assets/image-M662KTMJ.css +1 -0
  91. package/dist/browser/prod/excalidraw-assets/image-XP52XYUU.js +1 -0
  92. package/dist/browser/prod/excalidraw-assets/{image-blob-reduce.esm-C5HOGDIN.js → image-blob-reduce.esm-7C326NDW.js} +1 -1
  93. package/dist/browser/prod/excalidraw-assets/{infoDiagram-264bed3e-GNTQ26SY.js → infoDiagram-264bed3e-B3RQYU4J.js} +1 -1
  94. package/dist/browser/prod/excalidraw-assets/{journeyDiagram-31be0096-LKINE4MW.js → journeyDiagram-31be0096-SPHJ2Z6S.js} +1 -1
  95. package/dist/browser/prod/excalidraw-assets/{mindmap-definition-4fc2557c-2ZOKJH4X.js → mindmap-definition-4fc2557c-EKE5IPT5.js} +1 -1
  96. package/dist/browser/prod/excalidraw-assets/{pica-C7Q5T7SU.js → pica-WBNTBMON.js} +1 -1
  97. package/dist/browser/prod/excalidraw-assets/{pieDiagram-157505fe-V5EI75X3.js → pieDiagram-157505fe-R3GPKUOS.js} +1 -1
  98. package/dist/browser/prod/excalidraw-assets/{quadrantDiagram-fd70f2d0-FX47PVPZ.js → quadrantDiagram-fd70f2d0-E6DDN2FC.js} +1 -1
  99. package/dist/browser/prod/excalidraw-assets/{requirementDiagram-19c99588-6ZBUJ6AB.js → requirementDiagram-19c99588-EDK37RW4.js} +1 -1
  100. package/dist/browser/prod/excalidraw-assets/{roundRect-H7RKZWHK.js → roundRect-P4IDSYXR.js} +1 -1
  101. package/dist/browser/prod/excalidraw-assets/{sequenceDiagram-5dfd0049-RGN3USYI.js → sequenceDiagram-5dfd0049-SDPAZI6N.js} +1 -1
  102. package/dist/browser/prod/excalidraw-assets/{stateDiagram-133e3642-BZZPZIJC.js → stateDiagram-133e3642-2GOIU2WH.js} +1 -1
  103. package/dist/browser/prod/excalidraw-assets/{stateDiagram-v2-6371a76b-SMMXQVDX.js → stateDiagram-v2-6371a76b-HIFSCSY4.js} +1 -1
  104. package/dist/browser/prod/excalidraw-assets/{timeline-definition-5ed366f4-P2EZRRNS.js → timeline-definition-5ed366f4-KTXR6TKT.js} +1 -1
  105. package/dist/browser/prod/index.css +1 -1
  106. package/dist/browser/prod/index.js +1 -1
  107. package/dist/dev/{en-CVWI7UBD.json → en-54AU74IP.json} +11 -5
  108. package/dist/dev/index.css +269 -137
  109. package/dist/dev/index.css.map +3 -3
  110. package/dist/dev/index.js +23162 -21972
  111. package/dist/dev/index.js.map +4 -4
  112. package/dist/excalidraw/actions/actionAddToLibrary.d.ts +21 -12
  113. package/dist/excalidraw/actions/actionBoundText.d.ts +14 -8
  114. package/dist/excalidraw/actions/actionBoundText.js +9 -7
  115. package/dist/excalidraw/actions/actionCanvas.d.ts +82 -46
  116. package/dist/excalidraw/actions/actionClipboard.d.ts +48 -27
  117. package/dist/excalidraw/actions/actionClipboard.js +23 -8
  118. package/dist/excalidraw/actions/actionDeleteSelected.d.ts +21 -12
  119. package/dist/excalidraw/actions/actionDeleteSelected.js +3 -2
  120. package/dist/excalidraw/actions/actionDuplicateSelection.d.ts +1 -1
  121. package/dist/excalidraw/actions/actionDuplicateSelection.js +7 -2
  122. package/dist/excalidraw/actions/actionElementLock.d.ts +14 -8
  123. package/dist/excalidraw/actions/actionExport.d.ts +63 -36
  124. package/dist/excalidraw/actions/actionExport.js +4 -4
  125. package/dist/excalidraw/actions/actionFinalize.d.ts +13 -7
  126. package/dist/excalidraw/actions/actionFinalize.js +7 -6
  127. package/dist/excalidraw/actions/actionFlip.js +5 -5
  128. package/dist/excalidraw/actions/actionFrame.d.ts +21 -12
  129. package/dist/excalidraw/actions/actionGroup.d.ts +14 -8
  130. package/dist/excalidraw/actions/actionGroup.js +6 -3
  131. package/dist/excalidraw/actions/actionHistory.js +3 -0
  132. package/dist/excalidraw/actions/actionLinearEditor.d.ts +7 -4
  133. package/dist/excalidraw/actions/actionLinearEditor.js +1 -1
  134. package/dist/excalidraw/{element/Hyperlink.d.ts → actions/actionLink.d.ts} +31 -51
  135. package/dist/excalidraw/actions/actionLink.js +40 -0
  136. package/dist/excalidraw/actions/actionMenu.d.ts +20 -11
  137. package/dist/excalidraw/actions/actionNavigate.d.ts +14 -8
  138. package/dist/excalidraw/actions/actionNavigate.js +15 -6
  139. package/dist/excalidraw/actions/actionProperties.d.ts +91 -52
  140. package/dist/excalidraw/actions/actionProperties.js +4 -4
  141. package/dist/excalidraw/actions/actionSelectAll.d.ts +7 -4
  142. package/dist/excalidraw/actions/actionSelectAll.js +1 -1
  143. package/dist/excalidraw/actions/actionStyles.d.ts +7 -4
  144. package/dist/excalidraw/actions/actionStyles.js +1 -1
  145. package/dist/excalidraw/actions/actionToggleGridMode.d.ts +7 -4
  146. package/dist/excalidraw/actions/actionToggleObjectsSnapMode.d.ts +7 -4
  147. package/dist/excalidraw/actions/actionToggleStats.d.ts +7 -4
  148. package/dist/excalidraw/actions/actionToggleViewMode.d.ts +7 -4
  149. package/dist/excalidraw/actions/actionToggleZenMode.d.ts +7 -4
  150. package/dist/excalidraw/actions/actionZindex.d.ts +11 -11
  151. package/dist/excalidraw/actions/index.d.ts +1 -1
  152. package/dist/excalidraw/actions/index.js +1 -1
  153. package/dist/excalidraw/actions/manager.js +2 -1
  154. package/dist/excalidraw/appState.d.ts +1 -1
  155. package/dist/excalidraw/appState.js +3 -5
  156. package/dist/excalidraw/charts.js +4 -4
  157. package/dist/excalidraw/clients.d.ts +10 -1
  158. package/dist/excalidraw/clients.js +153 -6
  159. package/dist/excalidraw/clipboard.js +5 -5
  160. package/dist/excalidraw/colors.d.ts +8 -7
  161. package/dist/excalidraw/colors.js +8 -15
  162. package/dist/excalidraw/components/Actions.js +14 -2
  163. package/dist/excalidraw/components/App.d.ts +6 -3
  164. package/dist/excalidraw/components/App.js +208 -164
  165. package/dist/excalidraw/components/Avatar.d.ts +2 -3
  166. package/dist/excalidraw/components/Avatar.js +2 -5
  167. package/dist/excalidraw/components/Button.d.ts +1 -1
  168. package/dist/excalidraw/components/ColorPicker/colorPickerUtils.d.ts +1 -1
  169. package/dist/excalidraw/components/ColorPicker/keyboardNavHandlers.js +1 -1
  170. package/dist/excalidraw/components/FilledButton.d.ts +2 -2
  171. package/dist/excalidraw/components/FilledButton.js +27 -3
  172. package/dist/excalidraw/components/FollowMode/FollowMode.js +1 -1
  173. package/dist/excalidraw/components/ImageExportDialog.d.ts +2 -1
  174. package/dist/excalidraw/components/ImageExportDialog.js +16 -12
  175. package/dist/excalidraw/components/JSONExportDialog.js +1 -1
  176. package/dist/excalidraw/components/LayerUI.js +1 -1
  177. package/dist/excalidraw/components/PasteChartDialog.js +11 -5
  178. package/dist/excalidraw/components/ProjectName.d.ts +0 -1
  179. package/dist/excalidraw/components/ProjectName.js +1 -1
  180. package/dist/excalidraw/components/PublishLibrary.js +3 -3
  181. package/dist/excalidraw/components/ShareableLinkDialog.js +10 -10
  182. package/dist/excalidraw/components/Stack.d.ts +2 -2
  183. package/dist/excalidraw/components/TTDDialog/common.js +10 -1
  184. package/dist/excalidraw/components/TextField.d.ts +5 -2
  185. package/dist/excalidraw/components/TextField.js +6 -3
  186. package/dist/excalidraw/components/Toast.d.ts +3 -2
  187. package/dist/excalidraw/components/Toast.js +2 -2
  188. package/dist/excalidraw/components/ToolButton.js +2 -1
  189. package/dist/excalidraw/components/UserList.d.ts +3 -7
  190. package/dist/excalidraw/components/UserList.js +63 -34
  191. package/dist/excalidraw/components/canvases/InteractiveCanvas.js +20 -23
  192. package/dist/excalidraw/components/canvases/StaticCanvas.js +1 -1
  193. package/dist/excalidraw/components/dropdownMenu/DropdownMenuContent.js +22 -2
  194. package/dist/excalidraw/components/hyperlink/Hyperlink.d.ts +19 -0
  195. package/dist/excalidraw/{element → components/hyperlink}/Hyperlink.js +36 -109
  196. package/dist/excalidraw/components/hyperlink/helpers.d.ts +7 -0
  197. package/dist/excalidraw/components/hyperlink/helpers.js +49 -0
  198. package/dist/excalidraw/components/icons.d.ts +3 -0
  199. package/dist/excalidraw/components/icons.js +4 -1
  200. package/dist/excalidraw/components/live-collaboration/LiveCollaborationTrigger.js +3 -2
  201. package/dist/excalidraw/constants.d.ts +11 -7
  202. package/dist/excalidraw/constants.js +17 -10
  203. package/dist/excalidraw/data/blob.js +13 -14
  204. package/dist/excalidraw/data/filesystem.d.ts +1 -1
  205. package/dist/excalidraw/data/index.d.ts +16 -7
  206. package/dist/excalidraw/data/index.js +54 -35
  207. package/dist/excalidraw/data/json.d.ts +1 -1
  208. package/dist/excalidraw/data/json.js +5 -3
  209. package/dist/excalidraw/data/library.d.ts +60 -8
  210. package/dist/excalidraw/data/library.js +302 -33
  211. package/dist/excalidraw/data/reconcile.d.ts +6 -0
  212. package/dist/excalidraw/data/reconcile.js +49 -0
  213. package/dist/excalidraw/data/resave.d.ts +1 -1
  214. package/dist/excalidraw/data/resave.js +12 -8
  215. package/dist/excalidraw/data/restore.d.ts +3 -3
  216. package/dist/excalidraw/data/restore.js +8 -11
  217. package/dist/excalidraw/data/transform.d.ts +1 -1
  218. package/dist/excalidraw/data/transform.js +14 -9
  219. package/dist/excalidraw/element/ElementCanvasButtons.d.ts +3 -2
  220. package/dist/excalidraw/element/ElementCanvasButtons.js +4 -4
  221. package/dist/excalidraw/element/binding.d.ts +9 -9
  222. package/dist/excalidraw/element/binding.js +57 -56
  223. package/dist/excalidraw/element/bounds.d.ts +6 -6
  224. package/dist/excalidraw/element/bounds.js +22 -28
  225. package/dist/excalidraw/element/collision.d.ts +8 -8
  226. package/dist/excalidraw/element/collision.js +43 -40
  227. package/dist/excalidraw/element/containerCache.d.ts +11 -0
  228. package/dist/excalidraw/element/containerCache.js +14 -0
  229. package/dist/excalidraw/element/dragElements.js +1 -1
  230. package/dist/excalidraw/element/embeddable.d.ts +7 -4
  231. package/dist/excalidraw/element/embeddable.js +3 -4
  232. package/dist/excalidraw/element/image.js +1 -2
  233. package/dist/excalidraw/element/index.d.ts +8 -1
  234. package/dist/excalidraw/element/index.js +23 -1
  235. package/dist/excalidraw/element/linearElementEditor.d.ts +36 -32
  236. package/dist/excalidraw/element/linearElementEditor.js +66 -67
  237. package/dist/excalidraw/element/newElement.d.ts +4 -5
  238. package/dist/excalidraw/element/newElement.js +10 -10
  239. package/dist/excalidraw/element/resizeElements.d.ts +1 -1
  240. package/dist/excalidraw/element/resizeElements.js +20 -25
  241. package/dist/excalidraw/element/resizeTest.d.ts +3 -3
  242. package/dist/excalidraw/element/resizeTest.js +4 -4
  243. package/dist/excalidraw/element/sizeHelpers.d.ts +2 -2
  244. package/dist/excalidraw/element/sizeHelpers.js +2 -2
  245. package/dist/excalidraw/element/textElement.d.ts +25 -8
  246. package/dist/excalidraw/element/textElement.js +60 -69
  247. package/dist/excalidraw/element/textWysiwyg.d.ts +1 -6
  248. package/dist/excalidraw/element/textWysiwyg.js +11 -34
  249. package/dist/excalidraw/element/transformHandles.d.ts +4 -4
  250. package/dist/excalidraw/element/transformHandles.js +6 -6
  251. package/dist/excalidraw/element/types.d.ts +15 -4
  252. package/dist/excalidraw/errors.d.ts +3 -0
  253. package/dist/excalidraw/errors.js +3 -0
  254. package/dist/excalidraw/fractionalIndex.d.ts +40 -0
  255. package/dist/excalidraw/fractionalIndex.js +241 -0
  256. package/dist/excalidraw/frame.d.ts +12 -12
  257. package/dist/excalidraw/frame.js +48 -52
  258. package/dist/excalidraw/history.d.ts +1 -1
  259. package/dist/excalidraw/index-node.js +2 -1
  260. package/dist/excalidraw/index.d.ts +8 -4
  261. package/dist/excalidraw/index.js +10 -6
  262. package/dist/excalidraw/laser-trails.js +1 -1
  263. package/dist/excalidraw/locales/en.json +11 -5
  264. package/dist/excalidraw/queue.d.ts +9 -0
  265. package/dist/excalidraw/queue.js +27 -0
  266. package/dist/excalidraw/renderer/helpers.d.ts +13 -0
  267. package/dist/excalidraw/renderer/helpers.js +39 -0
  268. package/dist/excalidraw/renderer/interactiveScene.d.ts +20 -0
  269. package/dist/excalidraw/renderer/{renderScene.js → interactiveScene.js} +196 -575
  270. package/dist/excalidraw/renderer/renderElement.d.ts +3 -4
  271. package/dist/excalidraw/renderer/renderElement.js +20 -361
  272. package/dist/excalidraw/renderer/staticScene.d.ts +11 -0
  273. package/dist/excalidraw/renderer/staticScene.js +205 -0
  274. package/dist/excalidraw/renderer/staticSvgScene.d.ts +5 -0
  275. package/dist/excalidraw/renderer/staticSvgScene.js +385 -0
  276. package/dist/excalidraw/scene/Fonts.js +1 -1
  277. package/dist/excalidraw/scene/Renderer.js +5 -3
  278. package/dist/excalidraw/scene/Scene.d.ts +9 -13
  279. package/dist/excalidraw/scene/Scene.js +34 -29
  280. package/dist/excalidraw/scene/Shape.d.ts +1 -1
  281. package/dist/excalidraw/scene/Shape.js +1 -0
  282. package/dist/excalidraw/scene/ShapeCache.d.ts +3 -3
  283. package/dist/excalidraw/scene/ShapeCache.js +3 -3
  284. package/dist/excalidraw/scene/export.d.ts +21 -14
  285. package/dist/excalidraw/scene/export.js +30 -49
  286. package/dist/excalidraw/scene/index.d.ts +0 -1
  287. package/dist/excalidraw/scene/index.js +0 -1
  288. package/dist/excalidraw/scene/scrollbars.d.ts +3 -2
  289. package/dist/excalidraw/scene/scrollbars.js +1 -1
  290. package/dist/excalidraw/scene/selection.d.ts +3 -3
  291. package/dist/excalidraw/scene/selection.js +9 -9
  292. package/dist/excalidraw/scene/types.d.ts +12 -24
  293. package/dist/excalidraw/snapping.d.ts +7 -7
  294. package/dist/excalidraw/snapping.js +21 -21
  295. package/dist/excalidraw/types.d.ts +20 -14
  296. package/dist/excalidraw/utility-types.d.ts +2 -0
  297. package/dist/excalidraw/utils.d.ts +4 -1
  298. package/dist/excalidraw/utils.js +20 -6
  299. package/dist/excalidraw/zindex.d.ts +2 -2
  300. package/dist/excalidraw/zindex.js +9 -13
  301. package/dist/prod/{en-CVWI7UBD.json → en-54AU74IP.json} +11 -5
  302. package/dist/prod/index.css +1 -1
  303. package/dist/prod/index.js +45 -45
  304. package/dist/utils/export.d.ts +3 -6
  305. package/dist/utils/export.js +9 -12
  306. package/dist/utils/index.d.ts +3 -0
  307. package/dist/utils/index.js +3 -0
  308. package/dist/utils/withinBounds.js +2 -1
  309. package/package.json +4 -3
  310. package/dist/browser/dev/excalidraw-assets-dev/chunk-ALCD6MVO.js +0 -17
  311. package/dist/browser/dev/excalidraw-assets-dev/chunk-ALCD6MVO.js.map +0 -7
  312. package/dist/browser/dev/excalidraw-assets-dev/chunk-BHNA7NJW.js.map +0 -7
  313. package/dist/browser/dev/excalidraw-assets-dev/chunk-SETFIRY3.js.map +0 -7
  314. package/dist/browser/dev/excalidraw-assets-dev/dist-G3BXOFUL.js +0 -10
  315. package/dist/browser/dev/excalidraw-assets-dev/image-5ICVK422.css.map +0 -7
  316. package/dist/browser/prod/excalidraw-assets/chunk-CXVKHCCJ.js +0 -1
  317. package/dist/browser/prod/excalidraw-assets/chunk-TIF52737.js +0 -269
  318. package/dist/browser/prod/excalidraw-assets/dist-H2KBTIFX.js +0 -1
  319. package/dist/browser/prod/excalidraw-assets/en-BEWXQ75W.js +0 -1
  320. package/dist/browser/prod/excalidraw-assets/flowDiagram-v2-476db779-YHMMMOCL.js +0 -1
  321. package/dist/browser/prod/excalidraw-assets/image-RZAUMCLO.js +0 -1
  322. package/dist/browser/prod/excalidraw-assets/image-S6WF7PJU.css +0 -1
  323. package/dist/excalidraw/renderer/renderScene.d.ts +0 -24
  324. /package/dist/browser/dev/excalidraw-assets-dev/{c4Diagram-9cddb37f-PEY4VZB7.js.map → c4Diagram-9cddb37f-5K5MMBTZ.js.map} +0 -0
  325. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-NBYAYPHZ.js.map → chunk-ABU3Y4P6.js.map} +0 -0
  326. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-WBHNX65T.js.map → chunk-AQ5OI7FF.js.map} +0 -0
  327. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-Y5HKH6XA.js.map → chunk-AU5UG6FO.js.map} +0 -0
  328. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-LZZSOW5G.js.map → chunk-FSI24XHB.js.map} +0 -0
  329. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-E557S7MQ.js.map → chunk-HPE2QM6Z.js.map} +0 -0
  330. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-OWSGU75H.js.map → chunk-JRHEG4KR.js.map} +0 -0
  331. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-VPBFET2I.js.map → chunk-LARCHXKL.js.map} +0 -0
  332. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-3EGXR66X.js.map → chunk-PTRCE3YZ.js.map} +0 -0
  333. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-ZAXKJMAT.js.map → chunk-RMILGNZX.js.map} +0 -0
  334. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-TCBWJJWV.js.map → chunk-UN4RKPVH.js.map} +0 -0
  335. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-FODTRPG3.js.map → chunk-VJWYXZRD.js.map} +0 -0
  336. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-D66SDVP5.js.map → chunk-VVJS3CBB.js.map} +0 -0
  337. /package/dist/browser/dev/excalidraw-assets-dev/{chunk-N5BBQLFA.js.map → chunk-YLFK45LY.js.map} +0 -0
  338. /package/dist/browser/dev/excalidraw-assets-dev/{classDiagram-bc733c3b-JSZNPXOZ.js.map → classDiagram-bc733c3b-NWRL2CDH.js.map} +0 -0
  339. /package/dist/browser/dev/excalidraw-assets-dev/{classDiagram-v2-8931bdaf-XZABE7NO.js.map → classDiagram-v2-8931bdaf-Y5FPX4CT.js.map} +0 -0
  340. /package/dist/browser/dev/excalidraw-assets-dev/{directory-open-01563666-JBJQLHCB.js.map → directory-open-01563666-VWSBJ543.js.map} +0 -0
  341. /package/dist/browser/dev/excalidraw-assets-dev/{directory-open-4ed118d0-AVAL3OHL.js.map → directory-open-4ed118d0-FYNYOZXP.js.map} +0 -0
  342. /package/dist/browser/dev/excalidraw-assets-dev/{dist-G3BXOFUL.js.map → dist-HOOQ44NM.js.map} +0 -0
  343. /package/dist/browser/dev/excalidraw-assets-dev/{en-NZOK7NH7.js.map → en-OFPNSLTO.js.map} +0 -0
  344. /package/dist/browser/dev/excalidraw-assets-dev/{erDiagram-f6946109-4QSBUSYO.js.map → erDiagram-f6946109-URHWBVQF.js.map} +0 -0
  345. /package/dist/browser/dev/excalidraw-assets-dev/{file-open-002ab408-OO3RYMPC.js.map → file-open-002ab408-K7UWK3UX.js.map} +0 -0
  346. /package/dist/browser/dev/excalidraw-assets-dev/{file-open-7c801643-I4T65EE5.js.map → file-open-7c801643-PUS6AQBV.js.map} +0 -0
  347. /package/dist/browser/dev/excalidraw-assets-dev/{file-save-3189631c-6CIF7VXA.js.map → file-save-3189631c-AVBJT4K7.js.map} +0 -0
  348. /package/dist/browser/dev/excalidraw-assets-dev/{file-save-745eba88-Y6PZEOQJ.js.map → file-save-745eba88-FCWOWXVA.js.map} +0 -0
  349. /package/dist/browser/dev/excalidraw-assets-dev/{flowDiagram-93327f21-2Q3YOEXF.js.map → flowDiagram-93327f21-ARY24FIN.js.map} +0 -0
  350. /package/dist/browser/dev/excalidraw-assets-dev/{flowDiagram-v2-476db779-J5GISDEJ.js.map → flowDiagram-v2-476db779-Y3LYCDLM.js.map} +0 -0
  351. /package/dist/browser/dev/excalidraw-assets-dev/{flowchart-elk-definition-5082a990-IENP3HGW.js.map → flowchart-elk-definition-5082a990-DTGYPOS7.js.map} +0 -0
  352. /package/dist/browser/dev/excalidraw-assets-dev/{ganttDiagram-7ce12d6b-REFK6FBK.js.map → ganttDiagram-7ce12d6b-GWKDCJYX.js.map} +0 -0
  353. /package/dist/browser/dev/excalidraw-assets-dev/{gitGraphDiagram-1e960c50-IQVIPT45.js.map → gitGraphDiagram-1e960c50-A4SIEE63.js.map} +0 -0
  354. /package/dist/browser/dev/excalidraw-assets-dev/{image-LGX5I4ZO.js.map → image-J27XZPQC.js.map} +0 -0
  355. /package/dist/browser/dev/excalidraw-assets-dev/{image-blob-reduce.esm-YIBCQAZT.js.map → image-blob-reduce.esm-BDWVJKFQ.js.map} +0 -0
  356. /package/dist/browser/dev/excalidraw-assets-dev/{infoDiagram-264bed3e-F6HNESGL.js.map → infoDiagram-264bed3e-AUF35UHX.js.map} +0 -0
  357. /package/dist/browser/dev/excalidraw-assets-dev/{journeyDiagram-31be0096-U2VLZYDS.js.map → journeyDiagram-31be0096-ADAT3O42.js.map} +0 -0
  358. /package/dist/browser/dev/excalidraw-assets-dev/{mindmap-definition-4fc2557c-FPCY5KJG.js.map → mindmap-definition-4fc2557c-YC2LM75P.js.map} +0 -0
  359. /package/dist/browser/dev/excalidraw-assets-dev/{pica-MVKKFBEE.js.map → pica-GXUQBC7B.js.map} +0 -0
  360. /package/dist/browser/dev/excalidraw-assets-dev/{pieDiagram-157505fe-WZHX73VN.js.map → pieDiagram-157505fe-4XR6DLIZ.js.map} +0 -0
  361. /package/dist/browser/dev/excalidraw-assets-dev/{quadrantDiagram-fd70f2d0-LDIC264P.js.map → quadrantDiagram-fd70f2d0-LIR55Z6M.js.map} +0 -0
  362. /package/dist/browser/dev/excalidraw-assets-dev/{requirementDiagram-19c99588-L7QT6GLS.js.map → requirementDiagram-19c99588-NKRCRRBM.js.map} +0 -0
  363. /package/dist/browser/dev/excalidraw-assets-dev/{roundRect-DADH6WR7.js.map → roundRect-ZNZYUVWJ.js.map} +0 -0
  364. /package/dist/browser/dev/excalidraw-assets-dev/{sequenceDiagram-5dfd0049-GHIDHZQT.js.map → sequenceDiagram-5dfd0049-VUKNRO5G.js.map} +0 -0
  365. /package/dist/browser/dev/excalidraw-assets-dev/{stateDiagram-133e3642-65LI7CZ7.js.map → stateDiagram-133e3642-3NYPG4IW.js.map} +0 -0
  366. /package/dist/browser/dev/excalidraw-assets-dev/{stateDiagram-v2-6371a76b-XXMHR5TG.js.map → stateDiagram-v2-6371a76b-YINZI7AG.js.map} +0 -0
  367. /package/dist/browser/dev/excalidraw-assets-dev/{timeline-definition-5ed366f4-OIEEMQSB.js.map → timeline-definition-5ed366f4-KWC42LPI.js.map} +0 -0
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import "./UserList.scss";
3
- import React from "react";
3
+ import React, { useLayoutEffect } from "react";
4
4
  import clsx from "clsx";
5
5
  import { Tooltip } from "./Tooltip";
6
6
  import { useExcalidrawActionManager } from "./App";
@@ -9,24 +9,28 @@ import { Island } from "./Island";
9
9
  import { searchIcon } from "./icons";
10
10
  import { t } from "../i18n";
11
11
  import { isShallowEqual } from "../utils";
12
- const FIRST_N_AVATARS = 3;
12
+ import { supportsResizeObserver } from "../constants";
13
+ const DEFAULT_MAX_AVATARS = 4;
13
14
  const SHOW_COLLABORATORS_FILTER_AT = 8;
14
- const ConditionalTooltipWrapper = ({ shouldWrap, children, clientId, username, }) => shouldWrap ? (_jsx(Tooltip, { label: username || "Unknown user", children: children }, clientId)) : (_jsx(React.Fragment, { children: children }, clientId));
15
- const renderCollaborator = ({ actionManager, collaborator, clientId, withName = false, shouldWrapWithTooltip = false, isBeingFollowed, }) => {
15
+ const ConditionalTooltipWrapper = ({ shouldWrap, children, username, }) => shouldWrap ? (_jsx(Tooltip, { label: username || "Unknown user", children: children })) : (_jsx(React.Fragment, { children: children }));
16
+ const renderCollaborator = ({ actionManager, collaborator, socketId, withName = false, shouldWrapWithTooltip = false, isBeingFollowed, }) => {
16
17
  const data = {
17
- clientId,
18
+ socketId,
18
19
  collaborator,
19
20
  withName,
20
21
  isBeingFollowed,
21
22
  };
22
23
  const avatarJSX = actionManager.renderAction("goToCollaborator", data);
23
- return (_jsx(ConditionalTooltipWrapper, { clientId: clientId, username: collaborator.username, shouldWrap: shouldWrapWithTooltip, children: avatarJSX }, clientId));
24
+ return (_jsx(ConditionalTooltipWrapper, { username: collaborator.username, shouldWrap: shouldWrapWithTooltip, children: avatarJSX }, socketId));
24
25
  };
25
26
  const collaboratorComparatorKeys = [
26
27
  "avatarUrl",
27
28
  "id",
28
29
  "socketId",
29
30
  "username",
31
+ "isInCall",
32
+ "isSpeaking",
33
+ "isMuted",
30
34
  ];
31
35
  export const UserList = React.memo(({ className, mobile, collaborators, userToFollow }) => {
32
36
  const actionManager = useExcalidrawActionManager();
@@ -37,47 +41,68 @@ export const UserList = React.memo(({ className, mobile, collaborators, userToFo
37
41
  // filter on user id, else fall back on unique socketId
38
42
  userId, { ...collaborator, socketId });
39
43
  });
40
- const uniqueCollaboratorsArray = Array.from(uniqueCollaboratorsMap).filter(([_, collaborator]) => collaborator.username?.trim());
44
+ const uniqueCollaboratorsArray = Array.from(uniqueCollaboratorsMap.values()).filter((collaborator) => collaborator.username?.trim());
41
45
  const [searchTerm, setSearchTerm] = React.useState("");
42
- if (uniqueCollaboratorsArray.length === 0) {
43
- return null;
44
- }
46
+ const userListWrapper = React.useRef(null);
47
+ useLayoutEffect(() => {
48
+ if (userListWrapper.current) {
49
+ const updateMaxAvatars = (width) => {
50
+ const maxAvatars = Math.max(1, Math.min(8, Math.floor(width / 38)));
51
+ setMaxAvatars(maxAvatars);
52
+ };
53
+ updateMaxAvatars(userListWrapper.current.clientWidth);
54
+ if (!supportsResizeObserver) {
55
+ return;
56
+ }
57
+ const resizeObserver = new ResizeObserver((entries) => {
58
+ for (const entry of entries) {
59
+ const { width } = entry.contentRect;
60
+ updateMaxAvatars(width);
61
+ }
62
+ });
63
+ resizeObserver.observe(userListWrapper.current);
64
+ return () => {
65
+ resizeObserver.disconnect();
66
+ };
67
+ }
68
+ }, []);
69
+ const [maxAvatars, setMaxAvatars] = React.useState(DEFAULT_MAX_AVATARS);
45
70
  const searchTermNormalized = searchTerm.trim().toLowerCase();
46
71
  const filteredCollaborators = searchTermNormalized
47
- ? uniqueCollaboratorsArray.filter(([, collaborator]) => collaborator.username?.toLowerCase().includes(searchTerm))
72
+ ? uniqueCollaboratorsArray.filter((collaborator) => collaborator.username?.toLowerCase().includes(searchTerm))
48
73
  : uniqueCollaboratorsArray;
49
- const firstNCollaborators = uniqueCollaboratorsArray.slice(0, FIRST_N_AVATARS);
50
- const firstNAvatarsJSX = firstNCollaborators.map(([clientId, collaborator]) => renderCollaborator({
74
+ const firstNCollaborators = uniqueCollaboratorsArray.slice(0, maxAvatars - 1);
75
+ const firstNAvatarsJSX = firstNCollaborators.map((collaborator) => renderCollaborator({
51
76
  actionManager,
52
77
  collaborator,
53
- clientId,
78
+ socketId: collaborator.socketId,
54
79
  shouldWrapWithTooltip: true,
55
80
  isBeingFollowed: collaborator.socketId === userToFollow,
56
81
  }));
57
- return mobile ? (_jsx("div", { className: clsx("UserList UserList_mobile", className), children: uniqueCollaboratorsArray.map(([clientId, collaborator]) => renderCollaborator({
82
+ return mobile ? (_jsx("div", { className: clsx("UserList UserList_mobile", className), children: uniqueCollaboratorsArray.map((collaborator) => renderCollaborator({
58
83
  actionManager,
59
84
  collaborator,
60
- clientId,
85
+ socketId: collaborator.socketId,
61
86
  shouldWrapWithTooltip: true,
62
87
  isBeingFollowed: collaborator.socketId === userToFollow,
63
- })) })) : (_jsxs("div", { className: clsx("UserList", className), children: [firstNAvatarsJSX, uniqueCollaboratorsArray.length > FIRST_N_AVATARS && (_jsxs(Popover.Root, { onOpenChange: (isOpen) => {
64
- if (!isOpen) {
65
- setSearchTerm("");
66
- }
67
- }, children: [_jsxs(Popover.Trigger, { className: "UserList__more", children: ["+", uniqueCollaboratorsArray.length - FIRST_N_AVATARS] }), _jsx(Popover.Content, { style: {
68
- zIndex: 2,
69
- width: "13rem",
70
- textAlign: "left",
71
- }, align: "end", sideOffset: 10, children: _jsxs(Island, { style: { overflow: "hidden" }, children: [uniqueCollaboratorsArray.length >=
72
- SHOW_COLLABORATORS_FILTER_AT && (_jsxs("div", { className: "UserList__search-wrapper", children: [searchIcon, _jsx("input", { className: "UserList__search", type: "text", placeholder: t("userList.search.placeholder"), value: searchTerm, onChange: (e) => {
73
- setSearchTerm(e.target.value);
74
- } })] })), _jsxs("div", { className: "dropdown-menu UserList__collaborators", children: [filteredCollaborators.length === 0 && (_jsx("div", { className: "UserList__collaborators__empty", children: t("userList.search.empty") })), _jsx("div", { className: "UserList__hint", children: t("userList.hint.text") }), filteredCollaborators.map(([clientId, collaborator]) => renderCollaborator({
75
- actionManager,
76
- collaborator,
77
- clientId,
78
- withName: true,
79
- isBeingFollowed: collaborator.socketId === userToFollow,
80
- }))] })] }) })] }))] }));
88
+ })) })) : (_jsx("div", { className: "UserList-wrapper", ref: userListWrapper, children: _jsxs("div", { className: clsx("UserList", className), style: { [`--max-avatars`]: maxAvatars }, children: [firstNAvatarsJSX, uniqueCollaboratorsArray.length > maxAvatars - 1 && (_jsxs(Popover.Root, { onOpenChange: (isOpen) => {
89
+ if (!isOpen) {
90
+ setSearchTerm("");
91
+ }
92
+ }, children: [_jsxs(Popover.Trigger, { className: "UserList__more", children: ["+", uniqueCollaboratorsArray.length - maxAvatars + 1] }), _jsx(Popover.Content, { style: {
93
+ zIndex: 2,
94
+ width: "15rem",
95
+ textAlign: "left",
96
+ }, align: "end", sideOffset: 10, children: _jsxs(Island, { style: { overflow: "hidden" }, children: [uniqueCollaboratorsArray.length >=
97
+ SHOW_COLLABORATORS_FILTER_AT && (_jsxs("div", { className: "UserList__search-wrapper", children: [searchIcon, _jsx("input", { className: "UserList__search", type: "text", placeholder: t("userList.search.placeholder"), value: searchTerm, onChange: (e) => {
98
+ setSearchTerm(e.target.value);
99
+ } })] })), _jsxs("div", { className: "dropdown-menu UserList__collaborators", children: [filteredCollaborators.length === 0 && (_jsx("div", { className: "UserList__collaborators__empty", children: t("userList.search.empty") })), _jsx("div", { className: "UserList__hint", children: t("userList.hint.text") }), filteredCollaborators.map((collaborator) => renderCollaborator({
100
+ actionManager,
101
+ collaborator,
102
+ socketId: collaborator.socketId,
103
+ withName: true,
104
+ isBeingFollowed: collaborator.socketId === userToFollow,
105
+ }))] })] }) })] }))] }) }));
81
106
  }, (prev, next) => {
82
107
  if (prev.collaborators.size !== next.collaborators.size ||
83
108
  prev.mobile !== next.mobile ||
@@ -85,9 +110,13 @@ export const UserList = React.memo(({ className, mobile, collaborators, userToFo
85
110
  prev.userToFollow !== next.userToFollow) {
86
111
  return false;
87
112
  }
113
+ const nextCollaboratorSocketIds = next.collaborators.keys();
88
114
  for (const [socketId, collaborator] of prev.collaborators) {
89
115
  const nextCollaborator = next.collaborators.get(socketId);
90
116
  if (!nextCollaborator ||
117
+ // this checks order of collaborators in the map is the same
118
+ // as previous render
119
+ socketId !== nextCollaboratorSocketIds.next().value ||
91
120
  !isShallowEqual(collaborator, nextCollaborator, collaboratorComparatorKeys)) {
92
121
  return false;
93
122
  }
@@ -1,10 +1,10 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import React, { useEffect, useRef } from "react";
3
- import { renderInteractiveScene } from "../../renderer/renderScene";
4
3
  import { isShallowEqual, sceneCoordsToViewportCoords } from "../../utils";
5
4
  import { CURSOR_TYPE } from "../../constants";
6
5
  import { t } from "../../i18n";
7
6
  import { isRenderThrottlingEnabled } from "../../reactUtils";
7
+ import { renderInteractiveScene } from "../../renderer/interactiveScene";
8
8
  const InteractiveCanvas = (props) => {
9
9
  const isComponentMounted = useRef(false);
10
10
  useEffect(() => {
@@ -12,37 +12,34 @@ const InteractiveCanvas = (props) => {
12
12
  isComponentMounted.current = true;
13
13
  return;
14
14
  }
15
- const cursorButton = {};
16
- const pointerViewportCoords = {};
17
- const remoteSelectedElementIds = {};
18
- const pointerUsernames = {};
19
- const pointerUserStates = {};
15
+ const remotePointerButton = new Map();
16
+ const remotePointerViewportCoords = new Map();
17
+ const remoteSelectedElementIds = new Map();
18
+ const remotePointerUsernames = new Map();
19
+ const remotePointerUserStates = new Map();
20
20
  props.appState.collaborators.forEach((user, socketId) => {
21
21
  if (user.selectedElementIds) {
22
22
  for (const id of Object.keys(user.selectedElementIds)) {
23
- if (!(id in remoteSelectedElementIds)) {
24
- remoteSelectedElementIds[id] = [];
23
+ if (!remoteSelectedElementIds.has(id)) {
24
+ remoteSelectedElementIds.set(id, []);
25
25
  }
26
- remoteSelectedElementIds[id].push(socketId);
26
+ remoteSelectedElementIds.get(id).push(socketId);
27
27
  }
28
28
  }
29
29
  if (!user.pointer || user.pointer.renderCursor === false) {
30
30
  return;
31
31
  }
32
32
  if (user.username) {
33
- pointerUsernames[socketId] = user.username;
33
+ remotePointerUsernames.set(socketId, user.username);
34
34
  }
35
35
  if (user.userState) {
36
- pointerUserStates[socketId] = user.userState;
36
+ remotePointerUserStates.set(socketId, user.userState);
37
37
  }
38
- pointerViewportCoords[socketId] = {
39
- ...sceneCoordsToViewportCoords({
40
- sceneX: user.pointer.x,
41
- sceneY: user.pointer.y,
42
- }, props.appState),
43
- id: user.id || socketId,
44
- };
45
- cursorButton[socketId] = user.button;
38
+ remotePointerViewportCoords.set(socketId, sceneCoordsToViewportCoords({
39
+ sceneX: user.pointer.x,
40
+ sceneY: user.pointer.y,
41
+ }, props.appState));
42
+ remotePointerButton.set(socketId, user.button);
46
43
  });
47
44
  const selectionColor = (props.containerRef?.current &&
48
45
  getComputedStyle(props.containerRef.current).getPropertyValue("--color-selection")) ||
@@ -55,11 +52,11 @@ const InteractiveCanvas = (props) => {
55
52
  scale: window.devicePixelRatio,
56
53
  appState: props.appState,
57
54
  renderConfig: {
58
- remotePointerViewportCoords: pointerViewportCoords,
59
- remotePointerButton: cursorButton,
55
+ remotePointerViewportCoords,
56
+ remotePointerButton,
60
57
  remoteSelectedElementIds,
61
- remotePointerUsernames: pointerUsernames,
62
- remotePointerUserStates: pointerUserStates,
58
+ remotePointerUsernames,
59
+ remotePointerUserStates,
63
60
  selectionColor,
64
61
  renderScrollbars: false,
65
62
  },
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import React, { useEffect, useRef } from "react";
3
- import { renderStaticScene } from "../../renderer/renderScene";
3
+ import { renderStaticScene } from "../../renderer/staticScene";
4
4
  import { isShallowEqual } from "../../utils";
5
5
  import { isRenderThrottlingEnabled } from "../../reactUtils";
6
6
  const StaticCanvas = (props) => {
@@ -3,15 +3,35 @@ import { Island } from "../Island";
3
3
  import { useDevice } from "../App";
4
4
  import clsx from "clsx";
5
5
  import Stack from "../Stack";
6
- import { useRef } from "react";
6
+ import { useEffect, useRef } from "react";
7
7
  import { DropdownMenuContentPropsContext } from "./common";
8
8
  import { useOutsideClick } from "../../hooks/useOutsideClick";
9
+ import { KEYS } from "../../keys";
10
+ import { EVENT } from "../../constants";
11
+ import { useStable } from "../../hooks/useStable";
9
12
  const MenuContent = ({ children, onClickOutside, className = "", onSelect, style, }) => {
10
13
  const device = useDevice();
11
14
  const menuRef = useRef(null);
15
+ const callbacksRef = useStable({ onClickOutside });
12
16
  useOutsideClick(menuRef, () => {
13
- onClickOutside?.();
17
+ callbacksRef.onClickOutside?.();
14
18
  });
19
+ useEffect(() => {
20
+ const onKeyDown = (event) => {
21
+ if (event.key === KEYS.ESCAPE) {
22
+ event.stopImmediatePropagation();
23
+ callbacksRef.onClickOutside?.();
24
+ }
25
+ };
26
+ document.addEventListener(EVENT.KEYDOWN, onKeyDown, {
27
+ // so that we can stop propagation of the event before it reaches
28
+ // event handlers that were bound before this one
29
+ capture: true,
30
+ });
31
+ return () => {
32
+ document.removeEventListener(EVENT.KEYDOWN, onKeyDown);
33
+ };
34
+ }, [callbacksRef]);
15
35
  const classNames = clsx(`dropdown-menu ${className}`, {
16
36
  "dropdown-menu--mobile": device.editor.isMobile,
17
37
  }).trim();
@@ -0,0 +1,19 @@
1
+ /// <reference types="react" />
2
+ import { AppState, ExcalidrawProps } from "../../types";
3
+ import { ElementsMap, ExcalidrawEmbeddableElement, NonDeletedExcalidrawElement } from "../../element/types";
4
+ import "./Hyperlink.scss";
5
+ export declare const Hyperlink: ({ element, elementsMap, setAppState, onLinkOpen, setToast, updateEmbedValidationStatus, }: {
6
+ element: NonDeletedExcalidrawElement;
7
+ elementsMap: ElementsMap;
8
+ setAppState: React.Component<any, AppState>["setState"];
9
+ onLinkOpen: ExcalidrawProps["onLinkOpen"];
10
+ setToast: (toast: {
11
+ message: string;
12
+ closable?: boolean;
13
+ duration?: number;
14
+ } | null) => void;
15
+ updateEmbedValidationStatus: (element: ExcalidrawEmbeddableElement, status: boolean) => void;
16
+ }) => JSX.Element | null;
17
+ export declare const getContextMenuLabel: (elements: readonly NonDeletedExcalidrawElement[], appState: AppState) => "labels.link.editEmbed" | "labels.link.edit" | "labels.link.createEmbed" | "labels.link.create";
18
+ export declare const showHyperlinkTooltip: (element: NonDeletedExcalidrawElement, appState: AppState, elementsMap: ElementsMap) => void;
19
+ export declare const hideHyperlinkToolip: () => void;
@@ -1,36 +1,32 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { getShortcutKey, sceneCoordsToViewportCoords, viewportCoordsToSceneCoords, wrapEvent, } from "../utils";
3
- import { getEmbedLink, embeddableURLValidator } from "./embeddable";
4
- import { mutateElement } from "./mutateElement";
5
- import { register } from "../actions/register";
6
- import { ToolButton } from "../components/ToolButton";
7
- import { FreedrawIcon, LinkIcon, TrashIcon } from "../components/icons";
8
- import { t } from "../i18n";
2
+ import { sceneCoordsToViewportCoords, viewportCoordsToSceneCoords, wrapEvent, } from "../../utils";
3
+ import { getEmbedLink, embeddableURLValidator } from "../../element/embeddable";
4
+ import { mutateElement } from "../../element/mutateElement";
5
+ import { ToolButton } from "../ToolButton";
6
+ import { FreedrawIcon, TrashIcon } from "../icons";
7
+ import { t } from "../../i18n";
9
8
  import { useCallback, useEffect, useLayoutEffect, useRef, useState, } from "react";
10
9
  import clsx from "clsx";
11
- import { KEYS } from "../keys";
12
- import { DEFAULT_LINK_SIZE } from "../renderer/renderElement";
13
- import { rotate } from "../math";
14
- import { EVENT, HYPERLINK_TOOLTIP_DELAY, MIME_TYPES } from "../constants";
15
- import { getTooltipDiv, updateTooltipPosition } from "../components/Tooltip";
16
- import { getSelectedElements } from "../scene";
17
- import { isPointHittingElementBoundingBox } from "./collision";
18
- import { getElementAbsoluteCoords } from ".";
19
- import { isLocalLink, normalizeLink } from "../data/url";
10
+ import { KEYS } from "../../keys";
11
+ import { EVENT, HYPERLINK_TOOLTIP_DELAY } from "../../constants";
12
+ import { getElementAbsoluteCoords } from "../../element/bounds";
13
+ import { getTooltipDiv, updateTooltipPosition } from "../Tooltip";
14
+ import { getSelectedElements } from "../../scene";
15
+ import { isPointHittingElementBoundingBox } from "../../element/collision";
16
+ import { isLocalLink, normalizeLink } from "../../data/url";
20
17
  import "./Hyperlink.scss";
21
- import { trackEvent } from "../analytics";
22
- import { useAppProps, useExcalidrawAppState } from "../components/App";
23
- import { isEmbeddableElement } from "./typeChecks";
18
+ import { trackEvent } from "../../analytics";
19
+ import { useAppProps, useExcalidrawAppState } from "../App";
20
+ import { isEmbeddableElement } from "../../element/typeChecks";
21
+ import { getLinkHandleFromCoords } from "./helpers";
24
22
  const CONTAINER_WIDTH = 320;
25
23
  const SPACE_BOTTOM = 85;
26
24
  const CONTAINER_PADDING = 5;
27
25
  const CONTAINER_HEIGHT = 42;
28
26
  const AUTO_HIDE_TIMEOUT = 500;
29
- export const EXTERNAL_LINK_IMG = document.createElement("img");
30
- EXTERNAL_LINK_IMG.src = `data:${MIME_TYPES.svg}, ${encodeURIComponent(`<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#1971c2" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-external-link"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15 3 21 3 21 9"></polyline><line x1="10" y1="14" x2="21" y2="3"></line></svg>`)}`;
31
27
  let IS_HYPERLINK_TOOLTIP_VISIBLE = false;
32
28
  const embeddableLinkCache = new Map();
33
- export const Hyperlink = ({ element, setAppState, onLinkOpen, setToast, updateEmbedValidationStatus, }) => {
29
+ export const Hyperlink = ({ element, elementsMap, setAppState, onLinkOpen, setToast, updateEmbedValidationStatus, }) => {
34
30
  const appState = useExcalidrawAppState();
35
31
  const appProps = useAppProps();
36
32
  const linkVal = element.link || "";
@@ -69,8 +65,11 @@ export const Hyperlink = ({ element, setAppState, onLinkOpen, setToast, updateEm
69
65
  else {
70
66
  const { width, height } = element;
71
67
  const embedLink = getEmbedLink(link);
72
- if (embedLink?.warning) {
73
- setToast({ message: embedLink.warning, closable: true });
68
+ if (embedLink?.error instanceof URIError) {
69
+ setToast({
70
+ message: t("toast.unrecognizedLinkFormat"),
71
+ closable: true,
72
+ });
74
73
  }
75
74
  const ar = embedLink
76
75
  ? embedLink.intrinsicSize.w / embedLink.intrinsicSize.h
@@ -124,7 +123,7 @@ export const Hyperlink = ({ element, setAppState, onLinkOpen, setToast, updateEm
124
123
  if (timeoutId) {
125
124
  clearTimeout(timeoutId);
126
125
  }
127
- const shouldHide = shouldHideLinkPopup(element, appState, [
126
+ const shouldHide = shouldHideLinkPopup(element, elementsMap, appState, [
128
127
  event.clientX,
129
128
  event.clientY,
130
129
  ]);
@@ -141,7 +140,7 @@ export const Hyperlink = ({ element, setAppState, onLinkOpen, setToast, updateEm
141
140
  clearTimeout(timeoutId);
142
141
  }
143
142
  };
144
- }, [appState, element, isEditing, setAppState]);
143
+ }, [appState, element, isEditing, setAppState, elementsMap]);
145
144
  const handleRemove = useCallback(() => {
146
145
  trackEvent("hyperlink", "delete");
147
146
  mutateElement(element, { link: null });
@@ -154,7 +153,7 @@ export const Hyperlink = ({ element, setAppState, onLinkOpen, setToast, updateEm
154
153
  trackEvent("hyperlink", "edit", "popup-ui");
155
154
  setAppState({ showHyperlinkPopup: "editor" });
156
155
  };
157
- const { x, y } = getCoordsForPopover(element, appState);
156
+ const { x, y } = getCoordsForPopover(element, appState, elementsMap);
158
157
  if (appState.contextMenu ||
159
158
  appState.draggingElement ||
160
159
  appState.resizingElement ||
@@ -195,43 +194,13 @@ export const Hyperlink = ({ element, setAppState, onLinkOpen, setToast, updateEm
195
194
  }
196
195
  }, rel: "noopener noreferrer", children: element.link })) : (_jsx("div", { className: "excalidraw-hyperlinkContainer-link", children: t("labels.link.empty") })), _jsxs("div", { className: "excalidraw-hyperlinkContainer__buttons", children: [!isEditing && (_jsx(ToolButton, { type: "button", title: t("buttons.edit"), "aria-label": t("buttons.edit"), label: t("buttons.edit"), onClick: onEdit, className: "excalidraw-hyperlinkContainer--edit", icon: FreedrawIcon })), linkVal && !isEmbeddableElement(element) && (_jsx(ToolButton, { type: "button", title: t("buttons.remove"), "aria-label": t("buttons.remove"), label: t("buttons.remove"), onClick: handleRemove, className: "excalidraw-hyperlinkContainer--remove", icon: TrashIcon }))] })] }));
197
196
  };
198
- const getCoordsForPopover = (element, appState) => {
199
- const [x1, y1] = getElementAbsoluteCoords(element);
197
+ const getCoordsForPopover = (element, appState, elementsMap) => {
198
+ const [x1, y1] = getElementAbsoluteCoords(element, elementsMap);
200
199
  const { x: viewportX, y: viewportY } = sceneCoordsToViewportCoords({ sceneX: x1 + element.width / 2, sceneY: y1 }, appState);
201
200
  const x = viewportX - appState.offsetLeft - CONTAINER_WIDTH / 2;
202
201
  const y = viewportY - appState.offsetTop - SPACE_BOTTOM;
203
202
  return { x, y };
204
203
  };
205
- export const actionLink = register({
206
- name: "hyperlink",
207
- perform: (elements, appState) => {
208
- if (appState.showHyperlinkPopup === "editor") {
209
- return false;
210
- }
211
- return {
212
- elements,
213
- appState: {
214
- ...appState,
215
- showHyperlinkPopup: "editor",
216
- openMenu: null,
217
- },
218
- commitToHistory: true,
219
- };
220
- },
221
- trackEvent: { category: "hyperlink", action: "click" },
222
- keyTest: (event) => event[KEYS.CTRL_OR_CMD] && event.key === KEYS.K,
223
- contextItemLabel: (elements, appState) => getContextMenuLabel(elements, appState),
224
- predicate: (elements, appState) => {
225
- const selectedElements = getSelectedElements(elements, appState);
226
- return selectedElements.length === 1;
227
- },
228
- PanelComponent: ({ elements, appState, updateData }) => {
229
- const selectedElements = getSelectedElements(elements, appState);
230
- return (_jsx(ToolButton, { type: "button", icon: LinkIcon, "aria-label": t(getContextMenuLabel(elements, appState)), title: `${isEmbeddableElement(elements[0])
231
- ? t("labels.link.labelEmbed")
232
- : t("labels.link.label")} - ${getShortcutKey("CtrlOrCmd+K")}`, onClick: () => updateData(null), selected: selectedElements.length === 1 && !!selectedElements[0].link }));
233
- },
234
- });
235
204
  export const getContextMenuLabel = (elements, appState) => {
236
205
  const selectedElements = getSelectedElements(elements, appState);
237
206
  const label = selectedElements[0].link
@@ -243,56 +212,14 @@ export const getContextMenuLabel = (elements, appState) => {
243
212
  : "labels.link.create";
244
213
  return label;
245
214
  };
246
- export const getLinkHandleFromCoords = ([x1, y1, x2, y2], angle, appState) => {
247
- const size = DEFAULT_LINK_SIZE;
248
- const linkWidth = size / appState.zoom.value;
249
- const linkHeight = size / appState.zoom.value;
250
- const linkMarginY = size / appState.zoom.value;
251
- const centerX = (x1 + x2) / 2;
252
- const centerY = (y1 + y2) / 2;
253
- const centeringOffset = (size - 8) / (2 * appState.zoom.value);
254
- const dashedLineMargin = 4 / appState.zoom.value;
255
- // Same as `ne` resize handle
256
- const x = x2 + dashedLineMargin - centeringOffset;
257
- const y = y1 - dashedLineMargin - linkMarginY + centeringOffset;
258
- const [rotatedX, rotatedY] = rotate(x + linkWidth / 2, y + linkHeight / 2, centerX, centerY, angle);
259
- return [
260
- rotatedX - linkWidth / 2,
261
- rotatedY - linkHeight / 2,
262
- linkWidth,
263
- linkHeight,
264
- ];
265
- };
266
- export const isPointHittingLinkIcon = (element, appState, [x, y]) => {
267
- const threshold = 4 / appState.zoom.value;
268
- const [x1, y1, x2, y2] = getElementAbsoluteCoords(element);
269
- const [linkX, linkY, linkWidth, linkHeight] = getLinkHandleFromCoords([x1, y1, x2, y2], element.angle, appState);
270
- const hitLink = x > linkX - threshold &&
271
- x < linkX + threshold + linkWidth &&
272
- y > linkY - threshold &&
273
- y < linkY + linkHeight + threshold;
274
- return hitLink;
275
- };
276
- export const isPointHittingLink = (element, appState, [x, y], isMobile) => {
277
- if (!element.link || appState.selectedElementIds[element.id]) {
278
- return false;
279
- }
280
- const threshold = 4 / appState.zoom.value;
281
- if (!isMobile &&
282
- appState.viewModeEnabled &&
283
- isPointHittingElementBoundingBox(element, [x, y], threshold, null)) {
284
- return true;
285
- }
286
- return isPointHittingLinkIcon(element, appState, [x, y]);
287
- };
288
215
  let HYPERLINK_TOOLTIP_TIMEOUT_ID = null;
289
- export const showHyperlinkTooltip = (element, appState) => {
216
+ export const showHyperlinkTooltip = (element, appState, elementsMap) => {
290
217
  if (HYPERLINK_TOOLTIP_TIMEOUT_ID) {
291
218
  clearTimeout(HYPERLINK_TOOLTIP_TIMEOUT_ID);
292
219
  }
293
- HYPERLINK_TOOLTIP_TIMEOUT_ID = window.setTimeout(() => renderTooltip(element, appState), HYPERLINK_TOOLTIP_DELAY);
220
+ HYPERLINK_TOOLTIP_TIMEOUT_ID = window.setTimeout(() => renderTooltip(element, appState, elementsMap), HYPERLINK_TOOLTIP_DELAY);
294
221
  };
295
- const renderTooltip = (element, appState) => {
222
+ const renderTooltip = (element, appState, elementsMap) => {
296
223
  if (!element.link) {
297
224
  return;
298
225
  }
@@ -300,7 +227,7 @@ const renderTooltip = (element, appState) => {
300
227
  tooltipDiv.classList.add("excalidraw-tooltip--visible");
301
228
  tooltipDiv.style.maxWidth = "20rem";
302
229
  tooltipDiv.textContent = element.link;
303
- const [x1, y1, x2, y2] = getElementAbsoluteCoords(element);
230
+ const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);
304
231
  const [linkX, linkY, linkWidth, linkHeight] = getLinkHandleFromCoords([x1, y1, x2, y2], element.angle, appState);
305
232
  const linkViewportCoords = sceneCoordsToViewportCoords({ sceneX: linkX, sceneY: linkY }, appState);
306
233
  updateTooltipPosition(tooltipDiv, {
@@ -321,14 +248,14 @@ export const hideHyperlinkToolip = () => {
321
248
  getTooltipDiv().classList.remove("excalidraw-tooltip--visible");
322
249
  }
323
250
  };
324
- export const shouldHideLinkPopup = (element, appState, [clientX, clientY]) => {
251
+ const shouldHideLinkPopup = (element, elementsMap, appState, [clientX, clientY]) => {
325
252
  const { x: sceneX, y: sceneY } = viewportCoordsToSceneCoords({ clientX, clientY }, appState);
326
253
  const threshold = 15 / appState.zoom.value;
327
254
  // hitbox to prevent hiding when hovered in element bounding box
328
- if (isPointHittingElementBoundingBox(element, [sceneX, sceneY], threshold, null)) {
255
+ if (isPointHittingElementBoundingBox(element, elementsMap, [sceneX, sceneY], threshold, null)) {
329
256
  return false;
330
257
  }
331
- const [x1, y1, x2] = getElementAbsoluteCoords(element);
258
+ const [x1, y1, x2] = getElementAbsoluteCoords(element, elementsMap);
332
259
  // hit box to prevent hiding when hovered in the vertical area between element and popover
333
260
  if (sceneX >= x1 &&
334
261
  sceneX <= x2 &&
@@ -337,7 +264,7 @@ export const shouldHideLinkPopup = (element, appState, [clientX, clientY]) => {
337
264
  return false;
338
265
  }
339
266
  // hit box to prevent hiding when hovered around popover within threshold
340
- const { x: popoverX, y: popoverY } = getCoordsForPopover(element, appState);
267
+ const { x: popoverX, y: popoverY } = getCoordsForPopover(element, appState, elementsMap);
341
268
  if (clientX >= popoverX - threshold &&
342
269
  clientX <= popoverX + CONTAINER_WIDTH + CONTAINER_PADDING * 2 + threshold &&
343
270
  clientY >= popoverY - threshold &&
@@ -0,0 +1,7 @@
1
+ import { Bounds } from "../../element/bounds";
2
+ import { ElementsMap, NonDeletedExcalidrawElement } from "../../element/types";
3
+ import { AppState, UIAppState } from "../../types";
4
+ export declare const EXTERNAL_LINK_IMG: HTMLImageElement;
5
+ export declare const getLinkHandleFromCoords: ([x1, y1, x2, y2]: Bounds, angle: number, appState: Pick<UIAppState, "zoom">) => Bounds;
6
+ export declare const isPointHittingLinkIcon: (element: NonDeletedExcalidrawElement, elementsMap: ElementsMap, appState: AppState, [x, y]: readonly [number, number]) => boolean;
7
+ export declare const isPointHittingLink: (element: NonDeletedExcalidrawElement, elementsMap: ElementsMap, appState: AppState, [x, y]: readonly [number, number], isMobile: boolean) => boolean;
@@ -0,0 +1,49 @@
1
+ import { MIME_TYPES } from "../../constants";
2
+ import { getElementAbsoluteCoords } from "../../element/bounds";
3
+ import { isPointHittingElementBoundingBox } from "../../element/collision";
4
+ import { rotate } from "../../math";
5
+ import { DEFAULT_LINK_SIZE } from "../../renderer/renderElement";
6
+ export const EXTERNAL_LINK_IMG = document.createElement("img");
7
+ EXTERNAL_LINK_IMG.src = `data:${MIME_TYPES.svg}, ${encodeURIComponent(`<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#1971c2" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-external-link"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15 3 21 3 21 9"></polyline><line x1="10" y1="14" x2="21" y2="3"></line></svg>`)}`;
8
+ export const getLinkHandleFromCoords = ([x1, y1, x2, y2], angle, appState) => {
9
+ const size = DEFAULT_LINK_SIZE;
10
+ const linkWidth = size / appState.zoom.value;
11
+ const linkHeight = size / appState.zoom.value;
12
+ const linkMarginY = size / appState.zoom.value;
13
+ const centerX = (x1 + x2) / 2;
14
+ const centerY = (y1 + y2) / 2;
15
+ const centeringOffset = (size - 8) / (2 * appState.zoom.value);
16
+ const dashedLineMargin = 4 / appState.zoom.value;
17
+ // Same as `ne` resize handle
18
+ const x = x2 + dashedLineMargin - centeringOffset;
19
+ const y = y1 - dashedLineMargin - linkMarginY + centeringOffset;
20
+ const [rotatedX, rotatedY] = rotate(x + linkWidth / 2, y + linkHeight / 2, centerX, centerY, angle);
21
+ return [
22
+ rotatedX - linkWidth / 2,
23
+ rotatedY - linkHeight / 2,
24
+ linkWidth,
25
+ linkHeight,
26
+ ];
27
+ };
28
+ export const isPointHittingLinkIcon = (element, elementsMap, appState, [x, y]) => {
29
+ const threshold = 4 / appState.zoom.value;
30
+ const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);
31
+ const [linkX, linkY, linkWidth, linkHeight] = getLinkHandleFromCoords([x1, y1, x2, y2], element.angle, appState);
32
+ const hitLink = x > linkX - threshold &&
33
+ x < linkX + threshold + linkWidth &&
34
+ y > linkY - threshold &&
35
+ y < linkY + linkHeight + threshold;
36
+ return hitLink;
37
+ };
38
+ export const isPointHittingLink = (element, elementsMap, appState, [x, y], isMobile) => {
39
+ if (!element.link || appState.selectedElementIds[element.id]) {
40
+ return false;
41
+ }
42
+ const threshold = 4 / appState.zoom.value;
43
+ if (!isMobile &&
44
+ appState.viewModeEnabled &&
45
+ isPointHittingElementBoundingBox(element, elementsMap, [x, y], threshold, null)) {
46
+ return true;
47
+ }
48
+ return isPointHittingLinkIcon(element, elementsMap, appState, [x, y]);
49
+ };
@@ -60,6 +60,7 @@ export declare const UndoIcon: JSX.Element;
60
60
  export declare const RedoIcon: JSX.Element;
61
61
  export declare const questionCircle: JSX.Element;
62
62
  export declare const share: JSX.Element;
63
+ export declare const warning: JSX.Element;
63
64
  export declare const shareIOS: JSX.Element;
64
65
  export declare const shareWindows: JSX.Element;
65
66
  export declare const resetZoom: JSX.Element;
@@ -172,4 +173,6 @@ export declare const eyeIcon: JSX.Element;
172
173
  export declare const eyeClosedIcon: JSX.Element;
173
174
  export declare const brainIcon: JSX.Element;
174
175
  export declare const searchIcon: JSX.Element;
176
+ export declare const microphoneIcon: JSX.Element;
177
+ export declare const microphoneMutedIcon: JSX.Element;
175
178
  export {};