tldraw 4.1.0-canary.4ecbfdc37522 → 4.1.0-canary.533dd6427b33

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 (144) hide show
  1. package/dist-cjs/index.d.ts +46 -12
  2. package/dist-cjs/index.js +6 -1
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/defaultEmbedDefinitions.js +25 -30
  5. package/dist-cjs/lib/defaultEmbedDefinitions.js.map +2 -2
  6. package/dist-cjs/lib/defaultExternalContentHandlers.js +9 -32
  7. package/dist-cjs/lib/defaultExternalContentHandlers.js.map +2 -2
  8. package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js +3 -0
  9. package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js.map +2 -2
  10. package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js +43 -101
  11. package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js.map +2 -2
  12. package/dist-cjs/lib/shapes/bookmark/bookmarks.js +138 -0
  13. package/dist-cjs/lib/shapes/bookmark/bookmarks.js.map +7 -0
  14. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js +25 -3
  15. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js.map +2 -2
  16. package/dist-cjs/lib/shapes/line/LineShapeUtil.js +3 -0
  17. package/dist-cjs/lib/shapes/line/LineShapeUtil.js.map +2 -2
  18. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Cropping.js +20 -4
  19. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Cropping.js.map +2 -2
  20. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Idle.js +1 -1
  21. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Idle.js.map +2 -2
  22. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.js +23 -11
  23. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.js.map +2 -2
  24. package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js +27 -6
  25. package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js.map +2 -2
  26. package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js +1 -1
  27. package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js.map +2 -2
  28. package/dist-cjs/lib/tools/SelectTool/childStates/PointingArrowLabel.js +21 -9
  29. package/dist-cjs/lib/tools/SelectTool/childStates/PointingArrowLabel.js.map +2 -2
  30. package/dist-cjs/lib/tools/SelectTool/childStates/PointingResizeHandle.js +24 -8
  31. package/dist-cjs/lib/tools/SelectTool/childStates/PointingResizeHandle.js.map +2 -2
  32. package/dist-cjs/lib/tools/SelectTool/childStates/PointingRotateHandle.js +21 -9
  33. package/dist-cjs/lib/tools/SelectTool/childStates/PointingRotateHandle.js.map +2 -2
  34. package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js +23 -8
  35. package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js.map +2 -2
  36. package/dist-cjs/lib/tools/SelectTool/childStates/Rotating.js +21 -9
  37. package/dist-cjs/lib/tools/SelectTool/childStates/Rotating.js.map +2 -2
  38. package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js +26 -11
  39. package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js.map +2 -2
  40. package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js +5 -0
  41. package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js.map +2 -2
  42. package/dist-cjs/lib/ui/components/SharePanel/PeopleMenu.js +6 -2
  43. package/dist-cjs/lib/ui/components/SharePanel/PeopleMenu.js.map +2 -2
  44. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js +63 -55
  45. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js.map +2 -2
  46. package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js +54 -47
  47. package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js.map +3 -3
  48. package/dist-cjs/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.js +62 -55
  49. package/dist-cjs/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.js.map +2 -2
  50. package/dist-cjs/lib/ui/components/StylePanel/StylePanelDropdownPicker.js +12 -5
  51. package/dist-cjs/lib/ui/components/StylePanel/StylePanelDropdownPicker.js.map +2 -2
  52. package/dist-cjs/lib/ui/context/actions.js +23 -29
  53. package/dist-cjs/lib/ui/context/actions.js.map +2 -2
  54. package/dist-cjs/lib/ui/version.js +3 -3
  55. package/dist-cjs/lib/ui/version.js.map +1 -1
  56. package/dist-esm/index.d.mts +46 -12
  57. package/dist-esm/index.mjs +12 -4
  58. package/dist-esm/index.mjs.map +2 -2
  59. package/dist-esm/lib/defaultEmbedDefinitions.mjs +25 -30
  60. package/dist-esm/lib/defaultEmbedDefinitions.mjs.map +2 -2
  61. package/dist-esm/lib/defaultExternalContentHandlers.mjs +9 -32
  62. package/dist-esm/lib/defaultExternalContentHandlers.mjs.map +2 -2
  63. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs +3 -0
  64. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs.map +2 -2
  65. package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs +46 -101
  66. package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs.map +2 -2
  67. package/dist-esm/lib/shapes/bookmark/bookmarks.mjs +124 -0
  68. package/dist-esm/lib/shapes/bookmark/bookmarks.mjs.map +7 -0
  69. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs +26 -3
  70. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs.map +2 -2
  71. package/dist-esm/lib/shapes/line/LineShapeUtil.mjs +3 -0
  72. package/dist-esm/lib/shapes/line/LineShapeUtil.mjs.map +2 -2
  73. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Cropping.mjs +20 -4
  74. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Cropping.mjs.map +2 -2
  75. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Idle.mjs +1 -1
  76. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Idle.mjs.map +2 -2
  77. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.mjs +23 -11
  78. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.mjs.map +2 -2
  79. package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs +29 -7
  80. package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs.map +2 -2
  81. package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs +1 -1
  82. package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs.map +2 -2
  83. package/dist-esm/lib/tools/SelectTool/childStates/PointingArrowLabel.mjs +21 -9
  84. package/dist-esm/lib/tools/SelectTool/childStates/PointingArrowLabel.mjs.map +2 -2
  85. package/dist-esm/lib/tools/SelectTool/childStates/PointingResizeHandle.mjs +24 -8
  86. package/dist-esm/lib/tools/SelectTool/childStates/PointingResizeHandle.mjs.map +2 -2
  87. package/dist-esm/lib/tools/SelectTool/childStates/PointingRotateHandle.mjs +21 -9
  88. package/dist-esm/lib/tools/SelectTool/childStates/PointingRotateHandle.mjs.map +2 -2
  89. package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs +23 -8
  90. package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs.map +2 -2
  91. package/dist-esm/lib/tools/SelectTool/childStates/Rotating.mjs +21 -9
  92. package/dist-esm/lib/tools/SelectTool/childStates/Rotating.mjs.map +2 -2
  93. package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs +26 -11
  94. package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs.map +2 -2
  95. package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs +5 -0
  96. package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs.map +2 -2
  97. package/dist-esm/lib/ui/components/SharePanel/PeopleMenu.mjs +6 -2
  98. package/dist-esm/lib/ui/components/SharePanel/PeopleMenu.mjs.map +2 -2
  99. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs +68 -57
  100. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs.map +2 -2
  101. package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs +54 -47
  102. package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs.map +3 -3
  103. package/dist-esm/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.mjs +63 -56
  104. package/dist-esm/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.mjs.map +2 -2
  105. package/dist-esm/lib/ui/components/StylePanel/StylePanelDropdownPicker.mjs +12 -5
  106. package/dist-esm/lib/ui/components/StylePanel/StylePanelDropdownPicker.mjs.map +2 -2
  107. package/dist-esm/lib/ui/context/actions.mjs +23 -29
  108. package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
  109. package/dist-esm/lib/ui/version.mjs +3 -3
  110. package/dist-esm/lib/ui/version.mjs.map +1 -1
  111. package/package.json +3 -3
  112. package/src/index.ts +4 -0
  113. package/src/lib/defaultEmbedDefinitions.ts +20 -24
  114. package/src/lib/defaultExternalContentHandlers.ts +11 -36
  115. package/src/lib/shapes/arrow/ArrowShapeUtil.tsx +3 -0
  116. package/src/lib/shapes/bookmark/BookmarkShapeUtil.tsx +51 -135
  117. package/src/lib/shapes/bookmark/bookmarks.ts +170 -0
  118. package/src/lib/shapes/embed/EmbedShapeUtil.tsx +28 -2
  119. package/src/lib/shapes/line/LineShapeUtil.tsx +3 -0
  120. package/src/lib/shapes/text/TextShapeTool.test.ts +74 -0
  121. package/src/lib/tools/SelectTool/childStates/Crop/children/Cropping.ts +23 -6
  122. package/src/lib/tools/SelectTool/childStates/Crop/children/Idle.ts +1 -1
  123. package/src/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.ts +24 -12
  124. package/src/lib/tools/SelectTool/childStates/DraggingHandle.tsx +34 -11
  125. package/src/lib/tools/SelectTool/childStates/Idle.ts +1 -1
  126. package/src/lib/tools/SelectTool/childStates/PointingArrowLabel.ts +23 -11
  127. package/src/lib/tools/SelectTool/childStates/PointingResizeHandle.ts +26 -9
  128. package/src/lib/tools/SelectTool/childStates/PointingRotateHandle.ts +23 -10
  129. package/src/lib/tools/SelectTool/childStates/Resizing.ts +24 -9
  130. package/src/lib/tools/SelectTool/childStates/Rotating.ts +27 -11
  131. package/src/lib/tools/SelectTool/childStates/Translating.ts +28 -12
  132. package/src/lib/ui/components/Minimap/MinimapManager.ts +6 -0
  133. package/src/lib/ui/components/SharePanel/PeopleMenu.tsx +6 -2
  134. package/src/lib/ui/components/StylePanel/DefaultStylePanelContent.tsx +60 -49
  135. package/src/lib/ui/components/StylePanel/StylePanelButtonPicker.tsx +70 -53
  136. package/src/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.tsx +105 -90
  137. package/src/lib/ui/components/StylePanel/StylePanelDropdownPicker.tsx +72 -51
  138. package/src/lib/ui/context/actions.tsx +27 -31
  139. package/src/lib/ui/version.ts +3 -3
  140. package/src/lib/utils/embeds/embeds.test.ts +16 -34
  141. package/src/test/SelectTool.test.ts +251 -0
  142. package/src/test/bookmark-shapes.test.ts +129 -7
  143. package/src/test/customSnapping.test.tsx +55 -11
  144. package/tldraw.css +7 -2
