tldraw 4.1.1 → 4.2.0-next.d76c345101d5

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 (111) hide show
  1. package/dist-cjs/index.d.ts +15 -11
  2. package/dist-cjs/index.js +3 -1
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/defaultEmbedDefinitions.js +2 -25
  5. package/dist-cjs/lib/defaultEmbedDefinitions.js.map +2 -2
  6. package/dist-cjs/lib/defaultExternalContentHandlers.js +8 -31
  7. package/dist-cjs/lib/defaultExternalContentHandlers.js.map +2 -2
  8. package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js +31 -101
  9. package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js.map +2 -2
  10. package/dist-cjs/lib/shapes/bookmark/bookmarks.js +138 -0
  11. package/dist-cjs/lib/shapes/bookmark/bookmarks.js.map +7 -0
  12. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js +25 -3
  13. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js.map +2 -2
  14. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Cropping.js +20 -4
  15. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Cropping.js.map +2 -2
  16. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.js +23 -11
  17. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.js.map +2 -2
  18. package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js +18 -5
  19. package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js.map +2 -2
  20. package/dist-cjs/lib/tools/SelectTool/childStates/PointingArrowLabel.js +21 -9
  21. package/dist-cjs/lib/tools/SelectTool/childStates/PointingArrowLabel.js.map +2 -2
  22. package/dist-cjs/lib/tools/SelectTool/childStates/PointingResizeHandle.js +24 -8
  23. package/dist-cjs/lib/tools/SelectTool/childStates/PointingResizeHandle.js.map +2 -2
  24. package/dist-cjs/lib/tools/SelectTool/childStates/PointingRotateHandle.js +21 -9
  25. package/dist-cjs/lib/tools/SelectTool/childStates/PointingRotateHandle.js.map +2 -2
  26. package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js +23 -8
  27. package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js.map +2 -2
  28. package/dist-cjs/lib/tools/SelectTool/childStates/Rotating.js +21 -9
  29. package/dist-cjs/lib/tools/SelectTool/childStates/Rotating.js.map +2 -2
  30. package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js +26 -11
  31. package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js.map +2 -2
  32. package/dist-cjs/lib/ui/components/DebugMenu/DefaultDebugMenuContent.js +2 -2
  33. package/dist-cjs/lib/ui/components/DebugMenu/DefaultDebugMenuContent.js.map +1 -1
  34. package/dist-cjs/lib/ui/components/menu-items.js +2 -2
  35. package/dist-cjs/lib/ui/components/menu-items.js.map +1 -1
  36. package/dist-cjs/lib/ui/context/actions.js +23 -29
  37. package/dist-cjs/lib/ui/context/actions.js.map +2 -2
  38. package/dist-cjs/lib/ui/hooks/useEditorEvents.js +1 -1
  39. package/dist-cjs/lib/ui/hooks/useEditorEvents.js.map +1 -1
  40. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js +4 -4
  41. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js.map +1 -1
  42. package/dist-cjs/lib/ui/version.js +3 -3
  43. package/dist-cjs/lib/ui/version.js.map +1 -1
  44. package/dist-esm/index.d.mts +15 -11
  45. package/dist-esm/index.mjs +3 -1
  46. package/dist-esm/index.mjs.map +2 -2
  47. package/dist-esm/lib/defaultEmbedDefinitions.mjs +2 -25
  48. package/dist-esm/lib/defaultEmbedDefinitions.mjs.map +2 -2
  49. package/dist-esm/lib/defaultExternalContentHandlers.mjs +8 -31
  50. package/dist-esm/lib/defaultExternalContentHandlers.mjs.map +2 -2
  51. package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs +34 -101
  52. package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs.map +2 -2
  53. package/dist-esm/lib/shapes/bookmark/bookmarks.mjs +124 -0
  54. package/dist-esm/lib/shapes/bookmark/bookmarks.mjs.map +7 -0
  55. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs +26 -3
  56. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs.map +2 -2
  57. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Cropping.mjs +20 -4
  58. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Cropping.mjs.map +2 -2
  59. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.mjs +23 -11
  60. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.mjs.map +2 -2
  61. package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs +18 -5
  62. package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs.map +2 -2
  63. package/dist-esm/lib/tools/SelectTool/childStates/PointingArrowLabel.mjs +21 -9
  64. package/dist-esm/lib/tools/SelectTool/childStates/PointingArrowLabel.mjs.map +2 -2
  65. package/dist-esm/lib/tools/SelectTool/childStates/PointingResizeHandle.mjs +24 -8
  66. package/dist-esm/lib/tools/SelectTool/childStates/PointingResizeHandle.mjs.map +2 -2
  67. package/dist-esm/lib/tools/SelectTool/childStates/PointingRotateHandle.mjs +21 -9
  68. package/dist-esm/lib/tools/SelectTool/childStates/PointingRotateHandle.mjs.map +2 -2
  69. package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs +23 -8
  70. package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs.map +2 -2
  71. package/dist-esm/lib/tools/SelectTool/childStates/Rotating.mjs +21 -9
  72. package/dist-esm/lib/tools/SelectTool/childStates/Rotating.mjs.map +2 -2
  73. package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs +26 -11
  74. package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs.map +2 -2
  75. package/dist-esm/lib/ui/components/DebugMenu/DefaultDebugMenuContent.mjs +2 -2
  76. package/dist-esm/lib/ui/components/DebugMenu/DefaultDebugMenuContent.mjs.map +1 -1
  77. package/dist-esm/lib/ui/components/menu-items.mjs +2 -2
  78. package/dist-esm/lib/ui/components/menu-items.mjs.map +1 -1
  79. package/dist-esm/lib/ui/context/actions.mjs +23 -29
  80. package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
  81. package/dist-esm/lib/ui/hooks/useEditorEvents.mjs +1 -1
  82. package/dist-esm/lib/ui/hooks/useEditorEvents.mjs.map +1 -1
  83. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs +4 -4
  84. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs.map +1 -1
  85. package/dist-esm/lib/ui/version.mjs +3 -3
  86. package/dist-esm/lib/ui/version.mjs.map +1 -1
  87. package/package.json +3 -3
  88. package/src/index.ts +1 -0
  89. package/src/lib/defaultEmbedDefinitions.ts +2 -25
  90. package/src/lib/defaultExternalContentHandlers.ts +10 -35
  91. package/src/lib/shapes/bookmark/BookmarkShapeUtil.tsx +39 -133
  92. package/src/lib/shapes/bookmark/bookmarks.ts +170 -0
  93. package/src/lib/shapes/embed/EmbedShapeUtil.tsx +28 -2
  94. package/src/lib/tools/SelectTool/childStates/Crop/children/Cropping.ts +23 -6
  95. package/src/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.ts +24 -12
  96. package/src/lib/tools/SelectTool/childStates/DraggingHandle.tsx +21 -10
  97. package/src/lib/tools/SelectTool/childStates/PointingArrowLabel.ts +23 -11
  98. package/src/lib/tools/SelectTool/childStates/PointingResizeHandle.ts +26 -9
  99. package/src/lib/tools/SelectTool/childStates/PointingRotateHandle.ts +23 -10
  100. package/src/lib/tools/SelectTool/childStates/Resizing.ts +24 -9
  101. package/src/lib/tools/SelectTool/childStates/Rotating.ts +27 -11
  102. package/src/lib/tools/SelectTool/childStates/Translating.ts +28 -12
  103. package/src/lib/ui/components/DebugMenu/DefaultDebugMenuContent.tsx +2 -2
  104. package/src/lib/ui/components/menu-items.tsx +2 -2
  105. package/src/lib/ui/context/actions.tsx +27 -31
  106. package/src/lib/ui/hooks/useEditorEvents.ts +1 -1
  107. package/src/lib/ui/hooks/useTranslation/defaultTranslation.ts +4 -4
  108. package/src/lib/ui/version.ts +3 -3
  109. package/src/lib/utils/embeds/embeds.test.ts +16 -34
  110. package/src/test/SelectTool.test.ts +251 -0
  111. package/src/test/bookmark-shapes.test.ts +129 -7
