tldraw 4.1.0-canary.3766a107225c → 4.1.0-canary.37739a2e6894
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.
- package/dist-cjs/index.d.ts +35 -10
- package/dist-cjs/index.js +3 -1
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/canvas/TldrawCropHandles.js +1 -1
- package/dist-cjs/lib/canvas/TldrawScribble.js +1 -1
- package/dist-cjs/lib/canvas/TldrawSelectionForeground.js +1 -1
- package/dist-cjs/lib/defaultEmbedDefinitions.js +25 -30
- package/dist-cjs/lib/defaultEmbedDefinitions.js.map +2 -2
- package/dist-cjs/lib/defaultExternalContentHandlers.js +10 -33
- package/dist-cjs/lib/defaultExternalContentHandlers.js.map +2 -2
- package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js +3 -0
- package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js +44 -102
- package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/bookmark/bookmarks.js +138 -0
- package/dist-cjs/lib/shapes/bookmark/bookmarks.js.map +7 -0
- package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js +25 -3
- package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js +1 -1
- package/dist-cjs/lib/shapes/image/ImageShapeUtil.js +1 -1
- package/dist-cjs/lib/shapes/line/LineShapeUtil.js +3 -0
- package/dist-cjs/lib/shapes/line/LineShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/HyperlinkButton.js +1 -1
- package/dist-cjs/lib/shapes/shared/PlainTextLabel.js +1 -1
- package/dist-cjs/lib/shapes/shared/RichTextLabel.js +1 -1
- package/dist-cjs/lib/shapes/shared/ShapeFill.js +1 -1
- package/dist-cjs/lib/shapes/text/PlainTextArea.js +1 -1
- package/dist-cjs/lib/shapes/text/RichTextArea.js +1 -1
- package/dist-cjs/lib/shapes/video/VideoShapeUtil.js +1 -1
- package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Cropping.js +20 -4
- package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Cropping.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Idle.js +1 -1
- package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Idle.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.js +23 -11
- package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js +27 -6
- package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js +1 -1
- package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/PointingArrowLabel.js +21 -9
- package/dist-cjs/lib/tools/SelectTool/childStates/PointingArrowLabel.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/PointingResizeHandle.js +24 -8
- package/dist-cjs/lib/tools/SelectTool/childStates/PointingResizeHandle.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/PointingRotateHandle.js +21 -9
- package/dist-cjs/lib/tools/SelectTool/childStates/PointingRotateHandle.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js +23 -8
- package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Rotating.js +21 -9
- package/dist-cjs/lib/tools/SelectTool/childStates/Rotating.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js +26 -11
- package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js.map +2 -2
- package/dist-cjs/lib/ui/TldrawUi.js +2 -2
- package/dist-cjs/lib/ui/components/DebugMenu/DefaultDebugMenuContent.js +1 -1
- package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialog.js +1 -1
- package/dist-cjs/lib/ui/components/Minimap/DefaultMinimap.js +1 -1
- package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js +5 -0
- package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js.map +2 -2
- package/dist-cjs/lib/ui/components/OfflineIndicator/OfflineIndicator.js +1 -1
- package/dist-cjs/lib/ui/components/SharePanel/PeopleMenu.js +6 -2
- package/dist-cjs/lib/ui/components/SharePanel/PeopleMenu.js.map +2 -2
- package/dist-cjs/lib/ui/components/SharePanel/UserPresenceColorPicker.js +1 -1
- package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js +1 -1
- package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js +1 -1
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js +1 -1
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js.map +1 -1
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.js +1 -1
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelDropdownPicker.js +1 -1
- package/dist-cjs/lib/ui/components/Toolbar/DefaultToolbar.js +1 -1
- package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js +1 -1
- package/dist-cjs/lib/ui/components/Toolbar/ToggleToolLockedButton.js +1 -1
- package/dist-cjs/lib/ui/components/primitives/Button/TldrawUiButton.js +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js +1 -1
- package/dist-cjs/lib/ui/components/primitives/TldrawUiDialog.js +1 -1
- package/dist-cjs/lib/ui/components/primitives/TldrawUiDropdownMenu.js +1 -1
- package/dist-cjs/lib/ui/components/primitives/TldrawUiIcon.js +1 -1
- package/dist-cjs/lib/ui/components/primitives/TldrawUiInput.js +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiPopover.js +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js +1 -1
- package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js +1 -1
- package/dist-cjs/lib/ui/components/primitives/layout.js +1 -1
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuGroup.js +1 -1
- package/dist-cjs/lib/ui/context/actions.js +24 -30
- package/dist-cjs/lib/ui/context/actions.js.map +2 -2
- package/dist-cjs/lib/ui/context/breakpoints.js +1 -1
- package/dist-cjs/lib/ui/context/events.js +1 -1
- package/dist-cjs/lib/ui/hooks/useClipboardEvents.js +1 -1
- package/dist-cjs/lib/ui/hooks/useKeyboardShortcuts.js +1 -1
- package/dist-cjs/lib/ui/hooks/useLocalStorageState.js +1 -1
- package/dist-cjs/lib/ui/hooks/useTools.js +1 -1
- package/dist-cjs/lib/ui/hooks/useTranslation/useTranslation.js +1 -1
- package/dist-cjs/lib/ui/version.js +3 -3
- package/dist-cjs/lib/ui/version.js.map +1 -1
- package/dist-cjs/lib/utils/text/richText.js +4 -4
- package/dist-esm/index.d.mts +35 -10
- package/dist-esm/index.mjs +3 -1
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/defaultEmbedDefinitions.mjs +25 -30
- package/dist-esm/lib/defaultEmbedDefinitions.mjs.map +2 -2
- package/dist-esm/lib/defaultExternalContentHandlers.mjs +10 -33
- package/dist-esm/lib/defaultExternalContentHandlers.mjs.map +2 -2
- package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs +3 -0
- package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs +46 -101
- package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/bookmark/bookmarks.mjs +124 -0
- package/dist-esm/lib/shapes/bookmark/bookmarks.mjs.map +7 -0
- package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs +26 -3
- package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/line/LineShapeUtil.mjs +3 -0
- package/dist-esm/lib/shapes/line/LineShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Cropping.mjs +20 -4
- package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Cropping.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Idle.mjs +1 -1
- package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Idle.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.mjs +23 -11
- package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs +29 -7
- package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs +1 -1
- package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/PointingArrowLabel.mjs +21 -9
- package/dist-esm/lib/tools/SelectTool/childStates/PointingArrowLabel.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/PointingResizeHandle.mjs +24 -8
- package/dist-esm/lib/tools/SelectTool/childStates/PointingResizeHandle.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/PointingRotateHandle.mjs +21 -9
- package/dist-esm/lib/tools/SelectTool/childStates/PointingRotateHandle.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs +23 -8
- package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Rotating.mjs +21 -9
- package/dist-esm/lib/tools/SelectTool/childStates/Rotating.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs +26 -11
- package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs +5 -0
- package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs.map +2 -2
- package/dist-esm/lib/ui/components/SharePanel/PeopleMenu.mjs +6 -2
- package/dist-esm/lib/ui/components/SharePanel/PeopleMenu.mjs.map +2 -2
- package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs +1 -1
- package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs.map +1 -1
- package/dist-esm/lib/ui/context/actions.mjs +23 -29
- package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
- package/dist-esm/lib/ui/version.mjs +3 -3
- package/dist-esm/lib/ui/version.mjs.map +1 -1
- package/package.json +11 -11
- package/src/index.ts +1 -0
- package/src/lib/defaultEmbedDefinitions.ts +20 -24
- package/src/lib/defaultExternalContentHandlers.ts +12 -37
- package/src/lib/shapes/arrow/ArrowShapeUtil.tsx +3 -0
- package/src/lib/shapes/bookmark/BookmarkShapeUtil.tsx +51 -135
- package/src/lib/shapes/bookmark/bookmarks.ts +170 -0
- package/src/lib/shapes/embed/EmbedShapeUtil.tsx +28 -2
- package/src/lib/shapes/line/LineShapeUtil.tsx +3 -0
- package/src/lib/shapes/text/TextShapeTool.test.ts +74 -0
- package/src/lib/tools/SelectTool/childStates/Crop/children/Cropping.ts +23 -6
- package/src/lib/tools/SelectTool/childStates/Crop/children/Idle.ts +1 -1
- package/src/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.ts +24 -12
- package/src/lib/tools/SelectTool/childStates/DraggingHandle.tsx +34 -11
- package/src/lib/tools/SelectTool/childStates/Idle.ts +1 -1
- package/src/lib/tools/SelectTool/childStates/PointingArrowLabel.ts +23 -11
- package/src/lib/tools/SelectTool/childStates/PointingResizeHandle.ts +26 -9
- package/src/lib/tools/SelectTool/childStates/PointingRotateHandle.ts +23 -10
- package/src/lib/tools/SelectTool/childStates/Resizing.ts +24 -9
- package/src/lib/tools/SelectTool/childStates/Rotating.ts +27 -11
- package/src/lib/tools/SelectTool/childStates/Translating.ts +28 -12
- package/src/lib/ui/components/Minimap/MinimapManager.ts +6 -0
- package/src/lib/ui/components/SharePanel/PeopleMenu.tsx +6 -2
- package/src/lib/ui/components/StylePanel/StylePanelButtonPicker.tsx +1 -1
- package/src/lib/ui/context/actions.tsx +27 -31
- package/src/lib/ui/version.ts +3 -3
- package/src/lib/utils/embeds/embeds.test.ts +16 -34
- package/src/test/SelectTool.test.ts +251 -0
- package/src/test/bookmark-shapes.test.ts +129 -7
- package/src/test/customSnapping.test.tsx +55 -11
- package/tldraw.css +7 -2
|
@@ -19,14 +19,20 @@ export class Rotating extends StateNode {
|
|
|
19
19
|
|
|
20
20
|
snapshot = {} as TLRotationSnapshot
|
|
21
21
|
|
|
22
|
-
info = {} as Extract<TLPointerEventInfo, { target: 'selection' }> & {
|
|
22
|
+
info = {} as Extract<TLPointerEventInfo, { target: 'selection' }> & {
|
|
23
|
+
onInteractionEnd?: string | (() => void)
|
|
24
|
+
}
|
|
23
25
|
|
|
24
26
|
markId = ''
|
|
25
27
|
|
|
26
|
-
override onEnter(
|
|
28
|
+
override onEnter(
|
|
29
|
+
info: TLPointerEventInfo & { target: 'selection'; onInteractionEnd?: string | (() => void) }
|
|
30
|
+
) {
|
|
27
31
|
// Store the event information
|
|
28
32
|
this.info = info
|
|
29
|
-
|
|
33
|
+
if (typeof info.onInteractionEnd === 'string') {
|
|
34
|
+
this.parent.setCurrentToolIdMask(info.onInteractionEnd)
|
|
35
|
+
}
|
|
30
36
|
|
|
31
37
|
this.markId = this.editor.markHistoryStoppingPoint('rotate start')
|
|
32
38
|
|
|
@@ -121,11 +127,16 @@ export class Rotating extends StateNode {
|
|
|
121
127
|
})
|
|
122
128
|
|
|
123
129
|
this.editor.bailToMark(this.markId)
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
130
|
+
const { onInteractionEnd } = this.info
|
|
131
|
+
if (onInteractionEnd) {
|
|
132
|
+
if (typeof onInteractionEnd === 'string') {
|
|
133
|
+
this.editor.setCurrentTool(onInteractionEnd, this.info)
|
|
134
|
+
} else {
|
|
135
|
+
onInteractionEnd()
|
|
136
|
+
}
|
|
137
|
+
return
|
|
128
138
|
}
|
|
139
|
+
this.parent.transition('idle', this.info)
|
|
129
140
|
}
|
|
130
141
|
|
|
131
142
|
private complete() {
|
|
@@ -139,11 +150,16 @@ export class Rotating extends StateNode {
|
|
|
139
150
|
this.editor,
|
|
140
151
|
this.snapshot.shapeSnapshots.map((s) => s.shape.id)
|
|
141
152
|
)
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
153
|
+
const { onInteractionEnd } = this.info
|
|
154
|
+
if (onInteractionEnd) {
|
|
155
|
+
if (typeof onInteractionEnd === 'string') {
|
|
156
|
+
this.editor.setCurrentTool(onInteractionEnd, this.info)
|
|
157
|
+
} else {
|
|
158
|
+
onInteractionEnd()
|
|
159
|
+
}
|
|
160
|
+
return
|
|
146
161
|
}
|
|
162
|
+
this.parent.transition('idle', this.info)
|
|
147
163
|
}
|
|
148
164
|
|
|
149
165
|
_getRotationFromPointerPosition({ snapToNearestDegree }: { snapToNearestDegree: boolean }) {
|
|
@@ -28,7 +28,7 @@ export type TranslatingInfo = TLPointerEventInfo & {
|
|
|
28
28
|
isCreating?: boolean
|
|
29
29
|
creatingMarkId?: string
|
|
30
30
|
onCreate?(): void
|
|
31
|
-
onInteractionEnd?: string
|
|
31
|
+
onInteractionEnd?: string | (() => void)
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
export class Translating extends StateNode {
|
|
@@ -59,7 +59,9 @@ export class Translating extends StateNode {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
this.info = info
|
|
62
|
-
|
|
62
|
+
if (typeof info.onInteractionEnd === 'string') {
|
|
63
|
+
this.parent.setCurrentToolIdMask(info.onInteractionEnd)
|
|
64
|
+
}
|
|
63
65
|
this.isCreating = isCreating
|
|
64
66
|
|
|
65
67
|
this.markId = ''
|
|
@@ -190,15 +192,24 @@ export class Translating extends StateNode {
|
|
|
190
192
|
this.snapshot.movingShapes.map((s) => s.id)
|
|
191
193
|
)
|
|
192
194
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
195
|
+
const { onInteractionEnd } = this.info
|
|
196
|
+
if (onInteractionEnd) {
|
|
197
|
+
if (typeof onInteractionEnd === 'string') {
|
|
198
|
+
if (this.editor.getInstanceState().isToolLocked) {
|
|
199
|
+
this.editor.setCurrentTool(onInteractionEnd)
|
|
200
|
+
return
|
|
201
|
+
}
|
|
198
202
|
} else {
|
|
199
|
-
|
|
203
|
+
onInteractionEnd()
|
|
204
|
+
return
|
|
200
205
|
}
|
|
201
206
|
}
|
|
207
|
+
|
|
208
|
+
if (this.isCreating) {
|
|
209
|
+
this.onCreate?.(this.editor.getOnlySelectedShape())
|
|
210
|
+
} else {
|
|
211
|
+
this.parent.transition('idle')
|
|
212
|
+
}
|
|
202
213
|
}
|
|
203
214
|
|
|
204
215
|
private cancel() {
|
|
@@ -214,11 +225,16 @@ export class Translating extends StateNode {
|
|
|
214
225
|
})
|
|
215
226
|
|
|
216
227
|
this.reset()
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
228
|
+
const { onInteractionEnd } = this.info
|
|
229
|
+
if (onInteractionEnd) {
|
|
230
|
+
if (typeof onInteractionEnd === 'string') {
|
|
231
|
+
this.editor.setCurrentTool(onInteractionEnd)
|
|
232
|
+
} else {
|
|
233
|
+
onInteractionEnd()
|
|
234
|
+
}
|
|
235
|
+
return
|
|
221
236
|
}
|
|
237
|
+
this.parent.transition('idle', this.info)
|
|
222
238
|
}
|
|
223
239
|
|
|
224
240
|
protected handleStart() {
|
|
@@ -249,6 +249,12 @@ export class MinimapManager {
|
|
|
249
249
|
|
|
250
250
|
const len = geometry.length
|
|
251
251
|
|
|
252
|
+
const shape = this.editor.getShape(shapeId)
|
|
253
|
+
if (shape) {
|
|
254
|
+
const shapeUtil = this.editor.getShapeUtil(shape.type)
|
|
255
|
+
if (shapeUtil.hideInMinimap?.(shape)) continue
|
|
256
|
+
}
|
|
257
|
+
|
|
252
258
|
if (selectedShapes.has(shapeId)) {
|
|
253
259
|
appendVertices(this.gl.selectedShapes, selectedShapeOffset, geometry)
|
|
254
260
|
selectedShapeOffset += len
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { useContainer, useEditor, usePeerIds, useValue } from '@tldraw/editor'
|
|
2
2
|
import { Popover as _Popover } from 'radix-ui'
|
|
3
3
|
import { ReactNode } from 'react'
|
|
4
|
+
import { PORTRAIT_BREAKPOINT } from '../../constants'
|
|
5
|
+
import { useBreakpoint } from '../../context/breakpoints'
|
|
4
6
|
import { useMenuIsOpen } from '../../hooks/useMenuIsOpen'
|
|
5
7
|
import { useTranslation } from '../../hooks/useTranslation/useTranslation'
|
|
6
8
|
import { PeopleMenuAvatar } from './PeopleMenuAvatar'
|
|
@@ -25,6 +27,8 @@ export function PeopleMenu({ children }: PeopleMenuProps) {
|
|
|
25
27
|
const userName = useValue('user', () => editor.user.getName(), [editor])
|
|
26
28
|
|
|
27
29
|
const [isOpen, onOpenChange] = useMenuIsOpen('people menu')
|
|
30
|
+
const breakpoint = useBreakpoint()
|
|
31
|
+
const maxAvatars = breakpoint <= PORTRAIT_BREAKPOINT.MOBILE_XS ? 1 : 5
|
|
28
32
|
|
|
29
33
|
if (!userIds.length) return null
|
|
30
34
|
|
|
@@ -33,7 +37,7 @@ export function PeopleMenu({ children }: PeopleMenuProps) {
|
|
|
33
37
|
<_Popover.Trigger dir="ltr" asChild>
|
|
34
38
|
<button className="tlui-people-menu__avatars-button" title={msg('people-menu.title')}>
|
|
35
39
|
<div className="tlui-people-menu__avatars">
|
|
36
|
-
{userIds.slice(-
|
|
40
|
+
{userIds.slice(-maxAvatars).map((userId) => (
|
|
37
41
|
<PeopleMenuAvatar key={userId} userId={userId} />
|
|
38
42
|
))}
|
|
39
43
|
{userIds.length > 0 && (
|
|
@@ -46,7 +50,7 @@ export function PeopleMenu({ children }: PeopleMenuProps) {
|
|
|
46
50
|
{userName?.[0] ?? ''}
|
|
47
51
|
</div>
|
|
48
52
|
)}
|
|
49
|
-
{userIds.length >
|
|
53
|
+
{userIds.length > maxAvatars && <PeopleMenuMore count={userIds.length - maxAvatars} />}
|
|
50
54
|
</div>
|
|
51
55
|
</button>
|
|
52
56
|
</_Popover.Trigger>
|
|
@@ -132,7 +132,7 @@ export const StylePanelButtonPicker = memo(function StylePanelButtonPicker<T ext
|
|
|
132
132
|
<TldrawUiToolbarToggleGroup
|
|
133
133
|
data-testid={`style.${uiType}`}
|
|
134
134
|
type="single"
|
|
135
|
-
value={value.type === 'shared' ? value.value :
|
|
135
|
+
value={value.type === 'shared' ? value.value : null}
|
|
136
136
|
asChild
|
|
137
137
|
>
|
|
138
138
|
<Layout>
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
Editor,
|
|
6
6
|
HALF_PI,
|
|
7
7
|
PageRecordType,
|
|
8
|
+
Result,
|
|
8
9
|
TLBookmarkShape,
|
|
9
10
|
TLEmbedShape,
|
|
10
11
|
TLFrameShape,
|
|
@@ -24,6 +25,7 @@ import {
|
|
|
24
25
|
useMaybeEditor,
|
|
25
26
|
} from '@tldraw/editor'
|
|
26
27
|
import * as React from 'react'
|
|
28
|
+
import { createBookmarkFromUrl } from '../../shapes/bookmark/bookmarks'
|
|
27
29
|
import { fitFrameToContent, removeFrame } from '../../utils/frames/frames'
|
|
28
30
|
import { generateShapeAnnouncementMessage } from '../components/A11y'
|
|
29
31
|
import { EditLinkDialog } from '../components/EditLinkDialog'
|
|
@@ -387,45 +389,39 @@ export function ActionsProvider({ overrides, children }: ActionsProviderProps) {
|
|
|
387
389
|
{
|
|
388
390
|
id: 'convert-to-bookmark',
|
|
389
391
|
label: 'action.convert-to-bookmark',
|
|
390
|
-
onSelect(source) {
|
|
392
|
+
async onSelect(source) {
|
|
391
393
|
if (!canApplySelectionAction()) return
|
|
392
394
|
if (mustGoBackToSelectToolFirst()) return
|
|
393
395
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
const shapes = editor.getSelectedShapes()
|
|
396
|
+
trackEvent('convert-to-bookmark', { source })
|
|
397
|
+
const shapes = editor.getSelectedShapes()
|
|
397
398
|
|
|
398
|
-
|
|
399
|
-
const deleteList: TLShapeId[] = []
|
|
400
|
-
for (const shape of shapes) {
|
|
401
|
-
if (!shape || !editor.isShapeOfType<TLEmbedShape>(shape, 'embed') || !shape.props.url)
|
|
402
|
-
continue
|
|
399
|
+
const markId = editor.markHistoryStoppingPoint('convert shapes to bookmark')
|
|
403
400
|
|
|
404
|
-
|
|
405
|
-
newPos.rot(-shape.rotation)
|
|
406
|
-
newPos.add(new Vec(shape.props.w / 2 - 300 / 2, shape.props.h / 2 - 320 / 2)) // see bookmark shape util
|
|
407
|
-
newPos.rot(shape.rotation)
|
|
408
|
-
const partial: TLShapePartial<TLBookmarkShape> = {
|
|
409
|
-
id: createShapeId(),
|
|
410
|
-
type: 'bookmark',
|
|
411
|
-
rotation: shape.rotation,
|
|
412
|
-
x: newPos.x,
|
|
413
|
-
y: newPos.y,
|
|
414
|
-
opacity: 1,
|
|
415
|
-
props: {
|
|
416
|
-
url: shape.props.url,
|
|
417
|
-
},
|
|
418
|
-
}
|
|
401
|
+
const creationPromises: Promise<Result<any, any>>[] = []
|
|
419
402
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
403
|
+
for (const shape of shapes) {
|
|
404
|
+
if (!shape || !editor.isShapeOfType<TLEmbedShape>(shape, 'embed') || !shape.props.url)
|
|
405
|
+
continue
|
|
423
406
|
|
|
424
|
-
editor.
|
|
407
|
+
const center = editor.getShapePageBounds(shape)?.center
|
|
425
408
|
|
|
426
|
-
|
|
427
|
-
editor.deleteShapes(
|
|
428
|
-
|
|
409
|
+
if (!center) continue
|
|
410
|
+
editor.deleteShapes([shape.id])
|
|
411
|
+
|
|
412
|
+
creationPromises.push(
|
|
413
|
+
createBookmarkFromUrl(editor, { url: shape.props.url, center }).then((res) => {
|
|
414
|
+
if (!res.ok) {
|
|
415
|
+
throw new Error(res.error)
|
|
416
|
+
}
|
|
417
|
+
return res
|
|
418
|
+
})
|
|
419
|
+
)
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
await Promise.all(creationPromises).catch((error) => {
|
|
423
|
+
editor.bailToMark(markId)
|
|
424
|
+
console.error(error)
|
|
429
425
|
})
|
|
430
426
|
},
|
|
431
427
|
},
|
package/src/lib/ui/version.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// This file is automatically generated by internal/scripts/refresh-assets.ts.
|
|
2
2
|
// Do not edit manually. Or do, I'm a comment, not a cop.
|
|
3
3
|
|
|
4
|
-
export const version = '4.1.0-canary.
|
|
4
|
+
export const version = '4.1.0-canary.37739a2e6894'
|
|
5
5
|
export const publishDates = {
|
|
6
6
|
major: '2025-09-18T14:39:22.803Z',
|
|
7
|
-
minor: '2025-
|
|
8
|
-
patch: '2025-
|
|
7
|
+
minor: '2025-10-15T09:03:42.490Z',
|
|
8
|
+
patch: '2025-10-15T09:03:42.490Z',
|
|
9
9
|
}
|
|
@@ -275,6 +275,14 @@ const MATCH_URL_TEST_URLS: (MatchUrlTestNoMatchDef | MatchUrlTestMatchDef)[] = [
|
|
|
275
275
|
embedUrl: `https://replit.com/@omar/Blob-Generator?embed=true`,
|
|
276
276
|
},
|
|
277
277
|
},
|
|
278
|
+
{
|
|
279
|
+
url: 'https://replit.com/@omar/Blob-Generator#index.html',
|
|
280
|
+
match: true,
|
|
281
|
+
output: {
|
|
282
|
+
type: 'replit',
|
|
283
|
+
embedUrl: `https://replit.com/@omar/Blob-Generator?embed=true#index.html`,
|
|
284
|
+
},
|
|
285
|
+
},
|
|
278
286
|
{
|
|
279
287
|
url: 'https://replit.com/foobar',
|
|
280
288
|
match: false,
|
|
@@ -347,23 +355,6 @@ const MATCH_URL_TEST_URLS: (MatchUrlTestNoMatchDef | MatchUrlTestMatchDef)[] = [
|
|
|
347
355
|
url: 'https://vimeo.com/foobar',
|
|
348
356
|
match: false,
|
|
349
357
|
},
|
|
350
|
-
// excalidraw
|
|
351
|
-
{
|
|
352
|
-
url: 'https://excalidraw.com/#room=asdkjashdkjhaskdjh,sadkjhakjshdkjahd',
|
|
353
|
-
match: true,
|
|
354
|
-
output: {
|
|
355
|
-
type: 'excalidraw',
|
|
356
|
-
embedUrl: `https://excalidraw.com/#room=asdkjashdkjhaskdjh,sadkjhakjshdkjahd`,
|
|
357
|
-
},
|
|
358
|
-
},
|
|
359
|
-
{
|
|
360
|
-
url: 'https://excalidraw.com',
|
|
361
|
-
match: false,
|
|
362
|
-
},
|
|
363
|
-
{
|
|
364
|
-
url: 'https://excalidraw.com/help',
|
|
365
|
-
match: false,
|
|
366
|
-
},
|
|
367
358
|
//desmos
|
|
368
359
|
{
|
|
369
360
|
url: 'https://www.desmos.com/calculator/js9hryvejc',
|
|
@@ -599,6 +590,14 @@ const MATCH_EMBED_TEST_URLS: (MatchEmbedTestMatchDef | MatchEmbedTestNoMatchDef)
|
|
|
599
590
|
url: `https://replit.com/@omar/Blob-Generator`,
|
|
600
591
|
},
|
|
601
592
|
},
|
|
593
|
+
{
|
|
594
|
+
embedUrl: 'https://replit.com/@omar/Blob-Generator?embed=true#index.html',
|
|
595
|
+
match: true,
|
|
596
|
+
output: {
|
|
597
|
+
type: 'replit',
|
|
598
|
+
url: `https://replit.com/@omar/Blob-Generator#index.html`,
|
|
599
|
+
},
|
|
600
|
+
},
|
|
602
601
|
{
|
|
603
602
|
embedUrl: 'https://replit.com/@omar/Blob-Generator',
|
|
604
603
|
match: false,
|
|
@@ -671,23 +670,6 @@ const MATCH_EMBED_TEST_URLS: (MatchEmbedTestMatchDef | MatchEmbedTestNoMatchDef)
|
|
|
671
670
|
embedUrl: 'https://vimeo.com/foobar',
|
|
672
671
|
match: false,
|
|
673
672
|
},
|
|
674
|
-
// excalidraw
|
|
675
|
-
{
|
|
676
|
-
embedUrl: 'https://excalidraw.com/#room=asdkjashdkjhaskdjh,sadkjhakjshdkjahd',
|
|
677
|
-
match: true,
|
|
678
|
-
output: {
|
|
679
|
-
type: 'excalidraw',
|
|
680
|
-
url: `https://excalidraw.com/#room=asdkjashdkjhaskdjh,sadkjhakjshdkjahd`,
|
|
681
|
-
},
|
|
682
|
-
},
|
|
683
|
-
{
|
|
684
|
-
embedUrl: 'https://excalidraw.com',
|
|
685
|
-
match: false,
|
|
686
|
-
},
|
|
687
|
-
{
|
|
688
|
-
embedUrl: 'https://excalidraw.com/help',
|
|
689
|
-
match: false,
|
|
690
|
-
},
|
|
691
673
|
// desmos
|
|
692
674
|
{
|
|
693
675
|
embedUrl: 'https://www.desmos.com/calculator/js9hryvejc?embed',
|
|
@@ -648,3 +648,254 @@ test('right clicking a shape inside of a group does not focus the group if the g
|
|
|
648
648
|
editor.pointerUp(100, 100, { target: 'shape', button: 0, shape: editor.getShape(boxAId)! })
|
|
649
649
|
expect(editor.getFocusedGroupId()).toBe(groupId)
|
|
650
650
|
})
|
|
651
|
+
|
|
652
|
+
describe('when passing a function to onInteractionEnd', () => {
|
|
653
|
+
it('calls the function for cropping', () => {
|
|
654
|
+
const id = createShapeId('image')
|
|
655
|
+
editor.createShapes([
|
|
656
|
+
{
|
|
657
|
+
id,
|
|
658
|
+
type: 'image',
|
|
659
|
+
x: 100,
|
|
660
|
+
y: 100,
|
|
661
|
+
props: {
|
|
662
|
+
w: 1200,
|
|
663
|
+
h: 800,
|
|
664
|
+
},
|
|
665
|
+
},
|
|
666
|
+
])
|
|
667
|
+
|
|
668
|
+
editor.select(id)
|
|
669
|
+
|
|
670
|
+
const fn = vi.fn()
|
|
671
|
+
editor.setCurrentTool('select.cropping', {
|
|
672
|
+
handle: 'bottom_right',
|
|
673
|
+
onInteractionEnd: fn,
|
|
674
|
+
})
|
|
675
|
+
editor.pointerUp(50, 50)
|
|
676
|
+
|
|
677
|
+
expect(fn).toHaveBeenCalled()
|
|
678
|
+
})
|
|
679
|
+
|
|
680
|
+
it('calls the function for pointing crop handle', () => {
|
|
681
|
+
const fn = vi.fn()
|
|
682
|
+
editor.setCurrentTool('select.crop.pointing_crop_handle', {
|
|
683
|
+
onInteractionEnd: fn,
|
|
684
|
+
})
|
|
685
|
+
editor.pointerUp(50, 50)
|
|
686
|
+
expect(fn).toHaveBeenCalled()
|
|
687
|
+
})
|
|
688
|
+
|
|
689
|
+
it('calls the function for pointing arrow label', () => {
|
|
690
|
+
const fn = vi.fn()
|
|
691
|
+
const id = createShapeId('arrow')
|
|
692
|
+
|
|
693
|
+
const arrow = {
|
|
694
|
+
id,
|
|
695
|
+
type: 'arrow' as const,
|
|
696
|
+
x: 100,
|
|
697
|
+
y: 100,
|
|
698
|
+
props: {
|
|
699
|
+
richText: toRichText('Test Label'),
|
|
700
|
+
start: { x: 0, y: 0 },
|
|
701
|
+
end: { x: 100, y: 0 },
|
|
702
|
+
},
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
editor.createShapes<TLArrowShape>([arrow])
|
|
706
|
+
|
|
707
|
+
editor.setCurrentTool('select.pointing_arrow_label', {
|
|
708
|
+
shape: arrow,
|
|
709
|
+
onInteractionEnd: fn,
|
|
710
|
+
})
|
|
711
|
+
editor.pointerUp(50, 50)
|
|
712
|
+
expect(fn).toHaveBeenCalled()
|
|
713
|
+
})
|
|
714
|
+
|
|
715
|
+
it('calls the function for pointing a resize handle', () => {
|
|
716
|
+
const fn = vi.fn()
|
|
717
|
+
editor.setCurrentTool('select.pointing_resize_handle', {
|
|
718
|
+
target: 'selection',
|
|
719
|
+
handle: 'bottom_right',
|
|
720
|
+
onInteractionEnd: fn,
|
|
721
|
+
})
|
|
722
|
+
editor.pointerUp(50, 50)
|
|
723
|
+
expect(fn).toHaveBeenCalled()
|
|
724
|
+
})
|
|
725
|
+
|
|
726
|
+
it('calls the function for pointing a rotate handle', () => {
|
|
727
|
+
const fn = vi.fn()
|
|
728
|
+
editor.setCurrentTool('select.pointing_rotate_handle', {
|
|
729
|
+
target: 'selection',
|
|
730
|
+
handle: 'bottom_right_rotate',
|
|
731
|
+
onInteractionEnd: fn,
|
|
732
|
+
})
|
|
733
|
+
editor.pointerUp(50, 50)
|
|
734
|
+
expect(fn).toHaveBeenCalled()
|
|
735
|
+
})
|
|
736
|
+
|
|
737
|
+
it('calls the function for resizing', () => {
|
|
738
|
+
const id = createShapeId('box')
|
|
739
|
+
editor.createShapes([
|
|
740
|
+
{
|
|
741
|
+
id,
|
|
742
|
+
type: 'geo',
|
|
743
|
+
x: 100,
|
|
744
|
+
y: 100,
|
|
745
|
+
},
|
|
746
|
+
])
|
|
747
|
+
|
|
748
|
+
editor.select(id)
|
|
749
|
+
|
|
750
|
+
const fn = vi.fn()
|
|
751
|
+
editor.setCurrentTool('select.resizing', {
|
|
752
|
+
target: 'selection',
|
|
753
|
+
handle: 'bottom_right',
|
|
754
|
+
onInteractionEnd: fn,
|
|
755
|
+
})
|
|
756
|
+
editor.pointerUp(50, 50)
|
|
757
|
+
expect(fn).toHaveBeenCalled()
|
|
758
|
+
})
|
|
759
|
+
|
|
760
|
+
it('calls the function for translating', () => {
|
|
761
|
+
const id = createShapeId('box')
|
|
762
|
+
editor.createShapes([
|
|
763
|
+
{
|
|
764
|
+
id,
|
|
765
|
+
type: 'geo',
|
|
766
|
+
x: 100,
|
|
767
|
+
y: 100,
|
|
768
|
+
},
|
|
769
|
+
])
|
|
770
|
+
editor.select(id)
|
|
771
|
+
|
|
772
|
+
const fn = vi.fn()
|
|
773
|
+
editor.setCurrentTool('select.translating', {
|
|
774
|
+
onInteractionEnd: fn,
|
|
775
|
+
})
|
|
776
|
+
editor.pointerUp(50, 50)
|
|
777
|
+
expect(fn).toHaveBeenCalled()
|
|
778
|
+
})
|
|
779
|
+
})
|
|
780
|
+
|
|
781
|
+
describe('when passing a string to onInteractionEnd', () => {
|
|
782
|
+
it('transitions to the tool for cropping', () => {
|
|
783
|
+
const id = createShapeId('image')
|
|
784
|
+
editor.createShapes([
|
|
785
|
+
{
|
|
786
|
+
id,
|
|
787
|
+
type: 'image',
|
|
788
|
+
x: 100,
|
|
789
|
+
y: 100,
|
|
790
|
+
props: {
|
|
791
|
+
w: 1200,
|
|
792
|
+
h: 800,
|
|
793
|
+
},
|
|
794
|
+
},
|
|
795
|
+
])
|
|
796
|
+
|
|
797
|
+
editor.select(id)
|
|
798
|
+
|
|
799
|
+
editor.setCurrentTool('select.cropping', {
|
|
800
|
+
handle: 'bottom_right',
|
|
801
|
+
onInteractionEnd: 'select.idle',
|
|
802
|
+
})
|
|
803
|
+
editor.pointerUp(50, 50)
|
|
804
|
+
|
|
805
|
+
editor.expectToBeIn('select.idle')
|
|
806
|
+
})
|
|
807
|
+
|
|
808
|
+
it('transitions to the tool for pointing crop handle', () => {
|
|
809
|
+
editor.setCurrentTool('select.crop.pointing_crop_handle', {
|
|
810
|
+
onInteractionEnd: 'select.idle',
|
|
811
|
+
})
|
|
812
|
+
editor.pointerUp(50, 50)
|
|
813
|
+
editor.expectToBeIn('select.idle')
|
|
814
|
+
})
|
|
815
|
+
|
|
816
|
+
it('transitions to the tool for pointing arrow label', () => {
|
|
817
|
+
const id = createShapeId('arrow')
|
|
818
|
+
|
|
819
|
+
const arrow = {
|
|
820
|
+
id,
|
|
821
|
+
type: 'arrow' as const,
|
|
822
|
+
x: 100,
|
|
823
|
+
y: 100,
|
|
824
|
+
props: {
|
|
825
|
+
richText: toRichText('Test Label'),
|
|
826
|
+
start: { x: 0, y: 0 },
|
|
827
|
+
end: { x: 100, y: 0 },
|
|
828
|
+
},
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
editor.createShapes<TLArrowShape>([arrow])
|
|
832
|
+
|
|
833
|
+
editor.setCurrentTool('select.pointing_arrow_label', {
|
|
834
|
+
shape: arrow,
|
|
835
|
+
onInteractionEnd: 'select.idle',
|
|
836
|
+
})
|
|
837
|
+
editor.pointerUp(50, 50)
|
|
838
|
+
editor.expectToBeIn('select.idle')
|
|
839
|
+
})
|
|
840
|
+
|
|
841
|
+
it('transitions to the tool for pointing a resize handle', () => {
|
|
842
|
+
editor.setCurrentTool('select.pointing_resize_handle', {
|
|
843
|
+
target: 'selection',
|
|
844
|
+
handle: 'bottom_right',
|
|
845
|
+
onInteractionEnd: 'select.idle',
|
|
846
|
+
})
|
|
847
|
+
editor.pointerUp(50, 50)
|
|
848
|
+
editor.expectToBeIn('select.idle')
|
|
849
|
+
})
|
|
850
|
+
|
|
851
|
+
it('transitions to the tool for pointing a rotate handle', () => {
|
|
852
|
+
editor.setCurrentTool('select.pointing_rotate_handle', {
|
|
853
|
+
target: 'selection',
|
|
854
|
+
handle: 'bottom_right_rotate',
|
|
855
|
+
onInteractionEnd: 'select.idle',
|
|
856
|
+
})
|
|
857
|
+
editor.pointerUp(50, 50)
|
|
858
|
+
editor.expectToBeIn('select.idle')
|
|
859
|
+
})
|
|
860
|
+
|
|
861
|
+
it('transitions to the tool for resizing', () => {
|
|
862
|
+
const id = createShapeId('box')
|
|
863
|
+
editor.createShapes([
|
|
864
|
+
{
|
|
865
|
+
id,
|
|
866
|
+
type: 'geo',
|
|
867
|
+
x: 100,
|
|
868
|
+
y: 100,
|
|
869
|
+
},
|
|
870
|
+
])
|
|
871
|
+
|
|
872
|
+
editor.select(id)
|
|
873
|
+
|
|
874
|
+
editor.setCurrentTool('select.resizing', {
|
|
875
|
+
target: 'selection',
|
|
876
|
+
handle: 'bottom_right',
|
|
877
|
+
onInteractionEnd: 'select.idle',
|
|
878
|
+
})
|
|
879
|
+
editor.pointerUp(50, 50)
|
|
880
|
+
editor.expectToBeIn('select.idle')
|
|
881
|
+
})
|
|
882
|
+
|
|
883
|
+
it('transitions to the tool for translating', () => {
|
|
884
|
+
const id = createShapeId('box')
|
|
885
|
+
editor.createShapes([
|
|
886
|
+
{
|
|
887
|
+
id,
|
|
888
|
+
type: 'geo',
|
|
889
|
+
x: 100,
|
|
890
|
+
y: 100,
|
|
891
|
+
},
|
|
892
|
+
])
|
|
893
|
+
editor.select(id)
|
|
894
|
+
|
|
895
|
+
editor.setCurrentTool('select.translating', {
|
|
896
|
+
onInteractionEnd: 'select.idle',
|
|
897
|
+
})
|
|
898
|
+
editor.pointerUp(50, 50)
|
|
899
|
+
editor.expectToBeIn('select.idle')
|
|
900
|
+
})
|
|
901
|
+
})
|