@@ -0,0 +1,124 @@
1
+ import {
2
+ AssetRecordType,
3
+ Result,
4
+ createShapeId,
5
+ debounce,
6
+ getHashForString
7
+ } from "@tldraw/editor";
8
+ const BOOKMARK_WIDTH = 300;
9
+ const BOOKMARK_HEIGHT = 320;
10
+ const BOOKMARK_JUST_URL_HEIGHT = 46;
11
+ const SHORT_BOOKMARK_HEIGHT = 101;
12
+ function getBookmarkHeight(editor, assetId) {
13
+ const asset = assetId ? editor.getAsset(assetId) : null;
14
+ if (asset) {
15
+ if (!asset.props.image) {
16
+ if (!asset.props.title) {
17
+ return BOOKMARK_JUST_URL_HEIGHT;
18
+ } else {
19
+ return SHORT_BOOKMARK_HEIGHT;
20
+ }
21
+ }
22
+ }
23
+ return BOOKMARK_HEIGHT;
24
+ }
25
+ function setBookmarkHeight(editor, shape) {
26
+ return {
27
+ ...shape,
28
+ props: { ...shape.props, h: getBookmarkHeight(editor, shape.props.assetId) }
29
+ };
30
+ }
31
+ const getHumanReadableAddress = (url) => {
32
+ try {
33
+ const objUrl = new URL(url);
34
+ return objUrl.hostname.replace(/^www\./, "");
35
+ } catch {
36
+ return url;
37
+ }
38
+ };
39
+ function updateBookmarkAssetOnUrlChange(editor, shape) {
40
+ const { url } = shape.props;
41
+ const assetId = AssetRecordType.createId(getHashForString(url));
42
+ if (editor.getAsset(assetId)) {
43
+ if (shape.props.assetId !== assetId) {
44
+ editor.updateShapes([
45
+ {
46
+ id: shape.id,
47
+ type: shape.type,
48
+ props: { assetId }
49
+ }
50
+ ]);
51
+ }
52
+ } else {
53
+ editor.updateShapes([
54
+ {
55
+ id: shape.id,
56
+ type: shape.type,
57
+ props: { assetId: null }
58
+ }
59
+ ]);
60
+ createBookmarkAssetOnUrlChange(editor, shape);
61
+ }
62
+ }
63
+ const createBookmarkAssetOnUrlChange = debounce(async (editor, shape) => {
64
+ if (editor.isDisposed) return;
65
+ const { url } = shape.props;
66
+ const asset = await editor.getAssetForExternalContent({ type: "url", url });
67
+ if (!asset) {
68
+ return;
69
+ }
70
+ editor.run(() => {
71
+ editor.createAssets([asset]);
72
+ editor.updateShapes([
73
+ {
74
+ id: shape.id,
75
+ type: shape.type,
76
+ props: { assetId: asset.id }
77
+ }
78
+ ]);
79
+ });
80
+ }, 500);
81
+ async function createBookmarkFromUrl(editor, {
82
+ url,
83
+ center = editor.getViewportPageBounds().center
84
+ }) {
85
+ try {
86
+ const asset = await editor.getAssetForExternalContent({ type: "url", url });
87
+ const shapeId = createShapeId();
88
+ const shapePartial = {
89
+ id: shapeId,
90
+ type: "bookmark",
91
+ x: center.x - BOOKMARK_WIDTH / 2,
92
+ y: center.y - BOOKMARK_HEIGHT / 2,
93
+ rotation: 0,
94
+ opacity: 1,
95
+ props: {
96
+ url,
97
+ assetId: asset?.id || null,
98
+ w: BOOKMARK_WIDTH,
99
+ h: getBookmarkHeight(editor, asset?.id)
100
+ }
101
+ };
102
+ editor.run(() => {
103
+ if (asset) {
104
+ editor.createAssets([asset]);
105
+ }
106
+ editor.createShapes([shapePartial]);
107
+ });
108
+ const createdShape = editor.getShape(shapeId);
109
+ return Result.ok(createdShape);
110
+ } catch (error) {
111
+ return Result.err(error instanceof Error ? error.message : "Failed to create bookmark");
112
+ }
113
+ }
114
+ export {
115
+ BOOKMARK_HEIGHT,
116
+ BOOKMARK_JUST_URL_HEIGHT,
117
+ BOOKMARK_WIDTH,
118
+ createBookmarkFromUrl,
119
+ getBookmarkHeight,
120
+ getHumanReadableAddress,
121
+ setBookmarkHeight,
122
+ updateBookmarkAssetOnUrlChange
123
+ };
124
+ //# sourceMappingURL=bookmarks.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/lib/shapes/bookmark/bookmarks.ts"],
4
+ "sourcesContent": ["import {\n\tAssetRecordType,\n\tEditor,\n\tResult,\n\tTLAssetId,\n\tTLBookmarkAsset,\n\tTLBookmarkShape,\n\tTLShapePartial,\n\tcreateShapeId,\n\tdebounce,\n\tgetHashForString,\n} from '@tldraw/editor'\n\nexport const BOOKMARK_WIDTH = 300\nexport const BOOKMARK_HEIGHT = 320\nexport const BOOKMARK_JUST_URL_HEIGHT = 46\nconst SHORT_BOOKMARK_HEIGHT = 101\n\nexport function getBookmarkHeight(editor: Editor, assetId?: TLAssetId | null) {\n\tconst asset = (assetId ? editor.getAsset(assetId) : null) as TLBookmarkAsset | null\n\n\tif (asset) {\n\t\tif (!asset.props.image) {\n\t\t\tif (!asset.props.title) {\n\t\t\t\treturn BOOKMARK_JUST_URL_HEIGHT\n\t\t\t} else {\n\t\t\t\treturn SHORT_BOOKMARK_HEIGHT\n\t\t\t}\n\t\t}\n\t}\n\n\treturn BOOKMARK_HEIGHT\n}\n\nexport function setBookmarkHeight(editor: Editor, shape: TLBookmarkShape) {\n\treturn {\n\t\t...shape,\n\t\tprops: { ...shape.props, h: getBookmarkHeight(editor, shape.props.assetId) },\n\t}\n}\n\n/** @internal */\nexport const getHumanReadableAddress = (url: string) => {\n\ttry {\n\t\tconst objUrl = new URL(url)\n\t\t// we want the hostname without any www\n\t\treturn objUrl.hostname.replace(/^www\\./, '')\n\t} catch {\n\t\treturn url\n\t}\n}\n\nexport function updateBookmarkAssetOnUrlChange(editor: Editor, shape: TLBookmarkShape) {\n\tconst { url } = shape.props\n\n\t// Derive the asset id from the URL\n\tconst assetId: TLAssetId = AssetRecordType.createId(getHashForString(url))\n\n\tif (editor.getAsset(assetId)) {\n\t\t// Existing asset for this URL?\n\t\tif (shape.props.assetId !== assetId) {\n\t\t\teditor.updateShapes<TLBookmarkShape>([\n\t\t\t\t{\n\t\t\t\t\tid: shape.id,\n\t\t\t\t\ttype: shape.type,\n\t\t\t\t\tprops: { assetId },\n\t\t\t\t},\n\t\t\t])\n\t\t}\n\t} else {\n\t\t// No asset for this URL?\n\n\t\t// First, clear out the existing asset reference\n\t\teditor.updateShapes<TLBookmarkShape>([\n\t\t\t{\n\t\t\t\tid: shape.id,\n\t\t\t\ttype: shape.type,\n\t\t\t\tprops: { assetId: null },\n\t\t\t},\n\t\t])\n\n\t\t// Then try to asyncronously create a new one\n\t\tcreateBookmarkAssetOnUrlChange(editor, shape)\n\t}\n}\n\nconst createBookmarkAssetOnUrlChange = debounce(async (editor: Editor, shape: TLBookmarkShape) => {\n\tif (editor.isDisposed) return\n\n\tconst { url } = shape.props\n\n\t// Create the asset using the external content manager's createAssetFromUrl method.\n\t// This may be overwritten by the user (for example, we overwrite it on tldraw.com)\n\tconst asset = await editor.getAssetForExternalContent({ type: 'url', url })\n\n\tif (!asset) {\n\t\t// No asset? Just leave the bookmark as a null assetId.\n\t\treturn\n\t}\n\n\teditor.run(() => {\n\t\t// Create the new asset\n\t\teditor.createAssets([asset])\n\n\t\t// And update the shape\n\t\teditor.updateShapes<TLBookmarkShape>([\n\t\t\t{\n\t\t\t\tid: shape.id,\n\t\t\t\ttype: shape.type,\n\t\t\t\tprops: { assetId: asset.id },\n\t\t\t},\n\t\t])\n\t})\n}, 500)\n\n/**\n * Creates a bookmark shape from a URL with unfurled metadata.\n *\n * @returns A Result containing the created bookmark shape or an error\n * @public\n */\n\nexport async function createBookmarkFromUrl(\n\teditor: Editor,\n\t{\n\t\turl,\n\t\tcenter = editor.getViewportPageBounds().center,\n\t}: {\n\t\turl: string\n\t\tcenter?: { x: number; y: number }\n\t}\n): Promise<Result<TLBookmarkShape, string>> {\n\ttry {\n\t\t// Create the bookmark asset with unfurled metadata\n\t\tconst asset = await editor.getAssetForExternalContent({ type: 'url', url })\n\n\t\t// Create the bookmark shape\n\t\tconst shapeId = createShapeId()\n\t\tconst shapePartial: TLShapePartial<TLBookmarkShape> = {\n\t\t\tid: shapeId,\n\t\t\ttype: 'bookmark',\n\t\t\tx: center.x - BOOKMARK_WIDTH / 2,\n\t\t\ty: center.y - BOOKMARK_HEIGHT / 2,\n\t\t\trotation: 0,\n\t\t\topacity: 1,\n\t\t\tprops: {\n\t\t\t\turl,\n\t\t\t\tassetId: asset?.id || null,\n\t\t\t\tw: BOOKMARK_WIDTH,\n\t\t\t\th: getBookmarkHeight(editor, asset?.id),\n\t\t\t},\n\t\t}\n\n\t\teditor.run(() => {\n\t\t\t// Create the asset if we have one\n\t\t\tif (asset) {\n\t\t\t\teditor.createAssets([asset])\n\t\t\t}\n\n\t\t\t// Create the shape\n\t\t\teditor.createShapes([shapePartial])\n\t\t})\n\n\t\t// Get the created shape\n\t\tconst createdShape = editor.getShape(shapeId) as TLBookmarkShape\n\t\treturn Result.ok(createdShape)\n\t} catch (error) {\n\t\treturn Result.err(error instanceof Error ? error.message : 'Failed to create bookmark')\n\t}\n}\n"],
5
+ "mappings": "AAAA;AAAA,EACC;AAAA,EAEA;AAAA,EAKA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AAEA,MAAM,iBAAiB;AACvB,MAAM,kBAAkB;AACxB,MAAM,2BAA2B;AACxC,MAAM,wBAAwB;AAEvB,SAAS,kBAAkB,QAAgB,SAA4B;AAC7E,QAAM,QAAS,UAAU,OAAO,SAAS,OAAO,IAAI;AAEpD,MAAI,OAAO;AACV,QAAI,CAAC,MAAM,MAAM,OAAO;AACvB,UAAI,CAAC,MAAM,MAAM,OAAO;AACvB,eAAO;AAAA,MACR,OAAO;AACN,eAAO;AAAA,MACR;AAAA,IACD;AAAA,EACD;AAEA,SAAO;AACR;AAEO,SAAS,kBAAkB,QAAgB,OAAwB;AACzE,SAAO;AAAA,IACN,GAAG;AAAA,IACH,OAAO,EAAE,GAAG,MAAM,OAAO,GAAG,kBAAkB,QAAQ,MAAM,MAAM,OAAO,EAAE;AAAA,EAC5E;AACD;AAGO,MAAM,0BAA0B,CAAC,QAAgB;AACvD,MAAI;AACH,UAAM,SAAS,IAAI,IAAI,GAAG;AAE1B,WAAO,OAAO,SAAS,QAAQ,UAAU,EAAE;AAAA,EAC5C,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AAEO,SAAS,+BAA+B,QAAgB,OAAwB;AACtF,QAAM,EAAE,IAAI,IAAI,MAAM;AAGtB,QAAM,UAAqB,gBAAgB,SAAS,iBAAiB,GAAG,CAAC;AAEzE,MAAI,OAAO,SAAS,OAAO,GAAG;AAE7B,QAAI,MAAM,MAAM,YAAY,SAAS;AACpC,aAAO,aAA8B;AAAA,QACpC;AAAA,UACC,IAAI,MAAM;AAAA,UACV,MAAM,MAAM;AAAA,UACZ,OAAO,EAAE,QAAQ;AAAA,QAClB;AAAA,MACD,CAAC;AAAA,IACF;AAAA,EACD,OAAO;AAIN,WAAO,aAA8B;AAAA,MACpC;AAAA,QACC,IAAI,MAAM;AAAA,QACV,MAAM,MAAM;AAAA,QACZ,OAAO,EAAE,SAAS,KAAK;AAAA,MACxB;AAAA,IACD,CAAC;AAGD,mCAA+B,QAAQ,KAAK;AAAA,EAC7C;AACD;AAEA,MAAM,iCAAiC,SAAS,OAAO,QAAgB,UAA2B;AACjG,MAAI,OAAO,WAAY;AAEvB,QAAM,EAAE,IAAI,IAAI,MAAM;AAItB,QAAM,QAAQ,MAAM,OAAO,2BAA2B,EAAE,MAAM,OAAO,IAAI,CAAC;AAE1E,MAAI,CAAC,OAAO;AAEX;AAAA,EACD;AAEA,SAAO,IAAI,MAAM;AAEhB,WAAO,aAAa,CAAC,KAAK,CAAC;AAG3B,WAAO,aAA8B;AAAA,MACpC;AAAA,QACC,IAAI,MAAM;AAAA,QACV,MAAM,MAAM;AAAA,QACZ,OAAO,EAAE,SAAS,MAAM,GAAG;AAAA,MAC5B;AAAA,IACD,CAAC;AAAA,EACF,CAAC;AACF,GAAG,GAAG;AASN,eAAsB,sBACrB,QACA;AAAA,EACC;AAAA,EACA,SAAS,OAAO,sBAAsB,EAAE;AACzC,GAI2C;AAC3C,MAAI;AAEH,UAAM,QAAQ,MAAM,OAAO,2BAA2B,EAAE,MAAM,OAAO,IAAI,CAAC;AAG1E,UAAM,UAAU,cAAc;AAC9B,UAAM,eAAgD;AAAA,MACrD,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,GAAG,OAAO,IAAI,iBAAiB;AAAA,MAC/B,GAAG,OAAO,IAAI,kBAAkB;AAAA,MAChC,UAAU;AAAA,MACV,SAAS;AAAA,MACT,OAAO;AAAA,QACN;AAAA,QACA,SAAS,OAAO,MAAM;AAAA,QACtB,GAAG;AAAA,QACH,GAAG,kBAAkB,QAAQ,OAAO,EAAE;AAAA,MACvC;AAAA,IACD;AAEA,WAAO,IAAI,MAAM;AAEhB,UAAI,OAAO;AACV,eAAO,aAAa,CAAC,KAAK,CAAC;AAAA,MAC5B;AAGA,aAAO,aAAa,CAAC,YAAY,CAAC;AAAA,IACnC,CAAC;AAGD,UAAM,eAAe,OAAO,SAAS,OAAO;AAC5C,WAAO,OAAO,GAAG,YAAY;AAAA,EAC9B,SAAS,OAAO;AACf,WAAO,OAAO,IAAI,iBAAiB,QAAQ,MAAM,UAAU,2BAA2B;AAAA,EACvF;AACD;",
6
+ "names": []
7
+ }
@@ -2,6 +2,7 @@ import { jsx } from "react/jsx-runtime";
2
2
  import {
3
3
  BaseBoxShapeUtil,
4
4
  HTMLContainer,
5
+ Rectangle2d,
5
6
  embedShapeMigrations,
6
7
  embedShapeProps,
7
8
  lerp,
@@ -16,6 +17,8 @@ import {
16
17
  embedShapePermissionDefaults
17
18
  } from "../../defaultEmbedDefinitions.mjs";
18
19
  import { getEmbedInfo } from "../../utils/embeds/embeds.mjs";
20
+ import { BookmarkIndicatorComponent, BookmarkShapeComponent } from "../bookmark/BookmarkShapeUtil.mjs";
21
+ import { BOOKMARK_JUST_URL_HEIGHT, BOOKMARK_WIDTH } from "../bookmark/bookmarks.mjs";
19
22
  import { getRotatedBoxShadow } from "../shared/rotated-box-shadow.mjs";
20
23
  const getSandboxPermissions = (permissions) => {
21
24
  return Object.entries(permissions).filter(([_perm, isEnabled]) => isEnabled).map(([perm]) => perm).join(" ");
@@ -60,6 +63,17 @@ class EmbedShapeUtil extends BaseBoxShapeUtil {
60
63
  url: ""
61
64
  };
62
65
  }
66
+ getGeometry(shape) {
67
+ const embedInfo = this.getEmbedDefinition(shape.props.url);
68
+ if (!embedInfo?.definition) {
69
+ return new Rectangle2d({
70
+ width: BOOKMARK_WIDTH,
71
+ height: BOOKMARK_JUST_URL_HEIGHT,
72
+ isFilled: true
73
+ });
74
+ }
75
+ return super.getGeometry(shape);
76
+ }
63
77
  isAspectRatioLocked(shape) {
64
78
  const embedInfo = this.getEmbedDefinition(shape.props.url);
65
79
  return embedInfo?.definition.isAspectRatioLocked ?? false;
@@ -158,11 +172,20 @@ class EmbedShapeUtil extends BaseBoxShapeUtil {
158
172
  background: embedInfo?.definition.backgroundColor
159
173
  }
160
174
  }
161
- ) : null });
175
+ ) : /* @__PURE__ */ jsx(
176
+ BookmarkShapeComponent,
177
+ {
178
+ url,
179
+ h,
180
+ rotation: pageRotation,
181
+ assetId: null,
182
+ showImageContainer: false
183
+ }
184
+ ) });
162
185
  }