@@ -1,5 +1,6 @@
1
1
  import { TLBookmarkShape, createShapeId } from '@tldraw/editor'
2
- import { getHumanReadableAddress } from '../lib/shapes/bookmark/BookmarkShapeUtil'
2
+ import { vi } from 'vitest'
3
+ import { createBookmarkFromUrl, getHumanReadableAddress } from '../lib/shapes/bookmark/bookmarks'
3
4
  import { TestEditor } from './TestEditor'
4
5
 
5
6
  let editor: TestEditor
@@ -74,12 +75,12 @@ describe('The URL formatter', () => {
74
75
  const e = editor.getShape<TLBookmarkShape>(ids.e)!
75
76
  const f = editor.getShape<TLBookmarkShape>(ids.f)!
76
77
 
77
- expect(getHumanReadableAddress(a)).toBe('github.com')
78
- expect(getHumanReadableAddress(b)).toBe('github.com')
79
- expect(getHumanReadableAddress(c)).toBe('github.com')
80
- expect(getHumanReadableAddress(d)).toBe('github.com')
81
- expect(getHumanReadableAddress(e)).toBe('github.com')
82
- expect(getHumanReadableAddress(f)).toBe('github.com')
78
+ expect(getHumanReadableAddress(a.props.url)).toBe('github.com')
79
+ expect(getHumanReadableAddress(b.props.url)).toBe('github.com')
80
+ expect(getHumanReadableAddress(c.props.url)).toBe('github.com')
81
+ expect(getHumanReadableAddress(d.props.url)).toBe('github.com')
82
+ expect(getHumanReadableAddress(e.props.url)).toBe('github.com')
83
+ expect(getHumanReadableAddress(f.props.url)).toBe('github.com')
83
84
  })
84
85
 
85
86
  it("Doesn't resize bookmarks", () => {
@@ -132,3 +133,124 @@ describe('The URL formatter', () => {
132
133
  expect(newBookmark.props.h).toBe(320)
133
134
  })
134
135
  })
