@excalidraw/excalidraw 0.17.1-d2f67e6 → 0.17.1-e63dd02

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 (252) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/browser/dev/excalidraw-assets-dev/CascadiaCode-Regular-TMZI7IJ5.woff2 +0 -0
  3. package/dist/browser/dev/excalidraw-assets-dev/ComicShanns-Regular-6TOETDFT.woff2 +0 -0
  4. package/dist/browser/dev/excalidraw-assets-dev/Excalifont-Regular-CPKEUDVM.woff2 +0 -0
  5. package/dist/browser/dev/excalidraw-assets-dev/LiberationSans-Regular-ZQD73GJM.woff2 +0 -0
  6. package/dist/browser/dev/excalidraw-assets-dev/Virgil-Regular-YHAB2VGJ.woff2 +0 -0
  7. package/dist/browser/dev/excalidraw-assets-dev/{chunk-EM6LVGFW.js → chunk-IT7T3AIK.js} +23 -5
  8. package/dist/browser/dev/excalidraw-assets-dev/chunk-IT7T3AIK.js.map +7 -0
  9. package/dist/browser/dev/excalidraw-assets-dev/{chunk-B4UMSLQQ.js → chunk-RNHSD5AR.js} +7451 -2098
  10. package/dist/browser/dev/excalidraw-assets-dev/chunk-RNHSD5AR.js.map +7 -0
  11. package/dist/browser/dev/excalidraw-assets-dev/{dist-6QVAH5JA.js → dist-DNSPZDOZ.js} +31 -19
  12. package/dist/browser/dev/excalidraw-assets-dev/dist-DNSPZDOZ.js.map +7 -0
  13. package/dist/browser/dev/excalidraw-assets-dev/{en-AZFA5HJJ.js → en-XV7OZCPP.js} +6 -2
  14. package/dist/browser/dev/excalidraw-assets-dev/{image-V7E6IT6R.js → image-77HZYGLG.js} +2 -2
  15. package/dist/browser/dev/excalidraw-assets-dev/{image-O66MQ7WQ.css → image-WDHYGKKP.css} +1 -1
  16. package/dist/browser/dev/excalidraw-assets-dev/{image-O66MQ7WQ.css.map → image-WDHYGKKP.css.map} +2 -2
  17. package/dist/browser/dev/index.css +449 -114
  18. package/dist/browser/dev/index.css.map +3 -3
  19. package/dist/browser/dev/index.js +4143 -5956
  20. package/dist/browser/dev/index.js.map +4 -4
  21. package/dist/browser/prod/excalidraw-assets/CascadiaCode-Regular-TMZI7IJ5.woff2 +0 -0
  22. package/dist/browser/prod/excalidraw-assets/ComicShanns-Regular-6TOETDFT.woff2 +0 -0
  23. package/dist/browser/prod/excalidraw-assets/Excalifont-Regular-CPKEUDVM.woff2 +0 -0
  24. package/dist/browser/prod/excalidraw-assets/LiberationSans-Regular-ZQD73GJM.woff2 +0 -0
  25. package/dist/browser/prod/excalidraw-assets/Virgil-Regular-YHAB2VGJ.woff2 +0 -0
  26. package/dist/browser/prod/excalidraw-assets/chunk-OYEADJSR.js +63 -0
  27. package/dist/browser/prod/excalidraw-assets/{chunk-7DXALCB2.js → chunk-PDYFZJMS.js} +3 -3
  28. package/dist/browser/prod/excalidraw-assets/dist-NLUQPPQQ.js +7 -0
  29. package/dist/browser/prod/excalidraw-assets/en-YVAVVILW.js +1 -0
  30. package/dist/browser/prod/excalidraw-assets/image-X3GFZHNN.js +1 -0
  31. package/dist/browser/prod/index.css +1 -1
  32. package/dist/browser/prod/index.js +40 -50
  33. package/dist/dev/CascadiaCode-Regular-TMZI7IJ5.woff2 +0 -0
  34. package/dist/dev/ComicShanns-Regular-6TOETDFT.woff2 +0 -0
  35. package/dist/dev/Excalifont-Regular-CPKEUDVM.woff2 +0 -0
  36. package/dist/dev/LiberationSans-Regular-ZQD73GJM.woff2 +0 -0
  37. package/dist/dev/Virgil-Regular-YHAB2VGJ.woff2 +0 -0
  38. package/dist/dev/{en-EB2MBPAV.json → en-YNVBSAIL.json} +18 -4
  39. package/dist/dev/index.css +449 -114
  40. package/dist/dev/index.css.map +3 -3
  41. package/dist/dev/index.js +21626 -18122
  42. package/dist/dev/index.js.map +4 -4
  43. package/dist/excalidraw/actions/actionAddToLibrary.d.ts +9 -3
  44. package/dist/excalidraw/actions/actionBoundText.d.ts +6 -2
  45. package/dist/excalidraw/actions/actionCanvas.d.ts +36 -12
  46. package/dist/excalidraw/actions/actionClipboard.d.ts +22 -7
  47. package/dist/excalidraw/actions/actionDeleteSelected.d.ts +12 -5
  48. package/dist/excalidraw/actions/actionDeleteSelected.js +24 -5
  49. package/dist/excalidraw/actions/actionDuplicateSelection.js +1 -2
  50. package/dist/excalidraw/actions/actionElementLock.d.ts +6 -2
  51. package/dist/excalidraw/actions/actionExport.d.ts +27 -9
  52. package/dist/excalidraw/actions/actionFinalize.d.ts +6 -2
  53. package/dist/excalidraw/actions/actionFinalize.js +2 -2
  54. package/dist/excalidraw/actions/actionFlip.js +2 -2
  55. package/dist/excalidraw/actions/actionFrame.d.ts +12 -4
  56. package/dist/excalidraw/actions/actionGroup.d.ts +6 -2
  57. package/dist/excalidraw/actions/actionHistory.js +4 -4
  58. package/dist/excalidraw/actions/actionLinearEditor.d.ts +3 -1
  59. package/dist/excalidraw/actions/actionLinearEditor.js +3 -2
  60. package/dist/excalidraw/actions/actionLink.d.ts +3 -1
  61. package/dist/excalidraw/actions/actionMenu.d.ts +9 -3
  62. package/dist/excalidraw/actions/actionNavigate.d.ts +6 -2
  63. package/dist/excalidraw/actions/actionProperties.d.ts +411 -56
  64. package/dist/excalidraw/actions/actionProperties.js +383 -58
  65. package/dist/excalidraw/actions/actionSelectAll.d.ts +3 -1
  66. package/dist/excalidraw/actions/actionStyles.d.ts +3 -1
  67. package/dist/excalidraw/actions/actionStyles.js +3 -2
  68. package/dist/excalidraw/actions/actionToggleGridMode.d.ts +3 -1
  69. package/dist/excalidraw/actions/actionToggleObjectsSnapMode.d.ts +3 -1
  70. package/dist/excalidraw/actions/actionToggleStats.d.ts +3 -1
  71. package/dist/excalidraw/actions/actionToggleViewMode.d.ts +3 -1
  72. package/dist/excalidraw/actions/actionToggleZenMode.d.ts +3 -1
  73. package/dist/excalidraw/actions/types.d.ts +1 -1
  74. package/dist/excalidraw/analytics.js +9 -7
  75. package/dist/excalidraw/appState.d.ts +1 -0
  76. package/dist/excalidraw/appState.js +9 -1
  77. package/dist/excalidraw/binaryheap.d.ts +12 -0
  78. package/dist/excalidraw/binaryheap.js +93 -0
  79. package/dist/excalidraw/change.d.ts +2 -1
  80. package/dist/excalidraw/change.js +6 -4
  81. package/dist/excalidraw/charts.js +0 -10
  82. package/dist/excalidraw/components/Actions.js +7 -5
  83. package/dist/excalidraw/components/App.d.ts +5 -9
  84. package/dist/excalidraw/components/App.js +218 -161
  85. package/dist/excalidraw/components/ButtonIcon.d.ts +15 -0
  86. package/dist/excalidraw/components/ButtonIcon.js +8 -0
  87. package/dist/excalidraw/components/ButtonIconSelect.js +2 -3
  88. package/dist/excalidraw/components/ButtonSeparator.d.ts +2 -0
  89. package/dist/excalidraw/components/ButtonSeparator.js +7 -0
  90. package/dist/excalidraw/components/ColorPicker/ColorPicker.js +47 -79
  91. package/dist/excalidraw/components/ColorPicker/Picker.js +1 -1
  92. package/dist/excalidraw/components/FontPicker/FontPicker.d.ts +21 -0
  93. package/dist/excalidraw/components/FontPicker/FontPicker.js +49 -0
  94. package/dist/excalidraw/components/FontPicker/FontPickerList.d.ts +25 -0
  95. package/dist/excalidraw/components/FontPicker/FontPickerList.js +119 -0
  96. package/dist/excalidraw/components/FontPicker/FontPickerTrigger.d.ts +7 -0
  97. package/dist/excalidraw/components/FontPicker/FontPickerTrigger.js +13 -0
  98. package/dist/excalidraw/components/FontPicker/keyboardNavHandlers.d.ts +14 -0
  99. package/dist/excalidraw/components/FontPicker/keyboardNavHandlers.js +38 -0
  100. package/dist/excalidraw/components/HelpDialog.js +1 -1
  101. package/dist/excalidraw/components/HintViewer.js +6 -3
  102. package/dist/excalidraw/components/PropertiesPopover.d.ts +15 -0
  103. package/dist/excalidraw/components/PropertiesPopover.js +31 -0
  104. package/dist/excalidraw/components/QuickSearch.d.ts +9 -0
  105. package/dist/excalidraw/components/QuickSearch.js +8 -0
  106. package/dist/excalidraw/components/ScrollableList.d.ts +9 -0
  107. package/dist/excalidraw/components/ScrollableList.js +8 -0
  108. package/dist/excalidraw/components/Stats/Angle.d.ts +7 -3
  109. package/dist/excalidraw/components/Stats/Angle.js +39 -31
  110. package/dist/excalidraw/components/Stats/Dimension.d.ts +6 -3
  111. package/dist/excalidraw/components/Stats/Dimension.js +51 -49
  112. package/dist/excalidraw/components/Stats/DragInput.d.ts +15 -6
  113. package/dist/excalidraw/components/Stats/DragInput.js +59 -26
  114. package/dist/excalidraw/components/Stats/FontSize.d.ts +8 -4
  115. package/dist/excalidraw/components/Stats/FontSize.js +39 -36
  116. package/dist/excalidraw/components/Stats/MultiAngle.d.ts +5 -3
  117. package/dist/excalidraw/components/Stats/MultiAngle.js +43 -34
  118. package/dist/excalidraw/components/Stats/MultiDimension.d.ts +5 -3
  119. package/dist/excalidraw/components/Stats/MultiDimension.js +101 -99
  120. package/dist/excalidraw/components/Stats/MultiFontSize.d.ts +6 -3
  121. package/dist/excalidraw/components/Stats/MultiFontSize.js +47 -32
  122. package/dist/excalidraw/components/Stats/MultiPosition.d.ts +3 -1
  123. package/dist/excalidraw/components/Stats/MultiPosition.js +52 -48
  124. package/dist/excalidraw/components/Stats/Position.d.ts +5 -1
  125. package/dist/excalidraw/components/Stats/Position.js +31 -29
  126. package/dist/excalidraw/components/Stats/index.js +5 -17
  127. package/dist/excalidraw/components/Stats/utils.d.ts +14 -3
  128. package/dist/excalidraw/components/Stats/utils.js +48 -9
  129. package/dist/excalidraw/components/TTDDialog/common.d.ts +2 -2
  130. package/dist/excalidraw/components/TTDDialog/common.js +3 -7
  131. package/dist/excalidraw/components/UserList.js +22 -22
  132. package/dist/excalidraw/components/canvases/StaticCanvas.js +1 -0
  133. package/dist/excalidraw/components/dropdownMenu/DropdownMenu.d.ts +12 -3
  134. package/dist/excalidraw/components/dropdownMenu/DropdownMenuItem.d.ts +24 -4
  135. package/dist/excalidraw/components/dropdownMenu/DropdownMenuItem.js +55 -14
  136. package/dist/excalidraw/components/dropdownMenu/DropdownMenuItemContent.d.ts +2 -1
  137. package/dist/excalidraw/components/dropdownMenu/DropdownMenuItemContent.js +2 -2
  138. package/dist/excalidraw/components/dropdownMenu/common.d.ts +1 -1
  139. package/dist/excalidraw/components/dropdownMenu/common.js +3 -2
  140. package/dist/excalidraw/components/icons.d.ts +4 -0
  141. package/dist/excalidraw/components/icons.js +7 -0
  142. package/dist/excalidraw/components/main-menu/MainMenu.d.ts +12 -3
  143. package/dist/excalidraw/components/welcome-screen/WelcomeScreen.Center.js +2 -2
  144. package/dist/excalidraw/components/welcome-screen/WelcomeScreen.Hints.js +3 -3
  145. package/dist/excalidraw/constants.d.ts +17 -2
  146. package/dist/excalidraw/constants.js +21 -4
  147. package/dist/excalidraw/data/reconcile.js +18 -1
  148. package/dist/excalidraw/data/restore.js +55 -9
  149. package/dist/excalidraw/data/transform.js +8 -5
  150. package/dist/excalidraw/element/binding.d.ts +28 -9
  151. package/dist/excalidraw/element/binding.js +303 -71
  152. package/dist/excalidraw/element/collision.d.ts +1 -1
  153. package/dist/excalidraw/element/collision.js +4 -1
  154. package/dist/excalidraw/element/dragElements.d.ts +2 -2
  155. package/dist/excalidraw/element/dragElements.js +13 -3
  156. package/dist/excalidraw/element/embeddable.d.ts +3 -1
  157. package/dist/excalidraw/element/heading.d.ts +11 -0
  158. package/dist/excalidraw/element/heading.js +81 -0
  159. package/dist/excalidraw/element/index.d.ts +1 -1
  160. package/dist/excalidraw/element/index.js +1 -1
  161. package/dist/excalidraw/element/linearElementEditor.d.ts +21 -13
  162. package/dist/excalidraw/element/linearElementEditor.js +133 -56
  163. package/dist/excalidraw/element/newElement.d.ts +8 -3
  164. package/dist/excalidraw/element/newElement.js +15 -2
  165. package/dist/excalidraw/element/resizeElements.d.ts +4 -3
  166. package/dist/excalidraw/element/resizeElements.js +47 -23
  167. package/dist/excalidraw/element/routing.d.ts +13 -0
  168. package/dist/excalidraw/element/routing.js +641 -0
  169. package/dist/excalidraw/element/textElement.d.ts +3 -26
  170. package/dist/excalidraw/element/textElement.js +54 -110
  171. package/dist/excalidraw/element/textWysiwyg.js +39 -47
  172. package/dist/excalidraw/element/transformHandles.js +7 -2
  173. package/dist/excalidraw/element/typeChecks.d.ts +5 -2
  174. package/dist/excalidraw/element/typeChecks.js +17 -0
  175. package/dist/excalidraw/element/types.d.ts +12 -1
  176. package/dist/excalidraw/fonts/ExcalidrawFont.d.ts +21 -0
  177. package/dist/excalidraw/fonts/ExcalidrawFont.js +112 -0
  178. package/dist/excalidraw/fonts/index.d.ts +58 -0
  179. package/dist/excalidraw/fonts/index.js +240 -0
  180. package/dist/excalidraw/fonts/metadata.d.ts +36 -0
  181. package/dist/excalidraw/fonts/metadata.js +91 -0
  182. package/dist/excalidraw/fractionalIndex.d.ts +11 -4
  183. package/dist/excalidraw/fractionalIndex.js +38 -6
  184. package/dist/excalidraw/frame.d.ts +1 -1
  185. package/dist/excalidraw/frame.js +3 -3
  186. package/dist/excalidraw/history.d.ts +4 -3
  187. package/dist/excalidraw/history.js +8 -8
  188. package/dist/excalidraw/index.d.ts +1 -1
  189. package/dist/excalidraw/index.js +3 -3
  190. package/dist/excalidraw/locales/en.json +18 -4
  191. package/dist/excalidraw/math.d.ts +43 -0
  192. package/dist/excalidraw/math.js +110 -0
  193. package/dist/excalidraw/mermaid.js +4 -3
  194. package/dist/excalidraw/renderer/interactiveScene.js +33 -17
  195. package/dist/excalidraw/renderer/renderElement.d.ts +2 -0
  196. package/dist/excalidraw/renderer/renderElement.js +74 -54
  197. package/dist/excalidraw/renderer/staticSvgScene.js +2 -1
  198. package/dist/excalidraw/scene/Scene.js +9 -3
  199. package/dist/excalidraw/scene/Shape.js +56 -5
  200. package/dist/excalidraw/scene/comparisons.d.ts +1 -0
  201. package/dist/excalidraw/scene/comparisons.js +1 -1
  202. package/dist/excalidraw/scene/export.d.ts +2 -1
  203. package/dist/excalidraw/scene/export.js +33 -35
  204. package/dist/excalidraw/scene/types.d.ts +1 -4
  205. package/dist/excalidraw/shapes.d.ts +8 -0
  206. package/dist/excalidraw/shapes.js +57 -0
  207. package/dist/excalidraw/types.d.ts +8 -3
  208. package/dist/excalidraw/utils.d.ts +11 -1
  209. package/dist/excalidraw/utils.js +22 -0
  210. package/dist/prod/CascadiaCode-Regular-TMZI7IJ5.woff2 +0 -0
  211. package/dist/prod/ComicShanns-Regular-6TOETDFT.woff2 +0 -0
  212. package/dist/prod/Excalifont-Regular-CPKEUDVM.woff2 +0 -0
  213. package/dist/prod/LiberationSans-Regular-ZQD73GJM.woff2 +0 -0
  214. package/dist/prod/Virgil-Regular-YHAB2VGJ.woff2 +0 -0
  215. package/dist/prod/{en-EB2MBPAV.json → en-YNVBSAIL.json} +18 -4
  216. package/dist/prod/index.css +1 -1
  217. package/dist/prod/index.js +49 -53
  218. package/dist/utils/export.d.ts +2 -1
  219. package/dist/utils/export.js +2 -1
  220. package/dist/utils/geometry/geometry.d.ts +2 -1
  221. package/dist/utils/geometry/geometry.js +5 -1
  222. package/dist/utils/index.d.ts +1 -0
  223. package/dist/utils/index.js +1 -0
  224. package/history.ts +9 -2
  225. package/package.json +2 -2
  226. package/dist/browser/dev/Cascadia-CYPE3OJC.woff2 +0 -0
  227. package/dist/browser/dev/Virgil-UZN6MUT6.woff2 +0 -0
  228. package/dist/browser/dev/excalidraw-assets-dev/chunk-B4UMSLQQ.js.map +0 -7
  229. package/dist/browser/dev/excalidraw-assets-dev/chunk-EM6LVGFW.js.map +0 -7
  230. package/dist/browser/dev/excalidraw-assets-dev/dist-6QVAH5JA.js.map +0 -7
  231. package/dist/browser/prod/Cascadia-CYPE3OJC.woff2 +0 -0
  232. package/dist/browser/prod/Virgil-UZN6MUT6.woff2 +0 -0
  233. package/dist/browser/prod/excalidraw-assets/chunk-EGOLGOLD.js +0 -55
  234. package/dist/browser/prod/excalidraw-assets/dist-567JAXHK.js +0 -7
  235. package/dist/browser/prod/excalidraw-assets/en-6E7MYLWO.js +0 -1
  236. package/dist/browser/prod/excalidraw-assets/image-SI7BKULC.js +0 -1
  237. package/dist/dev/Cascadia-CYPE3OJC.woff2 +0 -0
  238. package/dist/dev/Virgil-UZN6MUT6.woff2 +0 -0
  239. package/dist/excalidraw/scene/Fonts.d.ts +0 -19
  240. package/dist/excalidraw/scene/Fonts.js +0 -66
  241. package/dist/prod/Cascadia-CYPE3OJC.woff2 +0 -0
  242. package/dist/prod/Virgil-UZN6MUT6.woff2 +0 -0
  243. /package/dist/browser/dev/{Assistant-Bold-ZDZZ6JHA.woff2 → excalidraw-assets-dev/Assistant-Bold-ZDZZ6JHA.woff2} +0 -0
  244. /package/dist/browser/dev/{Assistant-Medium-DZ25RZU3.woff2 → excalidraw-assets-dev/Assistant-Medium-DZ25RZU3.woff2} +0 -0
  245. /package/dist/browser/dev/{Assistant-Regular-PLF2XOGW.woff2 → excalidraw-assets-dev/Assistant-Regular-PLF2XOGW.woff2} +0 -0
  246. /package/dist/browser/dev/{Assistant-SemiBold-CZ5MX6FK.woff2 → excalidraw-assets-dev/Assistant-SemiBold-CZ5MX6FK.woff2} +0 -0
  247. /package/dist/browser/dev/excalidraw-assets-dev/{en-AZFA5HJJ.js.map → en-XV7OZCPP.js.map} +0 -0
  248. /package/dist/browser/dev/excalidraw-assets-dev/{image-V7E6IT6R.js.map → image-77HZYGLG.js.map} +0 -0
  249. /package/dist/browser/prod/{Assistant-Bold-ZDZZ6JHA.woff2 → excalidraw-assets/Assistant-Bold-ZDZZ6JHA.woff2} +0 -0
  250. /package/dist/browser/prod/{Assistant-Medium-DZ25RZU3.woff2 → excalidraw-assets/Assistant-Medium-DZ25RZU3.woff2} +0 -0
  251. /package/dist/browser/prod/{Assistant-Regular-PLF2XOGW.woff2 → excalidraw-assets/Assistant-Regular-PLF2XOGW.woff2} +0 -0
  252. /package/dist/browser/prod/{Assistant-SemiBold-CZ5MX6FK.woff2 → excalidraw-assets/Assistant-SemiBold-CZ5MX6FK.woff2} +0 -0