163
186
  indicator(shape) {
164
187
  const embedInfo = this.getEmbedDefinition(shape.props.url);
165
- return /* @__PURE__ */ jsx(
188
+ return embedInfo?.definition ? /* @__PURE__ */ jsx(
166
189
  "rect",
167
190
  {
168
191
  width: toDomPrecision(shape.props.w),
@@ -170,7 +193,7 @@ class EmbedShapeUtil extends BaseBoxShapeUtil {
170
193
  rx: embedInfo?.definition.overrideOutlineRadius ?? 8,
171
194
  ry: embedInfo?.definition.overrideOutlineRadius ?? 8
172
195
  }
173
- );
196
+ ) : /* @__PURE__ */ jsx(BookmarkIndicatorComponent, { w: BOOKMARK_WIDTH, h: BOOKMARK_JUST_URL_HEIGHT });
174
197
  }
175
198
  getInterpolatedProps(startShape, endShape, t) {
176
199
  return {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/shapes/embed/EmbedShapeUtil.tsx"],
4
- "sourcesContent": ["/* eslint-disable react-hooks/rules-of-hooks */\n\nimport {\n\tBaseBoxShapeUtil,\n\tHTMLContainer,\n\tTLEmbedShape,\n\tTLEmbedShapeProps,\n\tTLResizeInfo,\n\tembedShapeMigrations,\n\tembedShapeProps,\n\tlerp,\n\tresizeBox,\n\ttoDomPrecision,\n\tuseIsEditing,\n\tuseSvgExportContext,\n\tuseValue,\n} from '@tldraw/editor'\n\nimport {\n\tDEFAULT_EMBED_DEFINITIONS,\n\tEmbedDefinition,\n\tTLEmbedDefinition,\n\tTLEmbedShapePermissions,\n\tembedShapePermissionDefaults,\n} from '../../defaultEmbedDefinitions'\nimport { TLEmbedResult, getEmbedInfo } from '../../utils/embeds/embeds'\nimport { getRotatedBoxShadow } from '../shared/rotated-box-shadow'\n\nconst getSandboxPermissions = (permissions: TLEmbedShapePermissions) => {\n\treturn Object.entries(permissions)\n\t\t.filter(([_perm, isEnabled]) => isEnabled)\n\t\t.map(([perm]) => perm)\n\t\t.join(' ')\n}\n\n/** @public */\nexport class EmbedShapeUtil extends BaseBoxShapeUtil<TLEmbedShape> {\n\tstatic override type = 'embed' as const\n\tstatic override props = embedShapeProps\n\tstatic override migrations = embedShapeMigrations\n\tprivate static embedDefinitions: readonly EmbedDefinition[] = DEFAULT_EMBED_DEFINITIONS\n\n\tstatic setEmbedDefinitions(embedDefinitions: readonly TLEmbedDefinition[]) {\n\t\tEmbedShapeUtil.embedDefinitions = embedDefinitions\n\t}\n\n\tgetEmbedDefinitions(): readonly TLEmbedDefinition[] {\n\t\treturn EmbedShapeUtil.embedDefinitions\n\t}\n\n\tgetEmbedDefinition(url: string): TLEmbedResult {\n\t\treturn getEmbedInfo(EmbedShapeUtil.embedDefinitions, url)\n\t}\n\n\toverride getText(shape: TLEmbedShape) {\n\t\treturn shape.props.url\n\t}\n\n\toverride getAriaDescriptor(shape: TLEmbedShape) {\n\t\tconst embedInfo = this.getEmbedDefinition(shape.props.url)\n\t\treturn embedInfo?.definition.title\n\t}\n\n\toverride hideSelectionBoundsFg(shape: TLEmbedShape) {\n\t\treturn !this.canResize(shape)\n\t}\n\toverride canEdit() {\n\t\treturn true\n\t}\n\toverride canResize(shape: TLEmbedShape) {\n\t\treturn !!this.getEmbedDefinition(shape.props.url)?.definition?.doesResize\n\t}\n\toverride canEditInReadonly() {\n\t\treturn true\n\t}\n\n\toverride getDefaultProps(): TLEmbedShape['props'] {\n\t\treturn {\n\t\t\tw: 300,\n\t\t\th: 300,\n\t\t\turl: '',\n\t\t}\n\t}\n\n\toverride isAspectRatioLocked(shape: TLEmbedShape) {\n\t\tconst embedInfo = this.getEmbedDefinition(shape.props.url)\n\t\treturn embedInfo?.definition.isAspectRatioLocked ?? false\n\t}\n\n\toverride onResize(shape: TLEmbedShape, info: TLResizeInfo<TLEmbedShape>) {\n\t\tconst isAspectRatioLocked = this.isAspectRatioLocked(shape)\n\t\tconst embedInfo = this.getEmbedDefinition(shape.props.url)\n\t\tlet minWidth = embedInfo?.definition.minWidth ?? 200\n\t\tlet minHeight = embedInfo?.definition.minHeight ?? 200\n\t\tif (isAspectRatioLocked) {\n\t\t\t// Enforce aspect ratio\n\t\t\t// Neither the width or height can be less than 200\n\t\t\tconst aspectRatio = shape.props.w / shape.props.h\n\t\t\tif (aspectRatio > 1) {\n\t\t\t\t// Landscape\n\t\t\t\tminWidth *= aspectRatio\n\t\t\t} else {\n\t\t\t\t// Portrait\n\t\t\t\tminHeight /= aspectRatio\n\t\t\t}\n\t\t}\n\n\t\treturn resizeBox(shape, info, { minWidth, minHeight })\n\t}\n\n\toverride component(shape: TLEmbedShape) {\n\t\tconst svgExport = useSvgExportContext()\n\t\tconst { w, h, url } = shape.props\n\t\tconst isEditing = useIsEditing(shape.id)\n\n\t\tconst embedInfo = this.getEmbedDefinition(url)\n\n\t\tconst isHoveringWhileEditingSameShape = useValue(\n\t\t\t'is hovering',\n\t\t\t() => {\n\t\t\t\tconst { editingShapeId, hoveredShapeId } = this.editor.getCurrentPageState()\n\n\t\t\t\tif (editingShapeId && hoveredShapeId !== editingShapeId) {\n\t\t\t\t\tconst editingShape = this.editor.getShape(editingShapeId)\n\t\t\t\t\tif (editingShape && this.editor.isShapeOfType<TLEmbedShape>(editingShape, 'embed')) {\n\t\t\t\t\t\treturn true\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn false\n\t\t\t},\n\t\t\t[]\n\t\t)\n\n\t\tconst pageRotation = this.editor.getShapePageTransform(shape)!.rotation()\n\n\t\tif (svgExport) {\n\t\t\t// for SVG exports, we show a blank embed\n\t\t\treturn (\n\t\t\t\t<HTMLContainer className=\"tl-embed-container\" id={shape.id}>\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName=\"tl-embed\"\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tborder: 0,\n\t\t\t\t\t\t\tboxShadow: getRotatedBoxShadow(pageRotation),\n\t\t\t\t\t\t\tborderRadius: embedInfo?.definition.overrideOutlineRadius ?? 8,\n\t\t\t\t\t\t\tbackground: embedInfo?.definition.backgroundColor ?? 'var(--tl-color-background)',\n\t\t\t\t\t\t\twidth: w,\n\t\t\t\t\t\t\theight: h,\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t</HTMLContainer>\n\t\t\t)\n\t\t}\n\n\t\tconst isInteractive = isEditing || isHoveringWhileEditingSameShape\n\n\t\t// Prevent nested embedding of tldraw\n\t\tconst isIframe =\n\t\t\ttypeof window !== 'undefined' && (window !== window.top || window.self !== window.parent)\n\t\tif (isIframe && embedInfo?.definition.type === 'tldraw') return null\n\n\t\tif (embedInfo?.definition.type === 'github_gist') {\n\t\t\tconst idFromGistUrl = embedInfo.url.split('/').pop()\n\t\t\tif (!idFromGistUrl) throw Error('No gist id!')\n\n\t\t\treturn (\n\t\t\t\t<HTMLContainer className=\"tl-embed-container\" id={shape.id}>\n\t\t\t\t\t<Gist\n\t\t\t\t\t\tid={idFromGistUrl}\n\t\t\t\t\t\twidth={toDomPrecision(w)!}\n\t\t\t\t\t\theight={toDomPrecision(h)!}\n\t\t\t\t\t\tisInteractive={isInteractive}\n\t\t\t\t\t\tpageRotation={pageRotation}\n\t\t\t\t\t/>\n\t\t\t\t</HTMLContainer>\n\t\t\t)\n\t\t}\n\n\t\tconst sandbox = getSandboxPermissions({\n\t\t\t...embedShapePermissionDefaults,\n\t\t\t...(embedInfo?.definition.overridePermissions ?? {}),\n\t\t})\n\n\t\treturn (\n\t\t\t<HTMLContainer className=\"tl-embed-container\" id={shape.id}>\n\t\t\t\t{embedInfo?.definition ? (\n\t\t\t\t\t<iframe\n\t\t\t\t\t\tclassName=\"tl-embed\"\n\t\t\t\t\t\tsandbox={sandbox}\n\t\t\t\t\t\tsrc={embedInfo.embedUrl}\n\t\t\t\t\t\twidth={toDomPrecision(w)}\n\t\t\t\t\t\theight={toDomPrecision(h)}\n\t\t\t\t\t\tdraggable={false}\n\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\t\t\t\tframeBorder=\"0\"\n\t\t\t\t\t\treferrerPolicy=\"no-referrer-when-downgrade\"\n\t\t\t\t\t\ttabIndex={isEditing ? 0 : -1}\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tborder: 0,\n\t\t\t\t\t\t\tpointerEvents: isInteractive ? 'auto' : 'none',\n\t\t\t\t\t\t\t// Fix for safari <https://stackoverflow.com/a/49150908>\n\t\t\t\t\t\t\tzIndex: isInteractive ? '' : '-1',\n\t\t\t\t\t\t\tboxShadow: getRotatedBoxShadow(pageRotation),\n\t\t\t\t\t\t\tborderRadius: embedInfo?.definition.overrideOutlineRadius ?? 8,\n\t\t\t\t\t\t\tbackground: embedInfo?.definition.backgroundColor,\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t) : null}\n\t\t\t</HTMLContainer>\n\t\t)\n\t}\n\n\toverride indicator(shape: TLEmbedShape) {\n\t\tconst embedInfo = this.getEmbedDefinition(shape.props.url)\n\t\treturn (\n\t\t\t<rect\n\t\t\t\twidth={toDomPrecision(shape.props.w)}\n\t\t\t\theight={toDomPrecision(shape.props.h)}\n\t\t\t\trx={embedInfo?.definition.overrideOutlineRadius ?? 8}\n\t\t\t\try={embedInfo?.definition.overrideOutlineRadius ?? 8}\n\t\t\t/>\n\t\t)\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLEmbedShape,\n\t\tendShape: TLEmbedShape,\n\t\tt: number\n\t): TLEmbedShapeProps {\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\tw: lerp(startShape.props.w, endShape.props.w, t),\n\t\t\th: lerp(startShape.props.h, endShape.props.h, t),\n\t\t}\n\t}\n}\n\nfunction Gist({\n\tid,\n\tisInteractive,\n\twidth,\n\theight,\n\tstyle,\n\tpageRotation,\n}: {\n\tid: string\n\tisInteractive: boolean\n\twidth: number\n\theight: number\n\tpageRotation: number\n\tstyle?: React.CSSProperties\n}) {\n\t// Security warning:\n\t// Gists allow adding .json extensions to the URL which return JSONP.\n\t// Furthermore, the JSONP can include callbacks that execute arbitrary JavaScript.\n\t// It _is_ sandboxed by the iframe but we still want to disable it nonetheless.\n\t// We restrict the id to only allow hexdecimal characters to prevent this.\n\t// Read more:\n\t// https://github.com/bhaveshk90/Content-Security-Policy-CSP-Bypass-Techniques\n\t// https://github.com/renniepak/CSPBypass\n\tif (!id.match(/^[0-9a-f]+$/)) throw Error('No gist id!')\n\n\treturn (\n\t\t<iframe\n\t\t\tclassName=\"tl-embed\"\n\t\t\tdraggable={false}\n\t\t\twidth={toDomPrecision(width)}\n\t\t\theight={toDomPrecision(height)}\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\tframeBorder=\"0\"\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\tscrolling=\"no\"\n\t\t\treferrerPolicy=\"no-referrer-when-downgrade\"\n\t\t\ttabIndex={isInteractive ? 0 : -1}\n\t\t\tstyle={{\n\t\t\t\t...style,\n\t\t\t\tpointerEvents: isInteractive ? 'all' : 'none',\n\t\t\t\t// Fix for safari <https://stackoverflow.com/a/49150908>\n\t\t\t\tzIndex: isInteractive ? '' : '-1',\n\t\t\t\tboxShadow: getRotatedBoxShadow(pageRotation),\n\t\t\t}}\n\t\t\tsrcDoc={`\n\t\t\t<html>\n\t\t\t\t<head>\n\t\t\t\t\t<base target=\"_blank\">\n\t\t\t\t</head>\n\t\t\t\t<body>\n\t\t\t\t\t<script src=${`https://gist.github.com/${id}.js`}></script>\n\t\t\t\t\t<style type=\"text/css\">\n\t\t\t\t\t\t* { margin: 0px; }\n\t\t\t\t\t\ttable { height: 100%; background-color: red; }\n\t\t\t\t\t\t.gist { background-color: none; height: 100%; }\n\t\t\t\t\t\t.gist .gist-file { height: calc(100vh - 2px); padding: 0px; display: grid; grid-template-rows: 1fr auto; }\n\t\t\t\t\t</style>\n\t\t\t\t</body>\n\t\t\t</html>`}\n\t\t/>\n\t)\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/* eslint-disable react-hooks/rules-of-hooks */\n\nimport {\n\tBaseBoxShapeUtil,\n\tHTMLContainer,\n\tRectangle2d,\n\tTLEmbedShape,\n\tTLEmbedShapeProps,\n\tTLResizeInfo,\n\tembedShapeMigrations,\n\tembedShapeProps,\n\tlerp,\n\tresizeBox,\n\ttoDomPrecision,\n\tuseIsEditing,\n\tuseSvgExportContext,\n\tuseValue,\n} from '@tldraw/editor'\n\nimport {\n\tDEFAULT_EMBED_DEFINITIONS,\n\tEmbedDefinition,\n\tTLEmbedDefinition,\n\tTLEmbedShapePermissions,\n\tembedShapePermissionDefaults,\n} from '../../defaultEmbedDefinitions'\nimport { TLEmbedResult, getEmbedInfo } from '../../utils/embeds/embeds'\nimport { BookmarkIndicatorComponent, BookmarkShapeComponent } from '../bookmark/BookmarkShapeUtil'\nimport { BOOKMARK_JUST_URL_HEIGHT, BOOKMARK_WIDTH } from '../bookmark/bookmarks'\nimport { getRotatedBoxShadow } from '../shared/rotated-box-shadow'\n\nconst getSandboxPermissions = (permissions: TLEmbedShapePermissions) => {\n\treturn Object.entries(permissions)\n\t\t.filter(([_perm, isEnabled]) => isEnabled)\n\t\t.map(([perm]) => perm)\n\t\t.join(' ')\n}\n\n/** @public */\nexport class EmbedShapeUtil extends BaseBoxShapeUtil<TLEmbedShape> {\n\tstatic override type = 'embed' as const\n\tstatic override props = embedShapeProps\n\tstatic override migrations = embedShapeMigrations\n\tprivate static embedDefinitions: readonly EmbedDefinition[] = DEFAULT_EMBED_DEFINITIONS\n\n\tstatic setEmbedDefinitions(embedDefinitions: readonly TLEmbedDefinition[]) {\n\t\tEmbedShapeUtil.embedDefinitions = embedDefinitions\n\t}\n\n\tgetEmbedDefinitions(): readonly TLEmbedDefinition[] {\n\t\treturn EmbedShapeUtil.embedDefinitions\n\t}\n\n\tgetEmbedDefinition(url: string): TLEmbedResult {\n\t\treturn getEmbedInfo(EmbedShapeUtil.embedDefinitions, url)\n\t}\n\n\toverride getText(shape: TLEmbedShape) {\n\t\treturn shape.props.url\n\t}\n\n\toverride getAriaDescriptor(shape: TLEmbedShape) {\n\t\tconst embedInfo = this.getEmbedDefinition(shape.props.url)\n\t\treturn embedInfo?.definition.title\n\t}\n\n\toverride hideSelectionBoundsFg(shape: TLEmbedShape) {\n\t\treturn !this.canResize(shape)\n\t}\n\toverride canEdit() {\n\t\treturn true\n\t}\n\toverride canResize(shape: TLEmbedShape) {\n\t\treturn !!this.getEmbedDefinition(shape.props.url)?.definition?.doesResize\n\t}\n\toverride canEditInReadonly() {\n\t\treturn true\n\t}\n\n\toverride getDefaultProps(): TLEmbedShape['props'] {\n\t\treturn {\n\t\t\tw: 300,\n\t\t\th: 300,\n\t\t\turl: '',\n\t\t}\n\t}\n\n\toverride getGeometry(shape: TLEmbedShape) {\n\t\tconst embedInfo = this.getEmbedDefinition(shape.props.url)\n\t\tif (!embedInfo?.definition) {\n\t\t\treturn new Rectangle2d({\n\t\t\t\twidth: BOOKMARK_WIDTH,\n\t\t\t\theight: BOOKMARK_JUST_URL_HEIGHT,\n\t\t\t\tisFilled: true,\n\t\t\t})\n\t\t}\n\t\treturn super.getGeometry(shape)\n\t}\n\n\toverride isAspectRatioLocked(shape: TLEmbedShape) {\n\t\tconst embedInfo = this.getEmbedDefinition(shape.props.url)\n\t\treturn embedInfo?.definition.isAspectRatioLocked ?? false\n\t}\n\n\toverride onResize(shape: TLEmbedShape, info: TLResizeInfo<TLEmbedShape>) {\n\t\tconst isAspectRatioLocked = this.isAspectRatioLocked(shape)\n\t\tconst embedInfo = this.getEmbedDefinition(shape.props.url)\n\t\tlet minWidth = embedInfo?.definition.minWidth ?? 200\n\t\tlet minHeight = embedInfo?.definition.minHeight ?? 200\n\t\tif (isAspectRatioLocked) {\n\t\t\t// Enforce aspect ratio\n\t\t\t// Neither the width or height can be less than 200\n\t\t\tconst aspectRatio = shape.props.w / shape.props.h\n\t\t\tif (aspectRatio > 1) {\n\t\t\t\t// Landscape\n\t\t\t\tminWidth *= aspectRatio\n\t\t\t} else {\n\t\t\t\t// Portrait\n\t\t\t\tminHeight /= aspectRatio\n\t\t\t}\n\t\t}\n\n\t\treturn resizeBox(shape, info, { minWidth, minHeight })\n\t}\n\n\toverride component(shape: TLEmbedShape) {\n\t\tconst svgExport = useSvgExportContext()\n\t\tconst { w, h, url } = shape.props\n\t\tconst isEditing = useIsEditing(shape.id)\n\n\t\tconst embedInfo = this.getEmbedDefinition(url)\n\n\t\tconst isHoveringWhileEditingSameShape = useValue(\n\t\t\t'is hovering',\n\t\t\t() => {\n\t\t\t\tconst { editingShapeId, hoveredShapeId } = this.editor.getCurrentPageState()\n\n\t\t\t\tif (editingShapeId && hoveredShapeId !== editingShapeId) {\n\t\t\t\t\tconst editingShape = this.editor.getShape(editingShapeId)\n\t\t\t\t\tif (editingShape && this.editor.isShapeOfType<TLEmbedShape>(editingShape, 'embed')) {\n\t\t\t\t\t\treturn true\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn false\n\t\t\t},\n\t\t\t[]\n\t\t)\n\n\t\tconst pageRotation = this.editor.getShapePageTransform(shape)!.rotation()\n\n\t\tif (svgExport) {\n\t\t\t// for SVG exports, we show a blank embed\n\t\t\treturn (\n\t\t\t\t<HTMLContainer className=\"tl-embed-container\" id={shape.id}>\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName=\"tl-embed\"\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tborder: 0,\n\t\t\t\t\t\t\tboxShadow: getRotatedBoxShadow(pageRotation),\n\t\t\t\t\t\t\tborderRadius: embedInfo?.definition.overrideOutlineRadius ?? 8,\n\t\t\t\t\t\t\tbackground: embedInfo?.definition.backgroundColor ?? 'var(--tl-color-background)',\n\t\t\t\t\t\t\twidth: w,\n\t\t\t\t\t\t\theight: h,\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t</HTMLContainer>\n\t\t\t)\n\t\t}\n\n\t\tconst isInteractive = isEditing || isHoveringWhileEditingSameShape\n\n\t\t// Prevent nested embedding of tldraw\n\t\tconst isIframe =\n\t\t\ttypeof window !== 'undefined' && (window !== window.top || window.self !== window.parent)\n\t\tif (isIframe && embedInfo?.definition.type === 'tldraw') return null\n\n\t\tif (embedInfo?.definition.type === 'github_gist') {\n\t\t\tconst idFromGistUrl = embedInfo.url.split('/').pop()\n\t\t\tif (!idFromGistUrl) throw Error('No gist id!')\n\n\t\t\treturn (\n\t\t\t\t<HTMLContainer className=\"tl-embed-container\" id={shape.id}>\n\t\t\t\t\t<Gist\n\t\t\t\t\t\tid={idFromGistUrl}\n\t\t\t\t\t\twidth={toDomPrecision(w)!}\n\t\t\t\t\t\theight={toDomPrecision(h)!}\n\t\t\t\t\t\tisInteractive={isInteractive}\n\t\t\t\t\t\tpageRotation={pageRotation}\n\t\t\t\t\t/>\n\t\t\t\t</HTMLContainer>\n\t\t\t)\n\t\t}\n\n\t\tconst sandbox = getSandboxPermissions({\n\t\t\t...embedShapePermissionDefaults,\n\t\t\t...(embedInfo?.definition.overridePermissions ?? {}),\n\t\t})\n\n\t\treturn (\n\t\t\t<HTMLContainer className=\"tl-embed-container\" id={shape.id}>\n\t\t\t\t{embedInfo?.definition ? (\n\t\t\t\t\t<iframe\n\t\t\t\t\t\tclassName=\"tl-embed\"\n\t\t\t\t\t\tsandbox={sandbox}\n\t\t\t\t\t\tsrc={embedInfo.embedUrl}\n\t\t\t\t\t\twidth={toDomPrecision(w)}\n\t\t\t\t\t\theight={toDomPrecision(h)}\n\t\t\t\t\t\tdraggable={false}\n\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\t\t\t\tframeBorder=\"0\"\n\t\t\t\t\t\treferrerPolicy=\"no-referrer-when-downgrade\"\n\t\t\t\t\t\ttabIndex={isEditing ? 0 : -1}\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tborder: 0,\n\t\t\t\t\t\t\tpointerEvents: isInteractive ? 'auto' : 'none',\n\t\t\t\t\t\t\t// Fix for safari <https://stackoverflow.com/a/49150908>\n\t\t\t\t\t\t\tzIndex: isInteractive ? '' : '-1',\n\t\t\t\t\t\t\tboxShadow: getRotatedBoxShadow(pageRotation),\n\t\t\t\t\t\t\tborderRadius: embedInfo?.definition.overrideOutlineRadius ?? 8,\n\t\t\t\t\t\t\tbackground: embedInfo?.definition.backgroundColor,\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t) : (\n\t\t\t\t\t<BookmarkShapeComponent\n\t\t\t\t\t\turl={url}\n\t\t\t\t\t\th={h}\n\t\t\t\t\t\trotation={pageRotation}\n\t\t\t\t\t\tassetId={null}\n\t\t\t\t\t\tshowImageContainer={false}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</HTMLContainer>\n\t\t)\n\t}\n\n\toverride indicator(shape: TLEmbedShape) {\n\t\tconst embedInfo = this.getEmbedDefinition(shape.props.url)\n\n\t\treturn embedInfo?.definition ? (\n\t\t\t<rect\n\t\t\t\twidth={toDomPrecision(shape.props.w)}\n\t\t\t\theight={toDomPrecision(shape.props.h)}\n\t\t\t\trx={embedInfo?.definition.overrideOutlineRadius ?? 8}\n\t\t\t\try={embedInfo?.definition.overrideOutlineRadius ?? 8}\n\t\t\t/>\n\t\t) : (\n\t\t\t<BookmarkIndicatorComponent w={BOOKMARK_WIDTH} h={BOOKMARK_JUST_URL_HEIGHT} />\n\t\t)\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLEmbedShape,\n\t\tendShape: TLEmbedShape,\n\t\tt: number\n\t): TLEmbedShapeProps {\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\tw: lerp(startShape.props.w, endShape.props.w, t),\n\t\t\th: lerp(startShape.props.h, endShape.props.h, t),\n\t\t}\n\t}\n}\n\nfunction Gist({\n\tid,\n\tisInteractive,\n\twidth,\n\theight,\n\tstyle,\n\tpageRotation,\n}: {\n\tid: string\n\tisInteractive: boolean\n\twidth: number\n\theight: number\n\tpageRotation: number\n\tstyle?: React.CSSProperties\n}) {\n\t// Security warning:\n\t// Gists allow adding .json extensions to the URL which return JSONP.\n\t// Furthermore, the JSONP can include callbacks that execute arbitrary JavaScript.\n\t// It _is_ sandboxed by the iframe but we still want to disable it nonetheless.\n\t// We restrict the id to only allow hexdecimal characters to prevent this.\n\t// Read more:\n\t// https://github.com/bhaveshk90/Content-Security-Policy-CSP-Bypass-Techniques\n\t// https://github.com/renniepak/CSPBypass\n\tif (!id.match(/^[0-9a-f]+$/)) throw Error('No gist id!')\n\n\treturn (\n\t\t<iframe\n\t\t\tclassName=\"tl-embed\"\n\t\t\tdraggable={false}\n\t\t\twidth={toDomPrecision(width)}\n\t\t\theight={toDomPrecision(height)}\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\tframeBorder=\"0\"\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\tscrolling=\"no\"\n\t\t\treferrerPolicy=\"no-referrer-when-downgrade\"\n\t\t\ttabIndex={isInteractive ? 0 : -1}\n\t\t\tstyle={{\n\t\t\t\t...style,\n\t\t\t\tpointerEvents: isInteractive ? 'all' : 'none',\n\t\t\t\t// Fix for safari <https://stackoverflow.com/a/49150908>\n\t\t\t\tzIndex: isInteractive ? '' : '-1',\n\t\t\t\tboxShadow: getRotatedBoxShadow(pageRotation),\n\t\t\t}}\n\t\t\tsrcDoc={`\n\t\t\t<html>\n\t\t\t\t<head>\n\t\t\t\t\t<base target=\"_blank\">\n\t\t\t\t</head>\n\t\t\t\t<body>\n\t\t\t\t\t<script src=${`https://gist.github.com/${id}.js`}></script>\n\t\t\t\t\t<style type=\"text/css\">\n\t\t\t\t\t\t* { margin: 0px; }\n\t\t\t\t\t\ttable { height: 100%; background-color: red; }\n\t\t\t\t\t\t.gist { background-color: none; height: 100%; }\n\t\t\t\t\t\t.gist .gist-file { height: calc(100vh - 2px); padding: 0px; display: grid; grid-template-rows: 1fr auto; }\n\t\t\t\t\t</style>\n\t\t\t\t</body>\n\t\t\t</html>`}\n\t\t/>\n\t)\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -38,6 +38,9 @@ class LineShapeUtil extends ShapeUtil {
38
38
  hideSelectionBoundsBg() {
39
39
  return true;
40
40
  }
41
+ hideInMinimap() {
42
+ return true;
43
+ }
41
44
  getDefaultProps() {
42
45
  const [start, end] = getIndices(2);
43
46
  return {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/shapes/line/LineShapeUtil.tsx"],
4
- "sourcesContent": ["import {\n\tGroup2d,\n\tHandleSnapGeometry,\n\tSVGContainer,\n\tShapeUtil,\n\tTLHandle,\n\tTLHandleDragInfo,\n\tTLLineShape,\n\tTLLineShapePoint,\n\tTLResizeInfo,\n\tVec,\n\tWeakCache,\n\tZERO_INDEX_KEY,\n\tassert,\n\tgetColorValue,\n\tgetIndexAbove,\n\tgetIndexBetween,\n\tgetIndices,\n\tlerp,\n\tlineShapeMigrations,\n\tlineShapeProps,\n\tmapObjectMapValues,\n\tmaybeSnapToGrid,\n\tsortByIndex,\n} from '@tldraw/editor'\n\nimport { STROKE_SIZES } from '../arrow/shared'\nimport { PathBuilder, PathBuilderGeometry2d } from '../shared/PathBuilder'\nimport { useDefaultColorTheme } from '../shared/useDefaultColorTheme'\n\nconst handlesCache = new WeakCache<TLLineShape['props'], TLHandle[]>()\n\n/** @public */\nexport class LineShapeUtil extends ShapeUtil<TLLineShape> {\n\tstatic override type = 'line' as const\n\tstatic override props = lineShapeProps\n\tstatic override migrations = lineShapeMigrations\n\n\toverride hideResizeHandles() {\n\t\treturn true\n\t}\n\toverride hideRotateHandle() {\n\t\treturn true\n\t}\n\toverride hideSelectionBoundsFg() {\n\t\treturn true\n\t}\n\toverride hideSelectionBoundsBg() {\n\t\treturn true\n\t}\n\n\toverride getDefaultProps(): TLLineShape['props'] {\n\t\tconst [start, end] = getIndices(2)\n\t\treturn {\n\t\t\tdash: 'draw',\n\t\t\tsize: 'm',\n\t\t\tcolor: 'black',\n\t\t\tspline: 'line',\n\t\t\tpoints: {\n\t\t\t\t[start]: { id: start, index: start, x: 0, y: 0 },\n\t\t\t\t[end]: { id: end, index: end, x: 0.1, y: 0.1 },\n\t\t\t},\n\t\t\tscale: 1,\n\t\t}\n\t}\n\n\tgetGeometry(shape: TLLineShape) {\n\t\t// todo: should we have min size?\n\t\tconst geometry = getPathForLineShape(shape).toGeometry()\n\t\tassert(geometry instanceof PathBuilderGeometry2d)\n\t\treturn geometry\n\t}\n\n\toverride getHandles(shape: TLLineShape) {\n\t\treturn handlesCache.get(shape.props, () => {\n\t\t\tconst spline = this.getGeometry(shape)\n\n\t\t\tconst points = linePointsToArray(shape)\n\t\t\tconst results: TLHandle[] = points.map((point) => ({\n\t\t\t\t...point,\n\t\t\t\tid: point.index,\n\t\t\t\ttype: 'vertex',\n\t\t\t\tcanSnap: true,\n\t\t\t}))\n\n\t\t\tfor (let i = 0; i < points.length - 1; i++) {\n\t\t\t\tconst index = getIndexBetween(points[i].index, points[i + 1].index)\n\t\t\t\tconst segment = spline.getSegments()[i]\n\t\t\t\tconst point = segment.interpolateAlongEdge(0.5)\n\t\t\t\tresults.push({\n\t\t\t\t\tid: index,\n\t\t\t\t\ttype: 'create',\n\t\t\t\t\tindex,\n\t\t\t\t\tx: point.x,\n\t\t\t\t\ty: point.y,\n\t\t\t\t\tcanSnap: true,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\treturn results.sort(sortByIndex)\n\t\t})\n\t}\n\n\t// Events\n\n\toverride onResize(shape: TLLineShape, info: TLResizeInfo<TLLineShape>) {\n\t\tconst { scaleX, scaleY } = info\n\n\t\treturn {\n\t\t\tprops: {\n\t\t\t\tpoints: mapObjectMapValues(shape.props.points, (_, { id, index, x, y }) => ({\n\t\t\t\t\tid,\n\t\t\t\t\tindex,\n\t\t\t\t\tx: x * scaleX,\n\t\t\t\t\ty: y * scaleY,\n\t\t\t\t})),\n\t\t\t},\n\t\t}\n\t}\n\n\toverride onBeforeCreate(next: TLLineShape): void | TLLineShape {\n\t\tconst {\n\t\t\tprops: { points },\n\t\t} = next\n\t\tconst pointKeys = Object.keys(points)\n\n\t\tif (pointKeys.length < 2) {\n\t\t\treturn\n\t\t}\n\n\t\tconst firstPoint = points[pointKeys[0]]\n\t\tconst allSame = pointKeys.every((key) => {\n\t\t\tconst point = points[key]\n\t\t\treturn point.x === firstPoint.x && point.y === firstPoint.y\n\t\t})\n\t\tif (allSame) {\n\t\t\tconst lastKey = pointKeys[pointKeys.length - 1]\n\t\t\tpoints[lastKey] = {\n\t\t\t\t...points[lastKey],\n\t\t\t\tx: points[lastKey].x + 0.1,\n\t\t\t\ty: points[lastKey].y + 0.1,\n\t\t\t}\n\t\t\treturn next\n\t\t}\n\t\treturn\n\t}\n\n\toverride onHandleDrag(shape: TLLineShape, { handle }: TLHandleDragInfo<TLLineShape>) {\n\t\tconst newPoint = maybeSnapToGrid(new Vec(handle.x, handle.y), this.editor)\n\t\treturn {\n\t\t\t...shape,\n\t\t\tprops: {\n\t\t\t\t...shape.props,\n\t\t\t\tpoints: {\n\t\t\t\t\t...shape.props.points,\n\t\t\t\t\t[handle.id]: { id: handle.id, index: handle.index, x: newPoint.x, y: newPoint.y },\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t}\n\n\toverride onHandleDragStart(shape: TLLineShape, { handle }: TLHandleDragInfo<TLLineShape>) {\n\t\t// For line shapes, if we're dragging a \"create\" handle, then\n\t\t// create a new vertex handle at that point; and make this handle\n\t\t// the handle that we're dragging.\n\t\tif (handle.type === 'create') {\n\t\t\treturn {\n\t\t\t\t...shape,\n\t\t\t\tprops: {\n\t\t\t\t\t...shape.props,\n\t\t\t\t\tpoints: {\n\t\t\t\t\t\t...shape.props.points,\n\t\t\t\t\t\t[handle.index]: { id: handle.index, index: handle.index, x: handle.x, y: handle.y },\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\t\treturn\n\t}\n\n\tcomponent(shape: TLLineShape) {\n\t\treturn (\n\t\t\t<SVGContainer style={{ minWidth: 50, minHeight: 50 }}>\n\t\t\t\t<LineShapeSvg shape={shape} />\n\t\t\t</SVGContainer>\n\t\t)\n\t}\n\n\tindicator(shape: TLLineShape) {\n\t\tconst strokeWidth = STROKE_SIZES[shape.props.size] * shape.props.scale\n\t\tconst path = getPathForLineShape(shape)\n\t\tconst { dash } = shape.props\n\n\t\treturn path.toSvg({\n\t\t\tstyle: dash === 'draw' ? 'draw' : 'solid',\n\t\t\tstrokeWidth: 1,\n\t\t\tpasses: 1,\n\t\t\trandomSeed: shape.id,\n\t\t\toffset: 0,\n\t\t\troundness: strokeWidth * 2,\n\t\t\tprops: { strokeWidth: undefined },\n\t\t})\n\t}\n\n\toverride toSvg(shape: TLLineShape) {\n\t\treturn <LineShapeSvg shouldScale shape={shape} />\n\t}\n\n\toverride getHandleSnapGeometry(shape: TLLineShape): HandleSnapGeometry {\n\t\tconst points = linePointsToArray(shape)\n\t\treturn {\n\t\t\tpoints,\n\t\t\tgetSelfSnapPoints: (handle) => {\n\t\t\t\tconst index = this.getHandles(shape)\n\t\t\t\t\t.filter((h) => h.type === 'vertex')\n\t\t\t\t\t.findIndex((h) => h.id === handle.id)!\n\n\t\t\t\t// We want to skip the current and adjacent handles\n\t\t\t\treturn points.filter((_, i) => Math.abs(i - index) > 1).map(Vec.From)\n\t\t\t},\n\t\t\tgetSelfSnapOutline: (handle) => {\n\t\t\t\t// We want to skip the segments that include the handle, so\n\t\t\t\t// find the index of the handle that shares the same index property\n\t\t\t\t// as the initial dragging handle; this catches a quirk of create handles\n\t\t\t\tconst index = this.getHandles(shape)\n\t\t\t\t\t.filter((h) => h.type === 'vertex')\n\t\t\t\t\t.findIndex((h) => h.id === handle.id)!\n\n\t\t\t\t// Get all the outline segments from the shape that don't include the handle\n\t\t\t\tconst segments = this.getGeometry(shape)\n\t\t\t\t\t.getSegments()\n\t\t\t\t\t.filter((_, i) => i !== index - 1 && i !== index)\n\n\t\t\t\tif (!segments.length) return null\n\t\t\t\treturn new Group2d({ children: segments })\n\t\t\t},\n\t\t}\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLLineShape,\n\t\tendShape: TLLineShape,\n\t\tt: number\n\t): TLLineShape['props'] {\n\t\tconst startPoints = linePointsToArray(startShape)\n\t\tconst endPoints = linePointsToArray(endShape)\n\n\t\tconst pointsToUseStart: TLLineShapePoint[] = []\n\t\tconst pointsToUseEnd: TLLineShapePoint[] = []\n\n\t\tlet index = ZERO_INDEX_KEY\n\n\t\tif (startPoints.length > endPoints.length) {\n\t\t\t// we'll need to expand points\n\t\t\tfor (let i = 0; i < startPoints.length; i++) {\n\t\t\t\tpointsToUseStart[i] = { ...startPoints[i] }\n\t\t\t\tif (endPoints[i] === undefined) {\n\t\t\t\t\tpointsToUseEnd[i] = { ...endPoints[endPoints.length - 1], id: index }\n\t\t\t\t} else {\n\t\t\t\t\tpointsToUseEnd[i] = { ...endPoints[i], id: index }\n\t\t\t\t}\n\t\t\t\tindex = getIndexAbove(index)\n\t\t\t}\n\t\t} else if (endPoints.length > startPoints.length) {\n\t\t\t// we'll need to converge points\n\t\t\tfor (let i = 0; i < endPoints.length; i++) {\n\t\t\t\tpointsToUseEnd[i] = { ...endPoints[i] }\n\t\t\t\tif (startPoints[i] === undefined) {\n\t\t\t\t\tpointsToUseStart[i] = {\n\t\t\t\t\t\t...startPoints[startPoints.length - 1],\n\t\t\t\t\t\tid: index,\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tpointsToUseStart[i] = { ...startPoints[i], id: index }\n\t\t\t\t}\n\t\t\t\tindex = getIndexAbove(index)\n\t\t\t}\n\t\t} else {\n\t\t\t// noop, easy\n\t\t\tfor (let i = 0; i < endPoints.length; i++) {\n\t\t\t\tpointsToUseStart[i] = startPoints[i]\n\t\t\t\tpointsToUseEnd[i] = endPoints[i]\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\tpoints: Object.fromEntries(\n\t\t\t\tpointsToUseStart.map((point, i) => {\n\t\t\t\t\tconst endPoint = pointsToUseEnd[i]\n\t\t\t\t\treturn [\n\t\t\t\t\t\tpoint.id,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t...point,\n\t\t\t\t\t\t\tx: lerp(point.x, endPoint.x, t),\n\t\t\t\t\t\t\ty: lerp(point.y, endPoint.y, t),\n\t\t\t\t\t\t},\n\t\t\t\t\t]\n\t\t\t\t})\n\t\t\t),\n\t\t\tscale: lerp(startShape.props.scale, endShape.props.scale, t),\n\t\t}\n\t}\n}\n\nfunction linePointsToArray(shape: TLLineShape) {\n\treturn Object.values(shape.props.points).sort(sortByIndex)\n}\n\nconst pathCache = new WeakCache<TLLineShape, PathBuilder>()\nfunction getPathForLineShape(shape: TLLineShape): PathBuilder {\n\treturn pathCache.get(shape, () => {\n\t\tconst points = linePointsToArray(shape).map(Vec.From)\n\n\t\tswitch (shape.props.spline) {\n\t\t\tcase 'cubic': {\n\t\t\t\treturn PathBuilder.cubicSplineThroughPoints(points, { endOffsets: 0 })\n\t\t\t}\n\t\t\tcase 'line': {\n\t\t\t\treturn PathBuilder.lineThroughPoints(points, { endOffsets: 0 })\n\t\t\t}\n\t\t}\n\t})\n}\n\nfunction LineShapeSvg({\n\tshape,\n\tshouldScale = false,\n\tforceSolid = false,\n}: {\n\tshape: TLLineShape\n\tshouldScale?: boolean\n\tforceSolid?: boolean\n}) {\n\tconst theme = useDefaultColorTheme()\n\n\tconst path = getPathForLineShape(shape)\n\tconst { dash, color, size } = shape.props\n\n\tconst scaleFactor = 1 / shape.props.scale\n\n\tconst scale = shouldScale ? scaleFactor : 1\n\n\tconst strokeWidth = STROKE_SIZES[size] * shape.props.scale\n\n\treturn path.toSvg({\n\t\tstyle: dash,\n\t\tstrokeWidth,\n\t\tforceSolid,\n\t\trandomSeed: shape.id,\n\t\tprops: {\n\t\t\ttransform: `scale(${scale})`,\n\t\t\tstroke: getColorValue(theme, color, 'solid'),\n\t\t\tfill: 'none',\n\t\t},\n\t})\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n\tGroup2d,\n\tHandleSnapGeometry,\n\tSVGContainer,\n\tShapeUtil,\n\tTLHandle,\n\tTLHandleDragInfo,\n\tTLLineShape,\n\tTLLineShapePoint,\n\tTLResizeInfo,\n\tVec,\n\tWeakCache,\n\tZERO_INDEX_KEY,\n\tassert,\n\tgetColorValue,\n\tgetIndexAbove,\n\tgetIndexBetween,\n\tgetIndices,\n\tlerp,\n\tlineShapeMigrations,\n\tlineShapeProps,\n\tmapObjectMapValues,\n\tmaybeSnapToGrid,\n\tsortByIndex,\n} from '@tldraw/editor'\n\nimport { STROKE_SIZES } from '../arrow/shared'\nimport { PathBuilder, PathBuilderGeometry2d } from '../shared/PathBuilder'\nimport { useDefaultColorTheme } from '../shared/useDefaultColorTheme'\n\nconst handlesCache = new WeakCache<TLLineShape['props'], TLHandle[]>()\n\n/** @public */\nexport class LineShapeUtil extends ShapeUtil<TLLineShape> {\n\tstatic override type = 'line' as const\n\tstatic override props = lineShapeProps\n\tstatic override migrations = lineShapeMigrations\n\n\toverride hideResizeHandles() {\n\t\treturn true\n\t}\n\toverride hideRotateHandle() {\n\t\treturn true\n\t}\n\toverride hideSelectionBoundsFg() {\n\t\treturn true\n\t}\n\toverride hideSelectionBoundsBg() {\n\t\treturn true\n\t}\n\toverride hideInMinimap() {\n\t\treturn true\n\t}\n\n\toverride getDefaultProps(): TLLineShape['props'] {\n\t\tconst [start, end] = getIndices(2)\n\t\treturn {\n\t\t\tdash: 'draw',\n\t\t\tsize: 'm',\n\t\t\tcolor: 'black',\n\t\t\tspline: 'line',\n\t\t\tpoints: {\n\t\t\t\t[start]: { id: start, index: start, x: 0, y: 0 },\n\t\t\t\t[end]: { id: end, index: end, x: 0.1, y: 0.1 },\n\t\t\t},\n\t\t\tscale: 1,\n\t\t}\n\t}\n\n\tgetGeometry(shape: TLLineShape) {\n\t\t// todo: should we have min size?\n\t\tconst geometry = getPathForLineShape(shape).toGeometry()\n\t\tassert(geometry instanceof PathBuilderGeometry2d)\n\t\treturn geometry\n\t}\n\n\toverride getHandles(shape: TLLineShape) {\n\t\treturn handlesCache.get(shape.props, () => {\n\t\t\tconst spline = this.getGeometry(shape)\n\n\t\t\tconst points = linePointsToArray(shape)\n\t\t\tconst results: TLHandle[] = points.map((point) => ({\n\t\t\t\t...point,\n\t\t\t\tid: point.index,\n\t\t\t\ttype: 'vertex',\n\t\t\t\tcanSnap: true,\n\t\t\t}))\n\n\t\t\tfor (let i = 0; i < points.length - 1; i++) {\n\t\t\t\tconst index = getIndexBetween(points[i].index, points[i + 1].index)\n\t\t\t\tconst segment = spline.getSegments()[i]\n\t\t\t\tconst point = segment.interpolateAlongEdge(0.5)\n\t\t\t\tresults.push({\n\t\t\t\t\tid: index,\n\t\t\t\t\ttype: 'create',\n\t\t\t\t\tindex,\n\t\t\t\t\tx: point.x,\n\t\t\t\t\ty: point.y,\n\t\t\t\t\tcanSnap: true,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\treturn results.sort(sortByIndex)\n\t\t})\n\t}\n\n\t// Events\n\n\toverride onResize(shape: TLLineShape, info: TLResizeInfo<TLLineShape>) {\n\t\tconst { scaleX, scaleY } = info\n\n\t\treturn {\n\t\t\tprops: {\n\t\t\t\tpoints: mapObjectMapValues(shape.props.points, (_, { id, index, x, y }) => ({\n\t\t\t\t\tid,\n\t\t\t\t\tindex,\n\t\t\t\t\tx: x * scaleX,\n\t\t\t\t\ty: y * scaleY,\n\t\t\t\t})),\n\t\t\t},\n\t\t}\n\t}\n\n\toverride onBeforeCreate(next: TLLineShape): void | TLLineShape {\n\t\tconst {\n\t\t\tprops: { points },\n\t\t} = next\n\t\tconst pointKeys = Object.keys(points)\n\n\t\tif (pointKeys.length < 2) {\n\t\t\treturn\n\t\t}\n\n\t\tconst firstPoint = points[pointKeys[0]]\n\t\tconst allSame = pointKeys.every((key) => {\n\t\t\tconst point = points[key]\n\t\t\treturn point.x === firstPoint.x && point.y === firstPoint.y\n\t\t})\n\t\tif (allSame) {\n\t\t\tconst lastKey = pointKeys[pointKeys.length - 1]\n\t\t\tpoints[lastKey] = {\n\t\t\t\t...points[lastKey],\n\t\t\t\tx: points[lastKey].x + 0.1,\n\t\t\t\ty: points[lastKey].y + 0.1,\n\t\t\t}\n\t\t\treturn next\n\t\t}\n\t\treturn\n\t}\n\n\toverride onHandleDrag(shape: TLLineShape, { handle }: TLHandleDragInfo<TLLineShape>) {\n\t\tconst newPoint = maybeSnapToGrid(new Vec(handle.x, handle.y), this.editor)\n\t\treturn {\n\t\t\t...shape,\n\t\t\tprops: {\n\t\t\t\t...shape.props,\n\t\t\t\tpoints: {\n\t\t\t\t\t...shape.props.points,\n\t\t\t\t\t[handle.id]: { id: handle.id, index: handle.index, x: newPoint.x, y: newPoint.y },\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t}\n\n\toverride onHandleDragStart(shape: TLLineShape, { handle }: TLHandleDragInfo<TLLineShape>) {\n\t\t// For line shapes, if we're dragging a \"create\" handle, then\n\t\t// create a new vertex handle at that point; and make this handle\n\t\t// the handle that we're dragging.\n\t\tif (handle.type === 'create') {\n\t\t\treturn {\n\t\t\t\t...shape,\n\t\t\t\tprops: {\n\t\t\t\t\t...shape.props,\n\t\t\t\t\tpoints: {\n\t\t\t\t\t\t...shape.props.points,\n\t\t\t\t\t\t[handle.index]: { id: handle.index, index: handle.index, x: handle.x, y: handle.y },\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\t\treturn\n\t}\n\n\tcomponent(shape: TLLineShape) {\n\t\treturn (\n\t\t\t<SVGContainer style={{ minWidth: 50, minHeight: 50 }}>\n\t\t\t\t<LineShapeSvg shape={shape} />\n\t\t\t</SVGContainer>\n\t\t)\n\t}\n\n\tindicator(shape: TLLineShape) {\n\t\tconst strokeWidth = STROKE_SIZES[shape.props.size] * shape.props.scale\n\t\tconst path = getPathForLineShape(shape)\n\t\tconst { dash } = shape.props\n\n\t\treturn path.toSvg({\n\t\t\tstyle: dash === 'draw' ? 'draw' : 'solid',\n\t\t\tstrokeWidth: 1,\n\t\t\tpasses: 1,\n\t\t\trandomSeed: shape.id,\n\t\t\toffset: 0,\n\t\t\troundness: strokeWidth * 2,\n\t\t\tprops: { strokeWidth: undefined },\n\t\t})\n\t}\n\n\toverride toSvg(shape: TLLineShape) {\n\t\treturn <LineShapeSvg shouldScale shape={shape} />\n\t}\n\n\toverride getHandleSnapGeometry(shape: TLLineShape): HandleSnapGeometry {\n\t\tconst points = linePointsToArray(shape)\n\t\treturn {\n\t\t\tpoints,\n\t\t\tgetSelfSnapPoints: (handle) => {\n\t\t\t\tconst index = this.getHandles(shape)\n\t\t\t\t\t.filter((h) => h.type === 'vertex')\n\t\t\t\t\t.findIndex((h) => h.id === handle.id)!\n\n\t\t\t\t// We want to skip the current and adjacent handles\n\t\t\t\treturn points.filter((_, i) => Math.abs(i - index) > 1).map(Vec.From)\n\t\t\t},\n\t\t\tgetSelfSnapOutline: (handle) => {\n\t\t\t\t// We want to skip the segments that include the handle, so\n\t\t\t\t// find the index of the handle that shares the same index property\n\t\t\t\t// as the initial dragging handle; this catches a quirk of create handles\n\t\t\t\tconst index = this.getHandles(shape)\n\t\t\t\t\t.filter((h) => h.type === 'vertex')\n\t\t\t\t\t.findIndex((h) => h.id === handle.id)!\n\n\t\t\t\t// Get all the outline segments from the shape that don't include the handle\n\t\t\t\tconst segments = this.getGeometry(shape)\n\t\t\t\t\t.getSegments()\n\t\t\t\t\t.filter((_, i) => i !== index - 1 && i !== index)\n\n\t\t\t\tif (!segments.length) return null\n\t\t\t\treturn new Group2d({ children: segments })\n\t\t\t},\n\t\t}\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLLineShape,\n\t\tendShape: TLLineShape,\n\t\tt: number\n\t): TLLineShape['props'] {\n\t\tconst startPoints = linePointsToArray(startShape)\n\t\tconst endPoints = linePointsToArray(endShape)\n\n\t\tconst pointsToUseStart: TLLineShapePoint[] = []\n\t\tconst pointsToUseEnd: TLLineShapePoint[] = []\n\n\t\tlet index = ZERO_INDEX_KEY\n\n\t\tif (startPoints.length > endPoints.length) {\n\t\t\t// we'll need to expand points\n\t\t\tfor (let i = 0; i < startPoints.length; i++) {\n\t\t\t\tpointsToUseStart[i] = { ...startPoints[i] }\n\t\t\t\tif (endPoints[i] === undefined) {\n\t\t\t\t\tpointsToUseEnd[i] = { ...endPoints[endPoints.length - 1], id: index }\n\t\t\t\t} else {\n\t\t\t\t\tpointsToUseEnd[i] = { ...endPoints[i], id: index }\n\t\t\t\t}\n\t\t\t\tindex = getIndexAbove(index)\n\t\t\t}\n\t\t} else if (endPoints.length > startPoints.length) {\n\t\t\t// we'll need to converge points\n\t\t\tfor (let i = 0; i < endPoints.length; i++) {\n\t\t\t\tpointsToUseEnd[i] = { ...endPoints[i] }\n\t\t\t\tif (startPoints[i] === undefined) {\n\t\t\t\t\tpointsToUseStart[i] = {\n\t\t\t\t\t\t...startPoints[startPoints.length - 1],\n\t\t\t\t\t\tid: index,\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tpointsToUseStart[i] = { ...startPoints[i], id: index }\n\t\t\t\t}\n\t\t\t\tindex = getIndexAbove(index)\n\t\t\t}\n\t\t} else {\n\t\t\t// noop, easy\n\t\t\tfor (let i = 0; i < endPoints.length; i++) {\n\t\t\t\tpointsToUseStart[i] = startPoints[i]\n\t\t\t\tpointsToUseEnd[i] = endPoints[i]\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\tpoints: Object.fromEntries(\n\t\t\t\tpointsToUseStart.map((point, i) => {\n\t\t\t\t\tconst endPoint = pointsToUseEnd[i]\n\t\t\t\t\treturn [\n\t\t\t\t\t\tpoint.id,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t...point,\n\t\t\t\t\t\t\tx: lerp(point.x, endPoint.x, t),\n\t\t\t\t\t\t\ty: lerp(point.y, endPoint.y, t),\n\t\t\t\t\t\t},\n\t\t\t\t\t]\n\t\t\t\t})\n\t\t\t),\n\t\t\tscale: lerp(startShape.props.scale, endShape.props.scale, t),\n\t\t}\n\t}\n}\n\nfunction linePointsToArray(shape: TLLineShape) {\n\treturn Object.values(shape.props.points).sort(sortByIndex)\n}\n\nconst pathCache = new WeakCache<TLLineShape, PathBuilder>()\nfunction getPathForLineShape(shape: TLLineShape): PathBuilder {\n\treturn pathCache.get(shape, () => {\n\t\tconst points = linePointsToArray(shape).map(Vec.From)\n\n\t\tswitch (shape.props.spline) {\n\t\t\tcase 'cubic': {\n\t\t\t\treturn PathBuilder.cubicSplineThroughPoints(points, { endOffsets: 0 })\n\t\t\t}\n\t\t\tcase 'line': {\n\t\t\t\treturn PathBuilder.lineThroughPoints(points, { endOffsets: 0 })\n\t\t\t}\n\t\t}\n\t})\n}\n\nfunction LineShapeSvg({\n\tshape,\n\tshouldScale = false,\n\tforceSolid = false,\n}: {\n\tshape: TLLineShape\n\tshouldScale?: boolean\n\tforceSolid?: boolean\n}) {\n\tconst theme = useDefaultColorTheme()\n\n\tconst path = getPathForLineShape(shape)\n\tconst { dash, color, size } = shape.props\n\n\tconst scaleFactor = 1 / shape.props.scale\n\n\tconst scale = shouldScale ? scaleFactor : 1\n\n\tconst strokeWidth = STROKE_SIZES[size] * shape.props.scale\n\n\treturn path.toSvg({\n\t\tstyle: dash,\n\t\tstrokeWidth,\n\t\tforceSolid,\n\t\trandomSeed: shape.id,\n\t\tprops: {\n\t\t\ttransform: `scale(${scale})`,\n\t\t\tstroke: getColorValue(theme, color, 'solid'),\n\t\t\tfill: 'none',\n\t\t},\n\t})\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -12,6 +12,9 @@ class Cropping extends StateNode {
12
12
  snapshot = {};
13
13
  onEnter(info) {
14
14
  this.info = info;
15
+ if (typeof info.onInteractionEnd === "string") {
16
+ this.parent.setCurrentToolIdMask(info.onInteractionEnd);
17
+ }
15
18
  this.markId = this.editor.markHistoryStoppingPoint("cropping");
16
19
  this.snapshot = this.createSnapshot();
17
20
  this.updateShapes();
@@ -34,6 +37,9 @@ class Cropping extends StateNode {
34
37
  onCancel() {
35
38
  this.cancel();
36
39
  }
40
+ onExit() {
41
+ this.parent.setCurrentToolIdMask(void 0);
42
+ }
37
43
  updateCursor() {
38
44
  const selectedShape = this.editor.getSelectedShapes()[0];
39
45
  if (!selectedShape) return;
@@ -73,8 +79,13 @@ class Cropping extends StateNode {
73
79
  complete() {
74
80
  this.updateShapes();
75
81
  kickoutOccludedShapes(this.editor, [this.snapshot.shape.id]);
76
- if (this.info.onInteractionEnd) {
77
- this.editor.setCurrentTool(this.info.onInteractionEnd, this.info);
82
+ const { onInteractionEnd } = this.info;
83
+ if (onInteractionEnd) {
84
+ if (typeof onInteractionEnd === "string") {
85
+ this.editor.setCurrentTool(onInteractionEnd, this.info);
86
+ } else {
87
+ onInteractionEnd();
88
+ }
78
89
  } else {
79
90
  this.editor.setCroppingShape(null);
80
91
  this.editor.setCurrentTool("select.idle");
@@ -82,8 +93,13 @@ class Cropping extends StateNode {
82
93
  }
83
94
  cancel() {
84
95
  this.editor.bailToMark(this.markId);
85
- if (this.info.onInteractionEnd) {
86
- this.editor.setCurrentTool(this.info.onInteractionEnd, this.info);
96
+ const { onInteractionEnd } = this.info;
97
+ if (onInteractionEnd) {
98
+ if (typeof onInteractionEnd === "string") {
99
+ this.editor.setCurrentTool(onInteractionEnd, this.info);
100
+ } else {
101
+ onInteractionEnd();
102
+ }
87
103
  } else {
88
104
  this.editor.setCroppingShape(null);
89
105
  this.editor.setCurrentTool("select.idle");
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../src/lib/tools/SelectTool/childStates/Crop/children/Cropping.ts"],
4
- "sourcesContent": ["import {\n\tSelectionHandle,\n\tShapeWithCrop,\n\tStateNode,\n\tTLPointerEventInfo,\n\tVec,\n\tkickoutOccludedShapes,\n} from '@tldraw/editor'\nimport { getCropBox, getDefaultCrop, getUncroppedSize } from '../../../../../shapes/shared/crop'\nimport { CursorTypeMap } from '../../PointingResizeHandle'\n\ntype Snapshot = ReturnType<Cropping['createSnapshot']>\n\nexport class Cropping extends StateNode {\n\tstatic override id = 'cropping'\n\n\tinfo = {} as TLPointerEventInfo & {\n\t\ttarget: 'selection'\n\t\thandle: SelectionHandle\n\t\tonInteractionEnd?: string\n\t}\n\n\tmarkId = ''\n\n\tprivate snapshot = {} as any as Snapshot\n\n\toverride onEnter(\n\t\tinfo: TLPointerEventInfo & {\n\t\t\ttarget: 'selection'\n\t\t\thandle: SelectionHandle\n\t\t\tonInteractionEnd?: string\n\t\t}\n\t) {\n\t\tthis.info = info\n\t\tthis.markId = this.editor.markHistoryStoppingPoint('cropping')\n\t\tthis.snapshot = this.createSnapshot()\n\t\tthis.updateShapes()\n\t}\n\n\toverride onPointerMove() {\n\t\tthis.updateShapes()\n\t}\n\n\toverride onKeyDown() {\n\t\tthis.updateShapes()\n\t}\n\n\toverride onKeyUp() {\n\t\tthis.updateShapes()\n\t}\n\n\toverride onPointerUp() {\n\t\tthis.complete()\n\t}\n\n\toverride onComplete() {\n\t\tthis.complete()\n\t}\n\n\toverride onCancel() {\n\t\tthis.cancel()\n\t}\n\n\tprivate updateCursor() {\n\t\tconst selectedShape = this.editor.getSelectedShapes()[0]\n\t\tif (!selectedShape) return\n\n\t\tconst cursorType = CursorTypeMap[this.info.handle!]\n\t\tthis.editor.setCursor({ type: cursorType, rotation: this.editor.getSelectionRotation() })\n\t}\n\n\tprivate updateShapes() {\n\t\tconst { shape, cursorHandleOffset } = this.snapshot\n\n\t\tif (!shape) return\n\t\tconst util = this.editor.getShapeUtil<ShapeWithCrop>(shape.type)\n\t\tif (!util) return\n\n\t\tconst { shiftKey } = this.editor.inputs\n\t\tconst currentPagePoint = this.editor.inputs.currentPagePoint.clone().sub(cursorHandleOffset)\n\t\tconst originPagePoint = this.editor.inputs.originPagePoint.clone().sub(cursorHandleOffset)\n\t\tconst change = currentPagePoint.clone().sub(originPagePoint).rot(-shape.rotation)\n\n\t\tconst crop = shape.props.crop ?? getDefaultCrop()\n\t\tconst uncroppedSize = getUncroppedSize(shape.props, crop)\n\n\t\tconst cropFn = util.onCrop?.bind(util) ?? getCropBox\n\t\tconst partial = cropFn(shape, {\n\t\t\thandle: this.info.handle,\n\t\t\tchange,\n\t\t\tcrop,\n\t\t\tuncroppedSize,\n\t\t\tinitialShape: this.snapshot.shape,\n\t\t\taspectRatioLocked: shiftKey,\n\t\t})\n\t\tif (!partial) return\n\n\t\tthis.editor.updateShapes([\n\t\t\t{\n\t\t\t\tid: shape.id,\n\t\t\t\ttype: shape.type,\n\t\t\t\t...partial,\n\t\t\t},\n\t\t])\n\t\tthis.updateCursor()\n\t}\n\n\tprivate complete() {\n\t\tthis.updateShapes()\n\t\tkickoutOccludedShapes(this.editor, [this.snapshot.shape.id])\n\t\tif (this.info.onInteractionEnd) {\n\t\t\tthis.editor.setCurrentTool(this.info.onInteractionEnd, this.info)\n\t\t} else {\n\t\t\tthis.editor.setCroppingShape(null)\n\t\t\tthis.editor.setCurrentTool('select.idle')\n\t\t}\n\t}\n\n\tprivate cancel() {\n\t\tthis.editor.bailToMark(this.markId)\n\t\tif (this.info.onInteractionEnd) {\n\t\t\tthis.editor.setCurrentTool(this.info.onInteractionEnd, this.info)\n\t\t} else {\n\t\t\tthis.editor.setCroppingShape(null)\n\t\t\tthis.editor.setCurrentTool('select.idle')\n\t\t}\n\t}\n\n\tprivate createSnapshot() {\n\t\tconst selectionRotation = this.editor.getSelectionRotation()\n\t\tconst {\n\t\t\tinputs: { originPagePoint },\n\t\t} = this.editor\n\n\t\tconst shape = this.editor.getOnlySelectedShape() as ShapeWithCrop\n\n\t\tconst selectionBounds = this.editor.getSelectionRotatedPageBounds()!\n\n\t\tconst dragHandlePoint = Vec.RotWith(\n\t\t\tselectionBounds.getHandlePoint(this.info.handle!),\n\t\t\tselectionBounds.point,\n\t\t\tselectionRotation\n\t\t)\n\n\t\tconst cursorHandleOffset = Vec.Sub(originPagePoint, dragHandlePoint)\n\n\t\treturn {\n\t\t\tshape,\n\t\t\tcursorHandleOffset,\n\t\t}\n\t}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n\tSelectionHandle,\n\tShapeWithCrop,\n\tStateNode,\n\tTLPointerEventInfo,\n\tVec,\n\tkickoutOccludedShapes,\n} from '@tldraw/editor'\nimport { getCropBox, getDefaultCrop, getUncroppedSize } from '../../../../../shapes/shared/crop'\nimport { CursorTypeMap } from '../../PointingResizeHandle'\n\ntype Snapshot = ReturnType<Cropping['createSnapshot']>\n\nexport class Cropping extends StateNode {\n\tstatic override id = 'cropping'\n\n\tinfo = {} as TLPointerEventInfo & {\n\t\ttarget: 'selection'\n\t\thandle: SelectionHandle\n\t\tonInteractionEnd?: string | (() => void)\n\t}\n\n\tmarkId = ''\n\n\tprivate snapshot = {} as any as Snapshot\n\n\toverride onEnter(\n\t\tinfo: TLPointerEventInfo & {\n\t\t\ttarget: 'selection'\n\t\t\thandle: SelectionHandle\n\t\t\tonInteractionEnd?: string | (() => void)\n\t\t}\n\t) {\n\t\tthis.info = info\n\t\tif (typeof info.onInteractionEnd === 'string') {\n\t\t\tthis.parent.setCurrentToolIdMask(info.onInteractionEnd)\n\t\t}\n\t\tthis.markId = this.editor.markHistoryStoppingPoint('cropping')\n\t\tthis.snapshot = this.createSnapshot()\n\t\tthis.updateShapes()\n\t}\n\n\toverride onPointerMove() {\n\t\tthis.updateShapes()\n\t}\n\n\toverride onKeyDown() {\n\t\tthis.updateShapes()\n\t}\n\n\toverride onKeyUp() {\n\t\tthis.updateShapes()\n\t}\n\n\toverride onPointerUp() {\n\t\tthis.complete()\n\t}\n\n\toverride onComplete() {\n\t\tthis.complete()\n\t}\n\n\toverride onCancel() {\n\t\tthis.cancel()\n\t}\n\n\toverride onExit() {\n\t\tthis.parent.setCurrentToolIdMask(undefined)\n\t}\n\n\tprivate updateCursor() {\n\t\tconst selectedShape = this.editor.getSelectedShapes()[0]\n\t\tif (!selectedShape) return\n\n\t\tconst cursorType = CursorTypeMap[this.info.handle!]\n\t\tthis.editor.setCursor({ type: cursorType, rotation: this.editor.getSelectionRotation() })\n\t}\n\n\tprivate updateShapes() {\n\t\tconst { shape, cursorHandleOffset } = this.snapshot\n\n\t\tif (!shape) return\n\t\tconst util = this.editor.getShapeUtil<ShapeWithCrop>(shape.type)\n\t\tif (!util) return\n\n\t\tconst { shiftKey } = this.editor.inputs\n\t\tconst currentPagePoint = this.editor.inputs.currentPagePoint.clone().sub(cursorHandleOffset)\n\t\tconst originPagePoint = this.editor.inputs.originPagePoint.clone().sub(cursorHandleOffset)\n\t\tconst change = currentPagePoint.clone().sub(originPagePoint).rot(-shape.rotation)\n\n\t\tconst crop = shape.props.crop ?? getDefaultCrop()\n\t\tconst uncroppedSize = getUncroppedSize(shape.props, crop)\n\n\t\tconst cropFn = util.onCrop?.bind(util) ?? getCropBox\n\t\tconst partial = cropFn(shape, {\n\t\t\thandle: this.info.handle,\n\t\t\tchange,\n\t\t\tcrop,\n\t\t\tuncroppedSize,\n\t\t\tinitialShape: this.snapshot.shape,\n\t\t\taspectRatioLocked: shiftKey,\n\t\t})\n\t\tif (!partial) return\n\n\t\tthis.editor.updateShapes([\n\t\t\t{\n\t\t\t\tid: shape.id,\n\t\t\t\ttype: shape.type,\n\t\t\t\t...partial,\n\t\t\t},\n\t\t])\n\t\tthis.updateCursor()\n\t}\n\n\tprivate complete() {\n\t\tthis.updateShapes()\n\t\tkickoutOccludedShapes(this.editor, [this.snapshot.shape.id])\n\t\tconst { onInteractionEnd } = this.info\n\t\tif (onInteractionEnd) {\n\t\t\tif (typeof onInteractionEnd === 'string') {\n\t\t\t\tthis.editor.setCurrentTool(onInteractionEnd, this.info)\n\t\t\t} else {\n\t\t\t\tonInteractionEnd()\n\t\t\t}\n\t\t} else {\n\t\t\tthis.editor.setCroppingShape(null)\n\t\t\tthis.editor.setCurrentTool('select.idle')\n\t\t}\n\t}\n\n\tprivate cancel() {\n\t\tthis.editor.bailToMark(this.markId)\n\t\tconst { onInteractionEnd } = this.info\n\t\tif (onInteractionEnd) {\n\t\t\tif (typeof onInteractionEnd === 'string') {\n\t\t\t\tthis.editor.setCurrentTool(onInteractionEnd, this.info)\n\t\t\t} else {\n\t\t\t\tonInteractionEnd()\n\t\t\t}\n\t\t} else {\n\t\t\tthis.editor.setCroppingShape(null)\n\t\t\tthis.editor.setCurrentTool('select.idle')\n\t\t}\n\t}\n\n\tprivate createSnapshot() {\n\t\tconst selectionRotation = this.editor.getSelectionRotation()\n\t\tconst {\n\t\t\tinputs: { originPagePoint },\n\t\t} = this.editor\n\n\t\tconst shape = this.editor.getOnlySelectedShape() as ShapeWithCrop\n\n\t\tconst selectionBounds = this.editor.getSelectionRotatedPageBounds()!\n\n\t\tconst dragHandlePoint = Vec.RotWith(\n\t\t\tselectionBounds.getHandlePoint(this.info.handle!),\n\t\t\tselectionBounds.point,\n\t\t\tselectionRotation\n\t\t)\n\n\t\tconst cursorHandleOffset = Vec.Sub(originPagePoint, dragHandlePoint)\n\n\t\treturn {\n\t\t\tshape,\n\t\t\tcursorHandleOffset,\n\t\t}\n\t}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -114,7 +114,7 @@ class Idle extends StateNode {
114
114
  this.nudgeCroppingImage(true);
115
115
  }
116
116
  onKeyUp(info) {
117
- switch (info.code) {
117
+ switch (info.key) {
118
118
  case "Enter": {
119
119
  this.editor.setCroppingShape(null);
120
120
  this.editor.setCurrentTool("select.idle", {});
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../src/lib/tools/SelectTool/childStates/Crop/children/Idle.ts"],
4
- "sourcesContent": ["import {\n\tShapeWithCrop,\n\tStateNode,\n\tTLClickEventInfo,\n\tTLGroupShape,\n\tTLKeyboardEventInfo,\n\tTLPointerEventInfo,\n\tVec,\n} from '@tldraw/editor'\nimport { getHitShapeOnCanvasPointerDown } from '../../../../selection-logic/getHitShapeOnCanvasPointerDown'\nimport { getTranslateCroppedImageChange } from './crop_helpers'\n\nexport class Idle extends StateNode {\n\tstatic override id = 'idle'\n\n\toverride onEnter() {\n\t\tthis.editor.setCursor({ type: 'default', rotation: 0 })\n\n\t\tconst onlySelectedShape = this.editor.getOnlySelectedShape()\n\n\t\tif (onlySelectedShape) {\n\t\t\tthis.editor.setCroppingShape(onlySelectedShape.id)\n\t\t}\n\t}\n\n\toverride onExit() {\n\t\tthis.editor.setCursor({ type: 'default', rotation: 0 })\n\t}\n\n\toverride onCancel() {\n\t\tthis.editor.setCroppingShape(null)\n\t\tthis.editor.setCurrentTool('select.idle', {})\n\t}\n\n\toverride onPointerDown(info: TLPointerEventInfo) {\n\t\tif (info.accelKey) {\n\t\t\tthis.cancel()\n\t\t\t// feed the event back into the statechart\n\t\t\tthis.editor.root.handleEvent(info)\n\t\t\treturn\n\t\t}\n\n\t\tswitch (info.target) {\n\t\t\tcase 'canvas': {\n\t\t\t\tconst hitShape = getHitShapeOnCanvasPointerDown(this.editor)\n\t\t\t\tif (hitShape && !this.editor.isShapeOfType<TLGroupShape>(hitShape, 'group')) {\n\t\t\t\t\tthis.onPointerDown({\n\t\t\t\t\t\t...info,\n\t\t\t\t\t\tshape: hitShape,\n\t\t\t\t\t\ttarget: 'shape',\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tthis.cancel()\n\t\t\t\t// feed the event back into the statechart\n\t\t\t\tthis.editor.root.handleEvent(info)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'shape': {\n\t\t\t\tif (info.shape.id === this.editor.getCroppingShapeId()) {\n\t\t\t\t\tthis.editor.setCurrentTool('select.crop.pointing_crop', info)\n\t\t\t\t\treturn\n\t\t\t\t} else {\n\t\t\t\t\tif (this.editor.getShapeUtil(info.shape)?.canCrop(info.shape)) {\n\t\t\t\t\t\tthis.editor.setCroppingShape(info.shape.id)\n\t\t\t\t\t\tthis.editor.setSelectedShapes([info.shape.id])\n\t\t\t\t\t\tthis.editor.setCurrentTool('select.crop.pointing_crop', info)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.cancel()\n\t\t\t\t\t\t// feed the event back into the statechart\n\t\t\t\t\t\tthis.editor.root.handleEvent(info)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'selection': {\n\t\t\t\tswitch (info.handle) {\n\t\t\t\t\tcase 'mobile_rotate':\n\t\t\t\t\tcase 'top_left_rotate':\n\t\t\t\t\tcase 'top_right_rotate':\n\t\t\t\t\tcase 'bottom_left_rotate':\n\t\t\t\t\tcase 'bottom_right_rotate': {\n\t\t\t\t\t\tthis.editor.setCurrentTool('select.pointing_rotate_handle', {\n\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\tonInteractionEnd: 'select.crop.idle',\n\t\t\t\t\t\t})\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'top':\n\t\t\t\t\tcase 'right':\n\t\t\t\t\tcase 'bottom':\n\t\t\t\t\tcase 'left':\n\t\t\t\t\tcase 'top_left':\n\t\t\t\t\tcase 'top_right':\n\t\t\t\t\tcase 'bottom_left':\n\t\t\t\t\tcase 'bottom_right': {\n\t\t\t\t\t\tthis.editor.setCurrentTool('select.crop.pointing_crop_handle', {\n\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\tonInteractionEnd: 'select.crop.idle',\n\t\t\t\t\t\t})\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tdefault: {\n\t\t\t\t\t\tthis.cancel()\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\toverride onDoubleClick(info: TLClickEventInfo) {\n\t\t// Without this, the double click's \"settle\" would trigger the reset\n\t\t// after the user double clicked the edge to begin cropping\n\t\tif (this.editor.inputs.shiftKey || info.phase !== 'up') return\n\n\t\tconst croppingShapeId = this.editor.getCroppingShapeId()\n\t\tif (!croppingShapeId) return\n\t\tconst shape = this.editor.getShape(croppingShapeId)\n\t\tif (!shape) return\n\n\t\tconst util = this.editor.getShapeUtil(shape)\n\t\tif (!util) return\n\n\t\tif (info.target === 'selection') {\n\t\t\tutil.onDoubleClickEdge?.(shape, info)\n\t\t\treturn\n\t\t}\n\n\t\t// If the user double clicks the canvas, we want to cancel cropping,\n\t\t// especially if it's an animated image, we want the image to continue playing.\n\t\tthis.cancel()\n\t\tthis.editor.root.handleEvent(info)\n\t}\n\n\toverride onKeyDown() {\n\t\tthis.nudgeCroppingImage(false)\n\t}\n\n\toverride onKeyRepeat() {\n\t\tthis.nudgeCroppingImage(true)\n\t}\n\n\toverride onKeyUp(info: TLKeyboardEventInfo) {\n\t\tswitch (info.code) {\n\t\t\tcase 'Enter': {\n\t\t\t\tthis.editor.setCroppingShape(null)\n\t\t\t\tthis.editor.setCurrentTool('select.idle', {})\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate cancel() {\n\t\tthis.editor.setCroppingShape(null)\n\t\tthis.editor.setCurrentTool('select.idle', {})\n\t}\n\n\tprivate nudgeCroppingImage(ephemeral = false) {\n\t\tconst {\n\t\t\teditor: {\n\t\t\t\tinputs: { keys },\n\t\t\t},\n\t\t} = this\n\n\t\t// We want to use the \"actual\" shift key state,\n\t\t// not the one that's in the editor.inputs.shiftKey,\n\t\t// because that one uses a short timeout on release\n\t\tconst shiftKey = keys.has('ShiftLeft')\n\n\t\tconst delta = new Vec(0, 0)\n\n\t\tif (keys.has('ArrowLeft')) delta.x += 1\n\t\tif (keys.has('ArrowRight')) delta.x -= 1\n\t\tif (keys.has('ArrowUp')) delta.y += 1\n\t\tif (keys.has('ArrowDown')) delta.y -= 1\n\n\t\tif (delta.equals(new Vec(0, 0))) return\n\n\t\tif (shiftKey) delta.mul(10)\n\n\t\tconst shape = this.editor.getShape(this.editor.getCroppingShapeId()!) as ShapeWithCrop\n\t\tif (!shape) return\n\t\tconst partial = getTranslateCroppedImageChange(this.editor, shape, delta)\n\n\t\tif (partial) {\n\t\t\tif (!ephemeral) {\n\t\t\t\t// We don't want to create new marks if the user\n\t\t\t\t// is just holding down the arrow keys\n\t\t\t\tthis.editor.markHistoryStoppingPoint('translate crop')\n\t\t\t}\n\n\t\t\tthis.editor.updateShapes<ShapeWithCrop>([partial])\n\t\t}\n\t}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n\tShapeWithCrop,\n\tStateNode,\n\tTLClickEventInfo,\n\tTLGroupShape,\n\tTLKeyboardEventInfo,\n\tTLPointerEventInfo,\n\tVec,\n} from '@tldraw/editor'\nimport { getHitShapeOnCanvasPointerDown } from '../../../../selection-logic/getHitShapeOnCanvasPointerDown'\nimport { getTranslateCroppedImageChange } from './crop_helpers'\n\nexport class Idle extends StateNode {\n\tstatic override id = 'idle'\n\n\toverride onEnter() {\n\t\tthis.editor.setCursor({ type: 'default', rotation: 0 })\n\n\t\tconst onlySelectedShape = this.editor.getOnlySelectedShape()\n\n\t\tif (onlySelectedShape) {\n\t\t\tthis.editor.setCroppingShape(onlySelectedShape.id)\n\t\t}\n\t}\n\n\toverride onExit() {\n\t\tthis.editor.setCursor({ type: 'default', rotation: 0 })\n\t}\n\n\toverride onCancel() {\n\t\tthis.editor.setCroppingShape(null)\n\t\tthis.editor.setCurrentTool('select.idle', {})\n\t}\n\n\toverride onPointerDown(info: TLPointerEventInfo) {\n\t\tif (info.accelKey) {\n\t\t\tthis.cancel()\n\t\t\t// feed the event back into the statechart\n\t\t\tthis.editor.root.handleEvent(info)\n\t\t\treturn\n\t\t}\n\n\t\tswitch (info.target) {\n\t\t\tcase 'canvas': {\n\t\t\t\tconst hitShape = getHitShapeOnCanvasPointerDown(this.editor)\n\t\t\t\tif (hitShape && !this.editor.isShapeOfType<TLGroupShape>(hitShape, 'group')) {\n\t\t\t\t\tthis.onPointerDown({\n\t\t\t\t\t\t...info,\n\t\t\t\t\t\tshape: hitShape,\n\t\t\t\t\t\ttarget: 'shape',\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tthis.cancel()\n\t\t\t\t// feed the event back into the statechart\n\t\t\t\tthis.editor.root.handleEvent(info)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'shape': {\n\t\t\t\tif (info.shape.id === this.editor.getCroppingShapeId()) {\n\t\t\t\t\tthis.editor.setCurrentTool('select.crop.pointing_crop', info)\n\t\t\t\t\treturn\n\t\t\t\t} else {\n\t\t\t\t\tif (this.editor.getShapeUtil(info.shape)?.canCrop(info.shape)) {\n\t\t\t\t\t\tthis.editor.setCroppingShape(info.shape.id)\n\t\t\t\t\t\tthis.editor.setSelectedShapes([info.shape.id])\n\t\t\t\t\t\tthis.editor.setCurrentTool('select.crop.pointing_crop', info)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.cancel()\n\t\t\t\t\t\t// feed the event back into the statechart\n\t\t\t\t\t\tthis.editor.root.handleEvent(info)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'selection': {\n\t\t\t\tswitch (info.handle) {\n\t\t\t\t\tcase 'mobile_rotate':\n\t\t\t\t\tcase 'top_left_rotate':\n\t\t\t\t\tcase 'top_right_rotate':\n\t\t\t\t\tcase 'bottom_left_rotate':\n\t\t\t\t\tcase 'bottom_right_rotate': {\n\t\t\t\t\t\tthis.editor.setCurrentTool('select.pointing_rotate_handle', {\n\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\tonInteractionEnd: 'select.crop.idle',\n\t\t\t\t\t\t})\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'top':\n\t\t\t\t\tcase 'right':\n\t\t\t\t\tcase 'bottom':\n\t\t\t\t\tcase 'left':\n\t\t\t\t\tcase 'top_left':\n\t\t\t\t\tcase 'top_right':\n\t\t\t\t\tcase 'bottom_left':\n\t\t\t\t\tcase 'bottom_right': {\n\t\t\t\t\t\tthis.editor.setCurrentTool('select.crop.pointing_crop_handle', {\n\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\tonInteractionEnd: 'select.crop.idle',\n\t\t\t\t\t\t})\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tdefault: {\n\t\t\t\t\t\tthis.cancel()\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\toverride onDoubleClick(info: TLClickEventInfo) {\n\t\t// Without this, the double click's \"settle\" would trigger the reset\n\t\t// after the user double clicked the edge to begin cropping\n\t\tif (this.editor.inputs.shiftKey || info.phase !== 'up') return\n\n\t\tconst croppingShapeId = this.editor.getCroppingShapeId()\n\t\tif (!croppingShapeId) return\n\t\tconst shape = this.editor.getShape(croppingShapeId)\n\t\tif (!shape) return\n\n\t\tconst util = this.editor.getShapeUtil(shape)\n\t\tif (!util) return\n\n\t\tif (info.target === 'selection') {\n\t\t\tutil.onDoubleClickEdge?.(shape, info)\n\t\t\treturn\n\t\t}\n\n\t\t// If the user double clicks the canvas, we want to cancel cropping,\n\t\t// especially if it's an animated image, we want the image to continue playing.\n\t\tthis.cancel()\n\t\tthis.editor.root.handleEvent(info)\n\t}\n\n\toverride onKeyDown() {\n\t\tthis.nudgeCroppingImage(false)\n\t}\n\n\toverride onKeyRepeat() {\n\t\tthis.nudgeCroppingImage(true)\n\t}\n\n\toverride onKeyUp(info: TLKeyboardEventInfo) {\n\t\tswitch (info.key) {\n\t\t\tcase 'Enter': {\n\t\t\t\tthis.editor.setCroppingShape(null)\n\t\t\t\tthis.editor.setCurrentTool('select.idle', {})\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate cancel() {\n\t\tthis.editor.setCroppingShape(null)\n\t\tthis.editor.setCurrentTool('select.idle', {})\n\t}\n\n\tprivate nudgeCroppingImage(ephemeral = false) {\n\t\tconst {\n\t\t\teditor: {\n\t\t\t\tinputs: { keys },\n\t\t\t},\n\t\t} = this\n\n\t\t// We want to use the \"actual\" shift key state,\n\t\t// not the one that's in the editor.inputs.shiftKey,\n\t\t// because that one uses a short timeout on release\n\t\tconst shiftKey = keys.has('ShiftLeft')\n\n\t\tconst delta = new Vec(0, 0)\n\n\t\tif (keys.has('ArrowLeft')) delta.x += 1\n\t\tif (keys.has('ArrowRight')) delta.x -= 1\n\t\tif (keys.has('ArrowUp')) delta.y += 1\n\t\tif (keys.has('ArrowDown')) delta.y -= 1\n\n\t\tif (delta.equals(new Vec(0, 0))) return\n\n\t\tif (shiftKey) delta.mul(10)\n\n\t\tconst shape = this.editor.getShape(this.editor.getCroppingShapeId()!) as ShapeWithCrop\n\t\tif (!shape) return\n\t\tconst partial = getTranslateCroppedImageChange(this.editor, shape, delta)\n\n\t\tif (partial) {\n\t\t\tif (!ephemeral) {\n\t\t\t\t// We don't want to create new marks if the user\n\t\t\t\t// is just holding down the arrow keys\n\t\t\t\tthis.editor.markHistoryStoppingPoint('translate crop')\n\t\t\t}\n\n\t\t\tthis.editor.updateShapes<ShapeWithCrop>([partial])\n\t\t}\n\t}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -5,7 +5,9 @@ class PointingCropHandle extends StateNode {
5
5
  info = {};
6
6
  onEnter(info) {
7
7
  this.info = info;
8
- this.parent.setCurrentToolIdMask(info.onInteractionEnd);
8
+ if (typeof info.onInteractionEnd === "string") {
9
+ this.parent.setCurrentToolIdMask(info.onInteractionEnd);
10
+ }
9
11
  const selectedShape = this.editor.getSelectedShapes()[0];
10
12
  if (!selectedShape) return;
11
13
  const cursorType = CursorTypeMap[this.info.handle];
@@ -32,12 +34,17 @@ class PointingCropHandle extends StateNode {
32
34
  });
33
35
  }
34
36
  onPointerUp() {
35
- if (this.info.onInteractionEnd) {
36
- this.editor.setCurrentTool(this.info.onInteractionEnd, this.info);
37
- } else {
38
- this.editor.setCroppingShape(null);
39
- this.editor.setCurrentTool("select.idle");
37
+ const { onInteractionEnd } = this.info;
38
+ if (onInteractionEnd) {
39
+ if (typeof onInteractionEnd === "string") {
40
+ this.editor.setCurrentTool(onInteractionEnd, this.info);
41
+ } else {
42
+ onInteractionEnd();
43
+ }
44
+ return;
40
45
  }
46
+ this.editor.setCroppingShape(null);
47
+ this.editor.setCurrentTool("select.idle");
41
48
  }
42
49
  onCancel() {
43
50
  this.cancel();
@@ -49,12 +56,17 @@ class PointingCropHandle extends StateNode {
49
56
  this.cancel();
50
57
  }
51
58
  cancel() {
52
- if (this.info.onInteractionEnd) {
53
- this.editor.setCurrentTool(this.info.onInteractionEnd, this.info);
54
- } else {
55
- this.editor.setCroppingShape(null);
56
- this.editor.setCurrentTool("select.idle");
59
+ const { onInteractionEnd } = this.info;
60
+ if (onInteractionEnd) {
61
+ if (typeof onInteractionEnd === "string") {
62
+ this.editor.setCurrentTool(onInteractionEnd, this.info);
63
+ } else {
64
+ onInteractionEnd();
65
+ }
66
+ return;
57
67
  }
68
+ this.editor.setCroppingShape(null);
69
+ this.editor.setCurrentTool("select.idle");
58
70
  }
59
71
  }
60
72
  export {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../src/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.ts"],
4
- "sourcesContent": ["import { StateNode, TLPointerEventInfo } from '@tldraw/editor'\nimport { CursorTypeMap } from '../../PointingResizeHandle'\n\ntype TLPointingCropHandleInfo = TLPointerEventInfo & {\n\ttarget: 'selection'\n} & {\n\tonInteractionEnd?: string\n}\n\nexport class PointingCropHandle extends StateNode {\n\tstatic override id = 'pointing_crop_handle'\n\n\tprivate info = {} as TLPointingCropHandleInfo\n\n\toverride onEnter(info: TLPointingCropHandleInfo) {\n\t\tthis.info = info\n\t\tthis.parent.setCurrentToolIdMask(info.onInteractionEnd)\n\t\tconst selectedShape = this.editor.getSelectedShapes()[0]\n\t\tif (!selectedShape) return\n\n\t\tconst cursorType = CursorTypeMap[this.info.handle!]\n\t\tthis.editor.setCursor({ type: cursorType, rotation: this.editor.getSelectionRotation() })\n\t\tthis.editor.setCroppingShape(selectedShape.id)\n\t}\n\n\toverride onExit() {\n\t\tthis.editor.setCursor({ type: 'default', rotation: 0 })\n\t\tthis.parent.setCurrentToolIdMask(undefined)\n\t}\n\n\toverride onPointerMove() {\n\t\tif (this.editor.inputs.isDragging) {\n\t\t\tthis.startCropping()\n\t\t}\n\t}\n\n\toverride onLongPress() {\n\t\tthis.startCropping()\n\t}\n\n\tprivate startCropping() {\n\t\tif (this.editor.getIsReadonly()) return\n\t\tthis.parent.transition('cropping', {\n\t\t\t...this.info,\n\t\t\tonInteractionEnd: this.info.onInteractionEnd,\n\t\t})\n\t}\n\n\toverride onPointerUp() {\n\t\tif (this.info.onInteractionEnd) {\n\t\t\tthis.editor.setCurrentTool(this.info.onInteractionEnd, this.info)\n\t\t} else {\n\t\t\tthis.editor.setCroppingShape(null)\n\t\t\tthis.editor.setCurrentTool('select.idle')\n\t\t}\n\t}\n\n\toverride onCancel() {\n\t\tthis.cancel()\n\t}\n\n\toverride onComplete() {\n\t\tthis.cancel()\n\t}\n\n\toverride onInterrupt() {\n\t\tthis.cancel()\n\t}\n\n\tprivate cancel() {\n\t\tif (this.info.onInteractionEnd) {\n\t\t\tthis.editor.setCurrentTool(this.info.onInteractionEnd, this.info)\n\t\t} else {\n\t\t\tthis.editor.setCroppingShape(null)\n\t\t\tthis.editor.setCurrentTool('select.idle')\n\t\t}\n\t}\n}\n"],
5
- "mappings": "AAAA,SAAS,iBAAqC;AAC9C,SAAS,qBAAqB;AAQvB,MAAM,2BAA2B,UAAU;AAAA,EACjD,OAAgB,KAAK;AAAA,EAEb,OAAO,CAAC;AAAA,EAEP,QAAQ,MAAgC;AAChD,SAAK,OAAO;AACZ,SAAK,OAAO,qBAAqB,KAAK,gBAAgB;AACtD,UAAM,gBAAgB,KAAK,OAAO,kBAAkB,EAAE,CAAC;AACvD,QAAI,CAAC,cAAe;AAEpB,UAAM,aAAa,cAAc,KAAK,KAAK,MAAO;AAClD,SAAK,OAAO,UAAU,EAAE,MAAM,YAAY,UAAU,KAAK,OAAO,qBAAqB,EAAE,CAAC;AACxF,SAAK,OAAO,iBAAiB,cAAc,EAAE;AAAA,EAC9C;AAAA,EAES,SAAS;AACjB,SAAK,OAAO,UAAU,EAAE,MAAM,WAAW,UAAU,EAAE,CAAC;AACtD,SAAK,OAAO,qBAAqB,MAAS;AAAA,EAC3C;AAAA,EAES,gBAAgB;AACxB,QAAI,KAAK,OAAO,OAAO,YAAY;AAClC,WAAK,cAAc;AAAA,IACpB;AAAA,EACD;AAAA,EAES,cAAc;AACtB,SAAK,cAAc;AAAA,EACpB;AAAA,EAEQ,gBAAgB;AACvB,QAAI,KAAK,OAAO,cAAc,EAAG;AACjC,SAAK,OAAO,WAAW,YAAY;AAAA,MAClC,GAAG,KAAK;AAAA,MACR,kBAAkB,KAAK,KAAK;AAAA,IAC7B,CAAC;AAAA,EACF;AAAA,EAES,cAAc;AACtB,QAAI,KAAK,KAAK,kBAAkB;AAC/B,WAAK,OAAO,eAAe,KAAK,KAAK,kBAAkB,KAAK,IAAI;AAAA,IACjE,OAAO;AACN,WAAK,OAAO,iBAAiB,IAAI;AACjC,WAAK,OAAO,eAAe,aAAa;AAAA,IACzC;AAAA,EACD;AAAA,EAES,WAAW;AACnB,SAAK,OAAO;AAAA,EACb;AAAA,EAES,aAAa;AACrB,SAAK,OAAO;AAAA,EACb;AAAA,EAES,cAAc;AACtB,SAAK,OAAO;AAAA,EACb;AAAA,EAEQ,SAAS;AAChB,QAAI,KAAK,KAAK,kBAAkB;AAC/B,WAAK,OAAO,eAAe,KAAK,KAAK,kBAAkB,KAAK,IAAI;AAAA,IACjE,OAAO;AACN,WAAK,OAAO,iBAAiB,IAAI;AACjC,WAAK,OAAO,eAAe,aAAa;AAAA,IACzC;AAAA,EACD;AACD;",
4
+ "sourcesContent": ["import { StateNode, TLPointerEventInfo } from '@tldraw/editor'\nimport { CursorTypeMap } from '../../PointingResizeHandle'\n\ntype TLPointingCropHandleInfo = TLPointerEventInfo & {\n\ttarget: 'selection'\n} & {\n\tonInteractionEnd?: string | (() => void)\n}\n\nexport class PointingCropHandle extends StateNode {\n\tstatic override id = 'pointing_crop_handle'\n\n\tprivate info = {} as TLPointingCropHandleInfo\n\n\toverride onEnter(info: TLPointingCropHandleInfo) {\n\t\tthis.info = info\n\t\tif (typeof info.onInteractionEnd === 'string') {\n\t\t\tthis.parent.setCurrentToolIdMask(info.onInteractionEnd)\n\t\t}\n\t\tconst selectedShape = this.editor.getSelectedShapes()[0]\n\t\tif (!selectedShape) return\n\n\t\tconst cursorType = CursorTypeMap[this.info.handle!]\n\t\tthis.editor.setCursor({ type: cursorType, rotation: this.editor.getSelectionRotation() })\n\t\tthis.editor.setCroppingShape(selectedShape.id)\n\t}\n\n\toverride onExit() {\n\t\tthis.editor.setCursor({ type: 'default', rotation: 0 })\n\t\tthis.parent.setCurrentToolIdMask(undefined)\n\t}\n\n\toverride onPointerMove() {\n\t\tif (this.editor.inputs.isDragging) {\n\t\t\tthis.startCropping()\n\t\t}\n\t}\n\n\toverride onLongPress() {\n\t\tthis.startCropping()\n\t}\n\n\tprivate startCropping() {\n\t\tif (this.editor.getIsReadonly()) return\n\t\tthis.parent.transition('cropping', {\n\t\t\t...this.info,\n\t\t\tonInteractionEnd: this.info.onInteractionEnd,\n\t\t})\n\t}\n\n\toverride onPointerUp() {\n\t\tconst { onInteractionEnd } = this.info\n\t\tif (onInteractionEnd) {\n\t\t\tif (typeof onInteractionEnd === 'string') {\n\t\t\t\tthis.editor.setCurrentTool(onInteractionEnd, this.info)\n\t\t\t} else {\n\t\t\t\tonInteractionEnd()\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\tthis.editor.setCroppingShape(null)\n\t\tthis.editor.setCurrentTool('select.idle')\n\t}\n\n\toverride onCancel() {\n\t\tthis.cancel()\n\t}\n\n\toverride onComplete() {\n\t\tthis.cancel()\n\t}\n\n\toverride onInterrupt() {\n\t\tthis.cancel()\n\t}\n\n\tprivate cancel() {\n\t\tconst { onInteractionEnd } = this.info\n\t\tif (onInteractionEnd) {\n\t\t\tif (typeof onInteractionEnd === 'string') {\n\t\t\t\tthis.editor.setCurrentTool(onInteractionEnd, this.info)\n\t\t\t} else {\n\t\t\t\tonInteractionEnd()\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\tthis.editor.setCroppingShape(null)\n\t\tthis.editor.setCurrentTool('select.idle')\n\t}\n}\n"],
5
+ "mappings": "AAAA,SAAS,iBAAqC;AAC9C,SAAS,qBAAqB;AAQvB,MAAM,2BAA2B,UAAU;AAAA,EACjD,OAAgB,KAAK;AAAA,EAEb,OAAO,CAAC;AAAA,EAEP,QAAQ,MAAgC;AAChD,SAAK,OAAO;AACZ,QAAI,OAAO,KAAK,qBAAqB,UAAU;AAC9C,WAAK,OAAO,qBAAqB,KAAK,gBAAgB;AAAA,IACvD;AACA,UAAM,gBAAgB,KAAK,OAAO,kBAAkB,EAAE,CAAC;AACvD,QAAI,CAAC,cAAe;AAEpB,UAAM,aAAa,cAAc,KAAK,KAAK,MAAO;AAClD,SAAK,OAAO,UAAU,EAAE,MAAM,YAAY,UAAU,KAAK,OAAO,qBAAqB,EAAE,CAAC;AACxF,SAAK,OAAO,iBAAiB,cAAc,EAAE;AAAA,EAC9C;AAAA,EAES,SAAS;AACjB,SAAK,OAAO,UAAU,EAAE,MAAM,WAAW,UAAU,EAAE,CAAC;AACtD,SAAK,OAAO,qBAAqB,MAAS;AAAA,EAC3C;AAAA,EAES,gBAAgB;AACxB,QAAI,KAAK,OAAO,OAAO,YAAY;AAClC,WAAK,cAAc;AAAA,IACpB;AAAA,EACD;AAAA,EAES,cAAc;AACtB,SAAK,cAAc;AAAA,EACpB;AAAA,EAEQ,gBAAgB;AACvB,QAAI,KAAK,OAAO,cAAc,EAAG;AACjC,SAAK,OAAO,WAAW,YAAY;AAAA,MAClC,GAAG,KAAK;AAAA,MACR,kBAAkB,KAAK,KAAK;AAAA,IAC7B,CAAC;AAAA,EACF;AAAA,EAES,cAAc;AACtB,UAAM,EAAE,iBAAiB,IAAI,KAAK;AAClC,QAAI,kBAAkB;AACrB,UAAI,OAAO,qBAAqB,UAAU;AACzC,aAAK,OAAO,eAAe,kBAAkB,KAAK,IAAI;AAAA,MACvD,OAAO;AACN,yBAAiB;AAAA,MAClB;AACA;AAAA,IACD;AACA,SAAK,OAAO,iBAAiB,IAAI;AACjC,SAAK,OAAO,eAAe,aAAa;AAAA,EACzC;AAAA,EAES,WAAW;AACnB,SAAK,OAAO;AAAA,EACb;AAAA,EAES,aAAa;AACrB,SAAK,OAAO;AAAA,EACb;AAAA,EAES,cAAc;AACtB,SAAK,OAAO;AAAA,EACb;AAAA,EAEQ,SAAS;AAChB,UAAM,EAAE,iBAAiB,IAAI,KAAK;AAClC,QAAI,kBAAkB;AACrB,UAAI,OAAO,qBAAqB,UAAU;AACzC,aAAK,OAAO,eAAe,kBAAkB,KAAK,IAAI;AAAA,MACvD,OAAO;AACN,yBAAiB;AAAA,MAClB;AACA;AAAA,IACD;AACA,SAAK,OAAO,iBAAiB,IAAI;AACjC,SAAK,OAAO,eAAe,aAAa;AAAA,EACzC;AACD;",
6
6
  "names": []
7
7
  }