136
+
137
+ describe('createBookmarkFromUrl', () => {
138
+ it('creates a bookmark shape with unfurled metadata', async () => {
139
+ const url = 'https://example.com'
140
+ const center = { x: 100, y: 200 }
141
+
142
+ // Mock the asset creation to return a test asset
143
+ const mockAsset = {
144
+ id: 'asset:test-asset-id' as any,
145
+ typeName: 'asset' as const,
146
+ type: 'bookmark' as const,
147
+ props: {
148
+ src: url,
149
+ title: 'Example Site',
150
+ description: 'An example website',
151
+ image: 'https://example.com/image.jpg',
152
+ favicon: 'https://example.com/favicon.ico',
153
+ },
154
+ meta: {},
155
+ }
156
+
157
+ // Mock the getAssetForExternalContent method
158
+ vi.spyOn(editor, 'getAssetForExternalContent').mockResolvedValue(mockAsset)
159
+
160
+ const result = await createBookmarkFromUrl(editor, { url, center })
161
+
162
+ assert(result.ok, 'Failed to create bookmark')
163
+ const shape = result.value
164
+ expect(shape.type).toBe('bookmark')
165
+ expect(shape.props.url).toBe(url)
166
+ expect(shape.props.assetId).toBe('asset:test-asset-id')
167
+ expect(shape.props.w).toBe(300)
168
+ expect(shape.props.h).toBe(320)
169
+ expect(shape.x).toBe(center.x - 150) // BOOKMARK_WIDTH / 2
170
+ expect(shape.y).toBe(center.y - 160) // BOOKMARK_HEIGHT / 2
171
+
172
+ // Verify the shape was created in the editor
173
+ const createdShape = editor.getShape(result.value.id)
174
+ expect(createdShape).toBeDefined()
175
+ expect(createdShape?.type).toBe('bookmark')
176
+
177
+ // Verify the asset was created
178
+ const createdAsset = editor.getAsset('asset:test-asset-id' as any)
179
+ expect(createdAsset).toBeDefined()
180
+ expect(createdAsset?.type).toBe('bookmark')
181
+ })
182
+
183
+ it('creates a bookmark shape with default center when no center provided', async () => {
184
+ const url = 'https://example.com'
185
+ const viewportCenter = { x: 500, y: 300 }
186
+
187
+ // Mock getViewportPageBounds to return a known center
188
+ vi.spyOn(editor, 'getViewportPageBounds').mockReturnValue({
189
+ x: 0,
190
+ y: 0,
191
+ w: 1000,
192
+ h: 600,
193
+ center: viewportCenter,
194
+ } as any)
195
+
196
+ const mockAsset = {
197
+ id: 'asset:test-asset-id' as any,
198
+ typeName: 'asset' as const,
199
+ type: 'bookmark' as const,
200
+ props: {
201
+ src: url,
202
+ title: 'Example Site',
203
+ description: 'An example website',
204
+ image: '',
205
+ favicon: '',
206
+ },
207
+ meta: {},
208
+ }
209
+
210
+ vi.spyOn(editor, 'getAssetForExternalContent').mockResolvedValue(mockAsset)
211
+
212
+ const result = await createBookmarkFromUrl(editor, { url })
213
+
214
+ assert(result.ok, 'Failed to create bookmark')
215
+ const shape = result.value
216
+ expect(shape.x).toBe(viewportCenter.x - 150)
217
+ expect(shape.y).toBe(viewportCenter.y - 160)
218
+ })
219
+
220
+ it('handles asset creation failure gracefully', async () => {
221
+ const url = 'https://invalid-url.com'
222
+ const center = { x: 100, y: 200 }
223
+
224
+ // Mock the asset creation to fail
225
+ vi.spyOn(editor, 'getAssetForExternalContent').mockRejectedValue(new Error('Failed to fetch'))
226
+
227
+ const result = await createBookmarkFromUrl(editor, { url, center })
228
+
229
+ assert(!result.ok, 'Failed to create bookmark')
230
+ expect(result.error).toBe('Failed to fetch')
231
+
232
+ // Verify no shape was created
233
+ const shapes = editor.getCurrentPageShapes()
234
+ expect(shapes).toHaveLength(0)
235
+ })
236
+
237
+ it('creates bookmark shape even when asset creation returns null', async () => {
238
+ const url = 'https://example.com'
239
+ const center = { x: 100, y: 200 }
240
+
241
+ // Mock the asset creation to return null
242
+ vi.spyOn(editor, 'getAssetForExternalContent').mockResolvedValue(null as any)
243
+
244
+ const result = await createBookmarkFromUrl(editor, { url, center })
245
+
246
+ assert(result.ok, 'Failed to create bookmark')
247
+ const shape = result.value
248
+ expect(shape.type).toBe('bookmark')
249
+ expect(shape.props.url).toBe(url)
250
+ expect(shape.props.assetId).toBe(null)
251
+
252
+ // Verify the shape was created
253
+ const createdShape = editor.getShape(result.value.id)
254
+ expect(createdShape).toBeDefined()
255
+ })
256
+ })