@@ -1,26 +1,32 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useMemo, useRef, useState } from "react";
2
3
  import { DEFAULT_ELEMENT_BACKGROUND_COLOR_PALETTE, DEFAULT_ELEMENT_BACKGROUND_PICKS, DEFAULT_ELEMENT_STROKE_COLOR_PALETTE, DEFAULT_ELEMENT_STROKE_PICKS, } from "../colors";
3
4
  import { trackEvent } from "../analytics";
4
5
  import { ButtonIconSelect } from "../components/ButtonIconSelect";
5
6
  import { ColorPicker } from "../components/ColorPicker/ColorPicker";
6
7
  import { IconPicker } from "../components/IconPicker";
8
+ import { FontPicker } from "../components/FontPicker/FontPicker";
7
9
  // TODO barnabasmolnar/editor-redesign
8
10
  // TextAlignTopIcon, TextAlignBottomIcon,TextAlignMiddleIcon,
9
11
  // ArrowHead icons
10
- import { ArrowheadArrowIcon, ArrowheadBarIcon, ArrowheadCircleIcon, ArrowheadTriangleIcon, ArrowheadNoneIcon, StrokeStyleDashedIcon, StrokeStyleDottedIcon, TextAlignTopIcon, TextAlignBottomIcon, TextAlignMiddleIcon, FillHachureIcon, FillCrossHatchIcon, FillSolidIcon, SloppinessArchitectIcon, SloppinessArtistIcon, SloppinessCartoonistIcon, StrokeWidthBaseIcon, StrokeWidthBoldIcon, StrokeWidthExtraBoldIcon, FontSizeSmallIcon, FontSizeMediumIcon, FontSizeLargeIcon, FontSizeExtraLargeIcon, EdgeSharpIcon, EdgeRoundIcon, FreedrawIcon, FontFamilyNormalIcon, FontFamilyCodeIcon, TextAlignLeftIcon, TextAlignCenterIcon, TextAlignRightIcon, FillZigZagIcon, ArrowheadTriangleOutlineIcon, ArrowheadCircleOutlineIcon, ArrowheadDiamondIcon, ArrowheadDiamondOutlineIcon, fontSizeIcon, } from "../components/icons";
11
- import { DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE, FONT_FAMILY, ROUNDNESS, STROKE_WIDTH, VERTICAL_ALIGN, } from "../constants";
12
+ import { ArrowheadArrowIcon, ArrowheadBarIcon, ArrowheadCircleIcon, ArrowheadTriangleIcon, ArrowheadNoneIcon, StrokeStyleDashedIcon, StrokeStyleDottedIcon, TextAlignTopIcon, TextAlignBottomIcon, TextAlignMiddleIcon, FillHachureIcon, FillCrossHatchIcon, FillSolidIcon, SloppinessArchitectIcon, SloppinessArtistIcon, SloppinessCartoonistIcon, StrokeWidthBaseIcon, StrokeWidthBoldIcon, StrokeWidthExtraBoldIcon, FontSizeSmallIcon, FontSizeMediumIcon, FontSizeLargeIcon, FontSizeExtraLargeIcon, EdgeSharpIcon, EdgeRoundIcon, TextAlignLeftIcon, TextAlignCenterIcon, TextAlignRightIcon, FillZigZagIcon, ArrowheadTriangleOutlineIcon, ArrowheadCircleOutlineIcon, ArrowheadDiamondIcon, ArrowheadDiamondOutlineIcon, fontSizeIcon, sharpArrowIcon, roundArrowIcon, elbowArrowIcon, } from "../components/icons";
13
+ import { ARROW_TYPE, DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE, FONT_FAMILY, ROUNDNESS, STROKE_WIDTH, VERTICAL_ALIGN, } from "../constants";
12
14
  import { getNonDeletedElements, isTextElement, redrawTextBoundingBox, } from "../element";
13
15
  import { mutateElement, newElementWith } from "../element/mutateElement";
14
- import { getBoundTextElement, getDefaultLineHeight, } from "../element/textElement";
15
- import { isBoundToContainer, isLinearElement, isUsingAdaptiveRadius, } from "../element/typeChecks";
16
+ import { getBoundTextElement } from "../element/textElement";
17
+ import { isArrowElement, isBoundToContainer, isElbowArrow, isLinearElement, isUsingAdaptiveRadius, } from "../element/typeChecks";
16
18
  import { getLanguage, t } from "../i18n";
17
19
  import { KEYS } from "../keys";
18
20
  import { randomInteger } from "../random";
19
21
  import { canHaveArrowheads, getCommonAttributeOfSelectedElements, getSelectedElements, getTargetElements, isSomeElementSelected, } from "../scene";
20
22
  import { hasStrokeColor } from "../scene/comparisons";
21
- import { arrayToMap, getShortcutKey } from "../utils";
23
+ import { arrayToMap, getFontFamilyString, getShortcutKey, tupleToCoors, } from "../utils";
22
24
  import { register } from "./register";
23
25
  import { StoreAction } from "../store";
26
+ import { Fonts, getLineHeight } from "../fonts";
27
+ import { bindLinearElement, bindPointToSnapToElementOutline, calculateFixedPointForElbowArrowBinding, getHoveredElementForBinding, } from "../element/binding";
28
+ import { mutateElbowArrow } from "../element/routing";
29
+ import { LinearElementEditor } from "../element/linearElementEditor";
24
30
  const FONT_SIZE_RELATIVE_INCREASE_STEP = 0.1;
25
31
  export const changeProperty = (elements, appState, callback, includeBoundText = false) => {
26
32
  const selectedElementIds = arrayToMap(getSelectedElements(elements, appState, {
@@ -394,59 +400,253 @@ export const actionChangeFontFamily = register({
394
400
  label: "labels.fontFamily",
395
401
  trackEvent: false,
396
402
  perform: (elements, appState, value, app) => {
397
- return {
398
- elements: changeProperty(elements, appState, (oldElement) => {
399
- if (isTextElement(oldElement)) {
400
- const newElement = newElementWith(oldElement, {
401
- fontFamily: value,
402
- lineHeight: getDefaultLineHeight(value),
403
+ const { cachedElements, resetAll, resetContainers, ...nextAppState } = value;
404
+ if (resetAll) {
405
+ const nextElements = changeProperty(elements, appState, (element) => {
406
+ const cachedElement = cachedElements?.get(element.id);
407
+ if (cachedElement) {
408
+ const newElement = newElementWith(element, {
409
+ ...cachedElement,
403
410
  });
404
- redrawTextBoundingBox(newElement, app.scene.getContainerElement(oldElement), app.scene.getNonDeletedElementsMap());
405
411
  return newElement;
406
412
  }
407
- return oldElement;
408
- }, true),
413
+ return element;
414
+ }, true);
415
+ return {
416
+ elements: nextElements,
417
+ appState: {
418
+ ...appState,
419
+ ...nextAppState,
420
+ },
421
+ storeAction: StoreAction.UPDATE,
422
+ };
423
+ }
424
+ const { currentItemFontFamily, currentHoveredFontFamily } = value;
425
+ let nexStoreAction = StoreAction.NONE;
426
+ let nextFontFamily;
427
+ let skipOnHoverRender = false;
428
+ if (currentItemFontFamily) {
429
+ nextFontFamily = currentItemFontFamily;
430
+ nexStoreAction = StoreAction.CAPTURE;
431
+ }
432
+ else if (currentHoveredFontFamily) {
433
+ nextFontFamily = currentHoveredFontFamily;
434
+ nexStoreAction = StoreAction.NONE;
435
+ const selectedTextElements = getSelectedElements(elements, appState, {
436
+ includeBoundTextElement: true,
437
+ }).filter((element) => isTextElement(element));
438
+ // skip on hover re-render for more than 200 text elements or for text element with more than 5000 chars combined
439
+ if (selectedTextElements.length > 200) {
440
+ skipOnHoverRender = true;
441
+ }
442
+ else {
443
+ let i = 0;
444
+ let textLengthAccumulator = 0;
445
+ while (i < selectedTextElements.length &&
446
+ textLengthAccumulator < 5000) {
447
+ const textElement = selectedTextElements[i];
448
+ textLengthAccumulator += textElement?.originalText.length || 0;
449
+ i++;
450
+ }
451
+ if (textLengthAccumulator > 5000) {
452
+ skipOnHoverRender = true;
453
+ }
454
+ }
455
+ }
456
+ const result = {
409
457
  appState: {
410
458
  ...appState,
411
- currentItemFontFamily: value,
459
+ ...nextAppState,
412
460
  },
413
- storeAction: StoreAction.CAPTURE,
461
+ storeAction: nexStoreAction,
414
462
  };
463
+ if (nextFontFamily && !skipOnHoverRender) {
464
+ const elementContainerMapping = new Map();
465
+ let uniqueGlyphs = new Set();
466
+ let skipFontFaceCheck = false;
467
+ const fontsCache = Array.from(Fonts.loadedFontsCache.values());
468
+ const fontFamily = Object.entries(FONT_FAMILY).find(([_, value]) => value === nextFontFamily)?.[0];
469
+ // skip `document.font.check` check on hover, if at least one font family has loaded as it's super slow (could result in slightly different bbox, which is fine)
470
+ if (currentHoveredFontFamily &&
471
+ fontFamily &&
472
+ fontsCache.some((sig) => sig.startsWith(fontFamily))) {
473
+ skipFontFaceCheck = true;
474
+ }
475
+ // following causes re-render so make sure we changed the family
476
+ // otherwise it could cause unexpected issues, such as preventing opening the popover when in wysiwyg
477
+ Object.assign(result, {
478
+ elements: changeProperty(elements, appState, (oldElement) => {
479
+ if (isTextElement(oldElement) &&
480
+ (oldElement.fontFamily !== nextFontFamily ||
481
+ currentItemFontFamily) // force update on selection
482
+ ) {
483
+ const newElement = newElementWith(oldElement, {
484
+ fontFamily: nextFontFamily,
485
+ lineHeight: getLineHeight(nextFontFamily),
486
+ });
487
+ const cachedContainer = cachedElements?.get(oldElement.containerId || "") || {};
488
+ const container = app.scene.getContainerElement(oldElement);
489
+ if (resetContainers && container && cachedContainer) {
490
+ // reset the container back to it's cached version
491
+ mutateElement(container, { ...cachedContainer }, false);
492
+ }
493
+ if (!skipFontFaceCheck) {
494
+ uniqueGlyphs = new Set([
495
+ ...uniqueGlyphs,
496
+ ...Array.from(newElement.originalText),
497
+ ]);
498
+ }
499
+ elementContainerMapping.set(newElement, container);
500
+ return newElement;
501
+ }
502
+ return oldElement;
503
+ }, true),
504
+ });
505
+ // size is irrelevant, but necessary
506
+ const fontString = `10px ${getFontFamilyString({
507
+ fontFamily: nextFontFamily,
508
+ })}`;
509
+ const glyphs = Array.from(uniqueGlyphs.values()).join();
510
+ if (skipFontFaceCheck ||
511
+ window.document.fonts.check(fontString, glyphs)) {
512
+ // we either skip the check (have at least one font face loaded) or do the check and find out all the font faces have loaded
513
+ for (const [element, container] of elementContainerMapping) {
514
+ // trigger synchronous redraw
515
+ redrawTextBoundingBox(element, container, app.scene.getNonDeletedElementsMap(), false);
516
+ }
517
+ }
518
+ else {
519
+ // otherwise try to load all font faces for the given glyphs and redraw elements once our font faces loaded
520
+ window.document.fonts.load(fontString, glyphs).then((fontFaces) => {
521
+ for (const [element, container] of elementContainerMapping) {
522
+ // use latest element state to ensure we don't have closure over an old instance in order to avoid possible race conditions (i.e. font faces load out-of-order while rapidly switching fonts)
523
+ const latestElement = app.scene.getElement(element.id);
524
+ const latestContainer = container
525
+ ? app.scene.getElement(container.id)
526
+ : null;
527
+ if (latestElement) {
528
+ // trigger async redraw
529
+ redrawTextBoundingBox(latestElement, latestContainer, app.scene.getNonDeletedElementsMap(), false);
530
+ }
531
+ }
532
+ // trigger update once we've mutated all the elements, which also updates our cache
533
+ app.fonts.onLoaded(fontFaces);
534
+ });
535
+ }
536
+ }
537
+ return result;
415
538
  },
416
- PanelComponent: ({ elements, appState, updateData, app }) => {
417
- const options = [
418
- {
419
- value: FONT_FAMILY.Virgil,
420
- text: t("labels.handDrawn"),
421
- icon: FreedrawIcon,
422
- testId: "font-family-virgil",
423
- },
424
- {
425
- value: FONT_FAMILY.Helvetica,
426
- text: t("labels.normal"),
427
- icon: FontFamilyNormalIcon,
428
- testId: "font-family-normal",
429
- },
430
- {
431
- value: FONT_FAMILY.Cascadia,
432
- text: t("labels.code"),
433
- icon: FontFamilyCodeIcon,
434
- testId: "font-family-code",
435
- },
436
- ];
437
- return (_jsxs("fieldset", { children: [_jsx("legend", { children: t("labels.fontFamily") }), _jsx(ButtonIconSelect, { group: "font-family", options: options, value: getFormValue(elements, appState, (element) => {
438
- if (isTextElement(element)) {
439
- return element.fontFamily;
539
+ PanelComponent: ({ elements, appState, app, updateData }) => {
540
+ const cachedElementsRef = useRef(new Map());
541
+ const prevSelectedFontFamilyRef = useRef(null);
542
+ // relying on state batching as multiple `FontPicker` handlers could be called in rapid succession and we want to combine them
543
+ const [batchedData, setBatchedData] = useState({});
544
+ const isUnmounted = useRef(true);
545
+ const selectedFontFamily = useMemo(() => {
546
+ const getFontFamily = (elementsArray, elementsMap) => getFormValue(elementsArray, appState, (element) => {
547
+ if (isTextElement(element)) {
548
+ return element.fontFamily;
549
+ }
550
+ const boundTextElement = getBoundTextElement(element, elementsMap);
551
+ if (boundTextElement) {
552
+ return boundTextElement.fontFamily;
553
+ }
554
+ return null;
555
+ }, (element) => isTextElement(element) ||
556
+ getBoundTextElement(element, elementsMap) !== null, (hasSelection) => hasSelection
557
+ ? null
558
+ : appState.currentItemFontFamily || DEFAULT_FONT_FAMILY);
559
+ // popup opened, use cached elements
560
+ if (batchedData.openPopup === "fontFamily" &&
561
+ appState.openPopup === "fontFamily") {
562
+ return getFontFamily(Array.from(cachedElementsRef.current?.values() ?? []), cachedElementsRef.current);
563
+ }
564
+ // popup closed, use all elements
565
+ if (!batchedData.openPopup && appState.openPopup !== "fontFamily") {
566
+ return getFontFamily(elements, app.scene.getNonDeletedElementsMap());
567
+ }
568
+ // popup props are not in sync, hence we are in the middle of an update, so keeping the previous value we've had
569
+ return prevSelectedFontFamilyRef.current;
570
+ }, [batchedData.openPopup, appState, elements, app.scene]);
571
+ useEffect(() => {
572
+ prevSelectedFontFamilyRef.current = selectedFontFamily;
573
+ }, [selectedFontFamily]);
574
+ useEffect(() => {
575
+ if (Object.keys(batchedData).length) {
576
+ updateData(batchedData);
577
+ // reset the data after we've used the data
578
+ setBatchedData({});
579
+ }
580
+ // call update only on internal state changes
581
+ // eslint-disable-next-line react-hooks/exhaustive-deps
582
+ }, [batchedData]);
583
+ useEffect(() => {
584
+ isUnmounted.current = false;
585
+ return () => {
586
+ isUnmounted.current = true;
587
+ };
588
+ }, []);
589
+ return (_jsxs("fieldset", { children: [_jsx("legend", { children: t("labels.fontFamily") }), _jsx(FontPicker, { isOpened: appState.openPopup === "fontFamily", selectedFontFamily: selectedFontFamily, hoveredFontFamily: appState.currentHoveredFontFamily, onSelect: (fontFamily) => {
590
+ setBatchedData({
591
+ openPopup: null,
592
+ currentHoveredFontFamily: null,
593
+ currentItemFontFamily: fontFamily,
594
+ });
595
+ // defensive clear so immediate close won't abuse the cached elements
596
+ cachedElementsRef.current.clear();
597
+ }, onHover: (fontFamily) => {
598
+ setBatchedData({
599
+ currentHoveredFontFamily: fontFamily,
600
+ cachedElements: new Map(cachedElementsRef.current),
601
+ resetContainers: true,
602
+ });
603
+ }, onLeave: () => {
604
+ setBatchedData({
605
+ currentHoveredFontFamily: null,
606
+ cachedElements: new Map(cachedElementsRef.current),
607
+ resetAll: true,
608
+ });
609
+ }, onPopupChange: (open) => {
610
+ if (open) {
611
+ // open, populate the cache from scratch
612
+ cachedElementsRef.current.clear();
613
+ const { editingElement } = appState;
614
+ if (editingElement?.type === "text") {
615
+ // retrieve the latest version from the scene, as `editingElement` isn't mutated
616
+ const latestEditingElement = app.scene.getElement(editingElement.id);
617
+ // inside the wysiwyg editor
618
+ cachedElementsRef.current.set(editingElement.id, newElementWith(latestEditingElement || editingElement, {}, true));
619
+ }
620
+ else {
621
+ const selectedElements = getSelectedElements(elements, appState, {
622
+ includeBoundTextElement: true,
623
+ });
624
+ for (const element of selectedElements) {
625
+ cachedElementsRef.current.set(element.id, newElementWith(element, {}, true));
626
+ }
627
+ }
628
+ setBatchedData({
629
+ openPopup: "fontFamily",
630
+ });
440
631
  }
441
- const boundTextElement = getBoundTextElement(element, app.scene.getNonDeletedElementsMap());
442
- if (boundTextElement) {
443
- return boundTextElement.fontFamily;
632
+ else {
633
+ // close, use the cache and clear it afterwards
634
+ const data = {
635
+ openPopup: null,
636
+ currentHoveredFontFamily: null,
637
+ cachedElements: new Map(cachedElementsRef.current),
638
+ resetAll: true,
639
+ };
640
+ if (isUnmounted.current) {
641
+ // in case the component was unmounted by the parent, trigger the update directly
642
+ updateData({ ...batchedData, ...data });
643
+ }
644
+ else {
645
+ setBatchedData(data);
646
+ }
647
+ cachedElementsRef.current.clear();
444
648
  }
445
- return null;
446
- }, (element) => isTextElement(element) ||
447
- getBoundTextElement(element, app.scene.getNonDeletedElementsMap()) !== null, (hasSelection) => hasSelection
448
- ? null
449
- : appState.currentItemFontFamily || DEFAULT_FONT_FAMILY), onChange: (value) => updateData(value) })] }));
649
+ } })] }));
450
650
  },
451
651
  });
452
652
  export const actionChangeTextAlign = register({
@@ -563,15 +763,20 @@ export const actionChangeRoundness = register({
563
763
  trackEvent: false,
564
764
  perform: (elements, appState, value) => {
565
765
  return {
566
- elements: changeProperty(elements, appState, (el) => newElementWith(el, {
567
- roundness: value === "round"
568
- ? {
569
- type: isUsingAdaptiveRadius(el.type)
570
- ? ROUNDNESS.ADAPTIVE_RADIUS
571
- : ROUNDNESS.PROPORTIONAL_RADIUS,
572
- }
573
- : null,
574
- })),
766
+ elements: changeProperty(elements, appState, (el) => {
767
+ if (isElbowArrow(el)) {
768
+ return el;
769
+ }
770
+ return newElementWith(el, {
771
+ roundness: value === "round"
772
+ ? {
773
+ type: isUsingAdaptiveRadius(el.type)
774
+ ? ROUNDNESS.ADAPTIVE_RADIUS
775
+ : ROUNDNESS.PROPORTIONAL_RADIUS,
776
+ }
777
+ : null,
778
+ });
779
+ }),
575
780
  appState: {
576
781
  ...appState,
577
782
  currentItemRoundness: value,
@@ -593,7 +798,7 @@ export const actionChangeRoundness = register({
593
798
  text: t("labels.round"),
594
799
  icon: EdgeRoundIcon,
595
800
  },
596
- ], value: getFormValue(elements, appState, (element) => hasLegacyRoundness ? null : element.roundness ? "round" : "sharp", (element) => element.hasOwnProperty("roundness"), (hasSelection) => hasSelection ? null : appState.currentItemRoundness), onChange: (value) => updateData(value) })] }));
801
+ ], value: getFormValue(elements, appState, (element) => hasLegacyRoundness ? null : element.roundness ? "round" : "sharp", (element) => !isArrowElement(element) && element.hasOwnProperty("roundness"), (hasSelection) => hasSelection ? null : appState.currentItemRoundness), onChange: (value) => updateData(value) })] }));
597
802
  },
598
803
  });
599
804
  const getArrowheadOptions = (flip) => {
@@ -708,3 +913,123 @@ export const actionChangeArrowhead = register({
708
913
  : appState.currentItemEndArrowhead, true, appState.currentItemEndArrowhead), onChange: (value) => updateData({ position: "end", type: value }) })] })] }));
709
914
  },
710
915
  });
916
+ export const actionChangeArrowType = register({
917
+ name: "changeArrowType",
918
+ label: "Change arrow types",
919
+ trackEvent: false,
920
+ perform: (elements, appState, value, app) => {
921
+ return {
922
+ elements: changeProperty(elements, appState, (el) => {
923
+ if (!isArrowElement(el)) {
924
+ return el;
925
+ }
926
+ const newElement = newElementWith(el, {
927
+ roundness: value === ARROW_TYPE.round
928
+ ? {
929
+ type: ROUNDNESS.PROPORTIONAL_RADIUS,
930
+ }
931
+ : null,
932
+ elbowed: value === ARROW_TYPE.elbow,
933
+ points: value === ARROW_TYPE.elbow || el.elbowed
934
+ ? [el.points[0], el.points[el.points.length - 1]]
935
+ : el.points,
936
+ });
937
+ if (isElbowArrow(newElement)) {
938
+ const elementsMap = app.scene.getNonDeletedElementsMap();
939
+ app.dismissLinearEditor();
940
+ const startGlobalPoint = LinearElementEditor.getPointAtIndexGlobalCoordinates(newElement, 0, elementsMap);
941
+ const endGlobalPoint = LinearElementEditor.getPointAtIndexGlobalCoordinates(newElement, -1, elementsMap);
942
+ const startHoveredElement = !newElement.startBinding &&
943
+ getHoveredElementForBinding(tupleToCoors(startGlobalPoint), elements, elementsMap, true);
944
+ const endHoveredElement = !newElement.endBinding &&
945
+ getHoveredElementForBinding(tupleToCoors(endGlobalPoint), elements, elementsMap, true);
946
+ const startElement = startHoveredElement
947
+ ? startHoveredElement
948
+ : newElement.startBinding &&
949
+ elementsMap.get(newElement.startBinding.elementId);
950
+ const endElement = endHoveredElement
951
+ ? endHoveredElement
952
+ : newElement.endBinding &&
953
+ elementsMap.get(newElement.endBinding.elementId);
954
+ const finalStartPoint = startHoveredElement
955
+ ? bindPointToSnapToElementOutline(startGlobalPoint, endGlobalPoint, startHoveredElement, elementsMap)
956
+ : startGlobalPoint;
957
+ const finalEndPoint = endHoveredElement
958
+ ? bindPointToSnapToElementOutline(endGlobalPoint, startGlobalPoint, endHoveredElement, elementsMap)
959
+ : endGlobalPoint;
960
+ startHoveredElement &&
961
+ bindLinearElement(newElement, startHoveredElement, "start", elementsMap);
962
+ endHoveredElement &&
963
+ bindLinearElement(newElement, endHoveredElement, "end", elementsMap);
964
+ mutateElbowArrow(newElement, app.scene, [finalStartPoint, finalEndPoint].map((point) => [point[0] - newElement.x, point[1] - newElement.y]), [0, 0], {
965
+ ...(startElement && newElement.startBinding
966
+ ? {
967
+ startBinding: {
968
+ // @ts-ignore TS cannot discern check above
969
+ ...newElement.startBinding,
970
+ ...calculateFixedPointForElbowArrowBinding(newElement, startElement, "start", elementsMap),
971
+ },
972
+ }
973
+ : {}),
974
+ ...(endElement && newElement.endBinding
975
+ ? {
976
+ endBinding: {
977
+ // @ts-ignore TS cannot discern check above
978
+ ...newElement.endBinding,
979
+ ...calculateFixedPointForElbowArrowBinding(newElement, endElement, "end", elementsMap),
980
+ },
981
+ }
982
+ : {}),
983
+ });
984
+ }
985
+ else {
986
+ mutateElement(newElement, {
987
+ startBinding: newElement.startBinding
988
+ ? { ...newElement.startBinding, fixedPoint: null }
989
+ : null,
990
+ endBinding: newElement.endBinding
991
+ ? { ...newElement.endBinding, fixedPoint: null }
992
+ : null,
993
+ }, false);
994
+ }
995
+ return newElement;
996
+ }),
997
+ appState: {
998
+ ...appState,
999
+ currentItemArrowType: value,
1000
+ },
1001
+ storeAction: StoreAction.CAPTURE,
1002
+ };
1003
+ },
1004
+ PanelComponent: ({ elements, appState, updateData }) => {
1005
+ return (_jsxs("fieldset", { children: [_jsx("legend", { children: t("labels.arrowtypes") }), _jsx(ButtonIconSelect, { group: "arrowtypes", options: [
1006
+ {
1007
+ value: ARROW_TYPE.sharp,
1008
+ text: t("labels.arrowtype_sharp"),
1009
+ icon: sharpArrowIcon,
1010
+ testId: "sharp-arrow",
1011
+ },
1012
+ {
1013
+ value: ARROW_TYPE.round,
1014
+ text: t("labels.arrowtype_round"),
1015
+ icon: roundArrowIcon,
1016
+ testId: "round-arrow",
1017
+ },
1018
+ {
1019
+ value: ARROW_TYPE.elbow,
1020
+ text: t("labels.arrowtype_elbowed"),
1021
+ icon: elbowArrowIcon,
1022
+ testId: "elbow-arrow",
1023
+ },
1024
+ ], value: getFormValue(elements, appState, (element) => {
1025
+ if (isArrowElement(element)) {
1026
+ return element.elbowed
1027
+ ? ARROW_TYPE.elbow
1028
+ : element.roundness
1029
+ ? ARROW_TYPE.round
1030
+ : ARROW_TYPE.sharp;
1031
+ }
1032
+ return null;
1033
+ }, (element) => isArrowElement(element), (hasSelection) => hasSelection ? null : appState.currentItemArrowType), onChange: (value) => updateData(value) })] }));
1034
+ },
1035
+ });
@@ -71,7 +71,9 @@ export declare const actionSelectAll: {
71
71
  currentItemTextAlign: string;
72
72
  currentItemStartArrowhead: import("../element/types").Arrowhead | null;
73
73
  currentItemEndArrowhead: import("../element/types").Arrowhead | null;
74
+ currentHoveredFontFamily: number | null;
74
75
  currentItemRoundness: import("../element/types").StrokeRoundness;
76
+ currentItemArrowType: "sharp" | "round" | "elbow";
75
77
  viewBackgroundColor: string;
76
78
  scrollX: number;
77
79
  scrollY: number;
@@ -84,7 +86,7 @@ export declare const actionSelectAll: {
84
86
  value: import("../types").NormalizedZoomValue;
85
87
  }>;
86
88
  openMenu: "canvas" | "shape" | null;
87
- openPopup: "canvasBackground" | "elementBackground" | "elementStroke" | null;
89
+ openPopup: "fontFamily" | "canvasBackground" | "elementBackground" | "elementStroke" | null;
88
90
  openSidebar: {
89
91
  name: string;
90
92
  tab?: string | undefined;
@@ -64,7 +64,9 @@ export declare const actionCopyStyles: {
64
64
  currentItemTextAlign: string;
65
65
  currentItemStartArrowhead: import("../element/types").Arrowhead | null;
66
66
  currentItemEndArrowhead: import("../element/types").Arrowhead | null;
67
+ currentHoveredFontFamily: number | null;
67
68
  currentItemRoundness: import("../element/types").StrokeRoundness;
69
+ currentItemArrowType: "sharp" | "round" | "elbow";
68
70
  viewBackgroundColor: string;
69
71
  scrollX: number;
70
72
  scrollY: number;
@@ -77,7 +79,7 @@ export declare const actionCopyStyles: {
77
79
  value: import("../types").NormalizedZoomValue;
78
80
  }>;
79
81
  openMenu: "canvas" | "shape" | null;
80
- openPopup: "canvasBackground" | "elementBackground" | "elementStroke" | null;
82
+ openPopup: "fontFamily" | "canvasBackground" | "elementBackground" | "elementStroke" | null;
81
83
  openSidebar: {
82
84
  name: string;
83
85
  tab?: string | undefined;
@@ -4,11 +4,12 @@ import { t } from "../i18n";
4
4
  import { register } from "./register";
5
5
  import { newElementWith } from "../element/mutateElement";
6
6
  import { DEFAULT_FONT_SIZE, DEFAULT_FONT_FAMILY, DEFAULT_TEXT_ALIGN, } from "../constants";
7
- import { getBoundTextElement, getDefaultLineHeight, } from "../element/textElement";
7
+ import { getBoundTextElement } from "../element/textElement";
8
8
  import { hasBoundTextElement, canApplyRoundnessTypeToElement, getDefaultRoundnessTypeForElement, isFrameLikeElement, isArrowElement, } from "../element/typeChecks";
9
9
  import { getSelectedElements } from "../scene";
10
10
  import { paintIcon } from "../components/icons";
11
11
  import { StoreAction } from "../store";
12
+ import { getLineHeight } from "../fonts";
12
13
  // `copiedStyles` is exported only for tests.
13
14
  export let copiedStyles = "{}";
14
15
  export const actionCopyStyles = register({
@@ -88,7 +89,7 @@ export const actionPasteStyles = register({
88
89
  textAlign: elementStylesToCopyFrom.textAlign ||
89
90
  DEFAULT_TEXT_ALIGN,
90
91
  lineHeight: elementStylesToCopyFrom.lineHeight ||
91
- getDefaultLineHeight(fontFamily),
92
+ getLineHeight(fontFamily),
92
93
  });
93
94
  let container = null;
94
95
  if (newElement.containerId) {
@@ -66,7 +66,9 @@ export declare const actionToggleGridMode: {
66
66
  currentItemTextAlign: string;
67
67
  currentItemStartArrowhead: import("../element/types").Arrowhead | null;
68
68
  currentItemEndArrowhead: import("../element/types").Arrowhead | null;
69
+ currentHoveredFontFamily: number | null;
69
70
  currentItemRoundness: import("../element/types").StrokeRoundness;
71
+ currentItemArrowType: "sharp" | "round" | "elbow";
70
72
  viewBackgroundColor: string;
71
73
  scrollX: number;
72
74
  scrollY: number;
@@ -79,7 +81,7 @@ export declare const actionToggleGridMode: {
79
81
  value: import("../types").NormalizedZoomValue;
80
82
  }>;
81
83
  openMenu: "canvas" | "shape" | null;
82
- openPopup: "canvasBackground" | "elementBackground" | "elementStroke" | null;
84
+ openPopup: "fontFamily" | "canvasBackground" | "elementBackground" | "elementStroke" | null;
83
85
  openSidebar: {
84
86
  name: string;
85
87
  tab?: string | undefined;
@@ -64,7 +64,9 @@ export declare const actionToggleObjectsSnapMode: {
64
64
  currentItemTextAlign: string;
65
65
  currentItemStartArrowhead: import("../element/types").Arrowhead | null;
66
66
  currentItemEndArrowhead: import("../element/types").Arrowhead | null;
67
+ currentHoveredFontFamily: number | null;
67
68
  currentItemRoundness: import("../element/types").StrokeRoundness;
69
+ currentItemArrowType: "sharp" | "round" | "elbow";
68
70
  viewBackgroundColor: string;
69
71
  scrollX: number;
70
72
  scrollY: number;
@@ -77,7 +79,7 @@ export declare const actionToggleObjectsSnapMode: {
77
79
  value: import("../types").NormalizedZoomValue;
78
80
  }>;
79
81
  openMenu: "canvas" | "shape" | null;
80
- openPopup: "canvasBackground" | "elementBackground" | "elementStroke" | null;
82
+ openPopup: "fontFamily" | "canvasBackground" | "elementBackground" | "elementStroke" | null;
81
83
  openSidebar: {
82
84
  name: string;
83
85
  tab?: string | undefined;
@@ -67,7 +67,9 @@ export declare const actionToggleStats: {
67
67
  currentItemTextAlign: string;
68
68
  currentItemStartArrowhead: import("../element/types").Arrowhead | null;
69
69
  currentItemEndArrowhead: import("../element/types").Arrowhead | null;
70
+ currentHoveredFontFamily: number | null;
70
71
  currentItemRoundness: import("../element/types").StrokeRoundness;
72
+ currentItemArrowType: "sharp" | "round" | "elbow";
71
73
  viewBackgroundColor: string;
72
74
  scrollX: number;
73
75
  scrollY: number;
@@ -80,7 +82,7 @@ export declare const actionToggleStats: {
80
82
  value: import("../types").NormalizedZoomValue;
81
83
  }>;
82
84
  openMenu: "canvas" | "shape" | null;
83
- openPopup: "canvasBackground" | "elementBackground" | "elementStroke" | null;
85
+ openPopup: "fontFamily" | "canvasBackground" | "elementBackground" | "elementStroke" | null;
84
86
  openSidebar: {
85
87
  name: string;
86
88
  tab?: string | undefined;
@@ -64,7 +64,9 @@ export declare const actionToggleViewMode: {
64
64
  currentItemTextAlign: string;
65
65
  currentItemStartArrowhead: import("../element/types").Arrowhead | null;
66
66
  currentItemEndArrowhead: import("../element/types").Arrowhead | null;
67
+ currentHoveredFontFamily: number | null;
67
68
  currentItemRoundness: import("../element/types").StrokeRoundness;
69
+ currentItemArrowType: "sharp" | "round" | "elbow";
68
70
  viewBackgroundColor: string;
69
71
  scrollX: number;
70
72
  scrollY: number;
@@ -77,7 +79,7 @@ export declare const actionToggleViewMode: {
77
79
  value: import("../types").NormalizedZoomValue;
78
80
  }>;
79
81
  openMenu: "canvas" | "shape" | null;
80
- openPopup: "canvasBackground" | "elementBackground" | "elementStroke" | null;
82
+ openPopup: "fontFamily" | "canvasBackground" | "elementBackground" | "elementStroke" | null;
81
83
  openSidebar: {
82
84
  name: string;
83
85
  tab?: string | undefined;